Skip to content

Commit c5a87c9

Browse files
committed
C++: Add tests that incorrectly call destructors twice.
1 parent 0715c4a commit c5a87c9

File tree

4 files changed

+481
-0
lines changed

4 files changed

+481
-0
lines changed

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

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22442,6 +22442,139 @@ ir.cpp:
2244222442
#-----| Type = [Class] ClassWithDestructor
2244322443
#-----| ValueCategory = lvalue
2244422444
# 2499| getStmt(4): [ReturnStmt] return ...
22445+
# 2501| [TopLevelFunction] void destruction_in_switch_1(int)
22446+
# 2501| <params>:
22447+
# 2501| getParameter(0): [Parameter] c
22448+
# 2501| Type = [IntType] int
22449+
# 2501| getEntryPoint(): [BlockStmt] { ... }
22450+
# 2502| getStmt(0): [SwitchStmt] switch (...) ...
22451+
# 2502| getExpr(): [VariableAccess] c
22452+
# 2502| Type = [IntType] int
22453+
# 2502| ValueCategory = prvalue(load)
22454+
# 2502| getStmt(): [BlockStmt] { ... }
22455+
# 2503| getStmt(0): [SwitchCase] case ...:
22456+
# 2503| getExpr(): [Literal] 0
22457+
# 2503| Type = [IntType] int
22458+
# 2503| Value = [Literal] 0
22459+
# 2503| ValueCategory = prvalue
22460+
# 2503| getStmt(1): [BlockStmt] { ... }
22461+
# 2504| getStmt(0): [DeclStmt] declaration
22462+
# 2504| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
22463+
# 2504| Type = [Class] ClassWithDestructor
22464+
# 2504| getVariable().getInitializer(): [Initializer] initializer for x
22465+
# 2504| getExpr(): [ConstructorCall] call to ClassWithDestructor
22466+
# 2504| Type = [VoidType] void
22467+
# 2504| ValueCategory = prvalue
22468+
# 2505| getStmt(1): [BreakStmt] break;
22469+
# 2506| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
22470+
# 2506| Type = [VoidType] void
22471+
# 2506| ValueCategory = prvalue
22472+
# 2506| getQualifier(): [VariableAccess] x
22473+
# 2506| Type = [Class] ClassWithDestructor
22474+
# 2506| ValueCategory = lvalue
22475+
# 2506| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
22476+
# 2506| Type = [VoidType] void
22477+
# 2506| ValueCategory = prvalue
22478+
# 2506| getQualifier(): [VariableAccess] x
22479+
# 2506| Type = [Class] ClassWithDestructor
22480+
# 2506| ValueCategory = lvalue
22481+
# 2507| getStmt(1): [LabelStmt] label ...:
22482+
# 2508| getStmt(2): [ReturnStmt] return ...
22483+
# 2510| [TopLevelFunction] void destruction_in_switch_2(int)
22484+
# 2510| <params>:
22485+
# 2510| getParameter(0): [Parameter] c
22486+
# 2510| Type = [IntType] int
22487+
# 2510| getEntryPoint(): [BlockStmt] { ... }
22488+
# 2511| getStmt(0): [SwitchStmt] switch (...) ...
22489+
# 2511| getInitialization(): [DeclStmt] declaration
22490+
# 2511| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
22491+
# 2511| Type = [Class] ClassWithDestructor
22492+
# 2511| getVariable().getInitializer(): [Initializer] initializer for y
22493+
# 2511| getExpr(): [ConstructorCall] call to ClassWithDestructor
22494+
# 2511| Type = [VoidType] void
22495+
# 2511| ValueCategory = prvalue
22496+
# 2511| getExpr(): [VariableAccess] c
22497+
# 2511| Type = [IntType] int
22498+
# 2511| ValueCategory = prvalue(load)
22499+
# 2511| getStmt(): [BlockStmt] { ... }
22500+
# 2512| getStmt(0): [SwitchCase] case ...:
22501+
# 2512| getExpr(): [Literal] 0
22502+
# 2512| Type = [IntType] int
22503+
# 2512| Value = [Literal] 0
22504+
# 2512| ValueCategory = prvalue
22505+
# 2512| getStmt(1): [BlockStmt] { ... }
22506+
# 2513| getStmt(0): [BreakStmt] break;
22507+
# 2515| getStmt(2): [SwitchCase] default:
22508+
# 2515| getStmt(3): [BlockStmt] { ... }
22509+
# 2516| getStmt(0): [BreakStmt] break;
22510+
# 2518| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
22511+
# 2518| Type = [VoidType] void
22512+
# 2518| ValueCategory = prvalue
22513+
# 2518| getQualifier(): [VariableAccess] y
22514+
# 2518| Type = [Class] ClassWithDestructor
22515+
# 2518| ValueCategory = lvalue
22516+
# 2518| getStmt(1): [LabelStmt] label ...:
22517+
# 2519| getStmt(2): [ReturnStmt] return ...
22518+
# 2521| [TopLevelFunction] void destruction_in_switch_3(int)
22519+
# 2521| <params>:
22520+
# 2521| getParameter(0): [Parameter] c
22521+
# 2521| Type = [IntType] int
22522+
# 2521| getEntryPoint(): [BlockStmt] { ... }
22523+
# 2522| getStmt(0): [SwitchStmt] switch (...) ...
22524+
# 2522| getInitialization(): [DeclStmt] declaration
22525+
# 2522| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
22526+
# 2522| Type = [Class] ClassWithDestructor
22527+
# 2522| getVariable().getInitializer(): [Initializer] initializer for y
22528+
# 2522| getExpr(): [ConstructorCall] call to ClassWithDestructor
22529+
# 2522| Type = [VoidType] void
22530+
# 2522| ValueCategory = prvalue
22531+
# 2522| getExpr(): [VariableAccess] c
22532+
# 2522| Type = [IntType] int
22533+
# 2522| ValueCategory = prvalue(load)
22534+
# 2522| getStmt(): [BlockStmt] { ... }
22535+
# 2523| getStmt(0): [SwitchCase] case ...:
22536+
# 2523| getExpr(): [Literal] 0
22537+
# 2523| Type = [IntType] int
22538+
# 2523| Value = [Literal] 0
22539+
# 2523| ValueCategory = prvalue
22540+
# 2523| getStmt(1): [BlockStmt] { ... }
22541+
# 2524| getStmt(0): [DeclStmt] declaration
22542+
# 2524| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
22543+
# 2524| Type = [Class] ClassWithDestructor
22544+
# 2524| getVariable().getInitializer(): [Initializer] initializer for x
22545+
# 2524| getExpr(): [ConstructorCall] call to ClassWithDestructor
22546+
# 2524| Type = [VoidType] void
22547+
# 2524| ValueCategory = prvalue
22548+
# 2525| getStmt(1): [BreakStmt] break;
22549+
# 2526| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
22550+
# 2526| Type = [VoidType] void
22551+
# 2526| ValueCategory = prvalue
22552+
# 2526| getQualifier(): [VariableAccess] x
22553+
# 2526| Type = [Class] ClassWithDestructor
22554+
# 2526| ValueCategory = lvalue
22555+
# 2530| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor
22556+
# 2530| Type = [VoidType] void
22557+
# 2530| ValueCategory = prvalue
22558+
# 2530| getQualifier(): [VariableAccess] y
22559+
# 2530| Type = [Class] ClassWithDestructor
22560+
# 2530| ValueCategory = lvalue
22561+
# 2526| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
22562+
# 2526| Type = [VoidType] void
22563+
# 2526| ValueCategory = prvalue
22564+
# 2526| getQualifier(): [VariableAccess] x
22565+
# 2526| Type = [Class] ClassWithDestructor
22566+
# 2526| ValueCategory = lvalue
22567+
# 2527| getStmt(2): [SwitchCase] default:
22568+
# 2527| getStmt(3): [BlockStmt] { ... }
22569+
# 2528| getStmt(0): [BreakStmt] break;
22570+
# 2530| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
22571+
# 2530| Type = [VoidType] void
22572+
# 2530| ValueCategory = prvalue
22573+
# 2530| getQualifier(): [VariableAccess] y
22574+
# 2530| Type = [Class] ClassWithDestructor
22575+
# 2530| ValueCategory = lvalue
22576+
# 2530| getStmt(1): [LabelStmt] label ...:
22577+
# 2531| getStmt(2): [ReturnStmt] return ...
2244522578
perf-regression.cpp:
2244622579
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
2244722580
# 4| <params>:

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

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17958,6 +17958,165 @@ ir.cpp:
1795817958
# 2484| v2484_8(void) = AliasedUse : ~m2497_4
1795917959
# 2484| v2484_9(void) = ExitFunction :
1796017960

