From 254d55091c08f70f337364c4f79fbdf43896dfc3 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 10 Dec 2024 16:36:49 +0100 Subject: [PATCH] C++: Generate an SEH exception edge for each call inside a SEH block --- .../raw/internal/TranslatedCall.qll | 7 +- .../library-tests/ir/ir/aliased_ir.expected | 409 +++++++++++++----- .../ir/ir/raw_consistency.expected | 8 - .../test/library-tests/ir/ir/raw_ir.expected | 211 +++++---- 4 files changed, 433 insertions(+), 202 deletions(-) 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 15fa13242f94..a1d76bb64917 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 @@ -361,7 +361,12 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { not exists(MemberFunction func | expr.getTarget() = func and func.isStatic()) } - final override predicate mayThrowException(ExceptionEdge e) { this.mustThrowException(e) } + final override predicate mayThrowException(ExceptionEdge e) { + this.mustThrowException(e) + or + expr.getEnclosingStmt().getParentStmt*() instanceof MicrosoftTryStmt and + e instanceof SehExceptionEdge + } final override predicate mustThrowException(ExceptionEdge e) { expr.getTarget() instanceof AlwaysSehThrowingFunction and 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 71bc56386a47..ea5bfaba4496 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -38758,20 +38758,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] : @@ -38781,13 +38794,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 @@ -38805,6 +38837,18 @@ 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 3 +#-----| SEH Exception -> Block 4 + +# 18| Block 1 +# 18| v18_5(void) = AliasedUse : ~m26_8 +# 18| v18_6(void) = ExitFunction : + +# 18| Block 2 +# 18| v18_7(void) = Unwind : +#-----| Goto -> Block 1 + +# 22| Block 3 # 22| r22_1(glval) = VariableAddress[y] : # 22| r22_2(int) = Load[y] : &:r22_1, m19_5 # 22| r22_3(glval) = VariableAddress[x] : @@ -38814,16 +38858,24 @@ 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 4 + +# 26| Block 4 +# 26| m26_1(unknown) = Phi : from 0:~m21_5, from 3:~m23_5 +# 26| m26_2(int) = Phi : from 0:m19_2, from 3: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 +#-----| Goto -> Block 5 +#-----| SEH Exception -> Block 2 + +# 28| Block 5 +# 28| v28_1(void) = NoOp : +# 18| v18_8(void) = ReturnVoid : +#-----| Goto -> Block 1 # 32| void h(int) # 32| Block 0 @@ -38839,43 +38891,97 @@ try_except.c: # 35| r35_1(glval) = VariableAddress[b] : # 35| r35_2(int) = Load[b] : &:r35_1, m32_6 # 35| v35_3(void) = ConditionalBranch : r35_2 -#-----| False -> Block 2 -#-----| True -> Block 1 +#-----| False -> Block 8 +#-----| True -> Block 3 -# 36| Block 1 +# 32| Block 1 +# 32| m32_7(unknown) = Phi : from 2:~m40_6, from 8:~m42_1 +# 32| v32_8(void) = AliasedUse : ~m32_7 +# 32| v32_9(void) = ExitFunction : + +# 32| Block 2 +# 32| v32_10(void) = Unwind : +#-----| Goto -> Block 1 + +# 36| Block 3 # 36| r36_1(glval) = FunctionAddress[AfxThrowMemoryException] : # 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 8 +#-----| SEH Exception -> Block 6 -# 42| Block 2 -# 42| m42_1(unknown) = Phi : from 0:~m32_4, from 1:~m36_4 -# 42| v42_2(void) = NoOp : -# 32| v32_7(void) = ReturnVoid : -# 32| v32_8(void) = AliasedUse : ~m42_1 -# 32| v32_9(void) = ExitFunction : +# 39| Block 4 +# 39| r39_1(int) = Constant[0] : +# 39| r39_2(bool) = CompareEQ : r39_7, r39_1 +# 39| v39_3(void) = ConditionalBranch : r39_2 +#-----| False -> Block 5 +#-----| True -> Block 9 + +# 39| Block 5 +# 39| r39_4(int) = Constant[1] : +# 39| r39_5(bool) = CompareEQ : r39_7, r39_4 +# 39| v39_6(void) = ConditionalBranch : r39_5 +#-----| False -> Block 9 +#-----| True -> Block 7 -# 32| Block 3 -# 32| v32_10(void) = Unreached : +# 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 9 + +# 40| Block 7 +# 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 8 +#-----| SEH Exception -> Block 2 + +# 42| Block 8 +# 42| m42_1(unknown) = Phi : from 0:~m32_4, from 3:~m36_4, from 7:~m40_6 +# 42| v42_2(void) = NoOp : +# 32| v32_11(void) = ReturnVoid : +#-----| Goto -> Block 1 + +# 32| Block 9 +# 32| v32_12(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] : @@ -38885,13 +38991,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 @@ -38909,6 +39034,18 @@ 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 3 +#-----| SEH Exception -> Block 4 + +# 18| Block 1 +# 18| v18_5(void) = AliasedUse : ~m26_8 +# 18| v18_6(void) = ExitFunction : + +# 18| Block 2 +# 18| v18_7(void) = Unwind : +#-----| Goto -> Block 1 + +# 22| Block 3 # 22| r22_1(glval) = VariableAddress[y] : # 22| r22_2(int) = Load[y] : &:r22_1, m19_5 # 22| r22_3(glval) = VariableAddress[x] : @@ -38918,16 +39055,24 @@ 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 4 + +# 26| Block 4 +# 26| m26_1(unknown) = Phi : from 0:~m21_5, from 3:~m23_5 +# 26| m26_2(int) = Phi : from 0:m19_2, from 3: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 +#-----| Goto -> Block 5 +#-----| SEH Exception -> Block 2 + +# 28| Block 5 +# 28| v28_1(void) = NoOp : +# 18| v18_8(void) = ReturnVoid : +#-----| Goto -> Block 1 # 32| void h_cpp(int) # 32| Block 0 @@ -38945,25 +39090,66 @@ 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 -#-----| True -> Block 1 +#-----| False -> Block 8 +#-----| True -> Block 3 + +# 32| Block 1 +# 32| m32_7(unknown) = Phi : from 2:~m40_6, from 8:~m42_1 +# 32| v32_8(void) = AliasedUse : ~m32_7 +# 32| v32_9(void) = ExitFunction : -# 36| Block 1 +# 32| Block 2 +# 32| v32_10(void) = Unwind : +#-----| Goto -> Block 1 + +# 36| Block 3 # 36| r36_1(glval) = FunctionAddress[AfxThrowMemoryException] : # 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 8 +#-----| SEH Exception -> Block 6 -# 42| Block 2 -# 42| m42_1(unknown) = Phi : from 0:~m32_4, from 1:~m36_4 -# 42| v42_2(void) = NoOp : -# 32| v32_7(void) = ReturnVoid : -# 32| v32_8(void) = AliasedUse : ~m42_1 -# 32| v32_9(void) = ExitFunction : +# 39| Block 4 +# 39| r39_1(int) = Constant[0] : +# 39| r39_2(bool) = CompareEQ : r39_7, r39_1 +# 39| v39_3(void) = ConditionalBranch : r39_2 +#-----| False -> Block 5 +#-----| True -> Block 9 -# 32| Block 3 -# 32| v32_10(void) = Unreached : +# 39| Block 5 +# 39| r39_4(int) = Constant[1] : +# 39| r39_5(bool) = CompareEQ : r39_7, r39_4 +# 39| v39_6(void) = ConditionalBranch : r39_5 +#-----| False -> Block 9 +#-----| True -> Block 7 + +# 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 9 + +# 40| Block 7 +# 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 8 +#-----| SEH Exception -> Block 2 + +# 42| Block 8 +# 42| m42_1(unknown) = Phi : from 0:~m32_4, from 3:~m36_4, from 7:~m40_6 +# 42| v42_2(void) = NoOp : +# 32| v32_11(void) = ReturnVoid : +#-----| Goto -> Block 1 + +# 32| Block 9 +# 32| v32_12(void) = Unreached : # 44| void throw_cpp(int) # 44| Block 0 @@ -38981,53 +39167,62 @@ 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 6 -#-----| True -> Block 1 +#-----| False -> Block 8 +#-----| True -> Block 3 -# 48| Block 1 +# 44| Block 1 +# 44| m44_7(unknown) = Phi : from 2:~m52_6, from 8:~m54_1 +# 44| v44_8(void) = AliasedUse : ~m44_7 +# 44| v44_9(void) = ExitFunction : + +# 44| Block 2 +# 44| v44_10(void) = Unwind : +#-----| Goto -> Block 1 + +# 48| Block 3 # 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 -#-----| C++ Exception -> Block 4 +#-----| C++ Exception -> Block 6 -# 51| Block 2 +# 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 3 -#-----| True -> Block 7 +#-----| False -> Block 5 +#-----| True -> Block 9 -# 51| Block 3 +# 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 -#-----| False -> Block 7 -#-----| True -> Block 5 +#-----| False -> Block 9 +#-----| True -> Block 7 -# 51| Block 4 +# 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 2 -#-----| True -> Block 7 +#-----| False -> Block 4 +#-----| True -> Block 9 -# 52| Block 5 +# 52| Block 7 # 52| r52_1(glval) = FunctionAddress[sink] : # 52| r52_2(glval) = VariableAddress[x] : # 52| r52_3(int) = Load[x] : &:r52_2, m45_3 # 52| v52_4(void) = Call[sink] : func:r52_1, 0:r52_3 # 52| m52_5(unknown) = ^CallSideEffect : ~m44_4 # 52| m52_6(unknown) = Chi : total:m44_4, partial:m52_5 -#-----| Goto -> Block 6 +#-----| Goto -> Block 8 +#-----| SEH Exception -> Block 2 -# 54| Block 6 -# 54| m54_1(unknown) = Phi : from 0:~m44_4, from 5:~m52_6 -# 54| v54_2(void) = NoOp : -# 44| v44_7(void) = ReturnVoid : -# 44| v44_8(void) = AliasedUse : ~m54_1 -# 44| v44_9(void) = ExitFunction : +# 54| Block 8 +# 54| m54_1(unknown) = Phi : from 0:~m44_4, from 7:~m52_6 +# 54| v54_2(void) = NoOp : +# 44| v44_11(void) = ReturnVoid : +#-----| Goto -> Block 1 -# 44| Block 7 -# 44| v44_10(void) = Unreached : +# 44| Block 9 +# 44| v44_12(void) = Unreached : 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 7b5d32c65438..0e6d67a5ae9a 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 370ca8855e36..1f40ba6cce8e 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -36997,27 +36997,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? @@ -37027,36 +37020,49 @@ 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 +#-----| SEH Exception -> Block 2 -# 16| Block 7 +# 16| Block 8 # 16| v16_1(void) = NoOp : # 6| v6_7(void) = ReturnVoid : #-----| Goto -> Block 1 @@ -37075,6 +37081,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] : @@ -37083,21 +37101,20 @@ 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 : +# 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? +#-----| Goto -> Block 5 +#-----| SEH Exception -> Block 2 -# 18| Block 2 -# 18| v18_7(void) = Unwind : +# 28| Block 5 +# 28| v28_1(void) = NoOp : +# 18| v18_7(void) = ReturnVoid : #-----| Goto -> Block 1 # 32| void h(int) @@ -37129,6 +37146,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] : @@ -37158,6 +37176,7 @@ try_except.c: # 40| v40_4(void) = Call[sink] : func:r40_1, 0:r40_3 # 40| mu40_5(unknown) = ^CallSideEffect : ~m? #-----| Goto -> Block 8 +#-----| SEH Exception -> Block 2 # 42| Block 8 # 42| v42_1(void) = NoOp : @@ -37167,27 +37186,20 @@ try_except.c: 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? @@ -37197,36 +37209,49 @@ 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 +#-----| SEH Exception -> Block 2 -# 16| Block 7 +# 16| Block 8 # 16| v16_1(void) = NoOp : # 6| v6_7(void) = ReturnVoid : #-----| Goto -> Block 1 @@ -37245,6 +37270,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] : @@ -37253,21 +37290,20 @@ 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 : +# 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? +#-----| Goto -> Block 5 +#-----| SEH Exception -> Block 2 -# 18| Block 2 -# 18| v18_7(void) = Unwind : +# 28| Block 5 +# 28| v28_1(void) = NoOp : +# 18| v18_7(void) = ReturnVoid : #-----| Goto -> Block 1 # 32| void h_cpp(int) @@ -37301,6 +37337,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] : @@ -37330,6 +37367,7 @@ try_except.cpp: # 40| v40_4(void) = Call[sink] : func:r40_1, 0:r40_3 # 40| mu40_5(unknown) = ^CallSideEffect : ~m? #-----| Goto -> Block 8 +#-----| SEH Exception -> Block 2 # 42| Block 8 # 42| v42_1(void) = NoOp : @@ -37397,6 +37435,7 @@ try_except.cpp: # 52| v52_4(void) = Call[sink] : func:r52_1, 0:r52_3 # 52| mu52_5(unknown) = ^CallSideEffect : ~m? #-----| Goto -> Block 8 +#-----| SEH Exception -> Block 2 # 54| Block 8 # 54| v54_1(void) = NoOp :