This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[PATCH] fix PL_nan_u from leaking in every translation object on Win32 VC
authorDaniel Dragan <bulk88@hotmail.com>
Wed, 31 Dec 2014 20:58:07 +0000 (15:58 -0500)
committerJarkko Hietaniemi <jhi@iki.fi>
Thu, 5 Feb 2015 03:15:55 +0000 (22:15 -0500)
gv.c
numeric.c
perl.h
sv.c
win32/win32.h

diff --git a/gv.c b/gv.c
index 82db197..41cebeb 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -39,7 +39,7 @@ Perl stores its global variables.
 #include "feature.h"
 
 static const char S_autoload[] = "AUTOLOAD";
-static const STRLEN S_autolen = sizeof(S_autoload)-1;
+#define S_autolen (sizeof("AUTOLOAD")-1)
 
 GV *
 Perl_gv_add_by_type(pTHX_ GV *gv, svtype type)
index d5c422f..a6f6018 100644 (file)
--- a/numeric.c
+++ b/numeric.c
@@ -1259,6 +1259,11 @@ Perl_my_atof(pTHX_ const char* s)
     return x;
 }
 
+
+#ifdef USING_MSVC6
+#  pragma warning(push)
+#  pragma warning(disable:4756;disable:4056)
+#endif
 static char*
 S_my_atof_infnan(pTHX_ const char* s, bool negative, const char* send, NV* value)
 {
@@ -1330,6 +1335,9 @@ S_my_atof_infnan(pTHX_ const char* s, bool negative, const char* send, NV* value
     }
     return NULL;
 }
+#ifdef USING_MSVC6
+#  pragma warning(pop)
+#endif
 
 char*
 Perl_my_atof2(pTHX_ const char* orig, NV* value)
diff --git a/perl.h b/perl.h
index a9045c0..b6dbf61 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -4257,14 +4257,6 @@ START_EXTERN_C
 END_EXTERN_C
 #endif
 
-#ifdef WIN32
-#  if !defined(NV_INF) && defined(HUGE_VAL)
-#    define NV_INF HUGE_VAL
-#  endif
-/* For WIN32 the best NV_NAN is the __PL_nan_u trick, see below.
- * There is no supported way of getting the NAN across all the crts. */
-#endif
-
 /* If you are thinking of using HUGE_VAL for infinity, or using
  * <math.h> functions to generate NV_INF (e.g. exp(1e9), log(-1.0)),
  * stop.  Neither will work portably: HUGE_VAL can be just DBL_MAX,
diff --git a/sv.c b/sv.c
index 0160443..ca1a1da 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -2107,6 +2107,10 @@ S_sv_2iuv_non_preserve(pTHX_ SV *const sv
 
 /* If numtype is infnan, set the NV of the sv accordingly.
  * If numtype is anything else, try setting the NV using Atof(PV). */
+#ifdef USING_MSVC6
+#  pragma warning(push)
+#  pragma warning(disable:4756;disable:4056)
+#endif
 static void
 S_sv_setnv(pTHX_ SV* sv, int numtype)
 {
@@ -2131,6 +2135,9 @@ S_sv_setnv(pTHX_ SV* sv, int numtype)
             SvPOK_on(sv); /* PV is okay, though. */
     }
 }
+#ifdef USING_MSVC6
+#  pragma warning(pop)
+#endif
 
 STATIC bool
 S_sv_2iuv_common(pTHX_ SV *const sv)
index 657b008..8a55202 100644 (file)
@@ -260,6 +260,31 @@ typedef unsigned short     mode_t;
 #  pragma intrinsic(_rotl64,_rotr64)
 #endif
 
+#  pragma warning(push)
+#  pragma warning(disable:4756;disable:4056)
+PERL_STATIC_INLINE
+double S_Infinity() {
+    /* this is a real C literal which can get further constant folded
+       unlike using HUGE_VAL/_HUGE which are data symbol imports from the CRT
+       and therefore can not by folded by VC, an example of constant
+       folding INF is creating -INF */
+    return (DBL_MAX+DBL_MAX);
+}
+#  pragma warning(pop)
+#  define NV_INF S_Infinity()
+
+/* selectany allows duplicate and unused data symbols to be removed by
+   VC linker, if this were static, each translation unit will have its own,
+   usually unused __PL_nan_u, if this were plain extern it will cause link
+   to fail due to multiple definitions, since we dont know if we are being
+   compiled as static or DLL XS, selectany simply always works, the cost of
+   importing __PL_nan_u across DLL boundaries in size in the importing DLL
+   will be more than the 8 bytes it will take up being in each XS DLL if
+   that DLL actually uses __PL_nan_u */
+extern const __declspec(selectany) union { unsigned __int64 __q; double __d; }
+__PL_nan_u = { 0x7FF8000000000000UI64 };
+#  define NV_NAN ((NV)__PL_nan_u.__d)
+
 #endif /* _MSC_VER */
 
 #ifdef __MINGW32__             /* Minimal Gnu-Win32 */