[PATCH] D95409: [clang] implicitly delete space ship operator with function pointers

Matheus Izvekov via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 25 14:40:09 PST 2021


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 at -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 at -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 at -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 at -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);
     }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95409.326514.patch
Type: text/x-patch
Size: 3984 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210225/9c7cfc40/attachment.bin>


More information about the cfe-commits mailing list