forked from OSchip/llvm-project
Check and build conversion sequences for non-type template arguments in
dependent contexts when processing the template in C++11 and C++14, just like we do in C++98 and C++1z. This allows us to diagnose invalid templates earlier. llvm-svn: 290567
This commit is contained in:
parent
7f8540b5e7
commit
01bfa68fec
|
@ -5382,7 +5382,7 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
|
|||
|
||||
APValue V;
|
||||
auto R = ::CheckConvertedConstantExpression(*this, From, T, V, CCE, true);
|
||||
if (!R.isInvalid())
|
||||
if (!R.isInvalid() && !R.get()->isValueDependent())
|
||||
Value = V.getInt();
|
||||
return R;
|
||||
}
|
||||
|
|
|
@ -5076,8 +5076,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
|
|||
// For a value-dependent argument, CheckConvertedConstantExpression is
|
||||
// permitted (and expected) to be unable to determine a value.
|
||||
if (ArgResult.get()->isValueDependent()) {
|
||||
Converted = TemplateArgument(Arg);
|
||||
return Arg;
|
||||
Converted = TemplateArgument(ArgResult.get());
|
||||
return ArgResult;
|
||||
}
|
||||
|
||||
QualType CanonParamType = Context.getCanonicalType(ParamType);
|
||||
|
@ -5184,14 +5184,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
|
|||
// conversions (4.7) are applied.
|
||||
|
||||
if (getLangOpts().CPlusPlus11) {
|
||||
// We can't check arbitrary value-dependent arguments.
|
||||
// FIXME: If there's no viable conversion to the template parameter type,
|
||||
// we should be able to diagnose that prior to instantiation.
|
||||
if (Arg->isValueDependent()) {
|
||||
Converted = TemplateArgument(Arg);
|
||||
return Arg;
|
||||
}
|
||||
|
||||
// C++ [temp.arg.nontype]p1:
|
||||
// A template-argument for a non-type, non-template template-parameter
|
||||
// shall be one of:
|
||||
|
@ -5206,6 +5198,12 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
|
|||
if (ArgResult.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
// We can't check arbitrary value-dependent arguments.
|
||||
if (ArgResult.get()->isValueDependent()) {
|
||||
Converted = TemplateArgument(ArgResult.get());
|
||||
return ArgResult;
|
||||
}
|
||||
|
||||
// Widen the argument value to sizeof(parameter type). This is almost
|
||||
// always a no-op, except when the parameter type is bool. In
|
||||
// that case, this may extend the argument from 1 bit to 8 bits.
|
||||
|
|
|
@ -27,3 +27,12 @@ namespace CanonicalNullptr {
|
|||
namespace Auto {
|
||||
template<auto> struct A { }; // expected-error {{until C++1z}}
|
||||
}
|
||||
|
||||
namespace check_conversion_early {
|
||||
struct X {};
|
||||
template<int> struct A {};
|
||||
template<X &x> struct A<x> {}; // expected-error {{not implicitly convertible}}
|
||||
|
||||
struct Y { constexpr operator int() const { return 0; } };
|
||||
template<Y &y> struct A<y> {}; // expected-error {{depends on a template parameter of the partial specialization}}
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ namespace DeduceDifferentType {
|
|||
struct Z { constexpr operator Y&() { return y; } } z;
|
||||
constexpr Y::operator Z&() { return z; }
|
||||
template<Y &> struct D {};
|
||||
template<Z &z> int d(D<z>); // expected-note {{does not have the same type}}
|
||||
template<Z &z> int d(D<z>); // expected-note {{couldn't infer template argument 'z'}}
|
||||
int d_imp = d(D<y>()); // expected-error {{no matching function}}
|
||||
int d_exp = d<y>(D<y>());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue