aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-11-19 09:05:59 -0500
committerJason Merrill <jason@gcc.gnu.org>2012-11-19 09:05:59 -0500
commite252e96aae2161af2838e993ea2373c91436aaa3 (patch)
tree07b59f492613f899268894c0443637f8d803c443 /gcc
parent61d1b8214569675bd18c508ac7d75325a0e721c6 (diff)
downloadgcc-e252e96aae2161af2838e993ea2373c91436aaa3.zip
gcc-e252e96aae2161af2838e993ea2373c91436aaa3.tar.gz
gcc-e252e96aae2161af2838e993ea2373c91436aaa3.tar.bz2
* class.c (one_inheriting_sig): Don't inherit base copy ctors.
From-SVN: r193623
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog2
-rw-r--r--gcc/cp/class.c18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor15.C15
3 files changed, 28 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 088959f..06eec95 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 04f9df5..da511e2 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" }