On Tue, 2006-02-28 at 18:42 +0100, Eric Botcazou wrote:
> > Basically with the way Ada's setting of TYPE_MIN_VALUE/TYPE_MAX_VALUE
> > effectively makes them useless as we can not rely on them to
> > actually reflect the set of values allowed in an object.
> 
> Sorry, but why are you saying "we can not rely on them to actually reflect 
> the 
> set of values allowed in an object"?  I think we can.  My understanding is 
> that the only subtlety with Ada is the TYPE_PRECISION thing, as you've 
> written in your patch:
Here's a great example from uintp.adb (which is the cause of the
testsuite hang FWIW)

We have a loop with the following termination code in uintp.num_bits

  # BLOCK 8
  # PRED: 5 [100.0%]  (fallthru,exec) 6 (fallthru,dfs_back,exec)
  # num_2 = PHI <num_49(5), num_10(6)>;
  # bits_1 = PHI <bits_50(5), bits_13(6)>;
<L7>:;
  num.265_5 = (types__TintB) num_2;
  if (num.265_5 <= 0) goto <L5>; else goto <L4>;
  # SUCC: 7 (true,exec) 6 (false,exec)

num_2 has the type:



 <integer_type 0x4006aa6c types__nat___XDLU_0__2147483647
    type <integer_type 0x4006a33c types__TintB sizes-gimplified
asm_written public visited SI
        size <integer_cst 0x400163d8 constant invariant 32>
        unit size <integer_cst 0x40016168 constant invariant 4>
        user align 32 symtab 1074169056 alias set 8 precision 32 min
<integer_cst 0x4006c810 -2147483648> max <integer_cst 0x4006c870
2147483647> RM size <integer_cst 0x400163d8 32>>
    sizes-gimplified asm_written public visited unsigned SI size
<integer_cst 0x400163d8 32> unit size <integer_cst 0x40016168 4>
    user align 32 symtab 1080625184 alias set 8 precision 32 min
<integer_cst 0x40075498 0> max <integer_cst 0x4006c870 2147483647>
    RM size <integer_cst 0x40016318 type <integer_type 0x4002505c
bit_size_type> constant invariant 31>>


Note carefully, it has a min/max value of 0, 21474833647.  So
not surprisingly we have a range of [0, INF] recorded for num_2.

So given the range [0, INF] and the test num_5 <= 0 we can
(and do) simplify the test to num_5 == 0.


Sooooo, why am I bringing this up?  Because num can actually have
the value 0x80000000 at runtime, which is out of its type's
MIN/MAX range.  And what do you think happens?  Well, given the
(valid) simplification of the loop test and the way "num" is
assigned within the loop (num = num / 2), the loop never terminates.

How do we get the value 0x80000000 into "num"?  Let's look at
the first two blocks in our function:



  # BLOCK 2
  # PRED: ENTRY (fallthru,exec)
  #   uintp__uints__table_41 = V_MAY_DEF <uintp__uints__table_14>;
  #   uintp__udigits__table_42 = V_MAY_DEF <uintp__udigits__table_23>;
  #   TMT.2002_43 = V_MAY_DEF <TMT.2002_39>;
  #   TMT.2003_44 = V_MAY_DEF <TMT.2003_40>;
  D.2350_4 = uintp__ui_is_in_int_range (input_3);
  if (D.2350_4 != 0) goto <L0>; else goto <L1>;
  # SUCC: 3 (true,exec) 4 (false,exec)

  # BLOCK 3
  # PRED: 2 (true,exec)
<L0>:;
  #   uintp__uints__table_45 = V_MAY_DEF <uintp__uints__table_41>;
  #   uintp__udigits__table_46 = V_MAY_DEF <uintp__udigits__table_42>;
  #   TMT.2002_47 = V_MAY_DEF <TMT.2002_43>;
  #   TMT.2003_48 = V_MAY_DEF <TMT.2003_44>;
  D.2351_34 = uintp__ui_to_int (input_3);
  D.2352_35 = (types__TintB) D.2351_34;
  D.2353_36 = ABS_EXPR <D.2352_35>;
  num_37 = (types__nat___XDLU_0__2147483647) D.2353_36;
  goto <bb 5> (<L2>);
  # SUCC: 5 (fallthru,exec)

Let's assume that uintp__ui_is_int_range returns true (as it does) 
for our input (2000000007).

uintp__ui_to_int returns 0x80000000  [For you non-Ada folks,
uintp__ui_to_int doesn't do what you might initially think].  And
ABS (0x80000000) is 0x80000000 which we then proceed to stuff
into num_37 after a couple typecasts.  Voila, we have a value
in a variable that is out of the MIN/MAX range associated with
the variable.


> +   /* Ada creates sub-types where TYPE_MIN_VALUE/TYPE_MAX_VALUE do not
> +      cover the entire range of values allowed by TYPE_PRECISION.
> + 
> +      We do not want to optimize away conversions to such types.  Long
> +      term I'd rather see the Ada front-end fixed.  */
> 
> The obvious question would then be, why bother with TYPE_MIN_VALUE and 
> TYPE_MAX_VALUE if they can be directly deduced from TYPE_PRECISION and 
> TYPE_UNSIGNED?  How do you represent subtypes with non-canonical bounds?
I wouldn't have a problem with non-canonical bounds if there were
no way to get a value into an object which is outside the 
bounds.  But if we can get values into the object which are outside
those bounds, then either the bounds are incorrect or the program
is invalid.  

Jeff

Reply via email to