Skip to content

Commit 20a012d

Browse files
authored
Merge pull request #19454 from geoffw0/deref
Rust: Add Operation class
2 parents 1c863b1 + b3dc7a2 commit 20a012d

File tree

10 files changed

+181
-16
lines changed

10 files changed

+181
-16
lines changed

rust/ql/lib/codeql/rust/elements/AssignmentOperation.qll

+12-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
1-
/** Provides classes for assignment operations. */
1+
/**
2+
* Provides classes for assignment operations.
3+
*/
24

35
private import rust
46
private import codeql.rust.elements.internal.BinaryExprImpl
57

6-
/** An assignment operation. */
8+
/**
9+
* An assignment operation, for example:
10+
* ```rust
11+
* x = y;
12+
* x += y;
13+
* ```
14+
*/
715
abstract private class AssignmentOperationImpl extends Impl::BinaryExpr { }
816

917
final class AssignmentOperation = AssignmentOperationImpl;
1018

1119
/**
12-
* An assignment expression, for example
13-
*
20+
* An assignment expression, for example:
1421
* ```rust
1522
* x = y;
1623
* ```
@@ -22,8 +29,7 @@ final class AssignmentExpr extends AssignmentOperationImpl {
2229
}
2330

2431
/**
25-
* A compound assignment expression, for example
26-
*
32+
* A compound assignment expression, for example:
2733
* ```rust
2834
* x += y;
2935
* ```
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,46 @@
11
private import codeql.rust.elements.Expr
22
private import codeql.rust.elements.BinaryExpr
33
private import codeql.rust.elements.PrefixExpr
4+
private import codeql.rust.elements.Operation
45

5-
abstract private class LogicalOperationImpl extends Expr {
6-
abstract Expr getAnOperand();
7-
}
6+
/**
7+
* A logical operation, such as `&&`, `||` or `!`.
8+
*/
9+
abstract private class LogicalOperationImpl extends Operation { }
810

911
final class LogicalOperation = LogicalOperationImpl;
1012

11-
abstract private class BinaryLogicalOperationImpl extends BinaryExpr, LogicalOperationImpl {
12-
override Expr getAnOperand() { result = [this.getLhs(), this.getRhs()] }
13-
}
13+
/**
14+
* A binary logical operation, such as `&&` or `||`.
15+
*/
16+
abstract private class BinaryLogicalOperationImpl extends BinaryExpr, LogicalOperationImpl { }
1417

1518
final class BinaryLogicalOperation = BinaryLogicalOperationImpl;
1619

20+
/**
21+
* The logical "and" operation, `&&`.
22+
*/
1723
final class LogicalAndExpr extends BinaryLogicalOperationImpl, BinaryExpr {
1824
LogicalAndExpr() { this.getOperatorName() = "&&" }
1925
}
2026

27+
/**
28+
* The logical "or" operation, `||`.
29+
*/
2130
final class LogicalOrExpr extends BinaryLogicalOperationImpl {
2231
LogicalOrExpr() { this.getOperatorName() = "||" }
2332
}
2433

34+
/**
35+
* A unary logical operation, such as `!`.
36+
*/
2537
abstract private class UnaryLogicalOperationImpl extends PrefixExpr, LogicalOperationImpl { }
2638

2739
final class UnaryLogicalOperation = UnaryLogicalOperationImpl;
2840

