aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.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/expr.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/expr.c')
-rw-r--r--gcc/expr.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index fcd5b36..f9de908 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -4452,7 +4452,7 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart,
HOST_WIDE_INT bitpos)
{
unsigned HOST_WIDE_INT bitoffset;
- tree field, repr, offset;
+ tree field, repr;
gcc_assert (TREE_CODE (exp) == COMPONENT_REF);
@@ -4467,12 +4467,17 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart,
}
/* Compute the adjustment to bitpos from the offset of the field
- relative to the representative. */
- offset = size_diffop (DECL_FIELD_OFFSET (field),
- DECL_FIELD_OFFSET (repr));
- bitoffset = (tree_low_cst (offset, 1) * BITS_PER_UNIT
- + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
- - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
+ relative to the representative. DECL_FIELD_OFFSET of field and
+ repr are the same by construction if they are not constants,
+ see finish_bitfield_layout. */
+ if (host_integerp (DECL_FIELD_OFFSET (field), 1)
+ && host_integerp (DECL_FIELD_OFFSET (repr), 1))
+ bitoffset = (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
+ - tree_low_cst (DECL_FIELD_OFFSET (repr), 1)) * BITS_PER_UNIT;
+ else
+ bitoffset = 0;
+ bitoffset += (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
+ - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
*bitstart = bitpos - bitoffset;
*bitend = *bitstart + tree_low_cst (DECL_SIZE (repr), 1) - 1;