xref: /dragonfly/contrib/gcc-8.0/gcc/cp/optimize.c (revision ed183f8c)
1 /* Perform optimizations on tree structure.
2    Copyright (C) 1998-2018 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
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
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
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
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 corresponding complete destructor.  */
140   gcc_assert (complete_dtor);
141   tree call_dtor = build_cxx_call (complete_dtor, 1, &parm,
142 				   tf_warning_or_error);
143 
144   /* Call the delete function.  */
145   tree call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
146 					   virtual_size,
147 					   /*global_p=*/false,
148 					   /*placement=*/NULL_TREE,
149 					   /*alloc_fn=*/NULL_TREE,
150 					   tf_warning_or_error);
151 
152   /* Operator delete must be called, whether or not the dtor throws.  */
153   add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node, call_dtor, call_delete));
154 
155   /* Return the address of the object.  */
156   if (targetm.cxx.cdtor_returns_this ())
157     {
158       tree val = DECL_ARGUMENTS (delete_dtor);
159       val = build2 (MODIFY_EXPR, TREE_TYPE (val),
160                     DECL_RESULT (delete_dtor), val);
161       add_stmt (build_stmt (0, RETURN_EXPR, val));
162     }
163 }
164 
165 /* Return name of comdat group for complete and base ctor (or dtor)
166    that have the same body.  If dtor is virtual, deleting dtor goes
167    into this comdat group as well.  */
168 
169 static tree
170 cdtor_comdat_group (tree complete, tree base)
171 {
172   tree complete_name = DECL_ASSEMBLER_NAME (complete);
173   tree base_name = DECL_ASSEMBLER_NAME (base);
174   char *grp_name;
175   const char *p, *q;
176   bool diff_seen = false;
177   size_t idx;
178   gcc_assert (IDENTIFIER_LENGTH (complete_name)
179 	      == IDENTIFIER_LENGTH (base_name));
180   grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
181   p = IDENTIFIER_POINTER (complete_name);
182   q = IDENTIFIER_POINTER (base_name);
183   for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
184     if (p[idx] == q[idx])
185       grp_name[idx] = p[idx];
186     else
187       {
188 	gcc_assert (!diff_seen
189 		    && idx > 0
190 		    && (p[idx - 1] == 'C' || p[idx - 1] == 'D'
191 			|| p[idx - 1] == 'I')
192 		    && p[idx] == '1'
193 		    && q[idx] == '2');
194 	grp_name[idx] = '5';
195 	diff_seen = true;
196       }
197   grp_name[idx] = '\0';
198   gcc_assert (diff_seen);
199   return get_identifier (grp_name);
200 }
201 
202 /* Returns true iff we can make the base and complete [cd]tor aliases of
203    the same symbol rather than separate functions.  */
204 
205 static bool
206 can_alias_cdtor (tree fn)
207 {
208   /* If aliases aren't supported by the assembler, fail.  */
209   if (!TARGET_SUPPORTS_ALIASES)
210     return false;
211 
212   /* We can't use an alias if there are virtual bases.  */
213   if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
214     return false;
215   /* ??? Why not use aliases with -frepo?  */
216   if (flag_use_repository)
217     return false;
218   gcc_assert (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
219 	      || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn));
220   /* Don't use aliases for weak/linkonce definitions unless we can put both
221      symbols in the same COMDAT group.  */
222   return (DECL_INTERFACE_KNOWN (fn)
223 	  && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn))
224 	  && (!DECL_ONE_ONLY (fn)
225 	      || (HAVE_COMDAT_GROUP && DECL_WEAK (fn))));
226 }
227 
228 /* FN is a [cd]tor, fns is a pointer to an array of length 3.  Fill fns
229    with pointers to the base, complete, and deleting variants.  */
230 
231 static void
232 populate_clone_array (tree fn, tree *fns)
233 {
234   tree clone;
235 
236   fns[0] = NULL_TREE;
237   fns[1] = NULL_TREE;
238   fns[2] = NULL_TREE;
239 
240   /* Look for the complete destructor which may be used to build the
241      delete destructor.  */
242   FOR_EACH_CLONE (clone, fn)
243     if (DECL_NAME (clone) == complete_dtor_identifier
244 	|| DECL_NAME (clone) == complete_ctor_identifier)
245       fns[1] = clone;
246     else if (DECL_NAME (clone) == base_dtor_identifier
247 	     || DECL_NAME (clone) == base_ctor_identifier)
248       fns[0] = clone;
249     else if (DECL_NAME (clone) == deleting_dtor_identifier)
250       fns[2] = clone;
251     else
252       gcc_unreachable ();
253 }
254 
255 /* FN is a constructor or destructor, and there are FUNCTION_DECLs
256    cloned from it nearby.  Instead of cloning this body, leave it
257    alone and create tiny one-call bodies for the cloned
258    FUNCTION_DECLs.  These clones are sibcall candidates, and their
259    resulting code will be very thunk-esque.  */
260 
261 static bool
262 maybe_thunk_body (tree fn, bool force)
263 {
264   tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist;
265   tree last_arg, modify, *args;
266   int parmno, vtt_parmno, max_parms;
267   tree fns[3];
268 
269   if (!force && !flag_declone_ctor_dtor)
270     return 0;
271 
272   /* If function accepts variable arguments, give up.  */
273   last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
274   if (last_arg != void_list_node)
275     return 0;
276 
277   /* If we got this far, we've decided to turn the clones into thunks.  */
278 
279   /* We're going to generate code for fn, so it is no longer "abstract."
280      Also make the unified ctor/dtor private to either the translation unit
281      (for non-vague linkage ctors) or the COMDAT group (otherwise).  */
282 
283   populate_clone_array (fn, fns);
284 
285   /* Can happen during error recovery (c++/71464).  */
286   if (!fns[0] || !fns[1])
287     return 0;
288 
289   /* Don't use thunks if the base clone omits inherited parameters.  */
290   if (ctor_omit_inherited_parms (fns[0]))
291     return 0;
292 
293   DECL_ABSTRACT_P (fn) = false;
294   if (!DECL_WEAK (fn))
295     {
296       TREE_PUBLIC (fn) = false;
297       DECL_EXTERNAL (fn) = false;
298       DECL_INTERFACE_KNOWN (fn) = true;
299     }
300   else if (HAVE_COMDAT_GROUP)
301     {
302       /* At eof, defer creation of mangling aliases temporarily.  */
303       bool save_defer_mangling_aliases = defer_mangling_aliases;
304       defer_mangling_aliases = true;
305       tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
306       defer_mangling_aliases = save_defer_mangling_aliases;
307       cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
308       cgraph_node::get_create (fns[1])->add_to_same_comdat_group
309 	(cgraph_node::get_create (fns[0]));
310       symtab_node::get (fn)->add_to_same_comdat_group
311 	(symtab_node::get (fns[0]));
312       if (fns[2])
313 	/* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
314 	   virtual, it goes into the same comdat group as well.  */
315 	cgraph_node::get_create (fns[2])->add_to_same_comdat_group
316 	  (symtab_node::get (fns[0]));
317       /* Emit them now that the thunks are same comdat group aliases.  */
318       if (!save_defer_mangling_aliases)
319 	generate_mangling_aliases ();
320       TREE_PUBLIC (fn) = false;
321       DECL_EXTERNAL (fn) = false;
322       DECL_INTERFACE_KNOWN (fn) = true;
323       /* function_and_variable_visibility doesn't want !PUBLIC decls to
324 	 have these flags set.  */
325       DECL_WEAK (fn) = false;
326       DECL_COMDAT (fn) = false;
327     }
328 
329   /* Find the vtt_parm, if present.  */
330   for (vtt_parmno = -1, parmno = 0, fn_parm = DECL_ARGUMENTS (fn);
331        fn_parm;
332        ++parmno, fn_parm = TREE_CHAIN (fn_parm))
333     {
334       if (DECL_ARTIFICIAL (fn_parm)
335 	  && DECL_NAME (fn_parm) == vtt_parm_identifier)
336 	{
337 	  /* Compensate for removed in_charge parameter.  */
338 	  vtt_parmno = parmno;
339 	  break;
340 	}
341     }
342 
343   /* Allocate an argument buffer for build_cxx_call().
344      Make sure it is large enough for any of the clones.  */
345   max_parms = 0;
346   FOR_EACH_CLONE (clone, fn)
347     {
348       int length = list_length (DECL_ARGUMENTS (fn));
349       if (length > max_parms)
350         max_parms = length;
351     }
352   args = XALLOCAVEC (tree, max_parms);
353 
354   /* We know that any clones immediately follow FN in TYPE_FIELDS.  */
355   FOR_EACH_CLONE (clone, fn)
356     {
357       tree clone_parm;
358 
359       /* If we've already generated a body for this clone, avoid
360 	 duplicating it.  (Is it possible for a clone-list to grow after we
361 	 first see it?)  */
362       if (DECL_SAVED_TREE (clone) || TREE_ASM_WRITTEN (clone))
363 	continue;
364 
365       /* Start processing the function.  */
366       start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
367 
368       if (clone == fns[2])
369 	{
370 	  for (clone_parm = DECL_ARGUMENTS (clone); clone_parm;
371 	       clone_parm = TREE_CHAIN (clone_parm))
372 	    DECL_ABSTRACT_ORIGIN (clone_parm) = NULL_TREE;
373 	  /* Build the delete destructor by calling complete destructor and
374 	     delete function.  */
375 	  build_delete_destructor_body (clone, fns[1]);
376 	}
377       else
378 	{
379 	  /* Walk parameter lists together, creating parameter list for
380 	     call to original function.  */
381 	  for (parmno = 0,
382 		 fn_parm = DECL_ARGUMENTS (fn),
383 		 fn_parm_typelist = TYPE_ARG_TYPES (TREE_TYPE (fn)),
384 		 clone_parm = DECL_ARGUMENTS (clone);
385 	       fn_parm;
386 	       ++parmno,
387 		 fn_parm = TREE_CHAIN (fn_parm))
388 	    {
389 	      if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
390 		{
391 		  gcc_assert (fn_parm_typelist);
392 		  /* Clobber argument with formal parameter type.  */
393 		  args[parmno]
394 		    = convert (TREE_VALUE (fn_parm_typelist),
395 			       null_pointer_node);
396 		}
397 	      else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
398 		{
399 		  tree in_charge
400 		    = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
401 		  args[parmno] = in_charge;
402 		}
403 	      /* Map other parameters to their equivalents in the cloned
404 		 function.  */
405 	      else
406 		{
407 		  gcc_assert (clone_parm);
408 		  DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
409 		  args[parmno] = clone_parm;
410 		  /* Clear TREE_ADDRESSABLE on thunk arguments.  */
411 		  TREE_ADDRESSABLE (clone_parm) = 0;
412 		  clone_parm = TREE_CHAIN (clone_parm);
413 		}
414 	      if (fn_parm_typelist)
415 		fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
416 	    }
417 
418 	  /* We built this list backwards; fix now.  */
419 	  mark_used (fn);
420 	  call = build_cxx_call (fn, parmno, args, tf_warning_or_error);
421 	  /* Arguments passed to the thunk by invisible reference should
422 	     be transmitted to the callee unchanged.  Do not create a
423 	     temporary and invoke the copy constructor.  The thunking
424 	     transformation must not introduce any constructor calls.  */
425 	  CALL_FROM_THUNK_P (call) = 1;
426 	  block = make_node (BLOCK);
427 	  if (targetm.cxx.cdtor_returns_this ())
428 	    {
429 	      clone_result = DECL_RESULT (clone);
430 	      modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
431 			       clone_result, call);
432 	      modify = build1 (RETURN_EXPR, void_type_node, modify);
433 	      add_stmt (modify);
434 	    }
435 	  else
436 	    {
437 	      add_stmt (call);
438 	    }
439 	  bind = c_build_bind_expr (DECL_SOURCE_LOCATION (clone),
440 				    block, cur_stmt_list);
441 	  DECL_SAVED_TREE (clone) = push_stmt_list ();
442 	  add_stmt (bind);
443 	}
444 
445       DECL_ABSTRACT_ORIGIN (clone) = NULL;
446       expand_or_defer_fn (finish_function (/*inline_p=*/false));
447     }
448   return 1;
449 }
450 
451 /* FN is a function that has a complete body.  Clone the body as
452    necessary.  Returns nonzero if there's no longer any need to
453    process the main body.  */
454 
455 bool
456 maybe_clone_body (tree fn)
457 {
458   tree comdat_group = NULL_TREE;
459   tree clone;
460   tree fns[3];
461   bool first = true;
462   int idx;
463   bool need_alias = false;
464 
465   /* We only clone constructors and destructors.  */
466   if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
467       && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
468     return 0;
469 
470   populate_clone_array (fn, fns);
471 
472   /* Remember if we can't have multiple clones for some reason.  We need to
473      check this before we remap local static initializers in clone_body.  */
474   if (!tree_versionable_function_p (fn))
475     need_alias = true;
476 
477   /* We know that any clones immediately follow FN in the TYPE_FIELDS
478      list.  */
479   push_to_top_level ();
480   for (idx = 0; idx < 3; idx++)
481     {
482       tree parm;
483       tree clone_parm;
484 
485       clone = fns[idx];
486       if (!clone)
487 	continue;
488 
489       /* Update CLONE's source position information to match FN's.  */
490       DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
491       DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
492       DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
493       DECL_COMDAT (clone) = DECL_COMDAT (fn);
494       DECL_WEAK (clone) = DECL_WEAK (fn);
495 
496       /* We don't copy the comdat group from fn to clone because the assembler
497 	 name of fn was corrupted by write_mangled_name by adding *INTERNAL*
498 	 to it. By doing so, it also corrupted the comdat group. */
499       if (DECL_ONE_ONLY (fn))
500 	cgraph_node::get_create (clone)->set_comdat_group (cxx_comdat_group (clone));
501       DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
502       DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
503       DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
504       DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
505       TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
506       DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
507       DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
508       DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
509       DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
510       DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
511       set_decl_section_name (clone, DECL_SECTION_NAME (fn));
512 
513       /* Adjust the parameter names and locations.  */
514       parm = DECL_ARGUMENTS (fn);
515       clone_parm = DECL_ARGUMENTS (clone);
516       /* Update the `this' parameter, which is always first.  */
517       update_cloned_parm (parm, clone_parm, first);
518       parm = DECL_CHAIN (parm);
519       clone_parm = DECL_CHAIN (clone_parm);
520       if (DECL_HAS_IN_CHARGE_PARM_P (fn))
521 	parm = DECL_CHAIN (parm);
522       if (DECL_HAS_VTT_PARM_P (fn))
523 	parm = DECL_CHAIN (parm);
524       if (DECL_HAS_VTT_PARM_P (clone))
525 	clone_parm = DECL_CHAIN (clone_parm);
526       for (; parm && clone_parm;
527 	   parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
528 	/* Update this parameter.  */
529 	update_cloned_parm (parm, clone_parm, first);
530     }
531 
532   bool can_alias = can_alias_cdtor (fn);
533 
534   /* If we decide to turn clones into thunks, they will branch to fn.
535      Must have original function available to call.  */
536   if (!can_alias && maybe_thunk_body (fn, need_alias))
537     {
538       pop_from_top_level ();
539       /* We still need to emit the original function.  */
540       return 0;
541     }
542 
543   /* Emit the DWARF1 abstract instance.  */
544   (*debug_hooks->deferred_inline_function) (fn);
545 
546   /* We know that any clones immediately follow FN in the TYPE_FIELDS. */
547   for (idx = 0; idx < 3; idx++)
548     {
549       tree parm;
550       tree clone_parm;
551       int parmno;
552       hash_map<tree, tree> *decl_map;
553       bool alias = false;
554 
555       clone = fns[idx];
556       if (!clone)
557 	continue;
558 
559       /* Start processing the function.  */
560       start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
561 
562       /* Tell cgraph if both ctors or both dtors are known to have
563 	 the same body.  */
564       if (can_alias
565 	  && fns[0]
566 	  && idx == 1
567 	  && cgraph_node::get_create (fns[0])->create_same_body_alias
568 	       (clone, fns[0]))
569 	{
570 	  alias = true;
571 	  if (DECL_ONE_ONLY (fns[0]))
572 	    {
573 	      /* For comdat base and complete cdtors put them
574 		 into the same, *[CD]5* comdat group instead of
575 		 *[CD][12]*.  */
576 	      comdat_group = cdtor_comdat_group (fns[1], fns[0]);
577 	      cgraph_node::get_create (fns[0])->set_comdat_group (comdat_group);
578 	      if (symtab_node::get (clone)->same_comdat_group)
579 		symtab_node::get (clone)->remove_from_same_comdat_group ();
580 	      symtab_node::get (clone)->add_to_same_comdat_group
581 		(symtab_node::get (fns[0]));
582 	    }
583 	}
584 
585       /* Build the delete destructor by calling complete destructor
586          and delete function.  */
587       if (idx == 2)
588 	{
589 	  build_delete_destructor_body (clone, fns[1]);
590 	  /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
591 	     virtual, it goes into the same comdat group as well.  */
592 	  if (comdat_group)
593 	    cgraph_node::get_create (clone)->add_to_same_comdat_group
594 	      (symtab_node::get (fns[0]));
595 	}
596       else if (alias)
597 	/* No need to populate body.  */ ;
598       else
599 	{
600 	  /* If we can't have multiple copies of FN (say, because there's a
601 	     static local initialized with the address of a label), we need
602 	     to use an alias for the complete variant.  */
603 	  if (idx == 1 && need_alias)
604 	    {
605 	      if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set)
606 		sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn);
607 	      else
608 		sorry ("making multiple clones of %qD", fn);
609 	    }
610 
611           /* Remap the parameters.  */
612           decl_map = new hash_map<tree, tree>;
613           for (parmno = 0,
614                 parm = DECL_ARGUMENTS (fn),
615                 clone_parm = DECL_ARGUMENTS (clone);
616               parm;
617               ++parmno,
618                 parm = DECL_CHAIN (parm))
619             {
620               /* Map the in-charge parameter to an appropriate constant.  */
621               if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
622                 {
623                   tree in_charge;
624                   in_charge = in_charge_arg_for_name (DECL_NAME (clone));
625                   decl_map->put (parm, in_charge);
626                 }
627               else if (DECL_ARTIFICIAL (parm)
628                        && DECL_NAME (parm) == vtt_parm_identifier)
629                 {
630                   /* For a subobject constructor or destructor, the next
631                      argument is the VTT parameter.  Remap the VTT_PARM
632                      from the CLONE to this parameter.  */
633                   if (DECL_HAS_VTT_PARM_P (clone))
634                     {
635                       DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
636                       decl_map->put (parm, clone_parm);
637                       clone_parm = DECL_CHAIN (clone_parm);
638                     }
639                   /* Otherwise, map the VTT parameter to `NULL'.  */
640                   else
641 		    {
642 		      tree t
643 			= fold_convert (TREE_TYPE (parm), null_pointer_node);
644 		      decl_map->put (parm, t);
645 		    }
646                 }
647               /* Map other parameters to their equivalents in the cloned
648                  function.  */
649               else
650                 {
651 		  tree replacement;
652 		  if (clone_parm)
653 		    {
654 		      replacement = clone_parm;
655 		      clone_parm = DECL_CHAIN (clone_parm);
656 		    }
657 		  else
658 		    {
659 		      /* Inheriting ctors can omit parameters from the base
660 			 clone.  Replace them with null lvalues.  */
661 		      tree reftype = build_reference_type (TREE_TYPE (parm));
662 		      replacement = fold_convert (reftype, null_pointer_node);
663 		      replacement = convert_from_reference (replacement);
664 		    }
665                   decl_map->put (parm, replacement);
666                 }
667             }
668 
669           if (targetm.cxx.cdtor_returns_this ())
670             {
671               parm = DECL_RESULT (fn);
672               clone_parm = DECL_RESULT (clone);
673               decl_map->put (parm, clone_parm);
674             }
675 
676           /* Clone the body.  */
677           clone_body (clone, fn, decl_map);
678 
679           /* Clean up.  */
680           delete decl_map;
681         }
682 
683       /* The clone can throw iff the original function can throw.  */
684       cp_function_chain->can_throw = !TREE_NOTHROW (fn);
685 
686       /* Now, expand this function into RTL, if appropriate.  */
687       finish_function (/*inline_p=*/false);
688       BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
689       if (alias)
690 	{
691 	  if (expand_or_defer_fn_1 (clone))
692 	    emit_associated_thunks (clone);
693 	  /* We didn't generate a body, so remove the empty one.  */
694 	  DECL_SAVED_TREE (clone) = NULL_TREE;
695 	}
696       else
697 	expand_or_defer_fn (clone);
698       first = false;
699     }
700   pop_from_top_level ();
701 
702   /* We don't need to process the original function any further.  */
703   return 1;
704 }
705