[libcxx-commits] [libcxx] [libc++] Fix `unexpected` heterogeneous comparison (PR #115249)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Nov 6 18:14:41 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: A. Jiang (frederick-vs-ja)
<details>
<summary>Changes</summary>
Currently, libc++ incorrectly rejects heterogeneous comparison of `unexpected`, because the `operator==` is only a hidden friend of `unexpected<_Err>` but not of `unexpected<_Err2>`. We need to call the `error()` member function on `__y`.
Originally discovered by @<!-- -->Quuxplusone. Fixes Quuxplusone/llvm-project#<!-- -->40.
---
Full diff: https://github.com/llvm/llvm-project/pull/115249.diff
2 Files Affected:
- (modified) libcxx/include/__expected/unexpected.h (+1-1)
- (modified) libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp (+13)
``````````diff
diff --git a/libcxx/include/__expected/unexpected.h b/libcxx/include/__expected/unexpected.h
index c7fe3c52e43114..cf110bcf69a827 100644
--- a/libcxx/include/__expected/unexpected.h
+++ b/libcxx/include/__expected/unexpected.h
@@ -108,7 +108,7 @@ class unexpected {
template <class _Err2>
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const unexpected& __x, const unexpected<_Err2>& __y) {
- return __x.__unex_ == __y.__unex_;
+ return __x.__unex_ == __y.error();
}
private:
diff --git a/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp b/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp
index 3c29cf97580460..7098ffc22c5dab 100644
--- a/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.unexpected/equality.pass.cpp
@@ -23,15 +23,28 @@
struct Error{
int i;
friend constexpr bool operator==(const Error&, const Error&) = default;
+ friend constexpr bool operator==(const Error& lhs, int rhs) noexcept {
+ return lhs.i == rhs;
+ }
};
constexpr bool test() {
std::unexpected<Error> unex1(Error{2});
std::unexpected<Error> unex2(Error{3});
std::unexpected<Error> unex3(Error{2});
+
assert(unex1 == unex3);
assert(unex1 != unex2);
assert(unex2 != unex3);
+
+ std::unexpected<int> unex_i1(1);
+ std::unexpected<int> unex_i2(2);
+
+ assert(unex1 != unex_i1);
+ assert(unex_i1 != unex1);
+ assert(unex1 == unex_i2);
+ assert(unex_i2 == unex1);
+
return true;
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/115249
More information about the libcxx-commits
mailing list