1 /* Expression translation
2 Copyright (C) 2002-2022 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 /* trans-expr.cc-- generate GENERIC trees for gfc_expr. */
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "options.h"
28 #include "tree.h"
29 #include "gfortran.h"
30 #include "trans.h"
31 #include "stringpool.h"
32 #include "diagnostic-core.h" /* For fatal_error. */
33 #include "fold-const.h"
34 #include "langhooks.h"
35 #include "arith.h"
36 #include "constructor.h"
37 #include "trans-const.h"
38 #include "trans-types.h"
39 #include "trans-array.h"
40 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
41 #include "trans-stmt.h"
42 #include "dependency.h"
43 #include "gimplify.h"
44 #include "tm.h" /* For CHAR_TYPE_SIZE. */
45
46
47 /* Calculate the number of characters in a string. */
48
49 static tree
gfc_get_character_len(tree type)50 gfc_get_character_len (tree type)
51 {
52 tree len;
53
54 gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
55 && TYPE_STRING_FLAG (type));
56
57 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
58 len = (len) ? (len) : (integer_zero_node);
59 return fold_convert (gfc_charlen_type_node, len);
60 }
61
62
63
64 /* Calculate the number of bytes in a string. */
65
66 tree
gfc_get_character_len_in_bytes(tree type)67 gfc_get_character_len_in_bytes (tree type)
68 {
69 tree tmp, len;
70
71 gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
72 && TYPE_STRING_FLAG (type));
73
74 tmp = TYPE_SIZE_UNIT (TREE_TYPE (type));
75 tmp = (tmp && !integer_zerop (tmp))
76 ? (fold_convert (gfc_charlen_type_node, tmp)) : (NULL_TREE);
77 len = gfc_get_character_len (type);
78 if (tmp && len && !integer_zerop (len))
79 len = fold_build2_loc (input_location, MULT_EXPR,
80 gfc_charlen_type_node, len, tmp);
81 return len;
82 }
83
84
85 /* Convert a scalar to an array descriptor. To be used for assumed-rank
86 arrays. */
87
88 static tree
get_scalar_to_descriptor_type(tree scalar,symbol_attribute attr)89 get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
90 {
91 enum gfc_array_kind akind;
92
93 if (attr.pointer)
94 akind = GFC_ARRAY_POINTER_CONT;
95 else if (attr.allocatable)
96 akind = GFC_ARRAY_ALLOCATABLE;
97 else
98 akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
99
100 if (POINTER_TYPE_P (TREE_TYPE (scalar)))
101 scalar = TREE_TYPE (scalar);
102 return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
103 akind, !(attr.pointer || attr.target));
104 }
105
106 tree
gfc_conv_scalar_to_descriptor(gfc_se * se,tree scalar,symbol_attribute attr)107 gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
108 {
109 tree desc, type, etype;
110
111 type = get_scalar_to_descriptor_type (scalar, attr);
112 etype = TREE_TYPE (scalar);
113 desc = gfc_create_var (type, "desc");
114 DECL_ARTIFICIAL (desc) = 1;
115
116 if (CONSTANT_CLASS_P (scalar))
117 {
118 tree tmp;
119 tmp = gfc_create_var (TREE_TYPE (scalar), "scalar");
120 gfc_add_modify (&se->pre, tmp, scalar);
121 scalar = tmp;
122 }
123 if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
124 scalar = gfc_build_addr_expr (NULL_TREE, scalar);
125 else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
126 etype = TREE_TYPE (etype);
127 gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
128 gfc_get_dtype_rank_type (0, etype));
129 gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
130 gfc_conv_descriptor_span_set (&se->pre, desc,
131 gfc_conv_descriptor_elem_len (desc));
132
133 /* Copy pointer address back - but only if it could have changed and
134 if the actual argument is a pointer and not, e.g., NULL(). */
135 if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
136 gfc_add_modify (&se->post, scalar,
137 fold_convert (TREE_TYPE (scalar),
138 gfc_conv_descriptor_data_get (desc)));
139 return desc;
140 }
141
142
143 /* Get the coarray token from the ultimate array or component ref.
144 Returns a NULL_TREE, when the ref object is not allocatable or pointer. */
145
146 tree
gfc_get_ultimate_alloc_ptr_comps_caf_token(gfc_se * outerse,gfc_expr * expr)147 gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr)
148 {
149 gfc_symbol *sym = expr->symtree->n.sym;
150 bool is_coarray = sym->attr.codimension;
151 gfc_expr *caf_expr = gfc_copy_expr (expr);
152 gfc_ref *ref = caf_expr->ref, *last_caf_ref = NULL;
153
154 while (ref)
155 {
156 if (ref->type == REF_COMPONENT
157 && (ref->u.c.component->attr.allocatable
158 || ref->u.c.component->attr.pointer)
159 && (is_coarray || ref->u.c.component->attr.codimension))
160 last_caf_ref = ref;
161 ref = ref->next;
162 }
163
164 if (last_caf_ref == NULL)
165 return NULL_TREE;
166
167 tree comp = last_caf_ref->u.c.component->caf_token, caf;
168 gfc_se se;
169 bool comp_ref = !last_caf_ref->u.c.component->attr.dimension;
170 if (comp == NULL_TREE && comp_ref)
171 return NULL_TREE;
172 gfc_init_se (&se, outerse);
173 gfc_free_ref_list (last_caf_ref->next);
174 last_caf_ref->next = NULL;
175 caf_expr->rank = comp_ref ? 0 : last_caf_ref->u.c.component->as->rank;
176 se.want_pointer = comp_ref;
177 gfc_conv_expr (&se, caf_expr);
178 gfc_add_block_to_block (&outerse->pre, &se.pre);
179
180 if (TREE_CODE (se.expr) == COMPONENT_REF && comp_ref)
181 se.expr = TREE_OPERAND (se.expr, 0);
182 gfc_free_expr (caf_expr);
183
184 if (comp_ref)
185 caf = fold_build3_loc (input_location, COMPONENT_REF,
186 TREE_TYPE (comp), se.expr, comp, NULL_TREE);
187 else
188 caf = gfc_conv_descriptor_token (se.expr);
189 return gfc_build_addr_expr (NULL_TREE, caf);
190 }
191
192
193 /* This is the seed for an eventual trans-class.c
194
195 The following parameters should not be used directly since they might
196 in future implementations. Use the corresponding APIs. */
197 #define CLASS_DATA_FIELD 0
198 #define CLASS_VPTR_FIELD 1
199 #define CLASS_LEN_FIELD 2
200 #define VTABLE_HASH_FIELD 0
201 #define VTABLE_SIZE_FIELD 1
202 #define VTABLE_EXTENDS_FIELD 2
203 #define VTABLE_DEF_INIT_FIELD 3
204 #define VTABLE_COPY_FIELD 4
205 #define VTABLE_FINAL_FIELD 5
206 #define VTABLE_DEALLOCATE_FIELD 6
207
208
209 tree
gfc_class_set_static_fields(tree decl,tree vptr,tree data)210 gfc_class_set_static_fields (tree decl, tree vptr, tree data)
211 {
212 tree tmp;
213 tree field;
214 vec<constructor_elt, va_gc> *init = NULL;
215
216 field = TYPE_FIELDS (TREE_TYPE (decl));
217 tmp = gfc_advance_chain (field, CLASS_DATA_FIELD);
218 CONSTRUCTOR_APPEND_ELT (init, tmp, data);
219
220 tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD);
221 CONSTRUCTOR_APPEND_ELT (init, tmp, vptr);
222
223 return build_constructor (TREE_TYPE (decl), init);
224 }
225
226
227 tree
gfc_class_data_get(tree decl)228 gfc_class_data_get (tree decl)
229 {
230 tree data;
231 if (POINTER_TYPE_P (TREE_TYPE (decl)))
232 decl = build_fold_indirect_ref_loc (input_location, decl);
233 data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
234 CLASS_DATA_FIELD);
235 return fold_build3_loc (input_location, COMPONENT_REF,
236 TREE_TYPE (data), decl, data,
237 NULL_TREE);
238 }
239
240
241 tree
gfc_class_vptr_get(tree decl)242 gfc_class_vptr_get (tree decl)
243 {
244 tree vptr;
245 /* For class arrays decl may be a temporary descriptor handle, the vptr is
246 then available through the saved descriptor. */
247 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
248 && GFC_DECL_SAVED_DESCRIPTOR (decl))
249 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
250 if (POINTER_TYPE_P (TREE_TYPE (decl)))
251 decl = build_fold_indirect_ref_loc (input_location, decl);
252 vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
253 CLASS_VPTR_FIELD);
254 return fold_build3_loc (input_location, COMPONENT_REF,
255 TREE_TYPE (vptr), decl, vptr,
256 NULL_TREE);
257 }
258
259
260 tree
gfc_class_len_get(tree decl)261 gfc_class_len_get (tree decl)
262 {
263 tree len;
264 /* For class arrays decl may be a temporary descriptor handle, the len is
265 then available through the saved descriptor. */
266 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
267 && GFC_DECL_SAVED_DESCRIPTOR (decl))
268 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
269 if (POINTER_TYPE_P (TREE_TYPE (decl)))
270 decl = build_fold_indirect_ref_loc (input_location, decl);
271 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
272 CLASS_LEN_FIELD);
273 return fold_build3_loc (input_location, COMPONENT_REF,
274 TREE_TYPE (len), decl, len,
275 NULL_TREE);
276 }
277
278
279 /* Try to get the _len component of a class. When the class is not unlimited
280 poly, i.e. no _len field exists, then return a zero node. */
281
282 static tree
gfc_class_len_or_zero_get(tree decl)283 gfc_class_len_or_zero_get (tree decl)
284 {
285 tree len;
286 /* For class arrays decl may be a temporary descriptor handle, the vptr is
287 then available through the saved descriptor. */
288 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
289 && GFC_DECL_SAVED_DESCRIPTOR (decl))
290 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
291 if (POINTER_TYPE_P (TREE_TYPE (decl)))
292 decl = build_fold_indirect_ref_loc (input_location, decl);
293 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
294 CLASS_LEN_FIELD);
295 return len != NULL_TREE ? fold_build3_loc (input_location, COMPONENT_REF,
296 TREE_TYPE (len), decl, len,
297 NULL_TREE)
298 : build_zero_cst (gfc_charlen_type_node);
299 }
300
301
302 tree
gfc_resize_class_size_with_len(stmtblock_t * block,tree class_expr,tree size)303 gfc_resize_class_size_with_len (stmtblock_t * block, tree class_expr, tree size)
304 {
305 tree tmp;
306 tree tmp2;
307 tree type;
308
309 tmp = gfc_class_len_or_zero_get (class_expr);
310
311 /* Include the len value in the element size if present. */
312 if (!integer_zerop (tmp))
313 {
314 type = TREE_TYPE (size);
315 if (block)
316 {
317 size = gfc_evaluate_now (size, block);
318 tmp = gfc_evaluate_now (fold_convert (type , tmp), block);
319 }
320 tmp2 = fold_build2_loc (input_location, MULT_EXPR,
321 type, size, tmp);
322 tmp = fold_build2_loc (input_location, GT_EXPR,
323 logical_type_node, tmp,
324 build_zero_cst (type));
325 size = fold_build3_loc (input_location, COND_EXPR,
326 type, tmp, tmp2, size);
327 }
328 else
329 return size;
330
331 if (block)
332 size = gfc_evaluate_now (size, block);
333
334 return size;
335 }
336
337
338 /* Get the specified FIELD from the VPTR. */
339
340 static tree
vptr_field_get(tree vptr,int fieldno)341 vptr_field_get (tree vptr, int fieldno)
342 {
343 tree field;
344 vptr = build_fold_indirect_ref_loc (input_location, vptr);
345 field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
346 fieldno);
347 field = fold_build3_loc (input_location, COMPONENT_REF,
348 TREE_TYPE (field), vptr, field,
349 NULL_TREE);
350 gcc_assert (field);
351 return field;
352 }
353
354
355 /* Get the field from the class' vptr. */
356
357 static tree
class_vtab_field_get(tree decl,int fieldno)358 class_vtab_field_get (tree decl, int fieldno)
359 {
360 tree vptr;
361 vptr = gfc_class_vptr_get (decl);
362 return vptr_field_get (vptr, fieldno);
363 }
364
365
366 /* Define a macro for creating the class_vtab_* and vptr_* accessors in
367 unison. */
368 #define VTAB_GET_FIELD_GEN(name, field) tree \
369 gfc_class_vtab_## name ##_get (tree cl) \
370 { \
371 return class_vtab_field_get (cl, field); \
372 } \
373 \
374 tree \
375 gfc_vptr_## name ##_get (tree vptr) \
376 { \
377 return vptr_field_get (vptr, field); \
378 }
379
VTAB_GET_FIELD_GEN(hash,VTABLE_HASH_FIELD)380 VTAB_GET_FIELD_GEN (hash, VTABLE_HASH_FIELD)
381 VTAB_GET_FIELD_GEN (extends, VTABLE_EXTENDS_FIELD)
382 VTAB_GET_FIELD_GEN (def_init, VTABLE_DEF_INIT_FIELD)
383 VTAB_GET_FIELD_GEN (copy, VTABLE_COPY_FIELD)
384 VTAB_GET_FIELD_GEN (final, VTABLE_FINAL_FIELD)
385 VTAB_GET_FIELD_GEN (deallocate, VTABLE_DEALLOCATE_FIELD)
386 #undef VTAB_GET_FIELD_GEN
387
388 /* The size field is returned as an array index type. Therefore treat
389 it and only it specially. */
390
391 tree
392 gfc_class_vtab_size_get (tree cl)
393 {
394 tree size;
395 size = class_vtab_field_get (cl, VTABLE_SIZE_FIELD);
396 /* Always return size as an array index type. */
397 size = fold_convert (gfc_array_index_type, size);
398 gcc_assert (size);
399 return size;
400 }
401
402 tree
gfc_vptr_size_get(tree vptr)403 gfc_vptr_size_get (tree vptr)
404 {
405 tree size;
406 size = vptr_field_get (vptr, VTABLE_SIZE_FIELD);
407 /* Always return size as an array index type. */
408 size = fold_convert (gfc_array_index_type, size);
409 gcc_assert (size);
410 return size;
411 }
412
413
414 #undef CLASS_DATA_FIELD
415 #undef CLASS_VPTR_FIELD
416 #undef CLASS_LEN_FIELD
417 #undef VTABLE_HASH_FIELD
418 #undef VTABLE_SIZE_FIELD
419 #undef VTABLE_EXTENDS_FIELD
420 #undef VTABLE_DEF_INIT_FIELD
421 #undef VTABLE_COPY_FIELD
422 #undef VTABLE_FINAL_FIELD
423
424
425 /* IF ts is null (default), search for the last _class ref in the chain
426 of references of the expression and cut the chain there. Although
427 this routine is similiar to class.cc:gfc_add_component_ref (), there
428 is a significant difference: gfc_add_component_ref () concentrates
429 on an array ref that is the last ref in the chain and is oblivious
430 to the kind of refs following.
431 ELSE IF ts is non-null the cut is at the class entity or component
432 that is followed by an array reference, which is not an element.
433 These calls come from trans-array.cc:build_class_array_ref, which
434 handles scalarized class array references.*/
435
436 gfc_expr *
gfc_find_and_cut_at_last_class_ref(gfc_expr * e,bool is_mold,gfc_typespec ** ts)437 gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold,
438 gfc_typespec **ts)
439 {
440 gfc_expr *base_expr;
441 gfc_ref *ref, *class_ref, *tail = NULL, *array_ref;
442
443 /* Find the last class reference. */
444 class_ref = NULL;
445 array_ref = NULL;
446
447 if (ts)
448 {
449 if (e->symtree
450 && e->symtree->n.sym->ts.type == BT_CLASS)
451 *ts = &e->symtree->n.sym->ts;
452 else
453 *ts = NULL;
454 }
455
456 for (ref = e->ref; ref; ref = ref->next)
457 {
458 if (ts)
459 {
460 if (ref->type == REF_COMPONENT
461 && ref->u.c.component->ts.type == BT_CLASS
462 && ref->next && ref->next->type == REF_COMPONENT
463 && !strcmp (ref->next->u.c.component->name, "_data")
464 && ref->next->next
465 && ref->next->next->type == REF_ARRAY
466 && ref->next->next->u.ar.type != AR_ELEMENT)
467 {
468 *ts = &ref->u.c.component->ts;
469 class_ref = ref;
470 break;
471 }
472
473 if (ref->next == NULL)
474 break;
475 }
476 else
477 {
478 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
479 array_ref = ref;
480
481 if (ref->type == REF_COMPONENT
482 && ref->u.c.component->ts.type == BT_CLASS)
483 {
484 /* Component to the right of a part reference with nonzero
485 rank must not have the ALLOCATABLE attribute. If attempts
486 are made to reference such a component reference, an error
487 results followed by an ICE. */
488 if (array_ref
489 && CLASS_DATA (ref->u.c.component)->attr.allocatable)
490 return NULL;
491 class_ref = ref;
492 }
493 }
494 }
495
496 if (ts && *ts == NULL)
497 return NULL;
498
499 /* Remove and store all subsequent references after the
500 CLASS reference. */
501 if (class_ref)
502 {
503 tail = class_ref->next;
504 class_ref->next = NULL;
505 }
506 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
507 {
508 tail = e->ref;
509 e->ref = NULL;
510 }
511
512 if (is_mold)
513 base_expr = gfc_expr_to_initialize (e);
514 else
515 base_expr = gfc_copy_expr (e);
516
517 /* Restore the original tail expression. */
518 if (class_ref)
519 {
520 gfc_free_ref_list (class_ref->next);
521 class_ref->next = tail;
522 }
523 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
524 {
525 gfc_free_ref_list (e->ref);
526 e->ref = tail;
527 }
528 return base_expr;
529 }
530
531
532 /* Reset the vptr to the declared type, e.g. after deallocation. */
533
534 void
gfc_reset_vptr(stmtblock_t * block,gfc_expr * e)535 gfc_reset_vptr (stmtblock_t *block, gfc_expr *e)
536 {
537 gfc_symbol *vtab;
538 tree vptr;
539 tree vtable;
540 gfc_se se;
541
542 /* Evaluate the expression and obtain the vptr from it. */
543 gfc_init_se (&se, NULL);
544 if (e->rank)
545 gfc_conv_expr_descriptor (&se, e);
546 else
547 gfc_conv_expr (&se, e);
548 gfc_add_block_to_block (block, &se.pre);
549 vptr = gfc_get_vptr_from_expr (se.expr);
550
551 /* If a vptr is not found, we can do nothing more. */
552 if (vptr == NULL_TREE)
553 return;
554
555 if (UNLIMITED_POLY (e))
556 gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0));
557 else
558 {
559 /* Return the vptr to the address of the declared type. */
560 vtab = gfc_find_derived_vtab (e->ts.u.derived);
561 vtable = vtab->backend_decl;
562 if (vtable == NULL_TREE)
563 vtable = gfc_get_symbol_decl (vtab);
564 vtable = gfc_build_addr_expr (NULL, vtable);
565 vtable = fold_convert (TREE_TYPE (vptr), vtable);
566 gfc_add_modify (block, vptr, vtable);
567 }
568 }
569
570
571 /* Reset the len for unlimited polymorphic objects. */
572
573 void
gfc_reset_len(stmtblock_t * block,gfc_expr * expr)574 gfc_reset_len (stmtblock_t *block, gfc_expr *expr)
575 {
576 gfc_expr *e;
577 gfc_se se_len;
578 e = gfc_find_and_cut_at_last_class_ref (expr);
579 if (e == NULL)
580 return;
581 gfc_add_len_component (e);
582 gfc_init_se (&se_len, NULL);
583 gfc_conv_expr (&se_len, e);
584 gfc_add_modify (block, se_len.expr,
585 fold_convert (TREE_TYPE (se_len.expr), integer_zero_node));
586 gfc_free_expr (e);
587 }
588
589
590 /* Obtain the last class reference in a gfc_expr. Return NULL_TREE if no class
591 reference is found. Note that it is up to the caller to avoid using this
592 for expressions other than variables. */
593
594 tree
gfc_get_class_from_gfc_expr(gfc_expr * e)595 gfc_get_class_from_gfc_expr (gfc_expr *e)
596 {
597 gfc_expr *class_expr;
598 gfc_se cse;
599 class_expr = gfc_find_and_cut_at_last_class_ref (e);
600 if (class_expr == NULL)
601 return NULL_TREE;
602 gfc_init_se (&cse, NULL);
603 gfc_conv_expr (&cse, class_expr);
604 gfc_free_expr (class_expr);
605 return cse.expr;
606 }
607
608
609 /* Obtain the last class reference in an expression.
610 Return NULL_TREE if no class reference is found. */
611
612 tree
gfc_get_class_from_expr(tree expr)613 gfc_get_class_from_expr (tree expr)
614 {
615 tree tmp;
616 tree type;
617
618 for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
619 {
620 if (CONSTANT_CLASS_P (tmp))
621 return NULL_TREE;
622
623 type = TREE_TYPE (tmp);
624 while (type)
625 {
626 if (GFC_CLASS_TYPE_P (type))
627 return tmp;
628 if (type != TYPE_CANONICAL (type))
629 type = TYPE_CANONICAL (type);
630 else
631 type = NULL_TREE;
632 }
633 if (VAR_P (tmp) || TREE_CODE (tmp) == PARM_DECL)
634 break;
635 }
636
637 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
638 tmp = build_fold_indirect_ref_loc (input_location, tmp);
639
640 if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
641 return tmp;
642
643 return NULL_TREE;
644 }
645
646
647 /* Obtain the vptr of the last class reference in an expression.
648 Return NULL_TREE if no class reference is found. */
649
650 tree
gfc_get_vptr_from_expr(tree expr)651 gfc_get_vptr_from_expr (tree expr)
652 {
653 tree tmp;
654
655 tmp = gfc_get_class_from_expr (expr);
656
657 if (tmp != NULL_TREE)
658 return gfc_class_vptr_get (tmp);
659
660 return NULL_TREE;
661 }
662
663
664 static void
class_array_data_assign(stmtblock_t * block,tree lhs_desc,tree rhs_desc,bool lhs_type)665 class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
666 bool lhs_type)
667 {
668 tree tmp, tmp2, type;
669
670 gfc_conv_descriptor_data_set (block, lhs_desc,
671 gfc_conv_descriptor_data_get (rhs_desc));
672 gfc_conv_descriptor_offset_set (block, lhs_desc,
673 gfc_conv_descriptor_offset_get (rhs_desc));
674
675 gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
676 gfc_conv_descriptor_dtype (rhs_desc));
677
678 /* Assign the dimension as range-ref. */
679 tmp = gfc_get_descriptor_dimension (lhs_desc);
680 tmp2 = gfc_get_descriptor_dimension (rhs_desc);
681
682 type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
683 tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
684 gfc_index_zero_node, NULL_TREE, NULL_TREE);
685 tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
686 gfc_index_zero_node, NULL_TREE, NULL_TREE);
687 gfc_add_modify (block, tmp, tmp2);
688 }
689
690
691 /* Takes a derived type expression and returns the address of a temporary
692 class object of the 'declared' type. If vptr is not NULL, this is
693 used for the temporary class object.
694 optional_alloc_ptr is false when the dummy is neither allocatable
695 nor a pointer; that's only relevant for the optional handling.
696 The optional argument 'derived_array' is used to preserve the parmse
697 expression for deallocation of allocatable components. Assumed rank
698 formal arguments made this necessary. */
699 void
gfc_conv_derived_to_class(gfc_se * parmse,gfc_expr * e,gfc_typespec class_ts,tree vptr,bool optional,bool optional_alloc_ptr,tree * derived_array)700 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
701 gfc_typespec class_ts, tree vptr, bool optional,
702 bool optional_alloc_ptr,
703 tree *derived_array)
704 {
705 gfc_symbol *vtab;
706 tree cond_optional = NULL_TREE;
707 gfc_ss *ss;
708 tree ctree;
709 tree var;
710 tree tmp;
711 int dim;
712
713 /* The derived type needs to be converted to a temporary
714 CLASS object. */
715 tmp = gfc_typenode_for_spec (&class_ts);
716 var = gfc_create_var (tmp, "class");
717
718 /* Set the vptr. */
719 ctree = gfc_class_vptr_get (var);
720
721 if (vptr != NULL_TREE)
722 {
723 /* Use the dynamic vptr. */
724 tmp = vptr;
725 }
726 else
727 {
728 /* In this case the vtab corresponds to the derived type and the
729 vptr must point to it. */
730 vtab = gfc_find_derived_vtab (e->ts.u.derived);
731 gcc_assert (vtab);
732 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
733 }
734 gfc_add_modify (&parmse->pre, ctree,
735 fold_convert (TREE_TYPE (ctree), tmp));
736
737 /* Now set the data field. */
738 ctree = gfc_class_data_get (var);
739
740 if (optional)
741 cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
742
743 if (parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
744 {
745 /* If there is a ready made pointer to a derived type, use it
746 rather than evaluating the expression again. */
747 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
748 gfc_add_modify (&parmse->pre, ctree, tmp);
749 }
750 else if (parmse->ss && parmse->ss->info && parmse->ss->info->useflags)
751 {
752 /* For an array reference in an elemental procedure call we need
753 to retain the ss to provide the scalarized array reference. */
754 gfc_conv_expr_reference (parmse, e);
755 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
756 if (optional)
757 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
758 cond_optional, tmp,
759 fold_convert (TREE_TYPE (tmp), null_pointer_node));
760 gfc_add_modify (&parmse->pre, ctree, tmp);
761 }
762 else
763 {
764 ss = gfc_walk_expr (e);
765 if (ss == gfc_ss_terminator)
766 {
767 parmse->ss = NULL;
768 gfc_conv_expr_reference (parmse, e);
769
770 /* Scalar to an assumed-rank array. */
771 if (class_ts.u.derived->components->as)
772 {
773 tree type;
774 type = get_scalar_to_descriptor_type (parmse->expr,
775 gfc_expr_attr (e));
776 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
777 gfc_get_dtype (type));
778 if (optional)
779 parmse->expr = build3_loc (input_location, COND_EXPR,
780 TREE_TYPE (parmse->expr),
781 cond_optional, parmse->expr,
782 fold_convert (TREE_TYPE (parmse->expr),
783 null_pointer_node));
784 gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
785 }
786 else
787 {
788 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
789 if (optional)
790 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
791 cond_optional, tmp,
792 fold_convert (TREE_TYPE (tmp),
793 null_pointer_node));
794 gfc_add_modify (&parmse->pre, ctree, tmp);
795 }
796 }
797 else
798 {
799 stmtblock_t block;
800 gfc_init_block (&block);
801 gfc_ref *ref;
802
803 parmse->ss = ss;
804 parmse->use_offset = 1;
805 gfc_conv_expr_descriptor (parmse, e);
806
807 /* Detect any array references with vector subscripts. */
808 for (ref = e->ref; ref; ref = ref->next)
809 if (ref->type == REF_ARRAY
810 && ref->u.ar.type != AR_ELEMENT
811 && ref->u.ar.type != AR_FULL)
812 {
813 for (dim = 0; dim < ref->u.ar.dimen; dim++)
814 if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
815 break;
816 if (dim < ref->u.ar.dimen)
817 break;
818 }
819
820 /* Array references with vector subscripts and non-variable expressions
821 need be converted to a one-based descriptor. */
822 if (ref || e->expr_type != EXPR_VARIABLE)
823 {
824 for (dim = 0; dim < e->rank; ++dim)
825 gfc_conv_shift_descriptor_lbound (&block, parmse->expr, dim,
826 gfc_index_one_node);
827 }
828
829 if (e->rank != class_ts.u.derived->components->as->rank)
830 {
831 gcc_assert (class_ts.u.derived->components->as->type
832 == AS_ASSUMED_RANK);
833 if (derived_array
834 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse->expr)))
835 {
836 *derived_array = gfc_create_var (TREE_TYPE (parmse->expr),
837 "array");
838 gfc_add_modify (&block, *derived_array , parmse->expr);
839 }
840 class_array_data_assign (&block, ctree, parmse->expr, false);
841 }
842 else
843 {
844 if (gfc_expr_attr (e).codimension)
845 parmse->expr = fold_build1_loc (input_location,
846 VIEW_CONVERT_EXPR,
847 TREE_TYPE (ctree),
848 parmse->expr);
849 gfc_add_modify (&block, ctree, parmse->expr);
850 }
851
852 if (optional)
853 {
854 tmp = gfc_finish_block (&block);
855
856 gfc_init_block (&block);
857 gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
858 if (derived_array && *derived_array != NULL_TREE)
859 gfc_conv_descriptor_data_set (&block, *derived_array,
860 null_pointer_node);
861
862 tmp = build3_v (COND_EXPR, cond_optional, tmp,
863 gfc_finish_block (&block));
864 gfc_add_expr_to_block (&parmse->pre, tmp);
865 }
866 else
867 gfc_add_block_to_block (&parmse->pre, &block);
868 }
869 }
870
871 if (class_ts.u.derived->components->ts.type == BT_DERIVED
872 && class_ts.u.derived->components->ts.u.derived
873 ->attr.unlimited_polymorphic)
874 {
875 /* Take care about initializing the _len component correctly. */
876 ctree = gfc_class_len_get (var);
877 if (UNLIMITED_POLY (e))
878 {
879 gfc_expr *len;
880 gfc_se se;
881
882 len = gfc_find_and_cut_at_last_class_ref (e);
883 gfc_add_len_component (len);
884 gfc_init_se (&se, NULL);
885 gfc_conv_expr (&se, len);
886 if (optional)
887 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr),
888 cond_optional, se.expr,
889 fold_convert (TREE_TYPE (se.expr),
890 integer_zero_node));
891 else
892 tmp = se.expr;
893 gfc_free_expr (len);
894 }
895 else
896 tmp = integer_zero_node;
897 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree),
898 tmp));
899 }
900 /* Pass the address of the class object. */
901 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
902
903 if (optional && optional_alloc_ptr)
904 parmse->expr = build3_loc (input_location, COND_EXPR,
905 TREE_TYPE (parmse->expr),
906 cond_optional, parmse->expr,
907 fold_convert (TREE_TYPE (parmse->expr),
908 null_pointer_node));
909 }
910
911
912 /* Create a new class container, which is required as scalar coarrays
913 have an array descriptor while normal scalars haven't. Optionally,
914 NULL pointer checks are added if the argument is OPTIONAL. */
915
916 static void
class_scalar_coarray_to_class(gfc_se * parmse,gfc_expr * e,gfc_typespec class_ts,bool optional)917 class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
918 gfc_typespec class_ts, bool optional)
919 {
920 tree var, ctree, tmp;
921 stmtblock_t block;
922 gfc_ref *ref;
923 gfc_ref *class_ref;
924
925 gfc_init_block (&block);
926
927 class_ref = NULL;
928 for (ref = e->ref; ref; ref = ref->next)
929 {
930 if (ref->type == REF_COMPONENT
931 && ref->u.c.component->ts.type == BT_CLASS)
932 class_ref = ref;
933 }
934
935 if (class_ref == NULL
936 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
937 tmp = e->symtree->n.sym->backend_decl;
938 else
939 {
940 /* Remove everything after the last class reference, convert the
941 expression and then recover its tailend once more. */
942 gfc_se tmpse;
943 ref = class_ref->next;
944 class_ref->next = NULL;
945 gfc_init_se (&tmpse, NULL);
946 gfc_conv_expr (&tmpse, e);
947 class_ref->next = ref;
948 tmp = tmpse.expr;
949 }
950
951 var = gfc_typenode_for_spec (&class_ts);
952 var = gfc_create_var (var, "class");
953
954 ctree = gfc_class_vptr_get (var);
955 gfc_add_modify (&block, ctree,
956 fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
957
958 ctree = gfc_class_data_get (var);
959 tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
960 gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
961
962 /* Pass the address of the class object. */
963 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
964
965 if (optional)
966 {
967 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
968 tree tmp2;
969
970 tmp = gfc_finish_block (&block);
971
972 gfc_init_block (&block);
973 tmp2 = gfc_class_data_get (var);
974 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
975 null_pointer_node));
976 tmp2 = gfc_finish_block (&block);
977
978 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
979 cond, tmp, tmp2);
980 gfc_add_expr_to_block (&parmse->pre, tmp);
981 }
982 else
983 gfc_add_block_to_block (&parmse->pre, &block);
984 }
985
986
987 /* Takes an intrinsic type expression and returns the address of a temporary
988 class object of the 'declared' type. */
989 void
gfc_conv_intrinsic_to_class(gfc_se * parmse,gfc_expr * e,gfc_typespec class_ts)990 gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
991 gfc_typespec class_ts)
992 {
993 gfc_symbol *vtab;
994 gfc_ss *ss;
995 tree ctree;
996 tree var;
997 tree tmp;
998 int dim;
999
1000 /* The intrinsic type needs to be converted to a temporary
1001 CLASS object. */
1002 tmp = gfc_typenode_for_spec (&class_ts);
1003 var = gfc_create_var (tmp, "class");
1004
1005 /* Set the vptr. */
1006 ctree = gfc_class_vptr_get (var);
1007
1008 vtab = gfc_find_vtab (&e->ts);
1009 gcc_assert (vtab);
1010 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
1011 gfc_add_modify (&parmse->pre, ctree,
1012 fold_convert (TREE_TYPE (ctree), tmp));
1013
1014 /* Now set the data field. */
1015 ctree = gfc_class_data_get (var);
1016 if (parmse->ss && parmse->ss->info->useflags)
1017 {
1018 /* For an array reference in an elemental procedure call we need
1019 to retain the ss to provide the scalarized array reference. */
1020 gfc_conv_expr_reference (parmse, e);
1021 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
1022 gfc_add_modify (&parmse->pre, ctree, tmp);
1023 }
1024 else
1025 {
1026 ss = gfc_walk_expr (e);
1027 if (ss == gfc_ss_terminator)
1028 {
1029 parmse->ss = NULL;
1030 gfc_conv_expr_reference (parmse, e);
1031 if (class_ts.u.derived->components->as
1032 && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
1033 {
1034 tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
1035 gfc_expr_attr (e));
1036 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1037 TREE_TYPE (ctree), tmp);
1038 }
1039 else
1040 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
1041 gfc_add_modify (&parmse->pre, ctree, tmp);
1042 }
1043 else
1044 {
1045 parmse->ss = ss;
1046 parmse->use_offset = 1;
1047 gfc_conv_expr_descriptor (parmse, e);
1048
1049 /* Array references with vector subscripts and non-variable expressions
1050 need be converted to a one-based descriptor. */
1051 if (e->expr_type != EXPR_VARIABLE)
1052 {
1053 for (dim = 0; dim < e->rank; ++dim)
1054 gfc_conv_shift_descriptor_lbound (&parmse->pre, parmse->expr,
1055 dim, gfc_index_one_node);
1056 }
1057
1058 if (class_ts.u.derived->components->as->rank != e->rank)
1059 {
1060 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1061 TREE_TYPE (ctree), parmse->expr);
1062 gfc_add_modify (&parmse->pre, ctree, tmp);
1063 }
1064 else
1065 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
1066 }
1067 }
1068
1069 gcc_assert (class_ts.type == BT_CLASS);
1070 if (class_ts.u.derived->components->ts.type == BT_DERIVED
1071 && class_ts.u.derived->components->ts.u.derived
1072 ->attr.unlimited_polymorphic)
1073 {
1074 ctree = gfc_class_len_get (var);
1075 /* When the actual arg is a char array, then set the _len component of the
1076 unlimited polymorphic entity to the length of the string. */
1077 if (e->ts.type == BT_CHARACTER)
1078 {
1079 /* Start with parmse->string_length because this seems to be set to a
1080 correct value more often. */
1081 if (parmse->string_length)
1082 tmp = parmse->string_length;
1083 /* When the string_length is not yet set, then try the backend_decl of
1084 the cl. */
1085 else if (e->ts.u.cl->backend_decl)
1086 tmp = e->ts.u.cl->backend_decl;
1087 /* If both of the above approaches fail, then try to generate an
1088 expression from the input, which is only feasible currently, when the
1089 expression can be evaluated to a constant one. */
1090 else
1091 {
1092 /* Try to simplify the expression. */
1093 gfc_simplify_expr (e, 0);
1094 if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved)
1095 {
1096 /* Amazingly all data is present to compute the length of a
1097 constant string, but the expression is not yet there. */
1098 e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER,
1099 gfc_charlen_int_kind,
1100 &e->where);
1101 mpz_set_ui (e->ts.u.cl->length->value.integer,
1102 e->value.character.length);
1103 gfc_conv_const_charlen (e->ts.u.cl);
1104 e->ts.u.cl->resolved = 1;
1105 tmp = e->ts.u.cl->backend_decl;
1106 }
1107 else
1108 {
1109 gfc_error ("Cannot compute the length of the char array "
1110 "at %L.", &e->where);
1111 }
1112 }
1113 }
1114 else
1115 tmp = integer_zero_node;
1116
1117 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp));
1118 }
1119 else if (class_ts.type == BT_CLASS
1120 && class_ts.u.derived->components
1121 && class_ts.u.derived->components->ts.u
1122 .derived->attr.unlimited_polymorphic)
1123 {
1124 ctree = gfc_class_len_get (var);
1125 gfc_add_modify (&parmse->pre, ctree,
1126 fold_convert (TREE_TYPE (ctree),
1127 integer_zero_node));
1128 }
1129 /* Pass the address of the class object. */
1130 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1131 }
1132
1133
1134 /* Takes a scalarized class array expression and returns the
1135 address of a temporary scalar class object of the 'declared'
1136 type.
1137 OOP-TODO: This could be improved by adding code that branched on
1138 the dynamic type being the same as the declared type. In this case
1139 the original class expression can be passed directly.
1140 optional_alloc_ptr is false when the dummy is neither allocatable
1141 nor a pointer; that's relevant for the optional handling.
1142 Set copyback to true if class container's _data and _vtab pointers
1143 might get modified. */
1144
1145 void
gfc_conv_class_to_class(gfc_se * parmse,gfc_expr * e,gfc_typespec class_ts,bool elemental,bool copyback,bool optional,bool optional_alloc_ptr)1146 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
1147 bool elemental, bool copyback, bool optional,
1148 bool optional_alloc_ptr)
1149 {
1150 tree ctree;
1151 tree var;
1152 tree tmp;
1153 tree vptr;
1154 tree cond = NULL_TREE;
1155 tree slen = NULL_TREE;
1156 gfc_ref *ref;
1157 gfc_ref *class_ref;
1158 stmtblock_t block;
1159 bool full_array = false;
1160
1161 gfc_init_block (&block);
1162
1163 class_ref = NULL;
1164 for (ref = e->ref; ref; ref = ref->next)
1165 {
1166 if (ref->type == REF_COMPONENT
1167 && ref->u.c.component->ts.type == BT_CLASS)
1168 class_ref = ref;
1169
1170 if (ref->next == NULL)
1171 break;
1172 }
1173
1174 if ((ref == NULL || class_ref == ref)
1175 && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE)
1176 && (!class_ts.u.derived->components->as
1177 || class_ts.u.derived->components->as->rank != -1))
1178 return;
1179
1180 /* Test for FULL_ARRAY. */
1181 if (e->rank == 0
1182 && ((gfc_expr_attr (e).codimension && gfc_expr_attr (e).dimension)
1183 || (class_ts.u.derived->components->as
1184 && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)))
1185 full_array = true;
1186 else
1187 gfc_is_class_array_ref (e, &full_array);
1188
1189 /* The derived type needs to be converted to a temporary
1190 CLASS object. */
1191 tmp = gfc_typenode_for_spec (&class_ts);
1192 var = gfc_create_var (tmp, "class");
1193
1194 /* Set the data. */
1195 ctree = gfc_class_data_get (var);
1196 if (class_ts.u.derived->components->as
1197 && e->rank != class_ts.u.derived->components->as->rank)
1198 {
1199 if (e->rank == 0)
1200 {
1201 tree type = get_scalar_to_descriptor_type (parmse->expr,
1202 gfc_expr_attr (e));
1203 gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
1204 gfc_get_dtype (type));
1205
1206 tmp = gfc_class_data_get (parmse->expr);
1207 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1208 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1209
1210 gfc_conv_descriptor_data_set (&block, ctree, tmp);
1211 }
1212 else
1213 class_array_data_assign (&block, ctree, parmse->expr, false);
1214 }
1215 else
1216 {
1217 if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
1218 parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1219 TREE_TYPE (ctree), parmse->expr);
1220 gfc_add_modify (&block, ctree, parmse->expr);
1221 }
1222
1223 /* Return the data component, except in the case of scalarized array
1224 references, where nullification of the cannot occur and so there
1225 is no need. */
1226 if (!elemental && full_array && copyback)
1227 {
1228 if (class_ts.u.derived->components->as
1229 && e->rank != class_ts.u.derived->components->as->rank)
1230 {
1231 if (e->rank == 0)
1232 {
1233 tmp = gfc_class_data_get (parmse->expr);
1234 gfc_add_modify (&parmse->post, tmp,
1235 fold_convert (TREE_TYPE (tmp),
1236 gfc_conv_descriptor_data_get (ctree)));
1237 }
1238 else
1239 class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
1240 }
1241 else
1242 gfc_add_modify (&parmse->post, parmse->expr, ctree);
1243 }
1244
1245 /* Set the vptr. */
1246 ctree = gfc_class_vptr_get (var);
1247
1248 /* The vptr is the second field of the actual argument.
1249 First we have to find the corresponding class reference. */
1250
1251 tmp = NULL_TREE;
1252 if (gfc_is_class_array_function (e)
1253 && parmse->class_vptr != NULL_TREE)
1254 tmp = parmse->class_vptr;
1255 else if (class_ref == NULL
1256 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
1257 {
1258 tmp = e->symtree->n.sym->backend_decl;
1259
1260 if (TREE_CODE (tmp) == FUNCTION_DECL)
1261 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
1262
1263 if (DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp))
1264 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);
1265
1266 slen = build_zero_cst (size_type_node);
1267 }
1268 else
1269 {
1270 /* Remove everything after the last class reference, convert the
1271 expression and then recover its tailend once more. */
1272 gfc_se tmpse;
1273 ref = class_ref->next;
1274 class_ref->next = NULL;
1275 gfc_init_se (&tmpse, NULL);
1276 gfc_conv_expr (&tmpse, e);
1277 class_ref->next = ref;
1278 tmp = tmpse.expr;
1279 slen = tmpse.string_length;
1280 }
1281
1282 gcc_assert (tmp != NULL_TREE);
1283
1284 /* Dereference if needs be. */
1285 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
1286 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1287
1288 if (!(gfc_is_class_array_function (e) && parmse->class_vptr))
1289 vptr = gfc_class_vptr_get (tmp);
1290 else
1291 vptr = tmp;
1292
1293 gfc_add_modify (&block, ctree,
1294 fold_convert (TREE_TYPE (ctree), vptr));
1295
1296 /* Return the vptr component, except in the case of scalarized array
1297 references, where the dynamic type cannot change. */
1298 if (!elemental && full_array && copyback)
1299 gfc_add_modify (&parmse->post, vptr,
1300 fold_convert (TREE_TYPE (vptr), ctree));
1301
1302 /* For unlimited polymorphic objects also set the _len component. */
1303 if (class_ts.type == BT_CLASS
1304 && class_ts.u.derived->components
1305 && class_ts.u.derived->components->ts.u
1306 .derived->attr.unlimited_polymorphic)
1307 {
1308 ctree = gfc_class_len_get (var);
1309 if (UNLIMITED_POLY (e))
1310 tmp = gfc_class_len_get (tmp);
1311 else if (e->ts.type == BT_CHARACTER)
1312 {
1313 gcc_assert (slen != NULL_TREE);
1314 tmp = slen;
1315 }
1316 else
1317 tmp = build_zero_cst (size_type_node);
1318 gfc_add_modify (&parmse->pre, ctree,
1319 fold_convert (TREE_TYPE (ctree), tmp));
1320
1321 /* Return the len component, except in the case of scalarized array
1322 references, where the dynamic type cannot change. */
1323 if (!elemental && full_array && copyback
1324 && (UNLIMITED_POLY (e) || VAR_P (tmp)))
1325 gfc_add_modify (&parmse->post, tmp,
1326 fold_convert (TREE_TYPE (tmp), ctree));
1327 }
1328
1329 if (optional)
1330 {
1331 tree tmp2;
1332
1333 cond = gfc_conv_expr_present (e->symtree->n.sym);
1334 /* parmse->pre may contain some preparatory instructions for the
1335 temporary array descriptor. Those may only be executed when the
1336 optional argument is set, therefore add parmse->pre's instructions
1337 to block, which is later guarded by an if (optional_arg_given). */
1338 gfc_add_block_to_block (&parmse->pre, &block);
1339 block.head = parmse->pre.head;
1340 parmse->pre.head = NULL_TREE;
1341 tmp = gfc_finish_block (&block);
1342
1343 if (optional_alloc_ptr)
1344 tmp2 = build_empty_stmt (input_location);
1345 else
1346 {
1347 gfc_init_block (&block);
1348
1349 tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
1350 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
1351 null_pointer_node));
1352 tmp2 = gfc_finish_block (&block);
1353 }
1354
1355 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
1356 cond, tmp, tmp2);
1357 gfc_add_expr_to_block (&parmse->pre, tmp);
1358 }
1359 else
1360 gfc_add_block_to_block (&parmse->pre, &block);
1361
1362 /* Pass the address of the class object. */
1363 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1364
1365 if (optional && optional_alloc_ptr)
1366 parmse->expr = build3_loc (input_location, COND_EXPR,
1367 TREE_TYPE (parmse->expr),
1368 cond, parmse->expr,
1369 fold_convert (TREE_TYPE (parmse->expr),
1370 null_pointer_node));
1371 }
1372
1373
1374 /* Given a class array declaration and an index, returns the address
1375 of the referenced element. */
1376
1377 static tree
gfc_get_class_array_ref(tree index,tree class_decl,tree data_comp,bool unlimited)1378 gfc_get_class_array_ref (tree index, tree class_decl, tree data_comp,
1379 bool unlimited)
1380 {
1381 tree data, size, tmp, ctmp, offset, ptr;
1382
1383 data = data_comp != NULL_TREE ? data_comp :
1384 gfc_class_data_get (class_decl);
1385 size = gfc_class_vtab_size_get (class_decl);
1386
1387 if (unlimited)
1388 {
1389 tmp = fold_convert (gfc_array_index_type,
1390 gfc_class_len_get (class_decl));
1391 ctmp = fold_build2_loc (input_location, MULT_EXPR,
1392 gfc_array_index_type, size, tmp);
1393 tmp = fold_build2_loc (input_location, GT_EXPR,
1394 logical_type_node, tmp,
1395 build_zero_cst (TREE_TYPE (tmp)));
1396 size = fold_build3_loc (input_location, COND_EXPR,
1397 gfc_array_index_type, tmp, ctmp, size);
1398 }
1399
1400 offset = fold_build2_loc (input_location, MULT_EXPR,
1401 gfc_array_index_type,
1402 index, size);
1403
1404 data = gfc_conv_descriptor_data_get (data);
1405 ptr = fold_convert (pvoid_type_node, data);
1406 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
1407 return fold_convert (TREE_TYPE (data), ptr);
1408 }
1409
1410
1411 /* Copies one class expression to another, assuming that if either
1412 'to' or 'from' are arrays they are packed. Should 'from' be
1413 NULL_TREE, the initialization expression for 'to' is used, assuming
1414 that the _vptr is set. */
1415
1416 tree
gfc_copy_class_to_class(tree from,tree to,tree nelems,bool unlimited)1417 gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
1418 {
1419 tree fcn;
1420 tree fcn_type;
1421 tree from_data;
1422 tree from_len;
1423 tree to_data;
1424 tree to_len;
1425 tree to_ref;
1426 tree from_ref;
1427 vec<tree, va_gc> *args;
1428 tree tmp;
1429 tree stdcopy;
1430 tree extcopy;
1431 tree index;
1432 bool is_from_desc = false, is_to_class = false;
1433
1434 args = NULL;
1435 /* To prevent warnings on uninitialized variables. */
1436 from_len = to_len = NULL_TREE;
1437
1438 if (from != NULL_TREE)
1439 fcn = gfc_class_vtab_copy_get (from);
1440 else
1441 fcn = gfc_class_vtab_copy_get (to);
1442
1443 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
1444
1445 if (from != NULL_TREE)
1446 {
1447 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from));
1448 if (is_from_desc)
1449 {
1450 from_data = from;
1451 from = GFC_DECL_SAVED_DESCRIPTOR (from);
1452 }
1453 else
1454 {
1455 /* Check that from is a class. When the class is part of a coarray,
1456 then from is a common pointer and is to be used as is. */
1457 tmp = POINTER_TYPE_P (TREE_TYPE (from))
1458 ? build_fold_indirect_ref (from) : from;
1459 from_data =
1460 (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
1461 || (DECL_P (tmp) && GFC_DECL_CLASS (tmp)))
1462 ? gfc_class_data_get (from) : from;
1463 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data));
1464 }
1465 }
1466 else
1467 from_data = gfc_class_vtab_def_init_get (to);
1468
1469 if (unlimited)
1470 {
1471 if (from != NULL_TREE && unlimited)
1472 from_len = gfc_class_len_or_zero_get (from);
1473 else
1474 from_len = build_zero_cst (size_type_node);
1475 }
1476
1477 if (GFC_CLASS_TYPE_P (TREE_TYPE (to)))
1478 {
1479 is_to_class = true;
1480 to_data = gfc_class_data_get (to);
1481 if (unlimited)
1482 to_len = gfc_class_len_get (to);
1483 }
1484 else
1485 /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to. */
1486 to_data = to;
1487
1488 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
1489 {
1490 stmtblock_t loopbody;
1491 stmtblock_t body;
1492 stmtblock_t ifbody;
1493 gfc_loopinfo loop;
1494 tree orig_nelems = nelems; /* Needed for bounds check. */
1495
1496 gfc_init_block (&body);
1497 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1498 gfc_array_index_type, nelems,
1499 gfc_index_one_node);
1500 nelems = gfc_evaluate_now (tmp, &body);
1501 index = gfc_create_var (gfc_array_index_type, "S");
1502
1503 if (is_from_desc)
1504 {
1505 from_ref = gfc_get_class_array_ref (index, from, from_data,
1506 unlimited);
1507 vec_safe_push (args, from_ref);
1508 }
1509 else
1510 vec_safe_push (args, from_data);
1511
1512 if (is_to_class)
1513 to_ref = gfc_get_class_array_ref (index, to, to_data, unlimited);
1514 else
1515 {
1516 tmp = gfc_conv_array_data (to);
1517 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1518 to_ref = gfc_build_addr_expr (NULL_TREE,
1519 gfc_build_array_ref (tmp, index, to));
1520 }
1521 vec_safe_push (args, to_ref);
1522
1523 /* Add bounds check. */
1524 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc)
1525 {
1526 char *msg;
1527 const char *name = "<<unknown>>";
1528 tree from_len;
1529
1530 if (DECL_P (to))
1531 name = (const char *)(DECL_NAME (to)->identifier.id.str);
1532
1533 from_len = gfc_conv_descriptor_size (from_data, 1);
1534 from_len = fold_convert (TREE_TYPE (orig_nelems), from_len);
1535 tmp = fold_build2_loc (input_location, NE_EXPR,
1536 logical_type_node, from_len, orig_nelems);
1537 msg = xasprintf ("Array bound mismatch for dimension %d "
1538 "of array '%s' (%%ld/%%ld)",
1539 1, name);
1540
1541 gfc_trans_runtime_check (true, false, tmp, &body,
1542 &gfc_current_locus, msg,
1543 fold_convert (long_integer_type_node, orig_nelems),
1544 fold_convert (long_integer_type_node, from_len));
1545
1546 free (msg);
1547 }
1548
1549 tmp = build_call_vec (fcn_type, fcn, args);
1550
1551 /* Build the body of the loop. */
1552 gfc_init_block (&loopbody);
1553 gfc_add_expr_to_block (&loopbody, tmp);
1554
1555 /* Build the loop and return. */
1556 gfc_init_loopinfo (&loop);
1557 loop.dimen = 1;
1558 loop.from[0] = gfc_index_zero_node;
1559 loop.loopvar[0] = index;
1560 loop.to[0] = nelems;
1561 gfc_trans_scalarizing_loops (&loop, &loopbody);
1562 gfc_init_block (&ifbody);
1563 gfc_add_block_to_block (&ifbody, &loop.pre);
1564 stdcopy = gfc_finish_block (&ifbody);
1565 /* In initialization mode from_len is a constant zero. */
1566 if (unlimited && !integer_zerop (from_len))
1567 {
1568 vec_safe_push (args, from_len);
1569 vec_safe_push (args, to_len);
1570 tmp = build_call_vec (fcn_type, fcn, args);
1571 /* Build the body of the loop. */
1572 gfc_init_block (&loopbody);
1573 gfc_add_expr_to_block (&loopbody, tmp);
1574
1575 /* Build the loop and return. */
1576 gfc_init_loopinfo (&loop);
1577 loop.dimen = 1;
1578 loop.from[0] = gfc_index_zero_node;
1579 loop.loopvar[0] = index;
1580 loop.to[0] = nelems;
1581 gfc_trans_scalarizing_loops (&loop, &loopbody);
1582 gfc_init_block (&ifbody);
1583 gfc_add_block_to_block (&ifbody, &loop.pre);
1584 extcopy = gfc_finish_block (&ifbody);
1585
1586 tmp = fold_build2_loc (input_location, GT_EXPR,
1587 logical_type_node, from_len,
1588 build_zero_cst (TREE_TYPE (from_len)));
1589 tmp = fold_build3_loc (input_location, COND_EXPR,
1590 void_type_node, tmp, extcopy, stdcopy);
1591 gfc_add_expr_to_block (&body, tmp);
1592 tmp = gfc_finish_block (&body);
1593 }
1594 else
1595 {
1596 gfc_add_expr_to_block (&body, stdcopy);
1597 tmp = gfc_finish_block (&body);
1598 }
1599 gfc_cleanup_loop (&loop);
1600 }
1601 else
1602 {
1603 gcc_assert (!is_from_desc);
1604 vec_safe_push (args, from_data);
1605 vec_safe_push (args, to_data);
1606 stdcopy = build_call_vec (fcn_type, fcn, args);
1607
1608 /* In initialization mode from_len is a constant zero. */
1609 if (unlimited && !integer_zerop (from_len))
1610 {
1611 vec_safe_push (args, from_len);
1612 vec_safe_push (args, to_len);
1613 extcopy = build_call_vec (fcn_type, unshare_expr (fcn), args);
1614 tmp = fold_build2_loc (input_location, GT_EXPR,
1615 logical_type_node, from_len,
1616 build_zero_cst (TREE_TYPE (from_len)));
1617 tmp = fold_build3_loc (input_location, COND_EXPR,
1618 void_type_node, tmp, extcopy, stdcopy);
1619 }
1620 else
1621 tmp = stdcopy;
1622 }
1623
1624 /* Only copy _def_init to to_data, when it is not a NULL-pointer. */
1625 if (from == NULL_TREE)
1626 {
1627 tree cond;
1628 cond = fold_build2_loc (input_location, NE_EXPR,
1629 logical_type_node,
1630 from_data, null_pointer_node);
1631 tmp = fold_build3_loc (input_location, COND_EXPR,
1632 void_type_node, cond,
1633 tmp, build_empty_stmt (input_location));
1634 }
1635
1636 return tmp;
1637 }
1638
1639
1640 static tree
gfc_trans_class_array_init_assign(gfc_expr * rhs,gfc_expr * lhs,gfc_expr * obj)1641 gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
1642 {
1643 gfc_actual_arglist *actual;
1644 gfc_expr *ppc;
1645 gfc_code *ppc_code;
1646 tree res;
1647
1648 actual = gfc_get_actual_arglist ();
1649 actual->expr = gfc_copy_expr (rhs);
1650 actual->next = gfc_get_actual_arglist ();
1651 actual->next->expr = gfc_copy_expr (lhs);
1652 ppc = gfc_copy_expr (obj);
1653 gfc_add_vptr_component (ppc);
1654 gfc_add_component_ref (ppc, "_copy");
1655 ppc_code = gfc_get_code (EXEC_CALL);
1656 ppc_code->resolved_sym = ppc->symtree->n.sym;
1657 /* Although '_copy' is set to be elemental in class.cc, it is
1658 not staying that way. Find out why, sometime.... */
1659 ppc_code->resolved_sym->attr.elemental = 1;
1660 ppc_code->ext.actual = actual;
1661 ppc_code->expr1 = ppc;
1662 /* Since '_copy' is elemental, the scalarizer will take care
1663 of arrays in gfc_trans_call. */
1664 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
1665 gfc_free_statements (ppc_code);
1666
1667 if (UNLIMITED_POLY(obj))
1668 {
1669 /* Check if rhs is non-NULL. */
1670 gfc_se src;
1671 gfc_init_se (&src, NULL);
1672 gfc_conv_expr (&src, rhs);
1673 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1674 tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1675 src.expr, fold_convert (TREE_TYPE (src.expr),
1676 null_pointer_node));
1677 res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
1678 build_empty_stmt (input_location));
1679 }
1680
1681 return res;
1682 }
1683
1684 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
1685 A MEMCPY is needed to copy the full data from the default initializer
1686 of the dynamic type. */
1687
1688 tree
gfc_trans_class_init_assign(gfc_code * code)1689 gfc_trans_class_init_assign (gfc_code *code)
1690 {
1691 stmtblock_t block;
1692 tree tmp;
1693 gfc_se dst,src,memsz;
1694 gfc_expr *lhs, *rhs, *sz;
1695
1696 gfc_start_block (&block);
1697
1698 lhs = gfc_copy_expr (code->expr1);
1699
1700 rhs = gfc_copy_expr (code->expr1);
1701 gfc_add_vptr_component (rhs);
1702
1703 /* Make sure that the component backend_decls have been built, which
1704 will not have happened if the derived types concerned have not
1705 been referenced. */
1706 gfc_get_derived_type (rhs->ts.u.derived);
1707 gfc_add_def_init_component (rhs);
1708 /* The _def_init is always scalar. */
1709 rhs->rank = 0;
1710
1711 if (code->expr1->ts.type == BT_CLASS
1712 && CLASS_DATA (code->expr1)->attr.dimension)
1713 {
1714 gfc_array_spec *tmparr = gfc_get_array_spec ();
1715 *tmparr = *CLASS_DATA (code->expr1)->as;
1716 /* Adding the array ref to the class expression results in correct
1717 indexing to the dynamic type. */
1718 gfc_add_full_array_ref (lhs, tmparr);
1719 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
1720 }
1721 else
1722 {
1723 /* Scalar initialization needs the _data component. */
1724 gfc_add_data_component (lhs);
1725 sz = gfc_copy_expr (code->expr1);
1726 gfc_add_vptr_component (sz);
1727 gfc_add_size_component (sz);
1728
1729 gfc_init_se (&dst, NULL);
1730 gfc_init_se (&src, NULL);
1731 gfc_init_se (&memsz, NULL);
1732 gfc_conv_expr (&dst, lhs);
1733 gfc_conv_expr (&src, rhs);
1734 gfc_conv_expr (&memsz, sz);
1735 gfc_add_block_to_block (&block, &src.pre);
1736 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1737
1738 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
1739
1740 if (UNLIMITED_POLY(code->expr1))
1741 {
1742 /* Check if _def_init is non-NULL. */
1743 tree cond = fold_build2_loc (input_location, NE_EXPR,
1744 logical_type_node, src.expr,
1745 fold_convert (TREE_TYPE (src.expr),
1746 null_pointer_node));
1747 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
1748 tmp, build_empty_stmt (input_location));
1749 }
1750 }
1751
1752 if (code->expr1->symtree->n.sym->attr.dummy
1753 && (code->expr1->symtree->n.sym->attr.optional
1754 || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master))
1755 {
1756 tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
1757 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
1758 present, tmp,
1759 build_empty_stmt (input_location));
1760 }
1761
1762 gfc_add_expr_to_block (&block, tmp);
1763
1764 return gfc_finish_block (&block);
1765 }
1766
1767
1768 /* Class valued elemental function calls or class array elements arriving
1769 in gfc_trans_scalar_assign come here. Wherever possible the vptr copy
1770 is used to ensure that the rhs dynamic type is assigned to the lhs. */
1771
1772 static bool
trans_scalar_class_assign(stmtblock_t * block,gfc_se * lse,gfc_se * rse)1773 trans_scalar_class_assign (stmtblock_t *block, gfc_se *lse, gfc_se *rse)
1774 {
1775 tree fcn;
1776 tree rse_expr;
1777 tree class_data;
1778 tree tmp;
1779 tree zero;
1780 tree cond;
1781 tree final_cond;
1782 stmtblock_t inner_block;
1783 bool is_descriptor;
1784 bool not_call_expr = TREE_CODE (rse->expr) != CALL_EXPR;
1785 bool not_lhs_array_type;
1786
1787 /* Temporaries arising from dependencies in assignment get cast as a
1788 character type of the dynamic size of the rhs. Use the vptr copy
1789 for this case. */
1790 tmp = TREE_TYPE (lse->expr);
1791 not_lhs_array_type = !(tmp && TREE_CODE (tmp) == ARRAY_TYPE
1792 && TYPE_MAX_VALUE (TYPE_DOMAIN (tmp)) != NULL_TREE);
1793
1794 /* Use ordinary assignment if the rhs is not a call expression or
1795 the lhs is not a class entity or an array(ie. character) type. */
1796 if ((not_call_expr && gfc_get_class_from_expr (lse->expr) == NULL_TREE)
1797 && not_lhs_array_type)
1798 return false;
1799
1800 /* Ordinary assignment can be used if both sides are class expressions
1801 since the dynamic type is preserved by copying the vptr. This
1802 should only occur, where temporaries are involved. */
1803 if (GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
1804 && GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
1805 return false;
1806
1807 /* Fix the class expression and the class data of the rhs. */
1808 if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
1809 || not_call_expr)
1810 {
1811 tmp = gfc_get_class_from_expr (rse->expr);
1812 if (tmp == NULL_TREE)
1813 return false;
1814 rse_expr = gfc_evaluate_now (tmp, block);
1815 }
1816 else
1817 rse_expr = gfc_evaluate_now (rse->expr, block);
1818
1819 class_data = gfc_class_data_get (rse_expr);
1820
1821 /* Check that the rhs data is not null. */
1822 is_descriptor = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (class_data));
1823 if (is_descriptor)
1824 class_data = gfc_conv_descriptor_data_get (class_data);
1825 class_data = gfc_evaluate_now (class_data, block);
1826
1827 zero = build_int_cst (TREE_TYPE (class_data), 0);
1828 cond = fold_build2_loc (input_location, NE_EXPR,
1829 logical_type_node,
1830 class_data, zero);
1831
1832 /* Copy the rhs to the lhs. */
1833 fcn = gfc_vptr_copy_get (gfc_class_vptr_get (rse_expr));
1834 fcn = build_fold_indirect_ref_loc (input_location, fcn);
1835 tmp = gfc_evaluate_now (gfc_build_addr_expr (NULL, rse->expr), block);
1836 tmp = is_descriptor ? tmp : class_data;
1837 tmp = build_call_expr_loc (input_location, fcn, 2, tmp,
1838 gfc_build_addr_expr (NULL, lse->expr));
1839 gfc_add_expr_to_block (block, tmp);
1840
1841 /* Only elemental function results need to be finalised and freed. */
1842 if (not_call_expr)
1843 return true;
1844
1845 /* Finalize the class data if needed. */
1846 gfc_init_block (&inner_block);
1847 fcn = gfc_vptr_final_get (gfc_class_vptr_get (rse_expr));
1848 zero = build_int_cst (TREE_TYPE (fcn), 0);
1849 final_cond = fold_build2_loc (input_location, NE_EXPR,
1850 logical_type_node, fcn, zero);
1851 fcn = build_fold_indirect_ref_loc (input_location, fcn);
1852 tmp = build_call_expr_loc (input_location, fcn, 1, class_data);
1853 tmp = build3_v (COND_EXPR, final_cond,
1854 tmp, build_empty_stmt (input_location));
1855 gfc_add_expr_to_block (&inner_block, tmp);
1856
1857 /* Free the class data. */
1858 tmp = gfc_call_free (class_data);
1859 tmp = build3_v (COND_EXPR, cond, tmp,
1860 build_empty_stmt (input_location));
1861 gfc_add_expr_to_block (&inner_block, tmp);
1862
1863 /* Finish the inner block and subject it to the condition on the
1864 class data being non-zero. */
1865 tmp = gfc_finish_block (&inner_block);
1866 tmp = build3_v (COND_EXPR, cond, tmp,
1867 build_empty_stmt (input_location));
1868 gfc_add_expr_to_block (block, tmp);
1869
1870 return true;
1871 }
1872
1873 /* End of prototype trans-class.c */
1874
1875
1876 static void
realloc_lhs_warning(bt type,bool array,locus * where)1877 realloc_lhs_warning (bt type, bool array, locus *where)
1878 {
1879 if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs)
1880 gfc_warning (OPT_Wrealloc_lhs,
1881 "Code for reallocating the allocatable array at %L will "
1882 "be added", where);
1883 else if (warn_realloc_lhs_all)
1884 gfc_warning (OPT_Wrealloc_lhs_all,
1885 "Code for reallocating the allocatable variable at %L "
1886 "will be added", where);
1887 }
1888
1889
1890 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
1891 gfc_expr *);
1892
1893 /* Copy the scalarization loop variables. */
1894
1895 static void
gfc_copy_se_loopvars(gfc_se * dest,gfc_se * src)1896 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1897 {
1898 dest->ss = src->ss;
1899 dest->loop = src->loop;
1900 }
1901
1902
1903 /* Initialize a simple expression holder.
1904
1905 Care must be taken when multiple se are created with the same parent.
1906 The child se must be kept in sync. The easiest way is to delay creation
1907 of a child se until after the previous se has been translated. */
1908
1909 void
gfc_init_se(gfc_se * se,gfc_se * parent)1910 gfc_init_se (gfc_se * se, gfc_se * parent)
1911 {
1912 memset (se, 0, sizeof (gfc_se));
1913 gfc_init_block (&se->pre);
1914 gfc_init_block (&se->post);
1915
1916 se->parent = parent;
1917
1918 if (parent)
1919 gfc_copy_se_loopvars (se, parent);
1920 }
1921
1922
1923 /* Advances to the next SS in the chain. Use this rather than setting
1924 se->ss = se->ss->next because all the parents needs to be kept in sync.
1925 See gfc_init_se. */
1926
1927 void
gfc_advance_se_ss_chain(gfc_se * se)1928 gfc_advance_se_ss_chain (gfc_se * se)
1929 {
1930 gfc_se *p;
1931 gfc_ss *ss;
1932
1933 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
1934
1935 p = se;
1936 /* Walk down the parent chain. */
1937 while (p != NULL)
1938 {
1939 /* Simple consistency check. */
1940 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1941 || p->parent->ss->nested_ss == p->ss);
1942
1943 /* If we were in a nested loop, the next scalarized expression can be
1944 on the parent ss' next pointer. Thus we should not take the next
1945 pointer blindly, but rather go up one nest level as long as next
1946 is the end of chain. */
1947 ss = p->ss;
1948 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1949 ss = ss->parent;
1950
1951 p->ss = ss->next;
1952
1953 p = p->parent;
1954 }
1955 }
1956
1957
1958 /* Ensures the result of the expression as either a temporary variable
1959 or a constant so that it can be used repeatedly. */
1960
1961 void
gfc_make_safe_expr(gfc_se * se)1962 gfc_make_safe_expr (gfc_se * se)
1963 {
1964 tree var;
1965
1966 if (CONSTANT_CLASS_P (se->expr))
1967 return;
1968
1969 /* We need a temporary for this result. */
1970 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1971 gfc_add_modify (&se->pre, var, se->expr);
1972 se->expr = var;
1973 }
1974
1975
1976 /* Return an expression which determines if a dummy parameter is present.
1977 Also used for arguments to procedures with multiple entry points. */
1978
1979 tree
gfc_conv_expr_present(gfc_symbol * sym,bool use_saved_desc)1980 gfc_conv_expr_present (gfc_symbol * sym, bool use_saved_desc)
1981 {
1982 tree decl, orig_decl, cond;
1983
1984 gcc_assert (sym->attr.dummy);
1985 orig_decl = decl = gfc_get_symbol_decl (sym);
1986
1987 /* Intrinsic scalars with VALUE attribute which are passed by value
1988 use a hidden argument to denote the present status. */
1989 if (sym->attr.value && sym->ts.type != BT_CHARACTER
1990 && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
1991 && !sym->attr.dimension)
1992 {
1993 char name[GFC_MAX_SYMBOL_LEN + 2];
1994 tree tree_name;
1995
1996 gcc_assert (TREE_CODE (decl) == PARM_DECL);
1997 name[0] = '_';
1998 strcpy (&name[1], sym->name);
1999 tree_name = get_identifier (name);
2000
2001 /* Walk function argument list to find hidden arg. */
2002 cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
2003 for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
2004 if (DECL_NAME (cond) == tree_name
2005 && DECL_ARTIFICIAL (cond))
2006 break;
2007
2008 gcc_assert (cond);
2009 return cond;
2010 }
2011
2012 /* Assumed-shape arrays use a local variable for the array data;
2013 the actual PARAM_DECL is in a saved decl. As the local variable
2014 is NULL, it can be checked instead, unless use_saved_desc is
2015 requested. */
2016
2017 if (use_saved_desc && TREE_CODE (decl) != PARM_DECL)
2018 {
2019 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
2020 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
2021 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
2022 }
2023
2024 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, decl,
2025 fold_convert (TREE_TYPE (decl), null_pointer_node));
2026
2027 /* Fortran 2008 allows to pass null pointers and non-associated pointers
2028 as actual argument to denote absent dummies. For array descriptors,
2029 we thus also need to check the array descriptor. For BT_CLASS, it
2030 can also occur for scalars and F2003 due to type->class wrapping and
2031 class->class wrapping. Note further that BT_CLASS always uses an
2032 array descriptor for arrays, also for explicit-shape/assumed-size.
2033 For assumed-rank arrays, no local variable is generated, hence,
2034 the following also applies with !use_saved_desc. */
2035
2036 if ((use_saved_desc || TREE_CODE (orig_decl) == PARM_DECL)
2037 && !sym->attr.allocatable
2038 && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
2039 || (sym->ts.type == BT_CLASS
2040 && !CLASS_DATA (sym)->attr.allocatable
2041 && !CLASS_DATA (sym)->attr.class_pointer))
2042 && ((gfc_option.allow_std & GFC_STD_F2008) != 0
2043 || sym->ts.type == BT_CLASS))
2044 {
2045 tree tmp;
2046
2047 if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
2048 || sym->as->type == AS_ASSUMED_RANK
2049 || sym->attr.codimension))
2050 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
2051 {
2052 tmp = build_fold_indirect_ref_loc (input_location, decl);
2053 if (sym->ts.type == BT_CLASS)
2054 tmp = gfc_class_data_get (tmp);
2055 tmp = gfc_conv_array_data (tmp);
2056 }
2057 else if (sym->ts.type == BT_CLASS)
2058 tmp = gfc_class_data_get (decl);
2059 else
2060 tmp = NULL_TREE;
2061
2062 if (tmp != NULL_TREE)
2063 {
2064 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
2065 fold_convert (TREE_TYPE (tmp), null_pointer_node));
2066 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2067 logical_type_node, cond, tmp);
2068 }
2069 }
2070
2071 return cond;
2072 }
2073
2074
2075 /* Converts a missing, dummy argument into a null or zero. */
2076
2077 void
gfc_conv_missing_dummy(gfc_se * se,gfc_expr * arg,gfc_typespec ts,int kind)2078 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
2079 {
2080 tree present;
2081 tree tmp;
2082
2083 present = gfc_conv_expr_present (arg->symtree->n.sym);
2084
2085 if (kind > 0)
2086 {
2087 /* Create a temporary and convert it to the correct type. */
2088 tmp = gfc_get_int_type (kind);
2089 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
2090 se->expr));
2091
2092 /* Test for a NULL value. */
2093 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
2094 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
2095 tmp = gfc_evaluate_now (tmp, &se->pre);
2096 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
2097 }
2098 else
2099 {
2100 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
2101 present, se->expr,
2102 build_zero_cst (TREE_TYPE (se->expr)));
2103 tmp = gfc_evaluate_now (tmp, &se->pre);
2104 se->expr = tmp;
2105 }
2106
2107 if (ts.type == BT_CHARACTER)
2108 {
2109 tmp = build_int_cst (gfc_charlen_type_node, 0);
2110 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
2111 present, se->string_length, tmp);
2112 tmp = gfc_evaluate_now (tmp, &se->pre);
2113 se->string_length = tmp;
2114 }
2115 return;
2116 }
2117
2118
2119 /* Get the character length of an expression, looking through gfc_refs
2120 if necessary. */
2121
2122 tree
gfc_get_expr_charlen(gfc_expr * e)2123 gfc_get_expr_charlen (gfc_expr *e)
2124 {
2125 gfc_ref *r;
2126 tree length;
2127 gfc_se se;
2128
2129 gcc_assert (e->expr_type == EXPR_VARIABLE
2130 && e->ts.type == BT_CHARACTER);
2131
2132 length = NULL; /* To silence compiler warning. */
2133
2134 if (is_subref_array (e) && e->ts.u.cl->length)
2135 {
2136 gfc_se tmpse;
2137 gfc_init_se (&tmpse, NULL);
2138 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
2139 e->ts.u.cl->backend_decl = tmpse.expr;
2140 return tmpse.expr;
2141 }
2142
2143 /* First candidate: if the variable is of type CHARACTER, the
2144 expression's length could be the length of the character
2145 variable. */
2146 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
2147 length = e->symtree->n.sym->ts.u.cl->backend_decl;
2148
2149 /* Look through the reference chain for component references. */
2150 for (r = e->ref; r; r = r->next)
2151 {
2152 switch (r->type)
2153 {
2154 case REF_COMPONENT:
2155 if (r->u.c.component->ts.type == BT_CHARACTER)
2156 length = r->u.c.component->ts.u.cl->backend_decl;
2157 break;
2158
2159 case REF_ARRAY:
2160 /* Do nothing. */
2161 break;
2162
2163 case REF_SUBSTRING:
2164 gfc_init_se (&se, NULL);
2165 gfc_conv_expr_type (&se, r->u.ss.start, gfc_charlen_type_node);
2166 length = se.expr;
2167 gfc_conv_expr_type (&se, r->u.ss.end, gfc_charlen_type_node);
2168 length = fold_build2_loc (input_location, MINUS_EXPR,
2169 gfc_charlen_type_node,
2170 se.expr, length);
2171 length = fold_build2_loc (input_location, PLUS_EXPR,
2172 gfc_charlen_type_node, length,
2173 gfc_index_one_node);
2174 break;
2175
2176 default:
2177 gcc_unreachable ();
2178 break;
2179 }
2180 }
2181
2182 gcc_assert (length != NULL);
2183 return length;
2184 }
2185
2186
2187 /* Return for an expression the backend decl of the coarray. */
2188
2189 tree
gfc_get_tree_for_caf_expr(gfc_expr * expr)2190 gfc_get_tree_for_caf_expr (gfc_expr *expr)
2191 {
2192 tree caf_decl;
2193 bool found = false;
2194 gfc_ref *ref;
2195
2196 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
2197
2198 /* Not-implemented diagnostic. */
2199 if (expr->symtree->n.sym->ts.type == BT_CLASS
2200 && UNLIMITED_POLY (expr->symtree->n.sym)
2201 && CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2202 gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at "
2203 "%L is not supported", &expr->where);
2204
2205 for (ref = expr->ref; ref; ref = ref->next)
2206 if (ref->type == REF_COMPONENT)
2207 {
2208 if (ref->u.c.component->ts.type == BT_CLASS
2209 && UNLIMITED_POLY (ref->u.c.component)
2210 && CLASS_DATA (ref->u.c.component)->attr.codimension)
2211 gfc_error ("Sorry, coindexed access to an unlimited polymorphic "
2212 "component at %L is not supported", &expr->where);
2213 }
2214
2215 /* Make sure the backend_decl is present before accessing it. */
2216 caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE
2217 ? gfc_get_symbol_decl (expr->symtree->n.sym)
2218 : expr->symtree->n.sym->backend_decl;
2219
2220 if (expr->symtree->n.sym->ts.type == BT_CLASS)
2221 {
2222 if (expr->ref && expr->ref->type == REF_ARRAY)
2223 {
2224 caf_decl = gfc_class_data_get (caf_decl);
2225 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2226 return caf_decl;
2227 }
2228 for (ref = expr->ref; ref; ref = ref->next)
2229 {
2230 if (ref->type == REF_COMPONENT
2231 && strcmp (ref->u.c.component->name, "_data") != 0)
2232 {
2233 caf_decl = gfc_class_data_get (caf_decl);
2234 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2235 return caf_decl;
2236 break;
2237 }
2238 else if (ref->type == REF_ARRAY && ref->u.ar.dimen)
2239 break;
2240 }
2241 }
2242 if (expr->symtree->n.sym->attr.codimension)
2243 return caf_decl;
2244
2245 /* The following code assumes that the coarray is a component reachable via
2246 only scalar components/variables; the Fortran standard guarantees this. */
2247
2248 for (ref = expr->ref; ref; ref = ref->next)
2249 if (ref->type == REF_COMPONENT)
2250 {
2251 gfc_component *comp = ref->u.c.component;
2252
2253 if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
2254 caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
2255 caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
2256 TREE_TYPE (comp->backend_decl), caf_decl,
2257 comp->backend_decl, NULL_TREE);
2258 if (comp->ts.type == BT_CLASS)
2259 {
2260 caf_decl = gfc_class_data_get (caf_decl);
2261 if (CLASS_DATA (comp)->attr.codimension)
2262 {
2263 found = true;
2264 break;
2265 }
2266 }
2267 if (comp->attr.codimension)
2268 {
2269 found = true;
2270 break;
2271 }
2272 }
2273 gcc_assert (found && caf_decl);
2274 return caf_decl;
2275 }
2276
2277
2278 /* Obtain the Coarray token - and optionally also the offset. */
2279
2280 void
gfc_get_caf_token_offset(gfc_se * se,tree * token,tree * offset,tree caf_decl,tree se_expr,gfc_expr * expr)2281 gfc_get_caf_token_offset (gfc_se *se, tree *token, tree *offset, tree caf_decl,
2282 tree se_expr, gfc_expr *expr)
2283 {
2284 tree tmp;
2285
2286 /* Coarray token. */
2287 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2288 {
2289 gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
2290 == GFC_ARRAY_ALLOCATABLE
2291 || expr->symtree->n.sym->attr.select_type_temporary);
2292 *token = gfc_conv_descriptor_token (caf_decl);
2293 }
2294 else if (DECL_LANG_SPECIFIC (caf_decl)
2295 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
2296 *token = GFC_DECL_TOKEN (caf_decl);
2297 else
2298 {
2299 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
2300 && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
2301 *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
2302 }
2303
2304 if (offset == NULL)
2305 return;
2306
2307 /* Offset between the coarray base address and the address wanted. */
2308 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
2309 && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
2310 || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
2311 *offset = build_int_cst (gfc_array_index_type, 0);
2312 else if (DECL_LANG_SPECIFIC (caf_decl)
2313 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
2314 *offset = GFC_DECL_CAF_OFFSET (caf_decl);
2315 else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
2316 *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
2317 else
2318 *offset = build_int_cst (gfc_array_index_type, 0);
2319
2320 if (POINTER_TYPE_P (TREE_TYPE (se_expr))
2321 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
2322 {
2323 tmp = build_fold_indirect_ref_loc (input_location, se_expr);
2324 tmp = gfc_conv_descriptor_data_get (tmp);
2325 }
2326 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
2327 tmp = gfc_conv_descriptor_data_get (se_expr);
2328 else
2329 {
2330 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
2331 tmp = se_expr;
2332 }
2333
2334 *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2335 *offset, fold_convert (gfc_array_index_type, tmp));
2336
2337 if (expr->symtree->n.sym->ts.type == BT_DERIVED
2338 && expr->symtree->n.sym->attr.codimension
2339 && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
2340 {
2341 gfc_expr *base_expr = gfc_copy_expr (expr);
2342 gfc_ref *ref = base_expr->ref;
2343 gfc_se base_se;
2344
2345 // Iterate through the refs until the last one.
2346 while (ref->next)
2347 ref = ref->next;
2348
2349 if (ref->type == REF_ARRAY
2350 && ref->u.ar.type != AR_FULL)
2351 {
2352 const int ranksum = ref->u.ar.dimen + ref->u.ar.codimen;
2353 int i;
2354 for (i = 0; i < ranksum; ++i)
2355 {
2356 ref->u.ar.start[i] = NULL;
2357 ref->u.ar.end[i] = NULL;
2358 }
2359 ref->u.ar.type = AR_FULL;
2360 }
2361 gfc_init_se (&base_se, NULL);
2362 if (gfc_caf_attr (base_expr).dimension)
2363 {
2364 gfc_conv_expr_descriptor (&base_se, base_expr);
2365 tmp = gfc_conv_descriptor_data_get (base_se.expr);
2366 }
2367 else
2368 {
2369 gfc_conv_expr (&base_se, base_expr);
2370 tmp = base_se.expr;
2371 }
2372
2373 gfc_free_expr (base_expr);
2374 gfc_add_block_to_block (&se->pre, &base_se.pre);
2375 gfc_add_block_to_block (&se->post, &base_se.post);
2376 }
2377 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2378 tmp = gfc_conv_descriptor_data_get (caf_decl);
2379 else
2380 {
2381 gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
2382 tmp = caf_decl;
2383 }
2384
2385 *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
2386 fold_convert (gfc_array_index_type, *offset),
2387 fold_convert (gfc_array_index_type, tmp));
2388 }
2389
2390
2391 /* Convert the coindex of a coarray into an image index; the result is
2392 image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
2393 + (idx(3)-lcobound(3))*extend(1)*extent(2) + ... */
2394
2395 tree
gfc_caf_get_image_index(stmtblock_t * block,gfc_expr * e,tree desc)2396 gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
2397 {
2398 gfc_ref *ref;
2399 tree lbound, ubound, extent, tmp, img_idx;
2400 gfc_se se;
2401 int i;
2402
2403 for (ref = e->ref; ref; ref = ref->next)
2404 if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
2405 break;
2406 gcc_assert (ref != NULL);
2407
2408 if (ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE)
2409 {
2410 return build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
2411 integer_zero_node);
2412 }
2413
2414 img_idx = build_zero_cst (gfc_array_index_type);
2415 extent = build_one_cst (gfc_array_index_type);
2416 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
2417 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2418 {
2419 gfc_init_se (&se, NULL);
2420 gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2421 gfc_add_block_to_block (block, &se.pre);
2422 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
2423 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2424 TREE_TYPE (lbound), se.expr, lbound);
2425 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2426 extent, tmp);
2427 img_idx = fold_build2_loc (input_location, PLUS_EXPR,
2428 TREE_TYPE (tmp), img_idx, tmp);
2429 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2430 {
2431 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
2432 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
2433 extent = fold_build2_loc (input_location, MULT_EXPR,
2434 TREE_TYPE (tmp), extent, tmp);
2435 }
2436 }
2437 else
2438 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2439 {
2440 gfc_init_se (&se, NULL);
2441 gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2442 gfc_add_block_to_block (block, &se.pre);
2443 lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
2444 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2445 TREE_TYPE (lbound), se.expr, lbound);
2446 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2447 extent, tmp);
2448 img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2449 img_idx, tmp);
2450 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2451 {
2452 ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
2453 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2454 TREE_TYPE (ubound), ubound, lbound);
2455 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2456 tmp, build_one_cst (TREE_TYPE (tmp)));
2457 extent = fold_build2_loc (input_location, MULT_EXPR,
2458 TREE_TYPE (tmp), extent, tmp);
2459 }
2460 }
2461 img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (img_idx),
2462 img_idx, build_one_cst (TREE_TYPE (img_idx)));
2463 return fold_convert (integer_type_node, img_idx);
2464 }
2465
2466
2467 /* For each character array constructor subexpression without a ts.u.cl->length,
2468 replace it by its first element (if there aren't any elements, the length
2469 should already be set to zero). */
2470
2471 static void
flatten_array_ctors_without_strlen(gfc_expr * e)2472 flatten_array_ctors_without_strlen (gfc_expr* e)
2473 {
2474 gfc_actual_arglist* arg;
2475 gfc_constructor* c;
2476
2477 if (!e)
2478 return;
2479
2480 switch (e->expr_type)
2481 {
2482
2483 case EXPR_OP:
2484 flatten_array_ctors_without_strlen (e->value.op.op1);
2485 flatten_array_ctors_without_strlen (e->value.op.op2);
2486 break;
2487
2488 case EXPR_COMPCALL:
2489 /* TODO: Implement as with EXPR_FUNCTION when needed. */
2490 gcc_unreachable ();
2491
2492 case EXPR_FUNCTION:
2493 for (arg = e->value.function.actual; arg; arg = arg->next)
2494 flatten_array_ctors_without_strlen (arg->expr);
2495 break;
2496
2497 case EXPR_ARRAY:
2498
2499 /* We've found what we're looking for. */
2500 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
2501 {
2502 gfc_constructor *c;
2503 gfc_expr* new_expr;
2504
2505 gcc_assert (e->value.constructor);
2506
2507 c = gfc_constructor_first (e->value.constructor);
2508 new_expr = c->expr;
2509 c->expr = NULL;
2510
2511 flatten_array_ctors_without_strlen (new_expr);
2512 gfc_replace_expr (e, new_expr);
2513 break;
2514 }
2515
2516 /* Otherwise, fall through to handle constructor elements. */
2517 gcc_fallthrough ();
2518 case EXPR_STRUCTURE:
2519 for (c = gfc_constructor_first (e->value.constructor);
2520 c; c = gfc_constructor_next (c))
2521 flatten_array_ctors_without_strlen (c->expr);
2522 break;
2523
2524 default:
2525 break;
2526
2527 }
2528 }
2529
2530
2531 /* Generate code to initialize a string length variable. Returns the
2532 value. For array constructors, cl->length might be NULL and in this case,
2533 the first element of the constructor is needed. expr is the original
2534 expression so we can access it but can be NULL if this is not needed. */
2535
2536 void
gfc_conv_string_length(gfc_charlen * cl,gfc_expr * expr,stmtblock_t * pblock)2537 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
2538 {
2539 gfc_se se;
2540
2541 gfc_init_se (&se, NULL);
2542
2543 if (!cl->length && cl->backend_decl && VAR_P (cl->backend_decl))
2544 return;
2545
2546 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
2547 "flatten" array constructors by taking their first element; all elements
2548 should be the same length or a cl->length should be present. */
2549 if (!cl->length)
2550 {
2551 gfc_expr* expr_flat;
2552 if (!expr)
2553 return;
2554 expr_flat = gfc_copy_expr (expr);
2555 flatten_array_ctors_without_strlen (expr_flat);
2556 gfc_resolve_expr (expr_flat);
2557
2558 gfc_conv_expr (&se, expr_flat);
2559 gfc_add_block_to_block (pblock, &se.pre);
2560 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
2561
2562 gfc_free_expr (expr_flat);
2563 return;
2564 }
2565
2566 /* Convert cl->length. */
2567
2568 gcc_assert (cl->length);
2569
2570 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
2571 se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2572 se.expr, build_zero_cst (TREE_TYPE (se.expr)));
2573 gfc_add_block_to_block (pblock, &se.pre);
2574
2575 if (cl->backend_decl && VAR_P (cl->backend_decl))
2576 gfc_add_modify (pblock, cl->backend_decl, se.expr);
2577 else
2578 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
2579 }
2580
2581
2582 static void
gfc_conv_substring(gfc_se * se,gfc_ref * ref,int kind,const char * name,locus * where)2583 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
2584 const char *name, locus *where)
2585 {
2586 tree tmp;
2587 tree type;
2588 tree fault;
2589 gfc_se start;
2590 gfc_se end;
2591 char *msg;
2592 mpz_t length;
2593
2594 type = gfc_get_character_type (kind, ref->u.ss.length);
2595 type = build_pointer_type (type);
2596
2597 gfc_init_se (&start, se);
2598 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
2599 gfc_add_block_to_block (&se->pre, &start.pre);
2600
2601 if (integer_onep (start.expr))
2602 gfc_conv_string_parameter (se);
2603 else
2604 {
2605 tmp = start.expr;
2606 STRIP_NOPS (tmp);
2607 /* Avoid multiple evaluation of substring start. */
2608 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2609 start.expr = gfc_evaluate_now (start.expr, &se->pre);
2610
2611 /* Change the start of the string. */
2612 if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
2613 || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
2614 && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
2615 tmp = se->expr;
2616 else
2617 tmp = build_fold_indirect_ref_loc (input_location,
2618 se->expr);
2619 /* For BIND(C), a BT_CHARACTER is not an ARRAY_TYPE. */
2620 if (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2621 {
2622 tmp = gfc_build_array_ref (tmp, start.expr, NULL_TREE, true);
2623 se->expr = gfc_build_addr_expr (type, tmp);
2624 }
2625 }
2626
2627 /* Length = end + 1 - start. */
2628 gfc_init_se (&end, se);
2629 if (ref->u.ss.end == NULL)
2630 end.expr = se->string_length;
2631 else
2632 {
2633 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
2634 gfc_add_block_to_block (&se->pre, &end.pre);
2635 }
2636 tmp = end.expr;
2637 STRIP_NOPS (tmp);
2638 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
2639 end.expr = gfc_evaluate_now (end.expr, &se->pre);
2640
2641 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2642 && (ref->u.ss.start->symtree
2643 && !ref->u.ss.start->symtree->n.sym->attr.implied_index))
2644 {
2645 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
2646 logical_type_node, start.expr,
2647 end.expr);
2648
2649 /* Check lower bound. */
2650 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
2651 start.expr,
2652 build_one_cst (TREE_TYPE (start.expr)));
2653 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2654 logical_type_node, nonempty, fault);
2655 if (name)
2656 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
2657 "is less than one", name);
2658 else
2659 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) "
2660 "is less than one");
2661 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2662 fold_convert (long_integer_type_node,
2663 start.expr));
2664 free (msg);
2665
2666 /* Check upper bound. */
2667 fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
2668 end.expr, se->string_length);
2669 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
2670 logical_type_node, nonempty, fault);
2671 if (name)
2672 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
2673 "exceeds string length (%%ld)", name);
2674 else
2675 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) "
2676 "exceeds string length (%%ld)");
2677 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
2678 fold_convert (long_integer_type_node, end.expr),
2679 fold_convert (long_integer_type_node,
2680 se->string_length));
2681 free (msg);
2682 }
2683
2684 /* Try to calculate the length from the start and end expressions. */
2685 if (ref->u.ss.end
2686 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
2687 {
2688 HOST_WIDE_INT i_len;
2689
2690 i_len = gfc_mpz_get_hwi (length) + 1;
2691 if (i_len < 0)
2692 i_len = 0;
2693
2694 tmp = build_int_cst (gfc_charlen_type_node, i_len);
2695 mpz_clear (length); /* Was initialized by gfc_dep_difference. */
2696 }
2697 else
2698 {
2699 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
2700 fold_convert (gfc_charlen_type_node, end.expr),
2701 fold_convert (gfc_charlen_type_node, start.expr));
2702 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
2703 build_int_cst (gfc_charlen_type_node, 1), tmp);
2704 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2705 tmp, build_int_cst (gfc_charlen_type_node, 0));
2706 }
2707
2708 se->string_length = tmp;
2709 }
2710
2711
2712 /* Convert a derived type component reference. */
2713
2714 void
gfc_conv_component_ref(gfc_se * se,gfc_ref * ref)2715 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
2716 {
2717 gfc_component *c;
2718 tree tmp;
2719 tree decl;
2720 tree field;
2721 tree context;
2722
2723 c = ref->u.c.component;
2724
2725 if (c->backend_decl == NULL_TREE
2726 && ref->u.c.sym != NULL)
2727 gfc_get_derived_type (ref->u.c.sym);
2728
2729 field = c->backend_decl;
2730 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2731 decl = se->expr;
2732 context = DECL_FIELD_CONTEXT (field);
2733
2734 /* Components can correspond to fields of different containing
2735 types, as components are created without context, whereas
2736 a concrete use of a component has the type of decl as context.
2737 So, if the type doesn't match, we search the corresponding
2738 FIELD_DECL in the parent type. To not waste too much time
2739 we cache this result in norestrict_decl.
2740 On the other hand, if the context is a UNION or a MAP (a
2741 RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL. */
2742
2743 if (context != TREE_TYPE (decl)
2744 && !( TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
2745 || TREE_CODE (context) == UNION_TYPE)) /* Field is map */
2746 {
2747 tree f2 = c->norestrict_decl;
2748 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
2749 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
2750 if (TREE_CODE (f2) == FIELD_DECL
2751 && DECL_NAME (f2) == DECL_NAME (field))
2752 break;
2753 gcc_assert (f2);
2754 c->norestrict_decl = f2;
2755 field = f2;
2756 }
2757
2758 if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS
2759 && strcmp ("_data", c->name) == 0)
2760 {
2761 /* Found a ref to the _data component. Store the associated ref to
2762 the vptr in se->class_vptr. */
2763 se->class_vptr = gfc_class_vptr_get (decl);
2764 }
2765 else
2766 se->class_vptr = NULL_TREE;
2767
2768 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
2769 decl, field, NULL_TREE);
2770
2771 se->expr = tmp;
2772
2773 /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
2774 strlen () conditional below. */
2775 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
2776 && !c->ts.deferred
2777 && !c->attr.pdt_string)
2778 {
2779 tmp = c->ts.u.cl->backend_decl;
2780 /* Components must always be constant length. */
2781 gcc_assert (tmp && INTEGER_CST_P (tmp));
2782 se->string_length = tmp;
2783 }
2784
2785 if (gfc_deferred_strlen (c, &field))
2786 {
2787 tmp = fold_build3_loc (input_location, COMPONENT_REF,
2788 TREE_TYPE (field),
2789 decl, field, NULL_TREE);
2790 se->string_length = tmp;
2791 }
2792
2793 if (((c->attr.pointer || c->attr.allocatable)
2794 && (!c->attr.dimension && !c->attr.codimension)
2795 && c->ts.type != BT_CHARACTER)
2796 || c->attr.proc_pointer)
2797 se->expr = build_fold_indirect_ref_loc (input_location,
2798 se->expr);
2799 }
2800
2801
2802 /* This function deals with component references to components of the
2803 parent type for derived type extensions. */
2804 void
conv_parent_component_references(gfc_se * se,gfc_ref * ref)2805 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
2806 {
2807 gfc_component *c;
2808 gfc_component *cmp;
2809 gfc_symbol *dt;
2810 gfc_ref parent;
2811
2812 dt = ref->u.c.sym;
2813 c = ref->u.c.component;
2814
2815 /* Return if the component is in this type, i.e. not in the parent type. */
2816 for (cmp = dt->components; cmp; cmp = cmp->next)
2817 if (c == cmp)
2818 return;
2819
2820 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
2821 parent.type = REF_COMPONENT;
2822 parent.next = NULL;
2823 parent.u.c.sym = dt;
2824 parent.u.c.component = dt->components;
2825
2826 if (dt->backend_decl == NULL)
2827 gfc_get_derived_type (dt);
2828
2829 /* Build the reference and call self. */
2830 gfc_conv_component_ref (se, &parent);
2831 parent.u.c.sym = dt->components->ts.u.derived;
2832 parent.u.c.component = c;
2833 conv_parent_component_references (se, &parent);
2834 }
2835
2836
2837 static void
conv_inquiry(gfc_se * se,gfc_ref * ref,gfc_expr * expr,gfc_typespec * ts)2838 conv_inquiry (gfc_se * se, gfc_ref * ref, gfc_expr *expr, gfc_typespec *ts)
2839 {
2840 tree res = se->expr;
2841
2842 switch (ref->u.i)
2843 {
2844 case INQUIRY_RE:
2845 res = fold_build1_loc (input_location, REALPART_EXPR,
2846 TREE_TYPE (TREE_TYPE (res)), res);
2847 break;
2848
2849 case INQUIRY_IM:
2850 res = fold_build1_loc (input_location, IMAGPART_EXPR,
2851 TREE_TYPE (TREE_TYPE (res)), res);
2852 break;
2853
2854 case INQUIRY_KIND:
2855 res = build_int_cst (gfc_typenode_for_spec (&expr->ts),
2856 ts->kind);
2857 se->string_length = NULL_TREE;
2858 break;
2859
2860 case INQUIRY_LEN:
2861 res = fold_convert (gfc_typenode_for_spec (&expr->ts),
2862 se->string_length);
2863 se->string_length = NULL_TREE;
2864 break;
2865
2866 default:
2867 gcc_unreachable ();
2868 }
2869 se->expr = res;
2870 }
2871
2872 /* Dereference VAR where needed if it is a pointer, reference, etc.
2873 according to Fortran semantics. */
2874
2875 tree
gfc_maybe_dereference_var(gfc_symbol * sym,tree var,bool descriptor_only_p,bool is_classarray)2876 gfc_maybe_dereference_var (gfc_symbol *sym, tree var, bool descriptor_only_p,
2877 bool is_classarray)
2878 {
2879 if (!POINTER_TYPE_P (TREE_TYPE (var)))
2880 return var;
2881 if (is_CFI_desc (sym, NULL))
2882 return build_fold_indirect_ref_loc (input_location, var);
2883
2884 /* Characters are entirely different from other types, they are treated
2885 separately. */
2886 if (sym->ts.type == BT_CHARACTER)
2887 {
2888 /* Dereference character pointer dummy arguments
2889 or results. */
2890 if ((sym->attr.pointer || sym->attr.allocatable
2891 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2892 && (sym->attr.dummy
2893 || sym->attr.function
2894 || sym->attr.result))
2895 var = build_fold_indirect_ref_loc (input_location, var);
2896 }
2897 else if (!sym->attr.value)
2898 {
2899 /* Dereference temporaries for class array dummy arguments. */
2900 if (sym->attr.dummy && is_classarray
2901 && GFC_ARRAY_TYPE_P (TREE_TYPE (var)))
2902 {
2903 if (!descriptor_only_p)
2904 var = GFC_DECL_SAVED_DESCRIPTOR (var);
2905
2906 var = build_fold_indirect_ref_loc (input_location, var);
2907 }
2908
2909 /* Dereference non-character scalar dummy arguments. */
2910 if (sym->attr.dummy && !sym->attr.dimension
2911 && !(sym->attr.codimension && sym->attr.allocatable)
2912 && (sym->ts.type != BT_CLASS
2913 || (!CLASS_DATA (sym)->attr.dimension
2914 && !(CLASS_DATA (sym)->attr.codimension
2915 && CLASS_DATA (sym)->attr.allocatable))))
2916 var = build_fold_indirect_ref_loc (input_location, var);
2917
2918 /* Dereference scalar hidden result. */
2919 if (flag_f2c && sym->ts.type == BT_COMPLEX
2920 && (sym->attr.function || sym->attr.result)
2921 && !sym->attr.dimension && !sym->attr.pointer
2922 && !sym->attr.always_explicit)
2923 var = build_fold_indirect_ref_loc (input_location, var);
2924
2925 /* Dereference non-character, non-class pointer variables.
2926 These must be dummies, results, or scalars. */
2927 if (!is_classarray
2928 && (sym->attr.pointer || sym->attr.allocatable
2929 || gfc_is_associate_pointer (sym)
2930 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2931 && (sym->attr.dummy
2932 || sym->attr.function
2933 || sym->attr.result
2934 || (!sym->attr.dimension
2935 && (!sym->attr.codimension || !sym->attr.allocatable))))
2936 var = build_fold_indirect_ref_loc (input_location, var);
2937 /* Now treat the class array pointer variables accordingly. */
2938 else if (sym->ts.type == BT_CLASS
2939 && sym->attr.dummy
2940 && (CLASS_DATA (sym)->attr.dimension
2941 || CLASS_DATA (sym)->attr.codimension)
2942 && ((CLASS_DATA (sym)->as
2943 && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
2944 || CLASS_DATA (sym)->attr.allocatable
2945 || CLASS_DATA (sym)->attr.class_pointer))
2946 var = build_fold_indirect_ref_loc (input_location, var);
2947 /* And the case where a non-dummy, non-result, non-function,
2948 non-allocable and non-pointer classarray is present. This case was
2949 previously covered by the first if, but with introducing the
2950 condition !is_classarray there, that case has to be covered
2951 explicitly. */
2952 else if (sym->ts.type == BT_CLASS
2953 && !sym->attr.dummy
2954 && !sym->attr.function
2955 && !sym->attr.result
2956 && (CLASS_DATA (sym)->attr.dimension
2957 || CLASS_DATA (sym)->attr.codimension)
2958 && (sym->assoc
2959 || !CLASS_DATA (sym)->attr.allocatable)
2960 && !CLASS_DATA (sym)->attr.class_pointer)
2961 var = build_fold_indirect_ref_loc (input_location, var);
2962 }
2963
2964 return var;
2965 }
2966
2967 /* Return the contents of a variable. Also handles reference/pointer
2968 variables (all Fortran pointer references are implicit). */
2969
2970 static void
gfc_conv_variable(gfc_se * se,gfc_expr * expr)2971 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
2972 {
2973 gfc_ss *ss;
2974 gfc_ref *ref;
2975 gfc_symbol *sym;
2976 tree parent_decl = NULL_TREE;
2977 int parent_flag;
2978 bool return_value;
2979 bool alternate_entry;
2980 bool entry_master;
2981 bool is_classarray;
2982 bool first_time = true;
2983
2984 sym = expr->symtree->n.sym;
2985 is_classarray = IS_CLASS_ARRAY (sym);
2986 ss = se->ss;
2987 if (ss != NULL)
2988 {
2989 gfc_ss_info *ss_info = ss->info;
2990
2991 /* Check that something hasn't gone horribly wrong. */
2992 gcc_assert (ss != gfc_ss_terminator);
2993 gcc_assert (ss_info->expr == expr);
2994
2995 /* A scalarized term. We already know the descriptor. */
2996 se->expr = ss_info->data.array.descriptor;
2997 se->string_length = ss_info->string_length;
2998 ref = ss_info->data.array.ref;
2999 if (ref)
3000 gcc_assert (ref->type == REF_ARRAY
3001 && ref->u.ar.type != AR_ELEMENT);
3002 else
3003 gfc_conv_tmp_array_ref (se);
3004 }
3005 else
3006 {
3007 tree se_expr = NULL_TREE;
3008
3009 se->expr = gfc_get_symbol_decl (sym);
3010
3011 /* Deal with references to a parent results or entries by storing
3012 the current_function_decl and moving to the parent_decl. */
3013 return_value = sym->attr.function && sym->result == sym;
3014 alternate_entry = sym->attr.function && sym->attr.entry
3015 && sym->result == sym;
3016 entry_master = sym->attr.result
3017 && sym->ns->proc_name->attr.entry_master
3018 && !gfc_return_by_reference (sym->ns->proc_name);
3019 if (current_function_decl)
3020 parent_decl = DECL_CONTEXT (current_function_decl);
3021
3022 if ((se->expr == parent_decl && return_value)
3023 || (sym->ns && sym->ns->proc_name
3024 && parent_decl
3025 && sym->ns->proc_name->backend_decl == parent_decl
3026 && (alternate_entry || entry_master)))
3027 parent_flag = 1;
3028 else
3029 parent_flag = 0;
3030
3031 /* Special case for assigning the return value of a function.
3032 Self recursive functions must have an explicit return value. */
3033 if (return_value && (se->expr == current_function_decl || parent_flag))
3034 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3035
3036 /* Similarly for alternate entry points. */
3037 else if (alternate_entry
3038 && (sym->ns->proc_name->backend_decl == current_function_decl
3039 || parent_flag))
3040 {
3041 gfc_entry_list *el = NULL;
3042
3043 for (el = sym->ns->entries; el; el = el->next)
3044 if (sym == el->sym)
3045 {
3046 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3047 break;
3048 }
3049 }
3050
3051 else if (entry_master
3052 && (sym->ns->proc_name->backend_decl == current_function_decl
3053 || parent_flag))
3054 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
3055
3056 if (se_expr)
3057 se->expr = se_expr;
3058
3059 /* Procedure actual arguments. Look out for temporary variables
3060 with the same attributes as function values. */
3061 else if (!sym->attr.temporary
3062 && sym->attr.flavor == FL_PROCEDURE
3063 && se->expr != current_function_decl)
3064 {
3065 if (!sym->attr.dummy && !sym->attr.proc_pointer)
3066 {
3067 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
3068 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
3069 }
3070 return;
3071 }
3072
3073 /* Dereference the expression, where needed. */
3074 se->expr = gfc_maybe_dereference_var (sym, se->expr, se->descriptor_only,
3075 is_classarray);
3076
3077 ref = expr->ref;
3078 }
3079
3080 /* For character variables, also get the length. */
3081 if (sym->ts.type == BT_CHARACTER)
3082 {
3083 /* If the character length of an entry isn't set, get the length from
3084 the master function instead. */
3085 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
3086 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
3087 else
3088 se->string_length = sym->ts.u.cl->backend_decl;
3089 gcc_assert (se->string_length);
3090 }
3091
3092 gfc_typespec *ts = &sym->ts;
3093 while (ref)
3094 {
3095 switch (ref->type)
3096 {
3097 case REF_ARRAY:
3098 /* Return the descriptor if that's what we want and this is an array
3099 section reference. */
3100 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
3101 return;
3102 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
3103 /* Return the descriptor for array pointers and allocations. */
3104 if (se->want_pointer
3105 && ref->next == NULL && (se->descriptor_only))
3106 return;
3107
3108 gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
3109 /* Return a pointer to an element. */
3110 break;
3111
3112 case REF_COMPONENT:
3113 ts = &ref->u.c.component->ts;
3114 if (first_time && is_classarray && sym->attr.dummy
3115 && se->descriptor_only
3116 && !CLASS_DATA (sym)->attr.allocatable
3117 && !CLASS_DATA (sym)->attr.class_pointer
3118 && CLASS_DATA (sym)->as
3119 && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK
3120 && strcmp ("_data", ref->u.c.component->name) == 0)
3121 /* Skip the first ref of a _data component, because for class
3122 arrays that one is already done by introducing a temporary
3123 array descriptor. */
3124 break;
3125
3126 if (ref->u.c.sym->attr.extension)
3127 conv_parent_component_references (se, ref);
3128
3129 gfc_conv_component_ref (se, ref);
3130 if (!ref->next && ref->u.c.sym->attr.codimension
3131 && se->want_pointer && se->descriptor_only)
3132 return;
3133
3134 break;
3135
3136 case REF_SUBSTRING:
3137 gfc_conv_substring (se, ref, expr->ts.kind,
3138 expr->symtree->name, &expr->where);
3139 break;
3140
3141 case REF_INQUIRY:
3142 conv_inquiry (se, ref, expr, ts);
3143 break;
3144
3145 default:
3146 gcc_unreachable ();
3147 break;
3148 }
3149 first_time = false;
3150 ref = ref->next;
3151 }
3152 /* Pointer assignment, allocation or pass by reference. Arrays are handled
3153 separately. */
3154 if (se->want_pointer)
3155 {
3156 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
3157 gfc_conv_string_parameter (se);
3158 else
3159 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
3160 }
3161 }
3162
3163
3164 /* Unary ops are easy... Or they would be if ! was a valid op. */
3165
3166 static void
gfc_conv_unary_op(enum tree_code code,gfc_se * se,gfc_expr * expr)3167 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
3168 {
3169 gfc_se operand;
3170 tree type;
3171
3172 gcc_assert (expr->ts.type != BT_CHARACTER);
3173 /* Initialize the operand. */
3174 gfc_init_se (&operand, se);
3175 gfc_conv_expr_val (&operand, expr->value.op.op1);
3176 gfc_add_block_to_block (&se->pre, &operand.pre);
3177
3178 type = gfc_typenode_for_spec (&expr->ts);
3179
3180 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
3181 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
3182 All other unary operators have an equivalent GIMPLE unary operator. */
3183 if (code == TRUTH_NOT_EXPR)
3184 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
3185 build_int_cst (type, 0));
3186 else
3187 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
3188
3189 }
3190
3191 /* Expand power operator to optimal multiplications when a value is raised
3192 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
3193 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
3194 Programming", 3rd Edition, 1998. */
3195
3196 /* This code is mostly duplicated from expand_powi in the backend.
3197 We establish the "optimal power tree" lookup table with the defined size.
3198 The items in the table are the exponents used to calculate the index
3199 exponents. Any integer n less than the value can get an "addition chain",
3200 with the first node being one. */
3201 #define POWI_TABLE_SIZE 256
3202
3203 /* The table is from builtins.cc. */
3204 static const unsigned char powi_table[POWI_TABLE_SIZE] =
3205 {
3206 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
3207 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
3208 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
3209 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
3210 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
3211 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
3212 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
3213 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
3214 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
3215 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
3216 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
3217 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
3218 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
3219 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
3220 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
3221 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
3222 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
3223 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
3224 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
3225 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
3226 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
3227 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
3228 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
3229 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
3230 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
3231 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
3232 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
3233 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
3234 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
3235 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
3236 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
3237 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
3238 };
3239
3240 /* If n is larger than lookup table's max index, we use the "window
3241 method". */
3242 #define POWI_WINDOW_SIZE 3
3243
3244 /* Recursive function to expand the power operator. The temporary
3245 values are put in tmpvar. The function returns tmpvar[1] ** n. */
3246 static tree
gfc_conv_powi(gfc_se * se,unsigned HOST_WIDE_INT n,tree * tmpvar)3247 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
3248 {
3249 tree op0;
3250 tree op1;
3251 tree tmp;
3252 int digit;
3253
3254 if (n < POWI_TABLE_SIZE)
3255 {
3256 if (tmpvar[n])
3257 return tmpvar[n];
3258
3259 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
3260 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
3261 }
3262 else if (n & 1)
3263 {
3264 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
3265 op0 = gfc_conv_powi (se, n - digit, tmpvar);
3266 op1 = gfc_conv_powi (se, digit, tmpvar);
3267 }
3268 else
3269 {
3270 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
3271 op1 = op0;
3272 }
3273
3274 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
3275 tmp = gfc_evaluate_now (tmp, &se->pre);
3276
3277 if (n < POWI_TABLE_SIZE)
3278 tmpvar[n] = tmp;
3279
3280 return tmp;
3281 }
3282
3283
3284 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
3285 return 1. Else return 0 and a call to runtime library functions
3286 will have to be built. */
3287 static int
gfc_conv_cst_int_power(gfc_se * se,tree lhs,tree rhs)3288 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
3289 {
3290 tree cond;
3291 tree tmp;
3292 tree type;
3293 tree vartmp[POWI_TABLE_SIZE];
3294 HOST_WIDE_INT m;
3295 unsigned HOST_WIDE_INT n;
3296 int sgn;
3297 wi::tree_to_wide_ref wrhs = wi::to_wide (rhs);
3298
3299 /* If exponent is too large, we won't expand it anyway, so don't bother
3300 with large integer values. */
3301 if (!wi::fits_shwi_p (wrhs))
3302 return 0;
3303
3304 m = wrhs.to_shwi ();
3305 /* Use the wide_int's routine to reliably get the absolute value on all
3306 platforms. Then convert it to a HOST_WIDE_INT like above. */
3307 n = wi::abs (wrhs).to_shwi ();
3308
3309 type = TREE_TYPE (lhs);
3310 sgn = tree_int_cst_sgn (rhs);
3311
3312 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
3313 || optimize_size) && (m > 2 || m < -1))
3314 return 0;
3315
3316 /* rhs == 0 */
3317 if (sgn == 0)
3318 {
3319 se->expr = gfc_build_const (type, integer_one_node);
3320 return 1;
3321 }
3322
3323 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
3324 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
3325 {
3326 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3327 lhs, build_int_cst (TREE_TYPE (lhs), -1));
3328 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
3329 lhs, build_int_cst (TREE_TYPE (lhs), 1));
3330
3331 /* If rhs is even,
3332 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
3333 if ((n & 1) == 0)
3334 {
3335 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
3336 logical_type_node, tmp, cond);
3337 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3338 tmp, build_int_cst (type, 1),
3339 build_int_cst (type, 0));
3340 return 1;
3341 }
3342 /* If rhs is odd,
3343 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
3344 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
3345 build_int_cst (type, -1),
3346 build_int_cst (type, 0));
3347 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3348 cond, build_int_cst (type, 1), tmp);
3349 return 1;
3350 }
3351
3352 memset (vartmp, 0, sizeof (vartmp));
3353 vartmp[1] = lhs;
3354 if (sgn == -1)
3355 {
3356 tmp = gfc_build_const (type, integer_one_node);
3357 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
3358 vartmp[1]);
3359 }
3360
3361 se->expr = gfc_conv_powi (se, n, vartmp);
3362
3363 return 1;
3364 }
3365
3366
3367 /* Power op (**). Constant integer exponent has special handling. */
3368
3369 static void
gfc_conv_power_op(gfc_se * se,gfc_expr * expr)3370 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
3371 {
3372 tree gfc_int4_type_node;
3373 int kind;
3374 int ikind;
3375 int res_ikind_1, res_ikind_2;
3376 gfc_se lse;
3377 gfc_se rse;
3378 tree fndecl = NULL;
3379
3380 gfc_init_se (&lse, se);
3381 gfc_conv_expr_val (&lse, expr->value.op.op1);
3382 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
3383 gfc_add_block_to_block (&se->pre, &lse.pre);
3384
3385 gfc_init_se (&rse, se);
3386 gfc_conv_expr_val (&rse, expr->value.op.op2);
3387 gfc_add_block_to_block (&se->pre, &rse.pre);
3388
3389 if (expr->value.op.op2->ts.type == BT_INTEGER
3390 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
3391 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
3392 return;
3393
3394 if (INTEGER_CST_P (lse.expr)
3395 && TREE_CODE (TREE_TYPE (rse.expr)) == INTEGER_TYPE)
3396 {
3397 wi::tree_to_wide_ref wlhs = wi::to_wide (lse.expr);
3398 HOST_WIDE_INT v, w;
3399 int kind, ikind, bit_size;
3400
3401 v = wlhs.to_shwi ();
3402 w = abs (v);
3403
3404 kind = expr->value.op.op1->ts.kind;
3405 ikind = gfc_validate_kind (BT_INTEGER, kind, false);
3406 bit_size = gfc_integer_kinds[ikind].bit_size;
3407
3408 if (v == 1)
3409 {
3410 /* 1**something is always 1. */
3411 se->expr = build_int_cst (TREE_TYPE (lse.expr), 1);
3412 return;
3413 }
3414 else if (v == -1)
3415 {
3416 /* (-1)**n is 1 - ((n & 1) << 1) */
3417 tree type;
3418 tree tmp;
3419
3420 type = TREE_TYPE (lse.expr);
3421 tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3422 rse.expr, build_int_cst (type, 1));
3423 tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3424 tmp, build_int_cst (type, 1));
3425 tmp = fold_build2_loc (input_location, MINUS_EXPR, type,
3426 build_int_cst (type, 1), tmp);
3427 se->expr = tmp;
3428 return;
3429 }
3430 else if (w > 0 && ((w & (w-1)) == 0) && ((w >> (bit_size-1)) == 0))
3431 {
3432 /* Here v is +/- 2**e. The further simplification uses
3433 2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n =
3434 1<<(4*n), etc., but we have to make sure to return zero
3435 if the number of bits is too large. */
3436 tree lshift;
3437 tree type;
3438 tree shift;
3439 tree ge;
3440 tree cond;
3441 tree num_bits;
3442 tree cond2;
3443 tree tmp1;
3444
3445 type = TREE_TYPE (lse.expr);
3446
3447 if (w == 2)
3448 shift = rse.expr;
3449 else if (w == 4)
3450 shift = fold_build2_loc (input_location, PLUS_EXPR,
3451 TREE_TYPE (rse.expr),
3452 rse.expr, rse.expr);
3453 else
3454 {
3455 /* use popcount for fast log2(w) */
3456 int e = wi::popcount (w-1);
3457 shift = fold_build2_loc (input_location, MULT_EXPR,
3458 TREE_TYPE (rse.expr),
3459 build_int_cst (TREE_TYPE (rse.expr), e),
3460 rse.expr);
3461 }
3462
3463 lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3464 build_int_cst (type, 1), shift);
3465 ge = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3466 rse.expr, build_int_cst (type, 0));
3467 cond = fold_build3_loc (input_location, COND_EXPR, type, ge, lshift,
3468 build_int_cst (type, 0));
3469 num_bits = build_int_cst (TREE_TYPE (rse.expr), TYPE_PRECISION (type));
3470 cond2 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3471 rse.expr, num_bits);
3472 tmp1 = fold_build3_loc (input_location, COND_EXPR, type, cond2,
3473 build_int_cst (type, 0), cond);
3474 if (v > 0)
3475 {
3476 se->expr = tmp1;
3477 }
3478 else
3479 {
3480 /* for v < 0, calculate v**n = |v|**n * (-1)**n */
3481 tree tmp2;
3482 tmp2 = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3483 rse.expr, build_int_cst (type, 1));
3484 tmp2 = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3485 tmp2, build_int_cst (type, 1));
3486 tmp2 = fold_build2_loc (input_location, MINUS_EXPR, type,
3487 build_int_cst (type, 1), tmp2);
3488 se->expr = fold_build2_loc (input_location, MULT_EXPR, type,
3489 tmp1, tmp2);
3490 }
3491 return;
3492 }
3493 }
3494
3495 gfc_int4_type_node = gfc_get_int_type (4);
3496
3497 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
3498 library routine. But in the end, we have to convert the result back
3499 if this case applies -- with res_ikind_K, we keep track whether operand K
3500 falls into this case. */
3501 res_ikind_1 = -1;
3502 res_ikind_2 = -1;
3503
3504 kind = expr->value.op.op1->ts.kind;
3505 switch (expr->value.op.op2->ts.type)
3506 {
3507 case BT_INTEGER:
3508 ikind = expr->value.op.op2->ts.kind;
3509 switch (ikind)
3510 {
3511 case 1:
3512 case 2:
3513 rse.expr = convert (gfc_int4_type_node, rse.expr);
3514 res_ikind_2 = ikind;
3515 /* Fall through. */
3516
3517 case 4:
3518 ikind = 0;
3519 break;
3520
3521 case 8:
3522 ikind = 1;
3523 break;
3524
3525 case 16:
3526 ikind = 2;
3527 break;
3528
3529 default:
3530 gcc_unreachable ();
3531 }
3532 switch (kind)
3533 {
3534 case 1:
3535 case 2:
3536 if (expr->value.op.op1->ts.type == BT_INTEGER)
3537 {
3538 lse.expr = convert (gfc_int4_type_node, lse.expr);
3539 res_ikind_1 = kind;
3540 }
3541 else
3542 gcc_unreachable ();
3543 /* Fall through. */
3544
3545 case 4:
3546 kind = 0;
3547 break;
3548
3549 case 8:
3550 kind = 1;
3551 break;
3552
3553 case 10:
3554 kind = 2;
3555 break;
3556
3557 case 16:
3558 kind = 3;
3559 break;
3560
3561 default:
3562 gcc_unreachable ();
3563 }
3564
3565 switch (expr->value.op.op1->ts.type)
3566 {
3567 case BT_INTEGER:
3568 if (kind == 3) /* Case 16 was not handled properly above. */
3569 kind = 2;
3570 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
3571 break;
3572
3573 case BT_REAL:
3574 /* Use builtins for real ** int4. */
3575 if (ikind == 0)
3576 {
3577 switch (kind)
3578 {
3579 case 0:
3580 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
3581 break;
3582
3583 case 1:
3584 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
3585 break;
3586
3587 case 2:
3588 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3589 break;
3590
3591 case 3:
3592 /* Use the __builtin_powil() only if real(kind=16) is
3593 actually the C long double type. */
3594 if (!gfc_real16_is_float128)
3595 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
3596 break;
3597
3598 default:
3599 gcc_unreachable ();
3600 }
3601 }
3602
3603 /* If we don't have a good builtin for this, go for the
3604 library function. */
3605 if (!fndecl)
3606 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
3607 break;
3608
3609 case BT_COMPLEX:
3610 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
3611 break;
3612
3613 default:
3614 gcc_unreachable ();
3615 }
3616 break;
3617
3618 case BT_REAL:
3619 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
3620 break;
3621
3622 case BT_COMPLEX:
3623 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
3624 break;
3625
3626 default:
3627 gcc_unreachable ();
3628 break;
3629 }
3630
3631 se->expr = build_call_expr_loc (input_location,
3632 fndecl, 2, lse.expr, rse.expr);
3633
3634 /* Convert the result back if it is of wrong integer kind. */
3635 if (res_ikind_1 != -1 && res_ikind_2 != -1)
3636 {
3637 /* We want the maximum of both operand kinds as result. */
3638 if (res_ikind_1 < res_ikind_2)
3639 res_ikind_1 = res_ikind_2;
3640 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
3641 }
3642 }
3643
3644
3645 /* Generate code to allocate a string temporary. */
3646
3647 tree
gfc_conv_string_tmp(gfc_se * se,tree type,tree len)3648 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
3649 {
3650 tree var;
3651 tree tmp;
3652
3653 if (gfc_can_put_var_on_stack (len))
3654 {
3655 /* Create a temporary variable to hold the result. */
3656 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3657 TREE_TYPE (len), len,
3658 build_int_cst (TREE_TYPE (len), 1));
3659 tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp);
3660
3661 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
3662 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
3663 else
3664 tmp = build_array_type (TREE_TYPE (type), tmp);
3665
3666 var = gfc_create_var (tmp, "str");
3667 var = gfc_build_addr_expr (type, var);
3668 }
3669 else
3670 {
3671 /* Allocate a temporary to hold the result. */
3672 var = gfc_create_var (type, "pstr");
3673 gcc_assert (POINTER_TYPE_P (type));
3674 tmp = TREE_TYPE (type);
3675 if (TREE_CODE (tmp) == ARRAY_TYPE)
3676 tmp = TREE_TYPE (tmp);
3677 tmp = TYPE_SIZE_UNIT (tmp);
3678 tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
3679 fold_convert (size_type_node, len),
3680 fold_convert (size_type_node, tmp));
3681 tmp = gfc_call_malloc (&se->pre, type, tmp);
3682 gfc_add_modify (&se->pre, var, tmp);
3683
3684 /* Free the temporary afterwards. */
3685 tmp = gfc_call_free (var);
3686 gfc_add_expr_to_block (&se->post, tmp);
3687 }
3688
3689 return var;
3690 }
3691
3692
3693 /* Handle a string concatenation operation. A temporary will be allocated to
3694 hold the result. */
3695
3696 static void
gfc_conv_concat_op(gfc_se * se,gfc_expr * expr)3697 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
3698 {
3699 gfc_se lse, rse;
3700 tree len, type, var, tmp, fndecl;
3701
3702 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
3703 && expr->value.op.op2->ts.type == BT_CHARACTER);
3704 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
3705
3706 gfc_init_se (&lse, se);
3707 gfc_conv_expr (&lse, expr->value.op.op1);
3708 gfc_conv_string_parameter (&lse);
3709 gfc_init_se (&rse, se);
3710 gfc_conv_expr (&rse, expr->value.op.op2);
3711 gfc_conv_string_parameter (&rse);
3712
3713 gfc_add_block_to_block (&se->pre, &lse.pre);
3714 gfc_add_block_to_block (&se->pre, &rse.pre);
3715
3716 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
3717 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3718 if (len == NULL_TREE)
3719 {
3720 len = fold_build2_loc (input_location, PLUS_EXPR,
3721 gfc_charlen_type_node,
3722 fold_convert (gfc_charlen_type_node,
3723 lse.string_length),
3724 fold_convert (gfc_charlen_type_node,
3725 rse.string_length));
3726 }
3727
3728 type = build_pointer_type (type);
3729
3730 var = gfc_conv_string_tmp (se, type, len);
3731
3732 /* Do the actual concatenation. */
3733 if (expr->ts.kind == 1)
3734 fndecl = gfor_fndecl_concat_string;
3735 else if (expr->ts.kind == 4)
3736 fndecl = gfor_fndecl_concat_string_char4;
3737 else
3738 gcc_unreachable ();
3739
3740 tmp = build_call_expr_loc (input_location,
3741 fndecl, 6, len, var, lse.string_length, lse.expr,
3742 rse.string_length, rse.expr);
3743 gfc_add_expr_to_block (&se->pre, tmp);
3744
3745 /* Add the cleanup for the operands. */
3746 gfc_add_block_to_block (&se->pre, &rse.post);
3747 gfc_add_block_to_block (&se->pre, &lse.post);
3748
3749 se->expr = var;
3750 se->string_length = len;
3751 }
3752
3753 /* Translates an op expression. Common (binary) cases are handled by this
3754 function, others are passed on. Recursion is used in either case.
3755 We use the fact that (op1.ts == op2.ts) (except for the power
3756 operator **).
3757 Operators need no special handling for scalarized expressions as long as
3758 they call gfc_conv_simple_val to get their operands.
3759 Character strings get special handling. */
3760
3761 static void
gfc_conv_expr_op(gfc_se * se,gfc_expr * expr)3762 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
3763 {
3764 enum tree_code code;
3765 gfc_se lse;
3766 gfc_se rse;
3767 tree tmp, type;
3768 int lop;
3769 int checkstring;
3770
3771 checkstring = 0;
3772 lop = 0;
3773 switch (expr->value.op.op)
3774 {
3775 case INTRINSIC_PARENTHESES:
3776 if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
3777 && flag_protect_parens)
3778 {
3779 gfc_conv_unary_op (PAREN_EXPR, se, expr);
3780 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
3781 return;
3782 }
3783
3784 /* Fallthrough. */
3785 case INTRINSIC_UPLUS:
3786 gfc_conv_expr (se, expr->value.op.op1);
3787 return;
3788
3789 case INTRINSIC_UMINUS:
3790 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
3791 return;
3792
3793 case INTRINSIC_NOT:
3794 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
3795 return;
3796
3797 case INTRINSIC_PLUS:
3798 code = PLUS_EXPR;
3799 break;
3800
3801 case INTRINSIC_MINUS:
3802 code = MINUS_EXPR;
3803 break;
3804
3805 case INTRINSIC_TIMES:
3806 code = MULT_EXPR;
3807 break;
3808
3809 case INTRINSIC_DIVIDE:
3810 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
3811 an integer, we must round towards zero, so we use a
3812 TRUNC_DIV_EXPR. */
3813 if (expr->ts.type == BT_INTEGER)
3814 code = TRUNC_DIV_EXPR;
3815 else
3816 code = RDIV_EXPR;
3817 break;
3818
3819 case INTRINSIC_POWER:
3820 gfc_conv_power_op (se, expr);
3821 return;
3822
3823 case INTRINSIC_CONCAT:
3824 gfc_conv_concat_op (se, expr);
3825 return;
3826
3827 case INTRINSIC_AND:
3828 code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR;
3829 lop = 1;
3830 break;
3831
3832 case INTRINSIC_OR:
3833 code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR;
3834 lop = 1;
3835 break;
3836
3837 /* EQV and NEQV only work on logicals, but since we represent them
3838 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
3839 case INTRINSIC_EQ:
3840 case INTRINSIC_EQ_OS:
3841 case INTRINSIC_EQV:
3842 code = EQ_EXPR;
3843 checkstring = 1;
3844 lop = 1;
3845 break;
3846
3847 case INTRINSIC_NE:
3848 case INTRINSIC_NE_OS:
3849 case INTRINSIC_NEQV:
3850 code = NE_EXPR;
3851 checkstring = 1;
3852 lop = 1;
3853 break;
3854
3855 case INTRINSIC_GT:
3856 case INTRINSIC_GT_OS:
3857 code = GT_EXPR;
3858 checkstring = 1;
3859 lop = 1;
3860 break;
3861
3862 case INTRINSIC_GE:
3863 case INTRINSIC_GE_OS:
3864 code = GE_EXPR;
3865 checkstring = 1;
3866 lop = 1;
3867 break;
3868
3869 case INTRINSIC_LT:
3870 case INTRINSIC_LT_OS:
3871 code = LT_EXPR;
3872 checkstring = 1;
3873 lop = 1;
3874 break;
3875
3876 case INTRINSIC_LE:
3877 case INTRINSIC_LE_OS:
3878 code = LE_EXPR;
3879 checkstring = 1;
3880 lop = 1;
3881 break;
3882
3883 case INTRINSIC_USER:
3884 case INTRINSIC_ASSIGN:
3885 /* These should be converted into function calls by the frontend. */
3886 gcc_unreachable ();
3887
3888 default:
3889 fatal_error (input_location, "Unknown intrinsic op");
3890 return;
3891 }
3892
3893 /* The only exception to this is **, which is handled separately anyway. */
3894 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
3895
3896 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
3897 checkstring = 0;
3898
3899 /* lhs */
3900 gfc_init_se (&lse, se);
3901 gfc_conv_expr (&lse, expr->value.op.op1);
3902 gfc_add_block_to_block (&se->pre, &lse.pre);
3903
3904 /* rhs */
3905 gfc_init_se (&rse, se);
3906 gfc_conv_expr (&rse, expr->value.op.op2);
3907 gfc_add_block_to_block (&se->pre, &rse.pre);
3908
3909 if (checkstring)
3910 {
3911 gfc_conv_string_parameter (&lse);
3912 gfc_conv_string_parameter (&rse);
3913
3914 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
3915 rse.string_length, rse.expr,
3916 expr->value.op.op1->ts.kind,
3917 code);
3918 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
3919 gfc_add_block_to_block (&lse.post, &rse.post);
3920 }
3921
3922 type = gfc_typenode_for_spec (&expr->ts);
3923
3924 if (lop)
3925 {
3926 /* The result of logical ops is always logical_type_node. */
3927 tmp = fold_build2_loc (input_location, code, logical_type_node,
3928 lse.expr, rse.expr);
3929 se->expr = convert (type, tmp);
3930 }
3931 else
3932 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
3933
3934 /* Add the post blocks. */
3935 gfc_add_block_to_block (&se->post, &rse.post);
3936 gfc_add_block_to_block (&se->post, &lse.post);
3937 }
3938
3939 /* If a string's length is one, we convert it to a single character. */
3940
3941 tree
gfc_string_to_single_character(tree len,tree str,int kind)3942 gfc_string_to_single_character (tree len, tree str, int kind)
3943 {
3944
3945 if (len == NULL
3946 || !tree_fits_uhwi_p (len)
3947 || !POINTER_TYPE_P (TREE_TYPE (str)))
3948 return NULL_TREE;
3949
3950 if (TREE_INT_CST_LOW (len) == 1)
3951 {
3952 str = fold_convert (gfc_get_pchar_type (kind), str);
3953 return build_fold_indirect_ref_loc (input_location, str);
3954 }
3955
3956 if (kind == 1
3957 && TREE_CODE (str) == ADDR_EXPR
3958 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3959 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3960 && array_ref_low_bound (TREE_OPERAND (str, 0))
3961 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3962 && TREE_INT_CST_LOW (len) > 1
3963 && TREE_INT_CST_LOW (len)
3964 == (unsigned HOST_WIDE_INT)
3965 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3966 {
3967 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
3968 ret = build_fold_indirect_ref_loc (input_location, ret);
3969 if (TREE_CODE (ret) == INTEGER_CST)
3970 {
3971 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
3972 int i, length = TREE_STRING_LENGTH (string_cst);
3973 const char *ptr = TREE_STRING_POINTER (string_cst);
3974
3975 for (i = 1; i < length; i++)
3976 if (ptr[i] != ' ')
3977 return NULL_TREE;
3978
3979 return ret;
3980 }
3981 }
3982
3983 return NULL_TREE;
3984 }
3985
3986
3987 static void
conv_scalar_char_value(gfc_symbol * sym,gfc_se * se,gfc_expr ** expr)3988 conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
3989 {
3990 gcc_assert (expr);
3991
3992 /* We used to modify the tree here. Now it is done earlier in
3993 the front-end, so we only check it here to avoid regressions. */
3994 if (sym->backend_decl)
3995 {
3996 gcc_assert (TREE_CODE (TREE_TYPE (sym->backend_decl)) == INTEGER_TYPE);
3997 gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym->backend_decl)) == 1);
3998 gcc_assert (TYPE_PRECISION (TREE_TYPE (sym->backend_decl)) == CHAR_TYPE_SIZE);
3999 gcc_assert (DECL_BY_REFERENCE (sym->backend_decl) == 0);
4000 }
4001
4002 /* If we have a constant character expression, make it into an
4003 integer of type C char. */
4004 if ((*expr)->expr_type == EXPR_CONSTANT)
4005 {
4006 gfc_typespec ts;
4007 gfc_clear_ts (&ts);
4008
4009 *expr = gfc_get_int_expr (gfc_default_character_kind, NULL,
4010 (*expr)->value.character.string[0]);
4011 }
4012 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
4013 {
4014 if ((*expr)->ref == NULL)
4015 {
4016 se->expr = gfc_string_to_single_character
4017 (build_int_cst (integer_type_node, 1),
4018 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4019 gfc_get_symbol_decl
4020 ((*expr)->symtree->n.sym)),
4021 (*expr)->ts.kind);
4022 }
4023 else
4024 {
4025 gfc_conv_variable (se, *expr);
4026 se->expr = gfc_string_to_single_character
4027 (build_int_cst (integer_type_node, 1),
4028 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4029 se->expr),
4030 (*expr)->ts.kind);
4031 }
4032 }
4033 }
4034
4035 /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
4036 if STR is a string literal, otherwise return -1. */
4037
4038 static int
gfc_optimize_len_trim(tree len,tree str,int kind)4039 gfc_optimize_len_trim (tree len, tree str, int kind)
4040 {
4041 if (kind == 1
4042 && TREE_CODE (str) == ADDR_EXPR
4043 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
4044 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
4045 && array_ref_low_bound (TREE_OPERAND (str, 0))
4046 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
4047 && tree_fits_uhwi_p (len)
4048 && tree_to_uhwi (len) >= 1
4049 && tree_to_uhwi (len)
4050 == (unsigned HOST_WIDE_INT)
4051 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
4052 {
4053 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
4054 folded = build_fold_indirect_ref_loc (input_location, folded);
4055 if (TREE_CODE (folded) == INTEGER_CST)
4056 {
4057 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
4058 int length = TREE_STRING_LENGTH (string_cst);
4059 const char *ptr = TREE_STRING_POINTER (string_cst);
4060
4061 for (; length > 0; length--)
4062 if (ptr[length - 1] != ' ')
4063 break;
4064
4065 return length;
4066 }
4067 }
4068 return -1;
4069 }
4070
4071 /* Helper to build a call to memcmp. */
4072
4073 static tree
build_memcmp_call(tree s1,tree s2,tree n)4074 build_memcmp_call (tree s1, tree s2, tree n)
4075 {
4076 tree tmp;
4077
4078 if (!POINTER_TYPE_P (TREE_TYPE (s1)))
4079 s1 = gfc_build_addr_expr (pvoid_type_node, s1);
4080 else
4081 s1 = fold_convert (pvoid_type_node, s1);
4082
4083 if (!POINTER_TYPE_P (TREE_TYPE (s2)))
4084 s2 = gfc_build_addr_expr (pvoid_type_node, s2);
4085 else
4086 s2 = fold_convert (pvoid_type_node, s2);
4087
4088 n = fold_convert (size_type_node, n);
4089
4090 tmp = build_call_expr_loc (input_location,
4091 builtin_decl_explicit (BUILT_IN_MEMCMP),
4092 3, s1, s2, n);
4093
4094 return fold_convert (integer_type_node, tmp);
4095 }
4096
4097 /* Compare two strings. If they are all single characters, the result is the
4098 subtraction of them. Otherwise, we build a library call. */
4099
4100 tree
gfc_build_compare_string(tree len1,tree str1,tree len2,tree str2,int kind,enum tree_code code)4101 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
4102 enum tree_code code)
4103 {
4104 tree sc1;
4105 tree sc2;
4106 tree fndecl;
4107
4108 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
4109 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
4110
4111 sc1 = gfc_string_to_single_character (len1, str1, kind);
4112 sc2 = gfc_string_to_single_character (len2, str2, kind);
4113
4114 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
4115 {
4116 /* Deal with single character specially. */
4117 sc1 = fold_convert (integer_type_node, sc1);
4118 sc2 = fold_convert (integer_type_node, sc2);
4119 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
4120 sc1, sc2);
4121 }
4122
4123 if ((code == EQ_EXPR || code == NE_EXPR)
4124 && optimize
4125 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
4126 {
4127 /* If one string is a string literal with LEN_TRIM longer
4128 than the length of the second string, the strings
4129 compare unequal. */
4130 int len = gfc_optimize_len_trim (len1, str1, kind);
4131 if (len > 0 && compare_tree_int (len2, len) < 0)
4132 return integer_one_node;
4133 len = gfc_optimize_len_trim (len2, str2, kind);
4134 if (len > 0 && compare_tree_int (len1, len) < 0)
4135 return integer_one_node;
4136 }
4137
4138 /* We can compare via memcpy if the strings are known to be equal
4139 in length and they are
4140 - kind=1
4141 - kind=4 and the comparison is for (in)equality. */
4142
4143 if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
4144 && tree_int_cst_equal (len1, len2)
4145 && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
4146 {
4147 tree tmp;
4148 tree chartype;
4149
4150 chartype = gfc_get_char_type (kind);
4151 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
4152 fold_convert (TREE_TYPE(len1),
4153 TYPE_SIZE_UNIT(chartype)),
4154 len1);
4155 return build_memcmp_call (str1, str2, tmp);
4156 }
4157
4158 /* Build a call for the comparison. */
4159 if (kind == 1)
4160 fndecl = gfor_fndecl_compare_string;
4161 else if (kind == 4)
4162 fndecl = gfor_fndecl_compare_string_char4;
4163 else
4164 gcc_unreachable ();
4165
4166 return build_call_expr_loc (input_location, fndecl, 4,
4167 len1, str1, len2, str2);
4168 }
4169
4170
4171 /* Return the backend_decl for a procedure pointer component. */
4172
4173 static tree
get_proc_ptr_comp(gfc_expr * e)4174 get_proc_ptr_comp (gfc_expr *e)
4175 {
4176 gfc_se comp_se;
4177 gfc_expr *e2;
4178 expr_t old_type;
4179
4180 gfc_init_se (&comp_se, NULL);
4181 e2 = gfc_copy_expr (e);
4182 /* We have to restore the expr type later so that gfc_free_expr frees
4183 the exact same thing that was allocated.
4184 TODO: This is ugly. */
4185 old_type = e2->expr_type;
4186 e2->expr_type = EXPR_VARIABLE;
4187 gfc_conv_expr (&comp_se, e2);
4188 e2->expr_type = old_type;
4189 gfc_free_expr (e2);
4190 return build_fold_addr_expr_loc (input_location, comp_se.expr);
4191 }
4192
4193
4194 /* Convert a typebound function reference from a class object. */
4195 static void
conv_base_obj_fcn_val(gfc_se * se,tree base_object,gfc_expr * expr)4196 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
4197 {
4198 gfc_ref *ref;
4199 tree var;
4200
4201 if (!VAR_P (base_object))
4202 {
4203 var = gfc_create_var (TREE_TYPE (base_object), NULL);
4204 gfc_add_modify (&se->pre, var, base_object);
4205 }
4206 se->expr = gfc_class_vptr_get (base_object);
4207 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
4208 ref = expr->ref;
4209 while (ref && ref->next)
4210 ref = ref->next;
4211 gcc_assert (ref && ref->type == REF_COMPONENT);
4212 if (ref->u.c.sym->attr.extension)
4213 conv_parent_component_references (se, ref);
4214 gfc_conv_component_ref (se, ref);
4215 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
4216 }
4217
4218
4219 static void
conv_function_val(gfc_se * se,gfc_symbol * sym,gfc_expr * expr,gfc_actual_arglist * actual_args)4220 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr,
4221 gfc_actual_arglist *actual_args)
4222 {
4223 tree tmp;
4224
4225 if (gfc_is_proc_ptr_comp (expr))
4226 tmp = get_proc_ptr_comp (expr);
4227 else if (sym->attr.dummy)
4228 {
4229 tmp = gfc_get_symbol_decl (sym);
4230 if (sym->attr.proc_pointer)
4231 tmp = build_fold_indirect_ref_loc (input_location,
4232 tmp);
4233 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
4234 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
4235 }
4236 else
4237 {
4238 if (!sym->backend_decl)
4239 sym->backend_decl = gfc_get_extern_function_decl (sym, actual_args);
4240
4241 TREE_USED (sym->backend_decl) = 1;
4242
4243 tmp = sym->backend_decl;
4244
4245 if (sym->attr.cray_pointee)
4246 {
4247 /* TODO - make the cray pointee a pointer to a procedure,
4248 assign the pointer to it and use it for the call. This
4249 will do for now! */
4250 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
4251 gfc_get_symbol_decl (sym->cp_pointer));
4252 tmp = gfc_evaluate_now (tmp, &se->pre);
4253 }
4254
4255 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
4256 {
4257 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
4258 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4259 }
4260 }
4261 se->expr = tmp;
4262 }
4263
4264
4265 /* Initialize MAPPING. */
4266
4267 void
gfc_init_interface_mapping(gfc_interface_mapping * mapping)4268 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
4269 {
4270 mapping->syms = NULL;
4271 mapping->charlens = NULL;
4272 }
4273
4274
4275 /* Free all memory held by MAPPING (but not MAPPING itself). */
4276
4277 void
gfc_free_interface_mapping(gfc_interface_mapping * mapping)4278 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
4279 {
4280 gfc_interface_sym_mapping *sym;
4281 gfc_interface_sym_mapping *nextsym;
4282 gfc_charlen *cl;
4283 gfc_charlen *nextcl;
4284
4285 for (sym = mapping->syms; sym; sym = nextsym)
4286 {
4287 nextsym = sym->next;
4288 sym->new_sym->n.sym->formal = NULL;
4289 gfc_free_symbol (sym->new_sym->n.sym);
4290 gfc_free_expr (sym->expr);
4291 free (sym->new_sym);
4292 free (sym);
4293 }
4294 for (cl = mapping->charlens; cl; cl = nextcl)
4295 {
4296 nextcl = cl->next;
4297 gfc_free_expr (cl->length);
4298 free (cl);
4299 }
4300 }
4301
4302
4303 /* Return a copy of gfc_charlen CL. Add the returned structure to
4304 MAPPING so that it will be freed by gfc_free_interface_mapping. */
4305
4306 static gfc_charlen *
gfc_get_interface_mapping_charlen(gfc_interface_mapping * mapping,gfc_charlen * cl)4307 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
4308 gfc_charlen * cl)
4309 {
4310 gfc_charlen *new_charlen;
4311
4312 new_charlen = gfc_get_charlen ();
4313 new_charlen->next = mapping->charlens;
4314 new_charlen->length = gfc_copy_expr (cl->length);
4315
4316 mapping->charlens = new_charlen;
4317 return new_charlen;
4318 }
4319
4320
4321 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
4322 array variable that can be used as the actual argument for dummy
4323 argument SYM. Add any initialization code to BLOCK. PACKED is as
4324 for gfc_get_nodesc_array_type and DATA points to the first element
4325 in the passed array. */
4326
4327 static tree
gfc_get_interface_mapping_array(stmtblock_t * block,gfc_symbol * sym,gfc_packed packed,tree data)4328 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
4329 gfc_packed packed, tree data)
4330 {
4331 tree type;
4332 tree var;
4333
4334 type = gfc_typenode_for_spec (&sym->ts);
4335 type = gfc_get_nodesc_array_type (type, sym->as, packed,
4336 !sym->attr.target && !sym->attr.pointer
4337 && !sym->attr.proc_pointer);
4338
4339 var = gfc_create_var (type, "ifm");
4340 gfc_add_modify (block, var, fold_convert (type, data));
4341
4342 return var;
4343 }
4344
4345
4346 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
4347 and offset of descriptorless array type TYPE given that it has the same
4348 size as DESC. Add any set-up code to BLOCK. */
4349
4350 static void
gfc_set_interface_mapping_bounds(stmtblock_t * block,tree type,tree desc)4351 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
4352 {
4353 int n;
4354 tree dim;
4355 tree offset;
4356 tree tmp;
4357
4358 offset = gfc_index_zero_node;
4359 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
4360 {
4361 dim = gfc_rank_cst[n];
4362 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
4363 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
4364 {
4365 GFC_TYPE_ARRAY_LBOUND (type, n)
4366 = gfc_conv_descriptor_lbound_get (desc, dim);
4367 GFC_TYPE_ARRAY_UBOUND (type, n)
4368 = gfc_conv_descriptor_ubound_get (desc, dim);
4369 }
4370 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
4371 {
4372 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4373 gfc_array_index_type,
4374 gfc_conv_descriptor_ubound_get (desc, dim),
4375 gfc_conv_descriptor_lbound_get (desc, dim));
4376 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4377 gfc_array_index_type,
4378 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
4379 tmp = gfc_evaluate_now (tmp, block);
4380 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
4381 }
4382 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4383 GFC_TYPE_ARRAY_LBOUND (type, n),
4384 GFC_TYPE_ARRAY_STRIDE (type, n));
4385 offset = fold_build2_loc (input_location, MINUS_EXPR,
4386 gfc_array_index_type, offset, tmp);
4387 }
4388 offset = gfc_evaluate_now (offset, block);
4389 GFC_TYPE_ARRAY_OFFSET (type) = offset;
4390 }
4391
4392
4393 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
4394 in SE. The caller may still use se->expr and se->string_length after
4395 calling this function. */
4396
4397 void
gfc_add_interface_mapping(gfc_interface_mapping * mapping,gfc_symbol * sym,gfc_se * se,gfc_expr * expr)4398 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
4399 gfc_symbol * sym, gfc_se * se,
4400 gfc_expr *expr)
4401 {
4402 gfc_interface_sym_mapping *sm;
4403 tree desc;
4404 tree tmp;
4405 tree value;
4406 gfc_symbol *new_sym;
4407 gfc_symtree *root;
4408 gfc_symtree *new_symtree;
4409
4410 /* Create a new symbol to represent the actual argument. */
4411 new_sym = gfc_new_symbol (sym->name, NULL);
4412 new_sym->ts = sym->ts;
4413 new_sym->as = gfc_copy_array_spec (sym->as);
4414 new_sym->attr.referenced = 1;
4415 new_sym->attr.dimension = sym->attr.dimension;
4416 new_sym->attr.contiguous = sym->attr.contiguous;
4417 new_sym->attr.codimension = sym->attr.codimension;
4418 new_sym->attr.pointer = sym->attr.pointer;
4419 new_sym->attr.allocatable = sym->attr.allocatable;
4420 new_sym->attr.flavor = sym->attr.flavor;
4421 new_sym->attr.function = sym->attr.function;
4422
4423 /* Ensure that the interface is available and that
4424 descriptors are passed for array actual arguments. */
4425 if (sym->attr.flavor == FL_PROCEDURE)
4426 {
4427 new_sym->formal = expr->symtree->n.sym->formal;
4428 new_sym->attr.always_explicit
4429 = expr->symtree->n.sym->attr.always_explicit;
4430 }
4431
4432 /* Create a fake symtree for it. */
4433 root = NULL;
4434 new_symtree = gfc_new_symtree (&root, sym->name);
4435 new_symtree->n.sym = new_sym;
4436 gcc_assert (new_symtree == root);
4437
4438 /* Create a dummy->actual mapping. */
4439 sm = XCNEW (gfc_interface_sym_mapping);
4440 sm->next = mapping->syms;
4441 sm->old = sym;
4442 sm->new_sym = new_symtree;
4443 sm->expr = gfc_copy_expr (expr);
4444 mapping->syms = sm;
4445
4446 /* Stabilize the argument's value. */
4447 if (!sym->attr.function && se)
4448 se->expr = gfc_evaluate_now (se->expr, &se->pre);
4449
4450 if (sym->ts.type == BT_CHARACTER)
4451 {
4452 /* Create a copy of the dummy argument's length. */
4453 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
4454 sm->expr->ts.u.cl = new_sym->ts.u.cl;
4455
4456 /* If the length is specified as "*", record the length that
4457 the caller is passing. We should use the callee's length
4458 in all other cases. */
4459 if (!new_sym->ts.u.cl->length && se)
4460 {
4461 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
4462 new_sym->ts.u.cl->backend_decl = se->string_length;
4463 }
4464 }
4465
4466 if (!se)
4467 return;
4468
4469 /* Use the passed value as-is if the argument is a function. */
4470 if (sym->attr.flavor == FL_PROCEDURE)
4471 value = se->expr;
4472
4473 /* If the argument is a pass-by-value scalar, use the value as is. */
4474 else if (!sym->attr.dimension && sym->attr.value)
4475 value = se->expr;
4476
4477 /* If the argument is either a string or a pointer to a string,
4478 convert it to a boundless character type. */
4479 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
4480 {
4481 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
4482 tmp = build_pointer_type (tmp);
4483 if (sym->attr.pointer)
4484 value = build_fold_indirect_ref_loc (input_location,
4485 se->expr);
4486 else
4487 value = se->expr;
4488 value = fold_convert (tmp, value);
4489 }
4490
4491 /* If the argument is a scalar, a pointer to an array or an allocatable,
4492 dereference it. */
4493 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
4494 value = build_fold_indirect_ref_loc (input_location,
4495 se->expr);
4496
4497 /* For character(*), use the actual argument's descriptor. */
4498 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
4499 value = build_fold_indirect_ref_loc (input_location,
4500 se->expr);
4501
4502 /* If the argument is an array descriptor, use it to determine
4503 information about the actual argument's shape. */
4504 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
4505 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
4506 {
4507 /* Get the actual argument's descriptor. */
4508 desc = build_fold_indirect_ref_loc (input_location,
4509 se->expr);
4510
4511 /* Create the replacement variable. */
4512 tmp = gfc_conv_descriptor_data_get (desc);
4513 value = gfc_get_interface_mapping_array (&se->pre, sym,
4514 PACKED_NO, tmp);
4515
4516 /* Use DESC to work out the upper bounds, strides and offset. */
4517 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
4518 }
4519 else
4520 /* Otherwise we have a packed array. */
4521 value = gfc_get_interface_mapping_array (&se->pre, sym,
4522 PACKED_FULL, se->expr);
4523
4524 new_sym->backend_decl = value;
4525 }
4526
4527
4528 /* Called once all dummy argument mappings have been added to MAPPING,
4529 but before the mapping is used to evaluate expressions. Pre-evaluate
4530 the length of each argument, adding any initialization code to PRE and
4531 any finalization code to POST. */
4532
4533 static void
gfc_finish_interface_mapping(gfc_interface_mapping * mapping,stmtblock_t * pre,stmtblock_t * post)4534 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
4535 stmtblock_t * pre, stmtblock_t * post)
4536 {
4537 gfc_interface_sym_mapping *sym;
4538 gfc_expr *expr;
4539 gfc_se se;
4540
4541 for (sym = mapping->syms; sym; sym = sym->next)
4542 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
4543 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
4544 {
4545 expr = sym->new_sym->n.sym->ts.u.cl->length;
4546 gfc_apply_interface_mapping_to_expr (mapping, expr);
4547 gfc_init_se (&se, NULL);
4548 gfc_conv_expr (&se, expr);
4549 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
4550 se.expr = gfc_evaluate_now (se.expr, &se.pre);
4551 gfc_add_block_to_block (pre, &se.pre);
4552 gfc_add_block_to_block (post, &se.post);
4553
4554 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
4555 }
4556 }
4557
4558
4559 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4560 constructor C. */
4561
4562 static void
gfc_apply_interface_mapping_to_cons(gfc_interface_mapping * mapping,gfc_constructor_base base)4563 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
4564 gfc_constructor_base base)
4565 {
4566 gfc_constructor *c;
4567 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
4568 {
4569 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
4570 if (c->iterator)
4571 {
4572 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
4573 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
4574 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
4575 }
4576 }
4577 }
4578
4579
4580 /* Like gfc_apply_interface_mapping_to_expr, but applied to
4581 reference REF. */
4582
4583 static void
gfc_apply_interface_mapping_to_ref(gfc_interface_mapping * mapping,gfc_ref * ref)4584 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
4585 gfc_ref * ref)
4586 {
4587 int n;
4588
4589 for (; ref; ref = ref->next)
4590 switch (ref->type)
4591 {
4592 case REF_ARRAY:
4593 for (n = 0; n < ref->u.ar.dimen; n++)
4594 {
4595 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
4596 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
4597 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
4598 }
4599 break;
4600
4601 case REF_COMPONENT:
4602 case REF_INQUIRY:
4603 break;
4604
4605 case REF_SUBSTRING:
4606 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
4607 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
4608 break;
4609 }
4610 }
4611
4612
4613 /* Convert intrinsic function calls into result expressions. */
4614
4615 static bool
gfc_map_intrinsic_function(gfc_expr * expr,gfc_interface_mapping * mapping)4616 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
4617 {
4618 gfc_symbol *sym;
4619 gfc_expr *new_expr;
4620 gfc_expr *arg1;
4621 gfc_expr *arg2;
4622 int d, dup;
4623
4624 arg1 = expr->value.function.actual->expr;
4625 if (expr->value.function.actual->next)
4626 arg2 = expr->value.function.actual->next->expr;
4627 else
4628 arg2 = NULL;
4629
4630 sym = arg1->symtree->n.sym;
4631
4632 if (sym->attr.dummy)
4633 return false;
4634
4635 new_expr = NULL;
4636
4637 switch (expr->value.function.isym->id)
4638 {
4639 case GFC_ISYM_LEN:
4640 /* TODO figure out why this condition is necessary. */
4641 if (sym->attr.function
4642 && (arg1->ts.u.cl->length == NULL
4643 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
4644 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
4645 return false;
4646
4647 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
4648 break;
4649
4650 case GFC_ISYM_LEN_TRIM:
4651 new_expr = gfc_copy_expr (arg1);
4652 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4653
4654 if (!new_expr)
4655 return false;
4656
4657 gfc_replace_expr (arg1, new_expr);
4658 return true;
4659
4660 case GFC_ISYM_SIZE:
4661 if (!sym->as || sym->as->rank == 0)
4662 return false;
4663
4664 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4665 {
4666 dup = mpz_get_si (arg2->value.integer);
4667 d = dup - 1;
4668 }
4669 else
4670 {
4671 dup = sym->as->rank;
4672 d = 0;
4673 }
4674
4675 for (; d < dup; d++)
4676 {
4677 gfc_expr *tmp;
4678
4679 if (!sym->as->upper[d] || !sym->as->lower[d])
4680 {
4681 gfc_free_expr (new_expr);
4682 return false;
4683 }
4684
4685 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
4686 gfc_get_int_expr (gfc_default_integer_kind,
4687 NULL, 1));
4688 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
4689 if (new_expr)
4690 new_expr = gfc_multiply (new_expr, tmp);
4691 else
4692 new_expr = tmp;
4693 }
4694 break;
4695
4696 case GFC_ISYM_LBOUND:
4697 case GFC_ISYM_UBOUND:
4698 /* TODO These implementations of lbound and ubound do not limit if
4699 the size < 0, according to F95's 13.14.53 and 13.14.113. */
4700
4701 if (!sym->as || sym->as->rank == 0)
4702 return false;
4703
4704 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4705 d = mpz_get_si (arg2->value.integer) - 1;
4706 else
4707 return false;
4708
4709 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
4710 {
4711 if (sym->as->lower[d])
4712 new_expr = gfc_copy_expr (sym->as->lower[d]);
4713 }
4714 else
4715 {
4716 if (sym->as->upper[d])
4717 new_expr = gfc_copy_expr (sym->as->upper[d]);
4718 }
4719 break;
4720
4721 default:
4722 break;
4723 }
4724
4725 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4726 if (!new_expr)
4727 return false;
4728
4729 gfc_replace_expr (expr, new_expr);
4730 return true;
4731 }
4732
4733
4734 static void
gfc_map_fcn_formal_to_actual(gfc_expr * expr,gfc_expr * map_expr,gfc_interface_mapping * mapping)4735 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
4736 gfc_interface_mapping * mapping)
4737 {
4738 gfc_formal_arglist *f;
4739 gfc_actual_arglist *actual;
4740
4741 actual = expr->value.function.actual;
4742 f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
4743
4744 for (; f && actual; f = f->next, actual = actual->next)
4745 {
4746 if (!actual->expr)
4747 continue;
4748
4749 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
4750 }
4751
4752 if (map_expr->symtree->n.sym->attr.dimension)
4753 {
4754 int d;
4755 gfc_array_spec *as;
4756
4757 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
4758
4759 for (d = 0; d < as->rank; d++)
4760 {
4761 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
4762 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
4763 }
4764
4765 expr->value.function.esym->as = as;
4766 }
4767
4768 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
4769 {
4770 expr->value.function.esym->ts.u.cl->length
4771 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
4772
4773 gfc_apply_interface_mapping_to_expr (mapping,
4774 expr->value.function.esym->ts.u.cl->length);
4775 }
4776 }
4777
4778
4779 /* EXPR is a copy of an expression that appeared in the interface
4780 associated with MAPPING. Walk it recursively looking for references to
4781 dummy arguments that MAPPING maps to actual arguments. Replace each such
4782 reference with a reference to the associated actual argument. */
4783
4784 static void
gfc_apply_interface_mapping_to_expr(gfc_interface_mapping * mapping,gfc_expr * expr)4785 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
4786 gfc_expr * expr)
4787 {
4788 gfc_interface_sym_mapping *sym;
4789 gfc_actual_arglist *actual;
4790
4791 if (!expr)
4792 return;
4793
4794 /* Copying an expression does not copy its length, so do that here. */
4795 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
4796 {
4797 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
4798 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
4799 }
4800
4801 /* Apply the mapping to any references. */
4802 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
4803
4804 /* ...and to the expression's symbol, if it has one. */
4805 /* TODO Find out why the condition on expr->symtree had to be moved into
4806 the loop rather than being outside it, as originally. */
4807 for (sym = mapping->syms; sym; sym = sym->next)
4808 if (expr->symtree && sym->old == expr->symtree->n.sym)
4809 {
4810 if (sym->new_sym->n.sym->backend_decl)
4811 expr->symtree = sym->new_sym;
4812 else if (sym->expr)
4813 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
4814 }
4815
4816 /* ...and to subexpressions in expr->value. */
4817 switch (expr->expr_type)
4818 {
4819 case EXPR_VARIABLE:
4820 case EXPR_CONSTANT:
4821 case EXPR_NULL:
4822 case EXPR_SUBSTRING:
4823 break;
4824
4825 case EXPR_OP:
4826 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
4827 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
4828 break;
4829
4830 case EXPR_FUNCTION:
4831 for (actual = expr->value.function.actual; actual; actual = actual->next)
4832 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
4833
4834 if (expr->value.function.esym == NULL
4835 && expr->value.function.isym != NULL
4836 && expr->value.function.actual
4837 && expr->value.function.actual->expr
4838 && expr->value.function.actual->expr->symtree
4839 && gfc_map_intrinsic_function (expr, mapping))
4840 break;
4841
4842 for (sym = mapping->syms; sym; sym = sym->next)
4843 if (sym->old == expr->value.function.esym)
4844 {
4845 expr->value.function.esym = sym->new_sym->n.sym;
4846 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
4847 expr->value.function.esym->result = sym->new_sym->n.sym;
4848 }
4849 break;
4850
4851 case EXPR_ARRAY:
4852 case EXPR_STRUCTURE:
4853 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
4854 break;
4855
4856 case EXPR_COMPCALL:
4857 case EXPR_PPC:
4858 case EXPR_UNKNOWN:
4859 gcc_unreachable ();
4860 break;
4861 }
4862
4863 return;
4864 }
4865
4866
4867 /* Evaluate interface expression EXPR using MAPPING. Store the result
4868 in SE. */
4869
4870 void
gfc_apply_interface_mapping(gfc_interface_mapping * mapping,gfc_se * se,gfc_expr * expr)4871 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
4872 gfc_se * se, gfc_expr * expr)
4873 {
4874 expr = gfc_copy_expr (expr);
4875 gfc_apply_interface_mapping_to_expr (mapping, expr);
4876 gfc_conv_expr (se, expr);
4877 se->expr = gfc_evaluate_now (se->expr, &se->pre);
4878 gfc_free_expr (expr);
4879 }
4880
4881
4882 /* Returns a reference to a temporary array into which a component of
4883 an actual argument derived type array is copied and then returned
4884 after the function call. */
4885 void
gfc_conv_subref_array_arg(gfc_se * se,gfc_expr * expr,int g77,sym_intent intent,bool formal_ptr,const gfc_symbol * fsym,const char * proc_name,gfc_symbol * sym,bool check_contiguous)4886 gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, int g77,
4887 sym_intent intent, bool formal_ptr,
4888 const gfc_symbol *fsym, const char *proc_name,
4889 gfc_symbol *sym, bool check_contiguous)
4890 {
4891 gfc_se lse;
4892 gfc_se rse;
4893 gfc_ss *lss;
4894 gfc_ss *rss;
4895 gfc_loopinfo loop;
4896 gfc_loopinfo loop2;
4897 gfc_array_info *info;
4898 tree offset;
4899 tree tmp_index;
4900 tree tmp;
4901 tree base_type;
4902 tree size;
4903 stmtblock_t body;
4904 int n;
4905 int dimen;
4906 gfc_se work_se;
4907 gfc_se *parmse;
4908 bool pass_optional;
4909
4910 pass_optional = fsym && fsym->attr.optional && sym && sym->attr.optional;
4911
4912 if (pass_optional || check_contiguous)
4913 {
4914 gfc_init_se (&work_se, NULL);
4915 parmse = &work_se;
4916 }
4917 else
4918 parmse = se;
4919
4920 if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
4921 {
4922 /* We will create a temporary array, so let us warn. */
4923 char * msg;
4924
4925 if (fsym && proc_name)
4926 msg = xasprintf ("An array temporary was created for argument "
4927 "'%s' of procedure '%s'", fsym->name, proc_name);
4928 else
4929 msg = xasprintf ("An array temporary was created");
4930
4931 tmp = build_int_cst (logical_type_node, 1);
4932 gfc_trans_runtime_check (false, true, tmp, &parmse->pre,
4933 &expr->where, msg);
4934 free (msg);
4935 }
4936
4937 gfc_init_se (&lse, NULL);
4938 gfc_init_se (&rse, NULL);
4939
4940 /* Walk the argument expression. */
4941 rss = gfc_walk_expr (expr);
4942
4943 gcc_assert (rss != gfc_ss_terminator);
4944
4945 /* Initialize the scalarizer. */
4946 gfc_init_loopinfo (&loop);
4947 gfc_add_ss_to_loop (&loop, rss);
4948
4949 /* Calculate the bounds of the scalarization. */
4950 gfc_conv_ss_startstride (&loop);
4951
4952 /* Build an ss for the temporary. */
4953 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
4954 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
4955
4956 base_type = gfc_typenode_for_spec (&expr->ts);
4957 if (GFC_ARRAY_TYPE_P (base_type)
4958 || GFC_DESCRIPTOR_TYPE_P (base_type))
4959 base_type = gfc_get_element_type (base_type);
4960
4961 if (expr->ts.type == BT_CLASS)
4962 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
4963
4964 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
4965 ? expr->ts.u.cl->backend_decl
4966 : NULL),
4967 loop.dimen);
4968
4969 parmse->string_length = loop.temp_ss->info->string_length;
4970
4971 /* Associate the SS with the loop. */
4972 gfc_add_ss_to_loop (&loop, loop.temp_ss);
4973
4974 /* Setup the scalarizing loops. */
4975 gfc_conv_loop_setup (&loop, &expr->where);
4976
4977 /* Pass the temporary descriptor back to the caller. */
4978 info = &loop.temp_ss->info->data.array;
4979 parmse->expr = info->descriptor;
4980
4981 /* Setup the gfc_se structures. */
4982 gfc_copy_loopinfo_to_se (&lse, &loop);
4983 gfc_copy_loopinfo_to_se (&rse, &loop);
4984
4985 rse.ss = rss;
4986 lse.ss = loop.temp_ss;
4987 gfc_mark_ss_chain_used (rss, 1);
4988 gfc_mark_ss_chain_used (loop.temp_ss, 1);
4989
4990 /* Start the scalarized loop body. */
4991 gfc_start_scalarized_body (&loop, &body);
4992
4993 /* Translate the expression. */
4994 gfc_conv_expr (&rse, expr);
4995
4996 /* Reset the offset for the function call since the loop
4997 is zero based on the data pointer. Note that the temp
4998 comes first in the loop chain since it is added second. */
4999 if (gfc_is_class_array_function (expr))
5000 {
5001 tmp = loop.ss->loop_chain->info->data.array.descriptor;
5002 gfc_conv_descriptor_offset_set (&loop.pre, tmp,
5003 gfc_index_zero_node);
5004 }
5005
5006 gfc_conv_tmp_array_ref (&lse);
5007
5008 if (intent != INTENT_OUT)
5009 {
5010 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
5011 gfc_add_expr_to_block (&body, tmp);
5012 gcc_assert (rse.ss == gfc_ss_terminator);
5013 gfc_trans_scalarizing_loops (&loop, &body);
5014 }
5015 else
5016 {
5017 /* Make sure that the temporary declaration survives by merging
5018 all the loop declarations into the current context. */
5019 for (n = 0; n < loop.dimen; n++)
5020 {
5021 gfc_merge_block_scope (&body);
5022 body = loop.code[loop.order[n]];
5023 }
5024 gfc_merge_block_scope (&body);
5025 }
5026
5027 /* Add the post block after the second loop, so that any
5028 freeing of allocated memory is done at the right time. */
5029 gfc_add_block_to_block (&parmse->pre, &loop.pre);
5030
5031 /**********Copy the temporary back again.*********/
5032
5033 gfc_init_se (&lse, NULL);
5034 gfc_init_se (&rse, NULL);
5035
5036 /* Walk the argument expression. */
5037 lss = gfc_walk_expr (expr);
5038 rse.ss = loop.temp_ss;
5039 lse.ss = lss;
5040
5041 /* Initialize the scalarizer. */
5042 gfc_init_loopinfo (&loop2);
5043 gfc_add_ss_to_loop (&loop2, lss);
5044
5045 dimen = rse.ss->dimen;
5046
5047 /* Skip the write-out loop for this case. */
5048 if (gfc_is_class_array_function (expr))
5049 goto class_array_fcn;
5050
5051 /* Calculate the bounds of the scalarization. */
5052 gfc_conv_ss_startstride (&loop2);
5053
5054 /* Setup the scalarizing loops. */
5055 gfc_conv_loop_setup (&loop2, &expr->where);
5056
5057 gfc_copy_loopinfo_to_se (&lse, &loop2);
5058 gfc_copy_loopinfo_to_se (&rse, &loop2);
5059
5060 gfc_mark_ss_chain_used (lss, 1);
5061 gfc_mark_ss_chain_used (loop.temp_ss, 1);
5062
5063 /* Declare the variable to hold the temporary offset and start the
5064 scalarized loop body. */
5065 offset = gfc_create_var (gfc_array_index_type, NULL);
5066 gfc_start_scalarized_body (&loop2, &body);
5067
5068 /* Build the offsets for the temporary from the loop variables. The
5069 temporary array has lbounds of zero and strides of one in all
5070 dimensions, so this is very simple. The offset is only computed
5071 outside the innermost loop, so the overall transfer could be
5072 optimized further. */
5073 info = &rse.ss->info->data.array;
5074
5075 tmp_index = gfc_index_zero_node;
5076 for (n = dimen - 1; n > 0; n--)
5077 {
5078 tree tmp_str;
5079 tmp = rse.loop->loopvar[n];
5080 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5081 tmp, rse.loop->from[n]);
5082 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5083 tmp, tmp_index);
5084
5085 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
5086 gfc_array_index_type,
5087 rse.loop->to[n-1], rse.loop->from[n-1]);
5088 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
5089 gfc_array_index_type,
5090 tmp_str, gfc_index_one_node);
5091
5092 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
5093 gfc_array_index_type, tmp, tmp_str);
5094 }
5095
5096 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
5097 gfc_array_index_type,
5098 tmp_index, rse.loop->from[0]);
5099 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
5100
5101 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
5102 gfc_array_index_type,
5103 rse.loop->loopvar[0], offset);
5104
5105 /* Now use the offset for the reference. */
5106 tmp = build_fold_indirect_ref_loc (input_location,
5107 info->data);
5108 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
5109
5110 if (expr->ts.type == BT_CHARACTER)
5111 rse.string_length = expr->ts.u.cl->backend_decl;
5112
5113 gfc_conv_expr (&lse, expr);
5114
5115 gcc_assert (lse.ss == gfc_ss_terminator);
5116
5117 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true);
5118 gfc_add_expr_to_block (&body, tmp);
5119
5120 /* Generate the copying loops. */
5121 gfc_trans_scalarizing_loops (&loop2, &body);
5122
5123 /* Wrap the whole thing up by adding the second loop to the post-block
5124 and following it by the post-block of the first loop. In this way,
5125 if the temporary needs freeing, it is done after use! */
5126 if (intent != INTENT_IN)
5127 {
5128 gfc_add_block_to_block (&parmse->post, &loop2.pre);
5129 gfc_add_block_to_block (&parmse->post, &loop2.post);
5130 }
5131
5132 class_array_fcn:
5133
5134 gfc_add_block_to_block (&parmse->post, &loop.post);
5135
5136 gfc_cleanup_loop (&loop);
5137 gfc_cleanup_loop (&loop2);
5138
5139 /* Pass the string length to the argument expression. */
5140 if (expr->ts.type == BT_CHARACTER)
5141 parmse->string_length = expr->ts.u.cl->backend_decl;
5142
5143 /* Determine the offset for pointer formal arguments and set the
5144 lbounds to one. */
5145 if (formal_ptr)
5146 {
5147 size = gfc_index_one_node;
5148 offset = gfc_index_zero_node;
5149 for (n = 0; n < dimen; n++)
5150 {
5151 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
5152 gfc_rank_cst[n]);
5153 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5154 gfc_array_index_type, tmp,
5155 gfc_index_one_node);
5156 gfc_conv_descriptor_ubound_set (&parmse->pre,
5157 parmse->expr,
5158 gfc_rank_cst[n],
5159 tmp);
5160 gfc_conv_descriptor_lbound_set (&parmse->pre,
5161 parmse->expr,
5162 gfc_rank_cst[n],
5163 gfc_index_one_node);
5164 size = gfc_evaluate_now (size, &parmse->pre);
5165 offset = fold_build2_loc (input_location, MINUS_EXPR,
5166 gfc_array_index_type,
5167 offset, size);
5168 offset = gfc_evaluate_now (offset, &parmse->pre);
5169 tmp = fold_build2_loc (input_location, MINUS_EXPR,
5170 gfc_array_index_type,
5171 rse.loop->to[n], rse.loop->from[n]);
5172 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5173 gfc_array_index_type,
5174 tmp, gfc_index_one_node);
5175 size = fold_build2_loc (input_location, MULT_EXPR,
5176 gfc_array_index_type, size, tmp);
5177 }
5178
5179 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
5180 offset);
5181 }
5182
5183 /* We want either the address for the data or the address of the descriptor,
5184 depending on the mode of passing array arguments. */
5185 if (g77)
5186 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
5187 else
5188 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5189
5190 /* Basically make this into
5191
5192 if (present)
5193 {
5194 if (contiguous)
5195 {
5196 pointer = a;
5197 }
5198 else
5199 {
5200 parmse->pre();
5201 pointer = parmse->expr;
5202 }
5203 }
5204 else
5205 pointer = NULL;
5206
5207 foo (pointer);
5208 if (present && !contiguous)
5209 se->post();
5210
5211 */
5212
5213 if (pass_optional || check_contiguous)
5214 {
5215 tree type;
5216 stmtblock_t else_block;
5217 tree pre_stmts, post_stmts;
5218 tree pointer;
5219 tree else_stmt;
5220 tree present_var = NULL_TREE;
5221 tree cont_var = NULL_TREE;
5222 tree post_cond;
5223
5224 type = TREE_TYPE (parmse->expr);
5225 if (POINTER_TYPE_P (type) && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type)))
5226 type = TREE_TYPE (type);
5227 pointer = gfc_create_var (type, "arg_ptr");
5228
5229 if (check_contiguous)
5230 {
5231 gfc_se cont_se, array_se;
5232 stmtblock_t if_block, else_block;
5233 tree if_stmt, else_stmt;
5234 mpz_t size;
5235 bool size_set;
5236
5237 cont_var = gfc_create_var (boolean_type_node, "contiguous");
5238
5239 /* If the size is known to be one at compile-time, set
5240 cont_var to true unconditionally. This may look
5241 inelegant, but we're only doing this during
5242 optimization, so the statements will be optimized away,
5243 and this saves complexity here. */
5244
5245 size_set = gfc_array_size (expr, &size);
5246 if (size_set && mpz_cmp_ui (size, 1) == 0)
5247 {
5248 gfc_add_modify (&se->pre, cont_var,
5249 build_one_cst (boolean_type_node));
5250 }
5251 else
5252 {
5253 /* cont_var = is_contiguous (expr); . */
5254 gfc_init_se (&cont_se, parmse);
5255 gfc_conv_is_contiguous_expr (&cont_se, expr);
5256 gfc_add_block_to_block (&se->pre, &(&cont_se)->pre);
5257 gfc_add_modify (&se->pre, cont_var, cont_se.expr);
5258 gfc_add_block_to_block (&se->pre, &(&cont_se)->post);
5259 }
5260
5261 if (size_set)
5262 mpz_clear (size);
5263
5264 /* arrayse->expr = descriptor of a. */
5265 gfc_init_se (&array_se, se);
5266 gfc_conv_expr_descriptor (&array_se, expr);
5267 gfc_add_block_to_block (&se->pre, &(&array_se)->pre);
5268 gfc_add_block_to_block (&se->pre, &(&array_se)->post);
5269
5270 /* if_stmt = { descriptor ? pointer = a : pointer = &a[0]; } . */
5271 gfc_init_block (&if_block);
5272 if (GFC_DESCRIPTOR_TYPE_P (type))
5273 gfc_add_modify (&if_block, pointer, array_se.expr);
5274 else
5275 {
5276 tmp = gfc_conv_array_data (array_se.expr);
5277 tmp = fold_convert (type, tmp);
5278 gfc_add_modify (&if_block, pointer, tmp);
5279 }
5280 if_stmt = gfc_finish_block (&if_block);
5281
5282 /* else_stmt = { parmse->pre(); pointer = parmse->expr; } . */
5283 gfc_init_block (&else_block);
5284 gfc_add_block_to_block (&else_block, &parmse->pre);
5285 tmp = (GFC_DESCRIPTOR_TYPE_P (type)
5286 ? build_fold_indirect_ref_loc (input_location, parmse->expr)
5287 : parmse->expr);
5288 gfc_add_modify (&else_block, pointer, tmp);
5289 else_stmt = gfc_finish_block (&else_block);
5290
5291 /* And put the above into an if statement. */
5292 pre_stmts = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5293 gfc_likely (cont_var,
5294 PRED_FORTRAN_CONTIGUOUS),
5295 if_stmt, else_stmt);
5296 }
5297 else
5298 {
5299 /* pointer = pramse->expr; . */
5300 gfc_add_modify (&parmse->pre, pointer, parmse->expr);
5301 pre_stmts = gfc_finish_block (&parmse->pre);
5302 }
5303
5304 if (pass_optional)
5305 {
5306 present_var = gfc_create_var (boolean_type_node, "present");
5307
5308 /* present_var = present(sym); . */
5309 tmp = gfc_conv_expr_present (sym);
5310 tmp = fold_convert (boolean_type_node, tmp);
5311 gfc_add_modify (&se->pre, present_var, tmp);
5312
5313 /* else_stmt = { pointer = NULL; } . */
5314 gfc_init_block (&else_block);
5315 if (GFC_DESCRIPTOR_TYPE_P (type))
5316 gfc_conv_descriptor_data_set (&else_block, pointer,
5317 null_pointer_node);
5318 else
5319 gfc_add_modify (&else_block, pointer, build_int_cst (type, 0));
5320 else_stmt = gfc_finish_block (&else_block);
5321
5322 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5323 gfc_likely (present_var,
5324 PRED_FORTRAN_ABSENT_DUMMY),
5325 pre_stmts, else_stmt);
5326 gfc_add_expr_to_block (&se->pre, tmp);
5327 }
5328 else
5329 gfc_add_expr_to_block (&se->pre, pre_stmts);
5330
5331 post_stmts = gfc_finish_block (&parmse->post);
5332
5333 /* Put together the post stuff, plus the optional
5334 deallocation. */
5335 if (check_contiguous)
5336 {
5337 /* !cont_var. */
5338 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5339 cont_var,
5340 build_zero_cst (boolean_type_node));
5341 tmp = gfc_unlikely (tmp, PRED_FORTRAN_CONTIGUOUS);
5342
5343 if (pass_optional)
5344 {
5345 tree present_likely = gfc_likely (present_var,
5346 PRED_FORTRAN_ABSENT_DUMMY);
5347 post_cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
5348 boolean_type_node, present_likely,
5349 tmp);
5350 }
5351 else
5352 post_cond = tmp;
5353 }
5354 else
5355 {
5356 gcc_assert (pass_optional);
5357 post_cond = present_var;
5358 }
5359
5360 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, post_cond,
5361 post_stmts, build_empty_stmt (input_location));
5362 gfc_add_expr_to_block (&se->post, tmp);
5363 if (GFC_DESCRIPTOR_TYPE_P (type))
5364 {
5365 type = TREE_TYPE (parmse->expr);
5366 if (POINTER_TYPE_P (type))
5367 {
5368 pointer = gfc_build_addr_expr (type, pointer);
5369 if (pass_optional)
5370 {
5371 tmp = gfc_likely (present_var, PRED_FORTRAN_ABSENT_DUMMY);
5372 pointer = fold_build3_loc (input_location, COND_EXPR, type,
5373 tmp, pointer,
5374 fold_convert (type,
5375 null_pointer_node));
5376 }
5377 }
5378 else
5379 gcc_assert (!pass_optional);
5380 }
5381 se->expr = pointer;
5382 }
5383
5384 return;
5385 }
5386
5387
5388 /* Generate the code for argument list functions. */
5389
5390 static void
conv_arglist_function(gfc_se * se,gfc_expr * expr,const char * name)5391 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
5392 {
5393 /* Pass by value for g77 %VAL(arg), pass the address
5394 indirectly for %LOC, else by reference. Thus %REF
5395 is a "do-nothing" and %LOC is the same as an F95
5396 pointer. */
5397 if (strcmp (name, "%VAL") == 0)
5398 gfc_conv_expr (se, expr);
5399 else if (strcmp (name, "%LOC") == 0)
5400 {
5401 gfc_conv_expr_reference (se, expr);
5402 se->expr = gfc_build_addr_expr (NULL, se->expr);
5403 }
5404 else if (strcmp (name, "%REF") == 0)
5405 gfc_conv_expr_reference (se, expr);
5406 else
5407 gfc_error ("Unknown argument list function at %L", &expr->where);
5408 }
5409
5410
5411 /* This function tells whether the middle-end representation of the expression
5412 E given as input may point to data otherwise accessible through a variable
5413 (sub-)reference.
5414 It is assumed that the only expressions that may alias are variables,
5415 and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
5416 may alias.
5417 This function is used to decide whether freeing an expression's allocatable
5418 components is safe or should be avoided.
5419
5420 If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
5421 its elements are copied from a variable. This ARRAY_MAY_ALIAS trick
5422 is necessary because for array constructors, aliasing depends on how
5423 the array is used:
5424 - If E is an array constructor used as argument to an elemental procedure,
5425 the array, which is generated through shallow copy by the scalarizer,
5426 is used directly and can alias the expressions it was copied from.
5427 - If E is an array constructor used as argument to a non-elemental
5428 procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
5429 the array as in the previous case, but then that array is used
5430 to initialize a new descriptor through deep copy. There is no alias
5431 possible in that case.
5432 Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
5433 above. */
5434
5435 static bool
expr_may_alias_variables(gfc_expr * e,bool array_may_alias)5436 expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
5437 {
5438 gfc_constructor *c;
5439
5440 if (e->expr_type == EXPR_VARIABLE)
5441 return true;
5442 else if (e->expr_type == EXPR_FUNCTION)
5443 {
5444 gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
5445
5446 if (proc_ifc->result != NULL
5447 && ((proc_ifc->result->ts.type == BT_CLASS
5448 && proc_ifc->result->ts.u.derived->attr.is_class
5449 && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
5450 || proc_ifc->result->attr.pointer))
5451 return true;
5452 else
5453 return false;
5454 }
5455 else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
5456 return false;
5457
5458 for (c = gfc_constructor_first (e->value.constructor);
5459 c; c = gfc_constructor_next (c))
5460 if (c->expr
5461 && expr_may_alias_variables (c->expr, array_may_alias))
5462 return true;
5463
5464 return false;
5465 }
5466
5467
5468 /* A helper function to set the dtype for unallocated or unassociated
5469 entities. */
5470
5471 static void
set_dtype_for_unallocated(gfc_se * parmse,gfc_expr * e)5472 set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
5473 {
5474 tree tmp;
5475 tree desc;
5476 tree cond;
5477 tree type;
5478 stmtblock_t block;
5479
5480 /* TODO Figure out how to handle optional dummies. */
5481 if (e && e->expr_type == EXPR_VARIABLE
5482 && e->symtree->n.sym->attr.optional)
5483 return;
5484
5485 desc = parmse->expr;
5486 if (desc == NULL_TREE)
5487 return;
5488
5489 if (POINTER_TYPE_P (TREE_TYPE (desc)))
5490 desc = build_fold_indirect_ref_loc (input_location, desc);
5491 if (GFC_CLASS_TYPE_P (TREE_TYPE (desc)))
5492 desc = gfc_class_data_get (desc);
5493 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
5494 return;
5495
5496 gfc_init_block (&block);
5497 tmp = gfc_conv_descriptor_data_get (desc);
5498 cond = fold_build2_loc (input_location, EQ_EXPR,
5499 logical_type_node, tmp,
5500 build_int_cst (TREE_TYPE (tmp), 0));
5501 tmp = gfc_conv_descriptor_dtype (desc);
5502 type = gfc_get_element_type (TREE_TYPE (desc));
5503 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5504 TREE_TYPE (tmp), tmp,
5505 gfc_get_dtype_rank_type (e->rank, type));
5506 gfc_add_expr_to_block (&block, tmp);
5507 cond = build3_v (COND_EXPR, cond,
5508 gfc_finish_block (&block),
5509 build_empty_stmt (input_location));
5510 gfc_add_expr_to_block (&parmse->pre, cond);
5511 }
5512
5513
5514
5515 /* Provide an interface between gfortran array descriptors and the F2018:18.4
5516 ISO_Fortran_binding array descriptors. */
5517
5518 static void
gfc_conv_gfc_desc_to_cfi_desc(gfc_se * parmse,gfc_expr * e,gfc_symbol * fsym)5519 gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
5520 {
5521 stmtblock_t block, block2;
5522 tree cfi, gfc, tmp, tmp2;
5523 tree present = NULL;
5524 tree gfc_strlen = NULL;
5525 tree rank;
5526 gfc_se se;
5527
5528 if (fsym->attr.optional
5529 && e->expr_type == EXPR_VARIABLE
5530 && e->symtree->n.sym->attr.optional)
5531 present = gfc_conv_expr_present (e->symtree->n.sym);
5532
5533 gfc_init_block (&block);
5534
5535 /* Convert original argument to a tree. */
5536 gfc_init_se (&se, NULL);
5537 if (e->rank == 0)
5538 {
5539 se.want_pointer = 1;
5540 gfc_conv_expr (&se, e);
5541 gfc = se.expr;
5542 /* gfc_conv_constant ignores se.want_poiner, e.g. for string_cst. */
5543 if (!POINTER_TYPE_P (TREE_TYPE (gfc)))
5544 gfc = gfc_build_addr_expr (NULL, gfc);
5545 }
5546 else
5547 {
5548 /* If the actual argument can be noncontiguous, copy-in/out is required,
5549 if the dummy has either the CONTIGUOUS attribute or is an assumed-
5550 length assumed-length/assumed-size CHARACTER array. This only
5551 applies if the actual argument is a "variable"; if it's some
5552 non-lvalue expression, we are going to evaluate it to a
5553 temporary below anyway. */
5554 se.force_no_tmp = 1;
5555 if ((fsym->attr.contiguous
5556 || (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->length
5557 && (fsym->as->type == AS_ASSUMED_SIZE
5558 || fsym->as->type == AS_EXPLICIT)))
5559 && !gfc_is_simply_contiguous (e, false, true)
5560 && gfc_expr_is_variable (e))
5561 {
5562 bool optional = fsym->attr.optional;
5563 fsym->attr.optional = 0;
5564 gfc_conv_subref_array_arg (&se, e, false, fsym->attr.intent,
5565 fsym->attr.pointer, fsym,
5566 fsym->ns->proc_name->name, NULL,
5567 /* check_contiguous= */ true);
5568 fsym->attr.optional = optional;
5569 }
5570 else
5571 gfc_conv_expr_descriptor (&se, e);
5572 gfc = se.expr;
5573 /* For dt(:)%var the elem_len*stride != sm, hence, GFC uses
5574 elem_len = sizeof(dt) and base_addr = dt(lb) instead.
5575 gfc_get_dataptr_offset fixes the base_addr; for elem_len, see below.
5576 While sm is fine as it uses span*stride and not elem_len. */
5577 if (POINTER_TYPE_P (TREE_TYPE (gfc)))
5578 gfc = build_fold_indirect_ref_loc (input_location, gfc);
5579 else if (is_subref_array (e) && e->ts.type != BT_CHARACTER)
5580 gfc_get_dataptr_offset (&se.pre, gfc, gfc, NULL, true, e);
5581 }
5582 if (e->ts.type == BT_CHARACTER)
5583 {
5584 if (se.string_length)
5585 gfc_strlen = se.string_length;
5586 else if (e->ts.u.cl->backend_decl)
5587 gfc_strlen = e->ts.u.cl->backend_decl;
5588 else
5589 gcc_unreachable ();
5590 }
5591 gfc_add_block_to_block (&block, &se.pre);
5592
5593 /* Create array decriptor and set version, rank, attribute, type. */
5594 cfi = gfc_create_var (gfc_get_cfi_type (e->rank < 0
5595 ? GFC_MAX_DIMENSIONS : e->rank,
5596 false), "cfi");
5597 /* Convert to CFI_cdesc_t, which has dim[] to avoid TBAA issues,*/
5598 if (fsym->attr.dimension && fsym->as->type == AS_ASSUMED_RANK)
5599 {
5600 tmp = gfc_get_cfi_type (-1, !fsym->attr.pointer && !fsym->attr.target);
5601 tmp = build_pointer_type (tmp);
5602 parmse->expr = cfi = gfc_build_addr_expr (tmp, cfi);
5603 cfi = build_fold_indirect_ref_loc (input_location, cfi);
5604 }
5605 else
5606 parmse->expr = gfc_build_addr_expr (NULL, cfi);
5607
5608 tmp = gfc_get_cfi_desc_version (cfi);
5609 gfc_add_modify (&block, tmp,
5610 build_int_cst (TREE_TYPE (tmp), CFI_VERSION));
5611 if (e->rank < 0)
5612 rank = fold_convert (signed_char_type_node, gfc_conv_descriptor_rank (gfc));
5613 else
5614 rank = build_int_cst (signed_char_type_node, e->rank);
5615 tmp = gfc_get_cfi_desc_rank (cfi);
5616 gfc_add_modify (&block, tmp, rank);
5617 int itype = CFI_type_other;
5618 if (e->ts.f90_type == BT_VOID)
5619 itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
5620 ? CFI_type_cfunptr : CFI_type_cptr);
5621 else
5622 {
5623 if (e->expr_type == EXPR_NULL && e->ts.type == BT_UNKNOWN)
5624 e->ts = fsym->ts;
5625 switch (e->ts.type)
5626 {
5627 case BT_INTEGER:
5628 case BT_LOGICAL:
5629 case BT_REAL:
5630 case BT_COMPLEX:
5631 itype = CFI_type_from_type_kind (e->ts.type, e->ts.kind);
5632 break;
5633 case BT_CHARACTER:
5634 itype = CFI_type_from_type_kind (CFI_type_Character, e->ts.kind);
5635 break;
5636 case BT_DERIVED:
5637 itype = CFI_type_struct;
5638 break;
5639 case BT_VOID:
5640 itype = (e->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
5641 ? CFI_type_cfunptr : CFI_type_cptr);
5642 break;
5643 case BT_ASSUMED:
5644 itype = CFI_type_other; // FIXME: Or CFI_type_cptr ?
5645 break;
5646 case BT_CLASS:
5647 if (UNLIMITED_POLY (e) && fsym->ts.type == BT_ASSUMED)
5648 {
5649 // F2017: 7.3.2.2: "An entity that is declared using the TYPE(*)
5650 // type specifier is assumed-type and is an unlimited polymorphic
5651 // entity." The actual argument _data component is passed.
5652 itype = CFI_type_other; // FIXME: Or CFI_type_cptr ?
5653 break;
5654 }
5655 else
5656 gcc_unreachable ();
5657 case BT_PROCEDURE:
5658 case BT_HOLLERITH:
5659 case BT_UNION:
5660 case BT_BOZ:
5661 case BT_UNKNOWN:
5662 // FIXME: Really unreachable? Or reachable for type(*) ? If so, CFI_type_other?
5663 gcc_unreachable ();
5664 }
5665 }
5666
5667 tmp = gfc_get_cfi_desc_type (cfi);
5668 gfc_add_modify (&block, tmp,
5669 build_int_cst (TREE_TYPE (tmp), itype));
5670
5671 int attr = CFI_attribute_other;
5672 if (fsym->attr.pointer)
5673 attr = CFI_attribute_pointer;
5674 else if (fsym->attr.allocatable)
5675 attr = CFI_attribute_allocatable;
5676 tmp = gfc_get_cfi_desc_attribute (cfi);
5677 gfc_add_modify (&block, tmp,
5678 build_int_cst (TREE_TYPE (tmp), attr));
5679
5680 if (e->rank == 0)
5681 {
5682 tmp = gfc_get_cfi_desc_base_addr (cfi);
5683 gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), gfc));
5684 }
5685 else
5686 {
5687 tmp = gfc_get_cfi_desc_base_addr (cfi);
5688 tmp2 = gfc_conv_descriptor_data_get (gfc);
5689 gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), tmp2));
5690 }
5691
5692 /* Set elem_len if known - must be before the next if block.
5693 Note that allocatable implies 'len=:'. */
5694 if (e->ts.type != BT_ASSUMED && e->ts.type != BT_CHARACTER )
5695 {
5696 /* Length is known at compile time; use 'block' for it. */
5697 tmp = size_in_bytes (gfc_typenode_for_spec (&e->ts));
5698 tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5699 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5700 }
5701
5702 /* When allocatable + intent out, free the cfi descriptor. */
5703 if (fsym->attr.allocatable && fsym->attr.intent == INTENT_OUT)
5704 {
5705 tmp = gfc_get_cfi_desc_base_addr (cfi);
5706 tree call = builtin_decl_explicit (BUILT_IN_FREE);
5707 call = build_call_expr_loc (input_location, call, 1, tmp);
5708 gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
5709 gfc_add_modify (&block, tmp,
5710 fold_convert (TREE_TYPE (tmp), null_pointer_node));
5711 goto done;
5712 }
5713
5714 /* If not unallocated/unassociated. */
5715 gfc_init_block (&block2);
5716
5717 /* Set elem_len, which may be only known at run time. */
5718 if (e->ts.type == BT_CHARACTER
5719 && (e->expr_type != EXPR_NULL || gfc_strlen != NULL_TREE))
5720 {
5721 gcc_assert (gfc_strlen);
5722 tmp = gfc_strlen;
5723 if (e->ts.kind != 1)
5724 tmp = fold_build2_loc (input_location, MULT_EXPR,
5725 gfc_charlen_type_node, tmp,
5726 build_int_cst (gfc_charlen_type_node,
5727 e->ts.kind));
5728 tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5729 gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5730 }
5731 else if (e->ts.type == BT_ASSUMED)
5732 {
5733 tmp = gfc_conv_descriptor_elem_len (gfc);
5734 tmp2 = gfc_get_cfi_desc_elem_len (cfi);
5735 gfc_add_modify (&block2, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
5736 }
5737
5738 if (e->ts.type == BT_ASSUMED)
5739 {
5740 /* Note: type(*) implies assumed-shape/assumed-rank if fsym requires
5741 an CFI descriptor. Use the type in the descritor as it provide
5742 mode information. (Quality of implementation feature.) */
5743 tree cond;
5744 tree ctype = gfc_get_cfi_desc_type (cfi);
5745 tree type = fold_convert (TREE_TYPE (ctype),
5746 gfc_conv_descriptor_type (gfc));
5747 tree kind = fold_convert (TREE_TYPE (ctype),
5748 gfc_conv_descriptor_elem_len (gfc));
5749 kind = fold_build2_loc (input_location, LSHIFT_EXPR, TREE_TYPE (type),
5750 kind, build_int_cst (TREE_TYPE (type),
5751 CFI_type_kind_shift));
5752
5753 /* if (BT_VOID) CFI_type_cptr else CFI_type_other */
5754 /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
5755 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5756 build_int_cst (TREE_TYPE (type), BT_VOID));
5757 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype,
5758 build_int_cst (TREE_TYPE (type), CFI_type_cptr));
5759 tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5760 ctype,
5761 build_int_cst (TREE_TYPE (type), CFI_type_other));
5762 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5763 tmp, tmp2);
5764 /* if (BT_DERIVED) CFI_type_struct else < tmp2 > */
5765 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5766 build_int_cst (TREE_TYPE (type), BT_DERIVED));
5767 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, ctype,
5768 build_int_cst (TREE_TYPE (type), CFI_type_struct));
5769 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5770 tmp, tmp2);
5771 /* if (BT_CHARACTER) CFI_type_Character + kind=1 else < tmp2 > */
5772 /* Note: could also be kind=4, with cfi->elem_len = gfc->elem_len*4. */
5773 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5774 build_int_cst (TREE_TYPE (type), BT_CHARACTER));
5775 tmp = build_int_cst (TREE_TYPE (type),
5776 CFI_type_from_type_kind (CFI_type_Character, 1));
5777 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5778 ctype, tmp);
5779 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5780 tmp, tmp2);
5781 /* if (BT_COMPLEX) CFI_type_Complex + kind/2 else < tmp2 > */
5782 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5783 build_int_cst (TREE_TYPE (type), BT_COMPLEX));
5784 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (type),
5785 kind, build_int_cst (TREE_TYPE (type), 2));
5786 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type), tmp,
5787 build_int_cst (TREE_TYPE (type),
5788 CFI_type_Complex));
5789 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5790 ctype, tmp);
5791 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5792 tmp, tmp2);
5793 /* if (BT_INTEGER || BT_LOGICAL || BT_REAL) type + kind else <tmp2> */
5794 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5795 build_int_cst (TREE_TYPE (type), BT_INTEGER));
5796 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5797 build_int_cst (TREE_TYPE (type), BT_LOGICAL));
5798 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
5799 cond, tmp);
5800 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, type,
5801 build_int_cst (TREE_TYPE (type), BT_REAL));
5802 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
5803 cond, tmp);
5804 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (type),
5805 type, kind);
5806 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
5807 ctype, tmp);
5808 tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5809 tmp, tmp2);
5810 gfc_add_expr_to_block (&block2, tmp2);
5811 }
5812
5813 if (e->rank != 0)
5814 {
5815 /* Loop: for (i = 0; i < rank; ++i). */
5816 tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
5817 /* Loop body. */
5818 stmtblock_t loop_body;
5819 gfc_init_block (&loop_body);
5820 /* cfi->dim[i].lower_bound = (allocatable/pointer)
5821 ? gfc->dim[i].lbound : 0 */
5822 if (fsym->attr.pointer || fsym->attr.allocatable)
5823 tmp = gfc_conv_descriptor_lbound_get (gfc, idx);
5824 else
5825 tmp = gfc_index_zero_node;
5826 gfc_add_modify (&loop_body, gfc_get_cfi_dim_lbound (cfi, idx), tmp);
5827 /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1. */
5828 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5829 gfc_conv_descriptor_ubound_get (gfc, idx),
5830 gfc_conv_descriptor_lbound_get (gfc, idx));
5831 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5832 tmp, gfc_index_one_node);
5833 gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp);
5834 /* d->dim[n].sm = gfc->dim[i].stride * gfc->span); */
5835 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5836 gfc_conv_descriptor_stride_get (gfc, idx),
5837 gfc_conv_descriptor_span_get (gfc));
5838 gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp);
5839
5840 /* Generate loop. */
5841 gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
5842 rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
5843 gfc_finish_block (&loop_body));
5844
5845 if (e->expr_type == EXPR_VARIABLE
5846 && e->ref
5847 && e->ref->u.ar.type == AR_FULL
5848 && e->symtree->n.sym->attr.dummy
5849 && e->symtree->n.sym->as
5850 && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE)
5851 {
5852 tmp = gfc_get_cfi_dim_extent (cfi, gfc_rank_cst[e->rank-1]),
5853 gfc_add_modify (&block2, tmp, build_int_cst (TREE_TYPE (tmp), -1));
5854 }
5855 }
5856
5857 if (fsym->attr.allocatable || fsym->attr.pointer)
5858 {
5859 tmp = gfc_get_cfi_desc_base_addr (cfi),
5860 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5861 tmp, null_pointer_node);
5862 tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
5863 build_empty_stmt (input_location));
5864 gfc_add_expr_to_block (&block, tmp);
5865 }
5866 else
5867 gfc_add_block_to_block (&block, &block2);
5868
5869
5870 done:
5871 if (present)
5872 {
5873 parmse->expr = build3_loc (input_location, COND_EXPR,
5874 TREE_TYPE (parmse->expr),
5875 present, parmse->expr, null_pointer_node);
5876 tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
5877 build_empty_stmt (input_location));
5878 gfc_add_expr_to_block (&parmse->pre, tmp);
5879 }
5880 else
5881 gfc_add_block_to_block (&parmse->pre, &block);
5882
5883 gfc_init_block (&block);
5884
5885 if ((!fsym->attr.allocatable && !fsym->attr.pointer)
5886 || fsym->attr.intent == INTENT_IN)
5887 goto post_call;
5888
5889 gfc_init_block (&block2);
5890 if (e->rank == 0)
5891 {
5892 tmp = gfc_get_cfi_desc_base_addr (cfi);
5893 gfc_add_modify (&block, gfc, fold_convert (TREE_TYPE (gfc), tmp));
5894 }
5895 else
5896 {
5897 tmp = gfc_get_cfi_desc_base_addr (cfi);
5898 gfc_conv_descriptor_data_set (&block, gfc, tmp);
5899
5900 if (fsym->attr.allocatable)
5901 {
5902 /* gfc->span = cfi->elem_len. */
5903 tmp = fold_convert (gfc_array_index_type,
5904 gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]));
5905 }
5906 else
5907 {
5908 /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len)
5909 ? cfi->dim[0].sm : cfi->elem_len). */
5910 tmp = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]);
5911 tmp2 = fold_convert (gfc_array_index_type,
5912 gfc_get_cfi_desc_elem_len (cfi));
5913 tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
5914 gfc_array_index_type, tmp, tmp2);
5915 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5916 tmp, gfc_index_zero_node);
5917 tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, tmp,
5918 gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]), tmp2);
5919 }
5920 gfc_conv_descriptor_span_set (&block2, gfc, tmp);
5921
5922 /* Calculate offset + set lbound, ubound and stride. */
5923 gfc_conv_descriptor_offset_set (&block2, gfc, gfc_index_zero_node);
5924 /* Loop: for (i = 0; i < rank; ++i). */
5925 tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
5926 /* Loop body. */
5927 stmtblock_t loop_body;
5928 gfc_init_block (&loop_body);
5929 /* gfc->dim[i].lbound = ... */
5930 tmp = gfc_get_cfi_dim_lbound (cfi, idx);
5931 gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp);
5932
5933 /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
5934 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5935 gfc_conv_descriptor_lbound_get (gfc, idx),
5936 gfc_index_one_node);
5937 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5938 gfc_get_cfi_dim_extent (cfi, idx), tmp);
5939 gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp);
5940
5941 /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
5942 tmp = gfc_get_cfi_dim_sm (cfi, idx);
5943 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
5944 gfc_array_index_type, tmp,
5945 fold_convert (gfc_array_index_type,
5946 gfc_get_cfi_desc_elem_len (cfi)));
5947 gfc_conv_descriptor_stride_set (&loop_body, gfc, idx, tmp);
5948
5949 /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
5950 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5951 gfc_conv_descriptor_stride_get (gfc, idx),
5952 gfc_conv_descriptor_lbound_get (gfc, idx));
5953 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5954 gfc_conv_descriptor_offset_get (gfc), tmp);
5955 gfc_conv_descriptor_offset_set (&loop_body, gfc, tmp);
5956 /* Generate loop. */
5957 gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
5958 rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
5959 gfc_finish_block (&loop_body));
5960 }
5961
5962 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
5963 {
5964 tmp = fold_convert (gfc_charlen_type_node,
5965 gfc_get_cfi_desc_elem_len (cfi));
5966 if (e->ts.kind != 1)
5967 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
5968 gfc_charlen_type_node, tmp,
5969 build_int_cst (gfc_charlen_type_node,
5970 e->ts.kind));
5971 gfc_add_modify (&block2, gfc_strlen, tmp);
5972 }
5973
5974 tmp = gfc_get_cfi_desc_base_addr (cfi),
5975 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5976 tmp, null_pointer_node);
5977 tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
5978 build_empty_stmt (input_location));
5979 gfc_add_expr_to_block (&block, tmp);
5980
5981 post_call:
5982 gfc_add_block_to_block (&block, &se.post);
5983 if (present && block.head)
5984 {
5985 tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
5986 build_empty_stmt (input_location));
5987 gfc_add_expr_to_block (&parmse->post, tmp);
5988 }
5989 else if (block.head)
5990 gfc_add_block_to_block (&parmse->post, &block);
5991 }
5992
5993
5994 /* Generate code for a procedure call. Note can return se->post != NULL.
5995 If se->direct_byref is set then se->expr contains the return parameter.
5996 Return nonzero, if the call has alternate specifiers.
5997 'expr' is only needed for procedure pointer components. */
5998
5999 int
gfc_conv_procedure_call(gfc_se * se,gfc_symbol * sym,gfc_actual_arglist * args,gfc_expr * expr,vec<tree,va_gc> * append_args)6000 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
6001 gfc_actual_arglist * args, gfc_expr * expr,
6002 vec<tree, va_gc> *append_args)
6003 {
6004 gfc_interface_mapping mapping;
6005 vec<tree, va_gc> *arglist;
6006 vec<tree, va_gc> *retargs;
6007 tree tmp;
6008 tree fntype;
6009 gfc_se parmse;
6010 gfc_array_info *info;
6011 int byref;
6012 int parm_kind;
6013 tree type;
6014 tree var;
6015 tree len;
6016 tree base_object;
6017 vec<tree, va_gc> *stringargs;
6018 vec<tree, va_gc> *optionalargs;
6019 tree result = NULL;
6020 gfc_formal_arglist *formal;
6021 gfc_actual_arglist *arg;
6022 int has_alternate_specifier = 0;
6023 bool need_interface_mapping;
6024 bool callee_alloc;
6025 bool ulim_copy;
6026 gfc_typespec ts;
6027 gfc_charlen cl;
6028 gfc_expr *e;
6029 gfc_symbol *fsym;
6030 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
6031 gfc_component *comp = NULL;
6032 int arglen;
6033 unsigned int argc;
6034
6035 arglist = NULL;
6036 retargs = NULL;
6037 stringargs = NULL;
6038 optionalargs = NULL;
6039 var = NULL_TREE;
6040 len = NULL_TREE;
6041 gfc_clear_ts (&ts);
6042
6043 comp = gfc_get_proc_ptr_comp (expr);
6044
6045 bool elemental_proc = (comp
6046 && comp->ts.interface
6047 && comp->ts.interface->attr.elemental)
6048 || (comp && comp->attr.elemental)
6049 || sym->attr.elemental;
6050
6051 if (se->ss != NULL)
6052 {
6053 if (!elemental_proc)
6054 {
6055 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
6056 if (se->ss->info->useflags)
6057 {
6058 gcc_assert ((!comp && gfc_return_by_reference (sym)
6059 && sym->result->attr.dimension)
6060 || (comp && comp->attr.dimension)
6061 || gfc_is_class_array_function (expr));
6062 gcc_assert (se->loop != NULL);
6063 /* Access the previously obtained result. */
6064 gfc_conv_tmp_array_ref (se);
6065 return 0;
6066 }
6067 }
6068 info = &se->ss->info->data.array;
6069 }
6070 else
6071 info = NULL;
6072
6073 stmtblock_t post, clobbers;
6074 gfc_init_block (&post);
6075 gfc_init_block (&clobbers);
6076 gfc_init_interface_mapping (&mapping);
6077 if (!comp)
6078 {
6079 formal = gfc_sym_get_dummy_args (sym);
6080 need_interface_mapping = sym->attr.dimension ||
6081 (sym->ts.type == BT_CHARACTER
6082 && sym->ts.u.cl->length
6083 && sym->ts.u.cl->length->expr_type
6084 != EXPR_CONSTANT);
6085 }
6086 else
6087 {
6088 formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
6089 need_interface_mapping = comp->attr.dimension ||
6090 (comp->ts.type == BT_CHARACTER
6091 && comp->ts.u.cl->length
6092 && comp->ts.u.cl->length->expr_type
6093 != EXPR_CONSTANT);
6094 }
6095
6096 base_object = NULL_TREE;
6097 /* For _vprt->_copy () routines no formal symbol is present. Nevertheless
6098 is the third and fourth argument to such a function call a value
6099 denoting the number of elements to copy (i.e., most of the time the
6100 length of a deferred length string). */
6101 ulim_copy = (formal == NULL)
6102 && UNLIMITED_POLY (sym)
6103 && comp && (strcmp ("_copy", comp->name) == 0);
6104
6105 /* Evaluate the arguments. */
6106 for (arg = args, argc = 0; arg != NULL;
6107 arg = arg->next, formal = formal ? formal->next : NULL, ++argc)
6108 {
6109 bool finalized = false;
6110 tree derived_array = NULL_TREE;
6111
6112 e = arg->expr;
6113 fsym = formal ? formal->sym : NULL;
6114 parm_kind = MISSING;
6115
6116 /* If the procedure requires an explicit interface, the actual
6117 argument is passed according to the corresponding formal
6118 argument. If the corresponding formal argument is a POINTER,
6119 ALLOCATABLE or assumed shape, we do not use g77's calling
6120 convention, and pass the address of the array descriptor
6121 instead. Otherwise we use g77's calling convention, in other words
6122 pass the array data pointer without descriptor. */
6123 bool nodesc_arg = fsym != NULL
6124 && !(fsym->attr.pointer || fsym->attr.allocatable)
6125 && fsym->as
6126 && fsym->as->type != AS_ASSUMED_SHAPE
6127 && fsym->as->type != AS_ASSUMED_RANK;
6128 if (comp)
6129 nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
6130 else
6131 nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
6132
6133 /* Class array expressions are sometimes coming completely unadorned
6134 with either arrayspec or _data component. Correct that here.
6135 OOP-TODO: Move this to the frontend. */
6136 if (e && e->expr_type == EXPR_VARIABLE
6137 && !e->ref
6138 && e->ts.type == BT_CLASS
6139 && (CLASS_DATA (e)->attr.codimension
6140 || CLASS_DATA (e)->attr.dimension))
6141 {
6142 gfc_typespec temp_ts = e->ts;
6143 gfc_add_class_array_ref (e);
6144 e->ts = temp_ts;
6145 }
6146
6147 if (e == NULL)
6148 {
6149 if (se->ignore_optional)
6150 {
6151 /* Some intrinsics have already been resolved to the correct
6152 parameters. */
6153 continue;
6154 }
6155 else if (arg->label)
6156 {
6157 has_alternate_specifier = 1;
6158 continue;
6159 }
6160 else
6161 {
6162 gfc_init_se (&parmse, NULL);
6163
6164 /* For scalar arguments with VALUE attribute which are passed by
6165 value, pass "0" and a hidden argument gives the optional
6166 status. */
6167 if (fsym && fsym->attr.optional && fsym->attr.value
6168 && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
6169 && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
6170 {
6171 parmse.expr = fold_convert (gfc_sym_type (fsym),
6172 integer_zero_node);
6173 vec_safe_push (optionalargs, boolean_false_node);
6174 }
6175 else
6176 {
6177 /* Pass a NULL pointer for an absent arg. */
6178 parmse.expr = null_pointer_node;
6179 gfc_dummy_arg * const dummy_arg = arg->associated_dummy;
6180 if (dummy_arg
6181 && gfc_dummy_arg_get_typespec (*dummy_arg).type
6182 == BT_CHARACTER)
6183 parmse.string_length = build_int_cst (gfc_charlen_type_node,
6184 0);
6185 }
6186 }
6187 }
6188 else if (arg->expr->expr_type == EXPR_NULL
6189 && fsym && !fsym->attr.pointer
6190 && (fsym->ts.type != BT_CLASS
6191 || !CLASS_DATA (fsym)->attr.class_pointer))
6192 {
6193 /* Pass a NULL pointer to denote an absent arg. */
6194 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
6195 && (fsym->ts.type != BT_CLASS
6196 || !CLASS_DATA (fsym)->attr.allocatable));
6197 gfc_init_se (&parmse, NULL);
6198 parmse.expr = null_pointer_node;
6199 if (arg->associated_dummy
6200 && gfc_dummy_arg_get_typespec (*arg->associated_dummy).type
6201 == BT_CHARACTER)
6202 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
6203 }
6204 else if (fsym && fsym->ts.type == BT_CLASS
6205 && e->ts.type == BT_DERIVED)
6206 {
6207 /* The derived type needs to be converted to a temporary
6208 CLASS object. */
6209 gfc_init_se (&parmse, se);
6210 gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
6211 fsym->attr.optional
6212 && e->expr_type == EXPR_VARIABLE
6213 && e->symtree->n.sym->attr.optional,
6214 CLASS_DATA (fsym)->attr.class_pointer
6215 || CLASS_DATA (fsym)->attr.allocatable,
6216 &derived_array);
6217 }
6218 else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS
6219 && e->ts.type != BT_PROCEDURE
6220 && (gfc_expr_attr (e).flavor != FL_PROCEDURE
6221 || gfc_expr_attr (e).proc != PROC_UNKNOWN))
6222 {
6223 /* The intrinsic type needs to be converted to a temporary
6224 CLASS object for the unlimited polymorphic formal. */
6225 gfc_find_vtab (&e->ts);
6226 gfc_init_se (&parmse, se);
6227 gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
6228
6229 }
6230 else if (se->ss && se->ss->info->useflags)
6231 {
6232 gfc_ss *ss;
6233
6234 ss = se->ss;
6235
6236 /* An elemental function inside a scalarized loop. */
6237 gfc_init_se (&parmse, se);
6238 parm_kind = ELEMENTAL;
6239
6240 /* When no fsym is present, ulim_copy is set and this is a third or
6241 fourth argument, use call-by-value instead of by reference to
6242 hand the length properties to the copy routine (i.e., most of the
6243 time this will be a call to a __copy_character_* routine where the
6244 third and fourth arguments are the lengths of a deferred length
6245 char array). */
6246 if ((fsym && fsym->attr.value)
6247 || (ulim_copy && (argc == 2 || argc == 3)))
6248 gfc_conv_expr (&parmse, e);
6249 else
6250 gfc_conv_expr_reference (&parmse, e);
6251
6252 if (e->ts.type == BT_CHARACTER && !e->rank
6253 && e->expr_type == EXPR_FUNCTION)
6254 parmse.expr = build_fold_indirect_ref_loc (input_location,
6255 parmse.expr);
6256
6257 if (fsym && fsym->ts.type == BT_DERIVED
6258 && gfc_is_class_container_ref (e))
6259 {
6260 parmse.expr = gfc_class_data_get (parmse.expr);
6261
6262 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
6263 && e->symtree->n.sym->attr.optional)
6264 {
6265 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
6266 parmse.expr = build3_loc (input_location, COND_EXPR,
6267 TREE_TYPE (parmse.expr),
6268 cond, parmse.expr,
6269 fold_convert (TREE_TYPE (parmse.expr),
6270 null_pointer_node));
6271 }
6272 }
6273
6274 /* If we are passing an absent array as optional dummy to an
6275 elemental procedure, make sure that we pass NULL when the data
6276 pointer is NULL. We need this extra conditional because of
6277 scalarization which passes arrays elements to the procedure,
6278 ignoring the fact that the array can be absent/unallocated/... */
6279 if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
6280 {
6281 tree descriptor_data;
6282
6283 descriptor_data = ss->info->data.array.data;
6284 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
6285 descriptor_data,
6286 fold_convert (TREE_TYPE (descriptor_data),
6287 null_pointer_node));
6288 parmse.expr
6289 = fold_build3_loc (input_location, COND_EXPR,
6290 TREE_TYPE (parmse.expr),
6291 gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
6292 fold_convert (TREE_TYPE (parmse.expr),
6293 null_pointer_node),
6294 parmse.expr);
6295 }
6296
6297 /* The scalarizer does not repackage the reference to a class
6298 array - instead it returns a pointer to the data element. */
6299 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
6300 gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
6301 fsym->attr.intent != INTENT_IN
6302 && (CLASS_DATA (fsym)->attr.class_pointer
6303 || CLASS_DATA (fsym)->attr.allocatable),
6304 fsym->attr.optional
6305 && e->expr_type == EXPR_VARIABLE
6306 && e->symtree->n.sym->attr.optional,
6307 CLASS_DATA (fsym)->attr.class_pointer
6308 || CLASS_DATA (fsym)->attr.allocatable);
6309 }
6310 else
6311 {
6312 bool scalar;
6313 gfc_ss *argss;
6314
6315 gfc_init_se (&parmse, NULL);
6316
6317 /* Check whether the expression is a scalar or not; we cannot use
6318 e->rank as it can be nonzero for functions arguments. */
6319 argss = gfc_walk_expr (e);
6320 scalar = argss == gfc_ss_terminator;
6321 if (!scalar)
6322 gfc_free_ss_chain (argss);
6323
6324 /* Special handling for passing scalar polymorphic coarrays;
6325 otherwise one passes "class->_data.data" instead of "&class". */
6326 if (e->rank == 0 && e->ts.type == BT_CLASS
6327 && fsym && fsym->ts.type == BT_CLASS
6328 && CLASS_DATA (fsym)->attr.codimension
6329 && !CLASS_DATA (fsym)->attr.dimension)
6330 {
6331 gfc_add_class_array_ref (e);
6332 parmse.want_coarray = 1;
6333 scalar = false;
6334 }
6335
6336 /* A scalar or transformational function. */
6337 if (scalar)
6338 {
6339 if (e->expr_type == EXPR_VARIABLE
6340 && e->symtree->n.sym->attr.cray_pointee
6341 && fsym && fsym->attr.flavor == FL_PROCEDURE)
6342 {
6343 /* The Cray pointer needs to be converted to a pointer to
6344 a type given by the expression. */
6345 gfc_conv_expr (&parmse, e);
6346 type = build_pointer_type (TREE_TYPE (parmse.expr));
6347 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
6348 parmse.expr = convert (type, tmp);
6349 }
6350
6351 else if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL))
6352 /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
6353 gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
6354
6355 else if (fsym && fsym->attr.value)
6356 {
6357 if (fsym->ts.type == BT_CHARACTER
6358 && fsym->ts.is_c_interop
6359 && fsym->ns->proc_name != NULL
6360 && fsym->ns->proc_name->attr.is_bind_c)
6361 {
6362 parmse.expr = NULL;
6363 conv_scalar_char_value (fsym, &parmse, &e);
6364 if (parmse.expr == NULL)
6365 gfc_conv_expr (&parmse, e);
6366 }
6367 else
6368 {
6369 gfc_conv_expr (&parmse, e);
6370 if (fsym->attr.optional
6371 && fsym->ts.type != BT_CLASS
6372 && fsym->ts.type != BT_DERIVED)
6373 {
6374 if (e->expr_type != EXPR_VARIABLE
6375 || !e->symtree->n.sym->attr.optional
6376 || e->ref != NULL)
6377 vec_safe_push (optionalargs, boolean_true_node);
6378 else
6379 {
6380 tmp = gfc_conv_expr_present (e->symtree->n.sym);
6381 if (!e->symtree->n.sym->attr.value)
6382 parmse.expr
6383 = fold_build3_loc (input_location, COND_EXPR,
6384 TREE_TYPE (parmse.expr),
6385 tmp, parmse.expr,
6386 fold_convert (TREE_TYPE (parmse.expr),
6387 integer_zero_node));
6388
6389 vec_safe_push (optionalargs,
6390 fold_convert (boolean_type_node,
6391 tmp));
6392 }
6393 }
6394 }
6395 }
6396
6397 else if (arg->name && arg->name[0] == '%')
6398 /* Argument list functions %VAL, %LOC and %REF are signalled
6399 through arg->name. */
6400 conv_arglist_function (&parmse, arg->expr, arg->name);
6401 else if ((e->expr_type == EXPR_FUNCTION)
6402 && ((e->value.function.esym
6403 && e->value.function.esym->result->attr.pointer)
6404 || (!e->value.function.esym
6405 && e->symtree->n.sym->attr.pointer))
6406 && fsym && fsym->attr.target)
6407 /* Make sure the function only gets called once. */
6408 gfc_conv_expr_reference (&parmse, e);
6409 else if (e->expr_type == EXPR_FUNCTION
6410 && e->symtree->n.sym->result
6411 && e->symtree->n.sym->result != e->symtree->n.sym
6412 && e->symtree->n.sym->result->attr.proc_pointer)
6413 {
6414 /* Functions returning procedure pointers. */
6415 gfc_conv_expr (&parmse, e);
6416 if (fsym && fsym->attr.proc_pointer)
6417 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6418 }
6419
6420 else
6421 {
6422 if (e->ts.type == BT_CLASS && fsym
6423 && fsym->ts.type == BT_CLASS
6424 && (!CLASS_DATA (fsym)->as
6425 || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
6426 && CLASS_DATA (e)->attr.codimension)
6427 {
6428 gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
6429 gcc_assert (!CLASS_DATA (fsym)->as);
6430 gfc_add_class_array_ref (e);
6431 parmse.want_coarray = 1;
6432 gfc_conv_expr_reference (&parmse, e);
6433 class_scalar_coarray_to_class (&parmse, e, fsym->ts,
6434 fsym->attr.optional
6435 && e->expr_type == EXPR_VARIABLE);
6436 }
6437 else if (e->ts.type == BT_CLASS && fsym
6438 && fsym->ts.type == BT_CLASS
6439 && !CLASS_DATA (fsym)->as
6440 && !CLASS_DATA (e)->as
6441 && strcmp (fsym->ts.u.derived->name,
6442 e->ts.u.derived->name))
6443 {
6444 type = gfc_typenode_for_spec (&fsym->ts);
6445 var = gfc_create_var (type, fsym->name);
6446 gfc_conv_expr (&parmse, e);
6447 if (fsym->attr.optional
6448 && e->expr_type == EXPR_VARIABLE
6449 && e->symtree->n.sym->attr.optional)
6450 {
6451 stmtblock_t block;
6452 tree cond;
6453 tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6454 cond = fold_build2_loc (input_location, NE_EXPR,
6455 logical_type_node, tmp,
6456 fold_convert (TREE_TYPE (tmp),
6457 null_pointer_node));
6458 gfc_start_block (&block);
6459 gfc_add_modify (&block, var,
6460 fold_build1_loc (input_location,
6461 VIEW_CONVERT_EXPR,
6462 type, parmse.expr));
6463 gfc_add_expr_to_block (&parmse.pre,
6464 fold_build3_loc (input_location,
6465 COND_EXPR, void_type_node,
6466 cond, gfc_finish_block (&block),
6467 build_empty_stmt (input_location)));
6468 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6469 parmse.expr = build3_loc (input_location, COND_EXPR,
6470 TREE_TYPE (parmse.expr),
6471 cond, parmse.expr,
6472 fold_convert (TREE_TYPE (parmse.expr),
6473 null_pointer_node));
6474 }
6475 else
6476 {
6477 /* Since the internal representation of unlimited
6478 polymorphic expressions includes an extra field
6479 that other class objects do not, a cast to the
6480 formal type does not work. */
6481 if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
6482 {
6483 tree efield;
6484
6485 /* Set the _data field. */
6486 tmp = gfc_class_data_get (var);
6487 efield = fold_convert (TREE_TYPE (tmp),
6488 gfc_class_data_get (parmse.expr));
6489 gfc_add_modify (&parmse.pre, tmp, efield);
6490
6491 /* Set the _vptr field. */
6492 tmp = gfc_class_vptr_get (var);
6493 efield = fold_convert (TREE_TYPE (tmp),
6494 gfc_class_vptr_get (parmse.expr));
6495 gfc_add_modify (&parmse.pre, tmp, efield);
6496
6497 /* Set the _len field. */
6498 tmp = gfc_class_len_get (var);
6499 gfc_add_modify (&parmse.pre, tmp,
6500 build_int_cst (TREE_TYPE (tmp), 0));
6501 }
6502 else
6503 {
6504 tmp = fold_build1_loc (input_location,
6505 VIEW_CONVERT_EXPR,
6506 type, parmse.expr);
6507 gfc_add_modify (&parmse.pre, var, tmp);
6508 ;
6509 }
6510 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6511 }
6512 }
6513 else
6514 {
6515 gfc_conv_expr_reference (&parmse, e);
6516
6517 if (fsym
6518 && fsym->attr.intent == INTENT_OUT
6519 && !fsym->attr.allocatable
6520 && !fsym->attr.pointer
6521 && e->expr_type == EXPR_VARIABLE
6522 && e->ref == NULL
6523 && e->symtree
6524 && e->symtree->n.sym
6525 && !e->symtree->n.sym->attr.dimension
6526 && !e->symtree->n.sym->attr.pointer
6527 && !e->symtree->n.sym->attr.allocatable
6528 /* See PR 41453. */
6529 && !e->symtree->n.sym->attr.dummy
6530 /* FIXME - PR 87395 and PR 41453 */
6531 && e->symtree->n.sym->attr.save == SAVE_NONE
6532 && !e->symtree->n.sym->attr.associate_var
6533 && e->ts.type != BT_CHARACTER
6534 && e->ts.type != BT_DERIVED
6535 && e->ts.type != BT_CLASS
6536 && !sym->attr.elemental)
6537 {
6538 tree var;
6539 /* FIXME: This fails if var is passed by reference, see PR
6540 41453. */
6541 var = build_fold_indirect_ref_loc (input_location,
6542 parmse.expr);
6543 tree clobber = build_clobber (TREE_TYPE (var));
6544 gfc_add_modify (&clobbers, var, clobber);
6545 }
6546 }
6547 /* Catch base objects that are not variables. */
6548 if (e->ts.type == BT_CLASS
6549 && e->expr_type != EXPR_VARIABLE
6550 && expr && e == expr->base_expr)
6551 base_object = build_fold_indirect_ref_loc (input_location,
6552 parmse.expr);
6553
6554 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6555 allocated on entry, it must be deallocated. */
6556 if (fsym && fsym->attr.intent == INTENT_OUT
6557 && (fsym->attr.allocatable
6558 || (fsym->ts.type == BT_CLASS
6559 && CLASS_DATA (fsym)->attr.allocatable))
6560 && !is_CFI_desc (fsym, NULL))
6561 {
6562 stmtblock_t block;
6563 tree ptr;
6564
6565 gfc_init_block (&block);
6566 ptr = parmse.expr;
6567 if (e->ts.type == BT_CLASS)
6568 ptr = gfc_class_data_get (ptr);
6569
6570 tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
6571 NULL_TREE, true,
6572 e, e->ts);
6573 gfc_add_expr_to_block (&block, tmp);
6574 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6575 void_type_node, ptr,
6576 null_pointer_node);
6577 gfc_add_expr_to_block (&block, tmp);
6578
6579 if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
6580 {
6581 gfc_add_modify (&block, ptr,
6582 fold_convert (TREE_TYPE (ptr),
6583 null_pointer_node));
6584 gfc_add_expr_to_block (&block, tmp);
6585 }
6586 else if (fsym->ts.type == BT_CLASS)
6587 {
6588 gfc_symbol *vtab;
6589 vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
6590 tmp = gfc_get_symbol_decl (vtab);
6591 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6592 ptr = gfc_class_vptr_get (parmse.expr);
6593 gfc_add_modify (&block, ptr,
6594 fold_convert (TREE_TYPE (ptr), tmp));
6595 gfc_add_expr_to_block (&block, tmp);
6596 }
6597
6598 if (fsym->attr.optional
6599 && e->expr_type == EXPR_VARIABLE
6600 && e->symtree->n.sym->attr.optional)
6601 {
6602 tmp = fold_build3_loc (input_location, COND_EXPR,
6603 void_type_node,
6604 gfc_conv_expr_present (e->symtree->n.sym),
6605 gfc_finish_block (&block),
6606 build_empty_stmt (input_location));
6607 }
6608 else
6609 tmp = gfc_finish_block (&block);
6610
6611 gfc_add_expr_to_block (&se->pre, tmp);
6612 }
6613
6614 /* A class array element needs converting back to be a
6615 class object, if the formal argument is a class object. */
6616 if (fsym && fsym->ts.type == BT_CLASS
6617 && e->ts.type == BT_CLASS
6618 && ((CLASS_DATA (fsym)->as
6619 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
6620 || CLASS_DATA (e)->attr.dimension))
6621 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
6622 fsym->attr.intent != INTENT_IN
6623 && (CLASS_DATA (fsym)->attr.class_pointer
6624 || CLASS_DATA (fsym)->attr.allocatable),
6625 fsym->attr.optional
6626 && e->expr_type == EXPR_VARIABLE
6627 && e->symtree->n.sym->attr.optional,
6628 CLASS_DATA (fsym)->attr.class_pointer
6629 || CLASS_DATA (fsym)->attr.allocatable);
6630
6631 if (fsym && (fsym->ts.type == BT_DERIVED
6632 || fsym->ts.type == BT_ASSUMED)
6633 && e->ts.type == BT_CLASS
6634 && !CLASS_DATA (e)->attr.dimension
6635 && !CLASS_DATA (e)->attr.codimension)
6636 {
6637 parmse.expr = gfc_class_data_get (parmse.expr);
6638 /* The result is a class temporary, whose _data component
6639 must be freed to avoid a memory leak. */
6640 if (e->expr_type == EXPR_FUNCTION
6641 && CLASS_DATA (e)->attr.allocatable)
6642 {
6643 tree zero;
6644
6645 gfc_expr *var;
6646
6647 /* Borrow the function symbol to make a call to
6648 gfc_add_finalizer_call and then restore it. */
6649 tmp = e->symtree->n.sym->backend_decl;
6650 e->symtree->n.sym->backend_decl
6651 = TREE_OPERAND (parmse.expr, 0);
6652 e->symtree->n.sym->attr.flavor = FL_VARIABLE;
6653 var = gfc_lval_expr_from_sym (e->symtree->n.sym);
6654 finalized = gfc_add_finalizer_call (&parmse.post,
6655 var);
6656 gfc_free_expr (var);
6657 e->symtree->n.sym->backend_decl = tmp;
6658 e->symtree->n.sym->attr.flavor = FL_PROCEDURE;
6659
6660 /* Then free the class _data. */
6661 zero = build_int_cst (TREE_TYPE (parmse.expr), 0);
6662 tmp = fold_build2_loc (input_location, NE_EXPR,
6663 logical_type_node,
6664 parmse.expr, zero);
6665 tmp = build3_v (COND_EXPR, tmp,
6666 gfc_call_free (parmse.expr),
6667 build_empty_stmt (input_location));
6668 gfc_add_expr_to_block (&parmse.post, tmp);
6669 gfc_add_modify (&parmse.post, parmse.expr, zero);
6670 }
6671 }
6672
6673 /* Wrap scalar variable in a descriptor. We need to convert
6674 the address of a pointer back to the pointer itself before,
6675 we can assign it to the data field. */
6676
6677 if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
6678 && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
6679 {
6680 tmp = parmse.expr;
6681 if (TREE_CODE (tmp) == ADDR_EXPR)
6682 tmp = TREE_OPERAND (tmp, 0);
6683 parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
6684 fsym->attr);
6685 parmse.expr = gfc_build_addr_expr (NULL_TREE,
6686 parmse.expr);
6687 }
6688 else if (fsym && e->expr_type != EXPR_NULL
6689 && ((fsym->attr.pointer
6690 && fsym->attr.flavor != FL_PROCEDURE)
6691 || (fsym->attr.proc_pointer
6692 && !(e->expr_type == EXPR_VARIABLE
6693 && e->symtree->n.sym->attr.dummy))
6694 || (fsym->attr.proc_pointer
6695 && e->expr_type == EXPR_VARIABLE
6696 && gfc_is_proc_ptr_comp (e))
6697 || (fsym->attr.allocatable
6698 && fsym->attr.flavor != FL_PROCEDURE)))
6699 {
6700 /* Scalar pointer dummy args require an extra level of
6701 indirection. The null pointer already contains
6702 this level of indirection. */
6703 parm_kind = SCALAR_POINTER;
6704 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6705 }
6706 }
6707 }
6708 else if (e->ts.type == BT_CLASS
6709 && fsym && fsym->ts.type == BT_CLASS
6710 && (CLASS_DATA (fsym)->attr.dimension
6711 || CLASS_DATA (fsym)->attr.codimension))
6712 {
6713 /* Pass a class array. */
6714 parmse.use_offset = 1;
6715 gfc_conv_expr_descriptor (&parmse, e);
6716
6717 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6718 allocated on entry, it must be deallocated. */
6719 if (fsym->attr.intent == INTENT_OUT
6720 && CLASS_DATA (fsym)->attr.allocatable)
6721 {
6722 stmtblock_t block;
6723 tree ptr;
6724
6725 gfc_init_block (&block);
6726 ptr = parmse.expr;
6727 ptr = gfc_class_data_get (ptr);
6728
6729 tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
6730 NULL_TREE, NULL_TREE,
6731 NULL_TREE, true, e,
6732 GFC_CAF_COARRAY_NOCOARRAY);
6733 gfc_add_expr_to_block (&block, tmp);
6734 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6735 void_type_node, ptr,
6736 null_pointer_node);
6737 gfc_add_expr_to_block (&block, tmp);
6738 gfc_reset_vptr (&block, e);
6739
6740 if (fsym->attr.optional
6741 && e->expr_type == EXPR_VARIABLE
6742 && (!e->ref
6743 || (e->ref->type == REF_ARRAY
6744 && e->ref->u.ar.type != AR_FULL))
6745 && e->symtree->n.sym->attr.optional)
6746 {
6747 tmp = fold_build3_loc (input_location, COND_EXPR,
6748 void_type_node,
6749 gfc_conv_expr_present (e->symtree->n.sym),
6750 gfc_finish_block (&block),
6751 build_empty_stmt (input_location));
6752 }
6753 else
6754 tmp = gfc_finish_block (&block);
6755
6756 gfc_add_expr_to_block (&se->pre, tmp);
6757 }
6758
6759 /* The conversion does not repackage the reference to a class
6760 array - _data descriptor. */
6761 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
6762 fsym->attr.intent != INTENT_IN
6763 && (CLASS_DATA (fsym)->attr.class_pointer
6764 || CLASS_DATA (fsym)->attr.allocatable),
6765 fsym->attr.optional
6766 && e->expr_type == EXPR_VARIABLE
6767 && e->symtree->n.sym->attr.optional,
6768 CLASS_DATA (fsym)->attr.class_pointer
6769 || CLASS_DATA (fsym)->attr.allocatable);
6770 }
6771 else
6772 {
6773 /* If the argument is a function call that may not create
6774 a temporary for the result, we have to check that we
6775 can do it, i.e. that there is no alias between this
6776 argument and another one. */
6777 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
6778 {
6779 gfc_expr *iarg;
6780 sym_intent intent;
6781
6782 if (fsym != NULL)
6783 intent = fsym->attr.intent;
6784 else
6785 intent = INTENT_UNKNOWN;
6786
6787 if (gfc_check_fncall_dependency (e, intent, sym, args,
6788 NOT_ELEMENTAL))
6789 parmse.force_tmp = 1;
6790
6791 iarg = e->value.function.actual->expr;
6792
6793 /* Temporary needed if aliasing due to host association. */
6794 if (sym->attr.contained
6795 && !sym->attr.pure
6796 && !sym->attr.implicit_pure
6797 && !sym->attr.use_assoc
6798 && iarg->expr_type == EXPR_VARIABLE
6799 && sym->ns == iarg->symtree->n.sym->ns)
6800 parmse.force_tmp = 1;
6801
6802 /* Ditto within module. */
6803 if (sym->attr.use_assoc
6804 && !sym->attr.pure
6805 && !sym->attr.implicit_pure
6806 && iarg->expr_type == EXPR_VARIABLE
6807 && sym->module == iarg->symtree->n.sym->module)
6808 parmse.force_tmp = 1;
6809 }
6810
6811 /* Special case for assumed-rank arrays: when passing an
6812 argument to a nonallocatable/nonpointer dummy, the bounds have
6813 to be reset as otherwise a last-dim ubound of -1 is
6814 indistinguishable from an assumed-size array in the callee. */
6815 if (!sym->attr.is_bind_c && e && fsym && fsym->as
6816 && fsym->as->type == AS_ASSUMED_RANK
6817 && e->rank != -1
6818 && e->expr_type == EXPR_VARIABLE
6819 && ((fsym->ts.type == BT_CLASS
6820 && !CLASS_DATA (fsym)->attr.class_pointer
6821 && !CLASS_DATA (fsym)->attr.allocatable)
6822 || (fsym->ts.type != BT_CLASS
6823 && !fsym->attr.pointer && !fsym->attr.allocatable)))
6824 {
6825 /* Change AR_FULL to a (:,:,:) ref to force bounds update. */
6826 gfc_ref *ref;
6827 for (ref = e->ref; ref->next; ref = ref->next)
6828 ;
6829 if (ref->u.ar.type == AR_FULL
6830 && ref->u.ar.as->type != AS_ASSUMED_SIZE)
6831 ref->u.ar.type = AR_SECTION;
6832 }
6833
6834 if (sym->attr.is_bind_c && e && is_CFI_desc (fsym, NULL))
6835 /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
6836 gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
6837
6838 else if (e->expr_type == EXPR_VARIABLE
6839 && is_subref_array (e)
6840 && !(fsym && fsym->attr.pointer))
6841 /* The actual argument is a component reference to an
6842 array of derived types. In this case, the argument
6843 is converted to a temporary, which is passed and then
6844 written back after the procedure call. */
6845 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6846 fsym ? fsym->attr.intent : INTENT_INOUT,
6847 fsym && fsym->attr.pointer);
6848
6849 else if (e->ts.type == BT_CLASS && CLASS_DATA (e)->as
6850 && CLASS_DATA (e)->as->type == AS_ASSUMED_SIZE
6851 && nodesc_arg && fsym->ts.type == BT_DERIVED)
6852 /* An assumed size class actual argument being passed to
6853 a 'no descriptor' formal argument just requires the
6854 data pointer to be passed. For class dummy arguments
6855 this is stored in the symbol backend decl.. */
6856 parmse.expr = e->symtree->n.sym->backend_decl;
6857
6858 else if (gfc_is_class_array_ref (e, NULL)
6859 && fsym && fsym->ts.type == BT_DERIVED)
6860 /* The actual argument is a component reference to an
6861 array of derived types. In this case, the argument
6862 is converted to a temporary, which is passed and then
6863 written back after the procedure call.
6864 OOP-TODO: Insert code so that if the dynamic type is
6865 the same as the declared type, copy-in/copy-out does
6866 not occur. */
6867 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6868 fsym->attr.intent,
6869 fsym->attr.pointer);
6870
6871 else if (gfc_is_class_array_function (e)
6872 && fsym && fsym->ts.type == BT_DERIVED)
6873 /* See previous comment. For function actual argument,
6874 the write out is not needed so the intent is set as
6875 intent in. */
6876 {
6877 e->must_finalize = 1;
6878 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6879 INTENT_IN, fsym->attr.pointer);
6880 }
6881 else if (fsym && fsym->attr.contiguous
6882 && !gfc_is_simply_contiguous (e, false, true)
6883 && gfc_expr_is_variable (e))
6884 {
6885 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
6886 fsym->attr.intent,
6887 fsym->attr.pointer);
6888 }
6889 else
6890 /* This is where we introduce a temporary to store the
6891 result of a non-lvalue array expression. */
6892 gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
6893 sym->name, NULL);
6894
6895 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6896 allocated on entry, it must be deallocated.
6897 CFI descriptors are handled elsewhere. */
6898 if (fsym && fsym->attr.allocatable
6899 && fsym->attr.intent == INTENT_OUT
6900 && !is_CFI_desc (fsym, NULL))
6901 {
6902 if (fsym->ts.type == BT_DERIVED
6903 && fsym->ts.u.derived->attr.alloc_comp)
6904 {
6905 // deallocate the components first
6906 tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
6907 parmse.expr, e->rank);
6908 /* But check whether dummy argument is optional. */
6909 if (tmp != NULL_TREE
6910 && fsym->attr.optional
6911 && e->expr_type == EXPR_VARIABLE
6912 && e->symtree->n.sym->attr.optional)
6913 {
6914 tree present;
6915 present = gfc_conv_expr_present (e->symtree->n.sym);
6916 tmp = build3_v (COND_EXPR, present, tmp,
6917 build_empty_stmt (input_location));
6918 }
6919 if (tmp != NULL_TREE)
6920 gfc_add_expr_to_block (&se->pre, tmp);
6921 }
6922
6923 tmp = parmse.expr;
6924 /* With bind(C), the actual argument is replaced by a bind-C
6925 descriptor; in this case, the data component arrives here,
6926 which shall not be dereferenced, but still freed and
6927 nullified. */
6928 if (TREE_TYPE(tmp) != pvoid_type_node)
6929 tmp = build_fold_indirect_ref_loc (input_location,
6930 parmse.expr);
6931 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
6932 tmp = gfc_conv_descriptor_data_get (tmp);
6933 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
6934 NULL_TREE, NULL_TREE, true,
6935 e,
6936 GFC_CAF_COARRAY_NOCOARRAY);
6937 if (fsym->attr.optional
6938 && e->expr_type == EXPR_VARIABLE
6939 && e->symtree->n.sym->attr.optional)
6940 tmp = fold_build3_loc (input_location, COND_EXPR,
6941 void_type_node,
6942 gfc_conv_expr_present (e->symtree->n.sym),
6943 tmp, build_empty_stmt (input_location));
6944 gfc_add_expr_to_block (&se->pre, tmp);
6945 }
6946 }
6947 }
6948 /* Special case for an assumed-rank dummy argument. */
6949 if (!sym->attr.is_bind_c && e && fsym && e->rank > 0
6950 && (fsym->ts.type == BT_CLASS
6951 ? (CLASS_DATA (fsym)->as
6952 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
6953 : (fsym->as && fsym->as->type == AS_ASSUMED_RANK)))
6954 {
6955 if (fsym->ts.type == BT_CLASS
6956 ? (CLASS_DATA (fsym)->attr.class_pointer
6957 || CLASS_DATA (fsym)->attr.allocatable)
6958 : (fsym->attr.pointer || fsym->attr.allocatable))
6959 {
6960 /* Unallocated allocatable arrays and unassociated pointer
6961 arrays need their dtype setting if they are argument
6962 associated with assumed rank dummies to set the rank. */
6963 set_dtype_for_unallocated (&parmse, e);
6964 }
6965 else if (e->expr_type == EXPR_VARIABLE
6966 && e->symtree->n.sym->attr.dummy
6967 && (e->ts.type == BT_CLASS
6968 ? (e->ref && e->ref->next
6969 && e->ref->next->type == REF_ARRAY
6970 && e->ref->next->u.ar.type == AR_FULL
6971 && e->ref->next->u.ar.as->type == AS_ASSUMED_SIZE)
6972 : (e->ref && e->ref->type == REF_ARRAY
6973 && e->ref->u.ar.type == AR_FULL
6974 && e->ref->u.ar.as->type == AS_ASSUMED_SIZE)))
6975 {
6976 /* Assumed-size actual to assumed-rank dummy requires
6977 dim[rank-1].ubound = -1. */
6978 tree minus_one;
6979 tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
6980 if (fsym->ts.type == BT_CLASS)
6981 tmp = gfc_class_data_get (tmp);
6982 minus_one = build_int_cst (gfc_array_index_type, -1);
6983 gfc_conv_descriptor_ubound_set (&parmse.pre, tmp,
6984 gfc_rank_cst[e->rank - 1],
6985 minus_one);
6986 }
6987 }
6988
6989 /* The case with fsym->attr.optional is that of a user subroutine
6990 with an interface indicating an optional argument. When we call
6991 an intrinsic subroutine, however, fsym is NULL, but we might still
6992 have an optional argument, so we proceed to the substitution
6993 just in case. */
6994 if (e && (fsym == NULL || fsym->attr.optional))
6995 {
6996 /* If an optional argument is itself an optional dummy argument,
6997 check its presence and substitute a null if absent. This is
6998 only needed when passing an array to an elemental procedure
6999 as then array elements are accessed - or no NULL pointer is
7000 allowed and a "1" or "0" should be passed if not present.
7001 When passing a non-array-descriptor full array to a
7002 non-array-descriptor dummy, no check is needed. For
7003 array-descriptor actual to array-descriptor dummy, see
7004 PR 41911 for why a check has to be inserted.
7005 fsym == NULL is checked as intrinsics required the descriptor
7006 but do not always set fsym.
7007 Also, it is necessary to pass a NULL pointer to library routines
7008 which usually ignore optional arguments, so they can handle
7009 these themselves. */
7010 if (e->expr_type == EXPR_VARIABLE
7011 && e->symtree->n.sym->attr.optional
7012 && (((e->rank != 0 && elemental_proc)
7013 || e->representation.length || e->ts.type == BT_CHARACTER
7014 || (e->rank != 0
7015 && (fsym == NULL
7016 || (fsym->as
7017 && (fsym->as->type == AS_ASSUMED_SHAPE
7018 || fsym->as->type == AS_ASSUMED_RANK
7019 || fsym->as->type == AS_DEFERRED)))))
7020 || se->ignore_optional))
7021 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
7022 e->representation.length);
7023 }
7024
7025 if (fsym && e)
7026 {
7027 /* Obtain the character length of an assumed character length
7028 length procedure from the typespec. */
7029 if (fsym->ts.type == BT_CHARACTER
7030 && parmse.string_length == NULL_TREE
7031 && e->ts.type == BT_PROCEDURE
7032 && e->symtree->n.sym->ts.type == BT_CHARACTER
7033 && e->symtree->n.sym->ts.u.cl->length != NULL
7034 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
7035 {
7036 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
7037 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
7038 }
7039 }
7040
7041 if (fsym && need_interface_mapping && e)
7042 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
7043
7044 gfc_add_block_to_block (&se->pre, &parmse.pre);
7045 gfc_add_block_to_block (&post, &parmse.post);
7046
7047 /* Allocated allocatable components of derived types must be
7048 deallocated for non-variable scalars, array arguments to elemental
7049 procedures, and array arguments with descriptor to non-elemental
7050 procedures. As bounds information for descriptorless arrays is no
7051 longer available here, they are dealt with in trans-array.cc
7052 (gfc_conv_array_parameter). */
7053 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
7054 && e->ts.u.derived->attr.alloc_comp
7055 && (e->rank == 0 || elemental_proc || !nodesc_arg)
7056 && !expr_may_alias_variables (e, elemental_proc))
7057 {
7058 int parm_rank;
7059 /* It is known the e returns a structure type with at least one
7060 allocatable component. When e is a function, ensure that the
7061 function is called once only by using a temporary variable. */
7062 if (!DECL_P (parmse.expr))
7063 parmse.expr = gfc_evaluate_now_loc (input_location,
7064 parmse.expr, &se->pre);
7065
7066 if (fsym && fsym->attr.value)
7067 tmp = parmse.expr;
7068 else
7069 tmp = build_fold_indirect_ref_loc (input_location,
7070 parmse.expr);
7071
7072 parm_rank = e->rank;
7073 switch (parm_kind)
7074 {
7075 case (ELEMENTAL):
7076 case (SCALAR):
7077 parm_rank = 0;
7078 break;
7079
7080 case (SCALAR_POINTER):
7081 tmp = build_fold_indirect_ref_loc (input_location,
7082 tmp);
7083 break;
7084 }
7085
7086 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
7087 {
7088 /* The derived type is passed to gfc_deallocate_alloc_comp.
7089 Therefore, class actuals can be handled correctly but derived
7090 types passed to class formals need the _data component. */
7091 tmp = gfc_class_data_get (tmp);
7092 if (!CLASS_DATA (fsym)->attr.dimension)
7093 tmp = build_fold_indirect_ref_loc (input_location, tmp);
7094 }
7095
7096 if (e->expr_type == EXPR_OP
7097 && e->value.op.op == INTRINSIC_PARENTHESES
7098 && e->value.op.op1->expr_type == EXPR_VARIABLE)
7099 {
7100 tree local_tmp;
7101 local_tmp = gfc_evaluate_now (tmp, &se->pre);
7102 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp,
7103 parm_rank, 0);
7104 gfc_add_expr_to_block (&se->post, local_tmp);
7105 }
7106
7107 if (!finalized && !e->must_finalize)
7108 {
7109 bool scalar_res_outside_loop;
7110 scalar_res_outside_loop = e->expr_type == EXPR_FUNCTION
7111 && parm_rank == 0
7112 && parmse.loop;
7113
7114 /* Scalars passed to an assumed rank argument are converted to
7115 a descriptor. Obtain the data field before deallocating any
7116 allocatable components. */
7117 if (parm_rank == 0 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
7118 tmp = gfc_conv_descriptor_data_get (tmp);
7119
7120 if (scalar_res_outside_loop)
7121 {
7122 /* Go through the ss chain to find the argument and use
7123 the stored value. */
7124 gfc_ss *tmp_ss = parmse.loop->ss;
7125 for (; tmp_ss; tmp_ss = tmp_ss->next)
7126 if (tmp_ss->info
7127 && tmp_ss->info->expr == e
7128 && tmp_ss->info->data.scalar.value != NULL_TREE)
7129 {
7130 tmp = tmp_ss->info->data.scalar.value;
7131 break;
7132 }
7133 }
7134
7135 STRIP_NOPS (tmp);
7136
7137 if (derived_array != NULL_TREE)
7138 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived,
7139 derived_array,
7140 parm_rank);
7141 else if ((e->ts.type == BT_CLASS
7142 && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
7143 || e->ts.type == BT_DERIVED)
7144 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp,
7145 parm_rank);
7146 else if (e->ts.type == BT_CLASS)
7147 tmp = gfc_deallocate_alloc_comp (CLASS_DATA (e)->ts.u.derived,
7148 tmp, parm_rank);
7149
7150 if (scalar_res_outside_loop)
7151 gfc_add_expr_to_block (&parmse.loop->post, tmp);
7152 else
7153 gfc_prepend_expr_to_block (&post, tmp);
7154 }
7155 }
7156
7157 /* Add argument checking of passing an unallocated/NULL actual to
7158 a nonallocatable/nonpointer dummy. */
7159
7160 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
7161 {
7162 symbol_attribute attr;
7163 char *msg;
7164 tree cond;
7165 tree tmp;
7166 symbol_attribute fsym_attr;
7167
7168 if (fsym)
7169 {
7170 if (fsym->ts.type == BT_CLASS)
7171 {
7172 fsym_attr = CLASS_DATA (fsym)->attr;
7173 fsym_attr.pointer = fsym_attr.class_pointer;
7174 }
7175 else
7176 fsym_attr = fsym->attr;
7177 }
7178
7179 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
7180 attr = gfc_expr_attr (e);
7181 else
7182 goto end_pointer_check;
7183
7184 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
7185 allocatable to an optional dummy, cf. 12.5.2.12. */
7186 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
7187 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
7188 goto end_pointer_check;
7189
7190 if (attr.optional)
7191 {
7192 /* If the actual argument is an optional pointer/allocatable and
7193 the formal argument takes an nonpointer optional value,
7194 it is invalid to pass a non-present argument on, even
7195 though there is no technical reason for this in gfortran.
7196 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
7197 tree present, null_ptr, type;
7198
7199 if (attr.allocatable
7200 && (fsym == NULL || !fsym_attr.allocatable))
7201 msg = xasprintf ("Allocatable actual argument '%s' is not "
7202 "allocated or not present",
7203 e->symtree->n.sym->name);
7204 else if (attr.pointer
7205 && (fsym == NULL || !fsym_attr.pointer))
7206 msg = xasprintf ("Pointer actual argument '%s' is not "
7207 "associated or not present",
7208 e->symtree->n.sym->name);
7209 else if (attr.proc_pointer && !e->value.function.actual
7210 && (fsym == NULL || !fsym_attr.proc_pointer))
7211 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
7212 "associated or not present",
7213 e->symtree->n.sym->name);
7214 else
7215 goto end_pointer_check;
7216
7217 present = gfc_conv_expr_present (e->symtree->n.sym);
7218 type = TREE_TYPE (present);
7219 present = fold_build2_loc (input_location, EQ_EXPR,
7220 logical_type_node, present,
7221 fold_convert (type,
7222 null_pointer_node));
7223 type = TREE_TYPE (parmse.expr);
7224 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
7225 logical_type_node, parmse.expr,
7226 fold_convert (type,
7227 null_pointer_node));
7228 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
7229 logical_type_node, present, null_ptr);
7230 }
7231 else
7232 {
7233 if (attr.allocatable
7234 && (fsym == NULL || !fsym_attr.allocatable))
7235 msg = xasprintf ("Allocatable actual argument '%s' is not "
7236 "allocated", e->symtree->n.sym->name);
7237 else if (attr.pointer
7238 && (fsym == NULL || !fsym_attr.pointer))
7239 msg = xasprintf ("Pointer actual argument '%s' is not "
7240 "associated", e->symtree->n.sym->name);
7241 else if (attr.proc_pointer && !e->value.function.actual
7242 && (fsym == NULL || !fsym_attr.proc_pointer))
7243 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
7244 "associated", e->symtree->n.sym->name);
7245 else
7246 goto end_pointer_check;
7247
7248 tmp = parmse.expr;
7249 if (fsym && fsym->ts.type == BT_CLASS)
7250 {
7251 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
7252 tmp = build_fold_indirect_ref_loc (input_location, tmp);
7253 tmp = gfc_class_data_get (tmp);
7254 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
7255 tmp = gfc_conv_descriptor_data_get (tmp);
7256 }
7257
7258 /* If the argument is passed by value, we need to strip the
7259 INDIRECT_REF. */
7260 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
7261 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
7262
7263 cond = fold_build2_loc (input_location, EQ_EXPR,
7264 logical_type_node, tmp,
7265 fold_convert (TREE_TYPE (tmp),
7266 null_pointer_node));
7267 }
7268
7269 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
7270 msg);
7271 free (msg);
7272 }
7273 end_pointer_check:
7274
7275 /* Deferred length dummies pass the character length by reference
7276 so that the value can be returned. */
7277 if (parmse.string_length && fsym && fsym->ts.deferred)
7278 {
7279 if (INDIRECT_REF_P (parmse.string_length))
7280 /* In chains of functions/procedure calls the string_length already
7281 is a pointer to the variable holding the length. Therefore
7282 remove the deref on call. */
7283 parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
7284 else
7285 {
7286 tmp = parmse.string_length;
7287 if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF)
7288 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
7289 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
7290 }
7291 }
7292
7293 /* Character strings are passed as two parameters, a length and a
7294 pointer - except for Bind(c) which only passes the pointer.
7295 An unlimited polymorphic formal argument likewise does not
7296 need the length. */
7297 if (parmse.string_length != NULL_TREE
7298 && !sym->attr.is_bind_c
7299 && !(fsym && UNLIMITED_POLY (fsym)))
7300 vec_safe_push (stringargs, parmse.string_length);
7301
7302 /* When calling __copy for character expressions to unlimited
7303 polymorphic entities, the dst argument needs a string length. */
7304 if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
7305 && startswith (sym->name, "__vtab_CHARACTER")
7306 && arg->next && arg->next->expr
7307 && (arg->next->expr->ts.type == BT_DERIVED
7308 || arg->next->expr->ts.type == BT_CLASS)
7309 && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
7310 vec_safe_push (stringargs, parmse.string_length);
7311
7312 /* For descriptorless coarrays and assumed-shape coarray dummies, we
7313 pass the token and the offset as additional arguments. */
7314 if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
7315 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
7316 && !fsym->attr.allocatable)
7317 || (fsym->ts.type == BT_CLASS
7318 && CLASS_DATA (fsym)->attr.codimension
7319 && !CLASS_DATA (fsym)->attr.allocatable)))
7320 {
7321 /* Token and offset. */
7322 vec_safe_push (stringargs, null_pointer_node);
7323 vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
7324 gcc_assert (fsym->attr.optional);
7325 }
7326 else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
7327 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
7328 && !fsym->attr.allocatable)
7329 || (fsym->ts.type == BT_CLASS
7330 && CLASS_DATA (fsym)->attr.codimension
7331 && !CLASS_DATA (fsym)->attr.allocatable)))
7332 {
7333 tree caf_decl, caf_type;
7334 tree offset, tmp2;
7335
7336 caf_decl = gfc_get_tree_for_caf_expr (e);
7337 caf_type = TREE_TYPE (caf_decl);
7338
7339 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
7340 && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
7341 || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
7342 tmp = gfc_conv_descriptor_token (caf_decl);
7343 else if (DECL_LANG_SPECIFIC (caf_decl)
7344 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
7345 tmp = GFC_DECL_TOKEN (caf_decl);
7346 else
7347 {
7348 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
7349 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
7350 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
7351 }
7352
7353 vec_safe_push (stringargs, tmp);
7354
7355 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
7356 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
7357 offset = build_int_cst (gfc_array_index_type, 0);
7358 else if (DECL_LANG_SPECIFIC (caf_decl)
7359 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
7360 offset = GFC_DECL_CAF_OFFSET (caf_decl);
7361 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
7362 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
7363 else
7364 offset = build_int_cst (gfc_array_index_type, 0);
7365
7366 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
7367 tmp = gfc_conv_descriptor_data_get (caf_decl);
7368 else
7369 {
7370 gcc_assert (POINTER_TYPE_P (caf_type));
7371 tmp = caf_decl;
7372 }
7373
7374 tmp2 = fsym->ts.type == BT_CLASS
7375 ? gfc_class_data_get (parmse.expr) : parmse.expr;
7376 if ((fsym->ts.type != BT_CLASS
7377 && (fsym->as->type == AS_ASSUMED_SHAPE
7378 || fsym->as->type == AS_ASSUMED_RANK))
7379 || (fsym->ts.type == BT_CLASS
7380 && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
7381 || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
7382 {
7383 if (fsym->ts.type == BT_CLASS)
7384 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
7385 else
7386 {
7387 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
7388 tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
7389 }
7390 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
7391 tmp2 = gfc_conv_descriptor_data_get (tmp2);
7392 }
7393 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
7394 tmp2 = gfc_conv_descriptor_data_get (tmp2);
7395 else
7396 {
7397 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
7398 }
7399
7400 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7401 gfc_array_index_type,
7402 fold_convert (gfc_array_index_type, tmp2),
7403 fold_convert (gfc_array_index_type, tmp));
7404 offset = fold_build2_loc (input_location, PLUS_EXPR,
7405 gfc_array_index_type, offset, tmp);
7406
7407 vec_safe_push (stringargs, offset);
7408 }
7409
7410 vec_safe_push (arglist, parmse.expr);
7411 }
7412 gfc_add_block_to_block (&se->pre, &clobbers);
7413 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
7414
7415 if (comp)
7416 ts = comp->ts;
7417 else if (sym->ts.type == BT_CLASS)
7418 ts = CLASS_DATA (sym)->ts;
7419 else
7420 ts = sym->ts;
7421
7422 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
7423 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
7424 else if (ts.type == BT_CHARACTER)
7425 {
7426 if (ts.u.cl->length == NULL)
7427 {
7428 /* Assumed character length results are not allowed by C418 of the 2003
7429 standard and are trapped in resolve.cc; except in the case of SPREAD
7430 (and other intrinsics?) and dummy functions. In the case of SPREAD,
7431 we take the character length of the first argument for the result.
7432 For dummies, we have to look through the formal argument list for
7433 this function and use the character length found there.
7434 Likewise, we handle the case of deferred-length character dummy
7435 arguments to intrinsics that determine the characteristics of
7436 the result, which cannot be deferred-length. */
7437 if (expr->value.function.isym)
7438 ts.deferred = false;
7439 if (ts.deferred)
7440 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
7441 else if (!sym->attr.dummy)
7442 cl.backend_decl = (*stringargs)[0];
7443 else
7444 {
7445 formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
7446 for (; formal; formal = formal->next)
7447 if (strcmp (formal->sym->name, sym->name) == 0)
7448 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
7449 }
7450 len = cl.backend_decl;
7451 }
7452 else
7453 {
7454 tree tmp;
7455
7456 /* Calculate the length of the returned string. */
7457 gfc_init_se (&parmse, NULL);
7458 if (need_interface_mapping)
7459 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
7460 else
7461 gfc_conv_expr (&parmse, ts.u.cl->length);
7462 gfc_add_block_to_block (&se->pre, &parmse.pre);
7463 gfc_add_block_to_block (&se->post, &parmse.post);
7464 tmp = parmse.expr;
7465 /* TODO: It would be better to have the charlens as
7466 gfc_charlen_type_node already when the interface is
7467 created instead of converting it here (see PR 84615). */
7468 tmp = fold_build2_loc (input_location, MAX_EXPR,
7469 gfc_charlen_type_node,
7470 fold_convert (gfc_charlen_type_node, tmp),
7471 build_zero_cst (gfc_charlen_type_node));
7472 cl.backend_decl = tmp;
7473 }
7474
7475 /* Set up a charlen structure for it. */
7476 cl.next = NULL;
7477 cl.length = NULL;
7478 ts.u.cl = &cl;
7479
7480 len = cl.backend_decl;
7481 }
7482
7483 byref = (comp && (comp->attr.dimension
7484 || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
7485 || (!comp && gfc_return_by_reference (sym));
7486 if (byref)
7487 {
7488 if (se->direct_byref)
7489 {
7490 /* Sometimes, too much indirection can be applied; e.g. for
7491 function_result = array_valued_recursive_function. */
7492 if (TREE_TYPE (TREE_TYPE (se->expr))
7493 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
7494 && GFC_DESCRIPTOR_TYPE_P
7495 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
7496 se->expr = build_fold_indirect_ref_loc (input_location,
7497 se->expr);
7498
7499 /* If the lhs of an assignment x = f(..) is allocatable and
7500 f2003 is allowed, we must do the automatic reallocation.
7501 TODO - deal with intrinsics, without using a temporary. */
7502 if (flag_realloc_lhs
7503 && se->ss && se->ss->loop_chain
7504 && se->ss->loop_chain->is_alloc_lhs
7505 && !expr->value.function.isym
7506 && sym->result->as != NULL)
7507 {
7508 /* Evaluate the bounds of the result, if known. */
7509 gfc_set_loop_bounds_from_array_spec (&mapping, se,
7510 sym->result->as);
7511
7512 /* Perform the automatic reallocation. */
7513 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
7514 expr, NULL);
7515 gfc_add_expr_to_block (&se->pre, tmp);
7516
7517 /* Pass the temporary as the first argument. */
7518 result = info->descriptor;
7519 }
7520 else
7521 result = build_fold_indirect_ref_loc (input_location,
7522 se->expr);
7523 vec_safe_push (retargs, se->expr);
7524 }
7525 else if (comp && comp->attr.dimension)
7526 {
7527 gcc_assert (se->loop && info);
7528
7529 /* Set the type of the array. */
7530 tmp = gfc_typenode_for_spec (&comp->ts);
7531 gcc_assert (se->ss->dimen == se->loop->dimen);
7532
7533 /* Evaluate the bounds of the result, if known. */
7534 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
7535
7536 /* If the lhs of an assignment x = f(..) is allocatable and
7537 f2003 is allowed, we must not generate the function call
7538 here but should just send back the results of the mapping.
7539 This is signalled by the function ss being flagged. */
7540 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
7541 {
7542 gfc_free_interface_mapping (&mapping);
7543 return has_alternate_specifier;
7544 }
7545
7546 /* Create a temporary to store the result. In case the function
7547 returns a pointer, the temporary will be a shallow copy and
7548 mustn't be deallocated. */
7549 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
7550 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
7551 tmp, NULL_TREE, false,
7552 !comp->attr.pointer, callee_alloc,
7553 &se->ss->info->expr->where);
7554
7555 /* Pass the temporary as the first argument. */
7556 result = info->descriptor;
7557 tmp = gfc_build_addr_expr (NULL_TREE, result);
7558 vec_safe_push (retargs, tmp);
7559 }
7560 else if (!comp && sym->result->attr.dimension)
7561 {
7562 gcc_assert (se->loop && info);
7563
7564 /* Set the type of the array. */
7565 tmp = gfc_typenode_for_spec (&ts);
7566 gcc_assert (se->ss->dimen == se->loop->dimen);
7567
7568 /* Evaluate the bounds of the result, if known. */
7569 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
7570
7571 /* If the lhs of an assignment x = f(..) is allocatable and
7572 f2003 is allowed, we must not generate the function call
7573 here but should just send back the results of the mapping.
7574 This is signalled by the function ss being flagged. */
7575 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
7576 {
7577 gfc_free_interface_mapping (&mapping);
7578 return has_alternate_specifier;
7579 }
7580
7581 /* Create a temporary to store the result. In case the function
7582 returns a pointer, the temporary will be a shallow copy and
7583 mustn't be deallocated. */
7584 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
7585 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
7586 tmp, NULL_TREE, false,
7587 !sym->attr.pointer, callee_alloc,
7588 &se->ss->info->expr->where);
7589
7590 /* Pass the temporary as the first argument. */
7591 result = info->descriptor;
7592 tmp = gfc_build_addr_expr (NULL_TREE, result);
7593 vec_safe_push (retargs, tmp);
7594 }
7595 else if (ts.type == BT_CHARACTER)
7596 {
7597 /* Pass the string length. */
7598 type = gfc_get_character_type (ts.kind, ts.u.cl);
7599 type = build_pointer_type (type);
7600
7601 /* Emit a DECL_EXPR for the VLA type. */
7602 tmp = TREE_TYPE (type);
7603 if (TYPE_SIZE (tmp)
7604 && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST)
7605 {
7606 tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp);
7607 DECL_ARTIFICIAL (tmp) = 1;
7608 DECL_IGNORED_P (tmp) = 1;
7609 tmp = fold_build1_loc (input_location, DECL_EXPR,
7610 TREE_TYPE (tmp), tmp);
7611 gfc_add_expr_to_block (&se->pre, tmp);
7612 }
7613
7614 /* Return an address to a char[0:len-1]* temporary for
7615 character pointers. */
7616 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7617 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
7618 {
7619 var = gfc_create_var (type, "pstr");
7620
7621 if ((!comp && sym->attr.allocatable)
7622 || (comp && comp->attr.allocatable))
7623 {
7624 gfc_add_modify (&se->pre, var,
7625 fold_convert (TREE_TYPE (var),
7626 null_pointer_node));
7627 tmp = gfc_call_free (var);
7628 gfc_add_expr_to_block (&se->post, tmp);
7629 }
7630
7631 /* Provide an address expression for the function arguments. */
7632 var = gfc_build_addr_expr (NULL_TREE, var);
7633 }
7634 else
7635 var = gfc_conv_string_tmp (se, type, len);
7636
7637 vec_safe_push (retargs, var);
7638 }
7639 else
7640 {
7641 gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
7642
7643 type = gfc_get_complex_type (ts.kind);
7644 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
7645 vec_safe_push (retargs, var);
7646 }
7647
7648 /* Add the string length to the argument list. */
7649 if (ts.type == BT_CHARACTER && ts.deferred)
7650 {
7651 tmp = len;
7652 if (!VAR_P (tmp))
7653 tmp = gfc_evaluate_now (len, &se->pre);
7654 TREE_STATIC (tmp) = 1;
7655 gfc_add_modify (&se->pre, tmp,
7656 build_int_cst (TREE_TYPE (tmp), 0));
7657 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
7658 vec_safe_push (retargs, tmp);
7659 }
7660 else if (ts.type == BT_CHARACTER)
7661 vec_safe_push (retargs, len);
7662 }
7663 gfc_free_interface_mapping (&mapping);
7664
7665 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
7666 arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
7667 + vec_safe_length (stringargs) + vec_safe_length (append_args));
7668 vec_safe_reserve (retargs, arglen);
7669
7670 /* Add the return arguments. */
7671 vec_safe_splice (retargs, arglist);
7672
7673 /* Add the hidden present status for optional+value to the arguments. */
7674 vec_safe_splice (retargs, optionalargs);
7675
7676 /* Add the hidden string length parameters to the arguments. */
7677 vec_safe_splice (retargs, stringargs);
7678
7679 /* We may want to append extra arguments here. This is used e.g. for
7680 calls to libgfortran_matmul_??, which need extra information. */
7681 vec_safe_splice (retargs, append_args);
7682
7683 arglist = retargs;
7684
7685 /* Generate the actual call. */
7686 if (base_object == NULL_TREE)
7687 conv_function_val (se, sym, expr, args);
7688 else
7689 conv_base_obj_fcn_val (se, base_object, expr);
7690
7691 /* If there are alternate return labels, function type should be
7692 integer. Can't modify the type in place though, since it can be shared
7693 with other functions. For dummy arguments, the typing is done to
7694 this result, even if it has to be repeated for each call. */
7695 if (has_alternate_specifier
7696 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
7697 {
7698 if (!sym->attr.dummy)
7699 {
7700 TREE_TYPE (sym->backend_decl)
7701 = build_function_type (integer_type_node,
7702 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
7703 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
7704 }
7705 else
7706 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
7707 }
7708
7709 fntype = TREE_TYPE (TREE_TYPE (se->expr));
7710 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
7711
7712 /* Allocatable scalar function results must be freed and nullified
7713 after use. This necessitates the creation of a temporary to
7714 hold the result to prevent duplicate calls. */
7715 if (!byref && sym->ts.type != BT_CHARACTER
7716 && ((sym->attr.allocatable && !sym->attr.dimension && !comp)
7717 || (comp && comp->attr.allocatable && !comp->attr.dimension)))
7718 {
7719 tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
7720 gfc_add_modify (&se->pre, tmp, se->expr);
7721 se->expr = tmp;
7722 tmp = gfc_call_free (tmp);
7723 gfc_add_expr_to_block (&post, tmp);
7724 gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
7725 }
7726
7727 /* If we have a pointer function, but we don't want a pointer, e.g.
7728 something like
7729 x = f()
7730 where f is pointer valued, we have to dereference the result. */
7731 if (!se->want_pointer && !byref
7732 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7733 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
7734 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
7735
7736 /* f2c calling conventions require a scalar default real function to
7737 return a double precision result. Convert this back to default
7738 real. We only care about the cases that can happen in Fortran 77.
7739 */
7740 if (flag_f2c && sym->ts.type == BT_REAL
7741 && sym->ts.kind == gfc_default_real_kind
7742 && !sym->attr.always_explicit)
7743 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
7744
7745 /* A pure function may still have side-effects - it may modify its
7746 parameters. */
7747 TREE_SIDE_EFFECTS (se->expr) = 1;
7748 #if 0
7749 if (!sym->attr.pure)
7750 TREE_SIDE_EFFECTS (se->expr) = 1;
7751 #endif
7752
7753 if (byref)
7754 {
7755 /* Add the function call to the pre chain. There is no expression. */
7756 gfc_add_expr_to_block (&se->pre, se->expr);
7757 se->expr = NULL_TREE;
7758
7759 if (!se->direct_byref)
7760 {
7761 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
7762 {
7763 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
7764 {
7765 /* Check the data pointer hasn't been modified. This would
7766 happen in a function returning a pointer. */
7767 tmp = gfc_conv_descriptor_data_get (info->descriptor);
7768 tmp = fold_build2_loc (input_location, NE_EXPR,
7769 logical_type_node,
7770 tmp, info->data);
7771 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
7772 gfc_msg_fault);
7773 }
7774 se->expr = info->descriptor;
7775 /* Bundle in the string length. */
7776 se->string_length = len;
7777 }
7778 else if (ts.type == BT_CHARACTER)
7779 {
7780 /* Dereference for character pointer results. */
7781 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7782 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
7783 se->expr = build_fold_indirect_ref_loc (input_location, var);
7784 else
7785 se->expr = var;
7786
7787 se->string_length = len;
7788 }
7789 else
7790 {
7791 gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
7792 se->expr = build_fold_indirect_ref_loc (input_location, var);
7793 }
7794 }
7795 }
7796
7797 /* Associate the rhs class object's meta-data with the result, when the
7798 result is a temporary. */
7799 if (args && args->expr && args->expr->ts.type == BT_CLASS
7800 && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result)
7801 && !GFC_CLASS_TYPE_P (TREE_TYPE (result)))
7802 {
7803 gfc_se parmse;
7804 gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr);
7805
7806 gfc_init_se (&parmse, NULL);
7807 parmse.data_not_needed = 1;
7808 gfc_conv_expr (&parmse, class_expr);
7809 if (!DECL_LANG_SPECIFIC (result))
7810 gfc_allocate_lang_decl (result);
7811 GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr;
7812 gfc_free_expr (class_expr);
7813 /* -fcheck= can add diagnostic code, which has to be placed before
7814 the call. */
7815 if (parmse.pre.head != NULL)
7816 gfc_add_expr_to_block (&se->pre, parmse.pre.head);
7817 gcc_assert (parmse.post.head == NULL_TREE);
7818 }
7819
7820 /* Follow the function call with the argument post block. */
7821 if (byref)
7822 {
7823 gfc_add_block_to_block (&se->pre, &post);
7824
7825 /* Transformational functions of derived types with allocatable
7826 components must have the result allocatable components copied when the
7827 argument is actually given. */
7828 arg = expr->value.function.actual;
7829 if (result && arg && expr->rank
7830 && expr->value.function.isym
7831 && expr->value.function.isym->transformational
7832 && arg->expr
7833 && arg->expr->ts.type == BT_DERIVED
7834 && arg->expr->ts.u.derived->attr.alloc_comp)
7835 {
7836 tree tmp2;
7837 /* Copy the allocatable components. We have to use a
7838 temporary here to prevent source allocatable components
7839 from being corrupted. */
7840 tmp2 = gfc_evaluate_now (result, &se->pre);
7841 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
7842 result, tmp2, expr->rank, 0);
7843 gfc_add_expr_to_block (&se->pre, tmp);
7844 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
7845 expr->rank);
7846 gfc_add_expr_to_block (&se->pre, tmp);
7847
7848 /* Finally free the temporary's data field. */
7849 tmp = gfc_conv_descriptor_data_get (tmp2);
7850 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
7851 NULL_TREE, NULL_TREE, true,
7852 NULL, GFC_CAF_COARRAY_NOCOARRAY);
7853 gfc_add_expr_to_block (&se->pre, tmp);
7854 }
7855 }
7856 else
7857 {
7858 /* For a function with a class array result, save the result as
7859 a temporary, set the info fields needed by the scalarizer and
7860 call the finalization function of the temporary. Note that the
7861 nullification of allocatable components needed by the result
7862 is done in gfc_trans_assignment_1. */
7863 if (expr && ((gfc_is_class_array_function (expr)
7864 && se->ss && se->ss->loop)
7865 || gfc_is_alloc_class_scalar_function (expr))
7866 && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
7867 && expr->must_finalize)
7868 {
7869 tree final_fndecl;
7870 tree is_final;
7871 int n;
7872 if (se->ss && se->ss->loop)
7873 {
7874 gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
7875 se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
7876 tmp = gfc_class_data_get (se->expr);
7877 info->descriptor = tmp;
7878 info->data = gfc_conv_descriptor_data_get (tmp);
7879 info->offset = gfc_conv_descriptor_offset_get (tmp);
7880 for (n = 0; n < se->ss->loop->dimen; n++)
7881 {
7882 tree dim = gfc_rank_cst[n];
7883 se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
7884 se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
7885 }
7886 }
7887 else
7888 {
7889 /* TODO Eliminate the doubling of temporaries. This
7890 one is necessary to ensure no memory leakage. */
7891 se->expr = gfc_evaluate_now (se->expr, &se->pre);
7892 tmp = gfc_class_data_get (se->expr);
7893 tmp = gfc_conv_scalar_to_descriptor (se, tmp,
7894 CLASS_DATA (expr->value.function.esym->result)->attr);
7895 }
7896
7897 if ((gfc_is_class_array_function (expr)
7898 || gfc_is_alloc_class_scalar_function (expr))
7899 && CLASS_DATA (expr->value.function.esym->result)->attr.pointer)
7900 goto no_finalization;
7901
7902 final_fndecl = gfc_class_vtab_final_get (se->expr);
7903 is_final = fold_build2_loc (input_location, NE_EXPR,
7904 logical_type_node,
7905 final_fndecl,
7906 fold_convert (TREE_TYPE (final_fndecl),
7907 null_pointer_node));
7908 final_fndecl = build_fold_indirect_ref_loc (input_location,
7909 final_fndecl);
7910 tmp = build_call_expr_loc (input_location,
7911 final_fndecl, 3,
7912 gfc_build_addr_expr (NULL, tmp),
7913 gfc_class_vtab_size_get (se->expr),
7914 boolean_false_node);
7915 tmp = fold_build3_loc (input_location, COND_EXPR,
7916 void_type_node, is_final, tmp,
7917 build_empty_stmt (input_location));
7918
7919 if (se->ss && se->ss->loop)
7920 {
7921 gfc_prepend_expr_to_block (&se->ss->loop->post, tmp);
7922 tmp = fold_build2_loc (input_location, NE_EXPR,
7923 logical_type_node,
7924 info->data,
7925 fold_convert (TREE_TYPE (info->data),
7926 null_pointer_node));
7927 tmp = fold_build3_loc (input_location, COND_EXPR,
7928 void_type_node, tmp,
7929 gfc_call_free (info->data),
7930 build_empty_stmt (input_location));
7931 gfc_add_expr_to_block (&se->ss->loop->post, tmp);
7932 }
7933 else
7934 {
7935 tree classdata;
7936 gfc_prepend_expr_to_block (&se->post, tmp);
7937 classdata = gfc_class_data_get (se->expr);
7938 tmp = fold_build2_loc (input_location, NE_EXPR,
7939 logical_type_node,
7940 classdata,
7941 fold_convert (TREE_TYPE (classdata),
7942 null_pointer_node));
7943 tmp = fold_build3_loc (input_location, COND_EXPR,
7944 void_type_node, tmp,
7945 gfc_call_free (classdata),
7946 build_empty_stmt (input_location));
7947 gfc_add_expr_to_block (&se->post, tmp);
7948 }
7949 }
7950
7951 no_finalization:
7952 gfc_add_block_to_block (&se->post, &post);
7953 }
7954
7955 return has_alternate_specifier;
7956 }
7957
7958
7959 /* Fill a character string with spaces. */
7960
7961 static tree
fill_with_spaces(tree start,tree type,tree size)7962 fill_with_spaces (tree start, tree type, tree size)
7963 {
7964 stmtblock_t block, loop;
7965 tree i, el, exit_label, cond, tmp;
7966
7967 /* For a simple char type, we can call memset(). */
7968 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
7969 return build_call_expr_loc (input_location,
7970 builtin_decl_explicit (BUILT_IN_MEMSET),
7971 3, start,
7972 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
7973 lang_hooks.to_target_charset (' ')),
7974 fold_convert (size_type_node, size));
7975
7976 /* Otherwise, we use a loop:
7977 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
7978 *el = (type) ' ';
7979 */
7980
7981 /* Initialize variables. */
7982 gfc_init_block (&block);
7983 i = gfc_create_var (sizetype, "i");
7984 gfc_add_modify (&block, i, fold_convert (sizetype, size));
7985 el = gfc_create_var (build_pointer_type (type), "el");
7986 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
7987 exit_label = gfc_build_label_decl (NULL_TREE);
7988 TREE_USED (exit_label) = 1;
7989
7990
7991 /* Loop body. */
7992 gfc_init_block (&loop);
7993
7994 /* Exit condition. */
7995 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i,
7996 build_zero_cst (sizetype));
7997 tmp = build1_v (GOTO_EXPR, exit_label);
7998 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
7999 build_empty_stmt (input_location));
8000 gfc_add_expr_to_block (&loop, tmp);
8001
8002 /* Assignment. */
8003 gfc_add_modify (&loop,
8004 fold_build1_loc (input_location, INDIRECT_REF, type, el),
8005 build_int_cst (type, lang_hooks.to_target_charset (' ')));
8006
8007 /* Increment loop variables. */
8008 gfc_add_modify (&loop, i,
8009 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
8010 TYPE_SIZE_UNIT (type)));
8011 gfc_add_modify (&loop, el,
8012 fold_build_pointer_plus_loc (input_location,
8013 el, TYPE_SIZE_UNIT (type)));
8014
8015 /* Making the loop... actually loop! */
8016 tmp = gfc_finish_block (&loop);
8017 tmp = build1_v (LOOP_EXPR, tmp);
8018 gfc_add_expr_to_block (&block, tmp);
8019
8020 /* The exit label. */
8021 tmp = build1_v (LABEL_EXPR, exit_label);
8022 gfc_add_expr_to_block (&block, tmp);
8023
8024
8025 return gfc_finish_block (&block);
8026 }
8027
8028
8029 /* Generate code to copy a string. */
8030
8031 void
gfc_trans_string_copy(stmtblock_t * block,tree dlength,tree dest,int dkind,tree slength,tree src,int skind)8032 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
8033 int dkind, tree slength, tree src, int skind)
8034 {
8035 tree tmp, dlen, slen;
8036 tree dsc;
8037 tree ssc;
8038 tree cond;
8039 tree cond2;
8040 tree tmp2;
8041 tree tmp3;
8042 tree tmp4;
8043 tree chartype;
8044 stmtblock_t tempblock;
8045
8046 gcc_assert (dkind == skind);
8047
8048 if (slength != NULL_TREE)
8049 {
8050 slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block);
8051 ssc = gfc_string_to_single_character (slen, src, skind);
8052 }
8053 else
8054 {
8055 slen = build_one_cst (gfc_charlen_type_node);
8056 ssc = src;
8057 }
8058
8059 if (dlength != NULL_TREE)
8060 {
8061 dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block);
8062 dsc = gfc_string_to_single_character (dlen, dest, dkind);
8063 }
8064 else
8065 {
8066 dlen = build_one_cst (gfc_charlen_type_node);
8067 dsc = dest;
8068 }
8069
8070 /* Assign directly if the types are compatible. */
8071 if (dsc != NULL_TREE && ssc != NULL_TREE
8072 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
8073 {
8074 gfc_add_modify (block, dsc, ssc);
8075 return;
8076 }
8077
8078 /* The string copy algorithm below generates code like
8079
8080 if (destlen > 0)
8081 {
8082 if (srclen < destlen)
8083 {
8084 memmove (dest, src, srclen);
8085 // Pad with spaces.
8086 memset (&dest[srclen], ' ', destlen - srclen);
8087 }
8088 else
8089 {
8090 // Truncate if too long.
8091 memmove (dest, src, destlen);
8092 }
8093 }
8094 */
8095
8096 /* Do nothing if the destination length is zero. */
8097 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen,
8098 build_zero_cst (TREE_TYPE (dlen)));
8099
8100 /* For non-default character kinds, we have to multiply the string
8101 length by the base type size. */
8102 chartype = gfc_get_char_type (dkind);
8103 slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen),
8104 slen,
8105 fold_convert (TREE_TYPE (slen),
8106 TYPE_SIZE_UNIT (chartype)));
8107 dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen),
8108 dlen,
8109 fold_convert (TREE_TYPE (dlen),
8110 TYPE_SIZE_UNIT (chartype)));
8111
8112 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
8113 dest = fold_convert (pvoid_type_node, dest);
8114 else
8115 dest = gfc_build_addr_expr (pvoid_type_node, dest);
8116
8117 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
8118 src = fold_convert (pvoid_type_node, src);
8119 else
8120 src = gfc_build_addr_expr (pvoid_type_node, src);
8121
8122 /* Truncate string if source is too long. */
8123 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
8124 dlen);
8125
8126 /* Pre-evaluate pointers unless one of the IF arms will be optimized away. */
8127 if (!CONSTANT_CLASS_P (cond2))
8128 {
8129 dest = gfc_evaluate_now (dest, block);
8130 src = gfc_evaluate_now (src, block);
8131 }
8132
8133 /* Copy and pad with spaces. */
8134 tmp3 = build_call_expr_loc (input_location,
8135 builtin_decl_explicit (BUILT_IN_MEMMOVE),
8136 3, dest, src,
8137 fold_convert (size_type_node, slen));
8138
8139 /* Wstringop-overflow appears at -O3 even though this warning is not
8140 explicitly available in fortran nor can it be switched off. If the
8141 source length is a constant, its negative appears as a very large
8142 postive number and triggers the warning in BUILTIN_MEMSET. Fixing
8143 the result of the MINUS_EXPR suppresses this spurious warning. */
8144 tmp = fold_build2_loc (input_location, MINUS_EXPR,
8145 TREE_TYPE(dlen), dlen, slen);
8146 if (slength && TREE_CONSTANT (slength))
8147 tmp = gfc_evaluate_now (tmp, block);
8148
8149 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
8150 tmp4 = fill_with_spaces (tmp4, chartype, tmp);
8151
8152 gfc_init_block (&tempblock);
8153 gfc_add_expr_to_block (&tempblock, tmp3);
8154 gfc_add_expr_to_block (&tempblock, tmp4);
8155 tmp3 = gfc_finish_block (&tempblock);
8156
8157 /* The truncated memmove if the slen >= dlen. */
8158 tmp2 = build_call_expr_loc (input_location,
8159 builtin_decl_explicit (BUILT_IN_MEMMOVE),
8160 3, dest, src,
8161 fold_convert (size_type_node, dlen));
8162
8163 /* The whole copy_string function is there. */
8164 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
8165 tmp3, tmp2);
8166 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
8167 build_empty_stmt (input_location));
8168 gfc_add_expr_to_block (block, tmp);
8169 }
8170
8171
8172 /* Translate a statement function.
8173 The value of a statement function reference is obtained by evaluating the
8174 expression using the values of the actual arguments for the values of the
8175 corresponding dummy arguments. */
8176
8177 static void
gfc_conv_statement_function(gfc_se * se,gfc_expr * expr)8178 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
8179 {
8180 gfc_symbol *sym;
8181 gfc_symbol *fsym;
8182 gfc_formal_arglist *fargs;
8183 gfc_actual_arglist *args;
8184 gfc_se lse;
8185 gfc_se rse;
8186 gfc_saved_var *saved_vars;
8187 tree *temp_vars;
8188 tree type;
8189 tree tmp;
8190 int n;
8191
8192 sym = expr->symtree->n.sym;
8193 args = expr->value.function.actual;
8194 gfc_init_se (&lse, NULL);
8195 gfc_init_se (&rse, NULL);
8196
8197 n = 0;
8198 for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
8199 n++;
8200 saved_vars = XCNEWVEC (gfc_saved_var, n);
8201 temp_vars = XCNEWVEC (tree, n);
8202
8203 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8204 fargs = fargs->next, n++)
8205 {
8206 /* Each dummy shall be specified, explicitly or implicitly, to be
8207 scalar. */
8208 gcc_assert (fargs->sym->attr.dimension == 0);
8209 fsym = fargs->sym;
8210
8211 if (fsym->ts.type == BT_CHARACTER)
8212 {
8213 /* Copy string arguments. */
8214 tree arglen;
8215
8216 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
8217 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
8218
8219 /* Create a temporary to hold the value. */
8220 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
8221 fsym->ts.u.cl->backend_decl
8222 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
8223
8224 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
8225 temp_vars[n] = gfc_create_var (type, fsym->name);
8226
8227 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8228
8229 gfc_conv_expr (&rse, args->expr);
8230 gfc_conv_string_parameter (&rse);
8231 gfc_add_block_to_block (&se->pre, &lse.pre);
8232 gfc_add_block_to_block (&se->pre, &rse.pre);
8233
8234 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
8235 rse.string_length, rse.expr, fsym->ts.kind);
8236 gfc_add_block_to_block (&se->pre, &lse.post);
8237 gfc_add_block_to_block (&se->pre, &rse.post);
8238 }
8239 else
8240 {
8241 /* For everything else, just evaluate the expression. */
8242
8243 /* Create a temporary to hold the value. */
8244 type = gfc_typenode_for_spec (&fsym->ts);
8245 temp_vars[n] = gfc_create_var (type, fsym->name);
8246
8247 gfc_conv_expr (&lse, args->expr);
8248
8249 gfc_add_block_to_block (&se->pre, &lse.pre);
8250 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
8251 gfc_add_block_to_block (&se->pre, &lse.post);
8252 }
8253
8254 args = args->next;
8255 }
8256
8257 /* Use the temporary variables in place of the real ones. */
8258 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8259 fargs = fargs->next, n++)
8260 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
8261
8262 gfc_conv_expr (se, sym->value);
8263
8264 if (sym->ts.type == BT_CHARACTER)
8265 {
8266 gfc_conv_const_charlen (sym->ts.u.cl);
8267
8268 /* Force the expression to the correct length. */
8269 if (!INTEGER_CST_P (se->string_length)
8270 || tree_int_cst_lt (se->string_length,
8271 sym->ts.u.cl->backend_decl))
8272 {
8273 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
8274 tmp = gfc_create_var (type, sym->name);
8275 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
8276 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
8277 sym->ts.kind, se->string_length, se->expr,
8278 sym->ts.kind);
8279 se->expr = tmp;
8280 }
8281 se->string_length = sym->ts.u.cl->backend_decl;
8282 }
8283
8284 /* Restore the original variables. */
8285 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
8286 fargs = fargs->next, n++)
8287 gfc_restore_sym (fargs->sym, &saved_vars[n]);
8288 free (temp_vars);
8289 free (saved_vars);
8290 }
8291
8292
8293 /* Translate a function expression. */
8294
8295 static void
gfc_conv_function_expr(gfc_se * se,gfc_expr * expr)8296 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
8297 {
8298 gfc_symbol *sym;
8299
8300 if (expr->value.function.isym)
8301 {
8302 gfc_conv_intrinsic_function (se, expr);
8303 return;
8304 }
8305
8306 /* expr.value.function.esym is the resolved (specific) function symbol for
8307 most functions. However this isn't set for dummy procedures. */
8308 sym = expr->value.function.esym;
8309 if (!sym)
8310 sym = expr->symtree->n.sym;
8311
8312 /* The IEEE_ARITHMETIC functions are caught here. */
8313 if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
8314 if (gfc_conv_ieee_arithmetic_function (se, expr))
8315 return;
8316
8317 /* We distinguish statement functions from general functions to improve
8318 runtime performance. */
8319 if (sym->attr.proc == PROC_ST_FUNCTION)
8320 {
8321 gfc_conv_statement_function (se, expr);
8322 return;
8323 }
8324
8325 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
8326 NULL);
8327 }
8328
8329
8330 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
8331
8332 static bool
is_zero_initializer_p(gfc_expr * expr)8333 is_zero_initializer_p (gfc_expr * expr)
8334 {
8335 if (expr->expr_type != EXPR_CONSTANT)
8336 return false;
8337
8338 /* We ignore constants with prescribed memory representations for now. */
8339 if (expr->representation.string)
8340 return false;
8341
8342 switch (expr->ts.type)
8343 {
8344 case BT_INTEGER:
8345 return mpz_cmp_si (expr->value.integer, 0) == 0;
8346
8347 case BT_REAL:
8348 return mpfr_zero_p (expr->value.real)
8349 && MPFR_SIGN (expr->value.real) >= 0;
8350
8351 case BT_LOGICAL:
8352 return expr->value.logical == 0;
8353
8354 case BT_COMPLEX:
8355 return mpfr_zero_p (mpc_realref (expr->value.complex))
8356 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
8357 && mpfr_zero_p (mpc_imagref (expr->value.complex))
8358 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
8359
8360 default:
8361 break;
8362 }
8363 return false;
8364 }
8365
8366
8367 static void
gfc_conv_array_constructor_expr(gfc_se * se,gfc_expr * expr)8368 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
8369 {
8370 gfc_ss *ss;
8371
8372 ss = se->ss;
8373 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
8374 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
8375
8376 gfc_conv_tmp_array_ref (se);
8377 }
8378
8379
8380 /* Build a static initializer. EXPR is the expression for the initial value.
8381 The other parameters describe the variable of the component being
8382 initialized. EXPR may be null. */
8383
8384 tree
gfc_conv_initializer(gfc_expr * expr,gfc_typespec * ts,tree type,bool array,bool pointer,bool procptr)8385 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
8386 bool array, bool pointer, bool procptr)
8387 {
8388 gfc_se se;
8389
8390 if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
8391 && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
8392 && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
8393 return build_constructor (type, NULL);
8394
8395 if (!(expr || pointer || procptr))
8396 return NULL_TREE;
8397
8398 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
8399 (these are the only two iso_c_binding derived types that can be
8400 used as initialization expressions). If so, we need to modify
8401 the 'expr' to be that for a (void *). */
8402 if (expr != NULL && expr->ts.type == BT_DERIVED
8403 && expr->ts.is_iso_c && expr->ts.u.derived)
8404 {
8405 if (TREE_CODE (type) == ARRAY_TYPE)
8406 return build_constructor (type, NULL);
8407 else if (POINTER_TYPE_P (type))
8408 return build_int_cst (type, 0);
8409 else
8410 gcc_unreachable ();
8411 }
8412
8413 if (array && !procptr)
8414 {
8415 tree ctor;
8416 /* Arrays need special handling. */
8417 if (pointer)
8418 ctor = gfc_build_null_descriptor (type);
8419 /* Special case assigning an array to zero. */
8420 else if (is_zero_initializer_p (expr))
8421 ctor = build_constructor (type, NULL);
8422 else
8423 ctor = gfc_conv_array_initializer (type, expr);
8424 TREE_STATIC (ctor) = 1;
8425 return ctor;
8426 }
8427 else if (pointer || procptr)
8428 {
8429 if (ts->type == BT_CLASS && !procptr)
8430 {
8431 gfc_init_se (&se, NULL);
8432 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
8433 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8434 TREE_STATIC (se.expr) = 1;
8435 return se.expr;
8436 }
8437 else if (!expr || expr->expr_type == EXPR_NULL)
8438 return fold_convert (type, null_pointer_node);
8439 else
8440 {
8441 gfc_init_se (&se, NULL);
8442 se.want_pointer = 1;
8443 gfc_conv_expr (&se, expr);
8444 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
8445 return se.expr;
8446 }
8447 }
8448 else
8449 {
8450 switch (ts->type)
8451 {
8452 case_bt_struct:
8453 case BT_CLASS:
8454 gfc_init_se (&se, NULL);
8455 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
8456 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
8457 else
8458 gfc_conv_structure (&se, expr, 1);
8459 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8460 TREE_STATIC (se.expr) = 1;
8461 return se.expr;
8462
8463 case BT_CHARACTER:
8464 if (expr->expr_type == EXPR_CONSTANT)
8465 {
8466 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl, expr);
8467 TREE_STATIC (ctor) = 1;
8468 return ctor;
8469 }
8470
8471 /* Fallthrough. */
8472 default:
8473 gfc_init_se (&se, NULL);
8474 gfc_conv_constant (&se, expr);
8475 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
8476 return se.expr;
8477 }
8478 }
8479 }
8480
8481 static tree
gfc_trans_subarray_assign(tree dest,gfc_component * cm,gfc_expr * expr)8482 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
8483 {
8484 gfc_se rse;
8485 gfc_se lse;
8486 gfc_ss *rss;
8487 gfc_ss *lss;
8488 gfc_array_info *lss_array;
8489 stmtblock_t body;
8490 stmtblock_t block;
8491 gfc_loopinfo loop;
8492 int n;
8493 tree tmp;
8494
8495 gfc_start_block (&block);
8496
8497 /* Initialize the scalarizer. */
8498 gfc_init_loopinfo (&loop);
8499
8500 gfc_init_se (&lse, NULL);
8501 gfc_init_se (&rse, NULL);
8502
8503 /* Walk the rhs. */
8504 rss = gfc_walk_expr (expr);
8505 if (rss == gfc_ss_terminator)
8506 /* The rhs is scalar. Add a ss for the expression. */
8507 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
8508
8509 /* Create a SS for the destination. */
8510 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
8511 GFC_SS_COMPONENT);
8512 lss_array = &lss->info->data.array;
8513 lss_array->shape = gfc_get_shape (cm->as->rank);
8514 lss_array->descriptor = dest;
8515 lss_array->data = gfc_conv_array_data (dest);
8516 lss_array->offset = gfc_conv_array_offset (dest);
8517 for (n = 0; n < cm->as->rank; n++)
8518 {
8519 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
8520 lss_array->stride[n] = gfc_index_one_node;
8521
8522 mpz_init (lss_array->shape[n]);
8523 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
8524 cm->as->lower[n]->value.integer);
8525 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
8526 }
8527
8528 /* Associate the SS with the loop. */
8529 gfc_add_ss_to_loop (&loop, lss);
8530 gfc_add_ss_to_loop (&loop, rss);
8531
8532 /* Calculate the bounds of the scalarization. */
8533 gfc_conv_ss_startstride (&loop);
8534
8535 /* Setup the scalarizing loops. */
8536 gfc_conv_loop_setup (&loop, &expr->where);
8537
8538 /* Setup the gfc_se structures. */
8539 gfc_copy_loopinfo_to_se (&lse, &loop);
8540 gfc_copy_loopinfo_to_se (&rse, &loop);
8541
8542 rse.ss = rss;
8543 gfc_mark_ss_chain_used (rss, 1);
8544 lse.ss = lss;
8545 gfc_mark_ss_chain_used (lss, 1);
8546
8547 /* Start the scalarized loop body. */
8548 gfc_start_scalarized_body (&loop, &body);
8549
8550 gfc_conv_tmp_array_ref (&lse);
8551 if (cm->ts.type == BT_CHARACTER)
8552 lse.string_length = cm->ts.u.cl->backend_decl;
8553
8554 gfc_conv_expr (&rse, expr);
8555
8556 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
8557 gfc_add_expr_to_block (&body, tmp);
8558
8559 gcc_assert (rse.ss == gfc_ss_terminator);
8560
8561 /* Generate the copying loops. */
8562 gfc_trans_scalarizing_loops (&loop, &body);
8563
8564 /* Wrap the whole thing up. */
8565 gfc_add_block_to_block (&block, &loop.pre);
8566 gfc_add_block_to_block (&block, &loop.post);
8567
8568 gcc_assert (lss_array->shape != NULL);
8569 gfc_free_shape (&lss_array->shape, cm->as->rank);
8570 gfc_cleanup_loop (&loop);
8571
8572 return gfc_finish_block (&block);
8573 }
8574
8575
8576 static tree
gfc_trans_alloc_subarray_assign(tree dest,gfc_component * cm,gfc_expr * expr)8577 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
8578 gfc_expr * expr)
8579 {
8580 gfc_se se;
8581 stmtblock_t block;
8582 tree offset;
8583 int n;
8584 tree tmp;
8585 tree tmp2;
8586 gfc_array_spec *as;
8587 gfc_expr *arg = NULL;
8588
8589 gfc_start_block (&block);
8590 gfc_init_se (&se, NULL);
8591
8592 /* Get the descriptor for the expressions. */
8593 se.want_pointer = 0;
8594 gfc_conv_expr_descriptor (&se, expr);
8595 gfc_add_block_to_block (&block, &se.pre);
8596 gfc_add_modify (&block, dest, se.expr);
8597
8598 /* Deal with arrays of derived types with allocatable components. */
8599 if (gfc_bt_struct (cm->ts.type)
8600 && cm->ts.u.derived->attr.alloc_comp)
8601 // TODO: Fix caf_mode
8602 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
8603 se.expr, dest,
8604 cm->as->rank, 0);
8605 else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
8606 && CLASS_DATA(cm)->attr.allocatable)
8607 {
8608 if (cm->ts.u.derived->attr.alloc_comp)
8609 // TODO: Fix caf_mode
8610 tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
8611 se.expr, dest,
8612 expr->rank, 0);
8613 else
8614 {
8615 tmp = TREE_TYPE (dest);
8616 tmp = gfc_duplicate_allocatable (dest, se.expr,
8617 tmp, expr->rank, NULL_TREE);
8618 }
8619 }
8620 else
8621 tmp = gfc_duplicate_allocatable (dest, se.expr,
8622 TREE_TYPE(cm->backend_decl),
8623 cm->as->rank, NULL_TREE);
8624
8625 gfc_add_expr_to_block (&block, tmp);
8626 gfc_add_block_to_block (&block, &se.post);
8627
8628 if (expr->expr_type != EXPR_VARIABLE)
8629 gfc_conv_descriptor_data_set (&block, se.expr,
8630 null_pointer_node);
8631
8632 /* We need to know if the argument of a conversion function is a
8633 variable, so that the correct lower bound can be used. */
8634 if (expr->expr_type == EXPR_FUNCTION
8635 && expr->value.function.isym
8636 && expr->value.function.isym->conversion
8637 && expr->value.function.actual->expr
8638 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
8639 arg = expr->value.function.actual->expr;
8640
8641 /* Obtain the array spec of full array references. */
8642 if (arg)
8643 as = gfc_get_full_arrayspec_from_expr (arg);
8644 else
8645 as = gfc_get_full_arrayspec_from_expr (expr);
8646
8647 /* Shift the lbound and ubound of temporaries to being unity,
8648 rather than zero, based. Always calculate the offset. */
8649 offset = gfc_conv_descriptor_offset_get (dest);
8650 gfc_add_modify (&block, offset, gfc_index_zero_node);
8651 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
8652
8653 for (n = 0; n < expr->rank; n++)
8654 {
8655 tree span;
8656 tree lbound;
8657
8658 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
8659 TODO It looks as if gfc_conv_expr_descriptor should return
8660 the correct bounds and that the following should not be
8661 necessary. This would simplify gfc_conv_intrinsic_bound
8662 as well. */
8663 if (as && as->lower[n])
8664 {
8665 gfc_se lbse;
8666 gfc_init_se (&lbse, NULL);
8667 gfc_conv_expr (&lbse, as->lower[n]);
8668 gfc_add_block_to_block (&block, &lbse.pre);
8669 lbound = gfc_evaluate_now (lbse.expr, &block);
8670 }
8671 else if (as && arg)
8672 {
8673 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
8674 lbound = gfc_conv_descriptor_lbound_get (tmp,
8675 gfc_rank_cst[n]);
8676 }
8677 else if (as)
8678 lbound = gfc_conv_descriptor_lbound_get (dest,
8679 gfc_rank_cst[n]);
8680 else
8681 lbound = gfc_index_one_node;
8682
8683 lbound = fold_convert (gfc_array_index_type, lbound);
8684
8685 /* Shift the bounds and set the offset accordingly. */
8686 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
8687 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8688 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
8689 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
8690 span, lbound);
8691 gfc_conv_descriptor_ubound_set (&block, dest,
8692 gfc_rank_cst[n], tmp);
8693 gfc_conv_descriptor_lbound_set (&block, dest,
8694 gfc_rank_cst[n], lbound);
8695
8696 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
8697 gfc_conv_descriptor_lbound_get (dest,
8698 gfc_rank_cst[n]),
8699 gfc_conv_descriptor_stride_get (dest,
8700 gfc_rank_cst[n]));
8701 gfc_add_modify (&block, tmp2, tmp);
8702 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8703 offset, tmp2);
8704 gfc_conv_descriptor_offset_set (&block, dest, tmp);
8705 }
8706
8707 if (arg)
8708 {
8709 /* If a conversion expression has a null data pointer
8710 argument, nullify the allocatable component. */
8711 tree non_null_expr;
8712 tree null_expr;
8713
8714 if (arg->symtree->n.sym->attr.allocatable
8715 || arg->symtree->n.sym->attr.pointer)
8716 {
8717 non_null_expr = gfc_finish_block (&block);
8718 gfc_start_block (&block);
8719 gfc_conv_descriptor_data_set (&block, dest,
8720 null_pointer_node);
8721 null_expr = gfc_finish_block (&block);
8722 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
8723 tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
8724 fold_convert (TREE_TYPE (tmp), null_pointer_node));
8725 return build3_v (COND_EXPR, tmp,
8726 null_expr, non_null_expr);
8727 }
8728 }
8729
8730 return gfc_finish_block (&block);
8731 }
8732
8733
8734 /* Allocate or reallocate scalar component, as necessary. */
8735
8736 static void
alloc_scalar_allocatable_for_subcomponent_assignment(stmtblock_t * block,tree comp,gfc_component * cm,gfc_expr * expr2,gfc_symbol * sym)8737 alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
8738 tree comp,
8739 gfc_component *cm,
8740 gfc_expr *expr2,
8741 gfc_symbol *sym)
8742 {
8743 tree tmp;
8744 tree ptr;
8745 tree size;
8746 tree size_in_bytes;
8747 tree lhs_cl_size = NULL_TREE;
8748
8749 if (!comp)
8750 return;
8751
8752 if (!expr2 || expr2->rank)
8753 return;
8754
8755 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
8756
8757 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8758 {
8759 char name[GFC_MAX_SYMBOL_LEN+9];
8760 gfc_component *strlen;
8761 /* Use the rhs string length and the lhs element size. */
8762 gcc_assert (expr2->ts.type == BT_CHARACTER);
8763 if (!expr2->ts.u.cl->backend_decl)
8764 {
8765 gfc_conv_string_length (expr2->ts.u.cl, expr2, block);
8766 gcc_assert (expr2->ts.u.cl->backend_decl);
8767 }
8768
8769 size = expr2->ts.u.cl->backend_decl;
8770
8771 /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
8772 component. */
8773 sprintf (name, "_%s_length", cm->name);
8774 strlen = gfc_find_component (sym, name, true, true, NULL);
8775 lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
8776 gfc_charlen_type_node,
8777 TREE_OPERAND (comp, 0),
8778 strlen->backend_decl, NULL_TREE);
8779
8780 tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
8781 tmp = TYPE_SIZE_UNIT (tmp);
8782 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
8783 TREE_TYPE (tmp), tmp,
8784 fold_convert (TREE_TYPE (tmp), size));
8785 }
8786 else if (cm->ts.type == BT_CLASS)
8787 {
8788 gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED);
8789 if (expr2->ts.type == BT_DERIVED)
8790 {
8791 tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
8792 size = TYPE_SIZE_UNIT (tmp);
8793 }
8794 else
8795 {
8796 gfc_expr *e2vtab;
8797 gfc_se se;
8798 e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
8799 gfc_add_vptr_component (e2vtab);
8800 gfc_add_size_component (e2vtab);
8801 gfc_init_se (&se, NULL);
8802 gfc_conv_expr (&se, e2vtab);
8803 gfc_add_block_to_block (block, &se.pre);
8804 size = fold_convert (size_type_node, se.expr);
8805 gfc_free_expr (e2vtab);
8806 }
8807 size_in_bytes = size;
8808 }
8809 else
8810 {
8811 /* Otherwise use the length in bytes of the rhs. */
8812 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
8813 size_in_bytes = size;
8814 }
8815
8816 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
8817 size_in_bytes, size_one_node);
8818
8819 if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
8820 {
8821 tmp = build_call_expr_loc (input_location,
8822 builtin_decl_explicit (BUILT_IN_CALLOC),
8823 2, build_one_cst (size_type_node),
8824 size_in_bytes);
8825 tmp = fold_convert (TREE_TYPE (comp), tmp);
8826 gfc_add_modify (block, comp, tmp);
8827 }
8828 else
8829 {
8830 tmp = build_call_expr_loc (input_location,
8831 builtin_decl_explicit (BUILT_IN_MALLOC),
8832 1, size_in_bytes);
8833 if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
8834 ptr = gfc_class_data_get (comp);
8835 else
8836 ptr = comp;
8837 tmp = fold_convert (TREE_TYPE (ptr), tmp);
8838 gfc_add_modify (block, ptr, tmp);
8839 }
8840
8841 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8842 /* Update the lhs character length. */
8843 gfc_add_modify (block, lhs_cl_size,
8844 fold_convert (TREE_TYPE (lhs_cl_size), size));
8845 }
8846
8847
8848 /* Assign a single component of a derived type constructor. */
8849
8850 static tree
gfc_trans_subcomponent_assign(tree dest,gfc_component * cm,gfc_expr * expr,gfc_symbol * sym,bool init)8851 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
8852 gfc_symbol *sym, bool init)
8853 {
8854 gfc_se se;
8855 gfc_se lse;
8856 stmtblock_t block;
8857 tree tmp;
8858 tree vtab;
8859
8860 gfc_start_block (&block);
8861
8862 if (cm->attr.pointer || cm->attr.proc_pointer)
8863 {
8864 /* Only care about pointers here, not about allocatables. */
8865 gfc_init_se (&se, NULL);
8866 /* Pointer component. */
8867 if ((cm->attr.dimension || cm->attr.codimension)
8868 && !cm->attr.proc_pointer)
8869 {
8870 /* Array pointer. */
8871 if (expr->expr_type == EXPR_NULL)
8872 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8873 else
8874 {
8875 se.direct_byref = 1;
8876 se.expr = dest;
8877 gfc_conv_expr_descriptor (&se, expr);
8878 gfc_add_block_to_block (&block, &se.pre);
8879 gfc_add_block_to_block (&block, &se.post);
8880 }
8881 }
8882 else
8883 {
8884 /* Scalar pointers. */
8885 se.want_pointer = 1;
8886 gfc_conv_expr (&se, expr);
8887 gfc_add_block_to_block (&block, &se.pre);
8888
8889 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
8890 && expr->symtree->n.sym->attr.dummy)
8891 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
8892
8893 gfc_add_modify (&block, dest,
8894 fold_convert (TREE_TYPE (dest), se.expr));
8895 gfc_add_block_to_block (&block, &se.post);
8896 }
8897 }
8898 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
8899 {
8900 /* NULL initialization for CLASS components. */
8901 tmp = gfc_trans_structure_assign (dest,
8902 gfc_class_initializer (&cm->ts, expr),
8903 false);
8904 gfc_add_expr_to_block (&block, tmp);
8905 }
8906 else if ((cm->attr.dimension || cm->attr.codimension)
8907 && !cm->attr.proc_pointer)
8908 {
8909 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
8910 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8911 else if (cm->attr.allocatable || cm->attr.pdt_array)
8912 {
8913 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
8914 gfc_add_expr_to_block (&block, tmp);
8915 }
8916 else
8917 {
8918 tmp = gfc_trans_subarray_assign (dest, cm, expr);
8919 gfc_add_expr_to_block (&block, tmp);
8920 }
8921 }
8922 else if (cm->ts.type == BT_CLASS
8923 && CLASS_DATA (cm)->attr.dimension
8924 && CLASS_DATA (cm)->attr.allocatable
8925 && expr->ts.type == BT_DERIVED)
8926 {
8927 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
8928 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
8929 tmp = gfc_class_vptr_get (dest);
8930 gfc_add_modify (&block, tmp,
8931 fold_convert (TREE_TYPE (tmp), vtab));
8932 tmp = gfc_class_data_get (dest);
8933 tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
8934 gfc_add_expr_to_block (&block, tmp);
8935 }
8936 else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
8937 {
8938 /* NULL initialization for allocatable components. */
8939 gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
8940 null_pointer_node));
8941 }
8942 else if (init && (cm->attr.allocatable
8943 || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
8944 && expr->ts.type != BT_CLASS)))
8945 {
8946 /* Take care about non-array allocatable components here. The alloc_*
8947 routine below is motivated by the alloc_scalar_allocatable_for_
8948 assignment() routine, but with the realloc portions removed and
8949 different input. */
8950 alloc_scalar_allocatable_for_subcomponent_assignment (&block,
8951 dest,
8952 cm,
8953 expr,
8954 sym);
8955 /* The remainder of these instructions follow the if (cm->attr.pointer)
8956 if (!cm->attr.dimension) part above. */
8957 gfc_init_se (&se, NULL);
8958 gfc_conv_expr (&se, expr);
8959 gfc_add_block_to_block (&block, &se.pre);
8960
8961 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
8962 && expr->symtree->n.sym->attr.dummy)
8963 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
8964
8965 if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
8966 {
8967 tmp = gfc_class_data_get (dest);
8968 tmp = build_fold_indirect_ref_loc (input_location, tmp);
8969 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
8970 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
8971 gfc_add_modify (&block, gfc_class_vptr_get (dest),
8972 fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
8973 }
8974 else
8975 tmp = build_fold_indirect_ref_loc (input_location, dest);
8976
8977 /* For deferred strings insert a memcpy. */
8978 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8979 {
8980 tree size;
8981 gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
8982 size = size_of_string_in_bytes (cm->ts.kind, se.string_length
8983 ? se.string_length
8984 : expr->ts.u.cl->backend_decl);
8985 tmp = gfc_build_memcpy_call (tmp, se.expr, size);
8986 gfc_add_expr_to_block (&block, tmp);
8987 }
8988 else
8989 gfc_add_modify (&block, tmp,
8990 fold_convert (TREE_TYPE (tmp), se.expr));
8991 gfc_add_block_to_block (&block, &se.post);
8992 }
8993 else if (expr->ts.type == BT_UNION)
8994 {
8995 tree tmp;
8996 gfc_constructor *c = gfc_constructor_first (expr->value.constructor);
8997 /* We mark that the entire union should be initialized with a contrived
8998 EXPR_NULL expression at the beginning. */
8999 if (c != NULL && c->n.component == NULL
9000 && c->expr != NULL && c->expr->expr_type == EXPR_NULL)
9001 {
9002 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9003 dest, build_constructor (TREE_TYPE (dest), NULL));
9004 gfc_add_expr_to_block (&block, tmp);
9005 c = gfc_constructor_next (c);
9006 }
9007 /* The following constructor expression, if any, represents a specific
9008 map intializer, as given by the user. */
9009 if (c != NULL && c->expr != NULL)
9010 {
9011 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
9012 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
9013 gfc_add_expr_to_block (&block, tmp);
9014 }
9015 }
9016 else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
9017 {
9018 if (expr->expr_type != EXPR_STRUCTURE)
9019 {
9020 tree dealloc = NULL_TREE;
9021 gfc_init_se (&se, NULL);
9022 gfc_conv_expr (&se, expr);
9023 gfc_add_block_to_block (&block, &se.pre);
9024 /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
9025 expression in a temporary variable and deallocate the allocatable
9026 components. Then we can the copy the expression to the result. */
9027 if (cm->ts.u.derived->attr.alloc_comp
9028 && expr->expr_type != EXPR_VARIABLE)
9029 {
9030 se.expr = gfc_evaluate_now (se.expr, &block);
9031 dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr,
9032 expr->rank);
9033 }
9034 gfc_add_modify (&block, dest,
9035 fold_convert (TREE_TYPE (dest), se.expr));
9036 if (cm->ts.u.derived->attr.alloc_comp
9037 && expr->expr_type != EXPR_NULL)
9038 {
9039 // TODO: Fix caf_mode
9040 tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
9041 dest, expr->rank, 0);
9042 gfc_add_expr_to_block (&block, tmp);
9043 if (dealloc != NULL_TREE)
9044 gfc_add_expr_to_block (&block, dealloc);
9045 }
9046 gfc_add_block_to_block (&block, &se.post);
9047 }
9048 else
9049 {
9050 /* Nested constructors. */
9051 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
9052 gfc_add_expr_to_block (&block, tmp);
9053 }
9054 }
9055 else if (gfc_deferred_strlen (cm, &tmp))
9056 {
9057 tree strlen;
9058 strlen = tmp;
9059 gcc_assert (strlen);
9060 strlen = fold_build3_loc (input_location, COMPONENT_REF,
9061 TREE_TYPE (strlen),
9062 TREE_OPERAND (dest, 0),
9063 strlen, NULL_TREE);
9064
9065 if (expr->expr_type == EXPR_NULL)
9066 {
9067 tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
9068 gfc_add_modify (&block, dest, tmp);
9069 tmp = build_int_cst (TREE_TYPE (strlen), 0);
9070 gfc_add_modify (&block, strlen, tmp);
9071 }
9072 else
9073 {
9074 tree size;
9075 gfc_init_se (&se, NULL);
9076 gfc_conv_expr (&se, expr);
9077 size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
9078 tmp = build_call_expr_loc (input_location,
9079 builtin_decl_explicit (BUILT_IN_MALLOC),
9080 1, size);
9081 gfc_add_modify (&block, dest,
9082 fold_convert (TREE_TYPE (dest), tmp));
9083 gfc_add_modify (&block, strlen,
9084 fold_convert (TREE_TYPE (strlen), se.string_length));
9085 tmp = gfc_build_memcpy_call (dest, se.expr, size);
9086 gfc_add_expr_to_block (&block, tmp);
9087 }
9088 }
9089 else if (!cm->attr.artificial)
9090 {
9091 /* Scalar component (excluding deferred parameters). */
9092 gfc_init_se (&se, NULL);
9093 gfc_init_se (&lse, NULL);
9094
9095 gfc_conv_expr (&se, expr);
9096 if (cm->ts.type == BT_CHARACTER)
9097 lse.string_length = cm->ts.u.cl->backend_decl;
9098 lse.expr = dest;
9099 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false);
9100 gfc_add_expr_to_block (&block, tmp);
9101 }
9102 return gfc_finish_block (&block);
9103 }
9104
9105 /* Assign a derived type constructor to a variable. */
9106
9107 tree
gfc_trans_structure_assign(tree dest,gfc_expr * expr,bool init,bool coarray)9108 gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)
9109 {
9110 gfc_constructor *c;
9111 gfc_component *cm;
9112 stmtblock_t block;
9113 tree field;
9114 tree tmp;
9115 gfc_se se;
9116
9117 gfc_start_block (&block);
9118
9119 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
9120 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
9121 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
9122 {
9123 gfc_se lse;
9124
9125 gfc_init_se (&se, NULL);
9126 gfc_init_se (&lse, NULL);
9127 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
9128 lse.expr = dest;
9129 gfc_add_modify (&block, lse.expr,
9130 fold_convert (TREE_TYPE (lse.expr), se.expr));
9131
9132 return gfc_finish_block (&block);
9133 }
9134
9135 /* Make sure that the derived type has been completely built. */
9136 if (!expr->ts.u.derived->backend_decl
9137 || !TYPE_FIELDS (expr->ts.u.derived->backend_decl))
9138 {
9139 tmp = gfc_typenode_for_spec (&expr->ts);
9140 gcc_assert (tmp);
9141 }
9142
9143 cm = expr->ts.u.derived->components;
9144
9145
9146 if (coarray)
9147 gfc_init_se (&se, NULL);
9148
9149 for (c = gfc_constructor_first (expr->value.constructor);
9150 c; c = gfc_constructor_next (c), cm = cm->next)
9151 {
9152 /* Skip absent members in default initializers. */
9153 if (!c->expr && !cm->attr.allocatable)
9154 continue;
9155
9156 /* Register the component with the caf-lib before it is initialized.
9157 Register only allocatable components, that are not coarray'ed
9158 components (%comp[*]). Only register when the constructor is not the
9159 null-expression. */
9160 if (coarray && !cm->attr.codimension
9161 && (cm->attr.allocatable || cm->attr.pointer)
9162 && (!c->expr || c->expr->expr_type == EXPR_NULL))
9163 {
9164 tree token, desc, size;
9165 bool is_array = cm->ts.type == BT_CLASS
9166 ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
9167
9168 field = cm->backend_decl;
9169 field = fold_build3_loc (input_location, COMPONENT_REF,
9170 TREE_TYPE (field), dest, field, NULL_TREE);
9171 if (cm->ts.type == BT_CLASS)
9172 field = gfc_class_data_get (field);
9173
9174 token = is_array ? gfc_conv_descriptor_token (field)
9175 : fold_build3_loc (input_location, COMPONENT_REF,
9176 TREE_TYPE (cm->caf_token), dest,
9177 cm->caf_token, NULL_TREE);
9178
9179 if (is_array)
9180 {
9181 /* The _caf_register routine looks at the rank of the array
9182 descriptor to decide whether the data registered is an array
9183 or not. */
9184 int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank
9185 : cm->as->rank;
9186 /* When the rank is not known just set a positive rank, which
9187 suffices to recognize the data as array. */
9188 if (rank < 0)
9189 rank = 1;
9190 size = build_zero_cst (size_type_node);
9191 desc = field;
9192 gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
9193 build_int_cst (signed_char_type_node, rank));
9194 }
9195 else
9196 {
9197 desc = gfc_conv_scalar_to_descriptor (&se, field,
9198 cm->ts.type == BT_CLASS
9199 ? CLASS_DATA (cm)->attr
9200 : cm->attr);
9201 size = TYPE_SIZE_UNIT (TREE_TYPE (field));
9202 }
9203 gfc_add_block_to_block (&block, &se.pre);
9204 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register,
9205 7, size, build_int_cst (
9206 integer_type_node,
9207 GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY),
9208 gfc_build_addr_expr (pvoid_type_node,
9209 token),
9210 gfc_build_addr_expr (NULL_TREE, desc),
9211 null_pointer_node, null_pointer_node,
9212 integer_zero_node);
9213 gfc_add_expr_to_block (&block, tmp);
9214 }
9215 field = cm->backend_decl;
9216 gcc_assert(field);
9217 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
9218 dest, field, NULL_TREE);
9219 if (!c->expr)
9220 {
9221 gfc_expr *e = gfc_get_null_expr (NULL);
9222 tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived,
9223 init);
9224 gfc_free_expr (e);
9225 }
9226 else
9227 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr,
9228 expr->ts.u.derived, init);
9229 gfc_add_expr_to_block (&block, tmp);
9230 }
9231 return gfc_finish_block (&block);
9232 }
9233
9234 static void
gfc_conv_union_initializer(vec<constructor_elt,va_gc> * & v,gfc_component * un,gfc_expr * init)9235 gfc_conv_union_initializer (vec<constructor_elt, va_gc> *&v,
9236 gfc_component *un, gfc_expr *init)
9237 {
9238 gfc_constructor *ctor;
9239
9240 if (un->ts.type != BT_UNION || un == NULL || init == NULL)
9241 return;
9242
9243 ctor = gfc_constructor_first (init->value.constructor);
9244
9245 if (ctor == NULL || ctor->expr == NULL)
9246 return;
9247
9248 gcc_assert (init->expr_type == EXPR_STRUCTURE);
9249
9250 /* If we have an 'initialize all' constructor, do it first. */
9251 if (ctor->expr->expr_type == EXPR_NULL)
9252 {
9253 tree union_type = TREE_TYPE (un->backend_decl);
9254 tree val = build_constructor (union_type, NULL);
9255 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
9256 ctor = gfc_constructor_next (ctor);
9257 }
9258
9259 /* Add the map initializer on top. */
9260 if (ctor != NULL && ctor->expr != NULL)
9261 {
9262 gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE);
9263 tree val = gfc_conv_initializer (ctor->expr, &un->ts,
9264 TREE_TYPE (un->backend_decl),
9265 un->attr.dimension, un->attr.pointer,
9266 un->attr.proc_pointer);
9267 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
9268 }
9269 }
9270
9271 /* Build an expression for a constructor. If init is nonzero then
9272 this is part of a static variable initializer. */
9273
9274 void
gfc_conv_structure(gfc_se * se,gfc_expr * expr,int init)9275 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
9276 {
9277 gfc_constructor *c;
9278 gfc_component *cm;
9279 tree val;
9280 tree type;
9281 tree tmp;
9282 vec<constructor_elt, va_gc> *v = NULL;
9283
9284 gcc_assert (se->ss == NULL);
9285 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
9286 type = gfc_typenode_for_spec (&expr->ts);
9287
9288 if (!init)
9289 {
9290 /* Create a temporary variable and fill it in. */
9291 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
9292 /* The symtree in expr is NULL, if the code to generate is for
9293 initializing the static members only. */
9294 tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL,
9295 se->want_coarray);
9296 gfc_add_expr_to_block (&se->pre, tmp);
9297 return;
9298 }
9299
9300 cm = expr->ts.u.derived->components;
9301
9302 for (c = gfc_constructor_first (expr->value.constructor);
9303 c && cm; c = gfc_constructor_next (c), cm = cm->next)
9304 {
9305 /* Skip absent members in default initializers and allocatable
9306 components. Although the latter have a default initializer
9307 of EXPR_NULL,... by default, the static nullify is not needed
9308 since this is done every time we come into scope. */
9309 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
9310 continue;
9311
9312 if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
9313 && strcmp (cm->name, "_extends") == 0
9314 && cm->initializer->symtree)
9315 {
9316 tree vtab;
9317 gfc_symbol *vtabs;
9318 vtabs = cm->initializer->symtree->n.sym;
9319 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
9320 vtab = unshare_expr_without_location (vtab);
9321 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
9322 }
9323 else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
9324 {
9325 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
9326 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
9327 fold_convert (TREE_TYPE (cm->backend_decl),
9328 val));
9329 }
9330 else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
9331 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
9332 fold_convert (TREE_TYPE (cm->backend_decl),
9333 integer_zero_node));
9334 else if (cm->ts.type == BT_UNION)
9335 gfc_conv_union_initializer (v, cm, c->expr);
9336 else
9337 {
9338 val = gfc_conv_initializer (c->expr, &cm->ts,
9339 TREE_TYPE (cm->backend_decl),
9340 cm->attr.dimension, cm->attr.pointer,
9341 cm->attr.proc_pointer);
9342 val = unshare_expr_without_location (val);
9343
9344 /* Append it to the constructor list. */
9345 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
9346 }
9347 }
9348
9349 se->expr = build_constructor (type, v);
9350 if (init)
9351 TREE_CONSTANT (se->expr) = 1;
9352 }
9353
9354
9355 /* Translate a substring expression. */
9356
9357 static void
gfc_conv_substring_expr(gfc_se * se,gfc_expr * expr)9358 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
9359 {
9360 gfc_ref *ref;
9361
9362 ref = expr->ref;
9363
9364 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
9365
9366 se->expr = gfc_build_wide_string_const (expr->ts.kind,
9367 expr->value.character.length,
9368 expr->value.character.string);
9369
9370 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
9371 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
9372
9373 if (ref)
9374 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
9375 }
9376
9377
9378 /* Entry point for expression translation. Evaluates a scalar quantity.
9379 EXPR is the expression to be translated, and SE is the state structure if
9380 called from within the scalarized. */
9381
9382 void
gfc_conv_expr(gfc_se * se,gfc_expr * expr)9383 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
9384 {
9385 gfc_ss *ss;
9386
9387 ss = se->ss;
9388 if (ss && ss->info->expr == expr
9389 && (ss->info->type == GFC_SS_SCALAR
9390 || ss->info->type == GFC_SS_REFERENCE))
9391 {
9392 gfc_ss_info *ss_info;
9393
9394 ss_info = ss->info;
9395 /* Substitute a scalar expression evaluated outside the scalarization
9396 loop. */
9397 se->expr = ss_info->data.scalar.value;
9398 if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
9399 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
9400
9401 se->string_length = ss_info->string_length;
9402 gfc_advance_se_ss_chain (se);
9403 return;
9404 }
9405
9406 /* We need to convert the expressions for the iso_c_binding derived types.
9407 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
9408 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
9409 typespec for the C_PTR and C_FUNPTR symbols, which has already been
9410 updated to be an integer with a kind equal to the size of a (void *). */
9411 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
9412 && expr->ts.u.derived->attr.is_bind_c)
9413 {
9414 if (expr->expr_type == EXPR_VARIABLE
9415 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
9416 || expr->symtree->n.sym->intmod_sym_id
9417 == ISOCBINDING_NULL_FUNPTR))
9418 {
9419 /* Set expr_type to EXPR_NULL, which will result in
9420 null_pointer_node being used below. */
9421 expr->expr_type = EXPR_NULL;
9422 }
9423 else
9424 {
9425 /* Update the type/kind of the expression to be what the new
9426 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
9427 expr->ts.type = BT_INTEGER;
9428 expr->ts.f90_type = BT_VOID;
9429 expr->ts.kind = gfc_index_integer_kind;
9430 }
9431 }
9432
9433 gfc_fix_class_refs (expr);
9434
9435 switch (expr->expr_type)
9436 {
9437 case EXPR_OP:
9438 gfc_conv_expr_op (se, expr);
9439 break;
9440
9441 case EXPR_FUNCTION:
9442 gfc_conv_function_expr (se, expr);
9443 break;
9444
9445 case EXPR_CONSTANT:
9446 gfc_conv_constant (se, expr);
9447 break;
9448
9449 case EXPR_VARIABLE:
9450 gfc_conv_variable (se, expr);
9451 break;
9452
9453 case EXPR_NULL:
9454 se->expr = null_pointer_node;
9455 break;
9456
9457 case EXPR_SUBSTRING:
9458 gfc_conv_substring_expr (se, expr);
9459 break;
9460
9461 case EXPR_STRUCTURE:
9462 gfc_conv_structure (se, expr, 0);
9463 break;
9464
9465 case EXPR_ARRAY:
9466 gfc_conv_array_constructor_expr (se, expr);
9467 break;
9468
9469 default:
9470 gcc_unreachable ();
9471 break;
9472 }
9473 }
9474
9475 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
9476 of an assignment. */
9477 void
gfc_conv_expr_lhs(gfc_se * se,gfc_expr * expr)9478 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
9479 {
9480 gfc_conv_expr (se, expr);
9481 /* All numeric lvalues should have empty post chains. If not we need to
9482 figure out a way of rewriting an lvalue so that it has no post chain. */
9483 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
9484 }
9485
9486 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
9487 numeric expressions. Used for scalar values where inserting cleanup code
9488 is inconvenient. */
9489 void
gfc_conv_expr_val(gfc_se * se,gfc_expr * expr)9490 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
9491 {
9492 tree val;
9493
9494 gcc_assert (expr->ts.type != BT_CHARACTER);
9495 gfc_conv_expr (se, expr);
9496 if (se->post.head)
9497 {
9498 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
9499 gfc_add_modify (&se->pre, val, se->expr);
9500 se->expr = val;
9501 gfc_add_block_to_block (&se->pre, &se->post);
9502 }
9503 }
9504
9505 /* Helper to translate an expression and convert it to a particular type. */
9506 void
gfc_conv_expr_type(gfc_se * se,gfc_expr * expr,tree type)9507 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
9508 {
9509 gfc_conv_expr_val (se, expr);
9510 se->expr = convert (type, se->expr);
9511 }
9512
9513
9514 /* Converts an expression so that it can be passed by reference. Scalar
9515 values only. */
9516
9517 void
gfc_conv_expr_reference(gfc_se * se,gfc_expr * expr)9518 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
9519 {
9520 gfc_ss *ss;
9521 tree var;
9522
9523 ss = se->ss;
9524 if (ss && ss->info->expr == expr
9525 && ss->info->type == GFC_SS_REFERENCE)
9526 {
9527 /* Returns a reference to the scalar evaluated outside the loop
9528 for this case. */
9529 gfc_conv_expr (se, expr);
9530
9531 if (expr->ts.type == BT_CHARACTER
9532 && expr->expr_type != EXPR_FUNCTION)
9533 gfc_conv_string_parameter (se);
9534 else
9535 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
9536
9537 return;
9538 }
9539
9540 if (expr->ts.type == BT_CHARACTER)
9541 {
9542 gfc_conv_expr (se, expr);
9543 gfc_conv_string_parameter (se);
9544 return;
9545 }
9546
9547 if (expr->expr_type == EXPR_VARIABLE)
9548 {
9549 se->want_pointer = 1;
9550 gfc_conv_expr (se, expr);
9551 if (se->post.head)
9552 {
9553 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9554 gfc_add_modify (&se->pre, var, se->expr);
9555 gfc_add_block_to_block (&se->pre, &se->post);
9556 se->expr = var;
9557 }
9558 return;
9559 }
9560
9561 if (expr->expr_type == EXPR_FUNCTION
9562 && ((expr->value.function.esym
9563 && expr->value.function.esym->result
9564 && expr->value.function.esym->result->attr.pointer
9565 && !expr->value.function.esym->result->attr.dimension)
9566 || (!expr->value.function.esym && !expr->ref
9567 && expr->symtree->n.sym->attr.pointer
9568 && !expr->symtree->n.sym->attr.dimension)))
9569 {
9570 se->want_pointer = 1;
9571 gfc_conv_expr (se, expr);
9572 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9573 gfc_add_modify (&se->pre, var, se->expr);
9574 se->expr = var;
9575 return;
9576 }
9577
9578 gfc_conv_expr (se, expr);
9579
9580 /* Create a temporary var to hold the value. */
9581 if (TREE_CONSTANT (se->expr))
9582 {
9583 tree tmp = se->expr;
9584 STRIP_TYPE_NOPS (tmp);
9585 var = build_decl (input_location,
9586 CONST_DECL, NULL, TREE_TYPE (tmp));
9587 DECL_INITIAL (var) = tmp;
9588 TREE_STATIC (var) = 1;
9589 pushdecl (var);
9590 }
9591 else
9592 {
9593 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
9594 gfc_add_modify (&se->pre, var, se->expr);
9595 }
9596
9597 if (!expr->must_finalize)
9598 gfc_add_block_to_block (&se->pre, &se->post);
9599
9600 /* Take the address of that value. */
9601 se->expr = gfc_build_addr_expr (NULL_TREE, var);
9602 }
9603
9604
9605 /* Get the _len component for an unlimited polymorphic expression. */
9606
9607 static tree
trans_get_upoly_len(stmtblock_t * block,gfc_expr * expr)9608 trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
9609 {
9610 gfc_se se;
9611 gfc_ref *ref = expr->ref;
9612
9613 gfc_init_se (&se, NULL);
9614 while (ref && ref->next)
9615 ref = ref->next;
9616 gfc_add_len_component (expr);
9617 gfc_conv_expr (&se, expr);
9618 gfc_add_block_to_block (block, &se.pre);
9619 gcc_assert (se.post.head == NULL_TREE);
9620 if (ref)
9621 {
9622 gfc_free_ref_list (ref->next);
9623 ref->next = NULL;
9624 }
9625 else
9626 {
9627 gfc_free_ref_list (expr->ref);
9628 expr->ref = NULL;
9629 }
9630 return se.expr;
9631 }
9632
9633
9634 /* Assign _vptr and _len components as appropriate. BLOCK should be a
9635 statement-list outside of the scalarizer-loop. When code is generated, that
9636 depends on the scalarized expression, it is added to RSE.PRE.
9637 Returns le's _vptr tree and when set the len expressions in to_lenp and
9638 from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
9639 expression. */
9640
9641 static tree
trans_class_vptr_len_assignment(stmtblock_t * block,gfc_expr * le,gfc_expr * re,gfc_se * rse,tree * to_lenp,tree * from_lenp)9642 trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
9643 gfc_expr * re, gfc_se *rse,
9644 tree * to_lenp, tree * from_lenp)
9645 {
9646 gfc_se se;
9647 gfc_expr * vptr_expr;
9648 tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr;
9649 bool set_vptr = false, temp_rhs = false;
9650 stmtblock_t *pre = block;
9651 tree class_expr = NULL_TREE;
9652
9653 /* Create a temporary for complicated expressions. */
9654 if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
9655 && rse->expr != NULL_TREE && !DECL_P (rse->expr))
9656 {
9657 if (re->ts.type == BT_CLASS && !GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
9658 class_expr = gfc_get_class_from_expr (rse->expr);
9659
9660 if (rse->loop)
9661 pre = &rse->loop->pre;
9662 else
9663 pre = &rse->pre;
9664
9665 if (class_expr != NULL_TREE && UNLIMITED_POLY (re))
9666 {
9667 tmp = TREE_OPERAND (rse->expr, 0);
9668 tmp = gfc_create_var (TREE_TYPE (tmp), "rhs");
9669 gfc_add_modify (&rse->pre, tmp, TREE_OPERAND (rse->expr, 0));
9670 }
9671 else
9672 {
9673 tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs");
9674 gfc_add_modify (&rse->pre, tmp, rse->expr);
9675 }
9676
9677 rse->expr = tmp;
9678 temp_rhs = true;
9679 }
9680
9681 /* Get the _vptr for the left-hand side expression. */
9682 gfc_init_se (&se, NULL);
9683 vptr_expr = gfc_find_and_cut_at_last_class_ref (le);
9684 if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok)
9685 {
9686 /* Care about _len for unlimited polymorphic entities. */
9687 if (UNLIMITED_POLY (vptr_expr)
9688 || (vptr_expr->ts.type == BT_DERIVED
9689 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9690 to_len = trans_get_upoly_len (block, vptr_expr);
9691 gfc_add_vptr_component (vptr_expr);
9692 set_vptr = true;
9693 }
9694 else
9695 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
9696 se.want_pointer = 1;
9697 gfc_conv_expr (&se, vptr_expr);
9698 gfc_free_expr (vptr_expr);
9699 gfc_add_block_to_block (block, &se.pre);
9700 gcc_assert (se.post.head == NULL_TREE);
9701 lhs_vptr = se.expr;
9702 STRIP_NOPS (lhs_vptr);
9703
9704 /* Set the _vptr only when the left-hand side of the assignment is a
9705 class-object. */
9706 if (set_vptr)
9707 {
9708 /* Get the vptr from the rhs expression only, when it is variable.
9709 Functions are expected to be assigned to a temporary beforehand. */
9710 vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS)
9711 ? gfc_find_and_cut_at_last_class_ref (re)
9712 : NULL;
9713 if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS)
9714 {
9715 if (to_len != NULL_TREE)
9716 {
9717 /* Get the _len information from the rhs. */
9718 if (UNLIMITED_POLY (vptr_expr)
9719 || (vptr_expr->ts.type == BT_DERIVED
9720 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9721 from_len = trans_get_upoly_len (block, vptr_expr);
9722 }
9723 gfc_add_vptr_component (vptr_expr);
9724 }
9725 else
9726 {
9727 if (re->expr_type == EXPR_VARIABLE
9728 && DECL_P (re->symtree->n.sym->backend_decl)
9729 && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl)
9730 && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl)
9731 && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
9732 re->symtree->n.sym->backend_decl))))
9733 {
9734 vptr_expr = NULL;
9735 se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
9736 re->symtree->n.sym->backend_decl));
9737 if (to_len)
9738 from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
9739 re->symtree->n.sym->backend_decl));
9740 }
9741 else if (temp_rhs && re->ts.type == BT_CLASS)
9742 {
9743 vptr_expr = NULL;
9744 if (class_expr)
9745 tmp = class_expr;
9746 else if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
9747 tmp = gfc_get_class_from_expr (rse->expr);
9748 else
9749 tmp = rse->expr;
9750
9751 se.expr = gfc_class_vptr_get (tmp);
9752 if (UNLIMITED_POLY (re))
9753 from_len = gfc_class_len_get (tmp);
9754
9755 }
9756 else if (re->expr_type != EXPR_NULL)
9757 /* Only when rhs is non-NULL use its declared type for vptr
9758 initialisation. */
9759 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts));
9760 else
9761 /* When the rhs is NULL use the vtab of lhs' declared type. */
9762 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
9763 }
9764
9765 if (vptr_expr)
9766 {
9767 gfc_init_se (&se, NULL);
9768 se.want_pointer = 1;
9769 gfc_conv_expr (&se, vptr_expr);
9770 gfc_free_expr (vptr_expr);
9771 gfc_add_block_to_block (block, &se.pre);
9772 gcc_assert (se.post.head == NULL_TREE);
9773 }
9774 gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
9775 se.expr));
9776
9777 if (to_len != NULL_TREE)
9778 {
9779 /* The _len component needs to be set. Figure how to get the
9780 value of the right-hand side. */
9781 if (from_len == NULL_TREE)
9782 {
9783 if (rse->string_length != NULL_TREE)
9784 from_len = rse->string_length;
9785 else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length)
9786 {
9787 gfc_init_se (&se, NULL);
9788 gfc_conv_expr (&se, re->ts.u.cl->length);
9789 gfc_add_block_to_block (block, &se.pre);
9790 gcc_assert (se.post.head == NULL_TREE);
9791 from_len = gfc_evaluate_now (se.expr, block);
9792 }
9793 else
9794 from_len = build_zero_cst (gfc_charlen_type_node);
9795 }
9796 gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len),
9797 from_len));
9798 }
9799 }
9800
9801 /* Return the _len trees only, when requested. */
9802 if (to_lenp)
9803 *to_lenp = to_len;
9804 if (from_lenp)
9805 *from_lenp = from_len;
9806 return lhs_vptr;
9807 }
9808
9809
9810 /* Assign tokens for pointer components. */
9811
9812 static void
trans_caf_token_assign(gfc_se * lse,gfc_se * rse,gfc_expr * expr1,gfc_expr * expr2)9813 trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1,
9814 gfc_expr *expr2)
9815 {
9816 symbol_attribute lhs_attr, rhs_attr;
9817 tree tmp, lhs_tok, rhs_tok;
9818 /* Flag to indicated component refs on the rhs. */
9819 bool rhs_cr;
9820
9821 lhs_attr = gfc_caf_attr (expr1);
9822 if (expr2->expr_type != EXPR_NULL)
9823 {
9824 rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr);
9825 if (lhs_attr.codimension && rhs_attr.codimension)
9826 {
9827 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
9828 lhs_tok = build_fold_indirect_ref (lhs_tok);
9829
9830 if (rhs_cr)
9831 rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2);
9832 else
9833 {
9834 tree caf_decl;
9835 caf_decl = gfc_get_tree_for_caf_expr (expr2);
9836 gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl,
9837 NULL_TREE, NULL);
9838 }
9839 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9840 lhs_tok,
9841 fold_convert (TREE_TYPE (lhs_tok), rhs_tok));
9842 gfc_prepend_expr_to_block (&lse->post, tmp);
9843 }
9844 }
9845 else if (lhs_attr.codimension)
9846 {
9847 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
9848 lhs_tok = build_fold_indirect_ref (lhs_tok);
9849 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9850 lhs_tok, null_pointer_node);
9851 gfc_prepend_expr_to_block (&lse->post, tmp);
9852 }
9853 }
9854
9855
9856 /* Do everything that is needed for a CLASS function expr2. */
9857
9858 static tree
trans_class_pointer_fcn(stmtblock_t * block,gfc_se * lse,gfc_se * rse,gfc_expr * expr1,gfc_expr * expr2)9859 trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
9860 gfc_expr *expr1, gfc_expr *expr2)
9861 {
9862 tree expr1_vptr = NULL_TREE;
9863 tree tmp;
9864
9865 gfc_conv_function_expr (rse, expr2);
9866 rse->expr = gfc_evaluate_now (rse->expr, &rse->pre);
9867
9868 if (expr1->ts.type != BT_CLASS)
9869 rse->expr = gfc_class_data_get (rse->expr);
9870 else
9871 {
9872 expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
9873 expr2, rse,
9874 NULL, NULL);
9875 gfc_add_block_to_block (block, &rse->pre);
9876 tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
9877 gfc_add_modify (&lse->pre, tmp, rse->expr);
9878
9879 gfc_add_modify (&lse->pre, expr1_vptr,
9880 fold_convert (TREE_TYPE (expr1_vptr),
9881 gfc_class_vptr_get (tmp)));
9882 rse->expr = gfc_class_data_get (tmp);
9883 }
9884
9885 return expr1_vptr;
9886 }
9887
9888
9889 tree
gfc_trans_pointer_assign(gfc_code * code)9890 gfc_trans_pointer_assign (gfc_code * code)
9891 {
9892 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
9893 }
9894
9895
9896 /* Generate code for a pointer assignment. */
9897
9898 tree
gfc_trans_pointer_assignment(gfc_expr * expr1,gfc_expr * expr2)9899 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
9900 {
9901 gfc_se lse;
9902 gfc_se rse;
9903 stmtblock_t block;
9904 tree desc;
9905 tree tmp;
9906 tree expr1_vptr = NULL_TREE;
9907 bool scalar, non_proc_ptr_assign;
9908 gfc_ss *ss;
9909
9910 gfc_start_block (&block);
9911
9912 gfc_init_se (&lse, NULL);
9913
9914 /* Usually testing whether this is not a proc pointer assignment. */
9915 non_proc_ptr_assign = !(gfc_expr_attr (expr1).proc_pointer
9916 && expr2->expr_type == EXPR_VARIABLE
9917 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE);
9918
9919 /* Check whether the expression is a scalar or not; we cannot use
9920 expr1->rank as it can be nonzero for proc pointers. */
9921 ss = gfc_walk_expr (expr1);
9922 scalar = ss == gfc_ss_terminator;
9923 if (!scalar)
9924 gfc_free_ss_chain (ss);
9925
9926 if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
9927 && expr2->expr_type != EXPR_FUNCTION && non_proc_ptr_assign)
9928 {
9929 gfc_add_data_component (expr2);
9930 /* The following is required as gfc_add_data_component doesn't
9931 update ts.type if there is a trailing REF_ARRAY. */
9932 expr2->ts.type = BT_DERIVED;
9933 }
9934
9935 if (scalar)
9936 {
9937 /* Scalar pointers. */
9938 lse.want_pointer = 1;
9939 gfc_conv_expr (&lse, expr1);
9940 gfc_init_se (&rse, NULL);
9941 rse.want_pointer = 1;
9942 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9943 trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2);
9944 else
9945 gfc_conv_expr (&rse, expr2);
9946
9947 if (non_proc_ptr_assign && expr1->ts.type == BT_CLASS)
9948 {
9949 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
9950 NULL);
9951 lse.expr = gfc_class_data_get (lse.expr);
9952 }
9953
9954 if (expr1->symtree->n.sym->attr.proc_pointer
9955 && expr1->symtree->n.sym->attr.dummy)
9956 lse.expr = build_fold_indirect_ref_loc (input_location,
9957 lse.expr);
9958
9959 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
9960 && expr2->symtree->n.sym->attr.dummy)
9961 rse.expr = build_fold_indirect_ref_loc (input_location,
9962 rse.expr);
9963
9964 gfc_add_block_to_block (&block, &lse.pre);
9965 gfc_add_block_to_block (&block, &rse.pre);
9966
9967 /* Check character lengths if character expression. The test is only
9968 really added if -fbounds-check is enabled. Exclude deferred
9969 character length lefthand sides. */
9970 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
9971 && !expr1->ts.deferred
9972 && !expr1->symtree->n.sym->attr.proc_pointer
9973 && !gfc_is_proc_ptr_comp (expr1))
9974 {
9975 gcc_assert (expr2->ts.type == BT_CHARACTER);
9976 gcc_assert (lse.string_length && rse.string_length);
9977 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
9978 lse.string_length, rse.string_length,
9979 &block);
9980 }
9981
9982 /* The assignment to an deferred character length sets the string
9983 length to that of the rhs. */
9984 if (expr1->ts.deferred)
9985 {
9986 if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
9987 gfc_add_modify (&block, lse.string_length,
9988 fold_convert (TREE_TYPE (lse.string_length),
9989 rse.string_length));
9990 else if (lse.string_length != NULL)
9991 gfc_add_modify (&block, lse.string_length,
9992 build_zero_cst (TREE_TYPE (lse.string_length)));
9993 }
9994
9995 gfc_add_modify (&block, lse.expr,
9996 fold_convert (TREE_TYPE (lse.expr), rse.expr));
9997
9998 /* Also set the tokens for pointer components in derived typed
9999 coarrays. */
10000 if (flag_coarray == GFC_FCOARRAY_LIB)
10001 trans_caf_token_assign (&lse, &rse, expr1, expr2);
10002
10003 gfc_add_block_to_block (&block, &rse.post);
10004 gfc_add_block_to_block (&block, &lse.post);
10005 }
10006 else
10007 {
10008 gfc_ref* remap;
10009 bool rank_remap;
10010 tree strlen_lhs;
10011 tree strlen_rhs = NULL_TREE;
10012
10013 /* Array pointer. Find the last reference on the LHS and if it is an
10014 array section ref, we're dealing with bounds remapping. In this case,
10015 set it to AR_FULL so that gfc_conv_expr_descriptor does
10016 not see it and process the bounds remapping afterwards explicitly. */
10017 for (remap = expr1->ref; remap; remap = remap->next)
10018 if (!remap->next && remap->type == REF_ARRAY
10019 && remap->u.ar.type == AR_SECTION)
10020 break;
10021 rank_remap = (remap && remap->u.ar.end[0]);
10022
10023 if (remap && expr2->expr_type == EXPR_NULL)
10024 {
10025 gfc_error ("If bounds remapping is specified at %L, "
10026 "the pointer target shall not be NULL", &expr1->where);
10027 return NULL_TREE;
10028 }
10029
10030 gfc_init_se (&lse, NULL);
10031 if (remap)
10032 lse.descriptor_only = 1;
10033 gfc_conv_expr_descriptor (&lse, expr1);
10034 strlen_lhs = lse.string_length;
10035 desc = lse.expr;
10036
10037 if (expr2->expr_type == EXPR_NULL)
10038 {
10039 /* Just set the data pointer to null. */
10040 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
10041 }
10042 else if (rank_remap)
10043 {
10044 /* If we are rank-remapping, just get the RHS's descriptor and
10045 process this later on. */
10046 gfc_init_se (&rse, NULL);
10047 rse.direct_byref = 1;
10048 rse.byref_noassign = 1;
10049
10050 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
10051 expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse,
10052 expr1, expr2);
10053 else if (expr2->expr_type == EXPR_FUNCTION)
10054 {
10055 tree bound[GFC_MAX_DIMENSIONS];
10056 int i;
10057
10058 for (i = 0; i < expr2->rank; i++)
10059 bound[i] = NULL_TREE;
10060 tmp = gfc_typenode_for_spec (&expr2->ts);
10061 tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
10062 bound, bound, 0,
10063 GFC_ARRAY_POINTER_CONT, false);
10064 tmp = gfc_create_var (tmp, "ptrtemp");
10065 rse.descriptor_only = 0;
10066 rse.expr = tmp;
10067 rse.direct_byref = 1;
10068 gfc_conv_expr_descriptor (&rse, expr2);
10069 strlen_rhs = rse.string_length;
10070 rse.expr = tmp;
10071 }
10072 else
10073 {
10074 gfc_conv_expr_descriptor (&rse, expr2);
10075 strlen_rhs = rse.string_length;
10076 if (expr1->ts.type == BT_CLASS)
10077 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
10078 expr2, &rse,
10079 NULL, NULL);
10080 }
10081 }
10082 else if (expr2->expr_type == EXPR_VARIABLE)
10083 {
10084 /* Assign directly to the LHS's descriptor. */
10085 lse.descriptor_only = 0;
10086 lse.direct_byref = 1;
10087 gfc_conv_expr_descriptor (&lse, expr2);
10088 strlen_rhs = lse.string_length;
10089 gfc_init_se (&rse, NULL);
10090
10091 if (expr1->ts.type == BT_CLASS)
10092 {
10093 rse.expr = NULL_TREE;
10094 rse.string_length = strlen_rhs;
10095 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
10096 NULL, NULL);
10097 }
10098
10099 if (remap == NULL)
10100 {
10101 /* If the target is not a whole array, use the target array
10102 reference for remap. */
10103 for (remap = expr2->ref; remap; remap = remap->next)
10104 if (remap->type == REF_ARRAY
10105 && remap->u.ar.type == AR_FULL
10106 && remap->next)
10107 break;
10108 }
10109 }
10110 else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
10111 {
10112 gfc_init_se (&rse, NULL);
10113 rse.want_pointer = 1;
10114 gfc_conv_function_expr (&rse, expr2);
10115 if (expr1->ts.type != BT_CLASS)
10116 {
10117 rse.expr = gfc_class_data_get (rse.expr);
10118 gfc_add_modify (&lse.pre, desc, rse.expr);
10119 /* Set the lhs span. */
10120 tmp = TREE_TYPE (rse.expr);
10121 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
10122 tmp = fold_convert (gfc_array_index_type, tmp);
10123 gfc_conv_descriptor_span_set (&lse.pre, desc, tmp);
10124 }
10125 else
10126 {
10127 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
10128 expr2, &rse, NULL,
10129 NULL);
10130 gfc_add_block_to_block (&block, &rse.pre);
10131 tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
10132 gfc_add_modify (&lse.pre, tmp, rse.expr);
10133
10134 gfc_add_modify (&lse.pre, expr1_vptr,
10135 fold_convert (TREE_TYPE (expr1_vptr),
10136 gfc_class_vptr_get (tmp)));
10137 rse.expr = gfc_class_data_get (tmp);
10138 gfc_add_modify (&lse.pre, desc, rse.expr);
10139 }
10140 }
10141 else
10142 {
10143 /* Assign to a temporary descriptor and then copy that
10144 temporary to the pointer. */
10145 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
10146 lse.descriptor_only = 0;
10147 lse.expr = tmp;
10148 lse.direct_byref = 1;
10149 gfc_conv_expr_descriptor (&lse, expr2);
10150 strlen_rhs = lse.string_length;
10151 gfc_add_modify (&lse.pre, desc, tmp);
10152 }
10153
10154 if (expr1->ts.type == BT_CHARACTER
10155 && expr1->symtree->n.sym->ts.deferred
10156 && expr1->symtree->n.sym->ts.u.cl->backend_decl
10157 && VAR_P (expr1->symtree->n.sym->ts.u.cl->backend_decl))
10158 {
10159 tmp = expr1->symtree->n.sym->ts.u.cl->backend_decl;
10160 if (expr2->expr_type != EXPR_NULL)
10161 gfc_add_modify (&block, tmp,
10162 fold_convert (TREE_TYPE (tmp), strlen_rhs));
10163 else
10164 gfc_add_modify (&block, tmp, build_zero_cst (TREE_TYPE (tmp)));
10165 }
10166
10167 gfc_add_block_to_block (&block, &lse.pre);
10168 if (rank_remap)
10169 gfc_add_block_to_block (&block, &rse.pre);
10170
10171 /* If we do bounds remapping, update LHS descriptor accordingly. */
10172 if (remap)
10173 {
10174 int dim;
10175 gcc_assert (remap->u.ar.dimen == expr1->rank);
10176
10177 if (rank_remap)
10178 {
10179 /* Do rank remapping. We already have the RHS's descriptor
10180 converted in rse and now have to build the correct LHS
10181 descriptor for it. */
10182
10183 tree dtype, data, span;
10184 tree offs, stride;
10185 tree lbound, ubound;
10186
10187 /* Set dtype. */
10188 dtype = gfc_conv_descriptor_dtype (desc);
10189 tmp = gfc_get_dtype (TREE_TYPE (desc));
10190 gfc_add_modify (&block, dtype, tmp);
10191
10192 /* Copy data pointer. */
10193 data = gfc_conv_descriptor_data_get (rse.expr);
10194 gfc_conv_descriptor_data_set (&block, desc, data);
10195
10196 /* Copy the span. */
10197 if (TREE_CODE (rse.expr) == VAR_DECL
10198 && GFC_DECL_PTR_ARRAY_P (rse.expr))
10199 span = gfc_conv_descriptor_span_get (rse.expr);
10200 else
10201 {
10202 tmp = TREE_TYPE (rse.expr);
10203 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
10204 span = fold_convert (gfc_array_index_type, tmp);
10205 }
10206 gfc_conv_descriptor_span_set (&block, desc, span);
10207
10208 /* Copy offset but adjust it such that it would correspond
10209 to a lbound of zero. */
10210 offs = gfc_conv_descriptor_offset_get (rse.expr);
10211 for (dim = 0; dim < expr2->rank; ++dim)
10212 {
10213 stride = gfc_conv_descriptor_stride_get (rse.expr,
10214 gfc_rank_cst[dim]);
10215 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
10216 gfc_rank_cst[dim]);
10217 tmp = fold_build2_loc (input_location, MULT_EXPR,
10218 gfc_array_index_type, stride, lbound);
10219 offs = fold_build2_loc (input_location, PLUS_EXPR,
10220 gfc_array_index_type, offs, tmp);
10221 }
10222 gfc_conv_descriptor_offset_set (&block, desc, offs);
10223
10224 /* Set the bounds as declared for the LHS and calculate strides as
10225 well as another offset update accordingly. */
10226 stride = gfc_conv_descriptor_stride_get (rse.expr,
10227 gfc_rank_cst[0]);
10228 for (dim = 0; dim < expr1->rank; ++dim)
10229 {
10230 gfc_se lower_se;
10231 gfc_se upper_se;
10232
10233 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
10234
10235 /* Convert declared bounds. */
10236 gfc_init_se (&lower_se, NULL);
10237 gfc_init_se (&upper_se, NULL);
10238 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
10239 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
10240
10241 gfc_add_block_to_block (&block, &lower_se.pre);
10242 gfc_add_block_to_block (&block, &upper_se.pre);
10243
10244 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
10245 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
10246
10247 lbound = gfc_evaluate_now (lbound, &block);
10248 ubound = gfc_evaluate_now (ubound, &block);
10249
10250 gfc_add_block_to_block (&block, &lower_se.post);
10251 gfc_add_block_to_block (&block, &upper_se.post);
10252
10253 /* Set bounds in descriptor. */
10254 gfc_conv_descriptor_lbound_set (&block, desc,
10255 gfc_rank_cst[dim], lbound);
10256 gfc_conv_descriptor_ubound_set (&block, desc,
10257 gfc_rank_cst[dim], ubound);
10258
10259 /* Set stride. */
10260 stride = gfc_evaluate_now (stride, &block);
10261 gfc_conv_descriptor_stride_set (&block, desc,
10262 gfc_rank_cst[dim], stride);
10263
10264 /* Update offset. */
10265 offs = gfc_conv_descriptor_offset_get (desc);
10266 tmp = fold_build2_loc (input_location, MULT_EXPR,
10267 gfc_array_index_type, lbound, stride);
10268 offs = fold_build2_loc (input_location, MINUS_EXPR,
10269 gfc_array_index_type, offs, tmp);
10270 offs = gfc_evaluate_now (offs, &block);
10271 gfc_conv_descriptor_offset_set (&block, desc, offs);
10272
10273 /* Update stride. */
10274 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
10275 stride = fold_build2_loc (input_location, MULT_EXPR,
10276 gfc_array_index_type, stride, tmp);
10277 }
10278 }
10279 else
10280 {
10281 /* Bounds remapping. Just shift the lower bounds. */
10282
10283 gcc_assert (expr1->rank == expr2->rank);
10284
10285 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
10286 {
10287 gfc_se lbound_se;
10288
10289 gcc_assert (!remap->u.ar.end[dim]);
10290 gfc_init_se (&lbound_se, NULL);
10291 if (remap->u.ar.start[dim])
10292 {
10293 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
10294 gfc_add_block_to_block (&block, &lbound_se.pre);
10295 }
10296 else
10297 /* This remap arises from a target that is not a whole
10298 array. The start expressions will be NULL but we need
10299 the lbounds to be one. */
10300 lbound_se.expr = gfc_index_one_node;
10301 gfc_conv_shift_descriptor_lbound (&block, desc,
10302 dim, lbound_se.expr);
10303 gfc_add_block_to_block (&block, &lbound_se.post);
10304 }
10305 }
10306 }
10307
10308 /* If rank remapping was done, check with -fcheck=bounds that
10309 the target is at least as large as the pointer. */
10310 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
10311 {
10312 tree lsize, rsize;
10313 tree fault;
10314 const char* msg;
10315
10316 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
10317 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
10318
10319 lsize = gfc_evaluate_now (lsize, &block);
10320 rsize = gfc_evaluate_now (rsize, &block);
10321 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
10322 rsize, lsize);
10323
10324 msg = _("Target of rank remapping is too small (%ld < %ld)");
10325 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
10326 msg, rsize, lsize);
10327 }
10328
10329 /* Check string lengths if applicable. The check is only really added
10330 to the output code if -fbounds-check is enabled. */
10331 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
10332 {
10333 gcc_assert (expr2->ts.type == BT_CHARACTER);
10334 gcc_assert (strlen_lhs && strlen_rhs);
10335 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
10336 strlen_lhs, strlen_rhs, &block);
10337 }
10338
10339 gfc_add_block_to_block (&block, &lse.post);
10340 if (rank_remap)
10341 gfc_add_block_to_block (&block, &rse.post);
10342 }
10343
10344 return gfc_finish_block (&block);
10345 }
10346
10347
10348 /* Makes sure se is suitable for passing as a function string parameter. */
10349 /* TODO: Need to check all callers of this function. It may be abused. */
10350
10351 void
gfc_conv_string_parameter(gfc_se * se)10352 gfc_conv_string_parameter (gfc_se * se)
10353 {
10354 tree type;
10355
10356 if (TREE_CODE (se->expr) == STRING_CST)
10357 {
10358 type = TREE_TYPE (TREE_TYPE (se->expr));
10359 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
10360 return;
10361 }
10362
10363 if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
10364 || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
10365 && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
10366 {
10367 if (TREE_CODE (se->expr) != INDIRECT_REF)
10368 {
10369 type = TREE_TYPE (se->expr);
10370 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
10371 }
10372 else
10373 {
10374 type = gfc_get_character_type_len (gfc_default_character_kind,
10375 se->string_length);
10376 type = build_pointer_type (type);
10377 se->expr = gfc_build_addr_expr (type, se->expr);
10378 }
10379 }
10380
10381 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
10382 }
10383
10384
10385 /* Generate code for assignment of scalar variables. Includes character
10386 strings and derived types with allocatable components.
10387 If you know that the LHS has no allocations, set dealloc to false.
10388
10389 DEEP_COPY has no effect if the typespec TS is not a derived type with
10390 allocatable components. Otherwise, if it is set, an explicit copy of each
10391 allocatable component is made. This is necessary as a simple copy of the
10392 whole object would copy array descriptors as is, so that the lhs's
10393 allocatable components would point to the rhs's after the assignment.
10394 Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
10395 necessary if the rhs is a non-pointer function, as the allocatable components
10396 are not accessible by other means than the function's result after the
10397 function has returned. It is even more subtle when temporaries are involved,
10398 as the two following examples show:
10399 1. When we evaluate an array constructor, a temporary is created. Thus
10400 there is theoretically no alias possible. However, no deep copy is
10401 made for this temporary, so that if the constructor is made of one or
10402 more variable with allocatable components, those components still point
10403 to the variable's: DEEP_COPY should be set for the assignment from the
10404 temporary to the lhs in that case.
10405 2. When assigning a scalar to an array, we evaluate the scalar value out
10406 of the loop, store it into a temporary variable, and assign from that.
10407 In that case, deep copying when assigning to the temporary would be a
10408 waste of resources; however deep copies should happen when assigning from
10409 the temporary to each array element: again DEEP_COPY should be set for
10410 the assignment from the temporary to the lhs. */
10411
10412 tree
gfc_trans_scalar_assign(gfc_se * lse,gfc_se * rse,gfc_typespec ts,bool deep_copy,bool dealloc,bool in_coarray)10413 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
10414 bool deep_copy, bool dealloc, bool in_coarray)
10415 {
10416 stmtblock_t block;
10417 tree tmp;
10418 tree cond;
10419
10420 gfc_init_block (&block);
10421
10422 if (ts.type == BT_CHARACTER)
10423 {
10424 tree rlen = NULL;
10425 tree llen = NULL;
10426
10427 if (lse->string_length != NULL_TREE)
10428 {
10429 gfc_conv_string_parameter (lse);
10430 gfc_add_block_to_block (&block, &lse->pre);
10431 llen = lse->string_length;
10432 }
10433
10434 if (rse->string_length != NULL_TREE)
10435 {
10436 gfc_conv_string_parameter (rse);
10437 gfc_add_block_to_block (&block, &rse->pre);
10438 rlen = rse->string_length;
10439 }
10440
10441 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
10442 rse->expr, ts.kind);
10443 }
10444 else if (gfc_bt_struct (ts.type)
10445 && (ts.u.derived->attr.alloc_comp
10446 || (deep_copy && ts.u.derived->attr.pdt_type)))
10447 {
10448 tree tmp_var = NULL_TREE;
10449 cond = NULL_TREE;
10450
10451 /* Are the rhs and the lhs the same? */
10452 if (deep_copy)
10453 {
10454 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10455 gfc_build_addr_expr (NULL_TREE, lse->expr),
10456 gfc_build_addr_expr (NULL_TREE, rse->expr));
10457 cond = gfc_evaluate_now (cond, &lse->pre);
10458 }
10459
10460 /* Deallocate the lhs allocated components as long as it is not
10461 the same as the rhs. This must be done following the assignment
10462 to prevent deallocating data that could be used in the rhs
10463 expression. */
10464 if (dealloc)
10465 {
10466 tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
10467 tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
10468 if (deep_copy)
10469 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10470 tmp);
10471 gfc_add_expr_to_block (&lse->post, tmp);
10472 }
10473
10474 gfc_add_block_to_block (&block, &rse->pre);
10475 gfc_add_block_to_block (&block, &lse->pre);
10476
10477 gfc_add_modify (&block, lse->expr,
10478 fold_convert (TREE_TYPE (lse->expr), rse->expr));
10479
10480 /* Restore pointer address of coarray components. */
10481 if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
10482 {
10483 tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
10484 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10485 tmp);
10486 gfc_add_expr_to_block (&block, tmp);
10487 }
10488
10489 /* Do a deep copy if the rhs is a variable, if it is not the
10490 same as the lhs. */
10491 if (deep_copy)
10492 {
10493 int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
10494 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0;
10495 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0,
10496 caf_mode);
10497 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10498 tmp);
10499 gfc_add_expr_to_block (&block, tmp);
10500 }
10501 }
10502 else if (gfc_bt_struct (ts.type))
10503 {
10504 gfc_add_block_to_block (&block, &lse->pre);
10505 gfc_add_block_to_block (&block, &rse->pre);
10506 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10507 TREE_TYPE (lse->expr), rse->expr);
10508 gfc_add_modify (&block, lse->expr, tmp);
10509 }
10510 /* If possible use the rhs vptr copy with trans_scalar_class_assign.... */
10511 else if (ts.type == BT_CLASS)
10512 {
10513 gfc_add_block_to_block (&block, &lse->pre);
10514 gfc_add_block_to_block (&block, &rse->pre);
10515
10516 if (!trans_scalar_class_assign (&block, lse, rse))
10517 {
10518 /* ...otherwise assignment suffices. Note the use of VIEW_CONVERT_EXPR
10519 for the lhs which ensures that class data rhs cast as a string assigns
10520 correctly. */
10521 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10522 TREE_TYPE (rse->expr), lse->expr);
10523 gfc_add_modify (&block, tmp, rse->expr);
10524 }
10525 }
10526 else if (ts.type != BT_CLASS)
10527 {
10528 gfc_add_block_to_block (&block, &lse->pre);
10529 gfc_add_block_to_block (&block, &rse->pre);
10530
10531 gfc_add_modify (&block, lse->expr,
10532 fold_convert (TREE_TYPE (lse->expr), rse->expr));
10533 }
10534
10535 gfc_add_block_to_block (&block, &lse->post);
10536 gfc_add_block_to_block (&block, &rse->post);
10537
10538 return gfc_finish_block (&block);
10539 }
10540
10541
10542 /* There are quite a lot of restrictions on the optimisation in using an
10543 array function assign without a temporary. */
10544
10545 static bool
arrayfunc_assign_needs_temporary(gfc_expr * expr1,gfc_expr * expr2)10546 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
10547 {
10548 gfc_ref * ref;
10549 bool seen_array_ref;
10550 bool c = false;
10551 gfc_symbol *sym = expr1->symtree->n.sym;
10552
10553 /* Play it safe with class functions assigned to a derived type. */
10554 if (gfc_is_class_array_function (expr2)
10555 && expr1->ts.type == BT_DERIVED)
10556 return true;
10557
10558 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
10559 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
10560 return true;
10561
10562 /* Elemental functions are scalarized so that they don't need a
10563 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
10564 they would need special treatment in gfc_trans_arrayfunc_assign. */
10565 if (expr2->value.function.esym != NULL
10566 && expr2->value.function.esym->attr.elemental)
10567 return true;
10568
10569 /* Need a temporary if rhs is not FULL or a contiguous section. */
10570 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
10571 return true;
10572
10573 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
10574 if (gfc_ref_needs_temporary_p (expr1->ref))
10575 return true;
10576
10577 /* Functions returning pointers or allocatables need temporaries. */
10578 if (gfc_expr_attr (expr2).pointer
10579 || gfc_expr_attr (expr2).allocatable)
10580 return true;
10581
10582 /* Character array functions need temporaries unless the
10583 character lengths are the same. */
10584 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
10585 {
10586 if (expr1->ts.u.cl->length == NULL
10587 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
10588 return true;
10589
10590 if (expr2->ts.u.cl->length == NULL
10591 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
10592 return true;
10593
10594 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
10595 expr2->ts.u.cl->length->value.integer) != 0)
10596 return true;
10597 }
10598
10599 /* Check that no LHS component references appear during an array
10600 reference. This is needed because we do not have the means to
10601 span any arbitrary stride with an array descriptor. This check
10602 is not needed for the rhs because the function result has to be
10603 a complete type. */
10604 seen_array_ref = false;
10605 for (ref = expr1->ref; ref; ref = ref->next)
10606 {
10607 if (ref->type == REF_ARRAY)
10608 seen_array_ref= true;
10609 else if (ref->type == REF_COMPONENT && seen_array_ref)
10610 return true;
10611 }
10612
10613 /* Check for a dependency. */
10614 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
10615 expr2->value.function.esym,
10616 expr2->value.function.actual,
10617 NOT_ELEMENTAL))
10618 return true;
10619
10620 /* If we have reached here with an intrinsic function, we do not
10621 need a temporary except in the particular case that reallocation
10622 on assignment is active and the lhs is allocatable and a target,
10623 or a pointer which may be a subref pointer. FIXME: The last
10624 condition can go away when we use span in the intrinsics
10625 directly.*/
10626 if (expr2->value.function.isym)
10627 return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target)
10628 || (sym->attr.pointer && sym->attr.subref_array_pointer);
10629
10630 /* If the LHS is a dummy, we need a temporary if it is not
10631 INTENT(OUT). */
10632 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
10633 return true;
10634
10635 /* If the lhs has been host_associated, is in common, a pointer or is
10636 a target and the function is not using a RESULT variable, aliasing
10637 can occur and a temporary is needed. */
10638 if ((sym->attr.host_assoc
10639 || sym->attr.in_common
10640 || sym->attr.pointer
10641 || sym->attr.cray_pointee
10642 || sym->attr.target)
10643 && expr2->symtree != NULL
10644 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
10645 return true;
10646
10647 /* A PURE function can unconditionally be called without a temporary. */
10648 if (expr2->value.function.esym != NULL
10649 && expr2->value.function.esym->attr.pure)
10650 return false;
10651
10652 /* Implicit_pure functions are those which could legally be declared
10653 to be PURE. */
10654 if (expr2->value.function.esym != NULL
10655 && expr2->value.function.esym->attr.implicit_pure)
10656 return false;
10657
10658 if (!sym->attr.use_assoc
10659 && !sym->attr.in_common
10660 && !sym->attr.pointer
10661 && !sym->attr.target
10662 && !sym->attr.cray_pointee
10663 && expr2->value.function.esym)
10664 {
10665 /* A temporary is not needed if the function is not contained and
10666 the variable is local or host associated and not a pointer or
10667 a target. */
10668 if (!expr2->value.function.esym->attr.contained)
10669 return false;
10670
10671 /* A temporary is not needed if the lhs has never been host
10672 associated and the procedure is contained. */
10673 else if (!sym->attr.host_assoc)
10674 return false;
10675
10676 /* A temporary is not needed if the variable is local and not
10677 a pointer, a target or a result. */
10678 if (sym->ns->parent
10679 && expr2->value.function.esym->ns == sym->ns->parent)
10680 return false;
10681 }
10682
10683 /* Default to temporary use. */
10684 return true;
10685 }
10686
10687
10688 /* Provide the loop info so that the lhs descriptor can be built for
10689 reallocatable assignments from extrinsic function calls. */
10690
10691 static void
realloc_lhs_loop_for_fcn_call(gfc_se * se,locus * where,gfc_ss ** ss,gfc_loopinfo * loop)10692 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
10693 gfc_loopinfo *loop)
10694 {
10695 /* Signal that the function call should not be made by
10696 gfc_conv_loop_setup. */
10697 se->ss->is_alloc_lhs = 1;
10698 gfc_init_loopinfo (loop);
10699 gfc_add_ss_to_loop (loop, *ss);
10700 gfc_add_ss_to_loop (loop, se->ss);
10701 gfc_conv_ss_startstride (loop);
10702 gfc_conv_loop_setup (loop, where);
10703 gfc_copy_loopinfo_to_se (se, loop);
10704 gfc_add_block_to_block (&se->pre, &loop->pre);
10705 gfc_add_block_to_block (&se->pre, &loop->post);
10706 se->ss->is_alloc_lhs = 0;
10707 }
10708
10709
10710 /* For assignment to a reallocatable lhs from intrinsic functions,
10711 replace the se.expr (ie. the result) with a temporary descriptor.
10712 Null the data field so that the library allocates space for the
10713 result. Free the data of the original descriptor after the function,
10714 in case it appears in an argument expression and transfer the
10715 result to the original descriptor. */
10716
10717 static void
fcncall_realloc_result(gfc_se * se,int rank)10718 fcncall_realloc_result (gfc_se *se, int rank)
10719 {
10720 tree desc;
10721 tree res_desc;
10722 tree tmp;
10723 tree offset;
10724 tree zero_cond;
10725 tree not_same_shape;
10726 stmtblock_t shape_block;
10727 int n;
10728
10729 /* Use the allocation done by the library. Substitute the lhs
10730 descriptor with a copy, whose data field is nulled.*/
10731 desc = build_fold_indirect_ref_loc (input_location, se->expr);
10732 if (POINTER_TYPE_P (TREE_TYPE (desc)))
10733 desc = build_fold_indirect_ref_loc (input_location, desc);
10734
10735 /* Unallocated, the descriptor does not have a dtype. */
10736 tmp = gfc_conv_descriptor_dtype (desc);
10737 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
10738
10739 res_desc = gfc_evaluate_now (desc, &se->pre);
10740 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
10741 se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
10742
10743 /* Free the lhs after the function call and copy the result data to
10744 the lhs descriptor. */
10745 tmp = gfc_conv_descriptor_data_get (desc);
10746 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
10747 logical_type_node, tmp,
10748 build_int_cst (TREE_TYPE (tmp), 0));
10749 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
10750 tmp = gfc_call_free (tmp);
10751 gfc_add_expr_to_block (&se->post, tmp);
10752
10753 tmp = gfc_conv_descriptor_data_get (res_desc);
10754 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
10755
10756 /* Check that the shapes are the same between lhs and expression.
10757 The evaluation of the shape is done in 'shape_block' to avoid
10758 unitialized warnings from the lhs bounds. */
10759 not_same_shape = boolean_false_node;
10760 gfc_start_block (&shape_block);
10761 for (n = 0 ; n < rank; n++)
10762 {
10763 tree tmp1;
10764 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10765 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
10766 tmp = fold_build2_loc (input_location, MINUS_EXPR,
10767 gfc_array_index_type, tmp, tmp1);
10768 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
10769 tmp = fold_build2_loc (input_location, MINUS_EXPR,
10770 gfc_array_index_type, tmp, tmp1);
10771 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
10772 tmp = fold_build2_loc (input_location, PLUS_EXPR,
10773 gfc_array_index_type, tmp, tmp1);
10774 tmp = fold_build2_loc (input_location, NE_EXPR,
10775 logical_type_node, tmp,
10776 gfc_index_zero_node);
10777 tmp = gfc_evaluate_now (tmp, &shape_block);
10778 if (n == 0)
10779 not_same_shape = tmp;
10780 else
10781 not_same_shape = fold_build2_loc (input_location, TRUTH_OR_EXPR,
10782 logical_type_node, tmp,
10783 not_same_shape);
10784 }
10785
10786 /* 'zero_cond' being true is equal to lhs not being allocated or the
10787 shapes being different. */
10788 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, logical_type_node,
10789 zero_cond, not_same_shape);
10790 gfc_add_modify (&shape_block, zero_cond, tmp);
10791 tmp = gfc_finish_block (&shape_block);
10792 tmp = build3_v (COND_EXPR, zero_cond,
10793 build_empty_stmt (input_location), tmp);
10794 gfc_add_expr_to_block (&se->post, tmp);
10795
10796 /* Now reset the bounds returned from the function call to bounds based
10797 on the lhs lbounds, except where the lhs is not allocated or the shapes
10798 of 'variable and 'expr' are different. Set the offset accordingly. */
10799 offset = gfc_index_zero_node;
10800 for (n = 0 ; n < rank; n++)
10801 {
10802 tree lbound;
10803
10804 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10805 lbound = fold_build3_loc (input_location, COND_EXPR,
10806 gfc_array_index_type, zero_cond,
10807 gfc_index_one_node, lbound);
10808 lbound = gfc_evaluate_now (lbound, &se->post);
10809
10810 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
10811 tmp = fold_build2_loc (input_location, PLUS_EXPR,
10812 gfc_array_index_type, tmp, lbound);
10813 gfc_conv_descriptor_lbound_set (&se->post, desc,
10814 gfc_rank_cst[n], lbound);
10815 gfc_conv_descriptor_ubound_set (&se->post, desc,
10816 gfc_rank_cst[n], tmp);
10817
10818 /* Set stride and accumulate the offset. */
10819 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
10820 gfc_conv_descriptor_stride_set (&se->post, desc,
10821 gfc_rank_cst[n], tmp);
10822 tmp = fold_build2_loc (input_location, MULT_EXPR,
10823 gfc_array_index_type, lbound, tmp);
10824 offset = fold_build2_loc (input_location, MINUS_EXPR,
10825 gfc_array_index_type, offset, tmp);
10826 offset = gfc_evaluate_now (offset, &se->post);
10827 }
10828
10829 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
10830 }
10831
10832
10833
10834 /* Try to translate array(:) = func (...), where func is a transformational
10835 array function, without using a temporary. Returns NULL if this isn't the
10836 case. */
10837
10838 static tree
gfc_trans_arrayfunc_assign(gfc_expr * expr1,gfc_expr * expr2)10839 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
10840 {
10841 gfc_se se;
10842 gfc_ss *ss = NULL;
10843 gfc_component *comp = NULL;
10844 gfc_loopinfo loop;
10845
10846 if (arrayfunc_assign_needs_temporary (expr1, expr2))
10847 return NULL;
10848
10849 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
10850 functions. */
10851 comp = gfc_get_proc_ptr_comp (expr2);
10852
10853 if (!(expr2->value.function.isym
10854 || (comp && comp->attr.dimension)
10855 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
10856 && expr2->value.function.esym->result->attr.dimension)))
10857 return NULL;
10858
10859 gfc_init_se (&se, NULL);
10860 gfc_start_block (&se.pre);
10861 se.want_pointer = 1;
10862
10863 gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
10864
10865 if (expr1->ts.type == BT_DERIVED
10866 && expr1->ts.u.derived->attr.alloc_comp)
10867 {
10868 tree tmp;
10869 tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
10870 expr1->rank);
10871 gfc_add_expr_to_block (&se.pre, tmp);
10872 }
10873
10874 se.direct_byref = 1;
10875 se.ss = gfc_walk_expr (expr2);
10876 gcc_assert (se.ss != gfc_ss_terminator);
10877
10878 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
10879 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
10880 Clearly, this cannot be done for an allocatable function result, since
10881 the shape of the result is unknown and, in any case, the function must
10882 correctly take care of the reallocation internally. For intrinsic
10883 calls, the array data is freed and the library takes care of allocation.
10884 TODO: Add logic of trans-array.cc: gfc_alloc_allocatable_for_assignment
10885 to the library. */
10886 if (flag_realloc_lhs
10887 && gfc_is_reallocatable_lhs (expr1)
10888 && !gfc_expr_attr (expr1).codimension
10889 && !gfc_is_coindexed (expr1)
10890 && !(expr2->value.function.esym
10891 && expr2->value.function.esym->result->attr.allocatable))
10892 {
10893 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
10894
10895 if (!expr2->value.function.isym)
10896 {
10897 ss = gfc_walk_expr (expr1);
10898 gcc_assert (ss != gfc_ss_terminator);
10899
10900 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
10901 ss->is_alloc_lhs = 1;
10902 }
10903 else
10904 fcncall_realloc_result (&se, expr1->rank);
10905 }
10906
10907 gfc_conv_function_expr (&se, expr2);
10908 gfc_add_block_to_block (&se.pre, &se.post);
10909
10910 if (ss)
10911 gfc_cleanup_loop (&loop);
10912 else
10913 gfc_free_ss_chain (se.ss);
10914
10915 return gfc_finish_block (&se.pre);
10916 }
10917
10918
10919 /* Try to efficiently translate array(:) = 0. Return NULL if this
10920 can't be done. */
10921
10922 static tree
gfc_trans_zero_assign(gfc_expr * expr)10923 gfc_trans_zero_assign (gfc_expr * expr)
10924 {
10925 tree dest, len, type;
10926 tree tmp;
10927 gfc_symbol *sym;
10928
10929 sym = expr->symtree->n.sym;
10930 dest = gfc_get_symbol_decl (sym);
10931
10932 type = TREE_TYPE (dest);
10933 if (POINTER_TYPE_P (type))
10934 type = TREE_TYPE (type);
10935 if (!GFC_ARRAY_TYPE_P (type))
10936 return NULL_TREE;
10937
10938 /* Determine the length of the array. */
10939 len = GFC_TYPE_ARRAY_SIZE (type);
10940 if (!len || TREE_CODE (len) != INTEGER_CST)
10941 return NULL_TREE;
10942
10943 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
10944 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
10945 fold_convert (gfc_array_index_type, tmp));
10946
10947 /* If we are zeroing a local array avoid taking its address by emitting
10948 a = {} instead. */
10949 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
10950 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
10951 dest, build_constructor (TREE_TYPE (dest),
10952 NULL));
10953
10954 /* Convert arguments to the correct types. */
10955 dest = fold_convert (pvoid_type_node, dest);
10956 len = fold_convert (size_type_node, len);
10957
10958 /* Construct call to __builtin_memset. */
10959 tmp = build_call_expr_loc (input_location,
10960 builtin_decl_explicit (BUILT_IN_MEMSET),
10961 3, dest, integer_zero_node, len);
10962 return fold_convert (void_type_node, tmp);
10963 }
10964
10965
10966 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
10967 that constructs the call to __builtin_memcpy. */
10968
10969 tree
gfc_build_memcpy_call(tree dst,tree src,tree len)10970 gfc_build_memcpy_call (tree dst, tree src, tree len)
10971 {
10972 tree tmp;
10973
10974 /* Convert arguments to the correct types. */
10975 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
10976 dst = gfc_build_addr_expr (pvoid_type_node, dst);
10977 else
10978 dst = fold_convert (pvoid_type_node, dst);
10979
10980 if (!POINTER_TYPE_P (TREE_TYPE (src)))
10981 src = gfc_build_addr_expr (pvoid_type_node, src);
10982 else
10983 src = fold_convert (pvoid_type_node, src);
10984
10985 len = fold_convert (size_type_node, len);
10986
10987 /* Construct call to __builtin_memcpy. */
10988 tmp = build_call_expr_loc (input_location,
10989 builtin_decl_explicit (BUILT_IN_MEMCPY),
10990 3, dst, src, len);
10991 return fold_convert (void_type_node, tmp);
10992 }
10993
10994
10995 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
10996 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
10997 source/rhs, both are gfc_full_array_ref_p which have been checked for
10998 dependencies. */
10999
11000 static tree
gfc_trans_array_copy(gfc_expr * expr1,gfc_expr * expr2)11001 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
11002 {
11003 tree dst, dlen, dtype;
11004 tree src, slen, stype;
11005 tree tmp;
11006
11007 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
11008 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
11009
11010 dtype = TREE_TYPE (dst);
11011 if (POINTER_TYPE_P (dtype))
11012 dtype = TREE_TYPE (dtype);
11013 stype = TREE_TYPE (src);
11014 if (POINTER_TYPE_P (stype))
11015 stype = TREE_TYPE (stype);
11016
11017 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
11018 return NULL_TREE;
11019
11020 /* Determine the lengths of the arrays. */
11021 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
11022 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
11023 return NULL_TREE;
11024 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
11025 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
11026 dlen, fold_convert (gfc_array_index_type, tmp));
11027
11028 slen = GFC_TYPE_ARRAY_SIZE (stype);
11029 if (!slen || TREE_CODE (slen) != INTEGER_CST)
11030 return NULL_TREE;
11031 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
11032 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
11033 slen, fold_convert (gfc_array_index_type, tmp));
11034
11035 /* Sanity check that they are the same. This should always be
11036 the case, as we should already have checked for conformance. */
11037 if (!tree_int_cst_equal (slen, dlen))
11038 return NULL_TREE;
11039
11040 return gfc_build_memcpy_call (dst, src, dlen);
11041 }
11042
11043
11044 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
11045 this can't be done. EXPR1 is the destination/lhs for which
11046 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
11047
11048 static tree
gfc_trans_array_constructor_copy(gfc_expr * expr1,gfc_expr * expr2)11049 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
11050 {
11051 unsigned HOST_WIDE_INT nelem;
11052 tree dst, dtype;
11053 tree src, stype;
11054 tree len;
11055 tree tmp;
11056
11057 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
11058 if (nelem == 0)
11059 return NULL_TREE;
11060
11061 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
11062 dtype = TREE_TYPE (dst);
11063 if (POINTER_TYPE_P (dtype))
11064 dtype = TREE_TYPE (dtype);
11065 if (!GFC_ARRAY_TYPE_P (dtype))
11066 return NULL_TREE;
11067
11068 /* Determine the lengths of the array. */
11069 len = GFC_TYPE_ARRAY_SIZE (dtype);
11070 if (!len || TREE_CODE (len) != INTEGER_CST)
11071 return NULL_TREE;
11072
11073 /* Confirm that the constructor is the same size. */
11074 if (compare_tree_int (len, nelem) != 0)
11075 return NULL_TREE;
11076
11077 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
11078 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
11079 fold_convert (gfc_array_index_type, tmp));
11080
11081 stype = gfc_typenode_for_spec (&expr2->ts);
11082 src = gfc_build_constant_array_constructor (expr2, stype);
11083
11084 return gfc_build_memcpy_call (dst, src, len);
11085 }
11086
11087
11088 /* Tells whether the expression is to be treated as a variable reference. */
11089
11090 bool
gfc_expr_is_variable(gfc_expr * expr)11091 gfc_expr_is_variable (gfc_expr *expr)
11092 {
11093 gfc_expr *arg;
11094 gfc_component *comp;
11095 gfc_symbol *func_ifc;
11096
11097 if (expr->expr_type == EXPR_VARIABLE)
11098 return true;
11099
11100 arg = gfc_get_noncopying_intrinsic_argument (expr);
11101 if (arg)
11102 {
11103 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
11104 return gfc_expr_is_variable (arg);
11105 }
11106
11107 /* A data-pointer-returning function should be considered as a variable
11108 too. */
11109 if (expr->expr_type == EXPR_FUNCTION
11110 && expr->ref == NULL)
11111 {
11112 if (expr->value.function.isym != NULL)
11113 return false;
11114
11115 if (expr->value.function.esym != NULL)
11116 {
11117 func_ifc = expr->value.function.esym;
11118 goto found_ifc;
11119 }
11120 gcc_assert (expr->symtree);
11121 func_ifc = expr->symtree->n.sym;
11122 goto found_ifc;
11123 }
11124
11125 comp = gfc_get_proc_ptr_comp (expr);
11126 if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
11127 && comp)
11128 {
11129 func_ifc = comp->ts.interface;
11130 goto found_ifc;
11131 }
11132
11133 if (expr->expr_type == EXPR_COMPCALL)
11134 {
11135 gcc_assert (!expr->value.compcall.tbp->is_generic);
11136 func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
11137 goto found_ifc;
11138 }
11139
11140 return false;
11141
11142 found_ifc:
11143 gcc_assert (func_ifc->attr.function
11144 && func_ifc->result != NULL);
11145 return func_ifc->result->attr.pointer;
11146 }
11147
11148
11149 /* Is the lhs OK for automatic reallocation? */
11150
11151 static bool
is_scalar_reallocatable_lhs(gfc_expr * expr)11152 is_scalar_reallocatable_lhs (gfc_expr *expr)
11153 {
11154 gfc_ref * ref;
11155
11156 /* An allocatable variable with no reference. */
11157 if (expr->symtree->n.sym->attr.allocatable
11158 && !expr->ref)
11159 return true;
11160
11161 /* All that can be left are allocatable components. However, we do
11162 not check for allocatable components here because the expression
11163 could be an allocatable component of a pointer component. */
11164 if (expr->symtree->n.sym->ts.type != BT_DERIVED
11165 && expr->symtree->n.sym->ts.type != BT_CLASS)
11166 return false;
11167
11168 /* Find an allocatable component ref last. */
11169 for (ref = expr->ref; ref; ref = ref->next)
11170 if (ref->type == REF_COMPONENT
11171 && !ref->next
11172 && ref->u.c.component->attr.allocatable)
11173 return true;
11174
11175 return false;
11176 }
11177
11178
11179 /* Allocate or reallocate scalar lhs, as necessary. */
11180
11181 static void
alloc_scalar_allocatable_for_assignment(stmtblock_t * block,tree string_length,gfc_expr * expr1,gfc_expr * expr2)11182 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
11183 tree string_length,
11184 gfc_expr *expr1,
11185 gfc_expr *expr2)
11186
11187 {
11188 tree cond;
11189 tree tmp;
11190 tree size;
11191 tree size_in_bytes;
11192 tree jump_label1;
11193 tree jump_label2;
11194 gfc_se lse;
11195 gfc_ref *ref;
11196
11197 if (!expr1 || expr1->rank)
11198 return;
11199
11200 if (!expr2 || expr2->rank)
11201 return;
11202
11203 for (ref = expr1->ref; ref; ref = ref->next)
11204 if (ref->type == REF_SUBSTRING)
11205 return;
11206
11207 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
11208
11209 /* Since this is a scalar lhs, we can afford to do this. That is,
11210 there is no risk of side effects being repeated. */
11211 gfc_init_se (&lse, NULL);
11212 lse.want_pointer = 1;
11213 gfc_conv_expr (&lse, expr1);
11214
11215 jump_label1 = gfc_build_label_decl (NULL_TREE);
11216 jump_label2 = gfc_build_label_decl (NULL_TREE);
11217
11218 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
11219 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
11220 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
11221 lse.expr, tmp);
11222 tmp = build3_v (COND_EXPR, cond,
11223 build1_v (GOTO_EXPR, jump_label1),
11224 build_empty_stmt (input_location));
11225 gfc_add_expr_to_block (block, tmp);
11226
11227 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11228 {
11229 /* Use the rhs string length and the lhs element size. */
11230 size = string_length;
11231 tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
11232 tmp = TYPE_SIZE_UNIT (tmp);
11233 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
11234 TREE_TYPE (tmp), tmp,
11235 fold_convert (TREE_TYPE (tmp), size));
11236 }
11237 else
11238 {
11239 /* Otherwise use the length in bytes of the rhs. */
11240 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
11241 size_in_bytes = size;
11242 }
11243
11244 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
11245 size_in_bytes, size_one_node);
11246
11247 if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB)
11248 {
11249 tree caf_decl, token;
11250 gfc_se caf_se;
11251 symbol_attribute attr;
11252
11253 gfc_clear_attr (&attr);
11254 gfc_init_se (&caf_se, NULL);
11255
11256 caf_decl = gfc_get_tree_for_caf_expr (expr1);
11257 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE,
11258 NULL);
11259 gfc_add_block_to_block (block, &caf_se.pre);
11260 gfc_allocate_allocatable (block, lse.expr, size_in_bytes,
11261 gfc_build_addr_expr (NULL_TREE, token),
11262 NULL_TREE, NULL_TREE, NULL_TREE, jump_label1,
11263 expr1, 1);
11264 }
11265 else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
11266 {
11267 tmp = build_call_expr_loc (input_location,
11268 builtin_decl_explicit (BUILT_IN_CALLOC),
11269 2, build_one_cst (size_type_node),
11270 size_in_bytes);
11271 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11272 gfc_add_modify (block, lse.expr, tmp);
11273 }
11274 else
11275 {
11276 tmp = build_call_expr_loc (input_location,
11277 builtin_decl_explicit (BUILT_IN_MALLOC),
11278 1, size_in_bytes);
11279 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11280 gfc_add_modify (block, lse.expr, tmp);
11281 }
11282
11283 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11284 {
11285 /* Deferred characters need checking for lhs and rhs string
11286 length. Other deferred parameter variables will have to
11287 come here too. */
11288 tmp = build1_v (GOTO_EXPR, jump_label2);
11289 gfc_add_expr_to_block (block, tmp);
11290 }
11291 tmp = build1_v (LABEL_EXPR, jump_label1);
11292 gfc_add_expr_to_block (block, tmp);
11293
11294 /* For a deferred length character, reallocate if lengths of lhs and
11295 rhs are different. */
11296 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11297 {
11298 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
11299 lse.string_length,
11300 fold_convert (TREE_TYPE (lse.string_length),
11301 size));
11302 /* Jump past the realloc if the lengths are the same. */
11303 tmp = build3_v (COND_EXPR, cond,
11304 build1_v (GOTO_EXPR, jump_label2),
11305 build_empty_stmt (input_location));
11306 gfc_add_expr_to_block (block, tmp);
11307 tmp = build_call_expr_loc (input_location,
11308 builtin_decl_explicit (BUILT_IN_REALLOC),
11309 2, fold_convert (pvoid_type_node, lse.expr),
11310 size_in_bytes);
11311 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
11312 gfc_add_modify (block, lse.expr, tmp);
11313 tmp = build1_v (LABEL_EXPR, jump_label2);
11314 gfc_add_expr_to_block (block, tmp);
11315
11316 /* Update the lhs character length. */
11317 size = string_length;
11318 gfc_add_modify (block, lse.string_length,
11319 fold_convert (TREE_TYPE (lse.string_length), size));
11320 }
11321 }
11322
11323 /* Check for assignments of the type
11324
11325 a = a + 4
11326
11327 to make sure we do not check for reallocation unneccessarily. */
11328
11329
11330 static bool
is_runtime_conformable(gfc_expr * expr1,gfc_expr * expr2)11331 is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
11332 {
11333 gfc_actual_arglist *a;
11334 gfc_expr *e1, *e2;
11335
11336 switch (expr2->expr_type)
11337 {
11338 case EXPR_VARIABLE:
11339 return gfc_dep_compare_expr (expr1, expr2) == 0;
11340
11341 case EXPR_FUNCTION:
11342 if (expr2->value.function.esym
11343 && expr2->value.function.esym->attr.elemental)
11344 {
11345 for (a = expr2->value.function.actual; a != NULL; a = a->next)
11346 {
11347 e1 = a->expr;
11348 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
11349 return false;
11350 }
11351 return true;
11352 }
11353 else if (expr2->value.function.isym
11354 && expr2->value.function.isym->elemental)
11355 {
11356 for (a = expr2->value.function.actual; a != NULL; a = a->next)
11357 {
11358 e1 = a->expr;
11359 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
11360 return false;
11361 }
11362 return true;
11363 }
11364
11365 break;
11366
11367 case EXPR_OP:
11368 switch (expr2->value.op.op)
11369 {
11370 case INTRINSIC_NOT:
11371 case INTRINSIC_UPLUS:
11372 case INTRINSIC_UMINUS:
11373 case INTRINSIC_PARENTHESES:
11374 return is_runtime_conformable (expr1, expr2->value.op.op1);
11375
11376 case INTRINSIC_PLUS:
11377 case INTRINSIC_MINUS:
11378 case INTRINSIC_TIMES:
11379 case INTRINSIC_DIVIDE:
11380 case INTRINSIC_POWER:
11381 case INTRINSIC_AND:
11382 case INTRINSIC_OR:
11383 case INTRINSIC_EQV:
11384 case INTRINSIC_NEQV:
11385 case INTRINSIC_EQ:
11386 case INTRINSIC_NE:
11387 case INTRINSIC_GT:
11388 case INTRINSIC_GE:
11389 case INTRINSIC_LT:
11390 case INTRINSIC_LE:
11391 case INTRINSIC_EQ_OS:
11392 case INTRINSIC_NE_OS:
11393 case INTRINSIC_GT_OS:
11394 case INTRINSIC_GE_OS:
11395 case INTRINSIC_LT_OS:
11396 case INTRINSIC_LE_OS:
11397
11398 e1 = expr2->value.op.op1;
11399 e2 = expr2->value.op.op2;
11400
11401 if (e1->rank == 0 && e2->rank > 0)
11402 return is_runtime_conformable (expr1, e2);
11403 else if (e1->rank > 0 && e2->rank == 0)
11404 return is_runtime_conformable (expr1, e1);
11405 else if (e1->rank > 0 && e2->rank > 0)
11406 return is_runtime_conformable (expr1, e1)
11407 && is_runtime_conformable (expr1, e2);
11408 break;
11409
11410 default:
11411 break;
11412
11413 }
11414
11415 break;
11416
11417 default:
11418 break;
11419 }
11420 return false;
11421 }
11422
11423
11424 static tree
trans_class_assignment(stmtblock_t * block,gfc_expr * lhs,gfc_expr * rhs,gfc_se * lse,gfc_se * rse,bool use_vptr_copy,bool class_realloc)11425 trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
11426 gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
11427 bool class_realloc)
11428 {
11429 tree tmp, fcn, stdcopy, to_len, from_len, vptr, old_vptr;
11430 vec<tree, va_gc> *args = NULL;
11431
11432 /* Store the old vptr so that dynamic types can be compared for
11433 reallocation to occur or not. */
11434 if (class_realloc)
11435 {
11436 tmp = lse->expr;
11437 if (!GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11438 tmp = gfc_get_class_from_expr (tmp);
11439 }
11440
11441 vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
11442 &from_len);
11443
11444 /* Generate (re)allocation of the lhs. */
11445 if (class_realloc)
11446 {
11447 stmtblock_t alloc, re_alloc;
11448 tree class_han, re, size;
11449
11450 if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11451 old_vptr = gfc_evaluate_now (gfc_class_vptr_get (tmp), block);
11452 else
11453 old_vptr = build_int_cst (TREE_TYPE (vptr), 0);
11454
11455 size = gfc_vptr_size_get (vptr);
11456 class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11457 ? gfc_class_data_get (lse->expr) : lse->expr;
11458
11459 if (!POINTER_TYPE_P (TREE_TYPE (class_han)))
11460 class_han = gfc_build_addr_expr (NULL_TREE, class_han);
11461
11462 /* Allocate block. */
11463 gfc_init_block (&alloc);
11464 gfc_allocate_using_malloc (&alloc, class_han, size, NULL_TREE);
11465
11466 /* Reallocate if dynamic types are different. */
11467 gfc_init_block (&re_alloc);
11468 re = build_call_expr_loc (input_location,
11469 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
11470 fold_convert (pvoid_type_node, class_han),
11471 size);
11472 tmp = fold_build2_loc (input_location, NE_EXPR,
11473 logical_type_node, vptr, old_vptr);
11474 re = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11475 tmp, re, build_empty_stmt (input_location));
11476 gfc_add_expr_to_block (&re_alloc, re);
11477
11478 /* Allocate if _data is NULL, reallocate otherwise. */
11479 tmp = fold_build2_loc (input_location, EQ_EXPR,
11480 logical_type_node, class_han,
11481 build_int_cst (prvoid_type_node, 0));
11482 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11483 gfc_unlikely (tmp,
11484 PRED_FORTRAN_FAIL_ALLOC),
11485 gfc_finish_block (&alloc),
11486 gfc_finish_block (&re_alloc));
11487 gfc_add_expr_to_block (&lse->pre, tmp);
11488 }
11489
11490 fcn = gfc_vptr_copy_get (vptr);
11491
11492 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
11493 ? gfc_class_data_get (rse->expr) : rse->expr;
11494 if (use_vptr_copy)
11495 {
11496 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11497 || INDIRECT_REF_P (tmp)
11498 || (rhs->ts.type == BT_DERIVED
11499 && rhs->ts.u.derived->attr.unlimited_polymorphic
11500 && !rhs->ts.u.derived->attr.pointer
11501 && !rhs->ts.u.derived->attr.allocatable)
11502 || (UNLIMITED_POLY (rhs)
11503 && !CLASS_DATA (rhs)->attr.pointer
11504 && !CLASS_DATA (rhs)->attr.allocatable))
11505 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11506 else
11507 vec_safe_push (args, tmp);
11508 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11509 ? gfc_class_data_get (lse->expr) : lse->expr;
11510 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11511 || INDIRECT_REF_P (tmp)
11512 || (lhs->ts.type == BT_DERIVED
11513 && lhs->ts.u.derived->attr.unlimited_polymorphic
11514 && !lhs->ts.u.derived->attr.pointer
11515 && !lhs->ts.u.derived->attr.allocatable)
11516 || (UNLIMITED_POLY (lhs)
11517 && !CLASS_DATA (lhs)->attr.pointer
11518 && !CLASS_DATA (lhs)->attr.allocatable))
11519 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11520 else
11521 vec_safe_push (args, tmp);
11522
11523 stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11524
11525 if (to_len != NULL_TREE && !integer_zerop (from_len))
11526 {
11527 tree extcopy;
11528 vec_safe_push (args, from_len);
11529 vec_safe_push (args, to_len);
11530 extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11531
11532 tmp = fold_build2_loc (input_location, GT_EXPR,
11533 logical_type_node, from_len,
11534 build_zero_cst (TREE_TYPE (from_len)));
11535 return fold_build3_loc (input_location, COND_EXPR,
11536 void_type_node, tmp,
11537 extcopy, stdcopy);
11538 }
11539 else
11540 return stdcopy;
11541 }
11542 else
11543 {
11544 tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11545 ? gfc_class_data_get (lse->expr) : lse->expr;
11546 stmtblock_t tblock;
11547 gfc_init_block (&tblock);
11548 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
11549 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
11550 if (!POINTER_TYPE_P (TREE_TYPE (rhst)))
11551 rhst = gfc_build_addr_expr (NULL_TREE, rhst);
11552 /* When coming from a ptr_copy lhs and rhs are swapped. */
11553 gfc_add_modify_loc (input_location, &tblock, rhst,
11554 fold_convert (TREE_TYPE (rhst), tmp));
11555 return gfc_finish_block (&tblock);
11556 }
11557 }
11558
11559 /* Subroutine of gfc_trans_assignment that actually scalarizes the
11560 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
11561 init_flag indicates initialization expressions and dealloc that no
11562 deallocate prior assignment is needed (if in doubt, set true).
11563 When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
11564 routine instead of a pointer assignment. Alias resolution is only done,
11565 when MAY_ALIAS is set (the default). This flag is used by ALLOCATE()
11566 where it is known, that newly allocated memory on the lhs can never be
11567 an alias of the rhs. */
11568
11569 static tree
gfc_trans_assignment_1(gfc_expr * expr1,gfc_expr * expr2,bool init_flag,bool dealloc,bool use_vptr_copy,bool may_alias)11570 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
11571 bool dealloc, bool use_vptr_copy, bool may_alias)
11572 {
11573 gfc_se lse;
11574 gfc_se rse;
11575 gfc_ss *lss;
11576 gfc_ss *lss_section;
11577 gfc_ss *rss;
11578 gfc_loopinfo loop;
11579 tree tmp;
11580 stmtblock_t block;
11581 stmtblock_t body;
11582 bool l_is_temp;
11583 bool scalar_to_array;
11584 tree string_length;
11585 int n;
11586 bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false;
11587 symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
11588 bool is_poly_assign;
11589 bool realloc_flag;
11590
11591 /* Assignment of the form lhs = rhs. */
11592 gfc_start_block (&block);
11593
11594 gfc_init_se (&lse, NULL);
11595 gfc_init_se (&rse, NULL);
11596
11597 /* Walk the lhs. */
11598 lss = gfc_walk_expr (expr1);
11599 if (gfc_is_reallocatable_lhs (expr1))
11600 {
11601 lss->no_bounds_check = 1;
11602 if (!(expr2->expr_type == EXPR_FUNCTION
11603 && expr2->value.function.isym != NULL
11604 && !(expr2->value.function.isym->elemental
11605 || expr2->value.function.isym->conversion)))
11606 lss->is_alloc_lhs = 1;
11607 }
11608 else
11609 lss->no_bounds_check = expr1->no_bounds_check;
11610
11611 rss = NULL;
11612
11613 if ((expr1->ts.type == BT_DERIVED)
11614 && (gfc_is_class_array_function (expr2)
11615 || gfc_is_alloc_class_scalar_function (expr2)))
11616 expr2->must_finalize = 1;
11617
11618 /* Checking whether a class assignment is desired is quite complicated and
11619 needed at two locations, so do it once only before the information is
11620 needed. */
11621 lhs_attr = gfc_expr_attr (expr1);
11622 is_poly_assign = (use_vptr_copy || lhs_attr.pointer
11623 || (lhs_attr.allocatable && !lhs_attr.dimension))
11624 && (expr1->ts.type == BT_CLASS
11625 || gfc_is_class_array_ref (expr1, NULL)
11626 || gfc_is_class_scalar_expr (expr1)
11627 || gfc_is_class_array_ref (expr2, NULL)
11628 || gfc_is_class_scalar_expr (expr2))
11629 && lhs_attr.flavor != FL_PROCEDURE;
11630
11631 realloc_flag = flag_realloc_lhs
11632 && gfc_is_reallocatable_lhs (expr1)
11633 && expr2->rank
11634 && !is_runtime_conformable (expr1, expr2);
11635
11636 /* Only analyze the expressions for coarray properties, when in coarray-lib
11637 mode. */
11638 if (flag_coarray == GFC_FCOARRAY_LIB)
11639 {
11640 lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp);
11641 rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp);
11642 }
11643
11644 if (lss != gfc_ss_terminator)
11645 {
11646 /* The assignment needs scalarization. */
11647 lss_section = lss;
11648
11649 /* Find a non-scalar SS from the lhs. */
11650 while (lss_section != gfc_ss_terminator
11651 && lss_section->info->type != GFC_SS_SECTION)
11652 lss_section = lss_section->next;
11653
11654 gcc_assert (lss_section != gfc_ss_terminator);
11655
11656 /* Initialize the scalarizer. */
11657 gfc_init_loopinfo (&loop);
11658
11659 /* Walk the rhs. */
11660 rss = gfc_walk_expr (expr2);
11661 if (rss == gfc_ss_terminator)
11662 /* The rhs is scalar. Add a ss for the expression. */
11663 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
11664 /* When doing a class assign, then the handle to the rhs needs to be a
11665 pointer to allow for polymorphism. */
11666 if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
11667 rss->info->type = GFC_SS_REFERENCE;
11668
11669 rss->no_bounds_check = expr2->no_bounds_check;
11670 /* Associate the SS with the loop. */
11671 gfc_add_ss_to_loop (&loop, lss);
11672 gfc_add_ss_to_loop (&loop, rss);
11673
11674 /* Calculate the bounds of the scalarization. */
11675 gfc_conv_ss_startstride (&loop);
11676 /* Enable loop reversal. */
11677 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
11678 loop.reverse[n] = GFC_ENABLE_REVERSE;
11679 /* Resolve any data dependencies in the statement. */
11680 if (may_alias)
11681 gfc_conv_resolve_dependencies (&loop, lss, rss);
11682 /* Setup the scalarizing loops. */
11683 gfc_conv_loop_setup (&loop, &expr2->where);
11684
11685 /* Setup the gfc_se structures. */
11686 gfc_copy_loopinfo_to_se (&lse, &loop);
11687 gfc_copy_loopinfo_to_se (&rse, &loop);
11688
11689 rse.ss = rss;
11690 gfc_mark_ss_chain_used (rss, 1);
11691 if (loop.temp_ss == NULL)
11692 {
11693 lse.ss = lss;
11694 gfc_mark_ss_chain_used (lss, 1);
11695 }
11696 else
11697 {
11698 lse.ss = loop.temp_ss;
11699 gfc_mark_ss_chain_used (lss, 3);
11700 gfc_mark_ss_chain_used (loop.temp_ss, 3);
11701 }
11702
11703 /* Allow the scalarizer to workshare array assignments. */
11704 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
11705 == OMPWS_WORKSHARE_FLAG
11706 && loop.temp_ss == NULL)
11707 {
11708 maybe_workshare = true;
11709 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
11710 }
11711
11712 /* Start the scalarized loop body. */
11713 gfc_start_scalarized_body (&loop, &body);
11714 }
11715 else
11716 gfc_init_block (&body);
11717
11718 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
11719
11720 /* Translate the expression. */
11721 rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag
11722 && lhs_caf_attr.codimension;
11723 gfc_conv_expr (&rse, expr2);
11724
11725 /* Deal with the case of a scalar class function assigned to a derived type. */
11726 if (gfc_is_alloc_class_scalar_function (expr2)
11727 && expr1->ts.type == BT_DERIVED)
11728 {
11729 rse.expr = gfc_class_data_get (rse.expr);
11730 rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
11731 }
11732
11733 /* Stabilize a string length for temporaries. */
11734 if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred
11735 && !(VAR_P (rse.string_length)
11736 || TREE_CODE (rse.string_length) == PARM_DECL
11737 || TREE_CODE (rse.string_length) == INDIRECT_REF))
11738 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
11739 else if (expr2->ts.type == BT_CHARACTER)
11740 {
11741 if (expr1->ts.deferred
11742 && gfc_expr_attr (expr1).allocatable
11743 && gfc_check_dependency (expr1, expr2, true))
11744 rse.string_length =
11745 gfc_evaluate_now_function_scope (rse.string_length, &rse.pre);
11746 string_length = rse.string_length;
11747 }
11748 else
11749 string_length = NULL_TREE;
11750
11751 if (l_is_temp)
11752 {
11753 gfc_conv_tmp_array_ref (&lse);
11754 if (expr2->ts.type == BT_CHARACTER)
11755 lse.string_length = string_length;
11756 }
11757 else
11758 {
11759 gfc_conv_expr (&lse, expr1);
11760 if (gfc_option.rtcheck & GFC_RTCHECK_MEM
11761 && !init_flag
11762 && gfc_expr_attr (expr1).allocatable
11763 && expr1->rank
11764 && !expr2->rank)
11765 {
11766 tree cond;
11767 const char* msg;
11768
11769 tmp = INDIRECT_REF_P (lse.expr)
11770 ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
11771 STRIP_NOPS (tmp);
11772
11773 /* We should only get array references here. */
11774 gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
11775 || TREE_CODE (tmp) == ARRAY_REF);
11776
11777 /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
11778 or the array itself(ARRAY_REF). */
11779 tmp = TREE_OPERAND (tmp, 0);
11780
11781 /* Provide the address of the array. */
11782 if (TREE_CODE (lse.expr) == ARRAY_REF)
11783 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
11784
11785 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
11786 tmp, build_int_cst (TREE_TYPE (tmp), 0));
11787 msg = _("Assignment of scalar to unallocated array");
11788 gfc_trans_runtime_check (true, false, cond, &loop.pre,
11789 &expr1->where, msg);
11790 }
11791
11792 /* Deallocate the lhs parameterized components if required. */
11793 if (dealloc && expr2->expr_type == EXPR_FUNCTION
11794 && !expr1->symtree->n.sym->attr.associate_var)
11795 {
11796 if (expr1->ts.type == BT_DERIVED
11797 && expr1->ts.u.derived
11798 && expr1->ts.u.derived->attr.pdt_type)
11799 {
11800 tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr,
11801 expr1->rank);
11802 gfc_add_expr_to_block (&lse.pre, tmp);
11803 }
11804 else if (expr1->ts.type == BT_CLASS
11805 && CLASS_DATA (expr1)->ts.u.derived
11806 && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type)
11807 {
11808 tmp = gfc_class_data_get (lse.expr);
11809 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived,
11810 tmp, expr1->rank);
11811 gfc_add_expr_to_block (&lse.pre, tmp);
11812 }
11813 }
11814 }
11815
11816 /* Assignments of scalar derived types with allocatable components
11817 to arrays must be done with a deep copy and the rhs temporary
11818 must have its components deallocated afterwards. */
11819 scalar_to_array = (expr2->ts.type == BT_DERIVED
11820 && expr2->ts.u.derived->attr.alloc_comp
11821 && !gfc_expr_is_variable (expr2)
11822 && expr1->rank && !expr2->rank);
11823 scalar_to_array |= (expr1->ts.type == BT_DERIVED
11824 && expr1->rank
11825 && expr1->ts.u.derived->attr.alloc_comp
11826 && gfc_is_alloc_class_scalar_function (expr2));
11827 if (scalar_to_array && dealloc)
11828 {
11829 tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
11830 gfc_prepend_expr_to_block (&loop.post, tmp);
11831 }
11832
11833 /* When assigning a character function result to a deferred-length variable,
11834 the function call must happen before the (re)allocation of the lhs -
11835 otherwise the character length of the result is not known.
11836 NOTE 1: This relies on having the exact dependence of the length type
11837 parameter available to the caller; gfortran saves it in the .mod files.
11838 NOTE 2: Vector array references generate an index temporary that must
11839 not go outside the loop. Otherwise, variables should not generate
11840 a pre block.
11841 NOTE 3: The concatenation operation generates a temporary pointer,
11842 whose allocation must go to the innermost loop.
11843 NOTE 4: Elemental functions may generate a temporary, too. */
11844 if (flag_realloc_lhs
11845 && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
11846 && !(lss != gfc_ss_terminator
11847 && rss != gfc_ss_terminator
11848 && ((expr2->expr_type == EXPR_VARIABLE && expr2->rank)
11849 || (expr2->expr_type == EXPR_FUNCTION
11850 && expr2->value.function.esym != NULL
11851 && expr2->value.function.esym->attr.elemental)
11852 || (expr2->expr_type == EXPR_FUNCTION
11853 && expr2->value.function.isym != NULL
11854 && expr2->value.function.isym->elemental)
11855 || (expr2->expr_type == EXPR_OP
11856 && expr2->value.op.op == INTRINSIC_CONCAT))))
11857 gfc_add_block_to_block (&block, &rse.pre);
11858
11859 /* Nullify the allocatable components corresponding to those of the lhs
11860 derived type, so that the finalization of the function result does not
11861 affect the lhs of the assignment. Prepend is used to ensure that the
11862 nullification occurs before the call to the finalizer. In the case of
11863 a scalar to array assignment, this is done in gfc_trans_scalar_assign
11864 as part of the deep copy. */
11865 if (!scalar_to_array && expr1->ts.type == BT_DERIVED
11866 && (gfc_is_class_array_function (expr2)
11867 || gfc_is_alloc_class_scalar_function (expr2)))
11868 {
11869 tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
11870 gfc_prepend_expr_to_block (&rse.post, tmp);
11871 if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
11872 gfc_add_block_to_block (&loop.post, &rse.post);
11873 }
11874
11875 tmp = NULL_TREE;
11876
11877 if (is_poly_assign)
11878 {
11879 tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
11880 use_vptr_copy || (lhs_attr.allocatable
11881 && !lhs_attr.dimension),
11882 !realloc_flag && flag_realloc_lhs
11883 && !lhs_attr.pointer);
11884 if (expr2->expr_type == EXPR_FUNCTION
11885 && expr2->ts.type == BT_DERIVED
11886 && expr2->ts.u.derived->attr.alloc_comp)
11887 {
11888 tree tmp2 = gfc_deallocate_alloc_comp (expr2->ts.u.derived,
11889 rse.expr, expr2->rank);
11890 if (lss == gfc_ss_terminator)
11891 gfc_add_expr_to_block (&rse.post, tmp2);
11892 else
11893 gfc_add_expr_to_block (&loop.post, tmp2);
11894 }
11895 }
11896 else if (flag_coarray == GFC_FCOARRAY_LIB
11897 && lhs_caf_attr.codimension && rhs_caf_attr.codimension
11898 && ((lhs_caf_attr.allocatable && lhs_refs_comp)
11899 || (rhs_caf_attr.allocatable && rhs_refs_comp)))
11900 {
11901 /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
11902 allocatable component, because those need to be accessed via the
11903 caf-runtime. No need to check for coindexes here, because resolve
11904 has rewritten those already. */
11905 gfc_code code;
11906 gfc_actual_arglist a1, a2;
11907 /* Clear the structures to prevent accessing garbage. */
11908 memset (&code, '\0', sizeof (gfc_code));
11909 memset (&a1, '\0', sizeof (gfc_actual_arglist));
11910 memset (&a2, '\0', sizeof (gfc_actual_arglist));
11911 a1.expr = expr1;
11912 a1.next = &a2;
11913 a2.expr = expr2;
11914 a2.next = NULL;
11915 code.ext.actual = &a1;
11916 code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
11917 tmp = gfc_conv_intrinsic_subroutine (&code);
11918 }
11919 else if (!is_poly_assign && expr2->must_finalize
11920 && expr1->ts.type == BT_CLASS
11921 && expr2->ts.type == BT_CLASS)
11922 {
11923 /* This case comes about when the scalarizer provides array element
11924 references. Use the vptr copy function, since this does a deep
11925 copy of allocatable components, without which the finalizer call
11926 will deallocate the components. */
11927 tmp = gfc_get_vptr_from_expr (rse.expr);
11928 if (tmp != NULL_TREE)
11929 {
11930 tree fcn = gfc_vptr_copy_get (tmp);
11931 if (POINTER_TYPE_P (TREE_TYPE (fcn)))
11932 fcn = build_fold_indirect_ref_loc (input_location, fcn);
11933 tmp = build_call_expr_loc (input_location,
11934 fcn, 2,
11935 gfc_build_addr_expr (NULL, rse.expr),
11936 gfc_build_addr_expr (NULL, lse.expr));
11937 }
11938 }
11939
11940 /* If nothing else works, do it the old fashioned way! */
11941 if (tmp == NULL_TREE)
11942 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
11943 gfc_expr_is_variable (expr2)
11944 || scalar_to_array
11945 || expr2->expr_type == EXPR_ARRAY,
11946 !(l_is_temp || init_flag) && dealloc,
11947 expr1->symtree->n.sym->attr.codimension);
11948
11949 /* Add the pre blocks to the body. */
11950 gfc_add_block_to_block (&body, &rse.pre);
11951 gfc_add_block_to_block (&body, &lse.pre);
11952 gfc_add_expr_to_block (&body, tmp);
11953 /* Add the post blocks to the body. */
11954 gfc_add_block_to_block (&body, &rse.post);
11955 gfc_add_block_to_block (&body, &lse.post);
11956
11957 if (lss == gfc_ss_terminator)
11958 {
11959 /* F2003: Add the code for reallocation on assignment. */
11960 if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1)
11961 && !is_poly_assign)
11962 alloc_scalar_allocatable_for_assignment (&block, string_length,
11963 expr1, expr2);
11964
11965 /* Use the scalar assignment as is. */
11966 gfc_add_block_to_block (&block, &body);
11967 }
11968 else
11969 {
11970 gcc_assert (lse.ss == gfc_ss_terminator
11971 && rse.ss == gfc_ss_terminator);
11972
11973 if (l_is_temp)
11974 {
11975 gfc_trans_scalarized_loop_boundary (&loop, &body);
11976
11977 /* We need to copy the temporary to the actual lhs. */
11978 gfc_init_se (&lse, NULL);
11979 gfc_init_se (&rse, NULL);
11980 gfc_copy_loopinfo_to_se (&lse, &loop);
11981 gfc_copy_loopinfo_to_se (&rse, &loop);
11982
11983 rse.ss = loop.temp_ss;
11984 lse.ss = lss;
11985
11986 gfc_conv_tmp_array_ref (&rse);
11987 gfc_conv_expr (&lse, expr1);
11988
11989 gcc_assert (lse.ss == gfc_ss_terminator
11990 && rse.ss == gfc_ss_terminator);
11991
11992 if (expr2->ts.type == BT_CHARACTER)
11993 rse.string_length = string_length;
11994
11995 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
11996 false, dealloc);
11997 gfc_add_expr_to_block (&body, tmp);
11998 }
11999
12000 /* F2003: Allocate or reallocate lhs of allocatable array. */
12001 if (realloc_flag)
12002 {
12003 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
12004 ompws_flags &= ~OMPWS_SCALARIZER_WS;
12005 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
12006 if (tmp != NULL_TREE)
12007 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
12008 }
12009
12010 if (maybe_workshare)
12011 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
12012
12013 /* Generate the copying loops. */
12014 gfc_trans_scalarizing_loops (&loop, &body);
12015
12016 /* Wrap the whole thing up. */
12017 gfc_add_block_to_block (&block, &loop.pre);
12018 gfc_add_block_to_block (&block, &loop.post);
12019
12020 gfc_cleanup_loop (&loop);
12021 }
12022
12023 return gfc_finish_block (&block);
12024 }
12025
12026
12027 /* Check whether EXPR is a copyable array. */
12028
12029 static bool
copyable_array_p(gfc_expr * expr)12030 copyable_array_p (gfc_expr * expr)
12031 {
12032 if (expr->expr_type != EXPR_VARIABLE)
12033 return false;
12034
12035 /* First check it's an array. */
12036 if (expr->rank < 1 || !expr->ref || expr->ref->next)
12037 return false;
12038
12039 if (!gfc_full_array_ref_p (expr->ref, NULL))
12040 return false;
12041
12042 /* Next check that it's of a simple enough type. */
12043 switch (expr->ts.type)
12044 {
12045 case BT_INTEGER:
12046 case BT_REAL:
12047 case BT_COMPLEX:
12048 case BT_LOGICAL:
12049 return true;
12050
12051 case BT_CHARACTER:
12052 return false;
12053
12054 case_bt_struct:
12055 return !expr->ts.u.derived->attr.alloc_comp;
12056
12057 default:
12058 break;
12059 }
12060
12061 return false;
12062 }
12063
12064 /* Translate an assignment. */
12065
12066 tree
gfc_trans_assignment(gfc_expr * expr1,gfc_expr * expr2,bool init_flag,bool dealloc,bool use_vptr_copy,bool may_alias)12067 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
12068 bool dealloc, bool use_vptr_copy, bool may_alias)
12069 {
12070 tree tmp;
12071
12072 /* Special case a single function returning an array. */
12073 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
12074 {
12075 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
12076 if (tmp)
12077 return tmp;
12078 }
12079
12080 /* Special case assigning an array to zero. */
12081 if (copyable_array_p (expr1)
12082 && is_zero_initializer_p (expr2))
12083 {
12084 tmp = gfc_trans_zero_assign (expr1);
12085 if (tmp)
12086 return tmp;
12087 }
12088
12089 /* Special case copying one array to another. */
12090 if (copyable_array_p (expr1)
12091 && copyable_array_p (expr2)
12092 && gfc_compare_types (&expr1->ts, &expr2->ts)
12093 && !gfc_check_dependency (expr1, expr2, 0))
12094 {
12095 tmp = gfc_trans_array_copy (expr1, expr2);
12096 if (tmp)
12097 return tmp;
12098 }
12099
12100 /* Special case initializing an array from a constant array constructor. */
12101 if (copyable_array_p (expr1)
12102 && expr2->expr_type == EXPR_ARRAY
12103 && gfc_compare_types (&expr1->ts, &expr2->ts))
12104 {
12105 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
12106 if (tmp)
12107 return tmp;
12108 }
12109
12110 if (UNLIMITED_POLY (expr1) && expr1->rank)
12111 use_vptr_copy = true;
12112
12113 /* Fallback to the scalarizer to generate explicit loops. */
12114 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc,
12115 use_vptr_copy, may_alias);
12116 }
12117
12118 tree
gfc_trans_init_assign(gfc_code * code)12119 gfc_trans_init_assign (gfc_code * code)
12120 {
12121 return gfc_trans_assignment (code->expr1, code->expr2, true, false, true);
12122 }
12123
12124 tree
gfc_trans_assign(gfc_code * code)12125 gfc_trans_assign (gfc_code * code)
12126 {
12127 return gfc_trans_assignment (code->expr1, code->expr2, false, true);
12128 }
12129
12130 /* Generate a simple loop for internal use of the form
12131 for (var = begin; var <cond> end; var += step)
12132 body; */
12133 void
gfc_simple_for_loop(stmtblock_t * block,tree var,tree begin,tree end,enum tree_code cond,tree step,tree body)12134 gfc_simple_for_loop (stmtblock_t *block, tree var, tree begin, tree end,
12135 enum tree_code cond, tree step, tree body)
12136 {
12137 tree tmp;
12138
12139 /* var = begin. */
12140 gfc_add_modify (block, var, begin);
12141
12142 /* Loop: for (var = begin; var <cond> end; var += step). */
12143 tree label_loop = gfc_build_label_decl (NULL_TREE);
12144 tree label_cond = gfc_build_label_decl (NULL_TREE);
12145 TREE_USED (label_loop) = 1;
12146 TREE_USED (label_cond) = 1;
12147
12148 gfc_add_expr_to_block (block, build1_v (GOTO_EXPR, label_cond));
12149 gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_loop));
12150
12151 /* Loop body. */
12152 gfc_add_expr_to_block (block, body);
12153
12154 /* End of loop body. */
12155 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var, step);
12156 gfc_add_modify (block, var, tmp);
12157 gfc_add_expr_to_block (block, build1_v (LABEL_EXPR, label_cond));
12158 tmp = fold_build2_loc (input_location, cond, boolean_type_node, var, end);
12159 tmp = build3_v (COND_EXPR, tmp, build1_v (GOTO_EXPR, label_loop),
12160 build_empty_stmt (input_location));
12161 gfc_add_expr_to_block (block, tmp);
12162 }
12163