Home | History | Annotate | Line # | Download | only in cp
      1 /* coroutine-specific state, expansions and tests.
      2 
      3    Copyright (C) 2018-2024 Free Software Foundation, Inc.
      4 
      5  Contributed by Iain Sandoe <iain (at) sandoe.co.uk> under contract to Facebook.
      6 
      7 This file is part of GCC.
      8 
      9 GCC is free software; you can redistribute it and/or modify it under
     10 the terms of the GNU General Public License as published by the Free
     11 Software Foundation; either version 3, or (at your option) any later
     12 version.
     13 
     14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     17 for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with GCC; see the file COPYING3.  If not see
     21 <http://www.gnu.org/licenses/>.  */
     22 
     23 #include "config.h"
     24 #include "system.h"
     25 #include "coretypes.h"
     26 #include "target.h"
     27 #include "cp-tree.h"
     28 #include "stringpool.h"
     29 #include "stmt.h"
     30 #include "stor-layout.h"
     31 #include "tree-iterator.h"
     32 #include "tree.h"
     33 #include "gcc-rich-location.h"
     34 #include "hash-map.h"
     35 
     36 static bool coro_promise_type_found_p (tree, location_t);
     37 
     38 /* GCC C++ coroutines implementation.
     39 
     40   The user authors a function that becomes a coroutine (lazily) by
     41   making use of any of the co_await, co_yield or co_return keywords.
     42 
     43   Unlike a regular function, where the activation record is placed on the
     44   stack, and is destroyed on function exit, a coroutine has some state that
     45   persists between calls - the coroutine frame (analogous to a stack frame).
     46 
     47   We transform the user's function into three pieces:
     48   1. A so-called ramp function, that establishes the coroutine frame and
     49      begins execution of the coroutine.
     50   2. An actor function that contains the state machine corresponding to the
     51      user's suspend/resume structure.
     52   3. A stub function that calls the actor function in 'destroy' mode.
     53 
     54   The actor function is executed:
     55    * from "resume point 0" by the ramp.
     56    * from resume point N ( > 0 ) for handle.resume() calls.
     57    * from the destroy stub for destroy point N for handle.destroy() calls.
     58 
     59   The functions in this file carry out the necessary analysis of, and
     60   transforms to, the AST to perform this.
     61 
     62   The C++ coroutine design makes use of some helper functions that are
     63   authored in a so-called "promise" class provided by the user.
     64 
     65   At parse time (or post substitution) the type of the coroutine promise
     66   will be determined.  At that point, we can look up the required promise
     67   class methods and issue diagnostics if they are missing or incorrect.  To
     68   avoid repeating these actions at code-gen time, we make use of temporary
     69   'proxy' variables for the coroutine handle and the promise - which will
     70   eventually be instantiated in the coroutine frame.
     71 
     72   Each of the keywords will expand to a code sequence (although co_yield is
     73   just syntactic sugar for a co_await).
     74 
     75   We defer the analysis and transformation until template expansion is
     76   complete so that we have complete types at that time.  */
     77 
     78 
     79 /* The state that we collect during parsing (and template expansion) for
     80    a coroutine.  */
     81 
     82 struct GTY((for_user)) coroutine_info
     83 {
     84   tree function_decl; /* The original function decl.  */
     85   tree actor_decl;    /* The synthesized actor function.  */
     86   tree destroy_decl;  /* The synthesized destroy function.  */
     87   tree promise_type;  /* The cached promise type for this function.  */
     88   tree traits_type;   /* The cached traits type for this function.  */
     89   tree handle_type;   /* The cached coroutine handle for this function.  */
     90   tree self_h_proxy;  /* A handle instance that is used as the proxy for the
     91 			 one that will eventually be allocated in the coroutine
     92 			 frame.  */
     93   tree promise_proxy; /* Likewise, a proxy promise instance.  */
     94   tree from_address;  /* handle_type from_address function.  */
     95   tree return_void;   /* The expression for p.return_void() if it exists.  */
     96   location_t first_coro_keyword; /* The location of the keyword that made this
     97 				    function into a coroutine.  */
     98 
     99   /* Temporary variable number assigned by get_awaitable_var.  */
    100   int awaitable_number = 0;
    101 
    102   /* Flags to avoid repeated errors for per-function issues.  */
    103   bool coro_ret_type_error_emitted;
    104   bool coro_promise_error_emitted;
    105   bool coro_co_return_error_emitted;
    106 };
    107 
    108 struct coroutine_info_hasher : ggc_ptr_hash<coroutine_info>
    109 {
    110   typedef tree compare_type; /* We only compare the function decl.  */
    111   static inline hashval_t hash (coroutine_info *);
    112   static inline hashval_t hash (const compare_type &);
    113   static inline bool equal (coroutine_info *, coroutine_info *);
    114   static inline bool equal (coroutine_info *, const compare_type &);
    115 };
    116 
    117 /* This table holds all the collected coroutine state for coroutines in
    118    the current translation unit.  */
    119 
    120 static GTY (()) hash_table<coroutine_info_hasher> *coroutine_info_table;
    121 
    122 /* We will initialize state lazily.  */
    123 static bool coro_initialized = false;
    124 
    125 /* Return a hash value for the entry pointed to by INFO.
    126    The compare type is a tree, but the only trees we are going use are
    127    function decls.  We use the DECL_UID as the hash value since that is
    128    stable across PCH.  */
    129 
    130 hashval_t
    131 coroutine_info_hasher::hash (coroutine_info *info)
    132 {
    133   return DECL_UID (info->function_decl);
    134 }
    135 
    136 /* Return a hash value for the compare value COMP.  */
    137 
    138 hashval_t
    139 coroutine_info_hasher::hash (const compare_type& comp)
    140 {
    141   return DECL_UID (comp);
    142 }
    143 
    144 /* Return true if the entries pointed to by LHS and RHS are for the
    145    same coroutine.  */
    146 
    147 bool
    148 coroutine_info_hasher::equal (coroutine_info *lhs, coroutine_info *rhs)
    149 {
    150   return lhs->function_decl == rhs->function_decl;
    151 }
    152 
    153 bool
    154 coroutine_info_hasher::equal (coroutine_info *lhs, const compare_type& rhs)
    155 {
    156   return lhs->function_decl == rhs;
    157 }
    158 
    159 /* Get the existing coroutine_info for FN_DECL, or insert a new one if the
    160    entry does not yet exist.  */
    161 
    162 coroutine_info *
    163 get_or_insert_coroutine_info (tree fn_decl)
    164 {
    165   gcc_checking_assert (coroutine_info_table != NULL);
    166 
    167   coroutine_info **slot = coroutine_info_table->find_slot_with_hash
    168     (fn_decl, coroutine_info_hasher::hash (fn_decl), INSERT);
    169 
    170   if (*slot == NULL)
    171     {
    172       *slot = new (ggc_cleared_alloc<coroutine_info> ()) coroutine_info ();
    173       (*slot)->function_decl = fn_decl;
    174     }
    175 
    176   return *slot;
    177 }
    178 
    179 /* Get the existing coroutine_info for FN_DECL, fail if it doesn't exist.  */
    180 
    181 coroutine_info *
    182 get_coroutine_info (tree fn_decl)
    183 {
    184   if (coroutine_info_table == NULL)
    185     return NULL;
    186 
    187   coroutine_info **slot = coroutine_info_table->find_slot_with_hash
    188     (fn_decl, coroutine_info_hasher::hash (fn_decl), NO_INSERT);
    189   if (slot)
    190     return *slot;
    191   return NULL;
    192 }
    193 
    194 /* We will lazily create all the identifiers that are used by coroutines
    195    on the first attempt to lookup the traits.  */
    196 
    197 /* Identifiers that are used by all coroutines.  */
    198 
    199 static GTY(()) tree coro_traits_identifier;
    200 static GTY(()) tree coro_handle_identifier;
    201 static GTY(()) tree coro_promise_type_identifier;
    202 
    203 /* Required promise method name identifiers.  */
    204 
    205 static GTY(()) tree coro_await_transform_identifier;
    206 static GTY(()) tree coro_initial_suspend_identifier;
    207 static GTY(()) tree coro_final_suspend_identifier;
    208 static GTY(()) tree coro_return_void_identifier;
    209 static GTY(()) tree coro_return_value_identifier;
    210 static GTY(()) tree coro_yield_value_identifier;
    211 static GTY(()) tree coro_address_identifier;
    212 static GTY(()) tree coro_from_address_identifier;
    213 static GTY(()) tree coro_get_return_object_identifier;
    214 static GTY(()) tree coro_gro_on_allocation_fail_identifier;
    215 static GTY(()) tree coro_unhandled_exception_identifier;
    216 
    217 /* Awaitable methods.  */
    218 
    219 static GTY(()) tree coro_await_ready_identifier;
    220 static GTY(()) tree coro_await_suspend_identifier;
    221 static GTY(()) tree coro_await_resume_identifier;
    222 
    223 /* Accessors for the coroutine frame state used by the implementation.  */
    224 
    225 static GTY(()) tree coro_resume_fn_id;
    226 static GTY(()) tree coro_destroy_fn_id;
    227 static GTY(()) tree coro_promise_id;
    228 static GTY(()) tree coro_frame_needs_free_id;
    229 static GTY(()) tree coro_resume_index_id;
    230 static GTY(()) tree coro_self_handle_id;
    231 static GTY(()) tree coro_actor_continue_id;
    232 static GTY(()) tree coro_frame_i_a_r_c_id;
    233 
    234 /* Create the identifiers used by the coroutines library interfaces and
    235    the implementation frame state.  */
    236 
    237 static void
    238 coro_init_identifiers ()
    239 {
    240   coro_traits_identifier = get_identifier ("coroutine_traits");
    241   coro_handle_identifier = get_identifier ("coroutine_handle");
    242   coro_promise_type_identifier = get_identifier ("promise_type");
    243 
    244   coro_await_transform_identifier = get_identifier ("await_transform");
    245   coro_initial_suspend_identifier = get_identifier ("initial_suspend");
    246   coro_final_suspend_identifier = get_identifier ("final_suspend");
    247   coro_return_void_identifier = get_identifier ("return_void");
    248   coro_return_value_identifier = get_identifier ("return_value");
    249   coro_yield_value_identifier = get_identifier ("yield_value");
    250   coro_address_identifier = get_identifier ("address");
    251   coro_from_address_identifier = get_identifier ("from_address");
    252   coro_get_return_object_identifier = get_identifier ("get_return_object");
    253   coro_gro_on_allocation_fail_identifier =
    254     get_identifier ("get_return_object_on_allocation_failure");
    255   coro_unhandled_exception_identifier = get_identifier ("unhandled_exception");
    256 
    257   coro_await_ready_identifier = get_identifier ("await_ready");
    258   coro_await_suspend_identifier = get_identifier ("await_suspend");
    259   coro_await_resume_identifier = get_identifier ("await_resume");
    260 
    261   /* Coroutine state frame field accessors.  */
    262   coro_resume_fn_id = get_identifier ("_Coro_resume_fn");
    263   coro_destroy_fn_id = get_identifier ("_Coro_destroy_fn");
    264   coro_promise_id = get_identifier ("_Coro_promise");
    265   coro_frame_needs_free_id = get_identifier ("_Coro_frame_needs_free");
    266   coro_frame_i_a_r_c_id = get_identifier ("_Coro_initial_await_resume_called");
    267   coro_resume_index_id = get_identifier ("_Coro_resume_index");
    268   coro_self_handle_id = get_identifier ("_Coro_self_handle");
    269   coro_actor_continue_id = get_identifier ("_Coro_actor_continue");
    270 }
    271 
    272 /* Trees we only need to set up once.  */
    273 
    274 static GTY(()) tree coro_traits_templ;
    275 static GTY(()) tree coro_handle_templ;
    276 static GTY(()) tree void_coro_handle_type;
    277 static GTY(()) tree void_coro_handle_address;
    278 
    279 /* ================= Parse, Semantics and Type checking ================= */
    280 
    281 /* This initial set of routines are helper for the parsing and template
    282    expansion phases.
    283 
    284    At the completion of this, we will have completed trees for each of the
    285    keywords, but making use of proxy variables for the self-handle and the
    286    promise class instance.  */
    287 
    288 /* [coroutine.traits]
    289    Lookup the coroutine_traits template decl.  */
    290 
    291 static tree
    292 find_coro_traits_template_decl (location_t kw)
    293 {
    294   /* If we are missing fundamental information, such as the traits, (or the
    295      declaration found is not a type template), then don't emit an error for
    296      every keyword in a TU, just do it once.  */
    297   static bool traits_error_emitted = false;
    298 
    299   tree traits_decl = lookup_qualified_name (std_node, coro_traits_identifier,
    300 					    LOOK_want::NORMAL,
    301 					    /*complain=*/!traits_error_emitted);
    302   if (traits_decl == error_mark_node
    303       || !DECL_TYPE_TEMPLATE_P (traits_decl))
    304     {
    305       if (!traits_error_emitted)
    306 	{
    307 	  gcc_rich_location richloc (kw);
    308 	  error_at (&richloc, "coroutines require a traits template; cannot"
    309 		    " find %<%E::%E%>", std_node, coro_traits_identifier);
    310 	  inform (&richloc, "perhaps %<#include <coroutine>%> is missing");
    311 	  traits_error_emitted = true;
    312 	}
    313       return NULL_TREE;
    314     }
    315   else
    316     return traits_decl;
    317 }
    318 
    319 /*  Instantiate Coroutine traits for the function signature.  */
    320 
    321 static tree
    322 instantiate_coro_traits (tree fndecl, location_t kw)
    323 {
    324   /* [coroutine.traits.primary]
    325      So now build up a type list for the template <typename _R, typename...>.
    326      The types are the function's arg types and _R is the function return
    327      type.  */
    328 
    329   tree functyp = TREE_TYPE (fndecl);
    330   tree arg = DECL_ARGUMENTS (fndecl);
    331   tree arg_node = TYPE_ARG_TYPES (functyp);
    332   tree argtypes = make_tree_vec (list_length (arg_node)-1);
    333   unsigned p = 0;
    334 
    335   while (arg_node != NULL_TREE && !VOID_TYPE_P (TREE_VALUE (arg_node)))
    336     {
    337       if (is_this_parameter (arg)
    338 	  || DECL_NAME (arg) == closure_identifier)
    339 	{
    340 	  /* We pass a reference to *this to the param preview.  */
    341 	  tree ct = TREE_TYPE (TREE_TYPE (arg));
    342 	  TREE_VEC_ELT (argtypes, p++) = cp_build_reference_type (ct, false);
    343 	}
    344       else
    345 	TREE_VEC_ELT (argtypes, p++) = TREE_VALUE (arg_node);
    346 
    347       arg_node = TREE_CHAIN (arg_node);
    348       arg = DECL_CHAIN (arg);
    349     }
    350 
    351   tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK);
    352   ARGUMENT_PACK_ARGS (argtypepack) = argtypes;
    353 
    354   tree targ = make_tree_vec (2);
    355   TREE_VEC_ELT (targ, 0) = TREE_TYPE (functyp);
    356   TREE_VEC_ELT (targ, 1) = argtypepack;
    357 
    358   tree traits_class
    359     = lookup_template_class (coro_traits_templ, targ,
    360 			     /*in_decl=*/NULL_TREE, /*context=*/NULL_TREE,
    361 			     /*entering scope=*/false, tf_warning_or_error);
    362 
    363   if (traits_class == error_mark_node)
    364     {
    365       error_at (kw, "cannot instantiate %<coroutine traits%>");
    366       return NULL_TREE;
    367     }
    368 
    369   return traits_class;
    370 }
    371 
    372 /* [coroutine.handle] */
    373 
    374 static tree
    375 find_coro_handle_template_decl (location_t kw)
    376 {
    377   /* As for the coroutine traits, this error is per TU, so only emit
    378     it once.  */
    379   static bool coro_handle_error_emitted = false;
    380   tree handle_decl = lookup_qualified_name (std_node, coro_handle_identifier,
    381 					    LOOK_want::NORMAL,
    382 					    !coro_handle_error_emitted);
    383   if (handle_decl == error_mark_node
    384       || !DECL_CLASS_TEMPLATE_P (handle_decl))
    385     {
    386       if (!coro_handle_error_emitted)
    387 	error_at (kw, "coroutines require a handle class template;"
    388 		  " cannot find %<%E::%E%>", std_node, coro_handle_identifier);
    389       coro_handle_error_emitted = true;
    390       return NULL_TREE;
    391     }
    392   else
    393     return handle_decl;
    394 }
    395 
    396 /* Get and validate HANDLE_TYPE::address.  The resulting function, if any, will
    397    be a non-overloaded member function that takes no arguments and returns
    398    void*.  If that is not the case, signals an error and returns NULL_TREE.  */
    399 
    400 static tree
    401 get_handle_type_address (location_t kw, tree handle_type)
    402 {
    403   tree addr_getter = lookup_member (handle_type, coro_address_identifier, 1,
    404 				    0, tf_warning_or_error);
    405   if (!addr_getter || addr_getter == error_mark_node)
    406     {
    407       qualified_name_lookup_error (handle_type, coro_address_identifier,
    408 				   error_mark_node, kw);
    409       return NULL_TREE;
    410     }
    411 
    412   if (!BASELINK_P (addr_getter)
    413       || TREE_CODE (TREE_TYPE (addr_getter)) != METHOD_TYPE)
    414     {
    415       error_at (kw, "%qE must be a non-overloaded method", addr_getter);
    416       return NULL_TREE;
    417     }
    418 
    419   tree fn_t = TREE_TYPE (addr_getter);
    420   tree arg = TYPE_ARG_TYPES (fn_t);
    421 
    422   /* Skip the 'this' pointer.  */
    423   arg = TREE_CHAIN (arg);
    424 
    425   /* Check that from_addr has the argument list ().  */
    426   if (arg != void_list_node)
    427     {
    428       error_at (kw, "%qE must take no arguments", addr_getter);
    429       return NULL_TREE;
    430     }
    431 
    432   tree ret_t = TREE_TYPE (fn_t);
    433   if (!same_type_p (ret_t, ptr_type_node))
    434     {
    435       error_at (kw, "%qE must return %qT, not %qT",
    436 		addr_getter, ptr_type_node, ret_t);
    437       return NULL_TREE;
    438     }
    439 
    440   return addr_getter;
    441 }
    442 
    443 /* Get and validate HANDLE_TYPE::from_address.  The resulting function, if
    444    any, will be a non-overloaded static function that takes a single void* and
    445    returns HANDLE_TYPE.  If that is not the case, signals an error and returns
    446    NULL_TREE.  */
    447 
    448 static tree
    449 get_handle_type_from_address (location_t kw, tree handle_type)
    450 {
    451   tree from_addr = lookup_member (handle_type, coro_from_address_identifier, 1,
    452 				  0, tf_warning_or_error);
    453   if (!from_addr || from_addr == error_mark_node)
    454     {
    455       qualified_name_lookup_error (handle_type, coro_from_address_identifier,
    456 				   error_mark_node, kw);
    457       return NULL_TREE;
    458     }
    459   if (!BASELINK_P (from_addr)
    460       || TREE_CODE (TREE_TYPE (from_addr)) != FUNCTION_TYPE)
    461     {
    462       error_at (kw, "%qE must be a non-overloaded static function", from_addr);
    463       return NULL_TREE;
    464     }
    465 
    466   tree fn_t = TREE_TYPE (from_addr);
    467   tree arg = TYPE_ARG_TYPES (fn_t);
    468   /* Check that from_addr has the argument list (void*).  */
    469   if (!arg
    470       || !same_type_p (TREE_VALUE (arg), ptr_type_node)
    471       || TREE_CHAIN (arg) != void_list_node)
    472     {
    473       error_at (kw, "%qE must take a single %qT", from_addr, ptr_type_node);
    474       return NULL_TREE;
    475     }
    476 
    477   tree ret_t = TREE_TYPE (fn_t);
    478   if (!same_type_p (ret_t, handle_type))
    479     {
    480       error_at (kw, "%qE must return %qT, not %qT",
    481 		from_addr, handle_type, ret_t);
    482       return NULL_TREE;
    483     }
    484 
    485   return from_addr;
    486 }
    487 
    488 static tree
    489 instantiate_coro_handle_for_promise_type (location_t kw, tree promise_type)
    490 {
    491   /* So now build up a type list for the template, one entry, the promise.  */
    492   tree targ = make_tree_vec (1);
    493   TREE_VEC_ELT (targ, 0) = promise_type;
    494   tree handle_type
    495     = lookup_template_class (coro_handle_identifier, targ,
    496 			     /* in_decl=*/NULL_TREE,
    497 			     /* context=*/std_node,
    498 			     /* entering scope=*/false, tf_warning_or_error);
    499 
    500   if (handle_type == error_mark_node)
    501     {
    502       error_at (kw, "cannot instantiate a %<coroutine handle%> for"
    503 		" promise type %qT", promise_type);
    504       return NULL_TREE;
    505     }
    506 
    507   return handle_type;
    508 }
    509 
    510 /* Look for the promise_type in the instantiated traits.  */
    511 
    512 static tree
    513 find_promise_type (tree traits_class)
    514 {
    515   tree promise_type
    516     = lookup_member (traits_class, coro_promise_type_identifier,
    517 		     /* protect=*/1, /*want_type=*/true, tf_warning_or_error);
    518 
    519   if (promise_type)
    520     promise_type
    521       = complete_type_or_else (TREE_TYPE (promise_type), promise_type);
    522 
    523   /* NULL_TREE on fail.  */
    524   return promise_type;
    525 }
    526 
    527 /* Perform initialization of the coroutine processor state, if not done
    528    before.  */
    529 
    530 static bool
    531 ensure_coro_initialized (location_t loc)
    532 {
    533   if (!coro_initialized)
    534     {
    535       /* Trees we only need to create once.
    536 	 Set up the identifiers we will use.  */
    537       coro_init_identifiers ();
    538 
    539       /* Coroutine traits template.  */
    540       coro_traits_templ = find_coro_traits_template_decl (loc);
    541       if (coro_traits_templ == NULL_TREE)
    542 	return false;
    543 
    544       /*  coroutine_handle<> template.  */
    545       coro_handle_templ = find_coro_handle_template_decl (loc);
    546       if (coro_handle_templ == NULL_TREE)
    547 	return false;
    548 
    549       /*  We can also instantiate the void coroutine_handle<>  */
    550       void_coro_handle_type
    551 	= instantiate_coro_handle_for_promise_type (loc, void_type_node);
    552       if (void_coro_handle_type == NULL_TREE)
    553 	return false;
    554 
    555       void_coro_handle_address
    556 	= get_handle_type_address (loc, void_coro_handle_type);
    557       if (!void_coro_handle_address)
    558 	return false;
    559 
    560       /* A table to hold the state, per coroutine decl.  */
    561       gcc_checking_assert (coroutine_info_table == NULL);
    562       coroutine_info_table =
    563 	hash_table<coroutine_info_hasher>::create_ggc (11);
    564 
    565       if (coroutine_info_table == NULL)
    566 	return false;
    567 
    568       coro_initialized = true;
    569     }
    570   return true;
    571 }
    572 
    573 /* Try to get the coroutine traits class.  */
    574 static tree
    575 coro_get_traits_class (tree fndecl, location_t loc)
    576 {
    577   gcc_assert (fndecl != NULL_TREE);
    578   gcc_assert (coro_initialized);
    579 
    580   coroutine_info *coro_info = get_or_insert_coroutine_info (fndecl);
    581   auto& traits_type = coro_info->traits_type;
    582   if (!traits_type)
    583     traits_type = instantiate_coro_traits (fndecl, loc);
    584   return traits_type;
    585 }
    586 
    587 static bool
    588 coro_promise_type_found_p (tree fndecl, location_t loc)
    589 {
    590   gcc_assert (fndecl != NULL_TREE);
    591 
    592   if (!ensure_coro_initialized (loc))
    593     return false;
    594 
    595   /* Save the coroutine data on the side to avoid the overhead on every
    596      function decl tree.  */
    597 
    598   coroutine_info *coro_info = get_or_insert_coroutine_info (fndecl);
    599   /* Without this, we cannot really proceed.  */
    600   gcc_checking_assert (coro_info);
    601 
    602   /* If we don't already have a current promise type, try to look it up.  */
    603   if (coro_info->promise_type == NULL_TREE)
    604     {
    605       /* Get the coroutine traits template class instance for the function
    606 	 signature we have - coroutine_traits <R, ...>  */
    607 
    608       tree templ_class = coro_get_traits_class (fndecl, loc);
    609 
    610       /* Find the promise type for that.  */
    611       coro_info->promise_type = find_promise_type (templ_class);
    612 
    613       /* If we don't find it, punt on the rest.  */
    614       if (coro_info->promise_type == NULL_TREE)
    615 	{
    616 	  if (!coro_info->coro_promise_error_emitted)
    617 	    error_at (loc, "unable to find the promise type for"
    618 		      " this coroutine");
    619 	  coro_info->coro_promise_error_emitted = true;
    620 	  return false;
    621 	}
    622 
    623       /* Test for errors in the promise type that can be determined now.  */
    624       tree has_ret_void = lookup_member (coro_info->promise_type,
    625 					 coro_return_void_identifier,
    626 					 /*protect=*/1, /*want_type=*/0,
    627 					 tf_none);
    628       tree has_ret_val = lookup_member (coro_info->promise_type,
    629 					coro_return_value_identifier,
    630 					/*protect=*/1, /*want_type=*/0,
    631 					tf_none);
    632       if (has_ret_void && has_ret_val)
    633 	{
    634 	  location_t ploc = DECL_SOURCE_LOCATION (fndecl);
    635 	  if (!coro_info->coro_co_return_error_emitted)
    636 	    error_at (ploc, "the coroutine promise type %qT declares both"
    637 		      " %<return_value%> and %<return_void%>",
    638 		      coro_info->promise_type);
    639 	  inform (DECL_SOURCE_LOCATION (BASELINK_FUNCTIONS (has_ret_void)),
    640 		  "%<return_void%> declared here");
    641 	  has_ret_val = BASELINK_FUNCTIONS (has_ret_val);
    642 	  const char *message = "%<return_value%> declared here";
    643 	  if (TREE_CODE (has_ret_val) == OVERLOAD)
    644 	    {
    645 	      has_ret_val = OVL_FIRST (has_ret_val);
    646 	      message = "%<return_value%> first declared here";
    647 	    }
    648 	  inform (DECL_SOURCE_LOCATION (has_ret_val), message);
    649 	  coro_info->coro_co_return_error_emitted = true;
    650 	  return false;
    651 	}
    652 
    653       /* Try to find the handle type for the promise.  */
    654       tree handle_type
    655 	= instantiate_coro_handle_for_promise_type (loc, coro_info->promise_type);
    656       if (handle_type == NULL_TREE)
    657 	return false;
    658       tree from_address = get_handle_type_from_address (loc, handle_type);
    659       if (from_address == NULL_TREE)
    660 	return false;
    661 
    662       /* Complete this, we're going to use it.  */
    663       coro_info->handle_type = complete_type_or_else (handle_type, fndecl);
    664       coro_info->from_address = from_address;
    665 
    666       /* Diagnostic would be emitted by complete_type_or_else.  */
    667       if (!coro_info->handle_type)
    668 	return false;
    669 
    670       /* Build a proxy for a handle to "self" as the param to
    671 	 await_suspend() calls.  */
    672       coro_info->self_h_proxy
    673 	= build_lang_decl (VAR_DECL, coro_self_handle_id,
    674 			   coro_info->handle_type);
    675 
    676       /* Build a proxy for the promise so that we can perform lookups.  */
    677       coro_info->promise_proxy
    678 	= build_lang_decl (VAR_DECL, coro_promise_id,
    679 			   coro_info->promise_type);
    680 
    681       /* Note where we first saw a coroutine keyword.  */
    682       coro_info->first_coro_keyword = loc;
    683     }
    684 
    685   return true;
    686 }
    687 
    688 /* Map from actor or destroyer to ramp.  */
    689 static GTY(()) hash_map<tree, tree> *to_ramp;
    690 
    691 /* Given a tree that is an actor or destroy, find the ramp function.  */
    692 
    693 tree
    694 coro_get_ramp_function (tree decl)
    695 {
    696   if (!to_ramp)
    697     return NULL_TREE;
    698   tree *p = to_ramp->get (decl);
    699   if (p)
    700     return *p;
    701   return NULL_TREE;
    702 }
    703 
    704 /* Given the DECL for a ramp function (the user's original declaration) return
    705    the actor function if it has been defined.  */
    706 
    707 tree
    708 coro_get_actor_function (tree decl)
    709 {
    710   if (coroutine_info *info = get_coroutine_info (decl))
    711     return info->actor_decl;
    712 
    713   return NULL_TREE;
    714 }
    715 
    716 /* Given the DECL for a ramp function (the user's original declaration) return
    717    the destroy function if it has been defined.  */
    718 
    719 tree
    720 coro_get_destroy_function (tree decl)
    721 {
    722   if (coroutine_info *info = get_coroutine_info (decl))
    723     return info->destroy_decl;
    724 
    725   return NULL_TREE;
    726 }
    727 
    728 /* Given a CO_AWAIT_EXPR AWAIT_EXPR, return its resume call.  */
    729 
    730 tree
    731 co_await_get_resume_call (tree await_expr)
    732 {
    733   gcc_checking_assert (TREE_CODE (await_expr) == CO_AWAIT_EXPR);
    734   tree vec = TREE_OPERAND (await_expr, 3);
    735   if (!vec)
    736     return nullptr;
    737   return TREE_VEC_ELT (vec, 2);
    738 }
    739 
    740 /* These functions assumes that the caller has verified that the state for
    741    the decl has been initialized, we try to minimize work here.  */
    742 
    743 static tree
    744 get_coroutine_promise_type (tree decl)
    745 {
    746   if (coroutine_info *info = get_coroutine_info (decl))
    747     return info->promise_type;
    748 
    749   return NULL_TREE;
    750 }
    751 
    752 static tree
    753 get_coroutine_handle_type (tree decl)
    754 {
    755   if (coroutine_info *info = get_coroutine_info (decl))
    756     return info->handle_type;
    757 
    758   return NULL_TREE;
    759 }
    760 
    761 static tree
    762 get_coroutine_self_handle_proxy (tree decl)
    763 {
    764   if (coroutine_info *info = get_coroutine_info (decl))
    765     return info->self_h_proxy;
    766 
    767   return NULL_TREE;
    768 }
    769 
    770 static tree
    771 get_coroutine_promise_proxy (tree decl)
    772 {
    773   if (coroutine_info *info = get_coroutine_info (decl))
    774     return info->promise_proxy;
    775 
    776   return NULL_TREE;
    777 }
    778 
    779 static tree
    780 get_coroutine_from_address (tree decl)
    781 {
    782   if (coroutine_info *info = get_coroutine_info (decl))
    783     return info->from_address;
    784 
    785   return NULL_TREE;
    786 }
    787 
    788 static tree
    789 lookup_promise_method (tree fndecl, tree member_id, location_t loc,
    790 		       bool musthave)
    791 {
    792   tree promise = get_coroutine_promise_type (fndecl);
    793   tree pm_memb
    794     = lookup_member (promise, member_id,
    795 		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
    796   if (musthave && pm_memb == NULL_TREE)
    797     {
    798       error_at (loc, "no member named %qE in %qT", member_id, promise);
    799       return error_mark_node;
    800     }
    801   return pm_memb;
    802 }
    803 
    804 /* Build an expression of the form p.method (args) where the p is a promise
    805    object for the current coroutine.
    806    OBJECT is the promise object instance to use, it may be NULL, in which case
    807    we will use the promise_proxy instance for this coroutine.
    808    ARGS may be NULL, for empty parm lists.  */
    809 
    810 static tree
    811 coro_build_promise_expression (tree fn, tree promise_obj, tree member_id,
    812 			       location_t loc, vec<tree, va_gc> **args,
    813 			       bool musthave)
    814 {
    815   tree meth = lookup_promise_method (fn, member_id, loc, musthave);
    816   if (meth == error_mark_node)
    817     return error_mark_node;
    818 
    819   /* If we don't find it, and it isn't needed, an empty return is OK.  */
    820   if (!meth)
    821     return NULL_TREE;
    822 
    823   tree promise
    824     = promise_obj ? promise_obj
    825 		  : get_coroutine_promise_proxy (current_function_decl);
    826   tree expr;
    827   if (BASELINK_P (meth))
    828     expr = build_new_method_call (promise, meth, args, NULL_TREE,
    829 				  LOOKUP_NORMAL, NULL, tf_warning_or_error);
    830   else
    831     {
    832       expr = build_class_member_access_expr (promise, meth, NULL_TREE,
    833 					     true, tf_warning_or_error);
    834       vec<tree, va_gc> *real_args;
    835       if (!args)
    836 	real_args = make_tree_vector ();
    837       else
    838 	real_args = *args;
    839       expr = build_op_call (expr, &real_args, tf_warning_or_error);
    840     }
    841   return expr;
    842 }
    843 
    844 /* Caching get for the expression p.return_void ().  */
    845 
    846 static tree
    847 get_coroutine_return_void_expr (tree decl, location_t loc, bool musthave)
    848 {
    849   if (coroutine_info *info = get_coroutine_info (decl))
    850     {
    851       /* If we don't have it try to build it.  */
    852       if (!info->return_void)
    853 	info->return_void
    854 	  = coro_build_promise_expression (current_function_decl, NULL,
    855 					   coro_return_void_identifier,
    856 					   loc, NULL, musthave);
    857       /* Don't return an error if it's an optional call.  */
    858       if (!musthave && info->return_void == error_mark_node)
    859 	return NULL_TREE;
    860       return info->return_void;
    861     }
    862   return musthave ? error_mark_node : NULL_TREE;
    863 }
    864 
    865 /* Lookup an Awaitable member, which should be await_ready, await_suspend
    866    or await_resume.  */
    867 
    868 static tree
    869 lookup_awaitable_member (tree await_type, tree member_id, location_t loc)
    870 {
    871   tree aw_memb
    872     = lookup_member (await_type, member_id,
    873 		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
    874   if (aw_memb == NULL_TREE)
    875     {
    876       error_at (loc, "no member named %qE in %qT", member_id, await_type);
    877       return error_mark_node;
    878     }
    879   return aw_memb;
    880 }
    881 
    882 /* Here we check the constraints that are common to all keywords (since the
    883    presence of a coroutine keyword makes the function into a coroutine).  */
    884 
    885 static bool
    886 coro_common_keyword_context_valid_p (tree fndecl, location_t kw_loc,
    887 				     const char *kw_name)
    888 {
    889   if (fndecl == NULL_TREE)
    890     {
    891       error_at (kw_loc, "%qs cannot be used outside a function", kw_name);
    892       return false;
    893     }
    894 
    895   /* This is arranged in order of prohibitions in the std.  */
    896   if (DECL_MAIN_P (fndecl))
    897     {
    898       /* [basic.start.main] 3. The function main shall not be a coroutine.  */
    899       error_at (kw_loc, "%qs cannot be used in the %<main%> function",
    900 		kw_name);
    901       return false;
    902     }
    903 
    904   if (DECL_DECLARED_CONSTEXPR_P (fndecl))
    905     {
    906       cp_function_chain->invalid_constexpr = true;
    907       if (!is_instantiation_of_constexpr (fndecl))
    908 	{
    909 	  /* [dcl.constexpr] 3.3 it shall not be a coroutine.  */
    910 	  error_at (kw_loc, "%qs cannot be used in a %<constexpr%> function",
    911 		    kw_name);
    912 	  return false;
    913 	}
    914     }
    915 
    916   if (FNDECL_USED_AUTO (fndecl))
    917     {
    918       /* [dcl.spec.auto] 15. A function declared with a return type that uses
    919 	 a placeholder type shall not be a coroutine.  */
    920       error_at (kw_loc,
    921 		"%qs cannot be used in a function with a deduced return type",
    922 		kw_name);
    923       return false;
    924     }
    925 
    926   if (varargs_function_p (fndecl))
    927     {
    928       /* [dcl.fct.def.coroutine] The parameter-declaration-clause of the
    929 	 coroutine shall not terminate with an ellipsis that is not part
    930 	 of a parameter-declaration.  */
    931       error_at (kw_loc,
    932 		"%qs cannot be used in a varargs function", kw_name);
    933       return false;
    934     }
    935 
    936   if (DECL_CONSTRUCTOR_P (fndecl))
    937     {
    938       /* [class.ctor] 7. a constructor shall not be a coroutine.  */
    939       error_at (kw_loc, "%qs cannot be used in a constructor", kw_name);
    940       return false;
    941     }
    942 
    943   if (DECL_DESTRUCTOR_P (fndecl))
    944     {
    945       /* [class.dtor] 21. a destructor shall not be a coroutine.  */
    946       error_at (kw_loc, "%qs cannot be used in a destructor", kw_name);
    947       return false;
    948     }
    949 
    950   return true;
    951 }
    952 
    953 /* Here we check the constraints that are not per keyword.  */
    954 
    955 static bool
    956 coro_function_valid_p (tree fndecl)
    957 {
    958   location_t f_loc = DECL_SOURCE_LOCATION (fndecl);
    959 
    960   /* For cases where fundamental information cannot be found, e.g. the
    961      coroutine traits are missing, we need to punt early.  */
    962   if (!coro_promise_type_found_p (fndecl, f_loc))
    963     return false;
    964 
    965   /* Since we think the function is a coroutine, that implies we parsed
    966      a keyword that triggered this.  Keywords check promise validity for
    967      their context and thus the promise type should be known at this point.  */
    968   if (get_coroutine_handle_type (fndecl) == NULL_TREE
    969       || get_coroutine_promise_type (fndecl) == NULL_TREE)
    970     return false;
    971 
    972   if (current_function_returns_value || current_function_returns_null)
    973     {
    974        /* TODO: record or extract positions of returns (and the first coro
    975 	  keyword) so that we can add notes to the diagnostic about where
    976 	  the bad keyword is and what made the function into a coro.  */
    977       error_at (f_loc, "a %<return%> statement is not allowed in coroutine;"
    978 			" did you mean %<co_return%>?");
    979       return false;
    980     }
    981 
    982   return true;
    983 }
    984 
    985 enum suspend_point_kind {
    986   CO_AWAIT_SUSPEND_POINT = 0,
    987   CO_YIELD_SUSPEND_POINT,
    988   INITIAL_SUSPEND_POINT,
    989   FINAL_SUSPEND_POINT
    990 };
    991 
    992 /* Helper function to build a named variable for the temps we use for each
    993    await point.  The root of the name is determined by SUSPEND_KIND, and
    994    the variable is of type V_TYPE.  The awaitable number is reset each time
    995    we encounter a final suspend.  */
    996 
    997 static tree
    998 get_awaitable_var (suspend_point_kind suspend_kind, tree v_type)
    999 {
   1000   auto cinfo = get_coroutine_info (current_function_decl);
   1001   gcc_checking_assert (cinfo);
   1002   char *buf;
   1003   switch (suspend_kind)
   1004     {
   1005     default: buf = xasprintf ("Aw%d", cinfo->awaitable_number++); break;
   1006     case CO_YIELD_SUSPEND_POINT:
   1007       buf = xasprintf ("Yd%d", cinfo->awaitable_number++);
   1008       break;
   1009     case INITIAL_SUSPEND_POINT: buf = xasprintf ("Is"); break;
   1010     case FINAL_SUSPEND_POINT: buf = xasprintf ("Fs"); break;
   1011     }
   1012   tree ret = get_identifier (buf);
   1013   free (buf);
   1014   ret = build_lang_decl (VAR_DECL, ret, v_type);
   1015   DECL_ARTIFICIAL (ret) = true;
   1016   return ret;
   1017 }
   1018 
   1019 /* Helpers to diagnose missing noexcept on final await expressions.  */
   1020 
   1021 static bool
   1022 coro_diagnose_throwing_fn (tree fndecl)
   1023 {
   1024   if (!TYPE_NOTHROW_P (TREE_TYPE (fndecl)))
   1025     {
   1026       location_t f_loc = cp_expr_loc_or_loc (fndecl,
   1027 					     DECL_SOURCE_LOCATION (fndecl));
   1028       error_at (f_loc, "the expression %qE is required to be non-throwing",
   1029 		fndecl);
   1030       inform (f_loc, "must be declared with %<noexcept(true)%>");
   1031       return true;
   1032     }
   1033   return false;
   1034 }
   1035 
   1036 static bool
   1037 coro_diagnose_throwing_final_aw_expr (tree expr)
   1038 {
   1039   if (TREE_CODE (expr) == TARGET_EXPR)
   1040     expr = TARGET_EXPR_INITIAL (expr);
   1041   tree fn = NULL_TREE;
   1042   if (TREE_CODE (expr) == CALL_EXPR)
   1043     fn = CALL_EXPR_FN (expr);
   1044   else if (TREE_CODE (expr) == AGGR_INIT_EXPR)
   1045     fn = AGGR_INIT_EXPR_FN (expr);
   1046   else if (TREE_CODE (expr) == CONSTRUCTOR)
   1047     return false;
   1048   else
   1049     {
   1050       gcc_checking_assert (0 && "unhandled expression type");
   1051       return false;
   1052     }
   1053   fn = TREE_OPERAND (fn, 0);
   1054   return coro_diagnose_throwing_fn (fn);
   1055 }
   1056 
   1057 /* Build a co_await suitable for later expansion.  */
   1058 
   1059 tree
   1060 build_template_co_await_expr (location_t kw, tree type, tree expr, tree kind)
   1061 {
   1062   tree aw_expr = build5_loc (kw, CO_AWAIT_EXPR, type, expr,
   1063 			     NULL_TREE, NULL_TREE, NULL_TREE,
   1064 			     kind);
   1065   TREE_SIDE_EFFECTS (aw_expr) = true;
   1066   return aw_expr;
   1067 }
   1068 
   1069 /* Is EXPR an lvalue that will refer to the same object after a resume?
   1070 
   1071    This is close to asking tree_invariant_p of its address, but that doesn't
   1072    distinguish temporaries from other variables.  */
   1073 
   1074 static bool
   1075 is_stable_lvalue (tree expr)
   1076 {
   1077   if (TREE_SIDE_EFFECTS (expr))
   1078     return false;
   1079 
   1080   for (; handled_component_p (expr);
   1081        expr = TREE_OPERAND (expr, 0))
   1082     {
   1083       if (TREE_CODE (expr) == ARRAY_REF
   1084 	  && !TREE_CONSTANT (TREE_OPERAND (expr, 1)))
   1085 	return false;
   1086     }
   1087 
   1088   return (TREE_CODE (expr) == PARM_DECL
   1089 	  || (VAR_P (expr) && !is_local_temp (expr)));
   1090 }
   1091 
   1092 /*  This performs [expr.await] bullet 3.3 and validates the interface obtained.
   1093     It is also used to build the initial and final suspend points.
   1094 
   1095     'a', 'o' and 'e' are used as per the description in the section noted.
   1096 
   1097     A, the original yield/await expr, is found at source location LOC.
   1098 
   1099     We will be constructing a CO_AWAIT_EXPR for a suspend point of one of
   1100     the four suspend_point_kind kinds.  This is indicated by SUSPEND_KIND.
   1101 
   1102     In the case that we're processing a template declaration, we can't save
   1103     actual awaiter expressions as the frame type will differ between
   1104     instantiations, but we can generate them to type-check them and compute the
   1105     resulting expression type.  In those cases, we will return a
   1106     template-appropriate CO_AWAIT_EXPR and throw away the rest of the results.
   1107     Such an expression requires the original co_await operand unaltered.  Pass
   1108     it as ORIG_OPERAND.  If it is the same as 'a', you can pass NULL_TREE (the
   1109     default) to use 'a' as the value.  */
   1110 
   1111 static tree
   1112 build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind,
   1113 		tree orig_operand = NULL_TREE)
   1114 {
   1115   if (orig_operand == NULL_TREE)
   1116     orig_operand = a;
   1117 
   1118   /* Try and overload of operator co_await, .... */
   1119   tree o;
   1120   if (MAYBE_CLASS_TYPE_P (TREE_TYPE (a)))
   1121     {
   1122       o = build_new_op (loc, CO_AWAIT_EXPR, LOOKUP_NORMAL, a, NULL_TREE,
   1123 			NULL_TREE, NULL_TREE, NULL, tf_warning_or_error);
   1124       /* If no viable functions are found, o is a.  */
   1125       if (!o || o == error_mark_node)
   1126 	o = a;
   1127       else if (flag_exceptions && suspend_kind == FINAL_SUSPEND_POINT)
   1128 	{
   1129 	  /* We found an overload for co_await(), diagnose throwing cases.  */
   1130 	  if (TREE_CODE (o) == TARGET_EXPR
   1131 	      && coro_diagnose_throwing_final_aw_expr (o))
   1132 	    return error_mark_node;
   1133 
   1134 	  /* We now know that the final suspend object is distinct from the
   1135 	     final awaiter, so check for a non-throwing DTOR where needed.  */
   1136 	  if (tree dummy = cxx_maybe_build_cleanup (a, tf_none))
   1137 	    {
   1138 	      if (CONVERT_EXPR_P (dummy))
   1139 		dummy = TREE_OPERAND (dummy, 0);
   1140 	      dummy = TREE_OPERAND (CALL_EXPR_FN (dummy), 0);
   1141 	      if (coro_diagnose_throwing_fn (dummy))
   1142 		return error_mark_node;
   1143 	    }
   1144 	}
   1145     }
   1146   else
   1147     o = a; /* This is most likely about to fail anyway.  */
   1148 
   1149   tree o_type = TREE_TYPE (o);
   1150   if (o_type && !VOID_TYPE_P (o_type))
   1151     o_type = complete_type_or_else (o_type, o);
   1152 
   1153   if (!o_type || o_type == error_mark_node)
   1154     return error_mark_node;
   1155 
   1156   if (TREE_CODE (o_type) != RECORD_TYPE)
   1157     {
   1158       error_at (loc, "awaitable type %qT is not a structure",
   1159 		o_type);
   1160       return error_mark_node;
   1161     }
   1162 
   1163   /* Check for required awaitable members and their types.  */
   1164   tree awrd_meth
   1165     = lookup_awaitable_member (o_type, coro_await_ready_identifier, loc);
   1166   if (!awrd_meth || awrd_meth == error_mark_node)
   1167     return error_mark_node;
   1168   tree awsp_meth
   1169     = lookup_awaitable_member (o_type, coro_await_suspend_identifier, loc);
   1170   if (!awsp_meth || awsp_meth == error_mark_node)
   1171     return error_mark_node;
   1172 
   1173   /* The type of the co_await is the return type of the awaitable's
   1174      await_resume, so we need to look that up.  */
   1175   tree awrs_meth
   1176     = lookup_awaitable_member (o_type, coro_await_resume_identifier, loc);
   1177   if (!awrs_meth || awrs_meth == error_mark_node)
   1178     return error_mark_node;
   1179 
   1180   /* [expr.await]/3.3 If o would be a prvalue, the temporary
   1181      materialization conversion ([conv.rval]) is applied.  */
   1182   if (!glvalue_p (o))
   1183     o = get_target_expr (o, tf_warning_or_error);
   1184 
   1185   /* [expr.await]/3.4 e is an lvalue referring to the result of evaluating the
   1186      (possibly-converted) o.
   1187 
   1188      So, either reuse an existing stable lvalue such as a variable or
   1189      COMPONENT_REF thereof, or create a new a coroutine state frame variable
   1190      for the awaiter, since it must persist across suspension.  */
   1191   tree e_var = NULL_TREE;
   1192   tree e_proxy = o;
   1193   if (is_stable_lvalue (o))
   1194     o = NULL_TREE; /* Use the existing entity.  */
   1195   else /* We need a non-temp var.  */
   1196     {
   1197       tree p_type = TREE_TYPE (o);
   1198       tree o_a = o;
   1199       if (glvalue_p (o))
   1200 	{
   1201 	  /* Build a reference variable for a non-stable lvalue o.  */
   1202 	  p_type = cp_build_reference_type (p_type, xvalue_p (o));
   1203 	  o_a = build_address (o);
   1204 	  o_a = cp_fold_convert (p_type, o_a);
   1205 	}
   1206       e_var = get_awaitable_var (suspend_kind, p_type);
   1207       o = cp_build_init_expr (loc, e_var, o_a);
   1208       e_proxy = convert_from_reference (e_var);
   1209     }
   1210 
   1211   /* I suppose we could check that this is contextually convertible to bool.  */
   1212   tree awrd_func = NULL_TREE;
   1213   tree awrd_call
   1214     = build_new_method_call (e_proxy, awrd_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
   1215 			     &awrd_func, tf_warning_or_error);
   1216 
   1217   if (!awrd_func || !awrd_call || awrd_call == error_mark_node)
   1218     return error_mark_node;
   1219 
   1220   /* The suspend method may return one of three types:
   1221       1. void (no special action needed).
   1222       2. bool (if true, we don't need to suspend).
   1223       3. a coroutine handle, we execute the handle.resume() call.  */
   1224   tree awsp_func = NULL_TREE;
   1225   tree h_proxy = get_coroutine_self_handle_proxy (current_function_decl);
   1226   vec<tree, va_gc> *args = make_tree_vector_single (h_proxy);
   1227   tree awsp_call
   1228     = build_new_method_call (e_proxy, awsp_meth, &args, NULL_TREE,
   1229 			     LOOKUP_NORMAL, &awsp_func, tf_warning_or_error);
   1230 
   1231   release_tree_vector (args);
   1232   if (!awsp_func || !awsp_call || awsp_call == error_mark_node)
   1233     return error_mark_node;
   1234 
   1235   bool ok = false;
   1236   tree susp_return_type = TREE_TYPE (TREE_TYPE (awsp_func));
   1237   if (same_type_p (susp_return_type, void_type_node))
   1238     ok = true;
   1239   else if (same_type_p (susp_return_type, boolean_type_node))
   1240     ok = true;
   1241   else if (TREE_CODE (susp_return_type) == RECORD_TYPE
   1242 	   && CLASS_TYPE_P (susp_return_type)
   1243 	   && CLASSTYPE_TEMPLATE_INFO (susp_return_type))
   1244     {
   1245       tree tt = CLASSTYPE_TI_TEMPLATE (susp_return_type);
   1246       if (tt == coro_handle_templ)
   1247 	ok = true;
   1248     }
   1249 
   1250   if (!ok)
   1251     {
   1252       error_at (loc, "%<await_suspend%> must return %<void%>, %<bool%> or"
   1253 		     " a coroutine handle");
   1254       return error_mark_node;
   1255     }
   1256 
   1257   /* Finally, the type of e.await_resume() is the co_await's type.  */
   1258   tree awrs_func = NULL_TREE;
   1259   tree awrs_call
   1260     = build_new_method_call (e_proxy, awrs_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
   1261 			     &awrs_func, tf_warning_or_error);
   1262 
   1263   if (!awrs_func || !awrs_call || awrs_call == error_mark_node)
   1264     return error_mark_node;
   1265 
   1266   if (flag_exceptions && suspend_kind == FINAL_SUSPEND_POINT)
   1267     {
   1268       if (coro_diagnose_throwing_fn (awrd_func))
   1269 	return error_mark_node;
   1270       if (coro_diagnose_throwing_fn (awsp_func))
   1271 	return error_mark_node;
   1272       if (coro_diagnose_throwing_fn (awrs_func))
   1273 	return error_mark_node;
   1274       if (tree dummy = cxx_maybe_build_cleanup (e_var, tf_none))
   1275 	{
   1276 	  if (CONVERT_EXPR_P (dummy))
   1277 	    dummy = TREE_OPERAND (dummy, 0);
   1278 	  dummy = TREE_OPERAND (CALL_EXPR_FN (dummy), 0);
   1279 	  if (coro_diagnose_throwing_fn (dummy))
   1280 	    return error_mark_node;
   1281 	}
   1282     }
   1283 
   1284   /* We now have three call expressions, in terms of the promise, handle and
   1285      'e' proxy expression.  Save them in the await expression for later
   1286      expansion.  */
   1287 
   1288   tree awaiter_calls = make_tree_vec (3);
   1289   TREE_VEC_ELT (awaiter_calls, 0) = awrd_call; /* await_ready().  */
   1290   TREE_VEC_ELT (awaiter_calls, 1) = awsp_call; /* await_suspend().  */
   1291   tree te = NULL_TREE;
   1292   if (TREE_CODE (awrs_call) == TARGET_EXPR)
   1293     {
   1294       te = awrs_call;
   1295       awrs_call = TREE_OPERAND (awrs_call, 1);
   1296     }
   1297   TREE_VEC_ELT (awaiter_calls, 2) = awrs_call; /* await_resume().  */
   1298 
   1299   if (e_var)
   1300     e_proxy = e_var;
   1301 
   1302   tree awrs_type = TREE_TYPE (TREE_TYPE (awrs_func));
   1303   tree suspend_kind_cst = build_int_cst (integer_type_node,
   1304 					 (int) suspend_kind);
   1305   tree await_expr = build5_loc (loc, CO_AWAIT_EXPR,
   1306 				awrs_type,
   1307 				a, e_proxy, o, awaiter_calls,
   1308 				suspend_kind_cst);
   1309   TREE_SIDE_EFFECTS (await_expr) = true;
   1310   if (te)
   1311     {
   1312       TREE_OPERAND (te, 1) = await_expr;
   1313       TREE_SIDE_EFFECTS (te) = true;
   1314       await_expr = te;
   1315     }
   1316   SET_EXPR_LOCATION (await_expr, loc);
   1317 
   1318   if (processing_template_decl)
   1319     return build_template_co_await_expr (loc, awrs_type, orig_operand,
   1320 					 suspend_kind_cst);
   1321  return convert_from_reference (await_expr);
   1322 }
   1323 
   1324 /* Returns true iff EXPR or the TRAITS_CLASS, which should be a
   1325    coroutine_traits instance, are dependent.  In those cases, we can't decide
   1326    what the types of our co_{await,yield,return} expressions are, so we defer
   1327    expansion entirely.  */
   1328 
   1329 static bool
   1330 coro_dependent_p (tree expr, tree traits_class)
   1331 {
   1332   return type_dependent_expression_p (expr)
   1333     || dependent_type_p (traits_class);
   1334 }
   1335 
   1336 tree
   1337 finish_co_await_expr (location_t kw, tree expr)
   1338 {
   1339   if (!expr || error_operand_p (expr))
   1340     return error_mark_node;
   1341 
   1342   if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
   1343 					    "co_await"))
   1344     return error_mark_node;
   1345 
   1346   /* The current function has now become a coroutine, if it wasn't already.  */
   1347   DECL_COROUTINE_P (current_function_decl) = 1;
   1348 
   1349   /* This function will appear to have no return statement, even if it
   1350      is declared to return non-void (most likely).  This is correct - we
   1351      synthesize the return for the ramp in the compiler.  So suppress any
   1352      extraneous warnings during substitution.  */
   1353   suppress_warning (current_function_decl, OPT_Wreturn_type);
   1354 
   1355   /* Prepare for coroutine transformations.  */
   1356   if (!ensure_coro_initialized (kw))
   1357     return error_mark_node;
   1358 
   1359   /* Get our traits class.  */
   1360   tree traits_class = coro_get_traits_class (current_function_decl, kw);
   1361 
   1362   /* Defer expansion when we are processing a template, unless the traits type
   1363      and expression would not be dependent.  In the case that the types are
   1364      not dependent but we are processing a template declaration, we will do
   1365      most of the computation but throw away the results (except for the
   1366      await_resume type).  Otherwise, if our co_await is type-dependent
   1367      (i.e. the promise type or operand type is dependent), we can't do much,
   1368      and just return early with a NULL_TREE type (indicating that we cannot
   1369      compute the type yet).  */
   1370   if (coro_dependent_p (expr, traits_class))
   1371     return build_template_co_await_expr (kw, NULL_TREE, expr,
   1372 					 integer_zero_node);
   1373 
   1374   /* We must be able to look up the "await_transform" method in the scope of
   1375      the promise type, and obtain its return type.  */
   1376   if (!coro_promise_type_found_p (current_function_decl, kw))
   1377     return error_mark_node;
   1378 
   1379   /* [expr.await] 3.2
   1380      The incoming cast expression might be transformed by a promise
   1381      'await_transform()'.  */
   1382   tree at_meth
   1383     = lookup_promise_method (current_function_decl,
   1384 			     coro_await_transform_identifier, kw,
   1385 			     /*musthave=*/false);
   1386   if (at_meth == error_mark_node)
   1387     return error_mark_node;
   1388 
   1389   tree a = expr;
   1390   if (at_meth)
   1391     {
   1392       /* try to build a = p.await_transform (e). */
   1393       vec<tree, va_gc> *args = make_tree_vector_single (expr);
   1394       a = build_new_method_call (get_coroutine_promise_proxy (
   1395 				   current_function_decl),
   1396 				 at_meth, &args, NULL_TREE, LOOKUP_NORMAL,
   1397 				 NULL, tf_warning_or_error);
   1398 
   1399       /* As I read the section.
   1400 	 We saw an await_transform method, so it's mandatory that we replace
   1401 	 expr with p.await_transform (expr), therefore if the method call fails
   1402 	 (presumably, we don't have suitable arguments) then this part of the
   1403 	 process fails.  */
   1404       if (a == error_mark_node)
   1405 	return error_mark_node;
   1406     }
   1407 
   1408   /* Now we want to build co_await a.  */
   1409   return build_co_await (kw, a, CO_AWAIT_SUSPEND_POINT, expr);
   1410 }
   1411 
   1412 /* Take the EXPR given and attempt to build:
   1413      co_await p.yield_value (expr);
   1414    per [expr.yield] para 1. */
   1415 
   1416 tree
   1417 finish_co_yield_expr (location_t kw, tree expr)
   1418 {
   1419   if (!expr || error_operand_p (expr))
   1420     return error_mark_node;
   1421 
   1422   /* Check the general requirements and simple syntax errors.  */
   1423   if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
   1424 					    "co_yield"))
   1425     return error_mark_node;
   1426 
   1427   /* The current function has now become a coroutine, if it wasn't already.  */
   1428   DECL_COROUTINE_P (current_function_decl) = 1;
   1429 
   1430   /* This function will appear to have no return statement, even if it
   1431      is declared to return non-void (most likely).  This is correct - we
   1432      synthesize the return for the ramp in the compiler.  So suppress any
   1433      extraneous warnings during substitution.  */
   1434   suppress_warning (current_function_decl, OPT_Wreturn_type);
   1435 
   1436   /* Prepare for coroutine transformations.  */
   1437   if (!ensure_coro_initialized (kw))
   1438     return error_mark_node;
   1439 
   1440   /* Get our traits class.  */
   1441   tree traits_class = coro_get_traits_class (current_function_decl, kw);
   1442 
   1443   /* Defer expansion when we are processing a template; see note in
   1444      finish_co_await_expr.  Also note that a yield is equivalent to
   1445 
   1446        co_await p.yield_value(EXPR)
   1447 
   1448       If either p or EXPR are type-dependent, then the whole expression is
   1449       certainly type-dependent, and we can't proceed.  */
   1450   if (coro_dependent_p (expr, traits_class))
   1451     return build2_loc (kw, CO_YIELD_EXPR, NULL_TREE, expr, NULL_TREE);
   1452 
   1453   if (!coro_promise_type_found_p (current_function_decl, kw))
   1454     /* We must be able to look up the "yield_value" method in the scope of
   1455        the promise type, and obtain its return type.  */
   1456     return error_mark_node;
   1457 
   1458   /* [expr.yield] / 1
   1459      Let e be the operand of the yield-expression and p be an lvalue naming
   1460      the promise object of the enclosing coroutine, then the yield-expression
   1461      is equivalent to the expression co_await p.yield_value(e).
   1462      build p.yield_value(e):  */
   1463   vec<tree, va_gc> *args = make_tree_vector_single (expr);
   1464   tree yield_call
   1465     = coro_build_promise_expression (current_function_decl, NULL,
   1466 				     coro_yield_value_identifier, kw,
   1467 				     &args, /*musthave=*/true);
   1468   release_tree_vector (args);
   1469 
   1470   /* Now build co_await p.yield_value (e).
   1471      Noting that for co_yield, there is no evaluation of any potential
   1472      promise transform_await(), so we call build_co_await directly.  */
   1473 
   1474   tree op = build_co_await (kw, yield_call, CO_YIELD_SUSPEND_POINT);
   1475   if (op != error_mark_node)
   1476     {
   1477       if (REFERENCE_REF_P (op))
   1478 	op = TREE_OPERAND (op, 0);
   1479       /* If the await expression is wrapped in a TARGET_EXPR, then transfer
   1480 	 that wrapper to the CO_YIELD_EXPR, since this is just a proxy for
   1481 	 its contained await.  Otherwise, just build the CO_YIELD_EXPR.  */
   1482       if (TREE_CODE (op) == TARGET_EXPR)
   1483 	{
   1484 	  tree t = TREE_OPERAND (op, 1);
   1485 	  t = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (t), expr, t);
   1486 	  TREE_OPERAND (op, 1) = t;
   1487 	}
   1488       else
   1489 	op = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (op), expr, op);
   1490       TREE_SIDE_EFFECTS (op) = 1;
   1491       op = convert_from_reference (op);
   1492     }
   1493 
   1494   return op;
   1495 }
   1496 
   1497 /* Check and build a co_return statement.
   1498    First that it's valid to have a co_return keyword here.
   1499    If it is, then check and build the p.return_{void(),value(expr)}.
   1500    These are built against a proxy for the promise, which will be filled
   1501    in with the actual frame version when the function is transformed.  */
   1502 
   1503 tree
   1504 finish_co_return_stmt (location_t kw, tree expr)
   1505 {
   1506   if (expr)
   1507     STRIP_ANY_LOCATION_WRAPPER (expr);
   1508 
   1509   if (error_operand_p (expr))
   1510     return error_mark_node;
   1511 
   1512   /* If it fails the following test, the function is not permitted to be a
   1513      coroutine, so the co_return statement is erroneous.  */
   1514   if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
   1515 					    "co_return"))
   1516     return error_mark_node;
   1517 
   1518   /* The current function has now become a coroutine, if it wasn't
   1519      already.  */
   1520   DECL_COROUTINE_P (current_function_decl) = 1;
   1521 
   1522   /* This function will appear to have no return statement, even if it
   1523      is declared to return non-void (most likely).  This is correct - we
   1524      synthesize the return for the ramp in the compiler.  So suppress any
   1525      extraneous warnings during substitution.  */
   1526   suppress_warning (current_function_decl, OPT_Wreturn_type);
   1527 
   1528   /* Prepare for coroutine transformations.  */
   1529   if (!ensure_coro_initialized (kw))
   1530     return error_mark_node;
   1531 
   1532   /* Get our traits class.  */
   1533   tree traits_class = coro_get_traits_class (current_function_decl, kw);
   1534 
   1535   if (processing_template_decl
   1536       && check_for_bare_parameter_packs (expr))
   1537     return error_mark_node;
   1538 
   1539   /* Defer expansion when we must and are processing a template; see note in
   1540      finish_co_await_expr.  */
   1541   if (coro_dependent_p (expr, traits_class))
   1542     {
   1543       /* co_return expressions are always void type, regardless of the
   1544 	 expression type.  */
   1545       expr = build2_loc (kw, CO_RETURN_EXPR, void_type_node,
   1546 			 expr, NULL_TREE);
   1547       expr = maybe_cleanup_point_expr_void (expr);
   1548       return add_stmt (expr);
   1549     }
   1550 
   1551   if (!coro_promise_type_found_p (current_function_decl, kw))
   1552     return error_mark_node;
   1553 
   1554   /* Suppress -Wreturn-type for co_return, we need to check indirectly
   1555      whether the promise type has a suitable return_void/return_value.  */
   1556   suppress_warning (current_function_decl, OPT_Wreturn_type);
   1557 
   1558   if (!processing_template_decl && warn_sequence_point)
   1559     verify_sequence_points (expr);
   1560 
   1561   if (expr)
   1562     {
   1563       /* If we had an id-expression obfuscated by force_paren_expr, we need
   1564 	 to undo it so we can try to treat it as an rvalue below.  */
   1565       expr = maybe_undo_parenthesized_ref (expr);
   1566 
   1567       if (error_operand_p (expr))
   1568 	return error_mark_node;
   1569     }
   1570 
   1571   /* If the promise object doesn't have the correct return call then
   1572      there's a mis-match between the co_return <expr> and this.  */
   1573   tree co_ret_call = error_mark_node;
   1574   if (expr == NULL_TREE || VOID_TYPE_P (TREE_TYPE (expr)))
   1575     co_ret_call
   1576       = get_coroutine_return_void_expr (current_function_decl, kw, true);
   1577   else
   1578     {
   1579       /* [class.copy.elision] / 3.
   1580 	 An implicitly movable entity is a variable of automatic storage
   1581 	 duration that is either a non-volatile object or an rvalue reference
   1582 	 to a non-volatile object type.  For such objects in the context of
   1583 	 the co_return, the overload resolution should be carried out first
   1584 	 treating the object as an rvalue, if that fails, then we fall back
   1585 	 to regular overload resolution.  */
   1586 
   1587       tree arg = expr;
   1588       if (tree moved = treat_lvalue_as_rvalue_p (expr, /*return*/true))
   1589 	arg = moved;
   1590 
   1591       releasing_vec args = make_tree_vector_single (arg);
   1592       co_ret_call
   1593 	= coro_build_promise_expression (current_function_decl, NULL,
   1594 					 coro_return_value_identifier, kw,
   1595 					 &args, /*musthave=*/true);
   1596     }
   1597 
   1598   /* Makes no sense for a co-routine really. */
   1599   if (TREE_THIS_VOLATILE (current_function_decl))
   1600     warning_at (kw, 0,
   1601 		"function declared %<noreturn%> has a"
   1602 		" %<co_return%> statement");
   1603 
   1604   expr = build2_loc (kw, CO_RETURN_EXPR, void_type_node, expr, co_ret_call);
   1605   expr = maybe_cleanup_point_expr_void (expr);
   1606   return add_stmt (expr);
   1607 }
   1608 
   1609 /* We need to validate the arguments to __builtin_coro_promise, since the
   1610    second two must be constant, and the builtins machinery doesn't seem to
   1611    deal with that properly.  */
   1612 
   1613 tree
   1614 coro_validate_builtin_call (tree call, tsubst_flags_t)
   1615 {
   1616   tree fn = TREE_OPERAND (CALL_EXPR_FN (call), 0);
   1617 
   1618   gcc_checking_assert (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL);
   1619   switch (DECL_FUNCTION_CODE (fn))
   1620     {
   1621     default:
   1622       return call;
   1623 
   1624     case BUILT_IN_CORO_PROMISE:
   1625       {
   1626 	/* Argument 0 is already checked by the normal built-in machinery
   1627 	   Argument 1 must be a constant of size type.  It probably makes
   1628 	   little sense if it's not a power of 2, but that isn't specified
   1629 	   formally.  */
   1630 	tree arg = CALL_EXPR_ARG (call, 1);
   1631 	location_t loc = EXPR_LOCATION (arg);
   1632 
   1633 	/* We expect alignof expressions in templates.  */
   1634 	if (TREE_CODE (arg) == ALIGNOF_EXPR)
   1635 	  ;
   1636 	else if (!TREE_CONSTANT (arg))
   1637 	  {
   1638 	    error_at (loc, "the align argument to %<__builtin_coro_promise%>"
   1639 			   " must be a constant");
   1640 	    return error_mark_node;
   1641 	  }
   1642 	/* Argument 2 is the direction - to / from handle address to promise
   1643 	   address.  */
   1644 	arg = CALL_EXPR_ARG (call, 2);
   1645 	loc = EXPR_LOCATION (arg);
   1646 	if (!TREE_CONSTANT (arg))
   1647 	  {
   1648 	    error_at (loc, "the direction argument to"
   1649 			   " %<__builtin_coro_promise%> must be a constant");
   1650 	    return error_mark_node;
   1651 	  }
   1652 	return call;
   1653 	break;
   1654       }
   1655     }
   1656 }
   1657 
   1658 /* ================= Morph and Expand. =================
   1659 
   1660    The entry point here is morph_fn_to_coro () which is called from
   1661    finish_function () when we have completed any template expansion.
   1662 
   1663    This is preceded by helper functions that implement the phases below.
   1664 
   1665    The process proceeds in four phases.
   1666 
   1667    A Initial framing.
   1668      The user's function body is wrapped in the initial and final suspend
   1669      points and we begin building the coroutine frame.
   1670      We build empty decls for the actor and destroyer functions at this
   1671      time too.
   1672      When exceptions are enabled, the user's function body will also be
   1673      wrapped in a try-catch block with the catch invoking the promise
   1674      class 'unhandled_exception' method.
   1675 
   1676    B Analysis.
   1677      The user's function body is analyzed to determine the suspend points,
   1678      if any, and to capture local variables that might persist across such
   1679      suspensions.  In most cases, it is not necessary to capture compiler
   1680      temporaries, since the tree-lowering nests the suspensions correctly.
   1681      However, in the case of a captured reference, there is a lifetime
   1682      extension to the end of the full expression - which can mean across a
   1683      suspend point in which case it must be promoted to a frame variable.
   1684 
   1685      At the conclusion of analysis, we have a conservative frame layout and
   1686      maps of the local variables to their frame entry points.
   1687 
   1688    C Build the ramp function.
   1689      Carry out the allocation for the coroutine frame (NOTE; the actual size
   1690      computation is deferred until late in the middle end to allow for future
   1691      optimizations that will be allowed to elide unused frame entries).
   1692      We build the return object.
   1693 
   1694    D Build and expand the actor and destroyer function bodies.
   1695      The destroyer is a trivial shim that sets a bit to indicate that the
   1696      destroy dispatcher should be used and then calls into the actor.
   1697 
   1698      The actor function is the implementation of the user's state machine.
   1699      The current suspend point is noted in an index.
   1700      Each suspend point is encoded as a pair of internal functions, one in
   1701      the relevant dispatcher, and one representing the suspend point.
   1702 
   1703      During this process, the user's local variables and the proxies for the
   1704      self-handle and the promise class instance are re-written to their
   1705      coroutine frame equivalents.
   1706 
   1707      The complete bodies for the ramp, actor and destroy function are passed
   1708      back to finish_function for folding and gimplification.  */
   1709 
   1710 /* Helpers to build EXPR_STMT and void-cast EXPR_STMT, common ops.  */
   1711 
   1712 static tree
   1713 coro_build_expr_stmt (tree expr, location_t loc)
   1714 {
   1715   return maybe_cleanup_point_expr_void (build_stmt (loc, EXPR_STMT, expr));
   1716 }
   1717 
   1718 static tree
   1719 coro_build_cvt_void_expr_stmt (tree expr, location_t loc)
   1720 {
   1721   tree t = build1 (CONVERT_EXPR, void_type_node, expr);
   1722   return coro_build_expr_stmt (t, loc);
   1723 }
   1724 
   1725 /* Helpers to build an artificial var, with location LOC, NAME and TYPE, in
   1726    CTX, and with initializer INIT.  */
   1727 
   1728 static tree
   1729 coro_build_artificial_var (location_t loc, tree name, tree type, tree ctx,
   1730 			   tree init)
   1731 {
   1732   tree res = build_lang_decl (VAR_DECL, name, type);
   1733   DECL_SOURCE_LOCATION (res) = loc;
   1734   DECL_CONTEXT (res) = ctx;
   1735   DECL_ARTIFICIAL (res) = true;
   1736   DECL_INITIAL (res) = init;
   1737   return res;
   1738 }
   1739 
   1740 static tree
   1741 coro_build_artificial_var (location_t loc, const char *name, tree type,
   1742 			   tree ctx, tree init)
   1743 {
   1744   return coro_build_artificial_var (loc, get_identifier (name),
   1745 				    type, ctx, init);
   1746 }
   1747 
   1748 /* Helpers for label creation:
   1749    1. Create a named label in the specified context.  */
   1750 
   1751 static tree
   1752 create_anon_label_with_ctx (location_t loc, tree ctx)
   1753 {
   1754   tree lab = build_decl (loc, LABEL_DECL, NULL_TREE, void_type_node);
   1755 
   1756   DECL_CONTEXT (lab) = ctx;
   1757   DECL_ARTIFICIAL (lab) = true;
   1758   DECL_IGNORED_P (lab) = true;
   1759   TREE_USED (lab) = true;
   1760   return lab;
   1761 }
   1762 
   1763 /*  2. Create a named label in the specified context.  */
   1764 
   1765 static tree
   1766 create_named_label_with_ctx (location_t loc, const char *name, tree ctx)
   1767 {
   1768   tree lab_id = get_identifier (name);
   1769   tree lab = define_label (loc, lab_id);
   1770   DECL_CONTEXT (lab) = ctx;
   1771   DECL_ARTIFICIAL (lab) = true;
   1772   TREE_USED (lab) = true;
   1773   return lab;
   1774 }
   1775 
   1776 struct proxy_replace
   1777 {
   1778   tree from, to;
   1779 };
   1780 
   1781 static tree
   1782 replace_proxy (tree *here, int *do_subtree, void *d)
   1783 {
   1784   proxy_replace *data = (proxy_replace *) d;
   1785 
   1786   if (*here == data->from)
   1787     {
   1788       *here = data->to;
   1789       *do_subtree = 0;
   1790     }
   1791   else
   1792     *do_subtree = 1;
   1793   return NULL_TREE;
   1794 }
   1795 
   1796 /* Support for expansion of co_await statements.  */
   1797 
   1798 struct coro_aw_data
   1799 {
   1800   tree actor_fn;   /* Decl for context.  */
   1801   tree coro_fp;    /* Frame pointer var.  */
   1802   tree resume_idx; /* This is the index var in the frame.  */
   1803   tree i_a_r_c;    /* initial suspend await_resume() was called if true.  */
   1804   tree self_h;     /* This is a handle to the current coro (frame var).  */
   1805   tree cleanup;    /* This is where to go once we complete local destroy.  */
   1806   tree cororet;    /* This is where to go if we suspend.  */
   1807   tree corocont;   /* This is where to go if we continue.  */
   1808   tree dispatch;   /* This is where we go if we restart the dispatch.  */
   1809   tree conthand;   /* This is the handle for a continuation.  */
   1810   unsigned index;  /* This is our current resume index.  */
   1811 };
   1812 
   1813 /* Lightweight search for the first await expression in tree-walk order.
   1814    returns:
   1815      The first await expression found in STMT.
   1816      NULL_TREE if there are none.
   1817    So can be used to determine if the statement needs to be processed for
   1818    awaits.  */
   1819 
   1820 static tree
   1821 co_await_find_in_subtree (tree *stmt, int *, void *d)
   1822 {
   1823   tree **p = (tree **) d;
   1824   if (TREE_CODE (*stmt) == CO_AWAIT_EXPR)
   1825     {
   1826       *p = stmt;
   1827       return *stmt;
   1828     }
   1829   return NULL_TREE;
   1830 }
   1831 
   1832 /* Starting with a statement:
   1833 
   1834    stmt => some tree containing one or more await expressions.
   1835 
   1836    We replace the statement with:
   1837    <STATEMENT_LIST> {
   1838       initialize awaitable
   1839       if (!ready)
   1840 	{
   1841 	  suspension context.
   1842 	}
   1843       resume:
   1844 	revised statement with one await expression rewritten to its
   1845 	await_resume() return value.
   1846    }
   1847 
   1848    We then recurse into the initializer and the revised statement
   1849    repeating this replacement until there are no more await expressions
   1850    in either.  */
   1851 
   1852 static tree *
   1853 expand_one_await_expression (tree *expr, tree *await_expr, void *d)
   1854 {
   1855   coro_aw_data *data = (coro_aw_data *) d;
   1856 
   1857   tree saved_statement = *expr;
   1858   tree saved_co_await = *await_expr;
   1859 
   1860   tree actor = data->actor_fn;
   1861   location_t loc = EXPR_LOCATION (*expr);
   1862   tree var = TREE_OPERAND (saved_co_await, 1);  /* frame slot. */
   1863   tree init_expr = TREE_OPERAND (saved_co_await, 2); /* initializer.  */
   1864   tree awaiter_calls = TREE_OPERAND (saved_co_await, 3);
   1865 
   1866   tree source = TREE_OPERAND (saved_co_await, 4);
   1867   bool is_final = (source
   1868 		   && TREE_INT_CST_LOW (source) == (int) FINAL_SUSPEND_POINT);
   1869 
   1870   /* Build labels for the destinations of the control flow when we are resuming
   1871      or destroying.  */
   1872   int resume_point = data->index;
   1873   char *buf = xasprintf ("destroy.%d", resume_point);
   1874   tree destroy_label = create_named_label_with_ctx (loc, buf, actor);
   1875   free (buf);
   1876   buf = xasprintf ("resume.%d", resume_point);
   1877   tree resume_label = create_named_label_with_ctx (loc, buf, actor);
   1878   free (buf);
   1879 
   1880   /* This will contain our expanded expression and replace the original
   1881      expression.  */
   1882   tree stmt_list = push_stmt_list ();
   1883   tree *await_init = NULL;
   1884 
   1885   bool needs_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var));
   1886   if (!init_expr)
   1887     needs_dtor = false; /* No need, the var's lifetime is managed elsewhere.  */
   1888   else
   1889     {
   1890       finish_expr_stmt (init_expr);
   1891       /* We have an initializer, which might itself contain await exprs.  */
   1892       await_init = tsi_stmt_ptr (tsi_last (stmt_list));
   1893     }
   1894 
   1895   /* Use the await_ready() call to test if we need to suspend.  */
   1896   tree ready_cond = TREE_VEC_ELT (awaiter_calls, 0); /* await_ready().  */
   1897   /* Convert to bool, if necessary.  */
   1898   if (TREE_CODE (TREE_TYPE (ready_cond)) != BOOLEAN_TYPE)
   1899     ready_cond = cp_convert (boolean_type_node, ready_cond,
   1900 			     tf_warning_or_error);
   1901   tree susp_if = begin_if_stmt ();
   1902   /* Be aggressive in folding here, since there are a significant number of
   1903      cases where the ready condition is constant.  */
   1904   ready_cond = invert_truthvalue_loc (loc, ready_cond);
   1905   finish_if_stmt_cond (ready_cond, susp_if);
   1906 
   1907   tree susp_idx = build_int_cst (short_unsigned_type_node, data->index);
   1908   tree r = cp_build_init_expr (data->resume_idx, susp_idx);
   1909   finish_expr_stmt (r);
   1910 
   1911   /* Find out what we have to do with the awaiter's suspend method.
   1912      [expr.await]
   1913      (5.1) If the result of await-ready is false, the coroutine is considered
   1914 	   suspended. Then:
   1915      (5.1.1) If the type of await-suspend is std::coroutine_handle<Z>,
   1916 	     await-suspend.resume() is evaluated.
   1917      (5.1.2) if the type of await-suspend is bool, await-suspend is evaluated,
   1918 	     and the coroutine is resumed if the result is false.
   1919      (5.1.3) Otherwise, await-suspend is evaluated.  */
   1920 
   1921   tree suspend = TREE_VEC_ELT (awaiter_calls, 1); /* await_suspend().  */
   1922   tree susp_type = TREE_TYPE (suspend);
   1923 
   1924   bool is_cont = false;
   1925   /* NOTE: final suspend can't resume; the "resume" label in that case
   1926      corresponds to implicit destruction.  */
   1927   if (VOID_TYPE_P (susp_type))
   1928     /* Void return - just proceed to suspend.  */
   1929     finish_expr_stmt (suspend);
   1930   else if (TREE_CODE (susp_type) == BOOLEAN_TYPE)
   1931     {
   1932       /* Boolean return, "continue" if the call returns false.  */
   1933       tree restart_if = begin_if_stmt ();
   1934       suspend = invert_truthvalue_loc (loc, suspend);
   1935       finish_if_stmt_cond (suspend, restart_if);
   1936       /* Resume - so restart the dispatcher, since we do not know if this
   1937 	 coroutine was already resumed from within await_suspend.  We must
   1938 	 exit this scope without cleanups.  */
   1939       r = build_call_expr_internal_loc (loc, IFN_CO_SUSPN, void_type_node, 1,
   1940 					build_address (data->dispatch));
   1941       /* This will eventually expand to 'goto coro.restart.dispatch'.  */
   1942       finish_expr_stmt (r);
   1943       finish_then_clause (restart_if);
   1944       finish_if_stmt (restart_if);
   1945     }
   1946   else
   1947     {
   1948       /* Handle return, save it to the continuation.  */
   1949       r = suspend;
   1950       if (!same_type_ignoring_top_level_qualifiers_p (susp_type,
   1951 						      void_coro_handle_type))
   1952 	r = build1_loc (loc, VIEW_CONVERT_EXPR, void_coro_handle_type, r);
   1953       r = cp_build_init_expr (loc, data->conthand, r);
   1954       finish_expr_stmt (r);
   1955       is_cont = true;
   1956     }
   1957 
   1958   tree d_l = build_address (destroy_label);
   1959   tree r_l = build_address (resume_label);
   1960   tree susp = build_address (data->cororet);
   1961   tree cont = build_address (data->corocont);
   1962   tree final_susp = build_int_cst (integer_type_node, is_final ? 1 : 0);
   1963 
   1964   susp_idx = build_int_cst (integer_type_node, data->index);
   1965 
   1966   tree sw = begin_switch_stmt ();
   1967 
   1968   r = build_call_expr_internal_loc (loc, IFN_CO_YIELD, integer_type_node, 5,
   1969 				    susp_idx, final_susp, r_l, d_l,
   1970 				    data->coro_fp);
   1971   finish_switch_cond (r, sw);
   1972   r = build_case_label (integer_zero_node, NULL_TREE,
   1973 			create_anon_label_with_ctx (loc, actor));
   1974   add_stmt (r); /* case 0: */
   1975   /* Implement the suspend, a scope exit without clean ups.  */
   1976   r = build_call_expr_internal_loc (loc, IFN_CO_SUSPN, void_type_node, 1,
   1977 				    is_cont ? cont : susp);
   1978   finish_expr_stmt (r); /* This will eventually expand to 'goto return'.  */
   1979   r = build_case_label (integer_one_node, NULL_TREE,
   1980 			create_anon_label_with_ctx (loc, actor));
   1981   add_stmt (r); /* case 1:  */
   1982   add_stmt (build_stmt (loc, GOTO_EXPR, resume_label)); /*  goto resume;  */
   1983   r = build_case_label (NULL_TREE, NULL_TREE,
   1984 			create_anon_label_with_ctx (loc, actor));
   1985   add_stmt (r); /* default:;  */
   1986   add_stmt (build_stmt (loc, GOTO_EXPR, destroy_label)); /* goto destroy;  */
   1987 
   1988   finish_switch_stmt (sw);
   1989   add_stmt (build_stmt (loc, LABEL_EXPR, destroy_label));
   1990   if (needs_dtor)
   1991     finish_expr_stmt (build_cleanup (var));
   1992   add_stmt (build_stmt (loc, GOTO_EXPR, data->cleanup));
   1993 
   1994   finish_then_clause (susp_if);
   1995   finish_if_stmt (susp_if);
   1996 
   1997   /* Resume point.  */
   1998   add_stmt (build_stmt (loc, LABEL_EXPR, resume_label));
   1999 
   2000   /* This will produce the value (if one is provided) from the co_await
   2001      expression.  */
   2002   tree resume_call = TREE_VEC_ELT (awaiter_calls, 2); /* await_resume().  */
   2003   if (REFERENCE_REF_P (resume_call))
   2004     /* Sink to await_resume call_expr.  */
   2005     resume_call = TREE_OPERAND (resume_call, 0);
   2006 
   2007   *await_expr = resume_call; /* Replace the co_await expr with its result.  */
   2008   append_to_statement_list_force (saved_statement, &stmt_list);
   2009   /* Get a pointer to the revised statement.  */
   2010   tree *revised = tsi_stmt_ptr (tsi_last (stmt_list));
   2011   if (needs_dtor)
   2012     finish_expr_stmt (build_cleanup (var));
   2013   data->index += 2;
   2014 
   2015   /* Replace the original expression with the expansion.  */
   2016   *expr = pop_stmt_list (stmt_list);
   2017 
   2018   /* Now, if the awaitable had an initializer, expand any awaits that might
   2019      be embedded in it.  */
   2020   tree *aw_expr_ptr;
   2021   if (await_init &&
   2022       cp_walk_tree (await_init, co_await_find_in_subtree, &aw_expr_ptr, NULL))
   2023     expand_one_await_expression (await_init, aw_expr_ptr, d);
   2024 
   2025   /* Expand any more await expressions in the original statement.  */
   2026   if (cp_walk_tree (revised, co_await_find_in_subtree, &aw_expr_ptr, NULL))
   2027     expand_one_await_expression (revised, aw_expr_ptr, d);
   2028 
   2029   return NULL;
   2030 }
   2031 
   2032 /* Check to see if a statement contains at least one await expression, if
   2033    so, then process that.  */
   2034 
   2035 static tree
   2036 process_one_statement (tree *stmt, void *d)
   2037 {
   2038   tree *aw_expr_ptr;
   2039   if (cp_walk_tree (stmt, co_await_find_in_subtree, &aw_expr_ptr, NULL))
   2040     expand_one_await_expression (stmt, aw_expr_ptr, d);
   2041   return NULL_TREE;
   2042 }
   2043 
   2044 static tree
   2045 await_statement_expander (tree *stmt, int *do_subtree, void *d)
   2046 {
   2047   tree res = NULL_TREE;
   2048 
   2049   /* Process a statement at a time.  */
   2050   if (STATEMENT_CLASS_P (*stmt)
   2051       || TREE_CODE (*stmt) == BIND_EXPR
   2052       || TREE_CODE (*stmt) == CLEANUP_POINT_EXPR)
   2053     return NULL_TREE; /* Just process the sub-trees.  */
   2054   else if (TREE_CODE (*stmt) == STATEMENT_LIST)
   2055     {
   2056       for (tree &s : tsi_range (*stmt))
   2057 	{
   2058 	  res = cp_walk_tree (&s, await_statement_expander,
   2059 			      d, NULL);
   2060 	  if (res)
   2061 	    return res;
   2062 	}
   2063       *do_subtree = 0; /* Done subtrees.  */
   2064     }
   2065   else if (EXPR_P (*stmt))
   2066     {
   2067       process_one_statement (stmt, d);
   2068       *do_subtree = 0; /* Done subtrees.  */
   2069     }
   2070 
   2071   /* Continue statement walk, where required.  */
   2072   return res;
   2073 }
   2074 
   2075 /* Suspend point hash_map.  */
   2076 
   2077 struct suspend_point_info
   2078 {
   2079   /* coro frame field type.  */
   2080   tree awaitable_type;
   2081   /* coro frame field name.  */
   2082   tree await_field_id;
   2083 };
   2084 
   2085 struct await_xform_data
   2086 {
   2087   tree actor_fn;   /* Decl for context.  */
   2088   tree actor_frame;
   2089   hash_map<tree, suspend_point_info> *suspend_points;
   2090 };
   2091 
   2092 /* When we built the await expressions, we didn't know the coro frame
   2093    layout, therefore no idea where to find the promise or where to put
   2094    the awaitables.  Now we know these things, fill them in.  */
   2095 
   2096 static tree
   2097 transform_await_expr (tree await_expr, await_xform_data *xform)
   2098 {
   2099   suspend_point_info *si = xform->suspend_points->get (await_expr);
   2100   location_t loc = EXPR_LOCATION (await_expr);
   2101   if (!si)
   2102     {
   2103       error_at (loc, "no suspend point info for %qD", await_expr);
   2104       return error_mark_node;
   2105     }
   2106 
   2107   /* So, on entry, we have:
   2108      in : CO_AWAIT_EXPR (a, e_proxy, o, awr_call_vector, mode)
   2109 	  We no longer need a [it had diagnostic value, maybe?]
   2110 	  We need to replace the e_proxy in the awr_call.  */
   2111 
   2112   tree coro_frame_type = TREE_TYPE (xform->actor_frame);
   2113 
   2114   /* If we have a frame var for the awaitable, get a reference to it.  */
   2115   proxy_replace data;
   2116   if (si->await_field_id)
   2117     {
   2118       tree as_m
   2119 	 = lookup_member (coro_frame_type, si->await_field_id,
   2120 			  /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
   2121       tree as = build_class_member_access_expr (xform->actor_frame, as_m,
   2122 						NULL_TREE, true,
   2123 						tf_warning_or_error);
   2124 
   2125       /* Replace references to the instance proxy with the frame entry now
   2126 	 computed.  */
   2127       data.from = TREE_OPERAND (await_expr, 1);
   2128       data.to = as;
   2129       cp_walk_tree (&await_expr, replace_proxy, &data, NULL);
   2130 
   2131       /* .. and replace.  */
   2132       TREE_OPERAND (await_expr, 1) = as;
   2133     }
   2134 
   2135   return await_expr;
   2136 }
   2137 
   2138 /* A wrapper for the transform_await_expr function so that it can be a
   2139    callback from cp_walk_tree.  */
   2140 
   2141 static tree
   2142 transform_await_wrapper (tree *stmt, int *do_subtree, void *d)
   2143 {
   2144   /* Set actor function as new DECL_CONTEXT of label_decl.  */
   2145   struct await_xform_data *xform = (struct await_xform_data *) d;
   2146   if (TREE_CODE (*stmt) == LABEL_DECL
   2147       && DECL_CONTEXT (*stmt) != xform->actor_fn)
   2148     DECL_CONTEXT (*stmt) = xform->actor_fn;
   2149 
   2150   /* We should have already lowered co_yields to their co_await.  */
   2151   gcc_checking_assert (TREE_CODE (*stmt) != CO_YIELD_EXPR);
   2152   if (TREE_CODE (*stmt) != CO_AWAIT_EXPR)
   2153     return NULL_TREE;
   2154 
   2155   tree await_expr = *stmt;
   2156   *stmt = transform_await_expr (await_expr, xform);
   2157   if (*stmt == error_mark_node)
   2158     *do_subtree = 0;
   2159   return NULL_TREE;
   2160 }
   2161 
   2162 /* This caches information that we determine about function params,
   2163    their uses and copies in the coroutine frame.  */
   2164 
   2165 struct param_info
   2166 {
   2167   tree field_id;     /* The name of the copy in the coroutine frame.  */
   2168   tree copy_var;     /* The local var proxy for the frame copy.  */
   2169   vec<tree *> *body_uses; /* Worklist of uses, void if there are none.  */
   2170   tree frame_type;   /* The type used to represent this parm in the frame.  */
   2171   tree orig_type;    /* The original type of the parm (not as passed).  */
   2172   tree guard_var;    /* If we need a DTOR on exception, this bool guards it.  */
   2173   tree fr_copy_dtor; /* If we need a DTOR on exception, this is it.  */
   2174   bool by_ref;       /* Was passed by reference.  */
   2175   bool pt_ref;       /* Was a pointer to object.  */
   2176   bool rv_ref;       /* Was an rvalue ref.  */
   2177   bool trivial_dtor; /* The frame type has a trivial DTOR.  */
   2178   bool this_ptr;     /* Is 'this' */
   2179   bool lambda_cobj;  /* Lambda capture object */
   2180 };
   2181 
   2182 struct local_var_info
   2183 {
   2184   tree field_id;
   2185   tree field_idx;
   2186   tree frame_type;
   2187   bool is_lambda_capture;
   2188   bool is_static;
   2189   bool has_value_expr_p;
   2190   location_t def_loc;
   2191 };
   2192 
   2193 /* For figuring out what local variable usage we have.  */
   2194 struct local_vars_transform
   2195 {
   2196   tree context;
   2197   tree actor_frame;
   2198   tree coro_frame_type;
   2199   location_t loc;
   2200   hash_map<tree, local_var_info> *local_var_uses;
   2201 };
   2202 
   2203 static tree
   2204 transform_local_var_uses (tree *stmt, int *do_subtree, void *d)
   2205 {
   2206   local_vars_transform *lvd = (local_vars_transform *) d;
   2207 
   2208   /* For each var in this bind expr (that has a frame id, which means it was
   2209      accessed), build a frame reference and add it as the DECL_VALUE_EXPR.  */
   2210 
   2211   if (TREE_CODE (*stmt) == BIND_EXPR)
   2212     {
   2213       tree lvar;
   2214       for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
   2215 	   lvar = DECL_CHAIN (lvar))
   2216 	{
   2217 	  bool existed;
   2218 	  local_var_info &local_var
   2219 	    = lvd->local_var_uses->get_or_insert (lvar, &existed);
   2220 	  gcc_checking_assert (existed);
   2221 
   2222 	  /* Re-write the variable's context to be in the actor func.  */
   2223 	  DECL_CONTEXT (lvar) = lvd->context;
   2224 
   2225 	  /* For capture proxies, this could include the decl value expr.  */
   2226 	  if (local_var.is_lambda_capture || local_var.has_value_expr_p)
   2227 	    continue; /* No frame entry for this.  */
   2228 
   2229 	  /* TODO: implement selective generation of fields when vars are
   2230 	     known not-used.  */
   2231 	  if (local_var.field_id == NULL_TREE)
   2232 	    continue; /* Wasn't used.  */
   2233 
   2234 	  tree fld_ref
   2235 	    = lookup_member (lvd->coro_frame_type, local_var.field_id,
   2236 			     /*protect=*/1, /*want_type=*/0,
   2237 			     tf_warning_or_error);
   2238 	  tree fld_idx = build3 (COMPONENT_REF, TREE_TYPE (lvar),
   2239 				 lvd->actor_frame, fld_ref, NULL_TREE);
   2240 	  local_var.field_idx = fld_idx;
   2241 	  SET_DECL_VALUE_EXPR (lvar, fld_idx);
   2242 	  DECL_HAS_VALUE_EXPR_P (lvar) = true;
   2243 	}
   2244       cp_walk_tree (&BIND_EXPR_BODY (*stmt), transform_local_var_uses, d, NULL);
   2245       *do_subtree = 0; /* We've done the body already.  */
   2246       return NULL_TREE;
   2247     }
   2248   return NULL_TREE;
   2249 }
   2250 
   2251 /* A helper to build the frame DTOR.
   2252    [dcl.fct.def.coroutine] / 12
   2253    The deallocation functions name is looked up in the scope of the promise
   2254    type.  If this lookup fails, the deallocation functions name is looked up
   2255    in the global scope.  If deallocation function lookup finds both a usual
   2256    deallocation function with only a pointer parameter and a usual
   2257    deallocation function with both a pointer parameter and a size parameter,
   2258    then the selected deallocation function shall be the one with two
   2259    parameters.  Otherwise, the selected deallocation function shall be the
   2260    function with one parameter.  If no usual deallocation function is found
   2261    the program is ill-formed.  The selected deallocation function shall be
   2262    called with the address of the block of storage to be reclaimed as its
   2263    first argument.  If a deallocation function with a parameter of type
   2264    std::size_t is used, the size of the block is passed as the corresponding
   2265    argument.  */
   2266 
   2267 static tree
   2268 coro_get_frame_dtor (tree coro_fp, tree orig, tree frame_size,
   2269 		     tree promise_type, location_t loc)
   2270 {
   2271   tree del_coro_fr = NULL_TREE;
   2272   tree frame_arg = build1 (CONVERT_EXPR, ptr_type_node, coro_fp);
   2273   tree delname = ovl_op_identifier (false, DELETE_EXPR);
   2274   tree fns = lookup_promise_method (orig, delname, loc,
   2275 					/*musthave=*/false);
   2276   if (fns && BASELINK_P (fns))
   2277     {
   2278       /* Look for sized version first, since this takes precedence.  */
   2279       vec<tree, va_gc> *args = make_tree_vector ();
   2280       vec_safe_push (args, frame_arg);
   2281       vec_safe_push (args, frame_size);
   2282       tree dummy_promise = build_dummy_object (promise_type);
   2283 
   2284       /* It's OK to fail for this one... */
   2285       del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
   2286 					   NULL_TREE, LOOKUP_NORMAL, NULL,
   2287 					   tf_none);
   2288 
   2289       if (!del_coro_fr || del_coro_fr == error_mark_node)
   2290 	{
   2291 	  release_tree_vector (args);
   2292 	  args = make_tree_vector_single (frame_arg);
   2293 	  del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
   2294 					       NULL_TREE, LOOKUP_NORMAL, NULL,
   2295 					       tf_none);
   2296 	}
   2297 
   2298       /* But one of them must succeed, or the program is ill-formed.  */
   2299       if (!del_coro_fr || del_coro_fr == error_mark_node)
   2300 	{
   2301 	  error_at (loc, "%qE is provided by %qT but is not usable with"
   2302 		  " the function signature %qD", delname, promise_type, orig);
   2303 	  del_coro_fr = error_mark_node;
   2304 	}
   2305     }
   2306   else
   2307     {
   2308       del_coro_fr = build_op_delete_call (DELETE_EXPR, frame_arg, frame_size,
   2309 					  /*global_p=*/true, /*placement=*/NULL,
   2310 					  /*alloc_fn=*/NULL,
   2311 					  tf_warning_or_error);
   2312       if (!del_coro_fr || del_coro_fr == error_mark_node)
   2313 	del_coro_fr = error_mark_node;
   2314     }
   2315   return del_coro_fr;
   2316 }
   2317 
   2318 /* The actor transform.  */
   2319 
   2320 static void
   2321 build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
   2322 		tree orig, hash_map<tree, local_var_info> *local_var_uses,
   2323 		hash_map<tree, suspend_point_info> *suspend_points,
   2324 		vec<tree, va_gc> *param_dtor_list,
   2325 		tree resume_idx_var, unsigned body_count, tree frame_size)
   2326 {
   2327   verify_stmt_tree (fnbody);
   2328   /* Some things we inherit from the original function.  */
   2329   tree promise_type = get_coroutine_promise_type (orig);
   2330   tree promise_proxy = get_coroutine_promise_proxy (orig);
   2331 
   2332   /* One param, the coro frame pointer.  */
   2333   tree actor_fp = DECL_ARGUMENTS (actor);
   2334 
   2335   /* We have a definition here.  */
   2336   TREE_STATIC (actor) = 1;
   2337 
   2338   tree actor_outer = push_stmt_list ();
   2339   current_stmt_tree ()->stmts_are_full_exprs_p = 1;
   2340   tree stmt = begin_compound_stmt (BCS_FN_BODY);
   2341 
   2342   tree actor_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
   2343   tree top_block = make_node (BLOCK);
   2344   BIND_EXPR_BLOCK (actor_bind) = top_block;
   2345 
   2346   tree continuation = coro_build_artificial_var (loc, coro_actor_continue_id,
   2347 						 void_coro_handle_type, actor,
   2348 						 NULL_TREE);
   2349 
   2350   BIND_EXPR_VARS (actor_bind) = continuation;
   2351   BLOCK_VARS (top_block) = BIND_EXPR_VARS (actor_bind) ;
   2352 
   2353   /* Link in the block associated with the outer scope of the re-written
   2354      function body.  */
   2355   tree first = expr_first (fnbody);
   2356   gcc_checking_assert (first && TREE_CODE (first) == BIND_EXPR);
   2357   tree block = BIND_EXPR_BLOCK (first);
   2358   gcc_checking_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
   2359   gcc_checking_assert (BLOCK_CHAIN (block) == NULL_TREE);
   2360   BLOCK_SUPERCONTEXT (block) = top_block;
   2361   BLOCK_SUBBLOCKS (top_block) = block;
   2362 
   2363   add_stmt (actor_bind);
   2364   tree actor_body = push_stmt_list ();
   2365 
   2366   /* The entry point for the actor code from the ramp.  */
   2367   tree actor_begin_label
   2368     = create_named_label_with_ctx (loc, "actor.begin", actor);
   2369   tree actor_frame = build1_loc (loc, INDIRECT_REF, coro_frame_type, actor_fp);
   2370 
   2371   /* Declare the continuation handle.  */
   2372   add_decl_expr (continuation);
   2373 
   2374   /* Re-write local vars, similarly.  */
   2375   local_vars_transform xform_vars_data
   2376     = {actor, actor_frame, coro_frame_type, loc, local_var_uses};
   2377   cp_walk_tree (&fnbody, transform_local_var_uses, &xform_vars_data, NULL);
   2378 
   2379   tree rat_field = lookup_member (coro_frame_type, coro_resume_index_id,
   2380 				  1, 0, tf_warning_or_error);
   2381   tree rat = build3 (COMPONENT_REF, short_unsigned_type_node, actor_frame,
   2382 		     rat_field, NULL_TREE);
   2383 
   2384   tree ret_label
   2385     = create_named_label_with_ctx (loc, "actor.suspend.ret", actor);
   2386 
   2387   tree continue_label
   2388     = create_named_label_with_ctx (loc, "actor.continue.ret", actor);
   2389 
   2390   /* Build the dispatcher; for each await expression there is an odd entry
   2391      corresponding to the destruction action and an even entry for the resume
   2392      one:
   2393      if (resume index is odd)
   2394 	{
   2395 	  switch (resume index)
   2396 	   case 1:
   2397 	     goto cleanup.
   2398 	   case ... odd suspension point number
   2399 	     .CO_ACTOR (... odd suspension point number)
   2400 	     break;
   2401 	   default:
   2402 	     break;
   2403 	}
   2404       else
   2405 	{
   2406 	  coro.restart.dispatch:
   2407 	   case 0:
   2408 	     goto start.
   2409 	   case ... even suspension point number
   2410 	     .CO_ACTOR (... even suspension point number)
   2411 	     break;
   2412 	   default:
   2413 	     break;
   2414 	}
   2415     we should not get here unless something is broken badly.
   2416      __builtin_trap ();
   2417 */
   2418   tree lsb_if = begin_if_stmt ();
   2419   tree chkb0 = build2 (BIT_AND_EXPR, short_unsigned_type_node, rat,
   2420 		       build_int_cst (short_unsigned_type_node, 1));
   2421   chkb0 = build2 (NE_EXPR, short_unsigned_type_node, chkb0,
   2422 		  build_int_cst (short_unsigned_type_node, 0));
   2423   finish_if_stmt_cond (chkb0, lsb_if);
   2424 
   2425   tree destroy_dispatcher = begin_switch_stmt ();
   2426   finish_switch_cond (rat, destroy_dispatcher);
   2427 
   2428   /* The destroy point numbered #1 is special, in that it is reached from a
   2429      coroutine that is suspended after re-throwing from unhandled_exception().
   2430      This label just invokes the cleanup of promise, param copies and the
   2431      frame itself.  */
   2432   tree del_promise_label
   2433     = create_named_label_with_ctx (loc, "coro.delete.promise", actor);
   2434   tree b = build_case_label (build_int_cst (short_unsigned_type_node, 1),
   2435 			     NULL_TREE, create_anon_label_with_ctx (loc, actor));
   2436   add_stmt (b);
   2437   add_stmt (build_stmt (loc, GOTO_EXPR, del_promise_label));
   2438 
   2439   short unsigned lab_num = 3;
   2440   for (unsigned destr_pt = 0; destr_pt < body_count; destr_pt++)
   2441     {
   2442       tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
   2443       b = build_case_label (l_num, NULL_TREE,
   2444 			    create_anon_label_with_ctx (loc, actor));
   2445       add_stmt (b);
   2446       b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
   2447 					l_num);
   2448       finish_expr_stmt (b);
   2449       finish_break_stmt ();
   2450       lab_num += 2;
   2451     }
   2452   b = build_case_label (NULL_TREE, NULL_TREE,
   2453 			create_anon_label_with_ctx (loc, actor));
   2454   add_stmt (b);
   2455   finish_break_stmt ();
   2456 
   2457   /* Finish the destroy dispatcher.  */
   2458   finish_switch_stmt (destroy_dispatcher);
   2459 
   2460   finish_then_clause (lsb_if);
   2461   begin_else_clause (lsb_if);
   2462 
   2463   /* For the case of a boolean await_resume () that returns 'true' we should
   2464      restart the dispatch, since we cannot know if additional resumes were
   2465      executed from within the await_suspend function.  */
   2466   tree restart_dispatch_label
   2467     = create_named_label_with_ctx (loc, "coro.restart.dispatch", actor);
   2468   add_stmt (build_stmt (loc, LABEL_EXPR, restart_dispatch_label));
   2469 
   2470   tree dispatcher = begin_switch_stmt ();
   2471   finish_switch_cond (rat, dispatcher);
   2472   b = build_case_label (build_int_cst (short_unsigned_type_node, 0), NULL_TREE,
   2473 			create_anon_label_with_ctx (loc, actor));
   2474   add_stmt (b);
   2475   add_stmt (build_stmt (loc, GOTO_EXPR, actor_begin_label));
   2476 
   2477   lab_num = 2;
   2478   /* The final resume should be made to hit the default (trap, UB) entry
   2479      although it will be unreachable via the normal entry point, since that
   2480      is set to NULL on reaching final suspend.  */
   2481   for (unsigned resu_pt = 0; resu_pt < body_count; resu_pt++)
   2482     {
   2483       tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
   2484       b = build_case_label (l_num, NULL_TREE,
   2485 			    create_anon_label_with_ctx (loc, actor));
   2486       add_stmt (b);
   2487       b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
   2488 					l_num);
   2489       finish_expr_stmt (b);
   2490       finish_break_stmt ();
   2491       lab_num += 2;
   2492     }
   2493   b = build_case_label (NULL_TREE, NULL_TREE,
   2494 			create_anon_label_with_ctx (loc, actor));
   2495   add_stmt (b);
   2496   finish_break_stmt ();
   2497 
   2498   /* Finish the resume dispatcher.  */
   2499   finish_switch_stmt (dispatcher);
   2500   finish_else_clause (lsb_if);
   2501 
   2502   finish_if_stmt (lsb_if);
   2503 
   2504   /* If we reach here then we've hit UB.  */
   2505   tree t = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
   2506   finish_expr_stmt (t);
   2507 
   2508   /* Now we start building the rewritten function body.  */
   2509   add_stmt (build_stmt (loc, LABEL_EXPR, actor_begin_label));
   2510 
   2511   /* actor's coroutine 'self handle'.  */
   2512   tree ash_m = lookup_member (coro_frame_type, coro_self_handle_id, 1,
   2513 			      0, tf_warning_or_error);
   2514   tree ash = build_class_member_access_expr (actor_frame, ash_m, NULL_TREE,
   2515 					     false, tf_warning_or_error);
   2516   /* So construct the self-handle from the frame address.  */
   2517   tree hfa_m = get_coroutine_from_address (orig);
   2518   /* Should have been set earlier by coro_promise_type_found_p.  */
   2519   gcc_assert (hfa_m);
   2520 
   2521   tree r = build1 (CONVERT_EXPR, build_pointer_type (void_type_node), actor_fp);
   2522   vec<tree, va_gc> *args = make_tree_vector_single (r);
   2523   tree hfa = build_new_method_call (ash, hfa_m, &args, NULL_TREE, LOOKUP_NORMAL,
   2524 				    NULL, tf_warning_or_error);
   2525   r = cp_build_init_expr (ash, hfa);
   2526   r = coro_build_cvt_void_expr_stmt (r, loc);
   2527   add_stmt (r);
   2528   release_tree_vector (args);
   2529 
   2530   /* Now we know the real promise, and enough about the frame layout to
   2531      decide where to put things.  */
   2532 
   2533   await_xform_data xform = {actor, actor_frame, suspend_points};
   2534 
   2535   /* Transform the await expressions in the function body.  Only do each
   2536      await tree once!  */
   2537   hash_set<tree> pset;
   2538   cp_walk_tree (&fnbody, transform_await_wrapper, &xform, &pset);
   2539 
   2540   /* Add in our function body with the co_returns rewritten to final form.  */
   2541   add_stmt (fnbody);
   2542 
   2543   /* now do the tail of the function.  */
   2544   r = build_stmt (loc, LABEL_EXPR, del_promise_label);
   2545   add_stmt (r);
   2546 
   2547   /* Destructors for the things we built explicitly.  */
   2548   if (tree c = cxx_maybe_build_cleanup (promise_proxy, tf_warning_or_error))
   2549     add_stmt (c);
   2550 
   2551   tree del_frame_label
   2552     = create_named_label_with_ctx (loc, "coro.delete.frame", actor);
   2553   r = build_stmt (loc, LABEL_EXPR, del_frame_label);
   2554   add_stmt (r);
   2555 
   2556   /* Here deallocate the frame (if we allocated it), which we will have at
   2557      present.  */
   2558   tree fnf_m
   2559     = lookup_member (coro_frame_type, coro_frame_needs_free_id, 1,
   2560 		     0, tf_warning_or_error);
   2561   tree fnf2_x = build_class_member_access_expr (actor_frame, fnf_m, NULL_TREE,
   2562 						false, tf_warning_or_error);
   2563 
   2564   tree need_free_if = begin_if_stmt ();
   2565   fnf2_x = build1 (CONVERT_EXPR, integer_type_node, fnf2_x);
   2566   tree cmp = build2 (NE_EXPR, integer_type_node, fnf2_x, integer_zero_node);
   2567   finish_if_stmt_cond (cmp, need_free_if);
   2568   if (param_dtor_list != NULL)
   2569     {
   2570       int i;
   2571       tree pid;
   2572       FOR_EACH_VEC_ELT (*param_dtor_list, i, pid)
   2573 	{
   2574 	  tree m
   2575 	    = lookup_member (coro_frame_type, pid, 1, 0, tf_warning_or_error);
   2576 	  tree a = build_class_member_access_expr (actor_frame, m, NULL_TREE,
   2577 						   false, tf_warning_or_error);
   2578 	  if (tree dtor = cxx_maybe_build_cleanup (a, tf_warning_or_error))
   2579 	    add_stmt (dtor);
   2580 	}
   2581     }
   2582 
   2583   /* Build the frame DTOR.  */
   2584   tree del_coro_fr = coro_get_frame_dtor (actor_fp, orig, frame_size,
   2585 					  promise_type, loc);
   2586   finish_expr_stmt (del_coro_fr);
   2587   finish_then_clause (need_free_if);
   2588   tree scope = IF_SCOPE (need_free_if);
   2589   IF_SCOPE (need_free_if) = NULL;
   2590   r = do_poplevel (scope);
   2591   add_stmt (r);
   2592 
   2593   /* done.  */
   2594   r = build_stmt (loc, RETURN_EXPR, NULL);
   2595   suppress_warning (r); /* We don't want a warning about this.  */
   2596   r = maybe_cleanup_point_expr_void (r);
   2597   add_stmt (r);
   2598 
   2599   /* This is the suspend return point.  */
   2600   r = build_stmt (loc, LABEL_EXPR, ret_label);
   2601   add_stmt (r);
   2602 
   2603   r = build_stmt (loc, RETURN_EXPR, NULL);
   2604   suppress_warning (r); /* We don't want a warning about this.  */
   2605   r = maybe_cleanup_point_expr_void (r);
   2606   add_stmt (r);
   2607 
   2608   /* This is the 'continuation' return point.  For such a case we have a coro
   2609      handle (from the await_suspend() call) and we want handle.resume() to
   2610      execute as a tailcall allowing arbitrary chaining of coroutines.  */
   2611   r = build_stmt (loc, LABEL_EXPR, continue_label);
   2612   add_stmt (r);
   2613 
   2614   /* Should have been set earlier by the coro_initialized code.  */
   2615   gcc_assert (void_coro_handle_address);
   2616 
   2617   /* We want to force a tail-call even for O0/1, so this expands the resume
   2618      call into its underlying implementation.  */
   2619   tree addr = build_new_method_call (continuation, void_coro_handle_address,
   2620 				     NULL, NULL_TREE, LOOKUP_NORMAL, NULL,
   2621 				     tf_warning_or_error);
   2622   tree resume = build_call_expr_loc
   2623     (loc, builtin_decl_explicit (BUILT_IN_CORO_RESUME), 1, addr);
   2624 
   2625   /* In order to support an arbitrary number of coroutine continuations,
   2626      we must tail call them.  However, some targets do not support indirect
   2627      tail calls to arbitrary callees.  See PR94359.  */
   2628   CALL_EXPR_TAILCALL (resume) = true;
   2629   resume = coro_build_cvt_void_expr_stmt (resume, loc);
   2630   add_stmt (resume);
   2631 
   2632   r = build_stmt (loc, RETURN_EXPR, NULL);
   2633   gcc_checking_assert (maybe_cleanup_point_expr_void (r) == r);
   2634   add_stmt (r);
   2635 
   2636   /* We've now rewritten the tree and added the initial and final
   2637      co_awaits.  Now pass over the tree and expand the co_awaits.  */
   2638 
   2639   coro_aw_data data = {actor, actor_fp, resume_idx_var, NULL_TREE,
   2640 		       ash, del_promise_label, ret_label,
   2641 		       continue_label, restart_dispatch_label, continuation, 2};
   2642   cp_walk_tree (&actor_body, await_statement_expander, &data, NULL);
   2643 
   2644   BIND_EXPR_BODY (actor_bind) = pop_stmt_list (actor_body);
   2645   TREE_SIDE_EFFECTS (actor_bind) = true;
   2646 
   2647   finish_compound_stmt (stmt);
   2648   DECL_SAVED_TREE (actor) = pop_stmt_list (actor_outer);
   2649   verify_stmt_tree (DECL_SAVED_TREE (actor));
   2650 }
   2651 
   2652 /* The prototype 'destroy' function :
   2653    frame->__Coro_resume_index |= 1;
   2654    actor (frame);  */
   2655 
   2656 static void
   2657 build_destroy_fn (location_t loc, tree coro_frame_type, tree destroy,
   2658 		  tree actor)
   2659 {
   2660   /* One param, the coro frame pointer.  */
   2661   tree destr_fp = DECL_ARGUMENTS (destroy);
   2662 
   2663   /* We have a definition here.  */
   2664   TREE_STATIC (destroy) = 1;
   2665 
   2666   tree destr_outer = push_stmt_list ();
   2667   current_stmt_tree ()->stmts_are_full_exprs_p = 1;
   2668   tree dstr_stmt = begin_compound_stmt (BCS_FN_BODY);
   2669 
   2670   tree destr_frame = build1 (INDIRECT_REF, coro_frame_type, destr_fp);
   2671 
   2672   tree rat_field = lookup_member (coro_frame_type, coro_resume_index_id,
   2673 				  1, 0, tf_warning_or_error);
   2674   tree rat = build3 (COMPONENT_REF, short_unsigned_type_node,
   2675 			 destr_frame, rat_field, NULL_TREE);
   2676 
   2677   /* _resume_at |= 1 */
   2678   tree dstr_idx = build2 (BIT_IOR_EXPR, short_unsigned_type_node, rat,
   2679 			  build_int_cst (short_unsigned_type_node, 1));
   2680   tree r = build2 (MODIFY_EXPR, short_unsigned_type_node, rat, dstr_idx);
   2681   r = coro_build_cvt_void_expr_stmt (r, loc);
   2682   add_stmt (r);
   2683 
   2684   /* So .. call the actor ..  */
   2685   r = build_call_expr_loc (loc, actor, 1, destr_fp);
   2686   r = coro_build_cvt_void_expr_stmt (r, loc);
   2687   add_stmt (r);
   2688 
   2689   /* done. */
   2690   r = build_stmt (loc, RETURN_EXPR, NULL);
   2691   r = maybe_cleanup_point_expr_void (r);
   2692   add_stmt (r);
   2693 
   2694   finish_compound_stmt (dstr_stmt);
   2695   DECL_SAVED_TREE (destroy) = pop_stmt_list (destr_outer);
   2696 }
   2697 
   2698 /* Helper that returns an identifier for an appended extension to the
   2699    current un-mangled function name.  */
   2700 
   2701 static tree
   2702 get_fn_local_identifier (tree orig, const char *append)
   2703 {
   2704   /* Figure out the bits we need to generate names for the outlined things
   2705      For consistency, this needs to behave the same way as
   2706      ASM_FORMAT_PRIVATE_NAME does. */
   2707   tree nm = DECL_NAME (orig);
   2708   const char *sep, *pfx = "";
   2709 #ifndef NO_DOT_IN_LABEL
   2710   sep = ".";
   2711 #else
   2712 #ifndef NO_DOLLAR_IN_LABEL
   2713   sep = "$";
   2714 #else
   2715   sep = "_";
   2716   pfx = "__";
   2717 #endif
   2718 #endif
   2719 
   2720   char *an;
   2721   if (DECL_ASSEMBLER_NAME (orig))
   2722     an = ACONCAT ((IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (orig)), sep, append,
   2723 		   (char *) 0));
   2724   else if (DECL_USE_TEMPLATE (orig) && DECL_TEMPLATE_INFO (orig)
   2725 	   && DECL_TI_ARGS (orig))
   2726     {
   2727       tree tpl_args = DECL_TI_ARGS (orig);
   2728       an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), (char *) 0));
   2729       for (int i = 0; i < TREE_VEC_LENGTH (tpl_args); ++i)
   2730 	{
   2731 	  tree typ = DECL_NAME (TYPE_NAME (TREE_VEC_ELT (tpl_args, i)));
   2732 	  an = ACONCAT ((an, sep, IDENTIFIER_POINTER (typ), (char *) 0));
   2733 	}
   2734       an = ACONCAT ((an, sep, append, (char *) 0));
   2735     }
   2736   else
   2737     an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), sep, append, (char *) 0));
   2738 
   2739   return get_identifier (an);
   2740 }
   2741 
   2742 /* Build an initial or final await initialized from the promise
   2743    initial_suspend or final_suspend expression.  */
   2744 
   2745 static tree
   2746 build_init_or_final_await (location_t loc, bool is_final)
   2747 {
   2748   tree suspend_alt = is_final ? coro_final_suspend_identifier
   2749 			      : coro_initial_suspend_identifier;
   2750 
   2751   tree setup_call
   2752     = coro_build_promise_expression (current_function_decl, NULL, suspend_alt,
   2753 				     loc, NULL, /*musthave=*/true);
   2754 
   2755   /* Check for noexcept on the final_suspend call.  */
   2756   if (flag_exceptions && is_final && setup_call != error_mark_node
   2757       && coro_diagnose_throwing_final_aw_expr (setup_call))
   2758     return error_mark_node;
   2759 
   2760   /* So build the co_await for this */
   2761   /* For initial/final suspends the call is "a" per [expr.await] 3.2.  */
   2762   return build_co_await (loc, setup_call, (is_final ? FINAL_SUSPEND_POINT
   2763 						    : INITIAL_SUSPEND_POINT));
   2764 }
   2765 
   2766 /* Callback to record the essential data for each await point found in the
   2767    function.  */
   2768 
   2769 static bool
   2770 register_await_info (tree await_expr, tree aw_type, tree aw_nam,
   2771 		     hash_map<tree, suspend_point_info> *suspend_points)
   2772 {
   2773   bool seen;
   2774   suspend_point_info &s
   2775     = suspend_points->get_or_insert (await_expr, &seen);
   2776   if (seen)
   2777     {
   2778       warning_at (EXPR_LOCATION (await_expr), 0, "duplicate info for %qE",
   2779 		await_expr);
   2780       return false;
   2781     }
   2782   s.awaitable_type = aw_type;
   2783   s.await_field_id = aw_nam;
   2784   return true;
   2785 }
   2786 
   2787 /* This data set is used when analyzing statements for await expressions.  */
   2788 
   2789 struct susp_frame_data
   2790 {
   2791   /* Function-wide.  */
   2792   tree fs_label;		/* The destination for co_returns.  */
   2793   hash_map<tree, suspend_point_info> *suspend_points; /* Not owned.  */
   2794   vec<tree, va_gc> *block_stack; /* Track block scopes.  */
   2795   vec<tree, va_gc> *bind_stack;  /* Track current bind expr.  */
   2796   unsigned await_number = 0;	 /* Which await in the function.  */
   2797   unsigned cond_number = 0;		 /* Which replaced condition in the fn.  */
   2798 
   2799   /* Temporary values for one statement or expression being analyzed.  */
   2800   hash_set<tree> *truth_aoif_to_expand = nullptr; /* The set of TRUTH exprs to expand.  */
   2801   unsigned saw_awaits = 0;		 /* Count of awaits in this statement  */
   2802   bool captures_temporary = false;	 /* This expr captures temps by ref.  */
   2803   bool needs_truth_if_exp = false;	 /* We must expand a truth_if expression.  */
   2804   bool has_awaiter_init = false;	 /* We must handle initializing an awaiter.  */
   2805 
   2806   susp_frame_data (tree _final_susp, hash_map<tree, suspend_point_info> *_spt)
   2807     : fs_label (_final_susp), suspend_points (_spt)
   2808   {
   2809     block_stack = make_tree_vector ();
   2810     bind_stack = make_tree_vector ();
   2811   }
   2812 };
   2813 
   2814 /* If this is an await expression, then count it (both uniquely within the
   2815    function and locally within a single statement).  */
   2816 
   2817 static tree
   2818 register_awaits (tree *stmt, int *, void *d)
   2819 {
   2820   tree aw_expr = *stmt;
   2821 
   2822   /* We should have already lowered co_yields to their co_await.  */
   2823   gcc_checking_assert (TREE_CODE (aw_expr) != CO_YIELD_EXPR);
   2824 
   2825   if (TREE_CODE (aw_expr) != CO_AWAIT_EXPR)
   2826     return NULL_TREE;
   2827 
   2828   /* Count how many awaits the current expression contains.  */
   2829   susp_frame_data *data = (susp_frame_data *) d;
   2830   data->saw_awaits++;
   2831   /* Each await suspend context is unique, this is a function-wide value.  */
   2832   data->await_number++;
   2833 
   2834   /* Awaitables should either be user-locals or promoted to coroutine frame
   2835      entries at this point, and their initializers should have been broken
   2836      out.  */
   2837   tree aw = TREE_OPERAND (aw_expr, 1);
   2838   gcc_checking_assert (!TREE_OPERAND (aw_expr, 2));
   2839 
   2840   tree aw_field_type = TREE_TYPE (aw);
   2841   tree aw_field_nam = NULL_TREE;
   2842   register_await_info (aw_expr, aw_field_type, aw_field_nam, data->suspend_points);
   2843 
   2844   /* Rewrite target expressions on the await_suspend () to remove extraneous
   2845      cleanups for the awaitables, which are now promoted to frame vars and
   2846      managed via that.  */
   2847   tree v = TREE_OPERAND (aw_expr, 3);
   2848   tree o = TREE_VEC_ELT (v, 1);
   2849   if (TREE_CODE (o) == TARGET_EXPR)
   2850     TREE_VEC_ELT (v, 1) = get_target_expr (TREE_OPERAND (o, 1));
   2851   return NULL_TREE;
   2852 }
   2853 
   2854 /* There are cases where any await expression is relevant.  */
   2855 static tree
   2856 find_any_await (tree *stmt, int *dosub, void *d)
   2857 {
   2858   if (TREE_CODE (*stmt) == CO_AWAIT_EXPR)
   2859     {
   2860       *dosub = 0; /* We don't need to consider this any further.  */
   2861       tree **p = (tree **) d;
   2862       *p = stmt;
   2863       return *stmt;
   2864     }
   2865   return NULL_TREE;
   2866 }
   2867 
   2868 static bool
   2869 tmp_target_expr_p (tree t)
   2870 {
   2871   if (TREE_CODE (t) != TARGET_EXPR)
   2872     return false;
   2873   tree v = TREE_OPERAND (t, 0);
   2874   if (!DECL_ARTIFICIAL (v))
   2875     return false;
   2876   if (DECL_NAME (v))
   2877     return false;
   2878   return true;
   2879 }
   2880 
   2881 /* Structure to record sub-expressions that need to be handled by the
   2882    statement flattener.  */
   2883 
   2884 struct coro_interesting_subtree
   2885 {
   2886   tree* entry;
   2887   hash_set<tree> *temps_used;
   2888 };
   2889 
   2890 /* tree-walk callback that returns the first encountered sub-expression of
   2891    a kind that needs to be handled specifically by the statement flattener.  */
   2892 
   2893 static tree
   2894 find_interesting_subtree (tree *expr_p, int *dosub, void *d)
   2895 {
   2896   tree expr = *expr_p;
   2897   coro_interesting_subtree *p = (coro_interesting_subtree *)d;
   2898   if (TREE_CODE (expr) == CO_AWAIT_EXPR)
   2899     {
   2900       *dosub = 0; /* We don't need to consider this any further.  */
   2901       if (TREE_OPERAND (expr, 2))
   2902 	{
   2903 	  p->entry = expr_p;
   2904 	  return expr;
   2905 	}
   2906     }
   2907   else if (tmp_target_expr_p (expr)
   2908 	   && !TARGET_EXPR_ELIDING_P (expr)
   2909 	   && !p->temps_used->contains (expr))
   2910     {
   2911       p->entry = expr_p;
   2912       return expr;
   2913     }
   2914 
   2915   return NULL_TREE;
   2916 }
   2917 
   2918 /* Node for a doubly-linked list of promoted variables and their
   2919    initializers.  When the initializer is a conditional expression
   2920    the 'then' and 'else' clauses are represented by a linked list
   2921    attached to then_cl and else_cl respectively.  */
   2922 
   2923 struct var_nest_node
   2924 {
   2925   var_nest_node () = default;
   2926   var_nest_node (tree v, tree i, var_nest_node *p, var_nest_node *n)
   2927     : var(v), init(i), prev(p), next(n), then_cl (NULL), else_cl (NULL)
   2928     {
   2929       if (p)
   2930 	p->next = this;
   2931       if (n)
   2932 	n->prev = this;
   2933     }
   2934   tree var;
   2935   tree init;
   2936   var_nest_node *prev;
   2937   var_nest_node *next;
   2938   var_nest_node *then_cl;
   2939   var_nest_node *else_cl;
   2940 };
   2941 
   2942 /* This is called for single statements from the co-await statement walker.
   2943    It checks to see if the statement contains any initializers for awaitables
   2944    and if any of these capture items by reference.  */
   2945 
   2946 static void
   2947 flatten_await_stmt (var_nest_node *n, hash_set<tree> *promoted,
   2948 		    hash_set<tree> *temps_used, tree *replace_in)
   2949 {
   2950   bool init_expr = false;
   2951   switch (TREE_CODE (n->init))
   2952     {
   2953       default: break;
   2954       /* Compound expressions must be flattened specifically.  */
   2955       case COMPOUND_EXPR:
   2956 	{
   2957 	  tree first = TREE_OPERAND (n->init, 0);
   2958 	  n->init = TREE_OPERAND (n->init, 1);
   2959 	  var_nest_node *ins
   2960 	    = new var_nest_node(NULL_TREE, first, n->prev, n);
   2961 	  /* The compiler (but not the user) can generate temporaries with
   2962 	     uses in the second arm of a compound expr.  */
   2963 	  flatten_await_stmt (ins, promoted, temps_used, &n->init);
   2964 	  flatten_await_stmt (n, promoted, temps_used, NULL);
   2965 	  /* The two arms have been processed separately.  */
   2966 	  return;
   2967 	}
   2968 	break;
   2969       /* Handle conditional expressions.  */
   2970       case INIT_EXPR:
   2971 	init_expr = true;
   2972 	/* FALLTHROUGH */
   2973       case MODIFY_EXPR:
   2974 	{
   2975 	  tree old_expr = TREE_OPERAND (n->init, 1);
   2976 	  if (TREE_CODE (old_expr) == COMPOUND_EXPR)
   2977 	    {
   2978 	      tree first = TREE_OPERAND (old_expr, 0);
   2979 	      TREE_OPERAND (n->init, 1) = TREE_OPERAND (old_expr, 1);
   2980 	      var_nest_node *ins
   2981 		= new var_nest_node(NULL_TREE, first, n->prev, n);
   2982 	      flatten_await_stmt (ins, promoted, temps_used,
   2983 				  &TREE_OPERAND (n->init, 1));
   2984 	      flatten_await_stmt (n, promoted, temps_used, NULL);
   2985 	      return;
   2986 	    }
   2987 	  if (TREE_CODE (old_expr) != COND_EXPR)
   2988 	    break;
   2989 	  /* Reconstruct x = t ? y : z;
   2990 	     as (void) t ? x = y : x = z;  */
   2991 	  tree var = TREE_OPERAND (n->init, 0);
   2992 	  tree var_type = TREE_TYPE (var);
   2993 	  tree cond = COND_EXPR_COND (old_expr);
   2994 	  /* We are allowed a void type throw in one or both of the cond
   2995 	     expr arms.  */
   2996 	  tree then_cl = COND_EXPR_THEN (old_expr);
   2997 	  if (!VOID_TYPE_P (TREE_TYPE (then_cl)))
   2998 	    {
   2999 	      gcc_checking_assert (TREE_CODE (then_cl) != STATEMENT_LIST);
   3000 	      if (init_expr)
   3001 		then_cl = cp_build_init_expr (var, then_cl);
   3002 	      else
   3003 		then_cl = build2 (MODIFY_EXPR, var_type, var, then_cl);
   3004 	    }
   3005 	  tree else_cl = COND_EXPR_ELSE (old_expr);
   3006 	  if (!VOID_TYPE_P (TREE_TYPE (else_cl)))
   3007 	    {
   3008 	      gcc_checking_assert (TREE_CODE (else_cl) != STATEMENT_LIST);
   3009 	      if (init_expr)
   3010 		else_cl = cp_build_init_expr (var, else_cl);
   3011 	      else
   3012 		else_cl = build2 (MODIFY_EXPR, var_type, var, else_cl);
   3013 	    }
   3014 	  n->init = build3 (COND_EXPR, var_type, cond, then_cl, else_cl);
   3015 	}
   3016 	/* FALLTHROUGH */
   3017       case COND_EXPR:
   3018 	{
   3019 	  tree *found;
   3020 	  tree cond = COND_EXPR_COND (n->init);
   3021 	  /* If the condition contains an await expression, then we need to
   3022 	     set that first and use a separate var.  */
   3023 	  if (cp_walk_tree (&cond, find_any_await, &found, NULL))
   3024 	    {
   3025 	      tree cond_type = TREE_TYPE (cond);
   3026 	      tree cond_var  = build_lang_decl (VAR_DECL, NULL_TREE, cond_type);
   3027 	      DECL_ARTIFICIAL (cond_var) = true;
   3028 	      layout_decl (cond_var, 0);
   3029 	      gcc_checking_assert (!TYPE_NEEDS_CONSTRUCTING (cond_type));
   3030 	      cond = cp_build_init_expr (cond_var, cond);
   3031 	      var_nest_node *ins
   3032 		= new var_nest_node (cond_var, cond, n->prev, n);
   3033 	      COND_EXPR_COND (n->init) = cond_var;
   3034 	      flatten_await_stmt (ins, promoted, temps_used, NULL);
   3035 	    }
   3036 
   3037 	  n->then_cl
   3038 	    = new var_nest_node (n->var, COND_EXPR_THEN (n->init), NULL, NULL);
   3039 	  n->else_cl
   3040 	    = new var_nest_node (n->var, COND_EXPR_ELSE (n->init), NULL, NULL);
   3041 	  flatten_await_stmt (n->then_cl, promoted, temps_used, NULL);
   3042 	  /* Point to the start of the flattened code.  */
   3043 	  while (n->then_cl->prev)
   3044 	    n->then_cl = n->then_cl->prev;
   3045 	  flatten_await_stmt (n->else_cl, promoted, temps_used, NULL);
   3046 	  while (n->else_cl->prev)
   3047 	    n->else_cl = n->else_cl->prev;
   3048 	  return;
   3049 	}
   3050 	break;
   3051     }
   3052   coro_interesting_subtree v = { NULL, temps_used };
   3053   tree t = cp_walk_tree (&n->init, find_interesting_subtree, (void *)&v, NULL);
   3054   if (!t)
   3055     return;
   3056   switch (TREE_CODE (t))
   3057     {
   3058       default: break;
   3059       case CO_AWAIT_EXPR:
   3060 	{
   3061 	  /* Await expressions with initializers have a compiler-temporary
   3062 	     as the awaitable.  'promote' this.  */
   3063 	  tree var = TREE_OPERAND (t, 1);
   3064 	  bool already_present = promoted->add (var);
   3065 	  gcc_checking_assert (!already_present);
   3066 	  tree init = TREE_OPERAND (t, 2);
   3067 	  switch (TREE_CODE (init))
   3068 	    {
   3069 	      default: break;
   3070 	      case INIT_EXPR:
   3071 	      case MODIFY_EXPR:
   3072 		{
   3073 		  tree inner = TREE_OPERAND (init, 1);
   3074 		  /* We can have non-lvalue-expressions here, but when we see
   3075 		     a target expression, mark it as already used.  */
   3076 		  if (TREE_CODE (inner) == TARGET_EXPR)
   3077 		    {
   3078 		      temps_used->add (inner);
   3079 		      gcc_checking_assert
   3080 			(TREE_CODE (TREE_OPERAND (inner, 1)) != COND_EXPR);
   3081 		    }
   3082 		}
   3083 		break;
   3084 	      case CALL_EXPR:
   3085 		/* If this is a call and not a CTOR, then we didn't expect it.  */
   3086 		gcc_checking_assert
   3087 		  (DECL_CONSTRUCTOR_P (TREE_OPERAND (CALL_EXPR_FN (init), 0)));
   3088 		break;
   3089 	    }
   3090 	  var_nest_node *ins = new var_nest_node (var, init, n->prev, n);
   3091 	  TREE_OPERAND (t, 2) = NULL_TREE;
   3092 	  flatten_await_stmt (ins, promoted, temps_used, NULL);
   3093 	  flatten_await_stmt (n, promoted, temps_used, NULL);
   3094 	  return;
   3095 	}
   3096 	break;
   3097       case TARGET_EXPR:
   3098 	{
   3099 	  /* We have a temporary; promote it, but allow for the idiom in code
   3100 	     generated by the compiler like
   3101 	     a = (target_expr produces temp, op uses temp).  */
   3102 	  tree init = t;
   3103 	  temps_used->add (init);
   3104 	  tree var_type = TREE_TYPE (init);
   3105 	  char *buf = xasprintf ("T%03u", (unsigned) temps_used->elements ());
   3106 	  tree var = build_lang_decl (VAR_DECL, get_identifier (buf), var_type);
   3107 	  DECL_ARTIFICIAL (var) = true;
   3108 	  free (buf);
   3109 	  bool already_present = promoted->add (var);
   3110 	  gcc_checking_assert (!already_present);
   3111 	  tree inner = TREE_OPERAND (init, 1);
   3112 	  gcc_checking_assert (TREE_CODE (inner) != COND_EXPR);
   3113 	  init = cp_build_modify_expr (input_location, var, INIT_EXPR, init,
   3114 				       tf_warning_or_error);
   3115 	  /* Simplify for the case that we have an init containing the temp
   3116 	     alone.  */
   3117 	  if (t == n->init && n->var == NULL_TREE)
   3118 	    {
   3119 	      n->var = var;
   3120 	      proxy_replace pr = {TREE_OPERAND (t, 0), var};
   3121 	      cp_walk_tree (&init, replace_proxy, &pr, NULL);
   3122 	      n->init = init;
   3123 	      if (replace_in)
   3124 		cp_walk_tree (replace_in, replace_proxy, &pr, NULL);
   3125 	      flatten_await_stmt (n, promoted, temps_used, NULL);
   3126 	    }
   3127 	  else
   3128 	    {
   3129 	      var_nest_node *ins
   3130 		= new var_nest_node (var, init, n->prev, n);
   3131 	      /* We have to replace the target expr... */
   3132 	      *v.entry = var;
   3133 	      /* ... and any uses of its var.  */
   3134 	      proxy_replace pr = {TREE_OPERAND (t, 0), var};
   3135 	      cp_walk_tree (&n->init, replace_proxy, &pr, NULL);
   3136 	      /* Compiler-generated temporaries can also have uses in
   3137 		 following arms of compound expressions, which will be listed
   3138 		 in 'replace_in' if present.  */
   3139 	      if (replace_in)
   3140 		cp_walk_tree (replace_in, replace_proxy, &pr, NULL);
   3141 	      flatten_await_stmt (ins, promoted, temps_used, NULL);
   3142 	      flatten_await_stmt (n, promoted, temps_used, NULL);
   3143 	    }
   3144 	  return;
   3145 	}
   3146 	break;
   3147     }
   3148 }
   3149 
   3150 /* Helper for 'process_conditional' that handles recursion into nested
   3151    conditionals.  */
   3152 
   3153 static void
   3154 handle_nested_conditionals (var_nest_node *n, vec<tree>& list,
   3155 			    hash_map<tree, tree>& map)
   3156 {
   3157   do
   3158     {
   3159       if (n->var && DECL_NAME (n->var))
   3160 	{
   3161 	  list.safe_push (n->var);
   3162 	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (n->var)))
   3163 	    {
   3164 	      bool existed;
   3165 	      tree& flag = map.get_or_insert (n->var, &existed);
   3166 	      if (!existed)
   3167 		{
   3168 		  /* We didn't see this var before and it needs a DTOR, so
   3169 		     build a guard variable for it.  */
   3170 		  char *nam
   3171 		    = xasprintf ("%s_guard",
   3172 				 IDENTIFIER_POINTER (DECL_NAME (n->var)));
   3173 		  flag = build_lang_decl (VAR_DECL, get_identifier (nam),
   3174 					  boolean_type_node);
   3175 		  free (nam);
   3176 		  DECL_ARTIFICIAL (flag) = true;
   3177 		}
   3178 
   3179 	      /* The initializer for this variable is replaced by a compound
   3180 		 expression that performs the init and then records that the
   3181 		 variable is live (and the DTOR should be run at the scope
   3182 		 exit.  */
   3183 	      tree set_flag = cp_build_init_expr (flag, boolean_true_node);
   3184 	      n->init
   3185 		= build2 (COMPOUND_EXPR, boolean_type_node, n->init, set_flag);
   3186 	}
   3187 	}
   3188       if (TREE_CODE (n->init) == COND_EXPR)
   3189 	{
   3190 	  tree new_then = push_stmt_list ();
   3191 	  handle_nested_conditionals (n->then_cl, list, map);
   3192 	  new_then = pop_stmt_list (new_then);
   3193 	  tree new_else = push_stmt_list ();
   3194 	  handle_nested_conditionals (n->else_cl, list, map);
   3195 	  new_else = pop_stmt_list (new_else);
   3196 	  tree new_if
   3197 	    = build4 (IF_STMT, void_type_node, COND_EXPR_COND (n->init),
   3198 		      new_then, new_else, NULL_TREE);
   3199 	  add_stmt (new_if);
   3200 	}
   3201       else
   3202 	finish_expr_stmt (n->init);
   3203       n = n->next;
   3204     } while (n);
   3205 }
   3206 
   3207 /* helper for 'maybe_promote_temps'.
   3208 
   3209    When we have a conditional expression which might embed await expressions
   3210    and/or promoted variables, we need to handle it appropriately.
   3211 
   3212    The linked lists for the 'then' and 'else' clauses in a conditional node
   3213    identify the promoted variables (but these cannot be wrapped in a regular
   3214    cleanup).
   3215 
   3216    So recurse through the lists and build up a composite list of captured vars.
   3217    Declare these and any guard variables needed to decide if a DTOR should be
   3218    run.  Then embed the conditional into a try-finally expression that handles
   3219    running each DTOR conditionally on its guard variable.  */
   3220 
   3221 static void
   3222 process_conditional (var_nest_node *n, tree& vlist)
   3223 {
   3224   tree init = n->init;
   3225   hash_map<tree, tree> var_flags;
   3226   auto_vec<tree> var_list;
   3227   tree new_then = push_stmt_list ();
   3228   handle_nested_conditionals (n->then_cl, var_list, var_flags);
   3229   new_then = pop_stmt_list (new_then);
   3230   tree new_else = push_stmt_list ();
   3231   handle_nested_conditionals (n->else_cl, var_list, var_flags);
   3232   new_else = pop_stmt_list (new_else);
   3233   /* Declare the vars.  There are two loops so that the boolean flags are
   3234      grouped in the frame.  */
   3235   for (unsigned i = 0; i < var_list.length(); i++)
   3236     {
   3237       tree var = var_list[i];
   3238       DECL_CHAIN (var) = vlist;
   3239       vlist = var;
   3240       add_decl_expr (var);
   3241     }
   3242   /* Define the guard flags for variables that need a DTOR.  */
   3243   for (unsigned i = 0; i < var_list.length(); i++)
   3244     {
   3245       tree *flag = var_flags.get (var_list[i]);
   3246       if (flag)
   3247 	{
   3248 	  DECL_INITIAL (*flag) = boolean_false_node;
   3249 	  DECL_CHAIN (*flag) = vlist;
   3250 	  vlist = *flag;
   3251 	  add_decl_expr (*flag);
   3252 	}
   3253     }
   3254   tree new_if
   3255     = build4 (IF_STMT, void_type_node, COND_EXPR_COND (init),
   3256 	      new_then, new_else, NULL_TREE);
   3257   /* Build a set of conditional DTORs.  */
   3258   tree final_actions = push_stmt_list ();
   3259   while (!var_list.is_empty())
   3260     {
   3261       tree var = var_list.pop ();
   3262       tree *flag = var_flags.get (var);
   3263       if (!flag)
   3264 	continue;
   3265       if (tree cleanup = cxx_maybe_build_cleanup (var, tf_warning_or_error))
   3266 	{
   3267 	  tree cond_cleanup = begin_if_stmt ();
   3268 	  finish_if_stmt_cond (*flag, cond_cleanup);
   3269 	  finish_expr_stmt (cleanup);
   3270 	  finish_then_clause (cond_cleanup);
   3271 	  finish_if_stmt (cond_cleanup);
   3272 	}
   3273     }
   3274   final_actions = pop_stmt_list (final_actions);
   3275   tree try_finally
   3276     = build2 (TRY_FINALLY_EXPR, void_type_node, new_if, final_actions);
   3277   add_stmt (try_finally);
   3278 }
   3279 
   3280 /* Given *STMT, that contains at least one await expression.
   3281 
   3282    The full expression represented in the original source code will contain
   3283    suspension points, but it is still required that the lifetime of temporary
   3284    values extends to the end of the expression.
   3285 
   3286    We already have a mechanism to 'promote' user-authored local variables
   3287    to a coroutine frame counterpart (which allows explicit management of the
   3288    lifetime across suspensions).  The transform here re-writes STMT into
   3289    a bind expression, promotes temporary values into local variables in that
   3290    and flattens the statement into a series of cleanups.
   3291 
   3292    Conditional expressions are re-written to regular 'if' statements.
   3293    The cleanups for variables initialized inside a conditional (including
   3294    nested cases) are wrapped in a try-finally clause, with guard variables
   3295    to determine which DTORs need to be run.  */
   3296 
   3297 static tree
   3298 maybe_promote_temps (tree *stmt, void *d)
   3299 {
   3300   susp_frame_data *awpts = (susp_frame_data *) d;
   3301 
   3302   location_t sloc = EXPR_LOCATION (*stmt);
   3303   tree expr = *stmt;
   3304   /* Strip off uninteresting wrappers.  */
   3305   if (TREE_CODE (expr) == CLEANUP_POINT_EXPR)
   3306     expr = TREE_OPERAND (expr, 0);
   3307   if (TREE_CODE (expr) == EXPR_STMT)
   3308     expr = EXPR_STMT_EXPR (expr);
   3309   if (TREE_CODE (expr) == CONVERT_EXPR
   3310       && VOID_TYPE_P (TREE_TYPE (expr)))
   3311     expr = TREE_OPERAND (expr, 0);
   3312   STRIP_NOPS (expr);
   3313 
   3314   /* We walk the statement trees, flattening it into an ordered list of
   3315      variables with initializers and fragments corresponding to compound
   3316      expressions, truth or/and if and ternary conditionals.  Conditional
   3317      expressions carry a nested list of fragments for the then and else
   3318      clauses.  We anchor to the 'bottom' of the fragment list; we will write
   3319      a cleanup nest with one shell for each variable initialized.  */
   3320   var_nest_node *root = new var_nest_node (NULL_TREE, expr, NULL, NULL);
   3321   /* Check to see we didn't promote one twice.  */
   3322   hash_set<tree> promoted_vars;
   3323   hash_set<tree> used_temps;
   3324   flatten_await_stmt (root, &promoted_vars, &used_temps, NULL);
   3325 
   3326   gcc_checking_assert (root->next == NULL);
   3327   tree vlist = NULL_TREE;
   3328   var_nest_node *t = root;
   3329   /* We build the bind scope expression from the bottom-up.
   3330      EXPR_LIST holds the inner expression nest at the current cleanup
   3331      level (becoming the final expression list when we've exhausted the
   3332      number of sub-expression fragments).  */
   3333   tree expr_list = NULL_TREE;
   3334   do
   3335     {
   3336       tree new_list = push_stmt_list ();
   3337       /* When we have a promoted variable, then add that to the bind scope
   3338 	 and initialize it.  When there's no promoted variable, we just need
   3339 	 to run the initializer.
   3340 	 If the initializer is a conditional expression, we need to collect
   3341 	 and declare any promoted variables nested within it.  DTORs for such
   3342 	 variables must be run conditionally too.
   3343 
   3344 	 Since here we're synthetically processing code here, we've already
   3345 	 emitted any Wunused-result warnings.  Below, however, we call
   3346 	 finish_expr_stmt, which will convert its operand to void, and could
   3347 	 result in such a diagnostic being emitted.  To avoid that, convert to
   3348 	 void ahead of time.  */
   3349       if (t->var)
   3350 	{
   3351 	  tree var = t->var;
   3352 	  DECL_CHAIN (var) = vlist;
   3353 	  vlist = var;
   3354 	  add_decl_expr (var);
   3355 	  if (TREE_CODE (t->init) == COND_EXPR)
   3356 	    process_conditional (t, vlist);
   3357 	  else
   3358 	    finish_expr_stmt (convert_to_void (t->init, ICV_STATEMENT, tf_none));
   3359 	  if (tree cleanup = cxx_maybe_build_cleanup (var, tf_warning_or_error))
   3360 	    {
   3361 	      tree cl = build_stmt (sloc, CLEANUP_STMT, expr_list, cleanup, var);
   3362 	      add_stmt (cl); /* push this onto the level above.  */
   3363 	    }
   3364 	  else if (expr_list)
   3365 	    {
   3366 	      if (TREE_CODE (expr_list) != STATEMENT_LIST)
   3367 		add_stmt (expr_list);
   3368 	      else if (!tsi_end_p (tsi_start (expr_list)))
   3369 		add_stmt (expr_list);
   3370 	    }
   3371 	}
   3372       else
   3373 	{
   3374 	  if (TREE_CODE (t->init) == COND_EXPR)
   3375 	    process_conditional (t, vlist);
   3376 	  else
   3377 	    finish_expr_stmt (convert_to_void (t->init, ICV_STATEMENT, tf_none));
   3378 	  if (expr_list)
   3379 	    {
   3380 	      if (TREE_CODE (expr_list) != STATEMENT_LIST)
   3381 		add_stmt (expr_list);
   3382 	      else if (!tsi_end_p (tsi_start (expr_list)))
   3383 		add_stmt (expr_list);
   3384 	    }
   3385 	}
   3386       expr_list = pop_stmt_list (new_list);
   3387       var_nest_node *old = t;
   3388       t = t->prev;
   3389       delete old;
   3390     } while (t);
   3391 
   3392   /* Now produce the bind expression containing the 'promoted' temporaries
   3393      as its variable list, and the cleanup nest as the statement.  */
   3394   tree await_bind = build3_loc (sloc, BIND_EXPR, void_type_node,
   3395 				NULL, NULL, NULL);
   3396   BIND_EXPR_BODY (await_bind) = expr_list;
   3397   BIND_EXPR_VARS (await_bind) = nreverse (vlist);
   3398   tree b_block = make_node (BLOCK);
   3399   if (!awpts->block_stack->is_empty ())
   3400     {
   3401       tree s_block = awpts->block_stack->last ();
   3402       if (s_block)
   3403 	{
   3404 	BLOCK_SUPERCONTEXT (b_block) = s_block;
   3405 	BLOCK_CHAIN (b_block) = BLOCK_SUBBLOCKS (s_block);
   3406 	BLOCK_SUBBLOCKS (s_block) = b_block;
   3407 	}
   3408     }
   3409   BLOCK_VARS (b_block) = BIND_EXPR_VARS (await_bind) ;
   3410   BIND_EXPR_BLOCK (await_bind) = b_block;
   3411   TREE_SIDE_EFFECTS (await_bind) = TREE_SIDE_EFFECTS (BIND_EXPR_BODY (await_bind));
   3412   *stmt = await_bind;
   3413   hash_set<tree> visited;
   3414   return cp_walk_tree (stmt, register_awaits, d, &visited);
   3415 }
   3416 
   3417 /* Lightweight callback to determine two key factors:
   3418    1) If the statement/expression contains any await expressions.
   3419    2) If the statement/expression potentially requires a re-write to handle
   3420       TRUTH_{AND,OR}IF_EXPRs since, in most cases, they will need expansion
   3421       so that the await expressions are not processed in the case of the
   3422       short-circuit arm.
   3423 
   3424    CO_YIELD expressions are re-written to their underlying co_await.  */
   3425 
   3426 static tree
   3427 analyze_expression_awaits (tree *stmt, int *do_subtree, void *d)
   3428 {
   3429   susp_frame_data *awpts = (susp_frame_data *) d;
   3430 
   3431   switch (TREE_CODE (*stmt))
   3432     {
   3433       default: return NULL_TREE;
   3434       case CO_YIELD_EXPR:
   3435 	/* co_yield is syntactic sugar, re-write it to co_await.  */
   3436 	*stmt = TREE_OPERAND (*stmt, 1);
   3437 	/* FALLTHROUGH */
   3438       case CO_AWAIT_EXPR:
   3439 	awpts->saw_awaits++;
   3440 	/* A non-null initializer for the awaiter means we need to expand.  */
   3441 	if (TREE_OPERAND (*stmt, 2))
   3442 	  awpts->has_awaiter_init = true;
   3443 	break;
   3444       case TRUTH_ANDIF_EXPR:
   3445       case TRUTH_ORIF_EXPR:
   3446 	{
   3447 	  /* We don't need special action for awaits in the always-executed
   3448 	     arm of a TRUTH_IF.  */
   3449 	  if (tree res = cp_walk_tree (&TREE_OPERAND (*stmt, 0),
   3450 				       analyze_expression_awaits, d, NULL))
   3451 	    return res;
   3452 	  /* However, if there are await expressions on the conditionally
   3453 	     executed branch, we must expand the TRUTH_IF to ensure that the
   3454 	     expanded await expression control-flow is fully contained in the
   3455 	     conditionally executed code.  */
   3456 	  unsigned aw_count = awpts->saw_awaits;
   3457 	  if (tree res = cp_walk_tree (&TREE_OPERAND (*stmt, 1),
   3458 				       analyze_expression_awaits, d, NULL))
   3459 	    return res;
   3460 	  if (awpts->saw_awaits > aw_count)
   3461 	    {
   3462 	      awpts->truth_aoif_to_expand->add (*stmt);
   3463 	      awpts->needs_truth_if_exp = true;
   3464 	    }
   3465 	  /* We've done the sub-trees here.  */
   3466 	  *do_subtree = 0;
   3467 	}
   3468 	break;
   3469     }
   3470 
   3471   return NULL_TREE; /* Recurse until done.  */
   3472 }
   3473 
   3474 /* Given *EXPR
   3475    If EXPR contains a TRUTH_{AND,OR}IF_EXPR, TAOIE with an await expr on
   3476    the conditionally executed branch, change this in a ternary operator.
   3477 
   3478    bool not_expr = TAOIE == TRUTH_ORIF_EXPR ? NOT : NOP;
   3479    not_expr (always-exec expr) ? conditionally-exec expr : not_expr;
   3480 
   3481    Apply this recursively to the condition and the conditionally-exec
   3482    branch.  */
   3483 
   3484 struct truth_if_transform {
   3485   tree *orig_stmt;
   3486   tree scratch_var;
   3487   hash_set<tree> *truth_aoif_to_expand;
   3488 };
   3489 
   3490 static tree
   3491 expand_one_truth_if (tree *expr, int *do_subtree, void *d)
   3492 {
   3493   truth_if_transform *xform = (truth_if_transform *) d;
   3494 
   3495   bool needs_not = false;
   3496   switch (TREE_CODE (*expr))
   3497     {
   3498       default: break;
   3499       case TRUTH_ORIF_EXPR:
   3500 	needs_not = true;
   3501 	/* FALLTHROUGH */
   3502       case TRUTH_ANDIF_EXPR:
   3503 	{
   3504 	  if (!xform->truth_aoif_to_expand->contains (*expr))
   3505 	    break;
   3506 
   3507 	  location_t sloc = EXPR_LOCATION (*expr);
   3508 	  /* Transform truth expression into a cond expression with
   3509 	     * the always-executed arm as the condition.
   3510 	     * the conditionally-executed arm as the then clause.
   3511 	     * the 'else' clause is fixed: 'true' for ||,'false' for &&.  */
   3512 	  tree cond = TREE_OPERAND (*expr, 0);
   3513 	  tree test1 = TREE_OPERAND (*expr, 1);
   3514 	  tree fixed = needs_not ? boolean_true_node : boolean_false_node;
   3515 	  if (needs_not)
   3516 	    cond = build1 (TRUTH_NOT_EXPR, boolean_type_node, cond);
   3517 	  tree cond_expr
   3518 	    = build3_loc (sloc, COND_EXPR, boolean_type_node,
   3519 			  cond, test1, fixed);
   3520 	  *expr = cond_expr;
   3521 	  if (tree res = cp_walk_tree (&COND_EXPR_COND (*expr),
   3522 				       expand_one_truth_if, d, NULL))
   3523 	    return res;
   3524 	  if (tree res = cp_walk_tree (&COND_EXPR_THEN (*expr),
   3525 				       expand_one_truth_if, d, NULL))
   3526 	    return res;
   3527 	  /* We've manually processed necessary sub-trees here.  */
   3528 	  *do_subtree = 0;
   3529 	}
   3530 	break;
   3531     }
   3532   return NULL_TREE;
   3533 }
   3534 
   3535 /* Helper that adds a new variable of VAR_TYPE to a bind scope BIND, the
   3536    name is made up from NAM_ROOT, NAM_VERS.  */
   3537 
   3538 static tree
   3539 add_var_to_bind (tree& bind, tree var_type,
   3540 		 const char *nam_root, unsigned nam_vers)
   3541 {
   3542   tree b_vars = BIND_EXPR_VARS (bind);
   3543   /* Build a variable to hold the condition, this will be included in the
   3544      frame as a local var.  */
   3545   char *nam = xasprintf ("__%s_%d", nam_root, nam_vers);
   3546   tree newvar = build_lang_decl (VAR_DECL, get_identifier (nam), var_type);
   3547   free (nam);
   3548   DECL_CHAIN (newvar) = b_vars;
   3549   BIND_EXPR_VARS (bind) = newvar;
   3550   return newvar;
   3551 }
   3552 
   3553 /* Helper to build and add if (!cond) break;  */
   3554 
   3555 static void
   3556 coro_build_add_if_not_cond_break (tree cond)
   3557 {
   3558   tree if_stmt = begin_if_stmt ();
   3559   tree invert = build1 (TRUTH_NOT_EXPR, boolean_type_node, cond);
   3560   finish_if_stmt_cond (invert, if_stmt);
   3561   finish_break_stmt ();
   3562   finish_then_clause (if_stmt);
   3563   finish_if_stmt (if_stmt);
   3564 }
   3565 
   3566 /* Tree walk callback to replace continue statements with goto label.  */
   3567 static tree
   3568 replace_continue (tree *stmt, int *do_subtree, void *d)
   3569 {
   3570   tree expr = *stmt;
   3571   if (TREE_CODE (expr) == CLEANUP_POINT_EXPR)
   3572     expr = TREE_OPERAND (expr, 0);
   3573   if (CONVERT_EXPR_P (expr) && VOID_TYPE_P (TREE_TYPE (expr)))
   3574     expr = TREE_OPERAND (expr, 0);
   3575   STRIP_NOPS (expr);
   3576   if (!STATEMENT_CLASS_P (expr))
   3577     return NULL_TREE;
   3578 
   3579   switch (TREE_CODE (expr))
   3580     {
   3581       /* Unless it's a special case, just walk the subtrees as usual.  */
   3582       default: return NULL_TREE;
   3583 
   3584       case CONTINUE_STMT:
   3585 	{
   3586 	  tree *label = (tree *)d;
   3587 	  location_t loc = EXPR_LOCATION (expr);
   3588 	  /* re-write a continue to goto label.  */
   3589 	  *stmt = build_stmt (loc, GOTO_EXPR, *label);
   3590 	  *do_subtree = 0;
   3591 	  return NULL_TREE;
   3592 	}
   3593 
   3594       /* Statements that do not require recursion.  */
   3595       case DECL_EXPR:
   3596       case BREAK_STMT:
   3597       case GOTO_EXPR:
   3598       case LABEL_EXPR:
   3599       case CASE_LABEL_EXPR:
   3600       case ASM_EXPR:
   3601       /* These must break recursion.  */
   3602       case FOR_STMT:
   3603       case WHILE_STMT:
   3604       case DO_STMT:
   3605 	*do_subtree = 0;
   3606 	return NULL_TREE;
   3607     }
   3608 }
   3609 
   3610 /* Tree walk callback to analyze, register and pre-process statements that
   3611    contain await expressions.  */
   3612 
   3613 static tree
   3614 await_statement_walker (tree *stmt, int *do_subtree, void *d)
   3615 {
   3616   tree res = NULL_TREE;
   3617   susp_frame_data *awpts = (susp_frame_data *) d;
   3618 
   3619   /* Process a statement at a time.  */
   3620   if (TREE_CODE (*stmt) == BIND_EXPR)
   3621     {
   3622       /* For conditional expressions, we might wish to add an artificial var
   3623 	 to their containing bind expr.  */
   3624       vec_safe_push (awpts->bind_stack, *stmt);
   3625       /* We might need to insert a new bind expression, and want to link it
   3626 	 into the correct scope, so keep a note of the current block scope.  */
   3627       tree blk = BIND_EXPR_BLOCK (*stmt);
   3628       vec_safe_push (awpts->block_stack, blk);
   3629       res = cp_walk_tree (&BIND_EXPR_BODY (*stmt), await_statement_walker,
   3630 			  d, NULL);
   3631       awpts->block_stack->pop ();
   3632       awpts->bind_stack->pop ();
   3633       *do_subtree = 0; /* Done subtrees.  */
   3634       return res;
   3635     }
   3636   else if (TREE_CODE (*stmt) == STATEMENT_LIST)
   3637     {
   3638       for (tree &s : tsi_range (*stmt))
   3639 	{
   3640 	  res = cp_walk_tree (&s, await_statement_walker,
   3641 			      d, NULL);
   3642 	  if (res)
   3643 	    return res;
   3644 	}
   3645       *do_subtree = 0; /* Done subtrees.  */
   3646       return NULL_TREE;
   3647     }
   3648 
   3649   /* We have something to be handled as a single statement.  We have to handle
   3650      a few statements specially where await statements have to be moved out of
   3651      constructs.  */
   3652   tree expr = *stmt;
   3653   if (TREE_CODE (*stmt) == CLEANUP_POINT_EXPR)
   3654     expr = TREE_OPERAND (expr, 0);
   3655   STRIP_NOPS (expr);
   3656 
   3657   if (STATEMENT_CLASS_P (expr))
   3658     switch (TREE_CODE (expr))
   3659       {
   3660 	/* Unless it's a special case, just walk the subtrees as usual.  */
   3661 	default: return NULL_TREE;
   3662 
   3663 	/* When we have a conditional expression, which contains one or more
   3664 	   await expressions, we have to break the condition out into a
   3665 	   regular statement so that the control flow introduced by the await
   3666 	   transforms can be implemented.  */
   3667 	case IF_STMT:
   3668 	  {
   3669 	    tree *await_ptr;
   3670 	    hash_set<tree> visited;
   3671 	    /* Transform 'if (cond with awaits) then stmt1 else stmt2' into
   3672 	       bool cond = cond with awaits.
   3673 	       if (cond) then stmt1 else stmt2.  */
   3674 	    tree if_stmt = *stmt;
   3675 	    /* We treat the condition as if it was a stand-alone statement,
   3676 	       to see if there are any await expressions which will be analyzed
   3677 	       and registered.  */
   3678 	    if (!(cp_walk_tree (&IF_COND (if_stmt),
   3679 		  find_any_await, &await_ptr, &visited)))
   3680 	      return NULL_TREE; /* Nothing special to do here.  */
   3681 
   3682 	    gcc_checking_assert (!awpts->bind_stack->is_empty());
   3683 	    tree& bind_expr = awpts->bind_stack->last ();
   3684 	    tree newvar = add_var_to_bind (bind_expr, boolean_type_node,
   3685 					   "ifcd", awpts->cond_number++);
   3686 	    tree insert_list = push_stmt_list ();
   3687 	    tree cond_inner = IF_COND (if_stmt);
   3688 	    if (TREE_CODE (cond_inner) == CLEANUP_POINT_EXPR)
   3689 	      cond_inner = TREE_OPERAND (cond_inner, 0);
   3690 	    add_decl_expr (newvar);
   3691 	    location_t sloc = EXPR_LOCATION (IF_COND (if_stmt));
   3692 	    /* We want to initialize the new variable with the expression
   3693 	       that contains the await(s) and potentially also needs to
   3694 	       have truth_if expressions expanded.  */
   3695 	    tree new_s = cp_build_init_expr (sloc, newvar, cond_inner);
   3696 	    finish_expr_stmt (new_s);
   3697 	    IF_COND (if_stmt) = newvar;
   3698 	    add_stmt (if_stmt);
   3699 	    *stmt = pop_stmt_list (insert_list);
   3700 	    /* So now walk the new statement list.  */
   3701 	    res = cp_walk_tree (stmt, await_statement_walker, d, NULL);
   3702 	    *do_subtree = 0; /* Done subtrees.  */
   3703 	    return res;
   3704 	  }
   3705 	  break;
   3706 	case FOR_STMT:
   3707 	  {
   3708 	    tree *await_ptr;
   3709 	    hash_set<tree> visited;
   3710 	    /* for loops only need special treatment if the condition or the
   3711 	       iteration expression contain a co_await.  */
   3712 	    tree for_stmt = *stmt;
   3713 	    /* At present, the FE always generates a separate initializer for
   3714 	       the FOR_INIT_STMT, when the expression has an await.  Check that
   3715 	       this assumption holds in the future. */
   3716 	    gcc_checking_assert
   3717 	      (!(cp_walk_tree (&FOR_INIT_STMT (for_stmt), find_any_await,
   3718 			       &await_ptr, &visited)));
   3719 
   3720 	    visited.empty ();
   3721 	    bool for_cond_await
   3722 	      = cp_walk_tree (&FOR_COND (for_stmt), find_any_await,
   3723 			      &await_ptr, &visited);
   3724 
   3725 	    visited.empty ();
   3726 	    bool for_expr_await
   3727 	      = cp_walk_tree (&FOR_EXPR (for_stmt), find_any_await,
   3728 			      &await_ptr, &visited);
   3729 
   3730 	    /* If the condition has an await, then we will need to rewrite the
   3731 	       loop as
   3732 	       for (init expression;true;iteration expression) {
   3733 		  condition = await expression;
   3734 		  if (condition)
   3735 		    break;
   3736 		  ...
   3737 		}
   3738 	    */
   3739 	    if (for_cond_await)
   3740 	      {
   3741 		tree insert_list = push_stmt_list ();
   3742 		/* This will be expanded when the revised body is handled.  */
   3743 		coro_build_add_if_not_cond_break (FOR_COND (for_stmt));
   3744 		/* .. add the original for body.  */
   3745 		add_stmt (FOR_BODY (for_stmt));
   3746 		/* To make the new for body.  */
   3747 		FOR_BODY (for_stmt) = pop_stmt_list (insert_list);
   3748 		FOR_COND (for_stmt) = boolean_true_node;
   3749 	      }
   3750 	    /* If the iteration expression has an await, it's a bit more
   3751 	       tricky.
   3752 	       for (init expression;condition;) {
   3753 		 ...
   3754 		 iteration_expr_label:
   3755 		   iteration expression with await;
   3756 	       }
   3757 	       but, then we will need to re-write any continue statements into
   3758 	       'goto iteration_expr_label:'.
   3759 	    */
   3760 	    if (for_expr_await)
   3761 	      {
   3762 		location_t sloc = EXPR_LOCATION (FOR_EXPR (for_stmt));
   3763 		tree insert_list = push_stmt_list ();
   3764 		/* The original for body.  */
   3765 		add_stmt (FOR_BODY (for_stmt));
   3766 		char *buf = xasprintf ("for.iter.expr.%u", awpts->cond_number++);
   3767 		tree it_expr_label
   3768 		  = create_named_label_with_ctx (sloc, buf, NULL_TREE);
   3769 		free (buf);
   3770 		add_stmt (build_stmt (sloc, LABEL_EXPR, it_expr_label));
   3771 		tree for_expr = FOR_EXPR (for_stmt);
   3772 		/* Present the iteration expression as a statement.  */
   3773 		if (TREE_CODE (for_expr) == CLEANUP_POINT_EXPR)
   3774 		  for_expr = TREE_OPERAND (for_expr, 0);
   3775 		STRIP_NOPS (for_expr);
   3776 		finish_expr_stmt (for_expr);
   3777 		FOR_EXPR (for_stmt) = NULL_TREE;
   3778 		FOR_BODY (for_stmt) = pop_stmt_list (insert_list);
   3779 		/* rewrite continue statements to goto label.  */
   3780 		hash_set<tree> visited_continue;
   3781 		if ((res = cp_walk_tree (&FOR_BODY (for_stmt),
   3782 		     replace_continue, &it_expr_label, &visited_continue)))
   3783 		  return res;
   3784 	      }
   3785 
   3786 	    /* So now walk the body statement (list), if there were no await
   3787 	       expressions, then this handles the original body - and either
   3788 	       way we will have finished with this statement.  */
   3789 	    res = cp_walk_tree (&FOR_BODY (for_stmt),
   3790 				await_statement_walker, d, NULL);
   3791 	    *do_subtree = 0; /* Done subtrees.  */
   3792 	    return res;
   3793 	  }
   3794 	  break;
   3795 	case WHILE_STMT:
   3796 	  {
   3797 	    /* We turn 'while (cond with awaits) stmt' into
   3798 	       while (true) {
   3799 		  if (!(cond with awaits))
   3800 		    break;
   3801 		  stmt..
   3802 		} */
   3803 	    tree *await_ptr;
   3804 	    hash_set<tree> visited;
   3805 	    tree while_stmt = *stmt;
   3806 	    if (!(cp_walk_tree (&WHILE_COND (while_stmt),
   3807 		  find_any_await, &await_ptr, &visited)))
   3808 	      return NULL_TREE; /* Nothing special to do here.  */
   3809 
   3810 	    tree insert_list = push_stmt_list ();
   3811 	    coro_build_add_if_not_cond_break (WHILE_COND (while_stmt));
   3812 	    /* The original while body.  */
   3813 	    add_stmt (WHILE_BODY (while_stmt));
   3814 	    /* The new while body.  */
   3815 	    WHILE_BODY (while_stmt) = pop_stmt_list (insert_list);
   3816 	    WHILE_COND (while_stmt) = boolean_true_node;
   3817 	    /* So now walk the new statement list.  */
   3818 	    res = cp_walk_tree (&WHILE_BODY (while_stmt),
   3819 				await_statement_walker, d, NULL);
   3820 	    *do_subtree = 0; /* Done subtrees.  */
   3821 	    return res;
   3822 	  }
   3823 	  break;
   3824 	case DO_STMT:
   3825 	  {
   3826 	    /* We turn do stmt while (cond with awaits) into:
   3827 	       do {
   3828 		  stmt..
   3829 		  if (!(cond with awaits))
   3830 		    break;
   3831 	       } while (true); */
   3832 	    tree do_stmt = *stmt;
   3833 	    tree *await_ptr;
   3834 	    hash_set<tree> visited;
   3835 	    if (!(cp_walk_tree (&DO_COND (do_stmt),
   3836 		  find_any_await, &await_ptr, &visited)))
   3837 	      return NULL_TREE; /* Nothing special to do here.  */
   3838 
   3839 	    tree insert_list = push_stmt_list ();
   3840 	    /* The original do stmt body.  */
   3841 	    add_stmt (DO_BODY (do_stmt));
   3842 	    coro_build_add_if_not_cond_break (DO_COND (do_stmt));
   3843 	    /* The new while body.  */
   3844 	    DO_BODY (do_stmt) = pop_stmt_list (insert_list);
   3845 	    DO_COND (do_stmt) = boolean_true_node;
   3846 	    /* So now walk the new statement list.  */
   3847 	    res = cp_walk_tree (&DO_BODY (do_stmt), await_statement_walker,
   3848 				d, NULL);
   3849 	    *do_subtree = 0; /* Done subtrees.  */
   3850 	    return res;
   3851 	  }
   3852 	  break;
   3853 	case SWITCH_STMT:
   3854 	  {
   3855 	    /* We turn 'switch (cond with awaits) stmt' into
   3856 	       switch_type cond = cond with awaits
   3857 	       switch (cond) stmt.  */
   3858 	    tree sw_stmt = *stmt;
   3859 	    tree *await_ptr;
   3860 	    hash_set<tree> visited;
   3861 	    if (!(cp_walk_tree (&SWITCH_STMT_COND (sw_stmt),
   3862 		  find_any_await, &await_ptr, &visited)))
   3863 	      return NULL_TREE; /* Nothing special to do here.  */
   3864 
   3865 	    gcc_checking_assert (!awpts->bind_stack->is_empty());
   3866 	    /* Build a variable to hold the condition, this will be
   3867 		   included in the frame as a local var.  */
   3868 	    tree& bind_expr = awpts->bind_stack->last ();
   3869 	    tree sw_type = SWITCH_STMT_TYPE (sw_stmt);
   3870 	    tree newvar = add_var_to_bind (bind_expr, sw_type, "swch",
   3871 					   awpts->cond_number++);
   3872 	    tree insert_list = push_stmt_list ();
   3873 	    add_decl_expr (newvar);
   3874 
   3875 	    tree cond_inner = SWITCH_STMT_COND (sw_stmt);
   3876 	    if (TREE_CODE (cond_inner) == CLEANUP_POINT_EXPR)
   3877 	      cond_inner = TREE_OPERAND (cond_inner, 0);
   3878 	    location_t sloc = EXPR_LOCATION (SWITCH_STMT_COND (sw_stmt));
   3879 	    tree new_s = cp_build_init_expr (sloc, newvar,
   3880 				     cond_inner);
   3881 	    finish_expr_stmt (new_s);
   3882 	    SWITCH_STMT_COND (sw_stmt) = newvar;
   3883 	    /* Now add the switch statement with the condition re-
   3884 		   written to use the local var.  */
   3885 	    add_stmt (sw_stmt);
   3886 	    *stmt = pop_stmt_list (insert_list);
   3887 	    /* Process the expanded list.  */
   3888 	    res = cp_walk_tree (stmt, await_statement_walker,
   3889 				d, NULL);
   3890 	    *do_subtree = 0; /* Done subtrees.  */
   3891 	    return res;
   3892 	  }
   3893 	  break;
   3894 	case CO_RETURN_EXPR:
   3895 	  {
   3896 	    /* Expand the co_return as per [stmt.return.coroutine]
   3897 	       - for co_return;
   3898 		{ p.return_void (); goto final_suspend; }
   3899 	       - for co_return [void expr];
   3900 		{ expr; p.return_void(); goto final_suspend;}
   3901 	       - for co_return [non void expr];
   3902 		{ p.return_value(expr); goto final_suspend; }  */
   3903 	    location_t loc = EXPR_LOCATION (expr);
   3904 	    tree call = TREE_OPERAND (expr, 1);
   3905 	    expr = TREE_OPERAND (expr, 0);
   3906 	    tree ret_list = push_stmt_list ();
   3907 	    /* [stmt.return.coroutine], 2.2
   3908 	       If expr is present and void, it is placed immediately before
   3909 	       the call for return_void;  */
   3910 	    if (expr && VOID_TYPE_P (TREE_TYPE (expr)))
   3911 	      finish_expr_stmt (expr);
   3912 	    /* Insert p.return_{void,value(expr)}.  */
   3913 	    finish_expr_stmt (call);
   3914 	    TREE_USED (awpts->fs_label) = 1;
   3915 	    add_stmt (build_stmt (loc, GOTO_EXPR, awpts->fs_label));
   3916 	    *stmt = pop_stmt_list (ret_list);
   3917 	    res = cp_walk_tree (stmt, await_statement_walker, d, NULL);
   3918 	    /* Once this is complete, we will have processed subtrees.  */
   3919 	    *do_subtree = 0;
   3920 	    return res;
   3921 	  }
   3922 	  break;
   3923 	case HANDLER:
   3924 	  {
   3925 	    /* [expr.await] An await-expression shall appear only in a
   3926 	       potentially-evaluated expression within the compound-statement
   3927 	       of a function-body outside of a handler.  */
   3928 	    tree *await_ptr;
   3929 	    hash_set<tree> visited;
   3930 	    if (!(cp_walk_tree (&HANDLER_BODY (expr), find_any_await,
   3931 		  &await_ptr, &visited)))
   3932 	      return NULL_TREE; /* All OK.  */
   3933 	    location_t loc = EXPR_LOCATION (*await_ptr);
   3934 	    error_at (loc, "await expressions are not permitted in handlers");
   3935 	    return NULL_TREE; /* This is going to fail later anyway.  */
   3936 	  }
   3937 	  break;
   3938       }
   3939   else if (EXPR_P (expr))
   3940     {
   3941       hash_set<tree> visited;
   3942       tree *await_ptr;
   3943       if (!(cp_walk_tree (stmt, find_any_await, &await_ptr, &visited)))
   3944 	return NULL_TREE; /* Nothing special to do here.  */
   3945 
   3946       visited.empty ();
   3947       awpts->saw_awaits = 0;
   3948       hash_set<tree> truth_aoif_to_expand;
   3949       awpts->truth_aoif_to_expand = &truth_aoif_to_expand;
   3950       awpts->needs_truth_if_exp = false;
   3951       awpts->has_awaiter_init = false;
   3952       if ((res = cp_walk_tree (stmt, analyze_expression_awaits, d, &visited)))
   3953 	return res;
   3954       *do_subtree = 0; /* Done subtrees.  */
   3955       if (!awpts->saw_awaits)
   3956 	return NULL_TREE; /* Nothing special to do here.  */
   3957 
   3958       if (awpts->needs_truth_if_exp)
   3959 	{
   3960 	  /* If a truth-and/or-if expression has an await expression in the
   3961 	     conditionally-taken branch, then it must be rewritten into a
   3962 	     regular conditional.  */
   3963 	  truth_if_transform xf = {stmt, NULL_TREE, &truth_aoif_to_expand};
   3964 	  if ((res = cp_walk_tree (stmt, expand_one_truth_if, &xf, NULL)))
   3965 	    return res;
   3966 	}
   3967       /* Process this statement, which contains at least one await expression
   3968 	 to 'promote' temporary values to a coroutine frame slot.  */
   3969       return maybe_promote_temps (stmt, d);
   3970     }
   3971   /* Continue recursion, if needed.  */
   3972   return res;
   3973 }
   3974 
   3975 /* For figuring out what param usage we have.  */
   3976 
   3977 struct param_frame_data
   3978 {
   3979   tree *field_list;
   3980   hash_map<tree, param_info> *param_uses;
   3981   hash_set<tree *> *visited;
   3982   location_t loc;
   3983   bool param_seen;
   3984 };
   3985 
   3986 /* A tree walk callback that rewrites each parm use to the local variable
   3987    that represents its copy in the frame.  */
   3988 
   3989 static tree
   3990 rewrite_param_uses (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
   3991 {
   3992   param_frame_data *data = (param_frame_data *) d;
   3993 
   3994   /* For lambda closure content, we have to look specifically.  */
   3995   if (VAR_P (*stmt) && DECL_HAS_VALUE_EXPR_P (*stmt))
   3996     {
   3997       tree t = DECL_VALUE_EXPR (*stmt);
   3998       return cp_walk_tree (&t, rewrite_param_uses, d, NULL);
   3999     }
   4000 
   4001   if (unevaluated_p (TREE_CODE (*stmt)))
   4002     {
   4003       /* No odr-uses in unevaluated operands.  */
   4004       *do_subtree = 0;
   4005       return NULL_TREE;
   4006     }
   4007 
   4008   if (TREE_CODE (*stmt) != PARM_DECL)
   4009     return NULL_TREE;
   4010 
   4011   /* If we already saw the containing expression, then we're done.  */
   4012   if (data->visited->add (stmt))
   4013     return NULL_TREE;
   4014 
   4015   bool existed;
   4016   param_info &parm = data->param_uses->get_or_insert (*stmt, &existed);
   4017   gcc_checking_assert (existed);
   4018 
   4019   *stmt = parm.copy_var;
   4020   return NULL_TREE;
   4021 }
   4022 
   4023 /* Build up a set of info that determines how each param copy will be
   4024    handled.  */
   4025 
   4026 static hash_map<tree, param_info> *
   4027 analyze_fn_parms (tree orig)
   4028 {
   4029   if (!DECL_ARGUMENTS (orig))
   4030     return NULL;
   4031 
   4032   hash_map<tree, param_info> *param_uses = new hash_map<tree, param_info>;
   4033 
   4034   /* Build a hash map with an entry for each param.
   4035      The key is the param tree.
   4036      Then we have an entry for the frame field name.
   4037      Then a cache for the field ref when we come to use it.
   4038      Then a tree list of the uses.
   4039      The second two entries start out empty - and only get populated
   4040      when we see uses.  */
   4041   bool lambda_p = LAMBDA_FUNCTION_P (orig);
   4042 
   4043   unsigned no_name_parm = 0;
   4044   for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; arg = DECL_CHAIN (arg))
   4045     {
   4046       bool existed;
   4047       param_info &parm = param_uses->get_or_insert (arg, &existed);
   4048       gcc_checking_assert (!existed);
   4049       parm.body_uses = NULL;
   4050       tree actual_type = TREE_TYPE (arg);
   4051       actual_type = complete_type_or_else (actual_type, orig);
   4052       if (actual_type == NULL_TREE)
   4053 	actual_type = error_mark_node;
   4054       parm.orig_type = actual_type;
   4055       parm.by_ref = parm.pt_ref = parm.rv_ref =  false;
   4056       if (TREE_CODE (actual_type) == REFERENCE_TYPE)
   4057 	{
   4058 	  /* If the user passes by reference, then we will save the
   4059 	     pointer to the original.  As noted in
   4060 	     [dcl.fct.def.coroutine] / 13, if the lifetime of the
   4061 	     referenced item ends and then the coroutine is resumed,
   4062 	     we have UB; well, the user asked for it.  */
   4063 	  if (TYPE_REF_IS_RVALUE (actual_type))
   4064 		parm.rv_ref = true;
   4065 	  else
   4066 		parm.pt_ref = true;
   4067 	}
   4068       else if (TYPE_REF_P (DECL_ARG_TYPE (arg)))
   4069 	parm.by_ref = true;
   4070 
   4071       parm.frame_type = actual_type;
   4072 
   4073       parm.this_ptr = is_this_parameter (arg);
   4074       parm.lambda_cobj = lambda_p && DECL_NAME (arg) == closure_identifier;
   4075 
   4076       tree name = DECL_NAME (arg);
   4077       if (!name)
   4078 	{
   4079 	  char *buf = xasprintf ("_Coro_unnamed_parm_%d", no_name_parm++);
   4080 	  name = get_identifier (buf);
   4081 	  free (buf);
   4082 	}
   4083       parm.field_id = name;
   4084 
   4085       if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (parm.frame_type))
   4086 	{
   4087 	  char *buf = xasprintf ("%s%s_live", DECL_NAME (arg) ? "_Coro_" : "",
   4088 				 IDENTIFIER_POINTER (name));
   4089 	  parm.guard_var
   4090 	    = coro_build_artificial_var (UNKNOWN_LOCATION, get_identifier (buf),
   4091 					 boolean_type_node, orig,
   4092 					 boolean_false_node);
   4093 	  free (buf);
   4094 	  parm.trivial_dtor = false;
   4095 	}
   4096       else
   4097 	parm.trivial_dtor = true;
   4098     }
   4099 
   4100   return param_uses;
   4101 }
   4102 
   4103 /* Small helper for the repetitive task of adding a new field to the coro
   4104    frame type.  */
   4105 
   4106 static tree
   4107 coro_make_frame_entry (tree *field_list, const char *name, tree fld_type,
   4108 		       location_t loc)
   4109 {
   4110   tree id = get_identifier (name);
   4111   tree decl = build_decl (loc, FIELD_DECL, id, fld_type);
   4112   DECL_CHAIN (decl) = *field_list;
   4113   *field_list = decl;
   4114   return id;
   4115 }
   4116 
   4117 /* For recording local variable usage.  */
   4118 
   4119 struct local_vars_frame_data
   4120 {
   4121   tree *field_list;
   4122   hash_map<tree, local_var_info> *local_var_uses;
   4123   unsigned int nest_depth = 0;
   4124   unsigned int bind_indx = 0;
   4125   location_t loc = UNKNOWN_LOCATION;
   4126   bool saw_capture = false;
   4127   bool local_var_seen = false;
   4128 
   4129   local_vars_frame_data (tree *_fl, hash_map<tree, local_var_info> *_lvu)
   4130     : field_list (_fl), local_var_uses (_lvu) {}
   4131 };
   4132 
   4133 /* A tree-walk callback that processes one bind expression noting local
   4134    variables, and making a coroutine frame slot available for those that
   4135    need it, so that they can be 'promoted' across suspension points.  */
   4136 
   4137 static tree
   4138 register_local_var_uses (tree *stmt, int *do_subtree, void *d)
   4139 {
   4140   if (TREE_CODE (*stmt) != BIND_EXPR)
   4141     return NULL_TREE;
   4142 
   4143   local_vars_frame_data *lvd = (local_vars_frame_data *) d;
   4144 
   4145   /* As we enter a bind expression - record the vars there and then recurse.
   4146      As we exit drop the nest depth.
   4147      The bind index is a growing count of how many bind indices we've seen.
   4148      We build a space in the frame for each local var.  */
   4149 
   4150   tree lvar;
   4151   unsigned serial = 0;
   4152   for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL; lvar = DECL_CHAIN (lvar))
   4153     {
   4154       bool existed;
   4155       local_var_info &local_var
   4156 	= lvd->local_var_uses->get_or_insert (lvar, &existed);
   4157       gcc_checking_assert (!existed);
   4158       local_var.def_loc = DECL_SOURCE_LOCATION (lvar);
   4159       tree lvtype = TREE_TYPE (lvar);
   4160       local_var.frame_type = lvtype;
   4161       local_var.field_idx = local_var.field_id = NULL_TREE;
   4162 
   4163       /* Make sure that we only present vars to the tests below.  */
   4164       if (TREE_CODE (lvar) != PARM_DECL
   4165 	  && TREE_CODE (lvar) != VAR_DECL)
   4166 	continue;
   4167 
   4168       /* We don't move static vars into the frame. */
   4169       local_var.is_static = TREE_STATIC (lvar);
   4170       if (local_var.is_static)
   4171 	continue;
   4172 
   4173       poly_uint64 size;
   4174       if (TREE_CODE (lvtype) == ARRAY_TYPE
   4175 	  && !poly_int_tree_p (DECL_SIZE_UNIT (lvar), &size))
   4176 	{
   4177 	  sorry_at (local_var.def_loc, "variable length arrays are not"
   4178 		    " yet supported in coroutines");
   4179 	  /* Ignore it, this is broken anyway.  */
   4180 	  continue;
   4181 	}
   4182 
   4183       lvd->local_var_seen = true;
   4184       /* If this var is a lambda capture proxy, we want to leave it alone,
   4185 	 and later rewrite the DECL_VALUE_EXPR to indirect through the
   4186 	 frame copy of the pointer to the lambda closure object.  */
   4187       local_var.is_lambda_capture = is_capture_proxy (lvar);
   4188       if (local_var.is_lambda_capture)
   4189 	continue;
   4190 
   4191       /* If a variable has a value expression, then that's what needs
   4192 	 to be processed.  */
   4193       local_var.has_value_expr_p = DECL_HAS_VALUE_EXPR_P (lvar);
   4194       if (local_var.has_value_expr_p)
   4195 	continue;
   4196 
   4197       /* Make names depth+index unique, so that we can support nested
   4198 	 scopes with identically named locals and still be able to
   4199 	 identify them in the coroutine frame.  */
   4200       tree lvname = DECL_NAME (lvar);
   4201       char *buf = NULL;
   4202 
   4203       /* The outermost bind scope contains the artificial variables that
   4204 	 we inject to implement the coro state machine.  We want to be able
   4205 	 to inspect these in debugging.  */
   4206       if (lvname != NULL_TREE && lvd->nest_depth == 0)
   4207 	buf = xasprintf ("%s", IDENTIFIER_POINTER (lvname));
   4208       else if (lvname != NULL_TREE)
   4209 	buf = xasprintf ("%s_%u_%u", IDENTIFIER_POINTER (lvname),
   4210 			 lvd->nest_depth, lvd->bind_indx);
   4211       else
   4212 	buf = xasprintf ("_D%u_%u_%u", lvd->nest_depth, lvd->bind_indx,
   4213 			 serial++);
   4214 
   4215       /* TODO: Figure out if we should build a local type that has any
   4216 	 excess alignment or size from the original decl.  */
   4217       local_var.field_id = coro_make_frame_entry (lvd->field_list, buf,
   4218 						  lvtype, lvd->loc);
   4219       free (buf);
   4220       /* We don't walk any of the local var sub-trees, they won't contain
   4221 	 any bind exprs.  */
   4222     }
   4223   lvd->bind_indx++;
   4224   lvd->nest_depth++;
   4225   /* Ensure we only visit each expression once.  */
   4226   cp_walk_tree_without_duplicates (&BIND_EXPR_BODY (*stmt),
   4227 				   register_local_var_uses, d);
   4228   *do_subtree = 0; /* We've done this.  */
   4229   lvd->nest_depth--;
   4230   return NULL_TREE;
   4231 }
   4232 
   4233 /* Build, return FUNCTION_DECL node based on ORIG with a type FN_TYPE which has
   4234    a single argument of type CORO_FRAME_PTR.  Build the actor function if
   4235    ACTOR_P is true, otherwise the destroy. */
   4236 
   4237 static tree
   4238 coro_build_actor_or_destroy_function (tree orig, tree fn_type,
   4239 				      tree coro_frame_ptr, bool actor_p)
   4240 {
   4241   location_t loc = DECL_SOURCE_LOCATION (orig);
   4242   tree fn
   4243     = build_lang_decl (FUNCTION_DECL, copy_node (DECL_NAME (orig)), fn_type);
   4244 
   4245   /* Allow for locating the ramp (original) function from this one.  */
   4246   if (!to_ramp)
   4247     to_ramp = hash_map<tree, tree>::create_ggc (10);
   4248   to_ramp->put (fn, orig);
   4249 
   4250   DECL_CONTEXT (fn) = DECL_CONTEXT (orig);
   4251   DECL_SOURCE_LOCATION (fn) = loc;
   4252   DECL_ARTIFICIAL (fn) = true;
   4253   DECL_INITIAL (fn) = error_mark_node;
   4254 
   4255   tree id = get_identifier ("frame_ptr");
   4256   tree fp = build_lang_decl (PARM_DECL, id, coro_frame_ptr);
   4257   DECL_ARTIFICIAL (fp) = true;
   4258   DECL_CONTEXT (fp) = fn;
   4259   DECL_ARG_TYPE (fp) = type_passed_as (coro_frame_ptr);
   4260   DECL_ARGUMENTS (fn) = fp;
   4261 
   4262   /* Copy selected attributes from the original function.  */
   4263   TREE_USED (fn) = TREE_USED (orig);
   4264   if (DECL_SECTION_NAME (orig))
   4265     set_decl_section_name (fn, orig);
   4266   /* Copy any alignment that the FE added.  */
   4267   if (DECL_ALIGN (orig))
   4268     SET_DECL_ALIGN (fn, DECL_ALIGN (orig));
   4269   /* Copy any alignment the user added.  */
   4270   DECL_USER_ALIGN (fn) = DECL_USER_ALIGN (orig);
   4271   /* Apply attributes from the original fn.  */
   4272   DECL_ATTRIBUTES (fn) = copy_list (DECL_ATTRIBUTES (orig));
   4273   /* but we do not want ones for contracts.  */
   4274   remove_contract_attributes (fn);
   4275 
   4276   /* A void return.  */
   4277   tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
   4278   DECL_CONTEXT (resdecl) = fn;
   4279   DECL_ARTIFICIAL (resdecl) = 1;
   4280   DECL_IGNORED_P (resdecl) = 1;
   4281   DECL_RESULT (fn) = resdecl;
   4282 
   4283   /* This is a coroutine component.  */
   4284   DECL_COROUTINE_P (fn) = 1;
   4285 
   4286   /* Set up a means to find out if a decl is one of the helpers and, if so,
   4287      which one.  */
   4288   if (coroutine_info *info = get_coroutine_info (orig))
   4289     {
   4290       gcc_checking_assert ((actor_p && info->actor_decl == NULL_TREE)
   4291 			   || info->destroy_decl == NULL_TREE);
   4292       if (actor_p)
   4293 	info->actor_decl = fn;
   4294       else
   4295 	info->destroy_decl = fn;
   4296     }
   4297   return fn;
   4298 }
   4299 
   4300 /* Re-write the body as per [dcl.fct.def.coroutine] / 5.  */
   4301 
   4302 static tree
   4303 coro_rewrite_function_body (location_t fn_start, tree fnbody, tree orig,
   4304 			    hash_map<tree, param_info> *param_uses,
   4305 			    tree resume_fn_ptr_type,
   4306 			    tree& resume_idx_var, tree& fs_label)
   4307 {
   4308   /* This will be our new outer scope.  */
   4309   tree update_body = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
   4310   tree top_block = make_node (BLOCK);
   4311   BIND_EXPR_BLOCK (update_body) = top_block;
   4312   BIND_EXPR_BODY (update_body) = push_stmt_list ();
   4313 
   4314   /* If the function has a top level bind expression, then connect that
   4315      after first making sure we give it a new block.  */
   4316   tree first = expr_first (fnbody);
   4317   if (first && TREE_CODE (first) == BIND_EXPR)
   4318     {
   4319       tree block = BIND_EXPR_BLOCK (first);
   4320       gcc_checking_assert (block);
   4321       gcc_checking_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
   4322       gcc_checking_assert (BLOCK_CHAIN (block) == NULL_TREE);
   4323       /* Replace the top block to avoid issues with locations for args
   4324 	 appearing to be in a non-existent place.  */
   4325       tree replace_blk = make_node (BLOCK);
   4326       BLOCK_VARS (replace_blk) = BLOCK_VARS (block);
   4327       BLOCK_SUBBLOCKS (replace_blk) = BLOCK_SUBBLOCKS (block);
   4328       for (tree b = BLOCK_SUBBLOCKS (replace_blk); b; b = BLOCK_CHAIN (b))
   4329 	BLOCK_SUPERCONTEXT (b) = replace_blk;
   4330       BIND_EXPR_BLOCK (first) = replace_blk;
   4331       /* The top block has one child, so far, and we have now got a
   4332 	 superblock.  */
   4333       BLOCK_SUPERCONTEXT (replace_blk) = top_block;
   4334       BLOCK_SUBBLOCKS (top_block) = replace_blk;
   4335     }
   4336   else
   4337     {
   4338       /* We are missing a top level BIND_EXPR. We need one to ensure that we
   4339 	 don't shuffle around the coroutine frame and corrupt it.  */
   4340       tree bind_wrap = build3_loc (fn_start, BIND_EXPR, void_type_node,
   4341 				   NULL, NULL, NULL);
   4342       BIND_EXPR_BODY (bind_wrap) = fnbody;
   4343       /* Ensure we have a block to connect up the scopes.  */
   4344       tree new_blk = make_node (BLOCK);
   4345       BIND_EXPR_BLOCK (bind_wrap) = new_blk;
   4346       BLOCK_SUBBLOCKS (top_block) = new_blk;
   4347       fnbody = bind_wrap;
   4348     }
   4349 
   4350   /* Wrap the function body in a try {} catch (...) {} block, if exceptions
   4351      are enabled.  */
   4352   tree var_list = NULL_TREE;
   4353   tree initial_await = build_init_or_final_await (fn_start, false);
   4354 
   4355   /* [stmt.return.coroutine] / 3
   4356      If p.return_void() is a valid expression, flowing off the end of a
   4357      coroutine is equivalent to a co_return with no operand; otherwise
   4358      flowing off the end of a coroutine results in undefined behavior.  */
   4359   tree return_void
   4360     = get_coroutine_return_void_expr (current_function_decl, fn_start, false);
   4361 
   4362   /* The pointer to the resume function.  */
   4363   tree resume_fn_ptr
   4364     = coro_build_artificial_var (fn_start, coro_resume_fn_id,
   4365 				 resume_fn_ptr_type, orig, NULL_TREE);
   4366   DECL_CHAIN (resume_fn_ptr) = var_list;
   4367   var_list = resume_fn_ptr;
   4368   add_decl_expr (resume_fn_ptr);
   4369 
   4370   /* We will need to be able to set the resume function pointer to nullptr
   4371      to signal that the coroutine is 'done'.  */
   4372   tree zero_resume
   4373     = build1 (CONVERT_EXPR, resume_fn_ptr_type, nullptr_node);
   4374 
   4375   /* The pointer to the destroy function.  */
   4376   tree var = coro_build_artificial_var (fn_start, coro_destroy_fn_id,
   4377 					resume_fn_ptr_type, orig, NULL_TREE);
   4378   DECL_CHAIN (var) = var_list;
   4379   var_list = var;
   4380   add_decl_expr (var);
   4381 
   4382   /* The promise was created on demand when parsing we now link it into
   4383       our scope.  */
   4384   tree promise = get_coroutine_promise_proxy (orig);
   4385   DECL_CONTEXT (promise) = orig;
   4386   DECL_SOURCE_LOCATION (promise) = fn_start;
   4387   DECL_CHAIN (promise) = var_list;
   4388   var_list = promise;
   4389   add_decl_expr (promise);
   4390 
   4391   /* We need a handle to this coroutine, which is passed to every
   4392      await_suspend().  This was created on demand when parsing we now link it
   4393      into our scope.  */
   4394   var = get_coroutine_self_handle_proxy (orig);
   4395   DECL_CONTEXT (var) = orig;
   4396   DECL_SOURCE_LOCATION (var) = fn_start;
   4397   DECL_CHAIN (var) = var_list;
   4398   var_list = var;
   4399   add_decl_expr (var);
   4400 
   4401   /* If we have function parms, then these will be copied to the coroutine
   4402      frame.  Create a local (proxy) variable for each parm, since the original
   4403      parms will be out of scope once the ramp has finished. The proxy vars will
   4404      get DECL_VALUE_EXPRs pointing to the frame copies, so that we can interact
   4405      with them in the debugger.  */
   4406   if (param_uses)
   4407     {
   4408       gcc_checking_assert (DECL_ARGUMENTS (orig));
   4409       /* Add a local var for each parm.  */
   4410       for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
   4411 	   arg = DECL_CHAIN (arg))
   4412 	{
   4413 	  param_info *parm_i = param_uses->get (arg);
   4414 	  gcc_checking_assert (parm_i);
   4415 	  parm_i->copy_var
   4416 	    = build_lang_decl (VAR_DECL, parm_i->field_id, TREE_TYPE (arg));
   4417 	  DECL_SOURCE_LOCATION (parm_i->copy_var) = DECL_SOURCE_LOCATION (arg);
   4418 	  DECL_CONTEXT (parm_i->copy_var) = orig;
   4419 	  DECL_ARTIFICIAL (parm_i->copy_var) = true;
   4420 	  DECL_CHAIN (parm_i->copy_var) = var_list;
   4421 	  var_list = parm_i->copy_var;
   4422 	  add_decl_expr (parm_i->copy_var);
   4423       	}
   4424 
   4425       /* Now replace all uses of the parms in the function body with the proxy
   4426 	 vars.  We want to this to apply to every instance of param's use, so
   4427 	 don't include a 'visited' hash_set on the tree walk, however we will
   4428 	 arrange to visit each containing expression only once.  */
   4429       hash_set<tree *> visited;
   4430       param_frame_data param_data = {NULL, param_uses,
   4431 				     &visited, fn_start, false};
   4432       cp_walk_tree (&fnbody, rewrite_param_uses, &param_data, NULL);
   4433     }
   4434 
   4435   /* We create a resume index, this is initialized in the ramp.  */
   4436   resume_idx_var
   4437     = coro_build_artificial_var (fn_start, coro_resume_index_id,
   4438 				 short_unsigned_type_node, orig, NULL_TREE);
   4439   DECL_CHAIN (resume_idx_var) = var_list;
   4440   var_list = resume_idx_var;
   4441   add_decl_expr (resume_idx_var);
   4442 
   4443   /* If the coroutine has a frame that needs to be freed, this will be set by
   4444      the ramp.  */
   4445   var = coro_build_artificial_var (fn_start, coro_frame_needs_free_id,
   4446 				   boolean_type_node, orig, NULL_TREE);
   4447   DECL_CHAIN (var) = var_list;
   4448   var_list = var;
   4449   add_decl_expr (var);
   4450 
   4451   if (flag_exceptions)
   4452     {
   4453       /* Build promise.unhandled_exception();  */
   4454       tree ueh
   4455 	= coro_build_promise_expression (current_function_decl, promise,
   4456 					 coro_unhandled_exception_identifier,
   4457 					 fn_start, NULL, /*musthave=*/true);
   4458       /* Create and initialize the initial-await-resume-called variable per
   4459 	 [dcl.fct.def.coroutine] / 5.3.  */
   4460       tree i_a_r_c
   4461 	= coro_build_artificial_var (fn_start, coro_frame_i_a_r_c_id,
   4462 				     boolean_type_node, orig,
   4463 				     NULL_TREE);
   4464       DECL_CHAIN (i_a_r_c) = var_list;
   4465       var_list = i_a_r_c;
   4466       add_decl_expr (i_a_r_c);
   4467       /* Start the try-catch.  */
   4468       tree tcb = build_stmt (fn_start, TRY_BLOCK, NULL_TREE, NULL_TREE);
   4469       add_stmt (tcb);
   4470       TRY_STMTS (tcb) = push_stmt_list ();
   4471       if (initial_await != error_mark_node)
   4472 	{
   4473 	  /* Build a compound expression that sets the
   4474 	     initial-await-resume-called variable true and then calls the
   4475 	     initial suspend expression await resume.
   4476 	     In the case that the user decides to make the initial await
   4477 	     await_resume() return a value, we need to discard it and, it is
   4478 	     a reference type, look past the indirection.  */
   4479 	  if (INDIRECT_REF_P (initial_await))
   4480 	    initial_await = TREE_OPERAND (initial_await, 0);
   4481 	  /* In the case that the initial_await returns a target expression
   4482 	     we might need to look through that to update the await expr.  */
   4483 	  tree iaw = initial_await;
   4484 	  if (TREE_CODE (iaw) == TARGET_EXPR)
   4485 	    iaw = TARGET_EXPR_INITIAL (iaw);
   4486 	  gcc_checking_assert (TREE_CODE (iaw) == CO_AWAIT_EXPR);
   4487 	  tree vec = TREE_OPERAND (iaw, 3);
   4488 	  tree aw_r = TREE_VEC_ELT (vec, 2);
   4489 	  aw_r = convert_to_void (aw_r, ICV_STATEMENT, tf_warning_or_error);
   4490 	  tree update = build2 (MODIFY_EXPR, boolean_type_node, i_a_r_c,
   4491 				boolean_true_node);
   4492 	  aw_r = cp_build_compound_expr (update, aw_r, tf_warning_or_error);
   4493 	  TREE_VEC_ELT (vec, 2) = aw_r;
   4494 	}
   4495       /* Add the initial await to the start of the user-authored function.  */
   4496       finish_expr_stmt (initial_await);
   4497       /* Append the original function body.  */
   4498       add_stmt (fnbody);
   4499       if (return_void)
   4500 	add_stmt (return_void);
   4501       TRY_STMTS (tcb) = pop_stmt_list (TRY_STMTS (tcb));
   4502       TRY_HANDLERS (tcb) = push_stmt_list ();
   4503       /* Mimic what the parser does for the catch.  */
   4504       tree handler = begin_handler ();
   4505       finish_handler_parms (NULL_TREE, handler); /* catch (...) */
   4506 
   4507       /* Get the initial await resume called value.  */
   4508       tree not_iarc_if = begin_if_stmt ();
   4509       tree not_iarc = build1_loc (fn_start, TRUTH_NOT_EXPR,
   4510 				  boolean_type_node, i_a_r_c);
   4511       finish_if_stmt_cond (not_iarc, not_iarc_if);
   4512       /* If the initial await resume called value is false, rethrow...  */
   4513       tree rethrow = build_throw (fn_start, NULL_TREE, tf_warning_or_error);
   4514       suppress_warning (rethrow);
   4515       finish_expr_stmt (rethrow);
   4516       finish_then_clause (not_iarc_if);
   4517       tree iarc_scope = IF_SCOPE (not_iarc_if);
   4518       IF_SCOPE (not_iarc_if) = NULL;
   4519       not_iarc_if = do_poplevel (iarc_scope);
   4520       add_stmt (not_iarc_if);
   4521       /* ... else call the promise unhandled exception method
   4522 	 but first we set done = true and the resume index to 0.
   4523 	 If the unhandled exception method returns, then we continue
   4524 	 to the final await expression (which duplicates the clearing of
   4525 	 the field). */
   4526       tree r = build2 (MODIFY_EXPR, resume_fn_ptr_type, resume_fn_ptr,
   4527 		       zero_resume);
   4528       finish_expr_stmt (r);
   4529       tree short_zero = build_int_cst (short_unsigned_type_node, 0);
   4530       r = build2 (MODIFY_EXPR, short_unsigned_type_node, resume_idx_var,
   4531 		  short_zero);
   4532       finish_expr_stmt (r);
   4533       finish_expr_stmt (ueh);
   4534       finish_handler (handler);
   4535       TRY_HANDLERS (tcb) = pop_stmt_list (TRY_HANDLERS (tcb));
   4536     }
   4537   else
   4538     {
   4539       if (pedantic)
   4540 	{
   4541 	  /* We still try to look for the promise method and warn if it's not
   4542 	     present.  */
   4543 	  tree ueh_meth
   4544 	    = lookup_promise_method (orig, coro_unhandled_exception_identifier,
   4545 				     fn_start, /*musthave=*/false);
   4546 	  if (!ueh_meth || ueh_meth == error_mark_node)
   4547 	    warning_at (fn_start, 0, "no member named %qE in %qT",
   4548 			coro_unhandled_exception_identifier,
   4549 			get_coroutine_promise_type (orig));
   4550 	}
   4551       /* Else we don't check and don't care if the method is missing..
   4552 	 just add the initial suspend, function and return.  */
   4553       finish_expr_stmt (initial_await);
   4554       /* Append the original function body.  */
   4555       add_stmt (fnbody);
   4556       if (return_void)
   4557 	add_stmt (return_void);
   4558     }
   4559 
   4560   /* co_return branches to the final_suspend label, so declare that now.  */
   4561   fs_label
   4562     = create_named_label_with_ctx (fn_start, "final.suspend", NULL_TREE);
   4563   add_stmt (build_stmt (fn_start, LABEL_EXPR, fs_label));
   4564 
   4565   /* Before entering the final suspend point, we signal that this point has
   4566      been reached by setting the resume function pointer to zero (this is
   4567      what the 'done()' builtin tests) as per the current ABI.  */
   4568   zero_resume = build2 (MODIFY_EXPR, resume_fn_ptr_type, resume_fn_ptr,
   4569 			zero_resume);
   4570   finish_expr_stmt (zero_resume);
   4571   finish_expr_stmt (build_init_or_final_await (fn_start, true));
   4572   BIND_EXPR_BODY (update_body) = pop_stmt_list (BIND_EXPR_BODY (update_body));
   4573   BIND_EXPR_VARS (update_body) = nreverse (var_list);
   4574   BLOCK_VARS (top_block) = BIND_EXPR_VARS (update_body);
   4575 
   4576   return update_body;
   4577 }
   4578 
   4579 /* Here we:
   4580    a) Check that the function and promise type are valid for a
   4581       coroutine.
   4582    b) Carry out the initial morph to create the skeleton of the
   4583       coroutine ramp function and the rewritten body.
   4584 
   4585   Assumptions.
   4586 
   4587   1. We only hit this code once all dependencies are resolved.
   4588   2. The function body will be either a bind expr or a statement list
   4589   3. That cfun and current_function_decl are valid for the case we're
   4590      expanding.
   4591   4. 'input_location' will be of the final brace for the function.
   4592 
   4593  We do something like this:
   4594  declare a dummy coro frame.
   4595  struct _R_frame {
   4596   using handle_type = coro::coroutine_handle<coro1::promise_type>;
   4597   void (*_Coro_resume_fn)(_R_frame *);
   4598   void (*_Coro_destroy_fn)(_R_frame *);
   4599   coro1::promise_type _Coro_promise;
   4600   bool _Coro_frame_needs_free; free the coro frame mem if set.
   4601   bool _Coro_i_a_r_c; [dcl.fct.def.coroutine] / 5.3
   4602   short _Coro_resume_index;
   4603   handle_type _Coro_self_handle;
   4604   parameter copies (were required).
   4605   local variables saved (including awaitables)
   4606   (maybe) trailing space.
   4607  };  */
   4608 
   4609 bool
   4610 morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
   4611 {
   4612   gcc_checking_assert (orig && TREE_CODE (orig) == FUNCTION_DECL);
   4613 
   4614   *resumer = error_mark_node;
   4615   *destroyer = error_mark_node;
   4616   if (!coro_function_valid_p (orig))
   4617     {
   4618       /* For early errors, we do not want a diagnostic about the missing
   4619 	 ramp return value, since the user cannot fix this - a 'return' is
   4620 	 not allowed in a coroutine.  */
   4621       suppress_warning (orig, OPT_Wreturn_type);
   4622       /* Discard the body, we can't process it further.  */
   4623       pop_stmt_list (DECL_SAVED_TREE (orig));
   4624       DECL_SAVED_TREE (orig) = push_stmt_list ();
   4625       return false;
   4626     }
   4627 
   4628   /* We can't validly get here with an empty statement list, since there's no
   4629      way for the FE to decide it's a coroutine in the absence of any code.  */
   4630   tree fnbody = pop_stmt_list (DECL_SAVED_TREE (orig));
   4631   gcc_checking_assert (fnbody != NULL_TREE);
   4632 
   4633   /* We don't have the locus of the opening brace - it's filled in later (and
   4634      there doesn't really seem to be any easy way to get at it).
   4635      The closing brace is assumed to be input_location.  */
   4636   location_t fn_start = DECL_SOURCE_LOCATION (orig);
   4637   gcc_rich_location fn_start_loc (fn_start);
   4638 
   4639   /* Initial processing of the function-body.
   4640      If we have no expressions or just an error then punt.  */
   4641   tree body_start = expr_first (fnbody);
   4642   if (body_start == NULL_TREE || body_start == error_mark_node)
   4643     {
   4644       DECL_SAVED_TREE (orig) = push_stmt_list ();
   4645       append_to_statement_list (fnbody, &DECL_SAVED_TREE (orig));
   4646       /* Suppress warnings about the missing return value.  */
   4647       suppress_warning (orig, OPT_Wreturn_type);
   4648       return false;
   4649     }
   4650 
   4651   /* So, we've tied off the original user-authored body in fn_body.
   4652 
   4653      Start the replacement synthesized ramp body as newbody.
   4654      If we encounter a fatal error we might return a now-empty body.
   4655 
   4656      Note, the returned ramp body is not 'popped', to be compatible with
   4657      the way that decl.cc handles regular functions, the scope pop is done
   4658      in the caller.  */
   4659 
   4660   tree newbody = push_stmt_list ();
   4661   DECL_SAVED_TREE (orig) = newbody;
   4662 
   4663   /* If our original body is noexcept, then that's what we apply to our
   4664      generated ramp, transfer any MUST_NOT_THOW_EXPR to that.  */
   4665   bool is_noexcept = TREE_CODE (body_start) == MUST_NOT_THROW_EXPR;
   4666   if (is_noexcept)
   4667     {
   4668       /* The function body we will continue with is the single operand to
   4669 	 the must-not-throw.  */
   4670       fnbody = TREE_OPERAND (body_start, 0);
   4671       /* Transfer the must-not-throw to the ramp body.  */
   4672       add_stmt (body_start);
   4673       /* Re-start the ramp as must-not-throw.  */
   4674       TREE_OPERAND (body_start, 0) = push_stmt_list ();
   4675     }
   4676 
   4677   /* Create the coro frame type, as far as it can be known at this stage.
   4678      1. Types we already know.  */
   4679 
   4680   tree promise_type = get_coroutine_promise_type (orig);
   4681   tree fn_return_type = TREE_TYPE (TREE_TYPE (orig));
   4682   bool void_ramp_p = VOID_TYPE_P (fn_return_type);
   4683 
   4684   /* 2. Types we need to define or look up.  */
   4685 
   4686   tree fr_name = get_fn_local_identifier (orig, "Frame");
   4687   tree coro_frame_type = xref_tag (record_type, fr_name);
   4688   DECL_CONTEXT (TYPE_NAME (coro_frame_type)) = current_scope ();
   4689   tree coro_frame_ptr = build_pointer_type (coro_frame_type);
   4690   tree act_des_fn_type
   4691     = build_function_type_list (void_type_node, coro_frame_ptr, NULL_TREE);
   4692   tree act_des_fn_ptr = build_pointer_type (act_des_fn_type);
   4693 
   4694   /* Declare the actor and destroyer function.  */
   4695   tree actor = coro_build_actor_or_destroy_function (orig, act_des_fn_type,
   4696 						     coro_frame_ptr, true);
   4697   tree destroy = coro_build_actor_or_destroy_function (orig, act_des_fn_type,
   4698 						       coro_frame_ptr, false);
   4699 
   4700   /* Construct the wrapped function body; we will analyze this to determine
   4701      the requirements for the coroutine frame.  */
   4702 
   4703   tree resume_idx_var = NULL_TREE;
   4704   tree fs_label = NULL_TREE;
   4705   hash_map<tree, param_info> *param_uses = analyze_fn_parms (orig);
   4706 
   4707   fnbody = coro_rewrite_function_body (fn_start, fnbody, orig, param_uses,
   4708 				       act_des_fn_ptr,
   4709 				       resume_idx_var, fs_label);
   4710   /* Build our dummy coro frame layout.  */
   4711   coro_frame_type = begin_class_definition (coro_frame_type);
   4712 
   4713 
   4714   /* We need to know, and inspect, each suspend point in the function
   4715      in several places.  It's convenient to place this map out of line
   4716      since it's used from tree walk callbacks.  */
   4717 
   4718   hash_map<tree, suspend_point_info> suspend_points;
   4719   /* Now insert the data for any body await points, at this time we also need
   4720      to promote any temporaries that are captured by reference (to regular
   4721      vars) they will get added to the coro frame along with other locals.  */
   4722   susp_frame_data body_aw_points (fs_label, &suspend_points);
   4723   cp_walk_tree (&fnbody, await_statement_walker, &body_aw_points, NULL);
   4724 
   4725   /* 4. Now make space for local vars, this is conservative again, and we
   4726      would expect to delete unused entries later.  Compose the frame entries
   4727      list.  */
   4728 
   4729   /* The fields for the coro frame.  */
   4730   tree field_list = NULL_TREE;
   4731   hash_map<tree, local_var_info> local_var_uses;
   4732   local_vars_frame_data local_vars_data (&field_list, &local_var_uses);
   4733   cp_walk_tree_without_duplicates (&fnbody, register_local_var_uses,
   4734 				   &local_vars_data);
   4735 
   4736   /* Tie off the struct for now, so that we can build offsets to the
   4737      known entries.  */
   4738   TYPE_FIELDS (coro_frame_type) = field_list;
   4739   TYPE_BINFO (coro_frame_type) = make_tree_binfo (0);
   4740   BINFO_OFFSET (TYPE_BINFO (coro_frame_type)) = size_zero_node;
   4741   BINFO_TYPE (TYPE_BINFO (coro_frame_type)) = coro_frame_type;
   4742 
   4743   coro_frame_type = finish_struct (coro_frame_type, NULL_TREE);
   4744 
   4745   /* Ramp: */
   4746   /* Now build the ramp function pieces.  */
   4747   tree ramp_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
   4748   add_stmt (ramp_bind);
   4749   tree ramp_body = push_stmt_list ();
   4750 
   4751   tree zeroinit = build1_loc (fn_start, CONVERT_EXPR,
   4752 			      coro_frame_ptr, nullptr_node);
   4753   tree coro_fp = coro_build_artificial_var (fn_start, "_Coro_frameptr",
   4754 					    coro_frame_ptr, orig, zeroinit);
   4755   tree varlist = coro_fp;
   4756 
   4757   /* To signal that we need to cleanup copied function args.  */
   4758   if (flag_exceptions && DECL_ARGUMENTS (orig))
   4759     for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
   4760 	arg = DECL_CHAIN (arg))
   4761       {
   4762 	param_info *parm_i = param_uses->get (arg);
   4763 	gcc_checking_assert (parm_i);
   4764 	if (parm_i->trivial_dtor)
   4765 	  continue;
   4766 	DECL_CHAIN (parm_i->guard_var) = varlist;
   4767 	varlist = parm_i->guard_var;
   4768       }
   4769 
   4770   /* Signal that we need to clean up the promise object on exception.  */
   4771   tree coro_promise_live
   4772     = coro_build_artificial_var (fn_start, "_Coro_promise_live",
   4773 				 boolean_type_node, orig, boolean_false_node);
   4774   DECL_CHAIN (coro_promise_live) = varlist;
   4775   varlist = coro_promise_live;
   4776 
   4777   /* When the get-return-object is in the RETURN slot, we need to arrange for
   4778      cleanup on exception.  */
   4779   tree coro_gro_live
   4780     = coro_build_artificial_var (fn_start, "_Coro_gro_live",
   4781 				 boolean_type_node, orig, boolean_false_node);
   4782   DECL_CHAIN (coro_gro_live) = varlist;
   4783   varlist = coro_gro_live;
   4784 
   4785   tree coro_before_return
   4786     = coro_build_artificial_var (fn_start, "_Coro_before_return",
   4787 				 boolean_type_node, orig, boolean_true_node);
   4788   DECL_CHAIN (coro_before_return) = varlist;
   4789   varlist = coro_before_return;
   4790 
   4791   /* Collected the scope vars we need ... only one for now. */
   4792   BIND_EXPR_VARS (ramp_bind) = nreverse (varlist);
   4793 
   4794   /* We're now going to create a new top level scope block for the ramp
   4795      function.  */
   4796   tree top_block = make_node (BLOCK);
   4797 
   4798   BIND_EXPR_BLOCK (ramp_bind) = top_block;
   4799   BLOCK_VARS (top_block) = BIND_EXPR_VARS (ramp_bind);
   4800   BLOCK_SUBBLOCKS (top_block) = NULL_TREE;
   4801   current_binding_level->blocks = top_block;
   4802 
   4803   /* The decl_expr for the coro frame pointer, initialize to zero so that we
   4804      can pass it to the IFN_CO_FRAME (since there's no way to pass a type,
   4805      directly apparently).  This avoids a "used uninitialized" warning.  */
   4806 
   4807   add_decl_expr (coro_fp);
   4808   if (flag_exceptions && DECL_ARGUMENTS (orig))
   4809     for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
   4810 	arg = DECL_CHAIN (arg))
   4811       {
   4812 	param_info *parm_i = param_uses->get (arg);
   4813 	if (parm_i->trivial_dtor)
   4814 	  continue;
   4815 	add_decl_expr (parm_i->guard_var);;
   4816       }
   4817   add_decl_expr (coro_promise_live);
   4818   add_decl_expr (coro_gro_live);
   4819   add_decl_expr (coro_before_return);
   4820 
   4821   /* The CO_FRAME internal function is a mechanism to allow the middle end
   4822      to adjust the allocation in response to optimizations.  We provide the
   4823      current conservative estimate of the frame size (as per the current)
   4824      computed layout.  */
   4825   tree frame_size = TYPE_SIZE_UNIT (coro_frame_type);
   4826   tree resizeable
   4827     = build_call_expr_internal_loc (fn_start, IFN_CO_FRAME, size_type_node, 2,
   4828 				    frame_size, coro_fp);
   4829 
   4830   /* [dcl.fct.def.coroutine] / 10 (part1)
   4831     The unqualified-id get_return_object_on_allocation_failure is looked up
   4832     in the scope of the promise type by class member access lookup.  */
   4833 
   4834   /* We don't require this, so coro_build_promise_expression can return NULL,
   4835      but, if the lookup succeeds, then the function must be usable.  */
   4836   tree dummy_promise = build_dummy_object (get_coroutine_promise_type (orig));
   4837   tree grooaf
   4838     = coro_build_promise_expression (orig, dummy_promise,
   4839 				     coro_gro_on_allocation_fail_identifier,
   4840 				     fn_start, NULL, /*musthave=*/false);
   4841 
   4842   /* however, should that fail, returning an error, the later stages can't
   4843      handle the erroneous expression, so we reset the call as if it was
   4844      absent.  */
   4845   if (grooaf == error_mark_node)
   4846     grooaf = NULL_TREE;
   4847 
   4848   /* Allocate the frame, this has several possibilities:
   4849      [dcl.fct.def.coroutine] / 9 (part 1)
   4850      The allocation functions name is looked up in the scope of the promise
   4851      type.  It's not a failure for it to be absent see part 4, below.  */
   4852 
   4853   tree nwname = ovl_op_identifier (false, NEW_EXPR);
   4854   tree new_fn = NULL_TREE;
   4855 
   4856   if (TYPE_HAS_NEW_OPERATOR (promise_type))
   4857     {
   4858       tree fns = lookup_promise_method (orig, nwname, fn_start,
   4859 					/*musthave=*/true);
   4860       /* [dcl.fct.def.coroutine] / 9 (part 2)
   4861 	If the lookup finds an allocation function in the scope of the promise
   4862 	type, overload resolution is performed on a function call created by
   4863 	assembling an argument list.  The first argument is the amount of space
   4864 	requested, and has type std::size_t.  The lvalues p1...pn are the
   4865 	succeeding arguments..  */
   4866       vec<tree, va_gc> *args = make_tree_vector ();
   4867       vec_safe_push (args, resizeable); /* Space needed.  */
   4868 
   4869       for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
   4870 	   arg = DECL_CHAIN (arg))
   4871 	{
   4872 	  param_info *parm_i = param_uses->get (arg);
   4873 	  gcc_checking_assert (parm_i);
   4874 	  if (parm_i->this_ptr || parm_i->lambda_cobj)
   4875 	    {
   4876 	      /* We pass a reference to *this to the allocator lookup.  */
   4877 	      /* It's unsafe to use the cp_ version here since current_class_ref
   4878 		 might've gotten clobbered earlier during rewrite_param_uses.  */
   4879 	      tree this_ref = build_fold_indirect_ref (arg);
   4880 	      vec_safe_push (args, this_ref);
   4881 	    }
   4882 	  else
   4883 	    vec_safe_push (args, convert_from_reference (arg));
   4884 	}
   4885 
   4886       /* Note the function selected; we test to see if it's NOTHROW.  */
   4887       tree func;
   4888       /* Failure is not an error for this attempt.  */
   4889       new_fn = build_new_method_call (dummy_promise, fns, &args, NULL,
   4890 				      LOOKUP_NORMAL, &func, tf_none);
   4891       release_tree_vector (args);
   4892 
   4893       if (new_fn == error_mark_node)
   4894 	{
   4895 	  /* [dcl.fct.def.coroutine] / 9 (part 3)
   4896 	    If no viable function is found, overload resolution is performed
   4897 	    again on a function call created by passing just the amount of
   4898 	    space required as an argument of type std::size_t.  */
   4899 	  args = make_tree_vector_single (resizeable); /* Space needed.  */
   4900 	  new_fn = build_new_method_call (dummy_promise, fns, &args,
   4901 					  NULL_TREE, LOOKUP_NORMAL, &func,
   4902 					  tf_none);
   4903 	  release_tree_vector (args);
   4904 	}
   4905 
   4906      /* However, if the promise provides an operator new, then one of these
   4907 	two options must be available.  */
   4908     if (new_fn == error_mark_node)
   4909       {
   4910 	error_at (fn_start, "%qE is provided by %qT but is not usable with"
   4911 		  " the function signature %qD", nwname, promise_type, orig);
   4912 	new_fn = error_mark_node;
   4913       }
   4914     else if (grooaf && !TYPE_NOTHROW_P (TREE_TYPE (func)))
   4915       error_at (fn_start, "%qE is provided by %qT but %qE is not marked"
   4916 		" %<throw()%> or %<noexcept%>", grooaf, promise_type, nwname);
   4917     else if (!grooaf && TYPE_NOTHROW_P (TREE_TYPE (func)))
   4918       warning_at (fn_start, 0, "%qE is marked %<throw()%> or %<noexcept%> but"
   4919 		  " no usable %<get_return_object_on_allocation_failure%>"
   4920 		  " is provided by %qT", nwname, promise_type);
   4921     }
   4922   else /* No operator new in the promise.  */
   4923     {
   4924       /* [dcl.fct.def.coroutine] / 9 (part 4)
   4925 	 If this lookup fails, the allocation functions name is looked up in
   4926 	 the global scope.  */
   4927 
   4928       vec<tree, va_gc> *args;
   4929       /* build_operator_new_call () will insert size needed as element 0 of
   4930 	 this, and we might need to append the std::nothrow constant.  */
   4931       vec_alloc (args, 2);
   4932       if (grooaf)
   4933 	{
   4934 	  /* [dcl.fct.def.coroutine] / 10 (part 2)
   4935 	   If any declarations (of the get return on allocation fail) are
   4936 	   found, then the result of a call to an allocation function used
   4937 	   to obtain storage for the coroutine state is assumed to return
   4938 	   nullptr if it fails to obtain storage and, if a global allocation
   4939 	   function is selected, the ::operator new(size_t, nothrow_t) form
   4940 	   is used.  The allocation function used in this case shall have a
   4941 	   non-throwing noexcept-specification.  So we need std::nothrow.  */
   4942 	  tree std_nt = lookup_qualified_name (std_node,
   4943 					       get_identifier ("nothrow"),
   4944 					       LOOK_want::NORMAL,
   4945 					       /*complain=*/true);
   4946 	  if (!std_nt || std_nt == error_mark_node)
   4947 	    error_at (fn_start, "%qE is provided by %qT but %<std::nothrow%> "
   4948 		      "cannot be found", grooaf, promise_type);
   4949 	  vec_safe_push (args, std_nt);
   4950 	}
   4951 
   4952       /* If we get to this point, we must succeed in looking up the global
   4953 	 operator new for the params provided.  Extract a simplified version
   4954 	 of the machinery from build_operator_new_call.  This can update the
   4955 	 frame size.  */
   4956       tree cookie = NULL;
   4957       new_fn = build_operator_new_call (nwname, &args, &frame_size, &cookie,
   4958 					/*align_arg=*/NULL,
   4959 					/*size_check=*/NULL, /*fn=*/NULL,
   4960 					tf_warning_or_error);
   4961       resizeable = build_call_expr_internal_loc
   4962 	(fn_start, IFN_CO_FRAME, size_type_node, 2, frame_size, coro_fp);
   4963       /* If the operator call fails for some reason, then don't try to
   4964 	 amend it.  */
   4965       if (new_fn != error_mark_node)
   4966 	CALL_EXPR_ARG (new_fn, 0) = resizeable;
   4967 
   4968       release_tree_vector (args);
   4969     }
   4970 
   4971   tree allocated = build1 (CONVERT_EXPR, coro_frame_ptr, new_fn);
   4972   tree r = cp_build_init_expr (coro_fp, allocated);
   4973   finish_expr_stmt (r);
   4974 
   4975   /* deref the frame pointer, to use in member access code.  */
   4976   tree deref_fp = build_x_arrow (fn_start, coro_fp, tf_warning_or_error);
   4977 
   4978   /* If the user provided a method to return an object on alloc fail, then
   4979      check the returned pointer and call the func if it's null.
   4980      Otherwise, no check, and we fail for noexcept/fno-exceptions cases.  */
   4981 
   4982   if (grooaf)
   4983     {
   4984       /* [dcl.fct.def.coroutine] / 10 (part 3)
   4985 	 If the allocation function returns nullptr,the coroutine returns
   4986 	 control to the caller of the coroutine and the return value is
   4987 	 obtained by a call to T::get_return_object_on_allocation_failure(),
   4988 	 where T is the promise type.  */
   4989       tree if_stmt = begin_if_stmt ();
   4990       tree cond = build1 (CONVERT_EXPR, coro_frame_ptr, nullptr_node);
   4991       cond = build2 (EQ_EXPR, boolean_type_node, coro_fp, cond);
   4992       finish_if_stmt_cond (cond, if_stmt);
   4993       r = NULL_TREE;
   4994       if (void_ramp_p)
   4995 	/* Execute the get-return-object-on-alloc-fail call...  */
   4996 	finish_expr_stmt (grooaf);
   4997       else
   4998 	/* Get the fallback return object.  */
   4999 	r = grooaf;
   5000       finish_return_stmt (r);
   5001       finish_then_clause (if_stmt);
   5002       finish_if_stmt (if_stmt);
   5003     }
   5004 
   5005   /* Up to now any exception thrown will propagate directly to the caller.
   5006      This is OK since the only source of such exceptions would be in allocation
   5007      of the coroutine frame, and therefore the ramp will not have initialized
   5008      any further state.  From here, we will track state that needs explicit
   5009      destruction in the case that promise or g.r.o setup fails or an exception
   5010      is thrown from the initial suspend expression.  */
   5011   tree ramp_cleanup = NULL_TREE;
   5012   tree iarc_x = NULL_TREE;
   5013   if (flag_exceptions)
   5014     {
   5015       iarc_x = lookup_member (coro_frame_type, coro_frame_i_a_r_c_id,
   5016 		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
   5017       iarc_x
   5018 	= build_class_member_access_expr (deref_fp, iarc_x, NULL_TREE, false,
   5019 					  tf_warning_or_error);
   5020       r = cp_build_init_expr (iarc_x, boolean_false_node);
   5021       finish_expr_stmt (r);
   5022 
   5023       ramp_cleanup = build_stmt (fn_start, TRY_BLOCK, NULL, NULL);
   5024       add_stmt (ramp_cleanup);
   5025       TRY_STMTS (ramp_cleanup) = push_stmt_list ();
   5026     }
   5027 
   5028   /* For now, once allocation has succeeded we always assume that this needs
   5029      destruction, there's no impl. for frame allocation elision.  */
   5030   tree fnf_m = lookup_member (coro_frame_type, coro_frame_needs_free_id,
   5031 			      1, 0,tf_warning_or_error);
   5032   tree fnf_x = build_class_member_access_expr (deref_fp, fnf_m, NULL_TREE,
   5033 					       false, tf_warning_or_error);
   5034   r = cp_build_init_expr (fnf_x, boolean_true_node);
   5035   finish_expr_stmt (r);
   5036 
   5037   /* Put the resumer and destroyer functions in.  */
   5038 
   5039   tree actor_addr = build1 (ADDR_EXPR, act_des_fn_ptr, actor);
   5040   tree resume_m
   5041     = lookup_member (coro_frame_type, coro_resume_fn_id,
   5042 		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
   5043   tree resume_x = build_class_member_access_expr (deref_fp, resume_m, NULL_TREE,
   5044 						  false, tf_warning_or_error);
   5045   r = cp_build_init_expr (fn_start, resume_x, actor_addr);
   5046   finish_expr_stmt (r);
   5047 
   5048   tree destroy_addr = build1 (ADDR_EXPR, act_des_fn_ptr, destroy);
   5049   tree destroy_m
   5050     = lookup_member (coro_frame_type, coro_destroy_fn_id,
   5051 		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
   5052   tree destroy_x
   5053     = build_class_member_access_expr (deref_fp, destroy_m, NULL_TREE, false,
   5054 				      tf_warning_or_error);
   5055   r = cp_build_init_expr (fn_start, destroy_x, destroy_addr);
   5056   finish_expr_stmt (r);
   5057 
   5058   /* [dcl.fct.def.coroutine] /13
   5059      When a coroutine is invoked, a copy is created for each coroutine
   5060      parameter.  Each such copy is an object with automatic storage duration
   5061      that is direct-initialized from an lvalue referring to the corresponding
   5062      parameter if the parameter is an lvalue reference, and from an xvalue
   5063      referring to it otherwise.  A reference to a parameter in the function-
   5064      body of the coroutine and in the call to the coroutine promise
   5065      constructor is replaced by a reference to its copy.  */
   5066 
   5067   vec<tree, va_gc> *promise_args = NULL; /* So that we can adjust refs.  */
   5068 
   5069   /* The initialization and destruction of each parameter copy occurs in the
   5070      context of the called coroutine.  Initializations of parameter copies are
   5071      sequenced before the call to the coroutine promise constructor and
   5072      indeterminately sequenced with respect to each other.  The lifetime of
   5073      parameter copies ends immediately after the lifetime of the coroutine
   5074      promise object ends.  */
   5075 
   5076   vec<tree, va_gc> *param_dtor_list = NULL;
   5077 
   5078   if (DECL_ARGUMENTS (orig))
   5079     {
   5080       promise_args = make_tree_vector ();
   5081       for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
   5082 	   arg = DECL_CHAIN (arg))
   5083 	{
   5084 	  bool existed;
   5085 	  param_info &parm = param_uses->get_or_insert (arg, &existed);
   5086 
   5087 	  tree fld_ref = lookup_member (coro_frame_type, parm.field_id,
   5088 					/*protect=*/1, /*want_type=*/0,
   5089 					tf_warning_or_error);
   5090 	  tree fld_idx
   5091 	    = build_class_member_access_expr (deref_fp, fld_ref, NULL_TREE,
   5092 					      false, tf_warning_or_error);
   5093 
   5094 	  /* Add this to the promise CTOR arguments list, accounting for
   5095 	     refs and special handling for method this ptr.  */
   5096 	  if (parm.this_ptr || parm.lambda_cobj)
   5097 	    {
   5098 	      /* We pass a reference to *this to the param preview.  */
   5099 	      /* It's unsafe to use the cp_ version here since current_class_ref
   5100 		 might've gotten clobbered earlier during rewrite_param_uses.  */
   5101 	      tree this_ref = build_fold_indirect_ref (arg);
   5102 	      vec_safe_push (promise_args, this_ref);
   5103 	    }
   5104 	  else if (parm.rv_ref)
   5105 	    vec_safe_push (promise_args, move (fld_idx));
   5106 	  else
   5107 	    vec_safe_push (promise_args, fld_idx);
   5108 
   5109 	  if (parm.rv_ref || parm.pt_ref)
   5110 	    /* Initialise the frame reference field directly.  */
   5111 	    r = build2 (INIT_EXPR, TREE_TYPE (arg),
   5112 			TREE_OPERAND (fld_idx, 0), arg);
   5113 	  else
   5114 	    {
   5115 	      r = forward_parm (arg);
   5116 	      r = cp_build_modify_expr (fn_start, fld_idx, INIT_EXPR, r,
   5117 					tf_warning_or_error);
   5118 	    }
   5119 	  finish_expr_stmt (r);
   5120 	  if (!parm.trivial_dtor)
   5121 	    {
   5122 	      if (param_dtor_list == NULL)
   5123 		param_dtor_list = make_tree_vector ();
   5124 	      vec_safe_push (param_dtor_list, parm.field_id);
   5125 	      /* Cleanup this frame copy on exception.  */
   5126 	      parm.fr_copy_dtor
   5127 		= cxx_maybe_build_cleanup (fld_idx, tf_warning_or_error);
   5128 	      if (flag_exceptions)
   5129 		{
   5130 		  /* This var is now live.  */
   5131 		  r = build_modify_expr (fn_start, parm.guard_var,
   5132 					 boolean_type_node, INIT_EXPR, fn_start,
   5133 					 boolean_true_node, boolean_type_node);
   5134 		  finish_expr_stmt (r);
   5135 		}
   5136 	    }
   5137 	}
   5138     }
   5139 
   5140   /* Set up the promise.  */
   5141   tree promise_m
   5142     = lookup_member (coro_frame_type, coro_promise_id,
   5143 		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
   5144 
   5145   tree p = build_class_member_access_expr (deref_fp, promise_m, NULL_TREE,
   5146 					   false, tf_warning_or_error);
   5147 
   5148   if (type_build_ctor_call (promise_type))
   5149     {
   5150       /* Construct the promise object [dcl.fct.def.coroutine] / 5.7.
   5151 
   5152 	 First try to find a constructor with an argument list comprised of
   5153 	 the parameter copies.  */
   5154 
   5155       if (DECL_ARGUMENTS (orig))
   5156 	{
   5157 	  r = build_special_member_call (p, complete_ctor_identifier,
   5158 					 &promise_args, promise_type,
   5159 					 LOOKUP_NORMAL, tf_none);
   5160 	  release_tree_vector (promise_args);
   5161 	}
   5162       else
   5163 	r = NULL_TREE;
   5164 
   5165       /* If that fails then the promise constructor argument list is empty.  */
   5166       if (r == NULL_TREE || r == error_mark_node)
   5167 	r = build_special_member_call (p, complete_ctor_identifier, NULL,
   5168 				       promise_type, LOOKUP_NORMAL,
   5169 				       tf_warning_or_error);
   5170 
   5171       /* If type_build_ctor_call() encounters deprecated implicit CTORs it will
   5172 	 return true, and therefore we will execute this code path.  However,
   5173 	 we might well not actually require a CTOR and under those conditions
   5174 	 the build call above will not return a call expression, but the
   5175 	 original instance object.  Do not attempt to add the statement unless
   5176 	 it has side-effects.  */
   5177       if (r && r != error_mark_node && TREE_SIDE_EFFECTS (r))
   5178 	finish_expr_stmt (r);
   5179     }
   5180 
   5181   tree promise_dtor = cxx_maybe_build_cleanup (p, tf_warning_or_error);;
   5182   if (flag_exceptions && promise_dtor)
   5183     {
   5184       r = cp_build_init_expr (coro_promise_live, boolean_true_node);
   5185       finish_expr_stmt (r);
   5186     }
   5187 
   5188   /* Set up a new bind context for the GRO.  */
   5189   tree gro_context_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
   5190   /* Make and connect the scope blocks.  */
   5191   tree gro_block = make_node (BLOCK);
   5192   BLOCK_SUPERCONTEXT (gro_block) = top_block;
   5193   BLOCK_SUBBLOCKS (top_block) = gro_block;
   5194   BIND_EXPR_BLOCK (gro_context_bind) = gro_block;
   5195   add_stmt (gro_context_bind);
   5196 
   5197   tree get_ro
   5198     = coro_build_promise_expression (orig, p,
   5199 				     coro_get_return_object_identifier,
   5200 				     fn_start, NULL, /*musthave=*/true);
   5201   /* Without a return object we haven't got much clue what's going on.  */
   5202   if (!get_ro || get_ro == error_mark_node)
   5203     {
   5204       BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
   5205       DECL_SAVED_TREE (orig) = newbody;
   5206       /* Suppress warnings about the missing return value.  */
   5207       suppress_warning (orig, OPT_Wreturn_type);
   5208       return false;
   5209     }
   5210 
   5211   /* Check for a bad get return object type.
   5212      [dcl.fct.def.coroutine] / 7 requires:
   5213      The expression promise.get_return_object() is used to initialize the
   5214      returned reference or prvalue result object ... */
   5215   tree gro_type = TREE_TYPE (get_ro);
   5216   if (VOID_TYPE_P (gro_type) && !void_ramp_p)
   5217     {
   5218       error_at (fn_start, "no viable conversion from %<void%> provided by"
   5219 		" %<get_return_object%> to return type %qT", fn_return_type);
   5220       return false;
   5221     }
   5222 
   5223   tree gro_context_body = push_stmt_list ();
   5224 
   5225   tree gro = NULL_TREE;
   5226   tree gro_bind_vars = NULL_TREE;
   5227   /* Used for return objects in the RESULT slot.  */
   5228   tree gro_ret_dtor = NULL_TREE;
   5229   tree gro_cleanup_stmt = NULL_TREE;
   5230   /* We have to sequence the call to get_return_object before initial
   5231      suspend.  */
   5232   if (void_ramp_p)
   5233     {
   5234       gcc_checking_assert (VOID_TYPE_P (gro_type));
   5235       r = get_ro;
   5236     }
   5237   else if (same_type_p (gro_type, fn_return_type))
   5238     {
   5239      /* [dcl.fct.def.coroutine] / 7
   5240 	The expression promise.get_return_object() is used to initialize the
   5241 	glvalue result or... (see below)
   5242 	Construct the return result directly.  */
   5243       if (type_build_ctor_call (gro_type))
   5244 	{
   5245 	  vec<tree, va_gc> *arg = make_tree_vector_single (get_ro);
   5246 	  r = build_special_member_call (DECL_RESULT (orig),
   5247 					 complete_ctor_identifier,
   5248 					 &arg, gro_type, LOOKUP_NORMAL,
   5249 					 tf_warning_or_error);
   5250 	  release_tree_vector (arg);
   5251 	}
   5252       else
   5253 	r = cp_build_init_expr (fn_start, DECL_RESULT (orig), get_ro);
   5254 
   5255       if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (gro_type))
   5256 	/* If some part of the initalization code (prior to the await_resume
   5257 	     of the initial suspend expression), then we need to clean up the
   5258 	     return value.  */
   5259 	gro_ret_dtor = cxx_maybe_build_cleanup (DECL_RESULT (orig),
   5260 						tf_warning_or_error);
   5261     }
   5262   else
   5263     {
   5264       /* ... or ... Construct an object that will be used as the single
   5265 	param to the CTOR for the return object.  */
   5266       gro = coro_build_artificial_var (fn_start, "_Coro_gro", gro_type, orig,
   5267 				       NULL_TREE);
   5268       add_decl_expr (gro);
   5269       gro_bind_vars = gro;
   5270       r = cp_build_modify_expr (input_location, gro, INIT_EXPR, get_ro,
   5271 				tf_warning_or_error);
   5272       /* The constructed object might require a cleanup.  */
   5273       if (tree cleanup = cxx_maybe_build_cleanup (gro, tf_warning_or_error))
   5274 	gro_cleanup_stmt = build_stmt (input_location, CLEANUP_STMT, NULL,
   5275 				       cleanup, gro);
   5276     }
   5277   finish_expr_stmt (r);
   5278 
   5279   if (gro_cleanup_stmt && gro_cleanup_stmt != error_mark_node)
   5280     CLEANUP_BODY (gro_cleanup_stmt) = push_stmt_list ();
   5281 
   5282   /* If we have a live g.r.o in the return slot, then signal this for exception
   5283      cleanup.  */
   5284   if (gro_ret_dtor)
   5285     {
   5286        r = build_modify_expr (fn_start, coro_gro_live, boolean_type_node,
   5287 			      INIT_EXPR, fn_start, boolean_true_node,
   5288 			      boolean_type_node);
   5289       finish_expr_stmt (r);
   5290     }
   5291   /* Initialize the resume_idx_var to 0, meaning "not started".  */
   5292   tree resume_idx_m
   5293     = lookup_member (coro_frame_type, coro_resume_index_id,
   5294 		     /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
   5295   tree resume_idx
   5296     = build_class_member_access_expr (deref_fp, resume_idx_m, NULL_TREE, false,
   5297 				      tf_warning_or_error);
   5298   r = build_int_cst (short_unsigned_type_node, 0);
   5299   r = cp_build_init_expr (fn_start, resume_idx, r);
   5300   r = coro_build_cvt_void_expr_stmt (r, fn_start);
   5301   add_stmt (r);
   5302 
   5303   /* So .. call the actor ..  */
   5304   r = build_call_expr_loc (fn_start, actor, 1, coro_fp);
   5305   r = maybe_cleanup_point_expr_void (r);
   5306   add_stmt (r);
   5307 
   5308   /* Switch to using 'input_location' as the loc, since we're now more
   5309      logically doing things related to the end of the function.  */
   5310 
   5311   /* The ramp is done, we just need the return value.
   5312      [dcl.fct.def.coroutine] / 7
   5313      The expression promise.get_return_object() is used to initialize the
   5314      glvalue result or prvalue result object of a call to a coroutine.
   5315 
   5316      If the 'get return object' is non-void, then we built it before the
   5317      promise was constructed.  We now supply a reference to that var,
   5318      either as the return value (if it's the same type) or to the CTOR
   5319      for an object of the return type.  */
   5320 
   5321   r = build_modify_expr (fn_start, coro_before_return, boolean_type_node,
   5322 			 INIT_EXPR, fn_start, boolean_false_node,
   5323 			 boolean_type_node);
   5324   finish_expr_stmt (r);
   5325 
   5326   /* We must manage the cleanups ourselves, because the responsibility for
   5327      them changes after the initial suspend.  However, any use of
   5328      cxx_maybe_build_cleanup () can set the throwing_cleanup flag.  */
   5329   cp_function_chain->throwing_cleanup = false;
   5330   if (same_type_p (gro_type, fn_return_type))
   5331     r = void_ramp_p ? NULL_TREE : DECL_RESULT (orig);
   5332   else
   5333     /* check_return_expr will automatically return gro as an rvalue via
   5334        treat_lvalue_as_rvalue_p.  */
   5335     r = gro;
   5336 
   5337   finish_return_stmt (r);
   5338 
   5339   if (gro_cleanup_stmt)
   5340     {
   5341       CLEANUP_BODY (gro_cleanup_stmt)
   5342 	= pop_stmt_list (CLEANUP_BODY (gro_cleanup_stmt));
   5343       add_stmt (gro_cleanup_stmt);
   5344     }
   5345 
   5346   /* Finish up the ramp function.  */
   5347   BIND_EXPR_VARS (gro_context_bind) = gro_bind_vars;
   5348   BIND_EXPR_BODY (gro_context_bind) = pop_stmt_list (gro_context_body);
   5349   TREE_SIDE_EFFECTS (gro_context_bind) = true;
   5350 
   5351   if (flag_exceptions)
   5352     {
   5353       TRY_HANDLERS (ramp_cleanup) = push_stmt_list ();
   5354       tree handler = begin_handler ();
   5355       finish_handler_parms (NULL_TREE, handler); /* catch (...) */
   5356 
   5357       /* If we have a live G.R.O in the return slot, then run its DTOR.
   5358      When the return object is constructed from a separate g.r.o, this is
   5359      already handled by its regular cleanup.  */
   5360       if (gro_ret_dtor && gro_ret_dtor != error_mark_node)
   5361 	{
   5362 	  tree gro_d_if = begin_if_stmt ();
   5363 	  finish_if_stmt_cond (coro_gro_live, gro_d_if);
   5364 	  finish_expr_stmt (gro_ret_dtor);
   5365 	  finish_then_clause (gro_d_if);
   5366 	  tree gro_d_if_scope = IF_SCOPE (gro_d_if);
   5367 	  IF_SCOPE (gro_d_if) = NULL;
   5368 	  gro_d_if = do_poplevel (gro_d_if_scope);
   5369 	  add_stmt (gro_d_if);
   5370 	}
   5371 
   5372       tree gating_if = begin_if_stmt ();
   5373       tree gate = build1 (TRUTH_NOT_EXPR, boolean_type_node, iarc_x);
   5374       gate = build2 (TRUTH_AND_EXPR, boolean_type_node, coro_before_return,
   5375 		     gate);
   5376       finish_if_stmt_cond (gate, gating_if);
   5377 
   5378       /* If the promise is live, then run its dtor if that's available.  */
   5379       if (promise_dtor && promise_dtor != error_mark_node)
   5380 	{
   5381 	  tree promise_d_if = begin_if_stmt ();
   5382 	  finish_if_stmt_cond (coro_promise_live, promise_d_if);
   5383 	  finish_expr_stmt (promise_dtor);
   5384 	  finish_then_clause (promise_d_if);
   5385 	  tree promise_d_if_scope = IF_SCOPE (promise_d_if);
   5386 	  IF_SCOPE (promise_d_if) = NULL;
   5387 	  promise_d_if = do_poplevel (promise_d_if_scope);
   5388 	  add_stmt (promise_d_if);
   5389 	}
   5390 
   5391       /* Clean up any frame copies of parms with non-trivial dtors.  */
   5392       if (DECL_ARGUMENTS (orig))
   5393 	for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
   5394 	     arg = DECL_CHAIN (arg))
   5395 	  {
   5396 	    param_info *parm_i = param_uses->get (arg);
   5397 	    if (parm_i->trivial_dtor)
   5398 	      continue;
   5399 	    if (parm_i->fr_copy_dtor && parm_i->fr_copy_dtor != error_mark_node)
   5400 	      {
   5401 		tree dtor_if = begin_if_stmt ();
   5402 		finish_if_stmt_cond (parm_i->guard_var, dtor_if);
   5403 		finish_expr_stmt (parm_i->fr_copy_dtor);
   5404 		finish_then_clause (dtor_if);
   5405 		tree parm_d_if_scope = IF_SCOPE (dtor_if);
   5406 		IF_SCOPE (dtor_if) = NULL;
   5407 		dtor_if = do_poplevel (parm_d_if_scope);
   5408 		add_stmt (dtor_if);
   5409 	      }
   5410 	  }
   5411 
   5412       /* We always expect to delete the frame.  */
   5413       tree del_coro_fr = coro_get_frame_dtor (coro_fp, orig, frame_size,
   5414 					      promise_type, fn_start);
   5415       finish_expr_stmt (del_coro_fr);
   5416       finish_then_clause (gating_if);
   5417       finish_if_stmt (gating_if);
   5418 
   5419       tree rethrow = build_throw (fn_start, NULL_TREE, tf_warning_or_error);
   5420       suppress_warning (rethrow);
   5421       finish_expr_stmt (rethrow);
   5422       finish_handler (handler);
   5423       TRY_HANDLERS (ramp_cleanup) = pop_stmt_list (TRY_HANDLERS (ramp_cleanup));
   5424     }
   5425 
   5426   BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
   5427   TREE_SIDE_EFFECTS (ramp_bind) = true;
   5428 
   5429   /* Start to build the final functions.
   5430 
   5431      We push_deferring_access_checks to avoid these routines being seen as
   5432      nested by the middle end; we are doing the outlining here.  */
   5433 
   5434   push_deferring_access_checks (dk_no_check);
   5435 
   5436   /* Build the actor...  */
   5437   build_actor_fn (fn_start, coro_frame_type, actor, fnbody, orig,
   5438 		  &local_var_uses, &suspend_points, param_dtor_list,
   5439 		  resume_idx_var, body_aw_points.await_number, frame_size);
   5440 
   5441   /* Destroyer ... */
   5442   build_destroy_fn (fn_start, coro_frame_type, destroy, actor);
   5443 
   5444   pop_deferring_access_checks ();
   5445 
   5446   DECL_SAVED_TREE (orig) = newbody;
   5447   /* Link our new functions into the list.  */
   5448   TREE_CHAIN (destroy) = TREE_CHAIN (orig);
   5449   TREE_CHAIN (actor) = destroy;
   5450   TREE_CHAIN (orig) = actor;
   5451 
   5452   *resumer = actor;
   5453   *destroyer = destroy;
   5454 
   5455   return true;
   5456 }
   5457 
   5458 #include "gt-cp-coroutines.h"
   5459 
   5460