diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst index 9fcb0bbe9830..88282526859a 100644 --- a/libcxx/docs/ReleaseNotes/23.rst +++ b/libcxx/docs/ReleaseNotes/23.rst @@ -58,6 +58,9 @@ Deprecations and Removals - In ``__wrap_iter`` (iterator wrapper type for ``array``, ``span``, ``string``, ``string_view`` and ``vector``), the ``base()`` method and ``iterator_type`` member type have been removed as they are non-standard. +- In ``__bit_reference`` (the proxy ``reference`` type of ``bitset`` and ``vector``), the overloaded ``operator&`` + is removed as it is non-standard and causes non-conforming behavior. + Potentially breaking changes ---------------------------- diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference index 5155f18754b5..6bbe28967f57 100644 --- a/libcxx/include/__bit_reference +++ b/libcxx/include/__bit_reference @@ -165,9 +165,6 @@ public: } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT { *__seg_ ^= __mask_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT { - return __bit_iterator<_Cp, false>(__seg_, static_cast(std::__countr_zero(__mask_))); - } private: _LIBCPP_HIDE_FROM_ABI diff --git a/libcxx/test/std/containers/sequences/vector.bool/reference/builtin_address_of.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/reference/builtin_address_of.pass.cpp new file mode 100644 index 000000000000..ec2fa595a163 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector.bool/reference/builtin_address_of.pass.cpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// template +// class vector::reference; + +// Verify that vector::reference has no overloaded operator&. + +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + +#include +#include +#include +#include +#include + +#include "test_macros.h" +#include "min_allocator.h" + +namespace test_overloads { + +struct dummy {}; +void operator&(dummy); + +template +struct has_nonmember_operator_address_of : std::false_type {}; +template +struct has_nonmember_operator_address_of()))> : std::true_type {}; + +template +struct has_member_operator_address_of : std::false_type {}; +template +struct has_member_operator_address_of().operator&())> : std::true_type {}; + +} // namespace test_overloads + +template +struct can_take_address : std::false_type {}; +template +struct can_take_address())> : std::true_type {}; + +template +struct has_builtin_operator_address_of : std::false_type {}; +template +struct has_builtin_operator_address_of())> + : std::integral_constant::value && + !test_overloads::has_member_operator_address_of::value> {}; + +template +TEST_CONSTEXPR_CXX20 void test_proxy_references(Ref& r1, Ref& r2) { + static_assert(can_take_address::value, ""); + static_assert(can_take_address::value, ""); + static_assert(!can_take_address::value, ""); + static_assert(!can_take_address::value, ""); + + static_assert(has_builtin_operator_address_of::value, ""); + static_assert(has_builtin_operator_address_of::value, ""); + static_assert(!has_builtin_operator_address_of::value, ""); + static_assert(!has_builtin_operator_address_of::value, ""); + + static_assert(std::is_same::value, ""); + + assert(std::addressof(r1) == &r1); + assert(std::addressof(r2) == &r2); + assert((std::addressof(r1) == std::addressof(r2)) == (&r1 == &r2)); +} + +template +TEST_CONSTEXPR_CXX20 void test() { + VB vec(1); + + typename VB::reference r1 = vec[0]; + typename VB::reference r2 = vec[0]; + test_proxy_references(r1, r2); + assert(&r1 != &r2); +} + +TEST_CONSTEXPR_CXX20 bool test() { + test >(); +#if TEST_STD_VER >= 11 + test>>(); +#endif + + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 20 + static_assert(test()); +#endif + + return 0; +} diff --git a/libcxx/test/std/utilities/template.bitset/bitset.members/reference.builtin_address_of.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/reference.builtin_address_of.pass.cpp new file mode 100644 index 000000000000..bd004934595a --- /dev/null +++ b/libcxx/test/std/utilities/template.bitset/bitset.members/reference.builtin_address_of.pass.cpp @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// template +// class bitset::reference; + +// Verify that bitset::reference has no overloaded operator&. + +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + +#include +#include +#include +#include +#include + +#include "test_macros.h" + +namespace test_overloads { + +struct dummy {}; +void operator&(dummy); + +template +struct has_nonmember_operator_address_of : std::false_type {}; +template +struct has_nonmember_operator_address_of()))> : std::true_type {}; + +template +struct has_member_operator_address_of : std::false_type {}; +template +struct has_member_operator_address_of().operator&())> : std::true_type {}; + +} // namespace test_overloads + +template +struct can_take_address : std::false_type {}; +template +struct can_take_address())> : std::true_type {}; + +template +struct has_builtin_operator_address_of : std::false_type {}; +template +struct has_builtin_operator_address_of())> + : std::integral_constant::value && + !test_overloads::has_member_operator_address_of::value> {}; + +template +TEST_CONSTEXPR_CXX23 void test_proxy_references(Ref& r1, Ref& r2) { + static_assert(can_take_address::value, ""); + static_assert(can_take_address::value, ""); + static_assert(!can_take_address::value, ""); + static_assert(!can_take_address::value, ""); + + static_assert(has_builtin_operator_address_of::value, ""); + static_assert(has_builtin_operator_address_of::value, ""); + static_assert(!has_builtin_operator_address_of::value, ""); + static_assert(!has_builtin_operator_address_of::value, ""); + + static_assert(std::is_same::value, ""); + + assert(std::addressof(r1) == &r1); + assert(std::addressof(r2) == &r2); + assert((std::addressof(r1) == std::addressof(r2)) == (&r1 == &r2)); +} + +template +TEST_CONSTEXPR_CXX23 void test() { + Bitset bs; + + typename Bitset::reference r1 = bs[0]; + typename Bitset::reference r2 = bs[0]; + test_proxy_references(r1, r2); + assert(&r1 != &r2); +} + +TEST_CONSTEXPR_CXX23 bool test() { + test >(); + test >(); + test >(); + test >(); + test >(); + test >(); + test >(); + test >(); + test >(); + test >(); + test >(); + + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + + return 0; +}