Skip to content

Commit eff2a2a

Browse files
committedOct 18, 2019
[clang-format] fix regression recognizing casts in Obj-C calls
Summary: r373922 added checks for a few tokens that, following an `)` make it unlikely that the `)` is the closing paren of a cast expression. The specific check for `tok::l_square` there introduced a regression for casts of Obj-C calls, like: ``` (cast)[func arg] ``` From the tests added in r373922, I believe the `tok::l_square` case is added to capture the case where a non-cast `)` is directly followed by an attribute specifier, like: ``` int f(int x) [[noreturn]]; ``` I've specialized the code to look for such attribute specifier instead of `tok::l_square` in general. Also, I added a regression test and moved the test cases added in r373922 to an already existing place documenting other instances of historically misidentified casts. Reviewers: MyDeveloperDay Reviewed By: MyDeveloperDay Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D69164 llvm-svn: 375247
1 parent 7e5d5ee commit eff2a2a

File tree

2 files changed

+28
-29
lines changed

2 files changed

+28
-29
lines changed
 

‎clang/lib/Format/TokenAnnotator.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -1607,8 +1607,9 @@ class AnnotatingParser {
16071607
// Functions which end with decorations like volatile, noexcept are unlikely
16081608
// to be casts.
16091609
if (Tok.Next->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const,
1610-
tok::kw_throw, tok::l_square, tok::arrow,
1611-
Keywords.kw_override, Keywords.kw_final))
1610+
tok::kw_throw, tok::arrow, Keywords.kw_override,
1611+
Keywords.kw_final) ||
1612+
isCpp11AttributeSpecifier(*Tok.Next))
16121613
return false;
16131614

16141615
// As Java has no function types, a "(" after the ")" likely means that this

‎clang/unittests/Format/FormatTest.cpp

+25-27
Original file line numberDiff line numberDiff line change
@@ -7541,6 +7541,8 @@ TEST_F(FormatTest, FormatsCasts) {
75417541
verifyFormat("my_int a = (ns::my_int)-2;");
75427542
verifyFormat("case (my_int)ONE:");
75437543
verifyFormat("auto x = (X)this;");
7544+
// Casts in Obj-C style calls used to not be recognized as such.
7545+
verifyFormat("int a = [(type*)[((type*)val) arg] arg];", getGoogleStyle());
75447546

75457547
// FIXME: single value wrapped with paren will be treated as cast.
75467548
verifyFormat("void f(int i = (kValue)*kMask) {}");
@@ -7581,6 +7583,29 @@ TEST_F(FormatTest, FormatsCasts) {
75817583
verifyFormat("int a = alignof(int *) + b;", getGoogleStyle());
75827584
verifyFormat("bool b = f(g<int>) && c;");
75837585
verifyFormat("typedef void (*f)(int i) func;");
7586+
verifyFormat("void operator++(int) noexcept;");
7587+
verifyFormat("void operator++(int &) noexcept;");
7588+
verifyFormat("void operator delete(void *, std::size_t, const std::nothrow_t "
7589+
"&) noexcept;");
7590+
verifyFormat(
7591+
"void operator delete(std::size_t, const std::nothrow_t &) noexcept;");
7592+
verifyFormat("void operator delete(const std::nothrow_t &) noexcept;");
7593+
verifyFormat("void operator delete(std::nothrow_t &) noexcept;");
7594+
verifyFormat("void operator delete(nothrow_t &) noexcept;");
7595+
verifyFormat("void operator delete(foo &) noexcept;");
7596+
verifyFormat("void operator delete(foo) noexcept;");
7597+
verifyFormat("void operator delete(int) noexcept;");
7598+
verifyFormat("void operator delete(int &) noexcept;");
7599+
verifyFormat("void operator delete(int &) volatile noexcept;");
7600+
verifyFormat("void operator delete(int &) const");
7601+
verifyFormat("void operator delete(int &) = default");
7602+
verifyFormat("void operator delete(int &) = delete");
7603+
verifyFormat("void operator delete(int &) [[noreturn]]");
7604+
verifyFormat("void operator delete(int &) throw();");
7605+
verifyFormat("void operator delete(int &) throw(int);");
7606+
verifyFormat("auto operator delete(int &) -> int;");
7607+
verifyFormat("auto operator delete(int &) override");
7608+
verifyFormat("auto operator delete(int &) final");
75847609

75857610
verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *foo = (aaaaaaaaaaaaaaaaa *)\n"
75867611
" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;");
@@ -14696,33 +14721,6 @@ TEST_F(FormatTest, AlternativeOperators) {
1469614721
*/
1469714722
}
1469814723

14699-
TEST_F(FormatTest, NotCastRPaen) {
14700-
14701-
verifyFormat("void operator++(int) noexcept;");
14702-
verifyFormat("void operator++(int &) noexcept;");
14703-
verifyFormat("void operator delete(void *, std::size_t, const std::nothrow_t "
14704-
"&) noexcept;");
14705-
verifyFormat(
14706-
"void operator delete(std::size_t, const std::nothrow_t &) noexcept;");
14707-
verifyFormat("void operator delete(const std::nothrow_t &) noexcept;");
14708-
verifyFormat("void operator delete(std::nothrow_t &) noexcept;");
14709-
verifyFormat("void operator delete(nothrow_t &) noexcept;");
14710-
verifyFormat("void operator delete(foo &) noexcept;");
14711-
verifyFormat("void operator delete(foo) noexcept;");
14712-
verifyFormat("void operator delete(int) noexcept;");
14713-
verifyFormat("void operator delete(int &) noexcept;");
14714-
verifyFormat("void operator delete(int &) volatile noexcept;");
14715-
verifyFormat("void operator delete(int &) const");
14716-
verifyFormat("void operator delete(int &) = default");
14717-
verifyFormat("void operator delete(int &) = delete");
14718-
verifyFormat("void operator delete(int &) [[noreturn]]");
14719-
verifyFormat("void operator delete(int &) throw();");
14720-
verifyFormat("void operator delete(int &) throw(int);");
14721-
verifyFormat("auto operator delete(int &) -> int;");
14722-
verifyFormat("auto operator delete(int &) override");
14723-
verifyFormat("auto operator delete(int &) final");
14724-
}
14725-
1472614724
TEST_F(FormatTest, STLWhileNotDefineChed) {
1472714725
verifyFormat("#if defined(while)\n"
1472814726
"#define while EMIT WARNING C4005\n"

0 commit comments

Comments
 (0)
Please sign in to comment.