/* Flags to avoid repeated errors for per-function issues. */
bool coro_ret_type_error_emitted;
bool coro_promise_error_emitted;
+ bool coro_co_return_error_emitted;
};
struct coroutine_info_hasher : ggc_ptr_hash<coroutine_info>
return false;
}
+ /* Test for errors in the promise type that can be determined now. */
+ tree has_ret_void = lookup_member (coro_info->promise_type,
+ coro_return_void_identifier,
+ /*protect=*/1, /*want_type=*/0,
+ tf_none);
+ tree has_ret_val = lookup_member (coro_info->promise_type,
+ coro_return_value_identifier,
+ /*protect=*/1, /*want_type=*/0,
+ tf_none);
+ if (has_ret_void && has_ret_val)
+ {
+ location_t ploc = DECL_SOURCE_LOCATION (fndecl);
+ if (!coro_info->coro_co_return_error_emitted)
+ error_at (ploc, "the coroutine promise type %qT declares both"
+ " %<return_value%> and %<return_void%>",
+ coro_info->promise_type);
+ inform (DECL_SOURCE_LOCATION (BASELINK_FUNCTIONS (has_ret_void)),
+ "%<return_void%> declared here");
+ inform (DECL_SOURCE_LOCATION (BASELINK_FUNCTIONS (has_ret_val)),
+ "%<return_value%> declared here");
+ coro_info->coro_co_return_error_emitted = true;
+ return false;
+ }
+
/* Try to find the handle type for the promise. */
tree handle_type =
instantiate_coro_handle_for_promise_type (loc, coro_info->promise_type);
--- /dev/null
+#if __has_include(<coroutine>)
+#include <coroutine>
+#else
+#include <experimental/coroutine>
+namespace std { using namespace experimental; }
+#endif
+
+struct dummy_coroutine {};
+
+namespace std {
+
+template<>
+class coroutine_traits<::dummy_coroutine> {
+public:
+ struct promise_type {
+ void return_value(int x) { }
+ void return_void() {}
+ std::suspend_never initial_suspend() noexcept { return {}; }
+ std::suspend_never final_suspend() noexcept { return {}; }
+ dummy_coroutine get_return_object() { return {}; }
+ void unhandled_exception() {}
+ };
+};
+
+}
+
+dummy_coroutine
+foo() { // { dg-error {the coroutine promise type 'std::__n4861::coroutine_traits<dummy_coroutine>::promise_type' declares both 'return_value' and 'return_void'} }
+ co_return 17;
+}