C++: fix for constructor init without constructor

This commit is contained in:
Robert Marsh
2022-02-03 13:44:02 -05:00
parent 836c47abb3
commit 55cbff7614
6 changed files with 64 additions and 21 deletions

View File

@@ -567,6 +567,13 @@ newtype TTranslatedElement =
} or
// The initialization of a base class from within a constructor.
TTranslatedConstructorBaseInit(ConstructorBaseInit init) { not ignoreExpr(init) } or
// Workaround for a case where no base constructor is generated but a targetless base
// constructor call is present.
TTranslatedConstructorBareInit(ConstructorInit init) {
not ignoreExpr(init) and
not init instanceof ConstructorBaseInit and
not init instanceof ConstructorFieldInit
} or
// The destruction of a base class from within a destructor.
TTranslatedDestructorBaseDestruction(DestructorBaseDestruction destruction) {
not ignoreExpr(destruction)

View File

@@ -573,6 +573,11 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
baseInit = func.(Constructor).getInitializer(id) and
result = getTranslatedConstructorBaseInit(baseInit)
)
or
exists(ConstructorInit bareInit |
bareInit = func.(Constructor).getInitializer(id) and
result = getTranslatedConstructorBareInit(bareInit)
)
}
override Instruction getFirstInstruction() {

View File

@@ -917,3 +917,36 @@ class TranslatedDestructorBaseDestruction extends TranslatedBaseStructorCall,
final override string toString() { result = "destroy base: " + call.toString() }
}
/**
* A constructor base init call where no base constructor has been generated.
*
* Workaround for an extractor issue.
*/
class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstructorBareInit {
ConstructorInit init;
TranslatedConstructorBareInit() { this = TTranslatedConstructorBareInit(init) }
override Locatable getAST() { result = init }
final override string toString() { result = "construct base (no constructor)" }
override Instruction getFirstInstruction() { result = getParent().getChildSuccessor(this) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none()
}
override TranslatedElement getChild(int id) { none() }
override Function getFunction() { result = getParent().getFunction() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) { none() }
}
TranslatedConstructorBareInit getTranslatedConstructorBareInit(ConstructorInit init) {
result.getAST() = init
}

View File

@@ -6644,12 +6644,17 @@
| ir.cpp:1457:3:1457:20 | Load | m1457_6 |
| ir.cpp:1457:3:1457:20 | SideEffect | m1457_3 |
| ir.cpp:1457:3:1457:20 | SideEffect | m1458_6 |
| ir.cpp:1457:3:1457:20 | Unary | m1457_6 |
| ir.cpp:1457:26:1457:30 | Address | &:r1457_9 |
| ir.cpp:1457:26:1457:30 | ChiPartial | partial:m1457_11 |
| ir.cpp:1457:26:1457:30 | ChiTotal | total:m1457_8 |
| ir.cpp:1457:26:1457:30 | StoreValue | r1457_10 |
| ir.cpp:1458:5:1458:5 | Address | &:r1458_2 |
| ir.cpp:1458:5:1458:5 | Address | &:r1458_4 |
| ir.cpp:1458:5:1458:5 | Load | m1457_6 |
| ir.cpp:1458:5:1458:5 | Unary | r1458_3 |
| ir.cpp:1458:5:1458:9 | ChiPartial | partial:m1458_5 |
| ir.cpp:1458:5:1458:9 | ChiTotal | total:m1457_8 |
| ir.cpp:1458:5:1458:9 | ChiTotal | total:m1457_12 |
| ir.cpp:1458:9:1458:9 | StoreValue | r1458_1 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |

View File

@@ -17,7 +17,6 @@ containsLoopOfForwardEdges
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
| 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() |
switchInstructionWithoutDefaultEdge
notMarkedAsConflated
wronglyMarkedAsConflated

View File

@@ -7882,25 +7882,19 @@ ir.cpp:
# 1457| mu1457_5(glval<Inheritance_Test_A>) = InitializeParameter[#this] : &:r1457_4
# 1457| r1457_6(glval<Inheritance_Test_A>) = Load[#this] : &:r1457_4, ~m?
# 1457| mu1457_7(Inheritance_Test_A) = InitializeIndirection[#this] : &:r1457_6
#-----| Goto -> Block 2
# 1457| Block 1
# 1457| r1457_8(glval<int>) = FieldAddress[x] : mu1457_5
# 1457| r1457_9(int) = Constant[42] :
# 1457| mu1457_10(int) = Store[?] : &:r1457_8, r1457_9
#-----| Goto -> Block 2
# 1458| Block 2
# 1458| r1458_1(int) = Constant[3] :
# 1458| r1458_2(glval<unknown>) = VariableAddress[#this] :
# 1458| r1458_3(Inheritance_Test_A *) = Load[#this] : &:r1458_2, ~m?
# 1458| r1458_4(glval<int>) = FieldAddress[y] : r1458_3
# 1458| mu1458_5(int) = Store[?] : &:r1458_4, r1458_1
# 1459| v1459_1(void) = NoOp :
# 1457| v1457_11(void) = ReturnIndirection[#this] : &:r1457_6, ~m?
# 1457| v1457_12(void) = ReturnVoid :
# 1457| v1457_13(void) = AliasedUse : ~m?
# 1457| v1457_14(void) = ExitFunction :
# 1457| r1457_8(glval<int>) = FieldAddress[x] : mu1457_5
# 1457| r1457_9(int) = Constant[42] :
# 1457| mu1457_10(int) = Store[?] : &:r1457_8, r1457_9
# 1458| r1458_1(int) = Constant[3] :
# 1458| r1458_2(glval<unknown>) = VariableAddress[#this] :
# 1458| r1458_3(Inheritance_Test_A *) = Load[#this] : &:r1458_2, ~m?
# 1458| r1458_4(glval<int>) = FieldAddress[y] : r1458_3
# 1458| mu1458_5(int) = Store[?] : &:r1458_4, r1458_1
# 1459| v1459_1(void) = NoOp :
# 1457| v1457_11(void) = ReturnIndirection[#this] : &:r1457_6, ~m?
# 1457| v1457_12(void) = ReturnVoid :
# 1457| v1457_13(void) = AliasedUse : ~m?
# 1457| v1457_14(void) = ExitFunction :
perf-regression.cpp:
# 6| void Big::Big()