[clang] fix getReplacedTemplateParameter for partial specialziations (#162955)

The template argument returned should be relative to the partial
specialization, which would correspond to the partial template parameter
list.

Unfortunately we don't save this anywhere in the AST, and would
otherwise need to deduce them again.

Simply avoid providing this argument for now, until we make it
available.

This fixes regressions which were never released, so there are no
release notes.

Fixes #162770
Fixes #162855
This commit is contained in:
Matheus Izvekov
2025-10-10 23:00:36 -03:00
committed by GitHub
parent d95f8ffee4
commit 4cc0bae159
3 changed files with 41 additions and 6 deletions

View File

@@ -1670,20 +1670,25 @@ clang::getReplacedTemplateParameter(Decl *D, unsigned Index) {
auto P = CTSD->getSpecializedTemplateOrPartial();
TemplateParameterList *TPL;
if (const auto *CTPSD =
dyn_cast<ClassTemplatePartialSpecializationDecl *>(P))
dyn_cast<ClassTemplatePartialSpecializationDecl *>(P)) {
TPL = CTPSD->getTemplateParameters();
else
TPL = cast<ClassTemplateDecl *>(P)->getTemplateParameters();
// FIXME: Obtain Args deduced for the partial specialization.
return {TPL->getParam(Index), {}};
}
TPL = cast<ClassTemplateDecl *>(P)->getTemplateParameters();
return {TPL->getParam(Index), CTSD->getTemplateArgs()[Index]};
}
case Decl::Kind::VarTemplateSpecialization: {
const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
auto P = VTSD->getSpecializedTemplateOrPartial();
TemplateParameterList *TPL;
if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl *>(P))
if (const auto *VTPSD =
dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) {
TPL = VTPSD->getTemplateParameters();
else
TPL = cast<VarTemplateDecl *>(P)->getTemplateParameters();
// FIXME: Obtain Args deduced for the partial specialization.
return {TPL->getParam(Index), {}};
}
TPL = cast<VarTemplateDecl *>(P)->getTemplateParameters();
return {TPL->getParam(Index), VTSD->getTemplateArgs()[Index]};
}
case Decl::Kind::ClassTemplatePartialSpecialization:

View File

@@ -1476,3 +1476,20 @@ static_assert( requires {{ &f } -> C;} ); // expected-error {{reference to overl
// expected-error@-1 {{static assertion failed due to requirement 'requires { { &f() } -> C; }'}}
}
namespace GH162770 {
enum e {};
template<e> struct s {};
template<typename> struct specialized;
template<e x> struct specialized<s<x>> {
static auto make(auto) -> s<x>;
};
template<e x> struct check {
static constexpr auto m = requires { specialized<s<x>>::make(0); };
};
template<typename... Ts> auto comma = (..., Ts());
auto b = comma<check<e{}>>;
} // namespace GH162770

View File

@@ -152,3 +152,16 @@ namespace GH60778 {
ClassTemplate<>::Nested<int> instantiation;
}
}
#if __cplusplus >= 201103L
namespace GH162855 {
template <class...> using A = int;
template <class, int> struct B;
template <class...> struct C;
template <template <class, int...> class TT, long... X>
struct C<TT<int, X...>> {
template <class... Y> using l = A<B<Y, X>...>;
};
template <class> struct D;
template struct C<D<int>>;
} // namespace GH162855
#endif