diff options
| author | Howard Hinnant <hhinnant@apple.com> | 2011-02-25 19:52:41 +0000 |
|---|---|---|
| committer | Howard Hinnant <hhinnant@apple.com> | 2011-02-25 19:52:41 +0000 |
| commit | a8d8ca4d6f700890791d5a2ba99c647e522cdd38 (patch) | |
| tree | 20a0bdf5a5746b4cc032e3cc17819db64be1f452 /libcxx | |
| parent | 301416380e7ae3b2cc3e0b517504b46aa2b64a23 (diff) | |
| download | bcm5719-llvm-a8d8ca4d6f700890791d5a2ba99c647e522cdd38.tar.gz bcm5719-llvm-a8d8ca4d6f700890791d5a2ba99c647e522cdd38.zip | |
http://llvm.org/bugs/show_bug.cgi?id=9326
llvm-svn: 126504
Diffstat (limited to 'libcxx')
| -rw-r--r-- | libcxx/include/locale | 32 | ||||
| -rw-r--r-- | libcxx/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp | 53 |
2 files changed, 77 insertions, 8 deletions
diff --git a/libcxx/include/locale b/libcxx/include/locale index 13bac7ade1c..c024e657a51 100644 --- a/libcxx/include/locale +++ b/libcxx/include/locale @@ -733,22 +733,27 @@ __num_get_signed_integral(const char* __a, const char* __a_end, { if (__a != __a_end) { + int __save_errno = errno; + errno = 0; char *__p2; long long __ll = strtoll_l(__a, &__p2, __base, 0); + int __current_errno = errno; + if (__current_errno == 0) + errno = __save_errno; if (__p2 != __a_end) { __err = ios_base::failbit; return 0; } - else if (__ll > numeric_limits<_Tp>::max()) + else if (__current_errno == ERANGE || + __ll < numeric_limits<_Tp>::min() || + numeric_limits<_Tp>::max() < __ll) { __err = ios_base::failbit; - return numeric_limits<_Tp>::max(); - } - else if (__ll < numeric_limits<_Tp>::min()) - { - __err = ios_base::failbit; - return numeric_limits<_Tp>::min(); + if (__ll > 0) + return numeric_limits<_Tp>::max(); + else + return numeric_limits<_Tp>::min(); } return static_cast<_Tp>(__ll); } @@ -763,14 +768,25 @@ __num_get_unsigned_integral(const char* __a, const char* __a_end, { if (__a != __a_end) { + if (*__a == '-') + { + __err = ios_base::failbit; + return 0; + } + int __save_errno = errno; + errno = 0; char *__p2; unsigned long long __ll = strtoull_l(__a, &__p2, __base, 0); + int __current_errno = errno; + if (__current_errno == 0) + errno = __save_errno; if (__p2 != __a_end) { __err = ios_base::failbit; return 0; } - else if (__ll > numeric_limits<_Tp>::max()) + else if (__current_errno == ERANGE || + numeric_limits<_Tp>::max() < __ll) { __err = ios_base::failbit; return numeric_limits<_Tp>::max(); diff --git a/libcxx/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp b/libcxx/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp new file mode 100644 index 00000000000..c60ecc52536 --- /dev/null +++ b/libcxx/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp @@ -0,0 +1,53 @@ +#include <limits> +#include <sstream> +#include <iostream> +#include <cassert> +#include <iostream> + +using namespace std; + +template<typename T> +void check_limits() +{ + T minv = numeric_limits<T>::min(); + T maxv = numeric_limits<T>::max(); + + ostringstream miniss, maxiss; + assert(miniss << minv); + assert(maxiss << maxv); + std::string mins = miniss.str(); + std::string maxs = maxiss.str(); + + istringstream maxoss(maxs), minoss(mins); + + T new_minv, new_maxv; + assert(maxoss >> new_maxv); + assert(minoss >> new_minv); + + assert(new_minv == minv); + assert(new_maxv == maxv); + + if(mins == "0") + mins = "-1"; + else + mins[mins.size() - 1]++; + + maxs[maxs.size() - 1]++; + + istringstream maxoss2(maxs), minoss2(mins); + + assert(! (maxoss2 >> new_maxv)); + assert(! (minoss2 >> new_minv)); +} + +int main(void) +{ + check_limits<short>(); + check_limits<unsigned short>(); + check_limits<int>(); + check_limits<unsigned int>(); + check_limits<long>(); + check_limits<unsigned long>(); + check_limits<long long>(); + check_limits<unsigned long long>(); +} |

