@@ -156,19 +156,19 @@ private predicate variableReadActual(BasicBlock bb, int i, Variable v) {
156156 */
157157pragma [ noinline]
158158private predicate hasCapturedWrite ( Variable v , Cfg:: CfgScope scope ) {
159- any ( VariableWriteAccess write | write .getVariable ( ) = v and scope = write .getEnclosingCallable + ( ) )
159+ any ( VariableWriteAccess write | write .getVariable ( ) = v and scope = write .getEnclosingCfgScope + ( ) )
160160 .isCapture ( )
161161}
162162
163163/**
164164 * Holds if `v` is read inside basic block `bb` at index `i`, which is in the
165- * immediate outer scope of `scope`.
165+ * immediate outer CFG scope of `scope`.
166166 */
167167pragma [ noinline]
168168private predicate variableReadActualInOuterScope (
169169 BasicBlock bb , int i , Variable v , Cfg:: CfgScope scope
170170) {
171- variableReadActual ( bb , i , v ) and bb .getScope ( ) = scope .getEnclosingCallable ( )
171+ variableReadActual ( bb , i , v ) and bb .getScope ( ) = scope .getEnclosingCfgScope ( )
172172}
173173
174174pragma [ noinline]
@@ -263,7 +263,7 @@ private predicate readsCapturedVariable(BasicBlock bb, Variable v) {
263263 */
264264pragma [ noinline]
265265private predicate hasCapturedRead ( Variable v , Cfg:: CfgScope scope ) {
266- any ( VariableReadAccess read | read .getVariable ( ) = v and scope = read .getEnclosingCallable + ( ) )
266+ any ( VariableReadAccess read | read .getVariable ( ) = v and scope = read .getEnclosingCfgScope + ( ) )
267267 .isCapture ( )
268268}
269269
@@ -273,14 +273,18 @@ private predicate hasCapturedRead(Variable v, Cfg::CfgScope scope) {
273273 */
274274pragma [ noinline]
275275private predicate variableWriteInOuterScope ( BasicBlock bb , int i , Variable v , Cfg:: CfgScope scope ) {
276- SsaInput:: variableWrite ( bb , i , v , _) and scope .getEnclosingCallable ( ) = bb .getScope ( )
276+ SsaInput:: variableWrite ( bb , i , v , _) and scope .getEnclosingCfgScope ( ) = bb .getScope ( )
277277}
278278
279+ /** Holds if evaluating `e` jumps to the evaluation of a different CFG scope. */
280+ private predicate isControlFlowJump ( Expr e ) { e instanceof CallExprBase or e instanceof AwaitExpr }
281+
279282/**
280283 * Holds if the call `call` at index `i` in basic block `bb` may reach
281284 * a callable that reads captured variable `v`.
282285 */
283- private predicate capturedCallRead ( CallExprBase call , BasicBlock bb , int i , Variable v ) {
286+ private predicate capturedCallRead ( Expr call , BasicBlock bb , int i , Variable v ) {
287+ isControlFlowJump ( call ) and
284288 exists ( Cfg:: CfgScope scope |
285289 hasCapturedRead ( v , scope ) and
286290 (
@@ -295,7 +299,8 @@ private predicate capturedCallRead(CallExprBase call, BasicBlock bb, int i, Vari
295299 * Holds if the call `call` at index `i` in basic block `bb` may reach a callable
296300 * that writes captured variable `v`.
297301 */
298- predicate capturedCallWrite ( CallExprBase call , BasicBlock bb , int i , Variable v ) {
302+ predicate capturedCallWrite ( Expr call , BasicBlock bb , int i , Variable v ) {
303+ isControlFlowJump ( call ) and
299304 call = bb .getNode ( i ) .getAstNode ( ) and
300305 exists ( Cfg:: CfgScope scope |
301306 hasVariableReadWithCapturedWrite ( bb , any ( int j | j > i ) , v , scope )
0 commit comments