summaryrefslogtreecommitdiff
path: root/gcc/ada/layout.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/layout.adb')
-rw-r--r--gcc/ada/layout.adb45
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.