This is the mail archive of the gcc-bugs@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]

[Bug tree-optimization/30911] VRP fails to eliminate range checks in Ada code



------- Comment #15 from baldrick at free dot fr  2007-02-23 10:03 -------
Subject: Re:  VRP fails to eliminate range checks in Ada code

On Friday 23 February 2007 10:22:15 rguenth at gcc dot gnu dot org wrote:
> 
> ------- Comment #13 from rguenth at gcc dot gnu dot org  2007-02-23 09:22 -------
> In reply to comment #8
> 
> To understand the issues a little bit more -- are there any requirements on
> overflow behavior of the _base_ type?  Suppose a type T with range -100..120
> has indeed be assigned a signed char with precision 8 (and so range -128..127).
> If we now do arithmetic like (to add two Ts)
> 
>   T foo(T t1, T t2)
>   {
>     signed char t1_base = (signed char)t1;
>     signed char t2_base = (signed char)t2;
>     signed char res_base = t1_base + t2_base;
>     if (res_base < 10 || res_base > 120)
>       abort ();
>     return (T)res_base;
>   }
> 
> is it ok to not raise a constraint error if I happen to add 100 and 100 which
> wraps on the machine in signed char precision back to a valid value inside
> the range of T?

The Ada language requires the compiler to insert checks that arithmetic in
the base type does not overflow, and to raise an exception if it does.  To
be more precise, it is allowed either to raise an exception or return the
mathematically correct result (i.e. what you would get if the range of your
base type was infinite).  For example, calculating (x + INT_MAX) - INT_MAX
is allowed to return x or raise an exception.  The Ada f-e doesn't insert
the required checks by default - you have to give it the -gnato switch if
you want full language conformance (it doesn't do it by default because it
is too expensive; the Ada f-e really wants to use -ftrapv but doesn't because
-ftrapv doesn't work reliably enough, instead it inserts explicit checks).
Thus in standard conformant -gnato mode the problem you describe can never
happen.  What about the default mode, without -gnato?  The language provides
a way of suppressing checks, in this case the check is called Overflow_Check.
Not using -gnato is equivalent to suppressing Overflow_Check everywhere.  The
language standard says "If a given check has been suppressed, and the
corresponding error situation occurs, the execution of the program is
erroneous."
Thus you may reasonably assume that the result of signed overflow is undefined.
So you can do what you like here, the same as in C.  I think, as a general
rule,
that if you assume arithmetic on base types is the same as in C, then you won't
go wrong.

PS: For unsigned types the situation is different, as in C, namely addition has
wraparound semantics.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30911


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