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