diff --git a/cpp/ql/lib/change-notes/2024-03-19-ir-temp-extended-destructors.md b/cpp/ql/lib/change-notes/2024-03-19-ir-temp-extended-destructors.md new file mode 100644 index 00000000000..6def8303336 --- /dev/null +++ b/cpp/ql/lib/change-notes/2024-03-19-ir-temp-extended-destructors.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added destructors for temporary objects with extended lifetimes to the intermediate representation. \ No newline at end of file diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 51e3311a9a2..134b7802fc8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -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 - ) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 51111c24572..8684f4e5606 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -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. */ diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll index 247b15ed4c4..d8ec66a2ee7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll @@ -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() } diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index e80688b355a..a1e49dce3b1 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -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) = VariableAddress[rs] : -# 30| r30_2(glval) = VariableAddress[#temp30:38] : -# 30| r30_3(glval) = 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) = 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) = VariableAddress[rs] : +# 30| r30_2(glval) = VariableAddress[#temp30:38] : +# 30| r30_3(glval) = 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) = 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) = CopyValue : r30_2 +# 31| r31_3(glval) = 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) = VariableAddress[c] : +# 36| r36_2(glval) = CopyValue : r35_2 # 36| r36_3(glval) = 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) = VariableAddress[c] : +# 36| r36_11(glval) = 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) = VariableAddress[s] : +# 1426| r1426_2(glval) = CopyValue : r1416_2 # 1426| r1426_3(glval) = 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) = VariableAddress[s] : +# 1426| r1426_11(glval) = 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) = VariableAddress[d] : +# 1438| r1438_10(glval) = CopyValue : r1430_2 # 1438| r1438_11(glval) = 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) = VariableAddress[d] : +# 1438| r1438_19(glval) = 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() diff --git a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected index 912d2984956..eaf35e9029a 100644 --- a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected +++ b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected @@ -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 | diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 7698e996e12..595eeb47460 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -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) = VariableAddress[rs] : -# 30| r30_2(glval) = VariableAddress[#temp30:38] : -# 30| r30_3(glval) = 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) = 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) = VariableAddress[rs] : +# 30| r30_2(glval) = VariableAddress[#temp30:38] : +# 30| r30_3(glval) = 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) = 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) = CopyValue : r30_2 +# 31| r31_3(glval) = 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) = VariableAddress[c] : +# 36| r36_2(glval) = CopyValue : r35_2 # 36| r36_3(glval) = 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) = VariableAddress[c] : +# 36| r36_9(glval) = 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) = VariableAddress[s] : +# 1426| r1426_2(glval) = CopyValue : r1416_2 # 1426| r1426_3(glval) = 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) = VariableAddress[s] : +# 1426| r1426_9(glval) = 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) = VariableAddress[d] : +# 1438| r1438_8(glval) = CopyValue : r1430_2 # 1438| r1438_9(glval) = 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) = VariableAddress[d] : +# 1438| r1438_15(glval) = 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 :