aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDecl.cpp8
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp19
-rw-r--r--test/CXX/special/class.dtor/p3-0x.cpp6
3 files changed, 22 insertions, 11 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index fcff0b8ea0..aafab7d37b 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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();
}
}
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index cd58f32fd4..fc20403960 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -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),
diff --git a/test/CXX/special/class.dtor/p3-0x.cpp b/test/CXX/special/class.dtor/p3-0x.cpp
index ffac158acb..94b72a15e9 100644
--- a/test/CXX/special/class.dtor/p3-0x.cpp
+++ b/test/CXX/special/class.dtor/p3-0x.cpp
@@ -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() {}