aboutsummaryrefslogtreecommitdiff
path: root/gcc/stor-layout.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2012-04-25 16:27:08 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2012-04-25 16:27:08 +0200
commitf1cc958978c4b3a76ccf96571972f95963c9f0ea (patch)
tree81ecc613d94b359b676a0ac3492e351643109575 /gcc/stor-layout.c
parent948e73b3d6a3d10ada7c0240bfbfa4aef147f59d (diff)
downloadgcc-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.c11
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;
}