[gcc(refs/vendors/ARM/heads/arm-struct-reorg-wip)] coroutines: Fix cases where proxy variables are used [PR94879]

Tamar Christina tnfchris@gcc.gnu.org
Fri Jul 17 14:54:49 GMT 2020


https://gcc.gnu.org/g:b16fd5fd8afe6f95c8ae44e759971e605c31f97b

commit b16fd5fd8afe6f95c8ae44e759971e605c31f97b
Author: Iain Sandoe <iain@sandoe.co.uk>
Date:   Mon Apr 27 15:21:25 2020 +0100

    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.

Diff:
---
 gcc/cp/ChangeLog                                  |  8 ++++
 gcc/cp/coroutines.cc                              |  9 +++--
 gcc/testsuite/ChangeLog                           |  5 +++
 gcc/testsuite/g++.dg/coroutines/pr94879-folly-1.C | 49 +++++++++++++++++++++++
 4 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cbedbabe3a6..3172f949ee9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 7bb3e98fe6c..e2dbeabf48b 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -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
     {
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 49f00426e06..7f39eda0277 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/coroutines/pr94879-folly-1.C b/gcc/testsuite/g++.dg/coroutines/pr94879-folly-1.C
new file mode 100644
index 00000000000..7d66ce004f7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr94879-folly-1.C
@@ -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); };
+}


More information about the Gcc-cvs mailing list