C++: Add testcase where two destructor calls are remapped to a temporary object expression.

This commit is contained in:
Mathias Vorreiter Pedersen
2024-04-08 13:03:51 +01:00
parent d40fa4cfba
commit febd06063a
5 changed files with 175 additions and 0 deletions

View File

@@ -2326,6 +2326,47 @@ destructors_for_temps.cpp:
# 83| Type = [Class] ClassWithDestructor2
# 83| ValueCategory = xvalue
# 85| getStmt(1): [ReturnStmt] return ...
# 87| [CopyAssignmentOperator] ClassWithDestructor3& ClassWithDestructor3::operator=(ClassWithDestructor3 const&)
# 87| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const ClassWithDestructor3 &
# 87| [Constructor] void ClassWithDestructor3::ClassWithDestructor3()
# 87| <params>:
# 88| [Destructor] void ClassWithDestructor3::~ClassWithDestructor3()
# 88| <params>:
# 89| [MemberFunction] ClassWithDestructor2 ClassWithDestructor3::getClassWithDestructor2()
# 89| <params>:
# 92| [TopLevelFunction] ClassWithDestructor3 makeClassWithDestructor3()
# 92| <params>:
# 94| [TopLevelFunction] void temp_test11()
# 94| <params>:
# 94| getEntryPoint(): [BlockStmt] { ... }
# 99| getStmt(0): [ExprStmt] ExprStmt
# 99| getExpr(): [FunctionCall] call to getClassWithDestructor2
# 99| Type = [Class] ClassWithDestructor2
# 99| ValueCategory = prvalue
# 99| getQualifier(): [FunctionCall] call to makeClassWithDestructor3
# 99| Type = [Struct] ClassWithDestructor3
# 99| ValueCategory = prvalue
# 99| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 99| Type = [Struct] ClassWithDestructor3
# 99| ValueCategory = prvalue(load)
# 99| getExpr().getFullyConverted(): [TemporaryObjectExpr] temporary object
# 99| Type = [Class] ClassWithDestructor2
# 99| ValueCategory = prvalue
# 99| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor2
# 99| Type = [VoidType] void
# 99| ValueCategory = prvalue
# 99| getQualifier(): [ReuseExpr] reuse of temporary object
# 99| Type = [Class] ClassWithDestructor2
# 99| ValueCategory = xvalue
# 99| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor3
# 99| Type = [VoidType] void
# 99| ValueCategory = prvalue
# 99| getQualifier(): [ReuseExpr] reuse of temporary object
# 99| Type = [Struct] ClassWithDestructor3
# 99| ValueCategory = xvalue
# 100| getStmt(1): [ReturnStmt] return ...
ir.c:
# 5| [TopLevelFunction] int getX(MyCoords*)
# 5| <params>:

View File

@@ -1502,6 +1502,48 @@ destructors_for_temps.cpp:
# 81| v81_8(void) = AliasedUse : ~m82_1
# 81| v81_9(void) = ExitFunction :
# 94| void temp_test11()
# 94| Block 0
# 94| v94_1(void) = EnterFunction :
# 94| m94_2(unknown) = AliasedDefinition :
# 94| m94_3(unknown) = InitializeNonLocal :
# 94| m94_4(unknown) = Chi : total:m94_2, partial:m94_3
# 99| r99_1(glval<ClassWithDestructor2>) = VariableAddress[#temp99:5] :
# 99| r99_2(glval<ClassWithDestructor3>) = VariableAddress[#temp99:5] :
# 99| r99_3(glval<unknown>) = FunctionAddress[makeClassWithDestructor3] :
# 99| r99_4(ClassWithDestructor3) = Call[makeClassWithDestructor3] : func:r99_3
# 99| m99_5(unknown) = ^CallSideEffect : ~m94_4
# 99| m99_6(unknown) = Chi : total:m94_4, partial:m99_5
# 99| m99_7(ClassWithDestructor3) = Store[#temp99:5] : &:r99_2, r99_4
# 99| r99_8(glval<unknown>) = FunctionAddress[getClassWithDestructor2] :
# 99| r99_9(ClassWithDestructor2) = Call[getClassWithDestructor2] : func:r99_8, this:r99_2
# 99| m99_10(unknown) = ^CallSideEffect : ~m99_6
# 99| m99_11(unknown) = Chi : total:m99_6, partial:m99_10
# 99| v99_12(void) = ^IndirectReadSideEffect[-1] : &:r99_2, m99_7
# 99| m99_13(ClassWithDestructor3) = ^IndirectMayWriteSideEffect[-1] : &:r99_2
# 99| m99_14(ClassWithDestructor3) = Chi : total:m99_7, partial:m99_13
# 99| m99_15(ClassWithDestructor2) = Store[#temp99:5] : &:r99_1, r99_9
# 99| r99_16(glval<ClassWithDestructor2>) = CopyValue : r99_1
# 99| r99_17(glval<unknown>) = FunctionAddress[~ClassWithDestructor2] :
# 99| v99_18(void) = Call[~ClassWithDestructor2] : func:r99_17, this:r99_16
# 99| m99_19(unknown) = ^CallSideEffect : ~m99_11
# 99| m99_20(unknown) = Chi : total:m99_11, partial:m99_19
# 99| v99_21(void) = ^IndirectReadSideEffect[-1] : &:r99_16, m99_15
# 99| m99_22(ClassWithDestructor2) = ^IndirectMayWriteSideEffect[-1] : &:r99_16
# 99| m99_23(ClassWithDestructor2) = Chi : total:m99_15, partial:m99_22
# 99| r99_24(glval<ClassWithDestructor3>) = CopyValue : r99_2
# 99| r99_25(glval<unknown>) = FunctionAddress[~ClassWithDestructor3] :
# 99| v99_26(void) = Call[~ClassWithDestructor3] : func:r99_25, this:r99_24
# 99| m99_27(unknown) = ^CallSideEffect : ~m99_20
# 99| m99_28(unknown) = Chi : total:m99_20, partial:m99_27
# 99| v99_29(void) = ^IndirectReadSideEffect[-1] : &:r99_24, m99_14
# 99| m99_30(ClassWithDestructor3) = ^IndirectMayWriteSideEffect[-1] : &:r99_24
# 99| m99_31(ClassWithDestructor3) = Chi : total:m99_14, partial:m99_30
# 100| v100_1(void) = NoOp :
# 94| v94_5(void) = ReturnVoid :
# 94| v94_6(void) = AliasedUse : ~m99_28
# 94| v94_7(void) = ExitFunction :
ir.c:
# 7| void MyCoordsTest(int)
# 7| Block 0

