Clang error: 'A' cannot be used in the handler of a try block (err_coroutine_within_handler)
Jump to navigation
Jump to search
Text | error: 'A' cannot be used in the handler of a try block (since 9.0) |
---|---|
Type | Error |
Category | Coroutines Issue (since 9.0) |
Internal Id | err_coroutine_within_handler (since 9.0) |
Internal Message | '%0' cannot be used in the handler of a try block (since 9.0)
|
Regular Expression | (?:error|fatal error)\: '(.*?)' cannot be used in the handler of a try block
|
First Commit | 2019-03-15 9db9b1a17501 [coroutines][PR40978] Emit error for co_yield within catch block |
Description
Example
Flags | -std=c++20 -xc++
|
|
---|---|---|
Source |
#include <coroutine>
struct A{}; // Empty class to be used in catch
// Awaitable object
struct awaiter {
bool await_ready() noexcept { return false; } // Always await
void await_suspend(std::coroutine_handle<>) noexcept {} // Suspend logic
void await_resume() noexcept {} // Resume logic
};
// B has operator co_await
struct B {
auto operator co_await() const noexcept { return awaiter{}; }
};
// C has operator co_await and a destructor, making it unable to be used in a catch
struct C {
C() noexcept {}
~C() {}
auto operator co_await() const noexcept { return awaiter{}; }
};
// Coroutine that co_awaits on B
auto coro() -> std::coroutine_handle<> {
co_await B();
co_return;
}
// Main function trying to co_await in a catch block, which is invalid
int main() {
try {
coro().destroy();
} catch (A&) {
co_await C(); // Invalid use of co_await in catch
}
}
| |
Compiler Output |
<source>:25:6: error: this function cannot be a coroutine: 'std::coroutine_traits<std::coroutine_handle<void>>' has no member named 'promise_type' <source>:25:6: error: this function cannot be a coroutine: 'std::coroutine_traits<std::coroutine_handle<void>>' has no member named 'promise_type' <source>:35:5: error: 'co_await' cannot be used in the handler of a try block |
Clang Internals (17.0.6)
Git Commit Message
[coroutines][PR40978] Emit error for co_yield within catch block Summary: As reported in https://bugs.llvm.org/show_bug.cgi?id=40978, it's an error to use the `co_yield` or `co_await` keywords outside of a valid "suspension context" as defined by [expr.await]p2 of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4775.pdf. Whether or not the current scope was in a function-try-block's (https://en.cppreference.com/w/cpp/language/function-try-block) handler could be determined using scope flag `Scope::FnTryCatchScope`. No such flag existed for a simple C++ catch statement, so this commit adds one. Reviewers: GorNishanov, tks2103, rsmith Reviewed By: GorNishanov Subscribers: EricWF, jdoerfert, cfe-commits, lewissbaker Tags: #clang Differential Revision: https://reviews.llvm.org/D59076 llvm-svn: 356296
Used in Clang Sources
This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.
clang/lib/Sema/SemaCoroutine.cpp (line 781)
// [expr.await]p2, emphasis added: "An await-expression shall appear only in
// a *potentially evaluated* expression within the compound-statement of a
// function-body *outside of a handler* [...] A context within a function
// where an await-expression can appear is called a suspension context of the
// function."
static bool checkSuspensionContext(Sema &S, SourceLocation Loc, StringRef Keyword) {
// ...
// Second emphasis of [expr.await]p2: must be outside of an exception handler.
if (isWithinCatchScope(S.getCurScope())) {
S.Diag(Loc, diag::err_coroutine_within_handler) << Keyword;
Triggered in Clang Tests
This section lists all internal Clang test cases that trigger the diagnostic.
clang/test/SemaCXX/coroutines.cpp
- clang/test/SemaCXX/coroutines.cpp:357:5: error: 'co_await' cannot be used in the handler of a try block
- clang/test/SemaCXX/coroutines.cpp:365:7: error: 'co_await' cannot be used in the handler of a try block
- clang/test/SemaCXX/coroutines.cpp:383:5: error: 'co_yield' cannot be used in the handler of a try block