summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-04-21 18:42:51 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-04-21 18:42:51 +0000
commit84973e56e3094d4b93d0f1eab9e251c239d6455c (patch)
treeb523e1b1f35717b3a8afcee8aa5f35383ea1fc35 /clang/lib/Sema
parent2568bf3089a5dd91bc6ae47934681d70c5e5c0f0 (diff)
downloadbcm5719-llvm-84973e56e3094d4b93d0f1eab9e251c239d6455c.tar.gz
bcm5719-llvm-84973e56e3094d4b93d0f1eab9e251c239d6455c.zip
Fix regression in r154844. If necessary, defer computing adjusted destructor
exception specifications in C++11 until after we've parsed the exception specifications for nested classes. llvm-svn: 155293
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp15
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp39
2 files changed, 37 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1550993079a..38bb852fa23 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9784,21 +9784,6 @@ void Sema::ActOnFields(Scope* S,
if (!Completed)
Record->completeDefinition();
- // Now that the record is complete, do any delayed exception spec checks
- // we were missing.
- while (!DelayedDestructorExceptionSpecChecks.empty()) {
- const CXXDestructorDecl *Dtor =
- DelayedDestructorExceptionSpecChecks.back().first;
- if (Dtor->getParent() != Record)
- break;
-
- assert(!Dtor->getParent()->isDependentType() &&
- "Should not ever add destructors of templates into the list.");
- CheckOverridingFunctionExceptionSpec(Dtor,
- DelayedDestructorExceptionSpecChecks.back().second);
- DelayedDestructorExceptionSpecChecks.pop_back();
- }
-
} else {
ObjCIvarDecl **ClsFields =
reinterpret_cast<ObjCIvarDecl**>(RecFields.data());
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 65c8bbe7cff..b6395f5dcbf 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7317,15 +7317,42 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
}
}
+/// \brief Perform any semantic analysis which needs to be delayed until all
+/// pending class member declarations have been parsed.
+void Sema::ActOnFinishCXXMemberDecls() {
+ // Now we have parsed all exception specifications, determine the implicit
+ // exception specifications for destructors.
+ for (unsigned i = 0, e = DelayedDestructorExceptionSpecs.size();
+ i != e; ++i) {
+ CXXDestructorDecl *Dtor = DelayedDestructorExceptionSpecs[i];
+ AdjustDestructorExceptionSpec(Dtor->getParent(), Dtor, true);
+ }
+ DelayedDestructorExceptionSpecs.clear();
+
+ // Perform any deferred checking of exception specifications for virtual
+ // destructors.
+ for (unsigned i = 0, e = DelayedDestructorExceptionSpecChecks.size();
+ i != e; ++i) {
+ const CXXDestructorDecl *Dtor =
+ DelayedDestructorExceptionSpecChecks[i].first;
+ assert(!Dtor->getParent()->isDependentType() &&
+ "Should not ever add destructors of templates into the list.");
+ CheckOverridingFunctionExceptionSpec(Dtor,
+ DelayedDestructorExceptionSpecChecks[i].second);
+ }
+ DelayedDestructorExceptionSpecChecks.clear();
+}
+
void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *classDecl,
- CXXDestructorDecl *destructor) {
+ CXXDestructorDecl *destructor,
+ bool WasDelayed) {
// C++11 [class.dtor]p3:
// A declaration of a destructor that does not have an exception-
// specification is implicitly considered to have the same exception-
// specification as an implicit declaration.
const FunctionProtoType *dtorType = destructor->getType()->
getAs<FunctionProtoType>();
- if (dtorType->hasExceptionSpec())
+ if (!WasDelayed && dtorType->hasExceptionSpec())
return;
ImplicitExceptionSpecification exceptSpec =
@@ -7342,6 +7369,14 @@ void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *classDecl,
destructor->setType(ty);
+ // If we can't compute the exception specification for this destructor yet
+ // (because it depends on an exception specification which we have not parsed
+ // yet), make a note that we need to try again when the class is complete.
+ if (epi.ExceptionSpecType == EST_Delayed) {
+ assert(!WasDelayed && "couldn't compute destructor exception spec");
+ DelayedDestructorExceptionSpecs.push_back(destructor);
+ }
+
// FIXME: If the destructor has a body that could throw, and the newly created
// spec doesn't allow exceptions, we should emit a warning, because this
// change in behavior can break conforming C++03 programs at runtime.
OpenPOWER on IntegriCloud