This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Fix 'Last_Bit attribute applied to zero-sized type


The value of the attribute should be -1 if an object of such a type is placed 
on a storage unit boundary, but the compiler was generating Storage_Error.

Tested on x86_64-suse-linux, applied on all active branches.


2013-05-26  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Last_Bit>: Add kludge
	to avoid generating an overflow for -1.


2013-05-26  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/specs/last_bit.ads: New test.


-- 
Eric Botcazou
-- { dg-do compile }

package Last_Bit is

   Max_Components : constant := 100;
   type Count_Type is new Natural range 0 .. Max_Components;
   subtype Index_Type is Count_Type range 1 .. Count_Type'Last;
   
   type List_Type is array (Index_Type range <>) of Integer;

   type Record_Type (Count : Count_Type := 0) is record
      List : List_Type (1 .. Count);
   end record;

   Null_Record : Record_Type (Count => 0);

   List_Last_Bit : Integer := Null_Record.List'Last_Bit;

end Last_Bit;
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 199336)
+++ gcc-interface/trans.c	(working copy)
@@ -2080,14 +2080,19 @@ Attribute_to_gnu (Node_Id gnat_node, tre
 	    gnu_result = bitsize_int (bitpos % BITS_PER_UNIT);
 	    gnu_result = size_binop (PLUS_EXPR, gnu_result,
 				     TYPE_SIZE (TREE_TYPE (gnu_prefix)));
-	    gnu_result = size_binop (MINUS_EXPR, gnu_result,
-				     bitsize_one_node);
+	    /* ??? Avoid a large unsigned result that will overflow when
+	       converted to the signed universal_integer.  */
+	    if (integer_zerop (gnu_result))
+	      gnu_result = integer_minus_one_node;
+	    else
+	      gnu_result
+		= size_binop (MINUS_EXPR, gnu_result, bitsize_one_node);
 	    break;
 
 	  case Attr_Bit_Position:
 	    gnu_result = gnu_field_bitpos;
 	    break;
-		}
+	  }
 
 	/* If this has a PLACEHOLDER_EXPR, qualify it by the object we are
 	   handling.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]