Merge pull request #15964 from rdmarsh2/rdmarsh2/cpp/temp-destructors-extended

C++: IR translation for destruction of temporaries with extended lifetimes
This commit is contained in:
Mathias Vorreiter Pedersen
2024-03-27 11:58:48 +00:00
committed by GitHub
7 changed files with 204 additions and 75 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added destructors for temporary objects with extended lifetimes to the intermediate representation.

View File

@@ -130,11 +130,6 @@ private predicate ignoreExprAndDescendants(Expr expr) {
or
// suppress destructors of temporary variables until proper support is added for them.
exists(Expr parent | parent.getAnImplicitDestructorCall() = expr)
or
exists(Stmt parent |
parent.getAnImplicitDestructorCall() = expr and
expr.(DestructorCall).getQualifier() instanceof ReuseExpr
)
}
/**

View File

@@ -2769,6 +2769,50 @@ class TranslatedTemporaryObjectExpr extends TranslatedNonConstantExpr,
final override Instruction getResult() { result = this.getTargetAddress() }
}
/**
* IR translation of a `ReuseExpr`.
*
* This translation produces a copy of the glvalue instruction holding the (unconverted) result
* of the reused expression. In the case where the original expression was a prvalue, the
* result will be a copy of the glvalue operand of a `TranslatedLoad`.
*/
class TranslatedReuseExpr extends TranslatedNonConstantExpr {
override ReuseExpr expr;
override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(OnlyInstructionTag()) and
kind instanceof GotoEdge
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
opcode instanceof Opcode::CopyValue and
tag instanceof OnlyInstructionTag and
resultType = this.getResultType()
}
override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
kind instanceof GotoEdge and
result = this.getParent().getChildSuccessor(this, kind)
}
override TranslatedElement getChildInternal(int id) { none() }
override Instruction getALastInstructionInternal() {
result = this.getInstruction(OnlyInstructionTag())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
if getTranslatedExpr(expr.getReusedExpr()) instanceof TranslatedLoad
then result = getTranslatedExpr(expr.getReusedExpr()).(TranslatedLoad).getOperand().getResult()
else result = getTranslatedExpr(expr.getReusedExpr()).getResult()
}
}
/**
* IR translation of a `throw` expression.
*/

View File

@@ -248,19 +248,9 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
final override TranslatedElement getChild(int id) {
result = this.getChildInternal(id)
or
exists(int destructorIndex, int tempDestructorCount |
exists(int destructorIndex |
result.(TranslatedExpr).getExpr() = stmt.getImplicitDestructorCall(destructorIndex) and
id = this.getFirstDestructorCallIndex() + destructorIndex - tempDestructorCount and
// suppress destructors of temporary variables until proper support is added for them.
tempDestructorCount =
count(DestructorCall call, int tempIndex |
stmt.getImplicitDestructorCall(tempIndex) = call and
tempIndex < destructorIndex and
call.getQualifier() instanceof ReuseExpr
|
call
) and
not stmt.getImplicitDestructorCall(destructorIndex).getQualifier() instanceof ReuseExpr
id = this.getFirstDestructorCallIndex() + destructorIndex
)
}
@@ -271,11 +261,7 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
}
final override predicate hasAnImplicitDestructorCall() {
exists(stmt.getAnImplicitDestructorCall()) and
// suppress destructors of temporary variables until proper support is added for them.
exists(Expr expr | stmt.getAnImplicitDestructorCall().getQualifier() = expr |
not expr instanceof ReuseExpr
)
exists(stmt.getAnImplicitDestructorCall())
}
final override string toString() { result = stmt.toString() }

View File

