@@ -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