Hi all!

This patch fixes the following problem:
struct first {
    virtual void asdf() {}
    virtual void g(){}
    };

  struct second : virtual first {
    int q;
      virtual void asdf() { q = 90; }
      virtual void g(){ q = 12; }
  };

  struct third : virtual second {};
    void test2() { third *t; }

In clang "second" has vtordisp for "first", but MSVC doesn`t generate vtordisp for "first". According msdn " If a derived class overrides a virtual function that it inherits from a virtual base class,*and if a constructor or destructor for the derived class calls that function using a pointer to the virtual base class*, the compiler may introduce additional hidden "vtordisp" fields into classes with virtual bases. ". So in in this example "second" will not have vtordisp for "first". But if we add constructor or destructor in "second" then MSVC add vtordisp.

 - Dmitry Sokolov.
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp     (revision 157602)
+++ lib/AST/RecordLayoutBuilder.cpp     (working copy)
@@ -1319,7 +1319,6 @@
     for (CXXMethodDecl::method_iterator I = M->begin_overridden_methods(),
           E = M->end_overridden_methods(); I != E; ++I) {
       const CXXMethodDecl *overriddenMethod = (*I);
-
       // Ignore methods that override methods from vbases that require
       // require vtordisps.
       if (overridesMethodRequiringVtorDisp(Context, overriddenMethod))
@@ -1328,6 +1327,13 @@
       // As an optimization, check immediately whether we're overriding
       // something from the undecided set.
       const CXXRecordDecl *overriddenBase = overriddenMethod->getParent();
+      
+      // If in code wasn`t declared ctor or dtor then we don`t need vtordisp.
+      if (!RD->hasUserDeclaredConstructor() && 
+          !RD->hasUserDeclaredDestructor()) {
+        continue;
+      }
+
       if (undecidedVBases.erase(overriddenBase)) {
         vtordispVBases.insert(overriddenBase);
         if (undecidedVBases.empty()) return;
Index: test/Sema/ms_class_layout.cpp
===================================================================
--- test/Sema/ms_class_layout.cpp       (revision 157602)
+++ test/Sema/ms_class_layout.cpp       (working copy)
@@ -505,4 +505,29 @@
 // CHECK-NEXT:  16 |       (A vftable pointer)
 // CHECK-NEXT:  sizeof=20, dsize=20, align=4
 // CHECK-NEXT:  nvsize=4, nvalign=4
+
+
+  struct first {
+    virtual void asdf() {}
+    virtual void g(){}
+       };
+       
+  struct second : virtual first {
+    int q;
+         virtual void asdf() { q = 90; }
+         virtual void g(){ q = 12; }
+  };
+       
+  struct third : virtual second {};
+       void test2() { third *t; }
+       
+// CHECK:        0 | struct test1::third
+// CHECK-NEXT:   0 |   (third vbtable pointer)
+// CHECK-NEXT:   4 |   struct test1::first (virtual base)
+// CHECK-NEXT:   4 |     (first vftable pointer)
+// CHECK-NEXT:   8 |   struct test1::second (virtual base)
+// CHECK-NEXT:   8 |     (second vbtable pointer)
+// CHECK-NEXT:  12 |     int q
+// CHECK-NEXT:  sizeof=16, dsize=16, align=4
+// CHECK-NEXT:  nvsize=4, nvalign=4
 }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to