Fix Bug 30240 - std::string: append(first, last) error when aliasing. Add test cases for append/insert/assign/replace while we're at it, and fix a similar bug in insert.
llvm-svn: 280643
This commit is contained in:
parent
e9dd46f4d0
commit
7e1a23001d
@ -1998,7 +1998,7 @@ typename enable_if
|
|||||||
>::type
|
>::type
|
||||||
basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
|
basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
|
||||||
{
|
{
|
||||||
basic_string __temp(__first, __last, __alloc());
|
const basic_string __temp(__first, __last, __alloc());
|
||||||
assign(__temp.data(), __temp.size());
|
assign(__temp.data(), __temp.size());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -2151,11 +2151,17 @@ typename enable_if
|
|||||||
>::type
|
>::type
|
||||||
basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last)
|
basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last)
|
||||||
{
|
{
|
||||||
basic_string __temp (__first, __last, __alloc());
|
const basic_string __temp (__first, __last, __alloc());
|
||||||
append(__temp.data(), __temp.size());
|
append(__temp.data(), __temp.size());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename _Tp>
|
||||||
|
bool __ptr_in_range (const _Tp* __p, const _Tp* __first, const _Tp* __last)
|
||||||
|
{
|
||||||
|
return __first <= __p && __p < __last;
|
||||||
|
}
|
||||||
|
|
||||||
template <class _CharT, class _Traits, class _Allocator>
|
template <class _CharT, class _Traits, class _Allocator>
|
||||||
template<class _ForwardIterator>
|
template<class _ForwardIterator>
|
||||||
typename enable_if
|
typename enable_if
|
||||||
@ -2171,13 +2177,21 @@ basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _For
|
|||||||
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
||||||
if (__n)
|
if (__n)
|
||||||
{
|
{
|
||||||
if (__cap - __sz < __n)
|
if ( __ptr_in_range(&*__first, data(), data() + size()))
|
||||||
__grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
|
{
|
||||||
pointer __p = __get_pointer() + __sz;
|
const basic_string __temp (__first, __last, __alloc());
|
||||||
for (; __first != __last; ++__p, ++__first)
|
append(__temp.data(), __temp.size());
|
||||||
traits_type::assign(*__p, *__first);
|
}
|
||||||
traits_type::assign(*__p, value_type());
|
else
|
||||||
__set_size(__sz + __n);
|
{
|
||||||
|
if (__cap - __sz < __n)
|
||||||
|
__grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
|
||||||
|
pointer __p = __get_pointer() + __sz;
|
||||||
|
for (; __first != __last; ++__p, ++__first)
|
||||||
|
traits_type::assign(*__p, *__first);
|
||||||
|
traits_type::assign(*__p, value_type());
|
||||||
|
__set_size(__sz + __n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -2299,7 +2313,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIt
|
|||||||
"string::insert(iterator, range) called with an iterator not"
|
"string::insert(iterator, range) called with an iterator not"
|
||||||
" referring to this string");
|
" referring to this string");
|
||||||
#endif
|
#endif
|
||||||
basic_string __temp(__first, __last, __alloc());
|
const basic_string __temp(__first, __last, __alloc());
|
||||||
return insert(__pos, __temp.data(), __temp.data() + __temp.size());
|
return insert(__pos, __temp.data(), __temp.data() + __temp.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2319,11 +2333,17 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward
|
|||||||
" referring to this string");
|
" referring to this string");
|
||||||
#endif
|
#endif
|
||||||
size_type __ip = static_cast<size_type>(__pos - begin());
|
size_type __ip = static_cast<size_type>(__pos - begin());
|
||||||
size_type __sz = size();
|
|
||||||
size_type __cap = capacity();
|
|
||||||
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
|
||||||
if (__n)
|
if (__n)
|
||||||
{
|
{
|
||||||
|
if ( __ptr_in_range(&*__first, data(), data() + size()))
|
||||||
|
{
|
||||||
|
const basic_string __temp(__first, __last, __alloc());
|
||||||
|
return insert(__pos, __temp.data(), __temp.data() + __temp.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type __sz = size();
|
||||||
|
size_type __cap = capacity();
|
||||||
value_type* __p;
|
value_type* __p;
|
||||||
if (__cap - __sz >= __n)
|
if (__cap - __sz >= __n)
|
||||||
{
|
{
|
||||||
@ -2523,7 +2543,7 @@ typename enable_if
|
|||||||
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
|
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
|
||||||
_InputIterator __j1, _InputIterator __j2)
|
_InputIterator __j1, _InputIterator __j2)
|
||||||
{
|
{
|
||||||
basic_string __temp(__j1, __j2, __alloc());
|
const basic_string __temp(__j1, __j2, __alloc());
|
||||||
return this->replace(__i1, __i2, __temp);
|
return this->replace(__i1, __i2, __temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,4 +178,21 @@ int main()
|
|||||||
test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter());
|
test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ // test appending to self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.append(s_short.begin(), s_short.end());
|
||||||
|
assert(s_short == "123/123/");
|
||||||
|
s_short.append(s_short.begin(), s_short.end());
|
||||||
|
assert(s_short == "123/123/123/123/");
|
||||||
|
s_short.append(s_short.begin(), s_short.end());
|
||||||
|
assert(s_short == "123/123/123/123/123/123/123/123/");
|
||||||
|
|
||||||
|
s_long.append(s_long.begin(), s_long.end());
|
||||||
|
assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,4 +61,20 @@ int main()
|
|||||||
S("1234567890123456789012345678901234567890"));
|
S("1234567890123456789012345678901234567890"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ // test appending to self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.append(s_short.c_str());
|
||||||
|
assert(s_short == "123/123/");
|
||||||
|
s_short.append(s_short.c_str());
|
||||||
|
assert(s_short == "123/123/123/123/");
|
||||||
|
s_short.append(s_short.c_str());
|
||||||
|
assert(s_short == "123/123/123/123/123/123/123/123/");
|
||||||
|
|
||||||
|
s_long.append(s_long.c_str());
|
||||||
|
assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,4 +70,20 @@ int main()
|
|||||||
S("1234567890123456789012345678901234567890"));
|
S("1234567890123456789012345678901234567890"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ // test appending to self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.append(s_short.data(), s_short.size());
|
||||||
|
assert(s_short == "123/123/");
|
||||||
|
s_short.append(s_short.data(), s_short.size());
|
||||||
|
assert(s_short == "123/123/123/123/");
|
||||||
|
s_short.append(s_short.data(), s_short.size());
|
||||||
|
assert(s_short == "123/123/123/123/123/123/123/123/");
|
||||||
|
|
||||||
|
s_long.append(s_long.data(), s_long.size());
|
||||||
|
assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,4 +179,21 @@ int main()
|
|||||||
test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter());
|
test_exceptions(S(), TIter(s, s+10, 6, TIter::TAComparison), TIter());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ // test assigning to self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.assign(s_short.begin(), s_short.end());
|
||||||
|
assert(s_short == "123/");
|
||||||
|
s_short.assign(s_short.begin() + 2, s_short.end());
|
||||||
|
assert(s_short == "3/");
|
||||||
|
|
||||||
|
s_long.assign(s_long.begin(), s_long.end());
|
||||||
|
assert(s_long == "Lorem ipsum dolor sit amet, consectetur/");
|
||||||
|
|
||||||
|
s_long.assign(s_long.begin() + 30, s_long.end());
|
||||||
|
assert(s_long == "nsectetur/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,4 +61,18 @@ int main()
|
|||||||
S("12345678901234567890"));
|
S("12345678901234567890"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ // test assignment to self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.assign(s_short.c_str());
|
||||||
|
assert(s_short == "123/");
|
||||||
|
s_short.assign(s_short.c_str() + 2);
|
||||||
|
assert(s_short == "3/");
|
||||||
|
|
||||||
|
s_long.assign(s_long.c_str() + 30);
|
||||||
|
assert(s_long == "nsectetur/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,4 +70,20 @@ int main()
|
|||||||
S("12345678901234567890"));
|
S("12345678901234567890"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
{ // test assign to self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.assign(s_short.data(), s_short.size());
|
||||||
|
assert(s_short == "123/");
|
||||||
|
s_short.assign(s_short.data() + 2, s_short.size() - 2);
|
||||||
|
assert(s_short == "3/");
|
||||||
|
|
||||||
|
s_long.assign(s_long.data(), s_long.size());
|
||||||
|
assert(s_long == "Lorem ipsum dolor sit amet, consectetur/");
|
||||||
|
|
||||||
|
s_long.assign(s_long.data() + 2, 8 );
|
||||||
|
assert(s_long == "rem ipsu");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,4 +169,21 @@ int main()
|
|||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ // test inserting into self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.insert(s_short.begin(), s_short.begin(), s_short.end());
|
||||||
|
assert(s_short == "123/123/");
|
||||||
|
s_short.insert(s_short.begin(), s_short.begin(), s_short.end());
|
||||||
|
assert(s_short == "123/123/123/123/");
|
||||||
|
s_short.insert(s_short.begin(), s_short.begin(), s_short.end());
|
||||||
|
assert(s_short == "123/123/123/123/123/123/123/123/");
|
||||||
|
|
||||||
|
s_long.insert(s_long.begin(), s_long.begin(), s_long.end());
|
||||||
|
assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -210,4 +210,20 @@ int main()
|
|||||||
test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", S("can't happen"));
|
test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", S("can't happen"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ // test inserting into self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.insert(0, s_short.c_str());
|
||||||
|
assert(s_short == "123/123/");
|
||||||
|
s_short.insert(0, s_short.c_str());
|
||||||
|
assert(s_short == "123/123/123/123/");
|
||||||
|
s_short.insert(0, s_short.c_str());
|
||||||
|
assert(s_short == "123/123/123/123/123/123/123/123/");
|
||||||
|
|
||||||
|
s_long.insert(0, s_long.c_str());
|
||||||
|
assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -691,4 +691,20 @@ int main()
|
|||||||
test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 20, S("can't happen"));
|
test(S("abcdefghijklmnopqrst"), 21, "12345678901234567890", 20, S("can't happen"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ // test inserting into self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.insert(0, s_short.data(), s_short.size());
|
||||||
|
assert(s_short == "123/123/");
|
||||||
|
s_short.insert(0, s_short.data(), s_short.size());
|
||||||
|
assert(s_short == "123/123/123/123/");
|
||||||
|
s_short.insert(0, s_short.data(), s_short.size());
|
||||||
|
assert(s_short == "123/123/123/123/123/123/123/123/");
|
||||||
|
|
||||||
|
s_long.insert(0, s_long.data(), s_long.size());
|
||||||
|
assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1007,4 +1007,20 @@ int main()
|
|||||||
test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 6, TIter::TAComparison), TIter());
|
test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 6, TIter::TAComparison), TIter());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ // test replacing into self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.replace(s_short.begin(), s_short.begin(), s_short.begin(), s_short.end());
|
||||||
|
assert(s_short == "123/123/");
|
||||||
|
s_short.replace(s_short.begin(), s_short.begin(), s_short.begin(), s_short.end());
|
||||||
|
assert(s_short == "123/123/123/123/");
|
||||||
|
s_short.replace(s_short.begin(), s_short.begin(), s_short.begin(), s_short.end());
|
||||||
|
assert(s_short == "123/123/123/123/123/123/123/123/");
|
||||||
|
|
||||||
|
s_long.replace(s_long.begin(), s_long.begin(), s_long.begin(), s_long.end());
|
||||||
|
assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,4 +282,20 @@ int main()
|
|||||||
test2<S>();
|
test2<S>();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ // test replacing into self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.replace(s_short.begin(), s_short.begin(), s_short.c_str());
|
||||||
|
assert(s_short == "123/123/");
|
||||||
|
s_short.replace(s_short.begin(), s_short.begin(), s_short.c_str());
|
||||||
|
assert(s_short == "123/123/123/123/");
|
||||||
|
s_short.replace(s_short.begin(), s_short.begin(), s_short.c_str());
|
||||||
|
assert(s_short == "123/123/123/123/123/123/123/123/");
|
||||||
|
|
||||||
|
s_long.replace(s_long.begin(), s_long.begin(), s_long.c_str());
|
||||||
|
assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -972,4 +972,20 @@ int main()
|
|||||||
test8<S>();
|
test8<S>();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ // test replacing into self
|
||||||
|
typedef std::string S;
|
||||||
|
S s_short = "123/";
|
||||||
|
S s_long = "Lorem ipsum dolor sit amet, consectetur/";
|
||||||
|
|
||||||
|
s_short.replace(s_short.begin(), s_short.begin(), s_short.data(), s_short.size());
|
||||||
|
assert(s_short == "123/123/");
|
||||||
|
s_short.replace(s_short.begin(), s_short.begin(), s_short.data(), s_short.size());
|
||||||
|
assert(s_short == "123/123/123/123/");
|
||||||
|
s_short.replace(s_short.begin(), s_short.begin(), s_short.data(), s_short.size());
|
||||||
|
assert(s_short == "123/123/123/123/123/123/123/123/");
|
||||||
|
|
||||||
|
s_long.replace(s_long.begin(), s_long.begin(), s_long.data(), s_long.size());
|
||||||
|
assert(s_long == "Lorem ipsum dolor sit amet, consectetur/Lorem ipsum dolor sit amet, consectetur/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user