Skip to content

Commit 5b97db9

Browse files
committed
C#: Deprecate member predicates Definition.getAFirstRead and getAFirstReadAtNode.
1 parent 6e3749f commit 5b97db9

4 files changed

Lines changed: 54 additions & 7 deletions

File tree

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,9 +488,11 @@ class AssignableDefinition extends TAssignableDefinition {
488488
*/
489489
pragma[nomagic]
490490
AssignableRead getAFirstRead() {
491-
exists(Ssa::ExplicitDefinition def | result = def.getAFirstRead() | this = def.getADefinition())
491+
exists(Ssa::ExplicitDefinition def | result = Ssa::ssaGetAFirstUse(def) |
492+
this = def.getADefinition()
493+
)
492494
or
493-
exists(Ssa::ImplicitParameterDefinition def | result = def.getAFirstRead() |
495+
exists(Ssa::ImplicitParameterDefinition def | result = Ssa::ssaGetAFirstUse(def) |
494496
this.(AssignableDefinitions::ImplicitParameterDefinition).getParameter() = def.getParameter()
495497
)
496498
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ private Ssa::Definition getAnUltimateDefinition(Ssa::Definition def) {
255255
* exception.
256256
*/
257257
private predicate defReaches(Ssa::Definition def, ControlFlowNode cfn) {
258-
def.getAFirstRead().getControlFlowNode() = cfn
258+
Ssa::ssaGetAFirstUse(def).getControlFlowNode() = cfn
259259
or
260260
exists(ControlFlowNode mid | defReaches(def, mid) |
261261
SsaImpl::adjacentReadPairSameVar(_, mid, cfn) and

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

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,47 @@ module Ssa {
159159
}
160160
}
161161

162+
/**
163+
* Gets a read of the source variable underlying the SSA definition `def`
164+
* that can be reached from `def` without passing through any
165+
* other SSA definition or read. Example:
166+
*
167+
* ```csharp
168+
* int Field;
169+
*
170+
* void SetField(int i) {
171+
* this.Field = i;
172+
* Use(this.Field);
173+
* if (i > 0)
174+
* this.Field = i - 1;
175+
* else if (i < 0)
176+
* SetField(1);
177+
* Use(this.Field);
178+
* Use(this.Field);
179+
* }
180+
* ```
181+
*
182+
* - The read of `i` on line 4 can be reached from the explicit SSA
183+
* definition (wrapping an implicit entry definition) on line 3.
184+
* - The reads of `i` on lines 6 and 7 are not the first reads of any SSA
185+
* definition.
186+
* - The read of `this.Field` on line 5 can be reached from the explicit SSA
187+
* definition on line 4.
188+
* - The read of `this.Field` on line 10 can be reached from the phi node
189+
* between lines 9 and 10.
190+
* - The read of `this.Field` on line 11 is not the first read of any SSA
191+
* definition.
192+
*
193+
* Subsequent reads can be found by following the steps defined by
194+
* `AssignableRead.getANextRead()`.
195+
*/
196+
AssignableRead ssaGetAFirstUse(SsaDefinition def) {
197+
exists(ControlFlowNode cfn |
198+
SsaImpl::firstReadSameVar(def, cfn) and
199+
result.getControlFlowNode() = cfn
200+
)
201+
}
202+
162203
/**
163204
* A static single assignment (SSA) definition. Either an explicit variable
164205
* definition (`ExplicitDefinition`), an implicit variable definition
@@ -239,6 +280,8 @@ module Ssa {
239280
}
240281

241282
/**
283+
* DEPRECATED: Use `ssaGetAFirstUse` instead.
284+
*
242285
* Gets a read of the source variable underlying this SSA definition that
243286
* can be reached from this SSA definition without passing through any
244287
* other SSA definition or read. Example:
@@ -272,9 +315,11 @@ module Ssa {
272315
* Subsequent reads can be found by following the steps defined by
273316
* `AssignableRead.getANextRead()`.
274317
*/
275-
final AssignableRead getAFirstRead() { result = this.getAFirstReadAtNode(_) }
318+
deprecated final AssignableRead getAFirstRead() { result = this.getAFirstReadAtNode(_) }
276319

277320
/**
321+
* DEPRECATED: Use `ssaGetAFirstUse` instead.
322+
*
278323
* Gets a read of the source variable underlying this SSA definition at
279324
* control flow node `cfn` that can be reached from this SSA definition
280325
* without passing through any other SSA definition or read. Example:
@@ -308,7 +353,7 @@ module Ssa {
308353
* Subsequent reads can be found by following the steps defined by
309354
* `AssignableRead.getANextRead()`.
310355
*/
311-
final AssignableRead getAFirstReadAtNode(ControlFlowNode cfn) {
356+
deprecated final AssignableRead getAFirstReadAtNode(ControlFlowNode cfn) {
312357
SsaImpl::firstReadSameVar(this, cfn) and
313358
result.getControlFlowNode() = cfn
314359
}

csharp/ql/test/library-tests/dataflow/defuse/useUseEquivalence.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ private TLocalScopeVariableReadOrSsaDef getANextReadOrDef(TLocalScopeVariableRea
4242
)
4343
or
4444
exists(Ssa::Definition ssaDef | prev = TSsaDefinition(ssaDef) |
45-
result = TLocalScopeVariableRead(ssaDef.getAFirstRead())
45+
result = TLocalScopeVariableRead(Ssa::ssaGetAFirstUse(ssaDef))
4646
or
47-
not exists(ssaDef.getAFirstRead()) and
47+
not exists(Ssa::ssaGetAFirstUse(ssaDef)) and
4848
exists(Ssa::PhiNode phi |
4949
phi.getAnInput() = ssaDef and
5050
result = TSsaDefinition(phi)

0 commit comments

Comments
 (0)