Skip to content

Commit eff1492

Browse files
committed
[libc++] Work around namespace visibility annotations bleeding into user code
1 parent af2a957 commit eff1492

File tree

6 files changed

+83
-14
lines changed

6 files changed

+83
-14
lines changed

libcxx/include/__functional/hash.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -517,9 +517,6 @@ struct __enum_hash<_Tp, false> {
517517
__enum_hash& operator=(__enum_hash const&) = delete;
518518
};
519519

520-
template <class _Tp>
521-
struct hash : public __enum_hash<_Tp> {};
522-
523520
#if _LIBCPP_STD_VER >= 17
524521

525522
template <>
@@ -555,4 +552,13 @@ using __enable_hash_helper _LIBCPP_NODEBUG = _Type;
555552

556553
_LIBCPP_END_NAMESPACE_STD
557554

555+
// Work around the visibility on a namespace bleed into user specializations.
556+
// TODO: Remove this workaround once all supported compilers are fixed
557+
namespace std {
558+
inline namespace _LIBCPP_ABI_NAMESPACE {
559+
template <class _Tp>
560+
struct hash : public __enum_hash<_Tp> {};
561+
} // namespace _LIBCPP_ABI_NAMESPACE
562+
} // namespace std
563+
558564
#endif // _LIBCPP___FUNCTIONAL_HASH_H

libcxx/include/__fwd/functional.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@
1515
# pragma GCC system_header
1616
#endif
1717

18+
// Work around the visibility on a namespace bleed into user specializations.
19+
// TODO: Remove this workaround once all supported compilers are fixed
20+
namespace std {
21+
inline namespace _LIBCPP_ABI_NAMESPACE {
22+
template <class>
23+
struct hash;
24+
} // namespace _LIBCPP_ABI_NAMESPACE
25+
} // namespace std
26+
1827
_LIBCPP_BEGIN_NAMESPACE_STD
1928

2029
#if _LIBCPP_STD_VER >= 14
@@ -24,9 +33,6 @@ template <class _Tp>
2433
#endif
2534
struct less;
2635

27-
template <class>
28-
struct hash;
29-
3036
template <class>
3137
class reference_wrapper;
3238

libcxx/include/bitset

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -641,11 +641,6 @@ inline _LIBCPP_CONSTEXPR __bitset<0, 0>::__bitset() _NOEXCEPT {}
641641

642642
inline _LIBCPP_CONSTEXPR __bitset<0, 0>::__bitset(unsigned long long) _NOEXCEPT {}
643643

644-
template <size_t _Size>
645-
class bitset;
646-
template <size_t _Size>
647-
struct hash<bitset<_Size> >;
648-
649644
template <size_t _Size>
650645
class bitset : private __bitset<_Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1, _Size> {
651646
public:

libcxx/include/typeindex

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct hash<type_index>
5050
#else
5151
# include <__config>
5252
# include <__functional/unary_function.h>
53+
# include <__fwd/functional.h>
5354
# include <typeinfo>
5455
# include <version>
5556

@@ -90,9 +91,6 @@ public:
9091
_LIBCPP_HIDE_FROM_ABI const char* name() const _NOEXCEPT { return __t_->name(); }
9192
};
9293

93-
template <class _Tp>
94-
struct hash;
95-
9694
template <>
9795
struct hash<type_index> : public __unary_function<type_index, size_t> {
9896
_LIBCPP_HIDE_FROM_ABI size_t operator()(type_index __index) const _NOEXCEPT { return __index.hash_code(); }
Lines changed: 33 additions & 0 deletions
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+
// Ensure that user specializations of std::hash have default visibility
10+
11+
// RUN: %{cxx} %s %{flags} %{compile_flags} %{link_flags} -DSHARED -fPIC -shared -o %t.shared_lib
12+
// RUN: %{build} %t.shared_lib
13+
// RUN: %{run}
14+
15+
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
16+
17+
#include <__functional/hash.h>
18+
19+
struct S {};
20+
21+
template <>
22+
struct std::hash<S> {
23+
void operator()();
24+
};
25+
26+
#ifdef SHARED
27+
void std::hash<S>::operator()() {}
28+
#else
29+
int main(int, char**) {
30+
std::hash<S>()();
31+
return 0;
32+
}
33+
#endif
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
// Ensure that user specializations of std::hash have default visibility
10+
11+
// RUN: %{cxx} %s %{flags} %{compile_flags} %{link_flags} -DSHARED -fPIC -shared -o %t.shared_lib
12+
// RUN: %{build} %t.shared_lib
13+
// RUN: %{run}
14+
15+
#include <__fwd/functional.h>
16+
17+
struct S {};
18+
19+
template <>
20+
struct std::hash<S> {
21+
void operator()();
22+
};
23+
24+
#ifdef SHARED
25+
void std::hash<S>::operator()() {}
26+
#else
27+
int main(int, char**) {
28+
std::hash<S>()();
29+
return 0;
30+
}
31+
#endif

0 commit comments

Comments
 (0)