forked from OSchip/llvm-project
PR19372: Keep checking template arguments after we see an argument pack
expansion into a parameter pack; we know that we're still filling in that parameter's arguments. Previously, if we hit this case for an alias template, we'd try to substitute using non-canonical template arguments. llvm-svn: 221832
This commit is contained in:
parent
8870ad2439
commit
96d71c3936
|
@ -3695,12 +3695,12 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
ArgumentPack.size(), Converted))
|
||||
return true;
|
||||
|
||||
if (TemplateArgs[ArgIdx].getArgument().isPackExpansion() &&
|
||||
isa<TypeAliasTemplateDecl>(Template) &&
|
||||
!(Param + 1 == ParamEnd && (*Param)->isTemplateParameterPack() &&
|
||||
!getExpandedPackSize(*Param))) {
|
||||
bool PackExpansionIntoNonPack =
|
||||
TemplateArgs[ArgIdx].getArgument().isPackExpansion() &&
|
||||
(!(*Param)->isTemplateParameterPack() || getExpandedPackSize(*Param));
|
||||
if (PackExpansionIntoNonPack && isa<TypeAliasTemplateDecl>(Template)) {
|
||||
// Core issue 1430: we have a pack expansion as an argument to an
|
||||
// alias template, and it's not part of a final parameter pack. This
|
||||
// alias template, and it's not part of a parameter pack. This
|
||||
// can't be canonicalized, so reject it now.
|
||||
Diag(TemplateArgs[ArgIdx].getLocation(),
|
||||
diag::err_alias_template_expansion_into_fixed_list)
|
||||
|
@ -3723,16 +3723,11 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
++Param;
|
||||
}
|
||||
|
||||
// If we just saw a pack expansion, then directly convert the remaining
|
||||
// arguments, because we don't know what parameters they'll match up
|
||||
// with.
|
||||
if (TemplateArgs[ArgIdx-1].getArgument().isPackExpansion()) {
|
||||
bool InFinalParameterPack = Param != ParamEnd &&
|
||||
Param + 1 == ParamEnd &&
|
||||
(*Param)->isTemplateParameterPack() &&
|
||||
!getExpandedPackSize(*Param);
|
||||
|
||||
if (!InFinalParameterPack && !ArgumentPack.empty()) {
|
||||
// If we just saw a pack expansion into a non-pack, then directly convert
|
||||
// the remaining arguments, because we don't know what parameters they'll
|
||||
// match up with.
|
||||
if (PackExpansionIntoNonPack) {
|
||||
if (!ArgumentPack.empty()) {
|
||||
// If we were part way through filling in an expanded parameter pack,
|
||||
// fall back to just producing individual arguments.
|
||||
Converted.insert(Converted.end(),
|
||||
|
@ -3741,22 +3736,10 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
}
|
||||
|
||||
while (ArgIdx < NumArgs) {
|
||||
if (InFinalParameterPack)
|
||||
ArgumentPack.push_back(TemplateArgs[ArgIdx].getArgument());
|
||||
else
|
||||
Converted.push_back(TemplateArgs[ArgIdx].getArgument());
|
||||
Converted.push_back(TemplateArgs[ArgIdx].getArgument());
|
||||
++ArgIdx;
|
||||
}
|
||||
|
||||
// Push the argument pack onto the list of converted arguments.
|
||||
if (InFinalParameterPack && !ArgumentPack.empty()) {
|
||||
Converted.push_back(
|
||||
TemplateArgument::CreatePackCopy(Context,
|
||||
ArgumentPack.data(),
|
||||
ArgumentPack.size()));
|
||||
ArgumentPack.clear();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -178,3 +178,17 @@ namespace PR21536 {
|
|||
template<typename ...T> void f(S<T...>);
|
||||
void g() { f(S<int, int>()); }
|
||||
}
|
||||
|
||||
namespace PR19372 {
|
||||
template <template<typename...> class C, typename ...Us> struct BindBack {
|
||||
template <typename ...Ts> using apply = C<Ts..., Us...>;
|
||||
};
|
||||
template <typename, typename...> struct Y;
|
||||
template <typename ...Ts> using Z = Y<Ts...>;
|
||||
|
||||
using T = BindBack<Z, int>::apply<>;
|
||||
using T = Z<int>;
|
||||
|
||||
using U = BindBack<Z, int, int>::apply<char>;
|
||||
using U = Z<char, int, int>;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue