@@ -76,19 +76,29 @@ module LocalFlow {
7676 private import codeql.ruby.dataflow.internal.SsaImpl
7777
7878 /**
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`.
8180 */
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
8587 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
92102 )
93103 }
94104
@@ -139,9 +149,9 @@ module LocalFlow {
139149 // Flow from read to next read
140150 localSsaFlowStepUseUse ( def , nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) , nodeTo )
141151 or
142- // Flow into phi node
152+ // Flow into phi node from definition
143153 exists ( Ssa:: PhiNode phi |
144- localFlowSsaInput ( nodeFrom , def , phi ) and
154+ localFlowSsaInputFromDef ( nodeFrom , def , phi ) and
145155 phi = nodeTo .( SsaDefinitionNode ) .getDefinition ( ) and
146156 def = phi .getAnInput ( )
147157 )
@@ -308,6 +318,18 @@ private module Cached {
308318 LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo ) and
309319 not FlowSummaryImpl:: Private:: Steps:: prohibitsUseUseFlow ( nodeFrom , _)
310320 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
311333 FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( nodeFrom , nodeTo , true )
312334 }
313335
@@ -338,6 +360,14 @@ private module Cached {
338360 )
339361 or
340362 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+ )
341371 }
342372
343373 private predicate entrySsaDefinition ( SsaDefinitionNode n ) {
0 commit comments