From: Iain Sandoe Date: Tue, 30 Jun 2020 07:29:11 +0000 (+0100) Subject: coroutines: Handle namespaces while scanning local vars [PR95711]. X-Git-Tag: releases/gcc-10.2.0~119 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=65025a6dae4b2c62ca79d2d0687229dafa93af7f;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. (cherry picked from commit 06ed4aae1c2fa84b7050a286d866db4a6def3c36) --- diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 75efd503392c..9ab0a7ea10f1 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 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; +}