From 22a812674cef168628bcf4760ef8faba4bb4cdb0 Mon Sep 17 00:00:00 2001 From: Olivier Hainque Date: Thu, 24 Apr 2008 13:24:11 +0000 Subject: [PATCH] trans.c (Attribute_to_gnu): Length 2008-04-24 Olivier Hainque ada/ * trans.c (Attribute_to_gnu) : Length * computation doesn't require signed arithmetic anymore. testsuite/ * gnat.dg/concat_length.adb: New test. From-SVN: r134627 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/trans.c | 21 ++++++++++----------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/concat_length.adb | 15 +++++++++++++++ 4 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/concat_length.adb 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 + + * trans.c (Attribute_to_gnu) : Length computation + doesn't require signed arithmetic anymore. + 2008-04-23 Paolo Bonzini * 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 + + * gnat.dg/concat_length.adb: New test. + 2008-04-24 Ira Rosen 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; -- 2.30.2