[PATCH] Prevent __uses_alloc from holding dangling references
Jonathan Wakely
jwakely@redhat.com
Thu Jul 6 11:58:00 GMT 2017
The polymorphic_allocator::construct functions create dangling
pointers to rvalues of type memory_resource* and then dereference
them, leading to undefined behaviour.
This fixes those functions to use lvalues, and then adds a deleted
overload of __use_alloc to prevent this happening again.
This means __use_alloc can't be used like:
f( __use_alloc<T, Alloc>(c.get_allocator()) );
because get_allocator() returns an rvalue, but it's an internal-only
helper and we can just do this instead:
auto alloc = c.get_allocator();
f( __use_alloc<T, Alloc>(alloc) );
* include/bits/uses_allocator.h (__use_alloc(const _Alloc&&)): Add
deleted overload to prevent dangling references to rvalues.
* include/experimental/memory_resource
(polymorphic_allocator::construct): Do not call __use_alloc with
rvalue arguments.
Tested powerpc64le-linux, committed to trunk.
-------------- next part --------------
commit 072946c11b40cb13f709cb31ff5ef4a998d41f96
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu Jul 6 12:22:49 2017 +0100
Prevent __uses_alloc from holding dangling references
* include/bits/uses_allocator.h (__use_alloc(const _Alloc&&)): Add
deleted overload to prevent dangling references to rvalues.
* include/experimental/memory_resource
(polymorphic_allocator::construct): Do not call __use_alloc with
rvalue arguments.
diff --git a/libstdc++-v3/include/bits/uses_allocator.h b/libstdc++-v3/include/bits/uses_allocator.h
index 89d4e43..4d60716 100644
--- a/libstdc++-v3/include/bits/uses_allocator.h
+++ b/libstdc++-v3/include/bits/uses_allocator.h
@@ -109,6 +109,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__ret._M_a = std::__addressof(__a);
return __ret;
}
+
+ template<typename _Tp, typename _Alloc, typename... _Args>
+ void
+ __use_alloc(const _Alloc&&) = delete;
+
#if __cplusplus > 201402L
template <typename _Tp, typename _Alloc>
inline constexpr bool uses_allocator_v =
diff --git a/libstdc++-v3/include/experimental/memory_resource b/libstdc++-v3/include/experimental/memory_resource
index 653189c..99ace7a 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -168,8 +168,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template <typename _Tp1, typename... _Args> //used here
void construct(_Tp1* __p, _Args&&... __args)
{
- auto __use_tag = __use_alloc<_Tp1, memory_resource*,
- _Args...>(this->resource());
+ memory_resource* const __resource = this->resource();
+ auto __use_tag
+ = __use_alloc<_Tp1, memory_resource*, _Args...>(__resource);
_M_construct(__use_tag, __p, std::forward<_Args>(__args)...);
}
@@ -180,10 +181,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
tuple<_Args1...> __x,
tuple<_Args2...> __y)
{
+ memory_resource* const __resource = this->resource();
auto __x_use_tag =
- __use_alloc<_Tp1, memory_resource*, _Args1...>(this->resource());
+ __use_alloc<_Tp1, memory_resource*, _Args1...>(__resource);
auto __y_use_tag =
- __use_alloc<_Tp2, memory_resource*, _Args2...>(this->resource());
+ __use_alloc<_Tp2, memory_resource*, _Args2...>(__resource);
::new(__p) std::pair<_Tp1, _Tp2>(piecewise_construct,
_M_construct_p(__x_use_tag, __x),
More information about the Libstdc++
mailing list