[libc++] Fix `std::out_of_range` thrown from `basic_stringbuf::str() &&`
authorPiotr Fusik <fox@scene.pl>
Tue, 1 Aug 2023 18:17:46 +0000 (20:17 +0200)
committerTobias Hieta <tobias@hieta.se>
Thu, 3 Aug 2023 07:01:33 +0000 (09:01 +0200)
Reviewed By: #libc, Mordante, philnik

Differential Revision: https://reviews.llvm.org/D156783

(cherry picked from commit f418cb1a9367d85c7c9b1aa93dc3fa60c8ef9849)

libcxx/include/sstream
libcxx/test/std/input.output/string.streams/istringstream/istringstream.members/str.move.pass.cpp
libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.members/str.move.pass.cpp
libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.move.pass.cpp
libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.move.pass.cpp

index d7ad0213eb34996cd109af878f18680c01cabae3..81255c878f7f3af3467e0e346a20ee91f4d23c84 100644 (file)
@@ -399,8 +399,12 @@ public:
     _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return str(__str_.get_allocator()); }
 
     _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && {
+        string_type __result;
         const basic_string_view<_CharT, _Traits> __view = view();
-        string_type __result(std::move(__str_), __view.data() - __str_.data(), __view.size());
+        if (!__view.empty()) {
+            auto __pos = __view.data() - __str_.data();
+            __result.assign(std::move(__str_), __pos, __view.size());
+        }
         __str_.clear();
         __init_buf_ptrs();
         return __result;
index 7c8cf2c713db70abd771310b5f4d0c861064b557..546f82166aaefa7a4f7e07c2fdef49b4d1751e76 100644 (file)
@@ -31,6 +31,12 @@ static void test() {
     assert(s == STR("testing"));
     assert(ss.view().empty());
   }
+  {
+    std::basic_istringstream<CharT> ss;
+    std::basic_string<CharT> s = std::move(ss).str();
+    assert(s.empty());
+    assert(ss.view().empty());
+  }
 }
 
 int main(int, char**) {
index 5fbdf81f0c08ecf1d3cda2bd45da4ee864b8da56..57f2384bae52c618a598989b25276da1fa5e03d3 100644 (file)
@@ -31,6 +31,12 @@ static void test() {
     assert(s == STR("testing"));
     assert(ss.view().empty());
   }
+  {
+    std::basic_ostringstream<CharT> ss;
+    std::basic_string<CharT> s = std::move(ss).str();
+    assert(s.empty());
+    assert(ss.view().empty());
+  }
 }
 
 int main(int, char**) {
index f0fa330b4b600f2f7084e445ffd94167c6e2d763..0f0f540a9c2474d164f1a0a78ae7166ee78dbe20 100644 (file)
@@ -31,6 +31,12 @@ static void test() {
     assert(s == STR("testing"));
     assert(buf.view().empty());
   }
+  {
+    std::basic_stringbuf<CharT> buf;
+    std::basic_string<CharT> s = std::move(buf).str();
+    assert(s.empty());
+    assert(buf.view().empty());
+  }
 }
 
 int main(int, char**) {
index a6b8ec6c37ebaf1f5c24cf908a7dc66a37a4397c..35349c9c288ec1af87a90d3e836eeca3bb56a155 100644 (file)
@@ -31,6 +31,12 @@ static void test() {
     assert(s == STR("testing"));
     assert(ss.view().empty());
   }
+  {
+    std::basic_stringstream<CharT> ss;
+    std::basic_string<CharT> s = std::move(ss).str();
+    assert(s.empty());
+    assert(ss.view().empty());
+  }
 }
 
 int main(int, char**) {