* class.c (one_inheriting_sig): Don't inherit base copy ctors.
authorJason Merrill <jason@redhat.com>
Mon, 19 Nov 2012 14:05:59 +0000 (09:05 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 19 Nov 2012 14:05:59 +0000 (09:05 -0500)
From-SVN: r193623

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/g++.dg/cpp0x/inh-ctor15.C [new file with mode: 0644]

index 088959f7f464e0344783b07a7b5ec68edf38e95b..06eec9584ec1d97d8e27a7b399bbb72071df79f3 100644 (file)
@@ -1,5 +1,7 @@
 2012-11-19  Jason Merrill  <jason@redhat.com>
 
+       * class.c (one_inheriting_sig): Don't inherit base copy ctors.
+
        PR c++/55262
        * method.c (implicitly_declare_fn): Set DECL_PARM_INDEX on
        the parms of an inheriting ctor.
index 04f9df5a23a5af179199d2a6136cdb9f2031b6c2..da511e2aad2dc3597437986194c94100fecd3697 100644 (file)
@@ -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 (file)
index 0000000..cc10558
--- /dev/null
@@ -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" }