Kaynağa Gözat

Fix ParseInt1.js error

parseInt("4294967296") returned 1 due to strict aliasing bug at BigUInt.cpp:529.

Fix LuHiDbl/LuLoDbl to prevent similar issues caused by them:
access uint32 via a union, and __may_alias__ annotation for clang.
Ivan Krasilnikov 2 ay önce
ebeveyn
işleme
792ee7660c

+ 10 - 2
lib/Common/Common/NumberUtilities.h

@@ -84,6 +84,14 @@ namespace Js
 
     };
 
+#ifdef __clang__
+    typedef uint32 uint32_aliased __attribute__((__may_alias__));
+    typedef double double_aliased __attribute__((__may_alias__));
+#else
+    typedef uint32 uint32_aliased;
+    typedef double double_aliased;
+#endif
+
     class NumberUtilities : public NumberUtilitiesBase
     {
     public:
@@ -92,8 +100,8 @@ namespace Js
         static uint32 MulLu(uint32 lu1, uint32 lu2, uint32 *pluHi);
         static int AddLu(uint32 *plu1, uint32 lu2);
 
-        static uint32 &LuHiDbl(double &dbl);
-        static uint32 &LuLoDbl(double &dbl);
+        static uint32_aliased &LuHiDbl(double_aliased &dbl);
+        static uint32_aliased &LuLoDbl(double_aliased &dbl);
         static INT64 TryToInt64(double d);
         static bool IsValidTryToInt64(__int64 value);   // Whether TryToInt64 resulted in a valid value.
 

+ 18 - 11
lib/Common/Common/NumberUtilities.inl

@@ -50,22 +50,29 @@
 
 namespace Js
 {
-    NUMBER_UTIL_INLINE uint32 &NumberUtilities::LuHiDbl(double &dbl)
+    union DoubleAccessor
     {
+        double d;
+        struct
+        {
 #if defined(__BIG_ENDIAN__)
-        return ((uint32 *)&dbl)[0];
-#else //!BIG_ENDIAN
-        return ((uint32 *)&dbl)[1];
-#endif //!BIG_ENDIAN
+            uint32 hi;
+            uint32 lo;
+#else
+            uint32 lo;
+            uint32 hi;
+#endif
+        } u;
+    };
+
+    NUMBER_UTIL_INLINE uint32_aliased &NumberUtilities::LuHiDbl(double_aliased &dbl)
+    {
+        return reinterpret_cast<DoubleAccessor*>(&dbl)->u.hi;
     }
 
-    NUMBER_UTIL_INLINE uint32 &NumberUtilities::LuLoDbl(double &dbl)
+    NUMBER_UTIL_INLINE uint32_aliased &NumberUtilities::LuLoDbl(double_aliased &dbl)
     {
-#if defined(__BIG_ENDIAN__)
-        return ((uint32 *)&dbl)[1];
-#else //!BIG_ENDIAN
-        return ((uint32 *)&dbl)[0];
-#endif //!BIG_ENDIAN
+        return reinterpret_cast<DoubleAccessor*>(&dbl)->u.lo;
     }
 
 #if defined(_M_X64) && defined(_MSC_VER) && !defined(__clang__)