]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/cp/coroutines.cc
coroutines: Wrap co_await in a target expr where needed [PR95050]
[thirdparty/gcc.git] / gcc / cp / coroutines.cc
1 /* coroutine-specific state, expansions and tests.
2
3 Copyright (C) 2018-2020 Free Software Foundation, Inc.
4
5 Contributed by Iain Sandoe <iain@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 promise_type; /* The cached promise type for this function. */
86 tree handle_type; /* The cached coroutine handle for this function. */
87 tree self_h_proxy; /* A handle instance that is used as the proxy for the
88 one that will eventually be allocated in the coroutine
89 frame. */
90 tree promise_proxy; /* Likewise, a proxy promise instance. */
91 location_t first_coro_keyword; /* The location of the keyword that made this
92 function into a coroutine. */
93 /* Flags to avoid repeated errors for per-function issues. */
94 bool coro_ret_type_error_emitted;
95 bool coro_promise_error_emitted;
96 };
97
98 struct coroutine_info_hasher : ggc_ptr_hash<coroutine_info>
99 {
100 typedef tree compare_type; /* We only compare the function decl. */
101 static inline hashval_t hash (coroutine_info *);
102 static inline hashval_t hash (const compare_type &);
103 static inline bool equal (coroutine_info *, coroutine_info *);
104 static inline bool equal (coroutine_info *, const compare_type &);
105 };
106
107 /* This table holds all the collected coroutine state for coroutines in
108 the current translation unit. */
109
110 static GTY (()) hash_table<coroutine_info_hasher> *coroutine_info_table;
111
112 /* We will initialise state lazily. */
113 static bool coro_initialized = false;
114
115 /* Return a hash value for the entry pointed to by INFO.
116 The compare type is a tree, but the only trees we are going use are
117 function decls. We use the DECL_UID as the hash value since that is
118 stable across PCH. */
119
120 hashval_t
121 coroutine_info_hasher::hash (coroutine_info *info)
122 {
123 return DECL_UID (info->function_decl);
124 }
125
126 /* Return a hash value for the compare value COMP. */
127
128 hashval_t
129 coroutine_info_hasher::hash (const compare_type& comp)
130 {
131 return DECL_UID (comp);
132 }
133
134 /* Return true if the entries pointed to by LHS and RHS are for the
135 same coroutine. */
136
137 bool
138 coroutine_info_hasher::equal (coroutine_info *lhs, coroutine_info *rhs)
139 {
140 return lhs->function_decl == rhs->function_decl;
141 }
142
143 bool
144 coroutine_info_hasher::equal (coroutine_info *lhs, const compare_type& rhs)
145 {
146 return lhs->function_decl == rhs;
147 }
148
149 /* Get the existing coroutine_info for FN_DECL, or insert a new one if the
150 entry does not yet exist. */
151
152 coroutine_info *
153 get_or_insert_coroutine_info (tree fn_decl)
154 {
155 gcc_checking_assert (coroutine_info_table != NULL);
156
157 coroutine_info **slot = coroutine_info_table->find_slot_with_hash
158 (fn_decl, coroutine_info_hasher::hash (fn_decl), INSERT);
159
160 if (*slot == NULL)
161 {
162 *slot = new (ggc_cleared_alloc<coroutine_info> ()) coroutine_info ();
163 (*slot)->function_decl = fn_decl;
164 }
165
166 return *slot;
167 }
168
169 /* Get the existing coroutine_info for FN_DECL, fail if it doesn't exist. */
170
171 coroutine_info *
172 get_coroutine_info (tree fn_decl)
173 {
174 if (coroutine_info_table == NULL)
175 return NULL;
176
177 coroutine_info **slot = coroutine_info_table->find_slot_with_hash
178 (fn_decl, coroutine_info_hasher::hash (fn_decl), NO_INSERT);
179 if (slot)
180 return *slot;
181 return NULL;
182 }
183
184 /* We will lazily create all the identifiers that are used by coroutines
185 on the first attempt to lookup the traits. */
186
187 /* Identifiers that are used by all coroutines. */
188
189 static GTY(()) tree coro_traits_identifier;
190 static GTY(()) tree coro_handle_identifier;
191 static GTY(()) tree coro_promise_type_identifier;
192
193 /* Required promise method name identifiers. */
194
195 static GTY(()) tree coro_await_transform_identifier;
196 static GTY(()) tree coro_initial_suspend_identifier;
197 static GTY(()) tree coro_final_suspend_identifier;
198 static GTY(()) tree coro_return_void_identifier;
199 static GTY(()) tree coro_return_value_identifier;
200 static GTY(()) tree coro_yield_value_identifier;
201 static GTY(()) tree coro_resume_identifier;
202 static GTY(()) tree coro_address_identifier;
203 static GTY(()) tree coro_from_address_identifier;
204 static GTY(()) tree coro_get_return_object_identifier;
205 static GTY(()) tree coro_gro_on_allocation_fail_identifier;
206 static GTY(()) tree coro_unhandled_exception_identifier;
207
208 /* Awaitable methods. */
209
210 static GTY(()) tree coro_await_ready_identifier;
211 static GTY(()) tree coro_await_suspend_identifier;
212 static GTY(()) tree coro_await_resume_identifier;
213
214 /* Create the identifiers used by the coroutines library interfaces. */
215
216 static void
217 coro_init_identifiers ()
218 {
219 coro_traits_identifier = get_identifier ("coroutine_traits");
220 coro_handle_identifier = get_identifier ("coroutine_handle");
221 coro_promise_type_identifier = get_identifier ("promise_type");
222
223 coro_await_transform_identifier = get_identifier ("await_transform");
224 coro_initial_suspend_identifier = get_identifier ("initial_suspend");
225 coro_final_suspend_identifier = get_identifier ("final_suspend");
226 coro_return_void_identifier = get_identifier ("return_void");
227 coro_return_value_identifier = get_identifier ("return_value");
228 coro_yield_value_identifier = get_identifier ("yield_value");
229 coro_resume_identifier = get_identifier ("resume");
230 coro_address_identifier = get_identifier ("address");
231 coro_from_address_identifier = get_identifier ("from_address");
232 coro_get_return_object_identifier = get_identifier ("get_return_object");
233 coro_gro_on_allocation_fail_identifier =
234 get_identifier ("get_return_object_on_allocation_failure");
235 coro_unhandled_exception_identifier = get_identifier ("unhandled_exception");
236
237 coro_await_ready_identifier = get_identifier ("await_ready");
238 coro_await_suspend_identifier = get_identifier ("await_suspend");
239 coro_await_resume_identifier = get_identifier ("await_resume");
240 }
241
242 /* Trees we only need to set up once. */
243
244 static GTY(()) tree coro_traits_templ;
245 static GTY(()) tree coro_handle_templ;
246 static GTY(()) tree void_coro_handle_type;
247
248 /* ================= Parse, Semantics and Type checking ================= */
249
250 /* This initial set of routines are helper for the parsing and template
251 expansion phases.
252
253 At the completion of this, we will have completed trees for each of the
254 keywords, but making use of proxy variables for the self-handle and the
255 promise class instance. */
256
257 /* [coroutine.traits]
258 Lookup the coroutine_traits template decl. */
259
260 static tree
261 find_coro_traits_template_decl (location_t kw)
262 {
263 /* If we are missing fundmental information, such as the traits, (or the
264 declaration found is not a type template), then don't emit an error for
265 every keyword in a TU, just do it once. */
266 static bool traits_error_emitted = false;
267
268 tree traits_decl = lookup_qualified_name (std_node, coro_traits_identifier,
269 0,
270 /*complain=*/!traits_error_emitted);
271 if (traits_decl == error_mark_node
272 || !DECL_TYPE_TEMPLATE_P (traits_decl))
273 {
274 if (!traits_error_emitted)
275 {
276 gcc_rich_location richloc (kw);
277 error_at (&richloc, "coroutines require a traits template; cannot"
278 " find %<%E::%E%>", std_node, coro_traits_identifier);
279 inform (&richloc, "perhaps %<#include <coroutine>%> is missing");
280 traits_error_emitted = true;
281 }
282 return NULL_TREE;
283 }
284 else
285 return traits_decl;
286 }
287
288 /* Instantiate Coroutine traits for the function signature. */
289
290 static tree
291 instantiate_coro_traits (tree fndecl, location_t kw)
292 {
293 /* [coroutine.traits.primary]
294 So now build up a type list for the template <typename _R, typename...>.
295 The types are the function's arg types and _R is the function return
296 type. */
297
298 tree functyp = TREE_TYPE (fndecl);
299 tree arg = DECL_ARGUMENTS (fndecl);
300 bool lambda_p = LAMBDA_FUNCTION_P (fndecl);
301 tree arg_node = TYPE_ARG_TYPES (functyp);
302 tree argtypes = make_tree_vec (list_length (arg_node)-1);
303 unsigned p = 0;
304
305 while (arg_node != NULL_TREE && !VOID_TYPE_P (TREE_VALUE (arg_node)))
306 {
307 /* See PR94807, as to why we must exclude lambda here. */
308 if (is_this_parameter (arg) && !lambda_p)
309 {
310 /* We pass a reference to *this to the param preview. */
311 tree ct = TREE_TYPE (TREE_TYPE (arg));
312 TREE_VEC_ELT (argtypes, p++) = cp_build_reference_type (ct, false);
313 }
314 else
315 TREE_VEC_ELT (argtypes, p++) = TREE_VALUE (arg_node);
316
317 arg_node = TREE_CHAIN (arg_node);
318 arg = DECL_CHAIN (arg);
319 }
320
321 tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK);
322 SET_ARGUMENT_PACK_ARGS (argtypepack, argtypes);
323
324 tree targ = make_tree_vec (2);
325 TREE_VEC_ELT (targ, 0) = TREE_TYPE (functyp);
326 TREE_VEC_ELT (targ, 1) = argtypepack;
327
328 tree traits_class
329 = lookup_template_class (coro_traits_templ, targ,
330 /*in_decl=*/NULL_TREE, /*context=*/NULL_TREE,
331 /*entering scope=*/false, tf_warning_or_error);
332
333 if (traits_class == error_mark_node)
334 {
335 error_at (kw, "cannot instantiate %<coroutine traits%>");
336 return NULL_TREE;
337 }
338
339 return traits_class;
340 }
341
342 /* [coroutine.handle] */
343
344 static tree
345 find_coro_handle_template_decl (location_t kw)
346 {
347 /* As for the coroutine traits, this error is per TU, so only emit
348 it once. */
349 static bool coro_handle_error_emitted = false;
350 tree handle_decl = lookup_qualified_name (std_node, coro_handle_identifier,
351 0, !coro_handle_error_emitted);
352 if (handle_decl == error_mark_node
353 || !DECL_CLASS_TEMPLATE_P (handle_decl))
354 {
355 if (!coro_handle_error_emitted)
356 error_at (kw, "coroutines require a handle class template;"
357 " cannot find %<%E::%E%>", std_node, coro_handle_identifier);
358 coro_handle_error_emitted = true;
359 return NULL_TREE;
360 }
361 else
362 return handle_decl;
363 }
364
365 /* Instantiate the handle template for a given promise type. */
366
367 static tree
368 instantiate_coro_handle_for_promise_type (location_t kw, tree promise_type)
369 {
370 /* So now build up a type list for the template, one entry, the promise. */
371 tree targ = make_tree_vec (1);
372 TREE_VEC_ELT (targ, 0) = promise_type;
373 tree handle_type
374 = lookup_template_class (coro_handle_identifier, targ,
375 /* in_decl=*/NULL_TREE,
376 /* context=*/std_node,
377 /* entering scope=*/false, tf_warning_or_error);
378
379 if (handle_type == error_mark_node)
380 {
381 error_at (kw, "cannot instantiate a %<coroutine handle%> for"
382 " promise type %qT", promise_type);
383 return NULL_TREE;
384 }
385
386 return handle_type;
387 }
388
389 /* Look for the promise_type in the instantiated traits. */
390
391 static tree
392 find_promise_type (tree traits_class)
393 {
394 tree promise_type
395 = lookup_member (traits_class, coro_promise_type_identifier,
396 /* protect=*/1, /*want_type=*/true, tf_warning_or_error);
397
398 if (promise_type)
399 promise_type
400 = complete_type_or_else (TREE_TYPE (promise_type), promise_type);
401
402 /* NULL_TREE on fail. */
403 return promise_type;
404 }
405
406 static bool
407 coro_promise_type_found_p (tree fndecl, location_t loc)
408 {
409 gcc_assert (fndecl != NULL_TREE);
410
411 if (!coro_initialized)
412 {
413 /* Trees we only need to create once.
414 Set up the identifiers we will use. */
415 coro_init_identifiers ();
416
417 /* Coroutine traits template. */
418 coro_traits_templ = find_coro_traits_template_decl (loc);
419 if (coro_traits_templ == NULL_TREE)
420 return false;
421
422 /* coroutine_handle<> template. */
423 coro_handle_templ = find_coro_handle_template_decl (loc);
424 if (coro_handle_templ == NULL_TREE)
425 return false;
426
427 /* We can also instantiate the void coroutine_handle<> */
428 void_coro_handle_type =
429 instantiate_coro_handle_for_promise_type (loc, NULL_TREE);
430 if (void_coro_handle_type == NULL_TREE)
431 return false;
432
433 /* A table to hold the state, per coroutine decl. */
434 gcc_checking_assert (coroutine_info_table == NULL);
435 coroutine_info_table =
436 hash_table<coroutine_info_hasher>::create_ggc (11);
437
438 if (coroutine_info_table == NULL)
439 return false;
440
441 coro_initialized = true;
442 }
443
444 /* Save the coroutine data on the side to avoid the overhead on every
445 function decl tree. */
446
447 coroutine_info *coro_info = get_or_insert_coroutine_info (fndecl);
448 /* Without this, we cannot really proceed. */
449 gcc_checking_assert (coro_info);
450
451 /* If we don't already have a current promise type, try to look it up. */
452 if (coro_info->promise_type == NULL_TREE)
453 {
454 /* Get the coroutine traits template class instance for the function
455 signature we have - coroutine_traits <R, ...> */
456
457 tree templ_class = instantiate_coro_traits (fndecl, loc);
458
459 /* Find the promise type for that. */
460 coro_info->promise_type = find_promise_type (templ_class);
461
462 /* If we don't find it, punt on the rest. */
463 if (coro_info->promise_type == NULL_TREE)
464 {
465 if (!coro_info->coro_promise_error_emitted)
466 error_at (loc, "unable to find the promise type for"
467 " this coroutine");
468 coro_info->coro_promise_error_emitted = true;
469 return false;
470 }
471
472 /* Try to find the handle type for the promise. */
473 tree handle_type =
474 instantiate_coro_handle_for_promise_type (loc, coro_info->promise_type);
475 if (handle_type == NULL_TREE)
476 return false;
477
478 /* Complete this, we're going to use it. */
479 coro_info->handle_type = complete_type_or_else (handle_type, fndecl);
480
481 /* Diagnostic would be emitted by complete_type_or_else. */
482 if (!coro_info->handle_type)
483 return false;
484
485 /* Build a proxy for a handle to "self" as the param to
486 await_suspend() calls. */
487 coro_info->self_h_proxy
488 = build_lang_decl (VAR_DECL, get_identifier ("self_h.proxy"),
489 coro_info->handle_type);
490
491 /* Build a proxy for the promise so that we can perform lookups. */
492 coro_info->promise_proxy
493 = build_lang_decl (VAR_DECL, get_identifier ("promise.proxy"),
494 coro_info->promise_type);
495
496 /* Note where we first saw a coroutine keyword. */
497 coro_info->first_coro_keyword = loc;
498 }
499
500 return true;
501 }
502
503 /* These functions assumes that the caller has verified that the state for
504 the decl has been initialized, we try to minimize work here. */
505
506 static tree
507 get_coroutine_promise_type (tree decl)
508 {
509 if (coroutine_info *info = get_coroutine_info (decl))
510 return info->promise_type;
511
512 return NULL_TREE;
513 }
514
515 static tree
516 get_coroutine_handle_type (tree decl)
517 {
518 if (coroutine_info *info = get_coroutine_info (decl))
519 return info->handle_type;
520
521 return NULL_TREE;
522 }
523
524 static tree
525 get_coroutine_self_handle_proxy (tree decl)
526 {
527 if (coroutine_info *info = get_coroutine_info (decl))
528 return info->self_h_proxy;
529
530 return NULL_TREE;
531 }
532
533 static tree
534 get_coroutine_promise_proxy (tree decl)
535 {
536 if (coroutine_info *info = get_coroutine_info (decl))
537 return info->promise_proxy;
538
539 return NULL_TREE;
540 }
541
542 static tree
543 lookup_promise_method (tree fndecl, tree member_id, location_t loc,
544 bool musthave)
545 {
546 tree promise = get_coroutine_promise_type (fndecl);
547 tree pm_memb
548 = lookup_member (promise, member_id,
549 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
550 if (musthave && pm_memb == NULL_TREE)
551 {
552 error_at (loc, "no member named %qE in %qT", member_id, promise);
553 return error_mark_node;
554 }
555 return pm_memb;
556 }
557
558 /* Lookup an Awaitable member, which should be await_ready, await_suspend
559 or await_resume. */
560
561 static tree
562 lookup_awaitable_member (tree await_type, tree member_id, location_t loc)
563 {
564 tree aw_memb
565 = lookup_member (await_type, member_id,
566 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
567 if (aw_memb == NULL_TREE)
568 {
569 error_at (loc, "no member named %qE in %qT", member_id, await_type);
570 return error_mark_node;
571 }
572 return aw_memb;
573 }
574
575 /* Here we check the constraints that are common to all keywords (since the
576 presence of a coroutine keyword makes the function into a coroutine). */
577
578 static bool
579 coro_common_keyword_context_valid_p (tree fndecl, location_t kw_loc,
580 const char *kw_name)
581 {
582 if (fndecl == NULL_TREE)
583 {
584 error_at (kw_loc, "%qs cannot be used outside a function", kw_name);
585 return false;
586 }
587
588 /* This is arranged in order of prohibitions in the std. */
589 if (DECL_MAIN_P (fndecl))
590 {
591 /* [basic.start.main] 3. The function main shall not be a coroutine. */
592 error_at (kw_loc, "%qs cannot be used in the %<main%> function",
593 kw_name);
594 return false;
595 }
596
597 if (DECL_DECLARED_CONSTEXPR_P (fndecl))
598 {
599 /* [dcl.constexpr] 3.3 it shall not be a coroutine. */
600 error_at (kw_loc, "%qs cannot be used in a %<constexpr%> function",
601 kw_name);
602 cp_function_chain->invalid_constexpr = true;
603 return false;
604 }
605
606 if (FNDECL_USED_AUTO (fndecl))
607 {
608 /* [dcl.spec.auto] 15. A function declared with a return type that uses
609 a placeholder type shall not be a coroutine. */
610 error_at (kw_loc,
611 "%qs cannot be used in a function with a deduced return type",
612 kw_name);
613 return false;
614 }
615
616 if (varargs_function_p (fndecl))
617 {
618 /* [dcl.fct.def.coroutine] The parameter-declaration-clause of the
619 coroutine shall not terminate with an ellipsis that is not part
620 of a parameter-declaration. */
621 error_at (kw_loc,
622 "%qs cannot be used in a varargs function", kw_name);
623 return false;
624 }
625
626 if (DECL_CONSTRUCTOR_P (fndecl))
627 {
628 /* [class.ctor] 7. a constructor shall not be a coroutine. */
629 error_at (kw_loc, "%qs cannot be used in a constructor", kw_name);
630 return false;
631 }
632
633 if (DECL_DESTRUCTOR_P (fndecl))
634 {
635 /* [class.dtor] 21. a destructor shall not be a coroutine. */
636 error_at (kw_loc, "%qs cannot be used in a destructor", kw_name);
637 return false;
638 }
639
640 return true;
641 }
642
643 /* Here we check the constraints that are not per keyword. */
644
645 static bool
646 coro_function_valid_p (tree fndecl)
647 {
648 location_t f_loc = DECL_SOURCE_LOCATION (fndecl);
649
650 /* For cases where fundamental information cannot be found, e.g. the
651 coroutine traits are missing, we need to punt early. */
652 if (!coro_promise_type_found_p (fndecl, f_loc))
653 return false;
654
655 /* Since we think the function is a coroutine, that implies we parsed
656 a keyword that triggered this. Keywords check promise validity for
657 their context and thus the promise type should be known at this point. */
658 if (get_coroutine_handle_type (fndecl) == NULL_TREE
659 || get_coroutine_promise_type (fndecl) == NULL_TREE)
660 return false;
661
662 if (current_function_returns_value || current_function_returns_null)
663 {
664 /* TODO: record or extract positions of returns (and the first coro
665 keyword) so that we can add notes to the diagnostic about where
666 the bad keyword is and what made the function into a coro. */
667 error_at (f_loc, "a %<return%> statement is not allowed in coroutine;"
668 " did you mean %<co_return%>?");
669 return false;
670 }
671
672 return true;
673 }
674
675 enum suspend_point_kind {
676 CO_AWAIT_SUSPEND_POINT = 0,
677 CO_YIELD_SUSPEND_POINT,
678 INITIAL_SUSPEND_POINT,
679 FINAL_SUSPEND_POINT
680 };
681
682 /* This performs [expr.await] bullet 3.3 and validates the interface obtained.
683 It is also used to build the initial and final suspend points.
684
685 'a', 'o' and 'e' are used as per the description in the section noted.
686
687 A, the original yield/await expr, is found at source location LOC.
688
689 We will be constructing a CO_AWAIT_EXPR for a suspend point of one of
690 the four suspend_point_kind kinds. This is indicated by SUSPEND_KIND. */
691
692 static tree
693 build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind)
694 {
695 /* Try and overload of operator co_await, .... */
696 tree o;
697 if (MAYBE_CLASS_TYPE_P (TREE_TYPE (a)))
698 {
699 o = build_new_op (loc, CO_AWAIT_EXPR, LOOKUP_NORMAL, a, NULL_TREE,
700 NULL_TREE, NULL, tf_warning_or_error);
701 /* If no viable functions are found, o is a. */
702 if (!o || o == error_mark_node)
703 o = a;
704 }
705 else
706 o = a; /* This is most likely about to fail anyway. */
707
708 tree o_type = TREE_TYPE (o);
709 if (o_type && !VOID_TYPE_P (o_type))
710 o_type = complete_type_or_else (o_type, o);
711
712 if (!o_type)
713 return error_mark_node;
714
715 if (TREE_CODE (o_type) != RECORD_TYPE)
716 {
717 error_at (loc, "awaitable type %qT is not a structure",
718 o_type);
719 return error_mark_node;
720 }
721
722 /* Check for required awaitable members and their types. */
723 tree awrd_meth
724 = lookup_awaitable_member (o_type, coro_await_ready_identifier, loc);
725 if (!awrd_meth || awrd_meth == error_mark_node)
726 return error_mark_node;
727 tree awsp_meth
728 = lookup_awaitable_member (o_type, coro_await_suspend_identifier, loc);
729 if (!awsp_meth || awsp_meth == error_mark_node)
730 return error_mark_node;
731
732 /* The type of the co_await is the return type of the awaitable's
733 await_resume, so we need to look that up. */
734 tree awrs_meth
735 = lookup_awaitable_member (o_type, coro_await_resume_identifier, loc);
736 if (!awrs_meth || awrs_meth == error_mark_node)
737 return error_mark_node;
738
739 /* To complete the lookups, we need an instance of 'e' which is built from
740 'o' according to [expr.await] 3.4. However, we don't want to materialize
741 'e' here (it might need to be placed in the coroutine frame) so we will
742 make a temp placeholder instead. If 'o' is a parameter or a local var,
743 then we do not need an additional var (parms and local vars are already
744 copied into the frame and will have lifetimes according to their original
745 scope). */
746 tree e_proxy = STRIP_NOPS (o);
747 if (INDIRECT_REF_P (e_proxy))
748 e_proxy = TREE_OPERAND (e_proxy, 0);
749 if (TREE_CODE (e_proxy) == PARM_DECL
750 || (VAR_P (e_proxy) && (!DECL_ARTIFICIAL (e_proxy)
751 || DECL_HAS_VALUE_EXPR_P (e_proxy))))
752 e_proxy = o;
753 else
754 {
755 e_proxy = build_lang_decl (VAR_DECL, NULL_TREE, o_type);
756 DECL_ARTIFICIAL (e_proxy) = true;
757 }
758
759 /* I suppose we could check that this is contextually convertible to bool. */
760 tree awrd_func = NULL_TREE;
761 tree awrd_call
762 = build_new_method_call (e_proxy, awrd_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
763 &awrd_func, tf_warning_or_error);
764
765 if (!awrd_func || !awrd_call || awrd_call == error_mark_node)
766 return error_mark_node;
767
768 /* The suspend method may return one of three types:
769 1. void (no special action needed).
770 2. bool (if true, we don't need to suspend).
771 3. a coroutine handle, we execute the handle.resume() call. */
772 tree awsp_func = NULL_TREE;
773 tree h_proxy = get_coroutine_self_handle_proxy (current_function_decl);
774 vec<tree, va_gc> *args = make_tree_vector_single (h_proxy);
775 tree awsp_call
776 = build_new_method_call (e_proxy, awsp_meth, &args, NULL_TREE,
777 LOOKUP_NORMAL, &awsp_func, tf_warning_or_error);
778
779 release_tree_vector (args);
780 if (!awsp_func || !awsp_call || awsp_call == error_mark_node)
781 return error_mark_node;
782
783 bool ok = false;
784 tree susp_return_type = TREE_TYPE (TREE_TYPE (awsp_func));
785 if (same_type_p (susp_return_type, void_type_node))
786 ok = true;
787 else if (same_type_p (susp_return_type, boolean_type_node))
788 ok = true;
789 else if (TREE_CODE (susp_return_type) == RECORD_TYPE
790 && CLASS_TYPE_P (susp_return_type))
791 {
792 tree tt = CLASSTYPE_TI_TEMPLATE (susp_return_type);
793 if (tt == coro_handle_templ)
794 ok = true;
795 }
796
797 if (!ok)
798 {
799 error_at (loc, "%<await_suspend%> must return %<void%>, %<bool%> or"
800 " a coroutine handle");
801 return error_mark_node;
802 }
803
804 /* Finally, the type of e.await_resume() is the co_await's type. */
805 tree awrs_func = NULL_TREE;
806 tree awrs_call
807 = build_new_method_call (e_proxy, awrs_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
808 &awrs_func, tf_warning_or_error);
809
810 if (!awrs_func || !awrs_call || awrs_call == error_mark_node)
811 return error_mark_node;
812
813 /* We now have three call expressions, in terms of the promise, handle and
814 'e' proxies. Save them in the await expression for later expansion. */
815
816 tree awaiter_calls = make_tree_vec (3);
817 TREE_VEC_ELT (awaiter_calls, 0) = awrd_call; /* await_ready(). */
818 TREE_VEC_ELT (awaiter_calls, 1) = awsp_call; /* await_suspend(). */
819 tree te = NULL_TREE;
820 if (TREE_CODE (awrs_call) == TARGET_EXPR)
821 {
822 te = awrs_call;
823 awrs_call = TREE_OPERAND (awrs_call, 1);
824 }
825 TREE_VEC_ELT (awaiter_calls, 2) = awrs_call; /* await_resume(). */
826
827 tree await_expr = build5_loc (loc, CO_AWAIT_EXPR,
828 TREE_TYPE (TREE_TYPE (awrs_func)),
829 a, e_proxy, o, awaiter_calls,
830 build_int_cst (integer_type_node,
831 (int) suspend_kind));
832 if (te)
833 {
834 TREE_OPERAND (te, 1) = await_expr;
835 await_expr = te;
836 }
837 tree t = convert_from_reference (await_expr);
838 return t;
839 }
840
841 tree
842 finish_co_await_expr (location_t kw, tree expr)
843 {
844 if (!expr || error_operand_p (expr))
845 return error_mark_node;
846
847 if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
848 "co_await"))
849 return error_mark_node;
850
851 /* The current function has now become a coroutine, if it wasn't already. */
852 DECL_COROUTINE_P (current_function_decl) = 1;
853
854 if (processing_template_decl)
855 {
856 current_function_returns_value = 1;
857
858 if (check_for_bare_parameter_packs (expr))
859 return error_mark_node;
860
861 /* If we don't know the promise type, we can't proceed. */
862 tree functype = TREE_TYPE (current_function_decl);
863 if (dependent_type_p (functype) || type_dependent_expression_p (expr))
864 return build5_loc (kw, CO_AWAIT_EXPR, unknown_type_node, expr,
865 NULL_TREE, NULL_TREE, NULL_TREE, integer_zero_node);
866 }
867
868 /* We must be able to look up the "await_transform" method in the scope of
869 the promise type, and obtain its return type. */
870 if (!coro_promise_type_found_p (current_function_decl, kw))
871 return error_mark_node;
872
873 /* [expr.await] 3.2
874 The incoming cast expression might be transformed by a promise
875 'await_transform()'. */
876 tree at_meth
877 = lookup_promise_method (current_function_decl,
878 coro_await_transform_identifier, kw,
879 /*musthave=*/false);
880 if (at_meth == error_mark_node)
881 return error_mark_node;
882
883 tree a = expr;
884 if (at_meth)
885 {
886 /* try to build a = p.await_transform (e). */
887 vec<tree, va_gc> *args = make_tree_vector_single (expr);
888 a = build_new_method_call (get_coroutine_promise_proxy (
889 current_function_decl),
890 at_meth, &args, NULL_TREE, LOOKUP_NORMAL,
891 NULL, tf_warning_or_error);
892
893 /* As I read the section.
894 We saw an await_transform method, so it's mandatory that we replace
895 expr with p.await_transform (expr), therefore if the method call fails
896 (presumably, we don't have suitable arguments) then this part of the
897 process fails. */
898 if (a == error_mark_node)
899 return error_mark_node;
900 }
901
902 /* Now we want to build co_await a. */
903 tree op = build_co_await (kw, a, CO_AWAIT_SUSPEND_POINT);
904 if (op != error_mark_node)
905 {
906 TREE_SIDE_EFFECTS (op) = 1;
907 SET_EXPR_LOCATION (op, kw);
908 }
909
910 return op;
911 }
912
913 /* Take the EXPR given and attempt to build:
914 co_await p.yield_value (expr);
915 per [expr.yield] para 1. */
916
917 tree
918 finish_co_yield_expr (location_t kw, tree expr)
919 {
920 if (!expr || error_operand_p (expr))
921 return error_mark_node;
922
923 /* Check the general requirements and simple syntax errors. */
924 if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
925 "co_yield"))
926 return error_mark_node;
927
928 /* The current function has now become a coroutine, if it wasn't already. */
929 DECL_COROUTINE_P (current_function_decl) = 1;
930
931 if (processing_template_decl)
932 {
933 current_function_returns_value = 1;
934
935 if (check_for_bare_parameter_packs (expr))
936 return error_mark_node;
937
938 tree functype = TREE_TYPE (current_function_decl);
939 /* If we don't know the promise type, we can't proceed. */
940 if (dependent_type_p (functype) || type_dependent_expression_p (expr))
941 return build2_loc (kw, CO_YIELD_EXPR, unknown_type_node, expr,
942 NULL_TREE);
943 }
944
945 if (!coro_promise_type_found_p (current_function_decl, kw))
946 /* We must be able to look up the "yield_value" method in the scope of
947 the promise type, and obtain its return type. */
948 return error_mark_node;
949
950 /* The incoming expr is "e" per [expr.yield] para 1, lookup and build a
951 call for p.yield_value(e). */
952 tree y_meth = lookup_promise_method (current_function_decl,
953 coro_yield_value_identifier, kw,
954 /*musthave=*/true);
955 if (!y_meth || y_meth == error_mark_node)
956 return error_mark_node;
957
958 /* [expr.yield] / 1
959 Let e be the operand of the yield-expression and p be an lvalue naming
960 the promise object of the enclosing coroutine, then the yield-expression
961 is equivalent to the expression co_await p.yield_value(e).
962 build p.yield_value(e): */
963 vec<tree, va_gc> *args = make_tree_vector_single (expr);
964 tree yield_call = build_new_method_call
965 (get_coroutine_promise_proxy (current_function_decl), y_meth, &args,
966 NULL_TREE, LOOKUP_NORMAL, NULL, tf_warning_or_error);
967
968 /* Now build co_await p.yield_value (e).
969 Noting that for co_yield, there is no evaluation of any potential
970 promise transform_await(), so we call build_co_await directly. */
971
972 tree op = build_co_await (kw, yield_call, CO_YIELD_SUSPEND_POINT);
973 if (op != error_mark_node)
974 {
975 if (REFERENCE_REF_P (op))
976 op = TREE_OPERAND (op, 0);
977 /* If the await expression is wrapped in a TARGET_EXPR, then transfer
978 that wrapper to the CO_YIELD_EXPR, since this is just a proxy for
979 its contained await. Otherwise, just build the CO_YIELD_EXPR. */
980 if (TREE_CODE (op) == TARGET_EXPR)
981 {
982 tree t = TREE_OPERAND (op, 1);
983 t = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (t), expr, t);
984 TREE_OPERAND (op, 1) = t;
985 }
986 else
987 op = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (op), expr, op);
988 TREE_SIDE_EFFECTS (op) = 1;
989 op = convert_from_reference (op);
990 }
991
992 return op;
993 }
994
995 /* Check and build a co_return statememt.
996 First that it's valid to have a co_return keyword here.
997 If it is, then check and build the p.return_{void(),value(expr)}.
998 These are built against a proxy for the promise, which will be filled
999 in with the actual frame version when the function is transformed. */
1000
1001 tree
1002 finish_co_return_stmt (location_t kw, tree expr)
1003 {
1004 if (expr)
1005 STRIP_ANY_LOCATION_WRAPPER (expr);
1006
1007 if (error_operand_p (expr))
1008 return error_mark_node;
1009
1010 /* If it fails the following test, the function is not permitted to be a
1011 coroutine, so the co_return statement is erroneous. */
1012 if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
1013 "co_return"))
1014 return error_mark_node;
1015
1016 /* The current function has now become a coroutine, if it wasn't
1017 already. */
1018 DECL_COROUTINE_P (current_function_decl) = 1;
1019
1020 /* This function will appear to have no return statement, even if it
1021 is declared to return non-void (most likely). This is correct - we
1022 synthesize the return for the ramp in the compiler. So suppress any
1023 extraneous warnings during substitution. */
1024 TREE_NO_WARNING (current_function_decl) = true;
1025
1026 if (processing_template_decl
1027 && check_for_bare_parameter_packs (expr))
1028 return error_mark_node;
1029
1030 /* If we don't know the promise type, we can't proceed, build the
1031 co_return with the expression unchanged. */
1032 tree functype = TREE_TYPE (current_function_decl);
1033 if (dependent_type_p (functype) || type_dependent_expression_p (expr))
1034 {
1035 /* co_return expressions are always void type, regardless of the
1036 expression type. */
1037 expr = build2_loc (kw, CO_RETURN_EXPR, void_type_node,
1038 expr, NULL_TREE);
1039 expr = maybe_cleanup_point_expr_void (expr);
1040 return add_stmt (expr);
1041 }
1042
1043 if (!coro_promise_type_found_p (current_function_decl, kw))
1044 return error_mark_node;
1045
1046 /* Suppress -Wreturn-type for co_return, we need to check indirectly
1047 whether the promise type has a suitable return_void/return_value. */
1048 TREE_NO_WARNING (current_function_decl) = true;
1049
1050 if (!processing_template_decl && warn_sequence_point)
1051 verify_sequence_points (expr);
1052
1053 if (expr)
1054 {
1055 /* If we had an id-expression obfuscated by force_paren_expr, we need
1056 to undo it so we can try to treat it as an rvalue below. */
1057 expr = maybe_undo_parenthesized_ref (expr);
1058
1059 if (processing_template_decl)
1060 expr = build_non_dependent_expr (expr);
1061
1062 if (error_operand_p (expr))
1063 return error_mark_node;
1064 }
1065
1066 /* If the promise object doesn't have the correct return call then
1067 there's a mis-match between the co_return <expr> and this. */
1068 tree co_ret_call = error_mark_node;
1069 if (expr == NULL_TREE || VOID_TYPE_P (TREE_TYPE (expr)))
1070 {
1071 tree crv_meth
1072 = lookup_promise_method (current_function_decl,
1073 coro_return_void_identifier, kw,
1074 /*musthave=*/true);
1075 if (crv_meth == error_mark_node)
1076 return error_mark_node;
1077
1078 co_ret_call = build_new_method_call (
1079 get_coroutine_promise_proxy (current_function_decl), crv_meth, NULL,
1080 NULL_TREE, LOOKUP_NORMAL, NULL, tf_warning_or_error);
1081 }
1082 else
1083 {
1084 tree crv_meth
1085 = lookup_promise_method (current_function_decl,
1086 coro_return_value_identifier, kw,
1087 /*musthave=*/true);
1088 if (crv_meth == error_mark_node)
1089 return error_mark_node;
1090
1091 /* [class.copy.elision] / 3.
1092 An implicitly movable entity is a variable of automatic storage
1093 duration that is either a non-volatile object or an rvalue reference
1094 to a non-volatile object type. For such objects in the context of
1095 the co_return, the overload resolution should be carried out first
1096 treating the object as an rvalue, if that fails, then we fall back
1097 to regular overload resolution. */
1098
1099 if (treat_lvalue_as_rvalue_p (expr, /*parm_ok*/true)
1100 && CLASS_TYPE_P (TREE_TYPE (expr))
1101 && !TYPE_VOLATILE (TREE_TYPE (expr)))
1102 {
1103 vec<tree, va_gc> *args = make_tree_vector_single (move (expr));
1104 /* It's OK if this fails... */
1105 co_ret_call = build_new_method_call
1106 (get_coroutine_promise_proxy (current_function_decl), crv_meth,
1107 &args, NULL_TREE, LOOKUP_NORMAL|LOOKUP_PREFER_RVALUE,
1108 NULL, tf_none);
1109 }
1110
1111 if (co_ret_call == error_mark_node)
1112 {
1113 vec<tree, va_gc> *args = make_tree_vector_single (expr);
1114 /* ... but this must succeed if we didn't get the move variant. */
1115 co_ret_call = build_new_method_call
1116 (get_coroutine_promise_proxy (current_function_decl), crv_meth,
1117 &args, NULL_TREE, LOOKUP_NORMAL, NULL, tf_warning_or_error);
1118 }
1119 }
1120
1121 /* Makes no sense for a co-routine really. */
1122 if (TREE_THIS_VOLATILE (current_function_decl))
1123 warning_at (kw, 0,
1124 "function declared %<noreturn%> has a"
1125 " %<co_return%> statement");
1126
1127 expr = build2_loc (kw, CO_RETURN_EXPR, void_type_node, expr, co_ret_call);
1128 expr = maybe_cleanup_point_expr_void (expr);
1129 return add_stmt (expr);
1130 }
1131
1132 /* We need to validate the arguments to __builtin_coro_promise, since the
1133 second two must be constant, and the builtins machinery doesn't seem to
1134 deal with that properly. */
1135
1136 tree
1137 coro_validate_builtin_call (tree call, tsubst_flags_t)
1138 {
1139 tree fn = TREE_OPERAND (CALL_EXPR_FN (call), 0);
1140
1141 gcc_checking_assert (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL);
1142 switch (DECL_FUNCTION_CODE (fn))
1143 {
1144 default:
1145 return call;
1146
1147 case BUILT_IN_CORO_PROMISE:
1148 {
1149 /* Argument 0 is already checked by the normal built-in machinery
1150 Argument 1 must be a constant of size type. It probably makes
1151 little sense if it's not a power of 2, but that isn't specified
1152 formally. */
1153 tree arg = CALL_EXPR_ARG (call, 1);
1154 location_t loc = EXPR_LOCATION (arg);
1155
1156 /* We expect alignof expressions in templates. */
1157 if (TREE_CODE (arg) == NON_DEPENDENT_EXPR
1158 && TREE_CODE (TREE_OPERAND (arg, 0)) == ALIGNOF_EXPR)
1159 ;
1160 else if (!TREE_CONSTANT (arg))
1161 {
1162 error_at (loc, "the align argument to %<__builtin_coro_promise%>"
1163 " must be a constant");
1164 return error_mark_node;
1165 }
1166 /* Argument 2 is the direction - to / from handle address to promise
1167 address. */
1168 arg = CALL_EXPR_ARG (call, 2);
1169 loc = EXPR_LOCATION (arg);
1170 if (!TREE_CONSTANT (arg))
1171 {
1172 error_at (loc, "the direction argument to"
1173 " %<__builtin_coro_promise%> must be a constant");
1174 return error_mark_node;
1175 }
1176 return call;
1177 break;
1178 }
1179 }
1180 }
1181
1182 /* ================= Morph and Expand. =================
1183
1184 The entry point here is morph_fn_to_coro () which is called from
1185 finish_function () when we have completed any template expansion.
1186
1187 This is preceded by helper functions that implement the phases below.
1188
1189 The process proceeds in four phases.
1190
1191 A Initial framing.
1192 The user's function body is wrapped in the initial and final suspend
1193 points and we begin building the coroutine frame.
1194 We build empty decls for the actor and destroyer functions at this
1195 time too.
1196 When exceptions are enabled, the user's function body will also be
1197 wrapped in a try-catch block with the catch invoking the promise
1198 class 'unhandled_exception' method.
1199
1200 B Analysis.
1201 The user's function body is analyzed to determine the suspend points,
1202 if any, and to capture local variables that might persist across such
1203 suspensions. In most cases, it is not necessary to capture compiler
1204 temporaries, since the tree-lowering nests the suspensions correctly.
1205 However, in the case of a captured reference, there is a lifetime
1206 extension to the end of the full expression - which can mean across a
1207 suspend point in which case it must be promoted to a frame variable.
1208
1209 At the conclusion of analysis, we have a conservative frame layout and
1210 maps of the local variables to their frame entry points.
1211
1212 C Build the ramp function.
1213 Carry out the allocation for the coroutine frame (NOTE; the actual size
1214 computation is deferred until late in the middle end to allow for future
1215 optimizations that will be allowed to elide unused frame entries).
1216 We build the return object.
1217
1218 D Build and expand the actor and destroyer function bodies.
1219 The destroyer is a trivial shim that sets a bit to indicate that the
1220 destroy dispatcher should be used and then calls into the actor.
1221
1222 The actor function is the implementation of the user's state machine.
1223 The current suspend point is noted in an index.
1224 Each suspend point is encoded as a pair of internal functions, one in
1225 the relevant dispatcher, and one representing the suspend point.
1226
1227 During this process, the user's local variables and the proxies for the
1228 self-handle and the promise class instance are re-written to their
1229 coroutine frame equivalents.
1230
1231 The complete bodies for the ramp, actor and destroy function are passed
1232 back to finish_function for folding and gimplification. */
1233
1234 /* Helpers to build EXPR_STMT and void-cast EXPR_STMT, common ops. */
1235
1236 static tree
1237 coro_build_expr_stmt (tree expr, location_t loc)
1238 {
1239 return maybe_cleanup_point_expr_void (build_stmt (loc, EXPR_STMT, expr));
1240 }
1241
1242 static tree
1243 coro_build_cvt_void_expr_stmt (tree expr, location_t loc)
1244 {
1245 tree t = build1 (CONVERT_EXPR, void_type_node, expr);
1246 return coro_build_expr_stmt (t, loc);
1247 }
1248
1249 /* Helpers for label creation:
1250 1. Create a named label in the specified context. */
1251
1252 static tree
1253 create_anon_label_with_ctx (location_t loc, tree ctx)
1254 {
1255 tree lab = build_decl (loc, LABEL_DECL, NULL_TREE, void_type_node);
1256
1257 DECL_CONTEXT (lab) = ctx;
1258 DECL_ARTIFICIAL (lab) = true;
1259 DECL_IGNORED_P (lab) = true;
1260 TREE_USED (lab) = true;
1261 return lab;
1262 }
1263
1264 /* 2. Create a named label in the specified context. */
1265
1266 static tree
1267 create_named_label_with_ctx (location_t loc, const char *name, tree ctx)
1268 {
1269 tree lab_id = get_identifier (name);
1270 tree lab = define_label (loc, lab_id);
1271 DECL_CONTEXT (lab) = ctx;
1272 DECL_ARTIFICIAL (lab) = true;
1273 TREE_USED (lab) = true;
1274 return lab;
1275 }
1276
1277 struct proxy_replace
1278 {
1279 tree from, to;
1280 };
1281
1282 static tree
1283 replace_proxy (tree *here, int *do_subtree, void *d)
1284 {
1285 proxy_replace *data = (proxy_replace *) d;
1286
1287 if (*here == data->from)
1288 {
1289 *here = data->to;
1290 *do_subtree = 0;
1291 }
1292 else
1293 *do_subtree = 1;
1294 return NULL_TREE;
1295 }
1296
1297 /* Support for expansion of co_return statements. */
1298
1299 struct coro_ret_data
1300 {
1301 tree promise_proxy;
1302 tree real_promise;
1303 tree fs_label;
1304 };
1305
1306 /* If this is a coreturn statement (or one wrapped in a cleanup) then
1307 return the list of statements to replace it. */
1308
1309 static tree
1310 coro_maybe_expand_co_return (tree co_ret_expr, coro_ret_data *data)
1311 {
1312 /* Look inside <(void) (expr)> cleanup */
1313 if (TREE_CODE (co_ret_expr) == CLEANUP_POINT_EXPR)
1314 co_ret_expr = TREE_OPERAND (co_ret_expr, 0);
1315
1316 if (TREE_CODE (co_ret_expr) != CO_RETURN_EXPR)
1317 return NULL_TREE;
1318
1319 location_t loc = EXPR_LOCATION (co_ret_expr);
1320 tree expr = TREE_OPERAND (co_ret_expr, 0);
1321 tree call = TREE_OPERAND (co_ret_expr, 1);
1322 tree stmt_list = NULL;
1323 if (expr && VOID_TYPE_P (TREE_TYPE (expr)))
1324 {
1325 /* [stmt.return.coroutine], 2.2
1326 If expr is present and void, it is placed immediately before
1327 the call for return_void; */
1328 expr = maybe_cleanup_point_expr_void (expr);
1329 append_to_statement_list (expr, &stmt_list);
1330 }
1331
1332 /* Now replace the promise proxy with its real value. */
1333 proxy_replace p_data;
1334 p_data.from = data->promise_proxy;
1335 p_data.to = data->real_promise;
1336 cp_walk_tree (&call, replace_proxy, &p_data, NULL);
1337
1338 /* The types of p.return_void and p.return_value are not explicitly stated
1339 at least in n4835, it is expected that they will return void. */
1340 call = maybe_cleanup_point_expr_void (call);
1341 append_to_statement_list (call, &stmt_list);
1342 tree r = build1_loc (loc, GOTO_EXPR, void_type_node, data->fs_label);
1343 append_to_statement_list (r, &stmt_list);
1344 return stmt_list;
1345 }
1346
1347 /* Callback that rewrites co_return as per [stmt.return.coroutine]
1348 - for co_return;
1349 { p.return_void (); goto final_suspend; }
1350 - for co_return [void expr];
1351 { expr; p.return_void(); goto final_suspend;}
1352 - for co_return [non void expr];
1353 { p.return_value(expr); goto final_suspend; } */
1354
1355 static tree
1356 co_return_expander (tree *stmt, int *do_subtree, void *d)
1357 {
1358 coro_ret_data *data = (coro_ret_data *) d;
1359
1360 /* To avoid nesting statement lists, walk them and insert as needed. */
1361 if (TREE_CODE (*stmt) == STATEMENT_LIST)
1362 {
1363 tree_stmt_iterator i;
1364 for (i = tsi_start (*stmt); !tsi_end_p (i); tsi_next (&i))
1365 {
1366 tree *new_stmt = tsi_stmt_ptr (i);
1367 tree replace = coro_maybe_expand_co_return (*new_stmt, data);
1368 /* If we got something, it will be list and we want to splice
1369 it in. */
1370 if (replace != NULL_TREE)
1371 {
1372 /* Splice it in ... */
1373 tsi_link_before (&i, replace, TSI_SAME_STMT);
1374 /* ... and delete what we expanded. */
1375 tsi_delink (&i);
1376 /* Maybe, even likely, we replaced the last in the list. */
1377 if (tsi_end_p (i))
1378 break;
1379 }
1380 else /* Continue the walk. */
1381 cp_walk_tree (new_stmt, co_return_expander, d, NULL);
1382 }
1383 *do_subtree = 0; /* Done subtrees. */
1384 }
1385 else
1386 {
1387 /* We might have a single co_return statement, in which case, we do
1388 have to replace it with a list. */
1389 tree replace = coro_maybe_expand_co_return (*stmt, data);
1390 if (replace != NULL_TREE)
1391 {
1392 *stmt = replace;
1393 *do_subtree = 0; /* Done here. */
1394 }
1395 }
1396 return NULL_TREE;
1397 }
1398
1399 /* Walk the original function body, rewriting co_returns. */
1400
1401 static tree
1402 expand_co_returns (tree *fnbody, tree promise_proxy, tree promise,
1403 tree fs_label)
1404 {
1405 coro_ret_data data = {promise_proxy, promise, fs_label};
1406 cp_walk_tree (fnbody, co_return_expander, &data, NULL);
1407 return *fnbody;
1408 }
1409
1410 /* Support for expansion of co_await statements. */
1411
1412 struct coro_aw_data
1413 {
1414 tree actor_fn; /* Decl for context. */
1415 tree coro_fp; /* Frame pointer var. */
1416 tree resume_idx; /* This is the index var in the frame. */
1417 tree i_a_r_c; /* initial suspend await_resume() was called if true. */
1418 tree self_h; /* This is a handle to the current coro (frame var). */
1419 tree cleanup; /* This is where to go once we complete local destroy. */
1420 tree cororet; /* This is where to go if we suspend. */
1421 tree corocont; /* This is where to go if we continue. */
1422 tree conthand; /* This is the handle for a continuation. */
1423 unsigned index; /* This is our current resume index. */
1424 };
1425
1426 /* Lighweight search for the first await expression in tree-walk order.
1427 returns:
1428 The first await expression found in STMT.
1429 NULL_TREE if there are none.
1430 So can be used to determine if the statement needs to be processed for
1431 awaits. */
1432
1433 static tree
1434 co_await_find_in_subtree (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
1435 {
1436 tree **p = (tree **) d;
1437 if (TREE_CODE (*stmt) == CO_AWAIT_EXPR)
1438 {
1439 *p = stmt;
1440 return *stmt;
1441 }
1442 return NULL_TREE;
1443 }
1444
1445 /* Starting with a statment:
1446
1447 stmt => some tree containing one or more await expressions.
1448
1449 We replace the statement with:
1450 <STATEMENT_LIST> {
1451 initialise awaitable
1452 if (!ready)
1453 {
1454 suspension context.
1455 }
1456 resume:
1457 revised statement with one await expression rewritten to its
1458 await_resume() return value.
1459 }
1460
1461 We then recurse into the initializer and the revised statement
1462 repeating this replacement until there are no more await expressions
1463 in either. */
1464
1465 static tree *
1466 expand_one_await_expression (tree *stmt, tree *await_expr, void *d)
1467 {
1468 coro_aw_data *data = (coro_aw_data *) d;
1469
1470 tree saved_statement = *stmt;
1471 tree saved_co_await = *await_expr;
1472
1473 tree actor = data->actor_fn;
1474 location_t loc = EXPR_LOCATION (*stmt);
1475 tree var = TREE_OPERAND (saved_co_await, 1); /* frame slot. */
1476 tree expr = TREE_OPERAND (saved_co_await, 2); /* initializer. */
1477 tree awaiter_calls = TREE_OPERAND (saved_co_await, 3);
1478
1479 tree source = TREE_OPERAND (saved_co_await, 4);
1480 bool is_initial =
1481 (source && TREE_INT_CST_LOW (source) == (int) INITIAL_SUSPEND_POINT);
1482 bool is_final = (source
1483 && TREE_INT_CST_LOW (source) == (int) FINAL_SUSPEND_POINT);
1484 bool needs_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var));
1485 int resume_point = data->index;
1486 size_t bufsize = sizeof ("destroy.") + 10;
1487 char *buf = (char *) alloca (bufsize);
1488 snprintf (buf, bufsize, "destroy.%d", resume_point);
1489 tree destroy_label = create_named_label_with_ctx (loc, buf, actor);
1490 snprintf (buf, bufsize, "resume.%d", resume_point);
1491 tree resume_label = create_named_label_with_ctx (loc, buf, actor);
1492 tree empty_list = build_empty_stmt (loc);
1493
1494 tree dtor = NULL_TREE;
1495 tree await_type = TREE_TYPE (var);
1496 if (needs_dtor)
1497 dtor = build_special_member_call (var, complete_dtor_identifier, NULL,
1498 await_type, LOOKUP_NORMAL,
1499 tf_warning_or_error);
1500
1501 tree stmt_list = NULL;
1502 tree t_expr = STRIP_NOPS (expr);
1503 tree r;
1504 tree *await_init = NULL;
1505 if (t_expr == var)
1506 dtor = NULL_TREE;
1507 else
1508 {
1509 /* Initialize the var from the provided 'o' expression. */
1510 r = build2 (INIT_EXPR, await_type, var, expr);
1511 r = coro_build_cvt_void_expr_stmt (r, loc);
1512 append_to_statement_list_force (r, &stmt_list);
1513 /* We have an initializer, which might itself contain await exprs. */
1514 await_init = tsi_stmt_ptr (tsi_last (stmt_list));
1515 }
1516
1517 /* Use the await_ready() call to test if we need to suspend. */
1518 tree ready_cond = TREE_VEC_ELT (awaiter_calls, 0); /* await_ready(). */
1519 ready_cond = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, ready_cond);
1520 ready_cond
1521 = build1_loc (loc, CLEANUP_POINT_EXPR, boolean_type_node, ready_cond);
1522
1523 tree body_list = NULL;
1524 tree susp_idx = build_int_cst (short_unsigned_type_node, data->index);
1525 r = build2_loc (loc, MODIFY_EXPR, short_unsigned_type_node, data->resume_idx,
1526 susp_idx);
1527 r = coro_build_cvt_void_expr_stmt (r, loc);
1528 append_to_statement_list (r, &body_list);
1529
1530 /* Find out what we have to do with the awaiter's suspend method.
1531 [expr.await]
1532 (5.1) If the result of await-ready is false, the coroutine is considered
1533 suspended. Then:
1534 (5.1.1) If the type of await-suspend is std::coroutine_handle<Z>,
1535 await-suspend.resume() is evaluated.
1536 (5.1.2) if the type of await-suspend is bool, await-suspend is evaluated,
1537 and the coroutine is resumed if the result is false.
1538 (5.1.3) Otherwise, await-suspend is evaluated. */
1539
1540 tree suspend = TREE_VEC_ELT (awaiter_calls, 1); /* await_suspend(). */
1541 tree susp_type = TREE_TYPE (suspend);
1542
1543 bool is_cont = false;
1544 /* NOTE: final suspend can't resume; the "resume" label in that case
1545 corresponds to implicit destruction. */
1546 if (VOID_TYPE_P (susp_type))
1547 {
1548 /* We just call await_suspend() and hit the yield. */
1549 suspend = coro_build_cvt_void_expr_stmt (suspend, loc);
1550 append_to_statement_list (suspend, &body_list);
1551 }
1552 else if (TREE_CODE (susp_type) == BOOLEAN_TYPE)
1553 {
1554 /* Boolean return, continue if the call returns false. */
1555 suspend = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, suspend);
1556 suspend
1557 = build1_loc (loc, CLEANUP_POINT_EXPR, boolean_type_node, suspend);
1558 tree go_on = build1_loc (loc, GOTO_EXPR, void_type_node, resume_label);
1559 r = build3_loc (loc, COND_EXPR, void_type_node, suspend, go_on,
1560 empty_list);
1561 append_to_statement_list (r, &body_list);
1562 }
1563 else
1564 {
1565 r = build1_loc (loc, CONVERT_EXPR, void_coro_handle_type, suspend);
1566 r = build2_loc (loc, INIT_EXPR, void_coro_handle_type, data->conthand, r);
1567 r = build1 (CONVERT_EXPR, void_type_node, r);
1568 append_to_statement_list (r, &body_list);
1569 is_cont = true;
1570 }
1571
1572 tree d_l = build_address (destroy_label);
1573 tree r_l = build_address (resume_label);
1574 tree susp = build_address (data->cororet);
1575 tree cont = build_address (data->corocont);
1576 tree final_susp = build_int_cst (integer_type_node, is_final ? 1 : 0);
1577
1578 susp_idx = build_int_cst (integer_type_node, data->index);
1579
1580 tree sw = begin_switch_stmt ();
1581 tree cond = build_decl (loc, VAR_DECL, NULL_TREE, integer_type_node);
1582 DECL_ARTIFICIAL (cond) = 1;
1583 DECL_IGNORED_P (cond) = 1;
1584 layout_decl (cond, 0);
1585
1586 r = build_call_expr_internal_loc (loc, IFN_CO_YIELD, integer_type_node, 5,
1587 susp_idx, final_susp, r_l, d_l,
1588 data->coro_fp);
1589 r = build2 (INIT_EXPR, integer_type_node, cond, r);
1590 finish_switch_cond (r, sw);
1591 r = build_case_label (build_int_cst (integer_type_node, 0), NULL_TREE,
1592 create_anon_label_with_ctx (loc, actor));
1593 add_stmt (r); /* case 0: */
1594 /* Implement the suspend, a scope exit without clean ups. */
1595 r = build_call_expr_internal_loc (loc, IFN_CO_SUSPN, void_type_node, 1,
1596 is_cont ? cont : susp);
1597 r = coro_build_cvt_void_expr_stmt (r, loc);
1598 add_stmt (r); /* goto ret; */
1599 r = build_case_label (build_int_cst (integer_type_node, 1), NULL_TREE,
1600 create_anon_label_with_ctx (loc, actor));
1601 add_stmt (r); /* case 1: */
1602 r = build1_loc (loc, GOTO_EXPR, void_type_node, resume_label);
1603 add_stmt (r); /* goto resume; */
1604 r = build_case_label (NULL_TREE, NULL_TREE,
1605 create_anon_label_with_ctx (loc, actor));
1606 add_stmt (r); /* default:; */
1607 r = build1_loc (loc, GOTO_EXPR, void_type_node, destroy_label);
1608 add_stmt (r); /* goto destroy; */
1609
1610 /* part of finish switch. */
1611 SWITCH_STMT_BODY (sw) = pop_stmt_list (SWITCH_STMT_BODY (sw));
1612 pop_switch ();
1613 tree scope = SWITCH_STMT_SCOPE (sw);
1614 SWITCH_STMT_SCOPE (sw) = NULL;
1615 r = do_poplevel (scope);
1616 append_to_statement_list (r, &body_list);
1617
1618 destroy_label = build_stmt (loc, LABEL_EXPR, destroy_label);
1619 append_to_statement_list (destroy_label, &body_list);
1620 if (needs_dtor)
1621 append_to_statement_list (dtor, &body_list);
1622 r = build1_loc (loc, GOTO_EXPR, void_type_node, data->cleanup);
1623 append_to_statement_list (r, &body_list);
1624
1625 r = build3_loc (loc, COND_EXPR, void_type_node, ready_cond, body_list,
1626 empty_list);
1627
1628 append_to_statement_list (r, &stmt_list);
1629
1630 /* Resume point. */
1631 resume_label = build_stmt (loc, LABEL_EXPR, resume_label);
1632 append_to_statement_list (resume_label, &stmt_list);
1633
1634 if (is_initial)
1635 {
1636 /* Note that we are about to execute the await_resume() for the initial
1637 await expression. */
1638 r = build2_loc (loc, MODIFY_EXPR, boolean_type_node, data->i_a_r_c,
1639 boolean_true_node);
1640 r = coro_build_cvt_void_expr_stmt (r, loc);
1641 append_to_statement_list (r, &stmt_list);
1642 }
1643
1644 /* This will produce the value (if one is provided) from the co_await
1645 expression. */
1646 tree resume_call = TREE_VEC_ELT (awaiter_calls, 2); /* await_resume(). */
1647 if (REFERENCE_REF_P (resume_call))
1648 /* Sink to await_resume call_expr. */
1649 resume_call = TREE_OPERAND (resume_call, 0);
1650
1651 *await_expr = resume_call; /* Replace the co_await expr with its result. */
1652 append_to_statement_list_force (saved_statement, &stmt_list);
1653 /* Get a pointer to the revised statment. */
1654 tree *revised = tsi_stmt_ptr (tsi_last (stmt_list));
1655 if (needs_dtor)
1656 append_to_statement_list (dtor, &stmt_list);
1657 data->index += 2;
1658
1659 /* Replace the original statement with the expansion. */
1660 *stmt = stmt_list;
1661
1662 /* Now, if the awaitable had an initializer, expand any awaits that might
1663 be embedded in it. */
1664 tree *aw_expr_ptr;
1665 if (await_init &&
1666 cp_walk_tree (await_init, co_await_find_in_subtree, &aw_expr_ptr, NULL))
1667 expand_one_await_expression (await_init, aw_expr_ptr, d);
1668
1669 /* Expand any more await expressions in the the original statement. */
1670 if (cp_walk_tree (revised, co_await_find_in_subtree, &aw_expr_ptr, NULL))
1671 expand_one_await_expression (revised, aw_expr_ptr, d);
1672
1673 return NULL;
1674 }
1675
1676 /* Check to see if a statement contains at least one await expression, if
1677 so, then process that. */
1678
1679 static tree
1680 process_one_statement (tree *stmt, void *d)
1681 {
1682 tree *aw_expr_ptr;
1683 if (cp_walk_tree (stmt, co_await_find_in_subtree, &aw_expr_ptr, NULL))
1684 expand_one_await_expression (stmt, aw_expr_ptr, d);
1685 return NULL_TREE;
1686 }
1687
1688 static tree
1689 await_statement_expander (tree *stmt, int *do_subtree, void *d)
1690 {
1691 tree res = NULL_TREE;
1692
1693 /* Process a statement at a time. */
1694 if (STATEMENT_CLASS_P (*stmt) || TREE_CODE (*stmt) == BIND_EXPR)
1695 return NULL_TREE; /* Just process the sub-trees. */
1696 else if (TREE_CODE (*stmt) == STATEMENT_LIST)
1697 {
1698 tree_stmt_iterator i;
1699 for (i = tsi_start (*stmt); !tsi_end_p (i); tsi_next (&i))
1700 {
1701 res = cp_walk_tree (tsi_stmt_ptr (i), await_statement_expander,
1702 d, NULL);
1703 if (res)
1704 return res;
1705 }
1706 *do_subtree = 0; /* Done subtrees. */
1707 }
1708 else if (EXPR_P (*stmt))
1709 {
1710 process_one_statement (stmt, d);
1711 *do_subtree = 0; /* Done subtrees. */
1712 }
1713
1714 /* Continue statement walk, where required. */
1715 return res;
1716 }
1717
1718 /* Suspend point hash_map. */
1719
1720 struct suspend_point_info
1721 {
1722 /* coro frame field type. */
1723 tree awaitable_type;
1724 /* coro frame field name. */
1725 tree await_field_id;
1726 };
1727
1728 static hash_map<tree, suspend_point_info> *suspend_points;
1729
1730 struct await_xform_data
1731 {
1732 tree actor_fn; /* Decl for context. */
1733 tree actor_frame;
1734 tree promise_proxy;
1735 tree real_promise;
1736 tree self_h_proxy;
1737 tree real_self_h;
1738 };
1739
1740 /* When we built the await expressions, we didn't know the coro frame
1741 layout, therefore no idea where to find the promise or where to put
1742 the awaitables. Now we know these things, fill them in. */
1743
1744 static tree
1745 transform_await_expr (tree await_expr, await_xform_data *xform)
1746 {
1747 suspend_point_info *si = suspend_points->get (await_expr);
1748 location_t loc = EXPR_LOCATION (await_expr);
1749 if (!si)
1750 {
1751 error_at (loc, "no suspend point info for %qD", await_expr);
1752 return error_mark_node;
1753 }
1754
1755 /* So, on entry, we have:
1756 in : CO_AWAIT_EXPR (a, e_proxy, o, awr_call_vector, mode)
1757 We no longer need a [it had diagnostic value, maybe?]
1758 We need to replace the promise proxy in all elements
1759 We need to replace the e_proxy in the awr_call. */
1760
1761 tree coro_frame_type = TREE_TYPE (xform->actor_frame);
1762
1763 /* If we have a frame var for the awaitable, get a reference to it. */
1764 proxy_replace data;
1765 if (si->await_field_id)
1766 {
1767 tree as_m
1768 = lookup_member (coro_frame_type, si->await_field_id,
1769 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
1770 tree as = build_class_member_access_expr (xform->actor_frame, as_m,
1771 NULL_TREE, true,
1772 tf_warning_or_error);
1773
1774 /* Replace references to the instance proxy with the frame entry now
1775 computed. */
1776 data.from = TREE_OPERAND (await_expr, 1);
1777 data.to = as;
1778 cp_walk_tree (&await_expr, replace_proxy, &data, NULL);
1779
1780 /* .. and replace. */
1781 TREE_OPERAND (await_expr, 1) = as;
1782 }
1783
1784 /* Now do the self_handle. */
1785 data.from = xform->self_h_proxy;
1786 data.to = xform->real_self_h;
1787 cp_walk_tree (&await_expr, replace_proxy, &data, NULL);
1788
1789 /* Now do the promise. */
1790 data.from = xform->promise_proxy;
1791 data.to = xform->real_promise;
1792 cp_walk_tree (&await_expr, replace_proxy, &data, NULL);
1793
1794 return await_expr;
1795 }
1796
1797 /* A wrapper for the transform_await_expr function so that it can be a
1798 callback from cp_walk_tree. */
1799
1800 static tree
1801 transform_await_wrapper (tree *stmt, int *do_subtree, void *d)
1802 {
1803 /* Set actor function as new DECL_CONTEXT of label_decl. */
1804 struct await_xform_data *xform = (struct await_xform_data *) d;
1805 if (TREE_CODE (*stmt) == LABEL_DECL
1806 && DECL_CONTEXT (*stmt) != xform->actor_fn)
1807 DECL_CONTEXT (*stmt) = xform->actor_fn;
1808
1809 /* We should have already lowered co_yields to their co_await. */
1810 gcc_checking_assert (TREE_CODE (*stmt) != CO_YIELD_EXPR);
1811 if (TREE_CODE (*stmt) != CO_AWAIT_EXPR)
1812 return NULL_TREE;
1813
1814 tree await_expr = *stmt;
1815 *stmt = transform_await_expr (await_expr, xform);
1816 if (*stmt == error_mark_node)
1817 *do_subtree = 0;
1818 return NULL_TREE;
1819 }
1820
1821 /* This caches information that we determine about function params,
1822 their uses and copies in the coroutine frame. */
1823
1824 struct param_info
1825 {
1826 tree field_id; /* The name of the copy in the coroutine frame. */
1827 vec<tree *> *body_uses; /* Worklist of uses, void if there are none. */
1828 tree frame_type; /* The type used to represent this parm in the frame. */
1829 tree orig_type; /* The original type of the parm (not as passed). */
1830 bool by_ref; /* Was passed by reference. */
1831 bool pt_ref; /* Was a pointer to object. */
1832 bool trivial_dtor; /* The frame type has a trivial DTOR. */
1833 bool this_ptr; /* Is 'this' */
1834 bool lambda_cobj; /* Lambda capture object */
1835 };
1836
1837 struct local_var_info
1838 {
1839 tree field_id;
1840 tree field_idx;
1841 tree frame_type;
1842 bool is_lambda_capture;
1843 bool is_static;
1844 bool has_value_expr_p;
1845 location_t def_loc;
1846 };
1847
1848 /* For figuring out what local variable usage we have. */
1849 struct local_vars_transform
1850 {
1851 tree context;
1852 tree actor_frame;
1853 tree coro_frame_type;
1854 location_t loc;
1855 hash_map<tree, local_var_info> *local_var_uses;
1856 };
1857
1858 static tree
1859 transform_local_var_uses (tree *stmt, int *do_subtree, void *d)
1860 {
1861 local_vars_transform *lvd = (local_vars_transform *) d;
1862
1863 /* For each var in this bind expr (that has a frame id, which means it was
1864 accessed), build a frame reference for each and then walk the bind expr
1865 statements, substituting the frame ref for the original var. */
1866
1867 if (TREE_CODE (*stmt) == BIND_EXPR)
1868 {
1869 tree lvar;
1870 for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
1871 lvar = DECL_CHAIN (lvar))
1872 {
1873 bool existed;
1874 local_var_info &local_var
1875 = lvd->local_var_uses->get_or_insert (lvar, &existed);
1876 gcc_checking_assert (existed);
1877
1878 /* Re-write the variable's context to be in the actor func. */
1879 DECL_CONTEXT (lvar) = lvd->context;
1880
1881 /* For capture proxies, this could include the decl value expr. */
1882 if (local_var.is_lambda_capture || local_var.has_value_expr_p)
1883 {
1884 tree ve = DECL_VALUE_EXPR (lvar);
1885 cp_walk_tree (&ve, transform_local_var_uses, d, NULL);
1886 continue; /* No frame entry for this. */
1887 }
1888
1889 /* TODO: implement selective generation of fields when vars are
1890 known not-used. */
1891 if (local_var.field_id == NULL_TREE)
1892 continue; /* Wasn't used. */
1893
1894 tree fld_ref
1895 = lookup_member (lvd->coro_frame_type, local_var.field_id,
1896 /*protect=*/1, /*want_type=*/0,
1897 tf_warning_or_error);
1898 tree fld_idx = build3_loc (lvd->loc, COMPONENT_REF, TREE_TYPE (lvar),
1899 lvd->actor_frame, fld_ref, NULL_TREE);
1900 local_var.field_idx = fld_idx;
1901 }
1902 /* FIXME: we should be able to do this in the loop above, but (at least
1903 for range for) there are cases where the DECL_INITIAL contains
1904 forward references.
1905 So, now we've built the revised var in the frame, substitute uses of
1906 it in initializers and the bind expr body. */
1907 for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
1908 lvar = DECL_CHAIN (lvar))
1909 {
1910 /* we need to walk some of the decl trees, which might contain
1911 references to vars replaced at a higher level. */
1912 cp_walk_tree (&DECL_INITIAL (lvar), transform_local_var_uses, d,
1913 NULL);
1914 cp_walk_tree (&DECL_SIZE (lvar), transform_local_var_uses, d, NULL);
1915 cp_walk_tree (&DECL_SIZE_UNIT (lvar), transform_local_var_uses, d,
1916 NULL);
1917 }
1918 cp_walk_tree (&BIND_EXPR_BODY (*stmt), transform_local_var_uses, d, NULL);
1919
1920 /* Now we have processed and removed references to the original vars,
1921 we can drop those from the bind - leaving capture proxies alone. */
1922 for (tree *pvar = &BIND_EXPR_VARS (*stmt); *pvar != NULL;)
1923 {
1924 bool existed;
1925 local_var_info &local_var
1926 = lvd->local_var_uses->get_or_insert (*pvar, &existed);
1927 gcc_checking_assert (existed);
1928
1929 /* Leave lambda closure captures alone, we replace the *this
1930 pointer with the frame version and let the normal process
1931 deal with the rest.
1932 Likewise, variables with their value found elsewhere.
1933 Skip past unused ones too. */
1934 if (local_var.is_lambda_capture
1935 || local_var.has_value_expr_p
1936 || local_var.field_id == NULL_TREE)
1937 {
1938 pvar = &DECL_CHAIN (*pvar);
1939 continue;
1940 }
1941
1942 /* Discard this one, we replaced it. */
1943 *pvar = DECL_CHAIN (*pvar);
1944 }
1945
1946 *do_subtree = 0; /* We've done the body already. */
1947 return NULL_TREE;
1948 }
1949
1950 tree var_decl = *stmt;
1951 /* Look inside cleanups, we don't want to wrap a statement list in a
1952 cleanup. */
1953 bool needs_cleanup = true;
1954 if (TREE_CODE (var_decl) == CLEANUP_POINT_EXPR)
1955 var_decl = TREE_OPERAND (var_decl, 0);
1956 else
1957 needs_cleanup = false;
1958
1959 /* Look inside the decl_expr for the actual var. */
1960 bool decl_expr_p = TREE_CODE (var_decl) == DECL_EXPR;
1961 if (decl_expr_p && TREE_CODE (DECL_EXPR_DECL (var_decl)) == VAR_DECL)
1962 var_decl = DECL_EXPR_DECL (var_decl);
1963 else if (TREE_CODE (var_decl) != VAR_DECL)
1964 return NULL_TREE;
1965
1966 /* VAR_DECLs that are not recorded can belong to the proxies we've placed
1967 for the promise and coroutine handle(s), to global vars or to compiler
1968 temporaries. Skip past these, we will handle them later. */
1969 local_var_info *local_var_i = lvd->local_var_uses->get (var_decl);
1970
1971 if (local_var_i == NULL)
1972 return NULL_TREE;
1973
1974 if (local_var_i->is_lambda_capture
1975 || local_var_i->is_static
1976 || local_var_i->has_value_expr_p)
1977 return NULL_TREE;
1978
1979 /* This is our revised 'local' i.e. a frame slot. */
1980 tree revised = local_var_i->field_idx;
1981 gcc_checking_assert (DECL_CONTEXT (var_decl) == lvd->context);
1982
1983 if (decl_expr_p && DECL_INITIAL (var_decl))
1984 {
1985 location_t loc = DECL_SOURCE_LOCATION (var_decl);
1986 tree r
1987 = cp_build_modify_expr (loc, revised, INIT_EXPR,
1988 DECL_INITIAL (var_decl), tf_warning_or_error);
1989 if (needs_cleanup)
1990 r = coro_build_cvt_void_expr_stmt (r, EXPR_LOCATION (*stmt));
1991 *stmt = r;
1992 }
1993 else
1994 *stmt = revised;
1995
1996 if (decl_expr_p)
1997 *do_subtree = 0; /* We've accounted for the nested use. */
1998 return NULL_TREE;
1999 }
2000
2001 /* The actor transform. */
2002
2003 static void
2004 build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
2005 tree orig, hash_map<tree, param_info> *param_uses,
2006 hash_map<tree, local_var_info> *local_var_uses,
2007 vec<tree, va_gc> *param_dtor_list, tree initial_await,
2008 tree final_await, unsigned body_count, tree frame_size)
2009 {
2010 verify_stmt_tree (fnbody);
2011 /* Some things we inherit from the original function. */
2012 tree coro_frame_ptr = build_pointer_type (coro_frame_type);
2013 tree handle_type = get_coroutine_handle_type (orig);
2014 tree self_h_proxy = get_coroutine_self_handle_proxy (orig);
2015 tree promise_type = get_coroutine_promise_type (orig);
2016 tree promise_proxy = get_coroutine_promise_proxy (orig);
2017 tree act_des_fn_type
2018 = build_function_type_list (void_type_node, coro_frame_ptr, NULL_TREE);
2019 tree act_des_fn_ptr = build_pointer_type (act_des_fn_type);
2020
2021 /* One param, the coro frame pointer. */
2022 tree actor_fp = DECL_ARGUMENTS (actor);
2023
2024 /* A void return. */
2025 tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
2026 DECL_ARTIFICIAL (resdecl) = 1;
2027 DECL_IGNORED_P (resdecl) = 1;
2028 DECL_RESULT (actor) = resdecl;
2029 DECL_COROUTINE_P (actor) = 1;
2030
2031 /* We have a definition here. */
2032 TREE_STATIC (actor) = 1;
2033
2034 tree actor_outer = push_stmt_list ();
2035 current_stmt_tree ()->stmts_are_full_exprs_p = 1;
2036 tree stmt = begin_compound_stmt (BCS_FN_BODY);
2037
2038 tree actor_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
2039 tree top_block = make_node (BLOCK);
2040 BIND_EXPR_BLOCK (actor_bind) = top_block;
2041
2042 tree continuation = build_lang_decl (VAR_DECL,
2043 get_identifier ("actor.continue"),
2044 void_coro_handle_type);
2045 DECL_ARTIFICIAL (continuation) = 1;
2046 DECL_IGNORED_P (continuation) = 1;
2047 DECL_CONTEXT (continuation) = actor;
2048 BIND_EXPR_VARS (actor_bind) = continuation;
2049
2050 /* Update the block associated with the outer scope of the orig fn. */
2051 tree first = expr_first (fnbody);
2052 if (first && TREE_CODE (first) == BIND_EXPR)
2053 {
2054 /* We will discard this, since it's connected to the original scope
2055 nest. */
2056 tree block = BIND_EXPR_BLOCK (first);
2057 if (block) /* For this to be missing is probably a bug. */
2058 {
2059 gcc_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
2060 gcc_assert (BLOCK_CHAIN (block) == NULL_TREE);
2061 BLOCK_SUPERCONTEXT (block) = top_block;
2062 BLOCK_SUBBLOCKS (top_block) = block;
2063 }
2064 }
2065
2066 add_stmt (actor_bind);
2067 tree actor_body = push_stmt_list ();
2068
2069 /* The entry point for the actor code from the ramp. */
2070 tree actor_begin_label
2071 = create_named_label_with_ctx (loc, "actor.begin", actor);
2072 tree actor_frame = build1_loc (loc, INDIRECT_REF, coro_frame_type, actor_fp);
2073
2074 /* Declare the continuation handle. */
2075 add_decl_expr (continuation);
2076
2077 /* Re-write param references in the body, no code should be generated
2078 here. */
2079 if (DECL_ARGUMENTS (orig))
2080 {
2081 tree arg;
2082 for (arg = DECL_ARGUMENTS (orig); arg != NULL; arg = DECL_CHAIN (arg))
2083 {
2084 bool existed;
2085 param_info &parm = param_uses->get_or_insert (arg, &existed);
2086 if (!parm.body_uses)
2087 continue; /* Wasn't used in the orignal function body. */
2088
2089 tree fld_ref = lookup_member (coro_frame_type, parm.field_id,
2090 /*protect=*/1, /*want_type=*/0,
2091 tf_warning_or_error);
2092 tree fld_idx = build3_loc (loc, COMPONENT_REF, parm.frame_type,
2093 actor_frame, fld_ref, NULL_TREE);
2094
2095 /* We keep these in the frame as a regular pointer, so convert that
2096 back to the type expected. */
2097 if (parm.pt_ref)
2098 fld_idx = build1_loc (loc, CONVERT_EXPR, TREE_TYPE (arg), fld_idx);
2099
2100 int i;
2101 tree *puse;
2102 FOR_EACH_VEC_ELT (*parm.body_uses, i, puse)
2103 *puse = fld_idx;
2104 }
2105 }
2106
2107 /* Re-write local vars, similarly. */
2108 local_vars_transform xform_vars_data
2109 = {actor, actor_frame, coro_frame_type, loc, local_var_uses};
2110 cp_walk_tree (&fnbody, transform_local_var_uses, &xform_vars_data, NULL);
2111
2112 tree resume_idx_name = get_identifier ("__resume_at");
2113 tree rat_field = lookup_member (coro_frame_type, resume_idx_name, 1, 0,
2114 tf_warning_or_error);
2115 tree rat = build3 (COMPONENT_REF, short_unsigned_type_node, actor_frame,
2116 rat_field, NULL_TREE);
2117
2118 tree ret_label
2119 = create_named_label_with_ctx (loc, "actor.suspend.ret", actor);
2120
2121 tree continue_label
2122 = create_named_label_with_ctx (loc, "actor.continue.ret", actor);
2123
2124 tree lsb_if = begin_if_stmt ();
2125 tree chkb0 = build2 (BIT_AND_EXPR, short_unsigned_type_node, rat,
2126 build_int_cst (short_unsigned_type_node, 1));
2127 chkb0 = build2 (NE_EXPR, short_unsigned_type_node, chkb0,
2128 build_int_cst (short_unsigned_type_node, 0));
2129 finish_if_stmt_cond (chkb0, lsb_if);
2130
2131 tree destroy_dispatcher = begin_switch_stmt ();
2132 finish_switch_cond (rat, destroy_dispatcher);
2133 tree ddeflab = build_case_label (NULL_TREE, NULL_TREE,
2134 create_anon_label_with_ctx (loc, actor));
2135 add_stmt (ddeflab);
2136 tree b = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
2137 b = coro_build_cvt_void_expr_stmt (b, loc);
2138 add_stmt (b);
2139
2140 short unsigned lab_num = 3;
2141 for (unsigned destr_pt = 0; destr_pt < body_count + 2; destr_pt++)
2142 {
2143 tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
2144 b = build_case_label (l_num, NULL_TREE,
2145 create_anon_label_with_ctx (loc, actor));
2146 add_stmt (b);
2147 b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
2148 l_num);
2149 b = coro_build_cvt_void_expr_stmt (b, loc);
2150 add_stmt (b);
2151 b = build1 (GOTO_EXPR, void_type_node, CASE_LABEL (ddeflab));
2152 add_stmt (b);
2153 lab_num += 2;
2154 }
2155
2156 /* Insert the prototype dispatcher. */
2157 finish_switch_stmt (destroy_dispatcher);
2158
2159 finish_then_clause (lsb_if);
2160
2161 tree dispatcher = begin_switch_stmt ();
2162 finish_switch_cond (rat, dispatcher);
2163 b = build_case_label (build_int_cst (short_unsigned_type_node, 0), NULL_TREE,
2164 create_anon_label_with_ctx (loc, actor));
2165 add_stmt (b);
2166 b = build1 (GOTO_EXPR, void_type_node, actor_begin_label);
2167 add_stmt (b);
2168
2169 tree rdeflab = build_case_label (NULL_TREE, NULL_TREE,
2170 create_anon_label_with_ctx (loc, actor));
2171 add_stmt (rdeflab);
2172 b = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
2173 b = coro_build_cvt_void_expr_stmt (b, loc);
2174 add_stmt (b);
2175
2176 lab_num = 2;
2177 /* The final resume should be made to hit the default (trap, UB) entry. */
2178 for (unsigned resu_pt = 0; resu_pt < body_count + 1; resu_pt++)
2179 {
2180 tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
2181 b = build_case_label (l_num, NULL_TREE,
2182 create_anon_label_with_ctx (loc, actor));
2183 add_stmt (b);
2184 b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
2185 l_num);
2186 b = coro_build_cvt_void_expr_stmt (b, loc);
2187 add_stmt (b);
2188 b = build1 (GOTO_EXPR, void_type_node, CASE_LABEL (rdeflab));
2189 add_stmt (b);
2190 lab_num += 2;
2191 }
2192
2193 /* Insert the prototype dispatcher. */
2194 finish_switch_stmt (dispatcher);
2195
2196 finish_if_stmt (lsb_if);
2197
2198 tree r = build_stmt (loc, LABEL_EXPR, actor_begin_label);
2199 add_stmt (r);
2200
2201 /* actor's version of the promise. */
2202 tree ap_m = lookup_member (coro_frame_type, get_identifier ("__p"), 1, 0,
2203 tf_warning_or_error);
2204 tree ap = build_class_member_access_expr (actor_frame, ap_m, NULL_TREE, false,
2205 tf_warning_or_error);
2206
2207 /* actor's coroutine 'self handle'. */
2208 tree ash_m = lookup_member (coro_frame_type, get_identifier ("__self_h"), 1,
2209 0, tf_warning_or_error);
2210 tree ash = build_class_member_access_expr (actor_frame, ash_m, NULL_TREE,
2211 false, tf_warning_or_error);
2212 /* So construct the self-handle from the frame address. */
2213 tree hfa_m = lookup_member (handle_type, coro_from_address_identifier, 1,
2214 0, tf_warning_or_error);
2215
2216 r = build1 (CONVERT_EXPR, build_pointer_type (void_type_node), actor_fp);
2217 vec<tree, va_gc> *args = make_tree_vector_single (r);
2218 tree hfa = build_new_method_call (ash, hfa_m, &args, NULL_TREE, LOOKUP_NORMAL,
2219 NULL, tf_warning_or_error);
2220 r = build2 (INIT_EXPR, handle_type, ash, hfa);
2221 r = coro_build_cvt_void_expr_stmt (r, loc);
2222 add_stmt (r);
2223 release_tree_vector (args);
2224
2225 /* Now we know the real promise, and enough about the frame layout to
2226 decide where to put things. */
2227
2228 await_xform_data xform
2229 = {actor, actor_frame, promise_proxy, ap, self_h_proxy, ash};
2230
2231 /* Get a reference to the initial suspend var in the frame. */
2232 transform_await_expr (initial_await, &xform);
2233 tree initial_await_stmt = coro_build_expr_stmt (initial_await, loc);
2234
2235 /* co_return branches to the final_suspend label, so declare that now. */
2236 tree fs_label = create_named_label_with_ctx (loc, "final.suspend", actor);
2237
2238 /* Expand co_returns in the saved function body */
2239 fnbody = expand_co_returns (&fnbody, promise_proxy, ap, fs_label);
2240
2241 /* Specific behaviour to treat exceptions thrown by the await_resume ()
2242 of the initial suspend expression. In order to implement this, we
2243 need to treat the initial_suspend expression as if it were part of the
2244 user-authored function body. This only applies if exceptions are
2245 enabled. */
2246 if (flag_exceptions)
2247 {
2248 tree outer = fnbody;
2249 if (TREE_CODE (outer) == BIND_EXPR)
2250 outer = BIND_EXPR_BODY (outer);
2251 gcc_checking_assert (TREE_CODE (outer) == TRY_BLOCK);
2252 tree sl = TRY_STMTS (outer);
2253 if (TREE_CODE (sl) == STATEMENT_LIST)
2254 {
2255 tree_stmt_iterator si = tsi_start (sl);
2256 tsi_link_before (&si, initial_await_stmt, TSI_NEW_STMT);
2257 }
2258 else
2259 {
2260 tree new_try = NULL_TREE;
2261 append_to_statement_list (initial_await_stmt, &new_try);
2262 append_to_statement_list (sl, &new_try);
2263 TRY_STMTS (outer) = new_try;
2264 }
2265 }
2266 else
2267 add_stmt (initial_await_stmt);
2268
2269 /* Transform the await expressions in the function body. Only do each
2270 await tree once! */
2271 hash_set<tree> pset;
2272 cp_walk_tree (&fnbody, transform_await_wrapper, &xform, &pset);
2273
2274 /* Add in our function body with the co_returns rewritten to final form. */
2275 add_stmt (fnbody);
2276
2277 /* Final suspend starts here. */
2278 r = build_stmt (loc, LABEL_EXPR, fs_label);
2279 add_stmt (r);
2280
2281 /* Set the actor pointer to null, so that 'done' will work.
2282 Resume from here is UB anyway - although a 'ready' await will
2283 branch to the final resume, and fall through to the destroy. */
2284 tree resume_m
2285 = lookup_member (coro_frame_type, get_identifier ("__resume"),
2286 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
2287 tree res_x = build_class_member_access_expr (actor_frame, resume_m, NULL_TREE,
2288 false, tf_warning_or_error);
2289 r = build1 (CONVERT_EXPR, act_des_fn_ptr, integer_zero_node);
2290 r = build2 (INIT_EXPR, act_des_fn_ptr, res_x, r);
2291 r = coro_build_cvt_void_expr_stmt (r, loc);
2292 add_stmt (r);
2293
2294 /* Get a reference to the final suspend var in the frame. */
2295 transform_await_expr (final_await, &xform);
2296 r = coro_build_expr_stmt (final_await, loc);
2297 add_stmt (r);
2298
2299 /* now do the tail of the function. */
2300 tree del_promise_label
2301 = create_named_label_with_ctx (loc, "coro.delete.promise", actor);
2302 r = build_stmt (loc, LABEL_EXPR, del_promise_label);
2303 add_stmt (r);
2304
2305 /* Destructors for the things we built explicitly. */
2306 r = build_special_member_call (ap, complete_dtor_identifier, NULL,
2307 promise_type, LOOKUP_NORMAL,
2308 tf_warning_or_error);
2309 add_stmt (r);
2310
2311 tree del_frame_label
2312 = create_named_label_with_ctx (loc, "coro.delete.frame", actor);
2313 r = build_stmt (loc, LABEL_EXPR, del_frame_label);
2314 add_stmt (r);
2315
2316 /* Here deallocate the frame (if we allocated it), which we will have at
2317 present. */
2318 tree fnf_m
2319 = lookup_member (coro_frame_type, get_identifier ("__frame_needs_free"), 1,
2320 0, tf_warning_or_error);
2321 tree fnf2_x = build_class_member_access_expr (actor_frame, fnf_m, NULL_TREE,
2322 false, tf_warning_or_error);
2323
2324 tree need_free_if = begin_if_stmt ();
2325 fnf2_x = build1 (CONVERT_EXPR, integer_type_node, fnf2_x);
2326 tree cmp = build2 (NE_EXPR, integer_type_node, fnf2_x, integer_zero_node);
2327 finish_if_stmt_cond (cmp, need_free_if);
2328 if (param_dtor_list != NULL)
2329 {
2330 int i;
2331 tree pid;
2332 FOR_EACH_VEC_ELT (*param_dtor_list, i, pid)
2333 {
2334 tree m
2335 = lookup_member (coro_frame_type, pid, 1, 0, tf_warning_or_error);
2336 tree a = build_class_member_access_expr (actor_frame, m, NULL_TREE,
2337 false, tf_warning_or_error);
2338 tree t = TREE_TYPE (a);
2339 tree dtor;
2340 dtor
2341 = build_special_member_call (a, complete_dtor_identifier, NULL, t,
2342 LOOKUP_NORMAL, tf_warning_or_error);
2343 add_stmt (dtor);
2344 }
2345 }
2346
2347 /* [dcl.fct.def.coroutine] / 12
2348 The deallocation function’s name is looked up in the scope of the promise
2349 type. If this lookup fails, the deallocation function’s name is looked up
2350 in the global scope. If deallocation function lookup finds both a usual
2351 deallocation function with only a pointer parameter and a usual
2352 deallocation function with both a pointer parameter and a size parameter,
2353 then the selected deallocation function shall be the one with two
2354 parameters. Otherwise, the selected deallocation function shall be the
2355 function with one parameter. If no usual deallocation function is found
2356 the program is ill-formed. The selected deallocation function shall be
2357 called with the address of the block of storage to be reclaimed as its
2358 first argument. If a deallocation function with a parameter of type
2359 std::size_t is used, the size of the block is passed as the corresponding
2360 argument. */
2361
2362 tree del_coro_fr = NULL_TREE;
2363 tree frame_arg = build1 (CONVERT_EXPR, ptr_type_node, actor_fp);
2364
2365 tree delname = ovl_op_identifier (false, DELETE_EXPR);
2366 tree fns = lookup_promise_method (orig, delname, loc, /*musthave=*/false);
2367 if (fns && BASELINK_P (fns))
2368 {
2369 /* Look for sized version first, since this takes precedence. */
2370 vec<tree, va_gc> *args = make_tree_vector ();
2371 vec_safe_push (args, frame_arg);
2372 vec_safe_push (args, frame_size);
2373 tree dummy_promise = build_dummy_object (promise_type);
2374
2375 /* It's OK to fail for this one... */
2376 del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
2377 NULL_TREE, LOOKUP_NORMAL, NULL,
2378 tf_none);
2379
2380 if (!del_coro_fr || del_coro_fr == error_mark_node)
2381 {
2382 release_tree_vector (args);
2383 args = make_tree_vector_single (frame_arg);
2384 del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
2385 NULL_TREE, LOOKUP_NORMAL, NULL,
2386 tf_none);
2387 }
2388
2389 /* But one of them must succeed, or the program is ill-formed. */
2390 if (!del_coro_fr || del_coro_fr == error_mark_node)
2391 {
2392 error_at (loc, "%qE is provided by %qT but is not usable with"
2393 " the function signature %qD", delname, promise_type, orig);
2394 del_coro_fr = error_mark_node;
2395 }
2396 }
2397 else
2398 {
2399 del_coro_fr = build_op_delete_call (DELETE_EXPR, frame_arg, frame_size,
2400 /*global_p=*/true, /*placement=*/NULL,
2401 /*alloc_fn=*/NULL,
2402 tf_warning_or_error);
2403 if (!del_coro_fr || del_coro_fr == error_mark_node)
2404 del_coro_fr = error_mark_node;
2405 }
2406
2407 del_coro_fr = coro_build_cvt_void_expr_stmt (del_coro_fr, loc);
2408 add_stmt (del_coro_fr);
2409 finish_then_clause (need_free_if);
2410 tree scope = IF_SCOPE (need_free_if);
2411 IF_SCOPE (need_free_if) = NULL;
2412 r = do_poplevel (scope);
2413 add_stmt (r);
2414
2415 /* done. */
2416 r = build_stmt (loc, RETURN_EXPR, NULL);
2417 TREE_NO_WARNING (r) |= 1; /* We don't want a warning about this. */
2418 r = maybe_cleanup_point_expr_void (r);
2419 add_stmt (r);
2420
2421 /* This is the suspend return point. */
2422 r = build_stmt (loc, LABEL_EXPR, ret_label);
2423 add_stmt (r);
2424
2425 r = build_stmt (loc, RETURN_EXPR, NULL);
2426 TREE_NO_WARNING (r) |= 1; /* We don't want a warning about this. */
2427 r = maybe_cleanup_point_expr_void (r);
2428 add_stmt (r);
2429
2430 /* This is the 'continuation' return point. For such a case we have a coro
2431 handle (from the await_suspend() call) and we want handle.resume() to
2432 execute as a tailcall allowing arbitrary chaining of coroutines. */
2433 r = build_stmt (loc, LABEL_EXPR, continue_label);
2434 add_stmt (r);
2435
2436 /* We want to force a tail-call even for O0/1, so this expands the resume
2437 call into its underlying implementation. */
2438 tree addr = lookup_member (void_coro_handle_type, coro_address_identifier,
2439 1, 0, tf_warning_or_error);
2440 addr = build_new_method_call (continuation, addr, NULL, NULL_TREE,
2441 LOOKUP_NORMAL, NULL, tf_warning_or_error);
2442 tree resume = build_call_expr_loc
2443 (loc, builtin_decl_explicit (BUILT_IN_CORO_RESUME), 1, addr);
2444
2445 /* In order to support an arbitrary number of coroutine continuations,
2446 we must tail call them. However, some targets do not support indirect
2447 tail calls to arbitrary callees. See PR94359. */
2448 CALL_EXPR_TAILCALL (resume) = true;
2449 resume = coro_build_cvt_void_expr_stmt (resume, loc);
2450 add_stmt (resume);
2451
2452 r = build_stmt (loc, RETURN_EXPR, NULL);
2453 gcc_checking_assert (maybe_cleanup_point_expr_void (r) == r);
2454 add_stmt (r);
2455
2456 /* We will need to know which resume point number should be encoded. */
2457 tree res_idx_m
2458 = lookup_member (coro_frame_type, resume_idx_name,
2459 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
2460 tree resume_pt_number
2461 = build_class_member_access_expr (actor_frame, res_idx_m, NULL_TREE, false,
2462 tf_warning_or_error);
2463
2464 /* Boolean value to flag that the initial suspend expression's
2465 await_resume () has been called, and therefore we are in the user's
2466 function body for the purposes of handing exceptions. */
2467 tree i_a_r_c_m
2468 = lookup_member (coro_frame_type, get_identifier ("__i_a_r_c"),
2469 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
2470 tree i_a_r_c
2471 = build_class_member_access_expr (actor_frame, i_a_r_c_m, NULL_TREE,
2472 false, tf_warning_or_error);
2473
2474 /* We've now rewritten the tree and added the initial and final
2475 co_awaits. Now pass over the tree and expand the co_awaits. */
2476
2477 coro_aw_data data = {actor, actor_fp, resume_pt_number, i_a_r_c,
2478 ash, del_promise_label, ret_label,
2479 continue_label, continuation, 2};
2480 cp_walk_tree (&actor_body, await_statement_expander, &data, NULL);
2481
2482 BIND_EXPR_BODY (actor_bind) = pop_stmt_list (actor_body);
2483 TREE_SIDE_EFFECTS (actor_bind) = true;
2484
2485 finish_compound_stmt (stmt);
2486 DECL_SAVED_TREE (actor) = pop_stmt_list (actor_outer);
2487 verify_stmt_tree (DECL_SAVED_TREE (actor));
2488 }
2489
2490 /* The prototype 'destroy' function :
2491 frame->__resume_at |= 1;
2492 actor (frame); */
2493
2494 static void
2495 build_destroy_fn (location_t loc, tree coro_frame_type, tree destroy,
2496 tree actor)
2497 {
2498 /* One param, the coro frame pointer. */
2499 tree destr_fp = DECL_ARGUMENTS (destroy);
2500
2501 /* A void return. */
2502 tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
2503 DECL_ARTIFICIAL (resdecl) = 1;
2504 DECL_IGNORED_P (resdecl) = 1;
2505 DECL_RESULT (destroy) = resdecl;
2506
2507 /* We have a definition here. */
2508 TREE_STATIC (destroy) = 1;
2509 DECL_COROUTINE_P (destroy) = 1;
2510
2511 tree destr_outer = push_stmt_list ();
2512 current_stmt_tree ()->stmts_are_full_exprs_p = 1;
2513 tree dstr_stmt = begin_compound_stmt (BCS_FN_BODY);
2514
2515 tree destr_frame = build1 (INDIRECT_REF, coro_frame_type, destr_fp);
2516
2517 tree resume_idx_name = get_identifier ("__resume_at");
2518 tree rat_field = lookup_member (coro_frame_type, resume_idx_name, 1, 0,
2519 tf_warning_or_error);
2520 tree rat = build3 (COMPONENT_REF, short_unsigned_type_node, destr_frame,
2521 rat_field, NULL_TREE);
2522
2523 /* _resume_at |= 1 */
2524 tree dstr_idx = build2 (BIT_IOR_EXPR, short_unsigned_type_node, rat,
2525 build_int_cst (short_unsigned_type_node, 1));
2526 tree r = build2 (MODIFY_EXPR, short_unsigned_type_node, rat, dstr_idx);
2527 r = coro_build_cvt_void_expr_stmt (r, loc);
2528 add_stmt (r);
2529
2530 /* So .. call the actor .. */
2531 r = build_call_expr_loc (loc, actor, 1, destr_fp);
2532 r = coro_build_cvt_void_expr_stmt (r, loc);
2533 add_stmt (r);
2534
2535 /* done. */
2536 r = build_stmt (loc, RETURN_EXPR, NULL);
2537 r = maybe_cleanup_point_expr_void (r);
2538 add_stmt (r);
2539
2540 finish_compound_stmt (dstr_stmt);
2541 DECL_SAVED_TREE (destroy) = pop_stmt_list (destr_outer);
2542 }
2543
2544 /* Helper that returns an identifier for an appended extension to the
2545 current un-mangled function name. */
2546
2547 static tree
2548 get_fn_local_identifier (tree orig, const char *append)
2549 {
2550 /* Figure out the bits we need to generate names for the outlined things
2551 For consistency, this needs to behave the same way as
2552 ASM_FORMAT_PRIVATE_NAME does. */
2553 tree nm = DECL_NAME (orig);
2554 const char *sep, *pfx = "";
2555 #ifndef NO_DOT_IN_LABEL
2556 sep = ".";
2557 #else
2558 #ifndef NO_DOLLAR_IN_LABEL
2559 sep = "$";
2560 #else
2561 sep = "_";
2562 pfx = "__";
2563 #endif
2564 #endif
2565
2566 char *an;
2567 if (DECL_ASSEMBLER_NAME (orig))
2568 an = ACONCAT ((IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (orig)), sep, append,
2569 (char *) 0));
2570 else if (DECL_USE_TEMPLATE (orig) && DECL_TEMPLATE_INFO (orig)
2571 && DECL_TI_ARGS (orig))
2572 {
2573 tree tpl_args = DECL_TI_ARGS (orig);
2574 an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), (char *) 0));
2575 for (int i = 0; i < TREE_VEC_LENGTH (tpl_args); ++i)
2576 {
2577 tree typ = DECL_NAME (TYPE_NAME (TREE_VEC_ELT (tpl_args, i)));
2578 an = ACONCAT ((an, sep, IDENTIFIER_POINTER (typ), (char *) 0));
2579 }
2580 an = ACONCAT ((an, sep, append, (char *) 0));
2581 }
2582 else
2583 an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), sep, append, (char *) 0));
2584
2585 return get_identifier (an);
2586 }
2587
2588 static tree
2589 build_init_or_final_await (location_t loc, bool is_final)
2590 {
2591 tree suspend_alt = is_final ? coro_final_suspend_identifier
2592 : coro_initial_suspend_identifier;
2593 tree setup_meth = lookup_promise_method (current_function_decl, suspend_alt,
2594 loc, /*musthave=*/true);
2595 if (!setup_meth || setup_meth == error_mark_node)
2596 return error_mark_node;
2597
2598 tree s_fn = NULL_TREE;
2599 tree setup_call = build_new_method_call (
2600 get_coroutine_promise_proxy (current_function_decl), setup_meth, NULL,
2601 NULL_TREE, LOOKUP_NORMAL, &s_fn, tf_warning_or_error);
2602
2603 if (!s_fn || setup_call == error_mark_node)
2604 return error_mark_node;
2605
2606 /* So build the co_await for this */
2607 /* For initial/final suspends the call is "a" per [expr.await] 3.2. */
2608 return build_co_await (loc, setup_call, (is_final ? FINAL_SUSPEND_POINT
2609 : INITIAL_SUSPEND_POINT));
2610 }
2611
2612 /* Callback to record the essential data for each await point found in the
2613 function. */
2614
2615 static bool
2616 register_await_info (tree await_expr, tree aw_type, tree aw_nam)
2617 {
2618 bool seen;
2619 suspend_point_info &s
2620 = suspend_points->get_or_insert (await_expr, &seen);
2621 if (seen)
2622 {
2623 error_at (EXPR_LOCATION (await_expr), "duplicate info for %qE",
2624 await_expr);
2625 return false;
2626 }
2627 s.awaitable_type = aw_type;
2628 s.await_field_id = aw_nam;
2629 return true;
2630 }
2631
2632 /* Small helper for the repetitive task of adding a new field to the coro
2633 frame type. */
2634
2635 static tree
2636 coro_make_frame_entry (tree *field_list, const char *name, tree fld_type,
2637 location_t loc)
2638 {
2639 tree id = get_identifier (name);
2640 tree decl = build_decl (loc, FIELD_DECL, id, fld_type);
2641 DECL_CHAIN (decl) = *field_list;
2642 *field_list = decl;
2643 return id;
2644 }
2645
2646 /* This data set is used when analyzing statements for await expressions. */
2647 struct susp_frame_data
2648 {
2649 /* Function-wide. */
2650 tree *field_list; /* The current coroutine frame field list. */
2651 tree handle_type; /* The self-handle type for this coroutine. */
2652 vec<tree, va_gc> *block_stack; /* Track block scopes. */
2653 vec<tree, va_gc> *bind_stack; /* Track current bind expr. */
2654 unsigned await_number; /* Which await in the function. */
2655 unsigned cond_number; /* Which replaced condition in the fn. */
2656 /* Temporary values for one statement or expression being analyzed. */
2657 hash_set<tree> captured_temps; /* The suspend captured these temps. */
2658 vec<tree, va_gc> *to_replace; /* The VAR decls to replace. */
2659 hash_set<tree> *truth_aoif_to_expand; /* The set of TRUTH exprs to expand. */
2660 unsigned saw_awaits; /* Count of awaits in this statement */
2661 bool captures_temporary; /* This expr captures temps by ref. */
2662 bool needs_truth_if_exp; /* We must expand a truth_if expression. */
2663 };
2664
2665 /* Walk the sub-tree looking for call expressions that both capture
2666 references and have compiler-temporaries as parms. */
2667
2668 static tree
2669 captures_temporary (tree *stmt, int *do_subtree, void *d)
2670 {
2671 /* We should have already lowered co_yields to their co_await. */
2672 gcc_checking_assert (TREE_CODE (*stmt) != CO_YIELD_EXPR);
2673
2674 /* Stop recursing if we see an await expression, the subtrees
2675 of that will be handled when it is processed. */
2676 if (TREE_CODE (*stmt) == CO_AWAIT_EXPR)
2677 {
2678 *do_subtree = 0;
2679 return NULL_TREE;
2680 }
2681
2682 /* We're only interested in calls. */
2683 if (TREE_CODE (*stmt) != CALL_EXPR)
2684 return NULL_TREE;
2685
2686 /* Does this call capture references?
2687 Strip the ADDRESS_EXPR to get the fn decl and inspect it. */
2688 tree fn = TREE_OPERAND (CALL_EXPR_FN (*stmt), 0);
2689 bool is_meth = TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE;
2690 tree arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
2691 unsigned offset = 3;
2692 for (unsigned anum = 0; arg != NULL; arg = TREE_CHAIN (arg), anum++)
2693 {
2694 tree parm_type = TREE_VALUE (arg);
2695 if (anum == 0 && is_meth && INDIRECT_TYPE_P (parm_type))
2696 {
2697 /* Account for 'this' when the fn is a method. Unless it
2698 belongs to a CTOR or DTOR. */
2699 if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
2700 continue;
2701 }
2702 else if (!TYPE_REF_P (parm_type))
2703 /* If it's not a reference, we don't care. */
2704 continue;
2705
2706 /* Fetch the value presented to the fn. */
2707 tree parm = TREE_OPERAND (*stmt, anum + offset);
2708
2709 while (TREE_CODE (parm) == NOP_EXPR)
2710 parm = TREE_OPERAND (parm, 0);
2711
2712 /* We only care if we're taking the addr of a temporary. */
2713 if (TREE_CODE (parm) != ADDR_EXPR)
2714 continue;
2715
2716 parm = TREE_OPERAND (parm, 0);
2717
2718 /* In case of component_ref, we need to capture the object of base
2719 class as if it is temporary object. There are two possibilities:
2720 (*base).field and base->field. */
2721 while (TREE_CODE (parm) == COMPONENT_REF)
2722 {
2723 parm = TREE_OPERAND (parm, 0);
2724 if (TREE_CODE (parm) == INDIRECT_REF)
2725 parm = TREE_OPERAND (parm, 0);
2726 STRIP_NOPS (parm);
2727 }
2728
2729 /* This isn't a temporary. */
2730 if ((VAR_P (parm)
2731 && (!DECL_ARTIFICIAL (parm) || DECL_HAS_VALUE_EXPR_P (parm)))
2732 || TREE_CODE (parm) == PARM_DECL
2733 || TREE_CODE (parm) == NON_LVALUE_EXPR)
2734 continue;
2735
2736 if (TREE_CODE (parm) == TARGET_EXPR)
2737 {
2738 /* We're taking the address of a temporary and using it as a ref. */
2739 tree tvar = TREE_OPERAND (parm, 0);
2740 gcc_checking_assert (DECL_ARTIFICIAL (tvar));
2741
2742 susp_frame_data *data = (susp_frame_data *) d;
2743 data->captures_temporary = true;
2744 /* Record this one so we don't duplicate, and on the first
2745 occurrence note the target expr to be replaced. */
2746 if (!data->captured_temps.add (tvar))
2747 vec_safe_push (data->to_replace, parm);
2748 /* Now see if the initializer contains any more cases. */
2749 hash_set<tree> visited;
2750 tree res = cp_walk_tree (&TREE_OPERAND (parm, 1),
2751 captures_temporary, d, &visited);
2752 if (res)
2753 return res;
2754 /* Otherwise, we're done with sub-trees for this. */
2755 }
2756 else if (TREE_CODE (parm) == CO_AWAIT_EXPR)
2757 {
2758 /* CO_AWAIT expressions behave in a similar manner to target
2759 expressions when the await_resume call is contained in one. */
2760 tree awr = TREE_OPERAND (parm, 3); /* call vector. */
2761 awr = TREE_VEC_ELT (awr, 2); /* resume call. */
2762 if (TREE_CODE (awr) == TARGET_EXPR)
2763 {
2764 tree tvar = TREE_OPERAND (awr, 0);
2765 gcc_checking_assert (DECL_ARTIFICIAL (tvar));
2766
2767 susp_frame_data *data = (susp_frame_data *) d;
2768 data->captures_temporary = true;
2769 /* Use this as a place-holder. */
2770 if (!data->captured_temps.add (tvar))
2771 vec_safe_push (data->to_replace, parm);
2772 }
2773 /* We will walk the sub-trees of this co_await separately. */
2774 }
2775 else
2776 gcc_unreachable ();
2777 }
2778 /* As far as it's necessary, we've walked the subtrees of the call
2779 expr. */
2780 *do_subtree = 0;
2781 return NULL_TREE;
2782 }
2783
2784 /* If this is an await, then register it and decide on what coro
2785 frame storage is needed.
2786 If this is a co_yield (which embeds an await), drop the yield
2787 and record the await (the yield was kept for diagnostics only). */
2788
2789 static tree
2790 register_awaits (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
2791 {
2792 susp_frame_data *data = (susp_frame_data *) d;
2793
2794 /* We should have already lowered co_yields to their co_await. */
2795 gcc_checking_assert (TREE_CODE (*stmt) != CO_YIELD_EXPR);
2796
2797 if (TREE_CODE (*stmt) != CO_AWAIT_EXPR)
2798 return NULL_TREE;
2799
2800 tree aw_expr = *stmt;
2801 location_t aw_loc = EXPR_LOCATION (aw_expr); /* location of the co_xxxx. */
2802
2803 /* If the awaitable is a parm or a local variable, then we already have
2804 a frame copy, so don't make a new one. */
2805 tree aw = TREE_OPERAND (aw_expr, 1);
2806 tree aw_field_type = TREE_TYPE (aw);
2807 tree aw_field_nam = NULL_TREE;
2808 if (INDIRECT_REF_P (aw))
2809 aw = TREE_OPERAND (aw, 0);
2810 if (TREE_CODE (aw) == PARM_DECL
2811 || (VAR_P (aw) && (!DECL_ARTIFICIAL (aw)
2812 || DECL_HAS_VALUE_EXPR_P (aw))))
2813 ; /* Don't make an additional copy. */
2814 else
2815 {
2816 /* The required field has the same type as the proxy stored in the
2817 await expr. */
2818 char *nam = xasprintf ("__aw_s.%d", data->await_number);
2819 aw_field_nam = coro_make_frame_entry (data->field_list, nam,
2820 aw_field_type, aw_loc);
2821 free (nam);
2822 }
2823
2824 tree o = TREE_OPERAND (aw_expr, 2); /* Initialiser for the frame var. */
2825 /* If this is a target expression, then we need to remake it to strip off
2826 any extra cleanups added. */
2827 if (TREE_CODE (o) == TARGET_EXPR)
2828 TREE_OPERAND (aw_expr, 2) = get_target_expr (TREE_OPERAND (o, 1));
2829
2830 tree v = TREE_OPERAND (aw_expr, 3);
2831 o = TREE_VEC_ELT (v, 1);
2832 if (TREE_CODE (o) == TARGET_EXPR)
2833 TREE_VEC_ELT (v, 1) = get_target_expr (TREE_OPERAND (o, 1));
2834
2835 register_await_info (aw_expr, aw_field_type, aw_field_nam);
2836
2837 /* Count how many awaits the current expression contains. */
2838 data->saw_awaits++;
2839 /* Each await suspend context is unique, this is a function-wide value. */
2840 data->await_number++;
2841
2842 /* We now need to know if to take special action on lifetime extension
2843 of temporaries captured by reference. This can only happen if such
2844 a case appears in the initializer for the awaitable. The callback
2845 records captured temporaries including subtrees of initializers. */
2846 hash_set<tree> visited;
2847 tree res = cp_walk_tree (&TREE_OPERAND (aw_expr, 2), captures_temporary, d,
2848 &visited);
2849 return res;
2850 }
2851
2852 /* The gimplifier correctly extends the lifetime of temporaries captured
2853 by reference (per. [class.temporary] (6.9) "A temporary object bound
2854 to a reference parameter in a function call persists until the completion
2855 of the full-expression containing the call"). However, that is not
2856 sufficient to work across a suspension - and we need to promote such
2857 temporaries to be regular vars that will then get a coro frame slot.
2858 We don't want to incur the effort of checking for this unless we have
2859 an await expression in the current full expression. */
2860
2861 /* This takes the statement which contains one or more temporaries that have
2862 been 'captured' by reference in the initializer(s) of co_await(s).
2863 The statement is replaced by a bind expression that has actual variables
2864 to replace the temporaries. These variables will be added to the coro-
2865 frame in the same manner as user-authored ones. */
2866
2867 static void
2868 replace_statement_captures (tree *stmt, void *d)
2869 {
2870 susp_frame_data *awpts = (susp_frame_data *) d;
2871 location_t sloc = EXPR_LOCATION (*stmt);
2872 tree aw_bind
2873 = build3_loc (sloc, BIND_EXPR, void_type_node, NULL, NULL, NULL);
2874
2875 /* Any cleanup point expression might no longer be necessary, since we
2876 are removing one or more temporaries. */
2877 tree aw_statement_current = *stmt;
2878 if (TREE_CODE (aw_statement_current) == CLEANUP_POINT_EXPR)
2879 aw_statement_current = TREE_OPERAND (aw_statement_current, 0);
2880
2881 /* Collected the scope vars we need move the temps to regular. */
2882 tree aw_bind_body = push_stmt_list ();
2883 tree varlist = NULL_TREE;
2884 int vnum = -1;
2885 while (!awpts->to_replace->is_empty ())
2886 {
2887 tree to_replace = awpts->to_replace->pop ();
2888 tree orig_temp;
2889 if (TREE_CODE (to_replace) == CO_AWAIT_EXPR)
2890 {
2891 orig_temp = TREE_OPERAND (to_replace, 3);
2892 orig_temp = TREE_VEC_ELT (orig_temp, 2);
2893 orig_temp = TREE_OPERAND (orig_temp, 0);
2894 }
2895 else
2896 orig_temp = TREE_OPERAND (to_replace, 0);
2897
2898 tree var_type = TREE_TYPE (orig_temp);
2899 gcc_checking_assert (same_type_p (TREE_TYPE (to_replace), var_type));
2900 /* Build a variable to hold the captured value, this will be included
2901 in the frame along with any user-authored locals. */
2902 char *nam = xasprintf ("aw_%d.tmp.%d", awpts->await_number, ++vnum);
2903 tree newvar = build_lang_decl (VAR_DECL, get_identifier (nam), var_type);
2904 free (nam);
2905 /* If we have better location than the whole expression use that, else
2906 fall back to the expression loc. */
2907 DECL_CONTEXT (newvar) = DECL_CONTEXT (orig_temp);
2908 if (DECL_SOURCE_LOCATION (orig_temp))
2909 sloc = DECL_SOURCE_LOCATION (orig_temp);
2910 else
2911 sloc = EXPR_LOCATION (*stmt);
2912 DECL_SOURCE_LOCATION (newvar) = sloc;
2913 DECL_CHAIN (newvar) = varlist;
2914 varlist = newvar; /* Chain it onto the list for the bind expr. */
2915 /* Declare and initialize it in the new bind scope. */
2916 add_decl_expr (newvar);
2917 tree new_s = build2_loc (sloc, INIT_EXPR, var_type, newvar, to_replace);
2918 new_s = coro_build_cvt_void_expr_stmt (new_s, sloc);
2919 add_stmt (new_s);
2920
2921 /* Replace all instances of that temp in the original expr. */
2922 proxy_replace pr = {to_replace, newvar};
2923 cp_walk_tree (&aw_statement_current, replace_proxy, &pr, NULL);
2924 }
2925
2926 /* What's left should be the original statement with any co_await captured
2927 temporaries broken out. Other temporaries might remain so see if we
2928 need to wrap the revised statement in a cleanup. */
2929 aw_statement_current = maybe_cleanup_point_expr_void (aw_statement_current);
2930 add_stmt (aw_statement_current);
2931
2932 BIND_EXPR_BODY (aw_bind) = pop_stmt_list (aw_bind_body);
2933 awpts->captured_temps.empty ();
2934
2935 BIND_EXPR_VARS (aw_bind) = nreverse (varlist);
2936 tree b_block = make_node (BLOCK);
2937 if (!awpts->block_stack->is_empty ())
2938 {
2939 tree s_block = awpts->block_stack->last ();
2940 if (s_block)
2941 {
2942 BLOCK_SUPERCONTEXT (b_block) = s_block;
2943 BLOCK_CHAIN (b_block) = BLOCK_SUBBLOCKS (s_block);
2944 BLOCK_SUBBLOCKS (s_block) = b_block;
2945 }
2946 }
2947 BIND_EXPR_BLOCK (aw_bind) = b_block;
2948 TREE_SIDE_EFFECTS (aw_bind) = TREE_SIDE_EFFECTS (BIND_EXPR_BODY (aw_bind));
2949 *stmt = aw_bind;
2950 }
2951
2952 /* This is called for single statements from the co-await statement walker.
2953 It checks to see if the statement contains any co-awaits and, if so,
2954 whether any of these 'capture' a temporary by reference. */
2955
2956 static tree
2957 maybe_promote_captured_temps (tree *stmt, void *d)
2958 {
2959 susp_frame_data *awpts = (susp_frame_data *) d;
2960 hash_set<tree> visited;
2961 awpts->saw_awaits = 0;
2962
2963 /* When register_awaits sees an await, it walks the initializer for
2964 that await looking for temporaries captured by reference and notes
2965 them in awpts->captured_temps. */
2966
2967 if (tree res = cp_walk_tree (stmt, register_awaits, d, &visited))
2968 return res; /* We saw some reason to abort the tree walk. */
2969
2970 /* We only need to take any action here if the statement contained any
2971 awaits and any of those had temporaries captured by reference in their
2972 initializers. */
2973
2974 if (awpts->saw_awaits > 0 && !awpts->captured_temps.is_empty ())
2975 replace_statement_captures (stmt, d);
2976
2977 return NULL_TREE;
2978 }
2979
2980 /* Lightweight callback to determine two key factors:
2981 1) If the statement/expression contains any await expressions.
2982 2) If the statement/expression potentially requires a re-write to handle
2983 TRUTH_{AND,OR}IF_EXPRs since, in most cases, they will need expansion
2984 so that the await expressions are not processed in the case of the
2985 short-circuit arm.
2986 CO_YIELD expressions are re-written to their underlying co_await. */
2987
2988 static tree
2989 analyze_expression_awaits (tree *stmt, int *do_subtree, void *d)
2990 {
2991 susp_frame_data *awpts = (susp_frame_data *) d;
2992
2993 switch (TREE_CODE (*stmt))
2994 {
2995 default: return NULL_TREE;
2996 case CO_YIELD_EXPR:
2997 /* co_yield is syntactic sugar, re-write it to co_await. */
2998 *stmt = TREE_OPERAND (*stmt, 1);
2999 /* FALLTHROUGH */
3000 case CO_AWAIT_EXPR:
3001 awpts->saw_awaits++;
3002 break;
3003 case TRUTH_ANDIF_EXPR:
3004 case TRUTH_ORIF_EXPR:
3005 {
3006 /* We don't need special action for awaits in the always-executed
3007 arm of a TRUTH_IF. */
3008 if (tree res = cp_walk_tree (&TREE_OPERAND (*stmt, 0),
3009 analyze_expression_awaits, d, NULL))
3010 return res;
3011 /* However, if there are await expressions on the conditionally
3012 executed branch, we must expand the TRUTH_IF to ensure that the
3013 expanded await expression control-flow is fully contained in the
3014 conditionally executed code. */
3015 unsigned aw_count = awpts->saw_awaits;
3016 if (tree res = cp_walk_tree (&TREE_OPERAND (*stmt, 1),
3017 analyze_expression_awaits, d, NULL))
3018 return res;
3019 if (awpts->saw_awaits > aw_count)
3020 {
3021 awpts->truth_aoif_to_expand->add (*stmt);
3022 awpts->needs_truth_if_exp = true;
3023 }
3024 /* We've done the sub-trees here. */
3025 *do_subtree = 0;
3026 }
3027 break;
3028 }
3029
3030 return NULL_TREE; /* Recurse until done. */
3031 }
3032
3033 /* Given *EXPR
3034 If EXPR contains a TRUTH_{AND,OR}IF_EXPR, TAOIE with an await expr on
3035 the conditional branch expand this to:
3036
3037 bool not_expr = TAOIE == TRUTH_ORIF_EXPR ? NOT : NOP;
3038 A) bool t = always exec expr
3039 if (not_expr (t))
3040 B) t = conditionally exec expr
3041 c) EXPR' = EXPR with TAOIE replaced by t.
3042
3043 Then repeat this for A, B and C. */
3044
3045 struct truth_if_transform {
3046 tree *orig_stmt;
3047 tree scratch_var;
3048 hash_set<tree> *truth_aoif_to_expand;
3049 };
3050
3051 static tree
3052 expand_one_truth_if (tree *expr, int *do_subtree, void *d)
3053 {
3054 truth_if_transform *xform = (truth_if_transform *) d;
3055
3056 bool needs_not = false;
3057 switch (TREE_CODE (*expr))
3058 {
3059 default: break;
3060 case TRUTH_ORIF_EXPR:
3061 needs_not = true;
3062 /* FALLTHROUGH */
3063 case TRUTH_ANDIF_EXPR:
3064 {
3065 if (!xform->truth_aoif_to_expand->contains (*expr))
3066 break;
3067
3068 location_t sloc = EXPR_LOCATION (*expr);
3069 tree type = TREE_TYPE (xform->scratch_var);
3070 gcc_checking_assert (TREE_CODE (type) == BOOLEAN_TYPE);
3071 tree new_list = push_stmt_list ();
3072 /* Init our scratch with the unconditionally-evaluated expr. */
3073 tree new_s = build2_loc (sloc, INIT_EXPR, boolean_type_node,
3074 xform->scratch_var,
3075 TREE_OPERAND (*expr, 0));
3076 finish_expr_stmt (new_s);
3077 tree *pre = tsi_stmt_ptr (tsi_last (new_list));
3078 tree if_cond = xform->scratch_var;
3079 if (needs_not)
3080 if_cond = build1 (TRUTH_NOT_EXPR, boolean_type_node, if_cond);
3081 tree if_stmt = begin_if_stmt ();
3082 finish_if_stmt_cond (if_cond, if_stmt);
3083 /* If we take the if branch, then overwrite scratch with the cond
3084 executed branch. */
3085 new_s = build2 (INIT_EXPR, boolean_type_node,
3086 xform->scratch_var, TREE_OPERAND (*expr, 1));
3087 finish_expr_stmt (new_s);
3088 finish_then_clause (if_stmt);
3089 finish_if_stmt (if_stmt);
3090 *expr = xform->scratch_var; /* now contains the result. */
3091 /* So now we've got a statement list expanding one TAOIe. */
3092 add_stmt (*xform->orig_stmt);
3093 tree *post = tsi_stmt_ptr (tsi_last (new_list));
3094 *xform->orig_stmt = pop_stmt_list (new_list);
3095 /* Now recurse into the pre, if and post parts. */
3096 truth_if_transform sub_data = {pre, xform->scratch_var,
3097 xform->truth_aoif_to_expand};
3098 if (tree res = cp_walk_tree (pre, expand_one_truth_if, &sub_data,
3099 NULL))
3100 return res;
3101 sub_data.orig_stmt = &THEN_CLAUSE (if_stmt);
3102 if (tree res = cp_walk_tree (&THEN_CLAUSE (if_stmt),
3103 expand_one_truth_if, &sub_data, NULL))
3104 return res;
3105 sub_data.orig_stmt = post;
3106 if (tree res = cp_walk_tree (post, expand_one_truth_if, &sub_data,
3107 NULL))
3108 return res;
3109 /* We've done the sub-trees here. */
3110 *do_subtree = 0;
3111 }
3112 break;
3113 }
3114 return NULL_TREE;
3115 }
3116
3117 /* Helper that adds a new variable of VAR_TYPE to a bind scope BIND, the
3118 name is made up from NAM_ROOT, NAM_VERS. */
3119
3120 static tree
3121 add_var_to_bind (tree& bind, tree var_type,
3122 const char *nam_root, unsigned nam_vers)
3123 {
3124
3125 tree b_vars = BIND_EXPR_VARS (bind);
3126 /* Build a variable to hold the condition, this will be included in the
3127 frame as a local var. */
3128 char *nam = xasprintf ("%s.%d", nam_root, nam_vers);
3129 tree newvar = build_lang_decl (VAR_DECL, get_identifier (nam), var_type);
3130 free (nam);
3131 DECL_CHAIN (newvar) = b_vars;
3132 BIND_EXPR_VARS (bind) = newvar;
3133 return newvar;
3134 }
3135
3136 /* Helper to build and add if (!cond) break; */
3137
3138 static void
3139 coro_build_add_if_not_cond_break (tree cond)
3140 {
3141 tree if_stmt = begin_if_stmt ();
3142 tree invert = build1 (TRUTH_NOT_EXPR, boolean_type_node, cond);
3143 finish_if_stmt_cond (invert, if_stmt);
3144 finish_break_stmt ();
3145 finish_then_clause (if_stmt);
3146 finish_if_stmt (if_stmt);
3147 }
3148
3149 /* Tree walk callback to analyze, register and pre-process statements that
3150 contain await expressions. */
3151
3152 static tree
3153 await_statement_walker (tree *stmt, int *do_subtree, void *d)
3154 {
3155 tree res = NULL_TREE;
3156 susp_frame_data *awpts = (susp_frame_data *) d;
3157
3158 /* Process a statement at a time. */
3159 if (TREE_CODE (*stmt) == BIND_EXPR)
3160 {
3161 /* For conditional expressions, we might wish to add an artificial var
3162 to their containing bind expr. */
3163 vec_safe_push (awpts->bind_stack, *stmt);
3164 /* We might need to insert a new bind expression, and want to link it
3165 into the correct scope, so keep a note of the current block scope. */
3166 tree blk = BIND_EXPR_BLOCK (*stmt);
3167 vec_safe_push (awpts->block_stack, blk);
3168 res = cp_walk_tree (&BIND_EXPR_BODY (*stmt), await_statement_walker,
3169 d, NULL);
3170 awpts->block_stack->pop ();
3171 awpts->bind_stack->pop ();
3172 *do_subtree = 0; /* Done subtrees. */
3173 return res;
3174 }
3175 else if (TREE_CODE (*stmt) == STATEMENT_LIST)
3176 {
3177 tree_stmt_iterator i;
3178 for (i = tsi_start (*stmt); !tsi_end_p (i); tsi_next (&i))
3179 {
3180 res = cp_walk_tree (tsi_stmt_ptr (i), await_statement_walker,
3181 d, NULL);
3182 if (res)
3183 return res;
3184 }
3185 *do_subtree = 0; /* Done subtrees. */
3186 return NULL_TREE;
3187 }
3188
3189 /* We have something to be handled as a single statement. */
3190 hash_set<tree> visited;
3191 awpts->saw_awaits = 0;
3192 hash_set<tree> truth_aoif_to_expand;
3193 awpts->truth_aoif_to_expand = &truth_aoif_to_expand;
3194 awpts->needs_truth_if_exp = false;
3195
3196 if (STATEMENT_CLASS_P (*stmt))
3197 switch (TREE_CODE (*stmt))
3198 {
3199 /* Unless it's a special case, just walk the subtrees as usual. */
3200 default: return NULL_TREE;
3201
3202 /* When we have a conditional expression, which contains one or more
3203 await expressions, we have to break the condition out into a
3204 regular statement so that the control flow introduced by the await
3205 transforms can be implemented. */
3206 case IF_STMT:
3207 {
3208 /* Transform 'if (cond with awaits) then stmt1 else stmt2' into
3209 bool cond = cond with awaits.
3210 if (cond) then stmt1 else stmt2. */
3211 tree if_stmt = *stmt;
3212 /* We treat the condition as if it was a stand-alone statement,
3213 to see if there are any await expressions which will be analysed
3214 and registered. */
3215 if ((res = cp_walk_tree (&IF_COND (if_stmt),
3216 analyze_expression_awaits, d, &visited)))
3217 return res;
3218 if (!awpts->saw_awaits)
3219 return NULL_TREE; /* Nothing special to do here. */
3220
3221 gcc_checking_assert (!awpts->bind_stack->is_empty());
3222 tree& bind_expr = awpts->bind_stack->last ();
3223 tree newvar = add_var_to_bind (bind_expr, boolean_type_node,
3224 "ifcd", awpts->cond_number++);
3225 tree insert_list = push_stmt_list ();
3226 tree cond_inner = IF_COND (if_stmt);
3227 if (TREE_CODE (cond_inner) == CLEANUP_POINT_EXPR)
3228 cond_inner = TREE_OPERAND (cond_inner, 0);
3229 add_decl_expr (newvar);
3230 location_t sloc = EXPR_LOCATION (IF_COND (if_stmt));
3231 /* We want to initialize the new variable with the expression
3232 that contains the await(s) and potentially also needs to
3233 have truth_if expressions expanded. */
3234 tree new_s = build2_loc (sloc, MODIFY_EXPR, boolean_type_node,
3235 newvar, cond_inner);
3236 finish_expr_stmt (new_s);
3237 if (awpts->needs_truth_if_exp)
3238 {
3239 tree *sp = tsi_stmt_ptr (tsi_last (insert_list));
3240 truth_if_transform xf = {sp, newvar, &truth_aoif_to_expand};
3241 if ((res = cp_walk_tree (sp, expand_one_truth_if, &xf, NULL)))
3242 return res;
3243 }
3244 IF_COND (if_stmt) = newvar;
3245 add_stmt (if_stmt);
3246 *stmt = pop_stmt_list (insert_list);
3247 /* So now walk the new statement list. */
3248 res = cp_walk_tree (stmt, await_statement_walker, d, NULL);
3249 *do_subtree = 0; /* Done subtrees. */
3250 return res;
3251 }
3252 break;
3253 case WHILE_STMT:
3254 {
3255 /* We turn 'while (cond with awaits) stmt' into
3256 while (true) {
3257 if (!(cond with awaits))
3258 break;
3259 stmt..
3260 } */
3261 tree while_stmt = *stmt;
3262 if ((res = cp_walk_tree (&WHILE_COND (while_stmt),
3263 analyze_expression_awaits, d, &visited)))
3264 return res;
3265 if (!awpts->saw_awaits)
3266 return NULL_TREE; /* Nothing special to do here. */
3267
3268 tree insert_list = push_stmt_list ();
3269 coro_build_add_if_not_cond_break (WHILE_COND (while_stmt));
3270 /* The original while body. */
3271 add_stmt (WHILE_BODY (while_stmt));
3272 /* The new while body. */
3273 WHILE_BODY (while_stmt) = pop_stmt_list (insert_list);
3274 WHILE_COND (while_stmt) = boolean_true_node;
3275 /* So now walk the new statement list. */
3276 res = cp_walk_tree (&WHILE_BODY (while_stmt),
3277 await_statement_walker, d, NULL);
3278 *do_subtree = 0; /* Done subtrees. */
3279 return res;
3280 }
3281 break;
3282 case DO_STMT:
3283 {
3284 /* We turn do stmt while (cond with awaits) into:
3285 do {
3286 stmt..
3287 if (!(cond with awaits))
3288 break;
3289 } while (true); */
3290 tree do_stmt = *stmt;
3291 if ((res = cp_walk_tree (&DO_COND (do_stmt),
3292 analyze_expression_awaits, d, &visited)))
3293 return res;
3294 if (!awpts->saw_awaits)
3295 return NULL_TREE; /* Nothing special to do here. */
3296
3297 tree insert_list = push_stmt_list ();
3298 /* The original do stmt body. */
3299 add_stmt (DO_BODY (do_stmt));
3300 coro_build_add_if_not_cond_break (DO_COND (do_stmt));
3301 /* The new while body. */
3302 DO_BODY (do_stmt) = pop_stmt_list (insert_list);
3303 DO_COND (do_stmt) = boolean_true_node;
3304 /* So now walk the new statement list. */
3305 res = cp_walk_tree (&DO_BODY (do_stmt), await_statement_walker,
3306 d, NULL);
3307 *do_subtree = 0; /* Done subtrees. */
3308 return res;
3309
3310 }
3311 break;
3312 case SWITCH_STMT:
3313 {
3314 /* We turn 'switch (cond with awaits) stmt' into
3315 switch_type cond = cond with awaits
3316 switch (cond) stmt. */
3317 tree sw_stmt = *stmt;
3318 if ((res = cp_walk_tree (&SWITCH_STMT_COND (sw_stmt),
3319 analyze_expression_awaits, d, &visited)))
3320 return res;
3321 if (!awpts->saw_awaits)
3322 return NULL_TREE; /* Nothing special to do here. */
3323
3324 gcc_checking_assert (!awpts->bind_stack->is_empty());
3325 /* Build a variable to hold the condition, this will be
3326 included in the frame as a local var. */
3327 tree& bind_expr = awpts->bind_stack->last ();
3328 tree sw_type = SWITCH_STMT_TYPE (sw_stmt);
3329 tree newvar = add_var_to_bind (bind_expr, sw_type, "swch",
3330 awpts->cond_number++);
3331 tree insert_list = push_stmt_list ();
3332 add_decl_expr (newvar);
3333
3334 tree cond_inner = SWITCH_STMT_COND (sw_stmt);
3335 if (TREE_CODE (cond_inner) == CLEANUP_POINT_EXPR)
3336 cond_inner = TREE_OPERAND (cond_inner, 0);
3337 location_t sloc = EXPR_LOCATION (SWITCH_STMT_COND (sw_stmt));
3338 tree new_s = build2_loc (sloc, INIT_EXPR, sw_type, newvar,
3339 cond_inner);
3340 finish_expr_stmt (new_s);
3341 SWITCH_STMT_COND (sw_stmt) = newvar;
3342 /* Now add the switch statement with the condition re-
3343 written to use the local var. */
3344 add_stmt (sw_stmt);
3345 *stmt = pop_stmt_list (insert_list);
3346 /* Process the expanded list. */
3347 res = cp_walk_tree (stmt, await_statement_walker,
3348 d, NULL);
3349 *do_subtree = 0; /* Done subtrees. */
3350 return res;
3351 }
3352 break;
3353 }
3354 else if (EXPR_P (*stmt))
3355 {
3356 if ((res = cp_walk_tree (stmt, analyze_expression_awaits, d, &visited)))
3357 return res;
3358 *do_subtree = 0; /* Done subtrees. */
3359 if (!awpts->saw_awaits)
3360 return NULL_TREE; /* Nothing special to do here. */
3361
3362 /* Unless we need to expand any truth-and/or-if expressions, then the
3363 remaining action is to check for temporaries to await expressions
3364 captured by refence. */
3365 if (!awpts->needs_truth_if_exp)
3366 return maybe_promote_captured_temps (stmt, d);
3367
3368 gcc_checking_assert (!awpts->bind_stack->is_empty());
3369 tree& bind_expr = awpts->bind_stack->last ();
3370 /* Build a variable to hold the condition, this will be
3371 included in the frame as a local var. */
3372 tree newvar = add_var_to_bind (bind_expr, boolean_type_node,
3373 "taoi", awpts->cond_number++);
3374 tree insert_list = push_stmt_list ();
3375 add_decl_expr (newvar);
3376 add_stmt (*stmt);
3377 tree *sp = tsi_stmt_ptr (tsi_last (insert_list));
3378 *stmt = pop_stmt_list (insert_list);
3379
3380 truth_if_transform xf = {sp, newvar, &truth_aoif_to_expand};
3381 if ((res = cp_walk_tree (sp, expand_one_truth_if, &xf, NULL)))
3382 return res;
3383 /* Process the expanded trees. */
3384 return cp_walk_tree (stmt, await_statement_walker, d, NULL);
3385 }
3386
3387 /* Continue recursion, if needed. */
3388 return res;
3389 }
3390
3391 /* For figuring out what param usage we have. */
3392
3393 struct param_frame_data
3394 {
3395 tree *field_list;
3396 hash_map<tree, param_info> *param_uses;
3397 hash_set<tree *> *visited;
3398 location_t loc;
3399 bool param_seen;
3400 };
3401
3402 static tree
3403 register_param_uses (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
3404 {
3405 param_frame_data *data = (param_frame_data *) d;
3406
3407 /* For lambda closure content, we have to look specifically. */
3408 if (TREE_CODE (*stmt) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (*stmt))
3409 {
3410 tree t = DECL_VALUE_EXPR (*stmt);
3411 return cp_walk_tree (&t, register_param_uses, d, NULL);
3412 }
3413
3414 if (TREE_CODE (*stmt) != PARM_DECL)
3415 return NULL_TREE;
3416
3417 /* If we already saw the containing expression, then we're done. */
3418 if (data->visited->add (stmt))
3419 return NULL_TREE;
3420
3421 bool existed;
3422 param_info &parm = data->param_uses->get_or_insert (*stmt, &existed);
3423 gcc_checking_assert (existed);
3424
3425 if (!parm.body_uses)
3426 {
3427 vec_alloc (parm.body_uses, 4);
3428 parm.body_uses->quick_push (stmt);
3429 data->param_seen = true;
3430 }
3431 else
3432 parm.body_uses->safe_push (stmt);
3433
3434 return NULL_TREE;
3435 }
3436
3437 /* For figuring out what local variable usage we have. */
3438
3439 struct local_vars_frame_data
3440 {
3441 tree *field_list;
3442 hash_map<tree, local_var_info> *local_var_uses;
3443 unsigned int nest_depth, bind_indx;
3444 location_t loc;
3445 bool saw_capture;
3446 bool local_var_seen;
3447 };
3448
3449 static tree
3450 register_local_var_uses (tree *stmt, int *do_subtree, void *d)
3451 {
3452 local_vars_frame_data *lvd = (local_vars_frame_data *) d;
3453
3454 /* As we enter a bind expression - record the vars there and then recurse.
3455 As we exit drop the nest depth.
3456 The bind index is a growing count of how many bind indices we've seen.
3457 We build a space in the frame for each local var. */
3458
3459 if (TREE_CODE (*stmt) == BIND_EXPR)
3460 {
3461 lvd->bind_indx++;
3462 lvd->nest_depth++;
3463 tree lvar;
3464 for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
3465 lvar = DECL_CHAIN (lvar))
3466 {
3467 bool existed;
3468 local_var_info &local_var
3469 = lvd->local_var_uses->get_or_insert (lvar, &existed);
3470 gcc_checking_assert (!existed);
3471 local_var.def_loc = DECL_SOURCE_LOCATION (lvar);
3472 tree lvtype = TREE_TYPE (lvar);
3473 local_var.frame_type = lvtype;
3474 local_var.field_idx = local_var.field_id = NULL_TREE;
3475
3476 /* Make sure that we only present vars to the tests below. */
3477 if (TREE_CODE (lvar) == TYPE_DECL)
3478 continue;
3479
3480 /* We don't move static vars into the frame. */
3481 local_var.is_static = TREE_STATIC (lvar);
3482 if (local_var.is_static)
3483 continue;
3484
3485 lvd->local_var_seen = true;
3486 /* If this var is a lambda capture proxy, we want to leave it alone,
3487 and later rewrite the DECL_VALUE_EXPR to indirect through the
3488 frame copy of the pointer to the lambda closure object. */
3489 local_var.is_lambda_capture = is_capture_proxy (lvar);
3490 if (local_var.is_lambda_capture)
3491 continue;
3492
3493 /* If a variable has a value expression, then that's what needs
3494 to be processed. */
3495 local_var.has_value_expr_p = DECL_HAS_VALUE_EXPR_P (lvar);
3496 if (local_var.has_value_expr_p)
3497 continue;
3498
3499 /* Make names depth+index unique, so that we can support nested
3500 scopes with identically named locals. */
3501 tree lvname = DECL_NAME (lvar);
3502 char *buf;
3503 if (lvname != NULL_TREE)
3504 buf = xasprintf ("__lv.%u.%u.%s", lvd->bind_indx, lvd->nest_depth,
3505 IDENTIFIER_POINTER (lvname));
3506 else
3507 buf = xasprintf ("__lv.%u.%u.D%u", lvd->bind_indx, lvd->nest_depth,
3508 DECL_UID (lvar));
3509 /* TODO: Figure out if we should build a local type that has any
3510 excess alignment or size from the original decl. */
3511 local_var.field_id
3512 = coro_make_frame_entry (lvd->field_list, buf, lvtype, lvd->loc);
3513 free (buf);
3514 /* We don't walk any of the local var sub-trees, they won't contain
3515 any bind exprs. */
3516 }
3517 cp_walk_tree (&BIND_EXPR_BODY (*stmt), register_local_var_uses, d, NULL);
3518 *do_subtree = 0; /* We've done this. */
3519 lvd->nest_depth--;
3520 }
3521 return NULL_TREE;
3522 }
3523
3524 /* Build, return FUNCTION_DECL node with its coroutine frame pointer argument
3525 for either actor or destroy functions. */
3526
3527 static tree
3528 act_des_fn (tree orig, tree fn_type, tree coro_frame_ptr, const char* name)
3529 {
3530 tree fn_name = get_fn_local_identifier (orig, name);
3531 tree fn = build_lang_decl (FUNCTION_DECL, fn_name, fn_type);
3532 DECL_CONTEXT (fn) = DECL_CONTEXT (orig);
3533 DECL_INITIAL (fn) = error_mark_node;
3534 tree id = get_identifier ("frame_ptr");
3535 tree fp = build_lang_decl (PARM_DECL, id, coro_frame_ptr);
3536 DECL_CONTEXT (fp) = fn;
3537 DECL_ARG_TYPE (fp) = type_passed_as (coro_frame_ptr);
3538 DECL_ARGUMENTS (fn) = fp;
3539 return fn;
3540 }
3541
3542 /* Return a bind expression if we see one, else NULL_TREE. */
3543 static tree
3544 bind_expr_find_in_subtree (tree *stmt, int *, void *)
3545 {
3546 if (TREE_CODE (*stmt) == BIND_EXPR)
3547 return *stmt;
3548 return NULL_TREE;
3549 }
3550
3551 /* Return the first bind expression that the sub-tree given by STMT
3552 contains. */
3553
3554 static tree
3555 coro_body_contains_bind_expr_p (tree *stmt)
3556 {
3557 hash_set<tree> visited;
3558 return cp_walk_tree (stmt, bind_expr_find_in_subtree, NULL, &visited);
3559 }
3560
3561 /* Here we:
3562 a) Check that the function and promise type are valid for a
3563 coroutine.
3564 b) Carry out the initial morph to create the skeleton of the
3565 coroutine ramp function and the rewritten body.
3566
3567 Assumptions.
3568
3569 1. We only hit this code once all dependencies are resolved.
3570 2. The function body will be either a bind expr or a statement list
3571 3. That cfun and current_function_decl are valid for the case we're
3572 expanding.
3573 4. 'input_location' will be of the final brace for the function.
3574
3575 We do something like this:
3576 declare a dummy coro frame.
3577 struct _R_frame {
3578 using handle_type = coro::coroutine_handle<coro1::promise_type>;
3579 void (*__resume)(_R_frame *);
3580 void (*__destroy)(_R_frame *);
3581 coro1::promise_type __p;
3582 bool frame_needs_free; free the coro frame mem if set.
3583 bool i_a_r_c; [dcl.fct.def.coroutine] / 5.3
3584 short __resume_at;
3585 handle_type self_handle;
3586 (maybe) parameter copies.
3587 coro1::suspend_never_prt __is;
3588 coro1::suspend_always_prt __fs;
3589 (maybe) local variables saved
3590 (maybe) trailing space.
3591 }; */
3592
3593 bool
3594 morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
3595 {
3596 gcc_checking_assert (orig && TREE_CODE (orig) == FUNCTION_DECL);
3597
3598 *resumer = error_mark_node;
3599 *destroyer = error_mark_node;
3600 if (!coro_function_valid_p (orig))
3601 {
3602 /* For early errors, we do not want a diagnostic about the missing
3603 ramp return value, since the user cannot fix this - a 'return' is
3604 not allowed in a coroutine. */
3605 TREE_NO_WARNING (orig) = true;
3606 /* Discard the body, we can't process it further. */
3607 pop_stmt_list (DECL_SAVED_TREE (orig));
3608 DECL_SAVED_TREE (orig) = push_stmt_list ();
3609 return false;
3610 }
3611
3612 /* We can't validly get here with an empty statement list, since there's no
3613 way for the FE to decide it's a coroutine in the absence of any code. */
3614 tree fnbody = pop_stmt_list (DECL_SAVED_TREE (orig));
3615 gcc_checking_assert (fnbody != NULL_TREE);
3616
3617 /* We don't have the locus of the opening brace - it's filled in later (and
3618 there doesn't really seem to be any easy way to get at it).
3619 The closing brace is assumed to be input_location. */
3620 location_t fn_start = DECL_SOURCE_LOCATION (orig);
3621 gcc_rich_location fn_start_loc (fn_start);
3622
3623 /* Initial processing of the function-body.
3624 If we have no expressions or just an error then punt. */
3625 tree body_start = expr_first (fnbody);
3626 if (body_start == NULL_TREE || body_start == error_mark_node)
3627 {
3628 DECL_SAVED_TREE (orig) = push_stmt_list ();
3629 append_to_statement_list (fnbody, &DECL_SAVED_TREE (orig));
3630 /* Suppress warnings about the missing return value. */
3631 TREE_NO_WARNING (orig) = true;
3632 return false;
3633 }
3634
3635 /* So, we've tied off the original body. Now start the replacement.
3636 If we encounter a fatal error we might return a now-empty body.
3637 TODO: determine if it would help to restore the original.
3638 determine if looking for more errors in coro_function_valid_p()
3639 and stashing types is a better solution. */
3640
3641 tree newbody = push_stmt_list ();
3642 DECL_SAVED_TREE (orig) = newbody;
3643
3644 /* If our original body is noexcept, then that's what we apply to our
3645 generated functions. Remember that we're NOEXCEPT and fish out the
3646 contained list (we tied off to the top level already). */
3647 bool is_noexcept = TREE_CODE (body_start) == MUST_NOT_THROW_EXPR;
3648 if (is_noexcept)
3649 {
3650 /* Simplified abstract from begin_eh_spec_block, since we already
3651 know the outcome. */
3652 fnbody = TREE_OPERAND (body_start, 0); /* Stash the original... */
3653 add_stmt (body_start); /* ... and start the new. */
3654 TREE_OPERAND (body_start, 0) = push_stmt_list ();
3655 }
3656
3657 /* We can be presented with a function that currently has no outer bind
3658 expression. We will insert bind scopes in expanding await expressions,
3659 and therefore need a top level to the tree, so synthesize an outer bind
3660 expression and scope. */
3661 tree check_bind = expr_first (fnbody);
3662 if (check_bind && TREE_CODE (check_bind) != BIND_EXPR)
3663 {
3664 tree update_body = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3665 tree blk = make_node (BLOCK);
3666 gcc_checking_assert (!coro_body_contains_bind_expr_p (&fnbody));
3667 BIND_EXPR_BLOCK (update_body) = blk;
3668 if (TREE_CODE (fnbody) == STATEMENT_LIST)
3669 BIND_EXPR_BODY (update_body) = fnbody;
3670 else
3671 {
3672 tree tlist = NULL_TREE;
3673 append_to_statement_list_force (fnbody, &tlist);
3674 TREE_SIDE_EFFECTS (tlist) = TREE_SIDE_EFFECTS (fnbody);
3675 BIND_EXPR_BODY (update_body) = tlist;
3676 }
3677 tree new_body_list = NULL_TREE;
3678 TREE_SIDE_EFFECTS (update_body) = true;
3679 append_to_statement_list (update_body, &new_body_list);
3680 TREE_SIDE_EFFECTS (new_body_list) = true;
3681 fnbody = new_body_list;
3682 }
3683
3684 /* Create the coro frame type, as far as it can be known at this stage.
3685 1. Types we already know. */
3686
3687 tree fn_return_type = TREE_TYPE (TREE_TYPE (orig));
3688 tree handle_type = get_coroutine_handle_type (orig);
3689 tree promise_type = get_coroutine_promise_type (orig);
3690
3691 /* 2. Types we need to define or look up. */
3692
3693 /* We need to know, and inspect, each suspend point in the function
3694 in several places. It's convenient to place this map out of line
3695 since it's used from tree walk callbacks. */
3696 suspend_points = new hash_map<tree, suspend_point_info>;
3697
3698 /* Initial and final suspend types are special in that the co_awaits for
3699 them are synthetic. We need to find the type for each awaiter from
3700 the coroutine promise. */
3701 tree initial_await = build_init_or_final_await (fn_start, false);
3702 if (initial_await == error_mark_node)
3703 {
3704 /* Suppress warnings about the missing return value. */
3705 TREE_NO_WARNING (orig) = true;
3706 return false;
3707 }
3708 /* The type of the frame var for this is the type of its temp proxy. */
3709 tree initial_suspend_type = TREE_TYPE (TREE_OPERAND (initial_await, 1));
3710
3711 tree final_await = build_init_or_final_await (fn_start, true);
3712 if (final_await == error_mark_node)
3713 {
3714 /* Suppress warnings about the missing return value. */
3715 TREE_NO_WARNING (orig) = true;
3716 return false;
3717 }
3718
3719 /* The type of the frame var for this is the type of its temp proxy. */
3720 tree final_suspend_type = TREE_TYPE (TREE_OPERAND (final_await, 1));
3721
3722 tree fr_name = get_fn_local_identifier (orig, "frame");
3723 tree coro_frame_type = xref_tag (record_type, fr_name, ts_current, false);
3724 DECL_CONTEXT (TYPE_NAME (coro_frame_type)) = current_scope ();
3725 tree coro_frame_ptr = build_pointer_type (coro_frame_type);
3726 tree act_des_fn_type
3727 = build_function_type_list (void_type_node, coro_frame_ptr, NULL_TREE);
3728 tree act_des_fn_ptr = build_pointer_type (act_des_fn_type);
3729
3730 /* Declare the actor and destroyer function. */
3731 tree actor = act_des_fn (orig, act_des_fn_type, coro_frame_ptr, "actor");
3732 tree destroy = act_des_fn (orig, act_des_fn_type, coro_frame_ptr, "destroy");
3733
3734 /* Build our dummy coro frame layout. */
3735 coro_frame_type = begin_class_definition (coro_frame_type);
3736
3737 tree field_list = NULL_TREE;
3738 tree resume_name
3739 = coro_make_frame_entry (&field_list, "__resume", act_des_fn_ptr, fn_start);
3740 tree destroy_name = coro_make_frame_entry (&field_list, "__destroy",
3741 act_des_fn_ptr, fn_start);
3742 tree promise_name
3743 = coro_make_frame_entry (&field_list, "__p", promise_type, fn_start);
3744 tree fnf_name = coro_make_frame_entry (&field_list, "__frame_needs_free",
3745 boolean_type_node, fn_start);
3746 tree iarc_name = coro_make_frame_entry (&field_list, "__i_a_r_c",
3747 boolean_type_node, fn_start);
3748 tree resume_idx_name
3749 = coro_make_frame_entry (&field_list, "__resume_at",
3750 short_unsigned_type_node, fn_start);
3751
3752 /* We need a handle to this coroutine, which is passed to every
3753 await_suspend(). There's no point in creating it over and over. */
3754 (void) coro_make_frame_entry (&field_list, "__self_h", handle_type, fn_start);
3755
3756 /* Now add in fields for function params (if there are any).
3757 We do not attempt elision of copies at this stage, we do analyse the
3758 uses and build worklists to replace those when the state machine is
3759 lowered. */
3760
3761 hash_map<tree, param_info> *param_uses = NULL;
3762 if (DECL_ARGUMENTS (orig))
3763 {
3764 /* Build a hash map with an entry for each param.
3765 The key is the param tree.
3766 Then we have an entry for the frame field name.
3767 Then a cache for the field ref when we come to use it.
3768 Then a tree list of the uses.
3769 The second two entries start out empty - and only get populated
3770 when we see uses. */
3771 param_uses = new hash_map<tree, param_info>;
3772 bool lambda_p = LAMBDA_FUNCTION_P (orig);
3773
3774 unsigned no_name_parm = 0;
3775 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
3776 arg = DECL_CHAIN (arg))
3777 {
3778 bool existed;
3779 param_info &parm = param_uses->get_or_insert (arg, &existed);
3780 gcc_checking_assert (!existed);
3781 parm.body_uses = NULL;
3782 tree actual_type = TREE_TYPE (arg);
3783 actual_type = complete_type_or_else (actual_type, orig);
3784 if (actual_type == NULL_TREE)
3785 actual_type = error_mark_node;
3786 parm.orig_type = actual_type;
3787 parm.by_ref = parm.pt_ref = false;
3788 if (TREE_CODE (actual_type) == REFERENCE_TYPE)
3789 {
3790 /* If the user passes by reference, then we will save the
3791 pointer to the original. As noted in
3792 [dcl.fct.def.coroutine] / 13, if the lifetime of the
3793 referenced item ends and then the coroutine is resumed,
3794 we have UB; well, the user asked for it. */
3795 actual_type = build_pointer_type (TREE_TYPE (actual_type));
3796 parm.pt_ref = true;
3797 }
3798 else if (TYPE_REF_P (DECL_ARG_TYPE (arg)))
3799 parm.by_ref = true;
3800
3801 parm.frame_type = actual_type;
3802
3803 parm.this_ptr = is_this_parameter (arg);
3804 /* See PR94807. When a lambda is in a template instantiation, the
3805 closure object is named 'this' instead of '__closure'. */
3806 if (lambda_p)
3807 {
3808 parm.lambda_cobj = DECL_NAME (arg) == closure_identifier;
3809 gcc_checking_assert (!parm.this_ptr);
3810 }
3811 else
3812 parm.lambda_cobj = false;
3813
3814 parm.trivial_dtor = TYPE_HAS_TRIVIAL_DESTRUCTOR (parm.frame_type);
3815 char *buf;
3816 if (DECL_NAME (arg))
3817 {
3818 tree pname = DECL_NAME (arg);
3819 buf = xasprintf ("__parm.%s", IDENTIFIER_POINTER (pname));
3820 }
3821 else
3822 buf = xasprintf ("__unnamed_parm.%d", no_name_parm++);
3823 parm.field_id = coro_make_frame_entry
3824 (&field_list, buf, actual_type, DECL_SOURCE_LOCATION (arg));
3825 free (buf);
3826 }
3827
3828 /* We want to record every instance of param's use, so don't include
3829 a 'visited' hash_set on the tree walk, but only record a containing
3830 expression once. */
3831 hash_set<tree *> visited;
3832 param_frame_data param_data
3833 = {&field_list, param_uses, &visited, fn_start, false};
3834 cp_walk_tree (&fnbody, register_param_uses, &param_data, NULL);
3835 }
3836
3837 /* Initial suspend is mandated. */
3838 tree init_susp_name = coro_make_frame_entry (&field_list, "__aw_s.is",
3839 initial_suspend_type, fn_start);
3840
3841 register_await_info (initial_await, initial_suspend_type, init_susp_name);
3842
3843 /* Now insert the data for any body await points, at this time we also need
3844 to promote any temporaries that are captured by reference (to regular
3845 vars) they will get added to the coro frame along with other locals. */
3846 susp_frame_data body_aw_points
3847 = {&field_list, handle_type, NULL, NULL, 0, 0,
3848 hash_set<tree> (), NULL, NULL, 0, false, false};
3849 body_aw_points.block_stack = make_tree_vector ();
3850 body_aw_points.bind_stack = make_tree_vector ();
3851 body_aw_points.to_replace = make_tree_vector ();
3852 cp_walk_tree (&fnbody, await_statement_walker, &body_aw_points, NULL);
3853
3854 /* Final suspend is mandated. */
3855 tree fin_susp_name = coro_make_frame_entry (&field_list, "__aw_s.fs",
3856 final_suspend_type, fn_start);
3857
3858 register_await_info (final_await, final_suspend_type, fin_susp_name);
3859
3860 /* 4. Now make space for local vars, this is conservative again, and we
3861 would expect to delete unused entries later. */
3862 hash_map<tree, local_var_info> local_var_uses;
3863 local_vars_frame_data local_vars_data
3864 = {&field_list, &local_var_uses, 0, 0, fn_start, false, false};
3865 cp_walk_tree (&fnbody, register_local_var_uses, &local_vars_data, NULL);
3866
3867 /* Tie off the struct for now, so that we can build offsets to the
3868 known entries. */
3869 TYPE_FIELDS (coro_frame_type) = field_list;
3870 TYPE_BINFO (coro_frame_type) = make_tree_binfo (0);
3871 BINFO_OFFSET (TYPE_BINFO (coro_frame_type)) = size_zero_node;
3872 BINFO_TYPE (TYPE_BINFO (coro_frame_type)) = coro_frame_type;
3873
3874 coro_frame_type = finish_struct (coro_frame_type, NULL_TREE);
3875
3876 /* Ramp: */
3877 /* Now build the ramp function pieces. */
3878 tree ramp_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3879 add_stmt (ramp_bind);
3880 tree ramp_body = push_stmt_list ();
3881
3882 tree coro_fp = build_lang_decl (VAR_DECL, get_identifier ("coro.frameptr"),
3883 coro_frame_ptr);
3884 tree varlist = coro_fp;
3885
3886 /* Collected the scope vars we need ... only one for now. */
3887 BIND_EXPR_VARS (ramp_bind) = nreverse (varlist);
3888
3889 /* We're now going to create a new top level scope block for the ramp
3890 function. */
3891 tree top_block = make_node (BLOCK);
3892
3893 BIND_EXPR_BLOCK (ramp_bind) = top_block;
3894 BLOCK_VARS (top_block) = BIND_EXPR_VARS (ramp_bind);
3895 BLOCK_SUBBLOCKS (top_block) = NULL_TREE;
3896
3897 /* The decl_expr for the coro frame pointer, initialize to zero so that we
3898 can pass it to the IFN_CO_FRAME (since there's no way to pass a type,
3899 directly apparently). This avoids a "used uninitialized" warning. */
3900 tree zeroinit = build1 (CONVERT_EXPR, coro_frame_ptr, integer_zero_node);
3901 DECL_INITIAL (coro_fp) = zeroinit;
3902 add_decl_expr (coro_fp);
3903
3904 /* The CO_FRAME internal function is a mechanism to allow the middle end
3905 to adjust the allocation in response to optimisations. We provide the
3906 current conservative estimate of the frame size (as per the current)
3907 computed layout. */
3908 tree frame_size = TYPE_SIZE_UNIT (coro_frame_type);
3909 tree resizeable
3910 = build_call_expr_internal_loc (fn_start, IFN_CO_FRAME, size_type_node, 2,
3911 frame_size, coro_fp);
3912
3913 /* [dcl.fct.def.coroutine] / 10 (part1)
3914 The unqualified-id get_return_object_on_allocation_failure is looked up
3915 in the scope of the promise type by class member access lookup. */
3916
3917 tree grooaf_meth
3918 = lookup_promise_method (orig, coro_gro_on_allocation_fail_identifier,
3919 fn_start, /*musthave=*/false);
3920
3921 tree grooaf = NULL_TREE;
3922 tree dummy_promise = build_dummy_object (get_coroutine_promise_type (orig));
3923
3924 /* We don't require this, so lookup_promise_method can return NULL... */
3925 if (grooaf_meth && BASELINK_P (grooaf_meth))
3926 {
3927 /* ... but, if the lookup succeeds, then the function must be
3928 usable.
3929 build_new_method_call () wants a valid pointer to (an empty) args
3930 list in this case. */
3931 vec<tree, va_gc> *args = make_tree_vector ();
3932 grooaf = build_new_method_call (dummy_promise, grooaf_meth, &args,
3933 NULL_TREE, LOOKUP_NORMAL, NULL,
3934 tf_warning_or_error);
3935 release_tree_vector (args);
3936 }
3937
3938 /* Allocate the frame, this has several possibilities:
3939 [dcl.fct.def.coroutine] / 9 (part 1)
3940 The allocation function’s name is looked up in the scope of the promise
3941 type. It's not a failure for it to be absent see part 4, below. */
3942 tree nwname = ovl_op_identifier (false, NEW_EXPR);
3943 tree fns = lookup_promise_method (orig, nwname, fn_start,
3944 /*musthave=*/false);
3945 tree new_fn = NULL_TREE;
3946 if (fns && BASELINK_P (fns))
3947 {
3948 /* [dcl.fct.def.coroutine] / 9 (part 2)
3949 If the lookup finds an allocation function in the scope of the promise
3950 type, overload resolution is performed on a function call created by
3951 assembling an argument list. The first argument is the amount of space
3952 requested, and has type std::size_t. The succeeding arguments are
3953 those of the original function. */
3954 vec<tree, va_gc> *args = make_tree_vector ();
3955 vec_safe_push (args, resizeable); /* Space needed. */
3956
3957 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
3958 arg = DECL_CHAIN (arg))
3959 {
3960 param_info *parm_i = param_uses->get (arg);
3961 gcc_checking_assert (parm_i);
3962 if (parm_i->lambda_cobj)
3963 vec_safe_push (args, arg);
3964 else if (parm_i->this_ptr)
3965 {
3966 /* We pass a reference to *this to the allocator lookup. */
3967 tree tt = TREE_TYPE (TREE_TYPE (arg));
3968 tree this_ref = build1 (INDIRECT_REF, tt, arg);
3969 tt = cp_build_reference_type (tt, false);
3970 this_ref = convert_to_reference (tt, this_ref, CONV_STATIC,
3971 LOOKUP_NORMAL , NULL_TREE,
3972 tf_warning_or_error);
3973 vec_safe_push (args, this_ref);
3974 }
3975 else
3976 vec_safe_push (args, arg);
3977 }
3978
3979 /* We might need to check that the provided function is nothrow. */
3980 tree func;
3981 /* Failure is OK for the first attempt. */
3982 new_fn = build_new_method_call (dummy_promise, fns, &args, NULL,
3983 LOOKUP_NORMAL, &func, tf_none);
3984 release_tree_vector (args);
3985
3986 if (!new_fn || new_fn == error_mark_node)
3987 {
3988 /* [dcl.fct.def.coroutine] / 9 (part 3)
3989 If no viable function is found, overload resolution is performed
3990 again on a function call created by passing just the amount of
3991 space required as an argument of type std::size_t. */
3992 args = make_tree_vector ();
3993 vec_safe_push (args, resizeable); /* Space needed. */
3994 new_fn = build_new_method_call (dummy_promise, fns, &args,
3995 NULL_TREE, LOOKUP_NORMAL, &func,
3996 tf_none);
3997 release_tree_vector (args);
3998 }
3999
4000 /* However, if the initial lookup succeeded, then one of these two
4001 options must be available. */
4002 if (!new_fn || new_fn == error_mark_node)
4003 {
4004 error_at (fn_start, "%qE is provided by %qT but is not usable with"
4005 " the function signature %qD", nwname, promise_type, orig);
4006 new_fn = error_mark_node;
4007 }
4008 else if (grooaf && !TYPE_NOTHROW_P (TREE_TYPE (func)))
4009 error_at (fn_start, "%qE is provided by %qT but %qE is not marked"
4010 " %<throw()%> or %<noexcept%>", grooaf, promise_type, nwname);
4011 }
4012 else
4013 {
4014 /* [dcl.fct.def.coroutine] / 9 (part 4)
4015 If this lookup fails, the allocation function’s name is looked up in
4016 the global scope. */
4017
4018 vec<tree, va_gc> *args;
4019 /* build_operator_new_call () will insert size needed as element 0 of
4020 this, and we might need to append the std::nothrow constant. */
4021 vec_alloc (args, 2);
4022
4023 if (grooaf)
4024 {
4025 /* [dcl.fct.def.coroutine] / 10 (part 2)
4026 If any declarations (of the get return on allocation fail) are
4027 found, then the result of a call to an allocation function used
4028 to obtain storage for the coroutine state is assumed to return
4029 nullptr if it fails to obtain storage and, if a global allocation
4030 function is selected, the ::operator new(size_t, nothrow_t) form
4031 is used. The allocation function used in this case shall have a
4032 non-throwing noexcept-specification. So we need std::nothrow. */
4033 tree std_nt = lookup_qualified_name (std_node,
4034 get_identifier ("nothrow"),
4035 0, /*complain=*/true, false);
4036 vec_safe_push (args, std_nt);
4037 }
4038
4039 /* If we get to this point, we must succeed in looking up the global
4040 operator new for the params provided. Extract a simplified version
4041 of the machinery from build_operator_new_call. This can update the
4042 frame size. */
4043 tree cookie = NULL;
4044 new_fn = build_operator_new_call (nwname, &args, &frame_size, &cookie,
4045 /*align_arg=*/NULL,
4046 /*size_check=*/NULL, /*fn=*/NULL,
4047 tf_warning_or_error);
4048 resizeable = build_call_expr_internal_loc
4049 (fn_start, IFN_CO_FRAME, size_type_node, 2, frame_size, coro_fp);
4050 CALL_EXPR_ARG (new_fn, 0) = resizeable;
4051
4052 release_tree_vector (args);
4053 }
4054
4055 tree allocated = build1 (CONVERT_EXPR, coro_frame_ptr, new_fn);
4056 tree r = build2 (INIT_EXPR, TREE_TYPE (coro_fp), coro_fp, allocated);
4057 r = coro_build_cvt_void_expr_stmt (r, fn_start);
4058 add_stmt (r);
4059
4060 /* If the user provided a method to return an object on alloc fail, then
4061 check the returned pointer and call the func if it's null.
4062 Otherwise, no check, and we fail for noexcept/fno-exceptions cases. */
4063
4064 if (grooaf)
4065 {
4066 /* [dcl.fct.def.coroutine] / 10 (part 3)
4067 If the allocation function returns nullptr,the coroutine returns
4068 control to the caller of the coroutine and the return value is
4069 obtained by a call to T::get_return_object_on_allocation_failure(),
4070 where T is the promise type. */
4071
4072 gcc_checking_assert (same_type_p (fn_return_type, TREE_TYPE (grooaf)));
4073 tree if_stmt = begin_if_stmt ();
4074 tree cond = build1 (CONVERT_EXPR, coro_frame_ptr, integer_zero_node);
4075 cond = build2 (EQ_EXPR, boolean_type_node, coro_fp, cond);
4076 finish_if_stmt_cond (cond, if_stmt);
4077 if (VOID_TYPE_P (fn_return_type))
4078 {
4079 /* Execute the get-return-object-on-alloc-fail call... */
4080 finish_expr_stmt (grooaf);
4081 /* ... but discard the result, since we return void. */
4082 finish_return_stmt (NULL_TREE);
4083 }
4084 else
4085 {
4086 /* Get the fallback return object. */
4087 r = build_cplus_new (fn_return_type, grooaf, tf_warning_or_error);
4088 finish_return_stmt (r);
4089 }
4090 finish_then_clause (if_stmt);
4091 finish_if_stmt (if_stmt);
4092 }
4093
4094 /* deref the frame pointer, to use in member access code. */
4095 tree deref_fp = build_x_arrow (fn_start, coro_fp, tf_warning_or_error);
4096
4097 /* For now, once allocation has succeeded we always assume that this needs
4098 destruction, there's no impl. for frame allocation elision. */
4099 tree fnf_m
4100 = lookup_member (coro_frame_type, fnf_name, 1, 0, tf_warning_or_error);
4101 tree fnf_x = build_class_member_access_expr (deref_fp, fnf_m, NULL_TREE,
4102 false, tf_warning_or_error);
4103 r = build2 (INIT_EXPR, boolean_type_node, fnf_x, boolean_true_node);
4104 r = coro_build_cvt_void_expr_stmt (r, fn_start);
4105 add_stmt (r);
4106
4107 /* Put the resumer and destroyer functions in. */
4108
4109 tree actor_addr = build1 (ADDR_EXPR, act_des_fn_ptr, actor);
4110 tree resume_m
4111 = lookup_member (coro_frame_type, resume_name,
4112 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
4113 tree resume_x = build_class_member_access_expr (deref_fp, resume_m, NULL_TREE,
4114 false, tf_warning_or_error);
4115 r = build2_loc (fn_start, INIT_EXPR, act_des_fn_ptr, resume_x, actor_addr);
4116 r = coro_build_cvt_void_expr_stmt (r, fn_start);
4117 add_stmt (r);
4118
4119 tree destroy_addr = build1 (ADDR_EXPR, act_des_fn_ptr, destroy);
4120 tree destroy_m
4121 = lookup_member (coro_frame_type, destroy_name,
4122 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
4123 tree destroy_x
4124 = build_class_member_access_expr (deref_fp, destroy_m, NULL_TREE, false,
4125 tf_warning_or_error);
4126 r = build2_loc (fn_start, INIT_EXPR, act_des_fn_ptr, destroy_x, destroy_addr);
4127 r = coro_build_cvt_void_expr_stmt (r, fn_start);
4128 add_stmt (r);
4129
4130 /* [dcl.fct.def.coroutine] /13
4131 When a coroutine is invoked, a copy is created for each coroutine
4132 parameter. Each such copy is an object with automatic storage duration
4133 that is direct-initialized from an lvalue referring to the corresponding
4134 parameter if the parameter is an lvalue reference, and from an xvalue
4135 referring to it otherwise. A reference to a parameter in the function-
4136 body of the coroutine and in the call to the coroutine promise
4137 constructor is replaced by a reference to its copy. */
4138
4139 vec<tree, va_gc> *promise_args = NULL; /* So that we can adjust refs. */
4140
4141 /* The initialization and destruction of each parameter copy occurs in the
4142 context of the called coroutine. Initializations of parameter copies are
4143 sequenced before the call to the coroutine promise constructor and
4144 indeterminately sequenced with respect to each other. The lifetime of
4145 parameter copies ends immediately after the lifetime of the coroutine
4146 promise object ends. */
4147
4148 vec<tree, va_gc> *param_dtor_list = NULL;
4149
4150 if (DECL_ARGUMENTS (orig))
4151 {
4152 promise_args = make_tree_vector ();
4153 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
4154 arg = DECL_CHAIN (arg))
4155 {
4156 bool existed;
4157 param_info &parm = param_uses->get_or_insert (arg, &existed);
4158
4159 tree fld_ref = lookup_member (coro_frame_type, parm.field_id,
4160 /*protect=*/1, /*want_type=*/0,
4161 tf_warning_or_error);
4162 tree fld_idx
4163 = build_class_member_access_expr (deref_fp, fld_ref, NULL_TREE,
4164 false, tf_warning_or_error);
4165
4166 /* Add this to the promise CTOR arguments list, accounting for
4167 refs and special handling for method this ptr. */
4168 if (parm.lambda_cobj)
4169 vec_safe_push (promise_args, arg);
4170 else if (parm.this_ptr)
4171 {
4172 /* We pass a reference to *this to the param preview. */
4173 tree tt = TREE_TYPE (arg);
4174 gcc_checking_assert (POINTER_TYPE_P (tt));
4175 tree ct = TREE_TYPE (tt);
4176 tree this_ref = build1 (INDIRECT_REF, ct, arg);
4177 tree rt = cp_build_reference_type (ct, false);
4178 this_ref = convert_to_reference (rt, this_ref, CONV_STATIC,
4179 LOOKUP_NORMAL , NULL_TREE,
4180 tf_warning_or_error);
4181 vec_safe_push (promise_args, this_ref);
4182 }
4183 else if (parm.by_ref)
4184 vec_safe_push (promise_args, fld_idx);
4185 else
4186 vec_safe_push (promise_args, arg);
4187
4188 if (TYPE_NEEDS_CONSTRUCTING (parm.frame_type))
4189 {
4190 vec<tree, va_gc> *p_in;
4191 if (CLASS_TYPE_P (parm.frame_type)
4192 && classtype_has_non_deleted_move_ctor (parm.frame_type))
4193 p_in = make_tree_vector_single (move (arg));
4194 else if (lvalue_p (arg))
4195 p_in = make_tree_vector_single (rvalue (arg));
4196 else
4197 p_in = make_tree_vector_single (arg);
4198 /* Construct in place or move as relevant. */
4199 r = build_special_member_call (fld_idx, complete_ctor_identifier,
4200 &p_in, parm.frame_type,
4201 LOOKUP_NORMAL,
4202 tf_warning_or_error);
4203 release_tree_vector (p_in);
4204 }
4205 else
4206 {
4207 if (!same_type_p (parm.frame_type, DECL_ARG_TYPE (arg)))
4208 r = build1_loc (DECL_SOURCE_LOCATION (arg), CONVERT_EXPR,
4209 parm.frame_type, arg);
4210 else
4211 r = arg;
4212 r = build_modify_expr (fn_start, fld_idx, parm.frame_type,
4213 INIT_EXPR, DECL_SOURCE_LOCATION (arg), r,
4214 TREE_TYPE (r));
4215 }
4216 r = coro_build_cvt_void_expr_stmt (r, fn_start);
4217 add_stmt (r);
4218 if (!parm.trivial_dtor)
4219 {
4220 if (param_dtor_list == NULL)
4221 param_dtor_list = make_tree_vector ();
4222 vec_safe_push (param_dtor_list, parm.field_id);
4223 }
4224 }
4225 }
4226
4227 /* Set up the promise. */
4228 tree promise_m
4229 = lookup_member (coro_frame_type, promise_name,
4230 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
4231
4232 tree p = build_class_member_access_expr (deref_fp, promise_m, NULL_TREE,
4233 false, tf_warning_or_error);
4234
4235 if (TYPE_NEEDS_CONSTRUCTING (promise_type))
4236 {
4237 /* Do a placement new constructor for the promise type (we never call
4238 the new operator, just the constructor on the object in place in the
4239 frame).
4240
4241 First try to find a constructor with the same parameter list as the
4242 original function (if it has params), failing that find a constructor
4243 with no parameter list. */
4244
4245 if (DECL_ARGUMENTS (orig))
4246 {
4247 r = build_special_member_call (p, complete_ctor_identifier,
4248 &promise_args, promise_type,
4249 LOOKUP_NORMAL, tf_none);
4250 release_tree_vector (promise_args);
4251 }
4252 else
4253 r = NULL_TREE;
4254
4255 if (r == NULL_TREE || r == error_mark_node)
4256 r = build_special_member_call (p, complete_ctor_identifier, NULL,
4257 promise_type, LOOKUP_NORMAL,
4258 tf_warning_or_error);
4259
4260 r = coro_build_cvt_void_expr_stmt (r, fn_start);
4261 add_stmt (r);
4262 }
4263
4264 /* Set up a new bind context for the GRO. */
4265 tree gro_context_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4266 /* Make and connect the scope blocks. */
4267 tree gro_block = make_node (BLOCK);
4268 BLOCK_SUPERCONTEXT (gro_block) = top_block;
4269 BLOCK_SUBBLOCKS (top_block) = gro_block;
4270 BIND_EXPR_BLOCK (gro_context_bind) = gro_block;
4271 add_stmt (gro_context_bind);
4272
4273 tree gro_meth = lookup_promise_method (orig,
4274 coro_get_return_object_identifier,
4275 fn_start, /*musthave=*/true );
4276 tree get_ro
4277 = build_new_method_call (p, gro_meth, NULL, NULL_TREE, LOOKUP_NORMAL, NULL,
4278 tf_warning_or_error);
4279 /* Without a return object we haven't got much clue what's going on. */
4280 if (get_ro == error_mark_node)
4281 {
4282 BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
4283 DECL_SAVED_TREE (orig) = newbody;
4284 /* Suppress warnings about the missing return value. */
4285 TREE_NO_WARNING (orig) = true;
4286 return false;
4287 }
4288
4289 tree gro_context_body = push_stmt_list ();
4290 bool gro_is_void_p = VOID_TYPE_P (TREE_TYPE (get_ro));
4291
4292 tree gro = NULL_TREE;
4293 tree gro_bind_vars = NULL_TREE;
4294 /* We have to sequence the call to get_return_object before initial
4295 suspend. */
4296 if (gro_is_void_p)
4297 finish_expr_stmt (get_ro);
4298 else
4299 {
4300 gro = build_lang_decl (VAR_DECL, get_identifier ("coro.gro"),
4301 TREE_TYPE (get_ro));
4302 DECL_CONTEXT (gro) = current_scope ();
4303 DECL_ARTIFICIAL (gro) = true;
4304 DECL_IGNORED_P (gro) = true;
4305 add_decl_expr (gro);
4306 gro_bind_vars = gro;
4307
4308 r = build2_loc (fn_start, INIT_EXPR, TREE_TYPE (gro), gro, get_ro);
4309 r = coro_build_cvt_void_expr_stmt (r, fn_start);
4310 add_stmt (r);
4311 }
4312
4313 /* Initialize the resume_idx_name to 0, meaning "not started". */
4314 tree resume_idx_m
4315 = lookup_member (coro_frame_type, resume_idx_name,
4316 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
4317 tree resume_idx
4318 = build_class_member_access_expr (deref_fp, resume_idx_m, NULL_TREE, false,
4319 tf_warning_or_error);
4320 r = build_int_cst (short_unsigned_type_node, 0);
4321 r = build2_loc (fn_start, INIT_EXPR, short_unsigned_type_node, resume_idx, r);
4322 r = coro_build_cvt_void_expr_stmt (r, fn_start);
4323 add_stmt (r);
4324
4325 /* Initialize 'initial-await-resume-called' as per
4326 [dcl.fct.def.coroutine] / 5.3 */
4327 tree i_a_r_c_m
4328 = lookup_member (coro_frame_type, iarc_name, 1, 0, tf_warning_or_error);
4329 tree i_a_r_c = build_class_member_access_expr (deref_fp, i_a_r_c_m,
4330 NULL_TREE, false,
4331 tf_warning_or_error);
4332 r = build2 (INIT_EXPR, boolean_type_node, i_a_r_c, boolean_false_node);
4333 r = coro_build_cvt_void_expr_stmt (r, fn_start);
4334 add_stmt (r);
4335
4336 /* So .. call the actor .. */
4337 r = build_call_expr_loc (fn_start, actor, 1, coro_fp);
4338 r = maybe_cleanup_point_expr_void (r);
4339 add_stmt (r);
4340
4341 /* Switch to using 'input_location' as the loc, since we're now more
4342 logically doing things related to the end of the function. */
4343
4344 /* The ramp is done, we just need the return value. */
4345 if (!same_type_p (TREE_TYPE (get_ro), fn_return_type))
4346 {
4347 /* construct the return value with a single GRO param, if it's not
4348 void. */
4349 vec<tree, va_gc> *args = NULL;
4350 vec<tree, va_gc> **arglist = NULL;
4351 if (!gro_is_void_p)
4352 {
4353 args = make_tree_vector_single (gro);
4354 arglist = &args;
4355 }
4356 r = build_special_member_call (NULL_TREE,
4357 complete_ctor_identifier, arglist,
4358 fn_return_type, LOOKUP_NORMAL,
4359 tf_warning_or_error);
4360 r = build_cplus_new (fn_return_type, r, tf_warning_or_error);
4361 }
4362 else if (!gro_is_void_p)
4363 r = rvalue (gro); /* The GRO is the return value. */
4364 else
4365 r = NULL_TREE;
4366
4367 finish_return_stmt (r);
4368
4369 /* Finish up the ramp function. */
4370 BIND_EXPR_VARS (gro_context_bind) = gro_bind_vars;
4371 BIND_EXPR_BODY (gro_context_bind) = pop_stmt_list (gro_context_body);
4372 TREE_SIDE_EFFECTS (gro_context_bind) = true;
4373 BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
4374 TREE_SIDE_EFFECTS (ramp_bind) = true;
4375
4376 /* We know the "real" promise and have a frame layout with a slot for each
4377 suspend point, so we can build an actor function (which contains the
4378 functionality for both 'resume' and 'destroy').
4379
4380 wrap the function body in a try {} catch (...) {} block, if exceptions
4381 are enabled. */
4382
4383 /* First make a new block for the body - that will be embedded in the
4384 re-written function. */
4385 tree first = expr_first (fnbody);
4386 bool orig_fn_has_outer_bind = false;
4387 tree replace_blk = NULL_TREE;
4388 if (first && TREE_CODE (first) == BIND_EXPR)
4389 {
4390 orig_fn_has_outer_bind = true;
4391 tree block = BIND_EXPR_BLOCK (first);
4392 replace_blk = make_node (BLOCK);
4393 if (block) /* missing block is probably an error. */
4394 {
4395 gcc_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
4396 gcc_assert (BLOCK_CHAIN (block) == NULL_TREE);
4397 BLOCK_VARS (replace_blk) = BLOCK_VARS (block);
4398 BLOCK_SUBBLOCKS (replace_blk) = BLOCK_SUBBLOCKS (block);
4399 for (tree b = BLOCK_SUBBLOCKS (replace_blk); b; b = BLOCK_CHAIN (b))
4400 BLOCK_SUPERCONTEXT (b) = replace_blk;
4401 }
4402 BIND_EXPR_BLOCK (first) = replace_blk;
4403 }
4404
4405 /* actor's version of the promise. */
4406 tree actor_frame = build1_loc (fn_start, INDIRECT_REF, coro_frame_type,
4407 DECL_ARGUMENTS (actor));
4408 tree ap_m = lookup_member (coro_frame_type, get_identifier ("__p"), 1, 0,
4409 tf_warning_or_error);
4410 tree ap = build_class_member_access_expr (actor_frame, ap_m, NULL_TREE,
4411 false, tf_warning_or_error);
4412
4413 /* Now we've built the promise etc, process fnbody for co_returns.
4414 We want the call to return_void () below and it has no params so
4415 we can create it once here.
4416 Calls to return_value () will have to be checked and created as
4417 required. */
4418
4419 tree return_void = NULL_TREE;
4420 tree rvm
4421 = lookup_promise_method (orig, coro_return_void_identifier, fn_start,
4422 /*musthave=*/false);
4423 if (rvm && rvm != error_mark_node)
4424 return_void
4425 = build_new_method_call (ap, rvm, NULL, NULL_TREE, LOOKUP_NORMAL, NULL,
4426 tf_warning_or_error);
4427
4428 /* [stmt.return.coroutine] (2.2 : 3) if p.return_void() is a valid
4429 expression, flowing off the end of a coroutine is equivalent to
4430 co_return; otherwise UB.
4431 We just inject the call to p.return_void() here, and fall through to
4432 the final_suspend: label (eliding the goto). If the function body has
4433 a co_return, then this statement will be unreachable and DCEd. */
4434 if (return_void != NULL_TREE)
4435 {
4436 tree append = push_stmt_list ();
4437 add_stmt (fnbody);
4438 add_stmt (return_void);
4439 fnbody = pop_stmt_list(append);
4440 }
4441
4442 if (flag_exceptions)
4443 {
4444 tree ueh_meth
4445 = lookup_promise_method (orig, coro_unhandled_exception_identifier,
4446 fn_start, /*musthave=*/true);
4447 /* Build promise.unhandled_exception(); */
4448 tree ueh
4449 = build_new_method_call (ap, ueh_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
4450 NULL, tf_warning_or_error);
4451
4452 /* The try block is just the original function, there's no real
4453 need to call any function to do this. */
4454 fnbody = build_stmt (fn_start, TRY_BLOCK, fnbody, NULL_TREE);
4455 TRY_HANDLERS (fnbody) = push_stmt_list ();
4456 /* Mimic what the parser does for the catch. */
4457 tree handler = begin_handler ();
4458 finish_handler_parms (NULL_TREE, handler); /* catch (...) */
4459
4460 /* Get the initial await resume called value. */
4461 tree i_a_r_c = build_class_member_access_expr (actor_frame, i_a_r_c_m,
4462 NULL_TREE, false,
4463 tf_warning_or_error);
4464 tree not_iarc_if = begin_if_stmt ();
4465 tree not_iarc = build1_loc (fn_start, TRUTH_NOT_EXPR,
4466 boolean_type_node, i_a_r_c);
4467 finish_if_stmt_cond (not_iarc, not_iarc_if);
4468 /* If the initial await resume called value is false, rethrow... */
4469 tree rethrow = build_throw (fn_start, NULL_TREE);
4470 TREE_NO_WARNING (rethrow) = true;
4471 finish_expr_stmt (rethrow);
4472 finish_then_clause (not_iarc_if);
4473 tree iarc_scope = IF_SCOPE (not_iarc_if);
4474 IF_SCOPE (not_iarc_if) = NULL;
4475 not_iarc_if = do_poplevel (iarc_scope);
4476 add_stmt (not_iarc_if);
4477 /* ... else call the promise unhandled exception method. */
4478 ueh = maybe_cleanup_point_expr_void (ueh);
4479 add_stmt (ueh);
4480 finish_handler (handler);
4481 TRY_HANDLERS (fnbody) = pop_stmt_list (TRY_HANDLERS (fnbody));
4482 /* If the function starts with a BIND_EXPR, then we need to create
4483 one here to contain the try-catch and to link up the scopes. */
4484 if (orig_fn_has_outer_bind)
4485 {
4486 fnbody = build3 (BIND_EXPR, void_type_node, NULL, fnbody, NULL);
4487 /* Make and connect the scope blocks. */
4488 tree tcb_block = make_node (BLOCK);
4489 /* .. and connect it here. */
4490 BLOCK_SUPERCONTEXT (replace_blk) = tcb_block;
4491 BLOCK_SUBBLOCKS (tcb_block) = replace_blk;
4492 BIND_EXPR_BLOCK (fnbody) = tcb_block;
4493 TREE_SIDE_EFFECTS (fnbody) = true;
4494 }
4495 }
4496 else if (pedantic)
4497 {
4498 /* We still try to look for the promise method and warn if it's not
4499 present. */
4500 tree ueh_meth
4501 = lookup_promise_method (orig, coro_unhandled_exception_identifier,
4502 fn_start, /*musthave=*/false);
4503 if (!ueh_meth || ueh_meth == error_mark_node)
4504 warning_at (fn_start, 0, "no member named %qE in %qT",
4505 coro_unhandled_exception_identifier,
4506 get_coroutine_promise_type (orig));
4507 }
4508 /* Else we don't check and don't care if the method is missing. */
4509
4510 /* Start to build the final functions.
4511
4512 We push_deferring_access_checks to avoid these routines being seen as
4513 nested by the middle end; we are doing the outlining here. */
4514
4515 push_deferring_access_checks (dk_no_check);
4516
4517 /* Build the actor... */
4518 build_actor_fn (fn_start, coro_frame_type, actor, fnbody, orig, param_uses,
4519 &local_var_uses, param_dtor_list, initial_await, final_await,
4520 body_aw_points.await_number, frame_size);
4521
4522 /* Destroyer ... */
4523 build_destroy_fn (fn_start, coro_frame_type, destroy, actor);
4524
4525 pop_deferring_access_checks ();
4526
4527 DECL_SAVED_TREE (orig) = newbody;
4528 /* Link our new functions into the list. */
4529 TREE_CHAIN (destroy) = TREE_CHAIN (orig);
4530 TREE_CHAIN (actor) = destroy;
4531 TREE_CHAIN (orig) = actor;
4532
4533 *resumer = actor;
4534 *destroyer = destroy;
4535
4536 delete suspend_points;
4537 suspend_points = NULL;
4538 return true;
4539 }
4540
4541 #include "gt-cp-coroutines.h"
4542