@@ -605,7 +605,7 @@ module LocalFlow {
605605 isSuccessor = false
606606 or
607607 isSuccessor = true and
608- exists ( ControlFlowElement cfe | cfe = e2 .( TupleExpr ) . ( PatternExpr ) .getPatternMatch ( ) |
608+ exists ( ControlFlowElement cfe | cfe = e2 .( TuplePatternExpr ) .getPatternMatch ( ) |
609609 cfe .( IsExpr ) .getExpr ( ) = e1 and scope = cfe
610610 or
611611 exists ( Switch sw | sw .getACase ( ) = cfe and sw .getExpr ( ) = e1 and scope = sw )
@@ -624,18 +624,29 @@ module LocalFlow {
624624 scope = def .getExpr ( ) and
625625 isSuccessor = true
626626 or
627- scope = def .( AssignableDefinitions:: PatternDefinition ) .getMatch ( ) .( IsExpr ) and
628- isSuccessor = false
629- or
630- exists ( Switch s |
631- s .getACase ( ) = def .( AssignableDefinitions:: PatternDefinition ) .getMatch ( ) and
632- isSuccessor = true
633- |
634- scope = s .getExpr ( )
627+ exists ( AssignableDefinitions:: PatternDefinition def0 | def = def0 and def0 .isTopLevel ( ) |
628+ scope = def0 .getMatch ( ) .( IsExpr ) and
629+ isSuccessor = false
635630 or
636- scope = s .getACase ( )
631+ exists ( Switch s |
632+ s .getACase ( ) = def0 .getMatch ( ) and
633+ isSuccessor = true
634+ |
635+ scope = s .getExpr ( )
636+ or
637+ scope = s .getACase ( )
638+ )
637639 )
638640 )
641+ or
642+ // Needed for read steps for pattern matching involving properties.
643+ scope = def .getExpr ( ) and
644+ exactScope = false and
645+ isSuccessor = false and
646+ def =
647+ any ( AssignableDefinitions:: PatternDefinition apd |
648+ e = apd .getDeclaration ( ) and not apd .isTopLevel ( )
649+ )
639650 }
640651 }
641652
@@ -896,6 +907,30 @@ private predicate fieldOrPropertyStore(Expr e, ContentSet c, Expr src, Expr q, b
896907 )
897908}
898909
910+ private predicate patternPropertyRead0 ( RecursivePatternExpr rpe , ContentSet c , VariablePatternExpr e ) {
911+ exists ( TypeAccess ta , Property prop |
912+ ta = rpe .getTypeAccess ( ) and
913+ e = rpe .getPropertyPatterns ( ) .getPattern ( _) and
914+ prop .getDeclaringType ( ) = ta .getType ( ) and
915+ prop .getName ( ) = e .( LabeledPatternExpr ) .getLabel ( ) and
916+ c .isProperty ( prop )
917+ )
918+ }
919+
920+ private predicate patternPropertyRead ( Expr e1 , ContentSet c , VariablePatternExpr e2 ) {
921+ exists ( IsExpr ie , RecursivePatternExpr rpe |
922+ e1 = ie .getExpr ( ) and
923+ rpe = ie .getPattern ( ) and
924+ patternPropertyRead0 ( rpe , c , e2 )
925+ )
926+ or
927+ exists ( Switch sw , RecursivePatternExpr rpe |
928+ e1 = sw .getExpr ( ) and
929+ rpe = sw .getACase ( ) .getPattern ( ) and
930+ patternPropertyRead0 ( rpe , c , e2 )
931+ )
932+ }
933+
899934/**
900935 * Holds if `e2` is an expression that reads field or property `c` from
901936 * expression `e1`.
@@ -1124,6 +1159,8 @@ private module Cached {
11241159 or
11251160 dynamicPropertyRead ( e , _, read )
11261161 or
1162+ patternPropertyRead ( e , _, read )
1163+ or
11271164 arrayRead ( e , read )
11281165 )
11291166 )
@@ -2415,6 +2452,11 @@ private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration
24152452 e2 = e1 .( TupleExpr ) .getAnArgument ( ) and
24162453 scope = e1 and
24172454 isSuccessor = false
2455+ or
2456+ exactScope = false and
2457+ isSuccessor = true and
2458+ patternPropertyRead ( e1 , _, e2 ) and
2459+ scope = e1
24182460 }
24192461
24202462 override predicate candidateDef (
@@ -2446,8 +2488,8 @@ private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration
24462488 )
24472489 or
24482490 scope =
2449- any ( TupleExpr te |
2450- te .getAnArgument ( ) = defTo .( AssignableDefinitions:: LocalVariableDefinition ) .getDeclaration ( ) and
2491+ any ( TuplePatternExpr te |
2492+ te .getAnArgument ( ) = defTo .( AssignableDefinitions:: PatternDefinition ) .getDeclaration ( ) and
24512493 e = te and
24522494 exactScope = false and
24532495 isSuccessor = false
@@ -2496,8 +2538,8 @@ private predicate readContentStep(Node node1, Content c, Node node2) {
24962538 )
24972539 or
24982540 // item = variable in node1 = (..., variable, ...) in a case/is var (..., ...)
2499- te = any ( PatternExpr pe ) .getAChildExpr * ( ) and
2500- exists ( AssignableDefinitions:: LocalVariableDefinition lvd |
2541+ te = any ( TuplePatternExpr pe ) .getAChildExpr * ( ) and
2542+ exists ( AssignableDefinitions:: PatternDefinition lvd |
25012543 node2 .( AssignableDefinitionNode ) .getDefinition ( ) = lvd and
25022544 lvd .getDeclaration ( ) = item and
25032545 hasNodePath ( x , node1 , node2 )
@@ -2537,6 +2579,8 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
25372579 or
25382580 dynamicPropertyRead ( node1 .asExpr ( ) , c , node2 .asExpr ( ) )
25392581 or
2582+ patternPropertyRead ( node1 .asExpr ( ) , c , node2 .asExpr ( ) )
2583+ or
25402584 node2 .asExpr ( ) .( AwaitExpr ) .getExpr ( ) = node1 .asExpr ( ) and
25412585 c = getResultContent ( )
25422586 )
@@ -2927,8 +2971,10 @@ class CastNode extends Node {
29272971 CastNode ( ) {
29282972 this .asExpr ( ) instanceof Cast
29292973 or
2930- this .( AssignableDefinitionNode ) .getDefinition ( ) instanceof
2931- AssignableDefinitions:: PatternDefinition
2974+ this .( AssignableDefinitionNode )
2975+ .getDefinition ( )
2976+ .( AssignableDefinitions:: PatternDefinition )
2977+ .isTopLevel ( )
29322978 }
29332979}
29342980
0 commit comments