<div class="__aliyun_email_body_block"><div  style="clear:both;"><span  style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">Hi Adrian,</span></div><div  style="clear:both;"><span  style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;"><br ></span></div><div  style="clear:both;"><span  style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">Sorry for disturbing. When I am trying to look into this, I find that this bug is fixed in llvm trunk. (https://godbolt.org/z/ehTa78).</span></div><div  style="clear:both;"><br ></div><blockquote  style="margin-right:0;margin-top:0;margin-bottom:0;"><div  style="clear:both;"><span  style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">------------------------------------------------------------------</span></div><div  style="clear:both;"><span  style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">From:chuanqi.xcq via cfe-dev <cfe-dev@lists.llvm.org></span></div><div  style="clear:both;"><span  style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">Send Time:2021年2月8日(星期一) 16:27</span></div><div  style="clear:both;"><span  style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">To:cfe-dev@lists.llvm.org <cfe-dev@lists.llvm.org>; Adrian Vogelsgesang <avogelsgesang@tableau.com></span></div><div  style="clear:both;"><span  style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">Subject:Re: [cfe-dev] Miscompilation: heap-use-after-free in C++ coroutines</span></div><div  style="clear:both;"><span  style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;"><br ></span></div><div  style="clear:both;"><span  class=" __aliyun_node_has_color" style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">Hi Adrian,</span></div><div  style="clear:both;"><span  class=" __aliyun_node_has_color" style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;"><br ></span></div><div  style="clear:both;">Oh yes, the corourtine should be considered as suspended in await_suspend from the wording. I'm trying to fix this.</div><div  style="clear:both;"><br ></div><div  style="clear:both;"><span  class=" __aliyun_node_has_color" style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">------------------------------------------------------------------</span></div><div  style="clear:both;"><span  class=" __aliyun_node_has_color" style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">From:Adrian Vogelsgesang <avogelsgesang@tableau.com></span></div><div  style="clear:both;"><span  class=" __aliyun_node_has_color" style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">Send Time:2021年2月6日(星期六) 04:33</span></div><div  style="clear:both;"><span  class=" __aliyun_node_has_color" style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">To:chuanqi.xcq <yedeng.yd@linux.alibaba.com>; cfe-dev@lists.llvm.org <cfe-dev@lists.llvm.org></span></div><div  style="clear:both;"><span  class=" __aliyun_node_has_color" style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;">Subject:Re: [cfe-dev] Miscompilation: heap-use-after-free in C++ coroutines</span></div><div  style="clear:both;"><span  class=" __aliyun_node_has_color" style="font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;"><br ></span></div><style >!--  @font-face{font-family:Helvetica;panose-1:0 0 0 0 0 0 0 0 0 0;}{font-family:MS Gothic;panose-1:2 11 6 9 7 2 5 8 2 4;}{font-family:Cambria Math;panose-1:2 4 5 3 5 4 6 3 2 4;}{font-family:Calibri;panose-1:2 15 5 2 2 2 4 3 2 4;}{font-family:Tahoma;panose-1:2 11 6 4 3 5 4 4 2 4;}{font-family:\@MS Gothic;panose-1:2 11 6 9 7 2 5 8 2 4;}p.MsoNormal, li.MsoNormal, div.MsoNormal{margin:.0cm;font-size:11.0pt;font-family:Calibri,sans-serif;mso-fareast-language:EN-US;}a:link, span.MsoHyperlink{mso-style-priority:99;color:#0563c1;text-decoration:underline;}span.EmailStyle20{mso-style-type:personal-reply;font-family:Calibri,sans-serif;color:windowtext;}.MsoChpDefault{mso-style-type:export-only;font-size:10.0pt;}@page WordSection1{size:612.0pt 792.0pt;margin:72.0pt 72.0pt 72.0pt 72.0pt;}div.WordSection1{page:WordSection1;}--></style><div  class="WordSection1"><p  class="MsoNormal">HI Chuanqi,<br ><br >
> I met this problem before. I agree that this behavior would make symmetric transfer much harder.<br ><br >
Thanks for taking a look at this - I really appreciate it!<br ><br >
> the coroutine **isn't suspended** in the await_suspend. So it is an undefined behavior if we call `coroutine_handle::destroy()` in await_suspend.</p><p  class="MsoNormal"><br >
I think section 7.6.2.4, subpoint 5.1 is the relevant part of the standard here:<br >
```<br >
The await-expression evaluates the (possibly-converted) o expression and the await-ready expression, then:</p><p  class="MsoNormal">(5.1) — If the result of await-ready is false, the coroutine is considered suspended. Then:</p><p  class="MsoNormal">(5.1.1) — If the type of await-suspend is std::coroutine_handle<Z>, await-suspend.resume() is evaluated.<br >
```<br ><br >
My understanding of this sections, if mapped to my example, is:<br >
`await_ready` was called and returned false -> the coroutine is suspended.<br >
Now, await_suspend gets called. The coroutine should still be suspended and it should be valid to destroy it.<br ><br >
Cheers,<br >
Adrian<br ><br ></p><p  class="MsoNormal"> </p><div  style="border-style:solid none none;border-top-width:1.0px;border-top-color:#b5c4df;padding:.0px .0cm .0cm;"><p  class="MsoNormal" style="margin-bottom:16.0px;"><b ><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:16.0px;color:black;">From:
</span></b><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:16.0px;color:black;">chuanqi.xcq <yedeng.yd@linux.alibaba.com><br ><b >Date: </b>Thursday, 4. February 2021 at 03:07<br ><b >To: </b>cfe-dev@lists.llvm.org <cfe-dev@lists.llvm.org>, Adrian Vogelsgesang <avogelsgesang@tableau.com><br ><b >Subject: </b>Re: [cfe-dev] Miscompilation: heap-use-after-free in C++ coroutines</span></p></div><div ><div ><p  class="MsoNormal"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">Hi Adrian,</span></p></div><div ><p  class="MsoNormal"> </p></div><div ><p  class="MsoNormal"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">I met this problem before. I agree that this behavior would make symmetric transfer much harder.</span></p></div><div ><p  class="MsoNormal"> </p></div><div ><p  class="MsoNormal"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">From my point of view, this is an undefined behavior. From
<a  href="http://17.12.4.6" target="_blank">
17.12.4.6</a> of N4878, we can find:</span></p></div><div ><p  class="MsoNormal">```</p></div><div ><p  style="margin:.0px;font-variant-caps:normal;font-stretch:normal;"><span  style="font-size:16.0px;font-family:Helvetica;">void destroy() const;</span></p><p  style="margin:.0px;font-variant-caps:normal;font-stretch:normal;"><span  style="font-size:16.0px;font-family:Helvetica;">4 Preconditions: *this refers to a suspended coroutine.</span></p><p  style="margin:.0px;font-variant-caps:normal;font-stretch:normal;"><span  style="font-size:16.0px;font-family:Helvetica;">5 Effects: Destroys the coroutine</span></p></div><div ><p  class="MsoNormal">```</p></div><div ><p  class="MsoNormal"> </p></div><div ><p  class="MsoNormal">To my mind, the coroutine **isn't suspended** in the await_suspend. So it is an undefined behavior if we call `coroutine_handle::destroy()` in await_suspend.</p></div><div ><p  class="MsoNormal"> </p></div><div ><p  class="MsoNormal">But I strongly agree with you it is really suffering that if we want symmetric transfer and we can't destroy the coroutine in final await_suspend directly.</p></div><div ><p  class="MsoNormal"> </p></div><div ><p  class="MsoNormal">I would look into the details and try to fix it.</p></div><div ><p  class="MsoNormal"> </p></div><div ><p  class="MsoNormal">Thanks,</p></div><div ><p  class="MsoNormal">Chuanqi</p></div><div ><p  class="MsoNormal"> </p></div><div ><p  class="MsoNormal"> </p></div><div ><p  class="MsoNormal"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">------------------------------------------------------------------</span></p></div><div ><p  class="MsoNormal"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">From:Adrian Vogelsgesang via cfe-dev <cfe-dev@lists.llvm.org></span></p></div><div ><p  class="MsoNormal"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">Send Time:2021</span><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:MS Gothic;color:black;">年</span><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">2</span><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:MS Gothic;color:black;">月</span><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">4</span><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:MS Gothic;color:black;">日</span><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">(</span><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:MS Gothic;color:black;">星期四</span><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">)
 04:21</span></p></div><div ><p  class="MsoNormal"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">To:cfe-dev@lists.llvm.org <cfe-dev@lists.llvm.org></span></p></div><div ><p  class="MsoNormal"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="font-size:14.0px;font-family:Tahoma,sans-serif;color:black;">Subject:[cfe-dev] Miscompilation: heap-use-after-free in C++ coroutines</span></p></div><div ><p  class="MsoNormal"> </p></div><p  class="MsoNormal"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="color:black;">Dear Clang community,<br ><br >
I think I stumbled across a front-end bug in clang’s coroutine implementation.<br ><br >
Having an awaitable with<br ><br >
```<br >
template<typename PROMISE> std::experimental::coroutine_handle<> await_suspend(std::experimental::coroutine_handle<PROMISE> coro) noexcept {</span></p><p  class="MsoNormal" style="caret-color:#000000;font-variant-caps:normal;orphans:auto;text-align:start;widows:auto;"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="color:black;">      coro.destroy();</span></p><p  class="MsoNormal" style="caret-color:#000000;font-variant-caps:normal;orphans:auto;text-align:start;widows:auto;"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="color:black;">     return std::experimental::noop_coroutine();</span></p><p  class="MsoNormal" style="caret-color:#000000;font-variant-caps:normal;orphans:auto;text-align:start;widows:auto;"><span  class=" __aliyun_node_has_color __aliyun_node_has_color" style="color:black;">}<br >
```<br ><br >
destroys the function’s own coroutine frame. This is valid, as long as no-one afterwards resumes the coroutine anymore. However, address-sanitizer reports a heap-use-after-free error (see
<a  href="https://godbolt.org/z/eq6eoc" target="_blank">
https://godbolt.org/z/eq6eoc</a> )<br ><br >
Afaict, this is because clang stores the return value of `await_suspend` in the coroutine frame. Instead, clang should probably store this return value on the stack. Storing on the stack should be valid, as it is guaranteed that this return value will never
 live across a suspension point.<br ><br >
You can find a minimal repro in <a  href="https://godbolt.org/z/eq6eoc" target="_blank">https://godbolt.org/z/eq6eoc</a> and a more complex end-to-end version in <a  href="https://godbolt.org/z/8Yadv1" target="_blank">https://godbolt.org/z/8Yadv1</a> .
 See <a  href="https://stackoverflow.com/questions/65991264/c-coroutines-is-it-valid-to-call-handle-destroy-from-the-final-suspend-poin" target="_blank">https://stackoverflow.com/questions/65991264/c-coroutines-is-it-valid-to-call-handle-destroy-from-the-final-suspend-poin</a> (in particular the
 comments to David Haim’s reply) for more context.<br ><br >
Cheers,<br >
Adrian</span></p><p  class="MsoNormal"> </p><div ><p  class="MsoNormal"> </p></div></div></div><div ><br ></div></blockquote><div ><br ></div></div>