2013-01-08 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / fortran / trans-expr.c
blob7b41c65a374f98f42c912ce0efcb2456858c5ec9
1 /* Expression translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
3 2011, 2012, 2013
4 Free Software Foundation, Inc.
5 Contributed by Paul Brook <paul@nowt.org>
6 and Steven Bosscher <s.bosscher@student.tudelft.nl>
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 /* trans-expr.c-- generate GENERIC trees for gfc_expr. */
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tree.h"
30 #include "diagnostic-core.h" /* For fatal_error. */
31 #include "langhooks.h"
32 #include "flags.h"
33 #include "gfortran.h"
34 #include "arith.h"
35 #include "constructor.h"
36 #include "trans.h"
37 #include "trans-const.h"
38 #include "trans-types.h"
39 #include "trans-array.h"
40 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
41 #include "trans-stmt.h"
42 #include "dependency.h"
45 /* Convert a scalar to an array descriptor. To be used for assumed-rank
46 arrays. */
48 static tree
49 get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
51 enum gfc_array_kind akind;
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;
60 return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
61 akind, !(attr.pointer || attr.target));
64 tree
65 gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
67 tree desc, type;
69 type = get_scalar_to_descriptor_type (scalar, attr);
70 desc = gfc_create_var (type, "desc");
71 DECL_ARTIFICIAL (desc) = 1;
72 gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
73 gfc_get_dtype (type));
74 gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
76 /* Copy pointer address back - but only if it could have changed and
77 if the actual argument is a pointer and not, e.g., NULL(). */
78 if ((attr.pointer || attr.allocatable)
79 && attr.intent != INTENT_IN && POINTER_TYPE_P (TREE_TYPE (scalar)))
80 gfc_add_modify (&se->post, scalar,
81 fold_convert (TREE_TYPE (scalar),
82 gfc_conv_descriptor_data_get (desc)));
83 return desc;
87 /* This is the seed for an eventual trans-class.c
89 The following parameters should not be used directly since they might
90 in future implementations. Use the corresponding APIs. */
91 #define CLASS_DATA_FIELD 0
92 #define CLASS_VPTR_FIELD 1
93 #define VTABLE_HASH_FIELD 0
94 #define VTABLE_SIZE_FIELD 1
95 #define VTABLE_EXTENDS_FIELD 2
96 #define VTABLE_DEF_INIT_FIELD 3
97 #define VTABLE_COPY_FIELD 4
98 #define VTABLE_FINAL_FIELD 5
101 tree
102 gfc_class_data_get (tree decl)
104 tree data;
105 if (POINTER_TYPE_P (TREE_TYPE (decl)))
106 decl = build_fold_indirect_ref_loc (input_location, decl);
107 data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
108 CLASS_DATA_FIELD);
109 return fold_build3_loc (input_location, COMPONENT_REF,
110 TREE_TYPE (data), decl, data,
111 NULL_TREE);
115 tree
116 gfc_class_vptr_get (tree decl)
118 tree vptr;
119 if (POINTER_TYPE_P (TREE_TYPE (decl)))
120 decl = build_fold_indirect_ref_loc (input_location, decl);
121 vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
122 CLASS_VPTR_FIELD);
123 return fold_build3_loc (input_location, COMPONENT_REF,
124 TREE_TYPE (vptr), decl, vptr,
125 NULL_TREE);
129 static tree
130 gfc_vtable_field_get (tree decl, int field)
132 tree size;
133 tree vptr;
134 vptr = gfc_class_vptr_get (decl);
135 vptr = build_fold_indirect_ref_loc (input_location, vptr);
136 size = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
137 field);
138 size = fold_build3_loc (input_location, COMPONENT_REF,
139 TREE_TYPE (size), vptr, size,
140 NULL_TREE);
141 /* Always return size as an array index type. */
142 if (field == VTABLE_SIZE_FIELD)
143 size = fold_convert (gfc_array_index_type, size);
144 gcc_assert (size);
145 return size;
149 tree
150 gfc_vtable_hash_get (tree decl)
152 return gfc_vtable_field_get (decl, VTABLE_HASH_FIELD);
156 tree
157 gfc_vtable_size_get (tree decl)
159 return gfc_vtable_field_get (decl, VTABLE_SIZE_FIELD);
163 tree
164 gfc_vtable_extends_get (tree decl)
166 return gfc_vtable_field_get (decl, VTABLE_EXTENDS_FIELD);
170 tree
171 gfc_vtable_def_init_get (tree decl)
173 return gfc_vtable_field_get (decl, VTABLE_DEF_INIT_FIELD);
177 tree
178 gfc_vtable_copy_get (tree decl)
180 return gfc_vtable_field_get (decl, VTABLE_COPY_FIELD);
184 tree
185 gfc_vtable_final_get (tree decl)
187 return gfc_vtable_field_get (decl, VTABLE_FINAL_FIELD);
191 #undef CLASS_DATA_FIELD
192 #undef CLASS_VPTR_FIELD
193 #undef VTABLE_HASH_FIELD
194 #undef VTABLE_SIZE_FIELD
195 #undef VTABLE_EXTENDS_FIELD
196 #undef VTABLE_DEF_INIT_FIELD
197 #undef VTABLE_COPY_FIELD
198 #undef VTABLE_FINAL_FIELD
201 /* Obtain the vptr of the last class reference in an expression.
202 Return NULL_TREE if no class reference is found. */
204 tree
205 gfc_get_vptr_from_expr (tree expr)
207 tree tmp;
208 tree type;
210 for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
212 type = TREE_TYPE (tmp);
213 while (type)
215 if (GFC_CLASS_TYPE_P (type))
216 return gfc_class_vptr_get (tmp);
217 if (type != TYPE_CANONICAL (type))
218 type = TYPE_CANONICAL (type);
219 else
220 type = NULL_TREE;
222 if (TREE_CODE (tmp) == VAR_DECL)
223 break;
225 return NULL_TREE;
229 static void
230 class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
231 bool lhs_type)
233 tree tmp, tmp2, type;
235 gfc_conv_descriptor_data_set (block, lhs_desc,
236 gfc_conv_descriptor_data_get (rhs_desc));
237 gfc_conv_descriptor_offset_set (block, lhs_desc,
238 gfc_conv_descriptor_offset_get (rhs_desc));
240 gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
241 gfc_conv_descriptor_dtype (rhs_desc));
243 /* Assign the dimension as range-ref. */
244 tmp = gfc_get_descriptor_dimension (lhs_desc);
245 tmp2 = gfc_get_descriptor_dimension (rhs_desc);
247 type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
248 tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
249 gfc_index_zero_node, NULL_TREE, NULL_TREE);
250 tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
251 gfc_index_zero_node, NULL_TREE, NULL_TREE);
252 gfc_add_modify (block, tmp, tmp2);
256 /* Takes a derived type expression and returns the address of a temporary
257 class object of the 'declared' type. If vptr is not NULL, this is
258 used for the temporary class object.
259 optional_alloc_ptr is false when the dummy is neither allocatable
260 nor a pointer; that's only relevant for the optional handling. */
261 void
262 gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
263 gfc_typespec class_ts, tree vptr, bool optional,
264 bool optional_alloc_ptr)
266 gfc_symbol *vtab;
267 tree cond_optional = NULL_TREE;
268 gfc_ss *ss;
269 tree ctree;
270 tree var;
271 tree tmp;
273 /* The derived type needs to be converted to a temporary
274 CLASS object. */
275 tmp = gfc_typenode_for_spec (&class_ts);
276 var = gfc_create_var (tmp, "class");
278 /* Set the vptr. */
279 ctree = gfc_class_vptr_get (var);
281 if (vptr != NULL_TREE)
283 /* Use the dynamic vptr. */
284 tmp = vptr;
286 else
288 /* In this case the vtab corresponds to the derived type and the
289 vptr must point to it. */
290 vtab = gfc_find_derived_vtab (e->ts.u.derived);
291 gcc_assert (vtab);
292 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
294 gfc_add_modify (&parmse->pre, ctree,
295 fold_convert (TREE_TYPE (ctree), tmp));
297 /* Now set the data field. */
298 ctree = gfc_class_data_get (var);
300 if (optional)
301 cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
303 if (parmse->ss && parmse->ss->info->useflags)
305 /* For an array reference in an elemental procedure call we need
306 to retain the ss to provide the scalarized array reference. */
307 gfc_conv_expr_reference (parmse, e);
308 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
309 if (optional)
310 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
311 cond_optional, tmp,
312 fold_convert (TREE_TYPE (tmp), null_pointer_node));
313 gfc_add_modify (&parmse->pre, ctree, tmp);
316 else
318 ss = gfc_walk_expr (e);
319 if (ss == gfc_ss_terminator)
321 parmse->ss = NULL;
322 gfc_conv_expr_reference (parmse, e);
324 /* Scalar to an assumed-rank array. */
325 if (class_ts.u.derived->components->as)
327 tree type;
328 type = get_scalar_to_descriptor_type (parmse->expr,
329 gfc_expr_attr (e));
330 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
331 gfc_get_dtype (type));
332 if (optional)
333 parmse->expr = build3_loc (input_location, COND_EXPR,
334 TREE_TYPE (parmse->expr),
335 cond_optional, parmse->expr,
336 fold_convert (TREE_TYPE (parmse->expr),
337 null_pointer_node));
338 gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
340 else
342 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
343 if (optional)
344 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
345 cond_optional, tmp,
346 fold_convert (TREE_TYPE (tmp),
347 null_pointer_node));
348 gfc_add_modify (&parmse->pre, ctree, tmp);
351 else
353 stmtblock_t block;
354 gfc_init_block (&block);
356 parmse->ss = ss;
357 gfc_conv_expr_descriptor (parmse, e);
359 if (e->rank != class_ts.u.derived->components->as->rank)
360 class_array_data_assign (&block, ctree, parmse->expr, true);
361 else
363 if (gfc_expr_attr (e).codimension)
364 parmse->expr = fold_build1_loc (input_location,
365 VIEW_CONVERT_EXPR,
366 TREE_TYPE (ctree),
367 parmse->expr);
368 gfc_add_modify (&block, ctree, parmse->expr);
371 if (optional)
373 tmp = gfc_finish_block (&block);
375 gfc_init_block (&block);
376 gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
378 tmp = build3_v (COND_EXPR, cond_optional, tmp,
379 gfc_finish_block (&block));
380 gfc_add_expr_to_block (&parmse->pre, tmp);
382 else
383 gfc_add_block_to_block (&parmse->pre, &block);
387 /* Pass the address of the class object. */
388 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
390 if (optional && optional_alloc_ptr)
391 parmse->expr = build3_loc (input_location, COND_EXPR,
392 TREE_TYPE (parmse->expr),
393 cond_optional, parmse->expr,
394 fold_convert (TREE_TYPE (parmse->expr),
395 null_pointer_node));
399 /* Create a new class container, which is required as scalar coarrays
400 have an array descriptor while normal scalars haven't. Optionally,
401 NULL pointer checks are added if the argument is OPTIONAL. */
403 static void
404 class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
405 gfc_typespec class_ts, bool optional)
407 tree var, ctree, tmp;
408 stmtblock_t block;
409 gfc_ref *ref;
410 gfc_ref *class_ref;
412 gfc_init_block (&block);
414 class_ref = NULL;
415 for (ref = e->ref; ref; ref = ref->next)
417 if (ref->type == REF_COMPONENT
418 && ref->u.c.component->ts.type == BT_CLASS)
419 class_ref = ref;
422 if (class_ref == NULL
423 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
424 tmp = e->symtree->n.sym->backend_decl;
425 else
427 /* Remove everything after the last class reference, convert the
428 expression and then recover its tailend once more. */
429 gfc_se tmpse;
430 ref = class_ref->next;
431 class_ref->next = NULL;
432 gfc_init_se (&tmpse, NULL);
433 gfc_conv_expr (&tmpse, e);
434 class_ref->next = ref;
435 tmp = tmpse.expr;
438 var = gfc_typenode_for_spec (&class_ts);
439 var = gfc_create_var (var, "class");
441 ctree = gfc_class_vptr_get (var);
442 gfc_add_modify (&block, ctree,
443 fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
445 ctree = gfc_class_data_get (var);
446 tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
447 gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
449 /* Pass the address of the class object. */
450 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
452 if (optional)
454 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
455 tree tmp2;
457 tmp = gfc_finish_block (&block);
459 gfc_init_block (&block);
460 tmp2 = gfc_class_data_get (var);
461 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
462 null_pointer_node));
463 tmp2 = gfc_finish_block (&block);
465 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
466 cond, tmp, tmp2);
467 gfc_add_expr_to_block (&parmse->pre, tmp);
469 else
470 gfc_add_block_to_block (&parmse->pre, &block);
474 /* Takes an intrinsic type expression and returns the address of a temporary
475 class object of the 'declared' type. */
476 void
477 gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
478 gfc_typespec class_ts)
480 gfc_symbol *vtab;
481 gfc_ss *ss;
482 tree ctree;
483 tree var;
484 tree tmp;
486 /* The intrinsic type needs to be converted to a temporary
487 CLASS object. */
488 tmp = gfc_typenode_for_spec (&class_ts);
489 var = gfc_create_var (tmp, "class");
491 /* Set the vptr. */
492 ctree = gfc_class_vptr_get (var);
494 vtab = gfc_find_intrinsic_vtab (&e->ts);
495 gcc_assert (vtab);
496 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
497 gfc_add_modify (&parmse->pre, ctree,
498 fold_convert (TREE_TYPE (ctree), tmp));
500 /* Now set the data field. */
501 ctree = gfc_class_data_get (var);
502 if (parmse->ss && parmse->ss->info->useflags)
504 /* For an array reference in an elemental procedure call we need
505 to retain the ss to provide the scalarized array reference. */
506 gfc_conv_expr_reference (parmse, e);
507 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
508 gfc_add_modify (&parmse->pre, ctree, tmp);
510 else
512 ss = gfc_walk_expr (e);
513 if (ss == gfc_ss_terminator)
515 parmse->ss = NULL;
516 gfc_conv_expr_reference (parmse, e);
517 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
518 gfc_add_modify (&parmse->pre, ctree, tmp);
520 else
522 parmse->ss = ss;
523 gfc_conv_expr_descriptor (parmse, e);
524 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
528 /* Pass the address of the class object. */
529 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
533 /* Takes a scalarized class array expression and returns the
534 address of a temporary scalar class object of the 'declared'
535 type.
536 OOP-TODO: This could be improved by adding code that branched on
537 the dynamic type being the same as the declared type. In this case
538 the original class expression can be passed directly.
539 optional_alloc_ptr is false when the dummy is neither allocatable
540 nor a pointer; that's relevant for the optional handling.
541 Set copyback to true if class container's _data and _vtab pointers
542 might get modified. */
544 void
545 gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
546 bool elemental, bool copyback, bool optional,
547 bool optional_alloc_ptr)
549 tree ctree;
550 tree var;
551 tree tmp;
552 tree vptr;
553 tree cond = NULL_TREE;
554 gfc_ref *ref;
555 gfc_ref *class_ref;
556 stmtblock_t block;
557 bool full_array = false;
559 gfc_init_block (&block);
561 class_ref = NULL;
562 for (ref = e->ref; ref; ref = ref->next)
564 if (ref->type == REF_COMPONENT
565 && ref->u.c.component->ts.type == BT_CLASS)
566 class_ref = ref;
568 if (ref->next == NULL)
569 break;
572 if ((ref == NULL || class_ref == ref)
573 && (!class_ts.u.derived->components->as
574 || class_ts.u.derived->components->as->rank != -1))
575 return;
577 /* Test for FULL_ARRAY. */
578 if (e->rank == 0 && gfc_expr_attr (e).codimension
579 && gfc_expr_attr (e).dimension)
580 full_array = true;
581 else
582 gfc_is_class_array_ref (e, &full_array);
584 /* The derived type needs to be converted to a temporary
585 CLASS object. */
586 tmp = gfc_typenode_for_spec (&class_ts);
587 var = gfc_create_var (tmp, "class");
589 /* Set the data. */
590 ctree = gfc_class_data_get (var);
591 if (class_ts.u.derived->components->as
592 && e->rank != class_ts.u.derived->components->as->rank)
594 if (e->rank == 0)
596 tree type = get_scalar_to_descriptor_type (parmse->expr,
597 gfc_expr_attr (e));
598 gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
599 gfc_get_dtype (type));
601 tmp = gfc_class_data_get (parmse->expr);
602 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
603 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
605 gfc_conv_descriptor_data_set (&block, ctree, tmp);
607 else
608 class_array_data_assign (&block, ctree, parmse->expr, false);
610 else
612 if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
613 parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
614 TREE_TYPE (ctree), parmse->expr);
615 gfc_add_modify (&block, ctree, parmse->expr);
618 /* Return the data component, except in the case of scalarized array
619 references, where nullification of the cannot occur and so there
620 is no need. */
621 if (!elemental && full_array && copyback)
623 if (class_ts.u.derived->components->as
624 && e->rank != class_ts.u.derived->components->as->rank)
626 if (e->rank == 0)
627 gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr),
628 gfc_conv_descriptor_data_get (ctree));
629 else
630 class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
632 else
633 gfc_add_modify (&parmse->post, parmse->expr, ctree);
636 /* Set the vptr. */
637 ctree = gfc_class_vptr_get (var);
639 /* The vptr is the second field of the actual argument.
640 First we have to find the corresponding class reference. */
642 tmp = NULL_TREE;
643 if (class_ref == NULL
644 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
645 tmp = e->symtree->n.sym->backend_decl;
646 else
648 /* Remove everything after the last class reference, convert the
649 expression and then recover its tailend once more. */
650 gfc_se tmpse;
651 ref = class_ref->next;
652 class_ref->next = NULL;
653 gfc_init_se (&tmpse, NULL);
654 gfc_conv_expr (&tmpse, e);
655 class_ref->next = ref;
656 tmp = tmpse.expr;
659 gcc_assert (tmp != NULL_TREE);
661 /* Dereference if needs be. */
662 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
663 tmp = build_fold_indirect_ref_loc (input_location, tmp);
665 vptr = gfc_class_vptr_get (tmp);
666 gfc_add_modify (&block, ctree,
667 fold_convert (TREE_TYPE (ctree), vptr));
669 /* Return the vptr component, except in the case of scalarized array
670 references, where the dynamic type cannot change. */
671 if (!elemental && full_array && copyback)
672 gfc_add_modify (&parmse->post, vptr,
673 fold_convert (TREE_TYPE (vptr), ctree));
675 gcc_assert (!optional || (optional && !copyback));
676 if (optional)
678 tree tmp2;
680 cond = gfc_conv_expr_present (e->symtree->n.sym);
681 tmp = gfc_finish_block (&block);
683 if (optional_alloc_ptr)
684 tmp2 = build_empty_stmt (input_location);
685 else
687 gfc_init_block (&block);
689 tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
690 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
691 null_pointer_node));
692 tmp2 = gfc_finish_block (&block);
695 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
696 cond, tmp, tmp2);
697 gfc_add_expr_to_block (&parmse->pre, tmp);
699 else
700 gfc_add_block_to_block (&parmse->pre, &block);
702 /* Pass the address of the class object. */
703 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
705 if (optional && optional_alloc_ptr)
706 parmse->expr = build3_loc (input_location, COND_EXPR,
707 TREE_TYPE (parmse->expr),
708 cond, parmse->expr,
709 fold_convert (TREE_TYPE (parmse->expr),
710 null_pointer_node));
714 /* Given a class array declaration and an index, returns the address
715 of the referenced element. */
717 tree
718 gfc_get_class_array_ref (tree index, tree class_decl)
720 tree data = gfc_class_data_get (class_decl);
721 tree size = gfc_vtable_size_get (class_decl);
722 tree offset = fold_build2_loc (input_location, MULT_EXPR,
723 gfc_array_index_type,
724 index, size);
725 tree ptr;
726 data = gfc_conv_descriptor_data_get (data);
727 ptr = fold_convert (pvoid_type_node, data);
728 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
729 return fold_convert (TREE_TYPE (data), ptr);
733 /* Copies one class expression to another, assuming that if either
734 'to' or 'from' are arrays they are packed. Should 'from' be
735 NULL_TREE, the initialization expression for 'to' is used, assuming
736 that the _vptr is set. */
738 tree
739 gfc_copy_class_to_class (tree from, tree to, tree nelems)
741 tree fcn;
742 tree fcn_type;
743 tree from_data;
744 tree to_data;
745 tree to_ref;
746 tree from_ref;
747 vec<tree, va_gc> *args;
748 tree tmp;
749 tree index;
750 stmtblock_t loopbody;
751 stmtblock_t body;
752 gfc_loopinfo loop;
754 args = NULL;
756 if (from != NULL_TREE)
757 fcn = gfc_vtable_copy_get (from);
758 else
759 fcn = gfc_vtable_copy_get (to);
761 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
763 if (from != NULL_TREE)
764 from_data = gfc_class_data_get (from);
765 else
766 from_data = gfc_vtable_def_init_get (to);
768 to_data = gfc_class_data_get (to);
770 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
772 gfc_init_block (&body);
773 tmp = fold_build2_loc (input_location, MINUS_EXPR,
774 gfc_array_index_type, nelems,
775 gfc_index_one_node);
776 nelems = gfc_evaluate_now (tmp, &body);
777 index = gfc_create_var (gfc_array_index_type, "S");
779 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)))
781 from_ref = gfc_get_class_array_ref (index, from);
782 vec_safe_push (args, from_ref);
784 else
785 vec_safe_push (args, from_data);
787 to_ref = gfc_get_class_array_ref (index, to);
788 vec_safe_push (args, to_ref);
790 tmp = build_call_vec (fcn_type, fcn, args);
792 /* Build the body of the loop. */
793 gfc_init_block (&loopbody);
794 gfc_add_expr_to_block (&loopbody, tmp);
796 /* Build the loop and return. */
797 gfc_init_loopinfo (&loop);
798 loop.dimen = 1;
799 loop.from[0] = gfc_index_zero_node;
800 loop.loopvar[0] = index;
801 loop.to[0] = nelems;
802 gfc_trans_scalarizing_loops (&loop, &loopbody);
803 gfc_add_block_to_block (&body, &loop.pre);
804 tmp = gfc_finish_block (&body);
805 gfc_cleanup_loop (&loop);
807 else
809 gcc_assert (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)));
810 vec_safe_push (args, from_data);
811 vec_safe_push (args, to_data);
812 tmp = build_call_vec (fcn_type, fcn, args);
815 return tmp;
818 static tree
819 gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
821 gfc_actual_arglist *actual;
822 gfc_expr *ppc;
823 gfc_code *ppc_code;
824 tree res;
826 actual = gfc_get_actual_arglist ();
827 actual->expr = gfc_copy_expr (rhs);
828 actual->next = gfc_get_actual_arglist ();
829 actual->next->expr = gfc_copy_expr (lhs);
830 ppc = gfc_copy_expr (obj);
831 gfc_add_vptr_component (ppc);
832 gfc_add_component_ref (ppc, "_copy");
833 ppc_code = gfc_get_code ();
834 ppc_code->resolved_sym = ppc->symtree->n.sym;
835 /* Although '_copy' is set to be elemental in class.c, it is
836 not staying that way. Find out why, sometime.... */
837 ppc_code->resolved_sym->attr.elemental = 1;
838 ppc_code->ext.actual = actual;
839 ppc_code->expr1 = ppc;
840 ppc_code->op = EXEC_CALL;
841 /* Since '_copy' is elemental, the scalarizer will take care
842 of arrays in gfc_trans_call. */
843 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
844 gfc_free_statements (ppc_code);
845 return res;
848 /* Special case for initializing a polymorphic dummy with INTENT(OUT).
849 A MEMCPY is needed to copy the full data from the default initializer
850 of the dynamic type. */
852 tree
853 gfc_trans_class_init_assign (gfc_code *code)
855 stmtblock_t block;
856 tree tmp;
857 gfc_se dst,src,memsz;
858 gfc_expr *lhs, *rhs, *sz;
860 gfc_start_block (&block);
862 lhs = gfc_copy_expr (code->expr1);
863 gfc_add_data_component (lhs);
865 rhs = gfc_copy_expr (code->expr1);
866 gfc_add_vptr_component (rhs);
868 /* Make sure that the component backend_decls have been built, which
869 will not have happened if the derived types concerned have not
870 been referenced. */
871 gfc_get_derived_type (rhs->ts.u.derived);
872 gfc_add_def_init_component (rhs);
874 if (code->expr1->ts.type == BT_CLASS
875 && CLASS_DATA (code->expr1)->attr.dimension)
876 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
877 else
879 sz = gfc_copy_expr (code->expr1);
880 gfc_add_vptr_component (sz);
881 gfc_add_size_component (sz);
883 gfc_init_se (&dst, NULL);
884 gfc_init_se (&src, NULL);
885 gfc_init_se (&memsz, NULL);
886 gfc_conv_expr (&dst, lhs);
887 gfc_conv_expr (&src, rhs);
888 gfc_conv_expr (&memsz, sz);
889 gfc_add_block_to_block (&block, &src.pre);
890 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
892 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
895 if (code->expr1->symtree->n.sym->attr.optional
896 || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master)
898 tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
899 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
900 present, tmp,
901 build_empty_stmt (input_location));
904 gfc_add_expr_to_block (&block, tmp);
906 return gfc_finish_block (&block);
910 /* Translate an assignment to a CLASS object
911 (pointer or ordinary assignment). */
913 tree
914 gfc_trans_class_assign (gfc_expr *expr1, gfc_expr *expr2, gfc_exec_op op)
916 stmtblock_t block;
917 tree tmp;
918 gfc_expr *lhs;
919 gfc_expr *rhs;
920 gfc_ref *ref;
922 gfc_start_block (&block);
924 ref = expr1->ref;
925 while (ref && ref->next)
926 ref = ref->next;
928 /* Class valued proc_pointer assignments do not need any further
929 preparation. */
930 if (ref && ref->type == REF_COMPONENT
931 && ref->u.c.component->attr.proc_pointer
932 && expr2->expr_type == EXPR_VARIABLE
933 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE
934 && op == EXEC_POINTER_ASSIGN)
935 goto assign;
937 if (expr2->ts.type != BT_CLASS)
939 /* Insert an additional assignment which sets the '_vptr' field. */
940 gfc_symbol *vtab = NULL;
941 gfc_symtree *st;
943 lhs = gfc_copy_expr (expr1);
944 gfc_add_vptr_component (lhs);
946 if (UNLIMITED_POLY (expr1)
947 && expr2->expr_type == EXPR_NULL && expr2->ts.type == BT_UNKNOWN)
949 rhs = gfc_get_null_expr (&expr2->where);
950 goto assign_vptr;
953 if (expr2->ts.type == BT_DERIVED)
954 vtab = gfc_find_derived_vtab (expr2->ts.u.derived);
955 else if (expr2->expr_type == EXPR_NULL)
956 vtab = gfc_find_derived_vtab (expr1->ts.u.derived);
957 else
958 vtab = gfc_find_intrinsic_vtab (&expr2->ts);
959 gcc_assert (vtab);
961 rhs = gfc_get_expr ();
962 rhs->expr_type = EXPR_VARIABLE;
963 gfc_find_sym_tree (vtab->name, vtab->ns, 1, &st);
964 rhs->symtree = st;
965 rhs->ts = vtab->ts;
966 assign_vptr:
967 tmp = gfc_trans_pointer_assignment (lhs, rhs);
968 gfc_add_expr_to_block (&block, tmp);
970 gfc_free_expr (lhs);
971 gfc_free_expr (rhs);
973 else if (expr1->ts.type == BT_DERIVED && UNLIMITED_POLY (expr2))
975 /* F2003:C717 only sequence and bind-C types can come here. */
976 gcc_assert (expr1->ts.u.derived->attr.sequence
977 || expr1->ts.u.derived->attr.is_bind_c);
978 gfc_add_data_component (expr2);
979 goto assign;
981 else if (CLASS_DATA (expr2)->attr.dimension)
983 /* Insert an additional assignment which sets the '_vptr' field. */
984 lhs = gfc_copy_expr (expr1);
985 gfc_add_vptr_component (lhs);
987 rhs = gfc_copy_expr (expr2);
988 gfc_add_vptr_component (rhs);
990 tmp = gfc_trans_pointer_assignment (lhs, rhs);
991 gfc_add_expr_to_block (&block, tmp);
993 gfc_free_expr (lhs);
994 gfc_free_expr (rhs);
997 /* Do the actual CLASS assignment. */
998 if (expr2->ts.type == BT_CLASS
999 && !CLASS_DATA (expr2)->attr.dimension)
1000 op = EXEC_ASSIGN;
1001 else
1002 gfc_add_data_component (expr1);
1004 assign:
1006 if (op == EXEC_ASSIGN)
1007 tmp = gfc_trans_assignment (expr1, expr2, false, true);
1008 else if (op == EXEC_POINTER_ASSIGN)
1009 tmp = gfc_trans_pointer_assignment (expr1, expr2);
1010 else
1011 gcc_unreachable();
1013 gfc_add_expr_to_block (&block, tmp);
1015 return gfc_finish_block (&block);
1019 /* End of prototype trans-class.c */
1022 static void
1023 realloc_lhs_warning (bt type, bool array, locus *where)
1025 if (array && type != BT_CLASS && type != BT_DERIVED
1026 && gfc_option.warn_realloc_lhs)
1027 gfc_warning ("Code for reallocating the allocatable array at %L will "
1028 "be added", where);
1029 else if (gfc_option.warn_realloc_lhs_all)
1030 gfc_warning ("Code for reallocating the allocatable variable at %L "
1031 "will be added", where);
1035 static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
1036 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
1037 gfc_expr *);
1039 /* Copy the scalarization loop variables. */
1041 static void
1042 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1044 dest->ss = src->ss;
1045 dest->loop = src->loop;
1049 /* Initialize a simple expression holder.
1051 Care must be taken when multiple se are created with the same parent.
1052 The child se must be kept in sync. The easiest way is to delay creation
1053 of a child se until after after the previous se has been translated. */
1055 void
1056 gfc_init_se (gfc_se * se, gfc_se * parent)
1058 memset (se, 0, sizeof (gfc_se));
1059 gfc_init_block (&se->pre);
1060 gfc_init_block (&se->post);
1062 se->parent = parent;
1064 if (parent)
1065 gfc_copy_se_loopvars (se, parent);
1069 /* Advances to the next SS in the chain. Use this rather than setting
1070 se->ss = se->ss->next because all the parents needs to be kept in sync.
1071 See gfc_init_se. */
1073 void
1074 gfc_advance_se_ss_chain (gfc_se * se)
1076 gfc_se *p;
1077 gfc_ss *ss;
1079 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
1081 p = se;
1082 /* Walk down the parent chain. */
1083 while (p != NULL)
1085 /* Simple consistency check. */
1086 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1087 || p->parent->ss->nested_ss == p->ss);
1089 /* If we were in a nested loop, the next scalarized expression can be
1090 on the parent ss' next pointer. Thus we should not take the next
1091 pointer blindly, but rather go up one nest level as long as next
1092 is the end of chain. */
1093 ss = p->ss;
1094 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1095 ss = ss->parent;
1097 p->ss = ss->next;
1099 p = p->parent;
1104 /* Ensures the result of the expression as either a temporary variable
1105 or a constant so that it can be used repeatedly. */
1107 void
1108 gfc_make_safe_expr (gfc_se * se)
1110 tree var;
1112 if (CONSTANT_CLASS_P (se->expr))
1113 return;
1115 /* We need a temporary for this result. */
1116 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1117 gfc_add_modify (&se->pre, var, se->expr);
1118 se->expr = var;
1122 /* Return an expression which determines if a dummy parameter is present.
1123 Also used for arguments to procedures with multiple entry points. */
1125 tree
1126 gfc_conv_expr_present (gfc_symbol * sym)
1128 tree decl, cond;
1130 gcc_assert (sym->attr.dummy);
1132 decl = gfc_get_symbol_decl (sym);
1133 if (TREE_CODE (decl) != PARM_DECL)
1135 /* Array parameters use a temporary descriptor, we want the real
1136 parameter. */
1137 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
1138 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
1139 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
1142 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, decl,
1143 fold_convert (TREE_TYPE (decl), null_pointer_node));
1145 /* Fortran 2008 allows to pass null pointers and non-associated pointers
1146 as actual argument to denote absent dummies. For array descriptors,
1147 we thus also need to check the array descriptor. For BT_CLASS, it
1148 can also occur for scalars and F2003 due to type->class wrapping and
1149 class->class wrapping. Note futher that BT_CLASS always uses an
1150 array descriptor for arrays, also for explicit-shape/assumed-size. */
1152 if (!sym->attr.allocatable
1153 && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
1154 || (sym->ts.type == BT_CLASS
1155 && !CLASS_DATA (sym)->attr.allocatable
1156 && !CLASS_DATA (sym)->attr.class_pointer))
1157 && ((gfc_option.allow_std & GFC_STD_F2008) != 0
1158 || sym->ts.type == BT_CLASS))
1160 tree tmp;
1162 if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
1163 || sym->as->type == AS_ASSUMED_RANK
1164 || sym->attr.codimension))
1165 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
1167 tmp = build_fold_indirect_ref_loc (input_location, decl);
1168 if (sym->ts.type == BT_CLASS)
1169 tmp = gfc_class_data_get (tmp);
1170 tmp = gfc_conv_array_data (tmp);
1172 else if (sym->ts.type == BT_CLASS)
1173 tmp = gfc_class_data_get (decl);
1174 else
1175 tmp = NULL_TREE;
1177 if (tmp != NULL_TREE)
1179 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
1180 fold_convert (TREE_TYPE (tmp), null_pointer_node));
1181 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1182 boolean_type_node, cond, tmp);
1186 return cond;
1190 /* Converts a missing, dummy argument into a null or zero. */
1192 void
1193 gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
1195 tree present;
1196 tree tmp;
1198 present = gfc_conv_expr_present (arg->symtree->n.sym);
1200 if (kind > 0)
1202 /* Create a temporary and convert it to the correct type. */
1203 tmp = gfc_get_int_type (kind);
1204 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
1205 se->expr));
1207 /* Test for a NULL value. */
1208 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
1209 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
1210 tmp = gfc_evaluate_now (tmp, &se->pre);
1211 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
1213 else
1215 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
1216 present, se->expr,
1217 build_zero_cst (TREE_TYPE (se->expr)));
1218 tmp = gfc_evaluate_now (tmp, &se->pre);
1219 se->expr = tmp;
1222 if (ts.type == BT_CHARACTER)
1224 tmp = build_int_cst (gfc_charlen_type_node, 0);
1225 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
1226 present, se->string_length, tmp);
1227 tmp = gfc_evaluate_now (tmp, &se->pre);
1228 se->string_length = tmp;
1230 return;
1234 /* Get the character length of an expression, looking through gfc_refs
1235 if necessary. */
1237 tree
1238 gfc_get_expr_charlen (gfc_expr *e)
1240 gfc_ref *r;
1241 tree length;
1243 gcc_assert (e->expr_type == EXPR_VARIABLE
1244 && e->ts.type == BT_CHARACTER);
1246 length = NULL; /* To silence compiler warning. */
1248 if (is_subref_array (e) && e->ts.u.cl->length)
1250 gfc_se tmpse;
1251 gfc_init_se (&tmpse, NULL);
1252 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
1253 e->ts.u.cl->backend_decl = tmpse.expr;
1254 return tmpse.expr;
1257 /* First candidate: if the variable is of type CHARACTER, the
1258 expression's length could be the length of the character
1259 variable. */
1260 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1261 length = e->symtree->n.sym->ts.u.cl->backend_decl;
1263 /* Look through the reference chain for component references. */
1264 for (r = e->ref; r; r = r->next)
1266 switch (r->type)
1268 case REF_COMPONENT:
1269 if (r->u.c.component->ts.type == BT_CHARACTER)
1270 length = r->u.c.component->ts.u.cl->backend_decl;
1271 break;
1273 case REF_ARRAY:
1274 /* Do nothing. */
1275 break;
1277 default:
1278 /* We should never got substring references here. These will be
1279 broken down by the scalarizer. */
1280 gcc_unreachable ();
1281 break;
1285 gcc_assert (length != NULL);
1286 return length;
1290 /* Return for an expression the backend decl of the coarray. */
1292 static tree
1293 get_tree_for_caf_expr (gfc_expr *expr)
1295 tree caf_decl = NULL_TREE;
1296 gfc_ref *ref;
1298 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
1299 if (expr->symtree->n.sym->attr.codimension)
1300 caf_decl = expr->symtree->n.sym->backend_decl;
1302 for (ref = expr->ref; ref; ref = ref->next)
1303 if (ref->type == REF_COMPONENT)
1305 gfc_component *comp = ref->u.c.component;
1306 if (comp->attr.pointer || comp->attr.allocatable)
1307 caf_decl = NULL_TREE;
1308 if (comp->attr.codimension)
1309 caf_decl = comp->backend_decl;
1312 gcc_assert (caf_decl != NULL_TREE);
1313 return caf_decl;
1317 /* For each character array constructor subexpression without a ts.u.cl->length,
1318 replace it by its first element (if there aren't any elements, the length
1319 should already be set to zero). */
1321 static void
1322 flatten_array_ctors_without_strlen (gfc_expr* e)
1324 gfc_actual_arglist* arg;
1325 gfc_constructor* c;
1327 if (!e)
1328 return;
1330 switch (e->expr_type)
1333 case EXPR_OP:
1334 flatten_array_ctors_without_strlen (e->value.op.op1);
1335 flatten_array_ctors_without_strlen (e->value.op.op2);
1336 break;
1338 case EXPR_COMPCALL:
1339 /* TODO: Implement as with EXPR_FUNCTION when needed. */
1340 gcc_unreachable ();
1342 case EXPR_FUNCTION:
1343 for (arg = e->value.function.actual; arg; arg = arg->next)
1344 flatten_array_ctors_without_strlen (arg->expr);
1345 break;
1347 case EXPR_ARRAY:
1349 /* We've found what we're looking for. */
1350 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
1352 gfc_constructor *c;
1353 gfc_expr* new_expr;
1355 gcc_assert (e->value.constructor);
1357 c = gfc_constructor_first (e->value.constructor);
1358 new_expr = c->expr;
1359 c->expr = NULL;
1361 flatten_array_ctors_without_strlen (new_expr);
1362 gfc_replace_expr (e, new_expr);
1363 break;
1366 /* Otherwise, fall through to handle constructor elements. */
1367 case EXPR_STRUCTURE:
1368 for (c = gfc_constructor_first (e->value.constructor);
1369 c; c = gfc_constructor_next (c))
1370 flatten_array_ctors_without_strlen (c->expr);
1371 break;
1373 default:
1374 break;
1380 /* Generate code to initialize a string length variable. Returns the
1381 value. For array constructors, cl->length might be NULL and in this case,
1382 the first element of the constructor is needed. expr is the original
1383 expression so we can access it but can be NULL if this is not needed. */
1385 void
1386 gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
1388 gfc_se se;
1390 gfc_init_se (&se, NULL);
1392 if (!cl->length
1393 && cl->backend_decl
1394 && TREE_CODE (cl->backend_decl) == VAR_DECL)
1395 return;
1397 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
1398 "flatten" array constructors by taking their first element; all elements
1399 should be the same length or a cl->length should be present. */
1400 if (!cl->length)
1402 gfc_expr* expr_flat;
1403 gcc_assert (expr);
1404 expr_flat = gfc_copy_expr (expr);
1405 flatten_array_ctors_without_strlen (expr_flat);
1406 gfc_resolve_expr (expr_flat);
1408 gfc_conv_expr (&se, expr_flat);
1409 gfc_add_block_to_block (pblock, &se.pre);
1410 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
1412 gfc_free_expr (expr_flat);
1413 return;
1416 /* Convert cl->length. */
1418 gcc_assert (cl->length);
1420 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
1421 se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
1422 se.expr, build_int_cst (gfc_charlen_type_node, 0));
1423 gfc_add_block_to_block (pblock, &se.pre);
1425 if (cl->backend_decl)
1426 gfc_add_modify (pblock, cl->backend_decl, se.expr);
1427 else
1428 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
1432 static void
1433 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
1434 const char *name, locus *where)
1436 tree tmp;
1437 tree type;
1438 tree fault;
1439 gfc_se start;
1440 gfc_se end;
1441 char *msg;
1443 type = gfc_get_character_type (kind, ref->u.ss.length);
1444 type = build_pointer_type (type);
1446 gfc_init_se (&start, se);
1447 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
1448 gfc_add_block_to_block (&se->pre, &start.pre);
1450 if (integer_onep (start.expr))
1451 gfc_conv_string_parameter (se);
1452 else
1454 tmp = start.expr;
1455 STRIP_NOPS (tmp);
1456 /* Avoid multiple evaluation of substring start. */
1457 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1458 start.expr = gfc_evaluate_now (start.expr, &se->pre);
1460 /* Change the start of the string. */
1461 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
1462 tmp = se->expr;
1463 else
1464 tmp = build_fold_indirect_ref_loc (input_location,
1465 se->expr);
1466 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
1467 se->expr = gfc_build_addr_expr (type, tmp);
1470 /* Length = end + 1 - start. */
1471 gfc_init_se (&end, se);
1472 if (ref->u.ss.end == NULL)
1473 end.expr = se->string_length;
1474 else
1476 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
1477 gfc_add_block_to_block (&se->pre, &end.pre);
1479 tmp = end.expr;
1480 STRIP_NOPS (tmp);
1481 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1482 end.expr = gfc_evaluate_now (end.expr, &se->pre);
1484 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1486 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
1487 boolean_type_node, start.expr,
1488 end.expr);
1490 /* Check lower bound. */
1491 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1492 start.expr,
1493 build_int_cst (gfc_charlen_type_node, 1));
1494 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1495 boolean_type_node, nonempty, fault);
1496 if (name)
1497 asprintf (&msg, "Substring out of bounds: lower bound (%%ld) of '%s' "
1498 "is less than one", name);
1499 else
1500 asprintf (&msg, "Substring out of bounds: lower bound (%%ld)"
1501 "is less than one");
1502 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
1503 fold_convert (long_integer_type_node,
1504 start.expr));
1505 free (msg);
1507 /* Check upper bound. */
1508 fault = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1509 end.expr, se->string_length);
1510 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1511 boolean_type_node, nonempty, fault);
1512 if (name)
1513 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) of '%s' "
1514 "exceeds string length (%%ld)", name);
1515 else
1516 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) "
1517 "exceeds string length (%%ld)");
1518 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
1519 fold_convert (long_integer_type_node, end.expr),
1520 fold_convert (long_integer_type_node,
1521 se->string_length));
1522 free (msg);
1525 /* If the start and end expressions are equal, the length is one. */
1526 if (ref->u.ss.end
1527 && gfc_dep_compare_expr (ref->u.ss.start, ref->u.ss.end) == 0)
1528 tmp = build_int_cst (gfc_charlen_type_node, 1);
1529 else
1531 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
1532 end.expr, start.expr);
1533 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
1534 build_int_cst (gfc_charlen_type_node, 1), tmp);
1535 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
1536 tmp, build_int_cst (gfc_charlen_type_node, 0));
1539 se->string_length = tmp;
1543 /* Convert a derived type component reference. */
1545 static void
1546 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
1548 gfc_component *c;
1549 tree tmp;
1550 tree decl;
1551 tree field;
1553 c = ref->u.c.component;
1555 gcc_assert (c->backend_decl);
1557 field = c->backend_decl;
1558 gcc_assert (TREE_CODE (field) == FIELD_DECL);
1559 decl = se->expr;
1561 /* Components can correspond to fields of different containing
1562 types, as components are created without context, whereas
1563 a concrete use of a component has the type of decl as context.
1564 So, if the type doesn't match, we search the corresponding
1565 FIELD_DECL in the parent type. To not waste too much time
1566 we cache this result in norestrict_decl. */
1568 if (DECL_FIELD_CONTEXT (field) != TREE_TYPE (decl))
1570 tree f2 = c->norestrict_decl;
1571 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
1572 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
1573 if (TREE_CODE (f2) == FIELD_DECL
1574 && DECL_NAME (f2) == DECL_NAME (field))
1575 break;
1576 gcc_assert (f2);
1577 c->norestrict_decl = f2;
1578 field = f2;
1581 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
1582 decl, field, NULL_TREE);
1584 se->expr = tmp;
1586 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer)
1588 tmp = c->ts.u.cl->backend_decl;
1589 /* Components must always be constant length. */
1590 gcc_assert (tmp && INTEGER_CST_P (tmp));
1591 se->string_length = tmp;
1594 if (((c->attr.pointer || c->attr.allocatable)
1595 && (!c->attr.dimension && !c->attr.codimension)
1596 && c->ts.type != BT_CHARACTER)
1597 || c->attr.proc_pointer)
1598 se->expr = build_fold_indirect_ref_loc (input_location,
1599 se->expr);
1603 /* This function deals with component references to components of the
1604 parent type for derived type extensions. */
1605 static void
1606 conv_parent_component_references (gfc_se * se, gfc_ref * ref)
1608 gfc_component *c;
1609 gfc_component *cmp;
1610 gfc_symbol *dt;
1611 gfc_ref parent;
1613 dt = ref->u.c.sym;
1614 c = ref->u.c.component;
1616 /* Return if the component is in the parent type. */
1617 for (cmp = dt->components; cmp; cmp = cmp->next)
1618 if (strcmp (c->name, cmp->name) == 0)
1619 return;
1621 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
1622 parent.type = REF_COMPONENT;
1623 parent.next = NULL;
1624 parent.u.c.sym = dt;
1625 parent.u.c.component = dt->components;
1627 if (dt->backend_decl == NULL)
1628 gfc_get_derived_type (dt);
1630 /* Build the reference and call self. */
1631 gfc_conv_component_ref (se, &parent);
1632 parent.u.c.sym = dt->components->ts.u.derived;
1633 parent.u.c.component = c;
1634 conv_parent_component_references (se, &parent);
1637 /* Return the contents of a variable. Also handles reference/pointer
1638 variables (all Fortran pointer references are implicit). */
1640 static void
1641 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
1643 gfc_ss *ss;
1644 gfc_ref *ref;
1645 gfc_symbol *sym;
1646 tree parent_decl = NULL_TREE;
1647 int parent_flag;
1648 bool return_value;
1649 bool alternate_entry;
1650 bool entry_master;
1652 sym = expr->symtree->n.sym;
1653 ss = se->ss;
1654 if (ss != NULL)
1656 gfc_ss_info *ss_info = ss->info;
1658 /* Check that something hasn't gone horribly wrong. */
1659 gcc_assert (ss != gfc_ss_terminator);
1660 gcc_assert (ss_info->expr == expr);
1662 /* A scalarized term. We already know the descriptor. */
1663 se->expr = ss_info->data.array.descriptor;
1664 se->string_length = ss_info->string_length;
1665 for (ref = ss_info->data.array.ref; ref; ref = ref->next)
1666 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
1667 break;
1669 else
1671 tree se_expr = NULL_TREE;
1673 se->expr = gfc_get_symbol_decl (sym);
1675 /* Deal with references to a parent results or entries by storing
1676 the current_function_decl and moving to the parent_decl. */
1677 return_value = sym->attr.function && sym->result == sym;
1678 alternate_entry = sym->attr.function && sym->attr.entry
1679 && sym->result == sym;
1680 entry_master = sym->attr.result
1681 && sym->ns->proc_name->attr.entry_master
1682 && !gfc_return_by_reference (sym->ns->proc_name);
1683 if (current_function_decl)
1684 parent_decl = DECL_CONTEXT (current_function_decl);
1686 if ((se->expr == parent_decl && return_value)
1687 || (sym->ns && sym->ns->proc_name
1688 && parent_decl
1689 && sym->ns->proc_name->backend_decl == parent_decl
1690 && (alternate_entry || entry_master)))
1691 parent_flag = 1;
1692 else
1693 parent_flag = 0;
1695 /* Special case for assigning the return value of a function.
1696 Self recursive functions must have an explicit return value. */
1697 if (return_value && (se->expr == current_function_decl || parent_flag))
1698 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
1700 /* Similarly for alternate entry points. */
1701 else if (alternate_entry
1702 && (sym->ns->proc_name->backend_decl == current_function_decl
1703 || parent_flag))
1705 gfc_entry_list *el = NULL;
1707 for (el = sym->ns->entries; el; el = el->next)
1708 if (sym == el->sym)
1710 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
1711 break;
1715 else if (entry_master
1716 && (sym->ns->proc_name->backend_decl == current_function_decl
1717 || parent_flag))
1718 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
1720 if (se_expr)
1721 se->expr = se_expr;
1723 /* Procedure actual arguments. */
1724 else if (sym->attr.flavor == FL_PROCEDURE
1725 && se->expr != current_function_decl)
1727 if (!sym->attr.dummy && !sym->attr.proc_pointer)
1729 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
1730 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
1732 return;
1736 /* Dereference the expression, where needed. Since characters
1737 are entirely different from other types, they are treated
1738 separately. */
1739 if (sym->ts.type == BT_CHARACTER)
1741 /* Dereference character pointer dummy arguments
1742 or results. */
1743 if ((sym->attr.pointer || sym->attr.allocatable)
1744 && (sym->attr.dummy
1745 || sym->attr.function
1746 || sym->attr.result))
1747 se->expr = build_fold_indirect_ref_loc (input_location,
1748 se->expr);
1751 else if (!sym->attr.value)
1753 /* Dereference non-character scalar dummy arguments. */
1754 if (sym->attr.dummy && !sym->attr.dimension
1755 && !(sym->attr.codimension && sym->attr.allocatable))
1756 se->expr = build_fold_indirect_ref_loc (input_location,
1757 se->expr);
1759 /* Dereference scalar hidden result. */
1760 if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
1761 && (sym->attr.function || sym->attr.result)
1762 && !sym->attr.dimension && !sym->attr.pointer
1763 && !sym->attr.always_explicit)
1764 se->expr = build_fold_indirect_ref_loc (input_location,
1765 se->expr);
1767 /* Dereference non-character pointer variables.
1768 These must be dummies, results, or scalars. */
1769 if ((sym->attr.pointer || sym->attr.allocatable
1770 || gfc_is_associate_pointer (sym)
1771 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
1772 && (sym->attr.dummy
1773 || sym->attr.function
1774 || sym->attr.result
1775 || (!sym->attr.dimension
1776 && (!sym->attr.codimension || !sym->attr.allocatable))))
1777 se->expr = build_fold_indirect_ref_loc (input_location,
1778 se->expr);
1781 ref = expr->ref;
1784 /* For character variables, also get the length. */
1785 if (sym->ts.type == BT_CHARACTER)
1787 /* If the character length of an entry isn't set, get the length from
1788 the master function instead. */
1789 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
1790 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
1791 else
1792 se->string_length = sym->ts.u.cl->backend_decl;
1793 gcc_assert (se->string_length);
1796 while (ref)
1798 switch (ref->type)
1800 case REF_ARRAY:
1801 /* Return the descriptor if that's what we want and this is an array
1802 section reference. */
1803 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
1804 return;
1805 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
1806 /* Return the descriptor for array pointers and allocations. */
1807 if (se->want_pointer
1808 && ref->next == NULL && (se->descriptor_only))
1809 return;
1811 gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
1812 /* Return a pointer to an element. */
1813 break;
1815 case REF_COMPONENT:
1816 if (ref->u.c.sym->attr.extension)
1817 conv_parent_component_references (se, ref);
1819 gfc_conv_component_ref (se, ref);
1820 if (!ref->next && ref->u.c.sym->attr.codimension
1821 && se->want_pointer && se->descriptor_only)
1822 return;
1824 break;
1826 case REF_SUBSTRING:
1827 gfc_conv_substring (se, ref, expr->ts.kind,
1828 expr->symtree->name, &expr->where);
1829 break;
1831 default:
1832 gcc_unreachable ();
1833 break;
1835 ref = ref->next;
1837 /* Pointer assignment, allocation or pass by reference. Arrays are handled
1838 separately. */
1839 if (se->want_pointer)
1841 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
1842 gfc_conv_string_parameter (se);
1843 else
1844 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
1849 /* Unary ops are easy... Or they would be if ! was a valid op. */
1851 static void
1852 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
1854 gfc_se operand;
1855 tree type;
1857 gcc_assert (expr->ts.type != BT_CHARACTER);
1858 /* Initialize the operand. */
1859 gfc_init_se (&operand, se);
1860 gfc_conv_expr_val (&operand, expr->value.op.op1);
1861 gfc_add_block_to_block (&se->pre, &operand.pre);
1863 type = gfc_typenode_for_spec (&expr->ts);
1865 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
1866 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
1867 All other unary operators have an equivalent GIMPLE unary operator. */
1868 if (code == TRUTH_NOT_EXPR)
1869 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
1870 build_int_cst (type, 0));
1871 else
1872 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
1876 /* Expand power operator to optimal multiplications when a value is raised
1877 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
1878 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
1879 Programming", 3rd Edition, 1998. */
1881 /* This code is mostly duplicated from expand_powi in the backend.
1882 We establish the "optimal power tree" lookup table with the defined size.
1883 The items in the table are the exponents used to calculate the index
1884 exponents. Any integer n less than the value can get an "addition chain",
1885 with the first node being one. */
1886 #define POWI_TABLE_SIZE 256
1888 /* The table is from builtins.c. */
1889 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1891 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1892 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1893 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1894 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1895 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1896 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1897 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1898 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1899 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1900 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1901 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1902 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1903 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1904 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1905 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1906 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1907 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1908 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1909 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1910 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
1911 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
1912 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
1913 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
1914 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
1915 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
1916 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
1917 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
1918 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
1919 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
1920 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
1921 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
1922 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
1925 /* If n is larger than lookup table's max index, we use the "window
1926 method". */
1927 #define POWI_WINDOW_SIZE 3
1929 /* Recursive function to expand the power operator. The temporary
1930 values are put in tmpvar. The function returns tmpvar[1] ** n. */
1931 static tree
1932 gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
1934 tree op0;
1935 tree op1;
1936 tree tmp;
1937 int digit;
1939 if (n < POWI_TABLE_SIZE)
1941 if (tmpvar[n])
1942 return tmpvar[n];
1944 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
1945 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
1947 else if (n & 1)
1949 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
1950 op0 = gfc_conv_powi (se, n - digit, tmpvar);
1951 op1 = gfc_conv_powi (se, digit, tmpvar);
1953 else
1955 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
1956 op1 = op0;
1959 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
1960 tmp = gfc_evaluate_now (tmp, &se->pre);
1962 if (n < POWI_TABLE_SIZE)
1963 tmpvar[n] = tmp;
1965 return tmp;
1969 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
1970 return 1. Else return 0 and a call to runtime library functions
1971 will have to be built. */
1972 static int
1973 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
1975 tree cond;
1976 tree tmp;
1977 tree type;
1978 tree vartmp[POWI_TABLE_SIZE];
1979 HOST_WIDE_INT m;
1980 unsigned HOST_WIDE_INT n;
1981 int sgn;
1983 /* If exponent is too large, we won't expand it anyway, so don't bother
1984 with large integer values. */
1985 if (!TREE_INT_CST (rhs).fits_shwi ())
1986 return 0;
1988 m = TREE_INT_CST (rhs).to_shwi ();
1989 /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
1990 of the asymmetric range of the integer type. */
1991 n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
1993 type = TREE_TYPE (lhs);
1994 sgn = tree_int_cst_sgn (rhs);
1996 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
1997 || optimize_size) && (m > 2 || m < -1))
1998 return 0;
2000 /* rhs == 0 */
2001 if (sgn == 0)
2003 se->expr = gfc_build_const (type, integer_one_node);
2004 return 1;
2007 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
2008 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
2010 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
2011 lhs, build_int_cst (TREE_TYPE (lhs), -1));
2012 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
2013 lhs, build_int_cst (TREE_TYPE (lhs), 1));
2015 /* If rhs is even,
2016 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
2017 if ((n & 1) == 0)
2019 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
2020 boolean_type_node, tmp, cond);
2021 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
2022 tmp, build_int_cst (type, 1),
2023 build_int_cst (type, 0));
2024 return 1;
2026 /* If rhs is odd,
2027 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
2028 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
2029 build_int_cst (type, -1),
2030 build_int_cst (type, 0));
2031 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
2032 cond, build_int_cst (type, 1), tmp);
2033 return 1;
2036 memset (vartmp, 0, sizeof (vartmp));
2037 vartmp[1] = lhs;
2038 if (sgn == -1)
2040 tmp = gfc_build_const (type, integer_one_node);
2041 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
2042 vartmp[1]);
2045 se->expr = gfc_conv_powi (se, n, vartmp);
2047 return 1;
2051 /* Power op (**). Constant integer exponent has special handling. */
2053 static void
2054 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
2056 tree gfc_int4_type_node;
2057 int kind;
2058 int ikind;
2059 int res_ikind_1, res_ikind_2;
2060 gfc_se lse;
2061 gfc_se rse;
2062 tree fndecl = NULL;
2064 gfc_init_se (&lse, se);
2065 gfc_conv_expr_val (&lse, expr->value.op.op1);
2066 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
2067 gfc_add_block_to_block (&se->pre, &lse.pre);
2069 gfc_init_se (&rse, se);
2070 gfc_conv_expr_val (&rse, expr->value.op.op2);
2071 gfc_add_block_to_block (&se->pre, &rse.pre);
2073 if (expr->value.op.op2->ts.type == BT_INTEGER
2074 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
2075 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
2076 return;
2078 gfc_int4_type_node = gfc_get_int_type (4);
2080 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
2081 library routine. But in the end, we have to convert the result back
2082 if this case applies -- with res_ikind_K, we keep track whether operand K
2083 falls into this case. */
2084 res_ikind_1 = -1;
2085 res_ikind_2 = -1;
2087 kind = expr->value.op.op1->ts.kind;
2088 switch (expr->value.op.op2->ts.type)
2090 case BT_INTEGER:
2091 ikind = expr->value.op.op2->ts.kind;
2092 switch (ikind)
2094 case 1:
2095 case 2:
2096 rse.expr = convert (gfc_int4_type_node, rse.expr);
2097 res_ikind_2 = ikind;
2098 /* Fall through. */
2100 case 4:
2101 ikind = 0;
2102 break;
2104 case 8:
2105 ikind = 1;
2106 break;
2108 case 16:
2109 ikind = 2;
2110 break;
2112 default:
2113 gcc_unreachable ();
2115 switch (kind)
2117 case 1:
2118 case 2:
2119 if (expr->value.op.op1->ts.type == BT_INTEGER)
2121 lse.expr = convert (gfc_int4_type_node, lse.expr);
2122 res_ikind_1 = kind;
2124 else
2125 gcc_unreachable ();
2126 /* Fall through. */
2128 case 4:
2129 kind = 0;
2130 break;
2132 case 8:
2133 kind = 1;
2134 break;
2136 case 10:
2137 kind = 2;
2138 break;
2140 case 16:
2141 kind = 3;
2142 break;
2144 default:
2145 gcc_unreachable ();
2148 switch (expr->value.op.op1->ts.type)
2150 case BT_INTEGER:
2151 if (kind == 3) /* Case 16 was not handled properly above. */
2152 kind = 2;
2153 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
2154 break;
2156 case BT_REAL:
2157 /* Use builtins for real ** int4. */
2158 if (ikind == 0)
2160 switch (kind)
2162 case 0:
2163 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
2164 break;
2166 case 1:
2167 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
2168 break;
2170 case 2:
2171 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
2172 break;
2174 case 3:
2175 /* Use the __builtin_powil() only if real(kind=16) is
2176 actually the C long double type. */
2177 if (!gfc_real16_is_float128)
2178 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
2179 break;
2181 default:
2182 gcc_unreachable ();
2186 /* If we don't have a good builtin for this, go for the
2187 library function. */
2188 if (!fndecl)
2189 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
2190 break;
2192 case BT_COMPLEX:
2193 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
2194 break;
2196 default:
2197 gcc_unreachable ();
2199 break;
2201 case BT_REAL:
2202 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
2203 break;
2205 case BT_COMPLEX:
2206 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
2207 break;
2209 default:
2210 gcc_unreachable ();
2211 break;
2214 se->expr = build_call_expr_loc (input_location,
2215 fndecl, 2, lse.expr, rse.expr);
2217 /* Convert the result back if it is of wrong integer kind. */
2218 if (res_ikind_1 != -1 && res_ikind_2 != -1)
2220 /* We want the maximum of both operand kinds as result. */
2221 if (res_ikind_1 < res_ikind_2)
2222 res_ikind_1 = res_ikind_2;
2223 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
2228 /* Generate code to allocate a string temporary. */
2230 tree
2231 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
2233 tree var;
2234 tree tmp;
2236 if (gfc_can_put_var_on_stack (len))
2238 /* Create a temporary variable to hold the result. */
2239 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2240 gfc_charlen_type_node, len,
2241 build_int_cst (gfc_charlen_type_node, 1));
2242 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
2244 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
2245 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
2246 else
2247 tmp = build_array_type (TREE_TYPE (type), tmp);
2249 var = gfc_create_var (tmp, "str");
2250 var = gfc_build_addr_expr (type, var);
2252 else
2254 /* Allocate a temporary to hold the result. */
2255 var = gfc_create_var (type, "pstr");
2256 tmp = gfc_call_malloc (&se->pre, type,
2257 fold_build2_loc (input_location, MULT_EXPR,
2258 TREE_TYPE (len), len,
2259 fold_convert (TREE_TYPE (len),
2260 TYPE_SIZE (type))));
2261 gfc_add_modify (&se->pre, var, tmp);
2263 /* Free the temporary afterwards. */
2264 tmp = gfc_call_free (convert (pvoid_type_node, var));
2265 gfc_add_expr_to_block (&se->post, tmp);
2268 return var;
2272 /* Handle a string concatenation operation. A temporary will be allocated to
2273 hold the result. */
2275 static void
2276 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
2278 gfc_se lse, rse;
2279 tree len, type, var, tmp, fndecl;
2281 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
2282 && expr->value.op.op2->ts.type == BT_CHARACTER);
2283 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
2285 gfc_init_se (&lse, se);
2286 gfc_conv_expr (&lse, expr->value.op.op1);
2287 gfc_conv_string_parameter (&lse);
2288 gfc_init_se (&rse, se);
2289 gfc_conv_expr (&rse, expr->value.op.op2);
2290 gfc_conv_string_parameter (&rse);
2292 gfc_add_block_to_block (&se->pre, &lse.pre);
2293 gfc_add_block_to_block (&se->pre, &rse.pre);
2295 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
2296 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2297 if (len == NULL_TREE)
2299 len = fold_build2_loc (input_location, PLUS_EXPR,
2300 TREE_TYPE (lse.string_length),
2301 lse.string_length, rse.string_length);
2304 type = build_pointer_type (type);
2306 var = gfc_conv_string_tmp (se, type, len);
2308 /* Do the actual concatenation. */
2309 if (expr->ts.kind == 1)
2310 fndecl = gfor_fndecl_concat_string;
2311 else if (expr->ts.kind == 4)
2312 fndecl = gfor_fndecl_concat_string_char4;
2313 else
2314 gcc_unreachable ();
2316 tmp = build_call_expr_loc (input_location,
2317 fndecl, 6, len, var, lse.string_length, lse.expr,
2318 rse.string_length, rse.expr);
2319 gfc_add_expr_to_block (&se->pre, tmp);
2321 /* Add the cleanup for the operands. */
2322 gfc_add_block_to_block (&se->pre, &rse.post);
2323 gfc_add_block_to_block (&se->pre, &lse.post);
2325 se->expr = var;
2326 se->string_length = len;
2329 /* Translates an op expression. Common (binary) cases are handled by this
2330 function, others are passed on. Recursion is used in either case.
2331 We use the fact that (op1.ts == op2.ts) (except for the power
2332 operator **).
2333 Operators need no special handling for scalarized expressions as long as
2334 they call gfc_conv_simple_val to get their operands.
2335 Character strings get special handling. */
2337 static void
2338 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
2340 enum tree_code code;
2341 gfc_se lse;
2342 gfc_se rse;
2343 tree tmp, type;
2344 int lop;
2345 int checkstring;
2347 checkstring = 0;
2348 lop = 0;
2349 switch (expr->value.op.op)
2351 case INTRINSIC_PARENTHESES:
2352 if ((expr->ts.type == BT_REAL
2353 || expr->ts.type == BT_COMPLEX)
2354 && gfc_option.flag_protect_parens)
2356 gfc_conv_unary_op (PAREN_EXPR, se, expr);
2357 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
2358 return;
2361 /* Fallthrough. */
2362 case INTRINSIC_UPLUS:
2363 gfc_conv_expr (se, expr->value.op.op1);
2364 return;
2366 case INTRINSIC_UMINUS:
2367 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
2368 return;
2370 case INTRINSIC_NOT:
2371 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
2372 return;
2374 case INTRINSIC_PLUS:
2375 code = PLUS_EXPR;
2376 break;
2378 case INTRINSIC_MINUS:
2379 code = MINUS_EXPR;
2380 break;
2382 case INTRINSIC_TIMES:
2383 code = MULT_EXPR;
2384 break;
2386 case INTRINSIC_DIVIDE:
2387 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
2388 an integer, we must round towards zero, so we use a
2389 TRUNC_DIV_EXPR. */
2390 if (expr->ts.type == BT_INTEGER)
2391 code = TRUNC_DIV_EXPR;
2392 else
2393 code = RDIV_EXPR;
2394 break;
2396 case INTRINSIC_POWER:
2397 gfc_conv_power_op (se, expr);
2398 return;
2400 case INTRINSIC_CONCAT:
2401 gfc_conv_concat_op (se, expr);
2402 return;
2404 case INTRINSIC_AND:
2405 code = TRUTH_ANDIF_EXPR;
2406 lop = 1;
2407 break;
2409 case INTRINSIC_OR:
2410 code = TRUTH_ORIF_EXPR;
2411 lop = 1;
2412 break;
2414 /* EQV and NEQV only work on logicals, but since we represent them
2415 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
2416 case INTRINSIC_EQ:
2417 case INTRINSIC_EQ_OS:
2418 case INTRINSIC_EQV:
2419 code = EQ_EXPR;
2420 checkstring = 1;
2421 lop = 1;
2422 break;
2424 case INTRINSIC_NE:
2425 case INTRINSIC_NE_OS:
2426 case INTRINSIC_NEQV:
2427 code = NE_EXPR;
2428 checkstring = 1;
2429 lop = 1;
2430 break;
2432 case INTRINSIC_GT:
2433 case INTRINSIC_GT_OS:
2434 code = GT_EXPR;
2435 checkstring = 1;
2436 lop = 1;
2437 break;
2439 case INTRINSIC_GE:
2440 case INTRINSIC_GE_OS:
2441 code = GE_EXPR;
2442 checkstring = 1;
2443 lop = 1;
2444 break;
2446 case INTRINSIC_LT:
2447 case INTRINSIC_LT_OS:
2448 code = LT_EXPR;
2449 checkstring = 1;
2450 lop = 1;
2451 break;
2453 case INTRINSIC_LE:
2454 case INTRINSIC_LE_OS:
2455 code = LE_EXPR;
2456 checkstring = 1;
2457 lop = 1;
2458 break;
2460 case INTRINSIC_USER:
2461 case INTRINSIC_ASSIGN:
2462 /* These should be converted into function calls by the frontend. */
2463 gcc_unreachable ();
2465 default:
2466 fatal_error ("Unknown intrinsic op");
2467 return;
2470 /* The only exception to this is **, which is handled separately anyway. */
2471 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
2473 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
2474 checkstring = 0;
2476 /* lhs */
2477 gfc_init_se (&lse, se);
2478 gfc_conv_expr (&lse, expr->value.op.op1);
2479 gfc_add_block_to_block (&se->pre, &lse.pre);
2481 /* rhs */
2482 gfc_init_se (&rse, se);
2483 gfc_conv_expr (&rse, expr->value.op.op2);
2484 gfc_add_block_to_block (&se->pre, &rse.pre);
2486 if (checkstring)
2488 gfc_conv_string_parameter (&lse);
2489 gfc_conv_string_parameter (&rse);
2491 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
2492 rse.string_length, rse.expr,
2493 expr->value.op.op1->ts.kind,
2494 code);
2495 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
2496 gfc_add_block_to_block (&lse.post, &rse.post);
2499 type = gfc_typenode_for_spec (&expr->ts);
2501 if (lop)
2503 /* The result of logical ops is always boolean_type_node. */
2504 tmp = fold_build2_loc (input_location, code, boolean_type_node,
2505 lse.expr, rse.expr);
2506 se->expr = convert (type, tmp);
2508 else
2509 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
2511 /* Add the post blocks. */
2512 gfc_add_block_to_block (&se->post, &rse.post);
2513 gfc_add_block_to_block (&se->post, &lse.post);
2516 /* If a string's length is one, we convert it to a single character. */
2518 tree
2519 gfc_string_to_single_character (tree len, tree str, int kind)
2522 if (len == NULL
2523 || !INTEGER_CST_P (len) || TREE_INT_CST_HIGH (len) != 0
2524 || !POINTER_TYPE_P (TREE_TYPE (str)))
2525 return NULL_TREE;
2527 if (TREE_INT_CST_LOW (len) == 1)
2529 str = fold_convert (gfc_get_pchar_type (kind), str);
2530 return build_fold_indirect_ref_loc (input_location, str);
2533 if (kind == 1
2534 && TREE_CODE (str) == ADDR_EXPR
2535 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
2536 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
2537 && array_ref_low_bound (TREE_OPERAND (str, 0))
2538 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
2539 && TREE_INT_CST_LOW (len) > 1
2540 && TREE_INT_CST_LOW (len)
2541 == (unsigned HOST_WIDE_INT)
2542 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
2544 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
2545 ret = build_fold_indirect_ref_loc (input_location, ret);
2546 if (TREE_CODE (ret) == INTEGER_CST)
2548 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
2549 int i, length = TREE_STRING_LENGTH (string_cst);
2550 const char *ptr = TREE_STRING_POINTER (string_cst);
2552 for (i = 1; i < length; i++)
2553 if (ptr[i] != ' ')
2554 return NULL_TREE;
2556 return ret;
2560 return NULL_TREE;
2564 void
2565 gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
2568 if (sym->backend_decl)
2570 /* This becomes the nominal_type in
2571 function.c:assign_parm_find_data_types. */
2572 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
2573 /* This becomes the passed_type in
2574 function.c:assign_parm_find_data_types. C promotes char to
2575 integer for argument passing. */
2576 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
2578 DECL_BY_REFERENCE (sym->backend_decl) = 0;
2581 if (expr != NULL)
2583 /* If we have a constant character expression, make it into an
2584 integer. */
2585 if ((*expr)->expr_type == EXPR_CONSTANT)
2587 gfc_typespec ts;
2588 gfc_clear_ts (&ts);
2590 *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
2591 (int)(*expr)->value.character.string[0]);
2592 if ((*expr)->ts.kind != gfc_c_int_kind)
2594 /* The expr needs to be compatible with a C int. If the
2595 conversion fails, then the 2 causes an ICE. */
2596 ts.type = BT_INTEGER;
2597 ts.kind = gfc_c_int_kind;
2598 gfc_convert_type (*expr, &ts, 2);
2601 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
2603 if ((*expr)->ref == NULL)
2605 se->expr = gfc_string_to_single_character
2606 (build_int_cst (integer_type_node, 1),
2607 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
2608 gfc_get_symbol_decl
2609 ((*expr)->symtree->n.sym)),
2610 (*expr)->ts.kind);
2612 else
2614 gfc_conv_variable (se, *expr);
2615 se->expr = gfc_string_to_single_character
2616 (build_int_cst (integer_type_node, 1),
2617 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
2618 se->expr),
2619 (*expr)->ts.kind);
2625 /* Helper function for gfc_build_compare_string. Return LEN_TRIM value
2626 if STR is a string literal, otherwise return -1. */
2628 static int
2629 gfc_optimize_len_trim (tree len, tree str, int kind)
2631 if (kind == 1
2632 && TREE_CODE (str) == ADDR_EXPR
2633 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
2634 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
2635 && array_ref_low_bound (TREE_OPERAND (str, 0))
2636 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
2637 && TREE_INT_CST_LOW (len) >= 1
2638 && TREE_INT_CST_LOW (len)
2639 == (unsigned HOST_WIDE_INT)
2640 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
2642 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
2643 folded = build_fold_indirect_ref_loc (input_location, folded);
2644 if (TREE_CODE (folded) == INTEGER_CST)
2646 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
2647 int length = TREE_STRING_LENGTH (string_cst);
2648 const char *ptr = TREE_STRING_POINTER (string_cst);
2650 for (; length > 0; length--)
2651 if (ptr[length - 1] != ' ')
2652 break;
2654 return length;
2657 return -1;
2660 /* Compare two strings. If they are all single characters, the result is the
2661 subtraction of them. Otherwise, we build a library call. */
2663 tree
2664 gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
2665 enum tree_code code)
2667 tree sc1;
2668 tree sc2;
2669 tree fndecl;
2671 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
2672 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
2674 sc1 = gfc_string_to_single_character (len1, str1, kind);
2675 sc2 = gfc_string_to_single_character (len2, str2, kind);
2677 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
2679 /* Deal with single character specially. */
2680 sc1 = fold_convert (integer_type_node, sc1);
2681 sc2 = fold_convert (integer_type_node, sc2);
2682 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
2683 sc1, sc2);
2686 if ((code == EQ_EXPR || code == NE_EXPR)
2687 && optimize
2688 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
2690 /* If one string is a string literal with LEN_TRIM longer
2691 than the length of the second string, the strings
2692 compare unequal. */
2693 int len = gfc_optimize_len_trim (len1, str1, kind);
2694 if (len > 0 && compare_tree_int (len2, len) < 0)
2695 return integer_one_node;
2696 len = gfc_optimize_len_trim (len2, str2, kind);
2697 if (len > 0 && compare_tree_int (len1, len) < 0)
2698 return integer_one_node;
2701 /* Build a call for the comparison. */
2702 if (kind == 1)
2703 fndecl = gfor_fndecl_compare_string;
2704 else if (kind == 4)
2705 fndecl = gfor_fndecl_compare_string_char4;
2706 else
2707 gcc_unreachable ();
2709 return build_call_expr_loc (input_location, fndecl, 4,
2710 len1, str1, len2, str2);
2714 /* Return the backend_decl for a procedure pointer component. */
2716 static tree
2717 get_proc_ptr_comp (gfc_expr *e)
2719 gfc_se comp_se;
2720 gfc_expr *e2;
2721 expr_t old_type;
2723 gfc_init_se (&comp_se, NULL);
2724 e2 = gfc_copy_expr (e);
2725 /* We have to restore the expr type later so that gfc_free_expr frees
2726 the exact same thing that was allocated.
2727 TODO: This is ugly. */
2728 old_type = e2->expr_type;
2729 e2->expr_type = EXPR_VARIABLE;
2730 gfc_conv_expr (&comp_se, e2);
2731 e2->expr_type = old_type;
2732 gfc_free_expr (e2);
2733 return build_fold_addr_expr_loc (input_location, comp_se.expr);
2737 /* Convert a typebound function reference from a class object. */
2738 static void
2739 conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
2741 gfc_ref *ref;
2742 tree var;
2744 if (TREE_CODE (base_object) != VAR_DECL)
2746 var = gfc_create_var (TREE_TYPE (base_object), NULL);
2747 gfc_add_modify (&se->pre, var, base_object);
2749 se->expr = gfc_class_vptr_get (base_object);
2750 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
2751 ref = expr->ref;
2752 while (ref && ref->next)
2753 ref = ref->next;
2754 gcc_assert (ref && ref->type == REF_COMPONENT);
2755 if (ref->u.c.sym->attr.extension)
2756 conv_parent_component_references (se, ref);
2757 gfc_conv_component_ref (se, ref);
2758 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
2762 static void
2763 conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
2765 tree tmp;
2767 if (gfc_is_proc_ptr_comp (expr))
2768 tmp = get_proc_ptr_comp (expr);
2769 else if (sym->attr.dummy)
2771 tmp = gfc_get_symbol_decl (sym);
2772 if (sym->attr.proc_pointer)
2773 tmp = build_fold_indirect_ref_loc (input_location,
2774 tmp);
2775 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
2776 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
2778 else
2780 if (!sym->backend_decl)
2781 sym->backend_decl = gfc_get_extern_function_decl (sym);
2783 TREE_USED (sym->backend_decl) = 1;
2785 tmp = sym->backend_decl;
2787 if (sym->attr.cray_pointee)
2789 /* TODO - make the cray pointee a pointer to a procedure,
2790 assign the pointer to it and use it for the call. This
2791 will do for now! */
2792 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
2793 gfc_get_symbol_decl (sym->cp_pointer));
2794 tmp = gfc_evaluate_now (tmp, &se->pre);
2797 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
2799 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
2800 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
2803 se->expr = tmp;
2807 /* Initialize MAPPING. */
2809 void
2810 gfc_init_interface_mapping (gfc_interface_mapping * mapping)
2812 mapping->syms = NULL;
2813 mapping->charlens = NULL;
2817 /* Free all memory held by MAPPING (but not MAPPING itself). */
2819 void
2820 gfc_free_interface_mapping (gfc_interface_mapping * mapping)
2822 gfc_interface_sym_mapping *sym;
2823 gfc_interface_sym_mapping *nextsym;
2824 gfc_charlen *cl;
2825 gfc_charlen *nextcl;
2827 for (sym = mapping->syms; sym; sym = nextsym)
2829 nextsym = sym->next;
2830 sym->new_sym->n.sym->formal = NULL;
2831 gfc_free_symbol (sym->new_sym->n.sym);
2832 gfc_free_expr (sym->expr);
2833 free (sym->new_sym);
2834 free (sym);
2836 for (cl = mapping->charlens; cl; cl = nextcl)
2838 nextcl = cl->next;
2839 gfc_free_expr (cl->length);
2840 free (cl);
2845 /* Return a copy of gfc_charlen CL. Add the returned structure to
2846 MAPPING so that it will be freed by gfc_free_interface_mapping. */
2848 static gfc_charlen *
2849 gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
2850 gfc_charlen * cl)
2852 gfc_charlen *new_charlen;
2854 new_charlen = gfc_get_charlen ();
2855 new_charlen->next = mapping->charlens;
2856 new_charlen->length = gfc_copy_expr (cl->length);
2858 mapping->charlens = new_charlen;
2859 return new_charlen;
2863 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
2864 array variable that can be used as the actual argument for dummy
2865 argument SYM. Add any initialization code to BLOCK. PACKED is as
2866 for gfc_get_nodesc_array_type and DATA points to the first element
2867 in the passed array. */
2869 static tree
2870 gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
2871 gfc_packed packed, tree data)
2873 tree type;
2874 tree var;
2876 type = gfc_typenode_for_spec (&sym->ts);
2877 type = gfc_get_nodesc_array_type (type, sym->as, packed,
2878 !sym->attr.target && !sym->attr.pointer
2879 && !sym->attr.proc_pointer);
2881 var = gfc_create_var (type, "ifm");
2882 gfc_add_modify (block, var, fold_convert (type, data));
2884 return var;
2888 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
2889 and offset of descriptorless array type TYPE given that it has the same
2890 size as DESC. Add any set-up code to BLOCK. */
2892 static void
2893 gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
2895 int n;
2896 tree dim;
2897 tree offset;
2898 tree tmp;
2900 offset = gfc_index_zero_node;
2901 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
2903 dim = gfc_rank_cst[n];
2904 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
2905 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
2907 GFC_TYPE_ARRAY_LBOUND (type, n)
2908 = gfc_conv_descriptor_lbound_get (desc, dim);
2909 GFC_TYPE_ARRAY_UBOUND (type, n)
2910 = gfc_conv_descriptor_ubound_get (desc, dim);
2912 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
2914 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2915 gfc_array_index_type,
2916 gfc_conv_descriptor_ubound_get (desc, dim),
2917 gfc_conv_descriptor_lbound_get (desc, dim));
2918 tmp = fold_build2_loc (input_location, PLUS_EXPR,
2919 gfc_array_index_type,
2920 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
2921 tmp = gfc_evaluate_now (tmp, block);
2922 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
2924 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2925 GFC_TYPE_ARRAY_LBOUND (type, n),
2926 GFC_TYPE_ARRAY_STRIDE (type, n));
2927 offset = fold_build2_loc (input_location, MINUS_EXPR,
2928 gfc_array_index_type, offset, tmp);
2930 offset = gfc_evaluate_now (offset, block);
2931 GFC_TYPE_ARRAY_OFFSET (type) = offset;
2935 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
2936 in SE. The caller may still use se->expr and se->string_length after
2937 calling this function. */
2939 void
2940 gfc_add_interface_mapping (gfc_interface_mapping * mapping,
2941 gfc_symbol * sym, gfc_se * se,
2942 gfc_expr *expr)
2944 gfc_interface_sym_mapping *sm;
2945 tree desc;
2946 tree tmp;
2947 tree value;
2948 gfc_symbol *new_sym;
2949 gfc_symtree *root;
2950 gfc_symtree *new_symtree;
2952 /* Create a new symbol to represent the actual argument. */
2953 new_sym = gfc_new_symbol (sym->name, NULL);
2954 new_sym->ts = sym->ts;
2955 new_sym->as = gfc_copy_array_spec (sym->as);
2956 new_sym->attr.referenced = 1;
2957 new_sym->attr.dimension = sym->attr.dimension;
2958 new_sym->attr.contiguous = sym->attr.contiguous;
2959 new_sym->attr.codimension = sym->attr.codimension;
2960 new_sym->attr.pointer = sym->attr.pointer;
2961 new_sym->attr.allocatable = sym->attr.allocatable;
2962 new_sym->attr.flavor = sym->attr.flavor;
2963 new_sym->attr.function = sym->attr.function;
2965 /* Ensure that the interface is available and that
2966 descriptors are passed for array actual arguments. */
2967 if (sym->attr.flavor == FL_PROCEDURE)
2969 new_sym->formal = expr->symtree->n.sym->formal;
2970 new_sym->attr.always_explicit
2971 = expr->symtree->n.sym->attr.always_explicit;
2974 /* Create a fake symtree for it. */
2975 root = NULL;
2976 new_symtree = gfc_new_symtree (&root, sym->name);
2977 new_symtree->n.sym = new_sym;
2978 gcc_assert (new_symtree == root);
2980 /* Create a dummy->actual mapping. */
2981 sm = XCNEW (gfc_interface_sym_mapping);
2982 sm->next = mapping->syms;
2983 sm->old = sym;
2984 sm->new_sym = new_symtree;
2985 sm->expr = gfc_copy_expr (expr);
2986 mapping->syms = sm;
2988 /* Stabilize the argument's value. */
2989 if (!sym->attr.function && se)
2990 se->expr = gfc_evaluate_now (se->expr, &se->pre);
2992 if (sym->ts.type == BT_CHARACTER)
2994 /* Create a copy of the dummy argument's length. */
2995 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
2996 sm->expr->ts.u.cl = new_sym->ts.u.cl;
2998 /* If the length is specified as "*", record the length that
2999 the caller is passing. We should use the callee's length
3000 in all other cases. */
3001 if (!new_sym->ts.u.cl->length && se)
3003 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
3004 new_sym->ts.u.cl->backend_decl = se->string_length;
3008 if (!se)
3009 return;
3011 /* Use the passed value as-is if the argument is a function. */
3012 if (sym->attr.flavor == FL_PROCEDURE)
3013 value = se->expr;
3015 /* If the argument is either a string or a pointer to a string,
3016 convert it to a boundless character type. */
3017 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
3019 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
3020 tmp = build_pointer_type (tmp);
3021 if (sym->attr.pointer)
3022 value = build_fold_indirect_ref_loc (input_location,
3023 se->expr);
3024 else
3025 value = se->expr;
3026 value = fold_convert (tmp, value);
3029 /* If the argument is a scalar, a pointer to an array or an allocatable,
3030 dereference it. */
3031 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
3032 value = build_fold_indirect_ref_loc (input_location,
3033 se->expr);
3035 /* For character(*), use the actual argument's descriptor. */
3036 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
3037 value = build_fold_indirect_ref_loc (input_location,
3038 se->expr);
3040 /* If the argument is an array descriptor, use it to determine
3041 information about the actual argument's shape. */
3042 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
3043 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
3045 /* Get the actual argument's descriptor. */
3046 desc = build_fold_indirect_ref_loc (input_location,
3047 se->expr);
3049 /* Create the replacement variable. */
3050 tmp = gfc_conv_descriptor_data_get (desc);
3051 value = gfc_get_interface_mapping_array (&se->pre, sym,
3052 PACKED_NO, tmp);
3054 /* Use DESC to work out the upper bounds, strides and offset. */
3055 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
3057 else
3058 /* Otherwise we have a packed array. */
3059 value = gfc_get_interface_mapping_array (&se->pre, sym,
3060 PACKED_FULL, se->expr);
3062 new_sym->backend_decl = value;
3066 /* Called once all dummy argument mappings have been added to MAPPING,
3067 but before the mapping is used to evaluate expressions. Pre-evaluate
3068 the length of each argument, adding any initialization code to PRE and
3069 any finalization code to POST. */
3071 void
3072 gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
3073 stmtblock_t * pre, stmtblock_t * post)
3075 gfc_interface_sym_mapping *sym;
3076 gfc_expr *expr;
3077 gfc_se se;
3079 for (sym = mapping->syms; sym; sym = sym->next)
3080 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
3081 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
3083 expr = sym->new_sym->n.sym->ts.u.cl->length;
3084 gfc_apply_interface_mapping_to_expr (mapping, expr);
3085 gfc_init_se (&se, NULL);
3086 gfc_conv_expr (&se, expr);
3087 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
3088 se.expr = gfc_evaluate_now (se.expr, &se.pre);
3089 gfc_add_block_to_block (pre, &se.pre);
3090 gfc_add_block_to_block (post, &se.post);
3092 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
3097 /* Like gfc_apply_interface_mapping_to_expr, but applied to
3098 constructor C. */
3100 static void
3101 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
3102 gfc_constructor_base base)
3104 gfc_constructor *c;
3105 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
3107 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
3108 if (c->iterator)
3110 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
3111 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
3112 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
3118 /* Like gfc_apply_interface_mapping_to_expr, but applied to
3119 reference REF. */
3121 static void
3122 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
3123 gfc_ref * ref)
3125 int n;
3127 for (; ref; ref = ref->next)
3128 switch (ref->type)
3130 case REF_ARRAY:
3131 for (n = 0; n < ref->u.ar.dimen; n++)
3133 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
3134 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
3135 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
3137 break;
3139 case REF_COMPONENT:
3140 break;
3142 case REF_SUBSTRING:
3143 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
3144 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
3145 break;
3150 /* Convert intrinsic function calls into result expressions. */
3152 static bool
3153 gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
3155 gfc_symbol *sym;
3156 gfc_expr *new_expr;
3157 gfc_expr *arg1;
3158 gfc_expr *arg2;
3159 int d, dup;
3161 arg1 = expr->value.function.actual->expr;
3162 if (expr->value.function.actual->next)
3163 arg2 = expr->value.function.actual->next->expr;
3164 else
3165 arg2 = NULL;
3167 sym = arg1->symtree->n.sym;
3169 if (sym->attr.dummy)
3170 return false;
3172 new_expr = NULL;
3174 switch (expr->value.function.isym->id)
3176 case GFC_ISYM_LEN:
3177 /* TODO figure out why this condition is necessary. */
3178 if (sym->attr.function
3179 && (arg1->ts.u.cl->length == NULL
3180 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
3181 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
3182 return false;
3184 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
3185 break;
3187 case GFC_ISYM_SIZE:
3188 if (!sym->as || sym->as->rank == 0)
3189 return false;
3191 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
3193 dup = mpz_get_si (arg2->value.integer);
3194 d = dup - 1;
3196 else
3198 dup = sym->as->rank;
3199 d = 0;
3202 for (; d < dup; d++)
3204 gfc_expr *tmp;
3206 if (!sym->as->upper[d] || !sym->as->lower[d])
3208 gfc_free_expr (new_expr);
3209 return false;
3212 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
3213 gfc_get_int_expr (gfc_default_integer_kind,
3214 NULL, 1));
3215 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
3216 if (new_expr)
3217 new_expr = gfc_multiply (new_expr, tmp);
3218 else
3219 new_expr = tmp;
3221 break;
3223 case GFC_ISYM_LBOUND:
3224 case GFC_ISYM_UBOUND:
3225 /* TODO These implementations of lbound and ubound do not limit if
3226 the size < 0, according to F95's 13.14.53 and 13.14.113. */
3228 if (!sym->as || sym->as->rank == 0)
3229 return false;
3231 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
3232 d = mpz_get_si (arg2->value.integer) - 1;
3233 else
3234 /* TODO: If the need arises, this could produce an array of
3235 ubound/lbounds. */
3236 gcc_unreachable ();
3238 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
3240 if (sym->as->lower[d])
3241 new_expr = gfc_copy_expr (sym->as->lower[d]);
3243 else
3245 if (sym->as->upper[d])
3246 new_expr = gfc_copy_expr (sym->as->upper[d]);
3248 break;
3250 default:
3251 break;
3254 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
3255 if (!new_expr)
3256 return false;
3258 gfc_replace_expr (expr, new_expr);
3259 return true;
3263 static void
3264 gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
3265 gfc_interface_mapping * mapping)
3267 gfc_formal_arglist *f;
3268 gfc_actual_arglist *actual;
3270 actual = expr->value.function.actual;
3271 f = map_expr->symtree->n.sym->formal;
3273 for (; f && actual; f = f->next, actual = actual->next)
3275 if (!actual->expr)
3276 continue;
3278 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
3281 if (map_expr->symtree->n.sym->attr.dimension)
3283 int d;
3284 gfc_array_spec *as;
3286 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
3288 for (d = 0; d < as->rank; d++)
3290 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
3291 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
3294 expr->value.function.esym->as = as;
3297 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
3299 expr->value.function.esym->ts.u.cl->length
3300 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
3302 gfc_apply_interface_mapping_to_expr (mapping,
3303 expr->value.function.esym->ts.u.cl->length);
3308 /* EXPR is a copy of an expression that appeared in the interface
3309 associated with MAPPING. Walk it recursively looking for references to
3310 dummy arguments that MAPPING maps to actual arguments. Replace each such
3311 reference with a reference to the associated actual argument. */
3313 static void
3314 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
3315 gfc_expr * expr)
3317 gfc_interface_sym_mapping *sym;
3318 gfc_actual_arglist *actual;
3320 if (!expr)
3321 return;
3323 /* Copying an expression does not copy its length, so do that here. */
3324 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
3326 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
3327 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
3330 /* Apply the mapping to any references. */
3331 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
3333 /* ...and to the expression's symbol, if it has one. */
3334 /* TODO Find out why the condition on expr->symtree had to be moved into
3335 the loop rather than being outside it, as originally. */
3336 for (sym = mapping->syms; sym; sym = sym->next)
3337 if (expr->symtree && sym->old == expr->symtree->n.sym)
3339 if (sym->new_sym->n.sym->backend_decl)
3340 expr->symtree = sym->new_sym;
3341 else if (sym->expr)
3342 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
3343 /* Replace base type for polymorphic arguments. */
3344 if (expr->ref && expr->ref->type == REF_COMPONENT
3345 && sym->expr && sym->expr->ts.type == BT_CLASS)
3346 expr->ref->u.c.sym = sym->expr->ts.u.derived;
3349 /* ...and to subexpressions in expr->value. */
3350 switch (expr->expr_type)
3352 case EXPR_VARIABLE:
3353 case EXPR_CONSTANT:
3354 case EXPR_NULL:
3355 case EXPR_SUBSTRING:
3356 break;
3358 case EXPR_OP:
3359 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
3360 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
3361 break;
3363 case EXPR_FUNCTION:
3364 for (actual = expr->value.function.actual; actual; actual = actual->next)
3365 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
3367 if (expr->value.function.esym == NULL
3368 && expr->value.function.isym != NULL
3369 && expr->value.function.actual->expr->symtree
3370 && gfc_map_intrinsic_function (expr, mapping))
3371 break;
3373 for (sym = mapping->syms; sym; sym = sym->next)
3374 if (sym->old == expr->value.function.esym)
3376 expr->value.function.esym = sym->new_sym->n.sym;
3377 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
3378 expr->value.function.esym->result = sym->new_sym->n.sym;
3380 break;
3382 case EXPR_ARRAY:
3383 case EXPR_STRUCTURE:
3384 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
3385 break;
3387 case EXPR_COMPCALL:
3388 case EXPR_PPC:
3389 gcc_unreachable ();
3390 break;
3393 return;
3397 /* Evaluate interface expression EXPR using MAPPING. Store the result
3398 in SE. */
3400 void
3401 gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
3402 gfc_se * se, gfc_expr * expr)
3404 expr = gfc_copy_expr (expr);
3405 gfc_apply_interface_mapping_to_expr (mapping, expr);
3406 gfc_conv_expr (se, expr);
3407 se->expr = gfc_evaluate_now (se->expr, &se->pre);
3408 gfc_free_expr (expr);
3412 /* Returns a reference to a temporary array into which a component of
3413 an actual argument derived type array is copied and then returned
3414 after the function call. */
3415 void
3416 gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
3417 sym_intent intent, bool formal_ptr)
3419 gfc_se lse;
3420 gfc_se rse;
3421 gfc_ss *lss;
3422 gfc_ss *rss;
3423 gfc_loopinfo loop;
3424 gfc_loopinfo loop2;
3425 gfc_array_info *info;
3426 tree offset;
3427 tree tmp_index;
3428 tree tmp;
3429 tree base_type;
3430 tree size;
3431 stmtblock_t body;
3432 int n;
3433 int dimen;
3435 gcc_assert (expr->expr_type == EXPR_VARIABLE);
3437 gfc_init_se (&lse, NULL);
3438 gfc_init_se (&rse, NULL);
3440 /* Walk the argument expression. */
3441 rss = gfc_walk_expr (expr);
3443 gcc_assert (rss != gfc_ss_terminator);
3445 /* Initialize the scalarizer. */
3446 gfc_init_loopinfo (&loop);
3447 gfc_add_ss_to_loop (&loop, rss);
3449 /* Calculate the bounds of the scalarization. */
3450 gfc_conv_ss_startstride (&loop);
3452 /* Build an ss for the temporary. */
3453 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
3454 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
3456 base_type = gfc_typenode_for_spec (&expr->ts);
3457 if (GFC_ARRAY_TYPE_P (base_type)
3458 || GFC_DESCRIPTOR_TYPE_P (base_type))
3459 base_type = gfc_get_element_type (base_type);
3461 if (expr->ts.type == BT_CLASS)
3462 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
3464 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
3465 ? expr->ts.u.cl->backend_decl
3466 : NULL),
3467 loop.dimen);
3469 parmse->string_length = loop.temp_ss->info->string_length;
3471 /* Associate the SS with the loop. */
3472 gfc_add_ss_to_loop (&loop, loop.temp_ss);
3474 /* Setup the scalarizing loops. */
3475 gfc_conv_loop_setup (&loop, &expr->where);
3477 /* Pass the temporary descriptor back to the caller. */
3478 info = &loop.temp_ss->info->data.array;
3479 parmse->expr = info->descriptor;
3481 /* Setup the gfc_se structures. */
3482 gfc_copy_loopinfo_to_se (&lse, &loop);
3483 gfc_copy_loopinfo_to_se (&rse, &loop);
3485 rse.ss = rss;
3486 lse.ss = loop.temp_ss;
3487 gfc_mark_ss_chain_used (rss, 1);
3488 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3490 /* Start the scalarized loop body. */
3491 gfc_start_scalarized_body (&loop, &body);
3493 /* Translate the expression. */
3494 gfc_conv_expr (&rse, expr);
3496 gfc_conv_tmp_array_ref (&lse);
3498 if (intent != INTENT_OUT)
3500 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false, true);
3501 gfc_add_expr_to_block (&body, tmp);
3502 gcc_assert (rse.ss == gfc_ss_terminator);
3503 gfc_trans_scalarizing_loops (&loop, &body);
3505 else
3507 /* Make sure that the temporary declaration survives by merging
3508 all the loop declarations into the current context. */
3509 for (n = 0; n < loop.dimen; n++)
3511 gfc_merge_block_scope (&body);
3512 body = loop.code[loop.order[n]];
3514 gfc_merge_block_scope (&body);
3517 /* Add the post block after the second loop, so that any
3518 freeing of allocated memory is done at the right time. */
3519 gfc_add_block_to_block (&parmse->pre, &loop.pre);
3521 /**********Copy the temporary back again.*********/
3523 gfc_init_se (&lse, NULL);
3524 gfc_init_se (&rse, NULL);
3526 /* Walk the argument expression. */
3527 lss = gfc_walk_expr (expr);
3528 rse.ss = loop.temp_ss;
3529 lse.ss = lss;
3531 /* Initialize the scalarizer. */
3532 gfc_init_loopinfo (&loop2);
3533 gfc_add_ss_to_loop (&loop2, lss);
3535 /* Calculate the bounds of the scalarization. */
3536 gfc_conv_ss_startstride (&loop2);
3538 /* Setup the scalarizing loops. */
3539 gfc_conv_loop_setup (&loop2, &expr->where);
3541 gfc_copy_loopinfo_to_se (&lse, &loop2);
3542 gfc_copy_loopinfo_to_se (&rse, &loop2);
3544 gfc_mark_ss_chain_used (lss, 1);
3545 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3547 /* Declare the variable to hold the temporary offset and start the
3548 scalarized loop body. */
3549 offset = gfc_create_var (gfc_array_index_type, NULL);
3550 gfc_start_scalarized_body (&loop2, &body);
3552 /* Build the offsets for the temporary from the loop variables. The
3553 temporary array has lbounds of zero and strides of one in all
3554 dimensions, so this is very simple. The offset is only computed
3555 outside the innermost loop, so the overall transfer could be
3556 optimized further. */
3557 info = &rse.ss->info->data.array;
3558 dimen = rse.ss->dimen;
3560 tmp_index = gfc_index_zero_node;
3561 for (n = dimen - 1; n > 0; n--)
3563 tree tmp_str;
3564 tmp = rse.loop->loopvar[n];
3565 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3566 tmp, rse.loop->from[n]);
3567 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3568 tmp, tmp_index);
3570 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
3571 gfc_array_index_type,
3572 rse.loop->to[n-1], rse.loop->from[n-1]);
3573 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
3574 gfc_array_index_type,
3575 tmp_str, gfc_index_one_node);
3577 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
3578 gfc_array_index_type, tmp, tmp_str);
3581 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
3582 gfc_array_index_type,
3583 tmp_index, rse.loop->from[0]);
3584 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
3586 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
3587 gfc_array_index_type,
3588 rse.loop->loopvar[0], offset);
3590 /* Now use the offset for the reference. */
3591 tmp = build_fold_indirect_ref_loc (input_location,
3592 info->data);
3593 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
3595 if (expr->ts.type == BT_CHARACTER)
3596 rse.string_length = expr->ts.u.cl->backend_decl;
3598 gfc_conv_expr (&lse, expr);
3600 gcc_assert (lse.ss == gfc_ss_terminator);
3602 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false, true);
3603 gfc_add_expr_to_block (&body, tmp);
3605 /* Generate the copying loops. */
3606 gfc_trans_scalarizing_loops (&loop2, &body);
3608 /* Wrap the whole thing up by adding the second loop to the post-block
3609 and following it by the post-block of the first loop. In this way,
3610 if the temporary needs freeing, it is done after use! */
3611 if (intent != INTENT_IN)
3613 gfc_add_block_to_block (&parmse->post, &loop2.pre);
3614 gfc_add_block_to_block (&parmse->post, &loop2.post);
3617 gfc_add_block_to_block (&parmse->post, &loop.post);
3619 gfc_cleanup_loop (&loop);
3620 gfc_cleanup_loop (&loop2);
3622 /* Pass the string length to the argument expression. */
3623 if (expr->ts.type == BT_CHARACTER)
3624 parmse->string_length = expr->ts.u.cl->backend_decl;
3626 /* Determine the offset for pointer formal arguments and set the
3627 lbounds to one. */
3628 if (formal_ptr)
3630 size = gfc_index_one_node;
3631 offset = gfc_index_zero_node;
3632 for (n = 0; n < dimen; n++)
3634 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
3635 gfc_rank_cst[n]);
3636 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3637 gfc_array_index_type, tmp,
3638 gfc_index_one_node);
3639 gfc_conv_descriptor_ubound_set (&parmse->pre,
3640 parmse->expr,
3641 gfc_rank_cst[n],
3642 tmp);
3643 gfc_conv_descriptor_lbound_set (&parmse->pre,
3644 parmse->expr,
3645 gfc_rank_cst[n],
3646 gfc_index_one_node);
3647 size = gfc_evaluate_now (size, &parmse->pre);
3648 offset = fold_build2_loc (input_location, MINUS_EXPR,
3649 gfc_array_index_type,
3650 offset, size);
3651 offset = gfc_evaluate_now (offset, &parmse->pre);
3652 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3653 gfc_array_index_type,
3654 rse.loop->to[n], rse.loop->from[n]);
3655 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3656 gfc_array_index_type,
3657 tmp, gfc_index_one_node);
3658 size = fold_build2_loc (input_location, MULT_EXPR,
3659 gfc_array_index_type, size, tmp);
3662 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
3663 offset);
3666 /* We want either the address for the data or the address of the descriptor,
3667 depending on the mode of passing array arguments. */
3668 if (g77)
3669 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
3670 else
3671 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
3673 return;
3677 /* Generate the code for argument list functions. */
3679 static void
3680 conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
3682 /* Pass by value for g77 %VAL(arg), pass the address
3683 indirectly for %LOC, else by reference. Thus %REF
3684 is a "do-nothing" and %LOC is the same as an F95
3685 pointer. */
3686 if (strncmp (name, "%VAL", 4) == 0)
3687 gfc_conv_expr (se, expr);
3688 else if (strncmp (name, "%LOC", 4) == 0)
3690 gfc_conv_expr_reference (se, expr);
3691 se->expr = gfc_build_addr_expr (NULL, se->expr);
3693 else if (strncmp (name, "%REF", 4) == 0)
3694 gfc_conv_expr_reference (se, expr);
3695 else
3696 gfc_error ("Unknown argument list function at %L", &expr->where);
3700 /* The following routine generates code for the intrinsic
3701 procedures from the ISO_C_BINDING module:
3702 * C_LOC (function)
3703 * C_FUNLOC (function)
3704 * C_F_POINTER (subroutine)
3705 * C_F_PROCPOINTER (subroutine)
3706 * C_ASSOCIATED (function)
3707 One exception which is not handled here is C_F_POINTER with non-scalar
3708 arguments. Returns 1 if the call was replaced by inline code (else: 0). */
3710 static int
3711 conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
3712 gfc_actual_arglist * arg)
3714 gfc_symbol *fsym;
3716 if (sym->intmod_sym_id == ISOCBINDING_LOC)
3718 if (arg->expr->rank == 0)
3719 gfc_conv_expr_reference (se, arg->expr);
3720 else
3722 int f;
3723 /* This is really the actual arg because no formal arglist is
3724 created for C_LOC. */
3725 fsym = arg->expr->symtree->n.sym;
3727 /* We should want it to do g77 calling convention. */
3728 f = (fsym != NULL)
3729 && !(fsym->attr.pointer || fsym->attr.allocatable)
3730 && fsym->as->type != AS_ASSUMED_SHAPE;
3731 f = f || !sym->attr.always_explicit;
3733 gfc_conv_array_parameter (se, arg->expr, f, NULL, NULL, NULL);
3736 /* TODO -- the following two lines shouldn't be necessary, but if
3737 they're removed, a bug is exposed later in the code path.
3738 This workaround was thus introduced, but will have to be
3739 removed; please see PR 35150 for details about the issue. */
3740 se->expr = convert (pvoid_type_node, se->expr);
3741 se->expr = gfc_evaluate_now (se->expr, &se->pre);
3743 return 1;
3745 else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC)
3747 arg->expr->ts.type = sym->ts.u.derived->ts.type;
3748 arg->expr->ts.f90_type = sym->ts.u.derived->ts.f90_type;
3749 arg->expr->ts.kind = sym->ts.u.derived->ts.kind;
3750 gfc_conv_expr_reference (se, arg->expr);
3752 return 1;
3754 else if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
3755 || sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)
3757 /* Convert c_f_pointer and c_f_procpointer. */
3758 gfc_se cptrse;
3759 gfc_se fptrse;
3760 gfc_se shapese;
3761 gfc_ss *shape_ss;
3762 tree desc, dim, tmp, stride, offset;
3763 stmtblock_t body, block;
3764 gfc_loopinfo loop;
3766 gfc_init_se (&cptrse, NULL);
3767 gfc_conv_expr (&cptrse, arg->expr);
3768 gfc_add_block_to_block (&se->pre, &cptrse.pre);
3769 gfc_add_block_to_block (&se->post, &cptrse.post);
3771 gfc_init_se (&fptrse, NULL);
3772 if (arg->next->expr->rank == 0)
3774 if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
3775 || gfc_is_proc_ptr_comp (arg->next->expr))
3776 fptrse.want_pointer = 1;
3778 gfc_conv_expr (&fptrse, arg->next->expr);
3779 gfc_add_block_to_block (&se->pre, &fptrse.pre);
3780 gfc_add_block_to_block (&se->post, &fptrse.post);
3781 if (arg->next->expr->symtree->n.sym->attr.proc_pointer
3782 && arg->next->expr->symtree->n.sym->attr.dummy)
3783 fptrse.expr = build_fold_indirect_ref_loc (input_location,
3784 fptrse.expr);
3785 se->expr = fold_build2_loc (input_location, MODIFY_EXPR,
3786 TREE_TYPE (fptrse.expr),
3787 fptrse.expr,
3788 fold_convert (TREE_TYPE (fptrse.expr),
3789 cptrse.expr));
3790 return 1;
3793 gfc_start_block (&block);
3795 /* Get the descriptor of the Fortran pointer. */
3796 fptrse.descriptor_only = 1;
3797 gfc_conv_expr_descriptor (&fptrse, arg->next->expr);
3798 gfc_add_block_to_block (&block, &fptrse.pre);
3799 desc = fptrse.expr;
3801 /* Set data value, dtype, and offset. */
3802 tmp = GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc));
3803 gfc_conv_descriptor_data_set (&block, desc,
3804 fold_convert (tmp, cptrse.expr));
3805 gfc_add_modify (&block, gfc_conv_descriptor_dtype (desc),
3806 gfc_get_dtype (TREE_TYPE (desc)));
3808 /* Start scalarization of the bounds, using the shape argument. */
3810 shape_ss = gfc_walk_expr (arg->next->next->expr);
3811 gcc_assert (shape_ss != gfc_ss_terminator);
3812 gfc_init_se (&shapese, NULL);
3814 gfc_init_loopinfo (&loop);
3815 gfc_add_ss_to_loop (&loop, shape_ss);
3816 gfc_conv_ss_startstride (&loop);
3817 gfc_conv_loop_setup (&loop, &arg->next->expr->where);
3818 gfc_mark_ss_chain_used (shape_ss, 1);
3820 gfc_copy_loopinfo_to_se (&shapese, &loop);
3821 shapese.ss = shape_ss;
3823 stride = gfc_create_var (gfc_array_index_type, "stride");
3824 offset = gfc_create_var (gfc_array_index_type, "offset");
3825 gfc_add_modify (&block, stride, gfc_index_one_node);
3826 gfc_add_modify (&block, offset, gfc_index_zero_node);
3828 /* Loop body. */
3829 gfc_start_scalarized_body (&loop, &body);
3831 dim = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3832 loop.loopvar[0], loop.from[0]);
3834 /* Set bounds and stride. */
3835 gfc_conv_descriptor_lbound_set (&body, desc, dim, gfc_index_one_node);
3836 gfc_conv_descriptor_stride_set (&body, desc, dim, stride);
3838 gfc_conv_expr (&shapese, arg->next->next->expr);
3839 gfc_add_block_to_block (&body, &shapese.pre);
3840 gfc_conv_descriptor_ubound_set (&body, desc, dim, shapese.expr);
3841 gfc_add_block_to_block (&body, &shapese.post);
3843 /* Calculate offset. */
3844 gfc_add_modify (&body, offset,
3845 fold_build2_loc (input_location, PLUS_EXPR,
3846 gfc_array_index_type, offset, stride));
3847 /* Update stride. */
3848 gfc_add_modify (&body, stride,
3849 fold_build2_loc (input_location, MULT_EXPR,
3850 gfc_array_index_type, stride,
3851 fold_convert (gfc_array_index_type,
3852 shapese.expr)));
3853 /* Finish scalarization loop. */
3854 gfc_trans_scalarizing_loops (&loop, &body);
3855 gfc_add_block_to_block (&block, &loop.pre);
3856 gfc_add_block_to_block (&block, &loop.post);
3857 gfc_add_block_to_block (&block, &fptrse.post);
3858 gfc_cleanup_loop (&loop);
3860 gfc_add_modify (&block, offset,
3861 fold_build1_loc (input_location, NEGATE_EXPR,
3862 gfc_array_index_type, offset));
3863 gfc_conv_descriptor_offset_set (&block, desc, offset);
3865 se->expr = gfc_finish_block (&block);
3866 return 1;
3868 else if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
3870 gfc_se arg1se;
3871 gfc_se arg2se;
3873 /* Build the addr_expr for the first argument. The argument is
3874 already an *address* so we don't need to set want_pointer in
3875 the gfc_se. */
3876 gfc_init_se (&arg1se, NULL);
3877 gfc_conv_expr (&arg1se, arg->expr);
3878 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3879 gfc_add_block_to_block (&se->post, &arg1se.post);
3881 /* See if we were given two arguments. */
3882 if (arg->next == NULL)
3883 /* Only given one arg so generate a null and do a
3884 not-equal comparison against the first arg. */
3885 se->expr = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
3886 arg1se.expr,
3887 fold_convert (TREE_TYPE (arg1se.expr),
3888 null_pointer_node));
3889 else
3891 tree eq_expr;
3892 tree not_null_expr;
3894 /* Given two arguments so build the arg2se from second arg. */
3895 gfc_init_se (&arg2se, NULL);
3896 gfc_conv_expr (&arg2se, arg->next->expr);
3897 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3898 gfc_add_block_to_block (&se->post, &arg2se.post);
3900 /* Generate test to compare that the two args are equal. */
3901 eq_expr = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
3902 arg1se.expr, arg2se.expr);
3903 /* Generate test to ensure that the first arg is not null. */
3904 not_null_expr = fold_build2_loc (input_location, NE_EXPR,
3905 boolean_type_node,
3906 arg1se.expr, null_pointer_node);
3908 /* Finally, the generated test must check that both arg1 is not
3909 NULL and that it is equal to the second arg. */
3910 se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3911 boolean_type_node,
3912 not_null_expr, eq_expr);
3915 return 1;
3918 /* Nothing was done. */
3919 return 0;
3923 /* Generate code for a procedure call. Note can return se->post != NULL.
3924 If se->direct_byref is set then se->expr contains the return parameter.
3925 Return nonzero, if the call has alternate specifiers.
3926 'expr' is only needed for procedure pointer components. */
3929 gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
3930 gfc_actual_arglist * args, gfc_expr * expr,
3931 vec<tree, va_gc> *append_args)
3933 gfc_interface_mapping mapping;
3934 vec<tree, va_gc> *arglist;
3935 vec<tree, va_gc> *retargs;
3936 tree tmp;
3937 tree fntype;
3938 gfc_se parmse;
3939 gfc_array_info *info;
3940 int byref;
3941 int parm_kind;
3942 tree type;
3943 tree var;
3944 tree len;
3945 tree base_object;
3946 vec<tree, va_gc> *stringargs;
3947 tree result = NULL;
3948 gfc_formal_arglist *formal;
3949 gfc_actual_arglist *arg;
3950 int has_alternate_specifier = 0;
3951 bool need_interface_mapping;
3952 bool callee_alloc;
3953 gfc_typespec ts;
3954 gfc_charlen cl;
3955 gfc_expr *e;
3956 gfc_symbol *fsym;
3957 stmtblock_t post;
3958 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
3959 gfc_component *comp = NULL;
3960 int arglen;
3962 arglist = NULL;
3963 retargs = NULL;
3964 stringargs = NULL;
3965 var = NULL_TREE;
3966 len = NULL_TREE;
3967 gfc_clear_ts (&ts);
3969 if (sym->from_intmod == INTMOD_ISO_C_BINDING
3970 && conv_isocbinding_procedure (se, sym, args))
3971 return 0;
3973 comp = gfc_get_proc_ptr_comp (expr);
3975 if (se->ss != NULL)
3977 if (!sym->attr.elemental && !(comp && comp->attr.elemental))
3979 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
3980 if (se->ss->info->useflags)
3982 gcc_assert ((!comp && gfc_return_by_reference (sym)
3983 && sym->result->attr.dimension)
3984 || (comp && comp->attr.dimension));
3985 gcc_assert (se->loop != NULL);
3987 /* Access the previously obtained result. */
3988 gfc_conv_tmp_array_ref (se);
3989 return 0;
3992 info = &se->ss->info->data.array;
3994 else
3995 info = NULL;
3997 gfc_init_block (&post);
3998 gfc_init_interface_mapping (&mapping);
3999 if (!comp)
4001 formal = sym->formal;
4002 need_interface_mapping = sym->attr.dimension ||
4003 (sym->ts.type == BT_CHARACTER
4004 && sym->ts.u.cl->length
4005 && sym->ts.u.cl->length->expr_type
4006 != EXPR_CONSTANT);
4008 else
4010 formal = comp->formal;
4011 need_interface_mapping = comp->attr.dimension ||
4012 (comp->ts.type == BT_CHARACTER
4013 && comp->ts.u.cl->length
4014 && comp->ts.u.cl->length->expr_type
4015 != EXPR_CONSTANT);
4018 base_object = NULL_TREE;
4020 /* Evaluate the arguments. */
4021 for (arg = args; arg != NULL;
4022 arg = arg->next, formal = formal ? formal->next : NULL)
4024 e = arg->expr;
4025 fsym = formal ? formal->sym : NULL;
4026 parm_kind = MISSING;
4028 /* Class array expressions are sometimes coming completely unadorned
4029 with either arrayspec or _data component. Correct that here.
4030 OOP-TODO: Move this to the frontend. */
4031 if (e && e->expr_type == EXPR_VARIABLE
4032 && !e->ref
4033 && e->ts.type == BT_CLASS
4034 && (CLASS_DATA (e)->attr.codimension
4035 || CLASS_DATA (e)->attr.dimension))
4037 gfc_typespec temp_ts = e->ts;
4038 gfc_add_class_array_ref (e);
4039 e->ts = temp_ts;
4042 if (e == NULL)
4044 if (se->ignore_optional)
4046 /* Some intrinsics have already been resolved to the correct
4047 parameters. */
4048 continue;
4050 else if (arg->label)
4052 has_alternate_specifier = 1;
4053 continue;
4055 else
4057 /* Pass a NULL pointer for an absent arg. */
4058 gfc_init_se (&parmse, NULL);
4059 parmse.expr = null_pointer_node;
4060 if (arg->missing_arg_type == BT_CHARACTER)
4061 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
4064 else if (arg->expr->expr_type == EXPR_NULL
4065 && fsym && !fsym->attr.pointer
4066 && (fsym->ts.type != BT_CLASS
4067 || !CLASS_DATA (fsym)->attr.class_pointer))
4069 /* Pass a NULL pointer to denote an absent arg. */
4070 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
4071 && (fsym->ts.type != BT_CLASS
4072 || !CLASS_DATA (fsym)->attr.allocatable));
4073 gfc_init_se (&parmse, NULL);
4074 parmse.expr = null_pointer_node;
4075 if (arg->missing_arg_type == BT_CHARACTER)
4076 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
4078 else if (fsym && fsym->ts.type == BT_CLASS
4079 && e->ts.type == BT_DERIVED)
4081 /* The derived type needs to be converted to a temporary
4082 CLASS object. */
4083 gfc_init_se (&parmse, se);
4084 gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
4085 fsym->attr.optional
4086 && e->expr_type == EXPR_VARIABLE
4087 && e->symtree->n.sym->attr.optional,
4088 CLASS_DATA (fsym)->attr.class_pointer
4089 || CLASS_DATA (fsym)->attr.allocatable);
4091 else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS)
4093 /* The intrinsic type needs to be converted to a temporary
4094 CLASS object for the unlimited polymorphic formal. */
4095 gfc_init_se (&parmse, se);
4096 gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
4098 else if (se->ss && se->ss->info->useflags)
4100 gfc_ss *ss;
4102 ss = se->ss;
4104 /* An elemental function inside a scalarized loop. */
4105 gfc_init_se (&parmse, se);
4106 parm_kind = ELEMENTAL;
4108 if (ss->dimen > 0 && e->expr_type == EXPR_VARIABLE
4109 && ss->info->data.array.ref == NULL)
4111 gfc_conv_tmp_array_ref (&parmse);
4112 if (e->ts.type == BT_CHARACTER)
4113 gfc_conv_string_parameter (&parmse);
4114 else
4115 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
4117 else
4119 gfc_conv_expr_reference (&parmse, e);
4120 if (e->ts.type == BT_CHARACTER && !e->rank
4121 && e->expr_type == EXPR_FUNCTION)
4122 parmse.expr = build_fold_indirect_ref_loc (input_location,
4123 parmse.expr);
4126 if (fsym && fsym->ts.type == BT_DERIVED
4127 && gfc_is_class_container_ref (e))
4129 parmse.expr = gfc_class_data_get (parmse.expr);
4131 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
4132 && e->symtree->n.sym->attr.optional)
4134 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
4135 parmse.expr = build3_loc (input_location, COND_EXPR,
4136 TREE_TYPE (parmse.expr),
4137 cond, parmse.expr,
4138 fold_convert (TREE_TYPE (parmse.expr),
4139 null_pointer_node));
4143 /* If we are passing an absent array as optional dummy to an
4144 elemental procedure, make sure that we pass NULL when the data
4145 pointer is NULL. We need this extra conditional because of
4146 scalarization which passes arrays elements to the procedure,
4147 ignoring the fact that the array can be absent/unallocated/... */
4148 if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
4150 tree descriptor_data;
4152 descriptor_data = ss->info->data.array.data;
4153 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
4154 descriptor_data,
4155 fold_convert (TREE_TYPE (descriptor_data),
4156 null_pointer_node));
4157 parmse.expr
4158 = fold_build3_loc (input_location, COND_EXPR,
4159 TREE_TYPE (parmse.expr),
4160 gfc_unlikely (tmp),
4161 fold_convert (TREE_TYPE (parmse.expr),
4162 null_pointer_node),
4163 parmse.expr);
4166 /* The scalarizer does not repackage the reference to a class
4167 array - instead it returns a pointer to the data element. */
4168 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
4169 gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
4170 fsym->attr.intent != INTENT_IN
4171 && (CLASS_DATA (fsym)->attr.class_pointer
4172 || CLASS_DATA (fsym)->attr.allocatable),
4173 fsym->attr.optional
4174 && e->expr_type == EXPR_VARIABLE
4175 && e->symtree->n.sym->attr.optional,
4176 CLASS_DATA (fsym)->attr.class_pointer
4177 || CLASS_DATA (fsym)->attr.allocatable);
4179 else
4181 bool scalar;
4182 gfc_ss *argss;
4184 gfc_init_se (&parmse, NULL);
4186 /* Check whether the expression is a scalar or not; we cannot use
4187 e->rank as it can be nonzero for functions arguments. */
4188 argss = gfc_walk_expr (e);
4189 scalar = argss == gfc_ss_terminator;
4190 if (!scalar)
4191 gfc_free_ss_chain (argss);
4193 /* Special handling for passing scalar polymorphic coarrays;
4194 otherwise one passes "class->_data.data" instead of "&class". */
4195 if (e->rank == 0 && e->ts.type == BT_CLASS
4196 && fsym && fsym->ts.type == BT_CLASS
4197 && CLASS_DATA (fsym)->attr.codimension
4198 && !CLASS_DATA (fsym)->attr.dimension)
4200 gfc_add_class_array_ref (e);
4201 parmse.want_coarray = 1;
4202 scalar = false;
4205 /* A scalar or transformational function. */
4206 if (scalar)
4208 if (e->expr_type == EXPR_VARIABLE
4209 && e->symtree->n.sym->attr.cray_pointee
4210 && fsym && fsym->attr.flavor == FL_PROCEDURE)
4212 /* The Cray pointer needs to be converted to a pointer to
4213 a type given by the expression. */
4214 gfc_conv_expr (&parmse, e);
4215 type = build_pointer_type (TREE_TYPE (parmse.expr));
4216 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
4217 parmse.expr = convert (type, tmp);
4219 else if (fsym && fsym->attr.value)
4221 if (fsym->ts.type == BT_CHARACTER
4222 && fsym->ts.is_c_interop
4223 && fsym->ns->proc_name != NULL
4224 && fsym->ns->proc_name->attr.is_bind_c)
4226 parmse.expr = NULL;
4227 gfc_conv_scalar_char_value (fsym, &parmse, &e);
4228 if (parmse.expr == NULL)
4229 gfc_conv_expr (&parmse, e);
4231 else
4232 gfc_conv_expr (&parmse, e);
4234 else if (arg->name && arg->name[0] == '%')
4235 /* Argument list functions %VAL, %LOC and %REF are signalled
4236 through arg->name. */
4237 conv_arglist_function (&parmse, arg->expr, arg->name);
4238 else if ((e->expr_type == EXPR_FUNCTION)
4239 && ((e->value.function.esym
4240 && e->value.function.esym->result->attr.pointer)
4241 || (!e->value.function.esym
4242 && e->symtree->n.sym->attr.pointer))
4243 && fsym && fsym->attr.target)
4245 gfc_conv_expr (&parmse, e);
4246 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
4248 else if (e->expr_type == EXPR_FUNCTION
4249 && e->symtree->n.sym->result
4250 && e->symtree->n.sym->result != e->symtree->n.sym
4251 && e->symtree->n.sym->result->attr.proc_pointer)
4253 /* Functions returning procedure pointers. */
4254 gfc_conv_expr (&parmse, e);
4255 if (fsym && fsym->attr.proc_pointer)
4256 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
4258 else
4260 if (e->ts.type == BT_CLASS && fsym
4261 && fsym->ts.type == BT_CLASS
4262 && (!CLASS_DATA (fsym)->as
4263 || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
4264 && CLASS_DATA (e)->attr.codimension)
4266 gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
4267 gcc_assert (!CLASS_DATA (fsym)->as);
4268 gfc_add_class_array_ref (e);
4269 parmse.want_coarray = 1;
4270 gfc_conv_expr_reference (&parmse, e);
4271 class_scalar_coarray_to_class (&parmse, e, fsym->ts,
4272 fsym->attr.optional
4273 && e->expr_type == EXPR_VARIABLE);
4275 else
4276 gfc_conv_expr_reference (&parmse, e);
4278 /* Catch base objects that are not variables. */
4279 if (e->ts.type == BT_CLASS
4280 && e->expr_type != EXPR_VARIABLE
4281 && expr && e == expr->base_expr)
4282 base_object = build_fold_indirect_ref_loc (input_location,
4283 parmse.expr);
4285 /* A class array element needs converting back to be a
4286 class object, if the formal argument is a class object. */
4287 if (fsym && fsym->ts.type == BT_CLASS
4288 && e->ts.type == BT_CLASS
4289 && ((CLASS_DATA (fsym)->as
4290 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
4291 || CLASS_DATA (e)->attr.dimension))
4292 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
4293 fsym->attr.intent != INTENT_IN
4294 && (CLASS_DATA (fsym)->attr.class_pointer
4295 || CLASS_DATA (fsym)->attr.allocatable),
4296 fsym->attr.optional
4297 && e->expr_type == EXPR_VARIABLE
4298 && e->symtree->n.sym->attr.optional,
4299 CLASS_DATA (fsym)->attr.class_pointer
4300 || CLASS_DATA (fsym)->attr.allocatable);
4302 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
4303 allocated on entry, it must be deallocated. */
4304 if (fsym && fsym->attr.intent == INTENT_OUT
4305 && (fsym->attr.allocatable
4306 || (fsym->ts.type == BT_CLASS
4307 && CLASS_DATA (fsym)->attr.allocatable)))
4309 stmtblock_t block;
4310 tree ptr;
4312 gfc_init_block (&block);
4313 ptr = parmse.expr;
4314 if (e->ts.type == BT_CLASS)
4315 ptr = gfc_class_data_get (ptr);
4317 tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
4318 NULL_TREE, NULL_TREE,
4319 NULL_TREE, true, NULL,
4320 false);
4321 gfc_add_expr_to_block (&block, tmp);
4322 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4323 void_type_node, ptr,
4324 null_pointer_node);
4325 gfc_add_expr_to_block (&block, tmp);
4327 if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
4329 gfc_add_modify (&block, ptr,
4330 fold_convert (TREE_TYPE (ptr),
4331 null_pointer_node));
4332 gfc_add_expr_to_block (&block, tmp);
4334 else if (fsym->ts.type == BT_CLASS)
4336 gfc_symbol *vtab;
4337 vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
4338 tmp = gfc_get_symbol_decl (vtab);
4339 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4340 ptr = gfc_class_vptr_get (parmse.expr);
4341 gfc_add_modify (&block, ptr,
4342 fold_convert (TREE_TYPE (ptr), tmp));
4343 gfc_add_expr_to_block (&block, tmp);
4346 if (fsym->attr.optional
4347 && e->expr_type == EXPR_VARIABLE
4348 && e->symtree->n.sym->attr.optional)
4350 tmp = fold_build3_loc (input_location, COND_EXPR,
4351 void_type_node,
4352 gfc_conv_expr_present (e->symtree->n.sym),
4353 gfc_finish_block (&block),
4354 build_empty_stmt (input_location));
4356 else
4357 tmp = gfc_finish_block (&block);
4359 gfc_add_expr_to_block (&se->pre, tmp);
4362 if (fsym && (fsym->ts.type == BT_DERIVED
4363 || fsym->ts.type == BT_ASSUMED)
4364 && e->ts.type == BT_CLASS
4365 && !CLASS_DATA (e)->attr.dimension
4366 && !CLASS_DATA (e)->attr.codimension)
4367 parmse.expr = gfc_class_data_get (parmse.expr);
4369 /* Wrap scalar variable in a descriptor. We need to convert
4370 the address of a pointer back to the pointer itself before,
4371 we can assign it to the data field. */
4373 if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
4374 && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
4376 tmp = parmse.expr;
4377 if (TREE_CODE (tmp) == ADDR_EXPR
4378 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp, 0))))
4379 tmp = TREE_OPERAND (tmp, 0);
4380 parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
4381 fsym->attr);
4382 parmse.expr = gfc_build_addr_expr (NULL_TREE,
4383 parmse.expr);
4385 else if (fsym && e->expr_type != EXPR_NULL
4386 && ((fsym->attr.pointer
4387 && fsym->attr.flavor != FL_PROCEDURE)
4388 || (fsym->attr.proc_pointer
4389 && !(e->expr_type == EXPR_VARIABLE
4390 && e->symtree->n.sym->attr.dummy))
4391 || (fsym->attr.proc_pointer
4392 && e->expr_type == EXPR_VARIABLE
4393 && gfc_is_proc_ptr_comp (e))
4394 || (fsym->attr.allocatable
4395 && fsym->attr.flavor != FL_PROCEDURE)))
4397 /* Scalar pointer dummy args require an extra level of
4398 indirection. The null pointer already contains
4399 this level of indirection. */
4400 parm_kind = SCALAR_POINTER;
4401 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
4405 else if (e->ts.type == BT_CLASS
4406 && fsym && fsym->ts.type == BT_CLASS
4407 && (CLASS_DATA (fsym)->attr.dimension
4408 || CLASS_DATA (fsym)->attr.codimension))
4410 /* Pass a class array. */
4411 gfc_conv_expr_descriptor (&parmse, e);
4412 /* The conversion does not repackage the reference to a class
4413 array - _data descriptor. */
4414 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
4415 fsym->attr.intent != INTENT_IN
4416 && (CLASS_DATA (fsym)->attr.class_pointer
4417 || CLASS_DATA (fsym)->attr.allocatable),
4418 fsym->attr.optional
4419 && e->expr_type == EXPR_VARIABLE
4420 && e->symtree->n.sym->attr.optional,
4421 CLASS_DATA (fsym)->attr.class_pointer
4422 || CLASS_DATA (fsym)->attr.allocatable);
4424 else
4426 /* If the procedure requires an explicit interface, the actual
4427 argument is passed according to the corresponding formal
4428 argument. If the corresponding formal argument is a POINTER,
4429 ALLOCATABLE or assumed shape, we do not use g77's calling
4430 convention, and pass the address of the array descriptor
4431 instead. Otherwise we use g77's calling convention. */
4432 bool f;
4433 f = (fsym != NULL)
4434 && !(fsym->attr.pointer || fsym->attr.allocatable)
4435 && fsym->as && fsym->as->type != AS_ASSUMED_SHAPE
4436 && fsym->as->type != AS_ASSUMED_RANK;
4437 if (comp)
4438 f = f || !comp->attr.always_explicit;
4439 else
4440 f = f || !sym->attr.always_explicit;
4442 /* If the argument is a function call that may not create
4443 a temporary for the result, we have to check that we
4444 can do it, i.e. that there is no alias between this
4445 argument and another one. */
4446 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
4448 gfc_expr *iarg;
4449 sym_intent intent;
4451 if (fsym != NULL)
4452 intent = fsym->attr.intent;
4453 else
4454 intent = INTENT_UNKNOWN;
4456 if (gfc_check_fncall_dependency (e, intent, sym, args,
4457 NOT_ELEMENTAL))
4458 parmse.force_tmp = 1;
4460 iarg = e->value.function.actual->expr;
4462 /* Temporary needed if aliasing due to host association. */
4463 if (sym->attr.contained
4464 && !sym->attr.pure
4465 && !sym->attr.implicit_pure
4466 && !sym->attr.use_assoc
4467 && iarg->expr_type == EXPR_VARIABLE
4468 && sym->ns == iarg->symtree->n.sym->ns)
4469 parmse.force_tmp = 1;
4471 /* Ditto within module. */
4472 if (sym->attr.use_assoc
4473 && !sym->attr.pure
4474 && !sym->attr.implicit_pure
4475 && iarg->expr_type == EXPR_VARIABLE
4476 && sym->module == iarg->symtree->n.sym->module)
4477 parmse.force_tmp = 1;
4480 if (e->expr_type == EXPR_VARIABLE
4481 && is_subref_array (e))
4482 /* The actual argument is a component reference to an
4483 array of derived types. In this case, the argument
4484 is converted to a temporary, which is passed and then
4485 written back after the procedure call. */
4486 gfc_conv_subref_array_arg (&parmse, e, f,
4487 fsym ? fsym->attr.intent : INTENT_INOUT,
4488 fsym && fsym->attr.pointer);
4489 else if (gfc_is_class_array_ref (e, NULL)
4490 && fsym && fsym->ts.type == BT_DERIVED)
4491 /* The actual argument is a component reference to an
4492 array of derived types. In this case, the argument
4493 is converted to a temporary, which is passed and then
4494 written back after the procedure call.
4495 OOP-TODO: Insert code so that if the dynamic type is
4496 the same as the declared type, copy-in/copy-out does
4497 not occur. */
4498 gfc_conv_subref_array_arg (&parmse, e, f,
4499 fsym ? fsym->attr.intent : INTENT_INOUT,
4500 fsym && fsym->attr.pointer);
4501 else
4502 gfc_conv_array_parameter (&parmse, e, f, fsym, sym->name, NULL);
4504 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
4505 allocated on entry, it must be deallocated. */
4506 if (fsym && fsym->attr.allocatable
4507 && fsym->attr.intent == INTENT_OUT)
4509 tmp = build_fold_indirect_ref_loc (input_location,
4510 parmse.expr);
4511 tmp = gfc_trans_dealloc_allocated (tmp, false);
4512 if (fsym->attr.optional
4513 && e->expr_type == EXPR_VARIABLE
4514 && e->symtree->n.sym->attr.optional)
4515 tmp = fold_build3_loc (input_location, COND_EXPR,
4516 void_type_node,
4517 gfc_conv_expr_present (e->symtree->n.sym),
4518 tmp, build_empty_stmt (input_location));
4519 gfc_add_expr_to_block (&se->pre, tmp);
4524 /* The case with fsym->attr.optional is that of a user subroutine
4525 with an interface indicating an optional argument. When we call
4526 an intrinsic subroutine, however, fsym is NULL, but we might still
4527 have an optional argument, so we proceed to the substitution
4528 just in case. */
4529 if (e && (fsym == NULL || fsym->attr.optional))
4531 /* If an optional argument is itself an optional dummy argument,
4532 check its presence and substitute a null if absent. This is
4533 only needed when passing an array to an elemental procedure
4534 as then array elements are accessed - or no NULL pointer is
4535 allowed and a "1" or "0" should be passed if not present.
4536 When passing a non-array-descriptor full array to a
4537 non-array-descriptor dummy, no check is needed. For
4538 array-descriptor actual to array-descriptor dummy, see
4539 PR 41911 for why a check has to be inserted.
4540 fsym == NULL is checked as intrinsics required the descriptor
4541 but do not always set fsym. */
4542 if (e->expr_type == EXPR_VARIABLE
4543 && e->symtree->n.sym->attr.optional
4544 && ((e->rank != 0 && sym->attr.elemental)
4545 || e->representation.length || e->ts.type == BT_CHARACTER
4546 || (e->rank != 0
4547 && (fsym == NULL
4548 || (fsym-> as
4549 && (fsym->as->type == AS_ASSUMED_SHAPE
4550 || fsym->as->type == AS_ASSUMED_RANK
4551 || fsym->as->type == AS_DEFERRED))))))
4552 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
4553 e->representation.length);
4556 if (fsym && e)
4558 /* Obtain the character length of an assumed character length
4559 length procedure from the typespec. */
4560 if (fsym->ts.type == BT_CHARACTER
4561 && parmse.string_length == NULL_TREE
4562 && e->ts.type == BT_PROCEDURE
4563 && e->symtree->n.sym->ts.type == BT_CHARACTER
4564 && e->symtree->n.sym->ts.u.cl->length != NULL
4565 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
4567 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
4568 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
4572 if (fsym && need_interface_mapping && e)
4573 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
4575 gfc_add_block_to_block (&se->pre, &parmse.pre);
4576 gfc_add_block_to_block (&post, &parmse.post);
4578 /* Allocated allocatable components of derived types must be
4579 deallocated for non-variable scalars. Non-variable arrays are
4580 dealt with in trans-array.c(gfc_conv_array_parameter). */
4581 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
4582 && e->ts.u.derived->attr.alloc_comp
4583 && !(e->symtree && e->symtree->n.sym->attr.pointer)
4584 && (e->expr_type != EXPR_VARIABLE && !e->rank))
4586 int parm_rank;
4587 tmp = build_fold_indirect_ref_loc (input_location,
4588 parmse.expr);
4589 parm_rank = e->rank;
4590 switch (parm_kind)
4592 case (ELEMENTAL):
4593 case (SCALAR):
4594 parm_rank = 0;
4595 break;
4597 case (SCALAR_POINTER):
4598 tmp = build_fold_indirect_ref_loc (input_location,
4599 tmp);
4600 break;
4603 if (e->expr_type == EXPR_OP
4604 && e->value.op.op == INTRINSIC_PARENTHESES
4605 && e->value.op.op1->expr_type == EXPR_VARIABLE)
4607 tree local_tmp;
4608 local_tmp = gfc_evaluate_now (tmp, &se->pre);
4609 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
4610 gfc_add_expr_to_block (&se->post, local_tmp);
4613 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
4615 /* The derived type is passed to gfc_deallocate_alloc_comp.
4616 Therefore, class actuals can handled correctly but derived
4617 types passed to class formals need the _data component. */
4618 tmp = gfc_class_data_get (tmp);
4619 if (!CLASS_DATA (fsym)->attr.dimension)
4620 tmp = build_fold_indirect_ref_loc (input_location, tmp);
4623 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
4625 gfc_add_expr_to_block (&se->post, tmp);
4628 /* Add argument checking of passing an unallocated/NULL actual to
4629 a nonallocatable/nonpointer dummy. */
4631 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
4633 symbol_attribute attr;
4634 char *msg;
4635 tree cond;
4637 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
4638 attr = gfc_expr_attr (e);
4639 else
4640 goto end_pointer_check;
4642 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
4643 allocatable to an optional dummy, cf. 12.5.2.12. */
4644 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
4645 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
4646 goto end_pointer_check;
4648 if (attr.optional)
4650 /* If the actual argument is an optional pointer/allocatable and
4651 the formal argument takes an nonpointer optional value,
4652 it is invalid to pass a non-present argument on, even
4653 though there is no technical reason for this in gfortran.
4654 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
4655 tree present, null_ptr, type;
4657 if (attr.allocatable
4658 && (fsym == NULL || !fsym->attr.allocatable))
4659 asprintf (&msg, "Allocatable actual argument '%s' is not "
4660 "allocated or not present", e->symtree->n.sym->name);
4661 else if (attr.pointer
4662 && (fsym == NULL || !fsym->attr.pointer))
4663 asprintf (&msg, "Pointer actual argument '%s' is not "
4664 "associated or not present",
4665 e->symtree->n.sym->name);
4666 else if (attr.proc_pointer
4667 && (fsym == NULL || !fsym->attr.proc_pointer))
4668 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
4669 "associated or not present",
4670 e->symtree->n.sym->name);
4671 else
4672 goto end_pointer_check;
4674 present = gfc_conv_expr_present (e->symtree->n.sym);
4675 type = TREE_TYPE (present);
4676 present = fold_build2_loc (input_location, EQ_EXPR,
4677 boolean_type_node, present,
4678 fold_convert (type,
4679 null_pointer_node));
4680 type = TREE_TYPE (parmse.expr);
4681 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
4682 boolean_type_node, parmse.expr,
4683 fold_convert (type,
4684 null_pointer_node));
4685 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
4686 boolean_type_node, present, null_ptr);
4688 else
4690 if (attr.allocatable
4691 && (fsym == NULL || !fsym->attr.allocatable))
4692 asprintf (&msg, "Allocatable actual argument '%s' is not "
4693 "allocated", e->symtree->n.sym->name);
4694 else if (attr.pointer
4695 && (fsym == NULL || !fsym->attr.pointer))
4696 asprintf (&msg, "Pointer actual argument '%s' is not "
4697 "associated", e->symtree->n.sym->name);
4698 else if (attr.proc_pointer
4699 && (fsym == NULL || !fsym->attr.proc_pointer))
4700 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
4701 "associated", e->symtree->n.sym->name);
4702 else
4703 goto end_pointer_check;
4705 tmp = parmse.expr;
4707 /* If the argument is passed by value, we need to strip the
4708 INDIRECT_REF. */
4709 if (!POINTER_TYPE_P (TREE_TYPE (parmse.expr)))
4710 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4712 cond = fold_build2_loc (input_location, EQ_EXPR,
4713 boolean_type_node, tmp,
4714 fold_convert (TREE_TYPE (tmp),
4715 null_pointer_node));
4718 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
4719 msg);
4720 free (msg);
4722 end_pointer_check:
4724 /* Deferred length dummies pass the character length by reference
4725 so that the value can be returned. */
4726 if (parmse.string_length && fsym && fsym->ts.deferred)
4728 tmp = parmse.string_length;
4729 if (TREE_CODE (tmp) != VAR_DECL)
4730 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
4731 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
4734 /* Character strings are passed as two parameters, a length and a
4735 pointer - except for Bind(c) which only passes the pointer.
4736 An unlimited polymorphic formal argument likewise does not
4737 need the length. */
4738 if (parmse.string_length != NULL_TREE
4739 && !sym->attr.is_bind_c
4740 && !(fsym && UNLIMITED_POLY (fsym)))
4741 vec_safe_push (stringargs, parmse.string_length);
4743 /* When calling __copy for character expressions to unlimited
4744 polymorphic entities, the dst argument needs a string length. */
4745 if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
4746 && strncmp (sym->name, "__vtab_CHARACTER", 16) == 0
4747 && arg->next && arg->next->expr
4748 && arg->next->expr->ts.type == BT_DERIVED
4749 && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
4750 vec_safe_push (stringargs, parmse.string_length);
4752 /* For descriptorless coarrays and assumed-shape coarray dummies, we
4753 pass the token and the offset as additional arguments. */
4754 if (fsym && fsym->attr.codimension
4755 && gfc_option.coarray == GFC_FCOARRAY_LIB
4756 && !fsym->attr.allocatable
4757 && e == NULL)
4759 /* Token and offset. */
4760 vec_safe_push (stringargs, null_pointer_node);
4761 vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
4762 gcc_assert (fsym->attr.optional);
4764 else if (fsym && fsym->attr.codimension
4765 && !fsym->attr.allocatable
4766 && gfc_option.coarray == GFC_FCOARRAY_LIB)
4768 tree caf_decl, caf_type;
4769 tree offset, tmp2;
4771 caf_decl = get_tree_for_caf_expr (e);
4772 caf_type = TREE_TYPE (caf_decl);
4774 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
4775 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
4776 tmp = gfc_conv_descriptor_token (caf_decl);
4777 else if (DECL_LANG_SPECIFIC (caf_decl)
4778 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
4779 tmp = GFC_DECL_TOKEN (caf_decl);
4780 else
4782 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
4783 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
4784 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
4787 vec_safe_push (stringargs, tmp);
4789 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
4790 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
4791 offset = build_int_cst (gfc_array_index_type, 0);
4792 else if (DECL_LANG_SPECIFIC (caf_decl)
4793 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
4794 offset = GFC_DECL_CAF_OFFSET (caf_decl);
4795 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
4796 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
4797 else
4798 offset = build_int_cst (gfc_array_index_type, 0);
4800 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
4801 tmp = gfc_conv_descriptor_data_get (caf_decl);
4802 else
4804 gcc_assert (POINTER_TYPE_P (caf_type));
4805 tmp = caf_decl;
4808 if (fsym->as->type == AS_ASSUMED_SHAPE
4809 || (fsym->as->type == AS_ASSUMED_RANK && !fsym->attr.pointer
4810 && !fsym->attr.allocatable))
4812 gcc_assert (POINTER_TYPE_P (TREE_TYPE (parmse.expr)));
4813 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE
4814 (TREE_TYPE (parmse.expr))));
4815 tmp2 = build_fold_indirect_ref_loc (input_location, parmse.expr);
4816 tmp2 = gfc_conv_descriptor_data_get (tmp2);
4818 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse.expr)))
4819 tmp2 = gfc_conv_descriptor_data_get (parmse.expr);
4820 else
4822 gcc_assert (POINTER_TYPE_P (TREE_TYPE (parmse.expr)));
4823 tmp2 = parmse.expr;
4826 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4827 gfc_array_index_type,
4828 fold_convert (gfc_array_index_type, tmp2),
4829 fold_convert (gfc_array_index_type, tmp));
4830 offset = fold_build2_loc (input_location, PLUS_EXPR,
4831 gfc_array_index_type, offset, tmp);
4833 vec_safe_push (stringargs, offset);
4836 vec_safe_push (arglist, parmse.expr);
4838 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
4840 if (comp)
4841 ts = comp->ts;
4842 else
4843 ts = sym->ts;
4845 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
4846 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
4847 else if (ts.type == BT_CHARACTER)
4849 if (ts.u.cl->length == NULL)
4851 /* Assumed character length results are not allowed by 5.1.1.5 of the
4852 standard and are trapped in resolve.c; except in the case of SPREAD
4853 (and other intrinsics?) and dummy functions. In the case of SPREAD,
4854 we take the character length of the first argument for the result.
4855 For dummies, we have to look through the formal argument list for
4856 this function and use the character length found there.*/
4857 if (ts.deferred)
4858 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
4859 else if (!sym->attr.dummy)
4860 cl.backend_decl = (*stringargs)[0];
4861 else
4863 formal = sym->ns->proc_name->formal;
4864 for (; formal; formal = formal->next)
4865 if (strcmp (formal->sym->name, sym->name) == 0)
4866 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
4868 len = cl.backend_decl;
4870 else
4872 tree tmp;
4874 /* Calculate the length of the returned string. */
4875 gfc_init_se (&parmse, NULL);
4876 if (need_interface_mapping)
4877 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
4878 else
4879 gfc_conv_expr (&parmse, ts.u.cl->length);
4880 gfc_add_block_to_block (&se->pre, &parmse.pre);
4881 gfc_add_block_to_block (&se->post, &parmse.post);
4883 tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
4884 tmp = fold_build2_loc (input_location, MAX_EXPR,
4885 gfc_charlen_type_node, tmp,
4886 build_int_cst (gfc_charlen_type_node, 0));
4887 cl.backend_decl = tmp;
4890 /* Set up a charlen structure for it. */
4891 cl.next = NULL;
4892 cl.length = NULL;
4893 ts.u.cl = &cl;
4895 len = cl.backend_decl;
4898 byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
4899 || (!comp && gfc_return_by_reference (sym));
4900 if (byref)
4902 if (se->direct_byref)
4904 /* Sometimes, too much indirection can be applied; e.g. for
4905 function_result = array_valued_recursive_function. */
4906 if (TREE_TYPE (TREE_TYPE (se->expr))
4907 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
4908 && GFC_DESCRIPTOR_TYPE_P
4909 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
4910 se->expr = build_fold_indirect_ref_loc (input_location,
4911 se->expr);
4913 /* If the lhs of an assignment x = f(..) is allocatable and
4914 f2003 is allowed, we must do the automatic reallocation.
4915 TODO - deal with intrinsics, without using a temporary. */
4916 if (gfc_option.flag_realloc_lhs
4917 && se->ss && se->ss->loop_chain
4918 && se->ss->loop_chain->is_alloc_lhs
4919 && !expr->value.function.isym
4920 && sym->result->as != NULL)
4922 /* Evaluate the bounds of the result, if known. */
4923 gfc_set_loop_bounds_from_array_spec (&mapping, se,
4924 sym->result->as);
4926 /* Perform the automatic reallocation. */
4927 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
4928 expr, NULL);
4929 gfc_add_expr_to_block (&se->pre, tmp);
4931 /* Pass the temporary as the first argument. */
4932 result = info->descriptor;
4934 else
4935 result = build_fold_indirect_ref_loc (input_location,
4936 se->expr);
4937 vec_safe_push (retargs, se->expr);
4939 else if (comp && comp->attr.dimension)
4941 gcc_assert (se->loop && info);
4943 /* Set the type of the array. */
4944 tmp = gfc_typenode_for_spec (&comp->ts);
4945 gcc_assert (se->ss->dimen == se->loop->dimen);
4947 /* Evaluate the bounds of the result, if known. */
4948 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
4950 /* If the lhs of an assignment x = f(..) is allocatable and
4951 f2003 is allowed, we must not generate the function call
4952 here but should just send back the results of the mapping.
4953 This is signalled by the function ss being flagged. */
4954 if (gfc_option.flag_realloc_lhs
4955 && se->ss && se->ss->is_alloc_lhs)
4957 gfc_free_interface_mapping (&mapping);
4958 return has_alternate_specifier;
4961 /* Create a temporary to store the result. In case the function
4962 returns a pointer, the temporary will be a shallow copy and
4963 mustn't be deallocated. */
4964 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
4965 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
4966 tmp, NULL_TREE, false,
4967 !comp->attr.pointer, callee_alloc,
4968 &se->ss->info->expr->where);
4970 /* Pass the temporary as the first argument. */
4971 result = info->descriptor;
4972 tmp = gfc_build_addr_expr (NULL_TREE, result);
4973 vec_safe_push (retargs, tmp);
4975 else if (!comp && sym->result->attr.dimension)
4977 gcc_assert (se->loop && info);
4979 /* Set the type of the array. */
4980 tmp = gfc_typenode_for_spec (&ts);
4981 gcc_assert (se->ss->dimen == se->loop->dimen);
4983 /* Evaluate the bounds of the result, if known. */
4984 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
4986 /* If the lhs of an assignment x = f(..) is allocatable and
4987 f2003 is allowed, we must not generate the function call
4988 here but should just send back the results of the mapping.
4989 This is signalled by the function ss being flagged. */
4990 if (gfc_option.flag_realloc_lhs
4991 && se->ss && se->ss->is_alloc_lhs)
4993 gfc_free_interface_mapping (&mapping);
4994 return has_alternate_specifier;
4997 /* Create a temporary to store the result. In case the function
4998 returns a pointer, the temporary will be a shallow copy and
4999 mustn't be deallocated. */
5000 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
5001 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
5002 tmp, NULL_TREE, false,
5003 !sym->attr.pointer, callee_alloc,
5004 &se->ss->info->expr->where);
5006 /* Pass the temporary as the first argument. */
5007 result = info->descriptor;
5008 tmp = gfc_build_addr_expr (NULL_TREE, result);
5009 vec_safe_push (retargs, tmp);
5011 else if (ts.type == BT_CHARACTER)
5013 /* Pass the string length. */
5014 type = gfc_get_character_type (ts.kind, ts.u.cl);
5015 type = build_pointer_type (type);
5017 /* Return an address to a char[0:len-1]* temporary for
5018 character pointers. */
5019 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
5020 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
5022 var = gfc_create_var (type, "pstr");
5024 if ((!comp && sym->attr.allocatable)
5025 || (comp && comp->attr.allocatable))
5027 gfc_add_modify (&se->pre, var,
5028 fold_convert (TREE_TYPE (var),
5029 null_pointer_node));
5030 tmp = gfc_call_free (convert (pvoid_type_node, var));
5031 gfc_add_expr_to_block (&se->post, tmp);
5034 /* Provide an address expression for the function arguments. */
5035 var = gfc_build_addr_expr (NULL_TREE, var);
5037 else
5038 var = gfc_conv_string_tmp (se, type, len);
5040 vec_safe_push (retargs, var);
5042 else
5044 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
5046 type = gfc_get_complex_type (ts.kind);
5047 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
5048 vec_safe_push (retargs, var);
5051 /* Add the string length to the argument list. */
5052 if (ts.type == BT_CHARACTER && ts.deferred)
5054 tmp = len;
5055 if (TREE_CODE (tmp) != VAR_DECL)
5056 tmp = gfc_evaluate_now (len, &se->pre);
5057 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
5058 vec_safe_push (retargs, tmp);
5060 else if (ts.type == BT_CHARACTER)
5061 vec_safe_push (retargs, len);
5063 gfc_free_interface_mapping (&mapping);
5065 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
5066 arglen = (vec_safe_length (arglist) + vec_safe_length (stringargs)
5067 + vec_safe_length (append_args));
5068 vec_safe_reserve (retargs, arglen);
5070 /* Add the return arguments. */
5071 retargs->splice (arglist);
5073 /* Add the hidden string length parameters to the arguments. */
5074 retargs->splice (stringargs);
5076 /* We may want to append extra arguments here. This is used e.g. for
5077 calls to libgfortran_matmul_??, which need extra information. */
5078 if (!vec_safe_is_empty (append_args))
5079 retargs->splice (append_args);
5080 arglist = retargs;
5082 /* Generate the actual call. */
5083 if (base_object == NULL_TREE)
5084 conv_function_val (se, sym, expr);
5085 else
5086 conv_base_obj_fcn_val (se, base_object, expr);
5088 /* If there are alternate return labels, function type should be
5089 integer. Can't modify the type in place though, since it can be shared
5090 with other functions. For dummy arguments, the typing is done to
5091 this result, even if it has to be repeated for each call. */
5092 if (has_alternate_specifier
5093 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
5095 if (!sym->attr.dummy)
5097 TREE_TYPE (sym->backend_decl)
5098 = build_function_type (integer_type_node,
5099 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
5100 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
5102 else
5103 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
5106 fntype = TREE_TYPE (TREE_TYPE (se->expr));
5107 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
5109 /* If we have a pointer function, but we don't want a pointer, e.g.
5110 something like
5111 x = f()
5112 where f is pointer valued, we have to dereference the result. */
5113 if (!se->want_pointer && !byref
5114 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
5115 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
5116 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
5118 /* f2c calling conventions require a scalar default real function to
5119 return a double precision result. Convert this back to default
5120 real. We only care about the cases that can happen in Fortran 77.
5122 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
5123 && sym->ts.kind == gfc_default_real_kind
5124 && !sym->attr.always_explicit)
5125 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
5127 /* A pure function may still have side-effects - it may modify its
5128 parameters. */
5129 TREE_SIDE_EFFECTS (se->expr) = 1;
5130 #if 0
5131 if (!sym->attr.pure)
5132 TREE_SIDE_EFFECTS (se->expr) = 1;
5133 #endif
5135 if (byref)
5137 /* Add the function call to the pre chain. There is no expression. */
5138 gfc_add_expr_to_block (&se->pre, se->expr);
5139 se->expr = NULL_TREE;
5141 if (!se->direct_byref)
5143 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
5145 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
5147 /* Check the data pointer hasn't been modified. This would
5148 happen in a function returning a pointer. */
5149 tmp = gfc_conv_descriptor_data_get (info->descriptor);
5150 tmp = fold_build2_loc (input_location, NE_EXPR,
5151 boolean_type_node,
5152 tmp, info->data);
5153 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
5154 gfc_msg_fault);
5156 se->expr = info->descriptor;
5157 /* Bundle in the string length. */
5158 se->string_length = len;
5160 else if (ts.type == BT_CHARACTER)
5162 /* Dereference for character pointer results. */
5163 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
5164 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
5165 se->expr = build_fold_indirect_ref_loc (input_location, var);
5166 else
5167 se->expr = var;
5169 se->string_length = len;
5171 else
5173 gcc_assert (ts.type == BT_COMPLEX && gfc_option.flag_f2c);
5174 se->expr = build_fold_indirect_ref_loc (input_location, var);
5179 /* Follow the function call with the argument post block. */
5180 if (byref)
5182 gfc_add_block_to_block (&se->pre, &post);
5184 /* Transformational functions of derived types with allocatable
5185 components must have the result allocatable components copied. */
5186 arg = expr->value.function.actual;
5187 if (result && arg && expr->rank
5188 && expr->value.function.isym
5189 && expr->value.function.isym->transformational
5190 && arg->expr->ts.type == BT_DERIVED
5191 && arg->expr->ts.u.derived->attr.alloc_comp)
5193 tree tmp2;
5194 /* Copy the allocatable components. We have to use a
5195 temporary here to prevent source allocatable components
5196 from being corrupted. */
5197 tmp2 = gfc_evaluate_now (result, &se->pre);
5198 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
5199 result, tmp2, expr->rank);
5200 gfc_add_expr_to_block (&se->pre, tmp);
5201 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
5202 expr->rank);
5203 gfc_add_expr_to_block (&se->pre, tmp);
5205 /* Finally free the temporary's data field. */
5206 tmp = gfc_conv_descriptor_data_get (tmp2);
5207 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
5208 NULL_TREE, NULL_TREE, true,
5209 NULL, false);
5210 gfc_add_expr_to_block (&se->pre, tmp);
5213 else
5214 gfc_add_block_to_block (&se->post, &post);
5216 return has_alternate_specifier;
5220 /* Fill a character string with spaces. */
5222 static tree
5223 fill_with_spaces (tree start, tree type, tree size)
5225 stmtblock_t block, loop;
5226 tree i, el, exit_label, cond, tmp;
5228 /* For a simple char type, we can call memset(). */
5229 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
5230 return build_call_expr_loc (input_location,
5231 builtin_decl_explicit (BUILT_IN_MEMSET),
5232 3, start,
5233 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
5234 lang_hooks.to_target_charset (' ')),
5235 size);
5237 /* Otherwise, we use a loop:
5238 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
5239 *el = (type) ' ';
5242 /* Initialize variables. */
5243 gfc_init_block (&block);
5244 i = gfc_create_var (sizetype, "i");
5245 gfc_add_modify (&block, i, fold_convert (sizetype, size));
5246 el = gfc_create_var (build_pointer_type (type), "el");
5247 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
5248 exit_label = gfc_build_label_decl (NULL_TREE);
5249 TREE_USED (exit_label) = 1;
5252 /* Loop body. */
5253 gfc_init_block (&loop);
5255 /* Exit condition. */
5256 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, i,
5257 build_zero_cst (sizetype));
5258 tmp = build1_v (GOTO_EXPR, exit_label);
5259 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
5260 build_empty_stmt (input_location));
5261 gfc_add_expr_to_block (&loop, tmp);
5263 /* Assignment. */
5264 gfc_add_modify (&loop,
5265 fold_build1_loc (input_location, INDIRECT_REF, type, el),
5266 build_int_cst (type, lang_hooks.to_target_charset (' ')));
5268 /* Increment loop variables. */
5269 gfc_add_modify (&loop, i,
5270 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
5271 TYPE_SIZE_UNIT (type)));
5272 gfc_add_modify (&loop, el,
5273 fold_build_pointer_plus_loc (input_location,
5274 el, TYPE_SIZE_UNIT (type)));
5276 /* Making the loop... actually loop! */
5277 tmp = gfc_finish_block (&loop);
5278 tmp = build1_v (LOOP_EXPR, tmp);
5279 gfc_add_expr_to_block (&block, tmp);
5281 /* The exit label. */
5282 tmp = build1_v (LABEL_EXPR, exit_label);
5283 gfc_add_expr_to_block (&block, tmp);
5286 return gfc_finish_block (&block);
5290 /* Generate code to copy a string. */
5292 void
5293 gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
5294 int dkind, tree slength, tree src, int skind)
5296 tree tmp, dlen, slen;
5297 tree dsc;
5298 tree ssc;
5299 tree cond;
5300 tree cond2;
5301 tree tmp2;
5302 tree tmp3;
5303 tree tmp4;
5304 tree chartype;
5305 stmtblock_t tempblock;
5307 gcc_assert (dkind == skind);
5309 if (slength != NULL_TREE)
5311 slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
5312 ssc = gfc_string_to_single_character (slen, src, skind);
5314 else
5316 slen = build_int_cst (size_type_node, 1);
5317 ssc = src;
5320 if (dlength != NULL_TREE)
5322 dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
5323 dsc = gfc_string_to_single_character (dlen, dest, dkind);
5325 else
5327 dlen = build_int_cst (size_type_node, 1);
5328 dsc = dest;
5331 /* Assign directly if the types are compatible. */
5332 if (dsc != NULL_TREE && ssc != NULL_TREE
5333 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
5335 gfc_add_modify (block, dsc, ssc);
5336 return;
5339 /* Do nothing if the destination length is zero. */
5340 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, dlen,
5341 build_int_cst (size_type_node, 0));
5343 /* The following code was previously in _gfortran_copy_string:
5345 // The two strings may overlap so we use memmove.
5346 void
5347 copy_string (GFC_INTEGER_4 destlen, char * dest,
5348 GFC_INTEGER_4 srclen, const char * src)
5350 if (srclen >= destlen)
5352 // This will truncate if too long.
5353 memmove (dest, src, destlen);
5355 else
5357 memmove (dest, src, srclen);
5358 // Pad with spaces.
5359 memset (&dest[srclen], ' ', destlen - srclen);
5363 We're now doing it here for better optimization, but the logic
5364 is the same. */
5366 /* For non-default character kinds, we have to multiply the string
5367 length by the base type size. */
5368 chartype = gfc_get_char_type (dkind);
5369 slen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
5370 fold_convert (size_type_node, slen),
5371 fold_convert (size_type_node,
5372 TYPE_SIZE_UNIT (chartype)));
5373 dlen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
5374 fold_convert (size_type_node, dlen),
5375 fold_convert (size_type_node,
5376 TYPE_SIZE_UNIT (chartype)));
5378 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
5379 dest = fold_convert (pvoid_type_node, dest);
5380 else
5381 dest = gfc_build_addr_expr (pvoid_type_node, dest);
5383 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
5384 src = fold_convert (pvoid_type_node, src);
5385 else
5386 src = gfc_build_addr_expr (pvoid_type_node, src);
5388 /* Truncate string if source is too long. */
5389 cond2 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, slen,
5390 dlen);
5391 tmp2 = build_call_expr_loc (input_location,
5392 builtin_decl_explicit (BUILT_IN_MEMMOVE),
5393 3, dest, src, dlen);
5395 /* Else copy and pad with spaces. */
5396 tmp3 = build_call_expr_loc (input_location,
5397 builtin_decl_explicit (BUILT_IN_MEMMOVE),
5398 3, dest, src, slen);
5400 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
5401 tmp4 = fill_with_spaces (tmp4, chartype,
5402 fold_build2_loc (input_location, MINUS_EXPR,
5403 TREE_TYPE(dlen), dlen, slen));
5405 gfc_init_block (&tempblock);
5406 gfc_add_expr_to_block (&tempblock, tmp3);
5407 gfc_add_expr_to_block (&tempblock, tmp4);
5408 tmp3 = gfc_finish_block (&tempblock);
5410 /* The whole copy_string function is there. */
5411 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
5412 tmp2, tmp3);
5413 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
5414 build_empty_stmt (input_location));
5415 gfc_add_expr_to_block (block, tmp);
5419 /* Translate a statement function.
5420 The value of a statement function reference is obtained by evaluating the
5421 expression using the values of the actual arguments for the values of the
5422 corresponding dummy arguments. */
5424 static void
5425 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
5427 gfc_symbol *sym;
5428 gfc_symbol *fsym;
5429 gfc_formal_arglist *fargs;
5430 gfc_actual_arglist *args;
5431 gfc_se lse;
5432 gfc_se rse;
5433 gfc_saved_var *saved_vars;
5434 tree *temp_vars;
5435 tree type;
5436 tree tmp;
5437 int n;
5439 sym = expr->symtree->n.sym;
5440 args = expr->value.function.actual;
5441 gfc_init_se (&lse, NULL);
5442 gfc_init_se (&rse, NULL);
5444 n = 0;
5445 for (fargs = sym->formal; fargs; fargs = fargs->next)
5446 n++;
5447 saved_vars = XCNEWVEC (gfc_saved_var, n);
5448 temp_vars = XCNEWVEC (tree, n);
5450 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
5452 /* Each dummy shall be specified, explicitly or implicitly, to be
5453 scalar. */
5454 gcc_assert (fargs->sym->attr.dimension == 0);
5455 fsym = fargs->sym;
5457 if (fsym->ts.type == BT_CHARACTER)
5459 /* Copy string arguments. */
5460 tree arglen;
5462 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
5463 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
5465 /* Create a temporary to hold the value. */
5466 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
5467 fsym->ts.u.cl->backend_decl
5468 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
5470 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
5471 temp_vars[n] = gfc_create_var (type, fsym->name);
5473 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
5475 gfc_conv_expr (&rse, args->expr);
5476 gfc_conv_string_parameter (&rse);
5477 gfc_add_block_to_block (&se->pre, &lse.pre);
5478 gfc_add_block_to_block (&se->pre, &rse.pre);
5480 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
5481 rse.string_length, rse.expr, fsym->ts.kind);
5482 gfc_add_block_to_block (&se->pre, &lse.post);
5483 gfc_add_block_to_block (&se->pre, &rse.post);
5485 else
5487 /* For everything else, just evaluate the expression. */
5489 /* Create a temporary to hold the value. */
5490 type = gfc_typenode_for_spec (&fsym->ts);
5491 temp_vars[n] = gfc_create_var (type, fsym->name);
5493 gfc_conv_expr (&lse, args->expr);
5495 gfc_add_block_to_block (&se->pre, &lse.pre);
5496 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
5497 gfc_add_block_to_block (&se->pre, &lse.post);
5500 args = args->next;
5503 /* Use the temporary variables in place of the real ones. */
5504 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
5505 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
5507 gfc_conv_expr (se, sym->value);
5509 if (sym->ts.type == BT_CHARACTER)
5511 gfc_conv_const_charlen (sym->ts.u.cl);
5513 /* Force the expression to the correct length. */
5514 if (!INTEGER_CST_P (se->string_length)
5515 || tree_int_cst_lt (se->string_length,
5516 sym->ts.u.cl->backend_decl))
5518 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
5519 tmp = gfc_create_var (type, sym->name);
5520 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
5521 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
5522 sym->ts.kind, se->string_length, se->expr,
5523 sym->ts.kind);
5524 se->expr = tmp;
5526 se->string_length = sym->ts.u.cl->backend_decl;
5529 /* Restore the original variables. */
5530 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
5531 gfc_restore_sym (fargs->sym, &saved_vars[n]);
5532 free (temp_vars);
5533 free (saved_vars);
5537 /* Translate a function expression. */
5539 static void
5540 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
5542 gfc_symbol *sym;
5544 if (expr->value.function.isym)
5546 gfc_conv_intrinsic_function (se, expr);
5547 return;
5550 /* expr.value.function.esym is the resolved (specific) function symbol for
5551 most functions. However this isn't set for dummy procedures. */
5552 sym = expr->value.function.esym;
5553 if (!sym)
5554 sym = expr->symtree->n.sym;
5556 /* We distinguish statement functions from general functions to improve
5557 runtime performance. */
5558 if (sym->attr.proc == PROC_ST_FUNCTION)
5560 gfc_conv_statement_function (se, expr);
5561 return;
5564 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
5565 NULL);
5569 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
5571 static bool
5572 is_zero_initializer_p (gfc_expr * expr)
5574 if (expr->expr_type != EXPR_CONSTANT)
5575 return false;
5577 /* We ignore constants with prescribed memory representations for now. */
5578 if (expr->representation.string)
5579 return false;
5581 switch (expr->ts.type)
5583 case BT_INTEGER:
5584 return mpz_cmp_si (expr->value.integer, 0) == 0;
5586 case BT_REAL:
5587 return mpfr_zero_p (expr->value.real)
5588 && MPFR_SIGN (expr->value.real) >= 0;
5590 case BT_LOGICAL:
5591 return expr->value.logical == 0;
5593 case BT_COMPLEX:
5594 return mpfr_zero_p (mpc_realref (expr->value.complex))
5595 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
5596 && mpfr_zero_p (mpc_imagref (expr->value.complex))
5597 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
5599 default:
5600 break;
5602 return false;
5606 static void
5607 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
5609 gfc_ss *ss;
5611 ss = se->ss;
5612 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
5613 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
5615 gfc_conv_tmp_array_ref (se);
5619 /* Build a static initializer. EXPR is the expression for the initial value.
5620 The other parameters describe the variable of the component being
5621 initialized. EXPR may be null. */
5623 tree
5624 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
5625 bool array, bool pointer, bool procptr)
5627 gfc_se se;
5629 if (!(expr || pointer || procptr))
5630 return NULL_TREE;
5632 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
5633 (these are the only two iso_c_binding derived types that can be
5634 used as initialization expressions). If so, we need to modify
5635 the 'expr' to be that for a (void *). */
5636 if (expr != NULL && expr->ts.type == BT_DERIVED
5637 && expr->ts.is_iso_c && expr->ts.u.derived)
5639 gfc_symbol *derived = expr->ts.u.derived;
5641 /* The derived symbol has already been converted to a (void *). Use
5642 its kind. */
5643 expr = gfc_get_int_expr (derived->ts.kind, NULL, 0);
5644 expr->ts.f90_type = derived->ts.f90_type;
5646 gfc_init_se (&se, NULL);
5647 gfc_conv_constant (&se, expr);
5648 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5649 return se.expr;
5652 if (array && !procptr)
5654 tree ctor;
5655 /* Arrays need special handling. */
5656 if (pointer)
5657 ctor = gfc_build_null_descriptor (type);
5658 /* Special case assigning an array to zero. */
5659 else if (is_zero_initializer_p (expr))
5660 ctor = build_constructor (type, NULL);
5661 else
5662 ctor = gfc_conv_array_initializer (type, expr);
5663 TREE_STATIC (ctor) = 1;
5664 return ctor;
5666 else if (pointer || procptr)
5668 if (!expr || expr->expr_type == EXPR_NULL)
5669 return fold_convert (type, null_pointer_node);
5670 else
5672 gfc_init_se (&se, NULL);
5673 se.want_pointer = 1;
5674 gfc_conv_expr (&se, expr);
5675 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5676 return se.expr;
5679 else
5681 switch (ts->type)
5683 case BT_DERIVED:
5684 case BT_CLASS:
5685 gfc_init_se (&se, NULL);
5686 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
5687 gfc_conv_structure (&se, gfc_class_null_initializer(ts, expr), 1);
5688 else
5689 gfc_conv_structure (&se, expr, 1);
5690 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
5691 TREE_STATIC (se.expr) = 1;
5692 return se.expr;
5694 case BT_CHARACTER:
5696 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl,expr);
5697 TREE_STATIC (ctor) = 1;
5698 return ctor;
5701 default:
5702 gfc_init_se (&se, NULL);
5703 gfc_conv_constant (&se, expr);
5704 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
5705 return se.expr;
5710 static tree
5711 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
5713 gfc_se rse;
5714 gfc_se lse;
5715 gfc_ss *rss;
5716 gfc_ss *lss;
5717 gfc_array_info *lss_array;
5718 stmtblock_t body;
5719 stmtblock_t block;
5720 gfc_loopinfo loop;
5721 int n;
5722 tree tmp;
5724 gfc_start_block (&block);
5726 /* Initialize the scalarizer. */
5727 gfc_init_loopinfo (&loop);
5729 gfc_init_se (&lse, NULL);
5730 gfc_init_se (&rse, NULL);
5732 /* Walk the rhs. */
5733 rss = gfc_walk_expr (expr);
5734 if (rss == gfc_ss_terminator)
5735 /* The rhs is scalar. Add a ss for the expression. */
5736 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
5738 /* Create a SS for the destination. */
5739 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
5740 GFC_SS_COMPONENT);
5741 lss_array = &lss->info->data.array;
5742 lss_array->shape = gfc_get_shape (cm->as->rank);
5743 lss_array->descriptor = dest;
5744 lss_array->data = gfc_conv_array_data (dest);
5745 lss_array->offset = gfc_conv_array_offset (dest);
5746 for (n = 0; n < cm->as->rank; n++)
5748 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
5749 lss_array->stride[n] = gfc_index_one_node;
5751 mpz_init (lss_array->shape[n]);
5752 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
5753 cm->as->lower[n]->value.integer);
5754 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
5757 /* Associate the SS with the loop. */
5758 gfc_add_ss_to_loop (&loop, lss);
5759 gfc_add_ss_to_loop (&loop, rss);
5761 /* Calculate the bounds of the scalarization. */
5762 gfc_conv_ss_startstride (&loop);
5764 /* Setup the scalarizing loops. */
5765 gfc_conv_loop_setup (&loop, &expr->where);
5767 /* Setup the gfc_se structures. */
5768 gfc_copy_loopinfo_to_se (&lse, &loop);
5769 gfc_copy_loopinfo_to_se (&rse, &loop);
5771 rse.ss = rss;
5772 gfc_mark_ss_chain_used (rss, 1);
5773 lse.ss = lss;
5774 gfc_mark_ss_chain_used (lss, 1);
5776 /* Start the scalarized loop body. */
5777 gfc_start_scalarized_body (&loop, &body);
5779 gfc_conv_tmp_array_ref (&lse);
5780 if (cm->ts.type == BT_CHARACTER)
5781 lse.string_length = cm->ts.u.cl->backend_decl;
5783 gfc_conv_expr (&rse, expr);
5785 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false, true);
5786 gfc_add_expr_to_block (&body, tmp);
5788 gcc_assert (rse.ss == gfc_ss_terminator);
5790 /* Generate the copying loops. */
5791 gfc_trans_scalarizing_loops (&loop, &body);
5793 /* Wrap the whole thing up. */
5794 gfc_add_block_to_block (&block, &loop.pre);
5795 gfc_add_block_to_block (&block, &loop.post);
5797 gcc_assert (lss_array->shape != NULL);
5798 gfc_free_shape (&lss_array->shape, cm->as->rank);
5799 gfc_cleanup_loop (&loop);
5801 return gfc_finish_block (&block);
5805 static tree
5806 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
5807 gfc_expr * expr)
5809 gfc_se se;
5810 stmtblock_t block;
5811 tree offset;
5812 int n;
5813 tree tmp;
5814 tree tmp2;
5815 gfc_array_spec *as;
5816 gfc_expr *arg = NULL;
5818 gfc_start_block (&block);
5819 gfc_init_se (&se, NULL);
5821 /* Get the descriptor for the expressions. */
5822 se.want_pointer = 0;
5823 gfc_conv_expr_descriptor (&se, expr);
5824 gfc_add_block_to_block (&block, &se.pre);
5825 gfc_add_modify (&block, dest, se.expr);
5827 /* Deal with arrays of derived types with allocatable components. */
5828 if (cm->ts.type == BT_DERIVED
5829 && cm->ts.u.derived->attr.alloc_comp)
5830 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
5831 se.expr, dest,
5832 cm->as->rank);
5833 else
5834 tmp = gfc_duplicate_allocatable (dest, se.expr,
5835 TREE_TYPE(cm->backend_decl),
5836 cm->as->rank);
5838 gfc_add_expr_to_block (&block, tmp);
5839 gfc_add_block_to_block (&block, &se.post);
5841 if (expr->expr_type != EXPR_VARIABLE)
5842 gfc_conv_descriptor_data_set (&block, se.expr,
5843 null_pointer_node);
5845 /* We need to know if the argument of a conversion function is a
5846 variable, so that the correct lower bound can be used. */
5847 if (expr->expr_type == EXPR_FUNCTION
5848 && expr->value.function.isym
5849 && expr->value.function.isym->conversion
5850 && expr->value.function.actual->expr
5851 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
5852 arg = expr->value.function.actual->expr;
5854 /* Obtain the array spec of full array references. */
5855 if (arg)
5856 as = gfc_get_full_arrayspec_from_expr (arg);
5857 else
5858 as = gfc_get_full_arrayspec_from_expr (expr);
5860 /* Shift the lbound and ubound of temporaries to being unity,
5861 rather than zero, based. Always calculate the offset. */
5862 offset = gfc_conv_descriptor_offset_get (dest);
5863 gfc_add_modify (&block, offset, gfc_index_zero_node);
5864 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
5866 for (n = 0; n < expr->rank; n++)
5868 tree span;
5869 tree lbound;
5871 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
5872 TODO It looks as if gfc_conv_expr_descriptor should return
5873 the correct bounds and that the following should not be
5874 necessary. This would simplify gfc_conv_intrinsic_bound
5875 as well. */
5876 if (as && as->lower[n])
5878 gfc_se lbse;
5879 gfc_init_se (&lbse, NULL);
5880 gfc_conv_expr (&lbse, as->lower[n]);
5881 gfc_add_block_to_block (&block, &lbse.pre);
5882 lbound = gfc_evaluate_now (lbse.expr, &block);
5884 else if (as && arg)
5886 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
5887 lbound = gfc_conv_descriptor_lbound_get (tmp,
5888 gfc_rank_cst[n]);
5890 else if (as)
5891 lbound = gfc_conv_descriptor_lbound_get (dest,
5892 gfc_rank_cst[n]);
5893 else
5894 lbound = gfc_index_one_node;
5896 lbound = fold_convert (gfc_array_index_type, lbound);
5898 /* Shift the bounds and set the offset accordingly. */
5899 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
5900 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5901 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
5902 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5903 span, lbound);
5904 gfc_conv_descriptor_ubound_set (&block, dest,
5905 gfc_rank_cst[n], tmp);
5906 gfc_conv_descriptor_lbound_set (&block, dest,
5907 gfc_rank_cst[n], lbound);
5909 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5910 gfc_conv_descriptor_lbound_get (dest,
5911 gfc_rank_cst[n]),
5912 gfc_conv_descriptor_stride_get (dest,
5913 gfc_rank_cst[n]));
5914 gfc_add_modify (&block, tmp2, tmp);
5915 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5916 offset, tmp2);
5917 gfc_conv_descriptor_offset_set (&block, dest, tmp);
5920 if (arg)
5922 /* If a conversion expression has a null data pointer
5923 argument, nullify the allocatable component. */
5924 tree non_null_expr;
5925 tree null_expr;
5927 if (arg->symtree->n.sym->attr.allocatable
5928 || arg->symtree->n.sym->attr.pointer)
5930 non_null_expr = gfc_finish_block (&block);
5931 gfc_start_block (&block);
5932 gfc_conv_descriptor_data_set (&block, dest,
5933 null_pointer_node);
5934 null_expr = gfc_finish_block (&block);
5935 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
5936 tmp = build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
5937 fold_convert (TREE_TYPE (tmp), null_pointer_node));
5938 return build3_v (COND_EXPR, tmp,
5939 null_expr, non_null_expr);
5943 return gfc_finish_block (&block);
5947 /* Assign a single component of a derived type constructor. */
5949 static tree
5950 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
5952 gfc_se se;
5953 gfc_se lse;
5954 stmtblock_t block;
5955 tree tmp;
5957 gfc_start_block (&block);
5959 if (cm->attr.pointer || cm->attr.proc_pointer)
5961 gfc_init_se (&se, NULL);
5962 /* Pointer component. */
5963 if (cm->attr.dimension && !cm->attr.proc_pointer)
5965 /* Array pointer. */
5966 if (expr->expr_type == EXPR_NULL)
5967 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
5968 else
5970 se.direct_byref = 1;
5971 se.expr = dest;
5972 gfc_conv_expr_descriptor (&se, expr);
5973 gfc_add_block_to_block (&block, &se.pre);
5974 gfc_add_block_to_block (&block, &se.post);
5977 else
5979 /* Scalar pointers. */
5980 se.want_pointer = 1;
5981 gfc_conv_expr (&se, expr);
5982 gfc_add_block_to_block (&block, &se.pre);
5984 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
5985 && expr->symtree->n.sym->attr.dummy)
5986 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
5988 gfc_add_modify (&block, dest,
5989 fold_convert (TREE_TYPE (dest), se.expr));
5990 gfc_add_block_to_block (&block, &se.post);
5993 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
5995 /* NULL initialization for CLASS components. */
5996 tmp = gfc_trans_structure_assign (dest,
5997 gfc_class_null_initializer (&cm->ts, expr));
5998 gfc_add_expr_to_block (&block, tmp);
6000 else if (cm->attr.dimension && !cm->attr.proc_pointer)
6002 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
6003 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
6004 else if (cm->attr.allocatable)
6006 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
6007 gfc_add_expr_to_block (&block, tmp);
6009 else
6011 tmp = gfc_trans_subarray_assign (dest, cm, expr);
6012 gfc_add_expr_to_block (&block, tmp);
6015 else if (expr->ts.type == BT_DERIVED)
6017 if (expr->expr_type != EXPR_STRUCTURE)
6019 gfc_init_se (&se, NULL);
6020 gfc_conv_expr (&se, expr);
6021 gfc_add_block_to_block (&block, &se.pre);
6022 gfc_add_modify (&block, dest,
6023 fold_convert (TREE_TYPE (dest), se.expr));
6024 gfc_add_block_to_block (&block, &se.post);
6026 else
6028 /* Nested constructors. */
6029 tmp = gfc_trans_structure_assign (dest, expr);
6030 gfc_add_expr_to_block (&block, tmp);
6033 else
6035 /* Scalar component. */
6036 gfc_init_se (&se, NULL);
6037 gfc_init_se (&lse, NULL);
6039 gfc_conv_expr (&se, expr);
6040 if (cm->ts.type == BT_CHARACTER)
6041 lse.string_length = cm->ts.u.cl->backend_decl;
6042 lse.expr = dest;
6043 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false, true);
6044 gfc_add_expr_to_block (&block, tmp);
6046 return gfc_finish_block (&block);
6049 /* Assign a derived type constructor to a variable. */
6051 static tree
6052 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
6054 gfc_constructor *c;
6055 gfc_component *cm;
6056 stmtblock_t block;
6057 tree field;
6058 tree tmp;
6060 gfc_start_block (&block);
6061 cm = expr->ts.u.derived->components;
6063 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
6064 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
6065 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
6067 gfc_se se, lse;
6069 gcc_assert (cm->backend_decl == NULL);
6070 gfc_init_se (&se, NULL);
6071 gfc_init_se (&lse, NULL);
6072 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
6073 lse.expr = dest;
6074 gfc_add_modify (&block, lse.expr,
6075 fold_convert (TREE_TYPE (lse.expr), se.expr));
6077 return gfc_finish_block (&block);
6080 for (c = gfc_constructor_first (expr->value.constructor);
6081 c; c = gfc_constructor_next (c), cm = cm->next)
6083 /* Skip absent members in default initializers. */
6084 if (!c->expr)
6085 continue;
6087 field = cm->backend_decl;
6088 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
6089 dest, field, NULL_TREE);
6090 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
6091 gfc_add_expr_to_block (&block, tmp);
6093 return gfc_finish_block (&block);
6096 /* Build an expression for a constructor. If init is nonzero then
6097 this is part of a static variable initializer. */
6099 void
6100 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
6102 gfc_constructor *c;
6103 gfc_component *cm;
6104 tree val;
6105 tree type;
6106 tree tmp;
6107 vec<constructor_elt, va_gc> *v = NULL;
6109 gcc_assert (se->ss == NULL);
6110 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
6111 type = gfc_typenode_for_spec (&expr->ts);
6113 if (!init)
6115 /* Create a temporary variable and fill it in. */
6116 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
6117 tmp = gfc_trans_structure_assign (se->expr, expr);
6118 gfc_add_expr_to_block (&se->pre, tmp);
6119 return;
6122 cm = expr->ts.u.derived->components;
6124 for (c = gfc_constructor_first (expr->value.constructor);
6125 c; c = gfc_constructor_next (c), cm = cm->next)
6127 /* Skip absent members in default initializers and allocatable
6128 components. Although the latter have a default initializer
6129 of EXPR_NULL,... by default, the static nullify is not needed
6130 since this is done every time we come into scope. */
6131 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
6132 continue;
6134 if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
6135 && strcmp (cm->name, "_extends") == 0
6136 && cm->initializer->symtree)
6138 tree vtab;
6139 gfc_symbol *vtabs;
6140 vtabs = cm->initializer->symtree->n.sym;
6141 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
6142 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
6144 else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
6146 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
6147 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
6149 else
6151 val = gfc_conv_initializer (c->expr, &cm->ts,
6152 TREE_TYPE (cm->backend_decl),
6153 cm->attr.dimension, cm->attr.pointer,
6154 cm->attr.proc_pointer);
6156 /* Append it to the constructor list. */
6157 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
6160 se->expr = build_constructor (type, v);
6161 if (init)
6162 TREE_CONSTANT (se->expr) = 1;
6166 /* Translate a substring expression. */
6168 static void
6169 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
6171 gfc_ref *ref;
6173 ref = expr->ref;
6175 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
6177 se->expr = gfc_build_wide_string_const (expr->ts.kind,
6178 expr->value.character.length,
6179 expr->value.character.string);
6181 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
6182 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
6184 if (ref)
6185 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
6189 /* Entry point for expression translation. Evaluates a scalar quantity.
6190 EXPR is the expression to be translated, and SE is the state structure if
6191 called from within the scalarized. */
6193 void
6194 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
6196 gfc_ss *ss;
6198 ss = se->ss;
6199 if (ss && ss->info->expr == expr
6200 && (ss->info->type == GFC_SS_SCALAR
6201 || ss->info->type == GFC_SS_REFERENCE))
6203 gfc_ss_info *ss_info;
6205 ss_info = ss->info;
6206 /* Substitute a scalar expression evaluated outside the scalarization
6207 loop. */
6208 se->expr = ss_info->data.scalar.value;
6209 /* If the reference can be NULL, the value field contains the reference,
6210 not the value the reference points to (see gfc_add_loop_ss_code). */
6211 if (ss_info->can_be_null_ref)
6212 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
6214 se->string_length = ss_info->string_length;
6215 gfc_advance_se_ss_chain (se);
6216 return;
6219 /* We need to convert the expressions for the iso_c_binding derived types.
6220 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
6221 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
6222 typespec for the C_PTR and C_FUNPTR symbols, which has already been
6223 updated to be an integer with a kind equal to the size of a (void *). */
6224 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
6225 && expr->ts.u.derived->attr.is_iso_c)
6227 if (expr->expr_type == EXPR_VARIABLE
6228 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
6229 || expr->symtree->n.sym->intmod_sym_id
6230 == ISOCBINDING_NULL_FUNPTR))
6232 /* Set expr_type to EXPR_NULL, which will result in
6233 null_pointer_node being used below. */
6234 expr->expr_type = EXPR_NULL;
6236 else
6238 /* Update the type/kind of the expression to be what the new
6239 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
6240 expr->ts.type = expr->ts.u.derived->ts.type;
6241 expr->ts.f90_type = expr->ts.u.derived->ts.f90_type;
6242 expr->ts.kind = expr->ts.u.derived->ts.kind;
6246 gfc_fix_class_refs (expr);
6248 switch (expr->expr_type)
6250 case EXPR_OP:
6251 gfc_conv_expr_op (se, expr);
6252 break;
6254 case EXPR_FUNCTION:
6255 gfc_conv_function_expr (se, expr);
6256 break;
6258 case EXPR_CONSTANT:
6259 gfc_conv_constant (se, expr);
6260 break;
6262 case EXPR_VARIABLE:
6263 gfc_conv_variable (se, expr);
6264 break;
6266 case EXPR_NULL:
6267 se->expr = null_pointer_node;
6268 break;
6270 case EXPR_SUBSTRING:
6271 gfc_conv_substring_expr (se, expr);
6272 break;
6274 case EXPR_STRUCTURE:
6275 gfc_conv_structure (se, expr, 0);
6276 break;
6278 case EXPR_ARRAY:
6279 gfc_conv_array_constructor_expr (se, expr);
6280 break;
6282 default:
6283 gcc_unreachable ();
6284 break;
6288 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
6289 of an assignment. */
6290 void
6291 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
6293 gfc_conv_expr (se, expr);
6294 /* All numeric lvalues should have empty post chains. If not we need to
6295 figure out a way of rewriting an lvalue so that it has no post chain. */
6296 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
6299 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
6300 numeric expressions. Used for scalar values where inserting cleanup code
6301 is inconvenient. */
6302 void
6303 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
6305 tree val;
6307 gcc_assert (expr->ts.type != BT_CHARACTER);
6308 gfc_conv_expr (se, expr);
6309 if (se->post.head)
6311 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
6312 gfc_add_modify (&se->pre, val, se->expr);
6313 se->expr = val;
6314 gfc_add_block_to_block (&se->pre, &se->post);
6318 /* Helper to translate an expression and convert it to a particular type. */
6319 void
6320 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
6322 gfc_conv_expr_val (se, expr);
6323 se->expr = convert (type, se->expr);
6327 /* Converts an expression so that it can be passed by reference. Scalar
6328 values only. */
6330 void
6331 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
6333 gfc_ss *ss;
6334 tree var;
6336 ss = se->ss;
6337 if (ss && ss->info->expr == expr
6338 && ss->info->type == GFC_SS_REFERENCE)
6340 /* Returns a reference to the scalar evaluated outside the loop
6341 for this case. */
6342 gfc_conv_expr (se, expr);
6343 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
6344 return;
6347 if (expr->ts.type == BT_CHARACTER)
6349 gfc_conv_expr (se, expr);
6350 gfc_conv_string_parameter (se);
6351 return;
6354 if (expr->expr_type == EXPR_VARIABLE)
6356 se->want_pointer = 1;
6357 gfc_conv_expr (se, expr);
6358 if (se->post.head)
6360 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
6361 gfc_add_modify (&se->pre, var, se->expr);
6362 gfc_add_block_to_block (&se->pre, &se->post);
6363 se->expr = var;
6365 return;
6368 if (expr->expr_type == EXPR_FUNCTION
6369 && ((expr->value.function.esym
6370 && expr->value.function.esym->result->attr.pointer
6371 && !expr->value.function.esym->result->attr.dimension)
6372 || (!expr->value.function.esym && !expr->ref
6373 && expr->symtree->n.sym->attr.pointer
6374 && !expr->symtree->n.sym->attr.dimension)))
6376 se->want_pointer = 1;
6377 gfc_conv_expr (se, expr);
6378 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
6379 gfc_add_modify (&se->pre, var, se->expr);
6380 se->expr = var;
6381 return;
6384 gfc_conv_expr (se, expr);
6386 /* Create a temporary var to hold the value. */
6387 if (TREE_CONSTANT (se->expr))
6389 tree tmp = se->expr;
6390 STRIP_TYPE_NOPS (tmp);
6391 var = build_decl (input_location,
6392 CONST_DECL, NULL, TREE_TYPE (tmp));
6393 DECL_INITIAL (var) = tmp;
6394 TREE_STATIC (var) = 1;
6395 pushdecl (var);
6397 else
6399 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
6400 gfc_add_modify (&se->pre, var, se->expr);
6402 gfc_add_block_to_block (&se->pre, &se->post);
6404 /* Take the address of that value. */
6405 se->expr = gfc_build_addr_expr (NULL_TREE, var);
6409 tree
6410 gfc_trans_pointer_assign (gfc_code * code)
6412 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
6416 /* Generate code for a pointer assignment. */
6418 tree
6419 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
6421 gfc_se lse;
6422 gfc_se rse;
6423 stmtblock_t block;
6424 tree desc;
6425 tree tmp;
6426 tree decl;
6427 bool scalar;
6428 gfc_ss *ss;
6430 gfc_start_block (&block);
6432 gfc_init_se (&lse, NULL);
6434 /* Check whether the expression is a scalar or not; we cannot use
6435 expr1->rank as it can be nonzero for proc pointers. */
6436 ss = gfc_walk_expr (expr1);
6437 scalar = ss == gfc_ss_terminator;
6438 if (!scalar)
6439 gfc_free_ss_chain (ss);
6441 if (scalar)
6443 /* Scalar pointers. */
6444 lse.want_pointer = 1;
6445 gfc_conv_expr (&lse, expr1);
6446 gfc_init_se (&rse, NULL);
6447 rse.want_pointer = 1;
6448 gfc_conv_expr (&rse, expr2);
6450 if (expr1->symtree->n.sym->attr.proc_pointer
6451 && expr1->symtree->n.sym->attr.dummy)
6452 lse.expr = build_fold_indirect_ref_loc (input_location,
6453 lse.expr);
6455 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
6456 && expr2->symtree->n.sym->attr.dummy)
6457 rse.expr = build_fold_indirect_ref_loc (input_location,
6458 rse.expr);
6460 gfc_add_block_to_block (&block, &lse.pre);
6461 gfc_add_block_to_block (&block, &rse.pre);
6463 /* Check character lengths if character expression. The test is only
6464 really added if -fbounds-check is enabled. Exclude deferred
6465 character length lefthand sides. */
6466 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
6467 && !expr1->ts.deferred
6468 && !expr1->symtree->n.sym->attr.proc_pointer
6469 && !gfc_is_proc_ptr_comp (expr1))
6471 gcc_assert (expr2->ts.type == BT_CHARACTER);
6472 gcc_assert (lse.string_length && rse.string_length);
6473 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
6474 lse.string_length, rse.string_length,
6475 &block);
6478 /* The assignment to an deferred character length sets the string
6479 length to that of the rhs. */
6480 if (expr1->ts.deferred)
6482 if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
6483 gfc_add_modify (&block, lse.string_length, rse.string_length);
6484 else if (lse.string_length != NULL)
6485 gfc_add_modify (&block, lse.string_length,
6486 build_int_cst (gfc_charlen_type_node, 0));
6489 gfc_add_modify (&block, lse.expr,
6490 fold_convert (TREE_TYPE (lse.expr), rse.expr));
6492 gfc_add_block_to_block (&block, &rse.post);
6493 gfc_add_block_to_block (&block, &lse.post);
6495 else
6497 gfc_ref* remap;
6498 bool rank_remap;
6499 tree strlen_lhs;
6500 tree strlen_rhs = NULL_TREE;
6502 /* Array pointer. Find the last reference on the LHS and if it is an
6503 array section ref, we're dealing with bounds remapping. In this case,
6504 set it to AR_FULL so that gfc_conv_expr_descriptor does
6505 not see it and process the bounds remapping afterwards explicitly. */
6506 for (remap = expr1->ref; remap; remap = remap->next)
6507 if (!remap->next && remap->type == REF_ARRAY
6508 && remap->u.ar.type == AR_SECTION)
6509 break;
6510 rank_remap = (remap && remap->u.ar.end[0]);
6512 if (remap)
6513 lse.descriptor_only = 1;
6514 gfc_conv_expr_descriptor (&lse, expr1);
6515 strlen_lhs = lse.string_length;
6516 desc = lse.expr;
6518 if (expr2->expr_type == EXPR_NULL)
6520 /* Just set the data pointer to null. */
6521 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
6523 else if (rank_remap)
6525 /* If we are rank-remapping, just get the RHS's descriptor and
6526 process this later on. */
6527 gfc_init_se (&rse, NULL);
6528 rse.direct_byref = 1;
6529 rse.byref_noassign = 1;
6530 gfc_conv_expr_descriptor (&rse, expr2);
6531 strlen_rhs = rse.string_length;
6533 else if (expr2->expr_type == EXPR_VARIABLE)
6535 /* Assign directly to the LHS's descriptor. */
6536 lse.direct_byref = 1;
6537 gfc_conv_expr_descriptor (&lse, expr2);
6538 strlen_rhs = lse.string_length;
6540 /* If this is a subreference array pointer assignment, use the rhs
6541 descriptor element size for the lhs span. */
6542 if (expr1->symtree->n.sym->attr.subref_array_pointer)
6544 decl = expr1->symtree->n.sym->backend_decl;
6545 gfc_init_se (&rse, NULL);
6546 rse.descriptor_only = 1;
6547 gfc_conv_expr (&rse, expr2);
6548 tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
6549 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
6550 if (!INTEGER_CST_P (tmp))
6551 gfc_add_block_to_block (&lse.post, &rse.pre);
6552 gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
6555 else
6557 /* Assign to a temporary descriptor and then copy that
6558 temporary to the pointer. */
6559 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
6561 lse.expr = tmp;
6562 lse.direct_byref = 1;
6563 gfc_conv_expr_descriptor (&lse, expr2);
6564 strlen_rhs = lse.string_length;
6565 gfc_add_modify (&lse.pre, desc, tmp);
6568 gfc_add_block_to_block (&block, &lse.pre);
6569 if (rank_remap)
6570 gfc_add_block_to_block (&block, &rse.pre);
6572 /* If we do bounds remapping, update LHS descriptor accordingly. */
6573 if (remap)
6575 int dim;
6576 gcc_assert (remap->u.ar.dimen == expr1->rank);
6578 if (rank_remap)
6580 /* Do rank remapping. We already have the RHS's descriptor
6581 converted in rse and now have to build the correct LHS
6582 descriptor for it. */
6584 tree dtype, data;
6585 tree offs, stride;
6586 tree lbound, ubound;
6588 /* Set dtype. */
6589 dtype = gfc_conv_descriptor_dtype (desc);
6590 tmp = gfc_get_dtype (TREE_TYPE (desc));
6591 gfc_add_modify (&block, dtype, tmp);
6593 /* Copy data pointer. */
6594 data = gfc_conv_descriptor_data_get (rse.expr);
6595 gfc_conv_descriptor_data_set (&block, desc, data);
6597 /* Copy offset but adjust it such that it would correspond
6598 to a lbound of zero. */
6599 offs = gfc_conv_descriptor_offset_get (rse.expr);
6600 for (dim = 0; dim < expr2->rank; ++dim)
6602 stride = gfc_conv_descriptor_stride_get (rse.expr,
6603 gfc_rank_cst[dim]);
6604 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
6605 gfc_rank_cst[dim]);
6606 tmp = fold_build2_loc (input_location, MULT_EXPR,
6607 gfc_array_index_type, stride, lbound);
6608 offs = fold_build2_loc (input_location, PLUS_EXPR,
6609 gfc_array_index_type, offs, tmp);
6611 gfc_conv_descriptor_offset_set (&block, desc, offs);
6613 /* Set the bounds as declared for the LHS and calculate strides as
6614 well as another offset update accordingly. */
6615 stride = gfc_conv_descriptor_stride_get (rse.expr,
6616 gfc_rank_cst[0]);
6617 for (dim = 0; dim < expr1->rank; ++dim)
6619 gfc_se lower_se;
6620 gfc_se upper_se;
6622 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
6624 /* Convert declared bounds. */
6625 gfc_init_se (&lower_se, NULL);
6626 gfc_init_se (&upper_se, NULL);
6627 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
6628 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
6630 gfc_add_block_to_block (&block, &lower_se.pre);
6631 gfc_add_block_to_block (&block, &upper_se.pre);
6633 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
6634 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
6636 lbound = gfc_evaluate_now (lbound, &block);
6637 ubound = gfc_evaluate_now (ubound, &block);
6639 gfc_add_block_to_block (&block, &lower_se.post);
6640 gfc_add_block_to_block (&block, &upper_se.post);
6642 /* Set bounds in descriptor. */
6643 gfc_conv_descriptor_lbound_set (&block, desc,
6644 gfc_rank_cst[dim], lbound);
6645 gfc_conv_descriptor_ubound_set (&block, desc,
6646 gfc_rank_cst[dim], ubound);
6648 /* Set stride. */
6649 stride = gfc_evaluate_now (stride, &block);
6650 gfc_conv_descriptor_stride_set (&block, desc,
6651 gfc_rank_cst[dim], stride);
6653 /* Update offset. */
6654 offs = gfc_conv_descriptor_offset_get (desc);
6655 tmp = fold_build2_loc (input_location, MULT_EXPR,
6656 gfc_array_index_type, lbound, stride);
6657 offs = fold_build2_loc (input_location, MINUS_EXPR,
6658 gfc_array_index_type, offs, tmp);
6659 offs = gfc_evaluate_now (offs, &block);
6660 gfc_conv_descriptor_offset_set (&block, desc, offs);
6662 /* Update stride. */
6663 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
6664 stride = fold_build2_loc (input_location, MULT_EXPR,
6665 gfc_array_index_type, stride, tmp);
6668 else
6670 /* Bounds remapping. Just shift the lower bounds. */
6672 gcc_assert (expr1->rank == expr2->rank);
6674 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
6676 gfc_se lbound_se;
6678 gcc_assert (remap->u.ar.start[dim]);
6679 gcc_assert (!remap->u.ar.end[dim]);
6680 gfc_init_se (&lbound_se, NULL);
6681 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
6683 gfc_add_block_to_block (&block, &lbound_se.pre);
6684 gfc_conv_shift_descriptor_lbound (&block, desc,
6685 dim, lbound_se.expr);
6686 gfc_add_block_to_block (&block, &lbound_se.post);
6691 /* Check string lengths if applicable. The check is only really added
6692 to the output code if -fbounds-check is enabled. */
6693 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
6695 gcc_assert (expr2->ts.type == BT_CHARACTER);
6696 gcc_assert (strlen_lhs && strlen_rhs);
6697 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
6698 strlen_lhs, strlen_rhs, &block);
6701 /* If rank remapping was done, check with -fcheck=bounds that
6702 the target is at least as large as the pointer. */
6703 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
6705 tree lsize, rsize;
6706 tree fault;
6707 const char* msg;
6709 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
6710 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
6712 lsize = gfc_evaluate_now (lsize, &block);
6713 rsize = gfc_evaluate_now (rsize, &block);
6714 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
6715 rsize, lsize);
6717 msg = _("Target of rank remapping is too small (%ld < %ld)");
6718 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
6719 msg, rsize, lsize);
6722 gfc_add_block_to_block (&block, &lse.post);
6723 if (rank_remap)
6724 gfc_add_block_to_block (&block, &rse.post);
6727 return gfc_finish_block (&block);
6731 /* Makes sure se is suitable for passing as a function string parameter. */
6732 /* TODO: Need to check all callers of this function. It may be abused. */
6734 void
6735 gfc_conv_string_parameter (gfc_se * se)
6737 tree type;
6739 if (TREE_CODE (se->expr) == STRING_CST)
6741 type = TREE_TYPE (TREE_TYPE (se->expr));
6742 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
6743 return;
6746 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
6748 if (TREE_CODE (se->expr) != INDIRECT_REF)
6750 type = TREE_TYPE (se->expr);
6751 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
6753 else
6755 type = gfc_get_character_type_len (gfc_default_character_kind,
6756 se->string_length);
6757 type = build_pointer_type (type);
6758 se->expr = gfc_build_addr_expr (type, se->expr);
6762 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
6766 /* Generate code for assignment of scalar variables. Includes character
6767 strings and derived types with allocatable components.
6768 If you know that the LHS has no allocations, set dealloc to false.
6770 DEEP_COPY has no effect if the typespec TS is not a derived type with
6771 allocatable components. Otherwise, if it is set, an explicit copy of each
6772 allocatable component is made. This is necessary as a simple copy of the
6773 whole object would copy array descriptors as is, so that the lhs's
6774 allocatable components would point to the rhs's after the assignment.
6775 Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
6776 necessary if the rhs is a non-pointer function, as the allocatable components
6777 are not accessible by other means than the function's result after the
6778 function has returned. It is even more subtle when temporaries are involved,
6779 as the two following examples show:
6780 1. When we evaluate an array constructor, a temporary is created. Thus
6781 there is theoretically no alias possible. However, no deep copy is
6782 made for this temporary, so that if the constructor is made of one or
6783 more variable with allocatable components, those components still point
6784 to the variable's: DEEP_COPY should be set for the assignment from the
6785 temporary to the lhs in that case.
6786 2. When assigning a scalar to an array, we evaluate the scalar value out
6787 of the loop, store it into a temporary variable, and assign from that.
6788 In that case, deep copying when assigning to the temporary would be a
6789 waste of resources; however deep copies should happen when assigning from
6790 the temporary to each array element: again DEEP_COPY should be set for
6791 the assignment from the temporary to the lhs. */
6793 tree
6794 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
6795 bool l_is_temp, bool deep_copy, bool dealloc)
6797 stmtblock_t block;
6798 tree tmp;
6799 tree cond;
6801 gfc_init_block (&block);
6803 if (ts.type == BT_CHARACTER)
6805 tree rlen = NULL;
6806 tree llen = NULL;
6808 if (lse->string_length != NULL_TREE)
6810 gfc_conv_string_parameter (lse);
6811 gfc_add_block_to_block (&block, &lse->pre);
6812 llen = lse->string_length;
6815 if (rse->string_length != NULL_TREE)
6817 gcc_assert (rse->string_length != NULL_TREE);
6818 gfc_conv_string_parameter (rse);
6819 gfc_add_block_to_block (&block, &rse->pre);
6820 rlen = rse->string_length;
6823 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
6824 rse->expr, ts.kind);
6826 else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
6828 cond = NULL_TREE;
6830 /* Are the rhs and the lhs the same? */
6831 if (deep_copy)
6833 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
6834 gfc_build_addr_expr (NULL_TREE, lse->expr),
6835 gfc_build_addr_expr (NULL_TREE, rse->expr));
6836 cond = gfc_evaluate_now (cond, &lse->pre);
6839 /* Deallocate the lhs allocated components as long as it is not
6840 the same as the rhs. This must be done following the assignment
6841 to prevent deallocating data that could be used in the rhs
6842 expression. */
6843 if (!l_is_temp && dealloc)
6845 tmp = gfc_evaluate_now (lse->expr, &lse->pre);
6846 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
6847 if (deep_copy)
6848 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
6849 tmp);
6850 gfc_add_expr_to_block (&lse->post, tmp);
6853 gfc_add_block_to_block (&block, &rse->pre);
6854 gfc_add_block_to_block (&block, &lse->pre);
6856 gfc_add_modify (&block, lse->expr,
6857 fold_convert (TREE_TYPE (lse->expr), rse->expr));
6859 /* Do a deep copy if the rhs is a variable, if it is not the
6860 same as the lhs. */
6861 if (deep_copy)
6863 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
6864 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
6865 tmp);
6866 gfc_add_expr_to_block (&block, tmp);
6869 else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
6871 gfc_add_block_to_block (&block, &lse->pre);
6872 gfc_add_block_to_block (&block, &rse->pre);
6873 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
6874 TREE_TYPE (lse->expr), rse->expr);
6875 gfc_add_modify (&block, lse->expr, tmp);
6877 else
6879 gfc_add_block_to_block (&block, &lse->pre);
6880 gfc_add_block_to_block (&block, &rse->pre);
6882 gfc_add_modify (&block, lse->expr,
6883 fold_convert (TREE_TYPE (lse->expr), rse->expr));
6886 gfc_add_block_to_block (&block, &lse->post);
6887 gfc_add_block_to_block (&block, &rse->post);
6889 return gfc_finish_block (&block);
6893 /* There are quite a lot of restrictions on the optimisation in using an
6894 array function assign without a temporary. */
6896 static bool
6897 arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
6899 gfc_ref * ref;
6900 bool seen_array_ref;
6901 bool c = false;
6902 gfc_symbol *sym = expr1->symtree->n.sym;
6904 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
6905 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
6906 return true;
6908 /* Elemental functions are scalarized so that they don't need a
6909 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
6910 they would need special treatment in gfc_trans_arrayfunc_assign. */
6911 if (expr2->value.function.esym != NULL
6912 && expr2->value.function.esym->attr.elemental)
6913 return true;
6915 /* Need a temporary if rhs is not FULL or a contiguous section. */
6916 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
6917 return true;
6919 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
6920 if (gfc_ref_needs_temporary_p (expr1->ref))
6921 return true;
6923 /* Functions returning pointers or allocatables need temporaries. */
6924 c = expr2->value.function.esym
6925 ? (expr2->value.function.esym->attr.pointer
6926 || expr2->value.function.esym->attr.allocatable)
6927 : (expr2->symtree->n.sym->attr.pointer
6928 || expr2->symtree->n.sym->attr.allocatable);
6929 if (c)
6930 return true;
6932 /* Character array functions need temporaries unless the
6933 character lengths are the same. */
6934 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
6936 if (expr1->ts.u.cl->length == NULL
6937 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
6938 return true;
6940 if (expr2->ts.u.cl->length == NULL
6941 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
6942 return true;
6944 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
6945 expr2->ts.u.cl->length->value.integer) != 0)
6946 return true;
6949 /* Check that no LHS component references appear during an array
6950 reference. This is needed because we do not have the means to
6951 span any arbitrary stride with an array descriptor. This check
6952 is not needed for the rhs because the function result has to be
6953 a complete type. */
6954 seen_array_ref = false;
6955 for (ref = expr1->ref; ref; ref = ref->next)
6957 if (ref->type == REF_ARRAY)
6958 seen_array_ref= true;
6959 else if (ref->type == REF_COMPONENT && seen_array_ref)
6960 return true;
6963 /* Check for a dependency. */
6964 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
6965 expr2->value.function.esym,
6966 expr2->value.function.actual,
6967 NOT_ELEMENTAL))
6968 return true;
6970 /* If we have reached here with an intrinsic function, we do not
6971 need a temporary except in the particular case that reallocation
6972 on assignment is active and the lhs is allocatable and a target. */
6973 if (expr2->value.function.isym)
6974 return (gfc_option.flag_realloc_lhs
6975 && sym->attr.allocatable
6976 && sym->attr.target);
6978 /* If the LHS is a dummy, we need a temporary if it is not
6979 INTENT(OUT). */
6980 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
6981 return true;
6983 /* If the lhs has been host_associated, is in common, a pointer or is
6984 a target and the function is not using a RESULT variable, aliasing
6985 can occur and a temporary is needed. */
6986 if ((sym->attr.host_assoc
6987 || sym->attr.in_common
6988 || sym->attr.pointer
6989 || sym->attr.cray_pointee
6990 || sym->attr.target)
6991 && expr2->symtree != NULL
6992 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
6993 return true;
6995 /* A PURE function can unconditionally be called without a temporary. */
6996 if (expr2->value.function.esym != NULL
6997 && expr2->value.function.esym->attr.pure)
6998 return false;
7000 /* Implicit_pure functions are those which could legally be declared
7001 to be PURE. */
7002 if (expr2->value.function.esym != NULL
7003 && expr2->value.function.esym->attr.implicit_pure)
7004 return false;
7006 if (!sym->attr.use_assoc
7007 && !sym->attr.in_common
7008 && !sym->attr.pointer
7009 && !sym->attr.target
7010 && !sym->attr.cray_pointee
7011 && expr2->value.function.esym)
7013 /* A temporary is not needed if the function is not contained and
7014 the variable is local or host associated and not a pointer or
7015 a target. */
7016 if (!expr2->value.function.esym->attr.contained)
7017 return false;
7019 /* A temporary is not needed if the lhs has never been host
7020 associated and the procedure is contained. */
7021 else if (!sym->attr.host_assoc)
7022 return false;
7024 /* A temporary is not needed if the variable is local and not
7025 a pointer, a target or a result. */
7026 if (sym->ns->parent
7027 && expr2->value.function.esym->ns == sym->ns->parent)
7028 return false;
7031 /* Default to temporary use. */
7032 return true;
7036 /* Provide the loop info so that the lhs descriptor can be built for
7037 reallocatable assignments from extrinsic function calls. */
7039 static void
7040 realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
7041 gfc_loopinfo *loop)
7043 /* Signal that the function call should not be made by
7044 gfc_conv_loop_setup. */
7045 se->ss->is_alloc_lhs = 1;
7046 gfc_init_loopinfo (loop);
7047 gfc_add_ss_to_loop (loop, *ss);
7048 gfc_add_ss_to_loop (loop, se->ss);
7049 gfc_conv_ss_startstride (loop);
7050 gfc_conv_loop_setup (loop, where);
7051 gfc_copy_loopinfo_to_se (se, loop);
7052 gfc_add_block_to_block (&se->pre, &loop->pre);
7053 gfc_add_block_to_block (&se->pre, &loop->post);
7054 se->ss->is_alloc_lhs = 0;
7058 /* For assignment to a reallocatable lhs from intrinsic functions,
7059 replace the se.expr (ie. the result) with a temporary descriptor.
7060 Null the data field so that the library allocates space for the
7061 result. Free the data of the original descriptor after the function,
7062 in case it appears in an argument expression and transfer the
7063 result to the original descriptor. */
7065 static void
7066 fcncall_realloc_result (gfc_se *se, int rank)
7068 tree desc;
7069 tree res_desc;
7070 tree tmp;
7071 tree offset;
7072 tree zero_cond;
7073 int n;
7075 /* Use the allocation done by the library. Substitute the lhs
7076 descriptor with a copy, whose data field is nulled.*/
7077 desc = build_fold_indirect_ref_loc (input_location, se->expr);
7078 if (POINTER_TYPE_P (TREE_TYPE (desc)))
7079 desc = build_fold_indirect_ref_loc (input_location, desc);
7081 /* Unallocated, the descriptor does not have a dtype. */
7082 tmp = gfc_conv_descriptor_dtype (desc);
7083 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
7085 res_desc = gfc_evaluate_now (desc, &se->pre);
7086 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
7087 se->expr = gfc_build_addr_expr (TREE_TYPE (se->expr), res_desc);
7089 /* Free the lhs after the function call and copy the result data to
7090 the lhs descriptor. */
7091 tmp = gfc_conv_descriptor_data_get (desc);
7092 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
7093 boolean_type_node, tmp,
7094 build_int_cst (TREE_TYPE (tmp), 0));
7095 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
7096 tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
7097 gfc_add_expr_to_block (&se->post, tmp);
7099 tmp = gfc_conv_descriptor_data_get (res_desc);
7100 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
7102 /* Check that the shapes are the same between lhs and expression. */
7103 for (n = 0 ; n < rank; n++)
7105 tree tmp1;
7106 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
7107 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
7108 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7109 gfc_array_index_type, tmp, tmp1);
7110 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
7111 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7112 gfc_array_index_type, tmp, tmp1);
7113 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
7114 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7115 gfc_array_index_type, tmp, tmp1);
7116 tmp = fold_build2_loc (input_location, NE_EXPR,
7117 boolean_type_node, tmp,
7118 gfc_index_zero_node);
7119 tmp = gfc_evaluate_now (tmp, &se->post);
7120 zero_cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
7121 boolean_type_node, tmp,
7122 zero_cond);
7125 /* 'zero_cond' being true is equal to lhs not being allocated or the
7126 shapes being different. */
7127 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
7129 /* Now reset the bounds returned from the function call to bounds based
7130 on the lhs lbounds, except where the lhs is not allocated or the shapes
7131 of 'variable and 'expr' are different. Set the offset accordingly. */
7132 offset = gfc_index_zero_node;
7133 for (n = 0 ; n < rank; n++)
7135 tree lbound;
7137 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
7138 lbound = fold_build3_loc (input_location, COND_EXPR,
7139 gfc_array_index_type, zero_cond,
7140 gfc_index_one_node, lbound);
7141 lbound = gfc_evaluate_now (lbound, &se->post);
7143 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
7144 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7145 gfc_array_index_type, tmp, lbound);
7146 gfc_conv_descriptor_lbound_set (&se->post, desc,
7147 gfc_rank_cst[n], lbound);
7148 gfc_conv_descriptor_ubound_set (&se->post, desc,
7149 gfc_rank_cst[n], tmp);
7151 /* Set stride and accumulate the offset. */
7152 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
7153 gfc_conv_descriptor_stride_set (&se->post, desc,
7154 gfc_rank_cst[n], tmp);
7155 tmp = fold_build2_loc (input_location, MULT_EXPR,
7156 gfc_array_index_type, lbound, tmp);
7157 offset = fold_build2_loc (input_location, MINUS_EXPR,
7158 gfc_array_index_type, offset, tmp);
7159 offset = gfc_evaluate_now (offset, &se->post);
7162 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
7167 /* Try to translate array(:) = func (...), where func is a transformational
7168 array function, without using a temporary. Returns NULL if this isn't the
7169 case. */
7171 static tree
7172 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
7174 gfc_se se;
7175 gfc_ss *ss = NULL;
7176 gfc_component *comp = NULL;
7177 gfc_loopinfo loop;
7179 if (arrayfunc_assign_needs_temporary (expr1, expr2))
7180 return NULL;
7182 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
7183 functions. */
7184 comp = gfc_get_proc_ptr_comp (expr2);
7185 gcc_assert (expr2->value.function.isym
7186 || (comp && comp->attr.dimension)
7187 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
7188 && expr2->value.function.esym->result->attr.dimension));
7190 gfc_init_se (&se, NULL);
7191 gfc_start_block (&se.pre);
7192 se.want_pointer = 1;
7194 gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
7196 if (expr1->ts.type == BT_DERIVED
7197 && expr1->ts.u.derived->attr.alloc_comp)
7199 tree tmp;
7200 tmp = gfc_deallocate_alloc_comp (expr1->ts.u.derived, se.expr,
7201 expr1->rank);
7202 gfc_add_expr_to_block (&se.pre, tmp);
7205 se.direct_byref = 1;
7206 se.ss = gfc_walk_expr (expr2);
7207 gcc_assert (se.ss != gfc_ss_terminator);
7209 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
7210 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
7211 Clearly, this cannot be done for an allocatable function result, since
7212 the shape of the result is unknown and, in any case, the function must
7213 correctly take care of the reallocation internally. For intrinsic
7214 calls, the array data is freed and the library takes care of allocation.
7215 TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
7216 to the library. */
7217 if (gfc_option.flag_realloc_lhs
7218 && gfc_is_reallocatable_lhs (expr1)
7219 && !gfc_expr_attr (expr1).codimension
7220 && !gfc_is_coindexed (expr1)
7221 && !(expr2->value.function.esym
7222 && expr2->value.function.esym->result->attr.allocatable))
7224 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
7226 if (!expr2->value.function.isym)
7228 ss = gfc_walk_expr (expr1);
7229 gcc_assert (ss != gfc_ss_terminator);
7231 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
7232 ss->is_alloc_lhs = 1;
7234 else
7235 fcncall_realloc_result (&se, expr1->rank);
7238 gfc_conv_function_expr (&se, expr2);
7239 gfc_add_block_to_block (&se.pre, &se.post);
7241 if (ss)
7242 gfc_cleanup_loop (&loop);
7243 else
7244 gfc_free_ss_chain (se.ss);
7246 return gfc_finish_block (&se.pre);
7250 /* Try to efficiently translate array(:) = 0. Return NULL if this
7251 can't be done. */
7253 static tree
7254 gfc_trans_zero_assign (gfc_expr * expr)
7256 tree dest, len, type;
7257 tree tmp;
7258 gfc_symbol *sym;
7260 sym = expr->symtree->n.sym;
7261 dest = gfc_get_symbol_decl (sym);
7263 type = TREE_TYPE (dest);
7264 if (POINTER_TYPE_P (type))
7265 type = TREE_TYPE (type);
7266 if (!GFC_ARRAY_TYPE_P (type))
7267 return NULL_TREE;
7269 /* Determine the length of the array. */
7270 len = GFC_TYPE_ARRAY_SIZE (type);
7271 if (!len || TREE_CODE (len) != INTEGER_CST)
7272 return NULL_TREE;
7274 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
7275 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
7276 fold_convert (gfc_array_index_type, tmp));
7278 /* If we are zeroing a local array avoid taking its address by emitting
7279 a = {} instead. */
7280 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
7281 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
7282 dest, build_constructor (TREE_TYPE (dest),
7283 NULL));
7285 /* Convert arguments to the correct types. */
7286 dest = fold_convert (pvoid_type_node, dest);
7287 len = fold_convert (size_type_node, len);
7289 /* Construct call to __builtin_memset. */
7290 tmp = build_call_expr_loc (input_location,
7291 builtin_decl_explicit (BUILT_IN_MEMSET),
7292 3, dest, integer_zero_node, len);
7293 return fold_convert (void_type_node, tmp);
7297 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
7298 that constructs the call to __builtin_memcpy. */
7300 tree
7301 gfc_build_memcpy_call (tree dst, tree src, tree len)
7303 tree tmp;
7305 /* Convert arguments to the correct types. */
7306 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
7307 dst = gfc_build_addr_expr (pvoid_type_node, dst);
7308 else
7309 dst = fold_convert (pvoid_type_node, dst);
7311 if (!POINTER_TYPE_P (TREE_TYPE (src)))
7312 src = gfc_build_addr_expr (pvoid_type_node, src);
7313 else
7314 src = fold_convert (pvoid_type_node, src);
7316 len = fold_convert (size_type_node, len);
7318 /* Construct call to __builtin_memcpy. */
7319 tmp = build_call_expr_loc (input_location,
7320 builtin_decl_explicit (BUILT_IN_MEMCPY),
7321 3, dst, src, len);
7322 return fold_convert (void_type_node, tmp);
7326 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
7327 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
7328 source/rhs, both are gfc_full_array_ref_p which have been checked for
7329 dependencies. */
7331 static tree
7332 gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
7334 tree dst, dlen, dtype;
7335 tree src, slen, stype;
7336 tree tmp;
7338 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
7339 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
7341 dtype = TREE_TYPE (dst);
7342 if (POINTER_TYPE_P (dtype))
7343 dtype = TREE_TYPE (dtype);
7344 stype = TREE_TYPE (src);
7345 if (POINTER_TYPE_P (stype))
7346 stype = TREE_TYPE (stype);
7348 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
7349 return NULL_TREE;
7351 /* Determine the lengths of the arrays. */
7352 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
7353 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
7354 return NULL_TREE;
7355 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
7356 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7357 dlen, fold_convert (gfc_array_index_type, tmp));
7359 slen = GFC_TYPE_ARRAY_SIZE (stype);
7360 if (!slen || TREE_CODE (slen) != INTEGER_CST)
7361 return NULL_TREE;
7362 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
7363 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7364 slen, fold_convert (gfc_array_index_type, tmp));
7366 /* Sanity check that they are the same. This should always be
7367 the case, as we should already have checked for conformance. */
7368 if (!tree_int_cst_equal (slen, dlen))
7369 return NULL_TREE;
7371 return gfc_build_memcpy_call (dst, src, dlen);
7375 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
7376 this can't be done. EXPR1 is the destination/lhs for which
7377 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
7379 static tree
7380 gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
7382 unsigned HOST_WIDE_INT nelem;
7383 tree dst, dtype;
7384 tree src, stype;
7385 tree len;
7386 tree tmp;
7388 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
7389 if (nelem == 0)
7390 return NULL_TREE;
7392 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
7393 dtype = TREE_TYPE (dst);
7394 if (POINTER_TYPE_P (dtype))
7395 dtype = TREE_TYPE (dtype);
7396 if (!GFC_ARRAY_TYPE_P (dtype))
7397 return NULL_TREE;
7399 /* Determine the lengths of the array. */
7400 len = GFC_TYPE_ARRAY_SIZE (dtype);
7401 if (!len || TREE_CODE (len) != INTEGER_CST)
7402 return NULL_TREE;
7404 /* Confirm that the constructor is the same size. */
7405 if (compare_tree_int (len, nelem) != 0)
7406 return NULL_TREE;
7408 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
7409 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
7410 fold_convert (gfc_array_index_type, tmp));
7412 stype = gfc_typenode_for_spec (&expr2->ts);
7413 src = gfc_build_constant_array_constructor (expr2, stype);
7415 stype = TREE_TYPE (src);
7416 if (POINTER_TYPE_P (stype))
7417 stype = TREE_TYPE (stype);
7419 return gfc_build_memcpy_call (dst, src, len);
7423 /* Tells whether the expression is to be treated as a variable reference. */
7425 static bool
7426 expr_is_variable (gfc_expr *expr)
7428 gfc_expr *arg;
7429 gfc_component *comp;
7430 gfc_symbol *func_ifc;
7432 if (expr->expr_type == EXPR_VARIABLE)
7433 return true;
7435 arg = gfc_get_noncopying_intrinsic_argument (expr);
7436 if (arg)
7438 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
7439 return expr_is_variable (arg);
7442 /* A data-pointer-returning function should be considered as a variable
7443 too. */
7444 if (expr->expr_type == EXPR_FUNCTION
7445 && expr->ref == NULL)
7447 if (expr->value.function.isym != NULL)
7448 return false;
7450 if (expr->value.function.esym != NULL)
7452 func_ifc = expr->value.function.esym;
7453 goto found_ifc;
7455 else
7457 gcc_assert (expr->symtree);
7458 func_ifc = expr->symtree->n.sym;
7459 goto found_ifc;
7462 gcc_unreachable ();
7465 comp = gfc_get_proc_ptr_comp (expr);
7466 if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
7467 && comp)
7469 func_ifc = comp->ts.interface;
7470 goto found_ifc;
7473 if (expr->expr_type == EXPR_COMPCALL)
7475 gcc_assert (!expr->value.compcall.tbp->is_generic);
7476 func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
7477 goto found_ifc;
7480 return false;
7482 found_ifc:
7483 gcc_assert (func_ifc->attr.function
7484 && func_ifc->result != NULL);
7485 return func_ifc->result->attr.pointer;
7489 /* Is the lhs OK for automatic reallocation? */
7491 static bool
7492 is_scalar_reallocatable_lhs (gfc_expr *expr)
7494 gfc_ref * ref;
7496 /* An allocatable variable with no reference. */
7497 if (expr->symtree->n.sym->attr.allocatable
7498 && !expr->ref)
7499 return true;
7501 /* All that can be left are allocatable components. */
7502 if ((expr->symtree->n.sym->ts.type != BT_DERIVED
7503 && expr->symtree->n.sym->ts.type != BT_CLASS)
7504 || !expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
7505 return false;
7507 /* Find an allocatable component ref last. */
7508 for (ref = expr->ref; ref; ref = ref->next)
7509 if (ref->type == REF_COMPONENT
7510 && !ref->next
7511 && ref->u.c.component->attr.allocatable)
7512 return true;
7514 return false;
7518 /* Allocate or reallocate scalar lhs, as necessary. */
7520 static void
7521 alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
7522 tree string_length,
7523 gfc_expr *expr1,
7524 gfc_expr *expr2)
7527 tree cond;
7528 tree tmp;
7529 tree size;
7530 tree size_in_bytes;
7531 tree jump_label1;
7532 tree jump_label2;
7533 gfc_se lse;
7535 if (!expr1 || expr1->rank)
7536 return;
7538 if (!expr2 || expr2->rank)
7539 return;
7541 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
7543 /* Since this is a scalar lhs, we can afford to do this. That is,
7544 there is no risk of side effects being repeated. */
7545 gfc_init_se (&lse, NULL);
7546 lse.want_pointer = 1;
7547 gfc_conv_expr (&lse, expr1);
7549 jump_label1 = gfc_build_label_decl (NULL_TREE);
7550 jump_label2 = gfc_build_label_decl (NULL_TREE);
7552 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
7553 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
7554 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7555 lse.expr, tmp);
7556 tmp = build3_v (COND_EXPR, cond,
7557 build1_v (GOTO_EXPR, jump_label1),
7558 build_empty_stmt (input_location));
7559 gfc_add_expr_to_block (block, tmp);
7561 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7563 /* Use the rhs string length and the lhs element size. */
7564 size = string_length;
7565 tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
7566 tmp = TYPE_SIZE_UNIT (tmp);
7567 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
7568 TREE_TYPE (tmp), tmp,
7569 fold_convert (TREE_TYPE (tmp), size));
7571 else
7573 /* Otherwise use the length in bytes of the rhs. */
7574 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
7575 size_in_bytes = size;
7578 if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
7580 tmp = build_call_expr_loc (input_location,
7581 builtin_decl_explicit (BUILT_IN_CALLOC),
7582 2, build_one_cst (size_type_node),
7583 size_in_bytes);
7584 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
7585 gfc_add_modify (block, lse.expr, tmp);
7587 else
7589 tmp = build_call_expr_loc (input_location,
7590 builtin_decl_explicit (BUILT_IN_MALLOC),
7591 1, size_in_bytes);
7592 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
7593 gfc_add_modify (block, lse.expr, tmp);
7596 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7598 /* Deferred characters need checking for lhs and rhs string
7599 length. Other deferred parameter variables will have to
7600 come here too. */
7601 tmp = build1_v (GOTO_EXPR, jump_label2);
7602 gfc_add_expr_to_block (block, tmp);
7604 tmp = build1_v (LABEL_EXPR, jump_label1);
7605 gfc_add_expr_to_block (block, tmp);
7607 /* For a deferred length character, reallocate if lengths of lhs and
7608 rhs are different. */
7609 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
7611 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
7612 expr1->ts.u.cl->backend_decl, size);
7613 /* Jump past the realloc if the lengths are the same. */
7614 tmp = build3_v (COND_EXPR, cond,
7615 build1_v (GOTO_EXPR, jump_label2),
7616 build_empty_stmt (input_location));
7617 gfc_add_expr_to_block (block, tmp);
7618 tmp = build_call_expr_loc (input_location,
7619 builtin_decl_explicit (BUILT_IN_REALLOC),
7620 2, fold_convert (pvoid_type_node, lse.expr),
7621 size_in_bytes);
7622 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
7623 gfc_add_modify (block, lse.expr, tmp);
7624 tmp = build1_v (LABEL_EXPR, jump_label2);
7625 gfc_add_expr_to_block (block, tmp);
7627 /* Update the lhs character length. */
7628 size = string_length;
7629 gfc_add_modify (block, expr1->ts.u.cl->backend_decl, size);
7634 /* Subroutine of gfc_trans_assignment that actually scalarizes the
7635 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
7636 init_flag indicates initialization expressions and dealloc that no
7637 deallocate prior assignment is needed (if in doubt, set true). */
7639 static tree
7640 gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
7641 bool dealloc)
7643 gfc_se lse;
7644 gfc_se rse;
7645 gfc_ss *lss;
7646 gfc_ss *lss_section;
7647 gfc_ss *rss;
7648 gfc_loopinfo loop;
7649 tree tmp;
7650 stmtblock_t block;
7651 stmtblock_t body;
7652 bool l_is_temp;
7653 bool scalar_to_array;
7654 tree string_length;
7655 int n;
7657 /* Assignment of the form lhs = rhs. */
7658 gfc_start_block (&block);
7660 gfc_init_se (&lse, NULL);
7661 gfc_init_se (&rse, NULL);
7663 /* Walk the lhs. */
7664 lss = gfc_walk_expr (expr1);
7665 if (gfc_is_reallocatable_lhs (expr1)
7666 && !(expr2->expr_type == EXPR_FUNCTION
7667 && expr2->value.function.isym != NULL))
7668 lss->is_alloc_lhs = 1;
7669 rss = NULL;
7670 if (lss != gfc_ss_terminator)
7672 /* The assignment needs scalarization. */
7673 lss_section = lss;
7675 /* Find a non-scalar SS from the lhs. */
7676 while (lss_section != gfc_ss_terminator
7677 && lss_section->info->type != GFC_SS_SECTION)
7678 lss_section = lss_section->next;
7680 gcc_assert (lss_section != gfc_ss_terminator);
7682 /* Initialize the scalarizer. */
7683 gfc_init_loopinfo (&loop);
7685 /* Walk the rhs. */
7686 rss = gfc_walk_expr (expr2);
7687 if (rss == gfc_ss_terminator)
7688 /* The rhs is scalar. Add a ss for the expression. */
7689 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
7691 /* Associate the SS with the loop. */
7692 gfc_add_ss_to_loop (&loop, lss);
7693 gfc_add_ss_to_loop (&loop, rss);
7695 /* Calculate the bounds of the scalarization. */
7696 gfc_conv_ss_startstride (&loop);
7697 /* Enable loop reversal. */
7698 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
7699 loop.reverse[n] = GFC_ENABLE_REVERSE;
7700 /* Resolve any data dependencies in the statement. */
7701 gfc_conv_resolve_dependencies (&loop, lss, rss);
7702 /* Setup the scalarizing loops. */
7703 gfc_conv_loop_setup (&loop, &expr2->where);
7705 /* Setup the gfc_se structures. */
7706 gfc_copy_loopinfo_to_se (&lse, &loop);
7707 gfc_copy_loopinfo_to_se (&rse, &loop);
7709 rse.ss = rss;
7710 gfc_mark_ss_chain_used (rss, 1);
7711 if (loop.temp_ss == NULL)
7713 lse.ss = lss;
7714 gfc_mark_ss_chain_used (lss, 1);
7716 else
7718 lse.ss = loop.temp_ss;
7719 gfc_mark_ss_chain_used (lss, 3);
7720 gfc_mark_ss_chain_used (loop.temp_ss, 3);
7723 /* Allow the scalarizer to workshare array assignments. */
7724 if ((ompws_flags & OMPWS_WORKSHARE_FLAG) && loop.temp_ss == NULL)
7725 ompws_flags |= OMPWS_SCALARIZER_WS;
7727 /* Start the scalarized loop body. */
7728 gfc_start_scalarized_body (&loop, &body);
7730 else
7731 gfc_init_block (&body);
7733 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
7735 /* Translate the expression. */
7736 gfc_conv_expr (&rse, expr2);
7738 /* Stabilize a string length for temporaries. */
7739 if (expr2->ts.type == BT_CHARACTER)
7740 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
7741 else
7742 string_length = NULL_TREE;
7744 if (l_is_temp)
7746 gfc_conv_tmp_array_ref (&lse);
7747 if (expr2->ts.type == BT_CHARACTER)
7748 lse.string_length = string_length;
7750 else
7751 gfc_conv_expr (&lse, expr1);
7753 /* Assignments of scalar derived types with allocatable components
7754 to arrays must be done with a deep copy and the rhs temporary
7755 must have its components deallocated afterwards. */
7756 scalar_to_array = (expr2->ts.type == BT_DERIVED
7757 && expr2->ts.u.derived->attr.alloc_comp
7758 && !expr_is_variable (expr2)
7759 && !gfc_is_constant_expr (expr2)
7760 && expr1->rank && !expr2->rank);
7761 if (scalar_to_array && dealloc)
7763 tmp = gfc_deallocate_alloc_comp (expr2->ts.u.derived, rse.expr, 0);
7764 gfc_add_expr_to_block (&loop.post, tmp);
7767 /* When assigning a character function result to a deferred-length variable,
7768 the function call must happen before the (re)allocation of the lhs -
7769 otherwise the character length of the result is not known.
7770 NOTE: This relies on having the exact dependence of the length type
7771 parameter available to the caller; gfortran saves it in the .mod files. */
7772 if (gfc_option.flag_realloc_lhs && expr2->ts.type == BT_CHARACTER
7773 && expr1->ts.deferred)
7774 gfc_add_block_to_block (&block, &rse.pre);
7776 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
7777 l_is_temp || init_flag,
7778 expr_is_variable (expr2) || scalar_to_array
7779 || expr2->expr_type == EXPR_ARRAY, dealloc);
7780 gfc_add_expr_to_block (&body, tmp);
7782 if (lss == gfc_ss_terminator)
7784 /* F2003: Add the code for reallocation on assignment. */
7785 if (gfc_option.flag_realloc_lhs
7786 && is_scalar_reallocatable_lhs (expr1))
7787 alloc_scalar_allocatable_for_assignment (&block, rse.string_length,
7788 expr1, expr2);
7790 /* Use the scalar assignment as is. */
7791 gfc_add_block_to_block (&block, &body);
7793 else
7795 gcc_assert (lse.ss == gfc_ss_terminator
7796 && rse.ss == gfc_ss_terminator);
7798 if (l_is_temp)
7800 gfc_trans_scalarized_loop_boundary (&loop, &body);
7802 /* We need to copy the temporary to the actual lhs. */
7803 gfc_init_se (&lse, NULL);
7804 gfc_init_se (&rse, NULL);
7805 gfc_copy_loopinfo_to_se (&lse, &loop);
7806 gfc_copy_loopinfo_to_se (&rse, &loop);
7808 rse.ss = loop.temp_ss;
7809 lse.ss = lss;
7811 gfc_conv_tmp_array_ref (&rse);
7812 gfc_conv_expr (&lse, expr1);
7814 gcc_assert (lse.ss == gfc_ss_terminator
7815 && rse.ss == gfc_ss_terminator);
7817 if (expr2->ts.type == BT_CHARACTER)
7818 rse.string_length = string_length;
7820 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
7821 false, false, dealloc);
7822 gfc_add_expr_to_block (&body, tmp);
7825 /* F2003: Allocate or reallocate lhs of allocatable array. */
7826 if (gfc_option.flag_realloc_lhs
7827 && gfc_is_reallocatable_lhs (expr1)
7828 && !gfc_expr_attr (expr1).codimension
7829 && !gfc_is_coindexed (expr1)
7830 && expr2->rank)
7832 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
7833 ompws_flags &= ~OMPWS_SCALARIZER_WS;
7834 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
7835 if (tmp != NULL_TREE)
7836 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
7839 /* Generate the copying loops. */
7840 gfc_trans_scalarizing_loops (&loop, &body);
7842 /* Wrap the whole thing up. */
7843 gfc_add_block_to_block (&block, &loop.pre);
7844 gfc_add_block_to_block (&block, &loop.post);
7846 gfc_cleanup_loop (&loop);
7849 return gfc_finish_block (&block);
7853 /* Check whether EXPR is a copyable array. */
7855 static bool
7856 copyable_array_p (gfc_expr * expr)
7858 if (expr->expr_type != EXPR_VARIABLE)
7859 return false;
7861 /* First check it's an array. */
7862 if (expr->rank < 1 || !expr->ref || expr->ref->next)
7863 return false;
7865 if (!gfc_full_array_ref_p (expr->ref, NULL))
7866 return false;
7868 /* Next check that it's of a simple enough type. */
7869 switch (expr->ts.type)
7871 case BT_INTEGER:
7872 case BT_REAL:
7873 case BT_COMPLEX:
7874 case BT_LOGICAL:
7875 return true;
7877 case BT_CHARACTER:
7878 return false;
7880 case BT_DERIVED:
7881 return !expr->ts.u.derived->attr.alloc_comp;
7883 default:
7884 break;
7887 return false;
7890 /* Translate an assignment. */
7892 tree
7893 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
7894 bool dealloc)
7896 tree tmp;
7898 /* Special case a single function returning an array. */
7899 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
7901 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
7902 if (tmp)
7903 return tmp;
7906 /* Special case assigning an array to zero. */
7907 if (copyable_array_p (expr1)
7908 && is_zero_initializer_p (expr2))
7910 tmp = gfc_trans_zero_assign (expr1);
7911 if (tmp)
7912 return tmp;
7915 /* Special case copying one array to another. */
7916 if (copyable_array_p (expr1)
7917 && copyable_array_p (expr2)
7918 && gfc_compare_types (&expr1->ts, &expr2->ts)
7919 && !gfc_check_dependency (expr1, expr2, 0))
7921 tmp = gfc_trans_array_copy (expr1, expr2);
7922 if (tmp)
7923 return tmp;
7926 /* Special case initializing an array from a constant array constructor. */
7927 if (copyable_array_p (expr1)
7928 && expr2->expr_type == EXPR_ARRAY
7929 && gfc_compare_types (&expr1->ts, &expr2->ts))
7931 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
7932 if (tmp)
7933 return tmp;
7936 /* Fallback to the scalarizer to generate explicit loops. */
7937 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc);
7940 tree
7941 gfc_trans_init_assign (gfc_code * code)
7943 return gfc_trans_assignment (code->expr1, code->expr2, true, false);
7946 tree
7947 gfc_trans_assign (gfc_code * code)
7949 return gfc_trans_assignment (code->expr1, code->expr2, false, true);