From a054f828ddf4c1f9eae8889381cccdd3bdf7b2bf Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Wed, 2 Aug 2017 17:31:09 +0000 Subject: [PATCH] Fix PR33727: std::basic_stringbuf only works with DefaultConstructible allocators. Thanks to Jonathan Wakely for the report and suggested fix llvm-svn: 309838 --- libcxx/include/sstream | 3 ++- .../stringstream.cons/string.pass.cpp | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/libcxx/include/sstream b/libcxx/include/sstream index b9903f961823..fe65fd7db53d 100644 --- a/libcxx/include/sstream +++ b/libcxx/include/sstream @@ -249,7 +249,8 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(ios_base::openmode template basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(const string_type& __s, ios_base::openmode __wch) - : __hm_(0), + : __str_(__s.get_allocator()), + __hm_(0), __mode_(__wch) { str(__s); diff --git a/libcxx/test/std/input.output/string.streams/stringstream.cons/string.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream.cons/string.pass.cpp index 3776f17f5304..43b9df68674d 100644 --- a/libcxx/test/std/input.output/string.streams/stringstream.cons/string.pass.cpp +++ b/libcxx/test/std/input.output/string.streams/stringstream.cons/string.pass.cpp @@ -18,6 +18,16 @@ #include #include +template +struct NoDefaultAllocator : std::allocator +{ + template struct rebind { using other = NoDefaultAllocator; }; + NoDefaultAllocator(int id) : id(id) { } + template NoDefaultAllocator(const NoDefaultAllocator& a) : id(a.id) { } + int id; +}; + + int main() { { @@ -46,4 +56,13 @@ int main() ss << i << ' ' << 123; assert(ss.str() == L"456 1236 "); } + { // This is https://bugs.llvm.org/show_bug.cgi?id=33727 + typedef std::basic_string , NoDefaultAllocator > S; + typedef std::basic_stringbuf, NoDefaultAllocator > SB; + + S s(NoDefaultAllocator(1)); + SB sb(s); + // This test is not required by the standard, but *where else* could it get the allocator? + assert(sb.str().get_allocator() == s.get_allocator()); + } }