On 1/29/20 10:39 AM, Iain Sandoe wrote:
Hi Nathan,
Nathan Sidwell <nat...@acm.org> wrote:
Made the function type error recorded per function too.
OK now?
Still some things to address ...
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index e8a6a4033f6..3ad80699ca0 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -257,9 +260,15 @@ find_coro_traits_template_decl (location_t kw)
{
tree traits_decl = lookup_qualified_name (std_node, coro_traits_identifier,
0, true);
- if (traits_decl == NULL_TREE || traits_decl == error_mark_node)
- {
- error_at (kw, "cannot find %<coroutine traits%> template");
+ /* If we are missing fundmental information, such as the traits, then don't
+ emit this for every keyword in a TU. This particular error is per TU
+ so we don't need to keep the indicator per function. */
+ static bool traits_error_emitted = false;
You can of course move this into the if's block scope.
+ if (traits_decl == error_mark_node)
+ {
+ if (!traits_error_emitted)
+ error_at (kw, "cannot find %<coroutine traits%> template");
Give the name you were looking for:
"%<%E::%E%> ...", std_node, coro_traits_identifier
also, what if you find something, but it's not a type template?
/* Coroutine traits template. */
coro_traits_templ = find_coro_traits_template_decl (loc);
- gcc_checking_assert (coro_traits_templ != NULL);
+ if (coro_traits_templ == NULL_TREE
+ || coro_traits_templ == error_mark_node)
+ return false;
ISTM that find_coro_traits_template_decl should be returning exactly one
of NULL_TREE of error_mark_node on failure. Its users don't
particularly care why it failed (not found vs found ambiguous/not template).
+ /* Save the coroutine data on the side to avoid the overhead on every
+ function decl tree. */
+
coroutine_info *coro_info = get_or_insert_coroutine_info (fndecl);
/* Without this, we cannot really proceed. */
gcc_checking_assert (coro_info);
@@ -407,6 +427,18 @@ coro_promise_type_found_p (tree fndecl, location_t loc)
{
/* Get the coroutine traits template class instance for the function
signature we have - coroutine_traits <R, ...> */
+ if (!CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))))
+ {
+ /* It makes more sense to show the function header for this, even
+ though we will have encountered it when processing a keyword.
+ Only emit the error once, not for every keyword we encounter. */
+ if (!coro_info->coro_ret_type_error_emitted)
+ error_at (DECL_SOURCE_LOCATION (fndecl), "a coroutine must have a"
+ " class or struct return type");
Perhaps something like "coroutine return type %qT is not a class"? I.e.
show them the type.
(structs are classes, there's no need to say 'class or struct')
+ coro_info->coro_ret_type_error_emitted = true;
+ return false;
+ }
+
tree templ_class = instantiate_coro_traits (fndecl, loc);
/* Find the promise type for that. */
@@ -422,7 +454,7 @@ coro_promise_type_found_p (tree fndecl, location_t loc)
/* Try to find the handle type for the promise. */
tree handle_type =
instantiate_coro_handle_for_promise_type (loc, coro_info->promise_type);
- if (handle_type == NULL_TREE)
+ if (handle_type == NULL_TREE || handle_type == error_mark_node)
similar to coro_traits_template_decl.
--
Nathan Sidwell