Skip to content

[libc++] __uglify non-conforming member typedef base #112843

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

Merged
merged 1 commit into from
Oct 18, 2024

Conversation

frederick-vs-ja
Copy link
Contributor

@frederick-vs-ja frederick-vs-ja commented Oct 18, 2024

Currently, libc++'s bitset, forward_list, and list have non-conforming member typedef name base. The typedef is private, but can cause ambiguity in name lookup.

Some other classes in libc++ that are either implementation details or not precisely specified by the standard also have member typdef base. I think this can still be conforming.

Follows up #80706 and #111127.

@frederick-vs-ja frederick-vs-ja requested a review from a team as a code owner October 18, 2024 06:04
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Oct 18, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 18, 2024

@llvm/pr-subscribers-libcxx

Author: A. Jiang (frederick-vs-ja)

Changes

Currently, libc++'s bitset, forward_list, and list have non-conforming member typedef name base. The typedef is private, but can cause ambiguity in name lookup.

Some other classes in libc++ that are either implementation details or not precisely specified by the standard also have member typdef base. I think this can still be conforming.

Drive-by change: Using using typename __base:: to introduce member typedefs for short.

Follows up #80706 and #111127.


Patch is 50.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/112843.diff

7 Files Affected:

  • (modified) libcxx/docs/ReleaseNotes/20.rst (+3-3)
  • (modified) libcxx/include/bitset (+26-26)
  • (modified) libcxx/include/forward_list (+57-52)
  • (modified) libcxx/include/list (+96-95)
  • (modified) libcxx/test/std/containers/sequences/forwardlist/types.pass.cpp (+18)
  • (modified) libcxx/test/std/containers/sequences/list/types.pass.cpp (+18)
  • (modified) libcxx/test/std/utilities/template.bitset/bitset.members/nonstdmem.uglified.compile.pass.cpp (+13-2)
diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index abd6764579e52a..44912d2ddafac6 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -78,9 +78,9 @@ 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 ``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.
+- 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.
 
 - 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.)
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index f90ceaab816cca..a66c670c215a54 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -612,15 +612,15 @@ class _LIBCPP_TEMPLATE_VIS bitset
     : private __bitset<_Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1, _Size> {
 public:
   static const unsigned __n_words = _Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1;
-  typedef __bitset<__n_words, _Size> base;
+  typedef __bitset<__n_words, _Size> __base;
 
 public:
-  typedef typename base::reference reference;
-  typedef typename base::const_reference const_reference;
+  using typename __base::reference;
+  using typename __base::const_reference;
 
   // 23.3.5.1 constructors:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT : base(__v) {}
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT : __base(__v) {}
   template <class _CharT, __enable_if_t<_IsCharLikeType<_CharT>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
       const _CharT* __str,
@@ -681,11 +681,11 @@ public:
 
   // element access:
 #ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const { return base::__make_ref(__p); }
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const { return __base::__make_ref(__p); }
 #else
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference operator[](size_t __p) const { return base::__make_ref(__p); }
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference operator[](size_t __p) const { return __base::__make_ref(__p); }
 #endif
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference operator[](size_t __p) { return base::__make_ref(__p); }
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference operator[](size_t __p) { return __base::__make_ref(__p); }
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const;
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const;
   template <class _CharT, class _Traits, class _Allocator>
@@ -726,10 +726,10 @@ private:
       _CharT __c   = __str[__mp - 1 - __i];
       (*this)[__i] = _Traits::eq(__c, __one);
     }
-    std::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
+    std::fill(__base::__make_iter(__i), __base::__make_iter(_Size), false);
   }
 
-  _LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT { return base::__hash_code(); }
+  _LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT { return __base::__hash_code(); }
 
   friend struct hash<bitset>;
 };
