C#: Update the CFG implementation based on the new operations and remove hack that rotates children of assignments.

This commit is contained in:
Michael Nebel
2026-03-20 12:50:30 +01:00
parent 569e33b407
commit 149df86ce2

View File

@@ -62,18 +62,13 @@ class CfgScope extends Element, @top_level_exprorstmt_parent {
private class TAstNode = @callable or @control_flow_element;
private Element getAChild(Element p) {
result = p.getAChild() or
result = p.(AssignOperation).getExpandedAssignment()
}
pragma[nomagic]
private predicate astNode(Element e) {
e = any(@top_level_exprorstmt_parent p | not p instanceof Attribute)
or
exists(Element parent |
astNode(parent) and
e = getAChild(parent)
e = parent.getAChild()
)
}
@@ -447,7 +442,6 @@ module Expressions {
private AstNode getExprChild0(Expr e, int i) {
not e instanceof NameOfExpr and
not e instanceof QualifiableExpr and
not e instanceof Assignment and
not e instanceof AnonymousFunctionExpr and
result = e.getChild(i)
or
@@ -458,14 +452,6 @@ module Expressions {
not qe instanceof ExtensionMethodCall and
result = qe.getChild(i)
)
or
e =
any(Assignment a |
// The left-hand side of an assignment is evaluated before the right-hand side
i = 0 and result = a.getLValue()
or
i = 1 and result = a.getRValue()
)
}
private AstNode getExprChild(Expr e, int i) {
@@ -491,9 +477,8 @@ module Expressions {
not this instanceof LogicalNotExpr and
not this instanceof LogicalAndExpr and
not this instanceof LogicalOrExpr and
not this instanceof NullCoalescingExpr and
not this instanceof NullCoalescingOperation and
not this instanceof ConditionalExpr and
not this instanceof AssignOperationWithExpandedAssignment and
not this instanceof ConditionallyQualifiedExpr and
not this instanceof ThrowExpr and
not this instanceof ObjectCreation and
@@ -590,8 +575,7 @@ module Expressions {
QualifiedAccessorWrite() {
def.getExpr() = this and
def.getTargetAccess().(WriteAccess) instanceof QualifiableExpr and
not def instanceof AssignableDefinitions::OutRefDefinition and
not this instanceof AssignOperationWithExpandedAssignment
not def instanceof AssignableDefinitions::OutRefDefinition
}
/**
@@ -723,7 +707,8 @@ module Expressions {
}
}
private class NullCoalescingExprTree extends PostOrderTree instanceof NullCoalescingExpr {
private class NullCoalescingOperationTree extends PostOrderTree instanceof NullCoalescingOperation
{
final override predicate propagatesAbnormal(AstNode child) {
child in [super.getLeftOperand(), super.getRightOperand()]
}
@@ -774,26 +759,6 @@ module Expressions {
}
}
/**
* An assignment operation that has an expanded version. We use the expanded
* version in the control flow graph in order to get better data flow / taint
* tracking.
*/
private class AssignOperationWithExpandedAssignment extends ControlFlowTree instanceof AssignOperation
{
private Expr expanded;
AssignOperationWithExpandedAssignment() { expanded = this.getExpandedAssignment() }
final override predicate first(AstNode first) { first(expanded, first) }
final override predicate last(AstNode last, Completion c) { last(expanded, last, c) }
final override predicate propagatesAbnormal(AstNode child) { none() }
final override predicate succ(AstNode pred, AstNode succ, Completion c) { none() }
}
/** A conditionally qualified expression. */
private class ConditionallyQualifiedExpr extends PostOrderTree instanceof QualifiableExpr {
private Expr qualifier;
@@ -1551,7 +1516,7 @@ module Statements {
/** Gets a child of `cfe` that is in CFG scope `scope`. */
pragma[noinline]
private ControlFlowElement getAChildInScope(AstNode cfe, Callable scope) {
result = getAChild(cfe) and
result = cfe.getAChild() and
scope = result.getEnclosingCallable()
}