Bin.Cheng <amker.ch...@gmail.com> wrote:

> On Mon, Jan 20, 2020 at 6:31 PM Iain Sandoe <i...@sandoe.co.uk> wrote:
>> Hi Bin,
>> 
>> Bin.Cheng <amker.ch...@gmail.com> wrote:
>> 
>>> On Mon, Jan 20, 2020 at 5:28 PM Jakub Jelinek <ja...@redhat.com> wrote:
>>>> On Mon, Jan 20, 2020 at 08:59:20AM +0000, Iain Sandoe wrote:
>>>>> Hi Bin,
>>>>> 
>>>>> bin.cheng <bin.ch...@linux.alibaba.com> wrote:
>>>>> 
>>>>>> gcc/cp
>>>>>> 2020-01-20  Bin Cheng  <bin.li...@linux.alibaba.com>
>>>>>> 
>>>>>>      * coroutines.cc (build_co_await): Skip getting complete type for 
>>>>>> void.
>>>>>> 
>>>>>> gcc/testsuite
>>>>>> 2020-01-20  Bin Cheng  <bin.li...@linux.alibaba.com>
>>>>>> 
>>>>>>      * 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  <bin.li...@linux.alibaba.com>
> You can remove me from the ChangeLog or keep it as "bin.cheng"  :-)
ack.
>>          Iain Sandoe  <i...@sandoe.co.uk>
>> 
>>        * 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  <bin.li...@linux.alibaba.com>
>> 
>>       * 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


Reply via email to