[clang] [Clang][Sema] fix a bug on template partial specialization (PR #89862)

via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 23 19:52:33 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Qizhi Hu (jcsxky)

<details>
<summary>Changes</summary>

attempt to fix https://github.com/llvm/llvm-project/issues/68885#issuecomment-1764201896
Deduction of NTTP whose type is `decltype(auto)` would create an implicit cast expression to dependent type and makes the type of primary template definition (`InjectedClassNameSpecialization`) and its partial specialization different. Prevent emitting cast expression to make clang knows their types are identical by removing `CTAK == CTAK_Deduced` when the type is `decltype(auto)`.

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


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+1-1) 
- (added) clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp (+13) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3db558a1c11a3f..27341fb0e3a772 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -561,6 +561,7 @@ Bug Fixes to C++ Support
 - Fixed a crash when trying to evaluate a user-defined ``static_assert`` message whose ``size()``
   function returns a large or negative value. Fixes (#GH89407).
 - Fixed a use-after-free bug in parsing of type constraints with default arguments that involve lambdas. (#GH67235)
+- Fix a bug on template partial specialization whose template parameter is `decltype(auto)`.
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 4bda31ba67c02d..345d77849b49d0 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7706,7 +7706,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
     // FIXME: The language rules don't say what happens in this case.
     // FIXME: We get an opaque dependent type out of decltype(auto) if the
     // expression is merely instantiation-dependent; is this enough?
-    if (CTAK == CTAK_Deduced && Arg->isTypeDependent()) {
+    if (Arg->isTypeDependent()) {
       auto *AT = dyn_cast<AutoType>(DeducedT);
       if (AT && AT->isDecltypeAuto()) {
         SugaredConverted = TemplateArgument(Arg);
diff --git a/clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp b/clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp
new file mode 100644
index 00000000000000..ad51ca8252ef50
--- /dev/null
+++ b/clang/test/SemaCXX/identical-type-primary-partial-specialization.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+template <decltype(auto) a>
+struct S { // expected-note {{previous definition is here}}
+    static constexpr int i = 42;
+};
+
+template <decltype(auto) a>
+struct S<a> { // expected-error {{class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}} \
+              // expected-error {{redefinition of 'S'}}
+    static constexpr int i = 0;
+};

``````````

</details>


https://github.com/llvm/llvm-project/pull/89862


More information about the cfe-commits mailing list