Skip to content

Commit 870cf29

Browse files
committed
wip
1 parent f2abf80 commit 870cf29

File tree

10 files changed

+86
-71
lines changed

10 files changed

+86
-71
lines changed

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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,6 @@ private import internal.CallImpl
77

88
final class Call = Impl::Call;
99

10-
// todo: remove once internal query has been updated
11-
final class CallExpr extends ParenArgsExpr {
12-
Expr getFunction() { result = this.getBase() }
13-
14-
Expr getArg(int i) { result = this.getArgument(i) }
15-
16-
int getNumberOfArgs() { result = this.getNumberOfArguments() }
17-
}
18-
1910
private predicate isClosureCall(ParenArgsExpr call) {
2011
exists(Expr receiver | receiver = call.getBase() |
2112
// All calls to complex expressions and local variable accesses are lambda calls
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* This module provides the public class `CallExpr`.
3+
*/
4+
5+
private import rust
6+
private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl
7+
private import codeql.rust.internal.TypeInference as TypeInference
8+
9+
/**
10+
* A call expression. For example:
11+
* ```rust
12+
* foo(42);
13+
* foo::<u32, u64>(42);
14+
* foo[0](42);
15+
* foo(1) = 4;
16+
* ```
17+
*/
18+
final class CallExpr extends CallImpl::Call instanceof ParenArgsExpr {
19+
CallExpr() {
20+
forall(Addressable target |
21+
// Cannot use `this.getResolvedTarget()` as that results in non-monotonic recursion
22+
target = TypeInference::resolveCallTarget(this)
23+
|
24+
target instanceof Callable
25+
)
26+
}
27+
28+
private predicate isMethodCall() { this.getResolvedTarget() instanceof Method }
29+
30+
override Expr getArgument(int i) {
31+
if this.isMethodCall()
32+
then result = super.getArgList().getArg(i + 1)
33+
else result = super.getArgList().getArg(i)
34+
}
35+
36+
override Expr getReceiver() { this.isMethodCall() and result = super.getArgList().getArg(0) }
37+
38+
/**
39+
* Gets the `index`th attr of this paren arguments expression (0-based).
40+
*/
41+
Attr getAttr(int index) { result = super.getAttr(index) }
42+
43+
/**
44+
* Gets any of the attrs of this paren arguments expression.
45+
*/
46+
Attr getAnAttr() { result = this.getAttr(_) }
47+
48+
/**
49+
* Gets the number of attrs of this paren arguments expression.
50+
*/
51+
int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) }
52+
53+
/**
54+
* Gets the base of this paren arguments expression, if it exists.
55+
*/
56+
Expr getBase() { result = super.getBase() }
57+
58+
/**
59+
* Holds if `getBase()` exists.
60+
*/
61+
predicate hasBase() { exists(this.getBase()) }
62+
63+
// todo: remove once internal query has been updated
64+
Expr getFunction() { result = this.getBase() }
65+
66+
// todo: remove once internal query has been updated
67+
Expr getArg(int i) { result = this.getArgument(i) }
68+
69+
// todo: remove once internal query has been updated
70+
int getNumberOfArgs() { result = this.getNumberOfArguments() }
71+
}

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,6 @@ module Impl {
1919
/** Gets the number of positional arguments of this expression. */
2020
int getNumberOfArguments() { result = count(Expr arg | arg = this.getArgument(_)) }
2121

22-
/**
23-
* Gets the receiver of this expression, if any.
24-
*
25-
* This is either an actual receiver of a method call, the first operand of an operation,
26-
* or the base expression of an index expression.
27-
*/
28-
Expr getReceiver() { none() }
29-
3022
/** Gets the resolved target (function or tuple struct/variant) of this call, if any. */
3123
Addressable getResolvedTarget() { result = TypeInference::resolveCallTarget(this) }
3224
}

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

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,25 @@ private import rust
33
module Impl {
44
private import codeql.rust.internal.TypeInference as TypeInference
55
private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl
6+
private import codeql.rust.elements.internal.ArgsExprImpl::Impl as ArgsExprImpl
67

78
/**
89
* A call.
910
*
1011
* Either
1112
*
12-
* - a `ParenArgsExpr` that targets a function,
13+
* - a `CallExpr`,
1314
* - a `MethodCallExpr`,
1415
* - an `Operation` that targets an overloadable opeator, or
1516
* - an `IndexExpr`.
1617
*/
17-
abstract class Call extends ExprImpl::Expr {
18-
/** Gets the `i`th positional argument of this call, if any. */
19-
Expr getArgument(int i) { none() }
20-
21-
// todo: remove once internal query has been updated
22-
Expr getArg(int i) { result = this.getArgument(i) }
23-
24-
/** Gets a positional argument of this call, if any. */
25-
Expr getAnArgument() { result = this.getArgument(_) }
26-
27-
/** Gets the number of positional arguments of this call. */
28-
int getNumberOfArguments() { result = count(Expr arg | arg = this.getArgument(_)) }
29-
30-
// todo: remove once internal query has been updated
31-
int getNumberOfArgs() { result = this.getNumberOfArguments() }
32-
18+
abstract class Call extends ArgsExprImpl::ArgsExpr {
3319
/**
3420
* Gets the receiver of this call, if any.
3521
*
36-
* This is either an actual receiver of a method call, the first operand of an operation,
22+
* This is either an actual receiver of a method call, the first argument of a call
23+
* to a method
24+
* the first operand of an operation,
3725
* or the base expression of an index expression.
3826
*/
3927
Expr getReceiver() { none() }

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,4 @@ module Impl {
3232

3333
override Expr getReceiver() { result = this.getBase() }
3434
}
35-
36-
private class IndexArgsExpr extends ArgsExprImpl::ArgsExpr instanceof IndexExpr {
37-
override Expr getArgument(int i) { result = IndexExpr.super.getArgument(i) }
38-
39-
override Expr getReceiver() { result = IndexExpr.super.getReceiver() }
40-
}
4135
}

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,4 @@ module Impl {
4949

5050
override Expr getReceiver() { result = Generated::MethodCallExpr.super.getReceiver() }
5151
}
52-
53-
private class MethodCallArgsExpr extends ArgsExprImpl::ArgsExpr instanceof MethodCallExpr {
54-
override Expr getArgument(int i) { result = MethodCallExpr.super.getArgument(i) }
55-
56-
override Expr getReceiver() { result = MethodCallExpr.super.getReceiver() }
57-
}
5852
}

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,10 @@ module Impl {
115115
/** Gets the `n`th operand of this operation, if any. */
116116
abstract Expr getOperand(int n);
117117

118-
override Expr getArgument(int i) { result = this.getOperand(i + 1) and i >= 0 }
119-
120-
override Expr getReceiver() { result = this.getOperand(0) }
118+
override Expr getArgument(int i) {
119+
not this.isOverloaded(_, _, _) and
120+
result = this.getOperand(i)
121+
}
121122

122123
/**
123124
* Gets the number of operands of this operation.
@@ -142,8 +143,8 @@ module Impl {
142143
private class CallOperation extends CallImpl::Call instanceof Operation {
143144
CallOperation() { super.isOverloaded(_, _, _) }
144145

145-
override Expr getArgument(int i) { result = Operation.super.getArgument(i) }
146+
override Expr getArgument(int i) { result = super.getOperand(i + 1) and i >= 0 }
146147

147-
override Expr getReceiver() { result = Operation.super.getReceiver() }
148+
override Expr getReceiver() { result = super.getOperand(0) }
148149
}
149150
}

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

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ private import codeql.rust.elements.internal.generated.ParenArgsExpr
1212
*/
1313
module Impl {
1414
private import rust
15-
private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl
1615
private import codeql.rust.elements.internal.ArgsExprImpl::Impl as ArgsExprImpl
1716
private import codeql.rust.internal.PathResolution as PathResolution
1817

@@ -66,20 +65,4 @@ module Impl {
6665
)
6766
}
6867
}
69-
70-
private class ParenArgsCallExpr extends CallImpl::Call instanceof ParenArgsExpr {
71-
ParenArgsCallExpr() {
72-
forall(Addressable target | target = super.getResolvedTarget() | target instanceof Callable)
73-
}
74-
75-
private predicate isMethodCall() { super.getResolvedTarget() instanceof Method }
76-
77-
override Expr getArgument(int i) {
78-
if this.isMethodCall()
79-
then result = super.getArgList().getArg(i + 1)
80-
else result = super.getArgList().getArg(i)
81-
}
82-
83-
override Expr getReceiver() { this.isMethodCall() and result = super.getArgList().getArg(0) }
84-
}
8568
}

