* cp-tree.h (cp_expr): Remove copy constructor.
[official-gcc.git] / gcc / cp / optimize.c
blob0e9b84ed8a4d7e6a9aa6b7ef0c92948ff89c74ee
1 /* Perform optimizations on tree structure.
2 Copyright (C) 1998-2018 Free Software Foundation, Inc.
3 Written by Mark Michell (mark@codesourcery.com).
5 This file is part of GCC.
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.
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.
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/>. */
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"
32 /* Prototypes. */
34 static void update_cloned_parm (tree, tree, bool);
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. */
41 static void
42 update_cloned_parm (tree parm, tree cloned_parm, bool first)
44 DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
46 /* We may have taken its address. */
47 TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
49 /* The definition might have different constness. */
50 TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
52 TREE_USED (cloned_parm) = !first || TREE_USED (parm);
54 /* The name may have changed from the declaration. */
55 DECL_NAME (cloned_parm) = DECL_NAME (parm);
56 DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
57 TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
59 DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
63 /* FN is a function in High GIMPLE form that has a complete body and no
64 CFG. CLONE is a function whose body is to be set to a copy of FN,
65 mapping argument declarations according to the ARG_MAP splay_tree. */
67 static void
68 clone_body (tree clone, tree fn, void *arg_map)
70 copy_body_data id;
71 tree stmts;
73 /* Clone the body, as if we were making an inline call. But, remap
74 the parameters in the callee to the parameters of caller. */
75 memset (&id, 0, sizeof (id));
76 id.src_fn = fn;
77 id.dst_fn = clone;
78 id.src_cfun = DECL_STRUCT_FUNCTION (fn);
79 id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);
81 id.copy_decl = copy_decl_no_change;
82 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
83 id.transform_new_cfg = true;
84 id.transform_return_to_modify = false;
85 id.transform_lang_insert_block = NULL;
87 /* We're not inside any EH region. */
88 id.eh_lp_nr = 0;
90 stmts = DECL_SAVED_TREE (fn);
91 walk_tree (&stmts, copy_tree_body_r, &id, NULL);
93 /* Also remap the initializer of any static variables so that they (in
94 particular, any label addresses) correspond to the base variant rather
95 than the abstract one. */
96 if (DECL_NAME (clone) == base_dtor_identifier
97 || DECL_NAME (clone) == base_ctor_identifier)
99 unsigned ix;
100 tree decl;
102 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
103 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
106 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
109 /* DELETE_DTOR is a delete destructor whose body will be built.
110 COMPLETE_DTOR is the corresponding complete destructor. */
112 static void
113 build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
115 tree parm = DECL_ARGUMENTS (delete_dtor);
116 tree virtual_size = cxx_sizeof (current_class_type);
118 /* Call the corresponding complete destructor. */
119 gcc_assert (complete_dtor);
120 tree call_dtor = build_cxx_call (complete_dtor, 1, &parm,
121 tf_warning_or_error);
123 /* Call the delete function. */
124 tree call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
125 virtual_size,
126 /*global_p=*/false,
127 /*placement=*/NULL_TREE,
128 /*alloc_fn=*/NULL_TREE,
129 tf_warning_or_error);
131 /* Operator delete must be called, whether or not the dtor throws. */
132 add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node, call_dtor, call_delete));
134 /* Return the address of the object. */
135 if (targetm.cxx.cdtor_returns_this ())
137 tree val = DECL_ARGUMENTS (delete_dtor);
138 val = build2 (MODIFY_EXPR, TREE_TYPE (val),
139 DECL_RESULT (delete_dtor), val);
140 add_stmt (build_stmt (0, RETURN_EXPR, val));
144 /* Return name of comdat group for complete and base ctor (or dtor)
145 that have the same body. If dtor is virtual, deleting dtor goes
146 into this comdat group as well. */
148 static tree
149 cdtor_comdat_group (tree complete, tree base)
151 tree complete_name = DECL_ASSEMBLER_NAME (complete);
152 tree base_name = DECL_ASSEMBLER_NAME (base);
153 char *grp_name;
154 const char *p, *q;
155 bool diff_seen = false;
156 size_t idx;
157 gcc_assert (IDENTIFIER_LENGTH (complete_name)
158 == IDENTIFIER_LENGTH (base_name));
159 grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
160 p = IDENTIFIER_POINTER (complete_name);
161 q = IDENTIFIER_POINTER (base_name);
162 for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
163 if (p[idx] == q[idx])
164 grp_name[idx] = p[idx];
165 else
167 gcc_assert (!diff_seen
168 && idx > 0
169 && (p[idx - 1] == 'C' || p[idx - 1] == 'D'
170 || p[idx - 1] == 'I')
171 && p[idx] == '1'
172 && q[idx] == '2');
173 grp_name[idx] = '5';
174 diff_seen = true;
176 grp_name[idx] = '\0';
177 gcc_assert (diff_seen);
178 return get_identifier (grp_name);
181 /* Returns true iff we can make the base and complete [cd]tor aliases of
182 the same symbol rather than separate functions. */
184 static bool
185 can_alias_cdtor (tree fn)
187 /* If aliases aren't supported by the assembler, fail. */
188 if (!TARGET_SUPPORTS_ALIASES)
189 return false;
191 /* We can't use an alias if there are virtual bases. */
192 if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
193 return false;
194 /* ??? Why not use aliases with -frepo? */
195 if (flag_use_repository)
196 return false;
197 gcc_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn));
198 /* Don't use aliases for weak/linkonce definitions unless we can put both
199 symbols in the same COMDAT group. */
200 return (DECL_INTERFACE_KNOWN (fn)
201 && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn))
202 && (!DECL_ONE_ONLY (fn)
203 || (HAVE_COMDAT_GROUP && DECL_WEAK (fn))));
206 /* FN is a [cd]tor, fns is a pointer to an array of length 3. Fill fns
207 with pointers to the base, complete, and deleting variants. */
209 static void
210 populate_clone_array (tree fn, tree *fns)
212 tree clone;
214 fns[0] = NULL_TREE;
215 fns[1] = NULL_TREE;
216 fns[2] = NULL_TREE;
218 /* Look for the complete destructor which may be used to build the
219 delete destructor. */
220 FOR_EACH_CLONE (clone, fn)
221 if (DECL_NAME (clone) == complete_dtor_identifier
222 || DECL_NAME (clone) == complete_ctor_identifier)
223 fns[1] = clone;
224 else if (DECL_NAME (clone) == base_dtor_identifier
225 || DECL_NAME (clone) == base_ctor_identifier)
226 fns[0] = clone;
227 else if (DECL_NAME (clone) == deleting_dtor_identifier)
228 fns[2] = clone;
229 else
230 gcc_unreachable ();
233 /* FN is a constructor or destructor, and there are FUNCTION_DECLs
234 cloned from it nearby. Instead of cloning this body, leave it
235 alone and create tiny one-call bodies for the cloned
236 FUNCTION_DECLs. These clones are sibcall candidates, and their
237 resulting code will be very thunk-esque. */
239 static bool
240 maybe_thunk_body (tree fn, bool force)
242 tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist;
243 tree last_arg, modify, *args;
244 int parmno, vtt_parmno, max_parms;
245 tree fns[3];
247 if (!force && !flag_declone_ctor_dtor)
248 return 0;
250 /* If function accepts variable arguments, give up. */
251 last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
252 if (last_arg != void_list_node)
253 return 0;
255 /* If we got this far, we've decided to turn the clones into thunks. */
257 /* We're going to generate code for fn, so it is no longer "abstract."
258 Also make the unified ctor/dtor private to either the translation unit
259 (for non-vague linkage ctors) or the COMDAT group (otherwise). */
261 populate_clone_array (fn, fns);
263 /* Can happen during error recovery (c++/71464). */
264 if (!fns[0] || !fns[1])
265 return 0;
267 /* Don't use thunks if the base clone omits inherited parameters. */
268 if (ctor_omit_inherited_parms (fns[0]))
269 return 0;
271 DECL_ABSTRACT_P (fn) = false;
272 if (!DECL_WEAK (fn))
274 TREE_PUBLIC (fn) = false;
275 DECL_EXTERNAL (fn) = false;
276 DECL_INTERFACE_KNOWN (fn) = true;
278 else if (HAVE_COMDAT_GROUP)
280 /* At eof, defer creation of mangling aliases temporarily. */
281 bool save_defer_mangling_aliases = defer_mangling_aliases;
282 defer_mangling_aliases = true;
283 tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
284 defer_mangling_aliases = save_defer_mangling_aliases;
285 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
286 cgraph_node::get_create (fns[1])->add_to_same_comdat_group
287 (cgraph_node::get_create (fns[0]));
288 symtab_node::get (fn)->add_to_same_comdat_group
289 (symtab_node::get (fns[0]));
290 if (fns[2])
291 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
292 virtual, it goes into the same comdat group as well. */
293 cgraph_node::get_create (fns[2])->add_to_same_comdat_group
294 (symtab_node::get (fns[0]));
295 /* Emit them now that the thunks are same comdat group aliases. */
296 if (!save_defer_mangling_aliases)
297 generate_mangling_aliases ();
298 TREE_PUBLIC (fn) = false;
299 DECL_EXTERNAL (fn) = false;
300 DECL_INTERFACE_KNOWN (fn) = true;
301 /* function_and_variable_visibility doesn't want !PUBLIC decls to
302 have these flags set. */
303 DECL_WEAK (fn) = false;
304 DECL_COMDAT (fn) = false;
307 /* Find the vtt_parm, if present. */
308 for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
309 fn_parm;
310 ++parmno, fn_parm = TREE_CHAIN (fn_parm))
312 if (DECL_ARTIFICIAL (fn_parm)
313 && DECL_NAME (fn_parm) == vtt_parm_identifier)
315 /* Compensate for removed in_charge parameter. */
316 vtt_parmno = parmno;
317 break;
321 /* Allocate an argument buffer for build_cxx_call().
322 Make sure it is large enough for any of the clones. */
323 max_parms = 0;
324 FOR_EACH_CLONE (clone, fn)
326 int length = list_length (DECL_ARGUMENTS (fn));
327 if (length > max_parms)
328 max_parms = length;
330 args = XALLOCAVEC (tree, max_parms);
332 /* We know that any clones immediately follow FN in TYPE_FIELDS. */
333 FOR_EACH_CLONE (clone, fn)
335 tree clone_parm;
337 /* If we've already generated a body for this clone, avoid
338 duplicating it. (Is it possible for a clone-list to grow after we
339 first see it?) */
340 if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
341 continue;
343 /* Start processing the function. */
344 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
346 if (clone == fns[2])
348 for (clone_parm = DECL_ARGUMENTS (clone); clone_parm;
349 clone_parm = TREE_CHAIN (clone_parm))
350 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE;
351 /* Build the delete destructor by calling complete destructor and
352 delete function. */
353 build_delete_destructor_body (clone, fns[1]);
355 else
357 /* Walk parameter lists together, creating parameter list for
358 call to original function. */
359 for (parmno = 0,
360 fn_parm = DECL_ARGUMENTS (fn),
361 fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
362 clone_parm = DECL_ARGUMENTS (clone);
363 fn_parm;
364 ++parmno,
365 fn_parm = TREE_CHAIN (fn_parm))
367 if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
369 gcc_assert (fn_parm_typelist);
370 /* Clobber argument with formal parameter type. */
371 args[parmno]
372 = convert (TREE_VALUE (fn_parm_typelist),
373 null_pointer_node);
375 else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
377 tree in_charge
378 = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
379 args[parmno] = in_charge;
381 /* Map other parameters to their equivalents in the cloned
382 function. */
383 else
385 gcc_assert (clone_parm);
386 DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
387 args[parmno] = clone_parm;
388 clone_parm = TREE_CHAIN (clone_parm);
390 if (fn_parm_typelist)
391 fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
394 /* We built this list backwards; fix now. */
395 mark_used (fn);
396 call = build_cxx_call (fn, parmno, args, tf_warning_or_error);
397 /* Arguments passed to the thunk by invisible reference should
398 be transmitted to the callee unchanged. Do not create a
399 temporary and invoke the copy constructor. The thunking
400 transformation must not introduce any constructor calls. */
401 CALL_FROM_THUNK_P (call) = 1;
402 block = make_node (BLOCK);
403 if (targetm.cxx.cdtor_returns_this ())
405 clone_result = DECL_RESULT (clone);
406 modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
407 clone_result, call);
408 modify = build1 (RETURN_EXPR, void_type_node, modify);
409 add_stmt (modify);
411 else
413 add_stmt (call);
415 bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone),
416 block, cur_stmt_list);
417 DECL_SAVED_TREE (clone) = push_stmt_list ();
418 add_stmt (bind);
421 DECL_ABSTRACT_ORIGIN (clone) = NULL;
422 expand_or_defer_fn (finish_function (/*inline_p=*/false));
424 return 1;
427 /* FN is a function that has a complete body. Clone the body as
428 necessary. Returns nonzero if there's no longer any need to
429 process the main body. */
431 bool
432 maybe_clone_body (tree fn)
434 tree comdat_group = NULL_TREE;
435 tree clone;
436 tree fns[3];
437 bool first = true;
438 int idx;
439 bool need_alias = false;
441 /* We only clone constructors and destructors. */
442 if (!DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
443 return 0;
445 populate_clone_array (fn, fns);
447 /* Remember if we can't have multiple clones for some reason. We need to
448 check this before we remap local static initializers in clone_body. */
449 if (!tree_versionable_function_p (fn))
450 need_alias = true;
452 /* We know that any clones immediately follow FN in the TYPE_FIELDS
453 list. */
454 push_to_top_level ();
455 for (idx = 0; idx < 3; idx++)
457 tree parm;
458 tree clone_parm;
460 clone = fns[idx];
461 if (!clone)
462 continue;
464 /* Update CLONE's source position information to match FN's. */
465 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
466 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
467 DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
468 DECL_COMDAT (clone) = DECL_COMDAT (fn);
469 DECL_WEAK (clone) = DECL_WEAK (fn);
471 /* We don't copy the comdat group from fn to clone because the assembler
472 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
473 to it. By doing so, it also corrupted the comdat group. */
474 if (DECL_ONE_ONLY (fn))
475 cgraph_node::get_create (clone)->set_comdat_group (cxx_comdat_group (clone));
476 DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
477 DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
478 DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
479 DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
480 TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
481 DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
482 DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
483 DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
484 DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
485 DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
486 set_decl_section_name (clone, DECL_SECTION_NAME (fn));
488 /* Adjust the parameter names and locations. */
489 parm = DECL_ARGUMENTS (fn);
490 clone_parm = DECL_ARGUMENTS (clone);
491 /* Update the `this' parameter, which is always first. */
492 update_cloned_parm (parm, clone_parm, first);
493 parm = DECL_CHAIN (parm);
494 clone_parm = DECL_CHAIN (clone_parm);
495 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
496 parm = DECL_CHAIN (parm);
497 if (DECL_HAS_VTT_PARM_P (fn))
498 parm = DECL_CHAIN (parm);
499 if (DECL_HAS_VTT_PARM_P (clone))
500 clone_parm = DECL_CHAIN (clone_parm);
501 for (; parm && clone_parm;
502 parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
503 /* Update this parameter. */
504 update_cloned_parm (parm, clone_parm, first);
507 bool can_alias = can_alias_cdtor (fn);
509 /* If we decide to turn clones into thunks, they will branch to fn.
510 Must have original function available to call. */
511 if (!can_alias && maybe_thunk_body (fn, need_alias))
513 pop_from_top_level ();
514 /* We still need to emit the original function. */
515 return 0;
518 /* Emit the DWARF1 abstract instance. */
519 (*debug_hooks->deferred_inline_function) (fn);
521 /* We know that any clones immediately follow FN in the TYPE_FIELDS. */
522 for (idx = 0; idx < 3; idx++)
524 tree parm;
525 tree clone_parm;
526 int parmno;
527 hash_map<tree, tree> *decl_map;
528 bool alias = false;
530 clone = fns[idx];
531 if (!clone)
532 continue;
534 /* Start processing the function. */
535 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
537 /* Tell cgraph if both ctors or both dtors are known to have
538 the same body. */
539 if (can_alias
540 && fns[0]
541 && idx == 1
542 && cgraph_node::get_create (fns[0])->create_same_body_alias
543 (clone, fns[0]))
545 alias = true;
546 if (DECL_ONE_ONLY (fns[0]))
548 /* For comdat base and complete cdtors put them
549 into the same, *[CD]5* comdat group instead of
550 *[CD][12]*. */
551 comdat_group = cdtor_comdat_group (fns[1], fns[0]);
552 cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
553 if (symtab_node::get (clone)->same_comdat_group)
554 symtab_node::get (clone)->remove_from_same_comdat_group ();
555 symtab_node::get (clone)->add_to_same_comdat_group
556 (symtab_node::get (fns[0]));
560 /* Build the delete destructor by calling complete destructor
561 and delete function. */
562 if (idx == 2)
564 build_delete_destructor_body (clone, fns[1]);
565 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
566 virtual, it goes into the same comdat group as well. */
567 if (comdat_group)
568 cgraph_node::get_create (clone)->add_to_same_comdat_group
569 (symtab_node::get (fns[0]));
571 else if (alias)
572 /* No need to populate body. */ ;
573 else
575 /* If we can't have multiple copies of FN (say, because there's a
576 static local initialized with the address of a label), we need
577 to use an alias for the complete variant. */
578 if (idx == 1 && need_alias)
580 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
581 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
582 else
583 sorry ("making multiple clones of %qD", fn);
586 /* Remap the parameters. */
587 decl_map = new hash_map<tree, tree>;
588 for (parmno = 0,
589 parm = DECL_ARGUMENTS (fn),
590 clone_parm = DECL_ARGUMENTS (clone);
591 parm;
592 ++parmno,
593 parm = DECL_CHAIN (parm))
595 /* Map the in-charge parameter to an appropriate constant. */
596 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
598 tree in_charge;
599 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
600 decl_map->put (parm, in_charge);
602 else if (DECL_ARTIFICIAL (parm)
603 && DECL_NAME (parm) == vtt_parm_identifier)
605 /* For a subobject constructor or destructor, the next
606 argument is the VTT parameter. Remap the VTT_PARM
607 from the CLONE to this parameter. */
608 if (DECL_HAS_VTT_PARM_P (clone))
610 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
611 decl_map->put (parm, clone_parm);
612 clone_parm = DECL_CHAIN (clone_parm);
614 /* Otherwise, map the VTT parameter to `NULL'. */
615 else
617 tree t
618 = fold_convert (TREE_TYPE (parm), null_pointer_node);
619 decl_map->put (parm, t);
622 /* Map other parameters to their equivalents in the cloned
623 function. */
624 else
626 tree replacement;
627 if (clone_parm)
629 replacement = clone_parm;
630 clone_parm = DECL_CHAIN (clone_parm);
632 else
634 /* Inheriting ctors can omit parameters from the base
635 clone. Replace them with null lvalues. */
636 tree reftype = build_reference_type (TREE_TYPE (parm));
637 replacement = fold_convert (reftype, null_pointer_node);
638 replacement = convert_from_reference (replacement);
640 decl_map->put (parm, replacement);
644 if (targetm.cxx.cdtor_returns_this ())
646 parm = DECL_RESULT (fn);
647 clone_parm = DECL_RESULT (clone);
648 decl_map->put (parm, clone_parm);
651 /* Clone the body. */
652 clone_body (clone, fn, decl_map);
654 /* Clean up. */
655 delete decl_map;
658 /* The clone can throw iff the original function can throw. */
659 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
661 /* Now, expand this function into RTL, if appropriate. */
662 finish_function (/*inline_p=*/false);
663 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
664 if (alias)
666 if (expand_or_defer_fn_1 (clone))
667 emit_associated_thunks (clone);
668 /* We didn't generate a body, so remove the empty one. */
669 DECL_SAVED_TREE (clone) = NULL_TREE;
671 else
672 expand_or_defer_fn (clone);
673 first = false;
675 pop_from_top_level ();
677 /* We don't need to process the original function any further. */
678 return 1;