1 1.1 mrg /* Expression translation 2 1.1 mrg Copyright (C) 2002-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Paul Brook <paul (at) nowt.org> 4 1.1 mrg and Steven Bosscher <s.bosscher (at) student.tudelft.nl> 5 1.1 mrg 6 1.1 mrg This file is part of GCC. 7 1.1 mrg 8 1.1 mrg GCC is free software; you can redistribute it and/or modify it under 9 1.1 mrg the terms of the GNU General Public License as published by the Free 10 1.1 mrg Software Foundation; either version 3, or (at your option) any later 11 1.1 mrg version. 12 1.1 mrg 13 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 1.1 mrg for more details. 17 1.1 mrg 18 1.1 mrg You should have received a copy of the GNU General Public License 19 1.1 mrg along with GCC; see the file COPYING3. If not see 20 1.1 mrg <http://www.gnu.org/licenses/>. */ 21 1.1 mrg 22 1.1 mrg /* trans-expr.cc-- generate GENERIC trees for gfc_expr. */ 23 1.1 mrg 24 1.1 mrg #include "config.h" 25 1.1 mrg #include "system.h" 26 1.1 mrg #include "coretypes.h" 27 1.1 mrg #include "options.h" 28 1.1 mrg #include "tree.h" 29 1.1 mrg #include "gfortran.h" 30 1.1 mrg #include "trans.h" 31 1.1 mrg #include "stringpool.h" 32 1.1 mrg #include "diagnostic-core.h" /* For fatal_error. */ 33 1.1 mrg #include "fold-const.h" 34 1.1 mrg #include "langhooks.h" 35 1.1 mrg #include "arith.h" 36 1.1 mrg #include "constructor.h" 37 1.1 mrg #include "trans-const.h" 38 1.1 mrg #include "trans-types.h" 39 1.1 mrg #include "trans-array.h" 40 1.1 mrg /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */ 41 1.1 mrg #include "trans-stmt.h" 42 1.1 mrg #include "dependency.h" 43 1.1 mrg #include "gimplify.h" 44 1.1 mrg #include "tm.h" /* For CHAR_TYPE_SIZE. */ 45 1.1 mrg 46 1.1 mrg 47 1.1 mrg /* Calculate the number of characters in a string. */ 48 1.1 mrg 49 1.1 mrg static tree 50 1.1 mrg gfc_get_character_len (tree type) 51 1.1 mrg { 52 1.1 mrg tree len; 53 1.1 mrg 54 1.1 mrg gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE 55 1.1 mrg && TYPE_STRING_FLAG (type)); 56 1.1 mrg 57 1.1 mrg len = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); 58 1.1 mrg len = (len) ? (len) : (integer_zero_node); 59 1.1 mrg return fold_convert (gfc_charlen_type_node, len); 60 1.1 mrg } 61 1.1 mrg 62 1.1 mrg 63 1.1 mrg 64 1.1 mrg /* Calculate the number of bytes in a string. */ 65 1.1 mrg 66 1.1 mrg tree 67 1.1 mrg gfc_get_character_len_in_bytes (tree type) 68 1.1 mrg { 69 1.1 mrg tree tmp, len; 70 1.1 mrg 71 1.1 mrg gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE 72 1.1 mrg && TYPE_STRING_FLAG (type)); 73 1.1 mrg 74 1.1 mrg tmp = TYPE_SIZE_UNIT (TREE_TYPE (type)); 75 1.1 mrg tmp = (tmp && !integer_zerop (tmp)) 76 1.1 mrg ? (fold_convert (gfc_charlen_type_node, tmp)) : (NULL_TREE); 77 1.1 mrg len = gfc_get_character_len (type); 78 1.1 mrg if (tmp && len && !integer_zerop (len)) 79 1.1 mrg len = fold_build2_loc (input_location, MULT_EXPR, 80 1.1 mrg gfc_charlen_type_node, len, tmp); 81 1.1 mrg return len; 82 1.1 mrg } 83 1.1 mrg 84 1.1 mrg 85 1.1 mrg /* Convert a scalar to an array descriptor. To be used for assumed-rank 86 1.1 mrg arrays. */ 87 1.1 mrg 88 1.1 mrg static tree 89 1.1 mrg get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr) 90 1.1 mrg { 91 1.1 mrg enum gfc_array_kind akind; 92 1.1 mrg 93 1.1 mrg if (attr.pointer) 94 1.1 mrg akind = GFC_ARRAY_POINTER_CONT; 95 1.1 mrg else if (attr.allocatable) 96 1.1 mrg akind = GFC_ARRAY_ALLOCATABLE; 97 1.1 mrg else 98 1.1 mrg akind = GFC_ARRAY_ASSUMED_SHAPE_CONT; 99 1.1 mrg 100 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (scalar))) 101 1.1 mrg scalar = TREE_TYPE (scalar); 102 1.1 mrg return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1, 103 1.1 mrg akind, !(attr.pointer || attr.target)); 104 1.1 mrg } 105 1.1 mrg 106 1.1 mrg tree 107 1.1 mrg gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr) 108 1.1 mrg { 109 1.1 mrg tree desc, type, etype; 110 1.1 mrg 111 1.1 mrg type = get_scalar_to_descriptor_type (scalar, attr); 112 1.1 mrg etype = TREE_TYPE (scalar); 113 1.1 mrg desc = gfc_create_var (type, "desc"); 114 1.1 mrg DECL_ARTIFICIAL (desc) = 1; 115 1.1 mrg 116 1.1 mrg if (CONSTANT_CLASS_P (scalar)) 117 1.1 mrg { 118 1.1 mrg tree tmp; 119 1.1 mrg tmp = gfc_create_var (TREE_TYPE (scalar), "scalar"); 120 1.1 mrg gfc_add_modify (&se->pre, tmp, scalar); 121 1.1 mrg scalar = tmp; 122 1.1 mrg } 123 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (scalar))) 124 1.1 mrg scalar = gfc_build_addr_expr (NULL_TREE, scalar); 125 1.1 mrg else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE) 126 1.1 mrg etype = TREE_TYPE (etype); 127 1.1 mrg gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc), 128 1.1 mrg gfc_get_dtype_rank_type (0, etype)); 129 1.1 mrg gfc_conv_descriptor_data_set (&se->pre, desc, scalar); 130 1.1 mrg gfc_conv_descriptor_span_set (&se->pre, desc, 131 1.1 mrg gfc_conv_descriptor_elem_len (desc)); 132 1.1 mrg 133 1.1 mrg /* Copy pointer address back - but only if it could have changed and 134 1.1 mrg if the actual argument is a pointer and not, e.g., NULL(). */ 135 1.1 mrg if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN) 136 1.1 mrg gfc_add_modify (&se->post, scalar, 137 1.1 mrg fold_convert (TREE_TYPE (scalar), 138 1.1 mrg gfc_conv_descriptor_data_get (desc))); 139 1.1 mrg return desc; 140 1.1 mrg } 141 1.1 mrg 142 1.1 mrg 143 1.1 mrg /* Get the coarray token from the ultimate array or component ref. 144 1.1 mrg Returns a NULL_TREE, when the ref object is not allocatable or pointer. */ 145 1.1 mrg 146 1.1 mrg tree 147 1.1 mrg gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr) 148 1.1 mrg { 149 1.1 mrg gfc_symbol *sym = expr->symtree->n.sym; 150 1.1 mrg bool is_coarray = sym->attr.codimension; 151 1.1 mrg gfc_expr *caf_expr = gfc_copy_expr (expr); 152 1.1 mrg gfc_ref *ref = caf_expr->ref, *last_caf_ref = NULL; 153 1.1 mrg 154 1.1 mrg while (ref) 155 1.1 mrg { 156 1.1 mrg if (ref->type == REF_COMPONENT 157 1.1 mrg && (ref->u.c.component->attr.allocatable 158 1.1 mrg || ref->u.c.component->attr.pointer) 159 1.1 mrg && (is_coarray || ref->u.c.component->attr.codimension)) 160 1.1 mrg last_caf_ref = ref; 161 1.1 mrg ref = ref->next; 162 1.1 mrg } 163 1.1 mrg 164 1.1 mrg if (last_caf_ref == NULL) 165 1.1 mrg return NULL_TREE; 166 1.1 mrg 167 1.1 mrg tree comp = last_caf_ref->u.c.component->caf_token, caf; 168 1.1 mrg gfc_se se; 169 1.1 mrg bool comp_ref = !last_caf_ref->u.c.component->attr.dimension; 170 1.1 mrg if (comp == NULL_TREE && comp_ref) 171 1.1 mrg return NULL_TREE; 172 1.1 mrg gfc_init_se (&se, outerse); 173 1.1 mrg gfc_free_ref_list (last_caf_ref->next); 174 1.1 mrg last_caf_ref->next = NULL; 175 1.1 mrg caf_expr->rank = comp_ref ? 0 : last_caf_ref->u.c.component->as->rank; 176 1.1 mrg se.want_pointer = comp_ref; 177 1.1 mrg gfc_conv_expr (&se, caf_expr); 178 1.1 mrg gfc_add_block_to_block (&outerse->pre, &se.pre); 179 1.1 mrg 180 1.1 mrg if (TREE_CODE (se.expr) == COMPONENT_REF && comp_ref) 181 1.1 mrg se.expr = TREE_OPERAND (se.expr, 0); 182 1.1 mrg gfc_free_expr (caf_expr); 183 1.1 mrg 184 1.1 mrg if (comp_ref) 185 1.1 mrg caf = fold_build3_loc (input_location, COMPONENT_REF, 186 1.1 mrg TREE_TYPE (comp), se.expr, comp, NULL_TREE); 187 1.1 mrg else 188 1.1 mrg caf = gfc_conv_descriptor_token (se.expr); 189 1.1 mrg return gfc_build_addr_expr (NULL_TREE, caf); 190 1.1 mrg } 191 1.1 mrg 192 1.1 mrg 193 1.1 mrg /* This is the seed for an eventual trans-class.c 194 1.1 mrg 195 1.1 mrg The following parameters should not be used directly since they might 196 1.1 mrg in future implementations. Use the corresponding APIs. */ 197 1.1 mrg #define CLASS_DATA_FIELD 0 198 1.1 mrg #define CLASS_VPTR_FIELD 1 199 1.1 mrg #define CLASS_LEN_FIELD 2 200 1.1 mrg #define VTABLE_HASH_FIELD 0 201 1.1 mrg #define VTABLE_SIZE_FIELD 1 202 1.1 mrg #define VTABLE_EXTENDS_FIELD 2 203 1.1 mrg #define VTABLE_DEF_INIT_FIELD 3 204 1.1 mrg #define VTABLE_COPY_FIELD 4 205 1.1 mrg #define VTABLE_FINAL_FIELD 5 206 1.1 mrg #define VTABLE_DEALLOCATE_FIELD 6 207 1.1 mrg 208 1.1 mrg 209 1.1 mrg tree 210 1.1 mrg gfc_class_set_static_fields (tree decl, tree vptr, tree data) 211 1.1 mrg { 212 1.1 mrg tree tmp; 213 1.1 mrg tree field; 214 1.1 mrg vec<constructor_elt, va_gc> *init = NULL; 215 1.1 mrg 216 1.1 mrg field = TYPE_FIELDS (TREE_TYPE (decl)); 217 1.1 mrg tmp = gfc_advance_chain (field, CLASS_DATA_FIELD); 218 1.1 mrg CONSTRUCTOR_APPEND_ELT (init, tmp, data); 219 1.1 mrg 220 1.1 mrg tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD); 221 1.1 mrg CONSTRUCTOR_APPEND_ELT (init, tmp, vptr); 222 1.1 mrg 223 1.1 mrg return build_constructor (TREE_TYPE (decl), init); 224 1.1 mrg } 225 1.1 mrg 226 1.1 mrg 227 1.1 mrg tree 228 1.1 mrg gfc_class_data_get (tree decl) 229 1.1 mrg { 230 1.1 mrg tree data; 231 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (decl))) 232 1.1 mrg decl = build_fold_indirect_ref_loc (input_location, decl); 233 1.1 mrg data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)), 234 1.1 mrg CLASS_DATA_FIELD); 235 1.1 mrg return fold_build3_loc (input_location, COMPONENT_REF, 236 1.1 mrg TREE_TYPE (data), decl, data, 237 1.1 mrg NULL_TREE); 238 1.1 mrg } 239 1.1 mrg 240 1.1 mrg 241 1.1 mrg tree 242 1.1 mrg gfc_class_vptr_get (tree decl) 243 1.1 mrg { 244 1.1 mrg tree vptr; 245 1.1 mrg /* For class arrays decl may be a temporary descriptor handle, the vptr is 246 1.1 mrg then available through the saved descriptor. */ 247 1.1 mrg if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl) 248 1.1 mrg && GFC_DECL_SAVED_DESCRIPTOR (decl)) 249 1.1 mrg decl = GFC_DECL_SAVED_DESCRIPTOR (decl); 250 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (decl))) 251 1.1 mrg decl = build_fold_indirect_ref_loc (input_location, decl); 252 1.1 mrg vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)), 253 1.1 mrg CLASS_VPTR_FIELD); 254 1.1 mrg return fold_build3_loc (input_location, COMPONENT_REF, 255 1.1 mrg TREE_TYPE (vptr), decl, vptr, 256 1.1 mrg NULL_TREE); 257 1.1 mrg } 258 1.1 mrg 259 1.1 mrg 260 1.1 mrg tree 261 1.1 mrg gfc_class_len_get (tree decl) 262 1.1 mrg { 263 1.1 mrg tree len; 264 1.1 mrg /* For class arrays decl may be a temporary descriptor handle, the len is 265 1.1 mrg then available through the saved descriptor. */ 266 1.1 mrg if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl) 267 1.1 mrg && GFC_DECL_SAVED_DESCRIPTOR (decl)) 268 1.1 mrg decl = GFC_DECL_SAVED_DESCRIPTOR (decl); 269 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (decl))) 270 1.1 mrg decl = build_fold_indirect_ref_loc (input_location, decl); 271 1.1 mrg len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)), 272 1.1 mrg CLASS_LEN_FIELD); 273 1.1 mrg return fold_build3_loc (input_location, COMPONENT_REF, 274 1.1 mrg TREE_TYPE (len), decl, len, 275 1.1 mrg NULL_TREE); 276 1.1 mrg } 277 1.1 mrg 278 1.1 mrg 279 1.1 mrg /* Try to get the _len component of a class. When the class is not unlimited 280 1.1 mrg poly, i.e. no _len field exists, then return a zero node. */ 281 1.1 mrg 282 1.1 mrg static tree 283 1.1 mrg gfc_class_len_or_zero_get (tree decl) 284 1.1 mrg { 285 1.1 mrg tree len; 286 1.1 mrg /* For class arrays decl may be a temporary descriptor handle, the vptr is 287 1.1 mrg then available through the saved descriptor. */ 288 1.1 mrg if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl) 289 1.1 mrg && GFC_DECL_SAVED_DESCRIPTOR (decl)) 290 1.1 mrg decl = GFC_DECL_SAVED_DESCRIPTOR (decl); 291 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (decl))) 292 1.1 mrg decl = build_fold_indirect_ref_loc (input_location, decl); 293 1.1 mrg len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)), 294 1.1 mrg CLASS_LEN_FIELD); 295 1.1 mrg return len != NULL_TREE ? fold_build3_loc (input_location, COMPONENT_REF, 296 1.1 mrg TREE_TYPE (len), decl, len, 297 1.1 mrg NULL_TREE) 298 1.1 mrg : build_zero_cst (gfc_charlen_type_node); 299 1.1 mrg } 300 1.1 mrg 301 1.1 mrg 302 1.1 mrg tree 303 1.1 mrg gfc_resize_class_size_with_len (stmtblock_t * block, tree class_expr, tree size) 304 1.1 mrg { 305 1.1 mrg tree tmp; 306 1.1 mrg tree tmp2; 307 1.1 mrg tree type; 308 1.1 mrg 309 1.1 mrg tmp = gfc_class_len_or_zero_get (class_expr); 310 1.1 mrg 311 1.1 mrg /* Include the len value in the element size if present. */ 312 1.1 mrg if (!integer_zerop (tmp)) 313 1.1 mrg { 314 1.1 mrg type = TREE_TYPE (size); 315 1.1 mrg if (block) 316 1.1 mrg { 317 1.1 mrg size = gfc_evaluate_now (size, block); 318 1.1 mrg tmp = gfc_evaluate_now (fold_convert (type , tmp), block); 319 1.1 mrg } 320 1.1 mrg tmp2 = fold_build2_loc (input_location, MULT_EXPR, 321 1.1 mrg type, size, tmp); 322 1.1 mrg tmp = fold_build2_loc (input_location, GT_EXPR, 323 1.1 mrg logical_type_node, tmp, 324 1.1 mrg build_zero_cst (type)); 325 1.1 mrg size = fold_build3_loc (input_location, COND_EXPR, 326 1.1 mrg type, tmp, tmp2, size); 327 1.1 mrg } 328 1.1 mrg else 329 1.1 mrg return size; 330 1.1 mrg 331 1.1 mrg if (block) 332 1.1 mrg size = gfc_evaluate_now (size, block); 333 1.1 mrg 334 1.1 mrg return size; 335 1.1 mrg } 336 1.1 mrg 337 1.1 mrg 338 1.1 mrg /* Get the specified FIELD from the VPTR. */ 339 1.1 mrg 340 1.1 mrg static tree 341 1.1 mrg vptr_field_get (tree vptr, int fieldno) 342 1.1 mrg { 343 1.1 mrg tree field; 344 1.1 mrg vptr = build_fold_indirect_ref_loc (input_location, vptr); 345 1.1 mrg field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)), 346 1.1 mrg fieldno); 347 1.1 mrg field = fold_build3_loc (input_location, COMPONENT_REF, 348 1.1 mrg TREE_TYPE (field), vptr, field, 349 1.1 mrg NULL_TREE); 350 1.1 mrg gcc_assert (field); 351 1.1 mrg return field; 352 1.1 mrg } 353 1.1 mrg 354 1.1 mrg 355 1.1 mrg /* Get the field from the class' vptr. */ 356 1.1 mrg 357 1.1 mrg static tree 358 1.1 mrg class_vtab_field_get (tree decl, int fieldno) 359 1.1 mrg { 360 1.1 mrg tree vptr; 361 1.1 mrg vptr = gfc_class_vptr_get (decl); 362 1.1 mrg return vptr_field_get (vptr, fieldno); 363 1.1 mrg } 364 1.1 mrg 365 1.1 mrg 366 1.1 mrg /* Define a macro for creating the class_vtab_* and vptr_* accessors in 367 1.1 mrg unison. */ 368 1.1 mrg #define VTAB_GET_FIELD_GEN(name, field) tree \ 369 1.1 mrg gfc_class_vtab_## name ##_get (tree cl) \ 370 1.1 mrg { \ 371 1.1 mrg return class_vtab_field_get (cl, field); \ 372 1.1 mrg } \ 373 1.1 mrg \ 374 1.1 mrg tree \ 375 1.1 mrg gfc_vptr_## name ##_get (tree vptr) \ 376 1.1 mrg { \ 377 1.1 mrg return vptr_field_get (vptr, field); \ 378 1.1 mrg } 379 1.1 mrg 380 1.1 mrg VTAB_GET_FIELD_GEN (hash, VTABLE_HASH_FIELD) 381 1.1 mrg VTAB_GET_FIELD_GEN (extends, VTABLE_EXTENDS_FIELD) 382 1.1 mrg VTAB_GET_FIELD_GEN (def_init, VTABLE_DEF_INIT_FIELD) 383 1.1 mrg VTAB_GET_FIELD_GEN (copy, VTABLE_COPY_FIELD) 384 1.1 mrg VTAB_GET_FIELD_GEN (final, VTABLE_FINAL_FIELD) 385 1.1 mrg VTAB_GET_FIELD_GEN (deallocate, VTABLE_DEALLOCATE_FIELD) 386 1.1 mrg #undef VTAB_GET_FIELD_GEN 387 1.1 mrg 388 1.1 mrg /* The size field is returned as an array index type. Therefore treat 389 1.1 mrg it and only it specially. */ 390 1.1 mrg 391 1.1 mrg tree 392 1.1 mrg gfc_class_vtab_size_get (tree cl) 393 1.1 mrg { 394 1.1 mrg tree size; 395 1.1 mrg size = class_vtab_field_get (cl, VTABLE_SIZE_FIELD); 396 1.1 mrg /* Always return size as an array index type. */ 397 1.1 mrg size = fold_convert (gfc_array_index_type, size); 398 1.1 mrg gcc_assert (size); 399 1.1 mrg return size; 400 1.1 mrg } 401 1.1 mrg 402 1.1 mrg tree 403 1.1 mrg gfc_vptr_size_get (tree vptr) 404 1.1 mrg { 405 1.1 mrg tree size; 406 1.1 mrg size = vptr_field_get (vptr, VTABLE_SIZE_FIELD); 407 1.1 mrg /* Always return size as an array index type. */ 408 1.1 mrg size = fold_convert (gfc_array_index_type, size); 409 1.1 mrg gcc_assert (size); 410 1.1 mrg return size; 411 1.1 mrg } 412 1.1 mrg 413 1.1 mrg 414 1.1 mrg #undef CLASS_DATA_FIELD 415 1.1 mrg #undef CLASS_VPTR_FIELD 416 1.1 mrg #undef CLASS_LEN_FIELD 417 1.1 mrg #undef VTABLE_HASH_FIELD 418 1.1 mrg #undef VTABLE_SIZE_FIELD 419 1.1 mrg #undef VTABLE_EXTENDS_FIELD 420 1.1 mrg #undef VTABLE_DEF_INIT_FIELD 421 1.1 mrg #undef VTABLE_COPY_FIELD 422 1.1 mrg #undef VTABLE_FINAL_FIELD 423 1.1 mrg 424 1.1 mrg 425 1.1 mrg /* IF ts is null (default), search for the last _class ref in the chain 426 1.1 mrg of references of the expression and cut the chain there. Although 427 1.1 mrg this routine is similiar to class.cc:gfc_add_component_ref (), there 428 1.1 mrg is a significant difference: gfc_add_component_ref () concentrates 429 1.1 mrg on an array ref that is the last ref in the chain and is oblivious 430 1.1 mrg to the kind of refs following. 431 1.1 mrg ELSE IF ts is non-null the cut is at the class entity or component 432 1.1 mrg that is followed by an array reference, which is not an element. 433 1.1 mrg These calls come from trans-array.cc:build_class_array_ref, which 434 1.1 mrg handles scalarized class array references.*/ 435 1.1 mrg 436 1.1 mrg gfc_expr * 437 1.1 mrg gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold, 438 1.1 mrg gfc_typespec **ts) 439 1.1 mrg { 440 1.1 mrg gfc_expr *base_expr; 441 1.1 mrg gfc_ref *ref, *class_ref, *tail = NULL, *array_ref; 442 1.1 mrg 443 1.1 mrg /* Find the last class reference. */ 444 1.1 mrg class_ref = NULL; 445 1.1 mrg array_ref = NULL; 446 1.1 mrg 447 1.1 mrg if (ts) 448 1.1 mrg { 449 1.1 mrg if (e->symtree 450 1.1 mrg && e->symtree->n.sym->ts.type == BT_CLASS) 451 1.1 mrg *ts = &e->symtree->n.sym->ts; 452 1.1 mrg else 453 1.1 mrg *ts = NULL; 454 1.1 mrg } 455 1.1 mrg 456 1.1 mrg for (ref = e->ref; ref; ref = ref->next) 457 1.1 mrg { 458 1.1 mrg if (ts) 459 1.1 mrg { 460 1.1 mrg if (ref->type == REF_COMPONENT 461 1.1 mrg && ref->u.c.component->ts.type == BT_CLASS 462 1.1 mrg && ref->next && ref->next->type == REF_COMPONENT 463 1.1 mrg && !strcmp (ref->next->u.c.component->name, "_data") 464 1.1 mrg && ref->next->next 465 1.1 mrg && ref->next->next->type == REF_ARRAY 466 1.1 mrg && ref->next->next->u.ar.type != AR_ELEMENT) 467 1.1 mrg { 468 1.1 mrg *ts = &ref->u.c.component->ts; 469 1.1 mrg class_ref = ref; 470 1.1 mrg break; 471 1.1 mrg } 472 1.1 mrg 473 1.1 mrg if (ref->next == NULL) 474 1.1 mrg break; 475 1.1 mrg } 476 1.1 mrg else 477 1.1 mrg { 478 1.1 mrg if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT) 479 1.1 mrg array_ref = ref; 480 1.1 mrg 481 1.1 mrg if (ref->type == REF_COMPONENT 482 1.1 mrg && ref->u.c.component->ts.type == BT_CLASS) 483 1.1 mrg { 484 1.1 mrg /* Component to the right of a part reference with nonzero 485 1.1 mrg rank must not have the ALLOCATABLE attribute. If attempts 486 1.1 mrg are made to reference such a component reference, an error 487 1.1 mrg results followed by an ICE. */ 488 1.1 mrg if (array_ref 489 1.1 mrg && CLASS_DATA (ref->u.c.component)->attr.allocatable) 490 1.1 mrg return NULL; 491 1.1 mrg class_ref = ref; 492 1.1 mrg } 493 1.1 mrg } 494 1.1 mrg } 495 1.1 mrg 496 1.1 mrg if (ts && *ts == NULL) 497 1.1 mrg return NULL; 498 1.1 mrg 499 1.1 mrg /* Remove and store all subsequent references after the 500 1.1 mrg CLASS reference. */ 501 1.1 mrg if (class_ref) 502 1.1 mrg { 503 1.1 mrg tail = class_ref->next; 504 1.1 mrg class_ref->next = NULL; 505 1.1 mrg } 506 1.1 mrg else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS) 507 1.1 mrg { 508 1.1 mrg tail = e->ref; 509 1.1 mrg e->ref = NULL; 510 1.1 mrg } 511 1.1 mrg 512 1.1 mrg if (is_mold) 513 1.1 mrg base_expr = gfc_expr_to_initialize (e); 514 1.1 mrg else 515 1.1 mrg base_expr = gfc_copy_expr (e); 516 1.1 mrg 517 1.1 mrg /* Restore the original tail expression. */ 518 1.1 mrg if (class_ref) 519 1.1 mrg { 520 1.1 mrg gfc_free_ref_list (class_ref->next); 521 1.1 mrg class_ref->next = tail; 522 1.1 mrg } 523 1.1 mrg else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS) 524 1.1 mrg { 525 1.1 mrg gfc_free_ref_list (e->ref); 526 1.1 mrg e->ref = tail; 527 1.1 mrg } 528 1.1 mrg return base_expr; 529 1.1 mrg } 530 1.1 mrg 531 1.1 mrg 532 1.1 mrg /* Reset the vptr to the declared type, e.g. after deallocation. */ 533 1.1 mrg 534 1.1 mrg void 535 1.1 mrg gfc_reset_vptr (stmtblock_t *block, gfc_expr *e) 536 1.1 mrg { 537 1.1 mrg gfc_symbol *vtab; 538 1.1 mrg tree vptr; 539 1.1 mrg tree vtable; 540 1.1 mrg gfc_se se; 541 1.1 mrg 542 1.1 mrg /* Evaluate the expression and obtain the vptr from it. */ 543 1.1 mrg gfc_init_se (&se, NULL); 544 1.1 mrg if (e->rank) 545 1.1 mrg gfc_conv_expr_descriptor (&se, e); 546 1.1 mrg else 547 1.1 mrg gfc_conv_expr (&se, e); 548 1.1 mrg gfc_add_block_to_block (block, &se.pre); 549 1.1 mrg vptr = gfc_get_vptr_from_expr (se.expr); 550 1.1 mrg 551 1.1 mrg /* If a vptr is not found, we can do nothing more. */ 552 1.1 mrg if (vptr == NULL_TREE) 553 1.1 mrg return; 554 1.1 mrg 555 1.1 mrg if (UNLIMITED_POLY (e)) 556 1.1 mrg gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0)); 557 1.1 mrg else 558 1.1 mrg { 559 1.1 mrg /* Return the vptr to the address of the declared type. */ 560 1.1 mrg vtab = gfc_find_derived_vtab (e->ts.u.derived); 561 1.1 mrg vtable = vtab->backend_decl; 562 1.1 mrg if (vtable == NULL_TREE) 563 1.1 mrg vtable = gfc_get_symbol_decl (vtab); 564 1.1 mrg vtable = gfc_build_addr_expr (NULL, vtable); 565 1.1 mrg vtable = fold_convert (TREE_TYPE (vptr), vtable); 566 1.1 mrg gfc_add_modify (block, vptr, vtable); 567 1.1 mrg } 568 1.1 mrg } 569 1.1 mrg 570 1.1 mrg 571 1.1 mrg /* Reset the len for unlimited polymorphic objects. */ 572 1.1 mrg 573 1.1 mrg void 574 1.1 mrg gfc_reset_len (stmtblock_t *block, gfc_expr *expr) 575 1.1 mrg { 576 1.1 mrg gfc_expr *e; 577 1.1 mrg gfc_se se_len; 578 1.1 mrg e = gfc_find_and_cut_at_last_class_ref (expr); 579 1.1 mrg if (e == NULL) 580 1.1 mrg return; 581 1.1 mrg gfc_add_len_component (e); 582 1.1 mrg gfc_init_se (&se_len, NULL); 583 1.1 mrg gfc_conv_expr (&se_len, e); 584 1.1 mrg gfc_add_modify (block, se_len.expr, 585 1.1 mrg fold_convert (TREE_TYPE (se_len.expr), integer_zero_node)); 586 1.1 mrg gfc_free_expr (e); 587 1.1 mrg } 588 1.1 mrg 589 1.1 mrg 590 1.1 mrg /* Obtain the last class reference in a gfc_expr. Return NULL_TREE if no class 591 1.1 mrg reference is found. Note that it is up to the caller to avoid using this 592 1.1 mrg for expressions other than variables. */ 593 1.1 mrg 594 1.1 mrg tree 595 1.1 mrg gfc_get_class_from_gfc_expr (gfc_expr *e) 596 1.1 mrg { 597 1.1 mrg gfc_expr *class_expr; 598 1.1 mrg gfc_se cse; 599 1.1 mrg class_expr = gfc_find_and_cut_at_last_class_ref (e); 600 1.1 mrg if (class_expr == NULL) 601 1.1 mrg return NULL_TREE; 602 1.1 mrg gfc_init_se (&cse, NULL); 603 1.1 mrg gfc_conv_expr (&cse, class_expr); 604 1.1 mrg gfc_free_expr (class_expr); 605 1.1 mrg return cse.expr; 606 1.1 mrg } 607 1.1 mrg 608 1.1 mrg 609 1.1 mrg /* Obtain the last class reference in an expression. 610 1.1 mrg Return NULL_TREE if no class reference is found. */ 611 1.1 mrg 612 1.1 mrg tree 613 1.1 mrg gfc_get_class_from_expr (tree expr) 614 1.1 mrg { 615 1.1 mrg tree tmp; 616 1.1 mrg tree type; 617 1.1 mrg 618 1.1 mrg for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0)) 619 1.1 mrg { 620 1.1 mrg if (CONSTANT_CLASS_P (tmp)) 621 1.1 mrg return NULL_TREE; 622 1.1 mrg 623 1.1 mrg type = TREE_TYPE (tmp); 624 1.1 mrg while (type) 625 1.1 mrg { 626 1.1 mrg if (GFC_CLASS_TYPE_P (type)) 627 1.1 mrg return tmp; 628 1.1 mrg if (type != TYPE_CANONICAL (type)) 629 1.1 mrg type = TYPE_CANONICAL (type); 630 1.1 mrg else 631 1.1 mrg type = NULL_TREE; 632 1.1 mrg } 633 1.1 mrg if (VAR_P (tmp) || TREE_CODE (tmp) == PARM_DECL) 634 1.1 mrg break; 635 1.1 mrg } 636 1.1 mrg 637 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (tmp))) 638 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp); 639 1.1 mrg 640 1.1 mrg if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))) 641 1.1 mrg return tmp; 642 1.1 mrg 643 1.1 mrg return NULL_TREE; 644 1.1 mrg } 645 1.1 mrg 646 1.1 mrg 647 1.1 mrg /* Obtain the vptr of the last class reference in an expression. 648 1.1 mrg Return NULL_TREE if no class reference is found. */ 649 1.1 mrg 650 1.1 mrg tree 651 1.1 mrg gfc_get_vptr_from_expr (tree expr) 652 1.1 mrg { 653 1.1 mrg tree tmp; 654 1.1 mrg 655 1.1 mrg tmp = gfc_get_class_from_expr (expr); 656 1.1 mrg 657 1.1 mrg if (tmp != NULL_TREE) 658 1.1 mrg return gfc_class_vptr_get (tmp); 659 1.1 mrg 660 1.1 mrg return NULL_TREE; 661 1.1 mrg } 662 1.1 mrg 663 1.1 mrg 664 1.1 mrg static void 665 1.1 mrg class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc, 666 1.1 mrg bool lhs_type) 667 1.1 mrg { 668 1.1 mrg tree tmp, tmp2, type; 669 1.1 mrg 670 1.1 mrg gfc_conv_descriptor_data_set (block, lhs_desc, 671 1.1 mrg gfc_conv_descriptor_data_get (rhs_desc)); 672 1.1 mrg gfc_conv_descriptor_offset_set (block, lhs_desc, 673 1.1 mrg gfc_conv_descriptor_offset_get (rhs_desc)); 674 1.1 mrg 675 1.1 mrg gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc), 676 1.1 mrg gfc_conv_descriptor_dtype (rhs_desc)); 677 1.1 mrg 678 1.1 mrg /* Assign the dimension as range-ref. */ 679 1.1 mrg tmp = gfc_get_descriptor_dimension (lhs_desc); 680 1.1 mrg tmp2 = gfc_get_descriptor_dimension (rhs_desc); 681 1.1 mrg 682 1.1 mrg type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2); 683 1.1 mrg tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp, 684 1.1 mrg gfc_index_zero_node, NULL_TREE, NULL_TREE); 685 1.1 mrg tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2, 686 1.1 mrg gfc_index_zero_node, NULL_TREE, NULL_TREE); 687 1.1 mrg gfc_add_modify (block, tmp, tmp2); 688 1.1 mrg } 689 1.1 mrg 690 1.1 mrg 691 1.1 mrg /* Takes a derived type expression and returns the address of a temporary 692 1.1 mrg class object of the 'declared' type. If vptr is not NULL, this is 693 1.1 mrg used for the temporary class object. 694 1.1 mrg optional_alloc_ptr is false when the dummy is neither allocatable 695 1.1 mrg nor a pointer; that's only relevant for the optional handling. 696 1.1 mrg The optional argument 'derived_array' is used to preserve the parmse 697 1.1 mrg expression for deallocation of allocatable components. Assumed rank 698 1.1 mrg formal arguments made this necessary. */ 699 1.1 mrg void 700 1.1 mrg gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, 701 1.1 mrg gfc_typespec class_ts, tree vptr, bool optional, 702 1.1 mrg bool optional_alloc_ptr, 703 1.1 mrg tree *derived_array) 704 1.1 mrg { 705 1.1 mrg gfc_symbol *vtab; 706 1.1 mrg tree cond_optional = NULL_TREE; 707 1.1 mrg gfc_ss *ss; 708 1.1 mrg tree ctree; 709 1.1 mrg tree var; 710 1.1 mrg tree tmp; 711 1.1 mrg int dim; 712 1.1 mrg 713 1.1 mrg /* The derived type needs to be converted to a temporary 714 1.1 mrg CLASS object. */ 715 1.1 mrg tmp = gfc_typenode_for_spec (&class_ts); 716 1.1 mrg var = gfc_create_var (tmp, "class"); 717 1.1 mrg 718 1.1 mrg /* Set the vptr. */ 719 1.1 mrg ctree = gfc_class_vptr_get (var); 720 1.1 mrg 721 1.1 mrg if (vptr != NULL_TREE) 722 1.1 mrg { 723 1.1 mrg /* Use the dynamic vptr. */ 724 1.1 mrg tmp = vptr; 725 1.1 mrg } 726 1.1 mrg else 727 1.1 mrg { 728 1.1 mrg /* In this case the vtab corresponds to the derived type and the 729 1.1 mrg vptr must point to it. */ 730 1.1 mrg vtab = gfc_find_derived_vtab (e->ts.u.derived); 731 1.1 mrg gcc_assert (vtab); 732 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab)); 733 1.1 mrg } 734 1.1 mrg gfc_add_modify (&parmse->pre, ctree, 735 1.1 mrg fold_convert (TREE_TYPE (ctree), tmp)); 736 1.1 mrg 737 1.1 mrg /* Now set the data field. */ 738 1.1 mrg ctree = gfc_class_data_get (var); 739 1.1 mrg 740 1.1 mrg if (optional) 741 1.1 mrg cond_optional = gfc_conv_expr_present (e->symtree->n.sym); 742 1.1 mrg 743 1.1 mrg if (parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr))) 744 1.1 mrg { 745 1.1 mrg /* If there is a ready made pointer to a derived type, use it 746 1.1 mrg rather than evaluating the expression again. */ 747 1.1 mrg tmp = fold_convert (TREE_TYPE (ctree), parmse->expr); 748 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp); 749 1.1 mrg } 750 1.1 mrg else if (parmse->ss && parmse->ss->info && parmse->ss->info->useflags) 751 1.1 mrg { 752 1.1 mrg /* For an array reference in an elemental procedure call we need 753 1.1 mrg to retain the ss to provide the scalarized array reference. */ 754 1.1 mrg gfc_conv_expr_reference (parmse, e); 755 1.1 mrg tmp = fold_convert (TREE_TYPE (ctree), parmse->expr); 756 1.1 mrg if (optional) 757 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), 758 1.1 mrg cond_optional, tmp, 759 1.1 mrg fold_convert (TREE_TYPE (tmp), null_pointer_node)); 760 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp); 761 1.1 mrg } 762 1.1 mrg else 763 1.1 mrg { 764 1.1 mrg ss = gfc_walk_expr (e); 765 1.1 mrg if (ss == gfc_ss_terminator) 766 1.1 mrg { 767 1.1 mrg parmse->ss = NULL; 768 1.1 mrg gfc_conv_expr_reference (parmse, e); 769 1.1 mrg 770 1.1 mrg /* Scalar to an assumed-rank array. */ 771 1.1 mrg if (class_ts.u.derived->components->as) 772 1.1 mrg { 773 1.1 mrg tree type; 774 1.1 mrg type = get_scalar_to_descriptor_type (parmse->expr, 775 1.1 mrg gfc_expr_attr (e)); 776 1.1 mrg gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree), 777 1.1 mrg gfc_get_dtype (type)); 778 1.1 mrg if (optional) 779 1.1 mrg parmse->expr = build3_loc (input_location, COND_EXPR, 780 1.1 mrg TREE_TYPE (parmse->expr), 781 1.1 mrg cond_optional, parmse->expr, 782 1.1 mrg fold_convert (TREE_TYPE (parmse->expr), 783 1.1 mrg null_pointer_node)); 784 1.1 mrg gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr); 785 1.1 mrg } 786 1.1 mrg else 787 1.1 mrg { 788 1.1 mrg tmp = fold_convert (TREE_TYPE (ctree), parmse->expr); 789 1.1 mrg if (optional) 790 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), 791 1.1 mrg cond_optional, tmp, 792 1.1 mrg fold_convert (TREE_TYPE (tmp), 793 1.1 mrg null_pointer_node)); 794 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp); 795 1.1 mrg } 796 1.1 mrg } 797 1.1 mrg else 798 1.1 mrg { 799 1.1 mrg stmtblock_t block; 800 1.1 mrg gfc_init_block (&block); 801 1.1 mrg gfc_ref *ref; 802 1.1 mrg 803 1.1 mrg parmse->ss = ss; 804 1.1 mrg parmse->use_offset = 1; 805 1.1 mrg gfc_conv_expr_descriptor (parmse, e); 806 1.1 mrg 807 1.1 mrg /* Detect any array references with vector subscripts. */ 808 1.1 mrg for (ref = e->ref; ref; ref = ref->next) 809 1.1 mrg if (ref->type == REF_ARRAY 810 1.1 mrg && ref->u.ar.type != AR_ELEMENT 811 1.1 mrg && ref->u.ar.type != AR_FULL) 812 1.1 mrg { 813 1.1 mrg for (dim = 0; dim < ref->u.ar.dimen; dim++) 814 1.1 mrg if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR) 815 1.1 mrg break; 816 1.1 mrg if (dim < ref->u.ar.dimen) 817 1.1 mrg break; 818 1.1 mrg } 819 1.1 mrg 820 1.1 mrg /* Array references with vector subscripts and non-variable expressions 821 1.1 mrg need be converted to a one-based descriptor. */ 822 1.1 mrg if (ref || e->expr_type != EXPR_VARIABLE) 823 1.1 mrg { 824 1.1 mrg for (dim = 0; dim < e->rank; ++dim) 825 1.1 mrg gfc_conv_shift_descriptor_lbound (&block, parmse->expr, dim, 826 1.1 mrg gfc_index_one_node); 827 1.1 mrg } 828 1.1 mrg 829 1.1 mrg if (e->rank != class_ts.u.derived->components->as->rank) 830 1.1 mrg { 831 1.1 mrg gcc_assert (class_ts.u.derived->components->as->type 832 1.1 mrg == AS_ASSUMED_RANK); 833 1.1 mrg if (derived_array 834 1.1 mrg && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse->expr))) 835 1.1 mrg { 836 1.1 mrg *derived_array = gfc_create_var (TREE_TYPE (parmse->expr), 837 1.1 mrg "array"); 838 1.1 mrg gfc_add_modify (&block, *derived_array , parmse->expr); 839 1.1 mrg } 840 1.1 mrg class_array_data_assign (&block, ctree, parmse->expr, false); 841 1.1 mrg } 842 1.1 mrg else 843 1.1 mrg { 844 1.1 mrg if (gfc_expr_attr (e).codimension) 845 1.1 mrg parmse->expr = fold_build1_loc (input_location, 846 1.1 mrg VIEW_CONVERT_EXPR, 847 1.1 mrg TREE_TYPE (ctree), 848 1.1 mrg parmse->expr); 849 1.1 mrg gfc_add_modify (&block, ctree, parmse->expr); 850 1.1 mrg } 851 1.1 mrg 852 1.1 mrg if (optional) 853 1.1 mrg { 854 1.1 mrg tmp = gfc_finish_block (&block); 855 1.1 mrg 856 1.1 mrg gfc_init_block (&block); 857 1.1 mrg gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node); 858 1.1 mrg if (derived_array && *derived_array != NULL_TREE) 859 1.1 mrg gfc_conv_descriptor_data_set (&block, *derived_array, 860 1.1 mrg null_pointer_node); 861 1.1 mrg 862 1.1 mrg tmp = build3_v (COND_EXPR, cond_optional, tmp, 863 1.1 mrg gfc_finish_block (&block)); 864 1.1 mrg gfc_add_expr_to_block (&parmse->pre, tmp); 865 1.1 mrg } 866 1.1 mrg else 867 1.1 mrg gfc_add_block_to_block (&parmse->pre, &block); 868 1.1 mrg } 869 1.1 mrg } 870 1.1 mrg 871 1.1 mrg if (class_ts.u.derived->components->ts.type == BT_DERIVED 872 1.1 mrg && class_ts.u.derived->components->ts.u.derived 873 1.1 mrg ->attr.unlimited_polymorphic) 874 1.1 mrg { 875 1.1 mrg /* Take care about initializing the _len component correctly. */ 876 1.1 mrg ctree = gfc_class_len_get (var); 877 1.1 mrg if (UNLIMITED_POLY (e)) 878 1.1 mrg { 879 1.1 mrg gfc_expr *len; 880 1.1 mrg gfc_se se; 881 1.1 mrg 882 1.1 mrg len = gfc_find_and_cut_at_last_class_ref (e); 883 1.1 mrg gfc_add_len_component (len); 884 1.1 mrg gfc_init_se (&se, NULL); 885 1.1 mrg gfc_conv_expr (&se, len); 886 1.1 mrg if (optional) 887 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr), 888 1.1 mrg cond_optional, se.expr, 889 1.1 mrg fold_convert (TREE_TYPE (se.expr), 890 1.1 mrg integer_zero_node)); 891 1.1 mrg else 892 1.1 mrg tmp = se.expr; 893 1.1 mrg gfc_free_expr (len); 894 1.1 mrg } 895 1.1 mrg else 896 1.1 mrg tmp = integer_zero_node; 897 1.1 mrg gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), 898 1.1 mrg tmp)); 899 1.1 mrg } 900 1.1 mrg /* Pass the address of the class object. */ 901 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL_TREE, var); 902 1.1 mrg 903 1.1 mrg if (optional && optional_alloc_ptr) 904 1.1 mrg parmse->expr = build3_loc (input_location, COND_EXPR, 905 1.1 mrg TREE_TYPE (parmse->expr), 906 1.1 mrg cond_optional, parmse->expr, 907 1.1 mrg fold_convert (TREE_TYPE (parmse->expr), 908 1.1 mrg null_pointer_node)); 909 1.1 mrg } 910 1.1 mrg 911 1.1 mrg 912 1.1 mrg /* Create a new class container, which is required as scalar coarrays 913 1.1 mrg have an array descriptor while normal scalars haven't. Optionally, 914 1.1 mrg NULL pointer checks are added if the argument is OPTIONAL. */ 915 1.1 mrg 916 1.1 mrg static void 917 1.1 mrg class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e, 918 1.1 mrg gfc_typespec class_ts, bool optional) 919 1.1 mrg { 920 1.1 mrg tree var, ctree, tmp; 921 1.1 mrg stmtblock_t block; 922 1.1 mrg gfc_ref *ref; 923 1.1 mrg gfc_ref *class_ref; 924 1.1 mrg 925 1.1 mrg gfc_init_block (&block); 926 1.1 mrg 927 1.1 mrg class_ref = NULL; 928 1.1 mrg for (ref = e->ref; ref; ref = ref->next) 929 1.1 mrg { 930 1.1 mrg if (ref->type == REF_COMPONENT 931 1.1 mrg && ref->u.c.component->ts.type == BT_CLASS) 932 1.1 mrg class_ref = ref; 933 1.1 mrg } 934 1.1 mrg 935 1.1 mrg if (class_ref == NULL 936 1.1 mrg && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS) 937 1.1 mrg tmp = e->symtree->n.sym->backend_decl; 938 1.1 mrg else 939 1.1 mrg { 940 1.1 mrg /* Remove everything after the last class reference, convert the 941 1.1 mrg expression and then recover its tailend once more. */ 942 1.1 mrg gfc_se tmpse; 943 1.1 mrg ref = class_ref->next; 944 1.1 mrg class_ref->next = NULL; 945 1.1 mrg gfc_init_se (&tmpse, NULL); 946 1.1 mrg gfc_conv_expr (&tmpse, e); 947 1.1 mrg class_ref->next = ref; 948 1.1 mrg tmp = tmpse.expr; 949 1.1 mrg } 950 1.1 mrg 951 1.1 mrg var = gfc_typenode_for_spec (&class_ts); 952 1.1 mrg var = gfc_create_var (var, "class"); 953 1.1 mrg 954 1.1 mrg ctree = gfc_class_vptr_get (var); 955 1.1 mrg gfc_add_modify (&block, ctree, 956 1.1 mrg fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp))); 957 1.1 mrg 958 1.1 mrg ctree = gfc_class_data_get (var); 959 1.1 mrg tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp)); 960 1.1 mrg gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp)); 961 1.1 mrg 962 1.1 mrg /* Pass the address of the class object. */ 963 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL_TREE, var); 964 1.1 mrg 965 1.1 mrg if (optional) 966 1.1 mrg { 967 1.1 mrg tree cond = gfc_conv_expr_present (e->symtree->n.sym); 968 1.1 mrg tree tmp2; 969 1.1 mrg 970 1.1 mrg tmp = gfc_finish_block (&block); 971 1.1 mrg 972 1.1 mrg gfc_init_block (&block); 973 1.1 mrg tmp2 = gfc_class_data_get (var); 974 1.1 mrg gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2), 975 1.1 mrg null_pointer_node)); 976 1.1 mrg tmp2 = gfc_finish_block (&block); 977 1.1 mrg 978 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, void_type_node, 979 1.1 mrg cond, tmp, tmp2); 980 1.1 mrg gfc_add_expr_to_block (&parmse->pre, tmp); 981 1.1 mrg } 982 1.1 mrg else 983 1.1 mrg gfc_add_block_to_block (&parmse->pre, &block); 984 1.1 mrg } 985 1.1 mrg 986 1.1 mrg 987 1.1 mrg /* Takes an intrinsic type expression and returns the address of a temporary 988 1.1 mrg class object of the 'declared' type. */ 989 1.1 mrg void 990 1.1 mrg gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e, 991 1.1 mrg gfc_typespec class_ts) 992 1.1 mrg { 993 1.1 mrg gfc_symbol *vtab; 994 1.1 mrg gfc_ss *ss; 995 1.1 mrg tree ctree; 996 1.1 mrg tree var; 997 1.1 mrg tree tmp; 998 1.1 mrg int dim; 999 1.1 mrg 1000 1.1 mrg /* The intrinsic type needs to be converted to a temporary 1001 1.1 mrg CLASS object. */ 1002 1.1 mrg tmp = gfc_typenode_for_spec (&class_ts); 1003 1.1 mrg var = gfc_create_var (tmp, "class"); 1004 1.1 mrg 1005 1.1 mrg /* Set the vptr. */ 1006 1.1 mrg ctree = gfc_class_vptr_get (var); 1007 1.1 mrg 1008 1.1 mrg vtab = gfc_find_vtab (&e->ts); 1009 1.1 mrg gcc_assert (vtab); 1010 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab)); 1011 1.1 mrg gfc_add_modify (&parmse->pre, ctree, 1012 1.1 mrg fold_convert (TREE_TYPE (ctree), tmp)); 1013 1.1 mrg 1014 1.1 mrg /* Now set the data field. */ 1015 1.1 mrg ctree = gfc_class_data_get (var); 1016 1.1 mrg if (parmse->ss && parmse->ss->info->useflags) 1017 1.1 mrg { 1018 1.1 mrg /* For an array reference in an elemental procedure call we need 1019 1.1 mrg to retain the ss to provide the scalarized array reference. */ 1020 1.1 mrg gfc_conv_expr_reference (parmse, e); 1021 1.1 mrg tmp = fold_convert (TREE_TYPE (ctree), parmse->expr); 1022 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp); 1023 1.1 mrg } 1024 1.1 mrg else 1025 1.1 mrg { 1026 1.1 mrg ss = gfc_walk_expr (e); 1027 1.1 mrg if (ss == gfc_ss_terminator) 1028 1.1 mrg { 1029 1.1 mrg parmse->ss = NULL; 1030 1.1 mrg gfc_conv_expr_reference (parmse, e); 1031 1.1 mrg if (class_ts.u.derived->components->as 1032 1.1 mrg && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK) 1033 1.1 mrg { 1034 1.1 mrg tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr, 1035 1.1 mrg gfc_expr_attr (e)); 1036 1.1 mrg tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR, 1037 1.1 mrg TREE_TYPE (ctree), tmp); 1038 1.1 mrg } 1039 1.1 mrg else 1040 1.1 mrg tmp = fold_convert (TREE_TYPE (ctree), parmse->expr); 1041 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp); 1042 1.1 mrg } 1043 1.1 mrg else 1044 1.1 mrg { 1045 1.1 mrg parmse->ss = ss; 1046 1.1 mrg parmse->use_offset = 1; 1047 1.1 mrg gfc_conv_expr_descriptor (parmse, e); 1048 1.1 mrg 1049 1.1 mrg /* Array references with vector subscripts and non-variable expressions 1050 1.1 mrg need be converted to a one-based descriptor. */ 1051 1.1 mrg if (e->expr_type != EXPR_VARIABLE) 1052 1.1 mrg { 1053 1.1 mrg for (dim = 0; dim < e->rank; ++dim) 1054 1.1 mrg gfc_conv_shift_descriptor_lbound (&parmse->pre, parmse->expr, 1055 1.1 mrg dim, gfc_index_one_node); 1056 1.1 mrg } 1057 1.1 mrg 1058 1.1 mrg if (class_ts.u.derived->components->as->rank != e->rank) 1059 1.1 mrg { 1060 1.1 mrg tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR, 1061 1.1 mrg TREE_TYPE (ctree), parmse->expr); 1062 1.1 mrg gfc_add_modify (&parmse->pre, ctree, tmp); 1063 1.1 mrg } 1064 1.1 mrg else 1065 1.1 mrg gfc_add_modify (&parmse->pre, ctree, parmse->expr); 1066 1.1 mrg } 1067 1.1 mrg } 1068 1.1 mrg 1069 1.1 mrg gcc_assert (class_ts.type == BT_CLASS); 1070 1.1 mrg if (class_ts.u.derived->components->ts.type == BT_DERIVED 1071 1.1 mrg && class_ts.u.derived->components->ts.u.derived 1072 1.1 mrg ->attr.unlimited_polymorphic) 1073 1.1 mrg { 1074 1.1 mrg ctree = gfc_class_len_get (var); 1075 1.1 mrg /* When the actual arg is a char array, then set the _len component of the 1076 1.1 mrg unlimited polymorphic entity to the length of the string. */ 1077 1.1 mrg if (e->ts.type == BT_CHARACTER) 1078 1.1 mrg { 1079 1.1 mrg /* Start with parmse->string_length because this seems to be set to a 1080 1.1 mrg correct value more often. */ 1081 1.1 mrg if (parmse->string_length) 1082 1.1 mrg tmp = parmse->string_length; 1083 1.1 mrg /* When the string_length is not yet set, then try the backend_decl of 1084 1.1 mrg the cl. */ 1085 1.1 mrg else if (e->ts.u.cl->backend_decl) 1086 1.1 mrg tmp = e->ts.u.cl->backend_decl; 1087 1.1 mrg /* If both of the above approaches fail, then try to generate an 1088 1.1 mrg expression from the input, which is only feasible currently, when the 1089 1.1 mrg expression can be evaluated to a constant one. */ 1090 1.1 mrg else 1091 1.1 mrg { 1092 1.1 mrg /* Try to simplify the expression. */ 1093 1.1 mrg gfc_simplify_expr (e, 0); 1094 1.1 mrg if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved) 1095 1.1 mrg { 1096 1.1 mrg /* Amazingly all data is present to compute the length of a 1097 1.1 mrg constant string, but the expression is not yet there. */ 1098 1.1 mrg e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER, 1099 1.1 mrg gfc_charlen_int_kind, 1100 1.1 mrg &e->where); 1101 1.1 mrg mpz_set_ui (e->ts.u.cl->length->value.integer, 1102 1.1 mrg e->value.character.length); 1103 1.1 mrg gfc_conv_const_charlen (e->ts.u.cl); 1104 1.1 mrg e->ts.u.cl->resolved = 1; 1105 1.1 mrg tmp = e->ts.u.cl->backend_decl; 1106 1.1 mrg } 1107 1.1 mrg else 1108 1.1 mrg { 1109 1.1 mrg gfc_error ("Cannot compute the length of the char array " 1110 1.1 mrg "at %L.", &e->where); 1111 1.1 mrg } 1112 1.1 mrg } 1113 1.1 mrg } 1114 1.1 mrg else 1115 1.1 mrg tmp = integer_zero_node; 1116 1.1 mrg 1117 1.1 mrg gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp)); 1118 1.1 mrg } 1119 1.1 mrg else if (class_ts.type == BT_CLASS 1120 1.1 mrg && class_ts.u.derived->components 1121 1.1 mrg && class_ts.u.derived->components->ts.u 1122 1.1 mrg .derived->attr.unlimited_polymorphic) 1123 1.1 mrg { 1124 1.1 mrg ctree = gfc_class_len_get (var); 1125 1.1 mrg gfc_add_modify (&parmse->pre, ctree, 1126 1.1 mrg fold_convert (TREE_TYPE (ctree), 1127 1.1 mrg integer_zero_node)); 1128 1.1 mrg } 1129 1.1 mrg /* Pass the address of the class object. */ 1130 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL_TREE, var); 1131 1.1 mrg } 1132 1.1 mrg 1133 1.1 mrg 1134 1.1 mrg /* Takes a scalarized class array expression and returns the 1135 1.1 mrg address of a temporary scalar class object of the 'declared' 1136 1.1 mrg type. 1137 1.1 mrg OOP-TODO: This could be improved by adding code that branched on 1138 1.1 mrg the dynamic type being the same as the declared type. In this case 1139 1.1 mrg the original class expression can be passed directly. 1140 1.1 mrg optional_alloc_ptr is false when the dummy is neither allocatable 1141 1.1 mrg nor a pointer; that's relevant for the optional handling. 1142 1.1 mrg Set copyback to true if class container's _data and _vtab pointers 1143 1.1 mrg might get modified. */ 1144 1.1 mrg 1145 1.1 mrg void 1146 1.1 mrg gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts, 1147 1.1 mrg bool elemental, bool copyback, bool optional, 1148 1.1 mrg bool optional_alloc_ptr) 1149 1.1 mrg { 1150 1.1 mrg tree ctree; 1151 1.1 mrg tree var; 1152 1.1 mrg tree tmp; 1153 1.1 mrg tree vptr; 1154 1.1 mrg tree cond = NULL_TREE; 1155 1.1 mrg tree slen = NULL_TREE; 1156 1.1 mrg gfc_ref *ref; 1157 1.1 mrg gfc_ref *class_ref; 1158 1.1 mrg stmtblock_t block; 1159 1.1 mrg bool full_array = false; 1160 1.1 mrg 1161 1.1 mrg gfc_init_block (&block); 1162 1.1 mrg 1163 1.1 mrg class_ref = NULL; 1164 1.1 mrg for (ref = e->ref; ref; ref = ref->next) 1165 1.1 mrg { 1166 1.1 mrg if (ref->type == REF_COMPONENT 1167 1.1 mrg && ref->u.c.component->ts.type == BT_CLASS) 1168 1.1 mrg class_ref = ref; 1169 1.1 mrg 1170 1.1 mrg if (ref->next == NULL) 1171 1.1 mrg break; 1172 1.1 mrg } 1173 1.1 mrg 1174 1.1 mrg if ((ref == NULL || class_ref == ref) 1175 1.1 mrg && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE) 1176 1.1 mrg && (!class_ts.u.derived->components->as 1177 1.1 mrg || class_ts.u.derived->components->as->rank != -1)) 1178 1.1 mrg return; 1179 1.1 mrg 1180 1.1 mrg /* Test for FULL_ARRAY. */ 1181 1.1 mrg if (e->rank == 0 1182 1.1 mrg && ((gfc_expr_attr (e).codimension && gfc_expr_attr (e).dimension) 1183 1.1 mrg || (class_ts.u.derived->components->as 1184 1.1 mrg && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK))) 1185 1.1 mrg full_array = true; 1186 1.1 mrg else 1187 1.1 mrg gfc_is_class_array_ref (e, &full_array); 1188 1.1 mrg 1189 1.1 mrg /* The derived type needs to be converted to a temporary 1190 1.1 mrg CLASS object. */ 1191 1.1 mrg tmp = gfc_typenode_for_spec (&class_ts); 1192 1.1 mrg var = gfc_create_var (tmp, "class"); 1193 1.1 mrg 1194 1.1 mrg /* Set the data. */ 1195 1.1 mrg ctree = gfc_class_data_get (var); 1196 1.1 mrg if (class_ts.u.derived->components->as 1197 1.1 mrg && e->rank != class_ts.u.derived->components->as->rank) 1198 1.1 mrg { 1199 1.1 mrg if (e->rank == 0) 1200 1.1 mrg { 1201 1.1 mrg tree type = get_scalar_to_descriptor_type (parmse->expr, 1202 1.1 mrg gfc_expr_attr (e)); 1203 1.1 mrg gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree), 1204 1.1 mrg gfc_get_dtype (type)); 1205 1.1 mrg 1206 1.1 mrg tmp = gfc_class_data_get (parmse->expr); 1207 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp))) 1208 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp); 1209 1.1 mrg 1210 1.1 mrg gfc_conv_descriptor_data_set (&block, ctree, tmp); 1211 1.1 mrg } 1212 1.1 mrg else 1213 1.1 mrg class_array_data_assign (&block, ctree, parmse->expr, false); 1214 1.1 mrg } 1215 1.1 mrg else 1216 1.1 mrg { 1217 1.1 mrg if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree)) 1218 1.1 mrg parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR, 1219 1.1 mrg TREE_TYPE (ctree), parmse->expr); 1220 1.1 mrg gfc_add_modify (&block, ctree, parmse->expr); 1221 1.1 mrg } 1222 1.1 mrg 1223 1.1 mrg /* Return the data component, except in the case of scalarized array 1224 1.1 mrg references, where nullification of the cannot occur and so there 1225 1.1 mrg is no need. */ 1226 1.1 mrg if (!elemental && full_array && copyback) 1227 1.1 mrg { 1228 1.1 mrg if (class_ts.u.derived->components->as 1229 1.1 mrg && e->rank != class_ts.u.derived->components->as->rank) 1230 1.1 mrg { 1231 1.1 mrg if (e->rank == 0) 1232 1.1 mrg { 1233 1.1 mrg tmp = gfc_class_data_get (parmse->expr); 1234 1.1 mrg gfc_add_modify (&parmse->post, tmp, 1235 1.1 mrg fold_convert (TREE_TYPE (tmp), 1236 1.1 mrg gfc_conv_descriptor_data_get (ctree))); 1237 1.1 mrg } 1238 1.1 mrg else 1239 1.1 mrg class_array_data_assign (&parmse->post, parmse->expr, ctree, true); 1240 1.1 mrg } 1241 1.1 mrg else 1242 1.1 mrg gfc_add_modify (&parmse->post, parmse->expr, ctree); 1243 1.1 mrg } 1244 1.1 mrg 1245 1.1 mrg /* Set the vptr. */ 1246 1.1 mrg ctree = gfc_class_vptr_get (var); 1247 1.1 mrg 1248 1.1 mrg /* The vptr is the second field of the actual argument. 1249 1.1 mrg First we have to find the corresponding class reference. */ 1250 1.1 mrg 1251 1.1 mrg tmp = NULL_TREE; 1252 1.1 mrg if (gfc_is_class_array_function (e) 1253 1.1 mrg && parmse->class_vptr != NULL_TREE) 1254 1.1 mrg tmp = parmse->class_vptr; 1255 1.1 mrg else if (class_ref == NULL 1256 1.1 mrg && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS) 1257 1.1 mrg { 1258 1.1 mrg tmp = e->symtree->n.sym->backend_decl; 1259 1.1 mrg 1260 1.1 mrg if (TREE_CODE (tmp) == FUNCTION_DECL) 1261 1.1 mrg tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0); 1262 1.1 mrg 1263 1.1 mrg if (DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp)) 1264 1.1 mrg tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp); 1265 1.1 mrg 1266 1.1 mrg slen = build_zero_cst (size_type_node); 1267 1.1 mrg } 1268 1.1 mrg else 1269 1.1 mrg { 1270 1.1 mrg /* Remove everything after the last class reference, convert the 1271 1.1 mrg expression and then recover its tailend once more. */ 1272 1.1 mrg gfc_se tmpse; 1273 1.1 mrg ref = class_ref->next; 1274 1.1 mrg class_ref->next = NULL; 1275 1.1 mrg gfc_init_se (&tmpse, NULL); 1276 1.1 mrg gfc_conv_expr (&tmpse, e); 1277 1.1 mrg class_ref->next = ref; 1278 1.1 mrg tmp = tmpse.expr; 1279 1.1 mrg slen = tmpse.string_length; 1280 1.1 mrg } 1281 1.1 mrg 1282 1.1 mrg gcc_assert (tmp != NULL_TREE); 1283 1.1 mrg 1284 1.1 mrg /* Dereference if needs be. */ 1285 1.1 mrg if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE) 1286 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp); 1287 1.1 mrg 1288 1.1 mrg if (!(gfc_is_class_array_function (e) && parmse->class_vptr)) 1289 1.1 mrg vptr = gfc_class_vptr_get (tmp); 1290 1.1 mrg else 1291 1.1 mrg vptr = tmp; 1292 1.1 mrg 1293 1.1 mrg gfc_add_modify (&block, ctree, 1294 1.1 mrg fold_convert (TREE_TYPE (ctree), vptr)); 1295 1.1 mrg 1296 1.1 mrg /* Return the vptr component, except in the case of scalarized array 1297 1.1 mrg references, where the dynamic type cannot change. */ 1298 1.1 mrg if (!elemental && full_array && copyback) 1299 1.1 mrg gfc_add_modify (&parmse->post, vptr, 1300 1.1 mrg fold_convert (TREE_TYPE (vptr), ctree)); 1301 1.1 mrg 1302 1.1 mrg /* For unlimited polymorphic objects also set the _len component. */ 1303 1.1 mrg if (class_ts.type == BT_CLASS 1304 1.1 mrg && class_ts.u.derived->components 1305 1.1 mrg && class_ts.u.derived->components->ts.u 1306 1.1 mrg .derived->attr.unlimited_polymorphic) 1307 1.1 mrg { 1308 1.1 mrg ctree = gfc_class_len_get (var); 1309 1.1 mrg if (UNLIMITED_POLY (e)) 1310 1.1 mrg tmp = gfc_class_len_get (tmp); 1311 1.1 mrg else if (e->ts.type == BT_CHARACTER) 1312 1.1 mrg { 1313 1.1 mrg gcc_assert (slen != NULL_TREE); 1314 1.1 mrg tmp = slen; 1315 1.1 mrg } 1316 1.1 mrg else 1317 1.1 mrg tmp = build_zero_cst (size_type_node); 1318 1.1 mrg gfc_add_modify (&parmse->pre, ctree, 1319 1.1 mrg fold_convert (TREE_TYPE (ctree), tmp)); 1320 1.1 mrg 1321 1.1 mrg /* Return the len component, except in the case of scalarized array 1322 1.1 mrg references, where the dynamic type cannot change. */ 1323 1.1 mrg if (!elemental && full_array && copyback 1324 1.1 mrg && (UNLIMITED_POLY (e) || VAR_P (tmp))) 1325 1.1 mrg gfc_add_modify (&parmse->post, tmp, 1326 1.1 mrg fold_convert (TREE_TYPE (tmp), ctree)); 1327 1.1 mrg } 1328 1.1 mrg 1329 1.1 mrg if (optional) 1330 1.1 mrg { 1331 1.1 mrg tree tmp2; 1332 1.1 mrg 1333 1.1 mrg cond = gfc_conv_expr_present (e->symtree->n.sym); 1334 1.1 mrg /* parmse->pre may contain some preparatory instructions for the 1335 1.1 mrg temporary array descriptor. Those may only be executed when the 1336 1.1 mrg optional argument is set, therefore add parmse->pre's instructions 1337 1.1 mrg to block, which is later guarded by an if (optional_arg_given). */ 1338 1.1 mrg gfc_add_block_to_block (&parmse->pre, &block); 1339 1.1 mrg block.head = parmse->pre.head; 1340 1.1 mrg parmse->pre.head = NULL_TREE; 1341 1.1 mrg tmp = gfc_finish_block (&block); 1342 1.1 mrg 1343 1.1 mrg if (optional_alloc_ptr) 1344 1.1 mrg tmp2 = build_empty_stmt (input_location); 1345 1.1 mrg else 1346 1.1 mrg { 1347 1.1 mrg gfc_init_block (&block); 1348 1.1 mrg 1349 1.1 mrg tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var)); 1350 1.1 mrg gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2), 1351 1.1 mrg null_pointer_node)); 1352 1.1 mrg tmp2 = gfc_finish_block (&block); 1353 1.1 mrg } 1354 1.1 mrg 1355 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, void_type_node, 1356 1.1 mrg cond, tmp, tmp2); 1357 1.1 mrg gfc_add_expr_to_block (&parmse->pre, tmp); 1358 1.1 mrg } 1359 1.1 mrg else 1360 1.1 mrg gfc_add_block_to_block (&parmse->pre, &block); 1361 1.1 mrg 1362 1.1 mrg /* Pass the address of the class object. */ 1363 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL_TREE, var); 1364 1.1 mrg 1365 1.1 mrg if (optional && optional_alloc_ptr) 1366 1.1 mrg parmse->expr = build3_loc (input_location, COND_EXPR, 1367 1.1 mrg TREE_TYPE (parmse->expr), 1368 1.1 mrg cond, parmse->expr, 1369 1.1 mrg fold_convert (TREE_TYPE (parmse->expr), 1370 1.1 mrg null_pointer_node)); 1371 1.1 mrg } 1372 1.1 mrg 1373 1.1 mrg 1374 1.1 mrg /* Given a class array declaration and an index, returns the address 1375 1.1 mrg of the referenced element. */ 1376 1.1 mrg 1377 1.1 mrg static tree 1378 1.1 mrg gfc_get_class_array_ref (tree index, tree class_decl, tree data_comp, 1379 1.1 mrg bool unlimited) 1380 1.1 mrg { 1381 1.1 mrg tree data, size, tmp, ctmp, offset, ptr; 1382 1.1 mrg 1383 1.1 mrg data = data_comp != NULL_TREE ? data_comp : 1384 1.1 mrg gfc_class_data_get (class_decl); 1385 1.1 mrg size = gfc_class_vtab_size_get (class_decl); 1386 1.1 mrg 1387 1.1 mrg if (unlimited) 1388 1.1 mrg { 1389 1.1 mrg tmp = fold_convert (gfc_array_index_type, 1390 1.1 mrg gfc_class_len_get (class_decl)); 1391 1.1 mrg ctmp = fold_build2_loc (input_location, MULT_EXPR, 1392 1.1 mrg gfc_array_index_type, size, tmp); 1393 1.1 mrg tmp = fold_build2_loc (input_location, GT_EXPR, 1394 1.1 mrg logical_type_node, tmp, 1395 1.1 mrg build_zero_cst (TREE_TYPE (tmp))); 1396 1.1 mrg size = fold_build3_loc (input_location, COND_EXPR, 1397 1.1 mrg gfc_array_index_type, tmp, ctmp, size); 1398 1.1 mrg } 1399 1.1 mrg 1400 1.1 mrg offset = fold_build2_loc (input_location, MULT_EXPR, 1401 1.1 mrg gfc_array_index_type, 1402 1.1 mrg index, size); 1403 1.1 mrg 1404 1.1 mrg data = gfc_conv_descriptor_data_get (data); 1405 1.1 mrg ptr = fold_convert (pvoid_type_node, data); 1406 1.1 mrg ptr = fold_build_pointer_plus_loc (input_location, ptr, offset); 1407 1.1 mrg return fold_convert (TREE_TYPE (data), ptr); 1408 1.1 mrg } 1409 1.1 mrg 1410 1.1 mrg 1411 1.1 mrg /* Copies one class expression to another, assuming that if either 1412 1.1 mrg 'to' or 'from' are arrays they are packed. Should 'from' be 1413 1.1 mrg NULL_TREE, the initialization expression for 'to' is used, assuming 1414 1.1 mrg that the _vptr is set. */ 1415 1.1 mrg 1416 1.1 mrg tree 1417 1.1 mrg gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited) 1418 1.1 mrg { 1419 1.1 mrg tree fcn; 1420 1.1 mrg tree fcn_type; 1421 1.1 mrg tree from_data; 1422 1.1 mrg tree from_len; 1423 1.1 mrg tree to_data; 1424 1.1 mrg tree to_len; 1425 1.1 mrg tree to_ref; 1426 1.1 mrg tree from_ref; 1427 1.1 mrg vec<tree, va_gc> *args; 1428 1.1 mrg tree tmp; 1429 1.1 mrg tree stdcopy; 1430 1.1 mrg tree extcopy; 1431 1.1 mrg tree index; 1432 1.1 mrg bool is_from_desc = false, is_to_class = false; 1433 1.1 mrg 1434 1.1 mrg args = NULL; 1435 1.1 mrg /* To prevent warnings on uninitialized variables. */ 1436 1.1 mrg from_len = to_len = NULL_TREE; 1437 1.1 mrg 1438 1.1 mrg if (from != NULL_TREE) 1439 1.1 mrg fcn = gfc_class_vtab_copy_get (from); 1440 1.1 mrg else 1441 1.1 mrg fcn = gfc_class_vtab_copy_get (to); 1442 1.1 mrg 1443 1.1 mrg fcn_type = TREE_TYPE (TREE_TYPE (fcn)); 1444 1.1 mrg 1445 1.1 mrg if (from != NULL_TREE) 1446 1.1 mrg { 1447 1.1 mrg is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from)); 1448 1.1 mrg if (is_from_desc) 1449 1.1 mrg { 1450 1.1 mrg from_data = from; 1451 1.1 mrg from = GFC_DECL_SAVED_DESCRIPTOR (from); 1452 1.1 mrg } 1453 1.1 mrg else 1454 1.1 mrg { 1455 1.1 mrg /* Check that from is a class. When the class is part of a coarray, 1456 1.1 mrg then from is a common pointer and is to be used as is. */ 1457 1.1 mrg tmp = POINTER_TYPE_P (TREE_TYPE (from)) 1458 1.1 mrg ? build_fold_indirect_ref (from) : from; 1459 1.1 mrg from_data = 1460 1.1 mrg (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)) 1461 1.1 mrg || (DECL_P (tmp) && GFC_DECL_CLASS (tmp))) 1462 1.1 mrg ? gfc_class_data_get (from) : from; 1463 1.1 mrg is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)); 1464 1.1 mrg } 1465 1.1 mrg } 1466 1.1 mrg else 1467 1.1 mrg from_data = gfc_class_vtab_def_init_get (to); 1468 1.1 mrg 1469 1.1 mrg if (unlimited) 1470 1.1 mrg { 1471 1.1 mrg if (from != NULL_TREE && unlimited) 1472 1.1 mrg from_len = gfc_class_len_or_zero_get (from); 1473 1.1 mrg else 1474 1.1 mrg from_len = build_zero_cst (size_type_node); 1475 1.1 mrg } 1476 1.1 mrg 1477 1.1 mrg if (GFC_CLASS_TYPE_P (TREE_TYPE (to))) 1478 1.1 mrg { 1479 1.1 mrg is_to_class = true; 1480 1.1 mrg to_data = gfc_class_data_get (to); 1481 1.1 mrg if (unlimited) 1482 1.1 mrg to_len = gfc_class_len_get (to); 1483 1.1 mrg } 1484 1.1 mrg else 1485 1.1 mrg /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to. */ 1486 1.1 mrg to_data = to; 1487 1.1 mrg 1488 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data))) 1489 1.1 mrg { 1490 1.1 mrg stmtblock_t loopbody; 1491 1.1 mrg stmtblock_t body; 1492 1.1 mrg stmtblock_t ifbody; 1493 1.1 mrg gfc_loopinfo loop; 1494 1.1 mrg tree orig_nelems = nelems; /* Needed for bounds check. */ 1495 1.1 mrg 1496 1.1 mrg gfc_init_block (&body); 1497 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, 1498 1.1 mrg gfc_array_index_type, nelems, 1499 1.1 mrg gfc_index_one_node); 1500 1.1 mrg nelems = gfc_evaluate_now (tmp, &body); 1501 1.1 mrg index = gfc_create_var (gfc_array_index_type, "S"); 1502 1.1 mrg 1503 1.1 mrg if (is_from_desc) 1504 1.1 mrg { 1505 1.1 mrg from_ref = gfc_get_class_array_ref (index, from, from_data, 1506 1.1 mrg unlimited); 1507 1.1 mrg vec_safe_push (args, from_ref); 1508 1.1 mrg } 1509 1.1 mrg else 1510 1.1 mrg vec_safe_push (args, from_data); 1511 1.1 mrg 1512 1.1 mrg if (is_to_class) 1513 1.1 mrg to_ref = gfc_get_class_array_ref (index, to, to_data, unlimited); 1514 1.1 mrg else 1515 1.1 mrg { 1516 1.1 mrg tmp = gfc_conv_array_data (to); 1517 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp); 1518 1.1 mrg to_ref = gfc_build_addr_expr (NULL_TREE, 1519 1.1 mrg gfc_build_array_ref (tmp, index, to)); 1520 1.1 mrg } 1521 1.1 mrg vec_safe_push (args, to_ref); 1522 1.1 mrg 1523 1.1 mrg /* Add bounds check. */ 1524 1.1 mrg if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc) 1525 1.1 mrg { 1526 1.1 mrg char *msg; 1527 1.1 mrg const char *name = "<<unknown>>"; 1528 1.1 mrg tree from_len; 1529 1.1 mrg 1530 1.1 mrg if (DECL_P (to)) 1531 1.1 mrg name = (const char *)(DECL_NAME (to)->identifier.id.str); 1532 1.1 mrg 1533 1.1 mrg from_len = gfc_conv_descriptor_size (from_data, 1); 1534 1.1 mrg from_len = fold_convert (TREE_TYPE (orig_nelems), from_len); 1535 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, 1536 1.1 mrg logical_type_node, from_len, orig_nelems); 1537 1.1 mrg msg = xasprintf ("Array bound mismatch for dimension %d " 1538 1.1 mrg "of array '%s' (%%ld/%%ld)", 1539 1.1 mrg 1, name); 1540 1.1 mrg 1541 1.1 mrg gfc_trans_runtime_check (true, false, tmp, &body, 1542 1.1 mrg &gfc_current_locus, msg, 1543 1.1 mrg fold_convert (long_integer_type_node, orig_nelems), 1544 1.1 mrg fold_convert (long_integer_type_node, from_len)); 1545 1.1 mrg 1546 1.1 mrg free (msg); 1547 1.1 mrg } 1548 1.1 mrg 1549 1.1 mrg tmp = build_call_vec (fcn_type, fcn, args); 1550 1.1 mrg 1551 1.1 mrg /* Build the body of the loop. */ 1552 1.1 mrg gfc_init_block (&loopbody); 1553 1.1 mrg gfc_add_expr_to_block (&loopbody, tmp); 1554 1.1 mrg 1555 1.1 mrg /* Build the loop and return. */ 1556 1.1 mrg gfc_init_loopinfo (&loop); 1557 1.1 mrg loop.dimen = 1; 1558 1.1 mrg loop.from[0] = gfc_index_zero_node; 1559 1.1 mrg loop.loopvar[0] = index; 1560 1.1 mrg loop.to[0] = nelems; 1561 1.1 mrg gfc_trans_scalarizing_loops (&loop, &loopbody); 1562 1.1 mrg gfc_init_block (&ifbody); 1563 1.1 mrg gfc_add_block_to_block (&ifbody, &loop.pre); 1564 1.1 mrg stdcopy = gfc_finish_block (&ifbody); 1565 1.1 mrg /* In initialization mode from_len is a constant zero. */ 1566 1.1 mrg if (unlimited && !integer_zerop (from_len)) 1567 1.1 mrg { 1568 1.1 mrg vec_safe_push (args, from_len); 1569 1.1 mrg vec_safe_push (args, to_len); 1570 1.1 mrg tmp = build_call_vec (fcn_type, fcn, args); 1571 1.1 mrg /* Build the body of the loop. */ 1572 1.1 mrg gfc_init_block (&loopbody); 1573 1.1 mrg gfc_add_expr_to_block (&loopbody, tmp); 1574 1.1 mrg 1575 1.1 mrg /* Build the loop and return. */ 1576 1.1 mrg gfc_init_loopinfo (&loop); 1577 1.1 mrg loop.dimen = 1; 1578 1.1 mrg loop.from[0] = gfc_index_zero_node; 1579 1.1 mrg loop.loopvar[0] = index; 1580 1.1 mrg loop.to[0] = nelems; 1581 1.1 mrg gfc_trans_scalarizing_loops (&loop, &loopbody); 1582 1.1 mrg gfc_init_block (&ifbody); 1583 1.1 mrg gfc_add_block_to_block (&ifbody, &loop.pre); 1584 1.1 mrg extcopy = gfc_finish_block (&ifbody); 1585 1.1 mrg 1586 1.1 mrg tmp = fold_build2_loc (input_location, GT_EXPR, 1587 1.1 mrg logical_type_node, from_len, 1588 1.1 mrg build_zero_cst (TREE_TYPE (from_len))); 1589 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, 1590 1.1 mrg void_type_node, tmp, extcopy, stdcopy); 1591 1.1 mrg gfc_add_expr_to_block (&body, tmp); 1592 1.1 mrg tmp = gfc_finish_block (&body); 1593 1.1 mrg } 1594 1.1 mrg else 1595 1.1 mrg { 1596 1.1 mrg gfc_add_expr_to_block (&body, stdcopy); 1597 1.1 mrg tmp = gfc_finish_block (&body); 1598 1.1 mrg } 1599 1.1 mrg gfc_cleanup_loop (&loop); 1600 1.1 mrg } 1601 1.1 mrg else 1602 1.1 mrg { 1603 1.1 mrg gcc_assert (!is_from_desc); 1604 1.1 mrg vec_safe_push (args, from_data); 1605 1.1 mrg vec_safe_push (args, to_data); 1606 1.1 mrg stdcopy = build_call_vec (fcn_type, fcn, args); 1607 1.1 mrg 1608 1.1 mrg /* In initialization mode from_len is a constant zero. */ 1609 1.1 mrg if (unlimited && !integer_zerop (from_len)) 1610 1.1 mrg { 1611 1.1 mrg vec_safe_push (args, from_len); 1612 1.1 mrg vec_safe_push (args, to_len); 1613 1.1 mrg extcopy = build_call_vec (fcn_type, unshare_expr (fcn), args); 1614 1.1 mrg tmp = fold_build2_loc (input_location, GT_EXPR, 1615 1.1 mrg logical_type_node, from_len, 1616 1.1 mrg build_zero_cst (TREE_TYPE (from_len))); 1617 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, 1618 1.1 mrg void_type_node, tmp, extcopy, stdcopy); 1619 1.1 mrg } 1620 1.1 mrg else 1621 1.1 mrg tmp = stdcopy; 1622 1.1 mrg } 1623 1.1 mrg 1624 1.1 mrg /* Only copy _def_init to to_data, when it is not a NULL-pointer. */ 1625 1.1 mrg if (from == NULL_TREE) 1626 1.1 mrg { 1627 1.1 mrg tree cond; 1628 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, 1629 1.1 mrg logical_type_node, 1630 1.1 mrg from_data, null_pointer_node); 1631 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, 1632 1.1 mrg void_type_node, cond, 1633 1.1 mrg tmp, build_empty_stmt (input_location)); 1634 1.1 mrg } 1635 1.1 mrg 1636 1.1 mrg return tmp; 1637 1.1 mrg } 1638 1.1 mrg 1639 1.1 mrg 1640 1.1 mrg static tree 1641 1.1 mrg gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj) 1642 1.1 mrg { 1643 1.1 mrg gfc_actual_arglist *actual; 1644 1.1 mrg gfc_expr *ppc; 1645 1.1 mrg gfc_code *ppc_code; 1646 1.1 mrg tree res; 1647 1.1 mrg 1648 1.1 mrg actual = gfc_get_actual_arglist (); 1649 1.1 mrg actual->expr = gfc_copy_expr (rhs); 1650 1.1 mrg actual->next = gfc_get_actual_arglist (); 1651 1.1 mrg actual->next->expr = gfc_copy_expr (lhs); 1652 1.1 mrg ppc = gfc_copy_expr (obj); 1653 1.1 mrg gfc_add_vptr_component (ppc); 1654 1.1 mrg gfc_add_component_ref (ppc, "_copy"); 1655 1.1 mrg ppc_code = gfc_get_code (EXEC_CALL); 1656 1.1 mrg ppc_code->resolved_sym = ppc->symtree->n.sym; 1657 1.1 mrg /* Although '_copy' is set to be elemental in class.cc, it is 1658 1.1 mrg not staying that way. Find out why, sometime.... */ 1659 1.1 mrg ppc_code->resolved_sym->attr.elemental = 1; 1660 1.1 mrg ppc_code->ext.actual = actual; 1661 1.1 mrg ppc_code->expr1 = ppc; 1662 1.1 mrg /* Since '_copy' is elemental, the scalarizer will take care 1663 1.1 mrg of arrays in gfc_trans_call. */ 1664 1.1 mrg res = gfc_trans_call (ppc_code, false, NULL, NULL, false); 1665 1.1 mrg gfc_free_statements (ppc_code); 1666 1.1 mrg 1667 1.1 mrg if (UNLIMITED_POLY(obj)) 1668 1.1 mrg { 1669 1.1 mrg /* Check if rhs is non-NULL. */ 1670 1.1 mrg gfc_se src; 1671 1.1 mrg gfc_init_se (&src, NULL); 1672 1.1 mrg gfc_conv_expr (&src, rhs); 1673 1.1 mrg src.expr = gfc_build_addr_expr (NULL_TREE, src.expr); 1674 1.1 mrg tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 1675 1.1 mrg src.expr, fold_convert (TREE_TYPE (src.expr), 1676 1.1 mrg null_pointer_node)); 1677 1.1 mrg res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res, 1678 1.1 mrg build_empty_stmt (input_location)); 1679 1.1 mrg } 1680 1.1 mrg 1681 1.1 mrg return res; 1682 1.1 mrg } 1683 1.1 mrg 1684 1.1 mrg /* Special case for initializing a polymorphic dummy with INTENT(OUT). 1685 1.1 mrg A MEMCPY is needed to copy the full data from the default initializer 1686 1.1 mrg of the dynamic type. */ 1687 1.1 mrg 1688 1.1 mrg tree 1689 1.1 mrg gfc_trans_class_init_assign (gfc_code *code) 1690 1.1 mrg { 1691 1.1 mrg stmtblock_t block; 1692 1.1 mrg tree tmp; 1693 1.1 mrg gfc_se dst,src,memsz; 1694 1.1 mrg gfc_expr *lhs, *rhs, *sz; 1695 1.1 mrg 1696 1.1 mrg gfc_start_block (&block); 1697 1.1 mrg 1698 1.1 mrg lhs = gfc_copy_expr (code->expr1); 1699 1.1 mrg 1700 1.1 mrg rhs = gfc_copy_expr (code->expr1); 1701 1.1 mrg gfc_add_vptr_component (rhs); 1702 1.1 mrg 1703 1.1 mrg /* Make sure that the component backend_decls have been built, which 1704 1.1 mrg will not have happened if the derived types concerned have not 1705 1.1 mrg been referenced. */ 1706 1.1 mrg gfc_get_derived_type (rhs->ts.u.derived); 1707 1.1 mrg gfc_add_def_init_component (rhs); 1708 1.1 mrg /* The _def_init is always scalar. */ 1709 1.1 mrg rhs->rank = 0; 1710 1.1 mrg 1711 1.1 mrg if (code->expr1->ts.type == BT_CLASS 1712 1.1 mrg && CLASS_DATA (code->expr1)->attr.dimension) 1713 1.1 mrg { 1714 1.1 mrg gfc_array_spec *tmparr = gfc_get_array_spec (); 1715 1.1 mrg *tmparr = *CLASS_DATA (code->expr1)->as; 1716 1.1 mrg /* Adding the array ref to the class expression results in correct 1717 1.1 mrg indexing to the dynamic type. */ 1718 1.1 mrg gfc_add_full_array_ref (lhs, tmparr); 1719 1.1 mrg tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1); 1720 1.1 mrg } 1721 1.1 mrg else 1722 1.1 mrg { 1723 1.1 mrg /* Scalar initialization needs the _data component. */ 1724 1.1 mrg gfc_add_data_component (lhs); 1725 1.1 mrg sz = gfc_copy_expr (code->expr1); 1726 1.1 mrg gfc_add_vptr_component (sz); 1727 1.1 mrg gfc_add_size_component (sz); 1728 1.1 mrg 1729 1.1 mrg gfc_init_se (&dst, NULL); 1730 1.1 mrg gfc_init_se (&src, NULL); 1731 1.1 mrg gfc_init_se (&memsz, NULL); 1732 1.1 mrg gfc_conv_expr (&dst, lhs); 1733 1.1 mrg gfc_conv_expr (&src, rhs); 1734 1.1 mrg gfc_conv_expr (&memsz, sz); 1735 1.1 mrg gfc_add_block_to_block (&block, &src.pre); 1736 1.1 mrg src.expr = gfc_build_addr_expr (NULL_TREE, src.expr); 1737 1.1 mrg 1738 1.1 mrg tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr); 1739 1.1 mrg 1740 1.1 mrg if (UNLIMITED_POLY(code->expr1)) 1741 1.1 mrg { 1742 1.1 mrg /* Check if _def_init is non-NULL. */ 1743 1.1 mrg tree cond = fold_build2_loc (input_location, NE_EXPR, 1744 1.1 mrg logical_type_node, src.expr, 1745 1.1 mrg fold_convert (TREE_TYPE (src.expr), 1746 1.1 mrg null_pointer_node)); 1747 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond, 1748 1.1 mrg tmp, build_empty_stmt (input_location)); 1749 1.1 mrg } 1750 1.1 mrg } 1751 1.1 mrg 1752 1.1 mrg if (code->expr1->symtree->n.sym->attr.dummy 1753 1.1 mrg && (code->expr1->symtree->n.sym->attr.optional 1754 1.1 mrg || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master)) 1755 1.1 mrg { 1756 1.1 mrg tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym); 1757 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), 1758 1.1 mrg present, tmp, 1759 1.1 mrg build_empty_stmt (input_location)); 1760 1.1 mrg } 1761 1.1 mrg 1762 1.1 mrg gfc_add_expr_to_block (&block, tmp); 1763 1.1 mrg 1764 1.1 mrg return gfc_finish_block (&block); 1765 1.1 mrg } 1766 1.1 mrg 1767 1.1 mrg 1768 1.1 mrg /* Class valued elemental function calls or class array elements arriving 1769 1.1 mrg in gfc_trans_scalar_assign come here. Wherever possible the vptr copy 1770 1.1 mrg is used to ensure that the rhs dynamic type is assigned to the lhs. */ 1771 1.1 mrg 1772 1.1 mrg static bool 1773 1.1 mrg trans_scalar_class_assign (stmtblock_t *block, gfc_se *lse, gfc_se *rse) 1774 1.1 mrg { 1775 1.1 mrg tree fcn; 1776 1.1 mrg tree rse_expr; 1777 1.1 mrg tree class_data; 1778 1.1 mrg tree tmp; 1779 1.1 mrg tree zero; 1780 1.1 mrg tree cond; 1781 1.1 mrg tree final_cond; 1782 1.1 mrg stmtblock_t inner_block; 1783 1.1 mrg bool is_descriptor; 1784 1.1 mrg bool not_call_expr = TREE_CODE (rse->expr) != CALL_EXPR; 1785 1.1 mrg bool not_lhs_array_type; 1786 1.1 mrg 1787 1.1 mrg /* Temporaries arising from dependencies in assignment get cast as a 1788 1.1 mrg character type of the dynamic size of the rhs. Use the vptr copy 1789 1.1 mrg for this case. */ 1790 1.1 mrg tmp = TREE_TYPE (lse->expr); 1791 1.1 mrg not_lhs_array_type = !(tmp && TREE_CODE (tmp) == ARRAY_TYPE 1792 1.1 mrg && TYPE_MAX_VALUE (TYPE_DOMAIN (tmp)) != NULL_TREE); 1793 1.1 mrg 1794 1.1 mrg /* Use ordinary assignment if the rhs is not a call expression or 1795 1.1 mrg the lhs is not a class entity or an array(ie. character) type. */ 1796 1.1 mrg if ((not_call_expr && gfc_get_class_from_expr (lse->expr) == NULL_TREE) 1797 1.1 mrg && not_lhs_array_type) 1798 1.1 mrg return false; 1799 1.1 mrg 1800 1.1 mrg /* Ordinary assignment can be used if both sides are class expressions 1801 1.1 mrg since the dynamic type is preserved by copying the vptr. This 1802 1.1 mrg should only occur, where temporaries are involved. */ 1803 1.1 mrg if (GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr)) 1804 1.1 mrg && GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))) 1805 1.1 mrg return false; 1806 1.1 mrg 1807 1.1 mrg /* Fix the class expression and the class data of the rhs. */ 1808 1.1 mrg if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)) 1809 1.1 mrg || not_call_expr) 1810 1.1 mrg { 1811 1.1 mrg tmp = gfc_get_class_from_expr (rse->expr); 1812 1.1 mrg if (tmp == NULL_TREE) 1813 1.1 mrg return false; 1814 1.1 mrg rse_expr = gfc_evaluate_now (tmp, block); 1815 1.1 mrg } 1816 1.1 mrg else 1817 1.1 mrg rse_expr = gfc_evaluate_now (rse->expr, block); 1818 1.1 mrg 1819 1.1 mrg class_data = gfc_class_data_get (rse_expr); 1820 1.1 mrg 1821 1.1 mrg /* Check that the rhs data is not null. */ 1822 1.1 mrg is_descriptor = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (class_data)); 1823 1.1 mrg if (is_descriptor) 1824 1.1 mrg class_data = gfc_conv_descriptor_data_get (class_data); 1825 1.1 mrg class_data = gfc_evaluate_now (class_data, block); 1826 1.1 mrg 1827 1.1 mrg zero = build_int_cst (TREE_TYPE (class_data), 0); 1828 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, 1829 1.1 mrg logical_type_node, 1830 1.1 mrg class_data, zero); 1831 1.1 mrg 1832 1.1 mrg /* Copy the rhs to the lhs. */ 1833 1.1 mrg fcn = gfc_vptr_copy_get (gfc_class_vptr_get (rse_expr)); 1834 1.1 mrg fcn = build_fold_indirect_ref_loc (input_location, fcn); 1835 1.1 mrg tmp = gfc_evaluate_now (gfc_build_addr_expr (NULL, rse->expr), block); 1836 1.1 mrg tmp = is_descriptor ? tmp : class_data; 1837 1.1 mrg tmp = build_call_expr_loc (input_location, fcn, 2, tmp, 1838 1.1 mrg gfc_build_addr_expr (NULL, lse->expr)); 1839 1.1 mrg gfc_add_expr_to_block (block, tmp); 1840 1.1 mrg 1841 1.1 mrg /* Only elemental function results need to be finalised and freed. */ 1842 1.1 mrg if (not_call_expr) 1843 1.1 mrg return true; 1844 1.1 mrg 1845 1.1 mrg /* Finalize the class data if needed. */ 1846 1.1 mrg gfc_init_block (&inner_block); 1847 1.1 mrg fcn = gfc_vptr_final_get (gfc_class_vptr_get (rse_expr)); 1848 1.1 mrg zero = build_int_cst (TREE_TYPE (fcn), 0); 1849 1.1 mrg final_cond = fold_build2_loc (input_location, NE_EXPR, 1850 1.1 mrg logical_type_node, fcn, zero); 1851 1.1 mrg fcn = build_fold_indirect_ref_loc (input_location, fcn); 1852 1.1 mrg tmp = build_call_expr_loc (input_location, fcn, 1, class_data); 1853 1.1 mrg tmp = build3_v (COND_EXPR, final_cond, 1854 1.1 mrg tmp, build_empty_stmt (input_location)); 1855 1.1 mrg gfc_add_expr_to_block (&inner_block, tmp); 1856 1.1 mrg 1857 1.1 mrg /* Free the class data. */ 1858 1.1 mrg tmp = gfc_call_free (class_data); 1859 1.1 mrg tmp = build3_v (COND_EXPR, cond, tmp, 1860 1.1 mrg build_empty_stmt (input_location)); 1861 1.1 mrg gfc_add_expr_to_block (&inner_block, tmp); 1862 1.1 mrg 1863 1.1 mrg /* Finish the inner block and subject it to the condition on the 1864 1.1 mrg class data being non-zero. */ 1865 1.1 mrg tmp = gfc_finish_block (&inner_block); 1866 1.1 mrg tmp = build3_v (COND_EXPR, cond, tmp, 1867 1.1 mrg build_empty_stmt (input_location)); 1868 1.1 mrg gfc_add_expr_to_block (block, tmp); 1869 1.1 mrg 1870 1.1 mrg return true; 1871 1.1 mrg } 1872 1.1 mrg 1873 1.1 mrg /* End of prototype trans-class.c */ 1874 1.1 mrg 1875 1.1 mrg 1876 1.1 mrg static void 1877 1.1 mrg realloc_lhs_warning (bt type, bool array, locus *where) 1878 1.1 mrg { 1879 1.1 mrg if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs) 1880 1.1 mrg gfc_warning (OPT_Wrealloc_lhs, 1881 1.1 mrg "Code for reallocating the allocatable array at %L will " 1882 1.1 mrg "be added", where); 1883 1.1 mrg else if (warn_realloc_lhs_all) 1884 1.1 mrg gfc_warning (OPT_Wrealloc_lhs_all, 1885 1.1 mrg "Code for reallocating the allocatable variable at %L " 1886 1.1 mrg "will be added", where); 1887 1.1 mrg } 1888 1.1 mrg 1889 1.1 mrg 1890 1.1 mrg static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *, 1891 1.1 mrg gfc_expr *); 1892 1.1 mrg 1893 1.1 mrg /* Copy the scalarization loop variables. */ 1894 1.1 mrg 1895 1.1 mrg static void 1896 1.1 mrg gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src) 1897 1.1 mrg { 1898 1.1 mrg dest->ss = src->ss; 1899 1.1 mrg dest->loop = src->loop; 1900 1.1 mrg } 1901 1.1 mrg 1902 1.1 mrg 1903 1.1 mrg /* Initialize a simple expression holder. 1904 1.1 mrg 1905 1.1 mrg Care must be taken when multiple se are created with the same parent. 1906 1.1 mrg The child se must be kept in sync. The easiest way is to delay creation 1907 1.1 mrg of a child se until after the previous se has been translated. */ 1908 1.1 mrg 1909 1.1 mrg void 1910 1.1 mrg gfc_init_se (gfc_se * se, gfc_se * parent) 1911 1.1 mrg { 1912 1.1 mrg memset (se, 0, sizeof (gfc_se)); 1913 1.1 mrg gfc_init_block (&se->pre); 1914 1.1 mrg gfc_init_block (&se->post); 1915 1.1 mrg 1916 1.1 mrg se->parent = parent; 1917 1.1 mrg 1918 1.1 mrg if (parent) 1919 1.1 mrg gfc_copy_se_loopvars (se, parent); 1920 1.1 mrg } 1921 1.1 mrg 1922 1.1 mrg 1923 1.1 mrg /* Advances to the next SS in the chain. Use this rather than setting 1924 1.1 mrg se->ss = se->ss->next because all the parents needs to be kept in sync. 1925 1.1 mrg See gfc_init_se. */ 1926 1.1 mrg 1927 1.1 mrg void 1928 1.1 mrg gfc_advance_se_ss_chain (gfc_se * se) 1929 1.1 mrg { 1930 1.1 mrg gfc_se *p; 1931 1.1 mrg gfc_ss *ss; 1932 1.1 mrg 1933 1.1 mrg gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator); 1934 1.1 mrg 1935 1.1 mrg p = se; 1936 1.1 mrg /* Walk down the parent chain. */ 1937 1.1 mrg while (p != NULL) 1938 1.1 mrg { 1939 1.1 mrg /* Simple consistency check. */ 1940 1.1 mrg gcc_assert (p->parent == NULL || p->parent->ss == p->ss 1941 1.1 mrg || p->parent->ss->nested_ss == p->ss); 1942 1.1 mrg 1943 1.1 mrg /* If we were in a nested loop, the next scalarized expression can be 1944 1.1 mrg on the parent ss' next pointer. Thus we should not take the next 1945 1.1 mrg pointer blindly, but rather go up one nest level as long as next 1946 1.1 mrg is the end of chain. */ 1947 1.1 mrg ss = p->ss; 1948 1.1 mrg while (ss->next == gfc_ss_terminator && ss->parent != NULL) 1949 1.1 mrg ss = ss->parent; 1950 1.1 mrg 1951 1.1 mrg p->ss = ss->next; 1952 1.1 mrg 1953 1.1 mrg p = p->parent; 1954 1.1 mrg } 1955 1.1 mrg } 1956 1.1 mrg 1957 1.1 mrg 1958 1.1 mrg /* Ensures the result of the expression as either a temporary variable 1959 1.1 mrg or a constant so that it can be used repeatedly. */ 1960 1.1 mrg 1961 1.1 mrg void 1962 1.1 mrg gfc_make_safe_expr (gfc_se * se) 1963 1.1 mrg { 1964 1.1 mrg tree var; 1965 1.1 mrg 1966 1.1 mrg if (CONSTANT_CLASS_P (se->expr)) 1967 1.1 mrg return; 1968 1.1 mrg 1969 1.1 mrg /* We need a temporary for this result. */ 1970 1.1 mrg var = gfc_create_var (TREE_TYPE (se->expr), NULL); 1971 1.1 mrg gfc_add_modify (&se->pre, var, se->expr); 1972 1.1 mrg se->expr = var; 1973 1.1 mrg } 1974 1.1 mrg 1975 1.1 mrg 1976 1.1 mrg /* Return an expression which determines if a dummy parameter is present. 1977 1.1 mrg Also used for arguments to procedures with multiple entry points. */ 1978 1.1 mrg 1979 1.1 mrg tree 1980 1.1 mrg gfc_conv_expr_present (gfc_symbol * sym, bool use_saved_desc) 1981 1.1 mrg { 1982 1.1 mrg tree decl, orig_decl, cond; 1983 1.1 mrg 1984 1.1 mrg gcc_assert (sym->attr.dummy); 1985 1.1 mrg orig_decl = decl = gfc_get_symbol_decl (sym); 1986 1.1 mrg 1987 1.1 mrg /* Intrinsic scalars with VALUE attribute which are passed by value 1988 1.1 mrg use a hidden argument to denote the present status. */ 1989 1.1 mrg if (sym->attr.value && sym->ts.type != BT_CHARACTER 1990 1.1 mrg && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED 1991 1.1 mrg && !sym->attr.dimension) 1992 1.1 mrg { 1993 1.1 mrg char name[GFC_MAX_SYMBOL_LEN + 2]; 1994 1.1 mrg tree tree_name; 1995 1.1 mrg 1996 1.1 mrg gcc_assert (TREE_CODE (decl) == PARM_DECL); 1997 1.1 mrg name[0] = '_'; 1998 1.1 mrg strcpy (&name[1], sym->name); 1999 1.1 mrg tree_name = get_identifier (name); 2000 1.1 mrg 2001 1.1 mrg /* Walk function argument list to find hidden arg. */ 2002 1.1 mrg cond = DECL_ARGUMENTS (DECL_CONTEXT (decl)); 2003 1.1 mrg for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond)) 2004 1.1 mrg if (DECL_NAME (cond) == tree_name 2005 1.1 mrg && DECL_ARTIFICIAL (cond)) 2006 1.1 mrg break; 2007 1.1 mrg 2008 1.1 mrg gcc_assert (cond); 2009 1.1 mrg return cond; 2010 1.1 mrg } 2011 1.1 mrg 2012 1.1 mrg /* Assumed-shape arrays use a local variable for the array data; 2013 1.1 mrg the actual PARAM_DECL is in a saved decl. As the local variable 2014 1.1 mrg is NULL, it can be checked instead, unless use_saved_desc is 2015 1.1 mrg requested. */ 2016 1.1 mrg 2017 1.1 mrg if (use_saved_desc && TREE_CODE (decl) != PARM_DECL) 2018 1.1 mrg { 2019 1.1 mrg gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)) 2020 1.1 mrg || GFC_ARRAY_TYPE_P (TREE_TYPE (decl))); 2021 1.1 mrg decl = GFC_DECL_SAVED_DESCRIPTOR (decl); 2022 1.1 mrg } 2023 1.1 mrg 2024 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, decl, 2025 1.1 mrg fold_convert (TREE_TYPE (decl), null_pointer_node)); 2026 1.1 mrg 2027 1.1 mrg /* Fortran 2008 allows to pass null pointers and non-associated pointers 2028 1.1 mrg as actual argument to denote absent dummies. For array descriptors, 2029 1.1 mrg we thus also need to check the array descriptor. For BT_CLASS, it 2030 1.1 mrg can also occur for scalars and F2003 due to type->class wrapping and 2031 1.1 mrg class->class wrapping. Note further that BT_CLASS always uses an 2032 1.1 mrg array descriptor for arrays, also for explicit-shape/assumed-size. 2033 1.1 mrg For assumed-rank arrays, no local variable is generated, hence, 2034 1.1 mrg the following also applies with !use_saved_desc. */ 2035 1.1 mrg 2036 1.1 mrg if ((use_saved_desc || TREE_CODE (orig_decl) == PARM_DECL) 2037 1.1 mrg && !sym->attr.allocatable 2038 1.1 mrg && ((sym->ts.type != BT_CLASS && !sym->attr.pointer) 2039 1.1 mrg || (sym->ts.type == BT_CLASS 2040 1.1 mrg && !CLASS_DATA (sym)->attr.allocatable 2041 1.1 mrg && !CLASS_DATA (sym)->attr.class_pointer)) 2042 1.1 mrg && ((gfc_option.allow_std & GFC_STD_F2008) != 0 2043 1.1 mrg || sym->ts.type == BT_CLASS)) 2044 1.1 mrg { 2045 1.1 mrg tree tmp; 2046 1.1 mrg 2047 1.1 mrg if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE 2048 1.1 mrg || sym->as->type == AS_ASSUMED_RANK 2049 1.1 mrg || sym->attr.codimension)) 2050 1.1 mrg || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as)) 2051 1.1 mrg { 2052 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, decl); 2053 1.1 mrg if (sym->ts.type == BT_CLASS) 2054 1.1 mrg tmp = gfc_class_data_get (tmp); 2055 1.1 mrg tmp = gfc_conv_array_data (tmp); 2056 1.1 mrg } 2057 1.1 mrg else if (sym->ts.type == BT_CLASS) 2058 1.1 mrg tmp = gfc_class_data_get (decl); 2059 1.1 mrg else 2060 1.1 mrg tmp = NULL_TREE; 2061 1.1 mrg 2062 1.1 mrg if (tmp != NULL_TREE) 2063 1.1 mrg { 2064 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp, 2065 1.1 mrg fold_convert (TREE_TYPE (tmp), null_pointer_node)); 2066 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR, 2067 1.1 mrg logical_type_node, cond, tmp); 2068 1.1 mrg } 2069 1.1 mrg } 2070 1.1 mrg 2071 1.1 mrg return cond; 2072 1.1 mrg } 2073 1.1 mrg 2074 1.1 mrg 2075 1.1 mrg /* Converts a missing, dummy argument into a null or zero. */ 2076 1.1 mrg 2077 1.1 mrg void 2078 1.1 mrg gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind) 2079 1.1 mrg { 2080 1.1 mrg tree present; 2081 1.1 mrg tree tmp; 2082 1.1 mrg 2083 1.1 mrg present = gfc_conv_expr_present (arg->symtree->n.sym); 2084 1.1 mrg 2085 1.1 mrg if (kind > 0) 2086 1.1 mrg { 2087 1.1 mrg /* Create a temporary and convert it to the correct type. */ 2088 1.1 mrg tmp = gfc_get_int_type (kind); 2089 1.1 mrg tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location, 2090 1.1 mrg se->expr)); 2091 1.1 mrg 2092 1.1 mrg /* Test for a NULL value. */ 2093 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present, 2094 1.1 mrg tmp, fold_convert (TREE_TYPE (tmp), integer_one_node)); 2095 1.1 mrg tmp = gfc_evaluate_now (tmp, &se->pre); 2096 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, tmp); 2097 1.1 mrg } 2098 1.1 mrg else 2099 1.1 mrg { 2100 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr), 2101 1.1 mrg present, se->expr, 2102 1.1 mrg build_zero_cst (TREE_TYPE (se->expr))); 2103 1.1 mrg tmp = gfc_evaluate_now (tmp, &se->pre); 2104 1.1 mrg se->expr = tmp; 2105 1.1 mrg } 2106 1.1 mrg 2107 1.1 mrg if (ts.type == BT_CHARACTER) 2108 1.1 mrg { 2109 1.1 mrg tmp = build_int_cst (gfc_charlen_type_node, 0); 2110 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node, 2111 1.1 mrg present, se->string_length, tmp); 2112 1.1 mrg tmp = gfc_evaluate_now (tmp, &se->pre); 2113 1.1 mrg se->string_length = tmp; 2114 1.1 mrg } 2115 1.1 mrg return; 2116 1.1 mrg } 2117 1.1 mrg 2118 1.1 mrg 2119 1.1 mrg /* Get the character length of an expression, looking through gfc_refs 2120 1.1 mrg if necessary. */ 2121 1.1 mrg 2122 1.1 mrg tree 2123 1.1 mrg gfc_get_expr_charlen (gfc_expr *e) 2124 1.1 mrg { 2125 1.1 mrg gfc_ref *r; 2126 1.1 mrg tree length; 2127 1.1 mrg gfc_se se; 2128 1.1 mrg 2129 1.1 mrg gcc_assert (e->expr_type == EXPR_VARIABLE 2130 1.1 mrg && e->ts.type == BT_CHARACTER); 2131 1.1 mrg 2132 1.1 mrg length = NULL; /* To silence compiler warning. */ 2133 1.1 mrg 2134 1.1 mrg if (is_subref_array (e) && e->ts.u.cl->length) 2135 1.1 mrg { 2136 1.1 mrg gfc_se tmpse; 2137 1.1 mrg gfc_init_se (&tmpse, NULL); 2138 1.1 mrg gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node); 2139 1.1 mrg e->ts.u.cl->backend_decl = tmpse.expr; 2140 1.1 mrg return tmpse.expr; 2141 1.1 mrg } 2142 1.1 mrg 2143 1.1 mrg /* First candidate: if the variable is of type CHARACTER, the 2144 1.1 mrg expression's length could be the length of the character 2145 1.1 mrg variable. */ 2146 1.1 mrg if (e->symtree->n.sym->ts.type == BT_CHARACTER) 2147 1.1 mrg length = e->symtree->n.sym->ts.u.cl->backend_decl; 2148 1.1 mrg 2149 1.1 mrg /* Look through the reference chain for component references. */ 2150 1.1 mrg for (r = e->ref; r; r = r->next) 2151 1.1 mrg { 2152 1.1 mrg switch (r->type) 2153 1.1 mrg { 2154 1.1 mrg case REF_COMPONENT: 2155 1.1 mrg if (r->u.c.component->ts.type == BT_CHARACTER) 2156 1.1 mrg length = r->u.c.component->ts.u.cl->backend_decl; 2157 1.1 mrg break; 2158 1.1 mrg 2159 1.1 mrg case REF_ARRAY: 2160 1.1 mrg /* Do nothing. */ 2161 1.1 mrg break; 2162 1.1 mrg 2163 1.1 mrg case REF_SUBSTRING: 2164 1.1 mrg gfc_init_se (&se, NULL); 2165 1.1 mrg gfc_conv_expr_type (&se, r->u.ss.start, gfc_charlen_type_node); 2166 1.1 mrg length = se.expr; 2167 1.1 mrg gfc_conv_expr_type (&se, r->u.ss.end, gfc_charlen_type_node); 2168 1.1 mrg length = fold_build2_loc (input_location, MINUS_EXPR, 2169 1.1 mrg gfc_charlen_type_node, 2170 1.1 mrg se.expr, length); 2171 1.1 mrg length = fold_build2_loc (input_location, PLUS_EXPR, 2172 1.1 mrg gfc_charlen_type_node, length, 2173 1.1 mrg gfc_index_one_node); 2174 1.1 mrg break; 2175 1.1 mrg 2176 1.1 mrg default: 2177 1.1 mrg gcc_unreachable (); 2178 1.1 mrg break; 2179 1.1 mrg } 2180 1.1 mrg } 2181 1.1 mrg 2182 1.1 mrg gcc_assert (length != NULL); 2183 1.1 mrg return length; 2184 1.1 mrg } 2185 1.1 mrg 2186 1.1 mrg 2187 1.1 mrg /* Return for an expression the backend decl of the coarray. */ 2188 1.1 mrg 2189 1.1 mrg tree 2190 1.1 mrg gfc_get_tree_for_caf_expr (gfc_expr *expr) 2191 1.1 mrg { 2192 1.1 mrg tree caf_decl; 2193 1.1 mrg bool found = false; 2194 1.1 mrg gfc_ref *ref; 2195 1.1 mrg 2196 1.1 mrg gcc_assert (expr && expr->expr_type == EXPR_VARIABLE); 2197 1.1 mrg 2198 1.1 mrg /* Not-implemented diagnostic. */ 2199 1.1 mrg if (expr->symtree->n.sym->ts.type == BT_CLASS 2200 1.1 mrg && UNLIMITED_POLY (expr->symtree->n.sym) 2201 1.1 mrg && CLASS_DATA (expr->symtree->n.sym)->attr.codimension) 2202 1.1 mrg gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at " 2203 1.1 mrg "%L is not supported", &expr->where); 2204 1.1 mrg 2205 1.1 mrg for (ref = expr->ref; ref; ref = ref->next) 2206 1.1 mrg if (ref->type == REF_COMPONENT) 2207 1.1 mrg { 2208 1.1 mrg if (ref->u.c.component->ts.type == BT_CLASS 2209 1.1 mrg && UNLIMITED_POLY (ref->u.c.component) 2210 1.1 mrg && CLASS_DATA (ref->u.c.component)->attr.codimension) 2211 1.1 mrg gfc_error ("Sorry, coindexed access to an unlimited polymorphic " 2212 1.1 mrg "component at %L is not supported", &expr->where); 2213 1.1 mrg } 2214 1.1 mrg 2215 1.1 mrg /* Make sure the backend_decl is present before accessing it. */ 2216 1.1 mrg caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE 2217 1.1 mrg ? gfc_get_symbol_decl (expr->symtree->n.sym) 2218 1.1 mrg : expr->symtree->n.sym->backend_decl; 2219 1.1 mrg 2220 1.1 mrg if (expr->symtree->n.sym->ts.type == BT_CLASS) 2221 1.1 mrg { 2222 1.1 mrg if (expr->ref && expr->ref->type == REF_ARRAY) 2223 1.1 mrg { 2224 1.1 mrg caf_decl = gfc_class_data_get (caf_decl); 2225 1.1 mrg if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension) 2226 1.1 mrg return caf_decl; 2227 1.1 mrg } 2228 1.1 mrg for (ref = expr->ref; ref; ref = ref->next) 2229 1.1 mrg { 2230 1.1 mrg if (ref->type == REF_COMPONENT 2231 1.1 mrg && strcmp (ref->u.c.component->name, "_data") != 0) 2232 1.1 mrg { 2233 1.1 mrg caf_decl = gfc_class_data_get (caf_decl); 2234 1.1 mrg if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension) 2235 1.1 mrg return caf_decl; 2236 1.1 mrg break; 2237 1.1 mrg } 2238 1.1 mrg else if (ref->type == REF_ARRAY && ref->u.ar.dimen) 2239 1.1 mrg break; 2240 1.1 mrg } 2241 1.1 mrg } 2242 1.1 mrg if (expr->symtree->n.sym->attr.codimension) 2243 1.1 mrg return caf_decl; 2244 1.1 mrg 2245 1.1 mrg /* The following code assumes that the coarray is a component reachable via 2246 1.1 mrg only scalar components/variables; the Fortran standard guarantees this. */ 2247 1.1 mrg 2248 1.1 mrg for (ref = expr->ref; ref; ref = ref->next) 2249 1.1 mrg if (ref->type == REF_COMPONENT) 2250 1.1 mrg { 2251 1.1 mrg gfc_component *comp = ref->u.c.component; 2252 1.1 mrg 2253 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (caf_decl))) 2254 1.1 mrg caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl); 2255 1.1 mrg caf_decl = fold_build3_loc (input_location, COMPONENT_REF, 2256 1.1 mrg TREE_TYPE (comp->backend_decl), caf_decl, 2257 1.1 mrg comp->backend_decl, NULL_TREE); 2258 1.1 mrg if (comp->ts.type == BT_CLASS) 2259 1.1 mrg { 2260 1.1 mrg caf_decl = gfc_class_data_get (caf_decl); 2261 1.1 mrg if (CLASS_DATA (comp)->attr.codimension) 2262 1.1 mrg { 2263 1.1 mrg found = true; 2264 1.1 mrg break; 2265 1.1 mrg } 2266 1.1 mrg } 2267 1.1 mrg if (comp->attr.codimension) 2268 1.1 mrg { 2269 1.1 mrg found = true; 2270 1.1 mrg break; 2271 1.1 mrg } 2272 1.1 mrg } 2273 1.1 mrg gcc_assert (found && caf_decl); 2274 1.1 mrg return caf_decl; 2275 1.1 mrg } 2276 1.1 mrg 2277 1.1 mrg 2278 1.1 mrg /* Obtain the Coarray token - and optionally also the offset. */ 2279 1.1 mrg 2280 1.1 mrg void 2281 1.1 mrg gfc_get_caf_token_offset (gfc_se *se, tree *token, tree *offset, tree caf_decl, 2282 1.1 mrg tree se_expr, gfc_expr *expr) 2283 1.1 mrg { 2284 1.1 mrg tree tmp; 2285 1.1 mrg 2286 1.1 mrg /* Coarray token. */ 2287 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))) 2288 1.1 mrg { 2289 1.1 mrg gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) 2290 1.1 mrg == GFC_ARRAY_ALLOCATABLE 2291 1.1 mrg || expr->symtree->n.sym->attr.select_type_temporary); 2292 1.1 mrg *token = gfc_conv_descriptor_token (caf_decl); 2293 1.1 mrg } 2294 1.1 mrg else if (DECL_LANG_SPECIFIC (caf_decl) 2295 1.1 mrg && GFC_DECL_TOKEN (caf_decl) != NULL_TREE) 2296 1.1 mrg *token = GFC_DECL_TOKEN (caf_decl); 2297 1.1 mrg else 2298 1.1 mrg { 2299 1.1 mrg gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl)) 2300 1.1 mrg && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE); 2301 1.1 mrg *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)); 2302 1.1 mrg } 2303 1.1 mrg 2304 1.1 mrg if (offset == NULL) 2305 1.1 mrg return; 2306 1.1 mrg 2307 1.1 mrg /* Offset between the coarray base address and the address wanted. */ 2308 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)) 2309 1.1 mrg && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE 2310 1.1 mrg || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER)) 2311 1.1 mrg *offset = build_int_cst (gfc_array_index_type, 0); 2312 1.1 mrg else if (DECL_LANG_SPECIFIC (caf_decl) 2313 1.1 mrg && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE) 2314 1.1 mrg *offset = GFC_DECL_CAF_OFFSET (caf_decl); 2315 1.1 mrg else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE) 2316 1.1 mrg *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)); 2317 1.1 mrg else 2318 1.1 mrg *offset = build_int_cst (gfc_array_index_type, 0); 2319 1.1 mrg 2320 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (se_expr)) 2321 1.1 mrg && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr)))) 2322 1.1 mrg { 2323 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, se_expr); 2324 1.1 mrg tmp = gfc_conv_descriptor_data_get (tmp); 2325 1.1 mrg } 2326 1.1 mrg else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr))) 2327 1.1 mrg tmp = gfc_conv_descriptor_data_get (se_expr); 2328 1.1 mrg else 2329 1.1 mrg { 2330 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr))); 2331 1.1 mrg tmp = se_expr; 2332 1.1 mrg } 2333 1.1 mrg 2334 1.1 mrg *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, 2335 1.1 mrg *offset, fold_convert (gfc_array_index_type, tmp)); 2336 1.1 mrg 2337 1.1 mrg if (expr->symtree->n.sym->ts.type == BT_DERIVED 2338 1.1 mrg && expr->symtree->n.sym->attr.codimension 2339 1.1 mrg && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp) 2340 1.1 mrg { 2341 1.1 mrg gfc_expr *base_expr = gfc_copy_expr (expr); 2342 1.1 mrg gfc_ref *ref = base_expr->ref; 2343 1.1 mrg gfc_se base_se; 2344 1.1 mrg 2345 1.1 mrg // Iterate through the refs until the last one. 2346 1.1 mrg while (ref->next) 2347 1.1 mrg ref = ref->next; 2348 1.1 mrg 2349 1.1 mrg if (ref->type == REF_ARRAY 2350 1.1 mrg && ref->u.ar.type != AR_FULL) 2351 1.1 mrg { 2352 1.1 mrg const int ranksum = ref->u.ar.dimen + ref->u.ar.codimen; 2353 1.1 mrg int i; 2354 1.1 mrg for (i = 0; i < ranksum; ++i) 2355 1.1 mrg { 2356 1.1 mrg ref->u.ar.start[i] = NULL; 2357 1.1 mrg ref->u.ar.end[i] = NULL; 2358 1.1 mrg } 2359 1.1 mrg ref->u.ar.type = AR_FULL; 2360 1.1 mrg } 2361 1.1 mrg gfc_init_se (&base_se, NULL); 2362 1.1 mrg if (gfc_caf_attr (base_expr).dimension) 2363 1.1 mrg { 2364 1.1 mrg gfc_conv_expr_descriptor (&base_se, base_expr); 2365 1.1 mrg tmp = gfc_conv_descriptor_data_get (base_se.expr); 2366 1.1 mrg } 2367 1.1 mrg else 2368 1.1 mrg { 2369 1.1 mrg gfc_conv_expr (&base_se, base_expr); 2370 1.1 mrg tmp = base_se.expr; 2371 1.1 mrg } 2372 1.1 mrg 2373 1.1 mrg gfc_free_expr (base_expr); 2374 1.1 mrg gfc_add_block_to_block (&se->pre, &base_se.pre); 2375 1.1 mrg gfc_add_block_to_block (&se->post, &base_se.post); 2376 1.1 mrg } 2377 1.1 mrg else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))) 2378 1.1 mrg tmp = gfc_conv_descriptor_data_get (caf_decl); 2379 1.1 mrg else 2380 1.1 mrg { 2381 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl))); 2382 1.1 mrg tmp = caf_decl; 2383 1.1 mrg } 2384 1.1 mrg 2385 1.1 mrg *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, 2386 1.1 mrg fold_convert (gfc_array_index_type, *offset), 2387 1.1 mrg fold_convert (gfc_array_index_type, tmp)); 2388 1.1 mrg } 2389 1.1 mrg 2390 1.1 mrg 2391 1.1 mrg /* Convert the coindex of a coarray into an image index; the result is 2392 1.1 mrg image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1) 2393 1.1 mrg + (idx(3)-lcobound(3))*extend(1)*extent(2) + ... */ 2394 1.1 mrg 2395 1.1 mrg tree 2396 1.1 mrg gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc) 2397 1.1 mrg { 2398 1.1 mrg gfc_ref *ref; 2399 1.1 mrg tree lbound, ubound, extent, tmp, img_idx; 2400 1.1 mrg gfc_se se; 2401 1.1 mrg int i; 2402 1.1 mrg 2403 1.1 mrg for (ref = e->ref; ref; ref = ref->next) 2404 1.1 mrg if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0) 2405 1.1 mrg break; 2406 1.1 mrg gcc_assert (ref != NULL); 2407 1.1 mrg 2408 1.1 mrg if (ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE) 2409 1.1 mrg { 2410 1.1 mrg return build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1, 2411 1.1 mrg integer_zero_node); 2412 1.1 mrg } 2413 1.1 mrg 2414 1.1 mrg img_idx = build_zero_cst (gfc_array_index_type); 2415 1.1 mrg extent = build_one_cst (gfc_array_index_type); 2416 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))) 2417 1.1 mrg for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++) 2418 1.1 mrg { 2419 1.1 mrg gfc_init_se (&se, NULL); 2420 1.1 mrg gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type); 2421 1.1 mrg gfc_add_block_to_block (block, &se.pre); 2422 1.1 mrg lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]); 2423 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, 2424 1.1 mrg TREE_TYPE (lbound), se.expr, lbound); 2425 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp), 2426 1.1 mrg extent, tmp); 2427 1.1 mrg img_idx = fold_build2_loc (input_location, PLUS_EXPR, 2428 1.1 mrg TREE_TYPE (tmp), img_idx, tmp); 2429 1.1 mrg if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1) 2430 1.1 mrg { 2431 1.1 mrg ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]); 2432 1.1 mrg tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL); 2433 1.1 mrg extent = fold_build2_loc (input_location, MULT_EXPR, 2434 1.1 mrg TREE_TYPE (tmp), extent, tmp); 2435 1.1 mrg } 2436 1.1 mrg } 2437 1.1 mrg else 2438 1.1 mrg for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++) 2439 1.1 mrg { 2440 1.1 mrg gfc_init_se (&se, NULL); 2441 1.1 mrg gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type); 2442 1.1 mrg gfc_add_block_to_block (block, &se.pre); 2443 1.1 mrg lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i); 2444 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, 2445 1.1 mrg TREE_TYPE (lbound), se.expr, lbound); 2446 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp), 2447 1.1 mrg extent, tmp); 2448 1.1 mrg img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp), 2449 1.1 mrg img_idx, tmp); 2450 1.1 mrg if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1) 2451 1.1 mrg { 2452 1.1 mrg ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i); 2453 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, 2454 1.1 mrg TREE_TYPE (ubound), ubound, lbound); 2455 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp), 2456 1.1 mrg tmp, build_one_cst (TREE_TYPE (tmp))); 2457 1.1 mrg extent = fold_build2_loc (input_location, MULT_EXPR, 2458 1.1 mrg TREE_TYPE (tmp), extent, tmp); 2459 1.1 mrg } 2460 1.1 mrg } 2461 1.1 mrg img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (img_idx), 2462 1.1 mrg img_idx, build_one_cst (TREE_TYPE (img_idx))); 2463 1.1 mrg return fold_convert (integer_type_node, img_idx); 2464 1.1 mrg } 2465 1.1 mrg 2466 1.1 mrg 2467 1.1 mrg /* For each character array constructor subexpression without a ts.u.cl->length, 2468 1.1 mrg replace it by its first element (if there aren't any elements, the length 2469 1.1 mrg should already be set to zero). */ 2470 1.1 mrg 2471 1.1 mrg static void 2472 1.1 mrg flatten_array_ctors_without_strlen (gfc_expr* e) 2473 1.1 mrg { 2474 1.1 mrg gfc_actual_arglist* arg; 2475 1.1 mrg gfc_constructor* c; 2476 1.1 mrg 2477 1.1 mrg if (!e) 2478 1.1 mrg return; 2479 1.1 mrg 2480 1.1 mrg switch (e->expr_type) 2481 1.1 mrg { 2482 1.1 mrg 2483 1.1 mrg case EXPR_OP: 2484 1.1 mrg flatten_array_ctors_without_strlen (e->value.op.op1); 2485 1.1 mrg flatten_array_ctors_without_strlen (e->value.op.op2); 2486 1.1 mrg break; 2487 1.1 mrg 2488 1.1 mrg case EXPR_COMPCALL: 2489 1.1 mrg /* TODO: Implement as with EXPR_FUNCTION when needed. */ 2490 1.1 mrg gcc_unreachable (); 2491 1.1 mrg 2492 1.1 mrg case EXPR_FUNCTION: 2493 1.1 mrg for (arg = e->value.function.actual; arg; arg = arg->next) 2494 1.1 mrg flatten_array_ctors_without_strlen (arg->expr); 2495 1.1 mrg break; 2496 1.1 mrg 2497 1.1 mrg case EXPR_ARRAY: 2498 1.1 mrg 2499 1.1 mrg /* We've found what we're looking for. */ 2500 1.1 mrg if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length) 2501 1.1 mrg { 2502 1.1 mrg gfc_constructor *c; 2503 1.1 mrg gfc_expr* new_expr; 2504 1.1 mrg 2505 1.1 mrg gcc_assert (e->value.constructor); 2506 1.1 mrg 2507 1.1 mrg c = gfc_constructor_first (e->value.constructor); 2508 1.1 mrg new_expr = c->expr; 2509 1.1 mrg c->expr = NULL; 2510 1.1 mrg 2511 1.1 mrg flatten_array_ctors_without_strlen (new_expr); 2512 1.1 mrg gfc_replace_expr (e, new_expr); 2513 1.1 mrg break; 2514 1.1 mrg } 2515 1.1 mrg 2516 1.1 mrg /* Otherwise, fall through to handle constructor elements. */ 2517 1.1 mrg gcc_fallthrough (); 2518 1.1 mrg case EXPR_STRUCTURE: 2519 1.1 mrg for (c = gfc_constructor_first (e->value.constructor); 2520 1.1 mrg c; c = gfc_constructor_next (c)) 2521 1.1 mrg flatten_array_ctors_without_strlen (c->expr); 2522 1.1 mrg break; 2523 1.1 mrg 2524 1.1 mrg default: 2525 1.1 mrg break; 2526 1.1 mrg 2527 1.1 mrg } 2528 1.1 mrg } 2529 1.1 mrg 2530 1.1 mrg 2531 1.1 mrg /* Generate code to initialize a string length variable. Returns the 2532 1.1 mrg value. For array constructors, cl->length might be NULL and in this case, 2533 1.1 mrg the first element of the constructor is needed. expr is the original 2534 1.1 mrg expression so we can access it but can be NULL if this is not needed. */ 2535 1.1 mrg 2536 1.1 mrg void 2537 1.1 mrg gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock) 2538 1.1 mrg { 2539 1.1 mrg gfc_se se; 2540 1.1 mrg 2541 1.1 mrg gfc_init_se (&se, NULL); 2542 1.1 mrg 2543 1.1 mrg if (!cl->length && cl->backend_decl && VAR_P (cl->backend_decl)) 2544 1.1 mrg return; 2545 1.1 mrg 2546 1.1 mrg /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but 2547 1.1 mrg "flatten" array constructors by taking their first element; all elements 2548 1.1 mrg should be the same length or a cl->length should be present. */ 2549 1.1 mrg if (!cl->length) 2550 1.1 mrg { 2551 1.1 mrg gfc_expr* expr_flat; 2552 1.1 mrg if (!expr) 2553 1.1 mrg return; 2554 1.1 mrg expr_flat = gfc_copy_expr (expr); 2555 1.1 mrg flatten_array_ctors_without_strlen (expr_flat); 2556 1.1 mrg gfc_resolve_expr (expr_flat); 2557 1.1 mrg 2558 1.1 mrg gfc_conv_expr (&se, expr_flat); 2559 1.1 mrg gfc_add_block_to_block (pblock, &se.pre); 2560 1.1 mrg cl->backend_decl = convert (gfc_charlen_type_node, se.string_length); 2561 1.1 mrg 2562 1.1 mrg gfc_free_expr (expr_flat); 2563 1.1 mrg return; 2564 1.1 mrg } 2565 1.1 mrg 2566 1.1 mrg /* Convert cl->length. */ 2567 1.1 mrg 2568 1.1 mrg gcc_assert (cl->length); 2569 1.1 mrg 2570 1.1 mrg gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node); 2571 1.1 mrg se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node, 2572 1.1 mrg se.expr, build_zero_cst (TREE_TYPE (se.expr))); 2573 1.1 mrg gfc_add_block_to_block (pblock, &se.pre); 2574 1.1 mrg 2575 1.1 mrg if (cl->backend_decl && VAR_P (cl->backend_decl)) 2576 1.1 mrg gfc_add_modify (pblock, cl->backend_decl, se.expr); 2577 1.1 mrg else 2578 1.1 mrg cl->backend_decl = gfc_evaluate_now (se.expr, pblock); 2579 1.1 mrg } 2580 1.1 mrg 2581 1.1 mrg 2582 1.1 mrg static void 2583 1.1 mrg gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind, 2584 1.1 mrg const char *name, locus *where) 2585 1.1 mrg { 2586 1.1 mrg tree tmp; 2587 1.1 mrg tree type; 2588 1.1 mrg tree fault; 2589 1.1 mrg gfc_se start; 2590 1.1 mrg gfc_se end; 2591 1.1 mrg char *msg; 2592 1.1 mrg mpz_t length; 2593 1.1 mrg 2594 1.1 mrg type = gfc_get_character_type (kind, ref->u.ss.length); 2595 1.1 mrg type = build_pointer_type (type); 2596 1.1 mrg 2597 1.1 mrg gfc_init_se (&start, se); 2598 1.1 mrg gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node); 2599 1.1 mrg gfc_add_block_to_block (&se->pre, &start.pre); 2600 1.1 mrg 2601 1.1 mrg if (integer_onep (start.expr)) 2602 1.1 mrg gfc_conv_string_parameter (se); 2603 1.1 mrg else 2604 1.1 mrg { 2605 1.1 mrg tmp = start.expr; 2606 1.1 mrg STRIP_NOPS (tmp); 2607 1.1 mrg /* Avoid multiple evaluation of substring start. */ 2608 1.1 mrg if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp)) 2609 1.1 mrg start.expr = gfc_evaluate_now (start.expr, &se->pre); 2610 1.1 mrg 2611 1.1 mrg /* Change the start of the string. */ 2612 1.1 mrg if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE 2613 1.1 mrg || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE) 2614 1.1 mrg && TYPE_STRING_FLAG (TREE_TYPE (se->expr))) 2615 1.1 mrg tmp = se->expr; 2616 1.1 mrg else 2617 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, 2618 1.1 mrg se->expr); 2619 1.1 mrg /* For BIND(C), a BT_CHARACTER is not an ARRAY_TYPE. */ 2620 1.1 mrg if (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE) 2621 1.1 mrg { 2622 1.1 mrg tmp = gfc_build_array_ref (tmp, start.expr, NULL_TREE, true); 2623 1.1 mrg se->expr = gfc_build_addr_expr (type, tmp); 2624 1.1 mrg } 2625 1.1 mrg } 2626 1.1 mrg 2627 1.1 mrg /* Length = end + 1 - start. */ 2628 1.1 mrg gfc_init_se (&end, se); 2629 1.1 mrg if (ref->u.ss.end == NULL) 2630 1.1 mrg end.expr = se->string_length; 2631 1.1 mrg else 2632 1.1 mrg { 2633 1.1 mrg gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node); 2634 1.1 mrg gfc_add_block_to_block (&se->pre, &end.pre); 2635 1.1 mrg } 2636 1.1 mrg tmp = end.expr; 2637 1.1 mrg STRIP_NOPS (tmp); 2638 1.1 mrg if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp)) 2639 1.1 mrg end.expr = gfc_evaluate_now (end.expr, &se->pre); 2640 1.1 mrg 2641 1.1 mrg if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) 2642 1.1 mrg && (ref->u.ss.start->symtree 2643 1.1 mrg && !ref->u.ss.start->symtree->n.sym->attr.implied_index)) 2644 1.1 mrg { 2645 1.1 mrg tree nonempty = fold_build2_loc (input_location, LE_EXPR, 2646 1.1 mrg logical_type_node, start.expr, 2647 1.1 mrg end.expr); 2648 1.1 mrg 2649 1.1 mrg /* Check lower bound. */ 2650 1.1 mrg fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node, 2651 1.1 mrg start.expr, 2652 1.1 mrg build_one_cst (TREE_TYPE (start.expr))); 2653 1.1 mrg fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR, 2654 1.1 mrg logical_type_node, nonempty, fault); 2655 1.1 mrg if (name) 2656 1.1 mrg msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' " 2657 1.1 mrg "is less than one", name); 2658 1.1 mrg else 2659 1.1 mrg msg = xasprintf ("Substring out of bounds: lower bound (%%ld) " 2660 1.1 mrg "is less than one"); 2661 1.1 mrg gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg, 2662 1.1 mrg fold_convert (long_integer_type_node, 2663 1.1 mrg start.expr)); 2664 1.1 mrg free (msg); 2665 1.1 mrg 2666 1.1 mrg /* Check upper bound. */ 2667 1.1 mrg fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node, 2668 1.1 mrg end.expr, se->string_length); 2669 1.1 mrg fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR, 2670 1.1 mrg logical_type_node, nonempty, fault); 2671 1.1 mrg if (name) 2672 1.1 mrg msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' " 2673 1.1 mrg "exceeds string length (%%ld)", name); 2674 1.1 mrg else 2675 1.1 mrg msg = xasprintf ("Substring out of bounds: upper bound (%%ld) " 2676 1.1 mrg "exceeds string length (%%ld)"); 2677 1.1 mrg gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg, 2678 1.1 mrg fold_convert (long_integer_type_node, end.expr), 2679 1.1 mrg fold_convert (long_integer_type_node, 2680 1.1 mrg se->string_length)); 2681 1.1 mrg free (msg); 2682 1.1 mrg } 2683 1.1 mrg 2684 1.1 mrg /* Try to calculate the length from the start and end expressions. */ 2685 1.1 mrg if (ref->u.ss.end 2686 1.1 mrg && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length)) 2687 1.1 mrg { 2688 1.1 mrg HOST_WIDE_INT i_len; 2689 1.1 mrg 2690 1.1 mrg i_len = gfc_mpz_get_hwi (length) + 1; 2691 1.1 mrg if (i_len < 0) 2692 1.1 mrg i_len = 0; 2693 1.1 mrg 2694 1.1 mrg tmp = build_int_cst (gfc_charlen_type_node, i_len); 2695 1.1 mrg mpz_clear (length); /* Was initialized by gfc_dep_difference. */ 2696 1.1 mrg } 2697 1.1 mrg else 2698 1.1 mrg { 2699 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node, 2700 1.1 mrg fold_convert (gfc_charlen_type_node, end.expr), 2701 1.1 mrg fold_convert (gfc_charlen_type_node, start.expr)); 2702 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node, 2703 1.1 mrg build_int_cst (gfc_charlen_type_node, 1), tmp); 2704 1.1 mrg tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node, 2705 1.1 mrg tmp, build_int_cst (gfc_charlen_type_node, 0)); 2706 1.1 mrg } 2707 1.1 mrg 2708 1.1 mrg se->string_length = tmp; 2709 1.1 mrg } 2710 1.1 mrg 2711 1.1 mrg 2712 1.1 mrg /* Convert a derived type component reference. */ 2713 1.1 mrg 2714 1.1 mrg void 2715 1.1 mrg gfc_conv_component_ref (gfc_se * se, gfc_ref * ref) 2716 1.1 mrg { 2717 1.1 mrg gfc_component *c; 2718 1.1 mrg tree tmp; 2719 1.1 mrg tree decl; 2720 1.1 mrg tree field; 2721 1.1 mrg tree context; 2722 1.1 mrg 2723 1.1 mrg c = ref->u.c.component; 2724 1.1 mrg 2725 1.1 mrg if (c->backend_decl == NULL_TREE 2726 1.1 mrg && ref->u.c.sym != NULL) 2727 1.1 mrg gfc_get_derived_type (ref->u.c.sym); 2728 1.1 mrg 2729 1.1 mrg field = c->backend_decl; 2730 1.1 mrg gcc_assert (field && TREE_CODE (field) == FIELD_DECL); 2731 1.1 mrg decl = se->expr; 2732 1.1 mrg context = DECL_FIELD_CONTEXT (field); 2733 1.1 mrg 2734 1.1 mrg /* Components can correspond to fields of different containing 2735 1.1 mrg types, as components are created without context, whereas 2736 1.1 mrg a concrete use of a component has the type of decl as context. 2737 1.1 mrg So, if the type doesn't match, we search the corresponding 2738 1.1 mrg FIELD_DECL in the parent type. To not waste too much time 2739 1.1 mrg we cache this result in norestrict_decl. 2740 1.1 mrg On the other hand, if the context is a UNION or a MAP (a 2741 1.1 mrg RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL. */ 2742 1.1 mrg 2743 1.1 mrg if (context != TREE_TYPE (decl) 2744 1.1 mrg && !( TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */ 2745 1.1 mrg || TREE_CODE (context) == UNION_TYPE)) /* Field is map */ 2746 1.1 mrg { 2747 1.1 mrg tree f2 = c->norestrict_decl; 2748 1.1 mrg if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl)) 2749 1.1 mrg for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2)) 2750 1.1 mrg if (TREE_CODE (f2) == FIELD_DECL 2751 1.1 mrg && DECL_NAME (f2) == DECL_NAME (field)) 2752 1.1 mrg break; 2753 1.1 mrg gcc_assert (f2); 2754 1.1 mrg c->norestrict_decl = f2; 2755 1.1 mrg field = f2; 2756 1.1 mrg } 2757 1.1 mrg 2758 1.1 mrg if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS 2759 1.1 mrg && strcmp ("_data", c->name) == 0) 2760 1.1 mrg { 2761 1.1 mrg /* Found a ref to the _data component. Store the associated ref to 2762 1.1 mrg the vptr in se->class_vptr. */ 2763 1.1 mrg se->class_vptr = gfc_class_vptr_get (decl); 2764 1.1 mrg } 2765 1.1 mrg else 2766 1.1 mrg se->class_vptr = NULL_TREE; 2767 1.1 mrg 2768 1.1 mrg tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), 2769 1.1 mrg decl, field, NULL_TREE); 2770 1.1 mrg 2771 1.1 mrg se->expr = tmp; 2772 1.1 mrg 2773 1.1 mrg /* Allocatable deferred char arrays are to be handled by the gfc_deferred_ 2774 1.1 mrg strlen () conditional below. */ 2775 1.1 mrg if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer 2776 1.1 mrg && !c->ts.deferred 2777 1.1 mrg && !c->attr.pdt_string) 2778 1.1 mrg { 2779 1.1 mrg tmp = c->ts.u.cl->backend_decl; 2780 1.1 mrg /* Components must always be constant length. */ 2781 1.1 mrg gcc_assert (tmp && INTEGER_CST_P (tmp)); 2782 1.1 mrg se->string_length = tmp; 2783 1.1 mrg } 2784 1.1 mrg 2785 1.1 mrg if (gfc_deferred_strlen (c, &field)) 2786 1.1 mrg { 2787 1.1 mrg tmp = fold_build3_loc (input_location, COMPONENT_REF, 2788 1.1 mrg TREE_TYPE (field), 2789 1.1 mrg decl, field, NULL_TREE); 2790 1.1 mrg se->string_length = tmp; 2791 1.1 mrg } 2792 1.1 mrg 2793 1.1 mrg if (((c->attr.pointer || c->attr.allocatable) 2794 1.1 mrg && (!c->attr.dimension && !c->attr.codimension) 2795 1.1 mrg && c->ts.type != BT_CHARACTER) 2796 1.1 mrg || c->attr.proc_pointer) 2797 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, 2798 1.1 mrg se->expr); 2799 1.1 mrg } 2800 1.1 mrg 2801 1.1 mrg 2802 1.1 mrg /* This function deals with component references to components of the 2803 1.1 mrg parent type for derived type extensions. */ 2804 1.1 mrg void 2805 1.1 mrg conv_parent_component_references (gfc_se * se, gfc_ref * ref) 2806 1.1 mrg { 2807 1.1 mrg gfc_component *c; 2808 1.1 mrg gfc_component *cmp; 2809 1.1 mrg gfc_symbol *dt; 2810 1.1 mrg gfc_ref parent; 2811 1.1 mrg 2812 1.1 mrg dt = ref->u.c.sym; 2813 1.1 mrg c = ref->u.c.component; 2814 1.1 mrg 2815 1.1 mrg /* Return if the component is in this type, i.e. not in the parent type. */ 2816 1.1 mrg for (cmp = dt->components; cmp; cmp = cmp->next) 2817 1.1 mrg if (c == cmp) 2818 1.1 mrg return; 2819 1.1 mrg 2820 1.1 mrg /* Build a gfc_ref to recursively call gfc_conv_component_ref. */ 2821 1.1 mrg parent.type = REF_COMPONENT; 2822 1.1 mrg parent.next = NULL; 2823 1.1 mrg parent.u.c.sym = dt; 2824 1.1 mrg parent.u.c.component = dt->components; 2825 1.1 mrg 2826 1.1 mrg if (dt->backend_decl == NULL) 2827 1.1 mrg gfc_get_derived_type (dt); 2828 1.1 mrg 2829 1.1 mrg /* Build the reference and call self. */ 2830 1.1 mrg gfc_conv_component_ref (se, &parent); 2831 1.1 mrg parent.u.c.sym = dt->components->ts.u.derived; 2832 1.1 mrg parent.u.c.component = c; 2833 1.1 mrg conv_parent_component_references (se, &parent); 2834 1.1 mrg } 2835 1.1 mrg 2836 1.1 mrg 2837 1.1 mrg static void 2838 1.1 mrg conv_inquiry (gfc_se * se, gfc_ref * ref, gfc_expr *expr, gfc_typespec *ts) 2839 1.1 mrg { 2840 1.1 mrg tree res = se->expr; 2841 1.1 mrg 2842 1.1 mrg switch (ref->u.i) 2843 1.1 mrg { 2844 1.1 mrg case INQUIRY_RE: 2845 1.1 mrg res = fold_build1_loc (input_location, REALPART_EXPR, 2846 1.1 mrg TREE_TYPE (TREE_TYPE (res)), res); 2847 1.1 mrg break; 2848 1.1 mrg 2849 1.1 mrg case INQUIRY_IM: 2850 1.1 mrg res = fold_build1_loc (input_location, IMAGPART_EXPR, 2851 1.1 mrg TREE_TYPE (TREE_TYPE (res)), res); 2852 1.1 mrg break; 2853 1.1 mrg 2854 1.1 mrg case INQUIRY_KIND: 2855 1.1 mrg res = build_int_cst (gfc_typenode_for_spec (&expr->ts), 2856 1.1 mrg ts->kind); 2857 1.1 mrg se->string_length = NULL_TREE; 2858 1.1 mrg break; 2859 1.1 mrg 2860 1.1 mrg case INQUIRY_LEN: 2861 1.1 mrg res = fold_convert (gfc_typenode_for_spec (&expr->ts), 2862 1.1 mrg se->string_length); 2863 1.1 mrg se->string_length = NULL_TREE; 2864 1.1 mrg break; 2865 1.1 mrg 2866 1.1 mrg default: 2867 1.1 mrg gcc_unreachable (); 2868 1.1 mrg } 2869 1.1 mrg se->expr = res; 2870 1.1 mrg } 2871 1.1 mrg 2872 1.1 mrg /* Dereference VAR where needed if it is a pointer, reference, etc. 2873 1.1 mrg according to Fortran semantics. */ 2874 1.1 mrg 2875 1.1 mrg tree 2876 1.1 mrg gfc_maybe_dereference_var (gfc_symbol *sym, tree var, bool descriptor_only_p, 2877 1.1 mrg bool is_classarray) 2878 1.1 mrg { 2879 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (var))) 2880 1.1 mrg return var; 2881 1.1 mrg if (is_CFI_desc (sym, NULL)) 2882 1.1 mrg return build_fold_indirect_ref_loc (input_location, var); 2883 1.1 mrg 2884 1.1 mrg /* Characters are entirely different from other types, they are treated 2885 1.1 mrg separately. */ 2886 1.1 mrg if (sym->ts.type == BT_CHARACTER) 2887 1.1 mrg { 2888 1.1 mrg /* Dereference character pointer dummy arguments 2889 1.1 mrg or results. */ 2890 1.1 mrg if ((sym->attr.pointer || sym->attr.allocatable 2891 1.1 mrg || (sym->as && sym->as->type == AS_ASSUMED_RANK)) 2892 1.1 mrg && (sym->attr.dummy 2893 1.1 mrg || sym->attr.function 2894 1.1 mrg || sym->attr.result)) 2895 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var); 2896 1.1 mrg } 2897 1.1 mrg else if (!sym->attr.value) 2898 1.1 mrg { 2899 1.1 mrg /* Dereference temporaries for class array dummy arguments. */ 2900 1.1 mrg if (sym->attr.dummy && is_classarray 2901 1.1 mrg && GFC_ARRAY_TYPE_P (TREE_TYPE (var))) 2902 1.1 mrg { 2903 1.1 mrg if (!descriptor_only_p) 2904 1.1 mrg var = GFC_DECL_SAVED_DESCRIPTOR (var); 2905 1.1 mrg 2906 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var); 2907 1.1 mrg } 2908 1.1 mrg 2909 1.1 mrg /* Dereference non-character scalar dummy arguments. */ 2910 1.1 mrg if (sym->attr.dummy && !sym->attr.dimension 2911 1.1 mrg && !(sym->attr.codimension && sym->attr.allocatable) 2912 1.1 mrg && (sym->ts.type != BT_CLASS 2913 1.1 mrg || (!CLASS_DATA (sym)->attr.dimension 2914 1.1 mrg && !(CLASS_DATA (sym)->attr.codimension 2915 1.1 mrg && CLASS_DATA (sym)->attr.allocatable)))) 2916 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var); 2917 1.1 mrg 2918 1.1 mrg /* Dereference scalar hidden result. */ 2919 1.1 mrg if (flag_f2c && sym->ts.type == BT_COMPLEX 2920 1.1 mrg && (sym->attr.function || sym->attr.result) 2921 1.1 mrg && !sym->attr.dimension && !sym->attr.pointer 2922 1.1 mrg && !sym->attr.always_explicit) 2923 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var); 2924 1.1 mrg 2925 1.1 mrg /* Dereference non-character, non-class pointer variables. 2926 1.1 mrg These must be dummies, results, or scalars. */ 2927 1.1 mrg if (!is_classarray 2928 1.1 mrg && (sym->attr.pointer || sym->attr.allocatable 2929 1.1 mrg || gfc_is_associate_pointer (sym) 2930 1.1 mrg || (sym->as && sym->as->type == AS_ASSUMED_RANK)) 2931 1.1 mrg && (sym->attr.dummy 2932 1.1 mrg || sym->attr.function 2933 1.1 mrg || sym->attr.result 2934 1.1 mrg || (!sym->attr.dimension 2935 1.1 mrg && (!sym->attr.codimension || !sym->attr.allocatable)))) 2936 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var); 2937 1.1 mrg /* Now treat the class array pointer variables accordingly. */ 2938 1.1 mrg else if (sym->ts.type == BT_CLASS 2939 1.1 mrg && sym->attr.dummy 2940 1.1 mrg && (CLASS_DATA (sym)->attr.dimension 2941 1.1 mrg || CLASS_DATA (sym)->attr.codimension) 2942 1.1 mrg && ((CLASS_DATA (sym)->as 2943 1.1 mrg && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK) 2944 1.1 mrg || CLASS_DATA (sym)->attr.allocatable 2945 1.1 mrg || CLASS_DATA (sym)->attr.class_pointer)) 2946 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var); 2947 1.1 mrg /* And the case where a non-dummy, non-result, non-function, 2948 1.1 mrg non-allocable and non-pointer classarray is present. This case was 2949 1.1 mrg previously covered by the first if, but with introducing the 2950 1.1 mrg condition !is_classarray there, that case has to be covered 2951 1.1 mrg explicitly. */ 2952 1.1 mrg else if (sym->ts.type == BT_CLASS 2953 1.1 mrg && !sym->attr.dummy 2954 1.1 mrg && !sym->attr.function 2955 1.1 mrg && !sym->attr.result 2956 1.1 mrg && (CLASS_DATA (sym)->attr.dimension 2957 1.1 mrg || CLASS_DATA (sym)->attr.codimension) 2958 1.1 mrg && (sym->assoc 2959 1.1 mrg || !CLASS_DATA (sym)->attr.allocatable) 2960 1.1 mrg && !CLASS_DATA (sym)->attr.class_pointer) 2961 1.1 mrg var = build_fold_indirect_ref_loc (input_location, var); 2962 1.1 mrg } 2963 1.1 mrg 2964 1.1 mrg return var; 2965 1.1 mrg } 2966 1.1 mrg 2967 1.1 mrg /* Return the contents of a variable. Also handles reference/pointer 2968 1.1 mrg variables (all Fortran pointer references are implicit). */ 2969 1.1 mrg 2970 1.1 mrg static void 2971 1.1 mrg gfc_conv_variable (gfc_se * se, gfc_expr * expr) 2972 1.1 mrg { 2973 1.1 mrg gfc_ss *ss; 2974 1.1 mrg gfc_ref *ref; 2975 1.1 mrg gfc_symbol *sym; 2976 1.1 mrg tree parent_decl = NULL_TREE; 2977 1.1 mrg int parent_flag; 2978 1.1 mrg bool return_value; 2979 1.1 mrg bool alternate_entry; 2980 1.1 mrg bool entry_master; 2981 1.1 mrg bool is_classarray; 2982 1.1 mrg bool first_time = true; 2983 1.1 mrg 2984 1.1 mrg sym = expr->symtree->n.sym; 2985 1.1 mrg is_classarray = IS_CLASS_ARRAY (sym); 2986 1.1 mrg ss = se->ss; 2987 1.1 mrg if (ss != NULL) 2988 1.1 mrg { 2989 1.1 mrg gfc_ss_info *ss_info = ss->info; 2990 1.1 mrg 2991 1.1 mrg /* Check that something hasn't gone horribly wrong. */ 2992 1.1 mrg gcc_assert (ss != gfc_ss_terminator); 2993 1.1 mrg gcc_assert (ss_info->expr == expr); 2994 1.1 mrg 2995 1.1 mrg /* A scalarized term. We already know the descriptor. */ 2996 1.1 mrg se->expr = ss_info->data.array.descriptor; 2997 1.1 mrg se->string_length = ss_info->string_length; 2998 1.1 mrg ref = ss_info->data.array.ref; 2999 1.1 mrg if (ref) 3000 1.1 mrg gcc_assert (ref->type == REF_ARRAY 3001 1.1 mrg && ref->u.ar.type != AR_ELEMENT); 3002 1.1 mrg else 3003 1.1 mrg gfc_conv_tmp_array_ref (se); 3004 1.1 mrg } 3005 1.1 mrg else 3006 1.1 mrg { 3007 1.1 mrg tree se_expr = NULL_TREE; 3008 1.1 mrg 3009 1.1 mrg se->expr = gfc_get_symbol_decl (sym); 3010 1.1 mrg 3011 1.1 mrg /* Deal with references to a parent results or entries by storing 3012 1.1 mrg the current_function_decl and moving to the parent_decl. */ 3013 1.1 mrg return_value = sym->attr.function && sym->result == sym; 3014 1.1 mrg alternate_entry = sym->attr.function && sym->attr.entry 3015 1.1 mrg && sym->result == sym; 3016 1.1 mrg entry_master = sym->attr.result 3017 1.1 mrg && sym->ns->proc_name->attr.entry_master 3018 1.1 mrg && !gfc_return_by_reference (sym->ns->proc_name); 3019 1.1 mrg if (current_function_decl) 3020 1.1 mrg parent_decl = DECL_CONTEXT (current_function_decl); 3021 1.1 mrg 3022 1.1 mrg if ((se->expr == parent_decl && return_value) 3023 1.1 mrg || (sym->ns && sym->ns->proc_name 3024 1.1 mrg && parent_decl 3025 1.1 mrg && sym->ns->proc_name->backend_decl == parent_decl 3026 1.1 mrg && (alternate_entry || entry_master))) 3027 1.1 mrg parent_flag = 1; 3028 1.1 mrg else 3029 1.1 mrg parent_flag = 0; 3030 1.1 mrg 3031 1.1 mrg /* Special case for assigning the return value of a function. 3032 1.1 mrg Self recursive functions must have an explicit return value. */ 3033 1.1 mrg if (return_value && (se->expr == current_function_decl || parent_flag)) 3034 1.1 mrg se_expr = gfc_get_fake_result_decl (sym, parent_flag); 3035 1.1 mrg 3036 1.1 mrg /* Similarly for alternate entry points. */ 3037 1.1 mrg else if (alternate_entry 3038 1.1 mrg && (sym->ns->proc_name->backend_decl == current_function_decl 3039 1.1 mrg || parent_flag)) 3040 1.1 mrg { 3041 1.1 mrg gfc_entry_list *el = NULL; 3042 1.1 mrg 3043 1.1 mrg for (el = sym->ns->entries; el; el = el->next) 3044 1.1 mrg if (sym == el->sym) 3045 1.1 mrg { 3046 1.1 mrg se_expr = gfc_get_fake_result_decl (sym, parent_flag); 3047 1.1 mrg break; 3048 1.1 mrg } 3049 1.1 mrg } 3050 1.1 mrg 3051 1.1 mrg else if (entry_master 3052 1.1 mrg && (sym->ns->proc_name->backend_decl == current_function_decl 3053 1.1 mrg || parent_flag)) 3054 1.1 mrg se_expr = gfc_get_fake_result_decl (sym, parent_flag); 3055 1.1 mrg 3056 1.1 mrg if (se_expr) 3057 1.1 mrg se->expr = se_expr; 3058 1.1 mrg 3059 1.1 mrg /* Procedure actual arguments. Look out for temporary variables 3060 1.1 mrg with the same attributes as function values. */ 3061 1.1 mrg else if (!sym->attr.temporary 3062 1.1 mrg && sym->attr.flavor == FL_PROCEDURE 3063 1.1 mrg && se->expr != current_function_decl) 3064 1.1 mrg { 3065 1.1 mrg if (!sym->attr.dummy && !sym->attr.proc_pointer) 3066 1.1 mrg { 3067 1.1 mrg gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL); 3068 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, se->expr); 3069 1.1 mrg } 3070 1.1 mrg return; 3071 1.1 mrg } 3072 1.1 mrg 3073 1.1 mrg /* Dereference the expression, where needed. */ 3074 1.1 mrg se->expr = gfc_maybe_dereference_var (sym, se->expr, se->descriptor_only, 3075 1.1 mrg is_classarray); 3076 1.1 mrg 3077 1.1 mrg ref = expr->ref; 3078 1.1 mrg } 3079 1.1 mrg 3080 1.1 mrg /* For character variables, also get the length. */ 3081 1.1 mrg if (sym->ts.type == BT_CHARACTER) 3082 1.1 mrg { 3083 1.1 mrg /* If the character length of an entry isn't set, get the length from 3084 1.1 mrg the master function instead. */ 3085 1.1 mrg if (sym->attr.entry && !sym->ts.u.cl->backend_decl) 3086 1.1 mrg se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl; 3087 1.1 mrg else 3088 1.1 mrg se->string_length = sym->ts.u.cl->backend_decl; 3089 1.1 mrg gcc_assert (se->string_length); 3090 1.1 mrg } 3091 1.1 mrg 3092 1.1 mrg gfc_typespec *ts = &sym->ts; 3093 1.1 mrg while (ref) 3094 1.1 mrg { 3095 1.1 mrg switch (ref->type) 3096 1.1 mrg { 3097 1.1 mrg case REF_ARRAY: 3098 1.1 mrg /* Return the descriptor if that's what we want and this is an array 3099 1.1 mrg section reference. */ 3100 1.1 mrg if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT) 3101 1.1 mrg return; 3102 1.1 mrg /* TODO: Pointers to single elements of array sections, eg elemental subs. */ 3103 1.1 mrg /* Return the descriptor for array pointers and allocations. */ 3104 1.1 mrg if (se->want_pointer 3105 1.1 mrg && ref->next == NULL && (se->descriptor_only)) 3106 1.1 mrg return; 3107 1.1 mrg 3108 1.1 mrg gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where); 3109 1.1 mrg /* Return a pointer to an element. */ 3110 1.1 mrg break; 3111 1.1 mrg 3112 1.1 mrg case REF_COMPONENT: 3113 1.1 mrg ts = &ref->u.c.component->ts; 3114 1.1 mrg if (first_time && is_classarray && sym->attr.dummy 3115 1.1 mrg && se->descriptor_only 3116 1.1 mrg && !CLASS_DATA (sym)->attr.allocatable 3117 1.1 mrg && !CLASS_DATA (sym)->attr.class_pointer 3118 1.1 mrg && CLASS_DATA (sym)->as 3119 1.1 mrg && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK 3120 1.1 mrg && strcmp ("_data", ref->u.c.component->name) == 0) 3121 1.1 mrg /* Skip the first ref of a _data component, because for class 3122 1.1 mrg arrays that one is already done by introducing a temporary 3123 1.1 mrg array descriptor. */ 3124 1.1 mrg break; 3125 1.1 mrg 3126 1.1 mrg if (ref->u.c.sym->attr.extension) 3127 1.1 mrg conv_parent_component_references (se, ref); 3128 1.1 mrg 3129 1.1 mrg gfc_conv_component_ref (se, ref); 3130 1.1 mrg if (!ref->next && ref->u.c.sym->attr.codimension 3131 1.1 mrg && se->want_pointer && se->descriptor_only) 3132 1.1 mrg return; 3133 1.1 mrg 3134 1.1 mrg break; 3135 1.1 mrg 3136 1.1 mrg case REF_SUBSTRING: 3137 1.1 mrg gfc_conv_substring (se, ref, expr->ts.kind, 3138 1.1 mrg expr->symtree->name, &expr->where); 3139 1.1 mrg break; 3140 1.1 mrg 3141 1.1 mrg case REF_INQUIRY: 3142 1.1 mrg conv_inquiry (se, ref, expr, ts); 3143 1.1 mrg break; 3144 1.1 mrg 3145 1.1 mrg default: 3146 1.1 mrg gcc_unreachable (); 3147 1.1 mrg break; 3148 1.1 mrg } 3149 1.1 mrg first_time = false; 3150 1.1 mrg ref = ref->next; 3151 1.1 mrg } 3152 1.1 mrg /* Pointer assignment, allocation or pass by reference. Arrays are handled 3153 1.1 mrg separately. */ 3154 1.1 mrg if (se->want_pointer) 3155 1.1 mrg { 3156 1.1 mrg if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr)) 3157 1.1 mrg gfc_conv_string_parameter (se); 3158 1.1 mrg else 3159 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, se->expr); 3160 1.1 mrg } 3161 1.1 mrg } 3162 1.1 mrg 3163 1.1 mrg 3164 1.1 mrg /* Unary ops are easy... Or they would be if ! was a valid op. */ 3165 1.1 mrg 3166 1.1 mrg static void 3167 1.1 mrg gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr) 3168 1.1 mrg { 3169 1.1 mrg gfc_se operand; 3170 1.1 mrg tree type; 3171 1.1 mrg 3172 1.1 mrg gcc_assert (expr->ts.type != BT_CHARACTER); 3173 1.1 mrg /* Initialize the operand. */ 3174 1.1 mrg gfc_init_se (&operand, se); 3175 1.1 mrg gfc_conv_expr_val (&operand, expr->value.op.op1); 3176 1.1 mrg gfc_add_block_to_block (&se->pre, &operand.pre); 3177 1.1 mrg 3178 1.1 mrg type = gfc_typenode_for_spec (&expr->ts); 3179 1.1 mrg 3180 1.1 mrg /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC. 3181 1.1 mrg We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)). 3182 1.1 mrg All other unary operators have an equivalent GIMPLE unary operator. */ 3183 1.1 mrg if (code == TRUTH_NOT_EXPR) 3184 1.1 mrg se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr, 3185 1.1 mrg build_int_cst (type, 0)); 3186 1.1 mrg else 3187 1.1 mrg se->expr = fold_build1_loc (input_location, code, type, operand.expr); 3188 1.1 mrg 3189 1.1 mrg } 3190 1.1 mrg 3191 1.1 mrg /* Expand power operator to optimal multiplications when a value is raised 3192 1.1 mrg to a constant integer n. See section 4.6.3, "Evaluation of Powers" of 3193 1.1 mrg Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer 3194 1.1 mrg Programming", 3rd Edition, 1998. */ 3195 1.1 mrg 3196 1.1 mrg /* This code is mostly duplicated from expand_powi in the backend. 3197 1.1 mrg We establish the "optimal power tree" lookup table with the defined size. 3198 1.1 mrg The items in the table are the exponents used to calculate the index 3199 1.1 mrg exponents. Any integer n less than the value can get an "addition chain", 3200 1.1 mrg with the first node being one. */ 3201 1.1 mrg #define POWI_TABLE_SIZE 256 3202 1.1 mrg 3203 1.1 mrg /* The table is from builtins.cc. */ 3204 1.1 mrg static const unsigned char powi_table[POWI_TABLE_SIZE] = 3205 1.1 mrg { 3206 1.1 mrg 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */ 3207 1.1 mrg 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */ 3208 1.1 mrg 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */ 3209 1.1 mrg 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */ 3210 1.1 mrg 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */ 3211 1.1 mrg 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */ 3212 1.1 mrg 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */ 3213 1.1 mrg 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */ 3214 1.1 mrg 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */ 3215 1.1 mrg 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */ 3216 1.1 mrg 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */ 3217 1.1 mrg 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */ 3218 1.1 mrg 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */ 3219 1.1 mrg 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */ 3220 1.1 mrg 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */ 3221 1.1 mrg 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */ 3222 1.1 mrg 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */ 3223 1.1 mrg 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */ 3224 1.1 mrg 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */ 3225 1.1 mrg 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */ 3226 1.1 mrg 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */ 3227 1.1 mrg 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */ 3228 1.1 mrg 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */ 3229 1.1 mrg 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */ 3230 1.1 mrg 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */ 3231 1.1 mrg 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */ 3232 1.1 mrg 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */ 3233 1.1 mrg 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */ 3234 1.1 mrg 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */ 3235 1.1 mrg 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */ 3236 1.1 mrg 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */ 3237 1.1 mrg 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */ 3238 1.1 mrg }; 3239 1.1 mrg 3240 1.1 mrg /* If n is larger than lookup table's max index, we use the "window 3241 1.1 mrg method". */ 3242 1.1 mrg #define POWI_WINDOW_SIZE 3 3243 1.1 mrg 3244 1.1 mrg /* Recursive function to expand the power operator. The temporary 3245 1.1 mrg values are put in tmpvar. The function returns tmpvar[1] ** n. */ 3246 1.1 mrg static tree 3247 1.1 mrg gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar) 3248 1.1 mrg { 3249 1.1 mrg tree op0; 3250 1.1 mrg tree op1; 3251 1.1 mrg tree tmp; 3252 1.1 mrg int digit; 3253 1.1 mrg 3254 1.1 mrg if (n < POWI_TABLE_SIZE) 3255 1.1 mrg { 3256 1.1 mrg if (tmpvar[n]) 3257 1.1 mrg return tmpvar[n]; 3258 1.1 mrg 3259 1.1 mrg op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar); 3260 1.1 mrg op1 = gfc_conv_powi (se, powi_table[n], tmpvar); 3261 1.1 mrg } 3262 1.1 mrg else if (n & 1) 3263 1.1 mrg { 3264 1.1 mrg digit = n & ((1 << POWI_WINDOW_SIZE) - 1); 3265 1.1 mrg op0 = gfc_conv_powi (se, n - digit, tmpvar); 3266 1.1 mrg op1 = gfc_conv_powi (se, digit, tmpvar); 3267 1.1 mrg } 3268 1.1 mrg else 3269 1.1 mrg { 3270 1.1 mrg op0 = gfc_conv_powi (se, n >> 1, tmpvar); 3271 1.1 mrg op1 = op0; 3272 1.1 mrg } 3273 1.1 mrg 3274 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1); 3275 1.1 mrg tmp = gfc_evaluate_now (tmp, &se->pre); 3276 1.1 mrg 3277 1.1 mrg if (n < POWI_TABLE_SIZE) 3278 1.1 mrg tmpvar[n] = tmp; 3279 1.1 mrg 3280 1.1 mrg return tmp; 3281 1.1 mrg } 3282 1.1 mrg 3283 1.1 mrg 3284 1.1 mrg /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully, 3285 1.1 mrg return 1. Else return 0 and a call to runtime library functions 3286 1.1 mrg will have to be built. */ 3287 1.1 mrg static int 3288 1.1 mrg gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs) 3289 1.1 mrg { 3290 1.1 mrg tree cond; 3291 1.1 mrg tree tmp; 3292 1.1 mrg tree type; 3293 1.1 mrg tree vartmp[POWI_TABLE_SIZE]; 3294 1.1 mrg HOST_WIDE_INT m; 3295 1.1 mrg unsigned HOST_WIDE_INT n; 3296 1.1 mrg int sgn; 3297 1.1 mrg wi::tree_to_wide_ref wrhs = wi::to_wide (rhs); 3298 1.1 mrg 3299 1.1 mrg /* If exponent is too large, we won't expand it anyway, so don't bother 3300 1.1 mrg with large integer values. */ 3301 1.1 mrg if (!wi::fits_shwi_p (wrhs)) 3302 1.1 mrg return 0; 3303 1.1 mrg 3304 1.1 mrg m = wrhs.to_shwi (); 3305 1.1 mrg /* Use the wide_int's routine to reliably get the absolute value on all 3306 1.1 mrg platforms. Then convert it to a HOST_WIDE_INT like above. */ 3307 1.1 mrg n = wi::abs (wrhs).to_shwi (); 3308 1.1 mrg 3309 1.1 mrg type = TREE_TYPE (lhs); 3310 1.1 mrg sgn = tree_int_cst_sgn (rhs); 3311 1.1 mrg 3312 1.1 mrg if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations) 3313 1.1 mrg || optimize_size) && (m > 2 || m < -1)) 3314 1.1 mrg return 0; 3315 1.1 mrg 3316 1.1 mrg /* rhs == 0 */ 3317 1.1 mrg if (sgn == 0) 3318 1.1 mrg { 3319 1.1 mrg se->expr = gfc_build_const (type, integer_one_node); 3320 1.1 mrg return 1; 3321 1.1 mrg } 3322 1.1 mrg 3323 1.1 mrg /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */ 3324 1.1 mrg if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE)) 3325 1.1 mrg { 3326 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, 3327 1.1 mrg lhs, build_int_cst (TREE_TYPE (lhs), -1)); 3328 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, 3329 1.1 mrg lhs, build_int_cst (TREE_TYPE (lhs), 1)); 3330 1.1 mrg 3331 1.1 mrg /* If rhs is even, 3332 1.1 mrg result = (lhs == 1 || lhs == -1) ? 1 : 0. */ 3333 1.1 mrg if ((n & 1) == 0) 3334 1.1 mrg { 3335 1.1 mrg tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, 3336 1.1 mrg logical_type_node, tmp, cond); 3337 1.1 mrg se->expr = fold_build3_loc (input_location, COND_EXPR, type, 3338 1.1 mrg tmp, build_int_cst (type, 1), 3339 1.1 mrg build_int_cst (type, 0)); 3340 1.1 mrg return 1; 3341 1.1 mrg } 3342 1.1 mrg /* If rhs is odd, 3343 1.1 mrg result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */ 3344 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp, 3345 1.1 mrg build_int_cst (type, -1), 3346 1.1 mrg build_int_cst (type, 0)); 3347 1.1 mrg se->expr = fold_build3_loc (input_location, COND_EXPR, type, 3348 1.1 mrg cond, build_int_cst (type, 1), tmp); 3349 1.1 mrg return 1; 3350 1.1 mrg } 3351 1.1 mrg 3352 1.1 mrg memset (vartmp, 0, sizeof (vartmp)); 3353 1.1 mrg vartmp[1] = lhs; 3354 1.1 mrg if (sgn == -1) 3355 1.1 mrg { 3356 1.1 mrg tmp = gfc_build_const (type, integer_one_node); 3357 1.1 mrg vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp, 3358 1.1 mrg vartmp[1]); 3359 1.1 mrg } 3360 1.1 mrg 3361 1.1 mrg se->expr = gfc_conv_powi (se, n, vartmp); 3362 1.1 mrg 3363 1.1 mrg return 1; 3364 1.1 mrg } 3365 1.1 mrg 3366 1.1 mrg 3367 1.1 mrg /* Power op (**). Constant integer exponent has special handling. */ 3368 1.1 mrg 3369 1.1 mrg static void 3370 1.1 mrg gfc_conv_power_op (gfc_se * se, gfc_expr * expr) 3371 1.1 mrg { 3372 1.1 mrg tree gfc_int4_type_node; 3373 1.1 mrg int kind; 3374 1.1 mrg int ikind; 3375 1.1 mrg int res_ikind_1, res_ikind_2; 3376 1.1 mrg gfc_se lse; 3377 1.1 mrg gfc_se rse; 3378 1.1 mrg tree fndecl = NULL; 3379 1.1 mrg 3380 1.1 mrg gfc_init_se (&lse, se); 3381 1.1 mrg gfc_conv_expr_val (&lse, expr->value.op.op1); 3382 1.1 mrg lse.expr = gfc_evaluate_now (lse.expr, &lse.pre); 3383 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.pre); 3384 1.1 mrg 3385 1.1 mrg gfc_init_se (&rse, se); 3386 1.1 mrg gfc_conv_expr_val (&rse, expr->value.op.op2); 3387 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.pre); 3388 1.1 mrg 3389 1.1 mrg if (expr->value.op.op2->ts.type == BT_INTEGER 3390 1.1 mrg && expr->value.op.op2->expr_type == EXPR_CONSTANT) 3391 1.1 mrg if (gfc_conv_cst_int_power (se, lse.expr, rse.expr)) 3392 1.1 mrg return; 3393 1.1 mrg 3394 1.1 mrg if (INTEGER_CST_P (lse.expr) 3395 1.1 mrg && TREE_CODE (TREE_TYPE (rse.expr)) == INTEGER_TYPE) 3396 1.1 mrg { 3397 1.1 mrg wi::tree_to_wide_ref wlhs = wi::to_wide (lse.expr); 3398 1.1 mrg HOST_WIDE_INT v, w; 3399 1.1 mrg int kind, ikind, bit_size; 3400 1.1 mrg 3401 1.1 mrg v = wlhs.to_shwi (); 3402 1.1 mrg w = abs (v); 3403 1.1 mrg 3404 1.1 mrg kind = expr->value.op.op1->ts.kind; 3405 1.1 mrg ikind = gfc_validate_kind (BT_INTEGER, kind, false); 3406 1.1 mrg bit_size = gfc_integer_kinds[ikind].bit_size; 3407 1.1 mrg 3408 1.1 mrg if (v == 1) 3409 1.1 mrg { 3410 1.1 mrg /* 1**something is always 1. */ 3411 1.1 mrg se->expr = build_int_cst (TREE_TYPE (lse.expr), 1); 3412 1.1 mrg return; 3413 1.1 mrg } 3414 1.1 mrg else if (v == -1) 3415 1.1 mrg { 3416 1.1 mrg /* (-1)**n is 1 - ((n & 1) << 1) */ 3417 1.1 mrg tree type; 3418 1.1 mrg tree tmp; 3419 1.1 mrg 3420 1.1 mrg type = TREE_TYPE (lse.expr); 3421 1.1 mrg tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type, 3422 1.1 mrg rse.expr, build_int_cst (type, 1)); 3423 1.1 mrg tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type, 3424 1.1 mrg tmp, build_int_cst (type, 1)); 3425 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, type, 3426 1.1 mrg build_int_cst (type, 1), tmp); 3427 1.1 mrg se->expr = tmp; 3428 1.1 mrg return; 3429 1.1 mrg } 3430 1.1 mrg else if (w > 0 && ((w & (w-1)) == 0) && ((w >> (bit_size-1)) == 0)) 3431 1.1 mrg { 3432 1.1 mrg /* Here v is +/- 2**e. The further simplification uses 3433 1.1 mrg 2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n = 3434 1.1 mrg 1<<(4*n), etc., but we have to make sure to return zero 3435 1.1 mrg if the number of bits is too large. */ 3436 1.1 mrg tree lshift; 3437 1.1 mrg tree type; 3438 1.1 mrg tree shift; 3439 1.1 mrg tree ge; 3440 1.1 mrg tree cond; 3441 1.1 mrg tree num_bits; 3442 1.1 mrg tree cond2; 3443 1.1 mrg tree tmp1; 3444 1.1 mrg 3445 1.1 mrg type = TREE_TYPE (lse.expr); 3446 1.1 mrg 3447 1.1 mrg if (w == 2) 3448 1.1 mrg shift = rse.expr; 3449 1.1 mrg else if (w == 4) 3450 1.1 mrg shift = fold_build2_loc (input_location, PLUS_EXPR, 3451 1.1 mrg TREE_TYPE (rse.expr), 3452 1.1 mrg rse.expr, rse.expr); 3453 1.1 mrg else 3454 1.1 mrg { 3455 1.1 mrg /* use popcount for fast log2(w) */ 3456 1.1 mrg int e = wi::popcount (w-1); 3457 1.1 mrg shift = fold_build2_loc (input_location, MULT_EXPR, 3458 1.1 mrg TREE_TYPE (rse.expr), 3459 1.1 mrg build_int_cst (TREE_TYPE (rse.expr), e), 3460 1.1 mrg rse.expr); 3461 1.1 mrg } 3462 1.1 mrg 3463 1.1 mrg lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type, 3464 1.1 mrg build_int_cst (type, 1), shift); 3465 1.1 mrg ge = fold_build2_loc (input_location, GE_EXPR, logical_type_node, 3466 1.1 mrg rse.expr, build_int_cst (type, 0)); 3467 1.1 mrg cond = fold_build3_loc (input_location, COND_EXPR, type, ge, lshift, 3468 1.1 mrg build_int_cst (type, 0)); 3469 1.1 mrg num_bits = build_int_cst (TREE_TYPE (rse.expr), TYPE_PRECISION (type)); 3470 1.1 mrg cond2 = fold_build2_loc (input_location, GE_EXPR, logical_type_node, 3471 1.1 mrg rse.expr, num_bits); 3472 1.1 mrg tmp1 = fold_build3_loc (input_location, COND_EXPR, type, cond2, 3473 1.1 mrg build_int_cst (type, 0), cond); 3474 1.1 mrg if (v > 0) 3475 1.1 mrg { 3476 1.1 mrg se->expr = tmp1; 3477 1.1 mrg } 3478 1.1 mrg else 3479 1.1 mrg { 3480 1.1 mrg /* for v < 0, calculate v**n = |v|**n * (-1)**n */ 3481 1.1 mrg tree tmp2; 3482 1.1 mrg tmp2 = fold_build2_loc (input_location, BIT_AND_EXPR, type, 3483 1.1 mrg rse.expr, build_int_cst (type, 1)); 3484 1.1 mrg tmp2 = fold_build2_loc (input_location, LSHIFT_EXPR, type, 3485 1.1 mrg tmp2, build_int_cst (type, 1)); 3486 1.1 mrg tmp2 = fold_build2_loc (input_location, MINUS_EXPR, type, 3487 1.1 mrg build_int_cst (type, 1), tmp2); 3488 1.1 mrg se->expr = fold_build2_loc (input_location, MULT_EXPR, type, 3489 1.1 mrg tmp1, tmp2); 3490 1.1 mrg } 3491 1.1 mrg return; 3492 1.1 mrg } 3493 1.1 mrg } 3494 1.1 mrg 3495 1.1 mrg gfc_int4_type_node = gfc_get_int_type (4); 3496 1.1 mrg 3497 1.1 mrg /* In case of integer operands with kinds 1 or 2, we call the integer kind 4 3498 1.1 mrg library routine. But in the end, we have to convert the result back 3499 1.1 mrg if this case applies -- with res_ikind_K, we keep track whether operand K 3500 1.1 mrg falls into this case. */ 3501 1.1 mrg res_ikind_1 = -1; 3502 1.1 mrg res_ikind_2 = -1; 3503 1.1 mrg 3504 1.1 mrg kind = expr->value.op.op1->ts.kind; 3505 1.1 mrg switch (expr->value.op.op2->ts.type) 3506 1.1 mrg { 3507 1.1 mrg case BT_INTEGER: 3508 1.1 mrg ikind = expr->value.op.op2->ts.kind; 3509 1.1 mrg switch (ikind) 3510 1.1 mrg { 3511 1.1 mrg case 1: 3512 1.1 mrg case 2: 3513 1.1 mrg rse.expr = convert (gfc_int4_type_node, rse.expr); 3514 1.1 mrg res_ikind_2 = ikind; 3515 1.1 mrg /* Fall through. */ 3516 1.1 mrg 3517 1.1 mrg case 4: 3518 1.1 mrg ikind = 0; 3519 1.1 mrg break; 3520 1.1 mrg 3521 1.1 mrg case 8: 3522 1.1 mrg ikind = 1; 3523 1.1 mrg break; 3524 1.1 mrg 3525 1.1 mrg case 16: 3526 1.1 mrg ikind = 2; 3527 1.1 mrg break; 3528 1.1 mrg 3529 1.1 mrg default: 3530 1.1 mrg gcc_unreachable (); 3531 1.1 mrg } 3532 1.1 mrg switch (kind) 3533 1.1 mrg { 3534 1.1 mrg case 1: 3535 1.1 mrg case 2: 3536 1.1 mrg if (expr->value.op.op1->ts.type == BT_INTEGER) 3537 1.1 mrg { 3538 1.1 mrg lse.expr = convert (gfc_int4_type_node, lse.expr); 3539 1.1 mrg res_ikind_1 = kind; 3540 1.1 mrg } 3541 1.1 mrg else 3542 1.1 mrg gcc_unreachable (); 3543 1.1 mrg /* Fall through. */ 3544 1.1 mrg 3545 1.1 mrg case 4: 3546 1.1 mrg kind = 0; 3547 1.1 mrg break; 3548 1.1 mrg 3549 1.1 mrg case 8: 3550 1.1 mrg kind = 1; 3551 1.1 mrg break; 3552 1.1 mrg 3553 1.1 mrg case 10: 3554 1.1 mrg kind = 2; 3555 1.1 mrg break; 3556 1.1 mrg 3557 1.1 mrg case 16: 3558 1.1 mrg kind = 3; 3559 1.1 mrg break; 3560 1.1 mrg 3561 1.1 mrg default: 3562 1.1 mrg gcc_unreachable (); 3563 1.1 mrg } 3564 1.1 mrg 3565 1.1 mrg switch (expr->value.op.op1->ts.type) 3566 1.1 mrg { 3567 1.1 mrg case BT_INTEGER: 3568 1.1 mrg if (kind == 3) /* Case 16 was not handled properly above. */ 3569 1.1 mrg kind = 2; 3570 1.1 mrg fndecl = gfor_fndecl_math_powi[kind][ikind].integer; 3571 1.1 mrg break; 3572 1.1 mrg 3573 1.1 mrg case BT_REAL: 3574 1.1 mrg /* Use builtins for real ** int4. */ 3575 1.1 mrg if (ikind == 0) 3576 1.1 mrg { 3577 1.1 mrg switch (kind) 3578 1.1 mrg { 3579 1.1 mrg case 0: 3580 1.1 mrg fndecl = builtin_decl_explicit (BUILT_IN_POWIF); 3581 1.1 mrg break; 3582 1.1 mrg 3583 1.1 mrg case 1: 3584 1.1 mrg fndecl = builtin_decl_explicit (BUILT_IN_POWI); 3585 1.1 mrg break; 3586 1.1 mrg 3587 1.1 mrg case 2: 3588 1.1 mrg fndecl = builtin_decl_explicit (BUILT_IN_POWIL); 3589 1.1 mrg break; 3590 1.1 mrg 3591 1.1 mrg case 3: 3592 1.1 mrg /* Use the __builtin_powil() only if real(kind=16) is 3593 1.1 mrg actually the C long double type. */ 3594 1.1 mrg if (!gfc_real16_is_float128) 3595 1.1 mrg fndecl = builtin_decl_explicit (BUILT_IN_POWIL); 3596 1.1 mrg break; 3597 1.1 mrg 3598 1.1 mrg default: 3599 1.1 mrg gcc_unreachable (); 3600 1.1 mrg } 3601 1.1 mrg } 3602 1.1 mrg 3603 1.1 mrg /* If we don't have a good builtin for this, go for the 3604 1.1 mrg library function. */ 3605 1.1 mrg if (!fndecl) 3606 1.1 mrg fndecl = gfor_fndecl_math_powi[kind][ikind].real; 3607 1.1 mrg break; 3608 1.1 mrg 3609 1.1 mrg case BT_COMPLEX: 3610 1.1 mrg fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx; 3611 1.1 mrg break; 3612 1.1 mrg 3613 1.1 mrg default: 3614 1.1 mrg gcc_unreachable (); 3615 1.1 mrg } 3616 1.1 mrg break; 3617 1.1 mrg 3618 1.1 mrg case BT_REAL: 3619 1.1 mrg fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind); 3620 1.1 mrg break; 3621 1.1 mrg 3622 1.1 mrg case BT_COMPLEX: 3623 1.1 mrg fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind); 3624 1.1 mrg break; 3625 1.1 mrg 3626 1.1 mrg default: 3627 1.1 mrg gcc_unreachable (); 3628 1.1 mrg break; 3629 1.1 mrg } 3630 1.1 mrg 3631 1.1 mrg se->expr = build_call_expr_loc (input_location, 3632 1.1 mrg fndecl, 2, lse.expr, rse.expr); 3633 1.1 mrg 3634 1.1 mrg /* Convert the result back if it is of wrong integer kind. */ 3635 1.1 mrg if (res_ikind_1 != -1 && res_ikind_2 != -1) 3636 1.1 mrg { 3637 1.1 mrg /* We want the maximum of both operand kinds as result. */ 3638 1.1 mrg if (res_ikind_1 < res_ikind_2) 3639 1.1 mrg res_ikind_1 = res_ikind_2; 3640 1.1 mrg se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr); 3641 1.1 mrg } 3642 1.1 mrg } 3643 1.1 mrg 3644 1.1 mrg 3645 1.1 mrg /* Generate code to allocate a string temporary. */ 3646 1.1 mrg 3647 1.1 mrg tree 3648 1.1 mrg gfc_conv_string_tmp (gfc_se * se, tree type, tree len) 3649 1.1 mrg { 3650 1.1 mrg tree var; 3651 1.1 mrg tree tmp; 3652 1.1 mrg 3653 1.1 mrg if (gfc_can_put_var_on_stack (len)) 3654 1.1 mrg { 3655 1.1 mrg /* Create a temporary variable to hold the result. */ 3656 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, 3657 1.1 mrg TREE_TYPE (len), len, 3658 1.1 mrg build_int_cst (TREE_TYPE (len), 1)); 3659 1.1 mrg tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp); 3660 1.1 mrg 3661 1.1 mrg if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE) 3662 1.1 mrg tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp); 3663 1.1 mrg else 3664 1.1 mrg tmp = build_array_type (TREE_TYPE (type), tmp); 3665 1.1 mrg 3666 1.1 mrg var = gfc_create_var (tmp, "str"); 3667 1.1 mrg var = gfc_build_addr_expr (type, var); 3668 1.1 mrg } 3669 1.1 mrg else 3670 1.1 mrg { 3671 1.1 mrg /* Allocate a temporary to hold the result. */ 3672 1.1 mrg var = gfc_create_var (type, "pstr"); 3673 1.1 mrg gcc_assert (POINTER_TYPE_P (type)); 3674 1.1 mrg tmp = TREE_TYPE (type); 3675 1.1 mrg if (TREE_CODE (tmp) == ARRAY_TYPE) 3676 1.1 mrg tmp = TREE_TYPE (tmp); 3677 1.1 mrg tmp = TYPE_SIZE_UNIT (tmp); 3678 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node, 3679 1.1 mrg fold_convert (size_type_node, len), 3680 1.1 mrg fold_convert (size_type_node, tmp)); 3681 1.1 mrg tmp = gfc_call_malloc (&se->pre, type, tmp); 3682 1.1 mrg gfc_add_modify (&se->pre, var, tmp); 3683 1.1 mrg 3684 1.1 mrg /* Free the temporary afterwards. */ 3685 1.1 mrg tmp = gfc_call_free (var); 3686 1.1 mrg gfc_add_expr_to_block (&se->post, tmp); 3687 1.1 mrg } 3688 1.1 mrg 3689 1.1 mrg return var; 3690 1.1 mrg } 3691 1.1 mrg 3692 1.1 mrg 3693 1.1 mrg /* Handle a string concatenation operation. A temporary will be allocated to 3694 1.1 mrg hold the result. */ 3695 1.1 mrg 3696 1.1 mrg static void 3697 1.1 mrg gfc_conv_concat_op (gfc_se * se, gfc_expr * expr) 3698 1.1 mrg { 3699 1.1 mrg gfc_se lse, rse; 3700 1.1 mrg tree len, type, var, tmp, fndecl; 3701 1.1 mrg 3702 1.1 mrg gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER 3703 1.1 mrg && expr->value.op.op2->ts.type == BT_CHARACTER); 3704 1.1 mrg gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind); 3705 1.1 mrg 3706 1.1 mrg gfc_init_se (&lse, se); 3707 1.1 mrg gfc_conv_expr (&lse, expr->value.op.op1); 3708 1.1 mrg gfc_conv_string_parameter (&lse); 3709 1.1 mrg gfc_init_se (&rse, se); 3710 1.1 mrg gfc_conv_expr (&rse, expr->value.op.op2); 3711 1.1 mrg gfc_conv_string_parameter (&rse); 3712 1.1 mrg 3713 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.pre); 3714 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.pre); 3715 1.1 mrg 3716 1.1 mrg type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl); 3717 1.1 mrg len = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); 3718 1.1 mrg if (len == NULL_TREE) 3719 1.1 mrg { 3720 1.1 mrg len = fold_build2_loc (input_location, PLUS_EXPR, 3721 1.1 mrg gfc_charlen_type_node, 3722 1.1 mrg fold_convert (gfc_charlen_type_node, 3723 1.1 mrg lse.string_length), 3724 1.1 mrg fold_convert (gfc_charlen_type_node, 3725 1.1 mrg rse.string_length)); 3726 1.1 mrg } 3727 1.1 mrg 3728 1.1 mrg type = build_pointer_type (type); 3729 1.1 mrg 3730 1.1 mrg var = gfc_conv_string_tmp (se, type, len); 3731 1.1 mrg 3732 1.1 mrg /* Do the actual concatenation. */ 3733 1.1 mrg if (expr->ts.kind == 1) 3734 1.1 mrg fndecl = gfor_fndecl_concat_string; 3735 1.1 mrg else if (expr->ts.kind == 4) 3736 1.1 mrg fndecl = gfor_fndecl_concat_string_char4; 3737 1.1 mrg else 3738 1.1 mrg gcc_unreachable (); 3739 1.1 mrg 3740 1.1 mrg tmp = build_call_expr_loc (input_location, 3741 1.1 mrg fndecl, 6, len, var, lse.string_length, lse.expr, 3742 1.1 mrg rse.string_length, rse.expr); 3743 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 3744 1.1 mrg 3745 1.1 mrg /* Add the cleanup for the operands. */ 3746 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.post); 3747 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.post); 3748 1.1 mrg 3749 1.1 mrg se->expr = var; 3750 1.1 mrg se->string_length = len; 3751 1.1 mrg } 3752 1.1 mrg 3753 1.1 mrg /* Translates an op expression. Common (binary) cases are handled by this 3754 1.1 mrg function, others are passed on. Recursion is used in either case. 3755 1.1 mrg We use the fact that (op1.ts == op2.ts) (except for the power 3756 1.1 mrg operator **). 3757 1.1 mrg Operators need no special handling for scalarized expressions as long as 3758 1.1 mrg they call gfc_conv_simple_val to get their operands. 3759 1.1 mrg Character strings get special handling. */ 3760 1.1 mrg 3761 1.1 mrg static void 3762 1.1 mrg gfc_conv_expr_op (gfc_se * se, gfc_expr * expr) 3763 1.1 mrg { 3764 1.1 mrg enum tree_code code; 3765 1.1 mrg gfc_se lse; 3766 1.1 mrg gfc_se rse; 3767 1.1 mrg tree tmp, type; 3768 1.1 mrg int lop; 3769 1.1 mrg int checkstring; 3770 1.1 mrg 3771 1.1 mrg checkstring = 0; 3772 1.1 mrg lop = 0; 3773 1.1 mrg switch (expr->value.op.op) 3774 1.1 mrg { 3775 1.1 mrg case INTRINSIC_PARENTHESES: 3776 1.1 mrg if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX) 3777 1.1 mrg && flag_protect_parens) 3778 1.1 mrg { 3779 1.1 mrg gfc_conv_unary_op (PAREN_EXPR, se, expr); 3780 1.1 mrg gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr))); 3781 1.1 mrg return; 3782 1.1 mrg } 3783 1.1 mrg 3784 1.1 mrg /* Fallthrough. */ 3785 1.1 mrg case INTRINSIC_UPLUS: 3786 1.1 mrg gfc_conv_expr (se, expr->value.op.op1); 3787 1.1 mrg return; 3788 1.1 mrg 3789 1.1 mrg case INTRINSIC_UMINUS: 3790 1.1 mrg gfc_conv_unary_op (NEGATE_EXPR, se, expr); 3791 1.1 mrg return; 3792 1.1 mrg 3793 1.1 mrg case INTRINSIC_NOT: 3794 1.1 mrg gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr); 3795 1.1 mrg return; 3796 1.1 mrg 3797 1.1 mrg case INTRINSIC_PLUS: 3798 1.1 mrg code = PLUS_EXPR; 3799 1.1 mrg break; 3800 1.1 mrg 3801 1.1 mrg case INTRINSIC_MINUS: 3802 1.1 mrg code = MINUS_EXPR; 3803 1.1 mrg break; 3804 1.1 mrg 3805 1.1 mrg case INTRINSIC_TIMES: 3806 1.1 mrg code = MULT_EXPR; 3807 1.1 mrg break; 3808 1.1 mrg 3809 1.1 mrg case INTRINSIC_DIVIDE: 3810 1.1 mrg /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is 3811 1.1 mrg an integer, we must round towards zero, so we use a 3812 1.1 mrg TRUNC_DIV_EXPR. */ 3813 1.1 mrg if (expr->ts.type == BT_INTEGER) 3814 1.1 mrg code = TRUNC_DIV_EXPR; 3815 1.1 mrg else 3816 1.1 mrg code = RDIV_EXPR; 3817 1.1 mrg break; 3818 1.1 mrg 3819 1.1 mrg case INTRINSIC_POWER: 3820 1.1 mrg gfc_conv_power_op (se, expr); 3821 1.1 mrg return; 3822 1.1 mrg 3823 1.1 mrg case INTRINSIC_CONCAT: 3824 1.1 mrg gfc_conv_concat_op (se, expr); 3825 1.1 mrg return; 3826 1.1 mrg 3827 1.1 mrg case INTRINSIC_AND: 3828 1.1 mrg code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR; 3829 1.1 mrg lop = 1; 3830 1.1 mrg break; 3831 1.1 mrg 3832 1.1 mrg case INTRINSIC_OR: 3833 1.1 mrg code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR; 3834 1.1 mrg lop = 1; 3835 1.1 mrg break; 3836 1.1 mrg 3837 1.1 mrg /* EQV and NEQV only work on logicals, but since we represent them 3838 1.1 mrg as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */ 3839 1.1 mrg case INTRINSIC_EQ: 3840 1.1 mrg case INTRINSIC_EQ_OS: 3841 1.1 mrg case INTRINSIC_EQV: 3842 1.1 mrg code = EQ_EXPR; 3843 1.1 mrg checkstring = 1; 3844 1.1 mrg lop = 1; 3845 1.1 mrg break; 3846 1.1 mrg 3847 1.1 mrg case INTRINSIC_NE: 3848 1.1 mrg case INTRINSIC_NE_OS: 3849 1.1 mrg case INTRINSIC_NEQV: 3850 1.1 mrg code = NE_EXPR; 3851 1.1 mrg checkstring = 1; 3852 1.1 mrg lop = 1; 3853 1.1 mrg break; 3854 1.1 mrg 3855 1.1 mrg case INTRINSIC_GT: 3856 1.1 mrg case INTRINSIC_GT_OS: 3857 1.1 mrg code = GT_EXPR; 3858 1.1 mrg checkstring = 1; 3859 1.1 mrg lop = 1; 3860 1.1 mrg break; 3861 1.1 mrg 3862 1.1 mrg case INTRINSIC_GE: 3863 1.1 mrg case INTRINSIC_GE_OS: 3864 1.1 mrg code = GE_EXPR; 3865 1.1 mrg checkstring = 1; 3866 1.1 mrg lop = 1; 3867 1.1 mrg break; 3868 1.1 mrg 3869 1.1 mrg case INTRINSIC_LT: 3870 1.1 mrg case INTRINSIC_LT_OS: 3871 1.1 mrg code = LT_EXPR; 3872 1.1 mrg checkstring = 1; 3873 1.1 mrg lop = 1; 3874 1.1 mrg break; 3875 1.1 mrg 3876 1.1 mrg case INTRINSIC_LE: 3877 1.1 mrg case INTRINSIC_LE_OS: 3878 1.1 mrg code = LE_EXPR; 3879 1.1 mrg checkstring = 1; 3880 1.1 mrg lop = 1; 3881 1.1 mrg break; 3882 1.1 mrg 3883 1.1 mrg case INTRINSIC_USER: 3884 1.1 mrg case INTRINSIC_ASSIGN: 3885 1.1 mrg /* These should be converted into function calls by the frontend. */ 3886 1.1 mrg gcc_unreachable (); 3887 1.1 mrg 3888 1.1 mrg default: 3889 1.1 mrg fatal_error (input_location, "Unknown intrinsic op"); 3890 1.1 mrg return; 3891 1.1 mrg } 3892 1.1 mrg 3893 1.1 mrg /* The only exception to this is **, which is handled separately anyway. */ 3894 1.1 mrg gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type); 3895 1.1 mrg 3896 1.1 mrg if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER) 3897 1.1 mrg checkstring = 0; 3898 1.1 mrg 3899 1.1 mrg /* lhs */ 3900 1.1 mrg gfc_init_se (&lse, se); 3901 1.1 mrg gfc_conv_expr (&lse, expr->value.op.op1); 3902 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.pre); 3903 1.1 mrg 3904 1.1 mrg /* rhs */ 3905 1.1 mrg gfc_init_se (&rse, se); 3906 1.1 mrg gfc_conv_expr (&rse, expr->value.op.op2); 3907 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.pre); 3908 1.1 mrg 3909 1.1 mrg if (checkstring) 3910 1.1 mrg { 3911 1.1 mrg gfc_conv_string_parameter (&lse); 3912 1.1 mrg gfc_conv_string_parameter (&rse); 3913 1.1 mrg 3914 1.1 mrg lse.expr = gfc_build_compare_string (lse.string_length, lse.expr, 3915 1.1 mrg rse.string_length, rse.expr, 3916 1.1 mrg expr->value.op.op1->ts.kind, 3917 1.1 mrg code); 3918 1.1 mrg rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0); 3919 1.1 mrg gfc_add_block_to_block (&lse.post, &rse.post); 3920 1.1 mrg } 3921 1.1 mrg 3922 1.1 mrg type = gfc_typenode_for_spec (&expr->ts); 3923 1.1 mrg 3924 1.1 mrg if (lop) 3925 1.1 mrg { 3926 1.1 mrg // Inhibit overeager optimization of Cray pointer comparisons (PR106692). 3927 1.1 mrg if (expr->value.op.op1->expr_type == EXPR_VARIABLE 3928 1.1 mrg && expr->value.op.op1->ts.type == BT_INTEGER 3929 1.1 mrg && expr->value.op.op1->symtree 3930 1.1 mrg && expr->value.op.op1->symtree->n.sym->attr.cray_pointer) 3931 1.1 mrg TREE_THIS_VOLATILE (lse.expr) = 1; 3932 1.1 mrg 3933 1.1 mrg if (expr->value.op.op2->expr_type == EXPR_VARIABLE 3934 1.1 mrg && expr->value.op.op2->ts.type == BT_INTEGER 3935 1.1 mrg && expr->value.op.op2->symtree 3936 1.1 mrg && expr->value.op.op2->symtree->n.sym->attr.cray_pointer) 3937 1.1 mrg TREE_THIS_VOLATILE (rse.expr) = 1; 3938 1.1 mrg 3939 1.1 mrg /* The result of logical ops is always logical_type_node. */ 3940 1.1 mrg tmp = fold_build2_loc (input_location, code, logical_type_node, 3941 1.1 mrg lse.expr, rse.expr); 3942 1.1 mrg se->expr = convert (type, tmp); 3943 1.1 mrg } 3944 1.1 mrg else 3945 1.1 mrg se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr); 3946 1.1 mrg 3947 1.1 mrg /* Add the post blocks. */ 3948 1.1 mrg gfc_add_block_to_block (&se->post, &rse.post); 3949 1.1 mrg gfc_add_block_to_block (&se->post, &lse.post); 3950 1.1 mrg } 3951 1.1 mrg 3952 1.1 mrg /* If a string's length is one, we convert it to a single character. */ 3953 1.1 mrg 3954 1.1 mrg tree 3955 1.1 mrg gfc_string_to_single_character (tree len, tree str, int kind) 3956 1.1 mrg { 3957 1.1 mrg 3958 1.1 mrg if (len == NULL 3959 1.1 mrg || !tree_fits_uhwi_p (len) 3960 1.1 mrg || !POINTER_TYPE_P (TREE_TYPE (str))) 3961 1.1 mrg return NULL_TREE; 3962 1.1 mrg 3963 1.1 mrg if (TREE_INT_CST_LOW (len) == 1) 3964 1.1 mrg { 3965 1.1 mrg str = fold_convert (gfc_get_pchar_type (kind), str); 3966 1.1 mrg return build_fold_indirect_ref_loc (input_location, str); 3967 1.1 mrg } 3968 1.1 mrg 3969 1.1 mrg if (kind == 1 3970 1.1 mrg && TREE_CODE (str) == ADDR_EXPR 3971 1.1 mrg && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF 3972 1.1 mrg && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST 3973 1.1 mrg && array_ref_low_bound (TREE_OPERAND (str, 0)) 3974 1.1 mrg == TREE_OPERAND (TREE_OPERAND (str, 0), 1) 3975 1.1 mrg && TREE_INT_CST_LOW (len) > 1 3976 1.1 mrg && TREE_INT_CST_LOW (len) 3977 1.1 mrg == (unsigned HOST_WIDE_INT) 3978 1.1 mrg TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0))) 3979 1.1 mrg { 3980 1.1 mrg tree ret = fold_convert (gfc_get_pchar_type (kind), str); 3981 1.1 mrg ret = build_fold_indirect_ref_loc (input_location, ret); 3982 1.1 mrg if (TREE_CODE (ret) == INTEGER_CST) 3983 1.1 mrg { 3984 1.1 mrg tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0); 3985 1.1 mrg int i, length = TREE_STRING_LENGTH (string_cst); 3986 1.1 mrg const char *ptr = TREE_STRING_POINTER (string_cst); 3987 1.1 mrg 3988 1.1 mrg for (i = 1; i < length; i++) 3989 1.1 mrg if (ptr[i] != ' ') 3990 1.1 mrg return NULL_TREE; 3991 1.1 mrg 3992 1.1 mrg return ret; 3993 1.1 mrg } 3994 1.1 mrg } 3995 1.1 mrg 3996 1.1 mrg return NULL_TREE; 3997 1.1 mrg } 3998 1.1 mrg 3999 1.1 mrg 4000 1.1 mrg static void 4001 1.1 mrg conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr) 4002 1.1 mrg { 4003 1.1 mrg gcc_assert (expr); 4004 1.1 mrg 4005 1.1 mrg /* We used to modify the tree here. Now it is done earlier in 4006 1.1 mrg the front-end, so we only check it here to avoid regressions. */ 4007 1.1 mrg if (sym->backend_decl) 4008 1.1 mrg { 4009 1.1 mrg gcc_assert (TREE_CODE (TREE_TYPE (sym->backend_decl)) == INTEGER_TYPE); 4010 1.1 mrg gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym->backend_decl)) == 1); 4011 1.1 mrg gcc_assert (TYPE_PRECISION (TREE_TYPE (sym->backend_decl)) == CHAR_TYPE_SIZE); 4012 1.1 mrg gcc_assert (DECL_BY_REFERENCE (sym->backend_decl) == 0); 4013 1.1 mrg } 4014 1.1 mrg 4015 1.1 mrg /* If we have a constant character expression, make it into an 4016 1.1 mrg integer of type C char. */ 4017 1.1 mrg if ((*expr)->expr_type == EXPR_CONSTANT) 4018 1.1 mrg { 4019 1.1 mrg gfc_typespec ts; 4020 1.1 mrg gfc_clear_ts (&ts); 4021 1.1 mrg 4022 1.1 mrg *expr = gfc_get_int_expr (gfc_default_character_kind, NULL, 4023 1.1 mrg (*expr)->value.character.string[0]); 4024 1.1 mrg } 4025 1.1 mrg else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE) 4026 1.1 mrg { 4027 1.1 mrg if ((*expr)->ref == NULL) 4028 1.1 mrg { 4029 1.1 mrg se->expr = gfc_string_to_single_character 4030 1.1 mrg (build_int_cst (integer_type_node, 1), 4031 1.1 mrg gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind), 4032 1.1 mrg gfc_get_symbol_decl 4033 1.1 mrg ((*expr)->symtree->n.sym)), 4034 1.1 mrg (*expr)->ts.kind); 4035 1.1 mrg } 4036 1.1 mrg else 4037 1.1 mrg { 4038 1.1 mrg gfc_conv_variable (se, *expr); 4039 1.1 mrg se->expr = gfc_string_to_single_character 4040 1.1 mrg (build_int_cst (integer_type_node, 1), 4041 1.1 mrg gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind), 4042 1.1 mrg se->expr), 4043 1.1 mrg (*expr)->ts.kind); 4044 1.1 mrg } 4045 1.1 mrg } 4046 1.1 mrg } 4047 1.1 mrg 4048 1.1 mrg /* Helper function for gfc_build_compare_string. Return LEN_TRIM value 4049 1.1 mrg if STR is a string literal, otherwise return -1. */ 4050 1.1 mrg 4051 1.1 mrg static int 4052 1.1 mrg gfc_optimize_len_trim (tree len, tree str, int kind) 4053 1.1 mrg { 4054 1.1 mrg if (kind == 1 4055 1.1 mrg && TREE_CODE (str) == ADDR_EXPR 4056 1.1 mrg && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF 4057 1.1 mrg && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST 4058 1.1 mrg && array_ref_low_bound (TREE_OPERAND (str, 0)) 4059 1.1 mrg == TREE_OPERAND (TREE_OPERAND (str, 0), 1) 4060 1.1 mrg && tree_fits_uhwi_p (len) 4061 1.1 mrg && tree_to_uhwi (len) >= 1 4062 1.1 mrg && tree_to_uhwi (len) 4063 1.1 mrg == (unsigned HOST_WIDE_INT) 4064 1.1 mrg TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0))) 4065 1.1 mrg { 4066 1.1 mrg tree folded = fold_convert (gfc_get_pchar_type (kind), str); 4067 1.1 mrg folded = build_fold_indirect_ref_loc (input_location, folded); 4068 1.1 mrg if (TREE_CODE (folded) == INTEGER_CST) 4069 1.1 mrg { 4070 1.1 mrg tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0); 4071 1.1 mrg int length = TREE_STRING_LENGTH (string_cst); 4072 1.1 mrg const char *ptr = TREE_STRING_POINTER (string_cst); 4073 1.1 mrg 4074 1.1 mrg for (; length > 0; length--) 4075 1.1 mrg if (ptr[length - 1] != ' ') 4076 1.1 mrg break; 4077 1.1 mrg 4078 1.1 mrg return length; 4079 1.1 mrg } 4080 1.1 mrg } 4081 1.1 mrg return -1; 4082 1.1 mrg } 4083 1.1 mrg 4084 1.1 mrg /* Helper to build a call to memcmp. */ 4085 1.1 mrg 4086 1.1 mrg static tree 4087 1.1 mrg build_memcmp_call (tree s1, tree s2, tree n) 4088 1.1 mrg { 4089 1.1 mrg tree tmp; 4090 1.1 mrg 4091 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (s1))) 4092 1.1 mrg s1 = gfc_build_addr_expr (pvoid_type_node, s1); 4093 1.1 mrg else 4094 1.1 mrg s1 = fold_convert (pvoid_type_node, s1); 4095 1.1 mrg 4096 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (s2))) 4097 1.1 mrg s2 = gfc_build_addr_expr (pvoid_type_node, s2); 4098 1.1 mrg else 4099 1.1 mrg s2 = fold_convert (pvoid_type_node, s2); 4100 1.1 mrg 4101 1.1 mrg n = fold_convert (size_type_node, n); 4102 1.1 mrg 4103 1.1 mrg tmp = build_call_expr_loc (input_location, 4104 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMCMP), 4105 1.1 mrg 3, s1, s2, n); 4106 1.1 mrg 4107 1.1 mrg return fold_convert (integer_type_node, tmp); 4108 1.1 mrg } 4109 1.1 mrg 4110 1.1 mrg /* Compare two strings. If they are all single characters, the result is the 4111 1.1 mrg subtraction of them. Otherwise, we build a library call. */ 4112 1.1 mrg 4113 1.1 mrg tree 4114 1.1 mrg gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind, 4115 1.1 mrg enum tree_code code) 4116 1.1 mrg { 4117 1.1 mrg tree sc1; 4118 1.1 mrg tree sc2; 4119 1.1 mrg tree fndecl; 4120 1.1 mrg 4121 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1))); 4122 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2))); 4123 1.1 mrg 4124 1.1 mrg sc1 = gfc_string_to_single_character (len1, str1, kind); 4125 1.1 mrg sc2 = gfc_string_to_single_character (len2, str2, kind); 4126 1.1 mrg 4127 1.1 mrg if (sc1 != NULL_TREE && sc2 != NULL_TREE) 4128 1.1 mrg { 4129 1.1 mrg /* Deal with single character specially. */ 4130 1.1 mrg sc1 = fold_convert (integer_type_node, sc1); 4131 1.1 mrg sc2 = fold_convert (integer_type_node, sc2); 4132 1.1 mrg return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node, 4133 1.1 mrg sc1, sc2); 4134 1.1 mrg } 4135 1.1 mrg 4136 1.1 mrg if ((code == EQ_EXPR || code == NE_EXPR) 4137 1.1 mrg && optimize 4138 1.1 mrg && INTEGER_CST_P (len1) && INTEGER_CST_P (len2)) 4139 1.1 mrg { 4140 1.1 mrg /* If one string is a string literal with LEN_TRIM longer 4141 1.1 mrg than the length of the second string, the strings 4142 1.1 mrg compare unequal. */ 4143 1.1 mrg int len = gfc_optimize_len_trim (len1, str1, kind); 4144 1.1 mrg if (len > 0 && compare_tree_int (len2, len) < 0) 4145 1.1 mrg return integer_one_node; 4146 1.1 mrg len = gfc_optimize_len_trim (len2, str2, kind); 4147 1.1 mrg if (len > 0 && compare_tree_int (len1, len) < 0) 4148 1.1 mrg return integer_one_node; 4149 1.1 mrg } 4150 1.1 mrg 4151 1.1 mrg /* We can compare via memcpy if the strings are known to be equal 4152 1.1 mrg in length and they are 4153 1.1 mrg - kind=1 4154 1.1 mrg - kind=4 and the comparison is for (in)equality. */ 4155 1.1 mrg 4156 1.1 mrg if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2) 4157 1.1 mrg && tree_int_cst_equal (len1, len2) 4158 1.1 mrg && (kind == 1 || code == EQ_EXPR || code == NE_EXPR)) 4159 1.1 mrg { 4160 1.1 mrg tree tmp; 4161 1.1 mrg tree chartype; 4162 1.1 mrg 4163 1.1 mrg chartype = gfc_get_char_type (kind); 4164 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1), 4165 1.1 mrg fold_convert (TREE_TYPE(len1), 4166 1.1 mrg TYPE_SIZE_UNIT(chartype)), 4167 1.1 mrg len1); 4168 1.1 mrg return build_memcmp_call (str1, str2, tmp); 4169 1.1 mrg } 4170 1.1 mrg 4171 1.1 mrg /* Build a call for the comparison. */ 4172 1.1 mrg if (kind == 1) 4173 1.1 mrg fndecl = gfor_fndecl_compare_string; 4174 1.1 mrg else if (kind == 4) 4175 1.1 mrg fndecl = gfor_fndecl_compare_string_char4; 4176 1.1 mrg else 4177 1.1 mrg gcc_unreachable (); 4178 1.1 mrg 4179 1.1 mrg return build_call_expr_loc (input_location, fndecl, 4, 4180 1.1 mrg len1, str1, len2, str2); 4181 1.1 mrg } 4182 1.1 mrg 4183 1.1 mrg 4184 1.1 mrg /* Return the backend_decl for a procedure pointer component. */ 4185 1.1 mrg 4186 1.1 mrg static tree 4187 1.1 mrg get_proc_ptr_comp (gfc_expr *e) 4188 1.1 mrg { 4189 1.1 mrg gfc_se comp_se; 4190 1.1 mrg gfc_expr *e2; 4191 1.1 mrg expr_t old_type; 4192 1.1 mrg 4193 1.1 mrg gfc_init_se (&comp_se, NULL); 4194 1.1 mrg e2 = gfc_copy_expr (e); 4195 1.1 mrg /* We have to restore the expr type later so that gfc_free_expr frees 4196 1.1 mrg the exact same thing that was allocated. 4197 1.1 mrg TODO: This is ugly. */ 4198 1.1 mrg old_type = e2->expr_type; 4199 1.1 mrg e2->expr_type = EXPR_VARIABLE; 4200 1.1 mrg gfc_conv_expr (&comp_se, e2); 4201 1.1 mrg e2->expr_type = old_type; 4202 1.1 mrg gfc_free_expr (e2); 4203 1.1 mrg return build_fold_addr_expr_loc (input_location, comp_se.expr); 4204 1.1 mrg } 4205 1.1 mrg 4206 1.1 mrg 4207 1.1 mrg /* Convert a typebound function reference from a class object. */ 4208 1.1 mrg static void 4209 1.1 mrg conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr) 4210 1.1 mrg { 4211 1.1 mrg gfc_ref *ref; 4212 1.1 mrg tree var; 4213 1.1 mrg 4214 1.1 mrg if (!VAR_P (base_object)) 4215 1.1 mrg { 4216 1.1 mrg var = gfc_create_var (TREE_TYPE (base_object), NULL); 4217 1.1 mrg gfc_add_modify (&se->pre, var, base_object); 4218 1.1 mrg } 4219 1.1 mrg se->expr = gfc_class_vptr_get (base_object); 4220 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, se->expr); 4221 1.1 mrg ref = expr->ref; 4222 1.1 mrg while (ref && ref->next) 4223 1.1 mrg ref = ref->next; 4224 1.1 mrg gcc_assert (ref && ref->type == REF_COMPONENT); 4225 1.1 mrg if (ref->u.c.sym->attr.extension) 4226 1.1 mrg conv_parent_component_references (se, ref); 4227 1.1 mrg gfc_conv_component_ref (se, ref); 4228 1.1 mrg se->expr = build_fold_addr_expr_loc (input_location, se->expr); 4229 1.1 mrg } 4230 1.1 mrg 4231 1.1 mrg 4232 1.1 mrg static void 4233 1.1 mrg conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr, 4234 1.1 mrg gfc_actual_arglist *actual_args) 4235 1.1 mrg { 4236 1.1 mrg tree tmp; 4237 1.1 mrg 4238 1.1 mrg if (gfc_is_proc_ptr_comp (expr)) 4239 1.1 mrg tmp = get_proc_ptr_comp (expr); 4240 1.1 mrg else if (sym->attr.dummy) 4241 1.1 mrg { 4242 1.1 mrg tmp = gfc_get_symbol_decl (sym); 4243 1.1 mrg if (sym->attr.proc_pointer) 4244 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, 4245 1.1 mrg tmp); 4246 1.1 mrg gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE 4247 1.1 mrg && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE); 4248 1.1 mrg } 4249 1.1 mrg else 4250 1.1 mrg { 4251 1.1 mrg if (!sym->backend_decl) 4252 1.1 mrg sym->backend_decl = gfc_get_extern_function_decl (sym, actual_args); 4253 1.1 mrg 4254 1.1 mrg TREE_USED (sym->backend_decl) = 1; 4255 1.1 mrg 4256 1.1 mrg tmp = sym->backend_decl; 4257 1.1 mrg 4258 1.1 mrg if (sym->attr.cray_pointee) 4259 1.1 mrg { 4260 1.1 mrg /* TODO - make the cray pointee a pointer to a procedure, 4261 1.1 mrg assign the pointer to it and use it for the call. This 4262 1.1 mrg will do for now! */ 4263 1.1 mrg tmp = convert (build_pointer_type (TREE_TYPE (tmp)), 4264 1.1 mrg gfc_get_symbol_decl (sym->cp_pointer)); 4265 1.1 mrg tmp = gfc_evaluate_now (tmp, &se->pre); 4266 1.1 mrg } 4267 1.1 mrg 4268 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp))) 4269 1.1 mrg { 4270 1.1 mrg gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL); 4271 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp); 4272 1.1 mrg } 4273 1.1 mrg } 4274 1.1 mrg se->expr = tmp; 4275 1.1 mrg } 4276 1.1 mrg 4277 1.1 mrg 4278 1.1 mrg /* Initialize MAPPING. */ 4279 1.1 mrg 4280 1.1 mrg void 4281 1.1 mrg gfc_init_interface_mapping (gfc_interface_mapping * mapping) 4282 1.1 mrg { 4283 1.1 mrg mapping->syms = NULL; 4284 1.1 mrg mapping->charlens = NULL; 4285 1.1 mrg } 4286 1.1 mrg 4287 1.1 mrg 4288 1.1 mrg /* Free all memory held by MAPPING (but not MAPPING itself). */ 4289 1.1 mrg 4290 1.1 mrg void 4291 1.1 mrg gfc_free_interface_mapping (gfc_interface_mapping * mapping) 4292 1.1 mrg { 4293 1.1 mrg gfc_interface_sym_mapping *sym; 4294 1.1 mrg gfc_interface_sym_mapping *nextsym; 4295 1.1 mrg gfc_charlen *cl; 4296 1.1 mrg gfc_charlen *nextcl; 4297 1.1 mrg 4298 1.1 mrg for (sym = mapping->syms; sym; sym = nextsym) 4299 1.1 mrg { 4300 1.1 mrg nextsym = sym->next; 4301 1.1 mrg sym->new_sym->n.sym->formal = NULL; 4302 1.1 mrg gfc_free_symbol (sym->new_sym->n.sym); 4303 1.1 mrg gfc_free_expr (sym->expr); 4304 1.1 mrg free (sym->new_sym); 4305 1.1 mrg free (sym); 4306 1.1 mrg } 4307 1.1 mrg for (cl = mapping->charlens; cl; cl = nextcl) 4308 1.1 mrg { 4309 1.1 mrg nextcl = cl->next; 4310 1.1 mrg gfc_free_expr (cl->length); 4311 1.1 mrg free (cl); 4312 1.1 mrg } 4313 1.1 mrg } 4314 1.1 mrg 4315 1.1 mrg 4316 1.1 mrg /* Return a copy of gfc_charlen CL. Add the returned structure to 4317 1.1 mrg MAPPING so that it will be freed by gfc_free_interface_mapping. */ 4318 1.1 mrg 4319 1.1 mrg static gfc_charlen * 4320 1.1 mrg gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping, 4321 1.1 mrg gfc_charlen * cl) 4322 1.1 mrg { 4323 1.1 mrg gfc_charlen *new_charlen; 4324 1.1 mrg 4325 1.1 mrg new_charlen = gfc_get_charlen (); 4326 1.1 mrg new_charlen->next = mapping->charlens; 4327 1.1 mrg new_charlen->length = gfc_copy_expr (cl->length); 4328 1.1 mrg 4329 1.1 mrg mapping->charlens = new_charlen; 4330 1.1 mrg return new_charlen; 4331 1.1 mrg } 4332 1.1 mrg 4333 1.1 mrg 4334 1.1 mrg /* A subroutine of gfc_add_interface_mapping. Return a descriptorless 4335 1.1 mrg array variable that can be used as the actual argument for dummy 4336 1.1 mrg argument SYM. Add any initialization code to BLOCK. PACKED is as 4337 1.1 mrg for gfc_get_nodesc_array_type and DATA points to the first element 4338 1.1 mrg in the passed array. */ 4339 1.1 mrg 4340 1.1 mrg static tree 4341 1.1 mrg gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym, 4342 1.1 mrg gfc_packed packed, tree data, tree len) 4343 1.1 mrg { 4344 1.1 mrg tree type; 4345 1.1 mrg tree var; 4346 1.1 mrg 4347 1.1 mrg if (len != NULL_TREE && (TREE_CONSTANT (len) || VAR_P (len))) 4348 1.1 mrg type = gfc_get_character_type_len (sym->ts.kind, len); 4349 1.1 mrg else 4350 1.1 mrg type = gfc_typenode_for_spec (&sym->ts); 4351 1.1 mrg type = gfc_get_nodesc_array_type (type, sym->as, packed, 4352 1.1 mrg !sym->attr.target && !sym->attr.pointer 4353 1.1 mrg && !sym->attr.proc_pointer); 4354 1.1 mrg 4355 1.1 mrg var = gfc_create_var (type, "ifm"); 4356 1.1 mrg gfc_add_modify (block, var, fold_convert (type, data)); 4357 1.1 mrg 4358 1.1 mrg return var; 4359 1.1 mrg } 4360 1.1 mrg 4361 1.1 mrg 4362 1.1 mrg /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds 4363 1.1 mrg and offset of descriptorless array type TYPE given that it has the same 4364 1.1 mrg size as DESC. Add any set-up code to BLOCK. */ 4365 1.1 mrg 4366 1.1 mrg static void 4367 1.1 mrg gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc) 4368 1.1 mrg { 4369 1.1 mrg int n; 4370 1.1 mrg tree dim; 4371 1.1 mrg tree offset; 4372 1.1 mrg tree tmp; 4373 1.1 mrg 4374 1.1 mrg offset = gfc_index_zero_node; 4375 1.1 mrg for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++) 4376 1.1 mrg { 4377 1.1 mrg dim = gfc_rank_cst[n]; 4378 1.1 mrg GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n); 4379 1.1 mrg if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE) 4380 1.1 mrg { 4381 1.1 mrg GFC_TYPE_ARRAY_LBOUND (type, n) 4382 1.1 mrg = gfc_conv_descriptor_lbound_get (desc, dim); 4383 1.1 mrg GFC_TYPE_ARRAY_UBOUND (type, n) 4384 1.1 mrg = gfc_conv_descriptor_ubound_get (desc, dim); 4385 1.1 mrg } 4386 1.1 mrg else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE) 4387 1.1 mrg { 4388 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, 4389 1.1 mrg gfc_array_index_type, 4390 1.1 mrg gfc_conv_descriptor_ubound_get (desc, dim), 4391 1.1 mrg gfc_conv_descriptor_lbound_get (desc, dim)); 4392 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, 4393 1.1 mrg gfc_array_index_type, 4394 1.1 mrg GFC_TYPE_ARRAY_LBOUND (type, n), tmp); 4395 1.1 mrg tmp = gfc_evaluate_now (tmp, block); 4396 1.1 mrg GFC_TYPE_ARRAY_UBOUND (type, n) = tmp; 4397 1.1 mrg } 4398 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, 4399 1.1 mrg GFC_TYPE_ARRAY_LBOUND (type, n), 4400 1.1 mrg GFC_TYPE_ARRAY_STRIDE (type, n)); 4401 1.1 mrg offset = fold_build2_loc (input_location, MINUS_EXPR, 4402 1.1 mrg gfc_array_index_type, offset, tmp); 4403 1.1 mrg } 4404 1.1 mrg offset = gfc_evaluate_now (offset, block); 4405 1.1 mrg GFC_TYPE_ARRAY_OFFSET (type) = offset; 4406 1.1 mrg } 4407 1.1 mrg 4408 1.1 mrg 4409 1.1 mrg /* Extend MAPPING so that it maps dummy argument SYM to the value stored 4410 1.1 mrg in SE. The caller may still use se->expr and se->string_length after 4411 1.1 mrg calling this function. */ 4412 1.1 mrg 4413 1.1 mrg void 4414 1.1 mrg gfc_add_interface_mapping (gfc_interface_mapping * mapping, 4415 1.1 mrg gfc_symbol * sym, gfc_se * se, 4416 1.1 mrg gfc_expr *expr) 4417 1.1 mrg { 4418 1.1 mrg gfc_interface_sym_mapping *sm; 4419 1.1 mrg tree desc; 4420 1.1 mrg tree tmp; 4421 1.1 mrg tree value; 4422 1.1 mrg gfc_symbol *new_sym; 4423 1.1 mrg gfc_symtree *root; 4424 1.1 mrg gfc_symtree *new_symtree; 4425 1.1 mrg 4426 1.1 mrg /* Create a new symbol to represent the actual argument. */ 4427 1.1 mrg new_sym = gfc_new_symbol (sym->name, NULL); 4428 1.1 mrg new_sym->ts = sym->ts; 4429 1.1 mrg new_sym->as = gfc_copy_array_spec (sym->as); 4430 1.1 mrg new_sym->attr.referenced = 1; 4431 1.1 mrg new_sym->attr.dimension = sym->attr.dimension; 4432 1.1 mrg new_sym->attr.contiguous = sym->attr.contiguous; 4433 1.1 mrg new_sym->attr.codimension = sym->attr.codimension; 4434 1.1 mrg new_sym->attr.pointer = sym->attr.pointer; 4435 1.1 mrg new_sym->attr.allocatable = sym->attr.allocatable; 4436 1.1 mrg new_sym->attr.flavor = sym->attr.flavor; 4437 1.1 mrg new_sym->attr.function = sym->attr.function; 4438 1.1 mrg 4439 1.1 mrg /* Ensure that the interface is available and that 4440 1.1 mrg descriptors are passed for array actual arguments. */ 4441 1.1 mrg if (sym->attr.flavor == FL_PROCEDURE) 4442 1.1 mrg { 4443 1.1 mrg new_sym->formal = expr->symtree->n.sym->formal; 4444 1.1 mrg new_sym->attr.always_explicit 4445 1.1 mrg = expr->symtree->n.sym->attr.always_explicit; 4446 1.1 mrg } 4447 1.1 mrg 4448 1.1 mrg /* Create a fake symtree for it. */ 4449 1.1 mrg root = NULL; 4450 1.1 mrg new_symtree = gfc_new_symtree (&root, sym->name); 4451 1.1 mrg new_symtree->n.sym = new_sym; 4452 1.1 mrg gcc_assert (new_symtree == root); 4453 1.1 mrg 4454 1.1 mrg /* Create a dummy->actual mapping. */ 4455 1.1 mrg sm = XCNEW (gfc_interface_sym_mapping); 4456 1.1 mrg sm->next = mapping->syms; 4457 1.1 mrg sm->old = sym; 4458 1.1 mrg sm->new_sym = new_symtree; 4459 1.1 mrg sm->expr = gfc_copy_expr (expr); 4460 1.1 mrg mapping->syms = sm; 4461 1.1 mrg 4462 1.1 mrg /* Stabilize the argument's value. */ 4463 1.1 mrg if (!sym->attr.function && se) 4464 1.1 mrg se->expr = gfc_evaluate_now (se->expr, &se->pre); 4465 1.1 mrg 4466 1.1 mrg if (sym->ts.type == BT_CHARACTER) 4467 1.1 mrg { 4468 1.1 mrg /* Create a copy of the dummy argument's length. */ 4469 1.1 mrg new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl); 4470 1.1 mrg sm->expr->ts.u.cl = new_sym->ts.u.cl; 4471 1.1 mrg 4472 1.1 mrg /* If the length is specified as "*", record the length that 4473 1.1 mrg the caller is passing. We should use the callee's length 4474 1.1 mrg in all other cases. */ 4475 1.1 mrg if (!new_sym->ts.u.cl->length && se) 4476 1.1 mrg { 4477 1.1 mrg se->string_length = gfc_evaluate_now (se->string_length, &se->pre); 4478 1.1 mrg new_sym->ts.u.cl->backend_decl = se->string_length; 4479 1.1 mrg } 4480 1.1 mrg } 4481 1.1 mrg 4482 1.1 mrg if (!se) 4483 1.1 mrg return; 4484 1.1 mrg 4485 1.1 mrg /* Use the passed value as-is if the argument is a function. */ 4486 1.1 mrg if (sym->attr.flavor == FL_PROCEDURE) 4487 1.1 mrg value = se->expr; 4488 1.1 mrg 4489 1.1 mrg /* If the argument is a pass-by-value scalar, use the value as is. */ 4490 1.1 mrg else if (!sym->attr.dimension && sym->attr.value) 4491 1.1 mrg value = se->expr; 4492 1.1 mrg 4493 1.1 mrg /* If the argument is either a string or a pointer to a string, 4494 1.1 mrg convert it to a boundless character type. */ 4495 1.1 mrg else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER) 4496 1.1 mrg { 4497 1.1 mrg se->string_length = gfc_evaluate_now (se->string_length, &se->pre); 4498 1.1 mrg tmp = gfc_get_character_type_len (sym->ts.kind, se->string_length); 4499 1.1 mrg tmp = build_pointer_type (tmp); 4500 1.1 mrg if (sym->attr.pointer) 4501 1.1 mrg value = build_fold_indirect_ref_loc (input_location, 4502 1.1 mrg se->expr); 4503 1.1 mrg else 4504 1.1 mrg value = se->expr; 4505 1.1 mrg value = fold_convert (tmp, value); 4506 1.1 mrg } 4507 1.1 mrg 4508 1.1 mrg /* If the argument is a scalar, a pointer to an array or an allocatable, 4509 1.1 mrg dereference it. */ 4510 1.1 mrg else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable) 4511 1.1 mrg value = build_fold_indirect_ref_loc (input_location, 4512 1.1 mrg se->expr); 4513 1.1 mrg 4514 1.1 mrg /* For character(*), use the actual argument's descriptor. */ 4515 1.1 mrg else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length) 4516 1.1 mrg value = build_fold_indirect_ref_loc (input_location, 4517 1.1 mrg se->expr); 4518 1.1 mrg 4519 1.1 mrg /* If the argument is an array descriptor, use it to determine 4520 1.1 mrg information about the actual argument's shape. */ 4521 1.1 mrg else if (POINTER_TYPE_P (TREE_TYPE (se->expr)) 4522 1.1 mrg && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr)))) 4523 1.1 mrg { 4524 1.1 mrg /* Get the actual argument's descriptor. */ 4525 1.1 mrg desc = build_fold_indirect_ref_loc (input_location, 4526 1.1 mrg se->expr); 4527 1.1 mrg 4528 1.1 mrg /* Create the replacement variable. */ 4529 1.1 mrg tmp = gfc_conv_descriptor_data_get (desc); 4530 1.1 mrg value = gfc_get_interface_mapping_array (&se->pre, sym, 4531 1.1 mrg PACKED_NO, tmp, 4532 1.1 mrg se->string_length); 4533 1.1 mrg 4534 1.1 mrg /* Use DESC to work out the upper bounds, strides and offset. */ 4535 1.1 mrg gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc); 4536 1.1 mrg } 4537 1.1 mrg else 4538 1.1 mrg /* Otherwise we have a packed array. */ 4539 1.1 mrg value = gfc_get_interface_mapping_array (&se->pre, sym, 4540 1.1 mrg PACKED_FULL, se->expr, 4541 1.1 mrg se->string_length); 4542 1.1 mrg 4543 1.1 mrg new_sym->backend_decl = value; 4544 1.1 mrg } 4545 1.1 mrg 4546 1.1 mrg 4547 1.1 mrg /* Called once all dummy argument mappings have been added to MAPPING, 4548 1.1 mrg but before the mapping is used to evaluate expressions. Pre-evaluate 4549 1.1 mrg the length of each argument, adding any initialization code to PRE and 4550 1.1 mrg any finalization code to POST. */ 4551 1.1 mrg 4552 1.1 mrg static void 4553 1.1 mrg gfc_finish_interface_mapping (gfc_interface_mapping * mapping, 4554 1.1 mrg stmtblock_t * pre, stmtblock_t * post) 4555 1.1 mrg { 4556 1.1 mrg gfc_interface_sym_mapping *sym; 4557 1.1 mrg gfc_expr *expr; 4558 1.1 mrg gfc_se se; 4559 1.1 mrg 4560 1.1 mrg for (sym = mapping->syms; sym; sym = sym->next) 4561 1.1 mrg if (sym->new_sym->n.sym->ts.type == BT_CHARACTER 4562 1.1 mrg && !sym->new_sym->n.sym->ts.u.cl->backend_decl) 4563 1.1 mrg { 4564 1.1 mrg expr = sym->new_sym->n.sym->ts.u.cl->length; 4565 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, expr); 4566 1.1 mrg gfc_init_se (&se, NULL); 4567 1.1 mrg gfc_conv_expr (&se, expr); 4568 1.1 mrg se.expr = fold_convert (gfc_charlen_type_node, se.expr); 4569 1.1 mrg se.expr = gfc_evaluate_now (se.expr, &se.pre); 4570 1.1 mrg gfc_add_block_to_block (pre, &se.pre); 4571 1.1 mrg gfc_add_block_to_block (post, &se.post); 4572 1.1 mrg 4573 1.1 mrg sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr; 4574 1.1 mrg } 4575 1.1 mrg } 4576 1.1 mrg 4577 1.1 mrg 4578 1.1 mrg /* Like gfc_apply_interface_mapping_to_expr, but applied to 4579 1.1 mrg constructor C. */ 4580 1.1 mrg 4581 1.1 mrg static void 4582 1.1 mrg gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping, 4583 1.1 mrg gfc_constructor_base base) 4584 1.1 mrg { 4585 1.1 mrg gfc_constructor *c; 4586 1.1 mrg for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c)) 4587 1.1 mrg { 4588 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, c->expr); 4589 1.1 mrg if (c->iterator) 4590 1.1 mrg { 4591 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start); 4592 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end); 4593 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step); 4594 1.1 mrg } 4595 1.1 mrg } 4596 1.1 mrg } 4597 1.1 mrg 4598 1.1 mrg 4599 1.1 mrg /* Like gfc_apply_interface_mapping_to_expr, but applied to 4600 1.1 mrg reference REF. */ 4601 1.1 mrg 4602 1.1 mrg static void 4603 1.1 mrg gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping, 4604 1.1 mrg gfc_ref * ref) 4605 1.1 mrg { 4606 1.1 mrg int n; 4607 1.1 mrg 4608 1.1 mrg for (; ref; ref = ref->next) 4609 1.1 mrg switch (ref->type) 4610 1.1 mrg { 4611 1.1 mrg case REF_ARRAY: 4612 1.1 mrg for (n = 0; n < ref->u.ar.dimen; n++) 4613 1.1 mrg { 4614 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]); 4615 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]); 4616 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]); 4617 1.1 mrg } 4618 1.1 mrg break; 4619 1.1 mrg 4620 1.1 mrg case REF_COMPONENT: 4621 1.1 mrg case REF_INQUIRY: 4622 1.1 mrg break; 4623 1.1 mrg 4624 1.1 mrg case REF_SUBSTRING: 4625 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start); 4626 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end); 4627 1.1 mrg break; 4628 1.1 mrg } 4629 1.1 mrg } 4630 1.1 mrg 4631 1.1 mrg 4632 1.1 mrg /* Convert intrinsic function calls into result expressions. */ 4633 1.1 mrg 4634 1.1 mrg static bool 4635 1.1 mrg gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping) 4636 1.1 mrg { 4637 1.1 mrg gfc_symbol *sym; 4638 1.1 mrg gfc_expr *new_expr; 4639 1.1 mrg gfc_expr *arg1; 4640 1.1 mrg gfc_expr *arg2; 4641 1.1 mrg int d, dup; 4642 1.1 mrg 4643 1.1 mrg arg1 = expr->value.function.actual->expr; 4644 1.1 mrg if (expr->value.function.actual->next) 4645 1.1 mrg arg2 = expr->value.function.actual->next->expr; 4646 1.1 mrg else 4647 1.1 mrg arg2 = NULL; 4648 1.1 mrg 4649 1.1 mrg sym = arg1->symtree->n.sym; 4650 1.1 mrg 4651 1.1 mrg if (sym->attr.dummy) 4652 1.1 mrg return false; 4653 1.1 mrg 4654 1.1 mrg new_expr = NULL; 4655 1.1 mrg 4656 1.1 mrg switch (expr->value.function.isym->id) 4657 1.1 mrg { 4658 1.1 mrg case GFC_ISYM_LEN: 4659 1.1 mrg /* TODO figure out why this condition is necessary. */ 4660 1.1 mrg if (sym->attr.function 4661 1.1 mrg && (arg1->ts.u.cl->length == NULL 4662 1.1 mrg || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT 4663 1.1 mrg && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE))) 4664 1.1 mrg return false; 4665 1.1 mrg 4666 1.1 mrg new_expr = gfc_copy_expr (arg1->ts.u.cl->length); 4667 1.1 mrg break; 4668 1.1 mrg 4669 1.1 mrg case GFC_ISYM_LEN_TRIM: 4670 1.1 mrg new_expr = gfc_copy_expr (arg1); 4671 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, new_expr); 4672 1.1 mrg 4673 1.1 mrg if (!new_expr) 4674 1.1 mrg return false; 4675 1.1 mrg 4676 1.1 mrg gfc_replace_expr (arg1, new_expr); 4677 1.1 mrg return true; 4678 1.1 mrg 4679 1.1 mrg case GFC_ISYM_SIZE: 4680 1.1 mrg if (!sym->as || sym->as->rank == 0) 4681 1.1 mrg return false; 4682 1.1 mrg 4683 1.1 mrg if (arg2 && arg2->expr_type == EXPR_CONSTANT) 4684 1.1 mrg { 4685 1.1 mrg dup = mpz_get_si (arg2->value.integer); 4686 1.1 mrg d = dup - 1; 4687 1.1 mrg } 4688 1.1 mrg else 4689 1.1 mrg { 4690 1.1 mrg dup = sym->as->rank; 4691 1.1 mrg d = 0; 4692 1.1 mrg } 4693 1.1 mrg 4694 1.1 mrg for (; d < dup; d++) 4695 1.1 mrg { 4696 1.1 mrg gfc_expr *tmp; 4697 1.1 mrg 4698 1.1 mrg if (!sym->as->upper[d] || !sym->as->lower[d]) 4699 1.1 mrg { 4700 1.1 mrg gfc_free_expr (new_expr); 4701 1.1 mrg return false; 4702 1.1 mrg } 4703 1.1 mrg 4704 1.1 mrg tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]), 4705 1.1 mrg gfc_get_int_expr (gfc_default_integer_kind, 4706 1.1 mrg NULL, 1)); 4707 1.1 mrg tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d])); 4708 1.1 mrg if (new_expr) 4709 1.1 mrg new_expr = gfc_multiply (new_expr, tmp); 4710 1.1 mrg else 4711 1.1 mrg new_expr = tmp; 4712 1.1 mrg } 4713 1.1 mrg break; 4714 1.1 mrg 4715 1.1 mrg case GFC_ISYM_LBOUND: 4716 1.1 mrg case GFC_ISYM_UBOUND: 4717 1.1 mrg /* TODO These implementations of lbound and ubound do not limit if 4718 1.1 mrg the size < 0, according to F95's 13.14.53 and 13.14.113. */ 4719 1.1 mrg 4720 1.1 mrg if (!sym->as || sym->as->rank == 0) 4721 1.1 mrg return false; 4722 1.1 mrg 4723 1.1 mrg if (arg2 && arg2->expr_type == EXPR_CONSTANT) 4724 1.1 mrg d = mpz_get_si (arg2->value.integer) - 1; 4725 1.1 mrg else 4726 1.1 mrg return false; 4727 1.1 mrg 4728 1.1 mrg if (expr->value.function.isym->id == GFC_ISYM_LBOUND) 4729 1.1 mrg { 4730 1.1 mrg if (sym->as->lower[d]) 4731 1.1 mrg new_expr = gfc_copy_expr (sym->as->lower[d]); 4732 1.1 mrg } 4733 1.1 mrg else 4734 1.1 mrg { 4735 1.1 mrg if (sym->as->upper[d]) 4736 1.1 mrg new_expr = gfc_copy_expr (sym->as->upper[d]); 4737 1.1 mrg } 4738 1.1 mrg break; 4739 1.1 mrg 4740 1.1 mrg default: 4741 1.1 mrg break; 4742 1.1 mrg } 4743 1.1 mrg 4744 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, new_expr); 4745 1.1 mrg if (!new_expr) 4746 1.1 mrg return false; 4747 1.1 mrg 4748 1.1 mrg gfc_replace_expr (expr, new_expr); 4749 1.1 mrg return true; 4750 1.1 mrg } 4751 1.1 mrg 4752 1.1 mrg 4753 1.1 mrg static void 4754 1.1 mrg gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr, 4755 1.1 mrg gfc_interface_mapping * mapping) 4756 1.1 mrg { 4757 1.1 mrg gfc_formal_arglist *f; 4758 1.1 mrg gfc_actual_arglist *actual; 4759 1.1 mrg 4760 1.1 mrg actual = expr->value.function.actual; 4761 1.1 mrg f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym); 4762 1.1 mrg 4763 1.1 mrg for (; f && actual; f = f->next, actual = actual->next) 4764 1.1 mrg { 4765 1.1 mrg if (!actual->expr) 4766 1.1 mrg continue; 4767 1.1 mrg 4768 1.1 mrg gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr); 4769 1.1 mrg } 4770 1.1 mrg 4771 1.1 mrg if (map_expr->symtree->n.sym->attr.dimension) 4772 1.1 mrg { 4773 1.1 mrg int d; 4774 1.1 mrg gfc_array_spec *as; 4775 1.1 mrg 4776 1.1 mrg as = gfc_copy_array_spec (map_expr->symtree->n.sym->as); 4777 1.1 mrg 4778 1.1 mrg for (d = 0; d < as->rank; d++) 4779 1.1 mrg { 4780 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]); 4781 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]); 4782 1.1 mrg } 4783 1.1 mrg 4784 1.1 mrg expr->value.function.esym->as = as; 4785 1.1 mrg } 4786 1.1 mrg 4787 1.1 mrg if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER) 4788 1.1 mrg { 4789 1.1 mrg expr->value.function.esym->ts.u.cl->length 4790 1.1 mrg = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length); 4791 1.1 mrg 4792 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, 4793 1.1 mrg expr->value.function.esym->ts.u.cl->length); 4794 1.1 mrg } 4795 1.1 mrg } 4796 1.1 mrg 4797 1.1 mrg 4798 1.1 mrg /* EXPR is a copy of an expression that appeared in the interface 4799 1.1 mrg associated with MAPPING. Walk it recursively looking for references to 4800 1.1 mrg dummy arguments that MAPPING maps to actual arguments. Replace each such 4801 1.1 mrg reference with a reference to the associated actual argument. */ 4802 1.1 mrg 4803 1.1 mrg static void 4804 1.1 mrg gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping, 4805 1.1 mrg gfc_expr * expr) 4806 1.1 mrg { 4807 1.1 mrg gfc_interface_sym_mapping *sym; 4808 1.1 mrg gfc_actual_arglist *actual; 4809 1.1 mrg 4810 1.1 mrg if (!expr) 4811 1.1 mrg return; 4812 1.1 mrg 4813 1.1 mrg /* Copying an expression does not copy its length, so do that here. */ 4814 1.1 mrg if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl) 4815 1.1 mrg { 4816 1.1 mrg expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl); 4817 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length); 4818 1.1 mrg } 4819 1.1 mrg 4820 1.1 mrg /* Apply the mapping to any references. */ 4821 1.1 mrg gfc_apply_interface_mapping_to_ref (mapping, expr->ref); 4822 1.1 mrg 4823 1.1 mrg /* ...and to the expression's symbol, if it has one. */ 4824 1.1 mrg /* TODO Find out why the condition on expr->symtree had to be moved into 4825 1.1 mrg the loop rather than being outside it, as originally. */ 4826 1.1 mrg for (sym = mapping->syms; sym; sym = sym->next) 4827 1.1 mrg if (expr->symtree && sym->old == expr->symtree->n.sym) 4828 1.1 mrg { 4829 1.1 mrg if (sym->new_sym->n.sym->backend_decl) 4830 1.1 mrg expr->symtree = sym->new_sym; 4831 1.1 mrg else if (sym->expr) 4832 1.1 mrg gfc_replace_expr (expr, gfc_copy_expr (sym->expr)); 4833 1.1 mrg } 4834 1.1 mrg 4835 1.1 mrg /* ...and to subexpressions in expr->value. */ 4836 1.1 mrg switch (expr->expr_type) 4837 1.1 mrg { 4838 1.1 mrg case EXPR_VARIABLE: 4839 1.1 mrg case EXPR_CONSTANT: 4840 1.1 mrg case EXPR_NULL: 4841 1.1 mrg case EXPR_SUBSTRING: 4842 1.1 mrg break; 4843 1.1 mrg 4844 1.1 mrg case EXPR_OP: 4845 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1); 4846 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2); 4847 1.1 mrg break; 4848 1.1 mrg 4849 1.1 mrg case EXPR_FUNCTION: 4850 1.1 mrg for (actual = expr->value.function.actual; actual; actual = actual->next) 4851 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, actual->expr); 4852 1.1 mrg 4853 1.1 mrg if (expr->value.function.esym == NULL 4854 1.1 mrg && expr->value.function.isym != NULL 4855 1.1 mrg && expr->value.function.actual 4856 1.1 mrg && expr->value.function.actual->expr 4857 1.1 mrg && expr->value.function.actual->expr->symtree 4858 1.1 mrg && gfc_map_intrinsic_function (expr, mapping)) 4859 1.1 mrg break; 4860 1.1 mrg 4861 1.1 mrg for (sym = mapping->syms; sym; sym = sym->next) 4862 1.1 mrg if (sym->old == expr->value.function.esym) 4863 1.1 mrg { 4864 1.1 mrg expr->value.function.esym = sym->new_sym->n.sym; 4865 1.1 mrg gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping); 4866 1.1 mrg expr->value.function.esym->result = sym->new_sym->n.sym; 4867 1.1 mrg } 4868 1.1 mrg break; 4869 1.1 mrg 4870 1.1 mrg case EXPR_ARRAY: 4871 1.1 mrg case EXPR_STRUCTURE: 4872 1.1 mrg gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor); 4873 1.1 mrg break; 4874 1.1 mrg 4875 1.1 mrg case EXPR_COMPCALL: 4876 1.1 mrg case EXPR_PPC: 4877 1.1 mrg case EXPR_UNKNOWN: 4878 1.1 mrg gcc_unreachable (); 4879 1.1 mrg break; 4880 1.1 mrg } 4881 1.1 mrg 4882 1.1 mrg return; 4883 1.1 mrg } 4884 1.1 mrg 4885 1.1 mrg 4886 1.1 mrg /* Evaluate interface expression EXPR using MAPPING. Store the result 4887 1.1 mrg in SE. */ 4888 1.1 mrg 4889 1.1 mrg void 4890 1.1 mrg gfc_apply_interface_mapping (gfc_interface_mapping * mapping, 4891 1.1 mrg gfc_se * se, gfc_expr * expr) 4892 1.1 mrg { 4893 1.1 mrg expr = gfc_copy_expr (expr); 4894 1.1 mrg gfc_apply_interface_mapping_to_expr (mapping, expr); 4895 1.1 mrg gfc_conv_expr (se, expr); 4896 1.1 mrg se->expr = gfc_evaluate_now (se->expr, &se->pre); 4897 1.1 mrg gfc_free_expr (expr); 4898 1.1 mrg } 4899 1.1 mrg 4900 1.1 mrg 4901 1.1 mrg /* Returns a reference to a temporary array into which a component of 4902 1.1 mrg an actual argument derived type array is copied and then returned 4903 1.1 mrg after the function call. */ 4904 1.1 mrg void 4905 1.1 mrg gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, int g77, 4906 1.1 mrg sym_intent intent, bool formal_ptr, 4907 1.1 mrg const gfc_symbol *fsym, const char *proc_name, 4908 1.1 mrg gfc_symbol *sym, bool check_contiguous) 4909 1.1 mrg { 4910 1.1 mrg gfc_se lse; 4911 1.1 mrg gfc_se rse; 4912 1.1 mrg gfc_ss *lss; 4913 1.1 mrg gfc_ss *rss; 4914 1.1 mrg gfc_loopinfo loop; 4915 1.1 mrg gfc_loopinfo loop2; 4916 1.1 mrg gfc_array_info *info; 4917 1.1 mrg tree offset; 4918 1.1 mrg tree tmp_index; 4919 1.1 mrg tree tmp; 4920 1.1 mrg tree base_type; 4921 1.1 mrg tree size; 4922 1.1 mrg stmtblock_t body; 4923 1.1 mrg int n; 4924 1.1 mrg int dimen; 4925 1.1 mrg gfc_se work_se; 4926 1.1 mrg gfc_se *parmse; 4927 1.1 mrg bool pass_optional; 4928 1.1 mrg 4929 1.1 mrg pass_optional = fsym && fsym->attr.optional && sym && sym->attr.optional; 4930 1.1 mrg 4931 1.1 mrg if (pass_optional || check_contiguous) 4932 1.1 mrg { 4933 1.1 mrg gfc_init_se (&work_se, NULL); 4934 1.1 mrg parmse = &work_se; 4935 1.1 mrg } 4936 1.1 mrg else 4937 1.1 mrg parmse = se; 4938 1.1 mrg 4939 1.1 mrg if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS) 4940 1.1 mrg { 4941 1.1 mrg /* We will create a temporary array, so let us warn. */ 4942 1.1 mrg char * msg; 4943 1.1 mrg 4944 1.1 mrg if (fsym && proc_name) 4945 1.1 mrg msg = xasprintf ("An array temporary was created for argument " 4946 1.1 mrg "'%s' of procedure '%s'", fsym->name, proc_name); 4947 1.1 mrg else 4948 1.1 mrg msg = xasprintf ("An array temporary was created"); 4949 1.1 mrg 4950 1.1 mrg tmp = build_int_cst (logical_type_node, 1); 4951 1.1 mrg gfc_trans_runtime_check (false, true, tmp, &parmse->pre, 4952 1.1 mrg &expr->where, msg); 4953 1.1 mrg free (msg); 4954 1.1 mrg } 4955 1.1 mrg 4956 1.1 mrg gfc_init_se (&lse, NULL); 4957 1.1 mrg gfc_init_se (&rse, NULL); 4958 1.1 mrg 4959 1.1 mrg /* Walk the argument expression. */ 4960 1.1 mrg rss = gfc_walk_expr (expr); 4961 1.1 mrg 4962 1.1 mrg gcc_assert (rss != gfc_ss_terminator); 4963 1.1 mrg 4964 1.1 mrg /* Initialize the scalarizer. */ 4965 1.1 mrg gfc_init_loopinfo (&loop); 4966 1.1 mrg gfc_add_ss_to_loop (&loop, rss); 4967 1.1 mrg 4968 1.1 mrg /* Calculate the bounds of the scalarization. */ 4969 1.1 mrg gfc_conv_ss_startstride (&loop); 4970 1.1 mrg 4971 1.1 mrg /* Build an ss for the temporary. */ 4972 1.1 mrg if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl) 4973 1.1 mrg gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre); 4974 1.1 mrg 4975 1.1 mrg base_type = gfc_typenode_for_spec (&expr->ts); 4976 1.1 mrg if (GFC_ARRAY_TYPE_P (base_type) 4977 1.1 mrg || GFC_DESCRIPTOR_TYPE_P (base_type)) 4978 1.1 mrg base_type = gfc_get_element_type (base_type); 4979 1.1 mrg 4980 1.1 mrg if (expr->ts.type == BT_CLASS) 4981 1.1 mrg base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts); 4982 1.1 mrg 4983 1.1 mrg loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER) 4984 1.1 mrg ? expr->ts.u.cl->backend_decl 4985 1.1 mrg : NULL), 4986 1.1 mrg loop.dimen); 4987 1.1 mrg 4988 1.1 mrg parmse->string_length = loop.temp_ss->info->string_length; 4989 1.1 mrg 4990 1.1 mrg /* Associate the SS with the loop. */ 4991 1.1 mrg gfc_add_ss_to_loop (&loop, loop.temp_ss); 4992 1.1 mrg 4993 1.1 mrg /* Setup the scalarizing loops. */ 4994 1.1 mrg gfc_conv_loop_setup (&loop, &expr->where); 4995 1.1 mrg 4996 1.1 mrg /* Pass the temporary descriptor back to the caller. */ 4997 1.1 mrg info = &loop.temp_ss->info->data.array; 4998 1.1 mrg parmse->expr = info->descriptor; 4999 1.1 mrg 5000 1.1 mrg /* Setup the gfc_se structures. */ 5001 1.1 mrg gfc_copy_loopinfo_to_se (&lse, &loop); 5002 1.1 mrg gfc_copy_loopinfo_to_se (&rse, &loop); 5003 1.1 mrg 5004 1.1 mrg rse.ss = rss; 5005 1.1 mrg lse.ss = loop.temp_ss; 5006 1.1 mrg gfc_mark_ss_chain_used (rss, 1); 5007 1.1 mrg gfc_mark_ss_chain_used (loop.temp_ss, 1); 5008 1.1 mrg 5009 1.1 mrg /* Start the scalarized loop body. */ 5010 1.1 mrg gfc_start_scalarized_body (&loop, &body); 5011 1.1 mrg 5012 1.1 mrg /* Translate the expression. */ 5013 1.1 mrg gfc_conv_expr (&rse, expr); 5014 1.1 mrg 5015 1.1 mrg /* Reset the offset for the function call since the loop 5016 1.1 mrg is zero based on the data pointer. Note that the temp 5017 1.1 mrg comes first in the loop chain since it is added second. */ 5018 1.1 mrg if (gfc_is_class_array_function (expr)) 5019 1.1 mrg { 5020 1.1 mrg tmp = loop.ss->loop_chain->info->data.array.descriptor; 5021 1.1 mrg gfc_conv_descriptor_offset_set (&loop.pre, tmp, 5022 1.1 mrg gfc_index_zero_node); 5023 1.1 mrg } 5024 1.1 mrg 5025 1.1 mrg gfc_conv_tmp_array_ref (&lse); 5026 1.1 mrg 5027 1.1 mrg if (intent != INTENT_OUT) 5028 1.1 mrg { 5029 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false); 5030 1.1 mrg gfc_add_expr_to_block (&body, tmp); 5031 1.1 mrg gcc_assert (rse.ss == gfc_ss_terminator); 5032 1.1 mrg gfc_trans_scalarizing_loops (&loop, &body); 5033 1.1 mrg } 5034 1.1 mrg else 5035 1.1 mrg { 5036 1.1 mrg /* Make sure that the temporary declaration survives by merging 5037 1.1 mrg all the loop declarations into the current context. */ 5038 1.1 mrg for (n = 0; n < loop.dimen; n++) 5039 1.1 mrg { 5040 1.1 mrg gfc_merge_block_scope (&body); 5041 1.1 mrg body = loop.code[loop.order[n]]; 5042 1.1 mrg } 5043 1.1 mrg gfc_merge_block_scope (&body); 5044 1.1 mrg } 5045 1.1 mrg 5046 1.1 mrg /* Add the post block after the second loop, so that any 5047 1.1 mrg freeing of allocated memory is done at the right time. */ 5048 1.1 mrg gfc_add_block_to_block (&parmse->pre, &loop.pre); 5049 1.1 mrg 5050 1.1 mrg /**********Copy the temporary back again.*********/ 5051 1.1 mrg 5052 1.1 mrg gfc_init_se (&lse, NULL); 5053 1.1 mrg gfc_init_se (&rse, NULL); 5054 1.1 mrg 5055 1.1 mrg /* Walk the argument expression. */ 5056 1.1 mrg lss = gfc_walk_expr (expr); 5057 1.1 mrg rse.ss = loop.temp_ss; 5058 1.1 mrg lse.ss = lss; 5059 1.1 mrg 5060 1.1 mrg /* Initialize the scalarizer. */ 5061 1.1 mrg gfc_init_loopinfo (&loop2); 5062 1.1 mrg gfc_add_ss_to_loop (&loop2, lss); 5063 1.1 mrg 5064 1.1 mrg dimen = rse.ss->dimen; 5065 1.1 mrg 5066 1.1 mrg /* Skip the write-out loop for this case. */ 5067 1.1 mrg if (gfc_is_class_array_function (expr)) 5068 1.1 mrg goto class_array_fcn; 5069 1.1 mrg 5070 1.1 mrg /* Calculate the bounds of the scalarization. */ 5071 1.1 mrg gfc_conv_ss_startstride (&loop2); 5072 1.1 mrg 5073 1.1 mrg /* Setup the scalarizing loops. */ 5074 1.1 mrg gfc_conv_loop_setup (&loop2, &expr->where); 5075 1.1 mrg 5076 1.1 mrg gfc_copy_loopinfo_to_se (&lse, &loop2); 5077 1.1 mrg gfc_copy_loopinfo_to_se (&rse, &loop2); 5078 1.1 mrg 5079 1.1 mrg gfc_mark_ss_chain_used (lss, 1); 5080 1.1 mrg gfc_mark_ss_chain_used (loop.temp_ss, 1); 5081 1.1 mrg 5082 1.1 mrg /* Declare the variable to hold the temporary offset and start the 5083 1.1 mrg scalarized loop body. */ 5084 1.1 mrg offset = gfc_create_var (gfc_array_index_type, NULL); 5085 1.1 mrg gfc_start_scalarized_body (&loop2, &body); 5086 1.1 mrg 5087 1.1 mrg /* Build the offsets for the temporary from the loop variables. The 5088 1.1 mrg temporary array has lbounds of zero and strides of one in all 5089 1.1 mrg dimensions, so this is very simple. The offset is only computed 5090 1.1 mrg outside the innermost loop, so the overall transfer could be 5091 1.1 mrg optimized further. */ 5092 1.1 mrg info = &rse.ss->info->data.array; 5093 1.1 mrg 5094 1.1 mrg tmp_index = gfc_index_zero_node; 5095 1.1 mrg for (n = dimen - 1; n > 0; n--) 5096 1.1 mrg { 5097 1.1 mrg tree tmp_str; 5098 1.1 mrg tmp = rse.loop->loopvar[n]; 5099 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, 5100 1.1 mrg tmp, rse.loop->from[n]); 5101 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, 5102 1.1 mrg tmp, tmp_index); 5103 1.1 mrg 5104 1.1 mrg tmp_str = fold_build2_loc (input_location, MINUS_EXPR, 5105 1.1 mrg gfc_array_index_type, 5106 1.1 mrg rse.loop->to[n-1], rse.loop->from[n-1]); 5107 1.1 mrg tmp_str = fold_build2_loc (input_location, PLUS_EXPR, 5108 1.1 mrg gfc_array_index_type, 5109 1.1 mrg tmp_str, gfc_index_one_node); 5110 1.1 mrg 5111 1.1 mrg tmp_index = fold_build2_loc (input_location, MULT_EXPR, 5112 1.1 mrg gfc_array_index_type, tmp, tmp_str); 5113 1.1 mrg } 5114 1.1 mrg 5115 1.1 mrg tmp_index = fold_build2_loc (input_location, MINUS_EXPR, 5116 1.1 mrg gfc_array_index_type, 5117 1.1 mrg tmp_index, rse.loop->from[0]); 5118 1.1 mrg gfc_add_modify (&rse.loop->code[0], offset, tmp_index); 5119 1.1 mrg 5120 1.1 mrg tmp_index = fold_build2_loc (input_location, PLUS_EXPR, 5121 1.1 mrg gfc_array_index_type, 5122 1.1 mrg rse.loop->loopvar[0], offset); 5123 1.1 mrg 5124 1.1 mrg /* Now use the offset for the reference. */ 5125 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, 5126 1.1 mrg info->data); 5127 1.1 mrg rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL); 5128 1.1 mrg 5129 1.1 mrg if (expr->ts.type == BT_CHARACTER) 5130 1.1 mrg rse.string_length = expr->ts.u.cl->backend_decl; 5131 1.1 mrg 5132 1.1 mrg gfc_conv_expr (&lse, expr); 5133 1.1 mrg 5134 1.1 mrg gcc_assert (lse.ss == gfc_ss_terminator); 5135 1.1 mrg 5136 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true); 5137 1.1 mrg gfc_add_expr_to_block (&body, tmp); 5138 1.1 mrg 5139 1.1 mrg /* Generate the copying loops. */ 5140 1.1 mrg gfc_trans_scalarizing_loops (&loop2, &body); 5141 1.1 mrg 5142 1.1 mrg /* Wrap the whole thing up by adding the second loop to the post-block 5143 1.1 mrg and following it by the post-block of the first loop. In this way, 5144 1.1 mrg if the temporary needs freeing, it is done after use! */ 5145 1.1 mrg if (intent != INTENT_IN) 5146 1.1 mrg { 5147 1.1 mrg gfc_add_block_to_block (&parmse->post, &loop2.pre); 5148 1.1 mrg gfc_add_block_to_block (&parmse->post, &loop2.post); 5149 1.1 mrg } 5150 1.1 mrg 5151 1.1 mrg class_array_fcn: 5152 1.1 mrg 5153 1.1 mrg gfc_add_block_to_block (&parmse->post, &loop.post); 5154 1.1 mrg 5155 1.1 mrg gfc_cleanup_loop (&loop); 5156 1.1 mrg gfc_cleanup_loop (&loop2); 5157 1.1 mrg 5158 1.1 mrg /* Pass the string length to the argument expression. */ 5159 1.1 mrg if (expr->ts.type == BT_CHARACTER) 5160 1.1 mrg parmse->string_length = expr->ts.u.cl->backend_decl; 5161 1.1 mrg 5162 1.1 mrg /* Determine the offset for pointer formal arguments and set the 5163 1.1 mrg lbounds to one. */ 5164 1.1 mrg if (formal_ptr) 5165 1.1 mrg { 5166 1.1 mrg size = gfc_index_one_node; 5167 1.1 mrg offset = gfc_index_zero_node; 5168 1.1 mrg for (n = 0; n < dimen; n++) 5169 1.1 mrg { 5170 1.1 mrg tmp = gfc_conv_descriptor_ubound_get (parmse->expr, 5171 1.1 mrg gfc_rank_cst[n]); 5172 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, 5173 1.1 mrg gfc_array_index_type, tmp, 5174 1.1 mrg gfc_index_one_node); 5175 1.1 mrg gfc_conv_descriptor_ubound_set (&parmse->pre, 5176 1.1 mrg parmse->expr, 5177 1.1 mrg gfc_rank_cst[n], 5178 1.1 mrg tmp); 5179 1.1 mrg gfc_conv_descriptor_lbound_set (&parmse->pre, 5180 1.1 mrg parmse->expr, 5181 1.1 mrg gfc_rank_cst[n], 5182 1.1 mrg gfc_index_one_node); 5183 1.1 mrg size = gfc_evaluate_now (size, &parmse->pre); 5184 1.1 mrg offset = fold_build2_loc (input_location, MINUS_EXPR, 5185 1.1 mrg gfc_array_index_type, 5186 1.1 mrg offset, size); 5187 1.1 mrg offset = gfc_evaluate_now (offset, &parmse->pre); 5188 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, 5189 1.1 mrg gfc_array_index_type, 5190 1.1 mrg rse.loop->to[n], rse.loop->from[n]); 5191 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, 5192 1.1 mrg gfc_array_index_type, 5193 1.1 mrg tmp, gfc_index_one_node); 5194 1.1 mrg size = fold_build2_loc (input_location, MULT_EXPR, 5195 1.1 mrg gfc_array_index_type, size, tmp); 5196 1.1 mrg } 5197 1.1 mrg 5198 1.1 mrg gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr, 5199 1.1 mrg offset); 5200 1.1 mrg } 5201 1.1 mrg 5202 1.1 mrg /* We want either the address for the data or the address of the descriptor, 5203 1.1 mrg depending on the mode of passing array arguments. */ 5204 1.1 mrg if (g77) 5205 1.1 mrg parmse->expr = gfc_conv_descriptor_data_get (parmse->expr); 5206 1.1 mrg else 5207 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr); 5208 1.1 mrg 5209 1.1 mrg /* Basically make this into 5210 1.1 mrg 5211 1.1 mrg if (present) 5212 1.1 mrg { 5213 1.1 mrg if (contiguous) 5214 1.1 mrg { 5215 1.1 mrg pointer = a; 5216 1.1 mrg } 5217 1.1 mrg else 5218 1.1 mrg { 5219 1.1 mrg parmse->pre(); 5220 1.1 mrg pointer = parmse->expr; 5221 1.1 mrg } 5222 1.1 mrg } 5223 1.1 mrg else 5224 1.1 mrg pointer = NULL; 5225 1.1 mrg 5226 1.1 mrg foo (pointer); 5227 1.1 mrg if (present && !contiguous) 5228 1.1 mrg se->post(); 5229 1.1 mrg 5230 1.1 mrg */ 5231 1.1 mrg 5232 1.1 mrg if (pass_optional || check_contiguous) 5233 1.1 mrg { 5234 1.1 mrg tree type; 5235 1.1 mrg stmtblock_t else_block; 5236 1.1 mrg tree pre_stmts, post_stmts; 5237 1.1 mrg tree pointer; 5238 1.1 mrg tree else_stmt; 5239 1.1 mrg tree present_var = NULL_TREE; 5240 1.1 mrg tree cont_var = NULL_TREE; 5241 1.1 mrg tree post_cond; 5242 1.1 mrg 5243 1.1 mrg type = TREE_TYPE (parmse->expr); 5244 1.1 mrg if (POINTER_TYPE_P (type) && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type))) 5245 1.1 mrg type = TREE_TYPE (type); 5246 1.1 mrg pointer = gfc_create_var (type, "arg_ptr"); 5247 1.1 mrg 5248 1.1 mrg if (check_contiguous) 5249 1.1 mrg { 5250 1.1 mrg gfc_se cont_se, array_se; 5251 1.1 mrg stmtblock_t if_block, else_block; 5252 1.1 mrg tree if_stmt, else_stmt; 5253 1.1 mrg mpz_t size; 5254 1.1 mrg bool size_set; 5255 1.1 mrg 5256 1.1 mrg cont_var = gfc_create_var (boolean_type_node, "contiguous"); 5257 1.1 mrg 5258 1.1 mrg /* If the size is known to be one at compile-time, set 5259 1.1 mrg cont_var to true unconditionally. This may look 5260 1.1 mrg inelegant, but we're only doing this during 5261 1.1 mrg optimization, so the statements will be optimized away, 5262 1.1 mrg and this saves complexity here. */ 5263 1.1 mrg 5264 1.1 mrg size_set = gfc_array_size (expr, &size); 5265 1.1 mrg if (size_set && mpz_cmp_ui (size, 1) == 0) 5266 1.1 mrg { 5267 1.1 mrg gfc_add_modify (&se->pre, cont_var, 5268 1.1 mrg build_one_cst (boolean_type_node)); 5269 1.1 mrg } 5270 1.1 mrg else 5271 1.1 mrg { 5272 1.1 mrg /* cont_var = is_contiguous (expr); . */ 5273 1.1 mrg gfc_init_se (&cont_se, parmse); 5274 1.1 mrg gfc_conv_is_contiguous_expr (&cont_se, expr); 5275 1.1 mrg gfc_add_block_to_block (&se->pre, &(&cont_se)->pre); 5276 1.1 mrg gfc_add_modify (&se->pre, cont_var, cont_se.expr); 5277 1.1 mrg gfc_add_block_to_block (&se->pre, &(&cont_se)->post); 5278 1.1 mrg } 5279 1.1 mrg 5280 1.1 mrg if (size_set) 5281 1.1 mrg mpz_clear (size); 5282 1.1 mrg 5283 1.1 mrg /* arrayse->expr = descriptor of a. */ 5284 1.1 mrg gfc_init_se (&array_se, se); 5285 1.1 mrg gfc_conv_expr_descriptor (&array_se, expr); 5286 1.1 mrg gfc_add_block_to_block (&se->pre, &(&array_se)->pre); 5287 1.1 mrg gfc_add_block_to_block (&se->pre, &(&array_se)->post); 5288 1.1 mrg 5289 1.1 mrg /* if_stmt = { descriptor ? pointer = a : pointer = &a[0]; } . */ 5290 1.1 mrg gfc_init_block (&if_block); 5291 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (type)) 5292 1.1 mrg gfc_add_modify (&if_block, pointer, array_se.expr); 5293 1.1 mrg else 5294 1.1 mrg { 5295 1.1 mrg tmp = gfc_conv_array_data (array_se.expr); 5296 1.1 mrg tmp = fold_convert (type, tmp); 5297 1.1 mrg gfc_add_modify (&if_block, pointer, tmp); 5298 1.1 mrg } 5299 1.1 mrg if_stmt = gfc_finish_block (&if_block); 5300 1.1 mrg 5301 1.1 mrg /* else_stmt = { parmse->pre(); pointer = parmse->expr; } . */ 5302 1.1 mrg gfc_init_block (&else_block); 5303 1.1 mrg gfc_add_block_to_block (&else_block, &parmse->pre); 5304 1.1 mrg tmp = (GFC_DESCRIPTOR_TYPE_P (type) 5305 1.1 mrg ? build_fold_indirect_ref_loc (input_location, parmse->expr) 5306 1.1 mrg : parmse->expr); 5307 1.1 mrg gfc_add_modify (&else_block, pointer, tmp); 5308 1.1 mrg else_stmt = gfc_finish_block (&else_block); 5309 1.1 mrg 5310 1.1 mrg /* And put the above into an if statement. */ 5311 1.1 mrg pre_stmts = fold_build3_loc (input_location, COND_EXPR, void_type_node, 5312 1.1 mrg gfc_likely (cont_var, 5313 1.1 mrg PRED_FORTRAN_CONTIGUOUS), 5314 1.1 mrg if_stmt, else_stmt); 5315 1.1 mrg } 5316 1.1 mrg else 5317 1.1 mrg { 5318 1.1 mrg /* pointer = pramse->expr; . */ 5319 1.1 mrg gfc_add_modify (&parmse->pre, pointer, parmse->expr); 5320 1.1 mrg pre_stmts = gfc_finish_block (&parmse->pre); 5321 1.1 mrg } 5322 1.1 mrg 5323 1.1 mrg if (pass_optional) 5324 1.1 mrg { 5325 1.1 mrg present_var = gfc_create_var (boolean_type_node, "present"); 5326 1.1 mrg 5327 1.1 mrg /* present_var = present(sym); . */ 5328 1.1 mrg tmp = gfc_conv_expr_present (sym); 5329 1.1 mrg tmp = fold_convert (boolean_type_node, tmp); 5330 1.1 mrg gfc_add_modify (&se->pre, present_var, tmp); 5331 1.1 mrg 5332 1.1 mrg /* else_stmt = { pointer = NULL; } . */ 5333 1.1 mrg gfc_init_block (&else_block); 5334 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (type)) 5335 1.1 mrg gfc_conv_descriptor_data_set (&else_block, pointer, 5336 1.1 mrg null_pointer_node); 5337 1.1 mrg else 5338 1.1 mrg gfc_add_modify (&else_block, pointer, build_int_cst (type, 0)); 5339 1.1 mrg else_stmt = gfc_finish_block (&else_block); 5340 1.1 mrg 5341 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 5342 1.1 mrg gfc_likely (present_var, 5343 1.1 mrg PRED_FORTRAN_ABSENT_DUMMY), 5344 1.1 mrg pre_stmts, else_stmt); 5345 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 5346 1.1 mrg } 5347 1.1 mrg else 5348 1.1 mrg gfc_add_expr_to_block (&se->pre, pre_stmts); 5349 1.1 mrg 5350 1.1 mrg post_stmts = gfc_finish_block (&parmse->post); 5351 1.1 mrg 5352 1.1 mrg /* Put together the post stuff, plus the optional 5353 1.1 mrg deallocation. */ 5354 1.1 mrg if (check_contiguous) 5355 1.1 mrg { 5356 1.1 mrg /* !cont_var. */ 5357 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 5358 1.1 mrg cont_var, 5359 1.1 mrg build_zero_cst (boolean_type_node)); 5360 1.1 mrg tmp = gfc_unlikely (tmp, PRED_FORTRAN_CONTIGUOUS); 5361 1.1 mrg 5362 1.1 mrg if (pass_optional) 5363 1.1 mrg { 5364 1.1 mrg tree present_likely = gfc_likely (present_var, 5365 1.1 mrg PRED_FORTRAN_ABSENT_DUMMY); 5366 1.1 mrg post_cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR, 5367 1.1 mrg boolean_type_node, present_likely, 5368 1.1 mrg tmp); 5369 1.1 mrg } 5370 1.1 mrg else 5371 1.1 mrg post_cond = tmp; 5372 1.1 mrg } 5373 1.1 mrg else 5374 1.1 mrg { 5375 1.1 mrg gcc_assert (pass_optional); 5376 1.1 mrg post_cond = present_var; 5377 1.1 mrg } 5378 1.1 mrg 5379 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, post_cond, 5380 1.1 mrg post_stmts, build_empty_stmt (input_location)); 5381 1.1 mrg gfc_add_expr_to_block (&se->post, tmp); 5382 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (type)) 5383 1.1 mrg { 5384 1.1 mrg type = TREE_TYPE (parmse->expr); 5385 1.1 mrg if (POINTER_TYPE_P (type)) 5386 1.1 mrg { 5387 1.1 mrg pointer = gfc_build_addr_expr (type, pointer); 5388 1.1 mrg if (pass_optional) 5389 1.1 mrg { 5390 1.1 mrg tmp = gfc_likely (present_var, PRED_FORTRAN_ABSENT_DUMMY); 5391 1.1 mrg pointer = fold_build3_loc (input_location, COND_EXPR, type, 5392 1.1 mrg tmp, pointer, 5393 1.1 mrg fold_convert (type, 5394 1.1 mrg null_pointer_node)); 5395 1.1 mrg } 5396 1.1 mrg } 5397 1.1 mrg else 5398 1.1 mrg gcc_assert (!pass_optional); 5399 1.1 mrg } 5400 1.1 mrg se->expr = pointer; 5401 1.1 mrg } 5402 1.1 mrg 5403 1.1 mrg return; 5404 1.1 mrg } 5405 1.1 mrg 5406 1.1 mrg 5407 1.1 mrg /* Generate the code for argument list functions. */ 5408 1.1 mrg 5409 1.1 mrg static void 5410 1.1 mrg conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name) 5411 1.1 mrg { 5412 1.1 mrg /* Pass by value for g77 %VAL(arg), pass the address 5413 1.1 mrg indirectly for %LOC, else by reference. Thus %REF 5414 1.1 mrg is a "do-nothing" and %LOC is the same as an F95 5415 1.1 mrg pointer. */ 5416 1.1 mrg if (strcmp (name, "%VAL") == 0) 5417 1.1 mrg gfc_conv_expr (se, expr); 5418 1.1 mrg else if (strcmp (name, "%LOC") == 0) 5419 1.1 mrg { 5420 1.1 mrg gfc_conv_expr_reference (se, expr); 5421 1.1 mrg se->expr = gfc_build_addr_expr (NULL, se->expr); 5422 1.1 mrg } 5423 1.1 mrg else if (strcmp (name, "%REF") == 0) 5424 1.1 mrg gfc_conv_expr_reference (se, expr); 5425 1.1 mrg else 5426 1.1 mrg gfc_error ("Unknown argument list function at %L", &expr->where); 5427 1.1 mrg } 5428 1.1 mrg 5429 1.1 mrg 5430 1.1 mrg /* This function tells whether the middle-end representation of the expression 5431 1.1 mrg E given as input may point to data otherwise accessible through a variable 5432 1.1 mrg (sub-)reference. 5433 1.1 mrg It is assumed that the only expressions that may alias are variables, 5434 1.1 mrg and array constructors if ARRAY_MAY_ALIAS is true and some of its elements 5435 1.1 mrg may alias. 5436 1.1 mrg This function is used to decide whether freeing an expression's allocatable 5437 1.1 mrg components is safe or should be avoided. 5438 1.1 mrg 5439 1.1 mrg If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of 5440 1.1 mrg its elements are copied from a variable. This ARRAY_MAY_ALIAS trick 5441 1.1 mrg is necessary because for array constructors, aliasing depends on how 5442 1.1 mrg the array is used: 5443 1.1 mrg - If E is an array constructor used as argument to an elemental procedure, 5444 1.1 mrg the array, which is generated through shallow copy by the scalarizer, 5445 1.1 mrg is used directly and can alias the expressions it was copied from. 5446 1.1 mrg - If E is an array constructor used as argument to a non-elemental 5447 1.1 mrg procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate 5448 1.1 mrg the array as in the previous case, but then that array is used 5449 1.1 mrg to initialize a new descriptor through deep copy. There is no alias 5450 1.1 mrg possible in that case. 5451 1.1 mrg Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases 5452 1.1 mrg above. */ 5453 1.1 mrg 5454 1.1 mrg static bool 5455 1.1 mrg expr_may_alias_variables (gfc_expr *e, bool array_may_alias) 5456 1.1 mrg { 5457 1.1 mrg gfc_constructor *c; 5458 1.1 mrg 5459 1.1 mrg if (e->expr_type == EXPR_VARIABLE) 5460 1.1 mrg return true; 5461 1.1 mrg else if (e->expr_type == EXPR_FUNCTION) 5462 1.1 mrg { 5463 1.1 mrg gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e); 5464 1.1 mrg 5465 1.1 mrg if (proc_ifc->result != NULL 5466 1.1 mrg && ((proc_ifc->result->ts.type == BT_CLASS 5467 1.1 mrg && proc_ifc->result->ts.u.derived->attr.is_class 5468 1.1 mrg && CLASS_DATA (proc_ifc->result)->attr.class_pointer) 5469 1.1 mrg || proc_ifc->result->attr.pointer)) 5470 1.1 mrg return true; 5471 1.1 mrg else 5472 1.1 mrg return false; 5473 1.1 mrg } 5474 1.1 mrg else if (e->expr_type != EXPR_ARRAY || !array_may_alias) 5475 1.1 mrg return false; 5476 1.1 mrg 5477 1.1 mrg for (c = gfc_constructor_first (e->value.constructor); 5478 1.1 mrg c; c = gfc_constructor_next (c)) 5479 1.1 mrg if (c->expr 5480 1.1 mrg && expr_may_alias_variables (c->expr, array_may_alias)) 5481 1.1 mrg return true; 5482 1.1 mrg 5483 1.1 mrg return false; 5484 1.1 mrg } 5485 1.1 mrg 5486 1.1 mrg 5487 1.1 mrg /* A helper function to set the dtype for unallocated or unassociated 5488 1.1 mrg entities. */ 5489 1.1 mrg 5490 1.1 mrg static void 5491 1.1 mrg set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e) 5492 1.1 mrg { 5493 1.1 mrg tree tmp; 5494 1.1 mrg tree desc; 5495 1.1 mrg tree cond; 5496 1.1 mrg tree type; 5497 1.1 mrg stmtblock_t block; 5498 1.1 mrg 5499 1.1 mrg /* TODO Figure out how to handle optional dummies. */ 5500 1.1 mrg if (e && e->expr_type == EXPR_VARIABLE 5501 1.1 mrg && e->symtree->n.sym->attr.optional) 5502 1.1 mrg return; 5503 1.1 mrg 5504 1.1 mrg desc = parmse->expr; 5505 1.1 mrg if (desc == NULL_TREE) 5506 1.1 mrg return; 5507 1.1 mrg 5508 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (desc))) 5509 1.1 mrg desc = build_fold_indirect_ref_loc (input_location, desc); 5510 1.1 mrg if (GFC_CLASS_TYPE_P (TREE_TYPE (desc))) 5511 1.1 mrg desc = gfc_class_data_get (desc); 5512 1.1 mrg if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))) 5513 1.1 mrg return; 5514 1.1 mrg 5515 1.1 mrg gfc_init_block (&block); 5516 1.1 mrg tmp = gfc_conv_descriptor_data_get (desc); 5517 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, 5518 1.1 mrg logical_type_node, tmp, 5519 1.1 mrg build_int_cst (TREE_TYPE (tmp), 0)); 5520 1.1 mrg tmp = gfc_conv_descriptor_dtype (desc); 5521 1.1 mrg type = gfc_get_element_type (TREE_TYPE (desc)); 5522 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, 5523 1.1 mrg TREE_TYPE (tmp), tmp, 5524 1.1 mrg gfc_get_dtype_rank_type (e->rank, type)); 5525 1.1 mrg gfc_add_expr_to_block (&block, tmp); 5526 1.1 mrg cond = build3_v (COND_EXPR, cond, 5527 1.1 mrg gfc_finish_block (&block), 5528 1.1 mrg build_empty_stmt (input_location)); 5529 1.1 mrg gfc_add_expr_to_block (&parmse->pre, cond); 5530 1.1 mrg } 5531 1.1 mrg 5532 1.1 mrg 5533 1.1 mrg 5534 1.1 mrg /* Provide an interface between gfortran array descriptors and the F2018:18.4 5535 1.1 mrg ISO_Fortran_binding array descriptors. */ 5536 1.1 mrg 5537 1.1 mrg static void 5538 1.1 mrg gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym) 5539 1.1 mrg { 5540 1.1 mrg stmtblock_t block, block2; 5541 1.1 mrg tree cfi, gfc, tmp, tmp2; 5542 1.1 mrg tree present = NULL; 5543 1.1 mrg tree gfc_strlen = NULL; 5544 1.1 mrg tree rank; 5545 1.1 mrg gfc_se se; 5546 1.1 mrg 5547 1.1 mrg if (fsym->attr.optional 5548 1.1 mrg && e->expr_type == EXPR_VARIABLE 5549 1.1 mrg && e->symtree->n.sym->attr.optional) 5550 1.1 mrg present = gfc_conv_expr_present (e->symtree->n.sym); 5551 1.1 mrg 5552 1.1 mrg gfc_init_block (&block); 5553 1.1 mrg 5554 1.1 mrg /* Convert original argument to a tree. */ 5555 1.1 mrg gfc_init_se (&se, NULL); 5556 1.1 mrg if (e->rank == 0) 5557 1.1 mrg { 5558 1.1 mrg se.want_pointer = 1; 5559 1.1 mrg gfc_conv_expr (&se, e); 5560 1.1 mrg gfc = se.expr; 5561 1.1 mrg /* gfc_conv_constant ignores se.want_poiner, e.g. for string_cst. */ 5562 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (gfc))) 5563 1.1 mrg gfc = gfc_build_addr_expr (NULL, gfc); 5564 1.1 mrg } 5565 1.1 mrg else 5566 1.1 mrg { 5567 1.1 mrg /* If the actual argument can be noncontiguous, copy-in/out is required, 5568 1.1 mrg if the dummy has either the CONTIGUOUS attribute or is an assumed- 5569 1.1 mrg length assumed-length/assumed-size CHARACTER array. This only 5570 1.1 mrg applies if the actual argument is a "variable"; if it's some 5571 1.1 mrg non-lvalue expression, we are going to evaluate it to a 5572 1.1 mrg temporary below anyway. */ 5573 1.1 mrg se.force_no_tmp = 1; 5574 1.1 mrg if ((fsym->attr.contiguous 5575 1.1 mrg || (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->length 5576 1.1 mrg && (fsym->as->type == AS_ASSUMED_SIZE 5577 1.1 mrg || fsym->as->type == AS_EXPLICIT))) 5578 1.1 mrg && !gfc_is_simply_contiguous (e, false, true) 5579 1.1 mrg && gfc_expr_is_variable (e)) 5580 1.1 mrg { 5581 1.1 mrg bool optional = fsym->attr.optional; 5582 1.1 mrg fsym->attr.optional = 0; 5583 1.1 mrg gfc_conv_subref_array_arg (&se, e, false, fsym->attr.intent, 5584 1.1 mrg fsym->attr.pointer, fsym, 5585 1.1 mrg fsym->ns->proc_name->name, NULL, 5586 1.1 mrg /* check_contiguous= */ true); 5587 1.1 mrg fsym->attr.optional = optional; 5588 1.1 mrg } 5589 1.1 mrg else 5590 1.1 mrg gfc_conv_expr_descriptor (&se, e); 5591 1.1 mrg gfc = se.expr; 5592 1.1 mrg /* For dt(:)%var the elem_len*stride != sm, hence, GFC uses 5593 1.1 mrg elem_len = sizeof(dt) and base_addr = dt(lb) instead. 5594 1.1 mrg gfc_get_dataptr_offset fixes the base_addr; for elem_len, see below. 5595 1.1 mrg While sm is fine as it uses span*stride and not elem_len. */ 5596 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (gfc))) 5597 1.1 mrg gfc = build_fold_indirect_ref_loc (input_location, gfc); 5598 1.1 mrg else if (is_subref_array (e) && e->ts.type != BT_CHARACTER) 5599 1.1 mrg gfc_get_dataptr_offset (&se.pre, gfc, gfc, NULL, true, e); 5600 1.1 mrg } 5601 1.1 mrg if (e->ts.type == BT_CHARACTER) 5602 1.1 mrg { 5603 1.1 mrg if (se.string_length) 5604 1.1 mrg gfc_strlen = se.string_length; 5605 1.1 mrg else if (e->ts.u.cl->backend_decl) 5606 1.1 mrg gfc_strlen = e->ts.u.cl->backend_decl; 5607 1.1 mrg else 5608 1.1 mrg gcc_unreachable (); 5609 1.1 mrg } 5610 1.1 mrg gfc_add_block_to_block (&block, &se.pre); 5611 1.1 mrg 5612 1.1 mrg /* Create array decriptor and set version, rank, attribute, type. */ 5613 1.1 mrg cfi = gfc_create_var (gfc_get_cfi_type (e->rank < 0 5614 1.1 mrg ? GFC_MAX_DIMENSIONS : e->rank, 5615 1.1 mrg false), "cfi"); 5616 1.1 mrg /* Convert to CFI_cdesc_t, which has dim[] to avoid TBAA issues,*/ 5617 1.1 mrg if (fsym->attr.dimension && fsym->as->type == AS_ASSUMED_RANK) 5618 1.1 mrg { 5619 1.1 mrg tmp = gfc_get_cfi_type (-1, !fsym->attr.pointer && !fsym->attr.target); 5620 1.1 mrg tmp = build_pointer_type (tmp); 5621 1.1 mrg parmse->expr = cfi = gfc_build_addr_expr (tmp, cfi); 5622 1.1 mrg cfi = build_fold_indirect_ref_loc (input_location, cfi); 5623 1.1 mrg } 5624 1.1 mrg else 5625 1.1 mrg parmse->expr = gfc_build_addr_expr (NULL, cfi); 5626 1.1 mrg 5627 1.1 mrg tmp = gfc_get_cfi_desc_version (cfi); 5628 1.1 mrg gfc_add_modify (&block, tmp, 5629 1.1 mrg build_int_cst (TREE_TYPE (tmp), CFI_VERSION)); 5630 1.1 mrg if (e->rank < 0) 5631 1.1 mrg rank = fold_convert (signed_char_type_node, gfc_conv_descriptor_rank (gfc)); 5632 1.1 mrg else 5633 1.1 mrg rank = build_int_cst (signed_char_type_node, e->rank); 5634 1.1 mrg tmp = gfc_get_cfi_desc_rank (cfi); 5635 1.1 mrg gfc_add_modify (&block, tmp, rank); 5636 1.1 mrg int itype = CFI_type_other; 5637 1.1 mrg if (e->ts.f90_type == BT_VOID) 5638 1.1 mrg itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR 5639 1.1 mrg ? CFI_type_cfunptr : CFI_type_cptr); 5640 1.1 mrg else 5641 1.1 mrg { 5642 1.1 mrg if (e->expr_type == EXPR_NULL && e->ts.type == BT_UNKNOWN) 5643 1.1 mrg e->ts = fsym->ts; 5644 1.1 mrg switch (e->ts.type) 5645 1.1 mrg { 5646 1.1 mrg case BT_INTEGER: 5647 1.1 mrg case BT_LOGICAL: 5648 1.1 mrg case BT_REAL: 5649 1.1 mrg case BT_COMPLEX: 5650 1.1 mrg itype = CFI_type_from_type_kind (e->ts.type, e->ts.kind); 5651 1.1 mrg break; 5652 1.1 mrg case BT_CHARACTER: 5653 1.1 mrg itype = CFI_type_from_type_kind (CFI_type_Character, e->ts.kind); 5654 1.1 mrg break; 5655 1.1 mrg case BT_DERIVED: 5656 1.1 mrg itype = CFI_type_struct; 5657 1.1 mrg break; 5658 1.1 mrg case BT_VOID: 5659 1.1 mrg itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR 5660 1.1 mrg ? CFI_type_cfunptr : CFI_type_cptr); 5661 1.1 mrg break; 5662 1.1 mrg case BT_ASSUMED: 5663 1.1 mrg itype = CFI_type_other; // FIXME: Or CFI_type_cptr ? 5664 1.1 mrg break; 5665 1.1 mrg case BT_CLASS: 5666 1.1 mrg if (UNLIMITED_POLY (e) && fsym->ts.type == BT_ASSUMED) 5667 1.1 mrg { 5668 1.1 mrg // F2017: 7.3.2.2: "An entity that is declared using the TYPE(*) 5669 1.1 mrg // type specifier is assumed-type and is an unlimited polymorphic 5670 1.1 mrg // entity." The actual argument _data component is passed. 5671 1.1 mrg itype = CFI_type_other; // FIXME: Or CFI_type_cptr ? 5672 1.1 mrg break; 5673 1.1 mrg } 5674 1.1 mrg else 5675 1.1 mrg gcc_unreachable (); 5676 1.1 mrg case BT_PROCEDURE: 5677 1.1 mrg case BT_HOLLERITH: 5678 1.1 mrg case BT_UNION: 5679 1.1 mrg case BT_BOZ: 5680 1.1 mrg case BT_UNKNOWN: 5681 1.1 mrg // FIXME: Really unreachable? Or reachable for type(*) ? If so, CFI_type_other? 5682 1.1 mrg gcc_unreachable (); 5683 1.1 mrg } 5684 1.1 mrg } 5685 1.1 mrg 5686 1.1 mrg tmp = gfc_get_cfi_desc_type (cfi); 5687 1.1 mrg gfc_add_modify (&block, tmp, 5688 1.1 mrg build_int_cst (TREE_TYPE (tmp), itype)); 5689 1.1 mrg 5690 1.1 mrg int attr = CFI_attribute_other; 5691 1.1 mrg if (fsym->attr.pointer) 5692 1.1 mrg attr = CFI_attribute_pointer; 5693 1.1 mrg else if (fsym->attr.allocatable) 5694 1.1 mrg attr = CFI_attribute_allocatable; 5695 1.1 mrg tmp = gfc_get_cfi_desc_attribute (cfi); 5696 1.1 mrg gfc_add_modify (&block, tmp, 5697 1.1 mrg build_int_cst (TREE_TYPE (tmp), attr)); 5698 1.1 mrg 5699 1.1 mrg if (e->rank == 0) 5700 1.1 mrg { 5701 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi); 5702 1.1 mrg gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), gfc)); 5703 1.1 mrg } 5704 1.1 mrg else 5705 1.1 mrg { 5706 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi); 5707 1.1 mrg tmp2 = gfc_conv_descriptor_data_get (gfc); 5708 1.1 mrg gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), tmp2)); 5709 1.1 mrg } 5710 1.1 mrg 5711 1.1 mrg /* Set elem_len if known - must be before the next if block. 5712 1.1 mrg Note that allocatable implies 'len=:'. */ 5713 1.1 mrg if (e->ts.type != BT_ASSUMED && e->ts.type != BT_CHARACTER ) 5714 1.1 mrg { 5715 1.1 mrg /* Length is known at compile time; use 'block' for it. */ 5716 1.1 mrg tmp = size_in_bytes (gfc_typenode_for_spec (&e->ts)); 5717 1.1 mrg tmp2 = gfc_get_cfi_desc_elem_len (cfi); 5718 1.1 mrg gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2), tmp)); 5719 1.1 mrg } 5720 1.1 mrg 5721 1.1 mrg /* When allocatable + intent out, free the cfi descriptor. */ 5722 1.1 mrg if (fsym->attr.allocatable && fsym->attr.intent == INTENT_OUT) 5723 1.1 mrg { 5724 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi); 5725 1.1 mrg tree call = builtin_decl_explicit (BUILT_IN_FREE); 5726 1.1 mrg call = build_call_expr_loc (input_location, call, 1, tmp); 5727 1.1 mrg gfc_add_expr_to_block (&block, fold_convert (void_type_node, call)); 5728 1.1 mrg gfc_add_modify (&block, tmp, 5729 1.1 mrg fold_convert (TREE_TYPE (tmp), null_pointer_node)); 5730 1.1 mrg goto done; 5731 1.1 mrg } 5732 1.1 mrg 5733 1.1 mrg /* If not unallocated/unassociated. */ 5734 1.1 mrg gfc_init_block (&block2); 5735 1.1 mrg 5736 1.1 mrg /* Set elem_len, which may be only known at run time. */ 5737 1.1 mrg if (e->ts.type == BT_CHARACTER 5738 1.1 mrg && (e->expr_type != EXPR_NULL || gfc_strlen != NULL_TREE)) 5739 1.1 mrg { 5740 1.1 mrg gcc_assert (gfc_strlen); 5741 1.1 mrg tmp = gfc_strlen; 5742 1.1 mrg if (e->ts.kind != 1) 5743 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, 5744 1.1 mrg gfc_charlen_type_node, tmp, 5745 1.1 mrg build_int_cst (gfc_charlen_type_node, 5746 1.1 mrg e->ts.kind)); 5747 1.1 mrg tmp2 = gfc_get_cfi_desc_elem_len (cfi); 5748 1.1 mrg gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp)); 5749 1.1 mrg } 5750 1.1 mrg else if (e->ts.type == BT_ASSUMED) 5751 1.1 mrg { 5752 1.1 mrg tmp = gfc_conv_descriptor_elem_len (gfc); 5753 1.1 mrg tmp2 = gfc_get_cfi_desc_elem_len (cfi); 5754 1.1 mrg gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp)); 5755 1.1 mrg } 5756 1.1 mrg 5757 1.1 mrg if (e->ts.type == BT_ASSUMED) 5758 1.1 mrg { 5759 1.1 mrg /* Note: type(*) implies assumed-shape/assumed-rank if fsym requires 5760 1.1 mrg an CFI descriptor. Use the type in the descritor as it provide 5761 1.1 mrg mode information. (Quality of implementation feature.) */ 5762 1.1 mrg tree cond; 5763 1.1 mrg tree ctype = gfc_get_cfi_desc_type (cfi); 5764 1.1 mrg tree type = fold_convert (TREE_TYPE (ctype), 5765 1.1 mrg gfc_conv_descriptor_type (gfc)); 5766 1.1 mrg tree kind = fold_convert (TREE_TYPE (ctype), 5767 1.1 mrg gfc_conv_descriptor_elem_len (gfc)); 5768 1.1 mrg kind = fold_build2_loc (input_location, LSHIFT_EXPR, TREE_TYPE (type), 5769 1.1 mrg kind, build_int_cst (TREE_TYPE (type), 5770 1.1 mrg CFI_type_kind_shift)); 5771 1.1 mrg 5772 1.1 mrg /* if (BT_VOID) CFI_type_cptr else CFI_type_other */ 5773 1.1 mrg /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */ 5774 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type, 5775 1.1 mrg build_int_cst (TREE_TYPE (type), BT_VOID)); 5776 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype, 5777 1.1 mrg build_int_cst (TREE_TYPE (type), CFI_type_cptr)); 5778 1.1 mrg tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, 5779 1.1 mrg ctype, 5780 1.1 mrg build_int_cst (TREE_TYPE (type), CFI_type_other)); 5781 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, 5782 1.1 mrg tmp, tmp2); 5783 1.1 mrg /* if (BT_DERIVED) CFI_type_struct else < tmp2 > */ 5784 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type, 5785 1.1 mrg build_int_cst (TREE_TYPE (type), BT_DERIVED)); 5786 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype, 5787 1.1 mrg build_int_cst (TREE_TYPE (type), CFI_type_struct)); 5788 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, 5789 1.1 mrg tmp, tmp2); 5790 1.1 mrg /* if (BT_CHARACTER) CFI_type_Character + kind=1 else < tmp2 > */ 5791 1.1 mrg /* Note: could also be kind=4, with cfi->elem_len = gfc->elem_len*4. */ 5792 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type, 5793 1.1 mrg build_int_cst (TREE_TYPE (type), BT_CHARACTER)); 5794 1.1 mrg tmp = build_int_cst (TREE_TYPE (type), 5795 1.1 mrg CFI_type_from_type_kind (CFI_type_Character, 1)); 5796 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, 5797 1.1 mrg ctype, tmp); 5798 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, 5799 1.1 mrg tmp, tmp2); 5800 1.1 mrg /* if (BT_COMPLEX) CFI_type_Complex + kind/2 else < tmp2 > */ 5801 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type, 5802 1.1 mrg build_int_cst (TREE_TYPE (type), BT_COMPLEX)); 5803 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (type), 5804 1.1 mrg kind, build_int_cst (TREE_TYPE (type), 2)); 5805 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type), tmp, 5806 1.1 mrg build_int_cst (TREE_TYPE (type), 5807 1.1 mrg CFI_type_Complex)); 5808 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, 5809 1.1 mrg ctype, tmp); 5810 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, 5811 1.1 mrg tmp, tmp2); 5812 1.1 mrg /* if (BT_INTEGER || BT_LOGICAL || BT_REAL) type + kind else <tmp2> */ 5813 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type, 5814 1.1 mrg build_int_cst (TREE_TYPE (type), BT_INTEGER)); 5815 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type, 5816 1.1 mrg build_int_cst (TREE_TYPE (type), BT_LOGICAL)); 5817 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node, 5818 1.1 mrg cond, tmp); 5819 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type, 5820 1.1 mrg build_int_cst (TREE_TYPE (type), BT_REAL)); 5821 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node, 5822 1.1 mrg cond, tmp); 5823 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type), 5824 1.1 mrg type, kind); 5825 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, 5826 1.1 mrg ctype, tmp); 5827 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, 5828 1.1 mrg tmp, tmp2); 5829 1.1 mrg gfc_add_expr_to_block (&block2, tmp2); 5830 1.1 mrg } 5831 1.1 mrg 5832 1.1 mrg if (e->rank != 0) 5833 1.1 mrg { 5834 1.1 mrg /* Loop: for (i = 0; i < rank; ++i). */ 5835 1.1 mrg tree idx = gfc_create_var (TREE_TYPE (rank), "idx"); 5836 1.1 mrg /* Loop body. */ 5837 1.1 mrg stmtblock_t loop_body; 5838 1.1 mrg gfc_init_block (&loop_body); 5839 1.1 mrg /* cfi->dim[i].lower_bound = (allocatable/pointer) 5840 1.1 mrg ? gfc->dim[i].lbound : 0 */ 5841 1.1 mrg if (fsym->attr.pointer || fsym->attr.allocatable) 5842 1.1 mrg tmp = gfc_conv_descriptor_lbound_get (gfc, idx); 5843 1.1 mrg else 5844 1.1 mrg tmp = gfc_index_zero_node; 5845 1.1 mrg gfc_add_modify (&loop_body, gfc_get_cfi_dim_lbound (cfi, idx), tmp); 5846 1.1 mrg /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1. */ 5847 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, 5848 1.1 mrg gfc_conv_descriptor_ubound_get (gfc, idx), 5849 1.1 mrg gfc_conv_descriptor_lbound_get (gfc, idx)); 5850 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, 5851 1.1 mrg tmp, gfc_index_one_node); 5852 1.1 mrg gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp); 5853 1.1 mrg /* d->dim[n].sm = gfc->dim[i].stride * gfc->span); */ 5854 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, 5855 1.1 mrg gfc_conv_descriptor_stride_get (gfc, idx), 5856 1.1 mrg gfc_conv_descriptor_span_get (gfc)); 5857 1.1 mrg gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp); 5858 1.1 mrg 5859 1.1 mrg /* Generate loop. */ 5860 1.1 mrg gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0), 5861 1.1 mrg rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1), 5862 1.1 mrg gfc_finish_block (&loop_body)); 5863 1.1 mrg 5864 1.1 mrg if (e->expr_type == EXPR_VARIABLE 5865 1.1 mrg && e->ref 5866 1.1 mrg && e->ref->u.ar.type == AR_FULL 5867 1.1 mrg && e->symtree->n.sym->attr.dummy 5868 1.1 mrg && e->symtree->n.sym->as 5869 1.1 mrg && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE) 5870 1.1 mrg { 5871 1.1 mrg tmp = gfc_get_cfi_dim_extent (cfi, gfc_rank_cst[e->rank-1]), 5872 1.1 mrg gfc_add_modify (&block2, tmp, build_int_cst (TREE_TYPE (tmp), -1)); 5873 1.1 mrg } 5874 1.1 mrg } 5875 1.1 mrg 5876 1.1 mrg if (fsym->attr.allocatable || fsym->attr.pointer) 5877 1.1 mrg { 5878 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi), 5879 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, 5880 1.1 mrg tmp, null_pointer_node); 5881 1.1 mrg tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2), 5882 1.1 mrg build_empty_stmt (input_location)); 5883 1.1 mrg gfc_add_expr_to_block (&block, tmp); 5884 1.1 mrg } 5885 1.1 mrg else 5886 1.1 mrg gfc_add_block_to_block (&block, &block2); 5887 1.1 mrg 5888 1.1 mrg 5889 1.1 mrg done: 5890 1.1 mrg if (present) 5891 1.1 mrg { 5892 1.1 mrg parmse->expr = build3_loc (input_location, COND_EXPR, 5893 1.1 mrg TREE_TYPE (parmse->expr), 5894 1.1 mrg present, parmse->expr, null_pointer_node); 5895 1.1 mrg tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block), 5896 1.1 mrg build_empty_stmt (input_location)); 5897 1.1 mrg gfc_add_expr_to_block (&parmse->pre, tmp); 5898 1.1 mrg } 5899 1.1 mrg else 5900 1.1 mrg gfc_add_block_to_block (&parmse->pre, &block); 5901 1.1 mrg 5902 1.1 mrg gfc_init_block (&block); 5903 1.1 mrg 5904 1.1 mrg if ((!fsym->attr.allocatable && !fsym->attr.pointer) 5905 1.1 mrg || fsym->attr.intent == INTENT_IN) 5906 1.1 mrg goto post_call; 5907 1.1 mrg 5908 1.1 mrg gfc_init_block (&block2); 5909 1.1 mrg if (e->rank == 0) 5910 1.1 mrg { 5911 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi); 5912 1.1 mrg gfc_add_modify (&block, gfc, fold_convert (TREE_TYPE (gfc), tmp)); 5913 1.1 mrg } 5914 1.1 mrg else 5915 1.1 mrg { 5916 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi); 5917 1.1 mrg gfc_conv_descriptor_data_set (&block, gfc, tmp); 5918 1.1 mrg 5919 1.1 mrg if (fsym->attr.allocatable) 5920 1.1 mrg { 5921 1.1 mrg /* gfc->span = cfi->elem_len. */ 5922 1.1 mrg tmp = fold_convert (gfc_array_index_type, 5923 1.1 mrg gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0])); 5924 1.1 mrg } 5925 1.1 mrg else 5926 1.1 mrg { 5927 1.1 mrg /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len) 5928 1.1 mrg ? cfi->dim[0].sm : cfi->elem_len). */ 5929 1.1 mrg tmp = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]); 5930 1.1 mrg tmp2 = fold_convert (gfc_array_index_type, 5931 1.1 mrg gfc_get_cfi_desc_elem_len (cfi)); 5932 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR, 5933 1.1 mrg gfc_array_index_type, tmp, tmp2); 5934 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, 5935 1.1 mrg tmp, gfc_index_zero_node); 5936 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, tmp, 5937 1.1 mrg gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]), tmp2); 5938 1.1 mrg } 5939 1.1 mrg gfc_conv_descriptor_span_set (&block2, gfc, tmp); 5940 1.1 mrg 5941 1.1 mrg /* Calculate offset + set lbound, ubound and stride. */ 5942 1.1 mrg gfc_conv_descriptor_offset_set (&block2, gfc, gfc_index_zero_node); 5943 1.1 mrg /* Loop: for (i = 0; i < rank; ++i). */ 5944 1.1 mrg tree idx = gfc_create_var (TREE_TYPE (rank), "idx"); 5945 1.1 mrg /* Loop body. */ 5946 1.1 mrg stmtblock_t loop_body; 5947 1.1 mrg gfc_init_block (&loop_body); 5948 1.1 mrg /* gfc->dim[i].lbound = ... */ 5949 1.1 mrg tmp = gfc_get_cfi_dim_lbound (cfi, idx); 5950 1.1 mrg gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp); 5951 1.1 mrg 5952 1.1 mrg /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */ 5953 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, 5954 1.1 mrg gfc_conv_descriptor_lbound_get (gfc, idx), 5955 1.1 mrg gfc_index_one_node); 5956 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, 5957 1.1 mrg gfc_get_cfi_dim_extent (cfi, idx), tmp); 5958 1.1 mrg gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp); 5959 1.1 mrg 5960 1.1 mrg /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */ 5961 1.1 mrg tmp = gfc_get_cfi_dim_sm (cfi, idx); 5962 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, 5963 1.1 mrg gfc_array_index_type, tmp, 5964 1.1 mrg fold_convert (gfc_array_index_type, 5965 1.1 mrg gfc_get_cfi_desc_elem_len (cfi))); 5966 1.1 mrg gfc_conv_descriptor_stride_set (&loop_body, gfc, idx, tmp); 5967 1.1 mrg 5968 1.1 mrg /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */ 5969 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, 5970 1.1 mrg gfc_conv_descriptor_stride_get (gfc, idx), 5971 1.1 mrg gfc_conv_descriptor_lbound_get (gfc, idx)); 5972 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, 5973 1.1 mrg gfc_conv_descriptor_offset_get (gfc), tmp); 5974 1.1 mrg gfc_conv_descriptor_offset_set (&loop_body, gfc, tmp); 5975 1.1 mrg /* Generate loop. */ 5976 1.1 mrg gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0), 5977 1.1 mrg rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1), 5978 1.1 mrg gfc_finish_block (&loop_body)); 5979 1.1 mrg } 5980 1.1 mrg 5981 1.1 mrg if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length) 5982 1.1 mrg { 5983 1.1 mrg tmp = fold_convert (gfc_charlen_type_node, 5984 1.1 mrg gfc_get_cfi_desc_elem_len (cfi)); 5985 1.1 mrg if (e->ts.kind != 1) 5986 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, 5987 1.1 mrg gfc_charlen_type_node, tmp, 5988 1.1 mrg build_int_cst (gfc_charlen_type_node, 5989 1.1 mrg e->ts.kind)); 5990 1.1 mrg gfc_add_modify (&block2, gfc_strlen, tmp); 5991 1.1 mrg } 5992 1.1 mrg 5993 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi), 5994 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, 5995 1.1 mrg tmp, null_pointer_node); 5996 1.1 mrg tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2), 5997 1.1 mrg build_empty_stmt (input_location)); 5998 1.1 mrg gfc_add_expr_to_block (&block, tmp); 5999 1.1 mrg 6000 1.1 mrg post_call: 6001 1.1 mrg gfc_add_block_to_block (&block, &se.post); 6002 1.1 mrg if (present && block.head) 6003 1.1 mrg { 6004 1.1 mrg tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block), 6005 1.1 mrg build_empty_stmt (input_location)); 6006 1.1 mrg gfc_add_expr_to_block (&parmse->post, tmp); 6007 1.1 mrg } 6008 1.1 mrg else if (block.head) 6009 1.1 mrg gfc_add_block_to_block (&parmse->post, &block); 6010 1.1 mrg } 6011 1.1 mrg 6012 1.1 mrg 6013 1.1 mrg /* Generate code for a procedure call. Note can return se->post != NULL. 6014 1.1 mrg If se->direct_byref is set then se->expr contains the return parameter. 6015 1.1 mrg Return nonzero, if the call has alternate specifiers. 6016 1.1 mrg 'expr' is only needed for procedure pointer components. */ 6017 1.1 mrg 6018 1.1 mrg int 6019 1.1 mrg gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, 6020 1.1 mrg gfc_actual_arglist * args, gfc_expr * expr, 6021 1.1 mrg vec<tree, va_gc> *append_args) 6022 1.1 mrg { 6023 1.1 mrg gfc_interface_mapping mapping; 6024 1.1 mrg vec<tree, va_gc> *arglist; 6025 1.1 mrg vec<tree, va_gc> *retargs; 6026 1.1 mrg tree tmp; 6027 1.1 mrg tree fntype; 6028 1.1 mrg gfc_se parmse; 6029 1.1 mrg gfc_array_info *info; 6030 1.1 mrg int byref; 6031 1.1 mrg int parm_kind; 6032 1.1 mrg tree type; 6033 1.1 mrg tree var; 6034 1.1 mrg tree len; 6035 1.1 mrg tree base_object; 6036 1.1 mrg vec<tree, va_gc> *stringargs; 6037 1.1 mrg vec<tree, va_gc> *optionalargs; 6038 1.1 mrg tree result = NULL; 6039 1.1 mrg gfc_formal_arglist *formal; 6040 1.1 mrg gfc_actual_arglist *arg; 6041 1.1 mrg int has_alternate_specifier = 0; 6042 1.1 mrg bool need_interface_mapping; 6043 1.1 mrg bool callee_alloc; 6044 1.1 mrg bool ulim_copy; 6045 1.1 mrg gfc_typespec ts; 6046 1.1 mrg gfc_charlen cl; 6047 1.1 mrg gfc_expr *e; 6048 1.1 mrg gfc_symbol *fsym; 6049 1.1 mrg enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY}; 6050 1.1 mrg gfc_component *comp = NULL; 6051 1.1 mrg int arglen; 6052 1.1 mrg unsigned int argc; 6053 1.1 mrg 6054 1.1 mrg arglist = NULL; 6055 1.1 mrg retargs = NULL; 6056 1.1 mrg stringargs = NULL; 6057 1.1 mrg optionalargs = NULL; 6058 1.1 mrg var = NULL_TREE; 6059 1.1 mrg len = NULL_TREE; 6060 1.1 mrg gfc_clear_ts (&ts); 6061 1.1 mrg 6062 1.1 mrg comp = gfc_get_proc_ptr_comp (expr); 6063 1.1 mrg 6064 1.1 mrg bool elemental_proc = (comp 6065 1.1 mrg && comp->ts.interface 6066 1.1 mrg && comp->ts.interface->attr.elemental) 6067 1.1 mrg || (comp && comp->attr.elemental) 6068 1.1 mrg || sym->attr.elemental; 6069 1.1 mrg 6070 1.1 mrg if (se->ss != NULL) 6071 1.1 mrg { 6072 1.1 mrg if (!elemental_proc) 6073 1.1 mrg { 6074 1.1 mrg gcc_assert (se->ss->info->type == GFC_SS_FUNCTION); 6075 1.1 mrg if (se->ss->info->useflags) 6076 1.1 mrg { 6077 1.1 mrg gcc_assert ((!comp && gfc_return_by_reference (sym) 6078 1.1 mrg && sym->result->attr.dimension) 6079 1.1 mrg || (comp && comp->attr.dimension) 6080 1.1 mrg || gfc_is_class_array_function (expr)); 6081 1.1 mrg gcc_assert (se->loop != NULL); 6082 1.1 mrg /* Access the previously obtained result. */ 6083 1.1 mrg gfc_conv_tmp_array_ref (se); 6084 1.1 mrg return 0; 6085 1.1 mrg } 6086 1.1 mrg } 6087 1.1 mrg info = &se->ss->info->data.array; 6088 1.1 mrg } 6089 1.1 mrg else 6090 1.1 mrg info = NULL; 6091 1.1 mrg 6092 1.1 mrg stmtblock_t post, clobbers; 6093 1.1 mrg gfc_init_block (&post); 6094 1.1 mrg gfc_init_block (&clobbers); 6095 1.1 mrg gfc_init_interface_mapping (&mapping); 6096 1.1 mrg if (!comp) 6097 1.1 mrg { 6098 1.1 mrg formal = gfc_sym_get_dummy_args (sym); 6099 1.1 mrg need_interface_mapping = sym->attr.dimension || 6100 1.1 mrg (sym->ts.type == BT_CHARACTER 6101 1.1 mrg && sym->ts.u.cl->length 6102 1.1 mrg && sym->ts.u.cl->length->expr_type 6103 1.1 mrg != EXPR_CONSTANT); 6104 1.1 mrg } 6105 1.1 mrg else 6106 1.1 mrg { 6107 1.1 mrg formal = comp->ts.interface ? comp->ts.interface->formal : NULL; 6108 1.1 mrg need_interface_mapping = comp->attr.dimension || 6109 1.1 mrg (comp->ts.type == BT_CHARACTER 6110 1.1 mrg && comp->ts.u.cl->length 6111 1.1 mrg && comp->ts.u.cl->length->expr_type 6112 1.1 mrg != EXPR_CONSTANT); 6113 1.1 mrg } 6114 1.1 mrg 6115 1.1 mrg base_object = NULL_TREE; 6116 1.1 mrg /* For _vprt->_copy () routines no formal symbol is present. Nevertheless 6117 1.1 mrg is the third and fourth argument to such a function call a value 6118 1.1 mrg denoting the number of elements to copy (i.e., most of the time the 6119 1.1 mrg length of a deferred length string). */ 6120 1.1 mrg ulim_copy = (formal == NULL) 6121 1.1 mrg && UNLIMITED_POLY (sym) 6122 1.1 mrg && comp && (strcmp ("_copy", comp->name) == 0); 6123 1.1 mrg 6124 1.1 mrg /* Evaluate the arguments. */ 6125 1.1 mrg for (arg = args, argc = 0; arg != NULL; 6126 1.1 mrg arg = arg->next, formal = formal ? formal->next : NULL, ++argc) 6127 1.1 mrg { 6128 1.1 mrg bool finalized = false; 6129 1.1 mrg tree derived_array = NULL_TREE; 6130 1.1 mrg 6131 1.1 mrg e = arg->expr; 6132 1.1 mrg fsym = formal ? formal->sym : NULL; 6133 1.1 mrg parm_kind = MISSING; 6134 1.1 mrg 6135 1.1 mrg /* If the procedure requires an explicit interface, the actual 6136 1.1 mrg argument is passed according to the corresponding formal 6137 1.1 mrg argument. If the corresponding formal argument is a POINTER, 6138 1.1 mrg ALLOCATABLE or assumed shape, we do not use g77's calling 6139 1.1 mrg convention, and pass the address of the array descriptor 6140 1.1 mrg instead. Otherwise we use g77's calling convention, in other words 6141 1.1 mrg pass the array data pointer without descriptor. */ 6142 1.1 mrg bool nodesc_arg = fsym != NULL 6143 1.1 mrg && !(fsym->attr.pointer || fsym->attr.allocatable) 6144 1.1 mrg && fsym->as 6145 1.1 mrg && fsym->as->type != AS_ASSUMED_SHAPE 6146 1.1 mrg && fsym->as->type != AS_ASSUMED_RANK; 6147 1.1 mrg if (comp) 6148 1.1 mrg nodesc_arg = nodesc_arg || !comp->attr.always_explicit; 6149 1.1 mrg else 6150 1.1 mrg nodesc_arg = nodesc_arg || !sym->attr.always_explicit; 6151 1.1 mrg 6152 1.1 mrg /* Class array expressions are sometimes coming completely unadorned 6153 1.1 mrg with either arrayspec or _data component. Correct that here. 6154 1.1 mrg OOP-TODO: Move this to the frontend. */ 6155 1.1 mrg if (e && e->expr_type == EXPR_VARIABLE 6156 1.1 mrg && !e->ref 6157 1.1 mrg && e->ts.type == BT_CLASS 6158 1.1 mrg && (CLASS_DATA (e)->attr.codimension 6159 1.1 mrg || CLASS_DATA (e)->attr.dimension)) 6160 1.1 mrg { 6161 1.1 mrg gfc_typespec temp_ts = e->ts; 6162 1.1 mrg gfc_add_class_array_ref (e); 6163 1.1 mrg e->ts = temp_ts; 6164 1.1 mrg } 6165 1.1 mrg 6166 1.1 mrg if (e == NULL) 6167 1.1 mrg { 6168 1.1 mrg if (se->ignore_optional) 6169 1.1 mrg { 6170 1.1 mrg /* Some intrinsics have already been resolved to the correct 6171 1.1 mrg parameters. */ 6172 1.1 mrg continue; 6173 1.1 mrg } 6174 1.1 mrg else if (arg->label) 6175 1.1 mrg { 6176 1.1 mrg has_alternate_specifier = 1; 6177 1.1 mrg continue; 6178 1.1 mrg } 6179 1.1 mrg else 6180 1.1 mrg { 6181 1.1 mrg gfc_init_se (&parmse, NULL); 6182 1.1 mrg 6183 1.1 mrg /* For scalar arguments with VALUE attribute which are passed by 6184 1.1 mrg value, pass "0" and a hidden argument gives the optional 6185 1.1 mrg status. */ 6186 1.1 mrg if (fsym && fsym->attr.optional && fsym->attr.value 6187 1.1 mrg && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER 6188 1.1 mrg && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED) 6189 1.1 mrg { 6190 1.1 mrg parmse.expr = fold_convert (gfc_sym_type (fsym), 6191 1.1 mrg integer_zero_node); 6192 1.1 mrg vec_safe_push (optionalargs, boolean_false_node); 6193 1.1 mrg } 6194 1.1 mrg else 6195 1.1 mrg { 6196 1.1 mrg /* Pass a NULL pointer for an absent arg. */ 6197 1.1 mrg parmse.expr = null_pointer_node; 6198 1.1 mrg 6199 1.1 mrg /* Is it an absent character dummy? */ 6200 1.1 mrg bool absent_char = false; 6201 1.1 mrg gfc_dummy_arg * const dummy_arg = arg->associated_dummy; 6202 1.1 mrg 6203 1.1 mrg /* Fall back to inferred type only if no formal. */ 6204 1.1 mrg if (fsym) 6205 1.1 mrg absent_char = (fsym->ts.type == BT_CHARACTER); 6206 1.1 mrg else if (dummy_arg) 6207 1.1 mrg absent_char = (gfc_dummy_arg_get_typespec (*dummy_arg).type 6208 1.1 mrg == BT_CHARACTER); 6209 1.1 mrg if (absent_char) 6210 1.1 mrg parmse.string_length = build_int_cst (gfc_charlen_type_node, 6211 1.1 mrg 0); 6212 1.1 mrg } 6213 1.1 mrg } 6214 1.1 mrg } 6215 1.1 mrg else if (arg->expr->expr_type == EXPR_NULL 6216 1.1 mrg && fsym && !fsym->attr.pointer 6217 1.1 mrg && (fsym->ts.type != BT_CLASS 6218 1.1 mrg || !CLASS_DATA (fsym)->attr.class_pointer)) 6219 1.1 mrg { 6220 1.1 mrg /* Pass a NULL pointer to denote an absent arg. */ 6221 1.1 mrg gcc_assert (fsym->attr.optional && !fsym->attr.allocatable 6222 1.1 mrg && (fsym->ts.type != BT_CLASS 6223 1.1 mrg || !CLASS_DATA (fsym)->attr.allocatable)); 6224 1.1 mrg gfc_init_se (&parmse, NULL); 6225 1.1 mrg parmse.expr = null_pointer_node; 6226 1.1 mrg if (fsym->ts.type == BT_CHARACTER) 6227 1.1 mrg parmse.string_length = build_int_cst (gfc_charlen_type_node, 0); 6228 1.1 mrg } 6229 1.1 mrg else if (fsym && fsym->ts.type == BT_CLASS 6230 1.1 mrg && e->ts.type == BT_DERIVED) 6231 1.1 mrg { 6232 1.1 mrg /* The derived type needs to be converted to a temporary 6233 1.1 mrg CLASS object. */ 6234 1.1 mrg gfc_init_se (&parmse, se); 6235 1.1 mrg gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL, 6236 1.1 mrg fsym->attr.optional 6237 1.1 mrg && e->expr_type == EXPR_VARIABLE 6238 1.1 mrg && e->symtree->n.sym->attr.optional, 6239 1.1 mrg CLASS_DATA (fsym)->attr.class_pointer 6240 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable, 6241 1.1 mrg &derived_array); 6242 1.1 mrg } 6243 1.1 mrg else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS 6244 1.1 mrg && e->ts.type != BT_PROCEDURE 6245 1.1 mrg && (gfc_expr_attr (e).flavor != FL_PROCEDURE 6246 1.1 mrg || gfc_expr_attr (e).proc != PROC_UNKNOWN)) 6247 1.1 mrg { 6248 1.1 mrg /* The intrinsic type needs to be converted to a temporary 6249 1.1 mrg CLASS object for the unlimited polymorphic formal. */ 6250 1.1 mrg gfc_find_vtab (&e->ts); 6251 1.1 mrg gfc_init_se (&parmse, se); 6252 1.1 mrg gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts); 6253 1.1 mrg 6254 1.1 mrg } 6255 1.1 mrg else if (se->ss && se->ss->info->useflags) 6256 1.1 mrg { 6257 1.1 mrg gfc_ss *ss; 6258 1.1 mrg 6259 1.1 mrg ss = se->ss; 6260 1.1 mrg 6261 1.1 mrg /* An elemental function inside a scalarized loop. */ 6262 1.1 mrg gfc_init_se (&parmse, se); 6263 1.1 mrg parm_kind = ELEMENTAL; 6264 1.1 mrg 6265 1.1 mrg /* When no fsym is present, ulim_copy is set and this is a third or 6266 1.1 mrg fourth argument, use call-by-value instead of by reference to 6267 1.1 mrg hand the length properties to the copy routine (i.e., most of the 6268 1.1 mrg time this will be a call to a __copy_character_* routine where the 6269 1.1 mrg third and fourth arguments are the lengths of a deferred length 6270 1.1 mrg char array). */ 6271 1.1 mrg if ((fsym && fsym->attr.value) 6272 1.1 mrg || (ulim_copy && (argc == 2 || argc == 3))) 6273 1.1 mrg gfc_conv_expr (&parmse, e); 6274 1.1 mrg else 6275 1.1 mrg gfc_conv_expr_reference (&parmse, e); 6276 1.1 mrg 6277 1.1 mrg if (e->ts.type == BT_CHARACTER && !e->rank 6278 1.1 mrg && e->expr_type == EXPR_FUNCTION) 6279 1.1 mrg parmse.expr = build_fold_indirect_ref_loc (input_location, 6280 1.1 mrg parmse.expr); 6281 1.1 mrg 6282 1.1 mrg if (fsym && fsym->ts.type == BT_DERIVED 6283 1.1 mrg && gfc_is_class_container_ref (e)) 6284 1.1 mrg { 6285 1.1 mrg parmse.expr = gfc_class_data_get (parmse.expr); 6286 1.1 mrg 6287 1.1 mrg if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE 6288 1.1 mrg && e->symtree->n.sym->attr.optional) 6289 1.1 mrg { 6290 1.1 mrg tree cond = gfc_conv_expr_present (e->symtree->n.sym); 6291 1.1 mrg parmse.expr = build3_loc (input_location, COND_EXPR, 6292 1.1 mrg TREE_TYPE (parmse.expr), 6293 1.1 mrg cond, parmse.expr, 6294 1.1 mrg fold_convert (TREE_TYPE (parmse.expr), 6295 1.1 mrg null_pointer_node)); 6296 1.1 mrg } 6297 1.1 mrg } 6298 1.1 mrg 6299 1.1 mrg /* If we are passing an absent array as optional dummy to an 6300 1.1 mrg elemental procedure, make sure that we pass NULL when the data 6301 1.1 mrg pointer is NULL. We need this extra conditional because of 6302 1.1 mrg scalarization which passes arrays elements to the procedure, 6303 1.1 mrg ignoring the fact that the array can be absent/unallocated/... */ 6304 1.1 mrg if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE) 6305 1.1 mrg { 6306 1.1 mrg tree descriptor_data; 6307 1.1 mrg 6308 1.1 mrg descriptor_data = ss->info->data.array.data; 6309 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, 6310 1.1 mrg descriptor_data, 6311 1.1 mrg fold_convert (TREE_TYPE (descriptor_data), 6312 1.1 mrg null_pointer_node)); 6313 1.1 mrg parmse.expr 6314 1.1 mrg = fold_build3_loc (input_location, COND_EXPR, 6315 1.1 mrg TREE_TYPE (parmse.expr), 6316 1.1 mrg gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY), 6317 1.1 mrg fold_convert (TREE_TYPE (parmse.expr), 6318 1.1 mrg null_pointer_node), 6319 1.1 mrg parmse.expr); 6320 1.1 mrg } 6321 1.1 mrg 6322 1.1 mrg /* The scalarizer does not repackage the reference to a class 6323 1.1 mrg array - instead it returns a pointer to the data element. */ 6324 1.1 mrg if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS) 6325 1.1 mrg gfc_conv_class_to_class (&parmse, e, fsym->ts, true, 6326 1.1 mrg fsym->attr.intent != INTENT_IN 6327 1.1 mrg && (CLASS_DATA (fsym)->attr.class_pointer 6328 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable), 6329 1.1 mrg fsym->attr.optional 6330 1.1 mrg && e->expr_type == EXPR_VARIABLE 6331 1.1 mrg && e->symtree->n.sym->attr.optional, 6332 1.1 mrg CLASS_DATA (fsym)->attr.class_pointer 6333 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable); 6334 1.1 mrg } 6335 1.1 mrg else 6336 1.1 mrg { 6337 1.1 mrg bool scalar; 6338 1.1 mrg gfc_ss *argss; 6339 1.1 mrg 6340 1.1 mrg gfc_init_se (&parmse, NULL); 6341 1.1 mrg 6342 1.1 mrg /* Check whether the expression is a scalar or not; we cannot use 6343 1.1 mrg e->rank as it can be nonzero for functions arguments. */ 6344 1.1 mrg argss = gfc_walk_expr (e); 6345 1.1 mrg scalar = argss == gfc_ss_terminator; 6346 1.1 mrg if (!scalar) 6347 1.1 mrg gfc_free_ss_chain (argss); 6348 1.1 mrg 6349 1.1 mrg /* Special handling for passing scalar polymorphic coarrays; 6350 1.1 mrg otherwise one passes "class->_data.data" instead of "&class". */ 6351 1.1 mrg if (e->rank == 0 && e->ts.type == BT_CLASS 6352 1.1 mrg && fsym && fsym->ts.type == BT_CLASS 6353 1.1 mrg && CLASS_DATA (fsym)->attr.codimension 6354 1.1 mrg && !CLASS_DATA (fsym)->attr.dimension) 6355 1.1 mrg { 6356 1.1 mrg gfc_add_class_array_ref (e); 6357 1.1 mrg parmse.want_coarray = 1; 6358 1.1 mrg scalar = false; 6359 1.1 mrg } 6360 1.1 mrg 6361 1.1 mrg /* A scalar or transformational function. */ 6362 1.1 mrg if (scalar) 6363 1.1 mrg { 6364 1.1 mrg if (e->expr_type == EXPR_VARIABLE 6365 1.1 mrg && e->symtree->n.sym->attr.cray_pointee 6366 1.1 mrg && fsym && fsym->attr.flavor == FL_PROCEDURE) 6367 1.1 mrg { 6368 1.1 mrg /* The Cray pointer needs to be converted to a pointer to 6369 1.1 mrg a type given by the expression. */ 6370 1.1 mrg gfc_conv_expr (&parmse, e); 6371 1.1 mrg type = build_pointer_type (TREE_TYPE (parmse.expr)); 6372 1.1 mrg tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer); 6373 1.1 mrg parmse.expr = convert (type, tmp); 6374 1.1 mrg } 6375 1.1 mrg 6376 1.1 mrg else if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL)) 6377 1.1 mrg /* Implement F2018, 18.3.6, list item (5), bullet point 2. */ 6378 1.1 mrg gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym); 6379 1.1 mrg 6380 1.1 mrg else if (fsym && fsym->attr.value) 6381 1.1 mrg { 6382 1.1 mrg if (fsym->ts.type == BT_CHARACTER 6383 1.1 mrg && fsym->ts.is_c_interop 6384 1.1 mrg && fsym->ns->proc_name != NULL 6385 1.1 mrg && fsym->ns->proc_name->attr.is_bind_c) 6386 1.1 mrg { 6387 1.1 mrg parmse.expr = NULL; 6388 1.1 mrg conv_scalar_char_value (fsym, &parmse, &e); 6389 1.1 mrg if (parmse.expr == NULL) 6390 1.1 mrg gfc_conv_expr (&parmse, e); 6391 1.1 mrg } 6392 1.1 mrg else 6393 1.1 mrg { 6394 1.1 mrg gfc_conv_expr (&parmse, e); 6395 1.1 mrg if (fsym->attr.optional 6396 1.1 mrg && fsym->ts.type != BT_CLASS 6397 1.1 mrg && fsym->ts.type != BT_DERIVED) 6398 1.1 mrg { 6399 1.1 mrg if (e->expr_type != EXPR_VARIABLE 6400 1.1 mrg || !e->symtree->n.sym->attr.optional 6401 1.1 mrg || e->ref != NULL) 6402 1.1 mrg vec_safe_push (optionalargs, boolean_true_node); 6403 1.1 mrg else 6404 1.1 mrg { 6405 1.1 mrg tmp = gfc_conv_expr_present (e->symtree->n.sym); 6406 1.1 mrg if (!e->symtree->n.sym->attr.value) 6407 1.1 mrg parmse.expr 6408 1.1 mrg = fold_build3_loc (input_location, COND_EXPR, 6409 1.1 mrg TREE_TYPE (parmse.expr), 6410 1.1 mrg tmp, parmse.expr, 6411 1.1 mrg fold_convert (TREE_TYPE (parmse.expr), 6412 1.1 mrg integer_zero_node)); 6413 1.1 mrg 6414 1.1 mrg vec_safe_push (optionalargs, 6415 1.1 mrg fold_convert (boolean_type_node, 6416 1.1 mrg tmp)); 6417 1.1 mrg } 6418 1.1 mrg } 6419 1.1 mrg } 6420 1.1 mrg } 6421 1.1 mrg 6422 1.1 mrg else if (arg->name && arg->name[0] == '%') 6423 1.1 mrg /* Argument list functions %VAL, %LOC and %REF are signalled 6424 1.1 mrg through arg->name. */ 6425 1.1 mrg conv_arglist_function (&parmse, arg->expr, arg->name); 6426 1.1 mrg else if ((e->expr_type == EXPR_FUNCTION) 6427 1.1 mrg && ((e->value.function.esym 6428 1.1 mrg && e->value.function.esym->result->attr.pointer) 6429 1.1 mrg || (!e->value.function.esym 6430 1.1 mrg && e->symtree->n.sym->attr.pointer)) 6431 1.1 mrg && fsym && fsym->attr.target) 6432 1.1 mrg /* Make sure the function only gets called once. */ 6433 1.1 mrg gfc_conv_expr_reference (&parmse, e); 6434 1.1 mrg else if (e->expr_type == EXPR_FUNCTION 6435 1.1 mrg && e->symtree->n.sym->result 6436 1.1 mrg && e->symtree->n.sym->result != e->symtree->n.sym 6437 1.1 mrg && e->symtree->n.sym->result->attr.proc_pointer) 6438 1.1 mrg { 6439 1.1 mrg /* Functions returning procedure pointers. */ 6440 1.1 mrg gfc_conv_expr (&parmse, e); 6441 1.1 mrg if (fsym && fsym->attr.proc_pointer) 6442 1.1 mrg parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr); 6443 1.1 mrg } 6444 1.1 mrg 6445 1.1 mrg else 6446 1.1 mrg { 6447 1.1 mrg if (e->ts.type == BT_CLASS && fsym 6448 1.1 mrg && fsym->ts.type == BT_CLASS 6449 1.1 mrg && (!CLASS_DATA (fsym)->as 6450 1.1 mrg || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK) 6451 1.1 mrg && CLASS_DATA (e)->attr.codimension) 6452 1.1 mrg { 6453 1.1 mrg gcc_assert (!CLASS_DATA (fsym)->attr.codimension); 6454 1.1 mrg gcc_assert (!CLASS_DATA (fsym)->as); 6455 1.1 mrg gfc_add_class_array_ref (e); 6456 1.1 mrg parmse.want_coarray = 1; 6457 1.1 mrg gfc_conv_expr_reference (&parmse, e); 6458 1.1 mrg class_scalar_coarray_to_class (&parmse, e, fsym->ts, 6459 1.1 mrg fsym->attr.optional 6460 1.1 mrg && e->expr_type == EXPR_VARIABLE); 6461 1.1 mrg } 6462 1.1 mrg else if (e->ts.type == BT_CLASS && fsym 6463 1.1 mrg && fsym->ts.type == BT_CLASS 6464 1.1 mrg && !CLASS_DATA (fsym)->as 6465 1.1 mrg && !CLASS_DATA (e)->as 6466 1.1 mrg && strcmp (fsym->ts.u.derived->name, 6467 1.1 mrg e->ts.u.derived->name)) 6468 1.1 mrg { 6469 1.1 mrg type = gfc_typenode_for_spec (&fsym->ts); 6470 1.1 mrg var = gfc_create_var (type, fsym->name); 6471 1.1 mrg gfc_conv_expr (&parmse, e); 6472 1.1 mrg if (fsym->attr.optional 6473 1.1 mrg && e->expr_type == EXPR_VARIABLE 6474 1.1 mrg && e->symtree->n.sym->attr.optional) 6475 1.1 mrg { 6476 1.1 mrg stmtblock_t block; 6477 1.1 mrg tree cond; 6478 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr); 6479 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, 6480 1.1 mrg logical_type_node, tmp, 6481 1.1 mrg fold_convert (TREE_TYPE (tmp), 6482 1.1 mrg null_pointer_node)); 6483 1.1 mrg gfc_start_block (&block); 6484 1.1 mrg gfc_add_modify (&block, var, 6485 1.1 mrg fold_build1_loc (input_location, 6486 1.1 mrg VIEW_CONVERT_EXPR, 6487 1.1 mrg type, parmse.expr)); 6488 1.1 mrg gfc_add_expr_to_block (&parmse.pre, 6489 1.1 mrg fold_build3_loc (input_location, 6490 1.1 mrg COND_EXPR, void_type_node, 6491 1.1 mrg cond, gfc_finish_block (&block), 6492 1.1 mrg build_empty_stmt (input_location))); 6493 1.1 mrg parmse.expr = gfc_build_addr_expr (NULL_TREE, var); 6494 1.1 mrg parmse.expr = build3_loc (input_location, COND_EXPR, 6495 1.1 mrg TREE_TYPE (parmse.expr), 6496 1.1 mrg cond, parmse.expr, 6497 1.1 mrg fold_convert (TREE_TYPE (parmse.expr), 6498 1.1 mrg null_pointer_node)); 6499 1.1 mrg } 6500 1.1 mrg else 6501 1.1 mrg { 6502 1.1 mrg /* Since the internal representation of unlimited 6503 1.1 mrg polymorphic expressions includes an extra field 6504 1.1 mrg that other class objects do not, a cast to the 6505 1.1 mrg formal type does not work. */ 6506 1.1 mrg if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym)) 6507 1.1 mrg { 6508 1.1 mrg tree efield; 6509 1.1 mrg 6510 1.1 mrg /* Set the _data field. */ 6511 1.1 mrg tmp = gfc_class_data_get (var); 6512 1.1 mrg efield = fold_convert (TREE_TYPE (tmp), 6513 1.1 mrg gfc_class_data_get (parmse.expr)); 6514 1.1 mrg gfc_add_modify (&parmse.pre, tmp, efield); 6515 1.1 mrg 6516 1.1 mrg /* Set the _vptr field. */ 6517 1.1 mrg tmp = gfc_class_vptr_get (var); 6518 1.1 mrg efield = fold_convert (TREE_TYPE (tmp), 6519 1.1 mrg gfc_class_vptr_get (parmse.expr)); 6520 1.1 mrg gfc_add_modify (&parmse.pre, tmp, efield); 6521 1.1 mrg 6522 1.1 mrg /* Set the _len field. */ 6523 1.1 mrg tmp = gfc_class_len_get (var); 6524 1.1 mrg gfc_add_modify (&parmse.pre, tmp, 6525 1.1 mrg build_int_cst (TREE_TYPE (tmp), 0)); 6526 1.1 mrg } 6527 1.1 mrg else 6528 1.1 mrg { 6529 1.1 mrg tmp = fold_build1_loc (input_location, 6530 1.1 mrg VIEW_CONVERT_EXPR, 6531 1.1 mrg type, parmse.expr); 6532 1.1 mrg gfc_add_modify (&parmse.pre, var, tmp); 6533 1.1 mrg ; 6534 1.1 mrg } 6535 1.1 mrg parmse.expr = gfc_build_addr_expr (NULL_TREE, var); 6536 1.1 mrg } 6537 1.1 mrg } 6538 1.1 mrg else 6539 1.1 mrg { 6540 1.1 mrg gfc_conv_expr_reference (&parmse, e); 6541 1.1 mrg 6542 1.1 mrg if (fsym 6543 1.1 mrg && fsym->attr.intent == INTENT_OUT 6544 1.1 mrg && !fsym->attr.allocatable 6545 1.1 mrg && !fsym->attr.pointer 6546 1.1 mrg && e->expr_type == EXPR_VARIABLE 6547 1.1 mrg && e->ref == NULL 6548 1.1 mrg && e->symtree 6549 1.1 mrg && e->symtree->n.sym 6550 1.1 mrg && !e->symtree->n.sym->attr.dimension 6551 1.1 mrg && !e->symtree->n.sym->attr.pointer 6552 1.1 mrg && !e->symtree->n.sym->attr.allocatable 6553 1.1 mrg /* See PR 41453. */ 6554 1.1 mrg && !e->symtree->n.sym->attr.dummy 6555 1.1 mrg /* FIXME - PR 87395 and PR 41453 */ 6556 1.1 mrg && e->symtree->n.sym->attr.save == SAVE_NONE 6557 1.1 mrg && !e->symtree->n.sym->attr.associate_var 6558 1.1 mrg && e->ts.type != BT_CHARACTER 6559 1.1 mrg && e->ts.type != BT_DERIVED 6560 1.1 mrg && e->ts.type != BT_CLASS 6561 1.1 mrg && !sym->attr.elemental) 6562 1.1 mrg { 6563 1.1 mrg tree var; 6564 1.1 mrg /* FIXME: This fails if var is passed by reference, see PR 6565 1.1 mrg 41453. */ 6566 1.1 mrg var = build_fold_indirect_ref_loc (input_location, 6567 1.1 mrg parmse.expr); 6568 1.1 mrg tree clobber = build_clobber (TREE_TYPE (var)); 6569 1.1 mrg gfc_add_modify (&clobbers, var, clobber); 6570 1.1 mrg } 6571 1.1 mrg } 6572 1.1 mrg /* Catch base objects that are not variables. */ 6573 1.1 mrg if (e->ts.type == BT_CLASS 6574 1.1 mrg && e->expr_type != EXPR_VARIABLE 6575 1.1 mrg && expr && e == expr->base_expr) 6576 1.1 mrg base_object = build_fold_indirect_ref_loc (input_location, 6577 1.1 mrg parmse.expr); 6578 1.1 mrg 6579 1.1 mrg /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 6580 1.1 mrg allocated on entry, it must be deallocated. */ 6581 1.1 mrg if (fsym && fsym->attr.intent == INTENT_OUT 6582 1.1 mrg && (fsym->attr.allocatable 6583 1.1 mrg || (fsym->ts.type == BT_CLASS 6584 1.1 mrg && CLASS_DATA (fsym)->attr.allocatable)) 6585 1.1 mrg && !is_CFI_desc (fsym, NULL)) 6586 1.1 mrg { 6587 1.1 mrg stmtblock_t block; 6588 1.1 mrg tree ptr; 6589 1.1 mrg 6590 1.1 mrg gfc_init_block (&block); 6591 1.1 mrg ptr = parmse.expr; 6592 1.1 mrg if (e->ts.type == BT_CLASS) 6593 1.1 mrg ptr = gfc_class_data_get (ptr); 6594 1.1 mrg 6595 1.1 mrg tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE, 6596 1.1 mrg NULL_TREE, true, 6597 1.1 mrg e, e->ts); 6598 1.1 mrg gfc_add_expr_to_block (&block, tmp); 6599 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, 6600 1.1 mrg void_type_node, ptr, 6601 1.1 mrg null_pointer_node); 6602 1.1 mrg gfc_add_expr_to_block (&block, tmp); 6603 1.1 mrg 6604 1.1 mrg if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym)) 6605 1.1 mrg { 6606 1.1 mrg gfc_add_modify (&block, ptr, 6607 1.1 mrg fold_convert (TREE_TYPE (ptr), 6608 1.1 mrg null_pointer_node)); 6609 1.1 mrg gfc_add_expr_to_block (&block, tmp); 6610 1.1 mrg } 6611 1.1 mrg else if (fsym->ts.type == BT_CLASS) 6612 1.1 mrg { 6613 1.1 mrg gfc_symbol *vtab; 6614 1.1 mrg vtab = gfc_find_derived_vtab (fsym->ts.u.derived); 6615 1.1 mrg tmp = gfc_get_symbol_decl (vtab); 6616 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp); 6617 1.1 mrg ptr = gfc_class_vptr_get (parmse.expr); 6618 1.1 mrg gfc_add_modify (&block, ptr, 6619 1.1 mrg fold_convert (TREE_TYPE (ptr), tmp)); 6620 1.1 mrg gfc_add_expr_to_block (&block, tmp); 6621 1.1 mrg } 6622 1.1 mrg 6623 1.1 mrg if (fsym->attr.optional 6624 1.1 mrg && e->expr_type == EXPR_VARIABLE 6625 1.1 mrg && e->symtree->n.sym->attr.optional) 6626 1.1 mrg { 6627 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, 6628 1.1 mrg void_type_node, 6629 1.1 mrg gfc_conv_expr_present (e->symtree->n.sym), 6630 1.1 mrg gfc_finish_block (&block), 6631 1.1 mrg build_empty_stmt (input_location)); 6632 1.1 mrg } 6633 1.1 mrg else 6634 1.1 mrg tmp = gfc_finish_block (&block); 6635 1.1 mrg 6636 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 6637 1.1 mrg } 6638 1.1 mrg 6639 1.1 mrg /* A class array element needs converting back to be a 6640 1.1 mrg class object, if the formal argument is a class object. */ 6641 1.1 mrg if (fsym && fsym->ts.type == BT_CLASS 6642 1.1 mrg && e->ts.type == BT_CLASS 6643 1.1 mrg && ((CLASS_DATA (fsym)->as 6644 1.1 mrg && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK) 6645 1.1 mrg || CLASS_DATA (e)->attr.dimension)) 6646 1.1 mrg gfc_conv_class_to_class (&parmse, e, fsym->ts, false, 6647 1.1 mrg fsym->attr.intent != INTENT_IN 6648 1.1 mrg && (CLASS_DATA (fsym)->attr.class_pointer 6649 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable), 6650 1.1 mrg fsym->attr.optional 6651 1.1 mrg && e->expr_type == EXPR_VARIABLE 6652 1.1 mrg && e->symtree->n.sym->attr.optional, 6653 1.1 mrg CLASS_DATA (fsym)->attr.class_pointer 6654 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable); 6655 1.1 mrg 6656 1.1 mrg if (fsym && (fsym->ts.type == BT_DERIVED 6657 1.1 mrg || fsym->ts.type == BT_ASSUMED) 6658 1.1 mrg && e->ts.type == BT_CLASS 6659 1.1 mrg && !CLASS_DATA (e)->attr.dimension 6660 1.1 mrg && !CLASS_DATA (e)->attr.codimension) 6661 1.1 mrg { 6662 1.1 mrg parmse.expr = gfc_class_data_get (parmse.expr); 6663 1.1 mrg /* The result is a class temporary, whose _data component 6664 1.1 mrg must be freed to avoid a memory leak. */ 6665 1.1 mrg if (e->expr_type == EXPR_FUNCTION 6666 1.1 mrg && CLASS_DATA (e)->attr.allocatable) 6667 1.1 mrg { 6668 1.1 mrg tree zero; 6669 1.1 mrg 6670 1.1 mrg gfc_expr *var; 6671 1.1 mrg 6672 1.1 mrg /* Borrow the function symbol to make a call to 6673 1.1 mrg gfc_add_finalizer_call and then restore it. */ 6674 1.1 mrg tmp = e->symtree->n.sym->backend_decl; 6675 1.1 mrg e->symtree->n.sym->backend_decl 6676 1.1 mrg = TREE_OPERAND (parmse.expr, 0); 6677 1.1 mrg e->symtree->n.sym->attr.flavor = FL_VARIABLE; 6678 1.1 mrg var = gfc_lval_expr_from_sym (e->symtree->n.sym); 6679 1.1 mrg finalized = gfc_add_finalizer_call (&parmse.post, 6680 1.1 mrg var); 6681 1.1 mrg gfc_free_expr (var); 6682 1.1 mrg e->symtree->n.sym->backend_decl = tmp; 6683 1.1 mrg e->symtree->n.sym->attr.flavor = FL_PROCEDURE; 6684 1.1 mrg 6685 1.1 mrg /* Then free the class _data. */ 6686 1.1 mrg zero = build_int_cst (TREE_TYPE (parmse.expr), 0); 6687 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, 6688 1.1 mrg logical_type_node, 6689 1.1 mrg parmse.expr, zero); 6690 1.1 mrg tmp = build3_v (COND_EXPR, tmp, 6691 1.1 mrg gfc_call_free (parmse.expr), 6692 1.1 mrg build_empty_stmt (input_location)); 6693 1.1 mrg gfc_add_expr_to_block (&parmse.post, tmp); 6694 1.1 mrg gfc_add_modify (&parmse.post, parmse.expr, zero); 6695 1.1 mrg } 6696 1.1 mrg } 6697 1.1 mrg 6698 1.1 mrg /* Wrap scalar variable in a descriptor. We need to convert 6699 1.1 mrg the address of a pointer back to the pointer itself before, 6700 1.1 mrg we can assign it to the data field. */ 6701 1.1 mrg 6702 1.1 mrg if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK 6703 1.1 mrg && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL) 6704 1.1 mrg { 6705 1.1 mrg tmp = parmse.expr; 6706 1.1 mrg if (TREE_CODE (tmp) == ADDR_EXPR) 6707 1.1 mrg tmp = TREE_OPERAND (tmp, 0); 6708 1.1 mrg parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp, 6709 1.1 mrg fsym->attr); 6710 1.1 mrg parmse.expr = gfc_build_addr_expr (NULL_TREE, 6711 1.1 mrg parmse.expr); 6712 1.1 mrg } 6713 1.1 mrg else if (fsym && e->expr_type != EXPR_NULL 6714 1.1 mrg && ((fsym->attr.pointer 6715 1.1 mrg && fsym->attr.flavor != FL_PROCEDURE) 6716 1.1 mrg || (fsym->attr.proc_pointer 6717 1.1 mrg && !(e->expr_type == EXPR_VARIABLE 6718 1.1 mrg && e->symtree->n.sym->attr.dummy)) 6719 1.1 mrg || (fsym->attr.proc_pointer 6720 1.1 mrg && e->expr_type == EXPR_VARIABLE 6721 1.1 mrg && gfc_is_proc_ptr_comp (e)) 6722 1.1 mrg || (fsym->attr.allocatable 6723 1.1 mrg && fsym->attr.flavor != FL_PROCEDURE))) 6724 1.1 mrg { 6725 1.1 mrg /* Scalar pointer dummy args require an extra level of 6726 1.1 mrg indirection. The null pointer already contains 6727 1.1 mrg this level of indirection. */ 6728 1.1 mrg parm_kind = SCALAR_POINTER; 6729 1.1 mrg parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr); 6730 1.1 mrg } 6731 1.1 mrg } 6732 1.1 mrg } 6733 1.1 mrg else if (e->ts.type == BT_CLASS 6734 1.1 mrg && fsym && fsym->ts.type == BT_CLASS 6735 1.1 mrg && (CLASS_DATA (fsym)->attr.dimension 6736 1.1 mrg || CLASS_DATA (fsym)->attr.codimension)) 6737 1.1 mrg { 6738 1.1 mrg /* Pass a class array. */ 6739 1.1 mrg parmse.use_offset = 1; 6740 1.1 mrg gfc_conv_expr_descriptor (&parmse, e); 6741 1.1 mrg 6742 1.1 mrg /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 6743 1.1 mrg allocated on entry, it must be deallocated. */ 6744 1.1 mrg if (fsym->attr.intent == INTENT_OUT 6745 1.1 mrg && CLASS_DATA (fsym)->attr.allocatable) 6746 1.1 mrg { 6747 1.1 mrg stmtblock_t block; 6748 1.1 mrg tree ptr; 6749 1.1 mrg 6750 1.1 mrg gfc_init_block (&block); 6751 1.1 mrg ptr = parmse.expr; 6752 1.1 mrg ptr = gfc_class_data_get (ptr); 6753 1.1 mrg 6754 1.1 mrg tmp = gfc_deallocate_with_status (ptr, NULL_TREE, 6755 1.1 mrg NULL_TREE, NULL_TREE, 6756 1.1 mrg NULL_TREE, true, e, 6757 1.1 mrg GFC_CAF_COARRAY_NOCOARRAY); 6758 1.1 mrg gfc_add_expr_to_block (&block, tmp); 6759 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, 6760 1.1 mrg void_type_node, ptr, 6761 1.1 mrg null_pointer_node); 6762 1.1 mrg gfc_add_expr_to_block (&block, tmp); 6763 1.1 mrg gfc_reset_vptr (&block, e); 6764 1.1 mrg 6765 1.1 mrg if (fsym->attr.optional 6766 1.1 mrg && e->expr_type == EXPR_VARIABLE 6767 1.1 mrg && (!e->ref 6768 1.1 mrg || (e->ref->type == REF_ARRAY 6769 1.1 mrg && e->ref->u.ar.type != AR_FULL)) 6770 1.1 mrg && e->symtree->n.sym->attr.optional) 6771 1.1 mrg { 6772 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, 6773 1.1 mrg void_type_node, 6774 1.1 mrg gfc_conv_expr_present (e->symtree->n.sym), 6775 1.1 mrg gfc_finish_block (&block), 6776 1.1 mrg build_empty_stmt (input_location)); 6777 1.1 mrg } 6778 1.1 mrg else 6779 1.1 mrg tmp = gfc_finish_block (&block); 6780 1.1 mrg 6781 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 6782 1.1 mrg } 6783 1.1 mrg 6784 1.1 mrg /* The conversion does not repackage the reference to a class 6785 1.1 mrg array - _data descriptor. */ 6786 1.1 mrg gfc_conv_class_to_class (&parmse, e, fsym->ts, false, 6787 1.1 mrg fsym->attr.intent != INTENT_IN 6788 1.1 mrg && (CLASS_DATA (fsym)->attr.class_pointer 6789 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable), 6790 1.1 mrg fsym->attr.optional 6791 1.1 mrg && e->expr_type == EXPR_VARIABLE 6792 1.1 mrg && e->symtree->n.sym->attr.optional, 6793 1.1 mrg CLASS_DATA (fsym)->attr.class_pointer 6794 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable); 6795 1.1 mrg } 6796 1.1 mrg else 6797 1.1 mrg { 6798 1.1 mrg /* If the argument is a function call that may not create 6799 1.1 mrg a temporary for the result, we have to check that we 6800 1.1 mrg can do it, i.e. that there is no alias between this 6801 1.1 mrg argument and another one. */ 6802 1.1 mrg if (gfc_get_noncopying_intrinsic_argument (e) != NULL) 6803 1.1 mrg { 6804 1.1 mrg gfc_expr *iarg; 6805 1.1 mrg sym_intent intent; 6806 1.1 mrg 6807 1.1 mrg if (fsym != NULL) 6808 1.1 mrg intent = fsym->attr.intent; 6809 1.1 mrg else 6810 1.1 mrg intent = INTENT_UNKNOWN; 6811 1.1 mrg 6812 1.1 mrg if (gfc_check_fncall_dependency (e, intent, sym, args, 6813 1.1 mrg NOT_ELEMENTAL)) 6814 1.1 mrg parmse.force_tmp = 1; 6815 1.1 mrg 6816 1.1 mrg iarg = e->value.function.actual->expr; 6817 1.1 mrg 6818 1.1 mrg /* Temporary needed if aliasing due to host association. */ 6819 1.1 mrg if (sym->attr.contained 6820 1.1 mrg && !sym->attr.pure 6821 1.1 mrg && !sym->attr.implicit_pure 6822 1.1 mrg && !sym->attr.use_assoc 6823 1.1 mrg && iarg->expr_type == EXPR_VARIABLE 6824 1.1 mrg && sym->ns == iarg->symtree->n.sym->ns) 6825 1.1 mrg parmse.force_tmp = 1; 6826 1.1 mrg 6827 1.1 mrg /* Ditto within module. */ 6828 1.1 mrg if (sym->attr.use_assoc 6829 1.1 mrg && !sym->attr.pure 6830 1.1 mrg && !sym->attr.implicit_pure 6831 1.1 mrg && iarg->expr_type == EXPR_VARIABLE 6832 1.1 mrg && sym->module == iarg->symtree->n.sym->module) 6833 1.1 mrg parmse.force_tmp = 1; 6834 1.1 mrg } 6835 1.1 mrg 6836 1.1 mrg /* Special case for assumed-rank arrays: when passing an 6837 1.1 mrg argument to a nonallocatable/nonpointer dummy, the bounds have 6838 1.1 mrg to be reset as otherwise a last-dim ubound of -1 is 6839 1.1 mrg indistinguishable from an assumed-size array in the callee. */ 6840 1.1 mrg if (!sym->attr.is_bind_c && e && fsym && fsym->as 6841 1.1 mrg && fsym->as->type == AS_ASSUMED_RANK 6842 1.1 mrg && e->rank != -1 6843 1.1 mrg && e->expr_type == EXPR_VARIABLE 6844 1.1 mrg && ((fsym->ts.type == BT_CLASS 6845 1.1 mrg && !CLASS_DATA (fsym)->attr.class_pointer 6846 1.1 mrg && !CLASS_DATA (fsym)->attr.allocatable) 6847 1.1 mrg || (fsym->ts.type != BT_CLASS 6848 1.1 mrg && !fsym->attr.pointer && !fsym->attr.allocatable))) 6849 1.1 mrg { 6850 1.1 mrg /* Change AR_FULL to a (:,:,:) ref to force bounds update. */ 6851 1.1 mrg gfc_ref *ref; 6852 1.1 mrg for (ref = e->ref; ref->next; ref = ref->next) 6853 1.1 mrg ; 6854 1.1 mrg if (ref->u.ar.type == AR_FULL 6855 1.1 mrg && ref->u.ar.as->type != AS_ASSUMED_SIZE) 6856 1.1 mrg ref->u.ar.type = AR_SECTION; 6857 1.1 mrg } 6858 1.1 mrg 6859 1.1 mrg if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL)) 6860 1.1 mrg /* Implement F2018, 18.3.6, list item (5), bullet point 2. */ 6861 1.1 mrg gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym); 6862 1.1 mrg 6863 1.1 mrg else if (e->expr_type == EXPR_VARIABLE 6864 1.1 mrg && is_subref_array (e) 6865 1.1 mrg && !(fsym && fsym->attr.pointer)) 6866 1.1 mrg /* The actual argument is a component reference to an 6867 1.1 mrg array of derived types. In this case, the argument 6868 1.1 mrg is converted to a temporary, which is passed and then 6869 1.1 mrg written back after the procedure call. */ 6870 1.1 mrg gfc_conv_subref_array_arg (&parmse, e, nodesc_arg, 6871 1.1 mrg fsym ? fsym->attr.intent : INTENT_INOUT, 6872 1.1 mrg fsym && fsym->attr.pointer); 6873 1.1 mrg 6874 1.1 mrg else if (e->ts.type == BT_CLASS && CLASS_DATA (e)->as 6875 1.1 mrg && CLASS_DATA (e)->as->type == AS_ASSUMED_SIZE 6876 1.1 mrg && nodesc_arg && fsym->ts.type == BT_DERIVED) 6877 1.1 mrg /* An assumed size class actual argument being passed to 6878 1.1 mrg a 'no descriptor' formal argument just requires the 6879 1.1 mrg data pointer to be passed. For class dummy arguments 6880 1.1 mrg this is stored in the symbol backend decl.. */ 6881 1.1 mrg parmse.expr = e->symtree->n.sym->backend_decl; 6882 1.1 mrg 6883 1.1 mrg else if (gfc_is_class_array_ref (e, NULL) 6884 1.1 mrg && fsym && fsym->ts.type == BT_DERIVED) 6885 1.1 mrg /* The actual argument is a component reference to an 6886 1.1 mrg array of derived types. In this case, the argument 6887 1.1 mrg is converted to a temporary, which is passed and then 6888 1.1 mrg written back after the procedure call. 6889 1.1 mrg OOP-TODO: Insert code so that if the dynamic type is 6890 1.1 mrg the same as the declared type, copy-in/copy-out does 6891 1.1 mrg not occur. */ 6892 1.1 mrg gfc_conv_subref_array_arg (&parmse, e, nodesc_arg, 6893 1.1 mrg fsym->attr.intent, 6894 1.1 mrg fsym->attr.pointer); 6895 1.1 mrg 6896 1.1 mrg else if (gfc_is_class_array_function (e) 6897 1.1 mrg && fsym && fsym->ts.type == BT_DERIVED) 6898 1.1 mrg /* See previous comment. For function actual argument, 6899 1.1 mrg the write out is not needed so the intent is set as 6900 1.1 mrg intent in. */ 6901 1.1 mrg { 6902 1.1 mrg e->must_finalize = 1; 6903 1.1 mrg gfc_conv_subref_array_arg (&parmse, e, nodesc_arg, 6904 1.1 mrg INTENT_IN, fsym->attr.pointer); 6905 1.1 mrg } 6906 1.1 mrg else if (fsym && fsym->attr.contiguous 6907 1.1 mrg && !gfc_is_simply_contiguous (e, false, true) 6908 1.1 mrg && gfc_expr_is_variable (e)) 6909 1.1 mrg { 6910 1.1 mrg gfc_conv_subref_array_arg (&parmse, e, nodesc_arg, 6911 1.1 mrg fsym->attr.intent, 6912 1.1 mrg fsym->attr.pointer); 6913 1.1 mrg } 6914 1.1 mrg else 6915 1.1 mrg /* This is where we introduce a temporary to store the 6916 1.1 mrg result of a non-lvalue array expression. */ 6917 1.1 mrg gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym, 6918 1.1 mrg sym->name, NULL); 6919 1.1 mrg 6920 1.1 mrg /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 6921 1.1 mrg allocated on entry, it must be deallocated. 6922 1.1 mrg CFI descriptors are handled elsewhere. */ 6923 1.1 mrg if (fsym && fsym->attr.allocatable 6924 1.1 mrg && fsym->attr.intent == INTENT_OUT 6925 1.1 mrg && !is_CFI_desc (fsym, NULL)) 6926 1.1 mrg { 6927 1.1 mrg if (fsym->ts.type == BT_DERIVED 6928 1.1 mrg && fsym->ts.u.derived->attr.alloc_comp) 6929 1.1 mrg { 6930 1.1 mrg // deallocate the components first 6931 1.1 mrg tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived, 6932 1.1 mrg parmse.expr, e->rank); 6933 1.1 mrg /* But check whether dummy argument is optional. */ 6934 1.1 mrg if (tmp != NULL_TREE 6935 1.1 mrg && fsym->attr.optional 6936 1.1 mrg && e->expr_type == EXPR_VARIABLE 6937 1.1 mrg && e->symtree->n.sym->attr.optional) 6938 1.1 mrg { 6939 1.1 mrg tree present; 6940 1.1 mrg present = gfc_conv_expr_present (e->symtree->n.sym); 6941 1.1 mrg tmp = build3_v (COND_EXPR, present, tmp, 6942 1.1 mrg build_empty_stmt (input_location)); 6943 1.1 mrg } 6944 1.1 mrg if (tmp != NULL_TREE) 6945 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 6946 1.1 mrg } 6947 1.1 mrg 6948 1.1 mrg tmp = parmse.expr; 6949 1.1 mrg /* With bind(C), the actual argument is replaced by a bind-C 6950 1.1 mrg descriptor; in this case, the data component arrives here, 6951 1.1 mrg which shall not be dereferenced, but still freed and 6952 1.1 mrg nullified. */ 6953 1.1 mrg if (TREE_TYPE(tmp) != pvoid_type_node) 6954 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, 6955 1.1 mrg parmse.expr); 6956 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp))) 6957 1.1 mrg tmp = gfc_conv_descriptor_data_get (tmp); 6958 1.1 mrg tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE, 6959 1.1 mrg NULL_TREE, NULL_TREE, true, 6960 1.1 mrg e, 6961 1.1 mrg GFC_CAF_COARRAY_NOCOARRAY); 6962 1.1 mrg if (fsym->attr.optional 6963 1.1 mrg && e->expr_type == EXPR_VARIABLE 6964 1.1 mrg && e->symtree->n.sym->attr.optional) 6965 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, 6966 1.1 mrg void_type_node, 6967 1.1 mrg gfc_conv_expr_present (e->symtree->n.sym), 6968 1.1 mrg tmp, build_empty_stmt (input_location)); 6969 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 6970 1.1 mrg } 6971 1.1 mrg } 6972 1.1 mrg } 6973 1.1 mrg /* Special case for an assumed-rank dummy argument. */ 6974 1.1 mrg if (!sym->attr.is_bind_c && e && fsym && e->rank > 0 6975 1.1 mrg && (fsym->ts.type == BT_CLASS 6976 1.1 mrg ? (CLASS_DATA (fsym)->as 6977 1.1 mrg && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK) 6978 1.1 mrg : (fsym->as && fsym->as->type == AS_ASSUMED_RANK))) 6979 1.1 mrg { 6980 1.1 mrg if (fsym->ts.type == BT_CLASS 6981 1.1 mrg ? (CLASS_DATA (fsym)->attr.class_pointer 6982 1.1 mrg || CLASS_DATA (fsym)->attr.allocatable) 6983 1.1 mrg : (fsym->attr.pointer || fsym->attr.allocatable)) 6984 1.1 mrg { 6985 1.1 mrg /* Unallocated allocatable arrays and unassociated pointer 6986 1.1 mrg arrays need their dtype setting if they are argument 6987 1.1 mrg associated with assumed rank dummies to set the rank. */ 6988 1.1 mrg set_dtype_for_unallocated (&parmse, e); 6989 1.1 mrg } 6990 1.1 mrg else if (e->expr_type == EXPR_VARIABLE 6991 1.1 mrg && e->symtree->n.sym->attr.dummy 6992 1.1 mrg && (e->ts.type == BT_CLASS 6993 1.1 mrg ? (e->ref && e->ref->next 6994 1.1 mrg && e->ref->next->type == REF_ARRAY 6995 1.1 mrg && e->ref->next->u.ar.type == AR_FULL 6996 1.1 mrg && e->ref->next->u.ar.as->type == AS_ASSUMED_SIZE) 6997 1.1 mrg : (e->ref && e->ref->type == REF_ARRAY 6998 1.1 mrg && e->ref->u.ar.type == AR_FULL 6999 1.1 mrg && e->ref->u.ar.as->type == AS_ASSUMED_SIZE))) 7000 1.1 mrg { 7001 1.1 mrg /* Assumed-size actual to assumed-rank dummy requires 7002 1.1 mrg dim[rank-1].ubound = -1. */ 7003 1.1 mrg tree minus_one; 7004 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, parmse.expr); 7005 1.1 mrg if (fsym->ts.type == BT_CLASS) 7006 1.1 mrg tmp = gfc_class_data_get (tmp); 7007 1.1 mrg minus_one = build_int_cst (gfc_array_index_type, -1); 7008 1.1 mrg gfc_conv_descriptor_ubound_set (&parmse.pre, tmp, 7009 1.1 mrg gfc_rank_cst[e->rank - 1], 7010 1.1 mrg minus_one); 7011 1.1 mrg } 7012 1.1 mrg } 7013 1.1 mrg 7014 1.1 mrg /* The case with fsym->attr.optional is that of a user subroutine 7015 1.1 mrg with an interface indicating an optional argument. When we call 7016 1.1 mrg an intrinsic subroutine, however, fsym is NULL, but we might still 7017 1.1 mrg have an optional argument, so we proceed to the substitution 7018 1.1 mrg just in case. */ 7019 1.1 mrg if (e && (fsym == NULL || fsym->attr.optional)) 7020 1.1 mrg { 7021 1.1 mrg /* If an optional argument is itself an optional dummy argument, 7022 1.1 mrg check its presence and substitute a null if absent. This is 7023 1.1 mrg only needed when passing an array to an elemental procedure 7024 1.1 mrg as then array elements are accessed - or no NULL pointer is 7025 1.1 mrg allowed and a "1" or "0" should be passed if not present. 7026 1.1 mrg When passing a non-array-descriptor full array to a 7027 1.1 mrg non-array-descriptor dummy, no check is needed. For 7028 1.1 mrg array-descriptor actual to array-descriptor dummy, see 7029 1.1 mrg PR 41911 for why a check has to be inserted. 7030 1.1 mrg fsym == NULL is checked as intrinsics required the descriptor 7031 1.1 mrg but do not always set fsym. 7032 1.1 mrg Also, it is necessary to pass a NULL pointer to library routines 7033 1.1 mrg which usually ignore optional arguments, so they can handle 7034 1.1 mrg these themselves. */ 7035 1.1 mrg if (e->expr_type == EXPR_VARIABLE 7036 1.1 mrg && e->symtree->n.sym->attr.optional 7037 1.1 mrg && (((e->rank != 0 && elemental_proc) 7038 1.1 mrg || e->representation.length || e->ts.type == BT_CHARACTER 7039 1.1 mrg || (e->rank != 0 7040 1.1 mrg && (fsym == NULL 7041 1.1 mrg || (fsym->as 7042 1.1 mrg && (fsym->as->type == AS_ASSUMED_SHAPE 7043 1.1 mrg || fsym->as->type == AS_ASSUMED_RANK 7044 1.1 mrg || fsym->as->type == AS_DEFERRED))))) 7045 1.1 mrg || se->ignore_optional)) 7046 1.1 mrg gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts, 7047 1.1 mrg e->representation.length); 7048 1.1 mrg } 7049 1.1 mrg 7050 1.1 mrg if (fsym && e) 7051 1.1 mrg { 7052 1.1 mrg /* Obtain the character length of an assumed character length 7053 1.1 mrg length procedure from the typespec. */ 7054 1.1 mrg if (fsym->ts.type == BT_CHARACTER 7055 1.1 mrg && parmse.string_length == NULL_TREE 7056 1.1 mrg && e->ts.type == BT_PROCEDURE 7057 1.1 mrg && e->symtree->n.sym->ts.type == BT_CHARACTER 7058 1.1 mrg && e->symtree->n.sym->ts.u.cl->length != NULL 7059 1.1 mrg && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT) 7060 1.1 mrg { 7061 1.1 mrg gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl); 7062 1.1 mrg parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl; 7063 1.1 mrg } 7064 1.1 mrg } 7065 1.1 mrg 7066 1.1 mrg if (fsym && need_interface_mapping && e) 7067 1.1 mrg gfc_add_interface_mapping (&mapping, fsym, &parmse, e); 7068 1.1 mrg 7069 1.1 mrg gfc_add_block_to_block (&se->pre, &parmse.pre); 7070 1.1 mrg gfc_add_block_to_block (&post, &parmse.post); 7071 1.1 mrg 7072 1.1 mrg /* Allocated allocatable components of derived types must be 7073 1.1 mrg deallocated for non-variable scalars, array arguments to elemental 7074 1.1 mrg procedures, and array arguments with descriptor to non-elemental 7075 1.1 mrg procedures. As bounds information for descriptorless arrays is no 7076 1.1 mrg longer available here, they are dealt with in trans-array.cc 7077 1.1 mrg (gfc_conv_array_parameter). */ 7078 1.1 mrg if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS) 7079 1.1 mrg && e->ts.u.derived->attr.alloc_comp 7080 1.1 mrg && (e->rank == 0 || elemental_proc || !nodesc_arg) 7081 1.1 mrg && !expr_may_alias_variables (e, elemental_proc)) 7082 1.1 mrg { 7083 1.1 mrg int parm_rank; 7084 1.1 mrg /* It is known the e returns a structure type with at least one 7085 1.1 mrg allocatable component. When e is a function, ensure that the 7086 1.1 mrg function is called once only by using a temporary variable. */ 7087 1.1 mrg if (!DECL_P (parmse.expr)) 7088 1.1 mrg parmse.expr = gfc_evaluate_now_loc (input_location, 7089 1.1 mrg parmse.expr, &se->pre); 7090 1.1 mrg 7091 1.1 mrg if (fsym && fsym->attr.value) 7092 1.1 mrg tmp = parmse.expr; 7093 1.1 mrg else 7094 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, 7095 1.1 mrg parmse.expr); 7096 1.1 mrg 7097 1.1 mrg parm_rank = e->rank; 7098 1.1 mrg switch (parm_kind) 7099 1.1 mrg { 7100 1.1 mrg case (ELEMENTAL): 7101 1.1 mrg case (SCALAR): 7102 1.1 mrg parm_rank = 0; 7103 1.1 mrg break; 7104 1.1 mrg 7105 1.1 mrg case (SCALAR_POINTER): 7106 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, 7107 1.1 mrg tmp); 7108 1.1 mrg break; 7109 1.1 mrg } 7110 1.1 mrg 7111 1.1 mrg if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS) 7112 1.1 mrg { 7113 1.1 mrg /* The derived type is passed to gfc_deallocate_alloc_comp. 7114 1.1 mrg Therefore, class actuals can be handled correctly but derived 7115 1.1 mrg types passed to class formals need the _data component. */ 7116 1.1 mrg tmp = gfc_class_data_get (tmp); 7117 1.1 mrg if (!CLASS_DATA (fsym)->attr.dimension) 7118 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp); 7119 1.1 mrg } 7120 1.1 mrg 7121 1.1 mrg if (e->expr_type == EXPR_OP 7122 1.1 mrg && e->value.op.op == INTRINSIC_PARENTHESES 7123 1.1 mrg && e->value.op.op1->expr_type == EXPR_VARIABLE) 7124 1.1 mrg { 7125 1.1 mrg tree local_tmp; 7126 1.1 mrg local_tmp = gfc_evaluate_now (tmp, &se->pre); 7127 1.1 mrg local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, 7128 1.1 mrg parm_rank, 0); 7129 1.1 mrg gfc_add_expr_to_block (&se->post, local_tmp); 7130 1.1 mrg } 7131 1.1 mrg 7132 1.1 mrg if (!finalized && !e->must_finalize) 7133 1.1 mrg { 7134 1.1 mrg bool scalar_res_outside_loop; 7135 1.1 mrg scalar_res_outside_loop = e->expr_type == EXPR_FUNCTION 7136 1.1 mrg && parm_rank == 0 7137 1.1 mrg && parmse.loop; 7138 1.1 mrg 7139 1.1 mrg /* Scalars passed to an assumed rank argument are converted to 7140 1.1 mrg a descriptor. Obtain the data field before deallocating any 7141 1.1 mrg allocatable components. */ 7142 1.1 mrg if (parm_rank == 0 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp))) 7143 1.1 mrg tmp = gfc_conv_descriptor_data_get (tmp); 7144 1.1 mrg 7145 1.1 mrg if (scalar_res_outside_loop) 7146 1.1 mrg { 7147 1.1 mrg /* Go through the ss chain to find the argument and use 7148 1.1 mrg the stored value. */ 7149 1.1 mrg gfc_ss *tmp_ss = parmse.loop->ss; 7150 1.1 mrg for (; tmp_ss; tmp_ss = tmp_ss->next) 7151 1.1 mrg if (tmp_ss->info 7152 1.1 mrg && tmp_ss->info->expr == e 7153 1.1 mrg && tmp_ss->info->data.scalar.value != NULL_TREE) 7154 1.1 mrg { 7155 1.1 mrg tmp = tmp_ss->info->data.scalar.value; 7156 1.1 mrg break; 7157 1.1 mrg } 7158 1.1 mrg } 7159 1.1 mrg 7160 1.1 mrg STRIP_NOPS (tmp); 7161 1.1 mrg 7162 1.1 mrg if (derived_array != NULL_TREE) 7163 1.1 mrg tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, 7164 1.1 mrg derived_array, 7165 1.1 mrg parm_rank); 7166 1.1 mrg else if ((e->ts.type == BT_CLASS 7167 1.1 mrg && GFC_CLASS_TYPE_P (TREE_TYPE (tmp))) 7168 1.1 mrg || e->ts.type == BT_DERIVED) 7169 1.1 mrg tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, 7170 1.1 mrg parm_rank); 7171 1.1 mrg else if (e->ts.type == BT_CLASS) 7172 1.1 mrg tmp = gfc_deallocate_alloc_comp (CLASS_DATA (e)->ts.u.derived, 7173 1.1 mrg tmp, parm_rank); 7174 1.1 mrg 7175 1.1 mrg if (scalar_res_outside_loop) 7176 1.1 mrg gfc_add_expr_to_block (&parmse.loop->post, tmp); 7177 1.1 mrg else 7178 1.1 mrg gfc_prepend_expr_to_block (&post, tmp); 7179 1.1 mrg } 7180 1.1 mrg } 7181 1.1 mrg 7182 1.1 mrg /* Add argument checking of passing an unallocated/NULL actual to 7183 1.1 mrg a nonallocatable/nonpointer dummy. */ 7184 1.1 mrg 7185 1.1 mrg if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL) 7186 1.1 mrg { 7187 1.1 mrg symbol_attribute attr; 7188 1.1 mrg char *msg; 7189 1.1 mrg tree cond; 7190 1.1 mrg tree tmp; 7191 1.1 mrg symbol_attribute fsym_attr; 7192 1.1 mrg 7193 1.1 mrg if (fsym) 7194 1.1 mrg { 7195 1.1 mrg if (fsym->ts.type == BT_CLASS) 7196 1.1 mrg { 7197 1.1 mrg fsym_attr = CLASS_DATA (fsym)->attr; 7198 1.1 mrg fsym_attr.pointer = fsym_attr.class_pointer; 7199 1.1 mrg } 7200 1.1 mrg else 7201 1.1 mrg fsym_attr = fsym->attr; 7202 1.1 mrg } 7203 1.1 mrg 7204 1.1 mrg if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION) 7205 1.1 mrg attr = gfc_expr_attr (e); 7206 1.1 mrg else 7207 1.1 mrg goto end_pointer_check; 7208 1.1 mrg 7209 1.1 mrg /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated 7210 1.1 mrg allocatable to an optional dummy, cf. 12.5.2.12. */ 7211 1.1 mrg if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer 7212 1.1 mrg && (gfc_option.allow_std & GFC_STD_F2008) != 0) 7213 1.1 mrg goto end_pointer_check; 7214 1.1 mrg 7215 1.1 mrg if (attr.optional) 7216 1.1 mrg { 7217 1.1 mrg /* If the actual argument is an optional pointer/allocatable and 7218 1.1 mrg the formal argument takes an nonpointer optional value, 7219 1.1 mrg it is invalid to pass a non-present argument on, even 7220 1.1 mrg though there is no technical reason for this in gfortran. 7221 1.1 mrg See Fortran 2003, Section 12.4.1.6 item (7)+(8). */ 7222 1.1 mrg tree present, null_ptr, type; 7223 1.1 mrg 7224 1.1 mrg if (attr.allocatable 7225 1.1 mrg && (fsym == NULL || !fsym_attr.allocatable)) 7226 1.1 mrg msg = xasprintf ("Allocatable actual argument '%s' is not " 7227 1.1 mrg "allocated or not present", 7228 1.1 mrg e->symtree->n.sym->name); 7229 1.1 mrg else if (attr.pointer 7230 1.1 mrg && (fsym == NULL || !fsym_attr.pointer)) 7231 1.1 mrg msg = xasprintf ("Pointer actual argument '%s' is not " 7232 1.1 mrg "associated or not present", 7233 1.1 mrg e->symtree->n.sym->name); 7234 1.1 mrg else if (attr.proc_pointer && !e->value.function.actual 7235 1.1 mrg && (fsym == NULL || !fsym_attr.proc_pointer)) 7236 1.1 mrg msg = xasprintf ("Proc-pointer actual argument '%s' is not " 7237 1.1 mrg "associated or not present", 7238 1.1 mrg e->symtree->n.sym->name); 7239 1.1 mrg else 7240 1.1 mrg goto end_pointer_check; 7241 1.1 mrg 7242 1.1 mrg present = gfc_conv_expr_present (e->symtree->n.sym); 7243 1.1 mrg type = TREE_TYPE (present); 7244 1.1 mrg present = fold_build2_loc (input_location, EQ_EXPR, 7245 1.1 mrg logical_type_node, present, 7246 1.1 mrg fold_convert (type, 7247 1.1 mrg null_pointer_node)); 7248 1.1 mrg type = TREE_TYPE (parmse.expr); 7249 1.1 mrg null_ptr = fold_build2_loc (input_location, EQ_EXPR, 7250 1.1 mrg logical_type_node, parmse.expr, 7251 1.1 mrg fold_convert (type, 7252 1.1 mrg null_pointer_node)); 7253 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR, 7254 1.1 mrg logical_type_node, present, null_ptr); 7255 1.1 mrg } 7256 1.1 mrg else 7257 1.1 mrg { 7258 1.1 mrg if (attr.allocatable 7259 1.1 mrg && (fsym == NULL || !fsym_attr.allocatable)) 7260 1.1 mrg msg = xasprintf ("Allocatable actual argument '%s' is not " 7261 1.1 mrg "allocated", e->symtree->n.sym->name); 7262 1.1 mrg else if (attr.pointer 7263 1.1 mrg && (fsym == NULL || !fsym_attr.pointer)) 7264 1.1 mrg msg = xasprintf ("Pointer actual argument '%s' is not " 7265 1.1 mrg "associated", e->symtree->n.sym->name); 7266 1.1 mrg else if (attr.proc_pointer && !e->value.function.actual 7267 1.1 mrg && (fsym == NULL || !fsym_attr.proc_pointer)) 7268 1.1 mrg msg = xasprintf ("Proc-pointer actual argument '%s' is not " 7269 1.1 mrg "associated", e->symtree->n.sym->name); 7270 1.1 mrg else 7271 1.1 mrg goto end_pointer_check; 7272 1.1 mrg 7273 1.1 mrg tmp = parmse.expr; 7274 1.1 mrg if (fsym && fsym->ts.type == BT_CLASS) 7275 1.1 mrg { 7276 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (tmp))) 7277 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp); 7278 1.1 mrg tmp = gfc_class_data_get (tmp); 7279 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp))) 7280 1.1 mrg tmp = gfc_conv_descriptor_data_get (tmp); 7281 1.1 mrg } 7282 1.1 mrg 7283 1.1 mrg /* If the argument is passed by value, we need to strip the 7284 1.1 mrg INDIRECT_REF. */ 7285 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp))) 7286 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp); 7287 1.1 mrg 7288 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, 7289 1.1 mrg logical_type_node, tmp, 7290 1.1 mrg fold_convert (TREE_TYPE (tmp), 7291 1.1 mrg null_pointer_node)); 7292 1.1 mrg } 7293 1.1 mrg 7294 1.1 mrg gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where, 7295 1.1 mrg msg); 7296 1.1 mrg free (msg); 7297 1.1 mrg } 7298 1.1 mrg end_pointer_check: 7299 1.1 mrg 7300 1.1 mrg /* Deferred length dummies pass the character length by reference 7301 1.1 mrg so that the value can be returned. */ 7302 1.1 mrg if (parmse.string_length && fsym && fsym->ts.deferred) 7303 1.1 mrg { 7304 1.1 mrg if (INDIRECT_REF_P (parmse.string_length)) 7305 1.1 mrg /* In chains of functions/procedure calls the string_length already 7306 1.1 mrg is a pointer to the variable holding the length. Therefore 7307 1.1 mrg remove the deref on call. */ 7308 1.1 mrg parmse.string_length = TREE_OPERAND (parmse.string_length, 0); 7309 1.1 mrg else 7310 1.1 mrg { 7311 1.1 mrg tmp = parmse.string_length; 7312 1.1 mrg if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF) 7313 1.1 mrg tmp = gfc_evaluate_now (parmse.string_length, &se->pre); 7314 1.1 mrg parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp); 7315 1.1 mrg } 7316 1.1 mrg } 7317 1.1 mrg 7318 1.1 mrg /* Character strings are passed as two parameters, a length and a 7319 1.1 mrg pointer - except for Bind(c) which only passes the pointer. 7320 1.1 mrg An unlimited polymorphic formal argument likewise does not 7321 1.1 mrg need the length. */ 7322 1.1 mrg if (parmse.string_length != NULL_TREE 7323 1.1 mrg && !sym->attr.is_bind_c 7324 1.1 mrg && !(fsym && UNLIMITED_POLY (fsym))) 7325 1.1 mrg vec_safe_push (stringargs, parmse.string_length); 7326 1.1 mrg 7327 1.1 mrg /* When calling __copy for character expressions to unlimited 7328 1.1 mrg polymorphic entities, the dst argument needs a string length. */ 7329 1.1 mrg if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER 7330 1.1 mrg && startswith (sym->name, "__vtab_CHARACTER") 7331 1.1 mrg && arg->next && arg->next->expr 7332 1.1 mrg && (arg->next->expr->ts.type == BT_DERIVED 7333 1.1 mrg || arg->next->expr->ts.type == BT_CLASS) 7334 1.1 mrg && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic) 7335 1.1 mrg vec_safe_push (stringargs, parmse.string_length); 7336 1.1 mrg 7337 1.1 mrg /* For descriptorless coarrays and assumed-shape coarray dummies, we 7338 1.1 mrg pass the token and the offset as additional arguments. */ 7339 1.1 mrg if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB 7340 1.1 mrg && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension 7341 1.1 mrg && !fsym->attr.allocatable) 7342 1.1 mrg || (fsym->ts.type == BT_CLASS 7343 1.1 mrg && CLASS_DATA (fsym)->attr.codimension 7344 1.1 mrg && !CLASS_DATA (fsym)->attr.allocatable))) 7345 1.1 mrg { 7346 1.1 mrg /* Token and offset. */ 7347 1.1 mrg vec_safe_push (stringargs, null_pointer_node); 7348 1.1 mrg vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0)); 7349 1.1 mrg gcc_assert (fsym->attr.optional); 7350 1.1 mrg } 7351 1.1 mrg else if (fsym && flag_coarray == GFC_FCOARRAY_LIB 7352 1.1 mrg && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension 7353 1.1 mrg && !fsym->attr.allocatable) 7354 1.1 mrg || (fsym->ts.type == BT_CLASS 7355 1.1 mrg && CLASS_DATA (fsym)->attr.codimension 7356 1.1 mrg && !CLASS_DATA (fsym)->attr.allocatable))) 7357 1.1 mrg { 7358 1.1 mrg tree caf_decl, caf_type; 7359 1.1 mrg tree offset, tmp2; 7360 1.1 mrg 7361 1.1 mrg caf_decl = gfc_get_tree_for_caf_expr (e); 7362 1.1 mrg caf_type = TREE_TYPE (caf_decl); 7363 1.1 mrg 7364 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (caf_type) 7365 1.1 mrg && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE 7366 1.1 mrg || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER)) 7367 1.1 mrg tmp = gfc_conv_descriptor_token (caf_decl); 7368 1.1 mrg else if (DECL_LANG_SPECIFIC (caf_decl) 7369 1.1 mrg && GFC_DECL_TOKEN (caf_decl) != NULL_TREE) 7370 1.1 mrg tmp = GFC_DECL_TOKEN (caf_decl); 7371 1.1 mrg else 7372 1.1 mrg { 7373 1.1 mrg gcc_assert (GFC_ARRAY_TYPE_P (caf_type) 7374 1.1 mrg && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE); 7375 1.1 mrg tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type); 7376 1.1 mrg } 7377 1.1 mrg 7378 1.1 mrg vec_safe_push (stringargs, tmp); 7379 1.1 mrg 7380 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (caf_type) 7381 1.1 mrg && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE) 7382 1.1 mrg offset = build_int_cst (gfc_array_index_type, 0); 7383 1.1 mrg else if (DECL_LANG_SPECIFIC (caf_decl) 7384 1.1 mrg && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE) 7385 1.1 mrg offset = GFC_DECL_CAF_OFFSET (caf_decl); 7386 1.1 mrg else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE) 7387 1.1 mrg offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type); 7388 1.1 mrg else 7389 1.1 mrg offset = build_int_cst (gfc_array_index_type, 0); 7390 1.1 mrg 7391 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (caf_type)) 7392 1.1 mrg tmp = gfc_conv_descriptor_data_get (caf_decl); 7393 1.1 mrg else 7394 1.1 mrg { 7395 1.1 mrg gcc_assert (POINTER_TYPE_P (caf_type)); 7396 1.1 mrg tmp = caf_decl; 7397 1.1 mrg } 7398 1.1 mrg 7399 1.1 mrg tmp2 = fsym->ts.type == BT_CLASS 7400 1.1 mrg ? gfc_class_data_get (parmse.expr) : parmse.expr; 7401 1.1 mrg if ((fsym->ts.type != BT_CLASS 7402 1.1 mrg && (fsym->as->type == AS_ASSUMED_SHAPE 7403 1.1 mrg || fsym->as->type == AS_ASSUMED_RANK)) 7404 1.1 mrg || (fsym->ts.type == BT_CLASS 7405 1.1 mrg && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE 7406 1.1 mrg || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK))) 7407 1.1 mrg { 7408 1.1 mrg if (fsym->ts.type == BT_CLASS) 7409 1.1 mrg gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2))); 7410 1.1 mrg else 7411 1.1 mrg { 7412 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2))); 7413 1.1 mrg tmp2 = build_fold_indirect_ref_loc (input_location, tmp2); 7414 1.1 mrg } 7415 1.1 mrg gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2))); 7416 1.1 mrg tmp2 = gfc_conv_descriptor_data_get (tmp2); 7417 1.1 mrg } 7418 1.1 mrg else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2))) 7419 1.1 mrg tmp2 = gfc_conv_descriptor_data_get (tmp2); 7420 1.1 mrg else 7421 1.1 mrg { 7422 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2))); 7423 1.1 mrg } 7424 1.1 mrg 7425 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, 7426 1.1 mrg gfc_array_index_type, 7427 1.1 mrg fold_convert (gfc_array_index_type, tmp2), 7428 1.1 mrg fold_convert (gfc_array_index_type, tmp)); 7429 1.1 mrg offset = fold_build2_loc (input_location, PLUS_EXPR, 7430 1.1 mrg gfc_array_index_type, offset, tmp); 7431 1.1 mrg 7432 1.1 mrg vec_safe_push (stringargs, offset); 7433 1.1 mrg } 7434 1.1 mrg 7435 1.1 mrg vec_safe_push (arglist, parmse.expr); 7436 1.1 mrg } 7437 1.1 mrg gfc_add_block_to_block (&se->pre, &clobbers); 7438 1.1 mrg gfc_finish_interface_mapping (&mapping, &se->pre, &se->post); 7439 1.1 mrg 7440 1.1 mrg if (comp) 7441 1.1 mrg ts = comp->ts; 7442 1.1 mrg else if (sym->ts.type == BT_CLASS) 7443 1.1 mrg ts = CLASS_DATA (sym)->ts; 7444 1.1 mrg else 7445 1.1 mrg ts = sym->ts; 7446 1.1 mrg 7447 1.1 mrg if (ts.type == BT_CHARACTER && sym->attr.is_bind_c) 7448 1.1 mrg se->string_length = build_int_cst (gfc_charlen_type_node, 1); 7449 1.1 mrg else if (ts.type == BT_CHARACTER) 7450 1.1 mrg { 7451 1.1 mrg if (ts.u.cl->length == NULL) 7452 1.1 mrg { 7453 1.1 mrg /* Assumed character length results are not allowed by C418 of the 2003 7454 1.1 mrg standard and are trapped in resolve.cc; except in the case of SPREAD 7455 1.1 mrg (and other intrinsics?) and dummy functions. In the case of SPREAD, 7456 1.1 mrg we take the character length of the first argument for the result. 7457 1.1 mrg For dummies, we have to look through the formal argument list for 7458 1.1 mrg this function and use the character length found there. 7459 1.1 mrg Likewise, we handle the case of deferred-length character dummy 7460 1.1 mrg arguments to intrinsics that determine the characteristics of 7461 1.1 mrg the result, which cannot be deferred-length. */ 7462 1.1 mrg if (expr->value.function.isym) 7463 1.1 mrg ts.deferred = false; 7464 1.1 mrg if (ts.deferred) 7465 1.1 mrg cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen"); 7466 1.1 mrg else if (!sym->attr.dummy) 7467 1.1 mrg cl.backend_decl = (*stringargs)[0]; 7468 1.1 mrg else 7469 1.1 mrg { 7470 1.1 mrg formal = gfc_sym_get_dummy_args (sym->ns->proc_name); 7471 1.1 mrg for (; formal; formal = formal->next) 7472 1.1 mrg if (strcmp (formal->sym->name, sym->name) == 0) 7473 1.1 mrg cl.backend_decl = formal->sym->ts.u.cl->backend_decl; 7474 1.1 mrg } 7475 1.1 mrg len = cl.backend_decl; 7476 1.1 mrg } 7477 1.1 mrg else 7478 1.1 mrg { 7479 1.1 mrg tree tmp; 7480 1.1 mrg 7481 1.1 mrg /* Calculate the length of the returned string. */ 7482 1.1 mrg gfc_init_se (&parmse, NULL); 7483 1.1 mrg if (need_interface_mapping) 7484 1.1 mrg gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length); 7485 1.1 mrg else 7486 1.1 mrg gfc_conv_expr (&parmse, ts.u.cl->length); 7487 1.1 mrg gfc_add_block_to_block (&se->pre, &parmse.pre); 7488 1.1 mrg gfc_add_block_to_block (&se->post, &parmse.post); 7489 1.1 mrg tmp = parmse.expr; 7490 1.1 mrg /* TODO: It would be better to have the charlens as 7491 1.1 mrg gfc_charlen_type_node already when the interface is 7492 1.1 mrg created instead of converting it here (see PR 84615). */ 7493 1.1 mrg tmp = fold_build2_loc (input_location, MAX_EXPR, 7494 1.1 mrg gfc_charlen_type_node, 7495 1.1 mrg fold_convert (gfc_charlen_type_node, tmp), 7496 1.1 mrg build_zero_cst (gfc_charlen_type_node)); 7497 1.1 mrg cl.backend_decl = tmp; 7498 1.1 mrg } 7499 1.1 mrg 7500 1.1 mrg /* Set up a charlen structure for it. */ 7501 1.1 mrg cl.next = NULL; 7502 1.1 mrg cl.length = NULL; 7503 1.1 mrg ts.u.cl = &cl; 7504 1.1 mrg 7505 1.1 mrg len = cl.backend_decl; 7506 1.1 mrg } 7507 1.1 mrg 7508 1.1 mrg byref = (comp && (comp->attr.dimension 7509 1.1 mrg || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c))) 7510 1.1 mrg || (!comp && gfc_return_by_reference (sym)); 7511 1.1 mrg if (byref) 7512 1.1 mrg { 7513 1.1 mrg if (se->direct_byref) 7514 1.1 mrg { 7515 1.1 mrg /* Sometimes, too much indirection can be applied; e.g. for 7516 1.1 mrg function_result = array_valued_recursive_function. */ 7517 1.1 mrg if (TREE_TYPE (TREE_TYPE (se->expr)) 7518 1.1 mrg && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) 7519 1.1 mrg && GFC_DESCRIPTOR_TYPE_P 7520 1.1 mrg (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))))) 7521 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, 7522 1.1 mrg se->expr); 7523 1.1 mrg 7524 1.1 mrg /* If the lhs of an assignment x = f(..) is allocatable and 7525 1.1 mrg f2003 is allowed, we must do the automatic reallocation. 7526 1.1 mrg TODO - deal with intrinsics, without using a temporary. */ 7527 1.1 mrg if (flag_realloc_lhs 7528 1.1 mrg && se->ss && se->ss->loop_chain 7529 1.1 mrg && se->ss->loop_chain->is_alloc_lhs 7530 1.1 mrg && !expr->value.function.isym 7531 1.1 mrg && sym->result->as != NULL) 7532 1.1 mrg { 7533 1.1 mrg /* Evaluate the bounds of the result, if known. */ 7534 1.1 mrg gfc_set_loop_bounds_from_array_spec (&mapping, se, 7535 1.1 mrg sym->result->as); 7536 1.1 mrg 7537 1.1 mrg /* Perform the automatic reallocation. */ 7538 1.1 mrg tmp = gfc_alloc_allocatable_for_assignment (se->loop, 7539 1.1 mrg expr, NULL); 7540 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 7541 1.1 mrg 7542 1.1 mrg /* Pass the temporary as the first argument. */ 7543 1.1 mrg result = info->descriptor; 7544 1.1 mrg } 7545 1.1 mrg else 7546 1.1 mrg result = build_fold_indirect_ref_loc (input_location, 7547 1.1 mrg se->expr); 7548 1.1 mrg vec_safe_push (retargs, se->expr); 7549 1.1 mrg } 7550 1.1 mrg else if (comp && comp->attr.dimension) 7551 1.1 mrg { 7552 1.1 mrg gcc_assert (se->loop && info); 7553 1.1 mrg 7554 1.1 mrg /* Set the type of the array. */ 7555 1.1 mrg tmp = gfc_typenode_for_spec (&comp->ts); 7556 1.1 mrg gcc_assert (se->ss->dimen == se->loop->dimen); 7557 1.1 mrg 7558 1.1 mrg /* Evaluate the bounds of the result, if known. */ 7559 1.1 mrg gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as); 7560 1.1 mrg 7561 1.1 mrg /* If the lhs of an assignment x = f(..) is allocatable and 7562 1.1 mrg f2003 is allowed, we must not generate the function call 7563 1.1 mrg here but should just send back the results of the mapping. 7564 1.1 mrg This is signalled by the function ss being flagged. */ 7565 1.1 mrg if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs) 7566 1.1 mrg { 7567 1.1 mrg gfc_free_interface_mapping (&mapping); 7568 1.1 mrg return has_alternate_specifier; 7569 1.1 mrg } 7570 1.1 mrg 7571 1.1 mrg /* Create a temporary to store the result. In case the function 7572 1.1 mrg returns a pointer, the temporary will be a shallow copy and 7573 1.1 mrg mustn't be deallocated. */ 7574 1.1 mrg callee_alloc = comp->attr.allocatable || comp->attr.pointer; 7575 1.1 mrg gfc_trans_create_temp_array (&se->pre, &se->post, se->ss, 7576 1.1 mrg tmp, NULL_TREE, false, 7577 1.1 mrg !comp->attr.pointer, callee_alloc, 7578 1.1 mrg &se->ss->info->expr->where); 7579 1.1 mrg 7580 1.1 mrg /* Pass the temporary as the first argument. */ 7581 1.1 mrg result = info->descriptor; 7582 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, result); 7583 1.1 mrg vec_safe_push (retargs, tmp); 7584 1.1 mrg } 7585 1.1 mrg else if (!comp && sym->result->attr.dimension) 7586 1.1 mrg { 7587 1.1 mrg gcc_assert (se->loop && info); 7588 1.1 mrg 7589 1.1 mrg /* Set the type of the array. */ 7590 1.1 mrg tmp = gfc_typenode_for_spec (&ts); 7591 1.1 mrg gcc_assert (se->ss->dimen == se->loop->dimen); 7592 1.1 mrg 7593 1.1 mrg /* Evaluate the bounds of the result, if known. */ 7594 1.1 mrg gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as); 7595 1.1 mrg 7596 1.1 mrg /* If the lhs of an assignment x = f(..) is allocatable and 7597 1.1 mrg f2003 is allowed, we must not generate the function call 7598 1.1 mrg here but should just send back the results of the mapping. 7599 1.1 mrg This is signalled by the function ss being flagged. */ 7600 1.1 mrg if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs) 7601 1.1 mrg { 7602 1.1 mrg gfc_free_interface_mapping (&mapping); 7603 1.1 mrg return has_alternate_specifier; 7604 1.1 mrg } 7605 1.1 mrg 7606 1.1 mrg /* Create a temporary to store the result. In case the function 7607 1.1 mrg returns a pointer, the temporary will be a shallow copy and 7608 1.1 mrg mustn't be deallocated. */ 7609 1.1 mrg callee_alloc = sym->attr.allocatable || sym->attr.pointer; 7610 1.1 mrg gfc_trans_create_temp_array (&se->pre, &se->post, se->ss, 7611 1.1 mrg tmp, NULL_TREE, false, 7612 1.1 mrg !sym->attr.pointer, callee_alloc, 7613 1.1 mrg &se->ss->info->expr->where); 7614 1.1 mrg 7615 1.1 mrg /* Pass the temporary as the first argument. */ 7616 1.1 mrg result = info->descriptor; 7617 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, result); 7618 1.1 mrg vec_safe_push (retargs, tmp); 7619 1.1 mrg } 7620 1.1 mrg else if (ts.type == BT_CHARACTER) 7621 1.1 mrg { 7622 1.1 mrg /* Pass the string length. */ 7623 1.1 mrg type = gfc_get_character_type (ts.kind, ts.u.cl); 7624 1.1 mrg type = build_pointer_type (type); 7625 1.1 mrg 7626 1.1 mrg /* Emit a DECL_EXPR for the VLA type. */ 7627 1.1 mrg tmp = TREE_TYPE (type); 7628 1.1 mrg if (TYPE_SIZE (tmp) 7629 1.1 mrg && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST) 7630 1.1 mrg { 7631 1.1 mrg tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp); 7632 1.1 mrg DECL_ARTIFICIAL (tmp) = 1; 7633 1.1 mrg DECL_IGNORED_P (tmp) = 1; 7634 1.1 mrg tmp = fold_build1_loc (input_location, DECL_EXPR, 7635 1.1 mrg TREE_TYPE (tmp), tmp); 7636 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 7637 1.1 mrg } 7638 1.1 mrg 7639 1.1 mrg /* Return an address to a char[0:len-1]* temporary for 7640 1.1 mrg character pointers. */ 7641 1.1 mrg if ((!comp && (sym->attr.pointer || sym->attr.allocatable)) 7642 1.1 mrg || (comp && (comp->attr.pointer || comp->attr.allocatable))) 7643 1.1 mrg { 7644 1.1 mrg var = gfc_create_var (type, "pstr"); 7645 1.1 mrg 7646 1.1 mrg if ((!comp && sym->attr.allocatable) 7647 1.1 mrg || (comp && comp->attr.allocatable)) 7648 1.1 mrg { 7649 1.1 mrg gfc_add_modify (&se->pre, var, 7650 1.1 mrg fold_convert (TREE_TYPE (var), 7651 1.1 mrg null_pointer_node)); 7652 1.1 mrg tmp = gfc_call_free (var); 7653 1.1 mrg gfc_add_expr_to_block (&se->post, tmp); 7654 1.1 mrg } 7655 1.1 mrg 7656 1.1 mrg /* Provide an address expression for the function arguments. */ 7657 1.1 mrg var = gfc_build_addr_expr (NULL_TREE, var); 7658 1.1 mrg } 7659 1.1 mrg else 7660 1.1 mrg var = gfc_conv_string_tmp (se, type, len); 7661 1.1 mrg 7662 1.1 mrg vec_safe_push (retargs, var); 7663 1.1 mrg } 7664 1.1 mrg else 7665 1.1 mrg { 7666 1.1 mrg gcc_assert (flag_f2c && ts.type == BT_COMPLEX); 7667 1.1 mrg 7668 1.1 mrg type = gfc_get_complex_type (ts.kind); 7669 1.1 mrg var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx")); 7670 1.1 mrg vec_safe_push (retargs, var); 7671 1.1 mrg } 7672 1.1 mrg 7673 1.1 mrg /* Add the string length to the argument list. */ 7674 1.1 mrg if (ts.type == BT_CHARACTER && ts.deferred) 7675 1.1 mrg { 7676 1.1 mrg tmp = len; 7677 1.1 mrg if (!VAR_P (tmp)) 7678 1.1 mrg tmp = gfc_evaluate_now (len, &se->pre); 7679 1.1 mrg TREE_STATIC (tmp) = 1; 7680 1.1 mrg gfc_add_modify (&se->pre, tmp, 7681 1.1 mrg build_int_cst (TREE_TYPE (tmp), 0)); 7682 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp); 7683 1.1 mrg vec_safe_push (retargs, tmp); 7684 1.1 mrg } 7685 1.1 mrg else if (ts.type == BT_CHARACTER) 7686 1.1 mrg vec_safe_push (retargs, len); 7687 1.1 mrg } 7688 1.1 mrg gfc_free_interface_mapping (&mapping); 7689 1.1 mrg 7690 1.1 mrg /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */ 7691 1.1 mrg arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs) 7692 1.1 mrg + vec_safe_length (stringargs) + vec_safe_length (append_args)); 7693 1.1 mrg vec_safe_reserve (retargs, arglen); 7694 1.1 mrg 7695 1.1 mrg /* Add the return arguments. */ 7696 1.1 mrg vec_safe_splice (retargs, arglist); 7697 1.1 mrg 7698 1.1 mrg /* Add the hidden present status for optional+value to the arguments. */ 7699 1.1 mrg vec_safe_splice (retargs, optionalargs); 7700 1.1 mrg 7701 1.1 mrg /* Add the hidden string length parameters to the arguments. */ 7702 1.1 mrg vec_safe_splice (retargs, stringargs); 7703 1.1 mrg 7704 1.1 mrg /* We may want to append extra arguments here. This is used e.g. for 7705 1.1 mrg calls to libgfortran_matmul_??, which need extra information. */ 7706 1.1 mrg vec_safe_splice (retargs, append_args); 7707 1.1 mrg 7708 1.1 mrg arglist = retargs; 7709 1.1 mrg 7710 1.1 mrg /* Generate the actual call. */ 7711 1.1 mrg if (base_object == NULL_TREE) 7712 1.1 mrg conv_function_val (se, sym, expr, args); 7713 1.1 mrg else 7714 1.1 mrg conv_base_obj_fcn_val (se, base_object, expr); 7715 1.1 mrg 7716 1.1 mrg /* If there are alternate return labels, function type should be 7717 1.1 mrg integer. Can't modify the type in place though, since it can be shared 7718 1.1 mrg with other functions. For dummy arguments, the typing is done to 7719 1.1 mrg this result, even if it has to be repeated for each call. */ 7720 1.1 mrg if (has_alternate_specifier 7721 1.1 mrg && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node) 7722 1.1 mrg { 7723 1.1 mrg if (!sym->attr.dummy) 7724 1.1 mrg { 7725 1.1 mrg TREE_TYPE (sym->backend_decl) 7726 1.1 mrg = build_function_type (integer_type_node, 7727 1.1 mrg TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl))); 7728 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl); 7729 1.1 mrg } 7730 1.1 mrg else 7731 1.1 mrg TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node; 7732 1.1 mrg } 7733 1.1 mrg 7734 1.1 mrg fntype = TREE_TYPE (TREE_TYPE (se->expr)); 7735 1.1 mrg se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist); 7736 1.1 mrg 7737 1.1 mrg /* Allocatable scalar function results must be freed and nullified 7738 1.1 mrg after use. This necessitates the creation of a temporary to 7739 1.1 mrg hold the result to prevent duplicate calls. */ 7740 1.1 mrg if (!byref && sym->ts.type != BT_CHARACTER 7741 1.1 mrg && ((sym->attr.allocatable && !sym->attr.dimension && !comp) 7742 1.1 mrg || (comp && comp->attr.allocatable && !comp->attr.dimension))) 7743 1.1 mrg { 7744 1.1 mrg tmp = gfc_create_var (TREE_TYPE (se->expr), NULL); 7745 1.1 mrg gfc_add_modify (&se->pre, tmp, se->expr); 7746 1.1 mrg se->expr = tmp; 7747 1.1 mrg tmp = gfc_call_free (tmp); 7748 1.1 mrg gfc_add_expr_to_block (&post, tmp); 7749 1.1 mrg gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0)); 7750 1.1 mrg } 7751 1.1 mrg 7752 1.1 mrg /* If we have a pointer function, but we don't want a pointer, e.g. 7753 1.1 mrg something like 7754 1.1 mrg x = f() 7755 1.1 mrg where f is pointer valued, we have to dereference the result. */ 7756 1.1 mrg if (!se->want_pointer && !byref 7757 1.1 mrg && ((!comp && (sym->attr.pointer || sym->attr.allocatable)) 7758 1.1 mrg || (comp && (comp->attr.pointer || comp->attr.allocatable)))) 7759 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, se->expr); 7760 1.1 mrg 7761 1.1 mrg /* f2c calling conventions require a scalar default real function to 7762 1.1 mrg return a double precision result. Convert this back to default 7763 1.1 mrg real. We only care about the cases that can happen in Fortran 77. 7764 1.1 mrg */ 7765 1.1 mrg if (flag_f2c && sym->ts.type == BT_REAL 7766 1.1 mrg && sym->ts.kind == gfc_default_real_kind 7767 1.1 mrg && !sym->attr.always_explicit) 7768 1.1 mrg se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr); 7769 1.1 mrg 7770 1.1 mrg /* A pure function may still have side-effects - it may modify its 7771 1.1 mrg parameters. */ 7772 1.1 mrg TREE_SIDE_EFFECTS (se->expr) = 1; 7773 1.1 mrg #if 0 7774 1.1 mrg if (!sym->attr.pure) 7775 1.1 mrg TREE_SIDE_EFFECTS (se->expr) = 1; 7776 1.1 mrg #endif 7777 1.1 mrg 7778 1.1 mrg if (byref) 7779 1.1 mrg { 7780 1.1 mrg /* Add the function call to the pre chain. There is no expression. */ 7781 1.1 mrg gfc_add_expr_to_block (&se->pre, se->expr); 7782 1.1 mrg se->expr = NULL_TREE; 7783 1.1 mrg 7784 1.1 mrg if (!se->direct_byref) 7785 1.1 mrg { 7786 1.1 mrg if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension)) 7787 1.1 mrg { 7788 1.1 mrg if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) 7789 1.1 mrg { 7790 1.1 mrg /* Check the data pointer hasn't been modified. This would 7791 1.1 mrg happen in a function returning a pointer. */ 7792 1.1 mrg tmp = gfc_conv_descriptor_data_get (info->descriptor); 7793 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, 7794 1.1 mrg logical_type_node, 7795 1.1 mrg tmp, info->data); 7796 1.1 mrg gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL, 7797 1.1 mrg gfc_msg_fault); 7798 1.1 mrg } 7799 1.1 mrg se->expr = info->descriptor; 7800 1.1 mrg /* Bundle in the string length. */ 7801 1.1 mrg se->string_length = len; 7802 1.1 mrg } 7803 1.1 mrg else if (ts.type == BT_CHARACTER) 7804 1.1 mrg { 7805 1.1 mrg /* Dereference for character pointer results. */ 7806 1.1 mrg if ((!comp && (sym->attr.pointer || sym->attr.allocatable)) 7807 1.1 mrg || (comp && (comp->attr.pointer || comp->attr.allocatable))) 7808 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, var); 7809 1.1 mrg else 7810 1.1 mrg se->expr = var; 7811 1.1 mrg 7812 1.1 mrg se->string_length = len; 7813 1.1 mrg } 7814 1.1 mrg else 7815 1.1 mrg { 7816 1.1 mrg gcc_assert (ts.type == BT_COMPLEX && flag_f2c); 7817 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, var); 7818 1.1 mrg } 7819 1.1 mrg } 7820 1.1 mrg } 7821 1.1 mrg 7822 1.1 mrg /* Associate the rhs class object's meta-data with the result, when the 7823 1.1 mrg result is a temporary. */ 7824 1.1 mrg if (args && args->expr && args->expr->ts.type == BT_CLASS 7825 1.1 mrg && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result) 7826 1.1 mrg && !GFC_CLASS_TYPE_P (TREE_TYPE (result))) 7827 1.1 mrg { 7828 1.1 mrg gfc_se parmse; 7829 1.1 mrg gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr); 7830 1.1 mrg 7831 1.1 mrg gfc_init_se (&parmse, NULL); 7832 1.1 mrg parmse.data_not_needed = 1; 7833 1.1 mrg gfc_conv_expr (&parmse, class_expr); 7834 1.1 mrg if (!DECL_LANG_SPECIFIC (result)) 7835 1.1 mrg gfc_allocate_lang_decl (result); 7836 1.1 mrg GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr; 7837 1.1 mrg gfc_free_expr (class_expr); 7838 1.1 mrg /* -fcheck= can add diagnostic code, which has to be placed before 7839 1.1 mrg the call. */ 7840 1.1 mrg if (parmse.pre.head != NULL) 7841 1.1 mrg gfc_add_expr_to_block (&se->pre, parmse.pre.head); 7842 1.1 mrg gcc_assert (parmse.post.head == NULL_TREE); 7843 1.1 mrg } 7844 1.1 mrg 7845 1.1 mrg /* Follow the function call with the argument post block. */ 7846 1.1 mrg if (byref) 7847 1.1 mrg { 7848 1.1 mrg gfc_add_block_to_block (&se->pre, &post); 7849 1.1 mrg 7850 1.1 mrg /* Transformational functions of derived types with allocatable 7851 1.1 mrg components must have the result allocatable components copied when the 7852 1.1 mrg argument is actually given. */ 7853 1.1 mrg arg = expr->value.function.actual; 7854 1.1 mrg if (result && arg && expr->rank 7855 1.1 mrg && expr->value.function.isym 7856 1.1 mrg && expr->value.function.isym->transformational 7857 1.1 mrg && arg->expr 7858 1.1 mrg && arg->expr->ts.type == BT_DERIVED 7859 1.1 mrg && arg->expr->ts.u.derived->attr.alloc_comp) 7860 1.1 mrg { 7861 1.1 mrg tree tmp2; 7862 1.1 mrg /* Copy the allocatable components. We have to use a 7863 1.1 mrg temporary here to prevent source allocatable components 7864 1.1 mrg from being corrupted. */ 7865 1.1 mrg tmp2 = gfc_evaluate_now (result, &se->pre); 7866 1.1 mrg tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived, 7867 1.1 mrg result, tmp2, expr->rank, 0); 7868 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 7869 1.1 mrg tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2), 7870 1.1 mrg expr->rank); 7871 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 7872 1.1 mrg 7873 1.1 mrg /* Finally free the temporary's data field. */ 7874 1.1 mrg tmp = gfc_conv_descriptor_data_get (tmp2); 7875 1.1 mrg tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE, 7876 1.1 mrg NULL_TREE, NULL_TREE, true, 7877 1.1 mrg NULL, GFC_CAF_COARRAY_NOCOARRAY); 7878 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 7879 1.1 mrg } 7880 1.1 mrg } 7881 1.1 mrg else 7882 1.1 mrg { 7883 1.1 mrg /* For a function with a class array result, save the result as 7884 1.1 mrg a temporary, set the info fields needed by the scalarizer and 7885 1.1 mrg call the finalization function of the temporary. Note that the 7886 1.1 mrg nullification of allocatable components needed by the result 7887 1.1 mrg is done in gfc_trans_assignment_1. */ 7888 1.1 mrg if (expr && ((gfc_is_class_array_function (expr) 7889 1.1 mrg && se->ss && se->ss->loop) 7890 1.1 mrg || gfc_is_alloc_class_scalar_function (expr)) 7891 1.1 mrg && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr)) 7892 1.1 mrg && expr->must_finalize) 7893 1.1 mrg { 7894 1.1 mrg tree final_fndecl; 7895 1.1 mrg tree is_final; 7896 1.1 mrg int n; 7897 1.1 mrg if (se->ss && se->ss->loop) 7898 1.1 mrg { 7899 1.1 mrg gfc_add_block_to_block (&se->ss->loop->pre, &se->pre); 7900 1.1 mrg se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre); 7901 1.1 mrg tmp = gfc_class_data_get (se->expr); 7902 1.1 mrg info->descriptor = tmp; 7903 1.1 mrg info->data = gfc_conv_descriptor_data_get (tmp); 7904 1.1 mrg info->offset = gfc_conv_descriptor_offset_get (tmp); 7905 1.1 mrg for (n = 0; n < se->ss->loop->dimen; n++) 7906 1.1 mrg { 7907 1.1 mrg tree dim = gfc_rank_cst[n]; 7908 1.1 mrg se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim); 7909 1.1 mrg se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim); 7910 1.1 mrg } 7911 1.1 mrg } 7912 1.1 mrg else 7913 1.1 mrg { 7914 1.1 mrg /* TODO Eliminate the doubling of temporaries. This 7915 1.1 mrg one is necessary to ensure no memory leakage. */ 7916 1.1 mrg se->expr = gfc_evaluate_now (se->expr, &se->pre); 7917 1.1 mrg tmp = gfc_class_data_get (se->expr); 7918 1.1 mrg tmp = gfc_conv_scalar_to_descriptor (se, tmp, 7919 1.1 mrg CLASS_DATA (expr->value.function.esym->result)->attr); 7920 1.1 mrg } 7921 1.1 mrg 7922 1.1 mrg if ((gfc_is_class_array_function (expr) 7923 1.1 mrg || gfc_is_alloc_class_scalar_function (expr)) 7924 1.1 mrg && CLASS_DATA (expr->value.function.esym->result)->attr.pointer) 7925 1.1 mrg goto no_finalization; 7926 1.1 mrg 7927 1.1 mrg final_fndecl = gfc_class_vtab_final_get (se->expr); 7928 1.1 mrg is_final = fold_build2_loc (input_location, NE_EXPR, 7929 1.1 mrg logical_type_node, 7930 1.1 mrg final_fndecl, 7931 1.1 mrg fold_convert (TREE_TYPE (final_fndecl), 7932 1.1 mrg null_pointer_node)); 7933 1.1 mrg final_fndecl = build_fold_indirect_ref_loc (input_location, 7934 1.1 mrg final_fndecl); 7935 1.1 mrg tmp = build_call_expr_loc (input_location, 7936 1.1 mrg final_fndecl, 3, 7937 1.1 mrg gfc_build_addr_expr (NULL, tmp), 7938 1.1 mrg gfc_class_vtab_size_get (se->expr), 7939 1.1 mrg boolean_false_node); 7940 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, 7941 1.1 mrg void_type_node, is_final, tmp, 7942 1.1 mrg build_empty_stmt (input_location)); 7943 1.1 mrg 7944 1.1 mrg if (se->ss && se->ss->loop) 7945 1.1 mrg { 7946 1.1 mrg gfc_prepend_expr_to_block (&se->ss->loop->post, tmp); 7947 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, 7948 1.1 mrg logical_type_node, 7949 1.1 mrg info->data, 7950 1.1 mrg fold_convert (TREE_TYPE (info->data), 7951 1.1 mrg null_pointer_node)); 7952 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, 7953 1.1 mrg void_type_node, tmp, 7954 1.1 mrg gfc_call_free (info->data), 7955 1.1 mrg build_empty_stmt (input_location)); 7956 1.1 mrg gfc_add_expr_to_block (&se->ss->loop->post, tmp); 7957 1.1 mrg } 7958 1.1 mrg else 7959 1.1 mrg { 7960 1.1 mrg tree classdata; 7961 1.1 mrg gfc_prepend_expr_to_block (&se->post, tmp); 7962 1.1 mrg classdata = gfc_class_data_get (se->expr); 7963 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, 7964 1.1 mrg logical_type_node, 7965 1.1 mrg classdata, 7966 1.1 mrg fold_convert (TREE_TYPE (classdata), 7967 1.1 mrg null_pointer_node)); 7968 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, 7969 1.1 mrg void_type_node, tmp, 7970 1.1 mrg gfc_call_free (classdata), 7971 1.1 mrg build_empty_stmt (input_location)); 7972 1.1 mrg gfc_add_expr_to_block (&se->post, tmp); 7973 1.1 mrg } 7974 1.1 mrg } 7975 1.1 mrg 7976 1.1 mrg no_finalization: 7977 1.1 mrg gfc_add_block_to_block (&se->post, &post); 7978 1.1 mrg } 7979 1.1 mrg 7980 1.1 mrg return has_alternate_specifier; 7981 1.1 mrg } 7982 1.1 mrg 7983 1.1 mrg 7984 1.1 mrg /* Fill a character string with spaces. */ 7985 1.1 mrg 7986 1.1 mrg static tree 7987 1.1 mrg fill_with_spaces (tree start, tree type, tree size) 7988 1.1 mrg { 7989 1.1 mrg stmtblock_t block, loop; 7990 1.1 mrg tree i, el, exit_label, cond, tmp; 7991 1.1 mrg 7992 1.1 mrg /* For a simple char type, we can call memset(). */ 7993 1.1 mrg if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0) 7994 1.1 mrg return build_call_expr_loc (input_location, 7995 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMSET), 7996 1.1 mrg 3, start, 7997 1.1 mrg build_int_cst (gfc_get_int_type (gfc_c_int_kind), 7998 1.1 mrg lang_hooks.to_target_charset (' ')), 7999 1.1 mrg fold_convert (size_type_node, size)); 8000 1.1 mrg 8001 1.1 mrg /* Otherwise, we use a loop: 8002 1.1 mrg for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type)) 8003 1.1 mrg *el = (type) ' '; 8004 1.1 mrg */ 8005 1.1 mrg 8006 1.1 mrg /* Initialize variables. */ 8007 1.1 mrg gfc_init_block (&block); 8008 1.1 mrg i = gfc_create_var (sizetype, "i"); 8009 1.1 mrg gfc_add_modify (&block, i, fold_convert (sizetype, size)); 8010 1.1 mrg el = gfc_create_var (build_pointer_type (type), "el"); 8011 1.1 mrg gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start)); 8012 1.1 mrg exit_label = gfc_build_label_decl (NULL_TREE); 8013 1.1 mrg TREE_USED (exit_label) = 1; 8014 1.1 mrg 8015 1.1 mrg 8016 1.1 mrg /* Loop body. */ 8017 1.1 mrg gfc_init_block (&loop); 8018 1.1 mrg 8019 1.1 mrg /* Exit condition. */ 8020 1.1 mrg cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i, 8021 1.1 mrg build_zero_cst (sizetype)); 8022 1.1 mrg tmp = build1_v (GOTO_EXPR, exit_label); 8023 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp, 8024 1.1 mrg build_empty_stmt (input_location)); 8025 1.1 mrg gfc_add_expr_to_block (&loop, tmp); 8026 1.1 mrg 8027 1.1 mrg /* Assignment. */ 8028 1.1 mrg gfc_add_modify (&loop, 8029 1.1 mrg fold_build1_loc (input_location, INDIRECT_REF, type, el), 8030 1.1 mrg build_int_cst (type, lang_hooks.to_target_charset (' '))); 8031 1.1 mrg 8032 1.1 mrg /* Increment loop variables. */ 8033 1.1 mrg gfc_add_modify (&loop, i, 8034 1.1 mrg fold_build2_loc (input_location, MINUS_EXPR, sizetype, i, 8035 1.1 mrg TYPE_SIZE_UNIT (type))); 8036 1.1 mrg gfc_add_modify (&loop, el, 8037 1.1 mrg fold_build_pointer_plus_loc (input_location, 8038 1.1 mrg el, TYPE_SIZE_UNIT (type))); 8039 1.1 mrg 8040 1.1 mrg /* Making the loop... actually loop! */ 8041 1.1 mrg tmp = gfc_finish_block (&loop); 8042 1.1 mrg tmp = build1_v (LOOP_EXPR, tmp); 8043 1.1 mrg gfc_add_expr_to_block (&block, tmp); 8044 1.1 mrg 8045 1.1 mrg /* The exit label. */ 8046 1.1 mrg tmp = build1_v (LABEL_EXPR, exit_label); 8047 1.1 mrg gfc_add_expr_to_block (&block, tmp); 8048 1.1 mrg 8049 1.1 mrg 8050 1.1 mrg return gfc_finish_block (&block); 8051 1.1 mrg } 8052 1.1 mrg 8053 1.1 mrg 8054 1.1 mrg /* Generate code to copy a string. */ 8055 1.1 mrg 8056 1.1 mrg void 8057 1.1 mrg gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest, 8058 1.1 mrg int dkind, tree slength, tree src, int skind) 8059 1.1 mrg { 8060 1.1 mrg tree tmp, dlen, slen; 8061 1.1 mrg tree dsc; 8062 1.1 mrg tree ssc; 8063 1.1 mrg tree cond; 8064 1.1 mrg tree cond2; 8065 1.1 mrg tree tmp2; 8066 1.1 mrg tree tmp3; 8067 1.1 mrg tree tmp4; 8068 1.1 mrg tree chartype; 8069 1.1 mrg stmtblock_t tempblock; 8070 1.1 mrg 8071 1.1 mrg gcc_assert (dkind == skind); 8072 1.1 mrg 8073 1.1 mrg if (slength != NULL_TREE) 8074 1.1 mrg { 8075 1.1 mrg slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block); 8076 1.1 mrg ssc = gfc_string_to_single_character (slen, src, skind); 8077 1.1 mrg } 8078 1.1 mrg else 8079 1.1 mrg { 8080 1.1 mrg slen = build_one_cst (gfc_charlen_type_node); 8081 1.1 mrg ssc = src; 8082 1.1 mrg } 8083 1.1 mrg 8084 1.1 mrg if (dlength != NULL_TREE) 8085 1.1 mrg { 8086 1.1 mrg dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block); 8087 1.1 mrg dsc = gfc_string_to_single_character (dlen, dest, dkind); 8088 1.1 mrg } 8089 1.1 mrg else 8090 1.1 mrg { 8091 1.1 mrg dlen = build_one_cst (gfc_charlen_type_node); 8092 1.1 mrg dsc = dest; 8093 1.1 mrg } 8094 1.1 mrg 8095 1.1 mrg /* Assign directly if the types are compatible. */ 8096 1.1 mrg if (dsc != NULL_TREE && ssc != NULL_TREE 8097 1.1 mrg && TREE_TYPE (dsc) == TREE_TYPE (ssc)) 8098 1.1 mrg { 8099 1.1 mrg gfc_add_modify (block, dsc, ssc); 8100 1.1 mrg return; 8101 1.1 mrg } 8102 1.1 mrg 8103 1.1 mrg /* The string copy algorithm below generates code like 8104 1.1 mrg 8105 1.1 mrg if (destlen > 0) 8106 1.1 mrg { 8107 1.1 mrg if (srclen < destlen) 8108 1.1 mrg { 8109 1.1 mrg memmove (dest, src, srclen); 8110 1.1 mrg // Pad with spaces. 8111 1.1 mrg memset (&dest[srclen], ' ', destlen - srclen); 8112 1.1 mrg } 8113 1.1 mrg else 8114 1.1 mrg { 8115 1.1 mrg // Truncate if too long. 8116 1.1 mrg memmove (dest, src, destlen); 8117 1.1 mrg } 8118 1.1 mrg } 8119 1.1 mrg */ 8120 1.1 mrg 8121 1.1 mrg /* Do nothing if the destination length is zero. */ 8122 1.1 mrg cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen, 8123 1.1 mrg build_zero_cst (TREE_TYPE (dlen))); 8124 1.1 mrg 8125 1.1 mrg /* For non-default character kinds, we have to multiply the string 8126 1.1 mrg length by the base type size. */ 8127 1.1 mrg chartype = gfc_get_char_type (dkind); 8128 1.1 mrg slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen), 8129 1.1 mrg slen, 8130 1.1 mrg fold_convert (TREE_TYPE (slen), 8131 1.1 mrg TYPE_SIZE_UNIT (chartype))); 8132 1.1 mrg dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen), 8133 1.1 mrg dlen, 8134 1.1 mrg fold_convert (TREE_TYPE (dlen), 8135 1.1 mrg TYPE_SIZE_UNIT (chartype))); 8136 1.1 mrg 8137 1.1 mrg if (dlength && POINTER_TYPE_P (TREE_TYPE (dest))) 8138 1.1 mrg dest = fold_convert (pvoid_type_node, dest); 8139 1.1 mrg else 8140 1.1 mrg dest = gfc_build_addr_expr (pvoid_type_node, dest); 8141 1.1 mrg 8142 1.1 mrg if (slength && POINTER_TYPE_P (TREE_TYPE (src))) 8143 1.1 mrg src = fold_convert (pvoid_type_node, src); 8144 1.1 mrg else 8145 1.1 mrg src = gfc_build_addr_expr (pvoid_type_node, src); 8146 1.1 mrg 8147 1.1 mrg /* Truncate string if source is too long. */ 8148 1.1 mrg cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen, 8149 1.1 mrg dlen); 8150 1.1 mrg 8151 1.1 mrg /* Pre-evaluate pointers unless one of the IF arms will be optimized away. */ 8152 1.1 mrg if (!CONSTANT_CLASS_P (cond2)) 8153 1.1 mrg { 8154 1.1 mrg dest = gfc_evaluate_now (dest, block); 8155 1.1 mrg src = gfc_evaluate_now (src, block); 8156 1.1 mrg } 8157 1.1 mrg 8158 1.1 mrg /* Copy and pad with spaces. */ 8159 1.1 mrg tmp3 = build_call_expr_loc (input_location, 8160 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMMOVE), 8161 1.1 mrg 3, dest, src, 8162 1.1 mrg fold_convert (size_type_node, slen)); 8163 1.1 mrg 8164 1.1 mrg /* Wstringop-overflow appears at -O3 even though this warning is not 8165 1.1 mrg explicitly available in fortran nor can it be switched off. If the 8166 1.1 mrg source length is a constant, its negative appears as a very large 8167 1.1 mrg postive number and triggers the warning in BUILTIN_MEMSET. Fixing 8168 1.1 mrg the result of the MINUS_EXPR suppresses this spurious warning. */ 8169 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, 8170 1.1 mrg TREE_TYPE(dlen), dlen, slen); 8171 1.1 mrg if (slength && TREE_CONSTANT (slength)) 8172 1.1 mrg tmp = gfc_evaluate_now (tmp, block); 8173 1.1 mrg 8174 1.1 mrg tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen); 8175 1.1 mrg tmp4 = fill_with_spaces (tmp4, chartype, tmp); 8176 1.1 mrg 8177 1.1 mrg gfc_init_block (&tempblock); 8178 1.1 mrg gfc_add_expr_to_block (&tempblock, tmp3); 8179 1.1 mrg gfc_add_expr_to_block (&tempblock, tmp4); 8180 1.1 mrg tmp3 = gfc_finish_block (&tempblock); 8181 1.1 mrg 8182 1.1 mrg /* The truncated memmove if the slen >= dlen. */ 8183 1.1 mrg tmp2 = build_call_expr_loc (input_location, 8184 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMMOVE), 8185 1.1 mrg 3, dest, src, 8186 1.1 mrg fold_convert (size_type_node, dlen)); 8187 1.1 mrg 8188 1.1 mrg /* The whole copy_string function is there. */ 8189 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2, 8190 1.1 mrg tmp3, tmp2); 8191 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp, 8192 1.1 mrg build_empty_stmt (input_location)); 8193 1.1 mrg gfc_add_expr_to_block (block, tmp); 8194 1.1 mrg } 8195 1.1 mrg 8196 1.1 mrg 8197 1.1 mrg /* Translate a statement function. 8198 1.1 mrg The value of a statement function reference is obtained by evaluating the 8199 1.1 mrg expression using the values of the actual arguments for the values of the 8200 1.1 mrg corresponding dummy arguments. */ 8201 1.1 mrg 8202 1.1 mrg static void 8203 1.1 mrg gfc_conv_statement_function (gfc_se * se, gfc_expr * expr) 8204 1.1 mrg { 8205 1.1 mrg gfc_symbol *sym; 8206 1.1 mrg gfc_symbol *fsym; 8207 1.1 mrg gfc_formal_arglist *fargs; 8208 1.1 mrg gfc_actual_arglist *args; 8209 1.1 mrg gfc_se lse; 8210 1.1 mrg gfc_se rse; 8211 1.1 mrg gfc_saved_var *saved_vars; 8212 1.1 mrg tree *temp_vars; 8213 1.1 mrg tree type; 8214 1.1 mrg tree tmp; 8215 1.1 mrg int n; 8216 1.1 mrg 8217 1.1 mrg sym = expr->symtree->n.sym; 8218 1.1 mrg args = expr->value.function.actual; 8219 1.1 mrg gfc_init_se (&lse, NULL); 8220 1.1 mrg gfc_init_se (&rse, NULL); 8221 1.1 mrg 8222 1.1 mrg n = 0; 8223 1.1 mrg for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next) 8224 1.1 mrg n++; 8225 1.1 mrg saved_vars = XCNEWVEC (gfc_saved_var, n); 8226 1.1 mrg temp_vars = XCNEWVEC (tree, n); 8227 1.1 mrg 8228 1.1 mrg for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs; 8229 1.1 mrg fargs = fargs->next, n++) 8230 1.1 mrg { 8231 1.1 mrg /* Each dummy shall be specified, explicitly or implicitly, to be 8232 1.1 mrg scalar. */ 8233 1.1 mrg gcc_assert (fargs->sym->attr.dimension == 0); 8234 1.1 mrg fsym = fargs->sym; 8235 1.1 mrg 8236 1.1 mrg if (fsym->ts.type == BT_CHARACTER) 8237 1.1 mrg { 8238 1.1 mrg /* Copy string arguments. */ 8239 1.1 mrg tree arglen; 8240 1.1 mrg 8241 1.1 mrg gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length 8242 1.1 mrg && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT); 8243 1.1 mrg 8244 1.1 mrg /* Create a temporary to hold the value. */ 8245 1.1 mrg if (fsym->ts.u.cl->backend_decl == NULL_TREE) 8246 1.1 mrg fsym->ts.u.cl->backend_decl 8247 1.1 mrg = gfc_conv_constant_to_tree (fsym->ts.u.cl->length); 8248 1.1 mrg 8249 1.1 mrg type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl); 8250 1.1 mrg temp_vars[n] = gfc_create_var (type, fsym->name); 8251 1.1 mrg 8252 1.1 mrg arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type)); 8253 1.1 mrg 8254 1.1 mrg gfc_conv_expr (&rse, args->expr); 8255 1.1 mrg gfc_conv_string_parameter (&rse); 8256 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.pre); 8257 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.pre); 8258 1.1 mrg 8259 1.1 mrg gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind, 8260 1.1 mrg rse.string_length, rse.expr, fsym->ts.kind); 8261 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.post); 8262 1.1 mrg gfc_add_block_to_block (&se->pre, &rse.post); 8263 1.1 mrg } 8264 1.1 mrg else 8265 1.1 mrg { 8266 1.1 mrg /* For everything else, just evaluate the expression. */ 8267 1.1 mrg 8268 1.1 mrg /* Create a temporary to hold the value. */ 8269 1.1 mrg type = gfc_typenode_for_spec (&fsym->ts); 8270 1.1 mrg temp_vars[n] = gfc_create_var (type, fsym->name); 8271 1.1 mrg 8272 1.1 mrg gfc_conv_expr (&lse, args->expr); 8273 1.1 mrg 8274 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.pre); 8275 1.1 mrg gfc_add_modify (&se->pre, temp_vars[n], lse.expr); 8276 1.1 mrg gfc_add_block_to_block (&se->pre, &lse.post); 8277 1.1 mrg } 8278 1.1 mrg 8279 1.1 mrg args = args->next; 8280 1.1 mrg } 8281 1.1 mrg 8282 1.1 mrg /* Use the temporary variables in place of the real ones. */ 8283 1.1 mrg for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs; 8284 1.1 mrg fargs = fargs->next, n++) 8285 1.1 mrg gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]); 8286 1.1 mrg 8287 1.1 mrg gfc_conv_expr (se, sym->value); 8288 1.1 mrg 8289 1.1 mrg if (sym->ts.type == BT_CHARACTER) 8290 1.1 mrg { 8291 1.1 mrg gfc_conv_const_charlen (sym->ts.u.cl); 8292 1.1 mrg 8293 1.1 mrg /* Force the expression to the correct length. */ 8294 1.1 mrg if (!INTEGER_CST_P (se->string_length) 8295 1.1 mrg || tree_int_cst_lt (se->string_length, 8296 1.1 mrg sym->ts.u.cl->backend_decl)) 8297 1.1 mrg { 8298 1.1 mrg type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl); 8299 1.1 mrg tmp = gfc_create_var (type, sym->name); 8300 1.1 mrg tmp = gfc_build_addr_expr (build_pointer_type (type), tmp); 8301 1.1 mrg gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp, 8302 1.1 mrg sym->ts.kind, se->string_length, se->expr, 8303 1.1 mrg sym->ts.kind); 8304 1.1 mrg se->expr = tmp; 8305 1.1 mrg } 8306 1.1 mrg se->string_length = sym->ts.u.cl->backend_decl; 8307 1.1 mrg } 8308 1.1 mrg 8309 1.1 mrg /* Restore the original variables. */ 8310 1.1 mrg for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs; 8311 1.1 mrg fargs = fargs->next, n++) 8312 1.1 mrg gfc_restore_sym (fargs->sym, &saved_vars[n]); 8313 1.1 mrg free (temp_vars); 8314 1.1 mrg free (saved_vars); 8315 1.1 mrg } 8316 1.1 mrg 8317 1.1 mrg 8318 1.1 mrg /* Translate a function expression. */ 8319 1.1 mrg 8320 1.1 mrg static void 8321 1.1 mrg gfc_conv_function_expr (gfc_se * se, gfc_expr * expr) 8322 1.1 mrg { 8323 1.1 mrg gfc_symbol *sym; 8324 1.1 mrg 8325 1.1 mrg if (expr->value.function.isym) 8326 1.1 mrg { 8327 1.1 mrg gfc_conv_intrinsic_function (se, expr); 8328 1.1 mrg return; 8329 1.1 mrg } 8330 1.1 mrg 8331 1.1 mrg /* expr.value.function.esym is the resolved (specific) function symbol for 8332 1.1 mrg most functions. However this isn't set for dummy procedures. */ 8333 1.1 mrg sym = expr->value.function.esym; 8334 1.1 mrg if (!sym) 8335 1.1 mrg sym = expr->symtree->n.sym; 8336 1.1 mrg 8337 1.1 mrg /* The IEEE_ARITHMETIC functions are caught here. */ 8338 1.1 mrg if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC) 8339 1.1 mrg if (gfc_conv_ieee_arithmetic_function (se, expr)) 8340 1.1 mrg return; 8341 1.1 mrg 8342 1.1 mrg /* We distinguish statement functions from general functions to improve 8343 1.1 mrg runtime performance. */ 8344 1.1 mrg if (sym->attr.proc == PROC_ST_FUNCTION) 8345 1.1 mrg { 8346 1.1 mrg gfc_conv_statement_function (se, expr); 8347 1.1 mrg return; 8348 1.1 mrg } 8349 1.1 mrg 8350 1.1 mrg gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr, 8351 1.1 mrg NULL); 8352 1.1 mrg } 8353 1.1 mrg 8354 1.1 mrg 8355 1.1 mrg /* Determine whether the given EXPR_CONSTANT is a zero initializer. */ 8356 1.1 mrg 8357 1.1 mrg static bool 8358 1.1 mrg is_zero_initializer_p (gfc_expr * expr) 8359 1.1 mrg { 8360 1.1 mrg if (expr->expr_type != EXPR_CONSTANT) 8361 1.1 mrg return false; 8362 1.1 mrg 8363 1.1 mrg /* We ignore constants with prescribed memory representations for now. */ 8364 1.1 mrg if (expr->representation.string) 8365 1.1 mrg return false; 8366 1.1 mrg 8367 1.1 mrg switch (expr->ts.type) 8368 1.1 mrg { 8369 1.1 mrg case BT_INTEGER: 8370 1.1 mrg return mpz_cmp_si (expr->value.integer, 0) == 0; 8371 1.1 mrg 8372 1.1 mrg case BT_REAL: 8373 1.1 mrg return mpfr_zero_p (expr->value.real) 8374 1.1 mrg && MPFR_SIGN (expr->value.real) >= 0; 8375 1.1 mrg 8376 1.1 mrg case BT_LOGICAL: 8377 1.1 mrg return expr->value.logical == 0; 8378 1.1 mrg 8379 1.1 mrg case BT_COMPLEX: 8380 1.1 mrg return mpfr_zero_p (mpc_realref (expr->value.complex)) 8381 1.1 mrg && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0 8382 1.1 mrg && mpfr_zero_p (mpc_imagref (expr->value.complex)) 8383 1.1 mrg && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0; 8384 1.1 mrg 8385 1.1 mrg default: 8386 1.1 mrg break; 8387 1.1 mrg } 8388 1.1 mrg return false; 8389 1.1 mrg } 8390 1.1 mrg 8391 1.1 mrg 8392 1.1 mrg static void 8393 1.1 mrg gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr) 8394 1.1 mrg { 8395 1.1 mrg gfc_ss *ss; 8396 1.1 mrg 8397 1.1 mrg ss = se->ss; 8398 1.1 mrg gcc_assert (ss != NULL && ss != gfc_ss_terminator); 8399 1.1 mrg gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR); 8400 1.1 mrg 8401 1.1 mrg gfc_conv_tmp_array_ref (se); 8402 1.1 mrg } 8403 1.1 mrg 8404 1.1 mrg 8405 1.1 mrg /* Build a static initializer. EXPR is the expression for the initial value. 8406 1.1 mrg The other parameters describe the variable of the component being 8407 1.1 mrg initialized. EXPR may be null. */ 8408 1.1 mrg 8409 1.1 mrg tree 8410 1.1 mrg gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type, 8411 1.1 mrg bool array, bool pointer, bool procptr) 8412 1.1 mrg { 8413 1.1 mrg gfc_se se; 8414 1.1 mrg 8415 1.1 mrg if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED 8416 1.1 mrg && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV 8417 1.1 mrg && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE) 8418 1.1 mrg return build_constructor (type, NULL); 8419 1.1 mrg 8420 1.1 mrg if (!(expr || pointer || procptr)) 8421 1.1 mrg return NULL_TREE; 8422 1.1 mrg 8423 1.1 mrg /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR 8424 1.1 mrg (these are the only two iso_c_binding derived types that can be 8425 1.1 mrg used as initialization expressions). If so, we need to modify 8426 1.1 mrg the 'expr' to be that for a (void *). */ 8427 1.1 mrg if (expr != NULL && expr->ts.type == BT_DERIVED 8428 1.1 mrg && expr->ts.is_iso_c && expr->ts.u.derived) 8429 1.1 mrg { 8430 1.1 mrg if (TREE_CODE (type) == ARRAY_TYPE) 8431 1.1 mrg return build_constructor (type, NULL); 8432 1.1 mrg else if (POINTER_TYPE_P (type)) 8433 1.1 mrg return build_int_cst (type, 0); 8434 1.1 mrg else 8435 1.1 mrg gcc_unreachable (); 8436 1.1 mrg } 8437 1.1 mrg 8438 1.1 mrg if (array && !procptr) 8439 1.1 mrg { 8440 1.1 mrg tree ctor; 8441 1.1 mrg /* Arrays need special handling. */ 8442 1.1 mrg if (pointer) 8443 1.1 mrg ctor = gfc_build_null_descriptor (type); 8444 1.1 mrg /* Special case assigning an array to zero. */ 8445 1.1 mrg else if (is_zero_initializer_p (expr)) 8446 1.1 mrg ctor = build_constructor (type, NULL); 8447 1.1 mrg else 8448 1.1 mrg ctor = gfc_conv_array_initializer (type, expr); 8449 1.1 mrg TREE_STATIC (ctor) = 1; 8450 1.1 mrg return ctor; 8451 1.1 mrg } 8452 1.1 mrg else if (pointer || procptr) 8453 1.1 mrg { 8454 1.1 mrg if (ts->type == BT_CLASS && !procptr) 8455 1.1 mrg { 8456 1.1 mrg gfc_init_se (&se, NULL); 8457 1.1 mrg gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1); 8458 1.1 mrg gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR); 8459 1.1 mrg TREE_STATIC (se.expr) = 1; 8460 1.1 mrg return se.expr; 8461 1.1 mrg } 8462 1.1 mrg else if (!expr || expr->expr_type == EXPR_NULL) 8463 1.1 mrg return fold_convert (type, null_pointer_node); 8464 1.1 mrg else 8465 1.1 mrg { 8466 1.1 mrg gfc_init_se (&se, NULL); 8467 1.1 mrg se.want_pointer = 1; 8468 1.1 mrg gfc_conv_expr (&se, expr); 8469 1.1 mrg gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR); 8470 1.1 mrg return se.expr; 8471 1.1 mrg } 8472 1.1 mrg } 8473 1.1 mrg else 8474 1.1 mrg { 8475 1.1 mrg switch (ts->type) 8476 1.1 mrg { 8477 1.1 mrg case_bt_struct: 8478 1.1 mrg case BT_CLASS: 8479 1.1 mrg gfc_init_se (&se, NULL); 8480 1.1 mrg if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL) 8481 1.1 mrg gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1); 8482 1.1 mrg else 8483 1.1 mrg gfc_conv_structure (&se, expr, 1); 8484 1.1 mrg gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR); 8485 1.1 mrg TREE_STATIC (se.expr) = 1; 8486 1.1 mrg return se.expr; 8487 1.1 mrg 8488 1.1 mrg case BT_CHARACTER: 8489 1.1 mrg if (expr->expr_type == EXPR_CONSTANT) 8490 1.1 mrg { 8491 1.1 mrg tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl, expr); 8492 1.1 mrg TREE_STATIC (ctor) = 1; 8493 1.1 mrg return ctor; 8494 1.1 mrg } 8495 1.1 mrg 8496 1.1 mrg /* Fallthrough. */ 8497 1.1 mrg default: 8498 1.1 mrg gfc_init_se (&se, NULL); 8499 1.1 mrg gfc_conv_constant (&se, expr); 8500 1.1 mrg gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR); 8501 1.1 mrg return se.expr; 8502 1.1 mrg } 8503 1.1 mrg } 8504 1.1 mrg } 8505 1.1 mrg 8506 1.1 mrg static tree 8507 1.1 mrg gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr) 8508 1.1 mrg { 8509 1.1 mrg gfc_se rse; 8510 1.1 mrg gfc_se lse; 8511 1.1 mrg gfc_ss *rss; 8512 1.1 mrg gfc_ss *lss; 8513 1.1 mrg gfc_array_info *lss_array; 8514 1.1 mrg stmtblock_t body; 8515 1.1 mrg stmtblock_t block; 8516 1.1 mrg gfc_loopinfo loop; 8517 1.1 mrg int n; 8518 1.1 mrg tree tmp; 8519 1.1 mrg 8520 1.1 mrg gfc_start_block (&block); 8521 1.1 mrg 8522 1.1 mrg /* Initialize the scalarizer. */ 8523 1.1 mrg gfc_init_loopinfo (&loop); 8524 1.1 mrg 8525 1.1 mrg gfc_init_se (&lse, NULL); 8526 1.1 mrg gfc_init_se (&rse, NULL); 8527 1.1 mrg 8528 1.1 mrg /* Walk the rhs. */ 8529 1.1 mrg rss = gfc_walk_expr (expr); 8530 1.1 mrg if (rss == gfc_ss_terminator) 8531 1.1 mrg /* The rhs is scalar. Add a ss for the expression. */ 8532 1.1 mrg rss = gfc_get_scalar_ss (gfc_ss_terminator, expr); 8533 1.1 mrg 8534 1.1 mrg /* Create a SS for the destination. */ 8535 1.1 mrg lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank, 8536 1.1 mrg GFC_SS_COMPONENT); 8537 1.1 mrg lss_array = &lss->info->data.array; 8538 1.1 mrg lss_array->shape = gfc_get_shape (cm->as->rank); 8539 1.1 mrg lss_array->descriptor = dest; 8540 1.1 mrg lss_array->data = gfc_conv_array_data (dest); 8541 1.1 mrg lss_array->offset = gfc_conv_array_offset (dest); 8542 1.1 mrg for (n = 0; n < cm->as->rank; n++) 8543 1.1 mrg { 8544 1.1 mrg lss_array->start[n] = gfc_conv_array_lbound (dest, n); 8545 1.1 mrg lss_array->stride[n] = gfc_index_one_node; 8546 1.1 mrg 8547 1.1 mrg mpz_init (lss_array->shape[n]); 8548 1.1 mrg mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer, 8549 1.1 mrg cm->as->lower[n]->value.integer); 8550 1.1 mrg mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1); 8551 1.1 mrg } 8552 1.1 mrg 8553 1.1 mrg /* Associate the SS with the loop. */ 8554 1.1 mrg gfc_add_ss_to_loop (&loop, lss); 8555 1.1 mrg gfc_add_ss_to_loop (&loop, rss); 8556 1.1 mrg 8557 1.1 mrg /* Calculate the bounds of the scalarization. */ 8558 1.1 mrg gfc_conv_ss_startstride (&loop); 8559 1.1 mrg 8560 1.1 mrg /* Setup the scalarizing loops. */ 8561 1.1 mrg gfc_conv_loop_setup (&loop, &expr->where); 8562 1.1 mrg 8563 1.1 mrg /* Setup the gfc_se structures. */ 8564 1.1 mrg gfc_copy_loopinfo_to_se (&lse, &loop); 8565 1.1 mrg gfc_copy_loopinfo_to_se (&rse, &loop); 8566 1.1 mrg 8567 1.1 mrg rse.ss = rss; 8568 1.1 mrg gfc_mark_ss_chain_used (rss, 1); 8569 1.1 mrg lse.ss = lss; 8570 1.1 mrg gfc_mark_ss_chain_used (lss, 1); 8571 1.1 mrg 8572 1.1 mrg /* Start the scalarized loop body. */ 8573 1.1 mrg gfc_start_scalarized_body (&loop, &body); 8574 1.1 mrg 8575 1.1 mrg gfc_conv_tmp_array_ref (&lse); 8576 1.1 mrg if (cm->ts.type == BT_CHARACTER) 8577 1.1 mrg lse.string_length = cm->ts.u.cl->backend_decl; 8578 1.1 mrg 8579 1.1 mrg gfc_conv_expr (&rse, expr); 8580 1.1 mrg 8581 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false); 8582 1.1 mrg gfc_add_expr_to_block (&body, tmp); 8583 1.1 mrg 8584 1.1 mrg gcc_assert (rse.ss == gfc_ss_terminator); 8585 1.1 mrg 8586 1.1 mrg /* Generate the copying loops. */ 8587 1.1 mrg gfc_trans_scalarizing_loops (&loop, &body); 8588 1.1 mrg 8589 1.1 mrg /* Wrap the whole thing up. */ 8590 1.1 mrg gfc_add_block_to_block (&block, &loop.pre); 8591 1.1 mrg gfc_add_block_to_block (&block, &loop.post); 8592 1.1 mrg 8593 1.1 mrg gcc_assert (lss_array->shape != NULL); 8594 1.1 mrg gfc_free_shape (&lss_array->shape, cm->as->rank); 8595 1.1 mrg gfc_cleanup_loop (&loop); 8596 1.1 mrg 8597 1.1 mrg return gfc_finish_block (&block); 8598 1.1 mrg } 8599 1.1 mrg 8600 1.1 mrg 8601 1.1 mrg static tree 8602 1.1 mrg gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm, 8603 1.1 mrg gfc_expr * expr) 8604 1.1 mrg { 8605 1.1 mrg gfc_se se; 8606 1.1 mrg stmtblock_t block; 8607 1.1 mrg tree offset; 8608 1.1 mrg int n; 8609 1.1 mrg tree tmp; 8610 1.1 mrg tree tmp2; 8611 1.1 mrg gfc_array_spec *as; 8612 1.1 mrg gfc_expr *arg = NULL; 8613 1.1 mrg 8614 1.1 mrg gfc_start_block (&block); 8615 1.1 mrg gfc_init_se (&se, NULL); 8616 1.1 mrg 8617 1.1 mrg /* Get the descriptor for the expressions. */ 8618 1.1 mrg se.want_pointer = 0; 8619 1.1 mrg gfc_conv_expr_descriptor (&se, expr); 8620 1.1 mrg gfc_add_block_to_block (&block, &se.pre); 8621 1.1 mrg gfc_add_modify (&block, dest, se.expr); 8622 1.1 mrg 8623 1.1 mrg /* Deal with arrays of derived types with allocatable components. */ 8624 1.1 mrg if (gfc_bt_struct (cm->ts.type) 8625 1.1 mrg && cm->ts.u.derived->attr.alloc_comp) 8626 1.1 mrg // TODO: Fix caf_mode 8627 1.1 mrg tmp = gfc_copy_alloc_comp (cm->ts.u.derived, 8628 1.1 mrg se.expr, dest, 8629 1.1 mrg cm->as->rank, 0); 8630 1.1 mrg else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED 8631 1.1 mrg && CLASS_DATA(cm)->attr.allocatable) 8632 1.1 mrg { 8633 1.1 mrg if (cm->ts.u.derived->attr.alloc_comp) 8634 1.1 mrg // TODO: Fix caf_mode 8635 1.1 mrg tmp = gfc_copy_alloc_comp (expr->ts.u.derived, 8636 1.1 mrg se.expr, dest, 8637 1.1 mrg expr->rank, 0); 8638 1.1 mrg else 8639 1.1 mrg { 8640 1.1 mrg tmp = TREE_TYPE (dest); 8641 1.1 mrg tmp = gfc_duplicate_allocatable (dest, se.expr, 8642 1.1 mrg tmp, expr->rank, NULL_TREE); 8643 1.1 mrg } 8644 1.1 mrg } 8645 1.1 mrg else 8646 1.1 mrg tmp = gfc_duplicate_allocatable (dest, se.expr, 8647 1.1 mrg TREE_TYPE(cm->backend_decl), 8648 1.1 mrg cm->as->rank, NULL_TREE); 8649 1.1 mrg 8650 1.1 mrg gfc_add_expr_to_block (&block, tmp); 8651 1.1 mrg gfc_add_block_to_block (&block, &se.post); 8652 1.1 mrg 8653 1.1 mrg if (expr->expr_type != EXPR_VARIABLE) 8654 1.1 mrg gfc_conv_descriptor_data_set (&block, se.expr, 8655 1.1 mrg null_pointer_node); 8656 1.1 mrg 8657 1.1 mrg /* We need to know if the argument of a conversion function is a 8658 1.1 mrg variable, so that the correct lower bound can be used. */ 8659 1.1 mrg if (expr->expr_type == EXPR_FUNCTION 8660 1.1 mrg && expr->value.function.isym 8661 1.1 mrg && expr->value.function.isym->conversion 8662 1.1 mrg && expr->value.function.actual->expr 8663 1.1 mrg && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE) 8664 1.1 mrg arg = expr->value.function.actual->expr; 8665 1.1 mrg 8666 1.1 mrg /* Obtain the array spec of full array references. */ 8667 1.1 mrg if (arg) 8668 1.1 mrg as = gfc_get_full_arrayspec_from_expr (arg); 8669 1.1 mrg else 8670 1.1 mrg as = gfc_get_full_arrayspec_from_expr (expr); 8671 1.1 mrg 8672 1.1 mrg /* Shift the lbound and ubound of temporaries to being unity, 8673 1.1 mrg rather than zero, based. Always calculate the offset. */ 8674 1.1 mrg offset = gfc_conv_descriptor_offset_get (dest); 8675 1.1 mrg gfc_add_modify (&block, offset, gfc_index_zero_node); 8676 1.1 mrg tmp2 =gfc_create_var (gfc_array_index_type, NULL); 8677 1.1 mrg 8678 1.1 mrg for (n = 0; n < expr->rank; n++) 8679 1.1 mrg { 8680 1.1 mrg tree span; 8681 1.1 mrg tree lbound; 8682 1.1 mrg 8683 1.1 mrg /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9. 8684 1.1 mrg TODO It looks as if gfc_conv_expr_descriptor should return 8685 1.1 mrg the correct bounds and that the following should not be 8686 1.1 mrg necessary. This would simplify gfc_conv_intrinsic_bound 8687 1.1 mrg as well. */ 8688 1.1 mrg if (as && as->lower[n]) 8689 1.1 mrg { 8690 1.1 mrg gfc_se lbse; 8691 1.1 mrg gfc_init_se (&lbse, NULL); 8692 1.1 mrg gfc_conv_expr (&lbse, as->lower[n]); 8693 1.1 mrg gfc_add_block_to_block (&block, &lbse.pre); 8694 1.1 mrg lbound = gfc_evaluate_now (lbse.expr, &block); 8695 1.1 mrg } 8696 1.1 mrg else if (as && arg) 8697 1.1 mrg { 8698 1.1 mrg tmp = gfc_get_symbol_decl (arg->symtree->n.sym); 8699 1.1 mrg lbound = gfc_conv_descriptor_lbound_get (tmp, 8700 1.1 mrg gfc_rank_cst[n]); 8701 1.1 mrg } 8702 1.1 mrg else if (as) 8703 1.1 mrg lbound = gfc_conv_descriptor_lbound_get (dest, 8704 1.1 mrg gfc_rank_cst[n]); 8705 1.1 mrg else 8706 1.1 mrg lbound = gfc_index_one_node; 8707 1.1 mrg 8708 1.1 mrg lbound = fold_convert (gfc_array_index_type, lbound); 8709 1.1 mrg 8710 1.1 mrg /* Shift the bounds and set the offset accordingly. */ 8711 1.1 mrg tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]); 8712 1.1 mrg span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, 8713 1.1 mrg tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n])); 8714 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, 8715 1.1 mrg span, lbound); 8716 1.1 mrg gfc_conv_descriptor_ubound_set (&block, dest, 8717 1.1 mrg gfc_rank_cst[n], tmp); 8718 1.1 mrg gfc_conv_descriptor_lbound_set (&block, dest, 8719 1.1 mrg gfc_rank_cst[n], lbound); 8720 1.1 mrg 8721 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, 8722 1.1 mrg gfc_conv_descriptor_lbound_get (dest, 8723 1.1 mrg gfc_rank_cst[n]), 8724 1.1 mrg gfc_conv_descriptor_stride_get (dest, 8725 1.1 mrg gfc_rank_cst[n])); 8726 1.1 mrg gfc_add_modify (&block, tmp2, tmp); 8727 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, 8728 1.1 mrg offset, tmp2); 8729 1.1 mrg gfc_conv_descriptor_offset_set (&block, dest, tmp); 8730 1.1 mrg } 8731 1.1 mrg 8732 1.1 mrg if (arg) 8733 1.1 mrg { 8734 1.1 mrg /* If a conversion expression has a null data pointer 8735 1.1 mrg argument, nullify the allocatable component. */ 8736 1.1 mrg tree non_null_expr; 8737 1.1 mrg tree null_expr; 8738 1.1 mrg 8739 1.1 mrg if (arg->symtree->n.sym->attr.allocatable 8740 1.1 mrg || arg->symtree->n.sym->attr.pointer) 8741 1.1 mrg { 8742 1.1 mrg non_null_expr = gfc_finish_block (&block); 8743 1.1 mrg gfc_start_block (&block); 8744 1.1 mrg gfc_conv_descriptor_data_set (&block, dest, 8745 1.1 mrg null_pointer_node); 8746 1.1 mrg null_expr = gfc_finish_block (&block); 8747 1.1 mrg tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl); 8748 1.1 mrg tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp, 8749 1.1 mrg fold_convert (TREE_TYPE (tmp), null_pointer_node)); 8750 1.1 mrg return build3_v (COND_EXPR, tmp, 8751 1.1 mrg null_expr, non_null_expr); 8752 1.1 mrg } 8753 1.1 mrg } 8754 1.1 mrg 8755 1.1 mrg return gfc_finish_block (&block); 8756 1.1 mrg } 8757 1.1 mrg 8758 1.1 mrg 8759 1.1 mrg /* Allocate or reallocate scalar component, as necessary. */ 8760 1.1 mrg 8761 1.1 mrg static void 8762 1.1 mrg alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block, 8763 1.1 mrg tree comp, 8764 1.1 mrg gfc_component *cm, 8765 1.1 mrg gfc_expr *expr2, 8766 1.1 mrg gfc_symbol *sym) 8767 1.1 mrg { 8768 1.1 mrg tree tmp; 8769 1.1 mrg tree ptr; 8770 1.1 mrg tree size; 8771 1.1 mrg tree size_in_bytes; 8772 1.1 mrg tree lhs_cl_size = NULL_TREE; 8773 1.1 mrg 8774 1.1 mrg if (!comp) 8775 1.1 mrg return; 8776 1.1 mrg 8777 1.1 mrg if (!expr2 || expr2->rank) 8778 1.1 mrg return; 8779 1.1 mrg 8780 1.1 mrg realloc_lhs_warning (expr2->ts.type, false, &expr2->where); 8781 1.1 mrg 8782 1.1 mrg if (cm->ts.type == BT_CHARACTER && cm->ts.deferred) 8783 1.1 mrg { 8784 1.1 mrg char name[GFC_MAX_SYMBOL_LEN+9]; 8785 1.1 mrg gfc_component *strlen; 8786 1.1 mrg /* Use the rhs string length and the lhs element size. */ 8787 1.1 mrg gcc_assert (expr2->ts.type == BT_CHARACTER); 8788 1.1 mrg if (!expr2->ts.u.cl->backend_decl) 8789 1.1 mrg { 8790 1.1 mrg gfc_conv_string_length (expr2->ts.u.cl, expr2, block); 8791 1.1 mrg gcc_assert (expr2->ts.u.cl->backend_decl); 8792 1.1 mrg } 8793 1.1 mrg 8794 1.1 mrg size = expr2->ts.u.cl->backend_decl; 8795 1.1 mrg 8796 1.1 mrg /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length 8797 1.1 mrg component. */ 8798 1.1 mrg sprintf (name, "_%s_length", cm->name); 8799 1.1 mrg strlen = gfc_find_component (sym, name, true, true, NULL); 8800 1.1 mrg lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF, 8801 1.1 mrg gfc_charlen_type_node, 8802 1.1 mrg TREE_OPERAND (comp, 0), 8803 1.1 mrg strlen->backend_decl, NULL_TREE); 8804 1.1 mrg 8805 1.1 mrg tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts)); 8806 1.1 mrg tmp = TYPE_SIZE_UNIT (tmp); 8807 1.1 mrg size_in_bytes = fold_build2_loc (input_location, MULT_EXPR, 8808 1.1 mrg TREE_TYPE (tmp), tmp, 8809 1.1 mrg fold_convert (TREE_TYPE (tmp), size)); 8810 1.1 mrg } 8811 1.1 mrg else if (cm->ts.type == BT_CLASS) 8812 1.1 mrg { 8813 1.1 mrg gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED); 8814 1.1 mrg if (expr2->ts.type == BT_DERIVED) 8815 1.1 mrg { 8816 1.1 mrg tmp = gfc_get_symbol_decl (expr2->ts.u.derived); 8817 1.1 mrg size = TYPE_SIZE_UNIT (tmp); 8818 1.1 mrg } 8819 1.1 mrg else 8820 1.1 mrg { 8821 1.1 mrg gfc_expr *e2vtab; 8822 1.1 mrg gfc_se se; 8823 1.1 mrg e2vtab = gfc_find_and_cut_at_last_class_ref (expr2); 8824 1.1 mrg gfc_add_vptr_component (e2vtab); 8825 1.1 mrg gfc_add_size_component (e2vtab); 8826 1.1 mrg gfc_init_se (&se, NULL); 8827 1.1 mrg gfc_conv_expr (&se, e2vtab); 8828 1.1 mrg gfc_add_block_to_block (block, &se.pre); 8829 1.1 mrg size = fold_convert (size_type_node, se.expr); 8830 1.1 mrg gfc_free_expr (e2vtab); 8831 1.1 mrg } 8832 1.1 mrg size_in_bytes = size; 8833 1.1 mrg } 8834 1.1 mrg else 8835 1.1 mrg { 8836 1.1 mrg /* Otherwise use the length in bytes of the rhs. */ 8837 1.1 mrg size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts)); 8838 1.1 mrg size_in_bytes = size; 8839 1.1 mrg } 8840 1.1 mrg 8841 1.1 mrg size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node, 8842 1.1 mrg size_in_bytes, size_one_node); 8843 1.1 mrg 8844 1.1 mrg if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp) 8845 1.1 mrg { 8846 1.1 mrg tmp = build_call_expr_loc (input_location, 8847 1.1 mrg builtin_decl_explicit (BUILT_IN_CALLOC), 8848 1.1 mrg 2, build_one_cst (size_type_node), 8849 1.1 mrg size_in_bytes); 8850 1.1 mrg tmp = fold_convert (TREE_TYPE (comp), tmp); 8851 1.1 mrg gfc_add_modify (block, comp, tmp); 8852 1.1 mrg } 8853 1.1 mrg else 8854 1.1 mrg { 8855 1.1 mrg tmp = build_call_expr_loc (input_location, 8856 1.1 mrg builtin_decl_explicit (BUILT_IN_MALLOC), 8857 1.1 mrg 1, size_in_bytes); 8858 1.1 mrg if (GFC_CLASS_TYPE_P (TREE_TYPE (comp))) 8859 1.1 mrg ptr = gfc_class_data_get (comp); 8860 1.1 mrg else 8861 1.1 mrg ptr = comp; 8862 1.1 mrg tmp = fold_convert (TREE_TYPE (ptr), tmp); 8863 1.1 mrg gfc_add_modify (block, ptr, tmp); 8864 1.1 mrg } 8865 1.1 mrg 8866 1.1 mrg if (cm->ts.type == BT_CHARACTER && cm->ts.deferred) 8867 1.1 mrg /* Update the lhs character length. */ 8868 1.1 mrg gfc_add_modify (block, lhs_cl_size, 8869 1.1 mrg fold_convert (TREE_TYPE (lhs_cl_size), size)); 8870 1.1 mrg } 8871 1.1 mrg 8872 1.1 mrg 8873 1.1 mrg /* Assign a single component of a derived type constructor. */ 8874 1.1 mrg 8875 1.1 mrg static tree 8876 1.1 mrg gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr, 8877 1.1 mrg gfc_symbol *sym, bool init) 8878 1.1 mrg { 8879 1.1 mrg gfc_se se; 8880 1.1 mrg gfc_se lse; 8881 1.1 mrg stmtblock_t block; 8882 1.1 mrg tree tmp; 8883 1.1 mrg tree vtab; 8884 1.1 mrg 8885 1.1 mrg gfc_start_block (&block); 8886 1.1 mrg 8887 1.1 mrg if (cm->attr.pointer || cm->attr.proc_pointer) 8888 1.1 mrg { 8889 1.1 mrg /* Only care about pointers here, not about allocatables. */ 8890 1.1 mrg gfc_init_se (&se, NULL); 8891 1.1 mrg /* Pointer component. */ 8892 1.1 mrg if ((cm->attr.dimension || cm->attr.codimension) 8893 1.1 mrg && !cm->attr.proc_pointer) 8894 1.1 mrg { 8895 1.1 mrg /* Array pointer. */ 8896 1.1 mrg if (expr->expr_type == EXPR_NULL) 8897 1.1 mrg gfc_conv_descriptor_data_set (&block, dest, null_pointer_node); 8898 1.1 mrg else 8899 1.1 mrg { 8900 1.1 mrg se.direct_byref = 1; 8901 1.1 mrg se.expr = dest; 8902 1.1 mrg gfc_conv_expr_descriptor (&se, expr); 8903 1.1 mrg gfc_add_block_to_block (&block, &se.pre); 8904 1.1 mrg gfc_add_block_to_block (&block, &se.post); 8905 1.1 mrg } 8906 1.1 mrg } 8907 1.1 mrg else 8908 1.1 mrg { 8909 1.1 mrg /* Scalar pointers. */ 8910 1.1 mrg se.want_pointer = 1; 8911 1.1 mrg gfc_conv_expr (&se, expr); 8912 1.1 mrg gfc_add_block_to_block (&block, &se.pre); 8913 1.1 mrg 8914 1.1 mrg if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer 8915 1.1 mrg && expr->symtree->n.sym->attr.dummy) 8916 1.1 mrg se.expr = build_fold_indirect_ref_loc (input_location, se.expr); 8917 1.1 mrg 8918 1.1 mrg gfc_add_modify (&block, dest, 8919 1.1 mrg fold_convert (TREE_TYPE (dest), se.expr)); 8920 1.1 mrg gfc_add_block_to_block (&block, &se.post); 8921 1.1 mrg } 8922 1.1 mrg } 8923 1.1 mrg else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL) 8924 1.1 mrg { 8925 1.1 mrg /* NULL initialization for CLASS components. */ 8926 1.1 mrg tmp = gfc_trans_structure_assign (dest, 8927 1.1 mrg gfc_class_initializer (&cm->ts, expr), 8928 1.1 mrg false); 8929 1.1 mrg gfc_add_expr_to_block (&block, tmp); 8930 1.1 mrg } 8931 1.1 mrg else if ((cm->attr.dimension || cm->attr.codimension) 8932 1.1 mrg && !cm->attr.proc_pointer) 8933 1.1 mrg { 8934 1.1 mrg if (cm->attr.allocatable && expr->expr_type == EXPR_NULL) 8935 1.1 mrg gfc_conv_descriptor_data_set (&block, dest, null_pointer_node); 8936 1.1 mrg else if (cm->attr.allocatable || cm->attr.pdt_array) 8937 1.1 mrg { 8938 1.1 mrg tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr); 8939 1.1 mrg gfc_add_expr_to_block (&block, tmp); 8940 1.1 mrg } 8941 1.1 mrg else 8942 1.1 mrg { 8943 1.1 mrg tmp = gfc_trans_subarray_assign (dest, cm, expr); 8944 1.1 mrg gfc_add_expr_to_block (&block, tmp); 8945 1.1 mrg } 8946 1.1 mrg } 8947 1.1 mrg else if (cm->ts.type == BT_CLASS 8948 1.1 mrg && CLASS_DATA (cm)->attr.dimension 8949 1.1 mrg && CLASS_DATA (cm)->attr.allocatable 8950 1.1 mrg && expr->ts.type == BT_DERIVED) 8951 1.1 mrg { 8952 1.1 mrg vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts)); 8953 1.1 mrg vtab = gfc_build_addr_expr (NULL_TREE, vtab); 8954 1.1 mrg tmp = gfc_class_vptr_get (dest); 8955 1.1 mrg gfc_add_modify (&block, tmp, 8956 1.1 mrg fold_convert (TREE_TYPE (tmp), vtab)); 8957 1.1 mrg tmp = gfc_class_data_get (dest); 8958 1.1 mrg tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr); 8959 1.1 mrg gfc_add_expr_to_block (&block, tmp); 8960 1.1 mrg } 8961 1.1 mrg else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL) 8962 1.1 mrg { 8963 1.1 mrg /* NULL initialization for allocatable components. */ 8964 1.1 mrg gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest), 8965 1.1 mrg null_pointer_node)); 8966 1.1 mrg } 8967 1.1 mrg else if (init && (cm->attr.allocatable 8968 1.1 mrg || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable 8969 1.1 mrg && expr->ts.type != BT_CLASS))) 8970 1.1 mrg { 8971 1.1 mrg /* Take care about non-array allocatable components here. The alloc_* 8972 1.1 mrg routine below is motivated by the alloc_scalar_allocatable_for_ 8973 1.1 mrg assignment() routine, but with the realloc portions removed and 8974 1.1 mrg different input. */ 8975 1.1 mrg alloc_scalar_allocatable_for_subcomponent_assignment (&block, 8976 1.1 mrg dest, 8977 1.1 mrg cm, 8978 1.1 mrg expr, 8979 1.1 mrg sym); 8980 1.1 mrg /* The remainder of these instructions follow the if (cm->attr.pointer) 8981 1.1 mrg if (!cm->attr.dimension) part above. */ 8982 1.1 mrg gfc_init_se (&se, NULL); 8983 1.1 mrg gfc_conv_expr (&se, expr); 8984 1.1 mrg gfc_add_block_to_block (&block, &se.pre); 8985 1.1 mrg 8986 1.1 mrg if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer 8987 1.1 mrg && expr->symtree->n.sym->attr.dummy) 8988 1.1 mrg se.expr = build_fold_indirect_ref_loc (input_location, se.expr); 8989 1.1 mrg 8990 1.1 mrg if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED) 8991 1.1 mrg { 8992 1.1 mrg tmp = gfc_class_data_get (dest); 8993 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp); 8994 1.1 mrg vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts)); 8995 1.1 mrg vtab = gfc_build_addr_expr (NULL_TREE, vtab); 8996 1.1 mrg gfc_add_modify (&block, gfc_class_vptr_get (dest), 8997 1.1 mrg fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab)); 8998 1.1 mrg } 8999 1.1 mrg else 9000 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, dest); 9001 1.1 mrg 9002 1.1 mrg /* For deferred strings insert a memcpy. */ 9003 1.1 mrg if (cm->ts.type == BT_CHARACTER && cm->ts.deferred) 9004 1.1 mrg { 9005 1.1 mrg tree size; 9006 1.1 mrg gcc_assert (se.string_length || expr->ts.u.cl->backend_decl); 9007 1.1 mrg size = size_of_string_in_bytes (cm->ts.kind, se.string_length 9008 1.1 mrg ? se.string_length 9009 1.1 mrg : expr->ts.u.cl->backend_decl); 9010 1.1 mrg tmp = gfc_build_memcpy_call (tmp, se.expr, size); 9011 1.1 mrg gfc_add_expr_to_block (&block, tmp); 9012 1.1 mrg } 9013 1.1 mrg else 9014 1.1 mrg gfc_add_modify (&block, tmp, 9015 1.1 mrg fold_convert (TREE_TYPE (tmp), se.expr)); 9016 1.1 mrg gfc_add_block_to_block (&block, &se.post); 9017 1.1 mrg } 9018 1.1 mrg else if (expr->ts.type == BT_UNION) 9019 1.1 mrg { 9020 1.1 mrg tree tmp; 9021 1.1 mrg gfc_constructor *c = gfc_constructor_first (expr->value.constructor); 9022 1.1 mrg /* We mark that the entire union should be initialized with a contrived 9023 1.1 mrg EXPR_NULL expression at the beginning. */ 9024 1.1 mrg if (c != NULL && c->n.component == NULL 9025 1.1 mrg && c->expr != NULL && c->expr->expr_type == EXPR_NULL) 9026 1.1 mrg { 9027 1.1 mrg tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node, 9028 1.1 mrg dest, build_constructor (TREE_TYPE (dest), NULL)); 9029 1.1 mrg gfc_add_expr_to_block (&block, tmp); 9030 1.1 mrg c = gfc_constructor_next (c); 9031 1.1 mrg } 9032 1.1 mrg /* The following constructor expression, if any, represents a specific 9033 1.1 mrg map intializer, as given by the user. */ 9034 1.1 mrg if (c != NULL && c->expr != NULL) 9035 1.1 mrg { 9036 1.1 mrg gcc_assert (expr->expr_type == EXPR_STRUCTURE); 9037 1.1 mrg tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL); 9038 1.1 mrg gfc_add_expr_to_block (&block, tmp); 9039 1.1 mrg } 9040 1.1 mrg } 9041 1.1 mrg else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID) 9042 1.1 mrg { 9043 1.1 mrg if (expr->expr_type != EXPR_STRUCTURE) 9044 1.1 mrg { 9045 1.1 mrg tree dealloc = NULL_TREE; 9046 1.1 mrg gfc_init_se (&se, NULL); 9047 1.1 mrg gfc_conv_expr (&se, expr); 9048 1.1 mrg gfc_add_block_to_block (&block, &se.pre); 9049 1.1 mrg /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the 9050 1.1 mrg expression in a temporary variable and deallocate the allocatable 9051 1.1 mrg components. Then we can the copy the expression to the result. */ 9052 1.1 mrg if (cm->ts.u.derived->attr.alloc_comp 9053 1.1 mrg && expr->expr_type != EXPR_VARIABLE) 9054 1.1 mrg { 9055 1.1 mrg se.expr = gfc_evaluate_now (se.expr, &block); 9056 1.1 mrg dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr, 9057 1.1 mrg expr->rank); 9058 1.1 mrg } 9059 1.1 mrg gfc_add_modify (&block, dest, 9060 1.1 mrg fold_convert (TREE_TYPE (dest), se.expr)); 9061 1.1 mrg if (cm->ts.u.derived->attr.alloc_comp 9062 1.1 mrg && expr->expr_type != EXPR_NULL) 9063 1.1 mrg { 9064 1.1 mrg // TODO: Fix caf_mode 9065 1.1 mrg tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr, 9066 1.1 mrg dest, expr->rank, 0); 9067 1.1 mrg gfc_add_expr_to_block (&block, tmp); 9068 1.1 mrg if (dealloc != NULL_TREE) 9069 1.1 mrg gfc_add_expr_to_block (&block, dealloc); 9070 1.1 mrg } 9071 1.1 mrg gfc_add_block_to_block (&block, &se.post); 9072 1.1 mrg } 9073 1.1 mrg else 9074 1.1 mrg { 9075 1.1 mrg /* Nested constructors. */ 9076 1.1 mrg tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL); 9077 1.1 mrg gfc_add_expr_to_block (&block, tmp); 9078 1.1 mrg } 9079 1.1 mrg } 9080 1.1 mrg else if (gfc_deferred_strlen (cm, &tmp)) 9081 1.1 mrg { 9082 1.1 mrg tree strlen; 9083 1.1 mrg strlen = tmp; 9084 1.1 mrg gcc_assert (strlen); 9085 1.1 mrg strlen = fold_build3_loc (input_location, COMPONENT_REF, 9086 1.1 mrg TREE_TYPE (strlen), 9087 1.1 mrg TREE_OPERAND (dest, 0), 9088 1.1 mrg strlen, NULL_TREE); 9089 1.1 mrg 9090 1.1 mrg if (expr->expr_type == EXPR_NULL) 9091 1.1 mrg { 9092 1.1 mrg tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0); 9093 1.1 mrg gfc_add_modify (&block, dest, tmp); 9094 1.1 mrg tmp = build_int_cst (TREE_TYPE (strlen), 0); 9095 1.1 mrg gfc_add_modify (&block, strlen, tmp); 9096 1.1 mrg } 9097 1.1 mrg else 9098 1.1 mrg { 9099 1.1 mrg tree size; 9100 1.1 mrg gfc_init_se (&se, NULL); 9101 1.1 mrg gfc_conv_expr (&se, expr); 9102 1.1 mrg size = size_of_string_in_bytes (cm->ts.kind, se.string_length); 9103 1.1 mrg tmp = build_call_expr_loc (input_location, 9104 1.1 mrg builtin_decl_explicit (BUILT_IN_MALLOC), 9105 1.1 mrg 1, size); 9106 1.1 mrg gfc_add_modify (&block, dest, 9107 1.1 mrg fold_convert (TREE_TYPE (dest), tmp)); 9108 1.1 mrg gfc_add_modify (&block, strlen, 9109 1.1 mrg fold_convert (TREE_TYPE (strlen), se.string_length)); 9110 1.1 mrg tmp = gfc_build_memcpy_call (dest, se.expr, size); 9111 1.1 mrg gfc_add_expr_to_block (&block, tmp); 9112 1.1 mrg } 9113 1.1 mrg } 9114 1.1 mrg else if (!cm->attr.artificial) 9115 1.1 mrg { 9116 1.1 mrg /* Scalar component (excluding deferred parameters). */ 9117 1.1 mrg gfc_init_se (&se, NULL); 9118 1.1 mrg gfc_init_se (&lse, NULL); 9119 1.1 mrg 9120 1.1 mrg gfc_conv_expr (&se, expr); 9121 1.1 mrg if (cm->ts.type == BT_CHARACTER) 9122 1.1 mrg lse.string_length = cm->ts.u.cl->backend_decl; 9123 1.1 mrg lse.expr = dest; 9124 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false); 9125 1.1 mrg gfc_add_expr_to_block (&block, tmp); 9126 1.1 mrg } 9127 1.1 mrg return gfc_finish_block (&block); 9128 1.1 mrg } 9129 1.1 mrg 9130 1.1 mrg /* Assign a derived type constructor to a variable. */ 9131 1.1 mrg 9132 1.1 mrg tree 9133 1.1 mrg gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray) 9134 1.1 mrg { 9135 1.1 mrg gfc_constructor *c; 9136 1.1 mrg gfc_component *cm; 9137 1.1 mrg stmtblock_t block; 9138 1.1 mrg tree field; 9139 1.1 mrg tree tmp; 9140 1.1 mrg gfc_se se; 9141 1.1 mrg 9142 1.1 mrg gfc_start_block (&block); 9143 1.1 mrg 9144 1.1 mrg if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING 9145 1.1 mrg && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR 9146 1.1 mrg || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR)) 9147 1.1 mrg { 9148 1.1 mrg gfc_se lse; 9149 1.1 mrg 9150 1.1 mrg gfc_init_se (&se, NULL); 9151 1.1 mrg gfc_init_se (&lse, NULL); 9152 1.1 mrg gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr); 9153 1.1 mrg lse.expr = dest; 9154 1.1 mrg gfc_add_modify (&block, lse.expr, 9155 1.1 mrg fold_convert (TREE_TYPE (lse.expr), se.expr)); 9156 1.1 mrg 9157 1.1 mrg return gfc_finish_block (&block); 9158 1.1 mrg } 9159 1.1 mrg 9160 1.1 mrg /* Make sure that the derived type has been completely built. */ 9161 1.1 mrg if (!expr->ts.u.derived->backend_decl 9162 1.1 mrg || !TYPE_FIELDS (expr->ts.u.derived->backend_decl)) 9163 1.1 mrg { 9164 1.1 mrg tmp = gfc_typenode_for_spec (&expr->ts); 9165 1.1 mrg gcc_assert (tmp); 9166 1.1 mrg } 9167 1.1 mrg 9168 1.1 mrg cm = expr->ts.u.derived->components; 9169 1.1 mrg 9170 1.1 mrg 9171 1.1 mrg if (coarray) 9172 1.1 mrg gfc_init_se (&se, NULL); 9173 1.1 mrg 9174 1.1 mrg for (c = gfc_constructor_first (expr->value.constructor); 9175 1.1 mrg c; c = gfc_constructor_next (c), cm = cm->next) 9176 1.1 mrg { 9177 1.1 mrg /* Skip absent members in default initializers. */ 9178 1.1 mrg if (!c->expr && !cm->attr.allocatable) 9179 1.1 mrg continue; 9180 1.1 mrg 9181 1.1 mrg /* Register the component with the caf-lib before it is initialized. 9182 1.1 mrg Register only allocatable components, that are not coarray'ed 9183 1.1 mrg components (%comp[*]). Only register when the constructor is not the 9184 1.1 mrg null-expression. */ 9185 1.1 mrg if (coarray && !cm->attr.codimension 9186 1.1 mrg && (cm->attr.allocatable || cm->attr.pointer) 9187 1.1 mrg && (!c->expr || c->expr->expr_type == EXPR_NULL)) 9188 1.1 mrg { 9189 1.1 mrg tree token, desc, size; 9190 1.1 mrg bool is_array = cm->ts.type == BT_CLASS 9191 1.1 mrg ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension; 9192 1.1 mrg 9193 1.1 mrg field = cm->backend_decl; 9194 1.1 mrg field = fold_build3_loc (input_location, COMPONENT_REF, 9195 1.1 mrg TREE_TYPE (field), dest, field, NULL_TREE); 9196 1.1 mrg if (cm->ts.type == BT_CLASS) 9197 1.1 mrg field = gfc_class_data_get (field); 9198 1.1 mrg 9199 1.1 mrg token = is_array ? gfc_conv_descriptor_token (field) 9200 1.1 mrg : fold_build3_loc (input_location, COMPONENT_REF, 9201 1.1 mrg TREE_TYPE (cm->caf_token), dest, 9202 1.1 mrg cm->caf_token, NULL_TREE); 9203 1.1 mrg 9204 1.1 mrg if (is_array) 9205 1.1 mrg { 9206 1.1 mrg /* The _caf_register routine looks at the rank of the array 9207 1.1 mrg descriptor to decide whether the data registered is an array 9208 1.1 mrg or not. */ 9209 1.1 mrg int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank 9210 1.1 mrg : cm->as->rank; 9211 1.1 mrg /* When the rank is not known just set a positive rank, which 9212 1.1 mrg suffices to recognize the data as array. */ 9213 1.1 mrg if (rank < 0) 9214 1.1 mrg rank = 1; 9215 1.1 mrg size = build_zero_cst (size_type_node); 9216 1.1 mrg desc = field; 9217 1.1 mrg gfc_add_modify (&block, gfc_conv_descriptor_rank (desc), 9218 1.1 mrg build_int_cst (signed_char_type_node, rank)); 9219 1.1 mrg } 9220 1.1 mrg else 9221 1.1 mrg { 9222 1.1 mrg desc = gfc_conv_scalar_to_descriptor (&se, field, 9223 1.1 mrg cm->ts.type == BT_CLASS 9224 1.1 mrg ? CLASS_DATA (cm)->attr 9225 1.1 mrg : cm->attr); 9226 1.1 mrg size = TYPE_SIZE_UNIT (TREE_TYPE (field)); 9227 1.1 mrg } 9228 1.1 mrg gfc_add_block_to_block (&block, &se.pre); 9229 1.1 mrg tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register, 9230 1.1 mrg 7, size, build_int_cst ( 9231 1.1 mrg integer_type_node, 9232 1.1 mrg GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY), 9233 1.1 mrg gfc_build_addr_expr (pvoid_type_node, 9234 1.1 mrg token), 9235 1.1 mrg gfc_build_addr_expr (NULL_TREE, desc), 9236 1.1 mrg null_pointer_node, null_pointer_node, 9237 1.1 mrg integer_zero_node); 9238 1.1 mrg gfc_add_expr_to_block (&block, tmp); 9239 1.1 mrg } 9240 1.1 mrg field = cm->backend_decl; 9241 1.1 mrg gcc_assert(field); 9242 1.1 mrg tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), 9243 1.1 mrg dest, field, NULL_TREE); 9244 1.1 mrg if (!c->expr) 9245 1.1 mrg { 9246 1.1 mrg gfc_expr *e = gfc_get_null_expr (NULL); 9247 1.1 mrg tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived, 9248 1.1 mrg init); 9249 1.1 mrg gfc_free_expr (e); 9250 1.1 mrg } 9251 1.1 mrg else 9252 1.1 mrg tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr, 9253 1.1 mrg expr->ts.u.derived, init); 9254 1.1 mrg gfc_add_expr_to_block (&block, tmp); 9255 1.1 mrg } 9256 1.1 mrg return gfc_finish_block (&block); 9257 1.1 mrg } 9258 1.1 mrg 9259 1.1 mrg static void 9260 1.1 mrg gfc_conv_union_initializer (vec<constructor_elt, va_gc> *&v, 9261 1.1 mrg gfc_component *un, gfc_expr *init) 9262 1.1 mrg { 9263 1.1 mrg gfc_constructor *ctor; 9264 1.1 mrg 9265 1.1 mrg if (un->ts.type != BT_UNION || un == NULL || init == NULL) 9266 1.1 mrg return; 9267 1.1 mrg 9268 1.1 mrg ctor = gfc_constructor_first (init->value.constructor); 9269 1.1 mrg 9270 1.1 mrg if (ctor == NULL || ctor->expr == NULL) 9271 1.1 mrg return; 9272 1.1 mrg 9273 1.1 mrg gcc_assert (init->expr_type == EXPR_STRUCTURE); 9274 1.1 mrg 9275 1.1 mrg /* If we have an 'initialize all' constructor, do it first. */ 9276 1.1 mrg if (ctor->expr->expr_type == EXPR_NULL) 9277 1.1 mrg { 9278 1.1 mrg tree union_type = TREE_TYPE (un->backend_decl); 9279 1.1 mrg tree val = build_constructor (union_type, NULL); 9280 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val); 9281 1.1 mrg ctor = gfc_constructor_next (ctor); 9282 1.1 mrg } 9283 1.1 mrg 9284 1.1 mrg /* Add the map initializer on top. */ 9285 1.1 mrg if (ctor != NULL && ctor->expr != NULL) 9286 1.1 mrg { 9287 1.1 mrg gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE); 9288 1.1 mrg tree val = gfc_conv_initializer (ctor->expr, &un->ts, 9289 1.1 mrg TREE_TYPE (un->backend_decl), 9290 1.1 mrg un->attr.dimension, un->attr.pointer, 9291 1.1 mrg un->attr.proc_pointer); 9292 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val); 9293 1.1 mrg } 9294 1.1 mrg } 9295 1.1 mrg 9296 1.1 mrg /* Build an expression for a constructor. If init is nonzero then 9297 1.1 mrg this is part of a static variable initializer. */ 9298 1.1 mrg 9299 1.1 mrg void 9300 1.1 mrg gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init) 9301 1.1 mrg { 9302 1.1 mrg gfc_constructor *c; 9303 1.1 mrg gfc_component *cm; 9304 1.1 mrg tree val; 9305 1.1 mrg tree type; 9306 1.1 mrg tree tmp; 9307 1.1 mrg vec<constructor_elt, va_gc> *v = NULL; 9308 1.1 mrg 9309 1.1 mrg gcc_assert (se->ss == NULL); 9310 1.1 mrg gcc_assert (expr->expr_type == EXPR_STRUCTURE); 9311 1.1 mrg type = gfc_typenode_for_spec (&expr->ts); 9312 1.1 mrg 9313 1.1 mrg if (!init) 9314 1.1 mrg { 9315 1.1 mrg /* Create a temporary variable and fill it in. */ 9316 1.1 mrg se->expr = gfc_create_var (type, expr->ts.u.derived->name); 9317 1.1 mrg /* The symtree in expr is NULL, if the code to generate is for 9318 1.1 mrg initializing the static members only. */ 9319 1.1 mrg tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL, 9320 1.1 mrg se->want_coarray); 9321 1.1 mrg gfc_add_expr_to_block (&se->pre, tmp); 9322 1.1 mrg return; 9323 1.1 mrg } 9324 1.1 mrg 9325 1.1 mrg cm = expr->ts.u.derived->components; 9326 1.1 mrg 9327 1.1 mrg for (c = gfc_constructor_first (expr->value.constructor); 9328 1.1 mrg c && cm; c = gfc_constructor_next (c), cm = cm->next) 9329 1.1 mrg { 9330 1.1 mrg /* Skip absent members in default initializers and allocatable 9331 1.1 mrg components. Although the latter have a default initializer 9332 1.1 mrg of EXPR_NULL,... by default, the static nullify is not needed 9333 1.1 mrg since this is done every time we come into scope. */ 9334 1.1 mrg if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE)) 9335 1.1 mrg continue; 9336 1.1 mrg 9337 1.1 mrg if (cm->initializer && cm->initializer->expr_type != EXPR_NULL 9338 1.1 mrg && strcmp (cm->name, "_extends") == 0 9339 1.1 mrg && cm->initializer->symtree) 9340 1.1 mrg { 9341 1.1 mrg tree vtab; 9342 1.1 mrg gfc_symbol *vtabs; 9343 1.1 mrg vtabs = cm->initializer->symtree->n.sym; 9344 1.1 mrg vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs)); 9345 1.1 mrg vtab = unshare_expr_without_location (vtab); 9346 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab); 9347 1.1 mrg } 9348 1.1 mrg else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0) 9349 1.1 mrg { 9350 1.1 mrg val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived)); 9351 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, 9352 1.1 mrg fold_convert (TREE_TYPE (cm->backend_decl), 9353 1.1 mrg val)); 9354 1.1 mrg } 9355 1.1 mrg else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0) 9356 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, 9357 1.1 mrg fold_convert (TREE_TYPE (cm->backend_decl), 9358 1.1 mrg integer_zero_node)); 9359 1.1 mrg else if (cm->ts.type == BT_UNION) 9360 1.1 mrg gfc_conv_union_initializer (v, cm, c->expr); 9361 1.1 mrg else 9362 1.1 mrg { 9363 1.1 mrg val = gfc_conv_initializer (c->expr, &cm->ts, 9364 1.1 mrg TREE_TYPE (cm->backend_decl), 9365 1.1 mrg cm->attr.dimension, cm->attr.pointer, 9366 1.1 mrg cm->attr.proc_pointer); 9367 1.1 mrg val = unshare_expr_without_location (val); 9368 1.1 mrg 9369 1.1 mrg /* Append it to the constructor list. */ 9370 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val); 9371 1.1 mrg } 9372 1.1 mrg } 9373 1.1 mrg 9374 1.1 mrg se->expr = build_constructor (type, v); 9375 1.1 mrg if (init) 9376 1.1 mrg TREE_CONSTANT (se->expr) = 1; 9377 1.1 mrg } 9378 1.1 mrg 9379 1.1 mrg 9380 1.1 mrg /* Translate a substring expression. */ 9381 1.1 mrg 9382 1.1 mrg static void 9383 1.1 mrg gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr) 9384 1.1 mrg { 9385 1.1 mrg gfc_ref *ref; 9386 1.1 mrg 9387 1.1 mrg ref = expr->ref; 9388 1.1 mrg 9389 1.1 mrg gcc_assert (ref == NULL || ref->type == REF_SUBSTRING); 9390 1.1 mrg 9391 1.1 mrg se->expr = gfc_build_wide_string_const (expr->ts.kind, 9392 1.1 mrg expr->value.character.length, 9393 1.1 mrg expr->value.character.string); 9394 1.1 mrg 9395 1.1 mrg se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr))); 9396 1.1 mrg TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1; 9397 1.1 mrg 9398 1.1 mrg if (ref) 9399 1.1 mrg gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where); 9400 1.1 mrg } 9401 1.1 mrg 9402 1.1 mrg 9403 1.1 mrg /* Entry point for expression translation. Evaluates a scalar quantity. 9404 1.1 mrg EXPR is the expression to be translated, and SE is the state structure if 9405 1.1 mrg called from within the scalarized. */ 9406 1.1 mrg 9407 1.1 mrg void 9408 1.1 mrg gfc_conv_expr (gfc_se * se, gfc_expr * expr) 9409 1.1 mrg { 9410 1.1 mrg gfc_ss *ss; 9411 1.1 mrg 9412 1.1 mrg ss = se->ss; 9413 1.1 mrg if (ss && ss->info->expr == expr 9414 1.1 mrg && (ss->info->type == GFC_SS_SCALAR 9415 1.1 mrg || ss->info->type == GFC_SS_REFERENCE)) 9416 1.1 mrg { 9417 1.1 mrg gfc_ss_info *ss_info; 9418 1.1 mrg 9419 1.1 mrg ss_info = ss->info; 9420 1.1 mrg /* Substitute a scalar expression evaluated outside the scalarization 9421 1.1 mrg loop. */ 9422 1.1 mrg se->expr = ss_info->data.scalar.value; 9423 1.1 mrg if (gfc_scalar_elemental_arg_saved_as_reference (ss_info)) 9424 1.1 mrg se->expr = build_fold_indirect_ref_loc (input_location, se->expr); 9425 1.1 mrg 9426 1.1 mrg se->string_length = ss_info->string_length; 9427 1.1 mrg gfc_advance_se_ss_chain (se); 9428 1.1 mrg return; 9429 1.1 mrg } 9430 1.1 mrg 9431 1.1 mrg /* We need to convert the expressions for the iso_c_binding derived types. 9432 1.1 mrg C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to 9433 1.1 mrg null_pointer_node. C_PTR and C_FUNPTR are converted to match the 9434 1.1 mrg typespec for the C_PTR and C_FUNPTR symbols, which has already been 9435 1.1 mrg updated to be an integer with a kind equal to the size of a (void *). */ 9436 1.1 mrg if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID 9437 1.1 mrg && expr->ts.u.derived->attr.is_bind_c) 9438 1.1 mrg { 9439 1.1 mrg if (expr->expr_type == EXPR_VARIABLE 9440 1.1 mrg && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR 9441 1.1 mrg || expr->symtree->n.sym->intmod_sym_id 9442 1.1 mrg == ISOCBINDING_NULL_FUNPTR)) 9443 1.1 mrg { 9444 1.1 mrg /* Set expr_type to EXPR_NULL, which will result in 9445 1.1 mrg null_pointer_node being used below. */ 9446 1.1 mrg expr->expr_type = EXPR_NULL; 9447 1.1 mrg } 9448 1.1 mrg else 9449 1.1 mrg { 9450 1.1 mrg /* Update the type/kind of the expression to be what the new 9451 1.1 mrg type/kind are for the updated symbols of C_PTR/C_FUNPTR. */ 9452 1.1 mrg expr->ts.type = BT_INTEGER; 9453 1.1 mrg expr->ts.f90_type = BT_VOID; 9454 1.1 mrg expr->ts.kind = gfc_index_integer_kind; 9455 1.1 mrg } 9456 1.1 mrg } 9457 1.1 mrg 9458 1.1 mrg gfc_fix_class_refs (expr); 9459 1.1 mrg 9460 1.1 mrg switch (expr->expr_type) 9461 1.1 mrg { 9462 1.1 mrg case EXPR_OP: 9463 1.1 mrg gfc_conv_expr_op (se, expr); 9464 1.1 mrg break; 9465 1.1 mrg 9466 1.1 mrg case EXPR_FUNCTION: 9467 1.1 mrg gfc_conv_function_expr (se, expr); 9468 1.1 mrg break; 9469 1.1 mrg 9470 1.1 mrg case EXPR_CONSTANT: 9471 1.1 mrg gfc_conv_constant (se, expr); 9472 1.1 mrg break; 9473 1.1 mrg 9474 1.1 mrg case EXPR_VARIABLE: 9475 1.1 mrg gfc_conv_variable (se, expr); 9476 1.1 mrg break; 9477 1.1 mrg 9478 1.1 mrg case EXPR_NULL: 9479 1.1 mrg se->expr = null_pointer_node; 9480 1.1 mrg break; 9481 1.1 mrg 9482 1.1 mrg case EXPR_SUBSTRING: 9483 1.1 mrg gfc_conv_substring_expr (se, expr); 9484 1.1 mrg break; 9485 1.1 mrg 9486 1.1 mrg case EXPR_STRUCTURE: 9487 1.1 mrg gfc_conv_structure (se, expr, 0); 9488 1.1 mrg break; 9489 1.1 mrg 9490 1.1 mrg case EXPR_ARRAY: 9491 1.1 mrg gfc_conv_array_constructor_expr (se, expr); 9492 1.1 mrg break; 9493 1.1 mrg 9494 1.1 mrg default: 9495 1.1 mrg gcc_unreachable (); 9496 1.1 mrg break; 9497 1.1 mrg } 9498 1.1 mrg } 9499 1.1 mrg 9500 1.1 mrg /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs 9501 1.1 mrg of an assignment. */ 9502 1.1 mrg void 9503 1.1 mrg gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr) 9504 1.1 mrg { 9505 1.1 mrg gfc_conv_expr (se, expr); 9506 1.1 mrg /* All numeric lvalues should have empty post chains. If not we need to 9507 1.1 mrg figure out a way of rewriting an lvalue so that it has no post chain. */ 9508 1.1 mrg gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head); 9509 1.1 mrg } 9510 1.1 mrg 9511 1.1 mrg /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for 9512 1.1 mrg numeric expressions. Used for scalar values where inserting cleanup code 9513 1.1 mrg is inconvenient. */ 9514 1.1 mrg void 9515 1.1 mrg gfc_conv_expr_val (gfc_se * se, gfc_expr * expr) 9516 1.1 mrg { 9517 1.1 mrg tree val; 9518 1.1 mrg 9519 1.1 mrg gcc_assert (expr->ts.type != BT_CHARACTER); 9520 1.1 mrg gfc_conv_expr (se, expr); 9521 1.1 mrg if (se->post.head) 9522 1.1 mrg { 9523 1.1 mrg val = gfc_create_var (TREE_TYPE (se->expr), NULL); 9524 1.1 mrg gfc_add_modify (&se->pre, val, se->expr); 9525 1.1 mrg se->expr = val; 9526 1.1 mrg gfc_add_block_to_block (&se->pre, &se->post); 9527 1.1 mrg } 9528 1.1 mrg } 9529 1.1 mrg 9530 1.1 mrg /* Helper to translate an expression and convert it to a particular type. */ 9531 1.1 mrg void 9532 1.1 mrg gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type) 9533 1.1 mrg { 9534 1.1 mrg gfc_conv_expr_val (se, expr); 9535 1.1 mrg se->expr = convert (type, se->expr); 9536 1.1 mrg } 9537 1.1 mrg 9538 1.1 mrg 9539 1.1 mrg /* Converts an expression so that it can be passed by reference. Scalar 9540 1.1 mrg values only. */ 9541 1.1 mrg 9542 1.1 mrg void 9543 1.1 mrg gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr) 9544 1.1 mrg { 9545 1.1 mrg gfc_ss *ss; 9546 1.1 mrg tree var; 9547 1.1 mrg 9548 1.1 mrg ss = se->ss; 9549 1.1 mrg if (ss && ss->info->expr == expr 9550 1.1 mrg && ss->info->type == GFC_SS_REFERENCE) 9551 1.1 mrg { 9552 1.1 mrg /* Returns a reference to the scalar evaluated outside the loop 9553 1.1 mrg for this case. */ 9554 1.1 mrg gfc_conv_expr (se, expr); 9555 1.1 mrg 9556 1.1 mrg if (expr->ts.type == BT_CHARACTER 9557 1.1 mrg && expr->expr_type != EXPR_FUNCTION) 9558 1.1 mrg gfc_conv_string_parameter (se); 9559 1.1 mrg else 9560 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, se->expr); 9561 1.1 mrg 9562 1.1 mrg return; 9563 1.1 mrg } 9564 1.1 mrg 9565 1.1 mrg if (expr->ts.type == BT_CHARACTER) 9566 1.1 mrg { 9567 1.1 mrg gfc_conv_expr (se, expr); 9568 1.1 mrg gfc_conv_string_parameter (se); 9569 1.1 mrg return; 9570 1.1 mrg } 9571 1.1 mrg 9572 1.1 mrg if (expr->expr_type == EXPR_VARIABLE) 9573 1.1 mrg { 9574 1.1 mrg se->want_pointer = 1; 9575 1.1 mrg gfc_conv_expr (se, expr); 9576 1.1 mrg if (se->post.head) 9577 1.1 mrg { 9578 1.1 mrg var = gfc_create_var (TREE_TYPE (se->expr), NULL); 9579 1.1 mrg gfc_add_modify (&se->pre, var, se->expr); 9580 1.1 mrg gfc_add_block_to_block (&se->pre, &se->post); 9581 1.1 mrg se->expr = var; 9582 1.1 mrg } 9583 1.1 mrg return; 9584 1.1 mrg } 9585 1.1 mrg 9586 1.1 mrg if (expr->expr_type == EXPR_FUNCTION 9587 1.1 mrg && ((expr->value.function.esym 9588 1.1 mrg && expr->value.function.esym->result 9589 1.1 mrg && expr->value.function.esym->result->attr.pointer 9590 1.1 mrg && !expr->value.function.esym->result->attr.dimension) 9591 1.1 mrg || (!expr->value.function.esym && !expr->ref 9592 1.1 mrg && expr->symtree->n.sym->attr.pointer 9593 1.1 mrg && !expr->symtree->n.sym->attr.dimension))) 9594 1.1 mrg { 9595 1.1 mrg se->want_pointer = 1; 9596 1.1 mrg gfc_conv_expr (se, expr); 9597 1.1 mrg var = gfc_create_var (TREE_TYPE (se->expr), NULL); 9598 1.1 mrg gfc_add_modify (&se->pre, var, se->expr); 9599 1.1 mrg se->expr = var; 9600 1.1 mrg return; 9601 1.1 mrg } 9602 1.1 mrg 9603 1.1 mrg gfc_conv_expr (se, expr); 9604 1.1 mrg 9605 1.1 mrg /* Create a temporary var to hold the value. */ 9606 1.1 mrg if (TREE_CONSTANT (se->expr)) 9607 1.1 mrg { 9608 1.1 mrg tree tmp = se->expr; 9609 1.1 mrg STRIP_TYPE_NOPS (tmp); 9610 1.1 mrg var = build_decl (input_location, 9611 1.1 mrg CONST_DECL, NULL, TREE_TYPE (tmp)); 9612 1.1 mrg DECL_INITIAL (var) = tmp; 9613 1.1 mrg TREE_STATIC (var) = 1; 9614 1.1 mrg pushdecl (var); 9615 1.1 mrg } 9616 1.1 mrg else 9617 1.1 mrg { 9618 1.1 mrg var = gfc_create_var (TREE_TYPE (se->expr), NULL); 9619 1.1 mrg gfc_add_modify (&se->pre, var, se->expr); 9620 1.1 mrg } 9621 1.1 mrg 9622 1.1 mrg if (!expr->must_finalize) 9623 1.1 mrg gfc_add_block_to_block (&se->pre, &se->post); 9624 1.1 mrg 9625 1.1 mrg /* Take the address of that value. */ 9626 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, var); 9627 1.1 mrg } 9628 1.1 mrg 9629 1.1 mrg 9630 1.1 mrg /* Get the _len component for an unlimited polymorphic expression. */ 9631 1.1 mrg 9632 1.1 mrg static tree 9633 1.1 mrg trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr) 9634 1.1 mrg { 9635 1.1 mrg gfc_se se; 9636 1.1 mrg gfc_ref *ref = expr->ref; 9637 1.1 mrg 9638 1.1 mrg gfc_init_se (&se, NULL); 9639 1.1 mrg while (ref && ref->next) 9640 1.1 mrg ref = ref->next; 9641 1.1 mrg gfc_add_len_component (expr); 9642 1.1 mrg gfc_conv_expr (&se, expr); 9643 1.1 mrg gfc_add_block_to_block (block, &se.pre); 9644 1.1 mrg gcc_assert (se.post.head == NULL_TREE); 9645 1.1 mrg if (ref) 9646 1.1 mrg { 9647 1.1 mrg gfc_free_ref_list (ref->next); 9648 1.1 mrg ref->next = NULL; 9649 1.1 mrg } 9650 1.1 mrg else 9651 1.1 mrg { 9652 1.1 mrg gfc_free_ref_list (expr->ref); 9653 1.1 mrg expr->ref = NULL; 9654 1.1 mrg } 9655 1.1 mrg return se.expr; 9656 1.1 mrg } 9657 1.1 mrg 9658 1.1 mrg 9659 1.1 mrg /* Assign _vptr and _len components as appropriate. BLOCK should be a 9660 1.1 mrg statement-list outside of the scalarizer-loop. When code is generated, that 9661 1.1 mrg depends on the scalarized expression, it is added to RSE.PRE. 9662 1.1 mrg Returns le's _vptr tree and when set the len expressions in to_lenp and 9663 1.1 mrg from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp]) 9664 1.1 mrg expression. */ 9665 1.1 mrg 9666 1.1 mrg static tree 9667 1.1 mrg trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le, 9668 1.1 mrg gfc_expr * re, gfc_se *rse, 9669 1.1 mrg tree * to_lenp, tree * from_lenp) 9670 1.1 mrg { 9671 1.1 mrg gfc_se se; 9672 1.1 mrg gfc_expr * vptr_expr; 9673 1.1 mrg tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr; 9674 1.1 mrg bool set_vptr = false, temp_rhs = false; 9675 1.1 mrg stmtblock_t *pre = block; 9676 1.1 mrg tree class_expr = NULL_TREE; 9677 1.1 mrg 9678 1.1 mrg /* Create a temporary for complicated expressions. */ 9679 1.1 mrg if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL 9680 1.1 mrg && rse->expr != NULL_TREE && !DECL_P (rse->expr)) 9681 1.1 mrg { 9682 1.1 mrg if (re->ts.type == BT_CLASS && !GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))) 9683 1.1 mrg class_expr = gfc_get_class_from_expr (rse->expr); 9684 1.1 mrg 9685 1.1 mrg if (rse->loop) 9686 1.1 mrg pre = &rse->loop->pre; 9687 1.1 mrg else 9688 1.1 mrg pre = &rse->pre; 9689 1.1 mrg 9690 1.1 mrg if (class_expr != NULL_TREE && UNLIMITED_POLY (re)) 9691 1.1 mrg { 9692 1.1 mrg tmp = TREE_OPERAND (rse->expr, 0); 9693 1.1 mrg tmp = gfc_create_var (TREE_TYPE (tmp), "rhs"); 9694 1.1 mrg gfc_add_modify (&rse->pre, tmp, TREE_OPERAND (rse->expr, 0)); 9695 1.1 mrg } 9696 1.1 mrg else 9697 1.1 mrg { 9698 1.1 mrg tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs"); 9699 1.1 mrg gfc_add_modify (&rse->pre, tmp, rse->expr); 9700 1.1 mrg } 9701 1.1 mrg 9702 1.1 mrg rse->expr = tmp; 9703 1.1 mrg temp_rhs = true; 9704 1.1 mrg } 9705 1.1 mrg 9706 1.1 mrg /* Get the _vptr for the left-hand side expression. */ 9707 1.1 mrg gfc_init_se (&se, NULL); 9708 1.1 mrg vptr_expr = gfc_find_and_cut_at_last_class_ref (le); 9709 1.1 mrg if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok) 9710 1.1 mrg { 9711 1.1 mrg /* Care about _len for unlimited polymorphic entities. */ 9712 1.1 mrg if (UNLIMITED_POLY (vptr_expr) 9713 1.1 mrg || (vptr_expr->ts.type == BT_DERIVED 9714 1.1 mrg && vptr_expr->ts.u.derived->attr.unlimited_polymorphic)) 9715 1.1 mrg to_len = trans_get_upoly_len (block, vptr_expr); 9716 1.1 mrg gfc_add_vptr_component (vptr_expr); 9717 1.1 mrg set_vptr = true; 9718 1.1 mrg } 9719 1.1 mrg else 9720 1.1 mrg vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts)); 9721 1.1 mrg se.want_pointer = 1; 9722 1.1 mrg gfc_conv_expr (&se, vptr_expr); 9723 1.1 mrg gfc_free_expr (vptr_expr); 9724 1.1 mrg gfc_add_block_to_block (block, &se.pre); 9725 1.1 mrg gcc_assert (se.post.head == NULL_TREE); 9726 1.1 mrg lhs_vptr = se.expr; 9727 1.1 mrg STRIP_NOPS (lhs_vptr); 9728 1.1 mrg 9729 1.1 mrg /* Set the _vptr only when the left-hand side of the assignment is a 9730 1.1 mrg class-object. */ 9731 1.1 mrg if (set_vptr) 9732 1.1 mrg { 9733 1.1 mrg /* Get the vptr from the rhs expression only, when it is variable. 9734 1.1 mrg Functions are expected to be assigned to a temporary beforehand. */ 9735 1.1 mrg vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS) 9736 1.1 mrg ? gfc_find_and_cut_at_last_class_ref (re) 9737 1.1 mrg : NULL; 9738 1.1 mrg if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS) 9739 1.1 mrg { 9740 1.1 mrg if (to_len != NULL_TREE) 9741 1.1 mrg { 9742 1.1 mrg /* Get the _len information from the rhs. */ 9743 1.1 mrg if (UNLIMITED_POLY (vptr_expr) 9744 1.1 mrg || (vptr_expr->ts.type == BT_DERIVED 9745 1.1 mrg && vptr_expr->ts.u.derived->attr.unlimited_polymorphic)) 9746 1.1 mrg from_len = trans_get_upoly_len (block, vptr_expr); 9747 1.1 mrg } 9748 1.1 mrg gfc_add_vptr_component (vptr_expr); 9749 1.1 mrg } 9750 1.1 mrg else 9751 1.1 mrg { 9752 1.1 mrg if (re->expr_type == EXPR_VARIABLE 9753 1.1 mrg && DECL_P (re->symtree->n.sym->backend_decl) 9754 1.1 mrg && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl) 9755 1.1 mrg && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl) 9756 1.1 mrg && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR ( 9757 1.1 mrg re->symtree->n.sym->backend_decl)))) 9758 1.1 mrg { 9759 1.1 mrg vptr_expr = NULL; 9760 1.1 mrg se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR ( 9761 1.1 mrg re->symtree->n.sym->backend_decl)); 9762 1.1 mrg if (to_len) 9763 1.1 mrg from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR ( 9764 1.1 mrg re->symtree->n.sym->backend_decl)); 9765 1.1 mrg } 9766 1.1 mrg else if (temp_rhs && re->ts.type == BT_CLASS) 9767 1.1 mrg { 9768 1.1 mrg vptr_expr = NULL; 9769 1.1 mrg if (class_expr) 9770 1.1 mrg tmp = class_expr; 9771 1.1 mrg else if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))) 9772 1.1 mrg tmp = gfc_get_class_from_expr (rse->expr); 9773 1.1 mrg else 9774 1.1 mrg tmp = rse->expr; 9775 1.1 mrg 9776 1.1 mrg se.expr = gfc_class_vptr_get (tmp); 9777 1.1 mrg if (UNLIMITED_POLY (re)) 9778 1.1 mrg from_len = gfc_class_len_get (tmp); 9779 1.1 mrg 9780 1.1 mrg } 9781 1.1 mrg else if (re->expr_type != EXPR_NULL) 9782 1.1 mrg /* Only when rhs is non-NULL use its declared type for vptr 9783 1.1 mrg initialisation. */ 9784 1.1 mrg vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts)); 9785 1.1 mrg else 9786 1.1 mrg /* When the rhs is NULL use the vtab of lhs' declared type. */ 9787 1.1 mrg vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts)); 9788 1.1 mrg } 9789 1.1 mrg 9790 1.1 mrg if (vptr_expr) 9791 1.1 mrg { 9792 1.1 mrg gfc_init_se (&se, NULL); 9793 1.1 mrg se.want_pointer = 1; 9794 1.1 mrg gfc_conv_expr (&se, vptr_expr); 9795 1.1 mrg gfc_free_expr (vptr_expr); 9796 1.1 mrg gfc_add_block_to_block (block, &se.pre); 9797 1.1 mrg gcc_assert (se.post.head == NULL_TREE); 9798 1.1 mrg } 9799 1.1 mrg gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr), 9800 1.1 mrg se.expr)); 9801 1.1 mrg 9802 1.1 mrg if (to_len != NULL_TREE) 9803 1.1 mrg { 9804 1.1 mrg /* The _len component needs to be set. Figure how to get the 9805 1.1 mrg value of the right-hand side. */ 9806 1.1 mrg if (from_len == NULL_TREE) 9807 1.1 mrg { 9808 1.1 mrg if (rse->string_length != NULL_TREE) 9809 1.1 mrg from_len = rse->string_length; 9810 1.1 mrg else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length) 9811 1.1 mrg { 9812 1.1 mrg gfc_init_se (&se, NULL); 9813 1.1 mrg gfc_conv_expr (&se, re->ts.u.cl->length); 9814 1.1 mrg gfc_add_block_to_block (block, &se.pre); 9815 1.1 mrg gcc_assert (se.post.head == NULL_TREE); 9816 1.1 mrg from_len = gfc_evaluate_now (se.expr, block); 9817 1.1 mrg } 9818 1.1 mrg else 9819 1.1 mrg from_len = build_zero_cst (gfc_charlen_type_node); 9820 1.1 mrg } 9821 1.1 mrg gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len), 9822 1.1 mrg from_len)); 9823 1.1 mrg } 9824 1.1 mrg } 9825 1.1 mrg 9826 1.1 mrg /* Return the _len trees only, when requested. */ 9827 1.1 mrg if (to_lenp) 9828 1.1 mrg *to_lenp = to_len; 9829 1.1 mrg if (from_lenp) 9830 1.1 mrg *from_lenp = from_len; 9831 1.1 mrg return lhs_vptr; 9832 1.1 mrg } 9833 1.1 mrg 9834 1.1 mrg 9835 1.1 mrg /* Assign tokens for pointer components. */ 9836 1.1 mrg 9837 1.1 mrg static void 9838 1.1 mrg trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1, 9839 1.1 mrg gfc_expr *expr2) 9840 1.1 mrg { 9841 1.1 mrg symbol_attribute lhs_attr, rhs_attr; 9842 1.1 mrg tree tmp, lhs_tok, rhs_tok; 9843 1.1 mrg /* Flag to indicated component refs on the rhs. */ 9844 1.1 mrg bool rhs_cr; 9845 1.1 mrg 9846 1.1 mrg lhs_attr = gfc_caf_attr (expr1); 9847 1.1 mrg if (expr2->expr_type != EXPR_NULL) 9848 1.1 mrg { 9849 1.1 mrg rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr); 9850 1.1 mrg if (lhs_attr.codimension && rhs_attr.codimension) 9851 1.1 mrg { 9852 1.1 mrg lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1); 9853 1.1 mrg lhs_tok = build_fold_indirect_ref (lhs_tok); 9854 1.1 mrg 9855 1.1 mrg if (rhs_cr) 9856 1.1 mrg rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2); 9857 1.1 mrg else 9858 1.1 mrg { 9859 1.1 mrg tree caf_decl; 9860 1.1 mrg caf_decl = gfc_get_tree_for_caf_expr (expr2); 9861 1.1 mrg gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl, 9862 1.1 mrg NULL_TREE, NULL); 9863 1.1 mrg } 9864 1.1 mrg tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node, 9865 1.1 mrg lhs_tok, 9866 1.1 mrg fold_convert (TREE_TYPE (lhs_tok), rhs_tok)); 9867 1.1 mrg gfc_prepend_expr_to_block (&lse->post, tmp); 9868 1.1 mrg } 9869 1.1 mrg } 9870 1.1 mrg else if (lhs_attr.codimension) 9871 1.1 mrg { 9872 1.1 mrg lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1); 9873 1.1 mrg lhs_tok = build_fold_indirect_ref (lhs_tok); 9874 1.1 mrg tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node, 9875 1.1 mrg lhs_tok, null_pointer_node); 9876 1.1 mrg gfc_prepend_expr_to_block (&lse->post, tmp); 9877 1.1 mrg } 9878 1.1 mrg } 9879 1.1 mrg 9880 1.1 mrg 9881 1.1 mrg /* Do everything that is needed for a CLASS function expr2. */ 9882 1.1 mrg 9883 1.1 mrg static tree 9884 1.1 mrg trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse, 9885 1.1 mrg gfc_expr *expr1, gfc_expr *expr2) 9886 1.1 mrg { 9887 1.1 mrg tree expr1_vptr = NULL_TREE; 9888 1.1 mrg tree tmp; 9889 1.1 mrg 9890 1.1 mrg gfc_conv_function_expr (rse, expr2); 9891 1.1 mrg rse->expr = gfc_evaluate_now (rse->expr, &rse->pre); 9892 1.1 mrg 9893 1.1 mrg if (expr1->ts.type != BT_CLASS) 9894 1.1 mrg rse->expr = gfc_class_data_get (rse->expr); 9895 1.1 mrg else 9896 1.1 mrg { 9897 1.1 mrg expr1_vptr = trans_class_vptr_len_assignment (block, expr1, 9898 1.1 mrg expr2, rse, 9899 1.1 mrg NULL, NULL); 9900 1.1 mrg gfc_add_block_to_block (block, &rse->pre); 9901 1.1 mrg tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp"); 9902 1.1 mrg gfc_add_modify (&lse->pre, tmp, rse->expr); 9903 1.1 mrg 9904 1.1 mrg gfc_add_modify (&lse->pre, expr1_vptr, 9905 1.1 mrg fold_convert (TREE_TYPE (expr1_vptr), 9906 1.1 mrg gfc_class_vptr_get (tmp))); 9907 1.1 mrg rse->expr = gfc_class_data_get (tmp); 9908 1.1 mrg } 9909 1.1 mrg 9910 1.1 mrg return expr1_vptr; 9911 1.1 mrg } 9912 1.1 mrg 9913 1.1 mrg 9914 1.1 mrg tree 9915 1.1 mrg gfc_trans_pointer_assign (gfc_code * code) 9916 1.1 mrg { 9917 1.1 mrg return gfc_trans_pointer_assignment (code->expr1, code->expr2); 9918 1.1 mrg } 9919 1.1 mrg 9920 1.1 mrg 9921 1.1 mrg /* Generate code for a pointer assignment. */ 9922 1.1 mrg 9923 1.1 mrg tree 9924 1.1 mrg gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) 9925 1.1 mrg { 9926 1.1 mrg gfc_se lse; 9927 1.1 mrg gfc_se rse; 9928 1.1 mrg stmtblock_t block; 9929 1.1 mrg tree desc; 9930 1.1 mrg tree tmp; 9931 1.1 mrg tree expr1_vptr = NULL_TREE; 9932 1.1 mrg bool scalar, non_proc_ptr_assign; 9933 1.1 mrg gfc_ss *ss; 9934 1.1 mrg 9935 1.1 mrg gfc_start_block (&block); 9936 1.1 mrg 9937 1.1 mrg gfc_init_se (&lse, NULL); 9938 1.1 mrg 9939 1.1 mrg /* Usually testing whether this is not a proc pointer assignment. */ 9940 1.1 mrg non_proc_ptr_assign = !(gfc_expr_attr (expr1).proc_pointer 9941 1.1 mrg && expr2->expr_type == EXPR_VARIABLE 9942 1.1 mrg && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE); 9943 1.1 mrg 9944 1.1 mrg /* Check whether the expression is a scalar or not; we cannot use 9945 1.1 mrg expr1->rank as it can be nonzero for proc pointers. */ 9946 1.1 mrg ss = gfc_walk_expr (expr1); 9947 1.1 mrg scalar = ss == gfc_ss_terminator; 9948 1.1 mrg if (!scalar) 9949 1.1 mrg gfc_free_ss_chain (ss); 9950 1.1 mrg 9951 1.1 mrg if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS 9952 1.1 mrg && expr2->expr_type != EXPR_FUNCTION && non_proc_ptr_assign) 9953 1.1 mrg { 9954 1.1 mrg gfc_add_data_component (expr2); 9955 1.1 mrg /* The following is required as gfc_add_data_component doesn't 9956 1.1 mrg update ts.type if there is a trailing REF_ARRAY. */ 9957 1.1 mrg expr2->ts.type = BT_DERIVED; 9958 1.1 mrg } 9959 1.1 mrg 9960 1.1 mrg if (scalar) 9961 1.1 mrg { 9962 1.1 mrg /* Scalar pointers. */ 9963 1.1 mrg lse.want_pointer = 1; 9964 1.1 mrg gfc_conv_expr (&lse, expr1); 9965 1.1 mrg gfc_init_se (&rse, NULL); 9966 1.1 mrg rse.want_pointer = 1; 9967 1.1 mrg if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS) 9968 1.1 mrg trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2); 9969 1.1 mrg else 9970 1.1 mrg gfc_conv_expr (&rse, expr2); 9971 1.1 mrg 9972 1.1 mrg if (non_proc_ptr_assign && expr1->ts.type == BT_CLASS) 9973 1.1 mrg { 9974 1.1 mrg trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL, 9975 1.1 mrg NULL); 9976 1.1 mrg lse.expr = gfc_class_data_get (lse.expr); 9977 1.1 mrg } 9978 1.1 mrg 9979 1.1 mrg if (expr1->symtree->n.sym->attr.proc_pointer 9980 1.1 mrg && expr1->symtree->n.sym->attr.dummy) 9981 1.1 mrg lse.expr = build_fold_indirect_ref_loc (input_location, 9982 1.1 mrg lse.expr); 9983 1.1 mrg 9984 1.1 mrg if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer 9985 1.1 mrg && expr2->symtree->n.sym->attr.dummy) 9986 1.1 mrg rse.expr = build_fold_indirect_ref_loc (input_location, 9987 1.1 mrg rse.expr); 9988 1.1 mrg 9989 1.1 mrg gfc_add_block_to_block (&block, &lse.pre); 9990 1.1 mrg gfc_add_block_to_block (&block, &rse.pre); 9991 1.1 mrg 9992 1.1 mrg /* Check character lengths if character expression. The test is only 9993 1.1 mrg really added if -fbounds-check is enabled. Exclude deferred 9994 1.1 mrg character length lefthand sides. */ 9995 1.1 mrg if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL 9996 1.1 mrg && !expr1->ts.deferred 9997 1.1 mrg && !expr1->symtree->n.sym->attr.proc_pointer 9998 1.1 mrg && !gfc_is_proc_ptr_comp (expr1)) 9999 1.1 mrg { 10000 1.1 mrg gcc_assert (expr2->ts.type == BT_CHARACTER); 10001 1.1 mrg gcc_assert (lse.string_length && rse.string_length); 10002 1.1 mrg gfc_trans_same_strlen_check ("pointer assignment", &expr1->where, 10003 1.1 mrg lse.string_length, rse.string_length, 10004 1.1 mrg &block); 10005 1.1 mrg } 10006 1.1 mrg 10007 1.1 mrg /* The assignment to an deferred character length sets the string 10008 1.1 mrg length to that of the rhs. */ 10009 1.1 mrg if (expr1->ts.deferred) 10010 1.1 mrg { 10011 1.1 mrg if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL) 10012 1.1 mrg gfc_add_modify (&block, lse.string_length, 10013 1.1 mrg fold_convert (TREE_TYPE (lse.string_length), 10014 1.1 mrg rse.string_length)); 10015 1.1 mrg else if (lse.string_length != NULL) 10016 1.1 mrg gfc_add_modify (&block, lse.string_length, 10017 1.1 mrg build_zero_cst (TREE_TYPE (lse.string_length))); 10018 1.1 mrg } 10019 1.1 mrg 10020 1.1 mrg gfc_add_modify (&block, lse.expr, 10021 1.1 mrg fold_convert (TREE_TYPE (lse.expr), rse.expr)); 10022 1.1 mrg 10023 1.1 mrg /* Also set the tokens for pointer components in derived typed 10024 1.1 mrg coarrays. */ 10025 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB) 10026 1.1 mrg trans_caf_token_assign (&lse, &rse, expr1, expr2); 10027 1.1 mrg 10028 1.1 mrg gfc_add_block_to_block (&block, &rse.post); 10029 1.1 mrg gfc_add_block_to_block (&block, &lse.post); 10030 1.1 mrg } 10031 1.1 mrg else 10032 1.1 mrg { 10033 1.1 mrg gfc_ref* remap; 10034 1.1 mrg bool rank_remap; 10035 1.1 mrg tree strlen_lhs; 10036 1.1 mrg tree strlen_rhs = NULL_TREE; 10037 1.1 mrg 10038 1.1 mrg /* Array pointer. Find the last reference on the LHS and if it is an 10039 1.1 mrg array section ref, we're dealing with bounds remapping. In this case, 10040 1.1 mrg set it to AR_FULL so that gfc_conv_expr_descriptor does 10041 1.1 mrg not see it and process the bounds remapping afterwards explicitly. */ 10042 1.1 mrg for (remap = expr1->ref; remap; remap = remap->next) 10043 1.1 mrg if (!remap->next && remap->type == REF_ARRAY 10044 1.1 mrg && remap->u.ar.type == AR_SECTION) 10045 1.1 mrg break; 10046 1.1 mrg rank_remap = (remap && remap->u.ar.end[0]); 10047 1.1 mrg 10048 1.1 mrg if (remap && expr2->expr_type == EXPR_NULL) 10049 1.1 mrg { 10050 1.1 mrg gfc_error ("If bounds remapping is specified at %L, " 10051 1.1 mrg "the pointer target shall not be NULL", &expr1->where); 10052 1.1 mrg return NULL_TREE; 10053 1.1 mrg } 10054 1.1 mrg 10055 1.1 mrg gfc_init_se (&lse, NULL); 10056 1.1 mrg if (remap) 10057 1.1 mrg lse.descriptor_only = 1; 10058 1.1 mrg gfc_conv_expr_descriptor (&lse, expr1); 10059 1.1 mrg strlen_lhs = lse.string_length; 10060 1.1 mrg desc = lse.expr; 10061 1.1 mrg 10062 1.1 mrg if (expr2->expr_type == EXPR_NULL) 10063 1.1 mrg { 10064 1.1 mrg /* Just set the data pointer to null. */ 10065 1.1 mrg gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node); 10066 1.1 mrg } 10067 1.1 mrg else if (rank_remap) 10068 1.1 mrg { 10069 1.1 mrg /* If we are rank-remapping, just get the RHS's descriptor and 10070 1.1 mrg process this later on. */ 10071 1.1 mrg gfc_init_se (&rse, NULL); 10072 1.1 mrg rse.direct_byref = 1; 10073 1.1 mrg rse.byref_noassign = 1; 10074 1.1 mrg 10075 1.1 mrg if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS) 10076 1.1 mrg expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse, 10077 1.1 mrg expr1, expr2); 10078 1.1 mrg else if (expr2->expr_type == EXPR_FUNCTION) 10079 1.1 mrg { 10080 1.1 mrg tree bound[GFC_MAX_DIMENSIONS]; 10081 1.1 mrg int i; 10082 1.1 mrg 10083 1.1 mrg for (i = 0; i < expr2->rank; i++) 10084 1.1 mrg bound[i] = NULL_TREE; 10085 1.1 mrg tmp = gfc_typenode_for_spec (&expr2->ts); 10086 1.1 mrg tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0, 10087 1.1 mrg bound, bound, 0, 10088 1.1 mrg GFC_ARRAY_POINTER_CONT, false); 10089 1.1 mrg tmp = gfc_create_var (tmp, "ptrtemp"); 10090 1.1 mrg rse.descriptor_only = 0; 10091 1.1 mrg rse.expr = tmp; 10092 1.1 mrg rse.direct_byref = 1; 10093 1.1 mrg gfc_conv_expr_descriptor (&rse, expr2); 10094 1.1 mrg strlen_rhs = rse.string_length; 10095 1.1 mrg rse.expr = tmp; 10096 1.1 mrg } 10097 1.1 mrg else 10098 1.1 mrg { 10099 1.1 mrg gfc_conv_expr_descriptor (&rse, expr2); 10100 1.1 mrg strlen_rhs = rse.string_length; 10101 1.1 mrg if (expr1->ts.type == BT_CLASS) 10102 1.1 mrg expr1_vptr = trans_class_vptr_len_assignment (&block, expr1, 10103 1.1 mrg expr2, &rse, 10104 1.1 mrg NULL, NULL); 10105 1.1 mrg } 10106 1.1 mrg } 10107 1.1 mrg else if (expr2->expr_type == EXPR_VARIABLE) 10108 1.1 mrg { 10109 1.1 mrg /* Assign directly to the LHS's descriptor. */ 10110 1.1 mrg lse.descriptor_only = 0; 10111 1.1 mrg lse.direct_byref = 1; 10112 1.1 mrg gfc_conv_expr_descriptor (&lse, expr2); 10113 1.1 mrg strlen_rhs = lse.string_length; 10114 1.1 mrg gfc_init_se (&rse, NULL); 10115 1.1 mrg 10116 1.1 mrg if (expr1->ts.type == BT_CLASS) 10117 1.1 mrg { 10118 1.1 mrg rse.expr = NULL_TREE; 10119 1.1 mrg rse.string_length = strlen_rhs; 10120 1.1 mrg trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, 10121 1.1 mrg NULL, NULL); 10122 1.1 mrg } 10123 1.1 mrg 10124 1.1 mrg if (remap == NULL) 10125 1.1 mrg { 10126 1.1 mrg /* If the target is not a whole array, use the target array 10127 1.1 mrg reference for remap. */ 10128 1.1 mrg for (remap = expr2->ref; remap; remap = remap->next) 10129 1.1 mrg if (remap->type == REF_ARRAY 10130 1.1 mrg && remap->u.ar.type == AR_FULL 10131 1.1 mrg && remap->next) 10132 1.1 mrg break; 10133 1.1 mrg } 10134 1.1 mrg } 10135 1.1 mrg else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS) 10136 1.1 mrg { 10137 1.1 mrg gfc_init_se (&rse, NULL); 10138 1.1 mrg rse.want_pointer = 1; 10139 1.1 mrg gfc_conv_function_expr (&rse, expr2); 10140 1.1 mrg if (expr1->ts.type != BT_CLASS) 10141 1.1 mrg { 10142 1.1 mrg rse.expr = gfc_class_data_get (rse.expr); 10143 1.1 mrg gfc_add_modify (&lse.pre, desc, rse.expr); 10144 1.1 mrg /* Set the lhs span. */ 10145 1.1 mrg tmp = TREE_TYPE (rse.expr); 10146 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp)); 10147 1.1 mrg tmp = fold_convert (gfc_array_index_type, tmp); 10148 1.1 mrg gfc_conv_descriptor_span_set (&lse.pre, desc, tmp); 10149 1.1 mrg } 10150 1.1 mrg else 10151 1.1 mrg { 10152 1.1 mrg expr1_vptr = trans_class_vptr_len_assignment (&block, expr1, 10153 1.1 mrg expr2, &rse, NULL, 10154 1.1 mrg NULL); 10155 1.1 mrg gfc_add_block_to_block (&block, &rse.pre); 10156 1.1 mrg tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp"); 10157 1.1 mrg gfc_add_modify (&lse.pre, tmp, rse.expr); 10158 1.1 mrg 10159 1.1 mrg gfc_add_modify (&lse.pre, expr1_vptr, 10160 1.1 mrg fold_convert (TREE_TYPE (expr1_vptr), 10161 1.1 mrg gfc_class_vptr_get (tmp))); 10162 1.1 mrg rse.expr = gfc_class_data_get (tmp); 10163 1.1 mrg gfc_add_modify (&lse.pre, desc, rse.expr); 10164 1.1 mrg } 10165 1.1 mrg } 10166 1.1 mrg else 10167 1.1 mrg { 10168 1.1 mrg /* Assign to a temporary descriptor and then copy that 10169 1.1 mrg temporary to the pointer. */ 10170 1.1 mrg tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp"); 10171 1.1 mrg lse.descriptor_only = 0; 10172 1.1 mrg lse.expr = tmp; 10173 1.1 mrg lse.direct_byref = 1; 10174 1.1 mrg gfc_conv_expr_descriptor (&lse, expr2); 10175 1.1 mrg strlen_rhs = lse.string_length; 10176 1.1 mrg gfc_add_modify (&lse.pre, desc, tmp); 10177 1.1 mrg } 10178 1.1 mrg 10179 1.1 mrg if (expr1->ts.type == BT_CHARACTER 10180 1.1 mrg && expr1->symtree->n.sym->ts.deferred 10181 1.1 mrg && expr1->symtree->n.sym->ts.u.cl->backend_decl 10182 1.1 mrg && VAR_P (expr1->symtree->n.sym->ts.u.cl->backend_decl)) 10183 1.1 mrg { 10184 1.1 mrg tmp = expr1->symtree->n.sym->ts.u.cl->backend_decl; 10185 1.1 mrg if (expr2->expr_type != EXPR_NULL) 10186 1.1 mrg gfc_add_modify (&block, tmp, 10187 1.1 mrg fold_convert (TREE_TYPE (tmp), strlen_rhs)); 10188 1.1 mrg else 10189 1.1 mrg gfc_add_modify (&block, tmp, build_zero_cst (TREE_TYPE (tmp))); 10190 1.1 mrg } 10191 1.1 mrg 10192 1.1 mrg gfc_add_block_to_block (&block, &lse.pre); 10193 1.1 mrg if (rank_remap) 10194 1.1 mrg gfc_add_block_to_block (&block, &rse.pre); 10195 1.1 mrg 10196 1.1 mrg /* If we do bounds remapping, update LHS descriptor accordingly. */ 10197 1.1 mrg if (remap) 10198 1.1 mrg { 10199 1.1 mrg int dim; 10200 1.1 mrg gcc_assert (remap->u.ar.dimen == expr1->rank); 10201 1.1 mrg 10202 1.1 mrg if (rank_remap) 10203 1.1 mrg { 10204 1.1 mrg /* Do rank remapping. We already have the RHS's descriptor 10205 1.1 mrg converted in rse and now have to build the correct LHS 10206 1.1 mrg descriptor for it. */ 10207 1.1 mrg 10208 1.1 mrg tree dtype, data, span; 10209 1.1 mrg tree offs, stride; 10210 1.1 mrg tree lbound, ubound; 10211 1.1 mrg 10212 1.1 mrg /* Set dtype. */ 10213 1.1 mrg dtype = gfc_conv_descriptor_dtype (desc); 10214 1.1 mrg tmp = gfc_get_dtype (TREE_TYPE (desc)); 10215 1.1 mrg gfc_add_modify (&block, dtype, tmp); 10216 1.1 mrg 10217 1.1 mrg /* Copy data pointer. */ 10218 1.1 mrg data = gfc_conv_descriptor_data_get (rse.expr); 10219 1.1 mrg gfc_conv_descriptor_data_set (&block, desc, data); 10220 1.1 mrg 10221 1.1 mrg /* Copy the span. */ 10222 1.1 mrg if (TREE_CODE (rse.expr) == VAR_DECL 10223 1.1 mrg && GFC_DECL_PTR_ARRAY_P (rse.expr)) 10224 1.1 mrg span = gfc_conv_descriptor_span_get (rse.expr); 10225 1.1 mrg else 10226 1.1 mrg { 10227 1.1 mrg tmp = TREE_TYPE (rse.expr); 10228 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp)); 10229 1.1 mrg span = fold_convert (gfc_array_index_type, tmp); 10230 1.1 mrg } 10231 1.1 mrg gfc_conv_descriptor_span_set (&block, desc, span); 10232 1.1 mrg 10233 1.1 mrg /* Copy offset but adjust it such that it would correspond 10234 1.1 mrg to a lbound of zero. */ 10235 1.1 mrg offs = gfc_conv_descriptor_offset_get (rse.expr); 10236 1.1 mrg for (dim = 0; dim < expr2->rank; ++dim) 10237 1.1 mrg { 10238 1.1 mrg stride = gfc_conv_descriptor_stride_get (rse.expr, 10239 1.1 mrg gfc_rank_cst[dim]); 10240 1.1 mrg lbound = gfc_conv_descriptor_lbound_get (rse.expr, 10241 1.1 mrg gfc_rank_cst[dim]); 10242 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, 10243 1.1 mrg gfc_array_index_type, stride, lbound); 10244 1.1 mrg offs = fold_build2_loc (input_location, PLUS_EXPR, 10245 1.1 mrg gfc_array_index_type, offs, tmp); 10246 1.1 mrg } 10247 1.1 mrg gfc_conv_descriptor_offset_set (&block, desc, offs); 10248 1.1 mrg 10249 1.1 mrg /* Set the bounds as declared for the LHS and calculate strides as 10250 1.1 mrg well as another offset update accordingly. */ 10251 1.1 mrg stride = gfc_conv_descriptor_stride_get (rse.expr, 10252 1.1 mrg gfc_rank_cst[0]); 10253 1.1 mrg for (dim = 0; dim < expr1->rank; ++dim) 10254 1.1 mrg { 10255 1.1 mrg gfc_se lower_se; 10256 1.1 mrg gfc_se upper_se; 10257 1.1 mrg 10258 1.1 mrg gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]); 10259 1.1 mrg 10260 1.1 mrg /* Convert declared bounds. */ 10261 1.1 mrg gfc_init_se (&lower_se, NULL); 10262 1.1 mrg gfc_init_se (&upper_se, NULL); 10263 1.1 mrg gfc_conv_expr (&lower_se, remap->u.ar.start[dim]); 10264 1.1 mrg gfc_conv_expr (&upper_se, remap->u.ar.end[dim]); 10265 1.1 mrg 10266 1.1 mrg gfc_add_block_to_block (&block, &lower_se.pre); 10267 1.1 mrg gfc_add_block_to_block (&block, &upper_se.pre); 10268 1.1 mrg 10269 1.1 mrg lbound = fold_convert (gfc_array_index_type, lower_se.expr); 10270 1.1 mrg ubound = fold_convert (gfc_array_index_type, upper_se.expr); 10271 1.1 mrg 10272 1.1 mrg lbound = gfc_evaluate_now (lbound, &block); 10273 1.1 mrg ubound = gfc_evaluate_now (ubound, &block); 10274 1.1 mrg 10275 1.1 mrg gfc_add_block_to_block (&block, &lower_se.post); 10276 1.1 mrg gfc_add_block_to_block (&block, &upper_se.post); 10277 1.1 mrg 10278 1.1 mrg /* Set bounds in descriptor. */ 10279 1.1 mrg gfc_conv_descriptor_lbound_set (&block, desc, 10280 1.1 mrg gfc_rank_cst[dim], lbound); 10281 1.1 mrg gfc_conv_descriptor_ubound_set (&block, desc, 10282 1.1 mrg gfc_rank_cst[dim], ubound); 10283 1.1 mrg 10284 1.1 mrg /* Set stride. */ 10285 1.1 mrg stride = gfc_evaluate_now (stride, &block); 10286 1.1 mrg gfc_conv_descriptor_stride_set (&block, desc, 10287 1.1 mrg gfc_rank_cst[dim], stride); 10288 1.1 mrg 10289 1.1 mrg /* Update offset. */ 10290 1.1 mrg offs = gfc_conv_descriptor_offset_get (desc); 10291 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, 10292 1.1 mrg gfc_array_index_type, lbound, stride); 10293 1.1 mrg offs = fold_build2_loc (input_location, MINUS_EXPR, 10294 1.1 mrg gfc_array_index_type, offs, tmp); 10295 1.1 mrg offs = gfc_evaluate_now (offs, &block); 10296 1.1 mrg gfc_conv_descriptor_offset_set (&block, desc, offs); 10297 1.1 mrg 10298 1.1 mrg /* Update stride. */ 10299 1.1 mrg tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL); 10300 1.1 mrg stride = fold_build2_loc (input_location, MULT_EXPR, 10301 1.1 mrg gfc_array_index_type, stride, tmp); 10302 1.1 mrg } 10303 1.1 mrg } 10304 1.1 mrg else 10305 1.1 mrg { 10306 1.1 mrg /* Bounds remapping. Just shift the lower bounds. */ 10307 1.1 mrg 10308 1.1 mrg gcc_assert (expr1->rank == expr2->rank); 10309 1.1 mrg 10310 1.1 mrg for (dim = 0; dim < remap->u.ar.dimen; ++dim) 10311 1.1 mrg { 10312 1.1 mrg gfc_se lbound_se; 10313 1.1 mrg 10314 1.1 mrg gcc_assert (!remap->u.ar.end[dim]); 10315 1.1 mrg gfc_init_se (&lbound_se, NULL); 10316 1.1 mrg if (remap->u.ar.start[dim]) 10317 1.1 mrg { 10318 1.1 mrg gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]); 10319 1.1 mrg gfc_add_block_to_block (&block, &lbound_se.pre); 10320 1.1 mrg } 10321 1.1 mrg else 10322 1.1 mrg /* This remap arises from a target that is not a whole 10323 1.1 mrg array. The start expressions will be NULL but we need 10324 1.1 mrg the lbounds to be one. */ 10325 1.1 mrg lbound_se.expr = gfc_index_one_node; 10326 1.1 mrg gfc_conv_shift_descriptor_lbound (&block, desc, 10327 1.1 mrg dim, lbound_se.expr); 10328 1.1 mrg gfc_add_block_to_block (&block, &lbound_se.post); 10329 1.1 mrg } 10330 1.1 mrg } 10331 1.1 mrg } 10332 1.1 mrg 10333 1.1 mrg /* If rank remapping was done, check with -fcheck=bounds that 10334 1.1 mrg the target is at least as large as the pointer. */ 10335 1.1 mrg if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)) 10336 1.1 mrg { 10337 1.1 mrg tree lsize, rsize; 10338 1.1 mrg tree fault; 10339 1.1 mrg const char* msg; 10340 1.1 mrg 10341 1.1 mrg lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank); 10342 1.1 mrg rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank); 10343 1.1 mrg 10344 1.1 mrg lsize = gfc_evaluate_now (lsize, &block); 10345 1.1 mrg rsize = gfc_evaluate_now (rsize, &block); 10346 1.1 mrg fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node, 10347 1.1 mrg rsize, lsize); 10348 1.1 mrg 10349 1.1 mrg msg = _("Target of rank remapping is too small (%ld < %ld)"); 10350 1.1 mrg gfc_trans_runtime_check (true, false, fault, &block, &expr2->where, 10351 1.1 mrg msg, rsize, lsize); 10352 1.1 mrg } 10353 1.1 mrg 10354 1.1 mrg /* Check string lengths if applicable. The check is only really added 10355 1.1 mrg to the output code if -fbounds-check is enabled. */ 10356 1.1 mrg if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL) 10357 1.1 mrg { 10358 1.1 mrg gcc_assert (expr2->ts.type == BT_CHARACTER); 10359 1.1 mrg gcc_assert (strlen_lhs && strlen_rhs); 10360 1.1 mrg gfc_trans_same_strlen_check ("pointer assignment", &expr1->where, 10361 1.1 mrg strlen_lhs, strlen_rhs, &block); 10362 1.1 mrg } 10363 1.1 mrg 10364 1.1 mrg gfc_add_block_to_block (&block, &lse.post); 10365 1.1 mrg if (rank_remap) 10366 1.1 mrg gfc_add_block_to_block (&block, &rse.post); 10367 1.1 mrg } 10368 1.1 mrg 10369 1.1 mrg return gfc_finish_block (&block); 10370 1.1 mrg } 10371 1.1 mrg 10372 1.1 mrg 10373 1.1 mrg /* Makes sure se is suitable for passing as a function string parameter. */ 10374 1.1 mrg /* TODO: Need to check all callers of this function. It may be abused. */ 10375 1.1 mrg 10376 1.1 mrg void 10377 1.1 mrg gfc_conv_string_parameter (gfc_se * se) 10378 1.1 mrg { 10379 1.1 mrg tree type; 10380 1.1 mrg 10381 1.1 mrg if (TREE_CODE (se->expr) == STRING_CST) 10382 1.1 mrg { 10383 1.1 mrg type = TREE_TYPE (TREE_TYPE (se->expr)); 10384 1.1 mrg se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr); 10385 1.1 mrg return; 10386 1.1 mrg } 10387 1.1 mrg 10388 1.1 mrg if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE 10389 1.1 mrg || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE) 10390 1.1 mrg && TYPE_STRING_FLAG (TREE_TYPE (se->expr))) 10391 1.1 mrg { 10392 1.1 mrg if (TREE_CODE (se->expr) != INDIRECT_REF) 10393 1.1 mrg { 10394 1.1 mrg type = TREE_TYPE (se->expr); 10395 1.1 mrg se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr); 10396 1.1 mrg } 10397 1.1 mrg else 10398 1.1 mrg { 10399 1.1 mrg type = gfc_get_character_type_len (gfc_default_character_kind, 10400 1.1 mrg se->string_length); 10401 1.1 mrg type = build_pointer_type (type); 10402 1.1 mrg se->expr = gfc_build_addr_expr (type, se->expr); 10403 1.1 mrg } 10404 1.1 mrg } 10405 1.1 mrg 10406 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr))); 10407 1.1 mrg } 10408 1.1 mrg 10409 1.1 mrg 10410 1.1 mrg /* Generate code for assignment of scalar variables. Includes character 10411 1.1 mrg strings and derived types with allocatable components. 10412 1.1 mrg If you know that the LHS has no allocations, set dealloc to false. 10413 1.1 mrg 10414 1.1 mrg DEEP_COPY has no effect if the typespec TS is not a derived type with 10415 1.1 mrg allocatable components. Otherwise, if it is set, an explicit copy of each 10416 1.1 mrg allocatable component is made. This is necessary as a simple copy of the 10417 1.1 mrg whole object would copy array descriptors as is, so that the lhs's 10418 1.1 mrg allocatable components would point to the rhs's after the assignment. 10419 1.1 mrg Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not 10420 1.1 mrg necessary if the rhs is a non-pointer function, as the allocatable components 10421 1.1 mrg are not accessible by other means than the function's result after the 10422 1.1 mrg function has returned. It is even more subtle when temporaries are involved, 10423 1.1 mrg as the two following examples show: 10424 1.1 mrg 1. When we evaluate an array constructor, a temporary is created. Thus 10425 1.1 mrg there is theoretically no alias possible. However, no deep copy is 10426 1.1 mrg made for this temporary, so that if the constructor is made of one or 10427 1.1 mrg more variable with allocatable components, those components still point 10428 1.1 mrg to the variable's: DEEP_COPY should be set for the assignment from the 10429 1.1 mrg temporary to the lhs in that case. 10430 1.1 mrg 2. When assigning a scalar to an array, we evaluate the scalar value out 10431 1.1 mrg of the loop, store it into a temporary variable, and assign from that. 10432 1.1 mrg In that case, deep copying when assigning to the temporary would be a 10433 1.1 mrg waste of resources; however deep copies should happen when assigning from 10434 1.1 mrg the temporary to each array element: again DEEP_COPY should be set for 10435 1.1 mrg the assignment from the temporary to the lhs. */ 10436 1.1 mrg 10437 1.1 mrg tree 10438 1.1 mrg gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts, 10439 1.1 mrg bool deep_copy, bool dealloc, bool in_coarray) 10440 1.1 mrg { 10441 1.1 mrg stmtblock_t block; 10442 1.1 mrg tree tmp; 10443 1.1 mrg tree cond; 10444 1.1 mrg 10445 1.1 mrg gfc_init_block (&block); 10446 1.1 mrg 10447 1.1 mrg if (ts.type == BT_CHARACTER) 10448 1.1 mrg { 10449 1.1 mrg tree rlen = NULL; 10450 1.1 mrg tree llen = NULL; 10451 1.1 mrg 10452 1.1 mrg if (lse->string_length != NULL_TREE) 10453 1.1 mrg { 10454 1.1 mrg gfc_conv_string_parameter (lse); 10455 1.1 mrg gfc_add_block_to_block (&block, &lse->pre); 10456 1.1 mrg llen = lse->string_length; 10457 1.1 mrg } 10458 1.1 mrg 10459 1.1 mrg if (rse->string_length != NULL_TREE) 10460 1.1 mrg { 10461 1.1 mrg gfc_conv_string_parameter (rse); 10462 1.1 mrg gfc_add_block_to_block (&block, &rse->pre); 10463 1.1 mrg rlen = rse->string_length; 10464 1.1 mrg } 10465 1.1 mrg 10466 1.1 mrg gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen, 10467 1.1 mrg rse->expr, ts.kind); 10468 1.1 mrg } 10469 1.1 mrg else if (gfc_bt_struct (ts.type) 10470 1.1 mrg && (ts.u.derived->attr.alloc_comp 10471 1.1 mrg || (deep_copy && ts.u.derived->attr.pdt_type))) 10472 1.1 mrg { 10473 1.1 mrg tree tmp_var = NULL_TREE; 10474 1.1 mrg cond = NULL_TREE; 10475 1.1 mrg 10476 1.1 mrg /* Are the rhs and the lhs the same? */ 10477 1.1 mrg if (deep_copy) 10478 1.1 mrg { 10479 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, 10480 1.1 mrg gfc_build_addr_expr (NULL_TREE, lse->expr), 10481 1.1 mrg gfc_build_addr_expr (NULL_TREE, rse->expr)); 10482 1.1 mrg cond = gfc_evaluate_now (cond, &lse->pre); 10483 1.1 mrg } 10484 1.1 mrg 10485 1.1 mrg /* Deallocate the lhs allocated components as long as it is not 10486 1.1 mrg the same as the rhs. This must be done following the assignment 10487 1.1 mrg to prevent deallocating data that could be used in the rhs 10488 1.1 mrg expression. */ 10489 1.1 mrg if (dealloc) 10490 1.1 mrg { 10491 1.1 mrg tmp_var = gfc_evaluate_now (lse->expr, &lse->pre); 10492 1.1 mrg tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0); 10493 1.1 mrg if (deep_copy) 10494 1.1 mrg tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location), 10495 1.1 mrg tmp); 10496 1.1 mrg gfc_add_expr_to_block (&lse->post, tmp); 10497 1.1 mrg } 10498 1.1 mrg 10499 1.1 mrg gfc_add_block_to_block (&block, &rse->pre); 10500 1.1 mrg gfc_add_block_to_block (&block, &lse->pre); 10501 1.1 mrg 10502 1.1 mrg gfc_add_modify (&block, lse->expr, 10503 1.1 mrg fold_convert (TREE_TYPE (lse->expr), rse->expr)); 10504 1.1 mrg 10505 1.1 mrg /* Restore pointer address of coarray components. */ 10506 1.1 mrg if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE) 10507 1.1 mrg { 10508 1.1 mrg tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr); 10509 1.1 mrg tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location), 10510 1.1 mrg tmp); 10511 1.1 mrg gfc_add_expr_to_block (&block, tmp); 10512 1.1 mrg } 10513 1.1 mrg 10514 1.1 mrg /* Do a deep copy if the rhs is a variable, if it is not the 10515 1.1 mrg same as the lhs. */ 10516 1.1 mrg if (deep_copy) 10517 1.1 mrg { 10518 1.1 mrg int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY 10519 1.1 mrg | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0; 10520 1.1 mrg tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0, 10521 1.1 mrg caf_mode); 10522 1.1 mrg tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location), 10523 1.1 mrg tmp); 10524 1.1 mrg gfc_add_expr_to_block (&block, tmp); 10525 1.1 mrg } 10526 1.1 mrg } 10527 1.1 mrg else if (gfc_bt_struct (ts.type)) 10528 1.1 mrg { 10529 1.1 mrg gfc_add_block_to_block (&block, &lse->pre); 10530 1.1 mrg gfc_add_block_to_block (&block, &rse->pre); 10531 1.1 mrg tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR, 10532 1.1 mrg TREE_TYPE (lse->expr), rse->expr); 10533 1.1 mrg gfc_add_modify (&block, lse->expr, tmp); 10534 1.1 mrg } 10535 1.1 mrg /* If possible use the rhs vptr copy with trans_scalar_class_assign.... */ 10536 1.1 mrg else if (ts.type == BT_CLASS) 10537 1.1 mrg { 10538 1.1 mrg gfc_add_block_to_block (&block, &lse->pre); 10539 1.1 mrg gfc_add_block_to_block (&block, &rse->pre); 10540 1.1 mrg 10541 1.1 mrg if (!trans_scalar_class_assign (&block, lse, rse)) 10542 1.1 mrg { 10543 1.1 mrg /* ...otherwise assignment suffices. Note the use of VIEW_CONVERT_EXPR 10544 1.1 mrg for the lhs which ensures that class data rhs cast as a string assigns 10545 1.1 mrg correctly. */ 10546 1.1 mrg tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR, 10547 1.1 mrg TREE_TYPE (rse->expr), lse->expr); 10548 1.1 mrg gfc_add_modify (&block, tmp, rse->expr); 10549 1.1 mrg } 10550 1.1 mrg } 10551 1.1 mrg else if (ts.type != BT_CLASS) 10552 1.1 mrg { 10553 1.1 mrg gfc_add_block_to_block (&block, &lse->pre); 10554 1.1 mrg gfc_add_block_to_block (&block, &rse->pre); 10555 1.1 mrg 10556 1.1 mrg gfc_add_modify (&block, lse->expr, 10557 1.1 mrg fold_convert (TREE_TYPE (lse->expr), rse->expr)); 10558 1.1 mrg } 10559 1.1 mrg 10560 1.1 mrg gfc_add_block_to_block (&block, &lse->post); 10561 1.1 mrg gfc_add_block_to_block (&block, &rse->post); 10562 1.1 mrg 10563 1.1 mrg return gfc_finish_block (&block); 10564 1.1 mrg } 10565 1.1 mrg 10566 1.1 mrg 10567 1.1 mrg /* There are quite a lot of restrictions on the optimisation in using an 10568 1.1 mrg array function assign without a temporary. */ 10569 1.1 mrg 10570 1.1 mrg static bool 10571 1.1 mrg arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2) 10572 1.1 mrg { 10573 1.1 mrg gfc_ref * ref; 10574 1.1 mrg bool seen_array_ref; 10575 1.1 mrg bool c = false; 10576 1.1 mrg gfc_symbol *sym = expr1->symtree->n.sym; 10577 1.1 mrg 10578 1.1 mrg /* Play it safe with class functions assigned to a derived type. */ 10579 1.1 mrg if (gfc_is_class_array_function (expr2) 10580 1.1 mrg && expr1->ts.type == BT_DERIVED) 10581 1.1 mrg return true; 10582 1.1 mrg 10583 1.1 mrg /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */ 10584 1.1 mrg if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2)) 10585 1.1 mrg return true; 10586 1.1 mrg 10587 1.1 mrg /* Elemental functions are scalarized so that they don't need a 10588 1.1 mrg temporary in gfc_trans_assignment_1, so return a true. Otherwise, 10589 1.1 mrg they would need special treatment in gfc_trans_arrayfunc_assign. */ 10590 1.1 mrg if (expr2->value.function.esym != NULL 10591 1.1 mrg && expr2->value.function.esym->attr.elemental) 10592 1.1 mrg return true; 10593 1.1 mrg 10594 1.1 mrg /* Need a temporary if rhs is not FULL or a contiguous section. */ 10595 1.1 mrg if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c)) 10596 1.1 mrg return true; 10597 1.1 mrg 10598 1.1 mrg /* Need a temporary if EXPR1 can't be expressed as a descriptor. */ 10599 1.1 mrg if (gfc_ref_needs_temporary_p (expr1->ref)) 10600 1.1 mrg return true; 10601 1.1 mrg 10602 1.1 mrg /* Functions returning pointers or allocatables need temporaries. */ 10603 1.1 mrg if (gfc_expr_attr (expr2).pointer 10604 1.1 mrg || gfc_expr_attr (expr2).allocatable) 10605 1.1 mrg return true; 10606 1.1 mrg 10607 1.1 mrg /* Character array functions need temporaries unless the 10608 1.1 mrg character lengths are the same. */ 10609 1.1 mrg if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0) 10610 1.1 mrg { 10611 1.1 mrg if (expr1->ts.u.cl->length == NULL 10612 1.1 mrg || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT) 10613 1.1 mrg return true; 10614 1.1 mrg 10615 1.1 mrg if (expr2->ts.u.cl->length == NULL 10616 1.1 mrg || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT) 10617 1.1 mrg return true; 10618 1.1 mrg 10619 1.1 mrg if (mpz_cmp (expr1->ts.u.cl->length->value.integer, 10620 1.1 mrg expr2->ts.u.cl->length->value.integer) != 0) 10621 1.1 mrg return true; 10622 1.1 mrg } 10623 1.1 mrg 10624 1.1 mrg /* Check that no LHS component references appear during an array 10625 1.1 mrg reference. This is needed because we do not have the means to 10626 1.1 mrg span any arbitrary stride with an array descriptor. This check 10627 1.1 mrg is not needed for the rhs because the function result has to be 10628 1.1 mrg a complete type. */ 10629 1.1 mrg seen_array_ref = false; 10630 1.1 mrg for (ref = expr1->ref; ref; ref = ref->next) 10631 1.1 mrg { 10632 1.1 mrg if (ref->type == REF_ARRAY) 10633 1.1 mrg seen_array_ref= true; 10634 1.1 mrg else if (ref->type == REF_COMPONENT && seen_array_ref) 10635 1.1 mrg return true; 10636 1.1 mrg } 10637 1.1 mrg 10638 1.1 mrg /* Check for a dependency. */ 10639 1.1 mrg if (gfc_check_fncall_dependency (expr1, INTENT_OUT, 10640 1.1 mrg expr2->value.function.esym, 10641 1.1 mrg expr2->value.function.actual, 10642 1.1 mrg NOT_ELEMENTAL)) 10643 1.1 mrg return true; 10644 1.1 mrg 10645 1.1 mrg /* If we have reached here with an intrinsic function, we do not 10646 1.1 mrg need a temporary except in the particular case that reallocation 10647 1.1 mrg on assignment is active and the lhs is allocatable and a target, 10648 1.1 mrg or a pointer which may be a subref pointer. FIXME: The last 10649 1.1 mrg condition can go away when we use span in the intrinsics 10650 1.1 mrg directly.*/ 10651 1.1 mrg if (expr2->value.function.isym) 10652 1.1 mrg return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target) 10653 1.1 mrg || (sym->attr.pointer && sym->attr.subref_array_pointer); 10654 1.1 mrg 10655 1.1 mrg /* If the LHS is a dummy, we need a temporary if it is not 10656 1.1 mrg INTENT(OUT). */ 10657 1.1 mrg if (sym->attr.dummy && sym->attr.intent != INTENT_OUT) 10658 1.1 mrg return true; 10659 1.1 mrg 10660 1.1 mrg /* If the lhs has been host_associated, is in common, a pointer or is 10661 1.1 mrg a target and the function is not using a RESULT variable, aliasing 10662 1.1 mrg can occur and a temporary is needed. */ 10663 1.1 mrg if ((sym->attr.host_assoc 10664 1.1 mrg || sym->attr.in_common 10665 1.1 mrg || sym->attr.pointer 10666 1.1 mrg || sym->attr.cray_pointee 10667 1.1 mrg || sym->attr.target) 10668 1.1 mrg && expr2->symtree != NULL 10669 1.1 mrg && expr2->symtree->n.sym == expr2->symtree->n.sym->result) 10670 1.1 mrg return true; 10671 1.1 mrg 10672 1.1 mrg /* A PURE function can unconditionally be called without a temporary. */ 10673 1.1 mrg if (expr2->value.function.esym != NULL 10674 1.1 mrg && expr2->value.function.esym->attr.pure) 10675 1.1 mrg return false; 10676 1.1 mrg 10677 1.1 mrg /* Implicit_pure functions are those which could legally be declared 10678 1.1 mrg to be PURE. */ 10679 1.1 mrg if (expr2->value.function.esym != NULL 10680 1.1 mrg && expr2->value.function.esym->attr.implicit_pure) 10681 1.1 mrg return false; 10682 1.1 mrg 10683 1.1 mrg if (!sym->attr.use_assoc 10684 1.1 mrg && !sym->attr.in_common 10685 1.1 mrg && !sym->attr.pointer 10686 1.1 mrg && !sym->attr.target 10687 1.1 mrg && !sym->attr.cray_pointee 10688 1.1 mrg && expr2->value.function.esym) 10689 1.1 mrg { 10690 1.1 mrg /* A temporary is not needed if the function is not contained and 10691 1.1 mrg the variable is local or host associated and not a pointer or 10692 1.1 mrg a target. */ 10693 1.1 mrg if (!expr2->value.function.esym->attr.contained) 10694 1.1 mrg return false; 10695 1.1 mrg 10696 1.1 mrg /* A temporary is not needed if the lhs has never been host 10697 1.1 mrg associated and the procedure is contained. */ 10698 1.1 mrg else if (!sym->attr.host_assoc) 10699 1.1 mrg return false; 10700 1.1 mrg 10701 1.1 mrg /* A temporary is not needed if the variable is local and not 10702 1.1 mrg a pointer, a target or a result. */ 10703 1.1 mrg if (sym->ns->parent 10704 1.1 mrg && expr2->value.function.esym->ns == sym->ns->parent) 10705 1.1 mrg return false; 10706 1.1 mrg } 10707 1.1 mrg 10708 1.1 mrg /* Default to temporary use. */ 10709 1.1 mrg return true; 10710 1.1 mrg } 10711 1.1 mrg 10712 1.1 mrg 10713 1.1 mrg /* Provide the loop info so that the lhs descriptor can be built for 10714 1.1 mrg reallocatable assignments from extrinsic function calls. */ 10715 1.1 mrg 10716 1.1 mrg static void 10717 1.1 mrg realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss, 10718 1.1 mrg gfc_loopinfo *loop) 10719 1.1 mrg { 10720 1.1 mrg /* Signal that the function call should not be made by 10721 1.1 mrg gfc_conv_loop_setup. */ 10722 1.1 mrg se->ss->is_alloc_lhs = 1; 10723 1.1 mrg gfc_init_loopinfo (loop); 10724 1.1 mrg gfc_add_ss_to_loop (loop, *ss); 10725 1.1 mrg gfc_add_ss_to_loop (loop, se->ss); 10726 1.1 mrg gfc_conv_ss_startstride (loop); 10727 1.1 mrg gfc_conv_loop_setup (loop, where); 10728 1.1 mrg gfc_copy_loopinfo_to_se (se, loop); 10729 1.1 mrg gfc_add_block_to_block (&se->pre, &loop->pre); 10730 1.1 mrg gfc_add_block_to_block (&se->pre, &loop->post); 10731 1.1 mrg se->ss->is_alloc_lhs = 0; 10732 1.1 mrg } 10733 1.1 mrg 10734 1.1 mrg 10735 1.1 mrg /* For assignment to a reallocatable lhs from intrinsic functions, 10736 1.1 mrg replace the se.expr (ie. the result) with a temporary descriptor. 10737 1.1 mrg Null the data field so that the library allocates space for the 10738 1.1 mrg result. Free the data of the original descriptor after the function, 10739 1.1 mrg in case it appears in an argument expression and transfer the 10740 1.1 mrg result to the original descriptor. */ 10741 1.1 mrg 10742 1.1 mrg static void 10743 1.1 mrg fcncall_realloc_result (gfc_se *se, int rank) 10744 1.1 mrg { 10745 1.1 mrg tree desc; 10746 1.1 mrg tree res_desc; 10747 1.1 mrg tree tmp; 10748 1.1 mrg tree offset; 10749 1.1 mrg tree zero_cond; 10750 1.1 mrg tree not_same_shape; 10751 1.1 mrg stmtblock_t shape_block; 10752 1.1 mrg int n; 10753 1.1 mrg 10754 1.1 mrg /* Use the allocation done by the library. Substitute the lhs 10755 1.1 mrg descriptor with a copy, whose data field is nulled.*/ 10756 1.1 mrg desc = build_fold_indirect_ref_loc (input_location, se->expr); 10757 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (desc))) 10758 1.1 mrg desc = build_fold_indirect_ref_loc (input_location, desc); 10759 1.1 mrg 10760 1.1 mrg /* Unallocated, the descriptor does not have a dtype. */ 10761 1.1 mrg tmp = gfc_conv_descriptor_dtype (desc); 10762 1.1 mrg gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc))); 10763 1.1 mrg 10764 1.1 mrg res_desc = gfc_evaluate_now (desc, &se->pre); 10765 1.1 mrg gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node); 10766 1.1 mrg se->expr = gfc_build_addr_expr (NULL_TREE, res_desc); 10767 1.1 mrg 10768 1.1 mrg /* Free the lhs after the function call and copy the result data to 10769 1.1 mrg the lhs descriptor. */ 10770 1.1 mrg tmp = gfc_conv_descriptor_data_get (desc); 10771 1.1 mrg zero_cond = fold_build2_loc (input_location, EQ_EXPR, 10772 1.1 mrg logical_type_node, tmp, 10773 1.1 mrg build_int_cst (TREE_TYPE (tmp), 0)); 10774 1.1 mrg zero_cond = gfc_evaluate_now (zero_cond, &se->post); 10775 1.1 mrg tmp = gfc_call_free (tmp); 10776 1.1 mrg gfc_add_expr_to_block (&se->post, tmp); 10777 1.1 mrg 10778 1.1 mrg tmp = gfc_conv_descriptor_data_get (res_desc); 10779 1.1 mrg gfc_conv_descriptor_data_set (&se->post, desc, tmp); 10780 1.1 mrg 10781 1.1 mrg /* Check that the shapes are the same between lhs and expression. 10782 1.1 mrg The evaluation of the shape is done in 'shape_block' to avoid 10783 1.1 mrg unitialized warnings from the lhs bounds. */ 10784 1.1 mrg not_same_shape = boolean_false_node; 10785 1.1 mrg gfc_start_block (&shape_block); 10786 1.1 mrg for (n = 0 ; n < rank; n++) 10787 1.1 mrg { 10788 1.1 mrg tree tmp1; 10789 1.1 mrg tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]); 10790 1.1 mrg tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]); 10791 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, 10792 1.1 mrg gfc_array_index_type, tmp, tmp1); 10793 1.1 mrg tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]); 10794 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, 10795 1.1 mrg gfc_array_index_type, tmp, tmp1); 10796 1.1 mrg tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]); 10797 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, 10798 1.1 mrg gfc_array_index_type, tmp, tmp1); 10799 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, 10800 1.1 mrg logical_type_node, tmp, 10801 1.1 mrg gfc_index_zero_node); 10802 1.1 mrg tmp = gfc_evaluate_now (tmp, &shape_block); 10803 1.1 mrg if (n == 0) 10804 1.1 mrg not_same_shape = tmp; 10805 1.1 mrg else 10806 1.1 mrg not_same_shape = fold_build2_loc (input_location, TRUTH_OR_EXPR, 10807 1.1 mrg logical_type_node, tmp, 10808 1.1 mrg not_same_shape); 10809 1.1 mrg } 10810 1.1 mrg 10811 1.1 mrg /* 'zero_cond' being true is equal to lhs not being allocated or the 10812 1.1 mrg shapes being different. */ 10813 1.1 mrg tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, logical_type_node, 10814 1.1 mrg zero_cond, not_same_shape); 10815 1.1 mrg gfc_add_modify (&shape_block, zero_cond, tmp); 10816 1.1 mrg tmp = gfc_finish_block (&shape_block); 10817 1.1 mrg tmp = build3_v (COND_EXPR, zero_cond, 10818 1.1 mrg build_empty_stmt (input_location), tmp); 10819 1.1 mrg gfc_add_expr_to_block (&se->post, tmp); 10820 1.1 mrg 10821 1.1 mrg /* Now reset the bounds returned from the function call to bounds based 10822 1.1 mrg on the lhs lbounds, except where the lhs is not allocated or the shapes 10823 1.1 mrg of 'variable and 'expr' are different. Set the offset accordingly. */ 10824 1.1 mrg offset = gfc_index_zero_node; 10825 1.1 mrg for (n = 0 ; n < rank; n++) 10826 1.1 mrg { 10827 1.1 mrg tree lbound; 10828 1.1 mrg 10829 1.1 mrg lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]); 10830 1.1 mrg lbound = fold_build3_loc (input_location, COND_EXPR, 10831 1.1 mrg gfc_array_index_type, zero_cond, 10832 1.1 mrg gfc_index_one_node, lbound); 10833 1.1 mrg lbound = gfc_evaluate_now (lbound, &se->post); 10834 1.1 mrg 10835 1.1 mrg tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]); 10836 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, 10837 1.1 mrg gfc_array_index_type, tmp, lbound); 10838 1.1 mrg gfc_conv_descriptor_lbound_set (&se->post, desc, 10839 1.1 mrg gfc_rank_cst[n], lbound); 10840 1.1 mrg gfc_conv_descriptor_ubound_set (&se->post, desc, 10841 1.1 mrg gfc_rank_cst[n], tmp); 10842 1.1 mrg 10843 1.1 mrg /* Set stride and accumulate the offset. */ 10844 1.1 mrg tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]); 10845 1.1 mrg gfc_conv_descriptor_stride_set (&se->post, desc, 10846 1.1 mrg gfc_rank_cst[n], tmp); 10847 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, 10848 1.1 mrg gfc_array_index_type, lbound, tmp); 10849 1.1 mrg offset = fold_build2_loc (input_location, MINUS_EXPR, 10850 1.1 mrg gfc_array_index_type, offset, tmp); 10851 1.1 mrg offset = gfc_evaluate_now (offset, &se->post); 10852 1.1 mrg } 10853 1.1 mrg 10854 1.1 mrg gfc_conv_descriptor_offset_set (&se->post, desc, offset); 10855 1.1 mrg } 10856 1.1 mrg 10857 1.1 mrg 10858 1.1 mrg 10859 1.1 mrg /* Try to translate array(:) = func (...), where func is a transformational 10860 1.1 mrg array function, without using a temporary. Returns NULL if this isn't the 10861 1.1 mrg case. */ 10862 1.1 mrg 10863 1.1 mrg static tree 10864 1.1 mrg gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2) 10865 1.1 mrg { 10866 1.1 mrg gfc_se se; 10867 1.1 mrg gfc_ss *ss = NULL; 10868 1.1 mrg gfc_component *comp = NULL; 10869 1.1 mrg gfc_loopinfo loop; 10870 1.1 mrg 10871 1.1 mrg if (arrayfunc_assign_needs_temporary (expr1, expr2)) 10872 1.1 mrg return NULL; 10873 1.1 mrg 10874 1.1 mrg /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic 10875 1.1 mrg functions. */ 10876 1.1 mrg comp = gfc_get_proc_ptr_comp (expr2); 10877 1.1 mrg 10878 1.1 mrg if (!(expr2->value.function.isym 10879 1.1 mrg || (comp && comp->attr.dimension) 10880 1.1 mrg || (!comp && gfc_return_by_reference (expr2->value.function.esym) 10881 1.1 mrg && expr2->value.function.esym->result->attr.dimension))) 10882 1.1 mrg return NULL; 10883 1.1 mrg 10884 1.1 mrg gfc_init_se (&se, NULL); 10885 1.1 mrg gfc_start_block (&se.pre); 10886 1.1 mrg se.want_pointer = 1; 10887 1.1 mrg 10888 1.1 mrg gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL); 10889 1.1 mrg 10890 1.1 mrg if (expr1->ts.type == BT_DERIVED 10891 1.1 mrg && expr1->ts.u.derived->attr.alloc_comp) 10892 1.1 mrg { 10893 1.1 mrg tree tmp; 10894 1.1 mrg tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr, 10895 1.1 mrg expr1->rank); 10896 1.1 mrg gfc_add_expr_to_block (&se.pre, tmp); 10897 1.1 mrg } 10898 1.1 mrg 10899 1.1 mrg se.direct_byref = 1; 10900 1.1 mrg se.ss = gfc_walk_expr (expr2); 10901 1.1 mrg gcc_assert (se.ss != gfc_ss_terminator); 10902 1.1 mrg 10903 1.1 mrg /* Reallocate on assignment needs the loopinfo for extrinsic functions. 10904 1.1 mrg This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs. 10905 1.1 mrg Clearly, this cannot be done for an allocatable function result, since 10906 1.1 mrg the shape of the result is unknown and, in any case, the function must 10907 1.1 mrg correctly take care of the reallocation internally. For intrinsic 10908 1.1 mrg calls, the array data is freed and the library takes care of allocation. 10909 1.1 mrg TODO: Add logic of trans-array.cc: gfc_alloc_allocatable_for_assignment 10910 1.1 mrg to the library. */ 10911 1.1 mrg if (flag_realloc_lhs 10912 1.1 mrg && gfc_is_reallocatable_lhs (expr1) 10913 1.1 mrg && !gfc_expr_attr (expr1).codimension 10914 1.1 mrg && !gfc_is_coindexed (expr1) 10915 1.1 mrg && !(expr2->value.function.esym 10916 1.1 mrg && expr2->value.function.esym->result->attr.allocatable)) 10917 1.1 mrg { 10918 1.1 mrg realloc_lhs_warning (expr1->ts.type, true, &expr1->where); 10919 1.1 mrg 10920 1.1 mrg if (!expr2->value.function.isym) 10921 1.1 mrg { 10922 1.1 mrg ss = gfc_walk_expr (expr1); 10923 1.1 mrg gcc_assert (ss != gfc_ss_terminator); 10924 1.1 mrg 10925 1.1 mrg realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop); 10926 1.1 mrg ss->is_alloc_lhs = 1; 10927 1.1 mrg } 10928 1.1 mrg else 10929 1.1 mrg fcncall_realloc_result (&se, expr1->rank); 10930 1.1 mrg } 10931 1.1 mrg 10932 1.1 mrg gfc_conv_function_expr (&se, expr2); 10933 1.1 mrg gfc_add_block_to_block (&se.pre, &se.post); 10934 1.1 mrg 10935 1.1 mrg if (ss) 10936 1.1 mrg gfc_cleanup_loop (&loop); 10937 1.1 mrg else 10938 1.1 mrg gfc_free_ss_chain (se.ss); 10939 1.1 mrg 10940 1.1 mrg return gfc_finish_block (&se.pre); 10941 1.1 mrg } 10942 1.1 mrg 10943 1.1 mrg 10944 1.1 mrg /* Try to efficiently translate array(:) = 0. Return NULL if this 10945 1.1 mrg can't be done. */ 10946 1.1 mrg 10947 1.1 mrg static tree 10948 1.1 mrg gfc_trans_zero_assign (gfc_expr * expr) 10949 1.1 mrg { 10950 1.1 mrg tree dest, len, type; 10951 1.1 mrg tree tmp; 10952 1.1 mrg gfc_symbol *sym; 10953 1.1 mrg 10954 1.1 mrg sym = expr->symtree->n.sym; 10955 1.1 mrg dest = gfc_get_symbol_decl (sym); 10956 1.1 mrg 10957 1.1 mrg type = TREE_TYPE (dest); 10958 1.1 mrg if (POINTER_TYPE_P (type)) 10959 1.1 mrg type = TREE_TYPE (type); 10960 1.1 mrg if (!GFC_ARRAY_TYPE_P (type)) 10961 1.1 mrg return NULL_TREE; 10962 1.1 mrg 10963 1.1 mrg /* Determine the length of the array. */ 10964 1.1 mrg len = GFC_TYPE_ARRAY_SIZE (type); 10965 1.1 mrg if (!len || TREE_CODE (len) != INTEGER_CST) 10966 1.1 mrg return NULL_TREE; 10967 1.1 mrg 10968 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type)); 10969 1.1 mrg len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len, 10970 1.1 mrg fold_convert (gfc_array_index_type, tmp)); 10971 1.1 mrg 10972 1.1 mrg /* If we are zeroing a local array avoid taking its address by emitting 10973 1.1 mrg a = {} instead. */ 10974 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (dest))) 10975 1.1 mrg return build2_loc (input_location, MODIFY_EXPR, void_type_node, 10976 1.1 mrg dest, build_constructor (TREE_TYPE (dest), 10977 1.1 mrg NULL)); 10978 1.1 mrg 10979 1.1 mrg /* Convert arguments to the correct types. */ 10980 1.1 mrg dest = fold_convert (pvoid_type_node, dest); 10981 1.1 mrg len = fold_convert (size_type_node, len); 10982 1.1 mrg 10983 1.1 mrg /* Construct call to __builtin_memset. */ 10984 1.1 mrg tmp = build_call_expr_loc (input_location, 10985 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMSET), 10986 1.1 mrg 3, dest, integer_zero_node, len); 10987 1.1 mrg return fold_convert (void_type_node, tmp); 10988 1.1 mrg } 10989 1.1 mrg 10990 1.1 mrg 10991 1.1 mrg /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy 10992 1.1 mrg that constructs the call to __builtin_memcpy. */ 10993 1.1 mrg 10994 1.1 mrg tree 10995 1.1 mrg gfc_build_memcpy_call (tree dst, tree src, tree len) 10996 1.1 mrg { 10997 1.1 mrg tree tmp; 10998 1.1 mrg 10999 1.1 mrg /* Convert arguments to the correct types. */ 11000 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (dst))) 11001 1.1 mrg dst = gfc_build_addr_expr (pvoid_type_node, dst); 11002 1.1 mrg else 11003 1.1 mrg dst = fold_convert (pvoid_type_node, dst); 11004 1.1 mrg 11005 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (src))) 11006 1.1 mrg src = gfc_build_addr_expr (pvoid_type_node, src); 11007 1.1 mrg else 11008 1.1 mrg src = fold_convert (pvoid_type_node, src); 11009 1.1 mrg 11010 1.1 mrg len = fold_convert (size_type_node, len); 11011 1.1 mrg 11012 1.1 mrg /* Construct call to __builtin_memcpy. */ 11013 1.1 mrg tmp = build_call_expr_loc (input_location, 11014 1.1 mrg builtin_decl_explicit (BUILT_IN_MEMCPY), 11015 1.1 mrg 3, dst, src, len); 11016 1.1 mrg return fold_convert (void_type_node, tmp); 11017 1.1 mrg } 11018 1.1 mrg 11019 1.1 mrg 11020 1.1 mrg /* Try to efficiently translate dst(:) = src(:). Return NULL if this 11021 1.1 mrg can't be done. EXPR1 is the destination/lhs and EXPR2 is the 11022 1.1 mrg source/rhs, both are gfc_full_array_ref_p which have been checked for 11023 1.1 mrg dependencies. */ 11024 1.1 mrg 11025 1.1 mrg static tree 11026 1.1 mrg gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2) 11027 1.1 mrg { 11028 1.1 mrg tree dst, dlen, dtype; 11029 1.1 mrg tree src, slen, stype; 11030 1.1 mrg tree tmp; 11031 1.1 mrg 11032 1.1 mrg dst = gfc_get_symbol_decl (expr1->symtree->n.sym); 11033 1.1 mrg src = gfc_get_symbol_decl (expr2->symtree->n.sym); 11034 1.1 mrg 11035 1.1 mrg dtype = TREE_TYPE (dst); 11036 1.1 mrg if (POINTER_TYPE_P (dtype)) 11037 1.1 mrg dtype = TREE_TYPE (dtype); 11038 1.1 mrg stype = TREE_TYPE (src); 11039 1.1 mrg if (POINTER_TYPE_P (stype)) 11040 1.1 mrg stype = TREE_TYPE (stype); 11041 1.1 mrg 11042 1.1 mrg if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype)) 11043 1.1 mrg return NULL_TREE; 11044 1.1 mrg 11045 1.1 mrg /* Determine the lengths of the arrays. */ 11046 1.1 mrg dlen = GFC_TYPE_ARRAY_SIZE (dtype); 11047 1.1 mrg if (!dlen || TREE_CODE (dlen) != INTEGER_CST) 11048 1.1 mrg return NULL_TREE; 11049 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype)); 11050 1.1 mrg dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, 11051 1.1 mrg dlen, fold_convert (gfc_array_index_type, tmp)); 11052 1.1 mrg 11053 1.1 mrg slen = GFC_TYPE_ARRAY_SIZE (stype); 11054 1.1 mrg if (!slen || TREE_CODE (slen) != INTEGER_CST) 11055 1.1 mrg return NULL_TREE; 11056 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype)); 11057 1.1 mrg slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, 11058 1.1 mrg slen, fold_convert (gfc_array_index_type, tmp)); 11059 1.1 mrg 11060 1.1 mrg /* Sanity check that they are the same. This should always be 11061 1.1 mrg the case, as we should already have checked for conformance. */ 11062 1.1 mrg if (!tree_int_cst_equal (slen, dlen)) 11063 1.1 mrg return NULL_TREE; 11064 1.1 mrg 11065 1.1 mrg return gfc_build_memcpy_call (dst, src, dlen); 11066 1.1 mrg } 11067 1.1 mrg 11068 1.1 mrg 11069 1.1 mrg /* Try to efficiently translate array(:) = (/ ... /). Return NULL if 11070 1.1 mrg this can't be done. EXPR1 is the destination/lhs for which 11071 1.1 mrg gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */ 11072 1.1 mrg 11073 1.1 mrg static tree 11074 1.1 mrg gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2) 11075 1.1 mrg { 11076 1.1 mrg unsigned HOST_WIDE_INT nelem; 11077 1.1 mrg tree dst, dtype; 11078 1.1 mrg tree src, stype; 11079 1.1 mrg tree len; 11080 1.1 mrg tree tmp; 11081 1.1 mrg 11082 1.1 mrg nelem = gfc_constant_array_constructor_p (expr2->value.constructor); 11083 1.1 mrg if (nelem == 0) 11084 1.1 mrg return NULL_TREE; 11085 1.1 mrg 11086 1.1 mrg dst = gfc_get_symbol_decl (expr1->symtree->n.sym); 11087 1.1 mrg dtype = TREE_TYPE (dst); 11088 1.1 mrg if (POINTER_TYPE_P (dtype)) 11089 1.1 mrg dtype = TREE_TYPE (dtype); 11090 1.1 mrg if (!GFC_ARRAY_TYPE_P (dtype)) 11091 1.1 mrg return NULL_TREE; 11092 1.1 mrg 11093 1.1 mrg /* Determine the lengths of the array. */ 11094 1.1 mrg len = GFC_TYPE_ARRAY_SIZE (dtype); 11095 1.1 mrg if (!len || TREE_CODE (len) != INTEGER_CST) 11096 1.1 mrg return NULL_TREE; 11097 1.1 mrg 11098 1.1 mrg /* Confirm that the constructor is the same size. */ 11099 1.1 mrg if (compare_tree_int (len, nelem) != 0) 11100 1.1 mrg return NULL_TREE; 11101 1.1 mrg 11102 1.1 mrg tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype)); 11103 1.1 mrg len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len, 11104 1.1 mrg fold_convert (gfc_array_index_type, tmp)); 11105 1.1 mrg 11106 1.1 mrg stype = gfc_typenode_for_spec (&expr2->ts); 11107 1.1 mrg src = gfc_build_constant_array_constructor (expr2, stype); 11108 1.1 mrg 11109 1.1 mrg return gfc_build_memcpy_call (dst, src, len); 11110 1.1 mrg } 11111 1.1 mrg 11112 1.1 mrg 11113 1.1 mrg /* Tells whether the expression is to be treated as a variable reference. */ 11114 1.1 mrg 11115 1.1 mrg bool 11116 1.1 mrg gfc_expr_is_variable (gfc_expr *expr) 11117 1.1 mrg { 11118 1.1 mrg gfc_expr *arg; 11119 1.1 mrg gfc_component *comp; 11120 1.1 mrg gfc_symbol *func_ifc; 11121 1.1 mrg 11122 1.1 mrg if (expr->expr_type == EXPR_VARIABLE) 11123 1.1 mrg return true; 11124 1.1 mrg 11125 1.1 mrg arg = gfc_get_noncopying_intrinsic_argument (expr); 11126 1.1 mrg if (arg) 11127 1.1 mrg { 11128 1.1 mrg gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE); 11129 1.1 mrg return gfc_expr_is_variable (arg); 11130 1.1 mrg } 11131 1.1 mrg 11132 1.1 mrg /* A data-pointer-returning function should be considered as a variable 11133 1.1 mrg too. */ 11134 1.1 mrg if (expr->expr_type == EXPR_FUNCTION 11135 1.1 mrg && expr->ref == NULL) 11136 1.1 mrg { 11137 1.1 mrg if (expr->value.function.isym != NULL) 11138 1.1 mrg return false; 11139 1.1 mrg 11140 1.1 mrg if (expr->value.function.esym != NULL) 11141 1.1 mrg { 11142 1.1 mrg func_ifc = expr->value.function.esym; 11143 1.1 mrg goto found_ifc; 11144 1.1 mrg } 11145 1.1 mrg gcc_assert (expr->symtree); 11146 1.1 mrg func_ifc = expr->symtree->n.sym; 11147 1.1 mrg goto found_ifc; 11148 1.1 mrg } 11149 1.1 mrg 11150 1.1 mrg comp = gfc_get_proc_ptr_comp (expr); 11151 1.1 mrg if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION) 11152 1.1 mrg && comp) 11153 1.1 mrg { 11154 1.1 mrg func_ifc = comp->ts.interface; 11155 1.1 mrg goto found_ifc; 11156 1.1 mrg } 11157 1.1 mrg 11158 1.1 mrg if (expr->expr_type == EXPR_COMPCALL) 11159 1.1 mrg { 11160 1.1 mrg gcc_assert (!expr->value.compcall.tbp->is_generic); 11161 1.1 mrg func_ifc = expr->value.compcall.tbp->u.specific->n.sym; 11162 1.1 mrg goto found_ifc; 11163 1.1 mrg } 11164 1.1 mrg 11165 1.1 mrg return false; 11166 1.1 mrg 11167 1.1 mrg found_ifc: 11168 1.1 mrg gcc_assert (func_ifc->attr.function 11169 1.1 mrg && func_ifc->result != NULL); 11170 1.1 mrg return func_ifc->result->attr.pointer; 11171 1.1 mrg } 11172 1.1 mrg 11173 1.1 mrg 11174 1.1 mrg /* Is the lhs OK for automatic reallocation? */ 11175 1.1 mrg 11176 1.1 mrg static bool 11177 1.1 mrg is_scalar_reallocatable_lhs (gfc_expr *expr) 11178 1.1 mrg { 11179 1.1 mrg gfc_ref * ref; 11180 1.1 mrg 11181 1.1 mrg /* An allocatable variable with no reference. */ 11182 1.1 mrg if (expr->symtree->n.sym->attr.allocatable 11183 1.1 mrg && !expr->ref) 11184 1.1 mrg return true; 11185 1.1 mrg 11186 1.1 mrg /* All that can be left are allocatable components. However, we do 11187 1.1 mrg not check for allocatable components here because the expression 11188 1.1 mrg could be an allocatable component of a pointer component. */ 11189 1.1 mrg if (expr->symtree->n.sym->ts.type != BT_DERIVED 11190 1.1 mrg && expr->symtree->n.sym->ts.type != BT_CLASS) 11191 1.1 mrg return false; 11192 1.1 mrg 11193 1.1 mrg /* Find an allocatable component ref last. */ 11194 1.1 mrg for (ref = expr->ref; ref; ref = ref->next) 11195 1.1 mrg if (ref->type == REF_COMPONENT 11196 1.1 mrg && !ref->next 11197 1.1 mrg && ref->u.c.component->attr.allocatable) 11198 1.1 mrg return true; 11199 1.1 mrg 11200 1.1 mrg return false; 11201 1.1 mrg } 11202 1.1 mrg 11203 1.1 mrg 11204 1.1 mrg /* Allocate or reallocate scalar lhs, as necessary. */ 11205 1.1 mrg 11206 1.1 mrg static void 11207 1.1 mrg alloc_scalar_allocatable_for_assignment (stmtblock_t *block, 11208 1.1 mrg tree string_length, 11209 1.1 mrg gfc_expr *expr1, 11210 1.1 mrg gfc_expr *expr2) 11211 1.1 mrg 11212 1.1 mrg { 11213 1.1 mrg tree cond; 11214 1.1 mrg tree tmp; 11215 1.1 mrg tree size; 11216 1.1 mrg tree size_in_bytes; 11217 1.1 mrg tree jump_label1; 11218 1.1 mrg tree jump_label2; 11219 1.1 mrg gfc_se lse; 11220 1.1 mrg gfc_ref *ref; 11221 1.1 mrg 11222 1.1 mrg if (!expr1 || expr1->rank) 11223 1.1 mrg return; 11224 1.1 mrg 11225 1.1 mrg if (!expr2 || expr2->rank) 11226 1.1 mrg return; 11227 1.1 mrg 11228 1.1 mrg for (ref = expr1->ref; ref; ref = ref->next) 11229 1.1 mrg if (ref->type == REF_SUBSTRING) 11230 1.1 mrg return; 11231 1.1 mrg 11232 1.1 mrg realloc_lhs_warning (expr2->ts.type, false, &expr2->where); 11233 1.1 mrg 11234 1.1 mrg /* Since this is a scalar lhs, we can afford to do this. That is, 11235 1.1 mrg there is no risk of side effects being repeated. */ 11236 1.1 mrg gfc_init_se (&lse, NULL); 11237 1.1 mrg lse.want_pointer = 1; 11238 1.1 mrg gfc_conv_expr (&lse, expr1); 11239 1.1 mrg 11240 1.1 mrg jump_label1 = gfc_build_label_decl (NULL_TREE); 11241 1.1 mrg jump_label2 = gfc_build_label_decl (NULL_TREE); 11242 1.1 mrg 11243 1.1 mrg /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */ 11244 1.1 mrg tmp = build_int_cst (TREE_TYPE (lse.expr), 0); 11245 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, 11246 1.1 mrg lse.expr, tmp); 11247 1.1 mrg tmp = build3_v (COND_EXPR, cond, 11248 1.1 mrg build1_v (GOTO_EXPR, jump_label1), 11249 1.1 mrg build_empty_stmt (input_location)); 11250 1.1 mrg gfc_add_expr_to_block (block, tmp); 11251 1.1 mrg 11252 1.1 mrg if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred) 11253 1.1 mrg { 11254 1.1 mrg /* Use the rhs string length and the lhs element size. */ 11255 1.1 mrg size = string_length; 11256 1.1 mrg tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts)); 11257 1.1 mrg tmp = TYPE_SIZE_UNIT (tmp); 11258 1.1 mrg size_in_bytes = fold_build2_loc (input_location, MULT_EXPR, 11259 1.1 mrg TREE_TYPE (tmp), tmp, 11260 1.1 mrg fold_convert (TREE_TYPE (tmp), size)); 11261 1.1 mrg } 11262 1.1 mrg else 11263 1.1 mrg { 11264 1.1 mrg /* Otherwise use the length in bytes of the rhs. */ 11265 1.1 mrg size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts)); 11266 1.1 mrg size_in_bytes = size; 11267 1.1 mrg } 11268 1.1 mrg 11269 1.1 mrg size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node, 11270 1.1 mrg size_in_bytes, size_one_node); 11271 1.1 mrg 11272 1.1 mrg if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB) 11273 1.1 mrg { 11274 1.1 mrg tree caf_decl, token; 11275 1.1 mrg gfc_se caf_se; 11276 1.1 mrg symbol_attribute attr; 11277 1.1 mrg 11278 1.1 mrg gfc_clear_attr (&attr); 11279 1.1 mrg gfc_init_se (&caf_se, NULL); 11280 1.1 mrg 11281 1.1 mrg caf_decl = gfc_get_tree_for_caf_expr (expr1); 11282 1.1 mrg gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE, 11283 1.1 mrg NULL); 11284 1.1 mrg gfc_add_block_to_block (block, &caf_se.pre); 11285 1.1 mrg gfc_allocate_allocatable (block, lse.expr, size_in_bytes, 11286 1.1 mrg gfc_build_addr_expr (NULL_TREE, token), 11287 1.1 mrg NULL_TREE, NULL_TREE, NULL_TREE, jump_label1, 11288 1.1 mrg expr1, 1); 11289 1.1 mrg } 11290 1.1 mrg else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp) 11291 1.1 mrg { 11292 1.1 mrg tmp = build_call_expr_loc (input_location, 11293 1.1 mrg builtin_decl_explicit (BUILT_IN_CALLOC), 11294 1.1 mrg 2, build_one_cst (size_type_node), 11295 1.1 mrg size_in_bytes); 11296 1.1 mrg tmp = fold_convert (TREE_TYPE (lse.expr), tmp); 11297 1.1 mrg gfc_add_modify (block, lse.expr, tmp); 11298 1.1 mrg } 11299 1.1 mrg else 11300 1.1 mrg { 11301 1.1 mrg tmp = build_call_expr_loc (input_location, 11302 1.1 mrg builtin_decl_explicit (BUILT_IN_MALLOC), 11303 1.1 mrg 1, size_in_bytes); 11304 1.1 mrg tmp = fold_convert (TREE_TYPE (lse.expr), tmp); 11305 1.1 mrg gfc_add_modify (block, lse.expr, tmp); 11306 1.1 mrg } 11307 1.1 mrg 11308 1.1 mrg if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred) 11309 1.1 mrg { 11310 1.1 mrg /* Deferred characters need checking for lhs and rhs string 11311 1.1 mrg length. Other deferred parameter variables will have to 11312 1.1 mrg come here too. */ 11313 1.1 mrg tmp = build1_v (GOTO_EXPR, jump_label2); 11314 1.1 mrg gfc_add_expr_to_block (block, tmp); 11315 1.1 mrg } 11316 1.1 mrg tmp = build1_v (LABEL_EXPR, jump_label1); 11317 1.1 mrg gfc_add_expr_to_block (block, tmp); 11318 1.1 mrg 11319 1.1 mrg /* For a deferred length character, reallocate if lengths of lhs and 11320 1.1 mrg rhs are different. */ 11321 1.1 mrg if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred) 11322 1.1 mrg { 11323 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, 11324 1.1 mrg lse.string_length, 11325 1.1 mrg fold_convert (TREE_TYPE (lse.string_length), 11326 1.1 mrg size)); 11327 1.1 mrg /* Jump past the realloc if the lengths are the same. */ 11328 1.1 mrg tmp = build3_v (COND_EXPR, cond, 11329 1.1 mrg build1_v (GOTO_EXPR, jump_label2), 11330 1.1 mrg build_empty_stmt (input_location)); 11331 1.1 mrg gfc_add_expr_to_block (block, tmp); 11332 1.1 mrg tmp = build_call_expr_loc (input_location, 11333 1.1 mrg builtin_decl_explicit (BUILT_IN_REALLOC), 11334 1.1 mrg 2, fold_convert (pvoid_type_node, lse.expr), 11335 1.1 mrg size_in_bytes); 11336 1.1 mrg tmp = fold_convert (TREE_TYPE (lse.expr), tmp); 11337 1.1 mrg gfc_add_modify (block, lse.expr, tmp); 11338 1.1 mrg tmp = build1_v (LABEL_EXPR, jump_label2); 11339 1.1 mrg gfc_add_expr_to_block (block, tmp); 11340 1.1 mrg 11341 1.1 mrg /* Update the lhs character length. */ 11342 1.1 mrg size = string_length; 11343 1.1 mrg gfc_add_modify (block, lse.string_length, 11344 1.1 mrg fold_convert (TREE_TYPE (lse.string_length), size)); 11345 1.1 mrg } 11346 1.1 mrg } 11347 1.1 mrg 11348 1.1 mrg /* Check for assignments of the type 11349 1.1 mrg 11350 1.1 mrg a = a + 4 11351 1.1 mrg 11352 1.1 mrg to make sure we do not check for reallocation unneccessarily. */ 11353 1.1 mrg 11354 1.1 mrg 11355 1.1 mrg static bool 11356 1.1 mrg is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2) 11357 1.1 mrg { 11358 1.1 mrg gfc_actual_arglist *a; 11359 1.1 mrg gfc_expr *e1, *e2; 11360 1.1 mrg 11361 1.1 mrg switch (expr2->expr_type) 11362 1.1 mrg { 11363 1.1 mrg case EXPR_VARIABLE: 11364 1.1 mrg return gfc_dep_compare_expr (expr1, expr2) == 0; 11365 1.1 mrg 11366 1.1 mrg case EXPR_FUNCTION: 11367 1.1 mrg if (expr2->value.function.esym 11368 1.1 mrg && expr2->value.function.esym->attr.elemental) 11369 1.1 mrg { 11370 1.1 mrg for (a = expr2->value.function.actual; a != NULL; a = a->next) 11371 1.1 mrg { 11372 1.1 mrg e1 = a->expr; 11373 1.1 mrg if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1)) 11374 1.1 mrg return false; 11375 1.1 mrg } 11376 1.1 mrg return true; 11377 1.1 mrg } 11378 1.1 mrg else if (expr2->value.function.isym 11379 1.1 mrg && expr2->value.function.isym->elemental) 11380 1.1 mrg { 11381 1.1 mrg for (a = expr2->value.function.actual; a != NULL; a = a->next) 11382 1.1 mrg { 11383 1.1 mrg e1 = a->expr; 11384 1.1 mrg if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1)) 11385 1.1 mrg return false; 11386 1.1 mrg } 11387 1.1 mrg return true; 11388 1.1 mrg } 11389 1.1 mrg 11390 1.1 mrg break; 11391 1.1 mrg 11392 1.1 mrg case EXPR_OP: 11393 1.1 mrg switch (expr2->value.op.op) 11394 1.1 mrg { 11395 1.1 mrg case INTRINSIC_NOT: 11396 1.1 mrg case INTRINSIC_UPLUS: 11397 1.1 mrg case INTRINSIC_UMINUS: 11398 1.1 mrg case INTRINSIC_PARENTHESES: 11399 1.1 mrg return is_runtime_conformable (expr1, expr2->value.op.op1); 11400 1.1 mrg 11401 1.1 mrg case INTRINSIC_PLUS: 11402 1.1 mrg case INTRINSIC_MINUS: 11403 1.1 mrg case INTRINSIC_TIMES: 11404 1.1 mrg case INTRINSIC_DIVIDE: 11405 1.1 mrg case INTRINSIC_POWER: 11406 1.1 mrg case INTRINSIC_AND: 11407 1.1 mrg case INTRINSIC_OR: 11408 1.1 mrg case INTRINSIC_EQV: 11409 1.1 mrg case INTRINSIC_NEQV: 11410 1.1 mrg case INTRINSIC_EQ: 11411 1.1 mrg case INTRINSIC_NE: 11412 1.1 mrg case INTRINSIC_GT: 11413 1.1 mrg case INTRINSIC_GE: 11414 1.1 mrg case INTRINSIC_LT: 11415 1.1 mrg case INTRINSIC_LE: 11416 1.1 mrg case INTRINSIC_EQ_OS: 11417 1.1 mrg case INTRINSIC_NE_OS: 11418 1.1 mrg case INTRINSIC_GT_OS: 11419 1.1 mrg case INTRINSIC_GE_OS: 11420 1.1 mrg case INTRINSIC_LT_OS: 11421 1.1 mrg case INTRINSIC_LE_OS: 11422 1.1 mrg 11423 1.1 mrg e1 = expr2->value.op.op1; 11424 1.1 mrg e2 = expr2->value.op.op2; 11425 1.1 mrg 11426 1.1 mrg if (e1->rank == 0 && e2->rank > 0) 11427 1.1 mrg return is_runtime_conformable (expr1, e2); 11428 1.1 mrg else if (e1->rank > 0 && e2->rank == 0) 11429 1.1 mrg return is_runtime_conformable (expr1, e1); 11430 1.1 mrg else if (e1->rank > 0 && e2->rank > 0) 11431 1.1 mrg return is_runtime_conformable (expr1, e1) 11432 1.1 mrg && is_runtime_conformable (expr1, e2); 11433 1.1 mrg break; 11434 1.1 mrg 11435 1.1 mrg default: 11436 1.1 mrg break; 11437 1.1 mrg 11438 1.1 mrg } 11439 1.1 mrg 11440 1.1 mrg break; 11441 1.1 mrg 11442 1.1 mrg default: 11443 1.1 mrg break; 11444 1.1 mrg } 11445 1.1 mrg return false; 11446 1.1 mrg } 11447 1.1 mrg 11448 1.1 mrg 11449 1.1 mrg static tree 11450 1.1 mrg trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs, 11451 1.1 mrg gfc_se *lse, gfc_se *rse, bool use_vptr_copy, 11452 1.1 mrg bool class_realloc) 11453 1.1 mrg { 11454 1.1 mrg tree tmp, fcn, stdcopy, to_len, from_len, vptr, old_vptr; 11455 1.1 mrg vec<tree, va_gc> *args = NULL; 11456 1.1 mrg 11457 1.1 mrg /* Store the old vptr so that dynamic types can be compared for 11458 1.1 mrg reallocation to occur or not. */ 11459 1.1 mrg if (class_realloc) 11460 1.1 mrg { 11461 1.1 mrg tmp = lse->expr; 11462 1.1 mrg if (!GFC_CLASS_TYPE_P (TREE_TYPE (tmp))) 11463 1.1 mrg tmp = gfc_get_class_from_expr (tmp); 11464 1.1 mrg } 11465 1.1 mrg 11466 1.1 mrg vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len, 11467 1.1 mrg &from_len); 11468 1.1 mrg 11469 1.1 mrg /* Generate (re)allocation of the lhs. */ 11470 1.1 mrg if (class_realloc) 11471 1.1 mrg { 11472 1.1 mrg stmtblock_t alloc, re_alloc; 11473 1.1 mrg tree class_han, re, size; 11474 1.1 mrg 11475 1.1 mrg if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp))) 11476 1.1 mrg old_vptr = gfc_evaluate_now (gfc_class_vptr_get (tmp), block); 11477 1.1 mrg else 11478 1.1 mrg old_vptr = build_int_cst (TREE_TYPE (vptr), 0); 11479 1.1 mrg 11480 1.1 mrg size = gfc_vptr_size_get (vptr); 11481 1.1 mrg class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr)) 11482 1.1 mrg ? gfc_class_data_get (lse->expr) : lse->expr; 11483 1.1 mrg 11484 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (class_han))) 11485 1.1 mrg class_han = gfc_build_addr_expr (NULL_TREE, class_han); 11486 1.1 mrg 11487 1.1 mrg /* Allocate block. */ 11488 1.1 mrg gfc_init_block (&alloc); 11489 1.1 mrg gfc_allocate_using_malloc (&alloc, class_han, size, NULL_TREE); 11490 1.1 mrg 11491 1.1 mrg /* Reallocate if dynamic types are different. */ 11492 1.1 mrg gfc_init_block (&re_alloc); 11493 1.1 mrg re = build_call_expr_loc (input_location, 11494 1.1 mrg builtin_decl_explicit (BUILT_IN_REALLOC), 2, 11495 1.1 mrg fold_convert (pvoid_type_node, class_han), 11496 1.1 mrg size); 11497 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, 11498 1.1 mrg logical_type_node, vptr, old_vptr); 11499 1.1 mrg re = fold_build3_loc (input_location, COND_EXPR, void_type_node, 11500 1.1 mrg tmp, re, build_empty_stmt (input_location)); 11501 1.1 mrg gfc_add_expr_to_block (&re_alloc, re); 11502 1.1 mrg 11503 1.1 mrg /* Allocate if _data is NULL, reallocate otherwise. */ 11504 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, 11505 1.1 mrg logical_type_node, class_han, 11506 1.1 mrg build_int_cst (prvoid_type_node, 0)); 11507 1.1 mrg tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, 11508 1.1 mrg gfc_unlikely (tmp, 11509 1.1 mrg PRED_FORTRAN_FAIL_ALLOC), 11510 1.1 mrg gfc_finish_block (&alloc), 11511 1.1 mrg gfc_finish_block (&re_alloc)); 11512 1.1 mrg gfc_add_expr_to_block (&lse->pre, tmp); 11513 1.1 mrg } 11514 1.1 mrg 11515 1.1 mrg fcn = gfc_vptr_copy_get (vptr); 11516 1.1 mrg 11517 1.1 mrg tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)) 11518 1.1 mrg ? gfc_class_data_get (rse->expr) : rse->expr; 11519 1.1 mrg if (use_vptr_copy) 11520 1.1 mrg { 11521 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp)) 11522 1.1 mrg || INDIRECT_REF_P (tmp) 11523 1.1 mrg || (rhs->ts.type == BT_DERIVED 11524 1.1 mrg && rhs->ts.u.derived->attr.unlimited_polymorphic 11525 1.1 mrg && !rhs->ts.u.derived->attr.pointer 11526 1.1 mrg && !rhs->ts.u.derived->attr.allocatable) 11527 1.1 mrg || (UNLIMITED_POLY (rhs) 11528 1.1 mrg && !CLASS_DATA (rhs)->attr.pointer 11529 1.1 mrg && !CLASS_DATA (rhs)->attr.allocatable)) 11530 1.1 mrg vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp)); 11531 1.1 mrg else 11532 1.1 mrg vec_safe_push (args, tmp); 11533 1.1 mrg tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr)) 11534 1.1 mrg ? gfc_class_data_get (lse->expr) : lse->expr; 11535 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp)) 11536 1.1 mrg || INDIRECT_REF_P (tmp) 11537 1.1 mrg || (lhs->ts.type == BT_DERIVED 11538 1.1 mrg && lhs->ts.u.derived->attr.unlimited_polymorphic 11539 1.1 mrg && !lhs->ts.u.derived->attr.pointer 11540 1.1 mrg && !lhs->ts.u.derived->attr.allocatable) 11541 1.1 mrg || (UNLIMITED_POLY (lhs) 11542 1.1 mrg && !CLASS_DATA (lhs)->attr.pointer 11543 1.1 mrg && !CLASS_DATA (lhs)->attr.allocatable)) 11544 1.1 mrg vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp)); 11545 1.1 mrg else 11546 1.1 mrg vec_safe_push (args, tmp); 11547 1.1 mrg 11548 1.1 mrg stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args); 11549 1.1 mrg 11550 1.1 mrg if (to_len != NULL_TREE && !integer_zerop (from_len)) 11551 1.1 mrg { 11552 1.1 mrg tree extcopy; 11553 1.1 mrg vec_safe_push (args, from_len); 11554 1.1 mrg vec_safe_push (args, to_len); 11555 1.1 mrg extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args); 11556 1.1 mrg 11557 1.1 mrg tmp = fold_build2_loc (input_location, GT_EXPR, 11558 1.1 mrg logical_type_node, from_len, 11559 1.1 mrg build_zero_cst (TREE_TYPE (from_len))); 11560 1.1 mrg return fold_build3_loc (input_location, COND_EXPR, 11561 1.1 mrg void_type_node, tmp, 11562 1.1 mrg extcopy, stdcopy); 11563 1.1 mrg } 11564 1.1 mrg else 11565 1.1 mrg return stdcopy; 11566 1.1 mrg } 11567 1.1 mrg else 11568 1.1 mrg { 11569 1.1 mrg tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr)) 11570 1.1 mrg ? gfc_class_data_get (lse->expr) : lse->expr; 11571 1.1 mrg stmtblock_t tblock; 11572 1.1 mrg gfc_init_block (&tblock); 11573 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (tmp))) 11574 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp); 11575 1.1 mrg if (!POINTER_TYPE_P (TREE_TYPE (rhst))) 11576 1.1 mrg rhst = gfc_build_addr_expr (NULL_TREE, rhst); 11577 1.1 mrg /* When coming from a ptr_copy lhs and rhs are swapped. */ 11578 1.1 mrg gfc_add_modify_loc (input_location, &tblock, rhst, 11579 1.1 mrg fold_convert (TREE_TYPE (rhst), tmp)); 11580 1.1 mrg return gfc_finish_block (&tblock); 11581 1.1 mrg } 11582 1.1 mrg } 11583 1.1 mrg 11584 1.1 mrg /* Subroutine of gfc_trans_assignment that actually scalarizes the 11585 1.1 mrg assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS. 11586 1.1 mrg init_flag indicates initialization expressions and dealloc that no 11587 1.1 mrg deallocate prior assignment is needed (if in doubt, set true). 11588 1.1 mrg When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy 11589 1.1 mrg routine instead of a pointer assignment. Alias resolution is only done, 11590 1.1 mrg when MAY_ALIAS is set (the default). This flag is used by ALLOCATE() 11591 1.1 mrg where it is known, that newly allocated memory on the lhs can never be 11592 1.1 mrg an alias of the rhs. */ 11593 1.1 mrg 11594 1.1 mrg static tree 11595 1.1 mrg gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag, 11596 1.1 mrg bool dealloc, bool use_vptr_copy, bool may_alias) 11597 1.1 mrg { 11598 1.1 mrg gfc_se lse; 11599 1.1 mrg gfc_se rse; 11600 1.1 mrg gfc_ss *lss; 11601 1.1 mrg gfc_ss *lss_section; 11602 1.1 mrg gfc_ss *rss; 11603 1.1 mrg gfc_loopinfo loop; 11604 1.1 mrg tree tmp; 11605 1.1 mrg stmtblock_t block; 11606 1.1 mrg stmtblock_t body; 11607 1.1 mrg bool l_is_temp; 11608 1.1 mrg bool scalar_to_array; 11609 1.1 mrg tree string_length; 11610 1.1 mrg int n; 11611 1.1 mrg bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false; 11612 1.1 mrg symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr; 11613 1.1 mrg bool is_poly_assign; 11614 1.1 mrg bool realloc_flag; 11615 1.1 mrg 11616 1.1 mrg /* Assignment of the form lhs = rhs. */ 11617 1.1 mrg gfc_start_block (&block); 11618 1.1 mrg 11619 1.1 mrg gfc_init_se (&lse, NULL); 11620 1.1 mrg gfc_init_se (&rse, NULL); 11621 1.1 mrg 11622 1.1 mrg /* Walk the lhs. */ 11623 1.1 mrg lss = gfc_walk_expr (expr1); 11624 1.1 mrg if (gfc_is_reallocatable_lhs (expr1)) 11625 1.1 mrg { 11626 1.1 mrg lss->no_bounds_check = 1; 11627 1.1 mrg if (!(expr2->expr_type == EXPR_FUNCTION 11628 1.1 mrg && expr2->value.function.isym != NULL 11629 1.1 mrg && !(expr2->value.function.isym->elemental 11630 1.1 mrg || expr2->value.function.isym->conversion))) 11631 1.1 mrg lss->is_alloc_lhs = 1; 11632 1.1 mrg } 11633 1.1 mrg else 11634 1.1 mrg lss->no_bounds_check = expr1->no_bounds_check; 11635 1.1 mrg 11636 1.1 mrg rss = NULL; 11637 1.1 mrg 11638 1.1 mrg if ((expr1->ts.type == BT_DERIVED) 11639 1.1 mrg && (gfc_is_class_array_function (expr2) 11640 1.1 mrg || gfc_is_alloc_class_scalar_function (expr2))) 11641 1.1 mrg expr2->must_finalize = 1; 11642 1.1 mrg 11643 1.1 mrg /* Checking whether a class assignment is desired is quite complicated and 11644 1.1 mrg needed at two locations, so do it once only before the information is 11645 1.1 mrg needed. */ 11646 1.1 mrg lhs_attr = gfc_expr_attr (expr1); 11647 1.1 mrg is_poly_assign = (use_vptr_copy || lhs_attr.pointer 11648 1.1 mrg || (lhs_attr.allocatable && !lhs_attr.dimension)) 11649 1.1 mrg && (expr1->ts.type == BT_CLASS 11650 1.1 mrg || gfc_is_class_array_ref (expr1, NULL) 11651 1.1 mrg || gfc_is_class_scalar_expr (expr1) 11652 1.1 mrg || gfc_is_class_array_ref (expr2, NULL) 11653 1.1 mrg || gfc_is_class_scalar_expr (expr2)) 11654 1.1 mrg && lhs_attr.flavor != FL_PROCEDURE; 11655 1.1 mrg 11656 1.1 mrg realloc_flag = flag_realloc_lhs 11657 1.1 mrg && gfc_is_reallocatable_lhs (expr1) 11658 1.1 mrg && expr2->rank 11659 1.1 mrg && !is_runtime_conformable (expr1, expr2); 11660 1.1 mrg 11661 1.1 mrg /* Only analyze the expressions for coarray properties, when in coarray-lib 11662 1.1 mrg mode. */ 11663 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB) 11664 1.1 mrg { 11665 1.1 mrg lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp); 11666 1.1 mrg rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp); 11667 1.1 mrg } 11668 1.1 mrg 11669 1.1 mrg if (lss != gfc_ss_terminator) 11670 1.1 mrg { 11671 1.1 mrg /* The assignment needs scalarization. */ 11672 1.1 mrg lss_section = lss; 11673 1.1 mrg 11674 1.1 mrg /* Find a non-scalar SS from the lhs. */ 11675 1.1 mrg while (lss_section != gfc_ss_terminator 11676 1.1 mrg && lss_section->info->type != GFC_SS_SECTION) 11677 1.1 mrg lss_section = lss_section->next; 11678 1.1 mrg 11679 1.1 mrg gcc_assert (lss_section != gfc_ss_terminator); 11680 1.1 mrg 11681 1.1 mrg /* Initialize the scalarizer. */ 11682 1.1 mrg gfc_init_loopinfo (&loop); 11683 1.1 mrg 11684 1.1 mrg /* Walk the rhs. */ 11685 1.1 mrg rss = gfc_walk_expr (expr2); 11686 1.1 mrg if (rss == gfc_ss_terminator) 11687 1.1 mrg /* The rhs is scalar. Add a ss for the expression. */ 11688 1.1 mrg rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2); 11689 1.1 mrg /* When doing a class assign, then the handle to the rhs needs to be a 11690 1.1 mrg pointer to allow for polymorphism. */ 11691 1.1 mrg if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2)) 11692 1.1 mrg rss->info->type = GFC_SS_REFERENCE; 11693 1.1 mrg 11694 1.1 mrg rss->no_bounds_check = expr2->no_bounds_check; 11695 1.1 mrg /* Associate the SS with the loop. */ 11696 1.1 mrg gfc_add_ss_to_loop (&loop, lss); 11697 1.1 mrg gfc_add_ss_to_loop (&loop, rss); 11698 1.1 mrg 11699 1.1 mrg /* Calculate the bounds of the scalarization. */ 11700 1.1 mrg gfc_conv_ss_startstride (&loop); 11701 1.1 mrg /* Enable loop reversal. */ 11702 1.1 mrg for (n = 0; n < GFC_MAX_DIMENSIONS; n++) 11703 1.1 mrg loop.reverse[n] = GFC_ENABLE_REVERSE; 11704 1.1 mrg /* Resolve any data dependencies in the statement. */ 11705 1.1 mrg if (may_alias) 11706 1.1 mrg gfc_conv_resolve_dependencies (&loop, lss, rss); 11707 1.1 mrg /* Setup the scalarizing loops. */ 11708 1.1 mrg gfc_conv_loop_setup (&loop, &expr2->where); 11709 1.1 mrg 11710 1.1 mrg /* Setup the gfc_se structures. */ 11711 1.1 mrg gfc_copy_loopinfo_to_se (&lse, &loop); 11712 1.1 mrg gfc_copy_loopinfo_to_se (&rse, &loop); 11713 1.1 mrg 11714 1.1 mrg rse.ss = rss; 11715 1.1 mrg gfc_mark_ss_chain_used (rss, 1); 11716 1.1 mrg if (loop.temp_ss == NULL) 11717 1.1 mrg { 11718 1.1 mrg lse.ss = lss; 11719 1.1 mrg gfc_mark_ss_chain_used (lss, 1); 11720 1.1 mrg } 11721 1.1 mrg else 11722 1.1 mrg { 11723 1.1 mrg lse.ss = loop.temp_ss; 11724 1.1 mrg gfc_mark_ss_chain_used (lss, 3); 11725 1.1 mrg gfc_mark_ss_chain_used (loop.temp_ss, 3); 11726 1.1 mrg } 11727 1.1 mrg 11728 1.1 mrg /* Allow the scalarizer to workshare array assignments. */ 11729 1.1 mrg if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY)) 11730 1.1 mrg == OMPWS_WORKSHARE_FLAG 11731 1.1 mrg && loop.temp_ss == NULL) 11732 1.1 mrg { 11733 1.1 mrg maybe_workshare = true; 11734 1.1 mrg ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY; 11735 1.1 mrg } 11736 1.1 mrg 11737 1.1 mrg /* Start the scalarized loop body. */ 11738 1.1 mrg gfc_start_scalarized_body (&loop, &body); 11739 1.1 mrg } 11740 1.1 mrg else 11741 1.1 mrg gfc_init_block (&body); 11742 1.1 mrg 11743 1.1 mrg l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL); 11744 1.1 mrg 11745 1.1 mrg /* Translate the expression. */ 11746 1.1 mrg rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag 11747 1.1 mrg && lhs_caf_attr.codimension; 11748 1.1 mrg gfc_conv_expr (&rse, expr2); 11749 1.1 mrg 11750 1.1 mrg /* Deal with the case of a scalar class function assigned to a derived type. */ 11751 1.1 mrg if (gfc_is_alloc_class_scalar_function (expr2) 11752 1.1 mrg && expr1->ts.type == BT_DERIVED) 11753 1.1 mrg { 11754 1.1 mrg rse.expr = gfc_class_data_get (rse.expr); 11755 1.1 mrg rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr); 11756 1.1 mrg } 11757 1.1 mrg 11758 1.1 mrg /* Stabilize a string length for temporaries. */ 11759 1.1 mrg if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred 11760 1.1 mrg && !(VAR_P (rse.string_length) 11761 1.1 mrg || TREE_CODE (rse.string_length) == PARM_DECL 11762 1.1 mrg || TREE_CODE (rse.string_length) == INDIRECT_REF)) 11763 1.1 mrg string_length = gfc_evaluate_now (rse.string_length, &rse.pre); 11764 1.1 mrg else if (expr2->ts.type == BT_CHARACTER) 11765 1.1 mrg { 11766 1.1 mrg if (expr1->ts.deferred 11767 1.1 mrg && gfc_expr_attr (expr1).allocatable 11768 1.1 mrg && gfc_check_dependency (expr1, expr2, true)) 11769 1.1 mrg rse.string_length = 11770 1.1 mrg gfc_evaluate_now_function_scope (rse.string_length, &rse.pre); 11771 1.1 mrg string_length = rse.string_length; 11772 1.1 mrg } 11773 1.1 mrg else 11774 1.1 mrg string_length = NULL_TREE; 11775 1.1 mrg 11776 1.1 mrg if (l_is_temp) 11777 1.1 mrg { 11778 1.1 mrg gfc_conv_tmp_array_ref (&lse); 11779 1.1 mrg if (expr2->ts.type == BT_CHARACTER) 11780 1.1 mrg lse.string_length = string_length; 11781 1.1 mrg } 11782 1.1 mrg else 11783 1.1 mrg { 11784 1.1 mrg gfc_conv_expr (&lse, expr1); 11785 1.1 mrg if (gfc_option.rtcheck & GFC_RTCHECK_MEM 11786 1.1 mrg && !init_flag 11787 1.1 mrg && gfc_expr_attr (expr1).allocatable 11788 1.1 mrg && expr1->rank 11789 1.1 mrg && !expr2->rank) 11790 1.1 mrg { 11791 1.1 mrg tree cond; 11792 1.1 mrg const char* msg; 11793 1.1 mrg 11794 1.1 mrg tmp = INDIRECT_REF_P (lse.expr) 11795 1.1 mrg ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr; 11796 1.1 mrg STRIP_NOPS (tmp); 11797 1.1 mrg 11798 1.1 mrg /* We should only get array references here. */ 11799 1.1 mrg gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR 11800 1.1 mrg || TREE_CODE (tmp) == ARRAY_REF); 11801 1.1 mrg 11802 1.1 mrg /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR) 11803 1.1 mrg or the array itself(ARRAY_REF). */ 11804 1.1 mrg tmp = TREE_OPERAND (tmp, 0); 11805 1.1 mrg 11806 1.1 mrg /* Provide the address of the array. */ 11807 1.1 mrg if (TREE_CODE (lse.expr) == ARRAY_REF) 11808 1.1 mrg tmp = gfc_build_addr_expr (NULL_TREE, tmp); 11809 1.1 mrg 11810 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, 11811 1.1 mrg tmp, build_int_cst (TREE_TYPE (tmp), 0)); 11812 1.1 mrg msg = _("Assignment of scalar to unallocated array"); 11813 1.1 mrg gfc_trans_runtime_check (true, false, cond, &loop.pre, 11814 1.1 mrg &expr1->where, msg); 11815 1.1 mrg } 11816 1.1 mrg 11817 1.1 mrg /* Deallocate the lhs parameterized components if required. */ 11818 1.1 mrg if (dealloc && expr2->expr_type == EXPR_FUNCTION 11819 1.1 mrg && !expr1->symtree->n.sym->attr.associate_var) 11820 1.1 mrg { 11821 1.1 mrg if (expr1->ts.type == BT_DERIVED 11822 1.1 mrg && expr1->ts.u.derived 11823 1.1 mrg && expr1->ts.u.derived->attr.pdt_type) 11824 1.1 mrg { 11825 1.1 mrg tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr, 11826 1.1 mrg expr1->rank); 11827 1.1 mrg gfc_add_expr_to_block (&lse.pre, tmp); 11828 1.1 mrg } 11829 1.1 mrg else if (expr1->ts.type == BT_CLASS 11830 1.1 mrg && CLASS_DATA (expr1)->ts.u.derived 11831 1.1 mrg && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type) 11832 1.1 mrg { 11833 1.1 mrg tmp = gfc_class_data_get (lse.expr); 11834 1.1 mrg tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived, 11835 1.1 mrg tmp, expr1->rank); 11836 1.1 mrg gfc_add_expr_to_block (&lse.pre, tmp); 11837 1.1 mrg } 11838 1.1 mrg } 11839 1.1 mrg } 11840 1.1 mrg 11841 1.1 mrg /* Assignments of scalar derived types with allocatable components 11842 1.1 mrg to arrays must be done with a deep copy and the rhs temporary 11843 1.1 mrg must have its components deallocated afterwards. */ 11844 1.1 mrg scalar_to_array = (expr2->ts.type == BT_DERIVED 11845 1.1 mrg && expr2->ts.u.derived->attr.alloc_comp 11846 1.1 mrg && !gfc_expr_is_variable (expr2) 11847 1.1 mrg && expr1->rank && !expr2->rank); 11848 1.1 mrg scalar_to_array |= (expr1->ts.type == BT_DERIVED 11849 1.1 mrg && expr1->rank 11850 1.1 mrg && expr1->ts.u.derived->attr.alloc_comp 11851 1.1 mrg && gfc_is_alloc_class_scalar_function (expr2)); 11852 1.1 mrg if (scalar_to_array && dealloc) 11853 1.1 mrg { 11854 1.1 mrg tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0); 11855 1.1 mrg gfc_prepend_expr_to_block (&loop.post, tmp); 11856 1.1 mrg } 11857 1.1 mrg 11858 1.1 mrg /* When assigning a character function result to a deferred-length variable, 11859 1.1 mrg the function call must happen before the (re)allocation of the lhs - 11860 1.1 mrg otherwise the character length of the result is not known. 11861 1.1 mrg NOTE 1: This relies on having the exact dependence of the length type 11862 1.1 mrg parameter available to the caller; gfortran saves it in the .mod files. 11863 1.1 mrg NOTE 2: Vector array references generate an index temporary that must 11864 1.1 mrg not go outside the loop. Otherwise, variables should not generate 11865 1.1 mrg a pre block. 11866 1.1 mrg NOTE 3: The concatenation operation generates a temporary pointer, 11867 1.1 mrg whose allocation must go to the innermost loop. 11868 1.1 mrg NOTE 4: Elemental functions may generate a temporary, too. */ 11869 1.1 mrg if (flag_realloc_lhs 11870 1.1 mrg && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred 11871 1.1 mrg && !(lss != gfc_ss_terminator 11872 1.1 mrg && rss != gfc_ss_terminator 11873 1.1 mrg && ((expr2->expr_type == EXPR_VARIABLE && expr2->rank) 11874 1.1 mrg || (expr2->expr_type == EXPR_FUNCTION 11875 1.1 mrg && expr2->value.function.esym != NULL 11876 1.1 mrg && expr2->value.function.esym->attr.elemental) 11877 1.1 mrg || (expr2->expr_type == EXPR_FUNCTION 11878 1.1 mrg && expr2->value.function.isym != NULL 11879 1.1 mrg && expr2->value.function.isym->elemental) 11880 1.1 mrg || (expr2->expr_type == EXPR_OP 11881 1.1 mrg && expr2->value.op.op == INTRINSIC_CONCAT)))) 11882 1.1 mrg gfc_add_block_to_block (&block, &rse.pre); 11883 1.1 mrg 11884 1.1 mrg /* Nullify the allocatable components corresponding to those of the lhs 11885 1.1 mrg derived type, so that the finalization of the function result does not 11886 1.1 mrg affect the lhs of the assignment. Prepend is used to ensure that the 11887 1.1 mrg nullification occurs before the call to the finalizer. In the case of 11888 1.1 mrg a scalar to array assignment, this is done in gfc_trans_scalar_assign 11889 1.1 mrg as part of the deep copy. */ 11890 1.1 mrg if (!scalar_to_array && expr1->ts.type == BT_DERIVED 11891 1.1 mrg && (gfc_is_class_array_function (expr2) 11892 1.1 mrg || gfc_is_alloc_class_scalar_function (expr2))) 11893 1.1 mrg { 11894 1.1 mrg tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0); 11895 1.1 mrg gfc_prepend_expr_to_block (&rse.post, tmp); 11896 1.1 mrg if (lss != gfc_ss_terminator && rss == gfc_ss_terminator) 11897 1.1 mrg gfc_add_block_to_block (&loop.post, &rse.post); 11898 1.1 mrg } 11899 1.1 mrg 11900 1.1 mrg tmp = NULL_TREE; 11901 1.1 mrg 11902 1.1 mrg if (is_poly_assign) 11903 1.1 mrg { 11904 1.1 mrg tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse, 11905 1.1 mrg use_vptr_copy || (lhs_attr.allocatable 11906 1.1 mrg && !lhs_attr.dimension), 11907 1.1 mrg !realloc_flag && flag_realloc_lhs 11908 1.1 mrg && !lhs_attr.pointer); 11909 1.1 mrg if (expr2->expr_type == EXPR_FUNCTION 11910 1.1 mrg && expr2->ts.type == BT_DERIVED 11911 1.1 mrg && expr2->ts.u.derived->attr.alloc_comp) 11912 1.1 mrg { 11913 1.1 mrg tree tmp2 = gfc_deallocate_alloc_comp (expr2->ts.u.derived, 11914 1.1 mrg rse.expr, expr2->rank); 11915 1.1 mrg if (lss == gfc_ss_terminator) 11916 1.1 mrg gfc_add_expr_to_block (&rse.post, tmp2); 11917 1.1 mrg else 11918 1.1 mrg gfc_add_expr_to_block (&loop.post, tmp2); 11919 1.1 mrg } 11920 1.1 mrg } 11921 1.1 mrg else if (flag_coarray == GFC_FCOARRAY_LIB 11922 1.1 mrg && lhs_caf_attr.codimension && rhs_caf_attr.codimension 11923 1.1 mrg && ((lhs_caf_attr.allocatable && lhs_refs_comp) 11924 1.1 mrg || (rhs_caf_attr.allocatable && rhs_refs_comp))) 11925 1.1 mrg { 11926 1.1 mrg /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an 11927 1.1 mrg allocatable component, because those need to be accessed via the 11928 1.1 mrg caf-runtime. No need to check for coindexes here, because resolve 11929 1.1 mrg has rewritten those already. */ 11930 1.1 mrg gfc_code code; 11931 1.1 mrg gfc_actual_arglist a1, a2; 11932 1.1 mrg /* Clear the structures to prevent accessing garbage. */ 11933 1.1 mrg memset (&code, '\0', sizeof (gfc_code)); 11934 1.1 mrg memset (&a1, '\0', sizeof (gfc_actual_arglist)); 11935 1.1 mrg memset (&a2, '\0', sizeof (gfc_actual_arglist)); 11936 1.1 mrg a1.expr = expr1; 11937 1.1 mrg a1.next = &a2; 11938 1.1 mrg a2.expr = expr2; 11939 1.1 mrg a2.next = NULL; 11940 1.1 mrg code.ext.actual = &a1; 11941 1.1 mrg code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND); 11942 1.1 mrg tmp = gfc_conv_intrinsic_subroutine (&code); 11943 1.1 mrg } 11944 1.1 mrg else if (!is_poly_assign && expr2->must_finalize 11945 1.1 mrg && expr1->ts.type == BT_CLASS 11946 1.1 mrg && expr2->ts.type == BT_CLASS) 11947 1.1 mrg { 11948 1.1 mrg /* This case comes about when the scalarizer provides array element 11949 1.1 mrg references. Use the vptr copy function, since this does a deep 11950 1.1 mrg copy of allocatable components, without which the finalizer call 11951 1.1 mrg will deallocate the components. */ 11952 1.1 mrg tmp = gfc_get_vptr_from_expr (rse.expr); 11953 1.1 mrg if (tmp != NULL_TREE) 11954 1.1 mrg { 11955 1.1 mrg tree fcn = gfc_vptr_copy_get (tmp); 11956 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (fcn))) 11957 1.1 mrg fcn = build_fold_indirect_ref_loc (input_location, fcn); 11958 1.1 mrg tmp = build_call_expr_loc (input_location, 11959 1.1 mrg fcn, 2, 11960 1.1 mrg gfc_build_addr_expr (NULL, rse.expr), 11961 1.1 mrg gfc_build_addr_expr (NULL, lse.expr)); 11962 1.1 mrg } 11963 1.1 mrg } 11964 1.1 mrg 11965 1.1 mrg /* If nothing else works, do it the old fashioned way! */ 11966 1.1 mrg if (tmp == NULL_TREE) 11967 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, 11968 1.1 mrg gfc_expr_is_variable (expr2) 11969 1.1 mrg || scalar_to_array 11970 1.1 mrg || expr2->expr_type == EXPR_ARRAY, 11971 1.1 mrg !(l_is_temp || init_flag) && dealloc, 11972 1.1 mrg expr1->symtree->n.sym->attr.codimension); 11973 1.1 mrg 11974 1.1 mrg /* Add the pre blocks to the body. */ 11975 1.1 mrg gfc_add_block_to_block (&body, &rse.pre); 11976 1.1 mrg gfc_add_block_to_block (&body, &lse.pre); 11977 1.1 mrg gfc_add_expr_to_block (&body, tmp); 11978 1.1 mrg /* Add the post blocks to the body. */ 11979 1.1 mrg gfc_add_block_to_block (&body, &rse.post); 11980 1.1 mrg gfc_add_block_to_block (&body, &lse.post); 11981 1.1 mrg 11982 1.1 mrg if (lss == gfc_ss_terminator) 11983 1.1 mrg { 11984 1.1 mrg /* F2003: Add the code for reallocation on assignment. */ 11985 1.1 mrg if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1) 11986 1.1 mrg && !is_poly_assign) 11987 1.1 mrg alloc_scalar_allocatable_for_assignment (&block, string_length, 11988 1.1 mrg expr1, expr2); 11989 1.1 mrg 11990 1.1 mrg /* Use the scalar assignment as is. */ 11991 1.1 mrg gfc_add_block_to_block (&block, &body); 11992 1.1 mrg } 11993 1.1 mrg else 11994 1.1 mrg { 11995 1.1 mrg gcc_assert (lse.ss == gfc_ss_terminator 11996 1.1 mrg && rse.ss == gfc_ss_terminator); 11997 1.1 mrg 11998 1.1 mrg if (l_is_temp) 11999 1.1 mrg { 12000 1.1 mrg gfc_trans_scalarized_loop_boundary (&loop, &body); 12001 1.1 mrg 12002 1.1 mrg /* We need to copy the temporary to the actual lhs. */ 12003 1.1 mrg gfc_init_se (&lse, NULL); 12004 1.1 mrg gfc_init_se (&rse, NULL); 12005 1.1 mrg gfc_copy_loopinfo_to_se (&lse, &loop); 12006 1.1 mrg gfc_copy_loopinfo_to_se (&rse, &loop); 12007 1.1 mrg 12008 1.1 mrg rse.ss = loop.temp_ss; 12009 1.1 mrg lse.ss = lss; 12010 1.1 mrg 12011 1.1 mrg gfc_conv_tmp_array_ref (&rse); 12012 1.1 mrg gfc_conv_expr (&lse, expr1); 12013 1.1 mrg 12014 1.1 mrg gcc_assert (lse.ss == gfc_ss_terminator 12015 1.1 mrg && rse.ss == gfc_ss_terminator); 12016 1.1 mrg 12017 1.1 mrg if (expr2->ts.type == BT_CHARACTER) 12018 1.1 mrg rse.string_length = string_length; 12019 1.1 mrg 12020 1.1 mrg tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, 12021 1.1 mrg false, dealloc); 12022 1.1 mrg gfc_add_expr_to_block (&body, tmp); 12023 1.1 mrg } 12024 1.1 mrg 12025 1.1 mrg /* F2003: Allocate or reallocate lhs of allocatable array. */ 12026 1.1 mrg if (realloc_flag) 12027 1.1 mrg { 12028 1.1 mrg realloc_lhs_warning (expr1->ts.type, true, &expr1->where); 12029 1.1 mrg ompws_flags &= ~OMPWS_SCALARIZER_WS; 12030 1.1 mrg tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2); 12031 1.1 mrg if (tmp != NULL_TREE) 12032 1.1 mrg gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp); 12033 1.1 mrg } 12034 1.1 mrg 12035 1.1 mrg if (maybe_workshare) 12036 1.1 mrg ompws_flags &= ~OMPWS_SCALARIZER_BODY; 12037 1.1 mrg 12038 1.1 mrg /* Generate the copying loops. */ 12039 1.1 mrg gfc_trans_scalarizing_loops (&loop, &body); 12040 1.1 mrg 12041 1.1 mrg /* Wrap the whole thing up. */ 12042 1.1 mrg gfc_add_block_to_block (&block, &loop.pre); 12043 1.1 mrg gfc_add_block_to_block (&block, &loop.post); 12044 1.1 mrg 12045 1.1 mrg gfc_cleanup_loop (&loop); 12046 1.1 mrg } 12047 1.1 mrg 12048 1.1 mrg return gfc_finish_block (&block); 12049 1.1 mrg } 12050 1.1 mrg 12051 1.1 mrg 12052 1.1 mrg /* Check whether EXPR is a copyable array. */ 12053 1.1 mrg 12054 1.1 mrg static bool 12055 1.1 mrg copyable_array_p (gfc_expr * expr) 12056 1.1 mrg { 12057 1.1 mrg if (expr->expr_type != EXPR_VARIABLE) 12058 1.1 mrg return false; 12059 1.1 mrg 12060 1.1 mrg /* First check it's an array. */ 12061 1.1 mrg if (expr->rank < 1 || !expr->ref || expr->ref->next) 12062 1.1 mrg return false; 12063 1.1 mrg 12064 1.1 mrg if (!gfc_full_array_ref_p (expr->ref, NULL)) 12065 1.1 mrg return false; 12066 1.1 mrg 12067 1.1 mrg /* Next check that it's of a simple enough type. */ 12068 1.1 mrg switch (expr->ts.type) 12069 1.1 mrg { 12070 1.1 mrg case BT_INTEGER: 12071 1.1 mrg case BT_REAL: 12072 1.1 mrg case BT_COMPLEX: 12073 1.1 mrg case BT_LOGICAL: 12074 1.1 mrg return true; 12075 1.1 mrg 12076 1.1 mrg case BT_CHARACTER: 12077 1.1 mrg return false; 12078 1.1 mrg 12079 1.1 mrg case_bt_struct: 12080 1.1 mrg return !expr->ts.u.derived->attr.alloc_comp; 12081 1.1 mrg 12082 1.1 mrg default: 12083 1.1 mrg break; 12084 1.1 mrg } 12085 1.1 mrg 12086 1.1 mrg return false; 12087 1.1 mrg } 12088 1.1 mrg 12089 1.1 mrg /* Translate an assignment. */ 12090 1.1 mrg 12091 1.1 mrg tree 12092 1.1 mrg gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag, 12093 1.1 mrg bool dealloc, bool use_vptr_copy, bool may_alias) 12094 1.1 mrg { 12095 1.1 mrg tree tmp; 12096 1.1 mrg 12097 1.1 mrg /* Special case a single function returning an array. */ 12098 1.1 mrg if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0) 12099 1.1 mrg { 12100 1.1 mrg tmp = gfc_trans_arrayfunc_assign (expr1, expr2); 12101 1.1 mrg if (tmp) 12102 1.1 mrg return tmp; 12103 1.1 mrg } 12104 1.1 mrg 12105 1.1 mrg /* Special case assigning an array to zero. */ 12106 1.1 mrg if (copyable_array_p (expr1) 12107 1.1 mrg && is_zero_initializer_p (expr2)) 12108 1.1 mrg { 12109 1.1 mrg tmp = gfc_trans_zero_assign (expr1); 12110 1.1 mrg if (tmp) 12111 1.1 mrg return tmp; 12112 1.1 mrg } 12113 1.1 mrg 12114 1.1 mrg /* Special case copying one array to another. */ 12115 1.1 mrg if (copyable_array_p (expr1) 12116 1.1 mrg && copyable_array_p (expr2) 12117 1.1 mrg && gfc_compare_types (&expr1->ts, &expr2->ts) 12118 1.1 mrg && !gfc_check_dependency (expr1, expr2, 0)) 12119 1.1 mrg { 12120 1.1 mrg tmp = gfc_trans_array_copy (expr1, expr2); 12121 1.1 mrg if (tmp) 12122 1.1 mrg return tmp; 12123 1.1 mrg } 12124 1.1 mrg 12125 1.1 mrg /* Special case initializing an array from a constant array constructor. */ 12126 1.1 mrg if (copyable_array_p (expr1) 12127 1.1 mrg && expr2->expr_type == EXPR_ARRAY 12128 1.1 mrg && gfc_compare_types (&expr1->ts, &expr2->ts)) 12129 1.1 mrg { 12130 1.1 mrg tmp = gfc_trans_array_constructor_copy (expr1, expr2); 12131 1.1 mrg if (tmp) 12132 1.1 mrg return tmp; 12133 1.1 mrg } 12134 1.1 mrg 12135 1.1 mrg if (UNLIMITED_POLY (expr1) && expr1->rank) 12136 1.1 mrg use_vptr_copy = true; 12137 1.1 mrg 12138 1.1 mrg /* Fallback to the scalarizer to generate explicit loops. */ 12139 1.1 mrg return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc, 12140 1.1 mrg use_vptr_copy, may_alias); 12141 1.1 mrg } 12142 1.1 mrg 12143 1.1 mrg tree 12144 1.1 mrg gfc_trans_init_assign (gfc_code * code) 12145 1.1 mrg { 12146 1.1 mrg return gfc_trans_assignment (code->expr1, code->expr2, true, false, true); 12147 1.1 mrg } 12148 1.1 mrg 12149 1.1 mrg tree 12150 1.1 mrg gfc_trans_assign (gfc_code * code) 12151 1.1 mrg { 12152 1.1 mrg return gfc_trans_assignment (code->expr1, code->expr2, false, true); 12153 1.1 mrg } 12154 1.1 mrg 12155 1.1 mrg /* Generate a simple loop for internal use of the form 12156 1.1 mrg for (var = begin; var <cond> end; var += step) 12157 1.1 mrg body; */ 12158 1.1 mrg void 12159 1.1 mrg gfc_simple_for_loop (stmtblock_t *block, tree var, tree begin, tree end, 12160 1.1 mrg enum tree_code cond, tree step, tree body) 12161 1.1 mrg { 12162 1.1 mrg tree tmp; 12163 1.1 mrg 12164 1.1 mrg /* var = begin. */ 12165 1.1 mrg gfc_add_modify (block, var, begin); 12166 1.1 mrg 12167 1.1 mrg /* Loop: for (var = begin; var <cond> end; var += step). */ 12168 1.1 mrg tree label_loop = gfc_build_label_decl (NULL_TREE); 12169 1.1 mrg tree label_cond = gfc_build_label_decl (NULL_TREE); 12170 1.1 mrg TREE_USED (label_loop) = 1; 12171 1.1 mrg TREE_USED (label_cond) = 1; 12172 1.1 mrg 12173 1.1 mrg gfc_add_expr_to_block (block, build1_v (GOTO_EXPR, label_cond)); 12174 1.1 mrg gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_loop)); 12175 1.1 mrg 12176 1.1 mrg /* Loop body. */ 12177 1.1 mrg gfc_add_expr_to_block (block, body); 12178 1.1 mrg 12179 1.1 mrg /* End of loop body. */ 12180 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var, step); 12181 1.1 mrg gfc_add_modify (block, var, tmp); 12182 1.1 mrg gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_cond)); 12183 1.1 mrg tmp = fold_build2_loc (input_location, cond, boolean_type_node, var, end); 12184 1.1 mrg tmp = build3_v (COND_EXPR, tmp, build1_v (GOTO_EXPR, label_loop), 12185 1.1 mrg build_empty_stmt (input_location)); 12186 1.1 mrg gfc_add_expr_to_block (block, tmp); 12187 1.1 mrg } 12188