Skip to content

Commit a200ced

Browse files
committed
C++: Fix IR generation for jump statements.
1 parent c5a87c9 commit a200ced

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

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

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,11 @@ class TranslatedJumpStmt extends TranslatedStmt {
12761276
override JumpStmt stmt;
12771277

12781278
override Instruction getFirstInstruction(EdgeKind kind) {
1279+
// The first instruction is a destructor call, if any.
1280+
result = this.getChildInternal(0).getFirstInstruction(kind)
1281+
or
1282+
// Otherwise, the first (and only) instruction is a `NoOp`
1283+
not exists(this.getChildInternal(0)) and
12791284
result = this.getInstruction(OnlyInstructionTag()) and
12801285
kind instanceof GotoEdge
12811286
}
@@ -1284,7 +1289,20 @@ class TranslatedJumpStmt extends TranslatedStmt {
12841289
result = this.getInstruction(OnlyInstructionTag())
12851290
}
12861291

1287-
override TranslatedElement getChildInternal(int id) { none() }
1292+
private TranslatedCall getTranslatedImplicitDestructorCall(int id) {
1293+
result.getExpr() = stmt.getImplicitDestructorCall(id)
1294+
}
1295+
1296+
override TranslatedElement getLastChild() {
1297+
result =
1298+
this.getTranslatedImplicitDestructorCall(max(int id |
1299+
exists(stmt.getImplicitDestructorCall(id))
1300+
))
1301+
}
1302+
1303+
override TranslatedElement getChildInternal(int id) {
1304+
result = this.getTranslatedImplicitDestructorCall(id)
1305+
}
12881306

12891307
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
12901308
tag = OnlyInstructionTag() and
@@ -1297,7 +1315,19 @@ class TranslatedJumpStmt extends TranslatedStmt {
12971315
result = getTranslatedStmt(stmt.getTarget()).getFirstInstruction(kind)
12981316
}
12991317

1300-
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
1318+
final override predicate handlesDestructorsExplicitly() { any() }
1319+
1320+
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
1321+
exists(int id | child = this.getChildInternal(id) |
1322+
// Transition to the next destructor call, if any.
1323+
result = this.getChildInternal(id + 1).getFirstInstruction(kind)
1324+
or
1325+
// And otherwise, exit this element by flowing to the target of the jump.
1326+
not exists(this.getChildInternal(id + 1)) and
1327+
kind instanceof GotoEdge and
1328+
result = this.getInstruction(OnlyInstructionTag())
1329+
)
1330+
}
13011331
}
13021332

13031333
private EdgeKind getCaseEdge(SwitchCase switchCase) {

0 commit comments

Comments
 (0)