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: [email protected]
ReportedBy: [email protected]
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);
}