diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2018-08-21 14:46:40 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2018-08-21 14:46:40 +0000 |
commit | 294e7bbb9eb0b1f8d0484e9ddb562a08f7505cab (patch) | |
tree | 4f070890782e75ac457fb293811a7608860bb10c /gcc/ada | |
parent | 2e5df2955f9ec8deafeb2978fcb38fb99f2660fd (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ada/exp_util.adb | 21 |
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; |