PR43547: substitute into the type of a non-type template parameter if

it's instantiation-dependent, even if it's not dependent.

There might be a SFINAE check in the parameter type.

llvm-svn: 373643
This commit is contained in:
Richard Smith 2019-10-03 18:24:40 +00:00
parent 6fb03a290b
commit 8d2eaf9239
2 changed files with 13 additions and 3 deletions

View File

@ -4922,9 +4922,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
if (NTTP->isParameterPack() && NTTP->isExpandedParameterPack())
NTTPType = NTTP->getExpansionType(ArgumentPackIndex);
// FIXME: Do we need to substitute into parameters here if they're
// instantiation-dependent but not dependent?
if (NTTPType->isDependentType() &&
if (NTTPType->isInstantiationDependentType() &&
!isa<TemplateTemplateParmDecl>(Template) &&
!Template->getDeclContext()->isDependentContext()) {
// Do substitution on the type of the non-type template parameter.

View File

@ -482,3 +482,15 @@ namespace dependent_backreference {
template<short S> void a() { X<short, S, &arr> x; }
template<short S> void b() { X<int, S, &arr> x; } // expected-note {{substituting}}
}
namespace instantiation_dependent {
template<typename T, __typeof(sizeof(T))> void f(int);
template<typename T, __typeof(sizeof(0))> int &f(...);
int &rf = f<struct incomplete, 0>(0);
// FIXME: This fails because we mishandle instantiation-dependent array bounds :(
int arr[sizeof(sizeof(int))];
template<typename T, int (*)[sizeof(sizeof(T))]> void g(int);
template<typename T, int (*)[sizeof(sizeof(int))]> int &g(...);
int &rg = g<struct incomplete, &arr>(0); // expected-error {{cannot bind}}
}