Skip to content

Commit 55cbff7

Browse files
committed
C++: fix for constructor init without constructor
1 parent 836c47a commit 55cbff7

File tree

6 files changed

+64
-21
lines changed

6 files changed

+64
-21
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,13 @@ newtype TTranslatedElement =
567567
} or
568568
// The initialization of a base class from within a constructor.
569569
TTranslatedConstructorBaseInit(ConstructorBaseInit init) { not ignoreExpr(init) } or
570+
// Workaround for a case where no base constructor is generated but a targetless base
571+
// constructor call is present.
572+
TTranslatedConstructorBareInit(ConstructorInit init) {
573+
not ignoreExpr(init) and
574+
not init instanceof ConstructorBaseInit and
575+
not init instanceof ConstructorFieldInit
576+
} or
570577
// The destruction of a base class from within a destructor.
571578
TTranslatedDestructorBaseDestruction(DestructorBaseDestruction destruction) {
572579
not ignoreExpr(destruction)

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,11 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
573573
baseInit = func.(Constructor).getInitializer(id) and
574574
result = getTranslatedConstructorBaseInit(baseInit)
575575
)
576+
or
577+
exists(ConstructorInit bareInit |
578+
bareInit = func.(Constructor).getInitializer(id) and
579+
result = getTranslatedConstructorBareInit(bareInit)
580+
)
576581
}
577582

578583
override Instruction getFirstInstruction() {

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,3 +917,36 @@ class TranslatedDestructorBaseDestruction extends TranslatedBaseStructorCall,
917917

918918
final override string toString() { result = "destroy base: " + call.toString() }
919919
}
920+
921+
/**
922+
* A constructor base init call where no base constructor has been generated.
923+
*
924+
* Workaround for an extractor issue.
925+
*/
926+
class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstructorBareInit {
927+
ConstructorInit init;
928+
929+
TranslatedConstructorBareInit() { this = TTranslatedConstructorBareInit(init) }
930+
931+
override Locatable getAST() { result = init }
932+
933+
final override string toString() { result = "construct base (no constructor)" }
934+
935+
override Instruction getFirstInstruction() { result = getParent().getChildSuccessor(this) }
936+
937+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
938+
none()
939+
}
940+
941+
override TranslatedElement getChild(int id) { none() }
942+
943+
override Function getFunction() { result = getParent().getFunction() }
944+
945+
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
946+
947+
override Instruction getChildSuccessor(TranslatedElement child) { none() }
948+
}
949+
950+
TranslatedConstructorBareInit getTranslatedConstructorBareInit(ConstructorInit init) {
951+
result.getAST() = init
952+
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6644,12 +6644,17 @@
66446644
| ir.cpp:1457:3:1457:20 | Load | m1457_6 |
66456645
| ir.cpp:1457:3:1457:20 | SideEffect | m1457_3 |
66466646
| ir.cpp:1457:3:1457:20 | SideEffect | m1458_6 |
6647+
| ir.cpp:1457:3:1457:20 | Unary | m1457_6 |
6648+
| ir.cpp:1457:26:1457:30 | Address | &:r1457_9 |
6649+
| ir.cpp:1457:26:1457:30 | ChiPartial | partial:m1457_11 |
6650+
| ir.cpp:1457:26:1457:30 | ChiTotal | total:m1457_8 |
6651+
| ir.cpp:1457:26:1457:30 | StoreValue | r1457_10 |
66476652
| ir.cpp:1458:5:1458:5 | Address | &:r1458_2 |
66486653
| ir.cpp:1458:5:1458:5 | Address | &:r1458_4 |
66496654
| ir.cpp:1458:5:1458:5 | Load | m1457_6 |
66506655
| ir.cpp:1458:5:1458:5 | Unary | r1458_3 |
66516656
| ir.cpp:1458:5:1458:9 | ChiPartial | partial:m1458_5 |
6652-
| ir.cpp:1458:5:1458:9 | ChiTotal | total:m1457_8 |
6657+
| ir.cpp:1458:5:1458:9 | ChiTotal | total:m1457_12 |
66536658
| ir.cpp:1458:9:1458:9 | StoreValue | r1458_1 |
66546659
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
66556660
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ containsLoopOfForwardEdges
1717
lostReachability
1818
backEdgeCountMismatch
1919
useNotDominatedByDefinition
20-
| ir.cpp:1457:3:1457:20 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:1457:3:1457:20 | void Inheritance_Test_A::Inheritance_Test_A() | void Inheritance_Test_A::Inheritance_Test_A() |
2120
switchInstructionWithoutDefaultEdge
2221
notMarkedAsConflated
2322
wronglyMarkedAsConflated

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

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7882,25 +7882,19 @@ ir.cpp:
78827882
# 1457| mu1457_5(glval<Inheritance_Test_A>) = InitializeParameter[#this] : &:r1457_4
78837883
# 1457| r1457_6(glval<Inheritance_Test_A>) = Load[#this] : &:r1457_4, ~m?
78847884
# 1457| mu1457_7(Inheritance_Test_A) = InitializeIndirection[#this] : &:r1457_6
7885-
#-----| Goto -> Block 2
7886-
7887-
# 1457| Block 1
7888-
# 1457| r1457_8(glval<int>) = FieldAddress[x] : mu1457_5
7889-
# 1457| r1457_9(int) = Constant[42] :
7890-
# 1457| mu1457_10(int) = Store[?] : &:r1457_8, r1457_9
7891-
#-----| Goto -> Block 2
7892-
7893-
# 1458| Block 2
7894-
# 1458| r1458_1(int) = Constant[3] :
7895-
# 1458| r1458_2(glval<unknown>) = VariableAddress[#this] :
7896-
# 1458| r1458_3(Inheritance_Test_A *) = Load[#this] : &:r1458_2, ~m?
7897-
# 1458| r1458_4(glval<int>) = FieldAddress[y] : r1458_3
7898-
# 1458| mu1458_5(int) = Store[?] : &:r1458_4, r1458_1
7899-
# 1459| v1459_1(void) = NoOp :
7900-
# 1457| v1457_11(void) = ReturnIndirection[#this] : &:r1457_6, ~m?
7901-
# 1457| v1457_12(void) = ReturnVoid :
7902-
# 1457| v1457_13(void) = AliasedUse : ~m?
7903-
# 1457| v1457_14(void) = ExitFunction :
7885+
# 1457| r1457_8(glval<int>) = FieldAddress[x] : mu1457_5
7886+
# 1457| r1457_9(int) = Constant[42] :
7887+
# 1457| mu1457_10(int) = Store[?] : &:r1457_8, r1457_9
7888+
# 1458| r1458_1(int) = Constant[3] :
7889+
# 1458| r1458_2(glval<unknown>) = VariableAddress[#this] :
7890+
# 1458| r1458_3(Inheritance_Test_A *) = Load[#this] : &:r1458_2, ~m?
7891+
# 1458| r1458_4(glval<int>) = FieldAddress[y] : r1458_3
7892+
# 1458| mu1458_5(int) = Store[?] : &:r1458_4, r1458_1
7893+
# 1459| v1459_1(void) = NoOp :
7894+
# 1457| v1457_11(void) = ReturnIndirection[#this] : &:r1457_6, ~m?
7895+
# 1457| v1457_12(void) = ReturnVoid :
7896+
# 1457| v1457_13(void) = AliasedUse : ~m?
7897+
# 1457| v1457_14(void) = ExitFunction :
79047898

79057899
perf-regression.cpp:
79067900
# 6| void Big::Big()

0 commit comments

Comments
 (0)