Merge pull request #16436 from jketema/jketema/throw-wrong

C++: Add test case that shows that no destructors are attached to unwinds
This commit is contained in:
Jeroen Ketema
2024-05-07 11:07:24 +02:00
committed by GitHub
4 changed files with 152 additions and 0 deletions

View File

@@ -22605,6 +22605,41 @@ ir.cpp:
# 2530| ValueCategory = lvalue
# 2530| getStmt(1): [LabelStmt] label ...:
# 2531| getStmt(2): [ReturnStmt] return ...
# 2533| [TopLevelFunction] void destructor_possibly_not_handled()
# 2533| <params>:
# 2533| getEntryPoint(): [BlockStmt] { ... }
# 2534| getStmt(0): [DeclStmt] declaration
# 2534| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
# 2534| Type = [Class] ClassWithDestructor
# 2534| getVariable().getInitializer(): [Initializer] initializer for x
# 2534| getExpr(): [ConstructorCall] call to ClassWithDestructor
# 2534| Type = [VoidType] void
# 2534| ValueCategory = prvalue
# 2535| getStmt(1): [TryStmt] try { ... }
# 2535| getStmt(): [BlockStmt] { ... }
# 2536| getStmt(0): [ExprStmt] ExprStmt
# 2536| getExpr(): [ThrowExpr] throw ...
# 2536| Type = [IntType] int
# 2536| ValueCategory = prvalue
# 2536| getExpr(): [Literal] 42
# 2536| Type = [IntType] int
# 2536| Value = [Literal] 42
# 2536| ValueCategory = prvalue
# 2538| getChild(1): [Handler] <handler>
# 2538| getBlock(): [CatchBlock] { ... }
# 2540| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
# 2540| Type = [VoidType] void
# 2540| ValueCategory = prvalue
# 2540| getQualifier(): [VariableAccess] x
# 2540| Type = [Class] ClassWithDestructor
# 2540| ValueCategory = lvalue
# 2540| getStmt(2): [ReturnStmt] return ...
# 2540| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
# 2540| Type = [VoidType] void
# 2540| ValueCategory = prvalue
# 2540| getQualifier(): [VariableAccess] x
# 2540| Type = [Class] ClassWithDestructor
# 2540| ValueCategory = lvalue
perf-regression.cpp:
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
# 4| <params>:

View File

@@ -18177,6 +18177,64 @@ ir.cpp:
# 2521| v2521_8(void) = AliasedUse : ~m2530_17
# 2521| v2521_9(void) = ExitFunction :
# 2533| void destructor_possibly_not_handled()
# 2533| Block 0
# 2533| v2533_1(void) = EnterFunction :
# 2533| m2533_2(unknown) = AliasedDefinition :
# 2533| m2533_3(unknown) = InitializeNonLocal :
# 2533| m2533_4(unknown) = Chi : total:m2533_2, partial:m2533_3
# 2534| r2534_1(glval<ClassWithDestructor>) = VariableAddress[x] :
# 2534| m2534_2(ClassWithDestructor) = Uninitialized[x] : &:r2534_1
# 2534| r2534_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
# 2534| v2534_4(void) = Call[ClassWithDestructor] : func:r2534_3, this:r2534_1
# 2534| m2534_5(unknown) = ^CallSideEffect : ~m2533_4
# 2534| m2534_6(unknown) = Chi : total:m2533_4, partial:m2534_5
# 2534| m2534_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2534_1
# 2534| m2534_8(ClassWithDestructor) = Chi : total:m2534_2, partial:m2534_7
# 2536| r2536_1(glval<int>) = VariableAddress[#throw2536:5] :
# 2536| r2536_2(int) = Constant[42] :
# 2536| m2536_3(int) = Store[#throw2536:5] : &:r2536_1, r2536_2
# 2536| v2536_4(void) = ThrowValue : &:r2536_1, m2536_3
#-----| Exception -> Block 3
# 2533| Block 1
# 2533| m2533_5(unknown) = Phi : from 2:~m2534_6, from 4:~m2540_14
# 2533| v2533_6(void) = AliasedUse : ~m2533_5
# 2533| v2533_7(void) = ExitFunction :
# 2533| Block 2
# 2533| v2533_8(void) = Unwind :
#-----| Goto -> Block 1
# 2538| Block 3
# 2538| v2538_1(void) = CatchByType[char] :
#-----| Exception -> Block 2
#-----| Goto -> Block 4
# 2538| Block 4
# 2538| r2538_2(glval<char>) = VariableAddress[(unnamed parameter 0)] :
# 2538| m2538_3(char) = InitializeParameter[(unnamed parameter 0)] : &:r2538_2
# 2538| v2538_4(void) = NoOp :
# 2540| r2540_1(glval<ClassWithDestructor>) = VariableAddress[x] :
# 2540| r2540_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2540| v2540_3(void) = Call[~ClassWithDestructor] : func:r2540_2, this:r2540_1
# 2540| m2540_4(unknown) = ^CallSideEffect : ~m2534_6
# 2540| m2540_5(unknown) = Chi : total:m2534_6, partial:m2540_4
# 2540| v2540_6(void) = ^IndirectReadSideEffect[-1] : &:r2540_1, m2534_8
# 2540| m2540_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_1
# 2540| m2540_8(ClassWithDestructor) = Chi : total:m2534_8, partial:m2540_7
# 2540| v2540_9(void) = NoOp :
# 2540| r2540_10(glval<ClassWithDestructor>) = VariableAddress[x] :
# 2540| r2540_11(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2540| v2540_12(void) = Call[~ClassWithDestructor] : func:r2540_11, this:r2540_10
# 2540| m2540_13(unknown) = ^CallSideEffect : ~m2540_5
# 2540| m2540_14(unknown) = Chi : total:m2540_5, partial:m2540_13
# 2540| v2540_15(void) = ^IndirectReadSideEffect[-1] : &:r2540_10, m2540_8
# 2540| m2540_16(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_10
# 2540| m2540_17(ClassWithDestructor) = Chi : total:m2540_8, partial:m2540_16
# 2533| v2533_9(void) = ReturnVoid :
#-----| Goto -> Block 1
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0

