@@ -51,12 +51,21 @@ private import Splitting
5151private import semmle.code.csharp.ExprOrStmtParent
5252
5353/** An element that defines a new CFG scope. */
54- class CfgScope extends Element , @top_level_exprorstmt_parent { }
54+ class CfgScope extends Element , @top_level_exprorstmt_parent {
55+ CfgScope ( ) { not this instanceof Attribute }
56+ }
5557
5658module ControlFlowTree {
5759 private class Range_ = @callable or @control_flow_element;
5860
59- class Range extends Element , Range_ { }
61+ class Range extends Element , Range_ {
62+ Range ( ) { this = getAChild * ( any ( CfgScope scope ) ) }
63+ }
64+
65+ Element getAChild ( Element p ) {
66+ result = p .getAChild ( ) or
67+ result = p .( AssignOperation ) .getExpandedAssignment ( )
68+ }
6069
6170 private predicate id ( Range x , Range y ) { x = y }
6271
@@ -360,7 +369,9 @@ module Expressions {
360369 not this instanceof SwitchExpr and
361370 not this instanceof SwitchCaseExpr and
362371 not this instanceof ConstructorInitializer and
363- not this instanceof NotPatternExpr
372+ not this instanceof NotPatternExpr and
373+ not this instanceof OrPatternExpr and
374+ not this instanceof AndPatternExpr
364375 }
365376
366377 final override ControlFlowElement getChildElement ( int i ) { result = getExprChild ( this , i ) }
@@ -902,6 +913,56 @@ module Expressions {
902913 c instanceof NormalCompletion
903914 }
904915 }
916+
917+ private class AndPatternExprTree extends PostOrderTree , AndPatternExpr {
918+ final override predicate propagatesAbnormal ( ControlFlowElement child ) {
919+ child = this .getAnOperand ( )
920+ }
921+
922+ final override predicate first ( ControlFlowElement first ) { first ( this .getLeftOperand ( ) , first ) }
923+
924+ final override predicate succ ( ControlFlowElement pred , ControlFlowElement succ , Completion c ) {
925+ // Flow from last element of left operand to first element of right operand
926+ last ( this .getLeftOperand ( ) , pred , c ) and
927+ c .( MatchingCompletion ) .getValue ( ) = true and
928+ first ( this .getRightOperand ( ) , succ )
929+ or
930+ // Post-order: flow from last element of left operand to element itself
931+ last ( this .getLeftOperand ( ) , pred , c ) and
932+ c .( MatchingCompletion ) .getValue ( ) = false and
933+ succ = this
934+ or
935+ // Post-order: flow from last element of right operand to element itself
936+ last ( this .getRightOperand ( ) , pred , c ) and
937+ c instanceof MatchingCompletion and
938+ succ = this
939+ }
940+ }
941+
942+ private class OrPatternExprTree extends PostOrderTree , OrPatternExpr {
943+ final override predicate propagatesAbnormal ( ControlFlowElement child ) {
944+ child = this .getAnOperand ( )
945+ }
946+
947+ final override predicate first ( ControlFlowElement first ) { first ( this .getLeftOperand ( ) , first ) }
948+
949+ final override predicate succ ( ControlFlowElement pred , ControlFlowElement succ , Completion c ) {
950+ // Flow from last element of left operand to first element of right operand
951+ last ( this .getLeftOperand ( ) , pred , c ) and
952+ c .( MatchingCompletion ) .getValue ( ) = false and
953+ first ( this .getRightOperand ( ) , succ )
954+ or
955+ // Post-order: flow from last element of left operand to element itself
956+ last ( this .getLeftOperand ( ) , pred , c ) and
957+ c .( MatchingCompletion ) .getValue ( ) = true and
958+ succ = this
959+ or
960+ // Post-order: flow from last element of right operand to element itself
961+ last ( this .getRightOperand ( ) , pred , c ) and
962+ c instanceof MatchingCompletion and
963+ succ = this
964+ }
965+ }
905966}
906967
907968module Statements {
@@ -1273,7 +1334,7 @@ module Statements {
12731334 /** Gets a child of `cfe` that is in CFG scope `scope`. */
12741335 pragma [ noinline]
12751336 private ControlFlowElement getAChildInScope ( ControlFlowElement cfe , Callable scope ) {
1276- result = [ cfe . getAChild ( ) , cfe . ( AssignOperation ) . getExpandedAssignment ( ) ] and
1337+ result = ControlFlowTree :: getAChild ( cfe ) and
12771338 scope = result .getEnclosingCallable ( )
12781339 }
12791340
0 commit comments