Skip to content

Commit 9171151

Browse files
committed
[Clang] Fix pack indexing profiling
When profiling a pack indexing that has been partially substituted, we should profile the expansions, rather than the pattern itseld This is a better approach to llvm#139057 This mirrors the fix done for SizeOfPackExpr in llvm#124533 Fixes llvm#138255
1 parent 160abfb commit 9171151

File tree

8 files changed

+119
-25
lines changed

8 files changed

+119
-25
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,7 @@ Bug Fixes to C++ Support
667667
whose type depends on itself. (#GH51347), (#GH55872)
668668
- Improved parser recovery of invalid requirement expressions. In turn, this
669669
fixes crashes from follow-on processing of the invalid requirement. (#GH138820)
670+
- Fixed the handling of pack indexing types in the constraints of a member function redeclaration. (#GH138255)
670671

671672
Bug Fixes to AST Handling
672673
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/AST/ASTContext.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
221221
mutable llvm::ContextualFoldingSet<DependentDecltypeType, ASTContext &>
222222
DependentDecltypeTypes;
223223

224-
mutable llvm::FoldingSet<PackIndexingType> DependentPackIndexingTypes;
224+
mutable llvm::ContextualFoldingSet<PackIndexingType, ASTContext &>
225+
DependentPackIndexingTypes;
225226

226227
mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
227228
mutable llvm::FoldingSet<ObjCTypeParamType> ObjCTypeParamTypes;

clang/include/clang/AST/ExprCXX.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4549,6 +4549,10 @@ class PackIndexingExpr final
45494549

45504550
bool isFullySubstituted() const { return FullySubstituted; }
45514551

4552+
bool isPartiallySubstituted() const {
4553+
return isValueDependent() && TransformedExpressions;
4554+
};
4555+
45524556
/// Determine if the expression was expanded to empty.
45534557
bool expandsToEmptyPack() const {
45544558
return isFullySubstituted() && TransformedExpressions == 0;

clang/include/clang/AST/Type.h

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5976,7 +5976,6 @@ class PackIndexingType final
59765976
private llvm::TrailingObjects<PackIndexingType, QualType> {
59775977
friend TrailingObjects;
59785978

5979-
const ASTContext &Context;
59805979
QualType Pattern;
59815980
Expr *IndexExpr;
59825981

@@ -5987,9 +5986,8 @@ class PackIndexingType final
59875986

59885987
protected:
59895988
friend class ASTContext; // ASTContext creates these.
5990-
PackIndexingType(const ASTContext &Context, QualType Canonical,
5991-
QualType Pattern, Expr *IndexExpr, bool FullySubstituted,
5992-
ArrayRef<QualType> Expansions = {});
5989+
PackIndexingType(QualType Canonical, QualType Pattern, Expr *IndexExpr,
5990+
bool FullySubstituted, ArrayRef<QualType> Expansions = {});
59935991

59945992
public:
59955993
Expr *getIndexExpr() const { return IndexExpr; }
@@ -6024,14 +6022,10 @@ class PackIndexingType final
60246022
return T->getTypeClass() == PackIndexing;
60256023
}
60266024

6027-
void Profile(llvm::FoldingSetNodeID &ID) {
6028-
if (hasSelectedType())
6029-
getSelectedType().Profile(ID);
6030-
else
6031-
Profile(ID, Context, getPattern(), getIndexExpr(), isFullySubstituted());
6032-
}
6025+
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context);
60336026
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
6034-
QualType Pattern, Expr *E, bool FullySubstituted);
6027+
QualType Pattern, Expr *E, bool FullySubstituted,
6028+
ArrayRef<QualType> Expansions);
60356029

60366030
private:
60376031
const QualType *getExpansionsPtr() const {

clang/lib/AST/ASTContext.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,7 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
940940
DependentSizedMatrixTypes(this_()),
941941
FunctionProtoTypes(this_(), FunctionProtoTypesLog2InitSize),
942942
DependentTypeOfExprTypes(this_()), DependentDecltypeTypes(this_()),
943-
TemplateSpecializationTypes(this_()),
943+
DependentPackIndexingTypes(this_()), TemplateSpecializationTypes(this_()),
944944
DependentTemplateSpecializationTypes(this_()),
945945
DependentBitIntTypes(this_()), SubstTemplateTemplateParmPacks(this_()),
946946
DeducedTemplates(this_()), ArrayParameterTypes(this_()),
@@ -6438,7 +6438,7 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr,
64386438
} else {
64396439
llvm::FoldingSetNodeID ID;
64406440
PackIndexingType::Profile(ID, *this, Pattern.getCanonicalType(), IndexExpr,
6441-
FullySubstituted);
6441+
FullySubstituted, Expansions);
64426442
void *InsertPos = nullptr;
64436443
PackIndexingType *Canon =
64446444
DependentPackIndexingTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -6447,7 +6447,7 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr,
64476447
PackIndexingType::totalSizeToAlloc<QualType>(Expansions.size()),
64486448
TypeAlignment);
64496449
Canon = new (Mem)
6450-
PackIndexingType(*this, QualType(), Pattern.getCanonicalType(),
6450+
PackIndexingType(QualType(), Pattern.getCanonicalType(),
64516451
IndexExpr, FullySubstituted, Expansions);
64526452
DependentPackIndexingTypes.InsertNode(Canon, InsertPos);
64536453
}
@@ -6457,7 +6457,7 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr,
64576457
void *Mem =
64586458
Allocate(PackIndexingType::totalSizeToAlloc<QualType>(Expansions.size()),
64596459
TypeAlignment);
6460-
auto *T = new (Mem) PackIndexingType(*this, Canonical, Pattern, IndexExpr,
6460+
auto *T = new (Mem) PackIndexingType(Canonical, Pattern, IndexExpr,
64616461
FullySubstituted, Expansions);
64626462
Types.push_back(T);
64636463
return QualType(T, 0);

clang/lib/AST/StmtProfile.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,9 +2291,15 @@ void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
22912291
}
22922292

