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