diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 8f80e9d7e34..5de48acca39 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -4501,6 +4501,100 @@ ir.c: # 40| Value = [Literal] 1 # 40| ValueCategory = prvalue # 42| getStmt(1): [ReturnStmt] return ... +# 44| [TopLevelFunction] void try_with_finally() +# 44| : +# 45| getEntryPoint(): [BlockStmt] { ... } +# 46| getStmt(0): [DeclStmt] declaration +# 46| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 46| Type = [IntType] int +# 46| getVariable().getInitializer(): [Initializer] initializer for x +# 46| getExpr(): [Literal] 0 +# 46| Type = [IntType] int +# 46| Value = [Literal] 0 +# 46| ValueCategory = prvalue +# 47| getStmt(1): [MicrosoftTryFinallyStmt] __try { ... } __finally { ... } +# 48| getStmt(): [BlockStmt] { ... } +# 49| getStmt(0): [ExprStmt] ExprStmt +# 49| getExpr(): [AssignExpr] ... = ... +# 49| Type = [IntType] int +# 49| ValueCategory = prvalue +# 49| getLValue(): [VariableAccess] x +# 49| Type = [IntType] int +# 49| ValueCategory = lvalue +# 49| getRValue(): [Literal] 1 +# 49| Type = [IntType] int +# 49| Value = [Literal] 1 +# 49| ValueCategory = prvalue +# 52| getFinally(): [BlockStmt] { ... } +# 53| getStmt(0): [ExprStmt] ExprStmt +# 53| getExpr(): [AssignExpr] ... = ... +# 53| Type = [IntType] int +# 53| ValueCategory = prvalue +# 53| getLValue(): [VariableAccess] x +# 53| Type = [IntType] int +# 53| ValueCategory = lvalue +# 53| getRValue(): [Literal] 2 +# 53| Type = [IntType] int +# 53| Value = [Literal] 2 +# 53| ValueCategory = prvalue +# 55| getStmt(2): [ReturnStmt] return ... +# 57| [TopLevelFunction] void throw_in_try_with_finally() +# 57| : +# 58| getEntryPoint(): [BlockStmt] { ... } +# 59| getStmt(0): [DeclStmt] declaration +# 59| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 59| Type = [IntType] int +# 59| getVariable().getInitializer(): [Initializer] initializer for x +# 59| getExpr(): [Literal] 0 +# 59| Type = [IntType] int +# 59| Value = [Literal] 0 +# 59| ValueCategory = prvalue +# 60| getStmt(1): [MicrosoftTryFinallyStmt] __try { ... } __finally { ... } +# 61| getStmt(): [BlockStmt] { ... } +# 62| getStmt(0): [ExprStmt] ExprStmt +# 62| getExpr(): [FunctionCall] call to ExRaiseAccessViolation +# 62| Type = [VoidType] void +# 62| ValueCategory = prvalue +# 62| getArgument(0): [Literal] 0 +# 62| Type = [IntType] int +# 62| Value = [Literal] 0 +# 62| ValueCategory = prvalue +# 65| getFinally(): [BlockStmt] { ... } +# 66| getStmt(0): [ExprStmt] ExprStmt +# 66| getExpr(): [AssignExpr] ... = ... +# 66| Type = [IntType] int +# 66| ValueCategory = prvalue +# 66| getLValue(): [VariableAccess] x +# 66| Type = [IntType] int +# 66| ValueCategory = lvalue +# 66| getRValue(): [Literal] 1 +# 66| Type = [IntType] int +# 66| Value = [Literal] 1 +# 66| ValueCategory = prvalue +# 68| getStmt(2): [ReturnStmt] return ... +# 70| [TopLevelFunction] void throw_in_try_with_throw_in_finally() +# 70| : +# 71| getEntryPoint(): [BlockStmt] { ... } +# 72| getStmt(0): [MicrosoftTryFinallyStmt] __try { ... } __finally { ... } +# 72| getStmt(): [BlockStmt] { ... } +# 73| getStmt(0): [ExprStmt] ExprStmt +# 73| getExpr(): [FunctionCall] call to ExRaiseAccessViolation +# 73| Type = [VoidType] void +# 73| ValueCategory = prvalue +# 73| getArgument(0): [Literal] 0 +# 73| Type = [IntType] int +# 73| Value = [Literal] 0 +# 73| ValueCategory = prvalue +# 75| getFinally(): [BlockStmt] { ... } +# 76| getStmt(0): [ExprStmt] ExprStmt +# 76| getExpr(): [FunctionCall] call to ExRaiseAccessViolation +# 76| Type = [VoidType] void +# 76| ValueCategory = prvalue +# 76| getArgument(0): [Literal] 0 +# 76| Type = [IntType] int +# 76| Value = [Literal] 0 +# 76| ValueCategory = prvalue +# 78| getStmt(1): [ReturnStmt] return ... ir.cpp: # 1| [TopLevelFunction] void Constants() # 1| : 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 e149575e0fb..67d0bcb5dca 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -3203,6 +3203,53 @@ ir.c: # 32| Block 5 # 32| v32_5(void) = Unreached : +# 44| void try_with_finally() +# 44| Block 0 +# 44| v44_1(void) = EnterFunction : +# 44| m44_2(unknown) = AliasedDefinition : +# 44| m44_3(unknown) = InitializeNonLocal : +# 44| m44_4(unknown) = Chi : total:m44_2, partial:m44_3 +# 46| r46_1(glval) = VariableAddress[x] : +# 46| r46_2(int) = Constant[0] : +# 46| m46_3(int) = Store[x] : &:r46_1, r46_2 +# 49| r49_1(int) = Constant[1] : +# 49| r49_2(glval) = VariableAddress[x] : +# 49| m49_3(int) = Store[x] : &:r49_2, r49_1 +# 53| r53_1(int) = Constant[2] : +# 53| r53_2(glval) = VariableAddress[x] : +# 53| m53_3(int) = Store[x] : &:r53_2, r53_1 +# 55| v55_1(void) = NoOp : +# 44| v44_5(void) = ReturnVoid : +# 44| v44_6(void) = AliasedUse : m44_3 +# 44| v44_7(void) = ExitFunction : + +# 57| void throw_in_try_with_finally() +# 57| Block 0 +# 57| v57_1(void) = EnterFunction : +# 57| m57_2(unknown) = AliasedDefinition : +# 57| m57_3(unknown) = InitializeNonLocal : +# 57| m57_4(unknown) = Chi : total:m57_2, partial:m57_3 +# 59| r59_1(glval) = VariableAddress[x] : +# 59| r59_2(int) = Constant[0] : +# 59| m59_3(int) = Store[x] : &:r59_1, r59_2 +# 62| r62_1(glval) = FunctionAddress[ExRaiseAccessViolation] : +# 62| r62_2(int) = Constant[0] : +# 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 + +# 70| void throw_in_try_with_throw_in_finally() +# 70| Block 0 +# 70| v70_1(void) = EnterFunction : +# 70| m70_2(unknown) = AliasedDefinition : +# 70| m70_3(unknown) = InitializeNonLocal : +# 70| m70_4(unknown) = Chi : total:m70_2, partial:m70_3 +# 73| r73_1(glval) = FunctionAddress[ExRaiseAccessViolation] : +# 73| r73_2(int) = Constant[0] : +# 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 + ir.cpp: # 1| void Constants() # 1| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected index d04272f4319..b9208cfe01d 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected @@ -6,6 +6,8 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ir.c:62:5:62:26 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:57:6:57:30 | void throw_in_try_with_finally() | void throw_in_try_with_finally() | +| ir.c:73:5:73:26 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | ambiguousSuccessors unexplainedLoop | ir.c:38:13:38:37 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected index d04272f4319..b9208cfe01d 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected @@ -6,6 +6,8 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ir.c:62:5:62:26 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:57:6:57:30 | void throw_in_try_with_finally() | void throw_in_try_with_finally() | +| ir.c:73:5:73:26 | Chi: call to ExRaiseAccessViolation | Instruction 'Chi: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | ambiguousSuccessors unexplainedLoop | ir.c:38:13:38:37 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | diff --git a/cpp/ql/test/library-tests/ir/ir/ir.c b/cpp/ql/test/library-tests/ir/ir/ir.c index 0b12a36dc16..00b1fb5aba5 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.c +++ b/cpp/ql/test/library-tests/ir/ir/ir.c @@ -41,4 +41,40 @@ void unexplained_loop_regression() } } +void try_with_finally() +{ + int x = 0; + __try + { + x = 1; + } + __finally + { + x = 2; + } +} + +void throw_in_try_with_finally() +{ + int x = 0; + __try + { + ExRaiseAccessViolation(0); + } + __finally + { + x = 1; + } +} + +void throw_in_try_with_throw_in_finally() +{ + __try { + ExRaiseAccessViolation(0); + } + __finally { + ExRaiseAccessViolation(0); + } +} + // semmle-extractor-options: --microsoft 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 1181ba9b213..efb946ab274 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected @@ -6,6 +6,9 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ir.c:62:5:62:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:57:6:57:30 | void throw_in_try_with_finally() | void throw_in_try_with_finally() | +| ir.c:73:5:73:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | +| ir.c:76:5:76:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | ambiguousSuccessors unexplainedLoop | ir.c:38:13:38:37 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | 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 32421057d22..4d59cceaf32 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -2972,6 +2972,69 @@ ir.c: # 40| mu40_4(unknown) = ^CallSideEffect : ~m? #-----| Exception (back edge) -> Block 4 +# 44| void try_with_finally() +# 44| Block 0 +# 44| v44_1(void) = EnterFunction : +# 44| mu44_2(unknown) = AliasedDefinition : +# 44| mu44_3(unknown) = InitializeNonLocal : +# 46| r46_1(glval) = VariableAddress[x] : +# 46| r46_2(int) = Constant[0] : +# 46| mu46_3(int) = Store[x] : &:r46_1, r46_2 +# 49| r49_1(int) = Constant[1] : +# 49| r49_2(glval) = VariableAddress[x] : +# 49| mu49_3(int) = Store[x] : &:r49_2, r49_1 +# 53| r53_1(int) = Constant[2] : +# 53| r53_2(glval) = VariableAddress[x] : +# 53| mu53_3(int) = Store[x] : &:r53_2, r53_1 +# 55| v55_1(void) = NoOp : +# 44| v44_4(void) = ReturnVoid : +# 44| v44_5(void) = AliasedUse : ~m? +# 44| v44_6(void) = ExitFunction : + +# 57| void throw_in_try_with_finally() +# 57| Block 0 +# 57| v57_1(void) = EnterFunction : +# 57| mu57_2(unknown) = AliasedDefinition : +# 57| mu57_3(unknown) = InitializeNonLocal : +# 59| r59_1(glval) = VariableAddress[x] : +# 59| r59_2(int) = Constant[0] : +# 59| mu59_3(int) = Store[x] : &:r59_1, r59_2 +# 62| r62_1(glval) = FunctionAddress[ExRaiseAccessViolation] : +# 62| r62_2(int) = Constant[0] : +# 62| v62_3(void) = Call[ExRaiseAccessViolation] : func:r62_1, 0:r62_2 +# 62| mu62_4(unknown) = ^CallSideEffect : ~m? + +# 66| Block 1 +# 66| r66_1(int) = Constant[1] : +# 66| r66_2(glval) = VariableAddress[x] : +# 66| mu66_3(int) = Store[x] : &:r66_2, r66_1 +# 68| v68_1(void) = NoOp : +# 57| v57_4(void) = ReturnVoid : +# 57| v57_5(void) = AliasedUse : ~m? +# 57| v57_6(void) = ExitFunction : + +# 70| void throw_in_try_with_throw_in_finally() +# 70| Block 0 +# 70| v70_1(void) = EnterFunction : +# 70| mu70_2(unknown) = AliasedDefinition : +# 70| mu70_3(unknown) = InitializeNonLocal : +# 73| r73_1(glval) = FunctionAddress[ExRaiseAccessViolation] : +# 73| r73_2(int) = Constant[0] : +# 73| v73_3(void) = Call[ExRaiseAccessViolation] : func:r73_1, 0:r73_2 +# 73| mu73_4(unknown) = ^CallSideEffect : ~m? + +# 76| Block 1 +# 76| r76_1(glval) = FunctionAddress[ExRaiseAccessViolation] : +# 76| r76_2(int) = Constant[0] : +# 76| v76_3(void) = Call[ExRaiseAccessViolation] : func:r76_1, 0:r76_2 +# 76| mu76_4(unknown) = ^CallSideEffect : ~m? + +# 78| Block 2 +# 78| v78_1(void) = NoOp : +# 70| v70_4(void) = ReturnVoid : +# 70| v70_5(void) = AliasedUse : ~m? +# 70| v70_6(void) = ExitFunction : + ir.cpp: # 1| void Constants() # 1| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected index 9951220d616..0a87fed3c24 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected @@ -6,6 +6,8 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ir.c:62:5:62:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:57:6:57:30 | void throw_in_try_with_finally() | void throw_in_try_with_finally() | +| ir.c:73:5:73:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | ambiguousSuccessors unexplainedLoop | ir.c:38:13:38:37 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() | diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected index 9951220d616..0a87fed3c24 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected @@ -6,6 +6,8 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ir.c:62:5:62:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:57:6:57:30 | void throw_in_try_with_finally() | void throw_in_try_with_finally() | +| ir.c:73:5:73:26 | CallSideEffect: call to ExRaiseAccessViolation | Instruction 'CallSideEffect: call to ExRaiseAccessViolation' has no successors in function '$@'. | ir.c:70:6:70:39 | void throw_in_try_with_throw_in_finally() | void throw_in_try_with_throw_in_finally() | ambiguousSuccessors unexplainedLoop | ir.c:38:13:38:37 | Constant: 1 | Instruction 'Constant: 1' is part of an unexplained loop in function '$@'. | ir.c:32:6:32:32 | void unexplained_loop_regression() | void unexplained_loop_regression() |