[libcxx] r178690 - The move / swap members were not correctly taking all of the possible states of the basic_stringbuf into account. Just rewrote these members. Test included. This fixes http://llvm.org/bugs/show_bug.cgi?id=15659.

Howard Hinnant hhinnant at apple.com
Wed Apr 3 13:21:29 PDT 2013


Author: hhinnant
Date: Wed Apr  3 15:21:29 2013
New Revision: 178690

URL: http://llvm.org/viewvc/llvm-project?rev=178690&view=rev
Log:
The move / swap members were not correctly taking all of the possible states of the basic_stringbuf into account.  Just rewrote these members.  Test included.  This fixes http://llvm.org/bugs/show_bug.cgi?id=15659.

Added:
    libcxx/trunk/test/input.output/string.streams/stringstream.cons/move2.pass.cpp
Modified:
    libcxx/trunk/include/sstream

Modified: libcxx/trunk/include/sstream
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/sstream?rev=178690&r1=178689&r2=178690&view=diff
==============================================================================
--- libcxx/trunk/include/sstream (original)
+++ libcxx/trunk/include/sstream Wed Apr  3 15:21:29 2013
@@ -260,17 +260,36 @@ template <class _CharT, class _Traits, c
 basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(basic_stringbuf&& __rhs)
     : __mode_(__rhs.__mode_)
 {
-    ptrdiff_t __ninp = __rhs.gptr()  - __rhs.eback();
-    ptrdiff_t __einp = __rhs.egptr() - __rhs.eback();
-    ptrdiff_t __nout = __rhs.pptr()  - __rhs.pbase();
-    ptrdiff_t __eout = __rhs.epptr() - __rhs.pbase();
-    ptrdiff_t __hm   = __rhs.__hm_   - __rhs.pbase();
+    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
+    ptrdiff_t __binp = -1;
+    ptrdiff_t __ninp = -1;
+    ptrdiff_t __einp = -1;
+    if (__rhs.eback() != nullptr)
+    {
+        __binp = __rhs.eback() - __p;
+        __ninp = __rhs.gptr() - __p;
+        __einp = __rhs.egptr() - __p;
+    }
+    ptrdiff_t __bout = -1;
+    ptrdiff_t __nout = -1;
+    ptrdiff_t __eout = -1;
+    if (__rhs.pbase() != nullptr)
+    {
+        __bout = __rhs.pbase() - __p;
+        __nout = __rhs.pptr() - __p;
+        __eout = __rhs.epptr() - __p;
+    }
+    ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
     __str_ = _VSTD::move(__rhs.__str_);
-    char_type* __p = const_cast<char_type*>(__str_.data());
-    this->setg(__p, __p + __ninp, __p + __einp);
-    this->setp(__p, __p + __eout);
-    this->pbump(__nout);
-    __hm_ = __p + __hm;
+    __p = const_cast<char_type*>(__str_.data());
+    if (__binp != -1)
+        this->setg(__p + __binp, __p + __ninp, __p + __einp);
+    if (__bout != -1)
+    {
+        this->setp(__p + __bout, __p + __eout);
+        this->pbump(__nout);
+    }
+    __hm_ = __hm == -1 ? nullptr : __p + __hm;
     __p = const_cast<char_type*>(__rhs.__str_.data());
     __rhs.setg(__p, __p, __p);
     __rhs.setp(__p, __p);
@@ -282,18 +301,37 @@ template <class _CharT, class _Traits, c
 basic_stringbuf<_CharT, _Traits, _Allocator>&
 basic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs)
 {
-    ptrdiff_t __ninp = __rhs.gptr()  - __rhs.eback();
-    ptrdiff_t __einp = __rhs.egptr() - __rhs.eback();
-    ptrdiff_t __nout = __rhs.pptr()  - __rhs.pbase();
-    ptrdiff_t __eout = __rhs.epptr() - __rhs.pbase();
-    ptrdiff_t __hm   = __rhs.__hm_   - __rhs.pbase();
-    __mode_ = __rhs.__mode_;
+    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
+    ptrdiff_t __binp = -1;
+    ptrdiff_t __ninp = -1;
+    ptrdiff_t __einp = -1;
+    if (__rhs.eback() != nullptr)
+    {
+        __binp = __rhs.eback() - __p;
+        __ninp = __rhs.gptr() - __p;
+        __einp = __rhs.egptr() - __p;
+    }
+    ptrdiff_t __bout = -1;
+    ptrdiff_t __nout = -1;
+    ptrdiff_t __eout = -1;
+    if (__rhs.pbase() != nullptr)
+    {
+        __bout = __rhs.pbase() - __p;
+        __nout = __rhs.pptr() - __p;
+        __eout = __rhs.epptr() - __p;
+    }
+    ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
     __str_ = _VSTD::move(__rhs.__str_);
-    char_type* __p = const_cast<char_type*>(__str_.data());
-    this->setg(__p, __p + __ninp, __p + __einp);
-    this->setp(__p, __p + __eout);
-    this->pbump(__nout);
-    __hm_ = __p + __hm;
+    __p = const_cast<char_type*>(__str_.data());
+    if (__binp != -1)
+        this->setg(__p + __binp, __p + __ninp, __p + __einp);
+    if (__bout != -1)
+    {
+        this->setp(__p + __bout, __p + __eout);
+        this->pbump(__nout);
+    }
+    __hm_ = __hm == -1 ? nullptr : __p + __hm;
+    __mode_ = __rhs.__mode_;
     __p = const_cast<char_type*>(__rhs.__str_.data());
     __rhs.setg(__p, __p, __p);
     __rhs.setp(__p, __p);
@@ -308,28 +346,74 @@ template <class _CharT, class _Traits, c
 void
 basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs)
 {
-    ptrdiff_t __rninp = __rhs.gptr()  - __rhs.eback();
-    ptrdiff_t __reinp = __rhs.egptr() - __rhs.eback();
-    ptrdiff_t __rnout = __rhs.pptr()  - __rhs.pbase();
-    ptrdiff_t __reout = __rhs.epptr() - __rhs.pbase();
-    ptrdiff_t __rhm   = __rhs.__hm_   - __rhs.pbase();
-    ptrdiff_t __lninp = this->gptr()  - this->eback();
-    ptrdiff_t __leinp = this->egptr() - this->eback();
-    ptrdiff_t __lnout = this->pptr()  - this->pbase();
-    ptrdiff_t __leout = this->epptr() - this->pbase();
-    ptrdiff_t __lhm   = this->__hm_   - this->pbase();
+    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
+    ptrdiff_t __rbinp = -1;
+    ptrdiff_t __rninp = -1;
+    ptrdiff_t __reinp = -1;
+    if (__rhs.eback() != nullptr)
+    {
+        __rbinp = __rhs.eback() - __p;
+        __rninp = __rhs.gptr() - __p;
+        __reinp = __rhs.egptr() - __p;
+    }
+    ptrdiff_t __rbout = -1;
+    ptrdiff_t __rnout = -1;
+    ptrdiff_t __reout = -1;
+    if (__rhs.pbase() != nullptr)
+    {
+        __rbout = __rhs.pbase() - __p;
+        __rnout = __rhs.pptr() - __p;
+        __reout = __rhs.epptr() - __p;
+    }
+    ptrdiff_t __rhm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
+    __p = const_cast<char_type*>(__str_.data());
+    ptrdiff_t __lbinp = -1;
+    ptrdiff_t __lninp = -1;
+    ptrdiff_t __leinp = -1;
+    if (this->eback() != nullptr)
+    {
+        __lbinp = this->eback() - __p;
+        __lninp = this->gptr() - __p;
+        __leinp = this->egptr() - __p;
+    }
+    ptrdiff_t __lbout = -1;
+    ptrdiff_t __lnout = -1;
+    ptrdiff_t __leout = -1;
+    if (this->pbase() != nullptr)
+    {
+        __lbout = this->pbase() - __p;
+        __lnout = this->pptr() - __p;
+        __leout = this->epptr() - __p;
+    }
+    ptrdiff_t __lhm = __hm_ == nullptr ? -1 : __hm_ - __p;
     _VSTD::swap(__mode_, __rhs.__mode_);
     __str_.swap(__rhs.__str_);
-    char_type* __p = const_cast<char_type*>(__str_.data());
-    this->setg(__p, __p + __rninp, __p + __reinp);
-    this->setp(__p, __p + __reout);
-    this->pbump(__rnout);
-    __hm_ = __p + __rhm;
+    __p = const_cast<char_type*>(__str_.data());
+    if (__rbinp != -1)
+        this->setg(__p + __rbinp, __p + __rninp, __p + __reinp);
+    else
+        this->setg(nullptr, nullptr, nullptr);
+    if (__rbout != -1)
+    {
+        this->setp(__p + __rbout, __p + __reout);
+        this->pbump(__rnout);
+    }
+    else
+        this->setp(nullptr, nullptr);
+    __hm_ = __rhm == -1 ? nullptr : __p + __rhm;
     __p = const_cast<char_type*>(__rhs.__str_.data());
-    __rhs.setg(__p, __p + __lninp, __p + __leinp);
-    __rhs.setp(__p, __p + __leout);
-    __rhs.pbump(__lnout);
-    __rhs.__hm_ = __p + __lhm;
+    if (__lbinp != -1)
+        __rhs.setg(__p + __lbinp, __p + __lninp, __p + __leinp);
+    else
+        __rhs.setg(nullptr, nullptr, nullptr);
+    if (__lbout != -1)
+    {
+        __rhs.setp(__p + __lbout, __p + __leout);
+        __rhs.pbump(__lnout);
+    }
+    else
+        __rhs.setp(nullptr, nullptr);
+    __rhs.__hm_ = __lhm == -1 ? nullptr : __p + __lhm;
     locale __tl = __rhs.getloc();
     __rhs.pubimbue(this->getloc());
     this->pubimbue(__tl);

Added: libcxx/trunk/test/input.output/string.streams/stringstream.cons/move2.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/input.output/string.streams/stringstream.cons/move2.pass.cpp?rev=178690&view=auto
==============================================================================
--- libcxx/trunk/test/input.output/string.streams/stringstream.cons/move2.pass.cpp (added)
+++ libcxx/trunk/test/input.output/string.streams/stringstream.cons/move2.pass.cpp Wed Apr  3 15:21:29 2013
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <sstream>
+
+// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+// class basic_stringstream
+
+// basic_stringstream(basic_stringstream&& rhs);
+
+#include <sstream>
+#include <vector>
+#include <string>
+#include <cassert>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    std::vector<std::istringstream> vecis;
+    vecis.push_back(std::istringstream());
+    vecis.back().str("hub started at [00 6b 8b 45 69]");
+    vecis.push_back(std::istringstream());
+    vecis.back().str("hub started at [00 6b 8b 45 69]");
+    for (int n = 0; n < vecis.size(); n++)
+    {
+        assert(vecis[n].str().size() == 31);
+        vecis[n].seekg(0, std::ios_base::beg);
+        assert(vecis[n].str().size() == 31);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}





More information about the cfe-commits mailing list