Skip to content

Commit a5cd198

Browse files
committed
Java: Update toString for implicit writes.
1 parent a0960b9 commit a5cd198

File tree

1 file changed

+54
-13
lines changed
  • java/ql/lib/semmle/code/java/dataflow

1 file changed

+54
-13
lines changed

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

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,29 @@ class SsaCapturedDefinition extends SsaImplicitEntryDefinition {
157157
}
158158
}
159159

160+
/**
161+
* An SSA definition representing the potential definition of a variable
162+
* via a call.
163+
*/
164+
class SsaImplicitCallDefinition extends SsaImplicitWrite {
165+
SsaImplicitCallDefinition() { isNonLocal(this) and not hasQualifierUpdate(this) }
166+
167+
override string toString() { result = "SSA call def(" + this.getSourceVariable() + ")" }
168+
169+
/**
170+
* Gets a reachable `FieldWrite` that might represent this ssa update, if any.
171+
*/
172+
overlay[global]
173+
FieldWrite getANonLocalUpdate() { result = getANonLocalUpdate(this) }
174+
}
175+
176+
/** An SSA definition due to an update of the qualifier. */
177+
class SsaImplicitQualifierDefinition extends SsaImplicitWrite {
178+
SsaImplicitQualifierDefinition() { hasQualifierUpdate(this) }
179+
180+
override string toString() { result = "SSA qualifier def(" + this.getSourceVariable() + ")" }
181+
}
182+
160183
/**
161184
* Gets an access of the SSA source variable underlying this SSA variable
162185
* that can be reached from this SSA variable without passing through any
@@ -299,47 +322,65 @@ class SsaImplicitUpdate extends SsaUpdate {
299322

300323
private string getKind() {
301324
this.hasExplicitQualifierUpdate() and
302-
result = "explicit qualifier"
325+
result = "explicit qualifier" // -> SSA qualifier def
303326
or
304327
if this.hasImplicitQualifierUpdate()
305328
then
306329
if isNonLocal(this)
307-
then result = "nonlocal + nonlocal qualifier"
308-
else result = "nonlocal qualifier"
330+
then result = "nonlocal + nonlocal qualifier" // -> SSA qualifier def
331+
else result = "nonlocal qualifier" // -> SSA qualifier def
309332
else (
310-
isNonLocal(this) and result = "nonlocal"
333+
isNonLocal(this) and result = "nonlocal" // -> SSA call def
311334
)
312335
}
313336

314337
/**
338+
* DEPRECATED: Use `SsaImplicitCallDefinition.getANonLocalUpdate()` instead.
339+
*
315340
* Gets a reachable `FieldWrite` that might represent this ssa update, if any.
316341
*/
317342
overlay[global]
318-
FieldWrite getANonLocalUpdate() {
319-
exists(SsaSourceField f, Callable setter |
320-
relevantFieldUpdate(setter, f.getField(), result) and
321-
defUpdatesNamedField(this, f, setter)
322-
)
323-
}
343+
deprecated FieldWrite getANonLocalUpdate() { result = getANonLocalUpdate(this) }
324344

325345
/**
346+
* DEPRECATED: Use `SsaImplicitQualifierDefinition` instead.
347+
*
326348
* Holds if this ssa variable might change the value to something unknown.
327349
*
328350
* Examples include updates that might change the value of the qualifier, or
329351
* reads from untracked variables, for example those where the field or one
330352
* of its qualifiers is volatile.
331353
*/
332-
predicate assignsUnknownValue() {
354+
deprecated predicate assignsUnknownValue() {
333355
this.hasExplicitQualifierUpdate()
334356
or
335357
this.hasImplicitQualifierUpdate()
336358
}
337359
}
338360

361+
private predicate hasQualifierUpdate(SsaImplicitWrite def) {
362+
exists(SsaWriteDefinition qdef, BasicBlock bb, int i |
363+
qdef.definesAt(def.getSourceVariable().getQualifier(), bb, i) and
364+
def.definesAt(_, bb, i) and
365+
not qdef instanceof SsaImplicitEntryDefinition
366+
)
367+
}
368+
369+
/**
370+
* Gets a reachable `FieldWrite` that might represent this ssa update, if any.
371+
*/
372+
overlay[global]
373+
private FieldWrite getANonLocalUpdate(SsaImplicitWrite calldef) {
374+
exists(SsaSourceField f, Callable setter |
375+
relevantFieldUpdate(setter, f.getField(), result) and
376+
defUpdatesNamedField(calldef, f, setter)
377+
)
378+
}
379+
339380
overlay[global]
340-
private predicate isNonLocalImpl(SsaImplicitUpdate su) { exists(su.getANonLocalUpdate()) }
381+
private predicate isNonLocalImpl(SsaImplicitWrite calldef) { exists(getANonLocalUpdate(calldef)) }
341382

342-
private predicate isNonLocal(SsaImplicitUpdate su) = forceLocal(isNonLocalImpl/1)(su)
383+
private predicate isNonLocal(SsaImplicitWrite calldef) = forceLocal(isNonLocalImpl/1)(calldef)
343384

344385
/**
345386
* An SSA variable that represents an uncertain implicit update of the value.

0 commit comments

Comments
 (0)