[clang] [clang-format] Fix a bug in RemoveParentheses: ReturnStatement (PR #67911)

2023-10-02 Thread Owen Pan via cfe-commits

owenca wrote:

@tru np! That was my intention anyways.

https://github.com/llvm/llvm-project/pull/67911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Fix a bug in RemoveParentheses: ReturnStatement (PR #67911)

2023-10-02 Thread Tobias Hieta via cfe-commits

tru wrote:

oh sorry for merging this @owenca - it was tagged for the 17.x release and I 
thought it was a PR towards the backport branch so ti wasn't my intention to 
merge it into main for you. 

https://github.com/llvm/llvm-project/pull/67911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Fix a bug in RemoveParentheses: ReturnStatement (PR #67911)

2023-10-02 Thread Tobias Hieta via cfe-commits

https://github.com/tru closed https://github.com/llvm/llvm-project/pull/67911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Fix a bug in RemoveParentheses: ReturnStatement (PR #67911)

2023-10-01 Thread via cfe-commits

https://github.com/mydeveloperday approved this pull request.


https://github.com/llvm/llvm-project/pull/67911
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] Fix a bug in RemoveParentheses: ReturnStatement (PR #67911)

2023-10-01 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-format


Changes

Don't remove the outermost parentheses surrounding a return statement 
expression when inside a function/lambda that has the decltype(auto) return 
type.

Fixed #67892.

---
Full diff: https://github.com/llvm/llvm-project/pull/67911.diff


3 Files Affected:

- (modified) clang/lib/Format/UnwrappedLineParser.cpp (+24) 
- (modified) clang/lib/Format/UnwrappedLineParser.h (+11) 
- (modified) clang/unittests/Format/FormatTest.cpp (+50) 


``diff
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index bf38ed73c4a0b4e..dda5fd077e590e5 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -173,10 +173,12 @@ void UnwrappedLineParser::reset() {
   CommentsBeforeNextToken.clear();
   FormatTok = nullptr;
   MustBreakBeforeNextToken = false;
+  IsDecltypeAutoFunction = false;
   PreprocessorDirectives.clear();
   CurrentLines = 
   DeclarationScopeStack.clear();
   NestedTooDeep.clear();
+  NestedLambdas.clear();
   PPStack.clear();
   Line->FirstStartColumn = FirstStartColumn;
 
@@ -1766,6 +1768,17 @@ void UnwrappedLineParser::parseStructuralElement(
   if (parseStructLike())
 return;
   break;
+case tok::kw_decltype:
+  nextToken();
+  if (FormatTok->is(tok::l_paren)) {
+parseParens();
+assert(FormatTok->Previous);
+if (FormatTok->Previous->endsSequence(tok::r_paren, tok::kw_auto,
+  tok::l_paren)) {
+  Line->SeenDecltypeAuto = true;
+}
+  }
+  break;
 case tok::period:
   nextToken();
   // In Java, classes have an implicit static member "class".
@@ -1827,6 +1840,7 @@ void UnwrappedLineParser::parseStructuralElement(
   if (InRequiresExpression)
 FormatTok->setFinalizedType(TT_BracedListLBrace);
   if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
+IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
 // A block outside of parentheses must be the last part of a
 // structural element.
 // FIXME: Figure out cases where this is not true, and add projections
@@ -1844,6 +1858,7 @@ void UnwrappedLineParser::parseStructuralElement(
 }
 FormatTok->setFinalizedType(TT_FunctionLBrace);
 parseBlock();
+IsDecltypeAutoFunction = false;
 addUnwrappedLine();
 return;
   }
@@ -2249,9 +2264,15 @@ bool UnwrappedLineParser::tryToParseLambda() {
   return true;
 }
   }
+
   FormatTok->setFinalizedType(TT_LambdaLBrace);
   LSquare.setFinalizedType(TT_LambdaLSquare);
+
+  NestedLambdas.push_back(Line->SeenDecltypeAuto);
   parseChildBlock();
+  assert(!NestedLambdas.empty());
+  NestedLambdas.pop_back();
+
   return true;
 }
 
@@ -2469,6 +2490,8 @@ bool UnwrappedLineParser::parseParens(TokenType 
AmpAmpTokenType) {
PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if;
 const bool ReturnParens =
 Style.RemoveParentheses == FormatStyle::RPS_ReturnStatement &&
+((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
+ (!NestedLambdas.empty() && !NestedLambdas.back())) &&
 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
 Next->is(tok::semi);
 if ((DoubleParens && !Blacklisted) || ReturnParens) {
@@ -4379,6 +4402,7 @@ void UnwrappedLineParser::addUnwrappedLine(LineLevel 
AdjustLevel) {
   Line->MatchingOpeningBlockLineIndex = UnwrappedLine::kInvalidIndex;
   Line->FirstStartColumn = 0;
   Line->IsContinuation = false;
+  Line->SeenDecltypeAuto = false;
 
   if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
 --Line->Level;
diff --git a/clang/lib/Format/UnwrappedLineParser.h 
b/clang/lib/Format/UnwrappedLineParser.h
index 4138baaabe2693d..a4f150d19571266 100644
--- a/clang/lib/Format/UnwrappedLineParser.h
+++ b/clang/lib/Format/UnwrappedLineParser.h
@@ -61,6 +61,9 @@ struct UnwrappedLine {
 
   bool MustBeDeclaration = false;
 
+  /// Whether the parser has seen \c decltype(auto) in this line.
+  bool SeenDecltypeAuto = false;
+
   /// \c True if this line should be indented by ContinuationIndent in
   /// addition to the normal indention level.
   bool IsContinuation = false;
@@ -335,6 +338,14 @@ class UnwrappedLineParser {
   // statement contains more than some predefined number of nested statements).
   SmallVector NestedTooDeep;
 
+  // Keeps a stack of the states of nested lambdas (true if the return type of
+  // the lambda is `decltype(auto)`).
+  SmallVector NestedLambdas;
+
+  // Whether the parser is parsing the body of a function whose return type is
+  // `decltype(auto)`.
+  bool IsDecltypeAutoFunction = false;
+
   // Represents preprocessor branch type, so we can find matching
   // #if/#else/#endif directives.
   enum PPBranchKind {
diff --git 

[clang] [clang-format] Fix a bug in RemoveParentheses: ReturnStatement (PR #67911)

2023-10-01 Thread Owen Pan via cfe-commits

https://github.com/owenca created 
https://github.com/llvm/llvm-project/pull/67911

Don't remove the outermost parentheses surrounding a return statement 
expression when inside a function/lambda that has the decltype(auto) return 
type.

Fixed #67892.

>From 561af2122a9155b44e340d89549b13b0ea9b2ce6 Mon Sep 17 00:00:00 2001
From: Owen Pan 
Date: Sun, 1 Oct 2023 03:11:23 -0700
Subject: [PATCH] [clang-format] Fix a bug in RemoveParentheses:
 ReturnStatement

Don't remove the outermost parentheses surrounding a return statement
expression when inside a function/lambda that has the decltype(auto)
return type.

Fixed #67892.
---
 clang/lib/Format/UnwrappedLineParser.cpp | 24 
 clang/lib/Format/UnwrappedLineParser.h   | 11 ++
 clang/unittests/Format/FormatTest.cpp| 50 
 3 files changed, 85 insertions(+)

diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index bf38ed73c4a0b4e..dda5fd077e590e5 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -173,10 +173,12 @@ void UnwrappedLineParser::reset() {
   CommentsBeforeNextToken.clear();
   FormatTok = nullptr;
   MustBreakBeforeNextToken = false;
+  IsDecltypeAutoFunction = false;
   PreprocessorDirectives.clear();
   CurrentLines = 
   DeclarationScopeStack.clear();
   NestedTooDeep.clear();
+  NestedLambdas.clear();
   PPStack.clear();
   Line->FirstStartColumn = FirstStartColumn;
 
@@ -1766,6 +1768,17 @@ void UnwrappedLineParser::parseStructuralElement(
   if (parseStructLike())
 return;
   break;
+case tok::kw_decltype:
+  nextToken();
+  if (FormatTok->is(tok::l_paren)) {
+parseParens();
+assert(FormatTok->Previous);
+if (FormatTok->Previous->endsSequence(tok::r_paren, tok::kw_auto,
+  tok::l_paren)) {
+  Line->SeenDecltypeAuto = true;
+}
+  }
+  break;
 case tok::period:
   nextToken();
   // In Java, classes have an implicit static member "class".
@@ -1827,6 +1840,7 @@ void UnwrappedLineParser::parseStructuralElement(
   if (InRequiresExpression)
 FormatTok->setFinalizedType(TT_BracedListLBrace);
   if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
+IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
 // A block outside of parentheses must be the last part of a
 // structural element.
 // FIXME: Figure out cases where this is not true, and add projections
@@ -1844,6 +1858,7 @@ void UnwrappedLineParser::parseStructuralElement(
 }
 FormatTok->setFinalizedType(TT_FunctionLBrace);
 parseBlock();
+IsDecltypeAutoFunction = false;
 addUnwrappedLine();
 return;
   }
@@ -2249,9 +2264,15 @@ bool UnwrappedLineParser::tryToParseLambda() {
   return true;
 }
   }
+
   FormatTok->setFinalizedType(TT_LambdaLBrace);
   LSquare.setFinalizedType(TT_LambdaLSquare);
+
+  NestedLambdas.push_back(Line->SeenDecltypeAuto);
   parseChildBlock();
+  assert(!NestedLambdas.empty());
+  NestedLambdas.pop_back();
+
   return true;
 }
 
@@ -2469,6 +2490,8 @@ bool UnwrappedLineParser::parseParens(TokenType 
AmpAmpTokenType) {
PrevPrev->endsSequence(tok::kw_constexpr, tok::kw_if;
 const bool ReturnParens =
 Style.RemoveParentheses == FormatStyle::RPS_ReturnStatement &&
+((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
+ (!NestedLambdas.empty() && !NestedLambdas.back())) &&
 Prev && Prev->isOneOf(tok::kw_return, tok::kw_co_return) && Next &&
 Next->is(tok::semi);
 if ((DoubleParens && !Blacklisted) || ReturnParens) {
@@ -4379,6 +4402,7 @@ void UnwrappedLineParser::addUnwrappedLine(LineLevel 
AdjustLevel) {
   Line->MatchingOpeningBlockLineIndex = UnwrappedLine::kInvalidIndex;
   Line->FirstStartColumn = 0;
   Line->IsContinuation = false;
+  Line->SeenDecltypeAuto = false;
 
   if (ClosesWhitesmithsBlock && AdjustLevel == LineLevel::Remove)
 --Line->Level;
diff --git a/clang/lib/Format/UnwrappedLineParser.h 
b/clang/lib/Format/UnwrappedLineParser.h
index 4138baaabe2693d..a4f150d19571266 100644
--- a/clang/lib/Format/UnwrappedLineParser.h
+++ b/clang/lib/Format/UnwrappedLineParser.h
@@ -61,6 +61,9 @@ struct UnwrappedLine {
 
   bool MustBeDeclaration = false;
 
+  /// Whether the parser has seen \c decltype(auto) in this line.
+  bool SeenDecltypeAuto = false;
+
   /// \c True if this line should be indented by ContinuationIndent in
   /// addition to the normal indention level.
   bool IsContinuation = false;
@@ -335,6 +338,14 @@ class UnwrappedLineParser {
   // statement contains more than some predefined number of nested statements).
   SmallVector NestedTooDeep;
 
+  // Keeps a stack of the states of nested lambdas (true if the return type of
+  // the lambda is `decltype(auto)`).
+  SmallVector