tree fn_name = get_fn_local_identifier (orig, name);
tree fn = build_lang_decl (FUNCTION_DECL, fn_name, fn_type);
DECL_CONTEXT (fn) = DECL_CONTEXT (orig);
+ DECL_ARTIFICIAL (fn) = true;
DECL_INITIAL (fn) = error_mark_node;
tree id = get_identifier ("frame_ptr");
tree fp = build_lang_decl (PARM_DECL, id, coro_frame_ptr);
DECL_CONTEXT (fp) = fn;
DECL_ARG_TYPE (fp) = type_passed_as (coro_frame_ptr);
DECL_ARGUMENTS (fn) = fp;
+ /* Copy selected attributes from the original function. */
+ TREE_USED (fn) = TREE_USED (orig);
+ if (DECL_SECTION_NAME (orig))
+ set_decl_section_name (fn, DECL_SECTION_NAME (orig));
+ /* Copy any alignment that the FE added. */
+ if (DECL_ALIGN (orig))
+ SET_DECL_ALIGN (fn, DECL_ALIGN (orig));
+ /* Copy any alignment the user added. */
+ DECL_USER_ALIGN (fn) = DECL_USER_ALIGN (orig);
+ /* Apply attributes from the original fn. */
+ DECL_ATTRIBUTES (fn) = copy_list (DECL_ATTRIBUTES (orig));
return fn;
}
--- /dev/null
+// { dg-additional-options "-O -Wunused-function" }
+
+#if __has_include (<coroutine>)
+#include <coroutine>
+using namespace std;
+#elif defined (__clang__) && __has_include (<experimental/coroutine>)
+#include <experimental/coroutine>
+namespace std { using namespace experimental; }
+#endif
+
+struct dummy
+{
+ struct promise_type
+ {
+ dummy get_return_object() const noexcept { return {}; }
+ std::suspend_never initial_suspend() const noexcept { return {}; }
+ std::suspend_never final_suspend() const noexcept { return {}; }
+ void return_void() const noexcept {}
+ void unhandled_exception() const noexcept {}
+ };
+};
+
+// This checks that the attribute is passed on to the outlined coroutine
+// functions (so that there should be no diagnostic).
+[[maybe_unused]] static dummy foo()
+{
+ co_return;
+}
--- /dev/null
+// { dg-additional-options "-Wall -O" }
+
+// This should complete without any diagnostic.
+
+#include <coroutine>
+#include <exception>
+
+template <typename T>
+class lazy {
+ T _v = 0;
+public:
+ lazy() {}
+ bool await_ready() {return true;}
+ void await_suspend(auto x) noexcept {}
+ T await_resume() { return _v; }
+};
+
+namespace std {
+
+template <typename T, typename... Args>
+struct coroutine_traits<lazy<T>, Args...> {
+ struct promise_type {
+ suspend_always initial_suspend() const { return {}; }
+ suspend_always final_suspend() const { return {}; }
+ void return_value(T val) {}
+ lazy<T> get_return_object() {
+ return lazy<T>();
+ }
+ void unhandled_exception() {
+ std::terminate();
+ }
+ };
+};
+}
+
+struct xxx {
+ static lazy<int> func() {
+ co_return 1;
+ }
+};
+
+#if 0
+lazy<int> foo() {
+ co_return co_await xxx::func();
+}
+#endif