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 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free 10 Software Foundation; either version 3, or (at your option) any later 11 version. 12 13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 for more details. 17 18 You should have received a copy of the GNU General Public License 19 along 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 61 static tree cp_genericize_r (tree *, int *, void *); 62 static void cp_genericize_tree (tree*, bool); 63 64 /* Local declarations. */ 65 66 enum 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. */ 70 static 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 78 static tree 79 begin_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 98 static void 99 finish_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 114 static tree 115 get_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 126 static void 127 genericize_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 137 static void 138 genericize_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 150 static tree 151 build_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 168 static void 169 genericize_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 182 static void 183 genericize_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 216 static void 217 genericize_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 282 static void 283 genericize_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 306 static void 307 genericize_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 316 static void 317 genericize_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 326 static void 327 genericize_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 352 static void 353 genericize_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 367 static void 368 genericize_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 377 static void 378 genericize_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 397 static enum gimplify_status 398 cp_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 418 static void 419 gimplify_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 453 static void 454 cp_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 507 static enum gimplify_status 508 gimplify_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 540 static bool 541 simple_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 558 int 559 cp_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, false); 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 786 static inline bool 787 is_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 795 bool 796 cxx_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 803 unsigned int 804 cxx_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 811 static int 812 splay_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 822 struct 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 833 static bool 834 omp_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 852 static void 853 omp_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 903 struct 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 bool handle_invisiref_parm_p; 910 }; 911 912 /* Perform any pre-gimplification lowering of C++ front end trees to 913 GENERIC. */ 914 915 static tree 916 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) 917 { 918 tree stmt = *stmt_p; 919 struct cp_genericize_data *wtd = (struct cp_genericize_data *) data; 920 hash_set<tree> *p_set = wtd->p_set; 921 922 /* If in an OpenMP context, note var uses. */ 923 if (__builtin_expect (wtd->omp_ctx != NULL, 0) 924 && (VAR_P (stmt) 925 || TREE_CODE (stmt) == PARM_DECL 926 || TREE_CODE (stmt) == RESULT_DECL) 927 && omp_var_to_track (stmt)) 928 omp_cxx_notice_variable (wtd->omp_ctx, stmt); 929 930 if (wtd->handle_invisiref_parm_p 931 && is_invisiref_parm (stmt) 932 /* Don't dereference parms in a thunk, pass the references through. */ 933 && !(DECL_THUNK_P (current_function_decl) 934 && TREE_CODE (stmt) == PARM_DECL)) 935 { 936 *stmt_p = convert_from_reference (stmt); 937 *walk_subtrees = 0; 938 return NULL; 939 } 940 941 /* Map block scope extern declarations to visible declarations with the 942 same name and type in outer scopes if any. */ 943 if (cp_function_chain->extern_decl_map 944 && VAR_OR_FUNCTION_DECL_P (stmt) 945 && DECL_EXTERNAL (stmt)) 946 { 947 struct cxx_int_tree_map *h, in; 948 in.uid = DECL_UID (stmt); 949 h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid); 950 if (h) 951 { 952 *stmt_p = h->to; 953 *walk_subtrees = 0; 954 return NULL; 955 } 956 } 957 958 /* Other than invisiref parms, don't walk the same tree twice. */ 959 if (p_set->contains (stmt)) 960 { 961 *walk_subtrees = 0; 962 return NULL_TREE; 963 } 964 965 if (TREE_CODE (stmt) == ADDR_EXPR 966 && is_invisiref_parm (TREE_OPERAND (stmt, 0))) 967 { 968 /* If in an OpenMP context, note var uses. */ 969 if (__builtin_expect (wtd->omp_ctx != NULL, 0) 970 && omp_var_to_track (TREE_OPERAND (stmt, 0))) 971 omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0)); 972 *stmt_p = convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0)); 973 *walk_subtrees = 0; 974 } 975 else if (TREE_CODE (stmt) == RETURN_EXPR 976 && TREE_OPERAND (stmt, 0) 977 && is_invisiref_parm (TREE_OPERAND (stmt, 0))) 978 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */ 979 *walk_subtrees = 0; 980 else if (TREE_CODE (stmt) == OMP_CLAUSE) 981 switch (OMP_CLAUSE_CODE (stmt)) 982 { 983 case OMP_CLAUSE_LASTPRIVATE: 984 /* Don't dereference an invisiref in OpenMP clauses. */ 985 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 986 { 987 *walk_subtrees = 0; 988 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt)) 989 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt), 990 cp_genericize_r, data, NULL); 991 } 992 break; 993 case OMP_CLAUSE_PRIVATE: 994 /* Don't dereference an invisiref in OpenMP clauses. */ 995 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 996 *walk_subtrees = 0; 997 else if (wtd->omp_ctx != NULL) 998 { 999 /* Private clause doesn't cause any references to the 1000 var in outer contexts, avoid calling 1001 omp_cxx_notice_variable for it. */ 1002 struct cp_genericize_omp_taskreg *old = wtd->omp_ctx; 1003 wtd->omp_ctx = NULL; 1004 cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r, 1005 data, NULL); 1006 wtd->omp_ctx = old; 1007 *walk_subtrees = 0; 1008 } 1009 break; 1010 case OMP_CLAUSE_SHARED: 1011 case OMP_CLAUSE_FIRSTPRIVATE: 1012 case OMP_CLAUSE_COPYIN: 1013 case OMP_CLAUSE_COPYPRIVATE: 1014 /* Don't dereference an invisiref in OpenMP clauses. */ 1015 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 1016 *walk_subtrees = 0; 1017 break; 1018 case OMP_CLAUSE_REDUCTION: 1019 /* Don't dereference an invisiref in reduction clause's 1020 OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE} 1021 still needs to be genericized. */ 1022 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 1023 { 1024 *walk_subtrees = 0; 1025 if (OMP_CLAUSE_REDUCTION_INIT (stmt)) 1026 cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt), 1027 cp_genericize_r, data, NULL); 1028 if (OMP_CLAUSE_REDUCTION_MERGE (stmt)) 1029 cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt), 1030 cp_genericize_r, data, NULL); 1031 } 1032 break; 1033 default: 1034 break; 1035 } 1036 else if (IS_TYPE_OR_DECL_P (stmt)) 1037 *walk_subtrees = 0; 1038 1039 /* Due to the way voidify_wrapper_expr is written, we don't get a chance 1040 to lower this construct before scanning it, so we need to lower these 1041 before doing anything else. */ 1042 else if (TREE_CODE (stmt) == CLEANUP_STMT) 1043 *stmt_p = build2_loc (EXPR_LOCATION (stmt), 1044 CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR 1045 : TRY_FINALLY_EXPR, 1046 void_type_node, 1047 CLEANUP_BODY (stmt), 1048 CLEANUP_EXPR (stmt)); 1049 1050 else if (TREE_CODE (stmt) == IF_STMT) 1051 { 1052 genericize_if_stmt (stmt_p); 1053 /* *stmt_p has changed, tail recurse to handle it again. */ 1054 return cp_genericize_r (stmt_p, walk_subtrees, data); 1055 } 1056 1057 /* COND_EXPR might have incompatible types in branches if one or both 1058 arms are bitfields. Fix it up now. */ 1059 else if (TREE_CODE (stmt) == COND_EXPR) 1060 { 1061 tree type_left 1062 = (TREE_OPERAND (stmt, 1) 1063 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1)) 1064 : NULL_TREE); 1065 tree type_right 1066 = (TREE_OPERAND (stmt, 2) 1067 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2)) 1068 : NULL_TREE); 1069 if (type_left 1070 && !useless_type_conversion_p (TREE_TYPE (stmt), 1071 TREE_TYPE (TREE_OPERAND (stmt, 1)))) 1072 { 1073 TREE_OPERAND (stmt, 1) 1074 = fold_convert (type_left, TREE_OPERAND (stmt, 1)); 1075 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt), 1076 type_left)); 1077 } 1078 if (type_right 1079 && !useless_type_conversion_p (TREE_TYPE (stmt), 1080 TREE_TYPE (TREE_OPERAND (stmt, 2)))) 1081 { 1082 TREE_OPERAND (stmt, 2) 1083 = fold_convert (type_right, TREE_OPERAND (stmt, 2)); 1084 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt), 1085 type_right)); 1086 } 1087 } 1088 1089 else if (TREE_CODE (stmt) == BIND_EXPR) 1090 { 1091 if (__builtin_expect (wtd->omp_ctx != NULL, 0)) 1092 { 1093 tree decl; 1094 for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl)) 1095 if (VAR_P (decl) 1096 && !DECL_EXTERNAL (decl) 1097 && omp_var_to_track (decl)) 1098 { 1099 splay_tree_node n 1100 = splay_tree_lookup (wtd->omp_ctx->variables, 1101 (splay_tree_key) decl); 1102 if (n == NULL) 1103 splay_tree_insert (wtd->omp_ctx->variables, 1104 (splay_tree_key) decl, 1105 TREE_STATIC (decl) 1106 ? OMP_CLAUSE_DEFAULT_SHARED 1107 : OMP_CLAUSE_DEFAULT_PRIVATE); 1108 } 1109 } 1110 if (flag_sanitize 1111 & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR)) 1112 { 1113 /* The point here is to not sanitize static initializers. */ 1114 bool no_sanitize_p = wtd->no_sanitize_p; 1115 wtd->no_sanitize_p = true; 1116 for (tree decl = BIND_EXPR_VARS (stmt); 1117 decl; 1118 decl = DECL_CHAIN (decl)) 1119 if (VAR_P (decl) 1120 && TREE_STATIC (decl) 1121 && DECL_INITIAL (decl)) 1122 cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL); 1123 wtd->no_sanitize_p = no_sanitize_p; 1124 } 1125 wtd->bind_expr_stack.safe_push (stmt); 1126 cp_walk_tree (&BIND_EXPR_BODY (stmt), 1127 cp_genericize_r, data, NULL); 1128 wtd->bind_expr_stack.pop (); 1129 } 1130 1131 else if (TREE_CODE (stmt) == USING_STMT) 1132 { 1133 tree block = NULL_TREE; 1134 1135 /* Get the innermost inclosing GIMPLE_BIND that has a non NULL 1136 BLOCK, and append an IMPORTED_DECL to its 1137 BLOCK_VARS chained list. */ 1138 if (wtd->bind_expr_stack.exists ()) 1139 { 1140 int i; 1141 for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--) 1142 if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i]))) 1143 break; 1144 } 1145 if (block) 1146 { 1147 tree using_directive; 1148 gcc_assert (TREE_OPERAND (stmt, 0)); 1149 1150 using_directive = make_node (IMPORTED_DECL); 1151 TREE_TYPE (using_directive) = void_type_node; 1152 1153 IMPORTED_DECL_ASSOCIATED_DECL (using_directive) 1154 = TREE_OPERAND (stmt, 0); 1155 DECL_CHAIN (using_directive) = BLOCK_VARS (block); 1156 BLOCK_VARS (block) = using_directive; 1157 } 1158 /* The USING_STMT won't appear in GENERIC. */ 1159 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node); 1160 *walk_subtrees = 0; 1161 } 1162 1163 else if (TREE_CODE (stmt) == DECL_EXPR 1164 && TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL) 1165 { 1166 /* Using decls inside DECL_EXPRs are just dropped on the floor. */ 1167 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node); 1168 *walk_subtrees = 0; 1169 } 1170 else if (TREE_CODE (stmt) == OMP_PARALLEL || TREE_CODE (stmt) == OMP_TASK) 1171 { 1172 struct cp_genericize_omp_taskreg omp_ctx; 1173 tree c, decl; 1174 splay_tree_node n; 1175 1176 *walk_subtrees = 0; 1177 cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL); 1178 omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL; 1179 omp_ctx.default_shared = omp_ctx.is_parallel; 1180 omp_ctx.outer = wtd->omp_ctx; 1181 omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0); 1182 wtd->omp_ctx = &omp_ctx; 1183 for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c)) 1184 switch (OMP_CLAUSE_CODE (c)) 1185 { 1186 case OMP_CLAUSE_SHARED: 1187 case OMP_CLAUSE_PRIVATE: 1188 case OMP_CLAUSE_FIRSTPRIVATE: 1189 case OMP_CLAUSE_LASTPRIVATE: 1190 decl = OMP_CLAUSE_DECL (c); 1191 if (decl == error_mark_node || !omp_var_to_track (decl)) 1192 break; 1193 n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl); 1194 if (n != NULL) 1195 break; 1196 splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl, 1197 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED 1198 ? OMP_CLAUSE_DEFAULT_SHARED 1199 : OMP_CLAUSE_DEFAULT_PRIVATE); 1200 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE 1201 && omp_ctx.outer) 1202 omp_cxx_notice_variable (omp_ctx.outer, decl); 1203 break; 1204 case OMP_CLAUSE_DEFAULT: 1205 if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED) 1206 omp_ctx.default_shared = true; 1207 default: 1208 break; 1209 } 1210 cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL); 1211 wtd->omp_ctx = omp_ctx.outer; 1212 splay_tree_delete (omp_ctx.variables); 1213 } 1214 else if (TREE_CODE (stmt) == CONVERT_EXPR) 1215 gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt)); 1216 else if (TREE_CODE (stmt) == FOR_STMT) 1217 genericize_for_stmt (stmt_p, walk_subtrees, data); 1218 else if (TREE_CODE (stmt) == WHILE_STMT) 1219 genericize_while_stmt (stmt_p, walk_subtrees, data); 1220 else if (TREE_CODE (stmt) == DO_STMT) 1221 genericize_do_stmt (stmt_p, walk_subtrees, data); 1222 else if (TREE_CODE (stmt) == SWITCH_STMT) 1223 genericize_switch_stmt (stmt_p, walk_subtrees, data); 1224 else if (TREE_CODE (stmt) == CONTINUE_STMT) 1225 genericize_continue_stmt (stmt_p); 1226 else if (TREE_CODE (stmt) == BREAK_STMT) 1227 genericize_break_stmt (stmt_p); 1228 else if (TREE_CODE (stmt) == OMP_FOR 1229 || TREE_CODE (stmt) == OMP_SIMD 1230 || TREE_CODE (stmt) == OMP_DISTRIBUTE) 1231 genericize_omp_for_stmt (stmt_p, walk_subtrees, data); 1232 else if (TREE_CODE (stmt) == SIZEOF_EXPR) 1233 { 1234 if (SIZEOF_EXPR_TYPE_P (stmt)) 1235 *stmt_p 1236 = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (stmt, 0)), 1237 SIZEOF_EXPR, false); 1238 else if (TYPE_P (TREE_OPERAND (stmt, 0))) 1239 *stmt_p = cxx_sizeof_or_alignof_type (TREE_OPERAND (stmt, 0), 1240 SIZEOF_EXPR, false); 1241 else 1242 *stmt_p = cxx_sizeof_or_alignof_expr (TREE_OPERAND (stmt, 0), 1243 SIZEOF_EXPR, false); 1244 if (*stmt_p == error_mark_node) 1245 *stmt_p = size_one_node; 1246 return NULL; 1247 } 1248 else if ((flag_sanitize 1249 & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR)) 1250 && !wtd->no_sanitize_p) 1251 { 1252 if ((flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) 1253 && TREE_CODE (stmt) == NOP_EXPR 1254 && TREE_CODE (TREE_TYPE (stmt)) == REFERENCE_TYPE) 1255 ubsan_maybe_instrument_reference (stmt); 1256 else if (TREE_CODE (stmt) == CALL_EXPR) 1257 { 1258 tree fn = CALL_EXPR_FN (stmt); 1259 if (fn != NULL_TREE 1260 && !error_operand_p (fn) 1261 && POINTER_TYPE_P (TREE_TYPE (fn)) 1262 && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE) 1263 { 1264 bool is_ctor 1265 = TREE_CODE (fn) == ADDR_EXPR 1266 && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL 1267 && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)); 1268 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) 1269 ubsan_maybe_instrument_member_call (stmt, is_ctor); 1270 if ((flag_sanitize & SANITIZE_VPTR) && !is_ctor) 1271 cp_ubsan_maybe_instrument_member_call (stmt); 1272 } 1273 } 1274 } 1275 1276 p_set->add (*stmt_p); 1277 1278 return NULL; 1279 } 1280 1281 /* Lower C++ front end trees to GENERIC in T_P. */ 1282 1283 static void 1284 cp_genericize_tree (tree* t_p, bool handle_invisiref_parm_p) 1285 { 1286 struct cp_genericize_data wtd; 1287 1288 wtd.p_set = new hash_set<tree>; 1289 wtd.bind_expr_stack.create (0); 1290 wtd.omp_ctx = NULL; 1291 wtd.no_sanitize_p = false; 1292 wtd.handle_invisiref_parm_p = handle_invisiref_parm_p; 1293 cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL); 1294 delete wtd.p_set; 1295 wtd.bind_expr_stack.release (); 1296 if (flag_sanitize & SANITIZE_VPTR) 1297 cp_ubsan_instrument_member_accesses (t_p); 1298 } 1299 1300 /* If a function that should end with a return in non-void 1301 function doesn't obviously end with return, add ubsan 1302 instrumentation code to verify it at runtime. */ 1303 1304 static void 1305 cp_ubsan_maybe_instrument_return (tree fndecl) 1306 { 1307 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))) 1308 || DECL_CONSTRUCTOR_P (fndecl) 1309 || DECL_DESTRUCTOR_P (fndecl) 1310 || !targetm.warn_func_return (fndecl)) 1311 return; 1312 1313 tree t = DECL_SAVED_TREE (fndecl); 1314 while (t) 1315 { 1316 switch (TREE_CODE (t)) 1317 { 1318 case BIND_EXPR: 1319 t = BIND_EXPR_BODY (t); 1320 continue; 1321 case TRY_FINALLY_EXPR: 1322 t = TREE_OPERAND (t, 0); 1323 continue; 1324 case STATEMENT_LIST: 1325 { 1326 tree_stmt_iterator i = tsi_last (t); 1327 if (!tsi_end_p (i)) 1328 { 1329 t = tsi_stmt (i); 1330 continue; 1331 } 1332 } 1333 break; 1334 case RETURN_EXPR: 1335 return; 1336 default: 1337 break; 1338 } 1339 break; 1340 } 1341 if (t == NULL_TREE) 1342 return; 1343 tree *p = &DECL_SAVED_TREE (fndecl); 1344 if (TREE_CODE (*p) == BIND_EXPR) 1345 p = &BIND_EXPR_BODY (*p); 1346 t = ubsan_instrument_return (DECL_SOURCE_LOCATION (fndecl)); 1347 append_to_statement_list (t, p); 1348 } 1349 1350 void 1351 cp_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 (VAR_P (var) 1388 && DECL_NAME (t) == DECL_NAME (var) 1389 && DECL_HAS_VALUE_EXPR_P (var) 1390 && DECL_VALUE_EXPR (var) == t) 1391 { 1392 tree val = convert_from_reference (t); 1393 SET_DECL_VALUE_EXPR (var, val); 1394 break; 1395 } 1396 } 1397 } 1398 1399 /* If we're a clone, the body is already GIMPLE. */ 1400 if (DECL_CLONED_FUNCTION_P (fndecl)) 1401 return; 1402 1403 /* Expand all the array notations here. */ 1404 if (flag_cilkplus 1405 && contains_array_notation_expr (DECL_SAVED_TREE (fndecl))) 1406 DECL_SAVED_TREE (fndecl) 1407 = expand_array_notation_exprs (DECL_SAVED_TREE (fndecl)); 1408 1409 /* We do want to see every occurrence of the parms, so we can't just use 1410 walk_tree's hash functionality. */ 1411 cp_genericize_tree (&DECL_SAVED_TREE (fndecl), true); 1412 1413 if (flag_sanitize & SANITIZE_RETURN 1414 && do_ubsan_in_current_function ()) 1415 cp_ubsan_maybe_instrument_return (fndecl); 1416 1417 /* Do everything else. */ 1418 c_genericize (fndecl); 1419 1420 gcc_assert (bc_label[bc_break] == NULL); 1421 gcc_assert (bc_label[bc_continue] == NULL); 1422 } 1423 1424 /* Build code to apply FN to each member of ARG1 and ARG2. FN may be 1425 NULL if there is in fact nothing to do. ARG2 may be null if FN 1426 actually only takes one argument. */ 1427 1428 static tree 1429 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2) 1430 { 1431 tree defparm, parm, t; 1432 int i = 0; 1433 int nargs; 1434 tree *argarray; 1435 1436 if (fn == NULL) 1437 return NULL; 1438 1439 nargs = list_length (DECL_ARGUMENTS (fn)); 1440 argarray = XALLOCAVEC (tree, nargs); 1441 1442 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))); 1443 if (arg2) 1444 defparm = TREE_CHAIN (defparm); 1445 1446 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE) 1447 { 1448 tree inner_type = TREE_TYPE (arg1); 1449 tree start1, end1, p1; 1450 tree start2 = NULL, p2 = NULL; 1451 tree ret = NULL, lab; 1452 1453 start1 = arg1; 1454 start2 = arg2; 1455 do 1456 { 1457 inner_type = TREE_TYPE (inner_type); 1458 start1 = build4 (ARRAY_REF, inner_type, start1, 1459 size_zero_node, NULL, NULL); 1460 if (arg2) 1461 start2 = build4 (ARRAY_REF, inner_type, start2, 1462 size_zero_node, NULL, NULL); 1463 } 1464 while (TREE_CODE (inner_type) == ARRAY_TYPE); 1465 start1 = build_fold_addr_expr_loc (input_location, start1); 1466 if (arg2) 1467 start2 = build_fold_addr_expr_loc (input_location, start2); 1468 1469 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1)); 1470 end1 = fold_build_pointer_plus (start1, end1); 1471 1472 p1 = create_tmp_var (TREE_TYPE (start1)); 1473 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1); 1474 append_to_statement_list (t, &ret); 1475 1476 if (arg2) 1477 { 1478 p2 = create_tmp_var (TREE_TYPE (start2)); 1479 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2); 1480 append_to_statement_list (t, &ret); 1481 } 1482 1483 lab = create_artificial_label (input_location); 1484 t = build1 (LABEL_EXPR, void_type_node, lab); 1485 append_to_statement_list (t, &ret); 1486 1487 argarray[i++] = p1; 1488 if (arg2) 1489 argarray[i++] = p2; 1490 /* Handle default arguments. */ 1491 for (parm = defparm; parm && parm != void_list_node; 1492 parm = TREE_CHAIN (parm), i++) 1493 argarray[i] = convert_default_arg (TREE_VALUE (parm), 1494 TREE_PURPOSE (parm), fn, i, 1495 tf_warning_or_error); 1496 t = build_call_a (fn, i, argarray); 1497 t = fold_convert (void_type_node, t); 1498 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); 1499 append_to_statement_list (t, &ret); 1500 1501 t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type)); 1502 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t); 1503 append_to_statement_list (t, &ret); 1504 1505 if (arg2) 1506 { 1507 t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type)); 1508 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t); 1509 append_to_statement_list (t, &ret); 1510 } 1511 1512 t = build2 (NE_EXPR, boolean_type_node, p1, end1); 1513 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL); 1514 append_to_statement_list (t, &ret); 1515 1516 return ret; 1517 } 1518 else 1519 { 1520 argarray[i++] = build_fold_addr_expr_loc (input_location, arg1); 1521 if (arg2) 1522 argarray[i++] = build_fold_addr_expr_loc (input_location, arg2); 1523 /* Handle default arguments. */ 1524 for (parm = defparm; parm && parm != void_list_node; 1525 parm = TREE_CHAIN (parm), i++) 1526 argarray[i] = convert_default_arg (TREE_VALUE (parm), 1527 TREE_PURPOSE (parm), 1528 fn, i, tf_warning_or_error); 1529 t = build_call_a (fn, i, argarray); 1530 t = fold_convert (void_type_node, t); 1531 return fold_build_cleanup_point_expr (TREE_TYPE (t), t); 1532 } 1533 } 1534 1535 /* Return code to initialize DECL with its default constructor, or 1536 NULL if there's nothing to do. */ 1537 1538 tree 1539 cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/) 1540 { 1541 tree info = CP_OMP_CLAUSE_INFO (clause); 1542 tree ret = NULL; 1543 1544 if (info) 1545 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL); 1546 1547 return ret; 1548 } 1549 1550 /* Return code to initialize DST with a copy constructor from SRC. */ 1551 1552 tree 1553 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src) 1554 { 1555 tree info = CP_OMP_CLAUSE_INFO (clause); 1556 tree ret = NULL; 1557 1558 if (info) 1559 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src); 1560 if (ret == NULL) 1561 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); 1562 1563 return ret; 1564 } 1565 1566 /* Similarly, except use an assignment operator instead. */ 1567 1568 tree 1569 cxx_omp_clause_assign_op (tree clause, tree dst, tree src) 1570 { 1571 tree info = CP_OMP_CLAUSE_INFO (clause); 1572 tree ret = NULL; 1573 1574 if (info) 1575 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src); 1576 if (ret == NULL) 1577 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); 1578 1579 return ret; 1580 } 1581 1582 /* Return code to destroy DECL. */ 1583 1584 tree 1585 cxx_omp_clause_dtor (tree clause, tree decl) 1586 { 1587 tree info = CP_OMP_CLAUSE_INFO (clause); 1588 tree ret = NULL; 1589 1590 if (info) 1591 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL); 1592 1593 return ret; 1594 } 1595 1596 /* True if OpenMP should privatize what this DECL points to rather 1597 than the DECL itself. */ 1598 1599 bool 1600 cxx_omp_privatize_by_reference (const_tree decl) 1601 { 1602 return (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE 1603 || is_invisiref_parm (decl)); 1604 } 1605 1606 /* Return true if DECL is const qualified var having no mutable member. */ 1607 bool 1608 cxx_omp_const_qual_no_mutable (tree decl) 1609 { 1610 tree type = TREE_TYPE (decl); 1611 if (TREE_CODE (type) == REFERENCE_TYPE) 1612 { 1613 if (!is_invisiref_parm (decl)) 1614 return false; 1615 type = TREE_TYPE (type); 1616 1617 if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl)) 1618 { 1619 /* NVR doesn't preserve const qualification of the 1620 variable's type. */ 1621 tree outer = outer_curly_brace_block (current_function_decl); 1622 tree var; 1623 1624 if (outer) 1625 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) 1626 if (VAR_P (var) 1627 && DECL_NAME (decl) == DECL_NAME (var) 1628 && (TYPE_MAIN_VARIANT (type) 1629 == TYPE_MAIN_VARIANT (TREE_TYPE (var)))) 1630 { 1631 if (TYPE_READONLY (TREE_TYPE (var))) 1632 type = TREE_TYPE (var); 1633 break; 1634 } 1635 } 1636 } 1637 1638 if (type == error_mark_node) 1639 return false; 1640 1641 /* Variables with const-qualified type having no mutable member 1642 are predetermined shared. */ 1643 if (TYPE_READONLY (type) && !cp_has_mutable_p (type)) 1644 return true; 1645 1646 return false; 1647 } 1648 1649 /* True if OpenMP sharing attribute of DECL is predetermined. */ 1650 1651 enum omp_clause_default_kind 1652 cxx_omp_predetermined_sharing (tree decl) 1653 { 1654 /* Static data members are predetermined shared. */ 1655 if (TREE_STATIC (decl)) 1656 { 1657 tree ctx = CP_DECL_CONTEXT (decl); 1658 if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx)) 1659 return OMP_CLAUSE_DEFAULT_SHARED; 1660 } 1661 1662 /* Const qualified vars having no mutable member are predetermined 1663 shared. */ 1664 if (cxx_omp_const_qual_no_mutable (decl)) 1665 return OMP_CLAUSE_DEFAULT_SHARED; 1666 1667 return OMP_CLAUSE_DEFAULT_UNSPECIFIED; 1668 } 1669 1670 /* Finalize an implicitly determined clause. */ 1671 1672 void 1673 cxx_omp_finish_clause (tree c, gimple_seq *) 1674 { 1675 tree decl, inner_type; 1676 bool make_shared = false; 1677 1678 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE) 1679 return; 1680 1681 decl = OMP_CLAUSE_DECL (c); 1682 decl = require_complete_type (decl); 1683 inner_type = TREE_TYPE (decl); 1684 if (decl == error_mark_node) 1685 make_shared = true; 1686 else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE) 1687 { 1688 if (is_invisiref_parm (decl)) 1689 inner_type = TREE_TYPE (inner_type); 1690 else 1691 { 1692 error ("%qE implicitly determined as %<firstprivate%> has reference type", 1693 decl); 1694 make_shared = true; 1695 } 1696 } 1697 1698 /* We're interested in the base element, not arrays. */ 1699 while (TREE_CODE (inner_type) == ARRAY_TYPE) 1700 inner_type = TREE_TYPE (inner_type); 1701 1702 /* Check for special function availability by building a call to one. 1703 Save the results, because later we won't be in the right context 1704 for making these queries. */ 1705 if (!make_shared 1706 && CLASS_TYPE_P (inner_type) 1707 && cxx_omp_create_clause_info (c, inner_type, false, true, false, true)) 1708 make_shared = true; 1709 1710 if (make_shared) 1711 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED; 1712 } 1713