This patch prevents the initializer from being checked when it is dependent. It also sets the type of a dependent template-id referring to a variable template to be unknown, making such expressions type dependent.
2014-08-07 Andrew Sutton <andrew.n.sut...@gmail.com> * pt.c (lookup_template_variable): Make the type unspecified if any template arguments are dependent. * decl.c (cp_finish_decl): Don't check the initializer if it is value-dependent. New test included. Andrew Sutton On Wed, Aug 6, 2014 at 9:34 PM, Jason Merrill <ja...@redhat.com> wrote: > On 08/05/2014 04:06 PM, Paolo Carlini wrote: >> >> Great. I will double check but var-templ4.C fails for me with an ICE. > > > Hunh, I wonder how I missed that. > > Here's what I'm checking in; we want to unset DECL_COMDAT for variable > templates, too. > >
Index: gcc/testsuite/g++.dg/cpp1y/var-templ6.C =================================================================== --- gcc/testsuite/g++.dg/cpp1y/var-templ6.C (revision 0) +++ gcc/testsuite/g++.dg/cpp1y/var-templ6.C (revision 0) @@ -0,0 +1,12 @@ +// { dg-options "-std=c++1y" } + +template<typename T> + constexpr bool Class = __is_class(T); + +template<typename T> + constexpr bool Test = Class<T>; + +struct S { }; + +static_assert(!Test<int>, ""); +static_assert(Test<S>, "");
Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 213667) +++ gcc/cp/decl.c (working copy) @@ -6417,19 +6417,20 @@ cp_finish_decl (tree decl, tree init, bo DECL_INITIAL (decl) = NULL_TREE; } + bool value_dependent_p = init && value_dependent_init_p (init); + /* Generally, initializers in templates are expanded when the template is instantiated. But, if DECL is a variable constant then it can be used in future constant expressions, so its value must be available. */ - - if (!VAR_P (decl) || dependent_type_p (type)) + if (!VAR_P (decl) || type_dependent_p || value_dependent_p) /* We can't do anything if the decl has dependent type. */; else if (init && init_const_expr_p && !type_dependent_p && decl_maybe_constant_var_p (decl) && !type_dependent_init_p (init) - && !value_dependent_init_p (init)) + && !value_dependent_p) { /* This variable seems to be a non-dependent constant, so process its initializer. If check_initializer returns non-null the Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 213667) +++ gcc/cp/pt.c (working copy) @@ -8260,13 +8260,23 @@ lookup_template_class (tree d1, tree arg return ret; } -/* Return a TEMPLATE_ID_EXPR for the given variable template and ARGLIST. */ +/* Return a TEMPLATE_ID_EXPR for the given variable template and ARGLIST. + If the ARGLIST refers to any template parameters, the type of the + expression is the unknown_type_node since the template-id could + refer to an explicit or partial specialization. +*/ tree lookup_template_variable (tree templ, tree arglist) { - return build2 (TEMPLATE_ID_EXPR, TREE_TYPE (templ), templ, arglist); + tree type; + if (uses_template_parms (arglist)) + type = unknown_type_node; + else + type = TREE_TYPE (templ); + return build2 (TEMPLATE_ID_EXPR, type, templ, arglist); } + struct pair_fn_data {