This patch fixes an internal overflow when computing the alignment of a record component whose size is improperly specified as larger than the largest integer value.
Compiling the following must yield: prob.adb:6:38: warning: 4294967168 bits of "Unsigned_Integer_4" unused prob.adb:13:45: size for "Uint4" too small, minimum allowed is 16#1000_0000_0# --- procedure prob is Int_Size : constant := 4; Int_Size_Bit : constant := 4 * Standard'Storage_Unit; type Unsigned_Integer_4 is mod 2 ** Int_Size_Bit; for Unsigned_Integer_4'Size use 2 ** Int_Size_Bit; type Rec is record Uint4 : Unsigned_Integer_4; end record; for Rec use record Uint4 at 0 range 0 .. Int_Size_Bit - 1; end record; begin null; end; Tested on x86_64-pc-linux-gnu, committed on trunk 2012-07-09 Ed Schonberg <schonb...@adacore.com> * layout.adb (Set_Elem_Alignment): Protect against meaningless size clause, to prevent overflow in internal computation of alignment.
Index: layout.adb =================================================================== --- layout.adb (revision 189366) +++ layout.adb (working copy) @@ -3103,11 +3103,22 @@ -- the type, or the maximum allowed alignment. declare - S : constant Int := UI_To_Int (Esize (E)) / SSU; + 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; + + 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.