-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[libc++] Further constrain comparison against foo_ordering types #127311
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
base: main
Are you sure you want to change the base?
Conversation
This fixes an issue reported in llvm#79465.
@llvm/pr-subscribers-libcxx Author: Louis Dionne (ldionne) ChangesThis fixes an issue reported in #79465. Full diff: https://github.com/llvm/llvm-project/pull/127311.diff 2 Files Affected:
diff --git a/libcxx/include/__compare/ordering.h b/libcxx/include/__compare/ordering.h
index 902ef5329dd43..d8fffeda40000 100644
--- a/libcxx/include/__compare/ordering.h
+++ b/libcxx/include/__compare/ordering.h
@@ -49,6 +49,11 @@ struct _CmpUnspecifiedParam {
{
(void)__zero;
}
+
+ // Reject any other type and reject int lvalues.
+ template <class T>
+ _CmpUnspecifiedParam(T&&) = delete;
+ _CmpUnspecifiedParam(const volatile int&) = delete;
};
class partial_ordering {
diff --git a/libcxx/test/std/language.support/cmp/cmp.categories.pre/reject-other-than-literal-zero.verify.cpp b/libcxx/test/std/language.support/cmp/cmp.categories.pre/reject-other-than-literal-zero.verify.cpp
index b6bc4dd4f097a..d86bc418685e2 100644
--- a/libcxx/test/std/language.support/cmp/cmp.categories.pre/reject-other-than-literal-zero.verify.cpp
+++ b/libcxx/test/std/language.support/cmp/cmp.categories.pre/reject-other-than-literal-zero.verify.cpp
@@ -22,22 +22,33 @@
#include "test_macros.h"
+struct AnyType {
+ operator int() const { return 0; }
+};
+
#define TEST_FAIL(v, op) \
do { \
/* invalid types */ \
+ constexpr AnyType t; \
void(v op 0L); \
void(0L op v); \
void(v op 0.0); \
void(0.0 op v); \
void(v op nullptr); \
void(nullptr op v); \
+ void(v op t); \
+ void(t op v); \
/* invalid value */ \
void(v op 1); \
void(1 op v); \
- /* value not known at compile-time */ \
+ /* lvalue reference (also, value is not known at compile-time) */ \
int i = 0; \
void(v op i); \
void(i op v); \
+ /* value known at compile time, but still a lvalue */ \
+ constexpr int j = 0; \
+ void(v op j); \
+ void(j op v); \
} while (false)
#define TEST_PASS(v, op) \
@@ -50,13 +61,33 @@
template <typename T>
void test_category(T v) {
- TEST_FAIL(v, ==); // expected-error 30 {{invalid operands to binary expression}}
- TEST_FAIL(v, !=); // expected-error 30 {{invalid operands to binary expression}}
- TEST_FAIL(v, <); // expected-error 30 {{invalid operands to binary expression}}
- TEST_FAIL(v, <=); // expected-error 30 {{invalid operands to binary expression}}
- TEST_FAIL(v, >); // expected-error 30 {{invalid operands to binary expression}}
- TEST_FAIL(v, >=); // expected-error 30 {{invalid operands to binary expression}}
- TEST_FAIL(v, <=>); // expected-error 30 {{invalid operands to binary expression}}
+ TEST_FAIL(v, ==);
+ // expected-error-re@-1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+ // expected-error-re@-2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+ TEST_FAIL(v, !=);
+ // expected-error-re@-1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+ // expected-error-re@-2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+ TEST_FAIL(v, <);
+ // expected-error-re@-1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+ // expected-error-re@-2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+ TEST_FAIL(v, <=);
+ // expected-error-re@-1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+ // expected-error-re@-2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+ TEST_FAIL(v, >);
+ // expected-error-re@-1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+ // expected-error-re@-2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+ TEST_FAIL(v, >=);
+ // expected-error-re@-1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+ // expected-error-re@-2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+ TEST_FAIL(v, <=>);
+ // expected-error-re@-1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+ // expected-error-re@-2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
TEST_PASS(v, ==);
TEST_PASS(v, !=);
|
@zygoloid I'm not super thrilled by the change in diagnostics but I think I can live with it. |
Hmm, this doesn't seem to work (seen in CI):
I think that's because |
My preference would be to add an attribute or builtin type to Clang so that libc++ can use |
This fixes an issue reported in #79465.