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