trans.c (Attribute_to_gnu): Length
authorOlivier Hainque <hainque@adacore.com>
Thu, 24 Apr 2008 13:24:11 +0000 (13:24 +0000)
committerOlivier Hainque <hainque@gcc.gnu.org>
Thu, 24 Apr 2008 13:24:11 +0000 (13:24 +0000)
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.

From-SVN: r134627

gcc/ada/ChangeLog
gcc/ada/trans.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/concat_length.adb [new file with mode: 0644]

index 4da4abc23bda75854adba899031258bbf9c5457a..a29ffde444815ee7534c6cb4cb6793414b2188c4 100644 (file)
@@ -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.
index cb0e8c6beece6704fb9286595975f7acbdeaa760..07bdc69a4e4a0c317ea31e08d85dd3f831dc1c47 100644 (file)
@@ -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,
index 187c8a9120241d260c21632a45a7af6638a0d2ff..38e76fef8e65cfd3c13dd79b3f5bd56abcbceeb0 100644 (file)
@@ -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 (file)
index 0000000..fe482d9
--- /dev/null
@@ -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;