@@ -76,23 +76,25 @@ module LocalFlow {
7676 * Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
7777 * SSA definition `def`.
7878 */
79- predicate localSsaFlowStep ( Ssa:: Definition def , Node nodeFrom , Node nodeTo ) {
80- // Flow from assignment into SSA definition
81- def .( Ssa:: WriteDefinition ) .assigns ( nodeFrom .asExpr ( ) ) and
82- nodeTo .( SsaDefinitionNode ) .getDefinition ( ) = def
83- or
84- // Flow from SSA definition to first read
85- def = nodeFrom .( SsaDefinitionNode ) .getDefinition ( ) and
86- nodeTo .asExpr ( ) = def .getAFirstRead ( )
87- or
88- // Flow from read to next read
89- localSsaFlowStepUseUse ( def , nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) , nodeTo )
90- or
91- // Flow into phi node
92- exists ( Ssa:: PhiNode phi |
93- localFlowSsaInput ( nodeFrom , def , phi ) and
94- phi = nodeTo .( SsaDefinitionNode ) .getDefinition ( ) and
95- def = phi .getAnInput ( )
79+ private predicate localSsaFlowStep ( Node nodeFrom , Node nodeTo ) {
80+ exists ( Ssa:: Definition def |
81+ // Flow from assignment into SSA definition
82+ def .( Ssa:: WriteDefinition ) .assigns ( nodeFrom .asExpr ( ) ) and
83+ nodeTo .( SsaDefinitionNode ) .getDefinition ( ) = def
84+ or
85+ // Flow from SSA definition to first read
86+ def = nodeFrom .( SsaDefinitionNode ) .getDefinition ( ) and
87+ nodeTo .asExpr ( ) = def .getAFirstRead ( )
88+ or
89+ // Flow from read to next read
90+ localSsaFlowStepUseUse ( def , nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) , nodeTo )
91+ or
92+ // Flow into phi node
93+ exists ( Ssa:: PhiNode phi |
94+ localFlowSsaInput ( nodeFrom , def , phi ) and
95+ phi = nodeTo .( SsaDefinitionNode ) .getDefinition ( ) and
96+ def = phi .getAnInput ( )
97+ )
9698 )
9799 // TODO
98100 // or
@@ -103,6 +105,42 @@ module LocalFlow {
103105 // def = uncertain.getPriorDefinition()
104106 // )
105107 }
108+
109+ predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
110+ localSsaFlowStep ( nodeFrom , nodeTo )
111+ or
112+ nodeFrom .( SelfParameterNode ) .getMethod ( ) = nodeTo .asExpr ( ) .getExpr ( ) .getEnclosingCallable ( ) and
113+ nodeTo .asExpr ( ) .getExpr ( ) instanceof Self
114+ or
115+ nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: AssignExprCfgNode ) .getRhs ( )
116+ or
117+ nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: BlockArgumentCfgNode ) .getValue ( )
118+ or
119+ nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: StmtSequenceCfgNode ) .getLastStmt ( )
120+ or
121+ nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: ConditionalExprCfgNode ) .getBranch ( _)
122+ or
123+ nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: CaseExprCfgNode ) .getBranch ( _)
124+ or
125+ exists ( CfgNodes:: ExprCfgNode exprTo , ReturningStatementNode n |
126+ nodeFrom = n and
127+ exprTo = nodeTo .asExpr ( ) and
128+ n .getReturningNode ( ) .getNode ( ) instanceof BreakStmt and
129+ exprTo .getNode ( ) instanceof Loop and
130+ nodeTo .asExpr ( ) .getAPredecessor ( any ( SuccessorTypes:: BreakSuccessor s ) ) = n .getReturningNode ( )
131+ )
132+ or
133+ nodeFrom .asExpr ( ) = nodeTo .( ReturningStatementNode ) .getReturningNode ( ) .getReturnedValueNode ( )
134+ or
135+ nodeTo .asExpr ( ) =
136+ any ( CfgNodes:: ExprNodes:: ForExprCfgNode for |
137+ exists ( SuccessorType s |
138+ not s instanceof SuccessorTypes:: BreakSuccessor and
139+ exists ( for .getAPredecessor ( s ) )
140+ ) and
141+ nodeFrom .asExpr ( ) = for .getValue ( )
142+ )
143+ }
106144}
107145
108146/** An argument of a call (including qualifier arguments, excluding block arguments). */
@@ -158,49 +196,13 @@ private module Cached {
158196 p .( KeywordParameter ) .getDefaultValue ( ) = e .getExprNode ( ) .getExpr ( )
159197 }
160198
161- private predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
162- LocalFlow:: localSsaFlowStep ( _, nodeFrom , nodeTo )
163- or
164- nodeFrom .( SelfParameterNode ) .getMethod ( ) = nodeTo .asExpr ( ) .getExpr ( ) .getEnclosingCallable ( ) and
165- nodeTo .asExpr ( ) .getExpr ( ) instanceof Self
166- or
167- nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: AssignExprCfgNode ) .getRhs ( )
168- or
169- nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: BlockArgumentCfgNode ) .getValue ( )
170- or
171- nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: StmtSequenceCfgNode ) .getLastStmt ( )
172- or
173- nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: ConditionalExprCfgNode ) .getBranch ( _)
174- or
175- nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: CaseExprCfgNode ) .getBranch ( _)
176- or
177- exists ( CfgNodes:: ExprCfgNode exprTo , ReturningStatementNode n |
178- nodeFrom = n and
179- exprTo = nodeTo .asExpr ( ) and
180- n .getReturningNode ( ) .getNode ( ) instanceof BreakStmt and
181- exprTo .getNode ( ) instanceof Loop and
182- nodeTo .asExpr ( ) .getAPredecessor ( any ( SuccessorTypes:: BreakSuccessor s ) ) = n .getReturningNode ( )
183- )
184- or
185- nodeFrom .asExpr ( ) = nodeTo .( ReturningStatementNode ) .getReturningNode ( ) .getReturnedValueNode ( )
186- or
187- nodeTo .asExpr ( ) =
188- any ( CfgNodes:: ExprNodes:: ForExprCfgNode for |
189- exists ( SuccessorType s |
190- not s instanceof SuccessorTypes:: BreakSuccessor and
191- exists ( for .getAPredecessor ( s ) )
192- ) and
193- nodeFrom .asExpr ( ) = for .getValue ( )
194- )
195- }
196-
197199 /**
198200 * This is the local flow predicate that is used as a building block in global
199201 * data flow.
200202 */
201203 cached
202204 predicate simpleLocalFlowStep ( Node nodeFrom , Node nodeTo ) {
203- localFlowStepCommon ( nodeFrom , nodeTo )
205+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
204206 or
205207 defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
206208 or
@@ -217,7 +219,7 @@ private module Cached {
217219 /** This is the local flow predicate that is exposed. */
218220 cached
219221 predicate localFlowStepImpl ( Node nodeFrom , Node nodeTo ) {
220- localFlowStepCommon ( nodeFrom , nodeTo )
222+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
221223 or
222224 defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
223225 or
@@ -233,7 +235,7 @@ private module Cached {
233235 /** This is the local flow predicate that is used in type tracking. */
234236 cached
235237 predicate localFlowStepTypeTracker ( Node nodeFrom , Node nodeTo ) {
236- localFlowStepCommon ( nodeFrom , nodeTo )
238+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
237239 or
238240 exists ( NamedParameter p |
239241 defaultValueFlow ( p , nodeFrom ) and
0 commit comments