summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-24 13:24:11 +0000
committerhainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-24 13:24:11 +0000
commit8a663e44a5a06b3829c058863087d1c4fd4b3617 (patch)
treed4a267737cd34ccd9e86c61ac0f728f30d7635cc
parentced5bc56a892f34678fa445d3921ca683e5a4b64 (diff)
downloadgcc-8a663e44a5a06b3829c058863087d1c4fd4b3617.tar.gz
2008-04-24 Olivier Hainque <hainque@adacore.com>
ada/ * trans.c (Attribute_to_gnu) <case Attr_Length>: Length * computation doesn't require signed arithmetic anymore. testsuite/ * gnat.dg/concat_length.adb: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@134627 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/trans.c21
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/concat_length.adb15
4 files changed, 34 insertions, 11 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 4da4abc23bd..a29ffde4448 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,8 @@
+2008-04-24 Olivier Hainque <hainque@adacore.com>
+
+ * trans.c (Attribute_to_gnu) <case Attr_Length>: Length computation
+ doesn't require signed arithmetic anymore.
+
2008-04-23 Paolo Bonzini <bonzini@gnu.org>
* trans.c (Attribute_to_gnu): Don't set TREE_INVARIANT.
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c
index cb0e8c6beec..07bdc69a4e4 100644
--- a/gcc/ada/trans.c
+++ b/gcc/ada/trans.c
@@ -1234,9 +1234,16 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
}
else
{
- tree gnu_compute_type
- = signed_or_unsigned_type_for
- (0, get_base_type (gnu_result_type));
+ /* We used to compute the length as max (hb - lb + 1, 0),
+ which could overflow for some cases of empty arrays, e.g.
+ when lb == index_type'first. We now compute the length as
+ (hb < lb) ? 0 : hb - lb + 1, which would only overflow in
+ much rarer cases, for extremely large arrays we expect
+ never to encounter in practice. In addition, the former
+ computation required the use of potentially constraining
+ signed arithmetic while the latter doesn't. */
+
+ tree gnu_compute_type = get_base_type (gnu_result_type);
tree index_type
= TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type));
@@ -1245,14 +1252,6 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
tree hb
= convert (gnu_compute_type, TYPE_MAX_VALUE (index_type));
- /* We used to compute the length as max (hb - lb + 1, 0),
- which could overflow for some cases of empty arrays, e.g.
- when lb == index_type'first.
-
- We now compute it as (hb < lb) ? 0 : hb - lb + 1, which
- could overflow as well, but only for extremely large arrays
- which we expect never to encounter in practice. */
-
gnu_result
= build3
(COND_EXPR, gnu_compute_type,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 187c8a91202..38e76fef8e6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2008-04-24 Olivier Hainque <hainque@adacore.com>
+
+ * gnat.dg/concat_length.adb: New test.
+
2008-04-24 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/35982
diff --git a/gcc/testsuite/gnat.dg/concat_length.adb b/gcc/testsuite/gnat.dg/concat_length.adb
new file mode 100644
index 00000000000..fe482d98d0a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/concat_length.adb
@@ -0,0 +1,15 @@
+-- { dg-do run }
+
+procedure Concat_Length is
+ type Byte is mod 256;
+ for Byte'Size use 8;
+ type Block is array(Byte range <>) of Integer;
+
+ C0: Block(1..7) := (others => 0);
+ C1: Block(8..255) := (others => 0);
+ C2: Block := C0 & C1;
+begin
+ if C2'Length /= 255 then
+ raise Program_Error;
+ end if;
+end;