From patchwork Mon Jul 9 13:05:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Ada] Proper handling of meaningless size clauses Date: Mon, 09 Jul 2012 03:05:44 -0000 From: Arnaud Charlet X-Patchwork-Id: 169819 Message-Id: <20120709130544.GA16576@adacore.com> To: gcc-patches@gcc.gnu.org Cc: Ed Schonberg 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 * 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.