@@ -283,7 +283,7 @@ module VariableCapture {
283283 private import semmle.code.csharp.controlflow.BasicBlocks as BasicBlocks
284284
285285 private predicate closureFlowStep ( ControlFlow:: Nodes:: ExprNode e1 , ControlFlow:: Nodes:: ExprNode e2 ) {
286- e1 = LocalFlow:: getALastEvalNode ( e2 )
286+ e1 . getExpr ( ) = LocalFlow:: getALastEvalNode ( e2 . getExpr ( ) )
287287 or
288288 exists ( Ssa:: Definition def , AssignableDefinition adef |
289289 LocalFlow:: defAssigns ( adef , _, _, e1 ) and
@@ -528,98 +528,58 @@ module SsaFlow {
528528
529529/** Provides predicates related to local data flow. */
530530module LocalFlow {
531- class LocalExprStepConfiguration extends ControlFlowReachabilityConfiguration {
532- LocalExprStepConfiguration ( ) { this = "LocalExprStepConfiguration" }
533-
534- override predicate candidate (
535- Expr e1 , Expr e2 , ControlFlowElement scope , boolean exactScope , boolean isSuccessor
536- ) {
537- exactScope = false and
538- (
539- e1 = e2 .( ParenthesizedExpr ) .getExpr ( ) and
540- scope = e2 and
541- isSuccessor = true
542- or
543- e1 = e2 .( NullCoalescingExpr ) .getAnOperand ( ) and
544- scope = e2 and
545- isSuccessor = true
546- or
547- e1 = e2 .( SuppressNullableWarningExpr ) .getExpr ( ) and
548- scope = e2 and
549- isSuccessor = true
550- or
551- e2 =
552- any ( ConditionalExpr ce |
553- e1 = ce .getThen ( ) or
554- e1 = ce .getElse ( )
555- ) and
556- scope = e2 and
557- isSuccessor = true
558- or
559- e1 = e2 .( Cast ) .getExpr ( ) and
560- scope = e2 and
561- isSuccessor = true
562- or
563- // An `=` expression, where the result of the expression is used
564- e2 =
565- any ( AssignExpr ae |
566- ae .getParent ( ) = any ( ControlFlowElement cfe | not cfe instanceof ExprStmt ) and
567- e1 = ae .getRValue ( )
568- ) and
569- scope = e2 and
570- isSuccessor = true
571- or
572- e1 = e2 .( ObjectCreation ) .getInitializer ( ) and
573- scope = e2 and
574- isSuccessor = false
575- or
576- e1 = e2 .( ArrayCreation ) .getInitializer ( ) and
577- scope = e2 and
578- isSuccessor = false
579- or
580- e1 = e2 .( SwitchExpr ) .getACase ( ) .getBody ( ) and
581- scope = e2 and
582- isSuccessor = true
583- or
584- e1 = e2 .( CheckedExpr ) .getExpr ( ) and
585- scope = e2 and
586- isSuccessor = true
587- or
588- e1 = e2 .( UncheckedExpr ) .getExpr ( ) and
589- scope = e2 and
590- isSuccessor = true
591- or
592- e1 = e2 .( CollectionExpression ) .getAnElement ( ) and
593- e1 instanceof SpreadElementExpr and
594- scope = e2 and
595- isSuccessor = true
596- or
597- e1 = e2 .( SpreadElementExpr ) .getExpr ( ) and
598- scope = e2 and
599- isSuccessor = true
600- or
601- exists ( WithExpr we |
602- scope = we and
603- isSuccessor = true
604- |
605- e1 = we .getExpr ( ) and
606- e2 = we .getInitializer ( )
607- or
608- e1 = we .getInitializer ( ) and
609- e2 = we
610- )
611- or
612- scope = any ( AssignExpr ae | ae .getLValue ( ) .( TupleExpr ) = e2 and ae .getRValue ( ) = e1 ) and
613- isSuccessor = false
614- or
615- isSuccessor = true and
616- exists ( ControlFlowElement cfe | cfe = e2 .( TupleExpr ) .( PatternExpr ) .getPatternMatch ( ) |
617- cfe .( IsExpr ) .getExpr ( ) = e1 and scope = cfe
618- or
619- exists ( Switch sw | sw .getACase ( ) = cfe and sw .getExpr ( ) = e1 and scope = sw )
620- )
531+ predicate localExprStep ( Expr e1 , Expr e2 ) {
532+ e1 = e2 .( ParenthesizedExpr ) .getExpr ( )
533+ or
534+ e1 = e2 .( NullCoalescingExpr ) .getAnOperand ( )
535+ or
536+ e1 = e2 .( SuppressNullableWarningExpr ) .getExpr ( )
537+ or
538+ e2 =
539+ any ( ConditionalExpr ce |
540+ e1 = ce .getThen ( ) or
541+ e1 = ce .getElse ( )
621542 )
622- }
543+ or
544+ e1 = e2 .( Cast ) .getExpr ( )
545+ or
546+ // An `=` expression, where the result of the expression is used
547+ e2 =
548+ any ( AssignExpr ae |
549+ ae .getParent ( ) = any ( ControlFlowElement cfe | not cfe instanceof ExprStmt ) and
550+ e1 = ae .getRValue ( )
551+ )
552+ or
553+ e1 = e2 .( ObjectCreation ) .getInitializer ( )
554+ or
555+ e1 = e2 .( ArrayCreation ) .getInitializer ( )
556+ or
557+ e1 = e2 .( SwitchExpr ) .getACase ( ) .getBody ( )
558+ or
559+ e1 = e2 .( CheckedExpr ) .getExpr ( )
560+ or
561+ e1 = e2 .( UncheckedExpr ) .getExpr ( )
562+ or
563+ e1 = e2 .( CollectionExpression ) .getAnElement ( ) and
564+ e1 instanceof SpreadElementExpr
565+ or
566+ e1 = e2 .( SpreadElementExpr ) .getExpr ( )
567+ or
568+ exists ( WithExpr we |
569+ e1 = we .getExpr ( ) and
570+ e2 = we .getInitializer ( )
571+ or
572+ e1 = we .getInitializer ( ) and
573+ e2 = we
574+ )
575+ or
576+ exists ( AssignExpr ae | ae .getLValue ( ) .( TupleExpr ) = e2 and ae .getRValue ( ) = e1 )
577+ or
578+ exists ( ControlFlowElement cfe | cfe = e2 .( TupleExpr ) .( PatternExpr ) .getPatternMatch ( ) |
579+ cfe .( IsExpr ) .getExpr ( ) = e1
580+ or
581+ exists ( Switch sw | sw .getACase ( ) = cfe and sw .getExpr ( ) = e1 )
582+ )
623583 }
624584
625585 predicate defAssigns (
@@ -646,7 +606,7 @@ module LocalFlow {
646606 }
647607
648608 predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
649- hasNodePath ( any ( LocalExprStepConfiguration x ) , nodeFrom , nodeTo )
609+ localExprStep ( nodeFrom . asExpr ( ) , nodeTo . asExpr ( ) )
650610 or
651611 defAssigns ( nodeFrom , nodeTo )
652612 or
@@ -674,11 +634,12 @@ module LocalFlow {
674634 }
675635
676636 /**
677- * Gets a node that may execute last in `n `, and which, when it executes last,
678- * will be the value of `n `.
637+ * Gets a node that may execute last in `e `, and which, when it executes last,
638+ * will be the value of `e `.
679639 */
680- ControlFlow:: Nodes:: ExprNode getALastEvalNode ( ControlFlow:: Nodes:: ExprNode cfn ) {
681- exists ( Expr e | any ( LocalExprStepConfiguration x ) .hasExprPath ( _, result , e , cfn ) |
640+ Expr getALastEvalNode ( Expr e ) {
641+ localExprStep ( result , e ) and
642+ (
682643 e instanceof ConditionalExpr or
683644 e instanceof Cast or
684645 e instanceof NullCoalescingExpr or
@@ -702,9 +663,7 @@ module LocalFlow {
702663 * we add a reverse flow step from `[post] b ? x : y` to `[post] x` and to
703664 * `[post] y`, in order for the side-effect of `m` to reach both `x` and `y`.
704665 */
705- ControlFlow:: Nodes:: ExprNode getPostUpdateReverseStep ( ControlFlow:: Nodes:: ExprNode e ) {
706- result = getALastEvalNode ( e )
707- }
666+ Expr getPostUpdateReverseStep ( Expr e ) { result = getALastEvalNode ( e ) }
708667
709668 /**
710669 * Holds if the value of `node2` is given by `node1`.
@@ -720,7 +679,7 @@ module LocalFlow {
720679 or
721680 defAssigns ( node1 , node2 )
722681 or
723- hasNodePath ( any ( LocalExprStepConfiguration x ) , node1 , node2 ) and
682+ localExprStep ( node1 . asExpr ( ) , node2 . asExpr ( ) ) and
724683 (
725684 node2 .asExpr ( ) instanceof Cast or
726685 node2 .asExpr ( ) instanceof AssignExpr
@@ -765,12 +724,8 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
765724 or
766725 nodeTo = nodeFrom .( LocalFunctionCreationNode ) .getAnAccess ( true )
767726 or
768- nodeTo .( PostUpdateNode ) .getPreUpdateNode ( ) .( ExprNode ) .getControlFlowNode ( ) =
769- LocalFlow:: getPostUpdateReverseStep ( nodeFrom
770- .( PostUpdateNode )
771- .getPreUpdateNode ( )
772- .( ExprNode )
773- .getControlFlowNode ( ) )
727+ nodeTo .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) =
728+ LocalFlow:: getPostUpdateReverseStep ( nodeFrom .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) )
774729 ) and
775730 model = ""
776731 or
@@ -1119,10 +1074,10 @@ private module Cached {
11191074 (
11201075 cfn .getExpr ( ) instanceof Argument
11211076 or
1122- cfn =
1123- LocalFlow:: getPostUpdateReverseStep ( any ( ControlFlow :: Nodes :: ExprNode e |
1124- exists ( any ( SourcePostUpdateNode p ) .getPreUpdateNode ( ) . asExprAtNode ( e ) )
1125- ) )
1077+ cfn . getExpr ( ) =
1078+ LocalFlow:: getPostUpdateReverseStep ( any ( SourcePostUpdateNode p )
1079+ .getPreUpdateNode ( )
1080+ . asExpr ( ) )
11261081 ) and
11271082 exprMayHavePostUpdateNode ( cfn .getExpr ( ) )
11281083 or
0 commit comments