Skip to content

Commit 3d4f7d8

Browse files
committed
C++: unsuppress destructoion of temporaries with extended lifetimes
1 parent ba10ea8 commit 3d4f7d8

File tree

5 files changed

+156
-75
lines changed

5 files changed

+156
-75
lines changed

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,6 @@ private predicate ignoreExprAndDescendants(Expr expr) {
9999
or
100100
// suppress destructors of temporary variables until proper support is added for them.
101101
exists(Expr parent | parent.getAnImplicitDestructorCall() = expr)
102-
or
103-
exists(Stmt parent |
104-
parent.getAnImplicitDestructorCall() = expr and
105-
expr.(DestructorCall).getQualifier() instanceof ReuseExpr
106-
)
107102
}
108103

109104
/**

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -248,19 +248,9 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
248248
final override TranslatedElement getChild(int id) {
249249
result = this.getChildInternal(id)
250250
or
251-
exists(int destructorIndex, int tempDestructorCount |
251+
exists(int destructorIndex |
252252
result.(TranslatedExpr).getExpr() = stmt.getImplicitDestructorCall(destructorIndex) and
253-
id = this.getFirstDestructorCallIndex() + destructorIndex - tempDestructorCount and
254-
// suppress destructors of temporary variables until proper support is added for them.
255-
tempDestructorCount =
256-
count(DestructorCall call, int tempIndex |
257-
stmt.getImplicitDestructorCall(tempIndex) = call and
258-
tempIndex < destructorIndex and
259-
call.getQualifier() instanceof ReuseExpr
260-
|
261-
call
262-
) and
263-
not stmt.getImplicitDestructorCall(destructorIndex).getQualifier() instanceof ReuseExpr
253+
id = this.getFirstDestructorCallIndex() + destructorIndex
264254
)
265255
}
266256

@@ -271,11 +261,7 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
271261
}
272262

273263
final override predicate hasAnImplicitDestructorCall() {
274-
exists(stmt.getAnImplicitDestructorCall()) and
275-
// suppress destructors of temporary variables until proper support is added for them.
276-
exists(Expr expr | stmt.getAnImplicitDestructorCall().getQualifier() = expr |
277-
not expr instanceof ReuseExpr
278-
)
264+
exists(stmt.getAnImplicitDestructorCall())
279265
}
280266

281267
final override string toString() { result = stmt.toString() }

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

Lines changed: 62 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -891,24 +891,32 @@ destructors_for_temps.cpp:
891891

892892
# 29| void temp_test3()
893893
# 29| Block 0
894-
# 29| v29_1(void) = EnterFunction :
895-
# 29| m29_2(unknown) = AliasedDefinition :
896-
# 29| m29_3(unknown) = InitializeNonLocal :
897-
# 29| m29_4(unknown) = Chi : total:m29_2, partial:m29_3
898-
# 30| r30_1(glval<ClassWithDestructor2 &>) = VariableAddress[rs] :
899-
# 30| r30_2(glval<ClassWithDestructor2>) = VariableAddress[#temp30:38] :
900-
# 30| r30_3(glval<unknown>) = FunctionAddress[returnValue] :
901-
# 30| r30_4(ClassWithDestructor2) = Call[returnValue] : func:r30_3
902-
# 30| m30_5(unknown) = ^CallSideEffect : ~m29_4
903-
# 30| m30_6(unknown) = Chi : total:m29_4, partial:m30_5
904-
# 30| m30_7(ClassWithDestructor2) = Store[#temp30:38] : &:r30_2, r30_4
905-
# 30| r30_8(glval<ClassWithDestructor2>) = Convert : r30_2
906-
# 30| r30_9(ClassWithDestructor2 &) = CopyValue : r30_8
907-
# 30| m30_10(ClassWithDestructor2 &) = Store[rs] : &:r30_1, r30_9
908-
# 31| v31_1(void) = NoOp :
909-
# 29| v29_5(void) = ReturnVoid :
910-
# 29| v29_6(void) = AliasedUse : ~m30_6
911-
# 29| v29_7(void) = ExitFunction :
894+
# 29| v29_1(void) = EnterFunction :
895+
# 29| m29_2(unknown) = AliasedDefinition :
896+
# 29| m29_3(unknown) = InitializeNonLocal :
897+
# 29| m29_4(unknown) = Chi : total:m29_2, partial:m29_3
898+
# 30| r30_1(glval<ClassWithDestructor2 &>) = VariableAddress[rs] :
899+
# 30| r30_2(glval<ClassWithDestructor2>) = VariableAddress[#temp30:38] :
900+
# 30| r30_3(glval<unknown>) = FunctionAddress[returnValue] :
901+
# 30| r30_4(ClassWithDestructor2) = Call[returnValue] : func:r30_3
902+
# 30| m30_5(unknown) = ^CallSideEffect : ~m29_4
903+
# 30| m30_6(unknown) = Chi : total:m29_4, partial:m30_5
904+
# 30| m30_7(ClassWithDestructor2) = Store[#temp30:38] : &:r30_2, r30_4
905+
# 30| r30_8(glval<ClassWithDestructor2>) = Convert : r30_2
906+
# 30| r30_9(ClassWithDestructor2 &) = CopyValue : r30_8
907+
# 30| m30_10(ClassWithDestructor2 &) = Store[rs] : &:r30_1, r30_9
908+
# 31| v31_1(void) = NoOp :
909+
# 31| r31_2(glval<ClassWithDestructor2>) = CopyValue : r30_2
910+
# 31| r31_3(glval<unknown>) = FunctionAddress[~ClassWithDestructor2] :
911+
# 31| v31_4(void) = Call[~ClassWithDestructor2] : func:r31_3, this:r31_2
912+
# 31| m31_5(unknown) = ^CallSideEffect : ~m30_6
913+
# 31| m31_6(unknown) = Chi : total:m30_6, partial:m31_5
914+
# 31| v31_7(void) = ^IndirectReadSideEffect[-1] : &:r31_2, m30_7
915+
# 31| m31_8(ClassWithDestructor2) = ^IndirectMayWriteSideEffect[-1] : &:r31_2
916+
# 31| m31_9(ClassWithDestructor2) = Chi : total:m30_7, partial:m31_8
917+
# 29| v29_5(void) = ReturnVoid :
918+
# 29| v29_6(void) = AliasedUse : ~m31_6
919+
# 29| v29_7(void) = ExitFunction :
912920

913921
# 33| void temp_test4()
914922
# 33| Block 0
@@ -935,16 +943,24 @@ destructors_for_temps.cpp:
935943
# 35| r35_9(ClassWithDestructor2 &) = CopyValue : r35_8
936944
# 35| m35_10(ClassWithDestructor2 &) = Store[rs2] : &:r35_1, r35_9
937945
# 36| v36_1(void) = NoOp :
938-
# 36| r36_2(glval<ClassWithDestructor2>) = VariableAddress[c] :
946+
# 36| r36_2(glval<ClassWithDestructor2>) = CopyValue : r35_2
939947
# 36| r36_3(glval<unknown>) = FunctionAddress[~ClassWithDestructor2] :
940948
# 36| v36_4(void) = Call[~ClassWithDestructor2] : func:r36_3, this:r36_2
941949
# 36| m36_5(unknown) = ^CallSideEffect : ~m35_6
942950
# 36| m36_6(unknown) = Chi : total:m35_6, partial:m36_5
943-
# 36| v36_7(void) = ^IndirectReadSideEffect[-1] : &:r36_2, m34_8
951+
# 36| v36_7(void) = ^IndirectReadSideEffect[-1] : &:r36_2, m35_7
944952
# 36| m36_8(ClassWithDestructor2) = ^IndirectMayWriteSideEffect[-1] : &:r36_2
945-
# 36| m36_9(ClassWithDestructor2) = Chi : total:m34_8, partial:m36_8
953+
# 36| m36_9(ClassWithDestructor2) = Chi : total:m35_7, partial:m36_8
954+
# 36| r36_10(glval<ClassWithDestructor2>) = VariableAddress[c] :
955+
# 36| r36_11(glval<unknown>) = FunctionAddress[~ClassWithDestructor2] :
956+
# 36| v36_12(void) = Call[~ClassWithDestructor2] : func:r36_11, this:r36_10
957+
# 36| m36_13(unknown) = ^CallSideEffect : ~m36_6
958+
# 36| m36_14(unknown) = Chi : total:m36_6, partial:m36_13
959+
# 36| v36_15(void) = ^IndirectReadSideEffect[-1] : &:r36_10, m34_8
960+
# 36| m36_16(ClassWithDestructor2) = ^IndirectMayWriteSideEffect[-1] : &:r36_10
961+
# 36| m36_17(ClassWithDestructor2) = Chi : total:m34_8, partial:m36_16
946962
# 33| v33_5(void) = ReturnVoid :
947-
# 33| v33_6(void) = AliasedUse : ~m36_6
963+
# 33| v33_6(void) = AliasedUse : ~m36_14
948964
# 33| v33_7(void) = ExitFunction :
949965

950966
# 38| void temp_test5(bool)
@@ -8882,16 +8898,24 @@ ir.cpp:
88828898
# 1425| m1425_5(unknown) = Chi : total:m1423_11, partial:m1425_4
88838899
# 1425| m1425_6(String) = Store[#temp1425:5] : &:r1425_1, r1425_3
88848900
# 1426| v1426_1(void) = NoOp :
8885-
# 1426| r1426_2(glval<String>) = VariableAddress[s] :
8901+
# 1426| r1426_2(glval<String>) = CopyValue : r1416_2
88868902
# 1426| r1426_3(glval<unknown>) = FunctionAddress[~String] :
88878903
# 1426| v1426_4(void) = Call[~String] : func:r1426_3, this:r1426_2
88888904
# 1426| m1426_5(unknown) = ^CallSideEffect : ~m1425_5
88898905
# 1426| m1426_6(unknown) = Chi : total:m1425_5, partial:m1426_5
8890-
# 1426| v1426_7(void) = ^IndirectReadSideEffect[-1] : &:r1426_2, m1415_6
8906+
# 1426| v1426_7(void) = ^IndirectReadSideEffect[-1] : &:r1426_2, m1416_7
88918907
# 1426| m1426_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r1426_2
8892-
# 1426| m1426_9(String) = Chi : total:m1415_6, partial:m1426_8
8908+
# 1426| m1426_9(String) = Chi : total:m1416_7, partial:m1426_8
8909+
# 1426| r1426_10(glval<String>) = VariableAddress[s] :
8910+
# 1426| r1426_11(glval<unknown>) = FunctionAddress[~String] :
8911+
# 1426| v1426_12(void) = Call[~String] : func:r1426_11, this:r1426_10
8912+
# 1426| m1426_13(unknown) = ^CallSideEffect : ~m1426_6
8913+
# 1426| m1426_14(unknown) = Chi : total:m1426_6, partial:m1426_13
8914+
# 1426| v1426_15(void) = ^IndirectReadSideEffect[-1] : &:r1426_10, m1415_6
8915+
# 1426| m1426_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r1426_10
8916+
# 1426| m1426_17(String) = Chi : total:m1415_6, partial:m1426_16
88938917
# 1414| v1414_5(void) = ReturnVoid :
8894-
# 1414| v1414_6(void) = AliasedUse : ~m1426_6
8918+
# 1414| v1414_6(void) = AliasedUse : ~m1426_14
88958919
# 1414| v1414_7(void) = ExitFunction :
88968920

88978921
# 1428| void temporary_destructor_only()
@@ -8973,16 +8997,24 @@ ir.cpp:
89738997
# 1438| v1438_7(void) = ^IndirectReadSideEffect[-1] : &:r1438_2, m1431_2
89748998
# 1438| m1438_8(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1438_2
89758999
# 1438| m1438_9(destructor_only) = Chi : total:m1431_2, partial:m1438_8
8976-
# 1438| r1438_10(glval<destructor_only>) = VariableAddress[d] :
9000+
# 1438| r1438_10(glval<destructor_only>) = CopyValue : r1430_2
89779001
# 1438| r1438_11(glval<unknown>) = FunctionAddress[~destructor_only] :
89789002
# 1438| v1438_12(void) = Call[~destructor_only] : func:r1438_11, this:r1438_10
89799003
# 1438| m1438_13(unknown) = ^CallSideEffect : ~m1438_6
89809004
# 1438| m1438_14(unknown) = Chi : total:m1438_6, partial:m1438_13
8981-
# 1438| v1438_15(void) = ^IndirectReadSideEffect[-1] : &:r1438_10, m1429_6
9005+
# 1438| v1438_15(void) = ^IndirectReadSideEffect[-1] : &:r1438_10, m1430_7
89829006
# 1438| m1438_16(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1438_10
8983-
# 1438| m1438_17(destructor_only) = Chi : total:m1429_6, partial:m1438_16
9007+
# 1438| m1438_17(destructor_only) = Chi : total:m1430_7, partial:m1438_16
9008+
# 1438| r1438_18(glval<destructor_only>) = VariableAddress[d] :
9009+
# 1438| r1438_19(glval<unknown>) = FunctionAddress[~destructor_only] :
9010+
# 1438| v1438_20(void) = Call[~destructor_only] : func:r1438_19, this:r1438_18
9011+
# 1438| m1438_21(unknown) = ^CallSideEffect : ~m1438_14
9012+
# 1438| m1438_22(unknown) = Chi : total:m1438_14, partial:m1438_21
9013+
# 1438| v1438_23(void) = ^IndirectReadSideEffect[-1] : &:r1438_18, m1429_6
9014+
# 1438| m1438_24(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1438_18
9015+
# 1438| m1438_25(destructor_only) = Chi : total:m1429_6, partial:m1438_24
89849016
# 1428| v1428_5(void) = ReturnVoid :
8985-
# 1428| v1428_6(void) = AliasedUse : ~m1438_14
9017+
# 1428| v1428_6(void) = AliasedUse : ~m1438_22
89869018
# 1428| v1428_7(void) = ExitFunction :
89879019

89889020
# 1440| void temporary_copy_constructor()

0 commit comments

Comments
 (0)