Skip to content

Commit b8d49ab

Browse files
committed
C#: Remove splitting-awareness for local expression steps.
1 parent 8a29e5c commit b8d49ab

File tree

2 files changed

+67
-114
lines changed

2 files changed

+67
-114
lines changed

csharp/ql/consistency-queries/DataFlowConsistency.ql

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ private module Input implements InputSig<Location, CsharpDataFlow> {
3535
or
3636
n.asExpr().(ObjectCreation).hasInitializer()
3737
or
38-
exists(
39-
n.(PostUpdateNode).getPreUpdateNode().asExprAtNode(LocalFlow::getPostUpdateReverseStep(_))
40-
)
38+
n.(PostUpdateNode).getPreUpdateNode().asExpr() = LocalFlow::getPostUpdateReverseStep(_)
4139
}
4240

4341
predicate argHasPostUpdateExclude(ArgumentNode n) {

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

Lines changed: 66 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ module VariableCapture {
283283
private import semmle.code.csharp.controlflow.BasicBlocks as BasicBlocks
284284

285285
private predicate closureFlowStep(ControlFlow::Nodes::ExprNode e1, ControlFlow::Nodes::ExprNode e2) {
286-
e1 = LocalFlow::getALastEvalNode(e2)
286+
e1.getExpr() = LocalFlow::getALastEvalNode(e2.getExpr())
287287
or
288288
exists(Ssa::Definition def, AssignableDefinition adef |
289289
LocalFlow::defAssigns(adef, _, _, e1) and
@@ -528,98 +528,58 @@ module SsaFlow {
528528

529529
/** Provides predicates related to local data flow. */
530530
module LocalFlow {
531-
class LocalExprStepConfiguration extends ControlFlowReachabilityConfiguration {
532-
LocalExprStepConfiguration() { this = "LocalExprStepConfiguration" }
533-
534-
override predicate candidate(
535-
Expr e1, Expr e2, ControlFlowElement scope, boolean exactScope, boolean isSuccessor
536-
) {
537-
exactScope = false and
538-
(
539-
e1 = e2.(ParenthesizedExpr).getExpr() and
540-
scope = e2 and
541-
isSuccessor = true
542-
or
543-
e1 = e2.(NullCoalescingExpr).getAnOperand() and
544-
scope = e2 and
545-
isSuccessor = true
546-
or
547-
e1 = e2.(SuppressNullableWarningExpr).getExpr() and
548-
scope = e2 and
549-
isSuccessor = true
550-
or
551-
e2 =
552-
any(ConditionalExpr ce |
553-
e1 = ce.getThen() or
554-
e1 = ce.getElse()
555-
) and
556-
scope = e2 and
557-
isSuccessor = true
558-
or
559-
e1 = e2.(Cast).getExpr() and
560-
scope = e2 and
561-
isSuccessor = true
562-
or
563-
// An `=` expression, where the result of the expression is used
564-
e2 =
565-
any(AssignExpr ae |
566-
ae.getParent() = any(ControlFlowElement cfe | not cfe instanceof ExprStmt) and
567-
e1 = ae.getRValue()
568-
) and
569-
scope = e2 and
570-
isSuccessor = true
571-
or
572-
e1 = e2.(ObjectCreation).getInitializer() and
573-
scope = e2 and
574-
isSuccessor = false
575-
or
576-
e1 = e2.(ArrayCreation).getInitializer() and
577-
scope = e2 and
578-
isSuccessor = false
579-
or
580-
e1 = e2.(SwitchExpr).getACase().getBody() and
581-
scope = e2 and
582-
isSuccessor = true
583-
or
584-
e1 = e2.(CheckedExpr).getExpr() and
585-
scope = e2 and
586-
isSuccessor = true
587-
or
588-
e1 = e2.(UncheckedExpr).getExpr() and
589-
scope = e2 and
590-
isSuccessor = true
591-
or
592-
e1 = e2.(CollectionExpression).getAnElement() and
593-
e1 instanceof SpreadElementExpr and
594-
scope = e2 and
595-
isSuccessor = true
596-
or
597-
e1 = e2.(SpreadElementExpr).getExpr() and
598-
scope = e2 and
599-
isSuccessor = true
600-
or
601-
exists(WithExpr we |
602-
scope = we and
603-
isSuccessor = true
604-
|
605-
e1 = we.getExpr() and
606-
e2 = we.getInitializer()
607-
or
608-
e1 = we.getInitializer() and
609-
e2 = we
610-
)
611-
or
612-
scope = any(AssignExpr ae | ae.getLValue().(TupleExpr) = e2 and ae.getRValue() = e1) and
613-
isSuccessor = false
614-
or
615-
isSuccessor = true and
616-
exists(ControlFlowElement cfe | cfe = e2.(TupleExpr).(PatternExpr).getPatternMatch() |
617-
cfe.(IsExpr).getExpr() = e1 and scope = cfe
618-
or
619-
exists(Switch sw | sw.getACase() = cfe and sw.getExpr() = e1 and scope = sw)
620-
)
531+
predicate localExprStep(Expr e1, Expr e2) {
532+
e1 = e2.(ParenthesizedExpr).getExpr()
533+
or
534+
e1 = e2.(NullCoalescingExpr).getAnOperand()
535+
or
536+
e1 = e2.(SuppressNullableWarningExpr).getExpr()
537+
or
538+
e2 =
539+
any(ConditionalExpr ce |
540+
e1 = ce.getThen() or
541+
e1 = ce.getElse()
621542
)
622-
}
543+
or
544+
e1 = e2.(Cast).getExpr()
545+
or
546+
// An `=` expression, where the result of the expression is used
547+
e2 =
548+
any(AssignExpr ae |
549+
ae.getParent() = any(ControlFlowElement cfe | not cfe instanceof ExprStmt) and
550+
e1 = ae.getRValue()
551+
)
552+
or
553+
e1 = e2.(ObjectCreation).getInitializer()
554+
or
555+
e1 = e2.(ArrayCreation).getInitializer()
556+
or
557+
e1 = e2.(SwitchExpr).getACase().getBody()
558+
or
559+
e1 = e2.(CheckedExpr).getExpr()
560+
or
561+
e1 = e2.(UncheckedExpr).getExpr()
562+
or
563+
e1 = e2.(CollectionExpression).getAnElement() and
564+
e1 instanceof SpreadElementExpr
565+
or
566+
e1 = e2.(SpreadElementExpr).getExpr()
567+
or
568+
exists(WithExpr we |
569+
e1 = we.getExpr() and
570+
e2 = we.getInitializer()
571+
or
572+
e1 = we.getInitializer() and
573+
e2 = we
574+
)
575+
or
576+
exists(AssignExpr ae | ae.getLValue().(TupleExpr) = e2 and ae.getRValue() = e1)
577+
or
578+
exists(ControlFlowElement cfe | cfe = e2.(TupleExpr).(PatternExpr).getPatternMatch() |
579+
cfe.(IsExpr).getExpr() = e1
580+
or
581+
exists(Switch sw | sw.getACase() = cfe and sw.getExpr() = e1)
582+
)
623583
}
624584

625585
predicate defAssigns(
@@ -646,7 +606,7 @@ module LocalFlow {
646606
}
647607

648608
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
649-
hasNodePath(any(LocalExprStepConfiguration x), nodeFrom, nodeTo)
609+
localExprStep(nodeFrom.asExpr(), nodeTo.asExpr())
650610
or
651611
defAssigns(nodeFrom, nodeTo)
652612
or
@@ -674,11 +634,12 @@ module LocalFlow {
674634
}
675635

676636
/**
677-
* Gets a node that may execute last in `n`, and which, when it executes last,
678-
* will be the value of `n`.
637+
* Gets a node that may execute last in `e`, and which, when it executes last,
638+
* will be the value of `e`.
679639
*/
680-
ControlFlow::Nodes::ExprNode getALastEvalNode(ControlFlow::Nodes::ExprNode cfn) {
681-
exists(Expr e | any(LocalExprStepConfiguration x).hasExprPath(_, result, e, cfn) |
640+
Expr getALastEvalNode(Expr e) {
641+
localExprStep(result, e) and
642+
(
682643
e instanceof ConditionalExpr or
683644
e instanceof Cast or
684645
e instanceof NullCoalescingExpr or
@@ -702,9 +663,7 @@ module LocalFlow {
702663
* we add a reverse flow step from `[post] b ? x : y` to `[post] x` and to
703664
* `[post] y`, in order for the side-effect of `m` to reach both `x` and `y`.
704665
*/
705-
ControlFlow::Nodes::ExprNode getPostUpdateReverseStep(ControlFlow::Nodes::ExprNode e) {
706-
result = getALastEvalNode(e)
707-
}
666+
Expr getPostUpdateReverseStep(Expr e) { result = getALastEvalNode(e) }
708667

709668
/**
710669
* Holds if the value of `node2` is given by `node1`.
@@ -720,7 +679,7 @@ module LocalFlow {
720679
or
721680
defAssigns(node1, node2)
722681
or
723-
hasNodePath(any(LocalExprStepConfiguration x), node1, node2) and
682+
localExprStep(node1.asExpr(), node2.asExpr()) and
724683
(
725684
node2.asExpr() instanceof Cast or
726685
node2.asExpr() instanceof AssignExpr
@@ -765,12 +724,8 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
765724
or
766725
nodeTo = nodeFrom.(LocalFunctionCreationNode).getAnAccess(true)
767726
or
768-
nodeTo.(PostUpdateNode).getPreUpdateNode().(ExprNode).getControlFlowNode() =
769-
LocalFlow::getPostUpdateReverseStep(nodeFrom
770-
.(PostUpdateNode)
771-
.getPreUpdateNode()
772-
.(ExprNode)
773-
.getControlFlowNode())
727+
nodeTo.(PostUpdateNode).getPreUpdateNode().asExpr() =
728+
LocalFlow::getPostUpdateReverseStep(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExpr())
774729
) and
775730
model = ""
776731
or
@@ -1119,10 +1074,10 @@ private module Cached {
11191074
(
11201075
cfn.getExpr() instanceof Argument
11211076
or
1122-
cfn =
1123-
LocalFlow::getPostUpdateReverseStep(any(ControlFlow::Nodes::ExprNode e |
1124-
exists(any(SourcePostUpdateNode p).getPreUpdateNode().asExprAtNode(e))
1125-
))
1077+
cfn.getExpr() =
1078+
LocalFlow::getPostUpdateReverseStep(any(SourcePostUpdateNode p)
1079+
.getPreUpdateNode()
1080+
.asExpr())
11261081
) and
11271082
exprMayHavePostUpdateNode(cfn.getExpr())
11281083
or

0 commit comments

Comments
 (0)