On Wed, Apr 22, 2020 at 01:33:45PM +0100, Richard Sandiford wrote:
> Jakub Jelinek <ja...@redhat.com> writes:
> > On Wed, Apr 22, 2020 at 12:17:02PM +0100, Richard Sandiford wrote:
> >> But my point was that, if the DECL_NAME does actually act to exclude
> >
> > I'm fine with dropping DECL_NAME test there, on the other side would like to
> > add
> >   && TYPE_SIZE (TREE_TYPE (field))
> >   && !integer_zerop (TYPE_SIZE (TREE_TYPE (field)))
> > in there because that is what all these empty bases should satisfy too.
> 
> Sounds good to me FWIW.

Thus below in the patch form.  Ok for trunk?

> >         /* Verify that other zero sized fields don't affect the
> >            ABI decisions.  */
> >         if (DECL_SIZE (field) && integer_zerop (DECL_SIZE (field)))
> >           gcc_assert (sub_count == 0);
> >
> >             if (sub_count < 0)
> >               return -1;
> >             count += sub_count;
> > ?
> 
> I fear this will actually trip in practice, but I'd have to go back and
> check.  (This came up in the context of the SVE parameter-passing rules,
> where we ended up deliberately checking DECL_SIZE to avoid zero-size
> user-level decls.)
> 
> E.g. I'd expect a :0 bitfield to have a zero size and an integer
> TREE_TYPE, so the recursive call should return -1.  AIUI we should
> skip these kinds of bitfield too, but again that's just my understanding,
> not a definitive statement.

Indeed, struct S { int : 0; }; in C has (at least on x86) sizeof 0, so
does struct T { struct S a, b, c, d; };
Sure, the backend needs to decide whether those change the ABI decisions or
not.
E.g. on rs6000 where I was considering similar check that assertion
triggers on
struct S { int : 0; };
struct T { struct S a, b, c, d; } t;
struct U { struct T e; float f, g, h, i; } u;
void foo (struct U);
int
bar (void)
{
  foo (u);
  return 1;
}

2020-04-22  Jakub Jelinek  <ja...@redhat.com>

        PR target/94383
        * calls.h (cxx17_empty_base_field_p): Declare.
        * calls.c (cxx17_empty_base_field_p): Define.

--- gcc/calls.h.jj      2020-01-12 11:54:36.214416411 +0100
+++ gcc/calls.h 2020-04-22 11:44:09.037853379 +0200
@@ -135,5 +135,6 @@ extern tree get_attr_nonstring_decl (tre
 extern void maybe_warn_nonstring_arg (tree, tree);
 extern bool get_size_range (tree, tree[2], bool = false);
 extern rtx rtx_for_static_chain (const_tree, bool);
+extern bool cxx17_empty_base_field_p (const_tree);
 
 #endif // GCC_CALLS_H
--- gcc/calls.c.jj      2020-03-27 22:27:09.615964438 +0100
+++ gcc/calls.c 2020-04-22 11:44:17.621722376 +0200
@@ -6261,5 +6261,23 @@ must_pass_va_arg_in_stack (tree type)
   return targetm.calls.must_pass_in_stack (arg);
 }
 
+/* Return true if FIELD is the C++17 empty base field that should
+   be ignored for ABI calling convention decisions in order to
+   maintain ABI compatibility between C++14 and earlier, which doesn't
+   add this FIELD to classes with empty bases, and C++17 and later
+   which does.  */
+
+bool
+cxx17_empty_base_field_p (const_tree field)
+{
+  return (TREE_CODE (field) == FIELD_DECL
+         && DECL_ARTIFICIAL (field)
+         && 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))));
+}
+
 /* Tell the garbage collector about GTY markers in this source file.  */
 #include "gt-calls.h"


        Jakub

Reply via email to