@@ -1189,6 +1189,23 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
11891189 none ( )
11901190 }
11911191
1192+ /**
1193+ * Holds if `n` steps directly to the normal exit node (`normal = true`)
1194+ * or the exceptional exit node (`normal = false`) of callable `c`.
1195+ *
1196+ * By default the only node that reaches a callable's normal exit is the
1197+ * "after" node of its body. This predicate lets a language route the tail
1198+ * of a function epilogue (such as Go's result-read or deferred-call nodes)
1199+ * to the appropriate exit node, which is useful when the body cannot
1200+ * terminate normally (e.g. it always ends in a `return`) and therefore has
1201+ * no "after" node to anchor the epilogue on.
1202+ *
1203+ * The default implementation adds no such steps.
1204+ */
1205+ default predicate callableExitStep ( PreControlFlowNode n , Callable c , boolean normal ) {
1206+ none ( )
1207+ }
1208+
11921209 /**
11931210 * Holds if there is a local non-abrupt step from `n1` to `n2`.
11941211 *
@@ -1464,6 +1481,12 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
14641481 n1 .isAfter ( getBodyExit ( c ) ) and
14651482 n2 .( NormalExitNodeImpl ) .getEnclosingCallable ( ) = c
14661483 or
1484+ Input2:: callableExitStep ( n1 , c , true ) and
1485+ n2 .( NormalExitNodeImpl ) .getEnclosingCallable ( ) = c
1486+ or
1487+ Input2:: callableExitStep ( n1 , c , false ) and
1488+ n2 .( ExceptionalExitNodeImpl ) .getEnclosingCallable ( ) = c
1489+ or
14671490 n1 .( AnnotatedExitNodeImpl ) .getEnclosingCallable ( ) = c and
14681491 n2 .( ExitNodeImpl ) .getEnclosingCallable ( ) = c
14691492 )
0 commit comments