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