Bug 81338 - stringstream remains empty after being moved into multiple times
Summary: stringstream remains empty after being moved into multiple times
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 6.3.0
: P3 normal
Target Milestone: 5.5
Assignee: Jonathan Wakely
URL:
Keywords:
: 84367 (view as bug list)
Depends on:
Blocks:
 
Reported: 2017-07-06 11:24 UTC by zxy19980101
Modified: 2018-02-19 14:49 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 6.3.0, 7.1.0, 8.0
Last reconfirmed: 2017-07-06 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description zxy19980101 2017-07-06 11:24:34 UTC
Given the code below:

#include <sstream>
#include <iostream>

int main() {
	std::stringstream ss;
	while (true) {
		for (int i = rand() % 10 + 10; i > 0; --i) {
			ss << static_cast<char>(rand() % 26 + 'a');
		}
		std::cout << ss.str() << "\n";
		ss = std::stringstream();
	}
	return 0;
}

The output become blank lines after the first few. The code works on visual studio 2017.

My g++ version is:

g++.exe (x86_64-posix-seh-rev2, Built by MinGW-W64 project) 6.3.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Comment 1 Jonathan Wakely 2017-07-06 15:00:25 UTC
The problem is that basic_stringbuf::overflow assumes that if pptr() == epptr() then we need to reallocate.

After a move we might have pptr() == epptr() but also have unused capacity in the string. We should move epptr() to use that capacity, instead we reallocate to double the string's capacity, which keeps trying to allocate bigger and bigger buffers until allocation fails.
Comment 2 Jonathan Wakely 2017-07-10 17:59:28 UTC
Author: redi
Date: Mon Jul 10 17:58:56 2017
New Revision: 250100

URL: https://gcc.gnu.org/viewcvs?rev=250100&root=gcc&view=rev
Log:
PR libstdc++/81338 correctly manage string capacity

	PR libstdc++/81338
	* include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI] (basic_string):
	Declare basic_stringbuf to be a friend.
	* include/bits/sstream.tcc (basic_stringbuf::overflow)
	[_GLIBCXX_USE_CXX11_ABI]: Use unused capacity before reallocating.
	* include/std/sstream (basic_stringbuf::__xfer_bufptrs): Update string
	length to buffer length.
	* testsuite/27_io/basic_stringstream/assign/81338.cc: New.

Added:
    trunk/libstdc++-v3/testsuite/27_io/basic_stringstream/assign/81338.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/basic_string.h
    trunk/libstdc++-v3/include/bits/sstream.tcc
    trunk/libstdc++-v3/include/std/sstream
Comment 3 Jonathan Wakely 2017-09-04 12:25:04 UTC
Author: redi
Date: Mon Sep  4 12:24:33 2017
New Revision: 251652

URL: https://gcc.gnu.org/viewcvs?rev=251652&root=gcc&view=rev
Log:
PR libstdc++/81338 correctly manage string capacity

Backport from mainline
2017-07-10  Jonathan Wakely  <jwakely@redhat.com>

	PR libstdc++/81338
	* include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI] (basic_string):
	Declare basic_stringbuf to be a friend.
	* include/bits/sstream.tcc (basic_stringbuf::overflow)
	[_GLIBCXX_USE_CXX11_ABI]: Use unused capacity before reallocating.
	* include/std/sstream (basic_stringbuf::__xfer_bufptrs): Update string
	length to buffer length.
	* testsuite/27_io/basic_stringstream/assign/81338.cc: New.

Added:
    branches/gcc-7-branch/libstdc++-v3/testsuite/27_io/basic_stringstream/assign/81338.cc
Modified:
    branches/gcc-7-branch/libstdc++-v3/ChangeLog
    branches/gcc-7-branch/libstdc++-v3/include/bits/basic_string.h
    branches/gcc-7-branch/libstdc++-v3/include/bits/sstream.tcc
    branches/gcc-7-branch/libstdc++-v3/include/std/sstream
Comment 4 Jonathan Wakely 2017-09-04 16:17:30 UTC
Author: redi
Date: Mon Sep  4 16:16:58 2017
New Revision: 251665

URL: https://gcc.gnu.org/viewcvs?rev=251665&root=gcc&view=rev
Log:
PR libstdc++/81338 correctly manage string capacity

Backport from mainline
2017-07-10  Jonathan Wakely  <jwakely@redhat.com>

	PR libstdc++/81338
	* include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI] (basic_string):
	Declare basic_stringbuf to be a friend.
	* include/bits/sstream.tcc (basic_stringbuf::overflow)
	[_GLIBCXX_USE_CXX11_ABI]: Use unused capacity before reallocating.
	* include/std/sstream (basic_stringbuf::__xfer_bufptrs): Update string
	length to buffer length.
	* testsuite/27_io/basic_stringstream/assign/81338.cc: New.

Added:
    branches/gcc-6-branch/libstdc++-v3/testsuite/27_io/basic_stringstream/assign/81338.cc
Modified:
    branches/gcc-6-branch/libstdc++-v3/ChangeLog
    branches/gcc-6-branch/libstdc++-v3/include/bits/basic_string.h
    branches/gcc-6-branch/libstdc++-v3/include/bits/sstream.tcc
    branches/gcc-6-branch/libstdc++-v3/include/std/sstream
Comment 5 Jonathan Wakely 2017-09-04 16:41:56 UTC
Author: redi
Date: Mon Sep  4 16:41:25 2017
New Revision: 251669

URL: https://gcc.gnu.org/viewcvs?rev=251669&root=gcc&view=rev
Log:
PR libstdc++/81338 correctly manage string capacity

Backport from mainline
2017-07-10  Jonathan Wakely  <jwakely@redhat.com>

	PR libstdc++/81338
	* include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI] (basic_string):
	Declare basic_stringbuf to be a friend.
	* include/bits/sstream.tcc (basic_stringbuf::overflow)
	[_GLIBCXX_USE_CXX11_ABI]: Use unused capacity before reallocating.
	* include/std/sstream (basic_stringbuf::__xfer_bufptrs): Update string
	length to buffer length.
	* testsuite/27_io/basic_stringstream/assign/81338.cc: New.

Added:
    branches/gcc-5-branch/libstdc++-v3/testsuite/27_io/basic_stringstream/assign/81338.cc
Modified:
    branches/gcc-5-branch/libstdc++-v3/ChangeLog
    branches/gcc-5-branch/libstdc++-v3/include/bits/basic_string.h
    branches/gcc-5-branch/libstdc++-v3/include/bits/sstream.tcc
    branches/gcc-5-branch/libstdc++-v3/include/std/sstream
Comment 6 Jonathan Wakely 2017-09-04 17:13:33 UTC
Fixed for all branches that have the buggy new code.
Comment 7 Jonathan Wakely 2018-02-13 17:48:50 UTC
*** Bug 84367 has been marked as a duplicate of this bug. ***
Comment 8 Jonathan Wakely 2018-02-13 17:52:32 UTC
This was fixed for 5.5, 6.5, 7.3 and 8.1
Comment 9 Jonathan Wakely 2018-02-19 14:49:45 UTC
*** Bug 84367 has been marked as a duplicate of this bug. ***