diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 997fe92cabac5..27814b8f46862 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2428,12 +2428,16 @@ class AnnotatingParser { // If the next token after the parenthesis is a unary operator, assume // that this is cast, unless there are unexpected tokens inside the // parenthesis. - bool NextIsUnary = - Tok.Next->isUnaryOperator() || Tok.Next->isOneOf(tok::amp, tok::star); - if (!NextIsUnary || Tok.Next->is(tok::plus) || + const bool NextIsAmpOrStar = Tok.Next->isOneOf(tok::amp, tok::star); + if (!(Tok.Next->isUnaryOperator() || NextIsAmpOrStar) || + Tok.Next->is(tok::plus) || !Tok.Next->Next->isOneOf(tok::identifier, tok::numeric_constant)) { return false; } + if (NextIsAmpOrStar && + (Tok.Next->Next->is(tok::numeric_constant) || Line.InPPDirective)) { + return false; + } // Search for unexpected tokens. for (FormatToken *Prev = Tok.Previous; Prev != Tok.MatchingParen; Prev = Prev->Previous) { diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 59b1421f99617..b7980bb6d923d 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -554,6 +554,17 @@ TEST_F(TokenAnnotatorTest, UnderstandsCasts) { Tokens = annotate("throw (Foo)p;"); EXPECT_EQ(Tokens.size(), 7u) << Tokens; EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen); + + Tokens = annotate("#define FOO(x) (((uint64_t)(x) * BAR) / 100)"); + EXPECT_EQ(Tokens.size(), 21u) << Tokens; + EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_CastRParen); + EXPECT_TOKEN(Tokens[13], tok::r_paren, TT_Unknown); + EXPECT_TOKEN(Tokens[14], tok::star, TT_BinaryOperator); + + Tokens = annotate("return (Foo) & 10;"); + EXPECT_EQ(Tokens.size(), 8u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_Unknown); + EXPECT_TOKEN(Tokens[4], tok::amp, TT_BinaryOperator); } TEST_F(TokenAnnotatorTest, UnderstandsDynamicExceptionSpecifier) {