Skip to content

Commit eaee8aa

Browse files
authored
[Clang][Sema] fix a bug on template partial specialization (#89862)
attempt to fix #68885 (comment) 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)`. Co-authored-by: huqizhi <[email protected]>
1 parent 29dda26 commit eaee8aa

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ Bug Fixes to C++ Support
611611
immediate function context.
612612
- Fix CTAD for ``std::initializer_list``. This allows ``std::initializer_list{1, 2, 3}`` to be deduced as
613613
``std::initializer_list<int>`` as intended.
614+
- Fix a bug on template partial specialization whose template parameter is `decltype(auto)`.
614615

615616
Bug Fixes to AST Handling
616617
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7706,7 +7706,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
77067706
// FIXME: The language rules don't say what happens in this case.
77077707
// FIXME: We get an opaque dependent type out of decltype(auto) if the
77087708
// expression is merely instantiation-dependent; is this enough?
7709-
if (CTAK == CTAK_Deduced && Arg->isTypeDependent()) {
7709+
if (Arg->isTypeDependent()) {
77107710
auto *AT = dyn_cast<AutoType>(DeducedT);
77117711
if (AT && AT->isDecltypeAuto()) {
77127712
SugaredConverted = TemplateArgument(Arg);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
2+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
3+
4+
template <decltype(auto) a>
5+
struct S { // expected-note {{previous definition is here}}
6+
static constexpr int i = 42;
7+
};
8+
9+
template <decltype(auto) a>
10+
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}} \
11+
// expected-error {{redefinition of 'S'}}
12+
static constexpr int i = 0;
13+
};

0 commit comments

Comments
 (0)