On Mon, 26 Jul 2021, Jakub Jelinek wrote:

> Hi!
> 
> For the following testcase, B is 16-byte type, containing 8-byte
> virtual pointer and 1-byte A member, and C contains two FIELD_DECLs,
> one with B type and size of just 8-byte and then a field with type
> A and 1-byte size.
> The __builtin_clear_padding code was upset about the B typed FIELD_DECL
> containing FIELD_DECLs beyond the field size and triggered
> assertion failure.
> This patch makes it ignore all FIELD_DECLs that are (fully) beyond the sz
> passed from the caller (except for the flexible array member
> diagnostics that is kept).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2021-07-26  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR middle-end/101586
>       * gimple-fold.c (clear_padding_type): Ignore FIELD_DECLs with byte
>       positions above or equal to sz except for diagnostics of flexible
>       array members.
> 
>       * g++.dg/torture/builtin-clear-padding-4.C: New test.
> 
> --- gcc/gimple-fold.c.jj      2021-07-20 10:08:09.911687453 +0200
> +++ gcc/gimple-fold.c 2021-07-23 12:00:32.212892331 +0200
> @@ -4697,6 +4697,8 @@ clear_padding_type (clear_padding_struct
>               if (fldsz == 0)
>                 continue;
>               HOST_WIDE_INT pos = int_byte_position (field);
> +             if (pos >= sz)
> +               continue;
>               HOST_WIDE_INT bpos
>                 = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
>               bpos %= BITS_PER_UNIT;
> @@ -4772,6 +4774,8 @@ clear_padding_type (clear_padding_struct
>           else
>             {
>               HOST_WIDE_INT pos = int_byte_position (field);
> +             if (pos >= sz)
> +               continue;
>               HOST_WIDE_INT fldsz = tree_to_shwi (DECL_SIZE_UNIT (field));
>               gcc_assert (pos >= 0 && fldsz >= 0 && pos >= cur_pos);
>               clear_padding_add_padding (buf, pos - cur_pos);
> --- gcc/testsuite/g++.dg/torture/builtin-clear-padding-4.C.jj 2021-07-23 
> 12:53:48.372773954 +0200
> +++ gcc/testsuite/g++.dg/torture/builtin-clear-padding-4.C    2021-07-23 
> 12:50:41.855114231 +0200
> @@ -0,0 +1,44 @@
> +// PR middle-end/101586
> +
> +struct A { char a; };
> +struct B : virtual A {};
> +struct C : B {};
> +struct D : virtual A, C {};
> +
> +__attribute__((noipa)) A *
> +baz (C *p, D *q)
> +{
> +  if (p)
> +    return dynamic_cast <A *> (p);
> +  else
> +    return dynamic_cast <A *> (q);
> +}
> +
> +void
> +foo ()
> +{ 
> +  C c;
> +  c.a = 42;
> +  __builtin_clear_padding (&c);
> +  A *p = baz (&c, 0);
> +  if (c.a != 42 || p->a != 42)
> +    __builtin_abort ();
> +}
> +
> +void
> +bar ()
> +{
> +  D d;
> +  d.a = 42;
> +  __builtin_clear_padding (&d);
> +  A *p = baz (0, &d);
> +  if (d.a != 42 || p->a != 42)
> +    __builtin_abort ();
> +}
> +
> +int
> +main ()
> +{
> +  foo ();
> +  bar ();
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to