]> granicus.if.org Git - clang/commitdiff
Don't compute final overriders or build vtables for bases that don't need a vtable.
authorAnders Carlsson <andersca@mac.com>
Sun, 14 Feb 2010 17:05:59 +0000 (17:05 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 14 Feb 2010 17:05:59 +0000 (17:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96171 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGVtable.cpp
test/CodeGenCXX/vtable-layout.cpp

index 878e563d84728f0fbec1b90dbad27452bfa7bb8e..2f952c54b6e9eafe4987b5d82cf47cf26cfd3c30 100644 (file)
@@ -498,6 +498,10 @@ void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base,
     const CXXRecordDecl *BaseDecl = 
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
     
+    // Ignore bases that don't have any virtual member functions.
+    if (!BaseDecl->isPolymorphic())
+      continue;
+    
     uint64_t BaseOffset;
     if (I->isVirtual()) {
       BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
@@ -528,6 +532,10 @@ void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) {
     const CXXRecordDecl *BaseDecl = 
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
     
+    // Ignore bases that don't have any virtual member functions.
+    if (!BaseDecl->isPolymorphic())
+      continue;
+
     uint64_t BaseOffset;
     if (I->isVirtual()) {
       if (!VisitedVirtualBases.insert(BaseDecl)) {
@@ -949,7 +957,9 @@ VtableBuilder::AddMethods(BaseSubobject Base, PrimaryBasesSetTy &PrimaryBases) {
 
 void VtableBuilder::layoutVtable(BaseSubobject Base) {
   const CXXRecordDecl *RD = Base.getBase();
-  
+
+  assert(RD->isDynamicClass() && "class does not have a vtable!");
+
   // First, add the offset to top.
   // FIXME: This is not going to be right for construction vtables.
   // FIXME: We should not use / 8 here.
@@ -987,11 +997,15 @@ void VtableBuilder::layoutVtable(BaseSubobject Base) {
        E = RD->bases_end(); I != E; ++I) {
     const CXXRecordDecl *BaseDecl = 
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-    
+
     // Ignore the primary base.
     if (BaseDecl == PrimaryBase)
       continue;
-    
+
+    // Ignore bases that don't have a vtable.
+    if (!BaseDecl->isDynamicClass())
+      continue;
+
     assert(!I->isVirtual() && "FIXME: Handle virtual bases");
     
     // Get the base offset of this base.
index e151de14ed9be49c12f856ca37770ac1aa3e1fb2..a41aad41f9be26cdfc9ea5c04833185e7ee695c2 100644 (file)
@@ -321,3 +321,22 @@ struct D : C, B1, B2 {
 void D::f() { }
 
 }
+
+namespace Test8 {
+
+// Test that we don't try to layout vtables for classes that don't have
+// virtual bases or virtual member functions.
+
+struct A { };
+
+// CHECK:     Vtable for 'Test8::B' (3 entries).
+// CHECK-NEXT:   0 | offset_to_top (0)
+// CHECK-NEXT:   1 | Test8::B RTTI
+// CHECK-NEXT:       -- (Test8::B, 0) vtable address --
+// CHECK-NEXT:   2 | void Test8::B::f()
+struct B : A { 
+  virtual void f();
+};
+void B::f() { }
+
+}