Skip to content

Commit 4e502d1

Browse files
authored
Merge pull request github#5951 from MathiasVP/optimize-switcCase-getAStmt
C++: Remove large antijoin in `SwitchCase.getAStmt`
2 parents bae3728 + b4e4c12 commit 4e502d1

File tree

1 file changed

+12
-9
lines changed
  • cpp/ql/src/semmle/code/cpp/stmts

1 file changed

+12
-9
lines changed

cpp/ql/src/semmle/code/cpp/stmts/Stmt.qll

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,11 @@ private predicate inForUpdate(Expr forUpdate, Expr child) {
11361136
exists(Expr mid | inForUpdate(forUpdate, mid) and child.getParent() = mid)
11371137
}
11381138

1139+
/** Gets the `rnk`'th `case` statement in `b`. */
1140+
private int indexOfSwitchCaseRank(BlockStmt b, int rnk) {
1141+
result = rank[rnk](int i | b.getStmt(i) instanceof SwitchCase)
1142+
}
1143+
11391144
/**
11401145
* A C/C++ 'switch case' statement.
11411146
*
@@ -1331,16 +1336,14 @@ class SwitchCase extends Stmt, @stmt_switch_case {
13311336
* `default:` has results `{ x = 3; }, `x = 4;` and `break;`.
13321337
*/
13331338
Stmt getAStmt() {
1334-
exists(BlockStmt b, int i, int j |
1339+
exists(BlockStmt b, int rnk, int i |
13351340
b.getStmt(i) = this and
1336-
b.getStmt(j) = result and
1337-
i < j and
1338-
not result instanceof SwitchCase and
1339-
not exists(SwitchCase sc, int k |
1340-
b.getStmt(k) = sc and
1341-
i < k and
1342-
j > k
1343-
)
1341+
i = indexOfSwitchCaseRank(b, rnk)
1342+
|
1343+
pragma[only_bind_into](b).getStmt([i + 1 .. indexOfSwitchCaseRank(b, rnk + 1) - 1]) = result
1344+
or
1345+
not exists(indexOfSwitchCaseRank(b, rnk + 1)) and
1346+
b.getStmt([i + 1 .. b.getNumStmt() + 1]) = result
13441347
)
13451348
}
13461349

0 commit comments

Comments
 (0)