summaryrefslogtreecommitdiffstats
path: root/libcxx
diff options
context:
space:
mode:
authorHoward Hinnant <hhinnant@apple.com>2011-02-25 19:52:41 +0000
committerHoward Hinnant <hhinnant@apple.com>2011-02-25 19:52:41 +0000
commita8d8ca4d6f700890791d5a2ba99c647e522cdd38 (patch)
tree20a0bdf5a5746b4cc032e3cc17819db64be1f452 /libcxx
parent301416380e7ae3b2cc3e0b517504b46aa2b64a23 (diff)
downloadbcm5719-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/locale32
-rw-r--r--libcxx/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/test_min_max.pass.cpp53
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>();
+}
OpenPOWER on IntegriCloud