[gcc r17-2981] tree-optimization/126650 - get_inner_reference_aff and bitfields
Richard Biener via Gcc-cvs <[email protected]> Wed, 5 Aug 2026 11:35:06 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:9baaca2adeca178edf8c0816ef328dba1cf270bc commit r17-2981-g9baaca2adeca178edf8c0816ef328dba1cf270bc 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. 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; }