1 /* Perform optimizations on tree structure.
2 Copyright (C) 1998-2020 Free Software Foundation, Inc.
3 Written by Mark Michell (mark@codesourcery.com).
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "target.h"
25 #include "cp-tree.h"
26 #include "stringpool.h"
27 #include "cgraph.h"
28 #include "debug.h"
29 #include "tree-inline.h"
30 #include "tree-iterator.h"
31
32 /* Prototypes. */
33
34 static void update_cloned_parm (tree, tree, bool);
35
36 /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
37 or destructor. Update it to ensure that the source-position for
38 the cloned parameter matches that for the original, and that the
39 debugging generation code will be able to find the original PARM. */
40
41 static void
update_cloned_parm(tree parm,tree cloned_parm,bool first)42 update_cloned_parm (tree parm, tree cloned_parm, bool first)
43 {
44 DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
45
46 /* We may have taken its address. */
47 TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
48
49 DECL_BY_REFERENCE (cloned_parm) = DECL_BY_REFERENCE (parm);
50
51 /* The definition might have different constness. */
52 TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
53
54 TREE_USED (cloned_parm) = !first || TREE_USED (parm);
55
56 /* The name may have changed from the declaration. */
57 DECL_NAME (cloned_parm) = DECL_NAME (parm);
58 DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
59 TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
60
61 DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
62 }
63
64 /* Like copy_decl_no_change, but handle DECL_OMP_PRIVATIZED_MEMBER
65 properly. */
66
67 static tree
cxx_copy_decl(tree decl,copy_body_data * id)68 cxx_copy_decl (tree decl, copy_body_data *id)
69 {
70 tree copy = copy_decl_no_change (decl, id);
71 if (VAR_P (decl)
72 && DECL_HAS_VALUE_EXPR_P (decl)
73 && DECL_ARTIFICIAL (decl)
74 && DECL_LANG_SPECIFIC (decl)
75 && DECL_OMP_PRIVATIZED_MEMBER (decl))
76 {
77 tree expr = DECL_VALUE_EXPR (copy);
78 walk_tree (&expr, copy_tree_body_r, id, NULL);
79 SET_DECL_VALUE_EXPR (copy, expr);
80 }
81 return copy;
82 }
83
84 /* FN is a function in High GIMPLE form that has a complete body and no
85 CFG. CLONE is a function whose body is to be set to a copy of FN,
86 mapping argument declarations according to the ARG_MAP splay_tree. */
87
88 static void
clone_body(tree clone,tree fn,void * arg_map)89 clone_body (tree clone, tree fn, void *arg_map)
90 {
91 copy_body_data id;
92 tree stmts;
93
94 /* Clone the body, as if we were making an inline call. But, remap
95 the parameters in the callee to the parameters of caller. */
96 memset (&id, 0, sizeof (id));
97 id.src_fn = fn;
98 id.dst_fn = clone;
99 id.src_cfun = DECL_STRUCT_FUNCTION (fn);
100 id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);
101
102 id.copy_decl = cxx_copy_decl;
103 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
104 id.transform_new_cfg = true;
105 id.transform_return_to_modify = false;
106 id.transform_lang_insert_block = NULL;
107
108 /* We're not inside any EH region. */
109 id.eh_lp_nr = 0;
110
111 stmts = DECL_SAVED_TREE (fn);
112 walk_tree (&stmts, copy_tree_body_r, &id, NULL);
113
114 /* Also remap the initializer of any static variables so that they (in
115 particular, any label addresses) correspond to the base variant rather
116 than the abstract one. */
117 if (DECL_NAME (clone) == base_dtor_identifier
118 || DECL_NAME (clone) == base_ctor_identifier)
119 {
120 unsigned ix;
121 tree decl;
122
123 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
124 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
125 }
126
127 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
128 }
129
130 /* DELETE_DTOR is a delete destructor whose body will be built.
131 COMPLETE_DTOR is the corresponding complete destructor. */
132
133 static void
build_delete_destructor_body(tree delete_dtor,tree complete_dtor)134 build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
135 {
136 tree parm = DECL_ARGUMENTS (delete_dtor);
137 tree virtual_size = cxx_sizeof (current_class_type);
138
139 /* Call the delete function. */
140 tree call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
141 virtual_size,
142 /*global_p=*/false,
143 /*placement=*/NULL_TREE,
144 /*alloc_fn=*/NULL_TREE,
145 tf_warning_or_error);
146
147 tree op = get_callee_fndecl (call_delete);
148 if (op && DECL_P (op) && destroying_delete_p (op))
149 {
150 /* The destroying delete will handle calling complete_dtor. */
151 add_stmt (call_delete);
152 }
153 else
154 {
155 /* Call the corresponding complete destructor. */
156 gcc_assert (complete_dtor);
157 tree call_dtor = build_cxx_call (complete_dtor, 1, &parm,
158 tf_warning_or_error);
159
160 /* Operator delete must be called, whether or not the dtor throws. */
161 add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node,
162 call_dtor, call_delete));
163 }
164
165 /* Return the address of the object.
166 ??? How is it useful to return an invalid address? */
167 if (targetm.cxx.cdtor_returns_this ())
168 {
169 tree val = DECL_ARGUMENTS (delete_dtor);
170 val = build2 (MODIFY_EXPR, TREE_TYPE (val),
171 DECL_RESULT (delete_dtor), val);
172 add_stmt (build_stmt (0, RETURN_EXPR, val));
173 }
174 }
175
176 /* Return name of comdat group for complete and base ctor (or dtor)
177 that have the same body. If dtor is virtual, deleting dtor goes
178 into this comdat group as well. */
179
180 static tree
cdtor_comdat_group(tree complete,tree base)181 cdtor_comdat_group (tree complete, tree base)
182 {
183 tree complete_name = DECL_ASSEMBLER_NAME (complete);
184 tree base_name = DECL_ASSEMBLER_NAME (base);
185 char *grp_name;
186 const char *p, *q;
187 bool diff_seen = false;
188 size_t idx;
189 gcc_assert (IDENTIFIER_LENGTH (complete_name)
190 == IDENTIFIER_LENGTH (base_name));
191 grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
192 p = IDENTIFIER_POINTER (complete_name);
193 q = IDENTIFIER_POINTER (base_name);
194 for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
195 if (p[idx] == q[idx])
196 grp_name[idx] = p[idx];
197 else
198 {
199 gcc_assert (!diff_seen
200 && idx > 0
201 && (p[idx - 1] == 'C' || p[idx - 1] == 'D'
202 || p[idx - 1] == 'I')
203 && p[idx] == '1'
204 && q[idx] == '2');
205 grp_name[idx] = '5';
206 diff_seen = true;
207 }
208 grp_name[idx] = '\0';
209 gcc_assert (diff_seen);
210 return get_identifier (grp_name);
211 }
212
213 /* Returns true iff we can make the base and complete [cd]tor aliases of
214 the same symbol rather than separate functions. */
215
216 static bool
can_alias_cdtor(tree fn)217 can_alias_cdtor (tree fn)
218 {
219 /* If aliases aren't supported by the assembler, fail. */
220 if (!TARGET_SUPPORTS_ALIASES)
221 return false;
222
223 /* We can't use an alias if there are virtual bases. */
224 if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
225 return false;
226 gcc_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn));
227 /* Don't use aliases for weak/linkonce definitions unless we can put both
228 symbols in the same COMDAT group. */
229 return (DECL_INTERFACE_KNOWN (fn)
230 && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn))
231 && (!DECL_ONE_ONLY (fn)
232 || (HAVE_COMDAT_GROUP && DECL_WEAK (fn))));
233 }
234
235 /* FN is a [cd]tor, fns is a pointer to an array of length 3. Fill fns
236 with pointers to the base, complete, and deleting variants. */
237
238 static void
populate_clone_array(tree fn,tree * fns)239 populate_clone_array (tree fn, tree *fns)
240 {
241 tree clone;
242
243 fns[0] = NULL_TREE;
244 fns[1] = NULL_TREE;
245 fns[2] = NULL_TREE;
246
247 FOR_EACH_CLONE (clone, fn)
248 if (DECL_NAME (clone) == complete_dtor_identifier
249 || DECL_NAME (clone) == complete_ctor_identifier)
250 fns[1] = clone;
251 else if (DECL_NAME (clone) == base_dtor_identifier
252 || DECL_NAME (clone) == base_ctor_identifier)
253 fns[0] = clone;
254 else if (DECL_NAME (clone) == deleting_dtor_identifier)
255 fns[2] = clone;
256 else
257 gcc_unreachable ();
258 }
259
260 /* FN is a constructor or destructor, and there are FUNCTION_DECLs
261 cloned from it nearby. Instead of cloning this body, leave it
262 alone and create tiny one-call bodies for the cloned
263 FUNCTION_DECLs. These clones are sibcall candidates, and their
264 resulting code will be very thunk-esque. */
265
266 static bool
maybe_thunk_body(tree fn,bool force)267 maybe_thunk_body (tree fn, bool force)
268 {
269 tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist;
270 tree last_arg, modify, *args;
271 int parmno, vtt_parmno, max_parms;
272 tree fns[3];
273
274 if (!force && !flag_declone_ctor_dtor)
275 return 0;
276
277 /* If function accepts variable arguments, give up. */
278 last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
279 if (last_arg != void_list_node)
280 return 0;
281
282 /* If we got this far, we've decided to turn the clones into thunks. */
283
284 /* We're going to generate code for fn, so it is no longer "abstract."
285 Also make the unified ctor/dtor private to either the translation unit
286 (for non-vague linkage ctors) or the COMDAT group (otherwise). */
287
288 populate_clone_array (fn, fns);
289
290 /* Can happen during error recovery (c++/71464). */
291 if (!fns[0] || !fns[1])
292 return 0;
293
294 /* Don't use thunks if the base clone omits inherited parameters. */
295 if (ctor_omit_inherited_parms (fns[0]))
296 return 0;
297
298 DECL_ABSTRACT_P (fn) = false;
299 if (!DECL_WEAK (fn))
300 {
301 TREE_PUBLIC (fn) = false;
302 DECL_EXTERNAL (fn) = false;
303 DECL_INTERFACE_KNOWN (fn) = true;
304 }
305 else if (HAVE_COMDAT_GROUP)
306 {
307 /* At eof, defer creation of mangling aliases temporarily. */
308 bool save_defer_mangling_aliases = defer_mangling_aliases;
309 defer_mangling_aliases = true;
310 tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
311 defer_mangling_aliases = save_defer_mangling_aliases;
312 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
313 cgraph_node::get_create (fns[1])->add_to_same_comdat_group
314 (cgraph_node::get_create (fns[0]));
315 symtab_node::get (fn)->add_to_same_comdat_group
316 (symtab_node::get (fns[0]));
317 if (fns[2])
318 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
319 virtual, it goes into the same comdat group as well. */
320 cgraph_node::get_create (fns[2])->add_to_same_comdat_group
321 (symtab_node::get (fns[0]));
322 /* Emit them now that the thunks are same comdat group aliases. */
323 if (!save_defer_mangling_aliases)
324 generate_mangling_aliases ();
325 TREE_PUBLIC (fn) = false;
326 DECL_EXTERNAL (fn) = false;
327 DECL_INTERFACE_KNOWN (fn) = true;
328 /* function_and_variable_visibility doesn't want !PUBLIC decls to
329 have these flags set. */
330 DECL_WEAK (fn) = false;
331 DECL_COMDAT (fn) = false;
332 }
333
334 /* Find the vtt_parm, if present. */
335 for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
336 fn_parm;
337 ++parmno, fn_parm = TREE_CHAIN (fn_parm))
338 {
339 if (DECL_ARTIFICIAL (fn_parm)
340 && DECL_NAME (fn_parm) == vtt_parm_identifier)
341 {
342 /* Compensate for removed in_charge parameter. */
343 vtt_parmno = parmno;
344 break;
345 }
346 }
347
348 /* Allocate an argument buffer for build_cxx_call().
349 Make sure it is large enough for any of the clones. */
350 max_parms = 0;
351 FOR_EACH_CLONE (clone, fn)
352 {
353 int length = list_length (DECL_ARGUMENTS (fn));
354 if (length > max_parms)
355 max_parms = length;
356 }
357 args = XALLOCAVEC (tree, max_parms);
358
359 /* We know that any clones immediately follow FN in TYPE_FIELDS. */
360 FOR_EACH_CLONE (clone, fn)
361 {
362 tree clone_parm;
363
364 /* If we've already generated a body for this clone, avoid
365 duplicating it. (Is it possible for a clone-list to grow after we
366 first see it?) */
367 if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
368 continue;
369
370 /* Start processing the function. */
371 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
372
373 if (clone == fns[2])
374 {
375 for (clone_parm = DECL_ARGUMENTS (clone); clone_parm;
376 clone_parm = TREE_CHAIN (clone_parm))
377 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE;
378 /* Build the delete destructor by calling complete destructor and
379 delete function. */
380 build_delete_destructor_body (clone, fns[1]);
381 }
382 else
383 {
384 /* Walk parameter lists together, creating parameter list for
385 call to original function. */
386 for (parmno = 0,
387 fn_parm = DECL_ARGUMENTS (fn),
388 fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
389 clone_parm = DECL_ARGUMENTS (clone);
390 fn_parm;
391 ++parmno,
392 fn_parm = TREE_CHAIN (fn_parm))
393 {
394 if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
395 {
396 gcc_assert (fn_parm_typelist);
397 /* Clobber argument with formal parameter type. */
398 args[parmno]
399 = convert (TREE_VALUE (fn_parm_typelist),
400 null_pointer_node);
401 }
402 else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
403 {
404 tree in_charge
405 = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
406 args[parmno] = in_charge;
407 }
408 /* Map other parameters to their equivalents in the cloned
409 function. */
410 else
411 {
412 gcc_assert (clone_parm);
413 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
414 args[parmno] = clone_parm;
415 /* Clear TREE_ADDRESSABLE on thunk arguments. */
416 TREE_ADDRESSABLE (clone_parm) = 0;
417 clone_parm = TREE_CHAIN (clone_parm);
418 }
419 if (fn_parm_typelist)
420 fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
421 }
422
423 /* We built this list backwards; fix now. */
424 mark_used (fn);
425 call = build_cxx_call (fn, parmno, args, tf_warning_or_error);
426 /* Arguments passed to the thunk by invisible reference should
427 be transmitted to the callee unchanged. Do not create a
428 temporary and invoke the copy constructor. The thunking
429 transformation must not introduce any constructor calls. */
430 CALL_FROM_THUNK_P (call) = 1;
431 block = make_node (BLOCK);
432 if (targetm.cxx.cdtor_returns_this ())
433 {
434 clone_result = DECL_RESULT (clone);
435 modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
436 clone_result, call);
437 modify = build1 (RETURN_EXPR, void_type_node, modify);
438 add_stmt (modify);
439 }
440 else
441 {
442 add_stmt (call);
443 }
444 bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone),
445 block, cur_stmt_list);
446 DECL_SAVED_TREE (clone) = push_stmt_list ();
447 add_stmt (bind);
448 }
449
450 DECL_ABSTRACT_ORIGIN (clone) = NULL;
451 expand_or_defer_fn (finish_function (/*inline_p=*/false));
452 }
453 return 1;
454 }
455
456 /* FN is a function that has a complete body. Clone the body as
457 necessary. Returns nonzero if there's no longer any need to
458 process the main body. */
459
460 bool
maybe_clone_body(tree fn)461 maybe_clone_body (tree fn)
462 {
463 tree comdat_group = NULL_TREE;
464 tree clone;
465 tree fns[3];
466 bool first = true;
467 int idx;
468 bool need_alias = false;
469
470 /* We only clone constructors and destructors. */
471 if (!DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
472 return 0;
473
474 populate_clone_array (fn, fns);
475
476 /* Remember if we can't have multiple clones for some reason. We need to
477 check this before we remap local static initializers in clone_body. */
478 if (!tree_versionable_function_p (fn))
479 need_alias = true;
480
481 /* We know that any clones immediately follow FN in the TYPE_FIELDS
482 list. */
483 push_to_top_level ();
484 for (idx = 0; idx < 3; idx++)
485 {
486 tree parm;
487 tree clone_parm;
488
489 clone = fns[idx];
490 if (!clone)
491 continue;
492
493 /* Update CLONE's source position information to match FN's. */
494 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
495 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
496 DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
497 DECL_COMDAT (clone) = DECL_COMDAT (fn);
498 DECL_WEAK (clone) = DECL_WEAK (fn);
499
500 /* We don't copy the comdat group from fn to clone because the assembler
501 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
502 to it. By doing so, it also corrupted the comdat group. */
503 if (DECL_ONE_ONLY (fn))
504 cgraph_node::get_create (clone)->set_comdat_group (cxx_comdat_group (clone));
505 DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
506 DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
507 DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
508 DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
509 TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
510 DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
511 DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
512 DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
513 DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
514 DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
515 set_decl_section_name (clone, DECL_SECTION_NAME (fn));
516
517 /* Adjust the parameter names and locations. */
518 parm = DECL_ARGUMENTS (fn);
519 clone_parm = DECL_ARGUMENTS (clone);
520 /* Update the `this' parameter, which is always first. */
521 update_cloned_parm (parm, clone_parm, first);
522 parm = DECL_CHAIN (parm);
523 clone_parm = DECL_CHAIN (clone_parm);
524 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
525 parm = DECL_CHAIN (parm);
526 if (DECL_HAS_VTT_PARM_P (fn))
527 parm = DECL_CHAIN (parm);
528 if (DECL_HAS_VTT_PARM_P (clone))
529 clone_parm = DECL_CHAIN (clone_parm);
530 for (; parm && clone_parm;
531 parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
532 /* Update this parameter. */
533 update_cloned_parm (parm, clone_parm, first);
534 }
535
536 bool can_alias = can_alias_cdtor (fn);
537
538 /* If we decide to turn clones into thunks, they will branch to fn.
539 Must have original function available to call. */
540 if (!can_alias && maybe_thunk_body (fn, need_alias))
541 {
542 pop_from_top_level ();
543 /* We still need to emit the original function. */
544 return 0;
545 }
546
547 /* Emit the DWARF1 abstract instance. */
548 (*debug_hooks->deferred_inline_function) (fn);
549
550 /* We know that any clones immediately follow FN in the TYPE_FIELDS. */
551 for (idx = 0; idx < 3; idx++)
552 {
553 tree parm;
554 tree clone_parm;
555 int parmno;
556 hash_map<tree, tree> *decl_map;
557 bool alias = false;
558
559 clone = fns[idx];
560 if (!clone)
561 continue;
562
563 /* Start processing the function. */
564 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
565
566 /* Tell cgraph if both ctors or both dtors are known to have
567 the same body. */
568 if (can_alias
569 && fns[0]
570 && idx == 1
571 && cgraph_node::get_create (fns[0])->create_same_body_alias
572 (clone, fns[0]))
573 {
574 alias = true;
575 if (DECL_ONE_ONLY (fns[0]))
576 {
577 /* For comdat base and complete cdtors put them
578 into the same, *[CD]5* comdat group instead of
579 *[CD][12]*. */
580 comdat_group = cdtor_comdat_group (fns[1], fns[0]);
581 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
582 if (symtab_node::get (clone)->same_comdat_group)
583 symtab_node::get (clone)->remove_from_same_comdat_group ();
584 symtab_node::get (clone)->add_to_same_comdat_group
585 (symtab_node::get (fns[0]));
586 }
587 }
588
589 /* Build the delete destructor by calling complete destructor
590 and delete function. */
591 if (idx == 2)
592 {
593 build_delete_destructor_body (clone, fns[1]);
594 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
595 virtual, it goes into the same comdat group as well. */
596 if (comdat_group)
597 cgraph_node::get_create (clone)->add_to_same_comdat_group
598 (symtab_node::get (fns[0]));
599 }
600 else if (alias)
601 /* No need to populate body. */ ;
602 else
603 {
604 /* If we can't have multiple copies of FN (say, because there's a
605 static local initialized with the address of a label), we need
606 to use an alias for the complete variant. */
607 if (idx == 1 && need_alias)
608 {
609 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
610 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
611 else
612 sorry ("making multiple clones of %qD", fn);
613 }
614
615 /* Remap the parameters. */
616 decl_map = new hash_map<tree, tree>;
617 for (parmno = 0,
618 parm = DECL_ARGUMENTS (fn),
619 clone_parm = DECL_ARGUMENTS (clone);
620 parm;
621 ++parmno,
622 parm = DECL_CHAIN (parm))
623 {
624 /* Map the in-charge parameter to an appropriate constant. */
625 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
626 {
627 tree in_charge;
628 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
629 decl_map->put (parm, in_charge);
630 }
631 else if (DECL_ARTIFICIAL (parm)
632 && DECL_NAME (parm) == vtt_parm_identifier)
633 {
634 /* For a subobject constructor or destructor, the next
635 argument is the VTT parameter. Remap the VTT_PARM
636 from the CLONE to this parameter. */
637 if (DECL_HAS_VTT_PARM_P (clone))
638 {
639 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
640 decl_map->put (parm, clone_parm);
641 clone_parm = DECL_CHAIN (clone_parm);
642 }
643 /* Otherwise, map the VTT parameter to `NULL'. */
644 else
645 {
646 tree t
647 = fold_convert (TREE_TYPE (parm), null_pointer_node);
648 decl_map->put (parm, t);
649 }
650 }
651 /* Map other parameters to their equivalents in the cloned
652 function. */
653 else
654 {
655 tree replacement;
656 if (clone_parm)
657 {
658 replacement = clone_parm;
659 clone_parm = DECL_CHAIN (clone_parm);
660 }
661 else
662 {
663 /* Inheriting ctors can omit parameters from the base
664 clone. Replace them with null lvalues. */
665 tree reftype = build_reference_type (TREE_TYPE (parm));
666 replacement = fold_convert (reftype, null_pointer_node);
667 replacement = convert_from_reference (replacement);
668 }
669 decl_map->put (parm, replacement);
670 }
671 }
672
673 if (targetm.cxx.cdtor_returns_this ())
674 {
675 parm = DECL_RESULT (fn);
676 clone_parm = DECL_RESULT (clone);
677 decl_map->put (parm, clone_parm);
678 }
679
680 /* Clone the body. */
681 clone_body (clone, fn, decl_map);
682
683 /* Clean up. */
684 delete decl_map;
685 }
686
687 /* The clone can throw iff the original function can throw. */
688 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
689
690 /* Now, expand this function into RTL, if appropriate. */
691 finish_function (/*inline_p=*/false);
692 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
693 if (alias)
694 {
695 if (expand_or_defer_fn_1 (clone))
696 emit_associated_thunks (clone);
697 /* We didn't generate a body, so remove the empty one. */
698 DECL_SAVED_TREE (clone) = NULL_TREE;
699 }
700 else
701 expand_or_defer_fn (clone);
702 first = false;
703 }
704 pop_from_top_level ();
705
706 /* We don't need to process the original function any further. */
707 return 1;
708 }
709