@@ -737,43 +737,43 @@ private:
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>&
 bitset<_Size>::operator&=(const bitset& __rhs) _NOEXCEPT {
-  base::operator&=(__rhs);
+  __base::operator&=(__rhs);
   return *this;
 }
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>&
 bitset<_Size>::operator|=(const bitset& __rhs) _NOEXCEPT {
-  base::operator|=(__rhs);
+  __base::operator|=(__rhs);
   return *this;
 }
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>&
 bitset<_Size>::operator^=(const bitset& __rhs) _NOEXCEPT {
-  base::operator^=(__rhs);
+  __base::operator^=(__rhs);
   return *this;
 }
 
 template <size_t _Size>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::operator<<=(size_t __pos) _NOEXCEPT {
   __pos = std::min(__pos, _Size);
-  std::copy_backward(base::__make_iter(0), base::__make_iter(_Size - __pos), base::__make_iter(_Size));
-  std::fill_n(base::__make_iter(0), __pos, false);
+  std::copy_backward(__base::__make_iter(0), __base::__make_iter(_Size - __pos), __base::__make_iter(_Size));
+  std::fill_n(__base::__make_iter(0), __pos, false);
   return *this;
 }
 
 template <size_t _Size>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::operator>>=(size_t __pos) _NOEXCEPT {
   __pos = std::min(__pos, _Size);
-  std::copy(base::__make_iter(__pos), base::__make_iter(_Size), base::__make_iter(0));
-  std::fill_n(base::__make_iter(_Size - __pos), __pos, false);
+  std::copy(__base::__make_iter(__pos), __base::__make_iter(_Size), __base::__make_iter(0));
+  std::fill_n(__base::__make_iter(_Size - __pos), __pos, false);
   return *this;
 }
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::set() _NOEXCEPT {
-  std::fill_n(base::__make_iter(0), _Size, true);
+  std::fill_n(__base::__make_iter(0), _Size, true);
   return *this;
 }
 
@@ -788,7 +788,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::reset() _NOEXCEPT {
-  std::fill_n(base::__make_iter(0), _Size, false);
+  std::fill_n(__base::__make_iter(0), _Size, false);
   return *this;
 }
 
@@ -810,7 +810,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size> bitset<
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::flip() _NOEXCEPT {
-  base::flip();
+  __base::flip();
   return *this;
 }
 
@@ -819,19 +819,19 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>
   if (__pos >= _Size)
     __throw_out_of_range("bitset flip argument out of range");
 
-  reference __r = base::__make_ref(__pos);
+  reference __r = __base::__make_ref(__pos);
   __r           = ~__r;
   return *this;
 }
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long bitset<_Size>::to_ulong() const {
-  return base::to_ulong();
+  return __base::to_ulong();
 }
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long bitset<_Size>::to_ullong() const {
-  return base::to_ullong();
+  return __base::to_ullong();
 }
 
 template <size_t _Size>
@@ -868,13 +868,13 @@ bitset<_Size>::to_string(char __zero, char __one) const {
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t bitset<_Size>::count() const _NOEXCEPT {
-  return static_cast<size_t>(std::count(base::__make_iter(0), base::__make_iter(_Size), true));
+  return static_cast<size_t>(std::count(__base::__make_iter(0), __base::__make_iter(_Size), true));
 }
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
 bitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT {
-  return std::equal(base::__make_iter(0), base::__make_iter(_Size), __rhs.__make_iter(0));
+  return std::equal(__base::__make_iter(0), __base::__make_iter(_Size), __rhs.__make_iter(0));
 }
 
 #if _LIBCPP_STD_VER <= 17
@@ -896,12 +896,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool bitset<_Size>::test(siz
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool bitset<_Size>::all() const _NOEXCEPT {
-  return base::all();
+  return __base::all();
 }
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool bitset<_Size>::any() const _NOEXCEPT {
-  return base::any();
+  return __base::any();
 }
 
 template <size_t _Size>
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index d3262fb8eaed1f..5f28f9a83048c7 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -640,12 +640,12 @@ void __forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT {
 
 template <class _Tp, class _Alloc /*= allocator<_Tp>*/>
 class _LIBCPP_TEMPLATE_VIS forward_list : private __forward_list_base<_Tp, _Alloc> {
-  typedef __forward_list_base<_Tp, _Alloc> base;
-  typedef typename base::__node_allocator __node_allocator;
-  typedef typename base::__node_type __node_type;
-  typedef typename base::__node_traits __node_traits;
-  typedef typename base::__node_pointer __node_pointer;
-  typedef typename base::__begin_node_pointer __begin_node_pointer;
+  typedef __forward_list_base<_Tp, _Alloc> __base;
+  using typename __base::__begin_node_pointer;
+  using typename __base::__node_allocator;
+  using typename __base::__node_pointer;
+  using typename __base::__node_traits;
+  using typename __base::__node_type;
 
 public:
   typedef _Tp value_type;
@@ -666,8 +666,8 @@ public:
   typedef typename allocator_traits<allocator_type>::size_type size_type;
   typedef typename allocator_traits<allocator_type>::difference_type difference_type;
 
-  typedef typename base::iterator iterator;
-  typedef typename base::const_iterator const_iterator;
+  using typename __base::const_iterator;
+  using typename __base::iterator;
 #if _LIBCPP_STD_VER >= 20
   typedef size_type __remove_return_type;
 #else
@@ -684,7 +684,7 @@ public:
   _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v);
 
   template <__enable_if_t<__is_allocator<_Alloc>::value, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a) {
+  _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : __base(__a) {
     insert_after(cbefore_begin(), __n, __v);
   }
 
@@ -697,7 +697,7 @@ public:
 #if _LIBCPP_STD_VER >= 23
   template <_ContainerCompatibleRange<_Tp> _Range>
   _LIBCPP_HIDE_FROM_ABI forward_list(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type())
-      : base(__a) {
+      : __base(__a) {
     prepend_range(std::forward<_Range>(__range));
   }
 #endif
@@ -708,8 +708,8 @@ public:
   _LIBCPP_HIDE_FROM_ABI forward_list& operator=(const forward_list& __x);
 
 #ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x) noexcept(is_nothrow_move_constructible<base>::value)
-      : base(std::move(__x)) {}
+  _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x) noexcept(is_nothrow_move_constructible<__base>::value)
+      : __base(std::move(__x)) {}
   _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a);
 
   _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il);
@@ -738,35 +738,37 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v);
 
