diff options
-rw-r--r-- | clang/docs/ReleaseNotes.rst | 2 | ||||
-rw-r--r-- | clang/include/clang/AST/Type.h | 13 | ||||
-rw-r--r-- | clang/include/clang/AST/TypeProperties.td | 5 | ||||
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 12 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 4 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx2c-pack-indexing.cpp | 12 |
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 |