[clang] [Clang][Sema] Don't assert on friend declarators with an empty name (PR #223213)
Anirudh Mathur via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 12 23:36:41 PDT 2026
https://github.com/anirudhmathur12 created https://github.com/llvm/llvm-project/pull/223213
GetNameForDeclarator (via GetNameFromUnqualifiedId) can legitimately return an empty DeclarationNameInfo after already diagnosing the problem itself. For example when a declarator was parsed as a deduction-guide name but the named template isn't actually a class template, such as a template template parameter:
template <template <typename> class C> struct S {
friend C();
};
Every other caller of GetNameForDeclarator already treats an empty name as a normal recoverable failure (see HandleDeclarator), but ActOnFriendFunctionDecl asserted instead, causing a crash. Recover the same way HandleDeclarator does.
Fixes #222233
>From 84e331fa9f8868e4d3b9972ea846cc7f487a2ebb Mon Sep 17 00:00:00 2001
From: AnirudhMathur12 <anirudhmathur12 at gmail.com>
Date: Sun, 13 Sep 2026 11:48:48 +0530
Subject: [PATCH] [Clang][Sema] Don't assert on friend declarators with an
empty name
GetNameForDeclarator (via GetNameFromUnqualifiedId) can legitimately
return an empty DeclarationNameInfo after already diagnosing the
problem itself. For example when a declarator was parsed as a
deduction-guide name but the named template isn't actually a class
template, such as a template template parameter:
template <template <typename> class C> struct S {
friend C();
};
Every other caller of GetNameForDeclarator already treats an empty
name as a normal recoverable failure (see HandleDeclarator), but
ActOnFriendFunctionDecl asserted instead, causing a crash. Recover
the same way HandleDeclarator does.
Fixes #222233
---
clang/docs/ReleaseNotes.md | 6 ++++++
clang/lib/Sema/SemaDeclCXX.cpp | 16 +++++++++++++++-
clang/test/SemaCXX/GH222233.cpp | 5 +++++
3 files changed, 26 insertions(+), 1 deletion(-)
create mode 100644 clang/test/SemaCXX/GH222233.cpp
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index ef694e1d0f5cc..60c1f5204ccbb 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -675,6 +675,12 @@ features cannot lower the translation-unit ABI level;
class with an invalid non-static data member, such as one qualified with an
address space. (#GH194605)
+- Fixed an assertion failure when a friend declaration was parsed as a
+ deduction guide naming a template template parameter (e.g.
+ `template <template <typename> class C> struct S { friend C(); };`).
+ Clang now diagnoses the ill-formed deduction guide instead of asserting.
+ (#GH222233)
+
#### Bug Fixes to AST Handling
- Fixed a non-deterministic ordering of unused local typedefs that made
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index ea628f29d8a00..dd112defcec92 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18580,7 +18580,21 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
CXXScopeSpec &SS = D.getCXXScopeSpec();
DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
- assert(NameInfo.getName());
+
+ // GetNameForDeclarator (via GetNameFromUnqualifiedId) can fail and return
+ // an empty name after it has already diagnosed the problem itself. For
+ // example, a declarator that was parsed as a deduction-guide name (see
+ // Sema::isDeductionGuideName) but does not actually name a class
+ // template, such as a template template parameter used as in
+ // 'friend C();' where C is a 'template <typename> class' parameter.
+ // [temp.deduct.guide]p3 only permits the simple-template-id to name a
+ // class template, so this is ill-formed, but it's still a valid
+ // declarator syntactically and reaches here. Recover the same way
+ // HandleDeclarator does for the analogous non-friend case rather than
+ // asserting.
+
+ if (!NameInfo.getName())
+ return nullptr;
if (SS.isValid() && DiagnosePackIndexingInFriendNNS(
NameInfo.getLoc(), SS.getWithLocInContext(Context)))
diff --git a/clang/test/SemaCXX/GH222233.cpp b/clang/test/SemaCXX/GH222233.cpp
new file mode 100644
index 0000000000000..0f94c9b5ba2bd
--- /dev/null
+++ b/clang/test/SemaCXX/GH222233.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
+
+template <template <typename> class C> struct S { // expected-note {{template is declared here}}
+ friend C(); //expected-error {{cannot specify deduction guide for template template parameter 'C'}}
+};
More information about the cfe-commits
mailing list