[clang] aacdc65 - [Clang] Preserve the ExpandsToEmpty flag in PackIndexingType (#107181)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 4 01:34:31 PDT 2024
Author: Younan Zhang
Date: 2024-09-04T16:34:27+08:00
New Revision: aacdc657fc255b2547bb37ee9bacde2df0452298
URL: https://github.com/llvm/llvm-project/commit/aacdc657fc255b2547bb37ee9bacde2df0452298
DIFF: https://github.com/llvm/llvm-project/commit/aacdc657fc255b2547bb37ee9bacde2df0452298.diff
LOG: [Clang] Preserve the ExpandsToEmpty flag in PackIndexingType (#107181)
Similar to PackIndexingExpr, we should avoid another round of
transformation of the pattern if the pattern has already turned out to
be an empty pack. As an outcome, the empty SubstTemplateTypeParmPackType
won't occur, and we don't need to collect any unexpanded packs.
Fixes https://github.com/llvm/llvm-project/issues/105903
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/AST/Type.h
clang/include/clang/AST/TypeProperties.td
clang/lib/AST/ASTContext.cpp
clang/lib/AST/Type.cpp
clang/lib/Sema/TreeTransform.h
clang/test/SemaCXX/cxx2c-pack-indexing.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 511724c73015ea..4128ca78ce3960 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -345,7 +345,7 @@ Bug Fixes to C++ Support
- Fixed a constraint comparison bug for friend declarations. (#GH78101)
- Fix handling of ``_`` as the name of a lambda's init capture variable. (#GH107024)
- Fix an issue with dependent source location expressions (#GH106428), (#GH81155), (#GH80210), (#GH85373)
-
+- Fixed a bug in the substitution of empty pack indexing types. (#GH105903)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 08f7638d7d8f96..853226118af407 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -5828,12 +5828,15 @@ class PackIndexingType final
QualType Pattern;
Expr *IndexExpr;
- unsigned Size;
+ unsigned Size : 31;
+
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ExpandsToEmptyPack : 1;
protected:
friend class ASTContext; // ASTContext creates these.
PackIndexingType(const ASTContext &Context, QualType Canonical,
- QualType Pattern, Expr *IndexExpr,
+ QualType Pattern, Expr *IndexExpr, bool ExpandsToEmptyPack,
ArrayRef<QualType> Expansions = {});
public:
@@ -5857,6 +5860,8 @@ class PackIndexingType final
bool hasSelectedType() const { return getSelectedIndex() != std::nullopt; }
+ bool expandsToEmptyPack() const { return ExpandsToEmptyPack; }
+
ArrayRef<QualType> getExpansions() const {
return {getExpansionsPtr(), Size};
}
@@ -5869,10 +5874,10 @@ class PackIndexingType final
if (hasSelectedType())
getSelectedType().Profile(ID);
else
- Profile(ID, Context, getPattern(), getIndexExpr());
+ Profile(ID, Context, getPattern(), getIndexExpr(), expandsToEmptyPack());
}
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- QualType Pattern, Expr *E);
+ QualType Pattern, Expr *E, bool ExpandsToEmptyPack);
private:
const QualType *getExpansionsPtr() const {
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 3df19315fd573f..539a344cb0b690 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -473,9 +473,12 @@ let Class = PackIndexingType in {
def : Property<"indexExpression", ExprRef> {
let Read = [{ node->getIndexExpr() }];
}
+ def : Property<"expandsToEmptyPack", Bool> {
+ let Read = [{ node->expandsToEmptyPack() }];
+ }
def : Creator<[{
- return ctx.getPackIndexingType(pattern, indexExpression);
+ return ctx.getPackIndexingType(pattern, indexExpression, expandsToEmptyPack);
}]>;
}
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index c61234aa4d1af1..341ea98a1b1490 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -6188,11 +6188,13 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr,
ArrayRef<QualType> Expansions,
int Index) const {
QualType Canonical;
+ bool ExpandsToEmptyPack = FullySubstituted && Expansions.empty();
if (FullySubstituted && Index != -1) {
Canonical = getCanonicalType(Expansions[Index]);
} else {
llvm::FoldingSetNodeID ID;
- PackIndexingType::Profile(ID, *this, Pattern, IndexExpr);
+ PackIndexingType::Profile(ID, *this, Pattern, IndexExpr,
+ ExpandsToEmptyPack);
void *InsertPos = nullptr;
PackIndexingType *Canon =
DependentPackIndexingTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -6200,8 +6202,8 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr,
void *Mem = Allocate(
PackIndexingType::totalSizeToAlloc<QualType>(Expansions.size()),
TypeAlignment);
- Canon = new (Mem)
- PackIndexingType(*this, QualType(), Pattern, IndexExpr, Expansions);
+ Canon = new (Mem) PackIndexingType(*this, QualType(), Pattern, IndexExpr,
+ ExpandsToEmptyPack, Expansions);
DependentPackIndexingTypes.InsertNode(Canon, InsertPos);
}
Canonical = QualType(Canon, 0);
@@ -6210,8 +6212,8 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr,
void *Mem =
Allocate(PackIndexingType::totalSizeToAlloc<QualType>(Expansions.size()),
TypeAlignment);
- auto *T = new (Mem)
- PackIndexingType(*this, Canonical, Pattern, IndexExpr, Expansions);
+ auto *T = new (Mem) PackIndexingType(*this, Canonical, Pattern, IndexExpr,
+ ExpandsToEmptyPack, Expansions);
Types.push_back(T);
return QualType(T, 0);
}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e89ce2e4b38445..b976d1a0ee60ae 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -3992,12 +3992,12 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID,
PackIndexingType::PackIndexingType(const ASTContext &Context,
QualType Canonical, QualType Pattern,
- Expr *IndexExpr,
+ Expr *IndexExpr, bool ExpandsToEmptyPack,
ArrayRef<QualType> Expansions)
: Type(PackIndexing, Canonical,
computeDependence(Pattern, IndexExpr, Expansions)),
Context(Context), Pattern(Pattern), IndexExpr(IndexExpr),
- Size(Expansions.size()) {
+ Size(Expansions.size()), ExpandsToEmptyPack(ExpandsToEmptyPack) {
std::uninitialized_copy(Expansions.begin(), Expansions.end(),
getTrailingObjects<QualType>());
@@ -4042,9 +4042,10 @@ PackIndexingType::computeDependence(QualType Pattern, Expr *IndexExpr,
void PackIndexingType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context, QualType Pattern,
- Expr *E) {
+ Expr *E, bool ExpandsToEmptyPack) {
Pattern.Profile(ID);
E->Profile(ID, Context, true);
+ ID.AddBoolean(ExpandsToEmptyPack);
}
UnaryTransformType::UnaryTransformType(QualType BaseType,
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 66e3f27fed9de0..27eac401c28f5d 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6687,10 +6687,10 @@ TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
bool NotYetExpanded = Types.empty();
bool FullySubstituted = true;
- if (Types.empty())
+ if (Types.empty() && !PIT->expandsToEmptyPack())
Types = llvm::ArrayRef<QualType>(&Pattern, 1);
- for (const QualType &T : Types) {
+ for (QualType T : Types) {
if (!T->containsUnexpandedParameterPack()) {
QualType Transformed = getDerived().TransformType(T);
if (Transformed.isNull())
diff --git a/clang/test/SemaCXX/cxx2c-pack-indexing.cpp b/clang/test/SemaCXX/cxx2c-pack-indexing.cpp
index 7d7e808746217f..962dbb8137f289 100644
--- a/clang/test/SemaCXX/cxx2c-pack-indexing.cpp
+++ b/clang/test/SemaCXX/cxx2c-pack-indexing.cpp
@@ -258,4 +258,16 @@ void f() {
vars<0>::x<0>();
}
+} // namespace GH105900
+
+namespace GH105903 {
+
+template <typename... opts> struct temp {
+ template <unsigned s> static auto x() -> opts... [s] {} // expected-note {{invalid index 0 for pack 'opts' of size 0}}
+};
+
+void f() {
+ temp<>::x<0>(); // expected-error {{no matching}}
}
+
+} // namespace GH105903
More information about the cfe-commits
mailing list