1 /* Code translation -- generate GCC trees from gfc_code. 2 Copyright (C) 2002-2019 Free Software Foundation, Inc. 3 Contributed by Paul Brook 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 3, or (at your option) any later 10 version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 #include "options.h" 25 #include "tree.h" 26 #include "gfortran.h" 27 #include "gimple-expr.h" /* For create_tmp_var_raw. */ 28 #include "trans.h" 29 #include "stringpool.h" 30 #include "fold-const.h" 31 #include "tree-iterator.h" 32 #include "trans-stmt.h" 33 #include "trans-array.h" 34 #include "trans-types.h" 35 #include "trans-const.h" 36 37 /* Naming convention for backend interface code: 38 39 gfc_trans_* translate gfc_code into STMT trees. 40 41 gfc_conv_* expression conversion 42 43 gfc_get_* get a backend tree representation of a decl or type */ 44 45 static gfc_file *gfc_current_backend_file; 46 47 const char gfc_msg_fault[] = N_("Array reference out of bounds"); 48 const char gfc_msg_wrong_return[] = N_("Incorrect function return value"); 49 50 51 /* Advance along TREE_CHAIN n times. */ 52 53 tree 54 gfc_advance_chain (tree t, int n) 55 { 56 for (; n > 0; n--) 57 { 58 gcc_assert (t != NULL_TREE); 59 t = DECL_CHAIN (t); 60 } 61 return t; 62 } 63 64 /* Creates a variable declaration with a given TYPE. */ 65 66 tree 67 gfc_create_var_np (tree type, const char *prefix) 68 { 69 tree t; 70 71 t = create_tmp_var_raw (type, prefix); 72 73 /* No warnings for anonymous variables. */ 74 if (prefix == NULL) 75 TREE_NO_WARNING (t) = 1; 76 77 return t; 78 } 79 80 81 /* Like above, but also adds it to the current scope. */ 82 83 tree 84 gfc_create_var (tree type, const char *prefix) 85 { 86 tree tmp; 87 88 tmp = gfc_create_var_np (type, prefix); 89 90 pushdecl (tmp); 91 92 return tmp; 93 } 94 95 96 /* If the expression is not constant, evaluate it now. We assign the 97 result of the expression to an artificially created variable VAR, and 98 return a pointer to the VAR_DECL node for this variable. */ 99 100 tree 101 gfc_evaluate_now_loc (location_t loc, tree expr, stmtblock_t * pblock) 102 { 103 tree var; 104 105 if (CONSTANT_CLASS_P (expr)) 106 return expr; 107 108 var = gfc_create_var (TREE_TYPE (expr), NULL); 109 gfc_add_modify_loc (loc, pblock, var, expr); 110 111 return var; 112 } 113 114 115 tree 116 gfc_evaluate_now (tree expr, stmtblock_t * pblock) 117 { 118 return gfc_evaluate_now_loc (input_location, expr, pblock); 119 } 120 121 /* Like gfc_evaluate_now, but add the created variable to the 122 function scope. */ 123 124 tree 125 gfc_evaluate_now_function_scope (tree expr, stmtblock_t * pblock) 126 { 127 tree var; 128 var = gfc_create_var_np (TREE_TYPE (expr), NULL); 129 gfc_add_decl_to_function (var); 130 gfc_add_modify (pblock, var, expr); 131 132 return var; 133 } 134 135 /* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK. 136 A MODIFY_EXPR is an assignment: 137 LHS <- RHS. */ 138 139 void 140 gfc_add_modify_loc (location_t loc, stmtblock_t * pblock, tree lhs, tree rhs) 141 { 142 tree tmp; 143 144 tree t1, t2; 145 t1 = TREE_TYPE (rhs); 146 t2 = TREE_TYPE (lhs); 147 /* Make sure that the types of the rhs and the lhs are compatible 148 for scalar assignments. We should probably have something 149 similar for aggregates, but right now removing that check just 150 breaks everything. */ 151 gcc_checking_assert (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2) 152 || AGGREGATE_TYPE_P (TREE_TYPE (lhs))); 153 154 tmp = fold_build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, 155 rhs); 156 gfc_add_expr_to_block (pblock, tmp); 157 } 158 159 160 void 161 gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs) 162 { 163 gfc_add_modify_loc (input_location, pblock, lhs, rhs); 164 } 165 166 167 /* Create a new scope/binding level and initialize a block. Care must be 168 taken when translating expressions as any temporaries will be placed in 169 the innermost scope. */ 170 171 void 172 gfc_start_block (stmtblock_t * block) 173 { 174 /* Start a new binding level. */ 175 pushlevel (); 176 block->has_scope = 1; 177 178 /* The block is empty. */ 179 block->head = NULL_TREE; 180 } 181 182 183 /* Initialize a block without creating a new scope. */ 184 185 void 186 gfc_init_block (stmtblock_t * block) 187 { 188 block->head = NULL_TREE; 189 block->has_scope = 0; 190 } 191 192 193 /* Sometimes we create a scope but it turns out that we don't actually 194 need it. This function merges the scope of BLOCK with its parent. 195 Only variable decls will be merged, you still need to add the code. */ 196 197 void 198 gfc_merge_block_scope (stmtblock_t * block) 199 { 200 tree decl; 201 tree next; 202 203 gcc_assert (block->has_scope); 204 block->has_scope = 0; 205 206 /* Remember the decls in this scope. */ 207 decl = getdecls (); 208 poplevel (0, 0); 209 210 /* Add them to the parent scope. */ 211 while (decl != NULL_TREE) 212 { 213 next = DECL_CHAIN (decl); 214 DECL_CHAIN (decl) = NULL_TREE; 215 216 pushdecl (decl); 217 decl = next; 218 } 219 } 220 221 222 /* Finish a scope containing a block of statements. */ 223 224 tree 225 gfc_finish_block (stmtblock_t * stmtblock) 226 { 227 tree decl; 228 tree expr; 229 tree block; 230 231 expr = stmtblock->head; 232 if (!expr) 233 expr = build_empty_stmt (input_location); 234 235 stmtblock->head = NULL_TREE; 236 237 if (stmtblock->has_scope) 238 { 239 decl = getdecls (); 240 241 if (decl) 242 { 243 block = poplevel (1, 0); 244 expr = build3_v (BIND_EXPR, decl, expr, block); 245 } 246 else 247 poplevel (0, 0); 248 } 249 250 return expr; 251 } 252 253 254 /* Build an ADDR_EXPR and cast the result to TYPE. If TYPE is NULL, the 255 natural type is used. */ 256 257 tree 258 gfc_build_addr_expr (tree type, tree t) 259 { 260 tree base_type = TREE_TYPE (t); 261 tree natural_type; 262 263 if (type && POINTER_TYPE_P (type) 264 && TREE_CODE (base_type) == ARRAY_TYPE 265 && TYPE_MAIN_VARIANT (TREE_TYPE (type)) 266 == TYPE_MAIN_VARIANT (TREE_TYPE (base_type))) 267 { 268 tree min_val = size_zero_node; 269 tree type_domain = TYPE_DOMAIN (base_type); 270 if (type_domain && TYPE_MIN_VALUE (type_domain)) 271 min_val = TYPE_MIN_VALUE (type_domain); 272 t = fold (build4_loc (input_location, ARRAY_REF, TREE_TYPE (type), 273 t, min_val, NULL_TREE, NULL_TREE)); 274 natural_type = type; 275 } 276 else 277 natural_type = build_pointer_type (base_type); 278 279 if (TREE_CODE (t) == INDIRECT_REF) 280 { 281 if (!type) 282 type = natural_type; 283 t = TREE_OPERAND (t, 0); 284 natural_type = TREE_TYPE (t); 285 } 286 else 287 { 288 tree base = get_base_address (t); 289 if (base && DECL_P (base)) 290 TREE_ADDRESSABLE (base) = 1; 291 t = fold_build1_loc (input_location, ADDR_EXPR, natural_type, t); 292 } 293 294 if (type && natural_type != type) 295 t = convert (type, t); 296 297 return t; 298 } 299 300 301 static tree 302 get_array_span (tree type, tree decl) 303 { 304 tree span; 305 306 /* Component references are guaranteed to have a reliable value for 307 'span'. Likewise indirect references since they emerge from the 308 conversion of a CFI descriptor or the hidden dummy descriptor. */ 309 if (TREE_CODE (decl) == COMPONENT_REF 310 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) 311 return gfc_conv_descriptor_span_get (decl); 312 else if (TREE_CODE (decl) == INDIRECT_REF 313 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) 314 return gfc_conv_descriptor_span_get (decl); 315 316 /* Return the span for deferred character length array references. */ 317 if (type && TREE_CODE (type) == ARRAY_TYPE 318 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != NULL_TREE 319 && (VAR_P (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) 320 || TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == INDIRECT_REF) 321 && (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == INDIRECT_REF 322 || TREE_CODE (decl) == FUNCTION_DECL 323 || DECL_CONTEXT (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) 324 == DECL_CONTEXT (decl))) 325 { 326 span = fold_convert (gfc_array_index_type, 327 TYPE_MAX_VALUE (TYPE_DOMAIN (type))); 328 span = fold_build2 (MULT_EXPR, gfc_array_index_type, 329 fold_convert (gfc_array_index_type, 330 TYPE_SIZE_UNIT (TREE_TYPE (type))), 331 span); 332 } 333 else if (type && TREE_CODE (type) == ARRAY_TYPE 334 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != NULL_TREE 335 && integer_zerop (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))) 336 { 337 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) 338 span = gfc_conv_descriptor_span_get (decl); 339 else 340 span = NULL_TREE; 341 } 342 /* Likewise for class array or pointer array references. */ 343 else if (TREE_CODE (decl) == FIELD_DECL 344 || VAR_OR_FUNCTION_DECL_P (decl) 345 || TREE_CODE (decl) == PARM_DECL) 346 { 347 if (GFC_DECL_CLASS (decl)) 348 { 349 /* When a temporary is in place for the class array, then the 350 original class' declaration is stored in the saved 351 descriptor. */ 352 if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl)) 353 decl = GFC_DECL_SAVED_DESCRIPTOR (decl); 354 else 355 { 356 /* Allow for dummy arguments and other good things. */ 357 if (POINTER_TYPE_P (TREE_TYPE (decl))) 358 decl = build_fold_indirect_ref_loc (input_location, decl); 359 360 /* Check if '_data' is an array descriptor. If it is not, 361 the array must be one of the components of the class 362 object, so return a null span. */ 363 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE ( 364 gfc_class_data_get (decl)))) 365 return NULL_TREE; 366 } 367 span = gfc_class_vtab_size_get (decl); 368 } 369 else if (GFC_DECL_PTR_ARRAY_P (decl)) 370 { 371 if (TREE_CODE (decl) == PARM_DECL) 372 decl = build_fold_indirect_ref_loc (input_location, decl); 373 span = gfc_conv_descriptor_span_get (decl); 374 } 375 else 376 span = NULL_TREE; 377 } 378 else 379 span = NULL_TREE; 380 381 return span; 382 } 383 384 385 /* Build an ARRAY_REF with its natural type. */ 386 387 tree 388 gfc_build_array_ref (tree base, tree offset, tree decl, tree vptr) 389 { 390 tree type = TREE_TYPE (base); 391 tree tmp; 392 tree span = NULL_TREE; 393 394 if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0) 395 { 396 gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0); 397 398 return fold_convert (TYPE_MAIN_VARIANT (type), base); 399 } 400 401 /* Scalar coarray, there is nothing to do. */ 402 if (TREE_CODE (type) != ARRAY_TYPE) 403 { 404 gcc_assert (decl == NULL_TREE); 405 gcc_assert (integer_zerop (offset)); 406 return base; 407 } 408 409 type = TREE_TYPE (type); 410 411 if (DECL_P (base)) 412 TREE_ADDRESSABLE (base) = 1; 413 414 /* Strip NON_LVALUE_EXPR nodes. */ 415 STRIP_TYPE_NOPS (offset); 416 417 /* If decl or vptr are non-null, pointer arithmetic for the array reference 418 is likely. Generate the 'span' for the array reference. */ 419 if (vptr) 420 span = gfc_vptr_size_get (vptr); 421 else if (decl) 422 span = get_array_span (type, decl); 423 424 /* If a non-null span has been generated reference the element with 425 pointer arithmetic. */ 426 if (span != NULL_TREE) 427 { 428 offset = fold_build2_loc (input_location, MULT_EXPR, 429 gfc_array_index_type, 430 offset, span); 431 tmp = gfc_build_addr_expr (pvoid_type_node, base); 432 tmp = fold_build_pointer_plus_loc (input_location, tmp, offset); 433 tmp = fold_convert (build_pointer_type (type), tmp); 434 if (!TYPE_STRING_FLAG (type)) 435 tmp = build_fold_indirect_ref_loc (input_location, tmp); 436 return tmp; 437 } 438 /* Otherwise use a straightforward array reference. */ 439 else 440 return build4_loc (input_location, ARRAY_REF, type, base, offset, 441 NULL_TREE, NULL_TREE); 442 } 443 444 445 /* Generate a call to print a runtime error possibly including multiple 446 arguments and a locus. */ 447 448 static tree 449 trans_runtime_error_vararg (bool error, locus* where, const char* msgid, 450 va_list ap) 451 { 452 stmtblock_t block; 453 tree tmp; 454 tree arg, arg2; 455 tree *argarray; 456 tree fntype; 457 char *message; 458 const char *p; 459 int line, nargs, i; 460 location_t loc; 461 462 /* Compute the number of extra arguments from the format string. */ 463 for (p = msgid, nargs = 0; *p; p++) 464 if (*p == '%') 465 { 466 p++; 467 if (*p != '%') 468 nargs++; 469 } 470 471 /* The code to generate the error. */ 472 gfc_start_block (&block); 473 474 if (where) 475 { 476 line = LOCATION_LINE (where->lb->location); 477 message = xasprintf ("At line %d of file %s", line, 478 where->lb->file->filename); 479 } 480 else 481 message = xasprintf ("In file '%s', around line %d", 482 gfc_source_file, LOCATION_LINE (input_location) + 1); 483 484 arg = gfc_build_addr_expr (pchar_type_node, 485 gfc_build_localized_cstring_const (message)); 486 free (message); 487 488 message = xasprintf ("%s", _(msgid)); 489 arg2 = gfc_build_addr_expr (pchar_type_node, 490 gfc_build_localized_cstring_const (message)); 491 free (message); 492 493 /* Build the argument array. */ 494 argarray = XALLOCAVEC (tree, nargs + 2); 495 argarray[0] = arg; 496 argarray[1] = arg2; 497 for (i = 0; i < nargs; i++) 498 argarray[2 + i] = va_arg (ap, tree); 499 500 /* Build the function call to runtime_(warning,error)_at; because of the 501 variable number of arguments, we can't use build_call_expr_loc dinput_location, 502 irectly. */ 503 if (error) 504 fntype = TREE_TYPE (gfor_fndecl_runtime_error_at); 505 else 506 fntype = TREE_TYPE (gfor_fndecl_runtime_warning_at); 507 508 loc = where ? where->lb->location : input_location; 509 tmp = fold_build_call_array_loc (loc, TREE_TYPE (fntype), 510 fold_build1_loc (loc, ADDR_EXPR, 511 build_pointer_type (fntype), 512 error 513 ? gfor_fndecl_runtime_error_at 514 : gfor_fndecl_runtime_warning_at), 515 nargs + 2, argarray); 516 gfc_add_expr_to_block (&block, tmp); 517 518 return gfc_finish_block (&block); 519 } 520 521 522 tree 523 gfc_trans_runtime_error (bool error, locus* where, const char* msgid, ...) 524 { 525 va_list ap; 526 tree result; 527 528 va_start (ap, msgid); 529 result = trans_runtime_error_vararg (error, where, msgid, ap); 530 va_end (ap); 531 return result; 532 } 533 534 535 /* Generate a runtime error if COND is true. */ 536 537 void 538 gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock, 539 locus * where, const char * msgid, ...) 540 { 541 va_list ap; 542 stmtblock_t block; 543 tree body; 544 tree tmp; 545 tree tmpvar = NULL; 546 547 if (integer_zerop (cond)) 548 return; 549 550 if (once) 551 { 552 tmpvar = gfc_create_var (logical_type_node, "print_warning"); 553 TREE_STATIC (tmpvar) = 1; 554 DECL_INITIAL (tmpvar) = logical_true_node; 555 gfc_add_expr_to_block (pblock, tmpvar); 556 } 557 558 gfc_start_block (&block); 559 560 /* For error, runtime_error_at already implies PRED_NORETURN. */ 561 if (!error && once) 562 gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_WARN_ONCE, 563 NOT_TAKEN)); 564 565 /* The code to generate the error. */ 566 va_start (ap, msgid); 567 gfc_add_expr_to_block (&block, 568 trans_runtime_error_vararg (error, where, 569 msgid, ap)); 570 va_end (ap); 571 572 if (once) 573 gfc_add_modify (&block, tmpvar, logical_false_node); 574 575 body = gfc_finish_block (&block); 576 577 if (integer_onep (cond)) 578 { 579 gfc_add_expr_to_block (pblock, body); 580 } 581 else 582 { 583 if (once) 584 cond = fold_build2_loc (where->lb->location, TRUTH_AND_EXPR, 585 long_integer_type_node, tmpvar, cond); 586 else 587 cond = fold_convert (long_integer_type_node, cond); 588 589 tmp = fold_build3_loc (where->lb->location, COND_EXPR, void_type_node, 590 cond, body, 591 build_empty_stmt (where->lb->location)); 592 gfc_add_expr_to_block (pblock, tmp); 593 } 594 } 595 596 597 /* Call malloc to allocate size bytes of memory, with special conditions: 598 + if size == 0, return a malloced area of size 1, 599 + if malloc returns NULL, issue a runtime error. */ 600 tree 601 gfc_call_malloc (stmtblock_t * block, tree type, tree size) 602 { 603 tree tmp, msg, malloc_result, null_result, res, malloc_tree; 604 stmtblock_t block2; 605 606 /* Create a variable to hold the result. */ 607 res = gfc_create_var (prvoid_type_node, NULL); 608 609 /* Call malloc. */ 610 gfc_start_block (&block2); 611 612 size = fold_convert (size_type_node, size); 613 size = fold_build2_loc (input_location, MAX_EXPR, size_type_node, size, 614 build_int_cst (size_type_node, 1)); 615 616 malloc_tree = builtin_decl_explicit (BUILT_IN_MALLOC); 617 gfc_add_modify (&block2, res, 618 fold_convert (prvoid_type_node, 619 build_call_expr_loc (input_location, 620 malloc_tree, 1, size))); 621 622 /* Optionally check whether malloc was successful. */ 623 if (gfc_option.rtcheck & GFC_RTCHECK_MEM) 624 { 625 null_result = fold_build2_loc (input_location, EQ_EXPR, 626 logical_type_node, res, 627 build_int_cst (pvoid_type_node, 0)); 628 msg = gfc_build_addr_expr (pchar_type_node, 629 gfc_build_localized_cstring_const ("Memory allocation failed")); 630 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 631 null_result, 632 build_call_expr_loc (input_location, 633 gfor_fndecl_os_error, 1, msg), 634 build_empty_stmt (input_location)); 635 gfc_add_expr_to_block (&block2, tmp); 636 } 637 638 malloc_result = gfc_finish_block (&block2); 639 gfc_add_expr_to_block (block, malloc_result); 640 641 if (type != NULL) 642 res = fold_convert (type, res); 643 return res; 644 } 645 646 647 /* Allocate memory, using an optional status argument. 648 649 This function follows the following pseudo-code: 650 651 void * 652 allocate (size_t size, integer_type stat) 653 { 654 void *newmem; 655 656 if (stat requested) 657 stat = 0; 658 659 newmem = malloc (MAX (size, 1)); 660 if (newmem == NULL) 661 { 662 if (stat) 663 *stat = LIBERROR_ALLOCATION; 664 else 665 runtime_error ("Allocation would exceed memory limit"); 666 } 667 return newmem; 668 } */ 669 void 670 gfc_allocate_using_malloc (stmtblock_t * block, tree pointer, 671 tree size, tree status) 672 { 673 tree tmp, error_cond; 674 stmtblock_t on_error; 675 tree status_type = status ? TREE_TYPE (status) : NULL_TREE; 676 677 /* If successful and stat= is given, set status to 0. */ 678 if (status != NULL_TREE) 679 gfc_add_expr_to_block (block, 680 fold_build2_loc (input_location, MODIFY_EXPR, status_type, 681 status, build_int_cst (status_type, 0))); 682 683 /* The allocation itself. */ 684 size = fold_convert (size_type_node, size); 685 gfc_add_modify (block, pointer, 686 fold_convert (TREE_TYPE (pointer), 687 build_call_expr_loc (input_location, 688 builtin_decl_explicit (BUILT_IN_MALLOC), 1, 689 fold_build2_loc (input_location, 690 MAX_EXPR, size_type_node, size, 691 build_int_cst (size_type_node, 1))))); 692 693 /* What to do in case of error. */ 694 gfc_start_block (&on_error); 695 if (status != NULL_TREE) 696 { 697 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, status, 698 build_int_cst (status_type, LIBERROR_ALLOCATION)); 699 gfc_add_expr_to_block (&on_error, tmp); 700 } 701 else 702 { 703 /* Here, os_error already implies PRED_NORETURN. */ 704 tmp = build_call_expr_loc (input_location, gfor_fndecl_os_error, 1, 705 gfc_build_addr_expr (pchar_type_node, 706 gfc_build_localized_cstring_const 707 ("Allocation would exceed memory limit"))); 708 gfc_add_expr_to_block (&on_error, tmp); 709 } 710 711 error_cond = fold_build2_loc (input_location, EQ_EXPR, 712 logical_type_node, pointer, 713 build_int_cst (prvoid_type_node, 0)); 714 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 715 gfc_unlikely (error_cond, PRED_FORTRAN_FAIL_ALLOC), 716 gfc_finish_block (&on_error), 717 build_empty_stmt (input_location)); 718 719 gfc_add_expr_to_block (block, tmp); 720 } 721 722 723 /* Allocate memory, using an optional status argument. 724 725 This function follows the following pseudo-code: 726 727 void * 728 allocate (size_t size, void** token, int *stat, char* errmsg, int errlen) 729 { 730 void *newmem; 731 732 newmem = _caf_register (size, regtype, token, &stat, errmsg, errlen); 733 return newmem; 734 } */ 735 void 736 gfc_allocate_using_caf_lib (stmtblock_t * block, tree pointer, tree size, 737 tree token, tree status, tree errmsg, tree errlen, 738 gfc_coarray_regtype alloc_type) 739 { 740 tree tmp, pstat; 741 742 gcc_assert (token != NULL_TREE); 743 744 /* The allocation itself. */ 745 if (status == NULL_TREE) 746 pstat = null_pointer_node; 747 else 748 pstat = gfc_build_addr_expr (NULL_TREE, status); 749 750 if (errmsg == NULL_TREE) 751 { 752 gcc_assert(errlen == NULL_TREE); 753 errmsg = null_pointer_node; 754 errlen = build_int_cst (integer_type_node, 0); 755 } 756 757 size = fold_convert (size_type_node, size); 758 tmp = build_call_expr_loc (input_location, 759 gfor_fndecl_caf_register, 7, 760 fold_build2_loc (input_location, 761 MAX_EXPR, size_type_node, size, size_one_node), 762 build_int_cst (integer_type_node, alloc_type), 763 token, gfc_build_addr_expr (pvoid_type_node, pointer), 764 pstat, errmsg, errlen); 765 766 gfc_add_expr_to_block (block, tmp); 767 768 /* It guarantees memory consistency within the same segment */ 769 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"), 770 tmp = build5_loc (input_location, ASM_EXPR, void_type_node, 771 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE, 772 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE); 773 ASM_VOLATILE_P (tmp) = 1; 774 gfc_add_expr_to_block (block, tmp); 775 } 776 777 778 /* Generate code for an ALLOCATE statement when the argument is an 779 allocatable variable. If the variable is currently allocated, it is an 780 error to allocate it again. 781 782 This function follows the following pseudo-code: 783 784 void * 785 allocate_allocatable (void *mem, size_t size, integer_type stat) 786 { 787 if (mem == NULL) 788 return allocate (size, stat); 789 else 790 { 791 if (stat) 792 stat = LIBERROR_ALLOCATION; 793 else 794 runtime_error ("Attempting to allocate already allocated variable"); 795 } 796 } 797 798 expr must be set to the original expression being allocated for its locus 799 and variable name in case a runtime error has to be printed. */ 800 void 801 gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size, 802 tree token, tree status, tree errmsg, tree errlen, 803 tree label_finish, gfc_expr* expr, int corank) 804 { 805 stmtblock_t alloc_block; 806 tree tmp, null_mem, alloc, error; 807 tree type = TREE_TYPE (mem); 808 symbol_attribute caf_attr; 809 bool need_assign = false, refs_comp = false; 810 gfc_coarray_regtype caf_alloc_type = GFC_CAF_COARRAY_ALLOC; 811 812 size = fold_convert (size_type_node, size); 813 null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR, 814 logical_type_node, mem, 815 build_int_cst (type, 0)), 816 PRED_FORTRAN_REALLOC); 817 818 /* If mem is NULL, we call gfc_allocate_using_malloc or 819 gfc_allocate_using_lib. */ 820 gfc_start_block (&alloc_block); 821 822 if (flag_coarray == GFC_FCOARRAY_LIB) 823 caf_attr = gfc_caf_attr (expr, true, &refs_comp); 824 825 if (flag_coarray == GFC_FCOARRAY_LIB 826 && (corank > 0 || caf_attr.codimension)) 827 { 828 tree cond, sub_caf_tree; 829 gfc_se se; 830 bool compute_special_caf_types_size = false; 831 832 if (expr->ts.type == BT_DERIVED 833 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV 834 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE) 835 { 836 compute_special_caf_types_size = true; 837 caf_alloc_type = GFC_CAF_LOCK_ALLOC; 838 } 839 else if (expr->ts.type == BT_DERIVED 840 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV 841 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE) 842 { 843 compute_special_caf_types_size = true; 844 caf_alloc_type = GFC_CAF_EVENT_ALLOC; 845 } 846 else if (!caf_attr.coarray_comp && refs_comp) 847 /* Only allocatable components in a derived type coarray can be 848 allocate only. */ 849 caf_alloc_type = GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY; 850 851 gfc_init_se (&se, NULL); 852 sub_caf_tree = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr); 853 if (sub_caf_tree == NULL_TREE) 854 sub_caf_tree = token; 855 856 /* When mem is an array ref, then strip the .data-ref. */ 857 if (TREE_CODE (mem) == COMPONENT_REF 858 && !(GFC_ARRAY_TYPE_P (TREE_TYPE (mem)))) 859 tmp = TREE_OPERAND (mem, 0); 860 else 861 tmp = mem; 862 863 if (!(GFC_ARRAY_TYPE_P (TREE_TYPE (tmp)) 864 && TYPE_LANG_SPECIFIC (TREE_TYPE (tmp))->corank == 0) 865 && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp))) 866 { 867 symbol_attribute attr; 868 869 gfc_clear_attr (&attr); 870 tmp = gfc_conv_scalar_to_descriptor (&se, mem, attr); 871 need_assign = true; 872 } 873 gfc_add_block_to_block (&alloc_block, &se.pre); 874 875 /* In the front end, we represent the lock variable as pointer. However, 876 the FE only passes the pointer around and leaves the actual 877 representation to the library. Hence, we have to convert back to the 878 number of elements. */ 879 if (compute_special_caf_types_size) 880 size = fold_build2_loc (input_location, TRUNC_DIV_EXPR, size_type_node, 881 size, TYPE_SIZE_UNIT (ptr_type_node)); 882 883 gfc_allocate_using_caf_lib (&alloc_block, tmp, size, sub_caf_tree, 884 status, errmsg, errlen, caf_alloc_type); 885 if (need_assign) 886 gfc_add_modify (&alloc_block, mem, fold_convert (TREE_TYPE (mem), 887 gfc_conv_descriptor_data_get (tmp))); 888 if (status != NULL_TREE) 889 { 890 TREE_USED (label_finish) = 1; 891 tmp = build1_v (GOTO_EXPR, label_finish); 892 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 893 status, build_zero_cst (TREE_TYPE (status))); 894 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 895 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), 896 tmp, build_empty_stmt (input_location)); 897 gfc_add_expr_to_block (&alloc_block, tmp); 898 } 899 } 900 else 901 gfc_allocate_using_malloc (&alloc_block, mem, size, status); 902 903 alloc = gfc_finish_block (&alloc_block); 904 905 /* If mem is not NULL, we issue a runtime error or set the 906 status variable. */ 907 if (expr) 908 { 909 tree varname; 910 911 gcc_assert (expr->expr_type == EXPR_VARIABLE && expr->symtree); 912 varname = gfc_build_cstring_const (expr->symtree->name); 913 varname = gfc_build_addr_expr (pchar_type_node, varname); 914 915 error = gfc_trans_runtime_error (true, &expr->where, 916 "Attempting to allocate already" 917 " allocated variable '%s'", 918 varname); 919 } 920 else 921 error = gfc_trans_runtime_error (true, NULL, 922 "Attempting to allocate already allocated" 923 " variable"); 924 925 if (status != NULL_TREE) 926 { 927 tree status_type = TREE_TYPE (status); 928 929 error = fold_build2_loc (input_location, MODIFY_EXPR, status_type, 930 status, build_int_cst (status_type, LIBERROR_ALLOCATION)); 931 } 932 933 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem, 934 error, alloc); 935 gfc_add_expr_to_block (block, tmp); 936 } 937 938 939 /* Free a given variable. */ 940 941 tree 942 gfc_call_free (tree var) 943 { 944 return build_call_expr_loc (input_location, 945 builtin_decl_explicit (BUILT_IN_FREE), 946 1, fold_convert (pvoid_type_node, var)); 947 } 948 949 950 /* Build a call to a FINAL procedure, which finalizes "var". */ 951 952 static tree 953 gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var, 954 bool fini_coarray, gfc_expr *class_size) 955 { 956 stmtblock_t block; 957 gfc_se se; 958 tree final_fndecl, array, size, tmp; 959 symbol_attribute attr; 960 961 gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE); 962 gcc_assert (var); 963 964 gfc_start_block (&block); 965 gfc_init_se (&se, NULL); 966 gfc_conv_expr (&se, final_wrapper); 967 final_fndecl = se.expr; 968 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl))) 969 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl); 970 971 if (ts.type == BT_DERIVED) 972 { 973 tree elem_size; 974 975 gcc_assert (!class_size); 976 elem_size = gfc_typenode_for_spec (&ts); 977 elem_size = TYPE_SIZE_UNIT (elem_size); 978 size = fold_convert (gfc_array_index_type, elem_size); 979 980 gfc_init_se (&se, NULL); 981 se.want_pointer = 1; 982 if (var->rank) 983 { 984 se.descriptor_only = 1; 985 gfc_conv_expr_descriptor (&se, var); 986 array = se.expr; 987 } 988 else 989 { 990 gfc_conv_expr (&se, var); 991 gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE); 992 array = se.expr; 993 994 /* No copy back needed, hence set attr's allocatable/pointer 995 to zero. */ 996 gfc_clear_attr (&attr); 997 gfc_init_se (&se, NULL); 998 array = gfc_conv_scalar_to_descriptor (&se, array, attr); 999 gcc_assert (se.post.head == NULL_TREE); 1000 } 1001 } 1002 else 1003 { 1004 gfc_expr *array_expr; 1005 gcc_assert (class_size); 1006 gfc_init_se (&se, NULL); 1007 gfc_conv_expr (&se, class_size); 1008 gfc_add_block_to_block (&block, &se.pre); 1009 gcc_assert (se.post.head == NULL_TREE); 1010 size = se.expr; 1011 1012 array_expr = gfc_copy_expr (var); 1013 gfc_init_se (&se, NULL); 1014 se.want_pointer = 1; 1015 if (array_expr->rank) 1016 { 1017 gfc_add_class_array_ref (array_expr); 1018 se.descriptor_only = 1; 1019 gfc_conv_expr_descriptor (&se, array_expr); 1020 array = se.expr; 1021 } 1022 else 1023 { 1024 gfc_add_data_component (array_expr); 1025 gfc_conv_expr (&se, array_expr); 1026 gfc_add_block_to_block (&block, &se.pre); 1027 gcc_assert (se.post.head == NULL_TREE); 1028 array = se.expr; 1029 if (TREE_CODE (array) == ADDR_EXPR 1030 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (array, 0)))) 1031 tmp = TREE_OPERAND (array, 0); 1032 1033 if (!gfc_is_coarray (array_expr)) 1034 { 1035 /* No copy back needed, hence set attr's allocatable/pointer 1036 to zero. */ 1037 gfc_clear_attr (&attr); 1038 gfc_init_se (&se, NULL); 1039 array = gfc_conv_scalar_to_descriptor (&se, array, attr); 1040 } 1041 gcc_assert (se.post.head == NULL_TREE); 1042 } 1043 gfc_free_expr (array_expr); 1044 } 1045 1046 if (!POINTER_TYPE_P (TREE_TYPE (array))) 1047 array = gfc_build_addr_expr (NULL, array); 1048 1049 gfc_add_block_to_block (&block, &se.pre); 1050 tmp = build_call_expr_loc (input_location, 1051 final_fndecl, 3, array, 1052 size, fini_coarray ? boolean_true_node 1053 : boolean_false_node); 1054 gfc_add_block_to_block (&block, &se.post); 1055 gfc_add_expr_to_block (&block, tmp); 1056 return gfc_finish_block (&block); 1057 } 1058 1059 1060 bool 1061 gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp, 1062 bool fini_coarray) 1063 { 1064 gfc_se se; 1065 stmtblock_t block2; 1066 tree final_fndecl, size, array, tmp, cond; 1067 symbol_attribute attr; 1068 gfc_expr *final_expr = NULL; 1069 1070 if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS) 1071 return false; 1072 1073 gfc_init_block (&block2); 1074 1075 if (comp->ts.type == BT_DERIVED) 1076 { 1077 if (comp->attr.pointer) 1078 return false; 1079 1080 gfc_is_finalizable (comp->ts.u.derived, &final_expr); 1081 if (!final_expr) 1082 return false; 1083 1084 gfc_init_se (&se, NULL); 1085 gfc_conv_expr (&se, final_expr); 1086 final_fndecl = se.expr; 1087 size = gfc_typenode_for_spec (&comp->ts); 1088 size = TYPE_SIZE_UNIT (size); 1089 size = fold_convert (gfc_array_index_type, size); 1090 1091 array = decl; 1092 } 1093 else /* comp->ts.type == BT_CLASS. */ 1094 { 1095 if (CLASS_DATA (comp)->attr.class_pointer) 1096 return false; 1097 1098 gfc_is_finalizable (CLASS_DATA (comp)->ts.u.derived, &final_expr); 1099 final_fndecl = gfc_class_vtab_final_get (decl); 1100 size = gfc_class_vtab_size_get (decl); 1101 array = gfc_class_data_get (decl); 1102 } 1103 1104 if (comp->attr.allocatable 1105 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)->attr.allocatable)) 1106 { 1107 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array)) 1108 ? gfc_conv_descriptor_data_get (array) : array; 1109 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 1110 tmp, fold_convert (TREE_TYPE (tmp), 1111 null_pointer_node)); 1112 } 1113 else 1114 cond = logical_true_node; 1115 1116 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))) 1117 { 1118 gfc_clear_attr (&attr); 1119 gfc_init_se (&se, NULL); 1120 array = gfc_conv_scalar_to_descriptor (&se, array, attr); 1121 gfc_add_block_to_block (&block2, &se.pre); 1122 gcc_assert (se.post.head == NULL_TREE); 1123 } 1124 1125 if (!POINTER_TYPE_P (TREE_TYPE (array))) 1126 array = gfc_build_addr_expr (NULL, array); 1127 1128 if (!final_expr) 1129 { 1130 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 1131 final_fndecl, 1132 fold_convert (TREE_TYPE (final_fndecl), 1133 null_pointer_node)); 1134 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR, 1135 logical_type_node, cond, tmp); 1136 } 1137 1138 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl))) 1139 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl); 1140 1141 tmp = build_call_expr_loc (input_location, 1142 final_fndecl, 3, array, 1143 size, fini_coarray ? boolean_true_node 1144 : boolean_false_node); 1145 gfc_add_expr_to_block (&block2, tmp); 1146 tmp = gfc_finish_block (&block2); 1147 1148 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp, 1149 build_empty_stmt (input_location)); 1150 gfc_add_expr_to_block (block, tmp); 1151 1152 return true; 1153 } 1154 1155 1156 /* Add a call to the finalizer, using the passed *expr. Returns 1157 true when a finalizer call has been inserted. */ 1158 1159 bool 1160 gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) 1161 { 1162 tree tmp; 1163 gfc_ref *ref; 1164 gfc_expr *expr; 1165 gfc_expr *final_expr = NULL; 1166 gfc_expr *elem_size = NULL; 1167 bool has_finalizer = false; 1168 1169 if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS)) 1170 return false; 1171 1172 if (expr2->ts.type == BT_DERIVED) 1173 { 1174 gfc_is_finalizable (expr2->ts.u.derived, &final_expr); 1175 if (!final_expr) 1176 return false; 1177 } 1178 1179 /* If we have a class array, we need go back to the class 1180 container. */ 1181 expr = gfc_copy_expr (expr2); 1182 1183 if (expr->ref && expr->ref->next && !expr->ref->next->next 1184 && expr->ref->next->type == REF_ARRAY 1185 && expr->ref->type == REF_COMPONENT 1186 && strcmp (expr->ref->u.c.component->name, "_data") == 0) 1187 { 1188 gfc_free_ref_list (expr->ref); 1189 expr->ref = NULL; 1190 } 1191 else 1192 for (ref = expr->ref; ref; ref = ref->next) 1193 if (ref->next && ref->next->next && !ref->next->next->next 1194 && ref->next->next->type == REF_ARRAY 1195 && ref->next->type == REF_COMPONENT 1196 && strcmp (ref->next->u.c.component->name, "_data") == 0) 1197 { 1198 gfc_free_ref_list (ref->next); 1199 ref->next = NULL; 1200 } 1201 1202 if (expr->ts.type == BT_CLASS) 1203 { 1204 has_finalizer = gfc_is_finalizable (expr->ts.u.derived, NULL); 1205 1206 if (!expr2->rank && !expr2->ref && CLASS_DATA (expr2->symtree->n.sym)->as) 1207 expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank; 1208 1209 final_expr = gfc_copy_expr (expr); 1210 gfc_add_vptr_component (final_expr); 1211 gfc_add_final_component (final_expr); 1212 1213 elem_size = gfc_copy_expr (expr); 1214 gfc_add_vptr_component (elem_size); 1215 gfc_add_size_component (elem_size); 1216 } 1217 1218 gcc_assert (final_expr->expr_type == EXPR_VARIABLE); 1219 1220 tmp = gfc_build_final_call (expr->ts, final_expr, expr, 1221 false, elem_size); 1222 1223 if (expr->ts.type == BT_CLASS && !has_finalizer) 1224 { 1225 tree cond; 1226 gfc_se se; 1227 1228 gfc_init_se (&se, NULL); 1229 se.want_pointer = 1; 1230 gfc_conv_expr (&se, final_expr); 1231 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 1232 se.expr, build_int_cst (TREE_TYPE (se.expr), 0)); 1233 1234 /* For CLASS(*) not only sym->_vtab->_final can be NULL 1235 but already sym->_vtab itself. */ 1236 if (UNLIMITED_POLY (expr)) 1237 { 1238 tree cond2; 1239 gfc_expr *vptr_expr; 1240 1241 vptr_expr = gfc_copy_expr (expr); 1242 gfc_add_vptr_component (vptr_expr); 1243 1244 gfc_init_se (&se, NULL); 1245 se.want_pointer = 1; 1246 gfc_conv_expr (&se, vptr_expr); 1247 gfc_free_expr (vptr_expr); 1248 1249 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 1250 se.expr, 1251 build_int_cst (TREE_TYPE (se.expr), 0)); 1252 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR, 1253 logical_type_node, cond2, cond); 1254 } 1255 1256 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 1257 cond, tmp, build_empty_stmt (input_location)); 1258 } 1259 1260 gfc_add_expr_to_block (block, tmp); 1261 1262 return true; 1263 } 1264 1265 1266 /* User-deallocate; we emit the code directly from the front-end, and the 1267 logic is the same as the previous library function: 1268 1269 void 1270 deallocate (void *pointer, GFC_INTEGER_4 * stat) 1271 { 1272 if (!pointer) 1273 { 1274 if (stat) 1275 *stat = 1; 1276 else 1277 runtime_error ("Attempt to DEALLOCATE unallocated memory."); 1278 } 1279 else 1280 { 1281 free (pointer); 1282 if (stat) 1283 *stat = 0; 1284 } 1285 } 1286 1287 In this front-end version, status doesn't have to be GFC_INTEGER_4. 1288 Moreover, if CAN_FAIL is true, then we will not emit a runtime error, 1289 even when no status variable is passed to us (this is used for 1290 unconditional deallocation generated by the front-end at end of 1291 each procedure). 1292 1293 If a runtime-message is possible, `expr' must point to the original 1294 expression being deallocated for its locus and variable name. 1295 1296 For coarrays, "pointer" must be the array descriptor and not its 1297 "data" component. 1298 1299 COARRAY_DEALLOC_MODE gives the mode unregister coarrays. Available modes are 1300 the ones of GFC_CAF_DEREGTYPE, -1 when the mode for deregistration is to be 1301 analyzed and set by this routine, and -2 to indicate that a non-coarray is to 1302 be deallocated. */ 1303 tree 1304 gfc_deallocate_with_status (tree pointer, tree status, tree errmsg, 1305 tree errlen, tree label_finish, 1306 bool can_fail, gfc_expr* expr, 1307 int coarray_dealloc_mode, tree add_when_allocated, 1308 tree caf_token) 1309 { 1310 stmtblock_t null, non_null; 1311 tree cond, tmp, error; 1312 tree status_type = NULL_TREE; 1313 tree token = NULL_TREE; 1314 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER; 1315 1316 if (coarray_dealloc_mode >= GFC_CAF_COARRAY_ANALYZE) 1317 { 1318 if (flag_coarray == GFC_FCOARRAY_LIB) 1319 { 1320 if (caf_token) 1321 token = caf_token; 1322 else 1323 { 1324 tree caf_type, caf_decl = pointer; 1325 pointer = gfc_conv_descriptor_data_get (caf_decl); 1326 caf_type = TREE_TYPE (caf_decl); 1327 STRIP_NOPS (pointer); 1328 if (GFC_DESCRIPTOR_TYPE_P (caf_type)) 1329 token = gfc_conv_descriptor_token (caf_decl); 1330 else if (DECL_LANG_SPECIFIC (caf_decl) 1331 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE) 1332 token = GFC_DECL_TOKEN (caf_decl); 1333 else 1334 { 1335 gcc_assert (GFC_ARRAY_TYPE_P (caf_type) 1336 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) 1337 != NULL_TREE); 1338 token = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type); 1339 } 1340 } 1341 1342 if (coarray_dealloc_mode == GFC_CAF_COARRAY_ANALYZE) 1343 { 1344 bool comp_ref; 1345 if (expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp 1346 && comp_ref) 1347 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY; 1348 // else do a deregister as set by default. 1349 } 1350 else 1351 caf_dereg_type = (enum gfc_coarray_deregtype) coarray_dealloc_mode; 1352 } 1353 else if (flag_coarray == GFC_FCOARRAY_SINGLE) 1354 pointer = gfc_conv_descriptor_data_get (pointer); 1355 } 1356 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer))) 1357 pointer = gfc_conv_descriptor_data_get (pointer); 1358 1359 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer, 1360 build_int_cst (TREE_TYPE (pointer), 0)); 1361 1362 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise 1363 we emit a runtime error. */ 1364 gfc_start_block (&null); 1365 if (!can_fail) 1366 { 1367 tree varname; 1368 1369 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree); 1370 1371 varname = gfc_build_cstring_const (expr->symtree->name); 1372 varname = gfc_build_addr_expr (pchar_type_node, varname); 1373 1374 error = gfc_trans_runtime_error (true, &expr->where, 1375 "Attempt to DEALLOCATE unallocated '%s'", 1376 varname); 1377 } 1378 else 1379 error = build_empty_stmt (input_location); 1380 1381 if (status != NULL_TREE && !integer_zerop (status)) 1382 { 1383 tree cond2; 1384 1385 status_type = TREE_TYPE (TREE_TYPE (status)); 1386 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 1387 status, build_int_cst (TREE_TYPE (status), 0)); 1388 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, 1389 fold_build1_loc (input_location, INDIRECT_REF, 1390 status_type, status), 1391 build_int_cst (status_type, 1)); 1392 error = fold_build3_loc (input_location, COND_EXPR, void_type_node, 1393 cond2, tmp, error); 1394 } 1395 1396 gfc_add_expr_to_block (&null, error); 1397 1398 /* When POINTER is not NULL, we free it. */ 1399 gfc_start_block (&non_null); 1400 if (add_when_allocated) 1401 gfc_add_expr_to_block (&non_null, add_when_allocated); 1402 gfc_add_finalizer_call (&non_null, expr); 1403 if (coarray_dealloc_mode == GFC_CAF_COARRAY_NOCOARRAY 1404 || flag_coarray != GFC_FCOARRAY_LIB) 1405 { 1406 tmp = build_call_expr_loc (input_location, 1407 builtin_decl_explicit (BUILT_IN_FREE), 1, 1408 fold_convert (pvoid_type_node, pointer)); 1409 gfc_add_expr_to_block (&non_null, tmp); 1410 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer), 1411 0)); 1412 1413 if (status != NULL_TREE && !integer_zerop (status)) 1414 { 1415 /* We set STATUS to zero if it is present. */ 1416 tree status_type = TREE_TYPE (TREE_TYPE (status)); 1417 tree cond2; 1418 1419 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 1420 status, 1421 build_int_cst (TREE_TYPE (status), 0)); 1422 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, 1423 fold_build1_loc (input_location, INDIRECT_REF, 1424 status_type, status), 1425 build_int_cst (status_type, 0)); 1426 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 1427 gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC), 1428 tmp, build_empty_stmt (input_location)); 1429 gfc_add_expr_to_block (&non_null, tmp); 1430 } 1431 } 1432 else 1433 { 1434 tree cond2, pstat = null_pointer_node; 1435 1436 if (errmsg == NULL_TREE) 1437 { 1438 gcc_assert (errlen == NULL_TREE); 1439 errmsg = null_pointer_node; 1440 errlen = build_zero_cst (integer_type_node); 1441 } 1442 else 1443 { 1444 gcc_assert (errlen != NULL_TREE); 1445 if (!POINTER_TYPE_P (TREE_TYPE (errmsg))) 1446 errmsg = gfc_build_addr_expr (NULL_TREE, errmsg); 1447 } 1448 1449 if (status != NULL_TREE && !integer_zerop (status)) 1450 { 1451 gcc_assert (status_type == integer_type_node); 1452 pstat = status; 1453 } 1454 1455 token = gfc_build_addr_expr (NULL_TREE, token); 1456 gcc_assert (caf_dereg_type > GFC_CAF_COARRAY_ANALYZE); 1457 tmp = build_call_expr_loc (input_location, 1458 gfor_fndecl_caf_deregister, 5, 1459 token, build_int_cst (integer_type_node, 1460 caf_dereg_type), 1461 pstat, errmsg, errlen); 1462 gfc_add_expr_to_block (&non_null, tmp); 1463 1464 /* It guarantees memory consistency within the same segment */ 1465 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"), 1466 tmp = build5_loc (input_location, ASM_EXPR, void_type_node, 1467 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE, 1468 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE); 1469 ASM_VOLATILE_P (tmp) = 1; 1470 gfc_add_expr_to_block (&non_null, tmp); 1471 1472 if (status != NULL_TREE) 1473 { 1474 tree stat = build_fold_indirect_ref_loc (input_location, status); 1475 tree nullify = fold_build2_loc (input_location, MODIFY_EXPR, 1476 void_type_node, pointer, 1477 build_int_cst (TREE_TYPE (pointer), 1478 0)); 1479 1480 TREE_USED (label_finish) = 1; 1481 tmp = build1_v (GOTO_EXPR, label_finish); 1482 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 1483 stat, build_zero_cst (TREE_TYPE (stat))); 1484 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 1485 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC), 1486 tmp, nullify); 1487 gfc_add_expr_to_block (&non_null, tmp); 1488 } 1489 else 1490 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer), 1491 0)); 1492 } 1493 1494 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, 1495 gfc_finish_block (&null), 1496 gfc_finish_block (&non_null)); 1497 } 1498 1499 1500 /* Generate code for deallocation of allocatable scalars (variables or 1501 components). Before the object itself is freed, any allocatable 1502 subcomponents are being deallocated. */ 1503 1504 tree 1505 gfc_deallocate_scalar_with_status (tree pointer, tree status, tree label_finish, 1506 bool can_fail, gfc_expr* expr, 1507 gfc_typespec ts, bool coarray) 1508 { 1509 stmtblock_t null, non_null; 1510 tree cond, tmp, error; 1511 bool finalizable, comp_ref; 1512 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER; 1513 1514 if (coarray && expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp 1515 && comp_ref) 1516 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY; 1517 1518 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer, 1519 build_int_cst (TREE_TYPE (pointer), 0)); 1520 1521 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise 1522 we emit a runtime error. */ 1523 gfc_start_block (&null); 1524 if (!can_fail) 1525 { 1526 tree varname; 1527 1528 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree); 1529 1530 varname = gfc_build_cstring_const (expr->symtree->name); 1531 varname = gfc_build_addr_expr (pchar_type_node, varname); 1532 1533 error = gfc_trans_runtime_error (true, &expr->where, 1534 "Attempt to DEALLOCATE unallocated '%s'", 1535 varname); 1536 } 1537 else 1538 error = build_empty_stmt (input_location); 1539 1540 if (status != NULL_TREE && !integer_zerop (status)) 1541 { 1542 tree status_type = TREE_TYPE (TREE_TYPE (status)); 1543 tree cond2; 1544 1545 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 1546 status, build_int_cst (TREE_TYPE (status), 0)); 1547 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, 1548 fold_build1_loc (input_location, INDIRECT_REF, 1549 status_type, status), 1550 build_int_cst (status_type, 1)); 1551 error = fold_build3_loc (input_location, COND_EXPR, void_type_node, 1552 cond2, tmp, error); 1553 } 1554 gfc_add_expr_to_block (&null, error); 1555 1556 /* When POINTER is not NULL, we free it. */ 1557 gfc_start_block (&non_null); 1558 1559 /* Free allocatable components. */ 1560 finalizable = gfc_add_finalizer_call (&non_null, expr); 1561 if (!finalizable && ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp) 1562 { 1563 int caf_mode = coarray 1564 ? ((caf_dereg_type == GFC_CAF_COARRAY_DEALLOCATE_ONLY 1565 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0) 1566 | GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY 1567 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) 1568 : 0; 1569 if (coarray && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer))) 1570 tmp = gfc_conv_descriptor_data_get (pointer); 1571 else 1572 tmp = build_fold_indirect_ref_loc (input_location, pointer); 1573 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0, caf_mode); 1574 gfc_add_expr_to_block (&non_null, tmp); 1575 } 1576 1577 if (!coarray || flag_coarray == GFC_FCOARRAY_SINGLE) 1578 { 1579 tmp = build_call_expr_loc (input_location, 1580 builtin_decl_explicit (BUILT_IN_FREE), 1, 1581 fold_convert (pvoid_type_node, pointer)); 1582 gfc_add_expr_to_block (&non_null, tmp); 1583 1584 if (status != NULL_TREE && !integer_zerop (status)) 1585 { 1586 /* We set STATUS to zero if it is present. */ 1587 tree status_type = TREE_TYPE (TREE_TYPE (status)); 1588 tree cond2; 1589 1590 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 1591 status, 1592 build_int_cst (TREE_TYPE (status), 0)); 1593 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, 1594 fold_build1_loc (input_location, INDIRECT_REF, 1595 status_type, status), 1596 build_int_cst (status_type, 0)); 1597 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 1598 cond2, tmp, build_empty_stmt (input_location)); 1599 gfc_add_expr_to_block (&non_null, tmp); 1600 } 1601 } 1602 else 1603 { 1604 tree token; 1605 tree pstat = null_pointer_node; 1606 gfc_se se; 1607 1608 gfc_init_se (&se, NULL); 1609 token = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr); 1610 gcc_assert (token != NULL_TREE); 1611 1612 if (status != NULL_TREE && !integer_zerop (status)) 1613 { 1614 gcc_assert (TREE_TYPE (TREE_TYPE (status)) == integer_type_node); 1615 pstat = status; 1616 } 1617 1618 tmp = build_call_expr_loc (input_location, 1619 gfor_fndecl_caf_deregister, 5, 1620 token, build_int_cst (integer_type_node, 1621 caf_dereg_type), 1622 pstat, null_pointer_node, integer_zero_node); 1623 gfc_add_expr_to_block (&non_null, tmp); 1624 1625 /* It guarantees memory consistency within the same segment. */ 1626 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"); 1627 tmp = build5_loc (input_location, ASM_EXPR, void_type_node, 1628 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE, 1629 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE); 1630 ASM_VOLATILE_P (tmp) = 1; 1631 gfc_add_expr_to_block (&non_null, tmp); 1632 1633 if (status != NULL_TREE) 1634 { 1635 tree stat = build_fold_indirect_ref_loc (input_location, status); 1636 tree cond2; 1637 1638 TREE_USED (label_finish) = 1; 1639 tmp = build1_v (GOTO_EXPR, label_finish); 1640 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 1641 stat, build_zero_cst (TREE_TYPE (stat))); 1642 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 1643 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC), 1644 tmp, build_empty_stmt (input_location)); 1645 gfc_add_expr_to_block (&non_null, tmp); 1646 } 1647 } 1648 1649 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, 1650 gfc_finish_block (&null), 1651 gfc_finish_block (&non_null)); 1652 } 1653 1654 /* Reallocate MEM so it has SIZE bytes of data. This behaves like the 1655 following pseudo-code: 1656 1657 void * 1658 internal_realloc (void *mem, size_t size) 1659 { 1660 res = realloc (mem, size); 1661 if (!res && size != 0) 1662 _gfortran_os_error ("Allocation would exceed memory limit"); 1663 1664 return res; 1665 } */ 1666 tree 1667 gfc_call_realloc (stmtblock_t * block, tree mem, tree size) 1668 { 1669 tree msg, res, nonzero, null_result, tmp; 1670 tree type = TREE_TYPE (mem); 1671 1672 /* Only evaluate the size once. */ 1673 size = save_expr (fold_convert (size_type_node, size)); 1674 1675 /* Create a variable to hold the result. */ 1676 res = gfc_create_var (type, NULL); 1677 1678 /* Call realloc and check the result. */ 1679 tmp = build_call_expr_loc (input_location, 1680 builtin_decl_explicit (BUILT_IN_REALLOC), 2, 1681 fold_convert (pvoid_type_node, mem), size); 1682 gfc_add_modify (block, res, fold_convert (type, tmp)); 1683 null_result = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, 1684 res, build_int_cst (pvoid_type_node, 0)); 1685 nonzero = fold_build2_loc (input_location, NE_EXPR, logical_type_node, size, 1686 build_int_cst (size_type_node, 0)); 1687 null_result = fold_build2_loc (input_location, TRUTH_AND_EXPR, logical_type_node, 1688 null_result, nonzero); 1689 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const 1690 ("Allocation would exceed memory limit")); 1691 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 1692 null_result, 1693 build_call_expr_loc (input_location, 1694 gfor_fndecl_os_error, 1, msg), 1695 build_empty_stmt (input_location)); 1696 gfc_add_expr_to_block (block, tmp); 1697 1698 return res; 1699 } 1700 1701 1702 /* Add an expression to another one, either at the front or the back. */ 1703 1704 static void 1705 add_expr_to_chain (tree* chain, tree expr, bool front) 1706 { 1707 if (expr == NULL_TREE || IS_EMPTY_STMT (expr)) 1708 return; 1709 1710 if (*chain) 1711 { 1712 if (TREE_CODE (*chain) != STATEMENT_LIST) 1713 { 1714 tree tmp; 1715 1716 tmp = *chain; 1717 *chain = NULL_TREE; 1718 append_to_statement_list (tmp, chain); 1719 } 1720 1721 if (front) 1722 { 1723 tree_stmt_iterator i; 1724 1725 i = tsi_start (*chain); 1726 tsi_link_before (&i, expr, TSI_CONTINUE_LINKING); 1727 } 1728 else 1729 append_to_statement_list (expr, chain); 1730 } 1731 else 1732 *chain = expr; 1733 } 1734 1735 1736 /* Add a statement at the end of a block. */ 1737 1738 void 1739 gfc_add_expr_to_block (stmtblock_t * block, tree expr) 1740 { 1741 gcc_assert (block); 1742 add_expr_to_chain (&block->head, expr, false); 1743 } 1744 1745 1746 /* Add a statement at the beginning of a block. */ 1747 1748 void 1749 gfc_prepend_expr_to_block (stmtblock_t * block, tree expr) 1750 { 1751 gcc_assert (block); 1752 add_expr_to_chain (&block->head, expr, true); 1753 } 1754 1755 1756 /* Add a block the end of a block. */ 1757 1758 void 1759 gfc_add_block_to_block (stmtblock_t * block, stmtblock_t * append) 1760 { 1761 gcc_assert (append); 1762 gcc_assert (!append->has_scope); 1763 1764 gfc_add_expr_to_block (block, append->head); 1765 append->head = NULL_TREE; 1766 } 1767 1768 1769 /* Save the current locus. The structure may not be complete, and should 1770 only be used with gfc_restore_backend_locus. */ 1771 1772 void 1773 gfc_save_backend_locus (locus * loc) 1774 { 1775 loc->lb = XCNEW (gfc_linebuf); 1776 loc->lb->location = input_location; 1777 loc->lb->file = gfc_current_backend_file; 1778 } 1779 1780 1781 /* Set the current locus. */ 1782 1783 void 1784 gfc_set_backend_locus (locus * loc) 1785 { 1786 gfc_current_backend_file = loc->lb->file; 1787 input_location = loc->lb->location; 1788 } 1789 1790 1791 /* Restore the saved locus. Only used in conjunction with 1792 gfc_save_backend_locus, to free the memory when we are done. */ 1793 1794 void 1795 gfc_restore_backend_locus (locus * loc) 1796 { 1797 gfc_set_backend_locus (loc); 1798 free (loc->lb); 1799 } 1800 1801 1802 /* Translate an executable statement. The tree cond is used by gfc_trans_do. 1803 This static function is wrapped by gfc_trans_code_cond and 1804 gfc_trans_code. */ 1805 1806 static tree 1807 trans_code (gfc_code * code, tree cond) 1808 { 1809 stmtblock_t block; 1810 tree res; 1811 1812 if (!code) 1813 return build_empty_stmt (input_location); 1814 1815 gfc_start_block (&block); 1816 1817 /* Translate statements one by one into GENERIC trees until we reach 1818 the end of this gfc_code branch. */ 1819 for (; code; code = code->next) 1820 { 1821 if (code->here != 0) 1822 { 1823 res = gfc_trans_label_here (code); 1824 gfc_add_expr_to_block (&block, res); 1825 } 1826 1827 gfc_current_locus = code->loc; 1828 gfc_set_backend_locus (&code->loc); 1829 1830 switch (code->op) 1831 { 1832 case EXEC_NOP: 1833 case EXEC_END_BLOCK: 1834 case EXEC_END_NESTED_BLOCK: 1835 case EXEC_END_PROCEDURE: 1836 res = NULL_TREE; 1837 break; 1838 1839 case EXEC_ASSIGN: 1840 res = gfc_trans_assign (code); 1841 break; 1842 1843 case EXEC_LABEL_ASSIGN: 1844 res = gfc_trans_label_assign (code); 1845 break; 1846 1847 case EXEC_POINTER_ASSIGN: 1848 res = gfc_trans_pointer_assign (code); 1849 break; 1850 1851 case EXEC_INIT_ASSIGN: 1852 if (code->expr1->ts.type == BT_CLASS) 1853 res = gfc_trans_class_init_assign (code); 1854 else 1855 res = gfc_trans_init_assign (code); 1856 break; 1857 1858 case EXEC_CONTINUE: 1859 res = NULL_TREE; 1860 break; 1861 1862 case EXEC_CRITICAL: 1863 res = gfc_trans_critical (code); 1864 break; 1865 1866 case EXEC_CYCLE: 1867 res = gfc_trans_cycle (code); 1868 break; 1869 1870 case EXEC_EXIT: 1871 res = gfc_trans_exit (code); 1872 break; 1873 1874 case EXEC_GOTO: 1875 res = gfc_trans_goto (code); 1876 break; 1877 1878 case EXEC_ENTRY: 1879 res = gfc_trans_entry (code); 1880 break; 1881 1882 case EXEC_PAUSE: 1883 res = gfc_trans_pause (code); 1884 break; 1885 1886 case EXEC_STOP: 1887 case EXEC_ERROR_STOP: 1888 res = gfc_trans_stop (code, code->op == EXEC_ERROR_STOP); 1889 break; 1890 1891 case EXEC_CALL: 1892 /* For MVBITS we've got the special exception that we need a 1893 dependency check, too. */ 1894 { 1895 bool is_mvbits = false; 1896 1897 if (code->resolved_isym) 1898 { 1899 res = gfc_conv_intrinsic_subroutine (code); 1900 if (res != NULL_TREE) 1901 break; 1902 } 1903 1904 if (code->resolved_isym 1905 && code->resolved_isym->id == GFC_ISYM_MVBITS) 1906 is_mvbits = true; 1907 1908 res = gfc_trans_call (code, is_mvbits, NULL_TREE, 1909 NULL_TREE, false); 1910 } 1911 break; 1912 1913 case EXEC_CALL_PPC: 1914 res = gfc_trans_call (code, false, NULL_TREE, 1915 NULL_TREE, false); 1916 break; 1917 1918 case EXEC_ASSIGN_CALL: 1919 res = gfc_trans_call (code, true, NULL_TREE, 1920 NULL_TREE, false); 1921 break; 1922 1923 case EXEC_RETURN: 1924 res = gfc_trans_return (code); 1925 break; 1926 1927 case EXEC_IF: 1928 res = gfc_trans_if (code); 1929 break; 1930 1931 case EXEC_ARITHMETIC_IF: 1932 res = gfc_trans_arithmetic_if (code); 1933 break; 1934 1935 case EXEC_BLOCK: 1936 res = gfc_trans_block_construct (code); 1937 break; 1938 1939 case EXEC_DO: 1940 res = gfc_trans_do (code, cond); 1941 break; 1942 1943 case EXEC_DO_CONCURRENT: 1944 res = gfc_trans_do_concurrent (code); 1945 break; 1946 1947 case EXEC_DO_WHILE: 1948 res = gfc_trans_do_while (code); 1949 break; 1950 1951 case EXEC_SELECT: 1952 res = gfc_trans_select (code); 1953 break; 1954 1955 case EXEC_SELECT_TYPE: 1956 res = gfc_trans_select_type (code); 1957 break; 1958 1959 case EXEC_FLUSH: 1960 res = gfc_trans_flush (code); 1961 break; 1962 1963 case EXEC_SYNC_ALL: 1964 case EXEC_SYNC_IMAGES: 1965 case EXEC_SYNC_MEMORY: 1966 res = gfc_trans_sync (code, code->op); 1967 break; 1968 1969 case EXEC_LOCK: 1970 case EXEC_UNLOCK: 1971 res = gfc_trans_lock_unlock (code, code->op); 1972 break; 1973 1974 case EXEC_EVENT_POST: 1975 case EXEC_EVENT_WAIT: 1976 res = gfc_trans_event_post_wait (code, code->op); 1977 break; 1978 1979 case EXEC_FAIL_IMAGE: 1980 res = gfc_trans_fail_image (code); 1981 break; 1982 1983 case EXEC_FORALL: 1984 res = gfc_trans_forall (code); 1985 break; 1986 1987 case EXEC_FORM_TEAM: 1988 res = gfc_trans_form_team (code); 1989 break; 1990 1991 case EXEC_CHANGE_TEAM: 1992 res = gfc_trans_change_team (code); 1993 break; 1994 1995 case EXEC_END_TEAM: 1996 res = gfc_trans_end_team (code); 1997 break; 1998 1999 case EXEC_SYNC_TEAM: 2000 res = gfc_trans_sync_team (code); 2001 break; 2002 2003 case EXEC_WHERE: 2004 res = gfc_trans_where (code); 2005 break; 2006 2007 case EXEC_ALLOCATE: 2008 res = gfc_trans_allocate (code); 2009 break; 2010 2011 case EXEC_DEALLOCATE: 2012 res = gfc_trans_deallocate (code); 2013 break; 2014 2015 case EXEC_OPEN: 2016 res = gfc_trans_open (code); 2017 break; 2018 2019 case EXEC_CLOSE: 2020 res = gfc_trans_close (code); 2021 break; 2022 2023 case EXEC_READ: 2024 res = gfc_trans_read (code); 2025 break; 2026 2027 case EXEC_WRITE: 2028 res = gfc_trans_write (code); 2029 break; 2030 2031 case EXEC_IOLENGTH: 2032 res = gfc_trans_iolength (code); 2033 break; 2034 2035 case EXEC_BACKSPACE: 2036 res = gfc_trans_backspace (code); 2037 break; 2038 2039 case EXEC_ENDFILE: 2040 res = gfc_trans_endfile (code); 2041 break; 2042 2043 case EXEC_INQUIRE: 2044 res = gfc_trans_inquire (code); 2045 break; 2046 2047 case EXEC_WAIT: 2048 res = gfc_trans_wait (code); 2049 break; 2050 2051 case EXEC_REWIND: 2052 res = gfc_trans_rewind (code); 2053 break; 2054 2055 case EXEC_TRANSFER: 2056 res = gfc_trans_transfer (code); 2057 break; 2058 2059 case EXEC_DT_END: 2060 res = gfc_trans_dt_end (code); 2061 break; 2062 2063 case EXEC_OMP_ATOMIC: 2064 case EXEC_OMP_BARRIER: 2065 case EXEC_OMP_CANCEL: 2066 case EXEC_OMP_CANCELLATION_POINT: 2067 case EXEC_OMP_CRITICAL: 2068 case EXEC_OMP_DISTRIBUTE: 2069 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO: 2070 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD: 2071 case EXEC_OMP_DISTRIBUTE_SIMD: 2072 case EXEC_OMP_DO: 2073 case EXEC_OMP_DO_SIMD: 2074 case EXEC_OMP_FLUSH: 2075 case EXEC_OMP_MASTER: 2076 case EXEC_OMP_ORDERED: 2077 case EXEC_OMP_PARALLEL: 2078 case EXEC_OMP_PARALLEL_DO: 2079 case EXEC_OMP_PARALLEL_DO_SIMD: 2080 case EXEC_OMP_PARALLEL_SECTIONS: 2081 case EXEC_OMP_PARALLEL_WORKSHARE: 2082 case EXEC_OMP_SECTIONS: 2083 case EXEC_OMP_SIMD: 2084 case EXEC_OMP_SINGLE: 2085 case EXEC_OMP_TARGET: 2086 case EXEC_OMP_TARGET_DATA: 2087 case EXEC_OMP_TARGET_ENTER_DATA: 2088 case EXEC_OMP_TARGET_EXIT_DATA: 2089 case EXEC_OMP_TARGET_PARALLEL: 2090 case EXEC_OMP_TARGET_PARALLEL_DO: 2091 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD: 2092 case EXEC_OMP_TARGET_SIMD: 2093 case EXEC_OMP_TARGET_TEAMS: 2094 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE: 2095 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO: 2096 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: 2097 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD: 2098 case EXEC_OMP_TARGET_UPDATE: 2099 case EXEC_OMP_TASK: 2100 case EXEC_OMP_TASKGROUP: 2101 case EXEC_OMP_TASKLOOP: 2102 case EXEC_OMP_TASKLOOP_SIMD: 2103 case EXEC_OMP_TASKWAIT: 2104 case EXEC_OMP_TASKYIELD: 2105 case EXEC_OMP_TEAMS: 2106 case EXEC_OMP_TEAMS_DISTRIBUTE: 2107 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO: 2108 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: 2109 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD: 2110 case EXEC_OMP_WORKSHARE: 2111 res = gfc_trans_omp_directive (code); 2112 break; 2113 2114 case EXEC_OACC_CACHE: 2115 case EXEC_OACC_WAIT: 2116 case EXEC_OACC_UPDATE: 2117 case EXEC_OACC_LOOP: 2118 case EXEC_OACC_HOST_DATA: 2119 case EXEC_OACC_DATA: 2120 case EXEC_OACC_KERNELS: 2121 case EXEC_OACC_KERNELS_LOOP: 2122 case EXEC_OACC_PARALLEL: 2123 case EXEC_OACC_PARALLEL_LOOP: 2124 case EXEC_OACC_ENTER_DATA: 2125 case EXEC_OACC_EXIT_DATA: 2126 case EXEC_OACC_ATOMIC: 2127 case EXEC_OACC_DECLARE: 2128 res = gfc_trans_oacc_directive (code); 2129 break; 2130 2131 default: 2132 gfc_internal_error ("gfc_trans_code(): Bad statement code"); 2133 } 2134 2135 gfc_set_backend_locus (&code->loc); 2136 2137 if (res != NULL_TREE && ! IS_EMPTY_STMT (res)) 2138 { 2139 if (TREE_CODE (res) != STATEMENT_LIST) 2140 SET_EXPR_LOCATION (res, input_location); 2141 2142 /* Add the new statement to the block. */ 2143 gfc_add_expr_to_block (&block, res); 2144 } 2145 } 2146 2147 /* Return the finished block. */ 2148 return gfc_finish_block (&block); 2149 } 2150 2151 2152 /* Translate an executable statement with condition, cond. The condition is 2153 used by gfc_trans_do to test for IO result conditions inside implied 2154 DO loops of READ and WRITE statements. See build_dt in trans-io.c. */ 2155 2156 tree 2157 gfc_trans_code_cond (gfc_code * code, tree cond) 2158 { 2159 return trans_code (code, cond); 2160 } 2161 2162 /* Translate an executable statement without condition. */ 2163 2164 tree 2165 gfc_trans_code (gfc_code * code) 2166 { 2167 return trans_code (code, NULL_TREE); 2168 } 2169 2170 2171 /* This function is called after a complete program unit has been parsed 2172 and resolved. */ 2173 2174 void 2175 gfc_generate_code (gfc_namespace * ns) 2176 { 2177 ompws_flags = 0; 2178 if (ns->is_block_data) 2179 { 2180 gfc_generate_block_data (ns); 2181 return; 2182 } 2183 2184 gfc_generate_function_code (ns); 2185 } 2186 2187 2188 /* This function is called after a complete module has been parsed 2189 and resolved. */ 2190 2191 void 2192 gfc_generate_module_code (gfc_namespace * ns) 2193 { 2194 gfc_namespace *n; 2195 struct module_htab_entry *entry; 2196 2197 gcc_assert (ns->proc_name->backend_decl == NULL); 2198 ns->proc_name->backend_decl 2199 = build_decl (ns->proc_name->declared_at.lb->location, 2200 NAMESPACE_DECL, get_identifier (ns->proc_name->name), 2201 void_type_node); 2202 entry = gfc_find_module (ns->proc_name->name); 2203 if (entry->namespace_decl) 2204 /* Buggy sourcecode, using a module before defining it? */ 2205 entry->decls->empty (); 2206 entry->namespace_decl = ns->proc_name->backend_decl; 2207 2208 gfc_generate_module_vars (ns); 2209 2210 /* We need to generate all module function prototypes first, to allow 2211 sibling calls. */ 2212 for (n = ns->contained; n; n = n->sibling) 2213 { 2214 gfc_entry_list *el; 2215 2216 if (!n->proc_name) 2217 continue; 2218 2219 gfc_create_function_decl (n, false); 2220 DECL_CONTEXT (n->proc_name->backend_decl) = ns->proc_name->backend_decl; 2221 gfc_module_add_decl (entry, n->proc_name->backend_decl); 2222 for (el = ns->entries; el; el = el->next) 2223 { 2224 DECL_CONTEXT (el->sym->backend_decl) = ns->proc_name->backend_decl; 2225 gfc_module_add_decl (entry, el->sym->backend_decl); 2226 } 2227 } 2228 2229 for (n = ns->contained; n; n = n->sibling) 2230 { 2231 if (!n->proc_name) 2232 continue; 2233 2234 gfc_generate_function_code (n); 2235 } 2236 } 2237 2238 2239 /* Initialize an init/cleanup block with existing code. */ 2240 2241 void 2242 gfc_start_wrapped_block (gfc_wrapped_block* block, tree code) 2243 { 2244 gcc_assert (block); 2245 2246 block->init = NULL_TREE; 2247 block->code = code; 2248 block->cleanup = NULL_TREE; 2249 } 2250 2251 2252 /* Add a new pair of initializers/clean-up code. */ 2253 2254 void 2255 gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup) 2256 { 2257 gcc_assert (block); 2258 2259 /* The new pair of init/cleanup should be "wrapped around" the existing 2260 block of code, thus the initialization is added to the front and the 2261 cleanup to the back. */ 2262 add_expr_to_chain (&block->init, init, true); 2263 add_expr_to_chain (&block->cleanup, cleanup, false); 2264 } 2265 2266 2267 /* Finish up a wrapped block by building a corresponding try-finally expr. */ 2268 2269 tree 2270 gfc_finish_wrapped_block (gfc_wrapped_block* block) 2271 { 2272 tree result; 2273 2274 gcc_assert (block); 2275 2276 /* Build the final expression. For this, just add init and body together, 2277 and put clean-up with that into a TRY_FINALLY_EXPR. */ 2278 result = block->init; 2279 add_expr_to_chain (&result, block->code, false); 2280 if (block->cleanup) 2281 result = build2_loc (input_location, TRY_FINALLY_EXPR, void_type_node, 2282 result, block->cleanup); 2283 2284 /* Clear the block. */ 2285 block->init = NULL_TREE; 2286 block->code = NULL_TREE; 2287 block->cleanup = NULL_TREE; 2288 2289 return result; 2290 } 2291 2292 2293 /* Helper function for marking a boolean expression tree as unlikely. */ 2294 2295 tree 2296 gfc_unlikely (tree cond, enum br_predictor predictor) 2297 { 2298 tree tmp; 2299 2300 if (optimize) 2301 { 2302 cond = fold_convert (long_integer_type_node, cond); 2303 tmp = build_zero_cst (long_integer_type_node); 2304 cond = build_call_expr_loc (input_location, 2305 builtin_decl_explicit (BUILT_IN_EXPECT), 2306 3, cond, tmp, 2307 build_int_cst (integer_type_node, 2308 predictor)); 2309 } 2310 return cond; 2311 } 2312 2313 2314 /* Helper function for marking a boolean expression tree as likely. */ 2315 2316 tree 2317 gfc_likely (tree cond, enum br_predictor predictor) 2318 { 2319 tree tmp; 2320 2321 if (optimize) 2322 { 2323 cond = fold_convert (long_integer_type_node, cond); 2324 tmp = build_one_cst (long_integer_type_node); 2325 cond = build_call_expr_loc (input_location, 2326 builtin_decl_explicit (BUILT_IN_EXPECT), 2327 3, cond, tmp, 2328 build_int_cst (integer_type_node, 2329 predictor)); 2330 } 2331 return cond; 2332 } 2333 2334 2335 /* Get the string length for a deferred character length component. */ 2336 2337 bool 2338 gfc_deferred_strlen (gfc_component *c, tree *decl) 2339 { 2340 char name[GFC_MAX_SYMBOL_LEN+9]; 2341 gfc_component *strlen; 2342 if (!(c->ts.type == BT_CHARACTER 2343 && (c->ts.deferred || c->attr.pdt_string))) 2344 return false; 2345 sprintf (name, "_%s_length", c->name); 2346 for (strlen = c; strlen; strlen = strlen->next) 2347 if (strcmp (strlen->name, name) == 0) 2348 break; 2349 *decl = strlen ? strlen->backend_decl : NULL_TREE; 2350 return strlen != NULL; 2351 } 2352