From a974cb186168d13af5da3fd29b092167fa510ffe Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 22 Dec 2022 10:01:41 +0000 Subject: [PATCH] C++: Add another test with an _actual_ throw. --- .../library-tests/ir/ir/PrintAST.expected | 197 +++++++++++++++ .../ir/ir/operand_locations.expected | 97 ++++++++ .../ir/ir/raw_consistency.expected | 4 + .../test/library-tests/ir/ir/raw_ir.expected | 230 ++++++++++++++++++ .../test/library-tests/ir/ir/try_except.cpp | 54 ++++ 5 files changed, 582 insertions(+) create mode 100644 cpp/ql/test/library-tests/ir/ir/try_except.cpp diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 78ce035e880..c86e4dc5b8f 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -14970,3 +14970,200 @@ try_except.c: # 40| Type = [IntType] int # 40| ValueCategory = prvalue(load) # 42| getStmt(2): [ReturnStmt] return ... +try_except.cpp: +# 3| [TopLevelFunction] void ProbeFunction() +# 3| : +# 4| [TopLevelFunction] void sink() +# 4| : +# 6| [TopLevelFunction] void f_cpp() +# 6| : +# 6| getEntryPoint(): [BlockStmt] { ... } +# 7| getStmt(0): [DeclStmt] declaration +# 7| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 7| Type = [IntType] int +# 7| getDeclarationEntry(1): [VariableDeclarationEntry] definition of y +# 7| Type = [IntType] int +# 7| getVariable().getInitializer(): [Initializer] initializer for y +# 7| getExpr(): [Literal] 0 +# 7| Type = [IntType] int +# 7| Value = [Literal] 0 +# 7| ValueCategory = prvalue +# 8| getStmt(1): [MicrosoftTryExceptStmt] __try { ... } __except( ... ) { ... } +# 8| getStmt(): [BlockStmt] { ... } +# 9| getStmt(0): [ExprStmt] ExprStmt +# 9| getExpr(): [FunctionCall] call to ProbeFunction +# 9| Type = [VoidType] void +# 9| ValueCategory = prvalue +# 9| getArgument(0): [Literal] 0 +# 9| Type = [IntType] int +# 9| Value = [Literal] 0 +# 9| ValueCategory = prvalue +# 10| getStmt(1): [ExprStmt] ExprStmt +# 10| getExpr(): [AssignExpr] ... = ... +# 10| Type = [IntType] int +# 10| ValueCategory = lvalue +# 10| getLValue(): [VariableAccess] x +# 10| Type = [IntType] int +# 10| ValueCategory = lvalue +# 10| getRValue(): [VariableAccess] y +# 10| Type = [IntType] int +# 10| ValueCategory = prvalue(load) +# 11| getStmt(2): [ExprStmt] ExprStmt +# 11| getExpr(): [FunctionCall] call to ProbeFunction +# 11| Type = [VoidType] void +# 11| ValueCategory = prvalue +# 11| getArgument(0): [Literal] 0 +# 11| Type = [IntType] int +# 11| Value = [Literal] 0 +# 11| ValueCategory = prvalue +# 13| getCondition(): [Literal] 0 +# 13| Type = [IntType] int +# 13| Value = [Literal] 0 +# 13| ValueCategory = prvalue +# 13| getExcept(): [BlockStmt] { ... } +# 14| getStmt(0): [ExprStmt] ExprStmt +# 14| getExpr(): [FunctionCall] call to sink +# 14| Type = [VoidType] void +# 14| ValueCategory = prvalue +# 14| getArgument(0): [VariableAccess] x +# 14| Type = [IntType] int +# 14| ValueCategory = prvalue(load) +# 16| getStmt(2): [ReturnStmt] return ... +# 18| [TopLevelFunction] void g_cpp() +# 18| : +# 18| getEntryPoint(): [BlockStmt] { ... } +# 19| getStmt(0): [DeclStmt] declaration +# 19| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 19| Type = [IntType] int +# 19| getDeclarationEntry(1): [VariableDeclarationEntry] definition of y +# 19| Type = [IntType] int +# 19| getVariable().getInitializer(): [Initializer] initializer for y +# 19| getExpr(): [Literal] 0 +# 19| Type = [IntType] int +# 19| Value = [Literal] 0 +# 19| ValueCategory = prvalue +# 20| getStmt(1): [MicrosoftTryFinallyStmt] __try { ... } __finally { ... } +# 20| getStmt(): [BlockStmt] { ... } +# 21| getStmt(0): [ExprStmt] ExprStmt +# 21| getExpr(): [FunctionCall] call to ProbeFunction +# 21| Type = [VoidType] void +# 21| ValueCategory = prvalue +# 21| getArgument(0): [Literal] 0 +# 21| Type = [IntType] int +# 21| Value = [Literal] 0 +# 21| ValueCategory = prvalue +# 22| getStmt(1): [ExprStmt] ExprStmt +# 22| getExpr(): [AssignExpr] ... = ... +# 22| Type = [IntType] int +# 22| ValueCategory = lvalue +# 22| getLValue(): [VariableAccess] x +# 22| Type = [IntType] int +# 22| ValueCategory = lvalue +# 22| getRValue(): [VariableAccess] y +# 22| Type = [IntType] int +# 22| ValueCategory = prvalue(load) +# 23| getStmt(2): [ExprStmt] ExprStmt +# 23| getExpr(): [FunctionCall] call to ProbeFunction +# 23| Type = [VoidType] void +# 23| ValueCategory = prvalue +# 23| getArgument(0): [Literal] 0 +# 23| Type = [IntType] int +# 23| Value = [Literal] 0 +# 23| ValueCategory = prvalue +# 25| getFinally(): [BlockStmt] { ... } +# 26| getStmt(0): [ExprStmt] ExprStmt +# 26| getExpr(): [FunctionCall] call to sink +# 26| Type = [VoidType] void +# 26| ValueCategory = prvalue +# 26| getArgument(0): [VariableAccess] x +# 26| Type = [IntType] int +# 26| ValueCategory = prvalue(load) +# 28| getStmt(2): [ReturnStmt] return ... +# 30| [TopLevelFunction] void AfxThrowMemoryException() +# 30| : +# 32| [TopLevelFunction] void h_cpp(int) +# 32| : +# 32| getParameter(0): [Parameter] b +# 32| Type = [IntType] int +# 32| getEntryPoint(): [BlockStmt] { ... } +# 33| getStmt(0): [DeclStmt] declaration +# 33| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 33| Type = [IntType] int +# 33| getVariable().getInitializer(): [Initializer] initializer for x +# 33| getExpr(): [Literal] 0 +# 33| Type = [IntType] int +# 33| Value = [Literal] 0 +# 33| ValueCategory = prvalue +# 34| getStmt(1): [MicrosoftTryExceptStmt] __try { ... } __except( ... ) { ... } +# 34| getStmt(): [BlockStmt] { ... } +# 35| getStmt(0): [IfStmt] if (...) ... +# 35| getCondition(): [VariableAccess] b +# 35| Type = [IntType] int +# 35| ValueCategory = prvalue(load) +# 35| getThen(): [BlockStmt] { ... } +# 36| getStmt(0): [ExprStmt] ExprStmt +# 36| getExpr(): [FunctionCall] call to AfxThrowMemoryException +# 36| Type = [VoidType] void +# 36| ValueCategory = prvalue +# 35| getCondition().getFullyConverted(): [CStyleCast] (bool)... +# 35| Conversion = [BoolConversion] conversion to bool +# 35| Type = [BoolType] bool +# 35| ValueCategory = prvalue +# 39| getCondition(): [Literal] 1 +# 39| Type = [IntType] int +# 39| Value = [Literal] 1 +# 39| ValueCategory = prvalue +# 39| getExcept(): [BlockStmt] { ... } +# 40| getStmt(0): [ExprStmt] ExprStmt +# 40| getExpr(): [FunctionCall] call to sink +# 40| Type = [VoidType] void +# 40| ValueCategory = prvalue +# 40| getArgument(0): [VariableAccess] x +# 40| Type = [IntType] int +# 40| ValueCategory = prvalue(load) +# 42| getStmt(2): [ReturnStmt] return ... +# 44| [TopLevelFunction] void throw_cpp(int) +# 44| : +# 44| getParameter(0): [Parameter] b +# 44| Type = [IntType] int +# 44| getEntryPoint(): [BlockStmt] { ... } +# 45| getStmt(0): [DeclStmt] declaration +# 45| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 45| Type = [IntType] int +# 45| getVariable().getInitializer(): [Initializer] initializer for x +# 45| getExpr(): [Literal] 0 +# 45| Type = [IntType] int +# 45| Value = [Literal] 0 +# 45| ValueCategory = prvalue +# 46| getStmt(1): [MicrosoftTryExceptStmt] __try { ... } __except( ... ) { ... } +# 46| getStmt(): [BlockStmt] { ... } +# 47| getStmt(0): [IfStmt] if (...) ... +# 47| getCondition(): [VariableAccess] b +# 47| Type = [IntType] int +# 47| ValueCategory = prvalue(load) +# 47| getThen(): [BlockStmt] { ... } +# 48| getStmt(0): [ExprStmt] ExprStmt +# 48| getExpr(): [ThrowExpr] throw ... +# 48| Type = [IntType] int +# 48| ValueCategory = prvalue +# 48| getExpr(): [Literal] 1 +# 48| Type = [IntType] int +# 48| Value = [Literal] 1 +# 48| ValueCategory = prvalue +# 47| getCondition().getFullyConverted(): [CStyleCast] (bool)... +# 47| Conversion = [BoolConversion] conversion to bool +# 47| Type = [BoolType] bool +# 47| 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 ... diff --git a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected index b57f5d4e732..3bbbd4f099a 100644 --- a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected +++ b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected @@ -9202,3 +9202,100 @@ | try_except.c:36:13:36:35 | SideEffect | ~m32_4 | | try_except.c:42:1:42:1 | Phi | from 0:~m32_4 | | try_except.c:42:1:42:1 | Phi | from 1:~m36_4 | +| try_except.cpp:6:6:6:10 | ChiPartial | partial:m6_3 | +| try_except.cpp:6:6:6:10 | ChiTotal | total:m6_2 | +| try_except.cpp:6:6:6:10 | SideEffect | ~m11_5 | +| try_except.cpp:7:7:7:7 | Address | &:r7_1 | +| try_except.cpp:7:10:7:10 | Address | &:r7_3 | +| try_except.cpp:7:13:7:14 | StoreValue | r7_4 | +| try_except.cpp:9:5:9:17 | CallTarget | func:r9_1 | +| try_except.cpp:9:5:9:17 | ChiPartial | partial:m9_4 | +| try_except.cpp:9:5:9:17 | ChiTotal | total:m6_4 | +| try_except.cpp:9:5:9:17 | SideEffect | ~m6_4 | +| try_except.cpp:9:19:9:19 | Arg(0) | 0:r9_2 | +| try_except.cpp:10:5:10:5 | Address | &:r10_3 | +| try_except.cpp:10:9:10:9 | Address | &:r10_1 | +| try_except.cpp:10:9:10:9 | Load | m7_5 | +| try_except.cpp:10:9:10:9 | StoreValue | r10_2 | +| try_except.cpp:11:5:11:17 | CallTarget | func:r11_1 | +| try_except.cpp:11:5:11:17 | ChiPartial | partial:m11_4 | +| try_except.cpp:11:5:11:17 | ChiTotal | total:m9_5 | +| try_except.cpp:11:5:11:17 | SideEffect | ~m9_5 | +| try_except.cpp:11:19:11:19 | Arg(0) | 0:r11_2 | +| try_except.cpp:18:6:18:10 | ChiPartial | partial:m18_3 | +| try_except.cpp:18:6:18:10 | ChiTotal | total:m18_2 | +| try_except.cpp:18:6:18:10 | SideEffect | ~m26_6 | +| try_except.cpp:19:7:19:7 | Address | &:r19_1 | +| try_except.cpp:19:10:19:10 | Address | &:r19_3 | +| try_except.cpp:19:13:19:14 | StoreValue | r19_4 | +| try_except.cpp:21:5:21:17 | CallTarget | func:r21_1 | +| try_except.cpp:21:5:21:17 | ChiPartial | partial:m21_4 | +| try_except.cpp:21:5:21:17 | ChiTotal | total:m18_4 | +| try_except.cpp:21:5:21:17 | SideEffect | ~m18_4 | +| try_except.cpp:21:19:21:19 | Arg(0) | 0:r21_2 | +| try_except.cpp:22:5:22:5 | Address | &:r22_3 | +| try_except.cpp:22:9:22:9 | Address | &:r22_1 | +| try_except.cpp:22:9:22:9 | Load | m19_5 | +| try_except.cpp:22:9:22:9 | StoreValue | r22_2 | +| try_except.cpp:23:5:23:17 | CallTarget | func:r23_1 | +| try_except.cpp:23:5:23:17 | ChiPartial | partial:m23_4 | +| try_except.cpp:23:5:23:17 | ChiTotal | total:m21_5 | +| try_except.cpp:23:5:23:17 | SideEffect | ~m21_5 | +| try_except.cpp:23:19:23:19 | Arg(0) | 0:r23_2 | +| try_except.cpp:26:5:26:8 | CallTarget | func:r26_1 | +| try_except.cpp:26:5:26:8 | ChiPartial | partial:m26_5 | +| try_except.cpp:26:5:26:8 | ChiTotal | total:m23_5 | +| try_except.cpp:26:5:26:8 | SideEffect | ~m23_5 | +| try_except.cpp:26:10:26:10 | Address | &:r26_2 | +| try_except.cpp:26:10:26:10 | Arg(0) | 0:r26_3 | +| try_except.cpp:26:10:26:10 | Load | m22_4 | +| try_except.cpp:32:6:32:10 | ChiPartial | partial:m32_3 | +| try_except.cpp:32:6:32:10 | ChiTotal | total:m32_2 | +| try_except.cpp:32:6:32:10 | SideEffect | ~m42_1 | +| try_except.cpp:32:16:32:16 | Address | &:r32_5 | +| try_except.cpp:33:7:33:7 | Address | &:r33_1 | +| try_except.cpp:33:10:33:11 | StoreValue | r33_2 | +| try_except.cpp:35:13:35:13 | Address | &:r35_1 | +| try_except.cpp:35:13:35:13 | Condition | r35_4 | +| try_except.cpp:35:13:35:13 | Left | r35_2 | +| try_except.cpp:35:13:35:13 | Load | m32_6 | +| try_except.cpp:35:13:35:13 | Right | r35_3 | +| try_except.cpp:36:13:36:35 | CallTarget | func:r36_1 | +| try_except.cpp:36:13:36:35 | ChiPartial | partial:m36_3 | +| try_except.cpp:36:13:36:35 | ChiTotal | total:m32_4 | +| try_except.cpp:36:13:36:35 | SideEffect | ~m32_4 | +| try_except.cpp:42:1:42:1 | Phi | from 0:~m32_4 | +| try_except.cpp:42:1:42:1 | Phi | from 1:~m36_4 | +| try_except.cpp:44:6:44:14 | ChiPartial | partial:m44_3 | +| try_except.cpp:44:6:44:14 | ChiTotal | total:m44_2 | +| try_except.cpp:44:6:44:14 | SideEffect | ~m54_1 | +| try_except.cpp:44:20:44:20 | Address | &:r44_5 | +| try_except.cpp:45:7:45:7 | Address | &:r45_1 | +| try_except.cpp:45:10:45:11 | StoreValue | r45_2 | +| try_except.cpp:47:13:47:13 | Address | &:r47_1 | +| try_except.cpp:47:13:47:13 | Condition | r47_4 | +| try_except.cpp:47:13:47:13 | Left | r47_2 | +| try_except.cpp:47:13:47:13 | Load | m44_6 | +| try_except.cpp:47:13:47:13 | Right | r47_3 | +| try_except.cpp:48:13:48:19 | Address | &:r48_1 | +| try_except.cpp:48:13:48:19 | Address | &:r48_1 | +| try_except.cpp:48:13:48:19 | Load | m48_3 | +| try_except.cpp:48:19:48:19 | StoreValue | r48_2 | +| try_except.cpp:51:15:51:15 | Left | r51_7 | +| try_except.cpp:51:15:51:15 | Left | r51_7 | +| try_except.cpp:51:15:51:15 | Left | r51_7 | +| try_except.cpp:51:18:53:5 | Condition | r51_2 | +| try_except.cpp:51:18:53:5 | Condition | r51_5 | +| try_except.cpp:51:18:53:5 | Condition | r51_9 | +| try_except.cpp:51:18:53:5 | Right | r51_1 | +| try_except.cpp:51:18:53:5 | Right | r51_4 | +| try_except.cpp:51:18:53:5 | Right | r51_8 | +| try_except.cpp:52:9:52:12 | CallTarget | func:r52_1 | +| try_except.cpp:52:9:52:12 | ChiPartial | partial:m52_5 | +| try_except.cpp:52:9:52:12 | ChiTotal | total:m44_4 | +| try_except.cpp:52:9:52:12 | SideEffect | ~m44_4 | +| try_except.cpp:52:14:52:14 | Address | &:r52_2 | +| try_except.cpp:52:14:52:14 | Arg(0) | 0:r52_3 | +| try_except.cpp:52:14:52:14 | Load | m45_3 | +| try_except.cpp:54:1:54:1 | Phi | from 0:~m44_4 | +| try_except.cpp:54:1:54:1 | Phi | from 5:~m52_6 | 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 f755b0d8302..4f3f9315c01 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected @@ -23,6 +23,10 @@ useNotDominatedByDefinition | 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 48c2e361819..6f9186e3b8d 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -10567,3 +10567,233 @@ try_except.c: # 32| v32_6(void) = ReturnVoid : # 32| v32_7(void) = AliasedUse : ~m? # 32| v32_8(void) = ExitFunction : + +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 6 + +# 13| Block 1 +# 13| r13_1(int) = Constant[0] : +# 13| r13_2(bool) = CompareEQ : r13_8, r13_1 +# 13| v13_3(void) = ConditionalBranch : r13_2 +#-----| False -> Block 2 +#-----| True -> Block 3 + +# 13| Block 2 +# 13| r13_4(int) = Constant[1] : +# 13| r13_5(bool) = CompareEQ : r13_8, r13_4 +# 13| v13_6(void) = ConditionalBranch : r13_5 +#-----| True -> Block 5 + +# 13| Block 3 +# 13| v13_7(void) = Unwind : +#-----| Goto -> 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 + +# 14| Block 5 +# 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 + +# 16| Block 6 +# 16| v16_1(void) = NoOp : +# 6| v6_4(void) = ReturnVoid : +# 6| v6_5(void) = AliasedUse : ~m? +# 6| v6_6(void) = ExitFunction : + +# 18| void g_cpp() +# 18| Block 0 +# 18| v18_1(void) = EnterFunction : +# 18| mu18_2(unknown) = AliasedDefinition : +# 18| mu18_3(unknown) = InitializeNonLocal : +# 19| r19_1(glval) = VariableAddress[x] : +# 19| mu19_2(int) = Uninitialized[x] : &:r19_1 +# 19| r19_3(glval) = VariableAddress[y] : +# 19| r19_4(int) = Constant[0] : +# 19| mu19_5(int) = Store[y] : &:r19_3, r19_4 +# 21| r21_1(glval) = FunctionAddress[ProbeFunction] : +# 21| r21_2(int) = Constant[0] : +# 21| v21_3(void) = Call[ProbeFunction] : func:r21_1, 0:r21_2 +# 21| mu21_4(unknown) = ^CallSideEffect : ~m? +# 22| r22_1(glval) = VariableAddress[y] : +# 22| r22_2(int) = Load[y] : &:r22_1, ~m? +# 22| r22_3(glval) = VariableAddress[x] : +# 22| mu22_4(int) = Store[x] : &:r22_3, r22_2 +# 23| r23_1(glval) = FunctionAddress[ProbeFunction] : +# 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 : +# 18| v18_5(void) = AliasedUse : ~m? +# 18| v18_6(void) = ExitFunction : + +# 32| void h_cpp(int) +# 32| Block 0 +# 32| v32_1(void) = EnterFunction : +# 32| mu32_2(unknown) = AliasedDefinition : +# 32| mu32_3(unknown) = InitializeNonLocal : +# 32| r32_4(glval) = VariableAddress[b] : +# 32| mu32_5(int) = InitializeParameter[b] : &:r32_4 +# 33| r33_1(glval) = VariableAddress[x] : +# 33| r33_2(int) = Constant[0] : +# 33| mu33_3(int) = Store[x] : &:r33_1, r33_2 +# 35| r35_1(glval) = VariableAddress[b] : +# 35| r35_2(int) = Load[b] : &:r35_1, ~m? +# 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 + +# 36| Block 1 +# 36| r36_1(glval) = FunctionAddress[AfxThrowMemoryException] : +# 36| v36_2(void) = Call[AfxThrowMemoryException] : func:r36_1 +# 36| mu36_3(unknown) = ^CallSideEffect : ~m? +#-----| Goto -> Block 7 + +# 39| Block 2 +# 39| r39_1(int) = Constant[0] : +# 39| r39_2(bool) = CompareEQ : r39_8, r39_1 +# 39| v39_3(void) = ConditionalBranch : r39_2 +#-----| False -> Block 3 +#-----| True -> Block 4 + +# 39| Block 3 +# 39| r39_4(int) = Constant[1] : +# 39| r39_5(bool) = CompareEQ : r39_8, r39_4 +# 39| v39_6(void) = ConditionalBranch : r39_5 +#-----| True -> Block 6 + +# 39| Block 4 +# 39| v39_7(void) = Unwind : +#-----| Goto -> 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 + +# 40| Block 6 +# 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 + +# 42| Block 7 +# 42| v42_1(void) = NoOp : +# 32| v32_6(void) = ReturnVoid : +# 32| v32_7(void) = AliasedUse : ~m? +# 32| v32_8(void) = ExitFunction : + +# 44| void throw_cpp(int) +# 44| Block 0 +# 44| v44_1(void) = EnterFunction : +# 44| mu44_2(unknown) = AliasedDefinition : +# 44| mu44_3(unknown) = InitializeNonLocal : +# 44| r44_4(glval) = VariableAddress[b] : +# 44| mu44_5(int) = InitializeParameter[b] : &:r44_4 +# 45| r45_1(glval) = VariableAddress[x] : +# 45| r45_2(int) = Constant[0] : +# 45| mu45_3(int) = Store[x] : &:r45_1, r45_2 +# 47| r47_1(glval) = VariableAddress[b] : +# 47| r47_2(int) = Load[b] : &:r47_1, ~m? +# 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 +#-----| True -> Block 3 + +# 44| Block 1 +# 44| v44_6(void) = AliasedUse : ~m? +# 44| v44_7(void) = ExitFunction : + +# 44| Block 2 +# 44| v44_8(void) = Unwind : +#-----| 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? +#-----| Exception -> Block 7 + +# 51| Block 4 +# 51| r51_1(int) = Constant[0] : +# 51| r51_2(bool) = CompareEQ : r51_8, r51_1 +# 51| v51_3(void) = ConditionalBranch : r51_2 +#-----| False -> Block 5 +#-----| True -> Block 6 + +# 51| Block 5 +# 51| r51_4(int) = Constant[1] : +# 51| r51_5(bool) = CompareEQ : r51_8, r51_4 +# 51| v51_6(void) = ConditionalBranch : r51_5 +#-----| True -> Block 8 + +# 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 +#-----| False -> Block 4 +#-----| True -> Block 6 + +# 52| Block 8 +# 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 + +# 54| Block 9 +# 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 new file mode 100644 index 00000000000..fd8c5f59f1a --- /dev/null +++ b/cpp/ql/test/library-tests/ir/ir/try_except.cpp @@ -0,0 +1,54 @@ +// semmle-extractor-options: --microsoft + +void ProbeFunction(...); +void sink(...); + +void f_cpp() { + int x, y = 0; + __try { + ProbeFunction(0); + x = y; + ProbeFunction(0); + } + __except (0) { + sink(x); + } +} + +void g_cpp() { + int x, y = 0; + __try { + ProbeFunction(0); + x = y; + ProbeFunction(0); + } + __finally { + sink(x); + } +} + +void AfxThrowMemoryException(); + +void h_cpp(int b) { + int x = 0; + __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); + } +} \ No newline at end of file