<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/65030>65030</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[bug] clang (incorrectly?) optimizes away an entire simple coroutine
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
jacobsa
</td>
</tr>
</table>
<pre>
In #65018 I made a report about clang introducing a data race in the following program with `-O1`, by writing to the coroutine frame after suspending:
```c++
#include <coroutine>
// A simple awaiter type with an await_suspend method that can't be
// inlined.
struct Awaiter {
const int& x;
bool await_ready() { return false; }
std::coroutine_handle<> await_suspend(const std::coroutine_handle<> h);
void await_resume() {}
};
struct MyTask {
// A lazy promise with an await_transform method that supports awaiting
// integer references using the Awaiter struct above.
struct promise_type {
MyTask get_return_object() { return {}; }
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception();
auto await_transform(const int& x) { return Awaiter{x}; }
};
};
// A global array of integers.
int g_array[32];
// A coroutine that awaits each integer in the global array.
MyTask FooBar() {
for (const int& x : g_array) {
co_await x;
}
}
```
I found that if you compile it with `-O2` instead at `a738bdf35e` ([Compiler explorer](https://godbolt.org/z/PMxM385j4)), clang completely eliminates the application logic and just returns a pointer to an uninitialized object:
```asm
FooBar(): # @FooBar()
mov edi, 56
jmp operator new(unsigned long)@PLT # TAILCALL
g_array:
.zero 128
```
**I don't think this optimization is correct.** It seems like clang is asserting there is undefined behavior in the original code, but if there is I can't find it. It should be initializing the `resume` and `destroy` function pointers in the coroutine frame, then faithfully calling `Awaiter::await_suspend` for each element in the array. That function may have arbitrary behavior, including side effects that consume the integer in the array.
This may or may not have the same cause as #65018, where clang introduces a data race into this coroutine. Perhaps the data race that clang introduces allows it to convince itself there there is UB?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVlFvozgQ_jXOy2gjahKSPOQhaTdSpa5uH3rP0QADuGtsZJu29NefBggNjXbvpKtQqIw9881834wHvVelIdqL9VGsHxbYhsq6_QtmNvW4SG3e7R8NCBkn6-huC49QY06A4KixLgCmtg2QaTQlKBOczdtMmRIQcgwIDjMCZSBUBIXV2r7xx8bZ0mENbypUIJLo2193IomEvIe0gzenAm8Ktj-VWWfboAxB4bAmwCKQA9_6hkyuTCnig4geRHT5TaLhyYQ88jOsyliZTLc5gYjvJ5Mi_j47K09CnuAAXtWNJsA3VOwsdA0NWNEMi-fRP9QUKptDqDBAhkbITYCUZuaU0cpQvhwWfXBtFuAwmhabESFAZo0PnEMhE3gX8fEaGkBqrR6dO8K8E3Ir5I4NgKPQOgMFak8iPoLYPFxO-ZBzguLDFPO5QpNrEvG9iL_PoxFyO4D4t1OVkLsJIMCrVfkEzbc1fWKboPA_85DGTPzontH_uk7ERIPGj461Uiv_Nf_BofGFdfWMAd82LEo_bGJxzE0qE6gkB44KcmQy8tD6XmsVTZSMuDC1r7T8zGO_OII594r4hDzGUBIngLk42_SFsnDL0ZiSOUlXNI1MnFG_YedBGRUU6iuC_p-9Qpkba8bSe0ZN-A9me6JbM2ghPw_nlDWDpRvJAmAb7FfGJpVNUp-HNPIgNsf3WwwzGd1IalJOqW2KGtA57MAWF-L9yKcyAcpz_1Wsj7EU699a-mw_vcL6WDwQZtWkprG9Xfsc_Yy6OFl7RHdVFGMwhXVwkw0Q8WECN9_PPeLcI7jqDwCzGps3weuQHqGwrRkrRRXQ2RYyWzdKE6hw1YulSCJQxgfCHDDwIm7ibZoX8Zr4G0eyPt4PZx3Qe6OtI8dZlNsqhMaz-PoMljZPrQ5L60ohTx9Cnn7-eP8Rb9cvK1YMP_fj7cFYNAXSHZBWtTIYyPeZxabRKkNWGmhbqgzQ5PDS-jBqxgNCY5kPx9cGGmjNWDrqg3IYq_E3NwX6eli55olZ-NOfkDGIVTQ7MtHEf7V97d-UK45xncw_v9RN_7YNOQzWgaE3Ibet6a_jHLQ1JdtcRT-fnv-A4fnw-HR_eHoarF90Ex_m3pYf5Czcye0f9CEkP4-Q2-EaC5Uyv_jXg22CqtXHwIDyXBSOsrAcjsBjAE9Ue9DqF11mAQ_oPbkwtldHvNSanAq-DSGlCl-VnarHOlVyc4LM5tRPAm2v0uno43S_FsrkoMKy91vZVrM1mPi-9HORRONtlES9YEQS5eSDsx2vFK3J-nhG4fgLki8DB2MJFfH1qkJVtFp3kKHW7EYk0aVb9d12fpuyE-uGXkGaajLh4mNoEvDMpTgBqbGDCl_5a6qCQ9dNWWIQwwDDbr3KCagoKAt-HD2s4Uh721_a0nU_Gn6fmVJ2Zl3_MjYMfnm75xkrw9YToJ_GPvb_1jMxn_TIfxn0-qFtUMiQxCX8JFdhM1Ty59YB9o0xnhA9t6NgOahXZdhs8KQvUpgE8fdRxKdFvo_zXbzDBe3vkl18t7uTq3hR7VeJpGKz28iiiO8ow2idyW26SqL1LtsWRbxQexnJONrKbSTXqyhe5jLGJNlttqtoF28wF6uIalR6qfVrzQ1sobxvaZ-sozhaaExJ-8vU7Pa86Vvall6sIq188J_Hggq6n6_TthTrhzFqIbfKjIWkOxGfuNmPhUb9BNNxIyMTlKPLRDqlddE6vf_SalWo2nSZ2VrIEzsfX98aZ4dh5NQH4IU89TH8EwAA__9vrMDs">