On 6/11/20 3:53 PM, Iain Sandoe wrote:
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.
Do we do the right thing for say attribute((section("bob"))? what if the user
tries attribute((alias("bob")), presumable we don't want both ramp and actor to
alias bob? I think this might be tricky.
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;
+}
--
Nathan Sidwell