-  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(base::__alloc()); }
+  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(__base::__alloc()); }
 
-  _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(base::__before_begin()->__next_); }
+  _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__base::__before_begin()->__next_); }
   _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {
-    return const_iterator(base::__before_begin()->__next_);
+    return const_iterator(__base::__before_begin()->__next_);
   }
   _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(nullptr); }
   _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return const_iterator(nullptr); }
 
   _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
-    return const_iterator(base::__before_begin()->__next_);
+    return const_iterator(__base::__before_begin()->__next_);
   }
   _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return const_iterator(nullptr); }
 
-  _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT { return iterator(base::__before_begin()); }
-  _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT { return const_iterator(base::__before_begin()); }
+  _LIBCPP_HIDE_FROM_ABI iterator before_begin() _NOEXCEPT { return iterator(__base::__before_begin()); }
+  _LIBCPP_HIDE_FROM_ABI const_iterator before_begin() const _NOEXCEPT {
+    return const_iterator(__base::__before_begin());
+  }
   _LIBCPP_HIDE_FROM_ABI const_iterator cbefore_begin() const _NOEXCEPT {
-    return const_iterator(base::__before_begin());
+    return const_iterator(__base::__before_begin());
   }
 
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT {
-    return base::__before_begin()->__next_ == nullptr;
+    return __base::__before_begin()->__next_ == nullptr;
   }
   _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
-    return std::min<size_type>(__node_traits::max_size(base::__alloc()), numeric_limits<difference_type>::max());
+    return std::min<size_type>(__node_traits::max_size(__base::__alloc()), numeric_limits<difference_type>::max());
   }
 
-  _LIBCPP_HIDE_FROM_ABI reference front() { return base::__before_begin()->__next_->__get_value(); }
-  _LIBCPP_HIDE_FROM_ABI const_reference front() const { return base::__before_begin()->__next_->__get_value(); }
+  _LIBCPP_HIDE_FROM_ABI reference front() { return __base::__before_begin()->__next_->__get_value(); }
+  _LIBCPP_HIDE_FROM_ABI const_reference front() const { return __base::__before_begin()->__next_->__get_value(); }
 
 #ifndef _LIBCPP_CXX03_LANG
 #  if _LIBCPP_STD_VER >= 17
@@ -823,12 +825,12 @@ public:
       _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)
 #endif
   {
-    base::swap(__x);
+    __base::swap(__x);
   }
 
   _LIBCPP_HIDE_FROM_ABI void resize(size_type __n);
   _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v);
-  _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { base::clear(); }
+  _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __base::clear(); }
 
   _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list&& __x);
   _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
@@ -899,12 +901,12 @@ forward_list(from_range_t, _Range&&, _Alloc = _Alloc()) -> forward_list<ranges::
 #endif
 
 template <class _Tp, class _Alloc>
-inline forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) : base(__a) {}
+inline forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) : __base(__a) {}
 
 template <class _Tp, class _Alloc>
 forward_list<_Tp, _Alloc>::forward_list(size_type __n) {
   if (__n > 0) {
-    for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) {
+    for (__begin_node_pointer __p = __base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) {
       __p->__next_ = this->__create_node(/* next = */ nullptr);
     }
   }
@@ -912,9 +914,9 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n) {
 
 #if _LIBCPP_STD_VER >= 14
 template <class _Tp, class _Alloc>
-forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __base_alloc) : base(__base_alloc) {
+forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __base_alloc) : __base(__base_alloc) {
   if (__n > 0) {
-    for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) {
+    for (__begin_node_pointer __p = __base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) {
       __p->__next_ = this->__create_node(/* next = */ nullptr);
     }
   }
@@ -934,26 +936,27 @@ forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l)
 
 template <class _Tp, class _Alloc>
 template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
-forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : base(__a) {
+forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
+    : __base(__a) {
   insert_after(cbefore_begin(), __f, __l);
 }
 
 template <class _Tp, class _Alloc>
 forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
-    : base(__node_traits::select_on_container_copy_construction(__x.__alloc())) {
+    : __base(__node_traits::select_on_container_copy_construction(__x.__alloc())) {
   insert_after(cbefore_begin(), __x.begin(), __x.end());
 }
 
 template <class _Tp, class _Alloc>
 forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a)
-    : base(__a) {
+    : __base(__a) {
   insert_after(cbefore_begin(), __x.begin(), __x.end());
 }
 
 template <class _Tp, class _Alloc>
 forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(const forward_list& __x) {
   if (this != std::addressof(__x)) {
-    base::__copy_assign_alloc(__x);
+    __base::__copy_assign_alloc(__x);
     assign(__x.begin(), __x.end());
   }
   return *this;
@@ -962,8 +965,8 @@ forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(const forward_li
 #ifndef _LIBCPP_CXX03_LANG
 template <class _Tp, class _Alloc>
 forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a)
-    : base(std::move(__x), __a) {
-  if (base::__alloc() != __x.__alloc()) {
+    : __base(std::move(__x), __a) {
+  if (__base::__alloc() != __x.__alloc()) {
     typedef move_iterator<iterator> _Ip;
     insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
   }
@@ -975,7 +978,7 @@ forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il) {
 }
 
 template <class _Tp, class _Alloc>
-forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il, const allocator_type& __a) : base(__a) {
+forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il, const allocator_type& __a) : __base(__a) {
   insert_after(cbefore_begin(), __il.begin(), __il.end());
 }
 
@@ -983,14 +986,14 @@ template <class _Tp, class _Alloc>
 void forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
   clear();
-  base::__move_assign_alloc(__x);
-  base::__before_begin()->__next_ = __x.__before_begin()->__next_;
-  __x.__before_begin()->__next_   = nullptr;
+  __base::__move_assign_alloc(__x);
+  __base::__before_begin()->__next_ = __x.__before_begin()->__next_;
+  __x.__before_begin()->__next_     = nullptr;
 }
 
 template <class _Tp, class _Alloc>
 void forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type) {
-  if (base::__alloc() == __x.__alloc())
+  if (__base::__alloc() == __x.__alloc())
     __move_assign(__x, true_type());
   else {
     typedef move_iterator<iterator> _Ip;
@@ -1061,29 +1064,30 @@ typename forward_list<_Tp, _Alloc>::reference
 void
 #  endif
 forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) {
-  base::__before_begin()->__next_ =
-      this->__create_node(/* next = */ base::__before_begin()->__next_, std::forward<_Args>(__args)...);
+  __base::__before_begin()->__next_ =
+      this->__create_node(/* next = */ __base::__before_begin()->__next_, std::forward<_Args>(__args)...);
 #  if _LIBCPP_STD_VER >= 17
-  return base::__before_begin()->__next_->__get_value();
+  return __base::__before_begin()->__next_->__get_value();
 #  endif
 }
 
 template <class _Tp, class _Alloc>
 void fo...
[truncated]

Copy link

github-actions bot commented Oct 18, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@frederick-vs-ja frederick-vs-ja force-pushed the __uglify-member-base branch 2 times, most recently from 3658fd2 to 0c84981 Compare October 18, 2024 06:26
Currently, libc++'s `bitset`, `forward_list`, and `list` have
non-conforming member typedef name `base`. The typedef is private, but
can cause ambiguity in name lookup.

Some other classes in libc++ that are either implementation details or
not precisely specified by the standard also have member typdef `base`.
I think this can still be conforming.
@frederick-vs-ja frederick-vs-ja merged commit 397707f into llvm:main Oct 18, 2024
68 checks passed
@frederick-vs-ja frederick-vs-ja deleted the __uglify-member-base branch October 18, 2024 15:27
frederick-vs-ja pushed a commit that referenced this pull request Jan 9, 2025
…#121620)

According to
[[template.bitset.general]](https://eel.is/c++draft/template.bitset.general),
`std::bitset` is supposed to have only
one (public) member typedef, `reference`. However, libc++'s
implementation of `std::bitset` offers more that that. Specifically, it
offers a public typedef `const_reference` and two private typedefs
`size_type` and `difference_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 typedefs
`size_type` and `difference_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 address `size_type` and
`difference_type`.

Follows up #80706, #111127, and #112843,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants