https://github.com/Serosh-commits updated https://github.com/llvm/llvm-project/pull/186398
>From e1b01d244f07f2a20fa324a486dfa2749e183806 Mon Sep 17 00:00:00 2001 From: Serosh-commits <[email protected]> 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..5b7c85c05175b 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::Global || + Kind == NestedNameSpecifier::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; @@ -18245,6 +18259,9 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D, LookupResult Previous(*this, NameInfo, LookupOrdinaryName, RedeclarationKind::ForExternalRedeclaration); + if (IsEarlyRecovered) + Previous.clear(); + bool isTemplateId = D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId; // There are five cases here. 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>{}); +} + _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