@@ -891,24 +891,32 @@ destructors_for_temps.cpp:
# 29| void temp_test3()
# 29| Block 0
# 29| v29_1(void) = EnterFunction :
# 29| m29_2(unknown) = AliasedDefinition :
# 29| m29_3(unknown) = InitializeNonLocal :
# 29| m29_4(unknown) = Chi : total:m29_2, partial:m29_3
# 30| r30_1(glval<ClassWithDestructor2 &>) = VariableAddress[rs] :
# 30| r30_2(glval<ClassWithDestructor2>) = VariableAddress[#temp30:38] :
# 30| r30_3(glval<unknown>) = FunctionAddress[returnValue] :
# 30| r30_4(ClassWithDestructor2) = Call[returnValue] : func:r30_3
# 30| m30_5(unknown) = ^CallSideEffect : ~m29_4
# 30| m30_6(unknown) = Chi : total:m29_4, partial:m30_5
# 30| m30_7(ClassWithDestructor2) = Store[#temp30:38] : &:r30_2, r30_4
# 30| r30_8(glval<ClassWithDestructor2>) = Convert : r30_2
# 30| r30_9(ClassWithDestructor2 &) = CopyValue : r30_8
# 30| m30_10(ClassWithDestructor2 &) = Store[rs] : &:r30_1, r30_9
# 31| v31_1(void) = NoOp :
# 29| v29_5(void) = ReturnVoid :
# 29| v29_6(void) = AliasedUse : ~m30_6
# 29| v29_7(void) = ExitFunction :
# 29| v29_1(void) = EnterFunction :
# 29| m29_2(unknown) = AliasedDefinition :
# 29| m29_3(unknown) = InitializeNonLocal :
# 29| m29_4(unknown) = Chi : total:m29_2, partial:m29_3
# 30| r30_1(glval<ClassWithDestructor2 &>) = VariableAddress[rs] :
# 30| r30_2(glval<ClassWithDestructor2>) = VariableAddress[#temp30:38] :
# 30| r30_3(glval<unknown>) = FunctionAddress[returnValue] :
# 30| r30_4(ClassWithDestructor2) = Call[returnValue] : func:r30_3
# 30| m30_5(unknown) = ^CallSideEffect : ~m29_4
# 30| m30_6(unknown) = Chi : total:m29_4, partial:m30_5
# 30| m30_7(ClassWithDestructor2) = Store[#temp30:38] : &:r30_2, r30_4
# 30| r30_8(glval<ClassWithDestructor2>) = Convert : r30_2
# 30| r30_9(ClassWithDestructor2 &) = CopyValue : r30_8
# 30| m30_10(ClassWithDestructor2 &) = Store[rs] : &:r30_1, r30_9
# 31| v31_1(void) = NoOp :
# 31| r31_2(glval<ClassWithDestructor2>) = CopyValue : r30_2
# 31| r31_3(glval<unknown>) = FunctionAddress[~ClassWithDestructor2] :
# 31| v31_4(void) = Call[~ClassWithDestructor2] : func:r31_3, this:r31_2
# 31| m31_5(unknown) = ^CallSideEffect : ~m30_6
# 31| m31_6(unknown) = Chi : total:m30_6, partial:m31_5
# 31| v31_7(void) = ^IndirectReadSideEffect[-1] : &:r31_2, m30_7
# 31| m31_8(ClassWithDestructor2) = ^IndirectMayWriteSideEffect[-1] : &:r31_2
# 31| m31_9(ClassWithDestructor2) = Chi : total:m30_7, partial:m31_8
# 29| v29_5(void) = ReturnVoid :
# 29| v29_6(void) = AliasedUse : ~m31_6
# 29| v29_7(void) = ExitFunction :
# 33| void temp_test4()
# 33| Block 0
@@ -935,16 +943,24 @@ destructors_for_temps.cpp:
# 35| r35_9(ClassWithDestructor2 &) = CopyValue : r35_8
# 35| m35_10(ClassWithDestructor2 &) = Store[rs2] : &:r35_1, r35_9
# 36| v36_1(void) = NoOp :
# 36| r36_2(glval<ClassWithDestructor2>) = VariableAddress[c] :
# 36| r36_2(glval<ClassWithDestructor2>) = CopyValue : r35_2
# 36| r36_3(glval<unknown>) = FunctionAddress[~ClassWithDestructor2] :
# 36| v36_4(void) = Call[~ClassWithDestructor2] : func:r36_3, this:r36_2
# 36| m36_5(unknown) = ^CallSideEffect : ~m35_6
# 36| m36_6(unknown) = Chi : total:m35_6, partial:m36_5
# 36| v36_7(void) = ^IndirectReadSideEffect[-1] : &:r36_2, m34_8
# 36| v36_7(void) = ^IndirectReadSideEffect[-1] : &:r36_2, m35_7
# 36| m36_8(ClassWithDestructor2) = ^IndirectMayWriteSideEffect[-1] : &:r36_2
# 36| m36_9(ClassWithDestructor2) = Chi : total:m34_8, partial:m36_8
# 36| m36_9(ClassWithDestructor2) = Chi : total:m35_7, partial:m36_8
# 36| r36_10(glval<ClassWithDestructor2>) = VariableAddress[c] :
# 36| r36_11(glval<unknown>) = FunctionAddress[~ClassWithDestructor2] :
# 36| v36_12(void) = Call[~ClassWithDestructor2] : func:r36_11, this:r36_10
# 36| m36_13(unknown) = ^CallSideEffect : ~m36_6
# 36| m36_14(unknown) = Chi : total:m36_6, partial:m36_13
# 36| v36_15(void) = ^IndirectReadSideEffect[-1] : &:r36_10, m34_8
# 36| m36_16(ClassWithDestructor2) = ^IndirectMayWriteSideEffect[-1] : &:r36_10
# 36| m36_17(ClassWithDestructor2) = Chi : total:m34_8, partial:m36_16
# 33| v33_5(void) = ReturnVoid :
# 33| v33_6(void) = AliasedUse : ~m36_6
# 33| v33_6(void) = AliasedUse : ~m36_14
# 33| v33_7(void) = ExitFunction :
# 38| void temp_test5(bool)
@@ -8882,16 +8898,24 @@ ir.cpp:
# 1425| m1425_5(unknown) = Chi : total:m1423_11, partial:m1425_4
# 1425| m1425_6(String) = Store[#temp1425:5] : &:r1425_1, r1425_3
# 1426| v1426_1(void) = NoOp :
# 1426| r1426_2(glval<String>) = VariableAddress[s] :
# 1426| r1426_2(glval<String>) = CopyValue : r1416_2
# 1426| r1426_3(glval<unknown>) = FunctionAddress[~String] :
# 1426| v1426_4(void) = Call[~String] : func:r1426_3, this:r1426_2
# 1426| m1426_5(unknown) = ^CallSideEffect : ~m1425_5
# 1426| m1426_6(unknown) = Chi : total:m1425_5, partial:m1426_5
# 1426| v1426_7(void) = ^IndirectReadSideEffect[-1] : &:r1426_2, m1415_6
# 1426| v1426_7(void) = ^IndirectReadSideEffect[-1] : &:r1426_2, m1416_7
# 1426| m1426_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r1426_2
# 1426| m1426_9(String) = Chi : total:m1415_6, partial:m1426_8
# 1426| m1426_9(String) = Chi : total:m1416_7, partial:m1426_8
# 1426| r1426_10(glval<String>) = VariableAddress[s] :
# 1426| r1426_11(glval<unknown>) = FunctionAddress[~String] :
# 1426| v1426_12(void) = Call[~String] : func:r1426_11, this:r1426_10
# 1426| m1426_13(unknown) = ^CallSideEffect : ~m1426_6
# 1426| m1426_14(unknown) = Chi : total:m1426_6, partial:m1426_13
# 1426| v1426_15(void) = ^IndirectReadSideEffect[-1] : &:r1426_10, m1415_6
# 1426| m1426_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r1426_10
# 1426| m1426_17(String) = Chi : total:m1415_6, partial:m1426_16
# 1414| v1414_5(void) = ReturnVoid :
# 1414| v1414_6(void) = AliasedUse : ~m1426_6
# 1414| v1414_6(void) = AliasedUse : ~m1426_14
# 1414| v1414_7(void) = ExitFunction :
# 1428| void temporary_destructor_only()
@@ -8973,16 +8997,24 @@ ir.cpp:
# 1438| v1438_7(void) = ^IndirectReadSideEffect[-1] : &:r1438_2, m1431_2
# 1438| m1438_8(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1438_2
# 1438| m1438_9(destructor_only) = Chi : total:m1431_2, partial:m1438_8
# 1438| r1438_10(glval<destructor_only>) = VariableAddress[d] :
# 1438| r1438_10(glval<destructor_only>) = CopyValue : r1430_2
# 1438| r1438_11(glval<unknown>) = FunctionAddress[~destructor_only] :
# 1438| v1438_12(void) = Call[~destructor_only] : func:r1438_11, this:r1438_10
# 1438| m1438_13(unknown) = ^CallSideEffect : ~m1438_6
# 1438| m1438_14(unknown) = Chi : total:m1438_6, partial:m1438_13
# 1438| v1438_15(void) = ^IndirectReadSideEffect[-1] : &:r1438_10, m1429_6
# 1438| v1438_15(void) = ^IndirectReadSideEffect[-1] : &:r1438_10, m1430_7
# 1438| m1438_16(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1438_10
# 1438| m1438_17(destructor_only) = Chi : total:m1429_6, partial:m1438_16
# 1438| m1438_17(destructor_only) = Chi : total:m1430_7, partial:m1438_16
# 1438| r1438_18(glval<destructor_only>) = VariableAddress[d] :
# 1438| r1438_19(glval<unknown>) = FunctionAddress[~destructor_only] :
# 1438| v1438_20(void) = Call[~destructor_only] : func:r1438_19, this:r1438_18
# 1438| m1438_21(unknown) = ^CallSideEffect : ~m1438_14
# 1438| m1438_22(unknown) = Chi : total:m1438_14, partial:m1438_21
# 1438| v1438_23(void) = ^IndirectReadSideEffect[-1] : &:r1438_18, m1429_6
# 1438| m1438_24(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1438_18
# 1438| m1438_25(destructor_only) = Chi : total:m1429_6, partial:m1438_24
# 1428| v1428_5(void) = ReturnVoid :
# 1428| v1428_6(void) = AliasedUse : ~m1438_14
# 1428| v1428_6(void) = AliasedUse : ~m1438_22
# 1428| v1428_7(void) = ExitFunction :
# 1440| void temporary_copy_constructor()

