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.
This commit is contained in:
parent
f3a8f66a83
commit
06ed4aae1c
@ -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;
|
local_var.field_idx = local_var.field_id = NULL_TREE;
|
||||||
|
|
||||||
/* Make sure that we only present vars to the tests below. */
|
/* 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;
|
continue;
|
||||||
|
|
||||||
/* We don't move static vars into the frame. */
|
/* We don't move static vars into the frame. */
|
||||||
|
79
gcc/testsuite/g++.dg/coroutines/pr95711.C
Normal file
79
gcc/testsuite/g++.dg/coroutines/pr95711.C
Normal file
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user