https://github.com/Serosh-commits updated 
https://github.com/llvm/llvm-project/pull/186398

>From 00a22a4bd343225eef148b608034ad1df90a98be Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Wed, 8 Apr 2026 02:34:56 +0530
Subject: [PATCH 1/5] [Clang] Fix friend function crash

---
 clang/docs/ReleaseNotes.rst     |  1 +
 clang/lib/Sema/SemaDeclCXX.cpp  | 17 +++++++++++++++++
 clang/test/SemaCXX/gh185341.cpp | 17 +++++++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 clang/test/SemaCXX/gh185341.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 613d87668be18..330c46b2eaaf3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -243,6 +243,7 @@ Bug Fixes to Attribute Support
 
 Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^
+- Fixed a crash when a function template is defined as a non-template friend 
with a global scope qualifier. (#GH185341)
 - Fixed a crash when instantiating ``requires`` expressions involving 
substitution failures in C++ concepts. (#GH176402)
 - Fixed a crash when a default argument is passed to an explicit object 
parameter. (#GH176639)
 - Fixed a crash when diagnosing an invalid static member function with an 
explicit object parameter (#GH177741)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5837ecd6b9163..9e9b57814b8de 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18238,6 +18238,20 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, 
Declarator &D,
       DiagnoseUnexpandedParameterPack(SS, UPPC_FriendDeclaration))
     return nullptr;
 
+  bool IsEarlyRecovered = false;
+  if (D.isFunctionDefinition() && SS.isNotEmpty()) {
+    auto Kind = SS.getScopeRep().getKind();
+    if (Kind == NestedNameSpecifier::Kind::Global ||
+        Kind == NestedNameSpecifier::Kind::Namespace) {
+      if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {
+        Diag(SS.getRange().getBegin(), diag::err_qualified_friend_def)
+            << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
+        SS.clear();
+        IsEarlyRecovered = true;
+      }
+    }
+  }
+
   // The context we found the declaration in, or in which we should
   // create the declaration.
   DeclContext *DC;
@@ -18395,6 +18409,9 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, 
Declarator &D,
     DCScope = &FakeDCScope;
   }
 
+  if (IsEarlyRecovered)
+    Previous.clear();
+
   bool AddToScope = true;
   NamedDecl *ND = ActOnFunctionDeclarator(DCScope, D, DC, TInfo, Previous,
                                           TemplateParams, AddToScope);
diff --git a/clang/test/SemaCXX/gh185341.cpp b/clang/test/SemaCXX/gh185341.cpp
new file mode 100644
index 0000000000000..de2bb8c34382d
--- /dev/null
+++ b/clang/test/SemaCXX/gh185341.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
+
+template<class>
+struct D;
+
+template<class T>
+void foo(D<T>);
+
+template<class T>
+struct D {
+  friend void ::foo(D) {} // expected-error {{friend function definition 
cannot be qualified with '::'}}
+};
+
+int main() {
+  foo(D<int>{});
+}
+

>From 1d9836e334559fe7760c3f67780422928ca4147b Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Thu, 9 Apr 2026 21:07:40 +0530
Subject: [PATCH 2/5] fix the chain

---
 clang/lib/Sema/SemaDeclCXX.cpp | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 9e9b57814b8de..ac3a21a0c9a06 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18238,7 +18238,6 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, 
Declarator &D,
       DiagnoseUnexpandedParameterPack(SS, UPPC_FriendDeclaration))
     return nullptr;
 
-  bool IsEarlyRecovered = false;
   if (D.isFunctionDefinition() && SS.isNotEmpty()) {
     auto Kind = SS.getScopeRep().getKind();
     if (Kind == NestedNameSpecifier::Kind::Global ||
@@ -18247,7 +18246,6 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, 
Declarator &D,
         Diag(SS.getRange().getBegin(), diag::err_qualified_friend_def)
             << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
         SS.clear();
-        IsEarlyRecovered = true;
       }
     }
   }
@@ -18409,8 +18407,6 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, 
Declarator &D,
     DCScope = &FakeDCScope;
   }
 
-  if (IsEarlyRecovered)
-    Previous.clear();
 
   bool AddToScope = true;
   NamedDecl *ND = ActOnFunctionDeclarator(DCScope, D, DC, TInfo, Previous,

>From 1c8d7a96a70ae0546850242e3a3c9a3f26cbf1cc Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Thu, 9 Apr 2026 21:21:07 +0530
Subject: [PATCH 3/5] nit

---
 clang/lib/Sema/SemaDeclCXX.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index ac3a21a0c9a06..93cbe1c650ead 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18406,8 +18406,7 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, 
Declarator &D,
     FakeDCScope.setEntity(DC);
     DCScope = &FakeDCScope;
   }
-
-
+ 
   bool AddToScope = true;
   NamedDecl *ND = ActOnFunctionDeclarator(DCScope, D, DC, TInfo, Previous,
                                           TemplateParams, AddToScope);

>From d81f0e447788fb714fae8426097d767d7654f804 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Thu, 9 Apr 2026 21:33:41 +0530
Subject: [PATCH 4/5] nit

---
 clang/lib/Sema/SemaDeclCXX.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 93cbe1c650ead..4c2816801118a 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18406,7 +18406,7 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, 
Declarator &D,
     FakeDCScope.setEntity(DC);
     DCScope = &FakeDCScope;
   }
- 
+
   bool AddToScope = true;
   NamedDecl *ND = ActOnFunctionDeclarator(DCScope, D, DC, TInfo, Previous,
                                           TemplateParams, AddToScope);

>From 5cff20b27779349c054c99de431cc50064f50212 Mon Sep 17 00:00:00 2001
From: Serosh-commits <[email protected]>
Date: Fri, 10 Apr 2026 22:06:12 +0530
Subject: [PATCH 5/5] nits

---
 clang/lib/Sema/SemaDeclCXX.cpp | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 4c2816801118a..26ba9b156a50c 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18238,17 +18238,6 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, 
Declarator &D,
       DiagnoseUnexpandedParameterPack(SS, UPPC_FriendDeclaration))
     return nullptr;
 
-  if (D.isFunctionDefinition() && SS.isNotEmpty()) {
-    auto Kind = SS.getScopeRep().getKind();
-    if (Kind == NestedNameSpecifier::Kind::Global ||
-        Kind == NestedNameSpecifier::Kind::Namespace) {
-      if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {
-        Diag(SS.getRange().getBegin(), diag::err_qualified_friend_def)
-            << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
-        SS.clear();
-      }
-    }
-  }
 
   // The context we found the declaration in, or in which we should
   // create the declaration.
@@ -18259,6 +18248,17 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, 
Declarator &D,
 
   bool isTemplateId = D.getName().getKind() == 
UnqualifiedIdKind::IK_TemplateId;
 
+  if (D.isFunctionDefinition() && SS.isNotEmpty() && !isTemplateId) {
+    auto Kind = SS.getScopeRep().getKind();
+    bool IsNamespaceOrGlobal = Kind == NestedNameSpecifier::Global ||
+                               Kind == NestedNameSpecifier::Namespace;
+    if (IsNamespaceOrGlobal) {
+      Diag(SS.getRange().getBegin(), diag::err_qualified_friend_def)
+          << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
+      SS.clear();
+    }
+  }
+
   // There are five cases here.
   //   - There's no scope specifier and we're in a local class. Only look
   //     for functions declared in the immediately-enclosing block scope.

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to