diff options
author | Mark de Wever <koraq@xs4all.nl> | 2022-01-21 20:08:57 +0100 |
---|---|---|
committer | Mark de Wever <koraq@xs4all.nl> | 2022-01-22 11:41:13 +0100 |
commit | 26544b98f7bf744d2ccd29cc6559db24bc1a4e50 (patch) | |
tree | 8a165d085aefc682fe7476aba819b05863f2497f | |
parent | f7d4cafe5a6a51ccc6072c9dd304ced4f8e96aa7 (diff) |
[libc++] Use addressof in unordered_set.
This addresses the usage of `operator&` in `<unordered_set>`.
(Note there are still more headers with the same issue.)
Reviewed By: #libc, philnik, Quuxplusone
Differential Revision: https://reviews.llvm.org/D117917
9 files changed, 266 insertions, 7 deletions
diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set index ad58fda24f87..29a19f2f0cb5 100644 --- a/libcxx/include/unordered_set +++ b/libcxx/include/unordered_set @@ -463,6 +463,7 @@ template <class Value, class Hash, class Pred, class Alloc> #include <__debug> #include <__functional/is_transparent.h> #include <__hash_table> +#include <__memory/addressof.h> #include <__node_handle> #include <__utility/forward.h> #include <compare> @@ -640,7 +641,7 @@ public: #if _LIBCPP_DEBUG_LEVEL == 2 iterator emplace_hint(const_iterator __p, _Args&&... __args) { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not" " referring to this unordered_set"); return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; @@ -657,7 +658,7 @@ public: #if _LIBCPP_DEBUG_LEVEL == 2 iterator insert(const_iterator __p, value_type&& __x) { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, "unordered_set::insert(const_iterator, value_type&&) called with an iterator not" " referring to this unordered_set"); return insert(_VSTD::move(__x)).first; @@ -678,7 +679,7 @@ public: #if _LIBCPP_DEBUG_LEVEL == 2 iterator insert(const_iterator __p, const value_type& __x) { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, "unordered_set::insert(const_iterator, const value_type&) called with an iterator not" " referring to this unordered_set"); return insert(__x).first; @@ -1019,7 +1020,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( { _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1037,7 +1038,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( } #if _LIBCPP_DEBUG_LEVEL == 2 else - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1660,7 +1661,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( { _VSTD::__debug_db_insert_c(this); #if _LIBCPP_DEBUG_LEVEL == 2 - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } @@ -1678,7 +1679,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( } #if _LIBCPP_DEBUG_LEVEL == 2 else - __get_db()->swap(this, &__u); + __get_db()->swap(this, _VSTD::addressof(__u)); #endif } diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move.addressof.compile.pass.cpp new file mode 100644 index 000000000000..9df029e61341 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move.addressof.compile.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03 + +// <unordered_set> + +// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, +// class Alloc = allocator<Value>> +// class unordered_multiset + +// unordered_multiset(unordered_multiset&& u); + +// Validate whether the operation properly guards against ADL-hijacking operator& + +#include <unordered_set> + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::unordered_multiset<operator_hijacker> so; + std::unordered_multiset<operator_hijacker> s(std::move(so)); +} diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.addressof.compile.pass.cpp new file mode 100644 index 000000000000..cd1f70eab9e6 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.addressof.compile.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03 + +// <unordered_set> + +// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, +// class Alloc = allocator<Value>> +// class unordered_multiset + +// Validate whether the operation properly guards against ADL-hijacking operator& + +#include <unordered_set> + +#include "test_allocator.h" +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + using A = test_allocator<operator_hijacker>; + using H = std::hash<operator_hijacker>; + using P = std::equal_to<operator_hijacker>; + + const A a; + std::unordered_multiset<operator_hijacker, H, P, A> so; + std::unordered_multiset<operator_hijacker, H, P, A> s(std::move(so), a); +} diff --git a/libcxx/test/std/containers/unord/unord.set/emplace_hint.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/emplace_hint.addressof.compile.pass.cpp new file mode 100644 index 000000000000..af6e37eaef96 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/emplace_hint.addressof.compile.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03 + +// <unordered_set> + +// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, +// class Alloc = allocator<Value>> +// class unordered_set + +// template <class... Args> +// iterator emplace_hint(const_iterator p, Args&&... args); + +// Validate whether the operation properly guards against ADL-hijacking operator& + +#include <unordered_set> + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::unordered_set<operator_hijacker> s; + s.emplace_hint(s.cbegin()); +} diff --git a/libcxx/test/std/containers/unord/unord.set/insert_hint_const_lvalue.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/insert_hint_const_lvalue.addressof.compile.pass.cpp new file mode 100644 index 000000000000..f83f28fc923f --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/insert_hint_const_lvalue.addressof.compile.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, +// class Alloc = allocator<Value>> +// class unordered_set + +// iterator insert(const_iterator p, const value_type& x); + +// Validate whether the operation properly guards against ADL-hijacking operator& + +#include <unordered_set> + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::unordered_set<operator_hijacker> s; + const operator_hijacker v; + s.insert(s.cbegin(), v); +} diff --git a/libcxx/test/std/containers/unord/unord.set/insert_hint_rvalue.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/insert_hint_rvalue.addressof.compile.pass.cpp new file mode 100644 index 000000000000..333c673e30b9 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/insert_hint_rvalue.addressof.compile.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, +// class Alloc = allocator<Value>> +// class unordered_set + +// iterator insert(const_iterator p, value_type&& x); + +// Validate whether the operation properly guards against ADL-hijacking operator& + +#include <unordered_set> + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::unordered_set<operator_hijacker> s; + s.insert(s.cbegin(), operator_hijacker()); +} diff --git a/libcxx/test/std/containers/unord/unord.set/iterator.operators.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/iterator.operators.addressof.compile.pass.cpp new file mode 100644 index 000000000000..457172d11f6b --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/iterator.operators.addressof.compile.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// <unordered_set> + +// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, +// class Alloc = allocator<Value>> + +// class unordered_set + +#include <unordered_set> + +#include "test_macros.h" +#include "operator_hijacker.h" + +template <class ToIterator, class FromIterator> +void test() { + FromIterator from; + ToIterator copy(from); + copy = from; + + ToIterator move(std::move(from)); + from = FromIterator(); + move = std::move(from); +} + +void test() { + { + using I = std::unordered_set<operator_hijacker>::iterator; + using CI = std::unordered_set<operator_hijacker>::const_iterator; + test<I, I>(); + test<CI, I>(); + test<CI, CI>(); + } + { + using IL = std::unordered_set<operator_hijacker>::local_iterator; + using CIL = std::unordered_set<operator_hijacker>::const_local_iterator; + test<IL, IL>(); + test<CIL, IL>(); + test<CIL, CIL>(); + } +} diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move.addressof.compile.pass.cpp new file mode 100644 index 000000000000..f7e9eb444bd5 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move.addressof.compile.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03 + +// <unordered_set> + +// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, +// class Alloc = allocator<Value>> +// class unordered_set + +// unordered_set(unordered_set&& u); + +// Validate whether the operation properly guards against ADL-hijacking operator& + +#include <unordered_set> + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::unordered_set<operator_hijacker> so; + std::unordered_set<operator_hijacker> s(std::move(so)); +} diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_alloc.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_alloc.addressof.compile.pass.cpp new file mode 100644 index 000000000000..8e9d8cb8d87b --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/move_alloc.addressof.compile.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03 + +// <unordered_set> + +// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, +// class Alloc = allocator<Value>> +// class unordered_set + +// unordered_set(unordered_set&& u, const allocator_type& a); + +// Validate whether the operation properly guards against ADL-hijacking operator& + +#include <unordered_set> + +#include "test_allocator.h" +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + using A = test_allocator<operator_hijacker>; + using H = std::hash<operator_hijacker>; + using P = std::equal_to<operator_hijacker>; + + const A a; + std::unordered_set<operator_hijacker, H, P, A> so; + std::unordered_set<operator_hijacker, H, P, A> s(std::move(so), a); +} |