From 4ebad019fc608d8dd0ef84405a9b6e96c6dc9757 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 4 Sep 2026 11:40:19 +0200 Subject: [PATCH] Cfg: Add consistency check for multiple default cases. --- .../codeql/controlflow/ControlFlowGraph.qll | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll index c3f9868a638a..392a777d3ef4 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll @@ -2286,7 +2286,7 @@ module Make0 Ast> { multipleConditionalSuccessorKinds(node, t1, t2, succ1, succ2) ) or - query = "directAndConditionalSuccessor" and + query = "directAndConditionalSuccessors" and results = strictcount(ControlFlowNode node, ConditionalSuccessor t1, DirectSuccessor t2, ControlFlowNode succ1, ControlFlowNode succ2 | @@ -2295,6 +2295,19 @@ module Make0 Ast> { or query = "selfLoop" and results = strictcount(ControlFlowNode node, SuccessorType t | selfLoop(node, t)) + or + query = "bodyPartNonOverlap" and + results = strictcount(Callable c | bodyPartNonOverlap(c)) + or + query = "parameterNonOverlap" and + results = strictcount(Callable c, Parameter p | parameterNonOverlap(c, p)) + or + query = "parameterEnclosingCallable" and + results = strictcount(Parameter p, Callable c | parameterEnclosingCallable(p, c)) + or + query = "multipleDefaultCases" and + results = + strictcount(Switch s, int defaultCases | multipleDefaultCases(s, defaultCases)) } /** @@ -2495,6 +2508,16 @@ module Make0 Ast> { p = callableGetParameter(c, _) and not c = getEnclosingCallable(p) } + + /** + * Holds if a switch `s` has multiple default cases. + * + * A well-formed switch statement should have at most one default case. + */ + query predicate multipleDefaultCases(Switch s, int defaultCases) { + defaultCases = strictcount(DefaultCase c | s.getCase(_) = c) and + defaultCases > 1 + } } } }