[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