Skip to content

[clang] Distinguish NTTPs with deduced types in variable template partial specializations #152864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

keinflue
Copy link
Contributor

@keinflue keinflue commented Aug 9, 2025

If a template argument in a partial specialization of a variable template directly refers to a NTTP of the specialization without implicit type conversion it was assumed that the NTTP is identical to that of the primary template.

This doesn't hold if the primary template's NTTP uses a deduced type, so instead compare the types explicitly as well.

The affected function is used only to provide an improved early error if the partial specialization has identical template arguments to the primary template. The actual check that the partial specialization is more specialized happens later.

Fixes #118190
Fixes #152750

…tial specializations

If a template argument in a partial specialization of a variable template directly refers to a NTTP of the
specialization without implicit type conversion it was assumed that the NTTP is identical to that of the
primary template.

This doesn't hold if the primary template's NTTP uses a deduced type, so instead compare the types explicitly
as well.

Fixes llvm#118190
Fixes llvm#152750
Also remove unused and potentially confusing paramter from isTemplateArgumentTemplateParamter.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Aug 9, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 9, 2025

@llvm/pr-subscribers-clang

Author: None (keinflue)

Changes

If a template argument in a partial specialization of a variable template directly refers to a NTTP of the specialization without implicit type conversion it was assumed that the NTTP is identical to that of the primary template.

This doesn't hold if the primary template's NTTP uses a deduced type, so instead compare the types explicitly as well.

The affected function is used only to provide an improved early error if the partial specialization has identical template arguments to the primary template. The actual check that the partial specialization is more specialized happens later.

Fixes #118190
Fixes #152750


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

2 Files Affected:

  • (modified) clang/lib/Sema/SemaTemplate.cpp (+5-1)
  • (modified) clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp (+5)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 2d8fdb5b766fc..ae16323535bdc 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4126,7 +4126,11 @@ static bool isTemplateArgumentTemplateParameter(const TemplateArgument &Arg,
       return false;
     const NonTypeTemplateParmDecl *NTTP =
         dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl());
-    return NTTP && NTTP->getDepth() == Depth && NTTP->getIndex() == Index;
+    if (!NTTP || NTTP->getDepth() != Depth || NTTP->getIndex() != Index)
+      return false;
+    QualType ParamType = cast<NonTypeTemplateParmDecl>(Param)->getType();
+    QualType NTTPType = NTTP->getType();
+    return ParamType.getCanonicalType() == NTTPType.getCanonicalType();
   }
 
   case TemplateArgument::Template:
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
index c35743b87adbc..9c25e26f43c36 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -621,3 +621,8 @@ namespace GH73460 {
   int j;
   template struct A<int&, j, j>;
 } // namespace GH73460
+
+namespace GH118190 {
+  template <auto> int x;
+  template <int i> int x<i>;
+}

@keinflue keinflue requested a review from mizvekov August 9, 2025 20:40
Copy link
Contributor

@mizvekov mizvekov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, Thanks.

These regressions were never in a released clang right? If that's the case, it's fine not to add anything to the change log.

@keinflue
Copy link
Contributor Author

keinflue commented Aug 9, 2025

@mizvekov This is not a regression, the bug has been present since the introduction of auto non-type template parameters, i.e. Clang 4.

Also, I do not have commit access. If you can land the PR for me, please do so.

@mizvekov
Copy link
Contributor

mizvekov commented Aug 9, 2025

@mizvekov This is not a regression, the bug has been present since the introduction of auto non-type template parameters, i.e. Clang 4.

Alright, then this should be mentioned in the release notes.

@mizvekov
Copy link
Contributor

mizvekov commented Aug 9, 2025

Also, I do not have commit access. If you can land the PR for me, please do so.

Sure, I'll do it as soon as this has a release note.

@mizvekov mizvekov merged commit 4c0a7b7 into llvm:main Aug 9, 2025
10 checks passed
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
3 participants