c++, coroutines: Improve check for throwing final await [PR104051].
We check that the final_suspend () method returns a sane type (i.e. a class or structure) but, unfortunately, that check has to be later than the one for a throwing case. If the use returns some nonsensical type from the method, we need to handle that in the checking for noexcept. Signed-off-by: Iain Sandoe <iain@sandoe.co.uk> PR c++/104051 gcc/cp/ChangeLog: * coroutines.cc (coro_diagnose_throwing_final_aw_expr): Handle non-target expression inputs. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr104051.C: New test.
This commit is contained in:
parent
6cae3bb65c
commit
7b96274a34
@ -883,13 +883,14 @@ coro_diagnose_throwing_fn (tree fndecl)
|
||||
static bool
|
||||
coro_diagnose_throwing_final_aw_expr (tree expr)
|
||||
{
|
||||
tree t = TARGET_EXPR_INITIAL (expr);
|
||||
if (TREE_CODE (expr) == TARGET_EXPR)
|
||||
expr = TARGET_EXPR_INITIAL (expr);
|
||||
tree fn = NULL_TREE;
|
||||
if (TREE_CODE (t) == CALL_EXPR)
|
||||
fn = CALL_EXPR_FN(t);
|
||||
else if (TREE_CODE (t) == AGGR_INIT_EXPR)
|
||||
fn = AGGR_INIT_EXPR_FN (t);
|
||||
else if (TREE_CODE (t) == CONSTRUCTOR)
|
||||
if (TREE_CODE (expr) == CALL_EXPR)
|
||||
fn = CALL_EXPR_FN (expr);
|
||||
else if (TREE_CODE (expr) == AGGR_INIT_EXPR)
|
||||
fn = AGGR_INIT_EXPR_FN (expr);
|
||||
else if (TREE_CODE (expr) == CONSTRUCTOR)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
|
29
gcc/testsuite/g++.dg/coroutines/pr104051.C
Normal file
29
gcc/testsuite/g++.dg/coroutines/pr104051.C
Normal file
@ -0,0 +1,29 @@
|
||||
// { dg-additional-options "-fsyntax-only" }
|
||||
#include <coroutine>
|
||||
#include <vector>
|
||||
template <typename> struct promise {
|
||||
struct final_awaitable {
|
||||
bool await_ready() noexcept;
|
||||
template <typename Promise>
|
||||
std::coroutine_handle<>
|
||||
await_suspend(std::coroutine_handle<Promise>) noexcept;
|
||||
void await_resume() noexcept;
|
||||
};
|
||||
auto get_return_object() {
|
||||
return std::coroutine_handle<promise>::from_promise(*this);
|
||||
}
|
||||
auto initial_suspend() { return std::suspend_always(); }
|
||||
auto final_suspend() noexcept { return true; }
|
||||
void unhandled_exception();
|
||||
};
|
||||
template <typename T> struct task {
|
||||
using promise_type = promise<T>;
|
||||
task(std::coroutine_handle<promise<T>>);
|
||||
bool await_ready();
|
||||
std::coroutine_handle<> await_suspend(std::coroutine_handle<>);
|
||||
T await_resume();
|
||||
};
|
||||
task<std::vector<int>> foo() { // { dg-error {awaitable type 'bool' is not a structure} }
|
||||
while ((co_await foo()).empty())
|
||||
;
|
||||
}
|
Loading…
Reference in New Issue
Block a user