@@ -177,32 +177,6 @@ predicate hasNodePath(ControlFlowReachabilityConfiguration conf, ExprNode n1, No
177177 )
178178}
179179
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-
206180/** Provides predicates related to local data flow. */
207181module LocalFlow {
208182 private class LocalExprStepConfiguration extends ControlFlowReachabilityConfiguration {
@@ -436,6 +410,28 @@ module LocalFlow {
436410 n instanceof SummaryNode or
437411 n instanceof ImplicitCapturedArgumentNode
438412 }
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+ }
439435}
440436
441437/**
@@ -745,7 +741,7 @@ private module Cached {
745741 cfn .getElement ( ) .( ObjectCreation ) .hasInitializer ( )
746742 } or
747743 TExprPostUpdateNode ( ControlFlow:: Nodes:: ExprNode cfn ) {
748- cfn = getAPostUpdateNodeForArg ( _)
744+ cfn = LocalFlow :: getAPostUpdateNodeForArg ( _)
749745 or
750746 exists ( Expr e | e = cfn .getExpr ( ) |
751747 fieldOrPropertyStore ( _, _, _, e , true )
@@ -1943,14 +1939,14 @@ private module PostUpdateNodes {
19431939 ExprPostUpdateNode ( ) { this = TExprPostUpdateNode ( cfn ) }
19441940
19451941 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
19471943 // `[post] x` and `[post] y` to have two pre-update nodes: (1) the compund argument,
19481944 // `if b then x else y`; and the (2) the underlying expressions; `x` and `y`,
19491945 // respectively.
19501946 //
19511947 // This ensures that we get flow out of the call into both leafs (1), while still
19521948 // maintaining the invariant that the underlying expression is a pre-update node (2).
1953- cfn = getAPostUpdateNodeForArg ( result .asExpr ( ) )
1949+ cfn = LocalFlow :: getAPostUpdateNodeForArg ( result .asExpr ( ) )
19541950 or
19551951 cfn = result .getControlFlowNode ( )
19561952 }
0 commit comments