[PATCH] D148924: [clang] Show error if defaulted comparions operator function is volatile or has ref-qualifier &&.

Jens Massberg via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 21 07:43:30 PDT 2023


massberg created this revision.
massberg added a reviewer: ilya-biryukov.
Herald added a project: All.
massberg requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch implemed the change proposed in [P2002R1] to 11.11.1 [class.compare.default] paragraph 1.

A defaulted compariosn operator function must be non-volatile and must either have no ref-qualifier or the ref-qualifier &.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148924

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/class/class.compare/class.compare.default/p1.cpp


Index: clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
+++ clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
@@ -15,7 +15,8 @@
 
   bool operator<(const A&) const;
   bool operator<=(const A&) const = default;
-  bool operator==(const A&) const volatile && = default; // surprisingly, OK
+  bool operator==(const A&) const && = default; // expected-error {{ref-qualifier '&&' is not allowed on defaulted comparison operators}}
+  bool operator>=(const A&) const volatile = default; // expected-error {{defaulted comparison operator function must not be volatile}}
   bool operator<=>(const A&) = default; // expected-error {{defaulted member three-way comparison operator must be const-qualified}}
   bool operator>=(const B&) const = default; // expected-error-re {{invalid parameter type for defaulted relational comparison operator; found 'const B &', expected 'const A &'{{$}}}}
   static bool operator>(const B&) = default; // expected-error {{overloaded 'operator>' cannot be a static member function}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -8579,8 +8579,8 @@
   // C++2a [class.compare.default]p1:
   //   A defaulted comparison operator function for some class C shall be a
   //   non-template function declared in the member-specification of C that is
-  //    -- a non-static const member of C having one parameter of type
-  //       const C&, or
+  //    -- a non-static const non-volatile member of C having one parameter of type
+  //       const C& and either no ref-qualifier or the ref-qualifier &, or
   //    -- a friend of C having two parameters of type const C& or two
   //       parameters of type C.
 
@@ -8590,6 +8590,16 @@
     auto *MD = cast<CXXMethodDecl>(FD);
     assert(!MD->isStatic() && "comparison function cannot be a static member");
 
+    const FunctionProtoType *FnType = FD->getType()->castAs<FunctionProtoType>();
+    if (FnType->isVolatile()) {
+      Diag(FD->getLocation(), diag::err_volatile_comparison_operator);
+      return true;
+    }
+    if (FnType->getRefQualifier() == RQ_RValue) {
+      Diag(FD->getLocation(), diag::err_ref_qualifier_comparison_operator);
+      return true;
+    }
+
     // If we're out-of-class, this is the class we're comparing.
     if (!RD)
       RD = MD->getParent();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9430,6 +9430,10 @@
 def note_in_declaration_of_implicit_equality_comparison : Note<
   "while declaring the corresponding implicit 'operator==' "
   "for this defaulted 'operator<=>'">;
+def err_volatile_comparison_operator : Error<
+  "defaulted comparison operator function must not be volatile">;
+def err_ref_qualifier_comparison_operator : Error<
+  "ref-qualifier '&&' is not allowed on defaulted comparison operators">;
 
 def ext_implicit_exception_spec_mismatch : ExtWarn<
   "function previously declared with an %select{explicit|implicit}0 exception "


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D148924.515730.patch
Type: text/x-patch
Size: 3360 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230421/a62d2b61/attachment-0001.bin>


More information about the cfe-commits mailing list