@@ -174,7 +174,7 @@ predicate hasNodePath(ControlFlowReachabilityConfiguration conf, ExprNode n1, No
174
174
cfn = n1 .getControlFlowNode ( ) and
175
175
ssaDef .getADefinition ( ) = def and
176
176
ssaDef .getControlFlowNode ( ) = cfnDef and
177
- n2 .( SsaDefinitionNode ) . getDefinition ( ) = ssaDef
177
+ n2 .( SsaDefinitionExtNode ) . getDefinitionExt ( ) = ssaDef
178
178
)
179
179
}
180
180
@@ -310,17 +310,20 @@ module LocalFlow {
310
310
* Holds if `nodeFrom` is a last node referencing SSA definition `def`, which
311
311
* can reach `next`.
312
312
*/
313
- private predicate localFlowSsaInput ( Node nodeFrom , Ssa:: Definition def , Ssa:: Definition next ) {
314
- exists ( ControlFlow:: BasicBlock bb , int i | SsaImpl:: lastRefBeforeRedef ( def , bb , i , next ) |
315
- def .definesAt ( _, bb , i ) and
316
- def = getSsaDefinition ( nodeFrom )
313
+ private predicate localFlowSsaInput (
314
+ Node nodeFrom , SsaImpl:: DefinitionExt def , SsaImpl:: DefinitionExt next
315
+ ) {
316
+ exists ( ControlFlow:: BasicBlock bb , int i | SsaImpl:: lastRefBeforeRedefExt ( def , bb , i , next ) |
317
+ def .definesAt ( _, bb , i , _) and
318
+ def = getSsaDefinitionExt ( nodeFrom )
317
319
or
318
- nodeFrom .asExprAtNode ( bb .getNode ( i ) ) instanceof AssignableRead
320
+ [ nodeFrom , nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) ] .asExprAtNode ( bb .getNode ( i ) )
321
+ instanceof AssignableRead
319
322
)
320
323
}
321
324
322
- private Ssa :: Definition getSsaDefinition ( Node n ) {
323
- result = n .( SsaDefinitionNode ) . getDefinition ( )
325
+ private SsaImpl :: DefinitionExt getSsaDefinitionExt ( Node n ) {
326
+ result = n .( SsaDefinitionExtNode ) . getDefinitionExt ( )
324
327
or
325
328
result = n .( ExplicitParameterNode ) .getSsaDefinition ( )
326
329
}
@@ -329,9 +332,9 @@ module LocalFlow {
329
332
* Holds if there is a local use-use flow step from `nodeFrom` to `nodeTo`
330
333
* involving SSA definition `def`.
331
334
*/
332
- predicate localSsaFlowStepUseUse ( Ssa :: Definition def , Node nodeFrom , Node nodeTo ) {
335
+ predicate localSsaFlowStepUseUse ( SsaImpl :: DefinitionExt def , Node nodeFrom , Node nodeTo ) {
333
336
exists ( ControlFlow:: Node cfnFrom , ControlFlow:: Node cfnTo |
334
- SsaImpl:: adjacentReadPairSameVar ( def , cfnFrom , cfnTo ) and
337
+ SsaImpl:: adjacentReadPairSameVarExt ( def , cfnFrom , cfnTo ) and
335
338
nodeTo = TExprNode ( cfnTo ) and
336
339
nodeFrom = TExprNode ( cfnFrom )
337
340
)
@@ -341,35 +344,36 @@ module LocalFlow {
341
344
* Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
342
345
* SSA definition `def`.
343
346
*/
344
- predicate localSsaFlowStep ( Ssa :: Definition def , Node nodeFrom , Node nodeTo ) {
347
+ predicate localSsaFlowStep ( SsaImpl :: DefinitionExt def , Node nodeFrom , Node nodeTo ) {
345
348
// Flow from SSA definition/parameter to first read
346
- exists ( ControlFlow:: Node cfn |
347
- def = getSsaDefinition ( nodeFrom ) and
348
- nodeTo .asExprAtNode ( cfn ) = def .getAFirstReadAtNode ( cfn )
349
- )
349
+ def = getSsaDefinitionExt ( nodeFrom ) and
350
+ SsaImpl:: firstReadSameVarExt ( def , nodeTo .( ExprNode ) .getControlFlowNode ( ) )
350
351
or
351
352
// Flow from read to next read
352
353
localSsaFlowStepUseUse ( def , nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) , nodeTo )
353
354
or
354
- // Flow into phi node
355
- exists ( Ssa :: PhiNode phi |
355
+ // Flow into phi (read) node
356
+ exists ( SsaImpl :: DefinitionExt phi |
356
357
localFlowSsaInput ( nodeFrom , def , phi ) and
357
- phi = nodeTo .( SsaDefinitionNode ) .getDefinition ( ) and
358
- def = phi .getAnInput ( )
358
+ phi = nodeTo .( SsaDefinitionExtNode ) .getDefinitionExt ( )
359
+ |
360
+ phi instanceof Ssa:: PhiNode
361
+ or
362
+ phi instanceof SsaImpl:: PhiReadNode
359
363
)
360
364
or
361
365
// Flow into uncertain SSA definition
362
366
exists ( LocalFlow:: UncertainExplicitSsaDefinition uncertain |
363
367
localFlowSsaInput ( nodeFrom , def , uncertain ) and
364
- uncertain = nodeTo .( SsaDefinitionNode ) . getDefinition ( ) and
368
+ uncertain = nodeTo .( SsaDefinitionExtNode ) . getDefinitionExt ( ) and
365
369
def = uncertain .getPriorDefinition ( )
366
370
)
367
371
}
368
372
369
373
/**
370
374
* Holds if the source variable of SSA definition `def` is an instance field.
371
375
*/
372
- predicate usesInstanceField ( Ssa :: Definition def ) {
376
+ predicate usesInstanceField ( SsaImpl :: DefinitionExt def ) {
373
377
exists ( Ssa:: SourceVariables:: FieldOrPropSourceVariable fp | fp = def .getSourceVariable ( ) |
374
378
not fp .getAssignable ( ) .( Modifiable ) .isStatic ( )
375
379
)
@@ -378,7 +382,7 @@ module LocalFlow {
378
382
predicate localFlowCapturedVarStep ( Node nodeFrom , ImplicitCapturedArgumentNode nodeTo ) {
379
383
// Flow from SSA definition to implicit captured variable argument
380
384
exists ( Ssa:: ExplicitDefinition def , ControlFlow:: Nodes:: ElementNode call |
381
- def = getSsaDefinition ( nodeFrom ) and
385
+ def = getSsaDefinitionExt ( nodeFrom ) and
382
386
def .isCapturedVariableDefinitionFlowIn ( _, call , _) and
383
387
nodeTo = TImplicitCapturedArgumentNode ( call , def .getSourceVariable ( ) .getAssignable ( ) )
384
388
)
@@ -455,7 +459,7 @@ module LocalFlow {
455
459
}
456
460
457
461
predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
458
- exists ( Ssa :: Definition def |
462
+ exists ( SsaImpl :: DefinitionExt def |
459
463
localSsaFlowStep ( def , nodeFrom , nodeTo ) and
460
464
not usesInstanceField ( def )
461
465
)
@@ -517,7 +521,7 @@ module LocalFlow {
517
521
predicate simpleLocalFlowStep ( Node nodeFrom , Node nodeTo ) {
518
522
LocalFlow:: localFlowStepCommon ( nodeFrom , nodeTo )
519
523
or
520
- exists ( Ssa :: Definition def |
524
+ exists ( SsaImpl :: DefinitionExt def |
521
525
LocalFlow:: localSsaFlowStepUseUse ( def , nodeFrom , nodeTo ) and
522
526
not FlowSummaryImpl:: Private:: Steps:: prohibitsUseUseFlow ( nodeFrom ,
523
527
any ( DataFlowSummarizedCallable sc ) ) and
@@ -788,7 +792,7 @@ private module Cached {
788
792
} or
789
793
TCilExprNode ( CIL:: Expr e ) { e .getImplementation ( ) instanceof CIL:: BestImplementation } or
790
794
TCilSsaDefinitionNode ( CilSsa:: Definition def ) or
791
- TSsaDefinitionNode ( Ssa :: Definition def ) {
795
+ TSsaDefinitionExtNode ( SsaImpl :: DefinitionExt def ) {
792
796
// Handled by `TExplicitParameterNode` below
793
797
not def .( Ssa:: ExplicitDefinition ) .getADefinition ( ) instanceof
794
798
AssignableDefinitions:: ImplicitParameterDefinition
@@ -854,7 +858,7 @@ private module Cached {
854
858
or
855
859
LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo )
856
860
or
857
- exists ( Ssa :: Definition def |
861
+ exists ( SsaImpl :: DefinitionExt def |
858
862
LocalFlow:: localSsaFlowStep ( def , nodeFrom , nodeTo ) and
859
863
LocalFlow:: usesInstanceField ( def )
860
864
)
@@ -904,9 +908,11 @@ import Cached
904
908
905
909
/** Holds if `n` should be hidden from path explanations. */
906
910
predicate nodeIsHidden ( Node n ) {
907
- exists ( Ssa :: Definition def | def = n .( SsaDefinitionNode ) . getDefinition ( ) |
911
+ exists ( SsaImpl :: DefinitionExt def | def = n .( SsaDefinitionExtNode ) . getDefinitionExt ( ) |
908
912
def instanceof Ssa:: PhiNode
909
913
or
914
+ def instanceof SsaImpl:: PhiReadNode
915
+ or
910
916
def instanceof Ssa:: ImplicitEntryDefinition
911
917
or
912
918
def instanceof Ssa:: ImplicitCallDefinition
@@ -959,23 +965,31 @@ class CilSsaDefinitionNode extends NodeImpl, TCilSsaDefinitionNode {
959
965
}
960
966
961
967
/** An SSA definition, viewed as a node in a data flow graph. */
962
- class SsaDefinitionNode extends NodeImpl , TSsaDefinitionNode {
963
- Ssa :: Definition def ;
968
+ class SsaDefinitionExtNode extends NodeImpl , TSsaDefinitionExtNode {
969
+ SsaImpl :: DefinitionExt def ;
964
970
965
- SsaDefinitionNode ( ) { this = TSsaDefinitionNode ( def ) }
971
+ SsaDefinitionExtNode ( ) { this = TSsaDefinitionExtNode ( def ) }
966
972
967
973
/** Gets the underlying SSA definition. */
968
- Ssa :: Definition getDefinition ( ) { result = def }
974
+ SsaImpl :: DefinitionExt getDefinitionExt ( ) { result = def }
969
975
970
976
override DataFlowCallable getEnclosingCallableImpl ( ) {
971
- result .asCallable ( ) = def .getEnclosingCallable ( )
977
+ result .asCallable ( ) = def .( Ssa:: Definition ) .getEnclosingCallable ( )
978
+ or
979
+ result .asCallable ( ) = def .( SsaImpl:: PhiReadNode ) .getSourceVariable ( ) .getEnclosingCallable ( )
972
980
}
973
981
974
982
override Type getTypeImpl ( ) { result = def .getSourceVariable ( ) .getType ( ) }
975
983
976
- override ControlFlow:: Node getControlFlowNodeImpl ( ) { result = def .getControlFlowNode ( ) }
984
+ override ControlFlow:: Node getControlFlowNodeImpl ( ) {
985
+ result = def .( Ssa:: Definition ) .getControlFlowNode ( )
986
+ }
977
987
978
- override Location getLocationImpl ( ) { result = def .getLocation ( ) }
988
+ override Location getLocationImpl ( ) {
989
+ result = def .( Ssa:: Definition ) .getLocation ( )
990
+ or
991
+ result = def .( SsaImpl:: PhiReadNode ) .getBasicBlock ( ) .getLocation ( )
992
+ }
979
993
980
994
override string toStringImpl ( ) { result = def .toString ( ) }
981
995
}
@@ -1067,13 +1081,11 @@ private module ParameterNodes {
1067
1081
* } }
1068
1082
* ```
1069
1083
*/
1070
- class ImplicitCapturedParameterNode extends ParameterNodeImpl , SsaDefinitionNode {
1071
- override SsaCapturedEntryDefinition def ;
1072
-
1073
- ImplicitCapturedParameterNode ( ) { def = this .getDefinition ( ) }
1084
+ class ImplicitCapturedParameterNode extends ParameterNodeImpl , SsaDefinitionExtNode {
1085
+ ImplicitCapturedParameterNode ( ) { def instanceof SsaCapturedEntryDefinition }
1074
1086
1075
1087
/** Gets the captured variable that this implicit parameter models. */
1076
- LocalScopeVariable getVariable ( ) { result = def .getVariable ( ) }
1088
+ LocalScopeVariable getVariable ( ) { result = def .( SsaCapturedEntryDefinition ) . getVariable ( ) }
1077
1089
1078
1090
override predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
1079
1091
pos .isImplicitCapturedParameterPosition ( def .getSourceVariable ( ) .getAssignable ( ) ) and
@@ -1308,12 +1320,12 @@ private module ReturnNodes {
1308
1320
* A data-flow node that represents an assignment to an `out` or a `ref`
1309
1321
* parameter.
1310
1322
*/
1311
- class OutRefReturnNode extends ReturnNode , SsaDefinitionNode {
1323
+ class OutRefReturnNode extends ReturnNode , SsaDefinitionExtNode {
1312
1324
OutRefReturnKind kind ;
1313
1325
1314
1326
OutRefReturnNode ( ) {
1315
1327
exists ( Parameter p |
1316
- this .getDefinition ( ) .isLiveOutRefParameterDefinition ( p ) and
1328
+ this .getDefinitionExt ( ) . ( Ssa :: Definition ) .isLiveOutRefParameterDefinition ( p ) and
1317
1329
kind .getPosition ( ) = p .getPosition ( )
1318
1330
|
1319
1331
p .isOut ( ) and kind instanceof OutReturnKind
@@ -1397,20 +1409,20 @@ private module ReturnNodes {
1397
1409
* } }
1398
1410
* ```
1399
1411
*/
1400
- class ImplicitCapturedReturnNode extends ReturnNode , SsaDefinitionNode {
1412
+ class ImplicitCapturedReturnNode extends ReturnNode , SsaDefinitionExtNode {
1401
1413
private Ssa:: ExplicitDefinition edef ;
1402
1414
1403
1415
ImplicitCapturedReturnNode ( ) {
1404
- edef = this .getDefinition ( ) and
1416
+ edef = this .getDefinitionExt ( ) and
1405
1417
edef .isCapturedVariableDefinitionFlowOut ( _, _)
1406
1418
}
1407
1419
1408
1420
/**
1409
1421
* Holds if the value at this node may flow out to the implicit call definition
1410
1422
* at `node`, using one or more calls.
1411
1423
*/
1412
- predicate flowsOutTo ( SsaDefinitionNode node , boolean additionalCalls ) {
1413
- edef .isCapturedVariableDefinitionFlowOut ( node .getDefinition ( ) , additionalCalls )
1424
+ predicate flowsOutTo ( SsaDefinitionExtNode node , boolean additionalCalls ) {
1425
+ edef .isCapturedVariableDefinitionFlowOut ( node .getDefinitionExt ( ) , additionalCalls )
1414
1426
}
1415
1427
1416
1428
override ImplicitCapturedReturnKind getKind ( ) {
@@ -1517,13 +1529,13 @@ private module OutNodes {
1517
1529
* A data-flow node that reads a value returned implicitly by a callable
1518
1530
* using a captured variable.
1519
1531
*/
1520
- class CapturedOutNode extends OutNode , SsaDefinitionNode {
1532
+ class CapturedOutNode extends OutNode , SsaDefinitionExtNode {
1521
1533
private DataFlowCall call ;
1522
1534
1523
1535
CapturedOutNode ( ) {
1524
1536
exists ( ImplicitCapturedReturnNode n , boolean additionalCalls , ControlFlow:: Node cfn |
1525
1537
n .flowsOutTo ( this , additionalCalls ) and
1526
- cfn = this .getDefinition ( ) .getControlFlowNode ( )
1538
+ cfn = this .getDefinitionExt ( ) . ( Ssa :: Definition ) .getControlFlowNode ( )
1527
1539
|
1528
1540
additionalCalls = false and call = csharpCall ( _, cfn )
1529
1541
or
@@ -1535,7 +1547,7 @@ private module OutNodes {
1535
1547
override DataFlowCall getCall ( ReturnKind kind ) {
1536
1548
result = call and
1537
1549
kind .( ImplicitCapturedReturnKind ) .getVariable ( ) =
1538
- this .getDefinition ( ) .getSourceVariable ( ) .getAssignable ( )
1550
+ this .getDefinitionExt ( ) .getSourceVariable ( ) .getAssignable ( )
1539
1551
}
1540
1552
}
1541
1553
@@ -1816,7 +1828,7 @@ predicate readStep(Node node1, Content c, Node node2) {
1816
1828
exists ( ForeachStmt fs , Ssa:: ExplicitDefinition def |
1817
1829
x .hasDefPath ( fs .getIterableExpr ( ) , node1 .getControlFlowNode ( ) , def .getADefinition ( ) ,
1818
1830
def .getControlFlowNode ( ) ) and
1819
- node2 .( SsaDefinitionNode ) . getDefinition ( ) = def and
1831
+ node2 .( SsaDefinitionExtNode ) . getDefinitionExt ( ) = def and
1820
1832
c instanceof ElementContent
1821
1833
)
1822
1834
or
@@ -1839,7 +1851,7 @@ predicate readStep(Node node1, Content c, Node node2) {
1839
1851
or
1840
1852
// item = variable in node1 = (..., variable, ...)
1841
1853
exists ( AssignableDefinitions:: TupleAssignmentDefinition tad , Ssa:: ExplicitDefinition def |
1842
- node2 .( SsaDefinitionNode ) . getDefinition ( ) = def and
1854
+ node2 .( SsaDefinitionExtNode ) . getDefinitionExt ( ) = def and
1843
1855
def .getADefinition ( ) = tad and
1844
1856
tad .getLeaf ( ) = item and
1845
1857
hasNodePath ( x , node1 , node2 )
@@ -1848,7 +1860,7 @@ predicate readStep(Node node1, Content c, Node node2) {
1848
1860
// item = variable in node1 = (..., variable, ...) in a case/is var (..., ...)
1849
1861
te = any ( PatternExpr pe ) .getAChildExpr * ( ) and
1850
1862
exists ( AssignableDefinitions:: LocalVariableDefinition lvd , Ssa:: ExplicitDefinition def |
1851
- node2 .( SsaDefinitionNode ) . getDefinition ( ) = def and
1863
+ node2 .( SsaDefinitionExtNode ) . getDefinitionExt ( ) = def and
1852
1864
def .getADefinition ( ) = lvd and
1853
1865
lvd .getDeclaration ( ) = item and
1854
1866
hasNodePath ( x , node1 , node2 )
@@ -2182,7 +2194,7 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
2182
2194
2183
2195
/** Extra data-flow steps needed for lambda flow analysis. */
2184
2196
predicate additionalLambdaFlowStep ( Node nodeFrom , Node nodeTo , boolean preservesValue ) {
2185
- exists ( Ssa :: Definition def |
2197
+ exists ( SsaImpl :: DefinitionExt def |
2186
2198
LocalFlow:: localSsaFlowStep ( def , nodeFrom , nodeTo ) and
2187
2199
LocalFlow:: usesInstanceField ( def ) and
2188
2200
preservesValue = true
0 commit comments