[libcxx] r179461 - Set failbit when strtold sets errno to ERANGE when parsing floating point values.

Howard Hinnant hhinnant at apple.com
Sat Apr 13 11:19:26 PDT 2013


Author: hhinnant
Date: Sat Apr 13 13:19:25 2013
New Revision: 179461

URL: http://llvm.org/viewvc/llvm-project?rev=179461&view=rev
Log:
Set failbit when strtold sets errno to ERANGE when parsing floating point values.

Modified:
    libcxx/trunk/include/locale
    libcxx/trunk/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp

Modified: libcxx/trunk/include/locale
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/locale?rev=179461&r1=179460&r2=179461&view=diff
==============================================================================
--- libcxx/trunk/include/locale (original)
+++ libcxx/trunk/include/locale Sat Apr 13 13:19:25 2013
@@ -906,13 +906,20 @@ __num_get_float(const char* __a, const c
 {
     if (__a != __a_end)
     {
+        typename remove_reference<decltype(errno)>::type __save_errno = errno;
+        errno = 0;
         char *__p2;
         long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);
+        typename remove_reference<decltype(errno)>::type __current_errno = errno;
+        if (__current_errno == 0)
+            errno = __save_errno;
         if (__p2 != __a_end)
         {
             __err = ios_base::failbit;
             return 0;
         }
+        else if (__current_errno == ERANGE)
+            __err = ios_base::failbit;
         return static_cast<_Tp>(__ld);
     }
     __err = ios_base::failbit;

Modified: libcxx/trunk/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp?rev=179461&r1=179460&r2=179461&view=diff
==============================================================================
--- libcxx/trunk/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp (original)
+++ libcxx/trunk/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp Sat Apr 13 13:19:25 2013
@@ -168,4 +168,52 @@ int main()
         assert(err == ios.goodbit);
         assert(std::isnan(v));
     }
+    {
+        const char str[] = "1.189731495357231765021264e+49321";
+        std::ios_base::iostate err = ios.goodbit;
+        v = 0;
+        input_iterator<const char*> iter =
+            f.get(input_iterator<const char*>(str),
+                  input_iterator<const char*>(str+sizeof(str)),
+                  ios, err, v);
+        assert(iter.base() == str+sizeof(str)-1);
+        assert(err == ios.failbit);
+        assert(v == INFINITY);
+    }
+    {
+        const char str[] = "1.189731495357231765021264e+49329";
+        std::ios_base::iostate err = ios.goodbit;
+        v = 0;
+        input_iterator<const char*> iter =
+            f.get(input_iterator<const char*>(str),
+                  input_iterator<const char*>(str+sizeof(str)),
+                  ios, err, v);
+        assert(iter.base() == str+sizeof(str)-1);
+        assert(err == ios.failbit);
+        assert(v == INFINITY);
+    }
+    {
+        const char str[] = "11.189731495357231765021264e+4932";
+        std::ios_base::iostate err = ios.goodbit;
+        v = 0;
+        input_iterator<const char*> iter =
+            f.get(input_iterator<const char*>(str),
+                  input_iterator<const char*>(str+sizeof(str)),
+                  ios, err, v);
+        assert(iter.base() == str+sizeof(str)-1);
+        assert(err == ios.failbit);
+        assert(v == INFINITY);
+    }
+    {
+        const char str[] = "91.189731495357231765021264e+4932";
+        std::ios_base::iostate err = ios.goodbit;
+        v = 0;
+        input_iterator<const char*> iter =
+            f.get(input_iterator<const char*>(str),
+                  input_iterator<const char*>(str+sizeof(str)),
+                  ios, err, v);
+        assert(iter.base() == str+sizeof(str)-1);
+        assert(err == ios.failbit);
+        assert(v == INFINITY);
+    }
 }





More information about the cfe-commits mailing list