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 | d372942d77540ccca7b5c222b3a69da2e37f6498 (patch) | |
tree | 73478f10dcedf61fee5d08ffe84416d16e02dd32 /clang/lib | |
parent | 925a6d08c5d405c5fb0d7198b3fee4a8c18a8f07 (diff) | |
download | bcm5719-llvm-d372942d77540ccca7b5c222b3a69da2e37f6498.tar.gz bcm5719-llvm-d372942d77540ccca7b5c222b3a69da2e37f6498.zip |
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.
llvm-svn: 155076
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 31 |
4 files changed, 19 insertions, 22 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 65ddc059fa7..cb4d336de15 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2195,7 +2195,7 @@ ASTContext::getFunctionType(QualType ResultTy, else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { Size += sizeof(Expr*); } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { - Size += sizeof(FunctionDecl*); + Size += 2 * sizeof(FunctionDecl*); } if (EPI.ConsumedArguments) Size += NumArgs * sizeof(bool); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 10c1adc875d..3f6a09457d1 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1550,7 +1550,8 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, // Store the function decl from which we will resolve our // exception specification. FunctionDecl **slot = reinterpret_cast<FunctionDecl**>(argSlot + numArgs); - *slot = epi.ExceptionSpecDecl; + slot[0] = epi.ExceptionSpecDecl; + slot[1] = epi.ExceptionSpecTemplate; // This exception specification doesn't make the type dependent, because // it's not instantiated as part of instantiating the type. } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 669ba3ad376..d2e0e6b63b4 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 4d312f855f5..c7bd99c1ca6 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/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(), |