https://github.com/Daedie-git created
https://github.com/llvm/llvm-project/pull/217171
When synthesizing an aggregate deduction guide for a type alias template
failed, "Sema::DeclareAggregateDeductionGuideFromInitList" fell through and
llvm::cast the alias's TypeAliasDecl to CXXRecordDecl. That is UB and SIGSEGVs
after error recovery — for example a missing include while parsing Alias x{...}
for template<class T> using Alias = Aggr<T>.
This matches the crash clangd 22.1.8 hits while background-indexing TUs that
fail to include generated headers. Same stack as
https://github.com/llvm/llvm-project/issues/112953.
The sibling DeclareImplicitDeductionGuides already returns early for alias
templates and uses`dyn_cast_or_null. Apply the same here.
Minimal repro (crashes trunk/22.1.8, exits 1 with this patch):
```c++
template<class T> struct S { T v; };
template<class T> using U = S<T>;
#include "missing.h"
U x{0};
```
Please take a look: @Sirraide @Fznamznon @erichkeane @hokein
>From fff2feeaf5b76ccf6775cdb190a3e5376c198f23 Mon Sep 17 00:00:00 2001
From: Bjorn Schobben <[email protected]>
Date: Wed, 19 Aug 2026 02:00:52 +0200
Subject: [PATCH] [Clang][Sema] Don't crash on failed aggregate CTAD for
aliases
When synthesizing an aggregate deduction guide for a type alias
template failed, DeclareAggregateDeductionGuideFromInitList fell
through and llvm::cast the alias's TypeAliasDecl to CXXRecordDecl.
That is UB and segfaults after error recovery, for example after a
missing include when parsing `Alias x{...}`.
Return nullptr on failure and use dyn_cast_or_null, matching
DeclareImplicitDeductionGuides.
---
clang/docs/ReleaseNotes.md | 5 +++++
clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 9 +++++++--
.../test/SemaCXX/ctad-alias-aggregate-recovery.cpp | 13 +++++++++++++
3 files changed, 25 insertions(+), 2 deletions(-)
create mode 100644 clang/test/SemaCXX/ctad-alias-aggregate-recovery.cpp
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 16911cf384ea3..b64477c260467 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -443,6 +443,11 @@ features cannot lower the translation-unit ABI level;
#### Bug Fixes to C++ Support
+- Fixed a crash when aggregate class template argument deduction was attempted
+ on an alias template after error recovery, for example after a missing
+ include. Clang now fails deduction instead of treating the alias as a class
+ template.
+
- Fixed an issue where `__typeof__` incorrectly rejected cv-qualified function
types.
- Fixed a bug where top-level CV qualifiers (such as ``const``) were dropped
from pointers modified by Microsoft pointer attributes (like ``__ptr32`` and
``__ptr64``) and WebAssembly's ``__funcref``.
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 40c5a6181c51d..63a827b318421 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -1607,10 +1607,15 @@ CXXDeductionGuideDecl
*Sema::DeclareAggregateDeductionGuideFromInitList(
AggregateDeductionCandidates[Hash] = GD;
return GD;
}
+ // Failed alias synthesis must not fall through: the templated decl is a
+ // TypeAliasDecl, not a CXXRecordDecl.
+ return nullptr;
}
- if (CXXRecordDecl *DefRecord =
- cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) {
+ auto *RD = dyn_cast_or_null<CXXRecordDecl>(Template->getTemplatedDecl());
+ if (!RD)
+ return nullptr;
+ if (CXXRecordDecl *DefRecord = RD->getDefinition()) {
if (TemplateDecl *DescribedTemplate =
DefRecord->getDescribedClassTemplate())
Template = DescribedTemplate;
diff --git a/clang/test/SemaCXX/ctad-alias-aggregate-recovery.cpp
b/clang/test/SemaCXX/ctad-alias-aggregate-recovery.cpp
new file mode 100644
index 0000000000000..884b2962c593b
--- /dev/null
+++ b/clang/test/SemaCXX/ctad-alias-aggregate-recovery.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+
+// Aggregate CTAD for an alias template after error recovery must not crash.
+// DeclareAggregateDeductionGuideFromInitList used to fall through and
+// llvm::cast the alias's TypeAliasDecl to CXXRecordDecl.
+
+template <class T> struct S {
+ T v;
+};
+template <class T>
+using U = S<T>;
+#include "this_header_does_not_exist.h" // expected-error
{{'this_header_does_not_exist.h' file not found}}
+U x{0};
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits