Skip to content

Commit a9cf33c

Browse files
committed
Rust: &x is neither a read nor a write
1 parent 05f8549 commit a9cf33c

File tree

4 files changed

+61
-36
lines changed

4 files changed

+61
-36
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/** Provides classes for assignment operations. */
2+
3+
private import rust
4+
private import codeql.rust.elements.internal.BinaryExprImpl
5+
6+
/** An assignment operation. */
7+
abstract private class AssignmentOperationImpl extends Impl::BinaryExpr { }
8+
9+
final class AssignmentOperation = AssignmentOperationImpl;
10+
11+
/**
12+
* An assignment expression, for example
13+
*
14+
* ```rust
15+
* x = y;
16+
* ```
17+
*/
18+
final class AssignmentExpr extends AssignmentOperationImpl {
19+
AssignmentExpr() { this.getOperatorName() = "=" }
20+
21+
override string getAPrimaryQlClass() { result = "AssignmentExpr" }
22+
}
23+
24+
/**
25+
* A compound assignment expression, for example
26+
*
27+
* ```rust
28+
* x += y;
29+
* ```
30+
*
31+
* Note that compound assignment expressions are syntatic sugar for
32+
* trait invocations, i.e., the above actually means
33+
*
34+
* ```rust
35+
* (&mut x).add_assign(y);
36+
* ```
37+
*/
38+
final class CompoundAssignmentExpr extends AssignmentOperationImpl {
39+
private string operator;
40+
41+
CompoundAssignmentExpr() { this.getOperatorName().regexpCapture("(.)=", 1) = operator }
42+
43+
/**
44+
* Gets the operator of this compound assignment expression.
45+
*/
46+
string getOperator() { result = operator }
47+
48+
override string getAPrimaryQlClass() { result = "CompoundAssignmentExpr" }
49+
}

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

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -395,34 +395,27 @@ module Impl {
395395
}
396396

397397
/** Holds if `e` occurs in the LHS of an assignment or compound assignment. */
398-
private predicate assignLhs(Expr e, boolean compound) {
399-
exists(BinaryExpr be, string op |
400-
op = be.getOperatorName().regexpCapture("(.*)=", 1) and
401-
e = be.getLhs()
402-
|
403-
op = "" and compound = false
404-
or
405-
op != "" and compound = true
406-
)
398+
private predicate assignmentExprDescendant(Expr e) {
399+
e = any(AssignmentExpr ae).getLhs()
407400
or
408401
exists(Expr mid |
409-
assignLhs(mid, compound) and
410-
getImmediateParent(e) = mid
402+
assignmentExprDescendant(mid) and
403+
getImmediateParent(e) = mid and
404+
not mid.(PrefixExpr).getOperatorName() = "*"
411405
)
412406
}
413407

414408
/** A variable write. */
415409
class VariableWriteAccess extends VariableAccess {
416-
VariableWriteAccess() { assignLhs(this, _) }
410+
VariableWriteAccess() { assignmentExprDescendant(this) }
417411
}
418412

419413
/** A variable read. */
420414
class VariableReadAccess extends VariableAccess {
421415
VariableReadAccess() {
422-
not this instanceof VariableWriteAccess
423-
or
424-
// consider LHS in compound assignments both reads and writes
425-
assignLhs(this, true)
416+
not this instanceof VariableWriteAccess and
417+
not this = any(RefExpr re).getExpr() and
418+
not this = any(CompoundAssignmentExpr cae).getLhs()
426419
}
427420
}
428421

rust/ql/lib/rust.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
import codeql.rust.elements
44
import codeql.Locations
55
import codeql.files.FileSystem
6+
import codeql.rust.elements.AssignmentOperation
67
import codeql.rust.elements.LogicalOperation
78
import codeql.rust.elements.Variable

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

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,4 @@
11
testFailures
2-
| variables.rs:331:5:331:5 | a | Unexpected result: read_access=a |
3-
| variables.rs:331:5:331:5 | a | Unexpected result: write_access=a |
4-
| variables.rs:331:13:331:25 | Comment | Missing result:access=a |
5-
| variables.rs:333:11:333:11 | a | Unexpected result: read_access=a |
6-
| variables.rs:333:30:333:42 | Comment | Missing result:access=a |
7-
| variables.rs:340:14:340:14 | i | Unexpected result: read_access=i |
8-
| variables.rs:340:17:340:29 | Comment | Missing result:access=i |
9-
| variables.rs:341:6:341:10 | ref_i | Unexpected result: write_access=ref_i |
10-
| variables.rs:341:17:341:38 | Comment | Missing result:read_access=ref_i |
11-
| variables.rs:346:6:346:6 | x | Unexpected result: write_access=x |
12-
| variables.rs:346:10:346:27 | Comment | Missing result:read_access=x |
13-
| variables.rs:353:23:353:23 | x | Unexpected result: read_access=x |
14-
| variables.rs:353:27:353:39 | Comment | Missing result:access=x |
152
failures
163
variable
174
| variables.rs:3:14:3:14 | s |
@@ -185,9 +172,6 @@ variableWriteAccess
185172
| variables.rs:277:9:277:10 | c2 | variables.rs:270:13:270:14 | c2 |
186173
| variables.rs:278:9:278:10 | b4 | variables.rs:269:13:269:14 | b4 |
187174
| variables.rs:279:9:279:11 | a10 | variables.rs:268:13:268:15 | a10 |
188-
| variables.rs:331:5:331:5 | a | variables.rs:330:13:330:13 | a |
189-
| variables.rs:341:6:341:10 | ref_i | variables.rs:339:9:339:13 | ref_i |
190-
| variables.rs:346:6:346:6 | x | variables.rs:345:17:345:17 | x |
191175
variableReadAccess
192176
| variables.rs:13:15:13:16 | x1 | variables.rs:12:9:12:10 | x1 |
193177
| variables.rs:18:15:18:16 | x2 | variables.rs:17:13:17:14 | x2 |
@@ -267,15 +251,13 @@ variableReadAccess
267251
| variables.rs:317:15:317:16 | n2 | variables.rs:315:9:315:10 | n2 |
268252
| variables.rs:324:12:324:12 | v | variables.rs:321:9:321:9 | v |
269253
| variables.rs:325:19:325:22 | text | variables.rs:323:9:323:12 | text |
270-
| variables.rs:331:5:331:5 | a | variables.rs:330:13:330:13 | a |
271254
| variables.rs:332:15:332:15 | a | variables.rs:330:13:330:13 | a |
272-
| variables.rs:333:11:333:11 | a | variables.rs:330:13:330:13 | a |
273255
| variables.rs:334:15:334:15 | a | variables.rs:330:13:330:13 | a |
274-
| variables.rs:340:14:340:14 | i | variables.rs:338:13:338:13 | i |
256+
| variables.rs:341:6:341:10 | ref_i | variables.rs:339:9:339:13 | ref_i |
275257
| variables.rs:342:15:342:15 | i | variables.rs:338:13:338:13 | i |
258+
| variables.rs:346:6:346:6 | x | variables.rs:345:17:345:17 | x |
276259
| variables.rs:347:10:347:10 | x | variables.rs:345:17:345:17 | x |
277260
| variables.rs:348:10:348:10 | x | variables.rs:345:17:345:17 | x |
278-
| variables.rs:353:23:353:23 | x | variables.rs:352:13:352:13 | x |
279261
| variables.rs:354:15:354:15 | x | variables.rs:352:13:352:13 | x |
280262
variableInitializer
281263
| variables.rs:12:9:12:10 | x1 | variables.rs:12:14:12:16 | "a" |

0 commit comments

Comments
 (0)