aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo@gcc.gnu.org>2009-04-18 19:28:40 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2009-04-18 19:28:40 +0000
commit2daad65eaf4b3406d04d6ba4758b120312ed0a0c (patch)
treec2d965f605e2cc49ed79113b10c1508656af5be1
parent2505c5edcac3fbc0a39ad74c63bab1534ee6e491 (diff)
downloadgcc-2daad65eaf4b3406d04d6ba4758b120312ed0a0c.zip
gcc-2daad65eaf4b3406d04d6ba4758b120312ed0a0c.tar.gz
gcc-2daad65eaf4b3406d04d6ba4758b120312ed0a0c.tar.bz2
re PR libstdc++/39802 (std::num_get fails to parse negative zero input correctly)
2009-04-18 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/39802 * include/bits/locale_facets.tcc (num_get<>::_M_extract_int (_InIter, _InIter, ios_base&, ios_base::iostate&, _ValueT&)): Always accept negative values, for unsigned types too. * testsuite/22_locale/num_get/get/char/39802.cc: New. * testsuite/22_locale/num_get/get/wchar_t/39802.cc: Likewise. From-SVN: r146323
-rw-r--r--libstdc++-v3/ChangeLog19
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc9
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/char/39802.cc77
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/39802.cc77
4 files changed, 174 insertions, 8 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 7c434cf..22736cd 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,12 @@
+2009-04-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/39802
+ * include/bits/locale_facets.tcc (num_get<>::_M_extract_int
+ (_InIter, _InIter, ios_base&, ios_base::iostate&, _ValueT&)):
+ Always accept negative values, for unsigned types too.
+ * testsuite/22_locale/num_get/get/char/39802.cc: New.
+ * testsuite/22_locale/num_get/get/wchar_t/39802.cc: Likewise.
+
2009-04-18 Jan Hubicka <jh@suse.cz>
* include/debug/formater.h: Include bits/c++config.h.
@@ -5,10 +14,12 @@
* include/bits/c++config (_GLIBCXX_PURE, _GLIBCXX_CONST,
_GLIBCXX_NORETURN): New.
* include/bits/stl_tree.h (_Rb_tree_increment, _Rb_tree_increment,
- _Rb_tree_decrement, _Rb_tree_decrement, _Rb_tree_black_count): Mark pure.
- * include/c_compatibility/stdatomic.h (atomic_flag_test_and_set_explicit,
- atomic_flag_clear_explicit, __atomic_flag_wait_explicit,
- __atomic_flag_for_address): Mark by throw ().
+ _Rb_tree_decrement, _Rb_tree_decrement, _Rb_tree_black_count):
+ Mark pure.
+ * include/c_compatibility/stdatomic.h
+ (atomic_flag_test_and_set_explicit, atomic_flag_clear_explicit,
+ __atomic_flag_wait_explicit, __atomic_flag_for_address):
+ Mark by throw ().
* src/atomic.cc (atomic_flag_test_and_set_explicit,
atomic_flag_clear_explicit, __atomic_flag_wait_explicit,
__atomic_flag_for_address): Mark by throw ().
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index 47eac6a..ba8f398 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -379,8 +379,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
if (!__testeof)
{
__c = *__beg;
- if (__gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
- __negative = __c == __lit[__num_base::_S_iminus];
+ __negative = __c == __lit[__num_base::_S_iminus];
if ((__negative || __c == __lit[__num_base::_S_iplus])
&& !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
&& !(__c == __lc->_M_decimal_point))
@@ -449,7 +448,8 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
__found_grouping.reserve(32);
bool __testfail = false;
bool __testoverflow = false;
- const __unsigned_type __max = __negative
+ const __unsigned_type __max =
+ (__negative && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
? -__gnu_cxx::__numeric_traits<_ValueT>::__min
: __gnu_cxx::__numeric_traits<_ValueT>::__max;
const __unsigned_type __smax = __max / __base;
@@ -552,7 +552,8 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
}
else if (__testoverflow)
{
- if (__negative)
+ if (__negative
+ && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
__v = __gnu_cxx::__numeric_traits<_ValueT>::__min;
else
__v = __gnu_cxx::__numeric_traits<_ValueT>::__max;
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/char/39802.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/char/39802.cc
new file mode 100644
index 0000000..b310508
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/char/39802.cc
@@ -0,0 +1,77 @@
+// Copyright (C) 2009 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 22.2.2.1.1 num_get members
+
+#include <locale>
+#include <sstream>
+#include <limits>
+#include <testsuite_hooks.h>
+
+// libstdc++/39802
+void test01()
+{
+ using namespace std;
+ typedef istreambuf_iterator<char> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ stringstream ss;
+ const num_get<char>& ng = use_facet<num_get<char> >(ss.getloc());
+ ios_base::iostate err;
+ iterator_type end;
+ const string empty;
+
+ unsigned long ul0 = 1;
+ const unsigned long ul1 = numeric_limits<unsigned long>::max();
+
+ ss << "-0";
+ err = ios_base::goodbit;
+ end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( ul0 == 0 );
+
+ ss.clear();
+ ss.str(empty);
+ ss << "-1";
+ err = ios_base::goodbit;
+ end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( ul0 == ul1 );
+
+ ss.clear();
+ ss.str(empty);
+ ss << '-' << ul1;
+ err = ios_base::goodbit;
+ end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( ul0 == 1 );
+
+ ss.clear();
+ ss.str(empty);
+ ss << '-' << ul1 << '0';
+ err = ios_base::goodbit;
+ end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+ VERIFY( err == (ios_base::eofbit | ios_base::failbit) );
+ VERIFY( ul0 == ul1 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/39802.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/39802.cc
new file mode 100644
index 0000000..67138d1
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/39802.cc
@@ -0,0 +1,77 @@
+// Copyright (C) 2009 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 22.2.2.1.1 num_get members
+
+#include <locale>
+#include <sstream>
+#include <limits>
+#include <testsuite_hooks.h>
+
+// libstdc++/39802
+void test01()
+{
+ using namespace std;
+ typedef istreambuf_iterator<wchar_t> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ wstringstream ss;
+ const num_get<wchar_t>& ng = use_facet<num_get<wchar_t> >(ss.getloc());
+ ios_base::iostate err;
+ iterator_type end;
+ const wstring empty;
+
+ unsigned long ul0 = 1;
+ const unsigned long ul1 = numeric_limits<unsigned long>::max();
+
+ ss << L"-0";
+ err = ios_base::goodbit;
+ end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( ul0 == 0 );
+
+ ss.clear();
+ ss.str(empty);
+ ss << L"-1";
+ err = ios_base::goodbit;
+ end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( ul0 == ul1 );
+
+ ss.clear();
+ ss.str(empty);
+ ss << L'-' << ul1;
+ err = ios_base::goodbit;
+ end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( ul0 == 1 );
+
+ ss.clear();
+ ss.str(empty);
+ ss << L'-' << ul1 << L'0';
+ err = ios_base::goodbit;
+ end = ng.get(ss.rdbuf(), 0, ss, err, ul0);
+ VERIFY( err == (ios_base::eofbit | ios_base::failbit) );
+ VERIFY( ul0 == ul1 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}