diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll index 26fc341735b3e..8d4beb36c2459 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll @@ -5,6 +5,7 @@ private import semmle.code.cpp.ir.internal.CppType private import semmle.code.cpp.ir.internal.IRUtilities private import semmle.code.cpp.ir.implementation.internal.OperandTag private import semmle.code.cpp.ir.internal.TempVariableTag +private import semmle.code.cpp.models.interfaces.Throwing private import InstructionTag private import TranslatedElement private import TranslatedExpr @@ -209,8 +210,15 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction { ( // Only generate the `Unwind` instruction if there is any exception // handling present in the function. - exists(TryStmt try | try.getEnclosingFunction() = func) or + exists(TryStmt try | try.getEnclosingFunction() = func) + or + exists(MicrosoftTryStmt try | try.getEnclosingFunction() = func) + or exists(ThrowExpr throw | throw.getEnclosingFunction() = func) + or + exists(ThrowingFunction throwingFunc, FunctionCall call | throwingFunc.mayThrowException(true) | + call.getEnclosingFunction() = func and call.getTarget() = throwingFunc + ) ) or tag = AliasedUseTag() and diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll index d04514c31aab4..73bcfadf9f47e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll @@ -79,11 +79,6 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement, tag = TryExceptCompareOneBranch() and opcode instanceof Opcode::ConditionalBranch and resultType = getVoidType() - or - // unwind stack - tag = UnwindTag() and - opcode instanceof Opcode::Unwind and - resultType = getVoidType() } final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { @@ -156,7 +151,7 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement, // TODO: This is not really correct. The semantics of `EXCEPTION_CONTINUE_EXECUTION` is that // we should continue execution at the point where the exception occurred. But we don't have // any instruction to model this behavior. - result = this.getInstruction(UnwindTag()) + result = this.getExceptionSuccessorInstruction(any(GotoEdge edge)) or kind instanceof FalseEdge and result = this.getInstruction(TryExceptGenerateZero()) @@ -176,7 +171,7 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement, tag = TryExceptCompareZeroBranch() and ( kind instanceof TrueEdge and - result = this.getInstruction(UnwindTag()) + result = this.getExceptionSuccessorInstruction(any(GotoEdge edge)) or kind instanceof FalseEdge and result = this.getInstruction(TryExceptGenerateOne()) @@ -196,10 +191,6 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement, tag = TryExceptCompareOneBranch() and kind instanceof TrueEdge and result = this.getTranslatedHandler().getFirstInstruction(any(GotoEdge edge)) - or - // Unwind -> Parent - tag = UnwindTag() and - result = this.getParent().getChildSuccessor(this, kind) } override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { @@ -215,8 +206,6 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement, override Instruction getALastInstructionInternal() { result = this.getTranslatedHandler().getALastInstruction() - or - result = this.getInstruction(UnwindTag()) } private TranslatedExpr getTranslatedCondition() { @@ -236,6 +225,12 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement, } final override Function getFunction() { result = tryExcept.getEnclosingFunction() } + + override Instruction getExceptionSuccessorInstruction(EdgeKind kind) { + // A throw from within a `__except` block flows to the handler for the parent of + // the `__try`. + result = this.getParent().getParent().getExceptionSuccessorInstruction(kind) + } } abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt { diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index c1697f3fc1ab0..2979f18982640 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -3167,41 +3167,45 @@ ir.c: # 36| v36_3(void) = Call[ExRaiseAccessViolation] : func:r36_1, 0:r36_2 # 36| m36_4(unknown) = ^CallSideEffect : ~m32_4 # 36| m36_5(unknown) = Chi : total:m32_4, partial:m36_4 -#-----| Exception -> Block 3 +#-----| Exception -> Block 4 -# 39| Block 1 +# 32| Block 1 +# 32| v32_5(void) = Unwind : +# 32| v32_6(void) = AliasedUse : ~m40_5 +# 32| v32_7(void) = ExitFunction : + +# 39| Block 2 # 39| r39_1(int) = Constant[0] : -# 39| r39_2(bool) = CompareEQ : r38_2, r39_1 +# 39| r39_2(bool) = CompareEQ : r38_1, r39_1 # 39| v39_3(void) = ConditionalBranch : r39_2 -#-----| False (back edge) -> Block 2 -#-----| True -> Block 5 +#-----| False -> Block 3 +#-----| True -> Block 6 -# 39| Block 2 +# 39| Block 3 # 39| r39_4(int) = Constant[1] : -# 39| r39_5(bool) = CompareEQ : r38_2, r39_4 +# 39| r39_5(bool) = CompareEQ : r38_1, r39_4 # 39| v39_6(void) = ConditionalBranch : r39_5 -#-----| False -> Block 5 -#-----| True (back edge) -> Block 4 - -# 38| Block 3 -# 38| m38_1(unknown) = Phi : from 0:~m36_5, from 4:~m40_5 -# 38| r38_2(int) = Constant[1] : -# 39| r39_7(int) = Constant[-1] : -# 39| r39_8(bool) = CompareEQ : r38_2, r39_7 -# 39| v39_9(void) = ConditionalBranch : r39_8 -#-----| False (back edge) -> Block 1 +#-----| False -> Block 6 #-----| True -> Block 5 -# 40| Block 4 +# 38| Block 4 +# 38| r38_1(int) = Constant[1] : +# 39| r39_7(int) = Constant[-1] : +# 39| r39_8(bool) = CompareEQ : r38_1, r39_7 +# 39| v39_9(void) = ConditionalBranch : r39_8 +#-----| False -> Block 2 +#-----| True -> Block 6 + +# 40| Block 5 # 40| r40_1(glval) = FunctionAddress[ExRaiseAccessViolation] : # 40| r40_2(int) = Constant[1] : # 40| v40_3(void) = Call[ExRaiseAccessViolation] : func:r40_1, 0:r40_2 -# 40| m40_4(unknown) = ^CallSideEffect : ~m38_1 -# 40| m40_5(unknown) = Chi : total:m38_1, partial:m40_4 -#-----| Exception (back edge) -> Block 3 +# 40| m40_4(unknown) = ^CallSideEffect : ~m36_5 +# 40| m40_5(unknown) = Chi : total:m36_5, partial:m40_4 +#-----| Exception -> Block 1 -# 32| Block 5 -# 32| v32_5(void) = Unreached : +# 32| Block 6 +# 32| v32_8(void) = Unreached : # 44| void try_with_finally() # 44| Block 0 @@ -3261,6 +3265,12 @@ ir.c: # 81| v81_3(void) = Call[ExRaiseAccessViolation] : func:r81_1, 0:r81_2 # 81| m81_4(unknown) = ^CallSideEffect : ~m80_4 # 81| m81_5(unknown) = Chi : total:m80_4, partial:m81_4 +#-----| Exception -> Block 1 + +# 80| Block 1 +# 80| v80_5(void) = Unwind : +# 80| v80_6(void) = AliasedUse : ~m81_5 +# 80| v80_7(void) = ExitFunction : ir.cpp: # 1| void Constants() diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected index 4fcb306f76ddd..02d2858ea2b73 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected @@ -8,25 +8,8 @@ sideEffectWithoutPrimary instructionWithoutSuccessor | ir.c:62:5:62:26 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:57:6:57:30 | void throw_in_try_with_finally() | void throw_in_try_with_finally() | | ir.c:73:5:73:26 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | -| ir.c:81:3:81:24 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:80:6:80:27 | void raise_access_violation() | void raise_access_violation() | ambiguousSuccessors unexplainedLoop -| ir.c:38:13:38:37 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:38:13:38:37 | Phi: 1 | Instruction 'Phi: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | Call: call to ExRaiseAccessViolation | Instruction 'Call: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | FunctionAddress: call to ExRaiseAccessViolation | Instruction 'FunctionAddress: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:28:40:28 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions @@ -37,9 +20,6 @@ containsLoopOfForwardEdges missingIRType multipleIRTypes lostReachability -| ir.c:39:3:41:3 | Constant: { ... } | Block 'Constant: { ... }' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Block 'Constant: { ... }' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | FunctionAddress: call to ExRaiseAccessViolation | Block 'FunctionAddress: call to ExRaiseAccessViolation' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | backEdgeCountMismatch useNotDominatedByDefinition switchInstructionWithoutDefaultEdge diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected index 4fcb306f76ddd..02d2858ea2b73 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected @@ -8,25 +8,8 @@ sideEffectWithoutPrimary instructionWithoutSuccessor | ir.c:62:5:62:26 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:57:6:57:30 | void throw_in_try_with_finally() | void throw_in_try_with_finally() | | ir.c:73:5:73:26 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | -| ir.c:81:3:81:24 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:80:6:80:27 | void raise_access_violation() | void raise_access_violation() | ambiguousSuccessors unexplainedLoop -| ir.c:38:13:38:37 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:38:13:38:37 | Phi: 1 | Instruction 'Phi: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | Call: call to ExRaiseAccessViolation | Instruction 'Call: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | FunctionAddress: call to ExRaiseAccessViolation | Instruction 'FunctionAddress: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:28:40:28 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions @@ -37,9 +20,6 @@ containsLoopOfForwardEdges missingIRType multipleIRTypes lostReachability -| ir.c:39:3:41:3 | Constant: { ... } | Block 'Constant: { ... }' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Block 'Constant: { ... }' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | FunctionAddress: call to ExRaiseAccessViolation | Block 'FunctionAddress: call to ExRaiseAccessViolation' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | backEdgeCountMismatch useNotDominatedByDefinition switchInstructionWithoutDefaultEdge diff --git a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected index 3a19d7174b1f8..1cf65c43f52a0 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected @@ -9,23 +9,8 @@ instructionWithoutSuccessor | ir.c:62:5:62:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:57:6:57:30 | void throw_in_try_with_finally() | void throw_in_try_with_finally() | | ir.c:73:5:73:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | | ir.c:76:5:76:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | -| ir.c:81:3:81:24 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:80:6:80:27 | void raise_access_violation() | void raise_access_violation() | ambiguousSuccessors unexplainedLoop -| ir.c:38:13:38:37 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | Call: call to ExRaiseAccessViolation | Instruction 'Call: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | FunctionAddress: call to ExRaiseAccessViolation | Instruction 'FunctionAddress: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:28:40:28 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions @@ -36,10 +21,6 @@ containsLoopOfForwardEdges missingIRType multipleIRTypes lostReachability -| ir.c:39:3:41:3 | Constant: { ... } | Block 'Constant: { ... }' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Block 'Constant: { ... }' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Unwind: { ... } | Block 'Unwind: { ... }' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | FunctionAddress: call to ExRaiseAccessViolation | Block 'FunctionAddress: call to ExRaiseAccessViolation' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | backEdgeCountMismatch useNotDominatedByDefinition | ir.cpp:1535:8:1535:8 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:1535:8:1535:8 | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 1bfbcfe287118..3143950293be7 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -2884,47 +2884,53 @@ ir.c: # 25| r25_3(int) = Load[x] : &:r25_2, ~m? # 25| v25_4(void) = Call[ExRaiseAccessViolation] : func:r25_1, 0:r25_3 # 25| mu25_5(unknown) = ^CallSideEffect : ~m? -#-----| Exception -> Block 5 +#-----| Exception -> Block 6 # 21| Block 1 -# 21| r21_6(glval) = VariableAddress[#return] : -# 21| v21_7(void) = ReturnValue : &:r21_6, ~m? -# 21| v21_8(void) = AliasedUse : ~m? -# 21| v21_9(void) = ExitFunction : +# 21| v21_6(void) = AliasedUse : ~m? +# 21| v21_7(void) = ExitFunction : + +# 21| Block 2 +# 21| r21_8(glval) = VariableAddress[#return] : +# 21| v21_9(void) = ReturnValue : &:r21_8, ~m? +#-----| Goto -> Block 1 -# 26| Block 2 +# 21| Block 3 +# 21| v21_10(void) = Unwind : +#-----| Goto -> Block 1 + +# 26| Block 4 # 26| r26_1(int) = Constant[0] : -# 26| r26_2(bool) = CompareEQ : r26_8, r26_1 +# 26| r26_2(bool) = CompareEQ : r26_7, r26_1 # 26| v26_3(void) = ConditionalBranch : r26_2 -#-----| False -> Block 3 -#-----| True -> Block 4 +#-----| False -> Block 5 +#-----| True -> Block 3 -# 26| Block 3 +# 26| Block 5 # 26| r26_4(int) = Constant[1] : -# 26| r26_5(bool) = CompareEQ : r26_8, r26_4 +# 26| r26_5(bool) = CompareEQ : r26_7, r26_4 # 26| v26_6(void) = ConditionalBranch : r26_5 -#-----| True -> Block 6 - -# 26| Block 4 -# 26| v26_7(void) = Unwind : -# 29| r29_1(glval) = VariableAddress[#return] : -# 29| r29_2(int) = Constant[0] : -# 29| mu29_3(int) = Store[#return] : &:r29_1, r29_2 -#-----| Goto -> Block 1 +#-----| True -> Block 7 -# 26| Block 5 -# 26| r26_8(int) = Constant[1] : -# 26| r26_9(int) = Constant[-1] : -# 26| r26_10(bool) = CompareEQ : r26_8, r26_9 -# 26| v26_11(void) = ConditionalBranch : r26_10 -#-----| False -> Block 2 -#-----| True -> Block 4 +# 26| Block 6 +# 26| r26_7(int) = Constant[1] : +# 26| r26_8(int) = Constant[-1] : +# 26| r26_9(bool) = CompareEQ : r26_7, r26_8 +# 26| v26_10(void) = ConditionalBranch : r26_9 +#-----| False -> Block 4 +#-----| True -> Block 3 -# 27| Block 6 +# 27| Block 7 # 27| r27_1(glval) = VariableAddress[#return] : # 27| r27_2(int) = Constant[1] : # 27| mu27_3(int) = Store[#return] : &:r27_1, r27_2 -#-----| Goto -> Block 1 +#-----| Goto -> Block 2 + +# 29| Block 8 +# 29| r29_1(glval) = VariableAddress[#return] : +# 29| r29_2(int) = Constant[0] : +# 29| mu29_3(int) = Store[#return] : &:r29_1, r29_2 +#-----| Goto -> Block 2 # 32| void unexplained_loop_regression() # 32| Block 0 @@ -2935,42 +2941,48 @@ ir.c: # 36| r36_2(int) = Constant[0] : # 36| v36_3(void) = Call[ExRaiseAccessViolation] : func:r36_1, 0:r36_2 # 36| mu36_4(unknown) = ^CallSideEffect : ~m? -#-----| Exception -> Block 4 +#-----| Exception -> Block 5 -# 39| Block 1 +# 32| Block 1 +# 32| v32_4(void) = AliasedUse : ~m? +# 32| v32_5(void) = ExitFunction : + +# 32| Block 2 +# 32| v32_6(void) = Unwind : +#-----| Goto -> Block 1 + +# 39| Block 3 # 39| r39_1(int) = Constant[0] : # 39| r39_2(bool) = CompareEQ : r38_1, r39_1 # 39| v39_3(void) = ConditionalBranch : r39_2 -#-----| False (back edge) -> Block 2 -#-----| True (back edge) -> Block 3 +#-----| False -> Block 4 +#-----| True -> Block 2 -# 39| Block 2 +# 39| Block 4 # 39| r39_4(int) = Constant[1] : # 39| r39_5(bool) = CompareEQ : r38_1, r39_4 # 39| v39_6(void) = ConditionalBranch : r39_5 -#-----| True (back edge) -> Block 5 +#-----| True -> Block 6 -# 39| Block 3 -# 39| v39_7(void) = Unwind : -# 42| v42_1(void) = NoOp : -# 32| v32_4(void) = ReturnVoid : -# 32| v32_5(void) = AliasedUse : ~m? -# 32| v32_6(void) = ExitFunction : - -# 38| Block 4 -# 38| r38_1(int) = Constant[1] : -# 39| r39_8(int) = Constant[-1] : -# 39| r39_9(bool) = CompareEQ : r38_1, r39_8 -# 39| v39_10(void) = ConditionalBranch : r39_9 -#-----| False (back edge) -> Block 1 -#-----| True (back edge) -> Block 3 +# 38| Block 5 +# 38| r38_1(int) = Constant[1] : +# 39| r39_7(int) = Constant[-1] : +# 39| r39_8(bool) = CompareEQ : r38_1, r39_7 +# 39| v39_9(void) = ConditionalBranch : r39_8 +#-----| False -> Block 3 +#-----| True -> Block 2 -# 40| Block 5 +# 40| Block 6 # 40| r40_1(glval) = FunctionAddress[ExRaiseAccessViolation] : # 40| r40_2(int) = Constant[1] : # 40| v40_3(void) = Call[ExRaiseAccessViolation] : func:r40_1, 0:r40_2 # 40| mu40_4(unknown) = ^CallSideEffect : ~m? -#-----| Exception (back edge) -> Block 4 +#-----| Exception -> Block 2 + +# 42| Block 7 +# 42| v42_1(void) = NoOp : +# 32| v32_7(void) = ReturnVoid : +#-----| Goto -> Block 1 # 44| void try_with_finally() # 44| Block 0 @@ -2988,8 +3000,15 @@ ir.c: # 53| mu53_3(int) = Store[x] : &:r53_2, r53_1 # 55| v55_1(void) = NoOp : # 44| v44_4(void) = ReturnVoid : -# 44| v44_5(void) = AliasedUse : ~m? -# 44| v44_6(void) = ExitFunction : +#-----| Goto -> Block 1 + +# 44| Block 1 +# 44| v44_5(void) = AliasedUse : ~m? +# 44| v44_6(void) = ExitFunction : + +# 44| Block 2 +# 44| v44_7(void) = Unwind : +#-----| Goto -> Block 1 # 57| void throw_in_try_with_finally() # 57| Block 0 @@ -3004,14 +3023,21 @@ ir.c: # 62| v62_3(void) = Call[ExRaiseAccessViolation] : func:r62_1, 0:r62_2 # 62| mu62_4(unknown) = ^CallSideEffect : ~m? -# 66| Block 1 +# 57| Block 1 +# 57| v57_4(void) = AliasedUse : ~m? +# 57| v57_5(void) = ExitFunction : + +# 57| Block 2 +# 57| v57_6(void) = Unwind : +#-----| Goto -> Block 1 + +# 66| Block 3 # 66| r66_1(int) = Constant[1] : # 66| r66_2(glval) = VariableAddress[x] : # 66| mu66_3(int) = Store[x] : &:r66_2, r66_1 # 68| v68_1(void) = NoOp : -# 57| v57_4(void) = ReturnVoid : -# 57| v57_5(void) = AliasedUse : ~m? -# 57| v57_6(void) = ExitFunction : +# 57| v57_7(void) = ReturnVoid : +#-----| Goto -> Block 1 # 70| void throw_in_try_with_throw_in_finally() # 70| Block 0 @@ -3023,17 +3049,24 @@ ir.c: # 73| v73_3(void) = Call[ExRaiseAccessViolation] : func:r73_1, 0:r73_2 # 73| mu73_4(unknown) = ^CallSideEffect : ~m? -# 76| Block 1 +# 70| Block 1 +# 70| v70_4(void) = AliasedUse : ~m? +# 70| v70_5(void) = ExitFunction : + +# 70| Block 2 +# 70| v70_6(void) = Unwind : +#-----| Goto -> Block 1 + +# 76| Block 3 # 76| r76_1(glval) = FunctionAddress[ExRaiseAccessViolation] : # 76| r76_2(int) = Constant[0] : # 76| v76_3(void) = Call[ExRaiseAccessViolation] : func:r76_1, 0:r76_2 # 76| mu76_4(unknown) = ^CallSideEffect : ~m? -# 78| Block 2 -# 78| v78_1(void) = NoOp : -# 70| v70_4(void) = ReturnVoid : -# 70| v70_5(void) = AliasedUse : ~m? -# 70| v70_6(void) = ExitFunction : +# 78| Block 4 +# 78| v78_1(void) = NoOp : +# 70| v70_7(void) = ReturnVoid : +#-----| Goto -> Block 1 # 80| void raise_access_violation() # 80| Block 0 @@ -3044,12 +3077,20 @@ ir.c: # 81| r81_2(int) = Constant[1] : # 81| v81_3(void) = Call[ExRaiseAccessViolation] : func:r81_1, 0:r81_2 # 81| mu81_4(unknown) = ^CallSideEffect : ~m? +#-----| Exception -> Block 2 -# 82| Block 1 -# 82| v82_1(void) = NoOp : -# 80| v80_4(void) = ReturnVoid : -# 80| v80_5(void) = AliasedUse : ~m? -# 80| v80_6(void) = ExitFunction : +# 80| Block 1 +# 80| v80_4(void) = AliasedUse : ~m? +# 80| v80_5(void) = ExitFunction : + +# 80| Block 2 +# 80| v80_6(void) = Unwind : +#-----| Goto -> Block 1 + +# 82| Block 3 +# 82| v82_1(void) = NoOp : +# 80| v80_7(void) = ReturnVoid : +#-----| Goto -> Block 1 ir.cpp: # 1| void Constants() @@ -36340,46 +36381,49 @@ try_except.c: # 11| r11_2(int) = Constant[0] : # 11| v11_3(void) = Call[ProbeFunction] : func:r11_1, 0:r11_2 # 11| mu11_4(unknown) = ^CallSideEffect : ~m? -#-----| Goto -> Block 6 +#-----| Goto -> Block 7 + +# 6| Block 1 +# 6| v6_4(void) = AliasedUse : ~m? +# 6| v6_5(void) = ExitFunction : + +# 6| Block 2 +# 6| v6_6(void) = Unwind : +#-----| Goto -> Block 1 -# 13| Block 1 +# 13| Block 3 # 13| r13_1(int) = Constant[0] : -# 13| r13_2(bool) = CompareEQ : r13_8, r13_1 +# 13| r13_2(bool) = CompareEQ : r13_7, r13_1 # 13| v13_3(void) = ConditionalBranch : r13_2 -#-----| False -> Block 2 -#-----| True -> Block 3 +#-----| False -> Block 4 +#-----| True -> Block 2 -# 13| Block 2 +# 13| Block 4 # 13| r13_4(int) = Constant[1] : -# 13| r13_5(bool) = CompareEQ : r13_8, r13_4 +# 13| r13_5(bool) = CompareEQ : r13_7, r13_4 # 13| v13_6(void) = ConditionalBranch : r13_5 -#-----| True -> Block 5 - -# 13| Block 3 -# 13| v13_7(void) = Unwind : -#-----| Goto -> Block 6 +#-----| True -> Block 6 -# 13| Block 4 -# 13| r13_8(int) = Constant[0] : -# 13| r13_9(int) = Constant[-1] : -# 13| r13_10(bool) = CompareEQ : r13_8, r13_9 -# 13| v13_11(void) = ConditionalBranch : r13_10 -#-----| False -> Block 1 -#-----| True -> Block 3 +# 13| Block 5 +# 13| r13_7(int) = Constant[0] : +# 13| r13_8(int) = Constant[-1] : +# 13| r13_9(bool) = CompareEQ : r13_7, r13_8 +# 13| v13_10(void) = ConditionalBranch : r13_9 +#-----| False -> Block 3 +#-----| True -> Block 2 -# 14| Block 5 +# 14| Block 6 # 14| r14_1(glval) = FunctionAddress[sink] : # 14| r14_2(glval) = VariableAddress[x] : # 14| r14_3(int) = Load[x] : &:r14_2, ~m? # 14| v14_4(void) = Call[sink] : func:r14_1, 0:r14_3 # 14| mu14_5(unknown) = ^CallSideEffect : ~m? -#-----| Goto -> Block 6 +#-----| Goto -> Block 7 -# 16| Block 6 -# 16| v16_1(void) = NoOp : -# 6| v6_4(void) = ReturnVoid : -# 6| v6_5(void) = AliasedUse : ~m? -# 6| v6_6(void) = ExitFunction : +# 16| Block 7 +# 16| v16_1(void) = NoOp : +# 6| v6_7(void) = ReturnVoid : +#-----| Goto -> Block 1 # 18| void g() # 18| Block 0 @@ -36410,8 +36454,15 @@ try_except.c: # 26| mu26_5(unknown) = ^CallSideEffect : ~m? # 28| v28_1(void) = NoOp : # 18| v18_4(void) = ReturnVoid : -# 18| v18_5(void) = AliasedUse : ~m? -# 18| v18_6(void) = ExitFunction : +#-----| Goto -> Block 1 + +# 18| Block 1 +# 18| v18_5(void) = AliasedUse : ~m? +# 18| v18_6(void) = ExitFunction : + +# 18| Block 2 +# 18| v18_7(void) = Unwind : +#-----| Goto -> Block 1 # 32| void h(int) # 32| Block 0 @@ -36426,53 +36477,56 @@ try_except.c: # 35| r35_1(glval) = VariableAddress[b] : # 35| r35_2(int) = Load[b] : &:r35_1, ~m? # 35| v35_3(void) = ConditionalBranch : r35_2 -#-----| False -> Block 7 -#-----| True -> Block 1 +#-----| False -> Block 8 +#-----| True -> Block 3 + +# 32| Block 1 +# 32| v32_6(void) = AliasedUse : ~m? +# 32| v32_7(void) = ExitFunction : + +# 32| Block 2 +# 32| v32_8(void) = Unwind : +#-----| Goto -> Block 1 -# 36| Block 1 +# 36| Block 3 # 36| r36_1(glval) = FunctionAddress[AfxThrowMemoryException] : # 36| v36_2(void) = Call[AfxThrowMemoryException] : func:r36_1 # 36| mu36_3(unknown) = ^CallSideEffect : ~m? -#-----| Goto -> Block 7 +#-----| Goto -> Block 8 -# 39| Block 2 +# 39| Block 4 # 39| r39_1(int) = Constant[0] : -# 39| r39_2(bool) = CompareEQ : r39_8, r39_1 +# 39| r39_2(bool) = CompareEQ : r39_7, r39_1 # 39| v39_3(void) = ConditionalBranch : r39_2 -#-----| False -> Block 3 -#-----| True -> Block 4 +#-----| False -> Block 5 +#-----| True -> Block 2 -# 39| Block 3 +# 39| Block 5 # 39| r39_4(int) = Constant[1] : -# 39| r39_5(bool) = CompareEQ : r39_8, r39_4 +# 39| r39_5(bool) = CompareEQ : r39_7, r39_4 # 39| v39_6(void) = ConditionalBranch : r39_5 -#-----| True -> Block 6 - -# 39| Block 4 -# 39| v39_7(void) = Unwind : -#-----| Goto -> Block 7 +#-----| True -> Block 7 -# 39| Block 5 -# 39| r39_8(int) = Constant[1] : -# 39| r39_9(int) = Constant[-1] : -# 39| r39_10(bool) = CompareEQ : r39_8, r39_9 -# 39| v39_11(void) = ConditionalBranch : r39_10 -#-----| False -> Block 2 -#-----| True -> Block 4 +# 39| Block 6 +# 39| r39_7(int) = Constant[1] : +# 39| r39_8(int) = Constant[-1] : +# 39| r39_9(bool) = CompareEQ : r39_7, r39_8 +# 39| v39_10(void) = ConditionalBranch : r39_9 +#-----| False -> Block 4 +#-----| True -> Block 2 -# 40| Block 6 +# 40| Block 7 # 40| r40_1(glval) = FunctionAddress[sink] : # 40| r40_2(glval) = VariableAddress[x] : # 40| r40_3(int) = Load[x] : &:r40_2, ~m? # 40| v40_4(void) = Call[sink] : func:r40_1, 0:r40_3 # 40| mu40_5(unknown) = ^CallSideEffect : ~m? -#-----| Goto -> Block 7 +#-----| Goto -> Block 8 -# 42| Block 7 -# 42| v42_1(void) = NoOp : -# 32| v32_6(void) = ReturnVoid : -# 32| v32_7(void) = AliasedUse : ~m? -# 32| v32_8(void) = ExitFunction : +# 42| Block 8 +# 42| v42_1(void) = NoOp : +# 32| v32_9(void) = ReturnVoid : +#-----| Goto -> Block 1 try_except.cpp: # 6| void f_cpp() @@ -36497,46 +36551,49 @@ try_except.cpp: # 11| r11_2(int) = Constant[0] : # 11| v11_3(void) = Call[ProbeFunction] : func:r11_1, 0:r11_2 # 11| mu11_4(unknown) = ^CallSideEffect : ~m? -#-----| Goto -> Block 6 +#-----| Goto -> Block 7 + +# 6| Block 1 +# 6| v6_4(void) = AliasedUse : ~m? +# 6| v6_5(void) = ExitFunction : -# 13| Block 1 +# 6| Block 2 +# 6| v6_6(void) = Unwind : +#-----| Goto -> Block 1 + +# 13| Block 3 # 13| r13_1(int) = Constant[0] : -# 13| r13_2(bool) = CompareEQ : r13_8, r13_1 +# 13| r13_2(bool) = CompareEQ : r13_7, r13_1 # 13| v13_3(void) = ConditionalBranch : r13_2 -#-----| False -> Block 2 -#-----| True -> Block 3 +#-----| False -> Block 4 +#-----| True -> Block 2 -# 13| Block 2 +# 13| Block 4 # 13| r13_4(int) = Constant[1] : -# 13| r13_5(bool) = CompareEQ : r13_8, r13_4 +# 13| r13_5(bool) = CompareEQ : r13_7, r13_4 # 13| v13_6(void) = ConditionalBranch : r13_5 -#-----| True -> Block 5 - -# 13| Block 3 -# 13| v13_7(void) = Unwind : -#-----| Goto -> Block 6 +#-----| True -> Block 6 -# 13| Block 4 -# 13| r13_8(int) = Constant[0] : -# 13| r13_9(int) = Constant[-1] : -# 13| r13_10(bool) = CompareEQ : r13_8, r13_9 -# 13| v13_11(void) = ConditionalBranch : r13_10 -#-----| False -> Block 1 -#-----| True -> Block 3 +# 13| Block 5 +# 13| r13_7(int) = Constant[0] : +# 13| r13_8(int) = Constant[-1] : +# 13| r13_9(bool) = CompareEQ : r13_7, r13_8 +# 13| v13_10(void) = ConditionalBranch : r13_9 +#-----| False -> Block 3 +#-----| True -> Block 2 -# 14| Block 5 +# 14| Block 6 # 14| r14_1(glval) = FunctionAddress[sink] : # 14| r14_2(glval) = VariableAddress[x] : # 14| r14_3(int) = Load[x] : &:r14_2, ~m? # 14| v14_4(void) = Call[sink] : func:r14_1, 0:r14_3 # 14| mu14_5(unknown) = ^CallSideEffect : ~m? -#-----| Goto -> Block 6 +#-----| Goto -> Block 7 -# 16| Block 6 -# 16| v16_1(void) = NoOp : -# 6| v6_4(void) = ReturnVoid : -# 6| v6_5(void) = AliasedUse : ~m? -# 6| v6_6(void) = ExitFunction : +# 16| Block 7 +# 16| v16_1(void) = NoOp : +# 6| v6_7(void) = ReturnVoid : +#-----| Goto -> Block 1 # 18| void g_cpp() # 18| Block 0 @@ -36567,8 +36624,15 @@ try_except.cpp: # 26| mu26_5(unknown) = ^CallSideEffect : ~m? # 28| v28_1(void) = NoOp : # 18| v18_4(void) = ReturnVoid : -# 18| v18_5(void) = AliasedUse : ~m? -# 18| v18_6(void) = ExitFunction : +#-----| Goto -> Block 1 + +# 18| Block 1 +# 18| v18_5(void) = AliasedUse : ~m? +# 18| v18_6(void) = ExitFunction : + +# 18| Block 2 +# 18| v18_7(void) = Unwind : +#-----| Goto -> Block 1 # 32| void h_cpp(int) # 32| Block 0 @@ -36585,53 +36649,56 @@ try_except.cpp: # 35| r35_3(int) = Constant[0] : # 35| r35_4(bool) = CompareNE : r35_2, r35_3 # 35| v35_5(void) = ConditionalBranch : r35_4 -#-----| False -> Block 7 -#-----| True -> Block 1 +#-----| False -> Block 8 +#-----| True -> Block 3 + +# 32| Block 1 +# 32| v32_6(void) = AliasedUse : ~m? +# 32| v32_7(void) = ExitFunction : -# 36| Block 1 +# 32| Block 2 +# 32| v32_8(void) = Unwind : +#-----| Goto -> Block 1 + +# 36| Block 3 # 36| r36_1(glval) = FunctionAddress[AfxThrowMemoryException] : # 36| v36_2(void) = Call[AfxThrowMemoryException] : func:r36_1 # 36| mu36_3(unknown) = ^CallSideEffect : ~m? -#-----| Goto -> Block 7 +#-----| Goto -> Block 8 -# 39| Block 2 +# 39| Block 4 # 39| r39_1(int) = Constant[0] : -# 39| r39_2(bool) = CompareEQ : r39_8, r39_1 +# 39| r39_2(bool) = CompareEQ : r39_7, r39_1 # 39| v39_3(void) = ConditionalBranch : r39_2 -#-----| False -> Block 3 -#-----| True -> Block 4 +#-----| False -> Block 5 +#-----| True -> Block 2 -# 39| Block 3 +# 39| Block 5 # 39| r39_4(int) = Constant[1] : -# 39| r39_5(bool) = CompareEQ : r39_8, r39_4 +# 39| r39_5(bool) = CompareEQ : r39_7, r39_4 # 39| v39_6(void) = ConditionalBranch : r39_5 -#-----| True -> Block 6 - -# 39| Block 4 -# 39| v39_7(void) = Unwind : -#-----| Goto -> Block 7 +#-----| True -> Block 7 -# 39| Block 5 -# 39| r39_8(int) = Constant[1] : -# 39| r39_9(int) = Constant[-1] : -# 39| r39_10(bool) = CompareEQ : r39_8, r39_9 -# 39| v39_11(void) = ConditionalBranch : r39_10 -#-----| False -> Block 2 -#-----| True -> Block 4 +# 39| Block 6 +# 39| r39_7(int) = Constant[1] : +# 39| r39_8(int) = Constant[-1] : +# 39| r39_9(bool) = CompareEQ : r39_7, r39_8 +# 39| v39_10(void) = ConditionalBranch : r39_9 +#-----| False -> Block 4 +#-----| True -> Block 2 -# 40| Block 6 +# 40| Block 7 # 40| r40_1(glval) = FunctionAddress[sink] : # 40| r40_2(glval) = VariableAddress[x] : # 40| r40_3(int) = Load[x] : &:r40_2, ~m? # 40| v40_4(void) = Call[sink] : func:r40_1, 0:r40_3 # 40| mu40_5(unknown) = ^CallSideEffect : ~m? -#-----| Goto -> Block 7 +#-----| Goto -> Block 8 -# 42| Block 7 -# 42| v42_1(void) = NoOp : -# 32| v32_6(void) = ReturnVoid : -# 32| v32_7(void) = AliasedUse : ~m? -# 32| v32_8(void) = ExitFunction : +# 42| Block 8 +# 42| v42_1(void) = NoOp : +# 32| v32_9(void) = ReturnVoid : +#-----| Goto -> Block 1 # 44| void throw_cpp(int) # 44| Block 0 @@ -36648,7 +36715,7 @@ try_except.cpp: # 47| r47_3(int) = Constant[0] : # 47| r47_4(bool) = CompareNE : r47_2, r47_3 # 47| v47_5(void) = ConditionalBranch : r47_4 -#-----| False -> Block 9 +#-----| False -> Block 8 #-----| True -> Block 3 # 44| Block 1 @@ -36664,42 +36731,38 @@ try_except.cpp: # 48| r48_2(int) = Constant[1] : # 48| mu48_3(int) = Store[#throw48:13] : &:r48_1, r48_2 # 48| v48_4(void) = ThrowValue : &:r48_1, ~m? -#-----| Exception -> Block 7 +#-----| Exception -> Block 6 # 51| Block 4 # 51| r51_1(int) = Constant[0] : -# 51| r51_2(bool) = CompareEQ : r51_8, r51_1 +# 51| r51_2(bool) = CompareEQ : r51_7, r51_1 # 51| v51_3(void) = ConditionalBranch : r51_2 #-----| False -> Block 5 -#-----| True -> Block 6 +#-----| True -> Block 2 # 51| Block 5 # 51| r51_4(int) = Constant[1] : -# 51| r51_5(bool) = CompareEQ : r51_8, r51_4 +# 51| r51_5(bool) = CompareEQ : r51_7, r51_4 # 51| v51_6(void) = ConditionalBranch : r51_5 -#-----| True -> Block 8 +#-----| True -> Block 7 # 51| Block 6 -# 51| v51_7(void) = Unwind : -#-----| Goto -> Block 9 - -# 51| Block 7 -# 51| r51_8(int) = Constant[1] : -# 51| r51_9(int) = Constant[-1] : -# 51| r51_10(bool) = CompareEQ : r51_8, r51_9 -# 51| v51_11(void) = ConditionalBranch : r51_10 +# 51| r51_7(int) = Constant[1] : +# 51| r51_8(int) = Constant[-1] : +# 51| r51_9(bool) = CompareEQ : r51_7, r51_8 +# 51| v51_10(void) = ConditionalBranch : r51_9 #-----| False -> Block 4 -#-----| True -> Block 6 +#-----| True -> Block 2 -# 52| Block 8 +# 52| Block 7 # 52| r52_1(glval) = FunctionAddress[sink] : # 52| r52_2(glval) = VariableAddress[x] : # 52| r52_3(int) = Load[x] : &:r52_2, ~m? # 52| v52_4(void) = Call[sink] : func:r52_1, 0:r52_3 # 52| mu52_5(unknown) = ^CallSideEffect : ~m? -#-----| Goto -> Block 9 +#-----| Goto -> Block 8 -# 54| Block 9 +# 54| Block 8 # 54| v54_1(void) = NoOp : # 44| v44_9(void) = ReturnVoid : #-----| Goto -> Block 1 diff --git a/cpp/ql/test/library-tests/ir/ir/try_except.cpp b/cpp/ql/test/library-tests/ir/ir/try_except.cpp index fd8c5f59f1a40..9bf297263b75c 100644 --- a/cpp/ql/test/library-tests/ir/ir/try_except.cpp +++ b/cpp/ql/test/library-tests/ir/ir/try_except.cpp @@ -51,4 +51,4 @@ void throw_cpp(int b) { __except (1) { sink(x); } -} \ No newline at end of file +} diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected index a0143f9b0c6b9..c0a7c6c5c7c23 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected @@ -8,23 +8,8 @@ sideEffectWithoutPrimary instructionWithoutSuccessor | ir.c:62:5:62:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:57:6:57:30 | void throw_in_try_with_finally() | void throw_in_try_with_finally() | | ir.c:73:5:73:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | -| ir.c:81:3:81:24 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:80:6:80:27 | void raise_access_violation() | void raise_access_violation() | ambiguousSuccessors unexplainedLoop -| ir.c:38:13:38:37 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | Call: call to ExRaiseAccessViolation | Instruction 'Call: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | FunctionAddress: call to ExRaiseAccessViolation | Instruction 'FunctionAddress: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:28:40:28 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions @@ -35,9 +20,6 @@ containsLoopOfForwardEdges missingIRType multipleIRTypes lostReachability -| ir.c:39:3:41:3 | Constant: { ... } | Block 'Constant: { ... }' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Block 'Constant: { ... }' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | FunctionAddress: call to ExRaiseAccessViolation | Block 'FunctionAddress: call to ExRaiseAccessViolation' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | backEdgeCountMismatch useNotDominatedByDefinition switchInstructionWithoutDefaultEdge diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected index a0143f9b0c6b9..c0a7c6c5c7c23 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected @@ -8,23 +8,8 @@ sideEffectWithoutPrimary instructionWithoutSuccessor | ir.c:62:5:62:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:57:6:57:30 | void throw_in_try_with_finally() | void throw_in_try_with_finally() | | ir.c:73:5:73:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | -| ir.c:81:3:81:24 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:80:6:80:27 | void raise_access_violation() | void raise_access_violation() | ambiguousSuccessors unexplainedLoop -| ir.c:38:13:38:37 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | CompareEQ: { ... } | Instruction 'CompareEQ: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | ConditionalBranch: { ... } | Instruction 'ConditionalBranch: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Instruction 'Constant: { ... }' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | Call: call to ExRaiseAccessViolation | Instruction 'Call: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | FunctionAddress: call to ExRaiseAccessViolation | Instruction 'FunctionAddress: call to ExRaiseAccessViolation' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:28:40:28 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions @@ -35,9 +20,6 @@ containsLoopOfForwardEdges missingIRType multipleIRTypes lostReachability -| ir.c:39:3:41:3 | Constant: { ... } | Block 'Constant: { ... }' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:39:3:41:3 | Constant: { ... } | Block 'Constant: { ... }' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | -| ir.c:40:5:40:26 | FunctionAddress: call to ExRaiseAccessViolation | Block 'FunctionAddress: call to ExRaiseAccessViolation' is not reachable by traversing only forward edges in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | backEdgeCountMismatch useNotDominatedByDefinition switchInstructionWithoutDefaultEdge