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.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@178690 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cf31d3864e
commit
4aa8b06e67
164
include/sstream
164
include/sstream
@ -260,17 +260,36 @@ template <class _CharT, class _Traits, class _Allocator>
|
||||
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, class _Allocator>
|
||||
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, class _Allocator>
|
||||
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);
|
||||
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user