[clang] [Clang] Fix ICE where C++ Template Instantiation failed to handle attributed lambdas (PR #76523)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 28 10:23:27 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Yuxuan Chen (yuxuanchen1997)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/76523.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+3)
- (modified) clang/lib/Sema/TreeTransform.h (+54-17)
- (added) clang/test/SemaCXX/template-instantiation.cpp (+15)
``````````diff
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>();
+}
+
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/76523
More information about the cfe-commits
mailing list