Paolo Carlini
Fri Sep 28 03:57:00 GMT 2001

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

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)
        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;

More information about the Gcc-bugs mailing list