[libcxx-commits] [libcxx] [libc++] Further constrain comparison against foo_ordering types (PR #127311)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Sat Feb 15 02:35:53 PST 2025


https://github.com/ldionne created https://github.com/llvm/llvm-project/pull/127311

This fixes an issue reported in #79465.

>From 0e5104fc323aafd84ff1ceb984dcd8958f30704c Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Sat, 15 Feb 2025 11:34:25 +0100
Subject: [PATCH] [libc++] Further constrain comparison against foo_ordering
 types

This fixes an issue reported in #79465.
---
 libcxx/include/__compare/ordering.h           |  5 ++
 .../reject-other-than-literal-zero.verify.cpp | 47 +++++++++++++++----
 2 files changed, 44 insertions(+), 8 deletions(-)

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 at -1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+  // expected-error-re at -2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+  TEST_FAIL(v, !=);
+  // expected-error-re at -1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+  // expected-error-re at -2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+  TEST_FAIL(v, <);
+  // expected-error-re at -1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+  // expected-error-re at -2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+  TEST_FAIL(v, <=);
+  // expected-error-re at -1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+  // expected-error-re at -2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+  TEST_FAIL(v, >);
+  // expected-error-re at -1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+  // expected-error-re at -2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+  TEST_FAIL(v, >=);
+  // expected-error-re at -1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+  // expected-error-re at -2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
+
+  TEST_FAIL(v, <=>);
+  // expected-error-re at -1 36 {{conversion function from '{{.+}}' to '_CmpUnspecifiedParam' invokes a deleted function}}
+  // expected-error-re at -2 6 {{conversion from '{{.+}}' to '_CmpUnspecifiedParam' is ambiguous}}
 
   TEST_PASS(v, ==);
   TEST_PASS(v, !=);



More information about the libcxx-commits mailing list