Skip to content

Commit 26544b9

Browse files
committed
[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
1 parent f7d4caf commit 26544b9

9 files changed

+266
-7
lines changed

libcxx/include/unordered_set

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ template <class Value, class Hash, class Pred, class Alloc>
463463
#include <__debug>
464464
#include <__functional/is_transparent.h>
465465
#include <__hash_table>
466+
#include <__memory/addressof.h>
466467
#include <__node_handle>
467468
#include <__utility/forward.h>
468469
#include <compare>
@@ -640,7 +641,7 @@ public:
640641
#if _LIBCPP_DEBUG_LEVEL == 2
641642
iterator emplace_hint(const_iterator __p, _Args&&... __args)
642643
{
643-
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
644+
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
644645
"unordered_set::emplace_hint(const_iterator, args...) called with an iterator not"
645646
" referring to this unordered_set");
646647
return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
@@ -657,7 +658,7 @@ public:
657658
#if _LIBCPP_DEBUG_LEVEL == 2
658659
iterator insert(const_iterator __p, value_type&& __x)
659660
{
660-
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
661+
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
661662
"unordered_set::insert(const_iterator, value_type&&) called with an iterator not"
662663
" referring to this unordered_set");
663664
return insert(_VSTD::move(__x)).first;
@@ -678,7 +679,7 @@ public:
678679
#if _LIBCPP_DEBUG_LEVEL == 2
679680
iterator insert(const_iterator __p, const value_type& __x)
680681
{
681-
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
682+
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
682683
"unordered_set::insert(const_iterator, const value_type&) called with an iterator not"
683684
" referring to this unordered_set");
684685
return insert(__x).first;
@@ -1019,7 +1020,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
10191020
{
10201021
_VSTD::__debug_db_insert_c(this);
10211022
#if _LIBCPP_DEBUG_LEVEL == 2
1022-
__get_db()->swap(this, &__u);
1023+
__get_db()->swap(this, _VSTD::addressof(__u));
10231024
#endif
10241025
}
10251026

@@ -1037,7 +1038,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
10371038
}
10381039
#if _LIBCPP_DEBUG_LEVEL == 2
10391040
else
1040-
__get_db()->swap(this, &__u);
1041+
__get_db()->swap(this, _VSTD::addressof(__u));
10411042
#endif
10421043
}
10431044

@@ -1660,7 +1661,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16601661
{
16611662
_VSTD::__debug_db_insert_c(this);
16621663
#if _LIBCPP_DEBUG_LEVEL == 2
1663-
__get_db()->swap(this, &__u);
1664+
__get_db()->swap(this, _VSTD::addressof(__u));
16641665
#endif
16651666
}
16661667

