[clang] e0eb7c2 - [Clang] Ensure initialized NTTP expressions when building CTAD for type aliases (#161035)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 2 23:17:19 PDT 2025
Author: Younan Zhang
Date: 2025-10-03T06:17:15Z
New Revision: e0eb7c25cbb5b5b80f023b1e3cc0b31e1bdaa8f0
URL: https://github.com/llvm/llvm-project/commit/e0eb7c25cbb5b5b80f023b1e3cc0b31e1bdaa8f0
DIFF: https://github.com/llvm/llvm-project/commit/e0eb7c25cbb5b5b80f023b1e3cc0b31e1bdaa8f0.diff
LOG: [Clang] Ensure initialized NTTP expressions when building CTAD for type aliases (#161035)
We missed calling CheckTemplateArgument when building CTAD deduction
guides. That ensures some InitExprs are correctly initialized, as in the
test that crashed due to incorrect NTTP initialization.
I don't use CheckTemplateArguments because, in CTAD synthesis, template
parameter packs don't always appear at the end of the parameter list,
unlike user-written ones mandated by the standard. This makes it
difficult for CheckTemplateArguments to determine how many arguments a
pack in middle should match, leading to unnecessary complexity.
On the other hand, since we substitute non-deduced template parameters
with deduced ones, we need to fold the packs midway through
substitution, where CheckTemplateArgument is more convenient.
As a drive-by this also removes some dead code in SemaInit.
Fixes #131408
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/SemaTemplateDeductionGuide.cpp
clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 145a83af514ed..0ec333579ea86 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -361,7 +361,7 @@ Bug Fixes in This Version
first parameter. (#GH113323).
- Fixed a crash with incompatible pointer to integer conversions in designated
initializers involving string literals. (#GH154046)
-- Fix crash on CTAD for alias template. (#GH131342)
+- Fix crash on CTAD for alias template. (#GH131342), (#GH131408)
- Clang now emits a frontend error when a function marked with the `flatten` attribute
calls another function that requires target features not enabled in the caller. This
prevents a fatal error in the backend.
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index c97129336736b..0d0d2c00eb5d4 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -8219,8 +8219,8 @@ ExprResult InitializationSequence::Perform(Sema &S,
// InitializeTemporary entity for our target type.
QualType Ty = Step->Type;
bool IsTemporary = !S.Context.hasSameType(Entity.getType(), Ty);
- InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(Ty);
- InitializedEntity InitEntity = IsTemporary ? TempEntity : Entity;
+ InitializedEntity InitEntity =
+ IsTemporary ? InitializedEntity::InitializeTemporary(Ty) : Entity;
InitListChecker PerformInitList(S, InitEntity,
InitList, Ty, /*VerifyOnly=*/false,
/*TreatUnavailableAsInvalid=*/false);
@@ -8242,7 +8242,6 @@ ExprResult InitializationSequence::Perform(Sema &S,
InitListExpr *StructuredInitList =
PerformInitList.getFullyStructuredList();
- CurInit.get();
CurInit = shouldBindAsTemporary(InitEntity)
? S.MaybeBindToTemporary(StructuredInitList)
: StructuredInitList;
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index fe673eac8fcfa..9a61888e318b3 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -1171,17 +1171,46 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
const auto &D = DeduceResults[Index];
+ auto *TP = F->getTemplateParameters()->getParam(Index);
if (IsNonDeducedArgument(D)) {
// 2): Non-deduced template parameters would be substituted later.
continue;
}
TemplateArgumentLoc Input =
SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{});
- TemplateArgumentLoc Output;
- if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) {
- assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
- "InstantiatedArgs must be null before setting");
- TemplateArgsForBuildingFPrime[Index] = Output.getArgument();
+ TemplateArgumentListInfo Output;
+ if (SemaRef.SubstTemplateArguments(Input, Args, Output))
+ return nullptr;
+ assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
+ "InstantiatedArgs must be null before setting");
+ // CheckTemplateArgument is necessary for NTTP initializations.
+ // FIXME: We may want to call CheckTemplateArguments instead, but we cannot
+ // match packs as usual, since packs can appear in the middle of the
+ // parameter list of a synthesized CTAD guide. See also the FIXME in
+ // test/SemaCXX/cxx20-ctad-type-alias.cpp:test25.
+ Sema::CheckTemplateArgumentInfo CTAI;
+ if (Input.getArgument().getKind() == TemplateArgument::Pack) {
+ for (auto TA : Output.arguments()) {
+ if (SemaRef.CheckTemplateArgument(
+ TP, TA, F, F->getLocation(), F->getLocation(),
+ /*ArgumentPackIndex=*/-1, CTAI,
+ Sema::CheckTemplateArgumentKind::CTAK_Specified))
+ return nullptr;
+ }
+ // We will substitute the non-deduced template arguments with these
+ // transformed (unpacked at this point) arguments, where that substitution
+ // requires a pack for the corresponding parameter packs.
+ TemplateArgsForBuildingFPrime[Index] =
+ TemplateArgument::CreatePackCopy(Context, CTAI.SugaredConverted);
+ } else {
+ assert(Output.arguments().size() == 1);
+ TemplateArgumentLoc Transformed = Output.arguments()[0];
+ if (SemaRef.CheckTemplateArgument(
+ TP, Transformed, F, F->getLocation(), F->getLocation(),
+ /*ArgumentPackIndex=*/-1, CTAI,
+ Sema::CheckTemplateArgumentKind::CTAK_Specified))
+ return nullptr;
+ TemplateArgsForBuildingFPrime[Index] = CTAI.SugaredConverted[0];
}
}
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index fd1a5c01233d5..404b928903c8e 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -587,6 +587,23 @@ static_assert(__is_same(decltype(a), A<A<int>>));
} // namespace GH133132
+namespace GH131408 {
+
+struct Node {};
+
+template <class T, Node>
+struct A {
+ A(T) {}
+};
+
+template <class T>
+using AA = A<T, {}>;
+
+AA a{0};
+
+static_assert(__is_same(decltype(a), A<int, Node{}>));
+}
+
namespace GH130604 {
template <typename T> struct A {
A(T);
More information about the cfe-commits
mailing list