Skip to content

Commit

Permalink
Add BOOST_INTRUSIVE_NO_DANGLING ([[gnu::no_dangling]]) to avoid false…
Browse files Browse the repository at this point in the history
… positives on GCC 14 on container_from functions.
  • Loading branch information
igaztanaga committed Aug 11, 2024
1 parent 008795c commit 5a67b76
Show file tree
Hide file tree
Showing 16 changed files with 101 additions and 4 deletions.
1 change: 1 addition & 0 deletions doc/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ doxygen autodoc
\"treap_multiset_impl=treap_multiset\" \\
\"treap_impl=treap\" \\
\"BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) = template<TYPE VALUE> struct OPTION_NAME{};\" \\
\"BOOST_INTRUSIVE_NO_DANGLING\" \\
\"BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) = template<class TYPE> struct OPTION_NAME{};\" "
;

Expand Down
8 changes: 8 additions & 0 deletions include/boost/intrusive/avl_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,15 +554,19 @@ class avl_set
inline void clone_from(BOOST_RV_REF(avl_set) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static avl_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<avl_set &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const avl_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const avl_set &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static avl_set &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<avl_set &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const avl_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const avl_set &>(Base::container_from_iterator(it)); }
};
Expand Down Expand Up @@ -1049,15 +1053,19 @@ class avl_multiset
inline void clone_from(BOOST_RV_REF(avl_multiset) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static avl_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<avl_multiset &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const avl_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const avl_multiset &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static avl_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<avl_multiset &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const avl_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const avl_multiset &>(Base::container_from_iterator(it)); }
};
Expand Down
4 changes: 4 additions & 0 deletions include/boost/intrusive/avltree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -564,15 +564,19 @@ class avltree
inline void clone_from(BOOST_RV_REF(avltree) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static avltree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<avltree &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const avltree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const avltree &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static avltree &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<avltree &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const avltree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const avltree &>(Base::container_from_iterator(it)); }
};
Expand Down
8 changes: 8 additions & 0 deletions include/boost/intrusive/bs_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -551,15 +551,19 @@ class bs_set
inline void clone_from(BOOST_RV_REF(bs_set) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static bs_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<bs_set &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const bs_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const bs_set &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static bs_set &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<bs_set &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const bs_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const bs_set &>(Base::container_from_iterator(it)); }
};
Expand Down Expand Up @@ -1045,15 +1049,19 @@ class bs_multiset
inline void clone_from(BOOST_RV_REF(bs_multiset) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static bs_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<bs_multiset &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const bs_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const bs_multiset &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static bs_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<bs_multiset &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const bs_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const bs_multiset &>(Base::container_from_iterator(it)); }
};
Expand Down
16 changes: 12 additions & 4 deletions include/boost/intrusive/bstree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,8 @@ class bstree_impl
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
static bstree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
BOOST_INTRUSIVE_NO_DANGLING
static bstree_impl& container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{
return static_cast<bstree_impl&>
(data_type::get_tree_base_from_end_iterator(end_iterator));
Expand All @@ -890,7 +891,8 @@ class bstree_impl
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
static const bstree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
BOOST_INTRUSIVE_NO_DANGLING
static const bstree_impl & container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{
return static_cast<bstree_impl&>
(data_type::get_tree_base_from_end_iterator(end_iterator));
Expand All @@ -904,7 +906,8 @@ class bstree_impl
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Logarithmic.
static bstree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT
BOOST_INTRUSIVE_NO_DANGLING
static bstree_impl & container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return container_from_end_iterator(it.end_iterator_from_it()); }

//! <b>Precondition</b>: it must be a valid end const_iterator
Expand All @@ -915,7 +918,8 @@ class bstree_impl
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Logarithmic.
static const bstree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
BOOST_INTRUSIVE_NO_DANGLING
static const bstree_impl & container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return container_from_end_iterator(it.end_iterator_from_it()); }

#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Expand Down Expand Up @@ -2215,15 +2219,19 @@ class bstree
inline void clone_from(BOOST_RV_REF(bstree) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static bstree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<bstree &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const bstree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const bstree &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static bstree &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<bstree &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const bstree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const bstree &>(Base::container_from_iterator(it)); }
};
Expand Down
10 changes: 10 additions & 0 deletions include/boost/intrusive/detail/workaround.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@ template<unsigned> struct static_assert_test {};
(unsigned)sizeof(::boost::intrusive::detail::STATIC_ASSERTION_FAILURE<bool(B)>)>\
BOOST_JOIN(boost_intrusive_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED

#endif //BOOST_NO_CXX11_STATIC_ASSERT


//GCC has some false positives with some functions returning references.
//This silences this warning in selected functions
#if defined(BOOST_GCC) && (BOOST_GCC >= 140000)
# define BOOST_INTRUSIVE_NO_DANGLING [[gnu::no_dangling]]
#else
# define BOOST_INTRUSIVE_NO_DANGLING
#endif


#endif //#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP
5 changes: 5 additions & 0 deletions include/boost/intrusive/list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ class list_impl
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
BOOST_INTRUSIVE_NO_DANGLING
inline static list_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return list_impl::priv_container_from_end_iterator(end_iterator); }

