This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]