diff options
author | Jakub Jelinek <jakub@redhat.com> | 2012-04-25 16:27:08 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2012-04-25 16:27:08 +0200 |
commit | f1cc958978c4b3a76ccf96571972f95963c9f0ea (patch) | |
tree | 81ecc613d94b359b676a0ac3492e351643109575 /gcc/stor-layout.c | |
parent | 948e73b3d6a3d10ada7c0240bfbfa4aef147f59d (diff) | |
download | gcc-f1cc958978c4b3a76ccf96571972f95963c9f0ea.zip gcc-f1cc958978c4b3a76ccf96571972f95963c9f0ea.tar.gz gcc-f1cc958978c4b3a76ccf96571972f95963c9f0ea.tar.bz2 |
re PR tree-optimization/52979 (likely wrong code bug w/packed bitfields)
PR middle-end/52979
* stor-layout.c (get_best_mode): Don't return mode with bitsize
larger than maxbits. Don't compute maxbits modulo align.
Also check that unit bytes long store at bitpos / unit * unit
doesn't affect bits beyond bitregion_end.
* expmed.c (store_bit_field_1): Avoid trying insv if OP_MODE MEM
would not fit into bitregion_start ... bitregion_end + 1 bit
region.
(store_split_bit_field): Decrease unit close to end of bitregion_end
if access is restricted in order to avoid mutual recursion.
* gcc.c-torture/compile/pr52979-1.c: New test.
* gcc.c-torture/execute/pr52979-1.c: New test.
* gcc.c-torture/execute/pr52979-2.c: New test.
From-SVN: r186819
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r-- | gcc/stor-layout.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index d79be14..e72e7f3 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -2624,7 +2624,7 @@ get_best_mode (int bitsize, int bitpos, if (!bitregion_end) maxbits = MAX_FIXED_MODE_SIZE; else - maxbits = (bitregion_end - bitregion_start) % align + 1; + maxbits = bitregion_end - bitregion_start + 1; /* Find the narrowest integer mode that contains the bit field. */ for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode; @@ -2645,7 +2645,10 @@ get_best_mode (int bitsize, int bitpos, (Though at least one Unix compiler ignores this problem: that on the Sequent 386 machine. */ || MIN (unit, BIGGEST_ALIGNMENT) > align - || (largest_mode != VOIDmode && unit > GET_MODE_BITSIZE (largest_mode))) + || (largest_mode != VOIDmode && unit > GET_MODE_BITSIZE (largest_mode)) + || unit > maxbits + || (bitregion_end + && bitpos - (bitpos % unit) + unit > bitregion_end + 1)) return VOIDmode; if ((SLOW_BYTE_ACCESS && ! volatilep) @@ -2663,7 +2666,9 @@ get_best_mode (int bitsize, int bitpos, && unit <= MIN (align, BIGGEST_ALIGNMENT) && unit <= maxbits && (largest_mode == VOIDmode - || unit <= GET_MODE_BITSIZE (largest_mode))) + || unit <= GET_MODE_BITSIZE (largest_mode)) + && (bitregion_end == 0 + || bitpos - (bitpos % unit) + unit <= bitregion_end + 1)) wide_mode = tmode; } |