[clang] c9fd92d - [clang] Improve diagnostics on implicitly deleted defaulted comparisons

Matheus Izvekov via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 12 16:14:00 PST 2021


Author: Matheus Izvekov
Date: 2021-03-13T01:13:52+01:00
New Revision: c9fd92d573988c59b7a613f07909596cdad36095

URL: https://github.com/llvm/llvm-project/commit/c9fd92d573988c59b7a613f07909596cdad36095
DIFF: https://github.com/llvm/llvm-project/commit/c9fd92d573988c59b7a613f07909596cdad36095.diff

LOG: [clang] Improve diagnostics on implicitly deleted defaulted comparisons

This patch just makes the error message clearer by reinforcing the cause
was a lack of viable **three-way** comparison function for the
**complete object**.

Signed-off-by: Matheus Izvekov <mizvekov at gmail.com>

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D97990

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaDeclCXX.cpp
    clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
    clang/test/CXX/class/class.compare/class.compare.default/p2.cpp
    clang/test/CXX/class/class.compare/class.compare.default/p4.cpp
    clang/test/CXX/class/class.compare/class.eq/p2.cpp
    clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
    clang/test/CXX/class/class.compare/class.spaceship/p2.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d4578c5263a0..8e037260288f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8979,8 +8979,8 @@ def note_defaulted_comparison_calls_deleted : Note<
   "defaulted %0 is implicitly deleted because it would invoke a deleted "
   "comparison function%select{| for member %2| for base class %2}1">;
 def note_defaulted_comparison_no_viable_function : Note<
-  "defaulted %0 is implicitly deleted because there is no viable comparison "
-  "function%select{| for member %2| for base class %2}1">;
+  "defaulted %0 is implicitly deleted because there is no viable three-way "
+  "comparison function for%select{| member| base class}1 %2">;
 def note_defaulted_comparison_no_viable_function_synthesized : Note<
   "three-way comparison cannot be synthesized because there is no viable "
   "function for %select{'=='|'<'}0 comparison">;

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 940ef796ce5e..0365d77cfc4e 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7632,7 +7632,7 @@ class DefaultedComparisonAnalyzer
 
 private:
   Subobject getCompleteObject() {
-    return Subobject{Subobject::CompleteObject, nullptr, FD->getLocation()};
+    return Subobject{Subobject::CompleteObject, RD, FD->getLocation()};
   }
 
   Subobject getBase(CXXBaseSpecifier *Base) {

diff  --git a/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp b/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
index 1a0ccc91741b..dd622988d458 100644
--- a/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
+++ b/clang/test/CXX/class/class.compare/class.compare.default/p1.cpp
@@ -127,7 +127,7 @@ namespace P1946 {
     friend bool operator==(A &, A &); // expected-note {{would lose const qualifier}}
   };
   struct B {
-    A a; // expected-note {{no viable comparison}}
+    A a; // expected-note {{no viable three-way comparison}}
     friend bool operator==(B, B) = default; // ok
     friend bool operator==(const B&, const B&) = default; // expected-warning {{deleted}}
   };

diff  --git a/clang/test/CXX/class/class.compare/class.compare.default/p2.cpp b/clang/test/CXX/class/class.compare/class.compare.default/p2.cpp
index 226245ce8a44..a1653d85abbf 100644
--- a/clang/test/CXX/class/class.compare/class.compare.default/p2.cpp
+++ b/clang/test/CXX/class/class.compare/class.compare.default/p2.cpp
@@ -44,7 +44,7 @@ struct A3 {
 
   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}}
