Skip to content

Commit 7209011

Browse files
committed
C#: Use parameter CFG nodes in SSA
1 parent 11fd95c commit 7209011

10 files changed

Lines changed: 87 additions & 27 deletions

File tree

csharp/ql/lib/semmle/code/csharp/Assignable.qll

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ private class RefArg extends AssignableAccess {
204204
AssignableDefinition getAnAnalyzableRefDef(Parameter p) {
205205
this.isAnalyzable(p) and
206206
result.getTarget() = p and
207-
not result = TImplicitParameterDefinition(_)
207+
not result = TImplicitParameterDefinition(_, _)
208208
}
209209

210210
/**
@@ -271,6 +271,11 @@ module AssignableInternal {
271271
def = TPatternDefinition(result)
272272
or
273273
def = TAssignOperationDefinition(result)
274+
or
275+
exists(Parameter p |
276+
def = TImplicitParameterDefinition(p, true) and
277+
result = p.getDefaultValue()
278+
)
274279
}
275280

276281
/** A local variable declaration at the top-level of a pattern. */
@@ -304,12 +309,18 @@ module AssignableInternal {
304309
not lvde instanceof TopLevelPatternDecl and
305310
not lvde.isOutArgument()
306311
} or
307-
TImplicitParameterDefinition(Parameter p) {
312+
TImplicitParameterDefinition(Parameter p, boolean isDefault) {
308313
exists(Callable c | p = c.getAParameter() |
309314
c.hasBody()
310315
or
311316
// Same as `c.(Constructor).hasInitializer()`, but avoids negative recursion warning
312317
c.getAChildExpr() instanceof @constructor_init_expr
318+
) and
319+
(
320+
isDefault = false
321+
or
322+
p.hasDefaultValue() and
323+
isDefault = true
313324
)
314325
} or
315326
TAddressOfDefinition(AddressOfExpr aoe) or
@@ -673,7 +684,7 @@ module AssignableDefinitions {
673684
class ImplicitParameterDefinition extends AssignableDefinition, TImplicitParameterDefinition {
674685
Parameter p;
675686

676-
ImplicitParameterDefinition() { this = TImplicitParameterDefinition(p) }
687+
ImplicitParameterDefinition() { this = TImplicitParameterDefinition(p, false) }
677688

678689
/** Gets the underlying parameter. */
679690
Parameter getParameter() { result = p }
@@ -688,7 +699,27 @@ module AssignableDefinitions {
688699

689700
override string toString() { result = p.toString() }
690701

691-
override Location getLocation() { result = this.getTarget().getLocation() }
702+
override Location getLocation() { result = p.getLocation() }
703+
}
704+
705+
/**
706+
* A default value assigned to a parameter.
707+
*/
708+
class ParameterDefaultDefinition extends AssignableDefinition, TImplicitParameterDefinition {
709+
Parameter p;
710+
711+
ParameterDefaultDefinition() { this = TImplicitParameterDefinition(p, true) }
712+
713+
/** Gets the underlying parameter. */
714+
Parameter getParameter() { result = p }
715+
716+
override Expr getElement() { result = p.getDefaultValue() }
717+
718+
override Callable getEnclosingCallable() { result = p.getCallable() }
719+
720+
override string toString() { result = p.getDefaultValue().toString() }
721+
722+
override Location getLocation() { result = p.getDefaultValue().getLocation() }
692723
}
693724

694725
/**

csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -527,14 +527,15 @@ module Ssa {
527527
* An SSA definition representing the implicit initialization of a parameter
528528
* at the beginning of a callable.
529529
*/
530-
class ImplicitParameterDefinition extends ImplicitEntryDefinition {
530+
class ImplicitParameterDefinition extends ExplicitDefinition {
531531
private Parameter p;
532532

533533
ImplicitParameterDefinition() {
534-
exists(SourceVariable sv, Callable c |
535-
implicitEntryDef(this, sv, c) and
536-
localScopeSourceVariable(sv, p, _, c)
537-
)
534+
p = ad.(AssignableDefinitions::ImplicitParameterDefinition).getParameter()
535+
// exists(SourceVariable sv, Callable c |
536+
// implicitEntryDef(this, sv, c) and
537+
// localScopeSourceVariable(sv, p, _, c)
538+
// )
538539
}
539540

540541
/** Gets the parameter that this entry definition represents. */
@@ -545,14 +546,6 @@ module Ssa {
545546
override string toString() {
546547
result = "SSA param(" + pragma[only_bind_out](this.getParameter()) + ")"
547548
}
548-
549-
override Location getLocation() {
550-
not NearestLocation<NearestLocationInput>::nearestLocation(this, _, _) and
551-
result = p.getLocation()
552-
or
553-
// multi-bodied method: use matching parameter location
554-
NearestLocation<NearestLocationInput>::nearestLocation(this, result, _)
555-
}
556549
}
557550

558551
/**

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ private module SourceVariableImpl {
126126
*/
127127
predicate variableDefinition(BasicBlock bb, int i, Ssa::SourceVariable v, AssignableDefinition ad) {
128128
ad = v.getADefinition() and
129-
ad.getExpr().getControlFlowNode() = bb.getNode(i) and
130129
// In cases like `(x, x) = (0, 1)`, we discard the first (dead) definition of `x`
131130
not exists(TupleAssignmentDefinition first, TupleAssignmentDefinition second | first = ad |
132131
second.getAssignment() = first.getAssignment() and
@@ -136,7 +135,13 @@ private module SourceVariableImpl {
136135
// In cases like `M(out x, out x)`, there is no inherent evaluation order, so we
137136
// collapse the two definitions of `x`, using the first access as the representative,
138137
// and expose both definitions in `ExplicitDefinition.getADefinition()`
139-
not ad = getASameOutRefDefAfter(v, _)
138+
not ad = getASameOutRefDefAfter(v, _) and
139+
(
140+
ad.getExpr().getControlFlowNode() = bb.getNode(i)
141+
or
142+
ad.(AssignableDefinitions::ImplicitParameterDefinition).getParameter().getControlFlowNode() =
143+
bb.getNode(i)
144+
)
140145
}
141146

142147
/**
@@ -771,8 +776,6 @@ private module Cached {
771776
or
772777
// Each tracked field and property has an implicit entry definition
773778
v instanceof PlainFieldOrPropSourceVariable
774-
or
775-
v.getAssignable() instanceof Parameter
776779
)
777780
}
778781

csharp/ql/test/library-tests/dataflow/ssa/DefAdjacentRead.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@
8383
| Fields.cs:95:19:95:19 | f | Fields.cs:95:19:95:19 | f | Fields.cs:97:9:97:9 | access to parameter f |
8484
| Fields.cs:107:33:107:33 | f | Fields.cs:107:33:107:33 | f | Fields.cs:107:38:107:38 | access to parameter f |
8585
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:28:5:28 | access to parameter x |
86-
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:28:3:28 | access to parameter x |
8786
| OutRef.cs:5:9:5:13 | Field | OutRef.cs:13:28:13:32 | access to field Field | OutRef.cs:15:13:15:17 | access to field Field |
8887
| OutRef.cs:5:9:5:13 | Field | OutRef.cs:16:21:16:25 | access to field Field | OutRef.cs:17:13:17:17 | access to field Field |
8988
| OutRef.cs:5:9:5:13 | Field | OutRef.cs:16:32:16:36 | access to field Field | OutRef.cs:17:13:17:17 | access to field Field |

csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@
160160
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) |
161161
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) |
162162
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | SSA param(x) |
163-
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:22:3:22 | SSA param(x) |
164163
| OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) |
165164
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) |
166165
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:22:22:22 | SSA def(j) |

csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@
146146
| Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:114:9:114:22 | call to method SetField |
147147
| Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:114:9:114:22 | call to method SetField |
148148
| MultiImplementationA.cs:5:22:5:22 | SSA param(x) | MultiImplementationA.cs:5:22:5:22 | x |
149-
| MultiImplementationB.cs:3:22:3:22 | SSA param(x) | MultiImplementationA.cs:5:22:5:22 | x |
150149
| OutRef.cs:7:10:7:10 | SSA entry def(this.Field) | OutRef.cs:7:10:7:10 | M |
151150
| OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:9:13:9:17 | Int32 j = ... |
152151
| OutRef.cs:10:25:10:25 | SSA def(i) | OutRef.cs:10:9:10:33 | call to method OutRefM |

0 commit comments

Comments
 (0)