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 <[email protected]>
* 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.