@@ -76,19 +76,29 @@ module LocalFlow {
76
76
private import codeql.ruby.dataflow.internal.SsaImpl
77
77
78
78
/**
79
- * Holds if `nodeFrom` is a last node referencing SSA definition `def`, which
80
- * can reach `next`.
79
+ * Holds if `nodeFrom` is a node for SSA definition `def`, which can reach `next`.
81
80
*/
82
- private predicate localFlowSsaInput ( Node nodeFrom , Ssa:: Definition def , Ssa:: Definition next ) {
83
- exists ( BasicBlock bb , int i | lastRefBeforeRedef ( def , bb , i , next ) |
84
- def = nodeFrom .( SsaDefinitionNode ) .getDefinition ( ) and
81
+ private predicate localFlowSsaInputFromDef (
82
+ SsaDefinitionNode nodeFrom , Ssa:: Definition def , Ssa:: Definition next
83
+ ) {
84
+ exists ( BasicBlock bb , int i |
85
+ lastRefBeforeRedef ( def , bb , i , next ) and
86
+ def = nodeFrom .getDefinition ( ) and
85
87
def .definesAt ( _, bb , i )
86
- or
87
- exists ( CfgNodes:: ExprCfgNode e |
88
- e = nodeFrom .asExpr ( ) and
89
- e = bb .getNode ( i ) and
90
- e .getExpr ( ) instanceof VariableReadAccess
91
- )
88
+ )
89
+ }
90
+
91
+ /**
92
+ * Holds if `exprFrom` is a last read of SSA definition `def`, which
93
+ * can reach `next`.
94
+ */
95
+ predicate localFlowSsaInputFromExpr (
96
+ CfgNodes:: ExprCfgNode exprFrom , Ssa:: Definition def , Ssa:: Definition next
97
+ ) {
98
+ exists ( BasicBlock bb , int i |
99
+ lastRefBeforeRedef ( def , bb , i , next ) and
100
+ exprFrom = bb .getNode ( i ) and
101
+ exprFrom .getExpr ( ) instanceof VariableReadAccess
92
102
)
93
103
}
94
104
@@ -139,9 +149,9 @@ module LocalFlow {
139
149
// Flow from read to next read
140
150
localSsaFlowStepUseUse ( def , nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) , nodeTo )
141
151
or
142
- // Flow into phi node
152
+ // Flow into phi node from definition
143
153
exists ( Ssa:: PhiNode phi |
144
- localFlowSsaInput ( nodeFrom , def , phi ) and
154
+ localFlowSsaInputFromDef ( nodeFrom , def , phi ) and
145
155
phi = nodeTo .( SsaDefinitionNode ) .getDefinition ( ) and
146
156
def = phi .getAnInput ( )
147
157
)
@@ -308,6 +318,18 @@ private module Cached {
308
318
LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo ) and
309
319
not FlowSummaryImpl:: Private:: Steps:: prohibitsUseUseFlow ( nodeFrom , _)
310
320
or
321
+ // Flow into phi node from read
322
+ exists ( Ssa:: Definition def , Ssa:: PhiNode phi , CfgNodes:: ExprCfgNode exprFrom |
323
+ LocalFlow:: localFlowSsaInputFromExpr ( exprFrom , def , phi ) and
324
+ phi = nodeTo .( SsaDefinitionNode ) .getDefinition ( ) and
325
+ def = phi .getAnInput ( )
326
+ |
327
+ exprFrom = nodeFrom .asExpr ( ) and
328
+ not FlowSummaryImpl:: Private:: Steps:: prohibitsUseUseFlow ( nodeFrom , _)
329
+ or
330
+ exprFrom = nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( )
331
+ )
332
+ or
311
333
FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( nodeFrom , nodeTo , true )
312
334
}
313
335
@@ -338,6 +360,14 @@ private module Cached {
338
360
)
339
361
or
340
362
LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo )
363
+ or
364
+ // Flow into phi node from read
365
+ exists ( Ssa:: Definition def , Ssa:: PhiNode phi , CfgNodes:: ExprCfgNode exprFrom |
366
+ LocalFlow:: localFlowSsaInputFromExpr ( exprFrom , def , phi ) and
367
+ phi = nodeTo .( SsaDefinitionNode ) .getDefinition ( ) and
368
+ def = phi .getAnInput ( ) and
369
+ exprFrom = [ nodeFrom .asExpr ( ) , nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) ]
370
+ )
341
371
}
342
372
343
373
private predicate entrySsaDefinition ( SsaDefinitionNode n ) {
0 commit comments