]> granicus.if.org Git - postgresql/commitdiff
Cygwin and Mingw floating-point fixes.
authorAndrew Gierth <rhodiumtoad@postgresql.org>
Sat, 16 Feb 2019 01:50:16 +0000 (01:50 +0000)
committerAndrew Gierth <rhodiumtoad@postgresql.org>
Sat, 16 Feb 2019 01:50:16 +0000 (01:50 +0000)
Deal with silent-underflow errors in float4 for cygwin and mingw by
using our strtof() wrapper; deal with misrounding errors by adding
them to the resultmap. Some slight reorganization of declarations was
done to avoid duplicating material between cygwin.h and win32_port.h.

While here, remove from the resultmap all references to
float8-small-is-zero; inspection of cygwin output suggests it's no
longer required there, and the freebsd/netbsd/openbsd entries should
no longer be necessary (these date back to c. 2000). This commit
doesn't remove the file itself nor the documentation references for
it; that will happen in a subsequent commit if all goes well.

configure
configure.in
src/include/port.h
src/include/port/cygwin.h
src/include/port/win32_port.h
src/port/strtof.c
src/test/regress/resultmap

index 7291311ae38624ae1ce42a1073ed4ca1b521658e..849a7ebdf3de0c987379a8f159726c4e7c0d2d6e 100755 (executable)
--- a/configure
+++ b/configure
 
 
 
+case $host_os in
+       # Cygwin and (apparently, based on test results) Mingw both
+       # have a broken strtof(), so substitute the same replacement
+       # code we use with VS2013. That's not a perfect fix, since
+       # (unlike with VS2013) it doesn't avoid double-rounding, but
+       # we have no better options. To get that, though, we have to
+       # force the file to be compiled despite HAVE_STRTOF.
+       mingw*|cygwin*)
+               case " $LIBOBJS " in
+  *" strtof.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strtof.$ac_objext"
+ ;;
+esac
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: On $host_os we will use our strtof wrapper." >&5
+$as_echo "$as_me: On $host_os we will use our strtof wrapper." >&6;}
+       ;;
+esac
+
 case $host_os in
 
         # Windows uses a specialised env handler
index 8a55e8e8a5941d47f7c8d7843c188981fcf63789..71f8885fe2248d4794f4dc9127d2b6c75ac62952 100644 (file)
@@ -1715,6 +1715,19 @@ AC_REPLACE_FUNCS(m4_normalize([
        strtof
 ]))
 
+case $host_os in
+       # Cygwin and (apparently, based on test results) Mingw both
+       # have a broken strtof(), so substitute the same replacement
+       # code we use with VS2013. That's not a perfect fix, since
+       # (unlike with VS2013) it doesn't avoid double-rounding, but
+       # we have no better options. To get that, though, we have to
+       # force the file to be compiled despite HAVE_STRTOF.
+       mingw*|cygwin*)
+               AC_LIBOBJ([strtof])
+               AC_MSG_NOTICE([On $host_os we will use our strtof wrapper.])
+       ;;
+esac
+
 case $host_os in
 
         # Windows uses a specialised env handler
index 436bc83fe3803f3b6d0bb505ae5abb3911003cba..7e2004b178b2ebd4e0f029040b0babf13bc62a0f 100644 (file)
@@ -385,6 +385,11 @@ extern int isinf(double x);
 extern float strtof(const char *nptr, char **endptr);
 #endif
 
+#ifdef HAVE_BUGGY_STRTOF
+extern float pg_strtof(const char *nptr, char **endptr);
+#define strtof(a,b) (pg_strtof((a),(b)))
+#endif
+
 #ifndef HAVE_MKDTEMP
 extern char *mkdtemp(char *path);
 #endif
index 5c149470c68096c471326c455797f0dc6e250220..f1fc1a93d76c0e0f902b26e17f1694eb99ea7593 100644 (file)
 #endif
 
 #define PGDLLEXPORT
