On Fri, Jul 25, 2014 at 12:41 PM, Richard Biener <richard.guent...@gmail.com> wrote: > On Fri, Jul 25, 2014 at 12:35 PM, Richard Biener > <richard.guent...@gmail.com> wrote: >> On Fri, Jul 25, 2014 at 10:43 AM, Thomas Mertes <thomas.mer...@gmx.at> wrote: >>> On Thu, Jul 24 at 10:36 PM, Richard Biener <richard.guent...@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.