aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/port.h5
-rw-r--r--src/include/port/cygwin.h8
-rw-r--r--src/include/port/win32_port.h17
-rw-r--r--src/port/strtof.c10
-rw-r--r--src/test/regress/resultmap7
5 files changed, 36 insertions, 11 deletions
diff --git a/src/include/port.h b/src/include/port.h
index 436bc83fe38..7e2004b178b 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -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
diff --git a/src/include/port/cygwin.h b/src/include/port/cygwin.h
index 5c149470c68..f1fc1a93d76 100644
--- a/src/include/port/cygwin.h
+++ b/src/include/port/cygwin.h
@@ -16,3 +16,11 @@
#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
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 9bab75d5da0..1438082723f 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -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 */
diff --git a/src/port/strtof.c b/src/port/strtof.c
index 7aca8e2e3df..9e37633bda5 100644
--- a/src/port/strtof.c
+++ b/src/port/strtof.c
@@ -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)
diff --git a/src/test/regress/resultmap b/src/test/regress/resultmap
index 3bd1585a355..c766d03df23 100644
--- a/src/test/regress/resultmap
+++ b/src/test/regress/resultmap
@@ -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