mizvekov updated this revision to Diff 354920.
mizvekov added a comment.

- Rebase after split.
- Add tests which I had forgotten, covering the builtin candidates for the 
relational operators other than spaceship.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D104680/new/

https://reviews.llvm.org/D104680

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CXX/drs/dr15xx.cpp
  clang/test/CXX/drs/dr3xx.cpp
  clang/test/CXX/expr/expr.const/p2-0x.cpp
  clang/test/SemaCXX/compare-function-pointer.cpp
  clang/test/SemaTemplate/resolve-single-template-id.cpp

Index: clang/test/SemaTemplate/resolve-single-template-id.cpp
===================================================================
--- clang/test/SemaTemplate/resolve-single-template-id.cpp
+++ clang/test/SemaTemplate/resolve-single-template-id.cpp
@@ -68,11 +68,11 @@
 
   one < one; // expected-warning {{self-comparison always evaluates to false}} \
              // expected-warning {{relational comparison result unused}}       \
-             // expected-warning {{ordered comparison of function pointers}}
+             // expected-error   {{ordered comparison of function pointers}}
 
   oneT<int> < oneT<int>; // expected-warning {{self-comparison always evaluates to false}} \
                          // expected-warning {{relational comparison result unused}}       \
-                         // expected-warning {{ordered comparison of function pointers}}
+                         // expected-error   {{ordered comparison of function pointers}}
 
   two < two; //expected-error 2 {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error {{invalid operands to binary expression ('void' and 'void')}}
   twoT<int> < twoT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} {{cannot resolve overloaded function 'twoT' from context}}
Index: clang/test/SemaCXX/compare-function-pointer.cpp
===================================================================
--- clang/test/SemaCXX/compare-function-pointer.cpp
+++ clang/test/SemaCXX/compare-function-pointer.cpp
@@ -3,25 +3,48 @@
 using fp0_t = void (*)();
 using fp1_t = int (*)();
 
+namespace test_builtin {
+
 extern fp0_t a, b;
 extern fp1_t c;
 
 bool eq0 = a == b;
 bool ne0 = a != b;
-bool lt0 = a < b;   // expected-warning {{ordered comparison of function pointers ('fp0_t' (aka 'void (*)()') and 'fp0_t')}}
-bool le0 = a <= b;  // expected-warning {{ordered comparison of function pointers}}
-bool gt0 = a > b;   // expected-warning {{ordered comparison of function pointers}}
-bool ge0 = a >= b;  // expected-warning {{ordered comparison of function pointers}}
-auto tw0 = a <=> b; // expected-error {{ordered comparison of function pointers}}
+bool lt0 = a < b;   // expected-error {{ordered comparison of function pointers ('fp0_t' (aka 'void (*)()') and 'fp0_t')}}
+bool le0 = a <= b;  // expected-error {{ordered comparison of function pointers}}
+bool gt0 = a > b;   // expected-error {{ordered comparison of function pointers}}
+bool ge0 = a >= b;  // expected-error {{ordered comparison of function pointers}}
 
 bool eq1 = a == c;  // expected-error {{comparison of distinct pointer types}}
 bool ne1 = a != c;  // expected-error {{comparison of distinct pointer types}}
-bool lt1 = a < c;   // expected-warning {{ordered comparison of function pointers ('fp0_t' (aka 'void (*)()') and 'fp1_t' (aka 'int (*)()'))}}
-                    // expected-error@-1 {{comparison of distinct pointer types}}
-bool le1 = a <= c;  // expected-warning {{ordered comparison of function pointers}}
-                    // expected-error@-1 {{comparison of distinct pointer types}}
-bool gt1 = a > c;   // expected-warning {{ordered comparison of function pointers}}
-                    // expected-error@-1 {{comparison of distinct pointer types}}
-bool ge1 = a >= c;  // expected-warning {{ordered comparison of function pointers}}
-                    // expected-error@-1 {{comparison of distinct pointer types}}
+bool lt1 = a < c;   // expected-error {{ordered comparison of function pointers ('fp0_t' (aka 'void (*)()') and 'fp1_t' (aka 'int (*)()'))}}
+bool le1 = a <= c;  // expected-error {{ordered comparison of function pointers}}
+bool gt1 = a > c;   // expected-error {{ordered comparison of function pointers}}
+bool ge1 = a >= c;  // expected-error {{ordered comparison of function pointers}}
 auto tw1 = a <=> c; // expected-error {{ordered comparison of function pointers}}
+
+} // namespace test_builtin
+
+namespace test_overload {
+
+template<class T> struct wrapper { operator T(); };
+
+extern wrapper<fp0_t> a, b;
+extern wrapper<fp1_t> c;
+
+bool eq0 = a == b;
+bool ne0 = a != b;
+bool lt0 = a < b;   // expected-error {{invalid operands to binary expression}}
+bool le0 = a <= b;  // expected-error {{invalid operands to binary expression}}
+bool gt0 = a > b;   // expected-error {{invalid operands to binary expression}}
+bool ge0 = a >= b;  // expected-error {{invalid operands to binary expression}}
+
+bool eq1 = a == c;  // expected-error {{invalid operands to binary expression}}
+bool ne1 = a != c;  // expected-error {{invalid operands to binary expression}}
+bool lt1 = a < c;   // expected-error {{invalid operands to binary expression}}
+bool le1 = a <= c;  // expected-error {{invalid operands to binary expression}}
+bool gt1 = a > c;   // expected-error {{invalid operands to binary expression}}
+bool ge1 = a >= c;  // expected-error {{invalid operands to binary expression}}
+auto tw1 = a <=> c; // expected-error {{invalid operands to binary expression}}
+
+} // namespace test_overload
Index: clang/test/CXX/expr/expr.const/p2-0x.cpp
===================================================================
--- clang/test/CXX/expr/expr.const/p2-0x.cpp
+++ clang/test/CXX/expr/expr.const/p2-0x.cpp
@@ -514,9 +514,7 @@
   void f(), g();
 
   constexpr void (*pf)() = &f, (*pg)() = &g;
