On 26/05/15 15:46 +0100, Jonathan Wakely wrote:
On 22/05/15 18:48 +0100, Jonathan Wakely wrote:
On 22/05/15 16:21 +0100, Jonathan Wakely wrote:
On 22/05/15 17:13 +0200, Jakub Jelinek wrote:
On Fri, May 22, 2015 at 03:59:47PM +0100, Jonathan Wakely wrote:
+      alignas(alignof(_Tp2)) unsigned char _M_storage[sizeof(_Tp)];

Is alignof(_Tp2) always the same as alignof(_Tp2::_M_t) on all targets
(I mean, won't some target align the structure more than its only field)?

Hmm, maybe. I don't know.

Wouldn't it be safer to use alignof(_Tp2::_M_t) here?

Yes.

Though, apparently that is a GNU extension, so you'd need to use __alignof__
instead.

Yes, that's what I did in an earlier version of the patch, so I'll go
back to that.

Just grepped around, and e.g. on powerpc64le-linux -std=c++11 -malign-power -O2
typedef double _Tp;
struct _Tp2 { _Tp _M_t; };
extern _Tp2 tp2e;
int a = alignof(_Tp2);
int b = __alignof__(_Tp2::_M_t);
int c = alignof(_Tp);
int d = __alignof__(tp2e._M_t);
int e = alignof(_Tp2::_M_t);

we have a = 8, b = 4, c = 8, d = 4, e = 4.

OK, thanks.

Note clang++ with -pedantic-errors errors out on alignof(_Tp2::_M_t) though.

It allows __alignof__ though.

Revised patches attached, as two separate commits because the first
should be backported but the second doesn't need to be.

This includes the necessary changes for the Python printers.

The change to __aligned_buffer (which makes _Rb_tree_node<long long>
consistent in c++98 and c++11 modes) also affects some other
C++11-only types. Compiling the attached program with -std=gnu++11
-m32 before and after the patch produces these results:

Before:

future<long long> shared state: alignment: 8 size: 24
shared_ptr<long long> control block: alignment: 8 size: 24
forward_list<long long> node: alignment: 8 size: 16
unordered_set<long long> node: alignment: 8 size: 16

After:

future<long long> shared state: alignment: 4 size: 20
shared_ptr<long long> control block: alignment: 4 size: 20
forward_list<long long> node: alignment: 4 size: 12
unordered_set<long long> node: alignment: 4 size: 12

The fix for _Rb_tree_node<long long> is a bug fix and necessary for
consistency with existing c++98 code, which is more important than
consistency with existing c++11 code using 5.1 or earlier releases.

But changing the other types as well would make 5.2 inconsistent with
5.1 for those types. We could just make that change and deal with it,
or I could keep __aligned_buffer unchanged and add a new
__aligned_buffer_mem for use in _Rb_tree_node, so we only change the
one type that is currently inconsistent between c++98 and c++11 modes.
The attached patch makes that smaller change (the second patch in my
last mail remains unchanged).

It's a shame to waste some space in the other types using
__aligned_buffer, and to have to maintain both __aligned_buffer and
__aligned_buffer_mem, but I think this is safer.

Here's the version I've committed, it's the same as the version
yesterday but renaming __aligned_buffer_mem to __aligned_membuf and
adding some comments to <ext/aligned_buffer.h> explaining why there
are two types.

Tested powerpc64le-linux, committed to trunk.

I plan to commit patch1.txt to gcc-5-branch too.
commit 8dae241ed96d8ad400a4f8af7748a5bd0315c0e7
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Thu May 21 14:41:16 2015 +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.

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:
commit 04bab95db326f2c1ca51f3b6f673883f50025245
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Fri May 22 13:54:50 2015 +0100

        * include/bits/stl_tree.h (_Rb_tree::_M_end()): Return _Base_ptr
        instead of downcasting.
        (_Rb_tree::_M_copy): Change second parameter to _Base_ptr.
        (_Rb_tree::_M_lower_bound, _Rb_tree:_M_upper_bound): Likewise.
        (_Rb_tree::_S_iter): Remove.
        (_Rb_tree::_S_lower_bound_tr, _Rb_tree::_S_upper_bound_tr): Remove.
        (_Rb_tree::_M_find_tr(const _Kt&) const): Call _M_lower_bound_tr
        instead of _S_lower_bound_tr
        (_Rb_tree::_M_find_tr(const _Kt&)): Call const overload.
        (_Rb_tree::_M_lower_bound_tr(const _Kt&) const): Do the search here
        instead of calling _S_lower_bound_tr.
        (_Rb_tree::_M_lower_bound_tr(const _Kt&)): Call const overload.
        (_Rb_tree::_M_upper_bound_tr(const _Kt&) const): Do the search here
        instead of calling _S_upper_bound_tr.
        (_Rb_tree::_M_upper_bound_tr(const _Kt&)): Call const overload.
        (_Rb_tree::_M_equal_range_tr(const _Kt&)): Likewise.
        (_Rb_tree::equal_range): Use _Base_ptr for end pointer.
        (_Rb_tree::_M_get_insert_unique_pos): Likewise.
        (_Rb_tree::_M_get_insert_equal_pos): Likewise.
        (_Rb_tree::_M_insert_equal_lower_node): Likewise.
        (_Rb_tree::_M_insert_unique, _Rb_tree::_M_emplace_unique,
        _Rb_tree::_M_emplace_hint_unique): Remove static_cast.

diff --git a/libstdc++-v3/include/bits/stl_tree.h 
b/libstdc++-v3/include/bits/stl_tree.h
index d39042f..240f522 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -658,13 +658,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          (this->_M_impl._M_header._M_parent);
       }
 
