[clang] 0077d4c - [Clang] Fix pack indexing profiling (#139276)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 9 09:02:13 PDT 2025
Author: cor3ntin
Date: 2025-05-09T18:02:09+02:00
New Revision: 0077d4ca78342ed009eca324f93f1c62a90399c5
URL: https://github.com/llvm/llvm-project/commit/0077d4ca78342ed009eca324f93f1c62a90399c5
DIFF: https://github.com/llvm/llvm-project/commit/0077d4ca78342ed009eca324f93f1c62a90399c5.diff
LOG: [Clang] Fix pack indexing profiling (#139276)
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 #139057
This mirrors the fix done for SizeOfPackExpr in #124533
Fixes #138255
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/ExprCXX.h
clang/include/clang/AST/Type.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/AST/Type.cpp
clang/test/SemaTemplate/concepts-out-of-line-def.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3f38d510f7ad1..e8e67e14f007b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -679,6 +679,7 @@ Bug Fixes to C++ Support
whose type depends on itself. (#GH51347), (#GH55872)
- Improved parser recovery of invalid requirement expressions. In turn, this
fixes crashes from follow-on processing of the invalid requirement. (#GH138820)
+- Fixed the handling of pack indexing types in the constraints of a member function redeclaration. (#GH138255)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index e107db458742e..1fdc488a76507 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -221,7 +221,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::ContextualFoldingSet<DependentDecltypeType, ASTContext &>
DependentDecltypeTypes;
- mutable llvm::FoldingSet<PackIndexingType> DependentPackIndexingTypes;
+ mutable llvm::ContextualFoldingSet<PackIndexingType, ASTContext &>
+ DependentPackIndexingTypes;
mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
mutable llvm::FoldingSet<ObjCTypeParamType> ObjCTypeParamTypes;
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 8710f252a0c5c..e26eeb2f59a5f 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -4547,6 +4547,7 @@ class PackIndexingExpr final
static PackIndexingExpr *CreateDeserialized(ASTContext &Context,
unsigned NumTransformedExprs);
+ // The index expression and all elements of the pack have been substituted.
bool isFullySubstituted() const { return FullySubstituted; }
/// Determine if the expression was expanded to empty.
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 773796a55eaa1..242d7b72bd5b8 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -5976,7 +5976,6 @@ class PackIndexingType final
private llvm::TrailingObjects<PackIndexingType, QualType> {
friend TrailingObjects;
- const ASTContext &Context;
QualType Pattern;
Expr *IndexExpr;
@@ -5987,9 +5986,8 @@ class PackIndexingType final
protected:
friend class ASTContext; // ASTContext creates these.
- PackIndexingType(const ASTContext &Context, QualType Canonical,
- QualType Pattern, Expr *IndexExpr, bool FullySubstituted,
- ArrayRef<QualType> Expansions = {});
+ PackIndexingType(QualType Canonical, QualType Pattern, Expr *IndexExpr,
+ bool FullySubstituted, ArrayRef<QualType> Expansions = {});
public:
Expr *getIndexExpr() const { return IndexExpr; }
@@ -6024,14 +6022,10 @@ class PackIndexingType final
return T->getTypeClass() == PackIndexing;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
- if (hasSelectedType())
- getSelectedType().Profile(ID);
- else
- Profile(ID, Context, getPattern(), getIndexExpr(), isFullySubstituted());
- }
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context);
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- QualType Pattern, Expr *E, bool FullySubstituted);
+ QualType Pattern, Expr *E, bool FullySubstituted,
+ ArrayRef<QualType> Expansions);
private:
const QualType *getExpansionsPtr() const {
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 92b246a83bcec..0ace0a55afd7a 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -940,7 +940,7 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
DependentSizedMatrixTypes(this_()),
FunctionProtoTypes(this_(), FunctionProtoTypesLog2InitSize),
DependentTypeOfExprTypes(this_()), DependentDecltypeTypes(this_()),
- TemplateSpecializationTypes(this_()),
+ DependentPackIndexingTypes(this_()), TemplateSpecializationTypes(this_()),
DependentTemplateSpecializationTypes(this_()),
DependentBitIntTypes(this_()), SubstTemplateTemplateParmPacks(this_()),
DeducedTemplates(this_()), ArrayParameterTypes(this_()),
@@ -6438,7 +6438,7 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr,
} else {
llvm::FoldingSetNodeID ID;
PackIndexingType::Profile(ID, *this, Pattern.getCanonicalType(), IndexExpr,
- FullySubstituted);
+ FullySubstituted, Expansions);
void *InsertPos = nullptr;
PackIndexingType *Canon =
DependentPackIndexingTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -6446,9 +6446,9 @@ QualType ASTContext::getPackIndexingType(QualType Pattern, Expr *IndexExpr,
void *Mem = Allocate(
PackIndexingType::totalSizeToAlloc<QualType>(Expansions.size()),
TypeAlignment);
- Canon = new (Mem)
- PackIndexingType(*this, QualType(), Pattern.getCanonicalType(),
- IndexExpr, FullySubstituted, Expansions);
+ Canon =
+ new (Mem) PackIndexingType(QualType(), Pattern.getCanonicalType(),
+ IndexExpr, FullySubstituted, Expansions);
DependentPackIndexingTypes.InsertNode(Canon, InsertPos);
}
Canonical = QualType(Canon, 0);
@@ -6457,7 +6457,7 @@ 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,
+ auto *T = new (Mem) PackIndexingType(Canonical, Pattern, IndexExpr,
FullySubstituted, Expansions);
Types.push_back(T);
return QualType(T, 0);
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 83d54da9be7e5..f7d1655f67ed1 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2291,9 +2291,15 @@ void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
}
void StmtProfiler::VisitPackIndexingExpr(const PackIndexingExpr *E) {
- VisitExpr(E);
- VisitExpr(E->getPackIdExpression());
VisitExpr(E->getIndexExpr());
+
+ if (E->expandsToEmptyPack() || E->getExpressions().size() != 0) {
+ ID.AddInteger(E->getExpressions().size());
+ for (const Expr *Sub : E->getExpressions())
+ Visit(Sub);
+ } else {
+ VisitExpr(E->getPackIdExpression());
+ }
}
void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 3dde0e6b3a8b8..9b37f25e723f7 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -4125,14 +4125,14 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID,
E->Profile(ID, Context, true);
}
-PackIndexingType::PackIndexingType(const ASTContext &Context,
- QualType Canonical, QualType Pattern,
+PackIndexingType::PackIndexingType(QualType Canonical, QualType Pattern,
Expr *IndexExpr, bool FullySubstituted,
ArrayRef<QualType> Expansions)
: Type(PackIndexing, Canonical,
computeDependence(Pattern, IndexExpr, Expansions)),
- Context(Context), Pattern(Pattern), IndexExpr(IndexExpr),
- Size(Expansions.size()), FullySubstituted(FullySubstituted) {
+ Pattern(Pattern), IndexExpr(IndexExpr), Size(Expansions.size()),
+ FullySubstituted(FullySubstituted) {
+
llvm::uninitialized_copy(Expansions, getTrailingObjects<QualType>());
}
@@ -4173,12 +4173,26 @@ PackIndexingType::computeDependence(QualType Pattern, Expr *IndexExpr,
return TD;
}
+void PackIndexingType::Profile(llvm::FoldingSetNodeID &ID,
+ const ASTContext &Context) {
+ Profile(ID, Context, getPattern(), getIndexExpr(), isFullySubstituted(),
+ getExpansions());
+}
+
void PackIndexingType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context, QualType Pattern,
- Expr *E, bool FullySubstituted) {
- Pattern.Profile(ID);
+ Expr *E, bool FullySubstituted,
+ ArrayRef<QualType> Expansions) {
+
E->Profile(ID, Context, true);
ID.AddBoolean(FullySubstituted);
+ if (!Expansions.empty()) {
+ ID.AddInteger(Expansions.size());
+ for (QualType T : Expansions)
+ T.getCanonicalType().Profile(ID);
+ } else {
+ Pattern.Profile(ID);
+ }
}
UnaryTransformType::UnaryTransformType(QualType BaseType,
diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
index 5af4ec75cae90..e5d00491d3fb8 100644
--- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -std=c++20 -verify %s
+// RUN: %clang_cc1 -std=c++20 -Wno-c++26-extensions -verify %s
+// RUN: %clang_cc1 -std=c++2c -Wno-c++26-extensions -verify %s
+
static constexpr int PRIMARY = 0;
static constexpr int SPECIALIZATION_CONCEPT = 1;
@@ -779,3 +781,75 @@ template <typename T>
consteval void S::mfn() requires (bool(&fn)) {}
}
+
+
+namespace GH138255 {
+
+template <typename... T>
+concept C = true;
+
+struct Func {
+ template<typename... Ts>
+ requires C<Ts...[0]>
+ static auto buggy() -> void;
+
+ template<typename... Ts>
+ requires C<Ts...[0]>
+ friend auto fr() -> void;
+
+ template<typename... Ts>
+ requires C<Ts...[0]>
+ friend auto fr2() -> void{}; // expected-note{{previous definition is here}}
+};
+
+template<typename... Ts>
+requires C<Ts...[0]>
+auto Func::buggy() -> void {}
+
+template<typename... Ts>
+requires C<Ts...[0]>
+auto fr() -> void {}
+
+template<typename... Ts>
+requires C<Ts...[0]>
+auto fr2() -> void {} // expected-error{{redefinition of 'fr2'}}
+
+
+template <typename... Ts>
+requires C<Ts...[0]>
+struct Class;
+
+template <typename... Ts>
+requires C<Ts...[0]>
+struct Class;
+
+
+template <typename...>
+struct TplClass {
+ template<typename... Ts>
+ requires C<Ts...[0]>
+ static auto buggy() -> void;
+};
+
+template<>
+template<typename... Ts>
+requires C<Ts...[0]>
+auto TplClass<int>::buggy() -> void {}
+
+}
+
+namespace PackIndexExpr {
+template <int... T>
+concept C = true;
+
+template <typename...> struct TplClass {
+ template <int... Ts>
+ requires C<Ts...[0]>
+ static auto buggy() -> void;
+};
+
+template <>
+template <int... Ts>
+requires C<Ts...[0]>
+auto TplClass<int>::buggy() -> void {}
+}
More information about the cfe-commits
mailing list