https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105580

--- Comment #20 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tomasz Kaminski <[email protected]>:

https://gcc.gnu.org/g:a068d1b7c9da60a9b21efa4baf65f7325211be12

commit r17-376-ga068d1b7c9da60a9b21efa4baf65f7325211be12
Author: Tomasz KamiÅski <[email protected]>
Date:   Wed Jan 7 14:01:41 2026 +0100

    libstdc++: Rework istreambuf_iterator::_M_sbuf handling to slice
null-dereference warning [PR105580]

    The warning was produced by following sequence, given an
istream_iterator<char>
    it, such that *it will result in hitting EoF in it->_M_get(), and thus
clearing
    _M_sbuf, the subsequent call to ++it, will result in _M_sbuf->sbumpc() call
on
    null pointer. This is however an false-positive, as in such situation
    it == istream_iteator() returns true, and the iterator should not be
    incremented in first place.

    This patch addresses the above by clearing the _M_sbuf in operator++,
instead
    of _M_get(). This removes the need for making _M_sbuf mutable, and thus
make
    the implementation conforming with regards to C++11 [res.on.data.races] p3.
    Also removes no longer needed "-Wnull-dereference" disabling pragmas from
    streambuf (see r16-7844-gbfc2b87f8244a1).

    This change should have zero or positive performance impact on the usual
    iteration patterns, in form:
      while (it != end) { process(*it); ++it; }
    In case when it is end-of-stream iterator, the it != end returns in one
call
    of _M_sbuf->sgetc() both before and after the change. However we do not
modify
    _M_sbuf in this case. For non-empty range, we replace call to
_M_sbuf->sbumpc()
    with _M_sbuf->snextc() in pre-increment, and extract the check against EoF
from
    *it to ++it. However, as _M_sbuf is now cleared during increment, so last
    it != end check avoids _M_sbuf->sgetc() call to check against EoF.

    However, this change impact the behavior of the post-increment (*it++), as
    we now load both current character (for return value) and next character
(to
    check against EoF). In consequence we call both sgetc() and snextc(),
    in contrast to previous single sbumpc() call.

            PR libstdc++/105580

    libstdc++-v3/ChangeLog:

            * include/bits/streambuf_iterator.h (istreambuf_iterator::_M_sbuf):
            Remove mutable and adjust whitespace.
            (istreambuf_iterator::_M_c): Adjust whitespace.
            (istreambuf_iterator::operator++()): Clear _M_sbuf if next
character
            is EoF.
            (istreambuf_iterator::operator++(int)): Use _M_sbuf->sgetc() to
            load current character, and define in terms of ++*this.
            (istreambuf_iterator::_M_get()): Do not clear _M_sbuf in case of
EoF.
            * include/std/streambuf (streambuf::gptr, streambuf::egptr)
            (streambuf::gbump): Remove surrounding pragma disabling
-Wnull-dereference.
            * testsuite/24_iterators/istreambuf_iterator/2.cc: Test for using
            multiple iterators to same rdbuf.

    Reviewed-by: Jonathan Wakely <[email protected]>
    Signed-off-by: Tomasz KamiÅski <[email protected]>
  • [Bug libstdc++/105580] [13/14/1... cvs-commit at gcc dot gnu.org via Gcc-bugs

Reply via email to