Expand All @@ -511,6 +512,7 @@ class list_impl
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
BOOST_INTRUSIVE_NO_DANGLING
inline static const list_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return list_impl::priv_container_from_end_iterator(end_iterator); }

Expand Down Expand Up @@ -1391,6 +1393,7 @@ class list_impl
/// @cond

private:
BOOST_INTRUSIVE_NO_DANGLING
static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) BOOST_NOEXCEPT
{
BOOST_INTRUSIVE_STATIC_ASSERT((has_container_from_iterator));
Expand Down Expand Up @@ -1501,9 +1504,11 @@ class list
inline void clone_from(BOOST_RV_REF(list) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static list &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<list &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const list &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const list &>(Base::container_from_end_iterator(end_iterator)); }
};
Expand Down
4 changes: 4 additions & 0 deletions include/boost/intrusive/rbtree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,15 +567,19 @@ class rbtree
inline void clone_from(BOOST_RV_REF(rbtree) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static rbtree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<rbtree &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const rbtree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const rbtree &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static rbtree &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<rbtree &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const rbtree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const rbtree &>(Base::container_from_iterator(it)); }
};
Expand Down
8 changes: 8 additions & 0 deletions include/boost/intrusive/set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,15 +554,19 @@ class set
inline void clone_from(BOOST_RV_REF(set) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<set &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const set &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static set &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<set &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const set &>(Base::container_from_iterator(it)); }
};
Expand Down Expand Up @@ -1049,15 +1053,19 @@ class multiset
inline void clone_from(BOOST_RV_REF(multiset) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<multiset &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const multiset &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<multiset &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const multiset &>(Base::container_from_iterator(it)); }
};
Expand Down
8 changes: 8 additions & 0 deletions include/boost/intrusive/sg_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,15 +563,19 @@ class sg_set
inline void clone_from(BOOST_RV_REF(sg_set) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static sg_set &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<sg_set &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const sg_set &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const sg_set &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static sg_set &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<sg_set &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const sg_set &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const sg_set &>(Base::container_from_iterator(it)); }
};
Expand Down Expand Up @@ -1070,15 +1074,19 @@ class sg_multiset
inline void clone_from(BOOST_RV_REF(sg_multiset) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static sg_multiset &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<sg_multiset &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const sg_multiset &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const sg_multiset &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static sg_multiset &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<sg_multiset &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const sg_multiset &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const sg_multiset &>(Base::container_from_iterator(it)); }
};
Expand Down
4 changes: 4 additions & 0 deletions include/boost/intrusive/sgtree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1049,15 +1049,19 @@ class sgtree
inline void clone_from(BOOST_RV_REF(sgtree) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static sgtree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<sgtree &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const sgtree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const sgtree &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static sgtree &container_from_iterator(iterator it) BOOST_NOEXCEPT
{ return static_cast<sgtree &>(Base::container_from_iterator(it)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const sgtree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
{ return static_cast<const sgtree &>(Base::container_from_iterator(it)); }
};
Expand Down
5 changes: 5 additions & 0 deletions include/boost/intrusive/slist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ class slist_impl
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
BOOST_INTRUSIVE_NO_DANGLING
inline static slist_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return slist_impl::priv_container_from_end_iterator(end_iterator); }

Expand All @@ -671,6 +672,7 @@ class slist_impl
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
BOOST_INTRUSIVE_NO_DANGLING
inline static const slist_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return slist_impl::priv_container_from_end_iterator(end_iterator); }

Expand Down Expand Up @@ -2107,6 +2109,7 @@ class slist_impl
static void priv_swap_lists(node_ptr this_node, node_ptr other_node, detail::bool_<true>)
{ node_algorithms::swap_trailing_nodes(this_node, other_node); }

BOOST_INTRUSIVE_NO_DANGLING
static slist_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
{
//Obtaining the container from the end iterator is not possible with linear
Expand Down Expand Up @@ -2229,9 +2232,11 @@ class slist
inline void clone_from(BOOST_RV_REF(slist) src, Cloner cloner, Disposer disposer)
{ Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }

BOOST_INTRUSIVE_NO_DANGLING
inline static slist &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<slist &>(Base::container_from_end_iterator(end_iterator)); }

BOOST_INTRUSIVE_NO_DANGLING
inline static const slist &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
{ return static_cast<const slist &>(Base::container_from_end_iterator(end_iterator)); }
};
Expand Down
Loading

0 comments on commit 5a67b76

Please sign in to comment.