Hi As pointed out in the PR, parameters to user-defined coroutines might be unnamed. In that case, we must synthesize a name for the coroutine frame copy.
tested on x86_64-darwin16 so far, OK if it passes regtest on x86_64-linux? thanks Iain gcc/cp/ChangeLog: 2020-04-25 Iain Sandoe <i...@sandoe.co.uk> * coroutines.cc (morph_fn_to_coro): Ensure that unnamed function params have a usable and distinct frame field name. gcc/testsuite/ChangeLog: 2020-04-25 Iain Sandoe <i...@sandoe.co.uk> * g++.dg/coroutines/pr94752.C: New test. --- gcc/cp/coroutines.cc | 11 +++++++++-- gcc/testsuite/g++.dg/coroutines/pr94752.C | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/coroutines/pr94752.C diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 137d87bf294..ab1bdb9bcdb 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -3797,6 +3797,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) param_uses = new hash_map<tree, param_info>; bool lambda_p = LAMBDA_TYPE_P (DECL_CONTEXT (orig)); + unsigned no_name_parm = 0; for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; arg = DECL_CHAIN (arg)) { @@ -3847,8 +3848,14 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) parm.lambda_cobj = false; parm.trivial_dtor = TYPE_HAS_TRIVIAL_DESTRUCTOR (parm.frame_type); - tree pname = DECL_NAME (arg); - char *buf = xasprintf ("__parm.%s", IDENTIFIER_POINTER (pname)); + char *buf; + if (DECL_NAME (arg)) + { + tree pname = DECL_NAME (arg); + buf = xasprintf ("__parm.%s", IDENTIFIER_POINTER (pname)); + } + else + buf = xasprintf ("__unnamed_parm.%d", no_name_parm++); parm.field_id = coro_make_frame_entry (&field_list, buf, actual_type, DECL_SOURCE_LOCATION (arg)); free (buf); diff --git a/gcc/testsuite/g++.dg/coroutines/pr94752.C b/gcc/testsuite/g++.dg/coroutines/pr94752.C new file mode 100644 index 00000000000..7aa48ae8900 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr94752.C @@ -0,0 +1,17 @@ +#include <coroutine> +using namespace std; + +struct task { + struct promise_type { + promise_type() {} + task get_return_object() { return {}; } + suspend_never initial_suspend() { return {}; } + suspend_never final_suspend() { return {}; } + void return_void() {} + void unhandled_exception() {} + }; +}; + +task foo(int) { + co_return; +} -- 2.24.1