diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-04-19 00:08:28 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-04-19 00:08:28 +0000 |
commit | 13bffc532bafd45d4a77867993c1afb83c7661be (patch) | |
tree | 147f1e50c494e1a5616b3cf157381308109aeb19 /lib/Sema | |
parent | 103f41d0e72a9e52a07e19cbde58c3afc8735098 (diff) |
PR 12586: Fix assert while running libc++ testsuite: deal with exception
specifications on member function templates of class templates and other such
nested beasties. Store the function template from which we are to instantiate
an exception specification rather than trying to deduce it. Plus some
additional test cases.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155076 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 31 |
2 files changed, 16 insertions, 20 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 669ba3ad37..d2e0e6b63b 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9776,9 +9776,8 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { // Instantiate the exception specification for any function which is // used: CodeGen will need it. - if (Func->getTemplateInstantiationPattern() && - Func->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() - == EST_Uninstantiated) + const FunctionProtoType *FPT = Func->getType()->getAs<FunctionProtoType>(); + if (FPT && FPT->getExceptionSpecType() == EST_Uninstantiated) InstantiateExceptionSpec(Loc, Func); // Implicit instantiation of function templates and member functions of diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 4d312f855f..c7bd99c1ca 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2251,6 +2251,8 @@ static void addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function, static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, const FunctionProtoType *Proto, const MultiLevelTemplateArgumentList &TemplateArgs) { + assert(Proto->getExceptionSpecType() != EST_Uninstantiated); + // C++11 [expr.prim.general]p3: // If a declaration declares a member function or member function // template of a class X, the expression this is a prvalue of type @@ -2377,20 +2379,8 @@ static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, FunctionDecl *Decl) { - // Find the template declaration which contains the exception specification. - // Per [except.spec]p4, prefer the exception spec on the primary template - // if this is an explicit instantiation. - FunctionDecl *Tmpl = 0; - if (Decl->getPrimaryTemplate()) - Tmpl = Decl->getPrimaryTemplate()->getTemplatedDecl(); - else if (FunctionDecl *MemTmpl = Decl->getInstantiatedFromMemberFunction()) - Tmpl = MemTmpl; - else - Tmpl = Decl->getTemplateInstantiationPattern(); - assert(Tmpl && "can't instantiate non-template"); - - if (Decl->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() - != EST_Uninstantiated) + const FunctionProtoType *Proto = Decl->getType()->castAs<FunctionProtoType>(); + if (Proto->getExceptionSpecType() != EST_Uninstantiated) return; InstantiatingTemplate Inst(*this, PointOfInstantiation, Decl, @@ -2406,10 +2396,12 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, MultiLevelTemplateArgumentList TemplateArgs = getTemplateInstantiationArgs(Decl, 0, /*RelativeToPrimary*/true); - addInstantiatedParametersToScope(*this, Decl, Tmpl, Scope, TemplateArgs); + FunctionDecl *Template = Proto->getExceptionSpecTemplate(); + addInstantiatedParametersToScope(*this, Decl, Template, Scope, TemplateArgs); - const FunctionProtoType *Proto = Tmpl->getType()->castAs<FunctionProtoType>(); - ::InstantiateExceptionSpec(*this, Decl, Proto, TemplateArgs); + ::InstantiateExceptionSpec(*this, Decl, + Template->getType()->castAs<FunctionProtoType>(), + TemplateArgs); } /// \brief Initializes the common fields of an instantiation function @@ -2457,6 +2449,10 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, EPI.ExceptionSpecType != EST_None && EPI.ExceptionSpecType != EST_DynamicNone && EPI.ExceptionSpecType != EST_BasicNoexcept) { + FunctionDecl *ExceptionSpecTemplate = Tmpl; + if (EPI.ExceptionSpecType == EST_Uninstantiated) + ExceptionSpecTemplate = EPI.ExceptionSpecTemplate; + // Mark the function has having an uninstantiated exception specification. const FunctionProtoType *NewProto = New->getType()->getAs<FunctionProtoType>(); @@ -2464,6 +2460,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, EPI = NewProto->getExtProtoInfo(); EPI.ExceptionSpecType = EST_Uninstantiated; EPI.ExceptionSpecDecl = New; + EPI.ExceptionSpecTemplate = ExceptionSpecTemplate; New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(), NewProto->arg_type_begin(), NewProto->getNumArgs(), |