Skip to content

Commit db8b2cf

Browse files
committed
Allow overriding endAbruptCompletion for callables
1 parent 3cd6a27 commit db8b2cf

1 file changed

Lines changed: 23 additions & 2 deletions

File tree

‎shared/controlflow/codeql/controlflow/ControlFlowGraph.qll‎

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,7 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
11521152
signature module InputSig2 {
11531153
/**
11541154
* Holds if `ast` may result in an abrupt completion `c` originating at
1155-
* `n`. The boolean `always` indicates whether the abrupt completion
1155+
* `n`. The boolean `always` indicates whether the abrupt completion
11561156
* always occurs or whether `n` may also terminate normally.
11571157
*
11581158
* This predicate is only relevant for AST constructs that are not already
@@ -1171,6 +1171,24 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
11711171
*/
11721172
predicate endAbruptCompletion(AstNode ast, PreControlFlowNode n, AbruptCompletion c);
11731173

1174+
/**
1175+
* Holds if the language-specific implementation takes over the catching
1176+
* of the abrupt completion `completion` at the boundary of callable `c`.
1177+
*
1178+
* When this holds, the library's default routing of `completion` to the
1179+
* normal or exceptional exit node of `c` is suppressed, and the language
1180+
* is then responsible for catching `completion` itself via
1181+
* `endAbruptCompletion` (for example, to interpose a function epilogue
1182+
* such as Go's deferred calls between a `return` and the normal exit
1183+
* node).
1184+
*
1185+
* The default implementation does not override any completions, leaving
1186+
* the standard behaviour intact.
1187+
*/
1188+
default predicate overridesCallableEndAbruptCompletion(Callable c, AbruptCompletion completion) {
1189+
none()
1190+
}
1191+
11741192
/**
11751193
* Holds if there is a local non-abrupt step from `n1` to `n2`.
11761194
*
@@ -1241,7 +1259,10 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
12411259
private predicate endAbruptCompletion(AstNode ast, PreControlFlowNode n, AbruptCompletion c) {
12421260
Input2::endAbruptCompletion(ast, n, c)
12431261
or
1244-
exists(Callable callable | callableHasBodyPart(callable, ast) |
1262+
exists(Callable callable |
1263+
not Input2::overridesCallableEndAbruptCompletion(callable, c) and
1264+
callableHasBodyPart(callable, ast)
1265+
|
12451266
c.getSuccessorType() instanceof ReturnSuccessor and
12461267
n.(NormalExitNodeImpl).getEnclosingCallable() = callable
12471268
or

0 commit comments

Comments
 (0)