Skip to content

C#: Include all binding expr in data flow analysis. #7893

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
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
18 changes: 9 additions & 9 deletions csharp/ql/lib/semmle/code/csharp/Assignable.qll
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,11 @@ module AssignableInternal {
def = TPatternDefinition(result)
}

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

TopLevelPatternDecl() { this = pm.getPattern().(BindingPatternExpr).getVariableDeclExpr() }
AnyLevelPatternDecl() { this = pm.getAPattern().(BindingPatternExpr).getVariableDeclExpr() }

PatternMatch getMatch() { result = pm }
}
Expand All @@ -305,7 +305,7 @@ module AssignableInternal {
TLocalVariableDefinition(LocalVariableDeclExpr lvde) {
not lvde.hasInitializer() and
not exists(getTupleSource(TTupleAssignmentDefinition(_, lvde))) and
not lvde instanceof TopLevelPatternDecl and
not lvde instanceof AnyLevelPatternDecl and
not lvde.isOutArgument()
} or
TImplicitParameterDefinition(Parameter p) {
Expand All @@ -317,7 +317,7 @@ module AssignableInternal {
)
} or
TAddressOfDefinition(AddressOfExpr aoe) or
TPatternDefinition(TopLevelPatternDecl tlpd)
TPatternDefinition(AnyLevelPatternDecl tlpd)

/**
* Gets the source expression assigned in tuple definition `def`, if any.
Expand Down Expand Up @@ -707,15 +707,15 @@ module AssignableDefinitions {
* A local variable definition in a pattern, for example `x is int i`.
*/
class PatternDefinition extends AssignableDefinition, TPatternDefinition {
TopLevelPatternDecl tlpd;
AnyLevelPatternDecl alpd;

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

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

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

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

Expand Down
4 changes: 4 additions & 0 deletions csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll
Original file line number Diff line number Diff line change
Expand Up @@ -554,10 +554,14 @@ class PatternMatch extends ControlFlowElement, @pattern_match {
/** Gets the pattern of this match. */
PatternExpr getPattern() { none() }

PatternExpr getAPattern() { hasChildPattern(this, result) }

/** Gets the expression that is matched against a pattern. */
Expr getExpr() { none() }
}

private predicate myTest(PatternMatch pm, PatternExpr child) { child = pm.getAPattern() }

/** An `is` expression. */
class IsExpr extends Expr, PatternMatch, @is_expr {
/** Gets the expression being checked, for example `x` in `x is string`. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ private void M1()
var r = new RecordClass2(o);
if (r is RecordClass2 { Prop: object p })
{
Sink(p); // $ MISSING: hasValueFlow=1
Sink(p); // $ hasValueFlow=1
}
}

Expand Down