public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-6596] c++, abi: Fix up class layout with bitfields [PR109039]
@ 2023-03-10 19:37 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2023-03-10 19:37 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:991f9eb2da3a268b7b08346761fa0078ab55f506

commit r13-6596-g991f9eb2da3a268b7b08346761fa0078ab55f506
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Mar 10 20:36:33 2023 +0100

    c++, abi: Fix up class layout with bitfields [PR109039]
    
    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.
    
    2023-03-10  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.

Diff:
---
 gcc/cp/class.cc                               | 10 +++++++-
 gcc/testsuite/g++.dg/abi/no_unique_address7.C | 33 +++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index d37e9d4d576..68b62086340 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -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;
       }
diff --git a/gcc/testsuite/g++.dg/abi/no_unique_address7.C b/gcc/testsuite/g++.dg/abi/no_unique_address7.C
new file mode 100644
index 00000000000..82fcedf070e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/no_unique_address7.C
@@ -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 ();
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-03-10 19:37 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-10 19:37 [gcc r13-6596] c++, abi: Fix up class layout with bitfields [PR109039] Jakub Jelinek

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).