View File

@@ -82,4 +82,19 @@ void temp_test10(int i) {
while(i < 10) {
make();
}
}
struct ClassWithDestructor3 {
~ClassWithDestructor3();
ClassWithDestructor2 getClassWithDestructor2();
};
ClassWithDestructor3 makeClassWithDestructor3();
void temp_test11() {
// Two destructors are called at the semicolon (i.e., they're both attached
// to the call to `getClassWithDestructor2()`):
// First, ~ClassWithDestructor2::ClassWithDestructor2(), and then the call
// to `~ClassWithDestructor3::ClassWithDestructor3()`.
makeClassWithDestructor3().getClassWithDestructor2();
}

View File

@@ -1332,6 +1332,49 @@
| destructors_for_temps.cpp:83:9:83:14 | SideEffect | m83_6 |
| destructors_for_temps.cpp:83:9:83:14 | SideEffect | ~m83_5 |
| destructors_for_temps.cpp:83:9:83:14 | Unary | r83_1 |
| destructors_for_temps.cpp:94:6:94:16 | ChiPartial | partial:m94_3 |
| destructors_for_temps.cpp:94:6:94:16 | ChiTotal | total:m94_2 |
| destructors_for_temps.cpp:94:6:94:16 | SideEffect | ~m99_28 |
| destructors_for_temps.cpp:99:5:99:28 | CallTarget | func:r99_3 |
| destructors_for_temps.cpp:99:5:99:28 | ChiPartial | partial:m99_5 |
| destructors_for_temps.cpp:99:5:99:28 | ChiTotal | total:m94_4 |
| destructors_for_temps.cpp:99:5:99:28 | SideEffect | ~m94_4 |
| destructors_for_temps.cpp:99:5:99:28 | StoreValue | r99_4 |
| destructors_for_temps.cpp:99:5:99:30 | Address | &:r99_2 |
| destructors_for_temps.cpp:99:5:99:30 | Address | &:r99_2 |
| destructors_for_temps.cpp:99:5:99:30 | Address | &:r99_2 |
| destructors_for_temps.cpp:99:5:99:30 | Address | &:r99_24 |
| destructors_for_temps.cpp:99:5:99:30 | Address | &:r99_24 |
| destructors_for_temps.cpp:99:5:99:30 | Arg(this) | this:r99_2 |
| destructors_for_temps.cpp:99:5:99:30 | Arg(this) | this:r99_24 |
| destructors_for_temps.cpp:99:5:99:30 | CallTarget | func:r99_25 |
| destructors_for_temps.cpp:99:5:99:30 | ChiPartial | partial:m99_13 |
| destructors_for_temps.cpp:99:5:99:30 | ChiPartial | partial:m99_27 |
| destructors_for_temps.cpp:99:5:99:30 | ChiPartial | partial:m99_30 |
| destructors_for_temps.cpp:99:5:99:30 | ChiTotal | total:m99_7 |
| destructors_for_temps.cpp:99:5:99:30 | ChiTotal | total:m99_14 |
| destructors_for_temps.cpp:99:5:99:30 | ChiTotal | total:m99_20 |
| destructors_for_temps.cpp:99:5:99:30 | SideEffect | m99_7 |
| destructors_for_temps.cpp:99:5:99:30 | SideEffect | m99_14 |
| destructors_for_temps.cpp:99:5:99:30 | SideEffect | ~m99_20 |
| destructors_for_temps.cpp:99:5:99:30 | Unary | r99_2 |
| destructors_for_temps.cpp:99:5:99:56 | Address | &:r99_1 |
| destructors_for_temps.cpp:99:5:99:56 | Address | &:r99_16 |
| destructors_for_temps.cpp:99:5:99:56 | Address | &:r99_16 |
| destructors_for_temps.cpp:99:5:99:56 | Arg(this) | this:r99_16 |
| destructors_for_temps.cpp:99:5:99:56 | CallTarget | func:r99_17 |
| destructors_for_temps.cpp:99:5:99:56 | ChiPartial | partial:m99_19 |
| destructors_for_temps.cpp:99:5:99:56 | ChiPartial | partial:m99_22 |
| destructors_for_temps.cpp:99:5:99:56 | ChiTotal | total:m99_11 |
| destructors_for_temps.cpp:99:5:99:56 | ChiTotal | total:m99_15 |
| destructors_for_temps.cpp:99:5:99:56 | SideEffect | m99_15 |
| destructors_for_temps.cpp:99:5:99:56 | SideEffect | ~m99_11 |
| destructors_for_temps.cpp:99:5:99:56 | Unary | r99_1 |
| destructors_for_temps.cpp:99:32:99:54 | CallTarget | func:r99_8 |
| destructors_for_temps.cpp:99:32:99:54 | ChiPartial | partial:m99_10 |
| destructors_for_temps.cpp:99:32:99:54 | ChiTotal | total:m99_6 |
| destructors_for_temps.cpp:99:32:99:54 | SideEffect | ~m99_6 |
| destructors_for_temps.cpp:99:32:99:54 | StoreValue | r99_9 |
| file://:0:0:0:0 | Address | &:r0_1 |
| file://:0:0:0:0 | Address | &:r0_1 |
| file://:0:0:0:0 | Address | &:r0_1 |

