Skip to content
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++] Fix ambiguity due to non-uglified member typedefs #121664

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

winner245
Copy link
Contributor

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.

@winner245 winner245 marked this pull request as ready for review January 6, 2025 13:24
@winner245 winner245 requested a review from a team as a code owner January 6, 2025 13:24
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jan 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 6, 2025

@llvm/pr-subscribers-libcxx

Author: Peng Liu (winner245)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/121664.diff

7 Files Affected:

  • (modified) libcxx/include/__algorithm/count.h (+5-3)
  • (modified) libcxx/include/__algorithm/fill_n.h (+1-1)
  • (modified) libcxx/include/__algorithm/find.h (+5-3)
  • (modified) libcxx/include/__bit_reference (+13-6)
  • (modified) libcxx/include/__fwd/bit_reference.h (+3)
  • (modified) libcxx/include/bitset (+24-16)
  • (modified) libcxx/test/std/utilities/template.bitset/bitset.members/nonstdmem.uglified.compile.pass.cpp (+22)
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, "");

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
2 participants