ab06c0aef54a2fd2233167769febc6dcbe61051d
[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_node = TYPE_ARG_TYPES (functyp);
300 tree argtypes = make_tree_vec (list_length (arg_node)-1);
301 unsigned p = 0;
302
303 while (arg_node != NULL_TREE && !VOID_TYPE_P (TREE_VALUE (arg_node)))
304 {
305 TREE_VEC_ELT (argtypes, p++) = TREE_VALUE (arg_node);
306 arg_node = TREE_CHAIN (arg_node);
307 }
308
309 tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK);
310 SET_ARGUMENT_PACK_ARGS (argtypepack, argtypes);
311
312 tree targ = make_tree_vec (2);
313 TREE_VEC_ELT (targ, 0) = TREE_TYPE (functyp);
314 TREE_VEC_ELT (targ, 1) = argtypepack;
315
316 tree traits_class
317 = lookup_template_class (coro_traits_templ, targ,
318 /*in_decl=*/NULL_TREE, /*context=*/NULL_TREE,
319 /*entering scope=*/false, tf_warning_or_error);
320
321 if (traits_class == error_mark_node)
322 {
323 error_at (kw, "cannot instantiate %<coroutine traits%>");
324 return NULL_TREE;
325 }
326
327 return traits_class;
328 }
329
330 /* [coroutine.handle] */
331
332 static tree
333 find_coro_handle_template_decl (location_t kw)
334 {
335 /* As for the coroutine traits, this error is per TU, so only emit
336 it once. */
337 static bool coro_handle_error_emitted = false;
338 tree handle_decl = lookup_qualified_name (std_node, coro_handle_identifier,
339 0, !coro_handle_error_emitted);
340 if (handle_decl == error_mark_node
341 || !DECL_CLASS_TEMPLATE_P (handle_decl))
342 {
343 if (!coro_handle_error_emitted)
344 error_at (kw, "coroutines require a handle class template;"
345 " cannot find %<%E::%E%>", std_node, coro_handle_identifier);
346 coro_handle_error_emitted = true;
347 return NULL_TREE;
348 }
349 else
350 return handle_decl;
351 }
352
353 /* Instantiate the handle template for a given promise type. */
354
355 static tree
356 instantiate_coro_handle_for_promise_type (location_t kw, tree promise_type)
357 {
358 /* So now build up a type list for the template, one entry, the promise. */
359 tree targ = make_tree_vec (1);
360 TREE_VEC_ELT (targ, 0) = promise_type;
361 tree handle_type
362 = lookup_template_class (coro_handle_identifier, targ,
363 /* in_decl=*/NULL_TREE,
364 /* context=*/std_node,
365 /* entering scope=*/false, tf_warning_or_error);
366
367 if (handle_type == error_mark_node)
368 {
369 error_at (kw, "cannot instantiate a %<coroutine handle%> for"
370 " promise type %qT", promise_type);
371 return NULL_TREE;
372 }
373
374 return handle_type;
375 }
376
377 /* Look for the promise_type in the instantiated traits. */
378
379 static tree
380 find_promise_type (tree traits_class)
381 {
382 tree promise_type
383 = lookup_member (traits_class, coro_promise_type_identifier,
384 /* protect=*/1, /*want_type=*/true, tf_warning_or_error);
385
386 if (promise_type)
387 promise_type
388 = complete_type_or_else (TREE_TYPE (promise_type), promise_type);
389
390 /* NULL_TREE on fail. */
391 return promise_type;
392 }
393
394 static bool
395 coro_promise_type_found_p (tree fndecl, location_t loc)
396 {
397 gcc_assert (fndecl != NULL_TREE);
398
399 if (!coro_initialized)
400 {
401 /* Trees we only need to create once.
402 Set up the identifiers we will use. */
403 coro_init_identifiers ();
404
405 /* Coroutine traits template. */
406 coro_traits_templ = find_coro_traits_template_decl (loc);
407 if (coro_traits_templ == NULL_TREE)
408 return false;
409
410 /* coroutine_handle<> template. */
411 coro_handle_templ = find_coro_handle_template_decl (loc);
412 if (coro_handle_templ == NULL_TREE)
413 return false;
414
415 /* We can also instantiate the void coroutine_handle<> */
416 void_coro_handle_type =
417 instantiate_coro_handle_for_promise_type (loc, NULL_TREE);
418 if (void_coro_handle_type == NULL_TREE)
419 return false;
420
421 /* A table to hold the state, per coroutine decl. */
422 gcc_checking_assert (coroutine_info_table == NULL);
423 coroutine_info_table =
424 hash_table<coroutine_info_hasher>::create_ggc (11);
425
426 if (coroutine_info_table == NULL)
427 return false;
428
429 coro_initialized = true;
430 }
431
432 /* Save the coroutine data on the side to avoid the overhead on every
433 function decl tree. */
434
435 coroutine_info *coro_info = get_or_insert_coroutine_info (fndecl);
436 /* Without this, we cannot really proceed. */
437 gcc_checking_assert (coro_info);
438
439 /* If we don't already have a current promise type, try to look it up. */
440 if (coro_info->promise_type == NULL_TREE)
441 {
442 /* Get the coroutine traits template class instance for the function
443 signature we have - coroutine_traits <R, ...> */
444 tree return_type = TREE_TYPE (TREE_TYPE (fndecl));
445 if (!CLASS_TYPE_P (return_type))
446 {
447 /* It makes more sense to show the function header for this, even
448 though we will have encountered it when processing a keyword.
449 Only emit the error once, not for every keyword we encounter. */
450 if (!coro_info->coro_ret_type_error_emitted)
451 error_at (DECL_SOURCE_LOCATION (fndecl), "coroutine return type"
452 " %qT is not a class", return_type);
453 coro_info->coro_ret_type_error_emitted = true;
454 return false;
455 }
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 tree overload = NULL_TREE;
700 o = build_new_op (loc, CO_AWAIT_EXPR, LOOKUP_NORMAL, a, NULL_TREE,
701 NULL_TREE, &overload, tf_warning_or_error);
702 /* If no viable functions are found, o is a. */
703 if (!o || o == error_mark_node)
704 o = a;
705 }
706 else
707 o = a; /* This is most likely about to fail anyway. */
708
709 tree o_type = TREE_TYPE (o);
710 if (o_type && !VOID_TYPE_P (o_type))
711 o_type = complete_type_or_else (o_type, o);
712
713 if (!o_type)
714 return error_mark_node;
715
716 if (TREE_CODE (o_type) != RECORD_TYPE)
717 {
718 error_at (loc, "awaitable type %qT is not a structure",
719 o_type);
720 return error_mark_node;
721 }
722
723 /* Check for required awaitable members and their types. */
724 tree awrd_meth
725 = lookup_awaitable_member (o_type, coro_await_ready_identifier, loc);
726 if (!awrd_meth || awrd_meth == error_mark_node)
727 return error_mark_node;
728 tree awsp_meth
729 = lookup_awaitable_member (o_type, coro_await_suspend_identifier, loc);
730 if (!awsp_meth || awsp_meth == error_mark_node)
731 return error_mark_node;
732
733 /* The type of the co_await is the return type of the awaitable's
734 await_resume, so we need to look that up. */
735 tree awrs_meth
736 = lookup_awaitable_member (o_type, coro_await_resume_identifier, loc);
737 if (!awrs_meth || awrs_meth == error_mark_node)
738 return error_mark_node;
739
740 /* To complete the lookups, we need an instance of 'e' which is built from
741 'o' according to [expr.await] 3.4. However, we don't want to materialize
742 'e' here (it might need to be placed in the coroutine frame) so we will
743 make a temp placeholder instead. If 'o' is a parameter or a local var,
744 then we do not need an additional var (parms and local vars are already
745 copied into the frame and will have lifetimes according to their original
746 scope). */
747 tree e_proxy = STRIP_NOPS (o);
748 if (INDIRECT_REF_P (e_proxy))
749 e_proxy = TREE_OPERAND (e_proxy, 0);
750 if (TREE_CODE (e_proxy) == PARM_DECL
751 || (TREE_CODE (e_proxy) == VAR_DECL && !DECL_ARTIFICIAL (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 tree at_fn = NULL_TREE;
876 vec<tree, va_gc> *args = make_tree_vector_single (expr);
877 a = build_new_method_call (get_coroutine_promise_proxy (
878 current_function_decl),
879 at_meth, &args, NULL_TREE, LOOKUP_NORMAL,
880 &at_fn, tf_warning_or_error);
881
882 /* As I read the section.
883 We saw an await_transform method, so it's mandatory that we replace
884 expr with p.await_transform (expr), therefore if the method call fails
885 (presumably, we don't have suitable arguments) then this part of the
886 process fails. */
887 if (!at_fn || a == error_mark_node)
888 return error_mark_node;
889 }
890
891 /* Now we want to build co_await a. */
892 tree op = build_co_await (kw, a, CO_AWAIT_SUSPEND_POINT);
893 if (op != error_mark_node)
894 {
895 TREE_SIDE_EFFECTS (op) = 1;
896 SET_EXPR_LOCATION (op, kw);
897 }
898
899 return op;
900 }
901
902 /* Take the EXPR given and attempt to build:
903 co_await p.yield_value (expr);
904 per [expr.yield] para 1. */
905
906 tree
907 finish_co_yield_expr (location_t kw, tree expr)
908 {
909 if (!expr || error_operand_p (expr))
910 return error_mark_node;
911
912 /* Check the general requirements and simple syntax errors. */
913 if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
914 "co_yield"))
915 return error_mark_node;
916
917 /* The current function has now become a coroutine, if it wasn't already. */
918 DECL_COROUTINE_P (current_function_decl) = 1;
919
920 if (processing_template_decl)
921 {
922 current_function_returns_value = 1;
923
924 if (check_for_bare_parameter_packs (expr))
925 return error_mark_node;
926
927 tree functype = TREE_TYPE (current_function_decl);
928 /* If we don't know the promise type, we can't proceed. */
929 if (dependent_type_p (functype) || type_dependent_expression_p (expr))
930 return build2_loc (kw, CO_YIELD_EXPR, unknown_type_node, expr,
931 NULL_TREE);
932 }
933
934 if (!coro_promise_type_found_p (current_function_decl, kw))
935 /* We must be able to look up the "yield_value" method in the scope of
936 the promise type, and obtain its return type. */
937 return error_mark_node;
938
939 /* The incoming expr is "e" per [expr.yield] para 1, lookup and build a
940 call for p.yield_value(e). */
941 tree y_meth = lookup_promise_method (current_function_decl,
942 coro_yield_value_identifier, kw,
943 /*musthave=*/true);
944 if (!y_meth || y_meth == error_mark_node)
945 return error_mark_node;
946
947 tree yield_fn = NULL_TREE;
948 vec<tree, va_gc> *args = make_tree_vector_single (expr);
949 tree yield_call = build_new_method_call (
950 get_coroutine_promise_proxy (current_function_decl), y_meth, &args,
951 NULL_TREE, LOOKUP_NORMAL, &yield_fn, tf_warning_or_error);
952
953 if (!yield_fn || yield_call == error_mark_node)
954 return error_mark_node;
955
956 /* So now we have the type of p.yield_value (e).
957 Now we want to build co_await p.yield_value (e).
958 Noting that for co_yield, there is no evaluation of any potential
959 promise transform_await(). */
960
961 tree op = build_co_await (kw, yield_call, CO_YIELD_SUSPEND_POINT);
962 if (op != error_mark_node)
963 {
964 op = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (op), expr, op);
965 TREE_SIDE_EFFECTS (op) = 1;
966 }
967
968 return op;
969 }
970
971 /* Check 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 the promise proxy, but saved for expand time. */
974
975 tree
976 finish_co_return_stmt (location_t kw, tree expr)
977 {
978 if (expr == error_mark_node)
979 return error_mark_node;
980
981 if (!coro_common_keyword_context_valid_p (current_function_decl, kw,
982 "co_return"))
983 return error_mark_node;
984
985 /* The current function has now become a coroutine, if it wasn't
986 already. */
987 DECL_COROUTINE_P (current_function_decl) = 1;
988
989 if (processing_template_decl)
990 {
991 current_function_returns_value = 1;
992
993 if (check_for_bare_parameter_packs (expr))
994 return error_mark_node;
995
996 tree functype = TREE_TYPE (current_function_decl);
997 /* If we don't know the promise type, we can't proceed, return the
998 expression as it is. */
999 if (dependent_type_p (functype) || type_dependent_expression_p (expr))
1000 {
1001 expr
1002 = build2_loc (kw, CO_RETURN_EXPR, void_type_node, expr, NULL_TREE);
1003 expr = maybe_cleanup_point_expr_void (expr);
1004 expr = add_stmt (expr);
1005 return expr;
1006 }
1007 }
1008
1009 if (!coro_promise_type_found_p (current_function_decl, kw))
1010 return error_mark_node;
1011
1012 if (error_operand_p (expr))
1013 return error_mark_node;
1014
1015 /* Suppress -Wreturn-type for co_return, we need to check indirectly
1016 whether the promise type has a suitable return_void/return_value. */
1017 TREE_NO_WARNING (current_function_decl) = true;
1018
1019 if (!processing_template_decl && warn_sequence_point)
1020 verify_sequence_points (expr);
1021
1022 /* If the promise object doesn't have the correct return call then
1023 there's a mis-match between the co_return <expr> and this. */
1024 tree co_ret_call = NULL_TREE;
1025 if (expr == NULL_TREE || VOID_TYPE_P (TREE_TYPE (expr)))
1026 {
1027 tree crv_meth
1028 = lookup_promise_method (current_function_decl,
1029 coro_return_void_identifier, kw,
1030 /*musthave=*/true);
1031 if (!crv_meth || crv_meth == error_mark_node)
1032 return error_mark_node;
1033
1034 co_ret_call = build_new_method_call (
1035 get_coroutine_promise_proxy (current_function_decl), crv_meth, NULL,
1036 NULL_TREE, LOOKUP_NORMAL, NULL, tf_warning_or_error);
1037 }
1038 else
1039 {
1040 tree crv_meth
1041 = lookup_promise_method (current_function_decl,
1042 coro_return_value_identifier, kw,
1043 /*musthave=*/true);
1044 if (!crv_meth || crv_meth == error_mark_node)
1045 return error_mark_node;
1046
1047 vec<tree, va_gc> *args = make_tree_vector_single (expr);
1048 co_ret_call = build_new_method_call (
1049 get_coroutine_promise_proxy (current_function_decl), crv_meth, &args,
1050 NULL_TREE, LOOKUP_NORMAL, NULL, tf_warning_or_error);
1051 }
1052
1053 /* Makes no sense for a co-routine really. */
1054 if (TREE_THIS_VOLATILE (current_function_decl))
1055 warning_at (kw, 0,
1056 "function declared %<noreturn%> has a"
1057 " %<co_return%> statement");
1058
1059 if (!co_ret_call || co_ret_call == error_mark_node)
1060 return error_mark_node;
1061
1062 expr = build2_loc (kw, CO_RETURN_EXPR, void_type_node, expr, co_ret_call);
1063 expr = maybe_cleanup_point_expr_void (expr);
1064 expr = add_stmt (expr);
1065 return expr;
1066 }
1067
1068 /* We need to validate the arguments to __builtin_coro_promise, since the
1069 second two must be constant, and the builtins machinery doesn't seem to
1070 deal with that properly. */
1071
1072 tree
1073 coro_validate_builtin_call (tree call, tsubst_flags_t)
1074 {
1075 tree fn = TREE_OPERAND (CALL_EXPR_FN (call), 0);
1076
1077 gcc_checking_assert (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL);
1078 switch (DECL_FUNCTION_CODE (fn))
1079 {
1080 default:
1081 return call;
1082
1083 case BUILT_IN_CORO_PROMISE:
1084 {
1085 /* Argument 0 is already checked by the normal built-in machinery
1086 Argument 1 must be a constant of size type. It probably makes
1087 little sense if it's not a power of 2, but that isn't specified
1088 formally. */
1089 tree arg = CALL_EXPR_ARG (call, 1);
1090 location_t loc = EXPR_LOCATION (arg);
1091
1092 /* We expect alignof expressions in templates. */
1093 if (TREE_CODE (arg) == NON_DEPENDENT_EXPR
1094 && TREE_CODE (TREE_OPERAND (arg, 0)) == ALIGNOF_EXPR)
1095 ;
1096 else if (!TREE_CONSTANT (arg))
1097 {
1098 error_at (loc, "the align argument to %<__builtin_coro_promise%>"
1099 " must be a constant");
1100 return error_mark_node;
1101 }
1102 /* Argument 2 is the direction - to / from handle address to promise
1103 address. */
1104 arg = CALL_EXPR_ARG (call, 2);
1105 loc = EXPR_LOCATION (arg);
1106 if (!TREE_CONSTANT (arg))
1107 {
1108 error_at (loc, "the direction argument to"
1109 " %<__builtin_coro_promise%> must be a constant");
1110 return error_mark_node;
1111 }
1112 return call;
1113 break;
1114 }
1115 }
1116 }
1117
1118 /* ================= Morph and Expand. =================
1119
1120 The entry point here is morph_fn_to_coro () which is called from
1121 finish_function () when we have completed any template expansion.
1122
1123 This is preceded by helper functions that implement the phases below.
1124
1125 The process proceeds in four phases.
1126
1127 A Initial framing.
1128 The user's function body is wrapped in the initial and final suspend
1129 points and we begin building the coroutine frame.
1130 We build empty decls for the actor and destroyer functions at this
1131 time too.
1132 When exceptions are enabled, the user's function body will also be
1133 wrapped in a try-catch block with the catch invoking the promise
1134 class 'unhandled_exception' method.
1135
1136 B Analysis.
1137 The user's function body is analyzed to determine the suspend points,
1138 if any, and to capture local variables that might persist across such
1139 suspensions. In most cases, it is not necessary to capture compiler
1140 temporaries, since the tree-lowering nests the suspensions correctly.
1141 However, in the case of a captured reference, there is a lifetime
1142 extension to the end of the full expression - which can mean across a
1143 suspend point in which case it must be promoted to a frame variable.
1144
1145 At the conclusion of analysis, we have a conservative frame layout and
1146 maps of the local variables to their frame entry points.
1147
1148 C Build the ramp function.
1149 Carry out the allocation for the coroutine frame (NOTE; the actual size
1150 computation is deferred until late in the middle end to allow for future
1151 optimizations that will be allowed to elide unused frame entries).
1152 We build the return object.
1153
1154 D Build and expand the actor and destroyer function bodies.
1155 The destroyer is a trivial shim that sets a bit to indicate that the
1156 destroy dispatcher should be used and then calls into the actor.
1157
1158 The actor function is the implementation of the user's state machine.
1159 The current suspend point is noted in an index.
1160 Each suspend point is encoded as a pair of internal functions, one in
1161 the relevant dispatcher, and one representing the suspend point.
1162
1163 During this process, the user's local variables and the proxies for the
1164 self-handle and the promise class instance are re-written to their
1165 coroutine frame equivalents.
1166
1167 The complete bodies for the ramp, actor and destroy function are passed
1168 back to finish_function for folding and gimplification. */
1169
1170 /* Helpers to build EXPR_STMT and void-cast EXPR_STMT, common ops. */
1171
1172 static tree
1173 coro_build_expr_stmt (tree expr, location_t loc)
1174 {
1175 return maybe_cleanup_point_expr_void (build_stmt (loc, EXPR_STMT, expr));
1176 }
1177
1178 static tree
1179 coro_build_cvt_void_expr_stmt (tree expr, location_t loc)
1180 {
1181 tree t = build1 (CONVERT_EXPR, void_type_node, expr);
1182 return coro_build_expr_stmt (t, loc);
1183 }
1184
1185 /* Helpers for label creation:
1186 1. Create a named label in the specified context. */
1187
1188 static tree
1189 create_anon_label_with_ctx (location_t loc, tree ctx)
1190 {
1191 tree lab = build_decl (loc, LABEL_DECL, NULL_TREE, void_type_node);
1192
1193 DECL_CONTEXT (lab) = ctx;
1194 DECL_ARTIFICIAL (lab) = true;
1195 DECL_IGNORED_P (lab) = true;
1196 TREE_USED (lab) = true;
1197 return lab;
1198 }
1199
1200 /* 2. Create a named label in the specified context. */
1201
1202 static tree
1203 create_named_label_with_ctx (location_t loc, const char *name, tree ctx)
1204 {
1205 tree lab_id = get_identifier (name);
1206 tree lab = define_label (loc, lab_id);
1207 DECL_CONTEXT (lab) = ctx;
1208 DECL_ARTIFICIAL (lab) = true;
1209 TREE_USED (lab) = true;
1210 return lab;
1211 }
1212
1213 struct proxy_replace
1214 {
1215 tree from, to;
1216 };
1217
1218 static tree
1219 replace_proxy (tree *here, int *do_subtree, void *d)
1220 {
1221 proxy_replace *data = (proxy_replace *) d;
1222
1223 if (*here == data->from)
1224 {
1225 *here = data->to;
1226 *do_subtree = 0;
1227 }
1228 else
1229 *do_subtree = 1;
1230 return NULL_TREE;
1231 }
1232
1233 /* Support for expansion of co_return statements. */
1234
1235 struct coro_ret_data
1236 {
1237 tree promise_proxy;
1238 tree real_promise;
1239 tree fs_label;
1240 };
1241
1242 /* If this is a coreturn statement (or one wrapped in a cleanup) then
1243 return the list of statements to replace it. */
1244
1245 static tree
1246 coro_maybe_expand_co_return (tree co_ret_expr, coro_ret_data *data)
1247 {
1248 /* Look inside <(void) (expr)> cleanup */
1249 if (TREE_CODE (co_ret_expr) == CLEANUP_POINT_EXPR)
1250 co_ret_expr = TREE_OPERAND (co_ret_expr, 0);
1251
1252 if (TREE_CODE (co_ret_expr) != CO_RETURN_EXPR)
1253 return NULL_TREE;
1254
1255 location_t loc = EXPR_LOCATION (co_ret_expr);
1256 tree expr = TREE_OPERAND (co_ret_expr, 0);
1257 tree call = TREE_OPERAND (co_ret_expr, 1);
1258 tree stmt_list = NULL;
1259 if (expr && VOID_TYPE_P (TREE_TYPE (expr)))
1260 {
1261 /* [stmt.return.coroutine], 2.2
1262 If expr is present and void, it is placed immediately before
1263 the call for return_void; */
1264 expr = maybe_cleanup_point_expr_void (expr);
1265 append_to_statement_list (expr, &stmt_list);
1266 }
1267
1268 /* Now replace the promise proxy with its real value. */
1269 proxy_replace p_data;
1270 p_data.from = data->promise_proxy;
1271 p_data.to = data->real_promise;
1272 cp_walk_tree (&call, replace_proxy, &p_data, NULL);
1273
1274 /* The types of p.return_void and p.return_value are not explicitly stated
1275 at least in n4835, it is expected that they will return void. */
1276 call = maybe_cleanup_point_expr_void (call);
1277 append_to_statement_list (call, &stmt_list);
1278 tree r = build1_loc (loc, GOTO_EXPR, void_type_node, data->fs_label);
1279 append_to_statement_list (r, &stmt_list);
1280 return stmt_list;
1281 }
1282
1283 /* Callback that rewrites co_return as per [stmt.return.coroutine]
1284 - for co_return;
1285 { p.return_void (); goto final_suspend; }
1286 - for co_return [void expr];
1287 { expr; p.return_void(); goto final_suspend;}
1288 - for co_return [non void expr];
1289 { p.return_value(expr); goto final_suspend; } */
1290
1291 static tree
1292 co_return_expander (tree *stmt, int *do_subtree, void *d)
1293 {
1294 coro_ret_data *data = (coro_ret_data *) d;
1295
1296 /* To avoid nesting statement lists, walk them and insert as needed. */
1297 if (TREE_CODE (*stmt) == STATEMENT_LIST)
1298 {
1299 tree_stmt_iterator i;
1300 for (i = tsi_start (*stmt); !tsi_end_p (i); tsi_next (&i))
1301 {
1302 tree *new_stmt = tsi_stmt_ptr (i);
1303 tree replace = coro_maybe_expand_co_return (*new_stmt, data);
1304 /* If we got something, it will be list and we want to splice
1305 it in. */
1306 if (replace != NULL_TREE)
1307 {
1308 /* Splice it in ... */
1309 tsi_link_before (&i, replace, TSI_SAME_STMT);
1310 /* ... and delete what we expanded. */
1311 tsi_delink (&i);
1312 /* Maybe, even likely, we replaced the last in the list. */
1313 if (tsi_end_p (i))
1314 break;
1315 }
1316 else /* Continue the walk. */
1317 cp_walk_tree (new_stmt, co_return_expander, d, NULL);
1318 }
1319 *do_subtree = 0; /* Done subtrees. */
1320 }
1321 else
1322 {
1323 /* We might have a single co_return statement, in which case, we do
1324 have to replace it with a list. */
1325 tree replace = coro_maybe_expand_co_return (*stmt, data);
1326 if (replace != NULL_TREE)
1327 {
1328 *stmt = replace;
1329 *do_subtree = 0; /* Done here. */
1330 }
1331 }
1332 return NULL_TREE;
1333 }
1334
1335 /* Walk the original function body, rewriting co_returns. */
1336
1337 static tree
1338 expand_co_returns (tree *fnbody, tree promise_proxy, tree promise,
1339 tree fs_label)
1340 {
1341 coro_ret_data data = {promise_proxy, promise, fs_label};
1342 cp_walk_tree (fnbody, co_return_expander, &data, NULL);
1343 return *fnbody;
1344 }
1345
1346 /* Support for expansion of co_await statements. */
1347
1348 struct coro_aw_data
1349 {
1350 tree actor_fn; /* Decl for context. */
1351 tree coro_fp; /* Frame pointer var. */
1352 tree resume_idx; /* This is the index var in the frame. */
1353 tree i_a_r_c; /* initial suspend await_resume() was called if true. */
1354 tree self_h; /* This is a handle to the current coro (frame var). */
1355 tree cleanup; /* This is where to go once we complete local destroy. */
1356 tree cororet; /* This is where to go if we suspend. */
1357 tree corocont; /* This is where to go if we continue. */
1358 tree conthand; /* This is the handle for a continuation. */
1359 unsigned index; /* This is our current resume index. */
1360 };
1361
1362 static tree
1363 co_await_find_in_subtree (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
1364 {
1365 tree **p = (tree **) d;
1366 if (TREE_CODE (*stmt) == CO_AWAIT_EXPR)
1367 {
1368 *p = stmt;
1369 return *stmt;
1370 }
1371 return NULL_TREE;
1372 }
1373
1374 /* When we come here:
1375 the first operand is the [currently unused] handle for suspend.
1376 the second operand is the var to be copy-initialized
1377 the third operand is 'o' (the initializer for the second)
1378 as defined in [await.expr] (3.3)
1379 the fourth operand is the mode as per the comment on build_co_await ().
1380
1381 When we leave:
1382 the IFN_CO_YIELD carries the labels of the resume and destroy
1383 branch targets for this await. */
1384
1385 static tree
1386 co_await_expander (tree *stmt, int * /*do_subtree*/, void *d)
1387 {
1388 if (STATEMENT_CLASS_P (*stmt) || !EXPR_P (*stmt))
1389 return NULL_TREE;
1390
1391 coro_aw_data *data = (coro_aw_data *) d;
1392 enum tree_code stmt_code = TREE_CODE (*stmt);
1393 tree stripped_stmt = *stmt;
1394 tree *buried_stmt = NULL;
1395 tree saved_co_await = NULL_TREE;
1396 enum tree_code sub_code = NOP_EXPR;
1397
1398 if (stmt_code == MODIFY_EXPR || stmt_code == INIT_EXPR)
1399 {
1400 sub_code = TREE_CODE (TREE_OPERAND (stripped_stmt, 1));
1401 if (sub_code == CO_AWAIT_EXPR)
1402 saved_co_await = TREE_OPERAND (stripped_stmt, 1); /* Get the RHS. */
1403 else if (tree r
1404 = cp_walk_tree (&TREE_OPERAND (stripped_stmt, 1),
1405 co_await_find_in_subtree, &buried_stmt, NULL))
1406 saved_co_await = r;
1407 }
1408 else if (stmt_code == CALL_EXPR)
1409 {
1410 if (tree r = cp_walk_tree (&stripped_stmt, co_await_find_in_subtree,
1411 &buried_stmt, NULL))
1412 saved_co_await = r;
1413 }
1414 else if ((stmt_code == CONVERT_EXPR || stmt_code == NOP_EXPR)
1415 && TREE_CODE (TREE_OPERAND (stripped_stmt, 0)) == CO_AWAIT_EXPR)
1416 saved_co_await = TREE_OPERAND (stripped_stmt, 0);
1417 else if (stmt_code == CO_AWAIT_EXPR)
1418 saved_co_await = stripped_stmt;
1419
1420 if (!saved_co_await)
1421 return NULL_TREE;
1422
1423 /* We want to splice in the await_resume() value in some cases. */
1424 tree saved_statement = *stmt;
1425
1426 tree actor = data->actor_fn;
1427 location_t loc = EXPR_LOCATION (*stmt);
1428 tree var = TREE_OPERAND (saved_co_await, 1); /* frame slot. */
1429 tree expr = TREE_OPERAND (saved_co_await, 2); /* initializer. */
1430 tree awaiter_calls = TREE_OPERAND (saved_co_await, 3);
1431
1432 tree source = TREE_OPERAND (saved_co_await, 4);
1433 bool is_initial =
1434 (source && TREE_INT_CST_LOW (source) == (int) INITIAL_SUSPEND_POINT);
1435 bool is_final = (source
1436 && TREE_INT_CST_LOW (source) == (int) FINAL_SUSPEND_POINT);
1437 bool needs_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var));
1438 int resume_point = data->index;
1439 size_t bufsize = sizeof ("destroy.") + 10;
1440 char *buf = (char *) alloca (bufsize);
1441 snprintf (buf, bufsize, "destroy.%d", resume_point);
1442 tree destroy_label = create_named_label_with_ctx (loc, buf, actor);
1443 snprintf (buf, bufsize, "resume.%d", resume_point);
1444 tree resume_label = create_named_label_with_ctx (loc, buf, actor);
1445 tree empty_list = build_empty_stmt (loc);
1446
1447 tree dtor = NULL_TREE;
1448 tree await_type = TREE_TYPE (var);
1449 if (needs_dtor)
1450 dtor = build_special_member_call (var, complete_dtor_identifier, NULL,
1451 await_type, LOOKUP_NORMAL,
1452 tf_warning_or_error);
1453
1454 tree stmt_list = NULL;
1455 tree t_expr = STRIP_NOPS (expr);
1456 tree r;
1457 if (t_expr == var)
1458 dtor = NULL_TREE;
1459 else
1460 {
1461 /* Initialize the var from the provided 'o' expression. */
1462 r = build2 (INIT_EXPR, await_type, var, expr);
1463 r = coro_build_cvt_void_expr_stmt (r, loc);
1464 append_to_statement_list (r, &stmt_list);
1465 }
1466
1467 /* Use the await_ready() call to test if we need to suspend. */
1468 tree ready_cond = TREE_VEC_ELT (awaiter_calls, 0); /* await_ready(). */
1469 ready_cond = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, ready_cond);
1470 ready_cond
1471 = build1_loc (loc, CLEANUP_POINT_EXPR, boolean_type_node, ready_cond);
1472
1473 tree body_list = NULL;
1474 tree susp_idx = build_int_cst (short_unsigned_type_node, data->index);
1475 r = build2_loc (loc, MODIFY_EXPR, short_unsigned_type_node, data->resume_idx,
1476 susp_idx);
1477 r = coro_build_cvt_void_expr_stmt (r, loc);
1478 append_to_statement_list (r, &body_list);
1479
1480 /* Find out what we have to do with the awaiter's suspend method.
1481 [expr.await]
1482 (5.1) If the result of await-ready is false, the coroutine is considered
1483 suspended. Then:
1484 (5.1.1) If the type of await-suspend is std::coroutine_handle<Z>,
1485 await-suspend.resume() is evaluated.
1486 (5.1.2) if the type of await-suspend is bool, await-suspend is evaluated,
1487 and the coroutine is resumed if the result is false.
1488 (5.1.3) Otherwise, await-suspend is evaluated. */
1489
1490 tree suspend = TREE_VEC_ELT (awaiter_calls, 1); /* await_suspend(). */
1491 tree susp_type = TREE_TYPE (suspend);
1492
1493 bool is_cont = false;
1494 /* NOTE: final suspend can't resume; the "resume" label in that case
1495 corresponds to implicit destruction. */
1496 if (VOID_TYPE_P (susp_type))
1497 {
1498 /* We just call await_suspend() and hit the yield. */
1499 suspend = coro_build_cvt_void_expr_stmt (suspend, loc);
1500 append_to_statement_list (suspend, &body_list);
1501 }
1502 else if (TREE_CODE (susp_type) == BOOLEAN_TYPE)
1503 {
1504 /* Boolean return, continue if the call returns false. */
1505 suspend = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, suspend);
1506 suspend
1507 = build1_loc (loc, CLEANUP_POINT_EXPR, boolean_type_node, suspend);
1508 tree go_on = build1_loc (loc, GOTO_EXPR, void_type_node, resume_label);
1509 r = build3_loc (loc, COND_EXPR, void_type_node, suspend, go_on,
1510 empty_list);
1511 append_to_statement_list (r, &body_list);
1512 }
1513 else
1514 {
1515 r = build1_loc (loc, CONVERT_EXPR, void_coro_handle_type, suspend);
1516 r = build2_loc (loc, INIT_EXPR, void_coro_handle_type, data->conthand, r);
1517 r = build1 (CONVERT_EXPR, void_type_node, r);
1518 append_to_statement_list (r, &body_list);
1519 is_cont = true;
1520 }
1521
1522 tree d_l = build_address (destroy_label);
1523 tree r_l = build_address (resume_label);
1524 tree susp = build_address (data->cororet);
1525 tree cont = build_address (data->corocont);
1526 tree final_susp = build_int_cst (integer_type_node, is_final ? 1 : 0);
1527
1528 susp_idx = build_int_cst (integer_type_node, data->index);
1529
1530 tree sw = begin_switch_stmt ();
1531 tree cond = build_decl (loc, VAR_DECL, NULL_TREE, integer_type_node);
1532 DECL_ARTIFICIAL (cond) = 1;
1533 DECL_IGNORED_P (cond) = 1;
1534 layout_decl (cond, 0);
1535
1536 r = build_call_expr_internal_loc (loc, IFN_CO_YIELD, integer_type_node, 5,
1537 susp_idx, final_susp, r_l, d_l,
1538 data->coro_fp);
1539 r = build2 (INIT_EXPR, integer_type_node, cond, r);
1540 finish_switch_cond (r, sw);
1541 r = build_case_label (build_int_cst (integer_type_node, 0), NULL_TREE,
1542 create_anon_label_with_ctx (loc, actor));
1543 add_stmt (r); /* case 0: */
1544 /* Implement the suspend, a scope exit without clean ups. */
1545 r = build_call_expr_internal_loc (loc, IFN_CO_SUSPN, void_type_node, 1,
1546 is_cont ? cont : susp);
1547 r = coro_build_cvt_void_expr_stmt (r, loc);
1548 add_stmt (r); /* goto ret; */
1549 r = build_case_label (build_int_cst (integer_type_node, 1), NULL_TREE,
1550 create_anon_label_with_ctx (loc, actor));
1551 add_stmt (r); /* case 1: */
1552 r = build1_loc (loc, GOTO_EXPR, void_type_node, resume_label);
1553 add_stmt (r); /* goto resume; */
1554 r = build_case_label (NULL_TREE, NULL_TREE,
1555 create_anon_label_with_ctx (loc, actor));
1556 add_stmt (r); /* default:; */
1557 r = build1_loc (loc, GOTO_EXPR, void_type_node, destroy_label);
1558 add_stmt (r); /* goto destroy; */
1559
1560 /* part of finish switch. */
1561 SWITCH_STMT_BODY (sw) = pop_stmt_list (SWITCH_STMT_BODY (sw));
1562 pop_switch ();
1563 tree scope = SWITCH_STMT_SCOPE (sw);
1564 SWITCH_STMT_SCOPE (sw) = NULL;
1565 r = do_poplevel (scope);
1566 append_to_statement_list (r, &body_list);
1567
1568 destroy_label = build_stmt (loc, LABEL_EXPR, destroy_label);
1569 append_to_statement_list (destroy_label, &body_list);
1570 if (needs_dtor)
1571 append_to_statement_list (dtor, &body_list);
1572 r = build1_loc (loc, GOTO_EXPR, void_type_node, data->cleanup);
1573 append_to_statement_list (r, &body_list);
1574
1575 r = build3_loc (loc, COND_EXPR, void_type_node, ready_cond, body_list,
1576 empty_list);
1577
1578 append_to_statement_list (r, &stmt_list);
1579
1580 /* Resume point. */
1581 resume_label = build_stmt (loc, LABEL_EXPR, resume_label);
1582 append_to_statement_list (resume_label, &stmt_list);
1583
1584 if (is_initial)
1585 {
1586 /* Note that we are about to execute the await_resume() for the initial
1587 await expression. */
1588 r = build2_loc (loc, MODIFY_EXPR, boolean_type_node, data->i_a_r_c,
1589 boolean_true_node);
1590 r = coro_build_cvt_void_expr_stmt (r, loc);
1591 append_to_statement_list (r, &stmt_list);
1592 }
1593
1594 /* This will produce the value (if one is provided) from the co_await
1595 expression. */
1596 tree resume_call = TREE_VEC_ELT (awaiter_calls, 2); /* await_resume(). */
1597 if (REFERENCE_REF_P (resume_call))
1598 /* Sink to await_resume call_expr. */
1599 resume_call = TREE_OPERAND (resume_call, 0);
1600 switch (stmt_code)
1601 {
1602 default: /* not likely to work .. but... */
1603 append_to_statement_list (resume_call, &stmt_list);
1604 break;
1605 case CONVERT_EXPR:
1606 case NOP_EXPR:
1607 TREE_OPERAND (stripped_stmt, 0) = resume_call;
1608 append_to_statement_list (saved_statement, &stmt_list);
1609 break;
1610 case INIT_EXPR:
1611 case MODIFY_EXPR:
1612 case CALL_EXPR:
1613 /* Replace the use of co_await by the resume expr. */
1614 if (sub_code == CO_AWAIT_EXPR)
1615 {
1616 /* We're updating the interior of a possibly <(void) expr>cleanup. */
1617 TREE_OPERAND (stripped_stmt, 1) = resume_call;
1618 append_to_statement_list (saved_statement, &stmt_list);
1619 }
1620 else if (buried_stmt != NULL)
1621 {
1622 *buried_stmt = resume_call;
1623 append_to_statement_list (saved_statement, &stmt_list);
1624 }
1625 else
1626 {
1627 error_at (loc, "failed to substitute the resume method in %qE",
1628 saved_statement);
1629 append_to_statement_list (saved_statement, &stmt_list);
1630 }
1631 break;
1632 }
1633 if (needs_dtor)
1634 append_to_statement_list (dtor, &stmt_list);
1635 data->index += 2;
1636 *stmt = stmt_list;
1637 return NULL_TREE;
1638 }
1639
1640 /* Suspend point hash_map. */
1641
1642 struct suspend_point_info
1643 {
1644 /* coro frame field type. */
1645 tree awaitable_type;
1646 /* coro frame field name. */
1647 tree await_field_id;
1648 };
1649
1650 static hash_map<tree, suspend_point_info> *suspend_points;
1651
1652 struct await_xform_data
1653 {
1654 tree actor_fn; /* Decl for context. */
1655 tree actor_frame;
1656 tree promise_proxy;
1657 tree real_promise;
1658 tree self_h_proxy;
1659 tree real_self_h;
1660 };
1661
1662 /* When we built the await expressions, we didn't know the coro frame
1663 layout, therefore no idea where to find the promise or where to put
1664 the awaitables. Now we know these things, fill them in. */
1665
1666 static tree
1667 transform_await_expr (tree await_expr, await_xform_data *xform)
1668 {
1669 suspend_point_info *si = suspend_points->get (await_expr);
1670 location_t loc = EXPR_LOCATION (await_expr);
1671 if (!si)
1672 {
1673 error_at (loc, "no suspend point info for %qD", await_expr);
1674 return error_mark_node;
1675 }
1676
1677 /* So, on entry, we have:
1678 in : CO_AWAIT_EXPR (a, e_proxy, o, awr_call_vector, mode)
1679 We no longer need a [it had diagnostic value, maybe?]
1680 We need to replace the promise proxy in all elements
1681 We need to replace the e_proxy in the awr_call. */
1682
1683 tree coro_frame_type = TREE_TYPE (xform->actor_frame);
1684
1685 /* If we have a frame var for the awaitable, get a reference to it. */
1686 proxy_replace data;
1687 if (si->await_field_id)
1688 {
1689 tree as_m
1690 = lookup_member (coro_frame_type, si->await_field_id,
1691 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
1692 tree as = build_class_member_access_expr (xform->actor_frame, as_m,
1693 NULL_TREE, true,
1694 tf_warning_or_error);
1695
1696 /* Replace references to the instance proxy with the frame entry now
1697 computed. */
1698 data.from = TREE_OPERAND (await_expr, 1);
1699 data.to = as;
1700 cp_walk_tree (&await_expr, replace_proxy, &data, NULL);
1701
1702 /* .. and replace. */
1703 TREE_OPERAND (await_expr, 1) = as;
1704 }
1705
1706 /* Now do the self_handle. */
1707 data.from = xform->self_h_proxy;
1708 data.to = xform->real_self_h;
1709 cp_walk_tree (&await_expr, replace_proxy, &data, NULL);
1710
1711 /* Now do the promise. */
1712 data.from = xform->promise_proxy;
1713 data.to = xform->real_promise;
1714 cp_walk_tree (&await_expr, replace_proxy, &data, NULL);
1715
1716 return await_expr;
1717 }
1718
1719 /* A wrapper for the transform_await_expr function so that it can be a
1720 callback from cp_walk_tree. */
1721
1722 static tree
1723 transform_await_wrapper (tree *stmt, int *do_subtree, void *d)
1724 {
1725 /* Set actor function as new DECL_CONTEXT of label_decl. */
1726 struct await_xform_data *xform = (struct await_xform_data *) d;
1727 if (TREE_CODE (*stmt) == LABEL_DECL
1728 && DECL_CONTEXT (*stmt) != xform->actor_fn)
1729 DECL_CONTEXT (*stmt) = xform->actor_fn;
1730
1731 if (TREE_CODE (*stmt) != CO_AWAIT_EXPR && TREE_CODE (*stmt) != CO_YIELD_EXPR)
1732 return NULL_TREE;
1733
1734 tree await_expr = *stmt;
1735 *stmt = transform_await_expr (await_expr, xform);
1736 if (*stmt == error_mark_node)
1737 *do_subtree = 0;
1738 return NULL_TREE;
1739 }
1740
1741 /* This caches information that we determine about function params,
1742 their uses and copies in the coroutine frame. */
1743
1744 struct param_info
1745 {
1746 tree field_id; /* The name of the copy in the coroutine frame. */
1747 vec<tree *> *body_uses; /* Worklist of uses, void if there are none. */
1748 tree frame_type; /* The type used to represent this parm in the frame. */
1749 tree orig_type; /* The original type of the parm (not as passed). */
1750 bool by_ref; /* Was passed by reference. */
1751 bool rv_ref; /* Was an rvalue reference. */
1752 bool pt_ref; /* Was a pointer to object. */
1753 bool trivial_dtor; /* The frame type has a trivial DTOR. */
1754 };
1755
1756 struct local_var_info
1757 {
1758 tree field_id;
1759 tree field_idx;
1760 tree frame_type;
1761 bool is_lambda_capture;
1762 location_t def_loc;
1763 };
1764
1765 /* For figuring out what local variable usage we have. */
1766 struct local_vars_transform
1767 {
1768 tree context;
1769 tree actor_frame;
1770 tree coro_frame_type;
1771 location_t loc;
1772 hash_map<tree, local_var_info> *local_var_uses;
1773 };
1774
1775 static tree
1776 transform_local_var_uses (tree *stmt, int *do_subtree, void *d)
1777 {
1778 local_vars_transform *lvd = (local_vars_transform *) d;
1779
1780 /* For each var in this bind expr (that has a frame id, which means it was
1781 accessed), build a frame reference for each and then walk the bind expr
1782 statements, substituting the frame ref for the original var. */
1783
1784 if (TREE_CODE (*stmt) == BIND_EXPR)
1785 {
1786 tree lvar;
1787 for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
1788 lvar = DECL_CHAIN (lvar))
1789 {
1790 bool existed;
1791 local_var_info &local_var
1792 = lvd->local_var_uses->get_or_insert (lvar, &existed);
1793 gcc_checking_assert (existed);
1794
1795 /* Re-write the variable's context to be in the actor func. */
1796 DECL_CONTEXT (lvar) = lvd->context;
1797
1798 /* we need to walk some of the decl trees, which might contain
1799 references to vars replaced at a higher level. */
1800 cp_walk_tree (&DECL_INITIAL (lvar), transform_local_var_uses, d,
1801 NULL);
1802 cp_walk_tree (&DECL_SIZE (lvar), transform_local_var_uses, d, NULL);
1803 cp_walk_tree (&DECL_SIZE_UNIT (lvar), transform_local_var_uses, d,
1804 NULL);
1805
1806 /* For capture proxies, this could include the decl value expr. */
1807 if (local_var.is_lambda_capture)
1808 {
1809 tree ve = DECL_VALUE_EXPR (lvar);
1810 cp_walk_tree (&ve, transform_local_var_uses, d, NULL);
1811 continue; /* No frame entry for this. */
1812 }
1813
1814 /* TODO: implement selective generation of fields when vars are
1815 known not-used. */
1816 if (local_var.field_id == NULL_TREE)
1817 continue; /* Wasn't used. */
1818
1819 tree fld_ref
1820 = lookup_member (lvd->coro_frame_type, local_var.field_id,
1821 /*protect=*/1, /*want_type=*/0,
1822 tf_warning_or_error);
1823 tree fld_idx = build3_loc (lvd->loc, COMPONENT_REF, TREE_TYPE (lvar),
1824 lvd->actor_frame, fld_ref, NULL_TREE);
1825 local_var.field_idx = fld_idx;
1826 }
1827 cp_walk_tree (&BIND_EXPR_BODY (*stmt), transform_local_var_uses, d, NULL);
1828
1829 /* Now we have processed and removed references to the original vars,
1830 we can drop those from the bind - leaving capture proxies alone. */
1831 for (tree *pvar = &BIND_EXPR_VARS (*stmt); *pvar != NULL;)
1832 {
1833 bool existed;
1834 local_var_info &local_var
1835 = lvd->local_var_uses->get_or_insert (*pvar, &existed);
1836 gcc_checking_assert (existed);
1837
1838 /* Leave lambda closure captures alone, we replace the *this
1839 pointer with the frame version and let the normal process
1840 deal with the rest. */
1841 if (local_var.is_lambda_capture)
1842 {
1843 pvar = &DECL_CHAIN (*pvar);
1844 continue;
1845 }
1846
1847 /* It's not used, but we can let the optimizer deal with that. */
1848 if (local_var.field_id == NULL_TREE)
1849 {
1850 pvar = &DECL_CHAIN (*pvar);
1851 continue;
1852 }
1853
1854 /* Discard this one, we replaced it. */
1855 *pvar = DECL_CHAIN (*pvar);
1856 }
1857
1858 *do_subtree = 0; /* We've done the body already. */
1859 return NULL_TREE;
1860 }
1861
1862 tree var_decl = *stmt;
1863 /* Look inside cleanups, we don't want to wrap a statement list in a
1864 cleanup. */
1865 bool needs_cleanup = true;
1866 if (TREE_CODE (var_decl) == CLEANUP_POINT_EXPR)
1867 var_decl = TREE_OPERAND (var_decl, 0);
1868 else
1869 needs_cleanup = false;
1870
1871 /* Look inside the decl_expr for the actual var. */
1872 bool decl_expr_p = TREE_CODE (var_decl) == DECL_EXPR;
1873 if (decl_expr_p && TREE_CODE (DECL_EXPR_DECL (var_decl)) == VAR_DECL)
1874 var_decl = DECL_EXPR_DECL (var_decl);
1875 else if (TREE_CODE (var_decl) != VAR_DECL)
1876 return NULL_TREE;
1877
1878 /* VAR_DECLs that are not recorded can belong to the proxies we've placed
1879 for the promise and coroutine handle(s), to global vars or to compiler
1880 temporaries. Skip past these, we will handle them later. */
1881 local_var_info *local_var_i = lvd->local_var_uses->get (var_decl);
1882 if (local_var_i == NULL)
1883 return NULL_TREE;
1884
1885 if (local_var_i->is_lambda_capture)
1886 return NULL_TREE;
1887
1888 /* This is our revised 'local' i.e. a frame slot. */
1889 tree revised = local_var_i->field_idx;
1890 gcc_checking_assert (DECL_CONTEXT (var_decl) == lvd->context);
1891
1892 if (decl_expr_p && DECL_INITIAL (var_decl))
1893 {
1894 location_t loc = DECL_SOURCE_LOCATION (var_decl);
1895 tree r
1896 = cp_build_modify_expr (loc, revised, INIT_EXPR,
1897 DECL_INITIAL (var_decl), tf_warning_or_error);
1898 if (needs_cleanup)
1899 r = coro_build_cvt_void_expr_stmt (r, EXPR_LOCATION (*stmt));
1900 *stmt = r;
1901 }
1902 else
1903 *stmt = revised;
1904
1905 if (decl_expr_p)
1906 *do_subtree = 0; /* We've accounted for the nested use. */
1907 return NULL_TREE;
1908 }
1909
1910 /* The actor transform. */
1911
1912 static void
1913 build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
1914 tree orig, hash_map<tree, param_info> *param_uses,
1915 hash_map<tree, local_var_info> *local_var_uses,
1916 vec<tree, va_gc> *param_dtor_list, tree initial_await,
1917 tree final_await, unsigned body_count, tree frame_size)
1918 {
1919 verify_stmt_tree (fnbody);
1920 /* Some things we inherit from the original function. */
1921 tree coro_frame_ptr = build_pointer_type (coro_frame_type);
1922 tree handle_type = get_coroutine_handle_type (orig);
1923 tree self_h_proxy = get_coroutine_self_handle_proxy (orig);
1924 tree promise_type = get_coroutine_promise_type (orig);
1925 tree promise_proxy = get_coroutine_promise_proxy (orig);
1926 tree act_des_fn_type
1927 = build_function_type_list (void_type_node, coro_frame_ptr, NULL_TREE);
1928 tree act_des_fn_ptr = build_pointer_type (act_des_fn_type);
1929
1930 /* One param, the coro frame pointer. */
1931 tree actor_fp = DECL_ARGUMENTS (actor);
1932
1933 /* A void return. */
1934 tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
1935 DECL_ARTIFICIAL (resdecl) = 1;
1936 DECL_IGNORED_P (resdecl) = 1;
1937 DECL_RESULT (actor) = resdecl;
1938 DECL_COROUTINE_P (actor) = 1;
1939
1940 /* We have a definition here. */
1941 TREE_STATIC (actor) = 1;
1942
1943 tree actor_outer = push_stmt_list ();
1944 current_stmt_tree ()->stmts_are_full_exprs_p = 1;
1945 tree stmt = begin_compound_stmt (BCS_FN_BODY);
1946
1947 /* ??? Can we dispense with the enclosing bind if the function body does
1948 not start with a bind_expr? (i.e. there's no contained scopes). */
1949 tree actor_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
1950 tree top_block = make_node (BLOCK);
1951 BIND_EXPR_BLOCK (actor_bind) = top_block;
1952
1953 tree continuation = build_lang_decl (VAR_DECL,
1954 get_identifier ("actor.continue"),
1955 void_coro_handle_type);
1956 DECL_ARTIFICIAL (continuation) = 1;
1957 DECL_IGNORED_P (continuation) = 1;
1958 DECL_CONTEXT (continuation) = actor;
1959 BIND_EXPR_VARS (actor_bind) = continuation;
1960
1961 /* Update the block associated with the outer scope of the orig fn. */
1962 tree first = expr_first (fnbody);
1963 if (first && TREE_CODE (first) == BIND_EXPR)
1964 {
1965 /* We will discard this, since it's connected to the original scope
1966 nest. */
1967 tree block = BIND_EXPR_BLOCK (first);
1968 if (block) /* For this to be missing is probably a bug. */
1969 {
1970 gcc_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
1971 gcc_assert (BLOCK_CHAIN (block) == NULL_TREE);
1972 BLOCK_SUPERCONTEXT (block) = top_block;
1973 BLOCK_SUBBLOCKS (top_block) = block;
1974 }
1975 }
1976
1977 add_stmt (actor_bind);
1978 tree actor_body = push_stmt_list ();
1979
1980 /* The entry point for the actor code from the ramp. */
1981 tree actor_begin_label
1982 = create_named_label_with_ctx (loc, "actor.begin", actor);
1983 tree actor_frame = build1_loc (loc, INDIRECT_REF, coro_frame_type, actor_fp);
1984
1985 /* Declare the continuation handle. */
1986 add_decl_expr (continuation);
1987
1988 /* Re-write param references in the body, no code should be generated
1989 here. */
1990 if (DECL_ARGUMENTS (orig))
1991 {
1992 tree arg;
1993 for (arg = DECL_ARGUMENTS (orig); arg != NULL; arg = DECL_CHAIN (arg))
1994 {
1995 bool existed;
1996 param_info &parm = param_uses->get_or_insert (arg, &existed);
1997 if (!parm.body_uses)
1998 continue; /* Wasn't used in the orignal function body. */
1999
2000 tree fld_ref = lookup_member (coro_frame_type, parm.field_id,
2001 /*protect=*/1, /*want_type=*/0,
2002 tf_warning_or_error);
2003 tree fld_idx = build3_loc (loc, COMPONENT_REF, parm.frame_type,
2004 actor_frame, fld_ref, NULL_TREE);
2005
2006 /* We keep these in the frame as a regular pointer, so convert that
2007 back to the type expected. */
2008 if (parm.pt_ref)
2009 fld_idx = build1_loc (loc, CONVERT_EXPR, TREE_TYPE (arg), fld_idx);
2010
2011 /* We expect an rvalue ref. here. */
2012 if (parm.rv_ref)
2013 fld_idx = convert_to_reference (DECL_ARG_TYPE (arg), fld_idx,
2014 CONV_STATIC, LOOKUP_NORMAL,
2015 NULL_TREE, tf_warning_or_error);
2016
2017 int i;
2018 tree *puse;
2019 FOR_EACH_VEC_ELT (*parm.body_uses, i, puse)
2020 *puse = fld_idx;
2021 }
2022 }
2023
2024 /* Re-write local vars, similarly. */
2025 local_vars_transform xform_vars_data
2026 = {actor, actor_frame, coro_frame_type, loc, local_var_uses};
2027 cp_walk_tree (&fnbody, transform_local_var_uses, &xform_vars_data, NULL);
2028
2029 tree resume_idx_name = get_identifier ("__resume_at");
2030 tree rat_field = lookup_member (coro_frame_type, resume_idx_name, 1, 0,
2031 tf_warning_or_error);
2032 tree rat = build3 (COMPONENT_REF, short_unsigned_type_node, actor_frame,
2033 rat_field, NULL_TREE);
2034
2035 tree ret_label
2036 = create_named_label_with_ctx (loc, "actor.suspend.ret", actor);
2037
2038 tree continue_label
2039 = create_named_label_with_ctx (loc, "actor.continue.ret", actor);
2040
2041 tree lsb_if = begin_if_stmt ();
2042 tree chkb0 = build2 (BIT_AND_EXPR, short_unsigned_type_node, rat,
2043 build_int_cst (short_unsigned_type_node, 1));
2044 chkb0 = build2 (NE_EXPR, short_unsigned_type_node, chkb0,
2045 build_int_cst (short_unsigned_type_node, 0));
2046 finish_if_stmt_cond (chkb0, lsb_if);
2047
2048 tree destroy_dispatcher = begin_switch_stmt ();
2049 finish_switch_cond (rat, destroy_dispatcher);
2050 tree ddeflab = build_case_label (NULL_TREE, NULL_TREE,
2051 create_anon_label_with_ctx (loc, actor));
2052 add_stmt (ddeflab);
2053 tree b = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
2054 b = coro_build_cvt_void_expr_stmt (b, loc);
2055 add_stmt (b);
2056
2057 short unsigned lab_num = 3;
2058 for (unsigned destr_pt = 0; destr_pt < body_count + 2; destr_pt++)
2059 {
2060 tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
2061 b = build_case_label (l_num, NULL_TREE,
2062 create_anon_label_with_ctx (loc, actor));
2063 add_stmt (b);
2064 b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
2065 l_num);
2066 b = coro_build_cvt_void_expr_stmt (b, loc);
2067 add_stmt (b);
2068 b = build1 (GOTO_EXPR, void_type_node, CASE_LABEL (ddeflab));
2069 add_stmt (b);
2070 lab_num += 2;
2071 }
2072
2073 /* Insert the prototype dispatcher. */
2074 finish_switch_stmt (destroy_dispatcher);
2075
2076 finish_then_clause (lsb_if);
2077
2078 tree dispatcher = begin_switch_stmt ();
2079 finish_switch_cond (rat, dispatcher);
2080 b = build_case_label (build_int_cst (short_unsigned_type_node, 0), NULL_TREE,
2081 create_anon_label_with_ctx (loc, actor));
2082 add_stmt (b);
2083 b = build1 (GOTO_EXPR, void_type_node, actor_begin_label);
2084 add_stmt (b);
2085
2086 tree rdeflab = build_case_label (NULL_TREE, NULL_TREE,
2087 create_anon_label_with_ctx (loc, actor));
2088 add_stmt (rdeflab);
2089 b = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
2090 b = coro_build_cvt_void_expr_stmt (b, loc);
2091 add_stmt (b);
2092
2093 lab_num = 2;
2094 /* The final resume should be made to hit the default (trap, UB) entry. */
2095 for (unsigned resu_pt = 0; resu_pt < body_count + 1; resu_pt++)
2096 {
2097 tree l_num = build_int_cst (short_unsigned_type_node, lab_num);
2098 b = build_case_label (l_num, NULL_TREE,
2099 create_anon_label_with_ctx (loc, actor));
2100 add_stmt (b);
2101 b = build_call_expr_internal_loc (loc, IFN_CO_ACTOR, void_type_node, 1,
2102 l_num);
2103 b = coro_build_cvt_void_expr_stmt (b, loc);
2104 add_stmt (b);
2105 b = build1 (GOTO_EXPR, void_type_node, CASE_LABEL (rdeflab));
2106 add_stmt (b);
2107 lab_num += 2;
2108 }
2109
2110 /* Insert the prototype dispatcher. */
2111 finish_switch_stmt (dispatcher);
2112
2113 finish_if_stmt (lsb_if);
2114
2115 tree r = build_stmt (loc, LABEL_EXPR, actor_begin_label);
2116 add_stmt (r);
2117
2118 /* actor's version of the promise. */
2119 tree ap_m = lookup_member (coro_frame_type, get_identifier ("__p"), 1, 0,
2120 tf_warning_or_error);
2121 tree ap = build_class_member_access_expr (actor_frame, ap_m, NULL_TREE, false,
2122 tf_warning_or_error);
2123
2124 /* actor's coroutine 'self handle'. */
2125 tree ash_m = lookup_member (coro_frame_type, get_identifier ("__self_h"), 1,
2126 0, tf_warning_or_error);
2127 tree ash = build_class_member_access_expr (actor_frame, ash_m, NULL_TREE,
2128 false, tf_warning_or_error);
2129 /* So construct the self-handle from the frame address. */
2130 tree hfa_m = lookup_member (handle_type, coro_from_address_identifier, 1,
2131 0, tf_warning_or_error);
2132
2133 r = build1 (CONVERT_EXPR, build_pointer_type (void_type_node), actor_fp);
2134 vec<tree, va_gc> *args = make_tree_vector_single (r);
2135 tree hfa = build_new_method_call (ash, hfa_m, &args, NULL_TREE, LOOKUP_NORMAL,
2136 NULL, tf_warning_or_error);
2137 r = build2 (INIT_EXPR, handle_type, ash, hfa);
2138 r = coro_build_cvt_void_expr_stmt (r, loc);
2139 add_stmt (r);
2140 release_tree_vector (args);
2141
2142 /* Now we know the real promise, and enough about the frame layout to
2143 decide where to put things. */
2144
2145 await_xform_data xform
2146 = {actor, actor_frame, promise_proxy, ap, self_h_proxy, ash};
2147
2148 /* Get a reference to the initial suspend var in the frame. */
2149 transform_await_expr (initial_await, &xform);
2150 tree initial_await_stmt = coro_build_expr_stmt (initial_await, loc);
2151
2152 /* co_return branches to the final_suspend label, so declare that now. */
2153 tree fs_label = create_named_label_with_ctx (loc, "final.suspend", actor);
2154
2155 /* Expand co_returns in the saved function body */
2156 fnbody = expand_co_returns (&fnbody, promise_proxy, ap, fs_label);
2157
2158 /* n4849 adds specific behaviour to treat exceptions thrown by the
2159 await_resume () of the initial suspend expression. In order to
2160 implement this, we need to treat the initial_suspend expression
2161 as if it were part of the user-authored function body. This
2162 only applies if exceptions are enabled. */
2163 if (flag_exceptions)
2164 {
2165 tree outer = fnbody;
2166 if (TREE_CODE (outer) == BIND_EXPR)
2167 outer = BIND_EXPR_BODY (outer);
2168 gcc_checking_assert (TREE_CODE (outer) == TRY_BLOCK);
2169 tree sl = TRY_STMTS (outer);
2170 if (TREE_CODE (sl) == STATEMENT_LIST)
2171 {
2172 tree_stmt_iterator si = tsi_start (sl);
2173 tsi_link_before (&si, initial_await_stmt, TSI_NEW_STMT);
2174 }
2175 else
2176 {
2177 tree new_try = NULL_TREE;
2178 append_to_statement_list (initial_await_stmt, &new_try);
2179 append_to_statement_list (sl, &new_try);
2180 TRY_STMTS (outer) = new_try;
2181 }
2182 }
2183 else
2184 add_stmt (initial_await_stmt);
2185
2186 /* Transform the await expressions in the function body. Only do each
2187 await tree once! */
2188 hash_set<tree> pset;
2189 cp_walk_tree (&fnbody, transform_await_wrapper, &xform, &pset);
2190
2191 /* Add in our function body with the co_returns rewritten to final form. */
2192 add_stmt (fnbody);
2193
2194 /* Final suspend starts here. */
2195 r = build_stmt (loc, LABEL_EXPR, fs_label);
2196 add_stmt (r);
2197
2198 /* Set the actor pointer to null, so that 'done' will work.
2199 Resume from here is UB anyway - although a 'ready' await will
2200 branch to the final resume, and fall through to the destroy. */
2201 tree resume_m
2202 = lookup_member (coro_frame_type, get_identifier ("__resume"),
2203 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
2204 tree res_x = build_class_member_access_expr (actor_frame, resume_m, NULL_TREE,
2205 false, tf_warning_or_error);
2206 r = build1 (CONVERT_EXPR, act_des_fn_ptr, integer_zero_node);
2207 r = build2 (INIT_EXPR, act_des_fn_ptr, res_x, r);
2208 r = coro_build_cvt_void_expr_stmt (r, loc);
2209 add_stmt (r);
2210
2211 /* Get a reference to the final suspend var in the frame. */
2212 transform_await_expr (final_await, &xform);
2213 r = coro_build_expr_stmt (final_await, loc);
2214 add_stmt (r);
2215
2216 /* now do the tail of the function. */
2217 tree del_promise_label
2218 = create_named_label_with_ctx (loc, "coro.delete.promise", actor);
2219 r = build_stmt (loc, LABEL_EXPR, del_promise_label);
2220 add_stmt (r);
2221
2222 /* Destructors for the things we built explicitly. */
2223 r = build_special_member_call (ap, complete_dtor_identifier, NULL,
2224 promise_type, LOOKUP_NORMAL,
2225 tf_warning_or_error);
2226 add_stmt (r);
2227
2228 tree del_frame_label
2229 = create_named_label_with_ctx (loc, "coro.delete.frame", actor);
2230 r = build_stmt (loc, LABEL_EXPR, del_frame_label);
2231 add_stmt (r);
2232
2233 /* Here deallocate the frame (if we allocated it), which we will have at
2234 present. */
2235 tree fnf_m
2236 = lookup_member (coro_frame_type, get_identifier ("__frame_needs_free"), 1,
2237 0, tf_warning_or_error);
2238 tree fnf2_x = build_class_member_access_expr (actor_frame, fnf_m, NULL_TREE,
2239 false, tf_warning_or_error);
2240
2241 tree need_free_if = begin_if_stmt ();
2242 fnf2_x = build1 (CONVERT_EXPR, integer_type_node, fnf2_x);
2243 tree cmp = build2 (NE_EXPR, integer_type_node, fnf2_x, integer_zero_node);
2244 finish_if_stmt_cond (cmp, need_free_if);
2245 if (param_dtor_list != NULL)
2246 {
2247 int i;
2248 tree pid;
2249 FOR_EACH_VEC_ELT (*param_dtor_list, i, pid)
2250 {
2251 tree m
2252 = lookup_member (coro_frame_type, pid, 1, 0, tf_warning_or_error);
2253 tree a = build_class_member_access_expr (actor_frame, m, NULL_TREE,
2254 false, tf_warning_or_error);
2255 tree t = TREE_TYPE (a);
2256 tree dtor;
2257 dtor
2258 = build_special_member_call (a, complete_dtor_identifier, NULL, t,
2259 LOOKUP_NORMAL, tf_warning_or_error);
2260 add_stmt (dtor);
2261 }
2262 }
2263
2264 /* n4849 [dcl.fct.def.coroutine] / 12
2265 The deallocation function’s name is looked up in the scope of the promise
2266 type. If this lookup fails, the deallocation function’s name is looked up
2267 in the global scope. If deallocation function lookup finds both a usual
2268 deallocation function with only a pointer parameter and a usual
2269 deallocation function with both a pointer parameter and a size parameter,
2270 then the selected deallocation function shall be the one with two
2271 parameters. Otherwise, the selected deallocation function shall be the
2272 function with one parameter. If no usual deallocation function is found
2273 the program is ill-formed. The selected deallocation function shall be
2274 called with the address of the block of storage to be reclaimed as its
2275 first argument. If a deallocation function with a parameter of type
2276 std::size_t is used, the size of the block is passed as the corresponding
2277 argument. */
2278
2279 tree del_coro_fr = NULL_TREE;
2280 tree frame_arg = build1 (CONVERT_EXPR, ptr_type_node, actor_fp);
2281
2282 tree delname = ovl_op_identifier (false, DELETE_EXPR);
2283 tree fns = lookup_promise_method (orig, delname, loc, /*musthave=*/false);
2284 if (fns && BASELINK_P (fns))
2285 {
2286 /* Look for sized version first, since this takes precedence. */
2287 vec<tree, va_gc> *args = make_tree_vector ();
2288 vec_safe_push (args, frame_arg);
2289 vec_safe_push (args, frame_size);
2290 tree dummy_promise = build_dummy_object (promise_type);
2291
2292 /* It's OK to fail for this one... */
2293 del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
2294 NULL_TREE, LOOKUP_NORMAL, NULL,
2295 tf_none);
2296
2297 if (!del_coro_fr || del_coro_fr == error_mark_node)
2298 {
2299 release_tree_vector (args);
2300 args = make_tree_vector_single (frame_arg);
2301 del_coro_fr = build_new_method_call (dummy_promise, fns, &args,
2302 NULL_TREE, LOOKUP_NORMAL, NULL,
2303 tf_none);
2304 }
2305
2306 /* But one of them must succeed, or the program is ill-formed. */
2307 if (!del_coro_fr || del_coro_fr == error_mark_node)
2308 {
2309 error_at (loc, "%qE is provided by %qT but is not usable with"
2310 " the function signature %qD", delname, promise_type, orig);
2311 del_coro_fr = error_mark_node;
2312 }
2313 }
2314 else
2315 {
2316 del_coro_fr = build_op_delete_call (DELETE_EXPR, frame_arg, frame_size,
2317 /*global_p=*/true, /*placement=*/NULL,
2318 /*alloc_fn=*/NULL,
2319 tf_warning_or_error);
2320 if (!del_coro_fr || del_coro_fr == error_mark_node)
2321 del_coro_fr = error_mark_node;
2322 }
2323
2324 del_coro_fr = coro_build_cvt_void_expr_stmt (del_coro_fr, loc);
2325 add_stmt (del_coro_fr);
2326 finish_then_clause (need_free_if);
2327 tree scope = IF_SCOPE (need_free_if);
2328 IF_SCOPE (need_free_if) = NULL;
2329 r = do_poplevel (scope);
2330 add_stmt (r);
2331
2332 /* done. */
2333 r = build_stmt (loc, RETURN_EXPR, NULL);
2334 TREE_NO_WARNING (r) |= 1; /* We don't want a warning about this. */
2335 r = maybe_cleanup_point_expr_void (r);
2336 add_stmt (r);
2337
2338 /* This is the suspend return point. */
2339 r = build_stmt (loc, LABEL_EXPR, ret_label);
2340 add_stmt (r);
2341
2342 r = build_stmt (loc, RETURN_EXPR, NULL);
2343 TREE_NO_WARNING (r) |= 1; /* We don't want a warning about this. */
2344 r = maybe_cleanup_point_expr_void (r);
2345 add_stmt (r);
2346
2347 /* This is the 'continuation' return point. For such a case we have a coro
2348 handle (from the await_suspend() call) and we want handle.resume() to
2349 execute as a tailcall allowing arbitrary chaining of coroutines. */
2350 r = build_stmt (loc, LABEL_EXPR, continue_label);
2351 add_stmt (r);
2352
2353 /* We want to force a tail-call even for O0/1, so this expands the resume
2354 call into its underlying implementation. */
2355 tree addr = lookup_member (void_coro_handle_type, coro_address_identifier,
2356 1, 0, tf_warning_or_error);
2357 addr = build_new_method_call (continuation, addr, NULL, NULL_TREE,
2358 LOOKUP_NORMAL, NULL, tf_warning_or_error);
2359 tree resume = build_call_expr_loc
2360 (loc, builtin_decl_explicit (BUILT_IN_CORO_RESUME), 1, addr);
2361
2362 /* Now we have the actual call, and we can mark it as a tail. */
2363 CALL_EXPR_TAILCALL (resume) = true;
2364 /* ... and for optimisation levels 0..1, mark it as requiring a tail-call
2365 for correctness. It seems that doing this for optimisation levels that
2366 normally perform tail-calling, confuses the ME (or it would be logical
2367 to put this on unilaterally). */
2368 if (optimize < 2)
2369 CALL_EXPR_MUST_TAIL_CALL (resume) = true;
2370 resume = coro_build_cvt_void_expr_stmt (resume, loc);
2371 add_stmt (resume);
2372
2373 r = build_stmt (loc, RETURN_EXPR, NULL);
2374 gcc_checking_assert (maybe_cleanup_point_expr_void (r) == r);
2375 add_stmt (r);
2376
2377 /* We will need to know which resume point number should be encoded. */
2378 tree res_idx_m
2379 = lookup_member (coro_frame_type, resume_idx_name,
2380 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
2381 tree resume_pt_number
2382 = build_class_member_access_expr (actor_frame, res_idx_m, NULL_TREE, false,
2383 tf_warning_or_error);
2384
2385 /* Boolean value to flag that the initial suspend expression's
2386 await_resume () has been called, and therefore we are in the user's
2387 function body for the purposes of handing exceptions. */
2388 tree i_a_r_c_m
2389 = lookup_member (coro_frame_type, get_identifier ("__i_a_r_c"),
2390 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
2391 tree i_a_r_c
2392 = build_class_member_access_expr (actor_frame, i_a_r_c_m, NULL_TREE,
2393 false, tf_warning_or_error);
2394
2395 /* We've now rewritten the tree and added the initial and final
2396 co_awaits. Now pass over the tree and expand the co_awaits. */
2397
2398 coro_aw_data data = {actor, actor_fp, resume_pt_number, i_a_r_c,
2399 ash, del_promise_label, ret_label,
2400 continue_label, continuation, 2};
2401 cp_walk_tree (&actor_body, co_await_expander, &data, NULL);
2402
2403 actor_body = pop_stmt_list (actor_body);
2404 BIND_EXPR_BODY (actor_bind) = actor_body;
2405
2406 finish_compound_stmt (stmt);
2407 DECL_SAVED_TREE (actor) = pop_stmt_list (actor_outer);
2408 verify_stmt_tree (DECL_SAVED_TREE (actor));
2409 }
2410
2411 /* The prototype 'destroy' function :
2412 frame->__resume_at |= 1;
2413 actor (frame); */
2414
2415 static void
2416 build_destroy_fn (location_t loc, tree coro_frame_type, tree destroy,
2417 tree actor)
2418 {
2419 /* One param, the coro frame pointer. */
2420 tree destr_fp = DECL_ARGUMENTS (destroy);
2421
2422 /* A void return. */
2423 tree resdecl = build_decl (loc, RESULT_DECL, 0, void_type_node);
2424 DECL_ARTIFICIAL (resdecl) = 1;
2425 DECL_IGNORED_P (resdecl) = 1;
2426 DECL_RESULT (destroy) = resdecl;
2427
2428 /* We have a definition here. */
2429 TREE_STATIC (destroy) = 1;
2430 DECL_COROUTINE_P (destroy) = 1;
2431
2432 tree destr_outer = push_stmt_list ();
2433 current_stmt_tree ()->stmts_are_full_exprs_p = 1;
2434 tree dstr_stmt = begin_compound_stmt (BCS_FN_BODY);
2435
2436 tree destr_frame = build1 (INDIRECT_REF, coro_frame_type, destr_fp);
2437
2438 tree resume_idx_name = get_identifier ("__resume_at");
2439 tree rat_field = lookup_member (coro_frame_type, resume_idx_name, 1, 0,
2440 tf_warning_or_error);
2441 tree rat = build3 (COMPONENT_REF, short_unsigned_type_node, destr_frame,
2442 rat_field, NULL_TREE);
2443
2444 /* _resume_at |= 1 */
2445 tree dstr_idx = build2 (BIT_IOR_EXPR, short_unsigned_type_node, rat,
2446 build_int_cst (short_unsigned_type_node, 1));
2447 tree r = build2 (MODIFY_EXPR, short_unsigned_type_node, rat, dstr_idx);
2448 r = coro_build_cvt_void_expr_stmt (r, loc);
2449 add_stmt (r);
2450
2451 /* So .. call the actor .. */
2452 r = build_call_expr_loc (loc, actor, 1, destr_fp);
2453 r = coro_build_cvt_void_expr_stmt (r, loc);
2454 add_stmt (r);
2455
2456 /* done. */
2457 r = build_stmt (loc, RETURN_EXPR, NULL);
2458 r = maybe_cleanup_point_expr_void (r);
2459 add_stmt (r);
2460
2461 finish_compound_stmt (dstr_stmt);
2462 DECL_SAVED_TREE (destroy) = pop_stmt_list (destr_outer);
2463 }
2464
2465 /* Helper that returns an identifier for an appended extension to the
2466 current un-mangled function name. */
2467
2468 static tree
2469 get_fn_local_identifier (tree orig, const char *append)
2470 {
2471 /* Figure out the bits we need to generate names for the outlined things
2472 For consistency, this needs to behave the same way as
2473 ASM_FORMAT_PRIVATE_NAME does. */
2474 tree nm = DECL_NAME (orig);
2475 const char *sep, *pfx = "";
2476 #ifndef NO_DOT_IN_LABEL
2477 sep = ".";
2478 #else
2479 #ifndef NO_DOLLAR_IN_LABEL
2480 sep = "$";
2481 #else
2482 sep = "_";
2483 pfx = "__";
2484 #endif
2485 #endif
2486
2487 char *an;
2488 if (DECL_ASSEMBLER_NAME (orig))
2489 an = ACONCAT ((IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (orig)), sep, append,
2490 (char *) 0));
2491 else if (DECL_USE_TEMPLATE (orig) && DECL_TEMPLATE_INFO (orig)
2492 && DECL_TI_ARGS (orig))
2493 {
2494 tree tpl_args = DECL_TI_ARGS (orig);
2495 an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), (char *) 0));
2496 for (int i = 0; i < TREE_VEC_LENGTH (tpl_args); ++i)
2497 {
2498 tree typ = DECL_NAME (TYPE_NAME (TREE_VEC_ELT (tpl_args, i)));
2499 an = ACONCAT ((an, sep, IDENTIFIER_POINTER (typ), (char *) 0));
2500 }
2501 an = ACONCAT ((an, sep, append, (char *) 0));
2502 }
2503 else
2504 an = ACONCAT ((pfx, IDENTIFIER_POINTER (nm), sep, append, (char *) 0));
2505
2506 return get_identifier (an);
2507 }
2508
2509 static tree
2510 build_init_or_final_await (location_t loc, bool is_final)
2511 {
2512 tree suspend_alt = is_final ? coro_final_suspend_identifier
2513 : coro_initial_suspend_identifier;
2514 tree setup_meth = lookup_promise_method (current_function_decl, suspend_alt,
2515 loc, /*musthave=*/true);
2516 if (!setup_meth || setup_meth == error_mark_node)
2517 return error_mark_node;
2518
2519 tree s_fn = NULL_TREE;
2520 tree setup_call = build_new_method_call (
2521 get_coroutine_promise_proxy (current_function_decl), setup_meth, NULL,
2522 NULL_TREE, LOOKUP_NORMAL, &s_fn, tf_warning_or_error);
2523
2524 if (!s_fn || setup_call == error_mark_node)
2525 return error_mark_node;
2526
2527 /* So build the co_await for this */
2528 /* For initial/final suspends the call is "a" per [expr.await] 3.2. */
2529 return build_co_await (loc, setup_call, (is_final ? FINAL_SUSPEND_POINT
2530 : INITIAL_SUSPEND_POINT));
2531 }
2532
2533 /* Callback to record the essential data for each await point found in the
2534 function. */
2535
2536 static bool
2537 register_await_info (tree await_expr, tree aw_type, tree aw_nam)
2538 {
2539 bool seen;
2540 suspend_point_info &s
2541 = suspend_points->get_or_insert (await_expr, &seen);
2542 if (seen)
2543 {
2544 error_at (EXPR_LOCATION (await_expr), "duplicate info for %qE",
2545 await_expr);
2546 return false;
2547 }
2548 s.awaitable_type = aw_type;
2549 s.await_field_id = aw_nam;
2550 return true;
2551 }
2552
2553 /* Small helper for the repetitive task of adding a new field to the coro
2554 frame type. */
2555
2556 static tree
2557 coro_make_frame_entry (tree *field_list, const char *name, tree fld_type,
2558 location_t loc)
2559 {
2560 tree id = get_identifier (name);
2561 tree decl = build_decl (loc, FIELD_DECL, id, fld_type);
2562 DECL_CHAIN (decl) = *field_list;
2563 *field_list = decl;
2564 return id;
2565 }
2566
2567 struct susp_frame_data
2568 {
2569 tree *field_list;
2570 tree handle_type;
2571 hash_set<tree> captured_temps;
2572 vec<tree, va_gc> *to_replace;
2573 vec<tree, va_gc> *block_stack;
2574 unsigned count;
2575 unsigned saw_awaits;
2576 bool captures_temporary;
2577 };
2578
2579 /* Walk the sub-tree looking for call expressions that both capture
2580 references and have compiler-temporaries as parms. */
2581
2582 static tree
2583 captures_temporary (tree *stmt, int *do_subtree, void *d)
2584 {
2585 /* Stop recursing if we see an await expression, the subtrees
2586 of that will be handled when it is processed. */
2587 if (TREE_CODE (*stmt) == CO_AWAIT_EXPR || TREE_CODE (*stmt) == CO_YIELD_EXPR)
2588 {
2589 *do_subtree = 0;
2590 return NULL_TREE;
2591 }
2592
2593 /* We're only interested in calls. */
2594 if (TREE_CODE (*stmt) != CALL_EXPR)
2595 return NULL_TREE;
2596
2597 /* Does this call capture references?
2598 Strip the ADDRESS_EXPR to get the fn decl and inspect it. */
2599 tree fn = TREE_OPERAND (CALL_EXPR_FN (*stmt), 0);
2600 bool is_meth = TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE;
2601 tree arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
2602 unsigned offset = 3;
2603 for (unsigned anum = 0; arg != NULL; arg = TREE_CHAIN (arg), anum++)
2604 {
2605 tree parm_type = TREE_VALUE (arg);
2606 if (anum == 0 && is_meth && INDIRECT_TYPE_P (parm_type))
2607 {
2608 /* Account for 'this' when the fn is a method. Unless it
2609 belongs to a CTOR or DTOR. */
2610 if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
2611 continue;
2612 }
2613 else if (!TYPE_REF_P (parm_type))
2614 /* If it's not a reference, we don't care. */
2615 continue;
2616
2617 /* Fetch the value presented to the fn. */
2618 tree parm = TREE_OPERAND (*stmt, anum + offset);
2619
2620 while (TREE_CODE (parm) == NOP_EXPR)
2621 parm = TREE_OPERAND (parm, 0);
2622
2623 /* We only care if we're taking the addr of a temporary. */
2624 if (TREE_CODE (parm) != ADDR_EXPR)
2625 continue;
2626
2627 parm = TREE_OPERAND (parm, 0);
2628
2629 /* In case of component_ref, we need to capture the object of base
2630 class as if it is temporary object. There are two possibilities:
2631 (*base).field and base->field. */
2632 while (TREE_CODE (parm) == COMPONENT_REF)
2633 {
2634 parm = TREE_OPERAND (parm, 0);
2635 if (TREE_CODE (parm) == INDIRECT_REF)
2636 parm = TREE_OPERAND (parm, 0);
2637 parm = STRIP_NOPS (parm);
2638 }
2639
2640 /* This isn't a temporary. */
2641 if ((TREE_CODE (parm) == VAR_DECL && !DECL_ARTIFICIAL (parm))
2642 || TREE_CODE (parm) == PARM_DECL
2643 || TREE_CODE (parm) == NON_LVALUE_EXPR)
2644 continue;
2645
2646 if (TREE_CODE (parm) == TARGET_EXPR)
2647 {
2648 /* We're taking the address of a temporary and using it as a ref. */
2649 tree tvar = TREE_OPERAND (parm, 0);
2650 gcc_checking_assert (DECL_ARTIFICIAL (tvar));
2651
2652 susp_frame_data *data = (susp_frame_data *) d;
2653 data->captures_temporary = true;
2654 /* Record this one so we don't duplicate, and on the first
2655 occurrence note the target expr to be replaced. */
2656 if (!data->captured_temps.add (tvar))
2657 vec_safe_push (data->to_replace, parm);
2658 /* Now see if the initializer contains any more cases. */
2659 hash_set<tree> visited;
2660 tree res = cp_walk_tree (&TREE_OPERAND (parm, 1),
2661 captures_temporary, d, &visited);
2662 if (res)
2663 return res;
2664 /* Otherwise, we're done with sub-trees for this. */
2665 }
2666 else if (TREE_CODE (parm) == CO_AWAIT_EXPR)
2667 {
2668 /* CO_AWAIT expressions behave in a similar manner to target
2669 expressions when the await_resume call is contained in one. */
2670 tree awr = TREE_OPERAND (parm, 3); /* call vector. */
2671 awr = TREE_VEC_ELT (awr, 2); /* resume call. */
2672 if (TREE_CODE (awr) == TARGET_EXPR)
2673 {
2674 tree tvar = TREE_OPERAND (awr, 0);
2675 gcc_checking_assert (DECL_ARTIFICIAL (tvar));
2676
2677 susp_frame_data *data = (susp_frame_data *) d;
2678 data->captures_temporary = true;
2679 /* Use this as a place-holder. */
2680 if (!data->captured_temps.add (tvar))
2681 vec_safe_push (data->to_replace, parm);
2682 }
2683 /* We will walk the sub-trees of this co_await separately. */
2684 }
2685 else
2686 gcc_unreachable ();
2687 }
2688 /* As far as it's necessary, we've walked the subtrees of the call
2689 expr. */
2690 *do_subtree = 0;
2691 return NULL_TREE;
2692 }
2693
2694 /* If this is an await, then register it and decide on what coro
2695 frame storage is needed.
2696 If this is a co_yield (which embeds an await), drop the yield
2697 and record the await (the yield was kept for diagnostics only). */
2698
2699 static tree
2700 register_awaits (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
2701 {
2702 susp_frame_data *data = (susp_frame_data *) d;
2703
2704 if (TREE_CODE (*stmt) != CO_AWAIT_EXPR && TREE_CODE (*stmt) != CO_YIELD_EXPR)
2705 return NULL_TREE;
2706
2707 /* co_yield is syntactic sugar, re-write it to co_await. */
2708 tree aw_expr = *stmt;
2709 location_t aw_loc = EXPR_LOCATION (aw_expr); /* location of the co_xxxx. */
2710 if (TREE_CODE (aw_expr) == CO_YIELD_EXPR)
2711 {
2712 aw_expr = TREE_OPERAND (aw_expr, 1);
2713 *stmt = aw_expr;
2714 }
2715
2716 /* Count how many awaits full expression contains. This is not the same
2717 as the counter used for the function-wide await point number. */
2718 data->saw_awaits++;
2719
2720 /* If the awaitable is a parm or a local variable, then we already have
2721 a frame copy, so don't make a new one. */
2722 tree aw = TREE_OPERAND (aw_expr, 1);
2723 tree aw_field_type = TREE_TYPE (aw);
2724 tree aw_field_nam = NULL_TREE;
2725 if (INDIRECT_REF_P (aw))
2726 aw = TREE_OPERAND (aw, 0);
2727 if (TREE_CODE (aw) == PARM_DECL
2728 || (TREE_CODE (aw) == VAR_DECL && !DECL_ARTIFICIAL (aw)))
2729 ; /* Don't make an additional copy. */
2730 else
2731 {
2732 /* The required field has the same type as the proxy stored in the
2733 await expr. */
2734 char *nam = xasprintf ("__aw_s.%d", data->count);
2735 aw_field_nam = coro_make_frame_entry (data->field_list, nam,
2736 aw_field_type, aw_loc);
2737 free (nam);
2738 }
2739
2740 register_await_info (aw_expr, aw_field_type, aw_field_nam);
2741
2742 data->count++; /* Each await suspend context is unique. */
2743
2744 /* We now need to know if to take special action on lifetime extension
2745 of temporaries captured by reference. This can only happen if such
2746 a case appears in the initializer for the awaitable. The callback
2747 records captured temporaries including subtrees of initializers. */
2748 hash_set<tree> visited;
2749 tree res = cp_walk_tree (&TREE_OPERAND (aw_expr, 2), captures_temporary, d,
2750 &visited);
2751 return res;
2752 }
2753
2754 /* The gimplifier correctly extends the lifetime of temporaries captured
2755 by reference (per. [class.temporary] (6.9) "A temporary object bound
2756 to a reference parameter in a function call persists until the completion
2757 of the full-expression containing the call"). However, that is not
2758 sufficient to work across a suspension - and we need to promote such
2759 temporaries to be regular vars that will then get a coro frame slot.
2760 We don't want to incur the effort of checking for this unless we have
2761 an await expression in the current full expression. */
2762
2763 static tree
2764 maybe_promote_captured_temps (tree *stmt, void *d)
2765 {
2766 susp_frame_data *awpts = (susp_frame_data *) d;
2767 hash_set<tree> visited;
2768 awpts->saw_awaits = 0;
2769
2770 /* When register_awaits sees an await, it walks the initializer for
2771 that await looking for temporaries captured by reference and notes
2772 them in awpts->captured_temps. We only need to take any action here
2773 if the statement contained any awaits, and any of those had temporaries
2774 captured by reference in the initializers for their class. */
2775
2776 tree res = cp_walk_tree (stmt, register_awaits, d, &visited);
2777 if (!res && awpts->saw_awaits > 0 && !awpts->captured_temps.is_empty ())
2778 {
2779 location_t sloc = EXPR_LOCATION (*stmt);
2780 tree aw_bind
2781 = build3_loc (sloc, BIND_EXPR, void_type_node, NULL, NULL, NULL);
2782
2783 /* Any cleanup point expression might no longer be necessary, since we
2784 are removing one or more temporaries. */
2785 tree aw_statement_current = *stmt;
2786 if (TREE_CODE (aw_statement_current) == CLEANUP_POINT_EXPR)
2787 aw_statement_current = TREE_OPERAND (aw_statement_current, 0);
2788
2789 /* Collected the scope vars we need move the temps to regular. */
2790 tree aw_bind_body = push_stmt_list ();
2791 tree varlist = NULL_TREE;
2792 int vnum = -1;
2793 while (!awpts->to_replace->is_empty ())
2794 {
2795 size_t bufsize = sizeof ("__aw_.tmp.") + 20;
2796 char *buf = (char *) alloca (bufsize);
2797 snprintf (buf, bufsize, "__aw_%d.tmp.%d", awpts->count, ++vnum);
2798 tree to_replace = awpts->to_replace->pop ();
2799 tree orig_temp;
2800 if (TREE_CODE (to_replace) == CO_AWAIT_EXPR)
2801 {
2802 orig_temp = TREE_OPERAND (to_replace, 3);
2803 orig_temp = TREE_VEC_ELT (orig_temp, 2);
2804 orig_temp = TREE_OPERAND (orig_temp, 0);
2805 }
2806 else
2807 orig_temp = TREE_OPERAND (to_replace, 0);
2808
2809 tree var_type = TREE_TYPE (orig_temp);
2810 gcc_assert (same_type_p (TREE_TYPE (to_replace), var_type));
2811 tree newvar
2812 = build_lang_decl (VAR_DECL, get_identifier (buf), var_type);
2813 DECL_CONTEXT (newvar) = DECL_CONTEXT (orig_temp);
2814 if (DECL_SOURCE_LOCATION (orig_temp))
2815 sloc = DECL_SOURCE_LOCATION (orig_temp);
2816 DECL_SOURCE_LOCATION (newvar) = sloc;
2817 DECL_CHAIN (newvar) = varlist;
2818 varlist = newvar; /* Chain it onto the list for the bind expr. */
2819 /* Declare and initialze it in the new bind scope. */
2820 add_decl_expr (newvar);
2821 tree stmt
2822 = build2_loc (sloc, INIT_EXPR, var_type, newvar, to_replace);
2823 stmt = coro_build_cvt_void_expr_stmt (stmt, sloc);
2824 add_stmt (stmt);
2825 proxy_replace pr = {to_replace, newvar};
2826 /* Replace all instances of that temp in the original expr. */
2827 cp_walk_tree (&aw_statement_current, replace_proxy, &pr, NULL);
2828 }
2829
2830 /* What's left should be the original statement with any co_await
2831 captured temporaries broken out. Other temporaries might remain
2832 so see if we need to wrap the revised statement in a cleanup. */
2833 aw_statement_current =
2834 maybe_cleanup_point_expr_void (aw_statement_current);
2835 add_stmt (aw_statement_current);
2836 BIND_EXPR_BODY (aw_bind) = pop_stmt_list (aw_bind_body);
2837 awpts->captured_temps.empty ();
2838
2839 BIND_EXPR_VARS (aw_bind) = nreverse (varlist);
2840 tree b_block = make_node (BLOCK);
2841 if (!awpts->block_stack->is_empty ())
2842 {
2843 tree s_block = awpts->block_stack->last ();
2844 if (s_block)
2845 {
2846 BLOCK_SUPERCONTEXT (b_block) = s_block;
2847 BLOCK_CHAIN (b_block) = BLOCK_SUBBLOCKS (s_block);
2848 BLOCK_SUBBLOCKS (s_block) = b_block;
2849 }
2850 }
2851 BIND_EXPR_BLOCK (aw_bind) = b_block;
2852
2853 *stmt = aw_bind;
2854 }
2855 return res;
2856 }
2857
2858 static tree
2859 await_statement_walker (tree *stmt, int *do_subtree, void *d)
2860 {
2861 tree res = NULL_TREE;
2862 susp_frame_data *awpts = (susp_frame_data *) d;
2863
2864 /* We might need to insert a new bind expression, and want to link it
2865 into the correct scope, so keep a note of the current block scope. */
2866 if (TREE_CODE (*stmt) == BIND_EXPR)
2867 {
2868 tree *body = &BIND_EXPR_BODY (*stmt);
2869 tree blk = BIND_EXPR_BLOCK (*stmt);
2870 vec_safe_push (awpts->block_stack, blk);
2871
2872 if (TREE_CODE (*body) == STATEMENT_LIST)
2873 {
2874 tree_stmt_iterator i;
2875 for (i = tsi_start (*body); !tsi_end_p (i); tsi_next (&i))
2876 {
2877 tree *new_stmt = tsi_stmt_ptr (i);
2878 if (STATEMENT_CLASS_P (*new_stmt) || !EXPR_P (*new_stmt)
2879 || TREE_CODE (*new_stmt) == BIND_EXPR)
2880 res = cp_walk_tree (new_stmt, await_statement_walker, d, NULL);
2881 else
2882 res = maybe_promote_captured_temps (new_stmt, d);
2883 if (res)
2884 return res;
2885 }
2886 *do_subtree = 0; /* Done subtrees. */
2887 }
2888 else if (!STATEMENT_CLASS_P (*body) && EXPR_P (*body)
2889 && TREE_CODE (*body) != BIND_EXPR)
2890 {
2891 res = maybe_promote_captured_temps (body, d);
2892 *do_subtree = 0; /* Done subtrees. */
2893 }
2894 awpts->block_stack->pop ();
2895 }
2896 else if (!STATEMENT_CLASS_P (*stmt) && EXPR_P (*stmt)
2897 && TREE_CODE (*stmt) != BIND_EXPR)
2898 {
2899 res = maybe_promote_captured_temps (stmt, d);
2900 *do_subtree = 0; /* Done subtrees. */
2901 }
2902 /* If it wasn't a statement list, or a single statement, continue. */
2903 return res;
2904 }
2905
2906 /* For figuring out what param usage we have. */
2907
2908 struct param_frame_data
2909 {
2910 tree *field_list;
2911 hash_map<tree, param_info> *param_uses;
2912 hash_set<tree *> *visited;
2913 location_t loc;
2914 bool param_seen;
2915 };
2916
2917 static tree
2918 register_param_uses (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d)
2919 {
2920 param_frame_data *data = (param_frame_data *) d;
2921
2922 /* For lambda closure content, we have to look specifically. */
2923 if (TREE_CODE (*stmt) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (*stmt))
2924 {
2925 tree t = DECL_VALUE_EXPR (*stmt);
2926 return cp_walk_tree (&t, register_param_uses, d, NULL);
2927 }
2928
2929 if (TREE_CODE (*stmt) != PARM_DECL)
2930 return NULL_TREE;
2931
2932 /* If we already saw the containing expression, then we're done. */
2933 if (data->visited->add (stmt))
2934 return NULL_TREE;
2935
2936 bool existed;
2937 param_info &parm = data->param_uses->get_or_insert (*stmt, &existed);
2938 gcc_checking_assert (existed);
2939
2940 if (!parm.body_uses)
2941 {
2942 vec_alloc (parm.body_uses, 4);
2943 parm.body_uses->quick_push (stmt);
2944 data->param_seen = true;
2945 }
2946 else
2947 parm.body_uses->safe_push (stmt);
2948
2949 return NULL_TREE;
2950 }
2951
2952 /* For figuring out what local variable usage we have. */
2953
2954 struct local_vars_frame_data
2955 {
2956 tree *field_list;
2957 hash_map<tree, local_var_info> *local_var_uses;
2958 unsigned int nest_depth, bind_indx;
2959 location_t loc;
2960 bool saw_capture;
2961 bool local_var_seen;
2962 };
2963
2964 static tree
2965 register_local_var_uses (tree *stmt, int *do_subtree, void *d)
2966 {
2967 local_vars_frame_data *lvd = (local_vars_frame_data *) d;
2968
2969 /* As we enter a bind expression - record the vars there and then recurse.
2970 As we exit drop the nest depth.
2971 The bind index is a growing count of how many bind indices we've seen.
2972 We build a space in the frame for each local var. */
2973
2974 if (TREE_CODE (*stmt) == BIND_EXPR)
2975 {
2976 lvd->bind_indx++;
2977 lvd->nest_depth++;
2978 tree lvar;
2979 for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
2980 lvar = DECL_CHAIN (lvar))
2981 {
2982 bool existed;
2983 local_var_info &local_var
2984 = lvd->local_var_uses->get_or_insert (lvar, &existed);
2985 gcc_checking_assert (!existed);
2986 local_var.def_loc = DECL_SOURCE_LOCATION (lvar);
2987 tree lvtype = TREE_TYPE (lvar);
2988 local_var.frame_type = lvtype;
2989 local_var.field_idx = local_var.field_id = NULL_TREE;
2990 lvd->local_var_seen = true;
2991 /* If this var is a lambda capture proxy, we want to leave it alone,
2992 and later rewrite the DECL_VALUE_EXPR to indirect through the
2993 frame copy of the pointer to the lambda closure object. */
2994 local_var.is_lambda_capture = is_capture_proxy (lvar);
2995 if (local_var.is_lambda_capture)
2996 continue;
2997
2998 /* Make names depth+index unique, so that we can support nested
2999 scopes with identically named locals. */
3000 tree lvname = DECL_NAME (lvar);
3001 char *buf;
3002 if (lvname != NULL_TREE)
3003 buf = xasprintf ("__lv.%u.%u.%s", lvd->bind_indx, lvd->nest_depth,
3004 IDENTIFIER_POINTER (lvname));
3005 else
3006 buf = xasprintf ("__lv.%u.%u.D%u", lvd->bind_indx, lvd->nest_depth,
3007 DECL_UID (lvar));
3008 /* TODO: Figure out if we should build a local type that has any
3009 excess alignment or size from the original decl. */
3010 local_var.field_id
3011 = coro_make_frame_entry (lvd->field_list, buf, lvtype, lvd->loc);
3012 free (buf);
3013 /* We don't walk any of the local var sub-trees, they won't contain
3014 any bind exprs. */
3015 }
3016 cp_walk_tree (&BIND_EXPR_BODY (*stmt), register_local_var_uses, d, NULL);
3017 *do_subtree = 0; /* We've done this. */
3018 lvd->nest_depth--;
3019 }
3020 return NULL_TREE;
3021 }
3022
3023 /* Build, return FUNCTION_DECL node with its coroutine frame pointer argument
3024 for either actor or destroy functions. */
3025
3026 static tree
3027 act_des_fn (tree orig, tree fn_type, tree coro_frame_ptr, const char* name)
3028 {
3029 tree fn_name = get_fn_local_identifier (orig, name);
3030 tree fn = build_lang_decl (FUNCTION_DECL, fn_name, fn_type);
3031 DECL_CONTEXT (fn) = DECL_CONTEXT (orig);
3032 DECL_INITIAL (fn) = error_mark_node;
3033 tree id = get_identifier ("frame_ptr");
3034 tree fp = build_lang_decl (PARM_DECL, id, coro_frame_ptr);
3035 DECL_CONTEXT (fp) = fn;
3036 DECL_ARG_TYPE (fp) = type_passed_as (coro_frame_ptr);
3037 DECL_ARGUMENTS (fn) = fp;
3038 return fn;
3039 }
3040
3041 /* Here we:
3042 a) Check that the function and promise type are valid for a
3043 coroutine.
3044 b) Carry out the initial morph to create the skeleton of the
3045 coroutine ramp function and the rewritten body.
3046
3047 Assumptions.
3048
3049 1. We only hit this code once all dependencies are resolved.
3050 2. The function body will be either a bind expr or a statement list
3051 3. That cfun and current_function_decl are valid for the case we're
3052 expanding.
3053 4. 'input_location' will be of the final brace for the function.
3054
3055 We do something like this:
3056 declare a dummy coro frame.
3057 struct _R_frame {
3058 using handle_type = coro::coroutine_handle<coro1::promise_type>;
3059 void (*__resume)(_R_frame *);
3060 void (*__destroy)(_R_frame *);
3061 coro1::promise_type __p;
3062 bool frame_needs_free; free the coro frame mem if set.
3063 bool i_a_r_c; [dcl.fct.def.coroutine] / 5.3
3064 short __resume_at;
3065 handle_type self_handle;
3066 (maybe) parameter copies.
3067 coro1::suspend_never_prt __is;
3068 coro1::suspend_always_prt __fs;
3069 (maybe) local variables saved
3070 (maybe) trailing space.
3071 }; */
3072
3073 bool
3074 morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
3075 {
3076 gcc_checking_assert (orig && TREE_CODE (orig) == FUNCTION_DECL);
3077
3078 if (!coro_function_valid_p (orig))
3079 return false;
3080
3081 /* The ramp function does return a value. */
3082 current_function_returns_value = 1;
3083
3084 /* We can't validly get here with an empty statement list, since there's no
3085 way for the FE to decide it's a coroutine in the absence of any code. */
3086 tree fnbody = pop_stmt_list (DECL_SAVED_TREE (orig));
3087 if (fnbody == NULL_TREE)
3088 return false;
3089
3090 /* We don't have the locus of the opening brace - it's filled in later (and
3091 there doesn't really seem to be any easy way to get at it).
3092 The closing brace is assumed to be input_location. */
3093 location_t fn_start = DECL_SOURCE_LOCATION (orig);
3094 gcc_rich_location fn_start_loc (fn_start);
3095
3096 /* Initial processing of the function-body.
3097 If we have no expressions or just an error then punt. */
3098 tree body_start = expr_first (fnbody);
3099 if (body_start == NULL_TREE || body_start == error_mark_node)
3100 {
3101 DECL_SAVED_TREE (orig) = push_stmt_list ();
3102 append_to_statement_list (DECL_SAVED_TREE (orig), &fnbody);
3103 return false;
3104 }
3105
3106 /* So, we've tied off the original body. Now start the replacement.
3107 If we encounter a fatal error we might return a now-empty body.
3108 TODO: determine if it would help to restore the original.
3109 determine if looking for more errors in coro_function_valid_p()
3110 and stashing types is a better solution. */
3111
3112 tree newbody = push_stmt_list ();
3113 DECL_SAVED_TREE (orig) = newbody;
3114
3115 /* If our original body is noexcept, then that's what we apply to our
3116 generated functions. Remember that we're NOEXCEPT and fish out the
3117 contained list (we tied off to the top level already). */
3118 bool is_noexcept = TREE_CODE (body_start) == MUST_NOT_THROW_EXPR;
3119 if (is_noexcept)
3120 {
3121 /* Simplified abstract from begin_eh_spec_block, since we already
3122 know the outcome. */
3123 fnbody = TREE_OPERAND (body_start, 0); /* Stash the original... */
3124 add_stmt (body_start); /* ... and start the new. */
3125 TREE_OPERAND (body_start, 0) = push_stmt_list ();
3126 }
3127
3128 /* Create the coro frame type, as far as it can be known at this stage.
3129 1. Types we already know. */
3130
3131 tree fn_return_type = TREE_TYPE (TREE_TYPE (orig));
3132 gcc_assert (!VOID_TYPE_P (fn_return_type));
3133 tree handle_type = get_coroutine_handle_type (orig);
3134 tree promise_type = get_coroutine_promise_type (orig);
3135
3136 /* 2. Types we need to define or look up. */
3137
3138 /* We need to know, and inspect, each suspend point in the function
3139 in several places. It's convenient to place this map out of line
3140 since it's used from tree walk callbacks. */
3141 suspend_points = new hash_map<tree, suspend_point_info>;
3142
3143 /* Initial and final suspend types are special in that the co_awaits for
3144 them are synthetic. We need to find the type for each awaiter from
3145 the coroutine promise. */
3146 tree initial_await = build_init_or_final_await (fn_start, false);
3147 if (initial_await == error_mark_node)
3148 return false;
3149 /* The type of the frame var for this is the type of its temp proxy. */
3150 tree initial_suspend_type = TREE_TYPE (TREE_OPERAND (initial_await, 1));
3151
3152 tree final_await = build_init_or_final_await (fn_start, true);
3153 if (final_await == error_mark_node)
3154 return false;
3155
3156 /* The type of the frame var for this is the type of its temp proxy. */
3157 tree final_suspend_type = TREE_TYPE (TREE_OPERAND (final_await, 1));
3158
3159 tree fr_name = get_fn_local_identifier (orig, "frame");
3160 tree coro_frame_type = xref_tag (record_type, fr_name, ts_current, false);
3161 DECL_CONTEXT (TYPE_NAME (coro_frame_type)) = current_scope ();
3162 tree coro_frame_ptr = build_pointer_type (coro_frame_type);
3163 tree act_des_fn_type
3164 = build_function_type_list (void_type_node, coro_frame_ptr, NULL_TREE);
3165 tree act_des_fn_ptr = build_pointer_type (act_des_fn_type);
3166
3167 /* Declare the actor and destroyer function. */
3168 tree actor = act_des_fn (orig, act_des_fn_type, coro_frame_ptr, "actor");
3169 tree destroy = act_des_fn (orig, act_des_fn_type, coro_frame_ptr, "destroy");
3170
3171 /* Build our dummy coro frame layout. */
3172 coro_frame_type = begin_class_definition (coro_frame_type);
3173
3174 tree field_list = NULL_TREE;
3175 tree resume_name
3176 = coro_make_frame_entry (&field_list, "__resume", act_des_fn_ptr, fn_start);
3177 tree destroy_name = coro_make_frame_entry (&field_list, "__destroy",
3178 act_des_fn_ptr, fn_start);
3179 tree promise_name
3180 = coro_make_frame_entry (&field_list, "__p", promise_type, fn_start);
3181 tree fnf_name = coro_make_frame_entry (&field_list, "__frame_needs_free",
3182 boolean_type_node, fn_start);
3183 tree iarc_name = coro_make_frame_entry (&field_list, "__i_a_r_c",
3184 boolean_type_node, fn_start);
3185 tree resume_idx_name
3186 = coro_make_frame_entry (&field_list, "__resume_at",
3187 short_unsigned_type_node, fn_start);
3188
3189 /* We need a handle to this coroutine, which is passed to every
3190 await_suspend(). There's no point in creating it over and over. */
3191 (void) coro_make_frame_entry (&field_list, "__self_h", handle_type, fn_start);
3192
3193 /* Now add in fields for function params (if there are any).
3194 We do not attempt elision of copies at this stage, we do analyse the
3195 uses and build worklists to replace those when the state machine is
3196 lowered. */
3197
3198 hash_map<tree, param_info> *param_uses = NULL;
3199 if (DECL_ARGUMENTS (orig))
3200 {
3201 /* Build a hash map with an entry for each param.
3202 The key is the param tree.
3203 Then we have an entry for the frame field name.
3204 Then a cache for the field ref when we come to use it.
3205 Then a tree list of the uses.
3206 The second two entries start out empty - and only get populated
3207 when we see uses. */
3208 param_uses = new hash_map<tree, param_info>;
3209
3210 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
3211 arg = DECL_CHAIN (arg))
3212 {
3213 bool existed;
3214 param_info &parm = param_uses->get_or_insert (arg, &existed);
3215 gcc_checking_assert (!existed);
3216 parm.body_uses = NULL;
3217 tree actual_type = TREE_TYPE (arg);
3218 actual_type = complete_type_or_else (actual_type, orig);
3219 if (actual_type == NULL_TREE)
3220 actual_type = error_mark_node;
3221 parm.orig_type = actual_type;
3222 parm.by_ref = parm.rv_ref = parm.pt_ref = false;
3223 if (TREE_CODE (actual_type) == REFERENCE_TYPE
3224 && TYPE_REF_IS_RVALUE (DECL_ARG_TYPE (arg)))
3225 {
3226 parm.rv_ref = true;
3227 actual_type = TREE_TYPE (actual_type);
3228 parm.frame_type = actual_type;
3229 }
3230 else if (TREE_CODE (actual_type) == REFERENCE_TYPE)
3231 {
3232 /* If the user passes by reference, then we will save the
3233 pointer to the original. As noted in
3234 [dcl.fct.def.coroutine] / 13, if the lifetime of the
3235 referenced item ends and then the coroutine is resumed,
3236 we have UB; well, the user asked for it. */
3237 actual_type = build_pointer_type (TREE_TYPE (actual_type));
3238 parm.frame_type = actual_type;
3239 parm.pt_ref = true;
3240 }
3241 else if (TYPE_REF_P (DECL_ARG_TYPE (arg)))
3242 {
3243 parm.by_ref = true;
3244 parm.frame_type = actual_type;
3245 }
3246 else
3247 parm.frame_type = actual_type;
3248
3249 parm.trivial_dtor = TYPE_HAS_TRIVIAL_DESTRUCTOR (parm.frame_type);
3250 tree pname = DECL_NAME (arg);
3251 char *buf = xasprintf ("__parm.%s", IDENTIFIER_POINTER (pname));
3252 parm.field_id = coro_make_frame_entry
3253 (&field_list, buf, actual_type, DECL_SOURCE_LOCATION (arg));
3254 free (buf);
3255 }
3256
3257 /* We want to record every instance of param's use, so don't include
3258 a 'visited' hash_set on the tree walk, but only record a containing
3259 expression once. */
3260 hash_set<tree *> visited;
3261 param_frame_data param_data
3262 = {&field_list, param_uses, &visited, fn_start, false};
3263 cp_walk_tree (&fnbody, register_param_uses, &param_data, NULL);
3264 }
3265
3266 /* Initial suspend is mandated. */
3267 tree init_susp_name = coro_make_frame_entry (&field_list, "__aw_s.is",
3268 initial_suspend_type, fn_start);
3269
3270 register_await_info (initial_await, initial_suspend_type, init_susp_name);
3271
3272 /* Now insert the data for any body await points, at this time we also need
3273 to promote any temporaries that are captured by reference (to regular
3274 vars) they will get added to the coro frame along with other locals. */
3275 susp_frame_data body_aw_points
3276 = {&field_list, handle_type, hash_set<tree> (), NULL, NULL, 0, 0, false};
3277 body_aw_points.to_replace = make_tree_vector ();
3278 body_aw_points.block_stack = make_tree_vector ();
3279 cp_walk_tree (&fnbody, await_statement_walker, &body_aw_points, NULL);
3280
3281 /* Final suspend is mandated. */
3282 tree fin_susp_name = coro_make_frame_entry (&field_list, "__aw_s.fs",
3283 final_suspend_type, fn_start);
3284
3285 register_await_info (final_await, final_suspend_type, fin_susp_name);
3286
3287 /* 4. Now make space for local vars, this is conservative again, and we
3288 would expect to delete unused entries later. */
3289 hash_map<tree, local_var_info> local_var_uses;
3290 local_vars_frame_data local_vars_data
3291 = {&field_list, &local_var_uses, 0, 0, fn_start, false, false};
3292 cp_walk_tree (&fnbody, register_local_var_uses, &local_vars_data, NULL);
3293
3294 /* Tie off the struct for now, so that we can build offsets to the
3295 known entries. */
3296 TYPE_FIELDS (coro_frame_type) = field_list;
3297 TYPE_BINFO (coro_frame_type) = make_tree_binfo (0);
3298 BINFO_OFFSET (TYPE_BINFO (coro_frame_type)) = size_zero_node;
3299 BINFO_TYPE (TYPE_BINFO (coro_frame_type)) = coro_frame_type;
3300
3301 coro_frame_type = finish_struct (coro_frame_type, NULL_TREE);
3302
3303 /* Ramp: */
3304 /* Now build the ramp function pieces. */
3305 tree ramp_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3306 add_stmt (ramp_bind);
3307 tree ramp_body = push_stmt_list ();
3308 tree empty_list = build_empty_stmt (fn_start);
3309
3310 tree coro_fp = build_lang_decl (VAR_DECL, get_identifier ("coro.frameptr"),
3311 coro_frame_ptr);
3312 tree varlist = coro_fp;
3313
3314 /* Collected the scope vars we need ... only one for now. */
3315 BIND_EXPR_VARS (ramp_bind) = nreverse (varlist);
3316
3317 /* We're now going to create a new top level scope block for the ramp
3318 function. */
3319 tree top_block = make_node (BLOCK);
3320
3321 BIND_EXPR_BLOCK (ramp_bind) = top_block;
3322 BLOCK_VARS (top_block) = BIND_EXPR_VARS (ramp_bind);
3323 BLOCK_SUBBLOCKS (top_block) = NULL_TREE;
3324
3325 /* The decl_expr for the coro frame pointer, initialize to zero so that we
3326 can pass it to the IFN_CO_FRAME (since there's no way to pass a type,
3327 directly apparently). This avoids a "used uninitialized" warning. */
3328 tree r = build_stmt (fn_start, DECL_EXPR, coro_fp);
3329 tree zeroinit = build1 (CONVERT_EXPR, coro_frame_ptr, integer_zero_node);
3330 r = build2 (INIT_EXPR, TREE_TYPE (coro_fp), coro_fp, zeroinit);
3331 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3332 add_stmt (r);
3333
3334 /* The CO_FRAME internal function is a mechanism to allow the middle end
3335 to adjust the allocation in response to optimisations. We provide the
3336 current conservative estimate of the frame size (as per the current)
3337 computed layout. */
3338 tree frame_size = TYPE_SIZE_UNIT (coro_frame_type);
3339 tree resizeable
3340 = build_call_expr_internal_loc (fn_start, IFN_CO_FRAME, size_type_node, 2,
3341 frame_size, coro_fp);
3342
3343 /* n4849 [dcl.fct.def.coroutine] / 10 (part1)
3344 The unqualified-id get_return_object_on_allocation_failure is looked up
3345 in the scope of the promise type by class member access lookup. */
3346
3347 tree grooaf_meth
3348 = lookup_promise_method (orig, coro_gro_on_allocation_fail_identifier,
3349 fn_start, /*musthave=*/false);
3350
3351 tree grooaf = NULL_TREE;
3352 tree dummy_promise = build_dummy_object (get_coroutine_promise_type (orig));
3353
3354 /* We don't require this, so lookup_promise_method can return NULL... */
3355 if (grooaf_meth && BASELINK_P (grooaf_meth))
3356 {
3357 /* ... but, if the lookup succeeds, then the function must be
3358 usable.
3359 build_new_method_call () wants a valid pointer to (an empty) args
3360 list in this case. */
3361 vec<tree, va_gc> *args = make_tree_vector ();
3362 grooaf = build_new_method_call (dummy_promise, grooaf_meth, &args,
3363 NULL_TREE, LOOKUP_NORMAL, NULL,
3364 tf_warning_or_error);
3365 release_tree_vector (args);
3366 }
3367
3368 /* Allocate the frame, this has several possibilities:
3369 n4849 [dcl.fct.def.coroutine] / 9 (part 1)
3370 The allocation function’s name is looked up in the scope of the promise
3371 type. It's not a failure for it to be absent see part 4, below. */
3372 tree nwname = ovl_op_identifier (false, NEW_EXPR);
3373 tree fns = lookup_promise_method (orig, nwname, fn_start,
3374 /*musthave=*/false);
3375 tree new_fn = NULL_TREE;
3376 if (fns && BASELINK_P (fns))
3377 {
3378 /* n4849 [dcl.fct.def.coroutine] / 9 (part 2)
3379 If the lookup finds an allocation function in the scope of the promise
3380 type, overload resolution is performed on a function call created by
3381 assembling an argument list. The first argument is the amount of space
3382 requested, and has type std::size_t. The succeeding arguments are
3383 those of the original function. */
3384 vec<tree, va_gc> *args = make_tree_vector ();
3385 vec_safe_push (args, resizeable); /* Space needed. */
3386 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
3387 arg = DECL_CHAIN (arg))
3388 vec_safe_push (args, arg);
3389
3390 /* We might need to check that the provided function is nothrow. */
3391 tree func;
3392 /* Failure is OK for the first attempt. */
3393 new_fn = build_new_method_call (dummy_promise, fns, &args, NULL,
3394 LOOKUP_NORMAL, &func, tf_none);
3395 release_tree_vector (args);
3396
3397 if (!new_fn || new_fn == error_mark_node)
3398 {
3399 /* n4849 [dcl.fct.def.coroutine] / 9 (part 3)
3400 If no viable function is found, overload resolution is performed
3401 again on a function call created by passing just the amount of
3402 space required as an argument of type std::size_t. */
3403 args = make_tree_vector ();
3404 vec_safe_push (args, resizeable); /* Space needed. */
3405 new_fn = build_new_method_call (dummy_promise, fns, &args,
3406 NULL_TREE, LOOKUP_NORMAL, &func,
3407 tf_none);
3408 release_tree_vector (args);
3409 }
3410
3411 /* However, if the initial lookup succeeded, then one of these two
3412 options must be available. */
3413 if (!new_fn || new_fn == error_mark_node)
3414 {
3415 error_at (fn_start, "%qE is provided by %qT but is not usable with"
3416 " the function signature %qD", nwname, promise_type, orig);
3417 new_fn = error_mark_node;
3418 }
3419 else if (grooaf && !TYPE_NOTHROW_P (TREE_TYPE (func)))
3420 error_at (fn_start, "%qE is provided by %qT but %qE is not marked"
3421 " %<throw()%> or %<noexcept%>", grooaf, promise_type, nwname);
3422 }
3423 else
3424 {
3425 /* n4849 [dcl.fct.def.coroutine] / 9 (part 4)
3426 If this lookup fails, the allocation function’s name is looked up in
3427 the global scope. */
3428
3429 vec<tree, va_gc> *args;
3430 /* build_operator_new_call () will insert size needed as element 0 of
3431 this, and we might need to append the std::nothrow constant. */
3432 vec_alloc (args, 2);
3433
3434 if (grooaf)
3435 {
3436 /* n4849 [dcl.fct.def.coroutine] / 10 (part 2)
3437 If any declarations (of the get return on allocation fail) are
3438 found, then the result of a call to an allocation function used
3439 to obtain storage for the coroutine state is assumed to return
3440 nullptr if it fails to obtain storage and, if a global allocation
3441 function is selected, the ::operator new(size_t, nothrow_t) form
3442 is used. The allocation function used in this case shall have a
3443 non-throwing noexcept-specification. So we need std::nothrow. */
3444 tree std_nt = lookup_qualified_name (std_node,
3445 get_identifier ("nothrow"),
3446 0, /*complain=*/true, false);
3447 vec_safe_push (args, std_nt);
3448 }
3449
3450 /* If we get to this point, we must succeed in looking up the global
3451 operator new for the params provided. Extract a simplified version
3452 of the machinery from build_operator_new_call. This can update the
3453 frame size. */
3454 tree cookie = NULL;
3455 new_fn = build_operator_new_call (nwname, &args, &frame_size, &cookie,
3456 /*align_arg=*/NULL,
3457 /*size_check=*/NULL, /*fn=*/NULL,
3458 tf_warning_or_error);
3459 resizeable = build_call_expr_internal_loc
3460 (fn_start, IFN_CO_FRAME, size_type_node, 2, frame_size, coro_fp);
3461 CALL_EXPR_ARG (new_fn, 0) = resizeable;
3462
3463 release_tree_vector (args);
3464 }
3465
3466 tree allocated = build1 (CONVERT_EXPR, coro_frame_ptr, new_fn);
3467 r = build2 (INIT_EXPR, TREE_TYPE (coro_fp), coro_fp, allocated);
3468 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3469 add_stmt (r);
3470
3471 /* If the user provided a method to return an object on alloc fail, then
3472 check the returned pointer and call the func if it's null.
3473 Otherwise, no check, and we fail for noexcept/fno-exceptions cases. */
3474
3475 if (grooaf)
3476 {
3477 /* n4849 [dcl.fct.def.coroutine] / 10 (part 3)
3478 If the allocation function returns nullptr,the coroutine returns
3479 control to the caller of the coroutine and the return value is
3480 obtained by a call to T::get_return_object_on_allocation_failure(),
3481 where T is the promise type. */
3482 tree cfra_label
3483 = create_named_label_with_ctx (fn_start, "coro.frame.active",
3484 current_scope ());
3485 tree early_ret_list = NULL;
3486 /* init the retval using the user's func. */
3487 r = build2 (INIT_EXPR, TREE_TYPE (DECL_RESULT (orig)), DECL_RESULT (orig),
3488 grooaf);
3489 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3490 append_to_statement_list (r, &early_ret_list);
3491 /* We know it's the correct type. */
3492 r = DECL_RESULT (orig);
3493 r = build_stmt (fn_start, RETURN_EXPR, r);
3494 TREE_NO_WARNING (r) |= 1;
3495 r = maybe_cleanup_point_expr_void (r);
3496 append_to_statement_list (r, &early_ret_list);
3497
3498 tree goto_st = NULL;
3499 r = build1 (GOTO_EXPR, void_type_node, cfra_label);
3500 append_to_statement_list (r, &goto_st);
3501
3502 tree ckk = build1 (CONVERT_EXPR, coro_frame_ptr, integer_zero_node);
3503 tree ckz = build2 (EQ_EXPR, boolean_type_node, coro_fp, ckk);
3504 r = build3 (COND_EXPR, void_type_node, ckz, early_ret_list, empty_list);
3505 add_stmt (r);
3506
3507 cfra_label = build_stmt (fn_start, LABEL_EXPR, cfra_label);
3508 add_stmt (cfra_label);
3509 }
3510
3511 /* deref the frame pointer, to use in member access code. */
3512 tree deref_fp = build_x_arrow (fn_start, coro_fp, tf_warning_or_error);
3513
3514 /* For now, once allocation has succeeded we always assume that this needs
3515 destruction, there's no impl. for frame allocation elision. */
3516 tree fnf_m
3517 = lookup_member (coro_frame_type, fnf_name, 1, 0, tf_warning_or_error);
3518 tree fnf_x = build_class_member_access_expr (deref_fp, fnf_m, NULL_TREE,
3519 false, tf_warning_or_error);
3520 r = build2 (INIT_EXPR, boolean_type_node, fnf_x, boolean_true_node);
3521 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3522 add_stmt (r);
3523
3524 /* Put the resumer and destroyer functions in. */
3525
3526 tree actor_addr = build1 (ADDR_EXPR, act_des_fn_ptr, actor);
3527 tree resume_m
3528 = lookup_member (coro_frame_type, resume_name,
3529 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
3530 tree resume_x = build_class_member_access_expr (deref_fp, resume_m, NULL_TREE,
3531 false, tf_warning_or_error);
3532 r = build2_loc (fn_start, INIT_EXPR, act_des_fn_ptr, resume_x, actor_addr);
3533 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3534 add_stmt (r);
3535
3536 tree destroy_addr = build1 (ADDR_EXPR, act_des_fn_ptr, destroy);
3537 tree destroy_m
3538 = lookup_member (coro_frame_type, destroy_name,
3539 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
3540 tree destroy_x
3541 = build_class_member_access_expr (deref_fp, destroy_m, NULL_TREE, false,
3542 tf_warning_or_error);
3543 r = build2_loc (fn_start, INIT_EXPR, act_des_fn_ptr, destroy_x, destroy_addr);
3544 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3545 add_stmt (r);
3546
3547 /* n4849 [dcl.fct.def.coroutine] /13
3548 When a coroutine is invoked, a copy is created for each coroutine
3549 parameter. Each such copy is an object with automatic storage duration
3550 that is direct-initialized from an lvalue referring to the corresponding
3551 parameter if the parameter is an lvalue reference, and from an xvalue
3552 referring to it otherwise. A reference to a parameter in the function-
3553 body of the coroutine and in the call to the coroutine promise
3554 constructor is replaced by a reference to its copy. */
3555
3556 vec<tree, va_gc> *promise_args = NULL; /* So that we can adjust refs. */
3557
3558 /* The initialization and destruction of each parameter copy occurs in the
3559 context of the called coroutine. Initializations of parameter copies are
3560 sequenced before the call to the coroutine promise constructor and
3561 indeterminately sequenced with respect to each other. The lifetime of
3562 parameter copies ends immediately after the lifetime of the coroutine
3563 promise object ends. */
3564
3565 vec<tree, va_gc> *param_dtor_list = NULL;
3566
3567 if (DECL_ARGUMENTS (orig))
3568 {
3569 promise_args = make_tree_vector ();
3570 for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
3571 arg = DECL_CHAIN (arg))
3572 {
3573 bool existed;
3574 param_info &parm = param_uses->get_or_insert (arg, &existed);
3575
3576 tree fld_ref = lookup_member (coro_frame_type, parm.field_id,
3577 /*protect=*/1, /*want_type=*/0,
3578 tf_warning_or_error);
3579 tree fld_idx
3580 = build_class_member_access_expr (deref_fp, fld_ref, NULL_TREE,
3581 false, tf_warning_or_error);
3582
3583 /* Add this to the promise CTOR arguments list, accounting for
3584 refs. */
3585 if (parm.by_ref)
3586 vec_safe_push (promise_args, fld_idx);
3587 else if (parm.rv_ref)
3588 vec_safe_push (promise_args, rvalue (fld_idx));
3589 else
3590 vec_safe_push (promise_args, arg);
3591
3592 if (TYPE_NEEDS_CONSTRUCTING (parm.frame_type))
3593 {
3594 vec<tree, va_gc> *p_in;
3595 if (parm.by_ref
3596 && classtype_has_non_deleted_move_ctor (parm.frame_type)
3597 && !classtype_has_non_deleted_copy_ctor (parm.frame_type))
3598 p_in = make_tree_vector_single (rvalue (arg));
3599 else
3600 p_in = make_tree_vector_single (arg);
3601 /* Construct in place or move as relevant. */
3602 r = build_special_member_call (fld_idx, complete_ctor_identifier,
3603 &p_in, parm.frame_type,
3604 LOOKUP_NORMAL,
3605 tf_warning_or_error);
3606 release_tree_vector (p_in);
3607 }
3608 else
3609 {
3610 if (parm.rv_ref)
3611 r = convert_from_reference (arg);
3612 else if (!same_type_p (parm.frame_type, DECL_ARG_TYPE (arg)))
3613 r = build1_loc (DECL_SOURCE_LOCATION (arg), CONVERT_EXPR,
3614 parm.frame_type, arg);
3615 else
3616 r = arg;
3617 r = build_modify_expr (fn_start, fld_idx, parm.frame_type,
3618 INIT_EXPR, DECL_SOURCE_LOCATION (arg), r,
3619 TREE_TYPE (r));
3620 }
3621 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3622 add_stmt (r);
3623 if (!parm.trivial_dtor)
3624 {
3625 if (param_dtor_list == NULL)
3626 param_dtor_list = make_tree_vector ();
3627 vec_safe_push (param_dtor_list, parm.field_id);
3628 }
3629 }
3630 }
3631
3632 /* Set up the promise. */
3633 tree promise_m
3634 = lookup_member (coro_frame_type, promise_name,
3635 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
3636
3637 tree p = build_class_member_access_expr (deref_fp, promise_m, NULL_TREE,
3638 false, tf_warning_or_error);
3639
3640 if (TYPE_NEEDS_CONSTRUCTING (promise_type))
3641 {
3642 /* Do a placement new constructor for the promise type (we never call
3643 the new operator, just the constructor on the object in place in the
3644 frame).
3645
3646 First try to find a constructor with the same parameter list as the
3647 original function (if it has params), failing that find a constructor
3648 with no parameter list. */
3649
3650 if (DECL_ARGUMENTS (orig))
3651 {
3652 r = build_special_member_call (p, complete_ctor_identifier,
3653 &promise_args, promise_type,
3654 LOOKUP_NORMAL, tf_none);
3655 release_tree_vector (promise_args);
3656 }
3657 else
3658 r = NULL_TREE;
3659
3660 if (r == NULL_TREE || r == error_mark_node)
3661 r = build_special_member_call (p, complete_ctor_identifier, NULL,
3662 promise_type, LOOKUP_NORMAL,
3663 tf_warning_or_error);
3664
3665 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3666 add_stmt (r);
3667 }
3668
3669 /* Set up a new bind context for the GRO. */
3670 tree gro_context_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3671 /* Make and connect the scope blocks. */
3672 tree gro_block = make_node (BLOCK);
3673 BLOCK_SUPERCONTEXT (gro_block) = top_block;
3674 BLOCK_SUBBLOCKS (top_block) = gro_block;
3675 BIND_EXPR_BLOCK (gro_context_bind) = gro_block;
3676 add_stmt (gro_context_bind);
3677
3678 tree gro_meth = lookup_promise_method (orig,
3679 coro_get_return_object_identifier,
3680 fn_start, /*musthave=*/true );
3681 tree get_ro
3682 = build_new_method_call (p, gro_meth, NULL, NULL_TREE, LOOKUP_NORMAL, NULL,
3683 tf_warning_or_error);
3684 /* Without a return object we haven't got much clue what's going on. */
3685 if (get_ro == error_mark_node)
3686 {
3687 BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
3688 DECL_SAVED_TREE (orig) = newbody;
3689 return false;
3690 }
3691
3692 tree gro_context_body = push_stmt_list ();
3693 tree gro, gro_bind_vars;
3694 if (same_type_p (TREE_TYPE (get_ro), fn_return_type))
3695 {
3696 gro = DECL_RESULT (orig);
3697 gro_bind_vars = NULL_TREE; /* We don't need a separate var. */
3698 }
3699 else
3700 {
3701 gro = build_lang_decl (VAR_DECL, get_identifier ("coro.gro"),
3702 TREE_TYPE (TREE_OPERAND (get_ro, 0)));
3703 DECL_CONTEXT (gro) = current_scope ();
3704 r = build_stmt (fn_start, DECL_EXPR, gro);
3705 add_stmt (r);
3706 gro_bind_vars = gro; /* We need a temporary var. */
3707 }
3708
3709 /* Initialize our actual var. */
3710 r = build2_loc (fn_start, INIT_EXPR, TREE_TYPE (gro), gro, get_ro);
3711 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3712 add_stmt (r);
3713
3714 /* Initialize the resume_idx_name to 0, meaning "not started". */
3715 tree resume_idx_m
3716 = lookup_member (coro_frame_type, resume_idx_name,
3717 /*protect=*/1, /*want_type=*/0, tf_warning_or_error);
3718 tree resume_idx
3719 = build_class_member_access_expr (deref_fp, resume_idx_m, NULL_TREE, false,
3720 tf_warning_or_error);
3721 r = build_int_cst (short_unsigned_type_node, 0);
3722 r = build2_loc (fn_start, INIT_EXPR, short_unsigned_type_node, resume_idx, r);
3723 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3724 add_stmt (r);
3725
3726 /* Initialize 'initial-await-resume-called' as per
3727 [dcl.fct.def.coroutine] / 5.3 */
3728 tree i_a_r_c_m
3729 = lookup_member (coro_frame_type, iarc_name, 1, 0, tf_warning_or_error);
3730 tree i_a_r_c = build_class_member_access_expr (deref_fp, i_a_r_c_m,
3731 NULL_TREE, false,
3732 tf_warning_or_error);
3733 r = build2 (INIT_EXPR, boolean_type_node, i_a_r_c, boolean_false_node);
3734 r = coro_build_cvt_void_expr_stmt (r, fn_start);
3735 add_stmt (r);
3736
3737 /* So .. call the actor .. */
3738 r = build_call_expr_loc (fn_start, actor, 1, coro_fp);
3739 r = maybe_cleanup_point_expr_void (r);
3740 add_stmt (r);
3741
3742 /* Switch to using 'input_location' as the loc, since we're now more
3743 logically doing things related to the end of the function. */
3744
3745 /* The ramp is done, we just need the return value. */
3746 if (!same_type_p (TREE_TYPE (gro), fn_return_type))
3747 {
3748 /* construct the return value with a single GRO param. */
3749 vec<tree, va_gc> *args = make_tree_vector_single (gro);
3750 r = build_special_member_call (DECL_RESULT (orig),
3751 complete_ctor_identifier, &args,
3752 fn_return_type, LOOKUP_NORMAL,
3753 tf_warning_or_error);
3754 r = coro_build_cvt_void_expr_stmt (r, input_location);
3755 add_stmt (r);
3756 release_tree_vector (args);
3757 }
3758 /* Else the GRO is the return and we already built it in place. */
3759
3760 bool no_warning;
3761 r = check_return_expr (DECL_RESULT (orig), &no_warning);
3762 if (error_operand_p (r) && warn_return_type)
3763 /* Suppress -Wreturn-type for the ramp. */
3764 TREE_NO_WARNING (orig) = true;
3765
3766 r = build_stmt (input_location, RETURN_EXPR, DECL_RESULT (orig));
3767 TREE_NO_WARNING (r) |= no_warning;
3768 r = maybe_cleanup_point_expr_void (r);
3769 add_stmt (r);
3770 BIND_EXPR_VARS (gro_context_bind) = gro_bind_vars;
3771 BIND_EXPR_BODY (gro_context_bind) = pop_stmt_list (gro_context_body);
3772 BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body);
3773
3774 /* We know the "real" promise and have a frame layout with a slot for each
3775 suspend point, so we can build an actor function (which contains the
3776 functionality for both 'resume' and 'destroy').
3777
3778 wrap the function body in a try {} catch (...) {} block, if exceptions
3779 are enabled. */
3780
3781 /* First make a new block for the body - that will be embedded in the
3782 re-written function. */
3783 tree first = expr_first (fnbody);
3784 bool orig_fn_has_outer_bind = false;
3785 tree replace_blk = NULL_TREE;
3786 if (first && TREE_CODE (first) == BIND_EXPR)
3787 {
3788 orig_fn_has_outer_bind = true;
3789 tree block = BIND_EXPR_BLOCK (first);
3790 replace_blk = make_node (BLOCK);
3791 if (block) /* missing block is probably an error. */
3792 {
3793 gcc_assert (BLOCK_SUPERCONTEXT (block) == NULL_TREE);
3794 gcc_assert (BLOCK_CHAIN (block) == NULL_TREE);
3795 BLOCK_VARS (replace_blk) = BLOCK_VARS (block);
3796 BLOCK_SUBBLOCKS (replace_blk) = BLOCK_SUBBLOCKS (block);
3797 for (tree b = BLOCK_SUBBLOCKS (replace_blk); b; b = BLOCK_CHAIN (b))
3798 BLOCK_SUPERCONTEXT (b) = replace_blk;
3799 }
3800 BIND_EXPR_BLOCK (first) = replace_blk;
3801 }
3802
3803 /* actor's version of the promise. */
3804 tree actor_frame = build1_loc (fn_start, INDIRECT_REF, coro_frame_type,
3805 DECL_ARGUMENTS (actor));
3806 tree ap_m = lookup_member (coro_frame_type, get_identifier ("__p"), 1, 0,
3807 tf_warning_or_error);
3808 tree ap = build_class_member_access_expr (actor_frame, ap_m, NULL_TREE,
3809 false, tf_warning_or_error);
3810
3811 /* Now we've built the promise etc, process fnbody for co_returns.
3812 We want the call to return_void () below and it has no params so
3813 we can create it once here.
3814 Calls to return_value () will have to be checked and created as
3815 required. */
3816
3817 tree return_void = NULL_TREE;
3818 tree rvm
3819 = lookup_promise_method (orig, coro_return_void_identifier, fn_start,
3820 /*musthave=*/false);
3821 if (rvm && rvm != error_mark_node)
3822 return_void
3823 = build_new_method_call (ap, rvm, NULL, NULL_TREE, LOOKUP_NORMAL, NULL,
3824 tf_warning_or_error);
3825
3826 /* [stmt.return.coroutine] (2.2 : 3) if p.return_void() is a valid
3827 expression, flowing off the end of a coroutine is equivalent to
3828 co_return; otherwise UB.
3829 We just inject the call to p.return_void() here, and fall through to
3830 the final_suspend: label (eliding the goto). If the function body has
3831 a co_return, then this statement will be unreachable and DCEd. */
3832 if (return_void != NULL_TREE)
3833 {
3834 tree append = push_stmt_list ();
3835 add_stmt (fnbody);
3836 add_stmt (return_void);
3837 fnbody = pop_stmt_list(append);
3838 }
3839
3840 if (flag_exceptions)
3841 {
3842 tree ueh_meth
3843 = lookup_promise_method (orig, coro_unhandled_exception_identifier,
3844 fn_start, /*musthave=*/true);
3845 /* Build promise.unhandled_exception(); */
3846 tree ueh
3847 = build_new_method_call (ap, ueh_meth, NULL, NULL_TREE, LOOKUP_NORMAL,
3848 NULL, tf_warning_or_error);
3849
3850 /* The try block is just the original function, there's no real
3851 need to call any function to do this. */
3852 fnbody = build_stmt (fn_start, TRY_BLOCK, fnbody, NULL_TREE);
3853 TRY_HANDLERS (fnbody) = push_stmt_list ();
3854 /* Mimic what the parser does for the catch. */
3855 tree handler = begin_handler ();
3856 finish_handler_parms (NULL_TREE, handler); /* catch (...) */
3857
3858 /* Get the initial await resume called value. */
3859 tree i_a_r_c = build_class_member_access_expr (actor_frame, i_a_r_c_m,
3860 NULL_TREE, false,
3861 tf_warning_or_error);
3862 tree not_iarc_if = begin_if_stmt ();
3863 tree not_iarc = build1_loc (fn_start, TRUTH_NOT_EXPR,
3864 boolean_type_node, i_a_r_c);
3865 finish_if_stmt_cond (not_iarc, not_iarc_if);
3866 /* If the initial await resume called value is false, rethrow... */
3867 tree rethrow = build_throw (fn_start, NULL_TREE);
3868 TREE_NO_WARNING (rethrow) = true;
3869 finish_expr_stmt (rethrow);
3870 finish_then_clause (not_iarc_if);
3871 tree iarc_scope = IF_SCOPE (not_iarc_if);
3872 IF_SCOPE (not_iarc_if) = NULL;
3873 not_iarc_if = do_poplevel (iarc_scope);
3874 add_stmt (not_iarc_if);
3875 /* ... else call the promise unhandled exception method. */
3876 ueh = maybe_cleanup_point_expr_void (ueh);
3877 add_stmt (ueh);
3878 finish_handler (handler);
3879 TRY_HANDLERS (fnbody) = pop_stmt_list (TRY_HANDLERS (fnbody));
3880 /* If the function starts with a BIND_EXPR, then we need to create
3881 one here to contain the try-catch and to link up the scopes. */
3882 if (orig_fn_has_outer_bind)
3883 {
3884 fnbody = build3 (BIND_EXPR, void_type_node, NULL, fnbody, NULL);
3885 /* Make and connect the scope blocks. */
3886 tree tcb_block = make_node (BLOCK);
3887 /* .. and connect it here. */
3888 BLOCK_SUPERCONTEXT (replace_blk) = tcb_block;
3889 BLOCK_SUBBLOCKS (tcb_block) = replace_blk;
3890 BIND_EXPR_BLOCK (fnbody) = tcb_block;
3891 }
3892 }
3893 else if (pedantic)
3894 {
3895 /* We still try to look for the promise method and warn if it's not
3896 present. */
3897 tree ueh_meth
3898 = lookup_promise_method (orig, coro_unhandled_exception_identifier,
3899 fn_start, /*musthave=*/false);
3900 if (!ueh_meth || ueh_meth == error_mark_node)
3901 warning_at (fn_start, 0, "no member named %qE in %qT",
3902 coro_unhandled_exception_identifier,
3903 get_coroutine_promise_type (orig));
3904 }
3905 /* Else we don't check and don't care if the method is missing. */
3906
3907 /* Start to build the final functions.
3908
3909 We push_deferring_access_checks to avoid these routines being seen as
3910 nested by the middle end; we are doing the outlining here. */
3911
3912 push_deferring_access_checks (dk_no_check);
3913
3914 /* Actor ... */
3915 build_actor_fn (fn_start, coro_frame_type, actor, fnbody, orig, param_uses,
3916 &local_var_uses, param_dtor_list, initial_await, final_await,
3917 body_aw_points.count, frame_size);
3918
3919 /* Destroyer ... */
3920 build_destroy_fn (fn_start, coro_frame_type, destroy, actor);
3921
3922 pop_deferring_access_checks ();
3923
3924 DECL_SAVED_TREE (orig) = newbody;
3925 /* Link our new functions into the list. */
3926 TREE_CHAIN (destroy) = TREE_CHAIN (orig);
3927 TREE_CHAIN (actor) = destroy;
3928 TREE_CHAIN (orig) = actor;
3929
3930 *resumer = actor;
3931 *destroyer = destroy;
3932
3933 delete suspend_points;
3934 suspend_points = NULL;
3935 return true;
3936 }
3937
3938 #include "gt-cp-coroutines.h"
3939