https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/191817
>From 2ff11e8039463280bb77cc77a860555f019bd933 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 fd58d7847717c..feaba77368005 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -430,6 +430,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) - Clang incorrectly instantiated variable specializations outside of the immediate context. (#GH54439) - Fixed a crash when instantiating an invalid out-of-line static data member definition in a local class. (#GH176152) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 6647e52535114..6923d4df6f97f 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
