[PATCH] Address PR42832

Richard Guenther rguenther@suse.de
Wed Jan 27 15:59:00 GMT 2010


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;



More information about the Gcc-patches mailing list