diff options
Diffstat (limited to 'gcc/cp/coroutines.cc')
-rw-r--r-- | gcc/cp/coroutines.cc | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index cdf6503..551ddc9 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -513,8 +513,14 @@ coro_promise_type_found_p (tree fndecl, location_t loc) coro_info->promise_type); inform (DECL_SOURCE_LOCATION (BASELINK_FUNCTIONS (has_ret_void)), "%<return_void%> declared here"); - inform (DECL_SOURCE_LOCATION (BASELINK_FUNCTIONS (has_ret_val)), - "%<return_value%> declared here"); + has_ret_val = BASELINK_FUNCTIONS (has_ret_val); + const char *message = "%<return_value%> declared here"; + if (TREE_CODE (has_ret_val) == OVERLOAD) + { + has_ret_val = OVL_FIRST (has_ret_val); + message = "%<return_value%> first declared here"; + } + inform (DECL_SOURCE_LOCATION (has_ret_val), message); coro_info->coro_co_return_error_emitted = true; return false; } @@ -877,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 { @@ -1148,10 +1155,13 @@ finish_co_await_expr (location_t kw, tree expr) extraneous warnings during substitution. */ suppress_warning (current_function_decl, OPT_Wreturn_type); - /* If we don't know the promise type, we can't proceed, build the - co_await with the expression unchanged. */ - tree functype = TREE_TYPE (current_function_decl); - if (dependent_type_p (functype) || type_dependent_expression_p (expr)) + /* Defer expansion when we are processing a template. + FIXME: If the coroutine function's type is not dependent, and the operand + is not dependent, we should determine the type of the co_await expression + using the DEPENDENT_EXPR wrapper machinery. That allows us to determine + the subexpression type, but leave its operand unchanged and then + instantiate it later. */ + if (processing_template_decl) { tree aw_expr = build5_loc (kw, CO_AWAIT_EXPR, unknown_type_node, expr, NULL_TREE, NULL_TREE, NULL_TREE, @@ -1222,10 +1232,9 @@ finish_co_yield_expr (location_t kw, tree expr) extraneous warnings during substitution. */ suppress_warning (current_function_decl, OPT_Wreturn_type); - /* If we don't know the promise type, we can't proceed, build the - co_await with the expression unchanged. */ - tree functype = TREE_TYPE (current_function_decl); - if (dependent_type_p (functype) || type_dependent_expression_p (expr)) + /* Defer expansion when we are processing a template; see FIXME in the + co_await code. */ + if (processing_template_decl) return build2_loc (kw, CO_YIELD_EXPR, unknown_type_node, expr, NULL_TREE); if (!coro_promise_type_found_p (current_function_decl, kw)) @@ -1307,10 +1316,9 @@ finish_co_return_stmt (location_t kw, tree expr) && check_for_bare_parameter_packs (expr)) return error_mark_node; - /* If we don't know the promise type, we can't proceed, build the - co_return with the expression unchanged. */ - tree functype = TREE_TYPE (current_function_decl); - if (dependent_type_p (functype) || type_dependent_expression_p (expr)) + /* Defer expansion when we are processing a template; see FIXME in the + co_await code. */ + if (processing_template_decl) { /* co_return expressions are always void type, regardless of the expression type. */ @@ -3109,7 +3117,7 @@ maybe_promote_temps (tree *stmt, void *d) If the initializer is a conditional expression, we need to collect and declare any promoted variables nested within it. DTORs for such variables must be run conditionally too. */ - if (t->var && DECL_NAME (t->var)) + if (t->var) { tree var = t->var; DECL_CHAIN (var) = vlist; @@ -3310,7 +3318,7 @@ add_var_to_bind (tree& bind, tree var_type, tree b_vars = BIND_EXPR_VARS (bind); /* Build a variable to hold the condition, this will be included in the frame as a local var. */ - char *nam = xasprintf ("%s.%d", nam_root, nam_vers); + char *nam = xasprintf ("__%s_%d", nam_root, nam_vers); tree newvar = build_lang_decl (VAR_DECL, get_identifier (nam), var_type); free (nam); DECL_CHAIN (newvar) = b_vars; @@ -3955,7 +3963,7 @@ register_local_var_uses (tree *stmt, int *do_subtree, void *d) scopes with identically named locals and still be able to identify them in the coroutine frame. */ tree lvname = DECL_NAME (lvar); - char *buf; + char *buf = NULL; /* The outermost bind scope contains the artificial variables that we inject to implement the coro state machine. We want to be able @@ -3965,14 +3973,14 @@ register_local_var_uses (tree *stmt, int *do_subtree, void *d) else if (lvname != NULL_TREE) buf = xasprintf ("%s_%u_%u", IDENTIFIER_POINTER (lvname), lvd->nest_depth, lvd->bind_indx); - else - buf = xasprintf ("_D%u_%u_%u", DECL_UID (lvar), lvd->nest_depth, - lvd->bind_indx); /* TODO: Figure out if we should build a local type that has any excess alignment or size from the original decl. */ - local_var.field_id - = coro_make_frame_entry (lvd->field_list, buf, lvtype, lvd->loc); - free (buf); + if (buf) + { + local_var.field_id = coro_make_frame_entry (lvd->field_list, buf, + lvtype, lvd->loc); + free (buf); + } /* We don't walk any of the local var sub-trees, they won't contain any bind exprs. */ } |