coroutines: Prevent repeated error messages for missing promise.

Message ID A1E4F98A-45D2-49CE-8917-3EE9BBC97D3B@sandoe.co.uk
State New
Headers show
Series
  • coroutines: Prevent repeated error messages for missing promise.
Related show

Commit Message

Iain Sandoe Jan. 28, 2020, 8:55 p.m.
While looking at Pr93458, I spotted the following non-fatal, but 
unhelpful diagnostic output.

If the user's coroutine return type omits the mandatory promise
type then we will currently restate that error each time we see
a coroutine keyword, which doesn't provide any new information.
This suppresses all but the first instance in each coroutine.

tested on x86_64-darwin16
OK for master?
thanks
Iain

gcc/cp/ChangeLog:

2020-01-28  Iain Sandoe  <iain@sandoe.co.uk>

* coroutines.cc (find_promise_type): Delete unused forward
declaration.
(struct coroutine_info): Add a bool for no promise type error.
(coro_promise_type_found_p): Only emit the error for a missing
promise once in each affected coroutine.

gcc/testsuite/ChangeLog:

2020-01-28  Iain Sandoe  <iain@sandoe.co.uk>

* g++.dg/coroutines/coro-missing-promise.C: New test.
---
 gcc/cp/coroutines.cc                          |  7 +++++--
 .../g++.dg/coroutines/coro-missing-promise.C  | 20 +++++++++++++++++++
 2 files changed, 25 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/coroutines/coro-missing-promise.C

-- 
2.24.1

Comments

Nathan Sidwell Jan. 29, 2020, 2:40 p.m. | #1
On 1/28/20 3:55 PM, Iain Sandoe wrote:
> While looking at Pr93458, I spotted the following non-fatal, but

> unhelpful diagnostic output.

> 

> If the user's coroutine return type omits the mandatory promise

> type then we will currently restate that error each time we see

> a coroutine keyword, which doesn't provide any new information.

> This suppresses all but the first instance in each coroutine.

> 

> tested on x86_64-darwin16

> OK for master?

> thanks

> Iain

> 

> gcc/cp/ChangeLog:

> 

> 2020-01-28  Iain Sandoe  <iain@sandoe.co.uk>

> 

> * coroutines.cc (find_promise_type): Delete unused forward

> declaration.

> (struct coroutine_info): Add a bool for no promise type error.

> (coro_promise_type_found_p): Only emit the error for a missing

> promise once in each affected coroutine.


ok, thanks.

nathan
-- 
Nathan Sidwell

Patch

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 89ecea91b9a..a56bbc883ca 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -33,7 +33,6 @@  along with GCC; see the file COPYING3.  If not see
 #include "gcc-rich-location.h"
 #include "hash-map.h"
 
-static tree find_promise_type (tree);
 static bool coro_promise_type_found_p (tree, location_t);
 
 /* GCC C++ coroutines implementation.
@@ -93,6 +92,7 @@  struct GTY((for_user)) coroutine_info
 				    function into a coroutine.  */
   /* Flags to avoid repeated errors for per-function issues.  */
   bool coro_ret_type_error_emitted;
+  bool coro_promise_error_emitted;
 };
 
 struct coroutine_info_hasher : ggc_ptr_hash<coroutine_info>
@@ -447,7 +447,10 @@  coro_promise_type_found_p (tree fndecl, location_t loc)
       /* If we don't find it, punt on the rest.  */
       if (coro_info->promise_type == NULL_TREE)
 	{
-	  error_at (loc, "unable to find the promise type for this coroutine");
+	  if (!coro_info->coro_promise_error_emitted)
+	    error_at (loc, "unable to find the promise type for"
+		      " this coroutine");
+	  coro_info->coro_promise_error_emitted = true;
 	  return false;
 	}
 
diff --git a/gcc/testsuite/g++.dg/coroutines/coro-missing-promise.C b/gcc/testsuite/g++.dg/coroutines/coro-missing-promise.C
new file mode 100644
index 00000000000..3fc21a4e2ca
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/coro-missing-promise.C
@@ -0,0 +1,20 @@ 
+//  { dg-additional-options "-fsyntax-only -w" }
+
+#include "coro.h"
+
+// Diagnose completely missing promise.
+
+// { dg-error {no type named 'promise_type' in 'struct NoPromiseHere'} "" { target *-*-* } 0 }
+
+struct NoPromiseHere {
+  coro::coroutine_handle<> handle;
+  NoPromiseHere () : handle (nullptr) {}
+  NoPromiseHere (coro::coroutine_handle<> handle) : handle (handle) {}
+};
+
+NoPromiseHere
+bar ()
+{
+  co_yield 22; // { dg-error {unable to find the promise type for this coroutine} }
+  co_return 0;
+}