Skip to content

Conversation

mizvekov
Copy link
Contributor

@mizvekov mizvekov commented Oct 5, 2025

The redundant notes were introduced with the workaround for finding the template instantiationa args for lambdas inside template type aliases.

This removes the notes for the cases where we are simply instantiating an outer template, and when diagnosing uses of the alias template.

Also adds comments calling the workaround explicitly.

@mizvekov mizvekov self-assigned this Oct 5, 2025
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Oct 5, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 5, 2025

@llvm/pr-subscribers-clang

Author: Matheus Izvekov (mizvekov)

Changes

The redundant notes were introduced with the workaround for finding the template instantiationa args for lambdas inside template type aliases.

This removes the notes for the cases where we are simply instantiating an outer template, and when diagnosing uses of the alias template.

Also adds comments calling the workaround explicitly.


Full diff: https://github.com/llvm/llvm-project/pull/161986.diff

5 Files Affected:

  • (modified) clang/lib/Sema/SemaTemplate.cpp (+9-4)
  • (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+6)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+10-8)
  • (modified) clang/test/SemaTemplate/alias-template-deprecated.cpp (+6-11)
  • (modified) clang/test/SemaTemplate/alias-templates.cpp (+8)
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..e0f65685d963a 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<TypeAliasTemplateDecl>(Active->Entity)
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e2dc70360506e..0fd34ee1d5e7b 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<TemplateArgument>()
-          : (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<TemplateArgument>());
   if (InstTemplate.isInvalid())
     return nullptr;
 
+  TypeAliasDecl *Pattern = D->getTemplatedDecl();
   TypeAliasTemplateDecl *PrevAliasTemplate = nullptr;
   if (getPreviousDeclForInstantiation<TypedefNameDecl>(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<int>;
 void bar() {
   NoAttr<int> 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<int> 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<UsingWithAttr<int>> 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<DepInt>;
 
-  // 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<int>().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<int> 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<bool, 2, 3>::p); // expected-note {{instantiation of}}
 }
+
+namespace OuterSubstFailure {
+  template <class T> struct A {
+      template <class> using B = T&;
+      // expected-error@-1 {{cannot form a reference to 'void'}}
+  };
+  template struct A<void>; // expected-note {{requested here}}
+} // namespace OuterSubstFailure

Copy link

github-actions bot commented Oct 5, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

…templates

The redundant notes were introduced with the workaround for finding
the template instantiationa args for lambdas inside template type aliases.

This removes the notes for the cases where we are simply instantiating an
outer template, and when diagnosing uses of the alias template.

Also adds comments calling the workaround explicitly.
@mizvekov mizvekov force-pushed the users/mizvekov/fix-template-alias-inst-redundant-note branch from 8530264 to 3ffd3e4 Compare October 5, 2025 01:09
@mizvekov mizvekov merged commit 4a2f29d into main Oct 5, 2025
9 checks passed
@mizvekov mizvekov deleted the users/mizvekov/fix-template-alias-inst-redundant-note branch October 5, 2025 20:58
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 6, 2025
…templates (llvm#161986)

The redundant notes were introduced with the workaround for finding the
template instantiationa args for lambdas inside template type aliases.

This removes the notes for the cases where we are simply instantiating
an outer template, and when diagnosing uses of the alias template.

Also adds comments calling the workaround explicitly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants