https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/94889
Fixes https://github.com/llvm/llvm-project/issues/64625 Fixes https://github.com/llvm/llvm-project/issues/83368 >From 217c00f47aaa65b113d1c1cfd93a9c4e1d235c1a Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Sun, 9 Jun 2024 11:49:18 +0800 Subject: [PATCH] [Clang] Fix two issues of CTAD for aggregates --- clang/lib/Sema/SemaInit.cpp | 56 +++++++++++++++------ clang/test/SemaTemplate/deduction-guide.cpp | 19 +++++++ 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 79bdc8e9f8783..de2ea639bbba8 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -313,6 +313,8 @@ class InitListChecker { InitListExpr *FullyStructuredList = nullptr; NoInitExpr *DummyExpr = nullptr; SmallVectorImpl<QualType> *AggrDeductionCandidateParamTypes = nullptr; + SmallVectorImpl<QualType> + *AggrDeductionCandidateParamTypesWithoutBraceElision = nullptr; NoInitExpr *getDummyInit() { if (!DummyExpr) @@ -506,14 +508,19 @@ class InitListChecker { Sema &S, const InitializedEntity &Entity, InitListExpr *IL, QualType &T, bool VerifyOnly, bool TreatUnavailableAsInvalid, bool InOverloadResolution = false, - SmallVectorImpl<QualType> *AggrDeductionCandidateParamTypes = nullptr); + SmallVectorImpl<QualType> *AggrDeductionCandidateParamTypes = nullptr, + SmallVectorImpl<QualType> + *AggrDeductionCandidateParamTypesWithoutBraceElision = nullptr); InitListChecker(Sema &S, const InitializedEntity &Entity, InitListExpr *IL, QualType &T, - SmallVectorImpl<QualType> &AggrDeductionCandidateParamTypes) + SmallVectorImpl<QualType> &AggrDeductionCandidateParamTypes, + SmallVectorImpl<QualType> + &AggrDeductionCandidateParamTypesWithoutBraceElision) : InitListChecker(S, Entity, IL, T, /*VerifyOnly=*/true, /*TreatUnavailableAsInvalid=*/false, /*InOverloadResolution=*/false, - &AggrDeductionCandidateParamTypes){}; + &AggrDeductionCandidateParamTypes, + &AggrDeductionCandidateParamTypesWithoutBraceElision) {} bool HadError() { return hadError; } @@ -982,11 +989,15 @@ static bool hasAnyDesignatedInits(const InitListExpr *IL) { InitListChecker::InitListChecker( Sema &S, const InitializedEntity &Entity, InitListExpr *IL, QualType &T, bool VerifyOnly, bool TreatUnavailableAsInvalid, bool InOverloadResolution, - SmallVectorImpl<QualType> *AggrDeductionCandidateParamTypes) + SmallVectorImpl<QualType> *AggrDeductionCandidateParamTypes, + SmallVectorImpl<QualType> + *AggrDeductionCandidateParamTypesWithoutBraceElision) : SemaRef(S), VerifyOnly(VerifyOnly), TreatUnavailableAsInvalid(TreatUnavailableAsInvalid), InOverloadResolution(InOverloadResolution), - AggrDeductionCandidateParamTypes(AggrDeductionCandidateParamTypes) { + AggrDeductionCandidateParamTypes(AggrDeductionCandidateParamTypes), + AggrDeductionCandidateParamTypesWithoutBraceElision( + AggrDeductionCandidateParamTypesWithoutBraceElision) { if (!VerifyOnly || hasAnyDesignatedInits(IL)) { FullyStructuredList = createInitListExpr(T, IL->getSourceRange(), IL->getNumInits()); @@ -1448,13 +1459,17 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, // brace elision is not considered for any aggregate element that has a // dependent non-array type or an array type with a value-dependent // bound - assert(AggrDeductionCandidateParamTypes); - if (!isa_and_nonnull<ConstantArrayType>( + assert(AggrDeductionCandidateParamTypes && + AggrDeductionCandidateParamTypesWithoutBraceElision); + if (!isa_and_present<ConstantArrayType>( SemaRef.Context.getAsArrayType(ElemType))) { ++Index; AggrDeductionCandidateParamTypes->push_back(ElemType); return; } + // For array types with known bounds, we still want the brace version even + // though the braces can be elided. + AggrDeductionCandidateParamTypesWithoutBraceElision->push_back(ElemType); } else { InitializationSequence Seq(SemaRef, TmpEntity, Kind, expr, /*TopLevelOfInitList*/ true); @@ -10918,22 +10933,24 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( if (!(RD->getDefinition() && RD->isAggregate())) return; QualType Ty = Context.getRecordType(RD); - SmallVector<QualType, 8> ElementTypes; - - InitListChecker CheckInitList(*this, Entity, ListInit, Ty, ElementTypes); - if (!CheckInitList.HadError()) { + auto BuildAggregateDeductionGuide = [&](MutableArrayRef<QualType> + ElementTypes, + bool BracedVersion = false) { + if (ElementTypes.empty()) + return; // C++ [over.match.class.deduct]p1.8: // if e_i is of array type and x_i is a braced-init-list, T_i is an // rvalue reference to the declared type of e_i and // C++ [over.match.class.deduct]p1.9: - // if e_i is of array type and x_i is a bstring-literal, T_i is an + // if e_i is of array type and x_i is a string-literal, T_i is an // lvalue reference to the const-qualified declared type of e_i and // C++ [over.match.class.deduct]p1.10: // otherwise, T_i is the declared type of e_i - for (int I = 0, E = ListInit->getNumInits(); + for (int I = 0, E = BracedVersion ? ElementTypes.size() + : ListInit->getNumInits(); I < E && !isa<PackExpansionType>(ElementTypes[I]); ++I) if (ElementTypes[I]->isArrayType()) { - if (isa<InitListExpr>(ListInit->getInit(I))) + if (isa<InitListExpr, DesignatedInitExpr>(ListInit->getInit(I))) ElementTypes[I] = Context.getRValueReferenceType(ElementTypes[I]); else if (isa<StringLiteral>( ListInit->getInit(I)->IgnoreParenImpCasts())) @@ -10951,7 +10968,16 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( /*AllowAggregateDeductionCandidate=*/true); HasAnyDeductionGuide = true; } - } + }; + SmallVector<QualType, 8> ElementTypes, ElementTypesWithoutBraceElision; + + InitListChecker CheckInitList(*this, Entity, ListInit, Ty, ElementTypes, + ElementTypesWithoutBraceElision); + if (CheckInitList.HadError()) + return; + BuildAggregateDeductionGuide(ElementTypes); + BuildAggregateDeductionGuide(ElementTypesWithoutBraceElision, + /*BracedVersion=*/true); }; for (auto I = Guides.begin(), E = Guides.end(); I != E; ++I) { diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp index 758ca14e4b1c3..a72b2f0de1a58 100644 --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -335,3 +335,22 @@ namespace TTP { // CHECK-NEXT: `-TemplateArgument type 'T':'type-parameter-0-0'{{$}} // CHECK-NEXT: `-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0{{$}} // CHECK-NEXT: `-TemplateTypeParm {{.+}} 'T'{{$}} + +namespace GH83368 { + +template <int N> struct A { + int f1[N]; +}; + +A a{.f1 = {1}}; + +} // namespace GH83368 + +namespace GH64625 { +template <class T> struct X { + T t[2]; +}; + +X x = {{1, 2}}; + +} // namespace GH64625 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits