This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: libstdc++/4354
- To: bagnara at cs dot unipr dot it, gcc-gnats at gcc dot gnu dot org, gcc-prs at gcc dot gnu dot org, ncm at cantrip dot org, pcarlini at unitus dot it, gcc-bugs at gcc dot gnu dot org, nobody at gcc dot gnu dot org
- Subject: Re: libstdc++/4354
- From: Paolo Carlini <pcarlini at unitus dot it>
- Date: Fri, 28 Sep 2001 12:57:39 +0200
In the meanwhile I cross checked on the comp.std.c++ list that indeed we are
dealing with a regression wrt libstdc++-v2
But reference counting issues (basic_string class is COW) prevents from working
a solution involving the swap of the aforementioned calls whenever *this is
shared.
On the other hand, the following simple patch seems to robustly solve the
problem with basic_string::assign (and its siblings involving overlapping ranges
for basic_string::replace), at the cost of an additional temporary string.
The patch has been tested with no regressions on x86, deals correctly with
Roberto's testcase and variants of it and moreover basic_string::replace now
does the right thing in case of overlapping ranges:
--- basic_string.tcc.orig Sun Sep 23 16:56:21 2001
+++ basic_string.tcc Sun Sep 23 17:00:11 2001
@@ -453,10 +453,14 @@
if (__dmax <= __dnew)
__throw_length_error("basic_string::_M_replace");
size_type __off = __i1 - _M_ibegin();
+ // Save concerned source string data in a temporary
+ const basic_string __temp = basic_string(__k1, __k2);
_M_mutate(__off, __dold, __dnew);
- // Invalidated __i1, __i2
+ // Invalidated __i1, __i2 (and clobbered original source string
+ // data when destination string == source string and the string
+ // is unshared)
if (__dnew)
- _S_copy_chars(_M_data() + __off, __k1, __k2);
+ _S_copy_chars(_M_data() + __off, __temp.begin(), __temp.end());
return *this;
}
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=4354&database=gcc