Remove unsafe "__as_link()" cast member function.
"__as_link()" can only be used safely on "__list_node" objects. This patch moves the "__as_link()" member function from "__list_node_base" to "__list_node" so it cannot be used incorrectly. Unsafe downcasts now use a non-member function so we don't defer the type-punned pointer. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@256727 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
80
include/list
80
include/list
@@ -207,6 +207,22 @@ struct __list_node_pointer_traits {
|
|||||||
>::type __link_pointer;
|
>::type __link_pointer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef typename conditional<
|
||||||
|
is_same<__link_pointer, __node_pointer>::value,
|
||||||
|
__base_pointer,
|
||||||
|
__node_pointer
|
||||||
|
>::type __non_link_pointer;
|
||||||
|
|
||||||
|
static _LIBCPP_INLINE_VISIBILITY
|
||||||
|
__link_pointer __unsafe_link_pointer_cast(__link_pointer __p) {
|
||||||
|
return __p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _LIBCPP_INLINE_VISIBILITY
|
||||||
|
__link_pointer __unsafe_link_pointer_cast(__non_link_pointer __p) {
|
||||||
|
return static_cast<__link_pointer>(static_cast<_VoidPtr>(__p));
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class _Tp, class _VoidPtr>
|
template <class _Tp, class _VoidPtr>
|
||||||
@@ -221,22 +237,17 @@ struct __list_node_base
|
|||||||
__link_pointer __next_;
|
__link_pointer __next_;
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
__list_node_base() : __prev_(__as_link()), __next_(__as_link()) {}
|
__list_node_base() : __prev_(_NodeTraits::__unsafe_link_pointer_cast(__self())),
|
||||||
|
__next_(_NodeTraits::__unsafe_link_pointer_cast(__self())) {}
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
__base_pointer __as_base() {
|
__base_pointer __self() {
|
||||||
return pointer_traits<__base_pointer>::pointer_to(*this);
|
return pointer_traits<__base_pointer>::pointer_to(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
|
||||||
__link_pointer __as_link() {
|
|
||||||
return static_cast<__link_pointer>(static_cast<_VoidPtr>(
|
|
||||||
__as_base()));
|
|
||||||
}
|
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
__node_pointer __as_node() {
|
__node_pointer __as_node() {
|
||||||
return static_cast<__node_pointer>(__as_base());
|
return static_cast<__node_pointer>(__self());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -245,6 +256,14 @@ struct __list_node
|
|||||||
: public __list_node_base<_Tp, _VoidPtr>
|
: public __list_node_base<_Tp, _VoidPtr>
|
||||||
{
|
{
|
||||||
_Tp __value_;
|
_Tp __value_;
|
||||||
|
|
||||||
|
typedef __list_node_base<_Tp, _VoidPtr> __base;
|
||||||
|
typedef typename __base::__link_pointer __link_pointer;
|
||||||
|
|
||||||
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
|
__link_pointer __as_link() {
|
||||||
|
return static_cast<__link_pointer>(__base::__self());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TYPE_VIS_ONLY list;
|
template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TYPE_VIS_ONLY list;
|
||||||
@@ -520,7 +539,8 @@ protected:
|
|||||||
typedef allocator_traits<__node_allocator> __node_alloc_traits;
|
typedef allocator_traits<__node_allocator> __node_alloc_traits;
|
||||||
typedef typename __node_alloc_traits::pointer __node_pointer;
|
typedef typename __node_alloc_traits::pointer __node_pointer;
|
||||||
typedef typename __node_alloc_traits::pointer __node_const_pointer;
|
typedef typename __node_alloc_traits::pointer __node_const_pointer;
|
||||||
typedef typename __list_node_pointer_traits<value_type, __void_pointer>::__link_pointer __link_pointer;
|
typedef __list_node_pointer_traits<value_type, __void_pointer> __node_pointer_traits;
|
||||||
|
typedef typename __node_pointer_traits::__link_pointer __link_pointer;
|
||||||
typedef __link_pointer __link_const_pointer;
|
typedef __link_pointer __link_const_pointer;
|
||||||
typedef typename __alloc_traits::pointer pointer;
|
typedef typename __alloc_traits::pointer pointer;
|
||||||
typedef typename __alloc_traits::const_pointer const_pointer;
|
typedef typename __alloc_traits::const_pointer const_pointer;
|
||||||
@@ -532,6 +552,12 @@ protected:
|
|||||||
__node_base __end_;
|
__node_base __end_;
|
||||||
__compressed_pair<size_type, __node_allocator> __size_alloc_;
|
__compressed_pair<size_type, __node_allocator> __size_alloc_;
|
||||||
|
|
||||||
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
|
__link_pointer __end_as_link() const _NOEXCEPT {
|
||||||
|
return __node_pointer_traits::__unsafe_link_pointer_cast(
|
||||||
|
const_cast<__node_base&>(__end_).__self());
|
||||||
|
}
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
size_type& __sz() _NOEXCEPT {return __size_alloc_.first();}
|
size_type& __sz() _NOEXCEPT {return __size_alloc_.first();}
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
@@ -576,18 +602,18 @@ protected:
|
|||||||
iterator end() _NOEXCEPT
|
iterator end() _NOEXCEPT
|
||||||
{
|
{
|
||||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||||
return iterator(__end_.__as_link(), this);
|
return iterator(__end_as_link(), this);
|
||||||
#else
|
#else
|
||||||
return iterator(__end_.__as_link());
|
return iterator(__end_as_link());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
const_iterator end() const _NOEXCEPT
|
const_iterator end() const _NOEXCEPT
|
||||||
{
|
{
|
||||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||||
return const_iterator(const_cast<__node_base&>(__end_).__as_link(), this);
|
return const_iterator(__end_as_link(), this);
|
||||||
#else
|
#else
|
||||||
return const_iterator(const_cast<__node_base&>(__end_).__as_link());
|
return const_iterator(__end_as_link());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -681,7 +707,7 @@ __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT
|
|||||||
{
|
{
|
||||||
__node_allocator& __na = __node_alloc();
|
__node_allocator& __na = __node_alloc();
|
||||||
__link_pointer __f = __end_.__next_;
|
__link_pointer __f = __end_.__next_;
|
||||||
__link_pointer __l = __end_.__as_link();
|
__link_pointer __l = __end_as_link();
|
||||||
__unlink_nodes(__f, __l->__prev_);
|
__unlink_nodes(__f, __l->__prev_);
|
||||||
__sz() = 0;
|
__sz() = 0;
|
||||||
while (__f != __l)
|
while (__f != __l)
|
||||||
@@ -728,13 +754,13 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
|
|||||||
swap(__sz(), __c.__sz());
|
swap(__sz(), __c.__sz());
|
||||||
swap(__end_, __c.__end_);
|
swap(__end_, __c.__end_);
|
||||||
if (__sz() == 0)
|
if (__sz() == 0)
|
||||||
__end_.__next_ = __end_.__prev_ = __end_.__as_link();
|
__end_.__next_ = __end_.__prev_ = __end_as_link();
|
||||||
else
|
else
|
||||||
__end_.__prev_->__next_ = __end_.__next_->__prev_ = __end_.__as_link();
|
__end_.__prev_->__next_ = __end_.__next_->__prev_ = __end_as_link();
|
||||||
if (__c.__sz() == 0)
|
if (__c.__sz() == 0)
|
||||||
__c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_.__as_link();
|
__c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_as_link();
|
||||||
else
|
else
|
||||||
__c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_.__as_link();
|
__c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_as_link();
|
||||||
|
|
||||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||||
__libcpp_db* __db = __get_db();
|
__libcpp_db* __db = __get_db();
|
||||||
@@ -747,7 +773,7 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
|
|||||||
{
|
{
|
||||||
--__p;
|
--__p;
|
||||||
const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
|
const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
|
||||||
if (__i->__ptr_ == __c.__end_.__as_link())
|
if (__i->__ptr_ == __c.__end_as_link())
|
||||||
{
|
{
|
||||||
__cn2->__add(*__p);
|
__cn2->__add(*__p);
|
||||||
if (--__cn1->end_ != __p)
|
if (--__cn1->end_ != __p)
|
||||||
@@ -760,7 +786,7 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
|
|||||||
{
|
{
|
||||||
--__p;
|
--__p;
|
||||||
const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
|
const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
|
||||||
if (__i->__ptr_ == __end_.__as_link())
|
if (__i->__ptr_ == __end_as_link())
|
||||||
{
|
{
|
||||||
__cn1->__add(*__p);
|
__cn1->__add(*__p);
|
||||||
if (--__cn2->end_ != __p)
|
if (--__cn2->end_ != __p)
|
||||||
@@ -1061,7 +1087,7 @@ inline _LIBCPP_INLINE_VISIBILITY
|
|||||||
void
|
void
|
||||||
list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l)
|
list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l)
|
||||||
{
|
{
|
||||||
__f->__prev_ = base::__end_.__as_link();
|
__f->__prev_ = base::__end_as_link();
|
||||||
__l->__next_ = base::__end_.__next_;
|
__l->__next_ = base::__end_.__next_;
|
||||||
__l->__next_->__prev_ = __l;
|
__l->__next_->__prev_ = __l;
|
||||||
base::__end_.__next_ = __f;
|
base::__end_.__next_ = __f;
|
||||||
@@ -1073,7 +1099,7 @@ inline _LIBCPP_INLINE_VISIBILITY
|
|||||||
void
|
void
|
||||||
list<_Tp, _Alloc>::__link_nodes_at_back(__link_pointer __f, __link_pointer __l)
|
list<_Tp, _Alloc>::__link_nodes_at_back(__link_pointer __f, __link_pointer __l)
|
||||||
{
|
{
|
||||||
__l->__next_ = base::__end_.__as_link();
|
__l->__next_ = base::__end_as_link();
|
||||||
__f->__prev_ = base::__end_.__prev_;
|
__f->__prev_ = base::__end_.__prev_;
|
||||||
__f->__prev_->__next_ = __f;
|
__f->__prev_->__next_ = __f;
|
||||||
base::__end_.__prev_ = __l;
|
base::__end_.__prev_ = __l;
|
||||||
@@ -1892,7 +1918,7 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||||
__link_nodes(base::__end_.__as_link(), __r.__ptr_, __e.__ptr_);
|
__link_nodes(base::__end_as_link(), __r.__ptr_, __e.__ptr_);
|
||||||
base::__sz() += __ds;
|
base::__sz() += __ds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1924,7 +1950,7 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c)
|
|||||||
{
|
{
|
||||||
--__p;
|
--__p;
|
||||||
iterator* __i = static_cast<iterator*>((*__p)->__i_);
|
iterator* __i = static_cast<iterator*>((*__p)->__i_);
|
||||||
if (__i->__ptr_ != __c.__end_.__as_link())
|
if (__i->__ptr_ != __c.__end_as_link())
|
||||||
{
|
{
|
||||||
__cn1->__add(*__p);
|
__cn1->__add(*__p);
|
||||||
(*__p)->__c_ = __cn1;
|
(*__p)->__c_ = __cn1;
|
||||||
@@ -2153,7 +2179,7 @@ list<_Tp, _Alloc>::merge(list& __c, _Comp __comp)
|
|||||||
{
|
{
|
||||||
--__p;
|
--__p;
|
||||||
iterator* __i = static_cast<iterator*>((*__p)->__i_);
|
iterator* __i = static_cast<iterator*>((*__p)->__i_);
|
||||||
if (__i->__ptr_ != __c.__end_.__as_link())
|
if (__i->__ptr_ != __c.__end_as_link())
|
||||||
{
|
{
|
||||||
__cn1->__add(*__p);
|
__cn1->__add(*__p);
|
||||||
(*__p)->__c_ = __cn1;
|
(*__p)->__c_ = __cn1;
|
||||||
@@ -2275,7 +2301,7 @@ template <class _Tp, class _Alloc>
|
|||||||
bool
|
bool
|
||||||
list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const
|
list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const
|
||||||
{
|
{
|
||||||
return __i->__ptr_ != const_cast<__node_base&>(this->__end_).__as_link();
|
return __i->__ptr_ != this->__end_as_link();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class _Alloc>
|
template <class _Tp, class _Alloc>
|
||||||
|
|||||||
Reference in New Issue
Block a user