[libcxx-commits] [libcxx] [libc++] Fix ambiguity due to non-uglified member typedefs (PR #121664)

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jan 4 13:08:32 PST 2025


https://github.com/winner245 created https://github.com/llvm/llvm-project/pull/121664

This PR fixes the ambiguities in name lookup caused by non-standard member typedefs `size_type` and `difference_type` in `std::bitset`.  

Follows up #121620.
Closes #121618. 

>From 620da4a790b581457c52c08ca5d65b62dac80c86 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Sat, 4 Jan 2025 16:03:15 -0500
Subject: [PATCH] Fix ambiguity due to non-uglified member typedefs

---
 libcxx/include/__algorithm/count.h            |  8 ++--
 libcxx/include/__algorithm/fill_n.h           |  2 +-
 libcxx/include/__algorithm/find.h             |  8 ++--
 libcxx/include/__bit_reference                | 19 ++++++---
 libcxx/include/__fwd/bit_reference.h          |  3 ++
 libcxx/include/bitset                         | 40 +++++++++++--------
 .../nonstdmem.uglified.compile.pass.cpp       | 22 ++++++++++
 7 files changed, 73 insertions(+), 29 deletions(-)

diff --git a/libcxx/include/__algorithm/count.h b/libcxx/include/__algorithm/count.h
index 6910b4f43e9934..cd9125779ec64e 100644
--- a/libcxx/include/__algorithm/count.h
+++ b/libcxx/include/__algorithm/count.h
@@ -44,7 +44,7 @@ __count(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
 // __bit_iterator implementation
 template <bool _ToCount, class _Cp, bool _IsConst>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bit_iterator<_Cp, _IsConst>::difference_type
-__count_bool(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) {
+__count_bool(__bit_iterator<_Cp, _IsConst> __first, typename __size_difference_type_traits<_Cp>::size_type __n) {
   using _It             = __bit_iterator<_Cp, _IsConst>;
   using __storage_type  = typename _It::__storage_type;
   using difference_type = typename _It::difference_type;
@@ -75,8 +75,10 @@ template <class, class _Cp, bool _IsConst, class _Tp, class _Proj, __enable_if_t
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<__bit_iterator<_Cp, _IsConst> >
 __count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) {
   if (__value)
-    return std::__count_bool<true>(__first, static_cast<typename _Cp::size_type>(__last - __first));
-  return std::__count_bool<false>(__first, static_cast<typename _Cp::size_type>(__last - __first));
+    return std::__count_bool<true>(
+        __first, static_cast<typename __size_difference_type_traits<_Cp>::size_type>(__last - __first));
+  return std::__count_bool<false>(
+      __first, static_cast<typename __size_difference_type_traits<_Cp>::size_type>(__last - __first));
 }
 
 template <class _InputIterator, class _Tp>
diff --git a/libcxx/include/__algorithm/fill_n.h b/libcxx/include/__algorithm/fill_n.h
index 5069a72783f348..a7e01c45b92220 100644
--- a/libcxx/include/__algorithm/fill_n.h
+++ b/libcxx/include/__algorithm/fill_n.h
@@ -32,7 +32,7 @@ __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
 
 template <bool _FillVal, class _Cp>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
-__fill_n_bool(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) {
+__fill_n_bool(__bit_iterator<_Cp, false> __first, typename __size_difference_type_traits<_Cp>::size_type __n) {
   using _It            = __bit_iterator<_Cp, false>;
   using __storage_type = typename _It::__storage_type;
 
diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h
index a05d50718595ee..24b8b2f96443c9 100644
--- a/libcxx/include/__algorithm/find.h
+++ b/libcxx/include/__algorithm/find.h
@@ -97,7 +97,7 @@ __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj& __proj) {
 // __bit_iterator implementation
 template <bool _ToFind, class _Cp, bool _IsConst>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst>
-__find_bool(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) {
+__find_bool(__bit_iterator<_Cp, _IsConst> __first, typename __size_difference_type_traits<_Cp>::size_type __n) {
   using _It            = __bit_iterator<_Cp, _IsConst>;
   using __storage_type = typename _It::__storage_type;
 
@@ -135,8 +135,10 @@ template <class _Cp, bool _IsConst, class _Tp, class _Proj, __enable_if_t<__is_i
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, _IsConst>
 __find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) {
   if (static_cast<bool>(__value))
-    return std::__find_bool<true>(__first, static_cast<typename _Cp::size_type>(__last - __first));
-  return std::__find_bool<false>(__first, static_cast<typename _Cp::size_type>(__last - __first));
+    return std::__find_bool<true>(
+        __first, static_cast<typename __size_difference_type_traits<_Cp>::size_type>(__last - __first));
+  return std::__find_bool<false>(
+      __first, static_cast<typename __size_difference_type_traits<_Cp>::size_type>(__last - __first));
 }
 
 // segmented iterator implementation
diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference
index 9fa24c98d493fd..a9bcf6ff4e5533 100644
--- a/libcxx/include/__bit_reference
+++ b/libcxx/include/__bit_reference
@@ -15,6 +15,7 @@
 #include <__bit/countr.h>
 #include <__compare/ordering.h>
 #include <__config>
+#include <__cstddef/ptrdiff_t.h>
 #include <__cstddef/size_t.h>
 #include <__fwd/bit_reference.h>
 #include <__iterator/iterator_traits.h>
@@ -41,6 +42,12 @@ struct __has_storage_type {
   static const bool value = false;
 };
 
+template <typename _Cp>
+struct __size_difference_type_traits {
+  using difference_type = typename _Cp::difference_type;
+  using size_type       = typename _Cp::size_type;
+};
+
 template <class _Cp, bool = __has_storage_type<_Cp>::value>
 class __bit_reference {
   using __storage_type    = typename _Cp::__storage_type;
@@ -587,7 +594,7 @@ inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> swap_ranges(
 
 template <class _Cp>
 struct __bit_array {
-  using difference_type   = typename _Cp::difference_type;
+  using difference_type   = typename __size_difference_type_traits<_Cp>::difference_type;
   using __storage_type    = typename _Cp::__storage_type;
   using __storage_pointer = typename _Cp::__storage_pointer;
   using iterator          = typename _Cp::iterator;
@@ -779,7 +786,7 @@ equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __b
 template <class _Cp, bool _IsConst, typename _Cp::__storage_type>
 class __bit_iterator {
 public:
-  using difference_type = typename _Cp::difference_type;
+  using difference_type = typename __size_difference_type_traits<_Cp>::difference_type;
   using value_type      = bool;
   using pointer         = __bit_iterator;
 #ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
@@ -966,7 +973,7 @@ private:
 
   template <bool _FillVal, class _Dp>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend void
-  __fill_n_bool(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
+  __fill_n_bool(__bit_iterator<_Dp, false> __first, typename __size_difference_type_traits<_Dp>::size_type __n);
 
   template <class _Dp, bool _IC>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_aligned(
@@ -1009,10 +1016,10 @@ private:
       equal(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
   template <bool _ToFind, class _Dp, bool _IC>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, _IC>
-      __find_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
+      __find_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type);
   template <bool _ToCount, class _Dp, bool _IC>
-  friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 __count_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
+  friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
+  __count_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type);
 };
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__fwd/bit_reference.h b/libcxx/include/__fwd/bit_reference.h
index 237efb6db66429..0550473bcb9ec3 100644
--- a/libcxx/include/__fwd/bit_reference.h
+++ b/libcxx/include/__fwd/bit_reference.h
@@ -20,6 +20,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0>
 class __bit_iterator;
 
+template <typename _Cp>
+struct __size_difference_type_traits;
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP___FWD_BIT_REFERENCE_H
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index 919d2a0f07e096..fdba43f722e78d 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -136,6 +136,8 @@ template <size_t N> struct hash<std::bitset<N>>;
 #  include <__assert>
 #  include <__bit_reference>
 #  include <__config>
+#  include <__cstddef/ptrdiff_t.h>
+#  include <__cstddef/size_t.h>
 #  include <__functional/hash.h>
 #  include <__functional/unary_function.h>
 #  include <__type_traits/is_char_like_type.h>
@@ -167,12 +169,18 @@ struct __has_storage_type<__bitset<_N_words, _Size> > {
   static const bool value = true;
 };
 
+template <size_t _N_words, size_t _Size>
+struct __size_difference_type_traits<std::__bitset<_N_words, _Size> > {
+  using difference_type = typename std::__bitset<_N_words, _Size>::__difference_type;
+  using size_type       = typename std::__bitset<_N_words, _Size>::__size_type;
+};
+
 template <size_t _N_words, size_t _Size>
 class __bitset {
 public:
-  typedef ptrdiff_t difference_type;
-  typedef size_t size_type;
-  typedef size_type __storage_type;
+  typedef ptrdiff_t __difference_type;
+  typedef size_t __size_type;
+  typedef size_t __storage_type;
 
 protected:
   typedef __bitset __self;
@@ -301,28 +309,28 @@ inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long
 template <size_t _N_words, size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
 __bitset<_N_words, _Size>::operator&=(const __bitset& __v) _NOEXCEPT {
-  for (size_type __i = 0; __i < _N_words; ++__i)
+  for (size_t __i = 0; __i < _N_words; ++__i)
     __first_[__i] &= __v.__first_[__i];
 }
 
 template <size_t _N_words, size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
 __bitset<_N_words, _Size>::operator|=(const __bitset& __v) _NOEXCEPT {
-  for (size_type __i = 0; __i < _N_words; ++__i)
+  for (size_t __i = 0; __i < _N_words; ++__i)
     __first_[__i] |= __v.__first_[__i];
 }
 
 template <size_t _N_words, size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
 __bitset<_N_words, _Size>::operator^=(const __bitset& __v) _NOEXCEPT {
-  for (size_type __i = 0; __i < _N_words; ++__i)
+  for (size_t __i = 0; __i < _N_words; ++__i)
     __first_[__i] ^= __v.__first_[__i];
 }
 
 template <size_t _N_words, size_t _Size>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<_N_words, _Size>::flip() _NOEXCEPT {
   // do middle whole words
-  size_type __n         = _Size;
+  size_t __n            = _Size;
   __storage_pointer __p = __first_;
   for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
     *__p = ~*__p;
@@ -390,7 +398,7 @@ __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
 template <size_t _N_words, size_t _Size>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool __bitset<_N_words, _Size>::all() const _NOEXCEPT {
   // do middle whole words
-  size_type __n               = _Size;
+  size_t __n                  = _Size;
   __const_storage_pointer __p = __first_;
   for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
     if (~*__p)
@@ -407,7 +415,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool __bitset<_N_words, _Siz
 template <size_t _N_words, size_t _Size>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool __bitset<_N_words, _Size>::any() const _NOEXCEPT {
   // do middle whole words
-  size_type __n               = _Size;
+  size_t __n                  = _Size;
   __const_storage_pointer __p = __first_;
   for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
     if (*__p)
@@ -424,7 +432,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool __bitset<_N_words, _Siz
 template <size_t _N_words, size_t _Size>
 inline size_t __bitset<_N_words, _Size>::__hash_code() const _NOEXCEPT {
   size_t __h = 0;
-  for (size_type __i = 0; __i < _N_words; ++__i)
+  for (size_t __i = 0; __i < _N_words; ++__i)
     __h ^= __first_[__i];
   return __h;
 }
@@ -432,9 +440,9 @@ inline size_t __bitset<_N_words, _Size>::__hash_code() const _NOEXCEPT {
 template <size_t _Size>
 class __bitset<1, _Size> {
 public:
-  typedef ptrdiff_t difference_type;
-  typedef size_t size_type;
-  typedef size_type __storage_type;
+  typedef ptrdiff_t __difference_type;
+  typedef size_t __size_type;
+  typedef size_t __storage_type;
 
 protected:
   typedef __bitset __self;
@@ -549,9 +557,9 @@ inline size_t __bitset<1, _Size>::__hash_code() const _NOEXCEPT {
 template <>
 class __bitset<0, 0> {
 public:
-  typedef ptrdiff_t difference_type;
-  typedef size_t size_type;
-  typedef size_type __storage_type;
+  typedef ptrdiff_t __difference_type;
+  typedef size_t __size_type;
+  typedef size_t __storage_type;
 
 protected:
   typedef __bitset __self;
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..902a4daaaeab9b 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
@@ -23,6 +23,8 @@ struct my_base {
   typedef int* iterator;
   typedef const int* const_iterator;
   typedef my_base base;
+  typedef std::ptrdiff_t difference_type;
+  typedef std::size_t size_type;
 };
 
 template <std::size_t N>
@@ -57,3 +59,23 @@ 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>::difference_type, std::ptrdiff_t>::value, "");
+static_assert(std::is_same<my_derived<1>::difference_type, std::ptrdiff_t>::value, "");
+static_assert(std::is_same<my_derived<8>::difference_type, std::ptrdiff_t>::value, "");
+static_assert(std::is_same<my_derived<12>::difference_type, std::ptrdiff_t>::value, "");
+static_assert(std::is_same<my_derived<16>::difference_type, std::ptrdiff_t>::value, "");
+static_assert(std::is_same<my_derived<32>::difference_type, std::ptrdiff_t>::value, "");
+static_assert(std::is_same<my_derived<48>::difference_type, std::ptrdiff_t>::value, "");
+static_assert(std::is_same<my_derived<64>::difference_type, std::ptrdiff_t>::value, "");
+static_assert(std::is_same<my_derived<96>::difference_type, std::ptrdiff_t>::value, "");
+
+static_assert(std::is_same<my_derived<0>::size_type, std::size_t>::value, "");
+static_assert(std::is_same<my_derived<1>::size_type, std::size_t>::value, "");
+static_assert(std::is_same<my_derived<8>::size_type, std::size_t>::value, "");
+static_assert(std::is_same<my_derived<12>::size_type, std::size_t>::value, "");
+static_assert(std::is_same<my_derived<16>::size_type, std::size_t>::value, "");
+static_assert(std::is_same<my_derived<32>::size_type, std::size_t>::value, "");
+static_assert(std::is_same<my_derived<48>::size_type, std::size_t>::value, "");
+static_assert(std::is_same<my_derived<64>::size_type, std::size_t>::value, "");
+static_assert(std::is_same<my_derived<96>::size_type, std::size_t>::value, "");



More information about the libcxx-commits mailing list