Date: prev next · Thread: first prev next last
2013 Archives by date, by thread · List index


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/2166

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/66/2166/1

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.

(cherry picked from commit c91d353872b7d4e1a39192bff1444b46cab6e5eb)
Conflicts:
        config_host/config_global.h.in
...solved by resorting to the old -DHAVE_CXX11_PERFECT_FORWARDING logic spread
across various solenv/.../*.mk instead.

Change-Id: I3be22f59a8eb49d31458480c27f3ce15803c7fd4
---
M config_host.mk.in
M configure.ac
M sal/inc/rtl/allocator.hxx
M solenv/gbuild/platform/com_GCC_defs.mk
M solenv/gbuild/platform/com_MSC_defs.mk
M solenv/inc/settings.mk
6 files changed, 51 insertions(+), 0 deletions(-)



diff --git a/config_host.mk.in b/config_host.mk.in
index 73aecf8..0af569c 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -217,6 +217,7 @@
 export GUI_FOR_BUILD=@GUI_FOR_BUILD@
 export HARDLINKDELIVER=@HARDLINKDELIVER@
 export HAVE_CXX0X=@HAVE_CXX0X@
+export HAVE_CXX11_PERFECT_FORWARDING=@HAVE_CXX11_PERFECT_FORWARDING@
 export HAVE_GCC_AVX=@HAVE_GCC_AVX@
 export HAVE_GCC_BUILTIN_ATOMIC=@HAVE_GCC_BUILTIN_ATOMIC@
 export HAVE_GCC_GGDB2=@HAVE_GCC_GGDB2@
diff --git a/configure.ac b/configure.ac
index ce85229..703bb13 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5464,6 +5464,32 @@
 AC_SUBST(HAVE_GCC_BUILTIN_ATOMIC)
 
 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
+if test "$HAVE_CXX0X" = TRUE; then
+    CXXFLAGS="$CXXFLAGS -std=gnu++0x"
+fi
+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
+    HAVE_CXX11_PERFECT_FORWARDING=TRUE
+fi
+AC_SUBST([HAVE_CXX11_PERFECT_FORWARDING])
+
+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..979c743 100644
--- a/sal/inc/rtl/allocator.hxx
+++ b/sal/inc/rtl/allocator.hxx
@@ -125,10 +125,18 @@
     }
 
     //-----------------------------------------
+#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)
diff --git a/solenv/gbuild/platform/com_GCC_defs.mk b/solenv/gbuild/platform/com_GCC_defs.mk
index 437cdd3..1f50a97 100644
--- a/solenv/gbuild/platform/com_GCC_defs.mk
+++ b/solenv/gbuild/platform/com_GCC_defs.mk
@@ -58,6 +58,12 @@
        -D$(COM) \
        -DCPPU_ENV=$(gb_CPPU_ENV) \
 
+ifeq ($(HAVE_CXX11_PERFECT_FORWARDING),TRUE)
+gb_COMPILERDEFS += \
+    -DHAVE_CXX11_PERFECT_FORWARDING \
+
+endif
+
 ifeq ($(HAVE_GCC_BUILTIN_ATOMIC),TRUE)
 gb_COMPILERDEFS += \
     -DHAVE_GCC_BUILTIN_ATOMIC \
diff --git a/solenv/gbuild/platform/com_MSC_defs.mk b/solenv/gbuild/platform/com_MSC_defs.mk
index a81b5df..626274b 100644
--- a/solenv/gbuild/platform/com_MSC_defs.mk
+++ b/solenv/gbuild/platform/com_MSC_defs.mk
@@ -60,6 +60,12 @@
        -DCPPU_ENV=$(gb_CPPU_ENV) \
        -DM1500 \
 
+ifeq ($(HAVE_CXX11_PERFECT_FORWARDING),TRUE)
+gb_COMPILERDEFS += \
+    -DHAVE_CXX11_PERFECT_FORWARDING \
+
+endif
+
 gb_RCDEFS := \
         -DWINVER=0x0400 \
         -DWIN32 \
diff --git a/solenv/inc/settings.mk b/solenv/inc/settings.mk
index dbb513d..c1b6a78 100644
--- a/solenv/inc/settings.mk
+++ b/solenv/inc/settings.mk
@@ -813,6 +813,10 @@
 CDEFS+=-DTIMELOG
 .ENDIF
 
+.IF "$(HAVE_CXX11_PERFECT_FORWARDING)" == "TRUE"
+CDEFS += -DHAVE_CXX11_PERFECT_FORWARDING
+.ENDIF
+
 CDEFSCXX=
 CDEFSOBJ=
 #CDEFSMT=-DMULTITHREAD

-- 
To view, visit https://gerrit.libreoffice.org/2166
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3be22f59a8eb49d31458480c27f3ce15803c7fd4
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: libreoffice-4-0
Gerrit-Owner: Stephan Bergmann <sbergman@redhat.com>

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.