This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] Fix libstdc++/37958
- From: Paolo Carlini <paolo dot carlini at oracle dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Fri, 31 Oct 2008 17:49:00 +0100
- Subject: [v3] Fix libstdc++/37958
Hi,
tested x86_64-linux, committed to mainline.
Paolo.
///////////////////////
2008-10-31 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/37958
* include/bits/locale_facets.tcc (num_get<>::do_get(iter_type,
iter_type, ios_base&, ios_base::iostate&, bool&): Fix.
* testsuite/22_locale/num_get/get/char/37958.cc: New.
* testsuite/22_locale/num_get/get/wchar_t/37958.cc: Likewise.
Index: include/bits/locale_facets.tcc
===================================================================
*** include/bits/locale_facets.tcc (revision 141491)
--- include/bits/locale_facets.tcc (working copy)
*************** _GLIBCXX_BEGIN_LDBL_NAMESPACE
*** 599,653 ****
else
{
// Parse bool values as alphanumeric.
! typedef __numpunct_cache<_CharT> __cache_type;
__use_cache<__cache_type> __uc;
const locale& __loc = __io._M_getloc();
const __cache_type* __lc = __uc(__loc);
! bool __testf = true;
! bool __testt = true;
size_t __n;
bool __testeof = __beg == __end;
for (__n = 0; !__testeof; ++__n)
{
const char_type __c = *__beg;
! if (__testf)
! {
if (__n < __lc->_M_falsename_size)
! __testf = __c == __lc->_M_falsename[__n];
else
! break;
}
! if (__testt)
! {
if (__n < __lc->_M_truename_size)
! __testt = __c == __lc->_M_truename[__n];
else
! break;
}
! if (!__testf && !__testt)
break;
if (++__beg == __end)
__testeof = true;
}
if (__testf && __n == __lc->_M_falsename_size)
! __v = false;
else if (__testt && __n == __lc->_M_truename_size)
! __v = true;
else
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 23. Num_get overflow result.
__v = false;
__err = ios_base::failbit;
}
-
- if (__testeof)
- __err |= ios_base::eofbit;
}
return __beg;
}
--- 599,671 ----
else
{
// Parse bool values as alphanumeric.
! typedef __numpunct_cache<_CharT> __cache_type;
__use_cache<__cache_type> __uc;
const locale& __loc = __io._M_getloc();
const __cache_type* __lc = __uc(__loc);
! bool __testf = false;
! bool __donef = false;
! bool __testt = false;
! bool __donet = false;
size_t __n;
bool __testeof = __beg == __end;
for (__n = 0; !__testeof; ++__n)
{
const char_type __c = *__beg;
! if (!__donef)
! {
if (__n < __lc->_M_falsename_size)
! {
! __testf = __c == __lc->_M_falsename[__n];
! if (!__testf)
! __donef = true;
! }
else
! __donef = true;
}
! if (!__donet)
! {
if (__n < __lc->_M_truename_size)
! {
! __testt = __c == __lc->_M_truename[__n];
! if (!__testt)
! __donet = true;
! }
else
! __donet = true;
}
! if (__donef && __donet)
break;
if (++__beg == __end)
__testeof = true;
}
if (__testf && __n == __lc->_M_falsename_size)
! {
! __v = false;
! if (__testt && __n == __lc->_M_truename_size)
! __err = ios_base::failbit;
! else
! __err = __donet ? ios_base::goodbit : ios_base::eofbit;
! }
else if (__testt && __n == __lc->_M_truename_size)
! {
! __v = true;
! __err = __donef ? ios_base::goodbit : ios_base::eofbit;
! }
else
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 23. Num_get overflow result.
__v = false;
__err = ios_base::failbit;
+ if (__testeof && __n)
+ __err |= ios_base::eofbit;
}
}
return __beg;
}
Index: testsuite/22_locale/num_get/get/wchar_t/37958.cc
===================================================================
*** testsuite/22_locale/num_get/get/wchar_t/37958.cc (revision 0)
--- testsuite/22_locale/num_get/get/wchar_t/37958.cc (revision 0)
***************
*** 0 ****
--- 1,109 ----
+ // 2008-10-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ // Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+ // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ // USA.
+
+ // 22.2.2.1.1 num_get members
+
+ #include <locale>
+ #include <sstream>
+ #include <testsuite_hooks.h>
+
+ struct Punct1: std::numpunct<wchar_t>
+ {
+ std::wstring do_truename() const { return L"a"; }
+ std::wstring do_falsename() const { return L"abb"; }
+ };
+
+ struct Punct2: std::numpunct<wchar_t>
+ {
+ std::wstring do_truename() const { return L"1"; }
+ std::wstring do_falsename() const { return L"0"; }
+ };
+
+ struct Punct3: std::numpunct<wchar_t>
+ {
+ std::wstring do_truename() const { return L""; }
+ std::wstring do_falsename() const { return L""; }
+ };
+
+ // libstdc++/37958
+ void test01()
+ {
+ using namespace std;
+ typedef istreambuf_iterator<wchar_t> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ wistringstream iss1, iss2, iss3;
+ iss1.imbue(locale(iss1.getloc(), new Punct1));
+ iss2.imbue(locale(iss2.getloc(), new Punct2));
+ iss3.imbue(locale(iss3.getloc(), new Punct3));
+ const num_get<wchar_t>& ng1 = use_facet<num_get<wchar_t> >(iss1.getloc());
+ const num_get<wchar_t>& ng2 = use_facet<num_get<wchar_t> >(iss2.getloc());
+ const num_get<wchar_t>& ng3 = use_facet<num_get<wchar_t> >(iss3.getloc());
+
+ ios_base::iostate err = ios_base::goodbit;
+ iterator_type end;
+ bool b1 = false;
+ bool b2 = false;
+ bool b3 = true;
+
+ iss1.str(L"a");
+ iss1.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( b1 == true );
+
+ iss1.str(L"abb");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( b1 == false );
+
+ iss1.str(L"abc");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( b1 == false );
+ VERIFY( *end == L'c' );
+
+ iss2.str(L"1");
+ iss2.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, b2);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( b2 == true );
+
+ iss3.str(L"blah");
+ iss3.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng3.get(iss3.rdbuf(), 0, iss3, err, b3);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( b3 == false );
+ VERIFY( *end == L'b' );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }
Index: testsuite/22_locale/num_get/get/char/37958.cc
===================================================================
*** testsuite/22_locale/num_get/get/char/37958.cc (revision 0)
--- testsuite/22_locale/num_get/get/char/37958.cc (revision 0)
***************
*** 0 ****
--- 1,109 ----
+ // 2008-10-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ // Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+ // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ // USA.
+
+ // 22.2.2.1.1 num_get members
+
+ #include <locale>
+ #include <sstream>
+ #include <testsuite_hooks.h>
+
+ struct Punct1: std::numpunct<char>
+ {
+ std::string do_truename() const { return "a"; }
+ std::string do_falsename() const { return "abb"; }
+ };
+
+ struct Punct2: std::numpunct<char>
+ {
+ std::string do_truename() const { return "1"; }
+ std::string do_falsename() const { return "0"; }
+ };
+
+ struct Punct3: std::numpunct<char>
+ {
+ std::string do_truename() const { return ""; }
+ std::string do_falsename() const { return ""; }
+ };
+
+ // libstdc++/37958
+ void test01()
+ {
+ using namespace std;
+ typedef istreambuf_iterator<char> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ istringstream iss1, iss2, iss3;
+ iss1.imbue(locale(iss1.getloc(), new Punct1));
+ iss2.imbue(locale(iss2.getloc(), new Punct2));
+ iss3.imbue(locale(iss3.getloc(), new Punct3));
+ const num_get<char>& ng1 = use_facet<num_get<char> >(iss1.getloc());
+ const num_get<char>& ng2 = use_facet<num_get<char> >(iss2.getloc());
+ const num_get<char>& ng3 = use_facet<num_get<char> >(iss3.getloc());
+
+ ios_base::iostate err = ios_base::goodbit;
+ iterator_type end;
+ bool b1 = false;
+ bool b2 = false;
+ bool b3 = true;
+
+ iss1.str("a");
+ iss1.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( b1 == true );
+
+ iss1.str("abb");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( b1 == false );
+
+ iss1.str("abc");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( b1 == false );
+ VERIFY( *end == 'c' );
+
+ iss2.str("1");
+ iss2.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, b2);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( b2 == true );
+
+ iss3.str("blah");
+ iss3.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng3.get(iss3.rdbuf(), 0, iss3, err, b3);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( b3 == false );
+ VERIFY( *end == 'b' );
+ }
+
+ int main()
+ {
+ test01();
+ return 0;
+ }