expmed.c (store_bit_field): Assert that BITREGION_START is a multiple of a unit before computing the offset...

* expmed.c (store_bit_field): Assert that BITREGION_START is a multiple
	of a unit before computing the offset in units.
	* expr.c (get_bit_range): Return the null range if the enclosing record
	is part of a larger bit field.

From-SVN: r185857
This commit is contained in:
Eric Botcazou 2012-03-27 10:35:55 +00:00 committed by Eric Botcazou
parent d102ab714f
commit a59b038cc8
5 changed files with 71 additions and 2 deletions

View File

@ -1,3 +1,10 @@
2012-03-27 Eric Botcazou <ebotcazou@adacore.com>
* expmed.c (store_bit_field): Assert that BITREGION_START is a multiple
of a unit before computing the offset in units.
* expr.c (get_bit_range): Return the null range if the enclosing record
is part of a larger bit field.
2012-03-27 Tristan Gingold <gingold@adacore.com>
* config/ia64/vms.h (CASE_VECTOR_MODE): Define.

View File

@ -828,8 +828,7 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
/* Under the C++0x memory model, we must not touch bits outside the
bit region. Adjust the address to start at the beginning of the
bit region. */
if (MEM_P (str_rtx)
&& bitregion_start > 0)
if (MEM_P (str_rtx) && bitregion_start > 0)
{
enum machine_mode bestmode;
enum machine_mode op_mode;
@ -839,6 +838,8 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
if (op_mode == MAX_MACHINE_MODE)
op_mode = VOIDmode;
gcc_assert ((bitregion_start % BITS_PER_UNIT) == 0);
offset = bitregion_start / BITS_PER_UNIT;
bitnum -= bitregion_start;
bitregion_end -= bitregion_start;

View File

@ -4458,6 +4458,25 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart,
return;
}
/* If we have a DECL_BIT_FIELD_REPRESENTATIVE but the enclosing record is
part of a larger bit field, then the representative does not serve any
useful purpose. This can occur in Ada. */
if (handled_component_p (TREE_OPERAND (exp, 0)))
{
enum machine_mode rmode;
HOST_WIDE_INT rbitsize, rbitpos;
tree roffset;
int unsignedp;
int volatilep = 0;
get_inner_reference (TREE_OPERAND (exp, 0), &rbitsize, &rbitpos,
&roffset, &rmode, &unsignedp, &volatilep, false);
if ((rbitpos % BITS_PER_UNIT) != 0)
{
*bitstart = *bitend = 0;
return;
}
}
/* Compute the adjustment to bitpos from the offset of the field
relative to the representative. DECL_FIELD_OFFSET of field and
repr are the same by construction if they are not constants,

View File

@ -1,3 +1,7 @@
2012-03-27 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/pack17.adb: New test.
2012-03-27 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
* gcc.target/arm/thumb-ifcvt.c: Only run for -mthumb.

View File

@ -0,0 +1,38 @@
-- { dg-do run }
procedure Pack17 is
type Bitmap_T is array (Natural range <>) of Boolean;
pragma Pack (Bitmap_T);
type Uint8 is range 0 .. 2 ** 8 - 1;
for Uint8'Size use 8;
type Record_With_QImode_Variants (D : Boolean) is record
C_Filler : Bitmap_T (1..7);
C_Map : Bitmap_T (1..3);
case D is
when False =>
F_Bit : Boolean;
F_Filler : Bitmap_T (1..7);
when True =>
T_Int : Uint8;
end case;
end record;
pragma Pack (Record_With_QImode_Variants);
procedure Fill (R : out Record_With_QImode_Variants) is
begin
R.C_Filler := (True, False, True, False, True, False, True);
R.C_Map := (True, False, True);
R.T_Int := 17;
end;
RT : Record_With_QImode_Variants (D => True);
begin
Fill (RT);
if RT.T_Int /= 17 then
raise Program_Error;
end if;
end;