@@ -76,23 +76,25 @@ module LocalFlow {
76
76
* Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
77
77
* SSA definition `def`.
78
78
*/
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
+ )
96
98
)
97
99
// TODO
98
100
// or
@@ -103,6 +105,42 @@ module LocalFlow {
103
105
// def = uncertain.getPriorDefinition()
104
106
// )
105
107
}
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
+ }
106
144
}
107
145
108
146
/** An argument of a call (including qualifier arguments, excluding block arguments). */
@@ -158,49 +196,13 @@ private module Cached {
158
196
p .( KeywordParameter ) .getDefaultValue ( ) = e .getExprNode ( ) .getExpr ( )
159
197
}
160
198
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
-
197
199
/**
198
200
* This is the local flow predicate that is used as a building block in global
199
201
* data flow.
200
202
*/
201
203
cached
202
204
predicate simpleLocalFlowStep ( Node nodeFrom , Node nodeTo ) {
203
- localFlowStepCommon ( nodeFrom , nodeTo )
205
+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
204
206
or
205
207
defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
206
208
or
@@ -217,7 +219,7 @@ private module Cached {
217
219
/** This is the local flow predicate that is exposed. */
218
220
cached
219
221
predicate localFlowStepImpl ( Node nodeFrom , Node nodeTo ) {
220
- localFlowStepCommon ( nodeFrom , nodeTo )
222
+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
221
223
or
222
224
defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
223
225
or
@@ -233,7 +235,7 @@ private module Cached {
233
235
/** This is the local flow predicate that is used in type tracking. */
234
236
cached
235
237
predicate localFlowStepTypeTracker ( Node nodeFrom , Node nodeTo ) {
236
- localFlowStepCommon ( nodeFrom , nodeTo )
238
+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
237
239
or
238
240
exists ( NamedParameter p |
239
241
defaultValueFlow ( p , nodeFrom ) and
0 commit comments