forked from OSchip/llvm-project
Fix assertion failure for a cv-qualified array as a non-type template
parameter type. We were both failing to decay the array type to a pointer and failing to remove the top-level cv-qualifications. Fix this by decaying array parameters even if the parameter type is dependent. llvm-svn: 374496
This commit is contained in:
parent
4227c62bc7
commit
9d1eba184e
|
@ -1099,9 +1099,6 @@ QualType Sema::CheckNonTypeTemplateParameterType(QualType T,
|
|||
T->isMemberPointerType() ||
|
||||
// -- std::nullptr_t.
|
||||
T->isNullPtrType() ||
|
||||
// If T is a dependent type, we can't do the check now, so we
|
||||
// assume that it is well-formed.
|
||||
T->isDependentType() ||
|
||||
// Allow use of auto in template parameter declarations.
|
||||
T->isUndeducedType()) {
|
||||
// C++ [temp.param]p5: The top-level cv-qualifiers on the template-parameter
|
||||
|
@ -1114,9 +1111,18 @@ QualType Sema::CheckNonTypeTemplateParameterType(QualType T,
|
|||
// A non-type template-parameter of type "array of T" or
|
||||
// "function returning T" is adjusted to be of type "pointer to
|
||||
// T" or "pointer to function returning T", respectively.
|
||||
else if (T->isArrayType() || T->isFunctionType())
|
||||
if (T->isArrayType() || T->isFunctionType())
|
||||
return Context.getDecayedType(T);
|
||||
|
||||
// If T is a dependent type, we can't do the check now, so we
|
||||
// assume that it is well-formed. Note that stripping off the
|
||||
// qualifiers here is not really correct if T turns out to be
|
||||
// an array type, but we'll recompute the type everywhere it's
|
||||
// used during instantiation, so that should be OK. (Using the
|
||||
// qualified type is equally wrong.)
|
||||
if (T->isDependentType())
|
||||
return T.getUnqualifiedType();
|
||||
|
||||
Diag(Loc, diag::err_template_nontype_parm_bad_type)
|
||||
<< T;
|
||||
|
||||
|
|
|
@ -493,3 +493,16 @@ namespace instantiation_dependent {
|
|||
template<typename T, int (*)[sizeof(sizeof(int))]> int &g(...);
|
||||
int &rg = g<struct incomplete, &arr>(0);
|
||||
}
|
||||
|
||||
namespace complete_array_from_incomplete {
|
||||
template <typename T, const char* const A[static_cast<int>(T::kNum)]>
|
||||
class Base {};
|
||||
template <class T, const char* const A[]>
|
||||
class Derived : public Base<T, A> {};
|
||||
|
||||
struct T {
|
||||
static const int kNum = 3;
|
||||
};
|
||||
extern const char *const kStrs[3] = {};
|
||||
Derived<T, kStrs> d;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue