> This is what I have applied after bootstrapping and testing on
> x86_64-unknown-linux-gnu.
Thanks. Last identified problem: the miscompilation with variant record.
gnat.dg/pack17.adb
raised PROGRAM_ERROR : pack17.adb:36 explicit raise
FAIL: gnat.dg/pack17.adb execution test
Things start to go wrong at line 28:
24 procedure Fill (R : out Record_With_QImode_Variants) is
25 begin
26 R.C_Filler := (True, False, True, False, True, False, True);
27 R.C_Map := (True, False, True);
28 R.T_Int := 17;
29 end;
R is a packed record with variant part and -gnatR1 gives its layout:
for Record_With_Qimode_Variants'Object_Size use 24;
for Record_With_Qimode_Variants'Value_Size use 19;
for Record_With_Qimode_Variants'Alignment use 1;
for Record_With_Qimode_Variants use record
D at 0 range 0 .. 0;
C_Filler at 0 range 1 .. 7;
C_Map at 1 range 0 .. 2;
F_Bit at 1 range 3 .. 3;
F_Filler at 1 range 4 .. 10;
T_Int at 1 range 3 .. 10;
Now, since T_Int is within a variant, the assignment is translated into:
r_1(D)->d___XVN.O.t_int = 17;
d___XVN is QUAL_UNION_TYPE and O a RECORD_TYPE (fields of QUAL_UNION_TYPE are
always of RECORD_TYPE, that's why the overloading of qualifier is indeed OK).
The compiler now generates:
movl 8(%ebp), %eax
movb $17, 1(%eax)
which is of course wrong given the layout above.
It seems to me that the new code implicitly assumes that the first field in a
bitfield group starts on a byte boundary, which doesn't hold in Ada.
--
Eric Botcazou
-- { 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;