https://github.com/SoulTch updated 
https://github.com/llvm/llvm-project/pull/218168

>From f7bc746481505ceff87e0140e1d4de5c149b0e5d Mon Sep 17 00:00:00 2001
From: Jeongjin Lee <[email protected]>
Date: Sat, 22 Aug 2026 17:32:21 -0400
Subject: [PATCH 1/3] [Clang] Mark the declaration invalid when a function
 definition has no body

Fixes #194298

Assisted-by: Claude Opus 5 (Claude Code)
---
 clang/lib/Parse/ParseCXXInlineMethods.cpp | 1 +
 clang/lib/Parse/ParseTemplate.cpp         | 4 +++-
 clang/lib/Parse/Parser.cpp                | 2 ++
 clang/test/SemaCXX/coroutines.cpp         | 8 ++++++++
 4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp 
b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 3f101feb26a6d..51591011ca548 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -633,6 +633,7 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
     // Error recovery.
     if (!Tok.is(tok::l_brace)) {
       FnScope.Exit();
+      LM.D->getAsFunction()->setInvalidDecl();
       Actions.ActOnFinishFunctionBody(LM.D, nullptr);
       return;
     }
diff --git a/clang/lib/Parse/ParseTemplate.cpp 
b/clang/lib/Parse/ParseTemplate.cpp
index 7a3629ddc19a9..a174778307ada 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1528,8 +1528,10 @@ void 
Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
              "current template being instantiated!");
       ParseFunctionStatementBody(LPT.D, FnScope);
       Actions.UnmarkAsLateParsedTemplate(FunD);
-    } else
+    } else {
+      FunD->setInvalidDecl();
       Actions.ActOnFinishFunctionBody(LPT.D, nullptr);
+    }
   }
 }
 
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index bad81ea92cd2d..5c39ba2ad71a1 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1407,6 +1407,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator 
&D,
     // Recover from error.
     if (!Tok.is(tok::l_brace)) {
       BodyScope.Exit();
+      if (Res)
+        Res->getAsFunction()->setInvalidDecl();
       Actions.ActOnFinishFunctionBody(Res, nullptr);
       return Res;
     }
diff --git a/clang/test/SemaCXX/coroutines.cpp 
b/clang/test/SemaCXX/coroutines.cpp
index 4cef2f2b7ea0f..19b2ce1678e1f 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -1566,3 +1566,11 @@ void g() {
 }
 
 }
+
+namespace GH194298 {
+// https://github.com/llvm/llvm-project/issues/194298
+coro<promise_void> f1() : bar { co_await suspend_always{} }; // expected-error 
{{only constructors take base initializers}}
+coro<promise> f2() : bar { co_yield 0 }; // expected-error {{only constructors 
take base initializers}}
+coro<promise_void> f3() : bar { co_return }; // expected-error {{expected 
expression}} \
+                                             // expected-error {{only 
constructors take base initializers}}
+}

>From 6d20dada8a5462eb876883ab2e56477cf4b7bcf5 Mon Sep 17 00:00:00 2001
From: SoulTch <[email protected]>
Date: Sun, 23 Aug 2026 21:08:57 -0400
Subject: [PATCH 2/3] Add coroutine tests for base initializers

Added test cases for coroutine base initializers.
---
 clang/test/SemaCXX/coroutines.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/test/SemaCXX/coroutines.cpp 
b/clang/test/SemaCXX/coroutines.cpp
index 19b2ce1678e1f..207378256859d 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -1568,7 +1568,6 @@ void g() {
 }
 
 namespace GH194298 {
-// https://github.com/llvm/llvm-project/issues/194298
 coro<promise_void> f1() : bar { co_await suspend_always{} }; // expected-error 
{{only constructors take base initializers}}
 coro<promise> f2() : bar { co_yield 0 }; // expected-error {{only constructors 
take base initializers}}
 coro<promise_void> f3() : bar { co_return }; // expected-error {{expected 
expression}} \

>From d456fa79ce697834b41c73d587d6f0ace167df81 Mon Sep 17 00:00:00 2001
From: Jeongjin Lee <[email protected]>
Date: Wed, 26 Aug 2026 16:52:07 -0400
Subject: [PATCH 3/3] [Clang] Factor out function body parsing into
 Parser::ParseFunctionBody

Assisted-by: Claude Opus 5 (Claude Code)
---
 clang/include/clang/Parse/Parser.h        | 11 ++++++++
 clang/lib/Parse/ParseCXXInlineMethods.cpp | 19 +-------------
 clang/lib/Parse/ParseTemplate.cpp         | 31 +++++++----------------
 clang/lib/Parse/Parser.cpp                | 20 +++++++++------
 4 files changed, 33 insertions(+), 48 deletions(-)

diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index ae91153e34e3a..6913c42884a36 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -7738,6 +7738,17 @@ class Parser : public CodeCompletionHandler {
   ///
   Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope);
 
