@@ -177,32 +177,6 @@ predicate hasNodePath(ControlFlowReachabilityConfiguration conf, ExprNode n1, No
177
177
)
178
178
}
179
179
180
- /**
181
- * Gets a node that may execute last in `n`, and which, when it executes last,
182
- * will be the value of `n`.
183
- */
184
- private ControlFlow:: Nodes:: ExprNode getALastEvalNode ( ControlFlow:: Nodes:: ExprNode cfn ) {
185
- exists ( ConditionalExpr e | cfn .getExpr ( ) = e | result .getExpr ( ) = [ e .getThen ( ) , e .getElse ( ) ] )
186
- }
187
-
188
- private predicate relevantArgumentType ( ControlFlow:: Nodes:: ExprNode cfn ) {
189
- exists ( Expr e | cfn .getExpr ( ) = e |
190
- exists ( Type t | t = e .stripCasts ( ) .getType ( ) |
191
- t instanceof RefType and
192
- not t instanceof NullType
193
- or
194
- t = any ( TypeParameter tp | not tp .isValueType ( ) )
195
- )
196
- )
197
- }
198
-
199
- /** Gets a node for which to construct a post-update node for argument `arg`. */
200
- ControlFlow:: Nodes:: ExprNode getAPostUpdateNodeForArg ( Argument arg ) {
201
- result = getALastEvalNode * ( arg .getAControlFlowNode ( ) ) and
202
- relevantArgumentType ( result ) and
203
- not exists ( getALastEvalNode ( result ) )
204
- }
205
-
206
180
/** Provides predicates related to local data flow. */
207
181
module LocalFlow {
208
182
private class LocalExprStepConfiguration extends ControlFlowReachabilityConfiguration {
@@ -436,6 +410,28 @@ module LocalFlow {
436
410
n instanceof SummaryNode or
437
411
n instanceof ImplicitCapturedArgumentNode
438
412
}
413
+
414
+ /**
415
+ * Gets a node that may execute last in `n`, and which, when it executes last,
416
+ * will be the value of `n`.
417
+ */
418
+ private ControlFlow:: Nodes:: ExprNode getALastEvalNode ( ControlFlow:: Nodes:: ExprNode cfn ) {
419
+ any ( LocalExprStepConfiguration x ) .hasExprPath ( _, result , any ( ConditionalExpr ce ) , cfn )
420
+ }
421
+
422
+ /** Gets a node for which to construct a post-update node for argument `arg`. */
423
+ ControlFlow:: Nodes:: ExprNode getAPostUpdateNodeForArg ( Argument arg ) {
424
+ result = getALastEvalNode * ( arg .getAControlFlowNode ( ) ) and
425
+ exists ( Expr e | result .getExpr ( ) = e |
426
+ exists ( Type t | t = e .stripCasts ( ) .getType ( ) |
427
+ t instanceof RefType and
428
+ not t instanceof NullType
429
+ or
430
+ t = any ( TypeParameter tp | not tp .isValueType ( ) )
431
+ )
432
+ ) and
433
+ not exists ( getALastEvalNode ( result ) )
434
+ }
439
435
}
440
436
441
437
/**
@@ -745,7 +741,7 @@ private module Cached {
745
741
cfn .getElement ( ) .( ObjectCreation ) .hasInitializer ( )
746
742
} or
747
743
TExprPostUpdateNode ( ControlFlow:: Nodes:: ExprNode cfn ) {
748
- cfn = getAPostUpdateNodeForArg ( _)
744
+ cfn = LocalFlow :: getAPostUpdateNodeForArg ( _)
749
745
or
750
746
exists ( Expr e | e = cfn .getExpr ( ) |
751
747
fieldOrPropertyStore ( _, _, _, e , true )
@@ -1943,14 +1939,14 @@ private module PostUpdateNodes {
1943
1939
ExprPostUpdateNode ( ) { this = TExprPostUpdateNode ( cfn ) }
1944
1940
1945
1941
override ExprNode getPreUpdateNode ( ) {
1946
- // For compund arguments, such as `m(if b then x else y)`, we want the leaf nodes
1942
+ // For compund arguments, such as `m(b ? x : y)`, we want the leaf nodes
1947
1943
// `[post] x` and `[post] y` to have two pre-update nodes: (1) the compund argument,
1948
1944
// `if b then x else y`; and the (2) the underlying expressions; `x` and `y`,
1949
1945
// respectively.
1950
1946
//
1951
1947
// This ensures that we get flow out of the call into both leafs (1), while still
1952
1948
// maintaining the invariant that the underlying expression is a pre-update node (2).
1953
- cfn = getAPostUpdateNodeForArg ( result .asExpr ( ) )
1949
+ cfn = LocalFlow :: getAPostUpdateNodeForArg ( result .asExpr ( ) )
1954
1950
or
1955
1951
cfn = result .getControlFlowNode ( )
1956
1952
}
0 commit comments