From e05b12621571957b412d3d186305031ac027b4ea Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 8 Nov 2024 10:21:33 +0100 Subject: [PATCH 1/8] Rust: Add CFG tests for async/await and const --- .../CONSISTENCY/DataFlowConsistency.expected | 27 +- .../library-tests/controlflow/Cfg.expected | 275 ++++++++++++------ .../ql/test/library-tests/controlflow/test.rs | 51 ++++ 3 files changed, 263 insertions(+), 90 deletions(-) diff --git a/rust/ql/test/library-tests/controlflow/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/library-tests/controlflow/CONSISTENCY/DataFlowConsistency.expected index cd9ee6e7f966..02fd0c4dd63c 100644 --- a/rust/ql/test/library-tests/controlflow/CONSISTENCY/DataFlowConsistency.expected +++ b/rust/ql/test/library-tests/controlflow/CONSISTENCY/DataFlowConsistency.expected @@ -45,8 +45,9 @@ uniqueEnclosingCallable | test.rs:324:29:324:42 | Param | Node should have one enclosing callable but has 0. | | test.rs:335:28:335:35 | Param | Node should have one enclosing callable but has 0. | | test.rs:342:29:342:40 | Param | Node should have one enclosing callable but has 0. | -| test.rs:401:15:401:25 | Param | Node should have one enclosing callable but has 0. | -| test.rs:408:16:408:19 | Param | Node should have one enclosing callable but has 0. | +| test.rs:390:22:390:27 | Param | Node should have one enclosing callable but has 0. | +| test.rs:452:15:452:25 | Param | Node should have one enclosing callable but has 0. | +| test.rs:459:16:459:19 | Param | Node should have one enclosing callable but has 0. | uniqueCallEnclosingCallable | test.rs:6:9:6:44 | CallExpr | Call should have one enclosing callable but has 0. | | test.rs:7:9:7:27 | CallExpr | Call should have one enclosing callable but has 0. | @@ -57,9 +58,19 @@ uniqueCallEnclosingCallable | test.rs:275:21:275:31 | CallExpr | Call should have one enclosing callable but has 0. | | test.rs:276:22:276:31 | CallExpr | Call should have one enclosing callable but has 0. | | test.rs:292:34:292:40 | CallExpr | Call should have one enclosing callable but has 0. | -| test.rs:376:9:376:18 | CallExpr | Call should have one enclosing callable but has 0. | -| test.rs:377:12:377:30 | CallExpr | Call should have one enclosing callable but has 0. | -| test.rs:380:9:380:23 | CallExpr | Call should have one enclosing callable but has 0. | -| test.rs:381:12:381:30 | CallExpr | Call should have one enclosing callable but has 0. | -| test.rs:384:9:384:23 | CallExpr | Call should have one enclosing callable but has 0. | -| test.rs:404:5:404:18 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:369:18:369:32 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:374:22:374:40 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:377:22:377:35 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:380:9:380:19 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:394:30:394:39 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:400:13:400:49 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:400:13:400:49 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:400:21:400:44 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:411:17:411:24 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:411:17:411:24 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:427:9:427:18 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:428:12:428:30 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:431:9:431:23 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:432:12:432:30 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:435:9:435:23 | CallExpr | Call should have one enclosing callable but has 0. | +| test.rs:455:5:455:18 | CallExpr | Call should have one enclosing callable but has 0. | diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index f2637a115c44..9dafa30db1f3 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -765,85 +765,196 @@ edges | test.rs:360:9:362:9 | ExprStmt | test.rs:361:13:361:13 | 1 | | | test.rs:360:14:362:9 | BlockExpr | test.rs:361:13:361:13 | 1 | | | test.rs:361:13:361:13 | 1 | test.rs:360:14:362:9 | BlockExpr | | -| test.rs:367:1:372:1 | enter dead_code | test.rs:368:5:370:5 | ExprStmt | | -| test.rs:367:1:372:1 | exit dead_code (normal) | test.rs:367:1:372:1 | exit dead_code | | -| test.rs:368:5:370:5 | ExprStmt | test.rs:368:9:368:12 | true | | -| test.rs:368:9:368:12 | true | test.rs:369:9:369:17 | ExprStmt | true | -| test.rs:369:9:369:16 | ReturnExpr | test.rs:367:1:372:1 | exit dead_code (normal) | return | -| test.rs:369:9:369:17 | ExprStmt | test.rs:369:16:369:16 | 0 | | -| test.rs:369:16:369:16 | 0 | test.rs:369:9:369:16 | ReturnExpr | | -| test.rs:374:1:387:1 | enter labelled_block1 | test.rs:375:5:386:6 | LetStmt | | -| test.rs:374:1:387:1 | exit labelled_block1 (normal) | test.rs:374:1:387:1 | exit labelled_block1 | | -| test.rs:374:29:387:1 | BlockExpr | test.rs:374:1:387:1 | exit labelled_block1 (normal) | | -| test.rs:375:5:386:6 | LetStmt | test.rs:376:9:376:19 | ExprStmt | | -| test.rs:375:9:375:14 | result | test.rs:374:29:387:1 | BlockExpr | match | -| test.rs:375:18:386:5 | BlockExpr | test.rs:375:9:375:14 | result | | -| test.rs:376:9:376:16 | PathExpr | test.rs:376:9:376:18 | CallExpr | | -| test.rs:376:9:376:18 | CallExpr | test.rs:377:9:379:9 | ExprStmt | | -| test.rs:376:9:376:19 | ExprStmt | test.rs:376:9:376:16 | PathExpr | | -| test.rs:377:9:379:9 | ExprStmt | test.rs:377:12:377:28 | PathExpr | | -| test.rs:377:9:379:9 | IfExpr | test.rs:380:9:380:24 | ExprStmt | | -| test.rs:377:12:377:28 | PathExpr | test.rs:377:12:377:30 | CallExpr | | -| test.rs:377:12:377:30 | CallExpr | test.rs:377:9:379:9 | IfExpr | false | -| test.rs:377:12:377:30 | CallExpr | test.rs:378:13:378:27 | ExprStmt | true | -| test.rs:378:13:378:26 | BreakExpr | test.rs:375:18:386:5 | BlockExpr | break | -| test.rs:378:13:378:27 | ExprStmt | test.rs:378:26:378:26 | 1 | | -| test.rs:378:26:378:26 | 1 | test.rs:378:13:378:26 | BreakExpr | | -| test.rs:380:9:380:21 | PathExpr | test.rs:380:9:380:23 | CallExpr | | -| test.rs:380:9:380:23 | CallExpr | test.rs:381:9:383:9 | ExprStmt | | -| test.rs:380:9:380:24 | ExprStmt | test.rs:380:9:380:21 | PathExpr | | -| test.rs:381:9:383:9 | ExprStmt | test.rs:381:12:381:28 | PathExpr | | -| test.rs:381:9:383:9 | IfExpr | test.rs:384:9:384:24 | ExprStmt | | -| test.rs:381:12:381:28 | PathExpr | test.rs:381:12:381:30 | CallExpr | | -| test.rs:381:12:381:30 | CallExpr | test.rs:381:9:383:9 | IfExpr | false | -| test.rs:381:12:381:30 | CallExpr | test.rs:382:13:382:27 | ExprStmt | true | -| test.rs:382:13:382:26 | BreakExpr | test.rs:375:18:386:5 | BlockExpr | break | -| test.rs:382:13:382:27 | ExprStmt | test.rs:382:26:382:26 | 2 | | -| test.rs:382:26:382:26 | 2 | test.rs:382:13:382:26 | BreakExpr | | -| test.rs:384:9:384:21 | PathExpr | test.rs:384:9:384:23 | CallExpr | | -| test.rs:384:9:384:23 | CallExpr | test.rs:385:9:385:9 | 3 | | -| test.rs:384:9:384:24 | ExprStmt | test.rs:384:9:384:21 | PathExpr | | -| test.rs:385:9:385:9 | 3 | test.rs:375:18:386:5 | BlockExpr | | -| test.rs:389:1:397:1 | enter labelled_block2 | test.rs:390:5:396:6 | LetStmt | | -| test.rs:389:1:397:1 | exit labelled_block2 (normal) | test.rs:389:1:397:1 | exit labelled_block2 | | -| test.rs:389:29:397:1 | BlockExpr | test.rs:389:1:397:1 | exit labelled_block2 (normal) | | -| test.rs:390:5:396:6 | LetStmt | test.rs:391:9:391:34 | LetStmt | | -| test.rs:390:9:390:14 | result | test.rs:389:29:397:1 | BlockExpr | match | -| test.rs:390:18:396:5 | BlockExpr | test.rs:390:9:390:14 | result | | -| test.rs:391:9:391:34 | LetStmt | test.rs:391:30:391:33 | PathExpr | | -| test.rs:391:13:391:13 | x | test.rs:392:9:394:10 | LetStmt | match | -| test.rs:391:30:391:33 | PathExpr | test.rs:391:13:391:13 | x | | -| test.rs:392:9:394:10 | LetStmt | test.rs:392:23:392:23 | x | | -| test.rs:392:13:392:19 | TupleStructPat | test.rs:392:18:392:18 | y | match | -| test.rs:392:13:392:19 | TupleStructPat | test.rs:393:13:393:27 | ExprStmt | no-match | -| test.rs:392:18:392:18 | y | test.rs:395:9:395:9 | x | match | -| test.rs:392:23:392:23 | x | test.rs:392:13:392:19 | TupleStructPat | | -| test.rs:393:13:393:26 | BreakExpr | test.rs:390:18:396:5 | BlockExpr | break | -| test.rs:393:13:393:27 | ExprStmt | test.rs:393:26:393:26 | 1 | | -| test.rs:393:26:393:26 | 1 | test.rs:393:13:393:26 | BreakExpr | | -| test.rs:395:9:395:9 | x | test.rs:390:18:396:5 | BlockExpr | | -| test.rs:399:1:405:1 | enter test_nested_function | test.rs:400:5:400:18 | LetStmt | | -| test.rs:399:1:405:1 | exit test_nested_function (normal) | test.rs:399:1:405:1 | exit test_nested_function | | -| test.rs:399:27:405:1 | BlockExpr | test.rs:399:1:405:1 | exit test_nested_function (normal) | | -| test.rs:400:5:400:18 | LetStmt | test.rs:400:17:400:17 | 0 | | -| test.rs:400:9:400:13 | x | test.rs:401:5:403:5 | nested | match | -| test.rs:400:17:400:17 | 0 | test.rs:400:9:400:13 | x | | -| test.rs:401:5:403:5 | enter nested | test.rs:401:15:401:15 | x | | -| test.rs:401:5:403:5 | exit nested (normal) | test.rs:401:5:403:5 | exit nested | | -| test.rs:401:5:403:5 | nested | test.rs:404:5:404:19 | ExprStmt | | -| test.rs:401:15:401:15 | x | test.rs:401:15:401:25 | Param | match | -| test.rs:401:15:401:25 | Param | test.rs:402:9:402:16 | ExprStmt | | -| test.rs:401:28:403:5 | BlockExpr | test.rs:401:5:403:5 | exit nested (normal) | | -| test.rs:402:9:402:10 | * ... | test.rs:402:15:402:15 | 1 | | -| test.rs:402:9:402:15 | ... += ... | test.rs:401:28:403:5 | BlockExpr | | -| test.rs:402:9:402:16 | ExprStmt | test.rs:402:10:402:10 | x | | -| test.rs:402:10:402:10 | x | test.rs:402:9:402:10 | * ... | | -| test.rs:402:15:402:15 | 1 | test.rs:402:9:402:15 | ... += ... | | -| test.rs:404:5:404:10 | PathExpr | test.rs:404:17:404:17 | x | | -| test.rs:404:5:404:18 | CallExpr | test.rs:399:27:405:1 | BlockExpr | | -| test.rs:404:5:404:19 | ExprStmt | test.rs:404:5:404:10 | PathExpr | | -| test.rs:404:12:404:17 | RefExpr | test.rs:404:5:404:18 | CallExpr | | -| test.rs:404:17:404:17 | x | test.rs:404:12:404:17 | RefExpr | | +| test.rs:368:5:370:5 | enter say_hello | test.rs:369:9:369:34 | ExprStmt | | +| test.rs:368:5:370:5 | exit say_hello (normal) | test.rs:368:5:370:5 | exit say_hello | | +| test.rs:368:26:370:5 | BlockExpr | test.rs:368:5:370:5 | exit say_hello (normal) | | +| test.rs:369:9:369:33 | MacroExpr | test.rs:368:26:370:5 | BlockExpr | | +| test.rs:369:9:369:33 | PathExpr | test.rs:369:18:369:32 | "hello, world!\\n" | | +| test.rs:369:9:369:34 | ExprStmt | test.rs:369:18:369:32 | MacroStmts | | +| test.rs:369:18:369:32 | "hello, world!\\n" | test.rs:369:18:369:32 | FormatArgsExpr | | +| test.rs:369:18:369:32 | BlockExpr | test.rs:369:9:369:33 | MacroExpr | | +| test.rs:369:18:369:32 | CallExpr | test.rs:369:18:369:32 | BlockExpr | | +| test.rs:369:18:369:32 | ExprStmt | test.rs:369:9:369:33 | PathExpr | | +| test.rs:369:18:369:32 | FormatArgsExpr | test.rs:369:18:369:32 | MacroExpr | | +| test.rs:369:18:369:32 | MacroExpr | test.rs:369:18:369:32 | CallExpr | | +| test.rs:369:18:369:32 | MacroStmts | test.rs:369:18:369:32 | ExprStmt | | +| test.rs:372:5:384:5 | enter async_block | test.rs:373:9:375:10 | LetStmt | | +| test.rs:372:5:384:5 | exit async_block (normal) | test.rs:372:5:384:5 | exit async_block | | +| test.rs:372:28:384:5 | BlockExpr | test.rs:372:5:384:5 | exit async_block (normal) | | +| test.rs:373:9:375:10 | LetStmt | test.rs:374:13:374:42 | ExprStmt | | +| test.rs:373:13:373:22 | say_godbye | test.rs:376:9:378:10 | LetStmt | match | +| test.rs:373:26:375:9 | BlockExpr | test.rs:373:13:373:22 | say_godbye | | +| test.rs:374:13:374:41 | MacroExpr | test.rs:373:26:375:9 | BlockExpr | | +| test.rs:374:13:374:41 | PathExpr | test.rs:374:22:374:40 | "godbye, everyone!\\n" | | +| test.rs:374:13:374:42 | ExprStmt | test.rs:374:22:374:40 | MacroStmts | | +| test.rs:374:22:374:40 | "godbye, everyone!\\n" | test.rs:374:22:374:40 | FormatArgsExpr | | +| test.rs:374:22:374:40 | BlockExpr | test.rs:374:13:374:41 | MacroExpr | | +| test.rs:374:22:374:40 | CallExpr | test.rs:374:22:374:40 | BlockExpr | | +| test.rs:374:22:374:40 | ExprStmt | test.rs:374:13:374:41 | PathExpr | | +| test.rs:374:22:374:40 | FormatArgsExpr | test.rs:374:22:374:40 | MacroExpr | | +| test.rs:374:22:374:40 | MacroExpr | test.rs:374:22:374:40 | CallExpr | | +| test.rs:374:22:374:40 | MacroStmts | test.rs:374:22:374:40 | ExprStmt | | +| test.rs:376:9:378:10 | LetStmt | test.rs:377:13:377:37 | ExprStmt | | +| test.rs:376:13:376:27 | say_how_are_you | test.rs:379:9:379:28 | LetStmt | match | +| test.rs:376:31:378:9 | BlockExpr | test.rs:376:13:376:27 | say_how_are_you | | +| test.rs:377:13:377:36 | MacroExpr | test.rs:376:31:378:9 | BlockExpr | | +| test.rs:377:13:377:36 | PathExpr | test.rs:377:22:377:35 | "how are you?\\n" | | +| test.rs:377:13:377:37 | ExprStmt | test.rs:377:22:377:35 | MacroStmts | | +| test.rs:377:22:377:35 | "how are you?\\n" | test.rs:377:22:377:35 | FormatArgsExpr | | +| test.rs:377:22:377:35 | BlockExpr | test.rs:377:13:377:36 | MacroExpr | | +| test.rs:377:22:377:35 | CallExpr | test.rs:377:22:377:35 | BlockExpr | | +| test.rs:377:22:377:35 | ExprStmt | test.rs:377:13:377:36 | PathExpr | | +| test.rs:377:22:377:35 | FormatArgsExpr | test.rs:377:22:377:35 | MacroExpr | | +| test.rs:377:22:377:35 | MacroExpr | test.rs:377:22:377:35 | CallExpr | | +| test.rs:377:22:377:35 | MacroStmts | test.rs:377:22:377:35 | ExprStmt | | +| test.rs:379:9:379:28 | LetStmt | test.rs:379:20:379:27 | BlockExpr | | +| test.rs:379:13:379:16 | noop | test.rs:380:9:380:26 | ExprStmt | match | +| test.rs:379:20:379:27 | BlockExpr | test.rs:379:13:379:16 | noop | | +| test.rs:380:9:380:17 | PathExpr | test.rs:380:9:380:19 | CallExpr | | +| test.rs:380:9:380:19 | CallExpr | test.rs:380:9:380:25 | AwaitExpr | | +| test.rs:380:9:380:25 | AwaitExpr | test.rs:381:9:381:30 | ExprStmt | | +| test.rs:380:9:380:26 | ExprStmt | test.rs:380:9:380:17 | PathExpr | | +| test.rs:381:9:381:23 | say_how_are_you | test.rs:381:9:381:29 | AwaitExpr | | +| test.rs:381:9:381:29 | AwaitExpr | test.rs:382:9:382:25 | ExprStmt | | +| test.rs:381:9:381:30 | ExprStmt | test.rs:381:9:381:23 | say_how_are_you | | +| test.rs:382:9:382:18 | say_godbye | test.rs:382:9:382:24 | AwaitExpr | | +| test.rs:382:9:382:24 | AwaitExpr | test.rs:383:9:383:19 | ExprStmt | | +| test.rs:382:9:382:25 | ExprStmt | test.rs:382:9:382:18 | say_godbye | | +| test.rs:383:9:383:12 | noop | test.rs:383:9:383:18 | AwaitExpr | | +| test.rs:383:9:383:18 | AwaitExpr | test.rs:372:28:384:5 | BlockExpr | | +| test.rs:383:9:383:19 | ExprStmt | test.rs:383:9:383:12 | noop | | +| test.rs:390:5:392:5 | enter add_two | test.rs:390:22:390:22 | n | | +| test.rs:390:5:392:5 | exit add_two (normal) | test.rs:390:5:392:5 | exit add_two | | +| test.rs:390:22:390:22 | n | test.rs:390:22:390:27 | Param | match | +| test.rs:390:22:390:27 | Param | test.rs:391:9:391:9 | n | | +| test.rs:390:37:392:5 | BlockExpr | test.rs:390:5:392:5 | exit add_two (normal) | | +| test.rs:391:9:391:9 | n | test.rs:391:13:391:13 | 2 | | +| test.rs:391:9:391:13 | ... + ... | test.rs:390:37:392:5 | BlockExpr | | +| test.rs:391:13:391:13 | 2 | test.rs:391:9:391:13 | ... + ... | | +| test.rs:396:5:404:5 | enter const_block_assert | test.rs:399:9:401:9 | ExprStmt | | +| test.rs:396:5:404:5 | exit const_block_assert (normal) | test.rs:396:5:404:5 | exit const_block_assert | | +| test.rs:396:41:404:5 | BlockExpr | test.rs:396:5:404:5 | exit const_block_assert (normal) | | +| test.rs:399:9:401:9 | BlockExpr | test.rs:403:9:403:10 | 42 | | +| test.rs:399:9:401:9 | ExprStmt | test.rs:400:13:400:50 | ExprStmt | | +| test.rs:400:13:400:49 | BlockExpr | test.rs:400:13:400:49 | MacroExpr | | +| test.rs:400:13:400:49 | BlockExpr | test.rs:400:13:400:49 | exit panic_cold_explicit (normal) | | +| test.rs:400:13:400:49 | BlockExpr | test.rs:400:21:400:48 | IfExpr | | +| test.rs:400:13:400:49 | CallExpr | test.rs:400:13:400:49 | BlockExpr | | +| test.rs:400:13:400:49 | CallExpr | test.rs:400:13:400:49 | BlockExpr | | +| test.rs:400:13:400:49 | ExprStmt | test.rs:400:13:400:49 | MacroStmts | | +| test.rs:400:13:400:49 | ExprStmt | test.rs:400:13:400:49 | PathExpr | | +| test.rs:400:13:400:49 | MacroExpr | test.rs:399:9:401:9 | BlockExpr | | +| test.rs:400:13:400:49 | MacroExpr | test.rs:400:13:400:49 | BlockExpr | | +| test.rs:400:13:400:49 | MacroStmts | test.rs:400:13:400:49 | panic_cold_explicit | | +| test.rs:400:13:400:49 | PathExpr | test.rs:400:13:400:49 | CallExpr | | +| test.rs:400:13:400:49 | PathExpr | test.rs:400:13:400:49 | CallExpr | | +| test.rs:400:13:400:49 | enter panic_cold_explicit | test.rs:400:13:400:49 | PathExpr | | +| test.rs:400:13:400:49 | exit panic_cold_explicit (normal) | test.rs:400:13:400:49 | exit panic_cold_explicit | | +| test.rs:400:13:400:49 | panic_cold_explicit | test.rs:400:13:400:49 | ExprStmt | | +| test.rs:400:13:400:50 | ExprStmt | test.rs:400:21:400:48 | MacroStmts | | +| test.rs:400:21:400:42 | PathExpr | test.rs:400:21:400:44 | CallExpr | | +| test.rs:400:21:400:44 | CallExpr | test.rs:400:48:400:48 | 0 | | +| test.rs:400:21:400:48 | ... > ... | test.rs:400:21:400:48 | [boolean(false)] ! ... | true | +| test.rs:400:21:400:48 | ... > ... | test.rs:400:21:400:48 | [boolean(true)] ! ... | false | +| test.rs:400:21:400:48 | BlockExpr | test.rs:400:13:400:49 | MacroExpr | | +| test.rs:400:21:400:48 | IfExpr | test.rs:400:21:400:48 | BlockExpr | | +| test.rs:400:21:400:48 | MacroStmts | test.rs:400:21:400:42 | PathExpr | | +| test.rs:400:21:400:48 | [boolean(false)] ! ... | test.rs:400:21:400:48 | IfExpr | false | +| test.rs:400:21:400:48 | [boolean(true)] ! ... | test.rs:400:13:400:49 | ExprStmt | true | +| test.rs:400:48:400:48 | 0 | test.rs:400:21:400:48 | ... > ... | | +| test.rs:403:9:403:10 | 42 | test.rs:396:41:404:5 | BlockExpr | | +| test.rs:406:5:415:5 | enter const_block_panic | test.rs:407:9:407:30 | Const | | +| test.rs:406:5:415:5 | exit const_block_panic (normal) | test.rs:406:5:415:5 | exit const_block_panic | | +| test.rs:406:35:415:5 | BlockExpr | test.rs:406:5:415:5 | exit const_block_panic (normal) | | +| test.rs:407:9:407:30 | Const | test.rs:408:9:413:9 | ExprStmt | | +| test.rs:408:9:413:9 | ExprStmt | test.rs:408:12:408:16 | false | | +| test.rs:408:9:413:9 | IfExpr | test.rs:414:9:414:9 | PathExpr | | +| test.rs:408:12:408:16 | false | test.rs:408:9:413:9 | IfExpr | false | +| test.rs:411:17:411:24 | BlockExpr | test.rs:411:17:411:24 | exit panic_cold_explicit (normal) | | +| test.rs:411:17:411:24 | CallExpr | test.rs:411:17:411:24 | BlockExpr | | +| test.rs:411:17:411:24 | PathExpr | test.rs:411:17:411:24 | CallExpr | | +| test.rs:411:17:411:24 | enter panic_cold_explicit | test.rs:411:17:411:24 | PathExpr | | +| test.rs:411:17:411:24 | exit panic_cold_explicit (normal) | test.rs:411:17:411:24 | exit panic_cold_explicit | | +| test.rs:414:9:414:9 | PathExpr | test.rs:406:35:415:5 | BlockExpr | | +| test.rs:418:1:423:1 | enter dead_code | test.rs:419:5:421:5 | ExprStmt | | +| test.rs:418:1:423:1 | exit dead_code (normal) | test.rs:418:1:423:1 | exit dead_code | | +| test.rs:419:5:421:5 | ExprStmt | test.rs:419:9:419:12 | true | | +| test.rs:419:9:419:12 | true | test.rs:420:9:420:17 | ExprStmt | true | +| test.rs:420:9:420:16 | ReturnExpr | test.rs:418:1:423:1 | exit dead_code (normal) | return | +| test.rs:420:9:420:17 | ExprStmt | test.rs:420:16:420:16 | 0 | | +| test.rs:420:16:420:16 | 0 | test.rs:420:9:420:16 | ReturnExpr | | +| test.rs:425:1:438:1 | enter labelled_block1 | test.rs:426:5:437:6 | LetStmt | | +| test.rs:425:1:438:1 | exit labelled_block1 (normal) | test.rs:425:1:438:1 | exit labelled_block1 | | +| test.rs:425:29:438:1 | BlockExpr | test.rs:425:1:438:1 | exit labelled_block1 (normal) | | +| test.rs:426:5:437:6 | LetStmt | test.rs:427:9:427:19 | ExprStmt | | +| test.rs:426:9:426:14 | result | test.rs:425:29:438:1 | BlockExpr | match | +| test.rs:426:18:437:5 | BlockExpr | test.rs:426:9:426:14 | result | | +| test.rs:427:9:427:16 | PathExpr | test.rs:427:9:427:18 | CallExpr | | +| test.rs:427:9:427:18 | CallExpr | test.rs:428:9:430:9 | ExprStmt | | +| test.rs:427:9:427:19 | ExprStmt | test.rs:427:9:427:16 | PathExpr | | +| test.rs:428:9:430:9 | ExprStmt | test.rs:428:12:428:28 | PathExpr | | +| test.rs:428:9:430:9 | IfExpr | test.rs:431:9:431:24 | ExprStmt | | +| test.rs:428:12:428:28 | PathExpr | test.rs:428:12:428:30 | CallExpr | | +| test.rs:428:12:428:30 | CallExpr | test.rs:428:9:430:9 | IfExpr | false | +| test.rs:428:12:428:30 | CallExpr | test.rs:429:13:429:27 | ExprStmt | true | +| test.rs:429:13:429:26 | BreakExpr | test.rs:426:18:437:5 | BlockExpr | break | +| test.rs:429:13:429:27 | ExprStmt | test.rs:429:26:429:26 | 1 | | +| test.rs:429:26:429:26 | 1 | test.rs:429:13:429:26 | BreakExpr | | +| test.rs:431:9:431:21 | PathExpr | test.rs:431:9:431:23 | CallExpr | | +| test.rs:431:9:431:23 | CallExpr | test.rs:432:9:434:9 | ExprStmt | | +| test.rs:431:9:431:24 | ExprStmt | test.rs:431:9:431:21 | PathExpr | | +| test.rs:432:9:434:9 | ExprStmt | test.rs:432:12:432:28 | PathExpr | | +| test.rs:432:9:434:9 | IfExpr | test.rs:435:9:435:24 | ExprStmt | | +| test.rs:432:12:432:28 | PathExpr | test.rs:432:12:432:30 | CallExpr | | +| test.rs:432:12:432:30 | CallExpr | test.rs:432:9:434:9 | IfExpr | false | +| test.rs:432:12:432:30 | CallExpr | test.rs:433:13:433:27 | ExprStmt | true | +| test.rs:433:13:433:26 | BreakExpr | test.rs:426:18:437:5 | BlockExpr | break | +| test.rs:433:13:433:27 | ExprStmt | test.rs:433:26:433:26 | 2 | | +| test.rs:433:26:433:26 | 2 | test.rs:433:13:433:26 | BreakExpr | | +| test.rs:435:9:435:21 | PathExpr | test.rs:435:9:435:23 | CallExpr | | +| test.rs:435:9:435:23 | CallExpr | test.rs:436:9:436:9 | 3 | | +| test.rs:435:9:435:24 | ExprStmt | test.rs:435:9:435:21 | PathExpr | | +| test.rs:436:9:436:9 | 3 | test.rs:426:18:437:5 | BlockExpr | | +| test.rs:440:1:448:1 | enter labelled_block2 | test.rs:441:5:447:6 | LetStmt | | +| test.rs:440:1:448:1 | exit labelled_block2 (normal) | test.rs:440:1:448:1 | exit labelled_block2 | | +| test.rs:440:29:448:1 | BlockExpr | test.rs:440:1:448:1 | exit labelled_block2 (normal) | | +| test.rs:441:5:447:6 | LetStmt | test.rs:442:9:442:34 | LetStmt | | +| test.rs:441:9:441:14 | result | test.rs:440:29:448:1 | BlockExpr | match | +| test.rs:441:18:447:5 | BlockExpr | test.rs:441:9:441:14 | result | | +| test.rs:442:9:442:34 | LetStmt | test.rs:442:30:442:33 | PathExpr | | +| test.rs:442:13:442:13 | x | test.rs:443:9:445:10 | LetStmt | match | +| test.rs:442:30:442:33 | PathExpr | test.rs:442:13:442:13 | x | | +| test.rs:443:9:445:10 | LetStmt | test.rs:443:23:443:23 | x | | +| test.rs:443:13:443:19 | TupleStructPat | test.rs:443:18:443:18 | y | match | +| test.rs:443:13:443:19 | TupleStructPat | test.rs:444:13:444:27 | ExprStmt | no-match | +| test.rs:443:18:443:18 | y | test.rs:446:9:446:9 | x | match | +| test.rs:443:23:443:23 | x | test.rs:443:13:443:19 | TupleStructPat | | +| test.rs:444:13:444:26 | BreakExpr | test.rs:441:18:447:5 | BlockExpr | break | +| test.rs:444:13:444:27 | ExprStmt | test.rs:444:26:444:26 | 1 | | +| test.rs:444:26:444:26 | 1 | test.rs:444:13:444:26 | BreakExpr | | +| test.rs:446:9:446:9 | x | test.rs:441:18:447:5 | BlockExpr | | +| test.rs:450:1:456:1 | enter test_nested_function | test.rs:451:5:451:18 | LetStmt | | +| test.rs:450:1:456:1 | exit test_nested_function (normal) | test.rs:450:1:456:1 | exit test_nested_function | | +| test.rs:450:27:456:1 | BlockExpr | test.rs:450:1:456:1 | exit test_nested_function (normal) | | +| test.rs:451:5:451:18 | LetStmt | test.rs:451:17:451:17 | 0 | | +| test.rs:451:9:451:13 | x | test.rs:452:5:454:5 | nested | match | +| test.rs:451:17:451:17 | 0 | test.rs:451:9:451:13 | x | | +| test.rs:452:5:454:5 | enter nested | test.rs:452:15:452:15 | x | | +| test.rs:452:5:454:5 | exit nested (normal) | test.rs:452:5:454:5 | exit nested | | +| test.rs:452:5:454:5 | nested | test.rs:455:5:455:19 | ExprStmt | | +| test.rs:452:15:452:15 | x | test.rs:452:15:452:25 | Param | match | +| test.rs:452:15:452:25 | Param | test.rs:453:9:453:16 | ExprStmt | | +| test.rs:452:28:454:5 | BlockExpr | test.rs:452:5:454:5 | exit nested (normal) | | +| test.rs:453:9:453:10 | * ... | test.rs:453:15:453:15 | 1 | | +| test.rs:453:9:453:15 | ... += ... | test.rs:452:28:454:5 | BlockExpr | | +| test.rs:453:9:453:16 | ExprStmt | test.rs:453:10:453:10 | x | | +| test.rs:453:10:453:10 | x | test.rs:453:9:453:10 | * ... | | +| test.rs:453:15:453:15 | 1 | test.rs:453:9:453:15 | ... += ... | | +| test.rs:455:5:455:10 | PathExpr | test.rs:455:17:455:17 | x | | +| test.rs:455:5:455:18 | CallExpr | test.rs:450:27:456:1 | BlockExpr | | +| test.rs:455:5:455:19 | ExprStmt | test.rs:455:5:455:10 | PathExpr | | +| test.rs:455:12:455:17 | RefExpr | test.rs:455:5:455:18 | CallExpr | | +| test.rs:455:17:455:17 | x | test.rs:455:12:455:17 | RefExpr | | breakTarget | test.rs:26:17:26:21 | BreakExpr | test.rs:20:9:32:9 | LoopExpr | | test.rs:40:21:40:25 | BreakExpr | test.rs:38:13:45:13 | LoopExpr | @@ -856,9 +967,9 @@ breakTarget | test.rs:186:17:186:28 | BreakExpr | test.rs:184:13:189:9 | LoopExpr | | test.rs:199:17:199:35 | BreakExpr | test.rs:197:13:202:9 | LoopExpr | | test.rs:211:13:211:30 | BreakExpr | test.rs:210:13:212:9 | BlockExpr | -| test.rs:378:13:378:26 | BreakExpr | test.rs:375:18:386:5 | BlockExpr | -| test.rs:382:13:382:26 | BreakExpr | test.rs:375:18:386:5 | BlockExpr | -| test.rs:393:13:393:26 | BreakExpr | test.rs:390:18:396:5 | BlockExpr | +| test.rs:429:13:429:26 | BreakExpr | test.rs:426:18:437:5 | BlockExpr | +| test.rs:433:13:433:26 | BreakExpr | test.rs:426:18:437:5 | BlockExpr | +| test.rs:444:13:444:26 | BreakExpr | test.rs:441:18:447:5 | BlockExpr | continueTarget | test.rs:29:17:29:24 | ContinueExpr | test.rs:20:9:32:9 | LoopExpr | | test.rs:55:21:55:28 | ContinueExpr | test.rs:53:13:60:13 | LoopExpr | diff --git a/rust/ql/test/library-tests/controlflow/test.rs b/rust/ql/test/library-tests/controlflow/test.rs index 1de079eaa3bd..69a5244d5e50 100644 --- a/rust/ql/test/library-tests/controlflow/test.rs +++ b/rust/ql/test/library-tests/controlflow/test.rs @@ -364,6 +364,57 @@ mod divergence { } } +mod async_await { + async fn say_hello() { + println!("hello, world!"); + } + + async fn async_block() { + let say_godbye = async { + println!("godbye, everyone!"); + }; + let say_how_are_you = async { + println!("how are you?"); + }; + let noop = async {}; + say_hello().await; + say_how_are_you.await; + say_godbye.await; + noop.await; + } +} + +mod const_evaluation { + const PI: i64 = 3.14159; + + const fn add_two(n: i64) -> i64 { + n + 2 + } + + const A_NUMBER: i64 = if add_two(2) + 2 == 4 { PI } else { 0 }; + + fn const_block_assert() -> usize { + // If this code ever gets executed, then the assertion has definitely + // been evaluated at compile-time. + const { + assert!(std::mem::size_of::() > 0); + } + // Here we can have unsafe code relying on the type being non-zero-sized. + 42 + } + + fn const_block_panic() -> i64 { + const N: i64 = 12 + 7; + if false { + // The panic may or may not occur when the program is built. + const { + panic!(); + } + } + N + } +} + fn dead_code() -> i64 { if (true) { return 0; From d52a2d67a2b87050488d9bcb974d5fff2c77eef4 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 8 Nov 2024 15:00:02 +0100 Subject: [PATCH 2/8] Rust: Create CFG scope for async blocks --- .../controlflow/internal/CfgConsistency.qll | 8 +++- .../internal/ControlFlowGraphImpl.qll | 37 ++++++++++--------- .../rust/controlflow/internal/Scope.qll | 36 ++++++++++++++++-- .../codeql/rust/elements/AsyncBlockExpr.qll | 13 +++++++ rust/ql/lib/rust.qll | 1 + .../library-tests/controlflow/Cfg.expected | 12 ++++-- 6 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/elements/AsyncBlockExpr.qll diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll b/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll index 668533f1c3dd..2722661494d6 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/CfgConsistency.qll @@ -32,8 +32,12 @@ query predicate nonPostOrderExpr(Expr e, string cls) { */ query predicate scopeNoFirst(CfgScope scope) { Consistency::scopeNoFirst(scope) and - not scope = any(Function f | not exists(f.getBody())) and - not scope = any(ClosureExpr c | not exists(c.getBody())) + not scope = + [ + any(AstNode f | not f.(Function).hasBody()), + any(ClosureExpr c | not c.hasBody()), + any(AsyncBlockExpr b | not b.hasStmtList()) + ] } /** Holds if `be` is the `else` branch of a `let` statement that results in a panic. */ diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 173bb8876bc8..0541031594d7 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -44,12 +44,10 @@ private module CfgInput implements InputSig { predicate successorTypeIsCondition(SuccessorType t) { t instanceof Cfg::BooleanSuccessor } /** Holds if `first` is first executed when entering `scope`. */ - predicate scopeFirst(CfgScope scope, AstNode first) { - first(scope.(CfgScopeTree).getFirstChildNode(), first) - } + predicate scopeFirst(CfgScope scope, AstNode first) { scope.scopeFirst(first) } /** Holds if `scope` is exited when `last` finishes with completion `c`. */ - predicate scopeLast(CfgScope scope, AstNode last, Completion c) { last(scope.getBody(), last, c) } + predicate scopeLast(CfgScope scope, AstNode last, Completion c) { scope.scopeLast(last, c) } } private module CfgSplittingInput implements SplittingInputSig { @@ -71,14 +69,7 @@ private module CfgImpl = import CfgImpl -class CfgScopeTree extends StandardTree, Scope::CfgScope { - override predicate first(AstNode first) { first = this } - - override predicate last(AstNode last, Completion c) { - last = this and - completionIsValidFor(c, this) - } - +class CallableScopeTree extends StandardTree, PreOrderTree, PostOrderTree, Scope::CallableScope { override predicate propagatesAbnormal(AstNode child) { none() } override AstNode getChildNode(int i) { @@ -280,13 +271,23 @@ module ExprTrees { } } + private AstNode getBlockChildNode(BlockExpr b, int i) { + result = b.getStmtList().getStatement(i) + or + i = b.getStmtList().getNumberOfStatements() and + result = b.getStmtList().getTailExpr() + } + + class AsyncBlockExprTree extends StandardTree, PreOrderTree, PostOrderTree, AsyncBlockExpr { + override AstNode getChildNode(int i) { result = getBlockChildNode(this, i) } + + override predicate propagatesAbnormal(AstNode child) { none() } + } + class BlockExprTree extends StandardPostOrderTree, BlockExpr { - override AstNode getChildNode(int i) { - result = this.getStmtList().getStatement(i) - or - i = this.getStmtList().getNumberOfStatements() and - result = this.getStmtList().getTailExpr() - } + BlockExprTree() { not this.isAsync() } + + override AstNode getChildNode(int i) { result = getBlockChildNode(this, i) } override predicate propagatesAbnormal(AstNode child) { child = this.getChildNode(_) } } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll index 48b730cb7fc0..925675c17350 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll @@ -5,11 +5,32 @@ private import codeql.rust.elements.internal.generated.ParentChild /** * A control-flow graph (CFG) scope. - * - * A CFG scope is a callable with a body. */ -class CfgScope extends Callable { - CfgScope() { +abstract private class CfgScopeImpl extends AstNode { + abstract predicate scopeFirst(AstNode first); + + abstract predicate scopeLast(AstNode last, Completion c); +} + +final class CfgScope = CfgScopeImpl; + +class AsyncBlockScope extends CfgScopeImpl, BlockExpr { + AsyncBlockScope() { this.isAsync() } + + override predicate scopeFirst(AstNode first) { + first(this.(ExprTrees::AsyncBlockExprTree).getFirstChildNode(), first) + } + + override predicate scopeLast(AstNode last, Completion c) { + last(this.(ExprTrees::AsyncBlockExprTree).getLastChildElement(), last, c) + } +} + +/** + * A CFG scope for a callable (a function or a closure) with a body. + */ +class CallableScope extends CfgScopeImpl, Callable { + CallableScope() { // A function without a body corresponds to a trait method signature and // should not have a CFG scope. this.(Function).hasBody() @@ -23,4 +44,11 @@ class CfgScope extends Callable { or result = this.(ClosureExpr).getBody() } + + override predicate scopeFirst(AstNode first) { + first(this.(CallableScopeTree).getFirstChildNode(), first) + } + + /** Holds if `scope` is exited when `last` finishes with completion `c`. */ + override predicate scopeLast(AstNode last, Completion c) { last(this.getBody(), last, c) } } diff --git a/rust/ql/lib/codeql/rust/elements/AsyncBlockExpr.qll b/rust/ql/lib/codeql/rust/elements/AsyncBlockExpr.qll new file mode 100644 index 000000000000..e590f999c9ac --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/AsyncBlockExpr.qll @@ -0,0 +1,13 @@ +private import codeql.rust.elements.BlockExpr + +/** + * A async block expression. For example: + * ```rust + * async { + * let x = 42; + * } + * ``` + */ +final class AsyncBlockExpr extends BlockExpr { + AsyncBlockExpr() { this.isAsync() } +} diff --git a/rust/ql/lib/rust.qll b/rust/ql/lib/rust.qll index c61e177883ea..ff97a37b5d1f 100644 --- a/rust/ql/lib/rust.qll +++ b/rust/ql/lib/rust.qll @@ -5,6 +5,7 @@ import codeql.Locations import codeql.files.FileSystem import codeql.rust.elements.AssignmentOperation import codeql.rust.elements.LogicalOperation +import codeql.rust.elements.AsyncBlockExpr import codeql.rust.elements.Variable import codeql.rust.elements.NamedFormatArgument import codeql.rust.elements.PositionalFormatArgument diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 9dafa30db1f3..c3a938d67cad 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -781,10 +781,12 @@ edges | test.rs:372:5:384:5 | enter async_block | test.rs:373:9:375:10 | LetStmt | | | test.rs:372:5:384:5 | exit async_block (normal) | test.rs:372:5:384:5 | exit async_block | | | test.rs:372:28:384:5 | BlockExpr | test.rs:372:5:384:5 | exit async_block (normal) | | -| test.rs:373:9:375:10 | LetStmt | test.rs:374:13:374:42 | ExprStmt | | +| test.rs:373:9:375:10 | LetStmt | test.rs:373:26:375:9 | BlockExpr | | | test.rs:373:13:373:22 | say_godbye | test.rs:376:9:378:10 | LetStmt | match | | test.rs:373:26:375:9 | BlockExpr | test.rs:373:13:373:22 | say_godbye | | -| test.rs:374:13:374:41 | MacroExpr | test.rs:373:26:375:9 | BlockExpr | | +| test.rs:373:26:375:9 | enter BlockExpr | test.rs:374:13:374:42 | ExprStmt | | +| test.rs:373:26:375:9 | exit BlockExpr (normal) | test.rs:373:26:375:9 | exit BlockExpr | | +| test.rs:374:13:374:41 | MacroExpr | test.rs:373:26:375:9 | exit BlockExpr (normal) | | | test.rs:374:13:374:41 | PathExpr | test.rs:374:22:374:40 | "godbye, everyone!\\n" | | | test.rs:374:13:374:42 | ExprStmt | test.rs:374:22:374:40 | MacroStmts | | | test.rs:374:22:374:40 | "godbye, everyone!\\n" | test.rs:374:22:374:40 | FormatArgsExpr | | @@ -794,10 +796,12 @@ edges | test.rs:374:22:374:40 | FormatArgsExpr | test.rs:374:22:374:40 | MacroExpr | | | test.rs:374:22:374:40 | MacroExpr | test.rs:374:22:374:40 | CallExpr | | | test.rs:374:22:374:40 | MacroStmts | test.rs:374:22:374:40 | ExprStmt | | -| test.rs:376:9:378:10 | LetStmt | test.rs:377:13:377:37 | ExprStmt | | +| test.rs:376:9:378:10 | LetStmt | test.rs:376:31:378:9 | BlockExpr | | | test.rs:376:13:376:27 | say_how_are_you | test.rs:379:9:379:28 | LetStmt | match | | test.rs:376:31:378:9 | BlockExpr | test.rs:376:13:376:27 | say_how_are_you | | -| test.rs:377:13:377:36 | MacroExpr | test.rs:376:31:378:9 | BlockExpr | | +| test.rs:376:31:378:9 | enter BlockExpr | test.rs:377:13:377:37 | ExprStmt | | +| test.rs:376:31:378:9 | exit BlockExpr (normal) | test.rs:376:31:378:9 | exit BlockExpr | | +| test.rs:377:13:377:36 | MacroExpr | test.rs:376:31:378:9 | exit BlockExpr (normal) | | | test.rs:377:13:377:36 | PathExpr | test.rs:377:22:377:35 | "how are you?\\n" | | | test.rs:377:13:377:37 | ExprStmt | test.rs:377:22:377:35 | MacroStmts | | | test.rs:377:22:377:35 | "how are you?\\n" | test.rs:377:22:377:35 | FormatArgsExpr | | From 74a6d9812d303722cd7a7dd5211ea2755235b875 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Sun, 10 Nov 2024 11:33:03 +0100 Subject: [PATCH 3/8] Rust: Add SSA test for async blocks --- .../CONSISTENCY/DataFlowConsistency.expected | 104 ++-- .../test/library-tests/variables/Cfg.expected | 589 +++++++++--------- .../test/library-tests/variables/Ssa.expected | 136 ++-- .../variables/variables.expected | 142 +++-- .../test/library-tests/variables/variables.rs | 11 + 5 files changed, 520 insertions(+), 462 deletions(-) diff --git a/rust/ql/test/library-tests/variables/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/library-tests/variables/CONSISTENCY/DataFlowConsistency.expected index bb4e17c24372..ca9c3207ffce 100644 --- a/rust/ql/test/library-tests/variables/CONSISTENCY/DataFlowConsistency.expected +++ b/rust/ql/test/library-tests/variables/CONSISTENCY/DataFlowConsistency.expected @@ -92,54 +92,56 @@ uniqueCallEnclosingCallable | variables.rs:424:5:424:16 | CallExpr | Call should have one enclosing callable but has 0. | | variables.rs:431:5:431:14 | CallExpr | Call should have one enclosing callable but has 0. | | variables.rs:432:5:432:16 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:437:5:437:16 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:438:5:438:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:441:9:441:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:442:9:442:24 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:445:9:445:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:446:9:446:24 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:448:5:448:16 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:454:9:454:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:456:9:456:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:460:9:460:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:462:9:462:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:479:5:479:25 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:481:5:481:25 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:483:5:483:25 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:488:5:488:21 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:489:5:489:16 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:492:5:492:21 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:509:3:509:18 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:513:5:513:24 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:514:5:514:22 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:515:5:515:39 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:516:5:516:22 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:517:5:517:22 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:518:5:518:18 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:519:5:519:18 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:520:5:520:18 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:521:5:521:18 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:522:5:522:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:523:5:523:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:524:5:524:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:525:5:525:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:526:5:526:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:527:5:527:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:528:5:528:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:529:5:529:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:530:5:530:20 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:531:5:531:35 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:532:5:532:36 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:532:20:532:35 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:533:5:533:25 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:534:5:534:22 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:535:5:535:18 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:536:5:536:16 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:537:5:537:12 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:538:5:538:16 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:539:5:539:11 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:540:5:540:17 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:541:5:541:19 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:542:5:542:13 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:543:5:543:13 | CallExpr | Call should have one enclosing callable but has 0. | -| variables.rs:544:5:544:29 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:442:5:442:16 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:447:5:447:16 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:448:5:448:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:451:9:451:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:452:9:452:24 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:455:9:455:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:456:9:456:24 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:458:5:458:16 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:464:9:464:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:466:9:466:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:470:9:470:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:472:9:472:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:489:5:489:25 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:491:5:491:25 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:493:5:493:25 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:498:5:498:21 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:499:5:499:16 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:502:5:502:21 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:519:3:519:18 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:523:5:523:24 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:524:5:524:22 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:525:5:525:39 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:526:5:526:22 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:527:5:527:22 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:528:5:528:18 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:529:5:529:18 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:530:5:530:18 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:531:5:531:18 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:532:5:532:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:533:5:533:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:534:5:534:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:535:5:535:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:536:5:536:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:537:5:537:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:538:5:538:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:539:5:539:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:540:5:540:20 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:541:5:541:35 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:542:5:542:36 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:542:20:542:35 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:543:5:543:25 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:544:5:544:22 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:545:5:545:18 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:546:5:546:16 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:547:5:547:12 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:548:5:548:16 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:549:5:549:11 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:550:5:550:17 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:551:5:551:19 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:552:5:552:25 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:553:5:553:13 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:554:5:554:13 | CallExpr | Call should have one enclosing callable but has 0. | +| variables.rs:555:5:555:29 | CallExpr | Call should have one enclosing callable but has 0. | diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 646ef9351116..c7b122e2ab0e 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -955,289 +955,314 @@ edges | variables.rs:432:5:432:16 | CallExpr | variables.rs:409:18:433:1 | BlockExpr | | | variables.rs:432:5:432:17 | ExprStmt | variables.rs:432:5:432:13 | PathExpr | | | variables.rs:432:15:432:15 | z | variables.rs:432:5:432:16 | CallExpr | | -| variables.rs:435:1:449:1 | enter phi | variables.rs:435:8:435:8 | b | | -| variables.rs:435:1:449:1 | exit phi (normal) | variables.rs:435:1:449:1 | exit phi | | -| variables.rs:435:8:435:8 | b | variables.rs:435:8:435:15 | Param | match | -| variables.rs:435:8:435:15 | Param | variables.rs:436:5:436:18 | LetStmt | | -| variables.rs:435:18:449:1 | BlockExpr | variables.rs:435:1:449:1 | exit phi (normal) | | -| variables.rs:436:5:436:18 | LetStmt | variables.rs:436:17:436:17 | 1 | | -| variables.rs:436:9:436:13 | x | variables.rs:437:5:437:17 | ExprStmt | match | -| variables.rs:436:17:436:17 | 1 | variables.rs:436:9:436:13 | x | | -| variables.rs:437:5:437:13 | PathExpr | variables.rs:437:15:437:15 | x | | -| variables.rs:437:5:437:16 | CallExpr | variables.rs:438:5:438:21 | ExprStmt | | -| variables.rs:437:5:437:17 | ExprStmt | variables.rs:437:5:437:13 | PathExpr | | -| variables.rs:437:15:437:15 | x | variables.rs:437:5:437:16 | CallExpr | | -| variables.rs:438:5:438:13 | PathExpr | variables.rs:438:15:438:15 | x | | -| variables.rs:438:5:438:20 | CallExpr | variables.rs:439:5:447:5 | ExprStmt | | -| variables.rs:438:5:438:21 | ExprStmt | variables.rs:438:5:438:13 | PathExpr | | -| variables.rs:438:15:438:15 | x | variables.rs:438:19:438:19 | 1 | | -| variables.rs:438:15:438:19 | ... + ... | variables.rs:438:5:438:20 | CallExpr | | -| variables.rs:438:19:438:19 | 1 | variables.rs:438:15:438:19 | ... + ... | | -| variables.rs:439:5:447:5 | ExprStmt | variables.rs:439:8:439:8 | b | | -| variables.rs:439:5:447:5 | IfExpr | variables.rs:448:5:448:17 | ExprStmt | | -| variables.rs:439:8:439:8 | b | variables.rs:440:9:440:14 | ExprStmt | true | -| variables.rs:439:8:439:8 | b | variables.rs:444:9:444:14 | ExprStmt | false | -| variables.rs:439:10:443:5 | BlockExpr | variables.rs:439:5:447:5 | IfExpr | | -| variables.rs:440:9:440:9 | x | variables.rs:440:13:440:13 | 2 | | -| variables.rs:440:9:440:13 | ... = ... | variables.rs:441:9:441:21 | ExprStmt | | -| variables.rs:440:9:440:14 | ExprStmt | variables.rs:440:9:440:9 | x | | -| variables.rs:440:13:440:13 | 2 | variables.rs:440:9:440:13 | ... = ... | | -| variables.rs:441:9:441:17 | PathExpr | variables.rs:441:19:441:19 | x | | -| variables.rs:441:9:441:20 | CallExpr | variables.rs:442:9:442:25 | ExprStmt | | -| variables.rs:441:9:441:21 | ExprStmt | variables.rs:441:9:441:17 | PathExpr | | -| variables.rs:441:19:441:19 | x | variables.rs:441:9:441:20 | CallExpr | | -| variables.rs:442:9:442:17 | PathExpr | variables.rs:442:19:442:19 | x | | -| variables.rs:442:9:442:24 | CallExpr | variables.rs:439:10:443:5 | BlockExpr | | -| variables.rs:442:9:442:25 | ExprStmt | variables.rs:442:9:442:17 | PathExpr | | -| variables.rs:442:19:442:19 | x | variables.rs:442:23:442:23 | 1 | | -| variables.rs:442:19:442:23 | ... + ... | variables.rs:442:9:442:24 | CallExpr | | -| variables.rs:442:23:442:23 | 1 | variables.rs:442:19:442:23 | ... + ... | | -| variables.rs:443:12:447:5 | BlockExpr | variables.rs:439:5:447:5 | IfExpr | | -| variables.rs:444:9:444:9 | x | variables.rs:444:13:444:13 | 3 | | -| variables.rs:444:9:444:13 | ... = ... | variables.rs:445:9:445:21 | ExprStmt | | -| variables.rs:444:9:444:14 | ExprStmt | variables.rs:444:9:444:9 | x | | -| variables.rs:444:13:444:13 | 3 | variables.rs:444:9:444:13 | ... = ... | | -| variables.rs:445:9:445:17 | PathExpr | variables.rs:445:19:445:19 | x | | -| variables.rs:445:9:445:20 | CallExpr | variables.rs:446:9:446:25 | ExprStmt | | -| variables.rs:445:9:445:21 | ExprStmt | variables.rs:445:9:445:17 | PathExpr | | -| variables.rs:445:19:445:19 | x | variables.rs:445:9:445:20 | CallExpr | | -| variables.rs:446:9:446:17 | PathExpr | variables.rs:446:19:446:19 | x | | -| variables.rs:446:9:446:24 | CallExpr | variables.rs:443:12:447:5 | BlockExpr | | -| variables.rs:446:9:446:25 | ExprStmt | variables.rs:446:9:446:17 | PathExpr | | -| variables.rs:446:19:446:19 | x | variables.rs:446:23:446:23 | 1 | | -| variables.rs:446:19:446:23 | ... + ... | variables.rs:446:9:446:24 | CallExpr | | -| variables.rs:446:23:446:23 | 1 | variables.rs:446:19:446:23 | ... + ... | | +| variables.rs:435:1:443:1 | enter async_block_capture | variables.rs:436:5:436:23 | LetStmt | | +| variables.rs:435:1:443:1 | exit async_block_capture (normal) | variables.rs:435:1:443:1 | exit async_block_capture | | +| variables.rs:435:32:443:1 | BlockExpr | variables.rs:435:1:443:1 | exit async_block_capture (normal) | | +| variables.rs:436:5:436:23 | LetStmt | variables.rs:436:22:436:22 | 0 | | +| variables.rs:436:9:436:13 | i | variables.rs:437:5:439:6 | LetStmt | match | +| variables.rs:436:22:436:22 | 0 | variables.rs:436:9:436:13 | i | | +| variables.rs:437:5:439:6 | LetStmt | variables.rs:437:17:439:5 | BlockExpr | | +| variables.rs:437:9:437:13 | block | variables.rs:441:5:441:16 | ExprStmt | match | +| variables.rs:437:17:439:5 | BlockExpr | variables.rs:437:9:437:13 | block | | +| variables.rs:437:17:439:5 | enter BlockExpr | variables.rs:438:9:438:14 | ExprStmt | | +| variables.rs:437:17:439:5 | exit BlockExpr (normal) | variables.rs:437:17:439:5 | exit BlockExpr | | +| variables.rs:438:9:438:9 | i | variables.rs:438:13:438:13 | 1 | | +| variables.rs:438:9:438:13 | ... = ... | variables.rs:437:17:439:5 | exit BlockExpr (normal) | | +| variables.rs:438:9:438:14 | ExprStmt | variables.rs:438:9:438:9 | i | | +| variables.rs:438:13:438:13 | 1 | variables.rs:438:9:438:13 | ... = ... | | +| variables.rs:441:5:441:9 | block | variables.rs:441:5:441:15 | AwaitExpr | | +| variables.rs:441:5:441:15 | AwaitExpr | variables.rs:442:5:442:17 | ExprStmt | | +| variables.rs:441:5:441:16 | ExprStmt | variables.rs:441:5:441:9 | block | | +| variables.rs:442:5:442:13 | PathExpr | variables.rs:442:15:442:15 | i | | +| variables.rs:442:5:442:16 | CallExpr | variables.rs:435:32:443:1 | BlockExpr | | +| variables.rs:442:5:442:17 | ExprStmt | variables.rs:442:5:442:13 | PathExpr | | +| variables.rs:442:15:442:15 | i | variables.rs:442:5:442:16 | CallExpr | | +| variables.rs:445:1:459:1 | enter phi | variables.rs:445:8:445:8 | b | | +| variables.rs:445:1:459:1 | exit phi (normal) | variables.rs:445:1:459:1 | exit phi | | +| variables.rs:445:8:445:8 | b | variables.rs:445:8:445:15 | Param | match | +| variables.rs:445:8:445:15 | Param | variables.rs:446:5:446:18 | LetStmt | | +| variables.rs:445:18:459:1 | BlockExpr | variables.rs:445:1:459:1 | exit phi (normal) | | +| variables.rs:446:5:446:18 | LetStmt | variables.rs:446:17:446:17 | 1 | | +| variables.rs:446:9:446:13 | x | variables.rs:447:5:447:17 | ExprStmt | match | +| variables.rs:446:17:446:17 | 1 | variables.rs:446:9:446:13 | x | | +| variables.rs:447:5:447:13 | PathExpr | variables.rs:447:15:447:15 | x | | +| variables.rs:447:5:447:16 | CallExpr | variables.rs:448:5:448:21 | ExprStmt | | +| variables.rs:447:5:447:17 | ExprStmt | variables.rs:447:5:447:13 | PathExpr | | +| variables.rs:447:15:447:15 | x | variables.rs:447:5:447:16 | CallExpr | | | variables.rs:448:5:448:13 | PathExpr | variables.rs:448:15:448:15 | x | | -| variables.rs:448:5:448:16 | CallExpr | variables.rs:435:18:449:1 | BlockExpr | | -| variables.rs:448:5:448:17 | ExprStmt | variables.rs:448:5:448:13 | PathExpr | | -| variables.rs:448:15:448:15 | x | variables.rs:448:5:448:16 | CallExpr | | -| variables.rs:451:1:464:1 | enter phi_read | variables.rs:451:13:451:14 | b1 | | -| variables.rs:451:1:464:1 | exit phi_read (normal) | variables.rs:451:1:464:1 | exit phi_read | | -| variables.rs:451:13:451:14 | b1 | variables.rs:451:13:451:21 | Param | match | -| variables.rs:451:13:451:21 | Param | variables.rs:451:24:451:25 | b2 | | -| variables.rs:451:24:451:25 | b2 | variables.rs:451:24:451:32 | Param | match | -| variables.rs:451:24:451:32 | Param | variables.rs:452:5:452:14 | LetStmt | | -| variables.rs:451:35:464:1 | BlockExpr | variables.rs:451:1:464:1 | exit phi_read (normal) | | -| variables.rs:452:5:452:14 | LetStmt | variables.rs:452:13:452:13 | 1 | | -| variables.rs:452:9:452:9 | x | variables.rs:453:5:457:5 | ExprStmt | match | -| variables.rs:452:13:452:13 | 1 | variables.rs:452:9:452:9 | x | | -| variables.rs:453:5:457:5 | ExprStmt | variables.rs:453:8:453:9 | b1 | | -| variables.rs:453:5:457:5 | IfExpr | variables.rs:459:8:459:9 | b2 | | -| variables.rs:453:8:453:9 | b1 | variables.rs:454:9:454:21 | ExprStmt | true | -| variables.rs:453:8:453:9 | b1 | variables.rs:456:9:456:21 | ExprStmt | false | -| variables.rs:453:11:455:5 | BlockExpr | variables.rs:453:5:457:5 | IfExpr | | -| variables.rs:454:9:454:17 | PathExpr | variables.rs:454:19:454:19 | x | | -| variables.rs:454:9:454:20 | CallExpr | variables.rs:453:11:455:5 | BlockExpr | | -| variables.rs:454:9:454:21 | ExprStmt | variables.rs:454:9:454:17 | PathExpr | | -| variables.rs:454:19:454:19 | x | variables.rs:454:9:454:20 | CallExpr | | -| variables.rs:455:12:457:5 | BlockExpr | variables.rs:453:5:457:5 | IfExpr | | +| variables.rs:448:5:448:20 | CallExpr | variables.rs:449:5:457:5 | ExprStmt | | +| variables.rs:448:5:448:21 | ExprStmt | variables.rs:448:5:448:13 | PathExpr | | +| variables.rs:448:15:448:15 | x | variables.rs:448:19:448:19 | 1 | | +| variables.rs:448:15:448:19 | ... + ... | variables.rs:448:5:448:20 | CallExpr | | +| variables.rs:448:19:448:19 | 1 | variables.rs:448:15:448:19 | ... + ... | | +| variables.rs:449:5:457:5 | ExprStmt | variables.rs:449:8:449:8 | b | | +| variables.rs:449:5:457:5 | IfExpr | variables.rs:458:5:458:17 | ExprStmt | | +| variables.rs:449:8:449:8 | b | variables.rs:450:9:450:14 | ExprStmt | true | +| variables.rs:449:8:449:8 | b | variables.rs:454:9:454:14 | ExprStmt | false | +| variables.rs:449:10:453:5 | BlockExpr | variables.rs:449:5:457:5 | IfExpr | | +| variables.rs:450:9:450:9 | x | variables.rs:450:13:450:13 | 2 | | +| variables.rs:450:9:450:13 | ... = ... | variables.rs:451:9:451:21 | ExprStmt | | +| variables.rs:450:9:450:14 | ExprStmt | variables.rs:450:9:450:9 | x | | +| variables.rs:450:13:450:13 | 2 | variables.rs:450:9:450:13 | ... = ... | | +| variables.rs:451:9:451:17 | PathExpr | variables.rs:451:19:451:19 | x | | +| variables.rs:451:9:451:20 | CallExpr | variables.rs:452:9:452:25 | ExprStmt | | +| variables.rs:451:9:451:21 | ExprStmt | variables.rs:451:9:451:17 | PathExpr | | +| variables.rs:451:19:451:19 | x | variables.rs:451:9:451:20 | CallExpr | | +| variables.rs:452:9:452:17 | PathExpr | variables.rs:452:19:452:19 | x | | +| variables.rs:452:9:452:24 | CallExpr | variables.rs:449:10:453:5 | BlockExpr | | +| variables.rs:452:9:452:25 | ExprStmt | variables.rs:452:9:452:17 | PathExpr | | +| variables.rs:452:19:452:19 | x | variables.rs:452:23:452:23 | 1 | | +| variables.rs:452:19:452:23 | ... + ... | variables.rs:452:9:452:24 | CallExpr | | +| variables.rs:452:23:452:23 | 1 | variables.rs:452:19:452:23 | ... + ... | | +| variables.rs:453:12:457:5 | BlockExpr | variables.rs:449:5:457:5 | IfExpr | | +| variables.rs:454:9:454:9 | x | variables.rs:454:13:454:13 | 3 | | +| variables.rs:454:9:454:13 | ... = ... | variables.rs:455:9:455:21 | ExprStmt | | +| variables.rs:454:9:454:14 | ExprStmt | variables.rs:454:9:454:9 | x | | +| variables.rs:454:13:454:13 | 3 | variables.rs:454:9:454:13 | ... = ... | | +| variables.rs:455:9:455:17 | PathExpr | variables.rs:455:19:455:19 | x | | +| variables.rs:455:9:455:20 | CallExpr | variables.rs:456:9:456:25 | ExprStmt | | +| variables.rs:455:9:455:21 | ExprStmt | variables.rs:455:9:455:17 | PathExpr | | +| variables.rs:455:19:455:19 | x | variables.rs:455:9:455:20 | CallExpr | | | variables.rs:456:9:456:17 | PathExpr | variables.rs:456:19:456:19 | x | | -| variables.rs:456:9:456:20 | CallExpr | variables.rs:455:12:457:5 | BlockExpr | | -| variables.rs:456:9:456:21 | ExprStmt | variables.rs:456:9:456:17 | PathExpr | | -| variables.rs:456:19:456:19 | x | variables.rs:456:9:456:20 | CallExpr | | -| variables.rs:459:5:463:5 | IfExpr | variables.rs:451:35:464:1 | BlockExpr | | -| variables.rs:459:8:459:9 | b2 | variables.rs:460:9:460:21 | ExprStmt | true | -| variables.rs:459:8:459:9 | b2 | variables.rs:462:9:462:21 | ExprStmt | false | -| variables.rs:459:11:461:5 | BlockExpr | variables.rs:459:5:463:5 | IfExpr | | -| variables.rs:460:9:460:17 | PathExpr | variables.rs:460:19:460:19 | x | | -| variables.rs:460:9:460:20 | CallExpr | variables.rs:459:11:461:5 | BlockExpr | | -| variables.rs:460:9:460:21 | ExprStmt | variables.rs:460:9:460:17 | PathExpr | | -| variables.rs:460:19:460:19 | x | variables.rs:460:9:460:20 | CallExpr | | -| variables.rs:461:12:463:5 | BlockExpr | variables.rs:459:5:463:5 | IfExpr | | -| variables.rs:462:9:462:17 | PathExpr | variables.rs:462:19:462:19 | x | | -| variables.rs:462:9:462:20 | CallExpr | variables.rs:461:12:463:5 | BlockExpr | | -| variables.rs:462:9:462:21 | ExprStmt | variables.rs:462:9:462:17 | PathExpr | | -| variables.rs:462:19:462:19 | x | variables.rs:462:9:462:20 | CallExpr | | -| variables.rs:472:5:474:5 | enter my_get | variables.rs:473:9:473:24 | ExprStmt | | -| variables.rs:472:5:474:5 | exit my_get (normal) | variables.rs:472:5:474:5 | exit my_get | | -| variables.rs:473:9:473:23 | ReturnExpr | variables.rs:472:5:474:5 | exit my_get (normal) | return | -| variables.rs:473:9:473:24 | ExprStmt | variables.rs:473:16:473:19 | PathExpr | | -| variables.rs:473:16:473:19 | PathExpr | variables.rs:473:16:473:23 | FieldExpr | | -| variables.rs:473:16:473:23 | FieldExpr | variables.rs:473:9:473:23 | ReturnExpr | | -| variables.rs:477:1:484:1 | enter structs | variables.rs:478:5:478:36 | LetStmt | | -| variables.rs:477:1:484:1 | exit structs (normal) | variables.rs:477:1:484:1 | exit structs | | -| variables.rs:477:14:484:1 | BlockExpr | variables.rs:477:1:484:1 | exit structs (normal) | | -| variables.rs:478:5:478:36 | LetStmt | variables.rs:478:33:478:33 | 1 | | -| variables.rs:478:9:478:13 | a | variables.rs:479:5:479:26 | ExprStmt | match | -| variables.rs:478:17:478:35 | RecordExpr | variables.rs:478:9:478:13 | a | | -| variables.rs:478:33:478:33 | 1 | variables.rs:478:17:478:35 | RecordExpr | | -| variables.rs:479:5:479:13 | PathExpr | variables.rs:479:15:479:15 | a | | -| variables.rs:479:5:479:25 | CallExpr | variables.rs:480:5:480:14 | ExprStmt | | -| variables.rs:479:5:479:26 | ExprStmt | variables.rs:479:5:479:13 | PathExpr | | -| variables.rs:479:15:479:15 | a | variables.rs:479:15:479:24 | ... .my_get(...) | | -| variables.rs:479:15:479:24 | ... .my_get(...) | variables.rs:479:5:479:25 | CallExpr | | -| variables.rs:480:5:480:5 | a | variables.rs:480:5:480:9 | FieldExpr | | -| variables.rs:480:5:480:9 | FieldExpr | variables.rs:480:13:480:13 | 5 | | -| variables.rs:480:5:480:13 | ... = ... | variables.rs:481:5:481:26 | ExprStmt | | -| variables.rs:480:5:480:14 | ExprStmt | variables.rs:480:5:480:5 | a | | -| variables.rs:480:13:480:13 | 5 | variables.rs:480:5:480:13 | ... = ... | | -| variables.rs:481:5:481:13 | PathExpr | variables.rs:481:15:481:15 | a | | -| variables.rs:481:5:481:25 | CallExpr | variables.rs:482:5:482:28 | ExprStmt | | -| variables.rs:481:5:481:26 | ExprStmt | variables.rs:481:5:481:13 | PathExpr | | -| variables.rs:481:15:481:15 | a | variables.rs:481:15:481:24 | ... .my_get(...) | | -| variables.rs:481:15:481:24 | ... .my_get(...) | variables.rs:481:5:481:25 | CallExpr | | -| variables.rs:482:5:482:5 | a | variables.rs:482:25:482:25 | 2 | | -| variables.rs:482:5:482:27 | ... = ... | variables.rs:483:5:483:26 | ExprStmt | | -| variables.rs:482:5:482:28 | ExprStmt | variables.rs:482:5:482:5 | a | | -| variables.rs:482:9:482:27 | RecordExpr | variables.rs:482:5:482:27 | ... = ... | | -| variables.rs:482:25:482:25 | 2 | variables.rs:482:9:482:27 | RecordExpr | | -| variables.rs:483:5:483:13 | PathExpr | variables.rs:483:15:483:15 | a | | -| variables.rs:483:5:483:25 | CallExpr | variables.rs:477:14:484:1 | BlockExpr | | -| variables.rs:483:5:483:26 | ExprStmt | variables.rs:483:5:483:13 | PathExpr | | -| variables.rs:483:15:483:15 | a | variables.rs:483:15:483:24 | ... .my_get(...) | | -| variables.rs:483:15:483:24 | ... .my_get(...) | variables.rs:483:5:483:25 | CallExpr | | -| variables.rs:486:1:493:1 | enter ref_arg | variables.rs:487:5:487:15 | LetStmt | | -| variables.rs:486:1:493:1 | exit ref_arg (normal) | variables.rs:486:1:493:1 | exit ref_arg | | -| variables.rs:486:14:493:1 | BlockExpr | variables.rs:486:1:493:1 | exit ref_arg (normal) | | -| variables.rs:487:5:487:15 | LetStmt | variables.rs:487:13:487:14 | 16 | | -| variables.rs:487:9:487:9 | x | variables.rs:488:5:488:22 | ExprStmt | match | -| variables.rs:487:13:487:14 | 16 | variables.rs:487:9:487:9 | x | | -| variables.rs:488:5:488:17 | PathExpr | variables.rs:488:20:488:20 | x | | -| variables.rs:488:5:488:21 | CallExpr | variables.rs:489:5:489:17 | ExprStmt | | -| variables.rs:488:5:488:22 | ExprStmt | variables.rs:488:5:488:17 | PathExpr | | -| variables.rs:488:19:488:20 | RefExpr | variables.rs:488:5:488:21 | CallExpr | | -| variables.rs:488:20:488:20 | x | variables.rs:488:19:488:20 | RefExpr | | -| variables.rs:489:5:489:13 | PathExpr | variables.rs:489:15:489:15 | x | | -| variables.rs:489:5:489:16 | CallExpr | variables.rs:491:5:491:15 | LetStmt | | -| variables.rs:489:5:489:17 | ExprStmt | variables.rs:489:5:489:13 | PathExpr | | -| variables.rs:489:15:489:15 | x | variables.rs:489:5:489:16 | CallExpr | | -| variables.rs:491:5:491:15 | LetStmt | variables.rs:491:13:491:14 | 17 | | -| variables.rs:491:9:491:9 | z | variables.rs:492:5:492:22 | ExprStmt | match | -| variables.rs:491:13:491:14 | 17 | variables.rs:491:9:491:9 | z | | -| variables.rs:492:5:492:17 | PathExpr | variables.rs:492:20:492:20 | z | | -| variables.rs:492:5:492:21 | CallExpr | variables.rs:486:14:493:1 | BlockExpr | | -| variables.rs:492:5:492:22 | ExprStmt | variables.rs:492:5:492:17 | PathExpr | | -| variables.rs:492:19:492:20 | RefExpr | variables.rs:492:5:492:21 | CallExpr | | -| variables.rs:492:20:492:20 | z | variables.rs:492:19:492:20 | RefExpr | | -| variables.rs:500:3:502:3 | enter bar | variables.rs:501:5:501:32 | ExprStmt | | -| variables.rs:500:3:502:3 | exit bar (normal) | variables.rs:500:3:502:3 | exit bar | | -| variables.rs:500:21:502:3 | BlockExpr | variables.rs:500:3:502:3 | exit bar (normal) | | -| variables.rs:501:5:501:9 | * ... | variables.rs:501:29:501:29 | 3 | | -| variables.rs:501:5:501:31 | ... = ... | variables.rs:500:21:502:3 | BlockExpr | | -| variables.rs:501:5:501:32 | ExprStmt | variables.rs:501:6:501:9 | PathExpr | | -| variables.rs:501:6:501:9 | PathExpr | variables.rs:501:5:501:9 | * ... | | -| variables.rs:501:13:501:31 | RecordExpr | variables.rs:501:5:501:31 | ... = ... | | -| variables.rs:501:29:501:29 | 3 | variables.rs:501:13:501:31 | RecordExpr | | -| variables.rs:505:1:510:1 | enter ref_methodcall_receiver | variables.rs:506:3:506:34 | LetStmt | | -| variables.rs:505:1:510:1 | exit ref_methodcall_receiver (normal) | variables.rs:505:1:510:1 | exit ref_methodcall_receiver | | -| variables.rs:505:30:510:1 | BlockExpr | variables.rs:505:1:510:1 | exit ref_methodcall_receiver (normal) | | -| variables.rs:506:3:506:34 | LetStmt | variables.rs:506:31:506:31 | 1 | | -| variables.rs:506:7:506:11 | a | variables.rs:507:3:507:10 | ExprStmt | match | -| variables.rs:506:15:506:33 | RecordExpr | variables.rs:506:7:506:11 | a | | -| variables.rs:506:31:506:31 | 1 | variables.rs:506:15:506:33 | RecordExpr | | -| variables.rs:507:3:507:3 | a | variables.rs:507:3:507:9 | ... .bar(...) | | -| variables.rs:507:3:507:9 | ... .bar(...) | variables.rs:509:3:509:19 | ExprStmt | | -| variables.rs:507:3:507:10 | ExprStmt | variables.rs:507:3:507:3 | a | | -| variables.rs:509:3:509:11 | PathExpr | variables.rs:509:13:509:13 | a | | -| variables.rs:509:3:509:18 | CallExpr | variables.rs:505:30:510:1 | BlockExpr | | -| variables.rs:509:3:509:19 | ExprStmt | variables.rs:509:3:509:11 | PathExpr | | -| variables.rs:509:13:509:13 | a | variables.rs:509:13:509:17 | FieldExpr | | -| variables.rs:509:13:509:17 | FieldExpr | variables.rs:509:3:509:18 | CallExpr | | -| variables.rs:512:1:545:1 | enter main | variables.rs:513:5:513:25 | ExprStmt | | -| variables.rs:512:1:545:1 | exit main (normal) | variables.rs:512:1:545:1 | exit main | | -| variables.rs:512:11:545:1 | BlockExpr | variables.rs:512:1:545:1 | exit main (normal) | | -| variables.rs:513:5:513:22 | PathExpr | variables.rs:513:5:513:24 | CallExpr | | -| variables.rs:513:5:513:24 | CallExpr | variables.rs:514:5:514:23 | ExprStmt | | -| variables.rs:513:5:513:25 | ExprStmt | variables.rs:513:5:513:22 | PathExpr | | -| variables.rs:514:5:514:20 | PathExpr | variables.rs:514:5:514:22 | CallExpr | | -| variables.rs:514:5:514:22 | CallExpr | variables.rs:515:5:515:40 | ExprStmt | | -| variables.rs:514:5:514:23 | ExprStmt | variables.rs:514:5:514:20 | PathExpr | | -| variables.rs:515:5:515:37 | PathExpr | variables.rs:515:5:515:39 | CallExpr | | -| variables.rs:515:5:515:39 | CallExpr | variables.rs:516:5:516:23 | ExprStmt | | -| variables.rs:515:5:515:40 | ExprStmt | variables.rs:515:5:515:37 | PathExpr | | -| variables.rs:516:5:516:20 | PathExpr | variables.rs:516:5:516:22 | CallExpr | | -| variables.rs:516:5:516:22 | CallExpr | variables.rs:517:5:517:23 | ExprStmt | | -| variables.rs:516:5:516:23 | ExprStmt | variables.rs:516:5:516:20 | PathExpr | | -| variables.rs:517:5:517:20 | PathExpr | variables.rs:517:5:517:22 | CallExpr | | -| variables.rs:517:5:517:22 | CallExpr | variables.rs:518:5:518:19 | ExprStmt | | -| variables.rs:517:5:517:23 | ExprStmt | variables.rs:517:5:517:20 | PathExpr | | -| variables.rs:518:5:518:16 | PathExpr | variables.rs:518:5:518:18 | CallExpr | | -| variables.rs:518:5:518:18 | CallExpr | variables.rs:519:5:519:19 | ExprStmt | | -| variables.rs:518:5:518:19 | ExprStmt | variables.rs:518:5:518:16 | PathExpr | | -| variables.rs:519:5:519:16 | PathExpr | variables.rs:519:5:519:18 | CallExpr | | -| variables.rs:519:5:519:18 | CallExpr | variables.rs:520:5:520:19 | ExprStmt | | -| variables.rs:519:5:519:19 | ExprStmt | variables.rs:519:5:519:16 | PathExpr | | -| variables.rs:520:5:520:16 | PathExpr | variables.rs:520:5:520:18 | CallExpr | | -| variables.rs:520:5:520:18 | CallExpr | variables.rs:521:5:521:19 | ExprStmt | | -| variables.rs:520:5:520:19 | ExprStmt | variables.rs:520:5:520:16 | PathExpr | | -| variables.rs:521:5:521:16 | PathExpr | variables.rs:521:5:521:18 | CallExpr | | -| variables.rs:521:5:521:18 | CallExpr | variables.rs:522:5:522:21 | ExprStmt | | -| variables.rs:521:5:521:19 | ExprStmt | variables.rs:521:5:521:16 | PathExpr | | -| variables.rs:522:5:522:18 | PathExpr | variables.rs:522:5:522:20 | CallExpr | | -| variables.rs:522:5:522:20 | CallExpr | variables.rs:523:5:523:21 | ExprStmt | | -| variables.rs:522:5:522:21 | ExprStmt | variables.rs:522:5:522:18 | PathExpr | | -| variables.rs:523:5:523:18 | PathExpr | variables.rs:523:5:523:20 | CallExpr | | -| variables.rs:523:5:523:20 | CallExpr | variables.rs:524:5:524:21 | ExprStmt | | -| variables.rs:523:5:523:21 | ExprStmt | variables.rs:523:5:523:18 | PathExpr | | -| variables.rs:524:5:524:18 | PathExpr | variables.rs:524:5:524:20 | CallExpr | | -| variables.rs:524:5:524:20 | CallExpr | variables.rs:525:5:525:21 | ExprStmt | | -| variables.rs:524:5:524:21 | ExprStmt | variables.rs:524:5:524:18 | PathExpr | | -| variables.rs:525:5:525:18 | PathExpr | variables.rs:525:5:525:20 | CallExpr | | -| variables.rs:525:5:525:20 | CallExpr | variables.rs:526:5:526:21 | ExprStmt | | -| variables.rs:525:5:525:21 | ExprStmt | variables.rs:525:5:525:18 | PathExpr | | -| variables.rs:526:5:526:18 | PathExpr | variables.rs:526:5:526:20 | CallExpr | | -| variables.rs:526:5:526:20 | CallExpr | variables.rs:527:5:527:21 | ExprStmt | | -| variables.rs:526:5:526:21 | ExprStmt | variables.rs:526:5:526:18 | PathExpr | | -| variables.rs:527:5:527:18 | PathExpr | variables.rs:527:5:527:20 | CallExpr | | -| variables.rs:527:5:527:20 | CallExpr | variables.rs:528:5:528:21 | ExprStmt | | -| variables.rs:527:5:527:21 | ExprStmt | variables.rs:527:5:527:18 | PathExpr | | -| variables.rs:528:5:528:18 | PathExpr | variables.rs:528:5:528:20 | CallExpr | | -| variables.rs:528:5:528:20 | CallExpr | variables.rs:529:5:529:21 | ExprStmt | | -| variables.rs:528:5:528:21 | ExprStmt | variables.rs:528:5:528:18 | PathExpr | | -| variables.rs:529:5:529:18 | PathExpr | variables.rs:529:5:529:20 | CallExpr | | -| variables.rs:529:5:529:20 | CallExpr | variables.rs:530:5:530:21 | ExprStmt | | -| variables.rs:529:5:529:21 | ExprStmt | variables.rs:529:5:529:18 | PathExpr | | -| variables.rs:530:5:530:18 | PathExpr | variables.rs:530:5:530:20 | CallExpr | | -| variables.rs:530:5:530:20 | CallExpr | variables.rs:531:5:531:36 | ExprStmt | | -| variables.rs:530:5:530:21 | ExprStmt | variables.rs:530:5:530:18 | PathExpr | | -| variables.rs:531:5:531:18 | PathExpr | variables.rs:531:20:531:22 | "a" | | -| variables.rs:531:5:531:35 | CallExpr | variables.rs:532:5:532:37 | ExprStmt | | -| variables.rs:531:5:531:36 | ExprStmt | variables.rs:531:5:531:18 | PathExpr | | -| variables.rs:531:20:531:22 | "a" | variables.rs:531:26:531:28 | "b" | | -| variables.rs:531:25:531:34 | TupleExpr | variables.rs:531:5:531:35 | CallExpr | | -| variables.rs:531:26:531:28 | "b" | variables.rs:531:31:531:33 | "c" | | -| variables.rs:531:31:531:33 | "c" | variables.rs:531:25:531:34 | TupleExpr | | -| variables.rs:532:5:532:18 | PathExpr | variables.rs:532:20:532:31 | PathExpr | | -| variables.rs:532:5:532:36 | CallExpr | variables.rs:533:5:533:26 | ExprStmt | | -| variables.rs:532:5:532:37 | ExprStmt | variables.rs:532:5:532:18 | PathExpr | | -| variables.rs:532:20:532:31 | PathExpr | variables.rs:532:33:532:34 | 45 | | -| variables.rs:532:20:532:35 | CallExpr | variables.rs:532:5:532:36 | CallExpr | | -| variables.rs:532:33:532:34 | 45 | variables.rs:532:20:532:35 | CallExpr | | -| variables.rs:533:5:533:23 | PathExpr | variables.rs:533:5:533:25 | CallExpr | | -| variables.rs:533:5:533:25 | CallExpr | variables.rs:534:5:534:23 | ExprStmt | | -| variables.rs:533:5:533:26 | ExprStmt | variables.rs:533:5:533:23 | PathExpr | | -| variables.rs:534:5:534:20 | PathExpr | variables.rs:534:5:534:22 | CallExpr | | -| variables.rs:534:5:534:22 | CallExpr | variables.rs:535:5:535:19 | ExprStmt | | -| variables.rs:534:5:534:23 | ExprStmt | variables.rs:534:5:534:20 | PathExpr | | -| variables.rs:535:5:535:16 | PathExpr | variables.rs:535:5:535:18 | CallExpr | | -| variables.rs:535:5:535:18 | CallExpr | variables.rs:536:5:536:17 | ExprStmt | | -| variables.rs:535:5:535:19 | ExprStmt | variables.rs:535:5:535:16 | PathExpr | | -| variables.rs:536:5:536:14 | PathExpr | variables.rs:536:5:536:16 | CallExpr | | -| variables.rs:536:5:536:16 | CallExpr | variables.rs:537:5:537:13 | ExprStmt | | -| variables.rs:536:5:536:17 | ExprStmt | variables.rs:536:5:536:14 | PathExpr | | -| variables.rs:537:5:537:10 | PathExpr | variables.rs:537:5:537:12 | CallExpr | | -| variables.rs:537:5:537:12 | CallExpr | variables.rs:538:5:538:17 | ExprStmt | | -| variables.rs:537:5:537:13 | ExprStmt | variables.rs:537:5:537:10 | PathExpr | | -| variables.rs:538:5:538:14 | PathExpr | variables.rs:538:5:538:16 | CallExpr | | -| variables.rs:538:5:538:16 | CallExpr | variables.rs:539:5:539:12 | ExprStmt | | -| variables.rs:538:5:538:17 | ExprStmt | variables.rs:538:5:538:14 | PathExpr | | -| variables.rs:539:5:539:9 | PathExpr | variables.rs:539:5:539:11 | CallExpr | | -| variables.rs:539:5:539:11 | CallExpr | variables.rs:540:5:540:18 | ExprStmt | | -| variables.rs:539:5:539:12 | ExprStmt | variables.rs:539:5:539:9 | PathExpr | | -| variables.rs:540:5:540:15 | PathExpr | variables.rs:540:5:540:17 | CallExpr | | -| variables.rs:540:5:540:17 | CallExpr | variables.rs:541:5:541:20 | ExprStmt | | -| variables.rs:540:5:540:18 | ExprStmt | variables.rs:540:5:540:15 | PathExpr | | -| variables.rs:541:5:541:17 | PathExpr | variables.rs:541:5:541:19 | CallExpr | | -| variables.rs:541:5:541:19 | CallExpr | variables.rs:542:5:542:14 | ExprStmt | | -| variables.rs:541:5:541:20 | ExprStmt | variables.rs:541:5:541:17 | PathExpr | | -| variables.rs:542:5:542:11 | PathExpr | variables.rs:542:5:542:13 | CallExpr | | -| variables.rs:542:5:542:13 | CallExpr | variables.rs:543:5:543:14 | ExprStmt | | -| variables.rs:542:5:542:14 | ExprStmt | variables.rs:542:5:542:11 | PathExpr | | -| variables.rs:543:5:543:11 | PathExpr | variables.rs:543:5:543:13 | CallExpr | | -| variables.rs:543:5:543:13 | CallExpr | variables.rs:544:5:544:30 | ExprStmt | | -| variables.rs:543:5:543:14 | ExprStmt | variables.rs:543:5:543:11 | PathExpr | | -| variables.rs:544:5:544:27 | PathExpr | variables.rs:544:5:544:29 | CallExpr | | -| variables.rs:544:5:544:29 | CallExpr | variables.rs:512:11:545:1 | BlockExpr | | -| variables.rs:544:5:544:30 | ExprStmt | variables.rs:544:5:544:27 | PathExpr | | +| variables.rs:456:9:456:24 | CallExpr | variables.rs:453:12:457:5 | BlockExpr | | +| variables.rs:456:9:456:25 | ExprStmt | variables.rs:456:9:456:17 | PathExpr | | +| variables.rs:456:19:456:19 | x | variables.rs:456:23:456:23 | 1 | | +| variables.rs:456:19:456:23 | ... + ... | variables.rs:456:9:456:24 | CallExpr | | +| variables.rs:456:23:456:23 | 1 | variables.rs:456:19:456:23 | ... + ... | | +| variables.rs:458:5:458:13 | PathExpr | variables.rs:458:15:458:15 | x | | +| variables.rs:458:5:458:16 | CallExpr | variables.rs:445:18:459:1 | BlockExpr | | +| variables.rs:458:5:458:17 | ExprStmt | variables.rs:458:5:458:13 | PathExpr | | +| variables.rs:458:15:458:15 | x | variables.rs:458:5:458:16 | CallExpr | | +| variables.rs:461:1:474:1 | enter phi_read | variables.rs:461:13:461:14 | b1 | | +| variables.rs:461:1:474:1 | exit phi_read (normal) | variables.rs:461:1:474:1 | exit phi_read | | +| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:21 | Param | match | +| variables.rs:461:13:461:21 | Param | variables.rs:461:24:461:25 | b2 | | +| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:32 | Param | match | +| variables.rs:461:24:461:32 | Param | variables.rs:462:5:462:14 | LetStmt | | +| variables.rs:461:35:474:1 | BlockExpr | variables.rs:461:1:474:1 | exit phi_read (normal) | | +| variables.rs:462:5:462:14 | LetStmt | variables.rs:462:13:462:13 | 1 | | +| variables.rs:462:9:462:9 | x | variables.rs:463:5:467:5 | ExprStmt | match | +| variables.rs:462:13:462:13 | 1 | variables.rs:462:9:462:9 | x | | +| variables.rs:463:5:467:5 | ExprStmt | variables.rs:463:8:463:9 | b1 | | +| variables.rs:463:5:467:5 | IfExpr | variables.rs:469:8:469:9 | b2 | | +| variables.rs:463:8:463:9 | b1 | variables.rs:464:9:464:21 | ExprStmt | true | +| variables.rs:463:8:463:9 | b1 | variables.rs:466:9:466:21 | ExprStmt | false | +| variables.rs:463:11:465:5 | BlockExpr | variables.rs:463:5:467:5 | IfExpr | | +| variables.rs:464:9:464:17 | PathExpr | variables.rs:464:19:464:19 | x | | +| variables.rs:464:9:464:20 | CallExpr | variables.rs:463:11:465:5 | BlockExpr | | +| variables.rs:464:9:464:21 | ExprStmt | variables.rs:464:9:464:17 | PathExpr | | +| variables.rs:464:19:464:19 | x | variables.rs:464:9:464:20 | CallExpr | | +| variables.rs:465:12:467:5 | BlockExpr | variables.rs:463:5:467:5 | IfExpr | | +| variables.rs:466:9:466:17 | PathExpr | variables.rs:466:19:466:19 | x | | +| variables.rs:466:9:466:20 | CallExpr | variables.rs:465:12:467:5 | BlockExpr | | +| variables.rs:466:9:466:21 | ExprStmt | variables.rs:466:9:466:17 | PathExpr | | +| variables.rs:466:19:466:19 | x | variables.rs:466:9:466:20 | CallExpr | | +| variables.rs:469:5:473:5 | IfExpr | variables.rs:461:35:474:1 | BlockExpr | | +| variables.rs:469:8:469:9 | b2 | variables.rs:470:9:470:21 | ExprStmt | true | +| variables.rs:469:8:469:9 | b2 | variables.rs:472:9:472:21 | ExprStmt | false | +| variables.rs:469:11:471:5 | BlockExpr | variables.rs:469:5:473:5 | IfExpr | | +| variables.rs:470:9:470:17 | PathExpr | variables.rs:470:19:470:19 | x | | +| variables.rs:470:9:470:20 | CallExpr | variables.rs:469:11:471:5 | BlockExpr | | +| variables.rs:470:9:470:21 | ExprStmt | variables.rs:470:9:470:17 | PathExpr | | +| variables.rs:470:19:470:19 | x | variables.rs:470:9:470:20 | CallExpr | | +| variables.rs:471:12:473:5 | BlockExpr | variables.rs:469:5:473:5 | IfExpr | | +| variables.rs:472:9:472:17 | PathExpr | variables.rs:472:19:472:19 | x | | +| variables.rs:472:9:472:20 | CallExpr | variables.rs:471:12:473:5 | BlockExpr | | +| variables.rs:472:9:472:21 | ExprStmt | variables.rs:472:9:472:17 | PathExpr | | +| variables.rs:472:19:472:19 | x | variables.rs:472:9:472:20 | CallExpr | | +| variables.rs:482:5:484:5 | enter my_get | variables.rs:483:9:483:24 | ExprStmt | | +| variables.rs:482:5:484:5 | exit my_get (normal) | variables.rs:482:5:484:5 | exit my_get | | +| variables.rs:483:9:483:23 | ReturnExpr | variables.rs:482:5:484:5 | exit my_get (normal) | return | +| variables.rs:483:9:483:24 | ExprStmt | variables.rs:483:16:483:19 | PathExpr | | +| variables.rs:483:16:483:19 | PathExpr | variables.rs:483:16:483:23 | FieldExpr | | +| variables.rs:483:16:483:23 | FieldExpr | variables.rs:483:9:483:23 | ReturnExpr | | +| variables.rs:487:1:494:1 | enter structs | variables.rs:488:5:488:36 | LetStmt | | +| variables.rs:487:1:494:1 | exit structs (normal) | variables.rs:487:1:494:1 | exit structs | | +| variables.rs:487:14:494:1 | BlockExpr | variables.rs:487:1:494:1 | exit structs (normal) | | +| variables.rs:488:5:488:36 | LetStmt | variables.rs:488:33:488:33 | 1 | | +| variables.rs:488:9:488:13 | a | variables.rs:489:5:489:26 | ExprStmt | match | +| variables.rs:488:17:488:35 | RecordExpr | variables.rs:488:9:488:13 | a | | +| variables.rs:488:33:488:33 | 1 | variables.rs:488:17:488:35 | RecordExpr | | +| variables.rs:489:5:489:13 | PathExpr | variables.rs:489:15:489:15 | a | | +| variables.rs:489:5:489:25 | CallExpr | variables.rs:490:5:490:14 | ExprStmt | | +| variables.rs:489:5:489:26 | ExprStmt | variables.rs:489:5:489:13 | PathExpr | | +| variables.rs:489:15:489:15 | a | variables.rs:489:15:489:24 | ... .my_get(...) | | +| variables.rs:489:15:489:24 | ... .my_get(...) | variables.rs:489:5:489:25 | CallExpr | | +| variables.rs:490:5:490:5 | a | variables.rs:490:5:490:9 | FieldExpr | | +| variables.rs:490:5:490:9 | FieldExpr | variables.rs:490:13:490:13 | 5 | | +| variables.rs:490:5:490:13 | ... = ... | variables.rs:491:5:491:26 | ExprStmt | | +| variables.rs:490:5:490:14 | ExprStmt | variables.rs:490:5:490:5 | a | | +| variables.rs:490:13:490:13 | 5 | variables.rs:490:5:490:13 | ... = ... | | +| variables.rs:491:5:491:13 | PathExpr | variables.rs:491:15:491:15 | a | | +| variables.rs:491:5:491:25 | CallExpr | variables.rs:492:5:492:28 | ExprStmt | | +| variables.rs:491:5:491:26 | ExprStmt | variables.rs:491:5:491:13 | PathExpr | | +| variables.rs:491:15:491:15 | a | variables.rs:491:15:491:24 | ... .my_get(...) | | +| variables.rs:491:15:491:24 | ... .my_get(...) | variables.rs:491:5:491:25 | CallExpr | | +| variables.rs:492:5:492:5 | a | variables.rs:492:25:492:25 | 2 | | +| variables.rs:492:5:492:27 | ... = ... | variables.rs:493:5:493:26 | ExprStmt | | +| variables.rs:492:5:492:28 | ExprStmt | variables.rs:492:5:492:5 | a | | +| variables.rs:492:9:492:27 | RecordExpr | variables.rs:492:5:492:27 | ... = ... | | +| variables.rs:492:25:492:25 | 2 | variables.rs:492:9:492:27 | RecordExpr | | +| variables.rs:493:5:493:13 | PathExpr | variables.rs:493:15:493:15 | a | | +| variables.rs:493:5:493:25 | CallExpr | variables.rs:487:14:494:1 | BlockExpr | | +| variables.rs:493:5:493:26 | ExprStmt | variables.rs:493:5:493:13 | PathExpr | | +| variables.rs:493:15:493:15 | a | variables.rs:493:15:493:24 | ... .my_get(...) | | +| variables.rs:493:15:493:24 | ... .my_get(...) | variables.rs:493:5:493:25 | CallExpr | | +| variables.rs:496:1:503:1 | enter ref_arg | variables.rs:497:5:497:15 | LetStmt | | +| variables.rs:496:1:503:1 | exit ref_arg (normal) | variables.rs:496:1:503:1 | exit ref_arg | | +| variables.rs:496:14:503:1 | BlockExpr | variables.rs:496:1:503:1 | exit ref_arg (normal) | | +| variables.rs:497:5:497:15 | LetStmt | variables.rs:497:13:497:14 | 16 | | +| variables.rs:497:9:497:9 | x | variables.rs:498:5:498:22 | ExprStmt | match | +| variables.rs:497:13:497:14 | 16 | variables.rs:497:9:497:9 | x | | +| variables.rs:498:5:498:17 | PathExpr | variables.rs:498:20:498:20 | x | | +| variables.rs:498:5:498:21 | CallExpr | variables.rs:499:5:499:17 | ExprStmt | | +| variables.rs:498:5:498:22 | ExprStmt | variables.rs:498:5:498:17 | PathExpr | | +| variables.rs:498:19:498:20 | RefExpr | variables.rs:498:5:498:21 | CallExpr | | +| variables.rs:498:20:498:20 | x | variables.rs:498:19:498:20 | RefExpr | | +| variables.rs:499:5:499:13 | PathExpr | variables.rs:499:15:499:15 | x | | +| variables.rs:499:5:499:16 | CallExpr | variables.rs:501:5:501:15 | LetStmt | | +| variables.rs:499:5:499:17 | ExprStmt | variables.rs:499:5:499:13 | PathExpr | | +| variables.rs:499:15:499:15 | x | variables.rs:499:5:499:16 | CallExpr | | +| variables.rs:501:5:501:15 | LetStmt | variables.rs:501:13:501:14 | 17 | | +| variables.rs:501:9:501:9 | z | variables.rs:502:5:502:22 | ExprStmt | match | +| variables.rs:501:13:501:14 | 17 | variables.rs:501:9:501:9 | z | | +| variables.rs:502:5:502:17 | PathExpr | variables.rs:502:20:502:20 | z | | +| variables.rs:502:5:502:21 | CallExpr | variables.rs:496:14:503:1 | BlockExpr | | +| variables.rs:502:5:502:22 | ExprStmt | variables.rs:502:5:502:17 | PathExpr | | +| variables.rs:502:19:502:20 | RefExpr | variables.rs:502:5:502:21 | CallExpr | | +| variables.rs:502:20:502:20 | z | variables.rs:502:19:502:20 | RefExpr | | +| variables.rs:510:3:512:3 | enter bar | variables.rs:511:5:511:32 | ExprStmt | | +| variables.rs:510:3:512:3 | exit bar (normal) | variables.rs:510:3:512:3 | exit bar | | +| variables.rs:510:21:512:3 | BlockExpr | variables.rs:510:3:512:3 | exit bar (normal) | | +| variables.rs:511:5:511:9 | * ... | variables.rs:511:29:511:29 | 3 | | +| variables.rs:511:5:511:31 | ... = ... | variables.rs:510:21:512:3 | BlockExpr | | +| variables.rs:511:5:511:32 | ExprStmt | variables.rs:511:6:511:9 | PathExpr | | +| variables.rs:511:6:511:9 | PathExpr | variables.rs:511:5:511:9 | * ... | | +| variables.rs:511:13:511:31 | RecordExpr | variables.rs:511:5:511:31 | ... = ... | | +| variables.rs:511:29:511:29 | 3 | variables.rs:511:13:511:31 | RecordExpr | | +| variables.rs:515:1:520:1 | enter ref_methodcall_receiver | variables.rs:516:3:516:34 | LetStmt | | +| variables.rs:515:1:520:1 | exit ref_methodcall_receiver (normal) | variables.rs:515:1:520:1 | exit ref_methodcall_receiver | | +| variables.rs:515:30:520:1 | BlockExpr | variables.rs:515:1:520:1 | exit ref_methodcall_receiver (normal) | | +| variables.rs:516:3:516:34 | LetStmt | variables.rs:516:31:516:31 | 1 | | +| variables.rs:516:7:516:11 | a | variables.rs:517:3:517:10 | ExprStmt | match | +| variables.rs:516:15:516:33 | RecordExpr | variables.rs:516:7:516:11 | a | | +| variables.rs:516:31:516:31 | 1 | variables.rs:516:15:516:33 | RecordExpr | | +| variables.rs:517:3:517:3 | a | variables.rs:517:3:517:9 | ... .bar(...) | | +| variables.rs:517:3:517:9 | ... .bar(...) | variables.rs:519:3:519:19 | ExprStmt | | +| variables.rs:517:3:517:10 | ExprStmt | variables.rs:517:3:517:3 | a | | +| variables.rs:519:3:519:11 | PathExpr | variables.rs:519:13:519:13 | a | | +| variables.rs:519:3:519:18 | CallExpr | variables.rs:515:30:520:1 | BlockExpr | | +| variables.rs:519:3:519:19 | ExprStmt | variables.rs:519:3:519:11 | PathExpr | | +| variables.rs:519:13:519:13 | a | variables.rs:519:13:519:17 | FieldExpr | | +| variables.rs:519:13:519:17 | FieldExpr | variables.rs:519:3:519:18 | CallExpr | | +| variables.rs:522:1:556:1 | enter main | variables.rs:523:5:523:25 | ExprStmt | | +| variables.rs:522:1:556:1 | exit main (normal) | variables.rs:522:1:556:1 | exit main | | +| variables.rs:522:11:556:1 | BlockExpr | variables.rs:522:1:556:1 | exit main (normal) | | +| variables.rs:523:5:523:22 | PathExpr | variables.rs:523:5:523:24 | CallExpr | | +| variables.rs:523:5:523:24 | CallExpr | variables.rs:524:5:524:23 | ExprStmt | | +| variables.rs:523:5:523:25 | ExprStmt | variables.rs:523:5:523:22 | PathExpr | | +| variables.rs:524:5:524:20 | PathExpr | variables.rs:524:5:524:22 | CallExpr | | +| variables.rs:524:5:524:22 | CallExpr | variables.rs:525:5:525:40 | ExprStmt | | +| variables.rs:524:5:524:23 | ExprStmt | variables.rs:524:5:524:20 | PathExpr | | +| variables.rs:525:5:525:37 | PathExpr | variables.rs:525:5:525:39 | CallExpr | | +| variables.rs:525:5:525:39 | CallExpr | variables.rs:526:5:526:23 | ExprStmt | | +| variables.rs:525:5:525:40 | ExprStmt | variables.rs:525:5:525:37 | PathExpr | | +| variables.rs:526:5:526:20 | PathExpr | variables.rs:526:5:526:22 | CallExpr | | +| variables.rs:526:5:526:22 | CallExpr | variables.rs:527:5:527:23 | ExprStmt | | +| variables.rs:526:5:526:23 | ExprStmt | variables.rs:526:5:526:20 | PathExpr | | +| variables.rs:527:5:527:20 | PathExpr | variables.rs:527:5:527:22 | CallExpr | | +| variables.rs:527:5:527:22 | CallExpr | variables.rs:528:5:528:19 | ExprStmt | | +| variables.rs:527:5:527:23 | ExprStmt | variables.rs:527:5:527:20 | PathExpr | | +| variables.rs:528:5:528:16 | PathExpr | variables.rs:528:5:528:18 | CallExpr | | +| variables.rs:528:5:528:18 | CallExpr | variables.rs:529:5:529:19 | ExprStmt | | +| variables.rs:528:5:528:19 | ExprStmt | variables.rs:528:5:528:16 | PathExpr | | +| variables.rs:529:5:529:16 | PathExpr | variables.rs:529:5:529:18 | CallExpr | | +| variables.rs:529:5:529:18 | CallExpr | variables.rs:530:5:530:19 | ExprStmt | | +| variables.rs:529:5:529:19 | ExprStmt | variables.rs:529:5:529:16 | PathExpr | | +| variables.rs:530:5:530:16 | PathExpr | variables.rs:530:5:530:18 | CallExpr | | +| variables.rs:530:5:530:18 | CallExpr | variables.rs:531:5:531:19 | ExprStmt | | +| variables.rs:530:5:530:19 | ExprStmt | variables.rs:530:5:530:16 | PathExpr | | +| variables.rs:531:5:531:16 | PathExpr | variables.rs:531:5:531:18 | CallExpr | | +| variables.rs:531:5:531:18 | CallExpr | variables.rs:532:5:532:21 | ExprStmt | | +| variables.rs:531:5:531:19 | ExprStmt | variables.rs:531:5:531:16 | PathExpr | | +| variables.rs:532:5:532:18 | PathExpr | variables.rs:532:5:532:20 | CallExpr | | +| variables.rs:532:5:532:20 | CallExpr | variables.rs:533:5:533:21 | ExprStmt | | +| variables.rs:532:5:532:21 | ExprStmt | variables.rs:532:5:532:18 | PathExpr | | +| variables.rs:533:5:533:18 | PathExpr | variables.rs:533:5:533:20 | CallExpr | | +| variables.rs:533:5:533:20 | CallExpr | variables.rs:534:5:534:21 | ExprStmt | | +| variables.rs:533:5:533:21 | ExprStmt | variables.rs:533:5:533:18 | PathExpr | | +| variables.rs:534:5:534:18 | PathExpr | variables.rs:534:5:534:20 | CallExpr | | +| variables.rs:534:5:534:20 | CallExpr | variables.rs:535:5:535:21 | ExprStmt | | +| variables.rs:534:5:534:21 | ExprStmt | variables.rs:534:5:534:18 | PathExpr | | +| variables.rs:535:5:535:18 | PathExpr | variables.rs:535:5:535:20 | CallExpr | | +| variables.rs:535:5:535:20 | CallExpr | variables.rs:536:5:536:21 | ExprStmt | | +| variables.rs:535:5:535:21 | ExprStmt | variables.rs:535:5:535:18 | PathExpr | | +| variables.rs:536:5:536:18 | PathExpr | variables.rs:536:5:536:20 | CallExpr | | +| variables.rs:536:5:536:20 | CallExpr | variables.rs:537:5:537:21 | ExprStmt | | +| variables.rs:536:5:536:21 | ExprStmt | variables.rs:536:5:536:18 | PathExpr | | +| variables.rs:537:5:537:18 | PathExpr | variables.rs:537:5:537:20 | CallExpr | | +| variables.rs:537:5:537:20 | CallExpr | variables.rs:538:5:538:21 | ExprStmt | | +| variables.rs:537:5:537:21 | ExprStmt | variables.rs:537:5:537:18 | PathExpr | | +| variables.rs:538:5:538:18 | PathExpr | variables.rs:538:5:538:20 | CallExpr | | +| variables.rs:538:5:538:20 | CallExpr | variables.rs:539:5:539:21 | ExprStmt | | +| variables.rs:538:5:538:21 | ExprStmt | variables.rs:538:5:538:18 | PathExpr | | +| variables.rs:539:5:539:18 | PathExpr | variables.rs:539:5:539:20 | CallExpr | | +| variables.rs:539:5:539:20 | CallExpr | variables.rs:540:5:540:21 | ExprStmt | | +| variables.rs:539:5:539:21 | ExprStmt | variables.rs:539:5:539:18 | PathExpr | | +| variables.rs:540:5:540:18 | PathExpr | variables.rs:540:5:540:20 | CallExpr | | +| variables.rs:540:5:540:20 | CallExpr | variables.rs:541:5:541:36 | ExprStmt | | +| variables.rs:540:5:540:21 | ExprStmt | variables.rs:540:5:540:18 | PathExpr | | +| variables.rs:541:5:541:18 | PathExpr | variables.rs:541:20:541:22 | "a" | | +| variables.rs:541:5:541:35 | CallExpr | variables.rs:542:5:542:37 | ExprStmt | | +| variables.rs:541:5:541:36 | ExprStmt | variables.rs:541:5:541:18 | PathExpr | | +| variables.rs:541:20:541:22 | "a" | variables.rs:541:26:541:28 | "b" | | +| variables.rs:541:25:541:34 | TupleExpr | variables.rs:541:5:541:35 | CallExpr | | +| variables.rs:541:26:541:28 | "b" | variables.rs:541:31:541:33 | "c" | | +| variables.rs:541:31:541:33 | "c" | variables.rs:541:25:541:34 | TupleExpr | | +| variables.rs:542:5:542:18 | PathExpr | variables.rs:542:20:542:31 | PathExpr | | +| variables.rs:542:5:542:36 | CallExpr | variables.rs:543:5:543:26 | ExprStmt | | +| variables.rs:542:5:542:37 | ExprStmt | variables.rs:542:5:542:18 | PathExpr | | +| variables.rs:542:20:542:31 | PathExpr | variables.rs:542:33:542:34 | 45 | | +| variables.rs:542:20:542:35 | CallExpr | variables.rs:542:5:542:36 | CallExpr | | +| variables.rs:542:33:542:34 | 45 | variables.rs:542:20:542:35 | CallExpr | | +| variables.rs:543:5:543:23 | PathExpr | variables.rs:543:5:543:25 | CallExpr | | +| variables.rs:543:5:543:25 | CallExpr | variables.rs:544:5:544:23 | ExprStmt | | +| variables.rs:543:5:543:26 | ExprStmt | variables.rs:543:5:543:23 | PathExpr | | +| variables.rs:544:5:544:20 | PathExpr | variables.rs:544:5:544:22 | CallExpr | | +| variables.rs:544:5:544:22 | CallExpr | variables.rs:545:5:545:19 | ExprStmt | | +| variables.rs:544:5:544:23 | ExprStmt | variables.rs:544:5:544:20 | PathExpr | | +| variables.rs:545:5:545:16 | PathExpr | variables.rs:545:5:545:18 | CallExpr | | +| variables.rs:545:5:545:18 | CallExpr | variables.rs:546:5:546:17 | ExprStmt | | +| variables.rs:545:5:545:19 | ExprStmt | variables.rs:545:5:545:16 | PathExpr | | +| variables.rs:546:5:546:14 | PathExpr | variables.rs:546:5:546:16 | CallExpr | | +| variables.rs:546:5:546:16 | CallExpr | variables.rs:547:5:547:13 | ExprStmt | | +| variables.rs:546:5:546:17 | ExprStmt | variables.rs:546:5:546:14 | PathExpr | | +| variables.rs:547:5:547:10 | PathExpr | variables.rs:547:5:547:12 | CallExpr | | +| variables.rs:547:5:547:12 | CallExpr | variables.rs:548:5:548:17 | ExprStmt | | +| variables.rs:547:5:547:13 | ExprStmt | variables.rs:547:5:547:10 | PathExpr | | +| variables.rs:548:5:548:14 | PathExpr | variables.rs:548:5:548:16 | CallExpr | | +| variables.rs:548:5:548:16 | CallExpr | variables.rs:549:5:549:12 | ExprStmt | | +| variables.rs:548:5:548:17 | ExprStmt | variables.rs:548:5:548:14 | PathExpr | | +| variables.rs:549:5:549:9 | PathExpr | variables.rs:549:5:549:11 | CallExpr | | +| variables.rs:549:5:549:11 | CallExpr | variables.rs:550:5:550:18 | ExprStmt | | +| variables.rs:549:5:549:12 | ExprStmt | variables.rs:549:5:549:9 | PathExpr | | +| variables.rs:550:5:550:15 | PathExpr | variables.rs:550:5:550:17 | CallExpr | | +| variables.rs:550:5:550:17 | CallExpr | variables.rs:551:5:551:20 | ExprStmt | | +| variables.rs:550:5:550:18 | ExprStmt | variables.rs:550:5:550:15 | PathExpr | | +| variables.rs:551:5:551:17 | PathExpr | variables.rs:551:5:551:19 | CallExpr | | +| variables.rs:551:5:551:19 | CallExpr | variables.rs:552:5:552:26 | ExprStmt | | +| variables.rs:551:5:551:20 | ExprStmt | variables.rs:551:5:551:17 | PathExpr | | +| variables.rs:552:5:552:23 | PathExpr | variables.rs:552:5:552:25 | CallExpr | | +| variables.rs:552:5:552:25 | CallExpr | variables.rs:553:5:553:14 | ExprStmt | | +| variables.rs:552:5:552:26 | ExprStmt | variables.rs:552:5:552:23 | PathExpr | | +| variables.rs:553:5:553:11 | PathExpr | variables.rs:553:5:553:13 | CallExpr | | +| variables.rs:553:5:553:13 | CallExpr | variables.rs:554:5:554:14 | ExprStmt | | +| variables.rs:553:5:553:14 | ExprStmt | variables.rs:553:5:553:11 | PathExpr | | +| variables.rs:554:5:554:11 | PathExpr | variables.rs:554:5:554:13 | CallExpr | | +| variables.rs:554:5:554:13 | CallExpr | variables.rs:555:5:555:30 | ExprStmt | | +| variables.rs:554:5:554:14 | ExprStmt | variables.rs:554:5:554:11 | PathExpr | | +| variables.rs:555:5:555:27 | PathExpr | variables.rs:555:5:555:29 | CallExpr | | +| variables.rs:555:5:555:29 | CallExpr | variables.rs:522:11:556:1 | BlockExpr | | +| variables.rs:555:5:555:30 | ExprStmt | variables.rs:555:5:555:27 | PathExpr | | breakTarget continueTarget diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index 3e3ba9af7c99..0b5c99ec7f3f 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -5,8 +5,8 @@ nonSsaVariable | variables.rs:379:13:379:13 | z | | variables.rs:392:13:392:13 | x | | variables.rs:426:13:426:13 | z | -| variables.rs:478:13:478:13 | a | -| variables.rs:506:11:506:11 | a | +| variables.rs:488:13:488:13 | a | +| variables.rs:516:11:516:11 | a | definition | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | @@ -122,16 +122,18 @@ definition | variables.rs:421:9:421:9 | y | variables.rs:418:13:418:13 | y | | variables.rs:423:5:423:14 | CallExpr | variables.rs:418:13:418:13 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | -| variables.rs:435:8:435:8 | b | variables.rs:435:8:435:8 | b | -| variables.rs:436:9:436:13 | x | variables.rs:436:13:436:13 | x | -| variables.rs:439:5:447:5 | phi | variables.rs:436:13:436:13 | x | -| variables.rs:440:9:440:9 | x | variables.rs:436:13:436:13 | x | -| variables.rs:444:9:444:9 | x | variables.rs:436:13:436:13 | x | -| variables.rs:451:13:451:14 | b1 | variables.rs:451:13:451:14 | b1 | -| variables.rs:451:24:451:25 | b2 | variables.rs:451:24:451:25 | b2 | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | -| variables.rs:487:9:487:9 | x | variables.rs:487:9:487:9 | x | -| variables.rs:491:9:491:9 | z | variables.rs:491:9:491:9 | z | +| variables.rs:436:9:436:13 | i | variables.rs:436:13:436:13 | i | +| variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | +| variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | +| variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | +| variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | +| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | +| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | +| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:14 | b1 | +| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | +| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x | +| variables.rs:501:9:501:9 | z | variables.rs:501:9:501:9 | z | read | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -237,21 +239,23 @@ read | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | | variables.rs:423:5:423:14 | CallExpr | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | -| variables.rs:435:8:435:8 | b | variables.rs:435:8:435:8 | b | variables.rs:439:8:439:8 | b | -| variables.rs:436:9:436:13 | x | variables.rs:436:13:436:13 | x | variables.rs:437:15:437:15 | x | -| variables.rs:436:9:436:13 | x | variables.rs:436:13:436:13 | x | variables.rs:438:15:438:15 | x | -| variables.rs:439:5:447:5 | phi | variables.rs:436:13:436:13 | x | variables.rs:448:15:448:15 | x | -| variables.rs:440:9:440:9 | x | variables.rs:436:13:436:13 | x | variables.rs:441:19:441:19 | x | -| variables.rs:440:9:440:9 | x | variables.rs:436:13:436:13 | x | variables.rs:442:19:442:19 | x | -| variables.rs:444:9:444:9 | x | variables.rs:436:13:436:13 | x | variables.rs:445:19:445:19 | x | -| variables.rs:444:9:444:9 | x | variables.rs:436:13:436:13 | x | variables.rs:446:19:446:19 | x | -| variables.rs:451:13:451:14 | b1 | variables.rs:451:13:451:14 | b1 | variables.rs:453:8:453:9 | b1 | -| variables.rs:451:24:451:25 | b2 | variables.rs:451:24:451:25 | b2 | variables.rs:459:8:459:9 | b2 | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:454:19:454:19 | x | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:456:19:456:19 | x | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:460:19:460:19 | x | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:462:19:462:19 | x | -| variables.rs:487:9:487:9 | x | variables.rs:487:9:487:9 | x | variables.rs:489:15:489:15 | x | +| variables.rs:436:9:436:13 | i | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | +| variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | +| variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | +| variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:447:15:447:15 | x | +| variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:448:15:448:15 | x | +| variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | variables.rs:458:15:458:15 | x | +| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | variables.rs:451:19:451:19 | x | +| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | variables.rs:452:19:452:19 | x | +| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | variables.rs:455:19:455:19 | x | +| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | variables.rs:456:19:456:19 | x | +| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:14 | b1 | variables.rs:463:8:463:9 | b1 | +| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | variables.rs:469:8:469:9 | b2 | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:464:19:464:19 | x | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:470:19:470:19 | x | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:472:19:472:19 | x | +| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x | variables.rs:499:15:499:15 | x | firstRead | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -339,16 +343,18 @@ firstRead | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | | variables.rs:423:5:423:14 | CallExpr | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | -| variables.rs:435:8:435:8 | b | variables.rs:435:8:435:8 | b | variables.rs:439:8:439:8 | b | -| variables.rs:436:9:436:13 | x | variables.rs:436:13:436:13 | x | variables.rs:437:15:437:15 | x | -| variables.rs:439:5:447:5 | phi | variables.rs:436:13:436:13 | x | variables.rs:448:15:448:15 | x | -| variables.rs:440:9:440:9 | x | variables.rs:436:13:436:13 | x | variables.rs:441:19:441:19 | x | -| variables.rs:444:9:444:9 | x | variables.rs:436:13:436:13 | x | variables.rs:445:19:445:19 | x | -| variables.rs:451:13:451:14 | b1 | variables.rs:451:13:451:14 | b1 | variables.rs:453:8:453:9 | b1 | -| variables.rs:451:24:451:25 | b2 | variables.rs:451:24:451:25 | b2 | variables.rs:459:8:459:9 | b2 | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:454:19:454:19 | x | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:456:19:456:19 | x | -| variables.rs:487:9:487:9 | x | variables.rs:487:9:487:9 | x | variables.rs:489:15:489:15 | x | +| variables.rs:436:9:436:13 | i | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | +| variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | +| variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | +| variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:447:15:447:15 | x | +| variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | variables.rs:458:15:458:15 | x | +| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | variables.rs:451:19:451:19 | x | +| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | variables.rs:455:19:455:19 | x | +| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:14 | b1 | variables.rs:463:8:463:9 | b1 | +| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | variables.rs:469:8:469:9 | b2 | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:464:19:464:19 | x | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x | +| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x | variables.rs:499:15:499:15 | x | lastRead | variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s | | variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i | @@ -437,16 +443,18 @@ lastRead | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | | variables.rs:423:5:423:14 | CallExpr | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | -| variables.rs:435:8:435:8 | b | variables.rs:435:8:435:8 | b | variables.rs:439:8:439:8 | b | -| variables.rs:436:9:436:13 | x | variables.rs:436:13:436:13 | x | variables.rs:438:15:438:15 | x | -| variables.rs:439:5:447:5 | phi | variables.rs:436:13:436:13 | x | variables.rs:448:15:448:15 | x | -| variables.rs:440:9:440:9 | x | variables.rs:436:13:436:13 | x | variables.rs:442:19:442:19 | x | -| variables.rs:444:9:444:9 | x | variables.rs:436:13:436:13 | x | variables.rs:446:19:446:19 | x | -| variables.rs:451:13:451:14 | b1 | variables.rs:451:13:451:14 | b1 | variables.rs:453:8:453:9 | b1 | -| variables.rs:451:24:451:25 | b2 | variables.rs:451:24:451:25 | b2 | variables.rs:459:8:459:9 | b2 | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:460:19:460:19 | x | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:462:19:462:19 | x | -| variables.rs:487:9:487:9 | x | variables.rs:487:9:487:9 | x | variables.rs:489:15:489:15 | x | +| variables.rs:436:9:436:13 | i | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | +| variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | +| variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | +| variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:448:15:448:15 | x | +| variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | variables.rs:458:15:458:15 | x | +| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | variables.rs:452:19:452:19 | x | +| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | variables.rs:456:19:456:19 | x | +| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:14 | b1 | variables.rs:463:8:463:9 | b1 | +| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | variables.rs:469:8:469:9 | b2 | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:470:19:470:19 | x | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:472:19:472:19 | x | +| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x | variables.rs:499:15:499:15 | x | adjacentReads | variables.rs:35:9:35:10 | x3 | variables.rs:35:9:35:10 | x3 | variables.rs:36:15:36:16 | x3 | variables.rs:38:9:38:10 | x3 | | variables.rs:43:9:43:10 | x4 | variables.rs:43:9:43:10 | x4 | variables.rs:44:15:44:16 | x4 | variables.rs:49:15:49:16 | x4 | @@ -467,13 +475,13 @@ adjacentReads | variables.rs:363:22:363:22 | x | variables.rs:363:22:363:22 | x | variables.rs:365:10:365:10 | x | variables.rs:366:10:366:10 | x | | variables.rs:363:22:363:22 | x | variables.rs:363:22:363:22 | x | variables.rs:366:10:366:10 | x | variables.rs:368:9:368:9 | x | | variables.rs:380:9:380:9 | w | variables.rs:380:9:380:9 | w | variables.rs:384:9:384:9 | w | variables.rs:386:7:386:7 | w | -| variables.rs:436:9:436:13 | x | variables.rs:436:13:436:13 | x | variables.rs:437:15:437:15 | x | variables.rs:438:15:438:15 | x | -| variables.rs:440:9:440:9 | x | variables.rs:436:13:436:13 | x | variables.rs:441:19:441:19 | x | variables.rs:442:19:442:19 | x | -| variables.rs:444:9:444:9 | x | variables.rs:436:13:436:13 | x | variables.rs:445:19:445:19 | x | variables.rs:446:19:446:19 | x | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:454:19:454:19 | x | variables.rs:460:19:460:19 | x | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:454:19:454:19 | x | variables.rs:462:19:462:19 | x | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:456:19:456:19 | x | variables.rs:460:19:460:19 | x | -| variables.rs:452:9:452:9 | x | variables.rs:452:9:452:9 | x | variables.rs:456:19:456:19 | x | variables.rs:462:19:462:19 | x | +| variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:447:15:447:15 | x | variables.rs:448:15:448:15 | x | +| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | variables.rs:451:19:451:19 | x | variables.rs:452:19:452:19 | x | +| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | variables.rs:455:19:455:19 | x | variables.rs:456:19:456:19 | x | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:464:19:464:19 | x | variables.rs:470:19:470:19 | x | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:464:19:464:19 | x | variables.rs:472:19:472:19 | x | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x | variables.rs:470:19:470:19 | x | +| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x | variables.rs:472:19:472:19 | x | phi | variables.rs:191:9:191:44 | [match(true)] phi | variables.rs:191:9:191:44 | a3 | variables.rs:191:22:191:23 | a3 | | variables.rs:191:9:191:44 | [match(true)] phi | variables.rs:191:9:191:44 | a3 | variables.rs:191:42:191:43 | a3 | @@ -499,19 +507,19 @@ phi | variables.rs:255:35:255:82 | [match(true)] phi | variables.rs:255:9:255:109 | a13 | variables.rs:255:79:255:81 | a13 | | variables.rs:272:6:272:41 | [match(true)] phi | variables.rs:272:6:272:41 | a9 | variables.rs:272:19:272:20 | a9 | | variables.rs:272:6:272:41 | [match(true)] phi | variables.rs:272:6:272:41 | a9 | variables.rs:272:39:272:40 | a9 | -| variables.rs:439:5:447:5 | phi | variables.rs:436:13:436:13 | x | variables.rs:440:9:440:9 | x | -| variables.rs:439:5:447:5 | phi | variables.rs:436:13:436:13 | x | variables.rs:444:9:444:9 | x | +| variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | variables.rs:450:9:450:9 | x | +| variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | variables.rs:454:9:454:9 | x | phiReadNode | variables.rs:104:11:105:12 | SSA phi read(s1) | variables.rs:102:9:102:10 | s1 | -| variables.rs:453:5:457:5 | SSA phi read(x) | variables.rs:452:9:452:9 | x | +| variables.rs:463:5:467:5 | SSA phi read(x) | variables.rs:462:9:462:9 | x | phiReadNodeRead | variables.rs:104:11:105:12 | SSA phi read(s1) | variables.rs:102:9:102:10 | s1 | variables.rs:105:11:105:12 | s1 | -| variables.rs:453:5:457:5 | SSA phi read(x) | variables.rs:452:9:452:9 | x | variables.rs:460:19:460:19 | x | -| variables.rs:453:5:457:5 | SSA phi read(x) | variables.rs:452:9:452:9 | x | variables.rs:462:19:462:19 | x | +| variables.rs:463:5:467:5 | SSA phi read(x) | variables.rs:462:9:462:9 | x | variables.rs:470:19:470:19 | x | +| variables.rs:463:5:467:5 | SSA phi read(x) | variables.rs:462:9:462:9 | x | variables.rs:472:19:472:19 | x | phiReadInput | variables.rs:104:11:105:12 | SSA phi read(s1) | variables.rs:102:9:102:10 | s1 | | variables.rs:104:11:105:12 | SSA phi read(s1) | variables.rs:104:11:105:12 | SSA phi read(s1) | -| variables.rs:453:5:457:5 | SSA phi read(x) | variables.rs:452:9:452:9 | x | +| variables.rs:463:5:467:5 | SSA phi read(x) | variables.rs:462:9:462:9 | x | ultimateDef | variables.rs:191:9:191:44 | [match(true)] phi | variables.rs:191:22:191:23 | a3 | | variables.rs:191:9:191:44 | [match(true)] phi | variables.rs:191:42:191:43 | a3 | @@ -540,11 +548,11 @@ ultimateDef | variables.rs:255:35:255:82 | [match(true)] phi | variables.rs:255:79:255:81 | a13 | | variables.rs:272:6:272:41 | [match(true)] phi | variables.rs:272:19:272:20 | a9 | | variables.rs:272:6:272:41 | [match(true)] phi | variables.rs:272:39:272:40 | a9 | -| variables.rs:439:5:447:5 | phi | variables.rs:440:9:440:9 | x | -| variables.rs:439:5:447:5 | phi | variables.rs:444:9:444:9 | x | +| variables.rs:449:5:457:5 | phi | variables.rs:450:9:450:9 | x | +| variables.rs:449:5:457:5 | phi | variables.rs:454:9:454:9 | x | assigns | variables.rs:23:5:23:6 | x2 | variables.rs:23:10:23:10 | 5 | | variables.rs:30:5:30:5 | x | variables.rs:30:9:30:9 | 2 | | variables.rs:421:9:421:9 | y | variables.rs:421:13:421:13 | 3 | -| variables.rs:440:9:440:9 | x | variables.rs:440:13:440:13 | 2 | -| variables.rs:444:9:444:9 | x | variables.rs:444:13:444:13 | 3 | +| variables.rs:450:9:450:9 | x | variables.rs:450:13:450:13 | 2 | +| variables.rs:454:9:454:9 | x | variables.rs:454:13:454:13 | 3 | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index 53245eacea03..908ab40fc22e 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -1,4 +1,6 @@ testFailures +| variables.rs:438:9:438:9 | i | Unexpected result: write_access=i | +| variables.rs:438:16:438:33 | Comment | Missing result: read_access=i | failures variable | variables.rs:3:14:3:14 | s | @@ -88,15 +90,17 @@ variable | variables.rs:420:13:420:20 | closure2 | | variables.rs:426:13:426:13 | z | | variables.rs:428:13:428:20 | closure3 | -| variables.rs:435:8:435:8 | b | -| variables.rs:436:13:436:13 | x | -| variables.rs:451:13:451:14 | b1 | -| variables.rs:451:24:451:25 | b2 | -| variables.rs:452:9:452:9 | x | -| variables.rs:478:13:478:13 | a | -| variables.rs:487:9:487:9 | x | -| variables.rs:491:9:491:9 | z | -| variables.rs:506:11:506:11 | a | +| variables.rs:436:13:436:13 | i | +| variables.rs:437:9:437:13 | block | +| variables.rs:445:8:445:8 | b | +| variables.rs:446:13:446:13 | x | +| variables.rs:461:13:461:14 | b1 | +| variables.rs:461:24:461:25 | b2 | +| variables.rs:462:9:462:9 | x | +| variables.rs:488:13:488:13 | a | +| variables.rs:497:9:497:9 | x | +| variables.rs:501:9:501:9 | z | +| variables.rs:516:11:516:11 | a | variableAccess | variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s | | variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i | @@ -225,32 +229,35 @@ variableAccess | variables.rs:429:9:429:9 | z | variables.rs:426:13:426:13 | z | | variables.rs:431:5:431:12 | closure3 | variables.rs:428:13:428:20 | closure3 | | variables.rs:432:15:432:15 | z | variables.rs:426:13:426:13 | z | -| variables.rs:437:15:437:15 | x | variables.rs:436:13:436:13 | x | -| variables.rs:438:15:438:15 | x | variables.rs:436:13:436:13 | x | -| variables.rs:439:8:439:8 | b | variables.rs:435:8:435:8 | b | -| variables.rs:440:9:440:9 | x | variables.rs:436:13:436:13 | x | -| variables.rs:441:19:441:19 | x | variables.rs:436:13:436:13 | x | -| variables.rs:442:19:442:19 | x | variables.rs:436:13:436:13 | x | -| variables.rs:444:9:444:9 | x | variables.rs:436:13:436:13 | x | -| variables.rs:445:19:445:19 | x | variables.rs:436:13:436:13 | x | -| variables.rs:446:19:446:19 | x | variables.rs:436:13:436:13 | x | -| variables.rs:448:15:448:15 | x | variables.rs:436:13:436:13 | x | -| variables.rs:453:8:453:9 | b1 | variables.rs:451:13:451:14 | b1 | -| variables.rs:454:19:454:19 | x | variables.rs:452:9:452:9 | x | -| variables.rs:456:19:456:19 | x | variables.rs:452:9:452:9 | x | -| variables.rs:459:8:459:9 | b2 | variables.rs:451:24:451:25 | b2 | -| variables.rs:460:19:460:19 | x | variables.rs:452:9:452:9 | x | -| variables.rs:462:19:462:19 | x | variables.rs:452:9:452:9 | x | -| variables.rs:479:15:479:15 | a | variables.rs:478:13:478:13 | a | -| variables.rs:480:5:480:5 | a | variables.rs:478:13:478:13 | a | -| variables.rs:481:15:481:15 | a | variables.rs:478:13:478:13 | a | -| variables.rs:482:5:482:5 | a | variables.rs:478:13:478:13 | a | -| variables.rs:483:15:483:15 | a | variables.rs:478:13:478:13 | a | -| variables.rs:488:20:488:20 | x | variables.rs:487:9:487:9 | x | -| variables.rs:489:15:489:15 | x | variables.rs:487:9:487:9 | x | -| variables.rs:492:20:492:20 | z | variables.rs:491:9:491:9 | z | -| variables.rs:507:3:507:3 | a | variables.rs:506:11:506:11 | a | -| variables.rs:509:13:509:13 | a | variables.rs:506:11:506:11 | a | +| variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i | +| variables.rs:441:5:441:9 | block | variables.rs:437:9:437:13 | block | +| variables.rs:442:15:442:15 | i | variables.rs:436:13:436:13 | i | +| variables.rs:447:15:447:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:448:15:448:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:449:8:449:8 | b | variables.rs:445:8:445:8 | b | +| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | +| variables.rs:451:19:451:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:452:19:452:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | +| variables.rs:455:19:455:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:456:19:456:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:458:15:458:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:463:8:463:9 | b1 | variables.rs:461:13:461:14 | b1 | +| variables.rs:464:19:464:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:466:19:466:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 | +| variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:489:15:489:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:490:5:490:5 | a | variables.rs:488:13:488:13 | a | +| variables.rs:491:15:491:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:492:5:492:5 | a | variables.rs:488:13:488:13 | a | +| variables.rs:493:15:493:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:498:20:498:20 | x | variables.rs:497:9:497:9 | x | +| variables.rs:499:15:499:15 | x | variables.rs:497:9:497:9 | x | +| variables.rs:502:20:502:20 | z | variables.rs:501:9:501:9 | z | +| variables.rs:517:3:517:3 | a | variables.rs:516:11:516:11 | a | +| variables.rs:519:13:519:13 | a | variables.rs:516:11:516:11 | a | variableWriteAccess | variables.rs:23:5:23:6 | x2 | variables.rs:21:13:21:14 | x2 | | variables.rs:30:5:30:5 | x | variables.rs:28:13:28:13 | x | @@ -258,9 +265,10 @@ variableWriteAccess | variables.rs:289:9:289:10 | b4 | variables.rs:280:13:280:14 | b4 | | variables.rs:290:9:290:11 | a10 | variables.rs:279:13:279:15 | a10 | | variables.rs:421:9:421:9 | y | variables.rs:418:13:418:13 | y | -| variables.rs:440:9:440:9 | x | variables.rs:436:13:436:13 | x | -| variables.rs:444:9:444:9 | x | variables.rs:436:13:436:13 | x | -| variables.rs:482:5:482:5 | a | variables.rs:478:13:478:13 | a | +| variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i | +| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x | +| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x | +| variables.rs:492:5:492:5 | a | variables.rs:488:13:488:13 | a | variableReadAccess | variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s | | variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i | @@ -374,27 +382,29 @@ variableReadAccess | variables.rs:429:9:429:9 | z | variables.rs:426:13:426:13 | z | | variables.rs:431:5:431:12 | closure3 | variables.rs:428:13:428:20 | closure3 | | variables.rs:432:15:432:15 | z | variables.rs:426:13:426:13 | z | -| variables.rs:437:15:437:15 | x | variables.rs:436:13:436:13 | x | -| variables.rs:438:15:438:15 | x | variables.rs:436:13:436:13 | x | -| variables.rs:439:8:439:8 | b | variables.rs:435:8:435:8 | b | -| variables.rs:441:19:441:19 | x | variables.rs:436:13:436:13 | x | -| variables.rs:442:19:442:19 | x | variables.rs:436:13:436:13 | x | -| variables.rs:445:19:445:19 | x | variables.rs:436:13:436:13 | x | -| variables.rs:446:19:446:19 | x | variables.rs:436:13:436:13 | x | -| variables.rs:448:15:448:15 | x | variables.rs:436:13:436:13 | x | -| variables.rs:453:8:453:9 | b1 | variables.rs:451:13:451:14 | b1 | -| variables.rs:454:19:454:19 | x | variables.rs:452:9:452:9 | x | -| variables.rs:456:19:456:19 | x | variables.rs:452:9:452:9 | x | -| variables.rs:459:8:459:9 | b2 | variables.rs:451:24:451:25 | b2 | -| variables.rs:460:19:460:19 | x | variables.rs:452:9:452:9 | x | -| variables.rs:462:19:462:19 | x | variables.rs:452:9:452:9 | x | -| variables.rs:479:15:479:15 | a | variables.rs:478:13:478:13 | a | -| variables.rs:480:5:480:5 | a | variables.rs:478:13:478:13 | a | -| variables.rs:481:15:481:15 | a | variables.rs:478:13:478:13 | a | -| variables.rs:483:15:483:15 | a | variables.rs:478:13:478:13 | a | -| variables.rs:489:15:489:15 | x | variables.rs:487:9:487:9 | x | -| variables.rs:507:3:507:3 | a | variables.rs:506:11:506:11 | a | -| variables.rs:509:13:509:13 | a | variables.rs:506:11:506:11 | a | +| variables.rs:441:5:441:9 | block | variables.rs:437:9:437:13 | block | +| variables.rs:442:15:442:15 | i | variables.rs:436:13:436:13 | i | +| variables.rs:447:15:447:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:448:15:448:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:449:8:449:8 | b | variables.rs:445:8:445:8 | b | +| variables.rs:451:19:451:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:452:19:452:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:455:19:455:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:456:19:456:19 | x | variables.rs:446:13:446:13 | x | +| variables.rs:458:15:458:15 | x | variables.rs:446:13:446:13 | x | +| variables.rs:463:8:463:9 | b1 | variables.rs:461:13:461:14 | b1 | +| variables.rs:464:19:464:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:466:19:466:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 | +| variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x | +| variables.rs:489:15:489:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:490:5:490:5 | a | variables.rs:488:13:488:13 | a | +| variables.rs:491:15:491:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:493:15:493:15 | a | variables.rs:488:13:488:13 | a | +| variables.rs:499:15:499:15 | x | variables.rs:497:9:497:9 | x | +| variables.rs:517:3:517:3 | a | variables.rs:516:11:516:11 | a | +| variables.rs:519:13:519:13 | a | variables.rs:516:11:516:11 | a | variableInitializer | variables.rs:16:9:16:10 | x1 | variables.rs:16:14:16:16 | "a" | | variables.rs:21:13:21:14 | x2 | variables.rs:21:18:21:18 | 4 | @@ -438,12 +448,14 @@ variableInitializer | variables.rs:420:13:420:20 | closure2 | variables.rs:420:24:422:5 | ClosureExpr | | variables.rs:426:13:426:13 | z | variables.rs:426:17:426:17 | 2 | | variables.rs:428:13:428:20 | closure3 | variables.rs:428:24:430:5 | ClosureExpr | -| variables.rs:436:13:436:13 | x | variables.rs:436:17:436:17 | 1 | -| variables.rs:452:9:452:9 | x | variables.rs:452:13:452:13 | 1 | -| variables.rs:478:13:478:13 | a | variables.rs:478:17:478:35 | RecordExpr | -| variables.rs:487:9:487:9 | x | variables.rs:487:13:487:14 | 16 | -| variables.rs:491:9:491:9 | z | variables.rs:491:13:491:14 | 17 | -| variables.rs:506:11:506:11 | a | variables.rs:506:15:506:33 | RecordExpr | +| variables.rs:436:13:436:13 | i | variables.rs:436:22:436:22 | 0 | +| variables.rs:437:9:437:13 | block | variables.rs:437:17:439:5 | BlockExpr | +| variables.rs:446:13:446:13 | x | variables.rs:446:17:446:17 | 1 | +| variables.rs:462:9:462:9 | x | variables.rs:462:13:462:13 | 1 | +| variables.rs:488:13:488:13 | a | variables.rs:488:17:488:35 | RecordExpr | +| variables.rs:497:9:497:9 | x | variables.rs:497:13:497:14 | 16 | +| variables.rs:501:9:501:9 | z | variables.rs:501:13:501:14 | 17 | +| variables.rs:516:11:516:11 | a | variables.rs:516:15:516:33 | RecordExpr | capturedVariable | variables.rs:400:9:400:9 | x | | variables.rs:410:13:410:13 | x | diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs index c561daf2062f..c5b9bd80a8bd 100644 --- a/rust/ql/test/library-tests/variables/variables.rs +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -432,6 +432,16 @@ fn capture_mut() { print_i64(z); // $ read_access=z } +async fn async_block_capture() { + let mut i: i64 = 0; // i + let block = async { + i = 1; // $ read_access=i + }; + // The await below causes write to `i` + block.await; // $ read_access=block + print_i64(i); // $ read_access=i +} + fn phi(b : bool) { let mut x = 1; // x print_i64(x); // $ read_access=x @@ -539,6 +549,7 @@ fn main() { alias(); capture_mut(); capture_immut(); + async_block_capture(); structs(); ref_arg(); ref_methodcall_receiver(); From a5e13ee71b8e891d4172262b9719b5138b478e4b Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Sun, 10 Nov 2024 11:59:37 +0100 Subject: [PATCH 4/8] Rust: Handle async blocks in SSA analysis --- .../lib/codeql/rust/controlflow/BasicBlocks.qll | 2 +- .../codeql/rust/controlflow/ControlFlowGraph.qll | 5 +++++ .../internal/ControlFlowGraphImpl.qll | 2 +- .../codeql/rust/controlflow/internal/Scope.qll | 16 ++++++++++++---- .../rust/dataflow/internal/DataFlowImpl.qll | 4 ++-- .../codeql/rust/dataflow/internal/SsaImpl.qll | 16 +++++++++------- .../rust/elements/internal/VariableImpl.qll | 3 ++- .../ql/test/library-tests/variables/Ssa.expected | 9 ++++++--- .../library-tests/variables/variables.expected | 2 ++ 9 files changed, 40 insertions(+), 19 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/BasicBlocks.qll b/rust/ql/lib/codeql/rust/controlflow/BasicBlocks.qll index 60f5b4db5af8..f87a48a28a5b 100644 --- a/rust/ql/lib/codeql/rust/controlflow/BasicBlocks.qll +++ b/rust/ql/lib/codeql/rust/controlflow/BasicBlocks.qll @@ -12,7 +12,7 @@ final class BasicBlock = BasicBlockImpl; * without branches or joins. */ private class BasicBlockImpl extends TBasicBlockStart { - /** Gets the scope of this basic block. */ + /** Gets the CFG scope of this basic block. */ CfgScope getScope() { result = this.getAPredecessor().getScope() } /** Gets an immediate successor of this basic block, if any. */ diff --git a/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll b/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll index 20f1af4a4afb..28965b1b18fc 100644 --- a/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll +++ b/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll @@ -9,6 +9,8 @@ private import BasicBlocks final class CfgScope = Scope::CfgScope; +predicate getEnclosingCfgScope = Scope::getEnclosingCfgScope/1; + final class SuccessorType = SuccessorTypeImpl; final class NormalSuccessor = NormalSuccessorImpl; @@ -52,3 +54,6 @@ final class CfgNode extends Node { /** Gets the basic block that this control flow node belongs to. */ BasicBlock getBasicBlock() { result.getANode() = this } } + +/** Holds if evaluating `e` jumps to the evaluation of a different CFG scope. */ +predicate isControlFlowJump(Expr e) { e instanceof CallExprBase or e instanceof AwaitExpr } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 0541031594d7..649b4729dc3e 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -23,7 +23,7 @@ private module CfgInput implements InputSig { class CfgScope = Scope::CfgScope; CfgScope getCfgScope(AstNode n) { - result = n.getEnclosingCallable() and + result = Scope::getEnclosingCfgScope(n) and Stages::CfgStage::ref() } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll index 925675c17350..0adcef156c00 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll @@ -14,9 +14,7 @@ abstract private class CfgScopeImpl extends AstNode { final class CfgScope = CfgScopeImpl; -class AsyncBlockScope extends CfgScopeImpl, BlockExpr { - AsyncBlockScope() { this.isAsync() } - +final class AsyncBlockScope extends CfgScopeImpl, AsyncBlockExpr { override predicate scopeFirst(AstNode first) { first(this.(ExprTrees::AsyncBlockExprTree).getFirstChildNode(), first) } @@ -29,7 +27,7 @@ class AsyncBlockScope extends CfgScopeImpl, BlockExpr { /** * A CFG scope for a callable (a function or a closure) with a body. */ -class CallableScope extends CfgScopeImpl, Callable { +final class CallableScope extends CfgScopeImpl, Callable { CallableScope() { // A function without a body corresponds to a trait method signature and // should not have a CFG scope. @@ -52,3 +50,13 @@ class CallableScope extends CfgScopeImpl, Callable { /** Holds if `scope` is exited when `last` finishes with completion `c`. */ override predicate scopeLast(AstNode last, Completion c) { last(this.getBody(), last, c) } } + +/** Gets the CFG scope that encloses `node`, if any. */ +CfgScope getEnclosingCfgScope(AstNode node) { + exists(AstNode p | p = node.getParentNode() | + result = p + or + not p instanceof CfgScope and + result = getEnclosingCfgScope(p) + ) +} diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index b178e97acfe6..c93e374902a8 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -134,7 +134,7 @@ module Node { ExprNode() { this = TExprNode(n) } - override CfgScope getCfgScope() { result = this.asExpr().getEnclosingCallable() } + override CfgScope getCfgScope() { result = getEnclosingCfgScope(this.asExpr()) } override Location getLocation() { result = n.getExpr().getLocation() } @@ -154,7 +154,7 @@ module Node { ParameterNode() { this = TParameterNode(parameter) } - override CfgScope getCfgScope() { result = parameter.getEnclosingCallable() } + override CfgScope getCfgScope() { result = getEnclosingCfgScope(parameter) } override Location getLocation() { result = parameter.getLocation() } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll index b248c4d7c5cd..955dd9995a24 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll @@ -156,19 +156,19 @@ private predicate variableReadActual(BasicBlock bb, int i, Variable v) { */ pragma[noinline] private predicate hasCapturedWrite(Variable v, Cfg::CfgScope scope) { - any(VariableWriteAccess write | write.getVariable() = v and scope = write.getEnclosingCallable+()) + any(VariableWriteAccess write | write.getVariable() = v and scope = getEnclosingCfgScope+(write)) .isCapture() } /** * Holds if `v` is read inside basic block `bb` at index `i`, which is in the - * immediate outer scope of `scope`. + * immediate outer CFG scope of `scope`. */ pragma[noinline] private predicate variableReadActualInOuterScope( BasicBlock bb, int i, Variable v, Cfg::CfgScope scope ) { - variableReadActual(bb, i, v) and bb.getScope() = scope.getEnclosingCallable() + variableReadActual(bb, i, v) and bb.getScope() = getEnclosingCfgScope(scope) } pragma[noinline] @@ -263,7 +263,7 @@ private predicate readsCapturedVariable(BasicBlock bb, Variable v) { */ pragma[noinline] private predicate hasCapturedRead(Variable v, Cfg::CfgScope scope) { - any(VariableReadAccess read | read.getVariable() = v and scope = read.getEnclosingCallable+()) + any(VariableReadAccess read | read.getVariable() = v and scope = getEnclosingCfgScope+(read)) .isCapture() } @@ -273,14 +273,15 @@ private predicate hasCapturedRead(Variable v, Cfg::CfgScope scope) { */ pragma[noinline] private predicate variableWriteInOuterScope(BasicBlock bb, int i, Variable v, Cfg::CfgScope scope) { - SsaInput::variableWrite(bb, i, v, _) and scope.getEnclosingCallable() = bb.getScope() + SsaInput::variableWrite(bb, i, v, _) and getEnclosingCfgScope(scope) = bb.getScope() } /** * Holds if the call `call` at index `i` in basic block `bb` may reach * a callable that reads captured variable `v`. */ -private predicate capturedCallRead(CallExprBase call, BasicBlock bb, int i, Variable v) { +private predicate capturedCallRead(Expr call, BasicBlock bb, int i, Variable v) { + Cfg::isControlFlowJump(call) and exists(Cfg::CfgScope scope | hasCapturedRead(v, scope) and ( @@ -295,7 +296,8 @@ private predicate capturedCallRead(CallExprBase call, BasicBlock bb, int i, Vari * Holds if the call `call` at index `i` in basic block `bb` may reach a callable * that writes captured variable `v`. */ -predicate capturedCallWrite(CallExprBase call, BasicBlock bb, int i, Variable v) { +predicate capturedCallWrite(Expr call, BasicBlock bb, int i, Variable v) { + Cfg::isControlFlowJump(call) and call = bb.getNode(i).getAstNode() and exists(Cfg::CfgScope scope | hasVariableReadWithCapturedWrite(bb, any(int j | j > i), v, scope) diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index 10f079a4c5d6..bed98189e4d8 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -1,4 +1,5 @@ private import rust +private import codeql.rust.controlflow.ControlFlowGraph private import codeql.rust.elements.internal.generated.ParentChild private import codeql.rust.elements.internal.PathExprBaseImpl::Impl as PathExprBaseImpl private import codeql.rust.elements.internal.FormatTemplateVariableAccessImpl::Impl as FormatTemplateVariableAccessImpl @@ -445,7 +446,7 @@ module Impl { Variable getVariable() { result = v } /** Holds if this access is a capture. */ - predicate isCapture() { this.getEnclosingCallable() != v.getPat().getEnclosingCallable() } + predicate isCapture() { getEnclosingCfgScope(this) != getEnclosingCfgScope(v.getPat()) } override string toString() { result = name } diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected index 0b5c99ec7f3f..f17152793a3e 100644 --- a/rust/ql/test/library-tests/variables/Ssa.expected +++ b/rust/ql/test/library-tests/variables/Ssa.expected @@ -124,6 +124,8 @@ definition | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | | variables.rs:436:9:436:13 | i | variables.rs:436:13:436:13 | i | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | +| variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i | +| variables.rs:441:5:441:15 | AwaitExpr | variables.rs:436:13:436:13 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | | variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | @@ -239,8 +241,8 @@ read | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | | variables.rs:423:5:423:14 | CallExpr | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | -| variables.rs:436:9:436:13 | i | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | +| variables.rs:441:5:441:15 | AwaitExpr | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:447:15:447:15 | x | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:448:15:448:15 | x | @@ -343,8 +345,8 @@ firstRead | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | | variables.rs:423:5:423:14 | CallExpr | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | -| variables.rs:436:9:436:13 | i | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | +| variables.rs:441:5:441:15 | AwaitExpr | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:447:15:447:15 | x | | variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | variables.rs:458:15:458:15 | x | @@ -443,8 +445,8 @@ lastRead | variables.rs:420:9:420:20 | closure2 | variables.rs:420:13:420:20 | closure2 | variables.rs:423:5:423:12 | closure2 | | variables.rs:423:5:423:14 | CallExpr | variables.rs:418:13:418:13 | y | variables.rs:424:15:424:15 | y | | variables.rs:428:9:428:20 | closure3 | variables.rs:428:13:428:20 | closure3 | variables.rs:431:5:431:12 | closure3 | -| variables.rs:436:9:436:13 | i | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:437:9:437:13 | block | variables.rs:437:9:437:13 | block | variables.rs:441:5:441:9 | block | +| variables.rs:441:5:441:15 | AwaitExpr | variables.rs:436:13:436:13 | i | variables.rs:442:15:442:15 | i | | variables.rs:445:8:445:8 | b | variables.rs:445:8:445:8 | b | variables.rs:449:8:449:8 | b | | variables.rs:446:9:446:13 | x | variables.rs:446:13:446:13 | x | variables.rs:448:15:448:15 | x | | variables.rs:449:5:457:5 | phi | variables.rs:446:13:446:13 | x | variables.rs:458:15:458:15 | x | @@ -554,5 +556,6 @@ assigns | variables.rs:23:5:23:6 | x2 | variables.rs:23:10:23:10 | 5 | | variables.rs:30:5:30:5 | x | variables.rs:30:9:30:9 | 2 | | variables.rs:421:9:421:9 | y | variables.rs:421:13:421:13 | 3 | +| variables.rs:438:9:438:9 | i | variables.rs:438:13:438:13 | 1 | | variables.rs:450:9:450:9 | x | variables.rs:450:13:450:13 | 2 | | variables.rs:454:9:454:9 | x | variables.rs:454:13:454:13 | 3 | diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index 908ab40fc22e..6425411a3601 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -461,8 +461,10 @@ capturedVariable | variables.rs:410:13:410:13 | x | | variables.rs:418:13:418:13 | y | | variables.rs:426:13:426:13 | z | +| variables.rs:436:13:436:13 | i | capturedAccess | variables.rs:403:19:403:19 | x | | variables.rs:413:19:413:19 | x | | variables.rs:421:9:421:9 | y | | variables.rs:429:9:429:9 | z | +| variables.rs:438:9:438:9 | i | From db1b69868948058cfec0ef14e7beed166f4f736c Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 11 Nov 2024 08:59:34 +0100 Subject: [PATCH 5/8] Rust: Accept fixed spurious results --- .../unusedentities/CONSISTENCY/DataFlowConsistency.expected | 3 +++ rust/ql/test/query-tests/unusedentities/UnusedValue.expected | 2 -- rust/ql/test/query-tests/unusedentities/unreachable.rs | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected index b59b965efa12..d0187119e01c 100644 --- a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected +++ b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/DataFlowConsistency.expected @@ -218,6 +218,9 @@ uniqueCallEnclosingCallable | unreachable.rs:294:13:294:32 | CallExpr | Call should have one enclosing callable but has 0. | | unreachable.rs:296:9:296:22 | CallExpr | Call should have one enclosing callable but has 0. | | unreachable.rs:301:13:301:32 | CallExpr | Call should have one enclosing callable but has 0. | +| unreachable.rs:306:5:306:18 | CallExpr | Call should have one enclosing callable but has 0. | +| unreachable.rs:308:5:308:18 | CallExpr | Call should have one enclosing callable but has 0. | +| unreachable.rs:310:5:310:18 | CallExpr | Call should have one enclosing callable but has 0. | | unreachable.rs:318:22:318:41 | CallExpr | Call should have one enclosing callable but has 0. | | unreachable.rs:319:9:319:22 | CallExpr | Call should have one enclosing callable but has 0. | | unreachable.rs:322:9:322:22 | CallExpr | Call should have one enclosing callable but has 0. | diff --git a/rust/ql/test/query-tests/unusedentities/UnusedValue.expected b/rust/ql/test/query-tests/unusedentities/UnusedValue.expected index 6eebfc870bf3..f8538e5b8bc8 100644 --- a/rust/ql/test/query-tests/unusedentities/UnusedValue.expected +++ b/rust/ql/test/query-tests/unusedentities/UnusedValue.expected @@ -18,5 +18,3 @@ | more.rs:44:9:44:14 | a_ptr4 | Variable $@ is assigned a value that is never used. | more.rs:44:9:44:14 | a_ptr4 | a_ptr4 | | more.rs:59:9:59:13 | d_ptr | Variable $@ is assigned a value that is never used. | more.rs:59:9:59:13 | d_ptr | d_ptr | | more.rs:65:9:65:17 | f_ptr | Variable $@ is assigned a value that is never used. | more.rs:65:13:65:17 | f_ptr | f_ptr | -| unreachable.rs:292:9:292:15 | for_ten | Variable $@ is assigned a value that is never used. | unreachable.rs:292:9:292:15 | for_ten | for_ten | -| unreachable.rs:299:9:299:16 | for_ever | Variable $@ is assigned a value that is never used. | unreachable.rs:299:9:299:16 | for_ever | for_ever | diff --git a/rust/ql/test/query-tests/unusedentities/unreachable.rs b/rust/ql/test/query-tests/unusedentities/unreachable.rs index 5f26863b6257..f55459a0e6e7 100644 --- a/rust/ql/test/query-tests/unusedentities/unreachable.rs +++ b/rust/ql/test/query-tests/unusedentities/unreachable.rs @@ -289,14 +289,14 @@ pub fn unreachable_loop() { async fn do_something_async() {} pub async fn unreachable_loop_async() { - let for_ten = async { // $ SPURIOUS: Alert[rust/unused-value] + let for_ten = async { for _ in 1..10 { do_something_async().await; } do_something(); }; - let for_ever = async { // $ SPURIOUS: Alert[rust/unused-value] + let for_ever = async { loop { do_something_async().await; } From 9f0fba16cd615f00db3570b1f2e9a7b94252fd59 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 11 Nov 2024 09:15:53 +0100 Subject: [PATCH 6/8] Rust: Fix grammar and add documentation comments --- rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll | 2 ++ rust/ql/lib/codeql/rust/elements/AsyncBlockExpr.qll | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll index 0adcef156c00..dcbf3548c390 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll @@ -7,8 +7,10 @@ private import codeql.rust.elements.internal.generated.ParentChild * A control-flow graph (CFG) scope. */ abstract private class CfgScopeImpl extends AstNode { + /** Holds if `first` is executed first when entering `scope`. */ abstract predicate scopeFirst(AstNode first); + /** Holds if `scope` is exited when `last` finishes with completion `c`. */ abstract predicate scopeLast(AstNode last, Completion c); } diff --git a/rust/ql/lib/codeql/rust/elements/AsyncBlockExpr.qll b/rust/ql/lib/codeql/rust/elements/AsyncBlockExpr.qll index e590f999c9ac..951452cdf248 100644 --- a/rust/ql/lib/codeql/rust/elements/AsyncBlockExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/AsyncBlockExpr.qll @@ -1,7 +1,11 @@ +/** + * This module provides the public class `AsyncBlockExpr`. + */ + private import codeql.rust.elements.BlockExpr /** - * A async block expression. For example: + * An async block expression. For example: * ```rust * async { * let x = 42; From 63d84edfae92fe4b9a0b6fd309a1a0e708bc6925 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 12 Nov 2024 08:37:56 +0100 Subject: [PATCH 7/8] Rust: Fix minor issues from PR feedback --- .../rust/controlflow/ControlFlowGraph.qll | 5 ----- .../internal/ControlFlowGraphImpl.qll | 2 +- .../rust/controlflow/internal/Scope.qll | 19 ++++--------------- .../rust/dataflow/internal/DataFlowImpl.qll | 4 ++-- .../codeql/rust/dataflow/internal/SsaImpl.qll | 15 +++++++++------ .../rust/elements/internal/AstNodeImpl.qll | 11 +++++++++++ .../rust/elements/internal/VariableImpl.qll | 2 +- .../variables/variables.expected | 2 -- .../test/library-tests/variables/variables.rs | 2 +- 9 files changed, 29 insertions(+), 33 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll b/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll index 28965b1b18fc..20f1af4a4afb 100644 --- a/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll +++ b/rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll @@ -9,8 +9,6 @@ private import BasicBlocks final class CfgScope = Scope::CfgScope; -predicate getEnclosingCfgScope = Scope::getEnclosingCfgScope/1; - final class SuccessorType = SuccessorTypeImpl; final class NormalSuccessor = NormalSuccessorImpl; @@ -54,6 +52,3 @@ final class CfgNode extends Node { /** Gets the basic block that this control flow node belongs to. */ BasicBlock getBasicBlock() { result.getANode() = this } } - -/** Holds if evaluating `e` jumps to the evaluation of a different CFG scope. */ -predicate isControlFlowJump(Expr e) { e instanceof CallExprBase or e instanceof AwaitExpr } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 649b4729dc3e..b331ddd2d540 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -23,7 +23,7 @@ private module CfgInput implements InputSig { class CfgScope = Scope::CfgScope; CfgScope getCfgScope(AstNode n) { - result = Scope::getEnclosingCfgScope(n) and + result = n.getEnclosingCfgScope() and Stages::CfgStage::ref() } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll index dcbf3548c390..5a752abf4b9a 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll @@ -16,13 +16,12 @@ abstract private class CfgScopeImpl extends AstNode { final class CfgScope = CfgScopeImpl; -final class AsyncBlockScope extends CfgScopeImpl, AsyncBlockExpr { - override predicate scopeFirst(AstNode first) { - first(this.(ExprTrees::AsyncBlockExprTree).getFirstChildNode(), first) - } +final class AsyncBlockScope extends CfgScopeImpl, AsyncBlockExpr instanceof ExprTrees::AsyncBlockExprTree +{ + override predicate scopeFirst(AstNode first) { first(super.getFirstChildNode(), first) } override predicate scopeLast(AstNode last, Completion c) { - last(this.(ExprTrees::AsyncBlockExprTree).getLastChildElement(), last, c) + last(super.getLastChildElement(), last, c) } } @@ -52,13 +51,3 @@ final class CallableScope extends CfgScopeImpl, Callable { /** Holds if `scope` is exited when `last` finishes with completion `c`. */ override predicate scopeLast(AstNode last, Completion c) { last(this.getBody(), last, c) } } - -/** Gets the CFG scope that encloses `node`, if any. */ -CfgScope getEnclosingCfgScope(AstNode node) { - exists(AstNode p | p = node.getParentNode() | - result = p - or - not p instanceof CfgScope and - result = getEnclosingCfgScope(p) - ) -} diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index c93e374902a8..813c637af8df 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -134,7 +134,7 @@ module Node { ExprNode() { this = TExprNode(n) } - override CfgScope getCfgScope() { result = getEnclosingCfgScope(this.asExpr()) } + override CfgScope getCfgScope() { result = this.asExpr().getEnclosingCfgScope() } override Location getLocation() { result = n.getExpr().getLocation() } @@ -154,7 +154,7 @@ module Node { ParameterNode() { this = TParameterNode(parameter) } - override CfgScope getCfgScope() { result = getEnclosingCfgScope(parameter) } + override CfgScope getCfgScope() { result = parameter.getEnclosingCfgScope() } override Location getLocation() { result = parameter.getLocation() } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll index 955dd9995a24..d5263fca8106 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll @@ -156,7 +156,7 @@ private predicate variableReadActual(BasicBlock bb, int i, Variable v) { */ pragma[noinline] private predicate hasCapturedWrite(Variable v, Cfg::CfgScope scope) { - any(VariableWriteAccess write | write.getVariable() = v and scope = getEnclosingCfgScope+(write)) + any(VariableWriteAccess write | write.getVariable() = v and scope = write.getEnclosingCfgScope+()) .isCapture() } @@ -168,7 +168,7 @@ pragma[noinline] private predicate variableReadActualInOuterScope( BasicBlock bb, int i, Variable v, Cfg::CfgScope scope ) { - variableReadActual(bb, i, v) and bb.getScope() = getEnclosingCfgScope(scope) + variableReadActual(bb, i, v) and bb.getScope() = scope.getEnclosingCfgScope() } pragma[noinline] @@ -263,7 +263,7 @@ private predicate readsCapturedVariable(BasicBlock bb, Variable v) { */ pragma[noinline] private predicate hasCapturedRead(Variable v, Cfg::CfgScope scope) { - any(VariableReadAccess read | read.getVariable() = v and scope = getEnclosingCfgScope+(read)) + any(VariableReadAccess read | read.getVariable() = v and scope = read.getEnclosingCfgScope+()) .isCapture() } @@ -273,15 +273,18 @@ private predicate hasCapturedRead(Variable v, Cfg::CfgScope scope) { */ pragma[noinline] private predicate variableWriteInOuterScope(BasicBlock bb, int i, Variable v, Cfg::CfgScope scope) { - SsaInput::variableWrite(bb, i, v, _) and getEnclosingCfgScope(scope) = bb.getScope() + SsaInput::variableWrite(bb, i, v, _) and scope.getEnclosingCfgScope() = bb.getScope() } +/** Holds if evaluating `e` jumps to the evaluation of a different CFG scope. */ +private predicate isControlFlowJump(Expr e) { e instanceof CallExprBase or e instanceof AwaitExpr } + /** * Holds if the call `call` at index `i` in basic block `bb` may reach * a callable that reads captured variable `v`. */ private predicate capturedCallRead(Expr call, BasicBlock bb, int i, Variable v) { - Cfg::isControlFlowJump(call) and + isControlFlowJump(call) and exists(Cfg::CfgScope scope | hasCapturedRead(v, scope) and ( @@ -297,7 +300,7 @@ private predicate capturedCallRead(Expr call, BasicBlock bb, int i, Variable v) * that writes captured variable `v`. */ predicate capturedCallWrite(Expr call, BasicBlock bb, int i, Variable v) { - Cfg::isControlFlowJump(call) and + isControlFlowJump(call) and call = bb.getNode(i).getAstNode() and exists(Cfg::CfgScope scope | hasVariableReadWithCapturedWrite(bb, any(int j | j > i), v, scope) diff --git a/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll index b3dd56706032..c198436ea3e0 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll @@ -5,6 +5,7 @@ */ private import codeql.rust.elements.internal.generated.AstNode +private import codeql.rust.controlflow.ControlFlowGraph /** * INTERNAL: This module contains the customizable definition of `AstNode` and should not @@ -44,6 +45,16 @@ module Impl { ) } + /** Gets the CFG scope that encloses this node, if any. */ + CfgScope getEnclosingCfgScope() { + exists(AstNode p | p = this.getParentNode() | + result = p + or + not p instanceof CfgScope and + result = p.getEnclosingCfgScope() + ) + } + /** Holds if this node is inside a macro expansion. */ predicate isInMacroExpansion() { this = any(MacroCall mc).getExpanded() diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index bed98189e4d8..4b94546d8027 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -446,7 +446,7 @@ module Impl { Variable getVariable() { result = v } /** Holds if this access is a capture. */ - predicate isCapture() { getEnclosingCfgScope(this) != getEnclosingCfgScope(v.getPat()) } + predicate isCapture() { this.getEnclosingCfgScope() != v.getPat().getEnclosingCfgScope() } override string toString() { result = name } diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected index 6425411a3601..6760f9bcdde3 100644 --- a/rust/ql/test/library-tests/variables/variables.expected +++ b/rust/ql/test/library-tests/variables/variables.expected @@ -1,6 +1,4 @@ testFailures -| variables.rs:438:9:438:9 | i | Unexpected result: write_access=i | -| variables.rs:438:16:438:33 | Comment | Missing result: read_access=i | failures variable | variables.rs:3:14:3:14 | s | diff --git a/rust/ql/test/library-tests/variables/variables.rs b/rust/ql/test/library-tests/variables/variables.rs index c5b9bd80a8bd..8dd00c7ebb27 100644 --- a/rust/ql/test/library-tests/variables/variables.rs +++ b/rust/ql/test/library-tests/variables/variables.rs @@ -435,7 +435,7 @@ fn capture_mut() { async fn async_block_capture() { let mut i: i64 = 0; // i let block = async { - i = 1; // $ read_access=i + i = 1; // $ write_access=i }; // The await below causes write to `i` block.await; // $ read_access=block From 274d9421a74309d1285dbfd598e3e2346fa2ec49 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 12 Nov 2024 13:15:20 +0100 Subject: [PATCH 8/8] Rust: Cache `getEnclosingCfgScope` --- rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll index c198436ea3e0..f2784d058ae7 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll @@ -46,6 +46,7 @@ module Impl { } /** Gets the CFG scope that encloses this node, if any. */ + cached CfgScope getEnclosingCfgScope() { exists(AstNode p | p = this.getParentNode() | result = p