From 9c5ca11a33fa91345fe813d449ddc4a821fc72d5 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sat, 27 Jun 2020 08:54:39 +0100 Subject: [PATCH] coroutines: Improve diagnostics for one allocator case. If the user provides operator new and that is noexcept, this implies that it can fail with a null return. At that point, we expect to be able to call get_return_object_on_allocation_failure(). This diagnoses the case where such an operator new has been provided, but the g-r-o-o-a-f is either missing or unusable. gcc/cp/ChangeLog: * coroutines.cc (morph_fn_to_coro): Diagnose unavailable get_return_object_on_allocation_failure. gcc/testsuite/ChangeLog: * g++.dg/coroutines/coro-bad-grooaf-01-grooaf-expected.C: New test. --- gcc/cp/coroutines.cc | 4 ++++ .../coro-bad-grooaf-01-grooaf-expected.C | 14 ++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 gcc/testsuite/g++.dg/coroutines/coro-bad-grooaf-01-grooaf-expected.C diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 6e723c402db..8b8d00e8e0c 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -4041,6 +4041,10 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) else if (grooaf && !TYPE_NOTHROW_P (TREE_TYPE (func))) error_at (fn_start, "%qE is provided by %qT but %qE is not marked" " % or %", grooaf, promise_type, nwname); + else if (!grooaf && TYPE_NOTHROW_P (TREE_TYPE (func))) + warning_at (fn_start, 0, "%qE is marked % or % but" + " no usable %" + " is provided by %qT ", nwname, promise_type); } else /* No operator new in the promise. */ { diff --git a/gcc/testsuite/g++.dg/coroutines/coro-bad-grooaf-01-grooaf-expected.C b/gcc/testsuite/g++.dg/coroutines/coro-bad-grooaf-01-grooaf-expected.C new file mode 100644 index 00000000000..9fa3d64a9f2 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/coro-bad-grooaf-01-grooaf-expected.C @@ -0,0 +1,14 @@ +/* g-r-o-o-a-f would be expected, since we have a noexcept op new. */ + +#define USE_FAILING_OP_NEW +#include "coro1-allocators.h" + +int used_grooaf = 0; + +struct coro1 +f () noexcept // { dg-warning {'operator new' is marked 'throw\(\)' or 'noexcept' but no usable 'get_return_object_on_allocation_failure' is provided by 'std::__n4861::__coroutine_traits_impl::promise_type' \{aka 'coro1::promise_type'\}} } +{ + PRINT ("coro1: about to return"); + co_return; +} + -- 2.30.2