Skip to content

Commit bc84d4f

Browse files
committed
C#: Prototype of pattern match flow.
1 parent f5de231 commit bc84d4f

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,11 @@ module LocalFlow {
636636
scope = s.getACase()
637637
)
638638
)
639+
or
640+
e.(VariablePatternExpr).getVariableDeclExpr().getVariable() =
641+
def.(AssignableDefinitions::PatternDefinition).getTarget() and
642+
exactScope = false and
643+
isSuccessor = false
639644
}
640645
}
641646

@@ -896,6 +901,18 @@ private predicate fieldOrPropertyStore(Expr e, ContentSet c, Expr src, Expr q, b
896901
)
897902
}
898903

904+
private predicate patternPropertyRead(Expr e1, ContentSet c, LabeledPatternExpr e2) {
905+
exists(IsExpr ie, RecursivePatternExpr p, TypeAccess ta, Property prop |
906+
e1 = ie.getExpr() and
907+
p = ie.getPattern() and
908+
ta = p.getTypeAccess() and
909+
e2 = p.getPropertyPatterns().getPattern(_) and
910+
prop.getDeclaringType() = ta.getType() and
911+
prop.getName() = e2.getLabel() and
912+
c.isProperty(prop)
913+
)
914+
}
915+
899916
/**
900917
* Holds if `e2` is an expression that reads field or property `c` from
901918
* expression `e1`.
@@ -1124,6 +1141,8 @@ private module Cached {
11241141
or
11251142
dynamicPropertyRead(e, _, read)
11261143
or
1144+
patternPropertyRead(e, _, read)
1145+
or
11271146
arrayRead(e, read)
11281147
)
11291148
)
@@ -2415,6 +2434,11 @@ private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration
24152434
e2 = e1.(TupleExpr).getAnArgument() and
24162435
scope = e1 and
24172436
isSuccessor = false
2437+
or
2438+
exactScope = false and
2439+
isSuccessor = true and
2440+
patternPropertyRead(e1, _, e2) and
2441+
scope = e1
24182442
}
24192443

24202444
override predicate candidateDef(
@@ -2537,6 +2561,8 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
25372561
or
25382562
dynamicPropertyRead(node1.asExpr(), c, node2.asExpr())
25392563
or
2564+
patternPropertyRead(node1.asExpr(), c, node2.asExpr())
2565+
or
25402566
node2.asExpr().(AwaitExpr).getExpr() = node1.asExpr() and
25412567
c = getResultContent()
25422568
)

csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,10 @@ class RecursivePatternExpr extends BindingPatternExpr, @recursive_pattern_expr {
505505
*/
506506
TypeAccess getTypeAccess() { result = this.getChild(1) }
507507

508-
override LocalVariableDeclExpr getVariableDeclExpr() { result = this.getChild(0) }
508+
override LocalVariableDeclExpr getVariableDeclExpr() {
509+
result = this.getChild(0) or
510+
result = this.getPropertyPatterns().getPattern(_).(BindingPatternExpr).getVariableDeclExpr()
511+
}
509512
}
510513

511514
/** A property pattern. For example, `{ Length: 5 }`. */

0 commit comments

Comments
 (0)