aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/config
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2008-09-23 00:47:02 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2008-09-23 00:47:02 +0000
commit5ef46f95596c600cf4d17bf98f4804e6bd53cfc5 (patch)
tree9d02f6e05a6a1e62f93b452749b09a474b553c86 /libstdc++-v3/config
parent441154b19b1e998fe06a8f9045df8b69fa5ca274 (diff)
downloadgcc-5ef46f95596c600cf4d17bf98f4804e6bd53cfc5.zip
gcc-5ef46f95596c600cf4d17bf98f4804e6bd53cfc5.tar.gz
gcc-5ef46f95596c600cf4d17bf98f4804e6bd53cfc5.tar.bz2
PR libstdc++/32422, DR 23 [Ready in R60]
2008-09-23 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/32422, DR 23 [Ready in R60] * config/locale/gnu/c_locale.cc (__convert_to_v(const char*, float&, ios_base::iostate&, const __c_locale&), __convert_to_v(const char*, double&, ios_base::iostate&, const __c_locale&), __convert_to_v(const char*, long double&, ios_base::iostate&, const __c_locale&)): Implement DR 23 and deal correctly with broken exponents. * config/locale/generic/c_locale.cc (__convert_to_v(const char*, float&, ios_base::iostate&, const __c_locale&), __convert_to_v(const char*, double&, ios_base::iostate&, const __c_locale&), __convert_to_v(const char*, long double&, ios_base::iostate&, const __c_locale&)): Likewise. * include/bits/locale_facets.tcc (num_get<>::_M_extract_int(_InIter, _InIter, ios_base&, ios_base::iostate&, _ValueT&)): Likewise. (num_get<>::_M_extract_float(_InIter, _InIter, ios_base&, ios_base::iostate&, string&): Change grouping check to set instead of OR failbit; do not check for eofbit here... (num_get<>::do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, float&), num_get<>::do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, double&), num_get<>::do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long double&), num_get<>::__do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, double&)): ... do it here instead. (num_get<>::do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&)): Implement DR 23. (num_get<>::do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, void*&)): Adjust. * doc/xml/manual/intro.xml: Add and entry for DR 23. * testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/10.cc: Adjust. * testsuite/27_io/basic_istream/extractors_arithmetic/char/10.cc: Likewise. * testsuite/22_locale/num_get/get/wchar_t/22131.cc: Likewise. * testsuite/22_locale/num_get/get/wchar_t/10.cc: Likewise. * testsuite/22_locale/num_get/get/wchar_t/12.cc: Likewise. * testsuite/22_locale/num_get/get/wchar_t/15.cc: Likewise. * testsuite/22_locale/num_get/get/wchar_t/16.cc: Likewise. * testsuite/22_locale/num_get/get/char/22131.cc: Likewise. * testsuite/22_locale/num_get/get/char/10.cc: Likewise. * testsuite/22_locale/num_get/get/char/12.cc: Likewise. * testsuite/22_locale/num_get/get/char/15.cc: Likewise. * testsuite/22_locale/num_get/get/char/16.cc: Likewise. From-SVN: r140574
Diffstat (limited to 'libstdc++-v3/config')
-rw-r--r--libstdc++-v3/config/locale/generic/c_locale.cc127
-rw-r--r--libstdc++-v3/config/locale/gnu/c_locale.cc80
2 files changed, 137 insertions, 70 deletions
diff --git a/libstdc++-v3/config/locale/generic/c_locale.cc b/libstdc++-v3/config/locale/generic/c_locale.cc
index 47c2b4e..67efd9e 100644
--- a/libstdc++-v3/config/locale/generic/c_locale.cc
+++ b/libstdc++-v3/config/locale/generic/c_locale.cc
@@ -49,7 +49,6 @@
_GLIBCXX_BEGIN_NAMESPACE(std)
- // Specializations for all types used in num_get.
template<>
void
__convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
@@ -62,40 +61,53 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
memcpy(__sav, __old, __len);
setlocale(LC_ALL, "C");
char* __sanity;
+ bool __overflow = false;
#if !__FLT_HAS_INFINITY__
errno = 0;
#endif
-#if defined(_GLIBCXX_HAVE_STRTOF)
- float __f = strtof(__s, &__sanity);
+#ifdef _GLIBCXX_HAVE_STRTOF
+ __v = strtof(__s, &__sanity);
#else
double __d = strtod(__s, &__sanity);
- float __f = static_cast<float>(__d);
+ __v = static_cast<float>(__d);
#ifdef _GLIBCXX_HAVE_FINITEF
- if (!finitef (__f))
- __s = __sanity;
+ if (!finitef (__v))
+ __overflow = true;
#elif defined (_GLIBCXX_HAVE_FINITE)
- if (!finite (static_cast<double> (__f)))
- __s = __sanity;
+ if (!finite (static_cast<double> (__v)))
+ __overflow = true;
#elif defined (_GLIBCXX_HAVE_ISINF)
- if (isinf (static_cast<double> (__f)))
- __s = __sanity;
+ if (isinf (static_cast<double> (__v)))
+ __overflow = true;
#else
if (fabs(__d) > numeric_limits<float>::max())
- __s = __sanity;
+ __overflow = true;
#endif
-#endif
-
- if (__sanity != __s
-#if !__FLT_HAS_INFINITY__
- && errno != ERANGE)
+#endif // _GLIBCXX_HAVE_STRTOF
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 23. Num_get overflow result.
+ if (__sanity == __s || *__sanity != '\0')
+ {
+ __v = 0.0f;
+ __err = ios_base::failbit;
+ }
+ else if (__overflow
+#if __FLT_HAS_INFINITY__
+ || __v == numeric_limits<float>::infinity()
+ || __v == -numeric_limits<float>::infinity())
#else
- && __f != __builtin_huge_valf() && __f != -__builtin_huge_valf())
+ || ((__v > 1.0f || __v < -1.0f) && errno == ERANGE)
#endif
- __v = __f;
- else
- __err |= ios_base::failbit;
+ {
+ if (__v > 0.0f)
+ __v = numeric_limits<float>::max();
+ else
+ __v = -numeric_limits<float>::max();
+ __err = ios_base::failbit;
+ }
setlocale(LC_ALL, __sav);
delete [] __sav;
@@ -118,17 +130,29 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
errno = 0;
#endif
- double __d = strtod(__s, &__sanity);
-
- if (__sanity != __s
-#if !__DBL_HAS_INFINITY__
- && errno != ERANGE)
-#else
- && __d != __builtin_huge_val() && __d != -__builtin_huge_val())
+ __v = strtod(__s, &__sanity);
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 23. Num_get overflow result.
+ if (__sanity == __s || *__sanity != '\0')
+ {
+ __v = 0.0;
+ __err = ios_base::failbit;
+ }
+ else if (
+#if __DBL_HAS_INFINITY__
+ __v == numeric_limits<double>::infinity()
+ || __v == -numeric_limits<double>::infinity())
+#else
+ (__v > 1.0 || __v < -1.0) && errno == ERANGE)
#endif
- __v = __d;
- else
- __err |= ios_base::failbit;
+ {
+ if (__v > 0.0)
+ __v = numeric_limits<double>::max();
+ else
+ __v = -numeric_limits<double>::max();
+ __err = ios_base::failbit;
+ }
setlocale(LC_ALL, __sav);
delete [] __sav;
@@ -152,32 +176,35 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
#if defined(_GLIBCXX_HAVE_STRTOLD) && !defined(_GLIBCXX_HAVE_BROKEN_STRTOLD)
char* __sanity;
- long double __ld = strtold(__s, &__sanity);
-
- if (__sanity != __s
-#if !__LDBL_HAS_INFINITY__
- && errno != ERANGE)
-#else
- && __ld != __builtin_huge_vall() && __ld != -__builtin_huge_vall())
-#endif
- __v = __ld;
+ __v = strtold(__s, &__sanity);
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 23. Num_get overflow result.
+ if (__sanity == __s || *__sanity != '\0')
#else
typedef char_traits<char>::int_type int_type;
- long double __ld;
- int __p = sscanf(__s, "%Lf", &__ld);
+ int __p = sscanf(__s, "%Lf", &__v);
- if (__p && static_cast<int_type>(__p) != char_traits<char>::eof()
-#if !__LDBL_HAS_INFINITY__
- && errno != ERANGE)
-#else
- && __ld != __builtin_huge_vall() && __ld != -__builtin_huge_vall())
+ if (!__p || static_cast<int_type>(__p) == char_traits<char>::eof())
#endif
- __v = __ld;
-
+ {
+ __v = 0.0l;
+ __err = ios_base::failbit;
+ }
+ else if (
+#if __LDBL_HAS_INFINITY__
+ __v == numeric_limits<long double>::infinity()
+ || __v == -numeric_limits<long double>::infinity())
+#else
+ (__v > 1.0l || __v < -1.0l) && errno == ERANGE)
#endif
- else
- __err |= ios_base::failbit;
+ {
+ if (__v > 0.0l)
+ __v = numeric_limits<long double>::max();
+ else
+ __v = -numeric_limits<long double>::max();
+ __err = ios_base::failbit;
+ }
setlocale(LC_ALL, __sav);
delete [] __sav;
diff --git a/libstdc++-v3/config/locale/gnu/c_locale.cc b/libstdc++-v3/config/locale/gnu/c_locale.cc
index a811cc7..0e39d94 100644
--- a/libstdc++-v3/config/locale/gnu/c_locale.cc
+++ b/libstdc++-v3/config/locale/gnu/c_locale.cc
@@ -1,6 +1,6 @@
// Wrapper for underlying C-language localization -*- C++ -*-
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -36,6 +36,7 @@
#include <locale>
#include <stdexcept>
+#include <limits>
#include <langinfo.h>
#include <bits/c++locale_internal.h>
@@ -47,12 +48,25 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const __c_locale& __cloc)
{
char* __sanity;
- float __f = __strtof_l(__s, &__sanity, __cloc);
- if (__sanity != __s && __f != __builtin_huge_valf()
- && __f != -__builtin_huge_valf())
- __v = __f;
- else
- __err |= ios_base::failbit;
+ __v = __strtof_l(__s, &__sanity, __cloc);
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 23. Num_get overflow result.
+ if (__sanity == __s || *__sanity != '\0')
+ {
+ __v = 0.0f;
+ __err = ios_base::failbit;
+ }
+ else if (__v == numeric_limits<float>::infinity())
+ {
+ __v = numeric_limits<float>::max();
+ __err = ios_base::failbit;
+ }
+ else if (__v == -numeric_limits<float>::infinity())
+ {
+ __v = -numeric_limits<float>::max();
+ __err = ios_base::failbit;
+ }
}
template<>
@@ -61,12 +75,25 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const __c_locale& __cloc)
{
char* __sanity;
- double __d = __strtod_l(__s, &__sanity, __cloc);
- if (__sanity != __s && __d != __builtin_huge_val()
- && __d != -__builtin_huge_val())
- __v = __d;
- else
- __err |= ios_base::failbit;
+ __v = __strtod_l(__s, &__sanity, __cloc);
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 23. Num_get overflow result.
+ if (__sanity == __s || *__sanity != '\0')
+ {
+ __v = 0.0;
+ __err = ios_base::failbit;
+ }
+ else if (__v == numeric_limits<double>::infinity())
+ {
+ __v = numeric_limits<double>::max();
+ __err = ios_base::failbit;
+ }
+ else if (__v == -numeric_limits<double>::infinity())
+ {
+ __v = -numeric_limits<double>::max();
+ __err = ios_base::failbit;
+ }
}
template<>
@@ -78,15 +105,28 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
// Prefer strtold_l, as __strtold_l isn't prototyped in more recent
// glibc versions.
- long double __ld = strtold_l(__s, &__sanity, __cloc);
+ __v = strtold_l(__s, &__sanity, __cloc);
#else
- long double __ld = __strtold_l(__s, &__sanity, __cloc);
+ __v = __strtold_l(__s, &__sanity, __cloc);
#endif
- if (__sanity != __s && __ld != __builtin_huge_vall()
- && __ld != -__builtin_huge_vall())
- __v = __ld;
- else
- __err |= ios_base::failbit;
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 23. Num_get overflow result.
+ if (__sanity == __s || *__sanity != '\0')
+ {
+ __v = 0.0l;
+ __err = ios_base::failbit;
+ }
+ else if (__v == numeric_limits<long double>::infinity())
+ {
+ __v = numeric_limits<long double>::max();
+ __err = ios_base::failbit;
+ }
+ else if (__v == -numeric_limits<long double>::infinity())
+ {
+ __v = -numeric_limits<long double>::max();
+ __err = ios_base::failbit;
+ }
}
void