diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2020-06-28 12:29:11 +0100 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2020-06-28 13:52:25 +0100 |
commit | 06ed4aae1c2fa84b7050a286d866db4a6def3c36 (patch) | |
tree | b0bd54a66653be4d04b3733d3d2060395930f197 /gcc | |
parent | f3a8f66a83f8c94f6fbb0233cefba8032f2e4876 (diff) | |
download | gcc-06ed4aae1c2fa84b7050a286d866db4a6def3c36.zip gcc-06ed4aae1c2fa84b7050a286d866db4a6def3c36.tar.gz gcc-06ed4aae1c2fa84b7050a286d866db4a6def3c36.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/coroutines.cc | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/coroutines/pr95711.C | 79 |
2 files changed, 81 insertions, 1 deletions
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index bab03d4..54f9cb3 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 0000000..f6aedb1 --- /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; +} |