@@ -64,37 +64,37 @@ module LocalFlow {
6464 )
6565 }
6666
67+ /**
68+ * Holds if there is a local use-use flow step from `nodeFrom` to `nodeTo`
69+ * involving SSA definition `def`.
70+ */
71+ predicate localSsaFlowStepUseUse ( Ssa:: Definition def , Node nodeFrom , Node nodeTo ) {
72+ def .hasAdjacentReads ( nodeFrom .asExpr ( ) , nodeTo .asExpr ( ) )
73+ }
74+
6775 /**
6876 * Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
6977 * SSA definition `def`.
7078 */
71- predicate localSsaFlowStep ( Ssa:: Definition def , Node nodeFrom , Node nodeTo ) {
72- // Flow from assignment into SSA definition
73- def .( Ssa:: WriteDefinition ) .assigns ( nodeFrom .asExpr ( ) ) and
74- nodeTo .( SsaDefinitionNode ) .getDefinition ( ) = def
75- or
76- // Flow from SSA definition to first read
77- def = nodeFrom .( SsaDefinitionNode ) .getDefinition ( ) and
78- nodeTo .asExpr ( ) = def .getAFirstRead ( )
79- or
80- // Flow from read to next read
81- exists (
82- CfgNodes:: ExprNodes:: VariableReadAccessCfgNode read1 ,
83- CfgNodes:: ExprNodes:: VariableReadAccessCfgNode read2
84- |
85- def .hasAdjacentReads ( read1 , read2 ) and
86- nodeTo .asExpr ( ) = read2
87- |
88- nodeFrom .asExpr ( ) = read1
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
8984 or
90- read1 = nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( )
91- )
92- or
93- // Flow into phi node
94- exists ( Ssa:: PhiNode phi |
95- localFlowSsaInput ( nodeFrom , def , phi ) and
96- phi = nodeTo .( SsaDefinitionNode ) .getDefinition ( ) and
97- def = phi .getAnInput ( )
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+ )
9898 )
9999 // TODO
100100 // or
@@ -105,6 +105,42 @@ module LocalFlow {
105105 // def = uncertain.getPriorDefinition()
106106 // )
107107 }
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+ }
108144}
109145
110146/** An argument of a call (including qualifier arguments, excluding block arguments). */
@@ -160,68 +196,37 @@ private module Cached {
160196 p .( KeywordParameter ) .getDefaultValue ( ) = e .getExprNode ( ) .getExpr ( )
161197 }
162198
163- private predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
164- LocalFlow:: localSsaFlowStep ( _, nodeFrom , nodeTo )
165- or
166- nodeFrom .( SelfParameterNode ) .getMethod ( ) = nodeTo .asExpr ( ) .getExpr ( ) .getEnclosingCallable ( ) and
167- nodeTo .asExpr ( ) .getExpr ( ) instanceof Self
168- or
169- nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: AssignExprCfgNode ) .getRhs ( )
170- or
171- nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: BlockArgumentCfgNode ) .getValue ( )
172- or
173- nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: StmtSequenceCfgNode ) .getLastStmt ( )
174- or
175- nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: ConditionalExprCfgNode ) .getBranch ( _)
176- or
177- nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( CfgNodes:: ExprNodes:: CaseExprCfgNode ) .getBranch ( _)
178- or
179- exists ( CfgNodes:: ExprCfgNode exprTo , ReturningStatementNode n |
180- nodeFrom = n and
181- exprTo = nodeTo .asExpr ( ) and
182- n .getReturningNode ( ) .getNode ( ) instanceof BreakStmt and
183- exprTo .getNode ( ) instanceof Loop and
184- nodeTo .asExpr ( ) .getAPredecessor ( any ( SuccessorTypes:: BreakSuccessor s ) ) = n .getReturningNode ( )
185- )
186- or
187- nodeFrom .asExpr ( ) = nodeTo .( ReturningStatementNode ) .getReturningNode ( ) .getReturnedValueNode ( )
188- or
189- nodeTo .asExpr ( ) =
190- any ( CfgNodes:: ExprNodes:: ForExprCfgNode for |
191- exists ( SuccessorType s |
192- not s instanceof SuccessorTypes:: BreakSuccessor and
193- exists ( for .getAPredecessor ( s ) )
194- ) and
195- nodeFrom .asExpr ( ) = for .getValue ( )
196- )
197- }
198-
199199 /**
200200 * This is the local flow predicate that is used as a building block in global
201201 * data flow.
202202 */
203203 cached
204204 predicate simpleLocalFlowStep ( Node nodeFrom , Node nodeTo ) {
205- localFlowStepCommon ( nodeFrom , nodeTo )
205+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
206206 or
207207 defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
208208 or
209209 nodeTo = LocalFlow:: getParameterDefNode ( nodeFrom .( ParameterNode ) .getParameter ( ) )
210210 or
211211 nodeTo .( SynthReturnNode ) .getAnInput ( ) = nodeFrom
212212 or
213+ LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo ) and
214+ not FlowSummaryImpl:: Private:: Steps:: summaryClearsContentArg ( nodeFrom , _)
215+ or
213216 FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( nodeFrom , nodeTo , true )
214217 }
215218
216219 /** This is the local flow predicate that is exposed. */
217220 cached
218221 predicate localFlowStepImpl ( Node nodeFrom , Node nodeTo ) {
219- localFlowStepCommon ( nodeFrom , nodeTo )
222+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
220223 or
221224 defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
222225 or
223226 nodeTo = LocalFlow:: getParameterDefNode ( nodeFrom .( ParameterNode ) .getParameter ( ) )
224227 or
228+ LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo )
229+ or
225230 // Simple flow through library code is included in the exposed local
226231 // step relation, even though flow is technically inter-procedural
227232 FlowSummaryImpl:: Private:: Steps:: summaryThroughStep ( nodeFrom , nodeTo , true )
@@ -230,12 +235,14 @@ private module Cached {
230235 /** This is the local flow predicate that is used in type tracking. */
231236 cached
232237 predicate localFlowStepTypeTracker ( Node nodeFrom , Node nodeTo ) {
233- localFlowStepCommon ( nodeFrom , nodeTo )
238+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
234239 or
235240 exists ( NamedParameter p |
236241 defaultValueFlow ( p , nodeFrom ) and
237242 nodeTo = LocalFlow:: getParameterDefNode ( p )
238243 )
244+ or
245+ LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo )
239246 }
240247
241248 cached
0 commit comments