Skip to content

Commit 0335a4f

Browse files
authored
Merge pull request #15735 from MathiasVP/ir-for-vacuous-destructor-calls
C++: IR construction for `VacuousDestructorCall`s
2 parents 7c7c10e + bba152d commit 0335a4f

File tree

9 files changed

+3530
-2865
lines changed

9 files changed

+3530
-2865
lines changed

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2359,6 +2359,47 @@ class TranslatedDestructorFieldDestruction extends TranslatedNonConstantExpr, St
23592359
private TranslatedExpr getDestructorCall() { result = getTranslatedExpr(expr.getExpr()) }
23602360
}
23612361

2362+
/**
2363+
* The IR translation of a vacuous destructor call. That is, an expression that
2364+
* looks like a destructor call, but has no effect.
2365+
*
2366+
* Note that, even though there's no destructor call, we should still evaluate
2367+
* the qualifier.
2368+
*/
2369+
class TranslatedVacuousDestructorCall extends TranslatedNonConstantExpr {
2370+
override VacuousDestructorCall expr;
2371+
2372+
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
2373+
2374+
final TranslatedExpr getQualifier() {
2375+
result = getTranslatedExpr(expr.getQualifier().getFullyConverted())
2376+
}
2377+
2378+
override Instruction getFirstInstruction(EdgeKind kind) {
2379+
result = this.getQualifier().getFirstInstruction(kind)
2380+
}
2381+
2382+
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
2383+
child = this.getQualifier() and
2384+
result = this.getParent().getChildSuccessor(this, kind)
2385+
}
2386+
2387+
override TranslatedElement getChildInternal(int id) {
2388+
id = 0 and
2389+
result = this.getQualifier()
2390+
}
2391+
2392+
override Instruction getResult() { none() }
2393+
2394+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
2395+
none()
2396+
}
2397+
2398+
override Instruction getALastInstructionInternal() {
2399+
result = this.getQualifier().getALastInstruction()
2400+
}
2401+
}
2402+
23622403
/**
23632404
* The IR translation of the `?:` operator. This class has the portions of the implementation that
23642405
* are shared between the standard three-operand form (`a ? b : c`) and the GCC-extension

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

Lines changed: 844 additions & 683 deletions
Large diffs are not rendered by default.

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

Lines changed: 944 additions & 779 deletions
Large diffs are not rendered by default.

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,6 +2189,26 @@ void static_variable_with_destructor_3() {
21892189

21902190
static ClassWithDestructor global_class_with_destructor;
21912191

2192+
namespace vacuous_destructor_call {
2193+
template<typename T>
2194+
T& get(T& t) { return t; }
2195+
2196+
template<typename T>
2197+
void call_destructor(T& t) {
2198+
get(t).~T();
2199+
}
2200+
2201+
void non_vacuous_destructor_call() {
2202+
ClassWithDestructor c;
2203+
call_destructor(c);
2204+
}
2205+
2206+
void vacuous_destructor_call() {
2207+
int i;
2208+
call_destructor(i);
2209+
}
2210+
}
2211+
21922212
void TryCatchDestructors(bool b) {
21932213
try {
21942214
String s;

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

Lines changed: 897 additions & 758 deletions
Large diffs are not rendered by default.

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

Lines changed: 784 additions & 639 deletions
Large diffs are not rendered by default.

cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_consistency.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ missingOperandType
77
duplicateChiOperand
88
sideEffectWithoutPrimary
99
instructionWithoutSuccessor
10-
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
1110
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
1211
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
1312
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |

cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ missingOperandType
88
duplicateChiOperand
99
sideEffectWithoutPrimary
1010
instructionWithoutSuccessor
11-
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
12-
| VacuousDestructorCall.cpp:3:3:3:3 | VariableAddress: x | Instruction 'VariableAddress: x' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
13-
| VacuousDestructorCall.cpp:4:3:4:3 | Load: y | Instruction 'Load: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
1411
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
1512
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
1613
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
@@ -33,7 +30,6 @@ multipleIRTypes
3330
lostReachability
3431
backEdgeCountMismatch
3532
useNotDominatedByDefinition
36-
| VacuousDestructorCall.cpp:2:29:2:29 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
3733
| ms_try_except.cpp:9:19:9:19 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |
3834
| ms_try_except.cpp:9:19:9:19 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |
3935
| ms_try_except.cpp:19:17:19:21 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) |

cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_consistency.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ missingOperandType
77
duplicateChiOperand
88
sideEffectWithoutPrimary
99
instructionWithoutSuccessor
10-
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
1110
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
1211
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
1312
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |

0 commit comments

Comments
 (0)