https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/124533
>From b195bfb253df84ea315eb92a59bbae2401b0248f Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Mon, 27 Jan 2025 19:48:43 +0800 Subject: [PATCH 1/2] [Clang] Remove unnecessary Decl transform & profiles for SizeOfPackExpr We used to always transform the pattern declaration for SizeOfPackExpr to ensure the constraint expression's profile produced the desired result. However, this approach failed to handle pack expansions when the pack referred to function parameters. In such cases, the function parameters were previously expanded to 1 to avoid building Subst* nodes (see e6974daa7). That workaround caused us to transform a pack without a proper ArgumentPackSubstitutionIndex, leading to crashes when transforming the pattern. It turns out that profiling the pattern for partially substituted SizeOfPackExprs is unnecessary because their transformed forms are already profiled within the partial arguments. Moreover, we always end up with a partially transformed SizeOfPackExpr for constraint comparison. --- clang/include/clang/AST/ExprCXX.h | 2 -- clang/lib/AST/StmtProfile.cpp | 2 +- clang/lib/Sema/SemaTemplateInstantiate.cpp | 17 ----------- .../SemaTemplate/concepts-out-of-line-def.cpp | 28 +++++++++++++++++++ 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 4cec89c979f775..04529fa616d703 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -4326,8 +4326,6 @@ class SizeOfPackExpr final /// Retrieve the parameter pack. NamedDecl *getPack() const { return Pack; } - void setPack(NamedDecl *NewPack) { Pack = NewPack; } - /// Retrieve the length of the parameter pack. /// /// This routine may only be invoked when the expression is not diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 0f1ebc68a4f762..089d91d2736459 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2266,13 +2266,13 @@ void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) { void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) { VisitExpr(S); - VisitDecl(S->getPack()); if (S->isPartiallySubstituted()) { auto Args = S->getPartialArguments(); ID.AddInteger(Args.size()); for (const auto &TA : Args) VisitTemplateArgument(TA); } else { + VisitDecl(S->getPack()); ID.AddInteger(0); } } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 839c4e8a28220b..98bc630fb69cc5 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1747,23 +1747,6 @@ namespace { return inherited::TransformLambdaBody(E, Body); } - ExprResult TransformSizeOfPackExpr(SizeOfPackExpr *E) { - ExprResult Transformed = inherited::TransformSizeOfPackExpr(E); - if (!Transformed.isUsable()) - return Transformed; - auto *TransformedExpr = cast<SizeOfPackExpr>(Transformed.get()); - if (SemaRef.CodeSynthesisContexts.back().Kind == - Sema::CodeSynthesisContext::ConstraintNormalization && - TransformedExpr->getPack() == E->getPack()) { - Decl *NewPack = - TransformDecl(E->getPackLoc(), TransformedExpr->getPack()); - if (!NewPack) - return ExprError(); - TransformedExpr->setPack(cast<NamedDecl>(NewPack)); - } - return TransformedExpr; - } - ExprResult TransformRequiresExpr(RequiresExpr *E) { LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); ExprResult TransReq = inherited::TransformRequiresExpr(E); diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp index 7cb5cfc10b9a7b..16779ba184296d 100644 --- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp +++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp @@ -720,6 +720,34 @@ template <typename... Ts> struct d { template struct c<int>; template struct d<int, int>; +namespace Regression_123441 { + +struct buf { + constexpr buf(auto&&... initList) requires (sizeof...(initList) <= 8); +}; + +constexpr buf::buf(auto&&... initList) requires (sizeof...(initList) <= 8) {} + +template <class> +struct buffer { + constexpr buffer(auto&&... initList) requires (sizeof...(initList) <= 8); +}; + +template <class T> +constexpr buffer<T>::buffer(auto&&... initList) requires (sizeof...(initList) <= 8) {} + +template <class...> +struct foo { // expected-note {{foo defined here}} + constexpr foo(auto&&... initList) + requires (sizeof...(initList) <= 8); +}; + +template <class... T> +constexpr foo<T...>::foo(auto&&... initList) // expected-error {{does not match any declaration}} + requires (sizeof...(T) <= 8) {} + +} + } // namespace GH115098 namespace GH114685 { >From ff5c63238be87f6f08ccdf914581ebd907b41328 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Mon, 27 Jan 2025 21:52:46 +0800 Subject: [PATCH 2/2] Address review feedback --- clang/lib/Sema/SemaTemplateInstantiate.cpp | 9 --------- clang/test/SemaTemplate/concepts-out-of-line-def.cpp | 8 ++++---- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 98bc630fb69cc5..1f32de324977b8 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1870,15 +1870,6 @@ Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) { TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition()); if (TTP->isParameterPack()) { - // We might not have an index for pack expansion when normalizing - // constraint expressions. In that case, resort to instantiation scopes - // for the transformed declarations. - if (SemaRef.ArgumentPackSubstitutionIndex == -1 && - SemaRef.CodeSynthesisContexts.back().Kind == - Sema::CodeSynthesisContext::ConstraintNormalization) { - return SemaRef.FindInstantiatedDecl(Loc, cast<NamedDecl>(D), - TemplateArgs); - } assert(Arg.getKind() == TemplateArgument::Pack && "Missing argument pack"); Arg = getPackSubstitutedTemplateArgument(getSema(), Arg); diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp index 16779ba184296d..542b0e75d60d07 100644 --- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp +++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp @@ -720,7 +720,9 @@ template <typename... Ts> struct d { template struct c<int>; template struct d<int, int>; -namespace Regression_123441 { +} // namespace GH115098 + +namespace GH123441 { struct buf { constexpr buf(auto&&... initList) requires (sizeof...(initList) <= 8); @@ -746,9 +748,7 @@ template <class... T> constexpr foo<T...>::foo(auto&&... initList) // expected-error {{does not match any declaration}} requires (sizeof...(T) <= 8) {} -} - -} // namespace GH115098 +} // namespace GH123441 namespace GH114685 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits