This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[PATCH] Fix backwards compatibility problem in libstdc++
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Paolo Carlini <pcarlini at suse dot de>, Benjamin Kosnik <bkoz at redhat dot com>
- Cc: libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Fri, 13 Oct 2006 12:53:26 -0400
- Subject: [PATCH] Fix backwards compatibility problem in libstdc++
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
It seems the
http://gcc.gnu.org/ml/libstdc++/2004-10/msg00394.html
changes broke libstdc++ backwards compatibility, some GCC 3.4.x compiled
programs and/or libraries misbehave with GCC 4.0.x and later libstdc++.so.6.
The problem is if some 3.4.x program/library has an inlined copy of
_S_construct or _M_clone (that means it initializes _M_length and
_M_refdata's last char, but not _M_refcount) and calls out of line
_S_create (which in GCC 3.4.x used to clear _M_refcount, but after
the above patch it no longer does), then _M_refcount is uninitialized.
When running 3.4.x code against 3.4.x libstdc++ or 4.[01].x code against
4.[01].x libstdc++ there is no problem, in the first case _M_refcount
is initialized in _S_create, in the latter in _S_construct/_M_clone that
call it.
I'm afraid the only safe fix is now to clear _M_refcount in _S_create
in addition to clearing it in its callers (well, it is just one int/long
store, so it shouldn't slow things that much).
Ok for trunk/4.1/4.0?
2006-10-13 Jakub Jelinek <jakub@redhat.com>
* include/bits/basic_string.tcc (_Rep::_S_create): Call
_M_set_sharable() for backwards compatibility.
--- libstdc++-v3/include/bits/basic_string.tcc.jj 2006-10-05 00:28:47.000000000 +0200
+++ libstdc++-v3/include/bits/basic_string.tcc 2006-10-13 17:50:53.000000000 +0200
@@ -588,6 +588,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
_Rep *__p = new (__place) _Rep;
__p->_M_capacity = __capacity;
+ // ABI compatibility - 3.4.x set in _S_create both
+ // _M_refcount and _M_length. All callers of _S_create
+ // in basic_string.tcc then set just _M_length.
+ // In 4.0.x and later both _M_refcount and _M_length
+ // are initialized in the callers, unfortunately we can
+ // have 3.4.x compiled code with _S_create callers inlined
+ // calling 4.0.x+ _S_create.
+ __p->_M_set_sharable();
return __p;
}
Jakub