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

Re: C as intermediate language, signed integer overflow and -ftrapv


On Fri, Jul 25, 2014 at 12:41 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Fri, Jul 25, 2014 at 12:35 PM, Richard Biener
> <richard.guenther@gmail.com> wrote:
>> On Fri, Jul 25, 2014 at 10:43 AM, Thomas Mertes <thomas.mertes@gmx.at> wrote:
>>> On Thu, Jul 24 at 10:36 PM, Richard Biener <richard.guenther@gmail.com> wrote:
>>>> Fact is that if somebody is interested in
>>>> -ftrapv he/she is welcome to contribute patches.  Especially testing
>>>> coverage is poor.
>>>
>>> As I said I have test programs for integer overflow (not written
>>> in C). Now I have converted one test program to C. This program
>>> checks if an int64_t overflow raises SIGABRT or SIGILL. The name of
>>> the program is chkovf64.c and I have uploaded it to
>>>
>>>   http://sourceforge.net/projects/seed7/files/
>>>
>>> It is licenced with GPL. You can use it to improve the testing
>>> coverage of gcc. When I compile it with:
>>>
>>>   gcc -ftrapv chkovf64.c -o chkovf64
>>>
>>> it writes a lot of warnings about "integer overflow in expression".
>>> Running chkovf64 shows that -ftrapv does not work correct.
>>
>> That's https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61893 - basically
>> as soon as we can constant-fold we lose the trap.  Which is probably
>> not important for practical purposes, but you have a point here.
>>
>> Note the slight complication with static initializers that _do_ have
>> to simplify to something (well, maybe not with -ftrapv ...).  Joseph,
>> I can easily make fold fail if you don't explicitely use a constant
>> folding API (int_const_binop) and -ftrapv is set.  Is it valid to
>> reject
>>
>> static int x = __INT_MAX__ + 1;
>>
>> with an initializer-not-constant error?
>>
>> Index: fold-const.c
>> ===================================================================
>> --- fold-const.c        (revision 212388)
>> +++ fold-const.c        (working copy)
>> @@ -1121,7 +1121,12 @@
>>    STRIP_NOPS (arg2);
>>
>>    if (TREE_CODE (arg1) == INTEGER_CST)
>> -    return int_const_binop (code, arg1, arg2);
>> +    {
>> +      tree res = int_const_binop (code, arg1, arg2);
>> +      if (res && TYPE_OVERFLOW_TRAPS (TREE_TYPE (arg1)) && TREE_OVERFLOW (res))
>> +        return NULL_TREE;
>> +      return res;
>> +    }
>>
>>    if (TREE_CODE (arg1) == REAL_CST)
>>      {
>
> Just checked and for
>
> static int x = __INT_MAX__ + 1;
> int main()
> {
>   return __INT_MAX__ + 1;
> }
>
> we still fold the initializer (and warn) but no longer warn about the overflow
> in main() but generate a properly trapping call to __addvsi (at -O0, with
> optimization CCP manages to constant fold this).

Fixing that reveals

(insn 5 4 6 (set (reg:SI 4 si)
        (const_int 1 [0x1])) t.c:7 -1
     (nil))

(insn 6 5 7 (set (reg:SI 5 di)
        (const_int 2147483647 [0x7fffffff])) t.c:7 -1
     (nil))

(call_insn/u 7 6 8 (set (reg:SI 0 ax)
        (call (mem:QI (symbol_ref:DI ("__addvsi3") [flags 0x41]) [0  S1 A8])
            (const_int 0 [0]))) t.c:7 -1
     (expr_list:REG_EH_REGION (const_int -2147483648 [0xffffffff80000000])
        (nil))
    (expr_list (use (reg:SI 4 si))
        (expr_list (use (reg:SI 5 di))
            (nil))))

(insn 8 7 9 (set (reg:SI 86 [ D.1753 ])
        (reg:SI 0 ax)) t.c:7 -1
     (expr_list:REG_EQUAL (plus:SI (const_int 2147483647 [0x7fffffff])
            (const_int 1 [0x1]))
        (nil)))

(note the REG_EQUAL note which CSE happily consumes).  We can just
omit the REG_EQUAL notes here which results in a working testcase.

Richard.

> Richard.
>
>>
>>> It seems that gcc thinks that writing a warning is enough and
>>> raising a signal at runtime is not necessary. For human
>>> programmers this makes sense, since they read the warnings and
>>> correct the code. But for generated C programs this is not the
>>> right strategy. There are different needs when C is used as
>>> intermediate language.
>>>
>>> Maybe all -ftrapv problems uncovered by chkovf64.c are because
>>> of this. Unfortunately there are also other test cases where
>>> a signal is not raised although a signed integer overflow occurred.
>>> This happens in a much bigger program and until now I was not
>>> able to create a simple test case from it.
>>
>> Yes, not all optimizations may be aware of -ftrapv.
>>
>> Richard.
>>
>>> I used clang version 3.4-1 to proof that chkovf64.c works correct.
>>> When I compile it with:
>>>
>>>   clang -ftrapv chkovf64.c -o chkovf64
>>>
>>> and start chkovf64 afterwards it writes:
>>>
>>> Overflow checking of negation works correct.
>>> Overflow checking of addition works correct.
>>> Overflow checking of addition assignment works correct.
>>> Overflow checking of subtraction works correct.
>>> Overflow checking of subtraction assignment works correct.
>>> Overflow checking of incr works correct.
>>> Overflow checking of decr works correct.
>>> Overflow checking of multiplication works correct.
>>> Overflow checking of multiplication assignment works correct.
>>>
>>> Greetings Thomas Mertes
>>>
>>> --
>>> Seed7 Homepage:  http://seed7.sourceforge.net
>>> Seed7 - The extensible programming language: User defined statements
>>> and operators, abstract data types, templates without special
>>> syntax, OO with interfaces and multiple dispatch, statically typed,
>>> interpreted or compiled, portable, runs under linux/unix/windows.


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