[PATCH] D22034: [MSVC][DLL] use local vftable mangling only exported classes with virtual destructor

Dmitry Polukhin via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 6 00:15:35 PDT 2016


DmitryPolukhin created this revision.
DmitryPolukhin added a reviewer: rnk.
DmitryPolukhin added a subscriber: cfe-commits.

MSVC uses non-local mangling for vftable if class with dllexport attribute has no virtual destructor. I checked all examples that I fixed with MSVC and it uses '_7' in all cases. For more info see old thread in microsoft.public.vc.language: https://groups.google.com/d/msg/microsoft.public.vc.language/atSh_2VSc2w/EgJ3r_7OzVUJ

http://reviews.llvm.org/D22034

Files:
  lib/AST/MicrosoftMangle.cpp
  test/CodeGenCXX/PR26569.cpp
  test/CodeGenCXX/dllimport-rtti.cpp
  test/CodeGenCXX/dllimport.cpp

Index: test/CodeGenCXX/dllimport.cpp
===================================================================
--- test/CodeGenCXX/dllimport.cpp
+++ test/CodeGenCXX/dllimport.cpp
@@ -620,9 +620,18 @@
 struct __declspec(dllimport) W { virtual void foo() {} };
 USECLASS(W)
 // vftable:
-// MO1-DAG: @"\01??_SW@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo at W@@UAEXXZ" to i8*)]
+// MO1-DAG: @"\01??_7W@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo at W@@UAEXXZ" to i8*)]
 // GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
 
+struct __declspec(dllimport) W2 {
+  virtual ~W2();
+  virtual void foo() {}
+};
+USECLASS(W2)
+// vftable:
+// MO1-DAG: @"\01??_SW2@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// GO1-DAG: @_ZTV2W2 = external dllimport unnamed_addr constant [5 x i8*]
+
 struct __declspec(dllimport) KeyFuncClass {
   constexpr KeyFuncClass() {}
   virtual void foo();
Index: test/CodeGenCXX/dllimport-rtti.cpp
===================================================================
--- test/CodeGenCXX/dllimport-rtti.cpp
+++ test/CodeGenCXX/dllimport-rtti.cpp
@@ -4,8 +4,8 @@
 struct __declspec(dllimport) S {
   virtual void f() {}
 } s;
-// MSVC: [[VF_S:.*]] = private unnamed_addr constant [2 x i8*]
-// MSVC-DAG: @"\01??_SS@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VF_S]], i32 0, i32 1)
+// MSVC: [[VF_7:.*]] = private unnamed_addr constant [2 x i8*]
+// MSVC-DAG: @"\01??_7S@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VF_7]], i32 0, i32 1)
 // MSVC-DAG: @"\01??_R0?AUS@@@8" = linkonce_odr
 // MSVC-DAG: @"\01??_R1A@?0A at EA@S@@8" = linkonce_odr
 // MSVC-DAG: @"\01??_R2S@@8" = linkonce_odr
Index: test/CodeGenCXX/PR26569.cpp
===================================================================
--- test/CodeGenCXX/PR26569.cpp
+++ test/CodeGenCXX/PR26569.cpp
@@ -4,17 +4,17 @@
   virtual void m_fn1();
 };
 template <typename>
-class B : virtual A {};
+class B : public virtual A {};
 
 extern template class __declspec(dllimport) B<int>;
 class __declspec(dllexport) C : B<int> {};
 
 // CHECK-DAG: @[[VTABLE_C:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4C@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1 at A@@EAEXXZ" to i8*)]
-// CHECK-DAG: @[[VTABLE_B:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$B at H@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1 at A@@EAEXXZ" to i8*)], comdat($"\01??_S?$B at H@@6B@")
+// CHECK-DAG: @[[VTABLE_B:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$B at H@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1 at A@@EAEXXZ" to i8*)], comdat($"\01??_7?$B at H@@6B@")
 // CHECK-DAG: @[[VTABLE_A:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4A@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1 at A@@EAEXXZ" to i8*)], comdat($"\01??_7A@@6B@")
 
 // CHECK-DAG: @"\01??_7C@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_C]], i32 0, i32 1)
-// CHECK-DAG: @"\01??_S?$B at H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_B]], i32 0, i32 1)
+// CHECK-DAG: @"\01??_7?$B at H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_B]], i32 0, i32 1)
 // CHECK-DAG: @"\01??_7A@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_A]], i32 0, i32 1)
 
 // CHECK-DAG: @"\01??_8?$B at H@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -2601,7 +2601,15 @@
   // is always '6' for vftables.
   msvc_hashing_ostream MHO(Out);
   MicrosoftCXXNameMangler Mangler(*this, MHO);
-  if (Derived->hasAttr<DLLImportAttr>())
+  bool NeedLocalVFT = false;
+  if (Derived->hasAttr<DLLImportAttr>()) {
+    // Only dllimported classes with virtual d-tor may need local vtbl
+    // for proper memory deallocation without crossing DLL boundaries.
+    if (const CXXDestructorDecl *Destructor = Derived->getDestructor())
+      if (Destructor->isVirtual())
+        NeedLocalVFT = true;
+  }
+  if (NeedLocalVFT)
     Mangler.getStream() << "\01??_S";
   else
     Mangler.getStream() << "\01??_7";


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D22034.62826.patch
Type: text/x-patch
Size: 4684 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160706/f160e8b8/attachment.bin>


More information about the cfe-commits mailing list