[libcxx-commits] [libcxx] [libc++] Fix passing through object to comparisons in __tree (PR #186341)

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Mar 13 05:53:45 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

<details>
<summary>Changes</summary>

Fixes #<!-- -->180659

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


3 Files Affected:

- (modified) libcxx/include/__tree (+2-2) 
- (modified) libcxx/include/string (+14-11) 
- (added) libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp (+20) 


``````````diff
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 2c059a92473c7..bb8c4f3f8c623 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -1881,9 +1881,9 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const _Key& __v) {
   }
 
   __node_base_pointer* __node_ptr = __root_ptr();
-  auto&& __transparent            = std::__as_transparent<_Key>(value_comp());
+  auto&& __transparent            = std::__as_transparent<key_type>(value_comp());
   auto __comp =
-      __lazy_synth_three_way_comparator<__make_transparent_t<_Key, _Compare>, _Key, value_type>(__transparent);
+      __lazy_synth_three_way_comparator<__make_transparent_t<key_type, _Compare>, _Key, value_type>(__transparent);
 
   while (true) {
     auto __comp_res = __comp(__v, __nd->__get_value());
diff --git a/libcxx/include/string b/libcxx/include/string
index c59684c32a3fe..c17b94fa7b17b 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -625,6 +625,7 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len );
 #  include <__string/char_traits.h>
 #  include <__string/extern_template_lists.h>
 #  include <__type_traits/conditional.h>
+#  include <__type_traits/desugars_to.h>
 #  include <__type_traits/enable_if.h>
 #  include <__type_traits/is_allocator.h>
 #  include <__type_traits/is_array.h>
@@ -2602,19 +2603,21 @@ struct __default_three_way_comparator<basic_string<_CharT, _Traits, _Alloc>, bas
 };
 #  endif
 
-template <class _Comparator, class _CharT, class _Traits, class _Alloc>
-inline const bool __is_transparently_comparable_v<_Comparator,
-                                                  basic_string<_CharT, _Traits, _Alloc>,
-                                                  const _CharT*,
-                                                  __enable_if_t<__is_generic_transparent_comparator_v<_Comparator> > > =
-    true;
+template <class _Comparator, class _CharT2, class _CharT, class _Traits, class _Alloc>
+inline const bool __is_transparently_comparable_v<_Comparator, basic_string<_CharT, _Traits, _Alloc>, _CharT2*> =
+    is_same<_CharT, __remove_cv_t<_CharT2> >::value &&
+    (__desugars_to_v<__less_tag,
+                     _Comparator,
+                     basic_string<_CharT, _Traits, _Alloc>,
+                     basic_string<_CharT, _Traits, _Alloc> > ||
+     __desugars_to_v<__greater_tag,
+                     _Comparator,
+                     basic_string<_CharT, _Traits, _Alloc>,
+                     basic_string<_CharT, _Traits, _Alloc> >);
 
 template <class _Comparator, class _CharT, class _Traits, class _Alloc, size_t _Np>
-inline const bool __is_transparently_comparable_v<_Comparator,
-                                                  basic_string<_CharT, _Traits, _Alloc>,
-                                                  _CharT[_Np],
-                                                  __enable_if_t<__is_generic_transparent_comparator_v<_Comparator> > > =
-    true;
+inline const bool __is_transparently_comparable_v<_Comparator, basic_string<_CharT, _Traits, _Alloc>, _CharT[_Np]> =
+    __is_transparently_comparable_v<_Comparator, basic_string<_CharT, _Traits, _Alloc>, const _CharT*>;
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _InputIterator,
diff --git a/libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp b/libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp
new file mode 100644
index 0000000000000..2ceace3fbe1ff
--- /dev/null
+++ b/libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Check that `__is_transparently_comparable_v` is true when we expect it to be
+
+#include <functional>
+#include <string>
+#include <__type_traits/desugars_to.h>
+
+static_assert(std::__is_transparently_comparable_v<std::less<std::string>, std::string, const char*>);
+static_assert(std::__is_transparently_comparable_v<std::less<std::string>, std::string, char*>);
+static_assert(std::__is_transparently_comparable_v<std::less<std::string>, std::string, char[5]>);
+
+static_assert(
+    !std::__is_transparently_comparable_v<std::less<std::reference_wrapper<std::string>>, std::string, char[5]>);

``````````

</details>


https://github.com/llvm/llvm-project/pull/186341


More information about the libcxx-commits mailing list