diff options
author | Richard Guenther <rguenther@suse.de> | 2012-03-20 09:31:40 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-03-20 09:31:40 +0000 |
commit | 7ebf9677e58b3f97e71f267e4f27bcaf01458393 (patch) | |
tree | 0549509c3acd6070b5ca74672b96a9e435dd8bf6 /gcc/stor-layout.c | |
parent | 9b96cf92a4334eccb74163397e94ade6e4acac48 (diff) | |
download | gcc-7ebf9677e58b3f97e71f267e4f27bcaf01458393.zip gcc-7ebf9677e58b3f97e71f267e4f27bcaf01458393.tar.gz gcc-7ebf9677e58b3f97e71f267e4f27bcaf01458393.tar.bz2 |
stor-layout.c (finish_bitfield_representative): Fallback to conservative maximum size if the padding up to the next field...
2012-03-20 Richard Guenther <rguenther@suse.de>
* stor-layout.c (finish_bitfield_representative): Fallback
to conservative maximum size if the padding up to the next
field cannot be computed as a constant.
(finish_bitfield_layout): If we cannot compute the distance
between the start of the bitfield representative and the
bitfield member start a new representative.
* expr.c (get_bit_range): The distance between the start of
the bitfield representative and the bitfield member is zero
if the field offsets are not constants.
* gnat.dg/pack16.adb: New testcase.
* gnat.dg/pack16_pkg.ads: Likewise.
* gnat.dg/specs/pack8.ads: Likewise.
* gnat.dg/specs/pack8_pkg.ads: Likewise.
From-SVN: r185563
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r-- | gcc/stor-layout.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 2d3f92e..d79be14 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1781,10 +1781,17 @@ finish_bitfield_representative (tree repr, tree field) return; maxsize = size_diffop (DECL_FIELD_OFFSET (nextf), DECL_FIELD_OFFSET (repr)); - gcc_assert (host_integerp (maxsize, 1)); - maxbitsize = (tree_low_cst (maxsize, 1) * BITS_PER_UNIT - + tree_low_cst (DECL_FIELD_BIT_OFFSET (nextf), 1) - - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1)); + if (host_integerp (maxsize, 1)) + { + maxbitsize = (tree_low_cst (maxsize, 1) * BITS_PER_UNIT + + tree_low_cst (DECL_FIELD_BIT_OFFSET (nextf), 1) + - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1)); + /* If the group ends within a bitfield nextf does not need to be + aligned to BITS_PER_UNIT. Thus round up. */ + maxbitsize = (maxbitsize + BITS_PER_UNIT - 1) & ~(BITS_PER_UNIT - 1); + } + else + maxbitsize = bitsize; } else { @@ -1888,6 +1895,8 @@ finish_bitfield_layout (record_layout_info rli) } else if (DECL_BIT_FIELD_TYPE (field)) { + gcc_assert (repr != NULL_TREE); + /* Zero-size bitfields finish off a representative and do not have a representative themselves. This is required by the C++ memory model. */ @@ -1896,6 +1905,24 @@ finish_bitfield_layout (record_layout_info rli) finish_bitfield_representative (repr, prev); repr = NULL_TREE; } + + /* We assume that either DECL_FIELD_OFFSET of the representative + and each bitfield member is a constant or they are equal. + This is because we need to be able to compute the bit-offset + of each field relative to the representative in get_bit_range + during RTL expansion. + If these constraints are not met, simply force a new + representative to be generated. That will at most + generate worse code but still maintain correctness with + respect to the C++ memory model. */ + else if (!((host_integerp (DECL_FIELD_OFFSET (repr), 1) + && host_integerp (DECL_FIELD_OFFSET (field), 1)) + || operand_equal_p (DECL_FIELD_OFFSET (repr), + DECL_FIELD_OFFSET (field), 0))) + { + finish_bitfield_representative (repr, prev); + repr = start_bitfield_representative (field); + } } else continue; |