[clang] [clang] fix crash in friend definition (PR #186398)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 7 14:46:29 PDT 2026
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 <janmejayapanda400 at gmail.com>
Date: Wed, 8 Apr 2026 02:34:56 +0530
Subject: [PATCH] [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>{});
+}
+
More information about the cfe-commits
mailing list