From f55ace83113b4647a353f8567870afe6bde3ffb8 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:05:38 +0100 Subject: [PATCH 01/35] C++: Make the return type a bit more precise. --- cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll index d48a48dfb445..80b1d550627f 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll @@ -498,7 +498,9 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse { int getArgumentIndex() { result = p.getIndex() } - override Node getNode() { finalParameterNodeHasParameterAndIndex(result, p, indirectionIndex) } + override FinalParameterNode getNode() { + finalParameterNodeHasParameterAndIndex(result, p, indirectionIndex) + } override int getIndirection() { result = indirectionIndex + 1 } From f47dd2bbc68602ddf43af9c79e988b74778717fc Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:06:22 +0100 Subject: [PATCH 02/35] C++: Add a 'hasInputFromBlock' predicate. --- .../semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll index 80b1d550627f..3b6f21d594c8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll @@ -1126,7 +1126,15 @@ predicate ssaFlow(Node nodeFrom, Node nodeTo) { */ class PhiNode extends Definition instanceof SsaImpl::PhiNode { /** Gets a definition that is an input to this phi node. */ - final Definition getAnInput() { phiHasInputFromBlock(this, result, _) } + final Definition getAnInput() { this.hasInputFromBlock(result, _) } + + /** + * Holds if `input` is an input to this phi node along the edge originating + * in `bb`. + */ + final predicate hasInputFromBlock(Definition input, IRBlock bb) { + phiHasInputFromBlock(this, input, bb) + } } /** An static single assignment (SSA) definition. */ From be8195ab7dc810e4a59e149fd16d4fd12d7f44a5 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:08:45 +0100 Subject: [PATCH 03/35] C++: Do not rely on dataflow nodes when implement 'getAUse' and 'getAnIndirectUse'. This will solve a non-monotonic recursion issue later. --- cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll index 3b6f21d594c8..002e0ca61bc9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll @@ -1159,7 +1159,7 @@ class Definition extends SsaImpl::Definition { exists(SourceVariable sv, IRBlock bb, int i, UseImpl use | ssaDefReachesRead(sv, this, bb, i) and use.hasIndexInBlock(bb, i, sv) and - result = use.getNode().asOperand() + use = TDirectUseImpl(result, 0) ) } @@ -1177,10 +1177,11 @@ class Definition extends SsaImpl::Definition { * value that was defined by the definition. */ Operand getAnIndirectUse(int indirectionIndex) { + indirectionIndex > 0 and exists(SourceVariable sv, IRBlock bb, int i, UseImpl use | ssaDefReachesRead(sv, this, bb, i) and use.hasIndexInBlock(bb, i, sv) and - result = use.getNode().asIndirectOperand(indirectionIndex) + use = TDirectUseImpl(result, indirectionIndex) ) } From 19b8e0db9c4d2653a2cf4fc1d6580ba07b564952 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:09:31 +0100 Subject: [PATCH 04/35] C++: Add a few subclasses to 'EdgeKind'. --- .../code/cpp/ir/implementation/EdgeKind.qll | 63 ++++++++++++------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/EdgeKind.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/EdgeKind.qll index c7ab5edf6249..b449b21c3e47 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/EdgeKind.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/EdgeKind.qll @@ -52,11 +52,18 @@ class GotoEdge extends EdgeKindImpl, TGotoEdge { final override string toString() { result = "Goto" } } +/** + * A "true" or "false" edge representing a successor of a conditional branch. + */ +abstract private class BooleanEdgeKindImpl extends EdgeKindImpl { } + +final class BooleanEdge = BooleanEdgeKindImpl; + /** * A "true" edge, representing the successor of a conditional branch when the * condition is non-zero. */ -class TrueEdge extends EdgeKindImpl, TTrueEdge { +class TrueEdge extends BooleanEdgeKindImpl, TTrueEdge { final override string toString() { result = "True" } } @@ -64,7 +71,7 @@ class TrueEdge extends EdgeKindImpl, TTrueEdge { * A "false" edge, representing the successor of a conditional branch when the * condition is zero. */ -class FalseEdge extends EdgeKindImpl, TFalseEdge { +class FalseEdge extends BooleanEdgeKindImpl, TFalseEdge { final override string toString() { result = "False" } } @@ -95,19 +102,48 @@ class SehExceptionEdge extends ExceptionEdgeImpl, TSehExceptionEdge { final override string toString() { result = "SEH Exception" } } +/** + * An edge from a `Switch` instruction to one of the cases, or to the default + * branch. + */ +abstract private class SwitchEdgeKindImpl extends EdgeKindImpl { + /** + * Gets the smallest value of the switch expression for which control will flow along this edge. + */ + string getMinValue() { none() } + + /** + * Gets the largest value of the switch expression for which control will flow along this edge. + */ + string getMaxValue() { none() } + + /** + * Gets the unique value of the switch expression for which control will + * flow along this edge, if any. + */ + final string getValue() { result = unique( | | [this.getMinValue(), this.getMaxValue()]) } + + /** Holds if this edge is the default edge. */ + predicate isDefault() { none() } +} + +final class SwitchEdge = SwitchEdgeKindImpl; + /** * A "default" edge, representing the successor of a `Switch` instruction when * none of the case values matches the condition value. */ -class DefaultEdge extends EdgeKindImpl, TDefaultEdge { +class DefaultEdge extends SwitchEdgeKindImpl, TDefaultEdge { final override string toString() { result = "Default" } + + final override predicate isDefault() { any() } } /** * A "case" edge, representing the successor of a `Switch` instruction when the * the condition value matches a corresponding `case` label. */ -class CaseEdge extends EdgeKindImpl, TCaseEdge { +class CaseEdge extends SwitchEdgeKindImpl, TCaseEdge { string minValue; string maxValue; @@ -119,24 +155,9 @@ class CaseEdge extends EdgeKindImpl, TCaseEdge { else result = "Case[" + minValue + ".." + maxValue + "]" } - /** - * Gets the smallest value of the switch expression for which control will flow along this edge. - */ - final string getMinValue() { result = minValue } + final override string getMinValue() { result = minValue } - /** - * Gets the largest value of the switch expression for which control will flow along this edge. - */ - final string getMaxValue() { result = maxValue } - - /** - * Gets the unique value of the switch expression for which control will - * flow along this edge, if any. - */ - final string getValue() { - minValue = maxValue and - result = minValue - } + final override string getMaxValue() { result = maxValue } } /** From 70a8364a38f5b84f9a38a7ed21a234cb2409d15b Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:10:39 +0100 Subject: [PATCH 05/35] C++: Add another convenience predicate on 'BinaryInstruction'. --- .../code/cpp/ir/implementation/aliased_ssa/Instruction.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index a564508e16b4..8d3e960c3f87 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -1084,6 +1084,12 @@ class BinaryInstruction extends Instruction { or op1 = this.getRightOperand() and op2 = this.getLeftOperand() } + + /** + * Gets the instruction whose result provides the value of the left or right + * operand of this binary instruction. + */ + Instruction getAnInput() { result = this.getLeft() or result = this.getRight() } } /** From f0f4311b6560b9d3fa23b4bed5659029ea0e8ba8 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:10:59 +0100 Subject: [PATCH 06/35] C++: Sync identical files. --- .../semmle/code/cpp/ir/implementation/raw/Instruction.qll | 6 ++++++ .../cpp/ir/implementation/unaliased_ssa/Instruction.qll | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll index a564508e16b4..8d3e960c3f87 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -1084,6 +1084,12 @@ class BinaryInstruction extends Instruction { or op1 = this.getRightOperand() and op2 = this.getLeftOperand() } + + /** + * Gets the instruction whose result provides the value of the left or right + * operand of this binary instruction. + */ + Instruction getAnInput() { result = this.getLeft() or result = this.getRight() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index a564508e16b4..8d3e960c3f87 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -1084,6 +1084,12 @@ class BinaryInstruction extends Instruction { or op1 = this.getRightOperand() and op2 = this.getLeftOperand() } + + /** + * Gets the instruction whose result provides the value of the left or right + * operand of this binary instruction. + */ + Instruction getAnInput() { result = this.getLeft() or result = this.getRight() } } /** From 2b0b8402ce4e29ee75b16c4078d0be908043fb48 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 18 Sep 2025 10:01:55 +0100 Subject: [PATCH 07/35] C++: Delete a bunch of predicates. Also set up things so that they work after instantiating the shared guards library. --- .../semmle/code/cpp/controlflow/IRGuards.qll | 425 +++++------------- 1 file changed, 119 insertions(+), 306 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index f782a2c117d5..7e53c83494bb 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -21,70 +21,61 @@ private predicate isUnreachedBlock(IRBlock block) { block.getFirstInstruction() instanceof UnreachedInstruction } -private newtype TAbstractValue = - TBooleanValue(boolean b) { b = true or b = false } or - TMatchValue(CaseEdge c) - /** + * DEPRECATED: Use `GuardValue` instead. + * * An abstract value. This is either a boolean value, or a `switch` case. */ -abstract class AbstractValue extends TAbstractValue { - /** Gets an abstract value that represents the dual of this value, if any. */ - abstract AbstractValue getDualValue(); +deprecated class AbstractValue extends GuardValue { } - /** Gets a textual representation of this abstract value. */ - abstract string toString(); -} +/** + * DEPRECATED: Use `GuardValue` instead. + * + * A Boolean value. + */ +deprecated class BooleanValue extends AbstractValue { + BooleanValue() { exists(this.asBooleanValue()) } -/** A Boolean value. */ -class BooleanValue extends AbstractValue, TBooleanValue { /** Gets the underlying Boolean value. */ - boolean getValue() { this = TBooleanValue(result) } - - override BooleanValue getDualValue() { result.getValue() = this.getValue().booleanNot() } - - override string toString() { result = this.getValue().toString() } + boolean getValue() { result = this.asBooleanValue() } } -/** A value that represents a match against a specific `switch` case. */ -class MatchValue extends AbstractValue, TMatchValue { - /** Gets the case. */ - CaseEdge getCase() { this = TMatchValue(result) } - - override MatchValue getDualValue() { - // A `MatchValue` has no dual. - none() +/** + * DEPRECATED: Use `GuardValue` instead. + * + * A value that represents a match against a specific `switch` case. + */ +deprecated class MatchValue extends AbstractValue { + MatchValue() { + exists(this.asIntValue()) + or + this.asConstantValue().isRange(_, _) } - override string toString() { result = this.getCase().toString() } + /** Gets the case. */ + CaseEdge getCase() { + result.getValue().toInt() = this.asIntValue() + or + exists(string minValue, string maxValue | + result.getMinValue() = minValue and + result.getMaxValue() = maxValue and + this.asConstantValue().isRange(minValue, maxValue) + ) + } } /** * A Boolean condition in the AST that guards one or more basic blocks. This includes * operands of logical operators but not switch statements. */ -abstract private class GuardConditionImpl extends Expr { +private class GuardConditionImpl extends Element { /** * Holds if this condition controls `controlled`, meaning that `controlled` is only * entered if the value of this condition is `v`. * * For details on what "controls" mean, see the QLDoc for `controls`. */ - abstract predicate valueControls(BasicBlock controlled, AbstractValue v); - - /** - * Holds if the control-flow edge `(pred, succ)` may be taken only if - * the value of this condition is `v`. - */ - abstract predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, AbstractValue v); - - /** - * Holds if the control-flow edge `(pred, succ)` may be taken only if - * this the value of this condition is `testIsTrue`. - */ - final predicate controlsEdge(BasicBlock pred, BasicBlock succ, boolean testIsTrue) { - this.valueControlsEdge(pred, succ, any(BooleanValue bv | bv.getValue() = testIsTrue)) - } + abstract predicate valueControls(BasicBlock controlled, GuardValue v); /** * Holds if this condition controls `controlled`, meaning that `controlled` is only @@ -113,7 +104,21 @@ abstract private class GuardConditionImpl extends Expr { * true (for `&&`) or false (for `||`) branch. */ final predicate controls(BasicBlock controlled, boolean testIsTrue) { - this.valueControls(controlled, any(BooleanValue bv | bv.getValue() = testIsTrue)) + this.valueControls(controlled, any(GuardValue bv | bv.asBooleanValue() = testIsTrue)) + } + + /** + * Holds if the control-flow edge `(pred, succ)` may be taken only if + * the value of this condition is `v`. + */ + abstract predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, GuardValue v); + + /** + * Holds if the control-flow edge `(pred, succ)` may be taken only if + * this the value of this condition is `testIsTrue`. + */ + final predicate controlsEdge(BasicBlock pred, BasicBlock succ, boolean testIsTrue) { + this.valueControlsEdge(pred, succ, any(GuardValue bv | bv.asBooleanValue() = testIsTrue)) } /** @@ -138,7 +143,7 @@ abstract private class GuardConditionImpl extends Expr { * ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`). */ pragma[inline] - abstract predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value); + abstract predicate comparesLt(Expr e, int k, boolean isLessThan, GuardValue value); /** * Holds if (determined by this guard) `e < k` must be `isLessThan` in `block`. @@ -180,7 +185,7 @@ abstract private class GuardConditionImpl extends Expr { * necessarily integer). */ pragma[inline] - abstract predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value); + abstract predicate comparesEq(Expr e, int k, boolean areEqual, GuardValue value); /** * Holds if (determined by this guard) `e == k` must be `areEqual` in `block`. @@ -210,7 +215,7 @@ abstract private class GuardConditionImpl extends Expr { */ pragma[inline] final predicate ensuresEqEdge(Expr e, int k, BasicBlock pred, BasicBlock succ, boolean areEqual) { - exists(AbstractValue v | + exists(GuardValue v | this.comparesEq(e, k, areEqual, v) and this.valueControlsEdge(pred, succ, v) ) @@ -236,7 +241,7 @@ abstract private class GuardConditionImpl extends Expr { */ pragma[inline] final predicate ensuresLtEdge(Expr e, int k, BasicBlock pred, BasicBlock succ, boolean isLessThan) { - exists(AbstractValue v | + exists(GuardValue v | this.comparesLt(e, k, isLessThan, v) and this.valueControlsEdge(pred, succ, v) ) @@ -248,28 +253,25 @@ final class GuardCondition = GuardConditionImpl; /** * A binary logical operator in the AST that guards one or more basic blocks. */ -private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl { - GuardConditionFromBinaryLogicalOperator() { - this.(BinaryLogicalOperation).getAnOperand() instanceof GuardCondition - } - - override predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, AbstractValue v) { +private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl instanceof BinaryLogicalOperation +{ + override predicate valueControls(BasicBlock controlled, GuardValue v) { exists(BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs | this = binop and lhs = binop.getLeftOperand() and rhs = binop.getRightOperand() and - lhs.valueControlsEdge(pred, succ, v) and - rhs.valueControlsEdge(pred, succ, v) + lhs.valueControls(controlled, v) and + rhs.valueControls(controlled, v) ) } - override predicate valueControls(BasicBlock controlled, AbstractValue v) { + override predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, GuardValue v) { exists(BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs | this = binop and lhs = binop.getLeftOperand() and rhs = binop.getRightOperand() and - lhs.valueControls(controlled, v) and - rhs.valueControls(controlled, v) + lhs.valueControlsEdge(pred, succ, v) and + rhs.valueControlsEdge(pred, succ, v) ) } @@ -281,10 +283,10 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl ) } - override predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value) { - exists(BooleanValue partValue, GuardCondition part | + override predicate comparesLt(Expr e, int k, boolean isLessThan, GuardValue value) { + exists(GuardValue partValue, GuardCondition part | this.(BinaryLogicalOperation) - .impliesValue(part, partValue.getValue(), value.(BooleanValue).getValue()) + .impliesValue(part, partValue.asBooleanValue(), value.asBooleanValue()) | part.comparesLt(e, k, isLessThan, partValue) ) @@ -299,7 +301,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl pragma[inline] override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) { - exists(AbstractValue value | + exists(GuardValue value | this.comparesLt(e, k, isLessThan, value) and this.valueControls(block, value) ) } @@ -319,10 +321,10 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl ) } - override predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value) { - exists(BooleanValue partValue, GuardCondition part | + override predicate comparesEq(Expr e, int k, boolean areEqual, GuardValue value) { + exists(GuardValue partValue, GuardCondition part | this.(BinaryLogicalOperation) - .impliesValue(part, partValue.getValue(), value.(BooleanValue).getValue()) + .impliesValue(part, partValue.asBooleanValue(), value.asBooleanValue()) | part.comparesEq(e, k, areEqual, partValue) ) @@ -330,7 +332,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl pragma[inline] override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) { - exists(AbstractValue value | + exists(GuardValue value | this.comparesEq(e, k, areEqual, value) and this.valueControls(block, value) ) } @@ -342,7 +344,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl * predicate does not necessarily hold for binary logical operations like * `&&` and `||`. See the detailed explanation on predicate `controls`. */ -private predicate controlsBlock(IRGuardCondition ir, BasicBlock controlled, AbstractValue v) { +private predicate controlsBlock(IRGuardCondition ir, BasicBlock controlled, GuardValue v) { exists(IRBlock irb | ir.valueControls(irb, v) and nonExcludedIRAndBasicBlock(irb, controlled) and @@ -357,11 +359,9 @@ private predicate controlsBlock(IRGuardCondition ir, BasicBlock controlled, Abst * like `&&` and `||`. * See the detailed explanation on predicate `controlsEdge`. */ -private predicate controlsEdge( - IRGuardCondition ir, BasicBlock pred, BasicBlock succ, AbstractValue v -) { +private predicate controlsEdge(IRGuardCondition ir, BasicBlock pred, BasicBlock succ, GuardValue v) { exists(IRBlock irPred, IRBlock irSucc | - ir.valueControlsEdge(irPred, irSucc, v) and + ir.valueControlsBranchEdge(irPred, irSucc, v) and nonExcludedIRAndBasicBlock(irPred, pred) and nonExcludedIRAndBasicBlock(irSucc, succ) and not isUnreachedBlock(irPred) and @@ -378,19 +378,20 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { // comparison against 0 so it's not included as a normal // `IRGuardCondition`. So to align with user expectations we make that `x` // a `GuardCondition`. - exists(NotExpr notExpr | - this = notExpr.getOperand() and + exists(NotExpr notExpr | this = notExpr.getOperand() | ir.getUnconvertedResultExpression() = notExpr + or + ir.(ConditionalBranchInstruction).getCondition().getUnconvertedResultExpression() = notExpr ) } - override predicate valueControls(BasicBlock controlled, AbstractValue v) { + override predicate valueControls(BasicBlock controlled, GuardValue v) { // This condition must determine the flow of control; that is, this // node must be a top-level condition. controlsBlock(ir, controlled, v.getDualValue()) } - override predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, AbstractValue v) { + override predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, GuardValue v) { controlsEdge(ir, pred, succ, v.getDualValue()) } @@ -404,7 +405,7 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { } pragma[inline] - override predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value) { + override predicate comparesLt(Expr e, int k, boolean isLessThan, GuardValue value) { exists(Instruction i | i.getUnconvertedResultExpression() = e and ir.comparesLt(i.getAUse(), k, isLessThan, value.getDualValue()) @@ -423,7 +424,7 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { pragma[inline] override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) { - exists(Instruction i, AbstractValue value | + exists(Instruction i, GuardValue value | i.getUnconvertedResultExpression() = e and ir.comparesLt(i.getAUse(), k, isLessThan, value.getDualValue()) and this.valueControls(block, value) @@ -450,7 +451,7 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { } pragma[inline] - override predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value) { + override predicate comparesEq(Expr e, int k, boolean areEqual, GuardValue value) { exists(Instruction i | i.getUnconvertedResultExpression() = e and ir.comparesEq(i.getAUse(), k, areEqual, value.getDualValue()) @@ -459,7 +460,7 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { pragma[inline] override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) { - exists(Instruction i, AbstractValue value | + exists(Instruction i, GuardValue value | i.getUnconvertedResultExpression() = e and ir.comparesEq(i.getAUse(), k, areEqual, value.getDualValue()) and this.valueControls(block, value) @@ -474,15 +475,21 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { private class GuardConditionFromIR extends GuardConditionImpl { IRGuardCondition ir; - GuardConditionFromIR() { this = ir.getUnconvertedResultExpression() } + GuardConditionFromIR() { + ir.(InitializeParameterInstruction).getParameter() = this + or + ir.(ConditionalBranchInstruction).getCondition().getUnconvertedResultExpression() = this + or + ir.getUnconvertedResultExpression() = this + } - override predicate valueControls(BasicBlock controlled, AbstractValue v) { + override predicate valueControls(BasicBlock controlled, GuardValue v) { // This condition must determine the flow of control; that is, this // node must be a top-level condition. controlsBlock(ir, controlled, v) } - override predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, AbstractValue v) { + override predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, GuardValue v) { controlsEdge(ir, pred, succ, v) } @@ -496,7 +503,7 @@ private class GuardConditionFromIR extends GuardConditionImpl { } pragma[inline] - override predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value) { + override predicate comparesLt(Expr e, int k, boolean isLessThan, GuardValue value) { exists(Instruction i | i.getUnconvertedResultExpression() = e and ir.comparesLt(i.getAUse(), k, isLessThan, value) @@ -515,7 +522,7 @@ private class GuardConditionFromIR extends GuardConditionImpl { pragma[inline] override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) { - exists(Instruction i, AbstractValue value | + exists(Instruction i, GuardValue value | i.getUnconvertedResultExpression() = e and ir.comparesLt(i.getAUse(), k, isLessThan, value) and this.valueControls(block, value) @@ -542,7 +549,7 @@ private class GuardConditionFromIR extends GuardConditionImpl { } pragma[inline] - override predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value) { + override predicate comparesEq(Expr e, int k, boolean areEqual, GuardValue value) { exists(Instruction i | i.getUnconvertedResultExpression() = e and ir.comparesEq(i.getAUse(), k, areEqual, value) @@ -551,7 +558,7 @@ private class GuardConditionFromIR extends GuardConditionImpl { pragma[inline] override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) { - exists(Instruction i, AbstractValue value | + exists(Instruction i, GuardValue value | i.getUnconvertedResultExpression() = e and ir.comparesEq(i.getAUse(), k, areEqual, value) and this.valueControls(block, value) @@ -584,20 +591,17 @@ pragma[nomagic] private predicate nonExcludedIRAndBasicBlock(IRBlock irb, BasicBlock controlled) { exists(Instruction instr | instr = irb.getAnInstruction() and - instr.getAst().(ControlFlowNode).getBasicBlock() = controlled and + instr.getAst() = controlled.getANode() and not excludeAsControlledInstruction(instr) ) } /** - * A Boolean condition in the IR that guards one or more basic blocks. - * - * Note that `&&` and `||` don't have an explicit representation in the IR, - * and therefore will not appear as IRGuardConditions. + * A guard. This may be any expression whose value determines subsequent + * control flow. It may also be a switch case, which as a guard is considered + * to evaluate to either true or false depending on whether the case matches. */ -class IRGuardCondition extends Instruction { - Instruction branch; - +final class IRGuardCondition extends Guards_v1::Guard { /* * An `IRGuardCondition` supports reasoning about four different kinds of * relations: @@ -625,119 +629,12 @@ class IRGuardCondition extends Instruction { * `e1 + k1 == e2 + k2` into canonical the form `e1 == e2 + (k2 - k1)`. */ - IRGuardCondition() { branch = getBranchForCondition(this) } - - /** - * Holds if this condition controls `controlled`, meaning that `controlled` is only - * entered if the value of this condition is `v`. - * - * For details on what "controls" mean, see the QLDoc for `controls`. - */ - predicate valueControls(IRBlock controlled, AbstractValue v) { - // This condition must determine the flow of control; that is, this - // node must be a top-level condition. - this.controlsBlock(controlled, v) - or - exists(IRGuardCondition ne | - this = ne.(LogicalNotInstruction).getUnary() and - ne.valueControls(controlled, v.getDualValue()) - ) - } - - /** - * Holds if this condition controls `controlled`, meaning that `controlled` is only - * entered if the value of this condition is `testIsTrue`. - * - * Illustration: - * - * ``` - * [ (testIsTrue) ] - * [ this ----------------succ ---- controlled ] - * [ | | ] - * [ (testIsFalse) | ------ ... ] - * [ other ] - * ``` - * - * The predicate holds if all paths to `controlled` go via the `testIsTrue` - * edge of the control-flow graph. In other words, the `testIsTrue` edge - * must dominate `controlled`. This means that `controlled` must be - * dominated by both `this` and `succ` (the target of the `testIsTrue` - * edge). It also means that any other edge into `succ` must be a back-edge - * from a node which is dominated by `succ`. - * - * The short-circuit boolean operations have slightly surprising behavior - * here: because the operation itself only dominates one branch (due to - * being short-circuited) then it will only control blocks dominated by the - * true (for `&&`) or false (for `||`) branch. - */ - predicate controls(IRBlock controlled, boolean testIsTrue) { - this.valueControls(controlled, any(BooleanValue bv | bv.getValue() = testIsTrue)) - } - - /** - * Holds if the control-flow edge `(pred, succ)` may be taken only if - * the value of this condition is `v`. - */ - predicate valueControlsEdge(IRBlock pred, IRBlock succ, AbstractValue v) { - pred.getASuccessor() = succ and - this.valueControls(pred, v) - or - succ = this.getBranchSuccessor(v) and - ( - branch.(ConditionalBranchInstruction).getCondition() = this and - branch.getBlock() = pred - or - branch.(SwitchInstruction).getExpression() = this and - branch.getBlock() = pred - ) - } - - /** - * Holds if the control-flow edge `(pred, succ)` may be taken only if - * the value of this condition is `testIsTrue`. - */ - final predicate controlsEdge(IRBlock pred, IRBlock succ, boolean testIsTrue) { - this.valueControlsEdge(pred, succ, any(BooleanValue bv | bv.getValue() = testIsTrue)) - } - - /** - * Gets the block to which `branch` jumps directly when the value of this condition is `v`. - * - * This predicate is intended to help with situations in which an inference can only be made - * based on an edge between a block with multiple successors and a block with multiple - * predecessors. For example, in the following situation, an inference can be made about the - * value of `x` at the end of the `if` statement, but there is no block which is controlled by - * the `if` statement when `x >= y`. - * ``` - * if (x < y) { - * x = y; - * } - * return x; - * ``` - */ - private IRBlock getBranchSuccessor(AbstractValue v) { - branch.(ConditionalBranchInstruction).getCondition() = this and - exists(BooleanValue bv | bv = v | - bv.getValue() = true and - result.getFirstInstruction() = branch.(ConditionalBranchInstruction).getTrueSuccessor() - or - bv.getValue() = false and - result.getFirstInstruction() = branch.(ConditionalBranchInstruction).getFalseSuccessor() - ) - or - exists(SwitchInstruction switch, CaseEdge kind | switch = branch | - switch.getExpression() = this and - result.getFirstInstruction() = switch.getSuccessor(kind) and - kind = v.(MatchValue).getCase() - ) - } - /** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */ pragma[inline] predicate comparesLt(Operand left, Operand right, int k, boolean isLessThan, boolean testIsTrue) { - exists(BooleanValue value | + exists(GuardValue value | compares_lt(valueNumber(this), left, right, k, isLessThan, value) and - value.getValue() = testIsTrue + value.asBooleanValue() = testIsTrue ) } @@ -746,7 +643,7 @@ class IRGuardCondition extends Instruction { * this expression evaluates to `value`. */ pragma[inline] - predicate comparesLt(Operand op, int k, boolean isLessThan, AbstractValue value) { + predicate comparesLt(Operand op, int k, boolean isLessThan, GuardValue value) { compares_lt(valueNumber(this), op, k, isLessThan, value) } @@ -756,7 +653,7 @@ class IRGuardCondition extends Instruction { */ pragma[inline] predicate ensuresLt(Operand left, Operand right, int k, IRBlock block, boolean isLessThan) { - exists(AbstractValue value | + exists(GuardValue value | compares_lt(valueNumber(this), left, right, k, isLessThan, value) and this.valueControls(block, value) ) @@ -768,7 +665,7 @@ class IRGuardCondition extends Instruction { */ pragma[inline] predicate ensuresLt(Operand op, int k, IRBlock block, boolean isLessThan) { - exists(AbstractValue value | + exists(GuardValue value | compares_lt(valueNumber(this), op, k, isLessThan, value) and this.valueControls(block, value) ) @@ -782,9 +679,9 @@ class IRGuardCondition extends Instruction { predicate ensuresLtEdge( Operand left, Operand right, int k, IRBlock pred, IRBlock succ, boolean isLessThan ) { - exists(AbstractValue value | + exists(GuardValue value | compares_lt(valueNumber(this), left, right, k, isLessThan, value) and - this.valueControlsEdge(pred, succ, value) + this.valueControlsBranchEdge(pred, succ, value) ) } @@ -794,24 +691,24 @@ class IRGuardCondition extends Instruction { */ pragma[inline] predicate ensuresLtEdge(Operand left, int k, IRBlock pred, IRBlock succ, boolean isLessThan) { - exists(AbstractValue value | + exists(GuardValue value | compares_lt(valueNumber(this), left, k, isLessThan, value) and - this.valueControlsEdge(pred, succ, value) + this.valueControlsBranchEdge(pred, succ, value) ) } /** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */ pragma[inline] predicate comparesEq(Operand left, Operand right, int k, boolean areEqual, boolean testIsTrue) { - exists(BooleanValue value | + exists(GuardValue value | compares_eq(valueNumber(this), left, right, k, areEqual, value) and - value.getValue() = testIsTrue + value.asBooleanValue() = testIsTrue ) } /** Holds if (determined by this guard) `op == k` evaluates to `areEqual` if this expression evaluates to `value`. */ pragma[inline] - predicate comparesEq(Operand op, int k, boolean areEqual, AbstractValue value) { + predicate comparesEq(Operand op, int k, boolean areEqual, GuardValue value) { unary_compares_eq(valueNumber(this), op, k, areEqual, value) } @@ -821,7 +718,7 @@ class IRGuardCondition extends Instruction { */ pragma[inline] predicate ensuresEq(Operand left, Operand right, int k, IRBlock block, boolean areEqual) { - exists(AbstractValue value | + exists(GuardValue value | compares_eq(valueNumber(this), left, right, k, areEqual, value) and this.valueControls(block, value) ) @@ -833,7 +730,7 @@ class IRGuardCondition extends Instruction { */ pragma[inline] predicate ensuresEq(Operand op, int k, IRBlock block, boolean areEqual) { - exists(AbstractValue value | + exists(GuardValue value | unary_compares_eq(valueNumber(this), op, k, areEqual, value) and this.valueControls(block, value) ) @@ -847,9 +744,9 @@ class IRGuardCondition extends Instruction { predicate ensuresEqEdge( Operand left, Operand right, int k, IRBlock pred, IRBlock succ, boolean areEqual ) { - exists(AbstractValue value | + exists(GuardValue value | compares_eq(valueNumber(this), left, right, k, areEqual, value) and - this.valueControlsEdge(pred, succ, value) + this.valueControlsBranchEdge(pred, succ, value) ) } @@ -859,102 +756,18 @@ class IRGuardCondition extends Instruction { */ pragma[inline] predicate ensuresEqEdge(Operand op, int k, IRBlock pred, IRBlock succ, boolean areEqual) { - exists(AbstractValue value | + exists(GuardValue value | unary_compares_eq(valueNumber(this), op, k, areEqual, value) and - this.valueControlsEdge(pred, succ, value) + this.valueControlsBranchEdge(pred, succ, value) ) } /** - * Holds if this condition controls `block`, meaning that `block` is only - * entered if the value of this condition is `v`. This helper - * predicate does not necessarily hold for binary logical operations like - * `&&` and `||`. See the detailed explanation on predicate `controls`. + * DEPRECATED: Use `controlsBranchEdge` instead. */ - private predicate controlsBlock(IRBlock controlled, AbstractValue v) { - not isUnreachedBlock(controlled) and - // - // For this block to control the block `controlled` with `testIsTrue` the - // following must hold: Execution must have passed through the test; that - // is, `this` must strictly dominate `controlled`. Execution must have - // passed through the `testIsTrue` edge leaving `this`. - // - // Although "passed through the true edge" implies that - // `getBranchSuccessor(true)` dominates `controlled`, the reverse is not - // true, as flow may have passed through another edge to get to - // `getBranchSuccessor(true)`, so we need to assert that - // `getBranchSuccessor(true)` dominates `controlled` *and* that all - // predecessors of `getBranchSuccessor(true)` are either `this` or - // dominated by `getBranchSuccessor(true)`. - // - // For example, in the following snippet: - // - // if (x) - // controlled; - // false_successor; - // uncontrolled; - // - // `false_successor` dominates `uncontrolled`, but not all of its - // predecessors are `this` (`if (x)`) or dominated by itself. Whereas in - // the following code: - // - // if (x) - // while (controlled) - // also_controlled; - // false_successor; - // uncontrolled; - // - // the block `while (controlled)` is controlled because all of its - // predecessors are `this` (`if (x)`) or (in the case of `also_controlled`) - // dominated by itself. - // - // The additional constraint on the predecessors of the test successor implies - // that `this` strictly dominates `controlled` so that isn't necessary to check - // directly. - exists(IRBlock succ | - succ = this.getBranchSuccessor(v) and - this.hasDominatingEdgeTo(succ) and - succ.dominates(controlled) - ) + deprecated predicate controlsEdge(IRBlock bb1, IRBlock bb2, boolean branch) { + this.controlsBranchEdge(bb1, bb2, branch) } - - /** - * Holds if `(this, succ)` is an edge that dominates `succ`, that is, all other - * predecessors of `succ` are dominated by `succ`. This implies that `this` is the - * immediate dominator of `succ`. - * - * This is a necessary and sufficient condition for an edge to dominate anything, - * and in particular `bb1.hasDominatingEdgeTo(bb2) and bb2.dominates(bb3)` means - * that the edge `(bb1, bb2)` dominates `bb3`. - */ - private predicate hasDominatingEdgeTo(IRBlock succ) { - exists(IRBlock branchBlock | branchBlock = this.getBranchBlock() | - branchBlock.immediatelyDominates(succ) and - branchBlock.getASuccessor() = succ and - forall(IRBlock pred | pred = succ.getAPredecessor() and pred != branchBlock | - succ.dominates(pred) - or - // An unreachable `pred` is vacuously dominated by `succ` since all - // paths from the entry to `pred` go through `succ`. Such vacuous - // dominance is not included in the `dominates` predicate since that - // could cause quadratic blow-up. - not pred.isReachableFromFunctionEntry() - ) - ) - } - - pragma[noinline] - private IRBlock getBranchBlock() { result = branch.getBlock() } -} - -private Instruction getBranchForCondition(Instruction guard) { - result.(ConditionalBranchInstruction).getCondition() = guard - or - result.(SwitchInstruction).getExpression() = guard - or - exists(LogicalNotInstruction cond | - result = getBranchForCondition(cond) and cond.getUnary() = guard - ) } cached From 3a8f77d6f4bd2bdb3dc506e49ac1394a157b0262 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 18 Sep 2025 10:02:30 +0100 Subject: [PATCH 08/35] C++: Qualified import of cpp. --- .../semmle/code/cpp/controlflow/IRGuards.qll | 158 +++++++++++------- 1 file changed, 99 insertions(+), 59 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 7e53c83494bb..622b1f1468a9 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -3,7 +3,7 @@ * flow elements controlled by those guards. */ -import cpp +import cpp as Cpp import semmle.code.cpp.ir.IR private import semmle.code.cpp.ir.ValueNumbering private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr @@ -68,14 +68,14 @@ deprecated class MatchValue extends AbstractValue { * A Boolean condition in the AST that guards one or more basic blocks. This includes * operands of logical operators but not switch statements. */ -private class GuardConditionImpl extends Element { +private class GuardConditionImpl extends Cpp::Element { /** * Holds if this condition controls `controlled`, meaning that `controlled` is only * entered if the value of this condition is `v`. * * For details on what "controls" mean, see the QLDoc for `controls`. */ - abstract predicate valueControls(BasicBlock controlled, GuardValue v); + abstract predicate valueControls(Cpp::BasicBlock controlled, GuardValue v); /** * Holds if this condition controls `controlled`, meaning that `controlled` is only @@ -103,7 +103,7 @@ private class GuardConditionImpl extends Element { * being short-circuited) then it will only control blocks dominated by the * true (for `&&`) or false (for `||`) branch. */ - final predicate controls(BasicBlock controlled, boolean testIsTrue) { + final predicate controls(Cpp::BasicBlock controlled, boolean testIsTrue) { this.valueControls(controlled, any(GuardValue bv | bv.asBooleanValue() = testIsTrue)) } @@ -111,13 +111,13 @@ private class GuardConditionImpl extends Element { * Holds if the control-flow edge `(pred, succ)` may be taken only if * the value of this condition is `v`. */ - abstract predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, GuardValue v); + abstract predicate valueControlsEdge(Cpp::BasicBlock pred, Cpp::BasicBlock succ, GuardValue v); /** * Holds if the control-flow edge `(pred, succ)` may be taken only if * this the value of this condition is `testIsTrue`. */ - final predicate controlsEdge(BasicBlock pred, BasicBlock succ, boolean testIsTrue) { + final predicate controlsEdge(Cpp::BasicBlock pred, Cpp::BasicBlock succ, boolean testIsTrue) { this.valueControlsEdge(pred, succ, any(GuardValue bv | bv.asBooleanValue() = testIsTrue)) } @@ -127,7 +127,9 @@ private class GuardConditionImpl extends Element { * ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`). */ pragma[inline] - abstract predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue); + abstract predicate comparesLt( + Cpp::Expr left, Cpp::Expr right, int k, boolean isLessThan, boolean testIsTrue + ); /** * Holds if (determined by this guard) `left < right + k` must be `isLessThan` in `block`. @@ -135,7 +137,9 @@ private class GuardConditionImpl extends Element { * ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`). */ pragma[inline] - abstract predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan); + abstract predicate ensuresLt( + Cpp::Expr left, Cpp::Expr right, int k, Cpp::BasicBlock block, boolean isLessThan + ); /** * Holds if (determined by this guard) `e < k` evaluates to `isLessThan` if @@ -143,7 +147,7 @@ private class GuardConditionImpl extends Element { * ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`). */ pragma[inline] - abstract predicate comparesLt(Expr e, int k, boolean isLessThan, GuardValue value); + abstract predicate comparesLt(Cpp::Expr e, int k, boolean isLessThan, GuardValue value); /** * Holds if (determined by this guard) `e < k` must be `isLessThan` in `block`. @@ -151,7 +155,7 @@ private class GuardConditionImpl extends Element { * ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`). */ pragma[inline] - abstract predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan); + abstract predicate ensuresLt(Cpp::Expr e, int k, Cpp::BasicBlock block, boolean isLessThan); /** * Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this @@ -164,7 +168,9 @@ private class GuardConditionImpl extends Element { * necessarily integer). */ pragma[inline] - abstract predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue); + abstract predicate comparesEq( + Cpp::Expr left, Cpp::Expr right, int k, boolean areEqual, boolean testIsTrue + ); /** * Holds if (determined by this guard) `left == right + k` must be `areEqual` in `block`. @@ -172,7 +178,9 @@ private class GuardConditionImpl extends Element { * ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`). */ pragma[inline] - abstract predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual); + abstract predicate ensuresEq( + Cpp::Expr left, Cpp::Expr right, int k, Cpp::BasicBlock block, boolean areEqual + ); /** * Holds if (determined by this guard) `e == k` evaluates to `areEqual` if this expression @@ -185,7 +193,7 @@ private class GuardConditionImpl extends Element { * necessarily integer). */ pragma[inline] - abstract predicate comparesEq(Expr e, int k, boolean areEqual, GuardValue value); + abstract predicate comparesEq(Cpp::Expr e, int k, boolean areEqual, GuardValue value); /** * Holds if (determined by this guard) `e == k` must be `areEqual` in `block`. @@ -193,7 +201,7 @@ private class GuardConditionImpl extends Element { * ("unary") and a 5-argument ("binary") version of this predicate (see `comparesEq`). */ pragma[inline] - abstract predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual); + abstract predicate ensuresEq(Cpp::Expr e, int k, Cpp::BasicBlock block, boolean areEqual); /** * Holds if (determined by this guard) `left == right + k` must be `areEqual` on the edge from @@ -201,7 +209,8 @@ private class GuardConditionImpl extends Element { */ pragma[inline] final predicate ensuresEqEdge( - Expr left, Expr right, int k, BasicBlock pred, BasicBlock succ, boolean areEqual + Cpp::Expr left, Cpp::Expr right, int k, Cpp::BasicBlock pred, Cpp::BasicBlock succ, + boolean areEqual ) { exists(boolean testIsTrue | this.comparesEq(left, right, k, areEqual, testIsTrue) and @@ -214,7 +223,9 @@ private class GuardConditionImpl extends Element { * `pred` to `succ`. If `areEqual = false` then this implies `e != k`. */ pragma[inline] - final predicate ensuresEqEdge(Expr e, int k, BasicBlock pred, BasicBlock succ, boolean areEqual) { + final predicate ensuresEqEdge( + Cpp::Expr e, int k, Cpp::BasicBlock pred, Cpp::BasicBlock succ, boolean areEqual + ) { exists(GuardValue v | this.comparesEq(e, k, areEqual, v) and this.valueControlsEdge(pred, succ, v) @@ -227,7 +238,8 @@ private class GuardConditionImpl extends Element { */ pragma[inline] final predicate ensuresLtEdge( - Expr left, Expr right, int k, BasicBlock pred, BasicBlock succ, boolean isLessThan + Cpp::Expr left, Cpp::Expr right, int k, Cpp::BasicBlock pred, Cpp::BasicBlock succ, + boolean isLessThan ) { exists(boolean testIsTrue | this.comparesLt(left, right, k, isLessThan, testIsTrue) and @@ -240,7 +252,9 @@ private class GuardConditionImpl extends Element { * `pred` to `succ`. If `isLessThan = false` then this implies `e >= k`. */ pragma[inline] - final predicate ensuresLtEdge(Expr e, int k, BasicBlock pred, BasicBlock succ, boolean isLessThan) { + final predicate ensuresLtEdge( + Cpp::Expr e, int k, Cpp::BasicBlock pred, Cpp::BasicBlock succ, boolean isLessThan + ) { exists(GuardValue v | this.comparesLt(e, k, isLessThan, v) and this.valueControlsEdge(pred, succ, v) @@ -253,10 +267,10 @@ final class GuardCondition = GuardConditionImpl; /** * A binary logical operator in the AST that guards one or more basic blocks. */ -private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl instanceof BinaryLogicalOperation +private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl instanceof Cpp::BinaryLogicalOperation { - override predicate valueControls(BasicBlock controlled, GuardValue v) { - exists(BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs | + override predicate valueControls(Cpp::BasicBlock controlled, GuardValue v) { + exists(Cpp::BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs | this = binop and lhs = binop.getLeftOperand() and rhs = binop.getRightOperand() and @@ -265,8 +279,8 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl ) } - override predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, GuardValue v) { - exists(BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs | + override predicate valueControlsEdge(Cpp::BasicBlock pred, Cpp::BasicBlock succ, GuardValue v) { + exists(Cpp::BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs | this = binop and lhs = binop.getLeftOperand() and rhs = binop.getRightOperand() and @@ -275,17 +289,19 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl ) } - override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) { + override predicate comparesLt( + Cpp::Expr left, Cpp::Expr right, int k, boolean isLessThan, boolean testIsTrue + ) { exists(boolean partIsTrue, GuardCondition part | - this.(BinaryLogicalOperation).impliesValue(part, partIsTrue, testIsTrue) + this.(Cpp::BinaryLogicalOperation).impliesValue(part, partIsTrue, testIsTrue) | part.comparesLt(left, right, k, isLessThan, partIsTrue) ) } - override predicate comparesLt(Expr e, int k, boolean isLessThan, GuardValue value) { + override predicate comparesLt(Cpp::Expr e, int k, boolean isLessThan, GuardValue value) { exists(GuardValue partValue, GuardCondition part | - this.(BinaryLogicalOperation) + this.(Cpp::BinaryLogicalOperation) .impliesValue(part, partValue.asBooleanValue(), value.asBooleanValue()) | part.comparesLt(e, k, isLessThan, partValue) @@ -293,37 +309,43 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl } pragma[inline] - override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) { + override predicate ensuresLt( + Cpp::Expr left, Cpp::Expr right, int k, Cpp::BasicBlock block, boolean isLessThan + ) { exists(boolean testIsTrue | this.comparesLt(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue) ) } pragma[inline] - override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) { + override predicate ensuresLt(Cpp::Expr e, int k, Cpp::BasicBlock block, boolean isLessThan) { exists(GuardValue value | this.comparesLt(e, k, isLessThan, value) and this.valueControls(block, value) ) } - override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) { + override predicate comparesEq( + Cpp::Expr left, Cpp::Expr right, int k, boolean areEqual, boolean testIsTrue + ) { exists(boolean partIsTrue, GuardCondition part | - this.(BinaryLogicalOperation).impliesValue(part, partIsTrue, testIsTrue) + this.(Cpp::BinaryLogicalOperation).impliesValue(part, partIsTrue, testIsTrue) | part.comparesEq(left, right, k, areEqual, partIsTrue) ) } pragma[inline] - override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) { + override predicate ensuresEq( + Cpp::Expr left, Cpp::Expr right, int k, Cpp::BasicBlock block, boolean areEqual + ) { exists(boolean testIsTrue | this.comparesEq(left, right, k, areEqual, testIsTrue) and this.controls(block, testIsTrue) ) } - override predicate comparesEq(Expr e, int k, boolean areEqual, GuardValue value) { + override predicate comparesEq(Cpp::Expr e, int k, boolean areEqual, GuardValue value) { exists(GuardValue partValue, GuardCondition part | - this.(BinaryLogicalOperation) + this.(Cpp::BinaryLogicalOperation) .impliesValue(part, partValue.asBooleanValue(), value.asBooleanValue()) | part.comparesEq(e, k, areEqual, partValue) @@ -331,7 +353,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl } pragma[inline] - override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) { + override predicate ensuresEq(Cpp::Expr e, int k, Cpp::BasicBlock block, boolean areEqual) { exists(GuardValue value | this.comparesEq(e, k, areEqual, value) and this.valueControls(block, value) ) @@ -344,7 +366,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl * predicate does not necessarily hold for binary logical operations like * `&&` and `||`. See the detailed explanation on predicate `controls`. */ -private predicate controlsBlock(IRGuardCondition ir, BasicBlock controlled, GuardValue v) { +private predicate controlsBlock(IRGuardCondition ir, Cpp::BasicBlock controlled, GuardValue v) { exists(IRBlock irb | ir.valueControls(irb, v) and nonExcludedIRAndBasicBlock(irb, controlled) and @@ -359,7 +381,9 @@ private predicate controlsBlock(IRGuardCondition ir, BasicBlock controlled, Guar * like `&&` and `||`. * See the detailed explanation on predicate `controlsEdge`. */ -private predicate controlsEdge(IRGuardCondition ir, BasicBlock pred, BasicBlock succ, GuardValue v) { +private predicate controlsEdge( + IRGuardCondition ir, Cpp::BasicBlock pred, Cpp::BasicBlock succ, GuardValue v +) { exists(IRBlock irPred, IRBlock irSucc | ir.valueControlsBranchEdge(irPred, irSucc, v) and nonExcludedIRAndBasicBlock(irPred, pred) and @@ -378,25 +402,27 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { // comparison against 0 so it's not included as a normal // `IRGuardCondition`. So to align with user expectations we make that `x` // a `GuardCondition`. - exists(NotExpr notExpr | this = notExpr.getOperand() | + exists(Cpp::NotExpr notExpr | this = notExpr.getOperand() | ir.getUnconvertedResultExpression() = notExpr or ir.(ConditionalBranchInstruction).getCondition().getUnconvertedResultExpression() = notExpr ) } - override predicate valueControls(BasicBlock controlled, GuardValue v) { + override predicate valueControls(Cpp::BasicBlock controlled, GuardValue v) { // This condition must determine the flow of control; that is, this // node must be a top-level condition. controlsBlock(ir, controlled, v.getDualValue()) } - override predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, GuardValue v) { + override predicate valueControlsEdge(Cpp::BasicBlock pred, Cpp::BasicBlock succ, GuardValue v) { controlsEdge(ir, pred, succ, v.getDualValue()) } pragma[inline] - override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) { + override predicate comparesLt( + Cpp::Expr left, Cpp::Expr right, int k, boolean isLessThan, boolean testIsTrue + ) { exists(Instruction li, Instruction ri | li.getUnconvertedResultExpression() = left and ri.getUnconvertedResultExpression() = right and @@ -405,7 +431,7 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { } pragma[inline] - override predicate comparesLt(Expr e, int k, boolean isLessThan, GuardValue value) { + override predicate comparesLt(Cpp::Expr e, int k, boolean isLessThan, GuardValue value) { exists(Instruction i | i.getUnconvertedResultExpression() = e and ir.comparesLt(i.getAUse(), k, isLessThan, value.getDualValue()) @@ -413,7 +439,9 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { } pragma[inline] - override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) { + override predicate ensuresLt( + Cpp::Expr left, Cpp::Expr right, int k, Cpp::BasicBlock block, boolean isLessThan + ) { exists(Instruction li, Instruction ri, boolean testIsTrue | li.getUnconvertedResultExpression() = left and ri.getUnconvertedResultExpression() = right and @@ -423,7 +451,7 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { } pragma[inline] - override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) { + override predicate ensuresLt(Cpp::Expr e, int k, Cpp::BasicBlock block, boolean isLessThan) { exists(Instruction i, GuardValue value | i.getUnconvertedResultExpression() = e and ir.comparesLt(i.getAUse(), k, isLessThan, value.getDualValue()) and @@ -432,7 +460,9 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { } pragma[inline] - override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) { + override predicate comparesEq( + Cpp::Expr left, Cpp::Expr right, int k, boolean areEqual, boolean testIsTrue + ) { exists(Instruction li, Instruction ri | li.getUnconvertedResultExpression() = left and ri.getUnconvertedResultExpression() = right and @@ -441,7 +471,9 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { } pragma[inline] - override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) { + override predicate ensuresEq( + Cpp::Expr left, Cpp::Expr right, int k, Cpp::BasicBlock block, boolean areEqual + ) { exists(Instruction li, Instruction ri, boolean testIsTrue | li.getUnconvertedResultExpression() = left and ri.getUnconvertedResultExpression() = right and @@ -451,7 +483,7 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { } pragma[inline] - override predicate comparesEq(Expr e, int k, boolean areEqual, GuardValue value) { + override predicate comparesEq(Cpp::Expr e, int k, boolean areEqual, GuardValue value) { exists(Instruction i | i.getUnconvertedResultExpression() = e and ir.comparesEq(i.getAUse(), k, areEqual, value.getDualValue()) @@ -459,7 +491,7 @@ private class GuardConditionFromNotExpr extends GuardConditionImpl { } pragma[inline] - override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) { + override predicate ensuresEq(Cpp::Expr e, int k, Cpp::BasicBlock block, boolean areEqual) { exists(Instruction i, GuardValue value | i.getUnconvertedResultExpression() = e and ir.comparesEq(i.getAUse(), k, areEqual, value.getDualValue()) and @@ -483,18 +515,20 @@ private class GuardConditionFromIR extends GuardConditionImpl { ir.getUnconvertedResultExpression() = this } - override predicate valueControls(BasicBlock controlled, GuardValue v) { + override predicate valueControls(Cpp::BasicBlock controlled, GuardValue v) { // This condition must determine the flow of control; that is, this // node must be a top-level condition. controlsBlock(ir, controlled, v) } - override predicate valueControlsEdge(BasicBlock pred, BasicBlock succ, GuardValue v) { + override predicate valueControlsEdge(Cpp::BasicBlock pred, Cpp::BasicBlock succ, GuardValue v) { controlsEdge(ir, pred, succ, v) } pragma[inline] - override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) { + override predicate comparesLt( + Cpp::Expr left, Cpp::Expr right, int k, boolean isLessThan, boolean testIsTrue + ) { exists(Instruction li, Instruction ri | li.getUnconvertedResultExpression() = left and ri.getUnconvertedResultExpression() = right and @@ -503,7 +537,7 @@ private class GuardConditionFromIR extends GuardConditionImpl { } pragma[inline] - override predicate comparesLt(Expr e, int k, boolean isLessThan, GuardValue value) { + override predicate comparesLt(Cpp::Expr e, int k, boolean isLessThan, GuardValue value) { exists(Instruction i | i.getUnconvertedResultExpression() = e and ir.comparesLt(i.getAUse(), k, isLessThan, value) @@ -511,7 +545,9 @@ private class GuardConditionFromIR extends GuardConditionImpl { } pragma[inline] - override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) { + override predicate ensuresLt( + Cpp::Expr left, Cpp::Expr right, int k, Cpp::BasicBlock block, boolean isLessThan + ) { exists(Instruction li, Instruction ri, boolean testIsTrue | li.getUnconvertedResultExpression() = left and ri.getUnconvertedResultExpression() = right and @@ -521,7 +557,7 @@ private class GuardConditionFromIR extends GuardConditionImpl { } pragma[inline] - override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) { + override predicate ensuresLt(Cpp::Expr e, int k, Cpp::BasicBlock block, boolean isLessThan) { exists(Instruction i, GuardValue value | i.getUnconvertedResultExpression() = e and ir.comparesLt(i.getAUse(), k, isLessThan, value) and @@ -530,7 +566,9 @@ private class GuardConditionFromIR extends GuardConditionImpl { } pragma[inline] - override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) { + override predicate comparesEq( + Cpp::Expr left, Cpp::Expr right, int k, boolean areEqual, boolean testIsTrue + ) { exists(Instruction li, Instruction ri | li.getUnconvertedResultExpression() = left and ri.getUnconvertedResultExpression() = right and @@ -539,7 +577,9 @@ private class GuardConditionFromIR extends GuardConditionImpl { } pragma[inline] - override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) { + override predicate ensuresEq( + Cpp::Expr left, Cpp::Expr right, int k, Cpp::BasicBlock block, boolean areEqual + ) { exists(Instruction li, Instruction ri, boolean testIsTrue | li.getUnconvertedResultExpression() = left and ri.getUnconvertedResultExpression() = right and @@ -549,7 +589,7 @@ private class GuardConditionFromIR extends GuardConditionImpl { } pragma[inline] - override predicate comparesEq(Expr e, int k, boolean areEqual, GuardValue value) { + override predicate comparesEq(Cpp::Expr e, int k, boolean areEqual, GuardValue value) { exists(Instruction i | i.getUnconvertedResultExpression() = e and ir.comparesEq(i.getAUse(), k, areEqual, value) @@ -557,7 +597,7 @@ private class GuardConditionFromIR extends GuardConditionImpl { } pragma[inline] - override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) { + override predicate ensuresEq(Cpp::Expr e, int k, Cpp::BasicBlock block, boolean areEqual) { exists(Instruction i, GuardValue value | i.getUnconvertedResultExpression() = e and ir.comparesEq(i.getAUse(), k, areEqual, value) and @@ -588,7 +628,7 @@ private predicate excludeAsControlledInstruction(Instruction instr) { * the `irb` be ignored. */ pragma[nomagic] -private predicate nonExcludedIRAndBasicBlock(IRBlock irb, BasicBlock controlled) { +private predicate nonExcludedIRAndBasicBlock(IRBlock irb, Cpp::BasicBlock controlled) { exists(Instruction instr | instr = irb.getAnInstruction() and instr.getAst() = controlled.getANode() and From 840097f121868d2e52d9af740d2aceb65f02504f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:39:37 +0100 Subject: [PATCH 09/35] C++: Instantiate the shared guards library. --- .../semmle/code/cpp/controlflow/IRGuards.qll | 448 ++++++++++++++++++ 1 file changed, 448 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 622b1f1468a9..da87ee21a545 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -5,10 +5,458 @@ import cpp as Cpp import semmle.code.cpp.ir.IR +private import codeql.util.Void +private import codeql.controlflow.Guards as SharedGuards private import semmle.code.cpp.ir.ValueNumbering private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag +private class BasicBlock = IRCfg::BasicBlock; + +/** + * INTERNAL: Do not use. + */ +module GuardsInput implements SharedGuards::InputSig { + private import cpp as Cpp + + class NormalExitNode = ExitFunctionInstruction; + + class AstNode = Instruction; + + /** The `Guards` library uses `Instruction`s as expressions. */ + class Expr extends Instruction { + Instruction getControlFlowNode() { result = this } + + IRCfg::BasicBlock getBasicBlock() { result = this.getBlock() } + } + + private newtype TConstantValue = + TRange(string minValue, string maxValue) { + minValue != maxValue and + exists(EdgeKind::caseEdge(minValue, maxValue)) + } + + /** + * The constant values that can be inferred. The only additional constant + * value required is the GCC extension for case ranges. + */ + class ConstantValue extends TConstantValue { + /** + * Holds if this constant value is the case range `minValue..maxValue`. + */ + predicate isRange(string minValue, string maxValue) { this = TRange(minValue, maxValue) } + + string toString() { + exists(string minValue, string maxValue | + this.isRange(minValue, maxValue) and + result = minValue + ".." + maxValue + ) + } + } + + private class EqualityExpr extends CompareInstruction { + EqualityExpr() { + this instanceof CompareEQInstruction + or + this instanceof CompareNEInstruction + } + + boolean getPolarity() { + result = true and + this instanceof CompareEQInstruction + or + result = false and + this instanceof CompareNEInstruction + } + } + + /** A constant expression. */ + abstract class ConstantExpr extends Expr { + /** Holds if this expression is the null constant. */ + predicate isNull() { none() } + + /** Holds if this expression is a boolean constant. */ + boolean asBooleanValue() { none() } + + /** Holds if this expression is an integer constant. */ + int asIntegerValue() { none() } + + /** + * Holds if this expression is a C/C++ specific constant value such as + * a GCC case range. + */ + ConstantValue asConstantValue() { none() } + } + + private class NullConstant extends ConstantExpr instanceof ConstantInstruction { + NullConstant() { + this.getValue() = "0" and + this.getResultIRType() instanceof IRAddressType + } + + override predicate isNull() { any() } + } + + private class BooleanConstant extends ConstantExpr instanceof ConstantInstruction { + BooleanConstant() { this.getResultIRType() instanceof IRBooleanType } + + override boolean asBooleanValue() { + super.getValue() = "0" and + result = false + or + super.getValue() = "1" and + result = true + } + } + + private class IntegerConstant extends ConstantExpr { + int value; + + IntegerConstant() { + this.(ConstantInstruction).getValue().toInt() = value and + this.getResultIRType() instanceof IRIntegerType + or + // In order to have an "integer constant" for a switch case + // we misuse the first instruction (which is always a NoOp instruction) + // as a constant with the switch case's value. + exists(CaseEdge edge | + this = any(SwitchInstruction switch).getSuccessor(edge) and + value = edge.getValue().toInt() + ) + } + + override int asIntegerValue() { result = value } + } + + /** + * The instruction representing the constant expression in a case statement. + * + * Since the IR does not have an instruction for this (as this is represented + * by the edge) we use the `NoOp` instruction which is always generated. + */ + private class CaseConstant extends ConstantExpr instanceof NoOpInstruction { + SwitchInstruction switch; + SwitchEdge edge; + + CaseConstant() { this = switch.getSuccessor(edge) } + + override ConstantValue asConstantValue() { + exists(string minValue, string maxValue | + edge.getMinValue() = minValue and + edge.getMaxValue() = maxValue and + result.isRange(minValue, maxValue) + ) + } + + predicate hasEdge(SwitchInstruction switch_, SwitchEdge edge_) { + switch_ = switch and + edge_ = edge + } + } + + private predicate nonNullExpr(Instruction i) { + i instanceof VariableAddressInstruction + or + i.(PointerConstantInstruction).getValue() != "0" + or + i instanceof TypeidInstruction + or + nonNullExpr(i.(FieldAddressInstruction).getObjectAddress()) + or + nonNullExpr(i.(PointerAddInstruction).getLeft()) + or + nonNullExpr(i.(CopyInstruction).getSourceValue()) + or + nonNullExpr(i.(ConvertInstruction).getUnary()) + or + nonNullExpr(i.(CheckedConvertOrThrowInstruction).getUnary()) + or + nonNullExpr(i.(CompleteObjectAddressInstruction).getUnary()) + or + nonNullExpr(i.(InheritanceConversionInstruction).getUnary()) + or + nonNullExpr(i.(BitOrInstruction).getAnInput()) + } + + /** + * An expression that is guaranteed to not be `null`. + */ + class NonNullExpr extends Expr { + NonNullExpr() { nonNullExpr(this) } + } + + /** A `case` in a `switch` instruction. */ + class Case extends Expr { + SwitchInstruction switch; + SwitchEdge edge; + + Case() { switch.getSuccessor(edge) = this } + + /** + * Gets the edge for which control flows from the `Switch` instruction to + * the target case. + */ + SwitchEdge getEdge() { result = edge } + + /** + * Holds if this case takes control-flow from `bb1` to `bb2` when + * the case matches the scrutinee. + */ + predicate matchEdge(BasicBlock bb1, BasicBlock bb2) { + switch.getBlock() = bb1 and + this.getBasicBlock() = bb2 + } + + /** + * Holds if case takes control-flow from `bb1` to `bb2` when the + * case does not match the scrutinee. + * + * This predicate never holds for C/C++. + */ + predicate nonMatchEdge(BasicBlock bb1, BasicBlock bb2) { none() } + + /** + * Gets the scrutinee expression. + */ + Expr getSwitchExpr() { result = switch.getExpression() } + + /** + * Holds if this case is the default case. + */ + predicate isDefaultCase() { edge.isDefault() } + + /** + * Gets the constant expression of this case. + */ + ConstantExpr asConstantCase() { result.(CaseConstant).hasEdge(switch, edge) } + } + + abstract private class BinExpr extends Expr instanceof BinaryInstruction { + Expr getAnOperand() { result = super.getAnInput() } + } + + /** + * A bitwise "AND" expression. + * + * This does not include logical AND expressions since these are desugared as + * part of IR generation. + */ + class AndExpr extends BinExpr instanceof BitAndInstruction { } + + /** + * A bitwise "OR" expression. + * + * This does not include logical OR expressions since these are desugared as + * part of IR generation. + */ + class OrExpr extends BinExpr instanceof BitOrInstruction { } + + /** A (bitwise or logical) "NOT" expression. */ + class NotExpr extends Expr instanceof UnaryInstruction { + NotExpr() { + this instanceof LogicalNotInstruction + or + this instanceof BitComplementInstruction + } + + /** Gets the operand of this expression. */ + Expr getOperand() { result = super.getUnary() } + } + + private predicate isBoolToIntConversion(ConvertInstruction convert, Instruction unary) { + convert.getUnary() = unary and + unary.getResultIRType() instanceof IRBooleanType and + convert.getResultIRType() instanceof IRIntegerType + } + + /** + * A value preserving expression. + */ + class IdExpr extends Expr { + IdExpr() { + this instanceof CopyInstruction + or + not isBoolToIntConversion(this, _) and + this instanceof ConvertInstruction + or + this instanceof InheritanceConversionInstruction + } + + /** Get the child expression that defines the value of this expression. */ + Expr getEqualChildExpr() { + result = this.(CopyInstruction).getSourceValue() + or + result = this.(ConvertInstruction).getUnary() + or + result = this.(InheritanceConversionInstruction).getUnary() + } + } + + /** + * Holds if `eqtest` tests the equality (or inequality) of `left` and + * `right.` + * + * If `polarity` is `true` then `eqtest` is an equality test, and otherwise + * `eqtest` is an inequality test. + */ + pragma[nomagic] + predicate equalityTest(Expr eqtest, Expr left, Expr right, boolean polarity) { + exists(EqualityExpr eq | eqtest = eq | + eq.getLeft() = left and + eq.getRight() = right and + polarity = eq.getPolarity() + ) + } + + /** + * A conditional expression (i.e., `b ? e1 : e2`). This expression is desugared + * as part of IR generation. + */ + class ConditionalExpr extends Expr { + ConditionalExpr() { none() } + + /** Gets the condition of this conditional expression. */ + Expr getCondition() { none() } + + /** Gets the true branch of this conditional expression. */ + Expr getThen() { none() } + + /** Gets the false branch of this conditional expression. */ + Expr getElse() { none() } + } + + private import semmle.code.cpp.dataflow.new.DataFlow::DataFlow as DataFlow + private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as Private + + class Parameter = Cpp::Parameter; + + /** + * A (direct) parameter position. The value `-1` represents the position of + * the implicit `this` parameter. + */ + private int parameterPosition() { result in [-1, any(Cpp::Parameter p).getIndex()] } + + /** A parameter position represented by an integer. */ + class ParameterPosition extends int { + ParameterPosition() { this = parameterPosition() } + } + + /** An argument position represented by an integer. */ + class ArgumentPosition extends int { + ArgumentPosition() { this = parameterPosition() } + } + + /** Holds if arguments at position `apos` match parameters at position `ppos`. */ + overlay[caller?] + pragma[inline] + predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos } + + final private class FinalMethod = Cpp::Function; + + /** + * A non-overridable function. + * + * This function is non-overrideable either because it is not a member function, or + * because it is a final member function. + */ + class NonOverridableMethod extends FinalMethod { + NonOverridableMethod() { + not this instanceof Cpp::MemberFunction + or + exists(Cpp::MemberFunction mf | this = mf | + not mf.isVirtual() + or + mf.isFinal() + ) + } + + /** Gets the `Parameter` at `pos` of this function, if any. */ + Parameter getParameter(ParameterPosition ppos) { super.getParameter(ppos) = result } + + /** Gets an expression returned from this function. */ + GuardsInput::Expr getAReturnExpr() { + exists(ReturnValueInstruction ret | + ret.getEnclosingFunction() = this and + result = ret.getReturnValue() + ) + } + } + + private predicate nonOverridableMethodCall(CallInstruction call, NonOverridableMethod m) { + call.getStaticCallTarget() = m + } + + /** + * A call to a `NonOverridableMethod`. + */ + class NonOverridableMethodCall extends GuardsInput::Expr instanceof CallInstruction { + NonOverridableMethodCall() { nonOverridableMethodCall(this, _) } + + /** Gets the function that is called. */ + NonOverridableMethod getMethod() { nonOverridableMethodCall(this, result) } + + /** Gets the argument at `apos`, if any. */ + GuardsInput::Expr getArgument(ArgumentPosition apos) { result = super.getArgument(apos) } + } +} + +private module GuardsImpl = SharedGuards::Make; + +private module LogicInput_v1 implements GuardsImpl::LogicInputSig { + private import semmle.code.cpp.dataflow.new.DataFlow::DataFlow::Ssa + + final private class FinalBaseSsaVariable = Definition; + + class SsaDefinition extends FinalBaseSsaVariable { + GuardsInput::Expr getARead() { result = this.getAUse().getDef() } + } + + class SsaWriteDefinition extends SsaDefinition instanceof ExplicitDefinition { + GuardsInput::Expr getDefinition() { result = super.getAssignedInstruction() } + } + + class SsaPhiNode extends SsaDefinition instanceof PhiNode { + predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) { + super.hasInputFromBlock(inp, bb) + } + } + + predicate parameterDefinition(GuardsInput::Parameter p, SsaDefinition def) { + def.isParameterDefinition(p) + } + + predicate additionalImpliesStep( + GuardsImpl::PreGuard g1, GuardValue v1, GuardsImpl::PreGuard g2, GuardValue v2 + ) { + g1.(ConditionalBranchInstruction).getCondition() = g2 and + v1.asBooleanValue() = v2.asBooleanValue() + or + exists(SwitchInstruction switch, SwitchEdge edge | + g1 = switch.getSuccessor(edge) and + g2 = switch.getExpression() + | + v1.asBooleanValue() = true and + ( + v2.asIntValue() = edge.getValue().toInt() + or + v2.asConstantValue().isRange(edge.getMinValue(), edge.getMaxValue()) + ) + or + v1.asBooleanValue() = false and + ( + v2.getDualValue().asIntValue() = edge.getValue().toInt() + or + v2.getDualValue().asConstantValue().isRange(edge.getMinValue(), edge.getMaxValue()) + ) + ) + } +} + +class GuardValue = GuardsImpl::GuardValue; + +/** INTERNAL: Don't use. */ +module Guards_v1 = GuardsImpl::Logic; + /** * Holds if `block` consists of an `UnreachedInstruction`. * From ac5233d19c199c96dc3a8d61f17b327b903b6935 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:41:11 +0100 Subject: [PATCH 10/35] C++: Lots of renamings. --- .../semmle/code/cpp/controlflow/IRGuards.qll | 116 +++++++++--------- 1 file changed, 56 insertions(+), 60 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index da87ee21a545..d0f3de4fb3c5 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -1418,10 +1418,10 @@ private module Cached { */ cached predicate compares_eq( - ValueNumber test, Operand left, Operand right, int k, boolean areEqual, AbstractValue value + ValueNumber test, Operand left, Operand right, int k, boolean areEqual, GuardValue value ) { /* The simple case where the test *is* the comparison so areEqual = testIsTrue xor eq. */ - exists(AbstractValue v | simple_comparison_eq(test, left, right, k, v) | + exists(GuardValue v | simple_comparison_eq(test, left, right, k, v) | areEqual = true and value = v or areEqual = false and value = v.getDualValue() @@ -1436,15 +1436,15 @@ private module Cached { complex_eq(test, left, right, k, areEqual, value) or /* (x is true => (left == right + k)) => (!x is false => (left == right + k)) */ - exists(AbstractValue dual | value = dual.getDualValue() | + exists(GuardValue dual | value = dual.getDualValue() | compares_eq(test.(LogicalNotValueNumber).getUnary(), left, right, k, areEqual, dual) ) or compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), left, right, k, areEqual, value) or - exists(Operand l, BooleanValue bv | + exists(Operand l, GuardValue bv | // 1. test = value -> int(l) = 0 is !bv - unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and + unary_compares_eq(test, l, 0, bv.asBooleanValue().booleanNot(), value) and // 2. l = bv -> left + right is areEqual compares_eq(valueNumber(BooleanInstruction::get(l.getDef())), left, right, k, areEqual, bv) @@ -1461,10 +1461,10 @@ private module Cached { */ cached predicate unary_compares_eq( - ValueNumber test, Operand op, int k, boolean areEqual, AbstractValue value + ValueNumber test, Operand op, int k, boolean areEqual, GuardValue value ) { /* The simple case where the test *is* the comparison so areEqual = testIsTrue xor eq. */ - exists(AbstractValue v | unary_simple_comparison_eq(test, op, k, v) | + exists(GuardValue v | unary_simple_comparison_eq(test, op, k, v) | areEqual = true and value = v or areEqual = false and value = v.getDualValue() @@ -1473,7 +1473,7 @@ private module Cached { unary_complex_eq(test, op, k, areEqual, value) or /* (x is true => (op == k)) => (!x is false => (op == k)) */ - exists(AbstractValue dual | + exists(GuardValue dual | value = dual.getDualValue() and unary_compares_eq(test.(LogicalNotValueNumber).getUnary(), op, k, areEqual, dual) ) @@ -1487,18 +1487,18 @@ private module Cached { ) or // See argument for why this is correct in compares_eq - exists(Operand l, BooleanValue bv | - unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and + exists(Operand l, GuardValue bv | + unary_compares_eq(test, l, 0, bv.asBooleanValue().booleanNot(), value) and unary_compares_eq(valueNumber(BooleanInstruction::get(l.getDef())), op, k, areEqual, bv) ) or unary_compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, areEqual, value) or - exists(BinaryLogicalOperation logical, Expr operand, boolean b | + exists(Cpp::BinaryLogicalOperation logical, Cpp::Expr operand, boolean b | test.getAnInstruction().getUnconvertedResultExpression() = logical and op.getDef().getUnconvertedResultExpression() = operand and - logical.impliesValue(operand, b, value.(BooleanValue).getValue()) + logical.impliesValue(operand, b, value.asBooleanValue()) | k = 1 and areEqual = b @@ -1510,17 +1510,17 @@ private module Cached { /** Rearrange various simple comparisons into `left == right + k` form. */ private predicate simple_comparison_eq( - CompareValueNumber cmp, Operand left, Operand right, int k, AbstractValue value + CompareValueNumber cmp, Operand left, Operand right, int k, GuardValue value ) { cmp instanceof CompareEQValueNumber and cmp.hasOperands(left, right) and k = 0 and - value.(BooleanValue).getValue() = true + value.asBooleanValue() = true or cmp instanceof CompareNEValueNumber and cmp.hasOperands(left, right) and k = 0 and - value.(BooleanValue).getValue() = false + value.asBooleanValue() = false } /** @@ -1556,35 +1556,33 @@ private module Cached { } /** Rearrange various simple comparisons into `op == k` form. */ - private predicate unary_simple_comparison_eq( - ValueNumber test, Operand op, int k, AbstractValue value - ) { - exists(CaseEdge case, SwitchConditionValueNumber condition | + private predicate unary_simple_comparison_eq(ValueNumber test, Operand op, int k, GuardValue value) { + exists(SwitchConditionValueNumber condition, CaseEdge edge | condition = test and op = condition.getExpressionOperand() and - case = value.(MatchValue).getCase() and - exists(condition.getSuccessor(case)) and - case.getValue().toInt() = k + value.asIntValue() = k and + edge.getValue().toInt() = k and + exists(condition.getSuccessor(edge)) ) or exists(Instruction const | int_value(const) = k | - value.(BooleanValue).getValue() = true and + value.asBooleanValue() = true and test.(CompareEQValueNumber).hasOperands(op, const.getAUse()) or - value.(BooleanValue).getValue() = false and + value.asBooleanValue() = false and test.(CompareNEValueNumber).hasOperands(op, const.getAUse()) ) or - exists(BooleanValue bv | + exists(GuardValue bv | bv = value and mayBranchOn(op.getDef()) and op = test.getAUse() | k = 0 and - bv.getValue() = false + bv.asBooleanValue() = false or k = 1 and - bv.getValue() = true + bv.asBooleanValue() = true ) } @@ -1603,7 +1601,7 @@ private module Cached { } private predicate complex_eq( - ValueNumber cmp, Operand left, Operand right, int k, boolean areEqual, AbstractValue value + ValueNumber cmp, Operand left, Operand right, int k, boolean areEqual, GuardValue value ) { sub_eq(cmp, left, right, k, areEqual, value) or @@ -1611,7 +1609,7 @@ private module Cached { } private predicate unary_complex_eq( - ValueNumber test, Operand op, int k, boolean areEqual, AbstractValue value + ValueNumber test, Operand op, int k, boolean areEqual, GuardValue value ) { unary_sub_eq(test, op, k, areEqual, value) or @@ -1626,11 +1624,11 @@ private module Cached { /** Holds if `left < right + k` evaluates to `isLt` given that test is `value`. */ cached predicate compares_lt( - ValueNumber test, Operand left, Operand right, int k, boolean isLt, AbstractValue value + ValueNumber test, Operand left, Operand right, int k, boolean isLt, GuardValue value ) { /* In the simple case, the test is the comparison, so isLt = testIsTrue */ simple_comparison_lt(test, left, right, k) and - value.(BooleanValue).getValue() = isLt + value.asBooleanValue() = isLt or complex_lt(test, left, right, k, isLt, value) or @@ -1638,15 +1636,15 @@ private module Cached { exists(boolean isGe | isLt = isGe.booleanNot() | compares_ge(test, left, right, k, isGe, value)) or /* (x is true => (left < right + k)) => (!x is false => (left < right + k)) */ - exists(AbstractValue dual | value = dual.getDualValue() | + exists(GuardValue dual | value = dual.getDualValue() | compares_lt(test.(LogicalNotValueNumber).getUnary(), left, right, k, isLt, dual) ) or compares_lt(test.(BuiltinExpectCallValueNumber).getCondition(), left, right, k, isLt, value) or // See argument for why this is correct in compares_eq - exists(Operand l, BooleanValue bv | - unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and + exists(Operand l, GuardValue bv | + unary_compares_eq(test, l, 0, bv.asBooleanValue().booleanNot(), value) and compares_lt(valueNumber(BooleanInstruction::get(l.getDef())), left, right, k, isLt, bv) ) @@ -1654,13 +1652,13 @@ private module Cached { /** Holds if `op < k` evaluates to `isLt` given that `test` evaluates to `value`. */ cached - predicate compares_lt(ValueNumber test, Operand op, int k, boolean isLt, AbstractValue value) { + predicate compares_lt(ValueNumber test, Operand op, int k, boolean isLt, GuardValue value) { unary_simple_comparison_lt(test, op, k, isLt, value) or complex_lt(test, op, k, isLt, value) or /* (x is true => (op < k)) => (!x is false => (op < k)) */ - exists(AbstractValue dual | value = dual.getDualValue() | + exists(GuardValue dual | value = dual.getDualValue() | compares_lt(test.(LogicalNotValueNumber).getUnary(), op, k, isLt, dual) ) or @@ -1673,8 +1671,8 @@ private module Cached { compares_lt(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, isLt, value) or // See argument for why this is correct in compares_eq - exists(Operand l, BooleanValue bv | - unary_compares_eq(test, l, 0, bv.getValue().booleanNot(), value) and + exists(Operand l, GuardValue bv | + unary_compares_eq(test, l, 0, bv.asBooleanValue().booleanNot(), value) and compares_lt(valueNumber(BooleanInstruction::get(l.getDef())), op, k, isLt, bv) ) @@ -1682,7 +1680,7 @@ private module Cached { /** `(a < b + k) => (b > a - k) => (b >= a + (1-k))` */ private predicate compares_ge( - ValueNumber test, Operand left, Operand right, int k, boolean isGe, AbstractValue value + ValueNumber test, Operand left, Operand right, int k, boolean isGe, GuardValue value ) { exists(int onemk | k = 1 - onemk | compares_lt(test, right, left, onemk, isGe, value)) } @@ -1708,34 +1706,32 @@ private module Cached { /** Rearrange various simple comparisons into `op < k` form. */ private predicate unary_simple_comparison_lt( - SwitchConditionValueNumber test, Operand op, int k, boolean isLt, AbstractValue value + SwitchConditionValueNumber test, Operand op, int k, boolean isLt, GuardValue value ) { - exists(CaseEdge case | + exists(string minValue, string maxValue | test.getExpressionOperand() = op and - case = value.(MatchValue).getCase() and - exists(test.getSuccessor(case)) and - case.getMaxValue() > case.getMinValue() + exists(test.getSuccessor(EdgeKind::caseEdge(minValue, maxValue))) and + value.asConstantValue().isRange(minValue, maxValue) and + minValue < maxValue | // op <= k => op < k - 1 isLt = true and - case.getMaxValue().toInt() = k - 1 + maxValue.toInt() = k - 1 or isLt = false and - case.getMinValue().toInt() = k + minValue.toInt() = k ) } private predicate complex_lt( - ValueNumber cmp, Operand left, Operand right, int k, boolean isLt, AbstractValue value + ValueNumber cmp, Operand left, Operand right, int k, boolean isLt, GuardValue value ) { sub_lt(cmp, left, right, k, isLt, value) or add_lt(cmp, left, right, k, isLt, value) } - private predicate complex_lt( - ValueNumber test, Operand left, int k, boolean isLt, AbstractValue value - ) { + private predicate complex_lt(ValueNumber test, Operand left, int k, boolean isLt, GuardValue value) { sub_lt(test, left, k, isLt, value) or add_lt(test, left, k, isLt, value) @@ -1744,7 +1740,7 @@ private module Cached { // left - x < right + c => left < right + (c+x) // left < (right - x) + c => left < right + (c-x) private predicate sub_lt( - ValueNumber cmp, Operand left, Operand right, int k, boolean isLt, AbstractValue value + ValueNumber cmp, Operand left, Operand right, int k, boolean isLt, GuardValue value ) { exists(SubInstruction lhs, int c, int x | compares_lt(cmp, lhs.getAUse(), right, c, isLt, value) and @@ -1775,7 +1771,7 @@ private module Cached { ) } - private predicate sub_lt(ValueNumber test, Operand left, int k, boolean isLt, AbstractValue value) { + private predicate sub_lt(ValueNumber test, Operand left, int k, boolean isLt, GuardValue value) { exists(SubInstruction lhs, int c, int x | compares_lt(test, lhs.getAUse(), c, isLt, value) and left = lhs.getLeftOperand() and @@ -1794,7 +1790,7 @@ private module Cached { // left + x < right + c => left < right + (c-x) // left < (right + x) + c => left < right + (c+x) private predicate add_lt( - ValueNumber cmp, Operand left, Operand right, int k, boolean isLt, AbstractValue value + ValueNumber cmp, Operand left, Operand right, int k, boolean isLt, GuardValue value ) { exists(AddInstruction lhs, int c, int x | compares_lt(cmp, lhs.getAUse(), right, c, isLt, value) and @@ -1837,7 +1833,7 @@ private module Cached { ) } - private predicate add_lt(ValueNumber test, Operand left, int k, boolean isLt, AbstractValue value) { + private predicate add_lt(ValueNumber test, Operand left, int k, boolean isLt, GuardValue value) { exists(AddInstruction lhs, int c, int x | compares_lt(test, lhs.getAUse(), c, isLt, value) and ( @@ -1862,7 +1858,7 @@ private module Cached { // left - x == right + c => left == right + (c+x) // left == (right - x) + c => left == right + (c-x) private predicate sub_eq( - ValueNumber cmp, Operand left, Operand right, int k, boolean areEqual, AbstractValue value + ValueNumber cmp, Operand left, Operand right, int k, boolean areEqual, GuardValue value ) { exists(SubInstruction lhs, int c, int x | compares_eq(cmp, lhs.getAUse(), right, c, areEqual, value) and @@ -1895,7 +1891,7 @@ private module Cached { // op - x == c => op == (c+x) private predicate unary_sub_eq( - ValueNumber test, Operand op, int k, boolean areEqual, AbstractValue value + ValueNumber test, Operand op, int k, boolean areEqual, GuardValue value ) { exists(SubInstruction sub, int c, int x | unary_compares_eq(test, sub.getAUse(), c, areEqual, value) and @@ -1915,7 +1911,7 @@ private module Cached { // left + x == right + c => left == right + (c-x) // left == (right + x) + c => left == right + (c+x) private predicate add_eq( - ValueNumber cmp, Operand left, Operand right, int k, boolean areEqual, AbstractValue value + ValueNumber cmp, Operand left, Operand right, int k, boolean areEqual, GuardValue value ) { exists(AddInstruction lhs, int c, int x | compares_eq(cmp, lhs.getAUse(), right, c, areEqual, value) and @@ -1960,7 +1956,7 @@ private module Cached { // left + x == right + c => left == right + (c-x) private predicate unary_add_eq( - ValueNumber test, Operand left, int k, boolean areEqual, AbstractValue value + ValueNumber test, Operand left, int k, boolean areEqual, GuardValue value ) { exists(AddInstruction lhs, int c, int x | unary_compares_eq(test, lhs.getAUse(), c, areEqual, value) and @@ -2003,7 +1999,7 @@ private import Cached * To find the specific guard that performs the comparison * use `IRGuards.comparesLt`. */ -predicate comparesLt(Operand left, Operand right, int k, boolean isLt, AbstractValue value) { +predicate comparesLt(Operand left, Operand right, int k, boolean isLt, GuardValue value) { compares_lt(_, left, right, k, isLt, value) } @@ -2014,6 +2010,6 @@ predicate comparesLt(Operand left, Operand right, int k, boolean isLt, AbstractV * To find the specific guard that performs the comparison * use `IRGuards.comparesEq`. */ -predicate comparesEq(Operand left, Operand right, int k, boolean isLt, AbstractValue value) { +predicate comparesEq(Operand left, Operand right, int k, boolean isLt, GuardValue value) { compares_eq(_, left, right, k, isLt, value) } From 9ed8b75c5d1218240a12b9a967a580e4c8b7a134 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 18 Sep 2025 10:07:32 +0100 Subject: [PATCH 11/35] C++: Add a few helper predicates on 'Definition' which the guards library needs. --- .../code/cpp/ir/dataflow/internal/SsaImpl.qll | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll index 002e0ca61bc9..47e36a0a1079 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll @@ -1163,6 +1163,49 @@ class Definition extends SsaImpl::Definition { ) } + /** + * Holds if this definition defines the parameter `p` upon entry into the + * enclosing function. + */ + pragma[nomagic] + predicate isParameterDefinition(Parameter p) { + this.getIndirectionIndex() = 0 and + getDefImpl(this).getValue().asInstruction().(InitializeParameterInstruction).getParameter() = p + } + + /** + * Holds if this definition defines the `indirectionIndex`'th indirection of + * parameter `p` upon entry into the enclosing function. + */ + pragma[nomagic] + predicate isIndirectParameterDefinition(Parameter p, int indirectionIndex) { + this.getIndirectionIndex() = indirectionIndex and + indirectionIndex > 0 and + getDefImpl(this).getValue().asInstruction().(InitializeParameterInstruction).getParameter() = p + } + + /** + * Holds if this definition defines the implicit `this` parameter upon entry into + * the enclosing member function. + */ + pragma[nomagic] + predicate isThisDefinition() { + this.getIndirectionIndex() = 0 and + getDefImpl(this).getValue().asInstruction().(InitializeParameterInstruction).hasIndex(-1) + } + + /** + * Holds if this definition defines the implicit `*this` parameter (i.e., the + * indirection of the `this` parameter) upon entry into the enclosing member + * function. + */ + pragma[nomagic] + predicate isIndirectThisDefinition(int indirectionIndex) { + this.getIndirectionIndex() = indirectionIndex and + indirectionIndex > 0 and + getDefImpl(this).getValue().asInstruction().(InitializeParameterInstruction).hasIndex(-1) + } + /** * Gets an `Operand` that represents an indirect use of this definition. * From 0b81fbbb2b89dbb26b02c27add51bc85443b809f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:42:15 +0100 Subject: [PATCH 12/35] C++: Fixup tests. --- cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql | 4 ++-- cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.ql | 2 +- cpp/ql/test/library-tests/controlflow/guards/GuardsControl.ql | 2 +- .../dataflow-tests/guard-condition-regression-test.ql | 2 +- cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.ql | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql index 0f147f9ea8d3..e1009307880c 100644 --- a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql @@ -23,7 +23,7 @@ query predicate astGuardsCompare(int startLine, string msg) { ) ) or - exists(AbstractValue value | + exists(GuardValue value | guard.comparesEq(left, k, true, value) and op = " == " or guard.comparesEq(left, k, false, value) and op = " != " @@ -95,7 +95,7 @@ query predicate irGuardsCompare(int startLine, string msg) { ) ) or - exists(AbstractValue value | + exists(GuardValue value | guard.comparesLt(left, k, true, value) and op = " < " or guard.comparesLt(left, k, false, value) and op = " >= " diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.ql b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.ql index 59996548113a..a925bf91407c 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.ql +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.ql @@ -27,7 +27,7 @@ where ) ) or - exists(AbstractValue value | + exists(GuardValue value | guard.comparesLt(left, k, true, value) and op = " < " or guard.comparesLt(left, k, false, value) and op = " >= " diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.ql b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.ql index 698b80a06a02..1d9282807bd1 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.ql +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.ql @@ -7,6 +7,6 @@ import cpp import semmle.code.cpp.controlflow.Guards -from GuardCondition guard, AbstractValue value, BasicBlock block +from GuardCondition guard, GuardValue value, BasicBlock block where guard.valueControls(block, value) select guard, value, block diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.ql index a21cd910a2ae..1218fe396c84 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.ql +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.ql @@ -17,7 +17,7 @@ module IRTestAllocationConfig implements DataFlow::ConfigSig { } predicate isBarrier(DataFlow::Node node) { - exists(GuardCondition gc | node.asExpr() = gc.getAChild*()) + exists(GuardCondition gc | node.asExpr() = gc.(Expr).getAChild*()) } } diff --git a/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.ql b/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.ql index 15b165a7de11..20610c55385c 100644 --- a/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.ql +++ b/cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.ql @@ -7,7 +7,7 @@ predicate instructionGuardChecks(IRGuardCondition gc, Instruction checked, boole exists(CallInstruction call | call.getStaticCallTarget().hasName("checkArgument") and checked = call.getAnArgument() and - gc.comparesEq(call.getAUse(), 0, false, any(BooleanValue bv | bv.getValue() = branch)) + gc.comparesEq(call.getAUse(), 0, false, any(GuardValue bv | bv.asBooleanValue() = branch)) ) } From 2dc783d91f1430bcd77a30d7401977b40ce8282f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:43:49 +0100 Subject: [PATCH 13/35] C++: Accept test changes. --- .../rangeanalysis/RangeAnalysis.expected | 1 - .../controlflow/guards-ir/tests.expected | 151 ++ .../controlflow/guards/Guards.expected | 1436 +++++++++++++++++ .../controlflow/guards/GuardsCompare.expected | 273 +++- .../controlflow/guards/GuardsControl.expected | 142 +- .../controlflow/guards/GuardsEnsure.expected | 70 + .../IncorrectCheckScanf.expected | 1 + .../MissingCheckScanf.expected | 3 - .../Critical/MissingCheckScanf/test.cpp | 2 +- 9 files changed, 2063 insertions(+), 16 deletions(-) diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected b/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected index 15125038d19c..abdb752ca69e 100644 --- a/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected +++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected @@ -60,7 +60,6 @@ | test.cpp:177:10:177:10 | Load: i | test.cpp:175:23:175:23 | ValueNumberBound | 1 | false | CompareLT: ... < ... | test.cpp:176:7:176:11 | test.cpp:176:7:176:11 | | test.cpp:179:10:179:10 | Load: i | test.cpp:175:23:175:23 | ValueNumberBound | 0 | true | CompareLT: ... < ... | test.cpp:176:7:176:11 | test.cpp:176:7:176:11 | | test.cpp:183:10:183:10 | Load: i | test.cpp:175:23:175:23 | ValueNumberBound | -1 | true | CompareLT: ... < ... | test.cpp:182:9:182:13 | test.cpp:182:9:182:13 | -| test.cpp:185:10:185:10 | Load: i | test.cpp:175:23:175:23 | ValueNumberBound | 0 | true | CompareLT: ... < ... | test.cpp:176:7:176:11 | test.cpp:176:7:176:11 | | test.cpp:187:10:187:10 | Store: i | test.cpp:175:23:175:23 | ValueNumberBound | 0 | false | CompareLT: ... < ... | test.cpp:182:9:182:13 | test.cpp:182:9:182:13 | | test.cpp:194:8:194:8 | Load: l | test.cpp:191:16:191:16 | ValueNumberBound | 0 | false | NoReason | file://:0:0:0:0 | file://:0:0:0:0 | | test.cpp:194:8:194:8 | Load: l | test.cpp:191:16:191:16 | ValueNumberBound | 0 | true | NoReason | file://:0:0:0:0 | file://:0:0:0:0 | diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected index 1d138afcbeac..900b65eb7bd8 100644 --- a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected @@ -425,7 +425,9 @@ astGuardsControl | test.c:126:7:126:7 | 1 | true | 131 | 132 | | test.c:126:7:126:7 | 1 | true | 134 | 123 | | test.c:126:7:126:28 | ... && ... | true | 126 | 128 | +| test.c:126:7:126:28 | ... && ... | true | 131 | 132 | | test.c:126:12:126:26 | call to test3_condition | true | 126 | 128 | +| test.c:126:12:126:26 | call to test3_condition | true | 131 | 132 | | test.c:131:7:131:7 | b | true | 131 | 132 | | test.c:137:7:137:7 | 0 | false | 142 | 136 | | test.c:146:7:146:8 | ! ... | true | 146 | 147 | @@ -832,11 +834,17 @@ astGuardsEnsure_const | test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 131 | 132 | | test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 134 | 123 | | test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 | | test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 126 | 128 | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 131 | 132 | | test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 131 | 132 | | test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 131 | 132 | | test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 | +| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 131 | 132 | | test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 | +| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | 131 | 132 | | test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | != | 0 | 131 | 132 | | test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | == | 1 | 131 | 132 | | test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | != | 1 | 142 | 136 | @@ -1139,13 +1147,21 @@ irGuardsCompare | 146 | x != 0 when CompareEQ: ! ... is false | | 146 | x == 0 when CompareEQ: ! ... is true | | 152 | x != 0 when CompareNE: x is true | +| 152 | x != 0 when Load: ... && ... is true | +| 152 | x != 0 when Phi: ... && ... is true | | 152 | x != 1 when CompareNE: x is false | | 152 | x == 0 when CompareNE: x is false | | 152 | x == 1 when CompareNE: x is true | +| 152 | x == 1 when Load: ... && ... is true | +| 152 | x == 1 when Phi: ... && ... is true | | 152 | y != 0 when CompareNE: y is true | +| 152 | y != 0 when Load: ... && ... is true | +| 152 | y != 0 when Phi: ... && ... is true | | 152 | y != 1 when CompareNE: y is false | | 152 | y == 0 when CompareNE: y is false | | 152 | y == 1 when CompareNE: y is true | +| 152 | y == 1 when Load: ... && ... is true | +| 152 | y == 1 when Phi: ... && ... is true | | 156 | ... + ... != x+0 when CompareEQ: ... == ... is false | | 156 | ... + ... == x+0 when CompareEQ: ... == ... is true | | 156 | ... == ... != 0 when CompareEQ: ... == ... is true | @@ -1211,9 +1227,14 @@ irGuardsCompare irGuardsControl | test.c:7:9:7:13 | CompareGT: ... > ... | false | 11 | 11 | | test.c:7:9:7:13 | CompareGT: ... > ... | true | 8 | 8 | +| test.c:7:9:7:13 | ConditionalBranch: ... > ... | false | 11 | 11 | +| test.c:7:9:7:13 | ConditionalBranch: ... > ... | true | 8 | 8 | | test.c:17:8:17:12 | CompareLT: ... < ... | true | 17 | 17 | | test.c:17:8:17:12 | CompareLT: ... < ... | true | 18 | 18 | +| test.c:17:8:17:12 | ConditionalBranch: ... < ... | true | 17 | 17 | +| test.c:17:8:17:12 | ConditionalBranch: ... < ... | true | 18 | 18 | | test.c:17:17:17:21 | CompareGT: ... > ... | true | 18 | 18 | +| test.c:17:17:17:21 | ConditionalBranch: ... > ... | true | 18 | 18 | | test.c:26:11:26:15 | CompareGT: ... > ... | false | 2 | 2 | | test.c:26:11:26:15 | CompareGT: ... > ... | false | 31 | 31 | | test.c:26:11:26:15 | CompareGT: ... > ... | false | 34 | 34 | @@ -1229,6 +1250,21 @@ irGuardsControl | test.c:26:11:26:15 | CompareGT: ... > ... | false | 59 | 59 | | test.c:26:11:26:15 | CompareGT: ... > ... | false | 62 | 62 | | test.c:26:11:26:15 | CompareGT: ... > ... | true | 27 | 27 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 2 | 2 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 31 | 31 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 34 | 34 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 35 | 35 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 39 | 39 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 42 | 42 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 43 | 43 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 45 | 45 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 46 | 46 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 52 | 52 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 56 | 56 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 58 | 58 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 59 | 59 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | false | 62 | 62 | +| test.c:26:11:26:15 | ConditionalBranch: ... > ... | true | 27 | 27 | | test.c:34:16:34:21 | CompareLT: ... < ... | false | 2 | 2 | | test.c:34:16:34:21 | CompareLT: ... < ... | false | 39 | 39 | | test.c:34:16:34:21 | CompareLT: ... < ... | false | 42 | 42 | @@ -1241,22 +1277,56 @@ irGuardsControl | test.c:34:16:34:21 | CompareLT: ... < ... | false | 59 | 59 | | test.c:34:16:34:21 | CompareLT: ... < ... | false | 62 | 62 | | test.c:34:16:34:21 | CompareLT: ... < ... | true | 35 | 35 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | false | 2 | 2 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | false | 39 | 39 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | false | 42 | 42 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | false | 43 | 43 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | false | 45 | 45 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | false | 46 | 46 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | false | 52 | 52 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | false | 56 | 56 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | false | 58 | 58 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | false | 59 | 59 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | false | 62 | 62 | +| test.c:34:16:34:21 | ConditionalBranch: ... < ... | true | 35 | 35 | +| test.c:42:16:42:21 | CompareLT: ... < ... | true | 2 | 2 | | test.c:42:16:42:21 | CompareLT: ... < ... | true | 43 | 43 | | test.c:42:16:42:21 | CompareLT: ... < ... | true | 45 | 45 | | test.c:42:16:42:21 | CompareLT: ... < ... | true | 46 | 46 | | test.c:42:16:42:21 | CompareLT: ... < ... | true | 52 | 52 | +| test.c:42:16:42:21 | ConditionalBranch: ... < ... | true | 2 | 2 | +| test.c:42:16:42:21 | ConditionalBranch: ... < ... | true | 43 | 43 | +| test.c:42:16:42:21 | ConditionalBranch: ... < ... | true | 45 | 45 | +| test.c:42:16:42:21 | ConditionalBranch: ... < ... | true | 46 | 46 | +| test.c:42:16:42:21 | ConditionalBranch: ... < ... | true | 52 | 52 | | test.c:44:12:44:16 | CompareGT: ... > ... | false | 52 | 52 | +| test.c:44:12:44:16 | CompareGT: ... > ... | true | 2 | 2 | | test.c:44:12:44:16 | CompareGT: ... > ... | true | 45 | 45 | | test.c:44:12:44:16 | CompareGT: ... > ... | true | 46 | 46 | +| test.c:44:12:44:16 | ConditionalBranch: ... > ... | false | 52 | 52 | +| test.c:44:12:44:16 | ConditionalBranch: ... > ... | true | 2 | 2 | +| test.c:44:12:44:16 | ConditionalBranch: ... > ... | true | 45 | 45 | +| test.c:44:12:44:16 | ConditionalBranch: ... > ... | true | 46 | 46 | +| test.c:45:16:45:20 | CompareGT: ... > ... | false | 2 | 2 | | test.c:45:16:45:20 | CompareGT: ... > ... | true | 46 | 46 | +| test.c:45:16:45:20 | ConditionalBranch: ... > ... | false | 2 | 2 | +| test.c:45:16:45:20 | ConditionalBranch: ... > ... | true | 46 | 46 | | test.c:58:9:58:14 | CompareEQ: ... == ... | false | 58 | 58 | | test.c:58:9:58:14 | CompareEQ: ... == ... | false | 62 | 62 | +| test.c:58:9:58:14 | ConditionalBranch: ... == ... | false | 58 | 58 | +| test.c:58:9:58:14 | ConditionalBranch: ... == ... | false | 62 | 62 | | test.c:58:19:58:23 | CompareLT: ... < ... | false | 62 | 62 | +| test.c:58:19:58:23 | ConditionalBranch: ... < ... | false | 62 | 62 | | test.c:75:9:75:14 | CompareEQ: ... == ... | false | 79 | 79 | | test.c:75:9:75:14 | CompareEQ: ... == ... | true | 76 | 76 | +| test.c:75:9:75:14 | ConditionalBranch: ... == ... | false | 79 | 79 | +| test.c:75:9:75:14 | ConditionalBranch: ... == ... | true | 76 | 76 | | test.c:85:8:85:13 | CompareEQ: ... == ... | true | 85 | 85 | | test.c:85:8:85:13 | CompareEQ: ... == ... | true | 86 | 86 | +| test.c:85:8:85:13 | ConditionalBranch: ... == ... | true | 85 | 85 | +| test.c:85:8:85:13 | ConditionalBranch: ... == ... | true | 86 | 86 | | test.c:85:18:85:23 | CompareNE: ... != ... | true | 86 | 86 | +| test.c:85:18:85:23 | ConditionalBranch: ... != ... | true | 86 | 86 | | test.c:94:11:94:16 | CompareNE: ... != ... | false | 70 | 70 | | test.c:94:11:94:16 | CompareNE: ... != ... | false | 99 | 99 | | test.c:94:11:94:16 | CompareNE: ... != ... | false | 102 | 102 | @@ -1266,40 +1336,89 @@ irGuardsControl | test.c:94:11:94:16 | CompareNE: ... != ... | false | 110 | 110 | | test.c:94:11:94:16 | CompareNE: ... != ... | false | 113 | 113 | | test.c:94:11:94:16 | CompareNE: ... != ... | true | 95 | 95 | +| test.c:94:11:94:16 | ConditionalBranch: ... != ... | false | 70 | 70 | +| test.c:94:11:94:16 | ConditionalBranch: ... != ... | false | 99 | 99 | +| test.c:94:11:94:16 | ConditionalBranch: ... != ... | false | 102 | 102 | +| test.c:94:11:94:16 | ConditionalBranch: ... != ... | false | 103 | 103 | +| test.c:94:11:94:16 | ConditionalBranch: ... != ... | false | 107 | 107 | +| test.c:94:11:94:16 | ConditionalBranch: ... != ... | false | 109 | 109 | +| test.c:94:11:94:16 | ConditionalBranch: ... != ... | false | 110 | 110 | +| test.c:94:11:94:16 | ConditionalBranch: ... != ... | false | 113 | 113 | +| test.c:94:11:94:16 | ConditionalBranch: ... != ... | true | 95 | 95 | | test.c:102:16:102:21 | CompareLT: ... < ... | false | 70 | 70 | | test.c:102:16:102:21 | CompareLT: ... < ... | false | 107 | 107 | | test.c:102:16:102:21 | CompareLT: ... < ... | false | 109 | 109 | | test.c:102:16:102:21 | CompareLT: ... < ... | false | 110 | 110 | | test.c:102:16:102:21 | CompareLT: ... < ... | false | 113 | 113 | | test.c:102:16:102:21 | CompareLT: ... < ... | true | 103 | 103 | +| test.c:102:16:102:21 | ConditionalBranch: ... < ... | false | 70 | 70 | +| test.c:102:16:102:21 | ConditionalBranch: ... < ... | false | 107 | 107 | +| test.c:102:16:102:21 | ConditionalBranch: ... < ... | false | 109 | 109 | +| test.c:102:16:102:21 | ConditionalBranch: ... < ... | false | 110 | 110 | +| test.c:102:16:102:21 | ConditionalBranch: ... < ... | false | 113 | 113 | +| test.c:102:16:102:21 | ConditionalBranch: ... < ... | true | 103 | 103 | | test.c:109:9:109:14 | CompareEQ: ... == ... | false | 109 | 109 | | test.c:109:9:109:14 | CompareEQ: ... == ... | false | 113 | 113 | +| test.c:109:9:109:14 | ConditionalBranch: ... == ... | false | 109 | 109 | +| test.c:109:9:109:14 | ConditionalBranch: ... == ... | false | 113 | 113 | | test.c:109:19:109:23 | CompareLT: ... < ... | false | 113 | 113 | +| test.c:109:19:109:23 | ConditionalBranch: ... < ... | false | 113 | 113 | +| test.c:126:7:126:7 | CompareNE: 1 | false | 123 | 123 | | test.c:126:7:126:7 | CompareNE: 1 | true | 126 | 126 | | test.c:126:7:126:7 | CompareNE: 1 | true | 127 | 127 | | test.c:126:7:126:7 | CompareNE: 1 | true | 131 | 131 | | test.c:126:7:126:7 | CompareNE: 1 | true | 132 | 132 | | test.c:126:7:126:7 | CompareNE: 1 | true | 134 | 134 | +| test.c:126:7:126:7 | ConditionalBranch: 1 | false | 123 | 123 | +| test.c:126:7:126:7 | ConditionalBranch: 1 | true | 126 | 126 | +| test.c:126:7:126:7 | ConditionalBranch: 1 | true | 127 | 127 | +| test.c:126:7:126:7 | ConditionalBranch: 1 | true | 131 | 131 | +| test.c:126:7:126:7 | ConditionalBranch: 1 | true | 132 | 132 | +| test.c:126:7:126:7 | ConditionalBranch: 1 | true | 134 | 134 | | test.c:126:12:126:26 | CompareNE: call to test3_condition | true | 127 | 127 | +| test.c:126:12:126:26 | CompareNE: call to test3_condition | true | 132 | 132 | +| test.c:126:12:126:26 | ConditionalBranch: call to test3_condition | true | 127 | 127 | +| test.c:126:12:126:26 | ConditionalBranch: call to test3_condition | true | 132 | 132 | | test.c:131:7:131:7 | CompareNE: b | true | 132 | 132 | +| test.c:131:7:131:7 | ConditionalBranch: b | true | 132 | 132 | | test.c:137:7:137:7 | CompareNE: 0 | false | 142 | 142 | +| test.c:137:7:137:7 | CompareNE: 0 | true | 136 | 136 | +| test.c:137:7:137:7 | ConditionalBranch: 0 | false | 142 | 142 | +| test.c:137:7:137:7 | ConditionalBranch: 0 | true | 136 | 136 | | test.c:146:7:146:8 | CompareEQ: ! ... | true | 147 | 147 | +| test.c:146:7:146:8 | ConditionalBranch: ! ... | true | 147 | 147 | | test.c:152:10:152:10 | CompareNE: x | true | 152 | 152 | +| test.c:152:10:152:10 | ConditionalBranch: x | true | 152 | 152 | | test.c:152:15:152:15 | CompareNE: y | true | 152 | 152 | +| test.c:152:15:152:15 | ConditionalBranch: y | true | 152 | 152 | | test.c:156:9:156:19 | CompareEQ: ... == ... | true | 156 | 157 | +| test.c:156:9:156:19 | ConditionalBranch: ... == ... | true | 156 | 157 | | test.c:159:9:159:19 | CompareEQ: ... == ... | true | 159 | 160 | +| test.c:159:9:159:19 | ConditionalBranch: ... == ... | true | 159 | 160 | | test.c:162:9:162:18 | CompareLT: ... < ... | true | 162 | 163 | +| test.c:162:9:162:18 | ConditionalBranch: ... < ... | true | 162 | 163 | | test.c:165:9:165:18 | CompareLT: ... < ... | true | 165 | 166 | +| test.c:165:9:165:18 | ConditionalBranch: ... < ... | true | 165 | 166 | | test.c:175:13:175:32 | CompareEQ: ... == ... | false | 175 | 175 | | test.c:175:13:175:32 | CompareEQ: ... == ... | true | 175 | 175 | +| test.c:175:13:175:32 | ConditionalBranch: ... == ... | false | 175 | 175 | +| test.c:175:13:175:32 | ConditionalBranch: ... == ... | true | 175 | 175 | | test.c:181:9:181:9 | CompareNE: x | false | 184 | 184 | | test.c:181:9:181:9 | CompareNE: x | true | 182 | 182 | +| test.c:181:9:181:9 | ConditionalBranch: x | false | 184 | 184 | +| test.c:181:9:181:9 | ConditionalBranch: x | true | 182 | 182 | | test.cpp:18:8:18:12 | CompareNE: (bool)... | true | 19 | 19 | +| test.cpp:18:8:18:12 | ConditionalBranch: (bool)... | true | 19 | 19 | | test.cpp:31:7:31:13 | CompareEQ: ... == ... | false | 34 | 34 | | test.cpp:31:7:31:13 | CompareEQ: ... == ... | true | 30 | 30 | | test.cpp:31:7:31:13 | CompareEQ: ... == ... | true | 32 | 32 | +| test.cpp:31:7:31:13 | ConditionalBranch: ... == ... | false | 34 | 34 | +| test.cpp:31:7:31:13 | ConditionalBranch: ... == ... | true | 30 | 30 | +| test.cpp:31:7:31:13 | ConditionalBranch: ... == ... | true | 32 | 32 | | test.cpp:42:13:42:20 | Call: call to getABool | true | 44 | 44 | | test.cpp:42:13:42:20 | Call: call to getABool | true | 45 | 45 | +| test.cpp:42:13:42:20 | ConditionalBranch: call to getABool | true | 44 | 44 | +| test.cpp:42:13:42:20 | ConditionalBranch: call to getABool | true | 45 | 45 | irGuardsEnsure | test.c:7:9:7:13 | CompareGT: ... > ... | test.c:7:9:7:9 | Load: x | < | test.c:7:13:7:13 | Constant: 0 | 1 | 11 | 11 | | test.c:7:9:7:13 | CompareGT: ... > ... | test.c:7:9:7:9 | Load: x | >= | test.c:7:13:7:13 | Constant: 0 | 1 | 8 | 8 | @@ -1365,22 +1484,28 @@ irGuardsEnsure | test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:20:34:21 | Constant: 10 | < | test.c:34:16:34:16 | Load: j | 1 | 59 | 59 | | test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:20:34:21 | Constant: 10 | < | test.c:34:16:34:16 | Load: j | 1 | 62 | 62 | | test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:20:34:21 | Constant: 10 | >= | test.c:34:16:34:16 | Load: j | 1 | 35 | 35 | +| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | test.c:42:20:42:21 | Constant: 10 | 0 | 2 | 2 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | test.c:42:20:42:21 | Constant: 10 | 0 | 43 | 43 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | test.c:42:20:42:21 | Constant: 10 | 0 | 45 | 45 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | test.c:42:20:42:21 | Constant: 10 | 0 | 46 | 46 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | test.c:42:20:42:21 | Constant: 10 | 0 | 52 | 52 | +| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:20:42:21 | Constant: 10 | >= | test.c:42:16:42:16 | Load: j | 1 | 2 | 2 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:20:42:21 | Constant: 10 | >= | test.c:42:16:42:16 | Load: j | 1 | 43 | 43 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:20:42:21 | Constant: 10 | >= | test.c:42:16:42:16 | Load: j | 1 | 45 | 45 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:20:42:21 | Constant: 10 | >= | test.c:42:16:42:16 | Load: j | 1 | 46 | 46 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:20:42:21 | Constant: 10 | >= | test.c:42:16:42:16 | Load: j | 1 | 52 | 52 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | < | test.c:44:16:44:16 | Constant: 0 | 1 | 52 | 52 | +| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | >= | test.c:44:16:44:16 | Constant: 0 | 1 | 2 | 2 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | >= | test.c:44:16:44:16 | Constant: 0 | 1 | 45 | 45 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | >= | test.c:44:16:44:16 | Constant: 0 | 1 | 46 | 46 | +| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:16:44:16 | Constant: 0 | < | test.c:44:12:44:12 | Load: z | 0 | 2 | 2 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:16:44:16 | Constant: 0 | < | test.c:44:12:44:12 | Load: z | 0 | 45 | 45 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:16:44:16 | Constant: 0 | < | test.c:44:12:44:12 | Load: z | 0 | 46 | 46 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:16:44:16 | Constant: 0 | >= | test.c:44:12:44:12 | Load: z | 0 | 52 | 52 | +| test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:16:45:16 | Load: y | < | test.c:45:20:45:20 | Constant: (long)... | 1 | 2 | 2 | | test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:16:45:16 | Load: y | >= | test.c:45:20:45:20 | Constant: (long)... | 1 | 46 | 46 | | test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:20:45:20 | Constant: (long)... | < | test.c:45:16:45:16 | Load: y | 0 | 46 | 46 | +| test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:20:45:20 | Constant: (long)... | >= | test.c:45:16:45:16 | Load: y | 0 | 2 | 2 | | test.c:58:9:58:14 | CompareEQ: ... == ... | test.c:58:9:58:9 | Load: x | != | test.c:58:14:58:14 | Constant: 0 | 0 | 58 | 58 | | test.c:58:9:58:14 | CompareEQ: ... == ... | test.c:58:9:58:9 | Load: x | != | test.c:58:14:58:14 | Constant: 0 | 0 | 62 | 62 | | test.c:58:9:58:14 | CompareEQ: ... == ... | test.c:58:14:58:14 | Constant: 0 | != | test.c:58:9:58:9 | Load: x | 0 | 58 | 58 | @@ -1451,10 +1576,16 @@ irGuardsEnsure | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | Constant: 1 | != | test.c:126:7:126:7 | Constant: 1 | 0 | 132 | 132 | | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | Constant: 1 | != | test.c:126:7:126:7 | Constant: 1 | 0 | 134 | 134 | | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | Constant: 1 | != | test.c:126:7:126:7 | Constant: 1 | 0 | 134 | 134 | +| test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | Constant: 1 | == | test.c:126:7:126:7 | Constant: 1 | 0 | 123 | 123 | +| test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | Constant: 1 | == | test.c:126:7:126:7 | Constant: 1 | 0 | 123 | 123 | | test.c:126:12:126:26 | CompareNE: call to test3_condition | test.c:126:12:126:26 | Call: call to test3_condition | != | test.c:126:12:126:26 | Constant: call to test3_condition | 0 | 127 | 127 | +| test.c:126:12:126:26 | CompareNE: call to test3_condition | test.c:126:12:126:26 | Call: call to test3_condition | != | test.c:126:12:126:26 | Constant: call to test3_condition | 0 | 132 | 132 | | test.c:126:12:126:26 | CompareNE: call to test3_condition | test.c:126:12:126:26 | Constant: call to test3_condition | != | test.c:126:12:126:26 | Call: call to test3_condition | 0 | 127 | 127 | +| test.c:126:12:126:26 | CompareNE: call to test3_condition | test.c:126:12:126:26 | Constant: call to test3_condition | != | test.c:126:12:126:26 | Call: call to test3_condition | 0 | 132 | 132 | | test.c:131:7:131:7 | CompareNE: b | test.c:131:7:131:7 | Constant: b | != | test.c:131:7:131:7 | Load: b | 0 | 132 | 132 | | test.c:131:7:131:7 | CompareNE: b | test.c:131:7:131:7 | Load: b | != | test.c:131:7:131:7 | Constant: b | 0 | 132 | 132 | +| test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | Constant: 0 | != | test.c:137:7:137:7 | Constant: 0 | 0 | 136 | 136 | +| test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | Constant: 0 | != | test.c:137:7:137:7 | Constant: 0 | 0 | 136 | 136 | | test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | Constant: 0 | == | test.c:137:7:137:7 | Constant: 0 | 0 | 142 | 142 | | test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | Constant: 0 | == | test.c:137:7:137:7 | Constant: 0 | 0 | 142 | 142 | | test.c:146:7:146:8 | CompareEQ: ! ... | test.c:146:7:146:8 | Constant: ! ... | == | test.c:146:8:146:8 | Load: x | 0 | 147 | 147 | @@ -1592,29 +1723,38 @@ irGuardsEnsure_const | test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:21 | CompareLT: ... < ... | == | 0 | 59 | 59 | | test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:21 | CompareLT: ... < ... | == | 0 | 62 | 62 | | test.c:34:16:34:21 | CompareLT: ... < ... | test.c:34:16:34:21 | CompareLT: ... < ... | == | 1 | 35 | 35 | +| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | 10 | 2 | 2 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | 10 | 43 | 43 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | 10 | 45 | 45 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | 10 | 46 | 46 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:16 | Load: j | < | 10 | 52 | 52 | +| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:21 | CompareLT: ... < ... | != | 0 | 2 | 2 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:21 | CompareLT: ... < ... | != | 0 | 43 | 43 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:21 | CompareLT: ... < ... | != | 0 | 45 | 45 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:21 | CompareLT: ... < ... | != | 0 | 46 | 46 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:21 | CompareLT: ... < ... | != | 0 | 52 | 52 | +| test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:21 | CompareLT: ... < ... | == | 1 | 2 | 2 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:21 | CompareLT: ... < ... | == | 1 | 43 | 43 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:21 | CompareLT: ... < ... | == | 1 | 45 | 45 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:21 | CompareLT: ... < ... | == | 1 | 46 | 46 | | test.c:42:16:42:21 | CompareLT: ... < ... | test.c:42:16:42:21 | CompareLT: ... < ... | == | 1 | 52 | 52 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | < | 1 | 52 | 52 | +| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | >= | 1 | 2 | 2 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | >= | 1 | 45 | 45 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:12 | Load: z | >= | 1 | 46 | 46 | +| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:16 | CompareGT: ... > ... | != | 0 | 2 | 2 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:16 | CompareGT: ... > ... | != | 0 | 45 | 45 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:16 | CompareGT: ... > ... | != | 0 | 46 | 46 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:16 | CompareGT: ... > ... | != | 1 | 52 | 52 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:16 | CompareGT: ... > ... | == | 0 | 52 | 52 | +| test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:16 | CompareGT: ... > ... | == | 1 | 2 | 2 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:16 | CompareGT: ... > ... | == | 1 | 45 | 45 | | test.c:44:12:44:16 | CompareGT: ... > ... | test.c:44:12:44:16 | CompareGT: ... > ... | == | 1 | 46 | 46 | +| test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:16:45:16 | Load: y | < | 1 | 2 | 2 | | test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:16:45:16 | Load: y | >= | 1 | 46 | 46 | | test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:16:45:20 | CompareGT: ... > ... | != | 0 | 46 | 46 | +| test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:16:45:20 | CompareGT: ... > ... | != | 1 | 2 | 2 | +| test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:16:45:20 | CompareGT: ... > ... | == | 0 | 2 | 2 | | test.c:45:16:45:20 | CompareGT: ... > ... | test.c:45:16:45:20 | CompareGT: ... > ... | == | 1 | 46 | 46 | | test.c:58:9:58:14 | CompareEQ: ... == ... | test.c:58:9:58:9 | Load: x | != | 0 | 58 | 58 | | test.c:58:9:58:14 | CompareEQ: ... == ... | test.c:58:9:58:9 | Load: x | != | 0 | 62 | 62 | @@ -1711,6 +1851,8 @@ irGuardsEnsure_const | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | CompareNE: 1 | != | 0 | 131 | 131 | | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | CompareNE: 1 | != | 0 | 132 | 132 | | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | CompareNE: 1 | != | 0 | 134 | 134 | +| test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | CompareNE: 1 | != | 1 | 123 | 123 | +| test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | CompareNE: 1 | == | 0 | 123 | 123 | | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | CompareNE: 1 | == | 1 | 126 | 126 | | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | CompareNE: 1 | == | 1 | 127 | 127 | | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | CompareNE: 1 | == | 1 | 131 | 131 | @@ -1726,14 +1868,23 @@ irGuardsEnsure_const | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | Constant: 1 | != | 1 | 131 | 131 | | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | Constant: 1 | != | 1 | 132 | 132 | | test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | Constant: 1 | != | 1 | 134 | 134 | +| test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | Constant: 1 | == | 0 | 123 | 123 | +| test.c:126:7:126:7 | CompareNE: 1 | test.c:126:7:126:7 | Constant: 1 | == | 1 | 123 | 123 | | test.c:126:12:126:26 | CompareNE: call to test3_condition | test.c:126:12:126:26 | Call: call to test3_condition | != | 0 | 127 | 127 | +| test.c:126:12:126:26 | CompareNE: call to test3_condition | test.c:126:12:126:26 | Call: call to test3_condition | != | 0 | 132 | 132 | | test.c:126:12:126:26 | CompareNE: call to test3_condition | test.c:126:12:126:26 | CompareNE: call to test3_condition | != | 0 | 127 | 127 | +| test.c:126:12:126:26 | CompareNE: call to test3_condition | test.c:126:12:126:26 | CompareNE: call to test3_condition | != | 0 | 132 | 132 | | test.c:126:12:126:26 | CompareNE: call to test3_condition | test.c:126:12:126:26 | CompareNE: call to test3_condition | == | 1 | 127 | 127 | +| test.c:126:12:126:26 | CompareNE: call to test3_condition | test.c:126:12:126:26 | CompareNE: call to test3_condition | == | 1 | 132 | 132 | | test.c:131:7:131:7 | CompareNE: b | test.c:131:7:131:7 | CompareNE: b | != | 0 | 132 | 132 | | test.c:131:7:131:7 | CompareNE: b | test.c:131:7:131:7 | CompareNE: b | == | 1 | 132 | 132 | | test.c:131:7:131:7 | CompareNE: b | test.c:131:7:131:7 | Load: b | != | 0 | 132 | 132 | +| test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | CompareNE: 0 | != | 0 | 136 | 136 | | test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | CompareNE: 0 | != | 1 | 142 | 142 | | test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | CompareNE: 0 | == | 0 | 142 | 142 | +| test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | CompareNE: 0 | == | 1 | 136 | 136 | +| test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | Constant: 0 | != | 0 | 136 | 136 | +| test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | Constant: 0 | != | 0 | 136 | 136 | | test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | Constant: 0 | == | 0 | 142 | 142 | | test.c:137:7:137:7 | CompareNE: 0 | test.c:137:7:137:7 | Constant: 0 | == | 0 | 142 | 142 | | test.c:146:7:146:8 | CompareEQ: ! ... | test.c:146:7:146:8 | CompareEQ: ! ... | != | 0 | 147 | 147 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected index 70290c7e2260..d26dd740e64e 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected @@ -1,108 +1,1544 @@ +| file://:0:0:0:0 | | +| file://:0:0:0:0 | & | +| file://:0:0:0:0 | && | +| file://:0:0:0:0 | (global namespace) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 1) | +| file://:0:0:0:0 | ..()(..) | +| file://:0:0:0:0 | ..()(..) | +| file://:0:0:0:0 | ..()(..) | +| file://:0:0:0:0 | ..()(..) | +| file://:0:0:0:0 | ..()(..) | +| file://:0:0:0:0 | ..()(..) | +| file://:0:0:0:0 | ..()(..) | +| file://:0:0:0:0 | ..()(..) | +| file://:0:0:0:0 | ..()(..) | +| file://:0:0:0:0 | ..()(..) | +| file://:0:0:0:0 | ..(*)(..) | +| file://:0:0:0:0 | ..(*)(..) | +| file://:0:0:0:0 | ..(*)(..) | +| file://:0:0:0:0 | ..(*)(..) | +| file://:0:0:0:0 | ..(*)(..) | +| file://:0:0:0:0 | ..(*)(..) | +| file://:0:0:0:0 | ..(*)(..) | +| file://:0:0:0:0 | ..(*)(..) | +| file://:0:0:0:0 | ..(*)(..) | +| file://:0:0:0:0 | ..(*)(..) | +| file://:0:0:0:0 | ../../../library-tests | +| file://:0:0:0:0 | ../../controlflow | +| file://:0:0:0:0 | ../guards | +| file://:0:0:0:0 | / | +| file://:0:0:0:0 | /Users | +| file://:0:0:0:0 | /Users/mathias | +| file://:0:0:0:0 | /Users/mathias/semmle-code | +| file://:0:0:0:0 | /Users/mathias/semmle-code/ql | +| file://:0:0:0:0 | /Users/mathias/semmle-code/ql/cpp | +| file://:0:0:0:0 | /Users/mathias/semmle-code/ql/cpp/ql | +| file://:0:0:0:0 | /Users/mathias/semmle-code/ql/cpp/ql/test | +| file://:0:0:0:0 | Error & | +| file://:0:0:0:0 | Error && | +| file://:0:0:0:0 | Error * | +| file://:0:0:0:0 | Mystruct & | +| file://:0:0:0:0 | Mystruct && | +| file://:0:0:0:0 | X & | +| file://:0:0:0:0 | X && | +| file://:0:0:0:0 | X * | +| file://:0:0:0:0 | Y & | +| file://:0:0:0:0 | Y && | +| file://:0:0:0:0 | Y * | +| file://:0:0:0:0 | _Complex _Float16 | +| file://:0:0:0:0 | _Complex _Float32 | +| file://:0:0:0:0 | _Complex _Float32x | +| file://:0:0:0:0 | _Complex _Float64 | +| file://:0:0:0:0 | _Complex _Float64x | +| file://:0:0:0:0 | _Complex _Float128 | +| file://:0:0:0:0 | _Complex __bf16 | +| file://:0:0:0:0 | _Complex __float128 | +| file://:0:0:0:0 | _Complex __fp16 | +| file://:0:0:0:0 | _Complex double | +| file://:0:0:0:0 | _Complex float | +| file://:0:0:0:0 | _Complex long double | +| file://:0:0:0:0 | _Complex std::float16_t | +| file://:0:0:0:0 | _Decimal32 | +| file://:0:0:0:0 | _Decimal64 | +| file://:0:0:0:0 | _Decimal128 | +| file://:0:0:0:0 | _Float16 | +| file://:0:0:0:0 | _Float32 | +| file://:0:0:0:0 | _Float32x | +| file://:0:0:0:0 | _Float64 | +| file://:0:0:0:0 | _Float64x | +| file://:0:0:0:0 | _Float128 | +| file://:0:0:0:0 | _Imaginary double | +| file://:0:0:0:0 | _Imaginary float | +| file://:0:0:0:0 | _Imaginary long double | +| file://:0:0:0:0 | __SVCount_t | +| file://:0:0:0:0 | __bf16 | +| file://:0:0:0:0 | __block | +| file://:0:0:0:0 | __builtin_expect | +| file://:0:0:0:0 | __float128 | +| file://:0:0:0:0 | __fp16 | +| file://:0:0:0:0 | __int128 | +| file://:0:0:0:0 | __interface | +| file://:0:0:0:0 | __mfp8 | +| file://:0:0:0:0 | __ptr32 | +| file://:0:0:0:0 | __ptr64 | +| file://:0:0:0:0 | __sptr | +| file://:0:0:0:0 | __super | +| file://:0:0:0:0 | __uptr | +| file://:0:0:0:0 | __va_list_tag | +| file://:0:0:0:0 | __va_list_tag & | +| file://:0:0:0:0 | __va_list_tag && | +| file://:0:0:0:0 | abstract | +| file://:0:0:0:0 | atomic | +| file://:0:0:0:0 | auto | +| file://:0:0:0:0 | auto | +| file://:0:0:0:0 | bool | +| file://:0:0:0:0 | bool & | +| file://:0:0:0:0 | c_linkage | +| file://:0:0:0:0 | cdecl | +| file://:0:0:0:0 | char | +| file://:0:0:0:0 | char8_t | +| file://:0:0:0:0 | char16_t | +| file://:0:0:0:0 | char32_t | +| file://:0:0:0:0 | char * | +| file://:0:0:0:0 | clrcall | +| file://:0:0:0:0 | const | +| file://:0:0:0:0 | const Error | +| file://:0:0:0:0 | const Error & | +| file://:0:0:0:0 | const Mystruct | +| file://:0:0:0:0 | const Mystruct & | +| file://:0:0:0:0 | const X | +| file://:0:0:0:0 | const X & | +| file://:0:0:0:0 | const X * | +| file://:0:0:0:0 | const Y | +| file://:0:0:0:0 | const Y & | +| file://:0:0:0:0 | const Y * | +| file://:0:0:0:0 | const __va_list_tag | +| file://:0:0:0:0 | const __va_list_tag & | +| file://:0:0:0:0 | declaration of (unnamed parameter 0) | +| file://:0:0:0:0 | declaration of (unnamed parameter 0) | +| file://:0:0:0:0 | declaration of (unnamed parameter 0) | +| file://:0:0:0:0 | declaration of (unnamed parameter 0) | +| file://:0:0:0:0 | declaration of (unnamed parameter 0) | +| file://:0:0:0:0 | declaration of (unnamed parameter 0) | +| file://:0:0:0:0 | declaration of (unnamed parameter 0) | +| file://:0:0:0:0 | declaration of (unnamed parameter 0) | +| file://:0:0:0:0 | declaration of (unnamed parameter 0) | +| file://:0:0:0:0 | declaration of (unnamed parameter 0) | +| file://:0:0:0:0 | declared_constexpr | +| file://:0:0:0:0 | declared_constinit | +| file://:0:0:0:0 | declared_virtual | +| file://:0:0:0:0 | decltype(nullptr) | +| file://:0:0:0:0 | definition of fp_offset | +| file://:0:0:0:0 | definition of gp_offset | +| file://:0:0:0:0 | definition of overflow_arg_area | +| file://:0:0:0:0 | definition of reg_save_area | +| file://:0:0:0:0 | dllexport | +| file://:0:0:0:0 | dllimport | +| file://:0:0:0:0 | double | +| file://:0:0:0:0 | error | +| file://:0:0:0:0 | explicit | +| file://:0:0:0:0 | extern | +| file://:0:0:0:0 | far | +| file://:0:0:0:0 | fastcall | +| file://:0:0:0:0 | final | +| file://:0:0:0:0 | float | +| file://:0:0:0:0 | forceinline | +| file://:0:0:0:0 | fp_offset | +| file://:0:0:0:0 | gp_offset | +| file://:0:0:0:0 | has_trailing_return_type | +| file://:0:0:0:0 | implicit_int | +| file://:0:0:0:0 | inline | +| file://:0:0:0:0 | int | +| file://:0:0:0:0 | is_consteval | +| file://:0:0:0:0 | is_constexpr | +| file://:0:0:0:0 | is_thread_local | +| file://:0:0:0:0 | long | +| file://:0:0:0:0 | long double | +| file://:0:0:0:0 | long long | +| file://:0:0:0:0 | microsoft_inline | +| file://:0:0:0:0 | naked | +| file://:0:0:0:0 | near | +| file://:0:0:0:0 | noalias | +| file://:0:0:0:0 | noinline | +| file://:0:0:0:0 | nonnull | +| file://:0:0:0:0 | noreturn | +| file://:0:0:0:0 | nothrow | +| file://:0:0:0:0 | novtable | +| file://:0:0:0:0 | null_unspecified | +| file://:0:0:0:0 | nullable | +| file://:0:0:0:0 | operator delete | +| file://:0:0:0:0 | operator new | +| file://:0:0:0:0 | operator= | +| file://:0:0:0:0 | operator= | +| file://:0:0:0:0 | optional | +| file://:0:0:0:0 | overflow_arg_area | +| file://:0:0:0:0 | override | +| file://:0:0:0:0 | private | +| file://:0:0:0:0 | protected | +| file://:0:0:0:0 | public | +| file://:0:0:0:0 | pure | +| file://:0:0:0:0 | reg_save_area | +| file://:0:0:0:0 | register | +| file://:0:0:0:0 | restrict | +| file://:0:0:0:0 | sealed | +| file://:0:0:0:0 | selectany | +| file://:0:0:0:0 | short | +| file://:0:0:0:0 | signed __int128 | +| file://:0:0:0:0 | signed char | +| file://:0:0:0:0 | signed int | +| file://:0:0:0:0 | signed long | +| file://:0:0:0:0 | signed long long | +| file://:0:0:0:0 | signed short | +| file://:0:0:0:0 | static | +| file://:0:0:0:0 | std::float16_t | +| file://:0:0:0:0 | stdcall | +| file://:0:0:0:0 | thiscall | +| file://:0:0:0:0 | thread | +| file://:0:0:0:0 | unaligned | +| file://:0:0:0:0 | unknown | +| file://:0:0:0:0 | unsigned __int128 | +| file://:0:0:0:0 | unsigned char | +| file://:0:0:0:0 | unsigned int | +| file://:0:0:0:0 | unsigned long | +| file://:0:0:0:0 | unsigned long long | +| file://:0:0:0:0 | unsigned short | +| file://:0:0:0:0 | varargs | +| file://:0:0:0:0 | vectorcall | +| file://:0:0:0:0 | virtual | +| file://:0:0:0:0 | void | +| file://:0:0:0:0 | void * | +| file://:0:0:0:0 | volatile | +| file://:0:0:0:0 | wchar_t | +| test.c:0:0:0:0 | test.c | +| test.c:2:5:2:8 | definition of test | +| test.c:2:5:2:8 | test | +| test.c:2:14:2:14 | definition of x | +| test.c:2:14:2:14 | x | +| test.c:2:21:2:21 | definition of w | +| test.c:2:21:2:21 | w | +| test.c:2:28:2:28 | definition of z | +| test.c:2:28:2:28 | z | +| test.c:2:31:67:1 | { ... } | +| test.c:3:5:3:10 | declaration | +| test.c:3:9:3:9 | definition of j | +| test.c:3:9:3:9 | j | +| test.c:4:5:4:16 | declaration | +| test.c:4:10:4:10 | definition of y | +| test.c:4:10:4:10 | y | +| test.c:4:13:4:15 | initializer for y | +| test.c:4:14:4:15 | 50 | +| test.c:4:14:4:15 | (long)... | +| test.c:6:5:6:24 | // simple comparison | +| test.c:7:5:12:5 | if (...) ... | +| test.c:7:9:7:9 | x | | test.c:7:9:7:13 | ... > ... | +| test.c:7:13:7:13 | 0 | +| test.c:7:16:10:5 | { ... } | +| test.c:8:9:8:9 | y | +| test.c:8:9:8:14 | ... = ... | +| test.c:8:9:8:15 | ExprStmt | +| test.c:8:13:8:14 | 20 | +| test.c:8:13:8:14 | (long)... | +| test.c:9:9:9:9 | z | +| test.c:9:9:9:14 | ... = ... | +| test.c:9:9:9:15 | ExprStmt | +| test.c:9:13:9:14 | 10 | +| test.c:10:12:12:5 | { ... } | +| test.c:11:9:11:9 | y | +| test.c:11:9:11:14 | ... = ... | +| test.c:11:9:11:15 | ExprStmt | +| test.c:11:13:11:14 | 30 | +| test.c:11:13:11:14 | (long)... | +| test.c:14:5:14:5 | z | +| test.c:14:5:14:13 | ... = ... | +| test.c:14:5:14:14 | ExprStmt | +| test.c:14:9:14:9 | (long)... | +| test.c:14:9:14:9 | x | +| test.c:14:9:14:13 | (int)... | +| test.c:14:9:14:13 | ... + ... | +| test.c:14:13:14:13 | y | +| test.c:16:5:16:19 | // More complex | +| test.c:17:5:20:15 | if (...) ... | +| test.c:17:8:17:8 | x | | test.c:17:8:17:12 | ... < ... | | test.c:17:8:17:21 | ... && ... | +| test.c:17:12:17:12 | 0 | +| test.c:17:17:17:17 | y | | test.c:17:17:17:21 | ... > ... | +| test.c:17:21:17:21 | 1 | +| test.c:17:21:17:21 | (long)... | +| test.c:18:9:18:9 | y | +| test.c:18:9:18:14 | ... = ... | +| test.c:18:9:18:15 | ExprStmt | +| test.c:18:13:18:14 | 40 | +| test.c:18:13:18:14 | (long)... | +| test.c:20:9:20:9 | y | +| test.c:20:9:20:14 | ... = ... | +| test.c:20:9:20:15 | ExprStmt | +| test.c:20:13:20:14 | 20 | +| test.c:20:13:20:14 | (long)... | +| test.c:20:18:20:111 | /* The && expression does not control this block as the x<0 expression jumps here if false. */ | +| test.c:23:5:23:5 | z | +| test.c:23:5:23:10 | ... = ... | +| test.c:23:5:23:11 | ExprStmt | +| test.c:23:9:23:10 | 10 | +| test.c:25:5:25:17 | // while loop | +| test.c:26:5:29:5 | while (...) ... | +| test.c:26:11:26:11 | x | | test.c:26:11:26:15 | ... > ... | +| test.c:26:15:26:15 | 0 | +| test.c:26:18:29:5 | { ... } | +| test.c:27:9:27:9 | y | +| test.c:27:9:27:14 | ... = ... | +| test.c:27:9:27:15 | ExprStmt | +| test.c:27:13:27:14 | 10 | +| test.c:27:13:27:14 | (long)... | +| test.c:28:9:28:9 | x | +| test.c:28:9:28:11 | ... -- | +| test.c:28:9:28:12 | ExprStmt | +| test.c:31:5:31:5 | z | +| test.c:31:5:31:10 | ... += ... | +| test.c:31:5:31:11 | ExprStmt | +| test.c:31:10:31:10 | y | +| test.c:33:5:33:15 | // for loop | +| test.c:34:5:37:5 | for(...;...;...) ... | +| test.c:34:9:34:9 | j | +| test.c:34:9:34:13 | ... = ... | +| test.c:34:9:34:14 | ExprStmt | +| test.c:34:13:34:13 | 0 | +| test.c:34:16:34:16 | j | | test.c:34:16:34:21 | ... < ... | +| test.c:34:20:34:21 | 10 | +| test.c:34:24:34:24 | j | +| test.c:34:24:34:26 | ... ++ | +| test.c:34:29:37:5 | { ... } | +| test.c:35:9:35:9 | y | +| test.c:35:9:35:13 | ... = ... | +| test.c:35:9:35:14 | ExprStmt | +| test.c:35:13:35:13 | 0 | +| test.c:35:13:35:13 | (long)... | +| test.c:36:9:36:9 | w | +| test.c:36:9:36:14 | ... = ... | +| test.c:36:9:36:15 | ExprStmt | +| test.c:36:13:36:14 | 10 | +| test.c:39:5:39:5 | z | +| test.c:39:5:39:10 | ... += ... | +| test.c:39:5:39:11 | ExprStmt | +| test.c:39:10:39:10 | w | +| test.c:41:5:41:26 | // nested control flow | +| test.c:42:5:42:5 | label ...: | +| test.c:42:5:42:5 | { ... } | +| test.c:42:5:56:5 | for(...;...;...) ... | +| test.c:42:9:42:9 | j | +| test.c:42:9:42:13 | ... = ... | +| test.c:42:9:42:14 | ExprStmt | +| test.c:42:13:42:13 | 0 | +| test.c:42:16:42:16 | j | | test.c:42:16:42:21 | ... < ... | +| test.c:42:20:42:21 | 10 | +| test.c:42:24:42:24 | j | +| test.c:42:24:42:26 | ... ++ | +| test.c:42:29:56:5 | { ... } | +| test.c:43:9:43:9 | y | +| test.c:43:9:43:14 | ... = ... | +| test.c:43:9:43:15 | ExprStmt | +| test.c:43:13:43:14 | 30 | +| test.c:43:13:43:14 | (long)... | +| test.c:44:9:54:9 | if (...) ... | +| test.c:44:12:44:12 | z | | test.c:44:12:44:16 | ... > ... | +| test.c:44:16:44:16 | 0 | +| test.c:45:13:50:13 | if (...) ... | +| test.c:45:16:45:16 | y | | test.c:45:16:45:20 | ... > ... | +| test.c:45:20:45:20 | 0 | +| test.c:45:20:45:20 | (long)... | +| test.c:45:23:48:13 | { ... } | +| test.c:46:17:46:17 | w | +| test.c:46:17:46:21 | ... = ... | +| test.c:46:17:46:22 | ExprStmt | +| test.c:46:21:46:21 | 0 | +| test.c:47:17:47:22 | break; | +| test.c:48:20:50:13 | { ... } | +| test.c:49:17:49:17 | w | +| test.c:49:17:49:22 | ... = ... | +| test.c:49:17:49:23 | ExprStmt | +| test.c:49:21:49:22 | 20 | +| test.c:51:14:54:9 | { ... } | +| test.c:52:13:52:13 | w | +| test.c:52:13:52:18 | ... = ... | +| test.c:52:13:52:19 | ExprStmt | +| test.c:52:17:52:18 | 10 | +| test.c:53:13:53:21 | continue; | +| test.c:55:9:55:9 | x | +| test.c:55:9:55:13 | ... = ... | +| test.c:55:9:55:14 | ExprStmt | +| test.c:55:13:55:13 | 0 | +| test.c:56:5:56:5 | label ...: | +| test.c:58:5:62:17 | if (...) ... | +| test.c:58:9:58:9 | x | | test.c:58:9:58:14 | ... == ... | | test.c:58:9:58:23 | ... \|\| ... | +| test.c:58:14:58:14 | 0 | +| test.c:58:19:58:19 | y | | test.c:58:19:58:23 | ... < ... | +| test.c:58:23:58:23 | 0 | +| test.c:58:23:58:23 | (long)... | +| test.c:58:26:61:5 | { ... } | +| test.c:59:9:59:9 | y | +| test.c:59:9:59:14 | ... = ... | +| test.c:59:9:59:15 | ExprStmt | +| test.c:59:13:59:14 | 60 | +| test.c:59:13:59:14 | (long)... | +| test.c:60:9:60:9 | z | +| test.c:60:9:60:14 | ... = ... | +| test.c:60:9:60:15 | ExprStmt | +| test.c:60:13:60:14 | 10 | +| test.c:62:9:62:17 | return ... | +| test.c:62:16:62:16 | z | +| test.c:64:5:64:5 | z | +| test.c:64:5:64:10 | ... += ... | +| test.c:64:5:64:11 | ExprStmt | +| test.c:64:10:64:10 | x | +| test.c:66:5:66:13 | return ... | +| test.c:66:12:66:12 | 0 | +| test.c:70:5:70:9 | definition of test2 | +| test.c:70:5:70:9 | test2 | +| test.c:70:15:70:15 | definition of x | +| test.c:70:15:70:15 | x | +| test.c:70:22:70:22 | definition of w | +| test.c:70:22:70:22 | w | +| test.c:70:29:70:29 | definition of z | +| test.c:70:29:70:29 | z | +| test.c:70:32:118:1 | { ... } | +| test.c:71:5:71:10 | declaration | +| test.c:71:9:71:9 | definition of j | +| test.c:71:9:71:9 | j | +| test.c:72:5:72:16 | declaration | +| test.c:72:10:72:10 | definition of y | +| test.c:72:10:72:10 | y | +| test.c:72:13:72:15 | initializer for y | +| test.c:72:14:72:15 | 50 | +| test.c:72:14:72:15 | (long)... | +| test.c:74:5:74:24 | // simple comparison | +| test.c:75:5:80:5 | if (...) ... | +| test.c:75:9:75:9 | x | | test.c:75:9:75:14 | ... == ... | +| test.c:75:14:75:14 | 0 | +| test.c:75:17:78:5 | { ... } | +| test.c:76:9:76:9 | y | +| test.c:76:9:76:14 | ... = ... | +| test.c:76:9:76:15 | ExprStmt | +| test.c:76:13:76:14 | 20 | +| test.c:76:13:76:14 | (long)... | +| test.c:77:9:77:9 | z | +| test.c:77:9:77:14 | ... = ... | +| test.c:77:9:77:15 | ExprStmt | +| test.c:77:13:77:14 | 10 | +| test.c:78:12:80:5 | { ... } | +| test.c:79:9:79:9 | y | +| test.c:79:9:79:14 | ... = ... | +| test.c:79:9:79:15 | ExprStmt | +| test.c:79:13:79:14 | 30 | +| test.c:79:13:79:14 | (long)... | +| test.c:82:5:82:5 | z | +| test.c:82:5:82:13 | ... = ... | +| test.c:82:5:82:14 | ExprStmt | +| test.c:82:9:82:9 | (long)... | +| test.c:82:9:82:9 | x | +| test.c:82:9:82:13 | (int)... | +| test.c:82:9:82:13 | ... + ... | +| test.c:82:13:82:13 | y | +| test.c:84:5:84:19 | // More complex | +| test.c:85:5:88:15 | if (...) ... | +| test.c:85:8:85:8 | x | | test.c:85:8:85:13 | ... == ... | | test.c:85:8:85:23 | ... && ... | +| test.c:85:13:85:13 | 0 | +| test.c:85:18:85:18 | y | | test.c:85:18:85:23 | ... != ... | +| test.c:85:23:85:23 | 0 | +| test.c:85:23:85:23 | (long)... | +| test.c:86:9:86:9 | y | +| test.c:86:9:86:14 | ... = ... | +| test.c:86:9:86:15 | ExprStmt | +| test.c:86:13:86:14 | 40 | +| test.c:86:13:86:14 | (long)... | +| test.c:88:9:88:9 | y | +| test.c:88:9:88:14 | ... = ... | +| test.c:88:9:88:15 | ExprStmt | +| test.c:88:13:88:14 | 20 | +| test.c:88:13:88:14 | (long)... | +| test.c:91:5:91:5 | z | +| test.c:91:5:91:10 | ... = ... | +| test.c:91:5:91:11 | ExprStmt | +| test.c:91:9:91:10 | 10 | +| test.c:93:5:93:17 | // while loop | +| test.c:94:5:97:5 | while (...) ... | +| test.c:94:11:94:11 | x | | test.c:94:11:94:16 | ... != ... | +| test.c:94:16:94:16 | 0 | +| test.c:94:19:97:5 | { ... } | +| test.c:95:9:95:9 | y | +| test.c:95:9:95:14 | ... = ... | +| test.c:95:9:95:15 | ExprStmt | +| test.c:95:13:95:14 | 10 | +| test.c:95:13:95:14 | (long)... | +| test.c:96:9:96:9 | x | +| test.c:96:9:96:11 | ... -- | +| test.c:96:9:96:12 | ExprStmt | +| test.c:99:5:99:5 | z | +| test.c:99:5:99:10 | ... += ... | +| test.c:99:5:99:11 | ExprStmt | +| test.c:99:10:99:10 | y | +| test.c:101:5:101:15 | // for loop | +| test.c:102:5:105:5 | for(...;...;...) ... | +| test.c:102:9:102:9 | j | +| test.c:102:9:102:13 | ... = ... | +| test.c:102:9:102:14 | ExprStmt | +| test.c:102:13:102:13 | 0 | +| test.c:102:16:102:16 | j | | test.c:102:16:102:21 | ... < ... | +| test.c:102:20:102:21 | 10 | +| test.c:102:24:102:24 | j | +| test.c:102:24:102:26 | ... ++ | +| test.c:102:29:105:5 | { ... } | +| test.c:103:9:103:9 | y | +| test.c:103:9:103:13 | ... = ... | +| test.c:103:9:103:14 | ExprStmt | +| test.c:103:13:103:13 | 0 | +| test.c:103:13:103:13 | (long)... | +| test.c:104:9:104:9 | w | +| test.c:104:9:104:14 | ... = ... | +| test.c:104:9:104:15 | ExprStmt | +| test.c:104:13:104:14 | 10 | +| test.c:107:5:107:5 | z | +| test.c:107:5:107:10 | ... += ... | +| test.c:107:5:107:11 | ExprStmt | +| test.c:107:10:107:10 | w | +| test.c:109:5:113:17 | if (...) ... | +| test.c:109:9:109:9 | x | | test.c:109:9:109:14 | ... == ... | | test.c:109:9:109:23 | ... \|\| ... | +| test.c:109:14:109:14 | 0 | +| test.c:109:19:109:19 | y | | test.c:109:19:109:23 | ... < ... | +| test.c:109:23:109:23 | 0 | +| test.c:109:23:109:23 | (long)... | +| test.c:109:26:112:5 | { ... } | +| test.c:110:9:110:9 | y | +| test.c:110:9:110:14 | ... = ... | +| test.c:110:9:110:15 | ExprStmt | +| test.c:110:13:110:14 | 60 | +| test.c:110:13:110:14 | (long)... | +| test.c:111:9:111:9 | z | +| test.c:111:9:111:14 | ... = ... | +| test.c:111:9:111:15 | ExprStmt | +| test.c:111:13:111:14 | 10 | +| test.c:113:9:113:17 | return ... | +| test.c:113:16:113:16 | z | +| test.c:115:5:115:5 | z | +| test.c:115:5:115:10 | ... += ... | +| test.c:115:5:115:11 | ExprStmt | +| test.c:115:10:115:10 | x | +| test.c:117:5:117:13 | return ... | +| test.c:117:12:117:12 | 0 | +| test.c:120:5:120:19 | declaration of test3_condition | +| test.c:120:5:120:19 | test3_condition | +| test.c:121:6:121:17 | declaration of test3_action | +| test.c:121:6:121:17 | test3_action | +| test.c:123:6:123:10 | definition of test3 | +| test.c:123:6:123:10 | test3 | +| test.c:123:14:134:1 | { ... } | +| test.c:124:3:124:12 | declaration | +| test.c:124:7:124:7 | b | +| test.c:124:7:124:7 | definition of b | +| test.c:124:10:124:11 | 0 | +| test.c:124:10:124:11 | initializer for b | +| test.c:126:3:129:3 | if (...) ... | | test.c:126:7:126:7 | 1 | | test.c:126:7:126:28 | ... && ... | | test.c:126:12:126:26 | call to test3_condition | +| test.c:126:31:129:3 | { ... } | +| test.c:127:5:127:5 | b | +| test.c:127:5:127:9 | ... = ... | +| test.c:127:5:127:10 | ExprStmt | +| test.c:127:9:127:9 | 1 | +| test.c:128:5:128:16 | call to test3_action | +| test.c:128:5:128:19 | ExprStmt | +| test.c:131:3:133:3 | if (...) ... | | test.c:131:7:131:7 | b | +| test.c:131:10:133:3 | { ... } | +| test.c:132:5:132:16 | call to test3_action | +| test.c:132:5:132:19 | ExprStmt | +| test.c:134:1:134:1 | return ... | +| test.c:136:6:136:10 | definition of test4 | +| test.c:136:6:136:10 | test4 | +| test.c:136:16:136:16 | definition of i | +| test.c:136:16:136:16 | i | +| test.c:136:19:143:1 | { ... } | +| test.c:137:3:141:3 | if (...) ... | | test.c:137:7:137:7 | 0 | +| test.c:137:10:141:3 | { ... } | +| test.c:138:5:140:5 | if (...) ... | +| test.c:138:9:138:9 | i | +| test.c:138:12:140:5 | { ... } | +| test.c:139:7:139:7 | ; | +| test.c:142:3:142:9 | return ... | +| test.c:145:6:145:10 | definition of test5 | +| test.c:145:6:145:10 | test5 | +| test.c:145:16:145:16 | definition of x | +| test.c:145:16:145:16 | x | +| test.c:145:19:149:1 | { ... } | +| test.c:146:3:148:3 | if (...) ... | | test.c:146:7:146:8 | ! ... | | test.c:146:8:146:8 | x | +| test.c:146:11:148:3 | { ... } | +| test.c:147:5:147:9 | call to test3 | +| test.c:147:5:147:12 | ExprStmt | +| test.c:149:1:149:1 | return ... | +| test.c:151:6:151:10 | definition of test6 | +| test.c:151:6:151:10 | test6 | +| test.c:151:18:151:18 | definition of p | +| test.c:151:18:151:18 | p | +| test.c:151:21:155:1 | { ... } | +| test.c:152:5:154:5 | if (...) ... | | test.c:152:8:152:8 | p | +| test.c:152:11:154:5 | { ... } | +| test.c:155:1:155:1 | return ... | +| test.c:157:6:157:10 | definition of test7 | +| test.c:157:6:157:10 | test7 | +| test.c:157:18:157:18 | definition of p | +| test.c:157:18:157:18 | p | +| test.c:157:21:161:1 | { ... } | +| test.c:158:5:160:5 | if (...) ... | | test.c:158:8:158:9 | ! ... | | test.c:158:9:158:9 | p | +| test.c:158:12:160:5 | { ... } | +| test.c:161:1:161:1 | return ... | +| test.c:163:6:163:10 | definition of test8 | +| test.c:163:6:163:10 | test8 | +| test.c:163:18:163:18 | definition of s | +| test.c:163:18:163:18 | s | +| test.c:163:21:167:1 | { ... } | +| test.c:164:5:166:5 | if (...) ... | | test.c:164:8:164:8 | s | +| test.c:164:11:166:5 | { ... } | +| test.c:167:1:167:1 | return ... | +| test.c:169:6:169:10 | definition of test9 | +| test.c:169:6:169:10 | test9 | +| test.c:169:18:169:18 | definition of s | +| test.c:169:18:169:18 | s | +| test.c:169:21:173:1 | { ... } | +| test.c:170:5:172:5 | if (...) ... | | test.c:170:8:170:9 | ! ... | | test.c:170:9:170:9 | s | +| test.c:170:12:172:5 | { ... } | +| test.c:173:1:173:1 | return ... | +| test.c:175:6:175:11 | definition of test10 | +| test.c:175:6:175:11 | test10 | +| test.c:175:17:175:17 | a | +| test.c:175:17:175:17 | definition of a | +| test.c:175:24:175:24 | b | +| test.c:175:24:175:24 | definition of b | +| test.c:175:27:179:1 | { ... } | +| test.c:176:5:178:5 | if (...) ... | | test.c:176:8:176:15 | ! ... | +| test.c:176:9:176:15 | (...) | +| test.c:176:10:176:10 | a | | test.c:176:10:176:14 | ... < ... | +| test.c:176:14:176:14 | b | +| test.c:176:18:178:5 | { ... } | +| test.c:179:1:179:1 | return ... | +| test.c:181:6:181:11 | definition of test11 | +| test.c:181:6:181:11 | test11 | +| test.c:181:20:181:22 | definition of foo | +| test.c:181:20:181:22 | foo | +| test.c:181:25:185:1 | { ... } | +| test.c:182:5:184:5 | if (...) ... | | test.c:182:8:182:34 | ! ... | +| test.c:182:9:182:34 | (...) | +| test.c:182:10:182:12 | foo | | test.c:182:10:182:20 | ... >= ... | | test.c:182:10:182:33 | ... && ... | +| test.c:182:17:182:20 | 9.999999999999999547e-07 | +| test.c:182:25:182:27 | foo | | test.c:182:25:182:33 | ... < ... | +| test.c:182:31:182:33 | 1.0 | +| test.c:182:37:184:5 | { ... } | +| test.c:185:1:185:1 | return ... | +| test.c:187:6:187:11 | definition of test12 | +| test.c:187:6:187:11 | test12 | +| test.c:187:17:187:17 | a | +| test.c:187:17:187:17 | definition of a | +| test.c:187:24:187:24 | b | +| test.c:187:24:187:24 | definition of b | +| test.c:187:27:193:1 | { ... } | +| test.c:188:3:188:17 | declaration | +| test.c:188:7:188:7 | c | +| test.c:188:7:188:7 | definition of c | +| test.c:188:10:188:16 | initializer for c | +| test.c:188:11:188:11 | a | +| test.c:188:11:188:16 | ... != ... | +| test.c:188:16:188:16 | b | +| test.c:190:3:192:3 | if (...) ... | | test.c:190:7:190:8 | ! ... | | test.c:190:8:190:8 | c | +| test.c:190:11:192:3 | { ... } | +| test.c:193:1:193:1 | return ... | +| test.c:195:6:195:11 | definition of test13 | +| test.c:195:6:195:11 | test13 | +| test.c:195:17:195:17 | a | +| test.c:195:17:195:17 | definition of a | +| test.c:195:20:201:1 | { ... } | +| test.c:196:3:196:17 | declaration | +| test.c:196:7:196:7 | b | +| test.c:196:7:196:7 | definition of b | +| test.c:196:10:196:16 | initializer for b | +| test.c:196:11:196:11 | a | +| test.c:196:11:196:16 | ... > ... | +| test.c:196:15:196:16 | 10 | +| test.c:198:3:200:3 | if (...) ... | | test.c:198:7:198:8 | ! ... | | test.c:198:8:198:8 | b | +| test.c:198:11:200:3 | { ... } | +| test.c:201:1:201:1 | return ... | +| test.c:203:6:203:11 | definition of test14 | +| test.c:203:6:203:11 | test14 | +| test.c:203:17:203:17 | a | +| test.c:203:17:203:17 | definition of a | +| test.c:203:24:203:24 | b | +| test.c:203:24:203:24 | definition of b | +| test.c:203:27:209:1 | { ... } | +| test.c:204:3:204:16 | declaration | +| test.c:204:7:204:7 | c | +| test.c:204:7:204:7 | definition of c | +| test.c:204:10:204:15 | initializer for c | +| test.c:204:11:204:11 | a | +| test.c:204:11:204:15 | ... > ... | +| test.c:204:15:204:15 | b | +| test.c:206:3:208:3 | if (...) ... | | test.c:206:7:206:8 | ! ... | | test.c:206:8:206:8 | c | +| test.c:206:11:208:3 | { ... } | +| test.c:209:1:209:1 | return ... | +| test.c:211:1:211:45 | #define likely(x) __builtin_expect(!!(x), 1) | +| test.c:213:6:213:11 | definition of test15 | +| test.c:213:6:213:11 | test15 | +| test.c:213:17:213:17 | a | +| test.c:213:17:213:17 | definition of a | +| test.c:213:24:213:24 | b | +| test.c:213:24:213:24 | definition of b | +| test.c:214:1:222:1 | { ... } | +| test.c:215:2:217:5 | if (...) ... | +| test.c:215:6:215:18 | 1 | +| test.c:215:6:215:18 | ! ... | +| test.c:215:6:215:18 | ! ... | +| test.c:215:6:215:18 | (...) | +| test.c:215:6:215:18 | (long)... | +| test.c:215:6:215:18 | (long)... | | test.c:215:6:215:18 | call to __builtin_expect | +| test.c:215:6:215:18 | likely(x) | +| test.c:215:13:215:13 | a | +| test.c:215:13:215:17 | ... > ... | +| test.c:215:17:215:17 | b | +| test.c:215:21:217:5 | { ... } | +| test.c:219:5:221:5 | if (...) ... | +| test.c:219:9:219:22 | 1 | +| test.c:219:9:219:22 | ! ... | +| test.c:219:9:219:22 | ! ... | +| test.c:219:9:219:22 | (...) | +| test.c:219:9:219:22 | (long)... | +| test.c:219:9:219:22 | (long)... | | test.c:219:9:219:22 | call to __builtin_expect | +| test.c:219:9:219:22 | likely(x) | +| test.c:219:16:219:16 | a | +| test.c:219:16:219:21 | ... > ... | +| test.c:219:20:219:21 | 42 | +| test.c:219:25:221:5 | { ... } | +| test.c:222:1:222:1 | return ... | +| test.cpp:0:0:0:0 | test.cpp | +| test.cpp:1:7:1:7 | X | +| test.cpp:1:7:1:7 | declaration of operator= | +| test.cpp:1:7:1:7 | declaration of operator= | +| test.cpp:1:7:1:7 | definition of X | +| test.cpp:1:7:1:7 | operator= | +| test.cpp:1:7:1:7 | operator= | +| test.cpp:4:8:4:10 | declaration of set | +| test.cpp:4:8:4:10 | set | +| test.cpp:7:7:7:7 | Y | +| test.cpp:7:7:7:7 | declaration of operator= | +| test.cpp:7:7:7:7 | declaration of operator= | +| test.cpp:7:7:7:7 | definition of Y | +| test.cpp:7:7:7:7 | operator= | +| test.cpp:7:7:7:7 | operator= | +| test.cpp:10:3:10:3 | type mention | +| test.cpp:10:6:10:6 | declaration of f | +| test.cpp:12:9:12:9 | type mention | +| test.cpp:12:12:12:14 | definition of get | +| test.cpp:12:12:12:14 | get | +| test.cpp:12:24:12:36 | { ... } | +| test.cpp:12:26:12:34 | return ... | +| test.cpp:12:33:12:33 | 0 | +| test.cpp:12:33:12:33 | (const X *)... | +| test.cpp:13:3:13:3 | type mention | +| test.cpp:13:6:13:8 | definition of get | +| test.cpp:13:6:13:8 | get | +| test.cpp:13:12:13:24 | { ... } | +| test.cpp:13:14:13:22 | return ... | +| test.cpp:13:21:13:21 | 0 | +| test.cpp:13:21:13:21 | (X *)... | +| test.cpp:16:1:16:1 | type mention | +| test.cpp:16:4:16:4 | type mention | +| test.cpp:16:4:16:7 | definition of f | +| test.cpp:16:4:16:7 | f | +| test.cpp:17:1:21:1 | { ... } | +| test.cpp:18:3:19:17 | if (...) ... | | test.cpp:18:8:18:10 | call to get | +| test.cpp:18:8:18:10 | this | +| test.cpp:18:8:18:12 | (bool)... | +| test.cpp:19:5:19:7 | call to get | +| test.cpp:19:5:19:7 | this | +| test.cpp:19:5:19:17 | ExprStmt | +| test.cpp:19:12:19:14 | call to set | +| test.cpp:20:3:20:11 | return ... | +| test.cpp:20:10:20:10 | 0 | +| test.cpp:20:10:20:10 | (Y *)... | +| test.cpp:23:7:23:7 | Error | +| test.cpp:23:7:23:7 | Error | +| test.cpp:23:7:23:7 | declaration of Error | +| test.cpp:23:7:23:7 | declaration of Error | +| test.cpp:23:7:23:7 | declaration of operator= | +| test.cpp:23:7:23:7 | declaration of operator= | +| test.cpp:23:7:23:7 | operator= | +| test.cpp:23:7:23:7 | operator= | +| test.cpp:23:7:23:11 | Error | +| test.cpp:23:7:23:11 | definition of Error | +| test.cpp:25:3:25:7 | Error | +| test.cpp:25:3:25:7 | definition of Error | +| test.cpp:25:11:25:12 | { ... } | +| test.cpp:25:12:25:12 | return ... | +| test.cpp:28:6:28:13 | declaration of getABool | +| test.cpp:28:6:28:13 | getABool | +| test.cpp:30:6:30:16 | definition of doSomething | +| test.cpp:30:6:30:16 | doSomething | +| test.cpp:30:22:30:22 | definition of x | +| test.cpp:30:22:30:22 | x | +| test.cpp:30:25:34:1 | { ... } | +| test.cpp:31:3:33:3 | if (...) ... | +| test.cpp:31:7:31:7 | x | | test.cpp:31:7:31:13 | ... == ... | +| test.cpp:31:12:31:13 | - ... | +| test.cpp:31:13:31:13 | 1 | +| test.cpp:31:16:33:3 | { ... } | +| test.cpp:32:5:32:21 | throw ... | +| test.cpp:32:5:32:22 | ExprStmt | +| test.cpp:32:11:32:21 | call to Error | +| test.cpp:32:11:32:21 | new | +| test.cpp:32:15:32:19 | type mention | +| test.cpp:34:1:34:1 | return ... | +| test.cpp:36:6:36:20 | declaration of doSomethingElse | +| test.cpp:36:6:36:20 | doSomethingElse | +| test.cpp:36:26:36:26 | declaration of x | +| test.cpp:36:26:36:26 | x | +| test.cpp:38:6:38:19 | definition of testWithCatch0 | +| test.cpp:38:6:38:19 | testWithCatch0 | +| test.cpp:38:25:38:25 | definition of v | +| test.cpp:38:25:38:25 | v | +| test.cpp:39:1:54:1 | { ... } | +| test.cpp:40:5:47:5 | try { ... } | +| test.cpp:41:5:47:5 | { ... } | +| test.cpp:42:9:46:9 | if (...) ... | | test.cpp:42:13:42:20 | call to getABool | +| test.cpp:43:9:46:9 | { ... } | +| test.cpp:44:13:44:23 | call to doSomething | +| test.cpp:44:13:44:27 | ExprStmt | +| test.cpp:44:25:44:25 | v | +| test.cpp:45:13:45:24 | return ... | +| test.cpp:45:20:45:23 | 1 | +| test.cpp:48:11:48:15 | type mention | +| test.cpp:48:18:48:18 | definition of e | +| test.cpp:48:18:48:18 | e | +| test.cpp:49:5:51:5 | | +| test.cpp:49:5:51:5 | { ... } | +| test.cpp:50:7:50:21 | call to doSomethingElse | +| test.cpp:50:7:50:25 | ExprStmt | +| test.cpp:50:23:50:23 | v | +| test.cpp:53:5:53:17 | return ... | +| test.cpp:53:12:53:16 | 0 | +| test.cpp:56:6:56:9 | declaration of use1 | +| test.cpp:56:6:56:9 | use1 | +| test.cpp:56:11:56:13 | (unnamed parameter 0) | +| test.cpp:56:11:56:13 | declaration of (unnamed parameter 0) | +| test.cpp:57:6:57:9 | declaration of use2 | +| test.cpp:57:6:57:9 | use2 | +| test.cpp:57:11:57:13 | (unnamed parameter 0) | +| test.cpp:57:11:57:13 | declaration of (unnamed parameter 0) | +| test.cpp:58:6:58:9 | declaration of use3 | +| test.cpp:58:6:58:9 | use3 | +| test.cpp:58:11:58:13 | (unnamed parameter 0) | +| test.cpp:58:11:58:13 | declaration of (unnamed parameter 0) | +| test.cpp:60:6:60:25 | definition of test_switches_simple | +| test.cpp:60:6:60:25 | test_switches_simple | +| test.cpp:60:31:60:31 | definition of i | +| test.cpp:60:31:60:31 | i | +| test.cpp:60:34:71:1 | { ... } | +| test.cpp:61:3:70:3 | switch (...) ... | | test.cpp:61:10:61:10 | i | +| test.cpp:61:13:70:3 | { ... } | +| test.cpp:62:5:62:11 | case ...: | +| test.cpp:62:10:62:10 | 0 | +| test.cpp:63:7:63:10 | call to use1 | +| test.cpp:63:7:63:14 | ExprStmt | +| test.cpp:63:12:63:12 | i | +| test.cpp:64:7:64:12 | break; | +| test.cpp:65:5:65:11 | case ...: | +| test.cpp:65:10:65:10 | 1 | +| test.cpp:66:7:66:10 | call to use2 | +| test.cpp:66:7:66:14 | ExprStmt | +| test.cpp:66:12:66:12 | i | +| test.cpp:67:7:67:29 | /* NOTE: fallthrough */ | +| test.cpp:68:5:68:11 | case ...: | +| test.cpp:68:10:68:10 | 2 | +| test.cpp:69:7:69:10 | call to use3 | +| test.cpp:69:7:69:14 | ExprStmt | +| test.cpp:69:12:69:12 | i | +| test.cpp:70:3:70:3 | label ...: | +| test.cpp:71:1:71:1 | return ... | +| test.cpp:73:6:73:24 | definition of test_switches_range | +| test.cpp:73:6:73:24 | test_switches_range | +| test.cpp:73:30:73:30 | definition of i | +| test.cpp:73:30:73:30 | i | +| test.cpp:73:33:81:1 | { ... } | +| test.cpp:74:3:80:3 | switch (...) ... | | test.cpp:74:10:74:10 | i | +| test.cpp:74:13:80:3 | { ... } | +| test.cpp:75:5:75:18 | case ...: | +| test.cpp:75:10:75:10 | 0 | +| test.cpp:75:16:75:17 | 10 | +| test.cpp:76:7:76:10 | call to use1 | +| test.cpp:76:7:76:14 | ExprStmt | +| test.cpp:76:12:76:12 | i | +| test.cpp:77:7:77:12 | break; | +| test.cpp:78:5:78:19 | case ...: | +| test.cpp:78:10:78:11 | 11 | +| test.cpp:78:17:78:18 | 20 | +| test.cpp:79:7:79:10 | call to use2 | +| test.cpp:79:7:79:14 | ExprStmt | +| test.cpp:79:12:79:12 | i | +| test.cpp:80:3:80:3 | label ...: | +| test.cpp:81:1:81:1 | return ... | +| test.cpp:83:6:83:26 | definition of test_switches_default | +| test.cpp:83:6:83:26 | test_switches_default | +| test.cpp:83:32:83:32 | definition of i | +| test.cpp:83:32:83:32 | i | +| test.cpp:83:35:88:1 | { ... } | +| test.cpp:84:3:87:3 | switch (...) ... | | test.cpp:84:10:84:10 | i | +| test.cpp:84:13:87:3 | { ... } | +| test.cpp:85:5:85:12 | default: | +| test.cpp:86:7:86:10 | call to use1 | +| test.cpp:86:7:86:14 | ExprStmt | +| test.cpp:86:12:86:12 | i | +| test.cpp:88:1:88:1 | return ... | +| test.cpp:90:6:90:8 | declaration of use | +| test.cpp:90:6:90:8 | use | +| test.cpp:92:6:92:23 | definition of pointer_comparison | +| test.cpp:92:6:92:23 | pointer_comparison | +| test.cpp:92:31:92:31 | c | +| test.cpp:92:31:92:31 | definition of c | +| test.cpp:92:34:96:1 | { ... } | +| test.cpp:93:3:95:3 | if (...) ... | +| test.cpp:93:6:93:6 | (bool)... | | test.cpp:93:6:93:6 | c | +| test.cpp:93:9:95:3 | { ... } | +| test.cpp:94:5:94:7 | call to use | +| test.cpp:94:5:94:11 | ExprStmt | +| test.cpp:94:9:94:9 | c | +| test.cpp:96:1:96:1 | return ... | +| test.cpp:98:6:98:30 | definition of implicit_float_comparison | +| test.cpp:98:6:98:30 | implicit_float_comparison | +| test.cpp:98:38:98:38 | definition of f | +| test.cpp:98:38:98:38 | f | +| test.cpp:98:41:102:1 | { ... } | +| test.cpp:99:3:101:3 | if (...) ... | +| test.cpp:99:6:99:6 | (bool)... | | test.cpp:99:6:99:6 | f | +| test.cpp:99:9:101:3 | { ... } | +| test.cpp:100:5:100:7 | call to use | +| test.cpp:100:5:100:11 | ExprStmt | +| test.cpp:100:9:100:9 | (double)... | +| test.cpp:100:9:100:9 | f | +| test.cpp:102:1:102:1 | return ... | +| test.cpp:104:6:104:30 | definition of explicit_float_comparison | +| test.cpp:104:6:104:30 | explicit_float_comparison | +| test.cpp:104:38:104:38 | definition of f | +| test.cpp:104:38:104:38 | f | +| test.cpp:104:41:108:1 | { ... } | +| test.cpp:105:3:107:3 | if (...) ... | +| test.cpp:105:6:105:6 | f | | test.cpp:105:6:105:14 | ... != ... | +| test.cpp:105:11:105:14 | 0.0 | +| test.cpp:105:17:107:3 | { ... } | +| test.cpp:106:5:106:7 | call to use | +| test.cpp:106:5:106:11 | ExprStmt | +| test.cpp:106:9:106:9 | (double)... | +| test.cpp:106:9:106:9 | f | +| test.cpp:108:1:108:1 | return ... | +| test.cpp:110:6:110:25 | definition of int_float_comparison | +| test.cpp:110:6:110:25 | int_float_comparison | +| test.cpp:110:31:110:31 | definition of i | +| test.cpp:110:31:110:31 | i | +| test.cpp:110:34:114:1 | { ... } | +| test.cpp:111:3:113:3 | if (...) ... | +| test.cpp:111:6:111:6 | (float)... | +| test.cpp:111:6:111:6 | i | | test.cpp:111:6:111:14 | ... != ... | +| test.cpp:111:11:111:14 | 0.0 | +| test.cpp:111:17:113:3 | { ... } | +| test.cpp:112:5:112:7 | call to use | +| test.cpp:112:5:112:11 | ExprStmt | +| test.cpp:112:9:112:9 | i | +| test.cpp:114:1:114:1 | return ... | +| test.cpp:116:5:116:10 | declaration of source | +| test.cpp:116:5:116:10 | source | +| test.cpp:117:6:117:9 | declaration of safe | +| test.cpp:117:6:117:9 | safe | +| test.cpp:117:11:117:13 | (unnamed parameter 0) | +| test.cpp:117:11:117:13 | declaration of (unnamed parameter 0) | +| test.cpp:119:6:119:9 | definition of test | +| test.cpp:119:6:119:9 | test | +| test.cpp:119:16:119:16 | b | +| test.cpp:119:16:119:16 | definition of b | +| test.cpp:120:1:128:1 | { ... } | +| test.cpp:121:5:121:10 | declaration | +| test.cpp:121:9:121:9 | definition of x | +| test.cpp:121:9:121:9 | x | +| test.cpp:122:5:126:5 | if (...) ... | | test.cpp:122:9:122:9 | b | +| test.cpp:123:5:126:5 | { ... } | +| test.cpp:124:9:124:9 | x | +| test.cpp:124:9:124:20 | ... = ... | +| test.cpp:124:9:124:21 | ExprStmt | +| test.cpp:124:13:124:18 | call to source | +| test.cpp:125:9:125:29 | if (...) ... | | test.cpp:125:13:125:20 | ! ... | | test.cpp:125:14:125:17 | call to safe | +| test.cpp:125:19:125:19 | x | +| test.cpp:125:23:125:29 | return ... | +| test.cpp:127:5:127:7 | call to use | +| test.cpp:127:5:127:11 | ExprStmt | +| test.cpp:127:9:127:9 | x | +| test.cpp:128:1:128:1 | return ... | +| test.cpp:130:6:130:33 | binary_test_builtin_expected | +| test.cpp:130:6:130:33 | definition of binary_test_builtin_expected | +| test.cpp:130:39:130:39 | a | +| test.cpp:130:39:130:39 | definition of a | +| test.cpp:130:46:130:46 | b | +| test.cpp:130:46:130:46 | definition of b | +| test.cpp:130:49:138:1 | { ... } | +| test.cpp:131:3:133:3 | if (...) ... | | test.cpp:131:6:131:21 | call to __builtin_expect | +| test.cpp:131:6:131:37 | (bool)... | +| test.cpp:131:23:131:23 | a | +| test.cpp:131:23:131:33 | (long)... | +| test.cpp:131:23:131:33 | ... == ... | +| test.cpp:131:28:131:28 | b | +| test.cpp:131:28:131:33 | ... + ... | +| test.cpp:131:32:131:33 | 42 | +| test.cpp:131:36:131:36 | 0 | +| test.cpp:131:36:131:36 | (long)... | +| test.cpp:131:40:133:3 | { ... } | +| test.cpp:132:7:132:9 | call to use | +| test.cpp:132:7:132:13 | ExprStmt | +| test.cpp:132:11:132:11 | a | +| test.cpp:135:3:137:3 | if (...) ... | | test.cpp:135:6:135:21 | call to __builtin_expect | +| test.cpp:135:6:135:37 | (bool)... | +| test.cpp:135:23:135:23 | a | +| test.cpp:135:23:135:33 | (long)... | +| test.cpp:135:23:135:33 | ... != ... | +| test.cpp:135:28:135:28 | b | +| test.cpp:135:28:135:33 | ... + ... | +| test.cpp:135:32:135:33 | 42 | +| test.cpp:135:36:135:36 | 0 | +| test.cpp:135:36:135:36 | (long)... | +| test.cpp:135:40:137:3 | { ... } | +| test.cpp:136:7:136:9 | call to use | +| test.cpp:136:7:136:13 | ExprStmt | +| test.cpp:136:11:136:11 | a | +| test.cpp:138:1:138:1 | return ... | +| test.cpp:140:6:140:32 | definition of unary_test_builtin_expected | +| test.cpp:140:6:140:32 | unary_test_builtin_expected | +| test.cpp:140:38:140:38 | a | +| test.cpp:140:38:140:38 | definition of a | +| test.cpp:140:41:148:1 | { ... } | +| test.cpp:141:3:143:3 | if (...) ... | | test.cpp:141:6:141:21 | call to __builtin_expect | +| test.cpp:141:6:141:33 | (bool)... | +| test.cpp:141:23:141:23 | a | +| test.cpp:141:23:141:29 | (long)... | +| test.cpp:141:23:141:29 | ... == ... | +| test.cpp:141:28:141:29 | 42 | +| test.cpp:141:32:141:32 | 0 | +| test.cpp:141:32:141:32 | (long)... | +| test.cpp:141:36:143:3 | { ... } | +| test.cpp:142:7:142:9 | call to use | +| test.cpp:142:7:142:13 | ExprStmt | +| test.cpp:142:11:142:11 | a | +| test.cpp:145:3:147:3 | if (...) ... | | test.cpp:145:6:145:21 | call to __builtin_expect | +| test.cpp:145:6:145:33 | (bool)... | +| test.cpp:145:23:145:23 | a | +| test.cpp:145:23:145:29 | (long)... | +| test.cpp:145:23:145:29 | ... != ... | +| test.cpp:145:28:145:29 | 42 | +| test.cpp:145:32:145:32 | 0 | +| test.cpp:145:32:145:32 | (long)... | +| test.cpp:145:36:147:3 | { ... } | +| test.cpp:146:7:146:9 | call to use | +| test.cpp:146:7:146:13 | ExprStmt | +| test.cpp:146:11:146:11 | a | +| test.cpp:148:1:148:1 | return ... | +| test.cpp:150:6:150:24 | definition of test_with_reference | +| test.cpp:150:6:150:24 | test_with_reference | +| test.cpp:150:32:150:32 | b | +| test.cpp:150:32:150:32 | definition of b | +| test.cpp:150:39:150:39 | a | +| test.cpp:150:39:150:39 | definition of a | +| test.cpp:150:42:155:1 | { ... } | +| test.cpp:151:4:151:4 | (reference dereference) | +| test.cpp:151:4:151:4 | b | +| test.cpp:151:4:151:13 | ... = ... | +| test.cpp:151:4:151:14 | ExprStmt | +| test.cpp:151:8:151:8 | a | +| test.cpp:151:8:151:13 | ... < ... | +| test.cpp:151:12:151:13 | 10 | +| test.cpp:152:4:154:4 | if (...) ... | | test.cpp:152:7:152:8 | ! ... | +| test.cpp:152:8:152:8 | (reference dereference) | | test.cpp:152:8:152:8 | b | +| test.cpp:152:11:154:4 | { ... } | +| test.cpp:153:7:153:9 | call to use | +| test.cpp:153:7:153:13 | ExprStmt | +| test.cpp:153:11:153:11 | a | +| test.cpp:155:1:155:1 | return ... | +| test.cpp:157:6:157:38 | definition of test_with_negated_binary_equality | +| test.cpp:157:6:157:38 | test_with_negated_binary_equality | +| test.cpp:157:44:157:44 | a | +| test.cpp:157:44:157:44 | definition of a | +| test.cpp:157:51:157:51 | b | +| test.cpp:157:51:157:51 | definition of b | +| test.cpp:157:54:163:1 | { ... } | +| test.cpp:158:3:158:18 | declaration | +| test.cpp:158:8:158:8 | c | +| test.cpp:158:8:158:8 | definition of c | +| test.cpp:158:11:158:17 | initializer for c | +| test.cpp:158:12:158:12 | a | +| test.cpp:158:12:158:17 | ... != ... | +| test.cpp:158:17:158:17 | b | +| test.cpp:160:3:162:3 | if (...) ... | | test.cpp:160:7:160:8 | ! ... | | test.cpp:160:8:160:8 | c | +| test.cpp:160:11:162:3 | { ... } | +| test.cpp:163:1:163:1 | return ... | +| test.cpp:165:6:165:39 | definition of test_with_negated_unary_relational | +| test.cpp:165:6:165:39 | test_with_negated_unary_relational | +| test.cpp:165:45:165:45 | a | +| test.cpp:165:45:165:45 | definition of a | +| test.cpp:165:48:171:1 | { ... } | +| test.cpp:166:3:166:18 | declaration | +| test.cpp:166:8:166:8 | b | +| test.cpp:166:8:166:8 | definition of b | +| test.cpp:166:11:166:17 | initializer for b | +| test.cpp:166:12:166:12 | a | +| test.cpp:166:12:166:17 | ... > ... | +| test.cpp:166:16:166:17 | 10 | +| test.cpp:168:3:170:3 | if (...) ... | | test.cpp:168:7:168:8 | ! ... | | test.cpp:168:8:168:8 | b | +| test.cpp:168:11:170:3 | { ... } | +| test.cpp:171:1:171:1 | return ... | +| test.cpp:173:6:173:40 | definition of test_with_negated_binary_relational | +| test.cpp:173:6:173:40 | test_with_negated_binary_relational | +| test.cpp:173:46:173:46 | a | +| test.cpp:173:46:173:46 | definition of a | +| test.cpp:173:53:173:53 | b | +| test.cpp:173:53:173:53 | definition of b | +| test.cpp:173:56:179:1 | { ... } | +| test.cpp:174:3:174:17 | declaration | +| test.cpp:174:8:174:8 | c | +| test.cpp:174:8:174:8 | definition of c | +| test.cpp:174:11:174:16 | initializer for c | +| test.cpp:174:12:174:12 | a | +| test.cpp:174:12:174:16 | ... > ... | +| test.cpp:174:16:174:16 | b | +| test.cpp:176:3:178:3 | if (...) ... | | test.cpp:176:7:176:8 | ! ... | | test.cpp:176:8:176:8 | c | +| test.cpp:176:11:178:3 | { ... } | +| test.cpp:179:1:179:1 | return ... | +| test.cpp:181:6:181:21 | definition of test_logical_and | +| test.cpp:181:6:181:21 | test_logical_and | +| test.cpp:181:28:181:29 | b1 | +| test.cpp:181:28:181:29 | definition of b1 | +| test.cpp:181:37:181:38 | b2 | +| test.cpp:181:37:181:38 | definition of b2 | +| test.cpp:181:41:190:1 | { ... } | +| test.cpp:182:3:189:3 | if (...) ... | | test.cpp:182:6:182:16 | ! ... | +| test.cpp:182:7:182:16 | (...) | | test.cpp:182:8:182:9 | b1 | | test.cpp:182:8:182:15 | ... && ... | | test.cpp:182:14:182:15 | b2 | +| test.cpp:182:19:185:3 | { ... } | +| test.cpp:183:5:183:7 | call to use | +| test.cpp:183:5:183:12 | ExprStmt | +| test.cpp:183:9:183:10 | (int)... | +| test.cpp:183:9:183:10 | b1 | +| test.cpp:184:5:184:7 | call to use | +| test.cpp:184:5:184:12 | ExprStmt | +| test.cpp:184:9:184:10 | (int)... | +| test.cpp:184:9:184:10 | b2 | +| test.cpp:185:10:189:3 | { ... } | +| test.cpp:186:5:186:30 | // b1 = true and b2 = true | +| test.cpp:187:5:187:7 | call to use | +| test.cpp:187:5:187:12 | ExprStmt | +| test.cpp:187:9:187:10 | (int)... | +| test.cpp:187:9:187:10 | b1 | +| test.cpp:188:5:188:7 | call to use | +| test.cpp:188:5:188:12 | ExprStmt | +| test.cpp:188:9:188:10 | (int)... | +| test.cpp:188:9:188:10 | b2 | +| test.cpp:190:1:190:1 | return ... | +| test.cpp:192:6:192:20 | definition of test_logical_or | +| test.cpp:192:6:192:20 | test_logical_or | +| test.cpp:192:27:192:28 | b1 | +| test.cpp:192:27:192:28 | definition of b1 | +| test.cpp:192:36:192:37 | b2 | +| test.cpp:192:36:192:37 | definition of b2 | +| test.cpp:192:40:201:1 | { ... } | +| test.cpp:193:3:200:3 | if (...) ... | | test.cpp:193:6:193:16 | ! ... | +| test.cpp:193:7:193:16 | (...) | | test.cpp:193:8:193:9 | b1 | | test.cpp:193:8:193:15 | ... \|\| ... | | test.cpp:193:14:193:15 | b2 | +| test.cpp:193:19:197:3 | { ... } | +| test.cpp:194:5:194:32 | // b1 = false and b2 = false | +| test.cpp:195:5:195:7 | call to use | +| test.cpp:195:5:195:12 | ExprStmt | +| test.cpp:195:9:195:10 | (int)... | +| test.cpp:195:9:195:10 | b1 | +| test.cpp:196:5:196:7 | call to use | +| test.cpp:196:5:196:12 | ExprStmt | +| test.cpp:196:9:196:10 | (int)... | +| test.cpp:196:9:196:10 | b2 | +| test.cpp:197:10:200:3 | { ... } | +| test.cpp:198:5:198:7 | call to use | +| test.cpp:198:5:198:12 | ExprStmt | +| test.cpp:198:9:198:10 | (int)... | +| test.cpp:198:9:198:10 | b1 | +| test.cpp:199:5:199:7 | call to use | +| test.cpp:199:5:199:12 | ExprStmt | +| test.cpp:199:9:199:10 | (int)... | +| test.cpp:199:9:199:10 | b2 | +| test.cpp:201:1:201:1 | return ... | +| test.cpp:203:8:203:8 | declaration of operator= | +| test.cpp:203:8:203:8 | declaration of operator= | +| test.cpp:203:8:203:8 | operator= | +| test.cpp:203:8:203:8 | operator= | +| test.cpp:203:8:203:15 | Mystruct | +| test.cpp:203:8:203:15 | definition of Mystruct | +| test.cpp:204:7:204:7 | definition of i | +| test.cpp:204:7:204:7 | i | +| test.cpp:205:9:205:9 | definition of f | +| test.cpp:205:9:205:9 | f | +| test.cpp:208:5:208:14 | definition of test_types | +| test.cpp:208:5:208:14 | test_types | +| test.cpp:208:28:208:29 | definition of sc | +| test.cpp:208:28:208:29 | sc | +| test.cpp:208:46:208:47 | definition of ul | +| test.cpp:208:46:208:47 | ul | +| test.cpp:208:56:208:56 | definition of f | +| test.cpp:208:56:208:56 | f | +| test.cpp:208:66:208:66 | d | +| test.cpp:208:66:208:66 | definition of d | +| test.cpp:208:74:208:74 | b | +| test.cpp:208:74:208:74 | definition of b | +| test.cpp:208:77:208:84 | type mention | +| test.cpp:208:87:208:88 | definition of ms | +| test.cpp:208:87:208:88 | ms | +| test.cpp:208:91:244:1 | { ... } | +| test.cpp:209:5:209:16 | declaration | +| test.cpp:209:9:209:11 | ctr | +| test.cpp:209:9:209:11 | definition of ctr | +| test.cpp:209:14:209:15 | 0 | +| test.cpp:209:14:209:15 | initializer for ctr | +| test.cpp:211:5:213:5 | if (...) ... | +| test.cpp:211:9:211:10 | (int)... | +| test.cpp:211:9:211:10 | sc | | test.cpp:211:9:211:15 | ... == ... | +| test.cpp:211:15:211:15 | 0 | +| test.cpp:211:18:213:5 | { ... } | +| test.cpp:212:9:212:11 | ctr | +| test.cpp:212:9:212:13 | ... ++ | +| test.cpp:212:9:212:14 | ExprStmt | +| test.cpp:214:5:216:5 | if (...) ... | +| test.cpp:214:9:214:10 | (int)... | +| test.cpp:214:9:214:10 | sc | | test.cpp:214:9:214:17 | ... == ... | +| test.cpp:214:15:214:17 | 0 | +| test.cpp:214:20:216:5 | { ... } | +| test.cpp:215:9:215:11 | ctr | +| test.cpp:215:9:215:13 | ... ++ | +| test.cpp:215:9:215:14 | ExprStmt | +| test.cpp:217:5:219:5 | if (...) ... | +| test.cpp:217:9:217:10 | ul | | test.cpp:217:9:217:15 | ... == ... | +| test.cpp:217:15:217:15 | 0 | +| test.cpp:217:15:217:15 | (unsigned long)... | +| test.cpp:217:18:219:5 | { ... } | +| test.cpp:218:9:218:11 | ctr | +| test.cpp:218:9:218:13 | ... ++ | +| test.cpp:218:9:218:14 | ExprStmt | +| test.cpp:220:5:222:5 | if (...) ... | +| test.cpp:220:9:220:9 | f | | test.cpp:220:9:220:14 | ... == ... | +| test.cpp:220:14:220:14 | 0 | +| test.cpp:220:14:220:14 | (float)... | +| test.cpp:220:17:222:5 | { ... } | +| test.cpp:221:9:221:11 | ctr | +| test.cpp:221:9:221:13 | ... ++ | +| test.cpp:221:9:221:14 | ExprStmt | +| test.cpp:223:5:225:5 | if (...) ... | +| test.cpp:223:9:223:9 | (double)... | +| test.cpp:223:9:223:9 | f | | test.cpp:223:9:223:16 | ... == ... | +| test.cpp:223:14:223:16 | 0.0 | +| test.cpp:223:19:225:5 | { ... } | +| test.cpp:224:9:224:11 | ctr | +| test.cpp:224:9:224:13 | ... ++ | +| test.cpp:224:9:224:14 | ExprStmt | +| test.cpp:226:5:228:5 | if (...) ... | +| test.cpp:226:9:226:9 | d | | test.cpp:226:9:226:14 | ... == ... | +| test.cpp:226:14:226:14 | 0 | +| test.cpp:226:14:226:14 | (double)... | +| test.cpp:226:17:228:5 | { ... } | +| test.cpp:227:9:227:11 | ctr | +| test.cpp:227:9:227:13 | ... ++ | +| test.cpp:227:9:227:14 | ExprStmt | +| test.cpp:229:5:231:5 | if (...) ... | +| test.cpp:229:9:229:9 | (int)... | +| test.cpp:229:9:229:9 | b | | test.cpp:229:9:229:14 | ... == ... | +| test.cpp:229:14:229:14 | 0 | +| test.cpp:229:17:231:5 | { ... } | +| test.cpp:230:9:230:11 | ctr | +| test.cpp:230:9:230:13 | ... ++ | +| test.cpp:230:9:230:14 | ExprStmt | +| test.cpp:232:5:234:5 | if (...) ... | +| test.cpp:232:9:232:9 | (int)... | +| test.cpp:232:9:232:9 | b | | test.cpp:232:9:232:18 | ... == ... | +| test.cpp:232:14:232:18 | 0 | +| test.cpp:232:14:232:18 | (int)... | +| test.cpp:232:21:234:5 | { ... } | +| test.cpp:233:9:233:11 | ctr | +| test.cpp:233:9:233:13 | ... ++ | +| test.cpp:233:9:233:14 | ExprStmt | +| test.cpp:235:5:237:5 | if (...) ... | +| test.cpp:235:9:235:10 | (reference dereference) | +| test.cpp:235:9:235:10 | ms | | test.cpp:235:9:235:17 | ... == ... | +| test.cpp:235:12:235:12 | i | +| test.cpp:235:17:235:17 | 0 | +| test.cpp:235:20:237:5 | { ... } | +| test.cpp:236:9:236:11 | ctr | +| test.cpp:236:9:236:13 | ... ++ | +| test.cpp:236:9:236:14 | ExprStmt | +| test.cpp:238:5:240:5 | if (...) ... | +| test.cpp:238:9:238:10 | (reference dereference) | +| test.cpp:238:9:238:10 | ms | | test.cpp:238:9:238:17 | ... == ... | +| test.cpp:238:12:238:12 | f | +| test.cpp:238:17:238:17 | 0 | +| test.cpp:238:17:238:17 | (float)... | +| test.cpp:238:20:240:5 | { ... } | +| test.cpp:239:9:239:11 | ctr | +| test.cpp:239:9:239:13 | ... ++ | +| test.cpp:239:9:239:14 | ExprStmt | +| test.cpp:241:5:243:5 | if (...) ... | +| test.cpp:241:9:241:10 | (reference dereference) | +| test.cpp:241:9:241:10 | ms | | test.cpp:241:9:241:17 | ... == ... | | test.cpp:241:9:241:30 | ... && ... | | test.cpp:241:9:241:43 | ... && ... | +| test.cpp:241:12:241:12 | i | +| test.cpp:241:17:241:17 | 0 | +| test.cpp:241:22:241:23 | (reference dereference) | +| test.cpp:241:22:241:23 | ms | | test.cpp:241:22:241:30 | ... == ... | +| test.cpp:241:25:241:25 | f | +| test.cpp:241:30:241:30 | 0 | +| test.cpp:241:30:241:30 | (float)... | +| test.cpp:241:35:241:36 | (reference dereference) | +| test.cpp:241:35:241:36 | ms | | test.cpp:241:35:241:43 | ... == ... | +| test.cpp:241:38:241:38 | i | +| test.cpp:241:43:241:43 | 0 | +| test.cpp:241:46:243:5 | { ... } | +| test.cpp:242:9:242:11 | ctr | +| test.cpp:242:9:242:13 | ... ++ | +| test.cpp:242:9:242:14 | ExprStmt | +| test.cpp:244:1:244:1 | return ... | +| test.cpp:246:6:246:21 | definition of test_cmp_implies | +| test.cpp:246:6:246:21 | test_cmp_implies | +| test.cpp:246:27:246:27 | a | +| test.cpp:246:27:246:27 | definition of a | +| test.cpp:246:34:246:34 | b | +| test.cpp:246:34:246:34 | definition of b | +| test.cpp:246:37:284:1 | { ... } | +| test.cpp:247:3:251:3 | if (...) ... | +| test.cpp:247:6:247:13 | (...) | +| test.cpp:247:6:247:13 | (int)... | | test.cpp:247:6:247:18 | ... == ... | +| test.cpp:247:7:247:7 | a | +| test.cpp:247:7:247:12 | ... == ... | +| test.cpp:247:12:247:12 | b | +| test.cpp:247:18:247:18 | 0 | +| test.cpp:247:21:249:3 | { ... } | +| test.cpp:249:10:251:3 | { ... } | +| test.cpp:253:3:257:3 | if (...) ... | +| test.cpp:253:6:253:13 | (...) | +| test.cpp:253:6:253:13 | (int)... | | test.cpp:253:6:253:18 | ... != ... | +| test.cpp:253:7:253:7 | a | +| test.cpp:253:7:253:12 | ... == ... | +| test.cpp:253:12:253:12 | b | +| test.cpp:253:18:253:18 | 0 | +| test.cpp:253:21:255:3 | { ... } | +| test.cpp:255:10:257:3 | { ... } | +| test.cpp:260:3:264:3 | if (...) ... | +| test.cpp:260:6:260:13 | (...) | +| test.cpp:260:6:260:13 | (int)... | | test.cpp:260:6:260:18 | ... == ... | +| test.cpp:260:7:260:7 | a | +| test.cpp:260:7:260:12 | ... != ... | +| test.cpp:260:12:260:12 | b | +| test.cpp:260:18:260:18 | 0 | +| test.cpp:260:21:262:3 | { ... } | +| test.cpp:262:10:264:3 | { ... } | +| test.cpp:266:3:270:3 | if (...) ... | +| test.cpp:266:6:266:13 | (...) | +| test.cpp:266:6:266:13 | (int)... | | test.cpp:266:6:266:18 | ... != ... | +| test.cpp:266:7:266:7 | a | +| test.cpp:266:7:266:12 | ... != ... | +| test.cpp:266:12:266:12 | b | +| test.cpp:266:18:266:18 | 0 | +| test.cpp:266:21:268:3 | { ... } | +| test.cpp:268:10:270:3 | { ... } | +| test.cpp:273:3:277:3 | if (...) ... | +| test.cpp:273:6:273:12 | (...) | +| test.cpp:273:6:273:12 | (int)... | | test.cpp:273:6:273:17 | ... == ... | +| test.cpp:273:7:273:7 | a | +| test.cpp:273:7:273:11 | ... < ... | +| test.cpp:273:11:273:11 | b | +| test.cpp:273:17:273:17 | 0 | +| test.cpp:273:20:275:3 | { ... } | +| test.cpp:275:10:277:3 | { ... } | +| test.cpp:279:3:283:3 | if (...) ... | +| test.cpp:279:6:279:12 | (...) | +| test.cpp:279:6:279:12 | (int)... | | test.cpp:279:6:279:17 | ... != ... | +| test.cpp:279:7:279:7 | a | +| test.cpp:279:7:279:11 | ... < ... | +| test.cpp:279:11:279:11 | b | +| test.cpp:279:17:279:17 | 0 | +| test.cpp:279:20:281:3 | { ... } | +| test.cpp:281:10:283:3 | { ... } | +| test.cpp:284:1:284:1 | return ... | +| test.cpp:286:6:286:27 | definition of test_cmp_implies_unary | +| test.cpp:286:6:286:27 | test_cmp_implies_unary | +| test.cpp:286:33:286:33 | a | +| test.cpp:286:33:286:33 | definition of a | +| test.cpp:286:36:323:1 | { ... } | +| test.cpp:287:3:291:3 | if (...) ... | +| test.cpp:287:6:287:14 | (...) | +| test.cpp:287:6:287:14 | (int)... | | test.cpp:287:6:287:19 | ... == ... | +| test.cpp:287:7:287:7 | a | +| test.cpp:287:7:287:13 | ... == ... | +| test.cpp:287:12:287:13 | 42 | +| test.cpp:287:19:287:19 | 0 | +| test.cpp:287:22:289:3 | { ... } | +| test.cpp:289:10:291:3 | { ... } | +| test.cpp:293:3:297:3 | if (...) ... | +| test.cpp:293:6:293:14 | (...) | +| test.cpp:293:6:293:14 | (int)... | | test.cpp:293:6:293:19 | ... != ... | +| test.cpp:293:7:293:7 | a | +| test.cpp:293:7:293:13 | ... == ... | +| test.cpp:293:12:293:13 | 42 | +| test.cpp:293:19:293:19 | 0 | +| test.cpp:293:22:295:3 | { ... } | +| test.cpp:295:10:297:3 | { ... } | +| test.cpp:300:3:304:3 | if (...) ... | +| test.cpp:300:6:300:14 | (...) | +| test.cpp:300:6:300:14 | (int)... | | test.cpp:300:6:300:19 | ... == ... | +| test.cpp:300:7:300:7 | a | +| test.cpp:300:7:300:13 | ... != ... | +| test.cpp:300:12:300:13 | 42 | +| test.cpp:300:19:300:19 | 0 | +| test.cpp:300:22:302:3 | { ... } | +| test.cpp:302:10:304:3 | { ... } | +| test.cpp:306:3:310:3 | if (...) ... | +| test.cpp:306:6:306:14 | (...) | +| test.cpp:306:6:306:14 | (int)... | | test.cpp:306:6:306:19 | ... != ... | +| test.cpp:306:7:306:7 | a | +| test.cpp:306:7:306:13 | ... != ... | +| test.cpp:306:12:306:13 | 42 | +| test.cpp:306:19:306:19 | 0 | +| test.cpp:306:22:308:3 | { ... } | +| test.cpp:308:10:310:3 | { ... } | +| test.cpp:312:3:316:3 | if (...) ... | +| test.cpp:312:6:312:13 | (...) | +| test.cpp:312:6:312:13 | (int)... | | test.cpp:312:6:312:18 | ... == ... | +| test.cpp:312:7:312:7 | a | +| test.cpp:312:7:312:12 | ... < ... | +| test.cpp:312:11:312:12 | 42 | +| test.cpp:312:18:312:18 | 0 | +| test.cpp:312:21:314:3 | { ... } | +| test.cpp:314:10:316:3 | { ... } | +| test.cpp:318:3:322:3 | if (...) ... | +| test.cpp:318:6:318:13 | (...) | +| test.cpp:318:6:318:13 | (int)... | | test.cpp:318:6:318:18 | ... != ... | +| test.cpp:318:7:318:7 | a | +| test.cpp:318:7:318:12 | ... < ... | +| test.cpp:318:11:318:12 | 42 | +| test.cpp:318:18:318:18 | 0 | +| test.cpp:318:21:320:3 | { ... } | +| test.cpp:320:10:322:3 | { ... } | +| test.cpp:323:1:323:1 | return ... | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected index 5d3232d50faa..d1a3f22d7660 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected @@ -392,6 +392,12 @@ | test.c:206:8:206:8 | c | b >= a+0 when c is false | | test.c:206:8:206:8 | c | c != 0 when c is true | | test.c:206:8:206:8 | c | c == 0 when c is false | +| test.c:215:6:215:18 | ! ... | ... > ... != 0 when ! ... is false | +| test.c:215:6:215:18 | ! ... | ... > ... == 0 when ! ... is true | +| test.c:215:6:215:18 | ! ... | a < b+1 when ! ... is true | +| test.c:215:6:215:18 | ! ... | a >= b+1 when ! ... is false | +| test.c:215:6:215:18 | ! ... | b < a+0 when ! ... is false | +| test.c:215:6:215:18 | ! ... | b >= a+0 when ! ... is true | | test.c:215:6:215:18 | call to __builtin_expect | ... > ... != 0 when call to __builtin_expect is true | | test.c:215:6:215:18 | call to __builtin_expect | ... > ... == 0 when call to __builtin_expect is false | | test.c:215:6:215:18 | call to __builtin_expect | a < b+1 when call to __builtin_expect is false | @@ -402,6 +408,20 @@ | test.c:215:6:215:18 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | | test.c:215:6:215:18 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | | test.c:215:6:215:18 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.c:215:13:215:17 | ... > ... | ... > ... != 0 when ... > ... is true | +| test.c:215:13:215:17 | ... > ... | ... > ... == 0 when ... > ... is false | +| test.c:215:13:215:17 | ... > ... | a < b+1 when ... > ... is false | +| test.c:215:13:215:17 | ... > ... | a >= b+1 when ... > ... is true | +| test.c:215:13:215:17 | ... > ... | b < a+0 when ... > ... is true | +| test.c:215:13:215:17 | ... > ... | b >= a+0 when ... > ... is false | +| test.c:219:9:219:22 | ! ... | 42 < a+0 when ! ... is false | +| test.c:219:9:219:22 | ! ... | 42 >= a+0 when ! ... is true | +| test.c:219:9:219:22 | ! ... | ... > ... != 0 when ! ... is false | +| test.c:219:9:219:22 | ! ... | ... > ... == 0 when ! ... is true | +| test.c:219:9:219:22 | ! ... | a < 42+1 when ! ... is true | +| test.c:219:9:219:22 | ! ... | a < 43 when ! ... is true | +| test.c:219:9:219:22 | ! ... | a >= 42+1 when ! ... is false | +| test.c:219:9:219:22 | ! ... | a >= 43 when ! ... is false | | test.c:219:9:219:22 | call to __builtin_expect | 42 < a+0 when call to __builtin_expect is true | | test.c:219:9:219:22 | call to __builtin_expect | 42 >= a+0 when call to __builtin_expect is false | | test.c:219:9:219:22 | call to __builtin_expect | ... > ... != 0 when call to __builtin_expect is true | @@ -414,6 +434,14 @@ | test.c:219:9:219:22 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | | test.c:219:9:219:22 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | | test.c:219:9:219:22 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.c:219:16:219:21 | ... > ... | 42 < a+0 when ... > ... is true | +| test.c:219:16:219:21 | ... > ... | 42 >= a+0 when ... > ... is false | +| test.c:219:16:219:21 | ... > ... | ... > ... != 0 when ... > ... is true | +| test.c:219:16:219:21 | ... > ... | ... > ... == 0 when ... > ... is false | +| test.c:219:16:219:21 | ... > ... | a < 42+1 when ... > ... is false | +| test.c:219:16:219:21 | ... > ... | a < 43 when ... > ... is false | +| test.c:219:16:219:21 | ... > ... | a >= 42+1 when ... > ... is true | +| test.c:219:16:219:21 | ... > ... | a >= 43 when ... > ... is true | | test.cpp:18:8:18:10 | call to get | call to get != 0 when call to get is true | | test.cpp:18:8:18:10 | call to get | call to get != 1 when call to get is false | | test.cpp:18:8:18:10 | call to get | call to get == 0 when call to get is false | @@ -432,13 +460,52 @@ | test.cpp:42:13:42:20 | call to getABool | call to getABool != 1 when call to getABool is false | | test.cpp:42:13:42:20 | call to getABool | call to getABool == 0 when call to getABool is false | | test.cpp:42:13:42:20 | call to getABool | call to getABool == 1 when call to getABool is true | -| test.cpp:61:10:61:10 | i | i == 0 when i is Case[0] | -| test.cpp:61:10:61:10 | i | i == 1 when i is Case[1] | -| test.cpp:61:10:61:10 | i | i == 2 when i is Case[2] | -| test.cpp:74:10:74:10 | i | i < 11 when i is Case[0..10] | -| test.cpp:74:10:74:10 | i | i < 21 when i is Case[11..20] | -| test.cpp:74:10:74:10 | i | i >= 0 when i is Case[0..10] | -| test.cpp:74:10:74:10 | i | i >= 11 when i is Case[11..20] | +| test.cpp:60:31:60:31 | i | i != 0 when i is not 0 | +| test.cpp:60:31:60:31 | i | i != 1 when i is not 1 | +| test.cpp:60:31:60:31 | i | i != 2 when i is not 2 | +| test.cpp:60:31:60:31 | i | i == 0 when i is 0 | +| test.cpp:60:31:60:31 | i | i == 1 when i is 1 | +| test.cpp:60:31:60:31 | i | i == 2 when i is 2 | +| test.cpp:61:10:61:10 | i | i != 0 when i is not 0 | +| test.cpp:61:10:61:10 | i | i != 1 when i is not 1 | +| test.cpp:61:10:61:10 | i | i != 2 when i is not 2 | +| test.cpp:61:10:61:10 | i | i == 0 when i is 0 | +| test.cpp:61:10:61:10 | i | i == 1 when i is 1 | +| test.cpp:61:10:61:10 | i | i == 2 when i is 2 | +| test.cpp:63:12:63:12 | i | i != 0 when i is not 0 | +| test.cpp:63:12:63:12 | i | i != 1 when i is not 1 | +| test.cpp:63:12:63:12 | i | i != 2 when i is not 2 | +| test.cpp:63:12:63:12 | i | i == 0 when i is 0 | +| test.cpp:63:12:63:12 | i | i == 1 when i is 1 | +| test.cpp:63:12:63:12 | i | i == 2 when i is 2 | +| test.cpp:66:12:66:12 | i | i != 0 when i is not 0 | +| test.cpp:66:12:66:12 | i | i != 1 when i is not 1 | +| test.cpp:66:12:66:12 | i | i != 2 when i is not 2 | +| test.cpp:66:12:66:12 | i | i == 0 when i is 0 | +| test.cpp:66:12:66:12 | i | i == 1 when i is 1 | +| test.cpp:66:12:66:12 | i | i == 2 when i is 2 | +| test.cpp:69:12:69:12 | i | i != 0 when i is not 0 | +| test.cpp:69:12:69:12 | i | i != 1 when i is not 1 | +| test.cpp:69:12:69:12 | i | i != 2 when i is not 2 | +| test.cpp:69:12:69:12 | i | i == 0 when i is 0 | +| test.cpp:69:12:69:12 | i | i == 1 when i is 1 | +| test.cpp:69:12:69:12 | i | i == 2 when i is 2 | +| test.cpp:73:30:73:30 | i | i < 11 when i is 0..10 | +| test.cpp:73:30:73:30 | i | i < 21 when i is 11..20 | +| test.cpp:73:30:73:30 | i | i >= 0 when i is 0..10 | +| test.cpp:73:30:73:30 | i | i >= 11 when i is 11..20 | +| test.cpp:74:10:74:10 | i | i < 11 when i is 0..10 | +| test.cpp:74:10:74:10 | i | i < 21 when i is 11..20 | +| test.cpp:74:10:74:10 | i | i >= 0 when i is 0..10 | +| test.cpp:74:10:74:10 | i | i >= 11 when i is 11..20 | +| test.cpp:76:12:76:12 | i | i < 11 when i is 0..10 | +| test.cpp:76:12:76:12 | i | i < 21 when i is 11..20 | +| test.cpp:76:12:76:12 | i | i >= 0 when i is 0..10 | +| test.cpp:76:12:76:12 | i | i >= 11 when i is 11..20 | +| test.cpp:79:12:79:12 | i | i < 11 when i is 0..10 | +| test.cpp:79:12:79:12 | i | i < 21 when i is 11..20 | +| test.cpp:79:12:79:12 | i | i >= 0 when i is 0..10 | +| test.cpp:79:12:79:12 | i | i >= 11 when i is 11..20 | | test.cpp:93:6:93:6 | c | c != 0 when c is true | | test.cpp:93:6:93:6 | c | c != 1 when c is false | | test.cpp:93:6:93:6 | c | c == 0 when c is false | @@ -463,6 +530,10 @@ | test.cpp:111:6:111:14 | ... != ... | ... != ... == 1 when ... != ... is true | | test.cpp:111:6:111:14 | ... != ... | i != 0.0+0 when ... != ... is true | | test.cpp:111:6:111:14 | ... != ... | i == 0.0+0 when ... != ... is false | +| test.cpp:119:16:119:16 | b | b != 0 when b is true | +| test.cpp:119:16:119:16 | b | b != 1 when b is false | +| test.cpp:119:16:119:16 | b | b == 0 when b is false | +| test.cpp:119:16:119:16 | b | b == 1 when b is true | | test.cpp:122:9:122:9 | b | b != 0 when b is true | | test.cpp:122:9:122:9 | b | b != 1 when b is false | | test.cpp:122:9:122:9 | b | b == 0 when b is false | @@ -495,6 +566,14 @@ | test.cpp:131:6:131:21 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | | test.cpp:131:6:131:21 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | | test.cpp:131:6:131:21 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.cpp:131:23:131:33 | ... == ... | ... + ... != a+0 when ... == ... is false | +| test.cpp:131:23:131:33 | ... == ... | ... + ... == a+0 when ... == ... is true | +| test.cpp:131:23:131:33 | ... == ... | a != ... + ...+0 when ... == ... is false | +| test.cpp:131:23:131:33 | ... == ... | a != b+42 when ... == ... is false | +| test.cpp:131:23:131:33 | ... == ... | a == ... + ...+0 when ... == ... is true | +| test.cpp:131:23:131:33 | ... == ... | a == b+42 when ... == ... is true | +| test.cpp:131:23:131:33 | ... == ... | b != a+-42 when ... == ... is false | +| test.cpp:131:23:131:33 | ... == ... | b == a+-42 when ... == ... is true | | test.cpp:135:6:135:21 | call to __builtin_expect | ... + ... != a+0 when call to __builtin_expect is true | | test.cpp:135:6:135:21 | call to __builtin_expect | ... + ... == a+0 when call to __builtin_expect is false | | test.cpp:135:6:135:21 | call to __builtin_expect | a != ... + ...+0 when call to __builtin_expect is true | @@ -507,6 +586,14 @@ | test.cpp:135:6:135:21 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | | test.cpp:135:6:135:21 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | | test.cpp:135:6:135:21 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.cpp:135:23:135:33 | ... != ... | ... + ... != a+0 when ... != ... is true | +| test.cpp:135:23:135:33 | ... != ... | ... + ... == a+0 when ... != ... is false | +| test.cpp:135:23:135:33 | ... != ... | a != ... + ...+0 when ... != ... is true | +| test.cpp:135:23:135:33 | ... != ... | a != b+42 when ... != ... is true | +| test.cpp:135:23:135:33 | ... != ... | a == ... + ...+0 when ... != ... is false | +| test.cpp:135:23:135:33 | ... != ... | a == b+42 when ... != ... is false | +| test.cpp:135:23:135:33 | ... != ... | b != a+-42 when ... != ... is true | +| test.cpp:135:23:135:33 | ... != ... | b == a+-42 when ... != ... is false | | test.cpp:141:6:141:21 | call to __builtin_expect | 42 != a+0 when call to __builtin_expect is false | | test.cpp:141:6:141:21 | call to __builtin_expect | 42 == a+0 when call to __builtin_expect is true | | test.cpp:141:6:141:21 | call to __builtin_expect | a != 42 when call to __builtin_expect is false | @@ -517,6 +604,12 @@ | test.cpp:141:6:141:21 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | | test.cpp:141:6:141:21 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | | test.cpp:141:6:141:21 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.cpp:141:23:141:29 | ... == ... | 42 != a+0 when ... == ... is false | +| test.cpp:141:23:141:29 | ... == ... | 42 == a+0 when ... == ... is true | +| test.cpp:141:23:141:29 | ... == ... | a != 42 when ... == ... is false | +| test.cpp:141:23:141:29 | ... == ... | a != 42+0 when ... == ... is false | +| test.cpp:141:23:141:29 | ... == ... | a == 42 when ... == ... is true | +| test.cpp:141:23:141:29 | ... == ... | a == 42+0 when ... == ... is true | | test.cpp:145:6:145:21 | call to __builtin_expect | 42 != a+0 when call to __builtin_expect is true | | test.cpp:145:6:145:21 | call to __builtin_expect | 42 == a+0 when call to __builtin_expect is false | | test.cpp:145:6:145:21 | call to __builtin_expect | a != 42 when call to __builtin_expect is true | @@ -527,6 +620,26 @@ | test.cpp:145:6:145:21 | call to __builtin_expect | call to __builtin_expect != 1 when call to __builtin_expect is false | | test.cpp:145:6:145:21 | call to __builtin_expect | call to __builtin_expect == 0 when call to __builtin_expect is false | | test.cpp:145:6:145:21 | call to __builtin_expect | call to __builtin_expect == 1 when call to __builtin_expect is true | +| test.cpp:145:23:145:29 | ... != ... | 42 != a+0 when ... != ... is true | +| test.cpp:145:23:145:29 | ... != ... | 42 == a+0 when ... != ... is false | +| test.cpp:145:23:145:29 | ... != ... | a != 42 when ... != ... is true | +| test.cpp:145:23:145:29 | ... != ... | a != 42+0 when ... != ... is true | +| test.cpp:145:23:145:29 | ... != ... | a == 42 when ... != ... is false | +| test.cpp:145:23:145:29 | ... != ... | a == 42+0 when ... != ... is false | +| test.cpp:151:8:151:13 | ... < ... | 10 < a+1 when ... < ... is false | +| test.cpp:151:8:151:13 | ... < ... | 10 >= a+1 when ... < ... is true | +| test.cpp:151:8:151:13 | ... < ... | ... < ... != 0 when ... < ... is true | +| test.cpp:151:8:151:13 | ... < ... | ... < ... != 1 when ... < ... is false | +| test.cpp:151:8:151:13 | ... < ... | ... < ... == 0 when ... < ... is false | +| test.cpp:151:8:151:13 | ... < ... | ... < ... == 1 when ... < ... is true | +| test.cpp:151:8:151:13 | ... < ... | a < 10 when ... < ... is true | +| test.cpp:151:8:151:13 | ... < ... | a < 10+0 when ... < ... is true | +| test.cpp:151:8:151:13 | ... < ... | a >= 10 when ... < ... is false | +| test.cpp:151:8:151:13 | ... < ... | a >= 10+0 when ... < ... is false | +| test.cpp:151:8:151:13 | ... < ... | b != 0 when ... < ... is true | +| test.cpp:151:8:151:13 | ... < ... | b != 1 when ... < ... is false | +| test.cpp:151:8:151:13 | ... < ... | b == 0 when ... < ... is false | +| test.cpp:151:8:151:13 | ... < ... | b == 1 when ... < ... is true | | test.cpp:152:7:152:8 | ! ... | 10 < a+1 when ! ... is true | | test.cpp:152:7:152:8 | ! ... | 10 >= a+1 when ! ... is false | | test.cpp:152:7:152:8 | ! ... | ! ... != 0 when ! ... is true | @@ -563,6 +676,18 @@ | test.cpp:152:8:152:8 | b | b != 1 when b is false | | test.cpp:152:8:152:8 | b | b == 0 when b is false | | test.cpp:152:8:152:8 | b | b == 1 when b is true | +| test.cpp:158:12:158:17 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.cpp:158:12:158:17 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.cpp:158:12:158:17 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.cpp:158:12:158:17 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.cpp:158:12:158:17 | ... != ... | a != b+0 when ... != ... is true | +| test.cpp:158:12:158:17 | ... != ... | a == b+0 when ... != ... is false | +| test.cpp:158:12:158:17 | ... != ... | b != a+0 when ... != ... is true | +| test.cpp:158:12:158:17 | ... != ... | b == a+0 when ... != ... is false | +| test.cpp:158:12:158:17 | ... != ... | c != 0 when ... != ... is true | +| test.cpp:158:12:158:17 | ... != ... | c != 1 when ... != ... is false | +| test.cpp:158:12:158:17 | ... != ... | c == 0 when ... != ... is false | +| test.cpp:158:12:158:17 | ... != ... | c == 1 when ... != ... is true | | test.cpp:160:7:160:8 | ! ... | ! ... != 0 when ! ... is true | | test.cpp:160:7:160:8 | ! ... | ! ... != 1 when ! ... is false | | test.cpp:160:7:160:8 | ! ... | ! ... == 0 when ! ... is false | @@ -595,6 +720,20 @@ | test.cpp:160:8:160:8 | c | c != 1 when c is false | | test.cpp:160:8:160:8 | c | c == 0 when c is false | | test.cpp:160:8:160:8 | c | c == 1 when c is true | +| test.cpp:166:12:166:17 | ... > ... | 10 < a+0 when ... > ... is true | +| test.cpp:166:12:166:17 | ... > ... | 10 >= a+0 when ... > ... is false | +| test.cpp:166:12:166:17 | ... > ... | ... > ... != 0 when ... > ... is true | +| test.cpp:166:12:166:17 | ... > ... | ... > ... != 1 when ... > ... is false | +| test.cpp:166:12:166:17 | ... > ... | ... > ... == 0 when ... > ... is false | +| test.cpp:166:12:166:17 | ... > ... | ... > ... == 1 when ... > ... is true | +| test.cpp:166:12:166:17 | ... > ... | a < 10+1 when ... > ... is false | +| test.cpp:166:12:166:17 | ... > ... | a < 11 when ... > ... is false | +| test.cpp:166:12:166:17 | ... > ... | a >= 10+1 when ... > ... is true | +| test.cpp:166:12:166:17 | ... > ... | a >= 11 when ... > ... is true | +| test.cpp:166:12:166:17 | ... > ... | b != 0 when ... > ... is true | +| test.cpp:166:12:166:17 | ... > ... | b != 1 when ... > ... is false | +| test.cpp:166:12:166:17 | ... > ... | b == 0 when ... > ... is false | +| test.cpp:166:12:166:17 | ... > ... | b == 1 when ... > ... is true | | test.cpp:168:7:168:8 | ! ... | 10 < a+0 when ! ... is false | | test.cpp:168:7:168:8 | ! ... | 10 >= a+0 when ! ... is true | | test.cpp:168:7:168:8 | ! ... | ! ... != 0 when ! ... is true | @@ -631,6 +770,18 @@ | test.cpp:168:8:168:8 | b | b != 1 when b is false | | test.cpp:168:8:168:8 | b | b == 0 when b is false | | test.cpp:168:8:168:8 | b | b == 1 when b is true | +| test.cpp:174:12:174:16 | ... > ... | ... > ... != 0 when ... > ... is true | +| test.cpp:174:12:174:16 | ... > ... | ... > ... != 1 when ... > ... is false | +| test.cpp:174:12:174:16 | ... > ... | ... > ... == 0 when ... > ... is false | +| test.cpp:174:12:174:16 | ... > ... | ... > ... == 1 when ... > ... is true | +| test.cpp:174:12:174:16 | ... > ... | a < b+1 when ... > ... is false | +| test.cpp:174:12:174:16 | ... > ... | a >= b+1 when ... > ... is true | +| test.cpp:174:12:174:16 | ... > ... | b < a+0 when ... > ... is true | +| test.cpp:174:12:174:16 | ... > ... | b >= a+0 when ... > ... is false | +| test.cpp:174:12:174:16 | ... > ... | c != 0 when ... > ... is true | +| test.cpp:174:12:174:16 | ... > ... | c != 1 when ... > ... is false | +| test.cpp:174:12:174:16 | ... > ... | c == 0 when ... > ... is false | +| test.cpp:174:12:174:16 | ... > ... | c == 1 when ... > ... is true | | test.cpp:176:7:176:8 | ! ... | ! ... != 0 when ! ... is true | | test.cpp:176:7:176:8 | ! ... | ! ... != 1 when ! ... is false | | test.cpp:176:7:176:8 | ! ... | ! ... == 0 when ! ... is false | @@ -663,6 +814,14 @@ | test.cpp:176:8:176:8 | c | c != 1 when c is false | | test.cpp:176:8:176:8 | c | c == 0 when c is false | | test.cpp:176:8:176:8 | c | c == 1 when c is true | +| test.cpp:181:28:181:29 | b1 | b1 != 0 when b1 is true | +| test.cpp:181:28:181:29 | b1 | b1 != 1 when b1 is false | +| test.cpp:181:28:181:29 | b1 | b1 == 0 when b1 is false | +| test.cpp:181:28:181:29 | b1 | b1 == 1 when b1 is true | +| test.cpp:181:37:181:38 | b2 | b2 != 0 when b2 is true | +| test.cpp:181:37:181:38 | b2 | b2 != 1 when b2 is false | +| test.cpp:181:37:181:38 | b2 | b2 == 0 when b2 is false | +| test.cpp:181:37:181:38 | b2 | b2 == 1 when b2 is true | | test.cpp:182:6:182:16 | ! ... | ! ... != 0 when ! ... is true | | test.cpp:182:6:182:16 | ! ... | ! ... != 1 when ! ... is false | | test.cpp:182:6:182:16 | ! ... | ! ... == 0 when ! ... is false | @@ -695,6 +854,30 @@ | test.cpp:182:14:182:15 | b2 | b2 != 1 when b2 is false | | test.cpp:182:14:182:15 | b2 | b2 == 0 when b2 is false | | test.cpp:182:14:182:15 | b2 | b2 == 1 when b2 is true | +| test.cpp:183:9:183:10 | b1 | b1 != 0 when b1 is true | +| test.cpp:183:9:183:10 | b1 | b1 != 1 when b1 is false | +| test.cpp:183:9:183:10 | b1 | b1 == 0 when b1 is false | +| test.cpp:183:9:183:10 | b1 | b1 == 1 when b1 is true | +| test.cpp:184:9:184:10 | b2 | b2 != 0 when b2 is true | +| test.cpp:184:9:184:10 | b2 | b2 != 1 when b2 is false | +| test.cpp:184:9:184:10 | b2 | b2 == 0 when b2 is false | +| test.cpp:184:9:184:10 | b2 | b2 == 1 when b2 is true | +| test.cpp:187:9:187:10 | b1 | b1 != 0 when b1 is true | +| test.cpp:187:9:187:10 | b1 | b1 != 1 when b1 is false | +| test.cpp:187:9:187:10 | b1 | b1 == 0 when b1 is false | +| test.cpp:187:9:187:10 | b1 | b1 == 1 when b1 is true | +| test.cpp:188:9:188:10 | b2 | b2 != 0 when b2 is true | +| test.cpp:188:9:188:10 | b2 | b2 != 1 when b2 is false | +| test.cpp:188:9:188:10 | b2 | b2 == 0 when b2 is false | +| test.cpp:188:9:188:10 | b2 | b2 == 1 when b2 is true | +| test.cpp:192:27:192:28 | b1 | b1 != 0 when b1 is true | +| test.cpp:192:27:192:28 | b1 | b1 != 1 when b1 is false | +| test.cpp:192:27:192:28 | b1 | b1 == 0 when b1 is false | +| test.cpp:192:27:192:28 | b1 | b1 == 1 when b1 is true | +| test.cpp:192:36:192:37 | b2 | b2 != 0 when b2 is true | +| test.cpp:192:36:192:37 | b2 | b2 != 1 when b2 is false | +| test.cpp:192:36:192:37 | b2 | b2 == 0 when b2 is false | +| test.cpp:192:36:192:37 | b2 | b2 == 1 when b2 is true | | test.cpp:193:6:193:16 | ! ... | ! ... != 0 when ! ... is true | | test.cpp:193:6:193:16 | ! ... | ! ... != 1 when ! ... is false | | test.cpp:193:6:193:16 | ! ... | ! ... == 0 when ! ... is false | @@ -727,6 +910,22 @@ | test.cpp:193:14:193:15 | b2 | b2 != 1 when b2 is false | | test.cpp:193:14:193:15 | b2 | b2 == 0 when b2 is false | | test.cpp:193:14:193:15 | b2 | b2 == 1 when b2 is true | +| test.cpp:195:9:195:10 | b1 | b1 != 0 when b1 is true | +| test.cpp:195:9:195:10 | b1 | b1 != 1 when b1 is false | +| test.cpp:195:9:195:10 | b1 | b1 == 0 when b1 is false | +| test.cpp:195:9:195:10 | b1 | b1 == 1 when b1 is true | +| test.cpp:196:9:196:10 | b2 | b2 != 0 when b2 is true | +| test.cpp:196:9:196:10 | b2 | b2 != 1 when b2 is false | +| test.cpp:196:9:196:10 | b2 | b2 == 0 when b2 is false | +| test.cpp:196:9:196:10 | b2 | b2 == 1 when b2 is true | +| test.cpp:198:9:198:10 | b1 | b1 != 0 when b1 is true | +| test.cpp:198:9:198:10 | b1 | b1 != 1 when b1 is false | +| test.cpp:198:9:198:10 | b1 | b1 == 0 when b1 is false | +| test.cpp:198:9:198:10 | b1 | b1 == 1 when b1 is true | +| test.cpp:199:9:199:10 | b2 | b2 != 0 when b2 is true | +| test.cpp:199:9:199:10 | b2 | b2 != 1 when b2 is false | +| test.cpp:199:9:199:10 | b2 | b2 == 0 when b2 is false | +| test.cpp:199:9:199:10 | b2 | b2 == 1 when b2 is true | | test.cpp:211:9:211:15 | ... == ... | 0 != sc+0 when ... == ... is false | | test.cpp:211:9:211:15 | ... == ... | 0 == sc+0 when ... == ... is true | | test.cpp:211:9:211:15 | ... == ... | ... == ... != 0 when ... == ... is true | @@ -875,6 +1074,10 @@ | test.cpp:247:6:247:18 | ... == ... | a == b+0 when ... == ... is false | | test.cpp:247:6:247:18 | ... == ... | b != a+0 when ... == ... is true | | test.cpp:247:6:247:18 | ... == ... | b == a+0 when ... == ... is false | +| test.cpp:247:7:247:12 | ... == ... | a != b+0 when ... == ... is false | +| test.cpp:247:7:247:12 | ... == ... | a == b+0 when ... == ... is true | +| test.cpp:247:7:247:12 | ... == ... | b != a+0 when ... == ... is false | +| test.cpp:247:7:247:12 | ... == ... | b == a+0 when ... == ... is true | | test.cpp:253:6:253:18 | ... != ... | 0 != ... == ...+0 when ... != ... is true | | test.cpp:253:6:253:18 | ... != ... | 0 == ... == ...+0 when ... != ... is false | | test.cpp:253:6:253:18 | ... != ... | ... != ... != 0 when ... != ... is true | @@ -889,6 +1092,10 @@ | test.cpp:253:6:253:18 | ... != ... | a == b+0 when ... != ... is true | | test.cpp:253:6:253:18 | ... != ... | b != a+0 when ... != ... is false | | test.cpp:253:6:253:18 | ... != ... | b == a+0 when ... != ... is true | +| test.cpp:253:7:253:12 | ... == ... | a != b+0 when ... == ... is false | +| test.cpp:253:7:253:12 | ... == ... | a == b+0 when ... == ... is true | +| test.cpp:253:7:253:12 | ... == ... | b != a+0 when ... == ... is false | +| test.cpp:253:7:253:12 | ... == ... | b == a+0 when ... == ... is true | | test.cpp:260:6:260:18 | ... == ... | 0 != ... != ...+0 when ... == ... is false | | test.cpp:260:6:260:18 | ... == ... | 0 == ... != ...+0 when ... == ... is true | | test.cpp:260:6:260:18 | ... == ... | ... != ... != 0 when ... == ... is false | @@ -903,6 +1110,10 @@ | test.cpp:260:6:260:18 | ... == ... | a == b+0 when ... == ... is true | | test.cpp:260:6:260:18 | ... == ... | b != a+0 when ... == ... is false | | test.cpp:260:6:260:18 | ... == ... | b == a+0 when ... == ... is true | +| test.cpp:260:7:260:12 | ... != ... | a != b+0 when ... != ... is true | +| test.cpp:260:7:260:12 | ... != ... | a == b+0 when ... != ... is false | +| test.cpp:260:7:260:12 | ... != ... | b != a+0 when ... != ... is true | +| test.cpp:260:7:260:12 | ... != ... | b == a+0 when ... != ... is false | | test.cpp:266:6:266:18 | ... != ... | 0 != ... != ...+0 when ... != ... is true | | test.cpp:266:6:266:18 | ... != ... | 0 == ... != ...+0 when ... != ... is false | | test.cpp:266:6:266:18 | ... != ... | ... != ... != 0 when ... != ... is true | @@ -915,6 +1126,10 @@ | test.cpp:266:6:266:18 | ... != ... | a == b+0 when ... != ... is false | | test.cpp:266:6:266:18 | ... != ... | b != a+0 when ... != ... is true | | test.cpp:266:6:266:18 | ... != ... | b == a+0 when ... != ... is false | +| test.cpp:266:7:266:12 | ... != ... | a != b+0 when ... != ... is true | +| test.cpp:266:7:266:12 | ... != ... | a == b+0 when ... != ... is false | +| test.cpp:266:7:266:12 | ... != ... | b != a+0 when ... != ... is true | +| test.cpp:266:7:266:12 | ... != ... | b == a+0 when ... != ... is false | | test.cpp:273:6:273:17 | ... == ... | 0 != ... < ...+0 when ... == ... is false | | test.cpp:273:6:273:17 | ... == ... | 0 == ... < ...+0 when ... == ... is true | | test.cpp:273:6:273:17 | ... == ... | ... < ... != 0 when ... == ... is false | @@ -929,6 +1144,10 @@ | test.cpp:273:6:273:17 | ... == ... | a >= b+0 when ... == ... is true | | test.cpp:273:6:273:17 | ... == ... | b < a+1 when ... == ... is true | | test.cpp:273:6:273:17 | ... == ... | b >= a+1 when ... == ... is false | +| test.cpp:273:7:273:11 | ... < ... | a < b+0 when ... < ... is true | +| test.cpp:273:7:273:11 | ... < ... | a >= b+0 when ... < ... is false | +| test.cpp:273:7:273:11 | ... < ... | b < a+1 when ... < ... is false | +| test.cpp:273:7:273:11 | ... < ... | b >= a+1 when ... < ... is true | | test.cpp:279:6:279:17 | ... != ... | 0 != ... < ...+0 when ... != ... is true | | test.cpp:279:6:279:17 | ... != ... | 0 == ... < ...+0 when ... != ... is false | | test.cpp:279:6:279:17 | ... != ... | ... != ... != 0 when ... != ... is true | @@ -943,6 +1162,10 @@ | test.cpp:279:6:279:17 | ... != ... | a >= b+0 when ... != ... is false | | test.cpp:279:6:279:17 | ... != ... | b < a+1 when ... != ... is false | | test.cpp:279:6:279:17 | ... != ... | b >= a+1 when ... != ... is true | +| test.cpp:279:7:279:11 | ... < ... | a < b+0 when ... < ... is true | +| test.cpp:279:7:279:11 | ... < ... | a >= b+0 when ... < ... is false | +| test.cpp:279:7:279:11 | ... < ... | b < a+1 when ... < ... is false | +| test.cpp:279:7:279:11 | ... < ... | b >= a+1 when ... < ... is true | | test.cpp:287:6:287:19 | ... == ... | 0 != ... == ...+0 when ... == ... is false | | test.cpp:287:6:287:19 | ... == ... | 0 == ... == ...+0 when ... == ... is true | | test.cpp:287:6:287:19 | ... == ... | 42 != a+0 when ... == ... is true | @@ -959,6 +1182,12 @@ | test.cpp:287:6:287:19 | ... == ... | a != 42+0 when ... == ... is true | | test.cpp:287:6:287:19 | ... == ... | a == 42 when ... == ... is false | | test.cpp:287:6:287:19 | ... == ... | a == 42+0 when ... == ... is false | +| test.cpp:287:7:287:13 | ... == ... | 42 != a+0 when ... == ... is false | +| test.cpp:287:7:287:13 | ... == ... | 42 == a+0 when ... == ... is true | +| test.cpp:287:7:287:13 | ... == ... | a != 42 when ... == ... is false | +| test.cpp:287:7:287:13 | ... == ... | a != 42+0 when ... == ... is false | +| test.cpp:287:7:287:13 | ... == ... | a == 42 when ... == ... is true | +| test.cpp:287:7:287:13 | ... == ... | a == 42+0 when ... == ... is true | | test.cpp:293:6:293:19 | ... != ... | 0 != ... == ...+0 when ... != ... is true | | test.cpp:293:6:293:19 | ... != ... | 0 == ... == ...+0 when ... != ... is false | | test.cpp:293:6:293:19 | ... != ... | 42 != a+0 when ... != ... is false | @@ -975,6 +1204,12 @@ | test.cpp:293:6:293:19 | ... != ... | a != 42+0 when ... != ... is false | | test.cpp:293:6:293:19 | ... != ... | a == 42 when ... != ... is true | | test.cpp:293:6:293:19 | ... != ... | a == 42+0 when ... != ... is true | +| test.cpp:293:7:293:13 | ... == ... | 42 != a+0 when ... == ... is false | +| test.cpp:293:7:293:13 | ... == ... | 42 == a+0 when ... == ... is true | +| test.cpp:293:7:293:13 | ... == ... | a != 42 when ... == ... is false | +| test.cpp:293:7:293:13 | ... == ... | a != 42+0 when ... == ... is false | +| test.cpp:293:7:293:13 | ... == ... | a == 42 when ... == ... is true | +| test.cpp:293:7:293:13 | ... == ... | a == 42+0 when ... == ... is true | | test.cpp:300:6:300:19 | ... == ... | 0 != ... != ...+0 when ... == ... is false | | test.cpp:300:6:300:19 | ... == ... | 0 == ... != ...+0 when ... == ... is true | | test.cpp:300:6:300:19 | ... == ... | 42 != a+0 when ... == ... is false | @@ -991,6 +1226,12 @@ | test.cpp:300:6:300:19 | ... == ... | a != 42+0 when ... == ... is false | | test.cpp:300:6:300:19 | ... == ... | a == 42 when ... == ... is true | | test.cpp:300:6:300:19 | ... == ... | a == 42+0 when ... == ... is true | +| test.cpp:300:7:300:13 | ... != ... | 42 != a+0 when ... != ... is true | +| test.cpp:300:7:300:13 | ... != ... | 42 == a+0 when ... != ... is false | +| test.cpp:300:7:300:13 | ... != ... | a != 42 when ... != ... is true | +| test.cpp:300:7:300:13 | ... != ... | a != 42+0 when ... != ... is true | +| test.cpp:300:7:300:13 | ... != ... | a == 42 when ... != ... is false | +| test.cpp:300:7:300:13 | ... != ... | a == 42+0 when ... != ... is false | | test.cpp:306:6:306:19 | ... != ... | 0 != ... != ...+0 when ... != ... is true | | test.cpp:306:6:306:19 | ... != ... | 0 == ... != ...+0 when ... != ... is false | | test.cpp:306:6:306:19 | ... != ... | 42 != a+0 when ... != ... is true | @@ -1005,6 +1246,12 @@ | test.cpp:306:6:306:19 | ... != ... | a != 42+0 when ... != ... is true | | test.cpp:306:6:306:19 | ... != ... | a == 42 when ... != ... is false | | test.cpp:306:6:306:19 | ... != ... | a == 42+0 when ... != ... is false | +| test.cpp:306:7:306:13 | ... != ... | 42 != a+0 when ... != ... is true | +| test.cpp:306:7:306:13 | ... != ... | 42 == a+0 when ... != ... is false | +| test.cpp:306:7:306:13 | ... != ... | a != 42 when ... != ... is true | +| test.cpp:306:7:306:13 | ... != ... | a != 42+0 when ... != ... is true | +| test.cpp:306:7:306:13 | ... != ... | a == 42 when ... != ... is false | +| test.cpp:306:7:306:13 | ... != ... | a == 42+0 when ... != ... is false | | test.cpp:312:6:312:18 | ... == ... | 0 != ... < ...+0 when ... == ... is false | | test.cpp:312:6:312:18 | ... == ... | 0 == ... < ...+0 when ... == ... is true | | test.cpp:312:6:312:18 | ... == ... | 42 < a+1 when ... == ... is true | @@ -1021,6 +1268,12 @@ | test.cpp:312:6:312:18 | ... == ... | a < 42+0 when ... == ... is false | | test.cpp:312:6:312:18 | ... == ... | a >= 42 when ... == ... is true | | test.cpp:312:6:312:18 | ... == ... | a >= 42+0 when ... == ... is true | +| test.cpp:312:7:312:12 | ... < ... | 42 < a+1 when ... < ... is false | +| test.cpp:312:7:312:12 | ... < ... | 42 >= a+1 when ... < ... is true | +| test.cpp:312:7:312:12 | ... < ... | a < 42 when ... < ... is true | +| test.cpp:312:7:312:12 | ... < ... | a < 42+0 when ... < ... is true | +| test.cpp:312:7:312:12 | ... < ... | a >= 42 when ... < ... is false | +| test.cpp:312:7:312:12 | ... < ... | a >= 42+0 when ... < ... is false | | test.cpp:318:6:318:18 | ... != ... | 0 != ... < ...+0 when ... != ... is true | | test.cpp:318:6:318:18 | ... != ... | 0 == ... < ...+0 when ... != ... is false | | test.cpp:318:6:318:18 | ... != ... | 42 < a+1 when ... != ... is false | @@ -1037,3 +1290,9 @@ | test.cpp:318:6:318:18 | ... != ... | a < 42+0 when ... != ... is true | | test.cpp:318:6:318:18 | ... != ... | a >= 42 when ... != ... is false | | test.cpp:318:6:318:18 | ... != ... | a >= 42+0 when ... != ... is false | +| test.cpp:318:7:318:12 | ... < ... | 42 < a+1 when ... < ... is false | +| test.cpp:318:7:318:12 | ... < ... | 42 >= a+1 when ... < ... is true | +| test.cpp:318:7:318:12 | ... < ... | a < 42 when ... < ... is true | +| test.cpp:318:7:318:12 | ... < ... | a < 42+0 when ... < ... is true | +| test.cpp:318:7:318:12 | ... < ... | a >= 42 when ... < ... is false | +| test.cpp:318:7:318:12 | ... < ... | a >= 42+0 when ... < ... is false | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected index 05afe345b8c4..078d8aeea086 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected @@ -43,16 +43,36 @@ | test.c:44:12:44:16 | ... > ... | true | test.c:45:13:45:20 | if (...) ... | | test.c:44:12:44:16 | ... > ... | true | test.c:45:23:47:22 | { ... } | | test.c:45:16:45:20 | ... > ... | true | test.c:45:23:47:22 | { ... } | +| test.c:58:9:58:9 | x | not 0 | test.c:58:19:58:23 | y | +| test.c:58:9:58:9 | x | not 0 | test.c:62:9:62:16 | return ... | | test.c:58:9:58:14 | ... == ... | false | test.c:58:19:58:23 | y | | test.c:58:9:58:14 | ... == ... | false | test.c:62:9:62:16 | return ... | | test.c:58:9:58:23 | ... \|\| ... | false | test.c:62:9:62:16 | return ... | | test.c:58:19:58:23 | ... < ... | false | test.c:62:9:62:16 | return ... | +| test.c:70:15:70:15 | x | 0 | test.c:75:17:77:14 | { ... } | +| test.c:70:15:70:15 | x | 0 | test.c:85:18:85:23 | y | +| test.c:70:15:70:15 | x | 0 | test.c:86:9:86:14 | ExprStmt | +| test.c:70:15:70:15 | x | not 0 | test.c:78:12:79:14 | { ... } | +| test.c:75:9:75:9 | x | 0 | test.c:75:17:77:14 | { ... } | +| test.c:75:9:75:9 | x | not 0 | test.c:78:12:79:14 | { ... } | | test.c:75:9:75:14 | ... == ... | false | test.c:78:12:79:14 | { ... } | | test.c:75:9:75:14 | ... == ... | true | test.c:75:17:77:14 | { ... } | +| test.c:85:8:85:8 | x | 0 | test.c:85:18:85:23 | y | +| test.c:85:8:85:8 | x | 0 | test.c:86:9:86:14 | ExprStmt | | test.c:85:8:85:13 | ... == ... | true | test.c:85:18:85:23 | y | | test.c:85:8:85:13 | ... == ... | true | test.c:86:9:86:14 | ExprStmt | | test.c:85:8:85:23 | ... && ... | true | test.c:86:9:86:14 | ExprStmt | +| test.c:85:18:85:18 | y | not 0 | test.c:86:9:86:14 | ExprStmt | | test.c:85:18:85:23 | ... != ... | true | test.c:86:9:86:14 | ExprStmt | +| test.c:94:11:94:11 | x | 0 | test.c:70:5:70:9 | test2 | +| test.c:94:11:94:11 | x | 0 | test.c:99:5:102:13 | ExprStmt | +| test.c:94:11:94:11 | x | 0 | test.c:102:16:102:21 | j | +| test.c:94:11:94:11 | x | 0 | test.c:102:29:102:26 | { ... } | +| test.c:94:11:94:11 | x | 0 | test.c:107:5:109:14 | ExprStmt | +| test.c:94:11:94:11 | x | 0 | test.c:109:19:109:23 | y | +| test.c:94:11:94:11 | x | 0 | test.c:109:26:117:12 | { ... } | +| test.c:94:11:94:11 | x | 0 | test.c:113:9:113:16 | return ... | +| test.c:94:11:94:11 | x | not 0 | test.c:94:19:96:11 | { ... } | | test.c:94:11:94:16 | ... != ... | false | test.c:70:5:70:9 | test2 | | test.c:94:11:94:16 | ... != ... | false | test.c:99:5:102:13 | ExprStmt | | test.c:94:11:94:16 | ... != ... | false | test.c:102:16:102:21 | j | @@ -68,98 +88,184 @@ | test.c:102:16:102:21 | ... < ... | false | test.c:109:26:117:12 | { ... } | | test.c:102:16:102:21 | ... < ... | false | test.c:113:9:113:16 | return ... | | test.c:102:16:102:21 | ... < ... | true | test.c:102:29:102:26 | { ... } | +| test.c:109:9:109:9 | x | not 0 | test.c:109:19:109:23 | y | +| test.c:109:9:109:9 | x | not 0 | test.c:113:9:113:16 | return ... | | test.c:109:9:109:14 | ... == ... | false | test.c:109:19:109:23 | y | | test.c:109:9:109:14 | ... == ... | false | test.c:113:9:113:16 | return ... | | test.c:109:9:109:23 | ... \|\| ... | false | test.c:113:9:113:16 | return ... | | test.c:109:19:109:23 | ... < ... | false | test.c:113:9:113:16 | return ... | +| test.c:126:7:126:7 | 1 | not 0 | test.c:126:12:126:26 | call to test3_condition | +| test.c:126:7:126:7 | 1 | not 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:7 | 1 | not 0 | test.c:131:3:131:7 | if (...) ... | +| test.c:126:7:126:7 | 1 | not 0 | test.c:131:10:132:16 | { ... } | +| test.c:126:7:126:7 | 1 | not 0 | test.c:134:1:123:10 | return ... | | test.c:126:7:126:7 | 1 | true | test.c:126:12:126:26 | call to test3_condition | | test.c:126:7:126:7 | 1 | true | test.c:126:31:128:16 | { ... } | | test.c:126:7:126:7 | 1 | true | test.c:131:3:131:7 | if (...) ... | | test.c:126:7:126:7 | 1 | true | test.c:131:10:132:16 | { ... } | | test.c:126:7:126:7 | 1 | true | test.c:134:1:123:10 | return ... | +| test.c:126:7:126:28 | ... && ... | not 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | not 0 | test.c:131:10:132:16 | { ... } | | test.c:126:7:126:28 | ... && ... | true | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | true | test.c:131:10:132:16 | { ... } | +| test.c:126:12:126:26 | call to test3_condition | not 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:12:126:26 | call to test3_condition | not 0 | test.c:131:10:132:16 | { ... } | | test.c:126:12:126:26 | call to test3_condition | true | test.c:126:31:128:16 | { ... } | +| test.c:126:12:126:26 | call to test3_condition | true | test.c:131:10:132:16 | { ... } | +| test.c:127:9:127:9 | 1 | not 0 | test.c:131:10:132:16 | { ... } | +| test.c:131:7:131:7 | b | not 0 | test.c:131:10:132:16 | { ... } | | test.c:131:7:131:7 | b | true | test.c:131:10:132:16 | { ... } | +| test.c:137:7:137:7 | 0 | 0 | test.c:142:3:136:10 | return ... | | test.c:137:7:137:7 | 0 | false | test.c:142:3:136:10 | return ... | +| test.c:145:16:145:16 | x | 0 | test.c:146:11:147:9 | { ... } | | test.c:146:7:146:8 | ! ... | true | test.c:146:11:147:9 | { ... } | +| test.c:146:8:146:8 | x | 0 | test.c:146:11:147:9 | { ... } | | test.c:146:8:146:8 | x | false | test.c:146:11:147:9 | { ... } | +| test.c:151:18:151:18 | p | not null | test.c:152:11:154:5 | { ... } | +| test.c:152:8:152:8 | p | not null | test.c:152:11:154:5 | { ... } | | test.c:152:8:152:8 | p | true | test.c:152:11:154:5 | { ... } | +| test.c:157:18:157:18 | p | null | test.c:158:12:160:5 | { ... } | | test.c:158:8:158:9 | ! ... | true | test.c:158:12:160:5 | { ... } | | test.c:158:9:158:9 | p | false | test.c:158:12:160:5 | { ... } | +| test.c:158:9:158:9 | p | null | test.c:158:12:160:5 | { ... } | +| test.c:163:18:163:18 | s | not 0 | test.c:164:11:166:5 | { ... } | +| test.c:164:8:164:8 | s | not 0 | test.c:164:11:166:5 | { ... } | | test.c:164:8:164:8 | s | true | test.c:164:11:166:5 | { ... } | +| test.c:169:18:169:18 | s | 0 | test.c:170:12:172:5 | { ... } | | test.c:170:8:170:9 | ! ... | true | test.c:170:12:172:5 | { ... } | +| test.c:170:9:170:9 | s | 0 | test.c:170:12:172:5 | { ... } | | test.c:170:9:170:9 | s | false | test.c:170:12:172:5 | { ... } | | test.c:176:8:176:15 | ! ... | true | test.c:176:18:178:5 | { ... } | +| test.c:176:10:176:14 | ... < ... | 0 | test.c:176:18:178:5 | { ... } | | test.c:176:10:176:14 | ... < ... | false | test.c:176:18:178:5 | { ... } | | test.c:182:8:182:34 | ! ... | true | test.c:182:37:184:5 | { ... } | | test.c:182:10:182:20 | ... >= ... | true | test.c:181:25:182:20 | { ... } | | test.c:182:10:182:20 | ... >= ... | true | test.c:182:25:182:33 | foo | +| test.c:182:10:182:33 | ... && ... | 0 | test.c:182:37:184:5 | { ... } | | test.c:182:10:182:33 | ... && ... | false | test.c:182:37:184:5 | { ... } | | test.c:182:10:182:33 | ... && ... | true | test.c:181:25:182:20 | { ... } | | test.c:182:25:182:33 | ... < ... | true | test.c:181:25:182:20 | { ... } | +| test.c:188:11:188:16 | ... != ... | 0 | test.c:190:11:192:3 | { ... } | | test.c:190:7:190:8 | ! ... | true | test.c:190:11:192:3 | { ... } | +| test.c:190:8:190:8 | c | 0 | test.c:190:11:192:3 | { ... } | | test.c:190:8:190:8 | c | false | test.c:190:11:192:3 | { ... } | +| test.c:196:11:196:16 | ... > ... | 0 | test.c:198:11:200:3 | { ... } | | test.c:198:7:198:8 | ! ... | true | test.c:198:11:200:3 | { ... } | +| test.c:198:8:198:8 | b | 0 | test.c:198:11:200:3 | { ... } | | test.c:198:8:198:8 | b | false | test.c:198:11:200:3 | { ... } | +| test.c:204:11:204:15 | ... > ... | 0 | test.c:206:11:208:3 | { ... } | | test.c:206:7:206:8 | ! ... | true | test.c:206:11:208:3 | { ... } | +| test.c:206:8:206:8 | c | 0 | test.c:206:11:208:3 | { ... } | | test.c:206:8:206:8 | c | false | test.c:206:11:208:3 | { ... } | +| test.c:215:6:215:18 | call to __builtin_expect | not 0 | test.c:215:21:217:5 | { ... } | | test.c:215:6:215:18 | call to __builtin_expect | true | test.c:215:21:217:5 | { ... } | +| test.c:219:9:219:22 | call to __builtin_expect | not 0 | test.c:219:25:221:5 | { ... } | | test.c:219:9:219:22 | call to __builtin_expect | true | test.c:219:25:221:5 | { ... } | +| test.cpp:18:8:18:10 | call to get | not null | test.cpp:19:5:19:14 | ExprStmt | | test.cpp:18:8:18:10 | call to get | true | test.cpp:19:5:19:14 | ExprStmt | +| test.cpp:30:22:30:22 | x | -1 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:30:22:30:22 | x | -1 | test.cpp:31:16:32:21 | { ... } | +| test.cpp:30:22:30:22 | x | not -1 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:30:22:30:22 | x | not -1 | test.cpp:34:1:34:1 | return ... | +| test.cpp:31:7:31:7 | x | -1 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:7 | x | -1 | test.cpp:31:16:32:21 | { ... } | +| test.cpp:31:7:31:7 | x | not -1 | test.cpp:30:6:30:16 | doSomething | +| test.cpp:31:7:31:7 | x | not -1 | test.cpp:34:1:34:1 | return ... | | test.cpp:31:7:31:13 | ... == ... | false | test.cpp:30:6:30:16 | doSomething | | test.cpp:31:7:31:13 | ... == ... | false | test.cpp:34:1:34:1 | return ... | | test.cpp:31:7:31:13 | ... == ... | true | test.cpp:30:6:30:16 | doSomething | | test.cpp:31:7:31:13 | ... == ... | true | test.cpp:31:16:32:21 | { ... } | | test.cpp:42:13:42:20 | call to getABool | true | test.cpp:43:9:45:23 | { ... } | -| test.cpp:61:10:61:10 | i | Case[0] | test.cpp:62:5:64:12 | case ...: | -| test.cpp:61:10:61:10 | i | Case[1] | test.cpp:65:5:66:10 | case ...: | -| test.cpp:74:10:74:10 | i | Case[0..10] | test.cpp:75:5:77:12 | case ...: | -| test.cpp:74:10:74:10 | i | Case[11..20] | test.cpp:78:5:79:10 | case ...: | +| test.cpp:60:31:60:31 | i | 0 | test.cpp:62:5:64:12 | case ...: | +| test.cpp:60:31:60:31 | i | 1 | test.cpp:65:5:66:10 | case ...: | +| test.cpp:61:10:61:10 | i | 0 | test.cpp:62:5:64:12 | case ...: | +| test.cpp:61:10:61:10 | i | 1 | test.cpp:65:5:66:10 | case ...: | +| test.cpp:73:30:73:30 | i | 0..10 | test.cpp:75:5:77:12 | case ...: | +| test.cpp:73:30:73:30 | i | 11..20 | test.cpp:78:5:79:10 | case ...: | +| test.cpp:74:10:74:10 | i | 0..10 | test.cpp:75:5:77:12 | case ...: | +| test.cpp:74:10:74:10 | i | 11..20 | test.cpp:78:5:79:10 | case ...: | +| test.cpp:92:31:92:31 | c | not null | test.cpp:93:9:94:7 | { ... } | +| test.cpp:93:6:93:6 | c | not null | test.cpp:93:9:94:7 | { ... } | | test.cpp:93:6:93:6 | c | true | test.cpp:93:9:94:7 | { ... } | | test.cpp:99:6:99:6 | f | true | test.cpp:99:9:100:7 | { ... } | | test.cpp:105:6:105:14 | ... != ... | true | test.cpp:105:17:106:7 | { ... } | | test.cpp:111:6:111:14 | ... != ... | true | test.cpp:111:17:112:7 | { ... } | +| test.cpp:119:16:119:16 | b | true | test.cpp:123:5:125:20 | { ... } | +| test.cpp:119:16:119:16 | b | true | test.cpp:125:23:125:29 | return ... | | test.cpp:122:9:122:9 | b | true | test.cpp:123:5:125:20 | { ... } | | test.cpp:122:9:122:9 | b | true | test.cpp:125:23:125:29 | return ... | | test.cpp:125:13:125:20 | ! ... | true | test.cpp:125:23:125:29 | return ... | | test.cpp:125:14:125:17 | call to safe | false | test.cpp:125:23:125:29 | return ... | +| test.cpp:131:6:131:21 | call to __builtin_expect | not 0 | test.cpp:131:40:132:9 | { ... } | | test.cpp:131:6:131:21 | call to __builtin_expect | true | test.cpp:131:40:132:9 | { ... } | +| test.cpp:135:6:135:21 | call to __builtin_expect | not 0 | test.cpp:135:40:136:9 | { ... } | | test.cpp:135:6:135:21 | call to __builtin_expect | true | test.cpp:135:40:136:9 | { ... } | +| test.cpp:141:6:141:21 | call to __builtin_expect | not 0 | test.cpp:141:36:142:9 | { ... } | | test.cpp:141:6:141:21 | call to __builtin_expect | true | test.cpp:141:36:142:9 | { ... } | +| test.cpp:145:6:145:21 | call to __builtin_expect | not 0 | test.cpp:145:36:146:9 | { ... } | | test.cpp:145:6:145:21 | call to __builtin_expect | true | test.cpp:145:36:146:9 | { ... } | +| test.cpp:151:8:151:13 | ... < ... | false | test.cpp:152:11:153:9 | { ... } | | test.cpp:152:7:152:8 | ! ... | true | test.cpp:152:11:153:9 | { ... } | | test.cpp:152:8:152:8 | b | false | test.cpp:152:11:153:9 | { ... } | +| test.cpp:158:12:158:17 | ... != ... | false | test.cpp:160:11:162:3 | { ... } | | test.cpp:160:7:160:8 | ! ... | true | test.cpp:160:11:162:3 | { ... } | | test.cpp:160:8:160:8 | c | false | test.cpp:160:11:162:3 | { ... } | +| test.cpp:166:12:166:17 | ... > ... | false | test.cpp:168:11:170:3 | { ... } | | test.cpp:168:7:168:8 | ! ... | true | test.cpp:168:11:170:3 | { ... } | | test.cpp:168:8:168:8 | b | false | test.cpp:168:11:170:3 | { ... } | +| test.cpp:174:12:174:16 | ... > ... | false | test.cpp:176:11:178:3 | { ... } | | test.cpp:176:7:176:8 | ! ... | true | test.cpp:176:11:178:3 | { ... } | | test.cpp:176:8:176:8 | c | false | test.cpp:176:11:178:3 | { ... } | +| test.cpp:181:28:181:29 | b1 | true | test.cpp:181:41:182:9 | { ... } | +| test.cpp:181:28:181:29 | b1 | true | test.cpp:182:14:182:15 | b2 | +| test.cpp:181:28:181:29 | b1 | true | test.cpp:185:10:188:7 | { ... } | +| test.cpp:181:37:181:38 | b2 | true | test.cpp:181:41:182:9 | { ... } | +| test.cpp:181:37:181:38 | b2 | true | test.cpp:185:10:188:7 | { ... } | | test.cpp:182:6:182:16 | ! ... | false | test.cpp:185:10:188:7 | { ... } | | test.cpp:182:6:182:16 | ! ... | true | test.cpp:182:19:184:7 | { ... } | | test.cpp:182:8:182:9 | b1 | true | test.cpp:181:41:182:9 | { ... } | | test.cpp:182:8:182:9 | b1 | true | test.cpp:182:14:182:15 | b2 | +| test.cpp:182:8:182:9 | b1 | true | test.cpp:185:10:188:7 | { ... } | | test.cpp:182:8:182:15 | ... && ... | false | test.cpp:182:19:184:7 | { ... } | | test.cpp:182:8:182:15 | ... && ... | true | test.cpp:181:41:182:9 | { ... } | | test.cpp:182:8:182:15 | ... && ... | true | test.cpp:185:10:188:7 | { ... } | | test.cpp:182:14:182:15 | b2 | true | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:14:182:15 | b2 | true | test.cpp:185:10:188:7 | { ... } | +| test.cpp:192:27:192:28 | b1 | false | test.cpp:192:40:193:9 | { ... } | +| test.cpp:192:27:192:28 | b1 | false | test.cpp:193:14:193:15 | b2 | +| test.cpp:192:27:192:28 | b1 | false | test.cpp:193:19:196:7 | { ... } | +| test.cpp:192:36:192:37 | b2 | false | test.cpp:192:40:193:9 | { ... } | +| test.cpp:192:36:192:37 | b2 | false | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:6:193:16 | ! ... | false | test.cpp:197:10:199:7 | { ... } | | test.cpp:193:6:193:16 | ! ... | true | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:8:193:9 | b1 | false | test.cpp:192:40:193:9 | { ... } | | test.cpp:193:8:193:9 | b1 | false | test.cpp:193:14:193:15 | b2 | +| test.cpp:193:8:193:9 | b1 | false | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:8:193:15 | ... \|\| ... | false | test.cpp:192:40:193:9 | { ... } | | test.cpp:193:8:193:15 | ... \|\| ... | false | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:8:193:15 | ... \|\| ... | true | test.cpp:197:10:199:7 | { ... } | | test.cpp:193:14:193:15 | b2 | false | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:14:193:15 | b2 | false | test.cpp:193:19:196:7 | { ... } | +| test.cpp:208:28:208:29 | sc | 0 | test.cpp:211:18:212:13 | { ... } | +| test.cpp:208:28:208:29 | sc | 0 | test.cpp:214:20:215:13 | { ... } | +| test.cpp:208:46:208:47 | ul | 0 | test.cpp:217:18:218:13 | { ... } | +| test.cpp:208:74:208:74 | b | 0 | test.cpp:229:17:230:13 | { ... } | +| test.cpp:208:74:208:74 | b | 0 | test.cpp:232:21:233:13 | { ... } | +| test.cpp:211:9:211:10 | sc | 0 | test.cpp:211:18:212:13 | { ... } | | test.cpp:211:9:211:15 | ... == ... | true | test.cpp:211:18:212:13 | { ... } | +| test.cpp:214:9:214:10 | sc | 0 | test.cpp:214:20:215:13 | { ... } | | test.cpp:214:9:214:17 | ... == ... | true | test.cpp:214:20:215:13 | { ... } | +| test.cpp:217:9:217:10 | ul | 0 | test.cpp:217:18:218:13 | { ... } | | test.cpp:217:9:217:15 | ... == ... | true | test.cpp:217:18:218:13 | { ... } | | test.cpp:220:9:220:14 | ... == ... | true | test.cpp:220:17:221:13 | { ... } | | test.cpp:223:9:223:16 | ... == ... | true | test.cpp:223:19:224:13 | { ... } | | test.cpp:226:9:226:14 | ... == ... | true | test.cpp:226:17:227:13 | { ... } | +| test.cpp:229:9:229:9 | b | 0 | test.cpp:229:17:230:13 | { ... } | | test.cpp:229:9:229:14 | ... == ... | true | test.cpp:229:17:230:13 | { ... } | +| test.cpp:232:9:232:9 | b | 0 | test.cpp:232:21:233:13 | { ... } | | test.cpp:232:9:232:18 | ... == ... | true | test.cpp:232:21:233:13 | { ... } | | test.cpp:235:9:235:17 | ... == ... | true | test.cpp:235:20:236:13 | { ... } | +| test.cpp:235:12:235:12 | i | 0 | test.cpp:235:20:236:13 | { ... } | | test.cpp:238:9:238:17 | ... == ... | true | test.cpp:238:20:239:13 | { ... } | | test.cpp:241:9:241:17 | ... == ... | true | test.cpp:241:22:241:30 | ms | | test.cpp:241:9:241:17 | ... == ... | true | test.cpp:241:35:241:43 | ms | @@ -167,30 +273,58 @@ | test.cpp:241:9:241:30 | ... && ... | true | test.cpp:241:35:241:43 | ms | | test.cpp:241:9:241:30 | ... && ... | true | test.cpp:241:46:242:13 | { ... } | | test.cpp:241:9:241:43 | ... && ... | true | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:12:241:12 | i | 0 | test.cpp:241:22:241:30 | ms | +| test.cpp:241:12:241:12 | i | 0 | test.cpp:241:35:241:43 | ms | +| test.cpp:241:12:241:12 | i | 0 | test.cpp:241:46:242:13 | { ... } | | test.cpp:241:22:241:30 | ... == ... | true | test.cpp:241:35:241:43 | ms | | test.cpp:241:22:241:30 | ... == ... | true | test.cpp:241:46:242:13 | { ... } | | test.cpp:241:35:241:43 | ... == ... | true | test.cpp:241:46:242:13 | { ... } | +| test.cpp:241:38:241:38 | i | 0 | test.cpp:241:46:242:13 | { ... } | | test.cpp:247:6:247:18 | ... == ... | false | test.cpp:249:10:251:3 | { ... } | | test.cpp:247:6:247:18 | ... == ... | true | test.cpp:247:21:249:3 | { ... } | +| test.cpp:247:7:247:12 | ... == ... | 0 | test.cpp:247:21:249:3 | { ... } | +| test.cpp:247:7:247:12 | ... == ... | not 0 | test.cpp:249:10:251:3 | { ... } | | test.cpp:253:6:253:18 | ... != ... | false | test.cpp:255:10:257:3 | { ... } | | test.cpp:253:6:253:18 | ... != ... | true | test.cpp:253:21:255:3 | { ... } | +| test.cpp:253:7:253:12 | ... == ... | 0 | test.cpp:255:10:257:3 | { ... } | +| test.cpp:253:7:253:12 | ... == ... | not 0 | test.cpp:253:21:255:3 | { ... } | | test.cpp:260:6:260:18 | ... == ... | false | test.cpp:262:10:264:3 | { ... } | | test.cpp:260:6:260:18 | ... == ... | true | test.cpp:260:21:262:3 | { ... } | +| test.cpp:260:7:260:12 | ... != ... | 0 | test.cpp:260:21:262:3 | { ... } | +| test.cpp:260:7:260:12 | ... != ... | not 0 | test.cpp:262:10:264:3 | { ... } | | test.cpp:266:6:266:18 | ... != ... | false | test.cpp:268:10:270:3 | { ... } | | test.cpp:266:6:266:18 | ... != ... | true | test.cpp:266:21:268:3 | { ... } | +| test.cpp:266:7:266:12 | ... != ... | 0 | test.cpp:268:10:270:3 | { ... } | +| test.cpp:266:7:266:12 | ... != ... | not 0 | test.cpp:266:21:268:3 | { ... } | | test.cpp:273:6:273:17 | ... == ... | false | test.cpp:275:10:277:3 | { ... } | | test.cpp:273:6:273:17 | ... == ... | true | test.cpp:273:20:275:3 | { ... } | +| test.cpp:273:7:273:11 | ... < ... | 0 | test.cpp:273:20:275:3 | { ... } | +| test.cpp:273:7:273:11 | ... < ... | not 0 | test.cpp:275:10:277:3 | { ... } | | test.cpp:279:6:279:17 | ... != ... | false | test.cpp:281:10:283:3 | { ... } | | test.cpp:279:6:279:17 | ... != ... | true | test.cpp:279:20:281:3 | { ... } | +| test.cpp:279:7:279:11 | ... < ... | 0 | test.cpp:281:10:283:3 | { ... } | +| test.cpp:279:7:279:11 | ... < ... | not 0 | test.cpp:279:20:281:3 | { ... } | | test.cpp:287:6:287:19 | ... == ... | false | test.cpp:289:10:291:3 | { ... } | | test.cpp:287:6:287:19 | ... == ... | true | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:7:287:13 | ... == ... | 0 | test.cpp:287:22:289:3 | { ... } | +| test.cpp:287:7:287:13 | ... == ... | not 0 | test.cpp:289:10:291:3 | { ... } | | test.cpp:293:6:293:19 | ... != ... | false | test.cpp:295:10:297:3 | { ... } | | test.cpp:293:6:293:19 | ... != ... | true | test.cpp:293:22:295:3 | { ... } | +| test.cpp:293:7:293:13 | ... == ... | 0 | test.cpp:295:10:297:3 | { ... } | +| test.cpp:293:7:293:13 | ... == ... | not 0 | test.cpp:293:22:295:3 | { ... } | | test.cpp:300:6:300:19 | ... == ... | false | test.cpp:302:10:304:3 | { ... } | | test.cpp:300:6:300:19 | ... == ... | true | test.cpp:300:22:302:3 | { ... } | +| test.cpp:300:7:300:13 | ... != ... | 0 | test.cpp:300:22:302:3 | { ... } | +| test.cpp:300:7:300:13 | ... != ... | not 0 | test.cpp:302:10:304:3 | { ... } | | test.cpp:306:6:306:19 | ... != ... | false | test.cpp:308:10:310:3 | { ... } | | test.cpp:306:6:306:19 | ... != ... | true | test.cpp:306:22:308:3 | { ... } | +| test.cpp:306:7:306:13 | ... != ... | 0 | test.cpp:308:10:310:3 | { ... } | +| test.cpp:306:7:306:13 | ... != ... | not 0 | test.cpp:306:22:308:3 | { ... } | | test.cpp:312:6:312:18 | ... == ... | false | test.cpp:314:10:316:3 | { ... } | | test.cpp:312:6:312:18 | ... == ... | true | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:7:312:12 | ... < ... | 0 | test.cpp:312:21:314:3 | { ... } | +| test.cpp:312:7:312:12 | ... < ... | not 0 | test.cpp:314:10:316:3 | { ... } | | test.cpp:318:6:318:18 | ... != ... | false | test.cpp:320:10:322:3 | { ... } | | test.cpp:318:6:318:18 | ... != ... | true | test.cpp:318:21:320:3 | { ... } | +| test.cpp:318:7:318:12 | ... < ... | 0 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:318:7:318:12 | ... < ... | not 0 | test.cpp:318:21:320:3 | { ... } | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index c9f52e5f190c..da36308f8786 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -219,18 +219,26 @@ binary | test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:28:141:29 | 42 | == | test.cpp:141:23:141:23 | a | 0 | test.cpp:141:36:142:9 | { ... } | | test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:23:145:23 | a | != | test.cpp:145:28:145:29 | 42 | 0 | test.cpp:145:36:146:9 | { ... } | | test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:28:145:29 | 42 | != | test.cpp:145:23:145:23 | a | 0 | test.cpp:145:36:146:9 | { ... } | +| test.cpp:151:8:151:13 | ... < ... | test.cpp:151:8:151:8 | a | >= | test.cpp:151:12:151:13 | 10 | 0 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:151:8:151:13 | ... < ... | test.cpp:151:12:151:13 | 10 | < | test.cpp:151:8:151:8 | a | 1 | test.cpp:152:11:153:9 | { ... } | | test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:8 | a | >= | test.cpp:151:12:151:13 | 10 | 0 | test.cpp:152:11:153:9 | { ... } | | test.cpp:152:7:152:8 | ! ... | test.cpp:151:12:151:13 | 10 | < | test.cpp:151:8:151:8 | a | 1 | test.cpp:152:11:153:9 | { ... } | | test.cpp:152:8:152:8 | b | test.cpp:151:8:151:8 | a | >= | test.cpp:151:12:151:13 | 10 | 0 | test.cpp:152:11:153:9 | { ... } | | test.cpp:152:8:152:8 | b | test.cpp:151:12:151:13 | 10 | < | test.cpp:151:8:151:8 | a | 1 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:158:12:158:17 | ... != ... | test.cpp:158:12:158:12 | a | == | test.cpp:158:17:158:17 | b | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:158:12:158:17 | ... != ... | test.cpp:158:17:158:17 | b | == | test.cpp:158:12:158:12 | a | 0 | test.cpp:160:11:162:3 | { ... } | | test.cpp:160:7:160:8 | ! ... | test.cpp:158:12:158:12 | a | == | test.cpp:158:17:158:17 | b | 0 | test.cpp:160:11:162:3 | { ... } | | test.cpp:160:7:160:8 | ! ... | test.cpp:158:17:158:17 | b | == | test.cpp:158:12:158:12 | a | 0 | test.cpp:160:11:162:3 | { ... } | | test.cpp:160:8:160:8 | c | test.cpp:158:12:158:12 | a | == | test.cpp:158:17:158:17 | b | 0 | test.cpp:160:11:162:3 | { ... } | | test.cpp:160:8:160:8 | c | test.cpp:158:17:158:17 | b | == | test.cpp:158:12:158:12 | a | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:166:12:166:17 | ... > ... | test.cpp:166:12:166:12 | a | < | test.cpp:166:16:166:17 | 10 | 1 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:166:12:166:17 | ... > ... | test.cpp:166:16:166:17 | 10 | >= | test.cpp:166:12:166:12 | a | 0 | test.cpp:168:11:170:3 | { ... } | | test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:12 | a | < | test.cpp:166:16:166:17 | 10 | 1 | test.cpp:168:11:170:3 | { ... } | | test.cpp:168:7:168:8 | ! ... | test.cpp:166:16:166:17 | 10 | >= | test.cpp:166:12:166:12 | a | 0 | test.cpp:168:11:170:3 | { ... } | | test.cpp:168:8:168:8 | b | test.cpp:166:12:166:12 | a | < | test.cpp:166:16:166:17 | 10 | 1 | test.cpp:168:11:170:3 | { ... } | | test.cpp:168:8:168:8 | b | test.cpp:166:16:166:17 | 10 | >= | test.cpp:166:12:166:12 | a | 0 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:174:12:174:16 | ... > ... | test.cpp:174:12:174:12 | a | < | test.cpp:174:16:174:16 | b | 1 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:174:12:174:16 | ... > ... | test.cpp:174:16:174:16 | b | >= | test.cpp:174:12:174:12 | a | 0 | test.cpp:176:11:178:3 | { ... } | | test.cpp:176:7:176:8 | ! ... | test.cpp:174:12:174:12 | a | < | test.cpp:174:16:174:16 | b | 1 | test.cpp:176:11:178:3 | { ... } | | test.cpp:176:7:176:8 | ! ... | test.cpp:174:16:174:16 | b | >= | test.cpp:174:12:174:12 | a | 0 | test.cpp:176:11:178:3 | { ... } | | test.cpp:176:8:176:8 | c | test.cpp:174:12:174:12 | a | < | test.cpp:174:16:174:16 | b | 1 | test.cpp:176:11:178:3 | { ... } | @@ -736,11 +744,17 @@ unary | test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:10:132:16 | { ... } | | test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:134:1:123:10 | return ... | | test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:131:10:132:16 | { ... } | | test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:10:132:16 | { ... } | | test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:10:132:16 | { ... } | | test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:131:10:132:16 | { ... } | | test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:10:132:16 | { ... } | | test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:126:31:128:16 | { ... } | +| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:131:10:132:16 | { ... } | | test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | != | 0 | test.c:131:10:132:16 | { ... } | | test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | == | 1 | test.c:131:10:132:16 | { ... } | | test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | != | 1 | test.c:142:3:136:10 | return ... | @@ -835,8 +849,14 @@ unary | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | test.cpp:31:16:32:21 | { ... } | | test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | test.cpp:43:9:45:23 | { ... } | | test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 1 | test.cpp:43:9:45:23 | { ... } | +| test.cpp:60:31:60:31 | i | test.cpp:61:10:61:10 | i | == | 0 | test.cpp:62:5:64:12 | case ...: | +| test.cpp:60:31:60:31 | i | test.cpp:61:10:61:10 | i | == | 1 | test.cpp:65:5:66:10 | case ...: | | test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 0 | test.cpp:62:5:64:12 | case ...: | | test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 1 | test.cpp:65:5:66:10 | case ...: | +| test.cpp:73:30:73:30 | i | test.cpp:74:10:74:10 | i | < | 11 | test.cpp:75:5:77:12 | case ...: | +| test.cpp:73:30:73:30 | i | test.cpp:74:10:74:10 | i | < | 21 | test.cpp:78:5:79:10 | case ...: | +| test.cpp:73:30:73:30 | i | test.cpp:74:10:74:10 | i | >= | 0 | test.cpp:75:5:77:12 | case ...: | +| test.cpp:73:30:73:30 | i | test.cpp:74:10:74:10 | i | >= | 11 | test.cpp:78:5:79:10 | case ...: | | test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 11 | test.cpp:75:5:77:12 | case ...: | | test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 21 | test.cpp:78:5:79:10 | case ...: | | test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 0 | test.cpp:75:5:77:12 | case ...: | @@ -849,6 +869,10 @@ unary | test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:14 | ... != ... | == | 1 | test.cpp:105:17:106:7 | { ... } | | test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:14 | ... != ... | != | 0 | test.cpp:111:17:112:7 | { ... } | | test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:14 | ... != ... | == | 1 | test.cpp:111:17:112:7 | { ... } | +| test.cpp:119:16:119:16 | b | test.cpp:122:9:122:9 | b | != | 0 | test.cpp:123:5:125:20 | { ... } | +| test.cpp:119:16:119:16 | b | test.cpp:122:9:122:9 | b | != | 0 | test.cpp:125:23:125:29 | return ... | +| test.cpp:119:16:119:16 | b | test.cpp:122:9:122:9 | b | == | 1 | test.cpp:123:5:125:20 | { ... } | +| test.cpp:119:16:119:16 | b | test.cpp:122:9:122:9 | b | == | 1 | test.cpp:125:23:125:29 | return ... | | test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | != | 0 | test.cpp:123:5:125:20 | { ... } | | test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | != | 0 | test.cpp:125:23:125:29 | return ... | | test.cpp:122:9:122:9 | b | test.cpp:122:9:122:9 | b | == | 1 | test.cpp:123:5:125:20 | { ... } | @@ -871,6 +895,11 @@ unary | test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:6:145:21 | call to __builtin_expect | != | 0 | test.cpp:145:36:146:9 | { ... } | | test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:6:145:21 | call to __builtin_expect | == | 1 | test.cpp:145:36:146:9 | { ... } | | test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:23:145:23 | a | != | 42 | test.cpp:145:36:146:9 | { ... } | +| test.cpp:151:8:151:13 | ... < ... | test.cpp:151:8:151:8 | a | >= | 10 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:151:8:151:13 | ... < ... | test.cpp:151:8:151:13 | ... < ... | != | 1 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:151:8:151:13 | ... < ... | test.cpp:151:8:151:13 | ... < ... | == | 0 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:151:8:151:13 | ... < ... | test.cpp:152:8:152:8 | b | != | 1 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:151:8:151:13 | ... < ... | test.cpp:152:8:152:8 | b | == | 0 | test.cpp:152:11:153:9 | { ... } | | test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:8 | a | >= | 10 | test.cpp:152:11:153:9 | { ... } | | test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:13 | ... < ... | != | 1 | test.cpp:152:11:153:9 | { ... } | | test.cpp:152:7:152:8 | ! ... | test.cpp:151:8:151:13 | ... < ... | == | 0 | test.cpp:152:11:153:9 | { ... } | @@ -885,6 +914,10 @@ unary | test.cpp:152:8:152:8 | b | test.cpp:152:7:152:8 | ! ... | == | 1 | test.cpp:152:11:153:9 | { ... } | | test.cpp:152:8:152:8 | b | test.cpp:152:8:152:8 | b | != | 1 | test.cpp:152:11:153:9 | { ... } | | test.cpp:152:8:152:8 | b | test.cpp:152:8:152:8 | b | == | 0 | test.cpp:152:11:153:9 | { ... } | +| test.cpp:158:12:158:17 | ... != ... | test.cpp:158:12:158:17 | ... != ... | != | 1 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:158:12:158:17 | ... != ... | test.cpp:158:12:158:17 | ... != ... | == | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:158:12:158:17 | ... != ... | test.cpp:160:8:160:8 | c | != | 1 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:158:12:158:17 | ... != ... | test.cpp:160:8:160:8 | c | == | 0 | test.cpp:160:11:162:3 | { ... } | | test.cpp:160:7:160:8 | ! ... | test.cpp:158:12:158:17 | ... != ... | != | 1 | test.cpp:160:11:162:3 | { ... } | | test.cpp:160:7:160:8 | ! ... | test.cpp:158:12:158:17 | ... != ... | == | 0 | test.cpp:160:11:162:3 | { ... } | | test.cpp:160:7:160:8 | ! ... | test.cpp:160:7:160:8 | ! ... | != | 0 | test.cpp:160:11:162:3 | { ... } | @@ -897,6 +930,11 @@ unary | test.cpp:160:8:160:8 | c | test.cpp:160:7:160:8 | ! ... | == | 1 | test.cpp:160:11:162:3 | { ... } | | test.cpp:160:8:160:8 | c | test.cpp:160:8:160:8 | c | != | 1 | test.cpp:160:11:162:3 | { ... } | | test.cpp:160:8:160:8 | c | test.cpp:160:8:160:8 | c | == | 0 | test.cpp:160:11:162:3 | { ... } | +| test.cpp:166:12:166:17 | ... > ... | test.cpp:166:12:166:12 | a | < | 11 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:166:12:166:17 | ... > ... | test.cpp:166:12:166:17 | ... > ... | != | 1 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:166:12:166:17 | ... > ... | test.cpp:166:12:166:17 | ... > ... | == | 0 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:166:12:166:17 | ... > ... | test.cpp:168:8:168:8 | b | != | 1 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:166:12:166:17 | ... > ... | test.cpp:168:8:168:8 | b | == | 0 | test.cpp:168:11:170:3 | { ... } | | test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:12 | a | < | 11 | test.cpp:168:11:170:3 | { ... } | | test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:17 | ... > ... | != | 1 | test.cpp:168:11:170:3 | { ... } | | test.cpp:168:7:168:8 | ! ... | test.cpp:166:12:166:17 | ... > ... | == | 0 | test.cpp:168:11:170:3 | { ... } | @@ -911,6 +949,10 @@ unary | test.cpp:168:8:168:8 | b | test.cpp:168:7:168:8 | ! ... | == | 1 | test.cpp:168:11:170:3 | { ... } | | test.cpp:168:8:168:8 | b | test.cpp:168:8:168:8 | b | != | 1 | test.cpp:168:11:170:3 | { ... } | | test.cpp:168:8:168:8 | b | test.cpp:168:8:168:8 | b | == | 0 | test.cpp:168:11:170:3 | { ... } | +| test.cpp:174:12:174:16 | ... > ... | test.cpp:174:12:174:16 | ... > ... | != | 1 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:174:12:174:16 | ... > ... | test.cpp:174:12:174:16 | ... > ... | == | 0 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:174:12:174:16 | ... > ... | test.cpp:176:8:176:8 | c | != | 1 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:174:12:174:16 | ... > ... | test.cpp:176:8:176:8 | c | == | 0 | test.cpp:176:11:178:3 | { ... } | | test.cpp:176:7:176:8 | ! ... | test.cpp:174:12:174:16 | ... > ... | != | 1 | test.cpp:176:11:178:3 | { ... } | | test.cpp:176:7:176:8 | ! ... | test.cpp:174:12:174:16 | ... > ... | == | 0 | test.cpp:176:11:178:3 | { ... } | | test.cpp:176:7:176:8 | ! ... | test.cpp:176:7:176:8 | ! ... | != | 0 | test.cpp:176:11:178:3 | { ... } | @@ -923,6 +965,16 @@ unary | test.cpp:176:8:176:8 | c | test.cpp:176:7:176:8 | ! ... | == | 1 | test.cpp:176:11:178:3 | { ... } | | test.cpp:176:8:176:8 | c | test.cpp:176:8:176:8 | c | != | 1 | test.cpp:176:11:178:3 | { ... } | | test.cpp:176:8:176:8 | c | test.cpp:176:8:176:8 | c | == | 0 | test.cpp:176:11:178:3 | { ... } | +| test.cpp:181:28:181:29 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:181:28:181:29 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | test.cpp:182:14:182:15 | b2 | +| test.cpp:181:28:181:29 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:181:28:181:29 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:181:28:181:29 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | test.cpp:182:14:182:15 | b2 | +| test.cpp:181:28:181:29 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:181:37:181:38 | b2 | test.cpp:182:14:182:15 | b2 | != | 0 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:181:37:181:38 | b2 | test.cpp:182:14:182:15 | b2 | != | 0 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:181:37:181:38 | b2 | test.cpp:182:14:182:15 | b2 | == | 1 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:181:37:181:38 | b2 | test.cpp:182:14:182:15 | b2 | == | 1 | test.cpp:185:10:188:7 | { ... } | | test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | != | 0 | test.cpp:182:19:184:7 | { ... } | | test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | != | 1 | test.cpp:185:10:188:7 | { ... } | | test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | == | 0 | test.cpp:185:10:188:7 | { ... } | @@ -937,8 +989,10 @@ unary | test.cpp:182:6:182:16 | ! ... | test.cpp:182:14:182:15 | b2 | == | 1 | test.cpp:185:10:188:7 | { ... } | | test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | test.cpp:181:41:182:9 | { ... } | | test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | test.cpp:182:14:182:15 | b2 | +| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | test.cpp:185:10:188:7 | { ... } | | test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | test.cpp:181:41:182:9 | { ... } | | test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | test.cpp:182:14:182:15 | b2 | +| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | test.cpp:185:10:188:7 | { ... } | | test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 0 | test.cpp:182:19:184:7 | { ... } | | test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 1 | test.cpp:181:41:182:9 | { ... } | | test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 1 | test.cpp:185:10:188:7 | { ... } | @@ -960,7 +1014,19 @@ unary | test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | == | 1 | test.cpp:181:41:182:9 | { ... } | | test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | == | 1 | test.cpp:185:10:188:7 | { ... } | | test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | != | 0 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | != | 0 | test.cpp:185:10:188:7 | { ... } | | test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | == | 1 | test.cpp:181:41:182:9 | { ... } | +| test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | == | 1 | test.cpp:185:10:188:7 | { ... } | +| test.cpp:192:27:192:28 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:192:27:192:28 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | test.cpp:193:14:193:15 | b2 | +| test.cpp:192:27:192:28 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:192:27:192:28 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:192:27:192:28 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | test.cpp:193:14:193:15 | b2 | +| test.cpp:192:27:192:28 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:192:36:192:37 | b2 | test.cpp:193:14:193:15 | b2 | != | 1 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:192:36:192:37 | b2 | test.cpp:193:14:193:15 | b2 | != | 1 | test.cpp:193:19:196:7 | { ... } | +| test.cpp:192:36:192:37 | b2 | test.cpp:193:14:193:15 | b2 | == | 0 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:192:36:192:37 | b2 | test.cpp:193:14:193:15 | b2 | == | 0 | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | != | 0 | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | != | 1 | test.cpp:197:10:199:7 | { ... } | | test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | == | 0 | test.cpp:197:10:199:7 | { ... } | @@ -975,8 +1041,10 @@ unary | test.cpp:193:6:193:16 | ! ... | test.cpp:193:14:193:15 | b2 | == | 0 | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | test.cpp:192:40:193:9 | { ... } | | test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | test.cpp:193:14:193:15 | b2 | +| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | test.cpp:192:40:193:9 | { ... } | | test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | test.cpp:193:14:193:15 | b2 | +| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 0 | test.cpp:192:40:193:9 | { ... } | | test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 0 | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 1 | test.cpp:197:10:199:7 | { ... } | @@ -998,7 +1066,9 @@ unary | test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | == | 0 | test.cpp:192:40:193:9 | { ... } | | test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | == | 0 | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | != | 1 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | != | 1 | test.cpp:193:19:196:7 | { ... } | | test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | == | 0 | test.cpp:192:40:193:9 | { ... } | +| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | == | 0 | test.cpp:193:19:196:7 | { ... } | | test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:10 | sc | == | 0 | test.cpp:211:18:212:13 | { ... } | | test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:15 | ... == ... | != | 0 | test.cpp:211:18:212:13 | { ... } | | test.cpp:211:9:211:15 | ... == ... | test.cpp:211:9:211:15 | ... == ... | == | 1 | test.cpp:211:18:212:13 | { ... } | diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/IncorrectCheckScanf.expected b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/IncorrectCheckScanf.expected index c0ed43fee9b3..1591a287d9fb 100644 --- a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/IncorrectCheckScanf.expected +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/IncorrectCheckScanf.expected @@ -1,5 +1,6 @@ | test.cpp:162:7:162:11 | call to scanf | The result of scanf is only checked against 0, but it can also return EOF. | | test.cpp:171:7:171:11 | call to scanf | The result of scanf is only checked against 0, but it can also return EOF. | +| test.cpp:193:7:193:11 | call to scanf | The result of scanf is only checked against 0, but it can also return EOF. | | test.cpp:204:7:204:11 | call to scanf | The result of scanf is only checked against 0, but it can also return EOF. | | test.cpp:436:7:436:11 | call to scanf | The result of scanf is only checked against 0, but it can also return EOF. | | test.cpp:443:11:443:15 | call to scanf | The result of scanf is only checked against 0, but it can also return EOF. | diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected index 6dfe60dcb8ca..9b7564b9123d 100644 --- a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/MissingCheckScanf.expected @@ -15,7 +15,6 @@ edges | test.cpp:141:19:141:20 | scanf output argument | test.cpp:143:8:143:8 | i | provenance | | | test.cpp:150:23:150:24 | scanf output argument | test.cpp:154:9:154:9 | i | provenance | | | test.cpp:181:19:181:20 | scanf output argument | test.cpp:185:8:185:8 | i | provenance | | -| test.cpp:193:19:193:20 | scanf output argument | test.cpp:197:8:197:8 | i | provenance | | | test.cpp:211:22:211:23 | scanf output argument | test.cpp:213:8:213:8 | i | provenance | | | test.cpp:221:22:221:23 | scanf output argument | test.cpp:223:8:223:8 | i | provenance | | | test.cpp:221:26:221:27 | scanf output argument | test.cpp:224:8:224:8 | j | provenance | | @@ -89,8 +88,6 @@ nodes | test.cpp:154:9:154:9 | i | semmle.label | i | | test.cpp:181:19:181:20 | scanf output argument | semmle.label | scanf output argument | | test.cpp:185:8:185:8 | i | semmle.label | i | -| test.cpp:193:19:193:20 | scanf output argument | semmle.label | scanf output argument | -| test.cpp:197:8:197:8 | i | semmle.label | i | | test.cpp:211:22:211:23 | scanf output argument | semmle.label | scanf output argument | | test.cpp:213:8:213:8 | i | semmle.label | i | | test.cpp:221:22:221:23 | scanf output argument | semmle.label | scanf output argument | diff --git a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp index 92f5d10ddd9e..346cf607977b 100644 --- a/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp +++ b/cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp @@ -194,7 +194,7 @@ int main() if (b >= 1) { - use(i); // BAD [NOT DETECTED]: scanf can return EOF (boolifies true) + use(i); // BAD: scanf can return EOF (boolifies true) } } From fbd877a11881d86730e217582e28d55086b4056c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:44:17 +0100 Subject: [PATCH 14/35] C++: Delete a test. This is no longer useful when every expression is a guard condition. --- .../controlflow/guards-ir/tests.expected | 75 - .../controlflow/guards-ir/tests.ql | 4 - .../controlflow/guards/Guards.expected | 1544 ----------------- .../controlflow/guards/Guards.ql | 5 - 4 files changed, 1628 deletions(-) delete mode 100644 cpp/ql/test/library-tests/controlflow/guards/Guards.expected delete mode 100644 cpp/ql/test/library-tests/controlflow/guards/Guards.ql diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected index 900b65eb7bd8..2e18dcd7a620 100644 --- a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected @@ -1,44 +1,3 @@ -astGuards -| test.c:7:9:7:13 | ... > ... | -| test.c:17:8:17:12 | ... < ... | -| test.c:17:8:17:21 | ... && ... | -| test.c:17:17:17:21 | ... > ... | -| test.c:26:11:26:15 | ... > ... | -| test.c:34:16:34:21 | ... < ... | -| test.c:42:16:42:21 | ... < ... | -| test.c:44:12:44:16 | ... > ... | -| test.c:45:16:45:20 | ... > ... | -| test.c:58:9:58:14 | ... == ... | -| test.c:58:9:58:23 | ... \|\| ... | -| test.c:58:19:58:23 | ... < ... | -| test.c:75:9:75:14 | ... == ... | -| test.c:85:8:85:13 | ... == ... | -| test.c:85:8:85:23 | ... && ... | -| test.c:85:18:85:23 | ... != ... | -| test.c:94:11:94:16 | ... != ... | -| test.c:102:16:102:21 | ... < ... | -| test.c:109:9:109:14 | ... == ... | -| test.c:109:9:109:23 | ... \|\| ... | -| test.c:109:19:109:23 | ... < ... | -| test.c:126:7:126:7 | 1 | -| test.c:126:7:126:28 | ... && ... | -| test.c:126:12:126:26 | call to test3_condition | -| test.c:131:7:131:7 | b | -| test.c:137:7:137:7 | 0 | -| test.c:146:7:146:8 | ! ... | -| test.c:146:8:146:8 | x | -| test.c:152:10:152:10 | x | -| test.c:152:10:152:15 | ... && ... | -| test.c:152:15:152:15 | y | -| test.c:156:9:156:19 | ... == ... | -| test.c:159:9:159:19 | ... == ... | -| test.c:162:9:162:18 | ... < ... | -| test.c:165:9:165:18 | ... < ... | -| test.c:175:13:175:32 | ... == ... | -| test.c:181:9:181:9 | x | -| test.cpp:18:8:18:10 | call to get | -| test.cpp:31:7:31:13 | ... == ... | -| test.cpp:42:13:42:20 | call to getABool | astGuardsCompare | 7 | 0 < x+0 when ... > ... is true | | 7 | 0 >= x+0 when ... > ... is false | @@ -901,40 +860,6 @@ astGuardsEnsure_const | test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | 31 | 32 | | test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | 43 | 45 | | test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 1 | 43 | 45 | -irGuards -| test.c:7:9:7:13 | CompareGT: ... > ... | -| test.c:17:8:17:12 | CompareLT: ... < ... | -| test.c:17:17:17:21 | CompareGT: ... > ... | -| test.c:26:11:26:15 | CompareGT: ... > ... | -| test.c:34:16:34:21 | CompareLT: ... < ... | -| test.c:42:16:42:21 | CompareLT: ... < ... | -| test.c:44:12:44:16 | CompareGT: ... > ... | -| test.c:45:16:45:20 | CompareGT: ... > ... | -| test.c:58:9:58:14 | CompareEQ: ... == ... | -| test.c:58:19:58:23 | CompareLT: ... < ... | -| test.c:75:9:75:14 | CompareEQ: ... == ... | -| test.c:85:8:85:13 | CompareEQ: ... == ... | -| test.c:85:18:85:23 | CompareNE: ... != ... | -| test.c:94:11:94:16 | CompareNE: ... != ... | -| test.c:102:16:102:21 | CompareLT: ... < ... | -| test.c:109:9:109:14 | CompareEQ: ... == ... | -| test.c:109:19:109:23 | CompareLT: ... < ... | -| test.c:126:7:126:7 | CompareNE: 1 | -| test.c:126:12:126:26 | CompareNE: call to test3_condition | -| test.c:131:7:131:7 | CompareNE: b | -| test.c:137:7:137:7 | CompareNE: 0 | -| test.c:146:7:146:8 | CompareEQ: ! ... | -| test.c:152:10:152:10 | CompareNE: x | -| test.c:152:15:152:15 | CompareNE: y | -| test.c:156:9:156:19 | CompareEQ: ... == ... | -| test.c:159:9:159:19 | CompareEQ: ... == ... | -| test.c:162:9:162:18 | CompareLT: ... < ... | -| test.c:165:9:165:18 | CompareLT: ... < ... | -| test.c:175:13:175:32 | CompareEQ: ... == ... | -| test.c:181:9:181:9 | CompareNE: x | -| test.cpp:18:8:18:12 | CompareNE: (bool)... | -| test.cpp:31:7:31:13 | CompareEQ: ... == ... | -| test.cpp:42:13:42:20 | Call: call to getABool | irGuardsCompare | 7 | 0 < x+0 when CompareGT: ... > ... is true | | 7 | 0 >= x+0 when CompareGT: ... > ... is false | diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql index e1009307880c..f91ae1e423d8 100644 --- a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql @@ -1,8 +1,6 @@ import cpp import semmle.code.cpp.controlflow.IRGuards -query predicate astGuards(GuardCondition guard) { any() } - query predicate astGuardsCompare(int startLine, string msg) { exists(GuardCondition guard, Expr left, int k, string op | exists(boolean sense, string which | @@ -70,8 +68,6 @@ query predicate astGuardsEnsure_const( ) } -query predicate irGuards(IRGuardCondition guard) { any() } - query predicate irGuardsCompare(int startLine, string msg) { exists(IRGuardCondition guard, Operand left, int k, string op | exists(boolean sense, string which | diff --git a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected deleted file mode 100644 index d26dd740e64e..000000000000 --- a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected +++ /dev/null @@ -1,1544 +0,0 @@ -| file://:0:0:0:0 | | -| file://:0:0:0:0 | & | -| file://:0:0:0:0 | && | -| file://:0:0:0:0 | (global namespace) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 1) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ../../../library-tests | -| file://:0:0:0:0 | ../../controlflow | -| file://:0:0:0:0 | ../guards | -| file://:0:0:0:0 | / | -| file://:0:0:0:0 | /Users | -| file://:0:0:0:0 | /Users/mathias | -| file://:0:0:0:0 | /Users/mathias/semmle-code | -| file://:0:0:0:0 | /Users/mathias/semmle-code/ql | -| file://:0:0:0:0 | /Users/mathias/semmle-code/ql/cpp | -| file://:0:0:0:0 | /Users/mathias/semmle-code/ql/cpp/ql | -| file://:0:0:0:0 | /Users/mathias/semmle-code/ql/cpp/ql/test | -| file://:0:0:0:0 | Error & | -| file://:0:0:0:0 | Error && | -| file://:0:0:0:0 | Error * | -| file://:0:0:0:0 | Mystruct & | -| file://:0:0:0:0 | Mystruct && | -| file://:0:0:0:0 | X & | -| file://:0:0:0:0 | X && | -| file://:0:0:0:0 | X * | -| file://:0:0:0:0 | Y & | -| file://:0:0:0:0 | Y && | -| file://:0:0:0:0 | Y * | -| file://:0:0:0:0 | _Complex _Float16 | -| file://:0:0:0:0 | _Complex _Float32 | -| file://:0:0:0:0 | _Complex _Float32x | -| file://:0:0:0:0 | _Complex _Float64 | -| file://:0:0:0:0 | _Complex _Float64x | -| file://:0:0:0:0 | _Complex _Float128 | -| file://:0:0:0:0 | _Complex __bf16 | -| file://:0:0:0:0 | _Complex __float128 | -| file://:0:0:0:0 | _Complex __fp16 | -| file://:0:0:0:0 | _Complex double | -| file://:0:0:0:0 | _Complex float | -| file://:0:0:0:0 | _Complex long double | -| file://:0:0:0:0 | _Complex std::float16_t | -| file://:0:0:0:0 | _Decimal32 | -| file://:0:0:0:0 | _Decimal64 | -| file://:0:0:0:0 | _Decimal128 | -| file://:0:0:0:0 | _Float16 | -| file://:0:0:0:0 | _Float32 | -| file://:0:0:0:0 | _Float32x | -| file://:0:0:0:0 | _Float64 | -| file://:0:0:0:0 | _Float64x | -| file://:0:0:0:0 | _Float128 | -| file://:0:0:0:0 | _Imaginary double | -| file://:0:0:0:0 | _Imaginary float | -| file://:0:0:0:0 | _Imaginary long double | -| file://:0:0:0:0 | __SVCount_t | -| file://:0:0:0:0 | __bf16 | -| file://:0:0:0:0 | __block | -| file://:0:0:0:0 | __builtin_expect | -| file://:0:0:0:0 | __float128 | -| file://:0:0:0:0 | __fp16 | -| file://:0:0:0:0 | __int128 | -| file://:0:0:0:0 | __interface | -| file://:0:0:0:0 | __mfp8 | -| file://:0:0:0:0 | __ptr32 | -| file://:0:0:0:0 | __ptr64 | -| file://:0:0:0:0 | __sptr | -| file://:0:0:0:0 | __super | -| file://:0:0:0:0 | __uptr | -| file://:0:0:0:0 | __va_list_tag | -| file://:0:0:0:0 | __va_list_tag & | -| file://:0:0:0:0 | __va_list_tag && | -| file://:0:0:0:0 | abstract | -| file://:0:0:0:0 | atomic | -| file://:0:0:0:0 | auto | -| file://:0:0:0:0 | auto | -| file://:0:0:0:0 | bool | -| file://:0:0:0:0 | bool & | -| file://:0:0:0:0 | c_linkage | -| file://:0:0:0:0 | cdecl | -| file://:0:0:0:0 | char | -| file://:0:0:0:0 | char8_t | -| file://:0:0:0:0 | char16_t | -| file://:0:0:0:0 | char32_t | -| file://:0:0:0:0 | char * | -| file://:0:0:0:0 | clrcall | -| file://:0:0:0:0 | const | -| file://:0:0:0:0 | const Error | -| file://:0:0:0:0 | const Error & | -| file://:0:0:0:0 | const Mystruct | -| file://:0:0:0:0 | const Mystruct & | -| file://:0:0:0:0 | const X | -| file://:0:0:0:0 | const X & | -| file://:0:0:0:0 | const X * | -| file://:0:0:0:0 | const Y | -| file://:0:0:0:0 | const Y & | -| file://:0:0:0:0 | const Y * | -| file://:0:0:0:0 | const __va_list_tag | -| file://:0:0:0:0 | const __va_list_tag & | -| file://:0:0:0:0 | declaration of (unnamed parameter 0) | -| file://:0:0:0:0 | declaration of (unnamed parameter 0) | -| file://:0:0:0:0 | declaration of (unnamed parameter 0) | -| file://:0:0:0:0 | declaration of (unnamed parameter 0) | -| file://:0:0:0:0 | declaration of (unnamed parameter 0) | -| file://:0:0:0:0 | declaration of (unnamed parameter 0) | -| file://:0:0:0:0 | declaration of (unnamed parameter 0) | -| file://:0:0:0:0 | declaration of (unnamed parameter 0) | -| file://:0:0:0:0 | declaration of (unnamed parameter 0) | -| file://:0:0:0:0 | declaration of (unnamed parameter 0) | -| file://:0:0:0:0 | declared_constexpr | -| file://:0:0:0:0 | declared_constinit | -| file://:0:0:0:0 | declared_virtual | -| file://:0:0:0:0 | decltype(nullptr) | -| file://:0:0:0:0 | definition of fp_offset | -| file://:0:0:0:0 | definition of gp_offset | -| file://:0:0:0:0 | definition of overflow_arg_area | -| file://:0:0:0:0 | definition of reg_save_area | -| file://:0:0:0:0 | dllexport | -| file://:0:0:0:0 | dllimport | -| file://:0:0:0:0 | double | -| file://:0:0:0:0 | error | -| file://:0:0:0:0 | explicit | -| file://:0:0:0:0 | extern | -| file://:0:0:0:0 | far | -| file://:0:0:0:0 | fastcall | -| file://:0:0:0:0 | final | -| file://:0:0:0:0 | float | -| file://:0:0:0:0 | forceinline | -| file://:0:0:0:0 | fp_offset | -| file://:0:0:0:0 | gp_offset | -| file://:0:0:0:0 | has_trailing_return_type | -| file://:0:0:0:0 | implicit_int | -| file://:0:0:0:0 | inline | -| file://:0:0:0:0 | int | -| file://:0:0:0:0 | is_consteval | -| file://:0:0:0:0 | is_constexpr | -| file://:0:0:0:0 | is_thread_local | -| file://:0:0:0:0 | long | -| file://:0:0:0:0 | long double | -| file://:0:0:0:0 | long long | -| file://:0:0:0:0 | microsoft_inline | -| file://:0:0:0:0 | naked | -| file://:0:0:0:0 | near | -| file://:0:0:0:0 | noalias | -| file://:0:0:0:0 | noinline | -| file://:0:0:0:0 | nonnull | -| file://:0:0:0:0 | noreturn | -| file://:0:0:0:0 | nothrow | -| file://:0:0:0:0 | novtable | -| file://:0:0:0:0 | null_unspecified | -| file://:0:0:0:0 | nullable | -| file://:0:0:0:0 | operator delete | -| file://:0:0:0:0 | operator new | -| file://:0:0:0:0 | operator= | -| file://:0:0:0:0 | operator= | -| file://:0:0:0:0 | optional | -| file://:0:0:0:0 | overflow_arg_area | -| file://:0:0:0:0 | override | -| file://:0:0:0:0 | private | -| file://:0:0:0:0 | protected | -| file://:0:0:0:0 | public | -| file://:0:0:0:0 | pure | -| file://:0:0:0:0 | reg_save_area | -| file://:0:0:0:0 | register | -| file://:0:0:0:0 | restrict | -| file://:0:0:0:0 | sealed | -| file://:0:0:0:0 | selectany | -| file://:0:0:0:0 | short | -| file://:0:0:0:0 | signed __int128 | -| file://:0:0:0:0 | signed char | -| file://:0:0:0:0 | signed int | -| file://:0:0:0:0 | signed long | -| file://:0:0:0:0 | signed long long | -| file://:0:0:0:0 | signed short | -| file://:0:0:0:0 | static | -| file://:0:0:0:0 | std::float16_t | -| file://:0:0:0:0 | stdcall | -| file://:0:0:0:0 | thiscall | -| file://:0:0:0:0 | thread | -| file://:0:0:0:0 | unaligned | -| file://:0:0:0:0 | unknown | -| file://:0:0:0:0 | unsigned __int128 | -| file://:0:0:0:0 | unsigned char | -| file://:0:0:0:0 | unsigned int | -| file://:0:0:0:0 | unsigned long | -| file://:0:0:0:0 | unsigned long long | -| file://:0:0:0:0 | unsigned short | -| file://:0:0:0:0 | varargs | -| file://:0:0:0:0 | vectorcall | -| file://:0:0:0:0 | virtual | -| file://:0:0:0:0 | void | -| file://:0:0:0:0 | void * | -| file://:0:0:0:0 | volatile | -| file://:0:0:0:0 | wchar_t | -| test.c:0:0:0:0 | test.c | -| test.c:2:5:2:8 | definition of test | -| test.c:2:5:2:8 | test | -| test.c:2:14:2:14 | definition of x | -| test.c:2:14:2:14 | x | -| test.c:2:21:2:21 | definition of w | -| test.c:2:21:2:21 | w | -| test.c:2:28:2:28 | definition of z | -| test.c:2:28:2:28 | z | -| test.c:2:31:67:1 | { ... } | -| test.c:3:5:3:10 | declaration | -| test.c:3:9:3:9 | definition of j | -| test.c:3:9:3:9 | j | -| test.c:4:5:4:16 | declaration | -| test.c:4:10:4:10 | definition of y | -| test.c:4:10:4:10 | y | -| test.c:4:13:4:15 | initializer for y | -| test.c:4:14:4:15 | 50 | -| test.c:4:14:4:15 | (long)... | -| test.c:6:5:6:24 | // simple comparison | -| test.c:7:5:12:5 | if (...) ... | -| test.c:7:9:7:9 | x | -| test.c:7:9:7:13 | ... > ... | -| test.c:7:13:7:13 | 0 | -| test.c:7:16:10:5 | { ... } | -| test.c:8:9:8:9 | y | -| test.c:8:9:8:14 | ... = ... | -| test.c:8:9:8:15 | ExprStmt | -| test.c:8:13:8:14 | 20 | -| test.c:8:13:8:14 | (long)... | -| test.c:9:9:9:9 | z | -| test.c:9:9:9:14 | ... = ... | -| test.c:9:9:9:15 | ExprStmt | -| test.c:9:13:9:14 | 10 | -| test.c:10:12:12:5 | { ... } | -| test.c:11:9:11:9 | y | -| test.c:11:9:11:14 | ... = ... | -| test.c:11:9:11:15 | ExprStmt | -| test.c:11:13:11:14 | 30 | -| test.c:11:13:11:14 | (long)... | -| test.c:14:5:14:5 | z | -| test.c:14:5:14:13 | ... = ... | -| test.c:14:5:14:14 | ExprStmt | -| test.c:14:9:14:9 | (long)... | -| test.c:14:9:14:9 | x | -| test.c:14:9:14:13 | (int)... | -| test.c:14:9:14:13 | ... + ... | -| test.c:14:13:14:13 | y | -| test.c:16:5:16:19 | // More complex | -| test.c:17:5:20:15 | if (...) ... | -| test.c:17:8:17:8 | x | -| test.c:17:8:17:12 | ... < ... | -| test.c:17:8:17:21 | ... && ... | -| test.c:17:12:17:12 | 0 | -| test.c:17:17:17:17 | y | -| test.c:17:17:17:21 | ... > ... | -| test.c:17:21:17:21 | 1 | -| test.c:17:21:17:21 | (long)... | -| test.c:18:9:18:9 | y | -| test.c:18:9:18:14 | ... = ... | -| test.c:18:9:18:15 | ExprStmt | -| test.c:18:13:18:14 | 40 | -| test.c:18:13:18:14 | (long)... | -| test.c:20:9:20:9 | y | -| test.c:20:9:20:14 | ... = ... | -| test.c:20:9:20:15 | ExprStmt | -| test.c:20:13:20:14 | 20 | -| test.c:20:13:20:14 | (long)... | -| test.c:20:18:20:111 | /* The && expression does not control this block as the x<0 expression jumps here if false. */ | -| test.c:23:5:23:5 | z | -| test.c:23:5:23:10 | ... = ... | -| test.c:23:5:23:11 | ExprStmt | -| test.c:23:9:23:10 | 10 | -| test.c:25:5:25:17 | // while loop | -| test.c:26:5:29:5 | while (...) ... | -| test.c:26:11:26:11 | x | -| test.c:26:11:26:15 | ... > ... | -| test.c:26:15:26:15 | 0 | -| test.c:26:18:29:5 | { ... } | -| test.c:27:9:27:9 | y | -| test.c:27:9:27:14 | ... = ... | -| test.c:27:9:27:15 | ExprStmt | -| test.c:27:13:27:14 | 10 | -| test.c:27:13:27:14 | (long)... | -| test.c:28:9:28:9 | x | -| test.c:28:9:28:11 | ... -- | -| test.c:28:9:28:12 | ExprStmt | -| test.c:31:5:31:5 | z | -| test.c:31:5:31:10 | ... += ... | -| test.c:31:5:31:11 | ExprStmt | -| test.c:31:10:31:10 | y | -| test.c:33:5:33:15 | // for loop | -| test.c:34:5:37:5 | for(...;...;...) ... | -| test.c:34:9:34:9 | j | -| test.c:34:9:34:13 | ... = ... | -| test.c:34:9:34:14 | ExprStmt | -| test.c:34:13:34:13 | 0 | -| test.c:34:16:34:16 | j | -| test.c:34:16:34:21 | ... < ... | -| test.c:34:20:34:21 | 10 | -| test.c:34:24:34:24 | j | -| test.c:34:24:34:26 | ... ++ | -| test.c:34:29:37:5 | { ... } | -| test.c:35:9:35:9 | y | -| test.c:35:9:35:13 | ... = ... | -| test.c:35:9:35:14 | ExprStmt | -| test.c:35:13:35:13 | 0 | -| test.c:35:13:35:13 | (long)... | -| test.c:36:9:36:9 | w | -| test.c:36:9:36:14 | ... = ... | -| test.c:36:9:36:15 | ExprStmt | -| test.c:36:13:36:14 | 10 | -| test.c:39:5:39:5 | z | -| test.c:39:5:39:10 | ... += ... | -| test.c:39:5:39:11 | ExprStmt | -| test.c:39:10:39:10 | w | -| test.c:41:5:41:26 | // nested control flow | -| test.c:42:5:42:5 | label ...: | -| test.c:42:5:42:5 | { ... } | -| test.c:42:5:56:5 | for(...;...;...) ... | -| test.c:42:9:42:9 | j | -| test.c:42:9:42:13 | ... = ... | -| test.c:42:9:42:14 | ExprStmt | -| test.c:42:13:42:13 | 0 | -| test.c:42:16:42:16 | j | -| test.c:42:16:42:21 | ... < ... | -| test.c:42:20:42:21 | 10 | -| test.c:42:24:42:24 | j | -| test.c:42:24:42:26 | ... ++ | -| test.c:42:29:56:5 | { ... } | -| test.c:43:9:43:9 | y | -| test.c:43:9:43:14 | ... = ... | -| test.c:43:9:43:15 | ExprStmt | -| test.c:43:13:43:14 | 30 | -| test.c:43:13:43:14 | (long)... | -| test.c:44:9:54:9 | if (...) ... | -| test.c:44:12:44:12 | z | -| test.c:44:12:44:16 | ... > ... | -| test.c:44:16:44:16 | 0 | -| test.c:45:13:50:13 | if (...) ... | -| test.c:45:16:45:16 | y | -| test.c:45:16:45:20 | ... > ... | -| test.c:45:20:45:20 | 0 | -| test.c:45:20:45:20 | (long)... | -| test.c:45:23:48:13 | { ... } | -| test.c:46:17:46:17 | w | -| test.c:46:17:46:21 | ... = ... | -| test.c:46:17:46:22 | ExprStmt | -| test.c:46:21:46:21 | 0 | -| test.c:47:17:47:22 | break; | -| test.c:48:20:50:13 | { ... } | -| test.c:49:17:49:17 | w | -| test.c:49:17:49:22 | ... = ... | -| test.c:49:17:49:23 | ExprStmt | -| test.c:49:21:49:22 | 20 | -| test.c:51:14:54:9 | { ... } | -| test.c:52:13:52:13 | w | -| test.c:52:13:52:18 | ... = ... | -| test.c:52:13:52:19 | ExprStmt | -| test.c:52:17:52:18 | 10 | -| test.c:53:13:53:21 | continue; | -| test.c:55:9:55:9 | x | -| test.c:55:9:55:13 | ... = ... | -| test.c:55:9:55:14 | ExprStmt | -| test.c:55:13:55:13 | 0 | -| test.c:56:5:56:5 | label ...: | -| test.c:58:5:62:17 | if (...) ... | -| test.c:58:9:58:9 | x | -| test.c:58:9:58:14 | ... == ... | -| test.c:58:9:58:23 | ... \|\| ... | -| test.c:58:14:58:14 | 0 | -| test.c:58:19:58:19 | y | -| test.c:58:19:58:23 | ... < ... | -| test.c:58:23:58:23 | 0 | -| test.c:58:23:58:23 | (long)... | -| test.c:58:26:61:5 | { ... } | -| test.c:59:9:59:9 | y | -| test.c:59:9:59:14 | ... = ... | -| test.c:59:9:59:15 | ExprStmt | -| test.c:59:13:59:14 | 60 | -| test.c:59:13:59:14 | (long)... | -| test.c:60:9:60:9 | z | -| test.c:60:9:60:14 | ... = ... | -| test.c:60:9:60:15 | ExprStmt | -| test.c:60:13:60:14 | 10 | -| test.c:62:9:62:17 | return ... | -| test.c:62:16:62:16 | z | -| test.c:64:5:64:5 | z | -| test.c:64:5:64:10 | ... += ... | -| test.c:64:5:64:11 | ExprStmt | -| test.c:64:10:64:10 | x | -| test.c:66:5:66:13 | return ... | -| test.c:66:12:66:12 | 0 | -| test.c:70:5:70:9 | definition of test2 | -| test.c:70:5:70:9 | test2 | -| test.c:70:15:70:15 | definition of x | -| test.c:70:15:70:15 | x | -| test.c:70:22:70:22 | definition of w | -| test.c:70:22:70:22 | w | -| test.c:70:29:70:29 | definition of z | -| test.c:70:29:70:29 | z | -| test.c:70:32:118:1 | { ... } | -| test.c:71:5:71:10 | declaration | -| test.c:71:9:71:9 | definition of j | -| test.c:71:9:71:9 | j | -| test.c:72:5:72:16 | declaration | -| test.c:72:10:72:10 | definition of y | -| test.c:72:10:72:10 | y | -| test.c:72:13:72:15 | initializer for y | -| test.c:72:14:72:15 | 50 | -| test.c:72:14:72:15 | (long)... | -| test.c:74:5:74:24 | // simple comparison | -| test.c:75:5:80:5 | if (...) ... | -| test.c:75:9:75:9 | x | -| test.c:75:9:75:14 | ... == ... | -| test.c:75:14:75:14 | 0 | -| test.c:75:17:78:5 | { ... } | -| test.c:76:9:76:9 | y | -| test.c:76:9:76:14 | ... = ... | -| test.c:76:9:76:15 | ExprStmt | -| test.c:76:13:76:14 | 20 | -| test.c:76:13:76:14 | (long)... | -| test.c:77:9:77:9 | z | -| test.c:77:9:77:14 | ... = ... | -| test.c:77:9:77:15 | ExprStmt | -| test.c:77:13:77:14 | 10 | -| test.c:78:12:80:5 | { ... } | -| test.c:79:9:79:9 | y | -| test.c:79:9:79:14 | ... = ... | -| test.c:79:9:79:15 | ExprStmt | -| test.c:79:13:79:14 | 30 | -| test.c:79:13:79:14 | (long)... | -| test.c:82:5:82:5 | z | -| test.c:82:5:82:13 | ... = ... | -| test.c:82:5:82:14 | ExprStmt | -| test.c:82:9:82:9 | (long)... | -| test.c:82:9:82:9 | x | -| test.c:82:9:82:13 | (int)... | -| test.c:82:9:82:13 | ... + ... | -| test.c:82:13:82:13 | y | -| test.c:84:5:84:19 | // More complex | -| test.c:85:5:88:15 | if (...) ... | -| test.c:85:8:85:8 | x | -| test.c:85:8:85:13 | ... == ... | -| test.c:85:8:85:23 | ... && ... | -| test.c:85:13:85:13 | 0 | -| test.c:85:18:85:18 | y | -| test.c:85:18:85:23 | ... != ... | -| test.c:85:23:85:23 | 0 | -| test.c:85:23:85:23 | (long)... | -| test.c:86:9:86:9 | y | -| test.c:86:9:86:14 | ... = ... | -| test.c:86:9:86:15 | ExprStmt | -| test.c:86:13:86:14 | 40 | -| test.c:86:13:86:14 | (long)... | -| test.c:88:9:88:9 | y | -| test.c:88:9:88:14 | ... = ... | -| test.c:88:9:88:15 | ExprStmt | -| test.c:88:13:88:14 | 20 | -| test.c:88:13:88:14 | (long)... | -| test.c:91:5:91:5 | z | -| test.c:91:5:91:10 | ... = ... | -| test.c:91:5:91:11 | ExprStmt | -| test.c:91:9:91:10 | 10 | -| test.c:93:5:93:17 | // while loop | -| test.c:94:5:97:5 | while (...) ... | -| test.c:94:11:94:11 | x | -| test.c:94:11:94:16 | ... != ... | -| test.c:94:16:94:16 | 0 | -| test.c:94:19:97:5 | { ... } | -| test.c:95:9:95:9 | y | -| test.c:95:9:95:14 | ... = ... | -| test.c:95:9:95:15 | ExprStmt | -| test.c:95:13:95:14 | 10 | -| test.c:95:13:95:14 | (long)... | -| test.c:96:9:96:9 | x | -| test.c:96:9:96:11 | ... -- | -| test.c:96:9:96:12 | ExprStmt | -| test.c:99:5:99:5 | z | -| test.c:99:5:99:10 | ... += ... | -| test.c:99:5:99:11 | ExprStmt | -| test.c:99:10:99:10 | y | -| test.c:101:5:101:15 | // for loop | -| test.c:102:5:105:5 | for(...;...;...) ... | -| test.c:102:9:102:9 | j | -| test.c:102:9:102:13 | ... = ... | -| test.c:102:9:102:14 | ExprStmt | -| test.c:102:13:102:13 | 0 | -| test.c:102:16:102:16 | j | -| test.c:102:16:102:21 | ... < ... | -| test.c:102:20:102:21 | 10 | -| test.c:102:24:102:24 | j | -| test.c:102:24:102:26 | ... ++ | -| test.c:102:29:105:5 | { ... } | -| test.c:103:9:103:9 | y | -| test.c:103:9:103:13 | ... = ... | -| test.c:103:9:103:14 | ExprStmt | -| test.c:103:13:103:13 | 0 | -| test.c:103:13:103:13 | (long)... | -| test.c:104:9:104:9 | w | -| test.c:104:9:104:14 | ... = ... | -| test.c:104:9:104:15 | ExprStmt | -| test.c:104:13:104:14 | 10 | -| test.c:107:5:107:5 | z | -| test.c:107:5:107:10 | ... += ... | -| test.c:107:5:107:11 | ExprStmt | -| test.c:107:10:107:10 | w | -| test.c:109:5:113:17 | if (...) ... | -| test.c:109:9:109:9 | x | -| test.c:109:9:109:14 | ... == ... | -| test.c:109:9:109:23 | ... \|\| ... | -| test.c:109:14:109:14 | 0 | -| test.c:109:19:109:19 | y | -| test.c:109:19:109:23 | ... < ... | -| test.c:109:23:109:23 | 0 | -| test.c:109:23:109:23 | (long)... | -| test.c:109:26:112:5 | { ... } | -| test.c:110:9:110:9 | y | -| test.c:110:9:110:14 | ... = ... | -| test.c:110:9:110:15 | ExprStmt | -| test.c:110:13:110:14 | 60 | -| test.c:110:13:110:14 | (long)... | -| test.c:111:9:111:9 | z | -| test.c:111:9:111:14 | ... = ... | -| test.c:111:9:111:15 | ExprStmt | -| test.c:111:13:111:14 | 10 | -| test.c:113:9:113:17 | return ... | -| test.c:113:16:113:16 | z | -| test.c:115:5:115:5 | z | -| test.c:115:5:115:10 | ... += ... | -| test.c:115:5:115:11 | ExprStmt | -| test.c:115:10:115:10 | x | -| test.c:117:5:117:13 | return ... | -| test.c:117:12:117:12 | 0 | -| test.c:120:5:120:19 | declaration of test3_condition | -| test.c:120:5:120:19 | test3_condition | -| test.c:121:6:121:17 | declaration of test3_action | -| test.c:121:6:121:17 | test3_action | -| test.c:123:6:123:10 | definition of test3 | -| test.c:123:6:123:10 | test3 | -| test.c:123:14:134:1 | { ... } | -| test.c:124:3:124:12 | declaration | -| test.c:124:7:124:7 | b | -| test.c:124:7:124:7 | definition of b | -| test.c:124:10:124:11 | 0 | -| test.c:124:10:124:11 | initializer for b | -| test.c:126:3:129:3 | if (...) ... | -| test.c:126:7:126:7 | 1 | -| test.c:126:7:126:28 | ... && ... | -| test.c:126:12:126:26 | call to test3_condition | -| test.c:126:31:129:3 | { ... } | -| test.c:127:5:127:5 | b | -| test.c:127:5:127:9 | ... = ... | -| test.c:127:5:127:10 | ExprStmt | -| test.c:127:9:127:9 | 1 | -| test.c:128:5:128:16 | call to test3_action | -| test.c:128:5:128:19 | ExprStmt | -| test.c:131:3:133:3 | if (...) ... | -| test.c:131:7:131:7 | b | -| test.c:131:10:133:3 | { ... } | -| test.c:132:5:132:16 | call to test3_action | -| test.c:132:5:132:19 | ExprStmt | -| test.c:134:1:134:1 | return ... | -| test.c:136:6:136:10 | definition of test4 | -| test.c:136:6:136:10 | test4 | -| test.c:136:16:136:16 | definition of i | -| test.c:136:16:136:16 | i | -| test.c:136:19:143:1 | { ... } | -| test.c:137:3:141:3 | if (...) ... | -| test.c:137:7:137:7 | 0 | -| test.c:137:10:141:3 | { ... } | -| test.c:138:5:140:5 | if (...) ... | -| test.c:138:9:138:9 | i | -| test.c:138:12:140:5 | { ... } | -| test.c:139:7:139:7 | ; | -| test.c:142:3:142:9 | return ... | -| test.c:145:6:145:10 | definition of test5 | -| test.c:145:6:145:10 | test5 | -| test.c:145:16:145:16 | definition of x | -| test.c:145:16:145:16 | x | -| test.c:145:19:149:1 | { ... } | -| test.c:146:3:148:3 | if (...) ... | -| test.c:146:7:146:8 | ! ... | -| test.c:146:8:146:8 | x | -| test.c:146:11:148:3 | { ... } | -| test.c:147:5:147:9 | call to test3 | -| test.c:147:5:147:12 | ExprStmt | -| test.c:149:1:149:1 | return ... | -| test.c:151:6:151:10 | definition of test6 | -| test.c:151:6:151:10 | test6 | -| test.c:151:18:151:18 | definition of p | -| test.c:151:18:151:18 | p | -| test.c:151:21:155:1 | { ... } | -| test.c:152:5:154:5 | if (...) ... | -| test.c:152:8:152:8 | p | -| test.c:152:11:154:5 | { ... } | -| test.c:155:1:155:1 | return ... | -| test.c:157:6:157:10 | definition of test7 | -| test.c:157:6:157:10 | test7 | -| test.c:157:18:157:18 | definition of p | -| test.c:157:18:157:18 | p | -| test.c:157:21:161:1 | { ... } | -| test.c:158:5:160:5 | if (...) ... | -| test.c:158:8:158:9 | ! ... | -| test.c:158:9:158:9 | p | -| test.c:158:12:160:5 | { ... } | -| test.c:161:1:161:1 | return ... | -| test.c:163:6:163:10 | definition of test8 | -| test.c:163:6:163:10 | test8 | -| test.c:163:18:163:18 | definition of s | -| test.c:163:18:163:18 | s | -| test.c:163:21:167:1 | { ... } | -| test.c:164:5:166:5 | if (...) ... | -| test.c:164:8:164:8 | s | -| test.c:164:11:166:5 | { ... } | -| test.c:167:1:167:1 | return ... | -| test.c:169:6:169:10 | definition of test9 | -| test.c:169:6:169:10 | test9 | -| test.c:169:18:169:18 | definition of s | -| test.c:169:18:169:18 | s | -| test.c:169:21:173:1 | { ... } | -| test.c:170:5:172:5 | if (...) ... | -| test.c:170:8:170:9 | ! ... | -| test.c:170:9:170:9 | s | -| test.c:170:12:172:5 | { ... } | -| test.c:173:1:173:1 | return ... | -| test.c:175:6:175:11 | definition of test10 | -| test.c:175:6:175:11 | test10 | -| test.c:175:17:175:17 | a | -| test.c:175:17:175:17 | definition of a | -| test.c:175:24:175:24 | b | -| test.c:175:24:175:24 | definition of b | -| test.c:175:27:179:1 | { ... } | -| test.c:176:5:178:5 | if (...) ... | -| test.c:176:8:176:15 | ! ... | -| test.c:176:9:176:15 | (...) | -| test.c:176:10:176:10 | a | -| test.c:176:10:176:14 | ... < ... | -| test.c:176:14:176:14 | b | -| test.c:176:18:178:5 | { ... } | -| test.c:179:1:179:1 | return ... | -| test.c:181:6:181:11 | definition of test11 | -| test.c:181:6:181:11 | test11 | -| test.c:181:20:181:22 | definition of foo | -| test.c:181:20:181:22 | foo | -| test.c:181:25:185:1 | { ... } | -| test.c:182:5:184:5 | if (...) ... | -| test.c:182:8:182:34 | ! ... | -| test.c:182:9:182:34 | (...) | -| test.c:182:10:182:12 | foo | -| test.c:182:10:182:20 | ... >= ... | -| test.c:182:10:182:33 | ... && ... | -| test.c:182:17:182:20 | 9.999999999999999547e-07 | -| test.c:182:25:182:27 | foo | -| test.c:182:25:182:33 | ... < ... | -| test.c:182:31:182:33 | 1.0 | -| test.c:182:37:184:5 | { ... } | -| test.c:185:1:185:1 | return ... | -| test.c:187:6:187:11 | definition of test12 | -| test.c:187:6:187:11 | test12 | -| test.c:187:17:187:17 | a | -| test.c:187:17:187:17 | definition of a | -| test.c:187:24:187:24 | b | -| test.c:187:24:187:24 | definition of b | -| test.c:187:27:193:1 | { ... } | -| test.c:188:3:188:17 | declaration | -| test.c:188:7:188:7 | c | -| test.c:188:7:188:7 | definition of c | -| test.c:188:10:188:16 | initializer for c | -| test.c:188:11:188:11 | a | -| test.c:188:11:188:16 | ... != ... | -| test.c:188:16:188:16 | b | -| test.c:190:3:192:3 | if (...) ... | -| test.c:190:7:190:8 | ! ... | -| test.c:190:8:190:8 | c | -| test.c:190:11:192:3 | { ... } | -| test.c:193:1:193:1 | return ... | -| test.c:195:6:195:11 | definition of test13 | -| test.c:195:6:195:11 | test13 | -| test.c:195:17:195:17 | a | -| test.c:195:17:195:17 | definition of a | -| test.c:195:20:201:1 | { ... } | -| test.c:196:3:196:17 | declaration | -| test.c:196:7:196:7 | b | -| test.c:196:7:196:7 | definition of b | -| test.c:196:10:196:16 | initializer for b | -| test.c:196:11:196:11 | a | -| test.c:196:11:196:16 | ... > ... | -| test.c:196:15:196:16 | 10 | -| test.c:198:3:200:3 | if (...) ... | -| test.c:198:7:198:8 | ! ... | -| test.c:198:8:198:8 | b | -| test.c:198:11:200:3 | { ... } | -| test.c:201:1:201:1 | return ... | -| test.c:203:6:203:11 | definition of test14 | -| test.c:203:6:203:11 | test14 | -| test.c:203:17:203:17 | a | -| test.c:203:17:203:17 | definition of a | -| test.c:203:24:203:24 | b | -| test.c:203:24:203:24 | definition of b | -| test.c:203:27:209:1 | { ... } | -| test.c:204:3:204:16 | declaration | -| test.c:204:7:204:7 | c | -| test.c:204:7:204:7 | definition of c | -| test.c:204:10:204:15 | initializer for c | -| test.c:204:11:204:11 | a | -| test.c:204:11:204:15 | ... > ... | -| test.c:204:15:204:15 | b | -| test.c:206:3:208:3 | if (...) ... | -| test.c:206:7:206:8 | ! ... | -| test.c:206:8:206:8 | c | -| test.c:206:11:208:3 | { ... } | -| test.c:209:1:209:1 | return ... | -| test.c:211:1:211:45 | #define likely(x) __builtin_expect(!!(x), 1) | -| test.c:213:6:213:11 | definition of test15 | -| test.c:213:6:213:11 | test15 | -| test.c:213:17:213:17 | a | -| test.c:213:17:213:17 | definition of a | -| test.c:213:24:213:24 | b | -| test.c:213:24:213:24 | definition of b | -| test.c:214:1:222:1 | { ... } | -| test.c:215:2:217:5 | if (...) ... | -| test.c:215:6:215:18 | 1 | -| test.c:215:6:215:18 | ! ... | -| test.c:215:6:215:18 | ! ... | -| test.c:215:6:215:18 | (...) | -| test.c:215:6:215:18 | (long)... | -| test.c:215:6:215:18 | (long)... | -| test.c:215:6:215:18 | call to __builtin_expect | -| test.c:215:6:215:18 | likely(x) | -| test.c:215:13:215:13 | a | -| test.c:215:13:215:17 | ... > ... | -| test.c:215:17:215:17 | b | -| test.c:215:21:217:5 | { ... } | -| test.c:219:5:221:5 | if (...) ... | -| test.c:219:9:219:22 | 1 | -| test.c:219:9:219:22 | ! ... | -| test.c:219:9:219:22 | ! ... | -| test.c:219:9:219:22 | (...) | -| test.c:219:9:219:22 | (long)... | -| test.c:219:9:219:22 | (long)... | -| test.c:219:9:219:22 | call to __builtin_expect | -| test.c:219:9:219:22 | likely(x) | -| test.c:219:16:219:16 | a | -| test.c:219:16:219:21 | ... > ... | -| test.c:219:20:219:21 | 42 | -| test.c:219:25:221:5 | { ... } | -| test.c:222:1:222:1 | return ... | -| test.cpp:0:0:0:0 | test.cpp | -| test.cpp:1:7:1:7 | X | -| test.cpp:1:7:1:7 | declaration of operator= | -| test.cpp:1:7:1:7 | declaration of operator= | -| test.cpp:1:7:1:7 | definition of X | -| test.cpp:1:7:1:7 | operator= | -| test.cpp:1:7:1:7 | operator= | -| test.cpp:4:8:4:10 | declaration of set | -| test.cpp:4:8:4:10 | set | -| test.cpp:7:7:7:7 | Y | -| test.cpp:7:7:7:7 | declaration of operator= | -| test.cpp:7:7:7:7 | declaration of operator= | -| test.cpp:7:7:7:7 | definition of Y | -| test.cpp:7:7:7:7 | operator= | -| test.cpp:7:7:7:7 | operator= | -| test.cpp:10:3:10:3 | type mention | -| test.cpp:10:6:10:6 | declaration of f | -| test.cpp:12:9:12:9 | type mention | -| test.cpp:12:12:12:14 | definition of get | -| test.cpp:12:12:12:14 | get | -| test.cpp:12:24:12:36 | { ... } | -| test.cpp:12:26:12:34 | return ... | -| test.cpp:12:33:12:33 | 0 | -| test.cpp:12:33:12:33 | (const X *)... | -| test.cpp:13:3:13:3 | type mention | -| test.cpp:13:6:13:8 | definition of get | -| test.cpp:13:6:13:8 | get | -| test.cpp:13:12:13:24 | { ... } | -| test.cpp:13:14:13:22 | return ... | -| test.cpp:13:21:13:21 | 0 | -| test.cpp:13:21:13:21 | (X *)... | -| test.cpp:16:1:16:1 | type mention | -| test.cpp:16:4:16:4 | type mention | -| test.cpp:16:4:16:7 | definition of f | -| test.cpp:16:4:16:7 | f | -| test.cpp:17:1:21:1 | { ... } | -| test.cpp:18:3:19:17 | if (...) ... | -| test.cpp:18:8:18:10 | call to get | -| test.cpp:18:8:18:10 | this | -| test.cpp:18:8:18:12 | (bool)... | -| test.cpp:19:5:19:7 | call to get | -| test.cpp:19:5:19:7 | this | -| test.cpp:19:5:19:17 | ExprStmt | -| test.cpp:19:12:19:14 | call to set | -| test.cpp:20:3:20:11 | return ... | -| test.cpp:20:10:20:10 | 0 | -| test.cpp:20:10:20:10 | (Y *)... | -| test.cpp:23:7:23:7 | Error | -| test.cpp:23:7:23:7 | Error | -| test.cpp:23:7:23:7 | declaration of Error | -| test.cpp:23:7:23:7 | declaration of Error | -| test.cpp:23:7:23:7 | declaration of operator= | -| test.cpp:23:7:23:7 | declaration of operator= | -| test.cpp:23:7:23:7 | operator= | -| test.cpp:23:7:23:7 | operator= | -| test.cpp:23:7:23:11 | Error | -| test.cpp:23:7:23:11 | definition of Error | -| test.cpp:25:3:25:7 | Error | -| test.cpp:25:3:25:7 | definition of Error | -| test.cpp:25:11:25:12 | { ... } | -| test.cpp:25:12:25:12 | return ... | -| test.cpp:28:6:28:13 | declaration of getABool | -| test.cpp:28:6:28:13 | getABool | -| test.cpp:30:6:30:16 | definition of doSomething | -| test.cpp:30:6:30:16 | doSomething | -| test.cpp:30:22:30:22 | definition of x | -| test.cpp:30:22:30:22 | x | -| test.cpp:30:25:34:1 | { ... } | -| test.cpp:31:3:33:3 | if (...) ... | -| test.cpp:31:7:31:7 | x | -| test.cpp:31:7:31:13 | ... == ... | -| test.cpp:31:12:31:13 | - ... | -| test.cpp:31:13:31:13 | 1 | -| test.cpp:31:16:33:3 | { ... } | -| test.cpp:32:5:32:21 | throw ... | -| test.cpp:32:5:32:22 | ExprStmt | -| test.cpp:32:11:32:21 | call to Error | -| test.cpp:32:11:32:21 | new | -| test.cpp:32:15:32:19 | type mention | -| test.cpp:34:1:34:1 | return ... | -| test.cpp:36:6:36:20 | declaration of doSomethingElse | -| test.cpp:36:6:36:20 | doSomethingElse | -| test.cpp:36:26:36:26 | declaration of x | -| test.cpp:36:26:36:26 | x | -| test.cpp:38:6:38:19 | definition of testWithCatch0 | -| test.cpp:38:6:38:19 | testWithCatch0 | -| test.cpp:38:25:38:25 | definition of v | -| test.cpp:38:25:38:25 | v | -| test.cpp:39:1:54:1 | { ... } | -| test.cpp:40:5:47:5 | try { ... } | -| test.cpp:41:5:47:5 | { ... } | -| test.cpp:42:9:46:9 | if (...) ... | -| test.cpp:42:13:42:20 | call to getABool | -| test.cpp:43:9:46:9 | { ... } | -| test.cpp:44:13:44:23 | call to doSomething | -| test.cpp:44:13:44:27 | ExprStmt | -| test.cpp:44:25:44:25 | v | -| test.cpp:45:13:45:24 | return ... | -| test.cpp:45:20:45:23 | 1 | -| test.cpp:48:11:48:15 | type mention | -| test.cpp:48:18:48:18 | definition of e | -| test.cpp:48:18:48:18 | e | -| test.cpp:49:5:51:5 | | -| test.cpp:49:5:51:5 | { ... } | -| test.cpp:50:7:50:21 | call to doSomethingElse | -| test.cpp:50:7:50:25 | ExprStmt | -| test.cpp:50:23:50:23 | v | -| test.cpp:53:5:53:17 | return ... | -| test.cpp:53:12:53:16 | 0 | -| test.cpp:56:6:56:9 | declaration of use1 | -| test.cpp:56:6:56:9 | use1 | -| test.cpp:56:11:56:13 | (unnamed parameter 0) | -| test.cpp:56:11:56:13 | declaration of (unnamed parameter 0) | -| test.cpp:57:6:57:9 | declaration of use2 | -| test.cpp:57:6:57:9 | use2 | -| test.cpp:57:11:57:13 | (unnamed parameter 0) | -| test.cpp:57:11:57:13 | declaration of (unnamed parameter 0) | -| test.cpp:58:6:58:9 | declaration of use3 | -| test.cpp:58:6:58:9 | use3 | -| test.cpp:58:11:58:13 | (unnamed parameter 0) | -| test.cpp:58:11:58:13 | declaration of (unnamed parameter 0) | -| test.cpp:60:6:60:25 | definition of test_switches_simple | -| test.cpp:60:6:60:25 | test_switches_simple | -| test.cpp:60:31:60:31 | definition of i | -| test.cpp:60:31:60:31 | i | -| test.cpp:60:34:71:1 | { ... } | -| test.cpp:61:3:70:3 | switch (...) ... | -| test.cpp:61:10:61:10 | i | -| test.cpp:61:13:70:3 | { ... } | -| test.cpp:62:5:62:11 | case ...: | -| test.cpp:62:10:62:10 | 0 | -| test.cpp:63:7:63:10 | call to use1 | -| test.cpp:63:7:63:14 | ExprStmt | -| test.cpp:63:12:63:12 | i | -| test.cpp:64:7:64:12 | break; | -| test.cpp:65:5:65:11 | case ...: | -| test.cpp:65:10:65:10 | 1 | -| test.cpp:66:7:66:10 | call to use2 | -| test.cpp:66:7:66:14 | ExprStmt | -| test.cpp:66:12:66:12 | i | -| test.cpp:67:7:67:29 | /* NOTE: fallthrough */ | -| test.cpp:68:5:68:11 | case ...: | -| test.cpp:68:10:68:10 | 2 | -| test.cpp:69:7:69:10 | call to use3 | -| test.cpp:69:7:69:14 | ExprStmt | -| test.cpp:69:12:69:12 | i | -| test.cpp:70:3:70:3 | label ...: | -| test.cpp:71:1:71:1 | return ... | -| test.cpp:73:6:73:24 | definition of test_switches_range | -| test.cpp:73:6:73:24 | test_switches_range | -| test.cpp:73:30:73:30 | definition of i | -| test.cpp:73:30:73:30 | i | -| test.cpp:73:33:81:1 | { ... } | -| test.cpp:74:3:80:3 | switch (...) ... | -| test.cpp:74:10:74:10 | i | -| test.cpp:74:13:80:3 | { ... } | -| test.cpp:75:5:75:18 | case ...: | -| test.cpp:75:10:75:10 | 0 | -| test.cpp:75:16:75:17 | 10 | -| test.cpp:76:7:76:10 | call to use1 | -| test.cpp:76:7:76:14 | ExprStmt | -| test.cpp:76:12:76:12 | i | -| test.cpp:77:7:77:12 | break; | -| test.cpp:78:5:78:19 | case ...: | -| test.cpp:78:10:78:11 | 11 | -| test.cpp:78:17:78:18 | 20 | -| test.cpp:79:7:79:10 | call to use2 | -| test.cpp:79:7:79:14 | ExprStmt | -| test.cpp:79:12:79:12 | i | -| test.cpp:80:3:80:3 | label ...: | -| test.cpp:81:1:81:1 | return ... | -| test.cpp:83:6:83:26 | definition of test_switches_default | -| test.cpp:83:6:83:26 | test_switches_default | -| test.cpp:83:32:83:32 | definition of i | -| test.cpp:83:32:83:32 | i | -| test.cpp:83:35:88:1 | { ... } | -| test.cpp:84:3:87:3 | switch (...) ... | -| test.cpp:84:10:84:10 | i | -| test.cpp:84:13:87:3 | { ... } | -| test.cpp:85:5:85:12 | default: | -| test.cpp:86:7:86:10 | call to use1 | -| test.cpp:86:7:86:14 | ExprStmt | -| test.cpp:86:12:86:12 | i | -| test.cpp:88:1:88:1 | return ... | -| test.cpp:90:6:90:8 | declaration of use | -| test.cpp:90:6:90:8 | use | -| test.cpp:92:6:92:23 | definition of pointer_comparison | -| test.cpp:92:6:92:23 | pointer_comparison | -| test.cpp:92:31:92:31 | c | -| test.cpp:92:31:92:31 | definition of c | -| test.cpp:92:34:96:1 | { ... } | -| test.cpp:93:3:95:3 | if (...) ... | -| test.cpp:93:6:93:6 | (bool)... | -| test.cpp:93:6:93:6 | c | -| test.cpp:93:9:95:3 | { ... } | -| test.cpp:94:5:94:7 | call to use | -| test.cpp:94:5:94:11 | ExprStmt | -| test.cpp:94:9:94:9 | c | -| test.cpp:96:1:96:1 | return ... | -| test.cpp:98:6:98:30 | definition of implicit_float_comparison | -| test.cpp:98:6:98:30 | implicit_float_comparison | -| test.cpp:98:38:98:38 | definition of f | -| test.cpp:98:38:98:38 | f | -| test.cpp:98:41:102:1 | { ... } | -| test.cpp:99:3:101:3 | if (...) ... | -| test.cpp:99:6:99:6 | (bool)... | -| test.cpp:99:6:99:6 | f | -| test.cpp:99:9:101:3 | { ... } | -| test.cpp:100:5:100:7 | call to use | -| test.cpp:100:5:100:11 | ExprStmt | -| test.cpp:100:9:100:9 | (double)... | -| test.cpp:100:9:100:9 | f | -| test.cpp:102:1:102:1 | return ... | -| test.cpp:104:6:104:30 | definition of explicit_float_comparison | -| test.cpp:104:6:104:30 | explicit_float_comparison | -| test.cpp:104:38:104:38 | definition of f | -| test.cpp:104:38:104:38 | f | -| test.cpp:104:41:108:1 | { ... } | -| test.cpp:105:3:107:3 | if (...) ... | -| test.cpp:105:6:105:6 | f | -| test.cpp:105:6:105:14 | ... != ... | -| test.cpp:105:11:105:14 | 0.0 | -| test.cpp:105:17:107:3 | { ... } | -| test.cpp:106:5:106:7 | call to use | -| test.cpp:106:5:106:11 | ExprStmt | -| test.cpp:106:9:106:9 | (double)... | -| test.cpp:106:9:106:9 | f | -| test.cpp:108:1:108:1 | return ... | -| test.cpp:110:6:110:25 | definition of int_float_comparison | -| test.cpp:110:6:110:25 | int_float_comparison | -| test.cpp:110:31:110:31 | definition of i | -| test.cpp:110:31:110:31 | i | -| test.cpp:110:34:114:1 | { ... } | -| test.cpp:111:3:113:3 | if (...) ... | -| test.cpp:111:6:111:6 | (float)... | -| test.cpp:111:6:111:6 | i | -| test.cpp:111:6:111:14 | ... != ... | -| test.cpp:111:11:111:14 | 0.0 | -| test.cpp:111:17:113:3 | { ... } | -| test.cpp:112:5:112:7 | call to use | -| test.cpp:112:5:112:11 | ExprStmt | -| test.cpp:112:9:112:9 | i | -| test.cpp:114:1:114:1 | return ... | -| test.cpp:116:5:116:10 | declaration of source | -| test.cpp:116:5:116:10 | source | -| test.cpp:117:6:117:9 | declaration of safe | -| test.cpp:117:6:117:9 | safe | -| test.cpp:117:11:117:13 | (unnamed parameter 0) | -| test.cpp:117:11:117:13 | declaration of (unnamed parameter 0) | -| test.cpp:119:6:119:9 | definition of test | -| test.cpp:119:6:119:9 | test | -| test.cpp:119:16:119:16 | b | -| test.cpp:119:16:119:16 | definition of b | -| test.cpp:120:1:128:1 | { ... } | -| test.cpp:121:5:121:10 | declaration | -| test.cpp:121:9:121:9 | definition of x | -| test.cpp:121:9:121:9 | x | -| test.cpp:122:5:126:5 | if (...) ... | -| test.cpp:122:9:122:9 | b | -| test.cpp:123:5:126:5 | { ... } | -| test.cpp:124:9:124:9 | x | -| test.cpp:124:9:124:20 | ... = ... | -| test.cpp:124:9:124:21 | ExprStmt | -| test.cpp:124:13:124:18 | call to source | -| test.cpp:125:9:125:29 | if (...) ... | -| test.cpp:125:13:125:20 | ! ... | -| test.cpp:125:14:125:17 | call to safe | -| test.cpp:125:19:125:19 | x | -| test.cpp:125:23:125:29 | return ... | -| test.cpp:127:5:127:7 | call to use | -| test.cpp:127:5:127:11 | ExprStmt | -| test.cpp:127:9:127:9 | x | -| test.cpp:128:1:128:1 | return ... | -| test.cpp:130:6:130:33 | binary_test_builtin_expected | -| test.cpp:130:6:130:33 | definition of binary_test_builtin_expected | -| test.cpp:130:39:130:39 | a | -| test.cpp:130:39:130:39 | definition of a | -| test.cpp:130:46:130:46 | b | -| test.cpp:130:46:130:46 | definition of b | -| test.cpp:130:49:138:1 | { ... } | -| test.cpp:131:3:133:3 | if (...) ... | -| test.cpp:131:6:131:21 | call to __builtin_expect | -| test.cpp:131:6:131:37 | (bool)... | -| test.cpp:131:23:131:23 | a | -| test.cpp:131:23:131:33 | (long)... | -| test.cpp:131:23:131:33 | ... == ... | -| test.cpp:131:28:131:28 | b | -| test.cpp:131:28:131:33 | ... + ... | -| test.cpp:131:32:131:33 | 42 | -| test.cpp:131:36:131:36 | 0 | -| test.cpp:131:36:131:36 | (long)... | -| test.cpp:131:40:133:3 | { ... } | -| test.cpp:132:7:132:9 | call to use | -| test.cpp:132:7:132:13 | ExprStmt | -| test.cpp:132:11:132:11 | a | -| test.cpp:135:3:137:3 | if (...) ... | -| test.cpp:135:6:135:21 | call to __builtin_expect | -| test.cpp:135:6:135:37 | (bool)... | -| test.cpp:135:23:135:23 | a | -| test.cpp:135:23:135:33 | (long)... | -| test.cpp:135:23:135:33 | ... != ... | -| test.cpp:135:28:135:28 | b | -| test.cpp:135:28:135:33 | ... + ... | -| test.cpp:135:32:135:33 | 42 | -| test.cpp:135:36:135:36 | 0 | -| test.cpp:135:36:135:36 | (long)... | -| test.cpp:135:40:137:3 | { ... } | -| test.cpp:136:7:136:9 | call to use | -| test.cpp:136:7:136:13 | ExprStmt | -| test.cpp:136:11:136:11 | a | -| test.cpp:138:1:138:1 | return ... | -| test.cpp:140:6:140:32 | definition of unary_test_builtin_expected | -| test.cpp:140:6:140:32 | unary_test_builtin_expected | -| test.cpp:140:38:140:38 | a | -| test.cpp:140:38:140:38 | definition of a | -| test.cpp:140:41:148:1 | { ... } | -| test.cpp:141:3:143:3 | if (...) ... | -| test.cpp:141:6:141:21 | call to __builtin_expect | -| test.cpp:141:6:141:33 | (bool)... | -| test.cpp:141:23:141:23 | a | -| test.cpp:141:23:141:29 | (long)... | -| test.cpp:141:23:141:29 | ... == ... | -| test.cpp:141:28:141:29 | 42 | -| test.cpp:141:32:141:32 | 0 | -| test.cpp:141:32:141:32 | (long)... | -| test.cpp:141:36:143:3 | { ... } | -| test.cpp:142:7:142:9 | call to use | -| test.cpp:142:7:142:13 | ExprStmt | -| test.cpp:142:11:142:11 | a | -| test.cpp:145:3:147:3 | if (...) ... | -| test.cpp:145:6:145:21 | call to __builtin_expect | -| test.cpp:145:6:145:33 | (bool)... | -| test.cpp:145:23:145:23 | a | -| test.cpp:145:23:145:29 | (long)... | -| test.cpp:145:23:145:29 | ... != ... | -| test.cpp:145:28:145:29 | 42 | -| test.cpp:145:32:145:32 | 0 | -| test.cpp:145:32:145:32 | (long)... | -| test.cpp:145:36:147:3 | { ... } | -| test.cpp:146:7:146:9 | call to use | -| test.cpp:146:7:146:13 | ExprStmt | -| test.cpp:146:11:146:11 | a | -| test.cpp:148:1:148:1 | return ... | -| test.cpp:150:6:150:24 | definition of test_with_reference | -| test.cpp:150:6:150:24 | test_with_reference | -| test.cpp:150:32:150:32 | b | -| test.cpp:150:32:150:32 | definition of b | -| test.cpp:150:39:150:39 | a | -| test.cpp:150:39:150:39 | definition of a | -| test.cpp:150:42:155:1 | { ... } | -| test.cpp:151:4:151:4 | (reference dereference) | -| test.cpp:151:4:151:4 | b | -| test.cpp:151:4:151:13 | ... = ... | -| test.cpp:151:4:151:14 | ExprStmt | -| test.cpp:151:8:151:8 | a | -| test.cpp:151:8:151:13 | ... < ... | -| test.cpp:151:12:151:13 | 10 | -| test.cpp:152:4:154:4 | if (...) ... | -| test.cpp:152:7:152:8 | ! ... | -| test.cpp:152:8:152:8 | (reference dereference) | -| test.cpp:152:8:152:8 | b | -| test.cpp:152:11:154:4 | { ... } | -| test.cpp:153:7:153:9 | call to use | -| test.cpp:153:7:153:13 | ExprStmt | -| test.cpp:153:11:153:11 | a | -| test.cpp:155:1:155:1 | return ... | -| test.cpp:157:6:157:38 | definition of test_with_negated_binary_equality | -| test.cpp:157:6:157:38 | test_with_negated_binary_equality | -| test.cpp:157:44:157:44 | a | -| test.cpp:157:44:157:44 | definition of a | -| test.cpp:157:51:157:51 | b | -| test.cpp:157:51:157:51 | definition of b | -| test.cpp:157:54:163:1 | { ... } | -| test.cpp:158:3:158:18 | declaration | -| test.cpp:158:8:158:8 | c | -| test.cpp:158:8:158:8 | definition of c | -| test.cpp:158:11:158:17 | initializer for c | -| test.cpp:158:12:158:12 | a | -| test.cpp:158:12:158:17 | ... != ... | -| test.cpp:158:17:158:17 | b | -| test.cpp:160:3:162:3 | if (...) ... | -| test.cpp:160:7:160:8 | ! ... | -| test.cpp:160:8:160:8 | c | -| test.cpp:160:11:162:3 | { ... } | -| test.cpp:163:1:163:1 | return ... | -| test.cpp:165:6:165:39 | definition of test_with_negated_unary_relational | -| test.cpp:165:6:165:39 | test_with_negated_unary_relational | -| test.cpp:165:45:165:45 | a | -| test.cpp:165:45:165:45 | definition of a | -| test.cpp:165:48:171:1 | { ... } | -| test.cpp:166:3:166:18 | declaration | -| test.cpp:166:8:166:8 | b | -| test.cpp:166:8:166:8 | definition of b | -| test.cpp:166:11:166:17 | initializer for b | -| test.cpp:166:12:166:12 | a | -| test.cpp:166:12:166:17 | ... > ... | -| test.cpp:166:16:166:17 | 10 | -| test.cpp:168:3:170:3 | if (...) ... | -| test.cpp:168:7:168:8 | ! ... | -| test.cpp:168:8:168:8 | b | -| test.cpp:168:11:170:3 | { ... } | -| test.cpp:171:1:171:1 | return ... | -| test.cpp:173:6:173:40 | definition of test_with_negated_binary_relational | -| test.cpp:173:6:173:40 | test_with_negated_binary_relational | -| test.cpp:173:46:173:46 | a | -| test.cpp:173:46:173:46 | definition of a | -| test.cpp:173:53:173:53 | b | -| test.cpp:173:53:173:53 | definition of b | -| test.cpp:173:56:179:1 | { ... } | -| test.cpp:174:3:174:17 | declaration | -| test.cpp:174:8:174:8 | c | -| test.cpp:174:8:174:8 | definition of c | -| test.cpp:174:11:174:16 | initializer for c | -| test.cpp:174:12:174:12 | a | -| test.cpp:174:12:174:16 | ... > ... | -| test.cpp:174:16:174:16 | b | -| test.cpp:176:3:178:3 | if (...) ... | -| test.cpp:176:7:176:8 | ! ... | -| test.cpp:176:8:176:8 | c | -| test.cpp:176:11:178:3 | { ... } | -| test.cpp:179:1:179:1 | return ... | -| test.cpp:181:6:181:21 | definition of test_logical_and | -| test.cpp:181:6:181:21 | test_logical_and | -| test.cpp:181:28:181:29 | b1 | -| test.cpp:181:28:181:29 | definition of b1 | -| test.cpp:181:37:181:38 | b2 | -| test.cpp:181:37:181:38 | definition of b2 | -| test.cpp:181:41:190:1 | { ... } | -| test.cpp:182:3:189:3 | if (...) ... | -| test.cpp:182:6:182:16 | ! ... | -| test.cpp:182:7:182:16 | (...) | -| test.cpp:182:8:182:9 | b1 | -| test.cpp:182:8:182:15 | ... && ... | -| test.cpp:182:14:182:15 | b2 | -| test.cpp:182:19:185:3 | { ... } | -| test.cpp:183:5:183:7 | call to use | -| test.cpp:183:5:183:12 | ExprStmt | -| test.cpp:183:9:183:10 | (int)... | -| test.cpp:183:9:183:10 | b1 | -| test.cpp:184:5:184:7 | call to use | -| test.cpp:184:5:184:12 | ExprStmt | -| test.cpp:184:9:184:10 | (int)... | -| test.cpp:184:9:184:10 | b2 | -| test.cpp:185:10:189:3 | { ... } | -| test.cpp:186:5:186:30 | // b1 = true and b2 = true | -| test.cpp:187:5:187:7 | call to use | -| test.cpp:187:5:187:12 | ExprStmt | -| test.cpp:187:9:187:10 | (int)... | -| test.cpp:187:9:187:10 | b1 | -| test.cpp:188:5:188:7 | call to use | -| test.cpp:188:5:188:12 | ExprStmt | -| test.cpp:188:9:188:10 | (int)... | -| test.cpp:188:9:188:10 | b2 | -| test.cpp:190:1:190:1 | return ... | -| test.cpp:192:6:192:20 | definition of test_logical_or | -| test.cpp:192:6:192:20 | test_logical_or | -| test.cpp:192:27:192:28 | b1 | -| test.cpp:192:27:192:28 | definition of b1 | -| test.cpp:192:36:192:37 | b2 | -| test.cpp:192:36:192:37 | definition of b2 | -| test.cpp:192:40:201:1 | { ... } | -| test.cpp:193:3:200:3 | if (...) ... | -| test.cpp:193:6:193:16 | ! ... | -| test.cpp:193:7:193:16 | (...) | -| test.cpp:193:8:193:9 | b1 | -| test.cpp:193:8:193:15 | ... \|\| ... | -| test.cpp:193:14:193:15 | b2 | -| test.cpp:193:19:197:3 | { ... } | -| test.cpp:194:5:194:32 | // b1 = false and b2 = false | -| test.cpp:195:5:195:7 | call to use | -| test.cpp:195:5:195:12 | ExprStmt | -| test.cpp:195:9:195:10 | (int)... | -| test.cpp:195:9:195:10 | b1 | -| test.cpp:196:5:196:7 | call to use | -| test.cpp:196:5:196:12 | ExprStmt | -| test.cpp:196:9:196:10 | (int)... | -| test.cpp:196:9:196:10 | b2 | -| test.cpp:197:10:200:3 | { ... } | -| test.cpp:198:5:198:7 | call to use | -| test.cpp:198:5:198:12 | ExprStmt | -| test.cpp:198:9:198:10 | (int)... | -| test.cpp:198:9:198:10 | b1 | -| test.cpp:199:5:199:7 | call to use | -| test.cpp:199:5:199:12 | ExprStmt | -| test.cpp:199:9:199:10 | (int)... | -| test.cpp:199:9:199:10 | b2 | -| test.cpp:201:1:201:1 | return ... | -| test.cpp:203:8:203:8 | declaration of operator= | -| test.cpp:203:8:203:8 | declaration of operator= | -| test.cpp:203:8:203:8 | operator= | -| test.cpp:203:8:203:8 | operator= | -| test.cpp:203:8:203:15 | Mystruct | -| test.cpp:203:8:203:15 | definition of Mystruct | -| test.cpp:204:7:204:7 | definition of i | -| test.cpp:204:7:204:7 | i | -| test.cpp:205:9:205:9 | definition of f | -| test.cpp:205:9:205:9 | f | -| test.cpp:208:5:208:14 | definition of test_types | -| test.cpp:208:5:208:14 | test_types | -| test.cpp:208:28:208:29 | definition of sc | -| test.cpp:208:28:208:29 | sc | -| test.cpp:208:46:208:47 | definition of ul | -| test.cpp:208:46:208:47 | ul | -| test.cpp:208:56:208:56 | definition of f | -| test.cpp:208:56:208:56 | f | -| test.cpp:208:66:208:66 | d | -| test.cpp:208:66:208:66 | definition of d | -| test.cpp:208:74:208:74 | b | -| test.cpp:208:74:208:74 | definition of b | -| test.cpp:208:77:208:84 | type mention | -| test.cpp:208:87:208:88 | definition of ms | -| test.cpp:208:87:208:88 | ms | -| test.cpp:208:91:244:1 | { ... } | -| test.cpp:209:5:209:16 | declaration | -| test.cpp:209:9:209:11 | ctr | -| test.cpp:209:9:209:11 | definition of ctr | -| test.cpp:209:14:209:15 | 0 | -| test.cpp:209:14:209:15 | initializer for ctr | -| test.cpp:211:5:213:5 | if (...) ... | -| test.cpp:211:9:211:10 | (int)... | -| test.cpp:211:9:211:10 | sc | -| test.cpp:211:9:211:15 | ... == ... | -| test.cpp:211:15:211:15 | 0 | -| test.cpp:211:18:213:5 | { ... } | -| test.cpp:212:9:212:11 | ctr | -| test.cpp:212:9:212:13 | ... ++ | -| test.cpp:212:9:212:14 | ExprStmt | -| test.cpp:214:5:216:5 | if (...) ... | -| test.cpp:214:9:214:10 | (int)... | -| test.cpp:214:9:214:10 | sc | -| test.cpp:214:9:214:17 | ... == ... | -| test.cpp:214:15:214:17 | 0 | -| test.cpp:214:20:216:5 | { ... } | -| test.cpp:215:9:215:11 | ctr | -| test.cpp:215:9:215:13 | ... ++ | -| test.cpp:215:9:215:14 | ExprStmt | -| test.cpp:217:5:219:5 | if (...) ... | -| test.cpp:217:9:217:10 | ul | -| test.cpp:217:9:217:15 | ... == ... | -| test.cpp:217:15:217:15 | 0 | -| test.cpp:217:15:217:15 | (unsigned long)... | -| test.cpp:217:18:219:5 | { ... } | -| test.cpp:218:9:218:11 | ctr | -| test.cpp:218:9:218:13 | ... ++ | -| test.cpp:218:9:218:14 | ExprStmt | -| test.cpp:220:5:222:5 | if (...) ... | -| test.cpp:220:9:220:9 | f | -| test.cpp:220:9:220:14 | ... == ... | -| test.cpp:220:14:220:14 | 0 | -| test.cpp:220:14:220:14 | (float)... | -| test.cpp:220:17:222:5 | { ... } | -| test.cpp:221:9:221:11 | ctr | -| test.cpp:221:9:221:13 | ... ++ | -| test.cpp:221:9:221:14 | ExprStmt | -| test.cpp:223:5:225:5 | if (...) ... | -| test.cpp:223:9:223:9 | (double)... | -| test.cpp:223:9:223:9 | f | -| test.cpp:223:9:223:16 | ... == ... | -| test.cpp:223:14:223:16 | 0.0 | -| test.cpp:223:19:225:5 | { ... } | -| test.cpp:224:9:224:11 | ctr | -| test.cpp:224:9:224:13 | ... ++ | -| test.cpp:224:9:224:14 | ExprStmt | -| test.cpp:226:5:228:5 | if (...) ... | -| test.cpp:226:9:226:9 | d | -| test.cpp:226:9:226:14 | ... == ... | -| test.cpp:226:14:226:14 | 0 | -| test.cpp:226:14:226:14 | (double)... | -| test.cpp:226:17:228:5 | { ... } | -| test.cpp:227:9:227:11 | ctr | -| test.cpp:227:9:227:13 | ... ++ | -| test.cpp:227:9:227:14 | ExprStmt | -| test.cpp:229:5:231:5 | if (...) ... | -| test.cpp:229:9:229:9 | (int)... | -| test.cpp:229:9:229:9 | b | -| test.cpp:229:9:229:14 | ... == ... | -| test.cpp:229:14:229:14 | 0 | -| test.cpp:229:17:231:5 | { ... } | -| test.cpp:230:9:230:11 | ctr | -| test.cpp:230:9:230:13 | ... ++ | -| test.cpp:230:9:230:14 | ExprStmt | -| test.cpp:232:5:234:5 | if (...) ... | -| test.cpp:232:9:232:9 | (int)... | -| test.cpp:232:9:232:9 | b | -| test.cpp:232:9:232:18 | ... == ... | -| test.cpp:232:14:232:18 | 0 | -| test.cpp:232:14:232:18 | (int)... | -| test.cpp:232:21:234:5 | { ... } | -| test.cpp:233:9:233:11 | ctr | -| test.cpp:233:9:233:13 | ... ++ | -| test.cpp:233:9:233:14 | ExprStmt | -| test.cpp:235:5:237:5 | if (...) ... | -| test.cpp:235:9:235:10 | (reference dereference) | -| test.cpp:235:9:235:10 | ms | -| test.cpp:235:9:235:17 | ... == ... | -| test.cpp:235:12:235:12 | i | -| test.cpp:235:17:235:17 | 0 | -| test.cpp:235:20:237:5 | { ... } | -| test.cpp:236:9:236:11 | ctr | -| test.cpp:236:9:236:13 | ... ++ | -| test.cpp:236:9:236:14 | ExprStmt | -| test.cpp:238:5:240:5 | if (...) ... | -| test.cpp:238:9:238:10 | (reference dereference) | -| test.cpp:238:9:238:10 | ms | -| test.cpp:238:9:238:17 | ... == ... | -| test.cpp:238:12:238:12 | f | -| test.cpp:238:17:238:17 | 0 | -| test.cpp:238:17:238:17 | (float)... | -| test.cpp:238:20:240:5 | { ... } | -| test.cpp:239:9:239:11 | ctr | -| test.cpp:239:9:239:13 | ... ++ | -| test.cpp:239:9:239:14 | ExprStmt | -| test.cpp:241:5:243:5 | if (...) ... | -| test.cpp:241:9:241:10 | (reference dereference) | -| test.cpp:241:9:241:10 | ms | -| test.cpp:241:9:241:17 | ... == ... | -| test.cpp:241:9:241:30 | ... && ... | -| test.cpp:241:9:241:43 | ... && ... | -| test.cpp:241:12:241:12 | i | -| test.cpp:241:17:241:17 | 0 | -| test.cpp:241:22:241:23 | (reference dereference) | -| test.cpp:241:22:241:23 | ms | -| test.cpp:241:22:241:30 | ... == ... | -| test.cpp:241:25:241:25 | f | -| test.cpp:241:30:241:30 | 0 | -| test.cpp:241:30:241:30 | (float)... | -| test.cpp:241:35:241:36 | (reference dereference) | -| test.cpp:241:35:241:36 | ms | -| test.cpp:241:35:241:43 | ... == ... | -| test.cpp:241:38:241:38 | i | -| test.cpp:241:43:241:43 | 0 | -| test.cpp:241:46:243:5 | { ... } | -| test.cpp:242:9:242:11 | ctr | -| test.cpp:242:9:242:13 | ... ++ | -| test.cpp:242:9:242:14 | ExprStmt | -| test.cpp:244:1:244:1 | return ... | -| test.cpp:246:6:246:21 | definition of test_cmp_implies | -| test.cpp:246:6:246:21 | test_cmp_implies | -| test.cpp:246:27:246:27 | a | -| test.cpp:246:27:246:27 | definition of a | -| test.cpp:246:34:246:34 | b | -| test.cpp:246:34:246:34 | definition of b | -| test.cpp:246:37:284:1 | { ... } | -| test.cpp:247:3:251:3 | if (...) ... | -| test.cpp:247:6:247:13 | (...) | -| test.cpp:247:6:247:13 | (int)... | -| test.cpp:247:6:247:18 | ... == ... | -| test.cpp:247:7:247:7 | a | -| test.cpp:247:7:247:12 | ... == ... | -| test.cpp:247:12:247:12 | b | -| test.cpp:247:18:247:18 | 0 | -| test.cpp:247:21:249:3 | { ... } | -| test.cpp:249:10:251:3 | { ... } | -| test.cpp:253:3:257:3 | if (...) ... | -| test.cpp:253:6:253:13 | (...) | -| test.cpp:253:6:253:13 | (int)... | -| test.cpp:253:6:253:18 | ... != ... | -| test.cpp:253:7:253:7 | a | -| test.cpp:253:7:253:12 | ... == ... | -| test.cpp:253:12:253:12 | b | -| test.cpp:253:18:253:18 | 0 | -| test.cpp:253:21:255:3 | { ... } | -| test.cpp:255:10:257:3 | { ... } | -| test.cpp:260:3:264:3 | if (...) ... | -| test.cpp:260:6:260:13 | (...) | -| test.cpp:260:6:260:13 | (int)... | -| test.cpp:260:6:260:18 | ... == ... | -| test.cpp:260:7:260:7 | a | -| test.cpp:260:7:260:12 | ... != ... | -| test.cpp:260:12:260:12 | b | -| test.cpp:260:18:260:18 | 0 | -| test.cpp:260:21:262:3 | { ... } | -| test.cpp:262:10:264:3 | { ... } | -| test.cpp:266:3:270:3 | if (...) ... | -| test.cpp:266:6:266:13 | (...) | -| test.cpp:266:6:266:13 | (int)... | -| test.cpp:266:6:266:18 | ... != ... | -| test.cpp:266:7:266:7 | a | -| test.cpp:266:7:266:12 | ... != ... | -| test.cpp:266:12:266:12 | b | -| test.cpp:266:18:266:18 | 0 | -| test.cpp:266:21:268:3 | { ... } | -| test.cpp:268:10:270:3 | { ... } | -| test.cpp:273:3:277:3 | if (...) ... | -| test.cpp:273:6:273:12 | (...) | -| test.cpp:273:6:273:12 | (int)... | -| test.cpp:273:6:273:17 | ... == ... | -| test.cpp:273:7:273:7 | a | -| test.cpp:273:7:273:11 | ... < ... | -| test.cpp:273:11:273:11 | b | -| test.cpp:273:17:273:17 | 0 | -| test.cpp:273:20:275:3 | { ... } | -| test.cpp:275:10:277:3 | { ... } | -| test.cpp:279:3:283:3 | if (...) ... | -| test.cpp:279:6:279:12 | (...) | -| test.cpp:279:6:279:12 | (int)... | -| test.cpp:279:6:279:17 | ... != ... | -| test.cpp:279:7:279:7 | a | -| test.cpp:279:7:279:11 | ... < ... | -| test.cpp:279:11:279:11 | b | -| test.cpp:279:17:279:17 | 0 | -| test.cpp:279:20:281:3 | { ... } | -| test.cpp:281:10:283:3 | { ... } | -| test.cpp:284:1:284:1 | return ... | -| test.cpp:286:6:286:27 | definition of test_cmp_implies_unary | -| test.cpp:286:6:286:27 | test_cmp_implies_unary | -| test.cpp:286:33:286:33 | a | -| test.cpp:286:33:286:33 | definition of a | -| test.cpp:286:36:323:1 | { ... } | -| test.cpp:287:3:291:3 | if (...) ... | -| test.cpp:287:6:287:14 | (...) | -| test.cpp:287:6:287:14 | (int)... | -| test.cpp:287:6:287:19 | ... == ... | -| test.cpp:287:7:287:7 | a | -| test.cpp:287:7:287:13 | ... == ... | -| test.cpp:287:12:287:13 | 42 | -| test.cpp:287:19:287:19 | 0 | -| test.cpp:287:22:289:3 | { ... } | -| test.cpp:289:10:291:3 | { ... } | -| test.cpp:293:3:297:3 | if (...) ... | -| test.cpp:293:6:293:14 | (...) | -| test.cpp:293:6:293:14 | (int)... | -| test.cpp:293:6:293:19 | ... != ... | -| test.cpp:293:7:293:7 | a | -| test.cpp:293:7:293:13 | ... == ... | -| test.cpp:293:12:293:13 | 42 | -| test.cpp:293:19:293:19 | 0 | -| test.cpp:293:22:295:3 | { ... } | -| test.cpp:295:10:297:3 | { ... } | -| test.cpp:300:3:304:3 | if (...) ... | -| test.cpp:300:6:300:14 | (...) | -| test.cpp:300:6:300:14 | (int)... | -| test.cpp:300:6:300:19 | ... == ... | -| test.cpp:300:7:300:7 | a | -| test.cpp:300:7:300:13 | ... != ... | -| test.cpp:300:12:300:13 | 42 | -| test.cpp:300:19:300:19 | 0 | -| test.cpp:300:22:302:3 | { ... } | -| test.cpp:302:10:304:3 | { ... } | -| test.cpp:306:3:310:3 | if (...) ... | -| test.cpp:306:6:306:14 | (...) | -| test.cpp:306:6:306:14 | (int)... | -| test.cpp:306:6:306:19 | ... != ... | -| test.cpp:306:7:306:7 | a | -| test.cpp:306:7:306:13 | ... != ... | -| test.cpp:306:12:306:13 | 42 | -| test.cpp:306:19:306:19 | 0 | -| test.cpp:306:22:308:3 | { ... } | -| test.cpp:308:10:310:3 | { ... } | -| test.cpp:312:3:316:3 | if (...) ... | -| test.cpp:312:6:312:13 | (...) | -| test.cpp:312:6:312:13 | (int)... | -| test.cpp:312:6:312:18 | ... == ... | -| test.cpp:312:7:312:7 | a | -| test.cpp:312:7:312:12 | ... < ... | -| test.cpp:312:11:312:12 | 42 | -| test.cpp:312:18:312:18 | 0 | -| test.cpp:312:21:314:3 | { ... } | -| test.cpp:314:10:316:3 | { ... } | -| test.cpp:318:3:322:3 | if (...) ... | -| test.cpp:318:6:318:13 | (...) | -| test.cpp:318:6:318:13 | (int)... | -| test.cpp:318:6:318:18 | ... != ... | -| test.cpp:318:7:318:7 | a | -| test.cpp:318:7:318:12 | ... < ... | -| test.cpp:318:11:318:12 | 42 | -| test.cpp:318:18:318:18 | 0 | -| test.cpp:318:21:320:3 | { ... } | -| test.cpp:320:10:322:3 | { ... } | -| test.cpp:323:1:323:1 | return ... | diff --git a/cpp/ql/test/library-tests/controlflow/guards/Guards.ql b/cpp/ql/test/library-tests/controlflow/guards/Guards.ql deleted file mode 100644 index 6580c2acf589..000000000000 --- a/cpp/ql/test/library-tests/controlflow/guards/Guards.ql +++ /dev/null @@ -1,5 +0,0 @@ -import cpp -import semmle.code.cpp.controlflow.Guards - -from GuardCondition guard -select guard From 5e82eb9b246a58d9a18f5da298e4902f521a7cc5 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 16:45:50 +0100 Subject: [PATCH 15/35] C++: Fixup queries which assumes that a guard is always an expression. --- .../src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll | 2 +- cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql | 2 +- cpp/ql/src/Security/CWE/CWE-367/TOCTOUFilesystemRace.ql | 4 ++-- .../Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.ql | 2 +- .../analyzing-data-flow-in-cpp/index-flow-from-ntohl.ql | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll index 40c0f2173d90..f736a793a072 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll +++ b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll @@ -136,7 +136,7 @@ private module NetworkToBufferSizeConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { exists(GuardCondition gc, GVN gvn | - gc.getAChild*() = gvn.getAnExpr() and + gc.(Expr).getAChild*() = gvn.getAnExpr() and globalValueNumber(node.asExpr()) = gvn and gc.controls(node.asExpr().getBasicBlock(), _) ) diff --git a/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql b/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql index 379c20f51baf..9eccaebfdbd8 100644 --- a/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql +++ b/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql @@ -29,7 +29,7 @@ module VerifyResultConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.asExpr() instanceof SslGetVerifyResultCall } predicate isSink(DataFlow::Node sink) { - exists(GuardCondition guard | guard.getAChild*() = sink.asExpr()) + exists(GuardCondition guard | guard.(Expr).getAChild*() = sink.asExpr()) } predicate observeDiffInformedIncrementalMode() { any() } diff --git a/cpp/ql/src/Security/CWE/CWE-367/TOCTOUFilesystemRace.ql b/cpp/ql/src/Security/CWE/CWE-367/TOCTOUFilesystemRace.ql index 4b28a80f662e..5fd1b9819746 100644 --- a/cpp/ql/src/Security/CWE/CWE-367/TOCTOUFilesystemRace.ql +++ b/cpp/ql/src/Security/CWE/CWE-367/TOCTOUFilesystemRace.ql @@ -115,7 +115,7 @@ predicate checksPath(Expr check, Expr checkPath) { pragma[nomagic] predicate checkPathControlsUse(Expr check, Expr checkPath, Expr use) { - exists(GuardCondition guard | referenceTo(check, guard.getAChild*()) | + exists(GuardCondition guard | referenceTo(check, guard.(Expr).getAChild*()) | guard.controls(use.getBasicBlock(), _) ) and checksPath(pragma[only_bind_into](check), checkPath) @@ -123,7 +123,7 @@ predicate checkPathControlsUse(Expr check, Expr checkPath, Expr use) { pragma[nomagic] predicate fileNameOperationControlsUse(Expr check, Expr checkPath, Expr use) { - exists(GuardCondition guard | referenceTo(check, guard.getAChild*()) | + exists(GuardCondition guard | referenceTo(check, guard.(Expr).getAChild*()) | guard.controls(use.getBasicBlock(), _) ) and pragma[only_bind_into](check) = filenameOperation(checkPath) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.ql b/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.ql index 3132b103bbcc..df2fd13d79c9 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.ql @@ -51,7 +51,7 @@ class ReallocCallLeak extends FunctionCall { predicate mayHandleByTermination() { exists(GuardCondition guard, CallMayNotReturn exit | this.(ControlFlowNode).getASuccessor*() = guard and - guard.getAChild*() = v.getAnAccess() and + guard.(Expr).getAChild*() = v.getAnAccess() and guard.controls(exit.getBasicBlock(), _) ) } diff --git a/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/index-flow-from-ntohl.ql b/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/index-flow-from-ntohl.ql index 15cc379131ab..aaca52799d7a 100644 --- a/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/index-flow-from-ntohl.ql +++ b/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/index-flow-from-ntohl.ql @@ -22,7 +22,7 @@ module NetworkToBufferSizeConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { exists(GuardCondition gc, Variable v | - gc.getAChild*() = v.getAnAccess() and + gc.(Expr).getAChild*() = v.getAnAccess() and node.asExpr() = v.getAnAccess() and gc.controls(node.asExpr().getBasicBlock(), _) and not exists(Loop loop | loop.getControllingExpr() = gc) From d8f34dba17d925a58ef8df5f1679075141e597ac Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 17:30:39 +0100 Subject: [PATCH 16/35] C++: Do not use the deprecated predicate in queries. --- .../semmle/code/cpp/rangeanalysis/RangeAnalysis.qll | 2 +- .../new/internal/semantic/SemanticExprSpecific.qll | 2 +- .../src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll index e026c4dbe4b9..093d03ee0026 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll @@ -412,7 +412,7 @@ private predicate boundFlowStepPhi( or exists(IRGuardCondition guard, boolean testIsTrue | guard = boundFlowCond(valueNumberOfOperand(op2), op1, delta, upper, testIsTrue) and - guard.controlsEdge(op2.getPredecessorBlock(), op2.getUse().getBlock(), testIsTrue) and + guard.controlsBranchEdge(op2.getPredecessorBlock(), op2.getUse().getBlock(), testIsTrue) and reason = TCondReason(guard) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticExprSpecific.qll index 224f968ce693..242c023118f3 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticExprSpecific.qll @@ -259,7 +259,7 @@ module SemanticExprConfig { } predicate guardHasBranchEdge(Guard guard, BasicBlock bb1, BasicBlock bb2, boolean branch) { - guard.controlsEdge(bb1, bb2, branch) + guard.controlsBranchEdge(bb1, bb2, branch) } Guard comparisonGuard(Expr e) { getSemanticExpr(result) = e } diff --git a/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql b/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql index 17c1b09c3e68..36f4522b56c3 100644 --- a/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql +++ b/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql @@ -26,13 +26,13 @@ predicate isFlowSource(FS::FlowSource source, string sourceType) { predicate guardChecks(IRGuardCondition g, Expr e, boolean branch) { exists(Operand op | op.getDef().getConvertedResultExpression() = e | // `op < k` is true and `k > 0` - g.comparesLt(op, any(int k | k > 0), true, any(BooleanValue bv | bv.getValue() = branch)) + g.comparesLt(op, any(int k | k > 0), true, any(GuardValue bv | bv.asBooleanValue() = branch)) or // `op < _ + k` is true and `k > 0`. g.comparesLt(op, _, any(int k | k > 0), true, branch) or // op == k - g.comparesEq(op, _, true, any(BooleanValue bv | bv.getValue() = branch)) + g.comparesEq(op, _, true, any(GuardValue bv | bv.asBooleanValue() = branch)) or // op == _ + k g.comparesEq(op, _, _, true, branch) From e22d6656fe78f0dc5fe906970523918a40fe159d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 17 Sep 2025 15:59:02 +0100 Subject: [PATCH 17/35] C++: Fix barrier guards. --- .../code/cpp/ir/dataflow/internal/SsaImpl.qll | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll index 47e36a0a1079..285e0dc8419e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll @@ -1002,7 +1002,7 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI result instanceof FalseEdge } - class GuardValue = Boolean; + class GuardValue = IRGuards::GuardValue; class Guard instanceof IRGuards::IRGuardCondition { string toString() { result = super.toString() } @@ -1010,7 +1010,7 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI predicate hasValueBranchEdge(IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue branch) { exists(EdgeKind kind | super.getBlock() = bb1 and - kind = getConditionalEdge(branch) and + kind = getConditionalEdge(branch.asBooleanValue()) and bb1.getSuccessor(kind) = bb2 ) } @@ -1023,7 +1023,7 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI } predicate guardDirectlyControlsBlock(Guard guard, IRCfg::BasicBlock bb, GuardValue branch) { - guard.(IRGuards::IRGuardCondition).controls(bb, branch) + guard.(IRGuards::IRGuardCondition).valueControls(bb, branch) } predicate keepAllPhiInputBackEdges() { any() } @@ -1050,25 +1050,35 @@ module BarrierGuardWithIntParam { ) } - private predicate guardChecks( - DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, - DataFlowIntegrationInput::GuardValue branch, int indirectionIndex + private predicate guardChecksInstr( + IRGuards::Guards_v1::Guard g, IRGuards::GuardsInput::Expr instr, boolean branch, + int indirectionIndex ) { - exists(UseImpl use | - guardChecksNode(g, use.getNode(), branch, indirectionIndex) and - ssaDefReachesCertainUse(def, use) + exists(Node node | + nodeHasInstruction(node, instr, indirectionIndex) and + guardChecksNode(g, node, branch, indirectionIndex) ) } + private predicate guardChecksWithWrappers( + DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, IRGuards::GuardValue val, + int indirectionIndex + ) { + IRGuards::Guards_v1::ValidationWrapperWithState::guardChecksDef(g, def, + val, indirectionIndex) + } + Node getABarrierNode(int indirectionIndex) { // Only get the SynthNodes from the shared implementation, as the ExprNodes cannot // be matched on SourceVariable. result.(SsaSynthNode).getSynthNode() = - DataFlowIntegrationImpl::BarrierGuardDefWithState::getABarrierNode(indirectionIndex) + DataFlowIntegrationImpl::BarrierGuardDefWithState::getABarrierNode(indirectionIndex) or // Calculate the guarded UseImpls corresponding to ExprNodes directly. - exists(DataFlowIntegrationInput::Guard g, boolean branch, Definition def, IRBlock bb | - guardChecks(g, def, branch, indirectionIndex) and + exists( + DataFlowIntegrationInput::Guard g, IRGuards::GuardValue branch, Definition def, IRBlock bb + | + guardChecksWithWrappers(g, def, branch, indirectionIndex) and exists(UseImpl use | ssaDefReachesCertainUse(def, use) and use.getBlock() = bb and From a4dbee3b133c72d69d4cf05e09033ddcf4a49a41 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 18 Sep 2025 10:27:50 +0100 Subject: [PATCH 18/35] C++: Add change note. --- cpp/ql/lib/change-notes/2025-09-18-guards.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2025-09-18-guards.md diff --git a/cpp/ql/lib/change-notes/2025-09-18-guards.md b/cpp/ql/lib/change-notes/2025-09-18-guards.md new file mode 100644 index 000000000000..a739df714713 --- /dev/null +++ b/cpp/ql/lib/change-notes/2025-09-18-guards.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* The "Guards" libraries (`semmle.code.cpp.controlflow.Guards` and `semmle.code.cpp.controlflow.IRGuards`) have been totally rewritten to recognize many more guards. The API remains unchanged, but the `GuardCondition` class now extends `Element` instead of `Expr`. \ No newline at end of file From c481be8ea7d046ddf1db33d7a53e134d1b9047ea Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 18 Sep 2025 12:15:51 +0100 Subject: [PATCH 19/35] C++: Accept test changes for tests that select all types of an expression. --- .../test/library-tests/files/Files.expected | 8 +- .../functions/routinetype/types.expected | 2 +- .../preprocessor/preproc.expected | 202 ++++++++-------- .../library-tests/typedefs/Typedefs2.expected | 4 +- .../types/__wchar_t/wchar_t.expected | 6 +- .../cstd_types_fastestminimumwidth.expected | 16 +- .../cstd_types/cstd_types_fixedwidth.expected | 16 +- .../cstd_types_fixedwidthenum.expected | 4 +- .../cstd_types_maximumwidth.expected | 4 +- .../cstd_types_minimumwidth.expected | 16 +- .../types/integral_types_ms/vars.expected | 8 +- .../types/wchar_t_typedef/wchar_t.expected | 6 +- .../variables/variables/types.expected | 216 +++++++++--------- 13 files changed, 254 insertions(+), 254 deletions(-) diff --git a/cpp/ql/test/library-tests/files/Files.expected b/cpp/ql/test/library-tests/files/Files.expected index 13f3a6b2da17..f94c07badcfe 100644 --- a/cpp/ql/test/library-tests/files/Files.expected +++ b/cpp/ql/test/library-tests/files/Files.expected @@ -1,4 +1,4 @@ -| c.c | c.c | CFile, MetricFile | C | | | -| files1.cpp | files1.cpp | CppFile, MetricFile | C++ | swap | t | -| files1.h | files1.h | HeaderFile, MetricFile | | swap | | -| files2.cpp | files2.cpp | CppFile, MetricFile | C++ | g | x, y | +| c.c | c.c | CFile, GuardConditionImpl, MetricFile | C | | | +| files1.cpp | files1.cpp | CppFile, GuardConditionImpl, MetricFile | C++ | swap | t | +| files1.h | files1.h | GuardConditionImpl, HeaderFile, MetricFile | | swap | | +| files2.cpp | files2.cpp | CppFile, GuardConditionImpl, MetricFile | C++ | g | x, y | diff --git a/cpp/ql/test/library-tests/functions/routinetype/types.expected b/cpp/ql/test/library-tests/functions/routinetype/types.expected index d620bea517e8..87d51330d764 100644 --- a/cpp/ql/test/library-tests/functions/routinetype/types.expected +++ b/cpp/ql/test/library-tests/functions/routinetype/types.expected @@ -1 +1 @@ -| routinetype.cpp:2:7:2:19 | myRoutineType | file://:0:0:0:0 | ..()(..) | RoutineType | +| routinetype.cpp:2:7:2:19 | myRoutineType | file://:0:0:0:0 | ..()(..) | GuardConditionImpl, RoutineType | diff --git a/cpp/ql/test/library-tests/preprocessor/preprocessor/preproc.expected b/cpp/ql/test/library-tests/preprocessor/preprocessor/preproc.expected index 7c448ba6550e..e9198ba5ea04 100644 --- a/cpp/ql/test/library-tests/preprocessor/preprocessor/preproc.expected +++ b/cpp/ql/test/library-tests/preprocessor/preprocessor/preproc.expected @@ -1,101 +1,101 @@ -| a.h:0:0:0:0 | a.h | 1 | 1 | 1 | 19 | IncludeNext | "a.h" | N/A | -| pp23.cpp:0:0:0:0 | pp23.cpp | 3 | 1 | 3 | 11 | Macro | BAR | | -| pp23.cpp:0:0:0:0 | pp23.cpp | 5 | 1 | 5 | 10 | PreprocessorIfdef | FOO | N/A | -| pp23.cpp:0:0:0:0 | pp23.cpp | 7 | 1 | 7 | 12 | PreprocessorElifdef | BAR | N/A | -| pp23.cpp:0:0:0:0 | pp23.cpp | 8 | 1 | 8 | 16 | PreprocessorWarning | C++23 2 | N/A | -| pp23.cpp:0:0:0:0 | pp23.cpp | 9 | 1 | 9 | 6 | PreprocessorEndif | N/A | N/A | -| pp23.cpp:0:0:0:0 | pp23.cpp | 11 | 1 | 11 | 10 | PreprocessorIfdef | FOO | N/A | -| pp23.cpp:0:0:0:0 | pp23.cpp | 13 | 1 | 13 | 13 | PreprocessorElifndef | FOO | N/A | -| pp23.cpp:0:0:0:0 | pp23.cpp | 14 | 1 | 14 | 16 | PreprocessorWarning | C++23 3 | N/A | -| pp23.cpp:0:0:0:0 | pp23.cpp | 15 | 1 | 15 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 1 | 1 | 1 | 16 | PreprocessorIf | defined(FOO) | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 3 | 1 | 3 | 19 | PreprocessorElif | !defined(BAR) | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 4 | 1 | 4 | 11 | Macro | BAR | | -| pp.cpp:0:0:0:0 | pp.cpp | 5 | 1 | 5 | 17 | Macro | BAR_val | 1 | -| pp.cpp:0:0:0:0 | pp.cpp | 6 | 1 | 6 | 24 | Macro | BAR_fn() | BAR_val | -| pp.cpp:0:0:0:0 | pp.cpp | 7 | 1 | 7 | 5 | PreprocessorElse | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 9 | 1 | 9 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 11 | 1 | 11 | 10 | PreprocessorUndef | BAR | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 12 | 1 | 12 | 68 | Macro | SCARY(a,aa,aaah) | (aa ) | -| pp.cpp:0:0:0:0 | pp.cpp | 13 | 1 | 13 | 63 | Macro | LOG(fmt,__VA_ARGS__...) | printf("Warning: %s", fmt, __VA__ARGS__) | -| pp.cpp:0:0:0:0 | pp.cpp | 14 | 1 | 14 | 15 | Include | "pp.h" | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 16 | 1 | 16 | 5 | PreprocessorIf | 0 | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 17 | 1 | 17 | 5 | PreprocessorElse | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 18 | 1 | 18 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 20 | 1 | 20 | 5 | PreprocessorIf | 1 | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 21 | 1 | 21 | 5 | PreprocessorElse | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 22 | 1 | 22 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 24 | 1 | 24 | 13 | Import | "a.h" | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 30 | 2 | 30 | 32 | Macro | MACRO_FUNCTIONCONTEXT | 1 | -| pp.cpp:0:0:0:0 | pp.cpp | 36 | 2 | 36 | 29 | Macro | MACRO_CLASSCONTEXT | 2 | -| pp.cpp:0:0:0:0 | pp.cpp | 42 | 2 | 42 | 40 | Macro | MACRO_TEMPLATEFUNCTIONCONTEXT | 3 | -| pp.cpp:0:0:0:0 | pp.cpp | 49 | 2 | 49 | 37 | Macro | MACRO_TEMPLATECLASSCONTEXT | 4 | -| pp.cpp:0:0:0:0 | pp.cpp | 50 | 2 | 50 | 48 | Macro | MACRO_TEMPLATECLASSCONTEXT_REFERENCED | 5 | -| pp.cpp:0:0:0:0 | pp.cpp | 54 | 3 | 54 | 39 | Macro | MACRO_TEMPLATEMETHODCONTEXT | 6 | -| pp.cpp:0:0:0:0 | pp.cpp | 57 | 1 | 57 | 21 | PreprocessorIfdef | INSTANTIATION | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 59 | 1 | 59 | 6 | PreprocessorElse | | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 60 | 3 | 60 | 21 | Macro | IN_TEMPLATE | | -| pp.cpp:0:0:0:0 | pp.cpp | 61 | 1 | 61 | 7 | PreprocessorEndif | | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 69 | 1 | 69 | 21 | Macro | INSTANTIATION | | -| pp.cpp:0:0:0:0 | pp.cpp | 72 | 1 | 72 | 11 | Macro | BAR | | -| pp.cpp:0:0:0:0 | pp.cpp | 74 | 1 | 75 | 14 | PreprocessorIf | defined(BAR) && defined(BAR) | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 76 | 1 | 76 | 20 | PreprocessorWarning | BAR defined | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 77 | 1 | 77 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 79 | 1 | 80 | 26 | PreprocessorIf | defined MACROTHREE && (defined(MACROONE)) | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 81 | 1 | 81 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 83 | 1 | 83 | 26 | PreprocessorIf | defined SIMPLE_COMMENT | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 85 | 1 | 85 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 87 | 1 | 88 | 16 | PreprocessorIf | defined(FOO) && defined(BAR) | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 90 | 1 | 90 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 92 | 1 | 94 | 17 | PreprocessorIf | defined(FOO) && defined(BAR) && !defined(BAZ) | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 96 | 1 | 96 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 98 | 1 | 98 | 13 | Macro | FOO | 8 | -| pp.cpp:0:0:0:0 | pp.cpp | 99 | 1 | 99 | 13 | Macro | BAR | 2 | -| pp.cpp:0:0:0:0 | pp.cpp | 100 | 1 | 100 | 13 | Macro | BAZ | 4 | -| pp.cpp:0:0:0:0 | pp.cpp | 101 | 1 | 104 | 8 | PreprocessorIf | ((FOO / BAR) == 4) && ((BAZ * QUX) > 10) | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 106 | 1 | 106 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 109 | 1 | 111 | 13 | PreprocessorIf | defined(FOO) && defined(BAR) && defined(BAZ) | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 112 | 1 | 112 | 29 | Macro | CONDITIONAL_MACRO_4 | 4 | -| pp.cpp:0:0:0:0 | pp.cpp | 113 | 1 | 113 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 116 | 1 | 116 | 39 | PreprocessorIf | defined SIMPLE_COMMENT | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 118 | 1 | 118 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 120 | 1 | 120 | 12 | PreprocessorWarning | foo | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 122 | 1 | 122 | 12 | PreprocessorWarning | foo | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 126 | 1 | 126 | 12 | PreprocessorWarning | foo | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 129 | 1 | 129 | 12 | PreprocessorWarning | foo | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 134 | 1 | 134 | 13 | Macro | FOO | 8 | -| pp.cpp:0:0:0:0 | pp.cpp | 135 | 1 | 135 | 13 | Macro | BAR | 2 | -| pp.cpp:0:0:0:0 | pp.cpp | 136 | 1 | 136 | 13 | Macro | BAZ | 4 | -| pp.cpp:0:0:0:0 | pp.cpp | 137 | 1 | 142 | 8 | PreprocessorIf | ((FOO / BAR) == 4) && ((BAZ * QUX) > 10) | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 144 | 1 | 144 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 146 | 1 | 146 | 11 | Macro | X | 1 | -| pp.cpp:0:0:0:0 | pp.cpp | 147 | 1 | 147 | 11 | Macro | Y | 2 | -| pp.cpp:0:0:0:0 | pp.cpp | 148 | 1 | 149 | 36 | PreprocessorIf | defined(X) && defined(Y) | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 151 | 1 | 151 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 153 | 1 | 157 | 3 | PreprocessorWarning | FOO BAR | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 160 | 1 | 160 | 12 | PreprocessorWarning | foo | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 166 | 1 | 166 | 22 | PreprocessorIf | A &&B | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 167 | 1 | 167 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 170 | 1 | 170 | 20 | PreprocessorIf | A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 171 | 1 | 171 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 173 | 1 | 175 | 6 | PreprocessorIf | A && B | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 176 | 1 | 176 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 179 | 1 | 183 | 9 | PreprocessorIfdef | FOOBAR | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 185 | 1 | 185 | 5 | PreprocessorElse | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 186 | 1 | 186 | 10 | PreprocessorWarning | b | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 187 | 1 | 187 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 190 | 1 | 194 | 9 | PreprocessorIf | FOOBAR | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 195 | 1 | 195 | 6 | PreprocessorEndif | N/A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 197 | 1 | 197 | 18 | PreprocessorIf | A | N/A | -| pp.cpp:0:0:0:0 | pp.cpp | 198 | 1 | 198 | 6 | PreprocessorEndif | N/A | N/A | -| pp.h:0:0:0:0 | pp.h | 1 | 1 | 1 | 12 | PreprocessorPragma | once | N/A | -| pp.h:0:0:0:0 | pp.h | 2 | 1 | 2 | 29 | PreprocessorWarning | "This should happen" | N/A | -| pp.h:0:0:0:0 | pp.h | 3 | 1 | 3 | 27 | PreprocessorLine | 33 "emerald_city.h" | N/A | -| pp.h:0:0:0:0 | pp.h | 4 | 1 | 4 | 30 | PreprocessorPragma | byte_order(big_endian) | N/A | -| pp.h:0:0:0:0 | pp.h | 5 | 1 | 5 | 33 | PreprocessorWarning | "Not in Kansas any more" | N/A | -| pp.h:0:0:0:0 | pp.h | 7 | 1 | 11 | 8 | Macro | MULTILINE | world a long | -| pp.h:0:0:0:0 | pp.h | 13 | 1 | 14 | 11 | PreprocessorUndef | MULTILINE | N/A | -| pp.h:0:0:0:0 | pp.h | 16 | 1 | 17 | 8 | Include | "pp.h" | N/A | -| ppms.cpp:0:0:0:0 | ppms.cpp | 3 | 1 | 3 | 18 | TypeLibraryImport | "test.tlb" | N/A | -| test.tlh:0:0:0:0 | test.tlh | 1 | 1 | 1 | 12 | PreprocessorPragma | once | N/A | -| test.tlh:0:0:0:0 | test.tlh | 3 | 1 | 3 | 21 | PreprocessorWarning | type library | N/A | +| a.h:0:0:0:0 | a.h | 1 | 1 | 1 | 19 | GuardConditionImpl, IncludeNext | "a.h" | N/A | +| pp23.cpp:0:0:0:0 | pp23.cpp | 3 | 1 | 3 | 11 | GuardConditionImpl, Macro | BAR | | +| pp23.cpp:0:0:0:0 | pp23.cpp | 5 | 1 | 5 | 10 | GuardConditionImpl, PreprocessorIfdef | FOO | N/A | +| pp23.cpp:0:0:0:0 | pp23.cpp | 7 | 1 | 7 | 12 | GuardConditionImpl, PreprocessorElifdef | BAR | N/A | +| pp23.cpp:0:0:0:0 | pp23.cpp | 8 | 1 | 8 | 16 | GuardConditionImpl, PreprocessorWarning | C++23 2 | N/A | +| pp23.cpp:0:0:0:0 | pp23.cpp | 9 | 1 | 9 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp23.cpp:0:0:0:0 | pp23.cpp | 11 | 1 | 11 | 10 | GuardConditionImpl, PreprocessorIfdef | FOO | N/A | +| pp23.cpp:0:0:0:0 | pp23.cpp | 13 | 1 | 13 | 13 | GuardConditionImpl, PreprocessorElifndef | FOO | N/A | +| pp23.cpp:0:0:0:0 | pp23.cpp | 14 | 1 | 14 | 16 | GuardConditionImpl, PreprocessorWarning | C++23 3 | N/A | +| pp23.cpp:0:0:0:0 | pp23.cpp | 15 | 1 | 15 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 1 | 1 | 1 | 16 | GuardConditionImpl, PreprocessorIf | defined(FOO) | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 3 | 1 | 3 | 19 | GuardConditionImpl, PreprocessorElif | !defined(BAR) | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 4 | 1 | 4 | 11 | GuardConditionImpl, Macro | BAR | | +| pp.cpp:0:0:0:0 | pp.cpp | 5 | 1 | 5 | 17 | GuardConditionImpl, Macro | BAR_val | 1 | +| pp.cpp:0:0:0:0 | pp.cpp | 6 | 1 | 6 | 24 | GuardConditionImpl, Macro | BAR_fn() | BAR_val | +| pp.cpp:0:0:0:0 | pp.cpp | 7 | 1 | 7 | 5 | GuardConditionImpl, PreprocessorElse | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 9 | 1 | 9 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 11 | 1 | 11 | 10 | GuardConditionImpl, PreprocessorUndef | BAR | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 12 | 1 | 12 | 68 | GuardConditionImpl, Macro | SCARY(a,aa,aaah) | (aa ) | +| pp.cpp:0:0:0:0 | pp.cpp | 13 | 1 | 13 | 63 | GuardConditionImpl, Macro | LOG(fmt,__VA_ARGS__...) | printf("Warning: %s", fmt, __VA__ARGS__) | +| pp.cpp:0:0:0:0 | pp.cpp | 14 | 1 | 14 | 15 | GuardConditionImpl, Include | "pp.h" | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 16 | 1 | 16 | 5 | GuardConditionImpl, PreprocessorIf | 0 | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 17 | 1 | 17 | 5 | GuardConditionImpl, PreprocessorElse | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 18 | 1 | 18 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 20 | 1 | 20 | 5 | GuardConditionImpl, PreprocessorIf | 1 | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 21 | 1 | 21 | 5 | GuardConditionImpl, PreprocessorElse | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 22 | 1 | 22 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 24 | 1 | 24 | 13 | GuardConditionImpl, Import | "a.h" | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 30 | 2 | 30 | 32 | GuardConditionImpl, Macro | MACRO_FUNCTIONCONTEXT | 1 | +| pp.cpp:0:0:0:0 | pp.cpp | 36 | 2 | 36 | 29 | GuardConditionImpl, Macro | MACRO_CLASSCONTEXT | 2 | +| pp.cpp:0:0:0:0 | pp.cpp | 42 | 2 | 42 | 40 | GuardConditionImpl, Macro | MACRO_TEMPLATEFUNCTIONCONTEXT | 3 | +| pp.cpp:0:0:0:0 | pp.cpp | 49 | 2 | 49 | 37 | GuardConditionImpl, Macro | MACRO_TEMPLATECLASSCONTEXT | 4 | +| pp.cpp:0:0:0:0 | pp.cpp | 50 | 2 | 50 | 48 | GuardConditionImpl, Macro | MACRO_TEMPLATECLASSCONTEXT_REFERENCED | 5 | +| pp.cpp:0:0:0:0 | pp.cpp | 54 | 3 | 54 | 39 | GuardConditionImpl, Macro | MACRO_TEMPLATEMETHODCONTEXT | 6 | +| pp.cpp:0:0:0:0 | pp.cpp | 57 | 1 | 57 | 21 | GuardConditionImpl, PreprocessorIfdef | INSTANTIATION | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 59 | 1 | 59 | 6 | GuardConditionImpl, PreprocessorElse | | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 60 | 3 | 60 | 21 | GuardConditionImpl, Macro | IN_TEMPLATE | | +| pp.cpp:0:0:0:0 | pp.cpp | 61 | 1 | 61 | 7 | GuardConditionImpl, PreprocessorEndif | | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 69 | 1 | 69 | 21 | GuardConditionImpl, Macro | INSTANTIATION | | +| pp.cpp:0:0:0:0 | pp.cpp | 72 | 1 | 72 | 11 | GuardConditionImpl, Macro | BAR | | +| pp.cpp:0:0:0:0 | pp.cpp | 74 | 1 | 75 | 14 | GuardConditionImpl, PreprocessorIf | defined(BAR) && defined(BAR) | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 76 | 1 | 76 | 20 | GuardConditionImpl, PreprocessorWarning | BAR defined | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 77 | 1 | 77 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 79 | 1 | 80 | 26 | GuardConditionImpl, PreprocessorIf | defined MACROTHREE && (defined(MACROONE)) | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 81 | 1 | 81 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 83 | 1 | 83 | 26 | GuardConditionImpl, PreprocessorIf | defined SIMPLE_COMMENT | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 85 | 1 | 85 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 87 | 1 | 88 | 16 | GuardConditionImpl, PreprocessorIf | defined(FOO) && defined(BAR) | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 90 | 1 | 90 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 92 | 1 | 94 | 17 | GuardConditionImpl, PreprocessorIf | defined(FOO) && defined(BAR) && !defined(BAZ) | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 96 | 1 | 96 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 98 | 1 | 98 | 13 | GuardConditionImpl, Macro | FOO | 8 | +| pp.cpp:0:0:0:0 | pp.cpp | 99 | 1 | 99 | 13 | GuardConditionImpl, Macro | BAR | 2 | +| pp.cpp:0:0:0:0 | pp.cpp | 100 | 1 | 100 | 13 | GuardConditionImpl, Macro | BAZ | 4 | +| pp.cpp:0:0:0:0 | pp.cpp | 101 | 1 | 104 | 8 | GuardConditionImpl, PreprocessorIf | ((FOO / BAR) == 4) && ((BAZ * QUX) > 10) | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 106 | 1 | 106 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 109 | 1 | 111 | 13 | GuardConditionImpl, PreprocessorIf | defined(FOO) && defined(BAR) && defined(BAZ) | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 112 | 1 | 112 | 29 | GuardConditionImpl, Macro | CONDITIONAL_MACRO_4 | 4 | +| pp.cpp:0:0:0:0 | pp.cpp | 113 | 1 | 113 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 116 | 1 | 116 | 39 | GuardConditionImpl, PreprocessorIf | defined SIMPLE_COMMENT | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 118 | 1 | 118 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 120 | 1 | 120 | 12 | GuardConditionImpl, PreprocessorWarning | foo | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 122 | 1 | 122 | 12 | GuardConditionImpl, PreprocessorWarning | foo | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 126 | 1 | 126 | 12 | GuardConditionImpl, PreprocessorWarning | foo | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 129 | 1 | 129 | 12 | GuardConditionImpl, PreprocessorWarning | foo | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 134 | 1 | 134 | 13 | GuardConditionImpl, Macro | FOO | 8 | +| pp.cpp:0:0:0:0 | pp.cpp | 135 | 1 | 135 | 13 | GuardConditionImpl, Macro | BAR | 2 | +| pp.cpp:0:0:0:0 | pp.cpp | 136 | 1 | 136 | 13 | GuardConditionImpl, Macro | BAZ | 4 | +| pp.cpp:0:0:0:0 | pp.cpp | 137 | 1 | 142 | 8 | GuardConditionImpl, PreprocessorIf | ((FOO / BAR) == 4) && ((BAZ * QUX) > 10) | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 144 | 1 | 144 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 146 | 1 | 146 | 11 | GuardConditionImpl, Macro | X | 1 | +| pp.cpp:0:0:0:0 | pp.cpp | 147 | 1 | 147 | 11 | GuardConditionImpl, Macro | Y | 2 | +| pp.cpp:0:0:0:0 | pp.cpp | 148 | 1 | 149 | 36 | GuardConditionImpl, PreprocessorIf | defined(X) && defined(Y) | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 151 | 1 | 151 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 153 | 1 | 157 | 3 | GuardConditionImpl, PreprocessorWarning | FOO BAR | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 160 | 1 | 160 | 12 | GuardConditionImpl, PreprocessorWarning | foo | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 166 | 1 | 166 | 22 | GuardConditionImpl, PreprocessorIf | A &&B | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 167 | 1 | 167 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 170 | 1 | 170 | 20 | GuardConditionImpl, PreprocessorIf | A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 171 | 1 | 171 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 173 | 1 | 175 | 6 | GuardConditionImpl, PreprocessorIf | A && B | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 176 | 1 | 176 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 179 | 1 | 183 | 9 | GuardConditionImpl, PreprocessorIfdef | FOOBAR | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 185 | 1 | 185 | 5 | GuardConditionImpl, PreprocessorElse | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 186 | 1 | 186 | 10 | GuardConditionImpl, PreprocessorWarning | b | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 187 | 1 | 187 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 190 | 1 | 194 | 9 | GuardConditionImpl, PreprocessorIf | FOOBAR | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 195 | 1 | 195 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 197 | 1 | 197 | 18 | GuardConditionImpl, PreprocessorIf | A | N/A | +| pp.cpp:0:0:0:0 | pp.cpp | 198 | 1 | 198 | 6 | GuardConditionImpl, PreprocessorEndif | N/A | N/A | +| pp.h:0:0:0:0 | pp.h | 1 | 1 | 1 | 12 | GuardConditionImpl, PreprocessorPragma | once | N/A | +| pp.h:0:0:0:0 | pp.h | 2 | 1 | 2 | 29 | GuardConditionImpl, PreprocessorWarning | "This should happen" | N/A | +| pp.h:0:0:0:0 | pp.h | 3 | 1 | 3 | 27 | GuardConditionImpl, PreprocessorLine | 33 "emerald_city.h" | N/A | +| pp.h:0:0:0:0 | pp.h | 4 | 1 | 4 | 30 | GuardConditionImpl, PreprocessorPragma | byte_order(big_endian) | N/A | +| pp.h:0:0:0:0 | pp.h | 5 | 1 | 5 | 33 | GuardConditionImpl, PreprocessorWarning | "Not in Kansas any more" | N/A | +| pp.h:0:0:0:0 | pp.h | 7 | 1 | 11 | 8 | GuardConditionImpl, Macro | MULTILINE | world a long | +| pp.h:0:0:0:0 | pp.h | 13 | 1 | 14 | 11 | GuardConditionImpl, PreprocessorUndef | MULTILINE | N/A | +| pp.h:0:0:0:0 | pp.h | 16 | 1 | 17 | 8 | GuardConditionImpl, Include | "pp.h" | N/A | +| ppms.cpp:0:0:0:0 | ppms.cpp | 3 | 1 | 3 | 18 | GuardConditionImpl, TypeLibraryImport | "test.tlb" | N/A | +| test.tlh:0:0:0:0 | test.tlh | 1 | 1 | 1 | 12 | GuardConditionImpl, PreprocessorPragma | once | N/A | +| test.tlh:0:0:0:0 | test.tlh | 3 | 1 | 3 | 21 | GuardConditionImpl, PreprocessorWarning | type library | N/A | diff --git a/cpp/ql/test/library-tests/typedefs/Typedefs2.expected b/cpp/ql/test/library-tests/typedefs/Typedefs2.expected index 8645ce97fcd8..d83c74bb55e6 100644 --- a/cpp/ql/test/library-tests/typedefs/Typedefs2.expected +++ b/cpp/ql/test/library-tests/typedefs/Typedefs2.expected @@ -1,2 +1,2 @@ -| typedefs.cpp:6:6:6:7 | f1 | typedefs.cpp:8:15:8:18 | TYPE | CTypedefType, LocalTypedefType | -| typedefs.cpp:6:6:6:7 | f1 | typedefs.cpp:9:9:9:9 | D | DirectAccessHolder, LocalClass, MetricClass, StructLikeClass | +| typedefs.cpp:6:6:6:7 | f1 | typedefs.cpp:8:15:8:18 | TYPE | CTypedefType, GuardConditionImpl, LocalTypedefType | +| typedefs.cpp:6:6:6:7 | f1 | typedefs.cpp:9:9:9:9 | D | DirectAccessHolder, GuardConditionImpl, LocalClass, MetricClass, StructLikeClass | diff --git a/cpp/ql/test/library-tests/types/__wchar_t/wchar_t.expected b/cpp/ql/test/library-tests/types/__wchar_t/wchar_t.expected index d4c429faf170..d7faa82d924d 100644 --- a/cpp/ql/test/library-tests/types/__wchar_t/wchar_t.expected +++ b/cpp/ql/test/library-tests/types/__wchar_t/wchar_t.expected @@ -1,3 +1,3 @@ -| file://:0:0:0:0 | __wchar_t * | IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, PointerType | Wchar_t, WideCharType | -| file://:0:0:0:0 | const __wchar_t | SpecifiedType | Wchar_t, WideCharType | -| file://:0:0:0:0 | wchar_t | Wchar_t, WideCharType | | +| file://:0:0:0:0 | __wchar_t * | GuardConditionImpl, IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, PointerType | GuardConditionImpl, Wchar_t, WideCharType | +| file://:0:0:0:0 | const __wchar_t | GuardConditionImpl, SpecifiedType | GuardConditionImpl, Wchar_t, WideCharType | +| file://:0:0:0:0 | wchar_t | GuardConditionImpl, Wchar_t, WideCharType | | diff --git a/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fastestminimumwidth.expected b/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fastestminimumwidth.expected index 13fe25a48191..5eb5868fd8b5 100644 --- a/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fastestminimumwidth.expected +++ b/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fastestminimumwidth.expected @@ -1,8 +1,8 @@ -| cstd_types.cpp:47:13:47:15 | if8 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast8_t | -| cstd_types.cpp:48:14:48:17 | if16 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast16_t | -| cstd_types.cpp:49:14:49:17 | if32 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast32_t | -| cstd_types.cpp:50:14:50:17 | if64 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast64_t | -| cstd_types.cpp:51:14:51:16 | uf8 | CTypedefType, FastestMinimumWidthIntegralType, UInt_fast8_t | -| cstd_types.cpp:52:15:52:18 | uf16 | CTypedefType, FastestMinimumWidthIntegralType, UInt_fast16_t | -| cstd_types.cpp:53:15:53:18 | uf32 | CTypedefType, FastestMinimumWidthIntegralType, UInt_fast32_t | -| cstd_types.cpp:54:15:54:18 | uf64 | CTypedefType, FastestMinimumWidthIntegralType, UInt_fast64_t | \ No newline at end of file +| cstd_types.cpp:47:13:47:15 | if8 | CTypedefType, FastestMinimumWidthIntegralType, GuardConditionImpl, Int_fast8_t | +| cstd_types.cpp:48:14:48:17 | if16 | CTypedefType, FastestMinimumWidthIntegralType, GuardConditionImpl, Int_fast16_t | +| cstd_types.cpp:49:14:49:17 | if32 | CTypedefType, FastestMinimumWidthIntegralType, GuardConditionImpl, Int_fast32_t | +| cstd_types.cpp:50:14:50:17 | if64 | CTypedefType, FastestMinimumWidthIntegralType, GuardConditionImpl, Int_fast64_t | +| cstd_types.cpp:51:14:51:16 | uf8 | CTypedefType, FastestMinimumWidthIntegralType, GuardConditionImpl, UInt_fast8_t | +| cstd_types.cpp:52:15:52:18 | uf16 | CTypedefType, FastestMinimumWidthIntegralType, GuardConditionImpl, UInt_fast16_t | +| cstd_types.cpp:53:15:53:18 | uf32 | CTypedefType, FastestMinimumWidthIntegralType, GuardConditionImpl, UInt_fast32_t | +| cstd_types.cpp:54:15:54:18 | uf64 | CTypedefType, FastestMinimumWidthIntegralType, GuardConditionImpl, UInt_fast64_t | diff --git a/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fixedwidth.expected b/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fixedwidth.expected index d1c643436369..efa8890d8200 100644 --- a/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fixedwidth.expected +++ b/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fixedwidth.expected @@ -1,8 +1,8 @@ -| cstd_types.cpp:31:8:31:9 | i8 | CTypedefType, FixedWidthIntegralType, Int8_t | -| cstd_types.cpp:32:9:32:11 | i16 | CTypedefType, FixedWidthIntegralType, Int16_t | -| cstd_types.cpp:33:9:33:11 | i32 | CTypedefType, FixedWidthIntegralType, Int32_t | -| cstd_types.cpp:34:9:34:11 | i64 | CTypedefType, FixedWidthIntegralType, Int64_t | -| cstd_types.cpp:35:9:35:11 | ui8 | CTypedefType, FixedWidthIntegralType, UInt8_t | -| cstd_types.cpp:36:10:36:13 | ui16 | CTypedefType, FixedWidthIntegralType, UInt16_t | -| cstd_types.cpp:37:10:37:13 | ui32 | CTypedefType, FixedWidthIntegralType, UInt32_t | -| cstd_types.cpp:38:10:38:13 | ui64 | CTypedefType, FixedWidthIntegralType, UInt64_t | +| cstd_types.cpp:31:8:31:9 | i8 | CTypedefType, FixedWidthIntegralType, GuardConditionImpl, Int8_t | +| cstd_types.cpp:32:9:32:11 | i16 | CTypedefType, FixedWidthIntegralType, GuardConditionImpl, Int16_t | +| cstd_types.cpp:33:9:33:11 | i32 | CTypedefType, FixedWidthIntegralType, GuardConditionImpl, Int32_t | +| cstd_types.cpp:34:9:34:11 | i64 | CTypedefType, FixedWidthIntegralType, GuardConditionImpl, Int64_t | +| cstd_types.cpp:35:9:35:11 | ui8 | CTypedefType, FixedWidthIntegralType, GuardConditionImpl, UInt8_t | +| cstd_types.cpp:36:10:36:13 | ui16 | CTypedefType, FixedWidthIntegralType, GuardConditionImpl, UInt16_t | +| cstd_types.cpp:37:10:37:13 | ui32 | CTypedefType, FixedWidthIntegralType, GuardConditionImpl, UInt32_t | +| cstd_types.cpp:38:10:38:13 | ui64 | CTypedefType, FixedWidthIntegralType, GuardConditionImpl, UInt64_t | diff --git a/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fixedwidthenum.expected b/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fixedwidthenum.expected index d9884b22b00b..89428e7a6ec5 100644 --- a/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fixedwidthenum.expected +++ b/cpp/ql/test/library-tests/types/cstd_types/cstd_types_fixedwidthenum.expected @@ -1,2 +1,2 @@ -| cstd_types.cpp:74:4:74:6 | _e0 | Enum, FixedWidthEnumType | -| cstd_types.cpp:75:4:75:6 | _e1 | FixedWidthEnumType, ScopedEnum | +| cstd_types.cpp:74:4:74:6 | _e0 | Enum, FixedWidthEnumType, GuardConditionImpl | +| cstd_types.cpp:75:4:75:6 | _e1 | FixedWidthEnumType, GuardConditionImpl, ScopedEnum | diff --git a/cpp/ql/test/library-tests/types/cstd_types/cstd_types_maximumwidth.expected b/cpp/ql/test/library-tests/types/cstd_types/cstd_types_maximumwidth.expected index 0bf7779fcafd..b57ca4fb9362 100644 --- a/cpp/ql/test/library-tests/types/cstd_types/cstd_types_maximumwidth.expected +++ b/cpp/ql/test/library-tests/types/cstd_types/cstd_types_maximumwidth.expected @@ -1,2 +1,2 @@ -| cstd_types.cpp:55:10:55:11 | im | CTypedefType, Intmax_t, MaximumWidthIntegralType | -| cstd_types.cpp:56:11:56:13 | uim | CTypedefType, MaximumWidthIntegralType, Uintmax_t | +| cstd_types.cpp:55:10:55:11 | im | CTypedefType, GuardConditionImpl, Intmax_t, MaximumWidthIntegralType | +| cstd_types.cpp:56:11:56:13 | uim | CTypedefType, GuardConditionImpl, MaximumWidthIntegralType, Uintmax_t | diff --git a/cpp/ql/test/library-tests/types/cstd_types/cstd_types_minimumwidth.expected b/cpp/ql/test/library-tests/types/cstd_types/cstd_types_minimumwidth.expected index 2984f07be8c8..6aea59474733 100644 --- a/cpp/ql/test/library-tests/types/cstd_types/cstd_types_minimumwidth.expected +++ b/cpp/ql/test/library-tests/types/cstd_types/cstd_types_minimumwidth.expected @@ -1,8 +1,8 @@ -| cstd_types.cpp:39:15:39:16 | l8 | CTypedefType, Int_least8_t, MinimumWidthIntegralType | -| cstd_types.cpp:40:15:40:17 | l16 | CTypedefType, Int_least16_t, MinimumWidthIntegralType | -| cstd_types.cpp:41:15:41:17 | l32 | CTypedefType, Int_least32_t, MinimumWidthIntegralType | -| cstd_types.cpp:42:15:42:17 | l64 | CTypedefType, Int_least64_t, MinimumWidthIntegralType | -| cstd_types.cpp:43:15:43:17 | ul8 | CTypedefType, MinimumWidthIntegralType, UInt_least8_t | -| cstd_types.cpp:44:16:44:19 | ul16 | CTypedefType, MinimumWidthIntegralType, UInt_least16_t | -| cstd_types.cpp:45:16:45:19 | ul32 | CTypedefType, MinimumWidthIntegralType, UInt_least32_t | -| cstd_types.cpp:46:16:46:19 | ul64 | CTypedefType, MinimumWidthIntegralType, UInt_least64_t | +| cstd_types.cpp:39:15:39:16 | l8 | CTypedefType, GuardConditionImpl, Int_least8_t, MinimumWidthIntegralType | +| cstd_types.cpp:40:15:40:17 | l16 | CTypedefType, GuardConditionImpl, Int_least16_t, MinimumWidthIntegralType | +| cstd_types.cpp:41:15:41:17 | l32 | CTypedefType, GuardConditionImpl, Int_least32_t, MinimumWidthIntegralType | +| cstd_types.cpp:42:15:42:17 | l64 | CTypedefType, GuardConditionImpl, Int_least64_t, MinimumWidthIntegralType | +| cstd_types.cpp:43:15:43:17 | ul8 | CTypedefType, GuardConditionImpl, MinimumWidthIntegralType, UInt_least8_t | +| cstd_types.cpp:44:16:44:19 | ul16 | CTypedefType, GuardConditionImpl, MinimumWidthIntegralType, UInt_least16_t | +| cstd_types.cpp:45:16:45:19 | ul32 | CTypedefType, GuardConditionImpl, MinimumWidthIntegralType, UInt_least32_t | +| cstd_types.cpp:46:16:46:19 | ul64 | CTypedefType, GuardConditionImpl, MinimumWidthIntegralType, UInt_least64_t | diff --git a/cpp/ql/test/library-tests/types/integral_types_ms/vars.expected b/cpp/ql/test/library-tests/types/integral_types_ms/vars.expected index d2aac7454fdb..1f168f7f9426 100644 --- a/cpp/ql/test/library-tests/types/integral_types_ms/vars.expected +++ b/cpp/ql/test/library-tests/types/integral_types_ms/vars.expected @@ -1,4 +1,4 @@ -| integral_types.cpp:2:8:2:9 | i8 | file://:0:0:0:0 | char | MicrosoftInt8Type, PlainCharType | -| integral_types.cpp:3:9:3:11 | i16 | file://:0:0:0:0 | short | MicrosoftInt16Type, ShortType | -| integral_types.cpp:4:9:4:11 | i32 | file://:0:0:0:0 | int | IntType, MicrosoftInt32Type | -| integral_types.cpp:5:9:5:11 | i64 | file://:0:0:0:0 | long long | LongLongType, MicrosoftInt64Type | +| integral_types.cpp:2:8:2:9 | i8 | file://:0:0:0:0 | char | GuardConditionImpl, MicrosoftInt8Type, PlainCharType | +| integral_types.cpp:3:9:3:11 | i16 | file://:0:0:0:0 | short | GuardConditionImpl, MicrosoftInt16Type, ShortType | +| integral_types.cpp:4:9:4:11 | i32 | file://:0:0:0:0 | int | GuardConditionImpl, IntType, MicrosoftInt32Type | +| integral_types.cpp:5:9:5:11 | i64 | file://:0:0:0:0 | long long | GuardConditionImpl, LongLongType, MicrosoftInt64Type | diff --git a/cpp/ql/test/library-tests/types/wchar_t_typedef/wchar_t.expected b/cpp/ql/test/library-tests/types/wchar_t_typedef/wchar_t.expected index cebaff30994d..c823ed839d3d 100644 --- a/cpp/ql/test/library-tests/types/wchar_t_typedef/wchar_t.expected +++ b/cpp/ql/test/library-tests/types/wchar_t_typedef/wchar_t.expected @@ -1,3 +1,3 @@ -| file://:0:0:0:0 | wchar_t | Wchar_t, WideCharType | | -| file://:0:0:0:0 | wchar_t * | IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, PointerType | CTypedefType, Wchar_t | -| ms.c:2:24:2:30 | wchar_t | CTypedefType, Wchar_t | | +| file://:0:0:0:0 | wchar_t | GuardConditionImpl, Wchar_t, WideCharType | | +| file://:0:0:0:0 | wchar_t * | GuardConditionImpl, IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, PointerType | CTypedefType, GuardConditionImpl, Wchar_t | +| ms.c:2:24:2:30 | wchar_t | CTypedefType, GuardConditionImpl, Wchar_t | | diff --git a/cpp/ql/test/library-tests/variables/variables/types.expected b/cpp/ql/test/library-tests/variables/variables/types.expected index c2ea5f7cfe3c..5d8cec1cff89 100644 --- a/cpp/ql/test/library-tests/variables/variables/types.expected +++ b/cpp/ql/test/library-tests/variables/variables/types.expected @@ -1,108 +1,108 @@ -| ..()(..) | RoutineType | | | | | -| ..(*)(..) | FunctionPointerType | | ..()(..) | | | -| _Complex _Float16 | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex _Float32 | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex _Float32x | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex _Float64 | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex _Float64x | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex _Float128 | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex __bf16 | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex __float128 | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex __fp16 | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex double | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex float | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex long double | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Complex std::float16_t | BinaryFloatingPointType, ComplexNumberType | | | | | -| _Decimal32 | Decimal32Type | | | | | -| _Decimal64 | Decimal64Type | | | | | -| _Decimal128 | Decimal128Type | | | | | -| _Float16 | BinaryFloatingPointType, RealNumberType | | | | | -| _Float32 | BinaryFloatingPointType, RealNumberType | | | | | -| _Float32x | BinaryFloatingPointType, RealNumberType | | | | | -| _Float64 | BinaryFloatingPointType, RealNumberType | | | | | -| _Float64x | BinaryFloatingPointType, RealNumberType | | | | | -| _Float128 | BinaryFloatingPointType, RealNumberType | | | | | -| _Imaginary double | BinaryFloatingPointType, ImaginaryNumberType | | | | | -| _Imaginary float | BinaryFloatingPointType, ImaginaryNumberType | | | | | -| _Imaginary long double | BinaryFloatingPointType, ImaginaryNumberType | | | | | -| __SVCount_t | ScalableVectorCount | | | | | -| __bf16 | BinaryFloatingPointType, RealNumberType | | | | | -| __float128 | Float128Type | | | | | -| __fp16 | BinaryFloatingPointType, RealNumberType | | | | | -| __int128 | Int128Type | | | | | -| __mfp8 | BinaryFloatingPointType, RealNumberType | | | | | -| __va_list_tag | DirectAccessHolder, MetricClass, Struct, StructLikeClass | | | | | -| __va_list_tag & | LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | __va_list_tag | | | -| __va_list_tag && | PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, RValueReferenceType | | __va_list_tag | | | -| address | DirectAccessHolder, MetricClass, Struct, StructLikeClass | | | | | -| address & | LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | address | | | -| address && | PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, RValueReferenceType | | address | | | -| auto | AutoType | | | | | -| bool | BoolType | | | | | -| char | MicrosoftInt8Type, PlainCharType | | | | | -| char8_t | Char8Type | | | | | -| char16_t | Char16Type | | | | | -| char32_t | Char32Type | | | | | -| char * | CharPointerType, IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | char | | | -| char *[3] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char * | char * | | | -| char *[32] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char * | char * | | | -| char *[] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char * | char * | | | -| char[2] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | -| char[3] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | -| char[5] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | -| char[6] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | -| char[8] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | -| char[9] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | -| char[10] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | -| char[53] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | -| char[] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | -| const __va_list_tag | SpecifiedType | | __va_list_tag | | | -| const __va_list_tag & | LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | const __va_list_tag | | | -| const address | SpecifiedType | | address | | | -| const address & | LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | const address | | | -| const char | SpecifiedType | | char | | | -| const char * | IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, PointerType | | const char | | | -| const char *[3] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char * | const char * | | | -| const char *[] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char * | const char * | | | -| const char[5] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | -| const char[6] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | -| const char[8] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | -| const char[9] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | -| const char[10] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | -| const char[53] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | -| const double | SpecifiedType | | double | | | -| const int | SpecifiedType | | int | | | -| decltype(nullptr) | NullPointerType | | | | | -| double | DoubleType | | | | | -| error | ErroneousType | | | | | -| float | FloatType | | | | | -| float[3] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | float | float | | | -| int | IntType, MicrosoftInt32Type | | | | | -| int * | IntPointerType, IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | int | | | -| int[4] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | | -| int[8] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | | -| int[10] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | | -| int[10][20] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int[20] | int[20] | | | -| int[20] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | | -| int[] | ArrayType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | | -| long | LongType | | | | | -| long double | LongDoubleType | | | | | -| long long | LongLongType, MicrosoftInt64Type | | | | | -| short | MicrosoftInt16Type, ShortType | | | | | -| signed __int128 | Int128Type | | | | | -| signed char | SignedCharType | | | | | -| signed int | IntType | | | | | -| signed long | LongType | | | | | -| signed long long | LongLongType | | | | | -| signed short | ShortType | | | | | -| std::float16_t | BinaryFloatingPointType, RealNumberType | | | | | -| unknown | UnknownType | | | | | -| unsigned __int128 | Int128Type | | | | unsigned integral | -| unsigned char | UnsignedCharType | | | | unsigned integral | -| unsigned int | IntType | | | unsigned int | unsigned integral | -| unsigned long | LongType | | | | unsigned integral | -| unsigned long long | LongLongType | | | | unsigned integral | -| unsigned short | ShortType | | | | unsigned integral | -| void | VoidType | | | | | -| void * | IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, VoidPointerType | | void | | | -| wchar_t | Wchar_t, WideCharType | | | | | +| ..()(..) | GuardConditionImpl, RoutineType | | | | | +| ..(*)(..) | FunctionPointerType, GuardConditionImpl | | ..()(..) | | | +| _Complex _Float16 | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex _Float32 | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex _Float32x | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex _Float64 | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex _Float64x | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex _Float128 | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex __bf16 | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex __float128 | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex __fp16 | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex double | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex float | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex long double | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Complex std::float16_t | BinaryFloatingPointType, ComplexNumberType, GuardConditionImpl | | | | | +| _Decimal32 | Decimal32Type, GuardConditionImpl | | | | | +| _Decimal64 | Decimal64Type, GuardConditionImpl | | | | | +| _Decimal128 | Decimal128Type, GuardConditionImpl | | | | | +| _Float16 | BinaryFloatingPointType, GuardConditionImpl, RealNumberType | | | | | +| _Float32 | BinaryFloatingPointType, GuardConditionImpl, RealNumberType | | | | | +| _Float32x | BinaryFloatingPointType, GuardConditionImpl, RealNumberType | | | | | +| _Float64 | BinaryFloatingPointType, GuardConditionImpl, RealNumberType | | | | | +| _Float64x | BinaryFloatingPointType, GuardConditionImpl, RealNumberType | | | | | +| _Float128 | BinaryFloatingPointType, GuardConditionImpl, RealNumberType | | | | | +| _Imaginary double | BinaryFloatingPointType, GuardConditionImpl, ImaginaryNumberType | | | | | +| _Imaginary float | BinaryFloatingPointType, GuardConditionImpl, ImaginaryNumberType | | | | | +| _Imaginary long double | BinaryFloatingPointType, GuardConditionImpl, ImaginaryNumberType | | | | | +| __SVCount_t | GuardConditionImpl, ScalableVectorCount | | | | | +| __bf16 | BinaryFloatingPointType, GuardConditionImpl, RealNumberType | | | | | +| __float128 | Float128Type, GuardConditionImpl | | | | | +| __fp16 | BinaryFloatingPointType, GuardConditionImpl, RealNumberType | | | | | +| __int128 | GuardConditionImpl, Int128Type | | | | | +| __mfp8 | BinaryFloatingPointType, GuardConditionImpl, RealNumberType | | | | | +| __va_list_tag | DirectAccessHolder, GuardConditionImpl, MetricClass, Struct, StructLikeClass | | | | | +| __va_list_tag & | GuardConditionImpl, LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | __va_list_tag | | | +| __va_list_tag && | GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, RValueReferenceType | | __va_list_tag | | | +| address | DirectAccessHolder, GuardConditionImpl, MetricClass, Struct, StructLikeClass | | | | | +| address & | GuardConditionImpl, LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | address | | | +| address && | GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, RValueReferenceType | | address | | | +| auto | AutoType, GuardConditionImpl | | | | | +| bool | BoolType, GuardConditionImpl | | | | | +| char | GuardConditionImpl, MicrosoftInt8Type, PlainCharType | | | | | +| char8_t | Char8Type, GuardConditionImpl | | | | | +| char16_t | Char16Type, GuardConditionImpl | | | | | +| char32_t | Char32Type, GuardConditionImpl | | | | | +| char * | CharPointerType, GuardConditionImpl, IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | char | | | +| char *[3] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char * | char * | | | +| char *[32] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char * | char * | | | +| char *[] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char * | char * | | | +| char[2] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | +| char[3] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | +| char[5] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | +| char[6] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | +| char[8] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | +| char[9] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | +| char[10] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | +| char[53] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | +| char[] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | char | char | | | +| const __va_list_tag | GuardConditionImpl, SpecifiedType | | __va_list_tag | | | +| const __va_list_tag & | GuardConditionImpl, LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | const __va_list_tag | | | +| const address | GuardConditionImpl, SpecifiedType | | address | | | +| const address & | GuardConditionImpl, LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | const address | | | +| const char | GuardConditionImpl, SpecifiedType | | char | | | +| const char * | GuardConditionImpl, IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, PointerType | | const char | | | +| const char *[3] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char * | const char * | | | +| const char *[] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char * | const char * | | | +| const char[5] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | +| const char[6] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | +| const char[8] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | +| const char[9] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | +| const char[10] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | +| const char[53] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | const char | const char | | | +| const double | GuardConditionImpl, SpecifiedType | | double | | | +| const int | GuardConditionImpl, SpecifiedType | | int | | | +| decltype(nullptr) | GuardConditionImpl, NullPointerType | | | | | +| double | DoubleType, GuardConditionImpl | | | | | +| error | ErroneousType, GuardConditionImpl | | | | | +| float | FloatType, GuardConditionImpl | | | | | +| float[3] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | float | float | | | +| int | GuardConditionImpl, IntType, MicrosoftInt32Type | | | | | +| int * | GuardConditionImpl, IntPointerType, IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | int | | | +| int[4] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | | +| int[8] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | | +| int[10] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | | +| int[10][20] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int[20] | int[20] | | | +| int[20] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | | +| int[] | ArrayType, GuardConditionImpl, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | int | int | | | +| long | GuardConditionImpl, LongType | | | | | +| long double | GuardConditionImpl, LongDoubleType | | | | | +| long long | GuardConditionImpl, LongLongType, MicrosoftInt64Type | | | | | +| short | GuardConditionImpl, MicrosoftInt16Type, ShortType | | | | | +| signed __int128 | GuardConditionImpl, Int128Type | | | | | +| signed char | GuardConditionImpl, SignedCharType | | | | | +| signed int | GuardConditionImpl, IntType | | | | | +| signed long | GuardConditionImpl, LongType | | | | | +| signed long long | GuardConditionImpl, LongLongType | | | | | +| signed short | GuardConditionImpl, ShortType | | | | | +| std::float16_t | BinaryFloatingPointType, GuardConditionImpl, RealNumberType | | | | | +| unknown | GuardConditionImpl, UnknownType | | | | | +| unsigned __int128 | GuardConditionImpl, Int128Type | | | | unsigned integral | +| unsigned char | GuardConditionImpl, UnsignedCharType | | | | unsigned integral | +| unsigned int | GuardConditionImpl, IntType | | | unsigned int | unsigned integral | +| unsigned long | GuardConditionImpl, LongType | | | | unsigned integral | +| unsigned long long | GuardConditionImpl, LongLongType | | | | unsigned integral | +| unsigned short | GuardConditionImpl, ShortType | | | | unsigned integral | +| void | GuardConditionImpl, VoidType | | | | | +| void * | GuardConditionImpl, IteratorByPointer, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, VoidPointerType | | void | | | +| wchar_t | GuardConditionImpl, Wchar_t, WideCharType | | | | | From b3cbdb5c1a5a1e75547d473ca59cfbdb182f2b50 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 24 Sep 2025 10:39:27 +0100 Subject: [PATCH 20/35] C++: Add QLDoc to TRange. --- cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index d0f3de4fb3c5..5765816e0171 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -31,6 +31,12 @@ module GuardsInput implements SharedGuards::InputSig Date: Wed, 24 Sep 2025 10:51:45 +0100 Subject: [PATCH 21/35] C++: Remove superfluous inference logic. --- .../semmle/code/cpp/controlflow/IRGuards.qll | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 5765816e0171..42de61adf061 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -436,25 +436,6 @@ private module LogicInput_v1 implements GuardsImpl::LogicInputSig { ) { g1.(ConditionalBranchInstruction).getCondition() = g2 and v1.asBooleanValue() = v2.asBooleanValue() - or - exists(SwitchInstruction switch, SwitchEdge edge | - g1 = switch.getSuccessor(edge) and - g2 = switch.getExpression() - | - v1.asBooleanValue() = true and - ( - v2.asIntValue() = edge.getValue().toInt() - or - v2.asConstantValue().isRange(edge.getMinValue(), edge.getMaxValue()) - ) - or - v1.asBooleanValue() = false and - ( - v2.getDualValue().asIntValue() = edge.getValue().toInt() - or - v2.getDualValue().asConstantValue().isRange(edge.getMinValue(), edge.getMaxValue()) - ) - ) } } From 99e1a07b8e6a0a471a2bcfd55124588957da20d3 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 24 Sep 2025 10:58:47 +0100 Subject: [PATCH 22/35] C++: Add a comment to the 'ConditionalBranchInstruction' case in 'additionalImpliesStep. --- cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 42de61adf061..c1cb52432687 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -434,6 +434,15 @@ private module LogicInput_v1 implements GuardsImpl::LogicInputSig { predicate additionalImpliesStep( GuardsImpl::PreGuard g1, GuardValue v1, GuardsImpl::PreGuard g2, GuardValue v2 ) { + // The `ConditionalBranch` instruction is the instruction for which there are + // conditional successors out of. However, the condition that controls + // which conditional successor is taken is given by the condition of the + // `ConditionalBranch` instruction. So this step either needs to be here, + // or we need `ConditionalBranch` instructions to be `IdExpr`s. Modeling + // them as `IdExpr`s would be a bit weird since the result type is + // `IRVoidType`. Including them here is fine as long as `ConditionalBranch` + // instructions cannot be assigned to SSA variables (which they cannot + // since they produce no value). g1.(ConditionalBranchInstruction).getCondition() = g2 and v1.asBooleanValue() = v2.asBooleanValue() } From d10d5fd05e604f7040b80ff22114b38937b55e7f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 24 Sep 2025 15:17:02 +0100 Subject: [PATCH 23/35] C++: Rename in the name of consistency. --- .../semmle/code/cpp/controlflow/IRGuards.qll | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index c1cb52432687..a020c0c91e32 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -1128,7 +1128,7 @@ final class IRGuardCondition extends Guards_v1::Guard { */ pragma[inline] predicate comparesLt(Operand op, int k, boolean isLessThan, GuardValue value) { - compares_lt(valueNumber(this), op, k, isLessThan, value) + unary_compares_lt(valueNumber(this), op, k, isLessThan, value) } /** @@ -1150,7 +1150,7 @@ final class IRGuardCondition extends Guards_v1::Guard { pragma[inline] predicate ensuresLt(Operand op, int k, IRBlock block, boolean isLessThan) { exists(GuardValue value | - compares_lt(valueNumber(this), op, k, isLessThan, value) and + unary_compares_lt(valueNumber(this), op, k, isLessThan, value) and this.valueControls(block, value) ) } @@ -1176,7 +1176,7 @@ final class IRGuardCondition extends Guards_v1::Guard { pragma[inline] predicate ensuresLtEdge(Operand left, int k, IRBlock pred, IRBlock succ, boolean isLessThan) { exists(GuardValue value | - compares_lt(valueNumber(this), left, k, isLessThan, value) and + unary_compares_lt(valueNumber(this), left, k, isLessThan, value) and this.valueControlsBranchEdge(pred, succ, value) ) } @@ -1648,14 +1648,14 @@ private module Cached { /** Holds if `op < k` evaluates to `isLt` given that `test` evaluates to `value`. */ cached - predicate compares_lt(ValueNumber test, Operand op, int k, boolean isLt, GuardValue value) { + predicate unary_compares_lt(ValueNumber test, Operand op, int k, boolean isLt, GuardValue value) { unary_simple_comparison_lt(test, op, k, isLt, value) or complex_lt(test, op, k, isLt, value) or /* (x is true => (op < k)) => (!x is false => (op < k)) */ exists(GuardValue dual | value = dual.getDualValue() | - compares_lt(test.(LogicalNotValueNumber).getUnary(), op, k, isLt, dual) + unary_compares_lt(test.(LogicalNotValueNumber).getUnary(), op, k, isLt, dual) ) or exists(int k1, int k2, Instruction const | @@ -1664,13 +1664,13 @@ private module Cached { k = k1 + k2 ) or - compares_lt(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, isLt, value) + unary_compares_lt(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, isLt, value) or // See argument for why this is correct in compares_eq exists(Operand l, GuardValue bv | unary_compares_eq(test, l, 0, bv.asBooleanValue().booleanNot(), value) and - compares_lt(valueNumber(BooleanInstruction::get(l.getDef())), op, k, - isLt, bv) + unary_compares_lt(valueNumber(BooleanInstruction::get(l.getDef())), + op, k, isLt, bv) ) } @@ -1769,14 +1769,14 @@ private module Cached { private predicate sub_lt(ValueNumber test, Operand left, int k, boolean isLt, GuardValue value) { exists(SubInstruction lhs, int c, int x | - compares_lt(test, lhs.getAUse(), c, isLt, value) and + unary_compares_lt(test, lhs.getAUse(), c, isLt, value) and left = lhs.getLeftOperand() and x = int_value(lhs.getRight()) and k = c + x ) or exists(PointerSubInstruction lhs, int c, int x | - compares_lt(test, lhs.getAUse(), c, isLt, value) and + unary_compares_lt(test, lhs.getAUse(), c, isLt, value) and left = lhs.getLeftOperand() and x = int_value(lhs.getRight()) and k = c + x @@ -1831,7 +1831,7 @@ private module Cached { private predicate add_lt(ValueNumber test, Operand left, int k, boolean isLt, GuardValue value) { exists(AddInstruction lhs, int c, int x | - compares_lt(test, lhs.getAUse(), c, isLt, value) and + unary_compares_lt(test, lhs.getAUse(), c, isLt, value) and ( left = lhs.getLeftOperand() and x = int_value(lhs.getRight()) or @@ -1841,7 +1841,7 @@ private module Cached { ) or exists(PointerAddInstruction lhs, int c, int x | - compares_lt(test, lhs.getAUse(), c, isLt, value) and + unary_compares_lt(test, lhs.getAUse(), c, isLt, value) and ( left = lhs.getLeftOperand() and x = int_value(lhs.getRight()) or From 13cde4d7004089fa5c1e78104405981013413859 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 24 Sep 2025 15:34:35 +0100 Subject: [PATCH 24/35] C++: Add testcase demonstrating that a ConstantValue IPA branch representing a gcc case range is a bad idea. --- .../controlflow/guards/GuardsCompare.expected | 12 ++++++++++++ .../controlflow/guards/GuardsControl.expected | 6 ++++++ .../controlflow/guards/GuardsEnsure.expected | 10 ++++++++++ .../library-tests/controlflow/guards/test.cpp | 17 +++++++++++++++++ 4 files changed, 45 insertions(+) diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected index d1a3f22d7660..cb18638c71ef 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected @@ -1296,3 +1296,15 @@ | test.cpp:318:7:318:12 | ... < ... | a < 42+0 when ... < ... is true | | test.cpp:318:7:318:12 | ... < ... | a >= 42 when ... < ... is false | | test.cpp:318:7:318:12 | ... < ... | a >= 42+0 when ... < ... is false | +| test.cpp:327:46:327:46 | b | b != 0 when b is true | +| test.cpp:327:46:327:46 | b | b != 1 when b is false | +| test.cpp:327:46:327:46 | b | b == 0 when b is false | +| test.cpp:327:46:327:46 | b | b == 1 when b is true | +| test.cpp:330:7:330:7 | b | b != 0 when b is true | +| test.cpp:330:7:330:7 | b | b != 1 when b is false | +| test.cpp:330:7:330:7 | b | b == 0 when b is false | +| test.cpp:330:7:330:7 | b | b == 1 when b is true | +| test.cpp:334:11:334:11 | x | x < 51 when x is 40..50 | +| test.cpp:334:11:334:11 | x | x >= 40 when x is 40..50 | +| test.cpp:338:9:338:9 | x | x < 51 when x is 40..50 | +| test.cpp:338:9:338:9 | x | x >= 40 when x is 40..50 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected index 078d8aeea086..b35ec3232667 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected @@ -328,3 +328,9 @@ | test.cpp:318:6:318:18 | ... != ... | true | test.cpp:318:21:320:3 | { ... } | | test.cpp:318:7:318:12 | ... < ... | 0 | test.cpp:320:10:322:3 | { ... } | | test.cpp:318:7:318:12 | ... < ... | not 0 | test.cpp:318:21:320:3 | { ... } | +| test.cpp:327:46:327:46 | b | false | test.cpp:336:3:338:7 | case ...: | +| test.cpp:327:46:327:46 | b | true | test.cpp:331:3:332:10 | { ... } | +| test.cpp:329:11:329:13 | call to foo | 40..50 | test.cpp:336:3:338:7 | case ...: | +| test.cpp:330:7:330:7 | b | false | test.cpp:336:3:338:7 | case ...: | +| test.cpp:330:7:330:7 | b | true | test.cpp:331:3:332:10 | { ... } | +| test.cpp:334:11:334:11 | x | 40..50 | test.cpp:336:3:338:7 | case ...: | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index da36308f8786..fdbdca431845 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -1294,3 +1294,13 @@ unary | test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:7 | a | >= | 42 | test.cpp:320:10:322:3 | { ... } | | test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:12 | ... < ... | != | 0 | test.cpp:318:21:320:3 | { ... } | | test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:12 | ... < ... | == | 0 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:327:46:327:46 | b | test.cpp:330:7:330:7 | b | != | 0 | test.cpp:331:3:332:10 | { ... } | +| test.cpp:327:46:327:46 | b | test.cpp:330:7:330:7 | b | != | 1 | test.cpp:336:3:338:7 | case ...: | +| test.cpp:327:46:327:46 | b | test.cpp:330:7:330:7 | b | == | 0 | test.cpp:336:3:338:7 | case ...: | +| test.cpp:327:46:327:46 | b | test.cpp:330:7:330:7 | b | == | 1 | test.cpp:331:3:332:10 | { ... } | +| test.cpp:330:7:330:7 | b | test.cpp:330:7:330:7 | b | != | 0 | test.cpp:331:3:332:10 | { ... } | +| test.cpp:330:7:330:7 | b | test.cpp:330:7:330:7 | b | != | 1 | test.cpp:336:3:338:7 | case ...: | +| test.cpp:330:7:330:7 | b | test.cpp:330:7:330:7 | b | == | 0 | test.cpp:336:3:338:7 | case ...: | +| test.cpp:330:7:330:7 | b | test.cpp:330:7:330:7 | b | == | 1 | test.cpp:331:3:332:10 | { ... } | +| test.cpp:334:11:334:11 | x | test.cpp:334:11:334:11 | x | < | 51 | test.cpp:336:3:338:7 | case ...: | +| test.cpp:334:11:334:11 | x | test.cpp:334:11:334:11 | x | >= | 40 | test.cpp:336:3:338:7 | case ...: | diff --git a/cpp/ql/test/library-tests/controlflow/guards/test.cpp b/cpp/ql/test/library-tests/controlflow/guards/test.cpp index 2ef61734e69a..bb0fe83c7c72 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/test.cpp +++ b/cpp/ql/test/library-tests/controlflow/guards/test.cpp @@ -320,4 +320,21 @@ void test_cmp_implies_unary(int a) { } else { } +} + +int foo(); + +void test_constant_value_and_case_range(bool b) +{ + int x = foo(); + if (b) + { + x = 42; + } + switch (x) + { + case 40 ... 50: + // should not be guarded by `foo() = 40..50` + use(x); + } } \ No newline at end of file From d15e388f5c64d05d63f673ecbad1105d5ea153fd Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 24 Sep 2025 15:52:10 +0100 Subject: [PATCH 25/35] C++: Get rid of the case range constant value with and instead implement 'rangeGuard'. --- .../semmle/code/cpp/controlflow/IRGuards.qll | 64 +++++++++---------- .../controlflow/guards/GuardsCompare.expected | 40 ++++++------ .../controlflow/guards/GuardsControl.expected | 20 +++--- .../controlflow/guards/GuardsEnsure.expected | 4 -- 4 files changed, 63 insertions(+), 65 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index a020c0c91e32..76cccb4a6251 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -125,41 +125,16 @@ module GuardsInput implements SharedGuards::InputSig op < k - 1 isLt = true and - maxValue.toInt() = k - 1 + maxValue.toInt() = k - 1 and + value.isIntRange(k - 1, true) or isLt = false and - minValue.toInt() = k + minValue.toInt() = k and + value.isIntRange(k, false) ) } diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected index cb18638c71ef..0216df7b31f7 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected @@ -490,22 +490,22 @@ | test.cpp:69:12:69:12 | i | i == 0 when i is 0 | | test.cpp:69:12:69:12 | i | i == 1 when i is 1 | | test.cpp:69:12:69:12 | i | i == 2 when i is 2 | -| test.cpp:73:30:73:30 | i | i < 11 when i is 0..10 | -| test.cpp:73:30:73:30 | i | i < 21 when i is 11..20 | -| test.cpp:73:30:73:30 | i | i >= 0 when i is 0..10 | -| test.cpp:73:30:73:30 | i | i >= 11 when i is 11..20 | -| test.cpp:74:10:74:10 | i | i < 11 when i is 0..10 | -| test.cpp:74:10:74:10 | i | i < 21 when i is 11..20 | -| test.cpp:74:10:74:10 | i | i >= 0 when i is 0..10 | -| test.cpp:74:10:74:10 | i | i >= 11 when i is 11..20 | -| test.cpp:76:12:76:12 | i | i < 11 when i is 0..10 | -| test.cpp:76:12:76:12 | i | i < 21 when i is 11..20 | -| test.cpp:76:12:76:12 | i | i >= 0 when i is 0..10 | -| test.cpp:76:12:76:12 | i | i >= 11 when i is 11..20 | -| test.cpp:79:12:79:12 | i | i < 11 when i is 0..10 | -| test.cpp:79:12:79:12 | i | i < 21 when i is 11..20 | -| test.cpp:79:12:79:12 | i | i >= 0 when i is 0..10 | -| test.cpp:79:12:79:12 | i | i >= 11 when i is 11..20 | +| test.cpp:73:30:73:30 | i | i < 11 when i is Upper bound 10 | +| test.cpp:73:30:73:30 | i | i < 21 when i is Upper bound 20 | +| test.cpp:73:30:73:30 | i | i >= 0 when i is Lower bound 0 | +| test.cpp:73:30:73:30 | i | i >= 11 when i is Lower bound 11 | +| test.cpp:74:10:74:10 | i | i < 11 when i is Upper bound 10 | +| test.cpp:74:10:74:10 | i | i < 21 when i is Upper bound 20 | +| test.cpp:74:10:74:10 | i | i >= 0 when i is Lower bound 0 | +| test.cpp:74:10:74:10 | i | i >= 11 when i is Lower bound 11 | +| test.cpp:76:12:76:12 | i | i < 11 when i is Upper bound 10 | +| test.cpp:76:12:76:12 | i | i < 21 when i is Upper bound 20 | +| test.cpp:76:12:76:12 | i | i >= 0 when i is Lower bound 0 | +| test.cpp:76:12:76:12 | i | i >= 11 when i is Lower bound 11 | +| test.cpp:79:12:79:12 | i | i < 11 when i is Upper bound 10 | +| test.cpp:79:12:79:12 | i | i < 21 when i is Upper bound 20 | +| test.cpp:79:12:79:12 | i | i >= 0 when i is Lower bound 0 | +| test.cpp:79:12:79:12 | i | i >= 11 when i is Lower bound 11 | | test.cpp:93:6:93:6 | c | c != 0 when c is true | | test.cpp:93:6:93:6 | c | c != 1 when c is false | | test.cpp:93:6:93:6 | c | c == 0 when c is false | @@ -1304,7 +1304,7 @@ | test.cpp:330:7:330:7 | b | b != 1 when b is false | | test.cpp:330:7:330:7 | b | b == 0 when b is false | | test.cpp:330:7:330:7 | b | b == 1 when b is true | -| test.cpp:334:11:334:11 | x | x < 51 when x is 40..50 | -| test.cpp:334:11:334:11 | x | x >= 40 when x is 40..50 | -| test.cpp:338:9:338:9 | x | x < 51 when x is 40..50 | -| test.cpp:338:9:338:9 | x | x >= 40 when x is 40..50 | +| test.cpp:334:11:334:11 | x | x < 51 when x is Upper bound 50 | +| test.cpp:334:11:334:11 | x | x >= 40 when x is Lower bound 40 | +| test.cpp:338:9:338:9 | x | x < 51 when x is Upper bound 50 | +| test.cpp:338:9:338:9 | x | x >= 40 when x is Lower bound 40 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected index b35ec3232667..e9ef52f709d3 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected @@ -178,12 +178,18 @@ | test.cpp:42:13:42:20 | call to getABool | true | test.cpp:43:9:45:23 | { ... } | | test.cpp:60:31:60:31 | i | 0 | test.cpp:62:5:64:12 | case ...: | | test.cpp:60:31:60:31 | i | 1 | test.cpp:65:5:66:10 | case ...: | +| test.cpp:60:31:60:31 | i | 10 | test.cpp:62:5:64:12 | case ...: | | test.cpp:61:10:61:10 | i | 0 | test.cpp:62:5:64:12 | case ...: | | test.cpp:61:10:61:10 | i | 1 | test.cpp:65:5:66:10 | case ...: | -| test.cpp:73:30:73:30 | i | 0..10 | test.cpp:75:5:77:12 | case ...: | -| test.cpp:73:30:73:30 | i | 11..20 | test.cpp:78:5:79:10 | case ...: | -| test.cpp:74:10:74:10 | i | 0..10 | test.cpp:75:5:77:12 | case ...: | -| test.cpp:74:10:74:10 | i | 11..20 | test.cpp:78:5:79:10 | case ...: | +| test.cpp:61:10:61:10 | i | 10 | test.cpp:62:5:64:12 | case ...: | +| test.cpp:73:30:73:30 | i | Lower bound 0 | test.cpp:75:5:77:12 | case ...: | +| test.cpp:73:30:73:30 | i | Lower bound 11 | test.cpp:78:5:79:10 | case ...: | +| test.cpp:73:30:73:30 | i | Upper bound 10 | test.cpp:75:5:77:12 | case ...: | +| test.cpp:73:30:73:30 | i | Upper bound 20 | test.cpp:78:5:79:10 | case ...: | +| test.cpp:74:10:74:10 | i | Lower bound 0 | test.cpp:75:5:77:12 | case ...: | +| test.cpp:74:10:74:10 | i | Lower bound 11 | test.cpp:78:5:79:10 | case ...: | +| test.cpp:74:10:74:10 | i | Upper bound 10 | test.cpp:75:5:77:12 | case ...: | +| test.cpp:74:10:74:10 | i | Upper bound 20 | test.cpp:78:5:79:10 | case ...: | | test.cpp:92:31:92:31 | c | not null | test.cpp:93:9:94:7 | { ... } | | test.cpp:93:6:93:6 | c | not null | test.cpp:93:9:94:7 | { ... } | | test.cpp:93:6:93:6 | c | true | test.cpp:93:9:94:7 | { ... } | @@ -328,9 +334,7 @@ | test.cpp:318:6:318:18 | ... != ... | true | test.cpp:318:21:320:3 | { ... } | | test.cpp:318:7:318:12 | ... < ... | 0 | test.cpp:320:10:322:3 | { ... } | | test.cpp:318:7:318:12 | ... < ... | not 0 | test.cpp:318:21:320:3 | { ... } | -| test.cpp:327:46:327:46 | b | false | test.cpp:336:3:338:7 | case ...: | | test.cpp:327:46:327:46 | b | true | test.cpp:331:3:332:10 | { ... } | -| test.cpp:329:11:329:13 | call to foo | 40..50 | test.cpp:336:3:338:7 | case ...: | -| test.cpp:330:7:330:7 | b | false | test.cpp:336:3:338:7 | case ...: | | test.cpp:330:7:330:7 | b | true | test.cpp:331:3:332:10 | { ... } | -| test.cpp:334:11:334:11 | x | 40..50 | test.cpp:336:3:338:7 | case ...: | +| test.cpp:334:11:334:11 | x | Lower bound 40 | test.cpp:336:3:338:7 | case ...: | +| test.cpp:334:11:334:11 | x | Upper bound 50 | test.cpp:336:3:338:7 | case ...: | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index fdbdca431845..1f0b11972301 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -1295,12 +1295,8 @@ unary | test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:12 | ... < ... | != | 0 | test.cpp:318:21:320:3 | { ... } | | test.cpp:318:6:318:18 | ... != ... | test.cpp:318:7:318:12 | ... < ... | == | 0 | test.cpp:320:10:322:3 | { ... } | | test.cpp:327:46:327:46 | b | test.cpp:330:7:330:7 | b | != | 0 | test.cpp:331:3:332:10 | { ... } | -| test.cpp:327:46:327:46 | b | test.cpp:330:7:330:7 | b | != | 1 | test.cpp:336:3:338:7 | case ...: | -| test.cpp:327:46:327:46 | b | test.cpp:330:7:330:7 | b | == | 0 | test.cpp:336:3:338:7 | case ...: | | test.cpp:327:46:327:46 | b | test.cpp:330:7:330:7 | b | == | 1 | test.cpp:331:3:332:10 | { ... } | | test.cpp:330:7:330:7 | b | test.cpp:330:7:330:7 | b | != | 0 | test.cpp:331:3:332:10 | { ... } | -| test.cpp:330:7:330:7 | b | test.cpp:330:7:330:7 | b | != | 1 | test.cpp:336:3:338:7 | case ...: | -| test.cpp:330:7:330:7 | b | test.cpp:330:7:330:7 | b | == | 0 | test.cpp:336:3:338:7 | case ...: | | test.cpp:330:7:330:7 | b | test.cpp:330:7:330:7 | b | == | 1 | test.cpp:331:3:332:10 | { ... } | | test.cpp:334:11:334:11 | x | test.cpp:334:11:334:11 | x | < | 51 | test.cpp:336:3:338:7 | case ...: | | test.cpp:334:11:334:11 | x | test.cpp:334:11:334:11 | x | >= | 40 | test.cpp:336:3:338:7 | case ...: | From b2269fb5f590c5a40f3e1aea1d9cfc9155e99626 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 24 Sep 2025 19:00:38 +0100 Subject: [PATCH 26/35] C++: Add more tests. --- .../controlflow/guards/GuardsCompare.expected | 134 ++++++++++++++++++ .../controlflow/guards/GuardsControl.expected | 82 +++++++++++ .../controlflow/guards/GuardsEnsure.expected | 133 +++++++++++++++++ .../controlflow/guards/GuardsInline.expected | 27 ++++ .../controlflow/guards/GuardsInline.ql | 44 ++++++ .../controlflow/guards/GuardsInline.qlref | 2 + .../library-tests/controlflow/guards/test.cpp | 80 ++++++++++- 7 files changed, 501 insertions(+), 1 deletion(-) create mode 100644 cpp/ql/test/library-tests/controlflow/guards/GuardsInline.expected create mode 100644 cpp/ql/test/library-tests/controlflow/guards/GuardsInline.ql create mode 100644 cpp/ql/test/library-tests/controlflow/guards/GuardsInline.qlref diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected index 0216df7b31f7..4d78c4016dab 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected @@ -1308,3 +1308,137 @@ | test.cpp:334:11:334:11 | x | x >= 40 when x is Lower bound 40 | | test.cpp:338:9:338:9 | x | x < 51 when x is Upper bound 50 | | test.cpp:338:9:338:9 | x | x >= 40 when x is Lower bound 40 | +| test.cpp:345:10:345:25 | ... != ... | 0 != input+0 when ... != ... is true | +| test.cpp:345:10:345:25 | ... != ... | 0 == input+0 when ... != ... is false | +| test.cpp:345:10:345:25 | ... != ... | input != 0 when ... != ... is true | +| test.cpp:345:10:345:25 | ... != ... | input != 0+0 when ... != ... is true | +| test.cpp:345:10:345:25 | ... != ... | input == 0 when ... != ... is false | +| test.cpp:345:10:345:25 | ... != ... | input == 0+0 when ... != ... is false | +| test.cpp:349:11:349:22 | call to testNotNull1 | call to testNotNull1 != 0 when call to testNotNull1 is true | +| test.cpp:349:11:349:22 | call to testNotNull1 | call to testNotNull1 != 1 when call to testNotNull1 is false | +| test.cpp:349:11:349:22 | call to testNotNull1 | call to testNotNull1 == 0 when call to testNotNull1 is false | +| test.cpp:349:11:349:22 | call to testNotNull1 | call to testNotNull1 == 1 when call to testNotNull1 is true | +| test.cpp:350:7:350:12 | ... != ... | 0 != x+0 when ... != ... is true | +| test.cpp:350:7:350:12 | ... != ... | 0 == x+0 when ... != ... is false | +| test.cpp:350:7:350:12 | ... != ... | ... != ... != 0 when ... != ... is true | +| test.cpp:350:7:350:12 | ... != ... | ... != ... != 1 when ... != ... is false | +| test.cpp:350:7:350:12 | ... != ... | ... != ... == 0 when ... != ... is false | +| test.cpp:350:7:350:12 | ... != ... | ... != ... == 1 when ... != ... is true | +| test.cpp:350:7:350:12 | ... != ... | x != 0 when ... != ... is true | +| test.cpp:350:7:350:12 | ... != ... | x != 0+0 when ... != ... is true | +| test.cpp:350:7:350:12 | ... != ... | x == 0 when ... != ... is false | +| test.cpp:350:7:350:12 | ... != ... | x == 0+0 when ... != ... is false | +| test.cpp:356:7:356:22 | ... == ... | 0 != input+0 when ... == ... is false | +| test.cpp:356:7:356:22 | ... == ... | 0 == input+0 when ... == ... is true | +| test.cpp:356:7:356:22 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:356:7:356:22 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:356:7:356:22 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:356:7:356:22 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:356:7:356:22 | ... == ... | input != 0 when ... == ... is false | +| test.cpp:356:7:356:22 | ... == ... | input != 0+0 when ... == ... is false | +| test.cpp:356:7:356:22 | ... == ... | input == 0 when ... == ... is true | +| test.cpp:356:7:356:22 | ... == ... | input == 0+0 when ... == ... is true | +| test.cpp:361:10:361:26 | ... == ... | 0 != number+0 when ... == ... is false | +| test.cpp:361:10:361:26 | ... == ... | 0 == number+0 when ... == ... is true | +| test.cpp:361:10:361:26 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:361:10:361:26 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:361:10:361:26 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:361:10:361:26 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:361:10:361:26 | ... == ... | number != 0 when ... == ... is false | +| test.cpp:361:10:361:26 | ... == ... | number != 0+0 when ... == ... is false | +| test.cpp:361:10:361:26 | ... == ... | number == 0 when ... == ... is true | +| test.cpp:361:10:361:26 | ... == ... | number == 0+0 when ... == ... is true | +| test.cpp:365:7:365:9 | ! ... | ! ... != 0 when ! ... is true | +| test.cpp:365:7:365:9 | ! ... | ! ... != 1 when ! ... is false | +| test.cpp:365:7:365:9 | ! ... | ! ... == 0 when ! ... is false | +| test.cpp:365:7:365:9 | ! ... | ! ... == 1 when ! ... is true | +| test.cpp:365:7:365:9 | ! ... | s1 != 0 when ! ... is false | +| test.cpp:365:7:365:9 | ! ... | s1 != 1 when ! ... is true | +| test.cpp:365:7:365:9 | ! ... | s1 == 0 when ! ... is true | +| test.cpp:365:7:365:9 | ! ... | s1 == 1 when ! ... is false | +| test.cpp:365:7:365:16 | ... \|\| ... | ! ... != 1 when ... \|\| ... is false | +| test.cpp:365:7:365:16 | ... \|\| ... | ! ... == 0 when ... \|\| ... is false | +| test.cpp:365:7:365:16 | ... \|\| ... | s1 != 0 when ... \|\| ... is false | +| test.cpp:365:7:365:16 | ... \|\| ... | s1 == 1 when ... \|\| ... is false | +| test.cpp:365:7:365:16 | ... \|\| ... | s2 != 0 when ... \|\| ... is false | +| test.cpp:365:7:365:16 | ... \|\| ... | s2 == 1 when ... \|\| ... is false | +| test.cpp:365:8:365:9 | s1 | ! ... != 0 when s1 is false | +| test.cpp:365:8:365:9 | s1 | ! ... != 1 when s1 is true | +| test.cpp:365:8:365:9 | s1 | ! ... == 0 when s1 is true | +| test.cpp:365:8:365:9 | s1 | ! ... == 1 when s1 is false | +| test.cpp:365:8:365:9 | s1 | s1 != 0 when s1 is true | +| test.cpp:365:8:365:9 | s1 | s1 != 1 when s1 is false | +| test.cpp:365:8:365:9 | s1 | s1 == 0 when s1 is false | +| test.cpp:365:8:365:9 | s1 | s1 == 1 when s1 is true | +| test.cpp:365:14:365:16 | ! ... | ! ... != 0 when ! ... is true | +| test.cpp:365:14:365:16 | ! ... | ! ... != 1 when ! ... is false | +| test.cpp:365:14:365:16 | ! ... | ! ... == 0 when ! ... is false | +| test.cpp:365:14:365:16 | ! ... | ! ... == 1 when ! ... is true | +| test.cpp:365:14:365:16 | ! ... | s2 != 0 when ! ... is false | +| test.cpp:365:14:365:16 | ! ... | s2 != 1 when ! ... is true | +| test.cpp:365:14:365:16 | ! ... | s2 == 0 when ! ... is true | +| test.cpp:365:14:365:16 | ! ... | s2 == 1 when ! ... is false | +| test.cpp:365:15:365:16 | s2 | ! ... != 0 when s2 is false | +| test.cpp:365:15:365:16 | s2 | ! ... != 1 when s2 is true | +| test.cpp:365:15:365:16 | s2 | ! ... == 0 when s2 is true | +| test.cpp:365:15:365:16 | s2 | ! ... == 1 when s2 is false | +| test.cpp:365:15:365:16 | s2 | s2 != 0 when s2 is true | +| test.cpp:365:15:365:16 | s2 | s2 != 1 when s2 is false | +| test.cpp:365:15:365:16 | s2 | s2 == 0 when s2 is false | +| test.cpp:365:15:365:16 | s2 | s2 == 1 when s2 is true | +| test.cpp:371:29:371:32 | flag | flag != 0 when flag is true | +| test.cpp:371:29:371:32 | flag | flag != 1 when flag is false | +| test.cpp:371:29:371:32 | flag | flag == 0 when flag is false | +| test.cpp:371:29:371:32 | flag | flag == 1 when flag is true | +| test.cpp:372:10:372:13 | flag | flag != 0 when flag is true | +| test.cpp:372:10:372:13 | flag | flag != 1 when flag is false | +| test.cpp:372:10:372:13 | flag | flag == 0 when flag is false | +| test.cpp:372:10:372:13 | flag | flag == 1 when flag is true | +| test.cpp:376:7:376:18 | call to testNotNull1 | call to testNotNull1 != 0 when call to testNotNull1 is true | +| test.cpp:376:7:376:18 | call to testNotNull1 | call to testNotNull1 != 1 when call to testNotNull1 is false | +| test.cpp:376:7:376:18 | call to testNotNull1 | call to testNotNull1 == 0 when call to testNotNull1 is false | +| test.cpp:376:7:376:18 | call to testNotNull1 | call to testNotNull1 == 1 when call to testNotNull1 is true | +| test.cpp:382:7:382:18 | call to testNotNull2 | call to testNotNull2 != 0 when call to testNotNull2 is true | +| test.cpp:382:7:382:18 | call to testNotNull2 | call to testNotNull2 != 1 when call to testNotNull2 is false | +| test.cpp:382:7:382:18 | call to testNotNull2 | call to testNotNull2 == 0 when call to testNotNull2 is false | +| test.cpp:382:7:382:18 | call to testNotNull2 | call to testNotNull2 == 1 when call to testNotNull2 is true | +| test.cpp:388:7:388:29 | ... == ... | 0 != call to getNumOrDefault+0 when ... == ... is false | +| test.cpp:388:7:388:29 | ... == ... | 0 == call to getNumOrDefault+0 when ... == ... is true | +| test.cpp:388:7:388:29 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:388:7:388:29 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:388:7:388:29 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:388:7:388:29 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:388:7:388:29 | ... == ... | call to getNumOrDefault != 0 when ... == ... is false | +| test.cpp:388:7:388:29 | ... == ... | call to getNumOrDefault != 0+0 when ... == ... is false | +| test.cpp:388:7:388:29 | ... == ... | call to getNumOrDefault == 0 when ... == ... is true | +| test.cpp:388:7:388:29 | ... == ... | call to getNumOrDefault == 0+0 when ... == ... is true | +| test.cpp:394:7:394:47 | ... == ... | 0 != call to returnAIfNoneAreNull+0 when ... == ... is false | +| test.cpp:394:7:394:47 | ... == ... | 0 == call to returnAIfNoneAreNull+0 when ... == ... is true | +| test.cpp:394:7:394:47 | ... == ... | ... == ... != 0 when ... == ... is true | +| test.cpp:394:7:394:47 | ... == ... | ... == ... != 1 when ... == ... is false | +| test.cpp:394:7:394:47 | ... == ... | ... == ... == 0 when ... == ... is false | +| test.cpp:394:7:394:47 | ... == ... | ... == ... == 1 when ... == ... is true | +| test.cpp:394:7:394:47 | ... == ... | call to returnAIfNoneAreNull != 0 when ... == ... is false | +| test.cpp:394:7:394:47 | ... == ... | call to returnAIfNoneAreNull != 0+0 when ... == ... is false | +| test.cpp:394:7:394:47 | ... == ... | call to returnAIfNoneAreNull == 0 when ... == ... is true | +| test.cpp:394:7:394:47 | ... == ... | call to returnAIfNoneAreNull == 0+0 when ... == ... is true | +| test.cpp:400:11:400:25 | call to testEnumWrapper | call to testEnumWrapper != 1 when call to testEnumWrapper is not 1 | +| test.cpp:400:11:400:25 | call to testEnumWrapper | call to testEnumWrapper != 2 when call to testEnumWrapper is not 2 | +| test.cpp:400:11:400:25 | call to testEnumWrapper | call to testEnumWrapper == 1 when call to testEnumWrapper is 1 | +| test.cpp:400:11:400:25 | call to testEnumWrapper | call to testEnumWrapper == 2 when call to testEnumWrapper is 2 | +| test.cpp:411:7:411:8 | ! ... | ! ... != 0 when ! ... is true | +| test.cpp:411:7:411:8 | ! ... | ! ... != 1 when ! ... is false | +| test.cpp:411:7:411:8 | ! ... | ! ... == 0 when ! ... is false | +| test.cpp:411:7:411:8 | ! ... | ! ... == 1 when ! ... is true | +| test.cpp:411:7:411:8 | ! ... | o != 0 when ! ... is false | +| test.cpp:411:7:411:8 | ! ... | o != 1 when ! ... is true | +| test.cpp:411:7:411:8 | ! ... | o == 0 when ! ... is true | +| test.cpp:411:7:411:8 | ! ... | o == 1 when ! ... is false | +| test.cpp:411:8:411:8 | o | ! ... != 0 when o is false | +| test.cpp:411:8:411:8 | o | ! ... != 1 when o is true | +| test.cpp:411:8:411:8 | o | ! ... == 0 when o is true | +| test.cpp:411:8:411:8 | o | ! ... == 1 when o is false | +| test.cpp:411:8:411:8 | o | o != 0 when o is true | +| test.cpp:411:8:411:8 | o | o != 1 when o is false | +| test.cpp:411:8:411:8 | o | o == 0 when o is false | +| test.cpp:411:8:411:8 | o | o == 1 when o is true | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected index e9ef52f709d3..d00a6012ef45 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected @@ -338,3 +338,85 @@ | test.cpp:330:7:330:7 | b | true | test.cpp:331:3:332:10 | { ... } | | test.cpp:334:11:334:11 | x | Lower bound 40 | test.cpp:336:3:338:7 | case ...: | | test.cpp:334:11:334:11 | x | Upper bound 50 | test.cpp:336:3:338:7 | case ...: | +| test.cpp:348:25:348:25 | y | not null | test.cpp:349:29:349:30 | 42 | +| test.cpp:348:25:348:25 | y | not null | test.cpp:350:15:351:7 | { ... } | +| test.cpp:348:25:348:25 | y | null | test.cpp:349:34:349:34 | 0 | +| test.cpp:349:11:349:22 | call to testNotNull1 | false | test.cpp:349:34:349:34 | 0 | +| test.cpp:349:11:349:22 | call to testNotNull1 | true | test.cpp:349:29:349:30 | 42 | +| test.cpp:349:11:349:22 | call to testNotNull1 | true | test.cpp:350:15:351:7 | { ... } | +| test.cpp:349:11:349:34 | ... ? ... : ... | not 0 | test.cpp:350:15:351:7 | { ... } | +| test.cpp:349:24:349:24 | y | not null | test.cpp:349:29:349:30 | 42 | +| test.cpp:349:24:349:24 | y | not null | test.cpp:350:15:351:7 | { ... } | +| test.cpp:349:24:349:24 | y | null | test.cpp:349:34:349:34 | 0 | +| test.cpp:349:29:349:30 | 42 | not 0 | test.cpp:350:15:351:7 | { ... } | +| test.cpp:350:7:350:7 | x | not 0 | test.cpp:350:15:351:7 | { ... } | +| test.cpp:350:7:350:12 | ... != ... | true | test.cpp:350:15:351:7 | { ... } | +| test.cpp:355:25:355:29 | input | not null | test.cpp:357:3:357:13 | return ... | +| test.cpp:355:25:355:29 | input | null | test.cpp:356:25:356:36 | return ... | +| test.cpp:356:7:356:11 | input | not null | test.cpp:357:3:357:13 | return ... | +| test.cpp:356:7:356:11 | input | null | test.cpp:356:25:356:36 | return ... | +| test.cpp:356:7:356:22 | ... == ... | false | test.cpp:357:3:357:13 | return ... | +| test.cpp:356:7:356:22 | ... == ... | true | test.cpp:356:25:356:36 | return ... | +| test.cpp:360:26:360:31 | number | not null | test.cpp:361:35:361:40 | number | +| test.cpp:360:26:360:31 | number | null | test.cpp:361:30:361:30 | 0 | +| test.cpp:361:10:361:15 | number | not null | test.cpp:361:35:361:40 | number | +| test.cpp:361:10:361:15 | number | null | test.cpp:361:30:361:30 | 0 | +| test.cpp:361:10:361:26 | ... == ... | false | test.cpp:361:35:361:40 | number | +| test.cpp:361:10:361:26 | ... == ... | true | test.cpp:361:30:361:30 | 0 | +| test.cpp:364:33:364:34 | s1 | not null | test.cpp:365:15:365:16 | s2 | +| test.cpp:364:33:364:34 | s1 | not null | test.cpp:366:3:366:12 | return ... | +| test.cpp:364:43:364:44 | s2 | not null | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:9 | ! ... | false | test.cpp:365:15:365:16 | s2 | +| test.cpp:365:7:365:9 | ! ... | false | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:16 | ... \|\| ... | false | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:8:365:9 | s1 | not null | test.cpp:365:15:365:16 | s2 | +| test.cpp:365:8:365:9 | s1 | not null | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:8:365:9 | s1 | true | test.cpp:365:15:365:16 | s2 | +| test.cpp:365:8:365:9 | s1 | true | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:14:365:16 | ! ... | false | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:15:365:16 | s2 | not null | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:15:365:16 | s2 | true | test.cpp:366:3:366:12 | return ... | +| test.cpp:371:29:371:32 | flag | false | test.cpp:372:35:372:49 | FAILURE | +| test.cpp:371:29:371:32 | flag | true | test.cpp:372:17:372:31 | SUCCESS | +| test.cpp:372:10:372:13 | flag | false | test.cpp:372:35:372:49 | FAILURE | +| test.cpp:372:10:372:13 | flag | true | test.cpp:372:17:372:31 | SUCCESS | +| test.cpp:375:25:375:25 | p | not null | test.cpp:376:24:377:7 | { ... } | +| test.cpp:375:25:375:25 | p | null | test.cpp:378:10:379:7 | { ... } | +| test.cpp:375:33:375:33 | i | not null | test.cpp:390:10:391:7 | { ... } | +| test.cpp:375:50:375:50 | b | false | test.cpp:404:5:406:12 | case ...: | +| test.cpp:375:50:375:50 | b | true | test.cpp:401:5:403:12 | case ...: | +| test.cpp:376:7:376:18 | call to testNotNull1 | false | test.cpp:378:10:379:7 | { ... } | +| test.cpp:376:7:376:18 | call to testNotNull1 | true | test.cpp:376:24:377:7 | { ... } | +| test.cpp:376:20:376:20 | p | not null | test.cpp:376:24:377:7 | { ... } | +| test.cpp:376:20:376:20 | p | null | test.cpp:378:10:379:7 | { ... } | +| test.cpp:382:7:382:18 | call to testNotNull2 | false | test.cpp:384:10:385:7 | { ... } | +| test.cpp:382:7:382:18 | call to testNotNull2 | true | test.cpp:382:24:383:7 | { ... } | +| test.cpp:388:7:388:29 | ... == ... | false | test.cpp:390:10:391:7 | { ... } | +| test.cpp:388:7:388:29 | ... == ... | true | test.cpp:388:32:389:7 | { ... } | +| test.cpp:388:12:388:26 | call to getNumOrDefault | 0 | test.cpp:388:32:389:7 | { ... } | +| test.cpp:388:12:388:26 | call to getNumOrDefault | not 0 | test.cpp:390:10:391:7 | { ... } | +| test.cpp:388:28:388:28 | i | not null | test.cpp:390:10:391:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | false | test.cpp:396:10:397:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | true | test.cpp:394:50:395:7 | { ... } | +| test.cpp:394:15:394:34 | call to returnAIfNoneAreNull | 0 | test.cpp:394:50:395:7 | { ... } | +| test.cpp:394:15:394:34 | call to returnAIfNoneAreNull | not 0 | test.cpp:396:10:397:7 | { ... } | +| test.cpp:400:11:400:25 | call to testEnumWrapper | 1 | test.cpp:401:5:403:12 | case ...: | +| test.cpp:400:11:400:25 | call to testEnumWrapper | 2 | test.cpp:404:5:406:12 | case ...: | +| test.cpp:400:27:400:27 | b | false | test.cpp:404:5:406:12 | case ...: | +| test.cpp:400:27:400:27 | b | true | test.cpp:401:5:403:12 | case ...: | +| test.cpp:410:26:410:26 | o | not null | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:410:26:410:26 | o | not null | test.cpp:412:1:412:1 | return ... | +| test.cpp:410:26:410:26 | o | null | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:410:26:410:26 | o | null | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:7:411:8 | ! ... | false | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:7:411:8 | ! ... | false | test.cpp:412:1:412:1 | return ... | +| test.cpp:411:7:411:8 | ! ... | true | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:7:411:8 | ! ... | true | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:8:411:8 | o | false | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | false | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:8:411:8 | o | not null | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | not null | test.cpp:412:1:412:1 | return ... | +| test.cpp:411:8:411:8 | o | null | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | null | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:8:411:8 | o | true | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | true | test.cpp:412:1:412:1 | return ... | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index 1f0b11972301..0de63fa505b4 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -483,6 +483,24 @@ binary | test.cpp:318:6:318:18 | ... != ... | test.cpp:318:11:318:12 | 42 | >= | test.cpp:318:7:318:7 | a | 1 | test.cpp:318:21:320:3 | { ... } | | test.cpp:318:6:318:18 | ... != ... | test.cpp:318:18:318:18 | 0 | != | test.cpp:318:7:318:12 | ... < ... | 0 | test.cpp:318:21:320:3 | { ... } | | test.cpp:318:6:318:18 | ... != ... | test.cpp:318:18:318:18 | 0 | == | test.cpp:318:7:318:12 | ... < ... | 0 | test.cpp:320:10:322:3 | { ... } | +| test.cpp:350:7:350:12 | ... != ... | test.cpp:350:7:350:7 | x | != | test.cpp:350:12:350:12 | 0 | 0 | test.cpp:350:15:351:7 | { ... } | +| test.cpp:350:7:350:12 | ... != ... | test.cpp:350:12:350:12 | 0 | != | test.cpp:350:7:350:7 | x | 0 | test.cpp:350:15:351:7 | { ... } | +| test.cpp:356:7:356:22 | ... == ... | test.cpp:356:7:356:11 | input | != | test.cpp:356:16:356:22 | 0 | 0 | test.cpp:357:3:357:13 | return ... | +| test.cpp:356:7:356:22 | ... == ... | test.cpp:356:7:356:11 | input | == | test.cpp:356:16:356:22 | 0 | 0 | test.cpp:356:25:356:36 | return ... | +| test.cpp:356:7:356:22 | ... == ... | test.cpp:356:16:356:22 | 0 | != | test.cpp:356:7:356:11 | input | 0 | test.cpp:357:3:357:13 | return ... | +| test.cpp:356:7:356:22 | ... == ... | test.cpp:356:16:356:22 | 0 | == | test.cpp:356:7:356:11 | input | 0 | test.cpp:356:25:356:36 | return ... | +| test.cpp:361:10:361:26 | ... == ... | test.cpp:361:10:361:15 | number | != | test.cpp:361:20:361:26 | 0 | 0 | test.cpp:361:35:361:40 | number | +| test.cpp:361:10:361:26 | ... == ... | test.cpp:361:10:361:15 | number | == | test.cpp:361:20:361:26 | 0 | 0 | test.cpp:361:30:361:30 | 0 | +| test.cpp:361:10:361:26 | ... == ... | test.cpp:361:20:361:26 | 0 | != | test.cpp:361:10:361:15 | number | 0 | test.cpp:361:35:361:40 | number | +| test.cpp:361:10:361:26 | ... == ... | test.cpp:361:20:361:26 | 0 | == | test.cpp:361:10:361:15 | number | 0 | test.cpp:361:30:361:30 | 0 | +| test.cpp:388:7:388:29 | ... == ... | test.cpp:388:7:388:7 | 0 | != | test.cpp:388:12:388:26 | call to getNumOrDefault | 0 | test.cpp:390:10:391:7 | { ... } | +| test.cpp:388:7:388:29 | ... == ... | test.cpp:388:7:388:7 | 0 | == | test.cpp:388:12:388:26 | call to getNumOrDefault | 0 | test.cpp:388:32:389:7 | { ... } | +| test.cpp:388:7:388:29 | ... == ... | test.cpp:388:12:388:26 | call to getNumOrDefault | != | test.cpp:388:7:388:7 | 0 | 0 | test.cpp:390:10:391:7 | { ... } | +| test.cpp:388:7:388:29 | ... == ... | test.cpp:388:12:388:26 | call to getNumOrDefault | == | test.cpp:388:7:388:7 | 0 | 0 | test.cpp:388:32:389:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:7:394:10 | 0 | != | test.cpp:394:15:394:34 | call to returnAIfNoneAreNull | 0 | test.cpp:396:10:397:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:7:394:10 | 0 | == | test.cpp:394:15:394:34 | call to returnAIfNoneAreNull | 0 | test.cpp:394:50:395:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:15:394:34 | call to returnAIfNoneAreNull | != | test.cpp:394:7:394:10 | 0 | 0 | test.cpp:396:10:397:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:15:394:34 | call to returnAIfNoneAreNull | == | test.cpp:394:7:394:10 | 0 | 0 | test.cpp:394:50:395:7 | { ... } | unary | test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | 1 | test.c:10:12:11:14 | { ... } | | test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | 1 | test.c:7:16:9:14 | { ... } | @@ -1300,3 +1318,118 @@ unary | test.cpp:330:7:330:7 | b | test.cpp:330:7:330:7 | b | == | 1 | test.cpp:331:3:332:10 | { ... } | | test.cpp:334:11:334:11 | x | test.cpp:334:11:334:11 | x | < | 51 | test.cpp:336:3:338:7 | case ...: | | test.cpp:334:11:334:11 | x | test.cpp:334:11:334:11 | x | >= | 40 | test.cpp:336:3:338:7 | case ...: | +| test.cpp:349:11:349:22 | call to testNotNull1 | test.cpp:349:11:349:22 | call to testNotNull1 | != | 0 | test.cpp:349:29:349:30 | 42 | +| test.cpp:349:11:349:22 | call to testNotNull1 | test.cpp:349:11:349:22 | call to testNotNull1 | != | 0 | test.cpp:350:15:351:7 | { ... } | +| test.cpp:349:11:349:22 | call to testNotNull1 | test.cpp:349:11:349:22 | call to testNotNull1 | != | 1 | test.cpp:349:34:349:34 | 0 | +| test.cpp:349:11:349:22 | call to testNotNull1 | test.cpp:349:11:349:22 | call to testNotNull1 | == | 0 | test.cpp:349:34:349:34 | 0 | +| test.cpp:349:11:349:22 | call to testNotNull1 | test.cpp:349:11:349:22 | call to testNotNull1 | == | 1 | test.cpp:349:29:349:30 | 42 | +| test.cpp:349:11:349:22 | call to testNotNull1 | test.cpp:349:11:349:22 | call to testNotNull1 | == | 1 | test.cpp:350:15:351:7 | { ... } | +| test.cpp:350:7:350:12 | ... != ... | test.cpp:350:7:350:7 | x | != | 0 | test.cpp:350:15:351:7 | { ... } | +| test.cpp:350:7:350:12 | ... != ... | test.cpp:350:7:350:12 | ... != ... | != | 0 | test.cpp:350:15:351:7 | { ... } | +| test.cpp:350:7:350:12 | ... != ... | test.cpp:350:7:350:12 | ... != ... | == | 1 | test.cpp:350:15:351:7 | { ... } | +| test.cpp:356:7:356:22 | ... == ... | test.cpp:356:7:356:11 | input | != | 0 | test.cpp:357:3:357:13 | return ... | +| test.cpp:356:7:356:22 | ... == ... | test.cpp:356:7:356:11 | input | == | 0 | test.cpp:356:25:356:36 | return ... | +| test.cpp:356:7:356:22 | ... == ... | test.cpp:356:7:356:22 | ... == ... | != | 0 | test.cpp:356:25:356:36 | return ... | +| test.cpp:356:7:356:22 | ... == ... | test.cpp:356:7:356:22 | ... == ... | != | 1 | test.cpp:357:3:357:13 | return ... | +| test.cpp:356:7:356:22 | ... == ... | test.cpp:356:7:356:22 | ... == ... | == | 0 | test.cpp:357:3:357:13 | return ... | +| test.cpp:356:7:356:22 | ... == ... | test.cpp:356:7:356:22 | ... == ... | == | 1 | test.cpp:356:25:356:36 | return ... | +| test.cpp:361:10:361:26 | ... == ... | test.cpp:361:10:361:15 | number | != | 0 | test.cpp:361:35:361:40 | number | +| test.cpp:361:10:361:26 | ... == ... | test.cpp:361:10:361:15 | number | == | 0 | test.cpp:361:30:361:30 | 0 | +| test.cpp:361:10:361:26 | ... == ... | test.cpp:361:10:361:26 | ... == ... | != | 0 | test.cpp:361:30:361:30 | 0 | +| test.cpp:361:10:361:26 | ... == ... | test.cpp:361:10:361:26 | ... == ... | != | 1 | test.cpp:361:35:361:40 | number | +| test.cpp:361:10:361:26 | ... == ... | test.cpp:361:10:361:26 | ... == ... | == | 0 | test.cpp:361:35:361:40 | number | +| test.cpp:361:10:361:26 | ... == ... | test.cpp:361:10:361:26 | ... == ... | == | 1 | test.cpp:361:30:361:30 | 0 | +| test.cpp:365:7:365:9 | ! ... | test.cpp:365:7:365:9 | ! ... | != | 1 | test.cpp:365:15:365:16 | s2 | +| test.cpp:365:7:365:9 | ! ... | test.cpp:365:7:365:9 | ! ... | != | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:9 | ! ... | test.cpp:365:7:365:9 | ! ... | == | 0 | test.cpp:365:15:365:16 | s2 | +| test.cpp:365:7:365:9 | ! ... | test.cpp:365:7:365:9 | ! ... | == | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:9 | ! ... | test.cpp:365:8:365:9 | s1 | != | 0 | test.cpp:365:15:365:16 | s2 | +| test.cpp:365:7:365:9 | ! ... | test.cpp:365:8:365:9 | s1 | != | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:9 | ! ... | test.cpp:365:8:365:9 | s1 | == | 1 | test.cpp:365:15:365:16 | s2 | +| test.cpp:365:7:365:9 | ! ... | test.cpp:365:8:365:9 | s1 | == | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:16 | ... \|\| ... | test.cpp:365:7:365:9 | ! ... | != | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:16 | ... \|\| ... | test.cpp:365:7:365:9 | ! ... | == | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:16 | ... \|\| ... | test.cpp:365:8:365:9 | s1 | != | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:16 | ... \|\| ... | test.cpp:365:8:365:9 | s1 | == | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:16 | ... \|\| ... | test.cpp:365:14:365:16 | ! ... | != | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:16 | ... \|\| ... | test.cpp:365:14:365:16 | ! ... | == | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:16 | ... \|\| ... | test.cpp:365:15:365:16 | s2 | != | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:7:365:16 | ... \|\| ... | test.cpp:365:15:365:16 | s2 | == | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:8:365:9 | s1 | test.cpp:365:7:365:9 | ! ... | != | 1 | test.cpp:365:15:365:16 | s2 | +| test.cpp:365:8:365:9 | s1 | test.cpp:365:7:365:9 | ! ... | != | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:8:365:9 | s1 | test.cpp:365:7:365:9 | ! ... | == | 0 | test.cpp:365:15:365:16 | s2 | +| test.cpp:365:8:365:9 | s1 | test.cpp:365:7:365:9 | ! ... | == | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:8:365:9 | s1 | test.cpp:365:8:365:9 | s1 | != | 0 | test.cpp:365:15:365:16 | s2 | +| test.cpp:365:8:365:9 | s1 | test.cpp:365:8:365:9 | s1 | != | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:8:365:9 | s1 | test.cpp:365:8:365:9 | s1 | == | 1 | test.cpp:365:15:365:16 | s2 | +| test.cpp:365:8:365:9 | s1 | test.cpp:365:8:365:9 | s1 | == | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:14:365:16 | ! ... | test.cpp:365:14:365:16 | ! ... | != | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:14:365:16 | ! ... | test.cpp:365:14:365:16 | ! ... | == | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:14:365:16 | ! ... | test.cpp:365:15:365:16 | s2 | != | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:14:365:16 | ! ... | test.cpp:365:15:365:16 | s2 | == | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:15:365:16 | s2 | test.cpp:365:14:365:16 | ! ... | != | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:15:365:16 | s2 | test.cpp:365:14:365:16 | ! ... | == | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:15:365:16 | s2 | test.cpp:365:15:365:16 | s2 | != | 0 | test.cpp:366:3:366:12 | return ... | +| test.cpp:365:15:365:16 | s2 | test.cpp:365:15:365:16 | s2 | == | 1 | test.cpp:366:3:366:12 | return ... | +| test.cpp:371:29:371:32 | flag | test.cpp:372:10:372:13 | flag | != | 0 | test.cpp:372:17:372:31 | SUCCESS | +| test.cpp:371:29:371:32 | flag | test.cpp:372:10:372:13 | flag | != | 1 | test.cpp:372:35:372:49 | FAILURE | +| test.cpp:371:29:371:32 | flag | test.cpp:372:10:372:13 | flag | == | 0 | test.cpp:372:35:372:49 | FAILURE | +| test.cpp:371:29:371:32 | flag | test.cpp:372:10:372:13 | flag | == | 1 | test.cpp:372:17:372:31 | SUCCESS | +| test.cpp:372:10:372:13 | flag | test.cpp:372:10:372:13 | flag | != | 0 | test.cpp:372:17:372:31 | SUCCESS | +| test.cpp:372:10:372:13 | flag | test.cpp:372:10:372:13 | flag | != | 1 | test.cpp:372:35:372:49 | FAILURE | +| test.cpp:372:10:372:13 | flag | test.cpp:372:10:372:13 | flag | == | 0 | test.cpp:372:35:372:49 | FAILURE | +| test.cpp:372:10:372:13 | flag | test.cpp:372:10:372:13 | flag | == | 1 | test.cpp:372:17:372:31 | SUCCESS | +| test.cpp:376:7:376:18 | call to testNotNull1 | test.cpp:376:7:376:18 | call to testNotNull1 | != | 0 | test.cpp:376:24:377:7 | { ... } | +| test.cpp:376:7:376:18 | call to testNotNull1 | test.cpp:376:7:376:18 | call to testNotNull1 | != | 1 | test.cpp:378:10:379:7 | { ... } | +| test.cpp:376:7:376:18 | call to testNotNull1 | test.cpp:376:7:376:18 | call to testNotNull1 | == | 0 | test.cpp:378:10:379:7 | { ... } | +| test.cpp:376:7:376:18 | call to testNotNull1 | test.cpp:376:7:376:18 | call to testNotNull1 | == | 1 | test.cpp:376:24:377:7 | { ... } | +| test.cpp:382:7:382:18 | call to testNotNull2 | test.cpp:382:7:382:18 | call to testNotNull2 | != | 0 | test.cpp:382:24:383:7 | { ... } | +| test.cpp:382:7:382:18 | call to testNotNull2 | test.cpp:382:7:382:18 | call to testNotNull2 | != | 1 | test.cpp:384:10:385:7 | { ... } | +| test.cpp:382:7:382:18 | call to testNotNull2 | test.cpp:382:7:382:18 | call to testNotNull2 | == | 0 | test.cpp:384:10:385:7 | { ... } | +| test.cpp:382:7:382:18 | call to testNotNull2 | test.cpp:382:7:382:18 | call to testNotNull2 | == | 1 | test.cpp:382:24:383:7 | { ... } | +| test.cpp:388:7:388:29 | ... == ... | test.cpp:388:7:388:29 | ... == ... | != | 0 | test.cpp:388:32:389:7 | { ... } | +| test.cpp:388:7:388:29 | ... == ... | test.cpp:388:7:388:29 | ... == ... | != | 1 | test.cpp:390:10:391:7 | { ... } | +| test.cpp:388:7:388:29 | ... == ... | test.cpp:388:7:388:29 | ... == ... | == | 0 | test.cpp:390:10:391:7 | { ... } | +| test.cpp:388:7:388:29 | ... == ... | test.cpp:388:7:388:29 | ... == ... | == | 1 | test.cpp:388:32:389:7 | { ... } | +| test.cpp:388:7:388:29 | ... == ... | test.cpp:388:12:388:26 | call to getNumOrDefault | != | 0 | test.cpp:390:10:391:7 | { ... } | +| test.cpp:388:7:388:29 | ... == ... | test.cpp:388:12:388:26 | call to getNumOrDefault | == | 0 | test.cpp:388:32:389:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:7:394:47 | ... == ... | != | 0 | test.cpp:394:50:395:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:7:394:47 | ... == ... | != | 1 | test.cpp:396:10:397:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:7:394:47 | ... == ... | == | 0 | test.cpp:396:10:397:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:7:394:47 | ... == ... | == | 1 | test.cpp:394:50:395:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:15:394:34 | call to returnAIfNoneAreNull | != | 0 | test.cpp:396:10:397:7 | { ... } | +| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:15:394:34 | call to returnAIfNoneAreNull | == | 0 | test.cpp:394:50:395:7 | { ... } | +| test.cpp:400:11:400:25 | call to testEnumWrapper | test.cpp:400:11:400:25 | call to testEnumWrapper | == | 1 | test.cpp:401:5:403:12 | case ...: | +| test.cpp:400:11:400:25 | call to testEnumWrapper | test.cpp:400:11:400:25 | call to testEnumWrapper | == | 2 | test.cpp:404:5:406:12 | case ...: | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:412:1:412:1 | return ... | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:412:1:412:1 | return ... | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:412:1:412:1 | return ... | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:412:1:412:1 | return ... | +| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:412:1:412:1 | return ... | +| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:412:1:412:1 | return ... | +| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:412:1:412:1 | return ... | +| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:411:11:411:18 | ExprStmt | +| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:410:6:410:18 | ensureNotNull | +| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:412:1:412:1 | return ... | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsInline.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsInline.expected new file mode 100644 index 000000000000..8beb8bb2b151 --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsInline.expected @@ -0,0 +1,27 @@ +| test.cpp:351:5:351:7 | Call: call to chk | '42:not 0' | +| test.cpp:351:5:351:7 | Call: call to chk | '... ? ... : ...:not 0' | +| test.cpp:351:5:351:7 | Call: call to chk | 'call to testNotNull1:true' | +| test.cpp:351:5:351:7 | Call: call to chk | 'x != 0:true' | +| test.cpp:351:5:351:7 | Call: call to chk | 'x:not 0' | +| test.cpp:351:5:351:7 | Call: call to chk | 'y:not null' | +| test.cpp:377:5:377:7 | Call: call to chk | 'call to testNotNull1:true' | +| test.cpp:377:5:377:7 | Call: call to chk | 'p:not null' | +| test.cpp:379:5:379:7 | Call: call to chk | 'call to testNotNull1:false' | +| test.cpp:379:5:379:7 | Call: call to chk | p:null | +| test.cpp:383:5:383:7 | Call: call to chk | 'call to testNotNull2:true' | +| test.cpp:385:5:385:7 | Call: call to chk | 'call to testNotNull2:false' | +| test.cpp:389:5:389:7 | Call: call to chk | '0 == call to getNumOrDefault:true' | +| test.cpp:389:5:389:7 | Call: call to chk | 'call to getNumOrDefault:0' | +| test.cpp:391:5:391:7 | Call: call to chk | '0 == call to getNumOrDefault:false' | +| test.cpp:391:5:391:7 | Call: call to chk | 'call to getNumOrDefault:not 0' | +| test.cpp:391:5:391:7 | Call: call to chk | 'i:not null' | +| test.cpp:395:5:395:7 | Call: call to chk | '0 == call to returnAIfNoneAreNull:true' | +| test.cpp:395:5:395:7 | Call: call to chk | 'call to returnAIfNoneAreNull:0' | +| test.cpp:397:5:397:7 | Call: call to chk | '0 == call to returnAIfNoneAreNull:false' | +| test.cpp:397:5:397:7 | Call: call to chk | 'call to returnAIfNoneAreNull:not 0' | +| test.cpp:402:7:402:9 | Call: call to chk | 'call to testEnumWrapper:1' | +| test.cpp:402:7:402:9 | Call: call to chk | 'call to testEnumWrapper=SUCCESS:true' | +| test.cpp:402:7:402:9 | Call: call to chk | b:true | +| test.cpp:405:7:405:9 | Call: call to chk | 'call to testEnumWrapper:2' | +| test.cpp:405:7:405:9 | Call: call to chk | 'call to testEnumWrapper=FAILURE:true' | +| test.cpp:405:7:405:9 | Call: call to chk | b:false | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsInline.ql b/cpp/ql/test/library-tests/controlflow/guards/GuardsInline.ql new file mode 100644 index 000000000000..a6875080d370 --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsInline.ql @@ -0,0 +1,44 @@ +import cpp +import semmle.code.cpp.controlflow.Guards +import codeql.util.Boolean + +bindingset[s] +string escape(string s) { if s.matches("% %") then result = "'" + s + "'" else result = s } + +Expr getUnconverted(Element e) { + not e instanceof Expr and + result = e + or + result = e.(Expr).getUnconverted() +} + +string ppGuard(IRGuardCondition g, GuardValue val) { + exists(BinaryOperation bin | + bin = getUnconverted(g.getAst()) and + result = + bin.getLeftOperand() + " " + bin.getOperator() + " " + bin.getRightOperand() + ":" + val + ) + or + exists(SwitchCase cc, Expr s, string value | + cc = g.getAst() and + cc.getExpr() = s and + result = cc.getSwitchStmt().getExpr() + "=" + value + ":" + val + | + value = cc.getExpr().toString() + or + cc.isDefault() and value = "default" + ) +} + +query predicate guarded(CallInstruction c, string guard) { + c.getStaticCallTarget().hasName("chk") and + exists(IRGuardCondition g, IRBlock bb, GuardValue val | + g.valueControls(bb, val) and + c.getBlock() = bb + | + guard = escape(ppGuard(g, val)) + or + not exists(ppGuard(g, val)) and + guard = escape(getUnconverted(g.getAst()).toString() + ":" + val) + ) +} diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsInline.qlref b/cpp/ql/test/library-tests/controlflow/guards/GuardsInline.qlref new file mode 100644 index 000000000000..5a66d6da1a0a --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsInline.qlref @@ -0,0 +1,2 @@ +query: GuardsInline.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/cpp/ql/test/library-tests/controlflow/guards/test.cpp b/cpp/ql/test/library-tests/controlflow/guards/test.cpp index bb0fe83c7c72..49772506351d 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/test.cpp +++ b/cpp/ql/test/library-tests/controlflow/guards/test.cpp @@ -337,4 +337,82 @@ void test_constant_value_and_case_range(bool b) // should not be guarded by `foo() = 40..50` use(x); } -} \ No newline at end of file +} + +void chk(); + +bool testNotNull1(void* input) { + return input != nullptr; +} + +void test_ternary(void* y) { + int x = testNotNull1(y) ? 42 : 0; + if (x != 0) { + chk(); // $ guarded='... ? ... : ...:not 0' guarded='42:not 0' guarded='call to testNotNull1:true' guarded='x != 0:true' guarded='x:not 0' guarded='y:not null' + } +} + +bool testNotNull2(void* input) { + if (input == nullptr) return false; + return true; +} + +int getNumOrDefault(int* number) { + return number == nullptr ? 0 : *number; +} + +char returnAIfNoneAreNull(char* s1, char* s2) { + if (!s1 || !s2) return '\0'; + return 'a'; +} + +enum class Status { SUCCESS = 1, FAILURE = 2 }; + +Status testEnumWrapper(bool flag) { + return flag ? Status::SUCCESS : Status::FAILURE; +} + +void testWrappers(void* p, int* i, char* s, bool b) { + if (testNotNull1(p)) { + chk(); // $ guarded='p:not null' guarded='call to testNotNull1:true' + } else { + chk(); // $ guarded=p:null guarded='call to testNotNull1:false' + } + + if (testNotNull2(p)) { + chk(); // $ guarded='call to testNotNull2:true' MISSING: guarded='p:not null' + } else { + chk(); // $ guarded='call to testNotNull2:false' + } + + if (0 == getNumOrDefault(i)) { + chk(); // $ guarded='0 == call to getNumOrDefault:true' guarded='call to getNumOrDefault:0' + } else { + chk(); // $ guarded='0 == call to getNumOrDefault:false' guarded='call to getNumOrDefault:not 0' guarded='i:not null' + } + + if ('\0' == returnAIfNoneAreNull(s, "suffix")) { + chk(); // $ guarded='0 == call to returnAIfNoneAreNull:true' guarded='call to returnAIfNoneAreNull:0' + } else { + chk(); // $ guarded='0 == call to returnAIfNoneAreNull:false' guarded='call to returnAIfNoneAreNull:not 0' MISSING: guarded='s:not null' + } + + switch (testEnumWrapper(b)) { + case Status::SUCCESS: + chk(); // $ guarded='call to testEnumWrapper=SUCCESS:true' guarded='call to testEnumWrapper:1' guarded=b:true + break; + case Status::FAILURE: + chk(); // $ guarded='call to testEnumWrapper=FAILURE:true' guarded='call to testEnumWrapper:2' guarded=b:false + break; + } +} + +void ensureNotNull(void* o) { + if (!o) throw 42; +} + +void testExceptionWrapper(void* s) { + chk(); // nothing guards here + ensureNotNull(s); + chk(); // $ MISSING: guarded='call to ensureNotNull:no exception' guarded='s:not null' +} From 26a8a4b3d26422f315d7df90405c1e6f90376d48 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 24 Sep 2025 19:54:05 +0100 Subject: [PATCH 27/35] C++: Add failing test demonstrating broken wrapper barrier guards. --- .../dataflow/dataflow-tests/BarrierGuard.cpp | 18 ++++++++++++++++++ .../dataflow-tests/test-source-sink.expected | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp index 71d22ad4eddc..b08c2a7e8d42 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp @@ -125,4 +125,22 @@ void test_phi_read_guard_2(bool b) { } sink(x); // $ SPURIOUS: ast +} + +bool guarded_wrapper(int x) { + if(guarded(x)) { + return true; + } else { + return false; + } +} + +void test_guarded_wrapper() { + int x = source(); + + if(guarded_wrapper(x)) { + sink(x); // $ SPURIOUS: ast,ir + } else { + sink(x); // $ ast,ir + } } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected index 8c009241734a..92d792a67aca 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected @@ -16,6 +16,8 @@ astFlow | BarrierGuard.cpp:90:11:90:16 | call to source | BarrierGuard.cpp:101:8:101:8 | x | | BarrierGuard.cpp:107:11:107:16 | call to source | BarrierGuard.cpp:112:8:112:8 | x | | BarrierGuard.cpp:116:11:116:16 | call to source | BarrierGuard.cpp:127:8:127:8 | x | +| BarrierGuard.cpp:139:11:139:16 | call to source | BarrierGuard.cpp:142:10:142:10 | x | +| BarrierGuard.cpp:139:11:139:16 | call to source | BarrierGuard.cpp:144:10:144:10 | x | | acrossLinkTargets.cpp:19:27:19:32 | call to source | acrossLinkTargets.cpp:12:8:12:8 | x | | clang.cpp:12:9:12:20 | sourceArray1 | clang.cpp:18:8:18:19 | sourceArray1 | | clang.cpp:12:9:12:20 | sourceArray1 | clang.cpp:22:8:22:20 | & ... | @@ -156,6 +158,8 @@ irFlow | BarrierGuard.cpp:49:10:49:15 | call to source | BarrierGuard.cpp:55:13:55:13 | x | | BarrierGuard.cpp:60:11:60:16 | call to source | BarrierGuard.cpp:64:14:64:14 | x | | BarrierGuard.cpp:60:11:60:16 | call to source | BarrierGuard.cpp:66:14:66:14 | x | +| BarrierGuard.cpp:139:11:139:16 | call to source | BarrierGuard.cpp:142:10:142:10 | x | +| BarrierGuard.cpp:139:11:139:16 | call to source | BarrierGuard.cpp:144:10:144:10 | x | | acrossLinkTargets.cpp:19:27:19:32 | call to source | acrossLinkTargets.cpp:12:8:12:8 | x | | clang.cpp:12:9:12:20 | sourceArray1 | clang.cpp:18:8:18:19 | sourceArray1 | | clang.cpp:12:9:12:20 | sourceArray1 | clang.cpp:23:17:23:29 | *& ... | From a07d03f49b74e65d3143bc5a3c4dd561ad5ed634 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 24 Sep 2025 20:02:40 +0100 Subject: [PATCH 28/35] C++: Use the 'StoreInstruction' instead of the 'ReturnValueInstruction' when detecting return expressions. --- .../semmle/code/cpp/controlflow/IRGuards.qll | 27 ++++++++++++++++--- .../controlflow/guards/GuardsControl.expected | 7 +++++ .../controlflow/guards/GuardsInline.expected | 4 +++ .../library-tests/controlflow/guards/test.cpp | 6 ++--- .../dataflow/dataflow-tests/BarrierGuard.cpp | 2 +- .../dataflow-tests/test-source-sink.expected | 1 - 6 files changed, 39 insertions(+), 8 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 76cccb4a6251..eed38315f5c5 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -361,9 +361,30 @@ module GuardsInput implements SharedGuards::InputSig Date: Thu, 25 Sep 2025 08:30:42 +0100 Subject: [PATCH 29/35] C++: Fully delete TRange. --- .../semmle/code/cpp/controlflow/IRGuards.qll | 45 ++----------------- 1 file changed, 4 insertions(+), 41 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index eed38315f5c5..b49942f4006a 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -30,35 +30,10 @@ module GuardsInput implements SharedGuards::InputSig Date: Thu, 25 Sep 2025 12:33:44 +0100 Subject: [PATCH 30/35] C++: Fix fan-out. --- cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll | 2 +- .../library-tests/controlflow/guards/GuardsControl.expected | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index b49942f4006a..b7ad7e56d2a1 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -188,7 +188,7 @@ module GuardsInput implements SharedGuards::InputSig Date: Thu, 25 Sep 2025 12:43:57 +0100 Subject: [PATCH 31/35] C++: Add more comments to describe the constant expression hack. --- cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index b7ad7e56d2a1..91b6334922d4 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -97,9 +97,14 @@ module GuardsInput implements SharedGuards::InputSig Date: Thu, 25 Sep 2025 12:56:46 +0100 Subject: [PATCH 32/35] C++: Delete incorrect comment and add a bunch of barrier guard tests. --- .../semmle/code/cpp/controlflow/IRGuards.qll | 20 +------- .../dataflow/dataflow-tests/BarrierGuard.cpp | 47 ++++++++++++++++++- .../dataflow-tests/test-source-sink.expected | 15 ++++-- 3 files changed, 59 insertions(+), 23 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 91b6334922d4..042f815ac80c 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -342,25 +342,7 @@ module GuardsInput implements SharedGuards::InputSig Date: Tue, 30 Sep 2025 14:14:19 +0100 Subject: [PATCH 33/35] Update cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll Co-authored-by: Anders Schack-Mulligen --- cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 042f815ac80c..b41a484eedc3 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -322,7 +322,7 @@ module GuardsInput implements SharedGuards::InputSig Date: Tue, 30 Sep 2025 14:15:55 +0100 Subject: [PATCH 34/35] C++: Update QLDoc. --- cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index b41a484eedc3..e9ff5dbf5e48 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -63,8 +63,8 @@ module GuardsInput implements SharedGuards::InputSig Date: Wed, 1 Oct 2025 11:33:47 +0100 Subject: [PATCH 35/35] C++: Port a test from the experimental directory to show that it works in the non-experimental "new" range analysis. --- cpp/ql/test/library-tests/ir/range-analysis/test.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp index 7234449a4ed2..0c1a98b06bb7 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp @@ -145,4 +145,15 @@ void nonterminating_without_operands_as_ssa(X *x) { while (x->n) { x->n--; } +} + +void test_with_irreduble_cfg(int i, int x) { + if (x < i) { + } else { + goto inLoop; + } + for(; i < x; i++) { + inLoop: + range(i); // $ range="<=InitializeParameter: x+0" + } } \ No newline at end of file