https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/197598
>From e39b020cb7dbb434d86c88271f7583b67424ce59 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <[email protected]> Date: Wed, 13 May 2026 19:02:49 -0300 Subject: [PATCH] [clang] NFC: add asserts enforcing template parameters have valid positions Some tests are violating these assertions, so they are commented out. For the test in `clang/test/SemaTemplate/concepts.cpp`, that was broken by #195995 and needs a partial revert at least. --- clang/include/clang/AST/ASTContext.h | 3 +- clang/include/clang/AST/DeclTemplate.h | 59 +++++++++------------ clang/include/clang/AST/TypeBase.h | 9 +++- clang/lib/AST/ASTContext.cpp | 9 ++-- clang/lib/AST/DeclTemplate.cpp | 29 +++++----- clang/lib/Sema/SemaTemplateDeduction.cpp | 4 +- clang/test/SemaTemplate/concepts-lambda.cpp | 7 ++- clang/test/SemaTemplate/concepts.cpp | 4 +- 8 files changed, 64 insertions(+), 60 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index c45d54fdd2e88..b2fd522e6865c 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1998,8 +1998,7 @@ class ASTContext : public RefCountedBase<ASTContext> { QualType getSubstBuiltinTemplatePack(const TemplateArgument &ArgPack); QualType - getTemplateTypeParmType(unsigned Depth, unsigned Index, - bool ParameterPack, + getTemplateTypeParmType(int Depth, int Index, bool ParameterPack, TemplateTypeParmDecl *ParmDecl = nullptr) const; QualType getCanonicalTemplateSpecializationType( diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 9fb41c87da732..914bfb529302e 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -1128,16 +1128,9 @@ class TemplateParmPosition { unsigned Depth : DepthWidth; unsigned Position : PositionWidth; - static constexpr unsigned MaxDepth = (1U << DepthWidth) - 1; - static constexpr unsigned MaxPosition = (1U << PositionWidth) - 1; - - TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) { - // The input may fill maximum values to show that it is invalid. - // Add one here to convert it to zero. - assert((D + 1) <= MaxDepth && - "The depth of template parmeter position is more than 2^20!"); - assert((P + 1) <= MaxPosition && - "The position of template parmeter position is more than 2^12!"); + TemplateParmPosition(int D, int P) { + setDepth(D); + setPosition(P); } public: @@ -1145,17 +1138,17 @@ class TemplateParmPosition { /// Get the nesting depth of the template parameter. unsigned getDepth() const { return Depth; } - void setDepth(unsigned D) { - assert((D + 1) <= MaxDepth && - "The depth of template parmeter position is more than 2^20!"); + void setDepth(int D) { + assert(D >= 0 && "The depth cannot be negative"); + assert(D < (1 << DepthWidth) && "The depth is too large"); Depth = D; } /// Get the position of the template parameter within its parameter list. unsigned getPosition() const { return Position; } - void setPosition(unsigned P) { - assert((P + 1) <= MaxPosition && - "The position of template parmeter position is more than 2^12!"); + void setPosition(int P) { + assert(P >= 0 && "The position cannot be negative"); + assert(P < (1 << PositionWidth) && "The position is too large"); Position = P; } @@ -1208,7 +1201,7 @@ class TemplateTypeParmDecl final : public TypeDecl, public: static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, - SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, + SourceLocation NameLoc, int D, int P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint = false, UnsignedOrNone NumExpanded = std::nullopt); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, @@ -1389,14 +1382,14 @@ class NonTypeTemplateParmDecl final } NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, unsigned D, unsigned P, + SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo) : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), TemplateParmPosition(D, P), ParameterPack(ParameterPack) {} NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, unsigned D, unsigned P, + SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, @@ -1405,12 +1398,12 @@ class NonTypeTemplateParmDecl final public: static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, + SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo); static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, + SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos); @@ -1609,8 +1602,8 @@ class TemplateTemplateParmDecl final /// The number of parameters in an expanded parameter pack. unsigned NumExpandedParams = 0; - TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, bool ParameterPack, IdentifierInfo *Id, + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P, + bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename, TemplateParameterList *Params) : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), @@ -1618,10 +1611,9 @@ class TemplateTemplateParmDecl final Typename(Typename), ParameterPack(ParameterPack), ExpandedParameterPack(false) {} - TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, IdentifierInfo *Id, - TemplateNameKind ParameterKind, bool Typename, - TemplateParameterList *Params, + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P, + IdentifierInfo *Id, TemplateNameKind ParameterKind, + bool Typename, TemplateParameterList *Params, ArrayRef<TemplateParameterList *> Expansions); void anchor() override; @@ -1632,15 +1624,14 @@ class TemplateTemplateParmDecl final friend TrailingObjects; static TemplateTemplateParmDecl * - Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, bool ParameterPack, IdentifierInfo *Id, - TemplateNameKind ParameterKind, bool Typename, - TemplateParameterList *Params); + Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P, + bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind, + bool Typename, TemplateParameterList *Params); static TemplateTemplateParmDecl * - Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, IdentifierInfo *Id, TemplateNameKind ParameterKind, - bool Typename, TemplateParameterList *Params, + Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P, + IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename, + TemplateParameterList *Params, ArrayRef<TemplateParameterList *> Expansions); static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h index e90aa9fb09012..c64eee11fd91e 100644 --- a/clang/include/clang/AST/TypeBase.h +++ b/clang/include/clang/AST/TypeBase.h @@ -2226,6 +2226,9 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { unsigned hasTypeDifferentFromDecl : 1; }; + static constexpr unsigned TemplateTypeParmTypeDepthBits = 15; + static constexpr unsigned TemplateTypeParmTypeIndexBits = 16; + class TemplateTypeParmTypeBitfields { friend class TemplateTypeParmType; @@ -2233,14 +2236,14 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { unsigned : NumTypeBits; /// The depth of the template parameter. - unsigned Depth : 15; + unsigned Depth : TemplateTypeParmTypeDepthBits; /// Whether this is a template parameter pack. LLVM_PREFERRED_TYPE(bool) unsigned ParameterPack : 1; /// The index of the template parameter. - unsigned Index : 16; + unsigned Index : TemplateTypeParmTypeIndexBits; }; class SubstTemplateTypeParmTypeBitfields { @@ -7062,6 +7065,8 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { (PP ? TypeDependence::UnexpandedPack : TypeDependence::None)), TTPDecl(TTPDecl) { assert(!TTPDecl == Canon.isNull()); + assert(D < (1 << TemplateTypeParmTypeDepthBits) && "Depth too large"); + assert(I < (1 << TemplateTypeParmTypeIndexBits) && "Index too large"); TemplateTypeParmTypeBits.Depth = D; TemplateTypeParmTypeBits.Index = I; TemplateTypeParmTypeBits.ParameterPack = PP; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a0894318dbd53..bc4771aec77d1 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -5952,9 +5952,12 @@ ASTContext::getSubstBuiltinTemplatePack(const TemplateArgument &ArgPack) { /// Retrieve the template type parameter type for a template /// parameter or parameter pack with the given depth, index, and (optionally) /// name. -QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, - bool ParameterPack, - TemplateTypeParmDecl *TTPDecl) const { +QualType +ASTContext::getTemplateTypeParmType(int Depth, int Index, bool ParameterPack, + TemplateTypeParmDecl *TTPDecl) const { + assert(Depth >= 0 && "Depth must be non-negative"); + assert(Index >= 0 && "Index must be non-negative"); + llvm::FoldingSetNodeID ID; TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl); void *InsertPos = nullptr; diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 08e6512a1c74d..a6d7e1473cd5a 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -672,9 +672,8 @@ CanQualType ClassTemplateDecl::getCanonicalInjectedSpecializationType( TemplateTypeParmDecl *TemplateTypeParmDecl::Create( const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, - SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, - bool Typename, bool ParameterPack, bool HasTypeConstraint, - UnsignedOrNone NumExpanded) { + SourceLocation NameLoc, int D, int P, IdentifierInfo *Id, bool Typename, + bool ParameterPack, bool HasTypeConstraint, UnsignedOrNone NumExpanded) { auto *TTPDecl = new (C, DC, additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0)) @@ -756,8 +755,8 @@ void TemplateTypeParmDecl::setTypeConstraint( //===----------------------------------------------------------------------===// NonTypeTemplateParmDecl::NonTypeTemplateParmDecl( - DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, - unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, + DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, int D, + int P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos) : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), TemplateParmPosition(D, P), ParameterPack(true), @@ -774,8 +773,8 @@ NonTypeTemplateParmDecl::NonTypeTemplateParmDecl( NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, - QualType T, bool ParameterPack, TypeSourceInfo *TInfo) { + SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, + bool ParameterPack, TypeSourceInfo *TInfo) { AutoType *AT = C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr; const bool HasConstraint = AT && AT->isConstrained(); @@ -792,8 +791,8 @@ NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, + SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos) { AutoType *AT = TInfo->getType()->getContainedAutoType(); const bool HasConstraint = AT && AT->isConstrained(); @@ -865,9 +864,9 @@ void NonTypeTemplateParmDecl::setDefaultArgument( void TemplateTemplateParmDecl::anchor() {} TemplateTemplateParmDecl::TemplateTemplateParmDecl( - DeclContext *DC, SourceLocation L, unsigned D, unsigned P, - IdentifierInfo *Id, TemplateNameKind Kind, bool Typename, - TemplateParameterList *Params, ArrayRef<TemplateParameterList *> Expansions) + DeclContext *DC, SourceLocation L, int D, int P, IdentifierInfo *Id, + TemplateNameKind Kind, bool Typename, TemplateParameterList *Params, + ArrayRef<TemplateParameterList *> Expansions) : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), TemplateParmPosition(D, P), ParameterKind(Kind), Typename(Typename), ParameterPack(true), ExpandedParameterPack(true), @@ -876,8 +875,8 @@ TemplateTemplateParmDecl::TemplateTemplateParmDecl( } TemplateTemplateParmDecl *TemplateTemplateParmDecl::Create( - const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind Kind, + const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P, + bool ParameterPack, IdentifierInfo *Id, TemplateNameKind Kind, bool Typename, TemplateParameterList *Params) { assert(!Params->empty() && "template with no template parameters"); return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, @@ -886,7 +885,7 @@ TemplateTemplateParmDecl *TemplateTemplateParmDecl::Create( TemplateTemplateParmDecl * TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, - SourceLocation L, unsigned D, unsigned P, + SourceLocation L, int D, int P, IdentifierInfo *Id, TemplateNameKind Kind, bool Typename, TemplateParameterList *Params, ArrayRef<TemplateParameterList *> Expansions) { diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index ac6dc5bcefb7e..c04fff6cbd964 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3005,7 +3005,9 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template, TTP, CTAI.SugaredConverted, Template->getSourceRange()); - if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args)) + if (Inst.isInvalid() || + !S.SubstTemplateParams(TTP->getTemplateParameters(), S.CurContext, + Args)) return true; } // For type parameters, no substitution is ever required. diff --git a/clang/test/SemaTemplate/concepts-lambda.cpp b/clang/test/SemaTemplate/concepts-lambda.cpp index a583589340bd0..a08cd52843c73 100644 --- a/clang/test/SemaTemplate/concepts-lambda.cpp +++ b/clang/test/SemaTemplate/concepts-lambda.cpp @@ -158,18 +158,21 @@ static_assert(E<int>); // previously Asserted. // ensure we properly diagnose when "D" is false. namespace DIsFalse { -template<auto Q> concept C = requires { Q.template operator()<float>(); }; +template<auto Q> concept C = requires { Q.template operator()<float>(); }; // #GH60642-C template<class> concept D = false; +// FIXME: Crashes because it produces a template type parameter with invalid depth +#if 0 static_assert(C<[]<D>{}>); // expected-error@-1{{static assertion failed}} // expected-note@-2{{does not satisfy 'C'}} // expected-note@-5{{because 'Q.template operator()<float>()' would be invalid: no matching member function for call to 'operator()'}} +#endif template<class> concept E = C<[]<D>{}>; static_assert(E<int>); // expected-error@-1{{static assertion failed}} // expected-note@-2{{because 'int' does not satisfy 'E'}} // expected-note@-4{{does not satisfy 'C'}} -// expected-note@-11{{because 'Q.template operator()<float>()' would be invalid: no matching member function for call to 'operator()'}} +// expected-note@#GH60642-C{{because 'Q.template operator()<float>()' would be invalid: no matching member function for call to 'operator()'}} } } diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index 72a2fab99c581..6ac934ee2a629 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -1551,10 +1551,12 @@ template<generic_range_value<[]< >() {}> T> void x() {} +// FIXME: Crashes because it produces a template type parameter with invalid depth +#if 0 void foo() { x<vector<int>>(); } - +#endif } namespace GH162770 { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