+  /// ParseFunctionBody - Parse the body of a function definition. The
+  /// '= default' and '= delete' forms are handled by the caller.
+  ///
+  /// \verbatim
+  ///       function-body:
+  ///         ctor-initializer[opt] compound-statement
+  ///         function-try-block
+  /// \endverbatim
+  ///
+  Decl *ParseFunctionBody(Decl *D, ParseScope &BodyScope);
+
   /// When in code-completion, skip parsing of the function/method body
   /// unless the body contains the code-completion point.
   ///
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp 
b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 51591011ca548..0340540b239cd 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -623,23 +623,6 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
         Actions.ActOnFinishInlineFunctionDef(FD);
   });
 
-  if (Tok.is(tok::kw_try)) {
-    ParseFunctionTryBlock(LM.D, FnScope);
-    return;
-  }
-  if (Tok.is(tok::colon)) {
-    ParseConstructorInitializer(LM.D);
-
-    // Error recovery.
-    if (!Tok.is(tok::l_brace)) {
-      FnScope.Exit();
-      LM.D->getAsFunction()->setInvalidDecl();
-      Actions.ActOnFinishFunctionBody(LM.D, nullptr);
-      return;
-    }
-  } else
-    Actions.ActOnDefaultCtorInitializers(LM.D);
-
   assert((Actions.getDiagnostics().hasErrorOccurred() ||
           !isa<FunctionTemplateDecl>(LM.D) ||
           cast<FunctionTemplateDecl>(LM.D)->getTemplateParameters()->getDepth()
@@ -647,7 +630,7 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
          "TemplateParameterDepth should be greater than the depth of "
          "current template being instantiated!");
 
-  ParseFunctionStatementBody(LM.D, FnScope);
+  ParseFunctionBody(LM.D, FnScope);
 }
 
 void Parser::ParseLexedMemberInitializers(ParsingClass &Class) {
diff --git a/clang/lib/Parse/ParseTemplate.cpp 
b/clang/lib/Parse/ParseTemplate.cpp
index a174778307ada..ea2b44c359944 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1511,28 +1511,15 @@ void 
Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
 
   Actions.ActOnStartOfFunctionDef(getCurScope(), FunD);
 
-  if (Tok.is(tok::kw_try)) {
-    ParseFunctionTryBlock(LPT.D, FnScope);
-  } else {
-    if (Tok.is(tok::colon))
-      ParseConstructorInitializer(LPT.D);
-    else
-      Actions.ActOnDefaultCtorInitializers(LPT.D);
-
-    if (Tok.is(tok::l_brace)) {
-      assert((!isa<FunctionTemplateDecl>(LPT.D) ||
-              cast<FunctionTemplateDecl>(LPT.D)
-                      ->getTemplateParameters()
-                      ->getDepth() == TemplateParameterDepth - 1) &&
-             "TemplateParameterDepth should be greater than the depth of "
-             "current template being instantiated!");
-      ParseFunctionStatementBody(LPT.D, FnScope);
-      Actions.UnmarkAsLateParsedTemplate(FunD);
-    } else {
-      FunD->setInvalidDecl();
-      Actions.ActOnFinishFunctionBody(LPT.D, nullptr);
-    }
-  }
+  assert((!isa<FunctionTemplateDecl>(LPT.D) ||
+          cast<FunctionTemplateDecl>(LPT.D)
+                  ->getTemplateParameters()
+                  ->getDepth() == TemplateParameterDepth - 1) &&
+         "TemplateParameterDepth should be greater than the depth of "
+         "current template being instantiated!");
+
+  ParseFunctionBody(LPT.D, FnScope);
+  Actions.UnmarkAsLateParsedTemplate(FunD);
 }
 
 void Parser::LexTemplateFunctionForLateParsing(CachedTokens &Toks) {
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 5c39ba2ad71a1..3685de2d5aa28 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1396,26 +1396,30 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator 
&D,
     return Actions.ActOnFinishFunctionBody(Res, nullptr, false);
   }
 
+  return ParseFunctionBody(Res, BodyScope);
+}
+
+Decl *Parser::ParseFunctionBody(Decl *D, ParseScope &BodyScope) {
   if (Tok.is(tok::kw_try))
-    return ParseFunctionTryBlock(Res, BodyScope);
+    return ParseFunctionTryBlock(D, BodyScope);
 
   // If we have a colon, then we're probably parsing a C++
   // ctor-initializer.
   if (Tok.is(tok::colon)) {
-    ParseConstructorInitializer(Res);
+    ParseConstructorInitializer(D);
 
     // Recover from error.
     if (!Tok.is(tok::l_brace)) {
       BodyScope.Exit();
-      if (Res)
-        Res->getAsFunction()->setInvalidDecl();
-      Actions.ActOnFinishFunctionBody(Res, nullptr);
-      return Res;
+      if (D)
+        D->getAsFunction()->setInvalidDecl();
+      Actions.ActOnFinishFunctionBody(D, nullptr);
+      return D;
     }
   } else
-    Actions.ActOnDefaultCtorInitializers(Res);
+    Actions.ActOnDefaultCtorInitializers(D);
 
-  return ParseFunctionStatementBody(Res, BodyScope);
+  return ParseFunctionStatementBody(D, BodyScope);
 }
 
 void Parser::SkipFunctionBody() {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to