[clang] 9cafc5e - [Clang] prevent instantiation of invalid friend function templates (#227038)

via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 29 08:56:45 PDT 2026


Author: Oleksandr Tarasiuk
Date: 2026-09-29T18:56:37+03:00
New Revision: 9cafc5e731d39b5f5879c77e4e217f9cc76a2711

URL: https://github.com/llvm/llvm-project/commit/9cafc5e731d39b5f5879c77e4e217f9cc76a2711
DIFF: https://github.com/llvm/llvm-project/commit/9cafc5e731d39b5f5879c77e4e217f9cc76a2711.diff

LOG: [Clang] prevent instantiation of invalid friend function templates (#227038)

Fixes #226673

--- 

This patch addresses the issue in which an invalid friend function
template is instantiated as a valid declaration, leading to a crash upon
a later redeclaration.

---

This fixes a regression introduced by
https://github.com/llvm/llvm-project/pull/216555

Added: 
    

Modified: 
    clang/lib/Sema/SemaDeclCXX.cpp
    clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp
    clang/test/SemaTemplate/GH71595.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 68ad77ec5e8c7..5345966419d40 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18820,8 +18820,7 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
     FriendDecl *Friend = FriendDecl::Create(
         Context, CurContext, D.getIdentifierLoc(), ND, DS.getFriendSpecLoc());
     Friend->setAccess(AS_public);
-    if (!isa<FunctionTemplateDecl>(ND))
-      Friend->setInvalidDecl();
+    Friend->setInvalidDecl();
     CurContext->addDecl(Friend);
     return ND;
   }

diff  --git a/clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp b/clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp
index 42e87e5431f2a..51804d6fae816 100644
--- a/clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp
+++ b/clang/test/CXX/basic/basic.start/basic.start.main/p2.cpp
@@ -17,6 +17,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST12
 // RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST13
 // RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST15
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DTEST16
 
 #if TEST1
 
@@ -112,6 +114,23 @@ int main(void); // expected-error{{'main' cannot be a template}}
 
 int main(void) {}
 
+#elif TEST15
+template <int I> struct S {
+  template <class C> friend int main() { return I; } // expected-error {{'main' cannot be a template}}
+};
+template struct S<1>;
+
+int main() {}
+
+#elif TEST16
+
+template <int I> struct S {
+  template <class C> friend int main(); // expected-error {{'main' cannot be a template}}
+};
+template struct S<1>;
+
+int main() {}
+
 #else
 
 #error Unknown test mode

diff  --git a/clang/test/SemaTemplate/GH71595.cpp b/clang/test/SemaTemplate/GH71595.cpp
index c5c5d13036233..3d23917682814 100644
--- a/clang/test/SemaTemplate/GH71595.cpp
+++ b/clang/test/SemaTemplate/GH71595.cpp
@@ -21,18 +21,15 @@ class temp {
     friend void g();
     // expected-error at -1 {{friend declaration with a constraint that depends on an enclosing template parameter must be a definition}}
 
-    temp(); // #temp-ctor
+    temp();
 };
 
 template<C<temp<int>> T>
 void g() {
     auto v = temp<T>();
-    // expected-error at -1 {{calling a private constructor of class 'temp<int>'}}
-    //   expected-note@#temp-ctor {{implicitly declared private here}}
 }
 
 void h() {
     f<int>();
     g<int>();
-    // expected-note at -1 {{in instantiation of function template specialization 'g<int>' requested here}}
 }


        


More information about the cfe-commits mailing list