diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 5b93e513ea..9e9fda791f 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -3542,7 +3542,7 @@ public:
const QualType *data() const { return Exceptions.data(); }
/// \brief Integrate another called method into the collected data.
- void CalledDecl(SourceLocation CallLoc, CXXMethodDecl *Method);
+ void CalledDecl(SourceLocation CallLoc, const CXXMethodDecl *Method);
/// \brief Integrate an invoked expression into the collected data.
void CalledExpr(Expr *E);
@@ -3606,7 +3606,7 @@ public:
/// \brief Determine what sort of exception specification an inheriting
/// constructor of a class will have.
ImplicitExceptionSpecification
- ComputeInheritingCtorExceptionSpec(CXXMethodDecl *MD);
+ ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD);
/// \brief Evaluate the implicit exception specification for a defaulted
/// special member function.
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 5666c0a8d3..0bea565f93 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -145,8 +145,9 @@ namespace {
}
}
-void Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc,
- CXXMethodDecl *Method) {
+void
+Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc,
+ const CXXMethodDecl *Method) {
// If we have an MSAny spec already, don't bother.
if (!Method || ComputedEST == EST_MSAny)
return;
@@ -7522,9 +7523,73 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc,
}
Sema::ImplicitExceptionSpecification
-Sema::ComputeInheritingCtorExceptionSpec(CXXMethodDecl *MD) {
+Sema::ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD) {
+ CXXRecordDecl *ClassDecl = CD->getParent();
+
+ // C++ [except.spec]p14:
+ // An inheriting constructor [...] shall have an exception-specification. [...]
ImplicitExceptionSpecification ExceptSpec(*this);
- // FIXME: Compute the exception spec.
+ if (ClassDecl->isInvalidDecl())
+ return ExceptSpec;
+
+ // Inherited constructor.
+ const CXXConstructorDecl *InheritedCD = CD->getInheritedConstructor();
+ const CXXRecordDecl *InheritedDecl = InheritedCD->getParent();
+ // FIXME: Copying or moving the parameters could add extra exceptions to the
+ // set, as could the default arguments for the inherited constructor. This
+ // will be addressed when we implement the resolution of core issue 1351.
+ ExceptSpec.CalledDecl(CD->getLocStart(), InheritedCD);
+
+ // Direct base-class constructors.
+ for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(),
+ BEnd = ClassDecl->bases_end();
+ B != BEnd; ++B) {
+ if (B->isVirtual()) // Handled below.
+ continue;
+
+ if (const RecordType *BaseType = B->getType()->getAs