From: Iain Sandoe Date: Sun, 28 Jun 2020 11:29:11 +0000 (+0100) Subject: coroutines: Handle namespaces while scanning local vars [PR95711]. X-Git-Tag: basepoints/gcc-12~6563 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=06ed4aae1c2fa84b7050a286d866db4a6def3c36;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index bab03d448637..54f9cb3b4e45 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 000000000000..f6aedb16ebd7 --- /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; +}