@@ -303,8 +303,12 @@ package body Freeze is
if Known_Esize (Typ) and then Known_Alignment (Typ) then
Align := Alignment_In_Bits (Typ);
- if Align > Esize (Typ) and then Align <= System_Max_Integer_Size then
- Set_Esize (Typ, Align);
+ if Align > Esize (Typ) then
+ if Align > System_Max_Integer_Size then
+ pragma Assert (Serious_Errors_Detected > 0);
+ else
+ Set_Esize (Typ, Align);
+ end if;
end if;
end if;
end Adjust_Esize_For_Alignment;
@@ -6573,6 +6573,21 @@ package body Sem_Ch13 is
("alignment for & set to Maximum_Aligment??", Nam);
Set_Alignment (U_Ent, Max_Align);
+ -- Because Object_Size must be multiple of Alignment (in bits),
+ -- System_Max_Integer_Size limit for discrete and fixed point
+ -- types implies a limit on alignment for such types.
+
+ elsif (Is_Discrete_Type (U_Ent)
+ or else Is_Fixed_Point_Type (U_Ent))
+ and then Align > System_Max_Integer_Size / System_Storage_Unit
+ then
+ Error_Msg_N
+ ("specified alignment too large for discrete or fixed " &
+ "point type", Expr);
+ Set_Alignment
+ (U_Ent, UI_From_Int (System_Max_Integer_Size /
+ System_Storage_Unit));
+
-- All other cases
else
@@ -32,18 +32,4 @@ package Alignment2 is
end record;
for R4'Alignment use 32;
- -- warning
- type I1 is new Integer_32;
- for I1'Size use 32;
- for I1'Alignment use 32; -- { dg-warning "suspiciously large alignment" }
-
- -- warning
- type I2 is new Integer_32;
- for I2'Alignment use 32; -- { dg-warning "suspiciously large alignment" }
-
- -- OK, big size
- type I3 is new Integer_32;
- for I3'Size use 32 * 8; -- { dg-warning "unused" }
- for I3'Alignment use 32;
-
end Alignment2;
new file mode 100644
@@ -0,0 +1,36 @@
+-- { dg-do compile }
+
+with Interfaces; use Interfaces;
+
+package Alignment2_Bis is
+
+ pragma Warnings (Off, "*size*");
+
+ -- OK, big size
+ type R3 is record
+ A, B, C, D : Integer_8;
+ end record;
+ for R3'Size use 32 * 8;
+ for R3'Alignment use 32;
+
+ -- OK, big size
+ type R4 is record
+ A, B, C, D, E, F, G, H : Integer_32;
+ end record;
+ for R4'Alignment use 32;
+
+ -- warning
+ type I1 is new Integer_32;
+ for I1'Size use 32;
+ for I1'Alignment use 32; -- { dg-error "error: specified alignment too large for discrete or fixed point type" }
+
+ -- warning
+ type I2 is new Integer_32;
+ for I2'Alignment use 32; -- { dg-error "error: specified alignment too large for discrete or fixed point type" }
+
+ -- OK, big size
+ type I3 is new Integer_32;
+ for I3'Size use 32 * 8;
+ for I3'Alignment use 32; -- { dg-error "error: specified alignment too large for discrete or fixed point type" }
+
+end Alignment2_Bis;
From: Steve Baird <baird@adacore.com> For a discrete (or fixed-point) type T, GNAT requires that T'Object_Size shall be a multiple of T'Alignment * 8 . GNAT also requires that T'Object_Size shall be no larger than Standard'Max_Integer_Size. For a sufficiently-large alignment specification, these requirements can conflict. The conflict is resolved by rejecting such alignment specifications (which were previously accepted in some cases). gcc/ada/ * freeze.adb (Adjust_Esize_For_Alignment): Assert that a valid Alignment specification cannot result in adjusting the given type's Esize to be larger than System_Max_Integer_Size. * sem_ch13.adb (Analyze_Attribute_Definition_Clause): In analyzing an Alignment specification, enforce the rule that a specified Alignment value for a discrete or fixed-point type shall not be larger than System_Max_Integer_Size / 8 . gcc/testsuite/ChangeLog: * gnat.dg/specs/alignment2.ads: Adjust. * gnat.dg/specs/alignment2_bis.ads: New test. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/freeze.adb | 8 +++-- gcc/ada/sem_ch13.adb | 15 ++++++++ gcc/testsuite/gnat.dg/specs/alignment2.ads | 14 -------- .../gnat.dg/specs/alignment2_bis.ads | 36 +++++++++++++++++++ 4 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/specs/alignment2_bis.ads