mirror of
https://github.com/neovim/neovim.git
synced 2025-09-30 15:08:35 +00:00
build: fix fpclassify -Wfloat-conversion warning #15570
Work around a glibc bug where it truncates the argument to fpclassify() from double to float by implementing fpclassify() ourselves. Correctness test (Note that the FP_SUBNORMAL test depends on an atof() that knows how to parse subnormals. Glibc does, not sure about other libcs.): #include <math.h> #include <stdint.h> #include <string.h> int xfpclassify(double d) { uint64_t m; int e; memcpy(&m, &d, sizeof(m)); e = 0x7ff & (m >> 52); m = 0xfffffffffffffULL & m; switch (e) { default: return FP_NORMAL; case 0x000: return m ? FP_SUBNORMAL : FP_ZERO; case 0x7ff: return m ? FP_NAN : FP_INFINITE; } } #include <assert.h> #include <stdlib.h> int main(void) { assert(FP_ZERO == xfpclassify(atof("0.0"))); assert(FP_ZERO == xfpclassify(atof("-0.0"))); assert(FP_NORMAL == xfpclassify(atof("1.0"))); assert(FP_NORMAL == xfpclassify(atof("-1.0"))); assert(FP_INFINITE == xfpclassify(atof("inf"))); assert(FP_INFINITE == xfpclassify(atof("-inf"))); assert(FP_NAN == xfpclassify(atof("nan"))); assert(FP_NAN == xfpclassify(atof("-nan"))); assert(FP_SUBNORMAL == xfpclassify(atof("1.8011670033376514e-308"))); return 0; }
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "nvim/math.h"
|
#include "nvim/math.h"
|
||||||
|
|
||||||
@@ -9,34 +11,26 @@
|
|||||||
# include "math.c.generated.h"
|
# include "math.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__clang__) && __clang__ == 1 && __clang_major__ >= 6
|
|
||||||
// Workaround glibc + Clang 6+ bug. #8274
|
|
||||||
// https://bugzilla.redhat.com/show_bug.cgi?id=1472437
|
|
||||||
# pragma clang diagnostic push
|
|
||||||
# pragma clang diagnostic ignored "-Wconversion"
|
|
||||||
#endif
|
|
||||||
int xfpclassify(double d)
|
int xfpclassify(double d)
|
||||||
{
|
{
|
||||||
#if defined(__MINGW32__)
|
uint64_t m;
|
||||||
// Workaround mingw warning. #7863
|
int e;
|
||||||
return __fpclassify(d);
|
|
||||||
#else
|
memcpy(&m, &d, sizeof(m));
|
||||||
return fpclassify(d);
|
e = 0x7ff & (m >> 52);
|
||||||
#endif
|
m = 0xfffffffffffffULL & m;
|
||||||
|
|
||||||
|
switch (e) {
|
||||||
|
default: return FP_NORMAL;
|
||||||
|
case 0x000: return m ? FP_SUBNORMAL : FP_ZERO;
|
||||||
|
case 0x7ff: return m ? FP_NAN : FP_INFINITE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int xisinf(double d)
|
int xisinf(double d)
|
||||||
{
|
{
|
||||||
return isinf(d);
|
return FP_INFINITE == xfpclassify(d);
|
||||||
}
|
}
|
||||||
int xisnan(double d)
|
int xisnan(double d)
|
||||||
{
|
{
|
||||||
#if defined(__MINGW32__)
|
return FP_NAN == xfpclassify(d);
|
||||||
// Workaround mingw warning. #7863
|
|
||||||
return _isnan(d);
|
|
||||||
#else
|
|
||||||
return isnan(d);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#if defined(__clang__) && __clang__ == 1 && __clang_major__ >= 6
|
|
||||||
# pragma clang diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
Reference in New Issue
Block a user