Skip to content

Commit a8f4397

Browse files
[Clang] Fix ICE where C++ Template Instantiation failed to handle attributed lambdas (#76523)
This PR is proposing a fix for #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.
1 parent cba217a commit a8f4397

File tree

3 files changed

+72
-17
lines changed

3 files changed

+72
-17
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,9 @@ Bug Fixes to AST Handling
856856
- Fixed a bug where RecursiveASTVisitor fails to visit the
857857
initializer of a bitfield.
858858
`Issue 64916 <https://github.com/llvm/llvm-project/issues/64916>`_
859+
- Fixed a bug where Template Instantiation failed to handle Lambda Expressions
860+
with certain types of Attributes.
861+
(`#76521 <https://github.com/llvm/llvm-project/issues/76521>`_)
859862

860863
Miscellaneous Bug Fixes
861864
^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/TreeTransform.h

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,10 @@ class TreeTransform {
674674
Qualifiers ThisTypeQuals,
675675
Fn TransformExceptionSpec);
676676

677+
template <typename Fn>
678+
QualType TransformAttributedType(TypeLocBuilder &TLB, AttributedTypeLoc TL,
679+
Fn TransformModifiedType);
680+
677681
bool TransformExceptionSpec(SourceLocation Loc,
678682
FunctionProtoType::ExceptionSpecInfo &ESI,
679683
SmallVectorImpl<QualType> &Exceptions,
@@ -7050,12 +7054,12 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
70507054
return Result;
70517055
}
70527056

7053-
template<typename Derived>
7057+
template <typename Derived>
7058+
template <typename Fn>
70547059
QualType TreeTransform<Derived>::TransformAttributedType(
7055-
TypeLocBuilder &TLB,
7056-
AttributedTypeLoc TL) {
7060+
TypeLocBuilder &TLB, AttributedTypeLoc TL, Fn TransformModifiedTypeFn) {
70577061
const AttributedType *oldType = TL.getTypePtr();
7058-
QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7062+
QualType modifiedType = TransformModifiedTypeFn(TLB, TL.getModifiedLoc());
70597063
if (modifiedType.isNull())
70607064
return QualType();
70617065

@@ -7099,6 +7103,15 @@ QualType TreeTransform<Derived>::TransformAttributedType(
70997103
return result;
71007104
}
71017105

7106+
template <typename Derived>
7107+
QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7108+
AttributedTypeLoc TL) {
7109+
return getDerived().TransformAttributedType(
7110+
TLB, TL, [&](TypeLocBuilder &TLB, TypeLoc ModifiedLoc) -> QualType {
7111+
return getDerived().TransformType(TLB, ModifiedLoc);
7112+
});
7113+
}
7114+
71027115
template <typename Derived>
71037116
QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
71047117
TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
@@ -13600,32 +13613,56 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
1360013613
// transformed parameters.
1360113614
TypeSourceInfo *NewCallOpTSI = nullptr;
1360213615
{
13603-
TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
13604-
auto OldCallOpFPTL =
13605-
OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
13616+
auto OldCallOpTypeLoc =
13617+
E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
13618+
13619+
auto TransformFunctionProtoTypeLoc =
13620+
[this](TypeLocBuilder &TLB, FunctionProtoTypeLoc FPTL) -> QualType {
13621+
SmallVector<QualType, 4> ExceptionStorage;
13622+
TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
13623+
return this->TransformFunctionProtoType(
13624+
TLB, FPTL, nullptr, Qualifiers(),
13625+
[&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
13626+
return This->TransformExceptionSpec(FPTL.getBeginLoc(), ESI,
13627+
ExceptionStorage, Changed);
13628+
});
13629+
};
1360613630

13631+
QualType NewCallOpType;
1360713632
TypeLocBuilder NewCallOpTLBuilder;
13608-
SmallVector<QualType, 4> ExceptionStorage;
13609-
TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
13610-
QualType NewCallOpType = TransformFunctionProtoType(
13611-
NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(),
13612-
[&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
13613-
return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,
13614-
ExceptionStorage, Changed);
13615-
});
13633+
13634+
if (auto ATL = OldCallOpTypeLoc.getAs<AttributedTypeLoc>()) {
13635+
NewCallOpType = this->TransformAttributedType(
13636+
NewCallOpTLBuilder, ATL,
13637+
[&](TypeLocBuilder &TLB, TypeLoc TL) -> QualType {
13638+
return TransformFunctionProtoTypeLoc(
13639+
TLB, TL.castAs<FunctionProtoTypeLoc>());
13640+
});
13641+
} else {
13642+
auto FPTL = OldCallOpTypeLoc.castAs<FunctionProtoTypeLoc>();
13643+
NewCallOpType = TransformFunctionProtoTypeLoc(NewCallOpTLBuilder, FPTL);
13644+
}
13645+
1361613646
if (NewCallOpType.isNull())
1361713647
return ExprError();
1361813648
NewCallOpTSI =
1361913649
NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
1362013650
}
1362113651

13652+
ArrayRef<ParmVarDecl *> Params;
13653+
if (auto ATL = NewCallOpTSI->getTypeLoc().getAs<AttributedTypeLoc>()) {
13654+
Params = ATL.getModifiedLoc().castAs<FunctionProtoTypeLoc>().getParams();
13655+
} else {
13656+
auto FPTL = NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
13657+
Params = FPTL.getParams();
13658+
}
13659+
1362213660
getSema().CompleteLambdaCallOperator(
1362313661
NewCallOperator, E->getCallOperator()->getLocation(),
1362413662
E->getCallOperator()->getInnerLocStart(),
1362513663
E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
1362613664
E->getCallOperator()->getConstexprKind(),
13627-
E->getCallOperator()->getStorageClass(),
13628-
NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
13665+
E->getCallOperator()->getStorageClass(), Params,
1362913666
E->hasExplicitResultType());
1363013667

1363113668
getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %clang_cc1 -verify -fsyntax-only -Wno-ignored-attributes %s
2+
// expected-no-diagnostics
3+
4+
namespace GH76521 {
5+
6+
template <typename T>
7+
void foo() {
8+
auto l = []() __attribute__((pcs("aapcs-vfp"))) {};
9+
}
10+
11+
void bar() {
12+
foo<int>();
13+
}
14+
15+
}

0 commit comments

Comments
 (0)