mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Merge pull request #7839 from rdmarsh2/rdmarsh2/ir-initializer-inheritance-fix
C++: fix IR generation for constructor base inits when no constructor is present.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -11332,6 +11332,64 @@ ir.cpp:
|
||||
# 1447| Type = [Struct] POD_Derived
|
||||
# 1447| ValueCategory = prvalue
|
||||
# 1448| getStmt(4): [ReturnStmt] return ...
|
||||
# 1450| [CopyAssignmentOperator] Inheritance_Test_B& Inheritance_Test_B::operator=(Inheritance_Test_B const&)
|
||||
# 1450| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Inheritance_Test_B &
|
||||
# 1450| [Constructor] void Inheritance_Test_B::Inheritance_Test_B()
|
||||
# 1450| <params>:
|
||||
# 1451| [Destructor] void Inheritance_Test_B::~Inheritance_Test_B()
|
||||
# 1451| <params>:
|
||||
# 1451| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1451| getStmt(0): [ReturnStmt] return ...
|
||||
# 1451| <destructions>:
|
||||
# 1454| [CopyAssignmentOperator] Inheritance_Test_A& Inheritance_Test_A::operator=(Inheritance_Test_A const&)
|
||||
# 1454| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Inheritance_Test_A &
|
||||
# 1454| [MoveAssignmentOperator] Inheritance_Test_A& Inheritance_Test_A::operator=(Inheritance_Test_A&&)
|
||||
# 1454| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] Inheritance_Test_A &&
|
||||
# 1454| [CopyConstructor] void Inheritance_Test_A::Inheritance_Test_A(Inheritance_Test_A const&)
|
||||
# 1454| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Inheritance_Test_A &
|
||||
# 1454| [MoveConstructor] void Inheritance_Test_A::Inheritance_Test_A(Inheritance_Test_A&&)
|
||||
# 1454| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] Inheritance_Test_A &&
|
||||
# 1454| [Destructor] void Inheritance_Test_A::~Inheritance_Test_A()
|
||||
# 1454| <params>:
|
||||
# 1457| [Constructor] void Inheritance_Test_A::Inheritance_Test_A()
|
||||
# 1457| <params>:
|
||||
# 1457| <initializations>:
|
||||
# 1457| getInitializer(0): (no string representation)
|
||||
# 1457| Type = [Struct] Inheritance_Test_B
|
||||
# 1457| ValueCategory = prvalue
|
||||
# 1457| getInitializer(1): [ConstructorFieldInit] constructor init of field x
|
||||
# 1457| Type = [IntType] int
|
||||
# 1457| ValueCategory = prvalue
|
||||
# 1457| getExpr(): [Literal] 42
|
||||
# 1457| Type = [IntType] int
|
||||
# 1457| Value = [Literal] 42
|
||||
# 1457| ValueCategory = prvalue
|
||||
# 1457| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1458| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 1458| getExpr(): [AssignExpr] ... = ...
|
||||
# 1458| Type = [IntType] int
|
||||
# 1458| ValueCategory = lvalue
|
||||
# 1458| getLValue(): [PointerFieldAccess] y
|
||||
# 1458| Type = [IntType] int
|
||||
# 1458| ValueCategory = lvalue
|
||||
# 1458| getQualifier(): [ThisExpr] this
|
||||
# 1458| Type = [PointerType] Inheritance_Test_A *
|
||||
# 1458| ValueCategory = prvalue(load)
|
||||
# 1458| getRValue(): [Literal] 3
|
||||
# 1458| Type = [IntType] int
|
||||
# 1458| Value = [Literal] 3
|
||||
# 1458| ValueCategory = prvalue
|
||||
# 1459| getStmt(1): [ReturnStmt] return ...
|
||||
perf-regression.cpp:
|
||||
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
|
||||
# 4| <params>:
|
||||
|
||||
@@ -1447,4 +1447,15 @@ void temporary_hierarchy() {
|
||||
float f = (returnValue<POD_Derived>()).f();
|
||||
}
|
||||
|
||||
struct Inheritance_Test_B {
|
||||
~Inheritance_Test_B() {}
|
||||
};
|
||||
|
||||
struct Inheritance_Test_A : public Inheritance_Test_B {
|
||||
int x;
|
||||
int y;
|
||||
Inheritance_Test_A() : x(42) {
|
||||
y = 3;
|
||||
}
|
||||
};
|
||||
// semmle-extractor-options: -std=c++17 --clang
|
||||
|
||||
@@ -6626,6 +6626,36 @@
|
||||
| ir.cpp:1447:44:1447:44 | ChiTotal | total:m1447_5 |
|
||||
| ir.cpp:1447:44:1447:44 | SideEffect | ~m1447_5 |
|
||||
| ir.cpp:1447:44:1447:44 | StoreValue | r1447_8 |
|
||||
| ir.cpp:1451:3:1451:21 | Address | &:r1451_5 |
|
||||
| ir.cpp:1451:3:1451:21 | Address | &:r1451_5 |
|
||||
| ir.cpp:1451:3:1451:21 | Address | &:r1451_7 |
|
||||
| ir.cpp:1451:3:1451:21 | Address | &:r1451_7 |
|
||||
| ir.cpp:1451:3:1451:21 | ChiPartial | partial:m1451_3 |
|
||||
| ir.cpp:1451:3:1451:21 | ChiTotal | total:m1451_2 |
|
||||
| ir.cpp:1451:3:1451:21 | Load | m1451_6 |
|
||||
| ir.cpp:1451:3:1451:21 | SideEffect | m1451_3 |
|
||||
| ir.cpp:1451:3:1451:21 | SideEffect | m1451_8 |
|
||||
| ir.cpp:1457:3:1457:20 | Address | &:r1457_5 |
|
||||
| ir.cpp:1457:3:1457:20 | Address | &:r1457_5 |
|
||||
| ir.cpp:1457:3:1457:20 | Address | &:r1457_7 |
|
||||
| ir.cpp:1457:3:1457:20 | Address | &:r1457_7 |
|
||||
| ir.cpp:1457:3:1457:20 | ChiPartial | partial:m1457_3 |
|
||||
| ir.cpp:1457:3:1457:20 | ChiTotal | total:m1457_2 |
|
||||
| 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_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 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_7 |
|
||||
|
||||
@@ -7858,6 +7858,44 @@ ir.cpp:
|
||||
# 1443| v1443_5(void) = AliasedUse : ~m?
|
||||
# 1443| v1443_6(void) = ExitFunction :
|
||||
|
||||
# 1451| void Inheritance_Test_B::~Inheritance_Test_B()
|
||||
# 1451| Block 0
|
||||
# 1451| v1451_1(void) = EnterFunction :
|
||||
# 1451| mu1451_2(unknown) = AliasedDefinition :
|
||||
# 1451| mu1451_3(unknown) = InitializeNonLocal :
|
||||
# 1451| r1451_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 1451| mu1451_5(glval<Inheritance_Test_B>) = InitializeParameter[#this] : &:r1451_4
|
||||
# 1451| r1451_6(glval<Inheritance_Test_B>) = Load[#this] : &:r1451_4, ~m?
|
||||
# 1451| mu1451_7(Inheritance_Test_B) = InitializeIndirection[#this] : &:r1451_6
|
||||
# 1451| v1451_8(void) = NoOp :
|
||||
# 1451| v1451_9(void) = ReturnIndirection[#this] : &:r1451_6, ~m?
|
||||
# 1451| v1451_10(void) = ReturnVoid :
|
||||
# 1451| v1451_11(void) = AliasedUse : ~m?
|
||||
# 1451| v1451_12(void) = ExitFunction :
|
||||
|
||||
# 1457| void Inheritance_Test_A::Inheritance_Test_A()
|
||||
# 1457| Block 0
|
||||
# 1457| v1457_1(void) = EnterFunction :
|
||||
# 1457| mu1457_2(unknown) = AliasedDefinition :
|
||||
# 1457| mu1457_3(unknown) = InitializeNonLocal :
|
||||
# 1457| r1457_4(glval<unknown>) = VariableAddress[#this] :
|
||||
# 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
|
||||
# 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()
|
||||
# 6| Block 0
|
||||
|
||||
Reference in New Issue
Block a user