On Sat, Apr 25, 2020 at 6:03 AM Jakub Jelinek <ja...@redhat.com> wrote:
>
> Hi!
>
> As reported by Iain and David, powerpc-darwin and powerpc-aix* have C++14
> vs. C++17 ABI incompatibilities which are not fixed by mere adding of
> cxx17_empty_base_field_p calls.  Unlike the issues that were seen on other
> targets where the artificial empty base field affected function argument
> passing or returning of values, on these two targets the difference is
> during class layout, not afterwards (e.g.
> struct empty_base {};
> struct S : public empty_base { unsigned long long l[2]; };
> will have different __alignof__ (S) between C++14 and C++17 (or possibly
> with double instead of unsigned long long too)).
>
> The aim of the calls.c (cxx17_empty_base_field_p) was not to match random
> artificial fields with zero size, because they could be created by something
> else for some other reason, thus the DECL_SIZE is bitsize_zero but TYPE_SIZE
> is non-zero check.  Unfortunately, during the class layout, the empty base
> fields have a different type, one which has zero size, so the predicate only
> works after the class is laid out completely.
>
> This patch adds a langhook, which will return true for those cases.  It
> shouldn't be problematic with LTO, because lto1 should see only
> structures/classes that are already laid out, or if it does some structure
> layout, it won't be something that has C++17 empty base artificial fields.
>
> Tested with cross to powerpc-darwin12 on a simple testcase given from Iain,
> but otherwise untested.
> Iain/David, could you please test this on your targets?
> Ok for trunk?

The patch fixes the AIX failures.

The rs6000 part is okay.

Thanks for tracking down and fixing all of this fallout.

Thanks, David

