This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
libstdc++/5331: Returned iterator from num_get<>::get is not advanced.
- From: "David Seymour" <qfp at wn dot com dot au>
- To: gcc-gnats at gcc dot gnu dot org
- Date: 9 Jan 2002 05:02:37 -0000
- Subject: libstdc++/5331: Returned iterator from num_get<>::get is not advanced.
>Number: 5331
>Category: libstdc++
>Synopsis: Returned iterator from num_get<>::get is not advanced.
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Jan 09 03:06:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: David Seymour
>Release: 3.1 20011231 (experimental)
>Organization:
>Environment:
System: Linux quokka.home.bogonet 2.4.9-6 #1 Thu Oct 18 09:39:55 EDT 2001 i686 unknown
Architecture: i686
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../egcs/configure --prefix=/opt/gcc-3.1 --enable-threads --enable-version-specific-runtime-libs
>Description:
The returned iterator from num_get<>::get (all signatures) is
not advanced past the scanned number, as required by the
standard (22.2.2.1). Note not noticeable for input iterators,
only manifests for forward (and better) iterators.
>How-To-Repeat:
dave@quokka:~/tries> cat num_get.cc
#include <iostream>
#include <string>
#include <sstream>
#include <locale>
int main()
{
using namespace std;
typedef string::const_iterator iter_type;
typedef num_get<char, iter_type> num_get_type;
long i = 0;
ios_base::iostate err = ios_base::goodbit;
const string str = "42foo";
istringstream iss; // need an ios, add my num_get facet
iss.imbue(locale(iss.getloc(), new num_get_type));
const num_get_type& ng = use_facet<num_get_type>(iss.getloc());
iter_type end = ng.get(str.begin(), str.end(), iss, err, i);
string rem(end, str.end());
cout << "err = " << err << ", should be " << ios_base::goodbit << "\n";
cout << "i = " << i << ", should be 42\n";
cout << "rem = `" << rem << "' should be `foo'\n";
}
dave@quokka:~/tries> g++ -v -Wall -g -o num_get num_get.cc
Reading specs from /opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/specs
Configured with: ../egcs/configure --prefix=/opt/gcc-3.1 --enable-threads --enable-version-specific-runtime-libs
Thread model: posix
gcc version 3.1 20011231 (experimental)
/opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/cc1plus -v -D__GNUC__=3 -D__GNUC_MINOR__=1 -D__GNUC_PATCHLEVEL__=0 -D__ELF__ -Dunix -Dlinux -D__ELF__ -D__unix__ -D__linux__ -D__unix -D__linux -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 -Wall -D_GNU_SOURCE -Acpu=i386 -Amachine=i386 -Di386 -D__i386 -D__i386__ -D__tune_i686__ -D__tune_pentiumpro__ num_get.cc -D__GNUG__=3 -D__DEPRECATED -D__EXCEPTIONS -D__GXX_ABI_VERSION=100 -quiet -dumpbase num_get.cc -g -Wall -version -o /home/dave/.tmp/ccKjZ388.s
GNU CPP version 3.1 20011231 (experimental) (cpplib) (i386 Linux/ELF)
GNU C++ version 3.1 20011231 (experimental) (i686-pc-linux-gnu)
compiled by GNU C version 3.1 20011231 (experimental).
ignoring nonexistent directory "/opt/gcc-3.1/i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/include/g++
/opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/include/g++/i686-pc-linux-gnu
/opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/include/g++/backward
/usr/local/include
/opt/gcc-3.1/include
/opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/include
/usr/include
End of search list.
/opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/../../../../i686-pc-linux-gnu/bin/as -V -Qy -o /home/dave/.tmp/ccV60cIG.o /home/dave/.tmp/ccKjZ388.s
GNU assembler version 2.11.93 (i686-pc-linux-gnu) using BFD version 2.11.93 20011224
/opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/collect2 -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o num_get /usr/lib/crt1.o /usr/lib/crti.o /opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/crtbegin.o -L/opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1 -L/opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/../../../../i686-pc-linux-gnu/lib -L/opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/../../.. /home/dave/.tmp/ccV60cIG.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /opt/gcc-3.1/lib/gcc-lib/i686-pc-linux-gnu/3.1/crtend.o /usr/lib/crtn.o
dave@quokka:~/tries> ./num_get
err = 0, should be 0
i = 42, should be 42
rem = `42foo' should be `foo'
dave@quokka:~/tries>
>Fix:
The following patch works for me. Change in ABI for an internal
interface though and don't quite understand how such changes play out
with non inline templates.
Index: locale_facets.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.34
diff -u -3 -p -r1.34 locale_facets.h
--- locale_facets.h 2001/12/15 07:05:03 1.34
+++ locale_facets.h 2002/01/09 01:24:29
@@ -641,11 +641,11 @@ namespace std
protected:
virtual ~num_get() { }
- void
+ iter_type
_M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
string& __xtrc) const;
- void
+ iter_type
_M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
char* __xtrc, int __max, int& __base) const;
Index: locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.47
diff -u -3 -p -r1.47 locale_facets.tcc
--- locale_facets.tcc 2001/12/27 12:13:23 1.47
+++ locale_facets.tcc 2002/01/09 01:24:34
@@ -88,7 +88,7 @@ namespace std
template<typename _CharT, typename _InIter>
- void
+ _InIter
num_get<_CharT, _InIter>::
_M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
ios_base::iostate& __err, string& __xtrc) const
@@ -213,10 +213,11 @@ namespace std
__xtrc += char();
if (__beg == __end)
__err |= ios_base::eofbit;
+ return __beg;
}
template<typename _CharT, typename _InIter>
- void
+ _InIter
num_get<_CharT, _InIter>::
_M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
ios_base::iostate& __err, char* __xtrc, int __max,
@@ -369,6 +370,7 @@ namespace std
__xtrc[__pos] = char();
if (__beg == __end)
__err |= ios_base::eofbit;
+ return __beg;
}
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
@@ -394,8 +396,8 @@ namespace std
// that can be represented without change" so we have to add 1 to it
// in order to obtain the max number of digits. The same for the
// other do_get for integral types below.
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<bool>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<bool>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -459,8 +461,8 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<long>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<long>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -485,8 +487,9 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned short>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<unsigned short>::digits10 + 1,
+ __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -512,8 +515,9 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned int>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<unsigned int>::digits10 + 1,
+ __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -539,8 +543,9 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned long>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<unsigned long>::digits10 + 1,
+ __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -566,8 +571,8 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<long long>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<long long>::digits10 + 1, __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -592,8 +597,9 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned long long>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<unsigned long long>::digits10 + 1,
+ __base);
// Stage 2: convert and store results.
char* __sanity;
@@ -617,7 +623,7 @@ namespace std
// Stage 1: extract and determine the conversion specifier.
string __xtrc;
__xtrc.reserve(32);
- _M_extract_float(__beg, __end, __io, __err, __xtrc);
+ __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
// Stage 2: convert and store results.
char* __sanity;
@@ -644,7 +650,7 @@ namespace std
// Stage 1: extract and determine the conversion specifier.
string __xtrc;
__xtrc.reserve(32);
- _M_extract_float(__beg, __end, __io, __err, __xtrc);
+ __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
// Stage 2: convert and store results.
char* __sanity;
@@ -667,7 +673,7 @@ namespace std
// Stage 1: extract and determine the conversion specifier.
string __xtrc;
__xtrc.reserve(32);
- _M_extract_float(__beg, __end, __io, __err, __xtrc);
+ __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
#if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
// Stage 2: convert and store results.
@@ -721,8 +727,9 @@ namespace std
// integral types.
char __xtrc[32];
int __base;
- _M_extract_int(__beg, __end, __io, __err, __xtrc,
- numeric_limits<unsigned long>::digits10 + 1, __base);
+ __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc,
+ numeric_limits<unsigned long>::digits10 + 1,
+ __base);
// Stage 2: convert and store results.
char* __sanity;
>Release-Note:
>Audit-Trail:
>Unformatted: