Commit a59b038c by Eric Botcazou Committed by Eric Botcazou

expmed.c (store_bit_field): Assert that BITREGION_START is a multiple of a unit…

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
parent d102ab71
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> 2012-03-27 Tristan Gingold <gingold@adacore.com>
* config/ia64/vms.h (CASE_VECTOR_MODE): Define. * config/ia64/vms.h (CASE_VECTOR_MODE): Define.
......
...@@ -828,8 +828,7 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, ...@@ -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 /* 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. Adjust the address to start at the beginning of the
bit region. */ bit region. */
if (MEM_P (str_rtx) if (MEM_P (str_rtx) && bitregion_start > 0)
&& bitregion_start > 0)
{ {
enum machine_mode bestmode; enum machine_mode bestmode;
enum machine_mode op_mode; enum machine_mode op_mode;
...@@ -839,6 +838,8 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, ...@@ -839,6 +838,8 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
if (op_mode == MAX_MACHINE_MODE) if (op_mode == MAX_MACHINE_MODE)
op_mode = VOIDmode; op_mode = VOIDmode;
gcc_assert ((bitregion_start % BITS_PER_UNIT) == 0);
offset = bitregion_start / BITS_PER_UNIT; offset = bitregion_start / BITS_PER_UNIT;
bitnum -= bitregion_start; bitnum -= bitregion_start;
bitregion_end -= bitregion_start; bitregion_end -= bitregion_start;
......
...@@ -4458,6 +4458,25 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart, ...@@ -4458,6 +4458,25 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart,
return; 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 /* Compute the adjustment to bitpos from the offset of the field
relative to the representative. DECL_FIELD_OFFSET of field and relative to the representative. DECL_FIELD_OFFSET of field and
repr are the same by construction if they are not constants, repr are the same by construction if they are not constants,
......
2012-03-27 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/pack17.adb: New test.
2012-03-27 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> 2012-03-27 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
* gcc.target/arm/thumb-ifcvt.c: Only run for -mthumb. * gcc.target/arm/thumb-ifcvt.c: Only run for -mthumb.
......
-- { 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;
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