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

commit r14-11717-gee0736f665971446f8665a94ef597f683f8128e9
Author: Arsen Arsenovic <ar...@aarsen.me>
Date:   Tue Jul 30 13:42:56 2024 +0200

    c++: fix ICE on FUNCTION_DECLs inside coroutines [PR115906]
    
    When register_local_var_uses iterates a BIND_EXPRs BIND_EXPR_VARS, it
    fails to account for the fact that FUNCTION_DECLs might be present, and
    later passes it to DECL_HAS_VALUE_EXPR_P.  This leads to a tree check
    failure in DECL_HAS_VALUE_EXPR_P:
    
      tree check: expected var_decl or parm_decl or result_decl, have
      function_decl in register_local_var_uses
    
    We only care about PARM_DECL and VAR_DECL, so select only those.
    
    PR c++/115906 - [coroutines] missing diagnostic and ICE when co_await used 
as default argument in function declaration
    
    gcc/cp/ChangeLog:
    
            PR c++/115906
            * coroutines.cc (register_local_var_uses): Only process
            PARM_DECL and VAR_DECLs.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/115906
            * g++.dg/coroutines/coro-function-decl.C: New test.
    
    (cherry picked from commit a362c9ca4ef6585e678f899705043a9aa10dd670)

Diff:
---
 gcc/cp/coroutines.cc                                 |  4 ++--
 gcc/testsuite/g++.dg/coroutines/coro-function-decl.C | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 200789e89102..5fe9ec422c34 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3914,8 +3914,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
-             || TREE_CODE (lvar) == NAMESPACE_DECL)
+         if (TREE_CODE (lvar) != PARM_DECL
+             && TREE_CODE (lvar) != VAR_DECL)
            continue;
 
          /* We don't move static vars into the frame. */
diff --git a/gcc/testsuite/g++.dg/coroutines/coro-function-decl.C 
b/gcc/testsuite/g++.dg/coroutines/coro-function-decl.C
new file mode 100644
index 000000000000..86140569a76e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/coro-function-decl.C
@@ -0,0 +1,19 @@
+#include <coroutine>
+
+struct task
+{
+  struct promise_type
+  {
+    std::suspend_always initial_suspend () { return {}; }
+    std::suspend_always final_suspend () noexcept { return {}; }
+    void unhandled_exception () {}
+    task get_return_object () noexcept { return {}; }
+    void return_void () {}
+  };
+};
+
+task foo ()
+{
+  void bar ();
+  co_return;
+}

Reply via email to