Commit 19e8a45f by Jason Merrill Committed by Jason Merrill

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
parent 945c17d8
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> 2017-02-15 Martin Sebor <msebor@redhat.com>
PR c++/79363 PR c++/79363
......
...@@ -2005,7 +2005,11 @@ add_function_candidate (struct z_candidate **candidates, ...@@ -2005,7 +2005,11 @@ add_function_candidate (struct z_candidate **candidates,
considered in overload resolution. */ considered in overload resolution. */
if (DECL_CONSTRUCTOR_P (fn)) 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); skip = num_artificial_parms_for (fn);
if (skip > 0 && first_arg != NULL_TREE) if (skip > 0 && first_arg != NULL_TREE)
{ {
......
...@@ -1149,6 +1149,12 @@ add_method (tree type, tree method, tree using_decl) ...@@ -1149,6 +1149,12 @@ add_method (tree type, tree method, tree using_decl)
if (! DECL_STATIC_FUNCTION_P (method)) if (! DECL_STATIC_FUNCTION_P (method))
parms2 = TREE_CHAIN (parms2); 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) if (compparms (parms1, parms2)
&& (!DECL_CONV_FN_P (fn) && (!DECL_CONV_FN_P (fn)
|| same_type_p (TREE_TYPE (fn_type), || same_type_p (TREE_TYPE (fn_type),
...@@ -4761,6 +4767,10 @@ build_clone (tree fn, tree name) ...@@ -4761,6 +4767,10 @@ build_clone (tree fn, tree name)
DECL_VINDEX (clone) = NULL_TREE; 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 /* If there was an in-charge parameter, drop it from the function
type. */ type. */
if (DECL_HAS_IN_CHARGE_PARM_P (clone)) if (DECL_HAS_IN_CHARGE_PARM_P (clone))
...@@ -4780,8 +4790,12 @@ build_clone (tree fn, tree name) ...@@ -4780,8 +4790,12 @@ build_clone (tree fn, tree name)
if (DECL_HAS_VTT_PARM_P (fn) if (DECL_HAS_VTT_PARM_P (fn)
&& ! DECL_NEEDS_VTT_PARM_P (clone)) && ! DECL_NEEDS_VTT_PARM_P (clone))
parmtypes = TREE_CHAIN (parmtypes); parmtypes = TREE_CHAIN (parmtypes);
/* If this is subobject constructor or destructor, add the vtt if (ctor_omit_inherited_parms_p)
parameter. */ {
/* 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) TREE_TYPE (clone)
= build_method_type_directly (basetype, = build_method_type_directly (basetype,
TREE_TYPE (TREE_TYPE (clone)), TREE_TYPE (TREE_TYPE (clone)),
...@@ -4818,7 +4832,7 @@ build_clone (tree fn, tree name) ...@@ -4818,7 +4832,7 @@ build_clone (tree fn, tree name)
/* A base constructor inheriting from a virtual base doesn't get the /* A base constructor inheriting from a virtual base doesn't get the
arguments. */ arguments. */
if (ctor_omit_inherited_parms (clone)) if (ctor_omit_inherited_parms_p)
DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))) = NULL_TREE; DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))) = NULL_TREE;
for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms)) for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms))
...@@ -4965,6 +4979,13 @@ adjust_clone_args (tree decl) ...@@ -4965,6 +4979,13 @@ adjust_clone_args (tree decl)
decl_parms = TREE_CHAIN (decl_parms), decl_parms = TREE_CHAIN (decl_parms),
clone_parms = TREE_CHAIN (clone_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), gcc_assert (same_type_p (TREE_TYPE (decl_parms),
TREE_TYPE (clone_parms))); TREE_TYPE (clone_parms)));
...@@ -4999,7 +5020,7 @@ adjust_clone_args (tree decl) ...@@ -4999,7 +5020,7 @@ adjust_clone_args (tree decl)
break; break;
} }
} }
gcc_assert (!clone_parms); gcc_assert (!clone_parms || clone_parms == void_list_node);
} }
} }
......
...@@ -2740,6 +2740,10 @@ write_method_parms (tree parm_types, const int method_p, const tree decl) ...@@ -2740,6 +2740,10 @@ write_method_parms (tree parm_types, const int method_p, const tree decl)
parm_types = TREE_CHAIN (parm_types); parm_types = TREE_CHAIN (parm_types);
parm_decl = DECL_CHAIN (parm_decl); 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; for (first_parm_type = parm_types;
......
...@@ -575,6 +575,9 @@ ctor_omit_inherited_parms (tree fn) ...@@ -575,6 +575,9 @@ ctor_omit_inherited_parms (tree fn)
if (!DECL_BASE_CONSTRUCTOR_P (fn) if (!DECL_BASE_CONSTRUCTOR_P (fn)
|| !CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn))) || !CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
return false; 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); tree binfo = inherited_ctor_binfo (fn);
for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo)) for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo))
if (BINFO_VIRTUAL_P (binfo)) if (BINFO_VIRTUAL_P (binfo))
......
// Testcase from P0136 // Testcase from P0136
// { dg-do compile { target c++11 } } // { 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 W { W(int); };
struct V: W { using W::W; }; struct V: W { using W::W; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment