GCC claims to follow C99 Annex F when converting a floating value to an integer
type when the integral part exceeds the range of the integer type (C99 6.3.1.4
and F.4). Annex F says that in this case the conversion raises the "invalid"
floating-point exception. On powerpc64-linux and x86_64-linux, however, the
instruction that is used to convert double to int converts to a 64-bit integer,
not a 32-bit register, so the exception is not raised. On powerpc64-linux with
-m64 the instruction is fctidz (floating convert to integer doubleword with
round toward zero). If I replace that instruction with fctiwz (convert to
integer word) in the .s file and compile that, the code behaves as expected.
Here's a small test case:
#include <fenv.h>
extern void abort (void);
double x = 4294967296.0;
unsigned int i;
int
main ()
{
#pragma STDC FENV_ACCESS ON
feclearexcept (FE_ALL_EXCEPT);
i = x; /* value exceeds the range of 32-bit int */
if (! fetestexcept (FE_INVALID))
abort ();
return 0;
}
I see this behavior in all powerpc64-linux compilers I've checked from 3.2
through mainline. The exception is raised for tests compiled with -m32.
This is a problem for applications that try to detect such invalid conversions
after checking for __STDC_IEC_559__, which claims that the implementation
conforms to Annex F.
A possibly-related issue is that this macro is defined in a header file
provided by glibc, not by GCC.
--
Summary: float to int conversion doesn't raise invalid exception
Product: gcc
Version: 4.0.4
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: janis at gcc dot gnu dot org
GCC target triplet: powerpc64-linux, x86_64-linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27682