This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[PATCH] Address PR42832
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: libstdc++ at gcc dot gnu dot org
- Date: Wed, 27 Jan 2010 16:47:23 +0100 (CET)
- Subject: [PATCH] Address PR42832
This installs the agreed-upon fix for PR42832, [std/tr1]::functional::swap
operating in a very grey area by copying _M_functor which has an
unknown dynamic type via lvalues of type _Any_data. The fix is
to use lvalues of character type which would be either implementing
the swap with three memcpys or as the following patch using
bytewise std::swap.
Bootstrapped and tested on x86_64-unknown-linux-gnu, installed on trunk
as approved in the bugzilla audit-trail by Paolo.
Richard.
2010-01-27 Richard Guenther <rguenther@suse.de>
PR libstdc++/42832
* include/std/functional (function<>::swap): Perform bytewise
swap of _M_functor.
* include/tr1/functional (function<>::swap): Likewise.
Index: libstdc++-v3/include/std/functional
===================================================================
*** libstdc++-v3/include/std/functional (revision 156243)
--- libstdc++-v3/include/std/functional (working copy)
*************** namespace std
*** 1956,1964 ****
*/
void swap(function& __x)
{
! _Any_data __old_functor = _M_functor;
! _M_functor = __x._M_functor;
! __x._M_functor = __old_functor;
_Manager_type __old_manager = _M_manager;
_M_manager = __x._M_manager;
__x._M_manager = __old_manager;
--- 1956,1971 ----
*/
void swap(function& __x)
{
! /* We cannot perform direct assignments of the _M_functor
! parts as they are of type _Any_data and have a different
! dynamic type. Doing so would violate type-based aliasing
! rules and lead to spurious miscompilations.
! Instead perform a bytewise exchange of the memory of
! both POD objects.
! ??? A wordwise exchange honoring alignment of _M_functor
! would be more efficient. See PR42845. */
! for (unsigned i = 0; i < sizeof (_M_functor._M_pod_data); ++i)
! std::swap (_M_functor._M_pod_data[i], __x._M_functor._M_pod_data[i]);
_Manager_type __old_manager = _M_manager;
_M_manager = __x._M_manager;
__x._M_manager = __old_manager;
Index: libstdc++-v3/include/tr1/functional
===================================================================
*** libstdc++-v3/include/tr1/functional (revision 156243)
--- libstdc++-v3/include/tr1/functional (working copy)
*************** namespace tr1
*** 1904,1912 ****
*/
void swap(function& __x)
{
! _Any_data __old_functor = _M_functor;
! _M_functor = __x._M_functor;
! __x._M_functor = __old_functor;
_Manager_type __old_manager = _M_manager;
_M_manager = __x._M_manager;
__x._M_manager = __old_manager;
--- 1904,1919 ----
*/
void swap(function& __x)
{
! /* We cannot perform direct assignments of the _M_functor
! parts as they are of type _Any_data and have a different
! dynamic type. Doing so would violate type-based aliasing
! rules and lead to spurious miscompilations.
! Instead perform a bytewise exchange of the memory of
! both POD objects.
! ??? A wordwise exchange honoring alignment of _M_functor
! would be more efficient. See PR42845. */
! for (unsigned i = 0; i < sizeof (_M_functor._M_pod_data); ++i)
! std::swap (_M_functor._M_pod_data[i], __x._M_functor._M_pod_data[i]);
_Manager_type __old_manager = _M_manager;
_M_manager = __x._M_manager;
__x._M_manager = __old_manager;