Skip to content
Snippets Groups Projects
Unverified Commit 858918ef authored by Arsen Arsenović's avatar Arsen Arsenović Committed by Arsen Arsenović
Browse files

c++: add a testcase for [PR 108620]

Fixed by r15-2540-g32e678b2ed7521.  Add a testcase, as the original ones
do not cover this particular failure mode.

gcc/testsuite/ChangeLog:

	PR c++/108620
	* g++.dg/coroutines/pr108620.C: New test.
parent 7b7ad3f4
No related branches found
No related tags found
No related merge requests found
// https://gcc.gnu.org/PR108620
#include <iostream>
#include <memory>
#include <coroutine>
template<class PrivateDataType>
struct task;
template <class PrivateDataType>
struct task_private_data {
inline task_private_data() noexcept : data_(nullptr) {}
inline task_private_data(PrivateDataType* input) noexcept : data_(input) {}
inline task_private_data(task_private_data&& other) noexcept = default;
inline task_private_data& operator=(task_private_data&&) noexcept = default;
inline task_private_data(const task_private_data&) = delete;
inline task_private_data& operator=(const task_private_data&) = delete;
inline ~task_private_data() {}
inline bool await_ready() const noexcept { return true; }
inline PrivateDataType* await_resume() const noexcept { return data_; }
inline void await_suspend(std::coroutine_handle<>) noexcept {}
PrivateDataType* data_;
};
template<class PrivateDataType>
struct task_context {
PrivateDataType data_;
};
template<class PrivateDataType>
struct task {
using self_type = task<PrivateDataType>;
std::shared_ptr<task_context<PrivateDataType>> context_;
task(const std::shared_ptr<task_context<PrivateDataType>>& input): context_(input) {}
static auto yield_private_data() noexcept { return task_private_data<PrivateDataType>{}; }
struct promise_type {
std::shared_ptr<task_context<PrivateDataType>> context_;
template<class Input, class... Rest>
promise_type(Input&& input, Rest&&...) {
context_ = std::make_shared<task_context<PrivateDataType>>();
context_->data_ = std::forward<Input>(input);
}
auto get_return_object() noexcept { return self_type{context_}; }
std::suspend_never initial_suspend() noexcept { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void unhandled_exception() { throw; }
template<class ReturnType>
void return_value(ReturnType&&) {}
template <class InputPrivateDataType>
inline task_private_data<InputPrivateDataType> yield_value(
task_private_data<InputPrivateDataType>&& input) noexcept {
input.data_ = &context_->data_;
return task_private_data<InputPrivateDataType>(input.data_);
}
};
};
template<class TArg, class OutputType>
task<std::string> call1(TArg&& arg, OutputType& output) {
OutputType* ptr = co_yield task<TArg>::yield_private_data();
output = *ptr;
co_return 0;
}
struct container {
std::string* ptr;
};
template<class TArg>
task<std::string> call2(TArg&& arg, container& output) {
output.ptr = co_yield task<TArg>::yield_private_data();
co_return 0;
}
int main() {
// success
std::string output1;
call1(std::string("hello1"), output1);
std::cout<< "output1: "<< output1<< std::endl;
// crash
container output2;
auto task2 = call2(std::string("hello2"), output2);
std::cout<< "output2: "<< *output2.ptr<< std::endl;
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment