This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
On VC6 (broken NaN compare) redefine Perl_isinf.
authorJarkko Hietaniemi <jhi@iki.fi>
Sat, 20 Sep 2014 17:45:20 +0000 (13:45 -0400)
committerJarkko Hietaniemi <jhi@iki.fi>
Sat, 20 Sep 2014 20:27:08 +0000 (16:27 -0400)
So that it works with NaN, by not using the comparison version of
Perl_isinf.  A little messy but since win32/win32.h is included so
late in perl.h, cannot be done earlier with the other Perl_isinf
logic.  Partially reverts 128eeacb.

perl.h
sv.c
win32/win32.h

diff --git a/perl.h b/perl.h
index 5615b96..0b8e1db 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -3029,6 +3029,13 @@ typedef pthread_key_t    perl_key;
 
 #if defined(WIN32)
 #  include "win32.h"
+#  ifdef NAN_COMPARE_BROKEN /* VC6 */
+/* We need to redefine Perl_isinf() because we most likely defined it
+ * using the <DBL_MIN || >DBL_MAX way, which is broken if the NaN
+ * compare is broken. */
+#    undef Perl_isinf
+#    define Perl_isinf(x) Perl_fp_class_inf(x)
+#  endif
 #endif
 
 #ifdef NETWARE
diff --git a/sv.c b/sv.c
index b22f770..2ff999f 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -2821,20 +2821,7 @@ S_infnan_2pv(NV nv, char* buffer, size_t maxlen) {
         return 0;
     else {
         char* s = buffer;
-        /* isnan must be first due to NAN_COMPARE_BROKEN builds, since NAN might
-           use the broken for NAN >/< ops in the inf check, and then the inf
-           check returns true for NAN on NAN_COMPARE_BROKEN compilers */
-        if (Perl_isnan(nv)) {
-            *s++ = 'N';
-            *s++ = 'a';
-            *s++ = 'N';
-            /* XXX optionally output the payload mantissa bits as
-             * "(unsigned)" (to match the nan("...") C99 function,
-             * or maybe as "(0xhhh...)"  would make more sense...
-             * provide a format string so that the user can decide?
-             * NOTE: would affect the maxlen and assert() logic.*/
-        }
-        else if (Perl_isinf(nv)) {
+        if (Perl_isinf(nv)) {
             if (nv < 0) {
                 if (maxlen < 5) /* "-Inf\0"  */
                     return 0;
@@ -2843,6 +2830,15 @@ S_infnan_2pv(NV nv, char* buffer, size_t maxlen) {
             *s++ = 'I';
             *s++ = 'n';
             *s++ = 'f';
+        } else if (Perl_isnan(nv)) {
+            *s++ = 'N';
+            *s++ = 'a';
+            *s++ = 'N';
+            /* XXX optionally output the payload mantissa bits as
+             * "(unsigned)" (to match the nan("...") C99 function,
+             * or maybe as "(0xhhh...)"  would make more sense...
+             * provide a format string so that the user can decide?
+             * NOTE: would affect the maxlen and assert() logic.*/
         }
 
         else
index 8db0303..8587ac8 100644 (file)
@@ -255,7 +255,8 @@ typedef unsigned short      mode_t;
 #define vsnprintf      _vsnprintf
 
 #ifdef USING_MSVC6
-/* VC6 has broken NaN semantics: NaN == NaN returns true instead of false */
+/* VC6 has broken NaN semantics: NaN == NaN returns true instead of false,
+ * and for example NaN < IV_MIN. */
 #define NAN_COMPARE_BROKEN 1
 #endif