@@ -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+
339380overlay [ 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