Skip to content

Commit 4f40d24

Browse files
authored
Merge pull request #22711 from michaelnebel/csharp/prepareforpatternflow
C#: Prepare for pattern flow.
2 parents f229566 + a5555d9 commit 4f40d24

9 files changed

Lines changed: 63 additions & 33 deletions

File tree

‎csharp/ql/lib/semmle/code/csharp/Assignable.qll‎

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -277,15 +277,28 @@ module AssignableInternal {
277277
def = TParameterDefaultDefinition(_, result)
278278
}
279279

280-
/** A local variable declaration at the top-level of a pattern. */
281-
class TopLevelPatternDecl extends LocalVariableDeclExpr {
280+
/** A pattern containing a local variable declaration. */
281+
class LocalVariablePatternDecl extends LocalVariableDeclExpr {
282282
private PatternMatch pm;
283283

284-
TopLevelPatternDecl() { this = pm.getPattern().(BindingPatternExpr).getVariableDeclExpr() }
284+
LocalVariablePatternDecl() {
285+
exists(BindingPatternExpr bpe |
286+
this = bpe.getVariableDeclExpr() and pm = bpe.getPatternMatch()
287+
)
288+
}
289+
290+
/** Holds if the local variable definition is at the top level of the pattern. */
291+
predicate isTopLevel() { this = pm.getPattern().(BindingPatternExpr).getVariableDeclExpr() }
285292

293+
/** Gets the pattern match that this local variable declaration (pattern) belongs to. */
286294
PatternMatch getMatch() { result = pm }
287295
}
288296

297+
/** A local variable declaration at the top-level of a pattern. */
298+
class TopLevelPatternDecl extends LocalVariablePatternDecl {
299+
TopLevelPatternDecl() { this.isTopLevel() }
300+
}
301+
289302
cached
290303
private module Cached {
291304
cached
@@ -305,7 +318,7 @@ module AssignableInternal {
305318
TLocalVariableDefinition(LocalVariableDeclExpr lvde) {
306319
not lvde.hasInitializer() and
307320
not exists(getTupleSource(TTupleAssignmentDefinition(_, lvde))) and
308-
not lvde instanceof TopLevelPatternDecl and
321+
not lvde instanceof LocalVariablePatternDecl and
309322
not lvde.isOutArgument()
310323
} or
311324
TImplicitParameterDefinition(Parameter p) {
@@ -324,7 +337,7 @@ module AssignableInternal {
324337
default = p.getDefaultValue()
325338
} or
326339
TAddressOfDefinition(AddressOfExpr aoe) or
327-
TPatternDefinition(TopLevelPatternDecl tlpd) or
340+
TPatternDefinition(LocalVariablePatternDecl lvpd) or
328341
TAssignOperationDefinition(AssignOperation ao) {
329342
ao instanceof AssignCallExpr and not ao instanceof CompoundAssignmentOperatorCall
330343
or
@@ -737,24 +750,31 @@ module AssignableDefinitions {
737750
}
738751

739752
/**
740-
* A local variable definition in a pattern, for example `x is int i`.
753+
* A local variable definition in a pattern, for example `int i` in `x is int i`.
741754
*/
742755
class PatternDefinition extends AssignableDefinition, TPatternDefinition {
743-
TopLevelPatternDecl tlpd;
756+
LocalVariablePatternDecl lvpd;
744757

745-
PatternDefinition() { this = TPatternDefinition(tlpd) }
758+
PatternDefinition() { this = TPatternDefinition(lvpd) }
746759

747760
/** Gets the element matches against this pattern. */
748-
PatternMatch getMatch() { result = tlpd.getMatch() }
761+
PatternMatch getMatch() { result = lvpd.getMatch() }
749762

750763
/** Gets the underlying local variable declaration. */
751-
LocalVariableDeclExpr getDeclaration() { result = tlpd }
752-
753-
override Expr getSource() { result = this.getMatch().getExpr() }
764+
LocalVariableDeclExpr getDeclaration() { result = lvpd }
754765

755766
override string toString() { result = this.getDeclaration().toString() }
756767
}
757768

769+
/**
770+
* A local variable definition at the top level of a pattern.
771+
*/
772+
class TopLevelPatternDefinition extends PatternDefinition {
773+
TopLevelPatternDefinition() { lvpd.isTopLevel() }
774+
775+
override Expr getSource() { result = this.getMatch().getExpr() }
776+
}
777+
758778
/**
759779
* An initializer definition for a field or a property, for example
760780
* line 2 in

‎csharp/ql/lib/semmle/code/csharp/dataflow/Nullness.qll‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ private predicate nonNullDef(SsaExplicitWrite def) {
110110
def.getValue() instanceof NonNullExpr
111111
or
112112
exists(AssignableDefinition ad | ad = def.getDefinition() |
113-
ad instanceof AssignableDefinitions::PatternDefinition
113+
ad instanceof AssignableDefinitions::TopLevelPatternDefinition
114114
or
115115
ad =
116116
any(AssignableDefinitions::LocalVariableDefinition d |

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

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -560,10 +560,16 @@ module LocalFlow {
560560
or
561561
exists(AssignExpr ae | ae.getLeftOperand().(TupleExpr) = e2 and ae.getRightOperand() = e1)
562562
or
563-
exists(ControlFlowElement cfe | cfe = e2.(TupleExpr).(PatternExpr).getPatternMatch() |
564-
cfe.(IsExpr).getExpr() = e1
565-
or
566-
exists(Switch sw | sw.getACase() = cfe and sw.getExpr() = e1)
563+
exists(IsExpr e |
564+
e1 = e.getExpr() and
565+
e2 = e.getPattern() and
566+
e2 instanceof TuplePatternExpr
567+
)
568+
or
569+
exists(Switch sw |
570+
e1 = sw.getExpr() and
571+
e2 = sw.getACase().getPattern() and
572+
e2 instanceof TuplePatternExpr
567573
)
568574
}
569575

@@ -2242,8 +2248,8 @@ private predicate readContentStep(Node node1, Content c, Node node2) {
22422248
)
22432249
or
22442250
// item = variable in node1 = (..., variable, ...) in a case/is var (..., ...)
2245-
isPatternExprDescendant(te) and
2246-
exists(AssignableDefinitions::LocalVariableDefinition lvd |
2251+
te instanceof TuplePatternExpr and
2252+
exists(AssignableDefinitions::PatternDefinition lvd |
22472253
node2.(AssignableDefinitionNode).getDefinition() = lvd and
22482254
lvd.getDeclaration() = item
22492255
)
@@ -2677,7 +2683,7 @@ class CastNode extends Node {
26772683
this.asExpr() instanceof Cast
26782684
or
26792685
this.(AssignableDefinitionNode).getDefinition() instanceof
2680-
AssignableDefinitions::PatternDefinition
2686+
AssignableDefinitions::TopLevelPatternDefinition
26812687
}
26822688
}
26832689

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,13 @@ class PositionalPatternExpr extends PatternExpr, @positional_pattern_expr {
547547
override string getAPrimaryQlClass() { result = "PositionalPatternExpr" }
548548
}
549549

550+
/**
551+
* A tuple pattern. For example, `var (x, y)`.
552+
*/
553+
class TuplePatternExpr extends TupleExpr, PatternExpr {
554+
override string getAPrimaryQlClass() { result = "TuplePatternExpr" }
555+
}
556+
550557
/** A list pattern. For example `[1, 2, int y]` in `x is [1, 2, int y]`. */
551558
class ListPatternExpr extends PatternExpr, @list_pattern_expr {
552559
override string toString() { result = "[ ... ]" }

‎csharp/ql/src/Dead Code/DeadStoreOfLocal.ql‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class RelevantDefinition extends AssignableDefinition {
3535
not lvde.getName() = "_"
3636
)
3737
or
38-
this instanceof AssignableDefinitions::PatternDefinition
38+
this instanceof AssignableDefinitions::TopLevelPatternDefinition
3939
or
4040
this instanceof AssignableDefinitions::AssignOperationDefinition
4141
}

‎csharp/ql/test/library-tests/csharp8/PrintAst.expected‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ patterns.cs:
929929
# 57| 1: [ConstantPatternExpr,IntLiteral] 2
930930
# 58| 10: [BreakStmt] break;
931931
# 59| 11: [CaseStmt] case ...:
932-
# 59| 0: [TupleExpr] (..., ...)
932+
# 59| 0: [TuplePatternExpr] (..., ...)
933933
# 59| 0: [VariablePatternExpr] Int32 x
934934
# 59| 1: [VariablePatternExpr] Int32 y
935935
# 60| 12: [BreakStmt] break;
@@ -1156,7 +1156,7 @@ patterns.cs:
11561156
# 130| 1: [ConstantPatternExpr,IntLiteral] 2
11571157
# 130| 2: [IntLiteral] 2
11581158
# 131| 3: [SwitchCaseExpr] ... => ...
1159-
# 131| 0: [TupleExpr] (..., ...)
1159+
# 131| 0: [TuplePatternExpr] (..., ...)
11601160
# 131| 0: [VariablePatternExpr] Int32 x
11611161
# 131| 1: [DiscardPatternExpr] _
11621162
# 131| 2: [IntLiteral] 3

‎csharp/ql/test/library-tests/dataflow/tuples/DataFlowStep.expected‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@
108108
| Tuples.cs:59:17:59:32 | (..., ...) | Tuples.cs:59:13:59:13 | access to local variable x |
109109
| Tuples.cs:60:17:60:17 | access to local variable x | Tuples.cs:62:18:62:57 | (String,(Int32,String),Int32) t |
110110
| Tuples.cs:60:17:60:17 | access to local variable x | Tuples.cs:67:18:67:35 | (..., ...) |
111-
| Tuples.cs:60:17:60:17 | access to local variable x | Tuples.cs:67:18:67:35 | (..., ...) |
112111
| Tuples.cs:60:17:60:17 | access to local variable x | Tuples.cs:87:13:87:13 | access to local variable x |
113112
| Tuples.cs:62:18:62:57 | (String,(Int32,String),Int32) t | Tuples.cs:62:18:62:57 | SSA def(t) |
114113
| Tuples.cs:62:18:62:57 | SSA def(t) | Tuples.cs:62:64:62:64 | access to local variable t |
@@ -144,7 +143,6 @@
144143
| Tuples.cs:75:13:75:30 | SSA qualifier def(y.Item2.Item2) | Tuples.cs:80:22:80:34 | access to field Item2 |
145144
| Tuples.cs:75:17:75:30 | (..., ...) | Tuples.cs:75:13:75:13 | access to local variable y |
146145
| Tuples.cs:75:18:75:18 | access to parameter s | Tuples.cs:75:25:75:25 | access to parameter s |
147-
| Tuples.cs:76:17:76:17 | access to local variable y | Tuples.cs:78:26:78:35 | (..., ...) |
148146
| Tuples.cs:76:17:76:17 | access to local variable y | Tuples.cs:79:22:79:22 | access to local variable y |
149147
| Tuples.cs:78:19:78:23 | SSA def(a) | Tuples.cs:78:46:78:46 | access to local variable a |
150148
| Tuples.cs:78:19:78:23 | String a | Tuples.cs:78:19:78:23 | SSA def(a) |
@@ -161,7 +159,6 @@
161159
| Tuples.cs:82:22:82:34 | access to field Item1 | Tuples.cs:82:22:82:34 | (...) ... |
162160
| Tuples.cs:83:22:83:22 | access to local variable b | Tuples.cs:83:22:83:22 | (...) ... |
163161
| Tuples.cs:87:13:87:13 | access to local variable x | Tuples.cs:87:18:87:35 | (..., ...) |
164-
| Tuples.cs:87:13:87:13 | access to local variable x | Tuples.cs:87:18:87:35 | (..., ...) |
165162
| Tuples.cs:87:23:87:23 | SSA def(p) | Tuples.cs:89:18:89:18 | access to local variable p |
166163
| Tuples.cs:87:23:87:23 | String p | Tuples.cs:87:23:87:23 | SSA def(p) |
167164
| Tuples.cs:87:27:87:27 | Int32 q | Tuples.cs:87:27:87:27 | SSA def(q) |

‎csharp/ql/test/library-tests/dataflow/tuples/PrintAst.expected‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,9 @@ Tuples.cs:
262262
# 65| -1: [LocalVariableAccess] access to local variable t
263263
# 66| 4: [BreakStmt] break;
264264
# 67| 5: [CaseStmt] case ...:
265-
# 67| 0: [TupleExpr] (..., ...)
265+
# 67| 0: [TuplePatternExpr] (..., ...)
266266
# 67| 0: [VariablePatternExpr] String a
267-
# 67| 1: [TupleExpr] (..., ...)
267+
# 67| 1: [TuplePatternExpr] (..., ...)
268268
# 67| 0: [VariablePatternExpr] Int32 b
269269
# 67| 1: [VariablePatternExpr] String c
270270
# 67| 2: [DiscardPatternExpr] _
@@ -302,7 +302,7 @@ Tuples.cs:
302302
# 78| 0: [RecursivePatternExpr] { ... }
303303
# 78| 2: [PositionalPatternExpr] ( ... )
304304
# 78| 0: [VariablePatternExpr] String a
305-
# 78| 1: [TupleExpr] (..., ...)
305+
# 78| 1: [TuplePatternExpr] (..., ...)
306306
# 78| 0: [VariablePatternExpr] Int32 b
307307
# 78| 1: [VariablePatternExpr] String c
308308
# 78| 2: [DiscardPatternExpr] _
@@ -335,9 +335,9 @@ Tuples.cs:
335335
# 87| 7: [IfStmt] if (...) ...
336336
# 87| 0: [IsExpr] ... is ...
337337
# 87| 0: [LocalVariableAccess] access to local variable x
338-
# 87| 1: [TupleExpr] (..., ...)
338+
# 87| 1: [TuplePatternExpr] (..., ...)
339339
# 87| 0: [VariablePatternExpr] String p
340-
# 87| 1: [TupleExpr] (..., ...)
340+
# 87| 1: [TuplePatternExpr] (..., ...)
341341
# 87| 0: [VariablePatternExpr] Int32 q
342342
# 87| 1: [VariablePatternExpr] String r
343343
# 87| 2: [DiscardPatternExpr] _
@@ -417,7 +417,7 @@ Tuples.cs:
417417
# 107| 6: [SwitchStmt] switch (...) {...}
418418
# 107| 0: [LocalVariableAccess] access to local variable r
419419
# 109| 0: [CaseStmt] case ...:
420-
# 109| 0: [TupleExpr] (..., ...)
420+
# 109| 0: [TuplePatternExpr] (..., ...)
421421
# 109| 0: [VariablePatternExpr] String x
422422
# 109| 1: [VariablePatternExpr] Int32 y
423423
# 110| 1: [ExprStmt] ...;

‎csharp/ql/test/library-tests/dataflow/tuples/Tuples.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,4 +142,4 @@ public static void Sink(object o) { }
142142
namespace System.Runtime.CompilerServices
143143
{
144144
public class IsExternalInit { }
145-
}
145+
}

0 commit comments

Comments
 (0)