aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/docs/ReleaseNotes.rst2
-rw-r--r--clang/include/clang/AST/Type.h13
-rw-r--r--clang/include/clang/AST/TypeProperties.td5
-rw-r--r--clang/lib/AST/ASTContext.cpp12
-rw-r--r--clang/lib/AST/Type.cpp7
-rw-r--r--clang/lib/Sema/TreeTransform.h4
-rw-r--r--clang/test/SemaCXX/cxx2c-pack-indexing.cpp12
7 files changed, 39 insertions, 16 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 511724c..4128ca7 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 08f7638..8532261 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 @@ public:
bool hasSelectedType() const { return getSelectedIndex() != std::nullopt; }
+ bool expandsToEmptyPack() const { return ExpandsToEmptyPack; }
+
ArrayRef<QualType> getExpansions() const {
return {getExpansionsPtr(), Size};
}
@@ -5869,10 +5874,10 @@ public:
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 3df1931..539a344 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 c61234a..341ea98 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 e89ce2e..b976d1a 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 66e3f27..27eac40 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 7d7e808..962dbb8 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