View File

@@ -1365,6 +1365,40 @@ destructors_for_temps.cpp:
# 81| v81_7(void) = AliasedUse : ~m?
# 81| v81_8(void) = ExitFunction :
# 94| void temp_test11()
# 94| Block 0
# 94| v94_1(void) = EnterFunction :
# 94| mu94_2(unknown) = AliasedDefinition :
# 94| mu94_3(unknown) = InitializeNonLocal :
# 99| r99_1(glval<ClassWithDestructor2>) = VariableAddress[#temp99:5] :
# 99| r99_2(glval<ClassWithDestructor3>) = VariableAddress[#temp99:5] :
# 99| r99_3(glval<unknown>) = FunctionAddress[makeClassWithDestructor3] :
# 99| r99_4(ClassWithDestructor3) = Call[makeClassWithDestructor3] : func:r99_3
# 99| mu99_5(unknown) = ^CallSideEffect : ~m?
# 99| mu99_6(ClassWithDestructor3) = Store[#temp99:5] : &:r99_2, r99_4
# 99| r99_7(glval<unknown>) = FunctionAddress[getClassWithDestructor2] :
# 99| r99_8(ClassWithDestructor2) = Call[getClassWithDestructor2] : func:r99_7, this:r99_2
# 99| mu99_9(unknown) = ^CallSideEffect : ~m?
# 99| v99_10(void) = ^IndirectReadSideEffect[-1] : &:r99_2, ~m?
# 99| mu99_11(ClassWithDestructor3) = ^IndirectMayWriteSideEffect[-1] : &:r99_2
# 99| mu99_12(ClassWithDestructor2) = Store[#temp99:5] : &:r99_1, r99_8
# 99| r99_13(glval<ClassWithDestructor2>) = CopyValue : r99_1
# 99| r99_14(glval<unknown>) = FunctionAddress[~ClassWithDestructor2] :
# 99| v99_15(void) = Call[~ClassWithDestructor2] : func:r99_14, this:r99_13
# 99| mu99_16(unknown) = ^CallSideEffect : ~m?
# 99| v99_17(void) = ^IndirectReadSideEffect[-1] : &:r99_13, ~m?
# 99| mu99_18(ClassWithDestructor2) = ^IndirectMayWriteSideEffect[-1] : &:r99_13
# 99| r99_19(glval<ClassWithDestructor3>) = CopyValue : r99_2
# 99| r99_20(glval<unknown>) = FunctionAddress[~ClassWithDestructor3] :
# 99| v99_21(void) = Call[~ClassWithDestructor3] : func:r99_20, this:r99_19
# 99| mu99_22(unknown) = ^CallSideEffect : ~m?
# 99| v99_23(void) = ^IndirectReadSideEffect[-1] : &:r99_19, ~m?
# 99| mu99_24(ClassWithDestructor3) = ^IndirectMayWriteSideEffect[-1] : &:r99_19
# 100| v100_1(void) = NoOp :
# 94| v94_4(void) = ReturnVoid :
# 94| v94_5(void) = AliasedUse : ~m?
# 94| v94_6(void) = ExitFunction :
ir.c:
# 7| void MyCoordsTest(int)
# 7| Block 0