-      _Link_type
+      _Base_ptr
       _M_end() _GLIBCXX_NOEXCEPT
-      { return reinterpret_cast<_Link_type>(&this->_M_impl._M_header); }
+      { return &this->_M_impl._M_header; }
 
-      _Const_Link_type
+      _Const_Base_ptr
       _M_end() const _GLIBCXX_NOEXCEPT
-      { return reinterpret_cast<_Const_Link_type>(&this->_M_impl._M_header); }
+      { return &this->_M_impl._M_header; }
 
       static const_reference
       _S_value(_Const_Link_type __x)
@@ -774,10 +774,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       template<typename _NodeGen>
        _Link_type
-       _M_copy(_Const_Link_type __x, _Link_type __p, _NodeGen&);
+       _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen&);
 
       _Link_type
-      _M_copy(_Const_Link_type __x, _Link_type __p)
+      _M_copy(_Const_Link_type __x, _Base_ptr __p)
       {
        _Alloc_node __an(*this);
        return _M_copy(__x, __p, __an);
@@ -787,19 +787,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_erase(_Link_type __x);
 
       iterator
-      _M_lower_bound(_Link_type __x, _Link_type __y,
+      _M_lower_bound(_Link_type __x, _Base_ptr __y,
                     const _Key& __k);
 
       const_iterator
-      _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y,
+      _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y,
                     const _Key& __k) const;
 
       iterator
-      _M_upper_bound(_Link_type __x, _Link_type __y,
+      _M_upper_bound(_Link_type __x, _Base_ptr __y,
                     const _Key& __k);
 
       const_iterator
-      _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y,
+      _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y,
                     const _Key& __k) const;
 
     public:
@@ -1117,43 +1117,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        __is_transparent<_Cmp, _Kt, __void_t<typename _Cmp::is_transparent>>
        { typedef void type; };
 
-      static auto _S_iter(_Link_type __x) { return iterator(__x); }
-
-      static auto _S_iter(_Const_Link_type __x) { return const_iterator(__x); }
-
-      template<typename _Cmp, typename _Link, typename _Kt>
-       static auto
-       _S_lower_bound_tr(_Cmp& __cmp, _Link __x, _Link __y, const _Kt& __k)
-       {
-         while (__x != 0)
-           if (!__cmp(_S_key(__x), __k))
-             __y = __x, __x = _S_left(__x);
-           else
-             __x = _S_right(__x);
-         return _S_iter(__y);
-       }
-
-      template<typename _Cmp, typename _Link, typename _Kt>
-       static auto
-       _S_upper_bound_tr(_Cmp& __cmp, _Link __x, _Link __y, const _Kt& __k)
-       {
-         while (__x != 0)
-           if (__cmp(__k, _S_key(__x)))
-             __y = __x, __x = _S_left(__x);
-           else
-             __x = _S_right(__x);
-         return _S_iter(__y);
-       }
-
       template<typename _Kt,
               typename _Req = typename __is_transparent<_Compare, _Kt>::type>
        iterator
        _M_find_tr(const _Kt& __k)
        {
-         auto& __cmp = _M_impl._M_key_compare;
-         auto __j = _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
-         return (__j == end() || __cmp(__k, _S_key(__j._M_node)))
-           ? end() : __j;
+         const _Rb_tree* __const_this = this;
+         return __const_this->_M_find_tr(__k)._M_const_cast();
        }
 
       template<typename _Kt,
@@ -1161,10 +1131,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        const_iterator
        _M_find_tr(const _Kt& __k) const
        {
-         auto& __cmp = _M_impl._M_key_compare;
-         auto __j = _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
-         return (__j == end() || __cmp(__k, _S_key(__j._M_node)))
-           ? end() : __j;
+         auto __j = _M_lower_bound_tr(__k);
+         if (__j != end() && _M_impl._M_key_compare(__k, _S_key(__j._M_node)))
+           __j = end();
+         return __j;
        }
 
       template<typename _Kt,
@@ -1181,8 +1151,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        iterator
        _M_lower_bound_tr(const _Kt& __k)
        {
-         auto& __cmp = _M_impl._M_key_compare;
-         return _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
+         const _Rb_tree* __const_this = this;
+         return __const_this->_M_lower_bound_tr(__k)._M_const_cast();
        }
 
       template<typename _Kt,
@@ -1190,8 +1160,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        const_iterator
        _M_lower_bound_tr(const _Kt& __k) const
        {
-         auto& __cmp = _M_impl._M_key_compare;
-         return _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
+         auto __x = _M_begin();
+         auto __y = _M_end();
+         while (__x != 0)
+           if (!_M_impl._M_key_compare(_S_key(__x), __k))
+             {
+               __y = __x;
+               __x = _S_left(__x);
+             }
+           else
+             __x = _S_right(__x);
+         return const_iterator(__y);
        }
 
       template<typename _Kt,
@@ -1199,8 +1178,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        iterator
        _M_upper_bound_tr(const _Kt& __k)
        {
-         auto& __cmp = _M_impl._M_key_compare;
-         return _S_upper_bound_tr(__cmp, _M_begin(), _M_end(), __k);
+         const _Rb_tree* __const_this = this;
+         return __const_this->_M_upper_bound_tr(__k)._M_const_cast();
        }
 
       template<typename _Kt,
@@ -1208,8 +1187,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        const_iterator
        _M_upper_bound_tr(const _Kt& __k) const
        {
-         auto& __cmp = _M_impl._M_key_compare;
-         return _S_upper_bound_tr(__cmp, _M_begin(), _M_end(), __k);
+         auto __x = _M_begin();
+         auto __y = _M_end();
+         while (__x != 0)
+           if (_M_impl._M_key_compare(__k, _S_key(__x)))
+             {
+               __y = __x;
+               __x = _S_left(__x);
+             }
+           else
+             __x = _S_right(__x);
+         return const_iterator(__y);
        }
 
       template<typename _Kt,
@@ -1217,12 +1205,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        pair<iterator, iterator>
        _M_equal_range_tr(const _Kt& __k)
        {
-         auto __low = _M_lower_bound_tr(__k);
-         auto __high = __low;
-         auto& __cmp = _M_impl._M_key_compare;
-         while (__high != end() && !__cmp(__k, _S_key(__high._M_node)))
-           ++__high;
-         return { __low, __high };
+         const _Rb_tree* __const_this = this;
+         auto __ret = __const_this->_M_equal_range_tr(__k);
+         return { __ret.first._M_const_cast(), __ret.second._M_const_cast() };
        }
 
       template<typename _Kt,
@@ -1553,7 +1538,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
     {
       _Link_type __x = _M_begin();
-      _Link_type __y = _M_end();
+      _Base_ptr __y = _M_end();
       while (__x != 0)
        {
          __y = __x;
@@ -1568,7 +1553,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     template<typename _NodeGen>
       typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
       _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
-      _M_copy(_Const_Link_type __x, _Link_type __p, _NodeGen& __node_gen)
+      _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen& __node_gen)
       {
        // Structural copy. __x and __p must be non-null.
        _Link_type __top = _M_clone_node(__x, __node_gen);
@@ -1621,7 +1606,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     typename _Rb_tree<_Key, _Val, _KeyOfValue,
                      _Compare, _Alloc>::iterator
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    _M_lower_bound(_Link_type __x, _Link_type __y,
+    _M_lower_bound(_Link_type __x, _Base_ptr __y,
                   const _Key& __k)
     {
       while (__x != 0)
@@ -1637,7 +1622,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     typename _Rb_tree<_Key, _Val, _KeyOfValue,
                      _Compare, _Alloc>::const_iterator
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y,
+    _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y,
                   const _Key& __k) const
     {
       while (__x != 0)
@@ -1653,7 +1638,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     typename _Rb_tree<_Key, _Val, _KeyOfValue,
                      _Compare, _Alloc>::iterator
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    _M_upper_bound(_Link_type __x, _Link_type __y,
+    _M_upper_bound(_Link_type __x, _Base_ptr __y,
                   const _Key& __k)
     {
       while (__x != 0)
@@ -1669,7 +1654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     typename _Rb_tree<_Key, _Val, _KeyOfValue,
                      _Compare, _Alloc>::const_iterator
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y,
+    _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y,
                   const _Key& __k) const
     {
       while (__x != 0)
@@ -1690,7 +1675,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     equal_range(const _Key& __k)
     {
       _Link_type __x = _M_begin();
-      _Link_type __y = _M_end();
+      _Base_ptr __y = _M_end();
       while (__x != 0)
        {
          if (_M_impl._M_key_compare(_S_key(__x), __k))
@@ -1699,7 +1684,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            __y = __x, __x = _S_left(__x);
          else
            {
-             _Link_type __xu(__x), __yu(__y);
+             _Link_type __xu(__x);
+             _Base_ptr __yu(__y);
              __y = __x, __x = _S_left(__x);
              __xu = _S_right(__xu);
              return pair<iterator,
@@ -1721,7 +1707,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     equal_range(const _Key& __k) const
     {
       _Const_Link_type __x = _M_begin();
-      _Const_Link_type __y = _M_end();
+      _Const_Base_ptr __y = _M_end();
       while (__x != 0)
        {
          if (_M_impl._M_key_compare(_S_key(__x), __k))
@@ -1730,7 +1716,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            __y = __x, __x = _S_left(__x);
          else
            {
-             _Const_Link_type __xu(__x), __yu(__y);
+             _Const_Link_type __xu(__x);
+             _Const_Base_ptr __yu(__y);
              __y = __x, __x = _S_left(__x);
              __xu = _S_right(__xu);
              return pair<const_iterator,
@@ -1802,7 +1789,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       typedef pair<_Base_ptr, _Base_ptr> _Res;
       _Link_type __x = _M_begin();
-      _Link_type __y = _M_end();
+      _Base_ptr __y = _M_end();
       bool __comp = true;
       while (__x != 0)
        {
@@ -1834,7 +1821,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       typedef pair<_Base_ptr, _Base_ptr> _Res;
       _Link_type __x = _M_begin();
-      _Link_type __y = _M_end();
+      _Base_ptr __y = _M_end();
       while (__x != 0)
        {
          __y = __x;
@@ -1870,7 +1857,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                      true);
        }
 
-      return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
+      return _Res(iterator(__res.first), false);
     }
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
@@ -1976,7 +1963,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        return _M_insert_(__res.first, __res.second,
                          _GLIBCXX_FORWARD(_Arg, __v),
                          __node_gen);
-      return iterator(static_cast<_Link_type>(__res.first));
+      return iterator(__res.first);
     }
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
@@ -2102,7 +2089,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _M_insert_equal_lower_node(_Link_type __z)
     {
       _Link_type __x = _M_begin();
-      _Link_type __y = _M_end();
+      _Base_ptr __y = _M_end();
       while (__x != 0)
        {
          __y = __x;
@@ -2130,7 +2117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              return _Res(_M_insert_node(__res.first, __res.second, __z), true);
        
            _M_drop_node(__z);
-           return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
+           return _Res(iterator(__res.first), false);
          }
        __catch(...)
          {
@@ -2177,7 +2164,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              return _M_insert_node(__res.first, __res.second, __z);
 
            _M_drop_node(__z);
-           return iterator(static_cast<_Link_type>(__res.first));
+           return iterator(__res.first);
          }
        __catch(...)
          {

Reply via email to