Skip to content

Commit 8bbfb82

Browse files
authored
Merge pull request #15670 from jketema/destructors7
C++: Add IR tests for destruction of static locals
2 parents 204be4a + 57cb7f8 commit 8bbfb82

File tree

6 files changed

+474
-20
lines changed

6 files changed

+474
-20
lines changed

cpp/ql/test/library-tests/ir/ir/PrintAST.expected

Lines changed: 90 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10404,24 +10404,6 @@ ir.cpp:
1040410404
# 1245| Type = [PointerType] const char *
1040510405
# 1245| ValueCategory = prvalue(load)
1040610406
# 1246| getStmt(3): [ReturnStmt] return ...
10407-
# 1246| getImplicitDestructorCall(0): [DestructorCall] call to ~String
10408-
# 1246| Type = [VoidType] void
10409-
# 1246| ValueCategory = prvalue
10410-
# 1246| getQualifier(): [VariableAccess] c
10411-
# 1246| Type = [Struct] String
10412-
# 1246| ValueCategory = lvalue
10413-
# 1246| getImplicitDestructorCall(1): [DestructorCall] call to ~String
10414-
# 1246| Type = [VoidType] void
10415-
# 1246| ValueCategory = prvalue
10416-
# 1246| getQualifier(): [VariableAccess] b
10417-
# 1246| Type = [Struct] String
10418-
# 1246| ValueCategory = lvalue
10419-
# 1246| getImplicitDestructorCall(2): [DestructorCall] call to ~String
10420-
# 1246| Type = [VoidType] void
10421-
# 1246| ValueCategory = prvalue
10422-
# 1246| getQualifier(): [VariableAccess] a
10423-
# 1246| Type = [Struct] String
10424-
# 1246| ValueCategory = lvalue
1042510407
# 1250| [TopLevelFunction] char* strcpy(char*, char const*)
1042610408
# 1250| <params>:
1042710409
# 1250| getParameter(0): [Parameter] destination
@@ -16901,6 +16883,96 @@ ir.cpp:
1690116883
# 2167| getQualifier(): [VariableAccess] x
1690216884
# 2167| Type = [Class] ClassWithDestructor
1690316885
# 2167| ValueCategory = lvalue
16886+
# 2169| [TopLevelFunction] void static_variable_with_destructor_1()
16887+
# 2169| <params>:
16888+
# 2169| getEntryPoint(): [BlockStmt] { ... }
16889+
# 2170| getStmt(0): [DeclStmt] declaration
16890+
# 2170| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a
16891+
# 2170| Type = [Class] ClassWithDestructor
16892+
# 2170| getVariable().getInitializer(): [Initializer] initializer for a
16893+
# 2170| getExpr(): [ConstructorCall] call to ClassWithDestructor
16894+
# 2170| Type = [VoidType] void
16895+
# 2170| ValueCategory = prvalue
16896+
# 2171| getStmt(1): [DeclStmt] declaration
16897+
# 2171| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b
16898+
# 2171| Type = [Class] ClassWithDestructor
16899+
#-----| getVariable().getInitializer(): [Initializer] initializer for b
16900+
#-----| getExpr(): [ConstructorCall] call to ClassWithDestructor
16901+
#-----| Type = [VoidType] void
16902+
#-----| ValueCategory = prvalue
16903+
# 2172| getStmt(2): [ReturnStmt] return ...
16904+
# 2172| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
16905+
# 2172| Type = [VoidType] void
16906+
# 2172| ValueCategory = prvalue
16907+
# 2172| getQualifier(): [VariableAccess] a
16908+
# 2172| Type = [Class] ClassWithDestructor
16909+
# 2172| ValueCategory = lvalue
16910+
# 2174| [TopLevelFunction] void static_variable_with_destructor_2()
16911+
# 2174| <params>:
16912+
# 2174| getEntryPoint(): [BlockStmt] { ... }
16913+
# 2175| getStmt(0): [DeclStmt] declaration
16914+
# 2175| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a
16915+
# 2175| Type = [Class] ClassWithDestructor
16916+
#-----| getVariable().getInitializer(): [Initializer] initializer for a
16917+
#-----| getExpr(): [ConstructorCall] call to ClassWithDestructor
16918+
#-----| Type = [VoidType] void
16919+
#-----| ValueCategory = prvalue
16920+
# 2176| getStmt(1): [DeclStmt] declaration
16921+
# 2176| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b
16922+
# 2176| Type = [Class] ClassWithDestructor
16923+
# 2176| getVariable().getInitializer(): [Initializer] initializer for b
16924+
# 2176| getExpr(): [ConstructorCall] call to ClassWithDestructor
16925+
# 2176| Type = [VoidType] void
16926+
# 2176| ValueCategory = prvalue
16927+
# 2177| getStmt(2): [ReturnStmt] return ...
16928+
# 2177| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
16929+
# 2177| Type = [VoidType] void
16930+
# 2177| ValueCategory = prvalue
16931+
# 2177| getQualifier(): [VariableAccess] b
16932+
# 2177| Type = [Class] ClassWithDestructor
16933+
# 2177| ValueCategory = lvalue
16934+
# 2179| [TopLevelFunction] void static_variable_with_destructor_3()
16935+
# 2179| <params>:
16936+
# 2179| getEntryPoint(): [BlockStmt] { ... }
16937+
# 2180| getStmt(0): [DeclStmt] declaration
16938+
# 2180| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a
16939+
# 2180| Type = [Class] ClassWithDestructor
16940+
# 2180| getVariable().getInitializer(): [Initializer] initializer for a
16941+
# 2180| getExpr(): [ConstructorCall] call to ClassWithDestructor
16942+
# 2180| Type = [VoidType] void
16943+
# 2180| ValueCategory = prvalue
16944+
# 2181| getStmt(1): [DeclStmt] declaration
16945+
# 2181| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b
16946+
# 2181| Type = [Class] ClassWithDestructor
16947+
# 2181| getVariable().getInitializer(): [Initializer] initializer for b
16948+
# 2181| getExpr(): [ConstructorCall] call to ClassWithDestructor
16949+
# 2181| Type = [VoidType] void
16950+
# 2181| ValueCategory = prvalue
16951+
# 2182| getStmt(2): [DeclStmt] declaration
16952+
# 2182| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c
16953+
# 2182| Type = [Class] ClassWithDestructor
16954+
#-----| getVariable().getInitializer(): [Initializer] initializer for c
16955+
#-----| getExpr(): [ConstructorCall] call to ClassWithDestructor
16956+
#-----| Type = [VoidType] void
16957+
#-----| ValueCategory = prvalue
16958+
# 2183| getStmt(3): [ReturnStmt] return ...
16959+
# 2183| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
16960+
# 2183| Type = [VoidType] void
16961+
# 2183| ValueCategory = prvalue
16962+
# 2183| getQualifier(): [VariableAccess] b
16963+
# 2183| Type = [Class] ClassWithDestructor
16964+
# 2183| ValueCategory = lvalue
16965+
# 2183| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor
16966+
# 2183| Type = [VoidType] void
16967+
# 2183| ValueCategory = prvalue
16968+
# 2183| getQualifier(): [VariableAccess] a
16969+
# 2183| Type = [Class] ClassWithDestructor
16970+
# 2183| ValueCategory = lvalue
16971+
# 2185| [GlobalVariable] ClassWithDestructor global_class_with_destructor
16972+
# 2185| getInitializer(): [Initializer] initializer for global_class_with_destructor
16973+
# 2185| getExpr(): [ConstructorCall] call to ClassWithDestructor
16974+
# 2185| Type = [VoidType] void
16975+
# 2185| ValueCategory = prvalue
1690416976
perf-regression.cpp:
1690516977
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
1690616978
# 4| <params>:

cpp/ql/test/library-tests/ir/ir/aliased_ir.expected

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13030,6 +13030,149 @@ ir.cpp:
1303013030
# 2137| Block 21
1303113031
# 2137| v2137_13(void) = Unreached :
1303213032

13033+
# 2169| void static_variable_with_destructor_1()
13034+
# 2169| Block 0
13035+
# 2169| v2169_1(void) = EnterFunction :
13036+
# 2169| m2169_2(unknown) = AliasedDefinition :
13037+
# 2169| m2169_3(unknown) = InitializeNonLocal :
13038+
# 2169| m2169_4(unknown) = Chi : total:m2169_2, partial:m2169_3
13039+
# 2170| r2170_1(glval<ClassWithDestructor>) = VariableAddress[a] :
13040+
# 2170| m2170_2(ClassWithDestructor) = Uninitialized[a] : &:r2170_1
13041+
# 2170| r2170_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
13042+
# 2170| v2170_4(void) = Call[ClassWithDestructor] : func:r2170_3, this:r2170_1
13043+
# 2170| m2170_5(unknown) = ^CallSideEffect : ~m2169_4
13044+
# 2170| m2170_6(unknown) = Chi : total:m2169_4, partial:m2170_5
13045+
# 2170| m2170_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2170_1
13046+
# 2170| m2170_8(ClassWithDestructor) = Chi : total:m2170_2, partial:m2170_7
13047+
# 2171| r2171_1(glval<bool>) = VariableAddress[b#init] :
13048+
# 2171| r2171_2(bool) = Load[b#init] : &:r2171_1, ~m2170_6
13049+
# 2171| v2171_3(void) = ConditionalBranch : r2171_2
13050+
#-----| False -> Block 1
13051+
#-----| True -> Block 2
13052+
13053+
# 2171| Block 1
13054+
# 2171| r2171_4(glval<ClassWithDestructor>) = VariableAddress[b] :
13055+
#-----| r0_1(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
13056+
#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2171_4
13057+
#-----| m0_3(unknown) = ^CallSideEffect : ~m2170_6
13058+
#-----| m0_4(unknown) = Chi : total:m2170_6, partial:m0_3
13059+
#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2171_4
13060+
#-----| m0_6(unknown) = Chi : total:m0_4, partial:m0_5
13061+
# 2171| r2171_5(bool) = Constant[1] :
13062+
# 2171| m2171_6(bool) = Store[b#init] : &:r2171_1, r2171_5
13063+
# 2171| m2171_7(unknown) = Chi : total:m0_6, partial:m2171_6
13064+
#-----| Goto -> Block 2
13065+
13066+
# 2172| Block 2
13067+
# 2172| m2172_1(unknown) = Phi : from 0:~m2170_6, from 1:~m2171_7
13068+
# 2172| v2172_2(void) = NoOp :
13069+
# 2169| v2169_5(void) = ReturnVoid :
13070+
# 2169| v2169_6(void) = AliasedUse : ~m2172_1
13071+
# 2169| v2169_7(void) = ExitFunction :
13072+
13073+
# 2174| void static_variable_with_destructor_2()
13074+
# 2174| Block 0
13075+
# 2174| v2174_1(void) = EnterFunction :
13076+
# 2174| m2174_2(unknown) = AliasedDefinition :
13077+
# 2174| m2174_3(unknown) = InitializeNonLocal :
13078+
# 2174| m2174_4(unknown) = Chi : total:m2174_2, partial:m2174_3
13079+
# 2175| r2175_1(glval<bool>) = VariableAddress[a#init] :
13080+
# 2175| r2175_2(bool) = Load[a#init] : &:r2175_1, ~m2174_3
13081+
# 2175| v2175_3(void) = ConditionalBranch : r2175_2
13082+
#-----| False -> Block 1
13083+
#-----| True -> Block 2
13084+
13085+
# 2175| Block 1
13086+
# 2175| r2175_4(glval<ClassWithDestructor>) = VariableAddress[a] :
13087+
#-----| r0_1(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
13088+
#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2175_4
13089+
#-----| m0_3(unknown) = ^CallSideEffect : ~m2174_4
13090+
#-----| m0_4(unknown) = Chi : total:m2174_4, partial:m0_3
13091+
#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2175_4
13092+
#-----| m0_6(unknown) = Chi : total:m0_4, partial:m0_5
13093+
# 2175| r2175_5(bool) = Constant[1] :
13094+
# 2175| m2175_6(bool) = Store[a#init] : &:r2175_1, r2175_5
13095+
# 2175| m2175_7(unknown) = Chi : total:m0_6, partial:m2175_6
13096+
#-----| Goto -> Block 2
13097+
13098+
# 2176| Block 2
13099+
# 2176| m2176_1(unknown) = Phi : from 0:~m2174_4, from 1:~m2175_7
13100+
# 2176| r2176_2(glval<ClassWithDestructor>) = VariableAddress[b] :
13101+
# 2176| m2176_3(ClassWithDestructor) = Uninitialized[b] : &:r2176_2
13102+
# 2176| r2176_4(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
13103+
# 2176| v2176_5(void) = Call[ClassWithDestructor] : func:r2176_4, this:r2176_2
13104+
# 2176| m2176_6(unknown) = ^CallSideEffect : ~m2176_1
13105+
# 2176| m2176_7(unknown) = Chi : total:m2176_1, partial:m2176_6
13106+
# 2176| m2176_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2176_2
13107+
# 2176| m2176_9(ClassWithDestructor) = Chi : total:m2176_3, partial:m2176_8
13108+
# 2177| v2177_1(void) = NoOp :
13109+
# 2174| v2174_5(void) = ReturnVoid :
13110+
# 2174| v2174_6(void) = AliasedUse : ~m2176_7
13111+
# 2174| v2174_7(void) = ExitFunction :
13112+
13113+
# 2179| void static_variable_with_destructor_3()
13114+
# 2179| Block 0
13115+
# 2179| v2179_1(void) = EnterFunction :
13116+
# 2179| m2179_2(unknown) = AliasedDefinition :
13117+
# 2179| m2179_3(unknown) = InitializeNonLocal :
13118+
# 2179| m2179_4(unknown) = Chi : total:m2179_2, partial:m2179_3
13119+
# 2180| r2180_1(glval<ClassWithDestructor>) = VariableAddress[a] :
13120+
# 2180| m2180_2(ClassWithDestructor) = Uninitialized[a] : &:r2180_1
13121+
# 2180| r2180_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
13122+
# 2180| v2180_4(void) = Call[ClassWithDestructor] : func:r2180_3, this:r2180_1
13123+
# 2180| m2180_5(unknown) = ^CallSideEffect : ~m2179_4
13124+
# 2180| m2180_6(unknown) = Chi : total:m2179_4, partial:m2180_5
13125+
# 2180| m2180_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2180_1
13126+
# 2180| m2180_8(ClassWithDestructor) = Chi : total:m2180_2, partial:m2180_7
13127+
# 2181| r2181_1(glval<ClassWithDestructor>) = VariableAddress[b] :
13128+
# 2181| m2181_2(ClassWithDestructor) = Uninitialized[b] : &:r2181_1
13129+
# 2181| r2181_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
13130+
# 2181| v2181_4(void) = Call[ClassWithDestructor] : func:r2181_3, this:r2181_1
13131+
# 2181| m2181_5(unknown) = ^CallSideEffect : ~m2180_6
13132+
# 2181| m2181_6(unknown) = Chi : total:m2180_6, partial:m2181_5
13133+
# 2181| m2181_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2181_1
13134+
# 2181| m2181_8(ClassWithDestructor) = Chi : total:m2181_2, partial:m2181_7
13135+
# 2182| r2182_1(glval<bool>) = VariableAddress[c#init] :
13136+
# 2182| r2182_2(bool) = Load[c#init] : &:r2182_1, ~m2181_6
13137+
# 2182| v2182_3(void) = ConditionalBranch : r2182_2
13138+
#-----| False -> Block 1
13139+
#-----| True -> Block 2
13140+
13141+
# 2182| Block 1
13142+
# 2182| r2182_4(glval<ClassWithDestructor>) = VariableAddress[c] :
13143+
#-----| r0_1(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
13144+
#-----| v0_2(void) = Call[ClassWithDestructor] : func:r0_1, this:r2182_4
13145+
#-----| m0_3(unknown) = ^CallSideEffect : ~m2181_6
13146+
#-----| m0_4(unknown) = Chi : total:m2181_6, partial:m0_3
13147+
#-----| m0_5(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2182_4
13148+
#-----| m0_6(unknown) = Chi : total:m0_4, partial:m0_5
13149+
# 2182| r2182_5(bool) = Constant[1] :
13150+
# 2182| m2182_6(bool) = Store[c#init] : &:r2182_1, r2182_5
13151+
# 2182| m2182_7(unknown) = Chi : total:m0_6, partial:m2182_6
13152+
#-----| Goto -> Block 2
13153+
13154+
# 2183| Block 2
13155+
# 2183| m2183_1(unknown) = Phi : from 0:~m2181_6, from 1:~m2182_7
13156+
# 2183| v2183_2(void) = NoOp :
13157+
# 2179| v2179_5(void) = ReturnVoid :
13158+
# 2179| v2179_6(void) = AliasedUse : ~m2183_1
13159+
# 2179| v2179_7(void) = ExitFunction :
13160+
13161+
# 2185| ClassWithDestructor global_class_with_destructor
13162+
# 2185| Block 0
13163+
# 2185| v2185_1(void) = EnterFunction :
13164+
# 2185| m2185_2(unknown) = AliasedDefinition :
13165+
# 2185| r2185_3(glval<ClassWithDestructor>) = VariableAddress[global_class_with_destructor] :
13166+
# 2185| r2185_4(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
13167+
# 2185| v2185_5(void) = Call[ClassWithDestructor] : func:r2185_4, this:r2185_3
13168+
# 2185| m2185_6(unknown) = ^CallSideEffect : ~m2185_2
13169+
# 2185| m2185_7(unknown) = Chi : total:m2185_2, partial:m2185_6
13170+
# 2185| m2185_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2185_3
13171+
# 2185| m2185_9(unknown) = Chi : total:m2185_7, partial:m2185_8
13172+
# 2185| v2185_10(void) = ReturnVoid :
13173+
# 2185| v2185_11(void) = AliasedUse : ~m2185_9
13174+
# 2185| v2185_12(void) = ExitFunction :
13175+
1303313176
perf-regression.cpp:
1303413177
# 6| void Big::Big()
1303513178
# 6| Block 0

cpp/ql/test/library-tests/ir/ir/ir.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2166,4 +2166,22 @@ void initialization_with_destructor(bool b, char c) {
21662166
}
21672167
}
21682168

2169+
void static_variable_with_destructor_1() {
2170+
ClassWithDestructor a;
2171+
static ClassWithDestructor b;
2172+
}
2173+
2174+
void static_variable_with_destructor_2() {
2175+
static ClassWithDestructor a;
2176+
ClassWithDestructor b;
2177+
}
2178+
2179+
void static_variable_with_destructor_3() {
2180+
ClassWithDestructor a;
2181+
ClassWithDestructor b;
2182+
static ClassWithDestructor c;
2183+
}
2184+
2185+
static ClassWithDestructor global_class_with_destructor;
2186+
21692187
// semmle-extractor-options: -std=c++20 --clang

0 commit comments

Comments
 (0)