[libvirt] [PATCH 2/2] util: Cast to 'long double' when calling isnan()

Andrea Bolognani abologna at redhat.com
Mon Jan 2 18:15:31 UTC 2017


Clang 3.9 chokes when calling isnan() on a double variable:

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

Note how the wrong version of isnan() is being called: isnanl()
is for 'long double's, but obj->floatval is a double and a
suitable version should be called instead.

Cast the value to 'long double' to make the compiler happy.
---
Clang seems to be tripping on the specific way the isnan()
macro is defined in recent glibc versions; more specifically,
if I replace the current definition in <math.h> with the one
that predates the introduction of the __MATH_TG() macro, I
can get the current code to compile. I was not able to find
anything wrong with the __MATH_TG() macro though.

 src/util/virxml.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/util/virxml.c b/src/util/virxml.c
index 666024809..076c23c03 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -150,7 +150,7 @@ virXPathNumber(const char *xpath,
     obj = xmlXPathEval(BAD_CAST xpath, ctxt);
     ctxt->node = relnode;
     if ((obj == NULL) || (obj->type != XPATH_NUMBER) ||
-        (isnan(obj->floatval))) {
+        (isnan((long double) obj->floatval))) {
         xmlXPathFreeObject(obj);
         return -1;
     }
@@ -183,7 +183,7 @@ virXPathLongBase(const char *xpath,
         if (virStrToLong_l((char *) obj->stringval, NULL, base, value) < 0)
             ret = -2;
     } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
-               (!(isnan(obj->floatval)))) {
+               (!(isnan((long double) obj->floatval)))) {
         *value = (long) obj->floatval;
         if (*value != obj->floatval)
             ret = -2;
@@ -288,7 +288,7 @@ virXPathULongBase(const char *xpath,
         if (virStrToLong_ul((char *) obj->stringval, NULL, base, value) < 0)
             ret = -2;
     } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
-               (!(isnan(obj->floatval)))) {
+               (!(isnan((long double) obj->floatval)))) {
         *value = (unsigned long) obj->floatval;
         if (*value != obj->floatval)
             ret = -2;
@@ -404,7 +404,7 @@ virXPathULongLong(const char *xpath,
         if (virStrToLong_ull((char *) obj->stringval, NULL, 10, value) < 0)
             ret = -2;
     } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
-               (!(isnan(obj->floatval)))) {
+               (!(isnan((long double) obj->floatval)))) {
         *value = (unsigned long long) obj->floatval;
         if (*value != obj->floatval)
             ret = -2;
@@ -450,7 +450,7 @@ virXPathLongLong(const char *xpath,
         if (virStrToLong_ll((char *) obj->stringval, NULL, 10, value) < 0)
             ret = -2;
     } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) &&
-               (!(isnan(obj->floatval)))) {
+               (!(isnan((long double) obj->floatval)))) {
         *value = (long long) obj->floatval;
         if (*value != obj->floatval)
             ret = -2;
-- 
2.11.0




More information about the libvir-list mailing list