-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc++] Uglify non-standard member typedef const_reference in bitset #121620
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc++] Uglify non-standard member typedef const_reference in bitset #121620
Conversation
e4f1d20
to
f6a9d40
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
f6a9d40
to
b97c017
Compare
@llvm/pr-subscribers-libcxx Author: Peng Liu (winner245) ChangesAccording to [template.bitset.general], Fixing the public member typedef This PR fixes the member typedef Follows up #80706, #111127, and #112843, Full diff: https://github.com/llvm/llvm-project/pull/121620.diff 4 Files Affected:
diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index c8a07fb8b73348..913c2d8ff6380e 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -92,9 +92,10 @@ Deprecations and Removals
supported as an extension anymore, please migrate any code that uses e.g. ``std::vector<const T>`` to be
standards conforming.
-- Non-conforming member typedefs ``base``, ``iterator`` and ``const_iterator`` of ``std::bitset``, and member typedef
- ``base`` of ``std::forward_list`` and ``std::list`` are removed. Previously, they were private but could cause
- ambiguity in name lookup. Code that expects such ambiguity will possibly not compile in LLVM 20.
+- Non-conforming member typedefs ``base``, ``iterator``, ``const_iterator``, and ``const_reference`` of ``std::bitset``,
+ and member typedef ``base`` of ``std::forward_list`` and ``std::list`` are removed. Previously, these member typedefs
+ (except ``const_reference``) were private but could cause ambiguity in name lookup. Code that expects such ambiguity
+ will possibly not compile in LLVM 20.
- The function ``__libcpp_verbose_abort()`` is now ``noexcept``, to match ``std::terminate()``. (The combination of
``noexcept`` and ``[[noreturn]]`` has special significance for function effects analysis.) For backwards compatibility,
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index 919d2a0f07e096..c16635dc8092cd 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -189,7 +189,7 @@ protected:
__storage_type __first_[_N_words];
typedef __bit_reference<__bitset> reference;
- typedef __bit_const_reference<__bitset> const_reference;
+ typedef __bit_const_reference<__bitset> __const_reference;
typedef __bit_iterator<__bitset, false> __iterator;
typedef __bit_iterator<__bitset, true> __const_iterator;
@@ -199,8 +199,8 @@ protected:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference __make_ref(size_t __pos) _NOEXCEPT {
return reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT {
- return const_reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference __make_ref(size_t __pos) const _NOEXCEPT {
+ return __const_reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __iterator __make_iter(size_t __pos) _NOEXCEPT {
return __iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);
@@ -451,7 +451,7 @@ protected:
__storage_type __first_;
typedef __bit_reference<__bitset> reference;
- typedef __bit_const_reference<__bitset> const_reference;
+ typedef __bit_const_reference<__bitset> __const_reference;
typedef __bit_iterator<__bitset, false> __iterator;
typedef __bit_iterator<__bitset, true> __const_iterator;
@@ -461,8 +461,8 @@ protected:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference __make_ref(size_t __pos) _NOEXCEPT {
return reference(&__first_, __storage_type(1) << __pos);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT {
- return const_reference(&__first_, __storage_type(1) << __pos);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference __make_ref(size_t __pos) const _NOEXCEPT {
+ return __const_reference(&__first_, __storage_type(1) << __pos);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __iterator __make_iter(size_t __pos) _NOEXCEPT {
return __iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);
@@ -566,7 +566,7 @@ protected:
friend struct __bit_array<__bitset>;
typedef __bit_reference<__bitset> reference;
- typedef __bit_const_reference<__bitset> const_reference;
+ typedef __bit_const_reference<__bitset> __const_reference;
typedef __bit_iterator<__bitset, false> __iterator;
typedef __bit_iterator<__bitset, true> __const_iterator;
@@ -576,8 +576,8 @@ protected:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference __make_ref(size_t) _NOEXCEPT {
return reference(nullptr, 1);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference __make_ref(size_t) const _NOEXCEPT {
- return const_reference(nullptr, 1);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference __make_ref(size_t) const _NOEXCEPT {
+ return __const_reference(nullptr, 1);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __iterator __make_iter(size_t) _NOEXCEPT {
return __iterator(nullptr, 0);
@@ -619,7 +619,7 @@ public:
public:
typedef typename __base::reference reference;
- typedef typename __base::const_reference const_reference;
+ typedef typename __base::__const_reference __const_reference;
// 23.3.5.1 constructors:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
@@ -689,7 +689,7 @@ public:
return __base::__make_ref(__p);
}
# else
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference operator[](size_t __p) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference operator[](size_t __p) const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
return __base::__make_ref(__p);
}
diff --git a/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp
index 77eb9056bc6d99..bb7e10afc62ea9 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp
@@ -8,6 +8,8 @@
// constexpr bool operator[](size_t pos) const; // constexpr since C++23
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
#include <bitset>
#include <cassert>
#include <cstddef>
@@ -18,17 +20,17 @@
template <std::size_t N>
TEST_CONSTEXPR_CXX23 void test_index_const() {
- std::vector<std::bitset<N> > const cases = get_test_cases<N>();
- for (std::size_t c = 0; c != cases.size(); ++c) {
- std::bitset<N> const v = cases[c];
- if (v.size() > 0) {
- assert(v[N/2] == v.test(N/2));
- }
+ std::vector<std::bitset<N> > const cases = get_test_cases<N>();
+ for (std::size_t c = 0; c != cases.size(); ++c) {
+ std::bitset<N> const v = cases[c];
+ if (v.size() > 0) {
+ assert(v[N / 2] == v.test(N / 2));
}
+ }
#if !defined(_LIBCPP_VERSION) || defined(_LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL)
- ASSERT_SAME_TYPE(decltype(cases[0][0]), bool);
+ ASSERT_SAME_TYPE(decltype(cases[0][0]), bool);
#else
- ASSERT_SAME_TYPE(decltype(cases[0][0]), typename std::bitset<N>::const_reference);
+ ASSERT_SAME_TYPE(decltype(cases[0][0]), typename std::bitset<N>::__const_reference);
#endif
}
@@ -43,10 +45,10 @@ TEST_CONSTEXPR_CXX23 bool test() {
test_index_const<65>();
std::bitset<1> set_;
- set_[0] = false;
+ set_[0] = false;
const auto& set = set_;
- auto b = set[0];
- set_[0] = true;
+ auto b = set[0];
+ set_[0] = true;
#if !defined(_LIBCPP_VERSION) || defined(_LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL)
assert(!b);
#else
diff --git a/libcxx/test/std/utilities/template.bitset/bitset.members/nonstdmem.uglified.compile.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/nonstdmem.uglified.compile.pass.cpp
index ae3ac819b1f9c6..ee5c64f9df5c74 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/nonstdmem.uglified.compile.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/nonstdmem.uglified.compile.pass.cpp
@@ -8,10 +8,11 @@
// <bitset>
-// This test ensures that we don't use a non-uglified name 'iterator',
-// 'const_iterator', and 'base' in the implementation of bitset.
+// This test ensures that we don't use a non-uglified name 'base', 'iterator',
+// 'const_iterator', and `const_reference` in the implementation of bitset.
//
// See https://github.com/llvm/llvm-project/issues/111125.
+// See https://github.com/llvm/llvm-project/issues/121618.
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
@@ -23,6 +24,7 @@ struct my_base {
typedef int* iterator;
typedef const int* const_iterator;
typedef my_base base;
+ typedef const int& const_reference;
};
template <std::size_t N>
@@ -57,3 +59,13 @@ static_assert(std::is_same<my_derived<32>::base, my_base>::value, "");
static_assert(std::is_same<my_derived<48>::base, my_base>::value, "");
static_assert(std::is_same<my_derived<64>::base, my_base>::value, "");
static_assert(std::is_same<my_derived<96>::base, my_base>::value, "");
+
+static_assert(std::is_same<my_derived<0>::const_reference, const int&>::value, "");
+static_assert(std::is_same<my_derived<1>::const_reference, const int&>::value, "");
+static_assert(std::is_same<my_derived<8>::const_reference, const int&>::value, "");
+static_assert(std::is_same<my_derived<12>::const_reference, const int&>::value, "");
+static_assert(std::is_same<my_derived<16>::const_reference, const int&>::value, "");
+static_assert(std::is_same<my_derived<32>::const_reference, const int&>::value, "");
+static_assert(std::is_same<my_derived<48>::const_reference, const int&>::value, "");
+static_assert(std::is_same<my_derived<64>::const_reference, const int&>::value, "");
+static_assert(std::is_same<my_derived<96>::const_reference, const int&>::value, "");
|
According to [template.bitset.general],
std::bitset
is supposed to have onlyone (public) member typedef,
reference
. However, libc++'s implementation ofstd::bitset
offers more that that. Specifically, it offers a public typedefconst_reference
and two private typedefssize_type
anddifference_type
. These non-standard member typedefs, despite being private, can cause potential ambiguities in name lookup in user-defined classes, as demonstrated in issue #121618.Fixing the public member typedef
const_reference
is straightforward: we can simply replace it with an__ugly_name
such as__const_reference
. However, fixing the private member typedefssize_type
anddifference_type
is not so straightforward as they are required by the__bit_iterator
class and the corresponding algorithms optimized for__bit_iterator
s (e.g.,ranges::fill
).This PR fixes the member typedef
const_reference
by using uglified name for it. Further work will be undertaken to addresssize_type
anddifference_type
.Follows up #80706, #111127, and #112843,