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" }