re PR c++/41090 (Using static label reference in c++ class constructor produces wrong...
[platform/upstream/gcc.git] / gcc / cp / optimize.c
1 /* Perform optimizations on tree structure.
2    Copyright (C) 1998-2013 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 "tm.h"
25 #include "tree.h"
26 #include "stringpool.h"
27 #include "cp-tree.h"
28 #include "input.h"
29 #include "params.h"
30 #include "hashtab.h"
31 #include "target.h"
32 #include "debug.h"
33 #include "tree-inline.h"
34 #include "flags.h"
35 #include "langhooks.h"
36 #include "diagnostic-core.h"
37 #include "dumpfile.h"
38 #include "pointer-set.h"
39 #include "tree-iterator.h"
40 #include "cgraph.h"
41
42 /* Prototypes.  */
43
44 static void update_cloned_parm (tree, tree, bool);
45
46 /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
47    or destructor.  Update it to ensure that the source-position for
48    the cloned parameter matches that for the original, and that the
49    debugging generation code will be able to find the original PARM.  */
50
51 static void
52 update_cloned_parm (tree parm, tree cloned_parm, bool first)
53 {
54   DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
55
56   /* We may have taken its address.  */
57   TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
58
59   /* The definition might have different constness.  */
60   TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
61
62   TREE_USED (cloned_parm) = !first || TREE_USED (parm);
63
64   /* The name may have changed from the declaration.  */
65   DECL_NAME (cloned_parm) = DECL_NAME (parm);
66   DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
67   TREE_TYPE (cloned_parm) = TREE_TYPE (parm);
68
69   DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
70 }
71
72
73 /* FN is a function in High GIMPLE form that has a complete body and no
74    CFG.  CLONE is a function whose body is to be set to a copy of FN,
75    mapping argument declarations according to the ARG_MAP splay_tree.  */
76
77 static void
78 clone_body (tree clone, tree fn, void *arg_map)
79 {
80   copy_body_data id;
81   tree stmts;
82
83   /* Clone the body, as if we were making an inline call.  But, remap
84      the parameters in the callee to the parameters of caller.  */
85   memset (&id, 0, sizeof (id));
86   id.src_fn = fn;
87   id.dst_fn = clone;
88   id.src_cfun = DECL_STRUCT_FUNCTION (fn);
89   id.decl_map = (struct pointer_map_t *) arg_map;
90
91   id.copy_decl = copy_decl_no_change;
92   id.transform_call_graph_edges = CB_CGE_DUPLICATE;
93   id.transform_new_cfg = true;
94   id.transform_return_to_modify = false;
95   id.transform_lang_insert_block = NULL;
96
97   /* We're not inside any EH region.  */
98   id.eh_lp_nr = 0;
99
100   stmts = DECL_SAVED_TREE (fn);
101   walk_tree (&stmts, copy_tree_body_r, &id, NULL);
102
103   /* Also remap the initializer of any static variables so that they (in
104      particular, any label addresses) correspond to the base variant rather
105      than the abstract one.  */
106   if (DECL_NAME (clone) == base_dtor_identifier
107       || DECL_NAME (clone) == base_ctor_identifier)
108     {
109       unsigned ix;
110       tree decl;
111
112       FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (fn), ix, decl)
113         walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL);
114     }
115
116   append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
117 }
118
119 /* DELETE_DTOR is a delete destructor whose body will be built.
120    COMPLETE_DTOR is the corresponding complete destructor.  */
121
122 static void
123 build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
124 {
125   tree call_dtor, call_delete;
126   tree parm = DECL_ARGUMENTS (delete_dtor);
127   tree virtual_size = cxx_sizeof (current_class_type);
128
129   /* Call the corresponding complete destructor.  */
130   gcc_assert (complete_dtor);
131   call_dtor = build_cxx_call (complete_dtor, 1, &parm,
132                               tf_warning_or_error);
133   add_stmt (call_dtor);
134
135   add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
136
137   /* Call the delete function.  */
138   call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
139                                       virtual_size,
140                                       /*global_p=*/false,
141                                       /*placement=*/NULL_TREE,
142                                       /*alloc_fn=*/NULL_TREE,
143                                       tf_warning_or_error);
144   add_stmt (call_delete);
145
146   /* Return the address of the object.  */
147   if (targetm.cxx.cdtor_returns_this ())
148     {
149       tree val = DECL_ARGUMENTS (delete_dtor);
150       val = build2 (MODIFY_EXPR, TREE_TYPE (val),
151                     DECL_RESULT (delete_dtor), val);
152       add_stmt (build_stmt (0, RETURN_EXPR, val));
153     }
154 }
155
156 /* Return name of comdat group for complete and base ctor (or dtor)
157    that have the same body.  If dtor is virtual, deleting dtor goes
158    into this comdat group as well.  */
159
160 static tree
161 cdtor_comdat_group (tree complete, tree base)
162 {
163   tree complete_name = DECL_COMDAT_GROUP (complete);
164   tree base_name = DECL_COMDAT_GROUP (base);
165   char *grp_name;
166   const char *p, *q;
167   bool diff_seen = false;
168   size_t idx;
169   if (complete_name == NULL)
170     complete_name = cxx_comdat_group (complete);
171   if (base_name == NULL)
172     base_name = cxx_comdat_group (base);
173   gcc_assert (IDENTIFIER_LENGTH (complete_name)
174               == IDENTIFIER_LENGTH (base_name));
175   grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1);
176   p = IDENTIFIER_POINTER (complete_name);
177   q = IDENTIFIER_POINTER (base_name);
178   for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++)
179     if (p[idx] == q[idx])
180       grp_name[idx] = p[idx];
181     else
182       {
183         gcc_assert (!diff_seen
184                     && idx > 0
185                     && (p[idx - 1] == 'C' || p[idx - 1] == 'D')
186                     && p[idx] == '1'
187                     && q[idx] == '2');
188         grp_name[idx] = '5';
189         diff_seen = true;
190       }
191   grp_name[idx] = '\0';
192   gcc_assert (diff_seen);
193   return get_identifier (grp_name);
194 }
195
196 /* Returns true iff we can make the base and complete [cd]tor aliases of
197    the same symbol rather than separate functions.  */
198
199 static bool
200 can_alias_cdtor (tree fn)
201 {
202 #ifndef ASM_OUTPUT_DEF
203   /* If aliases aren't supported by the assembler, fail.  */
204   return false;
205 #endif
206   /* We can't use an alias if there are virtual bases.  */
207   if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)))
208     return false;
209   /* ??? Why not use aliases with -frepo?  */
210   if (flag_use_repository)
211     return false;
212   gcc_assert (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
213               || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn));
214   /* Don't use aliases for weak/linkonce definitions unless we can put both
215      symbols in the same COMDAT group.  */
216   return (DECL_INTERFACE_KNOWN (fn)
217           && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fn))
218           && (!DECL_ONE_ONLY (fn)
219               || (HAVE_COMDAT_GROUP && DECL_WEAK (fn))));
220 }
221
222 /* FN is a [cd]tor, fns is a pointer to an array of length 3.  Fill fns
223    with pointers to the base, complete, and deleting variants.  */
224
225 static void
226 populate_clone_array (tree fn, tree *fns)
227 {
228   tree clone;
229
230   fns[0] = NULL_TREE;
231   fns[1] = NULL_TREE;
232   fns[2] = NULL_TREE;
233
234   /* Look for the complete destructor which may be used to build the
235      delete destructor.  */
236   FOR_EACH_CLONE (clone, fn)
237     if (DECL_NAME (clone) == complete_dtor_identifier
238         || DECL_NAME (clone) == complete_ctor_identifier)
239       fns[1] = clone;
240     else if (DECL_NAME (clone) == base_dtor_identifier
241              || DECL_NAME (clone) == base_ctor_identifier)
242       fns[0] = clone;
243     else if (DECL_NAME (clone) == deleting_dtor_identifier)
244       fns[2] = clone;
245     else
246       gcc_unreachable ();
247 }
248
249 /* FN is a constructor or destructor, and there are FUNCTION_DECLs
250    cloned from it nearby.  Instead of cloning this body, leave it
251    alone and create tiny one-call bodies for the cloned
252    FUNCTION_DECLs.  These clones are sibcall candidates, and their
253    resulting code will be very thunk-esque.  */
254
255 static bool
256 maybe_thunk_body (tree fn, bool force)
257 {
258   tree bind, block, call, clone, clone_result, fn_parm, fn_parm_typelist;
259   tree last_arg, modify, *args;
260   int parmno, vtt_parmno, max_parms;
261   tree fns[3];
262
263   if (!force && !flag_declone_ctor_dtor)
264     return 0;
265
266   /* If function accepts variable arguments, give up.  */
267   last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn)));
268   if (last_arg != void_list_node)
269     return 0;
270
271   /* If we got this far, we've decided to turn the clones into thunks.  */
272
273   /* We're going to generate code for fn, so it is no longer "abstract."
274      Also make the unified ctor/dtor private to either the translation unit
275      (for non-vague linkage ctors) or the COMDAT group (otherwise).  */
276
277   populate_clone_array (fn, fns);
278   DECL_ABSTRACT (fn) = false;
279   if (!DECL_WEAK (fn))
280     {
281       TREE_PUBLIC (fn) = false;
282       DECL_EXTERNAL (fn) = false;
283       DECL_INTERFACE_KNOWN (fn) = true;
284     }
285   else if (HAVE_COMDAT_GROUP)
286     {
287       tree comdat_group = cdtor_comdat_group (fns[1], fns[0]);
288       DECL_COMDAT_GROUP (fns[0]) = comdat_group;
289       symtab_add_to_same_comdat_group (cgraph_get_create_node (fns[1]),
290                                        cgraph_get_create_node (fns[0]));
291       symtab_add_to_same_comdat_group (symtab_get_node (fn),
292                                        symtab_get_node (fns[0]));
293       if (fns[2])
294         /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
295            virtual, it goes into the same comdat group as well.  */
296         symtab_add_to_same_comdat_group (cgraph_get_create_node (fns[2]),
297                                          symtab_get_node (fns[0]));
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;
305     }
306
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))
311     {
312       if (DECL_ARTIFICIAL (fn_parm)
313           && DECL_NAME (fn_parm) == vtt_parm_identifier)
314         {
315           /* Compensate for removed in_charge parameter.  */
316           vtt_parmno = parmno;
317           break;
318         }
319     }
320
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)
325     {
326       int length = list_length (DECL_ARGUMENTS (fn));
327       if (length > max_parms)
328         max_parms = length;
329     }
330   args = (tree *) alloca (max_parms * sizeof (tree));
331
332   /* We know that any clones immediately follow FN in TYPE_METHODS.  */
333   FOR_EACH_CLONE (clone, fn)
334     {
335       tree clone_parm;
336
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;
342
343       /* Start processing the function.  */
344       start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
345
346       if (clone == fns[2])
347         {
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]);
354         }
355       else
356         {
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))
366             {
367               if (parmno == vtt_parmno && ! DECL_HAS_VTT_PARM_P (clone))
368                 {
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);
374                 }
375               else if (parmno == 1 && DECL_HAS_IN_CHARGE_PARM_P (fn))
376                 {
377                   tree in_charge
378                     = copy_node (in_charge_arg_for_name (DECL_NAME (clone)));
379                   args[parmno] = in_charge;
380                 }
381               /* Map other parameters to their equivalents in the cloned
382                  function.  */
383               else
384                 {
385                   gcc_assert (clone_parm);
386                   DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
387                   args[parmno] = clone_parm;
388                   clone_parm = TREE_CHAIN (clone_parm);
389                 }
390               if (fn_parm_typelist)
391                 fn_parm_typelist = TREE_CHAIN (fn_parm_typelist);
392             }
393
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 ())
404             {
405               clone_result = DECL_RESULT (clone);
406               modify = build2 (MODIFY_EXPR, TREE_TYPE (clone_result),
407                                clone_result, call);
408               add_stmt (modify);
409               BLOCK_VARS (block) = clone_result;
410             }
411           else
412             {
413               add_stmt (call);
414             }
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);
419         }
420
421       DECL_ABSTRACT_ORIGIN (clone) = NULL;
422       expand_or_defer_fn (finish_function (0));
423     }
424   return 1;
425 }
426
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.  */
430
431 bool
432 maybe_clone_body (tree fn)
433 {
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;
440
441   /* We only clone constructors and destructors.  */
442   if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
443       && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
444     return 0;
445
446   populate_clone_array (fn, fns);
447
448   /* Remember if we can't have multiple clones for some reason.  We need to
449      check this before we remap local static initializers in clone_body.  */
450   if (!tree_versionable_function_p (fn))
451     need_alias = true;
452
453   /* We know that any clones immediately follow FN in the TYPE_METHODS
454      list.  */
455   push_to_top_level ();
456   for (idx = 0; idx < 3; idx++)
457     {
458       tree parm;
459       tree clone_parm;
460
461       clone = fns[idx];
462       if (!clone)
463         continue;      
464
465       /* Update CLONE's source position information to match FN's.  */
466       DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
467       DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
468       DECL_DECLARED_CONSTEXPR_P (clone) = DECL_DECLARED_CONSTEXPR_P (fn);
469       DECL_COMDAT (clone) = DECL_COMDAT (fn);
470       DECL_WEAK (clone) = DECL_WEAK (fn);
471
472       /* We don't copy the comdat group from fn to clone because the assembler
473          name of fn was corrupted by write_mangled_name by adding *INTERNAL*
474          to it. By doing so, it also corrupted the comdat group. */
475       if (DECL_ONE_ONLY (fn))
476         DECL_COMDAT_GROUP (clone) = cxx_comdat_group (clone);
477       DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
478       DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
479       DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
480       DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
481       DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
482       TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
483       DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
484       DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn);
485       DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn);
486       DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn));
487       DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn);
488
489       /* Adjust the parameter names and locations.  */
490       parm = DECL_ARGUMENTS (fn);
491       clone_parm = DECL_ARGUMENTS (clone);
492       /* Update the `this' parameter, which is always first.  */
493       update_cloned_parm (parm, clone_parm, first);
494       parm = DECL_CHAIN (parm);
495       clone_parm = DECL_CHAIN (clone_parm);
496       if (DECL_HAS_IN_CHARGE_PARM_P (fn))
497         parm = DECL_CHAIN (parm);
498       if (DECL_HAS_VTT_PARM_P (fn))
499         parm = DECL_CHAIN (parm);
500       if (DECL_HAS_VTT_PARM_P (clone))
501         clone_parm = DECL_CHAIN (clone_parm);
502       for (; parm;
503            parm = DECL_CHAIN (parm), clone_parm = DECL_CHAIN (clone_parm))
504         /* Update this parameter.  */
505         update_cloned_parm (parm, clone_parm, first);
506     }
507
508   bool can_alias = can_alias_cdtor (fn);
509
510   /* If we decide to turn clones into thunks, they will branch to fn.
511      Must have original function available to call.  */
512   if (!can_alias && maybe_thunk_body (fn, need_alias))
513     {
514       pop_from_top_level ();
515       /* We still need to emit the original function.  */
516       return 0;
517     }
518
519   /* Emit the DWARF1 abstract instance.  */
520   (*debug_hooks->deferred_inline_function) (fn);
521
522   /* We know that any clones immediately follow FN in the TYPE_METHODS list. */
523   for (idx = 0; idx < 3; idx++)
524     {
525       tree parm;
526       tree clone_parm;
527       int parmno;
528       struct pointer_map_t *decl_map;
529       bool alias = false;
530
531       clone = fns[idx];
532       if (!clone)
533         continue;
534
535       /* Start processing the function.  */
536       start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
537
538       /* Tell cgraph if both ctors or both dtors are known to have
539          the same body.  */
540       if (can_alias
541           && fns[0]
542           && idx == 1
543           && cgraph_same_body_alias (cgraph_get_create_node (fns[0]),
544                                      clone, fns[0]))
545         {
546           alias = true;
547           if (DECL_ONE_ONLY (fns[0]))
548             {
549               /* For comdat base and complete cdtors put them
550                  into the same, *[CD]5* comdat group instead of
551                  *[CD][12]*.  */
552               comdat_group = cdtor_comdat_group (fns[1], fns[0]);
553               DECL_COMDAT_GROUP (fns[0]) = comdat_group;
554               symtab_add_to_same_comdat_group (symtab_get_node (clone),
555                                                symtab_get_node (fns[0]));
556             }
557         }
558
559       /* Build the delete destructor by calling complete destructor
560          and delete function.  */
561       if (idx == 2)
562         {
563           build_delete_destructor_body (clone, fns[1]);
564           /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
565              virtual, it goes into the same comdat group as well.  */
566           if (comdat_group)
567             symtab_add_to_same_comdat_group
568                (cgraph_get_create_node (clone),
569                 symtab_get_node (fns[0]));
570         }
571       else if (alias)
572         /* No need to populate body.  */ ;
573       else
574         {
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)
579             {
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);
584             }
585
586           /* Remap the parameters.  */
587           decl_map = pointer_map_create ();
588           for (parmno = 0,
589                 parm = DECL_ARGUMENTS (fn),
590                 clone_parm = DECL_ARGUMENTS (clone);
591               parm;
592               ++parmno,
593                 parm = DECL_CHAIN (parm))
594             {
595               /* Map the in-charge parameter to an appropriate constant.  */
596               if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
597                 {
598                   tree in_charge;
599                   in_charge = in_charge_arg_for_name (DECL_NAME (clone));
600                   *pointer_map_insert (decl_map, parm) = in_charge;
601                 }
602               else if (DECL_ARTIFICIAL (parm)
603                        && DECL_NAME (parm) == vtt_parm_identifier)
604                 {
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))
609                     {
610                       DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
611                       *pointer_map_insert (decl_map, parm) = clone_parm;
612                       clone_parm = DECL_CHAIN (clone_parm);
613                     }
614                   /* Otherwise, map the VTT parameter to `NULL'.  */
615                   else
616                     *pointer_map_insert (decl_map, parm)
617                        = fold_convert (TREE_TYPE (parm), null_pointer_node);
618                 }
619               /* Map other parameters to their equivalents in the cloned
620                  function.  */
621               else
622                 {
623                   *pointer_map_insert (decl_map, parm) = clone_parm;
624                   clone_parm = DECL_CHAIN (clone_parm);
625                 }
626             }
627
628           if (targetm.cxx.cdtor_returns_this ())
629             {
630               parm = DECL_RESULT (fn);
631               clone_parm = DECL_RESULT (clone);
632               *pointer_map_insert (decl_map, parm) = clone_parm;
633             }
634
635           /* Clone the body.  */
636           clone_body (clone, fn, decl_map);
637
638           /* Clean up.  */
639           pointer_map_destroy (decl_map);
640         }
641
642       /* The clone can throw iff the original function can throw.  */
643       cp_function_chain->can_throw = !TREE_NOTHROW (fn);
644
645       /* Now, expand this function into RTL, if appropriate.  */
646       finish_function (0);
647       BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
648       if (alias)
649         {
650           if (expand_or_defer_fn_1 (clone))
651             emit_associated_thunks (clone);
652         }
653       else
654         expand_or_defer_fn (clone);
655       first = false;
656     }
657   pop_from_top_level ();
658
659   /* We don't need to process the original function any further.  */
660   return 1;
661 }