coroutines: Fix cases where proxy variables are used [PR94879]
There are several places where the handling of a variable declaration depends on whether it corresponds to a compiler temporary, or to some other entity. We were testing that var decls were artificial in determining this. However, proxy vars are also artificial so that this is not sufficient. The solution is to exclude variables with a DECL_VALUE_EXPR as well, since the value variable will not be a temporary. gcc/cp/ChangeLog: 2020-04-30 Iain Sandoe <iain@sandoe.co.uk> PR c++/94879 * coroutines.cc (build_co_await): Account for variables with DECL_VALUE_EXPRs. (captures_temporary): Likewise. (register_awaits): Likewise. gcc/testsuite/ChangeLog: 2020-04-30 Iain Sandoe <iain@sandoe.co.uk> PR c++/94879 * g++.dg/coroutines/pr94879-folly-1.C: New test.
This commit is contained in:
parent
04e88369a7
commit
b16fd5fd8a
4 changed files with 68 additions and 3 deletions
|
@ -1,3 +1,11 @@
|
|||
2020-04-30 Iain Sandoe <iain@sandoe.co.uk>
|
||||
|
||||
PR c++/94879
|
||||
* coroutines.cc (build_co_await): Account for variables
|
||||
with DECL_VALUE_EXPRs.
|
||||
(captures_temporary): Likewise.
|
||||
(register_awaits): Likewise.
|
||||
|
||||
2020-04-29 Patrick Palka <ppalka@redhat.com>
|
||||
|
||||
PR c++/94830
|
||||
|
|
|
@ -748,7 +748,8 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind)
|
|||
if (INDIRECT_REF_P (e_proxy))
|
||||
e_proxy = TREE_OPERAND (e_proxy, 0);
|
||||
if (TREE_CODE (e_proxy) == PARM_DECL
|
||||
|| (TREE_CODE (e_proxy) == VAR_DECL && !DECL_ARTIFICIAL (e_proxy)))
|
||||
|| (VAR_P (e_proxy) && (!DECL_ARTIFICIAL (e_proxy)
|
||||
|| DECL_HAS_VALUE_EXPR_P (e_proxy))))
|
||||
e_proxy = o;
|
||||
else
|
||||
{
|
||||
|
@ -2659,7 +2660,8 @@ captures_temporary (tree *stmt, int *do_subtree, void *d)
|
|||
}
|
||||
|
||||
/* This isn't a temporary. */
|
||||
if ((TREE_CODE (parm) == VAR_DECL && !DECL_ARTIFICIAL (parm))
|
||||
if ((VAR_P (parm)
|
||||
&& (!DECL_ARTIFICIAL (parm) || DECL_HAS_VALUE_EXPR_P (parm)))
|
||||
|| TREE_CODE (parm) == PARM_DECL
|
||||
|| TREE_CODE (parm) == NON_LVALUE_EXPR)
|
||||
continue;
|
||||
|
@ -2742,7 +2744,8 @@ register_awaits (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
|
|||
if (INDIRECT_REF_P (aw))
|
||||
aw = TREE_OPERAND (aw, 0);
|
||||
if (TREE_CODE (aw) == PARM_DECL
|
||||
|| (TREE_CODE (aw) == VAR_DECL && !DECL_ARTIFICIAL (aw)))
|
||||
|| (VAR_P (aw) && (!DECL_ARTIFICIAL (aw)
|
||||
|| DECL_HAS_VALUE_EXPR_P (aw))))
|
||||
; /* Don't make an additional copy. */
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2020-04-30 Iain Sandoe <iain@sandoe.co.uk>
|
||||
|
||||
PR c++/94879
|
||||
* g++.dg/coroutines/pr94xxx-folly-1.C: New test.
|
||||
|
||||
2020-04-30 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/94775
|
||||
|
|
49
gcc/testsuite/g++.dg/coroutines/pr94879-folly-1.C
Normal file
49
gcc/testsuite/g++.dg/coroutines/pr94879-folly-1.C
Normal file
|
@ -0,0 +1,49 @@
|
|||
// { dg-additional-options "-fpreprocessed -w" }
|
||||
|
||||
namespace std {
|
||||
template <typename a> a b(a &&);
|
||||
template <typename c> struct d { c e; };
|
||||
template <typename f, typename> struct coroutine_traits : f {};
|
||||
template <typename = void> struct coroutine_handle;
|
||||
template <> struct coroutine_handle<> {};
|
||||
template <typename> struct coroutine_handle : coroutine_handle<> {};
|
||||
struct g {};
|
||||
} // namespace std
|
||||
|
||||
class h {};
|
||||
class i {
|
||||
i(i &&);
|
||||
};
|
||||
|
||||
namespace ac {
|
||||
template <typename> class ad {
|
||||
public:
|
||||
bool await_ready();
|
||||
void await_resume();
|
||||
void await_suspend(std::coroutine_handle<>);
|
||||
i ae;
|
||||
};
|
||||
} // namespace ac
|
||||
|
||||
template <typename ab> ac::ad<ab> operator co_await(ab);
|
||||
class j {
|
||||
class l {};
|
||||
|
||||
public:
|
||||
std::g initial_suspend();
|
||||
l final_suspend();
|
||||
};
|
||||
class m : public j {
|
||||
public:
|
||||
void get_return_object();
|
||||
void unhandled_exception();
|
||||
};
|
||||
class n {
|
||||
public:
|
||||
using promise_type = m;
|
||||
};
|
||||
std::d<h> k;
|
||||
void a() {
|
||||
auto am = k;
|
||||
[&]() -> n { co_await std::b(am.e); };
|
||||
}
|
Loading…
Add table
Reference in a new issue