Fix for PR 6745, 8071, 8127: __copy_streambufs in odd cases

Jonathan Lennox lennox@cs.columbia.edu
Mon Oct 7 10:59:00 GMT 2002


There are a number of PRs -- 6745, 8071, and 8127, at least -- which have to
deal with failures of the ostream::operator<<(streambuf*) operator.

I tracked these down, and determined what the problem was.  The problem is
that the __copy_streambufs function is making assumptions about the behavior
of streambuf classes which aren't guaranteed by the C++ standard.

There were two invalid assumptions this function was making:
* streambuf::in_avail() always returns a positive value, or -1 if EOF's been
  reached.
  This isn't guaranteed by showmanyc(), which in_avail() is defined as
  calling.  27.5.2.4.3 [lib.streambuf.virt.get] paragraph 2 only says what
  positive values and -1 mean, but nowhere requires that either be
  returned.  Indeed, the default behavior of this function is to return 0.

* streambuf::gptr() will always have a non-NULL value after a call to
  streambuf::in_avail().
  This isn't guaranteed either; section 27.5.1 [lib.streambuf.reqts]
  paragraph 3 only says that either eback(), gptr(), and egptr() will all be
  non-NULL, or they'll all be NULL.

This patch (below) checks for both these conditions while copying
streambufs.  If either assumption fails, it falls back to a less-efficient
but (hopefully) always correct implementation.

I've also attached a test case, which fails with gcc 3.1.  (This code hasn't
changed substantially between 3.1 and the mainline, so the test case should
fail with the current mainline as well.)

Note that I didn't actually test this code against a full gcc mainline
build.  I only tested it by copying bits/streambuf.tcc and bits/ostream.tcc
to a local include directory, #if 0'ing their 'extern template'
declarations, and putting this directory in the include path before
$prefix/include/g++-v3/.  (These tests were against gcc 3.1, but I've
updated the patch to apply cleanly to the mainline instead.)

PRs 6745 and 8127, which this patch fixes, are regressions from gcc 2.95.2.
(The test case fails under 2.95.2, however; I haven't investigated what the
difference is in the old library.)

I don't have a GCC copyright assignment filed.  Is this patch substantial
enough to require one?  (I don't think the test case requires a copyright
assignment, yes?)

2002-10-07  Jonathan Lennox  <lennox@cs.columbia.edu>

	PR libstdc++/8071, libstdc++/8127, c++/6745
	* streambuf.tcc (__copy_streambufs): Handle cases where
	__sbin->in_avail() returns 0, or where __sbin doesn't set gptr().


-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: streambuf.tcc.patch
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20021007/241078d1/attachment.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: test-streambuf.cxx
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20021007/241078d1/attachment.cxx>
-------------- next part --------------


-- 
Jonathan Lennox
lennox@cs.columbia.edu


More information about the Gcc-patches mailing list