https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118574
--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
In the rhbz bug Alessandro Astone came up with:
#include <iostream>
#include <string>
#include <vector>
#include <chrono>
#include <thread>
#include <coroutine>
using namespace std::chrono_literals;
struct TimerAwaiter {
std::chrono::milliseconds duration;
bool await_ready() const noexcept { return false; }
void await_suspend(std::coroutine_handle<> h) const noexcept {
std::this_thread::sleep_for(duration);
h.resume();
}
void await_resume() const noexcept {}
};
struct Task {
struct promise_type {
std::string value;
std::suspend_never initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_value(std::string v) { value = std::move(v); }
void unhandled_exception() { std::terminate(); }
Task get_return_object() { return Task{this}; }
};
promise_type *p;
explicit Task(promise_type *p) : p(p) {}
std::string get() { return p->value; }
};
std::vector<std::string> getStringList() {
std::vector<std::string> a;
a.push_back("foo");
a.push_back("bar");
return a;
}
Task processStringList() {
std::vector<std::string> ret;
for (const auto &item : getStringList()) {
co_await TimerAwaiter{200ms};
ret.push_back(item);
}
co_return "foobar";
}
int main() {
auto task = processStringList();
std::cout << task.get() << std::endl;
return 0;
}
$ ./g++ -std=gnu++20 -O2 -g -o /tmp/coro{,.C} -fno-range-for-ext-temps;
LD_LIBRARY_PATH=../lib64 /tmp/coro
foobar
$ ./g++ -std=gnu++20 -O2 -g -o /tmp/coro{,.C} -frange-for-ext-temps;
LD_LIBRARY_PATH=../lib64 /tmp/coro
Segmentation fault (core dumped)