aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2020-06-28 12:29:11 +0100
committerIain Sandoe <iain@sandoe.co.uk>2020-06-28 13:52:25 +0100
commit06ed4aae1c2fa84b7050a286d866db4a6def3c36 (patch)
treeb0bd54a66653be4d04b3733d3d2060395930f197 /gcc
parentf3a8f66a83f8c94f6fbb0233cefba8032f2e4876 (diff)
downloadgcc-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.cc3
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr95711.C79
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;
+}