ipa-cp.c (ipcp_cloning_candidate_p): Use opt_for_fn.
[gcc.git] / gcc / fortran / trans-expr.c
1 /* Expression translation
2 Copyright (C) 2002-2014 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 "gfortran.h"
28 #include "tree.h"
29 #include "stringpool.h"
30 #include "diagnostic-core.h" /* For fatal_error. */
31 #include "langhooks.h"
32 #include "flags.h"
33 #include "arith.h"
34 #include "constructor.h"
35 #include "trans.h"
36 #include "trans-const.h"
37 #include "trans-types.h"
38 #include "trans-array.h"
39 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
40 #include "trans-stmt.h"
41 #include "dependency.h"
42 #include "gimplify.h"
43 #include "wide-int.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;
70
71 type = get_scalar_to_descriptor_type (scalar, attr);
72 desc = gfc_create_var (type, "desc");
73 DECL_ARTIFICIAL (desc) = 1;
74
75 if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
76 scalar = gfc_build_addr_expr (NULL_TREE, scalar);
77 gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
78 gfc_get_dtype (type));
79 gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
80
81 /* Copy pointer address back - but only if it could have changed and
82 if the actual argument is a pointer and not, e.g., NULL(). */
83 if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
84 gfc_add_modify (&se->post, scalar,
85 fold_convert (TREE_TYPE (scalar),
86 gfc_conv_descriptor_data_get (desc)));
87 return desc;
88 }
89
90
91 /* This is the seed for an eventual trans-class.c
92
93 The following parameters should not be used directly since they might
94 in future implementations. Use the corresponding APIs. */
95 #define CLASS_DATA_FIELD 0
96 #define CLASS_VPTR_FIELD 1
97 #define VTABLE_HASH_FIELD 0
98 #define VTABLE_SIZE_FIELD 1
99 #define VTABLE_EXTENDS_FIELD 2
100 #define VTABLE_DEF_INIT_FIELD 3
101 #define VTABLE_COPY_FIELD 4
102 #define VTABLE_FINAL_FIELD 5
103
104
105 tree
106 gfc_class_set_static_fields (tree decl, tree vptr, tree data)
107 {
108 tree tmp;
109 tree field;
110 vec<constructor_elt, va_gc> *init = NULL;
111
112 field = TYPE_FIELDS (TREE_TYPE (decl));
113 tmp = gfc_advance_chain (field, CLASS_DATA_FIELD);
114 CONSTRUCTOR_APPEND_ELT (init, tmp, data);
115
116 tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD);
117 CONSTRUCTOR_APPEND_ELT (init, tmp, vptr);
118
119 return build_constructor (TREE_TYPE (decl), init);
120 }
121
122
123 tree
124 gfc_class_data_get (tree decl)
125 {
126 tree data;
127 if (POINTER_TYPE_P (TREE_TYPE (decl)))
128 decl = build_fold_indirect_ref_loc (input_location, decl);
129 data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
130 CLASS_DATA_FIELD);
131 return fold_build3_loc (input_location, COMPONENT_REF,
132 TREE_TYPE (data), decl, data,
133 NULL_TREE);
134 }
135
136
137 tree
138 gfc_class_vptr_get (tree decl)
139 {
140 tree vptr;
141 if (POINTER_TYPE_P (TREE_TYPE (decl)))
142 decl = build_fold_indirect_ref_loc (input_location, decl);
143 vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
144 CLASS_VPTR_FIELD);
145 return fold_build3_loc (input_location, COMPONENT_REF,
146 TREE_TYPE (vptr), decl, vptr,
147 NULL_TREE);
148 }
149
150
151 static tree
152 gfc_vtable_field_get (tree decl, int field)
153 {
154 tree size;
155 tree vptr;
156 vptr = gfc_class_vptr_get (decl);
157 vptr = build_fold_indirect_ref_loc (input_location, vptr);
158 size = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
159 field);
160 size = fold_build3_loc (input_location, COMPONENT_REF,
161 TREE_TYPE (size), vptr, size,
162 NULL_TREE);
163 /* Always return size as an array index type. */
164 if (field == VTABLE_SIZE_FIELD)
165 size = fold_convert (gfc_array_index_type, size);
166 gcc_assert (size);
167 return size;
168 }
169
170
171 tree
172 gfc_vtable_hash_get (tree decl)
173 {
174 return gfc_vtable_field_get (decl, VTABLE_HASH_FIELD);
175 }
176
177
178 tree
179 gfc_vtable_size_get (tree decl)
180 {
181 return gfc_vtable_field_get (decl, VTABLE_SIZE_FIELD);
182 }
183
184
185 tree
186 gfc_vtable_extends_get (tree decl)
187 {
188 return gfc_vtable_field_get (decl, VTABLE_EXTENDS_FIELD);
189 }
190
191
192 tree
193 gfc_vtable_def_init_get (tree decl)
194 {
195 return gfc_vtable_field_get (decl, VTABLE_DEF_INIT_FIELD);
196 }
197
198
199 tree
200 gfc_vtable_copy_get (tree decl)
201 {
202 return gfc_vtable_field_get (decl, VTABLE_COPY_FIELD);
203 }
204
205
206 tree
207 gfc_vtable_final_get (tree decl)
208 {
209 return gfc_vtable_field_get (decl, VTABLE_FINAL_FIELD);
210 }
211
212
213 #undef CLASS_DATA_FIELD
214 #undef CLASS_VPTR_FIELD
215 #undef VTABLE_HASH_FIELD
216 #undef VTABLE_SIZE_FIELD
217 #undef VTABLE_EXTENDS_FIELD
218 #undef VTABLE_DEF_INIT_FIELD
219 #undef VTABLE_COPY_FIELD
220 #undef VTABLE_FINAL_FIELD
221
222
223 /* Reset the vptr to the declared type, e.g. after deallocation. */
224
225 void
226 gfc_reset_vptr (stmtblock_t *block, gfc_expr *e)
227 {
228 gfc_expr *rhs, *lhs = gfc_copy_expr (e);
229 gfc_symbol *vtab;
230 tree tmp;
231 gfc_ref *ref;
232
233 /* If we have a class array, we need go back to the class
234 container. */
235 if (lhs->ref && lhs->ref->next && !lhs->ref->next->next
236 && lhs->ref->next->type == REF_ARRAY
237 && lhs->ref->next->u.ar.type == AR_FULL
238 && lhs->ref->type == REF_COMPONENT
239 && strcmp (lhs->ref->u.c.component->name, "_data") == 0)
240 {
241 gfc_free_ref_list (lhs->ref);
242 lhs->ref = NULL;
243 }
244 else
245 for (ref = lhs->ref; ref; ref = ref->next)
246 if (ref->next && ref->next->next && !ref->next->next->next
247 && ref->next->next->type == REF_ARRAY
248 && ref->next->next->u.ar.type == AR_FULL
249 && ref->next->type == REF_COMPONENT
250 && strcmp (ref->next->u.c.component->name, "_data") == 0)
251 {
252 gfc_free_ref_list (ref->next);
253 ref->next = NULL;
254 }
255
256 gfc_add_vptr_component (lhs);
257
258 if (UNLIMITED_POLY (e))
259 rhs = gfc_get_null_expr (NULL);
260 else
261 {
262 vtab = gfc_find_derived_vtab (e->ts.u.derived);
263 rhs = gfc_lval_expr_from_sym (vtab);
264 }
265 tmp = gfc_trans_pointer_assignment (lhs, rhs);
266 gfc_add_expr_to_block (block, tmp);
267 gfc_free_expr (lhs);
268 gfc_free_expr (rhs);
269 }
270
271
272 /* Obtain the vptr of the last class reference in an expression.
273 Return NULL_TREE if no class reference is found. */
274
275 tree
276 gfc_get_vptr_from_expr (tree expr)
277 {
278 tree tmp;
279 tree type;
280
281 for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
282 {
283 type = TREE_TYPE (tmp);
284 while (type)
285 {
286 if (GFC_CLASS_TYPE_P (type))
287 return gfc_class_vptr_get (tmp);
288 if (type != TYPE_CANONICAL (type))
289 type = TYPE_CANONICAL (type);
290 else
291 type = NULL_TREE;
292 }
293 if (TREE_CODE (tmp) == VAR_DECL)
294 break;
295 }
296 return NULL_TREE;
297 }
298
299
300 static void
301 class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
302 bool lhs_type)
303 {
304 tree tmp, tmp2, type;
305
306 gfc_conv_descriptor_data_set (block, lhs_desc,
307 gfc_conv_descriptor_data_get (rhs_desc));
308 gfc_conv_descriptor_offset_set (block, lhs_desc,
309 gfc_conv_descriptor_offset_get (rhs_desc));
310
311 gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
312 gfc_conv_descriptor_dtype (rhs_desc));
313
314 /* Assign the dimension as range-ref. */
315 tmp = gfc_get_descriptor_dimension (lhs_desc);
316 tmp2 = gfc_get_descriptor_dimension (rhs_desc);
317
318 type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
319 tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
320 gfc_index_zero_node, NULL_TREE, NULL_TREE);
321 tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
322 gfc_index_zero_node, NULL_TREE, NULL_TREE);
323 gfc_add_modify (block, tmp, tmp2);
324 }
325
326
327 /* Takes a derived type expression and returns the address of a temporary
328 class object of the 'declared' type. If vptr is not NULL, this is
329 used for the temporary class object.
330 optional_alloc_ptr is false when the dummy is neither allocatable
331 nor a pointer; that's only relevant for the optional handling. */
332 void
333 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
334 gfc_typespec class_ts, tree vptr, bool optional,
335 bool optional_alloc_ptr)
336 {
337 gfc_symbol *vtab;
338 tree cond_optional = NULL_TREE;
339 gfc_ss *ss;
340 tree ctree;
341 tree var;
342 tree tmp;
343
344 /* The derived type needs to be converted to a temporary
345 CLASS object. */
346 tmp = gfc_typenode_for_spec (&class_ts);
347 var = gfc_create_var (tmp, "class");
348
349 /* Set the vptr. */
350 ctree = gfc_class_vptr_get (var);
351
352 if (vptr != NULL_TREE)
353 {
354 /* Use the dynamic vptr. */
355 tmp = vptr;
356 }
357 else
358 {
359 /* In this case the vtab corresponds to the derived type and the
360 vptr must point to it. */
361 vtab = gfc_find_derived_vtab (e->ts.u.derived);
362 gcc_assert (vtab);
363 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
364 }
365 gfc_add_modify (&parmse->pre, ctree,
366 fold_convert (TREE_TYPE (ctree), tmp));
367
368 /* Now set the data field. */
369 ctree = gfc_class_data_get (var);
370
371 if (optional)
372 cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
373
374 if (parmse->ss && parmse->ss->info->useflags)
375 {
376 /* For an array reference in an elemental procedure call we need
377 to retain the ss to provide the scalarized array reference. */
378 gfc_conv_expr_reference (parmse, e);
379 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
380 if (optional)
381 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
382 cond_optional, tmp,
383 fold_convert (TREE_TYPE (tmp), null_pointer_node));
384 gfc_add_modify (&parmse->pre, ctree, tmp);
385
386 }
387 else
388 {
389 ss = gfc_walk_expr (e);
390 if (ss == gfc_ss_terminator)
391 {
392 parmse->ss = NULL;
393 gfc_conv_expr_reference (parmse, e);
394
395 /* Scalar to an assumed-rank array. */
396 if (class_ts.u.derived->components->as)
397 {
398 tree type;
399 type = get_scalar_to_descriptor_type (parmse->expr,
400 gfc_expr_attr (e));
401 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
402 gfc_get_dtype (type));
403 if (optional)
404 parmse->expr = build3_loc (input_location, COND_EXPR,
405 TREE_TYPE (parmse->expr),
406 cond_optional, parmse->expr,
407 fold_convert (TREE_TYPE (parmse->expr),
408 null_pointer_node));
409 gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
410 }
411 else
412 {
413 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
414 if (optional)
415 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
416 cond_optional, tmp,
417 fold_convert (TREE_TYPE (tmp),
418 null_pointer_node));
419 gfc_add_modify (&parmse->pre, ctree, tmp);
420 }
421 }
422 else
423 {
424 stmtblock_t block;
425 gfc_init_block (&block);
426
427 parmse->ss = ss;
428 gfc_conv_expr_descriptor (parmse, e);
429
430 if (e->rank != class_ts.u.derived->components->as->rank)
431 {
432 gcc_assert (class_ts.u.derived->components->as->type
433 == AS_ASSUMED_RANK);
434 class_array_data_assign (&block, ctree, parmse->expr, false);
435 }
436 else
437 {
438 if (gfc_expr_attr (e).codimension)
439 parmse->expr = fold_build1_loc (input_location,
440 VIEW_CONVERT_EXPR,
441 TREE_TYPE (ctree),
442 parmse->expr);
443 gfc_add_modify (&block, ctree, parmse->expr);
444 }
445
446 if (optional)
447 {
448 tmp = gfc_finish_block (&block);
449
450 gfc_init_block (&block);
451 gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
452
453 tmp = build3_v (COND_EXPR, cond_optional, tmp,
454 gfc_finish_block (&block));
455 gfc_add_expr_to_block (&parmse->pre, tmp);
456 }
457 else
458 gfc_add_block_to_block (&parmse->pre, &block);
459 }
460 }
461
462 /* Pass the address of the class object. */
463 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
464
465 if (optional && optional_alloc_ptr)
466 parmse->expr = build3_loc (input_location, COND_EXPR,
467 TREE_TYPE (parmse->expr),
468 cond_optional, parmse->expr,
469 fold_convert (TREE_TYPE (parmse->expr),
470 null_pointer_node));
471 }
472
473
474 /* Create a new class container, which is required as scalar coarrays
475 have an array descriptor while normal scalars haven't. Optionally,
476 NULL pointer checks are added if the argument is OPTIONAL. */
477
478 static void
479 class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
480 gfc_typespec class_ts, bool optional)
481 {
482 tree var, ctree, tmp;
483 stmtblock_t block;
484 gfc_ref *ref;
485 gfc_ref *class_ref;
486
487 gfc_init_block (&block);
488
489 class_ref = NULL;
490 for (ref = e->ref; ref; ref = ref->next)
491 {
492 if (ref->type == REF_COMPONENT
493 && ref->u.c.component->ts.type == BT_CLASS)
494 class_ref = ref;
495 }
496
497 if (class_ref == NULL
498 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
499 tmp = e->symtree->n.sym->backend_decl;
500 else
501 {
502 /* Remove everything after the last class reference, convert the
503 expression and then recover its tailend once more. */
504 gfc_se tmpse;
505 ref = class_ref->next;
506 class_ref->next = NULL;
507 gfc_init_se (&tmpse, NULL);
508 gfc_conv_expr (&tmpse, e);
509 class_ref->next = ref;
510 tmp = tmpse.expr;
511 }
512
513 var = gfc_typenode_for_spec (&class_ts);
514 var = gfc_create_var (var, "class");
515
516 ctree = gfc_class_vptr_get (var);
517 gfc_add_modify (&block, ctree,
518 fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
519
520 ctree = gfc_class_data_get (var);
521 tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
522 gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
523
524 /* Pass the address of the class object. */
525 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
526
527 if (optional)
528 {
529 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
530 tree tmp2;
531
532 tmp = gfc_finish_block (&block);
533
534 gfc_init_block (&block);
535 tmp2 = gfc_class_data_get (var);
536 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
537 null_pointer_node));
538 tmp2 = gfc_finish_block (&block);
539
540 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
541 cond, tmp, tmp2);
542 gfc_add_expr_to_block (&parmse->pre, tmp);
543 }
544 else
545 gfc_add_block_to_block (&parmse->pre, &block);
546 }
547
548
549 /* Takes an intrinsic type expression and returns the address of a temporary
550 class object of the 'declared' type. */
551 void
552 gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
553 gfc_typespec class_ts)
554 {
555 gfc_symbol *vtab;
556 gfc_ss *ss;
557 tree ctree;
558 tree var;
559 tree tmp;
560
561 /* The intrinsic type needs to be converted to a temporary
562 CLASS object. */
563 tmp = gfc_typenode_for_spec (&class_ts);
564 var = gfc_create_var (tmp, "class");
565
566 /* Set the vptr. */
567 ctree = gfc_class_vptr_get (var);
568
569 vtab = gfc_find_vtab (&e->ts);
570 gcc_assert (vtab);
571 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
572 gfc_add_modify (&parmse->pre, ctree,
573 fold_convert (TREE_TYPE (ctree), tmp));
574
575 /* Now set the data field. */
576 ctree = gfc_class_data_get (var);
577 if (parmse->ss && parmse->ss->info->useflags)
578 {
579 /* For an array reference in an elemental procedure call we need
580 to retain the ss to provide the scalarized array reference. */
581 gfc_conv_expr_reference (parmse, e);
582 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
583 gfc_add_modify (&parmse->pre, ctree, tmp);
584 }
585 else
586 {
587 ss = gfc_walk_expr (e);
588 if (ss == gfc_ss_terminator)
589 {
590 parmse->ss = NULL;
591 gfc_conv_expr_reference (parmse, e);
592 if (class_ts.u.derived->components->as
593 && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
594 {
595 tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
596 gfc_expr_attr (e));
597 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
598 TREE_TYPE (ctree), tmp);
599 }
600 else
601 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
602 gfc_add_modify (&parmse->pre, ctree, tmp);
603 }
604 else
605 {
606 parmse->ss = ss;
607 parmse->use_offset = 1;
608 gfc_conv_expr_descriptor (parmse, e);
609 if (class_ts.u.derived->components->as->rank != e->rank)
610 {
611 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
612 TREE_TYPE (ctree), parmse->expr);
613 gfc_add_modify (&parmse->pre, ctree, tmp);
614 }
615 else
616 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
617 }
618 }
619
620 /* Pass the address of the class object. */
621 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
622 }
623
624
625 /* Takes a scalarized class array expression and returns the
626 address of a temporary scalar class object of the 'declared'
627 type.
628 OOP-TODO: This could be improved by adding code that branched on
629 the dynamic type being the same as the declared type. In this case
630 the original class expression can be passed directly.
631 optional_alloc_ptr is false when the dummy is neither allocatable
632 nor a pointer; that's relevant for the optional handling.
633 Set copyback to true if class container's _data and _vtab pointers
634 might get modified. */
635
636 void
637 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
638 bool elemental, bool copyback, bool optional,
639 bool optional_alloc_ptr)
640 {
641 tree ctree;
642 tree var;
643 tree tmp;
644 tree vptr;
645 tree cond = NULL_TREE;
646 gfc_ref *ref;
647 gfc_ref *class_ref;
648 stmtblock_t block;
649 bool full_array = false;
650
651 gfc_init_block (&block);
652
653 class_ref = NULL;
654 for (ref = e->ref; ref; ref = ref->next)
655 {
656 if (ref->type == REF_COMPONENT
657 && ref->u.c.component->ts.type == BT_CLASS)
658 class_ref = ref;
659
660 if (ref->next == NULL)
661 break;
662 }
663
664 if ((ref == NULL || class_ref == ref)
665 && (!class_ts.u.derived->components->as
666 || class_ts.u.derived->components->as->rank != -1))
667 return;
668
669 /* Test for FULL_ARRAY. */
670 if (e->rank == 0 && gfc_expr_attr (e).codimension
671 && gfc_expr_attr (e).dimension)
672 full_array = true;
673 else
674 gfc_is_class_array_ref (e, &full_array);
675
676 /* The derived type needs to be converted to a temporary
677 CLASS object. */
678 tmp = gfc_typenode_for_spec (&class_ts);
679 var = gfc_create_var (tmp, "class");
680
681 /* Set the data. */
682 ctree = gfc_class_data_get (var);
683 if (class_ts.u.derived->components->as
684 && e->rank != class_ts.u.derived->components->as->rank)
685 {
686 if (e->rank == 0)
687 {
688 tree type = get_scalar_to_descriptor_type (parmse->expr,
689 gfc_expr_attr (e));
690 gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
691 gfc_get_dtype (type));
692
693 tmp = gfc_class_data_get (parmse->expr);
694 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
695 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
696
697 gfc_conv_descriptor_data_set (&block, ctree, tmp);
698 }
699 else
700 class_array_data_assign (&block, ctree, parmse->expr, false);
701 }
702 else
703 {
704 if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
705 parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
706 TREE_TYPE (ctree), parmse->expr);
707 gfc_add_modify (&block, ctree, parmse->expr);
708 }
709
710 /* Return the data component, except in the case of scalarized array
711 references, where nullification of the cannot occur and so there
712 is no need. */
713 if (!elemental && full_array && copyback)
714 {
715 if (class_ts.u.derived->components->as
716 && e->rank != class_ts.u.derived->components->as->rank)
717 {
718 if (e->rank == 0)
719 gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr),
720 gfc_conv_descriptor_data_get (ctree));
721 else
722 class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
723 }
724 else
725 gfc_add_modify (&parmse->post, parmse->expr, ctree);
726 }
727
728 /* Set the vptr. */
729 ctree = gfc_class_vptr_get (var);
730
731 /* The vptr is the second field of the actual argument.
732 First we have to find the corresponding class reference. */
733
734 tmp = NULL_TREE;
735 if (class_ref == NULL
736 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
737 tmp = e->symtree->n.sym->backend_decl;
738 else
739 {
740 /* Remove everything after the last class reference, convert the
741 expression and then recover its tailend once more. */
742 gfc_se tmpse;
743 ref = class_ref->next;
744 class_ref->next = NULL;
745 gfc_init_se (&tmpse, NULL);
746 gfc_conv_expr (&tmpse, e);
747 class_ref->next = ref;
748 tmp = tmpse.expr;
749 }
750
751 gcc_assert (tmp != NULL_TREE);
752
753 /* Dereference if needs be. */
754 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
755 tmp = build_fold_indirect_ref_loc (input_location, tmp);
756
757 vptr = gfc_class_vptr_get (tmp);
758 gfc_add_modify (&block, ctree,
759 fold_convert (TREE_TYPE (ctree), vptr));
760
761 /* Return the vptr component, except in the case of scalarized array
762 references, where the dynamic type cannot change. */
763 if (!elemental && full_array && copyback)
764 gfc_add_modify (&parmse->post, vptr,
765 fold_convert (TREE_TYPE (vptr), ctree));
766
767 if (optional)
768 {
769 tree tmp2;
770
771 cond = gfc_conv_expr_present (e->symtree->n.sym);
772 tmp = gfc_finish_block (&block);
773
774 if (optional_alloc_ptr)
775 tmp2 = build_empty_stmt (input_location);
776 else
777 {
778 gfc_init_block (&block);
779
780 tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
781 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
782 null_pointer_node));
783 tmp2 = gfc_finish_block (&block);
784 }
785
786 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
787 cond, tmp, tmp2);
788 gfc_add_expr_to_block (&parmse->pre, tmp);
789 }
790 else
791 gfc_add_block_to_block (&parmse->pre, &block);
792
793 /* Pass the address of the class object. */
794 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
795
796 if (optional && optional_alloc_ptr)
797 parmse->expr = build3_loc (input_location, COND_EXPR,
798 TREE_TYPE (parmse->expr),
799 cond, parmse->expr,
800 fold_convert (TREE_TYPE (parmse->expr),
801 null_pointer_node));
802 }
803
804
805 /* Given a class array declaration and an index, returns the address
806 of the referenced element. */
807
808 tree
809 gfc_get_class_array_ref (tree index, tree class_decl)
810 {
811 tree data = gfc_class_data_get (class_decl);
812 tree size = gfc_vtable_size_get (class_decl);
813 tree offset = fold_build2_loc (input_location, MULT_EXPR,
814 gfc_array_index_type,
815 index, size);
816 tree ptr;
817 data = gfc_conv_descriptor_data_get (data);
818 ptr = fold_convert (pvoid_type_node, data);
819 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
820 return fold_convert (TREE_TYPE (data), ptr);
821 }
822
823
824 /* Copies one class expression to another, assuming that if either
825 'to' or 'from' are arrays they are packed. Should 'from' be
826 NULL_TREE, the initialization expression for 'to' is used, assuming
827 that the _vptr is set. */
828
829 tree
830 gfc_copy_class_to_class (tree from, tree to, tree nelems)
831 {
832 tree fcn;
833 tree fcn_type;
834 tree from_data;
835 tree to_data;
836 tree to_ref;
837 tree from_ref;
838 vec<tree, va_gc> *args;
839 tree tmp;
840 tree index;
841 stmtblock_t loopbody;
842 stmtblock_t body;
843 gfc_loopinfo loop;
844
845 args = NULL;
846
847 if (from != NULL_TREE)
848 fcn = gfc_vtable_copy_get (from);
849 else
850 fcn = gfc_vtable_copy_get (to);
851
852 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
853
854 if (from != NULL_TREE)
855 from_data = gfc_class_data_get (from);
856 else
857 from_data = gfc_vtable_def_init_get (to);
858
859 to_data = gfc_class_data_get (to);
860
861 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
862 {
863 gfc_init_block (&body);
864 tmp = fold_build2_loc (input_location, MINUS_EXPR,
865 gfc_array_index_type, nelems,
866 gfc_index_one_node);
867 nelems = gfc_evaluate_now (tmp, &body);
868 index = gfc_create_var (gfc_array_index_type, "S");
869
870 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)))
871 {
872 from_ref = gfc_get_class_array_ref (index, from);
873 vec_safe_push (args, from_ref);
874 }
875 else
876 vec_safe_push (args, from_data);
877
878 to_ref = gfc_get_class_array_ref (index, to);
879 vec_safe_push (args, to_ref);
880
881 tmp = build_call_vec (fcn_type, fcn, args);
882
883 /* Build the body of the loop. */
884 gfc_init_block (&loopbody);
885 gfc_add_expr_to_block (&loopbody, tmp);
886
887 /* Build the loop and return. */
888 gfc_init_loopinfo (&loop);
889 loop.dimen = 1;
890 loop.from[0] = gfc_index_zero_node;
891 loop.loopvar[0] = index;
892 loop.to[0] = nelems;
893 gfc_trans_scalarizing_loops (&loop, &loopbody);
894 gfc_add_block_to_block (&body, &loop.pre);
895 tmp = gfc_finish_block (&body);
896 gfc_cleanup_loop (&loop);
897 }
898 else
899 {
900 gcc_assert (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)));
901 vec_safe_push (args, from_data);
902 vec_safe_push (args, to_data);
903 tmp = build_call_vec (fcn_type, fcn, args);
904 }
905
906 return tmp;
907 }
908
909 static tree
910 gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
911 {
912 gfc_actual_arglist *actual;
913 gfc_expr *ppc;
914 gfc_code *ppc_code;
915 tree res;
916
917 actual = gfc_get_actual_arglist ();
918 actual->expr = gfc_copy_expr (rhs);
919 actual->next = gfc_get_actual_arglist ();
920 actual->next->expr = gfc_copy_expr (lhs);
921 ppc = gfc_copy_expr (obj);
922 gfc_add_vptr_component (ppc);
923 gfc_add_component_ref (ppc, "_copy");
924 ppc_code = gfc_get_code (EXEC_CALL);
925 ppc_code->resolved_sym = ppc->symtree->n.sym;
926 /* Although '_copy' is set to be elemental in class.c, it is
927 not staying that way. Find out why, sometime.... */
928 ppc_code->resolved_sym->attr.elemental = 1;
929 ppc_code->ext.actual = actual;
930 ppc_code->expr1 = ppc;
931 /* Since '_copy' is elemental, the scalarizer will take care
932 of arrays in gfc_trans_call. */
933 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
934 gfc_free_statements (ppc_code);
935 return res;
936 }
937
938 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
939 A MEMCPY is needed to copy the full data from the default initializer
940 of the dynamic type. */
941
942 tree
943 gfc_trans_class_init_assign (gfc_code *code)
944 {
945 stmtblock_t block;
946 tree tmp;
947 gfc_se dst,src,memsz;
948 gfc_expr *lhs, *rhs, *sz;
949
950 gfc_start_block (&block);
951
952 lhs = gfc_copy_expr (code->expr1);
953 gfc_add_data_component (lhs);
954
955 rhs = gfc_copy_expr (code->expr1);
956 gfc_add_vptr_component (rhs);
957
958 /* Make sure that the component backend_decls have been built, which
959 will not have happened if the derived types concerned have not
960 been referenced. */
961 gfc_get_derived_type (rhs->ts.u.derived);
962 gfc_add_def_init_component (rhs);
963
964 if (code->expr1->ts.type == BT_CLASS
965 && CLASS_DATA (code->expr1)->attr.dimension)
966 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
967 else
968 {
969 sz = gfc_copy_expr (code->expr1);
970 gfc_add_vptr_component (sz);
971 gfc_add_size_component (sz);
972
973 gfc_init_se (&dst, NULL);
974 gfc_init_se (&src, NULL);
975 gfc_init_se (&memsz, NULL);
976 gfc_conv_expr (&dst, lhs);
977 gfc_conv_expr (&src, rhs);
978 gfc_conv_expr (&memsz, sz);
979 gfc_add_block_to_block (&block, &src.pre);
980 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
981
982 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
983 }
984
985 if (code->expr1->symtree->n.sym->attr.optional
986 || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master)
987 {
988 tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
989 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
990 present, tmp,
991 build_empty_stmt (input_location));
992 }
993
994 gfc_add_expr_to_block (&block, tmp);
995
996 return gfc_finish_block (&block);
997 }
998
999
1000 /* Translate an assignment to a CLASS object
1001 (pointer or ordinary assignment). */
1002
1003 tree
1004 gfc_trans_class_assign (gfc_expr *expr1, gfc_expr *expr2, gfc_exec_op op)
1005 {
1006 stmtblock_t block;
1007 tree tmp;
1008 gfc_expr *lhs;
1009 gfc_expr *rhs;
1010 gfc_ref *ref;
1011
1012 gfc_start_block (&block);
1013
1014 ref = expr1->ref;
1015 while (ref && ref->next)
1016 ref = ref->next;
1017
1018 /* Class valued proc_pointer assignments do not need any further
1019 preparation. */
1020 if (ref && ref->type == REF_COMPONENT
1021 && ref->u.c.component->attr.proc_pointer
1022 && expr2->expr_type == EXPR_VARIABLE
1023 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE
1024 && op == EXEC_POINTER_ASSIGN)
1025 goto assign;
1026
1027 if (expr2->ts.type != BT_CLASS)
1028 {
1029 /* Insert an additional assignment which sets the '_vptr' field. */
1030 gfc_symbol *vtab = NULL;
1031 gfc_symtree *st;
1032
1033 lhs = gfc_copy_expr (expr1);
1034 gfc_add_vptr_component (lhs);
1035
1036 if (UNLIMITED_POLY (expr1)
1037 && expr2->expr_type == EXPR_NULL && expr2->ts.type == BT_UNKNOWN)
1038 {
1039 rhs = gfc_get_null_expr (&expr2->where);
1040 goto assign_vptr;
1041 }
1042
1043 if (expr2->expr_type == EXPR_NULL)
1044 vtab = gfc_find_vtab (&expr1->ts);
1045 else
1046 vtab = gfc_find_vtab (&expr2->ts);
1047 gcc_assert (vtab);
1048
1049 rhs = gfc_get_expr ();
1050 rhs->expr_type = EXPR_VARIABLE;
1051 gfc_find_sym_tree (vtab->name, vtab->ns, 1, &st);
1052 rhs->symtree = st;
1053 rhs->ts = vtab->ts;
1054 assign_vptr:
1055 tmp = gfc_trans_pointer_assignment (lhs, rhs);
1056 gfc_add_expr_to_block (&block, tmp);
1057
1058 gfc_free_expr (lhs);
1059 gfc_free_expr (rhs);
1060 }
1061 else if (expr1->ts.type == BT_DERIVED && UNLIMITED_POLY (expr2))
1062 {
1063 /* F2003:C717 only sequence and bind-C types can come here. */
1064 gcc_assert (expr1->ts.u.derived->attr.sequence
1065 || expr1->ts.u.derived->attr.is_bind_c);
1066 gfc_add_data_component (expr2);
1067 goto assign;
1068 }
1069 else if (CLASS_DATA (expr2)->attr.dimension && expr2->expr_type != EXPR_FUNCTION)
1070 {
1071 /* Insert an additional assignment which sets the '_vptr' field. */
1072 lhs = gfc_copy_expr (expr1);
1073 gfc_add_vptr_component (lhs);
1074
1075 rhs = gfc_copy_expr (expr2);
1076 gfc_add_vptr_component (rhs);
1077
1078 tmp = gfc_trans_pointer_assignment (lhs, rhs);
1079 gfc_add_expr_to_block (&block, tmp);
1080
1081 gfc_free_expr (lhs);
1082 gfc_free_expr (rhs);
1083 }
1084
1085 /* Do the actual CLASS assignment. */
1086 if (expr2->ts.type == BT_CLASS
1087 && !CLASS_DATA (expr2)->attr.dimension)
1088 op = EXEC_ASSIGN;
1089 else if (expr2->expr_type != EXPR_FUNCTION || expr2->ts.type != BT_CLASS
1090 || !CLASS_DATA (expr2)->attr.dimension)
1091 gfc_add_data_component (expr1);
1092
1093 assign:
1094
1095 if (op == EXEC_ASSIGN)
1096 tmp = gfc_trans_assignment (expr1, expr2, false, true);
1097 else if (op == EXEC_POINTER_ASSIGN)
1098 tmp = gfc_trans_pointer_assignment (expr1, expr2);
1099 else
1100 gcc_unreachable();
1101
1102 gfc_add_expr_to_block (&block, tmp);
1103
1104 return gfc_finish_block (&block);
1105 }
1106
1107
1108 /* End of prototype trans-class.c */
1109
1110
1111 static void
1112 realloc_lhs_warning (bt type, bool array, locus *where)
1113 {
1114 if (array && type != BT_CLASS && type != BT_DERIVED
1115 && gfc_option.warn_realloc_lhs)
1116 gfc_warning ("Code for reallocating the allocatable array at %L will "
1117 "be added", where);
1118 else if (gfc_option.warn_realloc_lhs_all)
1119 gfc_warning ("Code for reallocating the allocatable variable at %L "
1120 "will be added", where);
1121 }
1122
1123
1124 static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
1125 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
1126 gfc_expr *);
1127
1128 /* Copy the scalarization loop variables. */
1129
1130 static void
1131 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1132 {
1133 dest->ss = src->ss;
1134 dest->loop = src->loop;
1135 }
1136
1137
1138 /* Initialize a simple expression holder.
1139
1140 Care must be taken when multiple se are created with the same parent.
1141 The child se must be kept in sync. The easiest way is to delay creation
1142 of a child se until after after the previous se has been translated. */
1143
1144 void
1145 gfc_init_se (gfc_se * se, gfc_se * parent)
1146 {
1147 memset (se, 0, sizeof (gfc_se));
1148 gfc_init_block (&se->pre);
1149 gfc_init_block (&se->post);
1150
1151 se->parent = parent;
1152
1153 if (parent)
1154 gfc_copy_se_loopvars (se, parent);
1155 }
1156
1157
1158 /* Advances to the next SS in the chain. Use this rather than setting
1159 se->ss = se->ss->next because all the parents needs to be kept in sync.
1160 See gfc_init_se. */
1161
1162 void
1163 gfc_advance_se_ss_chain (gfc_se * se)
1164 {
1165 gfc_se *p;
1166 gfc_ss *ss;
1167
1168 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
1169
1170 p = se;
1171 /* Walk down the parent chain. */
1172 while (p != NULL)
1173 {
1174 /* Simple consistency check. */
1175 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1176 || p->parent->ss->nested_ss == p->ss);
1177
1178 /* If we were in a nested loop, the next scalarized expression can be
1179 on the parent ss' next pointer. Thus we should not take the next
1180 pointer blindly, but rather go up one nest level as long as next
1181 is the end of chain. */
1182 ss = p->ss;
1183 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1184 ss = ss->parent;
1185
1186 p->ss = ss->next;
1187
1188 p = p->parent;
1189 }
1190 }
1191
1192
1193 /* Ensures the result of the expression as either a temporary variable
1194 or a constant so that it can be used repeatedly. */
1195
1196 void
1197 gfc_make_safe_expr (gfc_se * se)
1198 {
1199 tree var;
1200
1201 if (CONSTANT_CLASS_P (se->expr))
1202 return;
1203
1204 /* We need a temporary for this result. */
1205 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1206 gfc_add_modify (&se->pre, var, se->expr);
1207 se->expr = var;
1208 }
1209
1210
1211 /* Return an expression which determines if a dummy parameter is present.
1212 Also used for arguments to procedures with multiple entry points. */
1213
1214 tree
1215 gfc_conv_expr_present (gfc_symbol * sym)
1216 {
1217 tree decl, cond;
1218
1219 gcc_assert (sym->attr.dummy);
1220 decl = gfc_get_symbol_decl (sym);
1221
1222 /* Intrinsic scalars with VALUE attribute which are passed by value
1223 use a hidden argument to denote the present status. */
1224 if (sym->attr.value && sym->ts.type != BT_CHARACTER
1225 && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
1226 && !sym->attr.dimension)
1227 {
1228 char name[GFC_MAX_SYMBOL_LEN + 2];
1229 tree tree_name;
1230
1231 gcc_assert (TREE_CODE (decl) == PARM_DECL);
1232 name[0] = '_';
1233 strcpy (&name[1], sym->name);
1234 tree_name = get_identifier (name);
1235
1236 /* Walk function argument list to find hidden arg. */
1237 cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
1238 for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
1239 if (DECL_NAME (cond) == tree_name)
1240 break;
1241
1242 gcc_assert (cond);
1243 return cond;
1244 }
1245
1246 if (TREE_CODE (decl) != PARM_DECL)
1247 {
1248 /* Array parameters use a temporary descriptor, we want the real
1249 parameter. */
1250 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
1251 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
1252 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
1253 }
1254
1255 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, decl,
1256 fold_convert (TREE_TYPE (decl), null_pointer_node));
1257
1258 /* Fortran 2008 allows to pass null pointers and non-associated pointers
1259 as actual argument to denote absent dummies. For array descriptors,
1260 we thus also need to check the array descriptor. For BT_CLASS, it
1261 can also occur for scalars and F2003 due to type->class wrapping and
1262 class->class wrapping. Note further that BT_CLASS always uses an
1263 array descriptor for arrays, also for explicit-shape/assumed-size. */
1264
1265 if (!sym->attr.allocatable
1266 && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
1267 || (sym->ts.type == BT_CLASS
1268 && !CLASS_DATA (sym)->attr.allocatable
1269 && !CLASS_DATA (sym)->attr.class_pointer))
1270 && ((gfc_option.allow_std & GFC_STD_F2008) != 0
1271 || sym->ts.type == BT_CLASS))
1272 {
1273 tree tmp;
1274
1275 if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
1276 || sym->as->type == AS_ASSUMED_RANK
1277 || sym->attr.codimension))
1278 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
1279 {
1280 tmp = build_fold_indirect_ref_loc (input_location, decl);
1281 if (sym->ts.type == BT_CLASS)
1282 tmp = gfc_class_data_get (tmp);
1283 tmp = gfc_conv_array_data (tmp);
1284 }
1285 else if (sym->ts.type == BT_CLASS)
1286 tmp = gfc_class_data_get (decl);
1287 else
1288 tmp = NULL_TREE;
1289
1290 if (tmp != NULL_TREE)
1291 {
1292 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
1293 fold_convert (TREE_TYPE (tmp), null_pointer_node));
1294 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1295 boolean_type_node, cond, tmp);
1296 }
1297 }
1298
1299 return cond;
1300 }
1301
1302
1303 /* Converts a missing, dummy argument into a null or zero. */
1304
1305 void
1306 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
1307 {
1308 tree present;
1309 tree tmp;
1310
1311 present = gfc_conv_expr_present (arg->symtree->n.sym);
1312
1313 if (kind > 0)
1314 {
1315 /* Create a temporary and convert it to the correct type. */
1316 tmp = gfc_get_int_type (kind);
1317 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
1318 se->expr));
1319
1320 /* Test for a NULL value. */
1321 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
1322 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
1323 tmp = gfc_evaluate_now (tmp, &se->pre);
1324 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
1325 }
1326 else
1327 {
1328 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
1329 present, se->expr,
1330 build_zero_cst (TREE_TYPE (se->expr)));
1331 tmp = gfc_evaluate_now (tmp, &se->pre);
1332 se->expr = tmp;
1333 }
1334
1335 if (ts.type == BT_CHARACTER)
1336 {
1337 tmp = build_int_cst (gfc_charlen_type_node, 0);
1338 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
1339 present, se->string_length, tmp);
1340 tmp = gfc_evaluate_now (tmp, &se->pre);
1341 se->string_length = tmp;
1342 }
1343 return;
1344 }
1345
1346
1347 /* Get the character length of an expression, looking through gfc_refs
1348 if necessary. */
1349
1350 tree
1351 gfc_get_expr_charlen (gfc_expr *e)
1352 {
1353 gfc_ref *r;
1354 tree length;
1355
1356 gcc_assert (e->expr_type == EXPR_VARIABLE
1357 && e->ts.type == BT_CHARACTER);
1358
1359 length = NULL; /* To silence compiler warning. */
1360
1361 if (is_subref_array (e) && e->ts.u.cl->length)
1362 {
1363 gfc_se tmpse;
1364 gfc_init_se (&tmpse, NULL);
1365 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
1366 e->ts.u.cl->backend_decl = tmpse.expr;
1367 return tmpse.expr;
1368 }
1369
1370 /* First candidate: if the variable is of type CHARACTER, the
1371 expression's length could be the length of the character
1372 variable. */
1373 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1374 length = e->symtree->n.sym->ts.u.cl->backend_decl;
1375
1376 /* Look through the reference chain for component references. */
1377 for (r = e->ref; r; r = r->next)
1378 {
1379 switch (r->type)
1380 {
1381 case REF_COMPONENT:
1382 if (r->u.c.component->ts.type == BT_CHARACTER)
1383 length = r->u.c.component->ts.u.cl->backend_decl;
1384 break;
1385
1386 case REF_ARRAY:
1387 /* Do nothing. */
1388 break;
1389
1390 default:
1391 /* We should never got substring references here. These will be
1392 broken down by the scalarizer. */
1393 gcc_unreachable ();
1394 break;
1395 }
1396 }
1397
1398 gcc_assert (length != NULL);
1399 return length;
1400 }
1401
1402
1403 /* Return for an expression the backend decl of the coarray. */
1404
1405 tree
1406 gfc_get_tree_for_caf_expr (gfc_expr *expr)
1407 {
1408 tree caf_decl;
1409 bool found = false;
1410 gfc_ref *ref;
1411
1412 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
1413
1414 caf_decl = expr->symtree->n.sym->backend_decl;
1415 gcc_assert (caf_decl);
1416 if (expr->symtree->n.sym->ts.type == BT_CLASS)
1417 caf_decl = gfc_class_data_get (caf_decl);
1418 if (expr->symtree->n.sym->attr.codimension)
1419 return caf_decl;
1420
1421 /* The following code assumes that the coarray is a component reachable via
1422 only scalar components/variables; the Fortran standard guarantees this. */
1423
1424 for (ref = expr->ref; ref; ref = ref->next)
1425 if (ref->type == REF_COMPONENT)
1426 {
1427 gfc_component *comp = ref->u.c.component;
1428
1429 if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
1430 caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
1431 caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
1432 TREE_TYPE (comp->backend_decl), caf_decl,
1433 comp->backend_decl, NULL_TREE);
1434 if (comp->ts.type == BT_CLASS)
1435 caf_decl = gfc_class_data_get (caf_decl);
1436 if (comp->attr.codimension)
1437 {
1438 found = true;
1439 break;
1440 }
1441 }
1442 gcc_assert (found && caf_decl);
1443 return caf_decl;
1444 }
1445
1446
1447 /* Obtain the Coarray token - and optionally also the offset. */
1448
1449 void
1450 gfc_get_caf_token_offset (tree *token, tree *offset, tree caf_decl, tree se_expr,
1451 gfc_expr *expr)
1452 {
1453 tree tmp;
1454
1455 /* Coarray token. */
1456 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
1457 {
1458 gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
1459 == GFC_ARRAY_ALLOCATABLE
1460 || expr->symtree->n.sym->attr.select_type_temporary);
1461 *token = gfc_conv_descriptor_token (caf_decl);
1462 }
1463 else if (DECL_LANG_SPECIFIC (caf_decl)
1464 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1465 *token = GFC_DECL_TOKEN (caf_decl);
1466 else
1467 {
1468 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
1469 && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
1470 *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
1471 }
1472
1473 if (offset == NULL)
1474 return;
1475
1476 /* Offset between the coarray base address and the address wanted. */
1477 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
1478 && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
1479 || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
1480 *offset = build_int_cst (gfc_array_index_type, 0);
1481 else if (DECL_LANG_SPECIFIC (caf_decl)
1482 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
1483 *offset = GFC_DECL_CAF_OFFSET (caf_decl);
1484 else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
1485 *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
1486 else
1487 *offset = build_int_cst (gfc_array_index_type, 0);
1488
1489 if (POINTER_TYPE_P (TREE_TYPE (se_expr))
1490 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
1491 {
1492 tmp = build_fold_indirect_ref_loc (input_location, se_expr);
1493 tmp = gfc_conv_descriptor_data_get (tmp);
1494 }
1495 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
1496 tmp = gfc_conv_descriptor_data_get (se_expr);
1497 else
1498 {
1499 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
1500 tmp = se_expr;
1501 }
1502
1503 *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1504 *offset, fold_convert (gfc_array_index_type, tmp));
1505
1506 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
1507 tmp = gfc_conv_descriptor_data_get (caf_decl);
1508 else
1509 {
1510 gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
1511 tmp = caf_decl;
1512 }
1513
1514 *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
1515 fold_convert (gfc_array_index_type, *offset),
1516 fold_convert (gfc_array_index_type, tmp));
1517 }
1518
1519
1520 /* Convert the coindex of a coarray into an image index; the result is
1521 image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2)+1)*extent(1)
1522 + (idx(3)-lcobound(3)+1)*extent(2) + ... */
1523
1524 tree
1525 gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
1526 {
1527 gfc_ref *ref;
1528 tree lbound, ubound, extent, tmp, img_idx;
1529 gfc_se se;
1530 int i;
1531
1532 for (ref = e->ref; ref; ref = ref->next)
1533 if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
1534 break;
1535 gcc_assert (ref != NULL);
1536
1537 img_idx = integer_zero_node;
1538 extent = integer_one_node;
1539 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
1540 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
1541 {
1542 gfc_init_se (&se, NULL);
1543 gfc_conv_expr_type (&se, ref->u.ar.start[i], integer_type_node);
1544 gfc_add_block_to_block (block, &se.pre);
1545 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
1546 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1547 integer_type_node, se.expr,
1548 fold_convert(integer_type_node, lbound));
1549 tmp = fold_build2_loc (input_location, MULT_EXPR, integer_type_node,
1550 extent, tmp);
1551 img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
1552 img_idx, tmp);
1553 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
1554 {
1555 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
1556 extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
1557 extent = fold_convert (integer_type_node, extent);
1558 }
1559 }
1560 else
1561 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
1562 {
1563 gfc_init_se (&se, NULL);
1564 gfc_conv_expr_type (&se, ref->u.ar.start[i], integer_type_node);
1565 gfc_add_block_to_block (block, &se.pre);
1566 lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
1567 lbound = fold_convert (integer_type_node, lbound);
1568 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1569 integer_type_node, se.expr, lbound);
1570 tmp = fold_build2_loc (input_location, MULT_EXPR, integer_type_node,
1571 extent, tmp);
1572 img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
1573 img_idx, tmp);
1574 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
1575 {
1576 ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
1577 ubound = fold_convert (integer_type_node, ubound);
1578 extent = fold_build2_loc (input_location, MINUS_EXPR,
1579 integer_type_node, ubound, lbound);
1580 extent = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
1581 extent, integer_one_node);
1582 }
1583 }
1584 img_idx = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
1585 img_idx, integer_one_node);
1586 return img_idx;
1587 }
1588
1589
1590 /* For each character array constructor subexpression without a ts.u.cl->length,
1591 replace it by its first element (if there aren't any elements, the length
1592 should already be set to zero). */
1593
1594 static void
1595 flatten_array_ctors_without_strlen (gfc_expr* e)
1596 {
1597 gfc_actual_arglist* arg;
1598 gfc_constructor* c;
1599
1600 if (!e)
1601 return;
1602
1603 switch (e->expr_type)
1604 {
1605
1606 case EXPR_OP:
1607 flatten_array_ctors_without_strlen (e->value.op.op1);
1608 flatten_array_ctors_without_strlen (e->value.op.op2);
1609 break;
1610
1611 case EXPR_COMPCALL:
1612 /* TODO: Implement as with EXPR_FUNCTION when needed. */
1613 gcc_unreachable ();
1614
1615 case EXPR_FUNCTION:
1616 for (arg = e->value.function.actual; arg; arg = arg->next)
1617 flatten_array_ctors_without_strlen (arg->expr);
1618 break;
1619
1620 case EXPR_ARRAY:
1621
1622 /* We've found what we're looking for. */
1623 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
1624 {
1625 gfc_constructor *c;
1626 gfc_expr* new_expr;
1627
1628 gcc_assert (e->value.constructor);
1629
1630 c = gfc_constructor_first (e->value.constructor);
1631 new_expr = c->expr;
1632 c->expr = NULL;
1633
1634 flatten_array_ctors_without_strlen (new_expr);
1635 gfc_replace_expr (e, new_expr);
1636 break;
1637 }
1638
1639 /* Otherwise, fall through to handle constructor elements. */
1640 case EXPR_STRUCTURE:
1641 for (c = gfc_constructor_first (e->value.constructor);
1642 c; c = gfc_constructor_next (c))
1643 flatten_array_ctors_without_strlen (c->expr);
1644 break;
1645
1646 default:
1647 break;
1648
1649 }
1650 }
1651
1652
1653 /* Generate code to initialize a string length variable. Returns the
1654 value. For array constructors, cl->length might be NULL and in this case,
1655 the first element of the constructor is needed. expr is the original
1656 expression so we can access it but can be NULL if this is not needed. */
1657
1658 void
1659 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
1660 {
1661 gfc_se se;
1662
1663 gfc_init_se (&se, NULL);
1664
1665 if (!cl->length
1666 && cl->backend_decl
1667 && TREE_CODE (cl->backend_decl) == VAR_DECL)
1668 return;
1669
1670 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
1671 "flatten" array constructors by taking their first element; all elements
1672 should be the same length or a cl->length should be present. */
1673 if (!cl->length)
1674 {
1675 gfc_expr* expr_flat;
1676 gcc_assert (expr);
1677 expr_flat = gfc_copy_expr (expr);
1678 flatten_array_ctors_without_strlen (expr_flat);
1679 gfc_resolve_expr (expr_flat);
1680
1681 gfc_conv_expr (&se, expr_flat);
1682 gfc_add_block_to_block (pblock, &se.pre);
1683 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
1684
1685 gfc_free_expr (expr_flat);
1686 return;
1687 }
1688
1689 /* Convert cl->length. */
1690
1691 gcc_assert (cl->length);
1692
1693 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
1694 se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
1695 se.expr, build_int_cst (gfc_charlen_type_node, 0));
1696 gfc_add_block_to_block (pblock, &se.pre);
1697
1698 if (cl->backend_decl)
1699 gfc_add_modify (pblock, cl->backend_decl, se.expr);
1700 else
1701 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
1702 }
1703
1704
1705 static void
1706 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
1707 const char *name, locus *where)
1708 {
1709 tree tmp;
1710 tree type;
1711 tree fault;
1712 gfc_se start;
1713 gfc_se end;
1714 char *msg;
1715 mpz_t length;
1716
1717 type = gfc_get_character_type (kind, ref->u.ss.length);
1718 type = build_pointer_type (type);
1719
1720 gfc_init_se (&start, se);
1721 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
1722 gfc_add_block_to_block (&se->pre, &start.pre);
1723
1724 if (integer_onep (start.expr))
1725 gfc_conv_string_parameter (se);
1726 else
1727 {
1728 tmp = start.expr;
1729 STRIP_NOPS (tmp);
1730 /* Avoid multiple evaluation of substring start. */
1731 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1732 start.expr = gfc_evaluate_now (start.expr, &se->pre);
1733
1734 /* Change the start of the string. */
1735 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
1736 tmp = se->expr;
1737 else
1738 tmp = build_fold_indirect_ref_loc (input_location,
1739 se->expr);
1740 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
1741 se->expr = gfc_build_addr_expr (type, tmp);
1742 }
1743
1744 /* Length = end + 1 - start. */
1745 gfc_init_se (&end, se);
1746 if (ref->u.ss.end == NULL)
1747 end.expr = se->string_length;
1748 else
1749 {
1750 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
1751 gfc_add_block_to_block (&se->pre, &end.pre);
1752 }
1753 tmp = end.expr;
1754 STRIP_NOPS (tmp);
1755 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1756 end.expr = gfc_evaluate_now (end.expr, &se->pre);
1757
1758 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1759 {
1760 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
1761 boolean_type_node, start.expr,
1762 end.expr);
1763
1764 /* Check lower bound. */
1765 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1766 start.expr,
1767 build_int_cst (gfc_charlen_type_node, 1));
1768 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1769 boolean_type_node, nonempty, fault);
1770 if (name)
1771 asprintf (&msg, "Substring out of bounds: lower bound (%%ld) of '%s' "
1772 "is less than one", name);
1773 else
1774 asprintf (&msg, "Substring out of bounds: lower bound (%%ld)"
1775 "is less than one");
1776 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
1777 fold_convert (long_integer_type_node,
1778 start.expr));
1779 free (msg);
1780
1781 /* Check upper bound. */
1782 fault = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1783 end.expr, se->string_length);
1784 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1785 boolean_type_node, nonempty, fault);
1786 if (name)
1787 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) of '%s' "
1788 "exceeds string length (%%ld)", name);
1789 else
1790 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) "
1791 "exceeds string length (%%ld)");
1792 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
1793 fold_convert (long_integer_type_node, end.expr),
1794 fold_convert (long_integer_type_node,
1795 se->string_length));
1796 free (msg);
1797 }
1798
1799 /* Try to calculate the length from the start and end expressions. */
1800 if (ref->u.ss.end
1801 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
1802 {
1803 int i_len;
1804
1805 i_len = mpz_get_si (length) + 1;
1806 if (i_len < 0)
1807 i_len = 0;
1808
1809 tmp = build_int_cst (gfc_charlen_type_node, i_len);
1810 mpz_clear (length); /* Was initialized by gfc_dep_difference. */
1811 }
1812 else
1813 {
1814 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
1815 end.expr, start.expr);
1816 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
1817 build_int_cst (gfc_charlen_type_node, 1), tmp);
1818 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
1819 tmp, build_int_cst (gfc_charlen_type_node, 0));
1820 }
1821
1822 se->string_length = tmp;
1823 }
1824
1825
1826 /* Convert a derived type component reference. */
1827
1828 static void
1829 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
1830 {
1831 gfc_component *c;
1832 tree tmp;
1833 tree decl;
1834 tree field;
1835
1836 c = ref->u.c.component;
1837
1838 gcc_assert (c->backend_decl);
1839
1840 field = c->backend_decl;
1841 gcc_assert (TREE_CODE (field) == FIELD_DECL);
1842 decl = se->expr;
1843
1844 /* Components can correspond to fields of different containing
1845 types, as components are created without context, whereas
1846 a concrete use of a component has the type of decl as context.
1847 So, if the type doesn't match, we search the corresponding
1848 FIELD_DECL in the parent type. To not waste too much time
1849 we cache this result in norestrict_decl. */
1850
1851 if (DECL_FIELD_CONTEXT (field) != TREE_TYPE (decl))
1852 {
1853 tree f2 = c->norestrict_decl;
1854 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
1855 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
1856 if (TREE_CODE (f2) == FIELD_DECL
1857 && DECL_NAME (f2) == DECL_NAME (field))
1858 break;
1859 gcc_assert (f2);
1860 c->norestrict_decl = f2;
1861 field = f2;
1862 }
1863
1864 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
1865 decl, field, NULL_TREE);
1866
1867 se->expr = tmp;
1868
1869 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer)
1870 {
1871 tmp = c->ts.u.cl->backend_decl;
1872 /* Components must always be constant length. */
1873 gcc_assert (tmp && INTEGER_CST_P (tmp));
1874 se->string_length = tmp;
1875 }
1876
1877 if (gfc_deferred_strlen (c, &field))
1878 {
1879 tmp = fold_build3_loc (input_location, COMPONENT_REF,
1880 TREE_TYPE (field),
1881 decl, field, NULL_TREE);
1882 se->string_length = tmp;
1883 }
1884
1885 if (((c->attr.pointer || c->attr.allocatable)
1886 && (!c->attr.dimension && !c->attr.codimension)
1887 && c->ts.type != BT_CHARACTER)
1888 || c->attr.proc_pointer)
1889 se->expr = build_fold_indirect_ref_loc (input_location,
1890 se->expr);
1891 }
1892
1893
1894 /* This function deals with component references to components of the
1895 parent type for derived type extensions. */
1896 static void
1897 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
1898 {
1899 gfc_component *c;
1900 gfc_component *cmp;
1901 gfc_symbol *dt;
1902 gfc_ref parent;
1903
1904 dt = ref->u.c.sym;
1905 c = ref->u.c.component;
1906
1907 /* Return if the component is in the parent type. */
1908 for (cmp = dt->components; cmp; cmp = cmp->next)
1909 if (strcmp (c->name, cmp->name) == 0)
1910 return;
1911
1912 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
1913 parent.type = REF_COMPONENT;
1914 parent.next = NULL;
1915 parent.u.c.sym = dt;
1916 parent.u.c.component = dt->components;
1917
1918 if (dt->backend_decl == NULL)
1919 gfc_get_derived_type (dt);
1920
1921 /* Build the reference and call self. */
1922 gfc_conv_component_ref (se, &parent);
1923 parent.u.c.sym = dt->components->ts.u.derived;
1924 parent.u.c.component = c;
1925 conv_parent_component_references (se, &parent);
1926 }
1927
1928 /* Return the contents of a variable. Also handles reference/pointer
1929 variables (all Fortran pointer references are implicit). */
1930
1931 static void
1932 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
1933 {
1934 gfc_ss *ss;
1935 gfc_ref *ref;
1936 gfc_symbol *sym;
1937 tree parent_decl = NULL_TREE;
1938 int parent_flag;
1939 bool return_value;
1940 bool alternate_entry;
1941 bool entry_master;
1942
1943 sym = expr->symtree->n.sym;
1944 ss = se->ss;
1945 if (ss != NULL)
1946 {
1947 gfc_ss_info *ss_info = ss->info;
1948
1949 /* Check that something hasn't gone horribly wrong. */
1950 gcc_assert (ss != gfc_ss_terminator);
1951 gcc_assert (ss_info->expr == expr);
1952
1953 /* A scalarized term. We already know the descriptor. */
1954 se->expr = ss_info->data.array.descriptor;
1955 se->string_length = ss_info->string_length;
1956 ref = ss_info->data.array.ref;
1957 if (ref)
1958 gcc_assert (ref->type == REF_ARRAY
1959 && ref->u.ar.type != AR_ELEMENT);
1960 else
1961 gfc_conv_tmp_array_ref (se);
1962 }
1963 else
1964 {
1965 tree se_expr = NULL_TREE;
1966
1967 se->expr = gfc_get_symbol_decl (sym);
1968
1969 /* Deal with references to a parent results or entries by storing
1970 the current_function_decl and moving to the parent_decl. */
1971 return_value = sym->attr.function && sym->result == sym;
1972 alternate_entry = sym->attr.function && sym->attr.entry
1973 && sym->result == sym;
1974 entry_master = sym->attr.result
1975 && sym->ns->proc_name->attr.entry_master
1976 && !gfc_return_by_reference (sym->ns->proc_name);
1977 if (current_function_decl)
1978 parent_decl = DECL_CONTEXT (current_function_decl);
1979
1980 if ((se->expr == parent_decl && return_value)
1981 || (sym->ns && sym->ns->proc_name
1982 && parent_decl
1983 && sym->ns->proc_name->backend_decl == parent_decl
1984 && (alternate_entry || entry_master)))
1985 parent_flag = 1;
1986 else
1987 parent_flag = 0;
1988
1989 /* Special case for assigning the return value of a function.
1990 Self recursive functions must have an explicit return value. */
1991 if (return_value && (se->expr == current_function_decl || parent_flag))
1992 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
1993
1994 /* Similarly for alternate entry points. */
1995 else if (alternate_entry
1996 && (sym->ns->proc_name->backend_decl == current_function_decl
1997 || parent_flag))
1998 {
1999 gfc_entry_list *el = NULL;
2000
2001 for (el = sym->ns->entries; el; el = el->next)
2002 if (sym == el->sym)
2003 {
2004 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2005 break;
2006 }
2007 }
2008
2009 else if (entry_master
2010 && (sym->ns->proc_name->backend_decl == current_function_decl
2011 || parent_flag))
2012 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
2013
2014 if (se_expr)
2015 se->expr = se_expr;
2016
2017 /* Procedure actual arguments. */
2018 else if (sym->attr.flavor == FL_PROCEDURE
2019 && se->expr != current_function_decl)
2020 {
2021 if (!sym->attr.dummy && !sym->attr.proc_pointer)
2022 {
2023 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
2024 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
2025 }
2026 return;
2027 }
2028
2029
2030 /* Dereference the expression, where needed. Since characters
2031 are entirely different from other types, they are treated
2032 separately. */
2033 if (sym->ts.type == BT_CHARACTER)
2034 {
2035 /* Dereference character pointer dummy arguments
2036 or results. */
2037 if ((sym->attr.pointer || sym->attr.allocatable)
2038 && (sym->attr.dummy
2039 || sym->attr.function
2040 || sym->attr.result))
2041 se->expr = build_fold_indirect_ref_loc (input_location,
2042 se->expr);
2043
2044 }
2045 else if (!sym->attr.value)
2046 {
2047 /* Dereference non-character scalar dummy arguments. */
2048 if (sym->attr.dummy && !sym->attr.dimension
2049 && !(sym->attr.codimension && sym->attr.allocatable))
2050 se->expr = build_fold_indirect_ref_loc (input_location,
2051 se->expr);
2052
2053 /* Dereference scalar hidden result. */
2054 if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
2055 && (sym->attr.function || sym->attr.result)
2056 && !sym->attr.dimension && !sym->attr.pointer
2057 && !sym->attr.always_explicit)
2058 se->expr = build_fold_indirect_ref_loc (input_location,
2059 se->expr);
2060
2061 /* Dereference non-character pointer variables.
2062 These must be dummies, results, or scalars. */
2063 if ((sym->attr.pointer || sym->attr.allocatable
2064 || gfc_is_associate_pointer (sym)
2065 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2066 && (sym->attr.dummy
2067 || sym->attr.function
2068 || sym->attr.result
2069 || (!sym->attr.dimension
2070 && (!sym->attr.codimension || !sym->attr.allocatable))))
2071 se->expr = build_fold_indirect_ref_loc (input_location,
2072 se->expr);
2073 }
2074
2075 ref = expr->ref;
2076 }
2077
2078 /* For character variables, also get the length. */
2079 if (sym->ts.type == BT_CHARACTER)
2080 {
2081 /* If the character length of an entry isn't set, get the length from
2082 the master function instead. */
2083 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
2084 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
2085 else
2086 se->string_length = sym->ts.u.cl->backend_decl;
2087 gcc_assert (se->string_length);
2088 }
2089
2090 while (ref)
2091 {
2092 switch (ref->type)
2093 {
2094 case REF_ARRAY:
2095 /* Return the descriptor if that's what we want and this is an array
2096 section reference. */
2097 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
2098 return;
2099 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
2100 /* Return the descriptor for array pointers and allocations. */
2101 if (se->want_pointer
2102 && ref->next == NULL && (se->descriptor_only))
2103 return;
2104
2105 gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
2106 /* Return a pointer to an element. */
2107 break;
2108
2109 case REF_COMPONENT:
2110 if (ref->u.c.sym->attr.extension)
2111 conv_parent_component_references (se, ref);
2112
2113 gfc_conv_component_ref (se, ref);
2114 if (!ref->next && ref->u.c.sym->attr.codimension
2115 && se->want_pointer && se->descriptor_only)
2116 return;
2117
2118 break;
2119
2120 case REF_SUBSTRING:
2121 gfc_conv_substring (se, ref, expr->ts.kind,
2122 expr->symtree->name, &expr->where);
2123 break;
2124
2125 default:
2126 gcc_unreachable ();
2127 break;
2128 }
2129 ref = ref->next;
2130 }
2131 /* Pointer assignment, allocation or pass by reference. Arrays are handled
2132 separately. */
2133 if (se->want_pointer)
2134 {
2135 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
2136 gfc_conv_string_parameter (se);
2137 else
2138 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
2139 }
2140 }
2141
2142
2143 /* Unary ops are easy... Or they would be if ! was a valid op. */
2144
2145 static void
2146 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
2147 {
2148 gfc_se operand;
2149 tree type;
2150
2151 gcc_assert (expr->ts.type != BT_CHARACTER);
2152 /* Initialize the operand. */
2153 gfc_init_se (&operand, se);
2154 gfc_conv_expr_val (&operand, expr->value.op.op1);
2155 gfc_add_block_to_block (&se->pre, &operand.pre);
2156
2157 type = gfc_typenode_for_spec (&expr->ts);
2158
2159 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
2160 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
2161 All other unary operators have an equivalent GIMPLE unary operator. */
2162 if (code == TRUTH_NOT_EXPR)
2163 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
2164 build_int_cst (type, 0));
2165 else
2166 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
2167
2168 }
2169
2170 /* Expand power operator to optimal multiplications when a value is raised
2171 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
2172 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
2173 Programming", 3rd Edition, 1998. */
2174
2175 /* This code is mostly duplicated from expand_powi in the backend.
2176 We establish the "optimal power tree" lookup table with the defined size.
2177 The items in the table are the exponents used to calculate the index
2178 exponents. Any integer n less than the value can get an "addition chain",
2179 with the first node being one. */
2180 #define POWI_TABLE_SIZE 256
2181
2182 /* The table is from builtins.c. */
2183 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2184 {
2185 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2186 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2187 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2188 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2189 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2190 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2191 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2192 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2193 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2194 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2195 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2196 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2197 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2198 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2199 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2200 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2201 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2202 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2203 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2204 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2205 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2206 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2207 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2208 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2209 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2210 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2211 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2212 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2213 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2214 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2215 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2216 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2217 };
2218
2219 /* If n is larger than lookup table's max index, we use the "window
2220 method". */
2221 #define POWI_WINDOW_SIZE 3
2222
2223 /* Recursive function to expand the power operator. The temporary
2224 values are put in tmpvar. The function returns tmpvar[1] ** n. */
2225 static tree
2226 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
2227 {
2228 tree op0;
2229 tree op1;
2230 tree tmp;
2231 int digit;
2232
2233 if (n < POWI_TABLE_SIZE)
2234 {
2235 if (tmpvar[n])
2236 return tmpvar[n];
2237
2238 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
2239 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
2240 }
2241 else if (n & 1)
2242 {
2243 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2244 op0 = gfc_conv_powi (se, n - digit, tmpvar);
2245 op1 = gfc_conv_powi (se, digit, tmpvar);
2246 }
2247 else
2248 {
2249 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
2250 op1 = op0;
2251 }
2252
2253 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
2254 tmp = gfc_evaluate_now (tmp, &se->pre);
2255
2256 if (n < POWI_TABLE_SIZE)
2257 tmpvar[n] = tmp;
2258
2259 return tmp;
2260 }
2261
2262
2263 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
2264 return 1. Else return 0 and a call to runtime library functions
2265 will have to be built. */
2266 static int
2267 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
2268 {
2269 tree cond;
2270 tree tmp;
2271 tree type;
2272 tree vartmp[POWI_TABLE_SIZE];
2273 HOST_WIDE_INT m;
2274 unsigned HOST_WIDE_INT n;
2275 int sgn;
2276 wide_int wrhs = rhs;
2277
2278 /* If exponent is too large, we won't expand it anyway, so don't bother
2279 with large integer values. */
2280 if (!wi::fits_shwi_p (wrhs))
2281 return 0;
2282
2283 m = wrhs.to_shwi ();
2284 /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
2285 of the asymmetric range of the integer type. */
2286 n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
2287
2288 type = TREE_TYPE (lhs);
2289 sgn = tree_int_cst_sgn (rhs);
2290
2291 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
2292 || optimize_size) && (m > 2 || m < -1))
2293 return 0;
2294
2295 /* rhs == 0 */
2296 if (sgn == 0)
2297 {
2298 se->expr = gfc_build_const (type, integer_one_node);
2299 return 1;
2300 }
2301
2302 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
2303 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
2304 {
2305 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
2306 lhs, build_int_cst (TREE_TYPE (lhs), -1));
2307 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
2308 lhs, build_int_cst (TREE_TYPE (lhs), 1));
2309
2310 /* If rhs is even,
2311 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
2312 if ((n & 1) == 0)
2313 {
2314 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
2315 boolean_type_node, tmp, cond);
2316 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
2317 tmp, build_int_cst (type, 1),
2318 build_int_cst (type, 0));
2319 return 1;
2320 }
2321 /* If rhs is odd,
2322 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
2323 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
2324 build_int_cst (type, -1),
2325 build_int_cst (type, 0));
2326 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
2327 cond, build_int_cst (type, 1), tmp);
2328 return 1;
2329 }
2330
2331 memset (vartmp, 0, sizeof (vartmp));
2332 vartmp[1] = lhs;
2333 if (sgn == -1)
2334 {
2335 tmp = gfc_build_const (type, integer_one_node);
2336 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
2337 vartmp[1]);
2338 }
2339
2340 se->expr = gfc_conv_powi (se, n, vartmp);
2341
2342 return 1;
2343 }
2344
2345
2346 /* Power op (**). Constant integer exponent has special handling. */
2347
2348 static void
2349 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
2350 {
2351 tree gfc_int4_type_node;
2352 int kind;
2353 int ikind;
2354 int res_ikind_1, res_ikind_2;
2355 gfc_se lse;
2356 gfc_se rse;
2357 tree fndecl = NULL;
2358
2359 gfc_init_se (&lse, se);
2360 gfc_conv_expr_val (&lse, expr->value.op.op1);
2361 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
2362 gfc_add_block_to_block (&se->pre, &lse.pre);
2363
2364 gfc_init_se (&rse, se);
2365 gfc_conv_expr_val (&rse, expr->value.op.op2);
2366 gfc_add_block_to_block (&se->pre, &rse.pre);
2367
2368 if (expr->value.op.op2->ts.type == BT_INTEGER
2369 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
2370 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
2371 return;
2372
2373 gfc_int4_type_node = gfc_get_int_type (4);
2374
2375 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
2376 library routine. But in the end, we have to convert the result back
2377 if this case applies -- with res_ikind_K, we keep track whether operand K
2378 falls into this case. */
2379 res_ikind_1 = -1;
2380 res_ikind_2 = -1;
2381
2382 kind = expr->value.op.op1->ts.kind;
2383 switch (expr->value.op.op2->ts.type)
2384 {
2385 case BT_INTEGER:
2386 ikind = expr->value.op.op2->ts.kind;
2387 switch (ikind)
2388 {
2389 case 1:
2390 case 2:
2391 rse.expr = convert (gfc_int4_type_node, rse.expr);
2392 res_ikind_2 = ikind;
2393 /* Fall through. */
2394
2395 case 4:
2396 ikind = 0;
2397 break;
2398
2399 case 8:
2400 ikind = 1;
2401 break;
2402
2403 case 16:
2404 ikind = 2;
2405 break;
2406
2407 default:
2408 gcc_unreachable ();
2409 }
2410 switch (kind)
2411 {
2412 case 1:
2413 case 2:
2414 if (expr->value.op.op1->ts.type == BT_INTEGER)
2415 {
2416 lse.expr = convert (gfc_int4_type_node, lse.expr);
2417 res_ikind_1 = kind;
2418 }
2419 else
2420 gcc_unreachable ();
2421 /* Fall through. */
2422
2423 case 4:
2424 kind = 0;
2425 break;
2426
2427 case 8:
2428 kind = 1;
2429 break;
2430
2431 case 10:
2432 kind = 2;
2433 break;
2434
2435 case 16:
2436 kind = 3;
2437 break;
2438
2439 default:
2440 gcc_unreachable ();
2441 }
2442
2443 switch (expr->value.op.op1->ts.type)
2444 {
2445 case BT_INTEGER:
2446 if (kind == 3) /* Case 16 was not handled properly above. */
2447 kind = 2;
2448 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
2449 break;
2450
2451 case BT_REAL:
2452 /* Use builtins for real ** int4. */
2453 if (ikind == 0)
2454 {
2455 switch (kind)
2456 {
2457 case 0:
2458 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
2459 break;
2460
2461 case 1:
2462 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
2463 break;
2464
2465 case 2:
2466 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
2467 break;
2468
2469 case 3:
2470 /* Use the __builtin_powil() only if real(kind=16) is
2471 actually the C long double type. */
2472 if (!gfc_real16_is_float128)
2473 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
2474 break;
2475
2476 default:
2477 gcc_unreachable ();
2478 }
2479 }
2480
2481 /* If we don't have a good builtin for this, go for the
2482 library function. */
2483 if (!fndecl)
2484 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
2485 break;
2486
2487 case BT_COMPLEX:
2488 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
2489 break;
2490
2491 default:
2492 gcc_unreachable ();
2493 }
2494 break;
2495
2496 case BT_REAL:
2497 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
2498 break;
2499
2500 case BT_COMPLEX:
2501 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
2502 break;
2503
2504 default:
2505 gcc_unreachable ();
2506 break;
2507 }
2508
2509 se->expr = build_call_expr_loc (input_location,
2510 fndecl, 2, lse.expr, rse.expr);
2511
2512 /* Convert the result back if it is of wrong integer kind. */
2513 if (res_ikind_1 != -1 && res_ikind_2 != -1)
2514 {
2515 /* We want the maximum of both operand kinds as result. */
2516 if (res_ikind_1 < res_ikind_2)
2517 res_ikind_1 = res_ikind_2;
2518 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
2519 }
2520 }
2521
2522
2523 /* Generate code to allocate a string temporary. */
2524
2525 tree
2526 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
2527 {
2528 tree var;
2529 tree tmp;
2530
2531 if (gfc_can_put_var_on_stack (len))
2532 {
2533 /* Create a temporary variable to hold the result. */
2534 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2535 gfc_charlen_type_node, len,
2536 build_int_cst (gfc_charlen_type_node, 1));
2537 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
2538
2539 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
2540 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
2541 else
2542 tmp = build_array_type (TREE_TYPE (type), tmp);
2543
2544 var = gfc_create_var (tmp, "str");
2545 var = gfc_build_addr_expr (type, var);
2546 }
2547 else
2548 {
2549 /* Allocate a temporary to hold the result. */
2550 var = gfc_create_var (type, "pstr");
2551 gcc_assert (POINTER_TYPE_P (type));
2552 tmp = TREE_TYPE (type);
2553 if (TREE_CODE (tmp) == ARRAY_TYPE)
2554 tmp = TREE_TYPE (tmp);
2555 tmp = TYPE_SIZE_UNIT (tmp);
2556 tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
2557 fold_convert (size_type_node, len),
2558 fold_convert (size_type_node, tmp));
2559 tmp = gfc_call_malloc (&se->pre, type, tmp);
2560 gfc_add_modify (&se->pre, var, tmp);
2561
2562 /* Free the temporary afterwards. */
2563 tmp = gfc_call_free (convert (pvoid_type_node, var));
2564 gfc_add_expr_to_block (&se->post, tmp);
2565 }
2566
2567 return var;
2568 }
2569
2570
2571 /* Handle a string concatenation operation. A temporary will be allocated to
2572 hold the result. */
2573
2574 static void
2575 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
2576 {
2577 gfc_se lse, rse;
2578 tree len, type, var, tmp, fndecl;
2579
2580 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
2581 && expr->value.op.op2->ts.type == BT_CHARACTER);
2582 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
2583
2584 gfc_init_se (&lse, se);
2585 gfc_conv_expr (&lse, expr->value.op.op1);
2586 gfc_conv_string_parameter (&lse);
2587 gfc_init_se (&rse, se);
2588 gfc_conv_expr (&rse, expr->value.op.op2);
2589 gfc_conv_string_parameter (&rse);
2590
2591 gfc_add_block_to_block (&se->pre, &lse.pre);
2592 gfc_add_block_to_block (&se->pre, &rse.pre);
2593
2594 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
2595 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2596 if (len == NULL_TREE)
2597 {
2598 len = fold_build2_loc (input_location, PLUS_EXPR,
2599 TREE_TYPE (lse.string_length),
2600 lse.string_length, rse.string_length);
2601 }
2602
2603 type = build_pointer_type (type);
2604
2605 var = gfc_conv_string_tmp (se, type, len);
2606
2607 /* Do the actual concatenation. */
2608 if (expr->ts.kind == 1)
2609 fndecl = gfor_fndecl_concat_string;
2610 else if (expr->ts.kind == 4)
2611 fndecl = gfor_fndecl_concat_string_char4;
2612 else
2613 gcc_unreachable ();
2614
2615 tmp = build_call_expr_loc (input_location,
2616 fndecl, 6, len, var, lse.string_length, lse.expr,
2617 rse.string_length, rse.expr);
2618 gfc_add_expr_to_block (&se->pre, tmp);
2619
2620 /* Add the cleanup for the operands. */
2621 gfc_add_block_to_block (&se->pre, &rse.post);
2622 gfc_add_block_to_block (&se->pre, &lse.post);
2623
2624 se->expr = var;
2625 se->string_length = len;
2626 }
2627
2628 /* Translates an op expression. Common (binary) cases are handled by this
2629 function, others are passed on. Recursion is used in either case.
2630 We use the fact that (op1.ts == op2.ts) (except for the power
2631 operator **).
2632 Operators need no special handling for scalarized expressions as long as
2633 they call gfc_conv_simple_val to get their operands.
2634 Character strings get special handling. */
2635
2636 static void
2637 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
2638 {
2639 enum tree_code code;
2640 gfc_se lse;
2641 gfc_se rse;
2642 tree tmp, type;
2643 int lop;
2644 int checkstring;
2645
2646 checkstring = 0;
2647 lop = 0;
2648 switch (expr->value.op.op)
2649 {
2650 case INTRINSIC_PARENTHESES:
2651 if ((expr->ts.type == BT_REAL
2652 || expr->ts.type == BT_COMPLEX)
2653 && gfc_option.flag_protect_parens)
2654 {
2655 gfc_conv_unary_op (PAREN_EXPR, se, expr);
2656 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
2657 return;
2658 }
2659
2660 /* Fallthrough. */
2661 case INTRINSIC_UPLUS:
2662 gfc_conv_expr (se, expr->value.op.op1);
2663 return;
2664
2665 case INTRINSIC_UMINUS:
2666 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
2667 return;
2668
2669 case INTRINSIC_NOT:
2670 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
2671 return;
2672
2673 case INTRINSIC_PLUS:
2674 code = PLUS_EXPR;
2675 break;
2676
2677 case INTRINSIC_MINUS:
2678 code = MINUS_EXPR;
2679 break;
2680
2681 case INTRINSIC_TIMES:
2682 code = MULT_EXPR;
2683 break;
2684
2685 case INTRINSIC_DIVIDE:
2686 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
2687 an integer, we must round towards zero, so we use a
2688 TRUNC_DIV_EXPR. */
2689 if (expr->ts.type == BT_INTEGER)
2690 code = TRUNC_DIV_EXPR;
2691 else
2692 code = RDIV_EXPR;
2693 break;
2694
2695 case INTRINSIC_POWER:
2696 gfc_conv_power_op (se, expr);
2697 return;
2698
2699 case INTRINSIC_CONCAT:
2700 gfc_conv_concat_op (se, expr);
2701 return;
2702
2703 case INTRINSIC_AND:
2704 code = TRUTH_ANDIF_EXPR;
2705 lop = 1;
2706 break;
2707
2708 case INTRINSIC_OR:
2709 code = TRUTH_ORIF_EXPR;
2710 lop = 1;
2711 break;
2712
2713 /* EQV and NEQV only work on logicals, but since we represent them
2714 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
2715 case INTRINSIC_EQ:
2716 case INTRINSIC_EQ_OS:
2717 case INTRINSIC_EQV:
2718 code = EQ_EXPR;
2719 checkstring = 1;
2720 lop = 1;
2721 break;
2722
2723 case INTRINSIC_NE:
2724 case INTRINSIC_NE_OS:
2725 case INTRINSIC_NEQV:
2726 code = NE_EXPR;
2727 checkstring = 1;
2728 lop = 1;
2729 break;
2730
2731 case INTRINSIC_GT:
2732 case INTRINSIC_GT_OS:
2733 code = GT_EXPR;
2734 checkstring = 1;
2735 lop = 1;
2736 break;
2737
2738 case INTRINSIC_GE:
2739 case INTRINSIC_GE_OS:
2740 code = GE_EXPR;
2741 checkstring = 1;
2742 lop = 1;
2743 break;
2744
2745 case INTRINSIC_LT:
2746 case INTRINSIC_LT_OS:
2747 code = LT_EXPR;
2748 checkstring = 1;
2749 lop = 1;
2750 break;
2751
2752 case INTRINSIC_LE:
2753 case INTRINSIC_LE_OS:
2754 code = LE_EXPR;
2755 checkstring = 1;
2756 lop = 1;
2757 break;
2758
2759 case INTRINSIC_USER:
2760 case INTRINSIC_ASSIGN:
2761 /* These should be converted into function calls by the frontend. */
2762 gcc_unreachable ();
2763
2764 default:
2765 fatal_error ("Unknown intrinsic op");
2766 return;
2767 }
2768
2769 /* The only exception to this is **, which is handled separately anyway. */
2770 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
2771
2772 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
2773 checkstring = 0;
2774
2775 /* lhs */
2776 gfc_init_se (&lse, se);
2777 gfc_conv_expr (&lse, expr->value.op.op1);
2778 gfc_add_block_to_block (&se->pre, &lse.pre);
2779
2780 /* rhs */
2781 gfc_init_se (&rse, se);
2782 gfc_conv_expr (&rse, expr->value.op.op2);
2783 gfc_add_block_to_block (&se->pre, &rse.pre);
2784
2785 if (checkstring)
2786 {
2787 gfc_conv_string_parameter (&lse);
2788 gfc_conv_string_parameter (&rse);
2789
2790 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
2791 rse.string_length, rse.expr,
2792 expr->value.op.op1->ts.kind,
2793 code);
2794 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
2795 gfc_add_block_to_block (&lse.post, &rse.post);
2796 }
2797
2798 type = gfc_typenode_for_spec (&expr->ts);
2799
2800 if (lop)
2801 {
2802 /* The result of logical ops is always boolean_type_node. */
2803 tmp = fold_build2_loc (input_location, code, boolean_type_node,
2804 lse.expr, rse.expr);
2805 se->expr = convert (type, tmp);
2806 }
2807 else
2808 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
2809
2810 /* Add the post blocks. */
2811 gfc_add_block_to_block (&se->post, &rse.post);
2812 gfc_add_block_to_block (&se->post, &lse.post);
2813 }
2814
2815 /* If a string's length is one, we convert it to a single character. */
2816
2817 tree
2818 gfc_string_to_single_character (tree len, tree str, int kind)
2819 {
2820
2821 if (len == NULL
2822 || !tree_fits_uhwi_p (len)
2823 || !POINTER_TYPE_P (TREE_TYPE (str)))
2824 return NULL_TREE;
2825
2826 if (TREE_INT_CST_LOW (len) == 1)
2827 {
2828 str = fold_convert (gfc_get_pchar_type (kind), str);
2829 return build_fold_indirect_ref_loc (input_location, str);
2830 }
2831
2832 if (kind == 1
2833 && TREE_CODE (str) == ADDR_EXPR
2834 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
2835 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
2836 && array_ref_low_bound (TREE_OPERAND (str, 0))
2837 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
2838 && TREE_INT_CST_LOW (len) > 1
2839 && TREE_INT_CST_LOW (len)
2840 == (unsigned HOST_WIDE_INT)
2841 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
2842 {
2843 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
2844 ret = build_fold_indirect_ref_loc (input_location, ret);
2845 if (TREE_CODE (ret) == INTEGER_CST)
2846 {
2847 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
2848 int i, length = TREE_STRING_LENGTH (string_cst);
2849 const char *ptr = TREE_STRING_POINTER (string_cst);
2850
2851 for (i = 1; i < length; i++)
2852 if (ptr[i] != ' ')
2853 return NULL_TREE;
2854
2855 return ret;
2856 }
2857 }
2858
2859 return NULL_TREE;
2860 }
2861
2862
2863 void
2864 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
2865 {
2866
2867 if (sym->backend_decl)
2868 {
2869 /* This becomes the nominal_type in
2870 function.c:assign_parm_find_data_types. */
2871 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
2872 /* This becomes the passed_type in
2873 function.c:assign_parm_find_data_types. C promotes char to
2874 integer for argument passing. */
2875 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
2876
2877 DECL_BY_REFERENCE (sym->backend_decl) = 0;
2878 }
2879
2880 if (expr != NULL)
2881 {
2882 /* If we have a constant character expression, make it into an
2883 integer. */
2884 if ((*expr)->expr_type == EXPR_CONSTANT)
2885 {
2886 gfc_typespec ts;
2887 gfc_clear_ts (&ts);
2888
2889 *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
2890 (int)(*expr)->value.character.string[0]);
2891 if ((*expr)->ts.kind != gfc_c_int_kind)
2892 {
2893 /* The expr needs to be compatible with a C int. If the
2894 conversion fails, then the 2 causes an ICE. */
2895 ts.type = BT_INTEGER;
2896 ts.kind = gfc_c_int_kind;
2897 gfc_convert_type (*expr, &ts, 2);
2898 }
2899 }
2900 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
2901 {
2902 if ((*expr)->ref == NULL)
2903 {
2904 se->expr = gfc_string_to_single_character
2905 (build_int_cst (integer_type_node, 1),
2906 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
2907 gfc_get_symbol_decl
2908 ((*expr)->symtree->n.sym)),
2909 (*expr)->ts.kind);
2910 }
2911 else
2912 {
2913 gfc_conv_variable (se, *expr);
2914 se->expr = gfc_string_to_single_character
2915 (build_int_cst (integer_type_node, 1),
2916 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
2917 se->expr),
2918 (*expr)->ts.kind);
2919 }
2920 }
2921 }
2922 }
2923
2924 /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
2925 if STR is a string literal, otherwise return -1. */
2926
2927 static int
2928 gfc_optimize_len_trim (tree len, tree str, int kind)
2929 {
2930 if (kind == 1
2931 && TREE_CODE (str) == ADDR_EXPR
2932 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
2933 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
2934 && array_ref_low_bound (TREE_OPERAND (str, 0))
2935 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
2936 && tree_fits_uhwi_p (len)
2937 && tree_to_uhwi (len) >= 1
2938 && tree_to_uhwi (len)
2939 == (unsigned HOST_WIDE_INT)
2940 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
2941 {
2942 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
2943 folded = build_fold_indirect_ref_loc (input_location, folded);
2944 if (TREE_CODE (folded) == INTEGER_CST)
2945 {
2946 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
2947 int length = TREE_STRING_LENGTH (string_cst);
2948 const char *ptr = TREE_STRING_POINTER (string_cst);
2949
2950 for (; length > 0; length--)
2951 if (ptr[length - 1] != ' ')
2952 break;
2953
2954 return length;
2955 }
2956 }
2957 return -1;
2958 }
2959
2960 /* Helper to build a call to memcmp. */
2961
2962 static tree
2963 build_memcmp_call (tree s1, tree s2, tree n)
2964 {
2965 tree tmp;
2966
2967 if (!POINTER_TYPE_P (TREE_TYPE (s1)))
2968 s1 = gfc_build_addr_expr (pvoid_type_node, s1);
2969 else
2970 s1 = fold_convert (pvoid_type_node, s1);
2971
2972 if (!POINTER_TYPE_P (TREE_TYPE (s2)))
2973 s2 = gfc_build_addr_expr (pvoid_type_node, s2);
2974 else
2975 s2 = fold_convert (pvoid_type_node, s2);
2976
2977 n = fold_convert (size_type_node, n);
2978
2979 tmp = build_call_expr_loc (input_location,
2980 builtin_decl_explicit (BUILT_IN_MEMCMP),
2981 3, s1, s2, n);
2982
2983 return fold_convert (integer_type_node, tmp);
2984 }
2985
2986 /* Compare two strings. If they are all single characters, the result is the
2987 subtraction of them. Otherwise, we build a library call. */
2988
2989 tree
2990 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
2991 enum tree_code code)
2992 {
2993 tree sc1;
2994 tree sc2;
2995 tree fndecl;
2996
2997 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
2998 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
2999
3000 sc1 = gfc_string_to_single_character (len1, str1, kind);
3001 sc2 = gfc_string_to_single_character (len2, str2, kind);
3002
3003 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
3004 {
3005 /* Deal with single character specially. */
3006 sc1 = fold_convert (integer_type_node, sc1);
3007 sc2 = fold_convert (integer_type_node, sc2);
3008 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
3009 sc1, sc2);
3010 }
3011
3012 if ((code == EQ_EXPR || code == NE_EXPR)
3013 && optimize
3014 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
3015 {
3016 /* If one string is a string literal with LEN_TRIM longer
3017 than the length of the second string, the strings
3018 compare unequal. */
3019 int len = gfc_optimize_len_trim (len1, str1, kind);
3020 if (len > 0 && compare_tree_int (len2, len) < 0)
3021 return integer_one_node;
3022 len = gfc_optimize_len_trim (len2, str2, kind);
3023 if (len > 0 && compare_tree_int (len1, len) < 0)
3024 return integer_one_node;
3025 }
3026
3027 /* We can compare via memcpy if the strings are known to be equal
3028 in length and they are
3029 - kind=1
3030 - kind=4 and the comparison is for (in)equality. */
3031
3032 if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
3033 && tree_int_cst_equal (len1, len2)
3034 && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
3035 {
3036 tree tmp;
3037 tree chartype;
3038
3039 chartype = gfc_get_char_type (kind);
3040 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
3041 fold_convert (TREE_TYPE(len1),
3042 TYPE_SIZE_UNIT(chartype)),
3043 len1);
3044 return build_memcmp_call (str1, str2, tmp);
3045 }
3046
3047 /* Build a call for the comparison. */
3048 if (kind == 1)
3049 fndecl = gfor_fndecl_compare_string;
3050 else if (kind == 4)
3051 fndecl = gfor_fndecl_compare_string_char4;
3052 else
3053 gcc_unreachable ();
3054
3055 return build_call_expr_loc (input_location, fndecl, 4,
3056 len1, str1, len2, str2);
3057 }
3058
3059
3060 /* Return the backend_decl for a procedure pointer component. */
3061
3062 static tree
3063 get_proc_ptr_comp (gfc_expr *e)
3064 {
3065 gfc_se comp_se;
3066 gfc_expr *e2;
3067 expr_t old_type;
3068
3069 gfc_init_se (&comp_se, NULL);
3070 e2 = gfc_copy_expr (e);
3071 /* We have to restore the expr type later so that gfc_free_expr frees
3072 the exact same thing that was allocated.
3073 TODO: This is ugly. */
3074 old_type = e2->expr_type;
3075 e2->expr_type = EXPR_VARIABLE;
3076 gfc_conv_expr (&comp_se, e2);
3077 e2->expr_type = old_type;
3078 gfc_free_expr (e2);
3079 return build_fold_addr_expr_loc (input_location, comp_se.expr);
3080 }
3081
3082
3083 /* Convert a typebound function reference from a class object. */
3084 static void
3085 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
3086 {
3087 gfc_ref *ref;
3088 tree var;
3089
3090 if (TREE_CODE (base_object) != VAR_DECL)
3091 {
3092 var = gfc_create_var (TREE_TYPE (base_object), NULL);
3093 gfc_add_modify (&se->pre, var, base_object);
3094 }
3095 se->expr = gfc_class_vptr_get (base_object);
3096 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
3097 ref = expr->ref;
3098 while (ref && ref->next)
3099 ref = ref->next;
3100 gcc_assert (ref && ref->type == REF_COMPONENT);
3101 if (ref->u.c.sym->attr.extension)
3102 conv_parent_component_references (se, ref);
3103 gfc_conv_component_ref (se, ref);
3104 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
3105 }
3106
3107
3108 static void
3109 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
3110 {
3111 tree tmp;
3112
3113 if (gfc_is_proc_ptr_comp (expr))
3114 tmp = get_proc_ptr_comp (expr);
3115 else if (sym->attr.dummy)
3116 {
3117 tmp = gfc_get_symbol_decl (sym);
3118 if (sym->attr.proc_pointer)
3119 tmp = build_fold_indirect_ref_loc (input_location,
3120 tmp);
3121 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
3122 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
3123 }
3124 else
3125 {
3126 if (!sym->backend_decl)
3127 sym->backend_decl = gfc_get_extern_function_decl (sym);
3128
3129 TREE_USED (sym->backend_decl) = 1;
3130
3131 tmp = sym->backend_decl;
3132
3133 if (sym->attr.cray_pointee)
3134 {
3135 /* TODO - make the cray pointee a pointer to a procedure,
3136 assign the pointer to it and use it for the call. This
3137 will do for now! */
3138 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
3139 gfc_get_symbol_decl (sym->cp_pointer));
3140 tmp = gfc_evaluate_now (tmp, &se->pre);
3141 }
3142
3143 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
3144 {
3145 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
3146 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3147 }
3148 }
3149 se->expr = tmp;
3150 }
3151
3152
3153 /* Initialize MAPPING. */
3154
3155 void
3156 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
3157 {
3158 mapping->syms = NULL;
3159 mapping->charlens = NULL;
3160 }
3161
3162
3163 /* Free all memory held by MAPPING (but not MAPPING itself). */
3164
3165 void
3166 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
3167 {
3168 gfc_interface_sym_mapping *sym;
3169 gfc_interface_sym_mapping *nextsym;
3170 gfc_charlen *cl;
3171 gfc_charlen *nextcl;
3172
3173 for (sym = mapping->syms; sym; sym = nextsym)
3174 {
3175 nextsym = sym->next;
3176 sym->new_sym->n.sym->formal = NULL;
3177 gfc_free_symbol (sym->new_sym->n.sym);
3178 gfc_free_expr (sym->expr);
3179 free (sym->new_sym);
3180 free (sym);
3181 }
3182 for (cl = mapping->charlens; cl; cl = nextcl)
3183 {
3184 nextcl = cl->next;
3185 gfc_free_expr (cl->length);
3186 free (cl);
3187 }
3188 }
3189
3190
3191 /* Return a copy of gfc_charlen CL. Add the returned structure to
3192 MAPPING so that it will be freed by gfc_free_interface_mapping. */
3193
3194 static gfc_charlen *
3195 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
3196 gfc_charlen * cl)
3197 {
3198 gfc_charlen *new_charlen;
3199
3200 new_charlen = gfc_get_charlen ();
3201 new_charlen->next = mapping->charlens;
3202 new_charlen->length = gfc_copy_expr (cl->length);
3203
3204 mapping->charlens = new_charlen;
3205 return new_charlen;
3206 }
3207
3208
3209 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
3210 array variable that can be used as the actual argument for dummy
3211 argument SYM. Add any initialization code to BLOCK. PACKED is as
3212 for gfc_get_nodesc_array_type and DATA points to the first element
3213 in the passed array. */
3214
3215 static tree
3216 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
3217 gfc_packed packed, tree data)
3218 {
3219 tree type;
3220 tree var;
3221
3222 type = gfc_typenode_for_spec (&sym->ts);
3223 type = gfc_get_nodesc_array_type (type, sym->as, packed,
3224 !sym->attr.target && !sym->attr.pointer
3225 && !sym->attr.proc_pointer);
3226
3227 var = gfc_create_var (type, "ifm");
3228 gfc_add_modify (block, var, fold_convert (type, data));
3229
3230 return var;
3231 }
3232
3233
3234 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
3235 and offset of descriptorless array type TYPE given that it has the same
3236 size as DESC. Add any set-up code to BLOCK. */
3237
3238 static void
3239 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
3240 {
3241 int n;
3242 tree dim;
3243 tree offset;
3244 tree tmp;
3245
3246 offset = gfc_index_zero_node;
3247 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
3248 {
3249 dim = gfc_rank_cst[n];
3250 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
3251 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
3252 {
3253 GFC_TYPE_ARRAY_LBOUND (type, n)
3254 = gfc_conv_descriptor_lbound_get (desc, dim);
3255 GFC_TYPE_ARRAY_UBOUND (type, n)
3256 = gfc_conv_descriptor_ubound_get (desc, dim);
3257 }
3258 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
3259 {
3260 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3261 gfc_array_index_type,
3262 gfc_conv_descriptor_ubound_get (desc, dim),
3263 gfc_conv_descriptor_lbound_get (desc, dim));
3264 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3265 gfc_array_index_type,
3266 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
3267 tmp = gfc_evaluate_now (tmp, block);
3268 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
3269 }
3270 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3271 GFC_TYPE_ARRAY_LBOUND (type, n),
3272 GFC_TYPE_ARRAY_STRIDE (type, n));
3273 offset = fold_build2_loc (input_location, MINUS_EXPR,
3274 gfc_array_index_type, offset, tmp);
3275 }
3276 offset = gfc_evaluate_now (offset, block);
3277 GFC_TYPE_ARRAY_OFFSET (type) = offset;
3278 }
3279
3280
3281 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
3282 in SE. The caller may still use se->expr and se->string_length after
3283 calling this function. */
3284
3285 void
3286 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
3287 gfc_symbol * sym, gfc_se * se,
3288 gfc_expr *expr)
3289 {
3290 gfc_interface_sym_mapping *sm;
3291 tree desc;
3292 tree tmp;
3293 tree value;
3294 gfc_symbol *new_sym;
3295 gfc_symtree *root;
3296 gfc_symtree *new_symtree;
3297
3298 /* Create a new symbol to represent the actual argument. */
3299 new_sym = gfc_new_symbol (sym->name, NULL);
3300 new_sym->ts = sym->ts;
3301 new_sym->as = gfc_copy_array_spec (sym->as);
3302 new_sym->attr.referenced = 1;
3303 new_sym->attr.dimension = sym->attr.dimension;
3304 new_sym->attr.contiguous = sym->attr.contiguous;
3305 new_sym->attr.codimension = sym->attr.codimension;
3306 new_sym->attr.pointer = sym->attr.pointer;
3307 new_sym->attr.allocatable = sym->attr.allocatable;
3308 new_sym->attr.flavor = sym->attr.flavor;
3309 new_sym->attr.function = sym->attr.function;
3310
3311 /* Ensure that the interface is available and that
3312 descriptors are passed for array actual arguments. */
3313 if (sym->attr.flavor == FL_PROCEDURE)
3314 {
3315 new_sym->formal = expr->symtree->n.sym->formal;
3316 new_sym->attr.always_explicit
3317 = expr->symtree->n.sym->attr.always_explicit;
3318 }
3319
3320 /* Create a fake symtree for it. */
3321 root = NULL;
3322 new_symtree = gfc_new_symtree (&root, sym->name);
3323 new_symtree->n.sym = new_sym;
3324 gcc_assert (new_symtree == root);
3325
3326 /* Create a dummy->actual mapping. */
3327 sm = XCNEW (gfc_interface_sym_mapping);
3328 sm->next = mapping->syms;
3329 sm->old = sym;
3330 sm->new_sym = new_symtree;
3331 sm->expr = gfc_copy_expr (expr);
3332 mapping->syms = sm;
3333
3334 /* Stabilize the argument's value. */
3335 if (!sym->attr.function && se)
3336 se->expr = gfc_evaluate_now (se->expr, &se->pre);
3337
3338 if (sym->ts.type == BT_CHARACTER)
3339 {
3340 /* Create a copy of the dummy argument's length. */
3341 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
3342 sm->expr->ts.u.cl = new_sym->ts.u.cl;
3343
3344 /* If the length is specified as "*", record the length that
3345 the caller is passing. We should use the callee's length
3346 in all other cases. */
3347 if (!new_sym->ts.u.cl->length && se)
3348 {
3349 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
3350 new_sym->ts.u.cl->backend_decl = se->string_length;
3351 }
3352 }
3353
3354 if (!se)
3355 return;
3356
3357 /* Use the passed value as-is if the argument is a function. */
3358 if (sym->attr.flavor == FL_PROCEDURE)
3359 value = se->expr;
3360
3361 /* If the argument is either a string or a pointer to a string,
3362 convert it to a boundless character type. */
3363 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
3364 {
3365 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
3366 tmp = build_pointer_type (tmp);
3367 if (sym->attr.pointer)
3368 value = build_fold_indirect_ref_loc (input_location,
3369 se->expr);
3370 else
3371 value = se->expr;
3372 value = fold_convert (tmp, value);
3373 }
3374
3375 /* If the argument is a scalar, a pointer to an array or an allocatable,
3376 dereference it. */
3377 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
3378 value = build_fold_indirect_ref_loc (input_location,
3379 se->expr);
3380
3381 /* For character(*), use the actual argument's descriptor. */
3382 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
3383 value = build_fold_indirect_ref_loc (input_location,
3384 se->expr);
3385
3386 /* If the argument is an array descriptor, use it to determine
3387 information about the actual argument's shape. */
3388 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
3389 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
3390 {
3391 /* Get the actual argument's descriptor. */
3392 desc = build_fold_indirect_ref_loc (input_location,
3393 se->expr);
3394
3395 /* Create the replacement variable. */
3396 tmp = gfc_conv_descriptor_data_get (desc);
3397 value = gfc_get_interface_mapping_array (&se->pre, sym,
3398 PACKED_NO, tmp);
3399
3400 /* Use DESC to work out the upper bounds, strides and offset. */
3401 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
3402 }
3403 else
3404 /* Otherwise we have a packed array. */
3405 value = gfc_get_interface_mapping_array (&se->pre, sym,
3406 PACKED_FULL, se->expr);
3407
3408 new_sym->backend_decl = value;
3409 }
3410
3411
3412 /* Called once all dummy argument mappings have been added to MAPPING,
3413 but before the mapping is used to evaluate expressions. Pre-evaluate
3414 the length of each argument, adding any initialization code to PRE and
3415 any finalization code to POST. */
3416
3417 void
3418 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
3419 stmtblock_t * pre, stmtblock_t * post)
3420 {
3421 gfc_interface_sym_mapping *sym;
3422 gfc_expr *expr;
3423 gfc_se se;
3424
3425 for (sym = mapping->syms; sym; sym = sym->next)
3426 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
3427 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
3428 {
3429 expr = sym->new_sym->n.sym->ts.u.cl->length;
3430 gfc_apply_interface_mapping_to_expr (mapping, expr);
3431 gfc_init_se (&se, NULL);
3432 gfc_conv_expr (&se, expr);
3433 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
3434 se.expr = gfc_evaluate_now (se.expr, &se.pre);
3435 gfc_add_block_to_block (pre, &se.pre);
3436 gfc_add_block_to_block (post, &se.post);
3437
3438 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
3439 }
3440 }
3441
3442
3443 /* Like gfc_apply_interface_mapping_to_expr, but applied to
3444 constructor C. */
3445
3446 static void
3447 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
3448 gfc_constructor_base base)
3449 {
3450 gfc_constructor *c;
3451 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
3452 {
3453 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
3454 if (c->iterator)
3455 {
3456 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
3457 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
3458 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
3459 }
3460 }
3461 }
3462
3463
3464 /* Like gfc_apply_interface_mapping_to_expr, but applied to
3465 reference REF. */
3466
3467 static void
3468 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
3469 gfc_ref * ref)
3470 {
3471 int n;
3472
3473 for (; ref; ref = ref->next)
3474 switch (ref->type)
3475 {
3476 case REF_ARRAY:
3477 for (n = 0; n < ref->u.ar.dimen; n++)
3478 {
3479 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
3480 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
3481 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
3482 }
3483 break;
3484
3485 case REF_COMPONENT:
3486 break;
3487
3488 case REF_SUBSTRING:
3489 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
3490 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
3491 break;
3492 }
3493 }
3494
3495
3496 /* Convert intrinsic function calls into result expressions. */
3497
3498 static bool
3499 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
3500 {
3501 gfc_symbol *sym;
3502 gfc_expr *new_expr;
3503 gfc_expr *arg1;
3504 gfc_expr *arg2;
3505 int d, dup;
3506
3507 arg1 = expr->value.function.actual->expr;
3508 if (expr->value.function.actual->next)
3509 arg2 = expr->value.function.actual->next->expr;
3510 else
3511 arg2 = NULL;
3512
3513 sym = arg1->symtree->n.sym;
3514
3515 if (sym->attr.dummy)
3516 return false;
3517
3518 new_expr = NULL;
3519
3520 switch (expr->value.function.isym->id)
3521 {
3522 case GFC_ISYM_LEN:
3523 /* TODO figure out why this condition is necessary. */
3524 if (sym->attr.function
3525 && (arg1->ts.u.cl->length == NULL
3526 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
3527 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
3528 return false;
3529
3530 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
3531 break;
3532
3533 case GFC_ISYM_SIZE:
3534 if (!sym->as || sym->as->rank == 0)
3535 return false;
3536
3537 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
3538 {
3539 dup = mpz_get_si (arg2->value.integer);
3540 d = dup - 1;
3541 }
3542 else
3543 {
3544 dup = sym->as->rank;
3545 d = 0;
3546 }
3547
3548 for (; d < dup; d++)
3549 {
3550 gfc_expr *tmp;
3551
3552 if (!sym->as->upper[d] || !sym->as->lower[d])
3553 {
3554 gfc_free_expr (new_expr);
3555 return false;
3556 }
3557
3558 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
3559 gfc_get_int_expr (gfc_default_integer_kind,
3560 NULL, 1));
3561 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
3562 if (new_expr)
3563 new_expr = gfc_multiply (new_expr, tmp);
3564 else
3565 new_expr = tmp;
3566 }
3567 break;
3568
3569 case GFC_ISYM_LBOUND:
3570 case GFC_ISYM_UBOUND:
3571 /* TODO These implementations of lbound and ubound do not limit if
3572 the size < 0, according to F95's 13.14.53 and 13.14.113. */
3573
3574 if (!sym->as || sym->as->rank == 0)
3575 return false;
3576
3577 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
3578 d = mpz_get_si (arg2->value.integer) - 1;
3579 else
3580 /* TODO: If the need arises, this could produce an array of
3581 ubound/lbounds. */
3582 gcc_unreachable ();
3583
3584 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
3585 {
3586 if (sym->as->lower[d])
3587 new_expr = gfc_copy_expr (sym->as->lower[d]);
3588 }
3589 else
3590 {
3591 if (sym->as->upper[d])
3592 new_expr = gfc_copy_expr (sym->as->upper[d]);
3593 }
3594 break;
3595
3596 default:
3597 break;
3598 }
3599
3600 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
3601 if (!new_expr)
3602 return false;
3603
3604 gfc_replace_expr (expr, new_expr);
3605 return true;
3606 }
3607
3608
3609 static void
3610 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
3611 gfc_interface_mapping * mapping)
3612 {
3613 gfc_formal_arglist *f;
3614 gfc_actual_arglist *actual;
3615
3616 actual = expr->value.function.actual;
3617 f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
3618
3619 for (; f && actual; f = f->next, actual = actual->next)
3620 {
3621 if (!actual->expr)
3622 continue;
3623
3624 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
3625 }
3626
3627 if (map_expr->symtree->n.sym->attr.dimension)
3628 {
3629 int d;
3630 gfc_array_spec *as;
3631
3632 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
3633
3634 for (d = 0; d < as->rank; d++)
3635 {
3636 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
3637 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
3638 }
3639
3640 expr->value.function.esym->as = as;
3641 }
3642
3643 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
3644 {
3645 expr->value.function.esym->ts.u.cl->length
3646 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
3647
3648 gfc_apply_interface_mapping_to_expr (mapping,
3649 expr->value.function.esym->ts.u.cl->length);
3650 }
3651 }
3652
3653
3654 /* EXPR is a copy of an expression that appeared in the interface
3655 associated with MAPPING. Walk it recursively looking for references to
3656 dummy arguments that MAPPING maps to actual arguments. Replace each such
3657 reference with a reference to the associated actual argument. */
3658
3659 static void
3660 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
3661 gfc_expr * expr)
3662 {
3663 gfc_interface_sym_mapping *sym;
3664 gfc_actual_arglist *actual;
3665
3666 if (!expr)
3667 return;
3668
3669 /* Copying an expression does not copy its length, so do that here. */
3670 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
3671 {
3672 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
3673 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
3674 }
3675
3676 /* Apply the mapping to any references. */
3677 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
3678
3679 /* ...and to the expression's symbol, if it has one. */
3680 /* TODO Find out why the condition on expr->symtree had to be moved into
3681 the loop rather than being outside it, as originally. */
3682 for (sym = mapping->syms; sym; sym = sym->next)
3683 if (expr->symtree && sym->old == expr->symtree->n.sym)
3684 {
3685 if (sym->new_sym->n.sym->backend_decl)
3686 expr->symtree = sym->new_sym;
3687 else if (sym->expr)
3688 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
3689 /* Replace base type for polymorphic arguments. */
3690 if (expr->ref && expr->ref->type == REF_COMPONENT
3691 && sym->expr && sym->expr->ts.type == BT_CLASS)
3692 expr->ref->u.c.sym = sym->expr->ts.u.derived;
3693 }
3694
3695 /* ...and to subexpressions in expr->value. */
3696 switch (expr->expr_type)
3697 {
3698 case EXPR_VARIABLE:
3699 case EXPR_CONSTANT:
3700 case EXPR_NULL:
3701 case EXPR_SUBSTRING:
3702 break;
3703
3704 case EXPR_OP:
3705 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
3706 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
3707 break;
3708
3709 case EXPR_FUNCTION:
3710 for (actual = expr->value.function.actual; actual; actual = actual->next)
3711 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
3712
3713 if (expr->value.function.esym == NULL
3714 && expr->value.function.isym != NULL
3715 && expr->value.function.actual->expr->symtree
3716 && gfc_map_intrinsic_function (expr, mapping))
3717 break;
3718
3719 for (sym = mapping->syms; sym; sym = sym->next)
3720 if (sym->old == expr->value.function.esym)
3721 {
3722 expr->value.function.esym = sym->new_sym->n.sym;
3723 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
3724 expr->value.function.esym->result = sym->new_sym->n.sym;
3725 }
3726 break;
3727
3728 case EXPR_ARRAY:
3729 case EXPR_STRUCTURE:
3730 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
3731 break;
3732
3733 case EXPR_COMPCALL:
3734 case EXPR_PPC:
3735 gcc_unreachable ();
3736 break;
3737 }
3738
3739 return;
3740 }
3741
3742
3743 /* Evaluate interface expression EXPR using MAPPING. Store the result
3744 in SE. */
3745
3746 void
3747 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
3748 gfc_se * se, gfc_expr * expr)
3749 {
3750 expr = gfc_copy_expr (expr);
3751 gfc_apply_interface_mapping_to_expr (mapping, expr);
3752 gfc_conv_expr (se, expr);
3753 se->expr = gfc_evaluate_now (se->expr, &se->pre);
3754 gfc_free_expr (expr);
3755 }
3756
3757
3758 /* Returns a reference to a temporary array into which a component of
3759 an actual argument derived type array is copied and then returned
3760 after the function call. */
3761 void
3762 gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
3763 sym_intent intent, bool formal_ptr)
3764 {
3765 gfc_se lse;
3766 gfc_se rse;
3767 gfc_ss *lss;
3768 gfc_ss *rss;
3769 gfc_loopinfo loop;
3770 gfc_loopinfo loop2;
3771 gfc_array_info *info;
3772 tree offset;
3773 tree tmp_index;
3774 tree tmp;
3775 tree base_type;
3776 tree size;
3777 stmtblock_t body;
3778 int n;
3779 int dimen;
3780
3781 gcc_assert (expr->expr_type == EXPR_VARIABLE);
3782
3783 gfc_init_se (&lse, NULL);
3784 gfc_init_se (&rse, NULL);
3785
3786 /* Walk the argument expression. */
3787 rss = gfc_walk_expr (expr);
3788
3789 gcc_assert (rss != gfc_ss_terminator);
3790
3791 /* Initialize the scalarizer. */
3792 gfc_init_loopinfo (&loop);
3793 gfc_add_ss_to_loop (&loop, rss);
3794
3795 /* Calculate the bounds of the scalarization. */
3796 gfc_conv_ss_startstride (&loop);
3797
3798 /* Build an ss for the temporary. */
3799 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
3800 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
3801
3802 base_type = gfc_typenode_for_spec (&expr->ts);
3803 if (GFC_ARRAY_TYPE_P (base_type)
3804 || GFC_DESCRIPTOR_TYPE_P (base_type))
3805 base_type = gfc_get_element_type (base_type);
3806
3807 if (expr->ts.type == BT_CLASS)
3808 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
3809
3810 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
3811 ? expr->ts.u.cl->backend_decl
3812 : NULL),
3813 loop.dimen);
3814
3815 parmse->string_length = loop.temp_ss->info->string_length;
3816
3817 /* Associate the SS with the loop. */
3818 gfc_add_ss_to_loop (&loop, loop.temp_ss);
3819
3820 /* Setup the scalarizing loops. */
3821 gfc_conv_loop_setup (&loop, &expr->where);
3822
3823 /* Pass the temporary descriptor back to the caller. */
3824 info = &loop.temp_ss->info->data.array;
3825 parmse->expr = info->descriptor;
3826
3827 /* Setup the gfc_se structures. */
3828 gfc_copy_loopinfo_to_se (&lse, &loop);
3829 gfc_copy_loopinfo_to_se (&rse, &loop);
3830
3831 rse.ss = rss;
3832 lse.ss = loop.temp_ss;
3833 gfc_mark_ss_chain_used (rss, 1);
3834 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3835
3836 /* Start the scalarized loop body. */
3837 gfc_start_scalarized_body (&loop, &body);
3838
3839 /* Translate the expression. */
3840 gfc_conv_expr (&rse, expr);
3841
3842 gfc_conv_tmp_array_ref (&lse);
3843
3844 if (intent != INTENT_OUT)
3845 {
3846 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false, true);
3847 gfc_add_expr_to_block (&body, tmp);
3848 gcc_assert (rse.ss == gfc_ss_terminator);
3849 gfc_trans_scalarizing_loops (&loop, &body);
3850 }
3851 else
3852 {
3853 /* Make sure that the temporary declaration survives by merging
3854 all the loop declarations into the current context. */
3855 for (n = 0; n < loop.dimen; n++)
3856 {
3857 gfc_merge_block_scope (&body);
3858 body = loop.code[loop.order[n]];
3859 }
3860 gfc_merge_block_scope (&body);
3861 }
3862
3863 /* Add the post block after the second loop, so that any
3864 freeing of allocated memory is done at the right time. */
3865 gfc_add_block_to_block (&parmse->pre, &loop.pre);
3866
3867 /**********Copy the temporary back again.*********/
3868
3869 gfc_init_se (&lse, NULL);
3870 gfc_init_se (&rse, NULL);
3871
3872 /* Walk the argument expression. */
3873 lss = gfc_walk_expr (expr);
3874 rse.ss = loop.temp_ss;
3875 lse.ss = lss;
3876
3877 /* Initialize the scalarizer. */
3878 gfc_init_loopinfo (&loop2);
3879 gfc_add_ss_to_loop (&loop2, lss);
3880
3881 /* Calculate the bounds of the scalarization. */
3882 gfc_conv_ss_startstride (&loop2);
3883
3884 /* Setup the scalarizing loops. */
3885 gfc_conv_loop_setup (&loop2, &expr->where);
3886
3887 gfc_copy_loopinfo_to_se (&lse, &loop2);
3888 gfc_copy_loopinfo_to_se (&rse, &loop2);
3889
3890 gfc_mark_ss_chain_used (lss, 1);
3891 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3892
3893 /* Declare the variable to hold the temporary offset and start the
3894 scalarized loop body. */
3895 offset = gfc_create_var (gfc_array_index_type, NULL);
3896 gfc_start_scalarized_body (&loop2, &body);
3897
3898 /* Build the offsets for the temporary from the loop variables. The
3899 temporary array has lbounds of zero and strides of one in all
3900 dimensions, so this is very simple. The offset is only computed
3901 outside the innermost loop, so the overall transfer could be
3902 optimized further. */
3903 info = &rse.ss->info->data.array;
3904 dimen = rse.ss->dimen;
3905
3906 tmp_index = gfc_index_zero_node;
3907 for (n = dimen - 1; n > 0; n--)
3908 {
3909 tree tmp_str;
3910 tmp = rse.loop->loopvar[n];
3911 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3912 tmp, rse.loop->from[n]);
3913 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3914 tmp, tmp_index);
3915
3916 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
3917 gfc_array_index_type,
3918 rse.loop->to[n-1], rse.loop->from[n-1]);
3919 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
3920 gfc_array_index_type,
3921 tmp_str, gfc_index_one_node);
3922
3923 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
3924 gfc_array_index_type, tmp, tmp_str);
3925 }
3926
3927 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
3928 gfc_array_index_type,
3929 tmp_index, rse.loop->from[0]);
3930 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
3931
3932 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
3933 gfc_array_index_type,
3934 rse.loop->loopvar[0], offset);
3935
3936 /* Now use the offset for the reference. */
3937 tmp = build_fold_indirect_ref_loc (input_location,
3938 info->data);
3939 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
3940
3941 if (expr->ts.type == BT_CHARACTER)
3942 rse.string_length = expr->ts.u.cl->backend_decl;
3943
3944 gfc_conv_expr (&lse, expr);
3945
3946 gcc_assert (lse.ss == gfc_ss_terminator);
3947
3948 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false, true);
3949 gfc_add_expr_to_block (&body, tmp);
3950
3951 /* Generate the copying loops. */
3952 gfc_trans_scalarizing_loops (&loop2, &body);
3953
3954 /* Wrap the whole thing up by adding the second loop to the post-block
3955 and following it by the post-block of the first loop. In this way,
3956 if the temporary needs freeing, it is done after use! */
3957 if (intent != INTENT_IN)
3958 {
3959 gfc_add_block_to_block (&parmse->post, &loop2.pre);
3960 gfc_add_block_to_block (&parmse->post, &loop2.post);
3961 }
3962
3963 gfc_add_block_to_block (&parmse->post, &loop.post);
3964
3965 gfc_cleanup_loop (&loop);
3966 gfc_cleanup_loop (&loop2);
3967
3968 /* Pass the string length to the argument expression. */
3969 if (expr->ts.type == BT_CHARACTER)
3970 parmse->string_length = expr->ts.u.cl->backend_decl;
3971
3972 /* Determine the offset for pointer formal arguments and set the
3973 lbounds to one. */
3974 if (formal_ptr)
3975 {
3976 size = gfc_index_one_node;
3977 offset = gfc_index_zero_node;
3978 for (n = 0; n < dimen; n++)
3979 {
3980 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
3981 gfc_rank_cst[n]);
3982 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3983 gfc_array_index_type, tmp,
3984 gfc_index_one_node);
3985 gfc_conv_descriptor_ubound_set (&parmse->pre,
3986 parmse->expr,
3987 gfc_rank_cst[n],
3988 tmp);
3989 gfc_conv_descriptor_lbound_set (&parmse->pre,
3990 parmse->expr,
3991 gfc_rank_cst[n],
3992 gfc_index_one_node);
3993 size = gfc_evaluate_now (size, &parmse->pre);
3994 offset = fold_build2_loc (input_location, MINUS_EXPR,
3995 gfc_array_index_type,
3996 offset, size);
3997 offset = gfc_evaluate_now (offset, &parmse->pre);
3998 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3999 gfc_array_index_type,
4000 rse.loop->to[n], rse.loop->from[n]);
4001 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4002 gfc_array_index_type,
4003 tmp, gfc_index_one_node);
4004 size = fold_build2_loc (input_location, MULT_EXPR,
4005 gfc_array_index_type, size, tmp);
4006 }
4007
4008 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
4009 offset);
4010 }
4011
4012 /* We want either the address for the data or the address of the descriptor,
4013 depending on the mode of passing array arguments. */
4014 if (g77)
4015 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
4016 else
4017 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
4018
4019 return;
4020 }
4021
4022
4023 /* Generate the code for argument list functions. */
4024
4025 static void
4026 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
4027 {
4028 /* Pass by value for g77 %VAL(arg), pass the address
4029 indirectly for %LOC, else by reference. Thus %REF
4030 is a "do-nothing" and %LOC is the same as an F95
4031 pointer. */
4032 if (strncmp (name, "%VAL", 4) == 0)
4033 gfc_conv_expr (se, expr);
4034 else if (strncmp (name, "%LOC", 4) == 0)
4035 {
4036 gfc_conv_expr_reference (se, expr);
4037 se->expr = gfc_build_addr_expr (NULL, se->expr);
4038 }
4039 else if (strncmp (name, "%REF", 4) == 0)
4040 gfc_conv_expr_reference (se, expr);
4041 else
4042 gfc_error ("Unknown argument list function at %L", &expr->where);
4043 }
4044
4045
4046 /* Generate code for a procedure call. Note can return se->post != NULL.
4047 If se->direct_byref is set then se->expr contains the return parameter.
4048 Return nonzero, if the call has alternate specifiers.
4049 'expr' is only needed for procedure pointer components. */
4050
4051 int
4052 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
4053 gfc_actual_arglist * args, gfc_expr * expr,
4054 vec<tree, va_gc> *append_args)
4055 {
4056 gfc_interface_mapping mapping;
4057 vec<tree, va_gc> *arglist;
4058 vec<tree, va_gc> *retargs;
4059 tree tmp;
4060 tree fntype;
4061 gfc_se parmse;
4062 gfc_array_info *info;
4063 int byref;
4064 int parm_kind;
4065 tree type;
4066 tree var;
4067 tree len;
4068 tree base_object;
4069 vec<tree, va_gc> *stringargs;
4070 vec<tree, va_gc> *optionalargs;
4071 tree result = NULL;
4072 gfc_formal_arglist *formal;
4073 gfc_actual_arglist *arg;
4074 int has_alternate_specifier = 0;
4075 bool need_interface_mapping;
4076 bool callee_alloc;
4077 gfc_typespec ts;
4078 gfc_charlen cl;
4079 gfc_expr *e;
4080 gfc_symbol *fsym;
4081 stmtblock_t post;
4082 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
4083 gfc_component *comp = NULL;
4084 int arglen;
4085
4086 arglist = NULL;
4087 retargs = NULL;
4088 stringargs = NULL;
4089 optionalargs = NULL;
4090 var = NULL_TREE;
4091 len = NULL_TREE;
4092 gfc_clear_ts (&ts);
4093
4094 comp = gfc_get_proc_ptr_comp (expr);
4095
4096 if (se->ss != NULL)
4097 {
4098 if (!sym->attr.elemental && !(comp && comp->attr.elemental))
4099 {
4100 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
4101 if (se->ss->info->useflags)
4102 {
4103 gcc_assert ((!comp && gfc_return_by_reference (sym)
4104 && sym->result->attr.dimension)
4105 || (comp && comp->attr.dimension));
4106 gcc_assert (se->loop != NULL);
4107
4108 /* Access the previously obtained result. */
4109 gfc_conv_tmp_array_ref (se);
4110 return 0;
4111 }
4112 }
4113 info = &se->ss->info->data.array;
4114 }
4115 else
4116 info = NULL;
4117
4118 gfc_init_block (&post);
4119 gfc_init_interface_mapping (&mapping);
4120 if (!comp)
4121 {
4122 formal = gfc_sym_get_dummy_args (sym);
4123 need_interface_mapping = sym->attr.dimension ||
4124 (sym->ts.type == BT_CHARACTER
4125 && sym->ts.u.cl->length
4126 && sym->ts.u.cl->length->expr_type
4127 != EXPR_CONSTANT);
4128 }
4129 else
4130 {
4131 formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
4132 need_interface_mapping = comp->attr.dimension ||
4133 (comp->ts.type == BT_CHARACTER
4134 && comp->ts.u.cl->length
4135 && comp->ts.u.cl->length->expr_type
4136 != EXPR_CONSTANT);
4137 }
4138
4139 base_object = NULL_TREE;
4140
4141 /* Evaluate the arguments. */
4142 for (arg = args; arg != NULL;
4143 arg = arg->next, formal = formal ? formal->next : NULL)
4144 {
4145 e = arg->expr;
4146 fsym = formal ? formal->sym : NULL;
4147 parm_kind = MISSING;
4148
4149 /* Class array expressions are sometimes coming completely unadorned
4150 with either arrayspec or _data component. Correct that here.
4151 OOP-TODO: Move this to the frontend. */
4152 if (e && e->expr_type == EXPR_VARIABLE
4153 && !e->ref
4154 && e->ts.type == BT_CLASS
4155 && (CLASS_DATA (e)->attr.codimension
4156 || CLASS_DATA (e)->attr.dimension))
4157 {
4158 gfc_typespec temp_ts = e->ts;
4159 gfc_add_class_array_ref (e);
4160 e->ts = temp_ts;
4161 }
4162
4163 if (e == NULL)
4164 {
4165 if (se->ignore_optional)
4166 {
4167 /* Some intrinsics have already been resolved to the correct
4168 parameters. */
4169 continue;
4170 }
4171 else if (arg->label)
4172 {
4173 has_alternate_specifier = 1;
4174 continue;
4175 }
4176 else
4177 {
4178 gfc_init_se (&parmse, NULL);
4179
4180 /* For scalar arguments with VALUE attribute which are passed by
4181 value, pass "0" and a hidden argument gives the optional
4182 status. */
4183 if (fsym && fsym->attr.optional && fsym->attr.value
4184 && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
4185 && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
4186 {
4187 parmse.expr = fold_convert (gfc_sym_type (fsym),
4188 integer_zero_node);
4189 vec_safe_push (optionalargs, boolean_false_node);
4190 }
4191 else
4192 {
4193 /* Pass a NULL pointer for an absent arg. */
4194 parmse.expr = null_pointer_node;
4195 if (arg->missing_arg_type == BT_CHARACTER)
4196 parmse.string_length = build_int_cst (gfc_charlen_type_node,
4197 0);
4198 }
4199 }
4200 }
4201 else if (arg->expr->expr_type == EXPR_NULL
4202 && fsym && !fsym->attr.pointer
4203 && (fsym->ts.type != BT_CLASS
4204 || !CLASS_DATA (fsym)->attr.class_pointer))
4205 {
4206 /* Pass a NULL pointer to denote an absent arg. */
4207 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
4208 && (fsym->ts.type != BT_CLASS
4209 || !CLASS_DATA (fsym)->attr.allocatable));
4210 gfc_init_se (&parmse, NULL);
4211 parmse.expr = null_pointer_node;
4212 if (arg->missing_arg_type == BT_CHARACTER)
4213 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
4214 }
4215 else if (fsym && fsym->ts.type == BT_CLASS
4216 && e->ts.type == BT_DERIVED)
4217 {
4218 /* The derived type needs to be converted to a temporary
4219 CLASS object. */
4220 gfc_init_se (&parmse, se);
4221 gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
4222 fsym->attr.optional
4223 && e->expr_type == EXPR_VARIABLE
4224 && e->symtree->n.sym->attr.optional,
4225 CLASS_DATA (fsym)->attr.class_pointer
4226 || CLASS_DATA (fsym)->attr.allocatable);
4227 }
4228 else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS)
4229 {
4230 /* The intrinsic type needs to be converted to a temporary
4231 CLASS object for the unlimited polymorphic formal. */
4232 gfc_init_se (&parmse, se);
4233 gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
4234 }
4235 else if (se->ss && se->ss->info->useflags)
4236 {
4237 gfc_ss *ss;
4238
4239 ss = se->ss;
4240
4241 /* An elemental function inside a scalarized loop. */
4242 gfc_init_se (&parmse, se);
4243 parm_kind = ELEMENTAL;
4244
4245 if (fsym && fsym->attr.value)
4246 gfc_conv_expr (&parmse, e);
4247 else
4248 gfc_conv_expr_reference (&parmse, e);
4249
4250 if (e->ts.type == BT_CHARACTER && !e->rank
4251 && e->expr_type == EXPR_FUNCTION)
4252 parmse.expr = build_fold_indirect_ref_loc (input_location,
4253 parmse.expr);
4254
4255 if (fsym && fsym->ts.type == BT_DERIVED
4256 && gfc_is_class_container_ref (e))
4257 {
4258 parmse.expr = gfc_class_data_get (parmse.expr);
4259
4260 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
4261 && e->symtree->n.sym->attr.optional)
4262 {
4263 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
4264 parmse.expr = build3_loc (input_location, COND_EXPR,
4265 TREE_TYPE (parmse.expr),
4266 cond, parmse.expr,
4267 fold_convert (TREE_TYPE (parmse.expr),
4268 null_pointer_node));
4269 }
4270 }
4271
4272 /* If we are passing an absent array as optional dummy to an
4273 elemental procedure, make sure that we pass NULL when the data
4274 pointer is NULL. We need this extra conditional because of
4275 scalarization which passes arrays elements to the procedure,
4276 ignoring the fact that the array can be absent/unallocated/... */
4277 if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
4278 {
4279 tree descriptor_data;
4280
4281 descriptor_data = ss->info->data.array.data;
4282 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
4283 descriptor_data,
4284 fold_convert (TREE_TYPE (descriptor_data),
4285 null_pointer_node));
4286 parmse.expr
4287 = fold_build3_loc (input_location, COND_EXPR,
4288 TREE_TYPE (parmse.expr),
4289 gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
4290 fold_convert (TREE_TYPE (parmse.expr),
4291 null_pointer_node),
4292 parmse.expr);
4293 }
4294
4295 /* The scalarizer does not repackage the reference to a class
4296 array - instead it returns a pointer to the data element. */
4297 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
4298 gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
4299 fsym->attr.intent != INTENT_IN
4300 && (CLASS_DATA (fsym)->attr.class_pointer
4301 || CLASS_DATA (fsym)->attr.allocatable),
4302 fsym->attr.optional
4303 && e->expr_type == EXPR_VARIABLE
4304 && e->symtree->n.sym->attr.optional,
4305 CLASS_DATA (fsym)->attr.class_pointer
4306 || CLASS_DATA (fsym)->attr.allocatable);
4307 }
4308 else
4309 {
4310 bool scalar;
4311 gfc_ss *argss;
4312
4313 gfc_init_se (&parmse, NULL);
4314
4315 /* Check whether the expression is a scalar or not; we cannot use
4316 e->rank as it can be nonzero for functions arguments. */
4317 argss = gfc_walk_expr (e);
4318 scalar = argss == gfc_ss_terminator;
4319 if (!scalar)
4320 gfc_free_ss_chain (argss);
4321
4322 /* Special handling for passing scalar polymorphic coarrays;
4323 otherwise one passes "class->_data.data" instead of "&class". */
4324 if (e->rank == 0 && e->ts.type == BT_CLASS
4325 && fsym && fsym->ts.type == BT_CLASS
4326 && CLASS_DATA (fsym)->attr.codimension
4327 && !CLASS_DATA (fsym)->attr.dimension)
4328 {
4329 gfc_add_class_array_ref (e);
4330 parmse.want_coarray = 1;
4331 scalar = false;
4332 }
4333
4334 /* A scalar or transformational function. */
4335 if (scalar)
4336 {
4337 if (e->expr_type == EXPR_VARIABLE
4338 && e->symtree->n.sym->attr.cray_pointee
4339 && fsym && fsym->attr.flavor == FL_PROCEDURE)
4340 {
4341 /* The Cray pointer needs to be converted to a pointer to
4342 a type given by the expression. */
4343 gfc_conv_expr (&parmse, e);
4344 type = build_pointer_type (TREE_TYPE (parmse.expr));
4345 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
4346 parmse.expr = convert (type, tmp);
4347 }
4348 else if (fsym && fsym->attr.value)
4349 {
4350 if (fsym->ts.type == BT_CHARACTER
4351 && fsym->ts.is_c_interop
4352 && fsym->ns->proc_name != NULL
4353 && fsym->ns->proc_name->attr.is_bind_c)
4354 {
4355 parmse.expr = NULL;
4356 gfc_conv_scalar_char_value (fsym, &parmse, &e);
4357 if (parmse.expr == NULL)
4358 gfc_conv_expr (&parmse, e);
4359 }
4360 else
4361 {
4362 gfc_conv_expr (&parmse, e);
4363 if (fsym->attr.optional
4364 && fsym->ts.type != BT_CLASS
4365 && fsym->ts.type != BT_DERIVED)
4366 {
4367 if (e->expr_type != EXPR_VARIABLE
4368 || !e->symtree->n.sym->attr.optional
4369 || e->ref != NULL)
4370 vec_safe_push (optionalargs, boolean_true_node);
4371 else
4372 {
4373 tmp = gfc_conv_expr_present (e->symtree->n.sym);
4374 if (!e->symtree->n.sym->attr.value)
4375 parmse.expr
4376 = fold_build3_loc (input_location, COND_EXPR,
4377 TREE_TYPE (parmse.expr),
4378 tmp, parmse.expr,
4379 fold_convert (TREE_TYPE (parmse.expr),
4380 integer_zero_node));
4381
4382 vec_safe_push (optionalargs, tmp);
4383 }
4384 }
4385 }
4386 }
4387 else if (arg->name && arg->name[0] == '%')
4388 /* Argument list functions %VAL, %LOC and %REF are signalled
4389 through arg->name. */
4390 conv_arglist_function (&parmse, arg->expr, arg->name);
4391 else if ((e->expr_type == EXPR_FUNCTION)
4392 && ((e->value.function.esym
4393 && e->value.function.esym->result->attr.pointer)
4394 || (!e->value.function.esym
4395 && e->symtree->n.sym->attr.pointer))
4396 && fsym && fsym->attr.target)
4397 {
4398 gfc_conv_expr (&parmse, e);
4399 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
4400 }
4401 else if (e->expr_type == EXPR_FUNCTION
4402 && e->symtree->n.sym->result
4403 && e->symtree->n.sym->result != e->symtree->n.sym
4404 && e->symtree->n.sym->result->attr.proc_pointer)
4405 {
4406 /* Functions returning procedure pointers. */
4407 gfc_conv_expr (&parmse, e);
4408 if (fsym && fsym->attr.proc_pointer)
4409 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
4410 }
4411 else
4412 {
4413 if (e->ts.type == BT_CLASS && fsym
4414 && fsym->ts.type == BT_CLASS
4415 && (!CLASS_DATA (fsym)->as
4416 || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
4417 && CLASS_DATA (e)->attr.codimension)
4418 {
4419 gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
4420 gcc_assert (!CLASS_DATA (fsym)->as);
4421 gfc_add_class_array_ref (e);
4422 parmse.want_coarray = 1;
4423 gfc_conv_expr_reference (&parmse, e);
4424 class_scalar_coarray_to_class (&parmse, e, fsym->ts,
4425 fsym->attr.optional
4426 && e->expr_type == EXPR_VARIABLE);
4427 }
4428 else
4429 gfc_conv_expr_reference (&parmse, e);
4430
4431 /* Catch base objects that are not variables. */
4432 if (e->ts.type == BT_CLASS
4433 && e->expr_type != EXPR_VARIABLE
4434 && expr && e == expr->base_expr)
4435 base_object = build_fold_indirect_ref_loc (input_location,
4436 parmse.expr);
4437
4438 /* A class array element needs converting back to be a
4439 class object, if the formal argument is a class object. */
4440 if (fsym && fsym->ts.type == BT_CLASS
4441 && e->ts.type == BT_CLASS
4442 && ((CLASS_DATA (fsym)->as
4443 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
4444 || CLASS_DATA (e)->attr.dimension))
4445 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
4446 fsym->attr.intent != INTENT_IN
4447 && (CLASS_DATA (fsym)->attr.class_pointer
4448 || CLASS_DATA (fsym)->attr.allocatable),
4449 fsym->attr.optional
4450 && e->expr_type == EXPR_VARIABLE
4451 && e->symtree->n.sym->attr.optional,
4452 CLASS_DATA (fsym)->attr.class_pointer
4453 || CLASS_DATA (fsym)->attr.allocatable);
4454
4455 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
4456 allocated on entry, it must be deallocated. */
4457 if (fsym && fsym->attr.intent == INTENT_OUT
4458 && (fsym->attr.allocatable
4459 || (fsym->ts.type == BT_CLASS
4460 && CLASS_DATA (fsym)->attr.allocatable)))
4461 {
4462 stmtblock_t block;
4463 tree ptr;
4464
4465 gfc_init_block (&block);
4466 ptr = parmse.expr;
4467 if (e->ts.type == BT_CLASS)
4468 ptr = gfc_class_data_get (ptr);
4469
4470 tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
4471 true, e, e->ts);
4472 gfc_add_expr_to_block (&block, tmp);
4473 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4474 void_type_node, ptr,
4475 null_pointer_node);
4476 gfc_add_expr_to_block (&block, tmp);
4477
4478 if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
4479 {
4480 gfc_add_modify (&block, ptr,
4481 fold_convert (TREE_TYPE (ptr),
4482 null_pointer_node));
4483 gfc_add_expr_to_block (&block, tmp);
4484 }
4485 else if (fsym->ts.type == BT_CLASS)
4486 {
4487 gfc_symbol *vtab;
4488 vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
4489 tmp = gfc_get_symbol_decl (vtab);
4490 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4491 ptr = gfc_class_vptr_get (parmse.expr);
4492 gfc_add_modify (&block, ptr,
4493 fold_convert (TREE_TYPE (ptr), tmp));
4494 gfc_add_expr_to_block (&block, tmp);
4495 }
4496
4497 if (fsym->attr.optional
4498 && e->expr_type == EXPR_VARIABLE
4499 && e->symtree->n.sym->attr.optional)
4500 {
4501 tmp = fold_build3_loc (input_location, COND_EXPR,
4502 void_type_node,
4503 gfc_conv_expr_present (e->symtree->n.sym),
4504 gfc_finish_block (&block),
4505 build_empty_stmt (input_location));
4506 }
4507 else
4508 tmp = gfc_finish_block (&block);
4509
4510 gfc_add_expr_to_block (&se->pre, tmp);
4511 }
4512
4513 if (fsym && (fsym->ts.type == BT_DERIVED
4514 || fsym->ts.type == BT_ASSUMED)
4515 && e->ts.type == BT_CLASS
4516 && !CLASS_DATA (e)->attr.dimension
4517 && !CLASS_DATA (e)->attr.codimension)
4518 parmse.expr = gfc_class_data_get (parmse.expr);
4519
4520 /* Wrap scalar variable in a descriptor. We need to convert
4521 the address of a pointer back to the pointer itself before,
4522 we can assign it to the data field. */
4523
4524 if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
4525 && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
4526 {
4527 tmp = parmse.expr;
4528 if (TREE_CODE (tmp) == ADDR_EXPR
4529 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp, 0))))
4530 tmp = TREE_OPERAND (tmp, 0);
4531 parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
4532 fsym->attr);
4533 parmse.expr = gfc_build_addr_expr (NULL_TREE,
4534 parmse.expr);
4535 }
4536 else if (fsym && e->expr_type != EXPR_NULL
4537 && ((fsym->attr.pointer
4538 && fsym->attr.flavor != FL_PROCEDURE)
4539 || (fsym->attr.proc_pointer
4540 && !(e->expr_type == EXPR_VARIABLE
4541 && e->symtree->n.sym->attr.dummy))
4542 || (fsym->attr.proc_pointer
4543 && e->expr_type == EXPR_VARIABLE
4544 && gfc_is_proc_ptr_comp (e))
4545 || (fsym->attr.allocatable
4546 && fsym->attr.flavor != FL_PROCEDURE)))
4547 {
4548 /* Scalar pointer dummy args require an extra level of
4549 indirection. The null pointer already contains
4550 this level of indirection. */
4551 parm_kind = SCALAR_POINTER;
4552 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
4553 }
4554 }
4555 }
4556 else if (e->ts.type == BT_CLASS
4557 && fsym && fsym->ts.type == BT_CLASS
4558 && (CLASS_DATA (fsym)->attr.dimension
4559 || CLASS_DATA (fsym)->attr.codimension))
4560 {
4561 /* Pass a class array. */
4562 parmse.use_offset = 1;
4563 gfc_conv_expr_descriptor (&parmse, e);
4564
4565 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
4566 allocated on entry, it must be deallocated. */
4567 if (fsym->attr.intent == INTENT_OUT
4568 && CLASS_DATA (fsym)->attr.allocatable)
4569 {
4570 stmtblock_t block;
4571 tree ptr;
4572
4573 gfc_init_block (&block);
4574 ptr = parmse.expr;
4575 ptr = gfc_class_data_get (ptr);
4576
4577 tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
4578 NULL_TREE, NULL_TREE,
4579 NULL_TREE, true, e,
4580 false);
4581 gfc_add_expr_to_block (&block, tmp);
4582 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4583 void_type_node, ptr,
4584 null_pointer_node);
4585 gfc_add_expr_to_block (&block, tmp);
4586 gfc_reset_vptr (&block, e);
4587
4588 if (fsym->attr.optional
4589 && e->expr_type == EXPR_VARIABLE
4590 && (!e->ref
4591 || (e->ref->type == REF_ARRAY
4592 && e->ref->u.ar.type != AR_FULL))
4593 && e->symtree->n.sym->attr.optional)
4594 {
4595 tmp = fold_build3_loc (input_location, COND_EXPR,
4596 void_type_node,
4597 gfc_conv_expr_present (e->symtree->n.sym),
4598 gfc_finish_block (&block),
4599 build_empty_stmt (input_location));
4600 }
4601 else
4602 tmp = gfc_finish_block (&block);
4603
4604 gfc_add_expr_to_block (&se->pre, tmp);
4605 }
4606
4607 /* The conversion does not repackage the reference to a class
4608 array - _data descriptor. */
4609 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
4610 fsym->attr.intent != INTENT_IN
4611 && (CLASS_DATA (fsym)->attr.class_pointer
4612 || CLASS_DATA (fsym)->attr.allocatable),
4613 fsym->attr.optional
4614 && e->expr_type == EXPR_VARIABLE
4615 && e->symtree->n.sym->attr.optional,
4616 CLASS_DATA (fsym)->attr.class_pointer
4617 || CLASS_DATA (fsym)->attr.allocatable);
4618 }
4619 else
4620 {
4621 /* If the procedure requires an explicit interface, the actual
4622 argument is passed according to the corresponding formal
4623 argument. If the corresponding formal argument is a POINTER,
4624 ALLOCATABLE or assumed shape, we do not use g77's calling
4625 convention, and pass the address of the array descriptor
4626 instead. Otherwise we use g77's calling convention. */
4627 bool f;
4628 f = (fsym != NULL)
4629 && !(fsym->attr.pointer || fsym->attr.allocatable)
4630 && fsym->as && fsym->as->type != AS_ASSUMED_SHAPE
4631 && fsym->as->type != AS_ASSUMED_RANK;
4632 if (comp)
4633 f = f || !comp->attr.always_explicit;
4634 else
4635 f = f || !sym->attr.always_explicit;
4636
4637 /* If the argument is a function call that may not create
4638 a temporary for the result, we have to check that we
4639 can do it, i.e. that there is no alias between this
4640 argument and another one. */
4641 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
4642 {
4643 gfc_expr *iarg;
4644 sym_intent intent;
4645
4646 if (fsym != NULL)
4647 intent = fsym->attr.intent;
4648 else
4649 intent = INTENT_UNKNOWN;
4650
4651 if (gfc_check_fncall_dependency (e, intent, sym, args,
4652 NOT_ELEMENTAL))
4653 parmse.force_tmp = 1;
4654
4655 iarg = e->value.function.actual->expr;
4656
4657 /* Temporary needed if aliasing due to host association. */
4658 if (sym->attr.contained
4659 && !sym->attr.pure
4660 && !sym->attr.implicit_pure
4661 && !sym->attr.use_assoc
4662 && iarg->expr_type == EXPR_VARIABLE
4663 && sym->ns == iarg->symtree->n.sym->ns)
4664 parmse.force_tmp = 1;
4665
4666 /* Ditto within module. */
4667 if (sym->attr.use_assoc
4668 && !sym->attr.pure
4669 && !sym->attr.implicit_pure
4670 && iarg->expr_type == EXPR_VARIABLE
4671 && sym->module == iarg->symtree->n.sym->module)
4672 parmse.force_tmp = 1;
4673 }
4674
4675 if (e->expr_type == EXPR_VARIABLE
4676 && is_subref_array (e))
4677 /* The actual argument is a component reference to an
4678 array of derived types. In this case, the argument
4679 is converted to a temporary, which is passed and then
4680 written back after the procedure call. */
4681 gfc_conv_subref_array_arg (&parmse, e, f,
4682 fsym ? fsym->attr.intent : INTENT_INOUT,
4683 fsym && fsym->attr.pointer);
4684 else if (gfc_is_class_array_ref (e, NULL)
4685 && fsym && fsym->ts.type == BT_DERIVED)
4686 /* The actual argument is a component reference to an
4687 array of derived types. In this case, the argument
4688 is converted to a temporary, which is passed and then
4689 written back after the procedure call.
4690 OOP-TODO: Insert code so that if the dynamic type is
4691 the same as the declared type, copy-in/copy-out does
4692 not occur. */
4693 gfc_conv_subref_array_arg (&parmse, e, f,
4694 fsym ? fsym->attr.intent : INTENT_INOUT,
4695 fsym && fsym->attr.pointer);
4696 else
4697 gfc_conv_array_parameter (&parmse, e, f, fsym, sym->name, NULL);
4698
4699 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
4700 allocated on entry, it must be deallocated. */
4701 if (fsym && fsym->attr.allocatable
4702 && fsym->attr.intent == INTENT_OUT)
4703 {
4704 tmp = build_fold_indirect_ref_loc (input_location,
4705 parmse.expr);
4706 tmp = gfc_trans_dealloc_allocated (tmp, false, e);
4707 if (fsym->attr.optional
4708 && e->expr_type == EXPR_VARIABLE
4709 && e->symtree->n.sym->attr.optional)
4710 tmp = fold_build3_loc (input_location, COND_EXPR,
4711 void_type_node,
4712 gfc_conv_expr_present (e->symtree->n.sym),
4713 tmp, build_empty_stmt (input_location));
4714 gfc_add_expr_to_block (&se->pre, tmp);
4715 }
4716 }
4717 }
4718
4719 /* The case with fsym->attr.optional is that of a user subroutine
4720 with an interface indicating an optional argument. When we call
4721 an intrinsic subroutine, however, fsym is NULL, but we might still
4722 have an optional argument, so we proceed to the substitution
4723 just in case. */
4724 if (e && (fsym == NULL || fsym->attr.optional))
4725 {
4726 /* If an optional argument is itself an optional dummy argument,
4727 check its presence and substitute a null if absent. This is
4728 only needed when passing an array to an elemental procedure
4729 as then array elements are accessed - or no NULL pointer is
4730 allowed and a "1" or "0" should be passed if not present.
4731 When passing a non-array-descriptor full array to a
4732 non-array-descriptor dummy, no check is needed. For
4733 array-descriptor actual to array-descriptor dummy, see
4734 PR 41911 for why a check has to be inserted.
4735 fsym == NULL is checked as intrinsics required the descriptor
4736 but do not always set fsym. */
4737 if (e->expr_type == EXPR_VARIABLE
4738 && e->symtree->n.sym->attr.optional
4739 && ((e->rank != 0 && sym->attr.elemental)
4740 || e->representation.length || e->ts.type == BT_CHARACTER
4741 || (e->rank != 0
4742 && (fsym == NULL
4743 || (fsym-> as
4744 && (fsym->as->type == AS_ASSUMED_SHAPE
4745 || fsym->as->type == AS_ASSUMED_RANK
4746 || fsym->as->type == AS_DEFERRED))))))
4747 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
4748 e->representation.length);
4749 }
4750
4751 if (fsym && e)
4752 {
4753 /* Obtain the character length of an assumed character length
4754 length procedure from the typespec. */
4755 if (fsym->ts.type == BT_CHARACTER
4756 && parmse.string_length == NULL_TREE
4757 && e->ts.type == BT_PROCEDURE
4758 && e->symtree->n.sym->ts.type == BT_CHARACTER
4759 && e->symtree->n.sym->ts.u.cl->length != NULL
4760 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
4761 {
4762 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
4763 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
4764 }
4765 }
4766
4767 if (fsym && need_interface_mapping && e)
4768 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
4769
4770 gfc_add_block_to_block (&se->pre, &parmse.pre);
4771 gfc_add_block_to_block (&post, &parmse.post);
4772
4773 /* Allocated allocatable components of derived types must be
4774 deallocated for non-variable scalars. Non-variable arrays are
4775 dealt with in trans-array.c(gfc_conv_array_parameter). */
4776 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
4777 && e->ts.u.derived->attr.alloc_comp
4778 && !(e->symtree && e->symtree->n.sym->attr.pointer)
4779 && (e->expr_type != EXPR_VARIABLE && !e->rank))
4780 {
4781 int parm_rank;
4782 tmp = build_fold_indirect_ref_loc (input_location,
4783 parmse.expr);
4784 parm_rank = e->rank;
4785 switch (parm_kind)
4786 {
4787 case (ELEMENTAL):
4788 case (SCALAR):
4789 parm_rank = 0;
4790 break;
4791
4792 case (SCALAR_POINTER):
4793 tmp = build_fold_indirect_ref_loc (input_location,
4794 tmp);
4795 break;
4796 }
4797
4798 if (e->expr_type == EXPR_OP
4799 && e->value.op.op == INTRINSIC_PARENTHESES
4800 && e->value.op.op1->expr_type == EXPR_VARIABLE)
4801 {
4802 tree local_tmp;
4803 local_tmp = gfc_evaluate_now (tmp, &se->pre);
4804 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
4805 gfc_add_expr_to_block (&se->post, local_tmp);
4806 }
4807
4808 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
4809 {
4810 /* The derived type is passed to gfc_deallocate_alloc_comp.
4811 Therefore, class actuals can handled correctly but derived
4812 types passed to class formals need the _data component. */
4813 tmp = gfc_class_data_get (tmp);
4814 if (!CLASS_DATA (fsym)->attr.dimension)
4815 tmp = build_fold_indirect_ref_loc (input_location, tmp);
4816 }
4817
4818 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
4819
4820 gfc_add_expr_to_block (&se->post, tmp);
4821 }
4822
4823 /* Add argument checking of passing an unallocated/NULL actual to
4824 a nonallocatable/nonpointer dummy. */
4825
4826 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
4827 {
4828 symbol_attribute attr;
4829 char *msg;
4830 tree cond;
4831
4832 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
4833 attr = gfc_expr_attr (e);
4834 else
4835 goto end_pointer_check;
4836
4837 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
4838 allocatable to an optional dummy, cf. 12.5.2.12. */
4839 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
4840 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
4841 goto end_pointer_check;
4842
4843 if (attr.optional)
4844 {
4845 /* If the actual argument is an optional pointer/allocatable and
4846 the formal argument takes an nonpointer optional value,
4847 it is invalid to pass a non-present argument on, even
4848 though there is no technical reason for this in gfortran.
4849 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
4850 tree present, null_ptr, type;
4851
4852 if (attr.allocatable
4853 && (fsym == NULL || !fsym->attr.allocatable))
4854 asprintf (&msg, "Allocatable actual argument '%s' is not "
4855 "allocated or not present", e->symtree->n.sym->name);
4856 else if (attr.pointer
4857 && (fsym == NULL || !fsym->attr.pointer))
4858 asprintf (&msg, "Pointer actual argument '%s' is not "
4859 "associated or not present",
4860 e->symtree->n.sym->name);
4861 else if (attr.proc_pointer
4862 && (fsym == NULL || !fsym->attr.proc_pointer))
4863 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
4864 "associated or not present",
4865 e->symtree->n.sym->name);
4866 else
4867 goto end_pointer_check;
4868
4869 present = gfc_conv_expr_present (e->symtree->n.sym);
4870 type = TREE_TYPE (present);
4871 present = fold_build2_loc (input_location, EQ_EXPR,
4872 boolean_type_node, present,
4873 fold_convert (type,
4874 null_pointer_node));
4875 type = TREE_TYPE (parmse.expr);
4876 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
4877 boolean_type_node, parmse.expr,
4878 fold_convert (type,
4879 null_pointer_node));
4880 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
4881 boolean_type_node, present, null_ptr);
4882 }
4883 else
4884 {
4885 if (attr.allocatable
4886 && (fsym == NULL || !fsym->attr.allocatable))
4887 asprintf (&msg, "Allocatable actual argument '%s' is not "
4888 "allocated", e->symtree->n.sym->name);
4889 else if (attr.pointer
4890 && (fsym == NULL || !fsym->attr.pointer))
4891 asprintf (&msg, "Pointer actual argument '%s' is not "
4892 "associated", e->symtree->n.sym->name);
4893 else if (attr.proc_pointer
4894 && (fsym == NULL || !fsym->attr.proc_pointer))
4895 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
4896 "associated", e->symtree->n.sym->name);
4897 else
4898 goto end_pointer_check;
4899
4900 tmp = parmse.expr;
4901
4902 /* If the argument is passed by value, we need to strip the
4903 INDIRECT_REF. */
4904 if (!POINTER_TYPE_P (TREE_TYPE (parmse.expr)))
4905 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4906
4907 cond = fold_build2_loc (input_location, EQ_EXPR,
4908 boolean_type_node, tmp,
4909 fold_convert (TREE_TYPE (tmp),
4910 null_pointer_node));
4911 }
4912
4913 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
4914 msg);
4915 free (msg);
4916 }
4917 end_pointer_check:
4918
4919 /* Deferred length dummies pass the character length by reference
4920 so that the value can be returned. */
4921 if (parmse.string_length && fsym && fsym->ts.deferred)
4922 {
4923 tmp = parmse.string_length;
4924 if (TREE_CODE (tmp) != VAR_DECL)
4925 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
4926 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
4927 }
4928
4929 /* Character strings are passed as two parameters, a length and a
4930 pointer - except for Bind(c) which only passes the pointer.
4931 An unlimited polymorphic formal argument likewise does not
4932 need the length. */
4933 if (parmse.string_length != NULL_TREE
4934 && !sym->attr.is_bind_c
4935 && !(fsym && UNLIMITED_POLY (fsym)))
4936 vec_safe_push (stringargs, parmse.string_length);
4937
4938 /* When calling __copy for character expressions to unlimited
4939 polymorphic entities, the dst argument needs a string length. */
4940 if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
4941 && strncmp (sym->name, "__vtab_CHARACTER", 16) == 0
4942 && arg->next && arg->next->expr
4943 && arg->next->expr->ts.type == BT_DERIVED
4944 && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
4945 vec_safe_push (stringargs, parmse.string_length);
4946
4947 /* For descriptorless coarrays and assumed-shape coarray dummies, we
4948 pass the token and the offset as additional arguments. */
4949 if (fsym && e == NULL && gfc_option.coarray == GFC_FCOARRAY_LIB
4950 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
4951 && !fsym->attr.allocatable)
4952 || (fsym->ts.type == BT_CLASS
4953 && CLASS_DATA (fsym)->attr.codimension
4954 && !CLASS_DATA (fsym)->attr.allocatable)))
4955 {
4956 /* Token and offset. */
4957 vec_safe_push (stringargs, null_pointer_node);
4958 vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
4959 gcc_assert (fsym->attr.optional);
4960 }
4961 else if (fsym && gfc_option.coarray == GFC_FCOARRAY_LIB
4962 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
4963 && !fsym->attr.allocatable)
4964 || (fsym->ts.type == BT_CLASS
4965 && CLASS_DATA (fsym)->attr.codimension
4966 && !CLASS_DATA (fsym)->attr.allocatable)))
4967 {
4968 tree caf_decl, caf_type;
4969 tree offset, tmp2;
4970
4971 caf_decl = gfc_get_tree_for_caf_expr (e);
4972 caf_type = TREE_TYPE (caf_decl);
4973
4974 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
4975 && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
4976 || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
4977 tmp = gfc_conv_descriptor_token (caf_decl);
4978 else if (DECL_LANG_SPECIFIC (caf_decl)
4979 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
4980 tmp = GFC_DECL_TOKEN (caf_decl);
4981 else
4982 {
4983 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
4984 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
4985 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
4986 }
4987
4988 vec_safe_push (stringargs, tmp);
4989
4990 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
4991 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
4992 offset = build_int_cst (gfc_array_index_type, 0);
4993 else if (DECL_LANG_SPECIFIC (caf_decl)
4994 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
4995 offset = GFC_DECL_CAF_OFFSET (caf_decl);
4996 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
4997 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
4998 else
4999 offset = build_int_cst (gfc_array_index_type, 0);
5000
5001 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
5002 tmp = gfc_conv_descriptor_data_get (caf_decl);
5003 else
5004 {
5005 gcc_assert (POINTER_TYPE_P (caf_type));
5006 tmp = caf_decl;
5007 }
5008
5009 tmp2 = fsym->ts.type == BT_CLASS
5010 ? gfc_class_data_get (parmse.expr) : parmse.expr;
5011 if ((fsym->ts.type != BT_CLASS
5012 && (fsym->as->type == AS_ASSUMED_SHAPE
5013 || fsym->as->type == AS_ASSUMED_RANK))
5014 || (fsym->ts.type == BT_CLASS
5015 && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
5016 || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
5017 {
5018 if (fsym->ts.type == BT_CLASS)
5019 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
5020 else
5021 {
5022 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
5023 tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
5024 }
5025 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
5026 tmp2 = gfc_conv_descriptor_data_get (tmp2);
5027 }
5028 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
5029 tmp2 = gfc_conv_descriptor_data_get (tmp2);
5030 else
5031 {
5032 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
5033 }
5034
5035 tmp = fold_build2_loc (input_location, MINUS_EXPR,
5036 gfc_array_index_type,
5037 fold_convert (gfc_array_index_type, tmp2),
5038 fold_convert (gfc_array_index_type, tmp));
5039 offset = fold_build2_loc (input_location, PLUS_EXPR,
5040 gfc_array_index_type, offset, tmp);
5041
5042 vec_safe_push (stringargs, offset);
5043 }
5044
5045 vec_safe_push (arglist, parmse.expr);
5046 }
5047 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
5048
5049 if (comp)
5050 ts = comp->ts;
5051 else
5052 ts = sym->ts;
5053
5054 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
5055 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
5056 else if (ts.type == BT_CHARACTER)
5057 {
5058 if (ts.u.cl->length == NULL)
5059 {
5060 /* Assumed character length results are not allowed by 5.1.1.5 of the
5061 standard and are trapped in resolve.c; except in the case of SPREAD
5062 (and other intrinsics?) and dummy functions. In the case of SPREAD,
5063 we take the character length of the first argument for the result.
5064 For dummies, we have to look through the formal argument list for
5065 this function and use the character length found there.*/
5066 if (ts.deferred)
5067 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
5068 else if (!sym->attr.dummy)
5069 cl.backend_decl = (*stringargs)[0];
5070 else
5071 {
5072 formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
5073 for (; formal; formal = formal->next)
5074 if (strcmp (formal->sym->name, sym->name) == 0)
5075 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
5076 }
5077 len = cl.backend_decl;
5078 }
5079 else
5080 {
5081 tree tmp;
5082
5083 /* Calculate the length of the returned string. */
5084 gfc_init_se (&parmse, NULL);
5085 if (need_interface_mapping)
5086 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
5087 else
5088 gfc_conv_expr (&parmse, ts.u.cl->length);
5089 gfc_add_block_to_block (&se->pre, &parmse.pre);
5090 gfc_add_block_to_block (&se->post, &parmse.post);
5091
5092 tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
5093 tmp = fold_build2_loc (input_location, MAX_EXPR,
5094 gfc_charlen_type_node, tmp,
5095 build_int_cst (gfc_charlen_type_node, 0));
5096 cl.backend_decl = tmp;
5097 }
5098
5099 /* Set up a charlen structure for it. */
5100 cl.next = NULL;
5101 cl.length = NULL;
5102 ts.u.cl = &cl;
5103
5104 len = cl.backend_decl;
5105 }
5106
5107 byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
5108 || (!comp && gfc_return_by_reference (sym));
5109 if (byref)
5110 {
5111 if (se->direct_byref)
5112 {
5113 /* Sometimes, too much indirection can be applied; e.g. for
5114 function_result = array_valued_recursive_function. */
5115 if (TREE_TYPE (TREE_TYPE (se->expr))
5116 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
5117 && GFC_DESCRIPTOR_TYPE_P
5118 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
5119 se->expr = build_fold_indirect_ref_loc (input_location,
5120 se->expr);
5121
5122 /* If the lhs of an assignment x = f(..) is allocatable and
5123 f2003 is allowed, we must do the automatic reallocation.
5124 TODO - deal with intrinsics, without using a temporary. */
5125 if (gfc_option.flag_realloc_lhs
5126 && se->ss && se->ss->loop_chain
5127 && se->ss->loop_chain->is_alloc_lhs
5128 && !expr->value.function.isym
5129 && sym->result->as != NULL)
5130 {
5131 /* Evaluate the bounds of the result, if known. */
5132 gfc_set_loop_bounds_from_array_spec (&mapping, se,
5133 sym->result->as);
5134
5135 /* Perform the automatic reallocation. */
5136 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
5137 expr, NULL);
5138 gfc_add_expr_to_block (&se->pre, tmp);
5139
5140 /* Pass the temporary as the first argument. */
5141 result = info->descriptor;
5142 }
5143 else
5144 result = build_fold_indirect_ref_loc (input_location,
5145 se->expr);
5146 vec_safe_push (retargs, se->expr);
5147 }
5148 else if (comp && comp->attr.dimension)
5149 {
5150 gcc_assert (se->loop && info);
5151
5152 /* Set the type of the array. */
5153 tmp = gfc_typenode_for_spec (&comp->ts);
5154 gcc_assert (se->ss->dimen == se->loop->dimen);
5155
5156 /* Evaluate the bounds of the result, if known. */
5157 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
5158
5159 /* If the lhs of an assignment x = f(..) is allocatable and
5160 f2003 is allowed, we must not generate the function call
5161 here but should just send back the results of the mapping.
5162 This is signalled by the function ss being flagged. */
5163 if (gfc_option.flag_realloc_lhs
5164 && se->ss && se->ss->is_alloc_lhs)
5165 {
5166 gfc_free_interface_mapping (&mapping);
5167 return has_alternate_specifier;
5168 }
5169
5170 /* Create a temporary to store the result. In case the function
5171 returns a pointer, the temporary will be a shallow copy and
5172 mustn't be deallocated. */
5173 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
5174 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
5175 tmp, NULL_TREE, false,
5176 !comp->attr.pointer, callee_alloc,
5177 &se->ss->info->expr->where);
5178
5179 /* Pass the temporary as the first argument. */
5180 result = info->descriptor;
5181 tmp = gfc_build_addr_expr (NULL_TREE, result);
5182 vec_safe_push (retargs, tmp);
5183 }
5184 else if (!comp && sym->result->attr.dimension)
5185 {
5186 gcc_assert (se->loop && info);
5187
5188 /* Set the type of the array. */
5189 tmp = gfc_typenode_for_spec (&ts);
5190 gcc_assert (se->ss->dimen == se->loop->dimen);
5191
5192 /* Evaluate the bounds of the result, if known. */
5193 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
5194
5195 /* If the lhs of an assignment x = f(..) is allocatable and
5196 f2003 is allowed, we must not generate the function call
5197 here but should just send back the results of the mapping.
5198 This is signalled by the function ss being flagged. */
5199 if (gfc_option.flag_realloc_lhs
5200 && se->ss && se->ss->is_alloc_lhs)
5201 {
5202 gfc_free_interface_mapping (&mapping);
5203 return has_alternate_specifier;
5204 }
5205
5206 /* Create a temporary to store the result. In case the function
5207 returns a pointer, the temporary will be a shallow copy and
5208 mustn't be deallocated. */
5209 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
5210 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
5211 tmp, NULL_TREE, false,
5212 !sym->attr.pointer, callee_alloc,
5213 &se->ss->info->expr->where);
5214
5215 /* Pass the temporary as the first argument. */
5216 result = info->descriptor;
5217 tmp = gfc_build_addr_expr (NULL_TREE, result);
5218 vec_safe_push (retargs, tmp);
5219 }
5220 else if (ts.type == BT_CHARACTER)
5221 {
5222 /* Pass the string length. */
5223 type = gfc_get_character_type (ts.kind, ts.u.cl);
5224 type = build_pointer_type (type);
5225
5226 /* Return an address to a char[0:len-1]* temporary for
5227 character pointers. */
5228 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
5229 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
5230 {
5231 var = gfc_create_var (type, "pstr");
5232
5233 if ((!comp && sym->attr.allocatable)
5234 || (comp && comp->attr.allocatable))
5235 {
5236 gfc_add_modify (&se->pre, var,
5237 fold_convert (TREE_TYPE (var),
5238 null_pointer_node));
5239 tmp = gfc_call_free (convert (pvoid_type_node, var));
5240 gfc_add_expr_to_block (&se->post, tmp);
5241 }
5242
5243 /* Provide an address expression for the function arguments. */
5244 var = gfc_build_addr_expr (NULL_TREE, var);
5245 }
5246 else
5247 var = gfc_conv_string_tmp (se, type, len);
5248
5249 vec_safe_push (retargs, var);
5250 }
5251 else
5252 {
5253 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
5254
5255 type = gfc_get_complex_type (ts.kind);
5256 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
5257 vec_safe_push (retargs, var);
5258 }
5259
5260 /* Add the string length to the argument list. */
5261 if (ts.type == BT_CHARACTER && ts.deferred)
5262 {
5263 tmp = len;
5264 if (TREE_CODE (tmp) != VAR_DECL)
5265 tmp = gfc_evaluate_now (len, &se->pre);
5266 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
5267 vec_safe_push (retargs, tmp);
5268 }
5269 else if (ts.type == BT_CHARACTER)
5270 vec_safe_push (retargs, len);
5271 }
5272 gfc_free_interface_mapping (&mapping);
5273
5274 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
5275 arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
5276 + vec_safe_length (stringargs) + vec_safe_length (append_args));
5277 vec_safe_reserve (retargs, arglen);
5278
5279 /* Add the return arguments. */
5280 retargs->splice (arglist);
5281
5282 /* Add the hidden present status for optional+value to the arguments. */
5283 retargs->splice (optionalargs);
5284
5285 /* Add the hidden string length parameters to the arguments. */
5286 retargs->splice (stringargs);
5287
5288 /* We may want to append extra arguments here. This is used e.g. for
5289 calls to libgfortran_matmul_??, which need extra information. */
5290 if (!vec_safe_is_empty (append_args))
5291 retargs->splice (append_args);
5292 arglist = retargs;
5293
5294 /* Generate the actual call. */
5295 if (base_object == NULL_TREE)
5296 conv_function_val (se, sym, expr);
5297 else
5298 conv_base_obj_fcn_val (se, base_object, expr);
5299
5300 /* If there are alternate return labels, function type should be
5301 integer. Can't modify the type in place though, since it can be shared
5302 with other functions. For dummy arguments, the typing is done to
5303 this result, even if it has to be repeated for each call. */
5304 if (has_alternate_specifier
5305 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
5306 {
5307 if (!sym->attr.dummy)
5308 {
5309 TREE_TYPE (sym->backend_decl)
5310 = build_function_type (integer_type_node,
5311 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
5312 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
5313 }
5314 else
5315 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
5316 }
5317
5318 fntype = TREE_TYPE (TREE_TYPE (se->expr));
5319 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
5320
5321 /* If we have a pointer function, but we don't want a pointer, e.g.
5322 something like
5323 x = f()
5324 where f is pointer valued, we have to dereference the result. */
5325 if (!se->want_pointer && !byref
5326 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
5327 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
5328 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
5329
5330 /* f2c calling conventions require a scalar default real function to
5331 return a double precision result. Convert this back to default
5332 real. We only care about the cases that can happen in Fortran 77.
5333 */
5334 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
5335 && sym->ts.kind == gfc_default_real_kind
5336 && !sym->attr.always_explicit)
5337 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
5338
5339 /* A pure function may still have side-effects - it may modify its
5340 parameters. */
5341 TREE_SIDE_EFFECTS (se->expr) = 1;
5342 #if 0
5343 if (!sym->attr.pure)
5344 TREE_SIDE_EFFECTS (se->expr) = 1;
5345 #endif
5346
5347 if (byref)
5348 {
5349 /* Add the function call to the pre chain. There is no expression. */
5350 gfc_add_expr_to_block (&se->pre, se->expr);
5351 se->expr = NULL_TREE;
5352
5353 if (!se->direct_byref)
5354 {
5355 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
5356 {
5357 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
5358 {
5359 /* Check the data pointer hasn't been modified. This would
5360 happen in a function returning a pointer. */
5361 tmp = gfc_conv_descriptor_data_get (info->descriptor);
5362 tmp = fold_build2_loc (input_location, NE_EXPR,
5363 boolean_type_node,
5364 tmp, info->data);
5365 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
5366 gfc_msg_fault);
5367 }
5368 se->expr = info->descriptor;
5369 /* Bundle in the string length. */
5370 se->string_length = len;
5371 }
5372 else if (ts.type == BT_CHARACTER)
5373 {
5374 /* Dereference for character pointer results. */
5375 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
5376 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
5377 se->expr = build_fold_indirect_ref_loc (input_location, var);
5378 else
5379 se->expr = var;
5380
5381 se->string_length = len;
5382 }
5383 else
5384 {
5385 gcc_assert (ts.type == BT_COMPLEX && gfc_option.flag_f2c);
5386 se->expr = build_fold_indirect_ref_loc (input_location, var);
5387 }
5388 }
5389 }
5390
5391 /* Follow the function call with the argument post block. */
5392 if (byref)
5393 {
5394 gfc_add_block_to_block (&se->pre, &post);
5395
5396 /* Transformational functions of derived types with allocatable
5397 components must have the result allocatable components copied. */
5398 arg = expr->value.function.actual;
5399 if (result && arg && expr->rank
5400 && expr->value.function.isym
5401 && expr->value.function.isym->transformational
5402 && arg->expr->ts.type == BT_DERIVED
5403 && arg->expr->ts.u.derived->attr.alloc_comp)
5404 {
5405 tree tmp2;
5406 /* Copy the allocatable components. We have to use a
5407 temporary here to prevent source allocatable components
5408 from being corrupted. */
5409 tmp2 = gfc_evaluate_now (result, &se->pre);
5410 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
5411 result, tmp2, expr->rank);
5412 gfc_add_expr_to_block (&se->pre, tmp);
5413 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
5414 expr->rank);
5415 gfc_add_expr_to_block (&se->pre, tmp);
5416
5417 /* Finally free the temporary's data field. */
5418 tmp = gfc_conv_descriptor_data_get (tmp2);
5419 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
5420 NULL_TREE, NULL_TREE, true,
5421 NULL, false);
5422 gfc_add_expr_to_block (&se->pre, tmp);
5423 }
5424 }
5425 else
5426 gfc_add_block_to_block (&se->post, &post);
5427
5428 return has_alternate_specifier;
5429 }
5430
5431
5432 /* Fill a character string with spaces. */
5433
5434 static tree
5435 fill_with_spaces (tree start, tree type, tree size)
5436 {
5437 stmtblock_t block, loop;
5438 tree i, el, exit_label, cond, tmp;
5439
5440 /* For a simple char type, we can call memset(). */
5441 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
5442 return build_call_expr_loc (input_location,
5443 builtin_decl_explicit (BUILT_IN_MEMSET),
5444 3, start,
5445 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
5446 lang_hooks.to_target_charset (' ')),
5447 size);
5448
5449 /* Otherwise, we use a loop:
5450 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
5451 *el = (type) ' ';
5452 */
5453
5454 /* Initialize variables. */
5455 gfc_init_block (&block);
5456 i = gfc_create_var (sizetype, "i");
5457 gfc_add_modify (&block, i, fold_convert (sizetype, size));
5458 el = gfc_create_var (build_pointer_type (type), "el");
5459 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
5460 exit_label = gfc_build_label_decl (NULL_TREE);
5461 TREE_USED (exit_label) = 1;
5462
5463
5464 /* Loop body. */
5465 gfc_init_block (&loop);
5466
5467 /* Exit condition. */
5468 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, i,
5469 build_zero_cst (sizetype));
5470 tmp = build1_v (GOTO_EXPR, exit_label);
5471 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
5472 build_empty_stmt (input_location));
5473 gfc_add_expr_to_block (&loop, tmp);
5474
5475 /* Assignment. */
5476 gfc_add_modify (&loop,
5477 fold_build1_loc (input_location, INDIRECT_REF, type, el),
5478 build_int_cst (type, lang_hooks.to_target_charset (' ')));
5479
5480 /* Increment loop variables. */
5481 gfc_add_modify (&loop, i,
5482 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
5483 TYPE_SIZE_UNIT (type)));
5484 gfc_add_modify (&loop, el,
5485 fold_build_pointer_plus_loc (input_location,
5486 el, TYPE_SIZE_UNIT (type)));
5487
5488 /* Making the loop... actually loop! */
5489 tmp = gfc_finish_block (&loop);
5490 tmp = build1_v (LOOP_EXPR, tmp);
5491 gfc_add_expr_to_block (&block, tmp);
5492
5493 /* The exit label. */
5494 tmp = build1_v (LABEL_EXPR, exit_label);
5495 gfc_add_expr_to_block (&block, tmp);
5496
5497
5498 return gfc_finish_block (&block);
5499 }
5500
5501
5502 /* Generate code to copy a string. */
5503
5504 void
5505 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
5506 int dkind, tree slength, tree src, int skind)
5507 {
5508 tree tmp, dlen, slen;
5509 tree dsc;
5510 tree ssc;
5511 tree cond;
5512 tree cond2;
5513 tree tmp2;
5514 tree tmp3;
5515 tree tmp4;
5516 tree chartype;
5517 stmtblock_t tempblock;
5518
5519 gcc_assert (dkind == skind);
5520
5521 if (slength != NULL_TREE)
5522 {
5523 slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
5524 ssc = gfc_string_to_single_character (slen, src, skind);
5525 }
5526 else
5527 {
5528 slen = build_int_cst (size_type_node, 1);
5529 ssc = src;
5530 }
5531
5532 if (dlength != NULL_TREE)
5533 {
5534 dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
5535 dsc = gfc_string_to_single_character (dlen, dest, dkind);
5536 }
5537 else
5538 {
5539 dlen = build_int_cst (size_type_node, 1);
5540 dsc = dest;
5541 }
5542
5543 /* Assign directly if the types are compatible. */
5544 if (dsc != NULL_TREE && ssc != NULL_TREE
5545 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
5546 {
5547 gfc_add_modify (block, dsc, ssc);
5548 return;
5549 }
5550
5551 /* Do nothing if the destination length is zero. */
5552 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, dlen,
5553 build_int_cst (size_type_node, 0));
5554
5555 /* The following code was previously in _gfortran_copy_string:
5556
5557 // The two strings may overlap so we use memmove.
5558 void
5559 copy_string (GFC_INTEGER_4 destlen, char * dest,
5560 GFC_INTEGER_4 srclen, const char * src)
5561 {
5562 if (srclen >= destlen)
5563 {
5564 // This will truncate if too long.
5565 memmove (dest, src, destlen);
5566 }
5567 else
5568 {
5569 memmove (dest, src, srclen);
5570 // Pad with spaces.
5571 memset (&dest[srclen], ' ', destlen - srclen);
5572 }
5573 }
5574
5575 We're now doing it here for better optimization, but the logic
5576 is the same. */
5577
5578 /* For non-default character kinds, we have to multiply the string
5579 length by the base type size. */
5580 chartype = gfc_get_char_type (dkind);
5581 slen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
5582 fold_convert (size_type_node, slen),
5583 fold_convert (size_type_node,
5584 TYPE_SIZE_UNIT (chartype)));
5585 dlen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
5586 fold_convert (size_type_node, dlen),
5587 fold_convert (size_type_node,
5588 TYPE_SIZE_UNIT (chartype)));
5589
5590 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
5591 dest = fold_convert (pvoid_type_node, dest);
5592 else
5593 dest = gfc_build_addr_expr (pvoid_type_node, dest);
5594
5595 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
5596 src = fold_convert (pvoid_type_node, src);
5597 else
5598 src = gfc_build_addr_expr (pvoid_type_node, src);
5599
5600 /* Truncate string if source is too long. */
5601 cond2 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, slen,
5602 dlen);
5603 tmp2 = build_call_expr_loc (input_location,
5604 builtin_decl_explicit (BUILT_IN_MEMMOVE),
5605 3, dest, src, dlen);
5606
5607 /* Else copy and pad with spaces. */
5608 tmp3 = build_call_expr_loc (input_location,
5609 builtin_decl_explicit (BUILT_IN_MEMMOVE),
5610 3, dest, src, slen);
5611
5612 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
5613 tmp4 = fill_with_spaces (tmp4, chartype,
5614 fold_build2_loc (input_location, MINUS_EXPR,
5615 TREE_TYPE(dlen), dlen, slen));
5616
5617 gfc_init_block (&tempblock);
5618 gfc_add_expr_to_block (&tempblock, tmp3);
5619 gfc_add_expr_to_block (&tempblock, tmp4);
5620 tmp3 = gfc_finish_block (&tempblock);
5621
5622 /* The whole copy_string function is there. */
5623 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
5624 tmp2, tmp3);
5625 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
5626 build_empty_stmt (input_location));
5627 gfc_add_expr_to_block (block, tmp);
5628 }
5629
5630
5631 /* Translate a statement function.
5632 The value of a statement function reference is obtained by evaluating the
5633 expression using the values of the actual arguments for the values of the
5634 corresponding dummy arguments. */
5635
5636 static void
5637 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
5638 {
5639 gfc_symbol *sym;
5640 gfc_symbol *fsym;
5641 gfc_formal_arglist *fargs;
5642 gfc_actual_arglist *args;
5643 gfc_se lse;
5644 gfc_se rse;
5645 gfc_saved_var *saved_vars;
5646 tree *temp_vars;
5647 tree type;
5648 tree tmp;
5649 int n;
5650
5651 sym = expr->symtree->n.sym;
5652 args = expr->value.function.actual;
5653 gfc_init_se (&lse, NULL);
5654 gfc_init_se (&rse, NULL);
5655
5656 n = 0;
5657 for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
5658 n++;
5659 saved_vars = XCNEWVEC (gfc_saved_var, n);
5660 temp_vars = XCNEWVEC (tree, n);
5661
5662 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
5663 fargs = fargs->next, n++)
5664 {
5665 /* Each dummy shall be specified, explicitly or implicitly, to be
5666 scalar. */
5667 gcc_assert (fargs->sym->attr.dimension == 0);
5668 fsym = fargs->sym;
5669
5670 if (fsym->ts.type == BT_CHARACTER)
5671 {
5672 /* Copy string arguments. */
5673 tree arglen;
5674
5675 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
5676 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
5677
5678 /* Create a temporary to hold the value. */
5679 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
5680 fsym->ts.u.cl->backend_decl
5681 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
5682
5683 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
5684 temp_vars[n] = gfc_create_var (type, fsym->name);
5685
5686 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
5687
5688 gfc_conv_expr (&rse, args->expr);
5689 gfc_conv_string_parameter (&rse);
5690 gfc_add_block_to_block (&se->pre, &lse.pre);
5691 gfc_add_block_to_block (&se->pre, &rse.pre);
5692
5693 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
5694 rse.string_length, rse.expr, fsym->ts.kind);
5695 gfc_add_block_to_block (&se->pre, &lse.post);
5696 gfc_add_block_to_block (&se->pre, &rse.post);
5697 }
5698 else
5699 {
5700 /* For everything else, just evaluate the expression. */
5701
5702 /* Create a temporary to hold the value. */
5703 type = gfc_typenode_for_spec (&fsym->ts);
5704 temp_vars[n] = gfc_create_var (type, fsym->name);
5705
5706 gfc_conv_expr (&lse, args->expr);
5707
5708 gfc_add_block_to_block (&se->pre, &lse.pre);
5709 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
5710 gfc_add_block_to_block (&se->pre, &lse.post);
5711 }
5712
5713 args = args->next;
5714 }
5715
5716 /* Use the temporary variables in place of the real ones. */
5717 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
5718 fargs = fargs->next, n++)
5719 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
5720
5721 gfc_conv_expr (se, sym->value);
5722
5723 if (sym->ts.type == BT_CHARACTER)
5724 {
5725 gfc_conv_const_charlen (sym->ts.u.cl);
5726
5727 /* Force the expression to the correct length. */
5728 if (!INTEGER_CST_P (se->string_length)
5729 || tree_int_cst_lt (se->string_length,
5730 sym->ts.u.cl->backend_decl))
5731 {
5732 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
5733 tmp = gfc_create_var (type, sym->name);
5734 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
5735 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
5736 sym->ts.kind, se->string_length, se->expr,
5737 sym->ts.kind);
5738 se->expr = tmp;
5739 }
5740 se->string_length = sym->ts.u.cl->backend_decl;
5741 }
5742
5743 /* Restore the original variables. */
5744 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
5745 fargs = fargs->next, n++)
5746 gfc_restore_sym (fargs->sym, &saved_vars[n]);
5747 free (temp_vars);
5748 free (saved_vars);
5749 }
5750
5751
5752 /* Translate a function expression. */
5753
5754 static void
5755 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
5756 {
5757 gfc_symbol *sym;
5758
5759 if (expr->value.function.isym)
5760 {
5761 gfc_conv_intrinsic_function (se, expr);
5762 return;
5763 }
5764
5765 /* expr.value.function.esym is the resolved (specific) function symbol for
5766 most functions. However this isn't set for dummy procedures. */
5767 sym = expr->value.function.esym;
5768 if (!sym)
5769 sym = expr->symtree->n.sym;
5770
5771 /* The IEEE_ARITHMETIC functions are caught here. */
5772 if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
5773 if (gfc_conv_ieee_arithmetic_function (se, expr))
5774 return;
5775
5776 /* We distinguish statement functions from general functions to improve
5777 runtime performance. */
5778 if (sym->attr.proc == PROC_ST_FUNCTION)
5779 {
5780 gfc_conv_statement_function (se, expr);
5781 return;
5782 }
5783
5784 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
5785 NULL);
5786 }
5787
5788
5789 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
5790
5791 static bool
5792 is_zero_initializer_p (gfc_expr * expr)
5793 {
5794 if (expr->expr_type != EXPR_CONSTANT)
5795 return false;
5796
5797 /* We ignore constants with prescribed memory representations for now. */
5798 if (expr->representation.string)
5799 return false;
5800
5801 switch (expr->ts.type)
5802 {
5803 case BT_INTEGER:
5804 return mpz_cmp_si (expr->value.integer, 0) == 0;
5805
5806 case BT_REAL:
5807 return mpfr_zero_p (expr->value.real)
5808 && MPFR_SIGN (expr->value.real) >= 0;
5809
5810 case BT_LOGICAL:
5811 return expr->value.logical == 0;
5812
5813 case BT_COMPLEX:
5814 return mpfr_zero_p (mpc_realref (expr->value.complex))
5815 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
5816 && mpfr_zero_p (mpc_imagref (expr->value.complex))
5817 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
5818
5819 default:
5820 break;
5821 }
5822 return false;
5823 }
5824
5825
5826 static void
5827 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
5828 {
5829 gfc_ss *ss;
5830
5831 ss = se->ss;
5832 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
5833 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
5834
5835 gfc_conv_tmp_array_ref (se);
5836 }
5837
5838
5839 /* Build a static initializer. EXPR is the expression for the initial value.
5840 The other parameters describe the variable of the component being
5841 initialized. EXPR may be null. */
5842
5843 tree
5844 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
5845 bool array, bool pointer, bool procptr)
5846 {
5847 gfc_se se;
5848
5849 if (!(expr || pointer || procptr))
5850 return NULL_TREE;
5851
5852 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
5853 (these are the only two iso_c_binding derived types that can be
5854 used as initialization expressions). If so, we need to modify
5855 the 'expr' to be that for a (void *). */
5856 if (expr != NULL && expr->ts.type == BT_DERIVED
5857 && expr->ts.is_iso_c && expr->ts.u.derived)
5858 {
5859 gfc_symbol *derived = expr->ts.u.derived;
5860
5861 /* The derived symbol has already been converted to a (void *). Use
5862 its kind. */
5863 expr = gfc_get_int_expr (derived->ts.kind, NULL, 0);
5864 expr->ts.f90_type = derived->ts.f90_type;
5865
5866 gfc_init_se (&se, NULL);
5867 gfc_conv_constant (&se, expr);
5868 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5869 return se.expr;
5870 }
5871
5872 if (array && !procptr)
5873 {
5874 tree ctor;
5875 /* Arrays need special handling. */
5876 if (pointer)
5877 ctor = gfc_build_null_descriptor (type);
5878 /* Special case assigning an array to zero. */
5879 else if (is_zero_initializer_p (expr))
5880 ctor = build_constructor (type, NULL);
5881 else
5882 ctor = gfc_conv_array_initializer (type, expr);
5883 TREE_STATIC (ctor) = 1;
5884 return ctor;
5885 }
5886 else if (pointer || procptr)
5887 {
5888 if (ts->type == BT_CLASS && !procptr)
5889 {
5890 gfc_init_se (&se, NULL);
5891 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
5892 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
5893 TREE_STATIC (se.expr) = 1;
5894 return se.expr;
5895 }
5896 else if (!expr || expr->expr_type == EXPR_NULL)
5897 return fold_convert (type, null_pointer_node);
5898 else
5899 {
5900 gfc_init_se (&se, NULL);
5901 se.want_pointer = 1;
5902 gfc_conv_expr (&se, expr);
5903 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5904 return se.expr;
5905 }
5906 }
5907 else
5908 {
5909 switch (ts->type)
5910 {
5911 case BT_DERIVED:
5912 case BT_CLASS:
5913 gfc_init_se (&se, NULL);
5914 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
5915 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
5916 else
5917 gfc_conv_structure (&se, expr, 1);
5918 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
5919 TREE_STATIC (se.expr) = 1;
5920 return se.expr;
5921
5922 case BT_CHARACTER:
5923 {
5924 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl,expr);
5925 TREE_STATIC (ctor) = 1;
5926 return ctor;
5927 }
5928
5929 default:
5930 gfc_init_se (&se, NULL);
5931 gfc_conv_constant (&se, expr);
5932 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5933 return se.expr;
5934 }
5935 }
5936 }
5937
5938 static tree
5939 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
5940 {
5941 gfc_se rse;
5942 gfc_se lse;
5943 gfc_ss *rss;
5944 gfc_ss *lss;
5945 gfc_array_info *lss_array;
5946 stmtblock_t body;
5947 stmtblock_t block;
5948 gfc_loopinfo loop;
5949 int n;
5950 tree tmp;
5951
5952 gfc_start_block (&block);
5953
5954 /* Initialize the scalarizer. */
5955 gfc_init_loopinfo (&loop);
5956
5957 gfc_init_se (&lse, NULL);
5958 gfc_init_se (&rse, NULL);
5959
5960 /* Walk the rhs. */
5961 rss = gfc_walk_expr (expr);
5962 if (rss == gfc_ss_terminator)
5963 /* The rhs is scalar. Add a ss for the expression. */
5964 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
5965
5966 /* Create a SS for the destination. */
5967 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
5968 GFC_SS_COMPONENT);
5969 lss_array = &lss->info->data.array;
5970 lss_array->shape = gfc_get_shape (cm->as->rank);
5971 lss_array->descriptor = dest;
5972 lss_array->data = gfc_conv_array_data (dest);
5973 lss_array->offset = gfc_conv_array_offset (dest);
5974 for (n = 0; n < cm->as->rank; n++)
5975 {
5976 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
5977 lss_array->stride[n] = gfc_index_one_node;
5978
5979 mpz_init (lss_array->shape[n]);
5980 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
5981 cm->as->lower[n]->value.integer);
5982 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
5983 }
5984
5985 /* Associate the SS with the loop. */
5986 gfc_add_ss_to_loop (&loop, lss);
5987 gfc_add_ss_to_loop (&loop, rss);
5988
5989 /* Calculate the bounds of the scalarization. */
5990 gfc_conv_ss_startstride (&loop);
5991
5992 /* Setup the scalarizing loops. */
5993 gfc_conv_loop_setup (&loop, &expr->where);
5994
5995 /* Setup the gfc_se structures. */
5996 gfc_copy_loopinfo_to_se (&lse, &loop);
5997 gfc_copy_loopinfo_to_se (&rse, &loop);
5998
5999 rse.ss = rss;
6000 gfc_mark_ss_chain_used (rss, 1);
6001 lse.ss = lss;
6002 gfc_mark_ss_chain_used (lss, 1);
6003
6004 /* Start the scalarized loop body. */
6005 gfc_start_scalarized_body (&loop, &body);
6006
6007 gfc_conv_tmp_array_ref (&lse);
6008 if (cm->ts.type == BT_CHARACTER)
6009 lse.string_length = cm->ts.u.cl->backend_decl;
6010
6011 gfc_conv_expr (&rse, expr);
6012
6013 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false, true);
6014 gfc_add_expr_to_block (&body, tmp);
6015
6016 gcc_assert (rse.ss == gfc_ss_terminator);
6017
6018 /* Generate the copying loops. */
6019 gfc_trans_scalarizing_loops (&loop, &body);
6020
6021 /* Wrap the whole thing up. */
6022 gfc_add_block_to_block (&block, &loop.pre);
6023 gfc_add_block_to_block (&block, &loop.post);
6024
6025 gcc_assert (lss_array->shape != NULL);
6026 gfc_free_shape (&lss_array->shape, cm->as->rank);
6027 gfc_cleanup_loop (&loop);
6028
6029 return gfc_finish_block (&block);
6030 }
6031
6032
6033 static tree
6034 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
6035 gfc_expr * expr)
6036 {
6037 gfc_se se;
6038 stmtblock_t block;
6039 tree offset;
6040 int n;
6041 tree tmp;
6042 tree tmp2;
6043 gfc_array_spec *as;
6044 gfc_expr *arg = NULL;
6045
6046 gfc_start_block (&block);
6047 gfc_init_se (&se, NULL);
6048
6049 /* Get the descriptor for the expressions. */
6050 se.want_pointer = 0;
6051 gfc_conv_expr_descriptor (&se, expr);
6052 gfc_add_block_to_block (&block, &se.pre);
6053 gfc_add_modify (&block, dest, se.expr);
6054
6055 /* Deal with arrays of derived types with allocatable components. */
6056 if (cm->ts.type == BT_DERIVED
6057 && cm->ts.u.derived->attr.alloc_comp)
6058 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
6059 se.expr, dest,
6060 cm->as->rank);
6061 else
6062 tmp = gfc_duplicate_allocatable (dest, se.expr,
6063 TREE_TYPE(cm->backend_decl),
6064 cm->as->rank);
6065
6066 gfc_add_expr_to_block (&block, tmp);
6067 gfc_add_block_to_block (&block, &se.post);
6068
6069 if (expr->expr_type != EXPR_VARIABLE)
6070 gfc_conv_descriptor_data_set (&block, se.expr,
6071 null_pointer_node);
6072
6073 /* We need to know if the argument of a conversion function is a
6074 variable, so that the correct lower bound can be used. */
6075 if (expr->expr_type == EXPR_FUNCTION
6076 && expr->value.function.isym
6077 && expr->value.function.isym->conversion
6078 && expr->value.function.actual->expr
6079 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
6080 arg = expr->value.function.actual->expr;
6081
6082 /* Obtain the array spec of full array references. */
6083 if (arg)
6084 as = gfc_get_full_arrayspec_from_expr (arg);
6085 else
6086 as = gfc_get_full_arrayspec_from_expr (expr);
6087
6088 /* Shift the lbound and ubound of temporaries to being unity,
6089 rather than zero, based. Always calculate the offset. */
6090 offset = gfc_conv_descriptor_offset_get (dest);
6091 gfc_add_modify (&block, offset, gfc_index_zero_node);
6092 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
6093
6094 for (n = 0; n < expr->rank; n++)
6095 {
6096 tree span;
6097 tree lbound;
6098
6099 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
6100 TODO It looks as if gfc_conv_expr_descriptor should return
6101 the correct bounds and that the following should not be
6102 necessary. This would simplify gfc_conv_intrinsic_bound
6103 as well. */
6104 if (as && as->lower[n])
6105 {
6106 gfc_se lbse;
6107 gfc_init_se (&lbse, NULL);
6108 gfc_conv_expr (&lbse, as->lower[n]);
6109 gfc_add_block_to_block (&block, &lbse.pre);
6110 lbound = gfc_evaluate_now (lbse.expr, &block);
6111 }
6112 else if (as && arg)
6113 {
6114 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
6115 lbound = gfc_conv_descriptor_lbound_get (tmp,
6116 gfc_rank_cst[n]);
6117 }
6118 else if (as)
6119 lbound = gfc_conv_descriptor_lbound_get (dest,
6120 gfc_rank_cst[n]);
6121 else
6122 lbound = gfc_index_one_node;
6123
6124 lbound = fold_convert (gfc_array_index_type, lbound);
6125
6126 /* Shift the bounds and set the offset accordingly. */
6127 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
6128 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
6129 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
6130 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
6131 span, lbound);
6132 gfc_conv_descriptor_ubound_set (&block, dest,
6133 gfc_rank_cst[n], tmp);
6134 gfc_conv_descriptor_lbound_set (&block, dest,
6135 gfc_rank_cst[n], lbound);
6136
6137 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6138 gfc_conv_descriptor_lbound_get (dest,
6139 gfc_rank_cst[n]),
6140 gfc_conv_descriptor_stride_get (dest,
6141 gfc_rank_cst[n]));
6142 gfc_add_modify (&block, tmp2, tmp);
6143 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
6144 offset, tmp2);
6145 gfc_conv_descriptor_offset_set (&block, dest, tmp);
6146 }
6147
6148 if (arg)
6149 {
6150 /* If a conversion expression has a null data pointer
6151 argument, nullify the allocatable component. */
6152 tree non_null_expr;
6153 tree null_expr;
6154
6155 if (arg->symtree->n.sym->attr.allocatable
6156 || arg->symtree->n.sym->attr.pointer)
6157 {
6158 non_null_expr = gfc_finish_block (&block);
6159 gfc_start_block (&block);
6160 gfc_conv_descriptor_data_set (&block, dest,
6161 null_pointer_node);
6162 null_expr = gfc_finish_block (&block);
6163 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
6164 tmp = build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
6165 fold_convert (TREE_TYPE (tmp), null_pointer_node));
6166 return build3_v (COND_EXPR, tmp,
6167 null_expr, non_null_expr);
6168 }
6169 }
6170
6171 return gfc_finish_block (&block);
6172 }
6173
6174
6175 /* Assign a single component of a derived type constructor. */
6176
6177 static tree
6178 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
6179 {
6180 gfc_se se;
6181 gfc_se lse;
6182 stmtblock_t block;
6183 tree tmp;
6184
6185 gfc_start_block (&block);
6186
6187 if (cm->attr.pointer || cm->attr.proc_pointer)
6188 {
6189 gfc_init_se (&se, NULL);
6190 /* Pointer component. */
6191 if ((cm->attr.dimension || cm->attr.codimension)
6192 && !cm->attr.proc_pointer)
6193 {
6194 /* Array pointer. */
6195 if (expr->expr_type == EXPR_NULL)
6196 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
6197 else
6198 {
6199 se.direct_byref = 1;
6200 se.expr = dest;
6201 gfc_conv_expr_descriptor (&se, expr);
6202 gfc_add_block_to_block (&block, &se.pre);
6203 gfc_add_block_to_block (&block, &se.post);
6204 }
6205 }
6206 else
6207 {
6208 /* Scalar pointers. */
6209 se.want_pointer = 1;
6210 gfc_conv_expr (&se, expr);
6211 gfc_add_block_to_block (&block, &se.pre);
6212
6213 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
6214 && expr->symtree->n.sym->attr.dummy)
6215 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
6216
6217 gfc_add_modify (&block, dest,
6218 fold_convert (TREE_TYPE (dest), se.expr));
6219 gfc_add_block_to_block (&block, &se.post);
6220 }
6221 }
6222 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
6223 {
6224 /* NULL initialization for CLASS components. */
6225 tmp = gfc_trans_structure_assign (dest,
6226 gfc_class_initializer (&cm->ts, expr));
6227 gfc_add_expr_to_block (&block, tmp);
6228 }
6229 else if ((cm->attr.dimension || cm->attr.codimension)
6230 && !cm->attr.proc_pointer)
6231 {
6232 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
6233 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
6234 else if (cm->attr.allocatable)
6235 {
6236 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
6237 gfc_add_expr_to_block (&block, tmp);
6238 }
6239 else
6240 {
6241 tmp = gfc_trans_subarray_assign (dest, cm, expr);
6242 gfc_add_expr_to_block (&block, tmp);
6243 }
6244 }
6245 else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
6246 {
6247 if (expr->expr_type != EXPR_STRUCTURE)
6248 {
6249 gfc_init_se (&se, NULL);
6250 gfc_conv_expr (&se, expr);
6251 gfc_add_block_to_block (&block, &se.pre);
6252 gfc_add_modify (&block, dest,
6253 fold_convert (TREE_TYPE (dest), se.expr));
6254 gfc_add_block_to_block (&block, &se.post);
6255 }
6256 else
6257 {
6258 /* Nested constructors. */
6259 tmp = gfc_trans_structure_assign (dest, expr);
6260 gfc_add_expr_to_block (&block, tmp);
6261 }
6262 }
6263 else if (gfc_deferred_strlen (cm, &tmp))
6264 {
6265 tree strlen;
6266 strlen = tmp;
6267 gcc_assert (strlen);
6268 strlen = fold_build3_loc (input_location, COMPONENT_REF,
6269 TREE_TYPE (strlen),
6270 TREE_OPERAND (dest, 0),
6271 strlen, NULL_TREE);
6272
6273 if (expr->expr_type == EXPR_NULL)
6274 {
6275 tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
6276 gfc_add_modify (&block, dest, tmp);
6277 tmp = build_int_cst (TREE_TYPE (strlen), 0);
6278 gfc_add_modify (&block, strlen, tmp);
6279 }
6280 else
6281 {
6282 tree size;
6283 gfc_init_se (&se, NULL);
6284 gfc_conv_expr (&se, expr);
6285 size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
6286 tmp = build_call_expr_loc (input_location,
6287 builtin_decl_explicit (BUILT_IN_MALLOC),
6288 1, size);
6289 gfc_add_modify (&block, dest,
6290 fold_convert (TREE_TYPE (dest), tmp));
6291 gfc_add_modify (&block, strlen, se.string_length);
6292 tmp = gfc_build_memcpy_call (dest, se.expr, size);
6293 gfc_add_expr_to_block (&block, tmp);
6294 }
6295 }
6296 else if (!cm->attr.deferred_parameter)
6297 {
6298 /* Scalar component (excluding deferred parameters). */
6299 gfc_init_se (&se, NULL);
6300 gfc_init_se (&lse, NULL);
6301
6302 gfc_conv_expr (&se, expr);
6303 if (cm->ts.type == BT_CHARACTER)
6304 lse.string_length = cm->ts.u.cl->backend_decl;
6305 lse.expr = dest;
6306 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false, true);
6307 gfc_add_expr_to_block (&block, tmp);
6308 }
6309 return gfc_finish_block (&block);
6310 }
6311
6312 /* Assign a derived type constructor to a variable. */
6313
6314 static tree
6315 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
6316 {
6317 gfc_constructor *c;
6318 gfc_component *cm;
6319 stmtblock_t block;
6320 tree field;
6321 tree tmp;
6322
6323 gfc_start_block (&block);
6324 cm = expr->ts.u.derived->components;
6325
6326 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
6327 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
6328 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
6329 {
6330 gfc_se se, lse;
6331
6332 gcc_assert (cm->backend_decl == NULL);
6333 gfc_init_se (&se, NULL);
6334 gfc_init_se (&lse, NULL);
6335 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
6336 lse.expr = dest;
6337 gfc_add_modify (&block, lse.expr,
6338 fold_convert (TREE_TYPE (lse.expr), se.expr));
6339
6340 return gfc_finish_block (&block);
6341 }
6342
6343 for (c = gfc_constructor_first (expr->value.constructor);
6344 c; c = gfc_constructor_next (c), cm = cm->next)
6345 {
6346 /* Skip absent members in default initializers. */
6347 if (!c->expr)
6348 continue;
6349
6350 field = cm->backend_decl;
6351 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
6352 dest, field, NULL_TREE);
6353 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
6354 gfc_add_expr_to_block (&block, tmp);
6355 }
6356 return gfc_finish_block (&block);
6357 }
6358
6359 /* Build an expression for a constructor. If init is nonzero then
6360 this is part of a static variable initializer. */
6361
6362 void
6363 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
6364 {
6365 gfc_constructor *c;
6366 gfc_component *cm;
6367 tree val;
6368 tree type;
6369 tree tmp;
6370 vec<constructor_elt, va_gc> *v = NULL;
6371
6372 gcc_assert (se->ss == NULL);
6373 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
6374 type = gfc_typenode_for_spec (&expr->ts);
6375
6376 if (!init)
6377 {
6378 /* Create a temporary variable and fill it in. */
6379 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
6380 tmp = gfc_trans_structure_assign (se->expr, expr);
6381 gfc_add_expr_to_block (&se->pre, tmp);
6382 return;
6383 }
6384
6385 cm = expr->ts.u.derived->components;
6386
6387 for (c = gfc_constructor_first (expr->value.constructor);
6388 c; c = gfc_constructor_next (c), cm = cm->next)
6389 {
6390 /* Skip absent members in default initializers and allocatable
6391 components. Although the latter have a default initializer
6392 of EXPR_NULL,... by default, the static nullify is not needed
6393 since this is done every time we come into scope. */
6394 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
6395 continue;
6396
6397 if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
6398 && strcmp (cm->name, "_extends") == 0
6399 && cm->initializer->symtree)
6400 {
6401 tree vtab;
6402 gfc_symbol *vtabs;
6403 vtabs = cm->initializer->symtree->n.sym;
6404 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
6405 vtab = unshare_expr_without_location (vtab);
6406 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
6407 }
6408 else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
6409 {
6410 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
6411 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
6412 fold_convert (TREE_TYPE (cm->backend_decl),
6413 val));
6414 }
6415 else
6416 {
6417 val = gfc_conv_initializer (c->expr, &cm->ts,
6418 TREE_TYPE (cm->backend_decl),
6419 cm->attr.dimension, cm->attr.pointer,
6420 cm->attr.proc_pointer);
6421 val = unshare_expr_without_location (val);
6422
6423 /* Append it to the constructor list. */
6424 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
6425 }
6426 }
6427 se->expr = build_constructor (type, v);
6428 if (init)
6429 TREE_CONSTANT (se->expr) = 1;
6430 }
6431
6432
6433 /* Translate a substring expression. */
6434
6435 static void
6436 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
6437 {
6438 gfc_ref *ref;
6439
6440 ref = expr->ref;
6441
6442 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
6443
6444 se->expr = gfc_build_wide_string_const (expr->ts.kind,
6445 expr->value.character.length,
6446 expr->value.character.string);
6447
6448 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
6449 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
6450
6451 if (ref)
6452 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
6453 }
6454
6455
6456 /* Entry point for expression translation. Evaluates a scalar quantity.
6457 EXPR is the expression to be translated, and SE is the state structure if
6458 called from within the scalarized. */
6459
6460 void
6461 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
6462 {
6463 gfc_ss *ss;
6464
6465 ss = se->ss;
6466 if (ss && ss->info->expr == expr
6467 && (ss->info->type == GFC_SS_SCALAR
6468 || ss->info->type == GFC_SS_REFERENCE))
6469 {
6470 gfc_ss_info *ss_info;
6471
6472 ss_info = ss->info;
6473 /* Substitute a scalar expression evaluated outside the scalarization
6474 loop. */
6475 se->expr = ss_info->data.scalar.value;
6476 /* If the reference can be NULL, the value field contains the reference,
6477 not the value the reference points to (see gfc_add_loop_ss_code). */
6478 if (ss_info->can_be_null_ref)
6479 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
6480
6481 se->string_length = ss_info->string_length;
6482 gfc_advance_se_ss_chain (se);
6483 return;
6484 }
6485
6486 /* We need to convert the expressions for the iso_c_binding derived types.
6487 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
6488 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
6489 typespec for the C_PTR and C_FUNPTR symbols, which has already been
6490 updated to be an integer with a kind equal to the size of a (void *). */
6491 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID)
6492 {
6493 if (expr->expr_type == EXPR_VARIABLE
6494 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
6495 || expr->symtree->n.sym->intmod_sym_id
6496 == ISOCBINDING_NULL_FUNPTR))
6497 {
6498 /* Set expr_type to EXPR_NULL, which will result in
6499 null_pointer_node being used below. */
6500 expr->expr_type = EXPR_NULL;
6501 }
6502 else
6503 {
6504 /* Update the type/kind of the expression to be what the new
6505 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
6506 expr->ts.type = BT_INTEGER;
6507 expr->ts.f90_type = BT_VOID;
6508 expr->ts.kind = gfc_index_integer_kind;
6509 }
6510 }
6511
6512 gfc_fix_class_refs (expr);
6513
6514 switch (expr->expr_type)
6515 {
6516 case EXPR_OP:
6517 gfc_conv_expr_op (se, expr);
6518 break;
6519
6520 case EXPR_FUNCTION:
6521 gfc_conv_function_expr (se, expr);
6522 break;
6523
6524 case EXPR_CONSTANT:
6525 gfc_conv_constant (se, expr);
6526 break;
6527
6528 case EXPR_VARIABLE:
6529 gfc_conv_variable (se, expr);
6530 break;
6531
6532 case EXPR_NULL:
6533 se->expr = null_pointer_node;
6534 break;
6535
6536 case EXPR_SUBSTRING:
6537 gfc_conv_substring_expr (se, expr);
6538 break;
6539
6540 case EXPR_STRUCTURE:
6541 gfc_conv_structure (se, expr, 0);
6542 break;
6543
6544 case EXPR_ARRAY:
6545 gfc_conv_array_constructor_expr (se, expr);
6546 break;
6547
6548 default:
6549 gcc_unreachable ();
6550 break;
6551 }
6552 }
6553
6554 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
6555 of an assignment. */
6556 void
6557 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
6558 {
6559 gfc_conv_expr (se, expr);
6560 /* All numeric lvalues should have empty post chains. If not we need to
6561 figure out a way of rewriting an lvalue so that it has no post chain. */
6562 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
6563 }
6564
6565 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
6566 numeric expressions. Used for scalar values where inserting cleanup code
6567 is inconvenient. */
6568 void
6569 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
6570 {
6571 tree val;
6572
6573 gcc_assert (expr->ts.type != BT_CHARACTER);
6574 gfc_conv_expr (se, expr);
6575 if (se->post.head)
6576 {
6577 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
6578 gfc_add_modify (&se->pre, val, se->expr);
6579 se->expr = val;
6580 gfc_add_block_to_block (&se->pre, &se->post);
6581 }
6582 }
6583
6584 /* Helper to translate an expression and convert it to a particular type. */
6585 void
6586 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
6587 {
6588 gfc_conv_expr_val (se, expr);
6589 se->expr = convert (type, se->expr);
6590 }
6591
6592
6593 /* Converts an expression so that it can be passed by reference. Scalar
6594 values only. */
6595
6596 void
6597 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
6598 {
6599 gfc_ss *ss;
6600 tree var;
6601
6602 ss = se->ss;
6603 if (ss && ss->info->expr == expr
6604 && ss->info->type == GFC_SS_REFERENCE)
6605 {
6606 /* Returns a reference to the scalar evaluated outside the loop
6607 for this case. */
6608 gfc_conv_expr (se, expr);
6609
6610 if (expr->ts.type == BT_CHARACTER
6611 && expr->expr_type != EXPR_FUNCTION)
6612 gfc_conv_string_parameter (se);
6613 else
6614 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
6615
6616 return;
6617 }
6618
6619 if (expr->ts.type == BT_CHARACTER)
6620 {
6621 gfc_conv_expr (se, expr);
6622 gfc_conv_string_parameter (se);
6623 return;
6624 }
6625
6626 if (expr->expr_type == EXPR_VARIABLE)
6627 {
6628 se->want_pointer = 1;
6629 gfc_conv_expr (se, expr);
6630 if (se->post.head)
6631 {
6632 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
6633 gfc_add_modify (&se->pre, var, se->expr);
6634 gfc_add_block_to_block (&se->pre, &se->post);
6635 se->expr = var;
6636 }
6637 return;
6638 }
6639
6640 if (expr->expr_type == EXPR_FUNCTION
6641 && ((expr->value.function.esym
6642 && expr->value.function.esym->result->attr.pointer
6643 && !expr->value.function.esym->result->attr.dimension)
6644 || (!expr->value.function.esym && !expr->ref
6645 && expr->symtree->n.sym->attr.pointer
6646 && !expr->symtree->n.sym->attr.dimension)))
6647 {
6648 se->want_pointer = 1;
6649 gfc_conv_expr (se, expr);
6650 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
6651 gfc_add_modify (&se->pre, var, se->expr);
6652 se->expr = var;
6653 return;
6654 }
6655
6656 gfc_conv_expr (se, expr);
6657
6658 /* Create a temporary var to hold the value. */
6659 if (TREE_CONSTANT (se->expr))
6660 {
6661 tree tmp = se->expr;
6662 STRIP_TYPE_NOPS (tmp);
6663 var = build_decl (input_location,
6664 CONST_DECL, NULL, TREE_TYPE (tmp));
6665 DECL_INITIAL (var) = tmp;
6666 TREE_STATIC (var) = 1;
6667 pushdecl (var);
6668 }
6669 else
6670 {
6671 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
6672 gfc_add_modify (&se->pre, var, se->expr);
6673 }
6674 gfc_add_block_to_block (&se->pre, &se->post);
6675
6676 /* Take the address of that value. */
6677 se->expr = gfc_build_addr_expr (NULL_TREE, var);
6678 if (expr->ts.type == BT_DERIVED && expr->rank
6679 && !gfc_is_finalizable (expr->ts.u.derived, NULL)
6680 && expr->ts.u.derived->attr.alloc_comp
6681 && expr->expr_type != EXPR_VARIABLE)
6682 {
6683 tree tmp;
6684
6685 tmp = build_fold_indirect_ref_loc (input_location, se->expr);
6686 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp, expr->rank);
6687
6688 /* The components shall be deallocated before
6689 their containing entity. */
6690 gfc_prepend_expr_to_block (&se->post, tmp);
6691 }
6692 }
6693
6694
6695 tree
6696 gfc_trans_pointer_assign (gfc_code * code)
6697 {
6698 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
6699 }
6700
6701
6702 /* Generate code for a pointer assignment. */
6703
6704 tree
6705 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
6706 {
6707 gfc_expr *expr1_vptr = NULL;
6708 gfc_se lse;
6709 gfc_se rse;
6710 stmtblock_t block;
6711 tree desc;
6712 tree tmp;
6713 tree decl;
6714 bool scalar;
6715 gfc_ss *ss;
6716
6717 gfc_start_block (&block);
6718
6719 gfc_init_se (&lse, NULL);
6720
6721 /* Check whether the expression is a scalar or not; we cannot use
6722 expr1->rank as it can be nonzero for proc pointers. */
6723 ss = gfc_walk_expr (expr1);
6724 scalar = ss == gfc_ss_terminator;
6725 if (!scalar)
6726 gfc_free_ss_chain (ss);
6727
6728 if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
6729 && expr2->expr_type != EXPR_FUNCTION)
6730 {
6731 gfc_add_data_component (expr2);
6732 /* The following is required as gfc_add_data_component doesn't
6733 update ts.type if there is a tailing REF_ARRAY. */
6734 expr2->ts.type = BT_DERIVED;
6735 }
6736
6737 if (scalar)
6738 {
6739 /* Scalar pointers. */
6740 lse.want_pointer = 1;
6741 gfc_conv_expr (&lse, expr1);
6742 gfc_init_se (&rse, NULL);
6743 rse.want_pointer = 1;
6744 gfc_conv_expr (&rse, expr2);
6745
6746 if (expr1->symtree->n.sym->attr.proc_pointer
6747 && expr1->symtree->n.sym->attr.dummy)
6748 lse.expr = build_fold_indirect_ref_loc (input_location,
6749 lse.expr);
6750
6751 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
6752 && expr2->symtree->n.sym->attr.dummy)
6753 rse.expr = build_fold_indirect_ref_loc (input_location,
6754 rse.expr);
6755
6756 gfc_add_block_to_block (&block, &lse.pre);
6757 gfc_add_block_to_block (&block, &rse.pre);
6758
6759 /* Check character lengths if character expression. The test is only
6760 really added if -fbounds-check is enabled. Exclude deferred
6761 character length lefthand sides. */
6762 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
6763 && !expr1->ts.deferred
6764 && !expr1->symtree->n.sym->attr.proc_pointer
6765 && !gfc_is_proc_ptr_comp (expr1))
6766 {
6767 gcc_assert (expr2->ts.type == BT_CHARACTER);
6768 gcc_assert (lse.string_length && rse.string_length);
6769 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
6770 lse.string_length, rse.string_length,
6771 &block);
6772 }
6773
6774 /* The assignment to an deferred character length sets the string
6775 length to that of the rhs. */
6776 if (expr1->ts.deferred)
6777 {
6778 if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
6779 gfc_add_modify (&block, lse.string_length, rse.string_length);
6780 else if (lse.string_length != NULL)
6781 gfc_add_modify (&block, lse.string_length,
6782 build_int_cst (gfc_charlen_type_node, 0));
6783 }
6784
6785 if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS)
6786 rse.expr = gfc_class_data_get (rse.expr);
6787
6788 gfc_add_modify (&block, lse.expr,
6789 fold_convert (TREE_TYPE (lse.expr), rse.expr));
6790
6791 gfc_add_block_to_block (&block, &rse.post);
6792 gfc_add_block_to_block (&block, &lse.post);
6793 }
6794 else
6795 {
6796 gfc_ref* remap;
6797 bool rank_remap;
6798 tree strlen_lhs;
6799 tree strlen_rhs = NULL_TREE;
6800
6801 /* Array pointer. Find the last reference on the LHS and if it is an
6802 array section ref, we're dealing with bounds remapping. In this case,
6803 set it to AR_FULL so that gfc_conv_expr_descriptor does
6804 not see it and process the bounds remapping afterwards explicitly. */
6805 for (remap = expr1->ref; remap; remap = remap->next)
6806 if (!remap->next && remap->type == REF_ARRAY
6807 && remap->u.ar.type == AR_SECTION)
6808 break;
6809 rank_remap = (remap && remap->u.ar.end[0]);
6810
6811 gfc_init_se (&lse, NULL);
6812 if (remap)
6813 lse.descriptor_only = 1;
6814 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS
6815 && expr1->ts.type == BT_CLASS)
6816 expr1_vptr = gfc_copy_expr (expr1);
6817 gfc_conv_expr_descriptor (&lse, expr1);
6818 strlen_lhs = lse.string_length;
6819 desc = lse.expr;
6820
6821 if (expr2->expr_type == EXPR_NULL)
6822 {
6823 /* Just set the data pointer to null. */
6824 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
6825 }
6826 else if (rank_remap)
6827 {
6828 /* If we are rank-remapping, just get the RHS's descriptor and
6829 process this later on. */
6830 gfc_init_se (&rse, NULL);
6831 rse.direct_byref = 1;
6832 rse.byref_noassign = 1;
6833
6834 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
6835 {
6836 gfc_conv_function_expr (&rse, expr2);
6837
6838 if (expr1->ts.type != BT_CLASS)
6839 rse.expr = gfc_class_data_get (rse.expr);
6840 else
6841 {
6842 tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
6843 gfc_add_modify (&lse.pre, tmp, rse.expr);
6844
6845 gfc_add_vptr_component (expr1_vptr);
6846 gfc_init_se (&rse, NULL);
6847 rse.want_pointer = 1;
6848 gfc_conv_expr (&rse, expr1_vptr);
6849 gfc_add_modify (&lse.pre, rse.expr,
6850 fold_convert (TREE_TYPE (rse.expr),
6851 gfc_class_vptr_get (tmp)));
6852 rse.expr = gfc_class_data_get (tmp);
6853 }
6854 }
6855 else if (expr2->expr_type == EXPR_FUNCTION)
6856 {
6857 tree bound[GFC_MAX_DIMENSIONS];
6858 int i;
6859
6860 for (i = 0; i < expr2->rank; i++)
6861 bound[i] = NULL_TREE;
6862 tmp = gfc_typenode_for_spec (&expr2->ts);
6863 tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
6864 bound, bound, 0,
6865 GFC_ARRAY_POINTER_CONT, false);
6866 tmp = gfc_create_var (tmp, "ptrtemp");
6867 lse.expr = tmp;
6868 lse.direct_byref = 1;
6869 gfc_conv_expr_descriptor (&lse, expr2);
6870 strlen_rhs = lse.string_length;
6871 rse.expr = tmp;
6872 }
6873 else
6874 {
6875 gfc_conv_expr_descriptor (&rse, expr2);
6876 strlen_rhs = rse.string_length;
6877 }
6878 }
6879 else if (expr2->expr_type == EXPR_VARIABLE)
6880 {
6881 /* Assign directly to the LHS's descriptor. */
6882 lse.direct_byref = 1;
6883 gfc_conv_expr_descriptor (&lse, expr2);
6884 strlen_rhs = lse.string_length;
6885
6886 /* If this is a subreference array pointer assignment, use the rhs
6887 descriptor element size for the lhs span. */
6888 if (expr1->symtree->n.sym->attr.subref_array_pointer)
6889 {
6890 decl = expr1->symtree->n.sym->backend_decl;
6891 gfc_init_se (&rse, NULL);
6892 rse.descriptor_only = 1;
6893 gfc_conv_expr (&rse, expr2);
6894 tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
6895 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
6896 if (!INTEGER_CST_P (tmp))
6897 gfc_add_block_to_block (&lse.post, &rse.pre);
6898 gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
6899 }
6900 }
6901 else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
6902 {
6903 gfc_init_se (&rse, NULL);
6904 rse.want_pointer = 1;
6905 gfc_conv_function_expr (&rse, expr2);
6906 if (expr1->ts.type != BT_CLASS)
6907 {
6908 rse.expr = gfc_class_data_get (rse.expr);
6909 gfc_add_modify (&lse.pre, desc, rse.expr);
6910 }
6911 else
6912 {
6913 tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
6914 gfc_add_modify (&lse.pre, tmp, rse.expr);
6915
6916 gfc_add_vptr_component (expr1_vptr);
6917 gfc_init_se (&rse, NULL);
6918 rse.want_pointer = 1;
6919 gfc_conv_expr (&rse, expr1_vptr);
6920 gfc_add_modify (&lse.pre, rse.expr,
6921 fold_convert (TREE_TYPE (rse.expr),
6922 gfc_class_vptr_get (tmp)));
6923 rse.expr = gfc_class_data_get (tmp);
6924 gfc_add_modify (&lse.pre, desc, rse.expr);
6925 }
6926 }
6927 else
6928 {
6929 /* Assign to a temporary descriptor and then copy that
6930 temporary to the pointer. */
6931 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
6932 lse.expr = tmp;
6933 lse.direct_byref = 1;
6934 gfc_conv_expr_descriptor (&lse, expr2);
6935 strlen_rhs = lse.string_length;
6936 gfc_add_modify (&lse.pre, desc, tmp);
6937 }
6938
6939 if (expr1_vptr)
6940 gfc_free_expr (expr1_vptr);
6941
6942 gfc_add_block_to_block (&block, &lse.pre);
6943 if (rank_remap)
6944 gfc_add_block_to_block (&block, &rse.pre);
6945
6946 /* If we do bounds remapping, update LHS descriptor accordingly. */
6947 if (remap)
6948 {
6949 int dim;
6950 gcc_assert (remap->u.ar.dimen == expr1->rank);
6951
6952 if (rank_remap)
6953 {
6954 /* Do rank remapping. We already have the RHS's descriptor
6955 converted in rse and now have to build the correct LHS
6956 descriptor for it. */
6957
6958 tree dtype, data;
6959 tree offs, stride;
6960 tree lbound, ubound;
6961
6962 /* Set dtype. */
6963 dtype = gfc_conv_descriptor_dtype (desc);
6964 tmp = gfc_get_dtype (TREE_TYPE (desc));
6965 gfc_add_modify (&block, dtype, tmp);
6966
6967 /* Copy data pointer. */
6968 data = gfc_conv_descriptor_data_get (rse.expr);
6969 gfc_conv_descriptor_data_set (&block, desc, data);
6970
6971 /* Copy offset but adjust it such that it would correspond
6972 to a lbound of zero. */
6973 offs = gfc_conv_descriptor_offset_get (rse.expr);
6974 for (dim = 0; dim < expr2->rank; ++dim)
6975 {
6976 stride = gfc_conv_descriptor_stride_get (rse.expr,
6977 gfc_rank_cst[dim]);
6978 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
6979 gfc_rank_cst[dim]);
6980 tmp = fold_build2_loc (input_location, MULT_EXPR,
6981 gfc_array_index_type, stride, lbound);
6982 offs = fold_build2_loc (input_location, PLUS_EXPR,
6983 gfc_array_index_type, offs, tmp);
6984 }
6985 gfc_conv_descriptor_offset_set (&block, desc, offs);
6986
6987 /* Set the bounds as declared for the LHS and calculate strides as
6988 well as another offset update accordingly. */
6989 stride = gfc_conv_descriptor_stride_get (rse.expr,
6990 gfc_rank_cst[0]);
6991 for (dim = 0; dim < expr1->rank; ++dim)
6992 {
6993 gfc_se lower_se;
6994 gfc_se upper_se;
6995
6996 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
6997
6998 /* Convert declared bounds. */
6999 gfc_init_se (&lower_se, NULL);
7000 gfc_init_se (&upper_se, NULL);
7001 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
7002 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
7003
7004 gfc_add_block_to_block (&block, &lower_se.pre);
7005 gfc_add_block_to_block (&block, &upper_se.pre);
7006
7007 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
7008 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
7009
7010 lbound = gfc_evaluate_now (lbound, &block);
7011 ubound = gfc_evaluate_now (ubound, &block);
7012
7013 gfc_add_block_to_block (&block, &lower_se.post);
7014 gfc_add_block_to_block (&block, &upper_se.post);
7015
7016 /* Set bounds in descriptor. */
7017 gfc_conv_descriptor_lbound_set (&block, desc,
7018 gfc_rank_cst[dim], lbound);
7019 gfc_conv_descriptor_ubound_set (&block, desc,
7020 gfc_rank_cst[dim], ubound);
7021
7022 /* Set stride. */
7023 stride = gfc_evaluate_now (stride, &block);
7024 gfc_conv_descriptor_stride_set (&block, desc,
7025 gfc_rank_cst[dim], stride);
7026
7027 /* Update offset. */
7028 offs = gfc_conv_descriptor_offset_get (desc);
7029 tmp = fold_build2_loc (input_location, MULT_EXPR,
7030 gfc_array_index_type, lbound, stride);
7031 offs = fold_build2_loc (input_location, MINUS_EXPR,
7032 gfc_array_index_type, offs, tmp);
7033 offs = gfc_evaluate_now (offs, &block);
7034 gfc_conv_descriptor_offset_set (&block, desc, offs);
7035
7036 /* Update stride. */
7037 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
7038 stride = fold_build2_loc (input_location, MULT_EXPR,
7039 gfc_array_index_type, stride, tmp);
7040 }
7041 }
7042 else
7043 {
7044 /* Bounds remapping. Just shift the lower bounds. */
7045
7046 gcc_assert (expr1->rank == expr2->rank);
7047
7048 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
7049 {
7050 gfc_se lbound_se;
7051
7052 gcc_assert (remap->u.ar.start[dim]);
7053 gcc_assert (!remap->u.ar.end[dim]);
7054 gfc_init_se (&lbound_se, NULL);
7055 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
7056
7057 gfc_add_block_to_block (&block, &lbound_se.pre);
7058 gfc_conv_shift_descriptor_lbound (&block, desc,
7059 dim, lbound_se.expr);
7060 gfc_add_block_to_block (&block, &lbound_se.post);
7061 }
7062 }
7063 }
7064
7065 /* Check string lengths if applicable. The check is only really added
7066 to the output code if -fbounds-check is enabled. */
7067 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
7068 {
7069 gcc_assert (expr2->ts.type == BT_CHARACTER);
7070 gcc_assert (strlen_lhs && strlen_rhs);
7071 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
7072 strlen_lhs, strlen_rhs, &block);
7073 }
7074
7075 /* If rank remapping was done, check with -fcheck=bounds that
7076 the target is at least as large as the pointer. */
7077 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
7078 {
7079 tree lsize, rsize;
7080 tree fault;
7081 const char* msg;
7082
7083 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
7084 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
7085
7086 lsize = gfc_evaluate_now (lsize, &block);
7087 rsize = gfc_evaluate_now (rsize, &block);
7088 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
7089 rsize, lsize);
7090
7091 msg = _("Target of rank remapping is too small (%ld < %ld)");
7092 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
7093 msg, rsize, lsize);
7094 }
7095
7096 gfc_add_block_to_block (&block, &lse.post);
7097 if (rank_remap)
7098 gfc_add_block_to_block (&block, &rse.post);
7099 }
7100
7101 return gfc_finish_block (&block);
7102 }
7103
7104
7105 /* Makes sure se is suitable for passing as a function string parameter. */
7106 /* TODO: Need to check all callers of this function. It may be abused. */
7107
7108 void
7109 gfc_conv_string_parameter (gfc_se * se)
7110 {
7111 tree type;
7112
7113 if (TREE_CODE (se->expr) == STRING_CST)
7114 {
7115 type = TREE_TYPE (TREE_TYPE (se->expr));
7116 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
7117 return;
7118 }
7119
7120 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
7121 {
7122 if (TREE_CODE (se->expr) != INDIRECT_REF)
7123 {
7124 type = TREE_TYPE (se->expr);
7125 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
7126 }
7127 else
7128 {
7129 type = gfc_get_character_type_len (gfc_default_character_kind,
7130 se->string_length);
7131 type = build_pointer_type (type);
7132 se->expr = gfc_build_addr_expr (type, se->expr);
7133 }
7134 }
7135
7136 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
7137 }
7138
7139
7140 /* Generate code for assignment of scalar variables. Includes character
7141 strings and derived types with allocatable components.
7142 If you know that the LHS has no allocations, set dealloc to false.
7143
7144 DEEP_COPY has no effect if the typespec TS is not a derived type with
7145 allocatable components. Otherwise, if it is set, an explicit copy of each
7146 allocatable component is made. This is necessary as a simple copy of the
7147 whole object would copy array descriptors as is, so that the lhs's
7148 allocatable components would point to the rhs's after the assignment.
7149 Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
7150 necessary if the rhs is a non-pointer function, as the allocatable components
7151 are not accessible by other means than the function's result after the
7152 function has returned. It is even more subtle when temporaries are involved,
7153 as the two following examples show:
7154 1. When we evaluate an array constructor, a temporary is created. Thus
7155 there is theoretically no alias possible. However, no deep copy is
7156 made for this temporary, so that if the constructor is made of one or
7157 more variable with allocatable components, those components still point
7158 to the variable's: DEEP_COPY should be set for the assignment from the
7159 temporary to the lhs in that case.
7160 2. When assigning a scalar to an array, we evaluate the scalar value out
7161 of the loop, store it into a temporary variable, and assign from that.
7162 In that case, deep copying when assigning to the temporary would be a
7163 waste of resources; however deep copies should happen when assigning from
7164 the temporary to each array element: again DEEP_COPY should be set for
7165 the assignment from the temporary to the lhs. */
7166
7167 tree
7168 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
7169 bool l_is_temp, bool deep_copy, bool dealloc)
7170 {
7171 stmtblock_t block;
7172 tree tmp;
7173 tree cond;
7174
7175 gfc_init_block (&block);
7176
7177 if (ts.type == BT_CHARACTER)
7178 {
7179 tree rlen = NULL;
7180 tree llen = NULL;
7181
7182 if (lse->string_length != NULL_TREE)
7183 {
7184 gfc_conv_string_parameter (lse);
7185 gfc_add_block_to_block (&block, &lse->pre);
7186 llen = lse->string_length;
7187 }
7188
7189 if (rse->string_length != NULL_TREE)
7190 {
7191 gcc_assert (rse->string_length != NULL_TREE);
7192 gfc_conv_string_parameter (rse);
7193 gfc_add_block_to_block (&block, &rse->pre);
7194 rlen = rse->string_length;
7195 }
7196
7197 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
7198 rse->expr, ts.kind);
7199 }
7200 else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
7201 {
7202 tree tmp_var = NULL_TREE;
7203 cond = NULL_TREE;
7204
7205 /* Are the rhs and the lhs the same? */
7206 if (deep_copy)
7207 {
7208 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
7209 gfc_build_addr_expr (NULL_TREE, lse->expr),
7210 gfc_build_addr_expr (NULL_TREE, rse->expr));
7211 cond = gfc_evaluate_now (cond, &lse->pre);
7212 }
7213
7214 /* Deallocate the lhs allocated components as long as it is not
7215 the same as the rhs. This must be done following the assignment
7216 to prevent deallocating data that could be used in the rhs
7217 expression. */
7218 if (!l_is_temp && dealloc)
7219 {
7220 tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
7221 tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
7222 if (deep_copy)
7223 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
7224 tmp);
7225 gfc_add_expr_to_block (&lse->post, tmp);
7226 }
7227
7228 gfc_add_block_to_block (&block, &rse->pre);
7229 gfc_add_block_to_block (&block, &lse->pre);
7230
7231 gfc_add_modify (&block, lse->expr,
7232 fold_convert (TREE_TYPE (lse->expr), rse->expr));
7233
7234 /* Restore pointer address of coarray components. */
7235 if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
7236 {
7237 tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
7238 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
7239 tmp);
7240 gfc_add_expr_to_block (&block, tmp);
7241 }
7242
7243 /* Do a deep copy if the rhs is a variable, if it is not the
7244 same as the lhs. */
7245 if (deep_copy)
7246 {
7247 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
7248 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
7249 tmp);
7250 gfc_add_expr_to_block (&block, tmp);
7251 }
7252 }
7253 else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
7254 {
7255 gfc_add_block_to_block (&block, &lse->pre);
7256 gfc_add_block_to_block (&block, &rse->pre);
7257 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
7258 TREE_TYPE (lse->expr), rse->expr);
7259 gfc_add_modify (&block, lse->expr, tmp);
7260 }
7261 else
7262 {
7263 gfc_add_block_to_block (&block, &lse->pre);
7264 gfc_add_block_to_block (&block, &rse->pre);
7265
7266 gfc_add_modify (&block, lse->expr,
7267 fold_convert (TREE_TYPE (lse->expr), rse->expr));
7268 }
7269
7270 gfc_add_block_to_block (&block, &lse->post);
7271 gfc_add_block_to_block (&block, &rse->post);
7272
7273 return gfc_finish_block (&block);
7274 }
7275
7276
7277 /* There are quite a lot of restrictions on the optimisation in using an
7278 array function assign without a temporary. */
7279
7280 static bool
7281 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
7282 {
7283 gfc_ref * ref;
7284 bool seen_array_ref;
7285 bool c = false;
7286 gfc_symbol *sym = expr1->symtree->n.sym;
7287
7288 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
7289 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
7290 return true;
7291
7292 /* Elemental functions are scalarized so that they don't need a
7293 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
7294 they would need special treatment in gfc_trans_arrayfunc_assign. */
7295 if (expr2->value.function.esym != NULL
7296 && expr2->value.function.esym->attr.elemental)
7297 return true;
7298
7299 /* Need a temporary if rhs is not FULL or a contiguous section. */
7300 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
7301 return true;
7302
7303 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
7304 if (gfc_ref_needs_temporary_p (expr1->ref))
7305 return true;
7306
7307 /* Functions returning pointers or allocatables need temporaries. */
7308 c = expr2->value.function.esym
7309 ? (expr2->value.function.esym->attr.pointer
7310 || expr2->value.function.esym->attr.allocatable)
7311 : (expr2->symtree->n.sym->attr.pointer
7312 || expr2->symtree->n.sym->attr.allocatable);
7313 if (c)
7314 return true;
7315
7316 /* Character array functions need temporaries unless the
7317 character lengths are the same. */
7318 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
7319 {
7320 if (expr1->ts.u.cl->length == NULL
7321 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
7322 return true;
7323
7324 if (expr2->ts.u.cl->length == NULL
7325 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
7326 return true;
7327
7328 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
7329 expr2->ts.u.cl->length->value.integer) != 0)
7330 return true;
7331 }
7332
7333 /* Check that no LHS component references appear during an array
7334 reference. This is needed because we do not have the means to
7335 span any arbitrary stride with an array descriptor. This check
7336 is not needed for the rhs because the function result has to be
7337 a complete type. */
7338 seen_array_ref = false;
7339 for (ref = expr1->ref; ref; ref = ref->next)
7340 {
7341 if (ref->type == REF_ARRAY)
7342 seen_array_ref= true;
7343 else if (ref->type == REF_COMPONENT && seen_array_ref)
7344 return true;
7345 }
7346
7347 /* Check for a dependency. */
7348 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
7349 expr2->value.function.esym,
7350 expr2->value.function.actual,
7351 NOT_ELEMENTAL))
7352 return true;
7353
7354 /* If we have reached here with an intrinsic function, we do not
7355 need a temporary except in the particular case that reallocation
7356 on assignment is active and the lhs is allocatable and a target. */
7357 if (expr2->value.function.isym)
7358 return (gfc_option.flag_realloc_lhs
7359 && sym->attr.allocatable
7360 && sym->attr.target);
7361
7362 /* If the LHS is a dummy, we need a temporary if it is not
7363 INTENT(OUT). */
7364 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
7365 return true;
7366
7367 /* If the lhs has been host_associated, is in common, a pointer or is
7368 a target and the function is not using a RESULT variable, aliasing
7369 can occur and a temporary is needed. */
7370 if ((sym->attr.host_assoc
7371 || sym->attr.in_common
7372 || sym->attr.pointer
7373 || sym->attr.cray_pointee
7374 || sym->attr.target)
7375 && expr2->symtree != NULL
7376 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
7377 return true;
7378
7379 /* A PURE function can unconditionally be called without a temporary. */
7380 if (expr2->value.function.esym != NULL
7381 && expr2->value.function.esym->attr.pure)
7382 return false;
7383
7384 /* Implicit_pure functions are those which could legally be declared
7385 to be PURE. */
7386 if (expr2->value.function.esym != NULL
7387 && expr2->value.function.esym->attr.implicit_pure)
7388 return false;
7389
7390 if (!sym->attr.use_assoc
7391 && !sym->attr.in_common
7392 && !sym->attr.pointer
7393 && !sym->attr.target
7394 && !sym->attr.cray_pointee
7395 && expr2->value.function.esym)
7396 {
7397 /* A temporary is not needed if the function is not contained and
7398 the variable is local or host associated and not a pointer or
7399 a target. */
7400 if (!expr2->value.function.esym->attr.contained)
7401 return false;
7402
7403 /* A temporary is not needed if the lhs has never been host
7404 associated and the procedure is contained. */
7405 else if (!sym->attr.host_assoc)
7406 return false;
7407
7408 /* A temporary is not needed if the variable is local and not
7409 a pointer, a target or a result. */
7410 if (sym->ns->parent
7411 && expr2->value.function.esym->ns == sym->ns->parent)
7412 return false;
7413 }
7414
7415 /* Default to temporary use. */
7416 return true;
7417 }
7418
7419
7420 /* Provide the loop info so that the lhs descriptor can be built for
7421 reallocatable assignments from extrinsic function calls. */
7422
7423 static void
7424 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
7425 gfc_loopinfo *loop)
7426 {
7427 /* Signal that the function call should not be made by
7428 gfc_conv_loop_setup. */
7429 se->ss->is_alloc_lhs = 1;
7430 gfc_init_loopinfo (loop);
7431 gfc_add_ss_to_loop (loop, *ss);
7432 gfc_add_ss_to_loop (loop, se->ss);
7433 gfc_conv_ss_startstride (loop);
7434 gfc_conv_loop_setup (loop, where);
7435 gfc_copy_loopinfo_to_se (se, loop);
7436 gfc_add_block_to_block (&se->pre, &loop->pre);
7437 gfc_add_block_to_block (&se->pre, &loop->post);
7438 se->ss->is_alloc_lhs = 0;
7439 }
7440
7441
7442 /* For assignment to a reallocatable lhs from intrinsic functions,
7443 replace the se.expr (ie. the result) with a temporary descriptor.
7444 Null the data field so that the library allocates space for the
7445 result. Free the data of the original descriptor after the function,
7446 in case it appears in an argument expression and transfer the
7447 result to the original descriptor. */
7448
7449 static void
7450 fcncall_realloc_result (gfc_se *se, int rank)
7451 {
7452 tree desc;
7453 tree res_desc;
7454 tree tmp;
7455 tree offset;
7456 tree zero_cond;
7457 int n;
7458
7459 /* Use the allocation done by the library. Substitute the lhs
7460 descriptor with a copy, whose data field is nulled.*/
7461 desc = build_fold_indirect_ref_loc (input_location, se->expr);
7462 if (POINTER_TYPE_P (TREE_TYPE (desc)))
7463 desc = build_fold_indirect_ref_loc (input_location, desc);
7464
7465 /* Unallocated, the descriptor does not have a dtype. */
7466 tmp = gfc_conv_descriptor_dtype (desc);
7467 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
7468
7469 res_desc = gfc_evaluate_now (desc, &se->pre);
7470 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
7471 se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
7472
7473 /* Free the lhs after the function call and copy the result data to
7474 the lhs descriptor. */
7475 tmp = gfc_conv_descriptor_data_get (desc);
7476 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
7477 boolean_type_node, tmp,
7478 build_int_cst (TREE_TYPE (tmp), 0));
7479 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
7480 tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
7481 gfc_add_expr_to_block (&se->post, tmp);
7482
7483 tmp = gfc_conv_descriptor_data_get (res_desc);
7484 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
7485
7486 /* Check that the shapes are the same between lhs and expression. */
7487 for (n = 0 ; n < rank; n++)
7488 {
7489 tree tmp1;
7490 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
7491 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
7492 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7493 gfc_array_index_type, tmp, tmp1);
7494 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
7495 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7496 gfc_array_index_type, tmp, tmp1);
7497 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
7498 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7499 gfc_array_index_type, tmp, tmp1);
7500 tmp = fold_build2_loc (input_location, NE_EXPR,
7501 boolean_type_node, tmp,
7502 gfc_index_zero_node);
7503 tmp = gfc_evaluate_now (tmp, &se->post);
7504 zero_cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
7505 boolean_type_node, tmp,
7506 zero_cond);
7507 }
7508
7509 /* 'zero_cond' being true is equal to lhs not being allocated or the
7510 shapes being different. */
7511 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
7512
7513 /* Now reset the bounds returned from the function call to bounds based
7514 on the lhs lbounds, except where the lhs is not allocated or the shapes
7515 of 'variable and 'expr' are different. Set the offset accordingly. */
7516 offset = gfc_index_zero_node;
7517 for (n = 0 ; n < rank; n++)
7518 {
7519 tree lbound;
7520
7521 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
7522 lbound = fold_build3_loc (input_location, COND_EXPR,
7523 gfc_array_index_type, zero_cond,
7524 gfc_index_one_node, lbound);
7525 lbound = gfc_evaluate_now (lbound, &se->post);
7526
7527 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
7528 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7529 gfc_array_index_type, tmp, lbound);
7530 gfc_conv_descriptor_lbound_set (&se->post, desc,
7531 gfc_rank_cst[n], lbound);
7532 gfc_conv_descriptor_ubound_set (&se->post, desc,
7533 gfc_rank_cst[n], tmp);
7534
7535 /* Set stride and accumulate the offset. */
7536 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
7537 gfc_conv_descriptor_stride_set (&se->post, desc,
7538 gfc_rank_cst[n], tmp);
7539 tmp = fold_build2_loc (input_location, MULT_EXPR,
7540 gfc_array_index_type, lbound, tmp);
7541 offset = fold_build2_loc (input_location, MINUS_EXPR,
7542 gfc_array_index_type, offset, tmp);
7543 offset = gfc_evaluate_now (offset, &se->post);
7544 }
7545
7546 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
7547 }
7548
7549
7550
7551 /* Try to translate array(:) = func (...), where func is a transformational
7552 array function, without using a temporary. Returns NULL if this isn't the
7553 case. */
7554
7555 static tree
7556 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
7557 {
7558 gfc_se se;
7559 gfc_ss *ss = NULL;
7560 gfc_component *comp = NULL;
7561 gfc_loopinfo loop;
7562
7563 if (arrayfunc_assign_needs_temporary (expr1, expr2))
7564 return NULL;
7565
7566 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
7567 functions. */
7568 comp = gfc_get_proc_ptr_comp (expr2);
7569 gcc_assert (expr2->value.function.isym
7570 || (comp && comp->attr.dimension)
7571 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
7572 && expr2->value.function.esym->result->attr.dimension));
7573
7574 gfc_init_se (&se, NULL);
7575 gfc_start_block (&se.pre);
7576 se.want_pointer = 1;
7577
7578 gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
7579
7580 if (expr1->ts.type == BT_DERIVED
7581 && expr1->ts.u.derived->attr.alloc_comp)
7582 {
7583 tree tmp;
7584 tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
7585 expr1->rank);
7586 gfc_add_expr_to_block (&se.pre, tmp);
7587 }
7588
7589 se.direct_byref = 1;
7590 se.ss = gfc_walk_expr (expr2);
7591 gcc_assert (se.ss != gfc_ss_terminator);
7592
7593 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
7594 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
7595 Clearly, this cannot be done for an allocatable function result, since
7596 the shape of the result is unknown and, in any case, the function must
7597 correctly take care of the reallocation internally. For intrinsic
7598 calls, the array data is freed and the library takes care of allocation.
7599 TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
7600 to the library. */
7601 if (gfc_option.flag_realloc_lhs
7602 && gfc_is_reallocatable_lhs (expr1)
7603 && !gfc_expr_attr (expr1).codimension
7604 && !gfc_is_coindexed (expr1)
7605 && !(expr2->value.function.esym
7606 && expr2->value.function.esym->result->attr.allocatable))
7607 {
7608 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
7609
7610 if (!expr2->value.function.isym)
7611 {
7612 ss = gfc_walk_expr (expr1);
7613 gcc_assert (ss != gfc_ss_terminator);
7614
7615 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
7616 ss->is_alloc_lhs = 1;
7617 }
7618 else
7619 fcncall_realloc_result (&se, expr1->rank);
7620 }
7621
7622 gfc_conv_function_expr (&se, expr2);
7623 gfc_add_block_to_block (&se.pre, &se.post);
7624
7625 if (ss)
7626 gfc_cleanup_loop (&loop);
7627 else
7628 gfc_free_ss_chain (se.ss);
7629
7630 return gfc_finish_block (&se.pre);
7631 }
7632
7633
7634 /* Try to efficiently translate array(:) = 0. Return NULL if this
7635 can't be done. */
7636
7637 static tree
7638 gfc_trans_zero_assign (gfc_expr * expr)
7639 {
7640 tree dest, len, type;
7641 tree tmp;
7642 gfc_symbol *sym;
7643
7644 sym = expr->symtree->n.sym;
7645 dest = gfc_get_symbol_decl (sym);
7646
7647 type = TREE_TYPE (dest);
7648 if (POINTER_TYPE_P (type))
7649 type = TREE_TYPE (type);
7650 if (!GFC_ARRAY_TYPE_P (type))
7651 return NULL_TREE;
7652
7653 /* Determine the length of the array. */
7654 len = GFC_TYPE_ARRAY_SIZE (type);
7655 if (!len || TREE_CODE (len) != INTEGER_CST)
7656 return NULL_TREE;
7657
7658 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
7659 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
7660 fold_convert (gfc_array_index_type, tmp));
7661
7662 /* If we are zeroing a local array avoid taking its address by emitting
7663 a = {} instead. */
7664 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
7665 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
7666 dest, build_constructor (TREE_TYPE (dest),
7667 NULL));
7668
7669 /* Convert arguments to the correct types. */
7670 dest = fold_convert (pvoid_type_node, dest);
7671 len = fold_convert (size_type_node, len);
7672
7673 /* Construct call to __builtin_memset. */
7674 tmp = build_call_expr_loc (input_location,
7675 builtin_decl_explicit (BUILT_IN_MEMSET),
7676 3, dest, integer_zero_node, len);
7677 return fold_convert (void_type_node, tmp);
7678 }
7679
7680
7681 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
7682 that constructs the call to __builtin_memcpy. */
7683
7684 tree
7685 gfc_build_memcpy_call (tree dst, tree src, tree len)
7686 {
7687 tree tmp;
7688
7689 /* Convert arguments to the correct types. */
7690 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
7691 dst = gfc_build_addr_expr (pvoid_type_node, dst);
7692 else
7693 dst = fold_convert (pvoid_type_node, dst);
7694
7695 if (!POINTER_TYPE_P (TREE_TYPE (src)))
7696 src = gfc_build_addr_expr (pvoid_type_node, src);
7697 else
7698 src = fold_convert (pvoid_type_node, src);
7699
7700 len = fold_convert (size_type_node, len);
7701
7702 /* Construct call to __builtin_memcpy. */
7703 tmp = build_call_expr_loc (input_location,
7704 builtin_decl_explicit (BUILT_IN_MEMCPY),
7705 3, dst, src, len);
7706 return fold_convert (void_type_node, tmp);
7707 }
7708
7709
7710 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
7711 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
7712 source/rhs, both are gfc_full_array_ref_p which have been checked for
7713 dependencies. */
7714
7715 static tree
7716 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
7717 {
7718 tree dst, dlen, dtype;
7719 tree src, slen, stype;
7720 tree tmp;
7721
7722 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
7723 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
7724
7725 dtype = TREE_TYPE (dst);
7726 if (POINTER_TYPE_P (dtype))
7727 dtype = TREE_TYPE (dtype);
7728 stype = TREE_TYPE (src);
7729 if (POINTER_TYPE_P (stype))
7730 stype = TREE_TYPE (stype);
7731
7732 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
7733 return NULL_TREE;
7734
7735 /* Determine the lengths of the arrays. */
7736 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
7737 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
7738 return NULL_TREE;
7739 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
7740 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7741 dlen, fold_convert (gfc_array_index_type, tmp));
7742
7743 slen = GFC_TYPE_ARRAY_SIZE (stype);
7744 if (!slen || TREE_CODE (slen) != INTEGER_CST)
7745 return NULL_TREE;
7746 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
7747 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7748 slen, fold_convert (gfc_array_index_type, tmp));
7749
7750 /* Sanity check that they are the same. This should always be
7751 the case, as we should already have checked for conformance. */
7752 if (!tree_int_cst_equal (slen, dlen))
7753 return NULL_TREE;
7754
7755 return gfc_build_memcpy_call (dst, src, dlen);
7756 }
7757
7758
7759 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
7760 this can't be done. EXPR1 is the destination/lhs for which
7761 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
7762
7763 static tree
7764 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
7765 {
7766 unsigned HOST_WIDE_INT nelem;
7767 tree dst, dtype;
7768 tree src, stype;
7769 tree len;
7770 tree tmp;
7771
7772 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
7773 if (nelem == 0)
7774 return NULL_TREE;
7775
7776 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
7777 dtype = TREE_TYPE (dst);
7778 if (POINTER_TYPE_P (dtype))
7779 dtype = TREE_TYPE (dtype);
7780 if (!GFC_ARRAY_TYPE_P (dtype))
7781 return NULL_TREE;
7782
7783 /* Determine the lengths of the array. */
7784 len = GFC_TYPE_ARRAY_SIZE (dtype);
7785 if (!len || TREE_CODE (len) != INTEGER_CST)
7786 return NULL_TREE;
7787
7788 /* Confirm that the constructor is the same size. */
7789 if (compare_tree_int (len, nelem) != 0)
7790 return NULL_TREE;
7791
7792 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
7793 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
7794 fold_convert (gfc_array_index_type, tmp));
7795
7796 stype = gfc_typenode_for_spec (&expr2->ts);
7797 src = gfc_build_constant_array_constructor (expr2, stype);
7798
7799 stype = TREE_TYPE (src);
7800 if (POINTER_TYPE_P (stype))
7801 stype = TREE_TYPE (stype);
7802
7803 return gfc_build_memcpy_call (dst, src, len);
7804 }
7805
7806
7807 /* Tells whether the expression is to be treated as a variable reference. */
7808
7809 static bool
7810 expr_is_variable (gfc_expr *expr)
7811 {
7812 gfc_expr *arg;
7813 gfc_component *comp;
7814 gfc_symbol *func_ifc;
7815
7816 if (expr->expr_type == EXPR_VARIABLE)
7817 return true;
7818
7819 arg = gfc_get_noncopying_intrinsic_argument (expr);
7820 if (arg)
7821 {
7822 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
7823 return expr_is_variable (arg);
7824 }
7825
7826 /* A data-pointer-returning function should be considered as a variable
7827 too. */
7828 if (expr->expr_type == EXPR_FUNCTION
7829 && expr->ref == NULL)
7830 {
7831 if (expr->value.function.isym != NULL)
7832 return false;
7833
7834 if (expr->value.function.esym != NULL)
7835 {
7836 func_ifc = expr->value.function.esym;
7837 goto found_ifc;
7838 }
7839 else
7840 {
7841 gcc_assert (expr->symtree);
7842 func_ifc = expr->symtree->n.sym;
7843 goto found_ifc;
7844 }
7845
7846 gcc_unreachable ();
7847 }
7848
7849 comp = gfc_get_proc_ptr_comp (expr);
7850 if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
7851 && comp)
7852 {
7853 func_ifc = comp->ts.interface;
7854 goto found_ifc;
7855 }
7856
7857 if (expr->expr_type == EXPR_COMPCALL)
7858 {
7859 gcc_assert (!expr->value.compcall.tbp->is_generic);
7860 func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
7861 goto found_ifc;
7862 }
7863
7864 return false;
7865
7866 found_ifc:
7867 gcc_assert (func_ifc->attr.function
7868 && func_ifc->result != NULL);
7869 return func_ifc->result->attr.pointer;
7870 }
7871
7872
7873 /* Is the lhs OK for automatic reallocation? */
7874
7875 static bool
7876 is_scalar_reallocatable_lhs (gfc_expr *expr)
7877 {
7878 gfc_ref * ref;
7879
7880 /* An allocatable variable with no reference. */
7881 if (expr->symtree->n.sym->attr.allocatable
7882 && !expr->ref)
7883 return true;
7884
7885 /* All that can be left are allocatable components. */
7886 if ((expr->symtree->n.sym->ts.type != BT_DERIVED
7887 && expr->symtree->n.sym->ts.type != BT_CLASS)
7888 || !expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
7889 return false;
7890
7891 /* Find an allocatable component ref last. */
7892 for (ref = expr->ref; ref; ref = ref->next)
7893 if (ref->type == REF_COMPONENT
7894 && !ref->next
7895 && ref->u.c.component->attr.allocatable)
7896 return true;
7897
7898 return false;
7899 }
7900
7901
7902 /* Allocate or reallocate scalar lhs, as necessary. */
7903
7904 static void
7905 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
7906 tree string_length,
7907 gfc_expr *expr1,
7908 gfc_expr *expr2)
7909
7910 {
7911 tree cond;
7912 tree tmp;
7913 tree size;
7914 tree size_in_bytes;
7915 tree jump_label1;
7916 tree jump_label2;
7917 gfc_se lse;
7918
7919 if (!expr1 || expr1->rank)
7920 return;
7921
7922 if (!expr2 || expr2->rank)
7923 return;
7924
7925 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
7926
7927 /* Since this is a scalar lhs, we can afford to do this. That is,
7928 there is no risk of side effects being repeated. */
7929 gfc_init_se (&lse, NULL);
7930 lse.want_pointer = 1;
7931 gfc_conv_expr (&lse, expr1);
7932
7933 jump_label1 = gfc_build_label_decl (NULL_TREE);
7934 jump_label2 = gfc_build_label_decl (NULL_TREE);
7935
7936 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
7937 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
7938 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7939 lse.expr, tmp);
7940 tmp = build3_v (COND_EXPR, cond,
7941 build1_v (GOTO_EXPR, jump_label1),
7942 build_empty_stmt (input_location));
7943 gfc_add_expr_to_block (block, tmp);
7944
7945 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7946 {
7947 /* Use the rhs string length and the lhs element size. */
7948 size = string_length;
7949 tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
7950 tmp = TYPE_SIZE_UNIT (tmp);
7951 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
7952 TREE_TYPE (tmp), tmp,
7953 fold_convert (TREE_TYPE (tmp), size));
7954 }
7955 else
7956 {
7957 /* Otherwise use the length in bytes of the rhs. */
7958 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
7959 size_in_bytes = size;
7960 }
7961
7962 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
7963 size_in_bytes, size_one_node);
7964
7965 if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
7966 {
7967 tmp = build_call_expr_loc (input_location,
7968 builtin_decl_explicit (BUILT_IN_CALLOC),
7969 2, build_one_cst (size_type_node),
7970 size_in_bytes);
7971 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
7972 gfc_add_modify (block, lse.expr, tmp);
7973 }
7974 else
7975 {
7976 tmp = build_call_expr_loc (input_location,
7977 builtin_decl_explicit (BUILT_IN_MALLOC),
7978 1, size_in_bytes);
7979 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
7980 gfc_add_modify (block, lse.expr, tmp);
7981 }
7982
7983 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7984 {
7985 /* Deferred characters need checking for lhs and rhs string
7986 length. Other deferred parameter variables will have to
7987 come here too. */
7988 tmp = build1_v (GOTO_EXPR, jump_label2);
7989 gfc_add_expr_to_block (block, tmp);
7990 }
7991 tmp = build1_v (LABEL_EXPR, jump_label1);
7992 gfc_add_expr_to_block (block, tmp);
7993
7994 /* For a deferred length character, reallocate if lengths of lhs and
7995 rhs are different. */
7996 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7997 {
7998 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
7999 expr1->ts.u.cl->backend_decl, size);
8000 /* Jump past the realloc if the lengths are the same. */
8001 tmp = build3_v (COND_EXPR, cond,
8002 build1_v (GOTO_EXPR, jump_label2),
8003 build_empty_stmt (input_location));
8004 gfc_add_expr_to_block (block, tmp);
8005 tmp = build_call_expr_loc (input_location,
8006 builtin_decl_explicit (BUILT_IN_REALLOC),
8007 2, fold_convert (pvoid_type_node, lse.expr),
8008 size_in_bytes);
8009 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
8010 gfc_add_modify (block, lse.expr, tmp);
8011 tmp = build1_v (LABEL_EXPR, jump_label2);
8012 gfc_add_expr_to_block (block, tmp);
8013
8014 /* Update the lhs character length. */
8015 size = string_length;
8016 if (TREE_CODE (expr1->ts.u.cl->backend_decl) == VAR_DECL)
8017 gfc_add_modify (block, expr1->ts.u.cl->backend_decl, size);
8018 else
8019 gfc_add_modify (block, lse.string_length, size);
8020 }
8021 }
8022
8023 /* Check for assignments of the type
8024
8025 a = a + 4
8026
8027 to make sure we do not check for reallocation unneccessarily. */
8028
8029
8030 static bool
8031 is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
8032 {
8033 gfc_actual_arglist *a;
8034 gfc_expr *e1, *e2;
8035
8036 switch (expr2->expr_type)
8037 {
8038 case EXPR_VARIABLE:
8039 return gfc_dep_compare_expr (expr1, expr2) == 0;
8040
8041 case EXPR_FUNCTION:
8042 if (expr2->value.function.esym
8043 && expr2->value.function.esym->attr.elemental)
8044 {
8045 for (a = expr2->value.function.actual; a != NULL; a = a->next)
8046 {
8047 e1 = a->expr;
8048 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
8049 return false;
8050 }
8051 return true;
8052 }
8053 else if (expr2->value.function.isym
8054 && expr2->value.function.isym->elemental)
8055 {
8056 for (a = expr2->value.function.actual; a != NULL; a = a->next)
8057 {
8058 e1 = a->expr;
8059 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
8060 return false;
8061 }
8062 return true;
8063 }
8064
8065 break;
8066
8067 case EXPR_OP:
8068 switch (expr2->value.op.op)
8069 {
8070 case INTRINSIC_NOT:
8071 case INTRINSIC_UPLUS:
8072 case INTRINSIC_UMINUS:
8073 case INTRINSIC_PARENTHESES:
8074 return is_runtime_conformable (expr1, expr2->value.op.op1);
8075
8076 case INTRINSIC_PLUS:
8077 case INTRINSIC_MINUS:
8078 case INTRINSIC_TIMES:
8079 case INTRINSIC_DIVIDE:
8080 case INTRINSIC_POWER:
8081 case INTRINSIC_AND:
8082 case INTRINSIC_OR:
8083 case INTRINSIC_EQV:
8084 case INTRINSIC_NEQV:
8085 case INTRINSIC_EQ:
8086 case INTRINSIC_NE:
8087 case INTRINSIC_GT:
8088 case INTRINSIC_GE:
8089 case INTRINSIC_LT:
8090 case INTRINSIC_LE:
8091 case INTRINSIC_EQ_OS:
8092 case INTRINSIC_NE_OS:
8093 case INTRINSIC_GT_OS:
8094 case INTRINSIC_GE_OS:
8095 case INTRINSIC_LT_OS:
8096 case INTRINSIC_LE_OS:
8097
8098 e1 = expr2->value.op.op1;
8099 e2 = expr2->value.op.op2;
8100
8101 if (e1->rank == 0 && e2->rank > 0)
8102 return is_runtime_conformable (expr1, e2);
8103 else if (e1->rank > 0 && e2->rank == 0)
8104 return is_runtime_conformable (expr1, e1);
8105 else if (e1->rank > 0 && e2->rank > 0)
8106 return is_runtime_conformable (expr1, e1)
8107 && is_runtime_conformable (expr1, e2);
8108 break;
8109
8110 default:
8111 break;
8112
8113 }
8114
8115 break;
8116
8117 default:
8118 break;
8119 }
8120 return false;
8121 }
8122
8123 /* Subroutine of gfc_trans_assignment that actually scalarizes the
8124 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
8125 init_flag indicates initialization expressions and dealloc that no
8126 deallocate prior assignment is needed (if in doubt, set true). */
8127
8128 static tree
8129 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
8130 bool dealloc)
8131 {
8132 gfc_se lse;
8133 gfc_se rse;
8134 gfc_ss *lss;
8135 gfc_ss *lss_section;
8136 gfc_ss *rss;
8137 gfc_loopinfo loop;
8138 tree tmp;
8139 stmtblock_t block;
8140 stmtblock_t body;
8141 bool l_is_temp;
8142 bool scalar_to_array;
8143 tree string_length;
8144 int n;
8145
8146 /* Assignment of the form lhs = rhs. */
8147 gfc_start_block (&block);
8148
8149 gfc_init_se (&lse, NULL);
8150 gfc_init_se (&rse, NULL);
8151
8152 /* Walk the lhs. */
8153 lss = gfc_walk_expr (expr1);
8154 if (gfc_is_reallocatable_lhs (expr1)
8155 && !(expr2->expr_type == EXPR_FUNCTION
8156 && expr2->value.function.isym != NULL))
8157 lss->is_alloc_lhs = 1;
8158 rss = NULL;
8159 if (lss != gfc_ss_terminator)
8160 {
8161 /* The assignment needs scalarization. */
8162 lss_section = lss;
8163
8164 /* Find a non-scalar SS from the lhs. */
8165 while (lss_section != gfc_ss_terminator
8166 && lss_section->info->type != GFC_SS_SECTION)
8167 lss_section = lss_section->next;
8168
8169 gcc_assert (lss_section != gfc_ss_terminator);
8170
8171 /* Initialize the scalarizer. */
8172 gfc_init_loopinfo (&loop);
8173
8174 /* Walk the rhs. */
8175 rss = gfc_walk_expr (expr2);
8176 if (rss == gfc_ss_terminator)
8177 /* The rhs is scalar. Add a ss for the expression. */
8178 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
8179
8180 /* Associate the SS with the loop. */
8181 gfc_add_ss_to_loop (&loop, lss);
8182 gfc_add_ss_to_loop (&loop, rss);
8183
8184 /* Calculate the bounds of the scalarization. */
8185 gfc_conv_ss_startstride (&loop);
8186 /* Enable loop reversal. */
8187 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
8188 loop.reverse[n] = GFC_ENABLE_REVERSE;
8189 /* Resolve any data dependencies in the statement. */
8190 gfc_conv_resolve_dependencies (&loop, lss, rss);
8191 /* Setup the scalarizing loops. */
8192 gfc_conv_loop_setup (&loop, &expr2->where);
8193
8194 /* Setup the gfc_se structures. */
8195 gfc_copy_loopinfo_to_se (&lse, &loop);
8196 gfc_copy_loopinfo_to_se (&rse, &loop);
8197
8198 rse.ss = rss;
8199 gfc_mark_ss_chain_used (rss, 1);
8200 if (loop.temp_ss == NULL)
8201 {
8202 lse.ss = lss;
8203 gfc_mark_ss_chain_used (lss, 1);
8204 }
8205 else
8206 {
8207 lse.ss = loop.temp_ss;
8208 gfc_mark_ss_chain_used (lss, 3);
8209 gfc_mark_ss_chain_used (loop.temp_ss, 3);
8210 }
8211
8212 /* Allow the scalarizer to workshare array assignments. */
8213 if ((ompws_flags & OMPWS_WORKSHARE_FLAG) && loop.temp_ss == NULL)
8214 ompws_flags |= OMPWS_SCALARIZER_WS;
8215
8216 /* Start the scalarized loop body. */
8217 gfc_start_scalarized_body (&loop, &body);
8218 }
8219 else
8220 gfc_init_block (&body);
8221
8222 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
8223
8224 /* Translate the expression. */
8225 gfc_conv_expr (&rse, expr2);
8226
8227 /* Stabilize a string length for temporaries. */
8228 if (expr2->ts.type == BT_CHARACTER)
8229 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
8230 else
8231 string_length = NULL_TREE;
8232
8233 if (l_is_temp)
8234 {
8235 gfc_conv_tmp_array_ref (&lse);
8236 if (expr2->ts.type == BT_CHARACTER)
8237 lse.string_length = string_length;
8238 }
8239 else
8240 gfc_conv_expr (&lse, expr1);
8241
8242 /* Assignments of scalar derived types with allocatable components
8243 to arrays must be done with a deep copy and the rhs temporary
8244 must have its components deallocated afterwards. */
8245 scalar_to_array = (expr2->ts.type == BT_DERIVED
8246 && expr2->ts.u.derived->attr.alloc_comp
8247 && !expr_is_variable (expr2)
8248 && !gfc_is_constant_expr (expr2)
8249 && expr1->rank && !expr2->rank);
8250 if (scalar_to_array && dealloc)
8251 {
8252 tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
8253 gfc_add_expr_to_block (&loop.post, tmp);
8254 }
8255
8256 /* When assigning a character function result to a deferred-length variable,
8257 the function call must happen before the (re)allocation of the lhs -
8258 otherwise the character length of the result is not known.
8259 NOTE: This relies on having the exact dependence of the length type
8260 parameter available to the caller; gfortran saves it in the .mod files. */
8261 if (gfc_option.flag_realloc_lhs && expr2->ts.type == BT_CHARACTER
8262 && expr1->ts.deferred)
8263 gfc_add_block_to_block (&block, &rse.pre);
8264
8265 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
8266 l_is_temp || init_flag,
8267 expr_is_variable (expr2) || scalar_to_array
8268 || expr2->expr_type == EXPR_ARRAY, dealloc);
8269 gfc_add_expr_to_block (&body, tmp);
8270
8271 if (lss == gfc_ss_terminator)
8272 {
8273 /* F2003: Add the code for reallocation on assignment. */
8274 if (gfc_option.flag_realloc_lhs
8275 && is_scalar_reallocatable_lhs (expr1))
8276 alloc_scalar_allocatable_for_assignment (&block, rse.string_length,
8277 expr1, expr2);
8278
8279 /* Use the scalar assignment as is. */
8280 gfc_add_block_to_block (&block, &body);
8281 }
8282 else
8283 {
8284 gcc_assert (lse.ss == gfc_ss_terminator
8285 && rse.ss == gfc_ss_terminator);
8286
8287 if (l_is_temp)
8288 {
8289 gfc_trans_scalarized_loop_boundary (&loop, &body);
8290
8291 /* We need to copy the temporary to the actual lhs. */
8292 gfc_init_se (&lse, NULL);
8293 gfc_init_se (&rse, NULL);
8294 gfc_copy_loopinfo_to_se (&lse, &loop);
8295 gfc_copy_loopinfo_to_se (&rse, &loop);
8296
8297 rse.ss = loop.temp_ss;
8298 lse.ss = lss;
8299
8300 gfc_conv_tmp_array_ref (&rse);
8301 gfc_conv_expr (&lse, expr1);
8302
8303 gcc_assert (lse.ss == gfc_ss_terminator
8304 && rse.ss == gfc_ss_terminator);
8305
8306 if (expr2->ts.type == BT_CHARACTER)
8307 rse.string_length = string_length;
8308
8309 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
8310 false, false, dealloc);
8311 gfc_add_expr_to_block (&body, tmp);
8312 }
8313
8314 /* F2003: Allocate or reallocate lhs of allocatable array. */
8315 if (gfc_option.flag_realloc_lhs
8316 && gfc_is_reallocatable_lhs (expr1)
8317 && !gfc_expr_attr (expr1).codimension
8318 && !gfc_is_coindexed (expr1)
8319 && expr2->rank
8320 && !is_runtime_conformable (expr1, expr2))
8321 {
8322 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
8323 ompws_flags &= ~OMPWS_SCALARIZER_WS;
8324 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
8325 if (tmp != NULL_TREE)
8326 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
8327 }
8328
8329 /* Generate the copying loops. */
8330 gfc_trans_scalarizing_loops (&loop, &body);
8331
8332 /* Wrap the whole thing up. */
8333 gfc_add_block_to_block (&block, &loop.pre);
8334 gfc_add_block_to_block (&block, &loop.post);
8335
8336 gfc_cleanup_loop (&loop);
8337 }
8338
8339 return gfc_finish_block (&block);
8340 }
8341
8342
8343 /* Check whether EXPR is a copyable array. */
8344
8345 static bool
8346 copyable_array_p (gfc_expr * expr)
8347 {
8348 if (expr->expr_type != EXPR_VARIABLE)
8349 return false;
8350
8351 /* First check it's an array. */
8352 if (expr->rank < 1 || !expr->ref || expr->ref->next)
8353 return false;
8354
8355 if (!gfc_full_array_ref_p (expr->ref, NULL))
8356 return false;
8357
8358 /* Next check that it's of a simple enough type. */
8359 switch (expr->ts.type)
8360 {
8361 case BT_INTEGER:
8362 case BT_REAL:
8363 case BT_COMPLEX:
8364 case BT_LOGICAL:
8365 return true;
8366
8367 case BT_CHARACTER:
8368 return false;
8369
8370 case BT_DERIVED:
8371 return !expr->ts.u.derived->attr.alloc_comp;
8372
8373 default:
8374 break;
8375 }
8376
8377 return false;
8378 }
8379
8380 /* Translate an assignment. */
8381
8382 tree
8383 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
8384 bool dealloc)
8385 {
8386 tree tmp;
8387
8388 /* Special case a single function returning an array. */
8389 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
8390 {
8391 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
8392 if (tmp)
8393 return tmp;
8394 }
8395
8396 /* Special case assigning an array to zero. */
8397 if (copyable_array_p (expr1)
8398 && is_zero_initializer_p (expr2))
8399 {
8400 tmp = gfc_trans_zero_assign (expr1);
8401 if (tmp)
8402 return tmp;
8403 }
8404
8405 /* Special case copying one array to another. */
8406 if (copyable_array_p (expr1)
8407 && copyable_array_p (expr2)
8408 && gfc_compare_types (&expr1->ts, &expr2->ts)
8409 && !gfc_check_dependency (expr1, expr2, 0))
8410 {
8411 tmp = gfc_trans_array_copy (expr1, expr2);
8412 if (tmp)
8413 return tmp;
8414 }
8415
8416 /* Special case initializing an array from a constant array constructor. */
8417 if (copyable_array_p (expr1)
8418 && expr2->expr_type == EXPR_ARRAY
8419 && gfc_compare_types (&expr1->ts, &expr2->ts))
8420 {
8421 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
8422 if (tmp)
8423 return tmp;
8424 }
8425
8426 /* Fallback to the scalarizer to generate explicit loops. */
8427 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc);
8428 }
8429
8430 tree
8431 gfc_trans_init_assign (gfc_code * code)
8432 {
8433 return gfc_trans_assignment (code->expr1, code->expr2, true, false);
8434 }
8435
8436 tree
8437 gfc_trans_assign (gfc_code * code)
8438 {
8439 return gfc_trans_assignment (code->expr1, code->expr2, false, true);
8440 }