[C++,Patch/RFC] PR 60389

Submitted by Paolo Carlini on March 11, 2014, 12:03 p.m.

Details

Message ID 531EFBAE.6070009@oracle.com
State New
Headers show

Commit Message

Paolo Carlini March 11, 2014, 12:03 p.m.
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.

///////////////////////

Comments

Jason Merrill March 11, 2014, 1:10 p.m.
On 03/11/2014 08:03 AM, Paolo Carlini wrote:
> +  if (DECL_INHERITED_CTOR_BASE (fun)
> +      && TREE_CODE (fun) == TEMPLATE_DECL)
> +    {
> +      ret = false;
> +      if (complain)
> +	error ("inherited constructors inherit %<constexpr%> from "
> +	       "the designated base");
> +    }

To correct my wording, the B constructor is the inheriting constructor, 
the inherited constructor is in A.

Let's look up the inherited constructor here and print it to be helpful. 
  Probably the easiest way to find it will be to add a new entry point 
to locate_fn_flags so we call it with

(DECL_INHERITED_CTOR_BASE (fun), DECL_NAME (fun), 
FUNCTION_FIRST_USER_PARMTYPE (fun), LOOKUP_NORMAL|LOOKUP_SPECULATIVE, 
complain)

Then we can say "inherited constructor %qD is not constexpr".

Jason

Patch hide | download patch | download mbox

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