+2015-05-27 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/66017
+ * include/bits/stl_tree.h (_Rb_tree_node): Use __aligned_membuf.
+ (_Rb_tree_iterator, _Rb_tree_const_iterator): Support construction
+ from _Base_ptr.
+ (_Rb_tree_const_iterator::_M_const_cast): Remove static_cast.
+ (_Rb_tree::begin, _Rb_tree::end): Remove static_cast.
+ * include/ext/aligned_buffer.h (__aligned_membuf): New type using
+ alignment of _Tp as a member subobject, not as a complete object.
+ * python/libstdcxx/v6/printers.py (StdRbtreeIteratorPrinter): Lookup
+ _Link_type manually as it might not be in the debug info.
+
2015-05-26 Doug Evans <dje@google.com>
* python/libstdcxx/v6/xmethods.py (UniquePtrMethodsMatcher): Add
_M_valptr() const
{ return std::__addressof(_M_value_field); }
#else
- __gnu_cxx::__aligned_buffer<_Val> _M_storage;
+ __gnu_cxx::__aligned_membuf<_Val> _M_storage;
_Val*
_M_valptr()
: _M_node() { }
explicit
- _Rb_tree_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT
+ _Rb_tree_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT
: _M_node(__x) { }
reference
: _M_node() { }
explicit
- _Rb_tree_const_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT
+ _Rb_tree_const_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT
: _M_node(__x) { }
_Rb_tree_const_iterator(const iterator& __it) _GLIBCXX_NOEXCEPT
iterator
_M_const_cast() const _GLIBCXX_NOEXCEPT
- { return iterator(static_cast<typename iterator::_Link_type>
- (const_cast<typename iterator::_Base_ptr>(_M_node))); }
+ { return iterator(const_cast<typename iterator::_Base_ptr>(_M_node)); }
reference
operator*() const _GLIBCXX_NOEXCEPT
iterator
begin() _GLIBCXX_NOEXCEPT
- {
- return iterator(static_cast<_Link_type>
- (this->_M_impl._M_header._M_left));
- }
+ { return iterator(this->_M_impl._M_header._M_left); }
const_iterator
begin() const _GLIBCXX_NOEXCEPT
- {
- return const_iterator(static_cast<_Const_Link_type>
- (this->_M_impl._M_header._M_left));
- }
+ { return const_iterator(this->_M_impl._M_header._M_left); }
iterator
end() _GLIBCXX_NOEXCEPT
- { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); }
+ { return iterator(&this->_M_impl._M_header); }
const_iterator
end() const _GLIBCXX_NOEXCEPT
- {
- return const_iterator(static_cast<_Const_Link_type>
- (&this->_M_impl._M_header));
- }
+ { return const_iterator(&this->_M_impl._M_header); }
reverse_iterator
rbegin() _GLIBCXX_NOEXCEPT
namespace __gnu_cxx
{
+ // A utility type containing a POD object that can hold an object of type
+ // _Tp initialized via placement new or allocator_traits::construct.
+ // Intended for use as a data member subobject, use __aligned_buffer for
+ // complete objects.
+ template<typename _Tp>
+ struct __aligned_membuf
+ {
+ // Target macro ADJUST_FIELD_ALIGN can produce different alignment for
+ // types when used as class members. __aligned_membuf is intended
+ // for use as a class member, so align the buffer as for a class member.
+ struct _Tp2 { _Tp _M_t; };
+
+ alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)];
+
+ __aligned_membuf() = default;
+
+ // Can be used to avoid value-initialization zeroing _M_storage.
+ __aligned_membuf(std::nullptr_t) { }
+
+ void*
+ _M_addr() noexcept
+ { return static_cast<void*>(&_M_storage); }
+
+ const void*
+ _M_addr() const noexcept
+ { return static_cast<const void*>(&_M_storage); }
+
+ _Tp*
+ _M_ptr() noexcept
+ { return static_cast<_Tp*>(_M_addr()); }
+
+ const _Tp*
+ _M_ptr() const noexcept
+ { return static_cast<const _Tp*>(_M_addr()); }
+ };
+
+ // Similar to __aligned_membuf but aligned for complete objects, not members.
+ // This type is used in <forward_list>, <future>, <bits/shared_ptr_base.h>
+ // and <bits/hashtable_policy.h>, but ideally they would use __aligned_membuf
+ // instead, as it has smaller size for some types on some targets.
+ // This type is still used to avoid an ABI change.
template<typename _Tp>
struct __aligned_buffer
: std::aligned_storage<sizeof(_Tp), std::alignment_of<_Tp>::value>
def __init__ (self, typename, val):
self.val = val
+ valtype = self.val.type.template_argument(0).strip_typedefs()
+ nodetype = gdb.lookup_type('std::_Rb_tree_node<' + str(valtype) + '>')
+ self.link_type = nodetype.strip_typedefs().pointer()
def to_string (self):
- typename = str(self.val.type.strip_typedefs()) + '::_Link_type'
- nodetype = gdb.lookup_type(typename).strip_typedefs()
- node = self.val.cast(nodetype).dereference()
+ node = self.val['_M_node'].cast(self.link_type).dereference()
return get_value_from_Rb_tree_node(node)
class StdDebugIteratorPrinter: