-
Notifications
You must be signed in to change notification settings - Fork 14.7k
release/21.x: [libc++] Fix uses of non-empty transparent comparator in <map>
(#152624)
#152776
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
Conversation
@frederick-vs-ja What do you think about merging this PR to the release branch? |
@llvm/pr-subscribers-libcxx Author: None (llvmbot) ChangesBackport 7ae1424 Requested by: @frederick-vs-ja Full diff: https://github.com/llvm/llvm-project/pull/152776.diff 12 Files Affected:
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>
|
@frederick-vs-ja (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. |
…m#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 llvm#152543. (cherry picked from commit 7ae1424)
Backport 7ae1424
Requested by: @frederick-vs-ja