Skip to content

Commit 83c7a33

Browse files
committed
C#: Deprecate member predicates Definition.getAFirstRead and getAFirstReadAtNode.
1 parent fb438bf commit 83c7a33

4 files changed

Lines changed: 53 additions & 6 deletions

File tree

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,9 @@ class AssignableDefinition extends TAssignableDefinition {
500500
*/
501501
pragma[nomagic]
502502
AssignableRead getAFirstRead() {
503-
exists(Ssa::ExplicitDefinition def | result = def.getAFirstRead() | this = def.getADefinition())
503+
exists(Ssa::ExplicitDefinition def | result = Ssa::ssaGetAFirstUse(def) |
504+
this = def.getADefinition()
505+
)
504506
}
505507

506508
/** Gets a textual representation of this assignable definition. */

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ private Ssa::Definition getAnUltimateDefinition(Ssa::Definition def) {
241241
* exception.
242242
*/
243243
private predicate defReaches(Ssa::Definition def, ControlFlowNode cfn) {
244-
def.getAFirstRead().getControlFlowNode() = cfn
244+
Ssa::ssaGetAFirstUse(def).getControlFlowNode() = cfn
245245
or
246246
exists(ControlFlowNode mid | defReaches(def, mid) |
247247
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
@@ -149,6 +149,47 @@ module Ssa {
149149
}
150150
}
151151

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

231272
/**
273+
* DEPRECATED: Use `ssaGetAFirstUse` instead.
274+
*
232275
* Gets a read of the source variable underlying this SSA definition that
233276
* can be reached from this SSA definition without passing through any
234277
* other SSA definition or read. Example:
@@ -262,9 +305,11 @@ module Ssa {
262305
* Subsequent reads can be found by following the steps defined by
263306
* `AssignableRead.getANextRead()`.
264307
*/
265-
final AssignableRead getAFirstRead() { result = this.getAFirstReadAtNode(_) }
308+
deprecated final AssignableRead getAFirstRead() { result = this.getAFirstReadAtNode(_) }
266309

267310
/**
311+
* DEPRECATED: Use `ssaGetAFirstUse` instead.
312+
*
268313
* Gets a read of the source variable underlying this SSA definition at
269314
* control flow node `cfn` that can be reached from this SSA definition
270315
* without passing through any other SSA definition or read. Example:
@@ -298,7 +343,7 @@ module Ssa {
298343
* Subsequent reads can be found by following the steps defined by
299344
* `AssignableRead.getANextRead()`.
300345
*/
301-
final AssignableRead getAFirstReadAtNode(ControlFlowNode cfn) {
346+
deprecated final AssignableRead getAFirstReadAtNode(ControlFlowNode cfn) {
302347
SsaImpl::firstReadSameVar(this, cfn) and
303348
result.getControlFlowNode() = cfn
304349
}

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)