Skip to content

Commit 4f71655

Browse files
authored
[clang-format] Fix a bug in parsing C-style cast of lambdas (llvm#136099)
Fix llvm#135959
1 parent 122e515 commit 4f71655

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2368,13 +2368,25 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
23682368
const FormatToken *Previous = FormatTok->Previous;
23692369
const FormatToken *LeftSquare = FormatTok;
23702370
nextToken();
2371-
if ((Previous && ((Previous->Tok.getIdentifierInfo() &&
2372-
!Previous->isOneOf(tok::kw_return, tok::kw_co_await,
2373-
tok::kw_co_yield, tok::kw_co_return)) ||
2374-
Previous->closesScope())) ||
2375-
LeftSquare->isCppStructuredBinding(IsCpp)) {
2376-
return false;
2371+
if (Previous) {
2372+
if (Previous->Tok.getIdentifierInfo() &&
2373+
!Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
2374+
tok::kw_co_return)) {
2375+
return false;
2376+
}
2377+
if (Previous->closesScope()) {
2378+
// Not a potential C-style cast.
2379+
if (Previous->isNot(tok::r_paren))
2380+
return false;
2381+
const auto *BeforeRParen = Previous->getPreviousNonComment();
2382+
// Lambdas can be cast to function types only, e.g. `std::function<int()>`
2383+
// and `int (*)()`.
2384+
if (!BeforeRParen || !BeforeRParen->isOneOf(tok::greater, tok::r_paren))
2385+
return false;
2386+
}
23772387
}
2388+
if (LeftSquare->isCppStructuredBinding(IsCpp))
2389+
return false;
23782390
if (FormatTok->is(tok::l_square) || tok::isLiteral(FormatTok->Tok.getKind()))
23792391
return false;
23802392
if (FormatTok->is(tok::r_square)) {

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,16 @@ TEST_F(TokenAnnotatorTest, UnderstandsLambdas) {
21652165
// FIXME:
21662166
// EXPECT_TOKEN(Tokens[13], tok::l_paren, TT_LambdaDefinitionLParen);
21672167
EXPECT_TOKEN(Tokens[17], tok::l_brace, TT_LambdaLBrace);
2168+
2169+
Tokens = annotate("auto foo{(std::function<int()>)[] { return 0; }};");
2170+
ASSERT_EQ(Tokens.size(), 23u) << Tokens;
2171+
EXPECT_TOKEN(Tokens[13], tok::l_square, TT_LambdaLSquare);
2172+
EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_LambdaLBrace);
2173+
2174+
Tokens = annotate("auto foo{(int (*)())[] { return 0; }};");
2175+
ASSERT_EQ(Tokens.size(), 21u) << Tokens;
2176+
EXPECT_TOKEN(Tokens[11], tok::l_square, TT_LambdaLSquare);
2177+
EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_LambdaLBrace);
21682178
}
21692179

21702180
TEST_F(TokenAnnotatorTest, UnderstandsFunctionAnnotations) {

0 commit comments

Comments
 (0)