Hi We had omitted the copying of function attributes (including the 'used' status). Mark the outlined functions as artificial, since they are; some diagnostic processing tests this.
tested on Linux and Darwin, OK for master? 10.2? thanks Iain gcc/cp/ChangeLog: PR c++/95518 * coroutines.cc (act_des_fn): Copy function attributes from the user’s function decl onto the outlined helpers. gcc/testsuite/ChangeLog: PR c++/95518 * g++.dg/coroutines/pr95518.C: New test. --- gcc/cp/coroutines.cc | 5 +++++ gcc/testsuite/g++.dg/coroutines/pr95518.C | 27 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 gcc/testsuite/g++.dg/coroutines/pr95518.C diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 93f1e5ca30d..4f7356e94e5 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -3530,12 +3530,17 @@ act_des_fn (tree orig, tree fn_type, tree coro_frame_ptr, const char* name) 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 used-ness from the original function. */ + TREE_USED (fn) = TREE_USED (orig); + /* Apply attributes from the original fn. */ + DECL_ATTRIBUTES (fn) = copy_list (DECL_ATTRIBUTES (orig)); return fn; } diff --git a/gcc/testsuite/g++.dg/coroutines/pr95518.C b/gcc/testsuite/g++.dg/coroutines/pr95518.C new file mode 100644 index 00000000000..2d7dd049e1b --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr95518.C @@ -0,0 +1,27 @@ +// { 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 {} + }; + int i; // work around #95516 +}; + +[[maybe_unused]] static dummy foo() +{ + co_return; +} -- 2.24.1