[clang] d989950 - [clang-format] Disallow decltype in the middle of constraints

Emilia Dreamer via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 5 19:18:35 PST 2023


Author: Emilia Dreamer
Date: 2023-01-06T05:18:28+02:00
New Revision: d9899501576e7b3b8ec4a3f0f855a6bfe68cef88

URL: https://github.com/llvm/llvm-project/commit/d9899501576e7b3b8ec4a3f0f855a6bfe68cef88
DIFF: https://github.com/llvm/llvm-project/commit/d9899501576e7b3b8ec4a3f0f855a6bfe68cef88.diff

LOG: [clang-format] Disallow decltype in the middle of constraints

If a function with a `requires` clause as a constraint has a decltype
return type, such as `decltype(auto)`, the decltype was seen to be part
of the constraint clause, rather than as part of the function
declaration, causing it to be placed on the wrong line.

This patch disallows decltype to be a part of these clauses

Fixes https://github.com/llvm/llvm-project/issues/59578

Depends on D140339

Reviewed By: HazardyKnusperkeks, owenpan, MyDeveloperDay

Differential Revision: https://reviews.llvm.org/D140312

Added: 
    

Modified: 
    clang/lib/Format/UnwrappedLineParser.cpp
    clang/unittests/Format/FormatTest.cpp
    clang/unittests/Format/TokenAnnotatorTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 81a6d8ffc0ee..c97ecc782120 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -3543,7 +3543,6 @@ void UnwrappedLineParser::parseConstraintExpression() {
     case tok::minus:
     case tok::star:
     case tok::slash:
-    case tok::kw_decltype:
       LambdaNextTimeAllowed = true;
       // Just eat them.
       nextToken();

diff  --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 21b497bd9568..b2a1e2c57f8c 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -24199,6 +24199,10 @@ TEST_F(FormatTest, RequiresClauses) {
                "  }\n"
                "};");
 
+  verifyFormat("template <class T>\n"
+               "  requires(std::same_as<int, T>)\n"
+               "decltype(auto) fun() {}");
+
   auto Style = getLLVMStyle();
 
   verifyFormat(

diff  --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 806c75d1e813..dba893dfdd50 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -580,6 +580,14 @@ TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
   EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
   EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName);
 
+  Tokens = annotate("template <typename T>\n"
+                    "requires Bar<T>\n"
+                    "decltype(auto) foo(T) { return false; }");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[14], tok::identifier, TT_FunctionDeclarationName);
+
   Tokens = annotate("template <typename T>\n"
                     "struct S {\n"
                     "  void foo() const requires Bar<T>;\n"


        


More information about the cfe-commits mailing list