Skip to content

Commit fd86789

Browse files
committed
[clang-format] Don't allow variable decls to have trailing return arrows
The heuristic for determining if an arrow is a trailing return arrow looks for the auto keyword, along with parentheses. This isn't sufficient, since it also triggers on variable declarations with an auto type, and with an arrow operator. This patch makes sure a function declaration is being parsed, instead of any other declaration. Fixes #61469 Reviewed By: HazardyKnusperkeks, owenpan, MyDeveloperDay Differential Revision: https://reviews.llvm.org/D147377
1 parent b58a697 commit fd86789

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1922,7 +1922,7 @@ class AnnotatingParser {
19221922
Style.Language == FormatStyle::LK_Java) {
19231923
Current.setType(TT_LambdaArrow);
19241924
} else if (Current.is(tok::arrow) && AutoFound &&
1925-
(Line.MustBeDeclaration || Line.InPPDirective) &&
1925+
(Line.MightBeFunctionDecl || Line.InPPDirective) &&
19261926
Current.NestingLevel == 0 &&
19271927
!Current.Previous->isOneOf(tok::kw_operator, tok::identifier)) {
19281928
// not auto operator->() -> xxx;

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,72 @@ TEST_F(TokenAnnotatorTest, UnderstandsC11GenericSelection) {
14771477
EXPECT_TOKEN(Tokens[9], tok::colon, TT_GenericSelectionColon);
14781478
}
14791479

1480+
TEST_F(TokenAnnotatorTest, UnderstandsTrailingReturnArrow) {
1481+
auto Tokens = annotate("auto f() -> int;");
1482+
ASSERT_EQ(Tokens.size(), 8u) << Tokens;
1483+
EXPECT_TOKEN(Tokens[4], tok::arrow, TT_TrailingReturnArrow);
1484+
1485+
Tokens = annotate("auto operator->() -> int;");
1486+
ASSERT_EQ(Tokens.size(), 9u) << Tokens;
1487+
EXPECT_TOKEN(Tokens[2], tok::arrow, TT_OverloadedOperator);
1488+
EXPECT_TOKEN(Tokens[5], tok::arrow, TT_TrailingReturnArrow);
1489+
1490+
Tokens = annotate("auto operator++(int) -> int;");
1491+
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
1492+
EXPECT_TOKEN(Tokens[6], tok::arrow, TT_TrailingReturnArrow);
1493+
1494+
Tokens = annotate("auto operator=() -> int;");
1495+
ASSERT_EQ(Tokens.size(), 9u) << Tokens;
1496+
EXPECT_TOKEN(Tokens[5], tok::arrow, TT_TrailingReturnArrow);
1497+
1498+
Tokens = annotate("auto operator=(int) -> int;");
1499+
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
1500+
EXPECT_TOKEN(Tokens[6], tok::arrow, TT_TrailingReturnArrow);
1501+
1502+
Tokens = annotate("auto foo() -> auto { return Val; }");
1503+
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
1504+
EXPECT_TOKEN(Tokens[4], tok::arrow, TT_TrailingReturnArrow);
1505+
1506+
Tokens = annotate("struct S { auto bar() const -> int; };");
1507+
ASSERT_EQ(Tokens.size(), 14u) << Tokens;
1508+
EXPECT_TOKEN(Tokens[8], tok::arrow, TT_TrailingReturnArrow);
1509+
1510+
// Not trailing return arrows
1511+
Tokens = annotate("auto a = b->c;");
1512+
ASSERT_EQ(Tokens.size(), 8u) << Tokens;
1513+
EXPECT_TOKEN(Tokens[4], tok::arrow, TT_Unknown);
1514+
1515+
Tokens = annotate("auto a = (b)->c;");
1516+
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
1517+
EXPECT_TOKEN(Tokens[6], tok::arrow, TT_Unknown);
1518+
1519+
Tokens = annotate("auto a = b()->c;");
1520+
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
1521+
EXPECT_TOKEN(Tokens[6], tok::arrow, TT_Unknown);
1522+
1523+
Tokens = annotate("auto a = b->c();");
1524+
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
1525+
EXPECT_TOKEN(Tokens[4], tok::arrow, TT_Unknown);
1526+
1527+
Tokens = annotate("decltype(auto) a = b()->c;");
1528+
ASSERT_EQ(Tokens.size(), 13u) << Tokens;
1529+
EXPECT_TOKEN(Tokens[9], tok::arrow, TT_Unknown);
1530+
1531+
Tokens = annotate("void f() { auto a = b->c(); }");
1532+
ASSERT_EQ(Tokens.size(), 16u) << Tokens;
1533+
EXPECT_TOKEN(Tokens[9], tok::arrow, TT_Unknown);
1534+
1535+
Tokens = annotate("void f() { auto a = b()->c; }");
1536+
ASSERT_EQ(Tokens.size(), 16u) << Tokens;
1537+
EXPECT_TOKEN(Tokens[11], tok::arrow, TT_Unknown);
1538+
1539+
// Mixed
1540+
Tokens = annotate("auto f() -> int { auto a = b()->c; }");
1541+
ASSERT_EQ(Tokens.size(), 18u) << Tokens;
1542+
EXPECT_TOKEN(Tokens[4], tok::arrow, TT_TrailingReturnArrow);
1543+
EXPECT_TOKEN(Tokens[13], tok::arrow, TT_Unknown);
1544+
}
1545+
14801546
TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) {
14811547
auto Annotate = [this](llvm::StringRef Code) {
14821548
return annotate(Code, getLLVMStyle(FormatStyle::LK_Verilog));

0 commit comments

Comments
 (0)