https://github.com/cor3ntin created 
https://github.com/llvm/llvm-project/pull/191817

co_await/co_yield expressions are not allowed in default arguments. We were 
checking they do not appear outside of function contexts, which include default 
arguments of the corresponding function, but it missed default arguments of 
functions declared in the body of another functions.

Because parsing default argument isn't done in a dedicated scope, we do 
additional checks in `ActOnParamDefaultArgument`. Because the checks is done in 
two places, we cannot introduce a more precise diagnostic.

It might be worth considering a parse scope for default arguments in the future.

Fixes #98923

>From 65e67195e75e45ac6ea54183159d7b361cffea68 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Mon, 13 Apr 2026 15:50:40 +0200
Subject: [PATCH] [Clang] Diagnose `co_await` expressions in default arguments
 of nested functions

co_await/co_yield expressions are not allowed in default arguments.
We were checking they do not appear outside of function contexts,
which include default arguments of the corresponding function,
but it missed default argumernts of functions declared in the body
of another functions.

Because parsing default argument isn't done in a dedicated scope,
we do additional checks in `ActOnParamDefaultArgument`.
Because the chgecks is done in two places, we cannot introduce
a more precise diagnostic.

It might be worth considering a parse scope for default arguments
in the future.

Fixes #98923
---
 clang/docs/ReleaseNotes.rst       |  1 +
 clang/lib/Sema/SemaDeclCXX.cpp    | 19 +++++++++++++++++++
 clang/test/SemaCXX/coroutines.cpp | 21 +++++++++++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2da7175b51ea3..5bc016c0e1c6d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -426,6 +426,7 @@ Bug Fixes to C++ Support
   template parameters when one of its parameters is also a pack. (#GH181166)
 - Fixed a crash when a default argument is passed to an explicit object 
parameter. (#GH176639)
 - Fixed an alias template CTAD crash.
+- Correctly diagnose usesof ``coawait`` in the default argument of nested 
function declarations. (#GH98923)
 - Fixed a crash when diagnosing an invalid static member function with an 
explicit object parameter (#GH177741)
 - Fixed a crash when instantiating an invalid out-of-line static data member 
definition in a local class. (#GH176152)
 - Fixed a crash when pack expansions are used as arguments for non-pack 
parameters of built-in templates. (#GH180307)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index c1d3960e65ef6..c4a28796f4b5a 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -83,6 +83,8 @@ class CheckDefaultArgumentVisitor
   bool VisitCXXThisExpr(const CXXThisExpr *ThisE);
   bool VisitLambdaExpr(const LambdaExpr *Lambda);
   bool VisitPseudoObjectExpr(const PseudoObjectExpr *POE);
+  bool VisitCoawaitExpr(const CoawaitExpr *E);
+  bool VisitCoyieldExpr(const CoyieldExpr *E);
 };
 
 /// VisitExpr - Visit all of the children of this expression.
@@ -178,6 +180,23 @@ bool CheckDefaultArgumentVisitor::VisitLambdaExpr(const 
LambdaExpr *Lambda) {
   }
   return Invalid;
 }
+
+bool CheckDefaultArgumentVisitor::VisitCoawaitExpr(const CoawaitExpr *E) {
+  // [expr.await] An await-expression shall not appear in a default argument.
+  // Note that this is generally diagnosed by isValidCoroutineContext,
+  // however isValidCoroutineContext misses default argument in nested
+  // function declarations.
+  S.Diag(E->getBeginLoc(), diag::err_coroutine_outside_function)
+      << "co_await" << E->getSourceRange();
+  return true;
+}
+
+bool CheckDefaultArgumentVisitor::VisitCoyieldExpr(const CoyieldExpr *E) {
+  S.Diag(E->getBeginLoc(), diag::err_coroutine_outside_function)
+      << "co_yield" << E->getSourceRange();
+  return true;
+}
+
 } // namespace
 
 void
diff --git a/clang/test/SemaCXX/coroutines.cpp 
b/clang/test/SemaCXX/coroutines.cpp
index 098c1c21a5962..dcb670ea13173 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -1545,3 +1545,24 @@ void warn_always_inline() { // expected-warning {{this 
coroutine may be split in
 void warn_gnu_always_inline() { // expected-warning {{this coroutine may be 
split into pieces; not every piece is guaranteed to be inlined}}
   co_await suspend_always{};
 }
+
+namespace GH98923 {
+struct Awaiter : suspend_never {
+  int await_resume() { return 0; }
+};
+
+void f(int x = co_await Awaiter{});
+// expected-error@-1 {{'co_await' cannot be used outside a function}}
+
+void g() {
+    void g1(int x = co_await Awaiter{});
+    // expected-error@-1 {{'co_await' cannot be used outside a function}}
+    void g2(int x = ((co_yield 0), 1));
+    // expected-error@-1 {{'co_yield' cannot be used outside a function}}
+    auto g3 = [&](int x = co_await Awaiter{}) -> void{
+    // expected-error@-1 {{'co_await' cannot be used outside a function}}
+        co_return 0;
+    };
+}
+
+}

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

Reply via email to