aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2021-09-05 16:37:25 +0200
committerGitHub <noreply@github.com>2021-09-05 07:37:25 -0700
commitc9c9422af0671fea1a3967b98d4c8eef057b2e92 (patch)
treef94f92b7e5890fd0f22aee1dc37f6eb4509273ba
parentdce50312e1e9af81fb0e3b61d6e70bdf286fbffb (diff)
downloadrneovim-c9c9422af0671fea1a3967b98d4c8eef057b2e92.tar.gz
rneovim-c9c9422af0671fea1a3967b98d4c8eef057b2e92.tar.bz2
rneovim-c9c9422af0671fea1a3967b98d4c8eef057b2e92.zip
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; }
-rw-r--r--src/nvim/math.c38
1 files changed, 16 insertions, 22 deletions
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 <math.h>
+#include <stdint.h>
+#include <string.h>
#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