]> granicus.if.org Git - clang/commitdiff
Fix PR9941 for out-of-line template destructors too.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Fri, 20 May 2011 05:57:18 +0000 (05:57 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Fri, 20 May 2011 05:57:18 +0000 (05:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131722 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaExceptionSpec.cpp
test/CXX/special/class.dtor/p3-0x.cpp

index fcff0b8ea0d9b2d166b4c1fa34e72d0ed71ea7f8..aafab7d37b85cc70506bc7a6002061b35ff9a40d 100644 (file)
@@ -8200,10 +8200,10 @@ void Sema::ActOnFields(Scope* S,
       const CXXDestructorDecl *Dtor =
               DelayedDestructorExceptionSpecChecks.back().first;
       if (Dtor->getParent() == Record) {
-        // Don't check if we're a template. The spec hasn't been adjusted.
-        if (!Dtor->getParent()->isDependentType())
-          CheckOverridingFunctionExceptionSpec(Dtor,
-              DelayedDestructorExceptionSpecChecks.back().second);
+        assert(!Dtor->getParent()->isDependentType() &&
+            "Should not ever add destructors of templates into the list.");
+        CheckOverridingFunctionExceptionSpec(Dtor,
+            DelayedDestructorExceptionSpecChecks.back().second);
         DelayedDestructorExceptionSpecChecks.pop_back();
       }
     }
index cd58f32fd4814867ac7f5fdabbd755d8bf6e41a5..fc2040396046b734e48e0744b62fcf886ad36c21 100644 (file)
@@ -701,13 +701,18 @@ bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType)
 
 bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
                                                 const CXXMethodDecl *Old) {
-  if (getLangOptions().CPlusPlus0x && New->getParent()->isBeingDefined() &&
-      isa<CXXDestructorDecl>(New)) {
-    // The destructor might be updated once the definition is finished. So
-    // remember it and check later.
-    DelayedDestructorExceptionSpecChecks.push_back(std::make_pair(
-      cast<CXXDestructorDecl>(New), cast<CXXDestructorDecl>(Old)));
-    return false;
+  if (getLangOptions().CPlusPlus0x && isa<CXXDestructorDecl>(New)) {
+    // Don't check uninstantiated template destructors at all. We can only
+    // synthesize correct specs after the template is instantiated.
+    if (New->getParent()->isDependentType())
+      return false;
+    if (New->getParent()->isBeingDefined()) {
+      // The destructor might be updated once the definition is finished. So
+      // remember it and check later.
+      DelayedDestructorExceptionSpecChecks.push_back(std::make_pair(
+        cast<CXXDestructorDecl>(New), cast<CXXDestructorDecl>(Old)));
+      return false;
+    }
   }
   return CheckExceptionSpecSubset(PDiag(diag::err_override_exception_spec),
                                   PDiag(diag::note_overridden_virtual_function),
index ffac158acb6f16c1b1ddafd858b5e867b7bd6e56..94b72a15e9392686bb0375570998cd582865bd10 100644 (file)
@@ -169,3 +169,9 @@ void tsw() {
 // CHECK: _ZTIi
 // CHECK: __cxa_call_unexpected
 // CHECK: define linkonce_odr void @_ZN2SwIiED1Ev({{.*}} nounwind
+
+template <typename T>
+struct TVC : VX
+{ virtual ~TVC(); };
+template <typename T>
+TVC<T>::~TVC() {}