1/* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c. 2 3 Copyright (C) 2002-2015 Free Software Foundation, Inc. 4 Contributed by Jason Merrill <jason@redhat.com> 5 6This file is part of GCC. 7 8GCC is free software; you can redistribute it and/or modify it under 9the terms of the GNU General Public License as published by the Free 10Software Foundation; either version 3, or (at your option) any later 11version. 12 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14WARRANTY; without even the implied warranty of MERCHANTABILITY or 15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16for more details. 17 18You should have received a copy of the GNU General Public License 19along with GCC; see the file COPYING3. If not see 20<http://www.gnu.org/licenses/>. */ 21 22#include "config.h" 23#include "system.h" 24#include "coretypes.h" 25#include "tm.h" 26#include "hash-set.h" 27#include "machmode.h" 28#include "vec.h" 29#include "double-int.h" 30#include "input.h" 31#include "alias.h" 32#include "symtab.h" 33#include "wide-int.h" 34#include "inchash.h" 35#include "tree.h" 36#include "stor-layout.h" 37#include "cp-tree.h" 38#include "c-family/c-common.h" 39#include "tree-iterator.h" 40#include "predict.h" 41#include "hard-reg-set.h" 42#include "input.h" 43#include "function.h" 44#include "basic-block.h" 45#include "tree-ssa-alias.h" 46#include "internal-fn.h" 47#include "gimple-expr.h" 48#include "is-a.h" 49#include "gimple.h" 50#include "gimplify.h" 51#include "flags.h" 52#include "splay-tree.h" 53#include "target.h" 54#include "c-family/c-ubsan.h" 55#include "cilk.h" 56#include "gimplify.h" 57#include "gimple-expr.h" 58 59/* Forward declarations. */ 60 61static tree cp_genericize_r (tree *, int *, void *); 62static void cp_genericize_tree (tree*); 63 64/* Local declarations. */ 65 66enum bc_t { bc_break = 0, bc_continue = 1 }; 67 68/* Stack of labels which are targets for "break" or "continue", 69 linked through TREE_CHAIN. */ 70static tree bc_label[2]; 71 72/* Begin a scope which can be exited by a break or continue statement. BC 73 indicates which. 74 75 Just creates a label with location LOCATION and pushes it into the current 76 context. */ 77 78static tree 79begin_bc_block (enum bc_t bc, location_t location) 80{ 81 tree label = create_artificial_label (location); 82 DECL_CHAIN (label) = bc_label[bc]; 83 bc_label[bc] = label; 84 if (bc == bc_break) 85 LABEL_DECL_BREAK (label) = true; 86 else 87 LABEL_DECL_CONTINUE (label) = true; 88 return label; 89} 90 91/* Finish a scope which can be exited by a break or continue statement. 92 LABEL was returned from the most recent call to begin_bc_block. BLOCK is 93 an expression for the contents of the scope. 94 95 If we saw a break (or continue) in the scope, append a LABEL_EXPR to 96 BLOCK. Otherwise, just forget the label. */ 97 98static void 99finish_bc_block (tree *block, enum bc_t bc, tree label) 100{ 101 gcc_assert (label == bc_label[bc]); 102 103 if (TREE_USED (label)) 104 append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label), 105 block); 106 107 bc_label[bc] = DECL_CHAIN (label); 108 DECL_CHAIN (label) = NULL_TREE; 109} 110 111/* Get the LABEL_EXPR to represent a break or continue statement 112 in the current block scope. BC indicates which. */ 113 114static tree 115get_bc_label (enum bc_t bc) 116{ 117 tree label = bc_label[bc]; 118 119 /* Mark the label used for finish_bc_block. */ 120 TREE_USED (label) = 1; 121 return label; 122} 123 124/* Genericize a TRY_BLOCK. */ 125 126static void 127genericize_try_block (tree *stmt_p) 128{ 129 tree body = TRY_STMTS (*stmt_p); 130 tree cleanup = TRY_HANDLERS (*stmt_p); 131 132 *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup); 133} 134 135/* Genericize a HANDLER by converting to a CATCH_EXPR. */ 136 137static void 138genericize_catch_block (tree *stmt_p) 139{ 140 tree type = HANDLER_TYPE (*stmt_p); 141 tree body = HANDLER_BODY (*stmt_p); 142 143 /* FIXME should the caught type go in TREE_TYPE? */ 144 *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body); 145} 146 147/* A terser interface for building a representation of an exception 148 specification. */ 149 150static tree 151build_gimple_eh_filter_tree (tree body, tree allowed, tree failure) 152{ 153 tree t; 154 155 /* FIXME should the allowed types go in TREE_TYPE? */ 156 t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE); 157 append_to_statement_list (failure, &EH_FILTER_FAILURE (t)); 158 159 t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t); 160 append_to_statement_list (body, &TREE_OPERAND (t, 0)); 161 162 return t; 163} 164 165/* Genericize an EH_SPEC_BLOCK by converting it to a 166 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */ 167 168static void 169genericize_eh_spec_block (tree *stmt_p) 170{ 171 tree body = EH_SPEC_STMTS (*stmt_p); 172 tree allowed = EH_SPEC_RAISES (*stmt_p); 173 tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ()); 174 175 *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure); 176 TREE_NO_WARNING (*stmt_p) = true; 177 TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true; 178} 179 180/* Genericize an IF_STMT by turning it into a COND_EXPR. */ 181 182static void 183genericize_if_stmt (tree *stmt_p) 184{ 185 tree stmt, cond, then_, else_; 186 location_t locus = EXPR_LOCATION (*stmt_p); 187 188 stmt = *stmt_p; 189 cond = IF_COND (stmt); 190 then_ = THEN_CLAUSE (stmt); 191 else_ = ELSE_CLAUSE (stmt); 192 193 if (!then_) 194 then_ = build_empty_stmt (locus); 195 if (!else_) 196 else_ = build_empty_stmt (locus); 197 198 if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_)) 199 stmt = then_; 200 else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_)) 201 stmt = else_; 202 else 203 stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_); 204 if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt)) 205 SET_EXPR_LOCATION (stmt, locus); 206 *stmt_p = stmt; 207} 208 209/* Build a generic representation of one of the C loop forms. COND is the 210 loop condition or NULL_TREE. BODY is the (possibly compound) statement 211 controlled by the loop. INCR is the increment expression of a for-loop, 212 or NULL_TREE. COND_IS_FIRST indicates whether the condition is 213 evaluated before the loop body as in while and for loops, or after the 214 loop body as in do-while loops. */ 215 216static void 217genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body, 218 tree incr, bool cond_is_first, int *walk_subtrees, 219 void *data) 220{ 221 tree blab, clab; 222 tree exit = NULL; 223 tree stmt_list = NULL; 224 225 blab = begin_bc_block (bc_break, start_locus); 226 clab = begin_bc_block (bc_continue, start_locus); 227 228 if (incr && EXPR_P (incr)) 229 SET_EXPR_LOCATION (incr, start_locus); 230 231 cp_walk_tree (&cond, cp_genericize_r, data, NULL); 232 cp_walk_tree (&body, cp_genericize_r, data, NULL); 233 cp_walk_tree (&incr, cp_genericize_r, data, NULL); 234 *walk_subtrees = 0; 235 236 if (cond && TREE_CODE (cond) != INTEGER_CST) 237 { 238 /* If COND is constant, don't bother building an exit. If it's false, 239 we won't build a loop. If it's true, any exits are in the body. */ 240 location_t cloc = EXPR_LOC_OR_LOC (cond, start_locus); 241 exit = build1_loc (cloc, GOTO_EXPR, void_type_node, 242 get_bc_label (bc_break)); 243 exit = fold_build3_loc (cloc, COND_EXPR, void_type_node, cond, 244 build_empty_stmt (cloc), exit); 245 } 246 247 if (exit && cond_is_first) 248 append_to_statement_list (exit, &stmt_list); 249 append_to_statement_list (body, &stmt_list); 250 finish_bc_block (&stmt_list, bc_continue, clab); 251 append_to_statement_list (incr, &stmt_list); 252 if (exit && !cond_is_first) 253 append_to_statement_list (exit, &stmt_list); 254 255 if (!stmt_list) 256 stmt_list = build_empty_stmt (start_locus); 257 258 tree loop; 259 if (cond && integer_zerop (cond)) 260 { 261 if (cond_is_first) 262 loop = fold_build3_loc (start_locus, COND_EXPR, 263 void_type_node, cond, stmt_list, 264 build_empty_stmt (start_locus)); 265 else 266 loop = stmt_list; 267 } 268 else 269 loop = build1_loc (start_locus, LOOP_EXPR, void_type_node, stmt_list); 270 271 stmt_list = NULL; 272 append_to_statement_list (loop, &stmt_list); 273 finish_bc_block (&stmt_list, bc_break, blab); 274 if (!stmt_list) 275 stmt_list = build_empty_stmt (start_locus); 276 277 *stmt_p = stmt_list; 278} 279 280/* Genericize a FOR_STMT node *STMT_P. */ 281 282static void 283genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data) 284{ 285 tree stmt = *stmt_p; 286 tree expr = NULL; 287 tree loop; 288 tree init = FOR_INIT_STMT (stmt); 289 290 if (init) 291 { 292 cp_walk_tree (&init, cp_genericize_r, data, NULL); 293 append_to_statement_list (init, &expr); 294 } 295 296 genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt), 297 FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data); 298 append_to_statement_list (loop, &expr); 299 if (expr == NULL_TREE) 300 expr = loop; 301 *stmt_p = expr; 302} 303 304/* Genericize a WHILE_STMT node *STMT_P. */ 305 306static void 307genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data) 308{ 309 tree stmt = *stmt_p; 310 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt), 311 WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees, data); 312} 313 314/* Genericize a DO_STMT node *STMT_P. */ 315 316static void 317genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data) 318{ 319 tree stmt = *stmt_p; 320 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt), 321 DO_BODY (stmt), NULL_TREE, 0, walk_subtrees, data); 322} 323 324/* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR. */ 325 326static void 327genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data) 328{ 329 tree stmt = *stmt_p; 330 tree break_block, body, cond, type; 331 location_t stmt_locus = EXPR_LOCATION (stmt); 332 333 break_block = begin_bc_block (bc_break, stmt_locus); 334 335 body = SWITCH_STMT_BODY (stmt); 336 if (!body) 337 body = build_empty_stmt (stmt_locus); 338 cond = SWITCH_STMT_COND (stmt); 339 type = SWITCH_STMT_TYPE (stmt); 340 341 cp_walk_tree (&body, cp_genericize_r, data, NULL); 342 cp_walk_tree (&cond, cp_genericize_r, data, NULL); 343 cp_walk_tree (&type, cp_genericize_r, data, NULL); 344 *walk_subtrees = 0; 345 346 *stmt_p = build3_loc (stmt_locus, SWITCH_EXPR, type, cond, body, NULL_TREE); 347 finish_bc_block (stmt_p, bc_break, break_block); 348} 349 350/* Genericize a CONTINUE_STMT node *STMT_P. */ 351 352static void 353genericize_continue_stmt (tree *stmt_p) 354{ 355 tree stmt_list = NULL; 356 tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN); 357 tree label = get_bc_label (bc_continue); 358 location_t location = EXPR_LOCATION (*stmt_p); 359 tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label); 360 append_to_statement_list (pred, &stmt_list); 361 append_to_statement_list (jump, &stmt_list); 362 *stmt_p = stmt_list; 363} 364 365/* Genericize a BREAK_STMT node *STMT_P. */ 366 367static void 368genericize_break_stmt (tree *stmt_p) 369{ 370 tree label = get_bc_label (bc_break); 371 location_t location = EXPR_LOCATION (*stmt_p); 372 *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label); 373} 374 375/* Genericize a OMP_FOR node *STMT_P. */ 376 377static void 378genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data) 379{ 380 tree stmt = *stmt_p; 381 location_t locus = EXPR_LOCATION (stmt); 382 tree clab = begin_bc_block (bc_continue, locus); 383 384 cp_walk_tree (&OMP_FOR_BODY (stmt), cp_genericize_r, data, NULL); 385 cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_genericize_r, data, NULL); 386 cp_walk_tree (&OMP_FOR_INIT (stmt), cp_genericize_r, data, NULL); 387 cp_walk_tree (&OMP_FOR_COND (stmt), cp_genericize_r, data, NULL); 388 cp_walk_tree (&OMP_FOR_INCR (stmt), cp_genericize_r, data, NULL); 389 cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_genericize_r, data, NULL); 390 *walk_subtrees = 0; 391 392 finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab); 393} 394 395/* Hook into the middle of gimplifying an OMP_FOR node. */ 396 397static enum gimplify_status 398cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) 399{ 400 tree for_stmt = *expr_p; 401 gimple_seq seq = NULL; 402 403 /* Protect ourselves from recursion. */ 404 if (OMP_FOR_GIMPLIFYING_P (for_stmt)) 405 return GS_UNHANDLED; 406 OMP_FOR_GIMPLIFYING_P (for_stmt) = 1; 407 408 gimplify_and_add (for_stmt, &seq); 409 gimple_seq_add_seq (pre_p, seq); 410 411 OMP_FOR_GIMPLIFYING_P (for_stmt) = 0; 412 413 return GS_ALL_DONE; 414} 415 416/* Gimplify an EXPR_STMT node. */ 417 418static void 419gimplify_expr_stmt (tree *stmt_p) 420{ 421 tree stmt = EXPR_STMT_EXPR (*stmt_p); 422 423 if (stmt == error_mark_node) 424 stmt = NULL; 425 426 /* Gimplification of a statement expression will nullify the 427 statement if all its side effects are moved to *PRE_P and *POST_P. 428 429 In this case we will not want to emit the gimplified statement. 430 However, we may still want to emit a warning, so we do that before 431 gimplification. */ 432 if (stmt && warn_unused_value) 433 { 434 if (!TREE_SIDE_EFFECTS (stmt)) 435 { 436 if (!IS_EMPTY_STMT (stmt) 437 && !VOID_TYPE_P (TREE_TYPE (stmt)) 438 && !TREE_NO_WARNING (stmt)) 439 warning (OPT_Wunused_value, "statement with no effect"); 440 } 441 else 442 warn_if_unused_value (stmt, input_location); 443 } 444 445 if (stmt == NULL_TREE) 446 stmt = alloc_stmt_list (); 447 448 *stmt_p = stmt; 449} 450 451/* Gimplify initialization from an AGGR_INIT_EXPR. */ 452 453static void 454cp_gimplify_init_expr (tree *expr_p) 455{ 456 tree from = TREE_OPERAND (*expr_p, 1); 457 tree to = TREE_OPERAND (*expr_p, 0); 458 tree t; 459 460 /* What about code that pulls out the temp and uses it elsewhere? I 461 think that such code never uses the TARGET_EXPR as an initializer. If 462 I'm wrong, we'll abort because the temp won't have any RTL. In that 463 case, I guess we'll need to replace references somehow. */ 464 if (TREE_CODE (from) == TARGET_EXPR) 465 from = TARGET_EXPR_INITIAL (from); 466 467 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them 468 inside the TARGET_EXPR. */ 469 for (t = from; t; ) 470 { 471 tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t; 472 473 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and 474 replace the slot operand with our target. 475 476 Should we add a target parm to gimplify_expr instead? No, as in this 477 case we want to replace the INIT_EXPR. */ 478 if (TREE_CODE (sub) == AGGR_INIT_EXPR 479 || TREE_CODE (sub) == VEC_INIT_EXPR) 480 { 481 if (TREE_CODE (sub) == AGGR_INIT_EXPR) 482 AGGR_INIT_EXPR_SLOT (sub) = to; 483 else 484 VEC_INIT_EXPR_SLOT (sub) = to; 485 *expr_p = from; 486 487 /* The initialization is now a side-effect, so the container can 488 become void. */ 489 if (from != sub) 490 TREE_TYPE (from) = void_type_node; 491 } 492 493 if (cxx_dialect >= cxx14 && TREE_CODE (sub) == CONSTRUCTOR) 494 /* Handle aggregate NSDMI. */ 495 replace_placeholders (sub, to); 496 497 if (t == sub) 498 break; 499 else 500 t = TREE_OPERAND (t, 1); 501 } 502 503} 504 505/* Gimplify a MUST_NOT_THROW_EXPR. */ 506 507static enum gimplify_status 508gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p) 509{ 510 tree stmt = *expr_p; 511 tree temp = voidify_wrapper_expr (stmt, NULL); 512 tree body = TREE_OPERAND (stmt, 0); 513 gimple_seq try_ = NULL; 514 gimple_seq catch_ = NULL; 515 gimple mnt; 516 517 gimplify_and_add (body, &try_); 518 mnt = gimple_build_eh_must_not_throw (terminate_node); 519 gimple_seq_add_stmt_without_update (&catch_, mnt); 520 mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH); 521 522 gimple_seq_add_stmt_without_update (pre_p, mnt); 523 if (temp) 524 { 525 *expr_p = temp; 526 return GS_OK; 527 } 528 529 *expr_p = NULL; 530 return GS_ALL_DONE; 531} 532 533/* Return TRUE if an operand (OP) of a given TYPE being copied is 534 really just an empty class copy. 535 536 Check that the operand has a simple form so that TARGET_EXPRs and 537 non-empty CONSTRUCTORs get reduced properly, and we leave the 538 return slot optimization alone because it isn't a copy. */ 539 540static bool 541simple_empty_class_p (tree type, tree op) 542{ 543 return 544 ((TREE_CODE (op) == COMPOUND_EXPR 545 && simple_empty_class_p (type, TREE_OPERAND (op, 1))) 546 || is_gimple_lvalue (op) 547 || INDIRECT_REF_P (op) 548 || (TREE_CODE (op) == CONSTRUCTOR 549 && CONSTRUCTOR_NELTS (op) == 0 550 && !TREE_CLOBBER_P (op)) 551 || (TREE_CODE (op) == CALL_EXPR 552 && !CALL_EXPR_RETURN_SLOT_OPT (op))) 553 && is_really_empty_class (type); 554} 555 556/* Do C++-specific gimplification. Args are as for gimplify_expr. */ 557 558int 559cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 560{ 561 int saved_stmts_are_full_exprs_p = 0; 562 enum tree_code code = TREE_CODE (*expr_p); 563 enum gimplify_status ret; 564 565 if (STATEMENT_CODE_P (code)) 566 { 567 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); 568 current_stmt_tree ()->stmts_are_full_exprs_p 569 = STMT_IS_FULL_EXPR_P (*expr_p); 570 } 571 572 switch (code) 573 { 574 case PTRMEM_CST: 575 *expr_p = cplus_expand_constant (*expr_p); 576 ret = GS_OK; 577 break; 578 579 case AGGR_INIT_EXPR: 580 simplify_aggr_init_expr (expr_p); 581 ret = GS_OK; 582 break; 583 584 case VEC_INIT_EXPR: 585 { 586 location_t loc = input_location; 587 tree init = VEC_INIT_EXPR_INIT (*expr_p); 588 int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE); 589 gcc_assert (EXPR_HAS_LOCATION (*expr_p)); 590 input_location = EXPR_LOCATION (*expr_p); 591 *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE, 592 init, VEC_INIT_EXPR_VALUE_INIT (*expr_p), 593 from_array, 594 tf_warning_or_error); 595 cp_genericize_tree (expr_p); 596 ret = GS_OK; 597 input_location = loc; 598 } 599 break; 600 601 case THROW_EXPR: 602 /* FIXME communicate throw type to back end, probably by moving 603 THROW_EXPR into ../tree.def. */ 604 *expr_p = TREE_OPERAND (*expr_p, 0); 605 ret = GS_OK; 606 break; 607 608 case MUST_NOT_THROW_EXPR: 609 ret = gimplify_must_not_throw_expr (expr_p, pre_p); 610 break; 611 612 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the 613 LHS of an assignment might also be involved in the RHS, as in bug 614 25979. */ 615 case INIT_EXPR: 616 if (fn_contains_cilk_spawn_p (cfun) 617 && cilk_detect_spawn_and_unwrap (expr_p) 618 && !seen_error ()) 619 return (enum gimplify_status) gimplify_cilk_spawn (expr_p); 620 cp_gimplify_init_expr (expr_p); 621 if (TREE_CODE (*expr_p) != INIT_EXPR) 622 return GS_OK; 623 /* Otherwise fall through. */ 624 case MODIFY_EXPR: 625 modify_expr_case: 626 { 627 if (fn_contains_cilk_spawn_p (cfun) 628 && cilk_detect_spawn_and_unwrap (expr_p) 629 && !seen_error ()) 630 return (enum gimplify_status) gimplify_cilk_spawn (expr_p); 631 632 /* If the back end isn't clever enough to know that the lhs and rhs 633 types are the same, add an explicit conversion. */ 634 tree op0 = TREE_OPERAND (*expr_p, 0); 635 tree op1 = TREE_OPERAND (*expr_p, 1); 636 637 if (!error_operand_p (op0) 638 && !error_operand_p (op1) 639 && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0)) 640 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1))) 641 && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0))) 642 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR, 643 TREE_TYPE (op0), op1); 644 645 else if (simple_empty_class_p (TREE_TYPE (op0), op1)) 646 { 647 /* Remove any copies of empty classes. Also drop volatile 648 variables on the RHS to avoid infinite recursion from 649 gimplify_expr trying to load the value. */ 650 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 651 is_gimple_lvalue, fb_lvalue); 652 if (TREE_SIDE_EFFECTS (op1)) 653 { 654 if (TREE_THIS_VOLATILE (op1) 655 && (REFERENCE_CLASS_P (op1) || DECL_P (op1))) 656 op1 = build_fold_addr_expr (op1); 657 658 gimplify_and_add (op1, pre_p); 659 } 660 *expr_p = TREE_OPERAND (*expr_p, 0); 661 } 662 } 663 ret = GS_OK; 664 break; 665 666 case EMPTY_CLASS_EXPR: 667 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */ 668 *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL); 669 ret = GS_OK; 670 break; 671 672 case BASELINK: 673 *expr_p = BASELINK_FUNCTIONS (*expr_p); 674 ret = GS_OK; 675 break; 676 677 case TRY_BLOCK: 678 genericize_try_block (expr_p); 679 ret = GS_OK; 680 break; 681 682 case HANDLER: 683 genericize_catch_block (expr_p); 684 ret = GS_OK; 685 break; 686 687 case EH_SPEC_BLOCK: 688 genericize_eh_spec_block (expr_p); 689 ret = GS_OK; 690 break; 691 692 case USING_STMT: 693 gcc_unreachable (); 694 695 case FOR_STMT: 696 case WHILE_STMT: 697 case DO_STMT: 698 case SWITCH_STMT: 699 case CONTINUE_STMT: 700 case BREAK_STMT: 701 gcc_unreachable (); 702 703 case OMP_FOR: 704 case OMP_SIMD: 705 case OMP_DISTRIBUTE: 706 ret = cp_gimplify_omp_for (expr_p, pre_p); 707 break; 708 709 case EXPR_STMT: 710 gimplify_expr_stmt (expr_p); 711 ret = GS_OK; 712 break; 713 714 case UNARY_PLUS_EXPR: 715 { 716 tree arg = TREE_OPERAND (*expr_p, 0); 717 tree type = TREE_TYPE (*expr_p); 718 *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg) 719 : arg; 720 ret = GS_OK; 721 } 722 break; 723 724 case CILK_SPAWN_STMT: 725 gcc_assert 726 (fn_contains_cilk_spawn_p (cfun) 727 && cilk_detect_spawn_and_unwrap (expr_p)); 728 729 /* If errors are seen, then just process it as a CALL_EXPR. */ 730 if (!seen_error ()) 731 return (enum gimplify_status) gimplify_cilk_spawn (expr_p); 732 733 case CALL_EXPR: 734 if (fn_contains_cilk_spawn_p (cfun) 735 && cilk_detect_spawn_and_unwrap (expr_p) 736 && !seen_error ()) 737 return (enum gimplify_status) gimplify_cilk_spawn (expr_p); 738 739 /* DR 1030 says that we need to evaluate the elements of an 740 initializer-list in forward order even when it's used as arguments to 741 a constructor. So if the target wants to evaluate them in reverse 742 order and there's more than one argument other than 'this', gimplify 743 them in order. */ 744 ret = GS_OK; 745 if (PUSH_ARGS_REVERSED && CALL_EXPR_LIST_INIT_P (*expr_p) 746 && call_expr_nargs (*expr_p) > 2) 747 { 748 int nargs = call_expr_nargs (*expr_p); 749 location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location); 750 for (int i = 1; i < nargs; ++i) 751 { 752 enum gimplify_status t 753 = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc); 754 if (t == GS_ERROR) 755 ret = GS_ERROR; 756 } 757 } 758 break; 759 760 case RETURN_EXPR: 761 if (TREE_OPERAND (*expr_p, 0) 762 && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR 763 || TREE_CODE (TREE_OPERAND (*expr_p, 0)) == MODIFY_EXPR)) 764 { 765 expr_p = &TREE_OPERAND (*expr_p, 0); 766 code = TREE_CODE (*expr_p); 767 /* Avoid going through the INIT_EXPR case, which can 768 degrade INIT_EXPRs into AGGR_INIT_EXPRs. */ 769 goto modify_expr_case; 770 } 771 /* Fall through. */ 772 773 default: 774 ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p); 775 break; 776 } 777 778 /* Restore saved state. */ 779 if (STATEMENT_CODE_P (code)) 780 current_stmt_tree ()->stmts_are_full_exprs_p 781 = saved_stmts_are_full_exprs_p; 782 783 return ret; 784} 785 786static inline bool 787is_invisiref_parm (const_tree t) 788{ 789 return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL) 790 && DECL_BY_REFERENCE (t)); 791} 792 793/* Return true if the uid in both int tree maps are equal. */ 794 795bool 796cxx_int_tree_map_hasher::equal (cxx_int_tree_map *a, cxx_int_tree_map *b) 797{ 798 return (a->uid == b->uid); 799} 800 801/* Hash a UID in a cxx_int_tree_map. */ 802 803unsigned int 804cxx_int_tree_map_hasher::hash (cxx_int_tree_map *item) 805{ 806 return item->uid; 807} 808 809/* A stable comparison routine for use with splay trees and DECLs. */ 810 811static int 812splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb) 813{ 814 tree a = (tree) xa; 815 tree b = (tree) xb; 816 817 return DECL_UID (a) - DECL_UID (b); 818} 819 820/* OpenMP context during genericization. */ 821 822struct cp_genericize_omp_taskreg 823{ 824 bool is_parallel; 825 bool default_shared; 826 struct cp_genericize_omp_taskreg *outer; 827 splay_tree variables; 828}; 829 830/* Return true if genericization should try to determine if 831 DECL is firstprivate or shared within task regions. */ 832 833static bool 834omp_var_to_track (tree decl) 835{ 836 tree type = TREE_TYPE (decl); 837 if (is_invisiref_parm (decl)) 838 type = TREE_TYPE (type); 839 while (TREE_CODE (type) == ARRAY_TYPE) 840 type = TREE_TYPE (type); 841 if (type == error_mark_node || !CLASS_TYPE_P (type)) 842 return false; 843 if (VAR_P (decl) && DECL_THREAD_LOCAL_P (decl)) 844 return false; 845 if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED) 846 return false; 847 return true; 848} 849 850/* Note DECL use in OpenMP region OMP_CTX during genericization. */ 851 852static void 853omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl) 854{ 855 splay_tree_node n = splay_tree_lookup (omp_ctx->variables, 856 (splay_tree_key) decl); 857 if (n == NULL) 858 { 859 int flags = OMP_CLAUSE_DEFAULT_SHARED; 860 if (omp_ctx->outer) 861 omp_cxx_notice_variable (omp_ctx->outer, decl); 862 if (!omp_ctx->default_shared) 863 { 864 struct cp_genericize_omp_taskreg *octx; 865 866 for (octx = omp_ctx->outer; octx; octx = octx->outer) 867 { 868 n = splay_tree_lookup (octx->variables, (splay_tree_key) decl); 869 if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED) 870 { 871 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE; 872 break; 873 } 874 if (octx->is_parallel) 875 break; 876 } 877 if (octx == NULL 878 && (TREE_CODE (decl) == PARM_DECL 879 || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl)) 880 && DECL_CONTEXT (decl) == current_function_decl))) 881 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE; 882 if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE) 883 { 884 /* DECL is implicitly determined firstprivate in 885 the current task construct. Ensure copy ctor and 886 dtor are instantiated, because during gimplification 887 it will be already too late. */ 888 tree type = TREE_TYPE (decl); 889 if (is_invisiref_parm (decl)) 890 type = TREE_TYPE (type); 891 while (TREE_CODE (type) == ARRAY_TYPE) 892 type = TREE_TYPE (type); 893 get_copy_ctor (type, tf_none); 894 get_dtor (type, tf_none); 895 } 896 } 897 splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags); 898 } 899} 900 901/* Genericization context. */ 902 903struct cp_genericize_data 904{ 905 hash_set<tree> *p_set; 906 vec<tree> bind_expr_stack; 907 struct cp_genericize_omp_taskreg *omp_ctx; 908 bool no_sanitize_p; 909}; 910 911/* Perform any pre-gimplification lowering of C++ front end trees to 912 GENERIC. */ 913 914static tree 915cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) 916{ 917 tree stmt = *stmt_p; 918 struct cp_genericize_data *wtd = (struct cp_genericize_data *) data; 919 hash_set<tree> *p_set = wtd->p_set; 920 921 /* If in an OpenMP context, note var uses. */ 922 if (__builtin_expect (wtd->omp_ctx != NULL, 0) 923 && (VAR_P (stmt) 924 || TREE_CODE (stmt) == PARM_DECL 925 || TREE_CODE (stmt) == RESULT_DECL) 926 && omp_var_to_track (stmt)) 927 omp_cxx_notice_variable (wtd->omp_ctx, stmt); 928 929 if (is_invisiref_parm (stmt) 930 /* Don't dereference parms in a thunk, pass the references through. */ 931 && !(DECL_THUNK_P (current_function_decl) 932 && TREE_CODE (stmt) == PARM_DECL)) 933 { 934 *stmt_p = convert_from_reference (stmt); 935 *walk_subtrees = 0; 936 return NULL; 937 } 938 939 /* Map block scope extern declarations to visible declarations with the 940 same name and type in outer scopes if any. */ 941 if (cp_function_chain->extern_decl_map 942 && VAR_OR_FUNCTION_DECL_P (stmt) 943 && DECL_EXTERNAL (stmt)) 944 { 945 struct cxx_int_tree_map *h, in; 946 in.uid = DECL_UID (stmt); 947 h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid); 948 if (h) 949 { 950 *stmt_p = h->to; 951 *walk_subtrees = 0; 952 return NULL; 953 } 954 } 955 956 /* Other than invisiref parms, don't walk the same tree twice. */ 957 if (p_set->contains (stmt)) 958 { 959 *walk_subtrees = 0; 960 return NULL_TREE; 961 } 962 963 if (TREE_CODE (stmt) == ADDR_EXPR 964 && is_invisiref_parm (TREE_OPERAND (stmt, 0))) 965 { 966 /* If in an OpenMP context, note var uses. */ 967 if (__builtin_expect (wtd->omp_ctx != NULL, 0) 968 && omp_var_to_track (TREE_OPERAND (stmt, 0))) 969 omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0)); 970 *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0)); 971 *walk_subtrees = 0; 972 } 973 else if (TREE_CODE (stmt) == RETURN_EXPR 974 && TREE_OPERAND (stmt, 0) 975 && is_invisiref_parm (TREE_OPERAND (stmt, 0))) 976 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */ 977 *walk_subtrees = 0; 978 else if (TREE_CODE (stmt) == OMP_CLAUSE) 979 switch (OMP_CLAUSE_CODE (stmt)) 980 { 981 case OMP_CLAUSE_LASTPRIVATE: 982 /* Don't dereference an invisiref in OpenMP clauses. */ 983 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 984 { 985 *walk_subtrees = 0; 986 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt)) 987 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt), 988 cp_genericize_r, data, NULL); 989 } 990 break; 991 case OMP_CLAUSE_PRIVATE: 992 /* Don't dereference an invisiref in OpenMP clauses. */ 993 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 994 *walk_subtrees = 0; 995 else if (wtd->omp_ctx != NULL) 996 { 997 /* Private clause doesn't cause any references to the 998 var in outer contexts, avoid calling 999 omp_cxx_notice_variable for it. */ 1000 struct cp_genericize_omp_taskreg *old = wtd->omp_ctx; 1001 wtd->omp_ctx = NULL; 1002 cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r, 1003 data, NULL); 1004 wtd->omp_ctx = old; 1005 *walk_subtrees = 0; 1006 } 1007 break; 1008 case OMP_CLAUSE_SHARED: 1009 case OMP_CLAUSE_FIRSTPRIVATE: 1010 case OMP_CLAUSE_COPYIN: 1011 case OMP_CLAUSE_COPYPRIVATE: 1012 /* Don't dereference an invisiref in OpenMP clauses. */ 1013 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 1014 *walk_subtrees = 0; 1015 break; 1016 case OMP_CLAUSE_REDUCTION: 1017 /* Don't dereference an invisiref in reduction clause's 1018 OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE} 1019 still needs to be genericized. */ 1020 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 1021 { 1022 *walk_subtrees = 0; 1023 if (OMP_CLAUSE_REDUCTION_INIT (stmt)) 1024 cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt), 1025 cp_genericize_r, data, NULL); 1026 if (OMP_CLAUSE_REDUCTION_MERGE (stmt)) 1027 cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt), 1028 cp_genericize_r, data, NULL); 1029 } 1030 break; 1031 default: 1032 break; 1033 } 1034 else if (IS_TYPE_OR_DECL_P (stmt)) 1035 *walk_subtrees = 0; 1036 1037 /* Due to the way voidify_wrapper_expr is written, we don't get a chance 1038 to lower this construct before scanning it, so we need to lower these 1039 before doing anything else. */ 1040 else if (TREE_CODE (stmt) == CLEANUP_STMT) 1041 *stmt_p = build2_loc (EXPR_LOCATION (stmt), 1042 CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR 1043 : TRY_FINALLY_EXPR, 1044 void_type_node, 1045 CLEANUP_BODY (stmt), 1046 CLEANUP_EXPR (stmt)); 1047 1048 else if (TREE_CODE (stmt) == IF_STMT) 1049 { 1050 genericize_if_stmt (stmt_p); 1051 /* *stmt_p has changed, tail recurse to handle it again. */ 1052 return cp_genericize_r (stmt_p, walk_subtrees, data); 1053 } 1054 1055 /* COND_EXPR might have incompatible types in branches if one or both 1056 arms are bitfields. Fix it up now. */ 1057 else if (TREE_CODE (stmt) == COND_EXPR) 1058 { 1059 tree type_left 1060 = (TREE_OPERAND (stmt, 1) 1061 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1)) 1062 : NULL_TREE); 1063 tree type_right 1064 = (TREE_OPERAND (stmt, 2) 1065 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2)) 1066 : NULL_TREE); 1067 if (type_left 1068 && !useless_type_conversion_p (TREE_TYPE (stmt), 1069 TREE_TYPE (TREE_OPERAND (stmt, 1)))) 1070 { 1071 TREE_OPERAND (stmt, 1) 1072 = fold_convert (type_left, TREE_OPERAND (stmt, 1)); 1073 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt), 1074 type_left)); 1075 } 1076 if (type_right 1077 && !useless_type_conversion_p (TREE_TYPE (stmt), 1078 TREE_TYPE (TREE_OPERAND (stmt, 2)))) 1079 { 1080 TREE_OPERAND (stmt, 2) 1081 = fold_convert (type_right, TREE_OPERAND (stmt, 2)); 1082 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt), 1083 type_right)); 1084 } 1085 } 1086 1087 else if (TREE_CODE (stmt) == BIND_EXPR) 1088 { 1089 if (__builtin_expect (wtd->omp_ctx != NULL, 0)) 1090 { 1091 tree decl; 1092 for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl)) 1093 if (VAR_P (decl) 1094 && !DECL_EXTERNAL (decl) 1095 && omp_var_to_track (decl)) 1096 { 1097 splay_tree_node n 1098 = splay_tree_lookup (wtd->omp_ctx->variables, 1099 (splay_tree_key) decl); 1100 if (n == NULL) 1101 splay_tree_insert (wtd->omp_ctx->variables, 1102 (splay_tree_key) decl, 1103 TREE_STATIC (decl) 1104 ? OMP_CLAUSE_DEFAULT_SHARED 1105 : OMP_CLAUSE_DEFAULT_PRIVATE); 1106 } 1107 } 1108 if (flag_sanitize 1109 & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR)) 1110 { 1111 /* The point here is to not sanitize static initializers. */ 1112 bool no_sanitize_p = wtd->no_sanitize_p; 1113 wtd->no_sanitize_p = true; 1114 for (tree decl = BIND_EXPR_VARS (stmt); 1115 decl; 1116 decl = DECL_CHAIN (decl)) 1117 if (VAR_P (decl) 1118 && TREE_STATIC (decl) 1119 && DECL_INITIAL (decl)) 1120 cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL); 1121 wtd->no_sanitize_p = no_sanitize_p; 1122 } 1123 wtd->bind_expr_stack.safe_push (stmt); 1124 cp_walk_tree (&BIND_EXPR_BODY (stmt), 1125 cp_genericize_r, data, NULL); 1126 wtd->bind_expr_stack.pop (); 1127 } 1128 1129 else if (TREE_CODE (stmt) == USING_STMT) 1130 { 1131 tree block = NULL_TREE; 1132 1133 /* Get the innermost inclosing GIMPLE_BIND that has a non NULL 1134 BLOCK, and append an IMPORTED_DECL to its 1135 BLOCK_VARS chained list. */ 1136 if (wtd->bind_expr_stack.exists ()) 1137 { 1138 int i; 1139 for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--) 1140 if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i]))) 1141 break; 1142 } 1143 if (block) 1144 { 1145 tree using_directive; 1146 gcc_assert (TREE_OPERAND (stmt, 0)); 1147 1148 using_directive = make_node (IMPORTED_DECL); 1149 TREE_TYPE (using_directive) = void_type_node; 1150 1151 IMPORTED_DECL_ASSOCIATED_DECL (using_directive) 1152 = TREE_OPERAND (stmt, 0); 1153 DECL_CHAIN (using_directive) = BLOCK_VARS (block); 1154 BLOCK_VARS (block) = using_directive; 1155 } 1156 /* The USING_STMT won't appear in GENERIC. */ 1157 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node); 1158 *walk_subtrees = 0; 1159 } 1160 1161 else if (TREE_CODE (stmt) == DECL_EXPR 1162 && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL) 1163 { 1164 /* Using decls inside DECL_EXPRs are just dropped on the floor. */ 1165 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node); 1166 *walk_subtrees = 0; 1167 } 1168 else if (TREE_CODE (stmt) == OMP_PARALLEL || TREE_CODE (stmt) == OMP_TASK) 1169 { 1170 struct cp_genericize_omp_taskreg omp_ctx; 1171 tree c, decl; 1172 splay_tree_node n; 1173 1174 *walk_subtrees = 0; 1175 cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL); 1176 omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL; 1177 omp_ctx.default_shared = omp_ctx.is_parallel; 1178 omp_ctx.outer = wtd->omp_ctx; 1179 omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0); 1180 wtd->omp_ctx = &omp_ctx; 1181 for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c)) 1182 switch (OMP_CLAUSE_CODE (c)) 1183 { 1184 case OMP_CLAUSE_SHARED: 1185 case OMP_CLAUSE_PRIVATE: 1186 case OMP_CLAUSE_FIRSTPRIVATE: 1187 case OMP_CLAUSE_LASTPRIVATE: 1188 decl = OMP_CLAUSE_DECL (c); 1189 if (decl == error_mark_node || !omp_var_to_track (decl)) 1190 break; 1191 n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl); 1192 if (n != NULL) 1193 break; 1194 splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl, 1195 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED 1196 ? OMP_CLAUSE_DEFAULT_SHARED 1197 : OMP_CLAUSE_DEFAULT_PRIVATE); 1198 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE 1199 && omp_ctx.outer) 1200 omp_cxx_notice_variable (omp_ctx.outer, decl); 1201 break; 1202 case OMP_CLAUSE_DEFAULT: 1203 if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED) 1204 omp_ctx.default_shared = true; 1205 default: 1206 break; 1207 } 1208 cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL); 1209 wtd->omp_ctx = omp_ctx.outer; 1210 splay_tree_delete (omp_ctx.variables); 1211 } 1212 else if (TREE_CODE (stmt) == CONVERT_EXPR) 1213 gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt)); 1214 else if (TREE_CODE (stmt) == FOR_STMT) 1215 genericize_for_stmt (stmt_p, walk_subtrees, data); 1216 else if (TREE_CODE (stmt) == WHILE_STMT) 1217 genericize_while_stmt (stmt_p, walk_subtrees, data); 1218 else if (TREE_CODE (stmt) == DO_STMT) 1219 genericize_do_stmt (stmt_p, walk_subtrees, data); 1220 else if (TREE_CODE (stmt) == SWITCH_STMT) 1221 genericize_switch_stmt (stmt_p, walk_subtrees, data); 1222 else if (TREE_CODE (stmt) == CONTINUE_STMT) 1223 genericize_continue_stmt (stmt_p); 1224 else if (TREE_CODE (stmt) == BREAK_STMT) 1225 genericize_break_stmt (stmt_p); 1226 else if (TREE_CODE (stmt) == OMP_FOR 1227 || TREE_CODE (stmt) == OMP_SIMD 1228 || TREE_CODE (stmt) == OMP_DISTRIBUTE) 1229 genericize_omp_for_stmt (stmt_p, walk_subtrees, data); 1230 else if (TREE_CODE (stmt) == SIZEOF_EXPR) 1231 { 1232 if (SIZEOF_EXPR_TYPE_P (stmt)) 1233 *stmt_p 1234 = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (stmt, 0)), 1235 SIZEOF_EXPR, false); 1236 else if (TYPE_P (TREE_OPERAND (stmt, 0))) 1237 *stmt_p = cxx_sizeof_or_alignof_type (TREE_OPERAND (stmt, 0), 1238 SIZEOF_EXPR, false); 1239 else 1240 *stmt_p = cxx_sizeof_or_alignof_expr (TREE_OPERAND (stmt, 0), 1241 SIZEOF_EXPR, false); 1242 if (*stmt_p == error_mark_node) 1243 *stmt_p = size_one_node; 1244 return NULL; 1245 } 1246 else if ((flag_sanitize 1247 & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR)) 1248 && !wtd->no_sanitize_p) 1249 { 1250 if ((flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) 1251 && TREE_CODE (stmt) == NOP_EXPR 1252 && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE) 1253 ubsan_maybe_instrument_reference (stmt); 1254 else if (TREE_CODE (stmt) == CALL_EXPR) 1255 { 1256 tree fn = CALL_EXPR_FN (stmt); 1257 if (fn != NULL_TREE 1258 && !error_operand_p (fn) 1259 && POINTER_TYPE_P (TREE_TYPE (fn)) 1260 && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE) 1261 { 1262 bool is_ctor 1263 = TREE_CODE (fn) == ADDR_EXPR 1264 && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL 1265 && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)); 1266 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) 1267 ubsan_maybe_instrument_member_call (stmt, is_ctor); 1268 if ((flag_sanitize & SANITIZE_VPTR) && !is_ctor) 1269 cp_ubsan_maybe_instrument_member_call (stmt); 1270 } 1271 } 1272 } 1273 1274 p_set->add (*stmt_p); 1275 1276 return NULL; 1277} 1278 1279/* Lower C++ front end trees to GENERIC in T_P. */ 1280 1281static void 1282cp_genericize_tree (tree* t_p) 1283{ 1284 struct cp_genericize_data wtd; 1285 1286 wtd.p_set = new hash_set<tree>; 1287 wtd.bind_expr_stack.create (0); 1288 wtd.omp_ctx = NULL; 1289 wtd.no_sanitize_p = false; 1290 cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL); 1291 delete wtd.p_set; 1292 wtd.bind_expr_stack.release (); 1293 if (flag_sanitize & SANITIZE_VPTR) 1294 cp_ubsan_instrument_member_accesses (t_p); 1295} 1296 1297/* If a function that should end with a return in non-void 1298 function doesn't obviously end with return, add ubsan 1299 instrumentation code to verify it at runtime. */ 1300 1301static void 1302cp_ubsan_maybe_instrument_return (tree fndecl) 1303{ 1304 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))) 1305 || DECL_CONSTRUCTOR_P (fndecl) 1306 || DECL_DESTRUCTOR_P (fndecl) 1307 || !targetm.warn_func_return (fndecl)) 1308 return; 1309 1310 tree t = DECL_SAVED_TREE (fndecl); 1311 while (t) 1312 { 1313 switch (TREE_CODE (t)) 1314 { 1315 case BIND_EXPR: 1316 t = BIND_EXPR_BODY (t); 1317 continue; 1318 case TRY_FINALLY_EXPR: 1319 t = TREE_OPERAND (t, 0); 1320 continue; 1321 case STATEMENT_LIST: 1322 { 1323 tree_stmt_iterator i = tsi_last (t); 1324 if (!tsi_end_p (i)) 1325 { 1326 t = tsi_stmt (i); 1327 continue; 1328 } 1329 } 1330 break; 1331 case RETURN_EXPR: 1332 return; 1333 default: 1334 break; 1335 } 1336 break; 1337 } 1338 if (t == NULL_TREE) 1339 return; 1340 t = DECL_SAVED_TREE (fndecl); 1341 if (TREE_CODE (t) == BIND_EXPR 1342 && TREE_CODE (BIND_EXPR_BODY (t)) == STATEMENT_LIST) 1343 { 1344 tree_stmt_iterator i = tsi_last (BIND_EXPR_BODY (t)); 1345 t = ubsan_instrument_return (DECL_SOURCE_LOCATION (fndecl)); 1346 tsi_link_after (&i, t, TSI_NEW_STMT); 1347 } 1348} 1349 1350void 1351cp_genericize (tree fndecl) 1352{ 1353 tree t; 1354 1355 /* Fix up the types of parms passed by invisible reference. */ 1356 for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t)) 1357 if (TREE_ADDRESSABLE (TREE_TYPE (t))) 1358 { 1359 /* If a function's arguments are copied to create a thunk, 1360 then DECL_BY_REFERENCE will be set -- but the type of the 1361 argument will be a pointer type, so we will never get 1362 here. */ 1363 gcc_assert (!DECL_BY_REFERENCE (t)); 1364 gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t)); 1365 TREE_TYPE (t) = DECL_ARG_TYPE (t); 1366 DECL_BY_REFERENCE (t) = 1; 1367 TREE_ADDRESSABLE (t) = 0; 1368 relayout_decl (t); 1369 } 1370 1371 /* Do the same for the return value. */ 1372 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl)))) 1373 { 1374 t = DECL_RESULT (fndecl); 1375 TREE_TYPE (t) = build_reference_type (TREE_TYPE (t)); 1376 DECL_BY_REFERENCE (t) = 1; 1377 TREE_ADDRESSABLE (t) = 0; 1378 relayout_decl (t); 1379 if (DECL_NAME (t)) 1380 { 1381 /* Adjust DECL_VALUE_EXPR of the original var. */ 1382 tree outer = outer_curly_brace_block (current_function_decl); 1383 tree var; 1384 1385 if (outer) 1386 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) 1387 if (DECL_NAME (t) == DECL_NAME (var) 1388 && DECL_HAS_VALUE_EXPR_P (var) 1389 && DECL_VALUE_EXPR (var) == t) 1390 { 1391 tree val = convert_from_reference (t); 1392 SET_DECL_VALUE_EXPR (var, val); 1393 break; 1394 } 1395 } 1396 } 1397 1398 /* If we're a clone, the body is already GIMPLE. */ 1399 if (DECL_CLONED_FUNCTION_P (fndecl)) 1400 return; 1401 1402 /* Expand all the array notations here. */ 1403 if (flag_cilkplus 1404 && contains_array_notation_expr (DECL_SAVED_TREE (fndecl))) 1405 DECL_SAVED_TREE (fndecl) = 1406 expand_array_notation_exprs (DECL_SAVED_TREE (fndecl)); 1407 1408 /* We do want to see every occurrence of the parms, so we can't just use 1409 walk_tree's hash functionality. */ 1410 cp_genericize_tree (&DECL_SAVED_TREE (fndecl)); 1411 1412 if (flag_sanitize & SANITIZE_RETURN 1413 && do_ubsan_in_current_function ()) 1414 cp_ubsan_maybe_instrument_return (fndecl); 1415 1416 /* Do everything else. */ 1417 c_genericize (fndecl); 1418 1419 gcc_assert (bc_label[bc_break] == NULL); 1420 gcc_assert (bc_label[bc_continue] == NULL); 1421} 1422 1423/* Build code to apply FN to each member of ARG1 and ARG2. FN may be 1424 NULL if there is in fact nothing to do. ARG2 may be null if FN 1425 actually only takes one argument. */ 1426 1427static tree 1428cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2) 1429{ 1430 tree defparm, parm, t; 1431 int i = 0; 1432 int nargs; 1433 tree *argarray; 1434 1435 if (fn == NULL) 1436 return NULL; 1437 1438 nargs = list_length (DECL_ARGUMENTS (fn)); 1439 argarray = XALLOCAVEC (tree, nargs); 1440 1441 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))); 1442 if (arg2) 1443 defparm = TREE_CHAIN (defparm); 1444 1445 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE) 1446 { 1447 tree inner_type = TREE_TYPE (arg1); 1448 tree start1, end1, p1; 1449 tree start2 = NULL, p2 = NULL; 1450 tree ret = NULL, lab; 1451 1452 start1 = arg1; 1453 start2 = arg2; 1454 do 1455 { 1456 inner_type = TREE_TYPE (inner_type); 1457 start1 = build4 (ARRAY_REF, inner_type, start1, 1458 size_zero_node, NULL, NULL); 1459 if (arg2) 1460 start2 = build4 (ARRAY_REF, inner_type, start2, 1461 size_zero_node, NULL, NULL); 1462 } 1463 while (TREE_CODE (inner_type) == ARRAY_TYPE); 1464 start1 = build_fold_addr_expr_loc (input_location, start1); 1465 if (arg2) 1466 start2 = build_fold_addr_expr_loc (input_location, start2); 1467 1468 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1)); 1469 end1 = fold_build_pointer_plus (start1, end1); 1470 1471 p1 = create_tmp_var (TREE_TYPE (start1)); 1472 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1); 1473 append_to_statement_list (t, &ret); 1474 1475 if (arg2) 1476 { 1477 p2 = create_tmp_var (TREE_TYPE (start2)); 1478 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2); 1479 append_to_statement_list (t, &ret); 1480 } 1481 1482 lab = create_artificial_label (input_location); 1483 t = build1 (LABEL_EXPR, void_type_node, lab); 1484 append_to_statement_list (t, &ret); 1485 1486 argarray[i++] = p1; 1487 if (arg2) 1488 argarray[i++] = p2; 1489 /* Handle default arguments. */ 1490 for (parm = defparm; parm && parm != void_list_node; 1491 parm = TREE_CHAIN (parm), i++) 1492 argarray[i] = convert_default_arg (TREE_VALUE (parm), 1493 TREE_PURPOSE (parm), fn, i, 1494 tf_warning_or_error); 1495 t = build_call_a (fn, i, argarray); 1496 t = fold_convert (void_type_node, t); 1497 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); 1498 append_to_statement_list (t, &ret); 1499 1500 t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type)); 1501 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t); 1502 append_to_statement_list (t, &ret); 1503 1504 if (arg2) 1505 { 1506 t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type)); 1507 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t); 1508 append_to_statement_list (t, &ret); 1509 } 1510 1511 t = build2 (NE_EXPR, boolean_type_node, p1, end1); 1512 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL); 1513 append_to_statement_list (t, &ret); 1514 1515 return ret; 1516 } 1517 else 1518 { 1519 argarray[i++] = build_fold_addr_expr_loc (input_location, arg1); 1520 if (arg2) 1521 argarray[i++] = build_fold_addr_expr_loc (input_location, arg2); 1522 /* Handle default arguments. */ 1523 for (parm = defparm; parm && parm != void_list_node; 1524 parm = TREE_CHAIN (parm), i++) 1525 argarray[i] = convert_default_arg (TREE_VALUE (parm), 1526 TREE_PURPOSE (parm), 1527 fn, i, tf_warning_or_error); 1528 t = build_call_a (fn, i, argarray); 1529 t = fold_convert (void_type_node, t); 1530 return fold_build_cleanup_point_expr (TREE_TYPE (t), t); 1531 } 1532} 1533 1534/* Return code to initialize DECL with its default constructor, or 1535 NULL if there's nothing to do. */ 1536 1537tree 1538cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/) 1539{ 1540 tree info = CP_OMP_CLAUSE_INFO (clause); 1541 tree ret = NULL; 1542 1543 if (info) 1544 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL); 1545 1546 return ret; 1547} 1548 1549/* Return code to initialize DST with a copy constructor from SRC. */ 1550 1551tree 1552cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src) 1553{ 1554 tree info = CP_OMP_CLAUSE_INFO (clause); 1555 tree ret = NULL; 1556 1557 if (info) 1558 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src); 1559 if (ret == NULL) 1560 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); 1561 1562 return ret; 1563} 1564 1565/* Similarly, except use an assignment operator instead. */ 1566 1567tree 1568cxx_omp_clause_assign_op (tree clause, tree dst, tree src) 1569{ 1570 tree info = CP_OMP_CLAUSE_INFO (clause); 1571 tree ret = NULL; 1572 1573 if (info) 1574 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src); 1575 if (ret == NULL) 1576 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); 1577 1578 return ret; 1579} 1580 1581/* Return code to destroy DECL. */ 1582 1583tree 1584cxx_omp_clause_dtor (tree clause, tree decl) 1585{ 1586 tree info = CP_OMP_CLAUSE_INFO (clause); 1587 tree ret = NULL; 1588 1589 if (info) 1590 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL); 1591 1592 return ret; 1593} 1594 1595/* True if OpenMP should privatize what this DECL points to rather 1596 than the DECL itself. */ 1597 1598bool 1599cxx_omp_privatize_by_reference (const_tree decl) 1600{ 1601 return (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE 1602 || is_invisiref_parm (decl)); 1603} 1604 1605/* Return true if DECL is const qualified var having no mutable member. */ 1606bool 1607cxx_omp_const_qual_no_mutable (tree decl) 1608{ 1609 tree type = TREE_TYPE (decl); 1610 if (TREE_CODE (type) == REFERENCE_TYPE) 1611 { 1612 if (!is_invisiref_parm (decl)) 1613 return false; 1614 type = TREE_TYPE (type); 1615 1616 if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl)) 1617 { 1618 /* NVR doesn't preserve const qualification of the 1619 variable's type. */ 1620 tree outer = outer_curly_brace_block (current_function_decl); 1621 tree var; 1622 1623 if (outer) 1624 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) 1625 if (DECL_NAME (decl) == DECL_NAME (var) 1626 && (TYPE_MAIN_VARIANT (type) 1627 == TYPE_MAIN_VARIANT (TREE_TYPE (var)))) 1628 { 1629 if (TYPE_READONLY (TREE_TYPE (var))) 1630 type = TREE_TYPE (var); 1631 break; 1632 } 1633 } 1634 } 1635 1636 if (type == error_mark_node) 1637 return false; 1638 1639 /* Variables with const-qualified type having no mutable member 1640 are predetermined shared. */ 1641 if (TYPE_READONLY (type) && !cp_has_mutable_p (type)) 1642 return true; 1643 1644 return false; 1645} 1646 1647/* True if OpenMP sharing attribute of DECL is predetermined. */ 1648 1649enum omp_clause_default_kind 1650cxx_omp_predetermined_sharing (tree decl) 1651{ 1652 /* Static data members are predetermined shared. */ 1653 if (TREE_STATIC (decl)) 1654 { 1655 tree ctx = CP_DECL_CONTEXT (decl); 1656 if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx)) 1657 return OMP_CLAUSE_DEFAULT_SHARED; 1658 } 1659 1660 /* Const qualified vars having no mutable member are predetermined 1661 shared. */ 1662 if (cxx_omp_const_qual_no_mutable (decl)) 1663 return OMP_CLAUSE_DEFAULT_SHARED; 1664 1665 return OMP_CLAUSE_DEFAULT_UNSPECIFIED; 1666} 1667 1668/* Finalize an implicitly determined clause. */ 1669 1670void 1671cxx_omp_finish_clause (tree c, gimple_seq *) 1672{ 1673 tree decl, inner_type; 1674 bool make_shared = false; 1675 1676 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE) 1677 return; 1678 1679 decl = OMP_CLAUSE_DECL (c); 1680 decl = require_complete_type (decl); 1681 inner_type = TREE_TYPE (decl); 1682 if (decl == error_mark_node) 1683 make_shared = true; 1684 else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE) 1685 { 1686 if (is_invisiref_parm (decl)) 1687 inner_type = TREE_TYPE (inner_type); 1688 else 1689 { 1690 error ("%qE implicitly determined as %<firstprivate%> has reference type", 1691 decl); 1692 make_shared = true; 1693 } 1694 } 1695 1696 /* We're interested in the base element, not arrays. */ 1697 while (TREE_CODE (inner_type) == ARRAY_TYPE) 1698 inner_type = TREE_TYPE (inner_type); 1699 1700 /* Check for special function availability by building a call to one. 1701 Save the results, because later we won't be in the right context 1702 for making these queries. */ 1703 if (!make_shared 1704 && CLASS_TYPE_P (inner_type) 1705 && cxx_omp_create_clause_info (c, inner_type, false, true, false, true)) 1706 make_shared = true; 1707 1708 if (make_shared) 1709 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED; 1710} 1711