re PR libstdc++/42832 (Revisit std::function for aliasing issues and efficiency)
authorRichard Guenther <rguenther@suse.de>
Wed, 27 Jan 2010 15:49:00 +0000 (15:49 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 27 Jan 2010 15:49:00 +0000 (15:49 +0000)
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.

From-SVN: r156290

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/functional
libstdc++-v3/include/tr1/functional

index 4e5adf75e48524c1fb574eb76d86a729ee0a0dde..25cda7e571b03d38eca07fff3a57a69d7b09a7a9 100644 (file)
@@ -1,3 +1,10 @@
+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.
+
 2010-01-27  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
        * config/abi/pre/gnu.ver: Avoid time_get pattern conflicts.
index 29b19f67d0f8aab0e0b8b31a8322e53d32f13523..c390c3bbdcd51f745a188605fc00f4cee6e90517 100644 (file)
@@ -1940,9 +1940,16 @@ namespace std
        */
       void swap(function& __x)
       {
-       _Any_data __old_functor = _M_functor;
-       _M_functor = __x._M_functor;
-       __x._M_functor = __old_functor;
+       /* 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 4825509aed79ced7de8d60417028514088a4d23f..2052f885de8851f05b48fbfd82e88922312ad6d3 100644 (file)
@@ -1904,9 +1904,16 @@ namespace tr1
        */
       void swap(function& __x)
       {
-       _Any_data __old_functor = _M_functor;
-       _M_functor = __x._M_functor;
-       __x._M_functor = __old_functor;
+        /* 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;