[gcc r15-11491] 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:ba07588cc97d103842e1eac10065689321d97b56

commit r15-11491-gba07588cc97d103842e1eac10065689321d97b56
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 5044b54455a4..eb190527ab90 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.