This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Fix 'Length not to require signed arithmetic anymore


The testcase below is expected to compile and run silently. On at least
x86[_64]-linux, it raises a spurious Program_Error instead.

    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;

Assembly inspection revealed that the code for the concatenation
function computes the length of the second argument using 8bit signed
arithmetic, where 255 is interpreted as -1 and the second argument is
perceived as empty (bounds 8 .. -1). This is actually very visible
from the .original tree dump, as

  Concat_Length.C13b (struct concat_length__block___XUP S1,
                      struct concat_length__block___XUP S2)
  { ... 
  SAVE_EXPR < (SIGNED_8) SAVE_EXPR <S2.P_BOUNDS->UB0>
               < (SIGNED_8) SAVE_EXPR < S2.P_BOUNDS->LB0>
              ? 0
              : ((SIGNED_8) SAVE_EXPR <S2.P_BOUNDS->UB0>
                - (SIGNED_8) SAVE_EXPR <S2.P_BOUNDS->LB0>) + 1>;
  ...

The use of signed arithmetic is forced by

     Attribute_to_gnu
     ...
       case Attr_Length:

       tree gnu_compute_type
          = gnat_signed_or_unsigned_type
              (0, get_base_type (gnu_result_type));

This used to be required by our former mode of length computation:

        /* We used to compute the length as max (hb - lb + 1, 0), [...]

and is not required anymore since ...

           We now compute it as (hb < lb) ? 0 : hb - lb + 1 [...]

The attached patch stops the signed arithmetic enforcement, which
fixes the test at hand.  Tested on x86_64-suse-linux.

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.

A problem remains after that, still: our length computation over a
8bit index type doesn't work, even unsigned, for the widest possible
array (bounds 0 .. 255), as the length (256) doesn't fit the
result/computation type.

The more general issue here is the choice of an inappropriate type by
the front-end for the attribute reference node. This will be addressed
separately.




Attachment: concat_length.dif
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]