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

             Bug #: 52478
           Summary: -ftrapv calls the wrong functions in libgcc
    Classification: Unclassified
           Product: gcc
           Version: 4.8.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: middle-end
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: bur...@gcc.gnu.org


As PR 19020 has been closed ("let's ditch antiquated stuff and start afresh") -
open a fresh bug.


Using -ftrapv works with i368-gnu-linux:

$ gcc -m32 -ftrapv hjfff.c && ./a.out
Aborted (core dumped)
$

But not on x86-64-gnu-linux:
$ gcc -m64 -ftrapv hjfff.c && ./a.out
$


In the debugger, one sees:

a) i386:

__addvsi3 (a=2147483647, b=1) at
/home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:79
(gdb) pt a
type = int


b) x86-64:

(gdb)
__addvdi3 (a=2147483647, b=1) at
/home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:82
(gdb) pt a
type = long int

Thus, there is no overflow in that function.


THUS: On i386 it calls the correct function but on x86-64 it should call the SI
not the DI function.

 * * *

For long/LONG_MAX, one has again:

a) -m32

__addvsi3 (a=2147483647, b=1) at
/home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:79
79      {
(gdb) pt a
type = int

b) -m64

__addvdi3 (a=9223372036854775807, b=1) at
/home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:82
82        if (b >= 0 ? w < a : w > a)
(gdb) pt a
type = long int


THUS: x86-64 calls correctly the DI function but i386 wrongly the SI function

 * * *

long long / LLONG_MAX:

a) -m32:

__addvdi3 (a=9223372036854775807, b=1) at
/home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:82
82        if (b >= 0 ? w < a : w > a)
(gdb) pt a
type = long int

b) -m64

__addvdi3 (a=9223372036854775807, b=1) at
/home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:82
82        if (b >= 0 ? w < a : w > a)
(gdb) pt a  
type = long int


THUS: Both x86-64 and i386 call the "long int" instead of the "long long"
function. I had exepected a TI version, which does not seem to exist.

 * * *


#include <limits.h>

int __attribute__((noinline))
iaddv (int a, int b)
{
  return a + b;
}

int main(void)
{
  return iaddv (INT_MAX, 1);
}

Reply via email to