]> granicus.if.org Git - clang/commitdiff
Make sure CheckDestructor gets called on dllimported classes if the vtable is used...
authorHans Wennborg <hans@hanshq.net>
Wed, 13 Apr 2016 20:21:15 +0000 (20:21 +0000)
committerHans Wennborg <hans@hanshq.net>
Wed, 13 Apr 2016 20:21:15 +0000 (20:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@266242 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
test/CodeGenCXX/dllimport.cpp

index 995378c073b4118e6fc7f2c2da6b13766715c8d9..40be8d6456228ea88c8a6324ee123450f5c4fa88 100644 (file)
@@ -13314,13 +13314,20 @@ void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
     // the deleting destructor is emitted with the vtable, not with the
     // destructor definition as in the Itanium ABI.
     // If it has a definition, we do the check at that point instead.
-    if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
-        Class->hasUserDeclaredDestructor() &&
-        !Class->getDestructor()->isDefined() &&
-        !Class->getDestructor()->isDeleted()) {
-      CXXDestructorDecl *DD = Class->getDestructor();
-      ContextRAII SavedContext(*this, DD);
-      CheckDestructor(DD);
+    if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+      if (Class->hasUserDeclaredDestructor() &&
+          !Class->getDestructor()->isDefined() &&
+          !Class->getDestructor()->isDeleted()) {
+        CXXDestructorDecl *DD = Class->getDestructor();
+        ContextRAII SavedContext(*this, DD);
+        CheckDestructor(DD);
+      } else if (Class->hasAttr<DLLImportAttr>()) {
+        // We always synthesize vtables on the import side. To make sure
+        // CheckDestructor gets called, mark the destructor referenced.
+        assert(Class->getDestructor() &&
+               "The destructor has always been declared on a dllimport class");
+        MarkFunctionReferenced(Loc, Class->getDestructor());
+      }
     }
   }
 
index 433628f9c23f7719921838e236f8ca129b0e0b8b..2b159207a51b0709193c76fed4eb224b7e48f1aa 100644 (file)
@@ -743,6 +743,17 @@ namespace PR21366 {
   inline void S::outOfClassInlineMethod() {}
 }
 
+namespace PR27319 {
+  // Make sure we don't assert due to not having checked for operator delete on
+  // the destructor.
+  template <typename> struct A {
+    virtual ~A() = default;
+  };
+  extern template struct __declspec(dllimport) A<int>;
+  void f() { new A<int>(); }
+  // MO1-DAG: @"\01??_S?$A@H@PR27319@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*]
+}
+
 // MS ignores DLL attributes on partial specializations.
 template <typename T> struct PartiallySpecializedClassTemplate {};
 template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f(); };