aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-02-15 15:29:08 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-02-15 15:29:08 -0500
commit19e8a45feb6c8cda4bc324e8bd6434ca46033b7c (patch)
tree753e105ddd16894c23f726f7d2c1b39362e4d4df
parent945c17d8c1fd5e2299fb17becac9b35ec45db3e6 (diff)
downloadgcc-19e8a45feb6c8cda4bc324e8bd6434ca46033b7c.zip
gcc-19e8a45feb6c8cda4bc324e8bd6434ca46033b7c.tar.gz
gcc-19e8a45feb6c8cda4bc324e8bd6434ca46033b7c.tar.bz2
PR c++/79464 - ICE in IPA with omitted constructor parms
* class.c (build_clone): Also omit parms from TYPE_ARG_TYPES. (adjust_clone_args): Adjust. (add_method): Remember omitted parms. * call.c (add_function_candidate): Likewise. * mangle.c (write_method_parms): Likewise. * method.c (ctor_omit_inherited_parms): Return false if there are no parms to omit. Co-Authored-By: Jakub Jelinek <jakub@redhat.com> From-SVN: r245495
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/call.c6
-rw-r--r--gcc/cp/class.c29
-rw-r--r--gcc/cp/mangle.c4
-rw-r--r--gcc/cp/method.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/inh-ctor23.C2
6 files changed, 50 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4d4f1a0..d346d68 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2017-02-15 Jason Merrill <jason@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/79464 - ICE in IPA with omitted constructor parms
+ * class.c (build_clone): Also omit parms from TYPE_ARG_TYPES.
+ (adjust_clone_args): Adjust.
+ (add_method): Remember omitted parms.
+ * call.c (add_function_candidate): Likewise.
+ * mangle.c (write_method_parms): Likewise.
+ * method.c (ctor_omit_inherited_parms): Return false if there are no
+ parms to omit.
+
2017-02-15 Martin Sebor <msebor@redhat.com>
PR c++/79363
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 718438c..154509b 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -2005,7 +2005,11 @@ add_function_candidate (struct z_candidate **candidates,
considered in overload resolution. */
if (DECL_CONSTRUCTOR_P (fn))
{
- parmlist = skip_artificial_parms_for (fn, parmlist);
+ if (ctor_omit_inherited_parms (fn))
+ /* Bring back parameters omitted from an inherited ctor. */
+ parmlist = FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (fn));
+ else
+ parmlist = skip_artificial_parms_for (fn, parmlist);
skip = num_artificial_parms_for (fn);
if (skip > 0 && first_arg != NULL_TREE)
{
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 7ec07c9..1442b55 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1149,6 +1149,12 @@ add_method (tree type, tree method, tree using_decl)
if (! DECL_STATIC_FUNCTION_P (method))
parms2 = TREE_CHAIN (parms2);
+ /* Bring back parameters omitted from an inherited ctor. */
+ if (ctor_omit_inherited_parms (fn))
+ parms1 = FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (fn));
+ if (ctor_omit_inherited_parms (method))
+ parms2 = FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (method));
+
if (compparms (parms1, parms2)
&& (!DECL_CONV_FN_P (fn)
|| same_type_p (TREE_TYPE (fn_type),
@@ -4761,6 +4767,10 @@ build_clone (tree fn, tree name)
DECL_VINDEX (clone) = NULL_TREE;
}
+ bool ctor_omit_inherited_parms_p = ctor_omit_inherited_parms (clone);
+ if (ctor_omit_inherited_parms_p)
+ gcc_assert (DECL_HAS_IN_CHARGE_PARM_P (clone));
+
/* If there was an in-charge parameter, drop it from the function
type. */
if (DECL_HAS_IN_CHARGE_PARM_P (clone))
@@ -4780,8 +4790,12 @@ build_clone (tree fn, tree name)
if (DECL_HAS_VTT_PARM_P (fn)
&& ! DECL_NEEDS_VTT_PARM_P (clone))
parmtypes = TREE_CHAIN (parmtypes);
- /* If this is subobject constructor or destructor, add the vtt
- parameter. */
+ if (ctor_omit_inherited_parms_p)
+ {
+ /* If we're omitting inherited parms, that just leaves the VTT. */
+ gcc_assert (DECL_NEEDS_VTT_PARM_P (clone));
+ parmtypes = tree_cons (NULL_TREE, vtt_parm_type, void_list_node);
+ }
TREE_TYPE (clone)
= build_method_type_directly (basetype,
TREE_TYPE (TREE_TYPE (clone)),
@@ -4818,7 +4832,7 @@ build_clone (tree fn, tree name)
/* A base constructor inheriting from a virtual base doesn't get the
arguments. */
- if (ctor_omit_inherited_parms (clone))
+ if (ctor_omit_inherited_parms_p)
DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))) = NULL_TREE;
for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms))
@@ -4965,6 +4979,13 @@ adjust_clone_args (tree decl)
decl_parms = TREE_CHAIN (decl_parms),
clone_parms = TREE_CHAIN (clone_parms))
{
+ if (clone_parms == void_list_node)
+ {
+ gcc_assert (decl_parms == clone_parms
+ || ctor_omit_inherited_parms (clone));
+ break;
+ }
+
gcc_assert (same_type_p (TREE_TYPE (decl_parms),
TREE_TYPE (clone_parms)));
@@ -4999,7 +5020,7 @@ adjust_clone_args (tree decl)
break;
}
}
- gcc_assert (!clone_parms);
+ gcc_assert (!clone_parms || clone_parms == void_list_node);
}
}
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 3ead33e..8b30f42 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2740,6 +2740,10 @@ write_method_parms (tree parm_types, const int method_p, const tree decl)
parm_types = TREE_CHAIN (parm_types);
parm_decl = DECL_CHAIN (parm_decl);
}
+
+ if (decl && ctor_omit_inherited_parms (decl))
+ /* Bring back parameters omitted from an inherited ctor. */
+ parm_types = FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (decl));
}
for (first_parm_type = parm_types;
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index a6a9b4e..beb0a24 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -575,6 +575,9 @@ ctor_omit_inherited_parms (tree fn)
if (!DECL_BASE_CONSTRUCTOR_P (fn)
|| !CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
return false;
+ if (FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (fn)) == void_list_node)
+ /* No user-declared parameters to omit. */
+ return false;
tree binfo = inherited_ctor_binfo (fn);
for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo))
if (BINFO_VIRTUAL_P (binfo))
diff --git a/gcc/testsuite/g++.dg/cpp1z/inh-ctor23.C b/gcc/testsuite/g++.dg/cpp1z/inh-ctor23.C
index c0cf040..fe2c2eb 100644
--- a/gcc/testsuite/g++.dg/cpp1z/inh-ctor23.C
+++ b/gcc/testsuite/g++.dg/cpp1z/inh-ctor23.C
@@ -1,6 +1,6 @@
// Testcase from P0136
// { dg-do compile { target c++11 } }
-// { dg-options "-fnew-inheriting-ctors -fdump-tree-gimple" }
+// { dg-options "-fnew-inheriting-ctors -fdump-tree-gimple -O2 -fno-inline" }
struct W { W(int); };
struct V: W { using W::W; };