Skip to content

Commit 3ae793d

Browse files
committed
C#: Update lambda flow implementation
1 parent 906a478 commit 3ae793d

File tree

3 files changed

+25
-31
lines changed

3 files changed

+25
-31
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,12 @@ private class ExprNodeImpl extends ExprNode, NodeImpl {
126126
* Needed for flow through captured variables, where we treat local functions
127127
* as if they were lambdas.
128128
*/
129-
abstract private class LocalFunctionCreationNode extends NodeImpl, TLocalFunctionCreationNode {
129+
private class LocalFunctionCreationNode extends NodeImpl, TLocalFunctionCreationNode {
130130
ControlFlow::Nodes::ElementNode cfn;
131131
LocalFunction function;
132-
boolean isPostUpdate;
133132

134133
LocalFunctionCreationNode() {
135-
this = TLocalFunctionCreationNode(cfn, isPostUpdate) and
134+
this = TLocalFunctionCreationNode(cfn) and
136135
function = cfn.getAstNode().(LocalFunctionStmt).getLocalFunction()
137136
}
138137

@@ -156,10 +155,6 @@ abstract private class LocalFunctionCreationNode extends NodeImpl, TLocalFunctio
156155
ControlFlow::Nodes::ElementNode getUnderlyingControlFlowNode() { result = cfn }
157156

158157
override Location getLocationImpl() { result = cfn.getLocation() }
159-
}
160-
161-
private class LocalFunctionCreationPreNode extends LocalFunctionCreationNode {
162-
LocalFunctionCreationPreNode() { isPostUpdate = false }
163158

164159
override string toStringImpl() { result = cfn.toString() }
165160
}
@@ -419,17 +414,14 @@ module VariableCapture {
419414
result.(Flow::ExprNode).getExpr() =
420415
[
421416
n.(ExprNode).getControlFlowNode(),
422-
n.(LocalFunctionCreationPreNode).getUnderlyingControlFlowNode()
417+
n.(LocalFunctionCreationNode).getUnderlyingControlFlowNode()
423418
]
424419
or
425420
result.(Flow::VariableWriteSourceNode).getVariableWrite().getRhs() =
426421
n.(ExprNode).getControlFlowNode()
427422
or
428423
result.(Flow::ExprPostUpdateNode).getExpr() =
429-
[
430-
n.(PostUpdateNode).getPreUpdateNode().(ExprNode).getControlFlowNode(),
431-
n.(LocalFunctionCreationPostUpdateNode).getUnderlyingControlFlowNode()
432-
]
424+
[n.(PostUpdateNode).getPreUpdateNode().(ExprNode).getControlFlowNode(),]
433425
or
434426
result.(Flow::ParameterNode).getParameter().getParameterNode() = n
435427
or
@@ -1075,7 +1067,7 @@ private module Cached {
10751067
l = c.getARelevantLocation()
10761068
} or
10771069
TDelegateSelfReferenceNode(Callable c) { lambdaCreationExpr(_, c) } or
1078-
TLocalFunctionCreationNode(ControlFlow::Nodes::ElementNode cfn, Boolean isPostUpdate) {
1070+
TLocalFunctionCreationNode(ControlFlow::Nodes::ElementNode cfn) {
10791071
cfn.getAstNode() instanceof LocalFunctionStmt
10801072
} or
10811073
TYieldReturnNode(ControlFlow::Nodes::ElementNode cfn) {
@@ -1153,6 +1145,12 @@ private module Cached {
11531145
TDelegateCallArgumentContent(int i) {
11541146
i = [0 .. max(any(DelegateLikeCall dc).getNumberOfArguments()) - 1]
11551147
or
1148+
i in [0 .. 1000] // todo
1149+
or
1150+
// exists(ArgumentPosition apos |
1151+
// FlowSummaryImpl::Private::summaryArgumentNode(_, _, apos) and
1152+
// i = apos.getPosition()
1153+
// )
11561154
i = -1
11571155
} or
11581156
TDelegateCallReturnContent()
@@ -2604,7 +2602,7 @@ DataFlowType getNodeType(Node n) {
26042602
or
26052603
[
26062604
n.asExpr().(ControlFlowElement),
2607-
n.(LocalFunctionCreationPreNode).getUnderlyingControlFlowNode().getAstNode()
2605+
n.(LocalFunctionCreationNode).getUnderlyingControlFlowNode().getAstNode()
26082606
] = result.getADelegateCreation()
26092607
}
26102608

@@ -2839,16 +2837,6 @@ module PostUpdateNodes {
28392837
override string toStringImpl() { result = "[post] this" }
28402838
}
28412839

2842-
class LocalFunctionCreationPostUpdateNode extends LocalFunctionCreationNode, PostUpdateNode {
2843-
LocalFunctionCreationPostUpdateNode() { isPostUpdate = true }
2844-
2845-
override LocalFunctionCreationPreNode getPreUpdateNode() {
2846-
result = TLocalFunctionCreationNode(cfn, false)
2847-
}
2848-
2849-
override string toStringImpl() { result = "[post] " + cfn }
2850-
}
2851-
28522840
private class CapturePostUpdateNode extends PostUpdateNode, CaptureNode {
28532841
private CaptureNode pre;
28542842

@@ -2912,7 +2900,11 @@ int accessPathLimit() { result = 5 }
29122900
* Holds if access paths with `c` at their head always should be tracked at high
29132901
* precision. This disables adaptive access path precision for such access paths.
29142902
*/
2915-
predicate forceHighPrecision(Content c) { c instanceof ElementContent }
2903+
predicate forceHighPrecision(Content c) {
2904+
c instanceof ElementContent or
2905+
c instanceof DelegateCallArgumentContent or
2906+
c instanceof DelegateCallReturnContent
2907+
}
29162908

29172909
private predicate lambdaCreationExpr(ControlFlowElement creation, Callable c) {
29182910
c =
@@ -2928,7 +2920,11 @@ class LambdaCallKind = Unit;
29282920

29292921
/** Holds if `creation` is an expression that creates a delegate for `c`. */
29302922
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) {
2931-
lambdaCreationExpr(creation.asExpr(), c.asCallable(_)) and
2923+
(
2924+
lambdaCreationExpr(creation.asExpr(), c.asCallable(_))
2925+
or
2926+
creation.(LocalFunctionCreationNode).getFunction() = c.asCallable(_)
2927+
) and
29322928
exists(kind)
29332929
}
29342930

@@ -3009,9 +3005,7 @@ private predicate lambdaCallExpr(DataFlowCall call, ControlFlow::Node receiver)
30093005
/** Holds if `call` is a lambda call where `receiver` is the lambda expression. */
30103006
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
30113007
(
3012-
lambdaCallExpr(call, receiver.(ExprNode).getControlFlowNode()) and
3013-
// local function calls can be resolved directly without a flow analysis
3014-
not call.getControlFlowNode().getAstNode() instanceof LocalFunctionCall
3008+
lambdaCallExpr(call, receiver.(ExprNode).getControlFlowNode()) //and
30153009
or
30163010
receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver()
30173011
) and
@@ -3088,6 +3082,8 @@ predicate allowParameterReturnInSelf(ParameterNode p) {
30883082
or
30893083
VariableCapture::Flow::heuristicAllowInstanceParameterReturnInSelf(p.(DelegateSelfReferenceNode)
30903084
.getCallable())
3085+
or
3086+
p.getType() instanceof SystemLinqExpressions::DelegateExtType
30913087
}
30923088

30933089
/** An approximated `Content`. */

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ private import DataFlowDispatch
33
private import DataFlowPrivate
44
private import semmle.code.csharp.controlflow.Guards
55
private import semmle.code.csharp.Unification
6-
private import semmle.code.csharp.frameworks.system.linq.Expressions
76

87
/**
98
* An element, viewed as a node in a data flow graph. Either an expression

csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
private import csharp
66
private import semmle.code.csharp.commons.QualifiedName
7-
private import semmle.code.csharp.frameworks.system.linq.Expressions
87
private import codeql.dataflow.internal.FlowSummaryImpl
98
private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
109
private import DataFlowImplSpecific as DataFlowImplSpecific

0 commit comments

Comments
 (0)