Skip to content

Commit cbea5ea

Browse files
committed
C#: Simplify argument/parameter positions for captured variables
1 parent 128682b commit cbea5ea

File tree

2 files changed

+22
-37
lines changed

2 files changed

+22
-37
lines changed

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

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,23 @@ private module Cached {
116116
cached
117117
DataFlowCallable viableCallable(DataFlowCall call) { result = call.getARuntimeTarget() }
118118

119+
private predicate capturedWithFlowIn(LocalScopeVariable v) {
120+
exists(Ssa::ExplicitDefinition def | def.isCapturedVariableDefinitionFlowIn(_, _, _) |
121+
v = def.getSourceVariable().getAssignable()
122+
)
123+
}
124+
119125
cached
120126
newtype TParameterPosition =
121127
TPositionalParameterPosition(int i) { i = any(Parameter p).getPosition() } or
122128
TThisParameterPosition() or
123-
TImplicitCapturedParameterPosition(SsaCapturedEntryDefinition def)
129+
TImplicitCapturedParameterPosition(LocalScopeVariable v) { capturedWithFlowIn(v) }
124130

125131
cached
126132
newtype TArgumentPosition =
127133
TPositionalArgumentPosition(int i) { i = any(Parameter p).getPosition() } or
128134
TQualifierArgumentPosition() or
129-
TImplicitCapturedArgumentPosition(SsaCapturedEntryDefinition def)
135+
TImplicitCapturedArgumentPosition(LocalScopeVariable v) { capturedWithFlowIn(v) }
130136
}
131137

132138
import Cached
@@ -432,8 +438,8 @@ class ParameterPosition extends TParameterPosition {
432438
predicate isThisParameter() { this = TThisParameterPosition() }
433439

434440
/** Holds if this position is used to model flow through captured variables. */
435-
predicate isImplicitCapturedParameterPosition(SsaCapturedEntryDefinition def) {
436-
this = TImplicitCapturedParameterPosition(def)
441+
predicate isImplicitCapturedParameterPosition(LocalScopeVariable v) {
442+
this = TImplicitCapturedParameterPosition(v)
437443
}
438444

439445
/** Gets a textual representation of this position. */
@@ -442,8 +448,8 @@ class ParameterPosition extends TParameterPosition {
442448
or
443449
this.isThisParameter() and result = "this"
444450
or
445-
exists(SsaCapturedEntryDefinition def |
446-
this.isImplicitCapturedParameterPosition(def) and result = "captured " + def
451+
exists(LocalScopeVariable v |
452+
this.isImplicitCapturedParameterPosition(v) and result = "captured " + v
447453
)
448454
}
449455
}
@@ -457,8 +463,8 @@ class ArgumentPosition extends TArgumentPosition {
457463
predicate isQualifier() { this = TQualifierArgumentPosition() }
458464

459465
/** Holds if this position is used to model flow through captured variables. */
460-
predicate isImplicitCapturedArgumentPosition(SsaCapturedEntryDefinition def) {
461-
this = TImplicitCapturedArgumentPosition(def)
466+
predicate isImplicitCapturedArgumentPosition(LocalScopeVariable v) {
467+
this = TImplicitCapturedArgumentPosition(v)
462468
}
463469

464470
/** Gets a textual representation of this position. */
@@ -467,8 +473,8 @@ class ArgumentPosition extends TArgumentPosition {
467473
or
468474
this.isQualifier() and result = "qualifier"
469475
or
470-
exists(SsaCapturedEntryDefinition def |
471-
this.isImplicitCapturedArgumentPosition(def) and result = "captured " + def
476+
exists(LocalScopeVariable v |
477+
this.isImplicitCapturedArgumentPosition(v) and result = "captured " + v
472478
)
473479
}
474480
}
@@ -479,8 +485,8 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) {
479485
or
480486
ppos.isThisParameter() and apos.isQualifier()
481487
or
482-
exists(SsaCapturedEntryDefinition def |
483-
ppos.isImplicitCapturedParameterPosition(def) and
484-
apos.isImplicitCapturedArgumentPosition(def)
488+
exists(LocalScopeVariable v |
489+
ppos.isImplicitCapturedParameterPosition(v) and
490+
apos.isImplicitCapturedArgumentPosition(v)
485491
)
486492
}

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

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ private module ParameterNodes {
950950
LocalScopeVariable getVariable() { result = def.getVariable() }
951951

952952
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
953-
pos.isImplicitCapturedParameterPosition(def) and
953+
pos.isImplicitCapturedParameterPosition(def.getSourceVariable().getAssignable()) and
954954
c = this.getEnclosingCallable()
955955
}
956956
}
@@ -1031,30 +1031,9 @@ private module ArgumentNodes {
10311031

10321032
ImplicitCapturedArgumentNode() { this = TImplicitCapturedArgumentNode(cfn, v) }
10331033

1034-
/** Holds if the value at this node may flow into the implicit parameter `p`. */
1035-
private predicate flowsInto(ImplicitCapturedParameterNode p, boolean additionalCalls) {
1036-
exists(Ssa::ImplicitEntryDefinition def, Ssa::ExplicitDefinition edef |
1037-
def = p.getDefinition()
1038-
|
1039-
edef.isCapturedVariableDefinitionFlowIn(def, cfn, additionalCalls) and
1040-
v = def.getSourceVariable().getAssignable()
1041-
)
1042-
}
1043-
10441034
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
1045-
exists(
1046-
ImplicitCapturedParameterNode p, boolean additionalCalls, ParameterPosition ppos,
1047-
SsaCapturedEntryDefinition def
1048-
|
1049-
this.flowsInto(p, additionalCalls) and
1050-
p.isParameterOf(call.getARuntimeTarget(), ppos) and
1051-
pos.isImplicitCapturedArgumentPosition(def) and
1052-
ppos.isImplicitCapturedParameterPosition(def) and
1053-
call.getControlFlowNode() = cfn and
1054-
if call instanceof TransitiveCapturedDataFlowCall
1055-
then additionalCalls = true
1056-
else additionalCalls = false
1057-
)
1035+
pos.isImplicitCapturedArgumentPosition(v) and
1036+
call.getControlFlowNode() = cfn
10581037
}
10591038

10601039
override DataFlowCallable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() }

0 commit comments

Comments
 (0)