зеркало из https://github.com/microsoft/clang-1.git
Don't add address points for virtual primary bases that aren't primary bases in the complete class.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99555 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
e06c1a1317
Коммит
014a358058
|
@ -1900,20 +1900,32 @@ VtableBuilder::LayoutPrimaryAndSecondaryVtables(BaseSubobject Base,
|
||||||
// Compute 'this' pointer adjustments.
|
// Compute 'this' pointer adjustments.
|
||||||
ComputeThisAdjustments();
|
ComputeThisAdjustments();
|
||||||
|
|
||||||
// Record the address point.
|
// Add all address points.
|
||||||
AddressPoints.insert(std::make_pair(BaseSubobject(Base.getBase(),
|
const CXXRecordDecl *RD = Base.getBase();
|
||||||
OffsetInLayoutClass),
|
while (true) {
|
||||||
AddressPoint));
|
AddressPoints.insert(std::make_pair(BaseSubobject(RD, OffsetInLayoutClass),
|
||||||
|
AddressPoint));
|
||||||
// Record the address points for all primary bases.
|
|
||||||
for (PrimaryBasesSetVectorTy::const_iterator I = PrimaryBases.begin(),
|
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
|
||||||
E = PrimaryBases.end(); I != E; ++I) {
|
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
|
||||||
const CXXRecordDecl *BaseDecl = *I;
|
|
||||||
|
|
||||||
// We know that all the primary bases have the same offset as the base
|
if (!PrimaryBase)
|
||||||
// subobject.
|
break;
|
||||||
BaseSubobject PrimaryBase(BaseDecl, OffsetInLayoutClass);
|
|
||||||
AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint));
|
if (Layout.getPrimaryBaseWasVirtual()) {
|
||||||
|
// Check if this virtual primary base is a primary base in the layout
|
||||||
|
// class. If it's not, we don't want to add it.
|
||||||
|
const ASTRecordLayout &LayoutClassLayout =
|
||||||
|
Context.getASTRecordLayout(LayoutClass);
|
||||||
|
|
||||||
|
if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) !=
|
||||||
|
OffsetInLayoutClass) {
|
||||||
|
// We don't want to add this class (or any of its primary bases).
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RD = PrimaryBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseIsMorallyVirtual = BaseIsVirtual;
|
bool BaseIsMorallyVirtual = BaseIsVirtual;
|
||||||
|
|
|
@ -178,7 +178,6 @@ struct C : virtual public A { int j; };
|
||||||
// CHECK-NEXT: 7 | vcall_offset (-16)
|
// CHECK-NEXT: 7 | vcall_offset (-16)
|
||||||
// CHECK-NEXT: 8 | offset_to_top (-16)
|
// CHECK-NEXT: 8 | offset_to_top (-16)
|
||||||
// CHECK-NEXT: 9 | Test2::D RTTI
|
// CHECK-NEXT: 9 | Test2::D RTTI
|
||||||
// CHECK-NEXT: -- (Test2::A, 16) vtable address --
|
|
||||||
// CHECK-NEXT: -- (Test2::C, 16) vtable address --
|
// CHECK-NEXT: -- (Test2::C, 16) vtable address --
|
||||||
// CHECK-NEXT: 10 | [unused] void Test2::A::f()
|
// CHECK-NEXT: 10 | [unused] void Test2::A::f()
|
||||||
struct D : public B, public C {
|
struct D : public B, public C {
|
||||||
|
|
|
@ -635,7 +635,6 @@ struct D : virtual B, virtual C { virtual void f(); };
|
||||||
// CHECK-NEXT: 9 | vcall_offset (-8)
|
// CHECK-NEXT: 9 | vcall_offset (-8)
|
||||||
// CHECK-NEXT: 10 | offset_to_top (-8)
|
// CHECK-NEXT: 10 | offset_to_top (-8)
|
||||||
// CHECK-NEXT: 11 | Test17::E RTTI
|
// CHECK-NEXT: 11 | Test17::E RTTI
|
||||||
// CHECK-NEXT: -- (Test17::A, 8) vtable address --
|
|
||||||
// CHECK-NEXT: -- (Test17::C, 8) vtable address --
|
// CHECK-NEXT: -- (Test17::C, 8) vtable address --
|
||||||
// CHECK-NEXT: 12 | void Test17::E::f()
|
// CHECK-NEXT: 12 | void Test17::E::f()
|
||||||
// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
|
// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
|
||||||
|
@ -693,7 +692,6 @@ struct C : A, B {
|
||||||
// CHECK-NEXT: 19 | vcall_offset (-16)
|
// CHECK-NEXT: 19 | vcall_offset (-16)
|
||||||
// CHECK-NEXT: 20 | offset_to_top (-16)
|
// CHECK-NEXT: 20 | offset_to_top (-16)
|
||||||
// CHECK-NEXT: 21 | Test18::D RTTI
|
// CHECK-NEXT: 21 | Test18::D RTTI
|
||||||
// CHECK-NEXT: -- (Test18::A, 16) vtable address --
|
|
||||||
// CHECK-NEXT: -- (Test18::B, 16) vtable address --
|
// CHECK-NEXT: -- (Test18::B, 16) vtable address --
|
||||||
// CHECK-NEXT: 22 | void Test18::D::f()
|
// CHECK-NEXT: 22 | void Test18::D::f()
|
||||||
// CHECK-NEXT: [this adjustment: -8 non-virtual, -32 vcall offset offset]
|
// CHECK-NEXT: [this adjustment: -8 non-virtual, -32 vcall offset offset]
|
||||||
|
@ -725,7 +723,6 @@ struct C : A, B {
|
||||||
// CHECK-NEXT: 9 | vcall_offset (0)
|
// CHECK-NEXT: 9 | vcall_offset (0)
|
||||||
// CHECK-NEXT: 10 | offset_to_top (-8)
|
// CHECK-NEXT: 10 | offset_to_top (-8)
|
||||||
// CHECK-NEXT: 11 | Test18::C RTTI
|
// CHECK-NEXT: 11 | Test18::C RTTI
|
||||||
// CHECK-NEXT: -- (Test18::A, 16) vtable address --
|
|
||||||
// CHECK-NEXT: -- (Test18::B, 16) vtable address --
|
// CHECK-NEXT: -- (Test18::B, 16) vtable address --
|
||||||
// CHECK-NEXT: 12 | void Test18::B::f()
|
// CHECK-NEXT: 12 | void Test18::B::f()
|
||||||
// CHECK-NEXT: 13 | [unused] void Test18::C::g()
|
// CHECK-NEXT: 13 | [unused] void Test18::C::g()
|
||||||
|
@ -745,7 +742,6 @@ struct C : A, B {
|
||||||
// CHECK-NEXT: 2 | vcall_offset (0)
|
// CHECK-NEXT: 2 | vcall_offset (0)
|
||||||
// CHECK-NEXT: 3 | offset_to_top (0)
|
// CHECK-NEXT: 3 | offset_to_top (0)
|
||||||
// CHECK-NEXT: 4 | Test18::B RTTI
|
// CHECK-NEXT: 4 | Test18::B RTTI
|
||||||
// CHECK-NEXT: -- (Test18::A, 16) vtable address --
|
|
||||||
// CHECK-NEXT: -- (Test18::B, 16) vtable address --
|
// CHECK-NEXT: -- (Test18::B, 16) vtable address --
|
||||||
// CHECK-NEXT: 5 | void Test18::B::f()
|
// CHECK-NEXT: 5 | void Test18::B::f()
|
||||||
// CHECK-NEXT: 6 | [unused] void Test18::A::g()
|
// CHECK-NEXT: 6 | [unused] void Test18::A::g()
|
||||||
|
@ -881,9 +877,6 @@ class E : virtual C { };
|
||||||
// CHECK-NEXT: 12 | vcall_offset (-8)
|
// CHECK-NEXT: 12 | vcall_offset (-8)
|
||||||
// CHECK-NEXT: 13 | offset_to_top (-8)
|
// CHECK-NEXT: 13 | offset_to_top (-8)
|
||||||
// CHECK-NEXT: 14 | Test21::F RTTI
|
// CHECK-NEXT: 14 | Test21::F RTTI
|
||||||
// CHECK-NEXT: -- (Test21::A, 8) vtable address --
|
|
||||||
// CHECK-NEXT: -- (Test21::B, 8) vtable address --
|
|
||||||
// CHECK-NEXT: -- (Test21::C, 8) vtable address --
|
|
||||||
// CHECK-NEXT: -- (Test21::E, 8) vtable address --
|
// CHECK-NEXT: -- (Test21::E, 8) vtable address --
|
||||||
// CHECK-NEXT: 15 | [unused] void Test21::F::f()
|
// CHECK-NEXT: 15 | [unused] void Test21::F::f()
|
||||||
//
|
//
|
||||||
|
@ -1012,7 +1005,6 @@ struct C : virtual A { };
|
||||||
// CHECK-NEXT: 6 | vcall_offset (-8)
|
// CHECK-NEXT: 6 | vcall_offset (-8)
|
||||||
// CHECK-NEXT: 7 | offset_to_top (-8)
|
// CHECK-NEXT: 7 | offset_to_top (-8)
|
||||||
// CHECK-NEXT: 8 | Test24::D RTTI
|
// CHECK-NEXT: 8 | Test24::D RTTI
|
||||||
// CHECK-NEXT: -- (Test24::A, 8) vtable address --
|
|
||||||
// CHECK-NEXT: -- (Test24::C, 8) vtable address --
|
// CHECK-NEXT: -- (Test24::C, 8) vtable address --
|
||||||
// CHECK-NEXT: 9 | [unused] void Test24::D::f()
|
// CHECK-NEXT: 9 | [unused] void Test24::D::f()
|
||||||
|
|
||||||
|
@ -1030,14 +1022,13 @@ struct C : virtual A { };
|
||||||
// CHECK-NEXT: 1 | vcall_offset (-8)
|
// CHECK-NEXT: 1 | vcall_offset (-8)
|
||||||
// CHECK-NEXT: 2 | offset_to_top (0)
|
// CHECK-NEXT: 2 | offset_to_top (0)
|
||||||
// CHECK-NEXT: 3 | Test24::C RTTI
|
// CHECK-NEXT: 3 | Test24::C RTTI
|
||||||
// CHECK-NEXT: -- (Test24::A, 8) vtable address --
|
|
||||||
// CHECK-NEXT: -- (Test24::C, 8) vtable address --
|
// CHECK-NEXT: -- (Test24::C, 8) vtable address --
|
||||||
// CHECK-NEXT: 4 | [unused] void Test24::A::f()
|
// CHECK-NEXT: 4 | [unused] void Test24::A::f()
|
||||||
// CHECK-NEXT: 5 | vcall_offset (0)
|
// CHECK-NEXT: 5 | vcall_offset (0)
|
||||||
// CHECK-NEXT: 6 | offset_to_top (8)
|
// CHECK-NEXT: 6 | offset_to_top (8)
|
||||||
// CHECK-NEXT: 7 | Test24::C RTTI
|
// CHECK-NEXT: 7 | Test24::C RTTI
|
||||||
// CHECK-NEXT: -- (Test24::A, 0) vtable address --
|
// CHECK-NEXT: -- (Test24::A, 0) vtable address --
|
||||||
// CHECK-NEXT: 8 | void Test24::A::f()
|
// CHECK-NEXT: 8 | void Test24::A::f()
|
||||||
struct D : B, C {
|
struct D : B, C {
|
||||||
virtual void f();
|
virtual void f();
|
||||||
};
|
};
|
||||||
|
@ -1071,7 +1062,6 @@ struct B : virtual V { };
|
||||||
// CHECK-NEXT: 8 | offset_to_top (-8)
|
// CHECK-NEXT: 8 | offset_to_top (-8)
|
||||||
// CHECK-NEXT: 9 | Test25::C RTTI
|
// CHECK-NEXT: 9 | Test25::C RTTI
|
||||||
// CHECK-NEXT: -- (Test25::B, 8) vtable address --
|
// CHECK-NEXT: -- (Test25::B, 8) vtable address --
|
||||||
// CHECK-NEXT: -- (Test25::V, 8) vtable address --
|
|
||||||
// CHECK-NEXT: 10 | [unused] void Test25::V::f()
|
// CHECK-NEXT: 10 | [unused] void Test25::V::f()
|
||||||
|
|
||||||
// CHECK: Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries).
|
// CHECK: Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries).
|
||||||
|
@ -1089,7 +1079,6 @@ struct B : virtual V { };
|
||||||
// CHECK-NEXT: 2 | offset_to_top (0)
|
// CHECK-NEXT: 2 | offset_to_top (0)
|
||||||
// CHECK-NEXT: 3 | Test25::B RTTI
|
// CHECK-NEXT: 3 | Test25::B RTTI
|
||||||
// CHECK-NEXT: -- (Test25::B, 8) vtable address --
|
// CHECK-NEXT: -- (Test25::B, 8) vtable address --
|
||||||
// CHECK-NEXT: -- (Test25::V, 8) vtable address --
|
|
||||||
// CHECK-NEXT: 4 | [unused] void Test25::V::f()
|
// CHECK-NEXT: 4 | [unused] void Test25::V::f()
|
||||||
// CHECK-NEXT: 5 | vcall_offset (0)
|
// CHECK-NEXT: 5 | vcall_offset (0)
|
||||||
// CHECK-NEXT: 6 | offset_to_top (8)
|
// CHECK-NEXT: 6 | offset_to_top (8)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче