[gcc r10-8380] coroutines: Copy attributes to the outlined functions [PR95518, PR95813]

Iain D Sandoe iains@gcc.gnu.org
Sun Jun 28 08:59:26 GMT 2020


https://gcc.gnu.org/g:c3bf482a0e59b9da925b382387686656c3d8839f

commit r10-8380-gc3bf482a0e59b9da925b382387686656c3d8839f
Author: Iain Sandoe <iain@sandoe.co.uk>
Date:   Sun Jun 28 09:48:33 2020 +0100

    coroutines: Copy attributes to the outlined functions [PR95518,PR95813]
    
    We had omitted the copying of function attributes, we now copy
    the used, alignment, section values from the original decal and
    the complete set of function attributes.  It is likely that
    some function attributes don't really make sense for coroutines,
    but that can be disgnosed separately. Also mark the outlined
    functions as artificial, since they are; some diagnostic
    processing tests this.
    
    gcc/cp/ChangeLog:
    
            PR c++/95518
            PR c++/95813
            * coroutines.cc (act_des_fn): Copy function
            attributes onto the outlined coroutine helpers.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/95518
            PR c++/95813
            * g++.dg/coroutines/pr95518.C: New test.
            * g++.dg/coroutines/pr95813.C: New test.
    
    (cherry picked from commit 1e5da6a02fec8aa84bb00966282f420cb70fe4f0)

Diff:
---
 gcc/cp/coroutines.cc                      | 12 ++++++++
 gcc/testsuite/g++.dg/coroutines/pr95518.C | 28 +++++++++++++++++++
 gcc/testsuite/g++.dg/coroutines/pr95813.C | 46 +++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 702368c9247..736dfb60afb 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3530,12 +3530,24 @@ 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 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;
 }
 
diff --git a/gcc/testsuite/g++.dg/coroutines/pr95518.C b/gcc/testsuite/g++.dg/coroutines/pr95518.C
new file mode 100644
index 00000000000..b1717677810
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr95518.C
@@ -0,0 +1,28 @@
+// { 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;
+}
diff --git a/gcc/testsuite/g++.dg/coroutines/pr95813.C b/gcc/testsuite/g++.dg/coroutines/pr95813.C
new file mode 100644
index 00000000000..34ff5bb4a20
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr95813.C
@@ -0,0 +1,46 @@
+//  { dg-additional-options  "-Wall -O -fconcepts-ts" }
+
+// 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


More information about the Gcc-cvs mailing list