aboutsummaryrefslogtreecommitdiff
path: root/gcc/stor-layout.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-03-20 09:31:40 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-03-20 09:31:40 +0000
commit7ebf9677e58b3f97e71f267e4f27bcaf01458393 (patch)
tree0549509c3acd6070b5ca74672b96a9e435dd8bf6 /gcc/stor-layout.c
parent9b96cf92a4334eccb74163397e94ade6e4acac48 (diff)
downloadgcc-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.c35
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;