+  // expected-note at -1 {{because there is no viable three-way comparison function for 'A3'}}
 };
 
 struct B1 {

diff  --git a/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp b/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp
index 8c303c63d899..02adf3d51ded 100644
--- a/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp
+++ b/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp
@@ -99,7 +99,7 @@ namespace DeleteAfterFirstDecl {
   struct Q {
     struct X {
       friend std::strong_ordering operator<=>(const X&, const X&);
-    } x; // expected-note {{no viable comparison}}
+    } x; // expected-note {{no viable three-way comparison}}
     // expected-error at +1 {{defaulting the corresponding implicit 'operator==' for this defaulted 'operator<=>' would delete it after its first declaration}}
     friend std::strong_ordering operator<=>(const Q&, const Q&) = default;
   };

diff  --git a/clang/test/CXX/class/class.compare/class.eq/p2.cpp b/clang/test/CXX/class/class.compare/class.eq/p2.cpp
index 7e9416574eee..44da9191dc0e 100644
--- a/clang/test/CXX/class/class.compare/class.eq/p2.cpp
+++ b/clang/test/CXX/class/class.compare/class.eq/p2.cpp
@@ -18,26 +18,26 @@ 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}}
+  // expected-note at -1 {{because there is no viable three-way comparison function for 'H1'}}
   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}}
+  // expected-note at -1 {{because there is no viable three-way comparison function for 'H2'}}
   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}}
+  // expected-note at -1 {{because there is no viable three-way comparison function for 'H3'}}
   int H3::*x;
 };
 
 template<typename T> struct X {
   X();
   bool operator==(const X&) const = default; // #x expected-note 4{{deleted here}}
-  T t; // expected-note 3{{because there is no viable comparison function for member 't'}}
+  T t; // expected-note 3{{because there is no viable three-way comparison function for member 't'}}
        // expected-note at -1 {{because it would invoke a deleted comparison function for member 't'}}
 };
 

diff  --git a/clang/test/CXX/class/class.compare/class.spaceship/p1.cpp b/clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
index 7768e84323d0..b951ed2dabd9 100644
--- a/clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
+++ b/clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
@@ -78,9 +78,9 @@ namespace Deletedness {
   };
 
   // expected-note@#base {{deleted comparison function for base class 'C'}}
-  // expected-note@#base {{no viable comparison function for base class 'D1'}}
+  // expected-note@#base {{no viable three-way comparison function for base class 'D1'}}
   // expected-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}}
-  // expected-note@#base {{no viable comparison function for base class 'D2'}}
+  // expected-note@#base {{no viable three-way comparison function for base class 'D2'}}
   // expected-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}}
   // expected-note@#base {{deleted comparison function for base class 'E'}}
   // expected-note@#base {{implied comparison for base class 'F' is ambiguous}}
@@ -110,9 +110,9 @@ namespace Deletedness {
   }
 
   // expected-note@#arr {{deleted comparison function for member 'arr'}}
-  // expected-note@#arr {{no viable comparison function for member 'arr'}}
+  // expected-note@#arr {{no viable three-way comparison function for member 'arr'}}
   // expected-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}}
-  // expected-note@#arr {{no viable comparison function for member 'arr'}}
+  // expected-note@#arr {{no viable three-way comparison function for member 'arr'}}
   // expected-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}}
   // expected-note@#arr {{deleted comparison function for member 'arr'}}
   // expected-note@#arr {{implied comparison for member 'arr' is ambiguous}}

diff  --git a/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp b/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
index d7f95ee4a6fd..06126a48acf1 100644
--- a/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
+++ b/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
@@ -52,7 +52,7 @@ namespace DeducedVsSynthesized {
     bool operator<(const A&) const;
   };
   struct B {
-    A a; // expected-note {{no viable comparison function for member 'a'}}
+    A a; // expected-note {{no viable three-way comparison function for member 'a'}}
     auto operator<=>(const B&) const = default; // expected-warning {{implicitly deleted}}
   };
 }
@@ -159,16 +159,16 @@ namespace BadDeducedType {
 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'}}
+    void (*x)();                                 // expected-note {{because there is no viable three-way 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'}}
+    void (B::*x)();                              // expected-note {{because there is no viable three-way 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'}}
+    int C::*x;                                   // expected-note {{because there is no viable three-way comparison function for member 'x'}}
   };
 }


        


More information about the cfe-commits mailing list