How to reproduce: $ cat isnan.c #include <math.h> int main(void) { double foo = 1.0; if (isnan(foo)) return 1; return 0; } $ clang -Wdouble-promotion -o isnan isnan.c isnan.c:7:13: warning: implicit conversion increases floating-point precision: 'double' to 'long double' [-Wdouble-promotion] if (isnan(foo)) ~~~~~~^~~~ /usr/include/math.h:644:46: note: expanded from macro 'isnan' # define isnan(x) __MATH_TG ((x), __isnan, (x)) ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ /usr/include/math.h:562:16: note: expanded from macro '__MATH_TG' : FUNC ## l ARGS) ~~~~~~~~~ ^~~~ 1 warning generated. This is an issue with glibc 2.25 and newer. I spent some time debugging this and it looks like in lib/Basic/DiagnosticIDs.cpp:471, the isInSystemHeader() function is returning false, because the SourceLocation points to isnan.c:7. To make it more clear why there is a warning, here are the relevant parts of the source after running the preprocessor: extern int __isnan (double __value) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)); extern int __isnanf (float __value) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)); extern int __isnanl (long double __value) __attribute__ ((__nothrow__ )) __attribute__ ((__const__)); int main(void) { double foo = 1.0; if ((sizeof ((foo)) == sizeof (float) ? __isnanf (foo) : sizeof ((foo)) == sizeof (double) ? __isnan (foo) : __isnanl (foo))) return 1; return 0; }
I've been spending a long time tracking this one, and here are my findings: `isnanl' is built from the pasting of `isnan' and `l' so it's spelling is marked as `<scratch-space>' which is not a system header, thus the `inSystemHeader' check is by-passed and the warning appears. Possible workarounds: 1. disable the warning in scratch-space 2. when pasting two tokens together, mark their spelling as the union of the pasted tokens 3. ??
Fixed in https://reviews.llvm.org/rL352838
*** Bug 39738 has been marked as a duplicate of this bug. ***