rust/ql/lib/codeql/rust/internal/TypeInference.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,7 @@ private module MethodResolution {
13611361
*
13621362
* [1]: https://doc.rust-lang.org/std/ops/trait.Index.html
13631363
*/
1364-
abstract class MethodCall extends ArgsExpr {
1364+
abstract class MethodCall extends Expr {
13651365
abstract predicate hasNameAndArity(string name, int arity);
13661366

13671367
abstract Expr getArg(ArgumentPosition pos);
@@ -3483,7 +3483,7 @@ private module Cached {
34833483

34843484
/** Gets an item (function or tuple struct/variant) that `call` resolves to, if any. */
34853485
cached
3486-
Addressable resolveCallTarget(ArgsExpr call) {
3486+
Addressable resolveCallTarget(Expr call) {
34873487
result = call.(MethodResolution::MethodCall).resolveCallTarget(_, _, _)
34883488
or
34893489
result = call.(NonMethodResolution::NonMethodCall).resolveCallTarget()

rust/ql/lib/rust.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ import codeql.rust.elements.NamedFormatArgument
2020
import codeql.rust.elements.PositionalFormatArgument
2121
import codeql.rust.elements.RangeExprExt
2222
import codeql.rust.elements.Call
23+
import codeql.rust.elements.CallExpr
2324
import codeql.rust.elements.Method

0 commit comments

Comments
 (0)