coroutines: Prevent repeated error messages for missing promise.
authorIain Sandoe <iain@sandoe.co.uk>
Tue, 4 Feb 2020 09:36:30 +0000 (09:36 +0000)
committerIain Sandoe <iain@sandoe.co.uk>
Tue, 4 Feb 2020 09:37:18 +0000 (09:37 +0000)
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.

gcc/cp/ChangeLog:

2020-02-04  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-02-04  Iain Sandoe  <iain@sandoe.co.uk>

* g++.dg/coroutines/coro-missing-promise.C: New test.

gcc/cp/ChangeLog
gcc/cp/coroutines.cc
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/coroutines/coro-missing-promise.C [new file with mode: 0644]

index 8b352134aa73d6cf50c7e24b546145d70311672c..ab63ec7a0fed6ba2def0aa8aa037d7057efe8e7c 100644 (file)
@@ -1,3 +1,11 @@
+2020-02-04  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.
+
 2020-02-03  Jason Merrill  <jason@redhat.com>
 
        PR c++/66477
index 8a0ce384425d08c51eba1da583ea248f0d36d3dd..d5ff6750d2ee38cfcb1f384b7ba089178b8537c0 100644 (file)
@@ -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>
@@ -460,7 +460,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;
        }
 
index 06dba78e16f3e0dceaadf6236e22826dc00432e6..8e245303974c43c634ac19b28edb141f19bc74ff 100644 (file)
@@ -1,3 +1,7 @@
+2020-02-04  Iain Sandoe  <iain@sandoe.co.uk>
+
+       * g++.dg/coroutines/coro-missing-promise.C: New test.
+
 2020-02-04  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/91123
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 (file)
index 0000000..3fc21a4
--- /dev/null
@@ -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;
+}