Bin.Cheng <[email protected]> wrote:
> On Mon, Jan 20, 2020 at 6:31 PM Iain Sandoe <[email protected]> wrote:
>> Hi Bin,
>>
>> Bin.Cheng <[email protected]> wrote:
>>
>>> On Mon, Jan 20, 2020 at 5:28 PM Jakub Jelinek <[email protected]> wrote:
>>>> On Mon, Jan 20, 2020 at 08:59:20AM +0000, Iain Sandoe wrote:
>>>>> Hi Bin,
>>>>>
>>>>> bin.cheng <[email protected]> wrote:
>>>>>
>>>>>> gcc/cp
>>>>>> 2020-01-20 Bin Cheng <[email protected]>
>>>>>>
>>>>>> * coroutines.cc (build_co_await): Skip getting complete type for
>>>>>> void.
>>>>>>
>>>>>> gcc/testsuite
>>>>>> 2020-01-20 Bin Cheng <[email protected]>
>>>>>>
>>>>>> * g++.dg/coroutines/co-await-void_type.C: New
>>>>>> test.<0001-Fix-ICE-when-co_awaiting-on-void-type.patch>
>>>>>
>>>>> This LGTM, (borderline obvious, in fact) but you will need to wait for
>>>>> a C++
>>>>> maintainer to approve,
>>>>
>>>> The patch actually looks wrong to me, there is nothing magic about void
>>>> type here, it will ICE on any other incomplete type, because
>>>> complete_type_or_else returns NULL if the type is incomplete.
>>>>
>>>> So, I think you want instead:
>>>> tree o_type = complete_type_or_else (TREE_TYPE (o), o);
>>>> + if (o_type == NULL_TREE)
>>>> + return error_mark_node;
>>>> if (TREE_CODE (o_type) != RECORD_TYPE)
>>>>
>>>> or similar (the diagnostics should be emitted already, so I don't see
>>>> further point to emit it once again).
>>>
>>> Thanks very much for pointing out. I was trying to bypass generic
>>> void error message to make it more related to coroutine, like:
>>> e1.cc: In function ‘resumable foo(int)’:
>>> e1.cc:45:3: error: awaitable type ‘void’ is not a structure
>>> 45 | co_yield n + x + y;
>>> | ^~~~~~~~
>>>
>>> vs.
>>>
>>> e1.cc: In function ‘resumable foo(int)’:
>>> e1.cc:45:20: error: invalid use of ‘void’
>>> 45 | co_yield n + x + y;
>>> | ^
>>>
>>> Anyway I will update the patch.
>>
>> ...I had already made a start...
> Thanks very much!
>
>> The patch below gives the improved diagnostic while checking for NULL
>> returns fom complete_type_or_else.
>>
>> OK?
>> Iain
>>
>>
>> gcc/cp
>>
>> 2020-01-20 Bin Cheng <[email protected]>
> You can remove me from the ChangeLog or keep it as "bin.cheng" :-)
ack.
>> Iain Sandoe <[email protected]>
>>
>> * coroutines.cc (coro_promise_type_found_p): Check for NULL return
>> from
>> complete_type_or_else.
>> (register_param_uses): Likewise.
>> (build_co_await): Do not try to use complete_type_or_else for void
>> types,
>> otherwise for incomplete types, check for NULL return from
>> complete_type_or_else.
>>
>> gcc/testsuite
>> 2020-01-20 Bin Cheng <[email protected]>
>>
>> * g++.dg/coroutines/co-await-void_type.C: New
>> test.<0001-Fix-ICE-when-co_awaiting-on-void-type.patch>
>>
>>
>> diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
>> index f0febfe0c8a..4e1ba81fb46 100644
>> --- a/gcc/cp/coroutines.cc
>> +++ b/gcc/cp/coroutines.cc
>> @@ -428,8 +428,9 @@ coro_promise_type_found_p (tree fndecl, location_t loc)
>>
>> /* Complete this, we're going to use it. */
>> coro_info->handle_type = complete_type_or_else (handle_type, fndecl);
>> +
>> /* Diagnostic would be emitted by complete_type_or_else. */
>> - if (coro_info->handle_type == error_mark_node)
>> + if (!coro_info->handle_type)
>> return false;
>>
>> /* Build a proxy for a handle to "self" as the param to
>> @@ -651,8 +652,11 @@ build_co_await (location_t loc, tree a,
>> suspend_point_kind suspend_kind)
>> o = a; /* This is most likely about to fail anyway. */
>>
>> tree o_type = TREE_TYPE (o);
>> - if (!VOID_TYPE_P (o_type))
>> - o_type = complete_type_or_else (TREE_TYPE (o), o);
>> + if (o_type && !VOID_TYPE_P (o_type) && !COMPLETE_TYPE_P (o_type))
> IIUC, Jakub doesn't like checking void type specially here?
that is necessary if we want the coro-specific diagnostic (which is more
meaningful
than the vanilla void one, however, if there’s opposition to that, I don’t have
such a
strong opinion.
Iain
>> + o_type = complete_type_or_else (o_type, o);
>> +
>> + if (!o_type)
>> + return error_mark_node;
>>
>> if (TREE_CODE (o_type) != RECORD_TYPE)
>> {
>> @@ -2746,6 +2750,10 @@ register_param_uses (tree *stmt, int *do_subtree
>> ATTRIBUTE_UNUSED, void *d)
>> if (!COMPLETE_TYPE_P (actual_type))
>> actual_type = complete_type_or_else (actual_type, *stmt);
>>
>> + if (actual_type == NULL_TREE)
>> + /* Diagnostic emitted by complete_type_or_else. */
>> + actual_type = error_mark_node;
>> +
>> if (TREE_CODE (actual_type) == REFERENCE_TYPE)
>> actual_type = build_pointer_type (TREE_TYPE (actual_type));
>
> Thanks,
> bin