Commit 7ebf9677 by Richard Guenther Committed by Richard Biener

stor-layout.c (finish_bitfield_representative): Fallback to conservative maximum…

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
parent 9b96cf92
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> 2012-03-20 Tristan Gingold <gingold@adacore.com>
* tree.h (enum size_type_kind): Add stk_ prefix to constants, * tree.h (enum size_type_kind): Add stk_ prefix to constants,
......
...@@ -4452,7 +4452,7 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart, ...@@ -4452,7 +4452,7 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart,
HOST_WIDE_INT bitpos) HOST_WIDE_INT bitpos)
{ {
unsigned HOST_WIDE_INT bitoffset; unsigned HOST_WIDE_INT bitoffset;
tree field, repr, offset; tree field, repr;
gcc_assert (TREE_CODE (exp) == COMPONENT_REF); gcc_assert (TREE_CODE (exp) == COMPONENT_REF);
...@@ -4467,12 +4467,17 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart, ...@@ -4467,12 +4467,17 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart,
} }
/* Compute the adjustment to bitpos from the offset of the field /* Compute the adjustment to bitpos from the offset of the field
relative to the representative. */ relative to the representative. DECL_FIELD_OFFSET of field and
offset = size_diffop (DECL_FIELD_OFFSET (field), repr are the same by construction if they are not constants,
DECL_FIELD_OFFSET (repr)); see finish_bitfield_layout. */
bitoffset = (tree_low_cst (offset, 1) * BITS_PER_UNIT if (host_integerp (DECL_FIELD_OFFSET (field), 1)
+ tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1) && host_integerp (DECL_FIELD_OFFSET (repr), 1))
- tree_low_cst (DECL_FIELD_BIT_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; *bitstart = bitpos - bitoffset;
*bitend = *bitstart + tree_low_cst (DECL_SIZE (repr), 1) - 1; *bitend = *bitstart + tree_low_cst (DECL_SIZE (repr), 1) - 1;
......
...@@ -1781,10 +1781,17 @@ finish_bitfield_representative (tree repr, tree field) ...@@ -1781,10 +1781,17 @@ finish_bitfield_representative (tree repr, tree field)
return; return;
maxsize = size_diffop (DECL_FIELD_OFFSET (nextf), maxsize = size_diffop (DECL_FIELD_OFFSET (nextf),
DECL_FIELD_OFFSET (repr)); DECL_FIELD_OFFSET (repr));
gcc_assert (host_integerp (maxsize, 1)); if (host_integerp (maxsize, 1))
maxbitsize = (tree_low_cst (maxsize, 1) * BITS_PER_UNIT {
+ tree_low_cst (DECL_FIELD_BIT_OFFSET (nextf), 1) maxbitsize = (tree_low_cst (maxsize, 1) * BITS_PER_UNIT
- tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1)); + 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 else
{ {
...@@ -1888,6 +1895,8 @@ finish_bitfield_layout (record_layout_info rli) ...@@ -1888,6 +1895,8 @@ finish_bitfield_layout (record_layout_info rli)
} }
else if (DECL_BIT_FIELD_TYPE (field)) else if (DECL_BIT_FIELD_TYPE (field))
{ {
gcc_assert (repr != NULL_TREE);
/* Zero-size bitfields finish off a representative and /* Zero-size bitfields finish off a representative and
do not have a representative themselves. This is do not have a representative themselves. This is
required by the C++ memory model. */ required by the C++ memory model. */
...@@ -1896,6 +1905,24 @@ finish_bitfield_layout (record_layout_info rli) ...@@ -1896,6 +1905,24 @@ finish_bitfield_layout (record_layout_info rli)
finish_bitfield_representative (repr, prev); finish_bitfield_representative (repr, prev);
repr = NULL_TREE; 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 else
continue; continue;
......
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> 2012-03-19 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/warn/Wuseless-cast.C: Extend. * g++.dg/warn/Wuseless-cast.C: Extend.
......
-- { 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;
package Pack16_Pkg is
N : Natural := 16;
end Pack16_Pkg;
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;
package Pack8_Pkg is
N : Natural := 1;
end Pack8_Pkg;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment