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

login
register
mail settings
Submitter Paolo Carlini
Date March 11, 2014, 4:07 p.m.
Message ID <531F34B5.3010001@oracle.com>
Download mbox | patch
Permalink /patch/329151/
State New
Headers show

Comments

Paolo Carlini - March 11, 2014, 4:07 p.m.
Hi,

On 03/11/2014 02:10 PM, Jason Merrill wrote:
> 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".
I see. The below tries to implement the above (note: 
complete_ctor_identifier; push_deferring_access_checks, otherwise for a 
similar testcase inheriting from class A we produce duplicate diagnostic 
about accessibility). Tested x86_64-linux.

Thanks,
Paolo.

PS: I think we should also be more careful about inform vs error, but 
probably not at this Stage...
Jason Merrill - March 11, 2014, 5:09 p.m.
OK.

Jason

Patch

Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 208474)
+++ cp/cp-tree.h	(working copy)
@@ -5476,6 +5476,7 @@  extern tree get_copy_ctor			(tree, tsubst_flags_t)
 extern tree get_copy_assign			(tree);
 extern tree get_default_ctor			(tree);
 extern tree get_dtor				(tree, tsubst_flags_t);
+extern tree get_inherited_ctor			(tree);
 extern tree locate_ctor				(tree);
 extern tree implicitly_declare_fn               (special_function_kind, tree,
 						 bool, tree, tree);
Index: cp/method.c
===================================================================
--- cp/method.c	(revision 208474)
+++ cp/method.c	(working copy)
@@ -971,6 +971,25 @@  get_copy_assign (tree type)
   return fn;
 }
 
+/* Locate the inherited constructor of constructor CTOR.  */
+
+tree
+get_inherited_ctor (tree ctor)
+{
+  gcc_assert (DECL_INHERITED_CTOR_BASE (ctor));
+
+  push_deferring_access_checks (dk_no_check);
+  tree fn = locate_fn_flags (DECL_INHERITED_CTOR_BASE (ctor),
+			     complete_ctor_identifier,
+			     FUNCTION_FIRST_USER_PARMTYPE (ctor),
+			     LOOKUP_NORMAL|LOOKUP_SPECULATIVE,
+			     tf_none);
+  pop_deferring_access_checks ();
+  if (fn == error_mark_node)
+    return NULL_TREE;
+  return fn;
+}
+
 /* Subroutine of synthesized_method_walk.  Update SPEC_P, TRIVIAL_P and
    DELETED_P or give an error message MSG with argument ARG.  */
 
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 constructor %qD is not constexpr",
+	       get_inherited_ctor (fun));
+    }
+  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" }