Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 2 additions & 3 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -8242,7 +8242,6 @@ ExprResult InitializationSequence::Perform(Sema &S,

InitListExpr *StructuredInitList =
PerformInitList.getFullyStructuredList();
CurInit.get();
CurInit = shouldBindAsTemporary(InitEntity)
? S.MaybeBindToTemporary(StructuredInitList)
: StructuredInitList;
Expand Down
39 changes: 34 additions & 5 deletions clang/lib/Sema/SemaTemplateDeductionGuide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Copy link
Collaborator

@shafik shafik Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am looking at the for loop above and it sure seems like you could also use the for loop here and just these both above the if and remove the redundant code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I filed #161948

TP, Transformed, F, F->getLocation(), F->getLocation(),
/*ArgumentPackIndex=*/-1, CTAI,
Sema::CheckTemplateArgumentKind::CTAK_Specified))
return nullptr;
TemplateArgsForBuildingFPrime[Index] = CTAI.SugaredConverted[0];
}
}

Expand Down
17 changes: 17 additions & 0 deletions clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down