-  constexpr bool u13 = pf < pg; // expected-error {{constant expression}} expected-note {{comparison has unspecified value}}
-                                // expected-warning@-1 {{ordered comparison of function pointers}}
-  constexpr bool u14 = pf == pg;
+  constexpr bool u13 = pf == pg;
 
   // If two pointers point to non-static data members of the same object with
   // different access control, the result is unspecified.
Index: clang/test/CXX/drs/dr3xx.cpp
===================================================================
--- clang/test/CXX/drs/dr3xx.cpp
+++ clang/test/CXX/drs/dr3xx.cpp
@@ -18,9 +18,9 @@
   void operator-(S, S);
 
   void f() {
-    bool a = (void(*)(S, S))operator+<S> < // expected-warning {{ordered comparison of function pointers}}
+    bool a = (void(*)(S, S))operator+<S> < // expected-error {{ordered comparison of function pointers}}
              (void(*)(S, S))operator+<S>;
-    bool b = (void(*)(S, S))operator- < // cxx20_2b-note {{to match this '<'}} cxx98_17-warning {{ordered comparison of function pointers}}
+    bool b = (void(*)(S, S))operator- < // cxx20_2b-note {{to match this '<'}} cxx98_17-error {{ordered comparison of function pointers}}
              (void(*)(S, S))operator-; // cxx20_2b-error {{expected '>'}}
     bool c = (void(*)(S, S))operator+ < // expected-note {{to match this '<'}}
              (void(*)(S, S))operator-; // expected-error {{expected '>'}}
Index: clang/test/CXX/drs/dr15xx.cpp
===================================================================
--- clang/test/CXX/drs/dr15xx.cpp
+++ clang/test/CXX/drs/dr15xx.cpp
@@ -28,10 +28,10 @@
   template<typename A, typename B, typename C> void composite_pointer_type_is_ord() {
     composite_pointer_type_is_base<A, B, C>();
 
-    typedef __typeof(val<A>() < val<B>()) cmp;  // cxx17-warning 2 {{ordered comparison of function pointers}}
-    typedef __typeof(val<A>() <= val<B>()) cmp; // cxx17-warning 2 {{ordered comparison of function pointers}}
-    typedef __typeof(val<A>() > val<B>()) cmp;  // cxx17-warning 2 {{ordered comparison of function pointers}}
-    typedef __typeof(val<A>() >= val<B>()) cmp; // cxx17-warning 2 {{ordered comparison of function pointers}}
+    typedef __typeof(val<A>() < val<B>()) cmp;
+    typedef __typeof(val<A>() <= val<B>()) cmp;
+    typedef __typeof(val<A>() > val<B>()) cmp;
+    typedef __typeof(val<A>() >= val<B>()) cmp;
     typedef bool cmp;
   }
 
@@ -79,8 +79,8 @@
     no_composite_pointer_type<const int (A::*)(), volatile int (C::*)()>();
 
 #if __cplusplus > 201402
-    composite_pointer_type_is_ord<int (*)() noexcept, int (*)(), int (*)()>(); // expected-note {{requested here}}
-    composite_pointer_type_is_ord<int (*)(), int (*)() noexcept, int (*)()>(); // expected-note {{requested here}}
+    composite_pointer_type_is_unord<int (*)() noexcept, int (*)(), int (*)()>();
+    composite_pointer_type_is_unord<int (*)(), int (*)() noexcept, int (*)()>();
     composite_pointer_type_is_unord<int (A::*)() noexcept, int (A::*)(), int (A::*)()>();
     composite_pointer_type_is_unord<int (A::*)(), int (A::*)() noexcept, int (A::*)()>();
     // FIXME: This looks like a standard defect; these should probably all have type 'int (B::*)()'.
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -8466,7 +8466,7 @@
   //        bool       operator==(T, T);
   //        bool       operator!=(T, T);
   //           R       operator<=>(T, T)
-  void addGenericBinaryPointerOrEnumeralOverloads(bool IsSpaceship) {
+  void addGenericBinaryPointerOrEnumeralOverloads(bool IsOrdered) {
     // C++ [over.match.oper]p3:
     //   [...]the built-in candidates include all of the candidate operator
     //   functions defined in 13.6 that, compared to the given operator, [...]
@@ -8525,7 +8525,7 @@
         // Don't add the same builtin candidate twice.
         if (!AddedTypes.insert(S.Context.getCanonicalType(PtrTy)).second)
           continue;
-        if (IsSpaceship && PtrTy->isFunctionPointerType())
+        if (IsOrdered && PtrTy->isFunctionPointerType())
           continue;
 
         QualType ParamTypes[2] = {PtrTy, PtrTy};
@@ -9223,7 +9223,7 @@
   case OO_EqualEqual:
   case OO_ExclaimEqual:
     OpBuilder.addEqualEqualOrNotEqualMemberPointerOrNullptrOverloads();
-    OpBuilder.addGenericBinaryPointerOrEnumeralOverloads(/*IsSpaceship=*/false);
+    OpBuilder.addGenericBinaryPointerOrEnumeralOverloads(/*IsOrdered=*/false);
     OpBuilder.addGenericBinaryArithmeticOverloads();
     break;
 
@@ -9231,12 +9231,12 @@
   case OO_Greater:
   case OO_LessEqual:
   case OO_GreaterEqual:
-    OpBuilder.addGenericBinaryPointerOrEnumeralOverloads(/*IsSpaceship=*/false);
+    OpBuilder.addGenericBinaryPointerOrEnumeralOverloads(/*IsOrdered=*/true);
     OpBuilder.addGenericBinaryArithmeticOverloads();
     break;
 
   case OO_Spaceship:
-    OpBuilder.addGenericBinaryPointerOrEnumeralOverloads(/*IsSpaceship=*/true);
+    OpBuilder.addGenericBinaryPointerOrEnumeralOverloads(/*IsOrdered=*/true);
     OpBuilder.addThreeWayArithmeticOverloads();
     break;
 
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -11805,16 +11805,14 @@
   if (IsOrdered && LHSType->isFunctionPointerType() &&
       RHSType->isFunctionPointerType()) {
     // Valid unless a relational comparison of function pointers
-    bool IsError = Opc == BO_Cmp;
-    auto DiagID =
-        IsError ? diag::err_typecheck_ordered_comparison_of_function_pointers
-        : getLangOpts().CPlusPlus
-            ? diag::warn_typecheck_ordered_comparison_of_function_pointers
-            : diag::ext_typecheck_ordered_comparison_of_function_pointers;
-    Diag(Loc, DiagID) << LHSType << RHSType << LHS.get()->getSourceRange()
-                      << RHS.get()->getSourceRange();
+    bool IsError = getLangOpts().CPlusPlus;
+    Diag(Loc, IsError
+                  ? diag::err_typecheck_ordered_comparison_of_function_pointers
+                  : diag::ext_typecheck_ordered_comparison_of_function_pointers)
+        << LHSType << RHSType << LHS.get()->getSourceRange()
+        << RHS.get()->getSourceRange();
     if (IsError)
-      return QualType();
+      return Opc != BO_Cmp ? Context.getLogicalOperationType() : QualType();
   }
 
   if ((LHSType->isIntegerType() && !LHSIsNull) ||
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6788,9 +6788,6 @@
   "%0 is %select{|in}2complete and "
   "%1 is %select{|in}3complete">,
   InGroup<C11>;
-def warn_typecheck_ordered_comparison_of_function_pointers : Warning<
-  "ordered comparison of function pointers (%0 and %1)">,
-  InGroup<OrderedCompareFunctionPointers>;
 def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
   "ordered comparison of function pointers (%0 and %1)">,
   InGroup<OrderedCompareFunctionPointers>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to