This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCHes for inheriting ctor issues


When I implemented inheriting constructors, I thought that the wording that said that base copy/move constructors are not inherited was a wording problem, but discussion on the reflector indicates that it was intended, so that wrapper classes act like strong typedefs rather than drop-in replacements. So the first patch implements that.

In 55261 we were using CLASSTYPE_CONSTRUCTORS while the type still had undeclared lazy constructors, so we need to use lookup_fnfields to get the lazy declarations.

For 55262 we need to set DECL_PARM_INDEX on the inherited parameters.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 7b4b17ea6cfb867ca509aea9707ae056798684f8
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Nov 15 12:12:26 2012 -0500

    	* class.c (one_inheriting_sig): Don't inherit base copy ctors.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 2cab109..8902416 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2886,15 +2886,19 @@ static void
 one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
 {
   /* We don't declare an inheriting ctor that would be a default,
-     copy or move ctor.  */
-  if (nparms == 0
-      || (nparms == 1
-	  && TREE_CODE (parms[0]) == REFERENCE_TYPE
-	  && TYPE_MAIN_VARIANT (TREE_TYPE (parms[0])) == t))
+     copy or move ctor for derived or base.  */
+  if (nparms == 0)
     return;
-  int i;
+  if (nparms == 1
+      && TREE_CODE (parms[0]) == REFERENCE_TYPE)
+    {
+      tree parm = TYPE_MAIN_VARIANT (TREE_TYPE (parms[0]));
+      if (parm == t || parm == DECL_CONTEXT (ctor))
+	return;
+    }
+
   tree parmlist = void_list_node;
-  for (i = nparms - 1; i >= 0; i--)
+  for (int i = nparms - 1; i >= 0; i--)
     parmlist = tree_cons (NULL_TREE, parms[i], parmlist);
   tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
 				   t, false, ctor, parmlist);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor15.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor15.C
new file mode 100644
index 0000000..cc10558
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor15.C
@@ -0,0 +1,15 @@
+// Discussions on the core reflector indicate that not inheriting base copy
+// constructors was a deliberate choice.
+
+// { dg-options -std=c++11 }
+
+struct A { A(int); };
+struct B: public A
+{
+  using A::A;
+};
+
+A a (42);
+
+B b1 (24);			// inherited
+B b2 (a);			// not inherited { dg-error "no match" }
commit aa30433fe720e5d79bb7c291d8ea951928f3e68b
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Nov 15 11:58:24 2012 -0500

    	PR c++/55261
    	* class.c (add_implicitly_declared_members): Use
    	lookup_fnfields_slot to get the base constructors.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 56fe1d1..2cab109 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3014,7 +3014,8 @@ add_implicitly_declared_members (tree t, tree* access_decls,
       if (DECL_SELF_REFERENCE_P (decl))
 	{
 	  /* declare, then remove the decl */
-	  tree ctor_list = CLASSTYPE_CONSTRUCTORS (TREE_TYPE (decl));
+	  tree ctor_list = lookup_fnfields_slot (TREE_TYPE (decl),
+						 ctor_identifier);
 	  location_t loc = input_location;
 	  input_location = DECL_SOURCE_LOCATION (using_decl);
 	  if (ctor_list)
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor14.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor14.C
new file mode 100644
index 0000000..2032ad3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor14.C
@@ -0,0 +1,10 @@
+// PR c++/55261
+// { dg-options -std=c++11 }
+
+struct A
+{
+};
+struct B : A
+{
+  using A::A;
+};
commit bdfd9834c861aaead76fa86ace1b9c70409443d0
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Nov 15 11:58:50 2012 -0500

    	PR c++/55262
    	* method.c (implicitly_declare_fn): Set DECL_PARM_INDEX on
    	the parms of an inheriting ctor.

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 6458032..6dcb63a 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1663,10 +1663,14 @@ implicitly_declare_fn (special_function_kind kind, tree type,
   else if (kind == sfk_inheriting_constructor)
     {
       tree *p = &DECL_ARGUMENTS (fn);
+      int index = 1;
       for (tree parm = inherited_parms; parm != void_list_node;
 	   parm = TREE_CHAIN (parm))
 	{
 	  *p = cp_build_parm_decl (NULL_TREE, TREE_VALUE (parm));
+	  retrofit_lang_decl (*p);
+	  DECL_PARM_LEVEL (*p) = 1;
+	  DECL_PARM_INDEX (*p) = index++;
 	  DECL_CONTEXT (*p) = fn;
 	  p = &DECL_CHAIN (*p);
 	}
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C
index de57453..56c5bd6 100644
--- a/gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C
@@ -1,4 +1,4 @@
-// { dg-options "-std=c++11" }
+// { dg-options "-std=c++11 -g" }
 
 struct A
 {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]