[cfe-commits] Vtordisp for MS ABI.

r4start r4start at gmail.com
Tue May 29 03:57:22 PDT 2012


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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120529/11f2c4cf/attachment.html>
-------------- next part --------------
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
 }


More information about the cfe-commits mailing list