diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExceptionSpec.cpp | 19 |
3 files changed, 22 insertions, 21 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 61ee7702c07..b9aaf1616d6 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -680,7 +680,7 @@ void Sema::ActOnEndOfTranslationUnit() { // All delayed member exception specs should be checked or we end up accepting // incompatible declarations. assert(DelayedDefaultedMemberExceptionSpecs.empty()); - assert(DelayedDestructorExceptionSpecChecks.empty()); + assert(DelayedExceptionSpecChecks.empty()); // Remove file scoped decls that turned out to be used. UnusedFileScopedDecls.erase( diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 90ca97b5ca0..ec625346e82 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -5340,27 +5340,21 @@ void Sema::CheckExplicitlyDefaultedMemberExceptionSpec( } void Sema::CheckDelayedMemberExceptionSpecs() { - SmallVector<std::pair<const CXXDestructorDecl *, const CXXDestructorDecl *>, - 2> Checks; - SmallVector<std::pair<CXXMethodDecl *, const FunctionProtoType *>, 2> Specs; + decltype(DelayedExceptionSpecChecks) Checks; + decltype(DelayedDefaultedMemberExceptionSpecs) Specs; - std::swap(Checks, DelayedDestructorExceptionSpecChecks); + std::swap(Checks, DelayedExceptionSpecChecks); std::swap(Specs, DelayedDefaultedMemberExceptionSpecs); // Perform any deferred checking of exception specifications for virtual // destructors. - for (unsigned i = 0, e = Checks.size(); i != e; ++i) { - const CXXDestructorDecl *Dtor = Checks[i].first; - assert(!Dtor->getParent()->isDependentType() && - "Should not ever add destructors of templates into the list."); - CheckOverridingFunctionExceptionSpec(Dtor, Checks[i].second); - } + for (auto &Check : Checks) + CheckOverridingFunctionExceptionSpec(Check.first, Check.second); // Check that any explicitly-defaulted methods have exception specifications // compatible with their implicit exception specifications. - for (unsigned I = 0, N = Specs.size(); I != N; ++I) - CheckExplicitlyDefaultedMemberExceptionSpec(Specs[I].first, - Specs[I].second); + for (auto &Spec : Specs) + CheckExplicitlyDefaultedMemberExceptionSpec(Spec.first, Spec.second); } namespace { @@ -9298,7 +9292,7 @@ void Sema::ActOnFinishCXXMemberDecls() { if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(CurContext)) { if (Record->isInvalidDecl()) { DelayedDefaultedMemberExceptionSpecs.clear(); - DelayedDestructorExceptionSpecChecks.clear(); + DelayedExceptionSpecChecks.clear(); return; } } diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 7175c016734..2387325be43 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -801,6 +801,11 @@ bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) { bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, const CXXMethodDecl *Old) { + // If the new exception specification hasn't been parsed yet, skip the check. + // We'll get called again once it's been parsed. + if (New->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() == + EST_Unparsed) + return false; if (getLangOpts().CPlusPlus11 && isa<CXXDestructorDecl>(New)) { // Don't check uninstantiated template destructors at all. We can only // synthesize correct specs after the template is instantiated. @@ -809,16 +814,18 @@ bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, 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))); + DelayedExceptionSpecChecks.push_back(std::make_pair(New, Old)); return false; } } - // If the exception specification hasn't been parsed yet, skip the check. - // We'll get called again once it's been parsed. - if (New->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() == - EST_Unparsed) + // If the old exception specification hasn't been parsed yet, remember that + // we need to perform this check when we get to the end of the outermost + // lexically-surrounding class. + if (Old->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() == + EST_Unparsed) { + DelayedExceptionSpecChecks.push_back(std::make_pair(New, Old)); return false; + } unsigned DiagID = diag::err_override_exception_spec; if (getLangOpts().MicrosoftExt) DiagID = diag::ext_override_exception_spec; |