This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
libstdc++/10081: basic_ios constructor fails to initialize variables
- From: peturr02 at ru dot is
- To: gcc-gnats at gcc dot gnu dot org
- Date: 14 Mar 2003 12:02:09 -0000
- Subject: libstdc++/10081: basic_ios constructor fails to initialize variables
- Reply-to: peturr02 at ru dot is
>Number: 10081
>Category: libstdc++
>Synopsis: basic_ios constructor fails to initialize variables
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Mar 14 12:06:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: peturr02 at ru dot is
>Release: gcc-3.2.2
>Organization:
>Environment:
Red Hat Linux 8.0
>Description:
The constructor basic_ios::basic_ios() doesn't initialize the members _M_fctype, _M_fnumput and _M_fnumget, leading to crashes when these members are accessed later.
>How-To-Repeat:
See attachment. This only checks _M_fctype, to test for the others, numpunct must be specialized for the character type in use.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="iosconsbug.cc"
Content-Disposition: inline; filename="iosconsbug.cc"
#include <string>
#include <fstream>
#include <locale>
namespace __gnu_cxx_test
{
// Test data types.
struct pod_char
{
unsigned char c;
};
struct pod_int
{
int i;
};
struct state
{
unsigned long l;
unsigned long l2;
};
}
namespace std
{
// char_traits specialization
template<>
struct char_traits<__gnu_cxx_test::pod_char>
{
typedef __gnu_cxx_test::pod_char char_type;
typedef __gnu_cxx_test::pod_int int_type;
typedef fpos<__gnu_cxx_test::state> pos_type;
typedef long off_type;
typedef __gnu_cxx_test::state state_type;
static void
assign(char_type& c1, const char_type& c2)
{ c1.c = c2.c; }
static bool
eq(const char_type& c1, const char_type& c2)
{ return c1.c == c2.c; }
static bool
lt(const char_type& c1, const char_type& c2)
{ return c1.c < c2.c; }
static int
compare(const char_type* s1, const char_type* s2, size_t n)
{ return memcmp(s1, s2, n); }
static size_t
length(const char_type* s)
{ return strlen(reinterpret_cast<const char*>(s)); }
static const char_type*
find(const char_type* s, size_t n, const char_type& a)
{ return static_cast<const char_type*>(memchr(s, a.c, n)); }
static char_type*
move(char_type* s1, const char_type* s2, size_t n)
{
memmove(s1, s2, n);
return s1;
}
static char_type*
copy(char_type* s1, const char_type* s2, size_t n)
{
memcpy(s1, s2, n);
return s1;
}
static char_type*
assign(char_type* s, size_t n, char_type a)
{
memset(s, a.c, n);
return s;
}
static char_type
to_char_type(const int_type& c)
{
char_type ret;
ret.c = static_cast<unsigned char>(c.i);
return ret;
}
static int_type
to_int_type(const char_type& c)
{
int_type ret;
ret.i = c.c;
return ret;
}
static bool
eq_int_type(const int_type& c1, const int_type& c2)
{ return c1.i == c2.i; }
static int_type
eof()
{
int_type n;
n.i = -10;
return n;
}
static int_type
not_eof(const int_type& c)
{
if (eq_int_type(c, eof()))
return int_type();
return c;
}
};
template <>
class ctype<__gnu_cxx_test::pod_char>
: public locale::facet, public ctype_base
{
public:
static locale::id id;
typedef __gnu_cxx_test::pod_char char_type;
explicit
ctype(size_t __refs = 0): locale::facet(__refs) { }
bool
is(mask m, char_type c) const
{ return this->do_is(m, c); }
const char_type*
is(const char_type *__lo, const char_type *__hi, mask *__vec) const
{ return this->do_is(__lo, __hi, __vec); }
const char_type*
scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
{ return this->do_scan_is(__m, __lo, __hi); }
const char_type*
scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
{ return this->do_scan_not(__m, __lo, __hi); }
char_type
toupper(char_type __c) const
{ return this->do_toupper(__c); }
const char_type*
toupper(char_type *__lo, const char_type* __hi) const
{ return this->do_toupper(__lo, __hi); }
char_type
tolower(char_type __c) const
{ return this->do_tolower(__c); }
const char_type*
tolower(char_type* __lo, const char_type* __hi) const
{ return this->do_tolower(__lo, __hi); }
char_type
widen(char __c) const
{ return this->do_widen(__c); }
const char*
widen(const char* __lo, const char* __hi, char_type* __to) const
{ return this->do_widen(__lo, __hi, __to); }
char
narrow(char_type __c, char __dfault) const
{ return this->do_narrow(__c, __dfault); }
const char_type*
narrow(const char_type* __lo, const char_type* __hi,
char __dfault, char *__to) const
{ return this->do_narrow(__lo, __hi, __dfault, __to); }
protected:
virtual
~ctype() { }
virtual bool
do_is(mask __m, char_type __c) const
{ return false; }
virtual const char_type*
do_is(const char_type* __lo, const char_type* hi,
mask* __vec) const
{ return hi; }
virtual const char_type*
do_scan_is(mask __m, const char_type* __lo,
const char_type* hi) const
{ return hi; }
virtual const char_type*
do_scan_not(mask __m, const char_type* lo,
const char_type* __hi) const
{ return lo; }
virtual char_type
do_toupper(char_type c) const
{ return c; }
virtual const char_type*
do_toupper(char_type* __lo, const char_type* hi) const
{ return hi; }
virtual char_type
do_tolower(char_type c) const
{ return c; }
virtual const char_type*
do_tolower(char_type* __lo, const char_type* hi) const
{ return hi; }
virtual char_type
do_widen(char c) const
{
char_type ret;
ret.c = static_cast<unsigned char>(c);
return ret;
}
virtual const char*
do_widen(const char* lo, const char* hi,
char_type* dest) const
{
while (lo < hi)
*dest++ = do_widen(*lo++);
return hi;
}
virtual char
do_narrow(char_type c, char) const
{
return c.c;
}
virtual const char_type*
do_narrow(const char_type* lo, const char_type* hi,
char dfault, char* dest) const
{
while (lo < hi)
*dest++ = do_narrow(*lo++, dfault);
return hi;
}
};
locale::id ctype<__gnu_cxx_test::pod_char>::id;
}
int main()
{
using __gnu_cxx_test::pod_char;
{
char buf[1024];
memset(buf, 15, 1024);
}
std::basic_string<pod_char> str;
std::basic_ifstream<pod_char> stream;
stream >> str;
return 0;
}