This is the mail archive of the gcc-prs@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]

libstdc++/10081: basic_ios constructor fails to initialize variables


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


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