https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79464
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The problem is that the middle-end doesn't like TYPE_ARG_TYPES being inconsistent with DECL_ARGUMENTS (that we have in the former types for this, __vtt_parm and for the int original argument, while DECL_ARGUMENTS doesn't have that int argument). I've tried to change that: --- gcc/cp/class.c.jj 2017-02-07 18:44:43.000000000 +0100 +++ gcc/cp/class.c 2017-02-14 12:10:41.612988203 +0100 @@ -4761,12 +4761,14 @@ build_clone (tree fn, tree name) DECL_VINDEX (clone) = NULL_TREE; } + bool ctor_omit_inherited_parms_p = ctor_omit_inherited_parms (clone); + /* If there was an in-charge parameter, drop it from the function type. */ - if (DECL_HAS_IN_CHARGE_PARM_P (clone)) + if (DECL_HAS_IN_CHARGE_PARM_P (clone) || ctor_omit_inherited_parms_p) { tree basetype; - tree parmtypes; + tree parmtypes, orig_parmtypes; tree exceptions; exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone)); @@ -4774,24 +4776,33 @@ build_clone (tree fn, tree name) parmtypes = TYPE_ARG_TYPES (TREE_TYPE (clone)); /* Skip the `this' parameter. */ parmtypes = TREE_CHAIN (parmtypes); + orig_parmtypes = parmtypes; /* Skip the in-charge parameter. */ - parmtypes = TREE_CHAIN (parmtypes); + if (DECL_HAS_IN_CHARGE_PARM_P (clone)) + parmtypes = TREE_CHAIN (parmtypes); /* And the VTT parm, in a complete [cd]tor. */ 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. */ - TREE_TYPE (clone) - = build_method_type_directly (basetype, - TREE_TYPE (TREE_TYPE (clone)), - parmtypes); - if (exceptions) - TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), - exceptions); - TREE_TYPE (clone) - = cp_build_type_attribute_variant (TREE_TYPE (clone), - TYPE_ATTRIBUTES (TREE_TYPE (fn))); + if (ctor_omit_inherited_parms_p + && TREE_CHAIN (parmtypes) != void_list_node) + parmtypes = tree_cons (NULL_TREE, TREE_VALUE (parmtypes), + void_list_node); + if (parmtypes != orig_parmtypes) + { + /* If this is subobject constructor or destructor, add the vtt + parameter. */ + TREE_TYPE (clone) + = build_method_type_directly (basetype, + TREE_TYPE (TREE_TYPE (clone)), + parmtypes); + if (exceptions) + TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), + exceptions); + tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (fn)); + TREE_TYPE (clone) + = cp_build_type_attribute_variant (TREE_TYPE (clone), attrs); + } } /* Copy the function parameters. */ @@ -4818,7 +4829,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)) but that breaks many other things; guess we'd need in various spots in the FE start looking at TYPE_ARG_TYPES of DECL_CLONED_FUNCTION. So, is the FE fixable for that, or do we need to adjust the METHOD_TYPE of the inherited base ctors later (and if so, when? At genericization time (do we have a guarantee that the FE will not look at TYPE_ARG_TYPES of it anymore though?), or at free_lang_data time (using some langhook? Do we have a guarantee nothing looks at TYPE_ARG_TYPES in the FE at this point? And, won't the middle-end be upset about this already from gimplification till free_lang_data?