17961+
# 2501| void destruction_in_switch_1(int)
17962+
# 2501| Block 0
17963+
# 2501| v2501_1(void) = EnterFunction :
17964+
# 2501| m2501_2(unknown) = AliasedDefinition :
17965+
# 2501| m2501_3(unknown) = InitializeNonLocal :
17966+
# 2501| m2501_4(unknown) = Chi : total:m2501_2, partial:m2501_3
17967+
# 2501| r2501_5(glval<int>) = VariableAddress[c] :
17968+
# 2501| m2501_6(int) = InitializeParameter[c] : &:r2501_5
17969+
# 2502| r2502_1(glval<int>) = VariableAddress[c] :
17970+
# 2502| r2502_2(int) = Load[c] : &:r2502_1, m2501_6
17971+
# 2502| v2502_3(void) = Switch : r2502_2
17972+
#-----| Case[0] -> Block 1
17973+
#-----| Default -> Block 2
17974+
17975+
# 2503| Block 1
17976+
# 2503| v2503_1(void) = NoOp :
17977+
# 2504| r2504_1(glval<ClassWithDestructor>) = VariableAddress[x] :
17978+
# 2504| m2504_2(ClassWithDestructor) = Uninitialized[x] : &:r2504_1
17979+
# 2504| r2504_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
17980+
# 2504| v2504_4(void) = Call[ClassWithDestructor] : func:r2504_3, this:r2504_1
17981+
# 2504| m2504_5(unknown) = ^CallSideEffect : ~m2501_4
17982+
# 2504| m2504_6(unknown) = Chi : total:m2501_4, partial:m2504_5
17983+
# 2504| m2504_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2504_1
17984+
# 2504| m2504_8(ClassWithDestructor) = Chi : total:m2504_2, partial:m2504_7
17985+
# 2505| v2505_1(void) = NoOp :
17986+
# 2506| r2506_1(glval<ClassWithDestructor>) = VariableAddress[x] :
17987+
# 2506| r2506_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
17988+
# 2506| v2506_3(void) = Call[~ClassWithDestructor] : func:r2506_2, this:r2506_1
17989+
# 2506| m2506_4(unknown) = ^CallSideEffect : ~m2504_6
17990+
# 2506| m2506_5(unknown) = Chi : total:m2504_6, partial:m2506_4
17991+
# 2506| v2506_6(void) = ^IndirectReadSideEffect[-1] : &:r2506_1, m2504_8
17992+
# 2506| m2506_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_1
17993+
# 2506| m2506_8(ClassWithDestructor) = Chi : total:m2504_8, partial:m2506_7
17994+
# 2506| r2506_9(glval<ClassWithDestructor>) = VariableAddress[x] :
17995+
# 2506| r2506_10(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
17996+
# 2506| v2506_11(void) = Call[~ClassWithDestructor] : func:r2506_10, this:r2506_9
17997+
# 2506| m2506_12(unknown) = ^CallSideEffect : ~m2506_5
17998+
# 2506| m2506_13(unknown) = Chi : total:m2506_5, partial:m2506_12
17999+
# 2506| v2506_14(void) = ^IndirectReadSideEffect[-1] : &:r2506_9, m2506_8
18000+
# 2506| m2506_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_9
18001+
# 2506| m2506_16(ClassWithDestructor) = Chi : total:m2506_8, partial:m2506_15
18002+
#-----| Goto -> Block 2
18003+
18004+
# 2507| Block 2
18005+
# 2507| m2507_1(unknown) = Phi : from 0:~m2501_4, from 1:~m2506_13
18006+
# 2507| v2507_2(void) = NoOp :
18007+
# 2508| v2508_1(void) = NoOp :
18008+
# 2501| v2501_7(void) = ReturnVoid :
18009+
# 2501| v2501_8(void) = AliasedUse : ~m2507_1
18010+
# 2501| v2501_9(void) = ExitFunction :
18011+
18012+
# 2510| void destruction_in_switch_2(int)
18013+
# 2510| Block 0
18014+
# 2510| v2510_1(void) = EnterFunction :
18015+
# 2510| m2510_2(unknown) = AliasedDefinition :
18016+
# 2510| m2510_3(unknown) = InitializeNonLocal :
18017+
# 2510| m2510_4(unknown) = Chi : total:m2510_2, partial:m2510_3
18018+
# 2510| r2510_5(glval<int>) = VariableAddress[c] :
18019+
# 2510| m2510_6(int) = InitializeParameter[c] : &:r2510_5
18020+
# 2511| r2511_1(glval<ClassWithDestructor>) = VariableAddress[y] :
18021+
# 2511| m2511_2(ClassWithDestructor) = Uninitialized[y] : &:r2511_1
18022+
# 2511| r2511_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
18023+
# 2511| v2511_4(void) = Call[ClassWithDestructor] : func:r2511_3, this:r2511_1
18024+
# 2511| m2511_5(unknown) = ^CallSideEffect : ~m2510_4
18025+
# 2511| m2511_6(unknown) = Chi : total:m2510_4, partial:m2511_5
18026+
# 2511| m2511_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2511_1
18027+
# 2511| m2511_8(ClassWithDestructor) = Chi : total:m2511_2, partial:m2511_7
18028+
# 2511| r2511_9(glval<int>) = VariableAddress[c] :
18029+
# 2511| r2511_10(int) = Load[c] : &:r2511_9, m2510_6
18030+
# 2511| v2511_11(void) = Switch : r2511_10
18031+
#-----| Case[0] -> Block 1
18032+
#-----| Default -> Block 2
18033+
18034+
# 2512| Block 1
18035+
# 2512| v2512_1(void) = NoOp :
18036+
# 2513| v2513_1(void) = NoOp :
18037+
#-----| Goto -> Block 3
18038+
18039+
# 2515| Block 2
18040+
# 2515| v2515_1(void) = NoOp :
18041+
# 2516| v2516_1(void) = NoOp :
18042+
#-----| Goto -> Block 3
18043+
18044+
# 2518| Block 3
18045+
# 2518| v2518_1(void) = NoOp :
18046+
# 2519| v2519_1(void) = NoOp :
18047+
# 2510| v2510_7(void) = ReturnVoid :
18048+
# 2510| v2510_8(void) = AliasedUse : ~m2511_6
18049+
# 2510| v2510_9(void) = ExitFunction :
18050+
18051+
# 2521| void destruction_in_switch_3(int)
18052+
# 2521| Block 0
18053+
# 2521| v2521_1(void) = EnterFunction :
18054+
# 2521| m2521_2(unknown) = AliasedDefinition :
18055+
# 2521| m2521_3(unknown) = InitializeNonLocal :
18056+
# 2521| m2521_4(unknown) = Chi : total:m2521_2, partial:m2521_3
18057+
# 2521| r2521_5(glval<int>) = VariableAddress[c] :
18058+
# 2521| m2521_6(int) = InitializeParameter[c] : &:r2521_5
18059+
# 2522| r2522_1(glval<ClassWithDestructor>) = VariableAddress[y] :
18060+
# 2522| m2522_2(ClassWithDestructor) = Uninitialized[y] : &:r2522_1
18061+
# 2522| r2522_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
18062+
# 2522| v2522_4(void) = Call[ClassWithDestructor] : func:r2522_3, this:r2522_1
18063+
# 2522| m2522_5(unknown) = ^CallSideEffect : ~m2521_4
18064+
# 2522| m2522_6(unknown) = Chi : total:m2521_4, partial:m2522_5
18065+
# 2522| m2522_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2522_1
18066+
# 2522| m2522_8(ClassWithDestructor) = Chi : total:m2522_2, partial:m2522_7
18067+
# 2522| r2522_9(glval<int>) = VariableAddress[c] :
18068+
# 2522| r2522_10(int) = Load[c] : &:r2522_9, m2521_6
18069+
# 2522| v2522_11(void) = Switch : r2522_10
18070+
#-----| Case[0] -> Block 1
18071+
#-----| Default -> Block 2
18072+
18073+
# 2523| Block 1
18074+
# 2523| v2523_1(void) = NoOp :
18075+
# 2524| r2524_1(glval<ClassWithDestructor>) = VariableAddress[x] :
18076+
# 2524| m2524_2(ClassWithDestructor) = Uninitialized[x] : &:r2524_1
18077+
# 2524| r2524_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
18078+
# 2524| v2524_4(void) = Call[ClassWithDestructor] : func:r2524_3, this:r2524_1
18079+
# 2524| m2524_5(unknown) = ^CallSideEffect : ~m2522_6
18080+
# 2524| m2524_6(unknown) = Chi : total:m2522_6, partial:m2524_5
18081+
# 2524| m2524_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2524_1
18082+
# 2524| m2524_8(ClassWithDestructor) = Chi : total:m2524_2, partial:m2524_7
18083+
# 2525| v2525_1(void) = NoOp :
18084+
# 2526| r2526_1(glval<ClassWithDestructor>) = VariableAddress[x] :
18085+
# 2526| r2526_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
18086+
# 2526| v2526_3(void) = Call[~ClassWithDestructor] : func:r2526_2, this:r2526_1
18087+
# 2526| m2526_4(unknown) = ^CallSideEffect : ~m2524_6
18088+
# 2526| m2526_5(unknown) = Chi : total:m2524_6, partial:m2526_4
18089+
# 2526| v2526_6(void) = ^IndirectReadSideEffect[-1] : &:r2526_1, m2524_8
18090+
# 2526| m2526_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_1
18091+
# 2526| m2526_8(ClassWithDestructor) = Chi : total:m2524_8, partial:m2526_7
18092+
# 2530| r2530_1(glval<ClassWithDestructor>) = VariableAddress[y] :
18093+
# 2530| r2530_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
18094+
# 2530| v2530_3(void) = Call[~ClassWithDestructor] : func:r2530_2, this:r2530_1
18095+
# 2530| m2530_4(unknown) = ^CallSideEffect : ~m2526_5
18096+
# 2530| m2530_5(unknown) = Chi : total:m2526_5, partial:m2530_4
18097+
# 2530| v2530_6(void) = ^IndirectReadSideEffect[-1] : &:r2530_1, m2522_8
18098+
# 2530| m2530_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_1
18099+
# 2530| m2530_8(ClassWithDestructor) = Chi : total:m2522_8, partial:m2530_7
18100+
# 2526| r2526_9(glval<ClassWithDestructor>) = VariableAddress[x] :
18101+
# 2526| r2526_10(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
18102+
# 2526| v2526_11(void) = Call[~ClassWithDestructor] : func:r2526_10, this:r2526_9
18103+
# 2526| m2526_12(unknown) = ^CallSideEffect : ~m2530_5
18104+
# 2526| m2526_13(unknown) = Chi : total:m2530_5, partial:m2526_12
18105+
# 2526| v2526_14(void) = ^IndirectReadSideEffect[-1] : &:r2526_9, m2526_8
18106+
# 2526| m2526_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_9
18107+
# 2526| m2526_16(ClassWithDestructor) = Chi : total:m2526_8, partial:m2526_15
18108+
#-----| Goto -> Block 2
18109+
18110+
# 2527| Block 2
18111+
# 2527| m2527_1(unknown) = Phi : from 0:~m2522_6, from 1:~m2526_13
18112+
# 2527| v2527_2(void) = NoOp :
18113+
# 2528| v2528_1(void) = NoOp :
18114+
# 2530| v2530_9(void) = NoOp :
18115+
# 2531| v2531_1(void) = NoOp :
18116+
# 2521| v2521_7(void) = ReturnVoid :
18117+
# 2521| v2521_8(void) = AliasedUse : ~m2527_1
18118+
# 2521| v2521_9(void) = ExitFunction :
18119+
1796118120
perf-regression.cpp:
1796218121
# 6| void Big::Big()
1796318122
# 6| Block 0

0 commit comments

Comments
 (0)