[clang] fixed clang frontend crash with friend class declaration and overload == (PR #133878)

Ankur Ahir via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 2 00:27:55 PDT 2025


https://github.com/Ankur-0429 updated https://github.com/llvm/llvm-project/pull/133878

>From 3a3dea21957b70dfedc4eab47be0c1717ff0a229 Mon Sep 17 00:00:00 2001
From: Ankur Ahir <ankurahir at google.com>
Date: Tue, 1 Apr 2025 00:51:11 -0700
Subject: [PATCH 1/2] fixed clang frontend crash with friend class declaration
 and overloaded operator ==

---
 clang/lib/Sema/SemaDeclCXX.cpp                        |  5 +++--
 .../class/class.compare/class.compare.default/p1.cpp  | 11 +++++++++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 676d53a1f4b45..6cee832f98e6a 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -9037,8 +9037,9 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
       return true;
 
     if (llvm::none_of(RD->friends(), [&](const FriendDecl *F) {
-          return FD->getCanonicalDecl() ==
-                 F->getFriendDecl()->getCanonicalDecl();
+          return F->getFriendDecl() &&
+                 FD->getCanonicalDecl() ==
+                     F->getFriendDecl()->getCanonicalDecl();
         })) {
       Diag(FD->getLocation(), diag::err_defaulted_comparison_not_friend)
           << int(DCK) << int(0) << RD;
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 a195e0548152d..37bf98be889d5 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
@@ -285,3 +285,14 @@ struct j {
 };
 bool j::operator==(const j &) const = default;
 }
+
+namespace evil2 {
+  struct k {};
+  
+  struct l {
+    friend bool operator==(const l& a, const l& b);
+    friend class k;
+  };
+  
+  bool operator==(const l& a, const l& b) = default;
+}

>From 38f520e1f363f1cdc3afb30a07e379e0049e7e63 Mon Sep 17 00:00:00 2001
From: Ankur Ahir <ankurahir at google.com>
Date: Tue, 1 Apr 2025 00:51:11 -0700
Subject: [PATCH 2/2] fixed clang frontend crash with friend class declaration
 and overloaded operator ==

---
 clang/docs/ReleaseNotes.rst                           |  1 +
 clang/lib/Sema/SemaDeclCXX.cpp                        |  3 +--
 .../class/class.compare/class.compare.default/p1.cpp  | 11 +++++++++++
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index daad01919ecd4..431ae0863d9e4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -342,6 +342,7 @@ Bug Fixes to Attribute Support
 Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
+- Clang Now Supports Implicitly-Defined Comparison Operators for Friend-Declarations
 - Clang now diagnoses copy constructors taking the class by value in template instantiations. (#GH130866)
 - Clang is now better at keeping track of friend function template instance contexts. (#GH55509)
 - Clang now prints the correct instantiation context for diagnostics suppressed
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 676d53a1f4b45..d1516860dfe71 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -9037,8 +9037,7 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
       return true;
 
     if (llvm::none_of(RD->friends(), [&](const FriendDecl *F) {
-          return FD->getCanonicalDecl() ==
-                 F->getFriendDecl()->getCanonicalDecl();
+          return declaresSameEntity(F->getFriendDecl(), FD);
         })) {
       Diag(FD->getLocation(), diag::err_defaulted_comparison_not_friend)
           << int(DCK) << int(0) << RD;
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 a195e0548152d..37bf98be889d5 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
@@ -285,3 +285,14 @@ struct j {
 };
 bool j::operator==(const j &) const = default;
 }
+
+namespace evil2 {
+  struct k {};
+  
+  struct l {
+    friend bool operator==(const l& a, const l& b);
+    friend class k;
+  };
+  
+  bool operator==(const l& a, const l& b) = default;
+}



More information about the cfe-commits mailing list