Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion shared/controlflow/codeql/controlflow/ControlFlowGraph.qll
Original file line number Diff line number Diff line change
Expand Up @@ -2286,7 +2286,7 @@ module Make0<LocationSig Location, AstSig<Location> 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 |
Expand All @@ -2295,6 +2295,19 @@ module Make0<LocationSig Location, AstSig<Location> 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))
}

/**
Expand Down Expand Up @@ -2495,6 +2508,16 @@ module Make0<LocationSig Location, AstSig<Location> 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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yoff I think this indicates a mistake in the python CFG - a case _ if cond: should not be a DefaultCase, instead it should be included in predicate matchAll. The reason is that the shared CFG puts a default case last, and multiple default cases can't all be put "last". I.e. in several languages (e.g. in Java) it's valid to have the default case occur before another case, e.g. for the purpose of fallthrough, so it's only the non-default cases that are executed in-order.

defaultCases > 1
}
}
}
}
Expand Down
Loading