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
This commit is contained in:
Richard Guenther 2012-03-20 09:31:40 +00:00 committed by Richard Biener
parent 9b96cf92a4
commit 7ebf9677e5
8 changed files with 117 additions and 11 deletions

View File

@ -1,3 +1,15 @@
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.
2012-03-20 Tristan Gingold <gingold@adacore.com>
* tree.h (enum size_type_kind): Add stk_ prefix to constants,

View File

@ -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;

View File

@ -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;

View File

@ -1,3 +1,10 @@
2012-03-20 Richard Guenther <rguenther@suse.de>
* 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.
2012-03-19 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/warn/Wuseless-cast.C: Extend.

View File

@ -0,0 +1,26 @@
-- { dg-do compile }
-- { dg-options "-gnatws" }
with Pack16_Pkg; use Pack16_Pkg;
procedure Pack16 is
type Sample_Table_T is array (1 .. N) of Integer;
type Clock_T is record
N_Ticks : Integer := 0;
end record;
type Sampling_Descriptor_T is record
Values : Sample_Table_T;
Valid : Boolean;
Tstamp : Clock_T;
end record;
pragma Pack (Sampling_Descriptor_T);
Sampling_Data : Sampling_Descriptor_T;
begin
null;
end;

View File

@ -0,0 +1,5 @@
package Pack16_Pkg is
N : Natural := 16;
end Pack16_Pkg;

View File

@ -0,0 +1,19 @@
with Pack8_Pkg;
package Pack8 is
subtype Index_Type is Integer range 1 .. Pack8_Pkg.N;
subtype Str is String( Index_Type);
subtype Str2 is String (1 .. 11);
type Rec is record
S1 : Str;
S2 : Str;
B : Boolean;
S3 : Str2;
end record;
pragma Pack (Rec);
end Pack8;

View File

@ -0,0 +1,5 @@
package Pack8_Pkg is
N : Natural := 1;
end Pack8_Pkg;