mirror of
https://github.com/github/codeql.git
synced 2026-03-30 20:28:15 +02:00
Cfg: Move getCaseControlFlowOrder to shared code.
This commit is contained in:
@@ -134,15 +134,6 @@ private module Ast implements AstSig<Location> {
|
||||
}
|
||||
}
|
||||
|
||||
int getCaseControlFlowOrder(Switch s, Case c) {
|
||||
exists(int pos | s.getCase(pos) = c |
|
||||
// if a default case is not last in the AST, move it last in the CFG order
|
||||
if c instanceof DefaultCase and exists(s.getCase(pos + 1))
|
||||
then result = strictcount(s.getCase(_))
|
||||
else result = pos
|
||||
)
|
||||
}
|
||||
|
||||
private Stmt getSwitchStmt(Switch s, int i) {
|
||||
result = s.(SwitchStmt).getStmt(i) or
|
||||
result = s.(SwitchExpr).getStmt(i)
|
||||
@@ -191,6 +182,8 @@ private module Ast implements AstSig<Location> {
|
||||
}
|
||||
}
|
||||
|
||||
class DefaultCase extends Case instanceof J::DefaultCase { }
|
||||
|
||||
predicate fallsThrough(Case c) { not c.(J::SwitchCase).isRule() }
|
||||
|
||||
class ConditionalExpr = J::ConditionalExpr;
|
||||
|
||||
@@ -226,16 +226,6 @@ signature module AstSig<LocationSig Location> {
|
||||
Case getCase(int index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an integer indicating the control flow order of a case within a switch.
|
||||
* This is most often the same as the AST order, but can be different in some
|
||||
* languages if the language allows a default case to appear before other
|
||||
* cases.
|
||||
*
|
||||
* The values do not need to be contiguous; only the relative ordering matters.
|
||||
*/
|
||||
default int getCaseControlFlowOrder(Switch s, Case c) { s.getCase(result) = c }
|
||||
|
||||
/** A case in a switch. */
|
||||
class Case extends AstNode {
|
||||
/** Gets a pattern being matched by this case. */
|
||||
@@ -253,6 +243,8 @@ signature module AstSig<LocationSig Location> {
|
||||
AstNode getBodyElement(int index);
|
||||
}
|
||||
|
||||
class DefaultCase extends Case;
|
||||
|
||||
/**
|
||||
* Holds if this case can fall through to the next case if it is not
|
||||
* otherwise prevented with a `break` or similar.
|
||||
@@ -938,7 +930,7 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
|
||||
*
|
||||
* A match-all case can still ultimately fail to match if it has a guard.
|
||||
*/
|
||||
default predicate matchAll(Case c) { none() }
|
||||
default predicate matchAll(Case c) { c instanceof DefaultCase }
|
||||
|
||||
/**
|
||||
* Holds if `ast` may result in an abrupt completion `c` originating at
|
||||
@@ -1096,6 +1088,21 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an integer indicating the control flow order of a case within a
|
||||
* switch. This is equal to the AST order, except that default cases are
|
||||
* always last in control flow order, even if some languages allow them
|
||||
* to appear before other cases in the AST.
|
||||
*/
|
||||
private int getCaseControlFlowOrder(Switch s, Case c) {
|
||||
exists(int pos | s.getCase(pos) = c |
|
||||
// if a default case is not last in the AST, move it last in the CFG order
|
||||
if c instanceof DefaultCase and exists(s.getCase(pos + 1))
|
||||
then result = strictcount(s.getCase(_))
|
||||
else result = pos
|
||||
)
|
||||
}
|
||||
|
||||
private Case getRankedCaseCfgOrder(Switch s, int rnk) {
|
||||
result = rank[rnk](Case c, int i | getCaseControlFlowOrder(s, c) = i | c order by i)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user