From 06ed4aae1c2fa84b7050a286d866db4a6def3c36 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sun, 28 Jun 2020 12:29:11 +0100 Subject: [PATCH] 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. --- 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() +#include +#else +#include +namespace std { + using namespace std::experimental; +} +#endif +#include + +template +struct generator{ + struct promise_type; + using coro_handle = std::coroutine_handle; + + 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 +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.30.2