__builtin_isinf, __builtin_isnan and the various __builtin_is* functions for unordered comparisons are declared as functions taking variable arguments so they can be used directly to implement the corresponding C99 type-generic macros. However, __builtin_isinf does not work properly as type-generic as it sometimes expands to a function call and that call is always to isinf - which takes a double argument, not float or long double, if it is defined as a function at all. For example, the following wrongly returns 1 on x86_64-unknown-linux-gnu, where the double and long double calling conventions are different.
#include <float.h> double i = __builtin_inf(); int j; int x(long double ld) { j = __builtin_isinf(i); return __builtin_isinf(ld); } int main(void) { return x(LDBL_MAX); } While __builtin_isinf may call a library function, that function should depend on the argument type. But to be usable to implement the C99 macro, it should not depend on a library function which may not be in the standard library; it should be inlined based on examining the floating point number's bit pattern or call a libgcc function. [I don't think __builtin_isnan has this problem because I don't think it will ever call a library function. __builtin_signbit is not currently type-generic although it ought to be by analogy with the other functions for type-generic macros; I'm not sure if it can ever call a library function now. We don't have __builtin_isfinite or __builtin_isnormal functions. libgcc2.c has its own macro versions of isfinite and isinf but the bit-manipulation done e.g. in the glibc implementations may be more efficient.] -- Summary: variadic __builtin_isinf broken Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: normal Priority: P2 Component: middle-end AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jsm28 at gcc dot gnu dot org CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20558