On solaris 10, the C99 macros fpclassify, isinf, isfinite and isnormal are
created for GCC by fixincludes. The resulting macros do not properly guard
against raising FP exceptions in various cases. Here are the current macro
definitions as created by fixincludes into iso/math_c99.h:
#undef fpclassify
#define fpclassify(x) \
__extension__ ({ __typeof(x) __x_fp = (x); \
isnan(__x_fp) \
? FP_NAN \
: isinf(__x_fp) \
? FP_INFINITE \
: isnormal(__x_fp) \
? FP_NORMAL \
: __x_fp == 0.0 \
? FP_ZERO \
: FP_SUBNORMAL; })
#undef isfinite
#define isfinite(x) \
__extension__ ({ __typeof (x) __x_f = (x); \
__builtin_expect(!isnan(__x_f - __x_f), 1); })
#undef isinf
#define isinf(x) \
__extension__ ({ __typeof (x) __x_i = (x); \
__builtin_expect(!isnan(__x_i) && !isfinite(__x_i), 0); })
#undef isnan
#define isnan(x) __builtin_isnan(x)
#undef isnormal
#define isnormal(x) \
__extension__ ({ __typeof(x) __x_n = (x); \
if (__x_n < 0.0) __x_n = -__x_n; \
__builtin_expect(isfinite(__x_n) \
&& (sizeof(__x_n) == sizeof(float) \
? __x_n >= __FLT_MIN__ \
: sizeof(__x_n) == sizeof(long
double) \
? __x_n >= __LDBL_MIN__ \
: __x_n >= __DBL_MIN__), 1); })
Problems I've noted so far include:
1. The isfinite macro uses a subtraction. If supplied with inf, the inf-inf
expr results in a NaN, which raises an exception.
2. The isfinite macro is used in fpclassify and isinf, which can therefore
also raise exceptions.
3. The isnormal macro uses ordered comparisons, which raise exceptions when
supplied with NaN.
This occurs in 4.1.x, 4.2.x and mainline.
--
Summary: C99 fpclassify, isinf, isfinite, isnormal may raise FP
exceptions
Product: gcc
Version: 4.1.3
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: ghazi at gcc dot gnu dot org
GCC target triplet: sparc-sun-solaris2.10
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32641