]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++/coro: ignore cleanup_point_exprs while expanding awaits [PR116793]
authorArsen Arsenović <arsen@aarsen.me>
Tue, 24 Sep 2024 16:16:01 +0000 (18:16 +0200)
committerArsen Arsenović <arsen@gcc.gnu.org>
Fri, 27 Sep 2024 11:37:38 +0000 (13:37 +0200)
commitd888a8a8dcf391197ae82e2bbf99507effc27950
tree615de535d4f71f9d93f7cfb46419bbe3c512874a
parentde03ef6337b0a368d61c74b790313b4216c7ed6e
c++/coro: ignore cleanup_point_exprs while expanding awaits [PR116793]

If we reach a CLEANUP_POINT_EXPR while trying to walk statements, we
actually care about the statement or statement list contained within it.

Indeed, such a construction started happening with
r15-3513-g964577c31df206, after temporary promotion.  In the test case
presented in PR116793, the compiler generated:

  <<cleanup_point {
    struct _cleanup_task Aw0 [value-expr: frame_ptr->Aw0_2_3];
    int T002 [value-expr: frame_ptr->T002_2_3];

      int T002 [value-expr: frame_ptr->T002_2_3];
    <<cleanup_point <<< Unknown tree: expr_stmt
      (void) (T002 = TARGET_EXPR <D.20994, 3>) >>>>>;
      struct _cleanup_task Aw0 [value-expr: frame_ptr->Aw0_2_3];
    <<cleanup_point <<< Unknown tree: expr_stmt
      (void) (Aw0 = TARGET_EXPR <D.20995, func ((int &) &T002)>) >>>>>;
    <<cleanup_point <<< Unknown tree: expr_stmt
      (void) (D.22450 = <<< Unknown tree: co_await
        TARGET_EXPR <D.20995, func ((int &) &T002)>
        Aw0

        {_cleanup_task::await_ready (&Aw0), _cleanup_task::await_suspend<_task1::promise_type> (&Aw0, TARGET_EXPR <D.21078, _Coro_self_handle>), <<< Unknown tree: aggr_init_expr
          4
          await_resume
          D.22443
          &Aw0 >>>}
        0 >>>) >>>>>;
    <<cleanup_point <<< Unknown tree: expr_stmt
      (void) (D.20991 = (struct tuple &) &D.22450) >>>>>;
  }
  D.22467 = 1;
  int & i [value-expr: frame_ptr->i_1_2];
  <<cleanup_point <<< Unknown tree: expr_stmt
    (void) (i = std::get<0, int&> (NON_LVALUE_EXPR <D.20991>)) >>>>>;>>;

... i.e. a statement list within a cleanup point.  In such a case, we
don't actually care about the cleanup point, but we do care about the
statement inside, so, we can just walk down into the CLEANUP_POINT_EXPR.

PR c++/116793

gcc/cp/ChangeLog:

* coroutines.cc (await_statement_expander): Just process
subtrees if encountering a CLEANUP_POINT_EXPR.

gcc/testsuite/ChangeLog:

* g++.dg/coroutines/pr116793-1.C: New test.
gcc/cp/coroutines.cc
gcc/testsuite/g++.dg/coroutines/pr116793-1.C [new file with mode: 0644]