public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Jakub Jelinek <jakub@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c++, abi: Fix up class layout with bitfields [PR109039]
Date: Fri, 10 Mar 2023 13:33:42 -0500	[thread overview]
Message-ID: <1f74bd8f-9b09-0b1d-f200-4645ab230037@redhat.com> (raw)
In-Reply-To: <ZAo2E3aXm85gr4dw@tucnak>

On 3/9/23 14:40, Jakub Jelinek wrote:
> Hi!
> 
> The following testcase FAILs, because starting with r12-6028
> the S class has only 2 bytes, not enough to hold one 7-bit bitfield, one 8-bit
> bitfield and one 8-bit char field.
> 
> The reason is that when end_of_class attempts to compute dsize, it simply
> adds byte_position of the field and DECL_SIZE_UNIT (and uses maximum from
> those offsets).
> The problematic bit-field in question has bit_position 7, byte_position 0,
> DECL_SIZE 8 and DECL_SIZE_UNIT 1.  So, byte_position + DECL_SIZE_UNIT is
> 1, even when the bitfield only has a single bit in the first byte and 7
> further bits in the second byte, so per the Itanium ABI it should be 2:
> "In either case, update dsize(C) to include the last byte
> containing (part of) the bit-field, and update sizeof(C) to
> max(sizeof(C),dsize(C))."
> 
> The following patch fixes it by computing bitsize of the end and using
> CEIL_DIV_EXPR division to round it to next byte boundary and convert
> from bits to bytes.
> 
> While this is an ABI change, classes with such incorrect layout couldn't
> have worked properly, so I doubt anybody is actually running it often
> in the wild.  Thus I think adding some ABI warning for it is unnecessary.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk
> (and after a while for GCC 12)?

OK.

> 2023-03-09  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/109039
> 	* class.cc (end_of_class): For bit-fields, instead of computing
> 	offset as sum of byte_position (field) and DECL_SIZE_UNIT (field),
> 	compute it as sum of bit_position (field) and DECL_SIZE (field)
> 	divided by BITS_PER_UNIT rounded up.
> 
> 	* g++.dg/abi/no_unique_address7.C: New test.
> 
> --- gcc/cp/class.cc.jj	2023-02-04 06:22:17.053407477 +0100
> +++ gcc/cp/class.cc	2023-03-09 18:02:43.967815721 +0100
> @@ -6476,7 +6476,15 @@ end_of_class (tree t, eoc_mode mode)
>   	     size of the type (usually 1) for computing nvsize.  */
>   	  size = TYPE_SIZE_UNIT (TREE_TYPE (field));
>   
> -	offset = size_binop (PLUS_EXPR, byte_position (field), size);
> +	if (DECL_BIT_FIELD_TYPE (field))
> +	  {
> +	    offset = size_binop (PLUS_EXPR, bit_position (field),
> +				 DECL_SIZE (field));
> +	    offset = size_binop (CEIL_DIV_EXPR, offset, bitsize_unit_node);
> +	    offset = fold_convert (sizetype, offset);
> +	  }
> +	else
> +	  offset = size_binop (PLUS_EXPR, byte_position (field), size);
>   	if (tree_int_cst_lt (result, offset))
>   	  result = offset;
>         }
> --- gcc/testsuite/g++.dg/abi/no_unique_address7.C.jj	2023-03-09 18:09:08.397205087 +0100
> +++ gcc/testsuite/g++.dg/abi/no_unique_address7.C	2023-03-09 18:08:56.439379395 +0100
> @@ -0,0 +1,33 @@
> +// PR c++/109039
> +// { dg-do run { target c++11 } }
> +
> +struct X {
> +  signed short x0 : 7;
> +  signed short x1 : 8;
> +  X () : x0 (1), x1 (2) {}
> +  int get () { return x0 + x1; }
> +};
> +
> +struct S {
> +  [[no_unique_address]] X x;
> +  signed char c;
> +  S () : c (0) {}
> +};
> +
> +S s;
> +
> +int
> +main ()
> +{
> +  if (s.x.x0 != 1 || s.x.x1 != 2 || s.c != 0)
> +    __builtin_abort ();
> +  s.x.x0 = -1;
> +  s.x.x1 = -1;
> +  if (s.x.x0 != -1 || s.x.x1 != -1 || s.c != 0)
> +    __builtin_abort ();
> +  s.c = -1;
> +  s.x.x0 = 0;
> +  s.x.x1 = 0;
> +  if (s.x.x0 != 0 || s.x.x1 != 0 || s.c != -1)
> +    __builtin_abort ();
> +}
> 
> 	Jakub
> 


      reply	other threads:[~2023-03-10 18:33 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-09 19:40 Jakub Jelinek
2023-03-10 18:33 ` Jason Merrill [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1f74bd8f-9b09-0b1d-f200-4645ab230037@redhat.com \
    --to=jason@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).