diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index dcf2876af81fc..419f3e1ad30ed 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3822,14 +3822,19 @@ QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword Keyword, AliasTemplate->getTemplateParameters()->getDepth()); LocalInstantiationScope Scope(*this); - InstantiatingTemplate Inst( - *this, /*PointOfInstantiation=*/TemplateLoc, - /*Entity=*/AliasTemplate, - /*TemplateArgs=*/TemplateArgLists.getInnermost()); // Diagnose uses of this alias. (void)DiagnoseUseOfDecl(AliasTemplate, TemplateLoc); + // FIXME: The TemplateArgs passed here are not used for the context note, + // nor they should, because this note will be pointing to the specialization + // anyway. These arguments are needed for a hack for instantiating lambdas + // in the pattern of the alias. In getTemplateInstantiationArgs, these + // arguments will be used for collating the template arguments needed to + // instantiate the lambda. + InstantiatingTemplate Inst(*this, /*PointOfInstantiation=*/TemplateLoc, + /*Entity=*/AliasTemplate, + /*TemplateArgs=*/CTAI.SugaredConverted); if (Inst.isInvalid()) return QualType(); diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 1f762ca64c05f..7b05e4cf1385f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1271,6 +1271,12 @@ void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) { PDiag(diag::note_building_deduction_guide_here)); break; case CodeSynthesisContext::TypeAliasTemplateInstantiation: + // Workaround for a workaround: don't produce a note if we are merely + // instantiating some other template which contains this alias template. + // This would be redundant either with the error itself, or some other + // context note attached to it. + if (Active->NumTemplateArgs == 0) + break; DiagFunc(Active->PointOfInstantiation, PDiag(diag::note_template_type_alias_instantiation_here) << cast(Active->Entity) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index e2dc70360506e..3819f775811e5 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1580,17 +1580,19 @@ Decl *TemplateDeclInstantiator::InstantiateTypeAliasTemplateDecl( if (!InstParams) return nullptr; - TypeAliasDecl *Pattern = D->getTemplatedDecl(); - Sema::InstantiatingTemplate InstTemplate( - SemaRef, D->getBeginLoc(), D, - D->getTemplateDepth() >= TemplateArgs.getNumLevels() - ? ArrayRef() - : (TemplateArgs.begin() + TemplateArgs.getNumLevels() - 1 - - D->getTemplateDepth()) - ->Args); + // FIXME: This is a hack for instantiating lambdas in the pattern of the + // alias. We are not really instantiating the alias at its template level, + // that only happens in CheckTemplateId, this is only for outer templates + // which contain it. In getTemplateInstantiationArgs, the template arguments + // used here would be used for collating the template arguments needed to + // instantiate the lambda. Pass an empty argument list, so this workaround + // doesn't get confused if there is an outer alias being instantiated. + Sema::InstantiatingTemplate InstTemplate(SemaRef, D->getBeginLoc(), D, + ArrayRef()); if (InstTemplate.isInvalid()) return nullptr; + TypeAliasDecl *Pattern = D->getTemplatedDecl(); TypeAliasTemplateDecl *PrevAliasTemplate = nullptr; if (getPreviousDeclForInstantiation(Pattern)) { DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); diff --git a/clang/test/SemaTemplate/alias-template-deprecated.cpp b/clang/test/SemaTemplate/alias-template-deprecated.cpp index 7418e222bcfc5..6dffd37d14909 100644 --- a/clang/test/SemaTemplate/alias-template-deprecated.cpp +++ b/clang/test/SemaTemplate/alias-template-deprecated.cpp @@ -46,23 +46,19 @@ using UsingInstWithCPPAttr [[deprecated("Do not use this")]] = NoAttr; void bar() { NoAttr obj; // Okay - // expected-warning@+2 {{'UsingWithAttr' is deprecated}} - // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}} + // expected-warning@+1 {{'UsingWithAttr' is deprecated}} UsingWithAttr objUsingWA; - // expected-warning@+2 {{'UsingWithAttr' is deprecated}} - // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}} + // expected-warning@+1 {{'UsingWithAttr' is deprecated}} NoAttr> s; // expected-note@+1 {{'DepInt' has been explicitly marked deprecated here}} using DepInt [[deprecated]] = int; - // expected-warning@+3 {{'UsingWithAttr' is deprecated}} - // expected-warning@+2 {{'DepInt' is deprecated}} - // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}} + // expected-warning@+2 {{'UsingWithAttr' is deprecated}} + // expected-warning@+1 {{'DepInt' is deprecated}} using X = UsingWithAttr; - // expected-warning@+2 {{'UsingWithAttr' is deprecated}} - // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}} + // expected-warning@+1 {{'UsingWithAttr' is deprecated}} UsingWithAttr().foo(); // expected-warning@+1 {{'UsingInstWithAttr' is deprecated}} @@ -74,8 +70,7 @@ void bar() { // expected-warning@+1 {{'UsingTDWithAttr' is deprecated}} UsingTDWithAttr objUTDWA; - // expected-warning@+2 {{'UsingWithCPPAttr' is deprecated}} - // expected-note@+1 {{in instantiation of template type alias 'UsingWithCPPAttr' requested here}} + // expected-warning@+1 {{'UsingWithCPPAttr' is deprecated}} UsingWithCPPAttr objUsingWCPPA; // expected-warning@+1 {{'UsingInstWithCPPAttr' is deprecated: Do not use this}} diff --git a/clang/test/SemaTemplate/alias-templates.cpp b/clang/test/SemaTemplate/alias-templates.cpp index ab5cad72faf1b..09fe72e9c7db0 100644 --- a/clang/test/SemaTemplate/alias-templates.cpp +++ b/clang/test/SemaTemplate/alias-templates.cpp @@ -312,3 +312,11 @@ namespace resolved_nttp { using TC2 = decltype(C::p); // expected-note {{instantiation of}} } + +namespace OuterSubstFailure { + template struct A { + template using B = T&; + // expected-error@-1 {{cannot form a reference to 'void'}} + }; + template struct A; // expected-note {{requested here}} +} // namespace OuterSubstFailure