>
> 2020-04-25  Jakub Jelinek  <ja...@redhat.com>
>
>         PR target/94707
>         * langhooks.h (struct lang_hooks_for_decls): Add
>         cxx17_empty_base_field_p member.
>         * langhooks-def.h (LANG_HOOKS_CXX17_EMPTY_BASE_FIELD_P): Define.
>         (LANG_HOOKS_DECLS): Use it.
>         * calls.c (cxx17_empty_base_field_p): Use
>         langhooks.decls.cxx17_empty_base_field_p.
>         * config/rs6000/rs6000.c (rs6000_special_round_type_align,
>         darwin_rs6000_special_round_type_align): Skip cxx17_empty_base_field_p
>         fields.
> cp/
>         * cp-objcp-common.h (cp_cxx17_empty_base_field_p): Declare.
>         (LANG_HOOKS_CXX17_EMPTY_BASE_FIELD_P): Redefine.
>         * class.c (cp_cxx17_empty_base_field_p): New function.
>
> --- gcc/langhooks.h.jj  2020-03-17 13:50:52.262943386 +0100
> +++ gcc/langhooks.h     2020-04-25 11:06:11.921931710 +0200
> @@ -226,6 +226,9 @@ struct lang_hooks_for_decls
>    /* True if this decl may be called via a sibcall.  */
>    bool (*ok_for_sibcall) (const_tree);
>
> +  /* True if this FIELD_DECL is C++17 empty base field.  */
> +  bool (*cxx17_empty_base_field_p) (const_tree);
> +
>    /* Return a tree for the actual data of an array descriptor - or NULL_TREE
>       if original tree is not an array descriptor.  If the second argument
>       is true, only the TREE_TYPE is returned without generating a new tree.  
> */
> --- gcc/langhooks-def.h.jj      2020-01-12 11:54:36.670409531 +0100
> +++ gcc/langhooks-def.h 2020-04-25 11:06:03.300061347 +0200
> @@ -241,6 +241,7 @@ extern tree lhd_unit_size_without_reusab
>  #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
>  #define LANG_HOOKS_POST_COMPILATION_PARSING_CLEANUPS NULL
>  #define LANG_HOOKS_DECL_OK_FOR_SIBCALL lhd_decl_ok_for_sibcall
> +#define LANG_HOOKS_CXX17_EMPTY_BASE_FIELD_P    hook_bool_const_tree_false
>  #define LANG_HOOKS_OMP_ARRAY_DATA      hook_tree_tree_bool_null
>  #define LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR hook_bool_const_tree_false
>  #define LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT hook_tree_tree_bool_null
> @@ -269,6 +270,7 @@ extern tree lhd_unit_size_without_reusab
>    LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
>    LANG_HOOKS_POST_COMPILATION_PARSING_CLEANUPS, \
>    LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
> +  LANG_HOOKS_CXX17_EMPTY_BASE_FIELD_P, \
>    LANG_HOOKS_OMP_ARRAY_DATA, \
>    LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR, \
>    LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT, \
> --- gcc/calls.c.jj      2020-04-22 16:44:30.765946555 +0200
> +++ gcc/calls.c 2020-04-25 11:14:45.038217088 +0200
> @@ -6275,8 +6275,9 @@ cxx17_empty_base_field_p (const_tree fie
>           && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
>           && DECL_SIZE (field)
>           && integer_zerop (DECL_SIZE (field))
> -         && TYPE_SIZE (TREE_TYPE (field))
> -         && !integer_zerop (TYPE_SIZE (TREE_TYPE (field))));
> +         && ((TYPE_SIZE (TREE_TYPE (field))
> +              && !integer_zerop (TYPE_SIZE (TREE_TYPE (field))))
> +             || lang_hooks.decls.cxx17_empty_base_field_p (field)));
>  }
>
>  /* Tell the garbage collector about GTY markers in this source file.  */
> --- gcc/config/rs6000/rs6000.c.jj       2020-04-22 16:43:14.913087731 +0200
> +++ gcc/config/rs6000/rs6000.c  2020-04-25 11:16:01.536067016 +0200
> @@ -7192,7 +7192,9 @@ rs6000_special_round_type_align (tree ty
>    tree field = TYPE_FIELDS (type);
>
>    /* Skip all non field decls */
> -  while (field != NULL && TREE_CODE (field) != FIELD_DECL)
> +  while (field != NULL
> +        && (TREE_CODE (field) != FIELD_DECL
> +            || cxx17_empty_base_field_p (field)))
>      field = DECL_CHAIN (field);
>
>    if (field != NULL && field != type)
> @@ -7224,7 +7226,9 @@ darwin_rs6000_special_round_type_align (
>    do {
>      tree field = TYPE_FIELDS (type);
>      /* Skip all non field decls */
> -    while (field != NULL && TREE_CODE (field) != FIELD_DECL)
> +    while (field != NULL
> +          && (TREE_CODE (field) != FIELD_DECL
> +              || cxx17_empty_base_field_p (field)))
>        field = DECL_CHAIN (field);
>      if (! field)
>        break;
> --- gcc/cp/cp-objcp-common.h.jj 2020-01-12 11:54:36.478412428 +0100
> +++ gcc/cp/cp-objcp-common.h    2020-04-25 11:07:27.983788115 +0200
> @@ -31,6 +31,7 @@ extern int cp_decl_dwarf_attribute (cons
>  extern int cp_type_dwarf_attribute (const_tree, int);
>  extern void cp_common_init_ts (void);
>  extern tree cp_unit_size_without_reusable_padding (tree);
> +extern bool cp_cxx17_empty_base_field_p (const_tree);
>  extern tree cp_get_global_decls ();
>  extern tree cp_pushdecl (tree);
>  extern void cp_register_dumps (gcc::dump_manager *);
> @@ -159,6 +160,8 @@ extern tree cxx_simulate_enum_decl (loca
>  #define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE cp_type_dwarf_attribute
>  #undef LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING
>  #define LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING 
> cp_unit_size_without_reusable_padding
> +#undef LANG_HOOKS_CXX17_EMPTY_BASE_FIELD_P
> +#define LANG_HOOKS_CXX17_EMPTY_BASE_FIELD_P cp_cxx17_empty_base_field_p
>
>  #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
>  #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
> --- gcc/cp/class.c.jj   2020-04-23 09:46:17.432972832 +0200
> +++ gcc/cp/class.c      2020-04-25 11:13:13.060599884 +0200
> @@ -6734,6 +6734,23 @@ layout_class_type (tree t, tree *virtual
>      sizeof_biggest_empty_class = TYPE_SIZE_UNIT (t);
>  }
>
> +/* Return true if FIELD is C++17 empty base artificial field.
> +   The middle-end cxx17_empty_base_field_p predicate relies on
> +   the empty base field having DECL_SIZE of bitsize_zero and
> +   TYPE_SIZE of the field not bitsize_zero, but during class layout
> +   that is not the case and so this langhook is used to detect those.  */
> +
> +bool
> +cp_cxx17_empty_base_field_p (const_tree field)
> +{
> +  gcc_assert (TREE_CODE (field) == FIELD_DECL);
> +  return (DECL_ARTIFICIAL (field)
> +         && TYPE_CONTEXT (TREE_TYPE (field))
> +         && CLASS_TYPE_P (TYPE_CONTEXT (TREE_TYPE (field)))
> +         && TYPE_LANG_SPECIFIC (TYPE_CONTEXT (TREE_TYPE (field)))
> +         && IS_FAKE_BASE_TYPE (TREE_TYPE (field)));
> +}
> +
>  /* Determine the "key method" for the class type indicated by TYPE,
>     and set CLASSTYPE_KEY_METHOD accordingly.  */
>
>
>         Jakub
>

Reply via email to