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 if (name_independent_decl_p (lvar)) 4203 lvname = NULL_TREE; 4204 4205 /* The outermost bind scope contains the artificial variables that 4206 we inject to implement the coro state machine. We want to be able 4207 to inspect these in debugging. */ 4208 if (lvname != NULL_TREE && lvd->nest_depth == 0) 4209 buf = xasprintf ("%s", IDENTIFIER_POINTER (lvname)); 4210 else if (lvname != NULL_TREE) 4211 buf = xasprintf ("%s_%u_%u", IDENTIFIER_POINTER (lvname), 4212 lvd->nest_depth, lvd->bind_indx); 4213 else 4214 buf = xasprintf ("_D%u_%u_%u", lvd->nest_depth, lvd->bind_indx, 4215 serial++); 4216 4217 /* TODO: Figure out if we should build a local type that has any 4218 excess alignment or size from the original decl. */ 4219 local_var.field_id = coro_make_frame_entry (lvd->field_list, buf, 4220 lvtype, lvd->loc); 4221 free (buf); 4222 /* We don't walk any of the local var sub-trees, they won't contain 4223 any bind exprs. */ 4224 } 4225 lvd->bind_indx++; 4226 lvd->nest_depth++; 4227 /* Ensure we only visit each expression once. */ 4228 cp_walk_tree_without_duplicates (&BIND_EXPR_BODY (*stmt), 4229 register_local_var_uses, d); 4230 *do_subtree = 0; /* We've done this. */ 4231 lvd->nest_depth--; 4232 return NULL_TREE; 4233 } 4234 4235 /* Build, return FUNCTION_DECL node based on ORIG with a type FN_TYPE which has 4236 a single argument of type CORO_FRAME_PTR. Build the actor function if 4237 ACTOR_P is true, otherwise the destroy. */ 4238 4239 static tree 4240 coro_build_actor_or_destroy_function (tree orig, tree fn_type, 4241 tree coro_frame_ptr, bool actor_p) 4242 { 4243 location_t loc = DECL_SOURCE_LOCATION (orig); 4244 tree fn 4245 = build_lang_decl (FUNCTION_DECL, copy_node (DECL_NAME (orig)), fn_type); 4246 4247 /* Allow for locating the ramp (original) function from this one. */ 4248 if (!to_ramp) 4249 to_ramp = hash_map<tree, tree>::create_ggc (10); 4250 to_ramp->put (fn, orig); 4251 4252 DECL_CONTEXT (fn) = DECL_CONTEXT (orig); 4253 DECL_SOURCE_LOCATION (fn) = loc; 4254 DECL_ARTIFICIAL (fn) = true; 4255 DECL_INITIAL (fn) = error_mark_node; 4256 4257 tree id = get_identifier ("frame_ptr"); 4258 tree fp = build_lang_decl (PARM_DECL, id, coro_frame_ptr); 4259 DECL_ARTIFICIAL (fp) = true; 4260 DECL_CONTEXT (fp) = fn; 4261 DECL_ARG_TYPE (fp) = type_passed_as (coro_frame_ptr); 4262 DECL_ARGUMENTS (fn) = fp; 4263 4264 /* Copy selected attributes from the original function. */ 4265 TREE_USED (fn) = TREE_USED (orig); 4266 if (DECL_SECTION_NAME (orig)) 4267 set_decl_section_name (fn, orig); 4268 /* Copy any alignment that the FE added. */ 4269 if (DECL_ALIGN (orig)) 4270 SET_DECL_ALIGN (fn, DECL_ALIGN (orig)); 4271 /* Copy any alignment the user added. */ 4272 DECL_USER_ALIGN (fn) = DECL_USER_ALIGN (orig); 4273 /* Apply attributes from the original fn. */ 4274 DECL_ATTRIBUTES (fn) = copy_list (DECL_ATTRIBUTES (orig)); 4275 /* but we do not want ones for contracts. */ 4276 remove_contract_attributes (fn); 4277 4278 /* A void return. */ 4279 tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node); 4280 DECL_CONTEXT (resdecl) = fn; 4281 DECL_ARTIFICIAL (resdecl) = 1; 4282 DECL_IGNORED_P (resdecl) = 1; 4283 DECL_RESULT (fn) = resdecl; 4284 4285 /* This is a coroutine component. */ 4286 DECL_COROUTINE_P (fn) = 1; 4287 4288 /* Set up a means to find out if a decl is one of the helpers and, if so, 4289 which one. */ 4290 if (coroutine_info *info = get_coroutine_info (orig)) 4291 { 4292 gcc_checking_assert ((actor_p && info->actor_decl == NULL_TREE) 4293 || info->destroy_decl == NULL_TREE); 4294 if (actor_p) 4295 info->actor_decl = fn; 4296 else 4297 info->destroy_decl = fn; 4298 } 4299 return fn; 4300 } 4301 4302 /* Re-write the body as per [dcl.fct.def.coroutine] / 5. */ 4303 4304 static tree 4305 coro_rewrite_function_body (location_t fn_start, tree fnbody, tree orig, 4306 hash_map<tree, param_info> *param_uses, 4307 tree resume_fn_ptr_type, 4308 tree& resume_idx_var, tree& fs_label) 4309 { 4310 /* This will be our new outer scope. */ 4311 tree update_body = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); 4312 tree top_block = make_node (BLOCK); 4313 BIND_EXPR_BLOCK (update_body) = top_block; 4314 BIND_EXPR_BODY (update_body) = push_stmt_list (); 4315 4316 /* If the function has a top level bind expression, then connect that 4317 after first making sure we give it a new block. */ 4318 tree first = expr_first (fnbody); 4319 if (first && TREE_CODE (first) == BIND_EXPR) 4320 { 4321 tree block = BIND_EXPR_BLOCK (first); 4322 gcc_checking_assert (block); 4323 gcc_checking_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE); 4324 gcc_checking_assert (BLOCK_CHAIN (block) == NULL_TREE); 4325 /* Replace the top block to avoid issues with locations for args 4326 appearing to be in a non-existent place. */ 4327 tree replace_blk = make_node (BLOCK); 4328 BLOCK_VARS (replace_blk) = BLOCK_VARS (block); 4329 BLOCK_SUBBLOCKS (replace_blk) = BLOCK_SUBBLOCKS (block); 4330 for (tree b = BLOCK_SUBBLOCKS (replace_blk); b; b = BLOCK_CHAIN (b)) 4331 BLOCK_SUPERCONTEXT (b) = replace_blk; 4332 BIND_EXPR_BLOCK (first) = replace_blk; 4333 /* The top block has one child, so far, and we have now got a 4334 superblock. */ 4335 BLOCK_SUPERCONTEXT (replace_blk) = top_block; 4336 BLOCK_SUBBLOCKS (top_block) = replace_blk; 4337 } 4338 else 4339 { 4340 /* We are missing a top level BIND_EXPR. We need one to ensure that we 4341 don't shuffle around the coroutine frame and corrupt it. */ 4342 tree bind_wrap = build3_loc (fn_start, BIND_EXPR, void_type_node, 4343 NULL, NULL, NULL); 4344 BIND_EXPR_BODY (bind_wrap) = fnbody; 4345 /* Ensure we have a block to connect up the scopes. */ 4346 tree new_blk = make_node (BLOCK); 4347 BIND_EXPR_BLOCK (bind_wrap) = new_blk; 4348 BLOCK_SUBBLOCKS (top_block) = new_blk; 4349 fnbody = bind_wrap; 4350 } 4351 4352 /* Wrap the function body in a try {} catch (...) {} block, if exceptions 4353 are enabled. */ 4354 tree var_list = NULL_TREE; 4355 tree initial_await = build_init_or_final_await (fn_start, false); 4356 4357 /* [stmt.return.coroutine] / 3 4358 If p.return_void() is a valid expression, flowing off the end of a 4359 coroutine is equivalent to a co_return with no operand; otherwise 4360 flowing off the end of a coroutine results in undefined behavior. */ 4361 tree return_void 4362 = get_coroutine_return_void_expr (current_function_decl, fn_start, false); 4363 4364 /* The pointer to the resume function. */ 4365 tree resume_fn_ptr 4366 = coro_build_artificial_var (fn_start, coro_resume_fn_id, 4367 resume_fn_ptr_type, orig, NULL_TREE); 4368 DECL_CHAIN (resume_fn_ptr) = var_list; 4369 var_list = resume_fn_ptr; 4370 add_decl_expr (resume_fn_ptr); 4371 4372 /* We will need to be able to set the resume function pointer to nullptr 4373 to signal that the coroutine is 'done'. */ 4374 tree zero_resume 4375 = build1 (CONVERT_EXPR, resume_fn_ptr_type, nullptr_node); 4376 4377 /* The pointer to the destroy function. */ 4378 tree var = coro_build_artificial_var (fn_start, coro_destroy_fn_id, 4379 resume_fn_ptr_type, orig, NULL_TREE); 4380 DECL_CHAIN (var) = var_list; 4381 var_list = var; 4382 add_decl_expr (var); 4383 4384 /* The promise was created on demand when parsing we now link it into 4385 our scope. */ 4386 tree promise = get_coroutine_promise_proxy (orig); 4387 DECL_CONTEXT (promise) = orig; 4388 DECL_SOURCE_LOCATION (promise) = fn_start; 4389 DECL_CHAIN (promise) = var_list; 4390 var_list = promise; 4391 add_decl_expr (promise); 4392 4393 /* We need a handle to this coroutine, which is passed to every 4394 await_suspend(). This was created on demand when parsing we now link it 4395 into our scope. */ 4396 var = get_coroutine_self_handle_proxy (orig); 4397 DECL_CONTEXT (var) = orig; 4398 DECL_SOURCE_LOCATION (var) = fn_start; 4399 DECL_CHAIN (var) = var_list; 4400 var_list = var; 4401 add_decl_expr (var); 4402 4403 /* If we have function parms, then these will be copied to the coroutine 4404 frame. Create a local (proxy) variable for each parm, since the original 4405 parms will be out of scope once the ramp has finished. The proxy vars will 4406 get DECL_VALUE_EXPRs pointing to the frame copies, so that we can interact 4407 with them in the debugger. */ 4408 if (param_uses) 4409 { 4410 gcc_checking_assert (DECL_ARGUMENTS (orig)); 4411 /* Add a local var for each parm. */ 4412 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; 4413 arg = DECL_CHAIN (arg)) 4414 { 4415 param_info *parm_i = param_uses->get (arg); 4416 gcc_checking_assert (parm_i); 4417 parm_i->copy_var 4418 = build_lang_decl (VAR_DECL, parm_i->field_id, TREE_TYPE (arg)); 4419 DECL_SOURCE_LOCATION (parm_i->copy_var) = DECL_SOURCE_LOCATION (arg); 4420 DECL_CONTEXT (parm_i->copy_var) = orig; 4421 DECL_ARTIFICIAL (parm_i->copy_var) = true; 4422 DECL_CHAIN (parm_i->copy_var) = var_list; 4423 var_list = parm_i->copy_var; 4424 add_decl_expr (parm_i->copy_var); 4425 } 4426 4427 /* Now replace all uses of the parms in the function body with the proxy 4428 vars. We want to this to apply to every instance of param's use, so 4429 don't include a 'visited' hash_set on the tree walk, however we will 4430 arrange to visit each containing expression only once. */ 4431 hash_set<tree *> visited; 4432 param_frame_data param_data = {NULL, param_uses, 4433 &visited, fn_start, false}; 4434 cp_walk_tree (&fnbody, rewrite_param_uses, ¶m_data, NULL); 4435 } 4436 4437 /* We create a resume index, this is initialized in the ramp. */ 4438 resume_idx_var 4439 = coro_build_artificial_var (fn_start, coro_resume_index_id, 4440 short_unsigned_type_node, orig, NULL_TREE); 4441 DECL_CHAIN (resume_idx_var) = var_list; 4442 var_list = resume_idx_var; 4443 add_decl_expr (resume_idx_var); 4444 4445 /* If the coroutine has a frame that needs to be freed, this will be set by 4446 the ramp. */ 4447 var = coro_build_artificial_var (fn_start, coro_frame_needs_free_id, 4448 boolean_type_node, orig, NULL_TREE); 4449 DECL_CHAIN (var) = var_list; 4450 var_list = var; 4451 add_decl_expr (var); 4452 4453 if (flag_exceptions) 4454 { 4455 /* Build promise.unhandled_exception(); */ 4456 tree ueh 4457 = coro_build_promise_expression (current_function_decl, promise, 4458 coro_unhandled_exception_identifier, 4459 fn_start, NULL, /*musthave=*/true); 4460 /* Create and initialize the initial-await-resume-called variable per 4461 [dcl.fct.def.coroutine] / 5.3. */ 4462 tree i_a_r_c 4463 = coro_build_artificial_var (fn_start, coro_frame_i_a_r_c_id, 4464 boolean_type_node, orig, 4465 NULL_TREE); 4466 DECL_CHAIN (i_a_r_c) = var_list; 4467 var_list = i_a_r_c; 4468 add_decl_expr (i_a_r_c); 4469 /* Start the try-catch. */ 4470 tree tcb = build_stmt (fn_start, TRY_BLOCK, NULL_TREE, NULL_TREE); 4471 add_stmt (tcb); 4472 TRY_STMTS (tcb) = push_stmt_list (); 4473 if (initial_await != error_mark_node) 4474 { 4475 /* Build a compound expression that sets the 4476 initial-await-resume-called variable true and then calls the 4477 initial suspend expression await resume. 4478 In the case that the user decides to make the initial await 4479 await_resume() return a value, we need to discard it and, it is 4480 a reference type, look past the indirection. */ 4481 if (INDIRECT_REF_P (initial_await)) 4482 initial_await = TREE_OPERAND (initial_await, 0); 4483 /* In the case that the initial_await returns a target expression 4484 we might need to look through that to update the await expr. */ 4485 tree iaw = initial_await; 4486 if (TREE_CODE (iaw) == TARGET_EXPR) 4487 iaw = TARGET_EXPR_INITIAL (iaw); 4488 gcc_checking_assert (TREE_CODE (iaw) == CO_AWAIT_EXPR); 4489 tree vec = TREE_OPERAND (iaw, 3); 4490 tree aw_r = TREE_VEC_ELT (vec, 2); 4491 aw_r = convert_to_void (aw_r, ICV_STATEMENT, tf_warning_or_error); 4492 tree update = build2 (MODIFY_EXPR, boolean_type_node, i_a_r_c, 4493 boolean_true_node); 4494 aw_r = cp_build_compound_expr (update, aw_r, tf_warning_or_error); 4495 TREE_VEC_ELT (vec, 2) = aw_r; 4496 } 4497 /* Add the initial await to the start of the user-authored function. */ 4498 finish_expr_stmt (initial_await); 4499 /* Append the original function body. */ 4500 add_stmt (fnbody); 4501 if (return_void) 4502 add_stmt (return_void); 4503 TRY_STMTS (tcb) = pop_stmt_list (TRY_STMTS (tcb)); 4504 TRY_HANDLERS (tcb) = push_stmt_list (); 4505 /* Mimic what the parser does for the catch. */ 4506 tree handler = begin_handler (); 4507 finish_handler_parms (NULL_TREE, handler); /* catch (...) */ 4508 4509 /* Get the initial await resume called value. */ 4510 tree not_iarc_if = begin_if_stmt (); 4511 tree not_iarc = build1_loc (fn_start, TRUTH_NOT_EXPR, 4512 boolean_type_node, i_a_r_c); 4513 finish_if_stmt_cond (not_iarc, not_iarc_if); 4514 /* If the initial await resume called value is false, rethrow... */ 4515 tree rethrow = build_throw (fn_start, NULL_TREE, tf_warning_or_error); 4516 suppress_warning (rethrow); 4517 finish_expr_stmt (rethrow); 4518 finish_then_clause (not_iarc_if); 4519 tree iarc_scope = IF_SCOPE (not_iarc_if); 4520 IF_SCOPE (not_iarc_if) = NULL; 4521 not_iarc_if = do_poplevel (iarc_scope); 4522 add_stmt (not_iarc_if); 4523 /* ... else call the promise unhandled exception method 4524 but first we set done = true and the resume index to 0. 4525 If the unhandled exception method returns, then we continue 4526 to the final await expression (which duplicates the clearing of 4527 the field). */ 4528 tree r = build2 (MODIFY_EXPR, resume_fn_ptr_type, resume_fn_ptr, 4529 zero_resume); 4530 finish_expr_stmt (r); 4531 tree short_zero = build_int_cst (short_unsigned_type_node, 0); 4532 r = build2 (MODIFY_EXPR, short_unsigned_type_node, resume_idx_var, 4533 short_zero); 4534 finish_expr_stmt (r); 4535 finish_expr_stmt (ueh); 4536 finish_handler (handler); 4537 TRY_HANDLERS (tcb) = pop_stmt_list (TRY_HANDLERS (tcb)); 4538 } 4539 else 4540 { 4541 if (pedantic) 4542 { 4543 /* We still try to look for the promise method and warn if it's not 4544 present. */ 4545 tree ueh_meth 4546 = lookup_promise_method (orig, coro_unhandled_exception_identifier, 4547 fn_start, /*musthave=*/false); 4548 if (!ueh_meth || ueh_meth == error_mark_node) 4549 warning_at (fn_start, 0, "no member named %qE in %qT", 4550 coro_unhandled_exception_identifier, 4551 get_coroutine_promise_type (orig)); 4552 } 4553 /* Else we don't check and don't care if the method is missing.. 4554 just add the initial suspend, function and return. */ 4555 finish_expr_stmt (initial_await); 4556 /* Append the original function body. */ 4557 add_stmt (fnbody); 4558 if (return_void) 4559 add_stmt (return_void); 4560 } 4561 4562 /* co_return branches to the final_suspend label, so declare that now. */ 4563 fs_label 4564 = create_named_label_with_ctx (fn_start, "final.suspend", NULL_TREE); 4565 add_stmt (build_stmt (fn_start, LABEL_EXPR, fs_label)); 4566 4567 /* Before entering the final suspend point, we signal that this point has 4568 been reached by setting the resume function pointer to zero (this is 4569 what the 'done()' builtin tests) as per the current ABI. */ 4570 zero_resume = build2 (MODIFY_EXPR, resume_fn_ptr_type, resume_fn_ptr, 4571 zero_resume); 4572 finish_expr_stmt (zero_resume); 4573 finish_expr_stmt (build_init_or_final_await (fn_start, true)); 4574 BIND_EXPR_BODY (update_body) = pop_stmt_list (BIND_EXPR_BODY (update_body)); 4575 BIND_EXPR_VARS (update_body) = nreverse (var_list); 4576 BLOCK_VARS (top_block) = BIND_EXPR_VARS (update_body); 4577 4578 return update_body; 4579 } 4580 4581 /* Here we: 4582 a) Check that the function and promise type are valid for a 4583 coroutine. 4584 b) Carry out the initial morph to create the skeleton of the 4585 coroutine ramp function and the rewritten body. 4586 4587 Assumptions. 4588 4589 1. We only hit this code once all dependencies are resolved. 4590 2. The function body will be either a bind expr or a statement list 4591 3. That cfun and current_function_decl are valid for the case we're 4592 expanding. 4593 4. 'input_location' will be of the final brace for the function. 4594 4595 We do something like this: 4596 declare a dummy coro frame. 4597 struct _R_frame { 4598 using handle_type = coro::coroutine_handle<coro1::promise_type>; 4599 void (*_Coro_resume_fn)(_R_frame *); 4600 void (*_Coro_destroy_fn)(_R_frame *); 4601 coro1::promise_type _Coro_promise; 4602 bool _Coro_frame_needs_free; free the coro frame mem if set. 4603 bool _Coro_i_a_r_c; [dcl.fct.def.coroutine] / 5.3 4604 short _Coro_resume_index; 4605 handle_type _Coro_self_handle; 4606 parameter copies (were required). 4607 local variables saved (including awaitables) 4608 (maybe) trailing space. 4609 }; */ 4610 4611 bool 4612 morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) 4613 { 4614 gcc_checking_assert (orig && TREE_CODE (orig) == FUNCTION_DECL); 4615 4616 *resumer = error_mark_node; 4617 *destroyer = error_mark_node; 4618 if (!coro_function_valid_p (orig)) 4619 { 4620 /* For early errors, we do not want a diagnostic about the missing 4621 ramp return value, since the user cannot fix this - a 'return' is 4622 not allowed in a coroutine. */ 4623 suppress_warning (orig, OPT_Wreturn_type); 4624 /* Discard the body, we can't process it further. */ 4625 pop_stmt_list (DECL_SAVED_TREE (orig)); 4626 DECL_SAVED_TREE (orig) = push_stmt_list (); 4627 return false; 4628 } 4629 4630 /* We can't validly get here with an empty statement list, since there's no 4631 way for the FE to decide it's a coroutine in the absence of any code. */ 4632 tree fnbody = pop_stmt_list (DECL_SAVED_TREE (orig)); 4633 gcc_checking_assert (fnbody != NULL_TREE); 4634 4635 /* We don't have the locus of the opening brace - it's filled in later (and 4636 there doesn't really seem to be any easy way to get at it). 4637 The closing brace is assumed to be input_location. */ 4638 location_t fn_start = DECL_SOURCE_LOCATION (orig); 4639 gcc_rich_location fn_start_loc (fn_start); 4640 4641 /* Initial processing of the function-body. 4642 If we have no expressions or just an error then punt. */ 4643 tree body_start = expr_first (fnbody); 4644 if (body_start == NULL_TREE || body_start == error_mark_node) 4645 { 4646 DECL_SAVED_TREE (orig) = push_stmt_list (); 4647 append_to_statement_list (fnbody, &DECL_SAVED_TREE (orig)); 4648 /* Suppress warnings about the missing return value. */ 4649 suppress_warning (orig, OPT_Wreturn_type); 4650 return false; 4651 } 4652 4653 /* So, we've tied off the original user-authored body in fn_body. 4654 4655 Start the replacement synthesized ramp body as newbody. 4656 If we encounter a fatal error we might return a now-empty body. 4657 4658 Note, the returned ramp body is not 'popped', to be compatible with 4659 the way that decl.cc handles regular functions, the scope pop is done 4660 in the caller. */ 4661 4662 tree newbody = push_stmt_list (); 4663 DECL_SAVED_TREE (orig) = newbody; 4664 4665 /* If our original body is noexcept, then that's what we apply to our 4666 generated ramp, transfer any MUST_NOT_THOW_EXPR to that. */ 4667 bool is_noexcept = TREE_CODE (body_start) == MUST_NOT_THROW_EXPR; 4668 if (is_noexcept) 4669 { 4670 /* The function body we will continue with is the single operand to 4671 the must-not-throw. */ 4672 fnbody = TREE_OPERAND (body_start, 0); 4673 /* Transfer the must-not-throw to the ramp body. */ 4674 add_stmt (body_start); 4675 /* Re-start the ramp as must-not-throw. */ 4676 TREE_OPERAND (body_start, 0) = push_stmt_list (); 4677 } 4678 4679 /* Create the coro frame type, as far as it can be known at this stage. 4680 1. Types we already know. */ 4681 4682 tree promise_type = get_coroutine_promise_type (orig); 4683 tree fn_return_type = TREE_TYPE (TREE_TYPE (orig)); 4684 bool void_ramp_p = VOID_TYPE_P (fn_return_type); 4685 4686 /* 2. Types we need to define or look up. */ 4687 4688 tree fr_name = get_fn_local_identifier (orig, "Frame"); 4689 tree coro_frame_type = xref_tag (record_type, fr_name); 4690 DECL_CONTEXT (TYPE_NAME (coro_frame_type)) = current_scope (); 4691 tree coro_frame_ptr = build_pointer_type (coro_frame_type); 4692 tree act_des_fn_type 4693 = build_function_type_list (void_type_node, coro_frame_ptr, NULL_TREE); 4694 tree act_des_fn_ptr = build_pointer_type (act_des_fn_type); 4695 4696 /* Declare the actor and destroyer function. */ 4697 tree actor = coro_build_actor_or_destroy_function (orig, act_des_fn_type, 4698 coro_frame_ptr, true); 4699 tree destroy = coro_build_actor_or_destroy_function (orig, act_des_fn_type, 4700 coro_frame_ptr, false); 4701 4702 /* Construct the wrapped function body; we will analyze this to determine 4703 the requirements for the coroutine frame. */ 4704 4705 tree resume_idx_var = NULL_TREE; 4706 tree fs_label = NULL_TREE; 4707 hash_map<tree, param_info> *param_uses = analyze_fn_parms (orig); 4708 4709 fnbody = coro_rewrite_function_body (fn_start, fnbody, orig, param_uses, 4710 act_des_fn_ptr, 4711 resume_idx_var, fs_label); 4712 /* Build our dummy coro frame layout. */ 4713 coro_frame_type = begin_class_definition (coro_frame_type); 4714 4715 4716 /* We need to know, and inspect, each suspend point in the function 4717 in several places. It's convenient to place this map out of line 4718 since it's used from tree walk callbacks. */ 4719 4720 hash_map<tree, suspend_point_info> suspend_points; 4721 /* Now insert the data for any body await points, at this time we also need 4722 to promote any temporaries that are captured by reference (to regular 4723 vars) they will get added to the coro frame along with other locals. */ 4724 susp_frame_data body_aw_points (fs_label, &suspend_points); 4725 cp_walk_tree (&fnbody, await_statement_walker, &body_aw_points, NULL); 4726 4727 /* 4. Now make space for local vars, this is conservative again, and we 4728 would expect to delete unused entries later. Compose the frame entries 4729 list. */ 4730 4731 /* The fields for the coro frame. */ 4732 tree field_list = NULL_TREE; 4733 hash_map<tree, local_var_info> local_var_uses; 4734 local_vars_frame_data local_vars_data (&field_list, &local_var_uses); 4735 cp_walk_tree_without_duplicates (&fnbody, register_local_var_uses, 4736 &local_vars_data); 4737 4738 /* Tie off the struct for now, so that we can build offsets to the 4739 known entries. */ 4740 TYPE_FIELDS (coro_frame_type) = field_list; 4741 TYPE_BINFO (coro_frame_type) = make_tree_binfo (0); 4742 BINFO_OFFSET (TYPE_BINFO (coro_frame_type)) = size_zero_node; 4743 BINFO_TYPE (TYPE_BINFO (coro_frame_type)) = coro_frame_type; 4744 4745 coro_frame_type = finish_struct (coro_frame_type, NULL_TREE); 4746 4747 /* Ramp: */ 4748 /* Now build the ramp function pieces. */ 4749 tree ramp_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); 4750 add_stmt (ramp_bind); 4751 tree ramp_body = push_stmt_list (); 4752 4753 tree zeroinit = build1_loc (fn_start, CONVERT_EXPR, 4754 coro_frame_ptr, nullptr_node); 4755 tree coro_fp = coro_build_artificial_var (fn_start, "_Coro_frameptr", 4756 coro_frame_ptr, orig, zeroinit); 4757 tree varlist = coro_fp; 4758 4759 /* To signal that we need to cleanup copied function args. */ 4760 if (flag_exceptions && DECL_ARGUMENTS (orig)) 4761 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; 4762 arg = DECL_CHAIN (arg)) 4763 { 4764 param_info *parm_i = param_uses->get (arg); 4765 gcc_checking_assert (parm_i); 4766 if (parm_i->trivial_dtor) 4767 continue; 4768 DECL_CHAIN (parm_i->guard_var) = varlist; 4769 varlist = parm_i->guard_var; 4770 } 4771 4772 /* Signal that we need to clean up the promise object on exception. */ 4773 tree coro_promise_live 4774 = coro_build_artificial_var (fn_start, "_Coro_promise_live", 4775 boolean_type_node, orig, boolean_false_node); 4776 DECL_CHAIN (coro_promise_live) = varlist; 4777 varlist = coro_promise_live; 4778 4779 /* When the get-return-object is in the RETURN slot, we need to arrange for 4780 cleanup on exception. */ 4781 tree coro_gro_live 4782 = coro_build_artificial_var (fn_start, "_Coro_gro_live", 4783 boolean_type_node, orig, boolean_false_node); 4784 DECL_CHAIN (coro_gro_live) = varlist; 4785 varlist = coro_gro_live; 4786 4787 tree coro_before_return 4788 = coro_build_artificial_var (fn_start, "_Coro_before_return", 4789 boolean_type_node, orig, boolean_true_node); 4790 DECL_CHAIN (coro_before_return) = varlist; 4791 varlist = coro_before_return; 4792 4793 /* Collected the scope vars we need ... only one for now. */ 4794 BIND_EXPR_VARS (ramp_bind) = nreverse (varlist); 4795 4796 /* We're now going to create a new top level scope block for the ramp 4797 function. */ 4798 tree top_block = make_node (BLOCK); 4799 4800 BIND_EXPR_BLOCK (ramp_bind) = top_block; 4801 BLOCK_VARS (top_block) = BIND_EXPR_VARS (ramp_bind); 4802 BLOCK_SUBBLOCKS (top_block) = NULL_TREE; 4803 current_binding_level->blocks = top_block; 4804 4805 /* The decl_expr for the coro frame pointer, initialize to zero so that we 4806 can pass it to the IFN_CO_FRAME (since there's no way to pass a type, 4807 directly apparently). This avoids a "used uninitialized" warning. */ 4808 4809 add_decl_expr (coro_fp); 4810 if (flag_exceptions && DECL_ARGUMENTS (orig)) 4811 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; 4812 arg = DECL_CHAIN (arg)) 4813 { 4814 param_info *parm_i = param_uses->get (arg); 4815 if (parm_i->trivial_dtor) 4816 continue; 4817 add_decl_expr (parm_i->guard_var);; 4818 } 4819 add_decl_expr (coro_promise_live); 4820 add_decl_expr (coro_gro_live); 4821 add_decl_expr (coro_before_return); 4822 4823 /* The CO_FRAME internal function is a mechanism to allow the middle end 4824 to adjust the allocation in response to optimizations. We provide the 4825 current conservative estimate of the frame size (as per the current) 4826 computed layout. */ 4827 tree frame_size = TYPE_SIZE_UNIT (coro_frame_type); 4828 tree resizeable 4829 = build_call_expr_internal_loc (fn_start, IFN_CO_FRAME, size_type_node, 2, 4830 frame_size, coro_fp); 4831 4832 /* [dcl.fct.def.coroutine] / 10 (part1) 4833 The unqualified-id get_return_object_on_allocation_failure is looked up 4834 in the scope of the promise type by class member access lookup. */ 4835 4836 /* We don't require this, so coro_build_promise_expression can return NULL, 4837 but, if the lookup succeeds, then the function must be usable. */ 4838 tree dummy_promise = build_dummy_object (get_coroutine_promise_type (orig)); 4839 tree grooaf 4840 = coro_build_promise_expression (orig, dummy_promise, 4841 coro_gro_on_allocation_fail_identifier, 4842 fn_start, NULL, /*musthave=*/false); 4843 4844 /* however, should that fail, returning an error, the later stages can't 4845 handle the erroneous expression, so we reset the call as if it was 4846 absent. */ 4847 if (grooaf == error_mark_node) 4848 grooaf = NULL_TREE; 4849 4850 /* Allocate the frame, this has several possibilities: 4851 [dcl.fct.def.coroutine] / 9 (part 1) 4852 The allocation functions name is looked up in the scope of the promise 4853 type. It's not a failure for it to be absent see part 4, below. */ 4854 4855 tree nwname = ovl_op_identifier (false, NEW_EXPR); 4856 tree new_fn = NULL_TREE; 4857 4858 if (TYPE_HAS_NEW_OPERATOR (promise_type)) 4859 { 4860 tree fns = lookup_promise_method (orig, nwname, fn_start, 4861 /*musthave=*/true); 4862 /* [dcl.fct.def.coroutine] / 9 (part 2) 4863 If the lookup finds an allocation function in the scope of the promise 4864 type, overload resolution is performed on a function call created by 4865 assembling an argument list. The first argument is the amount of space 4866 requested, and has type std::size_t. The lvalues p1...pn are the 4867 succeeding arguments.. */ 4868 vec<tree, va_gc> *args = make_tree_vector (); 4869 vec_safe_push (args, resizeable); /* Space needed. */ 4870 4871 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; 4872 arg = DECL_CHAIN (arg)) 4873 { 4874 param_info *parm_i = param_uses->get (arg); 4875 gcc_checking_assert (parm_i); 4876 if (parm_i->this_ptr || parm_i->lambda_cobj) 4877 { 4878 /* We pass a reference to *this to the allocator lookup. */ 4879 /* It's unsafe to use the cp_ version here since current_class_ref 4880 might've gotten clobbered earlier during rewrite_param_uses. */ 4881 tree this_ref = build_fold_indirect_ref (arg); 4882 vec_safe_push (args, this_ref); 4883 } 4884 else 4885 vec_safe_push (args, convert_from_reference (arg)); 4886 } 4887 4888 /* Note the function selected; we test to see if it's NOTHROW. */ 4889 tree func; 4890 /* Failure is not an error for this attempt. */ 4891 new_fn = build_new_method_call (dummy_promise, fns, &args, NULL, 4892 LOOKUP_NORMAL, &func, tf_none); 4893 release_tree_vector (args); 4894 4895 if (new_fn == error_mark_node) 4896 { 4897 /* [dcl.fct.def.coroutine] / 9 (part 3) 4898 If no viable function is found, overload resolution is performed 4899 again on a function call created by passing just the amount of 4900 space required as an argument of type std::size_t. */ 4901 args = make_tree_vector_single (resizeable); /* Space needed. */ 4902 new_fn = build_new_method_call (dummy_promise, fns, &args, 4903 NULL_TREE, LOOKUP_NORMAL, &func, 4904 tf_none); 4905 release_tree_vector (args); 4906 } 4907 4908 /* However, if the promise provides an operator new, then one of these 4909 two options must be available. */ 4910 if (new_fn == error_mark_node) 4911 { 4912 error_at (fn_start, "%qE is provided by %qT but is not usable with" 4913 " the function signature %qD", nwname, promise_type, orig); 4914 new_fn = error_mark_node; 4915 } 4916 else if (grooaf && !TYPE_NOTHROW_P (TREE_TYPE (func))) 4917 error_at (fn_start, "%qE is provided by %qT but %qE is not marked" 4918 " %<throw()%> or %<noexcept%>", grooaf, promise_type, nwname); 4919 else if (!grooaf && TYPE_NOTHROW_P (TREE_TYPE (func))) 4920 warning_at (fn_start, 0, "%qE is marked %<throw()%> or %<noexcept%> but" 4921 " no usable %<get_return_object_on_allocation_failure%>" 4922 " is provided by %qT", nwname, promise_type); 4923 } 4924 else /* No operator new in the promise. */ 4925 { 4926 /* [dcl.fct.def.coroutine] / 9 (part 4) 4927 If this lookup fails, the allocation functions name is looked up in 4928 the global scope. */ 4929 4930 vec<tree, va_gc> *args; 4931 /* build_operator_new_call () will insert size needed as element 0 of 4932 this, and we might need to append the std::nothrow constant. */ 4933 vec_alloc (args, 2); 4934 if (grooaf) 4935 { 4936 /* [dcl.fct.def.coroutine] / 10 (part 2) 4937 If any declarations (of the get return on allocation fail) are 4938 found, then the result of a call to an allocation function used 4939 to obtain storage for the coroutine state is assumed to return 4940 nullptr if it fails to obtain storage and, if a global allocation 4941 function is selected, the ::operator new(size_t, nothrow_t) form 4942 is used. The allocation function used in this case shall have a 4943 non-throwing noexcept-specification. So we need std::nothrow. */ 4944 tree std_nt = lookup_qualified_name (std_node, 4945 get_identifier ("nothrow"), 4946 LOOK_want::NORMAL, 4947 /*complain=*/true); 4948 if (!std_nt || std_nt == error_mark_node) 4949 error_at (fn_start, "%qE is provided by %qT but %<std::nothrow%> " 4950 "cannot be found", grooaf, promise_type); 4951 vec_safe_push (args, std_nt); 4952 } 4953 4954 /* If we get to this point, we must succeed in looking up the global 4955 operator new for the params provided. Extract a simplified version 4956 of the machinery from build_operator_new_call. This can update the 4957 frame size. */ 4958 tree cookie = NULL; 4959 new_fn = build_operator_new_call (nwname, &args, &frame_size, &cookie, 4960 /*align_arg=*/NULL, 4961 /*size_check=*/NULL, /*fn=*/NULL, 4962 tf_warning_or_error); 4963 resizeable = build_call_expr_internal_loc 4964 (fn_start, IFN_CO_FRAME, size_type_node, 2, frame_size, coro_fp); 4965 /* If the operator call fails for some reason, then don't try to 4966 amend it. */ 4967 if (new_fn != error_mark_node) 4968 CALL_EXPR_ARG (new_fn, 0) = resizeable; 4969 4970 release_tree_vector (args); 4971 } 4972 4973 tree allocated = build1 (CONVERT_EXPR, coro_frame_ptr, new_fn); 4974 tree r = cp_build_init_expr (coro_fp, allocated); 4975 finish_expr_stmt (r); 4976 4977 /* deref the frame pointer, to use in member access code. */ 4978 tree deref_fp = build_x_arrow (fn_start, coro_fp, tf_warning_or_error); 4979 4980 /* If the user provided a method to return an object on alloc fail, then 4981 check the returned pointer and call the func if it's null. 4982 Otherwise, no check, and we fail for noexcept/fno-exceptions cases. */ 4983 4984 if (grooaf) 4985 { 4986 /* [dcl.fct.def.coroutine] / 10 (part 3) 4987 If the allocation function returns nullptr,the coroutine returns 4988 control to the caller of the coroutine and the return value is 4989 obtained by a call to T::get_return_object_on_allocation_failure(), 4990 where T is the promise type. */ 4991 tree if_stmt = begin_if_stmt (); 4992 tree cond = build1 (CONVERT_EXPR, coro_frame_ptr, nullptr_node); 4993 cond = build2 (EQ_EXPR, boolean_type_node, coro_fp, cond); 4994 finish_if_stmt_cond (cond, if_stmt); 4995 r = NULL_TREE; 4996 if (void_ramp_p) 4997 /* Execute the get-return-object-on-alloc-fail call... */ 4998 finish_expr_stmt (grooaf); 4999 else 5000 /* Get the fallback return object. */ 5001 r = grooaf; 5002 finish_return_stmt (r); 5003 finish_then_clause (if_stmt); 5004 finish_if_stmt (if_stmt); 5005 } 5006 5007 /* Up to now any exception thrown will propagate directly to the caller. 5008 This is OK since the only source of such exceptions would be in allocation 5009 of the coroutine frame, and therefore the ramp will not have initialized 5010 any further state. From here, we will track state that needs explicit 5011 destruction in the case that promise or g.r.o setup fails or an exception 5012 is thrown from the initial suspend expression. */ 5013 tree ramp_cleanup = NULL_TREE; 5014 tree iarc_x = NULL_TREE; 5015 if (flag_exceptions) 5016 { 5017 iarc_x = lookup_member (coro_frame_type, coro_frame_i_a_r_c_id, 5018 /*protect=*/1, /*want_type=*/0, tf_warning_or_error); 5019 iarc_x 5020 = build_class_member_access_expr (deref_fp, iarc_x, NULL_TREE, false, 5021 tf_warning_or_error); 5022 r = cp_build_init_expr (iarc_x, boolean_false_node); 5023 finish_expr_stmt (r); 5024 5025 ramp_cleanup = build_stmt (fn_start, TRY_BLOCK, NULL, NULL); 5026 add_stmt (ramp_cleanup); 5027 TRY_STMTS (ramp_cleanup) = push_stmt_list (); 5028 } 5029 5030 /* For now, once allocation has succeeded we always assume that this needs 5031 destruction, there's no impl. for frame allocation elision. */ 5032 tree fnf_m = lookup_member (coro_frame_type, coro_frame_needs_free_id, 5033 1, 0,tf_warning_or_error); 5034 tree fnf_x = build_class_member_access_expr (deref_fp, fnf_m, NULL_TREE, 5035 false, tf_warning_or_error); 5036 r = cp_build_init_expr (fnf_x, boolean_true_node); 5037 finish_expr_stmt (r); 5038 5039 /* Put the resumer and destroyer functions in. */ 5040 5041 tree actor_addr = build1 (ADDR_EXPR, act_des_fn_ptr, actor); 5042 tree resume_m 5043 = lookup_member (coro_frame_type, coro_resume_fn_id, 5044 /*protect=*/1, /*want_type=*/0, tf_warning_or_error); 5045 tree resume_x = build_class_member_access_expr (deref_fp, resume_m, NULL_TREE, 5046 false, tf_warning_or_error); 5047 r = cp_build_init_expr (fn_start, resume_x, actor_addr); 5048 finish_expr_stmt (r); 5049 5050 tree destroy_addr = build1 (ADDR_EXPR, act_des_fn_ptr, destroy); 5051 tree destroy_m 5052 = lookup_member (coro_frame_type, coro_destroy_fn_id, 5053 /*protect=*/1, /*want_type=*/0, tf_warning_or_error); 5054 tree destroy_x 5055 = build_class_member_access_expr (deref_fp, destroy_m, NULL_TREE, false, 5056 tf_warning_or_error); 5057 r = cp_build_init_expr (fn_start, destroy_x, destroy_addr); 5058 finish_expr_stmt (r); 5059 5060 /* [dcl.fct.def.coroutine] /13 5061 When a coroutine is invoked, a copy is created for each coroutine 5062 parameter. Each such copy is an object with automatic storage duration 5063 that is direct-initialized from an lvalue referring to the corresponding 5064 parameter if the parameter is an lvalue reference, and from an xvalue 5065 referring to it otherwise. A reference to a parameter in the function- 5066 body of the coroutine and in the call to the coroutine promise 5067 constructor is replaced by a reference to its copy. */ 5068 5069 vec<tree, va_gc> *promise_args = NULL; /* So that we can adjust refs. */ 5070 5071 /* The initialization and destruction of each parameter copy occurs in the 5072 context of the called coroutine. Initializations of parameter copies are 5073 sequenced before the call to the coroutine promise constructor and 5074 indeterminately sequenced with respect to each other. The lifetime of 5075 parameter copies ends immediately after the lifetime of the coroutine 5076 promise object ends. */ 5077 5078 vec<tree, va_gc> *param_dtor_list = NULL; 5079 5080 if (DECL_ARGUMENTS (orig)) 5081 { 5082 promise_args = make_tree_vector (); 5083 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; 5084 arg = DECL_CHAIN (arg)) 5085 { 5086 bool existed; 5087 param_info &parm = param_uses->get_or_insert (arg, &existed); 5088 5089 tree fld_ref = lookup_member (coro_frame_type, parm.field_id, 5090 /*protect=*/1, /*want_type=*/0, 5091 tf_warning_or_error); 5092 tree fld_idx 5093 = build_class_member_access_expr (deref_fp, fld_ref, NULL_TREE, 5094 false, tf_warning_or_error); 5095 5096 /* Add this to the promise CTOR arguments list, accounting for 5097 refs and special handling for method this ptr. */ 5098 if (parm.this_ptr || parm.lambda_cobj) 5099 { 5100 /* We pass a reference to *this to the param preview. */ 5101 /* It's unsafe to use the cp_ version here since current_class_ref 5102 might've gotten clobbered earlier during rewrite_param_uses. */ 5103 tree this_ref = build_fold_indirect_ref (arg); 5104 vec_safe_push (promise_args, this_ref); 5105 } 5106 else if (parm.rv_ref) 5107 vec_safe_push (promise_args, move (fld_idx)); 5108 else 5109 vec_safe_push (promise_args, fld_idx); 5110 5111 if (parm.rv_ref || parm.pt_ref) 5112 /* Initialise the frame reference field directly. */ 5113 r = build2 (INIT_EXPR, TREE_TYPE (arg), 5114 TREE_OPERAND (fld_idx, 0), arg); 5115 else 5116 { 5117 r = forward_parm (arg); 5118 r = cp_build_modify_expr (fn_start, fld_idx, INIT_EXPR, r, 5119 tf_warning_or_error); 5120 } 5121 finish_expr_stmt (r); 5122 if (!parm.trivial_dtor) 5123 { 5124 if (param_dtor_list == NULL) 5125 param_dtor_list = make_tree_vector (); 5126 vec_safe_push (param_dtor_list, parm.field_id); 5127 /* Cleanup this frame copy on exception. */ 5128 parm.fr_copy_dtor 5129 = cxx_maybe_build_cleanup (fld_idx, tf_warning_or_error); 5130 if (flag_exceptions) 5131 { 5132 /* This var is now live. */ 5133 r = build_modify_expr (fn_start, parm.guard_var, 5134 boolean_type_node, INIT_EXPR, fn_start, 5135 boolean_true_node, boolean_type_node); 5136 finish_expr_stmt (r); 5137 } 5138 } 5139 } 5140 } 5141 5142 /* Set up the promise. */ 5143 tree promise_m 5144 = lookup_member (coro_frame_type, coro_promise_id, 5145 /*protect=*/1, /*want_type=*/0, tf_warning_or_error); 5146 5147 tree p = build_class_member_access_expr (deref_fp, promise_m, NULL_TREE, 5148 false, tf_warning_or_error); 5149 5150 if (type_build_ctor_call (promise_type)) 5151 { 5152 /* Construct the promise object [dcl.fct.def.coroutine] / 5.7. 5153 5154 First try to find a constructor with an argument list comprised of 5155 the parameter copies. */ 5156 5157 if (DECL_ARGUMENTS (orig)) 5158 { 5159 r = build_special_member_call (p, complete_ctor_identifier, 5160 &promise_args, promise_type, 5161 LOOKUP_NORMAL, tf_none); 5162 release_tree_vector (promise_args); 5163 } 5164 else 5165 r = NULL_TREE; 5166 5167 /* If that fails then the promise constructor argument list is empty. */ 5168 if (r == NULL_TREE || r == error_mark_node) 5169 r = build_special_member_call (p, complete_ctor_identifier, NULL, 5170 promise_type, LOOKUP_NORMAL, 5171 tf_warning_or_error); 5172 5173 /* If type_build_ctor_call() encounters deprecated implicit CTORs it will 5174 return true, and therefore we will execute this code path. However, 5175 we might well not actually require a CTOR and under those conditions 5176 the build call above will not return a call expression, but the 5177 original instance object. Do not attempt to add the statement unless 5178 it has side-effects. */ 5179 if (r && r != error_mark_node && TREE_SIDE_EFFECTS (r)) 5180 finish_expr_stmt (r); 5181 } 5182 5183 tree promise_dtor = cxx_maybe_build_cleanup (p, tf_warning_or_error);; 5184 if (flag_exceptions && promise_dtor) 5185 { 5186 r = cp_build_init_expr (coro_promise_live, boolean_true_node); 5187 finish_expr_stmt (r); 5188 } 5189 5190 /* Set up a new bind context for the GRO. */ 5191 tree gro_context_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); 5192 /* Make and connect the scope blocks. */ 5193 tree gro_block = make_node (BLOCK); 5194 BLOCK_SUPERCONTEXT (gro_block) = top_block; 5195 BLOCK_SUBBLOCKS (top_block) = gro_block; 5196 BIND_EXPR_BLOCK (gro_context_bind) = gro_block; 5197 add_stmt (gro_context_bind); 5198 5199 tree get_ro 5200 = coro_build_promise_expression (orig, p, 5201 coro_get_return_object_identifier, 5202 fn_start, NULL, /*musthave=*/true); 5203 /* Without a return object we haven't got much clue what's going on. */ 5204 if (!get_ro || get_ro == error_mark_node) 5205 { 5206 BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body); 5207 DECL_SAVED_TREE (orig) = newbody; 5208 /* Suppress warnings about the missing return value. */ 5209 suppress_warning (orig, OPT_Wreturn_type); 5210 return false; 5211 } 5212 5213 /* Check for a bad get return object type. 5214 [dcl.fct.def.coroutine] / 7 requires: 5215 The expression promise.get_return_object() is used to initialize the 5216 returned reference or prvalue result object ... */ 5217 tree gro_type = TREE_TYPE (get_ro); 5218 if (VOID_TYPE_P (gro_type) && !void_ramp_p) 5219 { 5220 error_at (fn_start, "no viable conversion from %<void%> provided by" 5221 " %<get_return_object%> to return type %qT", fn_return_type); 5222 return false; 5223 } 5224 5225 tree gro_context_body = push_stmt_list (); 5226 5227 tree gro = NULL_TREE; 5228 tree gro_bind_vars = NULL_TREE; 5229 /* Used for return objects in the RESULT slot. */ 5230 tree gro_ret_dtor = NULL_TREE; 5231 tree gro_cleanup_stmt = NULL_TREE; 5232 /* We have to sequence the call to get_return_object before initial 5233 suspend. */ 5234 if (void_ramp_p) 5235 { 5236 gcc_checking_assert (VOID_TYPE_P (gro_type)); 5237 r = get_ro; 5238 } 5239 else if (same_type_p (gro_type, fn_return_type)) 5240 { 5241 /* [dcl.fct.def.coroutine] / 7 5242 The expression promise.get_return_object() is used to initialize the 5243 glvalue result or... (see below) 5244 Construct the return result directly. */ 5245 if (type_build_ctor_call (gro_type)) 5246 { 5247 vec<tree, va_gc> *arg = make_tree_vector_single (get_ro); 5248 r = build_special_member_call (DECL_RESULT (orig), 5249 complete_ctor_identifier, 5250 &arg, gro_type, LOOKUP_NORMAL, 5251 tf_warning_or_error); 5252 release_tree_vector (arg); 5253 } 5254 else 5255 r = cp_build_init_expr (fn_start, DECL_RESULT (orig), get_ro); 5256 5257 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (gro_type)) 5258 /* If some part of the initalization code (prior to the await_resume 5259 of the initial suspend expression), then we need to clean up the 5260 return value. */ 5261 gro_ret_dtor = cxx_maybe_build_cleanup (DECL_RESULT (orig), 5262 tf_warning_or_error); 5263 } 5264 else 5265 { 5266 /* ... or ... Construct an object that will be used as the single 5267 param to the CTOR for the return object. */ 5268 gro = coro_build_artificial_var (fn_start, "_Coro_gro", gro_type, orig, 5269 NULL_TREE); 5270 add_decl_expr (gro); 5271 gro_bind_vars = gro; 5272 r = cp_build_modify_expr (input_location, gro, INIT_EXPR, get_ro, 5273 tf_warning_or_error); 5274 /* The constructed object might require a cleanup. */ 5275 if (tree cleanup = cxx_maybe_build_cleanup (gro, tf_warning_or_error)) 5276 gro_cleanup_stmt = build_stmt (input_location, CLEANUP_STMT, NULL, 5277 cleanup, gro); 5278 } 5279 finish_expr_stmt (r); 5280 5281 if (gro_cleanup_stmt && gro_cleanup_stmt != error_mark_node) 5282 CLEANUP_BODY (gro_cleanup_stmt) = push_stmt_list (); 5283 5284 /* If we have a live g.r.o in the return slot, then signal this for exception 5285 cleanup. */ 5286 if (gro_ret_dtor) 5287 { 5288 r = build_modify_expr (fn_start, coro_gro_live, boolean_type_node, 5289 INIT_EXPR, fn_start, boolean_true_node, 5290 boolean_type_node); 5291 finish_expr_stmt (r); 5292 } 5293 /* Initialize the resume_idx_var to 0, meaning "not started". */ 5294 tree resume_idx_m 5295 = lookup_member (coro_frame_type, coro_resume_index_id, 5296 /*protect=*/1, /*want_type=*/0, tf_warning_or_error); 5297 tree resume_idx 5298 = build_class_member_access_expr (deref_fp, resume_idx_m, NULL_TREE, false, 5299 tf_warning_or_error); 5300 r = build_int_cst (short_unsigned_type_node, 0); 5301 r = cp_build_init_expr (fn_start, resume_idx, r); 5302 r = coro_build_cvt_void_expr_stmt (r, fn_start); 5303 add_stmt (r); 5304 5305 /* So .. call the actor .. */ 5306 r = build_call_expr_loc (fn_start, actor, 1, coro_fp); 5307 r = maybe_cleanup_point_expr_void (r); 5308 add_stmt (r); 5309 5310 /* Switch to using 'input_location' as the loc, since we're now more 5311 logically doing things related to the end of the function. */ 5312 5313 /* The ramp is done, we just need the return value. 5314 [dcl.fct.def.coroutine] / 7 5315 The expression promise.get_return_object() is used to initialize the 5316 glvalue result or prvalue result object of a call to a coroutine. 5317 5318 If the 'get return object' is non-void, then we built it before the 5319 promise was constructed. We now supply a reference to that var, 5320 either as the return value (if it's the same type) or to the CTOR 5321 for an object of the return type. */ 5322 5323 r = build_modify_expr (fn_start, coro_before_return, boolean_type_node, 5324 INIT_EXPR, fn_start, boolean_false_node, 5325 boolean_type_node); 5326 finish_expr_stmt (r); 5327 5328 /* We must manage the cleanups ourselves, because the responsibility for 5329 them changes after the initial suspend. However, any use of 5330 cxx_maybe_build_cleanup () can set the throwing_cleanup flag. */ 5331 cp_function_chain->throwing_cleanup = false; 5332 if (same_type_p (gro_type, fn_return_type)) 5333 r = void_ramp_p ? NULL_TREE : DECL_RESULT (orig); 5334 else 5335 /* check_return_expr will automatically return gro as an rvalue via 5336 treat_lvalue_as_rvalue_p. */ 5337 r = gro; 5338 5339 finish_return_stmt (r); 5340 5341 if (gro_cleanup_stmt) 5342 { 5343 CLEANUP_BODY (gro_cleanup_stmt) 5344 = pop_stmt_list (CLEANUP_BODY (gro_cleanup_stmt)); 5345 add_stmt (gro_cleanup_stmt); 5346 } 5347 5348 /* Finish up the ramp function. */ 5349 BIND_EXPR_VARS (gro_context_bind) = gro_bind_vars; 5350 BIND_EXPR_BODY (gro_context_bind) = pop_stmt_list (gro_context_body); 5351 TREE_SIDE_EFFECTS (gro_context_bind) = true; 5352 5353 if (flag_exceptions) 5354 { 5355 TRY_HANDLERS (ramp_cleanup) = push_stmt_list (); 5356 tree handler = begin_handler (); 5357 finish_handler_parms (NULL_TREE, handler); /* catch (...) */ 5358 5359 /* If we have a live G.R.O in the return slot, then run its DTOR. 5360 When the return object is constructed from a separate g.r.o, this is 5361 already handled by its regular cleanup. */ 5362 if (gro_ret_dtor && gro_ret_dtor != error_mark_node) 5363 { 5364 tree gro_d_if = begin_if_stmt (); 5365 finish_if_stmt_cond (coro_gro_live, gro_d_if); 5366 finish_expr_stmt (gro_ret_dtor); 5367 finish_then_clause (gro_d_if); 5368 tree gro_d_if_scope = IF_SCOPE (gro_d_if); 5369 IF_SCOPE (gro_d_if) = NULL; 5370 gro_d_if = do_poplevel (gro_d_if_scope); 5371 add_stmt (gro_d_if); 5372 } 5373 5374 tree gating_if = begin_if_stmt (); 5375 tree gate = build1 (TRUTH_NOT_EXPR, boolean_type_node, iarc_x); 5376 gate = build2 (TRUTH_AND_EXPR, boolean_type_node, coro_before_return, 5377 gate); 5378 finish_if_stmt_cond (gate, gating_if); 5379 5380 /* If the promise is live, then run its dtor if that's available. */ 5381 if (promise_dtor && promise_dtor != error_mark_node) 5382 { 5383 tree promise_d_if = begin_if_stmt (); 5384 finish_if_stmt_cond (coro_promise_live, promise_d_if); 5385 finish_expr_stmt (promise_dtor); 5386 finish_then_clause (promise_d_if); 5387 tree promise_d_if_scope = IF_SCOPE (promise_d_if); 5388 IF_SCOPE (promise_d_if) = NULL; 5389 promise_d_if = do_poplevel (promise_d_if_scope); 5390 add_stmt (promise_d_if); 5391 } 5392 5393 /* Clean up any frame copies of parms with non-trivial dtors. */ 5394 if (DECL_ARGUMENTS (orig)) 5395 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; 5396 arg = DECL_CHAIN (arg)) 5397 { 5398 param_info *parm_i = param_uses->get (arg); 5399 if (parm_i->trivial_dtor) 5400 continue; 5401 if (parm_i->fr_copy_dtor && parm_i->fr_copy_dtor != error_mark_node) 5402 { 5403 tree dtor_if = begin_if_stmt (); 5404 finish_if_stmt_cond (parm_i->guard_var, dtor_if); 5405 finish_expr_stmt (parm_i->fr_copy_dtor); 5406 finish_then_clause (dtor_if); 5407 tree parm_d_if_scope = IF_SCOPE (dtor_if); 5408 IF_SCOPE (dtor_if) = NULL; 5409 dtor_if = do_poplevel (parm_d_if_scope); 5410 add_stmt (dtor_if); 5411 } 5412 } 5413 5414 /* We always expect to delete the frame. */ 5415 tree del_coro_fr = coro_get_frame_dtor (coro_fp, orig, frame_size, 5416 promise_type, fn_start); 5417 finish_expr_stmt (del_coro_fr); 5418 finish_then_clause (gating_if); 5419 finish_if_stmt (gating_if); 5420 5421 tree rethrow = build_throw (fn_start, NULL_TREE, tf_warning_or_error); 5422 suppress_warning (rethrow); 5423 finish_expr_stmt (rethrow); 5424 finish_handler (handler); 5425 TRY_HANDLERS (ramp_cleanup) = pop_stmt_list (TRY_HANDLERS (ramp_cleanup)); 5426 } 5427 5428 BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body); 5429 TREE_SIDE_EFFECTS (ramp_bind) = true; 5430 5431 /* Start to build the final functions. 5432 5433 We push_deferring_access_checks to avoid these routines being seen as 5434 nested by the middle end; we are doing the outlining here. */ 5435 5436 push_deferring_access_checks (dk_no_check); 5437 5438 /* Build the actor... */ 5439 build_actor_fn (fn_start, coro_frame_type, actor, fnbody, orig, 5440 &local_var_uses, &suspend_points, param_dtor_list, 5441 resume_idx_var, body_aw_points.await_number, frame_size); 5442 5443 /* Destroyer ... */ 5444 build_destroy_fn (fn_start, coro_frame_type, destroy, actor); 5445 5446 pop_deferring_access_checks (); 5447 5448 DECL_SAVED_TREE (orig) = newbody; 5449 /* Link our new functions into the list. */ 5450 TREE_CHAIN (destroy) = TREE_CHAIN (orig); 5451 TREE_CHAIN (actor) = destroy; 5452 TREE_CHAIN (orig) = actor; 5453 5454 *resumer = actor; 5455 *destroyer = destroy; 5456 5457 return true; 5458 } 5459 5460 #include "gt-cp-coroutines.h" 5461 5462