Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions csharp/ql/lib/semmle/code/csharp/Assignable.qll
Original file line number Diff line number Diff line change
Expand Up @@ -277,15 +277,28 @@ module AssignableInternal {
def = TParameterDefaultDefinition(_, result)
}

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

TopLevelPatternDecl() { this = pm.getPattern().(BindingPatternExpr).getVariableDeclExpr() }
LocalVariablePatternDecl() {
exists(BindingPatternExpr bpe |
this = bpe.getVariableDeclExpr() and pm = bpe.getPatternMatch()
)
}

/** Holds if the local variable definition is at the top level of the pattern. */
predicate isTopLevel() { this = pm.getPattern().(BindingPatternExpr).getVariableDeclExpr() }

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

/** A local variable declaration at the top-level of a pattern. */
class TopLevelPatternDecl extends LocalVariablePatternDecl {
TopLevelPatternDecl() { this.isTopLevel() }
}

cached
private module Cached {
cached
Expand All @@ -305,7 +318,7 @@ module AssignableInternal {
TLocalVariableDefinition(LocalVariableDeclExpr lvde) {
not lvde.hasInitializer() and
not exists(getTupleSource(TTupleAssignmentDefinition(_, lvde))) and
not lvde instanceof TopLevelPatternDecl and
not lvde instanceof LocalVariablePatternDecl and
not lvde.isOutArgument()
} or
TImplicitParameterDefinition(Parameter p) {
Expand All @@ -324,7 +337,7 @@ module AssignableInternal {
default = p.getDefaultValue()
} or
TAddressOfDefinition(AddressOfExpr aoe) or
TPatternDefinition(TopLevelPatternDecl tlpd) or
TPatternDefinition(LocalVariablePatternDecl lvpd) or
TAssignOperationDefinition(AssignOperation ao) {
ao instanceof AssignCallExpr and not ao instanceof CompoundAssignmentOperatorCall
or
Expand Down Expand Up @@ -737,24 +750,31 @@ module AssignableDefinitions {
}

/**
* A local variable definition in a pattern, for example `x is int i`.
* A local variable definition in a pattern, for example `int i` in `x is int i`.
*/
class PatternDefinition extends AssignableDefinition, TPatternDefinition {
TopLevelPatternDecl tlpd;
LocalVariablePatternDecl lvpd;

PatternDefinition() { this = TPatternDefinition(tlpd) }
PatternDefinition() { this = TPatternDefinition(lvpd) }

/** Gets the element matches against this pattern. */
PatternMatch getMatch() { result = tlpd.getMatch() }
PatternMatch getMatch() { result = lvpd.getMatch() }

/** Gets the underlying local variable declaration. */
LocalVariableDeclExpr getDeclaration() { result = tlpd }

override Expr getSource() { result = this.getMatch().getExpr() }
LocalVariableDeclExpr getDeclaration() { result = lvpd }

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

/**
* A local variable definition at the top level of a pattern.
*/
class TopLevelPatternDefinition extends PatternDefinition {
TopLevelPatternDefinition() { lvpd.isTopLevel() }

override Expr getSource() { result = this.getMatch().getExpr() }
}

/**
* An initializer definition for a field or a property, for example
* line 2 in
Expand Down
2 changes: 1 addition & 1 deletion csharp/ql/lib/semmle/code/csharp/dataflow/Nullness.qll
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private predicate nonNullDef(SsaExplicitWrite def) {
def.getValue() instanceof NonNullExpr
or
exists(AssignableDefinition ad | ad = def.getDefinition() |
ad instanceof AssignableDefinitions::PatternDefinition
ad instanceof AssignableDefinitions::TopLevelPatternDefinition
or
ad =
any(AssignableDefinitions::LocalVariableDefinition d |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ module LocalFlow {
or
exists(AssignExpr ae | ae.getLeftOperand().(TupleExpr) = e2 and ae.getRightOperand() = e1)
or
exists(ControlFlowElement cfe | cfe = e2.(TupleExpr).(PatternExpr).getPatternMatch() |
exists(ControlFlowElement cfe | cfe = e2.(TuplePatternExpr).getPatternMatch() |
cfe.(IsExpr).getExpr() = e1
or
exists(Switch sw | sw.getACase() = cfe and sw.getExpr() = e1)
Expand Down Expand Up @@ -2242,8 +2242,8 @@ private predicate readContentStep(Node node1, Content c, Node node2) {
)
or
// item = variable in node1 = (..., variable, ...) in a case/is var (..., ...)
isPatternExprDescendant(te) and
exists(AssignableDefinitions::LocalVariableDefinition lvd |
te instanceof TuplePatternExpr and
exists(AssignableDefinitions::PatternDefinition lvd |
node2.(AssignableDefinitionNode).getDefinition() = lvd and
lvd.getDeclaration() = item
)
Expand Down Expand Up @@ -2677,7 +2677,7 @@ class CastNode extends Node {
this.asExpr() instanceof Cast
or
this.(AssignableDefinitionNode).getDefinition() instanceof
AssignableDefinitions::PatternDefinition
AssignableDefinitions::TopLevelPatternDefinition
}
}

Expand Down
7 changes: 7 additions & 0 deletions csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,13 @@ class PositionalPatternExpr extends PatternExpr, @positional_pattern_expr {
override string getAPrimaryQlClass() { result = "PositionalPatternExpr" }
}

/**
* A tuple pattern. For example, `var (x, y)`.
*/
class TuplePatternExpr extends TupleExpr, PatternExpr {
override string getAPrimaryQlClass() { result = "TuplePatternExpr" }
}

/** A list pattern. For example `[1, 2, int y]` in `x is [1, 2, int y]`. */
class ListPatternExpr extends PatternExpr, @list_pattern_expr {
override string toString() { result = "[ ... ]" }
Expand Down
2 changes: 1 addition & 1 deletion csharp/ql/src/Dead Code/DeadStoreOfLocal.ql
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class RelevantDefinition extends AssignableDefinition {
not lvde.getName() = "_"
)
or
this instanceof AssignableDefinitions::PatternDefinition
this instanceof AssignableDefinitions::TopLevelPatternDefinition
or
this instanceof AssignableDefinitions::AssignOperationDefinition
}
Expand Down
4 changes: 2 additions & 2 deletions csharp/ql/test/library-tests/csharp8/PrintAst.expected
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,7 @@ patterns.cs:
# 57| 1: [ConstantPatternExpr,IntLiteral] 2
# 58| 10: [BreakStmt] break;
# 59| 11: [CaseStmt] case ...:
# 59| 0: [TupleExpr] (..., ...)
# 59| 0: [TuplePatternExpr] (..., ...)
# 59| 0: [VariablePatternExpr] Int32 x
# 59| 1: [VariablePatternExpr] Int32 y
# 60| 12: [BreakStmt] break;
Expand Down Expand Up @@ -1156,7 +1156,7 @@ patterns.cs:
# 130| 1: [ConstantPatternExpr,IntLiteral] 2
# 130| 2: [IntLiteral] 2
# 131| 3: [SwitchCaseExpr] ... => ...
# 131| 0: [TupleExpr] (..., ...)
# 131| 0: [TuplePatternExpr] (..., ...)
# 131| 0: [VariablePatternExpr] Int32 x
# 131| 1: [DiscardPatternExpr] _
# 131| 2: [IntLiteral] 3
Expand Down
12 changes: 6 additions & 6 deletions csharp/ql/test/library-tests/dataflow/tuples/PrintAst.expected
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,9 @@ Tuples.cs:
# 65| -1: [LocalVariableAccess] access to local variable t
# 66| 4: [BreakStmt] break;
# 67| 5: [CaseStmt] case ...:
# 67| 0: [TupleExpr] (..., ...)
# 67| 0: [TuplePatternExpr] (..., ...)
# 67| 0: [VariablePatternExpr] String a
# 67| 1: [TupleExpr] (..., ...)
# 67| 1: [TuplePatternExpr] (..., ...)
# 67| 0: [VariablePatternExpr] Int32 b
# 67| 1: [VariablePatternExpr] String c
# 67| 2: [DiscardPatternExpr] _
Expand Down Expand Up @@ -302,7 +302,7 @@ Tuples.cs:
# 78| 0: [RecursivePatternExpr] { ... }
# 78| 2: [PositionalPatternExpr] ( ... )
# 78| 0: [VariablePatternExpr] String a
# 78| 1: [TupleExpr] (..., ...)
# 78| 1: [TuplePatternExpr] (..., ...)
# 78| 0: [VariablePatternExpr] Int32 b
# 78| 1: [VariablePatternExpr] String c
# 78| 2: [DiscardPatternExpr] _
Expand Down Expand Up @@ -335,9 +335,9 @@ Tuples.cs:
# 87| 7: [IfStmt] if (...) ...
# 87| 0: [IsExpr] ... is ...
# 87| 0: [LocalVariableAccess] access to local variable x
# 87| 1: [TupleExpr] (..., ...)
# 87| 1: [TuplePatternExpr] (..., ...)
# 87| 0: [VariablePatternExpr] String p
# 87| 1: [TupleExpr] (..., ...)
# 87| 1: [TuplePatternExpr] (..., ...)
# 87| 0: [VariablePatternExpr] Int32 q
# 87| 1: [VariablePatternExpr] String r
# 87| 2: [DiscardPatternExpr] _
Expand Down Expand Up @@ -417,7 +417,7 @@ Tuples.cs:
# 107| 6: [SwitchStmt] switch (...) {...}
# 107| 0: [LocalVariableAccess] access to local variable r
# 109| 0: [CaseStmt] case ...:
# 109| 0: [TupleExpr] (..., ...)
# 109| 0: [TuplePatternExpr] (..., ...)
# 109| 0: [VariablePatternExpr] String x
# 109| 1: [VariablePatternExpr] Int32 y
# 110| 1: [ExprStmt] ...;
Expand Down
Loading