This fixes a long-standing issue present for extensions of tagged record
types with a representation clause: the clause is correctly inherited
for components inherited in the extension but the position and size are
not, which fools the logic of Is_Possibly_Unaligned_Object.
This can result in an attempt to take the address of a component not
aligned on a byte boundary, which is then flagged as an internal error.
Tested on x86_64-pc-linux-gnu, committed on trunk
2018-08-21 Eric Botcazou <ebotca...@adacore.com>
gcc/ada/
* exp_util.adb (Is_Possibly_Unaligned_Object): For the case of a
selected component inherited in a record extension and subject
to a representation clause, retrieve the position and size from
the original record component.
gcc/testsuite/
* gnat.dg/rep_clause7.adb: New testcase.
--- gcc/ada/exp_util.adb
+++ gcc/ada/exp_util.adb
@@ -8402,9 +8402,26 @@ package body Exp_Util is
declare
Align_In_Bits : constant Nat := M * System_Storage_Unit;
+ Off : Uint;
+ Siz : Uint;
begin
- if Component_Bit_Offset (C) mod Align_In_Bits /= 0
- or else Esize (C) mod Align_In_Bits /= 0
+ -- For a component inherited in a record extension, the
+ -- clause is inherited but position and size are not set.
+
+ if Is_Base_Type (Etype (P))
+ and then Is_Tagged_Type (Etype (P))
+ and then Present (Original_Record_Component (C))
+ then
+ Off :=
+ Component_Bit_Offset (Original_Record_Component (C));
+ Siz := Esize (Original_Record_Component (C));
+ else
+ Off := Component_Bit_Offset (C);
+ Siz := Esize (C);
+ end if;
+
+ if Off mod Align_In_Bits /= 0
+ or else Siz mod Align_In_Bits /= 0
then
return True;
end if;
--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/rep_clause7.adb
@@ -0,0 +1,29 @@
+procedure Rep_Clause7 is
+
+ subtype Msg is String (1 .. 3);
+
+ type Root is tagged record
+ B : Boolean;
+ M : Msg;
+ end record;
+ for Root use record
+ B at 0 range 64 .. 64;
+ M at 0 range 65 .. 88;
+ end record;
+
+ type Ext is new Root with null record;
+
+ procedure Inner (T : Msg) is
+ begin
+ null;
+ end;
+
+ pragma Warnings (Off);
+ T1 : Root;
+ T2 : Ext;
+ pragma Warnings (On);
+
+begin
+ Inner (T1.M);
+ Inner (T2.M);
+end;