From 159d694c05500a656775f4cbd6931dae9aab290a Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 10 Oct 2024 21:14:05 +0800 Subject: [PATCH] [libc++] __uglify internal member names of iterators in `bitset` (#111127) [template.bitset.general] indicates that `bitset` shouldn't have member typedef-names `iterator` and `const_iterator`. Currently libc++'s typedef-names are causing ambiguity in name lookup, which isn't conforming. As these iterator types are themselves useful, I think we should just use __uglified member typedef-names for them. Fixes #111125 --- libcxx/docs/ReleaseNotes/20.rst | 4 ++ libcxx/include/bitset | 44 +++++++++--------- .../nonstdmem.uglified.compile.pass.cpp | 46 +++++++++++++++++++ 3 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 libcxx/test/std/utilities/template.bitset/bitset.members/nonstdmem.uglified.compile.pass.cpp diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst index dcb1102d81d64..3a66aecaf57cb 100644 --- a/libcxx/docs/ReleaseNotes/20.rst +++ b/libcxx/docs/ReleaseNotes/20.rst @@ -78,6 +78,10 @@ Deprecations and Removals supported as an extension anymore, please migrate any code that uses e.g. ``std::vector`` to be standards conforming. +- Non-conforming member typedefs ``iterator`` and ``const_iterator`` of ``std::bitset`` 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. + Upcoming Deprecations and Removals ---------------------------------- diff --git a/libcxx/include/bitset b/libcxx/include/bitset index ce23d522168c4..f90ceaab816cc 100644 --- a/libcxx/include/bitset +++ b/libcxx/include/bitset @@ -187,8 +187,8 @@ protected: typedef __bit_reference<__bitset> reference; typedef __bit_const_reference<__bitset> const_reference; - typedef __bit_iterator<__bitset, false> iterator; - typedef __bit_iterator<__bitset, true> const_iterator; + typedef __bit_iterator<__bitset, false> __iterator; + typedef __bit_iterator<__bitset, true> __const_iterator; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT; @@ -199,11 +199,11 @@ protected: _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); + _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); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const_iterator __make_iter(size_t __pos) const _NOEXCEPT { - return const_iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __const_iterator __make_iter(size_t __pos) const _NOEXCEPT { + return __const_iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator&=(const __bitset& __v) _NOEXCEPT; @@ -335,8 +335,8 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<_N_words, _Siz template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<_N_words, _Size>::to_ulong(false_type) const { - const_iterator __e = __make_iter(_Size); - const_iterator __i = std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true); + __const_iterator __e = __make_iter(_Size); + __const_iterator __i = std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true); if (__i != __e) __throw_overflow_error("bitset to_ulong overflow error"); @@ -352,8 +352,8 @@ __bitset<_N_words, _Size>::to_ulong(true_type) const { template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __bitset<_N_words, _Size>::to_ullong(false_type) const { - const_iterator __e = __make_iter(_Size); - const_iterator __i = std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true); + __const_iterator __e = __make_iter(_Size); + __const_iterator __i = std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true); if (__i != __e) __throw_overflow_error("bitset to_ullong overflow error"); @@ -449,8 +449,8 @@ protected: typedef __bit_reference<__bitset> reference; typedef __bit_const_reference<__bitset> const_reference; - typedef __bit_iterator<__bitset, false> iterator; - typedef __bit_iterator<__bitset, true> const_iterator; + typedef __bit_iterator<__bitset, false> __iterator; + typedef __bit_iterator<__bitset, true> __const_iterator; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT; @@ -461,11 +461,11 @@ protected: _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); + _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); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const_iterator __make_iter(size_t __pos) const _NOEXCEPT { - return const_iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __const_iterator __make_iter(size_t __pos) const _NOEXCEPT { + return __const_iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator&=(const __bitset& __v) _NOEXCEPT; @@ -564,8 +564,8 @@ protected: typedef __bit_reference<__bitset> reference; typedef __bit_const_reference<__bitset> const_reference; - typedef __bit_iterator<__bitset, false> iterator; - typedef __bit_iterator<__bitset, true> const_iterator; + typedef __bit_iterator<__bitset, false> __iterator; + typedef __bit_iterator<__bitset, true> __const_iterator; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT; _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long) _NOEXCEPT; @@ -576,11 +576,11 @@ protected: _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); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __iterator __make_iter(size_t) _NOEXCEPT { + return __iterator(nullptr, 0); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 const_iterator __make_iter(size_t) const _NOEXCEPT { - return const_iterator(nullptr, 0); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __const_iterator __make_iter(size_t) const _NOEXCEPT { + return __const_iterator(nullptr, 0); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator&=(const __bitset&) _NOEXCEPT {} 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 new file mode 100644 index 0000000000000..c9dd923d7130f --- /dev/null +++ b/libcxx/test/std/utilities/template.bitset/bitset.members/nonstdmem.uglified.compile.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// This test ensures that we don't use a non-uglified name 'iterator' and +// 'const_iterator' in the implementation of bitset. +// +// See https://github.com/llvm/llvm-project/issues/111125. + +#include +#include +#include + +struct my_base { + typedef int* iterator; + typedef const int* const_iterator; +}; + +template +struct my_derived : my_base, std::bitset {}; + +static_assert(std::is_same::iterator, int*>::value, ""); +static_assert(std::is_same::iterator, int*>::value, ""); +static_assert(std::is_same::iterator, int*>::value, ""); +static_assert(std::is_same::iterator, int*>::value, ""); +static_assert(std::is_same::iterator, int*>::value, ""); +static_assert(std::is_same::iterator, int*>::value, ""); +static_assert(std::is_same::iterator, int*>::value, ""); +static_assert(std::is_same::iterator, int*>::value, ""); +static_assert(std::is_same::iterator, int*>::value, ""); + +static_assert(std::is_same::const_iterator, const int*>::value, ""); +static_assert(std::is_same::const_iterator, const int*>::value, ""); +static_assert(std::is_same::const_iterator, const int*>::value, ""); +static_assert(std::is_same::const_iterator, const int*>::value, ""); +static_assert(std::is_same::const_iterator, const int*>::value, ""); +static_assert(std::is_same::const_iterator, const int*>::value, ""); +static_assert(std::is_same::const_iterator, const int*>::value, ""); +static_assert(std::is_same::const_iterator, const int*>::value, ""); +static_assert(std::is_same::const_iterator, const int*>::value, "");