[pushed] coroutines: Handle namespaces while scanning local vars [PR95711].

Iain Sandoe iain@sandoe.co.uk
Sun Jun 28 12:55:42 GMT 2020


Hi,

We need to skip past namespace decls when scanning the bind
expression var lists checking for local vars.

The PR notes that this omission results in an ice-on-valid.

tested on x86_64-linux, darwin, powerpc64-linux,

applied to master as obvious (and will backport to 10.2).

thanks
Iain

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.
---
 gcc/cp/coroutines.cc                      |  3 +-
 gcc/testsuite/g++.dg/coroutines/pr95711.C | 79 +++++++++++++++++++++++
 2 files changed, 81 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/coroutines/pr95711.C

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index bab03d44863..54f9cb3b4e4 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3563,7 +3563,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;
+}
-- 
2.24.1



More information about the Gcc-patches mailing list