@@ -270,6 +270,19 @@ module AccessPath {
270
270
271
271
/** A module for computing an access to a variable that happens after a property has been written onto it */
272
272
private module GetLaterAccess {
273
+ /**
274
+ * Gets an reference to the SSA variable `variable`.
275
+ * Either the definition or a use of the SSA variable
276
+ */
277
+ private VarRef getAVariableRef ( SsaVariable variable ) {
278
+ (
279
+ result = variable .getAUse ( )
280
+ or
281
+ result = variable .getDefinition ( ) .( SsaExplicitDefinition ) .getDef ( ) .getTarget ( )
282
+ ) and
283
+ variable = getARelevantVariableSimple ( )
284
+ }
285
+
273
286
/**
274
287
* Gets an access to a variable that is written to in `write`, where the access is after the write.
275
288
*
@@ -286,7 +299,7 @@ module AccessPath {
286
299
pragma [ noopt]
287
300
DataFlow:: Node getLaterBaseAccess ( DataFlow:: PropWrite write ) {
288
301
exists (
289
- ControlFlowNode writeNode , BindingPattern access , VarRef otherAccess , Variable variable ,
302
+ ControlFlowNode writeNode , BindingPattern access , VarRef otherAccess , SsaVariable variable ,
290
303
StmtContainer container
291
304
|
292
305
access = getBaseVar ( write ) and
@@ -303,7 +316,7 @@ module AccessPath {
303
316
i < j
304
317
)
305
318
or
306
- otherAccess .getBasicBlock ( ) = getASuccessorBBThatReadsVar ( write ) // more manual magic - outlined into a helper predicate.
319
+ otherAccess .getBasicBlock ( ) = getASuccessorBBThatReadsVar ( write )
307
320
)
308
321
}
309
322
@@ -323,24 +336,34 @@ module AccessPath {
323
336
}
324
337
325
338
/** Gets an access to `var` inside `container` where `usedInWrite` indicates whether the access is the base of a property write. */
326
- private VarRef getAnAccessInContainer ( Variable var , StmtContainer container , boolean usedInWrite ) {
327
- result .getVariable ( ) = var and
339
+ private VarRef getAnAccessInContainer (
340
+ SsaVariable var , StmtContainer container , boolean usedInWrite
341
+ ) {
342
+ result = getAVariableRef ( var ) and
328
343
result .getContainer ( ) = container and
329
- var .isLocal ( ) and
330
344
if result = getBaseVar ( _) then usedInWrite = true else usedInWrite = false
331
345
}
332
346
333
- /** Gets a variable that is relevant for the computations in the `GetLaterAccess` module. */
334
- private Variable getARelevantVariable ( ) {
347
+ /**
348
+ * Gets a variable that is relevant for the computations in the `GetLaterAccess` module.
349
+ * This predicate restricts as much as it can, but without depending on `getAVariableRef`.
350
+ */
351
+ pragma [ inline]
352
+ private SsaVariable getARelevantVariableSimple ( ) {
335
353
// The variable might be used where `getLaterBaseAccess()` is called.
336
354
exists ( DataFlow:: Node node |
337
355
exists ( fromRhs ( node , _) ) and
338
- node .asExpr ( ) .( VarAccess ) .getVariable ( ) = result
339
- ) and
356
+ node .asExpr ( ) = result .getAUse ( )
357
+ )
358
+ }
359
+
360
+ /**
361
+ * Gets a variable that is relevant for the computations in the `GetLaterAccess` module.
362
+ * This predicate depends on `getAVariableRef`, which in turn depends on `getARelevantVariableSimple`.
363
+ */
364
+ private SsaVariable getARelevantVariable ( ) {
340
365
// There is a write that writes to the variable.
341
- getBaseVar ( _) .getVariable ( ) = result and
342
- // It's local.
343
- result .isLocal ( ) and // we skip global variables, because that turns messy quick.
366
+ getBaseVar ( _) = getAVariableRef ( result ) and
344
367
// There is both a "write" and "read" in the same container of the variable.
345
368
exists ( StmtContainer container |
346
369
exists ( getAnAccessInContainer ( result , container , true ) ) and // a "write", an access to the variable that is the base of a property reference.
@@ -350,15 +373,15 @@ module AccessPath {
350
373
351
374
/** Gets a basic-block that has a read of the variable that is written to by `write`, where the basicblock occurs after `start`. */
352
375
private ReachableBasicBlock getASuccessorBBThatReadsVar ( DataFlow:: PropWrite write ) {
353
- exists ( VarAccess baseExpr , Variable var , ControlFlowNode writeNode |
376
+ exists ( VarRef baseExpr , SsaVariable var , ControlFlowNode writeNode |
354
377
baseExpr = getBaseVar ( write ) and
355
- var = baseExpr . getVariable ( ) and
378
+ getAVariableRef ( var ) = baseExpr and
356
379
var = getARelevantVariable ( ) and
357
380
writeNode = write .getWriteNode ( ) and
358
- writeNode .getBasicBlock ( ) .( ReachableBasicBlock ) .strictlyDominates ( result ) and
359
- // manual magic.
360
- result = getAnAccessInContainer ( getARelevantVariable ( ) , _, false ) .getBasicBlock ( )
381
+ result .getImmediateDominator ( ) = writeNode .getBasicBlock ( )
361
382
)
383
+ or
384
+ result .getImmediateDominator ( ) = getASuccessorBBThatReadsVar ( write )
362
385
}
363
386
}
364
387
0 commit comments