22932293
void StmtProfiler::VisitPackIndexingExpr(const PackIndexingExpr *E) {
2294-
VisitExpr(E);
2295-
VisitExpr(E->getPackIdExpression());
22962294
VisitExpr(E->getIndexExpr());
2295+
2296+
if (E->isPartiallySubstituted()) {
2297+
ID.AddInteger(E->getExpressions().size());
2298+
for (const Expr *Sub : E->getExpressions())
2299+
Visit(Sub);
2300+
} else {
2301+
VisitExpr(E->getPackIdExpression());
2302+
}
22972303
}
22982304

22992305
void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(

clang/lib/AST/Type.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4126,14 +4126,14 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID,
41264126
E->Profile(ID, Context, true);
41274127
}
41284128

4129-
PackIndexingType::PackIndexingType(const ASTContext &Context,
4130-
QualType Canonical, QualType Pattern,
4129+
PackIndexingType::PackIndexingType(QualType Canonical, QualType Pattern,
41314130
Expr *IndexExpr, bool FullySubstituted,
41324131
ArrayRef<QualType> Expansions)
41334132
: Type(PackIndexing, Canonical,
41344133
computeDependence(Pattern, IndexExpr, Expansions)),
4135-
Context(Context), Pattern(Pattern), IndexExpr(IndexExpr),
4136-
Size(Expansions.size()), FullySubstituted(FullySubstituted) {
4134+
Pattern(Pattern), IndexExpr(IndexExpr), Size(Expansions.size()),
4135+
FullySubstituted(FullySubstituted) {
4136+
41374137
llvm::uninitialized_copy(Expansions, getTrailingObjects<QualType>());
41384138
}
41394139

@@ -4174,12 +4174,26 @@ PackIndexingType::computeDependence(QualType Pattern, Expr *IndexExpr,
41744174
return TD;
41754175
}
41764176

4177+
void PackIndexingType::Profile(llvm::FoldingSetNodeID &ID,
4178+
const ASTContext &Context) {
4179+
Profile(ID, Context, getPattern(), getIndexExpr(), isFullySubstituted(), getExpansions());
4180+
}
4181+
41774182
void PackIndexingType::Profile(llvm::FoldingSetNodeID &ID,
41784183
const ASTContext &Context, QualType Pattern,
4179-
Expr *E, bool FullySubstituted) {
4180-
Pattern.Profile(ID);
4184+
Expr *E, bool FullySubstituted,
4185+
ArrayRef<QualType> Expansions) {
4186+
41814187
E->Profile(ID, Context, true);
41824188
ID.AddBoolean(FullySubstituted);
4189+
if(!Expansions.empty()) {
4190+
ID.AddInteger(Expansions.size());
4191+
for(QualType T : Expansions)
4192+
T.getCanonicalType().Profile(ID);
4193+
}
4194+
else {
4195+
Pattern.Profile(ID);
4196+
}
41834197
}
41844198

41854199
UnaryTransformType::UnaryTransformType(QualType BaseType,

clang/test/SemaTemplate/concepts-out-of-line-def.cpp

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// RUN: %clang_cc1 -std=c++20 -verify %s
1+
// RUN: %clang_cc1 -std=c++20 -Wno-c++26-extensions -verify %s
2+
// RUN: %clang_cc1 -std=c++2c -Wno-c++26-extensions -verify %s
3+
24

35
static constexpr int PRIMARY = 0;
46
static constexpr int SPECIALIZATION_CONCEPT = 1;
@@ -779,3 +781,75 @@ template <typename T>
779781
consteval void S::mfn() requires (bool(&fn)) {}
780782

781783
}
784+
785+
786+
namespace GH138255 {
787+
788+
template <typename... T>
789+
concept C = true;
790+
791+
struct Func {
792+
template<typename... Ts>
793+
requires C<Ts...[0]>
794+
static auto buggy() -> void;
795+
796+
template<typename... Ts>
797+
requires C<Ts...[0]>
798+
friend auto fr() -> void;
799+
800+
template<typename... Ts>
801+
requires C<Ts...[0]>
802+
friend auto fr2() -> void{}; // expected-note{{previous definition is here}}
803+
};
804+
805+
template<typename... Ts>
806+
requires C<Ts...[0]>
807+
auto Func::buggy() -> void {}
808+
809+
template<typename... Ts>
810+
requires C<Ts...[0]>
811+
auto fr() -> void {}
812+
813+
template<typename... Ts>
814+
requires C<Ts...[0]>
815+
auto fr2() -> void {} // expected-error{{redefinition of 'fr2'}}
816+
817+
818+
template <typename... Ts>
819+
requires C<Ts...[0]>
820+
struct Class;
821+
822+
template <typename... Ts>
823+
requires C<Ts...[0]>
824+
struct Class;
825+
826+
827+
template <typename...>
828+
struct TplClass {
829+
template<typename... Ts>
830+
requires C<Ts...[0]>
831+
static auto buggy() -> void;
832+
};
833+
834+
template<>
835+
template<typename... Ts>
836+
requires C<Ts...[0]>
837+
auto TplClass<int>::buggy() -> void {}
838+
839+
}
840+
841+
namespace PackIndexExpr {
842+
template <int... T>
843+
concept C = true;
844+
845+
template <typename...> struct TplClass {
846+
template <int... Ts>
847+
requires C<Ts...[0]>
848+
static auto buggy() -> void;
849+
};
850+
851+
template <>
852+
template <int... Ts>
853+
requires C<Ts...[0]>
854+
auto TplClass<int>::buggy() -> void {}
855+
}

0 commit comments

Comments
 (0)