@@ -1678,7 +1679,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
16781679
}
16791680
#if _LIBCPP_DEBUG_LEVEL == 2
16801681
else
1681-
__get_db()->swap(this, &__u);
1682+
__get_db()->swap(this, _VSTD::addressof(__u));
16821683
#endif
16831684
}
16841685

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03
10+
11+
// <unordered_set>
12+
13+
// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
14+
// class Alloc = allocator<Value>>
15+
// class unordered_multiset
16+
17+
// unordered_multiset(unordered_multiset&& u);
18+
19+
// Validate whether the operation properly guards against ADL-hijacking operator&
20+
21+
#include <unordered_set>
22+
23+
#include "test_macros.h"
24+
#include "operator_hijacker.h"
25+
26+
void test() {
27+
std::unordered_multiset<operator_hijacker> so;
28+
std::unordered_multiset<operator_hijacker> s(std::move(so));
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03
10+
11+
// <unordered_set>
12+
13+
// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
14+
// class Alloc = allocator<Value>>
15+
// class unordered_multiset
16+
17+
// Validate whether the operation properly guards against ADL-hijacking operator&
18+
19+
#include <unordered_set>
20+
21+
#include "test_allocator.h"
22+
#include "test_macros.h"
23+
#include "operator_hijacker.h"
24+
25+
void test() {
26+
using A = test_allocator<operator_hijacker>;
27+
using H = std::hash<operator_hijacker>;
28+
using P = std::equal_to<operator_hijacker>;
29+
30+
const A a;
31+
std::unordered_multiset<operator_hijacker, H, P, A> so;
32+
std::unordered_multiset<operator_hijacker, H, P, A> s(std::move(so), a);
33+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03
10+
11+
// <unordered_set>
12+
13+
// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
14+
// class Alloc = allocator<Value>>
15+
// class unordered_set
16+
17+
// template <class... Args>
18+
// iterator emplace_hint(const_iterator p, Args&&... args);
19+
20+
// Validate whether the operation properly guards against ADL-hijacking operator&
21+
22+
#include <unordered_set>
23+
24+
#include "test_macros.h"
25+
#include "operator_hijacker.h"
26+
27+
void test() {
28+
std::unordered_set<operator_hijacker> s;
29+
s.emplace_hint(s.cbegin());
30+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// <unordered_set>
10+
11+
// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
12+
// class Alloc = allocator<Value>>
13+
// class unordered_set
14+
15+
// iterator insert(const_iterator p, const value_type& x);
16+
17+
// Validate whether the operation properly guards against ADL-hijacking operator&
18+
19+
#include <unordered_set>
20+
21+
#include "test_macros.h"
22+
#include "operator_hijacker.h"
23+
24+
void test() {
25+
std::unordered_set<operator_hijacker> s;
26+
const operator_hijacker v;
27+
s.insert(s.cbegin(), v);
28+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// <unordered_set>
10+
11+
// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
12+
// class Alloc = allocator<Value>>
13+
// class unordered_set
14+
15+
// iterator insert(const_iterator p, value_type&& x);
16+
17+
// Validate whether the operation properly guards against ADL-hijacking operator&
18+
19+
#include <unordered_set>
20+
21+
#include "test_macros.h"
22+
#include "operator_hijacker.h"
23+
24+
void test() {
25+
std::unordered_set<operator_hijacker> s;
26+
s.insert(s.cbegin(), operator_hijacker());
27+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// <unordered_set>
10+
11+
// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
12+
// class Alloc = allocator<Value>>
13+
14+
// class unordered_set
15+
16+
#include <unordered_set>
17+
18+
#include "test_macros.h"
19+
#include "operator_hijacker.h"
20+
21+
template <class ToIterator, class FromIterator>
22+
void test() {
23+
FromIterator from;
24+
ToIterator copy(from);
25+
copy = from;
26+
27+
ToIterator move(std::move(from));
28+
from = FromIterator();
29+
move = std::move(from);
30+
}
31+
32+
void test() {
33+
{
34+
using I = std::unordered_set<operator_hijacker>::iterator;
35+
using CI = std::unordered_set<operator_hijacker>::const_iterator;
36+
test<I, I>();
37+
test<CI, I>();
38+
test<CI, CI>();
39+
}
40+
{
41+
using IL = std::unordered_set<operator_hijacker>::local_iterator;
42+
using CIL = std::unordered_set<operator_hijacker>::const_local_iterator;
43+
test<IL, IL>();
44+
test<CIL, IL>();
45+
test<CIL, CIL>();
46+
}
47+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03
10+
11+
// <unordered_set>
12+
13+
// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
14+
// class Alloc = allocator<Value>>
15+
// class unordered_set
16+
17+
// unordered_set(unordered_set&& u);
18+
19+
// Validate whether the operation properly guards against ADL-hijacking operator&
20+
21+
#include <unordered_set>
22+
23+
#include "test_macros.h"
24+
#include "operator_hijacker.h"
25+
26+
void test() {
27+
std::unordered_set<operator_hijacker> so;
28+
std::unordered_set<operator_hijacker> s(std::move(so));
29+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03
10+
11+
// <unordered_set>
12+
13+
// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
14+
// class Alloc = allocator<Value>>
15+
// class unordered_set
16+
17+
// unordered_set(unordered_set&& u, const allocator_type& a);
18+
19+
// Validate whether the operation properly guards against ADL-hijacking operator&
20+
21+
#include <unordered_set>
22+
23+
#include "test_allocator.h"
24+
#include "test_macros.h"
25+
#include "operator_hijacker.h"
26+
27+
void test() {
28+
using A = test_allocator<operator_hijacker>;
29+
using H = std::hash<operator_hijacker>;
30+
using P = std::equal_to<operator_hijacker>;
31+
32+
const A a;
33+
std::unordered_set<operator_hijacker, H, P, A> so;
34+
std::unordered_set<operator_hijacker, H, P, A> s(std::move(so), a);
35+
}

0 commit comments

Comments
 (0)