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