On Mon, 2006-03-06 at 00:31 +0100, Eric Botcazou wrote:

> 
> 
> cxa4025 and cxa4033 are very likely yours, originating in a miscompilation of
> the runtime (a-stwifi.adb) at -O2.  They succeed if the aforementioned unit 
> is compiled at -O2 -fno-tree-vrp.  You can pass -a to gnatmake to cause the 
> units to be recompiled locally.  Same for cxa4028 but with a-strsup.adb.
Here's the relevant bits from the .original dump for
Ada.Strings.Wide_Fixed.Trim:
Ada.Strings.Wide_Fixed.Trim (source, side)
[ ... ]

  if (side - 1 <= 1)
    {
      <<< Unknown tree: loop_stmt
  (integer) high >= (integer) low &&
VIEW_CONVERT_EXPR<wide_character[(long int) SAVE_EXPR
<source.P_BOUNDS->LB0>:MAX_EXPR <(long int) SAVE_EXPR
<source.P_BOUNDS->UB0>, (long int) SAVE_EXPR <source.P_BOUNDS->LB0> -
1>]>(*source.P_ARRAY)[(<unnamed type>) (integer) high]{lb: (long int)
SAVE_EXPR <source.P_BOUNDS->LB0> sz: 2} == 32


  high = (natural___XDLU_0__2147483647) ((integer) high - 1);
  <D5436> >>>
;
    }
 
Of particular interest is the (side - 1 <= 1) conditional which is
implementing this hunk of code from the Trim function:

 
      if Side = Right or else Side = Both then
         while High >= Low and then Source (High) = Wide_Space loop
            High := High - 1;
         end loop;
      end if;


side is an enumerated type with the following values


Symbolic name           Integer value
left                    0
right                   1
both                    2

The min/max values associated with the type specify that side
should have the values [0, 2].

Note carefully that the expression (side - 1) will produce a value
outside the defined min/max values for side's type [0, 2] when side
has the value "left".

Not surprisingly, we turn the .original code into this gimple code:

  D.5765 = side - 1;
  if (D.5765 <= 1)


Where D.5765 is of type ada__strings_trim_end, ie, it's got a range
of [0, 2].  So the computation will produce a result outside the
defined range of the type in the case where side == left.

Not surprisingly, the VRP code optimizes this test.  If we know that
D.5765's type has the values [0, 2], then the test is equivalent to
D.5765 != 2, and it's all downhill from there when side == left.

I think it's time to hand this one to the Ada guys :-0

Jeff



Reply via email to