1/* C++-specific tree lowering bits; see also c-gimplify.c and gimple.c. 2 3 Copyright (C) 2002-2020 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 "target.h" 26#include "basic-block.h" 27#include "cp-tree.h" 28#include "gimple.h" 29#include "predict.h" 30#include "stor-layout.h" 31#include "tree-iterator.h" 32#include "gimplify.h" 33#include "c-family/c-ubsan.h" 34#include "stringpool.h" 35#include "attribs.h" 36#include "asan.h" 37#include "gcc-rich-location.h" 38#include "memmodel.h" 39#include "tm_p.h" 40#include "output.h" 41#include "file-prefix-map.h" 42#include "cgraph.h" 43#include "omp-general.h" 44 45struct cp_fold_data 46{ 47 hash_set<tree> pset; 48 bool genericize; // called from cp_fold_function? 49 50 cp_fold_data (bool g): genericize (g) {} 51}; 52 53/* Forward declarations. */ 54 55static tree cp_genericize_r (tree *, int *, void *); 56static tree cp_fold_r (tree *, int *, void *); 57static void cp_genericize_tree (tree*, bool); 58static tree cp_fold (tree); 59 60/* Local declarations. */ 61 62enum bc_t { bc_break = 0, bc_continue = 1 }; 63 64/* Stack of labels which are targets for "break" or "continue", 65 linked through TREE_CHAIN. */ 66static tree bc_label[2]; 67 68/* Begin a scope which can be exited by a break or continue statement. BC 69 indicates which. 70 71 Just creates a label with location LOCATION and pushes it into the current 72 context. */ 73 74static tree 75begin_bc_block (enum bc_t bc, location_t location) 76{ 77 tree label = create_artificial_label (location); 78 DECL_CHAIN (label) = bc_label[bc]; 79 bc_label[bc] = label; 80 if (bc == bc_break) 81 LABEL_DECL_BREAK (label) = true; 82 else 83 LABEL_DECL_CONTINUE (label) = true; 84 return label; 85} 86 87/* Finish a scope which can be exited by a break or continue statement. 88 LABEL was returned from the most recent call to begin_bc_block. BLOCK is 89 an expression for the contents of the scope. 90 91 If we saw a break (or continue) in the scope, append a LABEL_EXPR to 92 BLOCK. Otherwise, just forget the label. */ 93 94static void 95finish_bc_block (tree *block, enum bc_t bc, tree label) 96{ 97 gcc_assert (label == bc_label[bc]); 98 99 if (TREE_USED (label)) 100 append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label), 101 block); 102 103 bc_label[bc] = DECL_CHAIN (label); 104 DECL_CHAIN (label) = NULL_TREE; 105} 106 107/* Get the LABEL_EXPR to represent a break or continue statement 108 in the current block scope. BC indicates which. */ 109 110static tree 111get_bc_label (enum bc_t bc) 112{ 113 tree label = bc_label[bc]; 114 115 /* Mark the label used for finish_bc_block. */ 116 TREE_USED (label) = 1; 117 return label; 118} 119 120/* Genericize a TRY_BLOCK. */ 121 122static void 123genericize_try_block (tree *stmt_p) 124{ 125 tree body = TRY_STMTS (*stmt_p); 126 tree cleanup = TRY_HANDLERS (*stmt_p); 127 128 *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup); 129} 130 131/* Genericize a HANDLER by converting to a CATCH_EXPR. */ 132 133static void 134genericize_catch_block (tree *stmt_p) 135{ 136 tree type = HANDLER_TYPE (*stmt_p); 137 tree body = HANDLER_BODY (*stmt_p); 138 139 /* FIXME should the caught type go in TREE_TYPE? */ 140 *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body); 141} 142 143/* A terser interface for building a representation of an exception 144 specification. */ 145 146static tree 147build_gimple_eh_filter_tree (tree body, tree allowed, tree failure) 148{ 149 tree t; 150 151 /* FIXME should the allowed types go in TREE_TYPE? */ 152 t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE); 153 append_to_statement_list (failure, &EH_FILTER_FAILURE (t)); 154 155 t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t); 156 append_to_statement_list (body, &TREE_OPERAND (t, 0)); 157 158 return t; 159} 160 161/* Genericize an EH_SPEC_BLOCK by converting it to a 162 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */ 163 164static void 165genericize_eh_spec_block (tree *stmt_p) 166{ 167 tree body = EH_SPEC_STMTS (*stmt_p); 168 tree allowed = EH_SPEC_RAISES (*stmt_p); 169 tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ()); 170 171 *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure); 172 TREE_NO_WARNING (*stmt_p) = true; 173 TREE_NO_WARNING (TREE_OPERAND (*stmt_p, 1)) = true; 174} 175 176/* Return the first non-compound statement in STMT. */ 177 178tree 179first_stmt (tree stmt) 180{ 181 switch (TREE_CODE (stmt)) 182 { 183 case STATEMENT_LIST: 184 if (tree_statement_list_node *p = STATEMENT_LIST_HEAD (stmt)) 185 return first_stmt (p->stmt); 186 return void_node; 187 188 case BIND_EXPR: 189 return first_stmt (BIND_EXPR_BODY (stmt)); 190 191 default: 192 return stmt; 193 } 194} 195 196/* Genericize an IF_STMT by turning it into a COND_EXPR. */ 197 198static void 199genericize_if_stmt (tree *stmt_p) 200{ 201 tree stmt, cond, then_, else_; 202 location_t locus = EXPR_LOCATION (*stmt_p); 203 204 stmt = *stmt_p; 205 cond = IF_COND (stmt); 206 then_ = THEN_CLAUSE (stmt); 207 else_ = ELSE_CLAUSE (stmt); 208 209 if (then_ && else_) 210 { 211 tree ft = first_stmt (then_); 212 tree fe = first_stmt (else_); 213 br_predictor pr; 214 if (TREE_CODE (ft) == PREDICT_EXPR 215 && TREE_CODE (fe) == PREDICT_EXPR 216 && (pr = PREDICT_EXPR_PREDICTOR (ft)) == PREDICT_EXPR_PREDICTOR (fe) 217 && (pr == PRED_HOT_LABEL || pr == PRED_COLD_LABEL)) 218 { 219 gcc_rich_location richloc (EXPR_LOC_OR_LOC (ft, locus)); 220 richloc.add_range (EXPR_LOC_OR_LOC (fe, locus)); 221 warning_at (&richloc, OPT_Wattributes, 222 "both branches of %<if%> statement marked as %qs", 223 pr == PRED_HOT_LABEL ? "likely" : "unlikely"); 224 } 225 } 226 227 if (!then_) 228 then_ = build_empty_stmt (locus); 229 if (!else_) 230 else_ = build_empty_stmt (locus); 231 232 if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_)) 233 stmt = then_; 234 else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_)) 235 stmt = else_; 236 else 237 stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_); 238 protected_set_expr_location_if_unset (stmt, locus); 239 *stmt_p = stmt; 240} 241 242/* Build a generic representation of one of the C loop forms. COND is the 243 loop condition or NULL_TREE. BODY is the (possibly compound) statement 244 controlled by the loop. INCR is the increment expression of a for-loop, 245 or NULL_TREE. COND_IS_FIRST indicates whether the condition is 246 evaluated before the loop body as in while and for loops, or after the 247 loop body as in do-while loops. */ 248 249static void 250genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body, 251 tree incr, bool cond_is_first, int *walk_subtrees, 252 void *data) 253{ 254 tree blab, clab; 255 tree exit = NULL; 256 tree stmt_list = NULL; 257 tree debug_begin = NULL; 258 259 protected_set_expr_location_if_unset (incr, start_locus); 260 261 cp_walk_tree (&cond, cp_genericize_r, data, NULL); 262 cp_walk_tree (&incr, cp_genericize_r, data, NULL); 263 264 blab = begin_bc_block (bc_break, start_locus); 265 clab = begin_bc_block (bc_continue, start_locus); 266 267 cp_walk_tree (&body, cp_genericize_r, data, NULL); 268 *walk_subtrees = 0; 269 270 if (MAY_HAVE_DEBUG_MARKER_STMTS 271 && (!cond || !integer_zerop (cond))) 272 { 273 debug_begin = build0 (DEBUG_BEGIN_STMT, void_type_node); 274 SET_EXPR_LOCATION (debug_begin, cp_expr_loc_or_loc (cond, start_locus)); 275 } 276 277 if (cond && TREE_CODE (cond) != INTEGER_CST) 278 { 279 /* If COND is constant, don't bother building an exit. If it's false, 280 we won't build a loop. If it's true, any exits are in the body. */ 281 location_t cloc = cp_expr_loc_or_loc (cond, start_locus); 282 exit = build1_loc (cloc, GOTO_EXPR, void_type_node, 283 get_bc_label (bc_break)); 284 exit = fold_build3_loc (cloc, COND_EXPR, void_type_node, cond, 285 build_empty_stmt (cloc), exit); 286 } 287 288 if (exit && cond_is_first) 289 { 290 append_to_statement_list (debug_begin, &stmt_list); 291 debug_begin = NULL_TREE; 292 append_to_statement_list (exit, &stmt_list); 293 } 294 append_to_statement_list (body, &stmt_list); 295 finish_bc_block (&stmt_list, bc_continue, clab); 296 if (incr) 297 { 298 if (MAY_HAVE_DEBUG_MARKER_STMTS) 299 { 300 tree d = build0 (DEBUG_BEGIN_STMT, void_type_node); 301 SET_EXPR_LOCATION (d, cp_expr_loc_or_loc (incr, start_locus)); 302 append_to_statement_list (d, &stmt_list); 303 } 304 append_to_statement_list (incr, &stmt_list); 305 } 306 append_to_statement_list (debug_begin, &stmt_list); 307 if (exit && !cond_is_first) 308 append_to_statement_list (exit, &stmt_list); 309 310 if (!stmt_list) 311 stmt_list = build_empty_stmt (start_locus); 312 313 tree loop; 314 if (cond && integer_zerop (cond)) 315 { 316 if (cond_is_first) 317 loop = fold_build3_loc (start_locus, COND_EXPR, 318 void_type_node, cond, stmt_list, 319 build_empty_stmt (start_locus)); 320 else 321 loop = stmt_list; 322 } 323 else 324 { 325 location_t loc = start_locus; 326 if (!cond || integer_nonzerop (cond)) 327 loc = EXPR_LOCATION (expr_first (body)); 328 if (loc == UNKNOWN_LOCATION) 329 loc = start_locus; 330 loop = build1_loc (loc, LOOP_EXPR, void_type_node, stmt_list); 331 } 332 333 stmt_list = NULL; 334 append_to_statement_list (loop, &stmt_list); 335 finish_bc_block (&stmt_list, bc_break, blab); 336 if (!stmt_list) 337 stmt_list = build_empty_stmt (start_locus); 338 339 *stmt_p = stmt_list; 340} 341 342/* Genericize a FOR_STMT node *STMT_P. */ 343 344static void 345genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data) 346{ 347 tree stmt = *stmt_p; 348 tree expr = NULL; 349 tree loop; 350 tree init = FOR_INIT_STMT (stmt); 351 352 if (init) 353 { 354 cp_walk_tree (&init, cp_genericize_r, data, NULL); 355 append_to_statement_list (init, &expr); 356 } 357 358 genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt), 359 FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data); 360 append_to_statement_list (loop, &expr); 361 if (expr == NULL_TREE) 362 expr = loop; 363 *stmt_p = expr; 364} 365 366/* Genericize a WHILE_STMT node *STMT_P. */ 367 368static void 369genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data) 370{ 371 tree stmt = *stmt_p; 372 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt), 373 WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees, data); 374} 375 376/* Genericize a DO_STMT node *STMT_P. */ 377 378static void 379genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data) 380{ 381 tree stmt = *stmt_p; 382 genericize_cp_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt), 383 DO_BODY (stmt), NULL_TREE, 0, walk_subtrees, data); 384} 385 386/* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR. */ 387 388static void 389genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data) 390{ 391 tree stmt = *stmt_p; 392 tree break_block, body, cond, type; 393 location_t stmt_locus = EXPR_LOCATION (stmt); 394 395 body = SWITCH_STMT_BODY (stmt); 396 if (!body) 397 body = build_empty_stmt (stmt_locus); 398 cond = SWITCH_STMT_COND (stmt); 399 type = SWITCH_STMT_TYPE (stmt); 400 401 cp_walk_tree (&cond, cp_genericize_r, data, NULL); 402 403 break_block = begin_bc_block (bc_break, stmt_locus); 404 405 cp_walk_tree (&body, cp_genericize_r, data, NULL); 406 cp_walk_tree (&type, cp_genericize_r, data, NULL); 407 *walk_subtrees = 0; 408 409 if (TREE_USED (break_block)) 410 SWITCH_BREAK_LABEL_P (break_block) = 1; 411 finish_bc_block (&body, bc_break, break_block); 412 *stmt_p = build2_loc (stmt_locus, SWITCH_EXPR, type, cond, body); 413 SWITCH_ALL_CASES_P (*stmt_p) = SWITCH_STMT_ALL_CASES_P (stmt); 414 gcc_checking_assert (!SWITCH_STMT_NO_BREAK_P (stmt) 415 || !TREE_USED (break_block)); 416} 417 418/* Genericize a CONTINUE_STMT node *STMT_P. */ 419 420static void 421genericize_continue_stmt (tree *stmt_p) 422{ 423 tree stmt_list = NULL; 424 tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN); 425 tree label = get_bc_label (bc_continue); 426 location_t location = EXPR_LOCATION (*stmt_p); 427 tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label); 428 append_to_statement_list_force (pred, &stmt_list); 429 append_to_statement_list (jump, &stmt_list); 430 *stmt_p = stmt_list; 431} 432 433/* Genericize a BREAK_STMT node *STMT_P. */ 434 435static void 436genericize_break_stmt (tree *stmt_p) 437{ 438 tree label = get_bc_label (bc_break); 439 location_t location = EXPR_LOCATION (*stmt_p); 440 *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label); 441} 442 443/* Genericize a OMP_FOR node *STMT_P. */ 444 445static void 446genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data) 447{ 448 tree stmt = *stmt_p; 449 location_t locus = EXPR_LOCATION (stmt); 450 tree clab = begin_bc_block (bc_continue, locus); 451 452 cp_walk_tree (&OMP_FOR_BODY (stmt), cp_genericize_r, data, NULL); 453 if (TREE_CODE (stmt) != OMP_TASKLOOP) 454 cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_genericize_r, data, NULL); 455 cp_walk_tree (&OMP_FOR_INIT (stmt), cp_genericize_r, data, NULL); 456 cp_walk_tree (&OMP_FOR_COND (stmt), cp_genericize_r, data, NULL); 457 cp_walk_tree (&OMP_FOR_INCR (stmt), cp_genericize_r, data, NULL); 458 cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_genericize_r, data, NULL); 459 *walk_subtrees = 0; 460 461 finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab); 462} 463 464/* Hook into the middle of gimplifying an OMP_FOR node. */ 465 466static enum gimplify_status 467cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) 468{ 469 tree for_stmt = *expr_p; 470 gimple_seq seq = NULL; 471 472 /* Protect ourselves from recursion. */ 473 if (OMP_FOR_GIMPLIFYING_P (for_stmt)) 474 return GS_UNHANDLED; 475 OMP_FOR_GIMPLIFYING_P (for_stmt) = 1; 476 477 gimplify_and_add (for_stmt, &seq); 478 gimple_seq_add_seq (pre_p, seq); 479 480 OMP_FOR_GIMPLIFYING_P (for_stmt) = 0; 481 482 return GS_ALL_DONE; 483} 484 485/* Gimplify an EXPR_STMT node. */ 486 487static void 488gimplify_expr_stmt (tree *stmt_p) 489{ 490 tree stmt = EXPR_STMT_EXPR (*stmt_p); 491 492 if (stmt == error_mark_node) 493 stmt = NULL; 494 495 /* Gimplification of a statement expression will nullify the 496 statement if all its side effects are moved to *PRE_P and *POST_P. 497 498 In this case we will not want to emit the gimplified statement. 499 However, we may still want to emit a warning, so we do that before 500 gimplification. */ 501 if (stmt && warn_unused_value) 502 { 503 if (!TREE_SIDE_EFFECTS (stmt)) 504 { 505 if (!IS_EMPTY_STMT (stmt) 506 && !VOID_TYPE_P (TREE_TYPE (stmt)) 507 && !TREE_NO_WARNING (stmt)) 508 warning (OPT_Wunused_value, "statement with no effect"); 509 } 510 else 511 warn_if_unused_value (stmt, input_location); 512 } 513 514 if (stmt == NULL_TREE) 515 stmt = alloc_stmt_list (); 516 517 *stmt_p = stmt; 518} 519 520/* Gimplify initialization from an AGGR_INIT_EXPR. */ 521 522static void 523cp_gimplify_init_expr (tree *expr_p) 524{ 525 tree from = TREE_OPERAND (*expr_p, 1); 526 tree to = TREE_OPERAND (*expr_p, 0); 527 tree t; 528 529 /* What about code that pulls out the temp and uses it elsewhere? I 530 think that such code never uses the TARGET_EXPR as an initializer. If 531 I'm wrong, we'll abort because the temp won't have any RTL. In that 532 case, I guess we'll need to replace references somehow. */ 533 if (TREE_CODE (from) == TARGET_EXPR && TARGET_EXPR_INITIAL (from)) 534 from = TARGET_EXPR_INITIAL (from); 535 536 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them 537 inside the TARGET_EXPR. */ 538 for (t = from; t; ) 539 { 540 tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t; 541 542 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and 543 replace the slot operand with our target. 544 545 Should we add a target parm to gimplify_expr instead? No, as in this 546 case we want to replace the INIT_EXPR. */ 547 if (TREE_CODE (sub) == AGGR_INIT_EXPR 548 || TREE_CODE (sub) == VEC_INIT_EXPR) 549 { 550 if (TREE_CODE (sub) == AGGR_INIT_EXPR) 551 AGGR_INIT_EXPR_SLOT (sub) = to; 552 else 553 VEC_INIT_EXPR_SLOT (sub) = to; 554 *expr_p = from; 555 556 /* The initialization is now a side-effect, so the container can 557 become void. */ 558 if (from != sub) 559 TREE_TYPE (from) = void_type_node; 560 } 561 562 /* Handle aggregate NSDMI. */ 563 replace_placeholders (sub, to); 564 565 if (t == sub) 566 break; 567 else 568 t = TREE_OPERAND (t, 1); 569 } 570 571} 572 573/* Gimplify a MUST_NOT_THROW_EXPR. */ 574 575static enum gimplify_status 576gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p) 577{ 578 tree stmt = *expr_p; 579 tree temp = voidify_wrapper_expr (stmt, NULL); 580 tree body = TREE_OPERAND (stmt, 0); 581 gimple_seq try_ = NULL; 582 gimple_seq catch_ = NULL; 583 gimple *mnt; 584 585 gimplify_and_add (body, &try_); 586 mnt = gimple_build_eh_must_not_throw (terminate_fn); 587 gimple_seq_add_stmt_without_update (&catch_, mnt); 588 mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH); 589 590 gimple_seq_add_stmt_without_update (pre_p, mnt); 591 if (temp) 592 { 593 *expr_p = temp; 594 return GS_OK; 595 } 596 597 *expr_p = NULL; 598 return GS_ALL_DONE; 599} 600 601/* Return TRUE if an operand (OP) of a given TYPE being copied is 602 really just an empty class copy. 603 604 Check that the operand has a simple form so that TARGET_EXPRs and 605 non-empty CONSTRUCTORs get reduced properly, and we leave the 606 return slot optimization alone because it isn't a copy. */ 607 608bool 609simple_empty_class_p (tree type, tree op, tree_code code) 610{ 611 if (TREE_CODE (op) == COMPOUND_EXPR) 612 return simple_empty_class_p (type, TREE_OPERAND (op, 1), code); 613 if (SIMPLE_TARGET_EXPR_P (op) 614 && TYPE_HAS_TRIVIAL_DESTRUCTOR (type)) 615 /* The TARGET_EXPR is itself a simple copy, look through it. */ 616 return simple_empty_class_p (type, TARGET_EXPR_INITIAL (op), code); 617 618 if (TREE_CODE (op) == PARM_DECL 619 && TREE_ADDRESSABLE (TREE_TYPE (op))) 620 { 621 tree fn = DECL_CONTEXT (op); 622 if (DECL_THUNK_P (fn) 623 || lambda_static_thunk_p (fn)) 624 /* In a thunk, we pass through invisible reference parms, so this isn't 625 actually a copy. */ 626 return false; 627 } 628 629 return 630 (TREE_CODE (op) == EMPTY_CLASS_EXPR 631 || code == MODIFY_EXPR 632 || is_gimple_lvalue (op) 633 || INDIRECT_REF_P (op) 634 || (TREE_CODE (op) == CONSTRUCTOR 635 && CONSTRUCTOR_NELTS (op) == 0) 636 || (TREE_CODE (op) == CALL_EXPR 637 && !CALL_EXPR_RETURN_SLOT_OPT (op))) 638 && !TREE_CLOBBER_P (op) 639 && is_really_empty_class (type, /*ignore_vptr*/true); 640} 641 642/* Returns true if evaluating E as an lvalue has side-effects; 643 specifically, a volatile lvalue has TREE_SIDE_EFFECTS, but it doesn't really 644 have side-effects until there is a read or write through it. */ 645 646static bool 647lvalue_has_side_effects (tree e) 648{ 649 if (!TREE_SIDE_EFFECTS (e)) 650 return false; 651 while (handled_component_p (e)) 652 { 653 if (TREE_CODE (e) == ARRAY_REF 654 && TREE_SIDE_EFFECTS (TREE_OPERAND (e, 1))) 655 return true; 656 e = TREE_OPERAND (e, 0); 657 } 658 if (DECL_P (e)) 659 /* Just naming a variable has no side-effects. */ 660 return false; 661 else if (INDIRECT_REF_P (e)) 662 /* Similarly, indirection has no side-effects. */ 663 return TREE_SIDE_EFFECTS (TREE_OPERAND (e, 0)); 664 else 665 /* For anything else, trust TREE_SIDE_EFFECTS. */ 666 return TREE_SIDE_EFFECTS (e); 667} 668 669/* Gimplify *EXPR_P as rvalue into an expression that can't be modified 670 by expressions with side-effects in other operands. */ 671 672static enum gimplify_status 673gimplify_to_rvalue (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, 674 bool (*gimple_test_f) (tree)) 675{ 676 enum gimplify_status t 677 = gimplify_expr (expr_p, pre_p, post_p, gimple_test_f, fb_rvalue); 678 if (t == GS_ERROR) 679 return GS_ERROR; 680 else if (is_gimple_variable (*expr_p) && TREE_CODE (*expr_p) != SSA_NAME) 681 *expr_p = get_initialized_tmp_var (*expr_p, pre_p); 682 return t; 683} 684 685/* Like gimplify_arg, but if ORDERED is set (which should be set if 686 any of the arguments this argument is sequenced before has 687 TREE_SIDE_EFFECTS set, make sure expressions with is_gimple_reg_type type 688 are gimplified into SSA_NAME or a fresh temporary and for 689 non-is_gimple_reg_type we don't optimize away TARGET_EXPRs. */ 690 691static enum gimplify_status 692cp_gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location, 693 bool ordered) 694{ 695 enum gimplify_status t; 696 if (ordered 697 && !is_gimple_reg_type (TREE_TYPE (*arg_p)) 698 && TREE_CODE (*arg_p) == TARGET_EXPR) 699 { 700 /* gimplify_arg would strip away the TARGET_EXPR, but 701 that can mean we don't copy the argument and some following 702 argument with side-effect could modify it. */ 703 protected_set_expr_location (*arg_p, call_location); 704 return gimplify_expr (arg_p, pre_p, NULL, is_gimple_lvalue, fb_either); 705 } 706 else 707 { 708 t = gimplify_arg (arg_p, pre_p, call_location); 709 if (t == GS_ERROR) 710 return GS_ERROR; 711 else if (ordered 712 && is_gimple_reg_type (TREE_TYPE (*arg_p)) 713 && is_gimple_variable (*arg_p) 714 && TREE_CODE (*arg_p) != SSA_NAME 715 /* No need to force references into register, references 716 can't be modified. */ 717 && !TYPE_REF_P (TREE_TYPE (*arg_p)) 718 /* And this can't be modified either. */ 719 && *arg_p != current_class_ptr) 720 *arg_p = get_initialized_tmp_var (*arg_p, pre_p); 721 return t; 722 } 723 724} 725 726/* Do C++-specific gimplification. Args are as for gimplify_expr. */ 727 728int 729cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 730{ 731 int saved_stmts_are_full_exprs_p = 0; 732 location_t loc = cp_expr_loc_or_input_loc (*expr_p); 733 enum tree_code code = TREE_CODE (*expr_p); 734 enum gimplify_status ret; 735 736 if (STATEMENT_CODE_P (code)) 737 { 738 saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); 739 current_stmt_tree ()->stmts_are_full_exprs_p 740 = STMT_IS_FULL_EXPR_P (*expr_p); 741 } 742 743 switch (code) 744 { 745 case AGGR_INIT_EXPR: 746 simplify_aggr_init_expr (expr_p); 747 ret = GS_OK; 748 break; 749 750 case VEC_INIT_EXPR: 751 { 752 location_t loc = input_location; 753 tree init = VEC_INIT_EXPR_INIT (*expr_p); 754 int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE); 755 gcc_assert (EXPR_HAS_LOCATION (*expr_p)); 756 input_location = EXPR_LOCATION (*expr_p); 757 *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE, 758 init, VEC_INIT_EXPR_VALUE_INIT (*expr_p), 759 from_array, 760 tf_warning_or_error); 761 cp_fold_data data (/*genericize*/true); 762 cp_walk_tree (expr_p, cp_fold_r, &data, NULL); 763 cp_genericize_tree (expr_p, false); 764 copy_if_shared (expr_p); 765 ret = GS_OK; 766 input_location = loc; 767 } 768 break; 769 770 case THROW_EXPR: 771 /* FIXME communicate throw type to back end, probably by moving 772 THROW_EXPR into ../tree.def. */ 773 *expr_p = TREE_OPERAND (*expr_p, 0); 774 ret = GS_OK; 775 break; 776 777 case MUST_NOT_THROW_EXPR: 778 ret = gimplify_must_not_throw_expr (expr_p, pre_p); 779 break; 780 781 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the 782 LHS of an assignment might also be involved in the RHS, as in bug 783 25979. */ 784 case INIT_EXPR: 785 cp_gimplify_init_expr (expr_p); 786 if (TREE_CODE (*expr_p) != INIT_EXPR) 787 return GS_OK; 788 /* Fall through. */ 789 case MODIFY_EXPR: 790 modify_expr_case: 791 { 792 /* If the back end isn't clever enough to know that the lhs and rhs 793 types are the same, add an explicit conversion. */ 794 tree op0 = TREE_OPERAND (*expr_p, 0); 795 tree op1 = TREE_OPERAND (*expr_p, 1); 796 797 if (!error_operand_p (op0) 798 && !error_operand_p (op1) 799 && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0)) 800 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1))) 801 && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0))) 802 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR, 803 TREE_TYPE (op0), op1); 804 805 else if (simple_empty_class_p (TREE_TYPE (op0), op1, code)) 806 { 807 while (TREE_CODE (op1) == TARGET_EXPR) 808 /* We're disconnecting the initializer from its target, 809 don't create a temporary. */ 810 op1 = TARGET_EXPR_INITIAL (op1); 811 812 /* Remove any copies of empty classes. Also drop volatile 813 variables on the RHS to avoid infinite recursion from 814 gimplify_expr trying to load the value. */ 815 if (TREE_SIDE_EFFECTS (op1)) 816 { 817 if (TREE_THIS_VOLATILE (op1) 818 && (REFERENCE_CLASS_P (op1) || DECL_P (op1))) 819 op1 = build_fold_addr_expr (op1); 820 821 gimplify_and_add (op1, pre_p); 822 } 823 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 824 is_gimple_lvalue, fb_lvalue); 825 *expr_p = TREE_OPERAND (*expr_p, 0); 826 if (code == RETURN_EXPR && REFERENCE_CLASS_P (*expr_p)) 827 /* Avoid 'return *<retval>;' */ 828 *expr_p = TREE_OPERAND (*expr_p, 0); 829 } 830 /* P0145 says that the RHS is sequenced before the LHS. 831 gimplify_modify_expr gimplifies the RHS before the LHS, but that 832 isn't quite strong enough in two cases: 833 834 1) gimplify.c wants to leave a CALL_EXPR on the RHS, which would 835 mean it's evaluated after the LHS. 836 837 2) the value calculation of the RHS is also sequenced before the 838 LHS, so for scalar assignment we need to preevaluate if the 839 RHS could be affected by LHS side-effects even if it has no 840 side-effects of its own. We don't need this for classes because 841 class assignment takes its RHS by reference. */ 842 else if (flag_strong_eval_order > 1 843 && TREE_CODE (*expr_p) == MODIFY_EXPR 844 && lvalue_has_side_effects (op0) 845 && (TREE_CODE (op1) == CALL_EXPR 846 || (SCALAR_TYPE_P (TREE_TYPE (op1)) 847 && !TREE_CONSTANT (op1)))) 848 TREE_OPERAND (*expr_p, 1) = get_initialized_tmp_var (op1, pre_p); 849 } 850 ret = GS_OK; 851 break; 852 853 case EMPTY_CLASS_EXPR: 854 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */ 855 *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL); 856 ret = GS_OK; 857 break; 858 859 case BASELINK: 860 *expr_p = BASELINK_FUNCTIONS (*expr_p); 861 ret = GS_OK; 862 break; 863 864 case TRY_BLOCK: 865 genericize_try_block (expr_p); 866 ret = GS_OK; 867 break; 868 869 case HANDLER: 870 genericize_catch_block (expr_p); 871 ret = GS_OK; 872 break; 873 874 case EH_SPEC_BLOCK: 875 genericize_eh_spec_block (expr_p); 876 ret = GS_OK; 877 break; 878 879 case USING_STMT: 880 gcc_unreachable (); 881 882 case FOR_STMT: 883 case WHILE_STMT: 884 case DO_STMT: 885 case SWITCH_STMT: 886 case CONTINUE_STMT: 887 case BREAK_STMT: 888 gcc_unreachable (); 889 890 case OMP_FOR: 891 case OMP_SIMD: 892 case OMP_DISTRIBUTE: 893 case OMP_LOOP: 894 case OMP_TASKLOOP: 895 ret = cp_gimplify_omp_for (expr_p, pre_p); 896 break; 897 898 case EXPR_STMT: 899 gimplify_expr_stmt (expr_p); 900 ret = GS_OK; 901 break; 902 903 case UNARY_PLUS_EXPR: 904 { 905 tree arg = TREE_OPERAND (*expr_p, 0); 906 tree type = TREE_TYPE (*expr_p); 907 *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg) 908 : arg; 909 ret = GS_OK; 910 } 911 break; 912 913 case CALL_EXPR: 914 ret = GS_OK; 915 if (flag_strong_eval_order == 2 916 && CALL_EXPR_FN (*expr_p) 917 && cp_get_callee_fndecl_nofold (*expr_p) == NULL_TREE) 918 { 919 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p)); 920 enum gimplify_status t 921 = gimplify_to_rvalue (&CALL_EXPR_FN (*expr_p), pre_p, NULL, 922 is_gimple_call_addr); 923 if (t == GS_ERROR) 924 ret = GS_ERROR; 925 /* GIMPLE considers most pointer conversion useless, but for 926 calls we actually care about the exact function pointer type. */ 927 else if (TREE_TYPE (CALL_EXPR_FN (*expr_p)) != fnptrtype) 928 CALL_EXPR_FN (*expr_p) 929 = build1 (NOP_EXPR, fnptrtype, CALL_EXPR_FN (*expr_p)); 930 } 931 if (!CALL_EXPR_FN (*expr_p)) 932 /* Internal function call. */; 933 else if (CALL_EXPR_REVERSE_ARGS (*expr_p)) 934 { 935 /* This is a call to a (compound) assignment operator that used 936 the operator syntax; gimplify the RHS first. */ 937 gcc_assert (call_expr_nargs (*expr_p) == 2); 938 gcc_assert (!CALL_EXPR_ORDERED_ARGS (*expr_p)); 939 enum gimplify_status t 940 = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 1), pre_p, loc, 941 TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, 0))); 942 if (t == GS_ERROR) 943 ret = GS_ERROR; 944 } 945 else if (CALL_EXPR_ORDERED_ARGS (*expr_p)) 946 { 947 /* Leave the last argument for gimplify_call_expr, to avoid problems 948 with __builtin_va_arg_pack(). */ 949 int nargs = call_expr_nargs (*expr_p) - 1; 950 int last_side_effects_arg = -1; 951 for (int i = nargs; i > 0; --i) 952 if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i))) 953 { 954 last_side_effects_arg = i; 955 break; 956 } 957 for (int i = 0; i < nargs; ++i) 958 { 959 enum gimplify_status t 960 = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc, 961 i < last_side_effects_arg); 962 if (t == GS_ERROR) 963 ret = GS_ERROR; 964 } 965 } 966 else if (flag_strong_eval_order 967 && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p)) 968 { 969 /* If flag_strong_eval_order, evaluate the object argument first. */ 970 tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p)); 971 if (INDIRECT_TYPE_P (fntype)) 972 fntype = TREE_TYPE (fntype); 973 if (TREE_CODE (fntype) == METHOD_TYPE) 974 { 975 int nargs = call_expr_nargs (*expr_p); 976 bool side_effects = false; 977 for (int i = 1; i < nargs; ++i) 978 if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i))) 979 { 980 side_effects = true; 981 break; 982 } 983 enum gimplify_status t 984 = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 0), pre_p, loc, 985 side_effects); 986 if (t == GS_ERROR) 987 ret = GS_ERROR; 988 } 989 } 990 if (ret != GS_ERROR) 991 { 992 tree decl = cp_get_callee_fndecl_nofold (*expr_p); 993 if (decl 994 && fndecl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, 995 BUILT_IN_FRONTEND)) 996 *expr_p = boolean_false_node; 997 else if (decl 998 && fndecl_built_in_p (decl, CP_BUILT_IN_SOURCE_LOCATION, 999 BUILT_IN_FRONTEND)) 1000 *expr_p = fold_builtin_source_location (EXPR_LOCATION (*expr_p)); 1001 } 1002 break; 1003 1004 case TARGET_EXPR: 1005 /* A TARGET_EXPR that expresses direct-initialization should have been 1006 elided by cp_gimplify_init_expr. */ 1007 gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (*expr_p)); 1008 ret = GS_UNHANDLED; 1009 break; 1010 1011 case PTRMEM_CST: 1012 *expr_p = cplus_expand_constant (*expr_p); 1013 if (TREE_CODE (*expr_p) == PTRMEM_CST) 1014 ret = GS_ERROR; 1015 else 1016 ret = GS_OK; 1017 break; 1018 1019 case RETURN_EXPR: 1020 if (TREE_OPERAND (*expr_p, 0) 1021 && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR 1022 || TREE_CODE (TREE_OPERAND (*expr_p, 0)) == MODIFY_EXPR)) 1023 { 1024 expr_p = &TREE_OPERAND (*expr_p, 0); 1025 /* Avoid going through the INIT_EXPR case, which can 1026 degrade INIT_EXPRs into AGGR_INIT_EXPRs. */ 1027 goto modify_expr_case; 1028 } 1029 /* Fall through. */ 1030 1031 default: 1032 ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p); 1033 break; 1034 } 1035 1036 /* Restore saved state. */ 1037 if (STATEMENT_CODE_P (code)) 1038 current_stmt_tree ()->stmts_are_full_exprs_p 1039 = saved_stmts_are_full_exprs_p; 1040 1041 return ret; 1042} 1043 1044static inline bool 1045is_invisiref_parm (const_tree t) 1046{ 1047 return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL) 1048 && DECL_BY_REFERENCE (t)); 1049} 1050 1051/* Return true if the uid in both int tree maps are equal. */ 1052 1053bool 1054cxx_int_tree_map_hasher::equal (cxx_int_tree_map *a, cxx_int_tree_map *b) 1055{ 1056 return (a->uid == b->uid); 1057} 1058 1059/* Hash a UID in a cxx_int_tree_map. */ 1060 1061unsigned int 1062cxx_int_tree_map_hasher::hash (cxx_int_tree_map *item) 1063{ 1064 return item->uid; 1065} 1066 1067/* A stable comparison routine for use with splay trees and DECLs. */ 1068 1069static int 1070splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb) 1071{ 1072 tree a = (tree) xa; 1073 tree b = (tree) xb; 1074 1075 return DECL_UID (a) - DECL_UID (b); 1076} 1077 1078/* OpenMP context during genericization. */ 1079 1080struct cp_genericize_omp_taskreg 1081{ 1082 bool is_parallel; 1083 bool default_shared; 1084 struct cp_genericize_omp_taskreg *outer; 1085 splay_tree variables; 1086}; 1087 1088/* Return true if genericization should try to determine if 1089 DECL is firstprivate or shared within task regions. */ 1090 1091static bool 1092omp_var_to_track (tree decl) 1093{ 1094 tree type = TREE_TYPE (decl); 1095 if (is_invisiref_parm (decl)) 1096 type = TREE_TYPE (type); 1097 else if (TYPE_REF_P (type)) 1098 type = TREE_TYPE (type); 1099 while (TREE_CODE (type) == ARRAY_TYPE) 1100 type = TREE_TYPE (type); 1101 if (type == error_mark_node || !CLASS_TYPE_P (type)) 1102 return false; 1103 if (VAR_P (decl) && CP_DECL_THREAD_LOCAL_P (decl)) 1104 return false; 1105 if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED) 1106 return false; 1107 return true; 1108} 1109 1110/* Note DECL use in OpenMP region OMP_CTX during genericization. */ 1111 1112static void 1113omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl) 1114{ 1115 splay_tree_node n = splay_tree_lookup (omp_ctx->variables, 1116 (splay_tree_key) decl); 1117 if (n == NULL) 1118 { 1119 int flags = OMP_CLAUSE_DEFAULT_SHARED; 1120 if (omp_ctx->outer) 1121 omp_cxx_notice_variable (omp_ctx->outer, decl); 1122 if (!omp_ctx->default_shared) 1123 { 1124 struct cp_genericize_omp_taskreg *octx; 1125 1126 for (octx = omp_ctx->outer; octx; octx = octx->outer) 1127 { 1128 n = splay_tree_lookup (octx->variables, (splay_tree_key) decl); 1129 if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED) 1130 { 1131 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE; 1132 break; 1133 } 1134 if (octx->is_parallel) 1135 break; 1136 } 1137 if (octx == NULL 1138 && (TREE_CODE (decl) == PARM_DECL 1139 || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl)) 1140 && DECL_CONTEXT (decl) == current_function_decl))) 1141 flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE; 1142 if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE) 1143 { 1144 /* DECL is implicitly determined firstprivate in 1145 the current task construct. Ensure copy ctor and 1146 dtor are instantiated, because during gimplification 1147 it will be already too late. */ 1148 tree type = TREE_TYPE (decl); 1149 if (is_invisiref_parm (decl)) 1150 type = TREE_TYPE (type); 1151 else if (TYPE_REF_P (type)) 1152 type = TREE_TYPE (type); 1153 while (TREE_CODE (type) == ARRAY_TYPE) 1154 type = TREE_TYPE (type); 1155 get_copy_ctor (type, tf_none); 1156 get_dtor (type, tf_none); 1157 } 1158 } 1159 splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags); 1160 } 1161} 1162 1163/* Genericization context. */ 1164 1165struct cp_genericize_data 1166{ 1167 hash_set<tree> *p_set; 1168 vec<tree> bind_expr_stack; 1169 struct cp_genericize_omp_taskreg *omp_ctx; 1170 tree try_block; 1171 bool no_sanitize_p; 1172 bool handle_invisiref_parm_p; 1173}; 1174 1175/* Perform any pre-gimplification folding of C++ front end trees to 1176 GENERIC. 1177 Note: The folding of none-omp cases is something to move into 1178 the middle-end. As for now we have most foldings only on GENERIC 1179 in fold-const, we need to perform this before transformation to 1180 GIMPLE-form. */ 1181 1182static tree 1183cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) 1184{ 1185 cp_fold_data *data = (cp_fold_data*)data_; 1186 tree stmt = *stmt_p; 1187 enum tree_code code = TREE_CODE (stmt); 1188 1189 switch (code) 1190 { 1191 case VAR_DECL: 1192 /* In initializers replace anon union artificial VAR_DECLs 1193 with their DECL_VALUE_EXPRs, as nothing will do it later. 1194 Ditto for structured bindings. */ 1195 if (!data->genericize 1196 && DECL_HAS_VALUE_EXPR_P (stmt) 1197 && (DECL_ANON_UNION_VAR_P (stmt) 1198 || (DECL_DECOMPOSITION_P (stmt) && DECL_DECOMP_BASE (stmt)))) 1199 { 1200 *stmt_p = stmt = unshare_expr (DECL_VALUE_EXPR (stmt)); 1201 break; 1202 } 1203 break; 1204 1205 default: 1206 break; 1207 } 1208 1209 *stmt_p = stmt = cp_fold (*stmt_p); 1210 1211 if (data->pset.add (stmt)) 1212 { 1213 /* Don't walk subtrees of stmts we've already walked once, otherwise 1214 we can have exponential complexity with e.g. lots of nested 1215 SAVE_EXPRs or TARGET_EXPRs. cp_fold uses a cache and will return 1216 always the same tree, which the first time cp_fold_r has been 1217 called on it had the subtrees walked. */ 1218 *walk_subtrees = 0; 1219 return NULL; 1220 } 1221 1222 code = TREE_CODE (stmt); 1223 if (code == OMP_FOR || code == OMP_SIMD || code == OMP_DISTRIBUTE 1224 || code == OMP_LOOP || code == OMP_TASKLOOP || code == OACC_LOOP) 1225 { 1226 tree x; 1227 int i, n; 1228 1229 cp_walk_tree (&OMP_FOR_BODY (stmt), cp_fold_r, data, NULL); 1230 cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_fold_r, data, NULL); 1231 cp_walk_tree (&OMP_FOR_INIT (stmt), cp_fold_r, data, NULL); 1232 x = OMP_FOR_COND (stmt); 1233 if (x && TREE_CODE_CLASS (TREE_CODE (x)) == tcc_comparison) 1234 { 1235 cp_walk_tree (&TREE_OPERAND (x, 0), cp_fold_r, data, NULL); 1236 cp_walk_tree (&TREE_OPERAND (x, 1), cp_fold_r, data, NULL); 1237 } 1238 else if (x && TREE_CODE (x) == TREE_VEC) 1239 { 1240 n = TREE_VEC_LENGTH (x); 1241 for (i = 0; i < n; i++) 1242 { 1243 tree o = TREE_VEC_ELT (x, i); 1244 if (o && TREE_CODE_CLASS (TREE_CODE (o)) == tcc_comparison) 1245 cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL); 1246 } 1247 } 1248 x = OMP_FOR_INCR (stmt); 1249 if (x && TREE_CODE (x) == TREE_VEC) 1250 { 1251 n = TREE_VEC_LENGTH (x); 1252 for (i = 0; i < n; i++) 1253 { 1254 tree o = TREE_VEC_ELT (x, i); 1255 if (o && TREE_CODE (o) == MODIFY_EXPR) 1256 o = TREE_OPERAND (o, 1); 1257 if (o && (TREE_CODE (o) == PLUS_EXPR || TREE_CODE (o) == MINUS_EXPR 1258 || TREE_CODE (o) == POINTER_PLUS_EXPR)) 1259 { 1260 cp_walk_tree (&TREE_OPERAND (o, 0), cp_fold_r, data, NULL); 1261 cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL); 1262 } 1263 } 1264 } 1265 cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_fold_r, data, NULL); 1266 *walk_subtrees = 0; 1267 } 1268 1269 return NULL; 1270} 1271 1272/* Fold ALL the trees! FIXME we should be able to remove this, but 1273 apparently that still causes optimization regressions. */ 1274 1275void 1276cp_fold_function (tree fndecl) 1277{ 1278 cp_fold_data data (/*genericize*/true); 1279 cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL); 1280} 1281 1282/* Turn SPACESHIP_EXPR EXPR into GENERIC. */ 1283 1284static tree genericize_spaceship (tree expr) 1285{ 1286 iloc_sentinel s (cp_expr_location (expr)); 1287 tree type = TREE_TYPE (expr); 1288 tree op0 = TREE_OPERAND (expr, 0); 1289 tree op1 = TREE_OPERAND (expr, 1); 1290 return genericize_spaceship (type, op0, op1); 1291} 1292 1293/* If EXPR involves an anonymous VLA type, prepend a DECL_EXPR for that type 1294 to trigger gimplify_type_sizes; otherwise a cast to pointer-to-VLA confuses 1295 the middle-end (c++/88256). */ 1296 1297static tree 1298predeclare_vla (tree expr) 1299{ 1300 tree type = TREE_TYPE (expr); 1301 if (type == error_mark_node) 1302 return expr; 1303 1304 /* We need to strip pointers for gimplify_type_sizes. */ 1305 tree vla = type; 1306 while (POINTER_TYPE_P (vla)) 1307 { 1308 if (TYPE_NAME (vla)) 1309 return expr; 1310 vla = TREE_TYPE (vla); 1311 } 1312 if (TYPE_NAME (vla) || !variably_modified_type_p (vla, NULL_TREE)) 1313 return expr; 1314 1315 tree decl = build_decl (input_location, TYPE_DECL, NULL_TREE, vla); 1316 DECL_ARTIFICIAL (decl) = 1; 1317 TYPE_NAME (vla) = decl; 1318 tree dexp = build_stmt (input_location, DECL_EXPR, decl); 1319 expr = build2 (COMPOUND_EXPR, type, dexp, expr); 1320 return expr; 1321} 1322 1323/* Perform any pre-gimplification lowering of C++ front end trees to 1324 GENERIC. */ 1325 1326static tree 1327cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) 1328{ 1329 tree stmt = *stmt_p; 1330 struct cp_genericize_data *wtd = (struct cp_genericize_data *) data; 1331 hash_set<tree> *p_set = wtd->p_set; 1332 1333 /* If in an OpenMP context, note var uses. */ 1334 if (__builtin_expect (wtd->omp_ctx != NULL, 0) 1335 && (VAR_P (stmt) 1336 || TREE_CODE (stmt) == PARM_DECL 1337 || TREE_CODE (stmt) == RESULT_DECL) 1338 && omp_var_to_track (stmt)) 1339 omp_cxx_notice_variable (wtd->omp_ctx, stmt); 1340 1341 /* Don't dereference parms in a thunk, pass the references through. */ 1342 if ((TREE_CODE (stmt) == CALL_EXPR && CALL_FROM_THUNK_P (stmt)) 1343 || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt))) 1344 { 1345 *walk_subtrees = 0; 1346 return NULL; 1347 } 1348 1349 /* Dereference invisible reference parms. */ 1350 if (wtd->handle_invisiref_parm_p && is_invisiref_parm (stmt)) 1351 { 1352 *stmt_p = convert_from_reference (stmt); 1353 p_set->add (*stmt_p); 1354 *walk_subtrees = 0; 1355 return NULL; 1356 } 1357 1358 /* Map block scope extern declarations to visible declarations with the 1359 same name and type in outer scopes if any. */ 1360 if (cp_function_chain->extern_decl_map 1361 && VAR_OR_FUNCTION_DECL_P (stmt) 1362 && DECL_EXTERNAL (stmt)) 1363 { 1364 struct cxx_int_tree_map *h, in; 1365 in.uid = DECL_UID (stmt); 1366 h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid); 1367 if (h) 1368 { 1369 *stmt_p = h->to; 1370 TREE_USED (h->to) |= TREE_USED (stmt); 1371 *walk_subtrees = 0; 1372 return NULL; 1373 } 1374 } 1375 1376 if (TREE_CODE (stmt) == INTEGER_CST 1377 && TYPE_REF_P (TREE_TYPE (stmt)) 1378 && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) 1379 && !wtd->no_sanitize_p) 1380 { 1381 ubsan_maybe_instrument_reference (stmt_p); 1382 if (*stmt_p != stmt) 1383 { 1384 *walk_subtrees = 0; 1385 return NULL_TREE; 1386 } 1387 } 1388 1389 /* Other than invisiref parms, don't walk the same tree twice. */ 1390 if (p_set->contains (stmt)) 1391 { 1392 *walk_subtrees = 0; 1393 return NULL_TREE; 1394 } 1395 1396 switch (TREE_CODE (stmt)) 1397 { 1398 case ADDR_EXPR: 1399 if (is_invisiref_parm (TREE_OPERAND (stmt, 0))) 1400 { 1401 /* If in an OpenMP context, note var uses. */ 1402 if (__builtin_expect (wtd->omp_ctx != NULL, 0) 1403 && omp_var_to_track (TREE_OPERAND (stmt, 0))) 1404 omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0)); 1405 *stmt_p = fold_convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0)); 1406 *walk_subtrees = 0; 1407 } 1408 break; 1409 1410 case RETURN_EXPR: 1411 if (TREE_OPERAND (stmt, 0) && is_invisiref_parm (TREE_OPERAND (stmt, 0))) 1412 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */ 1413 *walk_subtrees = 0; 1414 break; 1415 1416 case OMP_CLAUSE: 1417 switch (OMP_CLAUSE_CODE (stmt)) 1418 { 1419 case OMP_CLAUSE_LASTPRIVATE: 1420 /* Don't dereference an invisiref in OpenMP clauses. */ 1421 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 1422 { 1423 *walk_subtrees = 0; 1424 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt)) 1425 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt), 1426 cp_genericize_r, data, NULL); 1427 } 1428 break; 1429 case OMP_CLAUSE_PRIVATE: 1430 /* Don't dereference an invisiref in OpenMP clauses. */ 1431 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 1432 *walk_subtrees = 0; 1433 else if (wtd->omp_ctx != NULL) 1434 { 1435 /* Private clause doesn't cause any references to the 1436 var in outer contexts, avoid calling 1437 omp_cxx_notice_variable for it. */ 1438 struct cp_genericize_omp_taskreg *old = wtd->omp_ctx; 1439 wtd->omp_ctx = NULL; 1440 cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r, 1441 data, NULL); 1442 wtd->omp_ctx = old; 1443 *walk_subtrees = 0; 1444 } 1445 break; 1446 case OMP_CLAUSE_SHARED: 1447 case OMP_CLAUSE_FIRSTPRIVATE: 1448 case OMP_CLAUSE_COPYIN: 1449 case OMP_CLAUSE_COPYPRIVATE: 1450 case OMP_CLAUSE_INCLUSIVE: 1451 case OMP_CLAUSE_EXCLUSIVE: 1452 /* Don't dereference an invisiref in OpenMP clauses. */ 1453 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 1454 *walk_subtrees = 0; 1455 break; 1456 case OMP_CLAUSE_REDUCTION: 1457 case OMP_CLAUSE_IN_REDUCTION: 1458 case OMP_CLAUSE_TASK_REDUCTION: 1459 /* Don't dereference an invisiref in reduction clause's 1460 OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE} 1461 still needs to be genericized. */ 1462 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt))) 1463 { 1464 *walk_subtrees = 0; 1465 if (OMP_CLAUSE_REDUCTION_INIT (stmt)) 1466 cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt), 1467 cp_genericize_r, data, NULL); 1468 if (OMP_CLAUSE_REDUCTION_MERGE (stmt)) 1469 cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt), 1470 cp_genericize_r, data, NULL); 1471 } 1472 break; 1473 default: 1474 break; 1475 } 1476 break; 1477 1478 /* Due to the way voidify_wrapper_expr is written, we don't get a chance 1479 to lower this construct before scanning it, so we need to lower these 1480 before doing anything else. */ 1481 case CLEANUP_STMT: 1482 *stmt_p = build2_loc (EXPR_LOCATION (stmt), 1483 CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR 1484 : TRY_FINALLY_EXPR, 1485 void_type_node, 1486 CLEANUP_BODY (stmt), 1487 CLEANUP_EXPR (stmt)); 1488 break; 1489 1490 case IF_STMT: 1491 genericize_if_stmt (stmt_p); 1492 /* *stmt_p has changed, tail recurse to handle it again. */ 1493 return cp_genericize_r (stmt_p, walk_subtrees, data); 1494 1495 /* COND_EXPR might have incompatible types in branches if one or both 1496 arms are bitfields. Fix it up now. */ 1497 case COND_EXPR: 1498 { 1499 tree type_left 1500 = (TREE_OPERAND (stmt, 1) 1501 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1)) 1502 : NULL_TREE); 1503 tree type_right 1504 = (TREE_OPERAND (stmt, 2) 1505 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2)) 1506 : NULL_TREE); 1507 if (type_left 1508 && !useless_type_conversion_p (TREE_TYPE (stmt), 1509 TREE_TYPE (TREE_OPERAND (stmt, 1)))) 1510 { 1511 TREE_OPERAND (stmt, 1) 1512 = fold_convert (type_left, TREE_OPERAND (stmt, 1)); 1513 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt), 1514 type_left)); 1515 } 1516 if (type_right 1517 && !useless_type_conversion_p (TREE_TYPE (stmt), 1518 TREE_TYPE (TREE_OPERAND (stmt, 2)))) 1519 { 1520 TREE_OPERAND (stmt, 2) 1521 = fold_convert (type_right, TREE_OPERAND (stmt, 2)); 1522 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt), 1523 type_right)); 1524 } 1525 } 1526 break; 1527 1528 case BIND_EXPR: 1529 if (__builtin_expect (wtd->omp_ctx != NULL, 0)) 1530 { 1531 tree decl; 1532 for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl)) 1533 if (VAR_P (decl) 1534 && !DECL_EXTERNAL (decl) 1535 && omp_var_to_track (decl)) 1536 { 1537 splay_tree_node n 1538 = splay_tree_lookup (wtd->omp_ctx->variables, 1539 (splay_tree_key) decl); 1540 if (n == NULL) 1541 splay_tree_insert (wtd->omp_ctx->variables, 1542 (splay_tree_key) decl, 1543 TREE_STATIC (decl) 1544 ? OMP_CLAUSE_DEFAULT_SHARED 1545 : OMP_CLAUSE_DEFAULT_PRIVATE); 1546 } 1547 } 1548 if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR)) 1549 { 1550 /* The point here is to not sanitize static initializers. */ 1551 bool no_sanitize_p = wtd->no_sanitize_p; 1552 wtd->no_sanitize_p = true; 1553 for (tree decl = BIND_EXPR_VARS (stmt); 1554 decl; 1555 decl = DECL_CHAIN (decl)) 1556 if (VAR_P (decl) 1557 && TREE_STATIC (decl) 1558 && DECL_INITIAL (decl)) 1559 cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL); 1560 wtd->no_sanitize_p = no_sanitize_p; 1561 } 1562 wtd->bind_expr_stack.safe_push (stmt); 1563 cp_walk_tree (&BIND_EXPR_BODY (stmt), 1564 cp_genericize_r, data, NULL); 1565 wtd->bind_expr_stack.pop (); 1566 break; 1567 1568 case USING_STMT: 1569 { 1570 tree block = NULL_TREE; 1571 1572 /* Get the innermost inclosing GIMPLE_BIND that has a non NULL 1573 BLOCK, and append an IMPORTED_DECL to its 1574 BLOCK_VARS chained list. */ 1575 if (wtd->bind_expr_stack.exists ()) 1576 { 1577 int i; 1578 for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--) 1579 if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i]))) 1580 break; 1581 } 1582 if (block) 1583 { 1584 tree decl = TREE_OPERAND (stmt, 0); 1585 gcc_assert (decl); 1586 1587 if (undeduced_auto_decl (decl)) 1588 /* Omit from the GENERIC, the back-end can't handle it. */; 1589 else 1590 { 1591 tree using_directive = make_node (IMPORTED_DECL); 1592 TREE_TYPE (using_directive) = void_type_node; 1593 DECL_SOURCE_LOCATION (using_directive) 1594 = cp_expr_loc_or_input_loc (stmt); 1595 1596 IMPORTED_DECL_ASSOCIATED_DECL (using_directive) = decl; 1597 DECL_CHAIN (using_directive) = BLOCK_VARS (block); 1598 BLOCK_VARS (block) = using_directive; 1599 } 1600 } 1601 /* The USING_STMT won't appear in GENERIC. */ 1602 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node); 1603 *walk_subtrees = 0; 1604 } 1605 break; 1606 1607 case DECL_EXPR: 1608 if (TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL) 1609 { 1610 /* Using decls inside DECL_EXPRs are just dropped on the floor. */ 1611 *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node); 1612 *walk_subtrees = 0; 1613 } 1614 else 1615 { 1616 tree d = DECL_EXPR_DECL (stmt); 1617 if (VAR_P (d)) 1618 gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d)); 1619 } 1620 break; 1621 1622 case OMP_PARALLEL: 1623 case OMP_TASK: 1624 case OMP_TASKLOOP: 1625 { 1626 struct cp_genericize_omp_taskreg omp_ctx; 1627 tree c, decl; 1628 splay_tree_node n; 1629 1630 *walk_subtrees = 0; 1631 cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL); 1632 omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL; 1633 omp_ctx.default_shared = omp_ctx.is_parallel; 1634 omp_ctx.outer = wtd->omp_ctx; 1635 omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0); 1636 wtd->omp_ctx = &omp_ctx; 1637 for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c)) 1638 switch (OMP_CLAUSE_CODE (c)) 1639 { 1640 case OMP_CLAUSE_SHARED: 1641 case OMP_CLAUSE_PRIVATE: 1642 case OMP_CLAUSE_FIRSTPRIVATE: 1643 case OMP_CLAUSE_LASTPRIVATE: 1644 decl = OMP_CLAUSE_DECL (c); 1645 if (decl == error_mark_node || !omp_var_to_track (decl)) 1646 break; 1647 n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl); 1648 if (n != NULL) 1649 break; 1650 splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl, 1651 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED 1652 ? OMP_CLAUSE_DEFAULT_SHARED 1653 : OMP_CLAUSE_DEFAULT_PRIVATE); 1654 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE && omp_ctx.outer) 1655 omp_cxx_notice_variable (omp_ctx.outer, decl); 1656 break; 1657 case OMP_CLAUSE_DEFAULT: 1658 if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED) 1659 omp_ctx.default_shared = true; 1660 default: 1661 break; 1662 } 1663 if (TREE_CODE (stmt) == OMP_TASKLOOP) 1664 genericize_omp_for_stmt (stmt_p, walk_subtrees, data); 1665 else 1666 cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL); 1667 wtd->omp_ctx = omp_ctx.outer; 1668 splay_tree_delete (omp_ctx.variables); 1669 } 1670 break; 1671 1672 case TRY_BLOCK: 1673 { 1674 *walk_subtrees = 0; 1675 tree try_block = wtd->try_block; 1676 wtd->try_block = stmt; 1677 cp_walk_tree (&TRY_STMTS (stmt), cp_genericize_r, data, NULL); 1678 wtd->try_block = try_block; 1679 cp_walk_tree (&TRY_HANDLERS (stmt), cp_genericize_r, data, NULL); 1680 } 1681 break; 1682 1683 case MUST_NOT_THROW_EXPR: 1684 /* MUST_NOT_THROW_COND might be something else with TM. */ 1685 if (MUST_NOT_THROW_COND (stmt) == NULL_TREE) 1686 { 1687 *walk_subtrees = 0; 1688 tree try_block = wtd->try_block; 1689 wtd->try_block = stmt; 1690 cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL); 1691 wtd->try_block = try_block; 1692 } 1693 break; 1694 1695 case THROW_EXPR: 1696 { 1697 location_t loc = location_of (stmt); 1698 if (TREE_NO_WARNING (stmt)) 1699 /* Never mind. */; 1700 else if (wtd->try_block) 1701 { 1702 if (TREE_CODE (wtd->try_block) == MUST_NOT_THROW_EXPR) 1703 { 1704 auto_diagnostic_group d; 1705 if (warning_at (loc, OPT_Wterminate, 1706 "%<throw%> will always call %<terminate%>") 1707 && cxx_dialect >= cxx11 1708 && DECL_DESTRUCTOR_P (current_function_decl)) 1709 inform (loc, "in C++11 destructors default to %<noexcept%>"); 1710 } 1711 } 1712 else 1713 { 1714 if (warn_cxx11_compat && cxx_dialect < cxx11 1715 && DECL_DESTRUCTOR_P (current_function_decl) 1716 && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)) 1717 == NULL_TREE) 1718 && (get_defaulted_eh_spec (current_function_decl) 1719 == empty_except_spec)) 1720 warning_at (loc, OPT_Wc__11_compat, 1721 "in C++11 this %<throw%> will call %<terminate%> " 1722 "because destructors default to %<noexcept%>"); 1723 } 1724 } 1725 break; 1726 1727 case CONVERT_EXPR: 1728 gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt)); 1729 break; 1730 1731 case FOR_STMT: 1732 genericize_for_stmt (stmt_p, walk_subtrees, data); 1733 break; 1734 1735 case WHILE_STMT: 1736 genericize_while_stmt (stmt_p, walk_subtrees, data); 1737 break; 1738 1739 case DO_STMT: 1740 genericize_do_stmt (stmt_p, walk_subtrees, data); 1741 break; 1742 1743 case SWITCH_STMT: 1744 genericize_switch_stmt (stmt_p, walk_subtrees, data); 1745 break; 1746 1747 case CONTINUE_STMT: 1748 genericize_continue_stmt (stmt_p); 1749 break; 1750 1751 case BREAK_STMT: 1752 genericize_break_stmt (stmt_p); 1753 break; 1754 1755 case SPACESHIP_EXPR: 1756 *stmt_p = genericize_spaceship (*stmt_p); 1757 break; 1758 1759 case OMP_DISTRIBUTE: 1760 /* Need to explicitly instantiate copy ctors on class iterators of 1761 composite distribute parallel for. */ 1762 if (OMP_FOR_INIT (*stmt_p) == NULL_TREE) 1763 { 1764 tree *data[4] = { NULL, NULL, NULL, NULL }; 1765 tree inner = walk_tree (&OMP_FOR_BODY (*stmt_p), 1766 find_combined_omp_for, data, NULL); 1767 if (inner != NULL_TREE 1768 && TREE_CODE (inner) == OMP_FOR) 1769 { 1770 for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner)); i++) 1771 if (OMP_FOR_ORIG_DECLS (inner) 1772 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), 1773 i)) == TREE_LIST 1774 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), 1775 i))) 1776 { 1777 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), i); 1778 /* Class iterators aren't allowed on OMP_SIMD, so the only 1779 case we need to solve is distribute parallel for. */ 1780 gcc_assert (TREE_CODE (inner) == OMP_FOR 1781 && data[1]); 1782 tree orig_decl = TREE_PURPOSE (orig); 1783 tree c, cl = NULL_TREE; 1784 for (c = OMP_FOR_CLAUSES (inner); 1785 c; c = OMP_CLAUSE_CHAIN (c)) 1786 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE 1787 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE) 1788 && OMP_CLAUSE_DECL (c) == orig_decl) 1789 { 1790 cl = c; 1791 break; 1792 } 1793 if (cl == NULL_TREE) 1794 { 1795 for (c = OMP_PARALLEL_CLAUSES (*data[1]); 1796 c; c = OMP_CLAUSE_CHAIN (c)) 1797 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE 1798 && OMP_CLAUSE_DECL (c) == orig_decl) 1799 { 1800 cl = c; 1801 break; 1802 } 1803 } 1804 if (cl) 1805 { 1806 orig_decl = require_complete_type (orig_decl); 1807 tree inner_type = TREE_TYPE (orig_decl); 1808 if (orig_decl == error_mark_node) 1809 continue; 1810 if (TYPE_REF_P (TREE_TYPE (orig_decl))) 1811 inner_type = TREE_TYPE (inner_type); 1812 1813 while (TREE_CODE (inner_type) == ARRAY_TYPE) 1814 inner_type = TREE_TYPE (inner_type); 1815 get_copy_ctor (inner_type, tf_warning_or_error); 1816 } 1817 } 1818 } 1819 } 1820 /* FALLTHRU */ 1821 case OMP_FOR: 1822 case OMP_SIMD: 1823 case OMP_LOOP: 1824 case OACC_LOOP: 1825 genericize_omp_for_stmt (stmt_p, walk_subtrees, data); 1826 break; 1827 1828 case PTRMEM_CST: 1829 /* By the time we get here we're handing off to the back end, so we don't 1830 need or want to preserve PTRMEM_CST anymore. */ 1831 *stmt_p = cplus_expand_constant (stmt); 1832 *walk_subtrees = 0; 1833 break; 1834 1835 case MEM_REF: 1836 /* For MEM_REF, make sure not to sanitize the second operand even 1837 if it has reference type. It is just an offset with a type 1838 holding other information. There is no other processing we 1839 need to do for INTEGER_CSTs, so just ignore the second argument 1840 unconditionally. */ 1841 cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL); 1842 *walk_subtrees = 0; 1843 break; 1844 1845 case NOP_EXPR: 1846 *stmt_p = predeclare_vla (*stmt_p); 1847 if (!wtd->no_sanitize_p 1848 && sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT) 1849 && TYPE_REF_P (TREE_TYPE (stmt))) 1850 ubsan_maybe_instrument_reference (stmt_p); 1851 break; 1852 1853 case CALL_EXPR: 1854 /* Evaluate function concept checks instead of treating them as 1855 normal functions. */ 1856 if (concept_check_p (stmt)) 1857 { 1858 *stmt_p = evaluate_concept_check (stmt, tf_warning_or_error); 1859 * walk_subtrees = 0; 1860 break; 1861 } 1862 1863 if (!wtd->no_sanitize_p 1864 && sanitize_flags_p ((SANITIZE_NULL 1865 | SANITIZE_ALIGNMENT | SANITIZE_VPTR))) 1866 { 1867 tree fn = CALL_EXPR_FN (stmt); 1868 if (fn != NULL_TREE 1869 && !error_operand_p (fn) 1870 && INDIRECT_TYPE_P (TREE_TYPE (fn)) 1871 && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE) 1872 { 1873 bool is_ctor 1874 = TREE_CODE (fn) == ADDR_EXPR 1875 && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL 1876 && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)); 1877 if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT)) 1878 ubsan_maybe_instrument_member_call (stmt, is_ctor); 1879 if (sanitize_flags_p (SANITIZE_VPTR) && !is_ctor) 1880 cp_ubsan_maybe_instrument_member_call (stmt); 1881 } 1882 else if (fn == NULL_TREE 1883 && CALL_EXPR_IFN (stmt) == IFN_UBSAN_NULL 1884 && TREE_CODE (CALL_EXPR_ARG (stmt, 0)) == INTEGER_CST 1885 && TYPE_REF_P (TREE_TYPE (CALL_EXPR_ARG (stmt, 0)))) 1886 *walk_subtrees = 0; 1887 } 1888 /* Fall through. */ 1889 case AGGR_INIT_EXPR: 1890 /* For calls to a multi-versioned function, overload resolution 1891 returns the function with the highest target priority, that is, 1892 the version that will checked for dispatching first. If this 1893 version is inlinable, a direct call to this version can be made 1894 otherwise the call should go through the dispatcher. */ 1895 { 1896 tree fn = cp_get_callee_fndecl_nofold (stmt); 1897 if (fn && DECL_FUNCTION_VERSIONED (fn) 1898 && (current_function_decl == NULL 1899 || !targetm.target_option.can_inline_p (current_function_decl, 1900 fn))) 1901 if (tree dis = get_function_version_dispatcher (fn)) 1902 { 1903 mark_versions_used (dis); 1904 dis = build_address (dis); 1905 if (TREE_CODE (stmt) == CALL_EXPR) 1906 CALL_EXPR_FN (stmt) = dis; 1907 else 1908 AGGR_INIT_EXPR_FN (stmt) = dis; 1909 } 1910 } 1911 break; 1912 1913 case TARGET_EXPR: 1914 if (TARGET_EXPR_INITIAL (stmt) 1915 && TREE_CODE (TARGET_EXPR_INITIAL (stmt)) == CONSTRUCTOR 1916 && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (TARGET_EXPR_INITIAL (stmt))) 1917 TARGET_EXPR_NO_ELIDE (stmt) = 1; 1918 break; 1919 1920 case REQUIRES_EXPR: 1921 /* Emit the value of the requires-expression. */ 1922 *stmt_p = constant_boolean_node (constraints_satisfied_p (stmt), 1923 boolean_type_node); 1924 *walk_subtrees = 0; 1925 break; 1926 1927 case TEMPLATE_ID_EXPR: 1928 gcc_assert (concept_check_p (stmt)); 1929 /* Emit the value of the concept check. */ 1930 *stmt_p = evaluate_concept_check (stmt, tf_warning_or_error); 1931 walk_subtrees = 0; 1932 break; 1933 1934 case STATEMENT_LIST: 1935 if (TREE_SIDE_EFFECTS (stmt)) 1936 { 1937 tree_stmt_iterator i; 1938 int nondebug_stmts = 0; 1939 bool clear_side_effects = true; 1940 /* Genericization can clear TREE_SIDE_EFFECTS, e.g. when 1941 transforming an IF_STMT into COND_EXPR. If such stmt 1942 appears in a STATEMENT_LIST that contains only that 1943 stmt and some DEBUG_BEGIN_STMTs, without -g where the 1944 STATEMENT_LIST wouldn't be present at all the resulting 1945 expression wouldn't have TREE_SIDE_EFFECTS set, so make sure 1946 to clear it even on the STATEMENT_LIST in such cases. */ 1947 for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i)) 1948 { 1949 tree t = tsi_stmt (i); 1950 if (TREE_CODE (t) != DEBUG_BEGIN_STMT && nondebug_stmts < 2) 1951 nondebug_stmts++; 1952 cp_walk_tree (tsi_stmt_ptr (i), cp_genericize_r, data, NULL); 1953 if (TREE_CODE (t) != DEBUG_BEGIN_STMT 1954 && (nondebug_stmts > 1 || TREE_SIDE_EFFECTS (tsi_stmt (i)))) 1955 clear_side_effects = false; 1956 } 1957 if (clear_side_effects) 1958 TREE_SIDE_EFFECTS (stmt) = 0; 1959 *walk_subtrees = 0; 1960 } 1961 break; 1962 1963 default: 1964 if (IS_TYPE_OR_DECL_P (stmt)) 1965 *walk_subtrees = 0; 1966 break; 1967 } 1968 1969 p_set->add (*stmt_p); 1970 1971 return NULL; 1972} 1973 1974/* Lower C++ front end trees to GENERIC in T_P. */ 1975 1976static void 1977cp_genericize_tree (tree* t_p, bool handle_invisiref_parm_p) 1978{ 1979 struct cp_genericize_data wtd; 1980 1981 wtd.p_set = new hash_set<tree>; 1982 wtd.bind_expr_stack.create (0); 1983 wtd.omp_ctx = NULL; 1984 wtd.try_block = NULL_TREE; 1985 wtd.no_sanitize_p = false; 1986 wtd.handle_invisiref_parm_p = handle_invisiref_parm_p; 1987 cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL); 1988 delete wtd.p_set; 1989 wtd.bind_expr_stack.release (); 1990 if (sanitize_flags_p (SANITIZE_VPTR)) 1991 cp_ubsan_instrument_member_accesses (t_p); 1992} 1993 1994/* If a function that should end with a return in non-void 1995 function doesn't obviously end with return, add ubsan 1996 instrumentation code to verify it at runtime. If -fsanitize=return 1997 is not enabled, instrument __builtin_unreachable. */ 1998 1999static void 2000cp_maybe_instrument_return (tree fndecl) 2001{ 2002 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))) 2003 || DECL_CONSTRUCTOR_P (fndecl) 2004 || DECL_DESTRUCTOR_P (fndecl) 2005 || !targetm.warn_func_return (fndecl)) 2006 return; 2007 2008 if (!sanitize_flags_p (SANITIZE_RETURN, fndecl) 2009 /* Don't add __builtin_unreachable () if not optimizing, it will not 2010 improve any optimizations in that case, just break UB code. 2011 Don't add it if -fsanitize=unreachable -fno-sanitize=return either, 2012 UBSan covers this with ubsan_instrument_return above where sufficient 2013 information is provided, while the __builtin_unreachable () below 2014 if return sanitization is disabled will just result in hard to 2015 understand runtime error without location. */ 2016 && (!optimize 2017 || sanitize_flags_p (SANITIZE_UNREACHABLE, fndecl))) 2018 return; 2019 2020 tree t = DECL_SAVED_TREE (fndecl); 2021 while (t) 2022 { 2023 switch (TREE_CODE (t)) 2024 { 2025 case BIND_EXPR: 2026 t = BIND_EXPR_BODY (t); 2027 continue; 2028 case TRY_FINALLY_EXPR: 2029 case CLEANUP_POINT_EXPR: 2030 t = TREE_OPERAND (t, 0); 2031 continue; 2032 case STATEMENT_LIST: 2033 { 2034 tree_stmt_iterator i = tsi_last (t); 2035 while (!tsi_end_p (i)) 2036 { 2037 tree p = tsi_stmt (i); 2038 if (TREE_CODE (p) != DEBUG_BEGIN_STMT) 2039 break; 2040 tsi_prev (&i); 2041 } 2042 if (!tsi_end_p (i)) 2043 { 2044 t = tsi_stmt (i); 2045 continue; 2046 } 2047 } 2048 break; 2049 case RETURN_EXPR: 2050 return; 2051 default: 2052 break; 2053 } 2054 break; 2055 } 2056 if (t == NULL_TREE) 2057 return; 2058 tree *p = &DECL_SAVED_TREE (fndecl); 2059 if (TREE_CODE (*p) == BIND_EXPR) 2060 p = &BIND_EXPR_BODY (*p); 2061 2062 location_t loc = DECL_SOURCE_LOCATION (fndecl); 2063 if (sanitize_flags_p (SANITIZE_RETURN, fndecl)) 2064 t = ubsan_instrument_return (loc); 2065 else 2066 { 2067 tree fndecl = builtin_decl_explicit (BUILT_IN_UNREACHABLE); 2068 t = build_call_expr_loc (BUILTINS_LOCATION, fndecl, 0); 2069 } 2070 2071 append_to_statement_list (t, p); 2072} 2073 2074void 2075cp_genericize (tree fndecl) 2076{ 2077 tree t; 2078 2079 /* Fix up the types of parms passed by invisible reference. */ 2080 for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t)) 2081 if (TREE_ADDRESSABLE (TREE_TYPE (t))) 2082 { 2083 /* If a function's arguments are copied to create a thunk, 2084 then DECL_BY_REFERENCE will be set -- but the type of the 2085 argument will be a pointer type, so we will never get 2086 here. */ 2087 gcc_assert (!DECL_BY_REFERENCE (t)); 2088 gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t)); 2089 TREE_TYPE (t) = DECL_ARG_TYPE (t); 2090 DECL_BY_REFERENCE (t) = 1; 2091 TREE_ADDRESSABLE (t) = 0; 2092 relayout_decl (t); 2093 } 2094 2095 /* Do the same for the return value. */ 2096 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl)))) 2097 { 2098 t = DECL_RESULT (fndecl); 2099 TREE_TYPE (t) = build_reference_type (TREE_TYPE (t)); 2100 DECL_BY_REFERENCE (t) = 1; 2101 TREE_ADDRESSABLE (t) = 0; 2102 relayout_decl (t); 2103 if (DECL_NAME (t)) 2104 { 2105 /* Adjust DECL_VALUE_EXPR of the original var. */ 2106 tree outer = outer_curly_brace_block (current_function_decl); 2107 tree var; 2108 2109 if (outer) 2110 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) 2111 if (VAR_P (var) 2112 && DECL_NAME (t) == DECL_NAME (var) 2113 && DECL_HAS_VALUE_EXPR_P (var) 2114 && DECL_VALUE_EXPR (var) == t) 2115 { 2116 tree val = convert_from_reference (t); 2117 SET_DECL_VALUE_EXPR (var, val); 2118 break; 2119 } 2120 } 2121 } 2122 2123 /* If we're a clone, the body is already GIMPLE. */ 2124 if (DECL_CLONED_FUNCTION_P (fndecl)) 2125 return; 2126 2127 /* Allow cp_genericize calls to be nested. */ 2128 tree save_bc_label[2]; 2129 save_bc_label[bc_break] = bc_label[bc_break]; 2130 save_bc_label[bc_continue] = bc_label[bc_continue]; 2131 bc_label[bc_break] = NULL_TREE; 2132 bc_label[bc_continue] = NULL_TREE; 2133 2134 /* We do want to see every occurrence of the parms, so we can't just use 2135 walk_tree's hash functionality. */ 2136 cp_genericize_tree (&DECL_SAVED_TREE (fndecl), true); 2137 2138 cp_maybe_instrument_return (fndecl); 2139 2140 /* Do everything else. */ 2141 c_genericize (fndecl); 2142 2143 gcc_assert (bc_label[bc_break] == NULL); 2144 gcc_assert (bc_label[bc_continue] == NULL); 2145 bc_label[bc_break] = save_bc_label[bc_break]; 2146 bc_label[bc_continue] = save_bc_label[bc_continue]; 2147} 2148 2149/* Build code to apply FN to each member of ARG1 and ARG2. FN may be 2150 NULL if there is in fact nothing to do. ARG2 may be null if FN 2151 actually only takes one argument. */ 2152 2153static tree 2154cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2) 2155{ 2156 tree defparm, parm, t; 2157 int i = 0; 2158 int nargs; 2159 tree *argarray; 2160 2161 if (fn == NULL) 2162 return NULL; 2163 2164 nargs = list_length (DECL_ARGUMENTS (fn)); 2165 argarray = XALLOCAVEC (tree, nargs); 2166 2167 defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))); 2168 if (arg2) 2169 defparm = TREE_CHAIN (defparm); 2170 2171 bool is_method = TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE; 2172 if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE) 2173 { 2174 tree inner_type = TREE_TYPE (arg1); 2175 tree start1, end1, p1; 2176 tree start2 = NULL, p2 = NULL; 2177 tree ret = NULL, lab; 2178 2179 start1 = arg1; 2180 start2 = arg2; 2181 do 2182 { 2183 inner_type = TREE_TYPE (inner_type); 2184 start1 = build4 (ARRAY_REF, inner_type, start1, 2185 size_zero_node, NULL, NULL); 2186 if (arg2) 2187 start2 = build4 (ARRAY_REF, inner_type, start2, 2188 size_zero_node, NULL, NULL); 2189 } 2190 while (TREE_CODE (inner_type) == ARRAY_TYPE); 2191 start1 = build_fold_addr_expr_loc (input_location, start1); 2192 if (arg2) 2193 start2 = build_fold_addr_expr_loc (input_location, start2); 2194 2195 end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1)); 2196 end1 = fold_build_pointer_plus (start1, end1); 2197 2198 p1 = create_tmp_var (TREE_TYPE (start1)); 2199 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1); 2200 append_to_statement_list (t, &ret); 2201 2202 if (arg2) 2203 { 2204 p2 = create_tmp_var (TREE_TYPE (start2)); 2205 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2); 2206 append_to_statement_list (t, &ret); 2207 } 2208 2209 lab = create_artificial_label (input_location); 2210 t = build1 (LABEL_EXPR, void_type_node, lab); 2211 append_to_statement_list (t, &ret); 2212 2213 argarray[i++] = p1; 2214 if (arg2) 2215 argarray[i++] = p2; 2216 /* Handle default arguments. */ 2217 for (parm = defparm; parm && parm != void_list_node; 2218 parm = TREE_CHAIN (parm), i++) 2219 argarray[i] = convert_default_arg (TREE_VALUE (parm), 2220 TREE_PURPOSE (parm), fn, 2221 i - is_method, tf_warning_or_error); 2222 t = build_call_a (fn, i, argarray); 2223 t = fold_convert (void_type_node, t); 2224 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); 2225 append_to_statement_list (t, &ret); 2226 2227 t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type)); 2228 t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t); 2229 append_to_statement_list (t, &ret); 2230 2231 if (arg2) 2232 { 2233 t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type)); 2234 t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t); 2235 append_to_statement_list (t, &ret); 2236 } 2237 2238 t = build2 (NE_EXPR, boolean_type_node, p1, end1); 2239 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL); 2240 append_to_statement_list (t, &ret); 2241 2242 return ret; 2243 } 2244 else 2245 { 2246 argarray[i++] = build_fold_addr_expr_loc (input_location, arg1); 2247 if (arg2) 2248 argarray[i++] = build_fold_addr_expr_loc (input_location, arg2); 2249 /* Handle default arguments. */ 2250 for (parm = defparm; parm && parm != void_list_node; 2251 parm = TREE_CHAIN (parm), i++) 2252 argarray[i] = convert_default_arg (TREE_VALUE (parm), 2253 TREE_PURPOSE (parm), fn, 2254 i - is_method, tf_warning_or_error); 2255 t = build_call_a (fn, i, argarray); 2256 t = fold_convert (void_type_node, t); 2257 return fold_build_cleanup_point_expr (TREE_TYPE (t), t); 2258 } 2259} 2260 2261/* Return code to initialize DECL with its default constructor, or 2262 NULL if there's nothing to do. */ 2263 2264tree 2265cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/) 2266{ 2267 tree info = CP_OMP_CLAUSE_INFO (clause); 2268 tree ret = NULL; 2269 2270 if (info) 2271 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL); 2272 2273 return ret; 2274} 2275 2276/* Return code to initialize DST with a copy constructor from SRC. */ 2277 2278tree 2279cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src) 2280{ 2281 tree info = CP_OMP_CLAUSE_INFO (clause); 2282 tree ret = NULL; 2283 2284 if (info) 2285 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src); 2286 if (ret == NULL) 2287 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); 2288 2289 return ret; 2290} 2291 2292/* Similarly, except use an assignment operator instead. */ 2293 2294tree 2295cxx_omp_clause_assign_op (tree clause, tree dst, tree src) 2296{ 2297 tree info = CP_OMP_CLAUSE_INFO (clause); 2298 tree ret = NULL; 2299 2300 if (info) 2301 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src); 2302 if (ret == NULL) 2303 ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); 2304 2305 return ret; 2306} 2307 2308/* Return code to destroy DECL. */ 2309 2310tree 2311cxx_omp_clause_dtor (tree clause, tree decl) 2312{ 2313 tree info = CP_OMP_CLAUSE_INFO (clause); 2314 tree ret = NULL; 2315 2316 if (info) 2317 ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL); 2318 2319 return ret; 2320} 2321 2322/* True if OpenMP should privatize what this DECL points to rather 2323 than the DECL itself. */ 2324 2325bool 2326cxx_omp_privatize_by_reference (const_tree decl) 2327{ 2328 return (TYPE_REF_P (TREE_TYPE (decl)) 2329 || is_invisiref_parm (decl)); 2330} 2331 2332/* Return true if DECL is const qualified var having no mutable member. */ 2333bool 2334cxx_omp_const_qual_no_mutable (tree decl) 2335{ 2336 tree type = TREE_TYPE (decl); 2337 if (TYPE_REF_P (type)) 2338 { 2339 if (!is_invisiref_parm (decl)) 2340 return false; 2341 type = TREE_TYPE (type); 2342 2343 if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl)) 2344 { 2345 /* NVR doesn't preserve const qualification of the 2346 variable's type. */ 2347 tree outer = outer_curly_brace_block (current_function_decl); 2348 tree var; 2349 2350 if (outer) 2351 for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) 2352 if (VAR_P (var) 2353 && DECL_NAME (decl) == DECL_NAME (var) 2354 && (TYPE_MAIN_VARIANT (type) 2355 == TYPE_MAIN_VARIANT (TREE_TYPE (var)))) 2356 { 2357 if (TYPE_READONLY (TREE_TYPE (var))) 2358 type = TREE_TYPE (var); 2359 break; 2360 } 2361 } 2362 } 2363 2364 if (type == error_mark_node) 2365 return false; 2366 2367 /* Variables with const-qualified type having no mutable member 2368 are predetermined shared. */ 2369 if (TYPE_READONLY (type) && !cp_has_mutable_p (type)) 2370 return true; 2371 2372 return false; 2373} 2374 2375/* True if OpenMP sharing attribute of DECL is predetermined. */ 2376 2377enum omp_clause_default_kind 2378cxx_omp_predetermined_sharing_1 (tree decl) 2379{ 2380 /* Static data members are predetermined shared. */ 2381 if (TREE_STATIC (decl)) 2382 { 2383 tree ctx = CP_DECL_CONTEXT (decl); 2384 if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx)) 2385 return OMP_CLAUSE_DEFAULT_SHARED; 2386 2387 if (c_omp_predefined_variable (decl)) 2388 return OMP_CLAUSE_DEFAULT_SHARED; 2389 } 2390 2391 /* this may not be specified in data-sharing clauses, still we need 2392 to predetermined it firstprivate. */ 2393 if (decl == current_class_ptr) 2394 return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE; 2395 2396 return OMP_CLAUSE_DEFAULT_UNSPECIFIED; 2397} 2398 2399/* Likewise, but also include the artificial vars. We don't want to 2400 disallow the artificial vars being mentioned in explicit clauses, 2401 as we use artificial vars e.g. for loop constructs with random 2402 access iterators other than pointers, but during gimplification 2403 we want to treat them as predetermined. */ 2404 2405enum omp_clause_default_kind 2406cxx_omp_predetermined_sharing (tree decl) 2407{ 2408 enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl); 2409 if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED) 2410 return ret; 2411 2412 /* Predetermine artificial variables holding integral values, those 2413 are usually result of gimplify_one_sizepos or SAVE_EXPR 2414 gimplification. */ 2415 if (VAR_P (decl) 2416 && DECL_ARTIFICIAL (decl) 2417 && INTEGRAL_TYPE_P (TREE_TYPE (decl)) 2418 && !(DECL_LANG_SPECIFIC (decl) 2419 && DECL_OMP_PRIVATIZED_MEMBER (decl))) 2420 return OMP_CLAUSE_DEFAULT_SHARED; 2421 2422 /* Similarly for typeinfo symbols. */ 2423 if (VAR_P (decl) && DECL_ARTIFICIAL (decl) && DECL_TINFO_P (decl)) 2424 return OMP_CLAUSE_DEFAULT_SHARED; 2425 2426 return OMP_CLAUSE_DEFAULT_UNSPECIFIED; 2427} 2428 2429/* Finalize an implicitly determined clause. */ 2430 2431void 2432cxx_omp_finish_clause (tree c, gimple_seq *) 2433{ 2434 tree decl, inner_type; 2435 bool make_shared = false; 2436 2437 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE 2438 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE 2439 || !OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))) 2440 return; 2441 2442 decl = OMP_CLAUSE_DECL (c); 2443 decl = require_complete_type (decl); 2444 inner_type = TREE_TYPE (decl); 2445 if (decl == error_mark_node) 2446 make_shared = true; 2447 else if (TYPE_REF_P (TREE_TYPE (decl))) 2448 inner_type = TREE_TYPE (inner_type); 2449 2450 /* We're interested in the base element, not arrays. */ 2451 while (TREE_CODE (inner_type) == ARRAY_TYPE) 2452 inner_type = TREE_TYPE (inner_type); 2453 2454 /* Check for special function availability by building a call to one. 2455 Save the results, because later we won't be in the right context 2456 for making these queries. */ 2457 bool first = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE; 2458 if (!make_shared 2459 && CLASS_TYPE_P (inner_type) 2460 && cxx_omp_create_clause_info (c, inner_type, !first, first, !first, 2461 true)) 2462 make_shared = true; 2463 2464 if (make_shared) 2465 { 2466 OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED; 2467 OMP_CLAUSE_SHARED_FIRSTPRIVATE (c) = 0; 2468 OMP_CLAUSE_SHARED_READONLY (c) = 0; 2469 } 2470} 2471 2472/* Return true if DECL's DECL_VALUE_EXPR (if any) should be 2473 disregarded in OpenMP construct, because it is going to be 2474 remapped during OpenMP lowering. SHARED is true if DECL 2475 is going to be shared, false if it is going to be privatized. */ 2476 2477bool 2478cxx_omp_disregard_value_expr (tree decl, bool shared) 2479{ 2480 if (shared) 2481 return false; 2482 if (VAR_P (decl) 2483 && DECL_HAS_VALUE_EXPR_P (decl) 2484 && DECL_ARTIFICIAL (decl) 2485 && DECL_LANG_SPECIFIC (decl) 2486 && DECL_OMP_PRIVATIZED_MEMBER (decl)) 2487 return true; 2488 if (VAR_P (decl) && DECL_CONTEXT (decl) && is_capture_proxy (decl)) 2489 return true; 2490 return false; 2491} 2492 2493/* Fold expression X which is used as an rvalue if RVAL is true. */ 2494 2495tree 2496cp_fold_maybe_rvalue (tree x, bool rval) 2497{ 2498 while (true) 2499 { 2500 x = cp_fold (x); 2501 if (rval) 2502 x = mark_rvalue_use (x); 2503 if (rval && DECL_P (x) 2504 && !TYPE_REF_P (TREE_TYPE (x))) 2505 { 2506 tree v = decl_constant_value (x); 2507 if (v != x && v != error_mark_node) 2508 { 2509 x = v; 2510 continue; 2511 } 2512 } 2513 break; 2514 } 2515 return x; 2516} 2517 2518/* Fold expression X which is used as an rvalue. */ 2519 2520tree 2521cp_fold_rvalue (tree x) 2522{ 2523 return cp_fold_maybe_rvalue (x, true); 2524} 2525 2526/* Perform folding on expression X. */ 2527 2528tree 2529cp_fully_fold (tree x) 2530{ 2531 if (processing_template_decl) 2532 return x; 2533 /* FIXME cp_fold ought to be a superset of maybe_constant_value so we don't 2534 have to call both. */ 2535 if (cxx_dialect >= cxx11) 2536 { 2537 x = maybe_constant_value (x); 2538 /* Sometimes we are given a CONSTRUCTOR but the call above wraps it into 2539 a TARGET_EXPR; undo that here. */ 2540 if (TREE_CODE (x) == TARGET_EXPR) 2541 x = TARGET_EXPR_INITIAL (x); 2542 else if (TREE_CODE (x) == VIEW_CONVERT_EXPR 2543 && TREE_CODE (TREE_OPERAND (x, 0)) == CONSTRUCTOR 2544 && TREE_TYPE (TREE_OPERAND (x, 0)) == TREE_TYPE (x)) 2545 x = TREE_OPERAND (x, 0); 2546 } 2547 return cp_fold_rvalue (x); 2548} 2549 2550/* Likewise, but also fold recursively, which cp_fully_fold doesn't perform 2551 in some cases. */ 2552 2553tree 2554cp_fully_fold_init (tree x) 2555{ 2556 if (processing_template_decl) 2557 return x; 2558 x = cp_fully_fold (x); 2559 cp_fold_data data (/*genericize*/false); 2560 cp_walk_tree (&x, cp_fold_r, &data, NULL); 2561 return x; 2562} 2563 2564/* c-common interface to cp_fold. If IN_INIT, this is in a static initializer 2565 and certain changes are made to the folding done. Or should be (FIXME). We 2566 never touch maybe_const, as it is only used for the C front-end 2567 C_MAYBE_CONST_EXPR. */ 2568 2569tree 2570c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/, bool lval) 2571{ 2572 return cp_fold_maybe_rvalue (x, !lval); 2573} 2574 2575static GTY((deletable)) hash_map<tree, tree> *fold_cache; 2576 2577/* Dispose of the whole FOLD_CACHE. */ 2578 2579void 2580clear_fold_cache (void) 2581{ 2582 if (fold_cache != NULL) 2583 fold_cache->empty (); 2584} 2585 2586/* This function tries to fold an expression X. 2587 To avoid combinatorial explosion, folding results are kept in fold_cache. 2588 If X is invalid, we don't fold at all. 2589 For performance reasons we don't cache expressions representing a 2590 declaration or constant. 2591 Function returns X or its folded variant. */ 2592 2593static tree 2594cp_fold (tree x) 2595{ 2596 tree op0, op1, op2, op3; 2597 tree org_x = x, r = NULL_TREE; 2598 enum tree_code code; 2599 location_t loc; 2600 bool rval_ops = true; 2601 2602 if (!x || x == error_mark_node) 2603 return x; 2604 2605 if (EXPR_P (x) && (!TREE_TYPE (x) || TREE_TYPE (x) == error_mark_node)) 2606 return x; 2607 2608 /* Don't bother to cache DECLs or constants. */ 2609 if (DECL_P (x) || CONSTANT_CLASS_P (x)) 2610 return x; 2611 2612 if (fold_cache == NULL) 2613 fold_cache = hash_map<tree, tree>::create_ggc (101); 2614 2615 if (tree *cached = fold_cache->get (x)) 2616 return *cached; 2617 2618 code = TREE_CODE (x); 2619 switch (code) 2620 { 2621 case CLEANUP_POINT_EXPR: 2622 /* Strip CLEANUP_POINT_EXPR if the expression doesn't have side 2623 effects. */ 2624 r = cp_fold_rvalue (TREE_OPERAND (x, 0)); 2625 if (!TREE_SIDE_EFFECTS (r)) 2626 x = r; 2627 break; 2628 2629 case SIZEOF_EXPR: 2630 x = fold_sizeof_expr (x); 2631 break; 2632 2633 case VIEW_CONVERT_EXPR: 2634 rval_ops = false; 2635 /* FALLTHRU */ 2636 case CONVERT_EXPR: 2637 case NOP_EXPR: 2638 case NON_LVALUE_EXPR: 2639 2640 if (VOID_TYPE_P (TREE_TYPE (x))) 2641 { 2642 /* This is just to make sure we don't end up with casts to 2643 void from error_mark_node. If we just return x, then 2644 cp_fold_r might fold the operand into error_mark_node and 2645 leave the conversion in the IR. STRIP_USELESS_TYPE_CONVERSION 2646 during gimplification doesn't like such casts. 2647 Don't create a new tree if op0 != TREE_OPERAND (x, 0), the 2648 folding of the operand should be in the caches and if in cp_fold_r 2649 it will modify it in place. */ 2650 op0 = cp_fold (TREE_OPERAND (x, 0)); 2651 if (op0 == error_mark_node) 2652 x = error_mark_node; 2653 break; 2654 } 2655 2656 loc = EXPR_LOCATION (x); 2657 op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops); 2658 2659 if (code == CONVERT_EXPR 2660 && SCALAR_TYPE_P (TREE_TYPE (x)) 2661 && op0 != void_node) 2662 /* During parsing we used convert_to_*_nofold; re-convert now using the 2663 folding variants, since fold() doesn't do those transformations. */ 2664 x = fold (convert (TREE_TYPE (x), op0)); 2665 else if (op0 != TREE_OPERAND (x, 0)) 2666 { 2667 if (op0 == error_mark_node) 2668 x = error_mark_node; 2669 else 2670 x = fold_build1_loc (loc, code, TREE_TYPE (x), op0); 2671 } 2672 else 2673 x = fold (x); 2674 2675 /* Conversion of an out-of-range value has implementation-defined 2676 behavior; the language considers it different from arithmetic 2677 overflow, which is undefined. */ 2678 if (TREE_CODE (op0) == INTEGER_CST 2679 && TREE_OVERFLOW_P (x) && !TREE_OVERFLOW_P (op0)) 2680 TREE_OVERFLOW (x) = false; 2681 2682 break; 2683 2684 case INDIRECT_REF: 2685 /* We don't need the decltype(auto) obfuscation anymore. */ 2686 if (REF_PARENTHESIZED_P (x)) 2687 { 2688 tree p = maybe_undo_parenthesized_ref (x); 2689 return cp_fold (p); 2690 } 2691 goto unary; 2692 2693 case ADDR_EXPR: 2694 loc = EXPR_LOCATION (x); 2695 op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), false); 2696 2697 /* Cope with user tricks that amount to offsetof. */ 2698 if (op0 != error_mark_node 2699 && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (op0))) 2700 { 2701 tree val = get_base_address (op0); 2702 if (val 2703 && INDIRECT_REF_P (val) 2704 && COMPLETE_TYPE_P (TREE_TYPE (val)) 2705 && TREE_CONSTANT (TREE_OPERAND (val, 0))) 2706 { 2707 val = TREE_OPERAND (val, 0); 2708 STRIP_NOPS (val); 2709 val = maybe_constant_value (val); 2710 if (TREE_CODE (val) == INTEGER_CST) 2711 return fold_offsetof (op0, TREE_TYPE (x)); 2712 } 2713 } 2714 goto finish_unary; 2715 2716 case REALPART_EXPR: 2717 case IMAGPART_EXPR: 2718 rval_ops = false; 2719 /* FALLTHRU */ 2720 case CONJ_EXPR: 2721 case FIX_TRUNC_EXPR: 2722 case FLOAT_EXPR: 2723 case NEGATE_EXPR: 2724 case ABS_EXPR: 2725 case ABSU_EXPR: 2726 case BIT_NOT_EXPR: 2727 case TRUTH_NOT_EXPR: 2728 case FIXED_CONVERT_EXPR: 2729 unary: 2730 2731 loc = EXPR_LOCATION (x); 2732 op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops); 2733 2734 finish_unary: 2735 if (op0 != TREE_OPERAND (x, 0)) 2736 { 2737 if (op0 == error_mark_node) 2738 x = error_mark_node; 2739 else 2740 { 2741 x = fold_build1_loc (loc, code, TREE_TYPE (x), op0); 2742 if (code == INDIRECT_REF 2743 && (INDIRECT_REF_P (x) || TREE_CODE (x) == MEM_REF)) 2744 { 2745 TREE_READONLY (x) = TREE_READONLY (org_x); 2746 TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x); 2747 TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x); 2748 } 2749 } 2750 } 2751 else 2752 x = fold (x); 2753 2754 gcc_assert (TREE_CODE (x) != COND_EXPR 2755 || !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0)))); 2756 break; 2757 2758 case UNARY_PLUS_EXPR: 2759 op0 = cp_fold_rvalue (TREE_OPERAND (x, 0)); 2760 if (op0 == error_mark_node) 2761 x = error_mark_node; 2762 else 2763 x = fold_convert (TREE_TYPE (x), op0); 2764 break; 2765 2766 case POSTDECREMENT_EXPR: 2767 case POSTINCREMENT_EXPR: 2768 case INIT_EXPR: 2769 case PREDECREMENT_EXPR: 2770 case PREINCREMENT_EXPR: 2771 case COMPOUND_EXPR: 2772 case MODIFY_EXPR: 2773 rval_ops = false; 2774 /* FALLTHRU */ 2775 case POINTER_PLUS_EXPR: 2776 case PLUS_EXPR: 2777 case POINTER_DIFF_EXPR: 2778 case MINUS_EXPR: 2779 case MULT_EXPR: 2780 case TRUNC_DIV_EXPR: 2781 case CEIL_DIV_EXPR: 2782 case FLOOR_DIV_EXPR: 2783 case ROUND_DIV_EXPR: 2784 case TRUNC_MOD_EXPR: 2785 case CEIL_MOD_EXPR: 2786 case ROUND_MOD_EXPR: 2787 case RDIV_EXPR: 2788 case EXACT_DIV_EXPR: 2789 case MIN_EXPR: 2790 case MAX_EXPR: 2791 case LSHIFT_EXPR: 2792 case RSHIFT_EXPR: 2793 case LROTATE_EXPR: 2794 case RROTATE_EXPR: 2795 case BIT_AND_EXPR: 2796 case BIT_IOR_EXPR: 2797 case BIT_XOR_EXPR: 2798 case TRUTH_AND_EXPR: 2799 case TRUTH_ANDIF_EXPR: 2800 case TRUTH_OR_EXPR: 2801 case TRUTH_ORIF_EXPR: 2802 case TRUTH_XOR_EXPR: 2803 case LT_EXPR: case LE_EXPR: 2804 case GT_EXPR: case GE_EXPR: 2805 case EQ_EXPR: case NE_EXPR: 2806 case UNORDERED_EXPR: case ORDERED_EXPR: 2807 case UNLT_EXPR: case UNLE_EXPR: 2808 case UNGT_EXPR: case UNGE_EXPR: 2809 case UNEQ_EXPR: case LTGT_EXPR: 2810 case RANGE_EXPR: case COMPLEX_EXPR: 2811 2812 loc = EXPR_LOCATION (x); 2813 op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops); 2814 op1 = cp_fold_rvalue (TREE_OPERAND (x, 1)); 2815 2816 /* decltype(nullptr) has only one value, so optimize away all comparisons 2817 with that type right away, keeping them in the IL causes troubles for 2818 various optimizations. */ 2819 if (COMPARISON_CLASS_P (org_x) 2820 && TREE_CODE (TREE_TYPE (op0)) == NULLPTR_TYPE 2821 && TREE_CODE (TREE_TYPE (op1)) == NULLPTR_TYPE) 2822 { 2823 switch (code) 2824 { 2825 case EQ_EXPR: 2826 case LE_EXPR: 2827 case GE_EXPR: 2828 x = constant_boolean_node (true, TREE_TYPE (x)); 2829 break; 2830 case NE_EXPR: 2831 case LT_EXPR: 2832 case GT_EXPR: 2833 x = constant_boolean_node (false, TREE_TYPE (x)); 2834 break; 2835 default: 2836 gcc_unreachable (); 2837 } 2838 return omit_two_operands_loc (loc, TREE_TYPE (x), x, 2839 op0, op1); 2840 } 2841 2842 if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1)) 2843 { 2844 if (op0 == error_mark_node || op1 == error_mark_node) 2845 x = error_mark_node; 2846 else 2847 x = fold_build2_loc (loc, code, TREE_TYPE (x), op0, op1); 2848 } 2849 else 2850 x = fold (x); 2851 2852 /* This is only needed for -Wnonnull-compare and only if 2853 TREE_NO_WARNING (org_x), but to avoid that option affecting code 2854 generation, we do it always. */ 2855 if (COMPARISON_CLASS_P (org_x)) 2856 { 2857 if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST) 2858 ; 2859 else if (COMPARISON_CLASS_P (x)) 2860 { 2861 if (TREE_NO_WARNING (org_x) && warn_nonnull_compare) 2862 TREE_NO_WARNING (x) = 1; 2863 } 2864 /* Otherwise give up on optimizing these, let GIMPLE folders 2865 optimize those later on. */ 2866 else if (op0 != TREE_OPERAND (org_x, 0) 2867 || op1 != TREE_OPERAND (org_x, 1)) 2868 { 2869 x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1); 2870 if (TREE_NO_WARNING (org_x) && warn_nonnull_compare) 2871 TREE_NO_WARNING (x) = 1; 2872 } 2873 else 2874 x = org_x; 2875 } 2876 2877 break; 2878 2879 case VEC_COND_EXPR: 2880 case COND_EXPR: 2881 loc = EXPR_LOCATION (x); 2882 op0 = cp_fold_rvalue (TREE_OPERAND (x, 0)); 2883 op1 = cp_fold (TREE_OPERAND (x, 1)); 2884 op2 = cp_fold (TREE_OPERAND (x, 2)); 2885 2886 if (TREE_CODE (TREE_TYPE (x)) == BOOLEAN_TYPE) 2887 { 2888 warning_sentinel s (warn_int_in_bool_context); 2889 if (!VOID_TYPE_P (TREE_TYPE (op1))) 2890 op1 = cp_truthvalue_conversion (op1, tf_warning_or_error); 2891 if (!VOID_TYPE_P (TREE_TYPE (op2))) 2892 op2 = cp_truthvalue_conversion (op2, tf_warning_or_error); 2893 } 2894 else if (VOID_TYPE_P (TREE_TYPE (x))) 2895 { 2896 if (TREE_CODE (op0) == INTEGER_CST) 2897 { 2898 /* If the condition is constant, fold can fold away 2899 the COND_EXPR. If some statement-level uses of COND_EXPR 2900 have one of the branches NULL, avoid folding crash. */ 2901 if (!op1) 2902 op1 = build_empty_stmt (loc); 2903 if (!op2) 2904 op2 = build_empty_stmt (loc); 2905 } 2906 else 2907 { 2908 /* Otherwise, don't bother folding a void condition, since 2909 it can't produce a constant value. */ 2910 if (op0 != TREE_OPERAND (x, 0) 2911 || op1 != TREE_OPERAND (x, 1) 2912 || op2 != TREE_OPERAND (x, 2)) 2913 x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2); 2914 break; 2915 } 2916 } 2917 2918 if (op0 != TREE_OPERAND (x, 0) 2919 || op1 != TREE_OPERAND (x, 1) 2920 || op2 != TREE_OPERAND (x, 2)) 2921 { 2922 if (op0 == error_mark_node 2923 || op1 == error_mark_node 2924 || op2 == error_mark_node) 2925 x = error_mark_node; 2926 else 2927 x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2); 2928 } 2929 else 2930 x = fold (x); 2931 2932 /* A COND_EXPR might have incompatible types in branches if one or both 2933 arms are bitfields. If folding exposed such a branch, fix it up. */ 2934 if (TREE_CODE (x) != code 2935 && x != error_mark_node 2936 && !useless_type_conversion_p (TREE_TYPE (org_x), TREE_TYPE (x))) 2937 x = fold_convert (TREE_TYPE (org_x), x); 2938 2939 break; 2940 2941 case CALL_EXPR: 2942 { 2943 int i, m, sv = optimize, nw = sv, changed = 0; 2944 tree callee = get_callee_fndecl (x); 2945 2946 /* Some built-in function calls will be evaluated at compile-time in 2947 fold (). Set optimize to 1 when folding __builtin_constant_p inside 2948 a constexpr function so that fold_builtin_1 doesn't fold it to 0. */ 2949 if (callee && fndecl_built_in_p (callee) && !optimize 2950 && DECL_IS_BUILTIN_CONSTANT_P (callee) 2951 && current_function_decl 2952 && DECL_DECLARED_CONSTEXPR_P (current_function_decl)) 2953 nw = 1; 2954 2955 /* Defer folding __builtin_is_constant_evaluated. */ 2956 if (callee 2957 && fndecl_built_in_p (callee, CP_BUILT_IN_IS_CONSTANT_EVALUATED, 2958 BUILT_IN_FRONTEND)) 2959 break; 2960 2961 if (callee 2962 && fndecl_built_in_p (callee, CP_BUILT_IN_SOURCE_LOCATION, 2963 BUILT_IN_FRONTEND)) 2964 { 2965 x = fold_builtin_source_location (EXPR_LOCATION (x)); 2966 break; 2967 } 2968 2969 x = copy_node (x); 2970 2971 m = call_expr_nargs (x); 2972 for (i = 0; i < m; i++) 2973 { 2974 r = cp_fold (CALL_EXPR_ARG (x, i)); 2975 if (r != CALL_EXPR_ARG (x, i)) 2976 { 2977 if (r == error_mark_node) 2978 { 2979 x = error_mark_node; 2980 break; 2981 } 2982 changed = 1; 2983 } 2984 CALL_EXPR_ARG (x, i) = r; 2985 } 2986 if (x == error_mark_node) 2987 break; 2988 2989 optimize = nw; 2990 r = fold (x); 2991 optimize = sv; 2992 2993 if (TREE_CODE (r) != CALL_EXPR) 2994 { 2995 x = cp_fold (r); 2996 break; 2997 } 2998 2999 optimize = nw; 3000 3001 /* Invoke maybe_constant_value for functions declared 3002 constexpr and not called with AGGR_INIT_EXPRs. 3003 TODO: 3004 Do constexpr expansion of expressions where the call itself is not 3005 constant, but the call followed by an INDIRECT_REF is. */ 3006 if (callee && DECL_DECLARED_CONSTEXPR_P (callee) 3007 && !flag_no_inline) 3008 r = maybe_constant_value (x); 3009 optimize = sv; 3010 3011 if (TREE_CODE (r) != CALL_EXPR) 3012 { 3013 if (DECL_CONSTRUCTOR_P (callee)) 3014 { 3015 loc = EXPR_LOCATION (x); 3016 tree s = build_fold_indirect_ref_loc (loc, 3017 CALL_EXPR_ARG (x, 0)); 3018 r = build2_loc (loc, INIT_EXPR, TREE_TYPE (s), s, r); 3019 } 3020 x = r; 3021 break; 3022 } 3023 3024 if (!changed) 3025 x = org_x; 3026 break; 3027 } 3028 3029 case CONSTRUCTOR: 3030 { 3031 unsigned i; 3032 constructor_elt *p; 3033 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (x); 3034 vec<constructor_elt, va_gc> *nelts = NULL; 3035 FOR_EACH_VEC_SAFE_ELT (elts, i, p) 3036 { 3037 tree op = cp_fold (p->value); 3038 if (op != p->value) 3039 { 3040 if (op == error_mark_node) 3041 { 3042 x = error_mark_node; 3043 vec_free (nelts); 3044 break; 3045 } 3046 if (nelts == NULL) 3047 nelts = elts->copy (); 3048 (*nelts)[i].value = op; 3049 } 3050 } 3051 if (nelts) 3052 { 3053 x = build_constructor (TREE_TYPE (x), nelts); 3054 CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x) 3055 = CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x); 3056 } 3057 if (VECTOR_TYPE_P (TREE_TYPE (x))) 3058 x = fold (x); 3059 break; 3060 } 3061 case TREE_VEC: 3062 { 3063 bool changed = false; 3064 releasing_vec vec; 3065 int i, n = TREE_VEC_LENGTH (x); 3066 vec_safe_reserve (vec, n); 3067 3068 for (i = 0; i < n; i++) 3069 { 3070 tree op = cp_fold (TREE_VEC_ELT (x, i)); 3071 vec->quick_push (op); 3072 if (op != TREE_VEC_ELT (x, i)) 3073 changed = true; 3074 } 3075 3076 if (changed) 3077 { 3078 r = copy_node (x); 3079 for (i = 0; i < n; i++) 3080 TREE_VEC_ELT (r, i) = (*vec)[i]; 3081 x = r; 3082 } 3083 } 3084 3085 break; 3086 3087 case ARRAY_REF: 3088 case ARRAY_RANGE_REF: 3089 3090 loc = EXPR_LOCATION (x); 3091 op0 = cp_fold (TREE_OPERAND (x, 0)); 3092 op1 = cp_fold (TREE_OPERAND (x, 1)); 3093 op2 = cp_fold (TREE_OPERAND (x, 2)); 3094 op3 = cp_fold (TREE_OPERAND (x, 3)); 3095 3096 if (op0 != TREE_OPERAND (x, 0) 3097 || op1 != TREE_OPERAND (x, 1) 3098 || op2 != TREE_OPERAND (x, 2) 3099 || op3 != TREE_OPERAND (x, 3)) 3100 { 3101 if (op0 == error_mark_node 3102 || op1 == error_mark_node 3103 || op2 == error_mark_node 3104 || op3 == error_mark_node) 3105 x = error_mark_node; 3106 else 3107 { 3108 x = build4_loc (loc, code, TREE_TYPE (x), op0, op1, op2, op3); 3109 TREE_READONLY (x) = TREE_READONLY (org_x); 3110 TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x); 3111 TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x); 3112 } 3113 } 3114 3115 x = fold (x); 3116 break; 3117 3118 case SAVE_EXPR: 3119 /* A SAVE_EXPR might contain e.g. (0 * i) + (0 * j), which, after 3120 folding, evaluates to an invariant. In that case no need to wrap 3121 this folded tree with a SAVE_EXPR. */ 3122 r = cp_fold (TREE_OPERAND (x, 0)); 3123 if (tree_invariant_p (r)) 3124 x = r; 3125 break; 3126 3127 default: 3128 return org_x; 3129 } 3130 3131 if (EXPR_P (x) && TREE_CODE (x) == code) 3132 { 3133 TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x); 3134 TREE_NO_WARNING (x) = TREE_NO_WARNING (org_x); 3135 } 3136 3137 fold_cache->put (org_x, x); 3138 /* Prevent that we try to fold an already folded result again. */ 3139 if (x != org_x) 3140 fold_cache->put (x, x); 3141 3142 return x; 3143} 3144 3145/* Look up either "hot" or "cold" in attribute list LIST. */ 3146 3147tree 3148lookup_hotness_attribute (tree list) 3149{ 3150 for (; list; list = TREE_CHAIN (list)) 3151 { 3152 tree name = get_attribute_name (list); 3153 if (is_attribute_p ("hot", name) 3154 || is_attribute_p ("cold", name) 3155 || is_attribute_p ("likely", name) 3156 || is_attribute_p ("unlikely", name)) 3157 break; 3158 } 3159 return list; 3160} 3161 3162/* Remove both "hot" and "cold" attributes from LIST. */ 3163 3164static tree 3165remove_hotness_attribute (tree list) 3166{ 3167 list = remove_attribute ("hot", list); 3168 list = remove_attribute ("cold", list); 3169 list = remove_attribute ("likely", list); 3170 list = remove_attribute ("unlikely", list); 3171 return list; 3172} 3173 3174/* If [[likely]] or [[unlikely]] appear on this statement, turn it into a 3175 PREDICT_EXPR. */ 3176 3177tree 3178process_stmt_hotness_attribute (tree std_attrs, location_t attrs_loc) 3179{ 3180 if (std_attrs == error_mark_node) 3181 return std_attrs; 3182 if (tree attr = lookup_hotness_attribute (std_attrs)) 3183 { 3184 tree name = get_attribute_name (attr); 3185 bool hot = (is_attribute_p ("hot", name) 3186 || is_attribute_p ("likely", name)); 3187 tree pred = build_predict_expr (hot ? PRED_HOT_LABEL : PRED_COLD_LABEL, 3188 hot ? TAKEN : NOT_TAKEN); 3189 SET_EXPR_LOCATION (pred, attrs_loc); 3190 add_stmt (pred); 3191 if (tree other = lookup_hotness_attribute (TREE_CHAIN (attr))) 3192 warning (OPT_Wattributes, "ignoring attribute %qE after earlier %qE", 3193 get_attribute_name (other), name); 3194 std_attrs = remove_hotness_attribute (std_attrs); 3195 } 3196 return std_attrs; 3197} 3198 3199/* Helper of fold_builtin_source_location, return the 3200 std::source_location::__impl type after performing verification 3201 on it. LOC is used for reporting any errors. */ 3202 3203static tree 3204get_source_location_impl_type (location_t loc) 3205{ 3206 tree name = get_identifier ("source_location"); 3207 tree decl = lookup_qualified_name (std_node, name); 3208 if (TREE_CODE (decl) != TYPE_DECL) 3209 { 3210 auto_diagnostic_group d; 3211 if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST) 3212 qualified_name_lookup_error (std_node, name, decl, loc); 3213 else 3214 error_at (loc, "%qD is not a type", decl); 3215 return error_mark_node; 3216 } 3217 name = get_identifier ("__impl"); 3218 tree type = TREE_TYPE (decl); 3219 decl = lookup_qualified_name (type, name); 3220 if (TREE_CODE (decl) != TYPE_DECL) 3221 { 3222 auto_diagnostic_group d; 3223 if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST) 3224 qualified_name_lookup_error (type, name, decl, loc); 3225 else 3226 error_at (loc, "%qD is not a type", decl); 3227 return error_mark_node; 3228 } 3229 type = TREE_TYPE (decl); 3230 if (TREE_CODE (type) != RECORD_TYPE) 3231 { 3232 error_at (loc, "%qD is not a class type", decl); 3233 return error_mark_node; 3234 } 3235 3236 int cnt = 0; 3237 for (tree field = TYPE_FIELDS (type); 3238 (field = next_initializable_field (field)) != NULL_TREE; 3239 field = DECL_CHAIN (field)) 3240 { 3241 if (DECL_NAME (field) != NULL_TREE) 3242 { 3243 const char *n = IDENTIFIER_POINTER (DECL_NAME (field)); 3244 if (strcmp (n, "_M_file_name") == 0 3245 || strcmp (n, "_M_function_name") == 0) 3246 { 3247 if (TREE_TYPE (field) != const_string_type_node) 3248 { 3249 error_at (loc, "%qD does not have %<const char *%> type", 3250 field); 3251 return error_mark_node; 3252 } 3253 cnt++; 3254 continue; 3255 } 3256 else if (strcmp (n, "_M_line") == 0 || strcmp (n, "_M_column") == 0) 3257 { 3258 if (TREE_CODE (TREE_TYPE (field)) != INTEGER_TYPE) 3259 { 3260 error_at (loc, "%qD does not have integral type", field); 3261 return error_mark_node; 3262 } 3263 cnt++; 3264 continue; 3265 } 3266 } 3267 cnt = 0; 3268 break; 3269 } 3270 if (cnt != 4) 3271 { 3272 error_at (loc, "%<std::source_location::__impl%> does not contain only " 3273 "non-static data members %<_M_file_name%>, " 3274 "%<_M_function_name%>, %<_M_line%> and %<_M_column%>"); 3275 return error_mark_node; 3276 } 3277 return build_qualified_type (type, TYPE_QUAL_CONST); 3278} 3279 3280/* Type for source_location_table hash_set. */ 3281struct GTY((for_user)) source_location_table_entry { 3282 location_t loc; 3283 unsigned uid; 3284 tree var; 3285}; 3286 3287/* Traits class for function start hash maps below. */ 3288 3289struct source_location_table_entry_hash 3290 : ggc_remove <source_location_table_entry> 3291{ 3292 typedef source_location_table_entry value_type; 3293 typedef source_location_table_entry compare_type; 3294 3295 static hashval_t 3296 hash (const source_location_table_entry &ref) 3297 { 3298 inchash::hash hstate (0); 3299 hstate.add_int (ref.loc); 3300 hstate.add_int (ref.uid); 3301 return hstate.end (); 3302 } 3303 3304 static bool 3305 equal (const source_location_table_entry &ref1, 3306 const source_location_table_entry &ref2) 3307 { 3308 return ref1.loc == ref2.loc && ref1.uid == ref2.uid; 3309 } 3310 3311 static void 3312 mark_deleted (source_location_table_entry &ref) 3313 { 3314 ref.loc = UNKNOWN_LOCATION; 3315 ref.uid = -1U; 3316 ref.var = NULL_TREE; 3317 } 3318 3319 static const bool empty_zero_p = true; 3320 3321 static void 3322 mark_empty (source_location_table_entry &ref) 3323 { 3324 ref.loc = UNKNOWN_LOCATION; 3325 ref.uid = 0; 3326 ref.var = NULL_TREE; 3327 } 3328 3329 static bool 3330 is_deleted (const source_location_table_entry &ref) 3331 { 3332 return (ref.loc == UNKNOWN_LOCATION 3333 && ref.uid == -1U 3334 && ref.var == NULL_TREE); 3335 } 3336 3337 static bool 3338 is_empty (const source_location_table_entry &ref) 3339 { 3340 return (ref.loc == UNKNOWN_LOCATION 3341 && ref.uid == 0 3342 && ref.var == NULL_TREE); 3343 } 3344}; 3345 3346static GTY(()) hash_table <source_location_table_entry_hash> 3347 *source_location_table; 3348static GTY(()) unsigned int source_location_id; 3349 3350/* Fold __builtin_source_location () call. LOC is the location 3351 of the call. */ 3352 3353tree 3354fold_builtin_source_location (location_t loc) 3355{ 3356 if (source_location_impl == NULL_TREE) 3357 { 3358 auto_diagnostic_group d; 3359 source_location_impl = get_source_location_impl_type (loc); 3360 if (source_location_impl == error_mark_node) 3361 inform (loc, "evaluating %qs", "__builtin_source_location"); 3362 } 3363 if (source_location_impl == error_mark_node) 3364 return build_zero_cst (const_ptr_type_node); 3365 if (source_location_table == NULL) 3366 source_location_table 3367 = hash_table <source_location_table_entry_hash>::create_ggc (64); 3368 const line_map_ordinary *map; 3369 source_location_table_entry entry; 3370 entry.loc 3371 = linemap_resolve_location (line_table, loc, LRK_MACRO_EXPANSION_POINT, 3372 &map); 3373 entry.uid = current_function_decl ? DECL_UID (current_function_decl) : -1; 3374 entry.var = error_mark_node; 3375 source_location_table_entry *entryp 3376 = source_location_table->find_slot (entry, INSERT); 3377 tree var; 3378 if (entryp->var) 3379 var = entryp->var; 3380 else 3381 { 3382 char tmp_name[32]; 3383 ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lsrc_loc", source_location_id++); 3384 var = build_decl (loc, VAR_DECL, get_identifier (tmp_name), 3385 source_location_impl); 3386 TREE_STATIC (var) = 1; 3387 TREE_PUBLIC (var) = 0; 3388 DECL_ARTIFICIAL (var) = 1; 3389 DECL_IGNORED_P (var) = 1; 3390 DECL_EXTERNAL (var) = 0; 3391 DECL_DECLARED_CONSTEXPR_P (var) = 1; 3392 DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = 1; 3393 layout_decl (var, 0); 3394 3395 vec<constructor_elt, va_gc> *v = NULL; 3396 vec_alloc (v, 4); 3397 for (tree field = TYPE_FIELDS (source_location_impl); 3398 (field = next_initializable_field (field)) != NULL_TREE; 3399 field = DECL_CHAIN (field)) 3400 { 3401 const char *n = IDENTIFIER_POINTER (DECL_NAME (field)); 3402 tree val = NULL_TREE; 3403 if (strcmp (n, "_M_file_name") == 0) 3404 { 3405 if (const char *fname = LOCATION_FILE (loc)) 3406 { 3407 fname = remap_macro_filename (fname); 3408 val = build_string_literal (strlen (fname) + 1, fname); 3409 } 3410 else 3411 val = build_string_literal (1, ""); 3412 } 3413 else if (strcmp (n, "_M_function_name") == 0) 3414 { 3415 const char *name = ""; 3416 3417 if (current_function_decl) 3418 name = cxx_printable_name (current_function_decl, 0); 3419 3420 val = build_string_literal (strlen (name) + 1, name); 3421 } 3422 else if (strcmp (n, "_M_line") == 0) 3423 val = build_int_cst (TREE_TYPE (field), LOCATION_LINE (loc)); 3424 else if (strcmp (n, "_M_column") == 0) 3425 val = build_int_cst (TREE_TYPE (field), LOCATION_COLUMN (loc)); 3426 else 3427 gcc_unreachable (); 3428 CONSTRUCTOR_APPEND_ELT (v, field, val); 3429 } 3430 3431 tree ctor = build_constructor (source_location_impl, v); 3432 TREE_CONSTANT (ctor) = 1; 3433 TREE_STATIC (ctor) = 1; 3434 DECL_INITIAL (var) = ctor; 3435 varpool_node::finalize_decl (var); 3436 *entryp = entry; 3437 entryp->var = var; 3438 } 3439 3440 return build_fold_addr_expr_with_type_loc (loc, var, const_ptr_type_node); 3441} 3442 3443#include "gt-cp-cp-gimplify.h" 3444