[llvm-branch-commits] [libcxx] c092e2a - [libc++] Fix uses of non-empty transparent comparator in `<map>` (#152624)
Tobias Hieta via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Aug 11 05:09:30 PDT 2025
Author: A. Jiang
Date: 2025-08-11T14:10:52+02:00
New Revision: c092e2af144deb85b5dfc8cd9ead2c07068a2918
URL: https://github.com/llvm/llvm-project/commit/c092e2af144deb85b5dfc8cd9ead2c07068a2918
DIFF: https://github.com/llvm/llvm-project/commit/c092e2af144deb85b5dfc8cd9ead2c07068a2918.diff
LOG: [libc++] Fix uses of non-empty transparent comparator in `<map>` (#152624)
The `__get_value()` member function was removed in LLVM 21, but the
calls in `<map>` weren't removed. This patch completes the removal and
adds regression test cases.
Fixes #152543.
(cherry picked from commit 7ae1424286203e37f6238e9349b1bfbe873ebabf)
Added:
Modified:
libcxx/include/map
libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
libcxx/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp
libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp
libcxx/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp
libcxx/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp
libcxx/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp
libcxx/test/support/is_transparent.h
Removed:
################################################################################
diff --git a/libcxx/include/map b/libcxx/include/map
index 2251565801470..3d88b32dd426b 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -692,12 +692,12 @@ public:
# if _LIBCPP_STD_VER >= 14
template <typename _K2>
_LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const {
- return __comp_(__x, __y.__get_value().first);
+ return __comp_(__x, __y.first);
}
template <typename _K2>
_LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const {
- return __comp_(__x.__get_value().first, __y);
+ return __comp_(__x.first, __y);
}
# endif
};
diff --git a/libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp
index c7ba765178969..62491e2bc4438 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp
@@ -33,6 +33,10 @@ int main(int, char**) {
typedef std::map<int, double, transparent_less_not_referenceable> M;
assert(M().count(C2Int{5}) == 0);
}
+ {
+ using M = std::map<int, double, transparent_less_nonempty>;
+ assert(M().count(C2Int{5}) == 0);
+ }
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
index 75724bdb387ce..57ce9339f6323 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
@@ -40,6 +40,13 @@ int main(int, char**) {
P result = example.equal_range(C2Int{5});
assert(result.first == result.second);
}
+ {
+ using M = std::map<int, double, transparent_less_nonempty>;
+ using P = std::pair<typename M::iterator, typename M::iterator>;
+ M example;
+ P result = example.equal_range(C2Int{5});
+ assert(result.first == result.second);
+ }
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp
index 9825d6c5879b1..3f09d5608772d 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp
@@ -36,6 +36,11 @@ int main(int, char**) {
M example;
assert(example.find(C2Int{5}) == example.end());
}
+ {
+ using M = std::map<int, double, transparent_less_nonempty>;
+ M example;
+ assert(example.find(C2Int{5}) == example.end());
+ }
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
index fe7fe381a86eb..308a2ed1e3af0 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
@@ -36,6 +36,11 @@ int main(int, char**) {
M example;
assert(example.lower_bound(C2Int{5}) == example.end());
}
+ {
+ using M = std::map<int, double, transparent_less_nonempty>;
+ M example;
+ assert(example.lower_bound(C2Int{5}) == example.end());
+ }
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
index 525aa673ea74b..332b71a84e9fb 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
@@ -36,6 +36,11 @@ int main(int, char**) {
M example;
assert(example.upper_bound(C2Int{5}) == example.end());
}
+ {
+ using M = std::map<int, double, transparent_less_nonempty>;
+ M example;
+ assert(example.upper_bound(C2Int{5}) == example.end());
+ }
return 0;
}
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp
index 233d1a11e1d6c..36f0ac2647ba3 100644
--- a/libcxx/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp
+++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp
@@ -33,6 +33,10 @@ int main(int, char**) {
typedef std::multimap<int, double, transparent_less_not_referenceable> M;
assert(M().count(C2Int{5}) == 0);
}
+ {
+ using M = std::multimap<int, double, transparent_less_nonempty>;
+ assert(M().count(C2Int{5}) == 0);
+ }
return 0;
}
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp
index 0bead6c7938db..a362c03e26385 100644
--- a/libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp
+++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp
@@ -40,6 +40,13 @@ int main(int, char**) {
P result = example.equal_range(C2Int{5});
assert(result.first == result.second);
}
+ {
+ using M = std::multimap<int, double, transparent_less_nonempty>;
+ using P = std::pair<typename M::iterator, typename M::iterator>;
+ M example;
+ P result = example.equal_range(C2Int{5});
+ assert(result.first == result.second);
+ }
return 0;
}
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp
index 701d4e314e7a8..ccb0900e76835 100644
--- a/libcxx/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp
+++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp
@@ -36,6 +36,11 @@ int main(int, char**) {
M example;
assert(example.find(C2Int{5}) == example.end());
}
+ {
+ using M = std::multimap<int, double, transparent_less_nonempty>;
+ M example;
+ assert(example.find(C2Int{5}) == example.end());
+ }
return 0;
}
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp
index 79f994847f131..4b4853062001f 100644
--- a/libcxx/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp
+++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp
@@ -36,6 +36,11 @@ int main(int, char**) {
M example;
assert(example.lower_bound(C2Int{5}) == example.end());
}
+ {
+ using M = std::multimap<int, double, transparent_less_nonempty>;
+ M example;
+ assert(example.lower_bound(C2Int{5}) == example.end());
+ }
return 0;
}
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp
index 62f52416b9156..f2ae94577b6c1 100644
--- a/libcxx/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp
+++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp
@@ -36,6 +36,11 @@ int main(int, char**) {
M example;
assert(example.upper_bound(C2Int{5}) == example.end());
}
+ {
+ using M = std::multimap<int, double, transparent_less_nonempty>;
+ M example;
+ assert(example.upper_bound(C2Int{5}) == example.end());
+ }
return 0;
}
diff --git a/libcxx/test/support/is_transparent.h b/libcxx/test/support/is_transparent.h
index 700c894a8b60f..4b2a458f574aa 100644
--- a/libcxx/test/support/is_transparent.h
+++ b/libcxx/test/support/is_transparent.h
@@ -36,6 +36,17 @@ struct transparent_less_not_referenceable
using is_transparent = void () const &; // it's a type; a weird one, but a type
};
+// Prevent regression when empty base class optimization is not suitable.
+// See https://github.com/llvm/llvm-project/issues/152543.
+struct transparent_less_nonempty {
+ template <class T, class U>
+ constexpr bool operator()(T&& t, U&& u) const {
+ return std::forward<T>(t) < std::forward<U>(u);
+ }
+ struct is_transparent {
+ } pad_; // making this comparator non-empty
+};
+
struct transparent_less_no_type
{
template <class T, class U>
More information about the llvm-branch-commits
mailing list