41+
/**
42+
* A logical "not" operation, `!`.
43+
*/
2944
final class LogicalNotExpr extends UnaryLogicalOperationImpl {
3045
LogicalNotExpr() { this.getOperatorName() = "!" }
31-
32-
override Expr getAnOperand() { result = this.getExpr() }
3346
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* Provides classes for operations.
3+
*/
4+
5+
private import internal.OperationImpl
6+
private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl
7+
8+
final class Operation = Impl::Operation;

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
private import codeql.rust.elements.internal.generated.BinaryExpr
8+
private import codeql.rust.elements.internal.OperationImpl::Impl as OperationImpl
89

910
/**
1011
* INTERNAL: This module contains the customizable definition of `BinaryExpr` and should not
@@ -22,7 +23,11 @@ module Impl {
2223
* x += y;
2324
* ```
2425
*/
25-
class BinaryExpr extends Generated::BinaryExpr {
26+
class BinaryExpr extends Generated::BinaryExpr, OperationImpl::Operation {
2627
override string toStringImpl() { result = "... " + this.getOperatorName() + " ..." }
28+
29+
override string getOperatorName() { result = Generated::BinaryExpr.super.getOperatorName() }
30+
31+
override Expr getAnOperand() { result = [this.getLhs(), this.getRhs()] }
2732
}
2833
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Provides classes for operations.
3+
*
4+
* INTERNAL: Do not use.
5+
*/
6+
7+
private import rust
8+
private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl
9+
10+
/**
11+
* INTERNAL: This module contains the customizable definition of `Operation` and should not
12+
* be referenced directly.
13+
*/
14+
module Impl {
15+
/**
16+
* An operation, for example `&&`, `+=`, `!` or `*`.
17+
*/
18+
abstract class Operation extends ExprImpl::Expr {
19+
/**
20+
* Gets the operator name of this operation, if it exists.
21+
*/
22+
abstract string getOperatorName();
23+
24+
/**
25+
* Gets an operand of this operation.
26+
*/
27+
abstract Expr getAnOperand();
28+
}
29+
}

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
private import codeql.rust.elements.internal.generated.PrefixExpr
8+
private import codeql.rust.elements.internal.OperationImpl::Impl as OperationImpl
89

910
/**
1011
* INTERNAL: This module contains the customizable definition of `PrefixExpr` and should not
@@ -20,7 +21,11 @@ module Impl {
2021
* let z = *ptr;
2122
* ```
2223
*/
23-
class PrefixExpr extends Generated::PrefixExpr {
24+
class PrefixExpr extends Generated::PrefixExpr, OperationImpl::Operation {
2425
override string toStringImpl() { result = this.getOperatorName() + " ..." }
26+
27+
override string getOperatorName() { result = Generated::PrefixExpr.super.getOperatorName() }
28+
29+
override Expr getAnOperand() { result = this.getExpr() }
2530
}
2631
}

rust/ql/lib/rust.qll

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import codeql.rust.elements
44
import codeql.Locations
55
import codeql.files.FileSystem
6+
import codeql.rust.elements.Operation
67
import codeql.rust.elements.AssignmentOperation
78
import codeql.rust.elements.LogicalOperation
89
import codeql.rust.elements.AsyncBlockExpr

rust/ql/test/library-tests/operations/Operations.expected

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import rust
2+
import utils.test.InlineExpectationsTest
3+
4+
string describe(Expr op) {
5+
op instanceof Operation and result = "Operation"
6+
or
7+
op instanceof PrefixExpr and result = "PrefixExpr"
8+
or
9+
op instanceof BinaryExpr and result = "BinaryExpr"
10+
or
11+
op instanceof AssignmentOperation and result = "AssignmentOperation"
12+
or
13+
op instanceof LogicalOperation and result = "LogicalOperation"
14+
or
15+
op instanceof RefExpr and result = "RefExpr"
16+
}
17+
18+
module OperationsTest implements TestSig {
19+
string getARelevantTag() { result = describe(_) or result = ["Op", "Operands"] }
20+
21+
predicate hasActualResult(Location location, string element, string tag, string value) {
22+
exists(Expr op |
23+
location = op.getLocation() and
24+
location.getFile().getBaseName() != "" and
25+
element = op.toString() and
26+
(
27+
tag = describe(op) and
28+
value = ""
29+
or
30+
tag = "Op" and
31+
value = op.(Operation).getOperatorName()
32+
or
33+
op instanceof Operation and
34+
tag = "Operands" and
35+
value = count(op.(Operation).getAnOperand()).toString()
36+
)
37+
)
38+
}
39+
}
40+
41+
import MakeTest<OperationsTest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
2+
// --- tests ---
3+
4+
fn test_operations(
5+
y: i32, a: bool, b: bool,
6+
ptr: &i32, res: Result<i32, ()>) -> Result<(), ()>
7+
{
8+
let mut x: i32;
9+
10+
// simple assignment
11+
x = y; // $ Operation Op== Operands=2 AssignmentOperation BinaryExpr
12+
13+
// comparison operations
14+
x == y; // $ Operation Op=== Operands=2 BinaryExpr
15+
x != y; // $ Operation Op=!= Operands=2 BinaryExpr
16+
x < y; // $ Operation Op=< Operands=2 BinaryExpr
17+
x <= y; // $ Operation Op=<= Operands=2 BinaryExpr
18+
x > y; // $ Operation Op=> Operands=2 BinaryExpr
19+
x >= y; // $ Operation Op=>= Operands=2 BinaryExpr
20+
21+
// arithmetic operations
22+
x + y; // $ Operation Op=+ Operands=2 BinaryExpr
23+
x - y; // $ Operation Op=- Operands=2 BinaryExpr
24+
x * y; // $ Operation Op=* Operands=2 BinaryExpr
25+
x / y; // $ Operation Op=/ Operands=2 BinaryExpr
26+
x % y; // $ Operation Op=% Operands=2 BinaryExpr
27+
x += y; // $ Operation Op=+= Operands=2 AssignmentOperation BinaryExpr
28+
x -= y; // $ Operation Op=-= Operands=2 AssignmentOperation BinaryExpr
29+
x *= y; // $ Operation Op=*= Operands=2 AssignmentOperation BinaryExpr
30+
x /= y; // $ Operation Op=/= Operands=2 AssignmentOperation BinaryExpr
31+
x %= y; // $ Operation Op=%= Operands=2 AssignmentOperation BinaryExpr
32+
-x; // $ Operation Op=- Operands=1 PrefixExpr
33+
34+
// logical operations
35+
a && b; // $ Operation Op=&& Operands=2 BinaryExpr LogicalOperation
36+
a || b; // $ Operation Op=|| Operands=2 BinaryExpr LogicalOperation
37+
!a; // $ Operation Op=! Operands=1 PrefixExpr LogicalOperation
38+
39+
// bitwise operations
40+
x & y; // $ Operation Op=& Operands=2 BinaryExpr
41+
x | y; // $ Operation Op=| Operands=2 BinaryExpr
42+
x ^ y; // $ Operation Op=^ Operands=2 BinaryExpr
43+
x << y; // $ Operation Op=<< Operands=2 BinaryExpr
44+
x >> y; // $ Operation Op=>> Operands=2 BinaryExpr
45+
x &= y; // $ Operation Op=&= Operands=2 AssignmentOperation BinaryExpr
46+
x |= y; // $ Operation Op=|= Operands=2 AssignmentOperation BinaryExpr
47+
x ^= y; // $ Operation Op=^= Operands=2 AssignmentOperation BinaryExpr
48+
x <<= y; // $ Operation Op=<<= Operands=2 AssignmentOperation BinaryExpr
49+
x >>= y; // $ Operation Op=>>= Operands=2 AssignmentOperation BinaryExpr
50+
51+
// miscellaneous expressions that might be operations
52+
*ptr; // $ Operation Op=* Operands=1 PrefixExpr
53+
&x; // $ RefExpr
54+
res?;
55+
56+
return Ok(());
57+
}

0 commit comments

Comments
 (0)