Bug 1472437 - glibc: Can't compile libvirt with clang: implicit conversion increases floating-point precision in isnan()
glibc: Can't compile libvirt with clang: implicit conversion increases floati...
Status: NEW
Product: Fedora
Classification: Fedora
Component: clang (Show other bugs)
x86_64 Linux
unspecified Severity unspecified
: ---
: ---
Assigned To: Dave Airlie
Fedora Extras Quality Assurance
Depends On:
  Show dependency treegraph
Reported: 2017-07-18 13:46 EDT by Andrea Bolognani
Modified: 2017-11-09 16:33 EST (History)
15 users (show)

See Also:
Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
Last Closed:
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

External Trackers
Tracker ID Priority Status Summary Last Updated
LLVM 35268 None None None 2017-11-09 16:33 EST

  None (edit)
Description Andrea Bolognani 2017-07-18 13:46:48 EDT
Description of problem:

  libvirt can't be compiled using clang on Fedora rawhide,
  apparently due to the way the isnan() macro has been

Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:

  1. git clone git://libvirt.org/libvirt.git
  2. cd libvirt
  3. sudo yum-builddep libvirt.spec.in
  4. CC=clang-4.0 sh autogen.sh --system
  5. make -j

Actual results:

  Compilation fails with a bunch of errors along the lines of:

  util/virxml.c:453:30: error: implicit conversion increases floating-point
  precision: 'double' to 'long double' [-Werror,-Wdouble-promotion]
                 (!(isnan(obj->floatval)))) {
  /usr/include/math.h:440:46: note: expanded from macro 'isnan'
  #  define isnan(x) __MATH_TG ((x), __isnan, (x))
  /usr/include/math.h:373:16: note: expanded from macro '__MATH_TG'
     : FUNC ## l ARGS)
       ~~~~~~~~~ ^~~~

Expected results:

  Compilation doesn't fail :)

Additional info:

  Tweaking /usr/include/math.h to replace the definition of
  isnan() with the one lifted from the very same file of a
  Fedora 24 box (glibc-2.23.1-12.fc24.x86_64) results in a
  successful compilation.
Comment 1 Daniel Berrange 2017-08-11 12:28:55 EDT
FYI, this is is easily reproducable without libvirt

$ cat isnan.c 

#include <math.h>

int main(void)
  double foo = 1.0;

  if (isnan(foo))
    return 1;
  return 0;

$ clang -Wdouble-promotion -Wall -o isnan isnan.c
isnan.c:8:13: warning: implicit conversion increases floating-point precision:
      'double' to 'long double' [-Wdouble-promotion]
  if (isnan(foo))
/usr/include/math.h:385:46: note: expanded from macro 'isnan'
#  define isnan(x) __MATH_TG ((x), __isnan, (x))
/usr/include/math.h:320:16: note: expanded from macro '__MATH_TG'
   : FUNC ## l ARGS)
     ~~~~~~~~~ ^~~~
1 warning generated.

I do wonder if this is actually a clang bug though.  The new glib math.h is calling  _builtin_isnan(), so presumably it is clang's implementation of _builtin_isnan() that is causing the double promotion. Glibc just happens to trigger it ?
Comment 2 Jan Kurik 2017-08-15 03:20:25 EDT
This bug appears to have been reported against 'rawhide' during the Fedora 27 development cycle.
Changing version to '27'.
Comment 3 Dridi Boukelmoune 2017-11-03 09:52:33 EDT
Same problem on f26, and if I neuter -Wdouble-promotion then -Wconversion triggers, and I'd rather really keep this one around :)
Comment 4 Carlos O'Donell 2017-11-06 13:23:42 EST
The macro in question is this:


398 # define __MATH_TG(TG_ARG, FUNC, ARGS)          \
399   (sizeof (TG_ARG) == sizeof (float)            \
400    ? FUNC ## f ARGS                             \
401    : sizeof (TG_ARG) == sizeof (double)         \
402    ? FUNC ARGS                                  \
403    : FUNC ## l ARGS)

The problem is that clang warns about 'FUNC ## l ARGS' even though this is dead code, the parameter is a double, and will never be passed to 'FUNC ## l ARGS'.

The is is a false positive warning from clang.

I'm assigning to clang for further triage.
Comment 5 Tom Stellard 2017-11-07 17:04:21 EST
__builtin_isnan() is not actually called in this example program, because clang does:

Builder.defineMacro("__GNUC_MINOR__", "2");
Builder.defineMacro("__GNUC_PATCHLEVEL__", "1");
Builder.defineMacro("__GNUC__", "4");

And the call to __builtin_isnan() is guarded by:
if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__

Note You need to log in before you can comment on or make changes to this bug.