https://github.com/yuxuanchen1997 created https://github.com/llvm/llvm-project/pull/76523
This PR is proposing a fix for https://github.com/llvm/llvm-project/issues/76521. Clang used to assume that during template instantiation, Lambda expressions can only have `FunctionProtoTypeLoc`s. However, this is not true for certain attributes like `__attribute__((pcs("aapcs-vfp")))`, whose interpretation happens after template instantiation. This PR changes the transformation logic for lambdas. >From 09b339575b506317a5fbf5c4d52d3e5d0243a3c3 Mon Sep 17 00:00:00 2001 From: Yuxuan Chen <yuxuanchen1...@outlook.com> Date: Thu, 21 Dec 2023 14:48:52 -0800 Subject: [PATCH] attempt to fix the crash --- clang/docs/ReleaseNotes.rst | 3 + clang/lib/Sema/TreeTransform.h | 71 ++++++++++++++----- clang/test/SemaCXX/template-instantiation.cpp | 15 ++++ 3 files changed, 72 insertions(+), 17 deletions(-) create mode 100644 clang/test/SemaCXX/template-instantiation.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e21ec78a1e8a77..888a11bef15e7e 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -856,6 +856,9 @@ Bug Fixes to AST Handling - Fixed a bug where RecursiveASTVisitor fails to visit the initializer of a bitfield. `Issue 64916 <https://github.com/llvm/llvm-project/issues/64916>`_ +- Fixed a bug where Template Instantiation failed to handle Lambda Expressions + with certain types of Attributes. + (`#76521 <https://github.com/llvm/llvm-project/issues/76521>`_) Miscellaneous Bug Fixes ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 7df5bf0cb71370..5e9b5184570704 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -674,6 +674,10 @@ class TreeTransform { Qualifiers ThisTypeQuals, Fn TransformExceptionSpec); + template <typename Fn> + QualType TransformAttributedType(TypeLocBuilder &TLB, AttributedTypeLoc TL, + Fn TransformModifiedType); + bool TransformExceptionSpec(SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI, SmallVectorImpl<QualType> &Exceptions, @@ -7050,12 +7054,12 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, return Result; } -template<typename Derived> +template <typename Derived> +template <typename Fn> QualType TreeTransform<Derived>::TransformAttributedType( - TypeLocBuilder &TLB, - AttributedTypeLoc TL) { + TypeLocBuilder &TLB, AttributedTypeLoc TL, Fn TransformModifiedTypeFn) { const AttributedType *oldType = TL.getTypePtr(); - QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc()); + QualType modifiedType = TransformModifiedTypeFn(TLB, TL.getModifiedLoc()); if (modifiedType.isNull()) return QualType(); @@ -7099,6 +7103,15 @@ QualType TreeTransform<Derived>::TransformAttributedType( return result; } +template <typename Derived> +QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB, + AttributedTypeLoc TL) { + return getDerived().TransformAttributedType( + TLB, TL, [&](TypeLocBuilder &TLB, TypeLoc ModifiedLoc) -> QualType { + return getDerived().TransformType(TLB, ModifiedLoc); + }); +} + template <typename Derived> QualType TreeTransform<Derived>::TransformBTFTagAttributedType( TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) { @@ -13600,32 +13613,56 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { // transformed parameters. TypeSourceInfo *NewCallOpTSI = nullptr; { - TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo(); - auto OldCallOpFPTL = - OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>(); + auto OldCallOpTypeLoc = + E->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); + + auto TransformFunctionProtoTypeLoc = + [this](TypeLocBuilder &TLB, FunctionProtoTypeLoc FPTL) -> QualType { + SmallVector<QualType, 4> ExceptionStorage; + TreeTransform *This = this; // Work around gcc.gnu.org/PR56135. + return this->TransformFunctionProtoType( + TLB, FPTL, nullptr, Qualifiers(), + [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) { + return This->TransformExceptionSpec(FPTL.getBeginLoc(), ESI, + ExceptionStorage, Changed); + }); + }; + QualType NewCallOpType; TypeLocBuilder NewCallOpTLBuilder; - SmallVector<QualType, 4> ExceptionStorage; - TreeTransform *This = this; // Work around gcc.gnu.org/PR56135. - QualType NewCallOpType = TransformFunctionProtoType( - NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(), - [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) { - return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI, - ExceptionStorage, Changed); - }); + + if (auto ATL = OldCallOpTypeLoc.getAs<AttributedTypeLoc>()) { + NewCallOpType = this->TransformAttributedType( + NewCallOpTLBuilder, ATL, + [&](TypeLocBuilder &TLB, TypeLoc TL) -> QualType { + return TransformFunctionProtoTypeLoc( + TLB, TL.castAs<FunctionProtoTypeLoc>()); + }); + } else { + auto FPTL = OldCallOpTypeLoc.castAs<FunctionProtoTypeLoc>(); + NewCallOpType = TransformFunctionProtoTypeLoc(NewCallOpTLBuilder, FPTL); + } + if (NewCallOpType.isNull()) return ExprError(); NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType); } + ArrayRef<ParmVarDecl *> Params; + if (auto ATL = NewCallOpTSI->getTypeLoc().getAs<AttributedTypeLoc>()) { + Params = ATL.getModifiedLoc().castAs<FunctionProtoTypeLoc>().getParams(); + } else { + auto FPTL = NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>(); + Params = FPTL.getParams(); + } + getSema().CompleteLambdaCallOperator( NewCallOperator, E->getCallOperator()->getLocation(), E->getCallOperator()->getInnerLocStart(), E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI, E->getCallOperator()->getConstexprKind(), - E->getCallOperator()->getStorageClass(), - NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(), + E->getCallOperator()->getStorageClass(), Params, E->hasExplicitResultType()); getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); diff --git a/clang/test/SemaCXX/template-instantiation.cpp b/clang/test/SemaCXX/template-instantiation.cpp new file mode 100644 index 00000000000000..e714e070a206f5 --- /dev/null +++ b/clang/test/SemaCXX/template-instantiation.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -Wno-ignored-attributes %s +// expected-no-diagnostics + +namespace GH76521 { + +template <typename T> +void foo() { + auto l = []() __attribute__((pcs("aapcs-vfp"))) {}; +} + +void bar() { + foo<int>(); +} + +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits