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