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 <ebotca...@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 <ebotca...@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. */