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 <sberg...@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) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits