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
