Author: rsmith Date: Mon Dec 26 20:02:09 2016 New Revision: 290567 URL: http://llvm.org/viewvc/llvm-project?rev=290567&view=rev Log: 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.
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx11.cpp cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=290567&r1=290566&r2=290567&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Dec 26 20:02:09 2016 @@ -5382,7 +5382,7 @@ ExprResult Sema::CheckConvertedConstantE 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; } Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=290567&r1=290566&r2=290567&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Dec 26 20:02:09 2016 @@ -5076,8 +5076,8 @@ ExprResult Sema::CheckTemplateArgument(N // 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(N // 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(N 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. Modified: cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx11.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx11.cpp?rev=290567&r1=290566&r2=290567&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx11.cpp (original) +++ cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx11.cpp Mon Dec 26 20:02:09 2016 @@ -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}} +} Modified: cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp?rev=290567&r1=290566&r2=290567&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp (original) +++ cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp Mon Dec 26 20:02:09 2016 @@ -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>()); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits