re PR libstdc++/66017 (Undefined behaviour in std::set<long long>)
authorJonathan Wakely <jwakely@redhat.com>
Wed, 27 May 2015 11:18:37 +0000 (12:18 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 27 May 2015 11:18:37 +0000 (12:18 +0100)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_tree.h
libstdc++-v3/include/ext/aligned_buffer.h
libstdc++-v3/python/libstdcxx/v6/printers.py

index fa3963d1998997ba4ffb7df7d40c7f19c9acc2a6..1e5b30c8aacc795aada716347206784ecc6ec167 100644 (file)
@@ -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
index 5ca8e28ef43af3b9309680af6670a7b01712f20f..d39042f1aaf53dd9d5370388df97cca4297d7e5f 100644 (file)
@@ -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
index 01f57297863d7a9663513d90d502d111f8972d16..d023bc189e2cc8dfb8b3fc70bdb33dfbd096f99f 100644 (file)
 
 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>
index c6f96d737a4fba63093bd425bfd328008ced1c1f..2b6e4096ae4001e4c7c72b03a8bd74f2b71ed649 100644 (file)
@@ -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: