From c9c9422af0671fea1a3967b98d4c8eef057b2e92 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 5 Sep 2021 16:37:25 +0200 Subject: 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 #include #include 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 #include 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; } --- src/nvim/math.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'src/nvim/math.c') diff --git a/src/nvim/math.c b/src/nvim/math.c index b51f335ed7..63309b6f7a 100644 --- a/src/nvim/math.c +++ b/src/nvim/math.c @@ -2,6 +2,8 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include +#include +#include #include "nvim/math.h" @@ -9,34 +11,26 @@ # include "math.c.generated.h" #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) { -#if defined(__MINGW32__) - // Workaround mingw warning. #7863 - return __fpclassify(d); -#else - return fpclassify(d); -#endif + 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; + } } int xisinf(double d) { - return isinf(d); + return FP_INFINITE == xfpclassify(d); } int xisnan(double d) { -#if defined(__MINGW32__) - // Workaround mingw warning. #7863 - return _isnan(d); -#else - return isnan(d); -#endif + return FP_NAN == xfpclassify(d); } -#if defined(__clang__) && __clang__ == 1 && __clang_major__ >= 6 -# pragma clang diagnostic pop -#endif -- cgit