llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Serosh (Serosh-commits) <details> <summary>Changes</summary> Mark invalid friend definitions with `setInvalidDecl()` and skip the redecl chain search in `InstantiateFunctionDefinition` for friend-instantiated functions, which don't follow standard template redecl rules fixes #<!-- -->185341 --- Full diff: https://github.com/llvm/llvm-project/pull/186398.diff 4 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/lib/Sema/SemaDeclCXX.cpp (+3) - (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+4-1) - (added) clang/test/SemaCXX/gh185341.cpp (+17) ``````````diff 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..d966a3c1a25fd 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -18452,10 +18452,12 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D, DB << SS.getScopeRep(); if (DC->isFileContext()) DB << FixItHint::CreateRemoval(SS.getRange()); + ND->setInvalidDecl(); // Friend function defined in a local class. } else if (FunctionContainingLocalClass) { Diag(NameInfo.getBeginLoc(), diag::err_friend_def_in_local_class); + ND->setInvalidDecl(); // Per [basic.pre]p4, a template-id is not a name. Therefore, if we have // a template-id, the function name is not unqualified because these is @@ -18465,6 +18467,7 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D, // and diagnose them as such. } else if (isTemplateId) { Diag(NameInfo.getBeginLoc(), diag::err_friend_specialization_def); + ND->setInvalidDecl(); } } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index e74c41517ecbf..9e1416bac212c 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5563,6 +5563,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, // corresponding declaration of the function. assert(ExistingDefn->isThisDeclarationInstantiatedFromAFriendDefinition()); Function = const_cast<FunctionDecl*>(ExistingDefn); + if (Function->isInvalidDecl()) + return; } #ifndef NDEBUG @@ -5888,7 +5890,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, Primary && !isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function) && Function->getTemplateSpecializationKind() != - TSK_ExplicitSpecialization) { + TSK_ExplicitSpecialization && + !Function->isThisDeclarationInstantiatedFromAFriendDefinition()) { auto It = llvm::find_if(Primary->redecls(), [](const RedeclarableTemplateDecl *RTD) { return cast<FunctionTemplateDecl>(RTD) diff --git a/clang/test/SemaCXX/gh185341.cpp b/clang/test/SemaCXX/gh185341.cpp new file mode 100644 index 0000000000000..fb3ae259ccd6e --- /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>{}); +} \ No newline at end of file `````````` </details> https://github.com/llvm/llvm-project/pull/186398 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
