Hi, On 03/07/2014 06:36 PM, Jason Merrill wrote:
Inherited constructors inherit 'constexpr' from the designated base; B::B isn't constexpr because A::A isn't, and we should say that at the beginning of is_valid_constexpr_fn.
Ok, then something like the below? (passes testing)
Thanks, Paolo. ///////////////////////
Index: cp/semantics.c =================================================================== --- cp/semantics.c (revision 208474) +++ cp/semantics.c (working copy) @@ -7438,19 +7438,31 @@ retrieve_constexpr_fundef (tree fun) static bool is_valid_constexpr_fn (tree fun, bool complain) { - tree parm = FUNCTION_FIRST_USER_PARM (fun); bool ret = true; - for (; parm != NULL; parm = TREE_CHAIN (parm)) - if (!literal_type_p (TREE_TYPE (parm))) - { - ret = false; - if (complain) + + if (DECL_INHERITED_CTOR_BASE (fun) + && TREE_CODE (fun) == TEMPLATE_DECL) + { + ret = false; + if (complain) + error ("inherited constructors inherit %<constexpr%> from " + "the designated base"); + } + else + { + for (tree parm = FUNCTION_FIRST_USER_PARM (fun); + parm != NULL_TREE; parm = TREE_CHAIN (parm)) + if (!literal_type_p (TREE_TYPE (parm))) { - error ("invalid type for parameter %d of constexpr " - "function %q+#D", DECL_PARM_INDEX (parm), fun); - explain_non_literal_class (TREE_TYPE (parm)); + ret = false; + if (complain) + { + error ("invalid type for parameter %d of constexpr " + "function %q+#D", DECL_PARM_INDEX (parm), fun); + explain_non_literal_class (TREE_TYPE (parm)); + } } - } + } if (!DECL_CONSTRUCTOR_P (fun)) { Index: testsuite/g++.dg/cpp0x/inh-ctor19.C =================================================================== --- testsuite/g++.dg/cpp0x/inh-ctor19.C (revision 0) +++ testsuite/g++.dg/cpp0x/inh-ctor19.C (working copy) @@ -0,0 +1,14 @@ +// PR c++/60389 +// { dg-do compile { target c++11 } } + +struct A +{ + template<typename...T> A(T...) {} +}; + +struct B : A +{ + using A::A; // { dg-error "inherited" } +}; + +constexpr B b; // { dg-error "literal" }