@@ -64,37 +64,37 @@ module LocalFlow {
64
64
)
65
65
}
66
66
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
+
67
75
/**
68
76
* Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
69
77
* SSA definition `def`.
70
78
*/
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
89
84
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
+ )
98
98
)
99
99
// TODO
100
100
// or
@@ -105,6 +105,42 @@ module LocalFlow {
105
105
// def = uncertain.getPriorDefinition()
106
106
// )
107
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
+ }
108
144
}
109
145
110
146
/** An argument of a call (including qualifier arguments, excluding block arguments). */
@@ -160,68 +196,37 @@ private module Cached {
160
196
p .( KeywordParameter ) .getDefaultValue ( ) = e .getExprNode ( ) .getExpr ( )
161
197
}
162
198
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
-
199
199
/**
200
200
* This is the local flow predicate that is used as a building block in global
201
201
* data flow.
202
202
*/
203
203
cached
204
204
predicate simpleLocalFlowStep ( Node nodeFrom , Node nodeTo ) {
205
- localFlowStepCommon ( nodeFrom , nodeTo )
205
+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
206
206
or
207
207
defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
208
208
or
209
209
nodeTo = LocalFlow:: getParameterDefNode ( nodeFrom .( ParameterNode ) .getParameter ( ) )
210
210
or
211
211
nodeTo .( SynthReturnNode ) .getAnInput ( ) = nodeFrom
212
212
or
213
+ LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo ) and
214
+ not FlowSummaryImpl:: Private:: Steps:: summaryClearsContentArg ( nodeFrom , _)
215
+ or
213
216
FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( nodeFrom , nodeTo , true )
214
217
}
215
218
216
219
/** This is the local flow predicate that is exposed. */
217
220
cached
218
221
predicate localFlowStepImpl ( Node nodeFrom , Node nodeTo ) {
219
- localFlowStepCommon ( nodeFrom , nodeTo )
222
+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
220
223
or
221
224
defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
222
225
or
223
226
nodeTo = LocalFlow:: getParameterDefNode ( nodeFrom .( ParameterNode ) .getParameter ( ) )
224
227
or
228
+ LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo )
229
+ or
225
230
// Simple flow through library code is included in the exposed local
226
231
// step relation, even though flow is technically inter-procedural
227
232
FlowSummaryImpl:: Private:: Steps:: summaryThroughStep ( nodeFrom , nodeTo , true )
@@ -230,12 +235,14 @@ private module Cached {
230
235
/** This is the local flow predicate that is used in type tracking. */
231
236
cached
232
237
predicate localFlowStepTypeTracker ( Node nodeFrom , Node nodeTo ) {
233
- localFlowStepCommon ( nodeFrom , nodeTo )
238
+ LocalFlow :: localFlowStepCommon ( nodeFrom , nodeTo )
234
239
or
235
240
exists ( NamedParameter p |
236
241
defaultValueFlow ( p , nodeFrom ) and
237
242
nodeTo = LocalFlow:: getParameterDefNode ( p )
238
243
)
244
+ or
245
+ LocalFlow:: localSsaFlowStepUseUse ( _, nodeFrom , nodeTo )
239
246
}
240
247
241
248
cached
0 commit comments