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

Updated comment and moved tests to correct places.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95409

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/class/class.compare/class.compare.default/p2.cpp
  clang/test/CXX/class/class.compare/class.eq/p2.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p2.cpp


Index: clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
+++ clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
@@ -155,3 +155,20 @@
     friend CmpCat auto operator<=>(const D&, const D&) = default;
   };
 }
+
+namespace PR48856 {
+  struct A {
+    auto operator<=>(const A &) const = default; // expected-warning 
{{implicitly deleted}}
+    void (*x)();                                 // expected-note {{because 
there is no viable comparison function for member 'x'}}
+  };
+
+  struct B {
+    auto operator<=>(const B &) const = default; // expected-warning 
{{implicitly deleted}}
+    void (B::*x)();                              // expected-note {{because 
there is no viable comparison function for member 'x'}}
+  };
+
+  struct C {
+    auto operator<=>(const C &) const = default; // expected-warning 
{{implicitly deleted}}
+    int C::*x;                                   // expected-note {{because 
there is no viable comparison function for member 'x'}}
+  };
+}
Index: clang/test/CXX/class/class.compare/class.eq/p2.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.eq/p2.cpp
+++ clang/test/CXX/class/class.compare/class.eq/p2.cpp
@@ -15,6 +15,25 @@
 struct F { void operator==(F) const; };
 struct G { bool operator==(G) const = delete; }; // expected-note {{deleted 
here}}
 
+struct H1 {
+  bool operator==(const H1 &) const = default;
+  bool operator<(const H1 &) const = default; // expected-warning {{implicitly 
deleted}}
+  // expected-note@-1 {{because there is no viable comparison function}}
+  void (*x)();
+};
+struct H2 {
+  bool operator==(const H2 &) const = default;
+  bool operator<(const H2 &) const = default; // expected-warning {{implicitly 
deleted}}
+  // expected-note@-1 {{because there is no viable comparison function}}
+  void (H2::*x)();
+};
+struct H3 {
+  bool operator==(const H3 &) const = default;
+  bool operator<(const H3 &) const = default; // expected-warning {{implicitly 
deleted}}
+  // expected-note@-1 {{because there is no viable comparison function}}
+  int H3::*x;
+};
+
 template<typename T> struct X {
   X();
   bool operator==(const X&) const = default; // #x expected-note 4{{deleted 
here}}
Index: clang/test/CXX/class/class.compare/class.compare.default/p2.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.compare.default/p2.cpp
+++ clang/test/CXX/class/class.compare/class.compare.default/p2.cpp
@@ -39,6 +39,14 @@
   void(a >= a);
 }
 
+struct A3 {
+  int &x; // expected-note {{because class 'A3' has a reference member}}
+
+  bool operator==(const A3 &) const = default; // expected-warning 
{{implicitly deleted}}
+  bool operator<(const A3 &) const = default;  // expected-warning 
{{implicitly deleted}}
+  // expected-note@-1 {{because there is no viable comparison function}}
+};
+
 struct B1 {
   struct {
     int x;
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -7685,10 +7685,14 @@
 
     if (Args[0]->getType()->isOverloadableType())
       S.LookupOverloadedBinOp(CandidateSet, OO, Fns, Args);
-    else {
+    else if (OO == OO_EqualEqual ||
+             !Args[0]->getType()->isFunctionPointerType()) {
       // FIXME: We determine whether this is a valid expression by checking to
       // see if there's a viable builtin operator candidate for it. That isn't
       // really what the rules ask us to do, but should give the right results.
+      //
+      // Note that the builtin operator for relational comparisons on function
+      // pointers is the only known case which cannot be used.
       S.AddBuiltinOperatorCandidates(OO, FD->getLocation(), Args, 
CandidateSet);
     }
 


Index: clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
+++ clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
@@ -155,3 +155,20 @@
     friend CmpCat auto operator<=>(const D&, const D&) = default;
   };
 }
+
+namespace PR48856 {
+  struct A {
+    auto operator<=>(const A &) const = default; // expected-warning {{implicitly deleted}}
+    void (*x)();                                 // expected-note {{because there is no viable comparison function for member 'x'}}
+  };
+
+  struct B {
+    auto operator<=>(const B &) const = default; // expected-warning {{implicitly deleted}}
+    void (B::*x)();                              // expected-note {{because there is no viable comparison function for member 'x'}}
+  };
+
+  struct C {
+    auto operator<=>(const C &) const = default; // expected-warning {{implicitly deleted}}
+    int C::*x;                                   // expected-note {{because there is no viable comparison function for member 'x'}}
+  };
+}
Index: clang/test/CXX/class/class.compare/class.eq/p2.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.eq/p2.cpp
+++ clang/test/CXX/class/class.compare/class.eq/p2.cpp
@@ -15,6 +15,25 @@
 struct F { void operator==(F) const; };
 struct G { bool operator==(G) const = delete; }; // expected-note {{deleted here}}
 
+struct H1 {
+  bool operator==(const H1 &) const = default;
+  bool operator<(const H1 &) const = default; // expected-warning {{implicitly deleted}}
+  // expected-note@-1 {{because there is no viable comparison function}}
+  void (*x)();
+};
+struct H2 {
+  bool operator==(const H2 &) const = default;
+  bool operator<(const H2 &) const = default; // expected-warning {{implicitly deleted}}
+  // expected-note@-1 {{because there is no viable comparison function}}
+  void (H2::*x)();
+};
+struct H3 {
+  bool operator==(const H3 &) const = default;
+  bool operator<(const H3 &) const = default; // expected-warning {{implicitly deleted}}
+  // expected-note@-1 {{because there is no viable comparison function}}
+  int H3::*x;
+};
+
 template<typename T> struct X {
   X();
   bool operator==(const X&) const = default; // #x expected-note 4{{deleted here}}
Index: clang/test/CXX/class/class.compare/class.compare.default/p2.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.compare.default/p2.cpp
+++ clang/test/CXX/class/class.compare/class.compare.default/p2.cpp
@@ -39,6 +39,14 @@
   void(a >= a);
 }
 
+struct A3 {
+  int &x; // expected-note {{because class 'A3' has a reference member}}
+
+  bool operator==(const A3 &) const = default; // expected-warning {{implicitly deleted}}
+  bool operator<(const A3 &) const = default;  // expected-warning {{implicitly deleted}}
+  // expected-note@-1 {{because there is no viable comparison function}}
+};
+
 struct B1 {
   struct {
     int x;
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -7685,10 +7685,14 @@
 
     if (Args[0]->getType()->isOverloadableType())
       S.LookupOverloadedBinOp(CandidateSet, OO, Fns, Args);
-    else {
+    else if (OO == OO_EqualEqual ||
+             !Args[0]->getType()->isFunctionPointerType()) {
       // FIXME: We determine whether this is a valid expression by checking to
       // see if there's a viable builtin operator candidate for it. That isn't
       // really what the rules ask us to do, but should give the right results.
+      //
+      // Note that the builtin operator for relational comparisons on function
+      // pointers is the only known case which cannot be used.
       S.AddBuiltinOperatorCandidates(OO, FD->getLocation(), Args, CandidateSet);
     }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D95409: [... Matheus Izvekov via Phabricator via cfe-commits
    • [PATCH] D954... Matheus Izvekov via Phabricator via cfe-commits
    • [PATCH] D954... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D954... Matheus Izvekov via Phabricator via cfe-commits
    • [PATCH] D954... Richard Smith - zygoloid via Phabricator via cfe-commits

Reply via email to