https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81395
--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Paolo Carlini from comment #4) > Seems weird: -1 means uncommitted (per the comment before _M_set_buffer) and > we also set _M_reading? I don't think we do that anywhere else. But we also don't use _M_set_buffer(0) (write mode) and _M_reading=true (read mode) anywhere else, and doing that makes no sense to me. This comment says that _M_set_buffer(0) means write mode: /** * This function sets the pointers of the internal buffer, both get * and put areas. Typically: * * __off == egptr() - eback() upon underflow/uflow (@b read mode); * __off == 0 upon overflow (@b write mode); * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode). * * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size * reflects the actual allocated memory and the last cell is reserved * for the overflow char of a full put area. */ void _M_set_buffer(streamsize __off) But we call that from xsgetn which is obviously a read operation. And this comment says _M_reading == true means read mode: /** * _M_reading == false && _M_writing == false for @b uncommitted mode; * _M_reading == true for @b read mode; * _M_writing == true for @b write mode; * * NB: _M_reading == true && _M_writing == true is unused. */ bool _M_reading; bool _M_writing; And it also says we don't use both true at once. So calling _M_set_buffer(0) and setting _M_reading == true is a contradiction, or the comments are wrong.