+
+/*
+ * Cygwin has a strtof() which is literally just (float)strtod(), which means
+ * we get misrounding _and_ silent over/underflow. Using our wrapper doesn't
+ * fix the misrounding but does fix the error checks, which cuts down on the
+ * number of test variant files needed.
+ */
+#define HAVE_BUGGY_STRTOF 1
index 9bab75d5da0c64d1f7dd69c175190c4c910edc46..1438082723f5d03ded4f0f79cc3b44c3cafa63ac 100644 (file)
@@ -510,16 +510,23 @@ typedef unsigned short mode_t;
 #define isnan(x) _isnan(x)
 #endif
 
-#if defined(_MSC_VER) && (_MSC_VER < 1900)
+#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || \
+       defined(__MINGW32__) || defined(__MINGW64__)
 /*
  * VS2013 has a strtof() that seems to give correct answers for valid input,
  * even on the rounding edge cases, but which doesn't handle out-of-range
  * input correctly. Work around that.
+ *
+ * Mingw claims to have a strtof, and my reading of its source code suggests
+ * that it ought to work (and not need this hack), but the regression test
+ * results disagree with me; whether this is a version issue or not is not
+ * clear. However, using our wrapper (and the misrounded-input variant file,
+ * already required for supporting ancient systems) can't make things any
+ * worse, except for a tiny performance loss when reading zeros.
+ *
+ * See also cygwin.h for another instance of this.
  */
-#define HAVE_BUGGY_WINDOWS_STRTOF 1
-extern float pg_strtof(const char *nptr, char **endptr);
-#define strtof(a,b) (pg_strtof((a),(b)))
-
+#define HAVE_BUGGY_STRTOF 1
 #endif
 
 /* Pulled from Makefile.port in MinGW */
index 7aca8e2e3df25332d3fbc467b4a0bc5cbbb8371e..9e37633bda5629d83656b6ce7c0fc9099c47ef06 100644 (file)
@@ -52,7 +52,7 @@ strtof(const char *nptr, char **endptr)
        return fresult;
 }
 
-#elif HAVE_BUGGY_WINDOWS_STRTOF
+#elif HAVE_BUGGY_STRTOF
 /*
  * On Windows, there's a slightly different problem: VS2013 has a strtof()
  * that returns the correct results for valid input, but may fail to report an
@@ -62,6 +62,14 @@ strtof(const char *nptr, char **endptr)
  * well, so prefer to round the strtod() result in such cases. (Normally we'd
  * just say "too bad" if strtof() doesn't support subnormals, but since we're
  * already in here fixing stuff, we might as well do the best fix we can.)
+ *
+ * Cygwin has a strtof() which is literally just (float)strtod(), which means
+ * we can't avoid the double-rounding problem; but using this wrapper does get
+ * us proper over/underflow checks. (Also, if they fix their strtof(), the
+ * wrapper doesn't break anything.)
+ *
+ * Test results on Mingw suggest that it has the same problem, though looking
+ * at the code I can't figure out why.
  */
 float
 pg_strtof(const char *nptr, char **endptr)
index 3bd1585a35518e9811510646ef18ea23909f7c81..c766d03df23dfcca19e6abfc5f3c5d9b54dcc0f6 100644 (file)
@@ -1,6 +1,3 @@
-float8:out:i.86-.*-freebsd=float8-small-is-zero.out
-float8:out:i.86-.*-openbsd=float8-small-is-zero.out
-float8:out:i.86-.*-netbsd=float8-small-is-zero.out
-float8:out:m68k-.*-netbsd=float8-small-is-zero.out
-float8:out:i.86-pc-cygwin=float8-small-is-zero.out
+float4:out:.*-.*-cygwin.*=float4-misrounded-input.out
+float4:out:.*-.*-mingw.*=float4-misrounded-input.out
 float4:out:hppa.*-hp-hpux10.*=float4-misrounded-input.out