1/* Perform optimizations on tree structure.
2   Copyright (C) 1998-2022 Free Software Foundation, Inc.
3   Written by Mark Michell (mark@codesourcery.com).
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along 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
34static 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
41static void
42update_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_NOT_GIMPLE_REG_P (cloned_parm) = DECL_NOT_GIMPLE_REG_P (parm);
62}
63
64/* Like copy_decl_no_change, but handle DECL_OMP_PRIVATIZED_MEMBER
65   properly.  */
66
67static tree
68cxx_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
88static void
89clone_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
107  /* We're not inside any EH region.  */
108  id.eh_lp_nr = 0;
109
110  stmts = DECL_SAVED_TREE (fn);
111  walk_tree (&stmts, copy_tree_body_r, &id, NULL);
112
113  /* Also remap the initializer of any static variables so that they (in
114     particular, any label addresses) correspond to the base variant rather
115     than the abstract one.  */
116  if (DECL_NAME (clone) == base_dtor_identifier
117      || DECL_NAME (clone) == base_ctor_identifier)
118    {
119      unsigned ix;
120      tree decl;
121
122      FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
123        walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
124    }
125
126  append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
127}
128
129/* DELETE_DTOR is a delete destructor whose body will be built.
130   COMPLETE_DTOR is the corresponding complete destructor.  */
131
132static void
133build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
134{
135  tree parm = DECL_ARGUMENTS (delete_dtor);
136  tree virtual_size = cxx_sizeof (current_class_type);
137
138  /* Call the delete function.  */
139  tree call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
140					   virtual_size,
141					   /*global_p=*/false,
142					   /*placement=*/NULL_TREE,
143					   /*alloc_fn=*/NULL_TREE,
144					   tf_warning_or_error);
145
146  tree op = get_callee_fndecl (call_delete);
147  if (op && DECL_P (op) && destroying_delete_p (op))
148    {
149      /* The destroying delete will handle calling complete_dtor.  */
150      add_stmt (call_delete);
151    }
152  else
153    {
154      /* Call the corresponding complete destructor.  */
155      gcc_assert (complete_dtor);
156      tree call_dtor = build_cxx_call (complete_dtor, 1, &parm,
157				       tf_warning_or_error);
158
159      /* Operator delete must be called, whether or not the dtor throws.  */
160      add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node,
161			call_dtor, call_delete));
162    }
163
164  /* Return the address of the object.
165     ??? How is it useful to return an invalid address?  */
166  if (targetm.cxx.cdtor_returns_this ())
167    {
168      tree val = DECL_ARGUMENTS (delete_dtor);
169      suppress_warning (val, OPT_Wuse_after_free);
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
180static tree
181cdtor_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
216static bool
217can_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
238static void
239populate_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
266static bool
267maybe_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
460bool
461maybe_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, 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