[gcc r16-9557] tree-optimization/126650 - get_inner_reference_aff and bitfields

Richard Biener via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:4e9903e714e49f4cb51ff2b687d73beb296e6f55

commit r16-9557-g4e9903e714e49f4cb51ff2b687d73beb296e6f55
Author: Richard Biener <[email protected]>
Date:   Wed Aug 5 10:31:47 2026 +0200

    tree-optimization/126650 - get_inner_reference_aff and bitfields
    
    get_inner_reference_aff tries to compensate for bit precision
    offsets and sizes by rounding down and up, but fails to do this
    correctly.  The following makes it more obviously correct by
    rounding positions and computing the rounded size based on those.
    
            PR tree-optimization/126650
            * tree-affine.cc (get_inner_reference_aff): Fixup rounding
            of size.
    
            * gcc.dg/torture/pr126650.c: New testcase.
    
    (cherry picked from commit 9baaca2adeca178edf8c0816ef328dba1cf270bc)

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr126650.c | 35 +++++++++++++++++++++++++++++++++
 gcc/tree-affine.cc                      |  5 +++--
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr126650.c b/gcc/testsuite/gcc.dg/torture/pr126650.c
new file mode 100644
index 000000000000..166705d9cfe6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr126650.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+long a;
+
+void __attribute__((noipa)) foo (int n, ...)
+{
+  va_list list;
+  va_start (list, n);
+  int val = va_arg (list, int);
+  if (val != -64)
+    abort ();
+  va_end (list);
+}
+
+int main()
+{
+  struct b {
+    int : 7;
+    int : 2;
+    int : 6;
+    int : 3;
+    int c : 7;
+  };
+  union {
+    int d;
+    struct b bf;
+    char e[4];
+  } f;
+  f.d = a;
+  f.e[3] = 7;
+  foo (1, f.bf.c);
+}
diff --git a/gcc/tree-affine.cc b/gcc/tree-affine.cc
index b5b7249c6750..181fd6fb33ce 100644
--- a/gcc/tree-affine.cc
+++ b/gcc/tree-affine.cc
@@ -1030,10 +1030,11 @@ get_inner_reference_aff (tree ref, aff_tree *addr, poly_widest_int *size)
       aff_combination_add (addr, &tmp);
     }
 
-  aff_combination_const (&tmp, sizetype, bits_to_bytes_round_down (bitpos));
+  poly_int64 bytepos = bits_to_bytes_round_down (bitpos);
+  aff_combination_const (&tmp, sizetype, bytepos);
   aff_combination_add (addr, &tmp);
 
-  *size = bits_to_bytes_round_up (bitsize);
+  *size = bits_to_bytes_round_up (bitpos + bitsize) - bytepos;
 
   return base;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.