Patchwork [C++,Patch/RFC] PR 60389

login
register
mail settings
Submitter Paolo Carlini
Date March 11, 2014, 12:03 p.m.
Message ID <531EFBAE.6070009@oracle.com>
Download mbox | patch
Permalink /patch/329055/
State New
Headers show

Comments

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.

///////////////////////
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

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