[PATCH libreoffice-3-6] rhbz#908674: Adapt rtl::Allocator::construct to C++11

Stephan Bergmann (via Code Review) gerrit at gerrit.libreoffice.org
Fri Feb 15 04:04:07 PST 2013


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/2167

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/67/2167/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.

(cherry picked from commit https://gerrit.libreoffice.org/#/c/2166/1)
Conflicts:
	configure.ac
	solenv/gbuild/platform/com_GCC_defs.mk
	solenv/gbuild/platform/com_MSC_defs.mk

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



diff --git a/config_host.mk.in b/config_host.mk.in
index 4fb80d1..27f260e 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -196,6 +196,7 @@
 export GUI_FOR_BUILD=@GUI_FOR_BUILD@
 export GXX_INCLUDE_PATH=@GXX_INCLUDE_PATH@
 export HAVE_CXX0X=@HAVE_CXX0X@
+export HAVE_CXX11_PERFECT_FORWARDING=@HAVE_CXX11_PERFECT_FORWARDING@
 export HAVE_GCC_AVX=@HAVE_GCC_AVX@
 export HAVE_GCC_GGDB2=@HAVE_GCC_GGDB2@
 export HAVE_GCC_FINLINE_LIMIT=@HAVE_GCC_FINLINE_LIMIT@
diff --git a/configure.in b/configure.in
index e81566e..071380a 100644
--- a/configure.in
+++ b/configure.in
@@ -4781,6 +4781,32 @@
 AC_SUBST(HAVE_GCC_AVX)
 
 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 36bbd00..10f298a 100644
--- a/sal/inc/rtl/allocator.hxx
+++ b/sal/inc/rtl/allocator.hxx
@@ -139,10 +139,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 60ae0c3..58d8b29 100644
--- a/solenv/gbuild/platform/com_GCC_defs.mk
+++ b/solenv/gbuild/platform/com_GCC_defs.mk
@@ -57,6 +57,12 @@
 	-DCPPU_ENV=gcc3 \
 	-DGXX_INCLUDE_PATH=$(GXX_INCLUDE_PATH) \
 
+ifeq ($(HAVE_CXX11_PERFECT_FORWARDING),TRUE)
+gb_COMPILERDEFS += \
+    -DHAVE_CXX11_PERFECT_FORWARDING \
+
+endif
+
 gb_CFLAGS_COMMON := \
 	-Wall \
 	-Wendif-labels \
diff --git a/solenv/inc/settings.mk b/solenv/inc/settings.mk
index ea4bb0e..2f940f8 100644
--- a/solenv/inc/settings.mk
+++ b/solenv/inc/settings.mk
@@ -815,6 +815,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/2167
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3be22f59a8eb49d31458480c27f3ce15803c7fd4
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: libreoffice-3-6
Gerrit-Owner: Stephan Bergmann <sbergman at redhat.com>


More information about the LibreOffice mailing list