View File

@@ -805,7 +805,7 @@
| destructors_for_temps.cpp:23:68:23:72 | Unary | r23_27 |
| destructors_for_temps.cpp:29:6:29:15 | ChiPartial | partial:m29_3 |
| destructors_for_temps.cpp:29:6:29:15 | ChiTotal | total:m29_2 |
| destructors_for_temps.cpp:29:6:29:15 | SideEffect | ~m30_6 |
| destructors_for_temps.cpp:29:6:29:15 | SideEffect | ~m31_6 |
| destructors_for_temps.cpp:30:33:30:34 | Address | &:r30_1 |
| destructors_for_temps.cpp:30:38:30:70 | CallTarget | func:r30_3 |
| destructors_for_temps.cpp:30:38:30:70 | ChiPartial | partial:m30_5 |
@@ -815,10 +815,21 @@
| destructors_for_temps.cpp:30:38:30:72 | Address | &:r30_2 |
| destructors_for_temps.cpp:30:38:30:72 | StoreValue | r30_9 |
| destructors_for_temps.cpp:30:38:30:72 | Unary | r30_2 |
| destructors_for_temps.cpp:30:38:30:72 | Unary | r30_2 |
| destructors_for_temps.cpp:30:38:30:72 | Unary | r30_8 |
| destructors_for_temps.cpp:31:1:31:1 | Address | &:r31_2 |
| destructors_for_temps.cpp:31:1:31:1 | Address | &:r31_2 |
| destructors_for_temps.cpp:31:1:31:1 | Arg(this) | this:r31_2 |
| destructors_for_temps.cpp:31:1:31:1 | CallTarget | func:r31_3 |
| destructors_for_temps.cpp:31:1:31:1 | ChiPartial | partial:m31_5 |
| destructors_for_temps.cpp:31:1:31:1 | ChiPartial | partial:m31_8 |
| destructors_for_temps.cpp:31:1:31:1 | ChiTotal | total:m30_6 |
| destructors_for_temps.cpp:31:1:31:1 | ChiTotal | total:m30_7 |
| destructors_for_temps.cpp:31:1:31:1 | SideEffect | m30_7 |
| destructors_for_temps.cpp:31:1:31:1 | SideEffect | ~m30_6 |
| destructors_for_temps.cpp:33:6:33:15 | ChiPartial | partial:m33_3 |
| destructors_for_temps.cpp:33:6:33:15 | ChiTotal | total:m33_2 |
| destructors_for_temps.cpp:33:6:33:15 | SideEffect | ~m36_6 |
| destructors_for_temps.cpp:33:6:33:15 | SideEffect | ~m36_14 |
| destructors_for_temps.cpp:34:26:34:26 | Address | &:r34_1 |
| destructors_for_temps.cpp:34:26:34:26 | Address | &:r34_1 |
| destructors_for_temps.cpp:34:26:34:26 | Arg(this) | this:r34_1 |
@@ -837,17 +848,28 @@
| destructors_for_temps.cpp:35:39:35:73 | Address | &:r35_2 |
| destructors_for_temps.cpp:35:39:35:73 | StoreValue | r35_9 |
| destructors_for_temps.cpp:35:39:35:73 | Unary | r35_2 |
| destructors_for_temps.cpp:35:39:35:73 | Unary | r35_2 |
| destructors_for_temps.cpp:35:39:35:73 | Unary | r35_8 |
| destructors_for_temps.cpp:36:1:36:1 | Address | &:r36_2 |
| destructors_for_temps.cpp:36:1:36:1 | Address | &:r36_2 |
| destructors_for_temps.cpp:36:1:36:1 | Address | &:r36_10 |
| destructors_for_temps.cpp:36:1:36:1 | Address | &:r36_10 |
| destructors_for_temps.cpp:36:1:36:1 | Arg(this) | this:r36_2 |
| destructors_for_temps.cpp:36:1:36:1 | Arg(this) | this:r36_10 |
| destructors_for_temps.cpp:36:1:36:1 | CallTarget | func:r36_3 |
| destructors_for_temps.cpp:36:1:36:1 | CallTarget | func:r36_11 |
| destructors_for_temps.cpp:36:1:36:1 | ChiPartial | partial:m36_5 |
| destructors_for_temps.cpp:36:1:36:1 | ChiPartial | partial:m36_8 |
| destructors_for_temps.cpp:36:1:36:1 | ChiPartial | partial:m36_13 |
| destructors_for_temps.cpp:36:1:36:1 | ChiPartial | partial:m36_16 |
| destructors_for_temps.cpp:36:1:36:1 | ChiTotal | total:m34_8 |
| destructors_for_temps.cpp:36:1:36:1 | ChiTotal | total:m35_6 |
| destructors_for_temps.cpp:36:1:36:1 | ChiTotal | total:m35_7 |
| destructors_for_temps.cpp:36:1:36:1 | ChiTotal | total:m36_6 |
| destructors_for_temps.cpp:36:1:36:1 | SideEffect | m34_8 |
| destructors_for_temps.cpp:36:1:36:1 | SideEffect | m35_7 |
| destructors_for_temps.cpp:36:1:36:1 | SideEffect | ~m35_6 |
| destructors_for_temps.cpp:36:1:36:1 | SideEffect | ~m36_6 |
| destructors_for_temps.cpp:38:6:38:15 | ChiPartial | partial:m38_3 |
| destructors_for_temps.cpp:38:6:38:15 | ChiTotal | total:m38_2 |
| destructors_for_temps.cpp:38:6:38:15 | SideEffect | ~m39_5 |
@@ -7276,7 +7298,7 @@
| ir.cpp:1376:5:1376:15 | StoreValue | r1376_2 |
| ir.cpp:1414:6:1414:21 | ChiPartial | partial:m1414_3 |
| ir.cpp:1414:6:1414:21 | ChiTotal | total:m1414_2 |
| ir.cpp:1414:6:1414:21 | SideEffect | ~m1426_6 |
| ir.cpp:1414:6:1414:21 | SideEffect | ~m1426_14 |
| ir.cpp:1415:12:1415:12 | Address | &:r1415_1 |
| ir.cpp:1415:16:1415:34 | CallTarget | func:r1415_2 |
| ir.cpp:1415:16:1415:34 | ChiPartial | partial:m1415_4 |
@@ -7292,6 +7314,7 @@
| ir.cpp:1416:24:1416:44 | Address | &:r1416_2 |
| ir.cpp:1416:24:1416:44 | StoreValue | r1416_9 |
| ir.cpp:1416:24:1416:44 | Unary | r1416_2 |
| ir.cpp:1416:24:1416:44 | Unary | r1416_2 |
| ir.cpp:1416:24:1416:44 | Unary | r1416_8 |
| ir.cpp:1418:5:1418:13 | CallTarget | func:r1418_1 |
| ir.cpp:1418:5:1418:13 | ChiPartial | partial:m1418_6 |
@@ -7403,17 +7426,27 @@
| ir.cpp:1425:5:1425:30 | Address | &:r1425_1 |
| ir.cpp:1426:1:1426:1 | Address | &:r1426_2 |
| ir.cpp:1426:1:1426:1 | Address | &:r1426_2 |
| ir.cpp:1426:1:1426:1 | Address | &:r1426_10 |
| ir.cpp:1426:1:1426:1 | Address | &:r1426_10 |
| ir.cpp:1426:1:1426:1 | Arg(this) | this:r1426_2 |
| ir.cpp:1426:1:1426:1 | Arg(this) | this:r1426_10 |
| ir.cpp:1426:1:1426:1 | CallTarget | func:r1426_3 |
| ir.cpp:1426:1:1426:1 | CallTarget | func:r1426_11 |
| ir.cpp:1426:1:1426:1 | ChiPartial | partial:m1426_5 |
| ir.cpp:1426:1:1426:1 | ChiPartial | partial:m1426_8 |
| ir.cpp:1426:1:1426:1 | ChiPartial | partial:m1426_13 |
| ir.cpp:1426:1:1426:1 | ChiPartial | partial:m1426_16 |
| ir.cpp:1426:1:1426:1 | ChiTotal | total:m1415_6 |
| ir.cpp:1426:1:1426:1 | ChiTotal | total:m1416_7 |
| ir.cpp:1426:1:1426:1 | ChiTotal | total:m1425_5 |
| ir.cpp:1426:1:1426:1 | ChiTotal | total:m1426_6 |
| ir.cpp:1426:1:1426:1 | SideEffect | m1415_6 |
| ir.cpp:1426:1:1426:1 | SideEffect | m1416_7 |
| ir.cpp:1426:1:1426:1 | SideEffect | ~m1425_5 |
| ir.cpp:1426:1:1426:1 | SideEffect | ~m1426_6 |
| ir.cpp:1428:6:1428:30 | ChiPartial | partial:m1428_3 |
| ir.cpp:1428:6:1428:30 | ChiTotal | total:m1428_2 |
| ir.cpp:1428:6:1428:30 | SideEffect | ~m1438_14 |
| ir.cpp:1428:6:1428:30 | SideEffect | ~m1438_22 |
| ir.cpp:1429:21:1429:21 | Address | &:r1429_1 |
| ir.cpp:1429:25:1429:52 | CallTarget | func:r1429_2 |
| ir.cpp:1429:25:1429:52 | ChiPartial | partial:m1429_4 |
@@ -7429,6 +7462,7 @@
| ir.cpp:1430:33:1430:62 | Address | &:r1430_2 |
| ir.cpp:1430:33:1430:62 | StoreValue | r1430_9 |
| ir.cpp:1430:33:1430:62 | Unary | r1430_2 |
| ir.cpp:1430:33:1430:62 | Unary | r1430_2 |
| ir.cpp:1430:33:1430:62 | Unary | r1430_8 |
| ir.cpp:1431:21:1431:22 | Address | &:r1431_1 |
| ir.cpp:1432:5:1432:13 | CallTarget | func:r1432_1 |
@@ -7489,22 +7523,32 @@
| ir.cpp:1438:1:1438:1 | Address | &:r1438_2 |
| ir.cpp:1438:1:1438:1 | Address | &:r1438_10 |
| ir.cpp:1438:1:1438:1 | Address | &:r1438_10 |
| ir.cpp:1438:1:1438:1 | Address | &:r1438_18 |
| ir.cpp:1438:1:1438:1 | Address | &:r1438_18 |
| ir.cpp:1438:1:1438:1 | Arg(this) | this:r1438_2 |
| ir.cpp:1438:1:1438:1 | Arg(this) | this:r1438_10 |
| ir.cpp:1438:1:1438:1 | Arg(this) | this:r1438_18 |
| ir.cpp:1438:1:1438:1 | CallTarget | func:r1438_3 |
| ir.cpp:1438:1:1438:1 | CallTarget | func:r1438_11 |
| ir.cpp:1438:1:1438:1 | CallTarget | func:r1438_19 |
| ir.cpp:1438:1:1438:1 | ChiPartial | partial:m1438_5 |
| ir.cpp:1438:1:1438:1 | ChiPartial | partial:m1438_8 |
| ir.cpp:1438:1:1438:1 | ChiPartial | partial:m1438_13 |
| ir.cpp:1438:1:1438:1 | ChiPartial | partial:m1438_16 |
| ir.cpp:1438:1:1438:1 | ChiPartial | partial:m1438_21 |
| ir.cpp:1438:1:1438:1 | ChiPartial | partial:m1438_24 |
| ir.cpp:1438:1:1438:1 | ChiTotal | total:m1429_6 |
| ir.cpp:1438:1:1438:1 | ChiTotal | total:m1430_7 |
| ir.cpp:1438:1:1438:1 | ChiTotal | total:m1431_2 |
| ir.cpp:1438:1:1438:1 | ChiTotal | total:m1437_5 |
| ir.cpp:1438:1:1438:1 | ChiTotal | total:m1438_6 |
| ir.cpp:1438:1:1438:1 | ChiTotal | total:m1438_14 |
| ir.cpp:1438:1:1438:1 | SideEffect | m1429_6 |
| ir.cpp:1438:1:1438:1 | SideEffect | m1430_7 |
| ir.cpp:1438:1:1438:1 | SideEffect | m1431_2 |
| ir.cpp:1438:1:1438:1 | SideEffect | ~m1437_5 |
| ir.cpp:1438:1:1438:1 | SideEffect | ~m1438_6 |
| ir.cpp:1438:1:1438:1 | SideEffect | ~m1438_14 |
| ir.cpp:1440:6:1440:31 | ChiPartial | partial:m1440_3 |
| ir.cpp:1440:6:1440:31 | ChiTotal | total:m1440_2 |
| ir.cpp:1440:6:1440:31 | SideEffect | ~m1450_6 |

View File

@@ -849,22 +849,28 @@ destructors_for_temps.cpp:
# 29| void temp_test3()
# 29| Block 0
# 29| v29_1(void) = EnterFunction :
# 29| mu29_2(unknown) = AliasedDefinition :
# 29| mu29_3(unknown) = InitializeNonLocal :
# 30| r30_1(glval<ClassWithDestructor2 &>) = VariableAddress[rs] :
# 30| r30_2(glval<ClassWithDestructor2>) = VariableAddress[#temp30:38] :
# 30| r30_3(glval<unknown>) = FunctionAddress[returnValue] :
# 30| r30_4(ClassWithDestructor2) = Call[returnValue] : func:r30_3
# 30| mu30_5(unknown) = ^CallSideEffect : ~m?
# 30| mu30_6(ClassWithDestructor2) = Store[#temp30:38] : &:r30_2, r30_4
# 30| r30_7(glval<ClassWithDestructor2>) = Convert : r30_2
# 30| r30_8(ClassWithDestructor2 &) = CopyValue : r30_7
# 30| mu30_9(ClassWithDestructor2 &) = Store[rs] : &:r30_1, r30_8
# 31| v31_1(void) = NoOp :
# 29| v29_4(void) = ReturnVoid :
# 29| v29_5(void) = AliasedUse : ~m?
# 29| v29_6(void) = ExitFunction :
# 29| v29_1(void) = EnterFunction :
# 29| mu29_2(unknown) = AliasedDefinition :
# 29| mu29_3(unknown) = InitializeNonLocal :
# 30| r30_1(glval<ClassWithDestructor2 &>) = VariableAddress[rs] :
# 30| r30_2(glval<ClassWithDestructor2>) = VariableAddress[#temp30:38] :
# 30| r30_3(glval<unknown>) = FunctionAddress[returnValue] :
# 30| r30_4(ClassWithDestructor2) = Call[returnValue] : func:r30_3
# 30| mu30_5(unknown) = ^CallSideEffect : ~m?
# 30| mu30_6(ClassWithDestructor2) = Store[#temp30:38] : &:r30_2, r30_4
# 30| r30_7(glval<ClassWithDestructor2>) = Convert : r30_2
# 30| r30_8(ClassWithDestructor2 &) = CopyValue : r30_7
# 30| mu30_9(ClassWithDestructor2 &) = Store[rs] : &:r30_1, r30_8
# 31| v31_1(void) = NoOp :
# 31| r31_2(glval<ClassWithDestructor2>) = CopyValue : r30_2
# 31| r31_3(glval<unknown>) = FunctionAddress[~ClassWithDestructor2] :
# 31| v31_4(void) = Call[~ClassWithDestructor2] : func:r31_3, this:r31_2
# 31| mu31_5(unknown) = ^CallSideEffect : ~m?
# 31| v31_6(void) = ^IndirectReadSideEffect[-1] : &:r31_2, ~m?
# 31| mu31_7(ClassWithDestructor2) = ^IndirectMayWriteSideEffect[-1] : &:r31_2
# 29| v29_4(void) = ReturnVoid :
# 29| v29_5(void) = AliasedUse : ~m?
# 29| v29_6(void) = ExitFunction :
# 33| void temp_test4()
# 33| Block 0
@@ -887,12 +893,18 @@ destructors_for_temps.cpp:
# 35| r35_8(ClassWithDestructor2 &) = CopyValue : r35_7
# 35| mu35_9(ClassWithDestructor2 &) = Store[rs2] : &:r35_1, r35_8
# 36| v36_1(void) = NoOp :
# 36| r36_2(glval<ClassWithDestructor2>) = VariableAddress[c] :
# 36| r36_2(glval<ClassWithDestructor2>) = CopyValue : r35_2
# 36| r36_3(glval<unknown>) = FunctionAddress[~ClassWithDestructor2] :
# 36| v36_4(void) = Call[~ClassWithDestructor2] : func:r36_3, this:r36_2
# 36| mu36_5(unknown) = ^CallSideEffect : ~m?
# 36| v36_6(void) = ^IndirectReadSideEffect[-1] : &:r36_2, ~m?
# 36| mu36_7(ClassWithDestructor2) = ^IndirectMayWriteSideEffect[-1] : &:r36_2
# 36| r36_8(glval<ClassWithDestructor2>) = VariableAddress[c] :
# 36| r36_9(glval<unknown>) = FunctionAddress[~ClassWithDestructor2] :
# 36| v36_10(void) = Call[~ClassWithDestructor2] : func:r36_9, this:r36_8
# 36| mu36_11(unknown) = ^CallSideEffect : ~m?
# 36| v36_12(void) = ^IndirectReadSideEffect[-1] : &:r36_8, ~m?
# 36| mu36_13(ClassWithDestructor2) = ^IndirectMayWriteSideEffect[-1] : &:r36_8
# 33| v33_4(void) = ReturnVoid :
# 33| v33_5(void) = AliasedUse : ~m?
# 33| v33_6(void) = ExitFunction :
@@ -8321,12 +8333,18 @@ ir.cpp:
# 1425| mu1425_4(unknown) = ^CallSideEffect : ~m?
# 1425| mu1425_5(String) = Store[#temp1425:5] : &:r1425_1, r1425_3
# 1426| v1426_1(void) = NoOp :
# 1426| r1426_2(glval<String>) = VariableAddress[s] :
# 1426| r1426_2(glval<String>) = CopyValue : r1416_2
# 1426| r1426_3(glval<unknown>) = FunctionAddress[~String] :
# 1426| v1426_4(void) = Call[~String] : func:r1426_3, this:r1426_2
# 1426| mu1426_5(unknown) = ^CallSideEffect : ~m?
# 1426| v1426_6(void) = ^IndirectReadSideEffect[-1] : &:r1426_2, ~m?
# 1426| mu1426_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r1426_2
# 1426| r1426_8(glval<String>) = VariableAddress[s] :
# 1426| r1426_9(glval<unknown>) = FunctionAddress[~String] :
# 1426| v1426_10(void) = Call[~String] : func:r1426_9, this:r1426_8
# 1426| mu1426_11(unknown) = ^CallSideEffect : ~m?
# 1426| v1426_12(void) = ^IndirectReadSideEffect[-1] : &:r1426_8, ~m?
# 1426| mu1426_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r1426_8
# 1414| v1414_4(void) = ReturnVoid :
# 1414| v1414_5(void) = AliasedUse : ~m?
# 1414| v1414_6(void) = ExitFunction :
@@ -8397,12 +8415,18 @@ ir.cpp:
# 1438| mu1438_5(unknown) = ^CallSideEffect : ~m?
# 1438| v1438_6(void) = ^IndirectReadSideEffect[-1] : &:r1438_2, ~m?
# 1438| mu1438_7(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1438_2
# 1438| r1438_8(glval<destructor_only>) = VariableAddress[d] :
# 1438| r1438_8(glval<destructor_only>) = CopyValue : r1430_2
# 1438| r1438_9(glval<unknown>) = FunctionAddress[~destructor_only] :
# 1438| v1438_10(void) = Call[~destructor_only] : func:r1438_9, this:r1438_8
# 1438| mu1438_11(unknown) = ^CallSideEffect : ~m?
# 1438| v1438_12(void) = ^IndirectReadSideEffect[-1] : &:r1438_8, ~m?
# 1438| mu1438_13(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1438_8
# 1438| r1438_14(glval<destructor_only>) = VariableAddress[d] :
# 1438| r1438_15(glval<unknown>) = FunctionAddress[~destructor_only] :
# 1438| v1438_16(void) = Call[~destructor_only] : func:r1438_15, this:r1438_14
# 1438| mu1438_17(unknown) = ^CallSideEffect : ~m?
# 1438| v1438_18(void) = ^IndirectReadSideEffect[-1] : &:r1438_14, ~m?
# 1438| mu1438_19(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1438_14
# 1428| v1428_4(void) = ReturnVoid :
# 1428| v1428_5(void) = AliasedUse : ~m?
# 1428| v1428_6(void) = ExitFunction :