diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2015-05-27 12:18:37 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2015-05-27 12:18:37 +0100 |
commit | 2097b5b029851d531a1424a0092992d4c9f650e4 (patch) | |
tree | 96e7e2ca94b197e4d0a70f538b776fe1cbb86b64 /libstdc++-v3 | |
parent | b1af7da61278d2c4ae7b7f56fad37723461031cb (diff) | |
download | gcc-2097b5b029851d531a1424a0092992d4c9f650e4.zip gcc-2097b5b029851d531a1424a0092992d4c9f650e4.tar.gz gcc-2097b5b029851d531a1424a0092992d4c9f650e4.tar.bz2 |
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
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 13 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_tree.h | 26 | ||||
-rw-r--r-- | libstdc++-v3/include/ext/aligned_buffer.h | 41 | ||||
-rw-r--r-- | libstdc++-v3/python/libstdcxx/v6/printers.py | 7 |
4 files changed, 66 insertions, 21 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index fa3963d..1e5b30c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -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 diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index 5ca8e28..d39042f 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -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 diff --git a/libstdc++-v3/include/ext/aligned_buffer.h b/libstdc++-v3/include/ext/aligned_buffer.h index 01f5729..d023bc1 100644 --- a/libstdc++-v3/include/ext/aligned_buffer.h +++ b/libstdc++-v3/include/ext/aligned_buffer.h @@ -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> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index c6f96d7..2b6e409 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -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: |