From: Richard Smith Date: Tue, 4 Dec 2018 22:26:32 +0000 (+0000) Subject: Fix crash if an in-class explicit function specialization has explicit X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f8d79d803044ae1703b04edd8fc51f197e125499;p=clang Fix crash if an in-class explicit function specialization has explicit template arguments referring to template paramaeters. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@348313 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index f810c4eb31..f880d4616a 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2702,26 +2702,28 @@ Decl *TemplateDeclInstantiator::VisitUsingPackDecl(UsingPackDecl *D) { } Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl( - ClassScopeFunctionSpecializationDecl *Decl) { + ClassScopeFunctionSpecializationDecl *Decl) { CXXMethodDecl *OldFD = Decl->getSpecialization(); CXXMethodDecl *NewFD = cast_or_null(VisitCXXMethodDecl(OldFD, nullptr, true)); if (!NewFD) return nullptr; - LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName, - Sema::ForExternalRedeclaration); - - TemplateArgumentListInfo TemplateArgs; - TemplateArgumentListInfo *TemplateArgsPtr = nullptr; + TemplateArgumentListInfo ExplicitTemplateArgs; + TemplateArgumentListInfo *ExplicitTemplateArgsPtr = nullptr; if (Decl->hasExplicitTemplateArgs()) { - TemplateArgs = Decl->templateArgs(); - TemplateArgsPtr = &TemplateArgs; + if (SemaRef.Subst(Decl->templateArgs().getArgumentArray(), + Decl->templateArgs().size(), ExplicitTemplateArgs, + TemplateArgs)) + return nullptr; + ExplicitTemplateArgsPtr = &ExplicitTemplateArgs; } + LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName, + Sema::ForExternalRedeclaration); SemaRef.LookupQualifiedName(Previous, SemaRef.CurContext); - if (SemaRef.CheckFunctionTemplateSpecialization(NewFD, TemplateArgsPtr, - Previous)) { + if (SemaRef.CheckFunctionTemplateSpecialization( + NewFD, ExplicitTemplateArgsPtr, Previous)) { NewFD->setInvalidDecl(); return NewFD; } diff --git a/test/SemaTemplate/member-specialization.cpp b/test/SemaTemplate/member-specialization.cpp new file mode 100644 index 0000000000..ea30a7a0cd --- /dev/null +++ b/test/SemaTemplate/member-specialization.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++17 -verify %s +// expected-no-diagnostics + +template struct X { + template const V &as() { return V::error; } + template<> const U &as() { return u; } + U u; +}; +int f(X x) { + return x.as(); +}