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?

Reply via email to