re PR libstdc++/66017 (Undefined behaviour in std::set<long long>)
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. From-SVN: r223745
This commit is contained in:
parent
b1af7da612
commit
2097b5b029
4 changed files with 66 additions and 21 deletions
|
@ -1,3 +1,16 @@
|
|||
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
|
||||
|
|
|
@ -146,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_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()
|
||||
|
@ -188,7 +188,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
: _M_node() { }
|
||||
|
||||
explicit
|
||||
_Rb_tree_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT
|
||||
_Rb_tree_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT
|
||||
: _M_node(__x) { }
|
||||
|
||||
reference
|
||||
|
@ -260,7 +260,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
: _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
|
||||
|
@ -268,8 +268,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
|
||||
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
|
||||
|
@ -868,28 +867,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
|
||||
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
|
||||
|
|
|
@ -39,6 +39,47 @@
|
|||
|
||||
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>
|
||||
|
|
|
@ -456,11 +456,12 @@ class StdRbtreeIteratorPrinter:
|
|||
|
||||
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:
|
||||
|
|
Loading…
Add table
Reference in a new issue