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, ¶m_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