summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/gcc-interface/trans.c11
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/specs/last_bit.ads19
4 files changed, 36 insertions, 3 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 9eac544c955..8cd13769ddd 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,10 @@
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>
+
* gcc-interface/gigi.h (create_type_decl): Adjust prototype.
(create_label_decl): Complete prototype.
(process_attributes): Declare.
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 13767e9dd9b..4b71568b8ba 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -2080,14 +2080,19 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b6bb1b7ed3a..5cb426f8542 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2013-05-26 Eric Botcazou <ebotcazou@adacore.com>
+ * gnat.dg/specs/last_bit.ads: New test.
+
+2013-05-26 Eric Botcazou <ebotcazou@adacore.com>
+
* gnat.dg/specs/machine_attribute.ads: New test.
2013-05-26 Eric Botcazou <ebotcazou@adacore.com>
diff --git a/gcc/testsuite/gnat.dg/specs/last_bit.ads b/gcc/testsuite/gnat.dg/specs/last_bit.ads
new file mode 100644
index 00000000000..ecfc2540a8a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/last_bit.ads
@@ -0,0 +1,19 @@
+-- { 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;