[Format] Fix 'auto x(T&&, T &&)->F' with PAS_Left.

Summary:
An heuristic targetting `x && x->foo` was targed overly broadly and caused the
last T&& to be treated as a binary operator.

Reviewers: hokein

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D73334
This commit is contained in:
Sam McCall 2020-01-24 10:12:25 +01:00
parent 035c106f37
commit b3b68c0f80
2 changed files with 9 additions and 4 deletions

View File

@ -1801,14 +1801,16 @@ private:
return TT_BinaryOperator;
// "&&(" is quite unlikely to be two successive unary "&".
if (Tok.is(tok::ampamp) && NextToken && NextToken->is(tok::l_paren))
if (Tok.is(tok::ampamp) && NextToken->is(tok::l_paren))
return TT_BinaryOperator;
// This catches some cases where evaluation order is used as control flow:
// aaa && aaa->f();
if (NextToken->Tok.isAnyIdentifier()) {
const FormatToken *NextNextToken = NextToken->getNextNonComment();
if (NextNextToken && NextNextToken->is(tok::arrow))
return TT_BinaryOperator;
}
// It is very unlikely that we are going to find a pointer or reference type
// definition on the RHS of an assignment.

View File

@ -7407,6 +7407,9 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyFormat("typedef typeof(int(int, int))* MyFuncPtr;", Left);
verifyFormat("[](const decltype(*a)* ptr) {}", Left);
verifyFormat("typedef typeof /*comment*/ (int(int, int))* MyFuncPtr;", Left);
verifyFormat("auto x(A&&, B&&, C&&) -> D;", Left);
verifyFormat("auto x = [](A&&, B&&, C&&) -> D {};", Left);
verifyFormat("template <class T> X(T&&, T&&, T&&) -> X<T>;", Left);
verifyIndependentOfContext("a = *(x + y);");
verifyIndependentOfContext("a = &(x + y);");