[Libreoffice-commits] core.git: config_host/config_global.h.in configure.ac sal/inc

Stephan Bergmann sbergman at redhat.com
Thu Feb 14 06:55:35 PST 2013


 config_host/config_global.h.in |    1 +
 configure.ac                   |   23 +++++++++++++++++++++++
 sal/inc/rtl/allocator.hxx      |   12 ++++++++++++
 3 files changed, 36 insertions(+)

New commits:
commit c91d353872b7d4e1a39192bff1444b46cab6e5eb
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Thu Feb 14 15:21:46 2013 +0100

    rhbz#908674: Adapt rtl::Allocator::construct to C++11
    
    ...otherwise, at least with some --with-system-boost versions and C++11
    compilers, like with Fedora's boost-1.50.0-4.fc18.x86_64 and
    gcc-c++-4.7.2-8.fc18.x86_64, using this to copy-construct an instance of
    boost::unordered::detail::ptr_node<std::pair<rtl::OUString,Bootstrap_Impl*>> in
    the call to p_bootstrap_map->insert(...) in rtl_bootstrap_args_open
    (sal/rtl/source/bootstrap.cxx) would memcopy the ptr_node and fail to call
    rtl_uString_acquire, leading to memory corruption later on when
    rtl_uString_release is called one time too often.
    
    It is not entirely clear to me whether this is a shortcoming of the given Boost
    version, but this patch solves the problem and brings rtl::Allocator::construct
    in line with the (changed) Allocator requirements of C++11 anyway.
    
    The problem potentially lurks with every use of rtl::Allocator, but only showed
    now begining with LO 4.0 where e5111574fd904b38a3980ca4ea3d21cfcb22dea6 "Revert
    'sb140: sb140: #i116981# clean up memory upon exit'" re-introduced code into
    rtl_bootstrap_args_open that inserts into a boost::unordered_map that uses
    rtl::Allocator.
    
    Change-Id: I3be22f59a8eb49d31458480c27f3ce15803c7fd4

diff --git a/config_host/config_global.h.in b/config_host/config_global.h.in
index 0f85b59..5e7150b 100644
--- a/config_host/config_global.h.in
+++ b/config_host/config_global.h.in
@@ -14,6 +14,7 @@ Any change in this header will cause a rebuild of almost everything.
 
 #undef HAVE_CXX11_DELETE
 #undef HAVE_CXX11_OVERRIDE
+#undef HAVE_CXX11_PERFECT_FORWARDING
 #undef HAVE_GCC_BUILTIN_ATOMIC
 #undef HAVE_SFINAE_ANONYMOUS_BROKEN
 #undef HAVE_THREADSAFE_STATICS
diff --git a/configure.ac b/configure.ac
index a23e8d4..1061507 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5786,6 +5786,29 @@ else
 fi
 
 dnl ===================================================================
+dnl Check for C++11 perfect forwarding support
+dnl ===================================================================
+HAVE_CXX11_PERFECT_FORWARDING=
+AC_MSG_CHECKING([whether $CXX supports C++11 perfect forwarding])
+save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$CXXFLAGS $CXXFLAGS_CXX11"
+AC_LANG_PUSH([C++])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+        #include <utility>
+        template<typename T, typename... Args> T * f(Args &&... v) {
+            return new T(std::forward<Args>(v)...);
+        }
+    ]], [[
+        f<int>(0);
+    ]])], [perfect_forwarding=yes], [perfect_forwarding=no])
+AC_LANG_POP([C++])
+CXXFLAGS=$save_CXXFLAGS
+AC_MSG_RESULT([$perfect_forwarding])
+if test "$perfect_forwarding" = yes; then
+    AC_DEFINE([HAVE_CXX11_PERFECT_FORWARDING])
+fi
+
+dnl ===================================================================
 dnl system stl sanity tests
 dnl ===================================================================
 HAVE_GCC_VISIBILITY_BROKEN=
diff --git a/sal/inc/rtl/allocator.hxx b/sal/inc/rtl/allocator.hxx
index 4900d97..a70abff 100644
--- a/sal/inc/rtl/allocator.hxx
+++ b/sal/inc/rtl/allocator.hxx
@@ -23,6 +23,10 @@
 #include "rtl/alloc.h"
 #include <cstddef>
 
+#if defined LIBO_INTERNAL_ONLY
+#include "config_global.h"
+#endif
+
 /// @cond INTERNAL
 
 //######################################################
@@ -125,10 +129,18 @@ public:
     }
 
     //-----------------------------------------
+#if defined HAVE_CXX11_PERFECT_FORWARDING
+    template< typename... Args >
+    void construct (pointer p, Args &&... value)
+    {
+        new ((void*)p)T(std::forward< Args >(value)...);
+    }
+#else
     void construct (pointer p, const T& value)
     {
         new ((void*)p)T(value);
     }
+#endif
 
     //-----------------------------------------
     void destroy (pointer p)


More information about the Libreoffice-commits mailing list