[clang] [Clang][Concepts] Normalize SizeOfPackExpr's pack declaration (PR #110238)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 28 08:11:07 PDT 2024
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/110238
>From 23a765ac6d8e455121346405332d2066dcc0861e Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Fri, 27 Sep 2024 18:23:47 +0800
Subject: [PATCH 1/7] [Clang] GH93099
---
clang/include/clang/Sema/Sema.h | 4 ++-
clang/lib/Sema/SemaTemplateVariadic.cpp | 20 +++++++----
clang/lib/Sema/TreeTransform.h | 16 ++++++---
.../SemaTemplate/concepts-out-of-line-def.cpp | 34 +++++++++++++++++++
4 files changed, 61 insertions(+), 13 deletions(-)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e1c3a99cfa167e..1fce74880026ce 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14264,7 +14264,9 @@ class Sema final : public SemaBase {
///
/// This is intended for use when transforming 'sizeof...(Arg)' in order to
/// avoid actually expanding the pack where possible.
- std::optional<unsigned> getFullyPackExpandedSize(TemplateArgument Arg);
+ std::optional<unsigned>
+ getFullyPackExpandedSize(TemplateArgument Arg,
+ const NamedDecl *&ParameterPack);
/// Called when an expression computing the size of a parameter pack
/// is parsed.
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 40522a07f6339c..79e2f1f610b11f 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -1211,7 +1211,9 @@ TemplateArgumentLoc Sema::getTemplateArgumentPackExpansionPattern(
llvm_unreachable("Invalid TemplateArgument Kind!");
}
-std::optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
+std::optional<unsigned>
+Sema::getFullyPackExpandedSize(TemplateArgument Arg,
+ const NamedDecl *&ParameterPack) {
assert(Arg.containsUnexpandedParameterPack());
// If this is a substituted pack, grab that pack. If not, we don't know
@@ -1222,17 +1224,20 @@ std::optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
TemplateArgument Pack;
switch (Arg.getKind()) {
case TemplateArgument::Type:
- if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>())
+ if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>()) {
Pack = Subst->getArgumentPack();
- else
+ ParameterPack = Subst->getReplacedParameter();
+ } else
return std::nullopt;
break;
case TemplateArgument::Expression:
if (auto *Subst =
- dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr()))
+ dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr())) {
Pack = Subst->getArgumentPack();
- else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr())) {
+ ParameterPack = Subst->getParameterPack();
+ } else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr())) {
+ ParameterPack = Subst->getParameterPack();
for (VarDecl *PD : *Subst)
if (PD->isParameterPack())
return std::nullopt;
@@ -1243,9 +1248,10 @@ std::optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
case TemplateArgument::Template:
if (SubstTemplateTemplateParmPackStorage *Subst =
- Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack())
+ Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack()) {
Pack = Subst->getArgumentPack();
- else
+ ParameterPack = Subst->getParameterPack();
+ } else
return std::nullopt;
break;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 91cb980ee26b26..3a029e88e865df 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -15237,6 +15237,7 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
// Try to compute the result without performing a partial substitution.
std::optional<unsigned> Result = 0;
+ NamedDecl *NewPack = E->getPack();
for (const TemplateArgument &Arg : PackArgs) {
if (!Arg.isPackExpansion()) {
Result = *Result + 1;
@@ -15260,9 +15261,14 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
/*Uneval*/ true))
return true;
+ const NamedDecl *TransformedParameterPack = nullptr;
// See if we can determine the number of arguments from the result.
- std::optional<unsigned> NumExpansions =
- getSema().getFullyPackExpandedSize(OutPattern.getArgument());
+ std::optional<unsigned> NumExpansions = getSema().getFullyPackExpandedSize(
+ OutPattern.getArgument(), TransformedParameterPack);
+ if (TransformedParameterPack && !E->isPartiallySubstituted()) {
+ assert(PackArgs.size() == 1);
+ NewPack = const_cast<NamedDecl *>(TransformedParameterPack);
+ }
if (!NumExpansions) {
// No: we must be in an alias template expansion, and we're going to need
// to actually expand the packs.
@@ -15277,7 +15283,7 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
// substituting.
if (Result)
return getDerived().RebuildSizeOfPackExpr(
- E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
+ E->getOperatorLoc(), NewPack, E->getPackLoc(), E->getRParenLoc(),
*Result, std::nullopt);
TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
@@ -15304,10 +15310,10 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
if (PartialSubstitution)
return getDerived().RebuildSizeOfPackExpr(
- E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
+ E->getOperatorLoc(), NewPack, E->getPackLoc(), E->getRParenLoc(),
std::nullopt, Args);
- return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
+ return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), NewPack,
E->getPackLoc(), E->getRParenLoc(),
Args.size(), std::nullopt);
}
diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
index 5450d105a6f54a..8ca399a0f729a9 100644
--- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -666,3 +666,37 @@ int foo() {
}
} // namespace eve
+
+namespace GH93099 {
+
+// Issues with sizeof...(expr)
+
+template <typename T = int> struct C {
+ template <int... N>
+ requires(sizeof...(N) > 0)
+ friend class NTTP;
+
+ template <class... Tp>
+ requires(sizeof...(Tp) > 0)
+ friend class TP;
+
+ template <template <typename> class... TTp>
+ requires(sizeof...(TTp) > 0)
+ friend class TTP;
+};
+
+template <int... N>
+ requires(sizeof...(N) > 0)
+class NTTP;
+
+template <class... Tp>
+ requires(sizeof...(Tp) > 0)
+class TP;
+
+template <template <typename> class... TTp>
+ requires(sizeof...(TTp) > 0)
+class TTP;
+
+C v;
+
+} // namespace GH93099
>From e36ecb4ff45d97c445f3ac81b3df8bd2b8ddab14 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Fri, 27 Sep 2024 22:13:39 +0800
Subject: [PATCH 2/7] Fix CI - the associated Decls are wrong previously
---
clang/lib/Sema/SemaTemplateInstantiate.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index fd51fa4afcacbf..3e8b04743c5562 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -371,7 +371,7 @@ Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD,
Specialization->getTemplateInstantiationArgs().asArray();
}
Result.addOuterTemplateArguments(
- const_cast<FunctionTemplateDecl *>(FTD), Arguments,
+ TSTy->getTemplateName().getAsTemplateDecl(), Arguments,
/*Final=*/false);
}
}
>From a798926c842c3562e2ad7252fd182a221f6bc4d6 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sat, 28 Sep 2024 20:02:51 +0800
Subject: [PATCH 3/7] Revert "[Clang] GH93099"
This reverts commit 23a765ac6d8e455121346405332d2066dcc0861e.
---
clang/include/clang/Sema/Sema.h | 4 +--
clang/lib/Sema/SemaTemplateVariadic.cpp | 20 ++++-------
clang/lib/Sema/TreeTransform.h | 16 +++------
.../SemaTemplate/concepts-out-of-line-def.cpp | 34 -------------------
4 files changed, 13 insertions(+), 61 deletions(-)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1fce74880026ce..e1c3a99cfa167e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -14264,9 +14264,7 @@ class Sema final : public SemaBase {
///
/// This is intended for use when transforming 'sizeof...(Arg)' in order to
/// avoid actually expanding the pack where possible.
- std::optional<unsigned>
- getFullyPackExpandedSize(TemplateArgument Arg,
- const NamedDecl *&ParameterPack);
+ std::optional<unsigned> getFullyPackExpandedSize(TemplateArgument Arg);
/// Called when an expression computing the size of a parameter pack
/// is parsed.
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 79e2f1f610b11f..40522a07f6339c 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -1211,9 +1211,7 @@ TemplateArgumentLoc Sema::getTemplateArgumentPackExpansionPattern(
llvm_unreachable("Invalid TemplateArgument Kind!");
}
-std::optional<unsigned>
-Sema::getFullyPackExpandedSize(TemplateArgument Arg,
- const NamedDecl *&ParameterPack) {
+std::optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
assert(Arg.containsUnexpandedParameterPack());
// If this is a substituted pack, grab that pack. If not, we don't know
@@ -1224,20 +1222,17 @@ Sema::getFullyPackExpandedSize(TemplateArgument Arg,
TemplateArgument Pack;
switch (Arg.getKind()) {
case TemplateArgument::Type:
- if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>()) {
+ if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>())
Pack = Subst->getArgumentPack();
- ParameterPack = Subst->getReplacedParameter();
- } else
+ else
return std::nullopt;
break;
case TemplateArgument::Expression:
if (auto *Subst =
- dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr())) {
+ dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr()))
Pack = Subst->getArgumentPack();
- ParameterPack = Subst->getParameterPack();
- } else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr())) {
- ParameterPack = Subst->getParameterPack();
+ else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr())) {
for (VarDecl *PD : *Subst)
if (PD->isParameterPack())
return std::nullopt;
@@ -1248,10 +1243,9 @@ Sema::getFullyPackExpandedSize(TemplateArgument Arg,
case TemplateArgument::Template:
if (SubstTemplateTemplateParmPackStorage *Subst =
- Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack()) {
+ Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack())
Pack = Subst->getArgumentPack();
- ParameterPack = Subst->getParameterPack();
- } else
+ else
return std::nullopt;
break;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 3a029e88e865df..91cb980ee26b26 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -15237,7 +15237,6 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
// Try to compute the result without performing a partial substitution.
std::optional<unsigned> Result = 0;
- NamedDecl *NewPack = E->getPack();
for (const TemplateArgument &Arg : PackArgs) {
if (!Arg.isPackExpansion()) {
Result = *Result + 1;
@@ -15261,14 +15260,9 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
/*Uneval*/ true))
return true;
- const NamedDecl *TransformedParameterPack = nullptr;
// See if we can determine the number of arguments from the result.
- std::optional<unsigned> NumExpansions = getSema().getFullyPackExpandedSize(
- OutPattern.getArgument(), TransformedParameterPack);
- if (TransformedParameterPack && !E->isPartiallySubstituted()) {
- assert(PackArgs.size() == 1);
- NewPack = const_cast<NamedDecl *>(TransformedParameterPack);
- }
+ std::optional<unsigned> NumExpansions =
+ getSema().getFullyPackExpandedSize(OutPattern.getArgument());
if (!NumExpansions) {
// No: we must be in an alias template expansion, and we're going to need
// to actually expand the packs.
@@ -15283,7 +15277,7 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
// substituting.
if (Result)
return getDerived().RebuildSizeOfPackExpr(
- E->getOperatorLoc(), NewPack, E->getPackLoc(), E->getRParenLoc(),
+ E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
*Result, std::nullopt);
TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
@@ -15310,10 +15304,10 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
if (PartialSubstitution)
return getDerived().RebuildSizeOfPackExpr(
- E->getOperatorLoc(), NewPack, E->getPackLoc(), E->getRParenLoc(),
+ E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
std::nullopt, Args);
- return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), NewPack,
+ return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
E->getPackLoc(), E->getRParenLoc(),
Args.size(), std::nullopt);
}
diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
index 8ca399a0f729a9..5450d105a6f54a 100644
--- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -666,37 +666,3 @@ int foo() {
}
} // namespace eve
-
-namespace GH93099 {
-
-// Issues with sizeof...(expr)
-
-template <typename T = int> struct C {
- template <int... N>
- requires(sizeof...(N) > 0)
- friend class NTTP;
-
- template <class... Tp>
- requires(sizeof...(Tp) > 0)
- friend class TP;
-
- template <template <typename> class... TTp>
- requires(sizeof...(TTp) > 0)
- friend class TTP;
-};
-
-template <int... N>
- requires(sizeof...(N) > 0)
-class NTTP;
-
-template <class... Tp>
- requires(sizeof...(Tp) > 0)
-class TP;
-
-template <template <typename> class... TTp>
- requires(sizeof...(TTp) > 0)
-class TTP;
-
-C v;
-
-} // namespace GH93099
>From 9c72edc5e119399f809eaed3acbd5018f538368c Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sat, 28 Sep 2024 21:56:37 +0800
Subject: [PATCH 4/7] Only transform SizeOfPackExprs' pack decls when
normalizing constraints
---
clang/include/clang/AST/ExprCXX.h | 2 ++
clang/lib/Sema/SemaConcept.cpp | 14 +++++---
clang/lib/Sema/SemaTemplateInstantiate.cpp | 27 +++++++++++++++
.../SemaTemplate/concepts-out-of-line-def.cpp | 34 +++++++++++++++++++
4 files changed, 72 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 975bcdac5069b9..dfcf739ed1614f 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -4326,6 +4326,8 @@ 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/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 6a1b32598bb4a6..67fc603e9ce1d5 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -975,11 +975,14 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
// parameters that the surrounding function hasn't been instantiated yet. Note
// this may happen while we're comparing two templates' constraint
// equivalence.
- LocalInstantiationScope ScopeForParameters(S);
- if (auto *FD = DeclInfo.getDecl()->getAsFunction())
+ std::optional<LocalInstantiationScope> ScopeForParameters;
+ if (const NamedDecl *ND = DeclInfo.getDecl();
+ ND && ND->isFunctionOrFunctionTemplate()) {
+ ScopeForParameters.emplace(S);
+ const FunctionDecl *FD = ND->getAsFunction();
for (auto *PVD : FD->parameters()) {
if (!PVD->isParameterPack()) {
- ScopeForParameters.InstantiatedLocal(PVD, PVD);
+ ScopeForParameters->InstantiatedLocal(PVD, PVD);
continue;
}
// This is hacky: we're mapping the parameter pack to a size-of-1 argument
@@ -998,9 +1001,10 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
// that we can eliminate the Scope in the cases where the declarations are
// not necessarily instantiated. It would also benefit the noexcept
// specifier comparison.
- ScopeForParameters.MakeInstantiatedLocalArgPack(PVD);
- ScopeForParameters.InstantiatedLocalPackArg(PVD, PVD);
+ ScopeForParameters->MakeInstantiatedLocalArgPack(PVD);
+ ScopeForParameters->InstantiatedLocalPackArg(PVD, PVD);
}
+ }
std::optional<Sema::CXXThisScopeRAII> ThisScope;
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 3e8b04743c5562..eaf8cb6b2dae10 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/AST/RecursiveASTVisitor.h"
@@ -1722,6 +1723,32 @@ namespace {
return inherited::TransformLambdaBody(E, Body);
}
+ ExprResult TransformSizeOfPackExpr(SizeOfPackExpr *E) {
+ ExprResult Result = inherited::TransformSizeOfPackExpr(E);
+
+ if (SemaRef.CodeSynthesisContexts.back().Kind !=
+ Sema::CodeSynthesisContext::ConstraintNormalization)
+ return Result;
+
+ if (!Result.isUsable())
+ return Result;
+
+ SizeOfPackExpr *NewExpr = cast<SizeOfPackExpr>(Result.get());
+#ifndef NDEBUG
+ for (auto *Iter = TemplateArgs.begin(); Iter != TemplateArgs.end();
+ ++Iter)
+ for (const TemplateArgument &TA : Iter->Args)
+ assert(TA.getKind() != TemplateArgument::Pack || TA.pack_size() == 1);
+#endif
+ Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0);
+ Decl *NewDecl = TransformDecl(NewExpr->getPackLoc(), NewExpr->getPack());
+ if (!NewDecl)
+ return ExprError();
+
+ NewExpr->setPack(cast<NamedDecl>(NewDecl));
+ return NewExpr;
+ }
+
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 5450d105a6f54a..8ca399a0f729a9 100644
--- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -666,3 +666,37 @@ int foo() {
}
} // namespace eve
+
+namespace GH93099 {
+
+// Issues with sizeof...(expr)
+
+template <typename T = int> struct C {
+ template <int... N>
+ requires(sizeof...(N) > 0)
+ friend class NTTP;
+
+ template <class... Tp>
+ requires(sizeof...(Tp) > 0)
+ friend class TP;
+
+ template <template <typename> class... TTp>
+ requires(sizeof...(TTp) > 0)
+ friend class TTP;
+};
+
+template <int... N>
+ requires(sizeof...(N) > 0)
+class NTTP;
+
+template <class... Tp>
+ requires(sizeof...(Tp) > 0)
+class TP;
+
+template <template <typename> class... TTp>
+ requires(sizeof...(TTp) > 0)
+class TTP;
+
+C v;
+
+} // namespace GH93099
>From 1e384b5c6cc4686e234ef85d6c25cc0d2e3184ec Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sat, 28 Sep 2024 21:58:41 +0800
Subject: [PATCH 5/7] Remove unnecessary includes
---
clang/lib/Sema/SemaTemplateInstantiate.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index eaf8cb6b2dae10..20215d32539af9 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -18,7 +18,6 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/AST/RecursiveASTVisitor.h"
>From 391696e33b7a990b23f89e1c8f631a2feed1809e Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sat, 28 Sep 2024 22:50:53 +0800
Subject: [PATCH 6/7] Add a release note
---
clang/docs/ReleaseNotes.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1fbcac807d0b30..831dab0657fcaf 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -444,6 +444,8 @@ Bug Fixes to C++ Support
- Fixed an assertion failure in debug mode, and potential crashes in release mode, when
diagnosing a failed cast caused indirectly by a failed implicit conversion to the type of the constructor parameter.
- Fixed an assertion failure by adjusting integral to boolean vector conversions (#GH108326)
+- Fixed a bug in constraint expression comparison where the ``sizeof...`` expression was not handled properly
+ in certain friend declarations. (#GH93099)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
>From 314469807d47049faa4bb3114ba25fc1b8d63bc1 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sat, 28 Sep 2024 23:10:26 +0800
Subject: [PATCH 7/7] Use RebuildSizeOfPackExpr instead
---
clang/include/clang/AST/ExprCXX.h | 2 --
clang/lib/Sema/SemaTemplateInstantiate.cpp | 24 +++++++++++-----------
2 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index dfcf739ed1614f..975bcdac5069b9 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/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 20215d32539af9..16110629a36d02 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1722,17 +1722,16 @@ namespace {
return inherited::TransformLambdaBody(E, Body);
}
- ExprResult TransformSizeOfPackExpr(SizeOfPackExpr *E) {
- ExprResult Result = inherited::TransformSizeOfPackExpr(E);
-
+ ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc,
+ NamedDecl *Pack, SourceLocation PackLoc,
+ SourceLocation RParenLoc,
+ std::optional<unsigned> Length,
+ ArrayRef<TemplateArgument> PartialArgs) {
if (SemaRef.CodeSynthesisContexts.back().Kind !=
Sema::CodeSynthesisContext::ConstraintNormalization)
- return Result;
-
- if (!Result.isUsable())
- return Result;
+ return inherited::RebuildSizeOfPackExpr(OperatorLoc, Pack, PackLoc,
+ RParenLoc, Length, PartialArgs);
- SizeOfPackExpr *NewExpr = cast<SizeOfPackExpr>(Result.get());
#ifndef NDEBUG
for (auto *Iter = TemplateArgs.begin(); Iter != TemplateArgs.end();
++Iter)
@@ -1740,12 +1739,13 @@ namespace {
assert(TA.getKind() != TemplateArgument::Pack || TA.pack_size() == 1);
#endif
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0);
- Decl *NewDecl = TransformDecl(NewExpr->getPackLoc(), NewExpr->getPack());
- if (!NewDecl)
+ Decl *NewPack = TransformDecl(PackLoc, Pack);
+ if (!NewPack)
return ExprError();
- NewExpr->setPack(cast<NamedDecl>(NewDecl));
- return NewExpr;
+ return inherited::RebuildSizeOfPackExpr(OperatorLoc,
+ cast<NamedDecl>(NewPack), PackLoc,
+ RParenLoc, Length, PartialArgs);
}
ExprResult TransformRequiresExpr(RequiresExpr *E) {
More information about the cfe-commits
mailing list