Skip to content

Commit 4cc0bae

Browse files
authored
[clang] fix getReplacedTemplateParameter for partial specialziations (llvm#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 llvm#162770 Fixes llvm#162855
1 parent d95f8ff commit 4cc0bae

File tree

3 files changed

+41
-6
lines changed

3 files changed

+41
-6
lines changed

clang/lib/AST/DeclTemplate.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,20 +1670,25 @@ clang::getReplacedTemplateParameter(Decl *D, unsigned Index) {
16701670
auto P = CTSD->getSpecializedTemplateOrPartial();
16711671
TemplateParameterList *TPL;
16721672
if (const auto *CTPSD =
1673-
dyn_cast<ClassTemplatePartialSpecializationDecl *>(P))
1673+
dyn_cast<ClassTemplatePartialSpecializationDecl *>(P)) {
16741674
TPL = CTPSD->getTemplateParameters();
1675-
else
1676-
TPL = cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1675+
// FIXME: Obtain Args deduced for the partial specialization.
1676+
return {TPL->getParam(Index), {}};
1677+
}
1678+
TPL = cast<ClassTemplateDecl *>(P)->getTemplateParameters();
16771679
return {TPL->getParam(Index), CTSD->getTemplateArgs()[Index]};
16781680
}
16791681
case Decl::Kind::VarTemplateSpecialization: {
16801682
const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
16811683
auto P = VTSD->getSpecializedTemplateOrPartial();
16821684
TemplateParameterList *TPL;
1683-
if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl *>(P))
1685+
if (const auto *VTPSD =
1686+
dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) {
16841687
TPL = VTPSD->getTemplateParameters();
1685-
else
1686-
TPL = cast<VarTemplateDecl *>(P)->getTemplateParameters();
1688+
// FIXME: Obtain Args deduced for the partial specialization.
1689+
return {TPL->getParam(Index), {}};
1690+
}
1691+
TPL = cast<VarTemplateDecl *>(P)->getTemplateParameters();
16871692
return {TPL->getParam(Index), VTSD->getTemplateArgs()[Index]};
16881693
}
16891694
case Decl::Kind::ClassTemplatePartialSpecialization:

clang/test/SemaTemplate/concepts.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,3 +1476,20 @@ static_assert( requires {{ &f } -> C;} ); // expected-error {{reference to overl
14761476
// expected-error@-1 {{static assertion failed due to requirement 'requires { { &f() } -> C; }'}}
14771477

14781478
}
1479+
1480+
namespace GH162770 {
1481+
enum e {};
1482+
template<e> struct s {};
1483+
1484+
template<typename> struct specialized;
1485+
template<e x> struct specialized<s<x>> {
1486+
static auto make(auto) -> s<x>;
1487+
};
1488+
1489+
template<e x> struct check {
1490+
static constexpr auto m = requires { specialized<s<x>>::make(0); };
1491+
};
1492+
1493+
template<typename... Ts> auto comma = (..., Ts());
1494+
auto b = comma<check<e{}>>;
1495+
} // namespace GH162770

clang/test/SemaTemplate/partial-spec-instantiate.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,16 @@ namespace GH60778 {
152152
ClassTemplate<>::Nested<int> instantiation;
153153
}
154154
}
155+
#if __cplusplus >= 201103L
156+
namespace GH162855 {
157+
template <class...> using A = int;
158+
template <class, int> struct B;
159+
template <class...> struct C;
160+
template <template <class, int...> class TT, long... X>
161+
struct C<TT<int, X...>> {
162+
template <class... Y> using l = A<B<Y, X>...>;
163+
};
164+
template <class> struct D;
165+
template struct C<D<int>>;
166+
} // namespace GH162855
167+
#endif

0 commit comments

Comments
 (0)