This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCHes for inheriting ctor issues
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 19 Nov 2012 08:53:31 -0500
- Subject: 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
{