View File

@@ -2530,4 +2530,13 @@ void destruction_in_switch_3(int c) {
}
}
void destructor_possibly_not_handled() {
ClassWithDestructor x;
try {
throw 42;
}
catch(char) {
}
}
// semmle-extractor-options: -std=c++20 --clang

View File

@@ -16553,6 +16553,56 @@ ir.cpp:
# 2521| v2521_7(void) = AliasedUse : ~m?
# 2521| v2521_8(void) = ExitFunction :
# 2533| void destructor_possibly_not_handled()
# 2533| Block 0
# 2533| v2533_1(void) = EnterFunction :
# 2533| mu2533_2(unknown) = AliasedDefinition :
# 2533| mu2533_3(unknown) = InitializeNonLocal :
# 2534| r2534_1(glval<ClassWithDestructor>) = VariableAddress[x] :
# 2534| mu2534_2(ClassWithDestructor) = Uninitialized[x] : &:r2534_1
# 2534| r2534_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
# 2534| v2534_4(void) = Call[ClassWithDestructor] : func:r2534_3, this:r2534_1
# 2534| mu2534_5(unknown) = ^CallSideEffect : ~m?
# 2534| mu2534_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2534_1
# 2536| r2536_1(glval<int>) = VariableAddress[#throw2536:5] :
# 2536| r2536_2(int) = Constant[42] :
# 2536| mu2536_3(int) = Store[#throw2536:5] : &:r2536_1, r2536_2
# 2536| v2536_4(void) = ThrowValue : &:r2536_1, ~m?
#-----| Exception -> Block 3
# 2533| Block 1
# 2533| v2533_4(void) = AliasedUse : ~m?
# 2533| v2533_5(void) = ExitFunction :
# 2533| Block 2
# 2533| v2533_6(void) = Unwind :
#-----| Goto -> Block 1
# 2538| Block 3
# 2538| v2538_1(void) = CatchByType[char] :
#-----| Exception -> Block 2
#-----| Goto -> Block 4
# 2538| Block 4
# 2538| r2538_2(glval<char>) = VariableAddress[(unnamed parameter 0)] :
# 2538| mu2538_3(char) = InitializeParameter[(unnamed parameter 0)] : &:r2538_2
# 2538| v2538_4(void) = NoOp :
# 2540| r2540_1(glval<ClassWithDestructor>) = VariableAddress[x] :
# 2540| r2540_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2540| v2540_3(void) = Call[~ClassWithDestructor] : func:r2540_2, this:r2540_1
# 2540| mu2540_4(unknown) = ^CallSideEffect : ~m?
# 2540| v2540_5(void) = ^IndirectReadSideEffect[-1] : &:r2540_1, ~m?
# 2540| mu2540_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_1
# 2540| v2540_7(void) = NoOp :
# 2540| r2540_8(glval<ClassWithDestructor>) = VariableAddress[x] :
# 2540| r2540_9(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2540| v2540_10(void) = Call[~ClassWithDestructor] : func:r2540_9, this:r2540_8
# 2540| mu2540_11(unknown) = ^CallSideEffect : ~m?
# 2540| v2540_12(void) = ^IndirectReadSideEffect[-1] : &:r2540_8, ~m?
# 2540| mu2540_13(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2540_8
# 2533| v2533_7(void) = ReturnVoid :
#-----| Goto -> Block 1
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0