From c42b274a29c713029f987aaad4b36887fb290f5f Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 7 May 2026 15:57:02 +0200 Subject: [PATCH 1/2] CFG: Consider logical not a post order operation. --- .../codeql/controlflow/ControlFlowGraph.qll | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll index 514a68cba474..d8248e2de331 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll @@ -519,13 +519,14 @@ module Make0 Ast> { or n instanceof GotoStmt or + n instanceof LogicalNotExpr + or n instanceof Expr and exists(getChild(n, _)) and not Input1::preOrderExpr(n) and not n instanceof LogicalAndExpr and not n instanceof LogicalOrExpr and not n instanceof NullCoalescingExpr and - not n instanceof LogicalNotExpr and not n instanceof ConditionalExpr and not n instanceof Switch and not n instanceof Case @@ -1454,8 +1455,13 @@ module Make0 Ast> { n1.isBefore(notexpr) and n2.isBefore(notexpr.getOperand()) or - exists(BooleanSuccessor t | - n1.isAfterValue(notexpr.getOperand(), t) and + exists(BooleanSuccessor t, PreControlFlowNode operand | + operand.isAfterValue(notexpr.getOperand(), t) + | + n1 = operand and + n2.isIn(notexpr) + or + n1.isIn(notexpr) and n2.isAfterValue(notexpr, t.getDual()) ) ) From 40a2148deb50236ef362e8799b83e6ac99dcc829 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 8 May 2026 11:14:32 +0200 Subject: [PATCH 2/2] C#: Introduce additional nodes to carry the boolean successor state. --- .../codeql/controlflow/ControlFlowGraph.qll | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll index d8248e2de331..b7eda481103f 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll @@ -634,6 +634,10 @@ module Make0 Ast> { private string patternMatchTrueTag() { result = "[MatchTrue]" } + private string logicalNotTag(Boolean value) { + if value = true then result = "[LogicalNotTrue]" else result = "[LogicalNotFalse]" + } + /** * Holds if an additional node tagged with `tag` should be created for * `n`. Edges targeting such nodes are labeled with `t` and therefore `t` @@ -649,6 +653,12 @@ module Make0 Ast> { n instanceof PatternMatchExpr and tag = patternMatchTrueTag() and t.(BooleanSuccessor).getValue() = true + or + n instanceof LogicalNotExpr and + exists(Boolean b | + tag = logicalNotTag(b) and + t.(BooleanSuccessor).getValue() = b + ) } /** @@ -1455,13 +1465,11 @@ module Make0 Ast> { n1.isBefore(notexpr) and n2.isBefore(notexpr.getOperand()) or - exists(BooleanSuccessor t, PreControlFlowNode operand | - operand.isAfterValue(notexpr.getOperand(), t) - | - n1 = operand and - n2.isIn(notexpr) + exists(BooleanSuccessor t | + n1.isAfterValue(notexpr.getOperand(), t) and + n2.isAdditional(notexpr, logicalNotTag(t.getValue())) or - n1.isIn(notexpr) and + n1.isAdditional(notexpr, logicalNotTag(t.getValue())) and n2.isAfterValue(notexpr, t.getDual()) ) )