Skip to content

Commit c80301d

Browse files
committed
Rust: Handle variables introduced in if-let guards
1 parent db7b187 commit c80301d

File tree

4 files changed

+25
-24
lines changed

4 files changed

+25
-24
lines changed

rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,12 @@ module Impl {
1515

1616
class BlockExprScope extends VariableScope, BlockExpr { }
1717

18-
abstract class MatchArmScope extends VariableScope {
19-
MatchArm arm;
20-
21-
bindingset[arm]
22-
MatchArmScope() { exists(arm) }
23-
24-
Pat getPat() { result = arm.getPat() }
18+
class MatchArmExprScope extends VariableScope {
19+
MatchArmExprScope() { this = any(MatchArm arm).getExpr() }
2520
}
2621

27-
class MatchArmExprScope extends MatchArmScope {
28-
MatchArmExprScope() { this = arm.getExpr() }
29-
}
30-
31-
class MatchArmGuardScope extends MatchArmScope {
32-
MatchArmGuardScope() { this = arm.getGuard() }
22+
class MatchArmGuardScope extends VariableScope {
23+
MatchArmGuardScope() { this = any(MatchArm arm).getGuard() }
3324
}
3425

3526
class ClosureBodyScope extends VariableScope {
@@ -41,7 +32,7 @@ module Impl {
4132
*
4233
* Such variables are only available in the body guarded by the condition.
4334
*/
44-
class ConditionScope extends VariableScope, Expr {
35+
class ConditionScope extends VariableScope {
4536
private AstNode parent;
4637
private AstNode body;
4738

@@ -57,6 +48,12 @@ module Impl {
5748
this = we.getCondition() and
5849
body = we.getLoopBody()
5950
)
51+
or
52+
parent =
53+
any(MatchArm ma |
54+
this = ma.getGuard() and
55+
body = ma.getExpr()
56+
)
6057
}
6158

6259
/** Gets the parent of this condition. */
@@ -417,11 +414,14 @@ module Impl {
417414
ord = getPreOrderNumbering(scope, scope)
418415
or
419416
exists(Pat pat | pat = getAVariablePatAncestor(v) |
420-
scope =
421-
any(MatchArmScope arm |
422-
arm.getPat() = pat and
423-
ord = getPreOrderNumbering(scope, arm)
424-
)
417+
exists(MatchArm arm |
418+
pat = arm.getPat() and
419+
ord = getPreOrderNumbering(scope, scope)
420+
|
421+
scope = arm.getGuard()
422+
or
423+
not arm.hasGuard() and scope = arm.getExpr()
424+
)
425425
or
426426
exists(LetStmt let |
427427
let.getPat() = pat and

rust/ql/test/library-tests/variables/Ssa.expected

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ definition
9696
| main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x |
9797
| main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x |
9898
| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y |
99+
| main.rs:376:25:376:25 | y | main.rs:376:25:376:25 | y |
99100
| main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 |
100101
| main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 |
101102
| main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 |
@@ -288,7 +289,7 @@ read
288289
| main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x | main.rs:367:20:367:20 | x |
289290
| main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x | main.rs:374:11:374:11 | x |
290291
| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:377:22:377:22 | y |
291-
| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:378:26:378:26 | y |
292+
| main.rs:376:25:376:25 | y | main.rs:376:25:376:25 | y | main.rs:378:26:378:26 | y |
292293
| main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 | main.rs:390:15:390:16 | a8 |
293294
| main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 | main.rs:391:15:391:16 | b3 |
294295
| main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 | main.rs:392:15:392:16 | c1 |
@@ -479,6 +480,7 @@ firstRead
479480
| main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x | main.rs:367:20:367:20 | x |
480481
| main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x | main.rs:374:11:374:11 | x |
481482
| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:377:22:377:22 | y |
483+
| main.rs:376:25:376:25 | y | main.rs:376:25:376:25 | y | main.rs:378:26:378:26 | y |
482484
| main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 | main.rs:390:15:390:16 | a8 |
483485
| main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 | main.rs:391:15:391:16 | b3 |
484486
| main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 | main.rs:392:15:392:16 | c1 |
@@ -587,7 +589,6 @@ adjacentReads
587589
| main.rs:334:9:334:9 | x | main.rs:334:9:334:9 | x | main.rs:335:11:335:11 | x | main.rs:343:15:343:15 | x |
588590
| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:350:7:350:7 | x | main.rs:355:7:355:7 | x |
589591
| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:355:7:355:7 | x | main.rs:359:19:359:19 | x |
590-
| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:377:22:377:22 | y | main.rs:378:26:378:26 | y |
591592
| main.rs:402:13:402:15 | a10 | main.rs:402:13:402:15 | a10 | main.rs:406:15:406:17 | a10 | main.rs:415:9:415:11 | a10 |
592593
| main.rs:403:13:403:14 | b4 | main.rs:403:13:403:14 | b4 | main.rs:407:15:407:16 | b4 | main.rs:416:9:416:10 | b4 |
593594
| main.rs:404:13:404:14 | c2 | main.rs:404:13:404:14 | c2 | main.rs:408:15:408:16 | c2 | main.rs:417:9:417:10 | c2 |

rust/ql/test/library-tests/variables/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ fn match_pattern16() {
375375
Some(y) // y1
376376
if let Some(y) = // y2
377377
Some(y) // $ read_access=y1
378-
=> print_i64(y), // $ MISSING: read_access=y2 $ SPURIOUS: read_access=y1
378+
=> print_i64(y), // $ read_access=y2
379379
_ => {},
380380
}
381381
}

rust/ql/test/library-tests/variables/variables.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ variableAccess
238238
| main.rs:367:20:367:20 | x | main.rs:366:18:366:18 | x |
239239
| main.rs:374:11:374:11 | x | main.rs:373:9:373:9 | x |
240240
| main.rs:377:22:377:22 | y | main.rs:375:14:375:14 | y |
241-
| main.rs:378:26:378:26 | y | main.rs:375:14:375:14 | y |
241+
| main.rs:378:26:378:26 | y | main.rs:376:25:376:25 | y |
242242
| main.rs:390:15:390:16 | a8 | main.rs:384:5:384:6 | a8 |
243243
| main.rs:391:15:391:16 | b3 | main.rs:386:9:386:10 | b3 |
244244
| main.rs:392:15:392:16 | c1 | main.rs:387:9:387:10 | c1 |
@@ -470,7 +470,7 @@ variableReadAccess
470470
| main.rs:367:20:367:20 | x | main.rs:366:18:366:18 | x |
471471
| main.rs:374:11:374:11 | x | main.rs:373:9:373:9 | x |
472472
| main.rs:377:22:377:22 | y | main.rs:375:14:375:14 | y |
473-
| main.rs:378:26:378:26 | y | main.rs:375:14:375:14 | y |
473+
| main.rs:378:26:378:26 | y | main.rs:376:25:376:25 | y |
474474
| main.rs:390:15:390:16 | a8 | main.rs:384:5:384:6 | a8 |
475475
| main.rs:391:15:391:16 | b3 | main.rs:386:9:386:10 | b3 |
476476
| main.rs:392:15:392:16 | c1 | main.rs:387:9:387:10 | c1 |

0 commit comments

Comments
 (0)