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