mirror of
https://github.com/github/codeql.git
synced 2026-04-25 08:45:14 +02:00
Merge pull request #15296 from michaelnebel/csharp/getruntimeargument
C#: Improve getRuntimeArgumentForParameter to consider named arguments.
This commit is contained in:
@@ -60,18 +60,17 @@ class Call extends DotNet::Call, Expr, @call {
|
||||
*/
|
||||
cached
|
||||
override Expr getArgumentForParameter(DotNet::Parameter p) {
|
||||
// Appears in the positional part of the call
|
||||
result = this.getImplicitArgument(p)
|
||||
or
|
||||
// Appears in the named part of the call
|
||||
this.getTarget().getAParameter() = p and
|
||||
(
|
||||
// Appears in the positional part of the call
|
||||
result = this.getImplicitArgument(p)
|
||||
or
|
||||
// Appears in the named part of the call
|
||||
result = this.getExplicitArgument(p.getName())
|
||||
)
|
||||
result = this.getExplicitArgument(p.getName())
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Expr getImplicitArgument(DotNet::Parameter p) {
|
||||
this.getTarget().getAParameter() = p and
|
||||
not exists(result.getExplicitArgumentName()) and
|
||||
(
|
||||
p.(Parameter).isParams() and
|
||||
@@ -183,24 +182,38 @@ class Call extends DotNet::Call, Expr, @call {
|
||||
* Gets the argument that corresponds to parameter `p` of a potential
|
||||
* run-time target of this call.
|
||||
*
|
||||
* Does not consider
|
||||
* - default arguments,
|
||||
* - named arguments.
|
||||
* This takes into account both positional and named arguments, but does not
|
||||
* consider default arguments.
|
||||
*/
|
||||
cached
|
||||
Expr getRuntimeArgumentForParameter(Parameter p) {
|
||||
exists(Callable c |
|
||||
c = this.getARuntimeTarget() and
|
||||
p = c.getAParameter() and
|
||||
(
|
||||
p.isParams() and
|
||||
result = this.getRuntimeArgument(any(int i | i >= p.getPosition()))
|
||||
or
|
||||
not p.isParams() and
|
||||
result = this.getRuntimeArgument(p.getPosition())
|
||||
)
|
||||
// Appears in the positional part of the call
|
||||
result = this.getImplicitRuntimeArgument(p)
|
||||
or
|
||||
// Appears in the named part of the call
|
||||
this.getARuntimeTarget().getAParameter() = p and
|
||||
result = this.getExplicitRuntimeArgument(p.getName())
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Expr getImplicitRuntimeArgument(Parameter p) {
|
||||
this.getARuntimeTarget().getAParameter() = p and
|
||||
not exists(result.getExplicitArgumentName()) and
|
||||
(
|
||||
p.isParams() and
|
||||
result = this.getRuntimeArgument(any(int i | i >= p.getPosition()))
|
||||
or
|
||||
not p.isParams() and
|
||||
result = this.getRuntimeArgument(p.getPosition())
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Expr getExplicitRuntimeArgument(string name) {
|
||||
result = this.getARuntimeArgument() and
|
||||
result.getExplicitArgumentName() = name
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the argument that corresponds to a parameter named `name` of a potential
|
||||
* run-time target of this call.
|
||||
|
||||
@@ -421,3 +421,30 @@ lambdas.cs:
|
||||
# 17| 0: [IntLiteral] 7
|
||||
# 17| 1: [IntLiteral] 8
|
||||
# 17| 2: [IntLiteral] 9
|
||||
# 20| 6: [DelegateType] MyDelegate
|
||||
#-----| 2: (Parameters)
|
||||
# 20| 0: [Parameter] x
|
||||
# 20| -1: [TypeMention] int
|
||||
# 20| 1: [Parameter] y
|
||||
# 20| -1: [TypeMention] int
|
||||
# 22| 7: [Method] M2
|
||||
# 22| -1: [TypeMention] Void
|
||||
# 23| 4: [BlockStmt] {...}
|
||||
# 24| 0: [LocalVariableDeclStmt] ... ...;
|
||||
# 24| 0: [LocalVariableDeclAndInitExpr] MyDelegate sum = ...
|
||||
# 24| -1: [TypeMention] MyDelegate
|
||||
# 24| 0: [LocalVariableAccess] access to local variable sum
|
||||
# 24| 1: [LambdaExpr] (...) => ...
|
||||
#-----| 2: (Parameters)
|
||||
# 24| 0: [Parameter] x
|
||||
# 24| -1: [TypeMention] int
|
||||
# 24| 1: [Parameter] y
|
||||
# 24| -1: [TypeMention] int
|
||||
# 24| 4: [AddExpr] ... + ...
|
||||
# 24| 0: [ParameterAccess] access to parameter x
|
||||
# 24| 1: [ParameterAccess] access to parameter y
|
||||
# 25| 1: [ExprStmt] ...;
|
||||
# 25| 0: [DelegateCall] delegate call
|
||||
# 25| -1: [LocalVariableAccess] access to local variable sum
|
||||
# 25| 0: [IntLiteral] 4
|
||||
# 25| 1: [IntLiteral] 5
|
||||
|
||||
@@ -11,3 +11,5 @@
|
||||
| arguments.cs:70:36:70:36 | 0 | x |
|
||||
| arguments.cs:78:18:78:21 | access to parameter args | args |
|
||||
| arguments.cs:78:27:78:27 | 0 | o |
|
||||
| lambdas.cs:25:16:25:16 | 4 | y |
|
||||
| lambdas.cs:25:22:25:22 | 5 | x |
|
||||
|
||||
@@ -79,3 +79,5 @@
|
||||
| lambdas.cs:17:12:17:12 | 7 | 0 |
|
||||
| lambdas.cs:17:15:17:15 | 8 | 0 |
|
||||
| lambdas.cs:17:18:17:18 | 9 | 0 |
|
||||
| lambdas.cs:25:16:25:16 | 4 | 0 |
|
||||
| lambdas.cs:25:22:25:22 | 5 | 0 |
|
||||
|
||||
@@ -7,3 +7,5 @@
|
||||
| lambdas.cs:17:9:17:19 | delegate call | lambdas.cs:15:32:15:32 | x | lambdas.cs:17:12:17:12 | 7 |
|
||||
| lambdas.cs:17:9:17:19 | delegate call | lambdas.cs:15:32:15:32 | x | lambdas.cs:17:15:17:15 | 8 |
|
||||
| lambdas.cs:17:9:17:19 | delegate call | lambdas.cs:15:32:15:32 | x | lambdas.cs:17:18:17:18 | 9 |
|
||||
| lambdas.cs:25:9:25:23 | delegate call | lambdas.cs:24:31:24:31 | x | lambdas.cs:25:22:25:22 | 5 |
|
||||
| lambdas.cs:25:9:25:23 | delegate call | lambdas.cs:24:38:24:38 | y | lambdas.cs:25:16:25:16 | 4 |
|
||||
|
||||
@@ -16,4 +16,13 @@ class LambdaArgumentsTest
|
||||
l3();
|
||||
l3(7, 8, 9);
|
||||
}
|
||||
|
||||
delegate int MyDelegate(int x, int y);
|
||||
|
||||
void M2()
|
||||
{
|
||||
MyDelegate sum = (int x, int y) => x + y;
|
||||
sum(y: 4, x: 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user