[gcc r10-8395] coroutines: Handle namespaces while scanning local vars [PR95711].

Iain D Sandoe iains@gcc.gnu.org
Tue Jun 30 12:46:32 GMT 2020


https://gcc.gnu.org/g:65025a6dae4b2c62ca79d2d0687229dafa93af7f

commit r10-8395-g65025a6dae4b2c62ca79d2d0687229dafa93af7f
Author: Iain Sandoe <iain@sandoe.co.uk>
Date:   Tue Jun 30 08:29:11 2020 +0100

    coroutines: Handle namespaces while scanning local vars [PR95711].
    
    We need to skip past namespace decls when scanning the bind
    expression var lists checking for local vars.
    
    gcc/cp/ChangeLog:
    
            PR c++/95711
            * coroutines.cc (register_local_var_uses): Skip past
            namespace decls.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/95711
            * g++.dg/coroutines/pr95711.C: New test.
    
    (cherry picked from commit 06ed4aae1c2fa84b7050a286d866db4a6def3c36)

Diff:
---
 gcc/cp/coroutines.cc                      |  3 +-
 gcc/testsuite/g++.dg/coroutines/pr95711.C | 79 +++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 75efd503392..9ab0a7ea10f 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3564,7 +3564,8 @@ register_local_var_uses (tree *stmt, int *do_subtree, void *d)
 	  local_var.field_idx = local_var.field_id = NULL_TREE;
 
 	  /* Make sure that we only present vars to the tests below.  */
-	  if (TREE_CODE (lvar) == TYPE_DECL)
+	  if (TREE_CODE (lvar) == TYPE_DECL
+	      || TREE_CODE (lvar) == NAMESPACE_DECL)
 	    continue;
 
 	  /* We don't move static vars into the frame. */
diff --git a/gcc/testsuite/g++.dg/coroutines/pr95711.C b/gcc/testsuite/g++.dg/coroutines/pr95711.C
new file mode 100644
index 00000000000..f6aedb16ebd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr95711.C
@@ -0,0 +1,79 @@
+//  { dg-do run }
+
+#if __has_include(<coroutine>)
+#include <coroutine>
+#else
+#include <experimental/coroutine>
+namespace std {
+    using namespace std::experimental;
+}
+#endif
+#include <cstdlib>
+
+template <typename T>
+struct generator{
+    struct promise_type;
+    using coro_handle = std::coroutine_handle<promise_type>;
+
+    struct promise_type{
+        std::suspend_always yield_value (T value){
+            value_ = value;
+            return {};
+        }
+        std::suspend_always initial_suspend (){
+            return {};
+        }
+        std::suspend_always final_suspend (){
+            return {};
+        }
+
+        std::suspend_never return_void()
+        {
+            return {};
+        }
+        generator get_return_object () {
+            return {coro_handle::from_promise(*this)};
+        }
+        void unhandled_exception () {
+            return;
+        }
+        T value_;
+    };
+    coro_handle handle;
+    generator(coro_handle h)
+        :handle(h)
+    {}
+    ~generator(){
+        if(handle)
+            handle.destroy();
+    }
+
+    bool resume(){
+        if(not handle.done())
+            handle.resume();
+        return not handle.done();
+    };
+
+    T get () {
+        return handle.promise().value_;
+    }
+};
+namespace A
+{
+}
+
+generator<int>
+parse()
+{
+    namespace B = A;
+    co_yield 1;
+}
+
+int main()
+{
+    auto gen = parse();
+    gen.handle.resume (); /* init suspend. */
+    if (gen.get() != 1)
+      abort ();
+  return 0;
+}


More information about the Gcc-cvs mailing list