Skip to content

Commit f7b2de8

Browse files
authored
Merge pull request #15506 from rdmarsh2/rdmarsh2/cpp/ir-synthetic-destructors
C++: Add implicit destructors for named variables to the IR
2 parents 3ab6f22 + a513598 commit f7b2de8

23 files changed

+6020
-992
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added destructors for named objects to the intermediate representation.

cpp/ql/lib/semmle/code/cpp/Enclosing.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,6 @@ Element exprEnclosingElement(Expr e) {
6060
)
6161
else result = de.getDeclaration()
6262
)
63+
or
64+
result.(Stmt).getAnImplicitDestructorCall() = e
6365
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ private import InstructionTag
1111
private import TranslatedCondition
1212
private import TranslatedElement
1313
private import TranslatedExpr
14+
private import TranslatedCall
1415
private import TranslatedStmt
1516
private import TranslatedFunction
1617
private import TranslatedGlobalVar

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,14 @@ newtype TInstructionTag =
8585
// The next three cases handle generation of branching for __except handling.
8686
TryExceptCompareNegativeOneBranch() or
8787
TryExceptCompareZeroBranch() or
88-
TryExceptCompareOneBranch()
88+
TryExceptCompareOneBranch() or
89+
ImplicitDestructorTag(int index) {
90+
exists(Expr e | exists(e.getImplicitDestructorCall(index))) or
91+
exists(Stmt s | exists(s.getImplicitDestructorCall(index)))
92+
}
8993

9094
class InstructionTag extends TInstructionTag {
91-
final string toString() { result = "Tag" }
95+
final string toString() { result = getInstructionTagId(this) }
9296
}
9397

9498
/**
@@ -255,4 +259,8 @@ string getInstructionTagId(TInstructionTag tag) {
255259
tag = TryExceptCompareZeroBranch() and result = "TryExceptCompareZeroBranch"
256260
or
257261
tag = TryExceptCompareOneBranch() and result = "TryExceptCompareOneBranch"
262+
or
263+
exists(int index |
264+
tag = ImplicitDestructorTag(index) and result = "ImplicitDestructor(" + index + ")"
265+
)
258266
}

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

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ private CallInstruction getTranslatedCallInstruction(Call call) {
2727
* of a higher-level constructor (e.g. the allocator call in a `NewExpr`).
2828
*/
2929
abstract class TranslatedCall extends TranslatedExpr {
30-
final override TranslatedElement getChild(int id) {
30+
final override TranslatedElement getChildInternal(int id) {
3131
// We choose the child's id in the order of evaluation.
3232
// The qualifier is evaluated before the call target, because the value of
3333
// the call target may depend on the value of the qualifier for virtual
@@ -47,13 +47,19 @@ abstract class TranslatedCall extends TranslatedExpr {
4747
else result = this.getFirstCallTargetInstruction(kind)
4848
}
4949

50+
override Instruction getALastInstructionInternal() {
51+
result = this.getSideEffects().getALastInstruction()
52+
}
53+
54+
override TranslatedElement getLastChild() { result = this.getSideEffects() }
55+
5056
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
5157
tag = CallTag() and
5258
opcode instanceof Opcode::Call and
5359
resultType = getTypeForPRValue(this.getCallResultType())
5460
}
5561

56-
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
62+
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
5763
child = this.getQualifier() and
5864
result = this.getFirstCallTargetInstruction(kind)
5965
or
@@ -87,7 +93,7 @@ abstract class TranslatedCall extends TranslatedExpr {
8793
)
8894
}
8995

90-
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
96+
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
9197
tag = CallTag() and
9298
result = this.getSideEffects().getFirstInstruction(kind)
9399
}
@@ -225,7 +231,7 @@ abstract class TranslatedSideEffects extends TranslatedElement {
225231
)
226232
}
227233

228-
final override Instruction getChildSuccessor(TranslatedElement te, EdgeKind kind) {
234+
final override Instruction getChildSuccessorInternal(TranslatedElement te, EdgeKind kind) {
229235
exists(int i |
230236
this.getChild(i) = te and
231237
if exists(this.getChild(i + 1))
@@ -234,6 +240,10 @@ abstract class TranslatedSideEffects extends TranslatedElement {
234240
)
235241
}
236242

243+
override TranslatedElement getLastChild() {
244+
result = this.getChild(max(int i | exists(this.getChild(i))))
245+
}
246+
237247
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
238248
none()
239249
}
@@ -246,7 +256,18 @@ abstract class TranslatedSideEffects extends TranslatedElement {
246256
result = this.getParent().getChildSuccessor(this, kind)
247257
}
248258

249-
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
259+
override Instruction getALastInstructionInternal() {
260+
if exists(this.getAChild())
261+
then result = this.getChild(max(int i | exists(this.getChild(i)))).getALastInstruction()
262+
else
263+
// If there are no side effects, the "last" instruction should be the parent call's last
264+
// instruction, so that implicit destructors can be inserted in the right place.
265+
result = this.getParent().getInstruction(CallTag())
266+
}
267+
268+
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
269+
none()
270+
}
250271

251272
/** Gets the primary instruction to be associated with each side effect instruction. */
252273
abstract Instruction getPrimaryInstruction();
@@ -273,8 +294,8 @@ abstract class TranslatedDirectCall extends TranslatedCall {
273294
resultType = getFunctionGLValueType()
274295
}
275296

