[clang] 27c9173 - [Clang] Remove unnecessary Decl transform & profiles for SizeOfPackExpr (#124533)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 27 07:05:01 PST 2025
Author: Younan Zhang
Date: 2025-01-27T23:04:57+08:00
New Revision: 27c917307563eae93c7fef9c3944e56e1f5b5f6d
URL: https://github.com/llvm/llvm-project/commit/27c917307563eae93c7fef9c3944e56e1f5b5f6d
DIFF: https://github.com/llvm/llvm-project/commit/27c917307563eae93c7fef9c3944e56e1f5b5f6d.diff
LOG: [Clang] Remove unnecessary Decl transform & profiles for SizeOfPackExpr (#124533)
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 formerly 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 also
profiled within the partial arguments.
Fixes https://github.com/llvm/llvm-project/issues/124161
Added:
Modified:
clang/include/clang/AST/ExprCXX.h
clang/lib/AST/StmtProfile.cpp
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/test/SemaTemplate/concepts-out-of-line-def.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 2a130bc6da79a0..7b0450b90d5644 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 85b59f714ba845..5d1f370cac19f3 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2270,13 +2270,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 3dc5696bd38216..3c6b7ce2949c16 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1762,23 +1762,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);
@@ -1902,15 +1885,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 6c1a229a9fddab..5af4ec75cae90f 100644
--- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -722,6 +722,34 @@ template struct d<int, int>;
} // namespace GH115098
+namespace GH123441 {
+
+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 GH123441
+
namespace GH114685 {
template <typename T> struct ptr {
More information about the cfe-commits
mailing list