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
This commit is contained in:
parent
bc96a84370
commit
c91d353872
@ -14,6 +14,7 @@ Any change in this header will cause a rebuild of almost everything.
|
|||||||
|
|
||||||
#undef HAVE_CXX11_DELETE
|
#undef HAVE_CXX11_DELETE
|
||||||
#undef HAVE_CXX11_OVERRIDE
|
#undef HAVE_CXX11_OVERRIDE
|
||||||
|
#undef HAVE_CXX11_PERFECT_FORWARDING
|
||||||
#undef HAVE_GCC_BUILTIN_ATOMIC
|
#undef HAVE_GCC_BUILTIN_ATOMIC
|
||||||
#undef HAVE_SFINAE_ANONYMOUS_BROKEN
|
#undef HAVE_SFINAE_ANONYMOUS_BROKEN
|
||||||
#undef HAVE_THREADSAFE_STATICS
|
#undef HAVE_THREADSAFE_STATICS
|
||||||
|
23
configure.ac
23
configure.ac
@ -5785,6 +5785,29 @@ else
|
|||||||
AC_MSG_RESULT([no (C++11 disabled)])
|
AC_MSG_RESULT([no (C++11 disabled)])
|
||||||
fi
|
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 ===================================================================
|
||||||
dnl system stl sanity tests
|
dnl system stl sanity tests
|
||||||
dnl ===================================================================
|
dnl ===================================================================
|
||||||
|
@ -23,6 +23,10 @@
|
|||||||
#include "rtl/alloc.h"
|
#include "rtl/alloc.h"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if defined LIBO_INTERNAL_ONLY
|
||||||
|
#include "config_global.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @cond INTERNAL
|
/// @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)
|
void construct (pointer p, const T& value)
|
||||||
{
|
{
|
||||||
new ((void*)p)T(value);
|
new ((void*)p)T(value);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------
|
//-----------------------------------------
|
||||||
void destroy (pointer p)
|
void destroy (pointer p)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user