diff options
Diffstat (limited to 'gcc/ada/layout.adb')
-rw-r--r-- | gcc/ada/layout.adb | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/gcc/ada/layout.adb b/gcc/ada/layout.adb index 9b6c0ce9f94..60a44a90f87 100644 --- a/gcc/ada/layout.adb +++ b/gcc/ada/layout.adb @@ -2452,18 +2452,22 @@ package body Layout is Init_Size (E, 2 * System_Address_Size); -- When the target is AAMP, access-to-subprogram types are fat - -- pointers consisting of the subprogram address and a static link - -- (with the exception of library-level access types, where a simple - -- subprogram address is used). + -- pointers consisting of the subprogram address and a static link, + -- with the exception of library-level access types (including + -- library-level anonymous access types, such as for components), + -- where a simple subprogram address is used. elsif AAMP_On_Target and then - (Ekind (E) = E_Anonymous_Access_Subprogram_Type - or else (Ekind (E) = E_Access_Subprogram_Type - and then Present (Enclosing_Subprogram (E)))) + ((Ekind (E) = E_Access_Subprogram_Type + and then Present (Enclosing_Subprogram (E))) + or else + (Ekind (E) = E_Anonymous_Access_Subprogram_Type + and then + (not Is_Local_Anonymous_Access (E) + or else Present (Enclosing_Subprogram (E))))) then Init_Size (E, 2 * System_Address_Size); - else Init_Size (E, System_Address_Size); end if; @@ -3103,11 +3107,34 @@ package body Layout is -- the type, or the maximum allowed alignment. declare - S : constant Int := UI_To_Int (Esize (E)) / SSU; - A : Nat; + S : Int; + A : Nat; + Max_Alignment : Nat; begin + -- The given Esize may be larger that int'last because of a previous + -- error, and the call to UI_To_Int will fail, so use default. + + if Esize (E) / SSU > Ttypes.Maximum_Alignment then + S := Ttypes.Maximum_Alignment; + + -- If this is an access type and the target doesn't have strict + -- alignment and we are not doing front end layout, then cap the + -- alignment to that of a regular access type. This will avoid + -- giving fat pointers twice the usual alignment for no practical + -- benefit since the misalignment doesn't really matter. + + elsif Is_Access_Type (E) + and then not Target_Strict_Alignment + and then not Frontend_Layout_On_Target + then + S := System_Address_Size / SSU; + + else + S := UI_To_Int (Esize (E)) / SSU; + end if; + -- If the default alignment of "double" floating-point types is -- specifically capped, enforce the cap. |