Skip to content

Commit 0cbedfb

Browse files
authored
Merge pull request #16455 from jketema/if-fix
C++: Ensure destructors for ifs are called after both branches and for both if and constexpr if
2 parents 49aba25 + 1a53b92 commit 0cbedfb

File tree

4 files changed

+220
-226
lines changed

4 files changed

+220
-226
lines changed

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

Lines changed: 51 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -842,9 +842,7 @@ class TranslatedCatchAnyHandler extends TranslatedHandler {
842842
}
843843
}
844844

845-
class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
846-
override IfStmt stmt;
847-
845+
abstract class TranslatedIfLikeStmt extends TranslatedStmt, ConditionContext {
848846
override Instruction getFirstInstruction(EdgeKind kind) {
849847
if this.hasInitialization()
850848
then result = this.getInitialization().getFirstInstruction(kind)
@@ -857,6 +855,8 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
857855

858856
override TranslatedElement getLastChild() { result = this.getElse() or result = this.getThen() }
859857

858+
override predicate handlesDestructorsExplicitly() { any() }
859+
860860
override TranslatedElement getChildInternal(int id) {
861861
id = 0 and result = this.getInitialization()
862862
or
@@ -867,25 +867,21 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
867867
id = 3 and result = this.getElse()
868868
}
869869

870-
private predicate hasInitialization() { exists(stmt.getInitialization()) }
870+
abstract predicate hasInitialization();
871871

872-
private TranslatedStmt getInitialization() {
873-
result = getTranslatedStmt(stmt.getInitialization())
874-
}
872+
abstract TranslatedStmt getInitialization();
875873

876-
private TranslatedCondition getCondition() {
877-
result = getTranslatedCondition(stmt.getCondition().getFullyConverted())
878-
}
874+
abstract TranslatedCondition getCondition();
879875

880876
private Instruction getFirstConditionInstruction(EdgeKind kind) {
881877
result = this.getCondition().getFirstInstruction(kind)
882878
}
883879

884-
private TranslatedStmt getThen() { result = getTranslatedStmt(stmt.getThen()) }
880+
abstract TranslatedStmt getThen();
885881

886-
private TranslatedStmt getElse() { result = getTranslatedStmt(stmt.getElse()) }
882+
abstract TranslatedStmt getElse();
887883

888-
private predicate hasElse() { exists(stmt.getElse()) }
884+
abstract predicate hasElse();
889885

890886
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
891887

@@ -898,92 +894,81 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
898894
child = this.getCondition() and
899895
if this.hasElse()
900896
then result = this.getElse().getFirstInstruction(kind)
901-
else result = this.getParent().getChildSuccessor(this, kind)
897+
else (
898+
if this.hasAnImplicitDestructorCall()
899+
then result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind)
900+
else result = this.getParent().getChildSuccessor(this, kind)
901+
)
902902
}
903903

904904
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
905905
child = this.getInitialization() and
906906
result = this.getFirstConditionInstruction(kind)
907907
or
908908
(child = this.getThen() or child = this.getElse()) and
909-
result = this.getParent().getChildSuccessor(this, kind)
909+
(
910+
if this.hasAnImplicitDestructorCall()
911+
then result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind)
912+
else result = this.getParent().getChildSuccessor(this, kind)
913+
)
914+
or
915+
exists(int destructorId |
916+
destructorId >= this.getFirstDestructorCallIndex() and
917+
child = this.getChild(destructorId) and
918+
result = this.getChild(destructorId + 1).getFirstInstruction(kind)
919+
)
920+
or
921+
exists(int lastDestructorIndex |
922+
lastDestructorIndex =
923+
max(int n | exists(this.getChild(n)) and n >= this.getFirstDestructorCallIndex()) and
924+
child = this.getChild(lastDestructorIndex) and
925+
result = this.getParent().getChildSuccessor(this, kind)
926+
)
910927
}
911928

912929
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
913930
none()
914931
}
915932
}
916933

917-
class TranslatedConstExprIfStmt extends TranslatedStmt, ConditionContext {
918-
override ConstexprIfStmt stmt;
919-
920-
override Instruction getFirstInstruction(EdgeKind kind) {
921-
if this.hasInitialization()
922-
then result = this.getInitialization().getFirstInstruction(kind)
923-
else result = this.getFirstConditionInstruction(kind)
924-
}
925-
926-
override TranslatedElement getChildInternal(int id) {
927-
id = 0 and result = this.getInitialization()
928-
or
929-
id = 1 and result = this.getCondition()
930-
or
931-
id = 2 and result = this.getThen()
932-
or
933-
id = 3 and result = this.getElse()
934-
}
934+
class TranslatedIfStmt extends TranslatedIfLikeStmt {
935+
override IfStmt stmt;
935936

936-
private predicate hasInitialization() { exists(stmt.getInitialization()) }
937+
override predicate hasInitialization() { exists(stmt.getInitialization()) }
937938

938-
private TranslatedStmt getInitialization() {
939+
override TranslatedStmt getInitialization() {
939940
result = getTranslatedStmt(stmt.getInitialization())
940941
}
941942

942-
private TranslatedCondition getCondition() {
943+
override TranslatedCondition getCondition() {
943944
result = getTranslatedCondition(stmt.getCondition().getFullyConverted())
944945
}
945946

946-
private Instruction getFirstConditionInstruction(EdgeKind kind) {
947-
result = this.getCondition().getFirstInstruction(kind)
948-
}
947+
override TranslatedStmt getThen() { result = getTranslatedStmt(stmt.getThen()) }
949948

950-
private TranslatedStmt getThen() { result = getTranslatedStmt(stmt.getThen()) }
949+
override TranslatedStmt getElse() { result = getTranslatedStmt(stmt.getElse()) }
951950

952-
private TranslatedStmt getElse() { result = getTranslatedStmt(stmt.getElse()) }
951+
override predicate hasElse() { exists(stmt.getElse()) }
952+
}
953953

954-
private predicate hasElse() { exists(stmt.getElse()) }
954+
class TranslatedConstExprIfStmt extends TranslatedIfLikeStmt {
955+
override ConstexprIfStmt stmt;
955956

956-
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
957+
override predicate hasInitialization() { exists(stmt.getInitialization()) }
957958

958-
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
959-
child = this.getCondition() and
960-
result = this.getThen().getFirstInstruction(kind)
959+
override TranslatedStmt getInitialization() {
960+
result = getTranslatedStmt(stmt.getInitialization())
961961
}
962962

963-
override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
964-
child = this.getCondition() and
965-
if this.hasElse()
966-
then result = this.getElse().getFirstInstruction(kind)
967-
else result = this.getParent().getChildSuccessor(this, kind)
963+
override TranslatedCondition getCondition() {
964+
result = getTranslatedCondition(stmt.getCondition().getFullyConverted())
968965
}
969966

970-
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
971-
child = this.getInitialization() and
972-
result = this.getFirstConditionInstruction(kind)
973-
or
974-
(child = this.getThen() or child = this.getElse()) and
975-
result = this.getParent().getChildSuccessor(this, kind)
976-
}
967+
override TranslatedStmt getThen() { result = getTranslatedStmt(stmt.getThen()) }
977968

978-
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
979-
none()
980-
}
969+
override TranslatedStmt getElse() { result = getTranslatedStmt(stmt.getElse()) }
981970

982-
override Instruction getALastInstructionInternal() {
983-
result = this.getThen().getALastInstruction()
984-
or
985-
result = this.getElse().getALastInstruction()
986-
}
971+
override predicate hasElse() { exists(stmt.getElse()) }
987972
}
988973

989974
abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {

0 commit comments

Comments
 (0)