276-
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
277-
result = TranslatedCall.super.getInstructionSuccessor(tag, kind)
297+
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
298+
result = TranslatedCall.super.getInstructionSuccessorInternal(tag, kind)
278299
or
279300
tag = CallTargetTag() and
280301
result = this.getFirstArgumentOrCallInstruction(kind)
@@ -367,6 +388,16 @@ class TranslatedStructorCall extends TranslatedFunctionCall {
367388
context = this.getParent() and
368389
result = context.getReceiver()
369390
)
391+
or
392+
exists(Stmt parent |
393+
expr = parent.getAnImplicitDestructorCall() and
394+
result = getTranslatedExpr(expr.getQualifier().getFullyConverted()).getResult()
395+
)
396+
or
397+
exists(Expr parent |
398+
expr = parent.getAnImplicitDestructorCall() and
399+
result = getTranslatedExpr(expr.getQualifier().getFullyConverted()).getResult()
400+
)
370401
}
371402

372403
override predicate hasQualifier() { any() }
@@ -416,19 +447,25 @@ private int initializeAllocationGroup() { result = 3 }
416447
abstract class TranslatedSideEffect extends TranslatedElement {
417448
final override TranslatedElement getChild(int n) { none() }
418449

419-
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
450+
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
451+
none()
452+
}
420453

421454
final override Instruction getFirstInstruction(EdgeKind kind) {
422455
result = this.getInstruction(OnlyInstructionTag()) and
423456
kind instanceof GotoEdge
424457
}
425458

459+
override Instruction getALastInstructionInternal() {
460+
result = this.getInstruction(OnlyInstructionTag())
461+
}
462+
426463
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
427464
tag = OnlyInstructionTag() and
428465
this.sideEffectInstruction(opcode, type)
429466
}
430467

431-
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
468+
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
432469
result = this.getParent().getChildSuccessor(this, kind) and
433470
tag = OnlyInstructionTag()
434471
}

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

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,29 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
5050
{
5151
TranslatedFlexibleCondition() { this = TTranslatedFlexibleCondition(expr) }
5252

53+
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
54+
5355
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
5456

5557
final override Instruction getFirstInstruction(EdgeKind kind) {
5658
result = this.getOperand().getFirstInstruction(kind)
5759
}
5860

61+
final override Instruction getALastInstructionInternal() {
62+
result = this.getOperand().getALastInstruction()
63+
}
64+
5965
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
6066
none()
6167
}
6268

63-
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
69+
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
70+
none()
71+
}
6472

65-
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
73+
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
74+
none()
75+
}
6676

6777
abstract TranslatedCondition getOperand();
6878
}
@@ -88,12 +98,16 @@ class TranslatedParenthesisCondition extends TranslatedFlexibleCondition {
8898
abstract class TranslatedNativeCondition extends TranslatedCondition, TTranslatedNativeCondition {
8999
TranslatedNativeCondition() { this = TTranslatedNativeCondition(expr) }
90100

91-
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
101+
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
102+
none()
103+
}
92104
}
93105

94106
abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeCondition, ConditionContext {
95107
override BinaryLogicalOperation expr;
96108

109+
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
110+
97111
final override TranslatedElement getChild(int id) {
98112
id = 0 and result = this.getLeftOperand()
99113
or
@@ -104,11 +118,19 @@ abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeConditio
104118
result = this.getLeftOperand().getFirstInstruction(kind)
105119
}
106120

121+
final override Instruction getALastInstructionInternal() {
122+
result = this.getLeftOperand().getALastInstruction()
123+
or
124+
result = this.getRightOperand().getALastInstruction()
125+
}
126+
107127
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
108128
none()
109129
}
110130

111-
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
131+
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
132+
none()
133+
}
112134

113135
final TranslatedCondition getLeftOperand() {
114136
result = getTranslatedCondition(expr.getLeftOperand().getFullyConverted())
@@ -162,19 +184,25 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
162184
result = this.getValueExpr().getFirstInstruction(kind)
163185
}
164186

187+
override Instruction getALastInstructionInternal() {
188+
result = this.getInstruction(ValueConditionConditionalBranchTag())
189+
}
190+
191+
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
192+
165193
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
166194
tag = ValueConditionConditionalBranchTag() and
167195
opcode instanceof Opcode::ConditionalBranch and
168196
resultType = getVoidType()
169197
}
170198

171-
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
199+
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
172200
child = this.getValueExpr() and
173201
result = this.getInstruction(ValueConditionConditionalBranchTag()) and
174202
kind instanceof GotoEdge
175203
}
176204

177-
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
205+
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
178206
tag = ValueConditionConditionalBranchTag() and
179207
(
180208
kind instanceof TrueEdge and

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ abstract class TranslatedLocalVariableDeclaration extends TranslatedVariableInit
6060
*/
6161
abstract LocalVariable getVariable();
6262

63+
final override TranslatedElement getChild(int id) {
64+
result = TranslatedVariableInitialization.super.getChildInternal(id)
65+
}
66+
6367
final override Type getTargetType() { result = getVariableType(this.getVariable()) }
6468

6569
final override TranslatedInitialization getInitialization() {
@@ -152,7 +156,13 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
152156
kind instanceof GotoEdge
153157
}
154158

155-
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
159+
final override Instruction getALastInstructionInternal() {
160+
result = this.getInstruction(DynamicInitializationConditionalBranchTag())
161+
or
162+
result = this.getInstruction(DynamicInitializationFlagStoreTag())
163+
}
164+
165+
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
156166
tag = DynamicInitializationFlagAddressTag() and
157167
kind instanceof GotoEdge and
158168
result = this.getInstruction(DynamicInitializationFlagLoadTag())
@@ -178,7 +188,7 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
178188
result = this.getParent().getChildSuccessor(this, kind)
179189
}
180190

181-
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
191+
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
182192
child = this.getInitialization() and
183193
result = this.getInstruction(DynamicInitializationFlagConstantTag()) and
184194
kind instanceof GotoEdge

0 commit comments

Comments
 (0)