aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2018-08-21 14:46:40 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2018-08-21 14:46:40 +0000
commit294e7bbb9eb0b1f8d0484e9ddb562a08f7505cab (patch)
tree4f070890782e75ac457fb293811a7608860bb10c /gcc/ada
parent2e5df2955f9ec8deafeb2978fcb38fb99f2660fd (diff)
downloadgcc-294e7bbb9eb0b1f8d0484e9ddb562a08f7505cab.zip
gcc-294e7bbb9eb0b1f8d0484e9ddb562a08f7505cab.tar.gz
gcc-294e7bbb9eb0b1f8d0484e9ddb562a08f7505cab.tar.bz2
[Ada] Fix internal error on extension of record with representation clause
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. 2018-08-21 Eric Botcazou <ebotcazou@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. From-SVN: r263717
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog7
-rw-r--r--gcc/ada/exp_util.adb21
2 files changed, 26 insertions, 2 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index df4a9db..27bb79d 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,10 @@
+2018-08-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ * 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.
+
2018-08-21 Ed Schonberg <schonberg@adacore.com>
* sem_util.ads, sem_util.adb (New_External_Entity): Type of
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 3bed508..632c879 100644
--- a/gcc/ada/exp_util.adb
+++ b/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;