Don't warn when alignment of global common data exceeds maximum alignment.
[official-gcc.git] / gcc / cp / optimize.c
blob22ed7d357eea6b69de72cc101401191e2e124b8c
1 /* Perform optimizations on tree structure.
2 Copyright (C) 1998-2021 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 DECL_BY_REFERENCE (cloned_parm) = DECL_BY_REFERENCE (parm);
51 /* The definition might have different constness. */
52 TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
54 TREE_USED (cloned_parm) = !first || TREE_USED (parm);
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);
61 DECL_NOT_GIMPLE_REG_P (cloned_parm) = DECL_NOT_GIMPLE_REG_P (parm);
64 /* Like copy_decl_no_change, but handle DECL_OMP_PRIVATIZED_MEMBER
65 properly. */
67 static tree
68 cxx_copy_decl (tree decl, copy_body_data *id)
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))
77 tree expr = DECL_VALUE_EXPR (copy);
78 walk_tree (&expr, copy_tree_body_r, id, NULL);
79 SET_DECL_VALUE_EXPR (copy, expr);
81 return copy;
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. */
88 static void
89 clone_body (tree clone, tree fn, void *arg_map)
91 copy_body_data id;
92 tree stmts;
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);
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;
108 /* We're not inside any EH region. */
109 id.eh_lp_nr = 0;
111 stmts = DECL_SAVED_TREE (fn);
112 walk_tree (&stmts, copy_tree_body_r, &id, NULL);
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)
120 unsigned ix;
121 tree decl;
123 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
124 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
127 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
130 /* DELETE_DTOR is a delete destructor whose body will be built.
131 COMPLETE_DTOR is the corresponding complete destructor. */
133 static void
134 build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
136 tree parm = DECL_ARGUMENTS (delete_dtor);
137 tree virtual_size = cxx_sizeof (current_class_type);
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);
147 tree op = get_callee_fndecl (call_delete);
148 if (op && DECL_P (op) && destroying_delete_p (op))
150 /* The destroying delete will handle calling complete_dtor. */
151 add_stmt (call_delete);
153 else
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);
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));
165 /* Return the address of the object.
166 ??? How is it useful to return an invalid address? */
167 if (targetm.cxx.cdtor_returns_this ())
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));
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. */
180 static tree
181 cdtor_comdat_group (tree complete, tree base)
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
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;
208 grp_name[idx] = '\0';
209 gcc_assert (diff_seen);
210 return get_identifier (grp_name);
213 /* Returns true iff we can make the base and complete [cd]tor aliases of
214 the same symbol rather than separate functions. */
216 static bool
217 can_alias_cdtor (tree fn)
219 /* If aliases aren't supported by the assembler, fail. */
220 if (!TARGET_SUPPORTS_ALIASES)
221 return false;
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))));
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. */
238 static void
239 populate_clone_array (tree fn, tree *fns)
241 tree clone;
243 fns[0] = NULL_TREE;
244 fns[1] = NULL_TREE;
245 fns[2] = NULL_TREE;
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 ();
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. */
266 static bool
267 maybe_thunk_body (tree fn, bool force)
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];
274 if (!force && !flag_declone_ctor_dtor)
275 return 0;
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;
282 /* If we got this far, we've decided to turn the clones into thunks. */
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). */
288 populate_clone_array (fn, fns);
290 /* Can happen during error recovery (c++/71464). */
291 if (!fns[0] || !fns[1])
292 return 0;
294 /* Don't use thunks if the base clone omits inherited parameters. */
295 if (ctor_omit_inherited_parms (fns[0]))
296 return 0;
298 DECL_ABSTRACT_P (fn) = false;
299 if (!DECL_WEAK (fn))
301 TREE_PUBLIC (fn) = false;
302 DECL_EXTERNAL (fn) = false;
303 DECL_INTERFACE_KNOWN (fn) = true;
305 else if (HAVE_COMDAT_GROUP)
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;
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))
339 if (DECL_ARTIFICIAL (fn_parm)
340 && DECL_NAME (fn_parm) == vtt_parm_identifier)
342 /* Compensate for removed in_charge parameter. */
343 vtt_parmno = parmno;
344 break;
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)
353 int length = list_length (DECL_ARGUMENTS (fn));
354 if (length > max_parms)
355 max_parms = length;
357 args = XALLOCAVEC (tree, max_parms);
359 /* We know that any clones immediately follow FN in TYPE_FIELDS. */
360 FOR_EACH_CLONE (clone, fn)
362 tree clone_parm;
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;
370 /* Start processing the function. */
371 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
373 if (clone == fns[2])
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]);
382 else
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))
394 if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
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);
402 else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
404 tree in_charge
405 = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
406 args[parmno] = in_charge;
408 /* Map other parameters to their equivalents in the cloned
409 function. */
410 else
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);
419 if (fn_parm_typelist)
420 fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
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 ())
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);
440 else
442 add_stmt (call);
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);
450 DECL_ABSTRACT_ORIGIN (clone) = NULL;
451 expand_or_defer_fn (finish_function (/*inline_p=*/false));
453 return 1;
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. */
460 bool
461 maybe_clone_body (tree fn)
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;
470 /* We only clone constructors and destructors. */
471 if (!DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
472 return 0;
474 populate_clone_array (fn, fns);
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;
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++)
486 tree parm;
487 tree clone_parm;
489 clone = fns[idx];
490 if (!clone)
491 continue;
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);
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, fn);
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);
536 bool can_alias = can_alias_cdtor (fn);
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))
542 pop_from_top_level ();
543 /* We still need to emit the original function. */
544 return 0;
547 /* Emit the DWARF1 abstract instance. */
548 (*debug_hooks->deferred_inline_function) (fn);
550 /* We know that any clones immediately follow FN in the TYPE_FIELDS. */
551 for (idx = 0; idx < 3; idx++)
553 tree parm;
554 tree clone_parm;
555 int parmno;
556 hash_map<tree, tree> *decl_map;
557 bool alias = false;
559 clone = fns[idx];
560 if (!clone)
561 continue;
563 /* Start processing the function. */
564 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
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]))
574 alias = true;
575 if (DECL_ONE_ONLY (fns[0]))
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]));
589 /* Build the delete destructor by calling complete destructor
590 and delete function. */
591 if (idx == 2)
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]));
600 else if (alias)
601 /* No need to populate body. */ ;
602 else
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)
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);
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))
624 /* Map the in-charge parameter to an appropriate constant. */
625 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
627 tree in_charge;
628 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
629 decl_map->put (parm, in_charge);
631 else if (DECL_ARTIFICIAL (parm)
632 && DECL_NAME (parm) == vtt_parm_identifier)
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))
639 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
640 decl_map->put (parm, clone_parm);
641 clone_parm = DECL_CHAIN (clone_parm);
643 /* Otherwise, map the VTT parameter to `NULL'. */
644 else
646 tree t
647 = fold_convert (TREE_TYPE (parm), null_pointer_node);
648 decl_map->put (parm, t);
651 /* Map other parameters to their equivalents in the cloned
652 function. */
653 else
655 tree replacement;
656 if (clone_parm)
658 replacement = clone_parm;
659 clone_parm = DECL_CHAIN (clone_parm);
661 else
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);
669 decl_map->put (parm, replacement);
673 if (targetm.cxx.cdtor_returns_this ())
675 parm = DECL_RESULT (fn);
676 clone_parm = DECL_RESULT (clone);
677 decl_map->put (parm, clone_parm);
680 /* Clone the body. */
681 clone_body (clone, fn, decl_map);
683 /* Clean up. */
684 delete decl_map;
687 /* The clone can throw iff the original function can throw. */
688 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
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)
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;
700 else
701 expand_or_defer_fn (clone);
702 first = false;
704 pop_from_top_level ();
706 /* We don't need to process the original function any further. */
707 return 1;