diff --git a/cpp/ql/lib/change-notes/2014-12-13-deprecate-throwing.md b/cpp/ql/lib/change-notes/2014-12-13-deprecate-throwing.md new file mode 100644 index 000000000000..9a46cc7da8f2 --- /dev/null +++ b/cpp/ql/lib/change-notes/2014-12-13-deprecate-throwing.md @@ -0,0 +1,4 @@ +--- +category: deprecated +--- +* The `ThrowingFunction` class (`semmle.code.cpp.models.interfaces.Throwing`) has been deprecated. Please use the `AlwaysSehThrowingFunction` class instead. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index 4f8932c4a289..db46f6807cdb 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -84,11 +84,10 @@ abstract class TranslatedCall extends TranslatedExpr { this.getEnclosingFunction().getFunction() = instr.getEnclosingFunction() ) else ( - not this.mustThrowException() and + not this.mustThrowException(_) and result = this.getParent().getChildSuccessor(this, kind) or - this.mayThrowException() and - kind instanceof CppExceptionEdge and + this.mayThrowException(kind) and result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge edge)) ) } @@ -117,14 +116,14 @@ abstract class TranslatedCall extends TranslatedExpr { final override Instruction getResult() { result = this.getInstruction(CallTag()) } /** - * Holds if the evaluation of this call may throw an exception. + * Holds if the evaluation of this call may throw an exception of the kind represented by the `ExceptionEdge`. */ - abstract predicate mayThrowException(); + abstract predicate mayThrowException(ExceptionEdge e); /** - * Holds if the evaluation of this call always throws an exception. + * Holds if the evaluation of this call always throws an exception of the kind represented by the `ExceptionEdge`. */ - abstract predicate mustThrowException(); + abstract predicate mustThrowException(ExceptionEdge e); /** * Gets the result type of the call. @@ -332,14 +331,14 @@ class TranslatedExprCall extends TranslatedCallExpr { result = getTranslatedExpr(expr.getExpr().getFullyConverted()) } - final override predicate mayThrowException() { + final override predicate mayThrowException(ExceptionEdge e) { // We assume that a call to a function pointer will not throw an exception. // This is not sound in general, but this will greatly reduce the number of // exceptional edges. none() } - final override predicate mustThrowException() { none() } + final override predicate mustThrowException(ExceptionEdge e) { none() } } /** @@ -362,16 +361,16 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { not exists(MemberFunction func | expr.getTarget() = func and func.isStatic()) } - final override predicate mayThrowException() { - expr.getTarget().(ThrowingFunction).mayThrowException(_) + final override predicate mayThrowException(ExceptionEdge e) { + this.mustThrowException(e) or - expr.getTarget() instanceof AlwaysSehThrowingFunction + exists(MicrosoftTryStmt tryStmt | tryStmt.getStmt() = expr.getEnclosingStmt().getParent*()) and + e instanceof SehExceptionEdge } - final override predicate mustThrowException() { - expr.getTarget().(ThrowingFunction).mayThrowException(true) - or - expr.getTarget() instanceof AlwaysSehThrowingFunction + final override predicate mustThrowException(ExceptionEdge e) { + expr.getTarget() instanceof AlwaysSehThrowingFunction and + e instanceof SehExceptionEdge } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index f21f44956768..ef2096e9b392 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -2483,14 +2483,14 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedDirect result = getTranslatedExpr(expr.getAllocatorCall().getArgument(index).getFullyConverted()) } - final override predicate mayThrowException() { + final override predicate mayThrowException(ExceptionEdge e) { // We assume that a call to `new` or `new[]` will never throw. This is not // sound in general, but this will greatly reduce the number of exceptional // edges. none() } - final override predicate mustThrowException() { none() } + final override predicate mustThrowException(ExceptionEdge e) { none() } } TranslatedAllocatorCall getTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) { @@ -2556,14 +2556,14 @@ class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, Trans result = getTranslatedExpr(expr.getExprWithReuse().getFullyConverted()) } - final override predicate mayThrowException() { + final override predicate mayThrowException(ExceptionEdge e) { // We assume that a call to `delete` or `delete[]` will never throw. This is not // sound in general, but this will greatly reduce the number of exceptional // edges. none() } - final override predicate mustThrowException() { none() } + final override predicate mustThrowException(ExceptionEdge e) { none() } } TranslatedDeleteOrDeleteArrayExpr getTranslatedDeleteOrDeleteArray(DeleteOrDeleteArrayExpr newExpr) { 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 57f718bcb6ab..83736ae98d04 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 @@ -214,7 +214,7 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction { exists(ThrowExpr throw | throw.getEnclosingFunction() = func) or exists(FunctionCall call | call.getEnclosingFunction() = func | - getTranslatedExpr(call).(TranslatedCallExpr).mayThrowException() + getTranslatedExpr(call).(TranslatedCallExpr).mayThrowException(_) ) ) or diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll index cc2948067092..111b99533957 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll @@ -12,8 +12,10 @@ import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs /** * A function that is known to raise an exception. + * + * DEPRECATED: use `AlwaysSehThrowingFunction` instead. */ -abstract class ThrowingFunction extends Function { +abstract deprecated class ThrowingFunction extends Function { /** * Holds if this function may throw an exception during evaluation. * If `unconditional` is `true` the function always throws an exception. diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index b9ffaf71656b..bde0ac736752 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -49652,6 +49652,43 @@ try_except.c: # 40| Type = [IntType] int # 40| ValueCategory = prvalue(load) # 42| getStmt(2): [ReturnStmt] return ... +# 44| [TopLevelFunction] int i() +# 44| : +# 46| [TopLevelFunction] void j(int) +# 46| : +# 46| getParameter(0): [Parameter] b +# 46| Type = [IntType] int +# 46| getEntryPoint(): [BlockStmt] { ... } +# 47| getStmt(0): [DeclStmt] declaration +# 47| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 47| Type = [IntType] int +# 47| getVariable().getInitializer(): [Initializer] initializer for x +# 47| getExpr(): [Literal] 0 +# 47| Type = [IntType] int +# 47| Value = [Literal] 0 +# 47| ValueCategory = prvalue +# 48| getStmt(1): [MicrosoftTryExceptStmt] __try { ... } __except( ... ) { ... } +# 48| getStmt(): [BlockStmt] { ... } +# 49| getStmt(0): [DeclStmt] declaration +# 49| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y +# 49| Type = [IntType] int +# 49| getVariable().getInitializer(): [Initializer] initializer for y +# 49| getExpr(): [FunctionCall] call to i +# 49| Type = [IntType] int +# 49| ValueCategory = prvalue +# 51| getCondition(): [Literal] 1 +# 51| Type = [IntType] int +# 51| Value = [Literal] 1 +# 51| ValueCategory = prvalue +# 51| getExcept(): [BlockStmt] { ... } +# 52| getStmt(0): [ExprStmt] ExprStmt +# 52| getExpr(): [FunctionCall] call to sink +# 52| Type = [VoidType] void +# 52| ValueCategory = prvalue +# 52| getArgument(0): [VariableAccess] x +# 52| Type = [IntType] int +# 52| ValueCategory = prvalue(load) +# 54| getStmt(2): [ReturnStmt] return ... try_except.cpp: # 3| [TopLevelFunction] void ProbeFunction() # 3| : 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 fbd0db5e7966..4f35e4f62097 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -3244,7 +3244,7 @@ ir.c: # 25| v25_4(void) = Call[ExRaiseAccessViolation] : func:r25_1, 0:r25_3 # 25| m25_5(unknown) = ^CallSideEffect : ~m21_4 # 25| m25_6(unknown) = Chi : total:m21_4, partial:m25_5 -#-----| C++ Exception -> Block 3 +#-----| SEH Exception -> Block 3 # 26| Block 1 # 26| r26_1(int) = Constant[0] : @@ -3291,7 +3291,7 @@ 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 -#-----| C++ Exception -> Block 4 +#-----| SEH Exception -> Block 4 # 32| Block 1 # 32| v32_5(void) = Unwind : @@ -3326,7 +3326,7 @@ ir.c: # 40| v40_3(void) = Call[ExRaiseAccessViolation] : func:r40_1, 0:r40_2 # 40| m40_4(unknown) = ^CallSideEffect : ~m36_5 # 40| m40_5(unknown) = Chi : total:m36_5, partial:m40_4 -#-----| C++ Exception -> Block 1 +#-----| SEH Exception -> Block 1 # 32| Block 6 # 32| v32_8(void) = Unreached : @@ -3365,7 +3365,7 @@ ir.c: # 62| v62_3(void) = Call[ExRaiseAccessViolation] : func:r62_1, 0:r62_2 # 62| m62_4(unknown) = ^CallSideEffect : ~m57_4 # 62| m62_5(unknown) = Chi : total:m57_4, partial:m62_4 -#-----| C++ Exception -> Block 1 +#-----| SEH Exception -> Block 1 # 66| Block 1 # 66| r66_1(int) = Constant[1] : @@ -3387,7 +3387,7 @@ ir.c: # 73| v73_3(void) = Call[ExRaiseAccessViolation] : func:r73_1, 0:r73_2 # 73| m73_4(unknown) = ^CallSideEffect : ~m70_4 # 73| m73_5(unknown) = Chi : total:m70_4, partial:m73_4 -#-----| C++ Exception -> Block 2 +#-----| SEH Exception -> Block 2 # 70| Block 1 # 70| v70_5(void) = Unwind : @@ -3400,7 +3400,7 @@ ir.c: # 76| v76_3(void) = Call[ExRaiseAccessViolation] : func:r76_1, 0:r76_2 # 76| m76_4(unknown) = ^CallSideEffect : ~m73_5 # 76| m76_5(unknown) = Chi : total:m73_5, partial:m76_4 -#-----| C++ Exception -> Block 1 +#-----| SEH Exception -> Block 1 # 80| void raise_access_violation() # 80| Block 0 @@ -3413,7 +3413,7 @@ 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 -#-----| C++ Exception -> Block 1 +#-----| SEH Exception -> Block 1 # 80| Block 1 # 80| v80_5(void) = Unwind : @@ -39018,20 +39018,33 @@ struct_init.cpp: try_except.c: # 6| void f() # 6| Block 0 -# 6| v6_1(void) = EnterFunction : -# 6| m6_2(unknown) = AliasedDefinition : -# 6| m6_3(unknown) = InitializeNonLocal : -# 6| m6_4(unknown) = Chi : total:m6_2, partial:m6_3 -# 7| r7_1(glval) = VariableAddress[x] : -# 7| m7_2(int) = Uninitialized[x] : &:r7_1 -# 7| r7_3(glval) = VariableAddress[y] : -# 7| r7_4(int) = Constant[0] : -# 7| m7_5(int) = Store[y] : &:r7_3, r7_4 -# 9| r9_1(glval) = FunctionAddress[ProbeFunction] : -# 9| r9_2(int) = Constant[0] : -# 9| v9_3(void) = Call[ProbeFunction] : func:r9_1, 0:r9_2 -# 9| m9_4(unknown) = ^CallSideEffect : ~m6_4 -# 9| m9_5(unknown) = Chi : total:m6_4, partial:m9_4 +# 6| v6_1(void) = EnterFunction : +# 6| m6_2(unknown) = AliasedDefinition : +# 6| m6_3(unknown) = InitializeNonLocal : +# 6| m6_4(unknown) = Chi : total:m6_2, partial:m6_3 +# 7| r7_1(glval) = VariableAddress[x] : +# 7| m7_2(int) = Uninitialized[x] : &:r7_1 +# 7| r7_3(glval) = VariableAddress[y] : +# 7| r7_4(int) = Constant[0] : +# 7| m7_5(int) = Store[y] : &:r7_3, r7_4 +# 9| r9_1(glval) = FunctionAddress[ProbeFunction] : +# 9| r9_2(int) = Constant[0] : +# 9| v9_3(void) = Call[ProbeFunction] : func:r9_1, 0:r9_2 +# 9| m9_4(unknown) = ^CallSideEffect : ~m6_4 +# 9| m9_5(unknown) = Chi : total:m6_4, partial:m9_4 +#-----| Goto -> Block 3 +#-----| SEH Exception -> Block 5 + +# 6| Block 1 +# 6| m6_5(unknown) = Phi : from 2:~m13_4, from 6:~m11_5 +# 6| v6_6(void) = AliasedUse : ~m6_5 +# 6| v6_7(void) = ExitFunction : + +# 6| Block 2 +# 6| v6_8(void) = Unwind : +#-----| Goto -> Block 1 + +# 10| Block 3 # 10| r10_1(glval) = VariableAddress[y] : # 10| r10_2(int) = Load[y] : &:r10_1, m7_5 # 10| r10_3(glval) = VariableAddress[x] : @@ -39041,13 +39054,32 @@ try_except.c: # 11| v11_3(void) = Call[ProbeFunction] : func:r11_1, 0:r11_2 # 11| m11_4(unknown) = ^CallSideEffect : ~m9_5 # 11| m11_5(unknown) = Chi : total:m9_5, partial:m11_4 -# 16| v16_1(void) = NoOp : -# 6| v6_5(void) = ReturnVoid : -# 6| v6_6(void) = AliasedUse : ~m11_5 -# 6| v6_7(void) = ExitFunction : +#-----| Goto -> Block 6 +#-----| SEH Exception -> Block 5 -# 6| Block 1 -# 6| v6_8(void) = Unreached : +# 13| Block 4 +# 13| r13_1(int) = Constant[0] : +# 13| r13_2(bool) = CompareEQ : r13_5, r13_1 +# 13| v13_3(void) = ConditionalBranch : r13_2 +#-----| False -> Block 7 +#-----| True -> Block 2 + +# 13| Block 5 +# 13| m13_4(unknown) = Phi : from 0:~m9_5, from 3:~m11_5 +# 13| r13_5(int) = Constant[0] : +# 13| r13_6(int) = Constant[-1] : +# 13| r13_7(bool) = CompareEQ : r13_5, r13_6 +# 13| v13_8(void) = ConditionalBranch : r13_7 +#-----| False -> Block 4 +#-----| True -> Block 7 + +# 16| Block 6 +# 16| v16_1(void) = NoOp : +# 6| v6_9(void) = ReturnVoid : +#-----| Goto -> Block 1 + +# 6| Block 7 +# 6| v6_10(void) = Unreached : # 18| void g() # 18| Block 0 @@ -39065,6 +39097,10 @@ try_except.c: # 21| v21_3(void) = Call[ProbeFunction] : func:r21_1, 0:r21_2 # 21| m21_4(unknown) = ^CallSideEffect : ~m18_4 # 21| m21_5(unknown) = Chi : total:m18_4, partial:m21_4 +#-----| Goto -> Block 1 +#-----| SEH Exception -> Block 2 + +# 22| Block 1 # 22| r22_1(glval) = VariableAddress[y] : # 22| r22_2(int) = Load[y] : &:r22_1, m19_5 # 22| r22_3(glval) = VariableAddress[x] : @@ -39074,16 +39110,21 @@ try_except.c: # 23| v23_3(void) = Call[ProbeFunction] : func:r23_1, 0:r23_2 # 23| m23_4(unknown) = ^CallSideEffect : ~m21_5 # 23| m23_5(unknown) = Chi : total:m21_5, partial:m23_4 -# 26| r26_1(glval) = FunctionAddress[sink] : -# 26| r26_2(glval) = VariableAddress[x] : -# 26| r26_3(int) = Load[x] : &:r26_2, m22_4 -# 26| v26_4(void) = Call[sink] : func:r26_1, 0:r26_3 -# 26| m26_5(unknown) = ^CallSideEffect : ~m23_5 -# 26| m26_6(unknown) = Chi : total:m23_5, partial:m26_5 -# 28| v28_1(void) = NoOp : -# 18| v18_5(void) = ReturnVoid : -# 18| v18_6(void) = AliasedUse : ~m26_6 -# 18| v18_7(void) = ExitFunction : +#-----| Goto|SEH Exception -> Block 2 + +# 26| Block 2 +# 26| m26_1(unknown) = Phi : from 0:~m21_5, from 1:~m23_5 +# 26| m26_2(int) = Phi : from 0:m19_2, from 1:m22_4 +# 26| r26_3(glval) = FunctionAddress[sink] : +# 26| r26_4(glval) = VariableAddress[x] : +# 26| r26_5(int) = Load[x] : &:r26_4, m26_2 +# 26| v26_6(void) = Call[sink] : func:r26_3, 0:r26_5 +# 26| m26_7(unknown) = ^CallSideEffect : ~m26_1 +# 26| m26_8(unknown) = Chi : total:m26_1, partial:m26_7 +# 28| v28_1(void) = NoOp : +# 18| v18_5(void) = ReturnVoid : +# 18| v18_6(void) = AliasedUse : ~m26_8 +# 18| v18_7(void) = ExitFunction : # 32| void h(int) # 32| Block 0 @@ -39101,7 +39142,7 @@ try_except.c: # 35| r35_3(int) = Constant[0] : # 35| r35_4(bool) = CompareNE : r35_2, r35_3 # 35| v35_5(void) = ConditionalBranch : r35_4 -#-----| False -> Block 2 +#-----| False -> Block 6 #-----| True -> Block 1 # 36| Block 1 @@ -39109,35 +39150,144 @@ try_except.c: # 36| v36_2(void) = Call[AfxThrowMemoryException] : func:r36_1 # 36| m36_3(unknown) = ^CallSideEffect : ~m32_4 # 36| m36_4(unknown) = Chi : total:m32_4, partial:m36_3 -#-----| Goto -> Block 2 +#-----| Goto -> Block 6 +#-----| SEH Exception -> Block 4 -# 42| Block 2 -# 42| m42_1(unknown) = Phi : from 0:~m32_4, from 1:~m36_4 +# 39| Block 2 +# 39| r39_1(int) = Constant[0] : +# 39| r39_2(bool) = CompareEQ : r39_7, r39_1 +# 39| v39_3(void) = ConditionalBranch : r39_2 +#-----| False -> Block 3 +#-----| True -> Block 7 + +# 39| Block 3 +# 39| r39_4(int) = Constant[1] : +# 39| r39_5(bool) = CompareEQ : r39_7, r39_4 +# 39| v39_6(void) = ConditionalBranch : r39_5 +#-----| False -> Block 7 +#-----| True -> Block 5 + +# 39| Block 4 +# 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 2 +#-----| True -> Block 7 + +# 40| Block 5 +# 40| r40_1(glval) = FunctionAddress[sink] : +# 40| r40_2(glval) = VariableAddress[x] : +# 40| r40_3(int) = Load[x] : &:r40_2, m33_3 +# 40| v40_4(void) = Call[sink] : func:r40_1, 0:r40_3 +# 40| m40_5(unknown) = ^CallSideEffect : ~m36_4 +# 40| m40_6(unknown) = Chi : total:m36_4, partial:m40_5 +#-----| Goto -> Block 6 + +# 42| Block 6 +# 42| m42_1(unknown) = Phi : from 0:~m32_4, from 1:~m36_4, from 5:~m40_6 # 42| v42_2(void) = NoOp : # 32| v32_7(void) = ReturnVoid : # 32| v32_8(void) = AliasedUse : ~m42_1 # 32| v32_9(void) = ExitFunction : -# 32| Block 3 +# 32| Block 7 # 32| v32_10(void) = Unreached : +# 46| void j(int) +# 46| Block 0 +# 46| v46_1(void) = EnterFunction : +# 46| m46_2(unknown) = AliasedDefinition : +# 46| m46_3(unknown) = InitializeNonLocal : +# 46| m46_4(unknown) = Chi : total:m46_2, partial:m46_3 +# 46| r46_5(glval) = VariableAddress[b] : +# 46| m46_6(int) = InitializeParameter[b] : &:r46_5 +# 47| r47_1(glval) = VariableAddress[x] : +# 47| r47_2(int) = Constant[0] : +# 47| m47_3(int) = Store[x] : &:r47_1, r47_2 +# 49| r49_1(glval) = VariableAddress[y] : +# 49| r49_2(glval) = FunctionAddress[i] : +# 49| r49_3(int) = Call[i] : func:r49_2 +# 49| m49_4(unknown) = ^CallSideEffect : ~m46_4 +# 49| m49_5(unknown) = Chi : total:m46_4, partial:m49_4 +#-----| Goto -> Block 1 +#-----| SEH Exception -> Block 4 + +# 49| Block 1 +# 49| m49_6(int) = Store[y] : &:r49_1, r49_3 +#-----| Goto -> Block 6 + +# 51| Block 2 +# 51| r51_1(int) = Constant[0] : +# 51| r51_2(bool) = CompareEQ : r51_7, r51_1 +# 51| v51_3(void) = ConditionalBranch : r51_2 +#-----| False -> Block 3 +#-----| True -> Block 7 + +# 51| Block 3 +# 51| r51_4(int) = Constant[1] : +# 51| r51_5(bool) = CompareEQ : r51_7, r51_4 +# 51| v51_6(void) = ConditionalBranch : r51_5 +#-----| False -> Block 7 +#-----| True -> Block 5 + +# 51| Block 4 +# 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 2 +#-----| True -> Block 7 + +# 52| Block 5 +# 52| r52_1(glval) = FunctionAddress[sink] : +# 52| r52_2(glval) = VariableAddress[x] : +# 52| r52_3(int) = Load[x] : &:r52_2, m47_3 +# 52| v52_4(void) = Call[sink] : func:r52_1, 0:r52_3 +# 52| m52_5(unknown) = ^CallSideEffect : ~m49_5 +# 52| m52_6(unknown) = Chi : total:m49_5, partial:m52_5 +#-----| Goto -> Block 6 + +# 54| Block 6 +# 54| m54_1(unknown) = Phi : from 1:~m49_5, from 5:~m52_6 +# 54| v54_2(void) = NoOp : +# 46| v46_7(void) = ReturnVoid : +# 46| v46_8(void) = AliasedUse : ~m54_1 +# 46| v46_9(void) = ExitFunction : + +# 46| Block 7 +# 46| v46_10(void) = Unreached : + try_except.cpp: # 6| void f_cpp() # 6| Block 0 -# 6| v6_1(void) = EnterFunction : -# 6| m6_2(unknown) = AliasedDefinition : -# 6| m6_3(unknown) = InitializeNonLocal : -# 6| m6_4(unknown) = Chi : total:m6_2, partial:m6_3 -# 7| r7_1(glval) = VariableAddress[x] : -# 7| m7_2(int) = Uninitialized[x] : &:r7_1 -# 7| r7_3(glval) = VariableAddress[y] : -# 7| r7_4(int) = Constant[0] : -# 7| m7_5(int) = Store[y] : &:r7_3, r7_4 -# 9| r9_1(glval) = FunctionAddress[ProbeFunction] : -# 9| r9_2(int) = Constant[0] : -# 9| v9_3(void) = Call[ProbeFunction] : func:r9_1, 0:r9_2 -# 9| m9_4(unknown) = ^CallSideEffect : ~m6_4 -# 9| m9_5(unknown) = Chi : total:m6_4, partial:m9_4 +# 6| v6_1(void) = EnterFunction : +# 6| m6_2(unknown) = AliasedDefinition : +# 6| m6_3(unknown) = InitializeNonLocal : +# 6| m6_4(unknown) = Chi : total:m6_2, partial:m6_3 +# 7| r7_1(glval) = VariableAddress[x] : +# 7| m7_2(int) = Uninitialized[x] : &:r7_1 +# 7| r7_3(glval) = VariableAddress[y] : +# 7| r7_4(int) = Constant[0] : +# 7| m7_5(int) = Store[y] : &:r7_3, r7_4 +# 9| r9_1(glval) = FunctionAddress[ProbeFunction] : +# 9| r9_2(int) = Constant[0] : +# 9| v9_3(void) = Call[ProbeFunction] : func:r9_1, 0:r9_2 +# 9| m9_4(unknown) = ^CallSideEffect : ~m6_4 +# 9| m9_5(unknown) = Chi : total:m6_4, partial:m9_4 +#-----| Goto -> Block 3 +#-----| SEH Exception -> Block 5 + +# 6| Block 1 +# 6| m6_5(unknown) = Phi : from 2:~m13_4, from 6:~m11_5 +# 6| v6_6(void) = AliasedUse : ~m6_5 +# 6| v6_7(void) = ExitFunction : + +# 6| Block 2 +# 6| v6_8(void) = Unwind : +#-----| Goto -> Block 1 + +# 10| Block 3 # 10| r10_1(glval) = VariableAddress[y] : # 10| r10_2(int) = Load[y] : &:r10_1, m7_5 # 10| r10_3(glval) = VariableAddress[x] : @@ -39147,13 +39297,32 @@ try_except.cpp: # 11| v11_3(void) = Call[ProbeFunction] : func:r11_1, 0:r11_2 # 11| m11_4(unknown) = ^CallSideEffect : ~m9_5 # 11| m11_5(unknown) = Chi : total:m9_5, partial:m11_4 -# 16| v16_1(void) = NoOp : -# 6| v6_5(void) = ReturnVoid : -# 6| v6_6(void) = AliasedUse : ~m11_5 -# 6| v6_7(void) = ExitFunction : +#-----| Goto -> Block 6 +#-----| SEH Exception -> Block 5 -# 6| Block 1 -# 6| v6_8(void) = Unreached : +# 13| Block 4 +# 13| r13_1(int) = Constant[0] : +# 13| r13_2(bool) = CompareEQ : r13_5, r13_1 +# 13| v13_3(void) = ConditionalBranch : r13_2 +#-----| False -> Block 7 +#-----| True -> Block 2 + +# 13| Block 5 +# 13| m13_4(unknown) = Phi : from 0:~m9_5, from 3:~m11_5 +# 13| r13_5(int) = Constant[0] : +# 13| r13_6(int) = Constant[-1] : +# 13| r13_7(bool) = CompareEQ : r13_5, r13_6 +# 13| v13_8(void) = ConditionalBranch : r13_7 +#-----| False -> Block 4 +#-----| True -> Block 7 + +# 16| Block 6 +# 16| v16_1(void) = NoOp : +# 6| v6_9(void) = ReturnVoid : +#-----| Goto -> Block 1 + +# 6| Block 7 +# 6| v6_10(void) = Unreached : # 18| void g_cpp() # 18| Block 0 @@ -39171,6 +39340,10 @@ try_except.cpp: # 21| v21_3(void) = Call[ProbeFunction] : func:r21_1, 0:r21_2 # 21| m21_4(unknown) = ^CallSideEffect : ~m18_4 # 21| m21_5(unknown) = Chi : total:m18_4, partial:m21_4 +#-----| Goto -> Block 1 +#-----| SEH Exception -> Block 2 + +# 22| Block 1 # 22| r22_1(glval) = VariableAddress[y] : # 22| r22_2(int) = Load[y] : &:r22_1, m19_5 # 22| r22_3(glval) = VariableAddress[x] : @@ -39180,16 +39353,21 @@ try_except.cpp: # 23| v23_3(void) = Call[ProbeFunction] : func:r23_1, 0:r23_2 # 23| m23_4(unknown) = ^CallSideEffect : ~m21_5 # 23| m23_5(unknown) = Chi : total:m21_5, partial:m23_4 -# 26| r26_1(glval) = FunctionAddress[sink] : -# 26| r26_2(glval) = VariableAddress[x] : -# 26| r26_3(int) = Load[x] : &:r26_2, m22_4 -# 26| v26_4(void) = Call[sink] : func:r26_1, 0:r26_3 -# 26| m26_5(unknown) = ^CallSideEffect : ~m23_5 -# 26| m26_6(unknown) = Chi : total:m23_5, partial:m26_5 -# 28| v28_1(void) = NoOp : -# 18| v18_5(void) = ReturnVoid : -# 18| v18_6(void) = AliasedUse : ~m26_6 -# 18| v18_7(void) = ExitFunction : +#-----| Goto|SEH Exception -> Block 2 + +# 26| Block 2 +# 26| m26_1(unknown) = Phi : from 0:~m21_5, from 1:~m23_5 +# 26| m26_2(int) = Phi : from 0:m19_2, from 1:m22_4 +# 26| r26_3(glval) = FunctionAddress[sink] : +# 26| r26_4(glval) = VariableAddress[x] : +# 26| r26_5(int) = Load[x] : &:r26_4, m26_2 +# 26| v26_6(void) = Call[sink] : func:r26_3, 0:r26_5 +# 26| m26_7(unknown) = ^CallSideEffect : ~m26_1 +# 26| m26_8(unknown) = Chi : total:m26_1, partial:m26_7 +# 28| v28_1(void) = NoOp : +# 18| v18_5(void) = ReturnVoid : +# 18| v18_6(void) = AliasedUse : ~m26_8 +# 18| v18_7(void) = ExitFunction : # 32| void h_cpp(int) # 32| Block 0 @@ -39207,7 +39385,7 @@ 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 2 +#-----| False -> Block 6 #-----| True -> Block 1 # 36| Block 1 @@ -39215,16 +39393,48 @@ try_except.cpp: # 36| v36_2(void) = Call[AfxThrowMemoryException] : func:r36_1 # 36| m36_3(unknown) = ^CallSideEffect : ~m32_4 # 36| m36_4(unknown) = Chi : total:m32_4, partial:m36_3 -#-----| Goto -> Block 2 +#-----| Goto -> Block 6 +#-----| SEH Exception -> Block 4 -# 42| Block 2 -# 42| m42_1(unknown) = Phi : from 0:~m32_4, from 1:~m36_4 +# 39| Block 2 +# 39| r39_1(int) = Constant[0] : +# 39| r39_2(bool) = CompareEQ : r39_7, r39_1 +# 39| v39_3(void) = ConditionalBranch : r39_2 +#-----| False -> Block 3 +#-----| True -> Block 7 + +# 39| Block 3 +# 39| r39_4(int) = Constant[1] : +# 39| r39_5(bool) = CompareEQ : r39_7, r39_4 +# 39| v39_6(void) = ConditionalBranch : r39_5 +#-----| False -> Block 7 +#-----| True -> Block 5 + +# 39| Block 4 +# 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 2 +#-----| True -> Block 7 + +# 40| Block 5 +# 40| r40_1(glval) = FunctionAddress[sink] : +# 40| r40_2(glval) = VariableAddress[x] : +# 40| r40_3(int) = Load[x] : &:r40_2, m33_3 +# 40| v40_4(void) = Call[sink] : func:r40_1, 0:r40_3 +# 40| m40_5(unknown) = ^CallSideEffect : ~m36_4 +# 40| m40_6(unknown) = Chi : total:m36_4, partial:m40_5 +#-----| Goto -> Block 6 + +# 42| Block 6 +# 42| m42_1(unknown) = Phi : from 0:~m32_4, from 1:~m36_4, from 5:~m40_6 # 42| v42_2(void) = NoOp : # 32| v32_7(void) = ReturnVoid : # 32| v32_8(void) = AliasedUse : ~m42_1 # 32| v32_9(void) = ExitFunction : -# 32| Block 3 +# 32| Block 7 # 32| v32_10(void) = Unreached : # 44| void throw_cpp(int) @@ -39247,10 +39457,10 @@ try_except.cpp: #-----| True -> Block 1 # 48| Block 1 -# 48| r48_1(glval) = VariableAddress[#throw48:13] : -# 48| r48_2(int) = Constant[1] : -# 48| m48_3(int) = Store[#throw48:13] : &:r48_1, r48_2 -# 48| v48_4(void) = ThrowValue : &:r48_1, m48_3 +# 48| r48_1(glval) = VariableAddress[#throw48:7] : +# 48| r48_2(int) = Constant[1] : +# 48| m48_3(int) = Store[#throw48:7] : &:r48_1, r48_2 +# 48| v48_4(void) = ThrowValue : &:r48_1, m48_3 #-----| C++ Exception -> Block 4 # 51| Block 2 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 ee6f9f2073a7..e30106d35204 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected @@ -21,14 +21,6 @@ lostReachability 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() | -| try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() | -| try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() | -| try_except.c:39:15:39:15 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:32:6:32:6 | void h(int) | void h(int) | -| try_except.c:39:15:39:15 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:32:6:32:6 | void h(int) | void h(int) | -| try_except.cpp:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.cpp:6:6:6:10 | void f_cpp() | void f_cpp() | -| try_except.cpp:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.cpp:6:6:6:10 | void f_cpp() | void f_cpp() | -| try_except.cpp:39:15:39:15 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.cpp:32:6:32:10 | void h_cpp(int) | void h_cpp(int) | -| try_except.cpp:39:15:39:15 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.cpp:32:6:32:10 | void h_cpp(int) | void h_cpp(int) | switchInstructionWithoutDefaultEdge notMarkedAsConflated wronglyMarkedAsConflated 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 978d05d4b165..26b6d8a18170 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -3000,7 +3000,7 @@ 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? -#-----| C++ Exception -> Block 6 +#-----| SEH Exception -> Block 6 # 21| Block 1 # 21| v21_6(void) = AliasedUse : ~m? @@ -3057,7 +3057,7 @@ 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? -#-----| C++ Exception -> Block 5 +#-----| SEH Exception -> Block 5 # 32| Block 1 # 32| v32_4(void) = AliasedUse : ~m? @@ -3093,7 +3093,7 @@ ir.c: # 40| r40_2(int) = Constant[1] : # 40| v40_3(void) = Call[ExRaiseAccessViolation] : func:r40_1, 0:r40_2 # 40| mu40_4(unknown) = ^CallSideEffect : ~m? -#-----| C++ Exception -> Block 2 +#-----| SEH Exception -> Block 2 # 42| Block 7 # 42| v42_1(void) = NoOp : @@ -3138,7 +3138,7 @@ ir.c: # 62| r62_2(int) = Constant[0] : # 62| v62_3(void) = Call[ExRaiseAccessViolation] : func:r62_1, 0:r62_2 # 62| mu62_4(unknown) = ^CallSideEffect : ~m? -#-----| C++ Exception -> Block 3 +#-----| SEH Exception -> Block 3 # 57| Block 1 # 57| v57_4(void) = AliasedUse : ~m? @@ -3165,7 +3165,7 @@ ir.c: # 73| r73_2(int) = Constant[0] : # 73| v73_3(void) = Call[ExRaiseAccessViolation] : func:r73_1, 0:r73_2 # 73| mu73_4(unknown) = ^CallSideEffect : ~m? -#-----| C++ Exception -> Block 3 +#-----| SEH Exception -> Block 3 # 70| Block 1 # 70| v70_4(void) = AliasedUse : ~m? @@ -3180,7 +3180,7 @@ ir.c: # 76| r76_2(int) = Constant[0] : # 76| v76_3(void) = Call[ExRaiseAccessViolation] : func:r76_1, 0:r76_2 # 76| mu76_4(unknown) = ^CallSideEffect : ~m? -#-----| C++ Exception -> Block 2 +#-----| SEH Exception -> Block 2 # 78| Block 4 # 78| v78_1(void) = NoOp : @@ -3196,7 +3196,7 @@ 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? -#-----| C++ Exception -> Block 2 +#-----| SEH Exception -> Block 2 # 80| Block 1 # 80| v80_4(void) = AliasedUse : ~m? @@ -37288,27 +37288,20 @@ struct_init.cpp: try_except.c: # 6| void f() # 6| Block 0 -# 6| v6_1(void) = EnterFunction : -# 6| mu6_2(unknown) = AliasedDefinition : -# 6| mu6_3(unknown) = InitializeNonLocal : -# 7| r7_1(glval) = VariableAddress[x] : -# 7| mu7_2(int) = Uninitialized[x] : &:r7_1 -# 7| r7_3(glval) = VariableAddress[y] : -# 7| r7_4(int) = Constant[0] : -# 7| mu7_5(int) = Store[y] : &:r7_3, r7_4 -# 9| r9_1(glval) = FunctionAddress[ProbeFunction] : -# 9| r9_2(int) = Constant[0] : -# 9| v9_3(void) = Call[ProbeFunction] : func:r9_1, 0:r9_2 -# 9| mu9_4(unknown) = ^CallSideEffect : ~m? -# 10| r10_1(glval) = VariableAddress[y] : -# 10| r10_2(int) = Load[y] : &:r10_1, ~m? -# 10| r10_3(glval) = VariableAddress[x] : -# 10| mu10_4(int) = Store[x] : &:r10_3, r10_2 -# 11| r11_1(glval) = FunctionAddress[ProbeFunction] : -# 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 7 +# 6| v6_1(void) = EnterFunction : +# 6| mu6_2(unknown) = AliasedDefinition : +# 6| mu6_3(unknown) = InitializeNonLocal : +# 7| r7_1(glval) = VariableAddress[x] : +# 7| mu7_2(int) = Uninitialized[x] : &:r7_1 +# 7| r7_3(glval) = VariableAddress[y] : +# 7| r7_4(int) = Constant[0] : +# 7| mu7_5(int) = Store[y] : &:r7_3, r7_4 +# 9| r9_1(glval) = FunctionAddress[ProbeFunction] : +# 9| r9_2(int) = Constant[0] : +# 9| v9_3(void) = Call[ProbeFunction] : func:r9_1, 0:r9_2 +# 9| mu9_4(unknown) = ^CallSideEffect : ~m? +#-----| Goto -> Block 3 +#-----| SEH Exception -> Block 6 # 6| Block 1 # 6| v6_4(void) = AliasedUse : ~m? @@ -37318,36 +37311,48 @@ try_except.c: # 6| v6_6(void) = Unwind : #-----| Goto -> Block 1 -# 13| Block 3 +# 10| Block 3 +# 10| r10_1(glval) = VariableAddress[y] : +# 10| r10_2(int) = Load[y] : &:r10_1, ~m? +# 10| r10_3(glval) = VariableAddress[x] : +# 10| mu10_4(int) = Store[x] : &:r10_3, r10_2 +# 11| r11_1(glval) = FunctionAddress[ProbeFunction] : +# 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 8 +#-----| SEH Exception -> Block 6 + +# 13| Block 4 # 13| r13_1(int) = Constant[0] : # 13| r13_2(bool) = CompareEQ : r13_7, r13_1 # 13| v13_3(void) = ConditionalBranch : r13_2 -#-----| False -> Block 4 +#-----| False -> Block 5 #-----| True -> Block 2 -# 13| Block 4 +# 13| Block 5 # 13| r13_4(int) = Constant[1] : # 13| r13_5(bool) = CompareEQ : r13_7, r13_4 # 13| v13_6(void) = ConditionalBranch : r13_5 -#-----| True -> Block 6 +#-----| True -> Block 7 -# 13| Block 5 +# 13| Block 6 # 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 +#-----| False -> Block 4 #-----| True -> Block 2 -# 14| Block 6 +# 14| Block 7 # 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 7 +#-----| Goto -> Block 8 -# 16| Block 7 +# 16| Block 8 # 16| v16_1(void) = NoOp : # 6| v6_7(void) = ReturnVoid : #-----| Goto -> Block 1 @@ -37366,6 +37371,18 @@ try_except.c: # 21| r21_2(int) = Constant[0] : # 21| v21_3(void) = Call[ProbeFunction] : func:r21_1, 0:r21_2 # 21| mu21_4(unknown) = ^CallSideEffect : ~m? +#-----| Goto -> Block 3 +#-----| SEH Exception -> Block 4 + +# 18| Block 1 +# 18| v18_4(void) = AliasedUse : ~m? +# 18| v18_5(void) = ExitFunction : + +# 18| Block 2 +# 18| v18_6(void) = Unwind : +#-----| Goto -> Block 1 + +# 22| Block 3 # 22| r22_1(glval) = VariableAddress[y] : # 22| r22_2(int) = Load[y] : &:r22_1, ~m? # 22| r22_3(glval) = VariableAddress[x] : @@ -37374,21 +37391,16 @@ try_except.c: # 23| r23_2(int) = Constant[0] : # 23| v23_3(void) = Call[ProbeFunction] : func:r23_1, 0:r23_2 # 23| mu23_4(unknown) = ^CallSideEffect : ~m? -# 26| r26_1(glval) = FunctionAddress[sink] : -# 26| r26_2(glval) = VariableAddress[x] : -# 26| r26_3(int) = Load[x] : &:r26_2, ~m? -# 26| v26_4(void) = Call[sink] : func:r26_1, 0:r26_3 -# 26| mu26_5(unknown) = ^CallSideEffect : ~m? -# 28| v28_1(void) = NoOp : -# 18| v18_4(void) = ReturnVoid : -#-----| Goto -> Block 1 +#-----| Goto|SEH Exception -> Block 4 -# 18| Block 1 -# 18| v18_5(void) = AliasedUse : ~m? -# 18| v18_6(void) = ExitFunction : - -# 18| Block 2 -# 18| v18_7(void) = Unwind : +# 26| Block 4 +# 26| r26_1(glval) = FunctionAddress[sink] : +# 26| r26_2(glval) = VariableAddress[x] : +# 26| r26_3(int) = Load[x] : &:r26_2, ~m? +# 26| v26_4(void) = Call[sink] : func:r26_1, 0:r26_3 +# 26| mu26_5(unknown) = ^CallSideEffect : ~m? +# 28| v28_1(void) = NoOp : +# 18| v18_7(void) = ReturnVoid : #-----| Goto -> Block 1 # 32| void h(int) @@ -37422,6 +37434,7 @@ try_except.c: # 36| v36_2(void) = Call[AfxThrowMemoryException] : func:r36_1 # 36| mu36_3(unknown) = ^CallSideEffect : ~m? #-----| Goto -> Block 8 +#-----| SEH Exception -> Block 6 # 39| Block 4 # 39| r39_1(int) = Constant[0] : @@ -37457,30 +37470,86 @@ try_except.c: # 32| v32_9(void) = ReturnVoid : #-----| Goto -> Block 1 +# 46| void j(int) +# 46| Block 0 +# 46| v46_1(void) = EnterFunction : +# 46| mu46_2(unknown) = AliasedDefinition : +# 46| mu46_3(unknown) = InitializeNonLocal : +# 46| r46_4(glval) = VariableAddress[b] : +# 46| mu46_5(int) = InitializeParameter[b] : &:r46_4 +# 47| r47_1(glval) = VariableAddress[x] : +# 47| r47_2(int) = Constant[0] : +# 47| mu47_3(int) = Store[x] : &:r47_1, r47_2 +# 49| r49_1(glval) = VariableAddress[y] : +# 49| r49_2(glval) = FunctionAddress[i] : +# 49| r49_3(int) = Call[i] : func:r49_2 +# 49| mu49_4(unknown) = ^CallSideEffect : ~m? +#-----| Goto -> Block 3 +#-----| SEH Exception -> Block 6 + +# 46| Block 1 +# 46| v46_6(void) = AliasedUse : ~m? +# 46| v46_7(void) = ExitFunction : + +# 46| Block 2 +# 46| v46_8(void) = Unwind : +#-----| Goto -> Block 1 + +# 49| Block 3 +# 49| mu49_5(int) = Store[y] : &:r49_1, r49_3 +#-----| Goto -> Block 8 + +# 51| Block 4 +# 51| r51_1(int) = Constant[0] : +# 51| r51_2(bool) = CompareEQ : r51_7, r51_1 +# 51| v51_3(void) = ConditionalBranch : r51_2 +#-----| False -> Block 5 +#-----| True -> Block 2 + +# 51| Block 5 +# 51| r51_4(int) = Constant[1] : +# 51| r51_5(bool) = CompareEQ : r51_7, r51_4 +# 51| v51_6(void) = ConditionalBranch : r51_5 +#-----| True -> Block 7 + +# 51| Block 6 +# 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 2 + +# 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 8 + +# 54| Block 8 +# 54| v54_1(void) = NoOp : +# 46| v46_9(void) = ReturnVoid : +#-----| Goto -> Block 1 + try_except.cpp: # 6| void f_cpp() # 6| Block 0 -# 6| v6_1(void) = EnterFunction : -# 6| mu6_2(unknown) = AliasedDefinition : -# 6| mu6_3(unknown) = InitializeNonLocal : -# 7| r7_1(glval) = VariableAddress[x] : -# 7| mu7_2(int) = Uninitialized[x] : &:r7_1 -# 7| r7_3(glval) = VariableAddress[y] : -# 7| r7_4(int) = Constant[0] : -# 7| mu7_5(int) = Store[y] : &:r7_3, r7_4 -# 9| r9_1(glval) = FunctionAddress[ProbeFunction] : -# 9| r9_2(int) = Constant[0] : -# 9| v9_3(void) = Call[ProbeFunction] : func:r9_1, 0:r9_2 -# 9| mu9_4(unknown) = ^CallSideEffect : ~m? -# 10| r10_1(glval) = VariableAddress[y] : -# 10| r10_2(int) = Load[y] : &:r10_1, ~m? -# 10| r10_3(glval) = VariableAddress[x] : -# 10| mu10_4(int) = Store[x] : &:r10_3, r10_2 -# 11| r11_1(glval) = FunctionAddress[ProbeFunction] : -# 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 7 +# 6| v6_1(void) = EnterFunction : +# 6| mu6_2(unknown) = AliasedDefinition : +# 6| mu6_3(unknown) = InitializeNonLocal : +# 7| r7_1(glval) = VariableAddress[x] : +# 7| mu7_2(int) = Uninitialized[x] : &:r7_1 +# 7| r7_3(glval) = VariableAddress[y] : +# 7| r7_4(int) = Constant[0] : +# 7| mu7_5(int) = Store[y] : &:r7_3, r7_4 +# 9| r9_1(glval) = FunctionAddress[ProbeFunction] : +# 9| r9_2(int) = Constant[0] : +# 9| v9_3(void) = Call[ProbeFunction] : func:r9_1, 0:r9_2 +# 9| mu9_4(unknown) = ^CallSideEffect : ~m? +#-----| Goto -> Block 3 +#-----| SEH Exception -> Block 6 # 6| Block 1 # 6| v6_4(void) = AliasedUse : ~m? @@ -37490,36 +37559,48 @@ try_except.cpp: # 6| v6_6(void) = Unwind : #-----| Goto -> Block 1 -# 13| Block 3 +# 10| Block 3 +# 10| r10_1(glval) = VariableAddress[y] : +# 10| r10_2(int) = Load[y] : &:r10_1, ~m? +# 10| r10_3(glval) = VariableAddress[x] : +# 10| mu10_4(int) = Store[x] : &:r10_3, r10_2 +# 11| r11_1(glval) = FunctionAddress[ProbeFunction] : +# 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 8 +#-----| SEH Exception -> Block 6 + +# 13| Block 4 # 13| r13_1(int) = Constant[0] : # 13| r13_2(bool) = CompareEQ : r13_7, r13_1 # 13| v13_3(void) = ConditionalBranch : r13_2 -#-----| False -> Block 4 +#-----| False -> Block 5 #-----| True -> Block 2 -# 13| Block 4 +# 13| Block 5 # 13| r13_4(int) = Constant[1] : # 13| r13_5(bool) = CompareEQ : r13_7, r13_4 # 13| v13_6(void) = ConditionalBranch : r13_5 -#-----| True -> Block 6 +#-----| True -> Block 7 -# 13| Block 5 +# 13| Block 6 # 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 +#-----| False -> Block 4 #-----| True -> Block 2 -# 14| Block 6 +# 14| Block 7 # 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 7 +#-----| Goto -> Block 8 -# 16| Block 7 +# 16| Block 8 # 16| v16_1(void) = NoOp : # 6| v6_7(void) = ReturnVoid : #-----| Goto -> Block 1 @@ -37538,6 +37619,18 @@ try_except.cpp: # 21| r21_2(int) = Constant[0] : # 21| v21_3(void) = Call[ProbeFunction] : func:r21_1, 0:r21_2 # 21| mu21_4(unknown) = ^CallSideEffect : ~m? +#-----| Goto -> Block 3 +#-----| SEH Exception -> Block 4 + +# 18| Block 1 +# 18| v18_4(void) = AliasedUse : ~m? +# 18| v18_5(void) = ExitFunction : + +# 18| Block 2 +# 18| v18_6(void) = Unwind : +#-----| Goto -> Block 1 + +# 22| Block 3 # 22| r22_1(glval) = VariableAddress[y] : # 22| r22_2(int) = Load[y] : &:r22_1, ~m? # 22| r22_3(glval) = VariableAddress[x] : @@ -37546,21 +37639,16 @@ try_except.cpp: # 23| r23_2(int) = Constant[0] : # 23| v23_3(void) = Call[ProbeFunction] : func:r23_1, 0:r23_2 # 23| mu23_4(unknown) = ^CallSideEffect : ~m? -# 26| r26_1(glval) = FunctionAddress[sink] : -# 26| r26_2(glval) = VariableAddress[x] : -# 26| r26_3(int) = Load[x] : &:r26_2, ~m? -# 26| v26_4(void) = Call[sink] : func:r26_1, 0:r26_3 -# 26| mu26_5(unknown) = ^CallSideEffect : ~m? -# 28| v28_1(void) = NoOp : -# 18| v18_4(void) = ReturnVoid : -#-----| Goto -> Block 1 +#-----| Goto|SEH Exception -> Block 4 -# 18| Block 1 -# 18| v18_5(void) = AliasedUse : ~m? -# 18| v18_6(void) = ExitFunction : - -# 18| Block 2 -# 18| v18_7(void) = Unwind : +# 26| Block 4 +# 26| r26_1(glval) = FunctionAddress[sink] : +# 26| r26_2(glval) = VariableAddress[x] : +# 26| r26_3(int) = Load[x] : &:r26_2, ~m? +# 26| v26_4(void) = Call[sink] : func:r26_1, 0:r26_3 +# 26| mu26_5(unknown) = ^CallSideEffect : ~m? +# 28| v28_1(void) = NoOp : +# 18| v18_7(void) = ReturnVoid : #-----| Goto -> Block 1 # 32| void h_cpp(int) @@ -37594,6 +37682,7 @@ try_except.cpp: # 36| v36_2(void) = Call[AfxThrowMemoryException] : func:r36_1 # 36| mu36_3(unknown) = ^CallSideEffect : ~m? #-----| Goto -> Block 8 +#-----| SEH Exception -> Block 6 # 39| Block 4 # 39| r39_1(int) = Constant[0] : @@ -37656,10 +37745,10 @@ try_except.cpp: #-----| Goto -> Block 1 # 48| Block 3 -# 48| r48_1(glval) = VariableAddress[#throw48:13] : -# 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? +# 48| r48_1(glval) = VariableAddress[#throw48:7] : +# 48| r48_2(int) = Constant[1] : +# 48| mu48_3(int) = Store[#throw48:7] : &:r48_1, r48_2 +# 48| v48_4(void) = ThrowValue : &:r48_1, ~m? #-----| C++ Exception -> Block 6 # 51| Block 4 diff --git a/cpp/ql/test/library-tests/ir/ir/try_except.c b/cpp/ql/test/library-tests/ir/ir/try_except.c index 410068dae5ea..48f3227bf078 100644 --- a/cpp/ql/test/library-tests/ir/ir/try_except.c +++ b/cpp/ql/test/library-tests/ir/ir/try_except.c @@ -31,12 +31,24 @@ void AfxThrowMemoryException(); void h(int b) { int x = 0; - __try { - if (b) { - AfxThrowMemoryException(); - } - } - __except (1) { - sink(x); + __try { + if (b) { + AfxThrowMemoryException(); } -} \ No newline at end of file + } + __except (1) { + sink(x); + } +} + +int i(); + +void j(int b) { + int x = 0; + __try { + int y = i(); + } + __except (1) { + sink(x); + } +} 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 9bf297263b75..d1e33de0ba00 100644 --- a/cpp/ql/test/library-tests/ir/ir/try_except.cpp +++ b/cpp/ql/test/library-tests/ir/ir/try_except.cpp @@ -31,24 +31,24 @@ void AfxThrowMemoryException(); void h_cpp(int b) { int x = 0; - __try { - if (b) { - AfxThrowMemoryException(); - } - } - __except (1) { - sink(x); + __try { + if (b) { + AfxThrowMemoryException(); } + } + __except (1) { + sink(x); + } } void throw_cpp(int b) { int x = 0; - __try { - if (b) { - throw 1; - } - } - __except (1) { - sink(x); + __try { + if (b) { + throw 1; } + } + __except (1) { + sink(x); + } }