]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans-expr.c
PR fortran/93308/93963/94327/94331/97046 problems raised by descriptor handling
[thirdparty/gcc.git] / gcc / fortran / trans-expr.c
CommitLineData
6de9cd9a 1/* Expression translation
99dee823 2 Copyright (C) 2002-2021 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
9fc4d79b 6This file is part of GCC.
6de9cd9a 7
9fc4d79b
TS
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
d234d788 10Software Foundation; either version 3, or (at your option) any later
9fc4d79b 11version.
6de9cd9a 12
9fc4d79b
TS
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.
6de9cd9a
DN
17
18You should have received a copy of the GNU General Public License
d234d788
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
21
22/* trans-expr.c-- generate GENERIC trees for gfc_expr. */
23
24#include "config.h"
25#include "system.h"
26#include "coretypes.h"
c7131fb2 27#include "options.h"
2adfab87
AM
28#include "tree.h"
29#include "gfortran.h"
30#include "trans.h"
d8a2d370 31#include "stringpool.h"
c829d016 32#include "diagnostic-core.h" /* For fatal_error. */
2adfab87 33#include "fold-const.h"
b3eb1e0e 34#include "langhooks.h"
0a164a3c 35#include "arith.h"
b7e75771 36#include "constructor.h"
6de9cd9a
DN
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"
7a70c12d 42#include "dependency.h"
45b0be94 43#include "gimplify.h"
c49ea23d 44
d514626e
JRFS
45
46/* Calculate the number of characters in a string. */
47
48tree
49gfc_get_character_len (tree type)
50{
51 tree len;
52
53 gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
54 && TYPE_STRING_FLAG (type));
55
56 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
57 len = (len) ? (len) : (integer_zero_node);
58 return fold_convert (gfc_charlen_type_node, len);
59}
60
61
62
63/* Calculate the number of bytes in a string. */
64
65tree
66gfc_get_character_len_in_bytes (tree type)
67{
68 tree tmp, len;
69
70 gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
71 && TYPE_STRING_FLAG (type));
72
73 tmp = TYPE_SIZE_UNIT (TREE_TYPE (type));
74 tmp = (tmp && !integer_zerop (tmp))
75 ? (fold_convert (gfc_charlen_type_node, tmp)) : (NULL_TREE);
76 len = gfc_get_character_len (type);
77 if (tmp && len && !integer_zerop (len))
78 len = fold_build2_loc (input_location, MULT_EXPR,
79 gfc_charlen_type_node, len, tmp);
80 return len;
81}
82
83
c62c6622
TB
84/* Convert a scalar to an array descriptor. To be used for assumed-rank
85 arrays. */
86
87static tree
88get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
89{
90 enum gfc_array_kind akind;
91
92 if (attr.pointer)
93 akind = GFC_ARRAY_POINTER_CONT;
94 else if (attr.allocatable)
95 akind = GFC_ARRAY_ALLOCATABLE;
96 else
97 akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
98
aa9ca5ca
TB
99 if (POINTER_TYPE_P (TREE_TYPE (scalar)))
100 scalar = TREE_TYPE (scalar);
c62c6622
TB
101 return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
102 akind, !(attr.pointer || attr.target));
103}
104
429cb994
TB
105tree
106gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
c62c6622 107{
7fb43006 108 tree desc, type, etype;
c62c6622
TB
109
110 type = get_scalar_to_descriptor_type (scalar, attr);
7fb43006 111 etype = TREE_TYPE (scalar);
c62c6622
TB
112 desc = gfc_create_var (type, "desc");
113 DECL_ARTIFICIAL (desc) = 1;
7651172f 114
3c9f5092
AV
115 if (CONSTANT_CLASS_P (scalar))
116 {
117 tree tmp;
118 tmp = gfc_create_var (TREE_TYPE (scalar), "scalar");
119 gfc_add_modify (&se->pre, tmp, scalar);
120 scalar = tmp;
121 }
7651172f
TB
122 if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
123 scalar = gfc_build_addr_expr (NULL_TREE, scalar);
7fb43006
PT
124 else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
125 etype = TREE_TYPE (etype);
c62c6622 126 gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
7fb43006 127 gfc_get_dtype_rank_type (0, etype));
c62c6622 128 gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
d514626e
JRFS
129 gfc_conv_descriptor_span_set (&se->pre, desc,
130 gfc_conv_descriptor_elem_len (desc));
c62c6622
TB
131
132 /* Copy pointer address back - but only if it could have changed and
133 if the actual argument is a pointer and not, e.g., NULL(). */
7651172f 134 if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
c62c6622
TB
135 gfc_add_modify (&se->post, scalar,
136 fold_convert (TREE_TYPE (scalar),
137 gfc_conv_descriptor_data_get (desc)));
138 return desc;
139}
140
141
3c9f5092
AV
142/* Get the coarray token from the ultimate array or component ref.
143 Returns a NULL_TREE, when the ref object is not allocatable or pointer. */
144
145tree
146gfc_get_ultimate_alloc_ptr_comps_caf_token (gfc_se *outerse, gfc_expr *expr)
147{
148 gfc_symbol *sym = expr->symtree->n.sym;
149 bool is_coarray = sym->attr.codimension;
150 gfc_expr *caf_expr = gfc_copy_expr (expr);
151 gfc_ref *ref = caf_expr->ref, *last_caf_ref = NULL;
152
153 while (ref)
154 {
155 if (ref->type == REF_COMPONENT
156 && (ref->u.c.component->attr.allocatable
157 || ref->u.c.component->attr.pointer)
158 && (is_coarray || ref->u.c.component->attr.codimension))
159 last_caf_ref = ref;
160 ref = ref->next;
161 }
162
163 if (last_caf_ref == NULL)
164 return NULL_TREE;
165
166 tree comp = last_caf_ref->u.c.component->caf_token, caf;
167 gfc_se se;
168 bool comp_ref = !last_caf_ref->u.c.component->attr.dimension;
169 if (comp == NULL_TREE && comp_ref)
170 return NULL_TREE;
171 gfc_init_se (&se, outerse);
172 gfc_free_ref_list (last_caf_ref->next);
173 last_caf_ref->next = NULL;
174 caf_expr->rank = comp_ref ? 0 : last_caf_ref->u.c.component->as->rank;
175 se.want_pointer = comp_ref;
176 gfc_conv_expr (&se, caf_expr);
177 gfc_add_block_to_block (&outerse->pre, &se.pre);
178
179 if (TREE_CODE (se.expr) == COMPONENT_REF && comp_ref)
180 se.expr = TREE_OPERAND (se.expr, 0);
181 gfc_free_expr (caf_expr);
182
183 if (comp_ref)
184 caf = fold_build3_loc (input_location, COMPONENT_REF,
185 TREE_TYPE (comp), se.expr, comp, NULL_TREE);
186 else
187 caf = gfc_conv_descriptor_token (se.expr);
188 return gfc_build_addr_expr (NULL_TREE, caf);
189}
190
191
c49ea23d
PT
192/* This is the seed for an eventual trans-class.c
193
194 The following parameters should not be used directly since they might
195 in future implementations. Use the corresponding APIs. */
196#define CLASS_DATA_FIELD 0
197#define CLASS_VPTR_FIELD 1
5b384b3d 198#define CLASS_LEN_FIELD 2
c49ea23d
PT
199#define VTABLE_HASH_FIELD 0
200#define VTABLE_SIZE_FIELD 1
201#define VTABLE_EXTENDS_FIELD 2
202#define VTABLE_DEF_INIT_FIELD 3
203#define VTABLE_COPY_FIELD 4
86035eec 204#define VTABLE_FINAL_FIELD 5
bf9f15ee 205#define VTABLE_DEALLOCATE_FIELD 6
c49ea23d
PT
206
207
f118468a
TB
208tree
209gfc_class_set_static_fields (tree decl, tree vptr, tree data)
210{
211 tree tmp;
212 tree field;
213 vec<constructor_elt, va_gc> *init = NULL;
214
215 field = TYPE_FIELDS (TREE_TYPE (decl));
216 tmp = gfc_advance_chain (field, CLASS_DATA_FIELD);
217 CONSTRUCTOR_APPEND_ELT (init, tmp, data);
218
219 tmp = gfc_advance_chain (field, CLASS_VPTR_FIELD);
220 CONSTRUCTOR_APPEND_ELT (init, tmp, vptr);
221
222 return build_constructor (TREE_TYPE (decl), init);
223}
224
225
c49ea23d
PT
226tree
227gfc_class_data_get (tree decl)
228{
229 tree data;
230 if (POINTER_TYPE_P (TREE_TYPE (decl)))
231 decl = build_fold_indirect_ref_loc (input_location, decl);
232 data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
233 CLASS_DATA_FIELD);
234 return fold_build3_loc (input_location, COMPONENT_REF,
235 TREE_TYPE (data), decl, data,
236 NULL_TREE);
237}
238
239
240tree
241gfc_class_vptr_get (tree decl)
242{
243 tree vptr;
f3b0bb7a
AV
244 /* For class arrays decl may be a temporary descriptor handle, the vptr is
245 then available through the saved descriptor. */
d168c883 246 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
f3b0bb7a
AV
247 && GFC_DECL_SAVED_DESCRIPTOR (decl))
248 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
c49ea23d
PT
249 if (POINTER_TYPE_P (TREE_TYPE (decl)))
250 decl = build_fold_indirect_ref_loc (input_location, decl);
251 vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
252 CLASS_VPTR_FIELD);
253 return fold_build3_loc (input_location, COMPONENT_REF,
254 TREE_TYPE (vptr), decl, vptr,
255 NULL_TREE);
256}
257
258
5b384b3d
PT
259tree
260gfc_class_len_get (tree decl)
261{
262 tree len;
f3b0bb7a
AV
263 /* For class arrays decl may be a temporary descriptor handle, the len is
264 then available through the saved descriptor. */
d168c883 265 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
f3b0bb7a
AV
266 && GFC_DECL_SAVED_DESCRIPTOR (decl))
267 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
5b384b3d
PT
268 if (POINTER_TYPE_P (TREE_TYPE (decl)))
269 decl = build_fold_indirect_ref_loc (input_location, decl);
270 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
34d9d749 271 CLASS_LEN_FIELD);
5b384b3d
PT
272 return fold_build3_loc (input_location, COMPONENT_REF,
273 TREE_TYPE (len), decl, len,
274 NULL_TREE);
275}
276
277
728557fd
AV
278/* Try to get the _len component of a class. When the class is not unlimited
279 poly, i.e. no _len field exists, then return a zero node. */
280
281tree
282gfc_class_len_or_zero_get (tree decl)
283{
284 tree len;
285 /* For class arrays decl may be a temporary descriptor handle, the vptr is
286 then available through the saved descriptor. */
d168c883 287 if (VAR_P (decl) && DECL_LANG_SPECIFIC (decl)
728557fd
AV
288 && GFC_DECL_SAVED_DESCRIPTOR (decl))
289 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
290 if (POINTER_TYPE_P (TREE_TYPE (decl)))
291 decl = build_fold_indirect_ref_loc (input_location, decl);
292 len = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
293 CLASS_LEN_FIELD);
294 return len != NULL_TREE ? fold_build3_loc (input_location, COMPONENT_REF,
295 TREE_TYPE (len), decl, len,
296 NULL_TREE)
f622221a 297 : build_zero_cst (gfc_charlen_type_node);
728557fd
AV
298}
299
300
ce8dcc91
PT
301tree
302gfc_resize_class_size_with_len (stmtblock_t * block, tree class_expr, tree size)
303{
304 tree tmp;
305 tree tmp2;
306 tree type;
307
308 tmp = gfc_class_len_or_zero_get (class_expr);
309
310 /* Include the len value in the element size if present. */
311 if (!integer_zerop (tmp))
312 {
313 type = TREE_TYPE (size);
314 if (block)
315 {
316 size = gfc_evaluate_now (size, block);
317 tmp = gfc_evaluate_now (fold_convert (type , tmp), block);
318 }
319 tmp2 = fold_build2_loc (input_location, MULT_EXPR,
320 type, size, tmp);
321 tmp = fold_build2_loc (input_location, GT_EXPR,
322 logical_type_node, tmp,
323 build_zero_cst (type));
324 size = fold_build3_loc (input_location, COND_EXPR,
325 type, tmp, tmp2, size);
326 }
327 else
328 return size;
329
330 if (block)
331 size = gfc_evaluate_now (size, block);
332
333 return size;
334}
335
336
34d9d749
AV
337/* Get the specified FIELD from the VPTR. */
338
c49ea23d 339static tree
34d9d749 340vptr_field_get (tree vptr, int fieldno)
c49ea23d 341{
34d9d749 342 tree field;
c49ea23d 343 vptr = build_fold_indirect_ref_loc (input_location, vptr);
34d9d749
AV
344 field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
345 fieldno);
346 field = fold_build3_loc (input_location, COMPONENT_REF,
347 TREE_TYPE (field), vptr, field,
348 NULL_TREE);
349 gcc_assert (field);
350 return field;
c49ea23d
PT
351}
352
353
34d9d749 354/* Get the field from the class' vptr. */
c49ea23d 355
34d9d749
AV
356static tree
357class_vtab_field_get (tree decl, int fieldno)
c49ea23d 358{
34d9d749
AV
359 tree vptr;
360 vptr = gfc_class_vptr_get (decl);
361 return vptr_field_get (vptr, fieldno);
c49ea23d
PT
362}
363
364
34d9d749
AV
365/* Define a macro for creating the class_vtab_* and vptr_* accessors in
366 unison. */
367#define VTAB_GET_FIELD_GEN(name, field) tree \
368gfc_class_vtab_## name ##_get (tree cl) \
369{ \
370 return class_vtab_field_get (cl, field); \
371} \
372 \
373tree \
374gfc_vptr_## name ##_get (tree vptr) \
375{ \
376 return vptr_field_get (vptr, field); \
c49ea23d
PT
377}
378
34d9d749
AV
379VTAB_GET_FIELD_GEN (hash, VTABLE_HASH_FIELD)
380VTAB_GET_FIELD_GEN (extends, VTABLE_EXTENDS_FIELD)
381VTAB_GET_FIELD_GEN (def_init, VTABLE_DEF_INIT_FIELD)
382VTAB_GET_FIELD_GEN (copy, VTABLE_COPY_FIELD)
383VTAB_GET_FIELD_GEN (final, VTABLE_FINAL_FIELD)
bf9f15ee 384VTAB_GET_FIELD_GEN (deallocate, VTABLE_DEALLOCATE_FIELD)
c49ea23d 385
c49ea23d 386
34d9d749
AV
387/* The size field is returned as an array index type. Therefore treat
388 it and only it specially. */
c49ea23d
PT
389
390tree
34d9d749 391gfc_class_vtab_size_get (tree cl)
c49ea23d 392{
34d9d749
AV
393 tree size;
394 size = class_vtab_field_get (cl, VTABLE_SIZE_FIELD);
395 /* Always return size as an array index type. */
396 size = fold_convert (gfc_array_index_type, size);
397 gcc_assert (size);
398 return size;
c49ea23d
PT
399}
400
86035eec 401tree
34d9d749 402gfc_vptr_size_get (tree vptr)
86035eec 403{
34d9d749
AV
404 tree size;
405 size = vptr_field_get (vptr, VTABLE_SIZE_FIELD);
406 /* Always return size as an array index type. */
407 size = fold_convert (gfc_array_index_type, size);
408 gcc_assert (size);
409 return size;
86035eec
TB
410}
411
412
c49ea23d
PT
413#undef CLASS_DATA_FIELD
414#undef CLASS_VPTR_FIELD
728557fd 415#undef CLASS_LEN_FIELD
c49ea23d
PT
416#undef VTABLE_HASH_FIELD
417#undef VTABLE_SIZE_FIELD
418#undef VTABLE_EXTENDS_FIELD
419#undef VTABLE_DEF_INIT_FIELD
420#undef VTABLE_COPY_FIELD
86035eec 421#undef VTABLE_FINAL_FIELD
c49ea23d
PT
422
423
9a0e09f3
PT
424/* IF ts is null (default), search for the last _class ref in the chain
425 of references of the expression and cut the chain there. Although
426 this routine is similiar to class.c:gfc_add_component_ref (), there
427 is a significant difference: gfc_add_component_ref () concentrates
428 on an array ref that is the last ref in the chain and is oblivious
429 to the kind of refs following.
430 ELSE IF ts is non-null the cut is at the class entity or component
431 that is followed by an array reference, which is not an element.
432 These calls come from trans-array.c:build_class_array_ref, which
433 handles scalarized class array references.*/
34d9d749
AV
434
435gfc_expr *
9a0e09f3
PT
436gfc_find_and_cut_at_last_class_ref (gfc_expr *e, bool is_mold,
437 gfc_typespec **ts)
34d9d749
AV
438{
439 gfc_expr *base_expr;
574284e9 440 gfc_ref *ref, *class_ref, *tail = NULL, *array_ref;
34d9d749
AV
441
442 /* Find the last class reference. */
443 class_ref = NULL;
6a4236ce 444 array_ref = NULL;
9a0e09f3
PT
445
446 if (ts)
34d9d749 447 {
9a0e09f3
PT
448 if (e->symtree
449 && e->symtree->n.sym->ts.type == BT_CLASS)
450 *ts = &e->symtree->n.sym->ts;
451 else
452 *ts = NULL;
453 }
6a4236ce 454
9a0e09f3
PT
455 for (ref = e->ref; ref; ref = ref->next)
456 {
457 if (ts)
6a4236ce 458 {
9a0e09f3
PT
459 if (ref->type == REF_COMPONENT
460 && ref->u.c.component->ts.type == BT_CLASS
461 && ref->next && ref->next->type == REF_COMPONENT
462 && !strcmp (ref->next->u.c.component->name, "_data")
463 && ref->next->next
464 && ref->next->next->type == REF_ARRAY
465 && ref->next->next->u.ar.type != AR_ELEMENT)
466 {
467 *ts = &ref->u.c.component->ts;
468 class_ref = ref;
469 break;
470 }
471
472 if (ref->next == NULL)
473 break;
6a4236ce 474 }
9a0e09f3
PT
475 else
476 {
477 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
478 array_ref = ref;
34d9d749 479
9a0e09f3
PT
480 if (ref->type == REF_COMPONENT
481 && ref->u.c.component->ts.type == BT_CLASS)
482 {
483 /* Component to the right of a part reference with nonzero
484 rank must not have the ALLOCATABLE attribute. If attempts
485 are made to reference such a component reference, an error
486 results followed by an ICE. */
487 if (array_ref
488 && CLASS_DATA (ref->u.c.component)->attr.allocatable)
489 return NULL;
490 class_ref = ref;
491 }
492 }
34d9d749
AV
493 }
494
9a0e09f3
PT
495 if (ts && *ts == NULL)
496 return NULL;
497
34d9d749
AV
498 /* Remove and store all subsequent references after the
499 CLASS reference. */
500 if (class_ref)
501 {
502 tail = class_ref->next;
503 class_ref->next = NULL;
504 }
574284e9 505 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
34d9d749
AV
506 {
507 tail = e->ref;
508 e->ref = NULL;
509 }
510
4afe8252
TK
511 if (is_mold)
512 base_expr = gfc_expr_to_initialize (e);
513 else
514 base_expr = gfc_copy_expr (e);
34d9d749
AV
515
516 /* Restore the original tail expression. */
517 if (class_ref)
518 {
519 gfc_free_ref_list (class_ref->next);
520 class_ref->next = tail;
521 }
574284e9 522 else if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
34d9d749
AV
523 {
524 gfc_free_ref_list (e->ref);
525 e->ref = tail;
526 }
527 return base_expr;
528}
529
530
4fb5478c
TB
531/* Reset the vptr to the declared type, e.g. after deallocation. */
532
533void
534gfc_reset_vptr (stmtblock_t *block, gfc_expr *e)
535{
4fb5478c 536 gfc_symbol *vtab;
6a4236ce
PT
537 tree vptr;
538 tree vtable;
539 gfc_se se;
540
541 /* Evaluate the expression and obtain the vptr from it. */
542 gfc_init_se (&se, NULL);
543 if (e->rank)
544 gfc_conv_expr_descriptor (&se, e);
4fb5478c 545 else
6a4236ce
PT
546 gfc_conv_expr (&se, e);
547 gfc_add_block_to_block (block, &se.pre);
548 vptr = gfc_get_vptr_from_expr (se.expr);
4fb5478c 549
6a4236ce
PT
550 /* If a vptr is not found, we can do nothing more. */
551 if (vptr == NULL_TREE)
552 return;
4fb5478c
TB
553
554 if (UNLIMITED_POLY (e))
6a4236ce 555 gfc_add_modify (block, vptr, build_int_cst (TREE_TYPE (vptr), 0));
4fb5478c
TB
556 else
557 {
6a4236ce 558 /* Return the vptr to the address of the declared type. */
4fb5478c 559 vtab = gfc_find_derived_vtab (e->ts.u.derived);
6a4236ce
PT
560 vtable = vtab->backend_decl;
561 if (vtable == NULL_TREE)
562 vtable = gfc_get_symbol_decl (vtab);
563 vtable = gfc_build_addr_expr (NULL, vtable);
564 vtable = fold_convert (TREE_TYPE (vptr), vtable);
565 gfc_add_modify (block, vptr, vtable);
4fb5478c 566 }
4fb5478c
TB
567}
568
569
34d9d749
AV
570/* Reset the len for unlimited polymorphic objects. */
571
572void
573gfc_reset_len (stmtblock_t *block, gfc_expr *expr)
574{
575 gfc_expr *e;
576 gfc_se se_len;
577 e = gfc_find_and_cut_at_last_class_ref (expr);
6a4236ce
PT
578 if (e == NULL)
579 return;
34d9d749
AV
580 gfc_add_len_component (e);
581 gfc_init_se (&se_len, NULL);
582 gfc_conv_expr (&se_len, e);
583 gfc_add_modify (block, se_len.expr,
584 fold_convert (TREE_TYPE (se_len.expr), integer_zero_node));
585 gfc_free_expr (e);
586}
587
588
0175d45d
PT
589/* Obtain the last class reference in a gfc_expr. Return NULL_TREE if no class
590 reference is found. Note that it is up to the caller to avoid using this
591 for expressions other than variables. */
592
593tree
594gfc_get_class_from_gfc_expr (gfc_expr *e)
595{
596 gfc_expr *class_expr;
597 gfc_se cse;
598 class_expr = gfc_find_and_cut_at_last_class_ref (e);
599 if (class_expr == NULL)
600 return NULL_TREE;
601 gfc_init_se (&cse, NULL);
602 gfc_conv_expr (&cse, class_expr);
603 gfc_free_expr (class_expr);
604 return cse.expr;
605}
606
607
56b070e3 608/* Obtain the last class reference in an expression.
f04986a9 609 Return NULL_TREE if no class reference is found. */
8f75db9f
PT
610
611tree
56b070e3 612gfc_get_class_from_expr (tree expr)
8f75db9f 613{
f04986a9
PT
614 tree tmp;
615 tree type;
616
617 for (tmp = expr; tmp; tmp = TREE_OPERAND (tmp, 0))
618 {
ce8dcc91
PT
619 if (CONSTANT_CLASS_P (tmp))
620 return NULL_TREE;
621
f04986a9
PT
622 type = TREE_TYPE (tmp);
623 while (type)
624 {
625 if (GFC_CLASS_TYPE_P (type))
56b070e3 626 return tmp;
f04986a9
PT
627 if (type != TYPE_CANONICAL (type))
628 type = TYPE_CANONICAL (type);
629 else
630 type = NULL_TREE;
631 }
d168c883 632 if (VAR_P (tmp) || TREE_CODE (tmp) == PARM_DECL)
f04986a9
PT
633 break;
634 }
e73d3ca6
PT
635
636 if (POINTER_TYPE_P (TREE_TYPE (tmp)))
637 tmp = build_fold_indirect_ref_loc (input_location, tmp);
638
639 if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
56b070e3
PT
640 return tmp;
641
642 return NULL_TREE;
643}
644
645
646/* Obtain the vptr of the last class reference in an expression.
647 Return NULL_TREE if no class reference is found. */
648
649tree
650gfc_get_vptr_from_expr (tree expr)
651{
652 tree tmp;
653
654 tmp = gfc_get_class_from_expr (expr);
655
656 if (tmp != NULL_TREE)
e73d3ca6
PT
657 return gfc_class_vptr_get (tmp);
658
f04986a9 659 return NULL_TREE;
8f75db9f 660}
c62c6622
TB
661
662
663static void
664class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
665 bool lhs_type)
666{
667 tree tmp, tmp2, type;
668
669 gfc_conv_descriptor_data_set (block, lhs_desc,
670 gfc_conv_descriptor_data_get (rhs_desc));
671 gfc_conv_descriptor_offset_set (block, lhs_desc,
672 gfc_conv_descriptor_offset_get (rhs_desc));
673
674 gfc_add_modify (block, gfc_conv_descriptor_dtype (lhs_desc),
675 gfc_conv_descriptor_dtype (rhs_desc));
676
677 /* Assign the dimension as range-ref. */
678 tmp = gfc_get_descriptor_dimension (lhs_desc);
679 tmp2 = gfc_get_descriptor_dimension (rhs_desc);
680
681 type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
682 tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
683 gfc_index_zero_node, NULL_TREE, NULL_TREE);
684 tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
685 gfc_index_zero_node, NULL_TREE, NULL_TREE);
686 gfc_add_modify (block, tmp, tmp2);
687}
688
8f75db9f 689
c49ea23d 690/* Takes a derived type expression and returns the address of a temporary
8f75db9f 691 class object of the 'declared' type. If vptr is not NULL, this is
16e82b25
TB
692 used for the temporary class object.
693 optional_alloc_ptr is false when the dummy is neither allocatable
5159b88e
PT
694 nor a pointer; that's only relevant for the optional handling.
695 The optional argument 'derived_array' is used to preserve the parmse
696 expression for deallocation of allocatable components. Assumed rank
697 formal arguments made this necessary. */
8f75db9f 698void
c49ea23d 699gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
16e82b25 700 gfc_typespec class_ts, tree vptr, bool optional,
5159b88e
PT
701 bool optional_alloc_ptr,
702 tree *derived_array)
c49ea23d
PT
703{
704 gfc_symbol *vtab;
16e82b25 705 tree cond_optional = NULL_TREE;
c49ea23d
PT
706 gfc_ss *ss;
707 tree ctree;
708 tree var;
709 tree tmp;
e519d2e8 710 int dim;
c49ea23d
PT
711
712 /* The derived type needs to be converted to a temporary
713 CLASS object. */
714 tmp = gfc_typenode_for_spec (&class_ts);
715 var = gfc_create_var (tmp, "class");
716
717 /* Set the vptr. */
718 ctree = gfc_class_vptr_get (var);
719
8f75db9f
PT
720 if (vptr != NULL_TREE)
721 {
722 /* Use the dynamic vptr. */
723 tmp = vptr;
724 }
725 else
726 {
727 /* In this case the vtab corresponds to the derived type and the
728 vptr must point to it. */
729 vtab = gfc_find_derived_vtab (e->ts.u.derived);
730 gcc_assert (vtab);
731 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
732 }
c49ea23d
PT
733 gfc_add_modify (&parmse->pre, ctree,
734 fold_convert (TREE_TYPE (ctree), tmp));
735
736 /* Now set the data field. */
737 ctree = gfc_class_data_get (var);
738
16e82b25
TB
739 if (optional)
740 cond_optional = gfc_conv_expr_present (e->symtree->n.sym);
741
e73d3ca6
PT
742 if (parmse->expr && POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
743 {
744 /* If there is a ready made pointer to a derived type, use it
745 rather than evaluating the expression again. */
746 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
747 gfc_add_modify (&parmse->pre, ctree, tmp);
748 }
749 else if (parmse->ss && parmse->ss->info && parmse->ss->info->useflags)
c49ea23d
PT
750 {
751 /* For an array reference in an elemental procedure call we need
752 to retain the ss to provide the scalarized array reference. */
753 gfc_conv_expr_reference (parmse, e);
754 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
16e82b25
TB
755 if (optional)
756 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
757 cond_optional, tmp,
758 fold_convert (TREE_TYPE (tmp), null_pointer_node));
c49ea23d
PT
759 gfc_add_modify (&parmse->pre, ctree, tmp);
760 }
761 else
762 {
763 ss = gfc_walk_expr (e);
764 if (ss == gfc_ss_terminator)
765 {
766 parmse->ss = NULL;
767 gfc_conv_expr_reference (parmse, e);
c62c6622
TB
768
769 /* Scalar to an assumed-rank array. */
770 if (class_ts.u.derived->components->as)
771 {
772 tree type;
773 type = get_scalar_to_descriptor_type (parmse->expr,
774 gfc_expr_attr (e));
775 gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
776 gfc_get_dtype (type));
16e82b25
TB
777 if (optional)
778 parmse->expr = build3_loc (input_location, COND_EXPR,
779 TREE_TYPE (parmse->expr),
780 cond_optional, parmse->expr,
781 fold_convert (TREE_TYPE (parmse->expr),
782 null_pointer_node));
c62c6622
TB
783 gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
784 }
785 else
786 {
787 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
16e82b25
TB
788 if (optional)
789 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
790 cond_optional, tmp,
791 fold_convert (TREE_TYPE (tmp),
792 null_pointer_node));
c62c6622
TB
793 gfc_add_modify (&parmse->pre, ctree, tmp);
794 }
c49ea23d
PT
795 }
796 else
797 {
16e82b25
TB
798 stmtblock_t block;
799 gfc_init_block (&block);
e519d2e8 800 gfc_ref *ref;
16e82b25 801
c49ea23d 802 parmse->ss = ss;
e519d2e8 803 parmse->use_offset = 1;
2960a368 804 gfc_conv_expr_descriptor (parmse, e);
c62c6622 805
e519d2e8
PT
806 /* Detect any array references with vector subscripts. */
807 for (ref = e->ref; ref; ref = ref->next)
808 if (ref->type == REF_ARRAY
809 && ref->u.ar.type != AR_ELEMENT
810 && ref->u.ar.type != AR_FULL)
811 {
812 for (dim = 0; dim < ref->u.ar.dimen; dim++)
813 if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
814 break;
815 if (dim < ref->u.ar.dimen)
816 break;
817 }
818
819 /* Array references with vector subscripts and non-variable expressions
a8399af8 820 need be converted to a one-based descriptor. */
e519d2e8
PT
821 if (ref || e->expr_type != EXPR_VARIABLE)
822 {
823 for (dim = 0; dim < e->rank; ++dim)
824 gfc_conv_shift_descriptor_lbound (&block, parmse->expr, dim,
825 gfc_index_one_node);
826 }
827
c62c6622 828 if (e->rank != class_ts.u.derived->components->as->rank)
61b6bed7
MM
829 {
830 gcc_assert (class_ts.u.derived->components->as->type
831 == AS_ASSUMED_RANK);
5159b88e
PT
832 if (derived_array
833 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse->expr)))
834 {
835 *derived_array = gfc_create_var (TREE_TYPE (parmse->expr),
836 "array");
837 gfc_add_modify (&block, *derived_array , parmse->expr);
838 }
61b6bed7
MM
839 class_array_data_assign (&block, ctree, parmse->expr, false);
840 }
c62c6622 841 else
16e82b25
TB
842 {
843 if (gfc_expr_attr (e).codimension)
844 parmse->expr = fold_build1_loc (input_location,
845 VIEW_CONVERT_EXPR,
846 TREE_TYPE (ctree),
847 parmse->expr);
848 gfc_add_modify (&block, ctree, parmse->expr);
849 }
850
851 if (optional)
852 {
853 tmp = gfc_finish_block (&block);
854
855 gfc_init_block (&block);
856 gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
5159b88e
PT
857 if (derived_array && *derived_array != NULL_TREE)
858 gfc_conv_descriptor_data_set (&block, *derived_array,
859 null_pointer_node);
16e82b25
TB
860
861 tmp = build3_v (COND_EXPR, cond_optional, tmp,
862 gfc_finish_block (&block));
863 gfc_add_expr_to_block (&parmse->pre, tmp);
864 }
865 else
866 gfc_add_block_to_block (&parmse->pre, &block);
c49ea23d
PT
867 }
868 }
869
a2581005
AV
870 if (class_ts.u.derived->components->ts.type == BT_DERIVED
871 && class_ts.u.derived->components->ts.u.derived
872 ->attr.unlimited_polymorphic)
873 {
874 /* Take care about initializing the _len component correctly. */
875 ctree = gfc_class_len_get (var);
876 if (UNLIMITED_POLY (e))
877 {
878 gfc_expr *len;
879 gfc_se se;
880
fcc4891d 881 len = gfc_find_and_cut_at_last_class_ref (e);
a2581005
AV
882 gfc_add_len_component (len);
883 gfc_init_se (&se, NULL);
884 gfc_conv_expr (&se, len);
885 if (optional)
886 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se.expr),
887 cond_optional, se.expr,
888 fold_convert (TREE_TYPE (se.expr),
889 integer_zero_node));
890 else
891 tmp = se.expr;
fcc4891d 892 gfc_free_expr (len);
a2581005
AV
893 }
894 else
895 tmp = integer_zero_node;
896 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree),
897 tmp));
898 }
c49ea23d
PT
899 /* Pass the address of the class object. */
900 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
16e82b25
TB
901
902 if (optional && optional_alloc_ptr)
903 parmse->expr = build3_loc (input_location, COND_EXPR,
904 TREE_TYPE (parmse->expr),
905 cond_optional, parmse->expr,
906 fold_convert (TREE_TYPE (parmse->expr),
907 null_pointer_node));
908}
909
910
911/* Create a new class container, which is required as scalar coarrays
912 have an array descriptor while normal scalars haven't. Optionally,
913 NULL pointer checks are added if the argument is OPTIONAL. */
914
915static void
916class_scalar_coarray_to_class (gfc_se *parmse, gfc_expr *e,
917 gfc_typespec class_ts, bool optional)
918{
919 tree var, ctree, tmp;
920 stmtblock_t block;
921 gfc_ref *ref;
922 gfc_ref *class_ref;
923
924 gfc_init_block (&block);
925
926 class_ref = NULL;
927 for (ref = e->ref; ref; ref = ref->next)
928 {
929 if (ref->type == REF_COMPONENT
930 && ref->u.c.component->ts.type == BT_CLASS)
931 class_ref = ref;
932 }
933
934 if (class_ref == NULL
935 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
936 tmp = e->symtree->n.sym->backend_decl;
937 else
938 {
939 /* Remove everything after the last class reference, convert the
940 expression and then recover its tailend once more. */
941 gfc_se tmpse;
942 ref = class_ref->next;
943 class_ref->next = NULL;
944 gfc_init_se (&tmpse, NULL);
945 gfc_conv_expr (&tmpse, e);
946 class_ref->next = ref;
947 tmp = tmpse.expr;
948 }
949
950 var = gfc_typenode_for_spec (&class_ts);
951 var = gfc_create_var (var, "class");
952
953 ctree = gfc_class_vptr_get (var);
954 gfc_add_modify (&block, ctree,
955 fold_convert (TREE_TYPE (ctree), gfc_class_vptr_get (tmp)));
956
957 ctree = gfc_class_data_get (var);
958 tmp = gfc_conv_descriptor_data_get (gfc_class_data_get (tmp));
959 gfc_add_modify (&block, ctree, fold_convert (TREE_TYPE (ctree), tmp));
960
961 /* Pass the address of the class object. */
962 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
963
964 if (optional)
965 {
966 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
967 tree tmp2;
968
969 tmp = gfc_finish_block (&block);
970
971 gfc_init_block (&block);
972 tmp2 = gfc_class_data_get (var);
973 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
974 null_pointer_node));
975 tmp2 = gfc_finish_block (&block);
976
977 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
978 cond, tmp, tmp2);
979 gfc_add_expr_to_block (&parmse->pre, tmp);
980 }
981 else
982 gfc_add_block_to_block (&parmse->pre, &block);
c49ea23d
PT
983}
984
985
8b704316
PT
986/* Takes an intrinsic type expression and returns the address of a temporary
987 class object of the 'declared' type. */
988void
989gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
990 gfc_typespec class_ts)
991{
992 gfc_symbol *vtab;
993 gfc_ss *ss;
994 tree ctree;
995 tree var;
996 tree tmp;
7485ace8 997 int dim;
8b704316
PT
998
999 /* The intrinsic type needs to be converted to a temporary
1000 CLASS object. */
1001 tmp = gfc_typenode_for_spec (&class_ts);
1002 var = gfc_create_var (tmp, "class");
1003
1004 /* Set the vptr. */
69c3654c 1005 ctree = gfc_class_vptr_get (var);
8b704316 1006
7289d1c9 1007 vtab = gfc_find_vtab (&e->ts);
8b704316
PT
1008 gcc_assert (vtab);
1009 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
1010 gfc_add_modify (&parmse->pre, ctree,
1011 fold_convert (TREE_TYPE (ctree), tmp));
1012
1013 /* Now set the data field. */
69c3654c 1014 ctree = gfc_class_data_get (var);
8b704316
PT
1015 if (parmse->ss && parmse->ss->info->useflags)
1016 {
1017 /* For an array reference in an elemental procedure call we need
1018 to retain the ss to provide the scalarized array reference. */
1019 gfc_conv_expr_reference (parmse, e);
1020 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
1021 gfc_add_modify (&parmse->pre, ctree, tmp);
1022 }
1023 else
1024 {
1025 ss = gfc_walk_expr (e);
1026 if (ss == gfc_ss_terminator)
1027 {
1028 parmse->ss = NULL;
1029 gfc_conv_expr_reference (parmse, e);
69c3654c
TB
1030 if (class_ts.u.derived->components->as
1031 && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK)
1032 {
1033 tmp = gfc_conv_scalar_to_descriptor (parmse, parmse->expr,
1034 gfc_expr_attr (e));
1035 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1036 TREE_TYPE (ctree), tmp);
1037 }
1038 else
1039 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
8b704316
PT
1040 gfc_add_modify (&parmse->pre, ctree, tmp);
1041 }
1042 else
1043 {
1044 parmse->ss = ss;
1cf43a1d 1045 parmse->use_offset = 1;
8b704316 1046 gfc_conv_expr_descriptor (parmse, e);
7485ace8
PT
1047
1048 /* Array references with vector subscripts and non-variable expressions
1049 need be converted to a one-based descriptor. */
1050 if (e->expr_type != EXPR_VARIABLE)
1051 {
1052 for (dim = 0; dim < e->rank; ++dim)
1053 gfc_conv_shift_descriptor_lbound (&parmse->pre, parmse->expr,
1054 dim, gfc_index_one_node);
1055 }
1056
69c3654c
TB
1057 if (class_ts.u.derived->components->as->rank != e->rank)
1058 {
1059 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1060 TREE_TYPE (ctree), parmse->expr);
1061 gfc_add_modify (&parmse->pre, ctree, tmp);
1062 }
1063 else
1064 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
8b704316
PT
1065 }
1066 }
1067
a2581005
AV
1068 gcc_assert (class_ts.type == BT_CLASS);
1069 if (class_ts.u.derived->components->ts.type == BT_DERIVED
1070 && class_ts.u.derived->components->ts.u.derived
1071 ->attr.unlimited_polymorphic)
5b384b3d
PT
1072 {
1073 ctree = gfc_class_len_get (var);
a2581005 1074 /* When the actual arg is a char array, then set the _len component of the
cef026ec 1075 unlimited polymorphic entity to the length of the string. */
a2581005
AV
1076 if (e->ts.type == BT_CHARACTER)
1077 {
1078 /* Start with parmse->string_length because this seems to be set to a
1079 correct value more often. */
1080 if (parmse->string_length)
1081 tmp = parmse->string_length;
1082 /* When the string_length is not yet set, then try the backend_decl of
1083 the cl. */
1084 else if (e->ts.u.cl->backend_decl)
1085 tmp = e->ts.u.cl->backend_decl;
1086 /* If both of the above approaches fail, then try to generate an
1087 expression from the input, which is only feasible currently, when the
1088 expression can be evaluated to a constant one. */
56d1b78a
AV
1089 else
1090 {
a2581005
AV
1091 /* Try to simplify the expression. */
1092 gfc_simplify_expr (e, 0);
1093 if (e->expr_type == EXPR_CONSTANT && !e->ts.u.cl->resolved)
1094 {
1095 /* Amazingly all data is present to compute the length of a
1096 constant string, but the expression is not yet there. */
f622221a
JB
1097 e->ts.u.cl->length = gfc_get_constant_expr (BT_INTEGER,
1098 gfc_charlen_int_kind,
a2581005
AV
1099 &e->where);
1100 mpz_set_ui (e->ts.u.cl->length->value.integer,
1101 e->value.character.length);
1102 gfc_conv_const_charlen (e->ts.u.cl);
1103 e->ts.u.cl->resolved = 1;
1104 tmp = e->ts.u.cl->backend_decl;
1105 }
1106 else
1107 {
1fe61adf
ML
1108 gfc_error ("Cannot compute the length of the char array "
1109 "at %L.", &e->where);
a2581005 1110 }
56d1b78a
AV
1111 }
1112 }
a2581005
AV
1113 else
1114 tmp = integer_zero_node;
1115
f622221a 1116 gfc_add_modify (&parmse->pre, ctree, fold_convert (TREE_TYPE (ctree), tmp));
5b384b3d 1117 }
f3b0bb7a
AV
1118 else if (class_ts.type == BT_CLASS
1119 && class_ts.u.derived->components
1120 && class_ts.u.derived->components->ts.u
1121 .derived->attr.unlimited_polymorphic)
1122 {
1123 ctree = gfc_class_len_get (var);
1124 gfc_add_modify (&parmse->pre, ctree,
1125 fold_convert (TREE_TYPE (ctree),
1126 integer_zero_node));
1127 }
8b704316
PT
1128 /* Pass the address of the class object. */
1129 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
1130}
1131
1132
c49ea23d
PT
1133/* Takes a scalarized class array expression and returns the
1134 address of a temporary scalar class object of the 'declared'
8b704316 1135 type.
c49ea23d
PT
1136 OOP-TODO: This could be improved by adding code that branched on
1137 the dynamic type being the same as the declared type. In this case
16e82b25
TB
1138 the original class expression can be passed directly.
1139 optional_alloc_ptr is false when the dummy is neither allocatable
1140 nor a pointer; that's relevant for the optional handling.
1141 Set copyback to true if class container's _data and _vtab pointers
1142 might get modified. */
1143
4daa71b0 1144void
16e82b25
TB
1145gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
1146 bool elemental, bool copyback, bool optional,
1147 bool optional_alloc_ptr)
c49ea23d
PT
1148{
1149 tree ctree;
1150 tree var;
1151 tree tmp;
1152 tree vptr;
16e82b25 1153 tree cond = NULL_TREE;
f3b0bb7a 1154 tree slen = NULL_TREE;
c49ea23d
PT
1155 gfc_ref *ref;
1156 gfc_ref *class_ref;
16e82b25 1157 stmtblock_t block;
c49ea23d
PT
1158 bool full_array = false;
1159
16e82b25
TB
1160 gfc_init_block (&block);
1161
c49ea23d
PT
1162 class_ref = NULL;
1163 for (ref = e->ref; ref; ref = ref->next)
1164 {
1165 if (ref->type == REF_COMPONENT
1166 && ref->u.c.component->ts.type == BT_CLASS)
1167 class_ref = ref;
1168
1169 if (ref->next == NULL)
1170 break;
1171 }
1172
c62c6622 1173 if ((ref == NULL || class_ref == ref)
a6b22eea 1174 && !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE)
c62c6622
TB
1175 && (!class_ts.u.derived->components->as
1176 || class_ts.u.derived->components->as->rank != -1))
c49ea23d
PT
1177 return;
1178
1179 /* Test for FULL_ARRAY. */
16e82b25
TB
1180 if (e->rank == 0 && gfc_expr_attr (e).codimension
1181 && gfc_expr_attr (e).dimension)
1182 full_array = true;
1183 else
1184 gfc_is_class_array_ref (e, &full_array);
c49ea23d
PT
1185
1186 /* The derived type needs to be converted to a temporary
1187 CLASS object. */
1188 tmp = gfc_typenode_for_spec (&class_ts);
1189 var = gfc_create_var (tmp, "class");
1190
1191 /* Set the data. */
1192 ctree = gfc_class_data_get (var);
c62c6622
TB
1193 if (class_ts.u.derived->components->as
1194 && e->rank != class_ts.u.derived->components->as->rank)
1195 {
1196 if (e->rank == 0)
1197 {
1198 tree type = get_scalar_to_descriptor_type (parmse->expr,
1199 gfc_expr_attr (e));
16e82b25 1200 gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
c62c6622 1201 gfc_get_dtype (type));
c62c6622 1202
16e82b25
TB
1203 tmp = gfc_class_data_get (parmse->expr);
1204 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1205 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1206
1207 gfc_conv_descriptor_data_set (&block, ctree, tmp);
c62c6622
TB
1208 }
1209 else
16e82b25 1210 class_array_data_assign (&block, ctree, parmse->expr, false);
c62c6622
TB
1211 }
1212 else
16e82b25 1213 {
f04986a9 1214 if (TREE_TYPE (parmse->expr) != TREE_TYPE (ctree))
16e82b25
TB
1215 parmse->expr = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1216 TREE_TYPE (ctree), parmse->expr);
1217 gfc_add_modify (&block, ctree, parmse->expr);
1218 }
c49ea23d
PT
1219
1220 /* Return the data component, except in the case of scalarized array
1221 references, where nullification of the cannot occur and so there
1222 is no need. */
16e82b25 1223 if (!elemental && full_array && copyback)
c62c6622
TB
1224 {
1225 if (class_ts.u.derived->components->as
1226 && e->rank != class_ts.u.derived->components->as->rank)
1227 {
1228 if (e->rank == 0)
1229 gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr),
1230 gfc_conv_descriptor_data_get (ctree));
1231 else
1232 class_array_data_assign (&parmse->post, parmse->expr, ctree, true);
1233 }
1234 else
1235 gfc_add_modify (&parmse->post, parmse->expr, ctree);
1236 }
c49ea23d
PT
1237
1238 /* Set the vptr. */
1239 ctree = gfc_class_vptr_get (var);
1240
1241 /* The vptr is the second field of the actual argument.
1cc0e193 1242 First we have to find the corresponding class reference. */
c49ea23d
PT
1243
1244 tmp = NULL_TREE;
a6b22eea
PT
1245 if (gfc_is_class_array_function (e)
1246 && parmse->class_vptr != NULL_TREE)
1247 tmp = parmse->class_vptr;
1248 else if (class_ref == NULL
1249 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
f3b0bb7a
AV
1250 {
1251 tmp = e->symtree->n.sym->backend_decl;
de514d40
PT
1252
1253 if (TREE_CODE (tmp) == FUNCTION_DECL)
1254 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
1255
f3b0bb7a
AV
1256 if (DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp))
1257 tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);
de514d40 1258
f622221a 1259 slen = build_zero_cst (size_type_node);
f3b0bb7a 1260 }
c49ea23d
PT
1261 else
1262 {
1263 /* Remove everything after the last class reference, convert the
1264 expression and then recover its tailend once more. */
1265 gfc_se tmpse;
1266 ref = class_ref->next;
1267 class_ref->next = NULL;
1268 gfc_init_se (&tmpse, NULL);
1269 gfc_conv_expr (&tmpse, e);
1270 class_ref->next = ref;
1271 tmp = tmpse.expr;
f3b0bb7a 1272 slen = tmpse.string_length;
c49ea23d
PT
1273 }
1274
1275 gcc_assert (tmp != NULL_TREE);
1276
1277 /* Dereference if needs be. */
1278 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
1279 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1280
a6b22eea
PT
1281 if (!(gfc_is_class_array_function (e) && parmse->class_vptr))
1282 vptr = gfc_class_vptr_get (tmp);
1283 else
1284 vptr = tmp;
1285
16e82b25 1286 gfc_add_modify (&block, ctree,
c49ea23d
PT
1287 fold_convert (TREE_TYPE (ctree), vptr));
1288
1289 /* Return the vptr component, except in the case of scalarized array
1290 references, where the dynamic type cannot change. */
16e82b25 1291 if (!elemental && full_array && copyback)
c49ea23d
PT
1292 gfc_add_modify (&parmse->post, vptr,
1293 fold_convert (TREE_TYPE (vptr), ctree));
1294
f3b0bb7a
AV
1295 /* For unlimited polymorphic objects also set the _len component. */
1296 if (class_ts.type == BT_CLASS
1297 && class_ts.u.derived->components
1298 && class_ts.u.derived->components->ts.u
1299 .derived->attr.unlimited_polymorphic)
1300 {
1301 ctree = gfc_class_len_get (var);
1302 if (UNLIMITED_POLY (e))
1303 tmp = gfc_class_len_get (tmp);
1304 else if (e->ts.type == BT_CHARACTER)
1305 {
1306 gcc_assert (slen != NULL_TREE);
1307 tmp = slen;
1308 }
1309 else
f622221a 1310 tmp = build_zero_cst (size_type_node);
f3b0bb7a
AV
1311 gfc_add_modify (&parmse->pre, ctree,
1312 fold_convert (TREE_TYPE (ctree), tmp));
d233ee5f
PT
1313
1314 /* Return the len component, except in the case of scalarized array
1315 references, where the dynamic type cannot change. */
e60f68ec
PT
1316 if (!elemental && full_array && copyback
1317 && (UNLIMITED_POLY (e) || VAR_P (tmp)))
d233ee5f
PT
1318 gfc_add_modify (&parmse->post, tmp,
1319 fold_convert (TREE_TYPE (tmp), ctree));
f3b0bb7a
AV
1320 }
1321
16e82b25
TB
1322 if (optional)
1323 {
1324 tree tmp2;
1325
1326 cond = gfc_conv_expr_present (e->symtree->n.sym);
f3b0bb7a
AV
1327 /* parmse->pre may contain some preparatory instructions for the
1328 temporary array descriptor. Those may only be executed when the
1329 optional argument is set, therefore add parmse->pre's instructions
1330 to block, which is later guarded by an if (optional_arg_given). */
1331 gfc_add_block_to_block (&parmse->pre, &block);
1332 block.head = parmse->pre.head;
1333 parmse->pre.head = NULL_TREE;
16e82b25
TB
1334 tmp = gfc_finish_block (&block);
1335
1336 if (optional_alloc_ptr)
1337 tmp2 = build_empty_stmt (input_location);
1338 else
1339 {
1340 gfc_init_block (&block);
1341
1342 tmp2 = gfc_conv_descriptor_data_get (gfc_class_data_get (var));
1343 gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2),
1344 null_pointer_node));
1345 tmp2 = gfc_finish_block (&block);
1346 }
1347
1348 tmp = build3_loc (input_location, COND_EXPR, void_type_node,
1349 cond, tmp, tmp2);
1350 gfc_add_expr_to_block (&parmse->pre, tmp);
1351 }
1352 else
1353 gfc_add_block_to_block (&parmse->pre, &block);
1354
c49ea23d
PT
1355 /* Pass the address of the class object. */
1356 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
16e82b25
TB
1357
1358 if (optional && optional_alloc_ptr)
1359 parmse->expr = build3_loc (input_location, COND_EXPR,
1360 TREE_TYPE (parmse->expr),
1361 cond, parmse->expr,
1362 fold_convert (TREE_TYPE (parmse->expr),
1363 null_pointer_node));
c49ea23d
PT
1364}
1365
94fae14b 1366
4daa71b0
PT
1367/* Given a class array declaration and an index, returns the address
1368 of the referenced element. */
1369
1370tree
26219cee
PT
1371gfc_get_class_array_ref (tree index, tree class_decl, tree data_comp,
1372 bool unlimited)
4daa71b0 1373{
26219cee
PT
1374 tree data, size, tmp, ctmp, offset, ptr;
1375
1376 data = data_comp != NULL_TREE ? data_comp :
1377 gfc_class_data_get (class_decl);
1378 size = gfc_class_vtab_size_get (class_decl);
1379
1380 if (unlimited)
1381 {
1382 tmp = fold_convert (gfc_array_index_type,
1383 gfc_class_len_get (class_decl));
1384 ctmp = fold_build2_loc (input_location, MULT_EXPR,
1385 gfc_array_index_type, size, tmp);
1386 tmp = fold_build2_loc (input_location, GT_EXPR,
1387 logical_type_node, tmp,
1388 build_zero_cst (TREE_TYPE (tmp)));
1389 size = fold_build3_loc (input_location, COND_EXPR,
1390 gfc_array_index_type, tmp, ctmp, size);
1391 }
1392
1393 offset = fold_build2_loc (input_location, MULT_EXPR,
1394 gfc_array_index_type,
1395 index, size);
1396
4daa71b0
PT
1397 data = gfc_conv_descriptor_data_get (data);
1398 ptr = fold_convert (pvoid_type_node, data);
1399 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
1400 return fold_convert (TREE_TYPE (data), ptr);
1401}
1402
1403
1404/* Copies one class expression to another, assuming that if either
1405 'to' or 'from' are arrays they are packed. Should 'from' be
62732c30 1406 NULL_TREE, the initialization expression for 'to' is used, assuming
4daa71b0
PT
1407 that the _vptr is set. */
1408
1409tree
34d9d749 1410gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited)
4daa71b0
PT
1411{
1412 tree fcn;
1413 tree fcn_type;
1414 tree from_data;
34d9d749 1415 tree from_len;
4daa71b0 1416 tree to_data;
34d9d749 1417 tree to_len;
4daa71b0
PT
1418 tree to_ref;
1419 tree from_ref;
9771b263 1420 vec<tree, va_gc> *args;
4daa71b0 1421 tree tmp;
34d9d749
AV
1422 tree stdcopy;
1423 tree extcopy;
4daa71b0 1424 tree index;
b8ac4f3b 1425 bool is_from_desc = false, is_to_class = false;
4daa71b0
PT
1426
1427 args = NULL;
34d9d749
AV
1428 /* To prevent warnings on uninitialized variables. */
1429 from_len = to_len = NULL_TREE;
4daa71b0
PT
1430
1431 if (from != NULL_TREE)
34d9d749 1432 fcn = gfc_class_vtab_copy_get (from);
4daa71b0 1433 else
34d9d749 1434 fcn = gfc_class_vtab_copy_get (to);
4daa71b0
PT
1435
1436 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
1437
1438 if (from != NULL_TREE)
b8ac4f3b
AV
1439 {
1440 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from));
1441 if (is_from_desc)
1442 {
1443 from_data = from;
1444 from = GFC_DECL_SAVED_DESCRIPTOR (from);
1445 }
1446 else
1447 {
781d83d9
AV
1448 /* Check that from is a class. When the class is part of a coarray,
1449 then from is a common pointer and is to be used as is. */
1450 tmp = POINTER_TYPE_P (TREE_TYPE (from))
1451 ? build_fold_indirect_ref (from) : from;
1452 from_data =
1453 (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
1454 || (DECL_P (tmp) && GFC_DECL_CLASS (tmp)))
1455 ? gfc_class_data_get (from) : from;
b8ac4f3b
AV
1456 is_from_desc = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data));
1457 }
1458 }
4daa71b0 1459 else
34d9d749
AV
1460 from_data = gfc_class_vtab_def_init_get (to);
1461
1462 if (unlimited)
1463 {
1464 if (from != NULL_TREE && unlimited)
728557fd 1465 from_len = gfc_class_len_or_zero_get (from);
34d9d749 1466 else
f622221a 1467 from_len = build_zero_cst (size_type_node);
34d9d749 1468 }
4daa71b0 1469
b8ac4f3b
AV
1470 if (GFC_CLASS_TYPE_P (TREE_TYPE (to)))
1471 {
1472 is_to_class = true;
1473 to_data = gfc_class_data_get (to);
1474 if (unlimited)
1475 to_len = gfc_class_len_get (to);
1476 }
1477 else
1478 /* When to is a BT_DERIVED and not a BT_CLASS, then to_data == to. */
1479 to_data = to;
4daa71b0
PT
1480
1481 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
1482 {
34d9d749
AV
1483 stmtblock_t loopbody;
1484 stmtblock_t body;
1485 stmtblock_t ifbody;
1486 gfc_loopinfo loop;
92c5266b 1487 tree orig_nelems = nelems; /* Needed for bounds check. */
34d9d749 1488
4daa71b0
PT
1489 gfc_init_block (&body);
1490 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1491 gfc_array_index_type, nelems,
1492 gfc_index_one_node);
1493 nelems = gfc_evaluate_now (tmp, &body);
1494 index = gfc_create_var (gfc_array_index_type, "S");
1495
b8ac4f3b 1496 if (is_from_desc)
4daa71b0 1497 {
26219cee
PT
1498 from_ref = gfc_get_class_array_ref (index, from, from_data,
1499 unlimited);
9771b263 1500 vec_safe_push (args, from_ref);
4daa71b0
PT
1501 }
1502 else
9771b263 1503 vec_safe_push (args, from_data);
4daa71b0 1504
b8ac4f3b 1505 if (is_to_class)
26219cee 1506 to_ref = gfc_get_class_array_ref (index, to, to_data, unlimited);
b8ac4f3b
AV
1507 else
1508 {
1509 tmp = gfc_conv_array_data (to);
1510 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1511 to_ref = gfc_build_addr_expr (NULL_TREE,
1512 gfc_build_array_ref (tmp, index, to));
1513 }
9771b263 1514 vec_safe_push (args, to_ref);
4daa71b0 1515
92c5266b
AV
1516 /* Add bounds check. */
1517 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) > 0 && is_from_desc)
1518 {
1519 char *msg;
1520 const char *name = "<<unknown>>";
1521 tree from_len;
1522
1523 if (DECL_P (to))
1524 name = (const char *)(DECL_NAME (to)->identifier.id.str);
1525
1526 from_len = gfc_conv_descriptor_size (from_data, 1);
1527 tmp = fold_build2_loc (input_location, NE_EXPR,
63ee5404 1528 logical_type_node, from_len, orig_nelems);
92c5266b
AV
1529 msg = xasprintf ("Array bound mismatch for dimension %d "
1530 "of array '%s' (%%ld/%%ld)",
1531 1, name);
1532
1533 gfc_trans_runtime_check (true, false, tmp, &body,
1534 &gfc_current_locus, msg,
1535 fold_convert (long_integer_type_node, orig_nelems),
1536 fold_convert (long_integer_type_node, from_len));
1537
1538 free (msg);
1539 }
1540
4daa71b0
PT
1541 tmp = build_call_vec (fcn_type, fcn, args);
1542
1543 /* Build the body of the loop. */
1544 gfc_init_block (&loopbody);
1545 gfc_add_expr_to_block (&loopbody, tmp);
1546
1547 /* Build the loop and return. */
1548 gfc_init_loopinfo (&loop);
1549 loop.dimen = 1;
1550 loop.from[0] = gfc_index_zero_node;
1551 loop.loopvar[0] = index;
1552 loop.to[0] = nelems;
1553 gfc_trans_scalarizing_loops (&loop, &loopbody);
34d9d749
AV
1554 gfc_init_block (&ifbody);
1555 gfc_add_block_to_block (&ifbody, &loop.pre);
1556 stdcopy = gfc_finish_block (&ifbody);
f3b0bb7a
AV
1557 /* In initialization mode from_len is a constant zero. */
1558 if (unlimited && !integer_zerop (from_len))
34d9d749
AV
1559 {
1560 vec_safe_push (args, from_len);
1561 vec_safe_push (args, to_len);
1562 tmp = build_call_vec (fcn_type, fcn, args);
1563 /* Build the body of the loop. */
1564 gfc_init_block (&loopbody);
1565 gfc_add_expr_to_block (&loopbody, tmp);
1566
1567 /* Build the loop and return. */
1568 gfc_init_loopinfo (&loop);
1569 loop.dimen = 1;
1570 loop.from[0] = gfc_index_zero_node;
1571 loop.loopvar[0] = index;
1572 loop.to[0] = nelems;
1573 gfc_trans_scalarizing_loops (&loop, &loopbody);
1574 gfc_init_block (&ifbody);
1575 gfc_add_block_to_block (&ifbody, &loop.pre);
1576 extcopy = gfc_finish_block (&ifbody);
1577
1578 tmp = fold_build2_loc (input_location, GT_EXPR,
63ee5404 1579 logical_type_node, from_len,
f622221a 1580 build_zero_cst (TREE_TYPE (from_len)));
34d9d749
AV
1581 tmp = fold_build3_loc (input_location, COND_EXPR,
1582 void_type_node, tmp, extcopy, stdcopy);
1583 gfc_add_expr_to_block (&body, tmp);
1584 tmp = gfc_finish_block (&body);
1585 }
1586 else
1587 {
1588 gfc_add_expr_to_block (&body, stdcopy);
1589 tmp = gfc_finish_block (&body);
1590 }
2960a368 1591 gfc_cleanup_loop (&loop);
4daa71b0
PT
1592 }
1593 else
1594 {
b8ac4f3b 1595 gcc_assert (!is_from_desc);
9771b263
DN
1596 vec_safe_push (args, from_data);
1597 vec_safe_push (args, to_data);
34d9d749
AV
1598 stdcopy = build_call_vec (fcn_type, fcn, args);
1599
f3b0bb7a
AV
1600 /* In initialization mode from_len is a constant zero. */
1601 if (unlimited && !integer_zerop (from_len))
34d9d749
AV
1602 {
1603 vec_safe_push (args, from_len);
1604 vec_safe_push (args, to_len);
0e3b3b77 1605 extcopy = build_call_vec (fcn_type, unshare_expr (fcn), args);
34d9d749 1606 tmp = fold_build2_loc (input_location, GT_EXPR,
63ee5404 1607 logical_type_node, from_len,
f622221a 1608 build_zero_cst (TREE_TYPE (from_len)));
34d9d749
AV
1609 tmp = fold_build3_loc (input_location, COND_EXPR,
1610 void_type_node, tmp, extcopy, stdcopy);
1611 }
1612 else
1613 tmp = stdcopy;
4daa71b0
PT
1614 }
1615
f3b0bb7a
AV
1616 /* Only copy _def_init to to_data, when it is not a NULL-pointer. */
1617 if (from == NULL_TREE)
1618 {
1619 tree cond;
1620 cond = fold_build2_loc (input_location, NE_EXPR,
63ee5404 1621 logical_type_node,
f3b0bb7a
AV
1622 from_data, null_pointer_node);
1623 tmp = fold_build3_loc (input_location, COND_EXPR,
1624 void_type_node, cond,
1625 tmp, build_empty_stmt (input_location));
1626 }
1627
4daa71b0
PT
1628 return tmp;
1629}
1630
34d9d749 1631
94fae14b
PT
1632static tree
1633gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
1634{
1635 gfc_actual_arglist *actual;
1636 gfc_expr *ppc;
1637 gfc_code *ppc_code;
1638 tree res;
1639
1640 actual = gfc_get_actual_arglist ();
1641 actual->expr = gfc_copy_expr (rhs);
1642 actual->next = gfc_get_actual_arglist ();
1643 actual->next->expr = gfc_copy_expr (lhs);
1644 ppc = gfc_copy_expr (obj);
1645 gfc_add_vptr_component (ppc);
1646 gfc_add_component_ref (ppc, "_copy");
11e5274a 1647 ppc_code = gfc_get_code (EXEC_CALL);
94fae14b
PT
1648 ppc_code->resolved_sym = ppc->symtree->n.sym;
1649 /* Although '_copy' is set to be elemental in class.c, it is
1650 not staying that way. Find out why, sometime.... */
1651 ppc_code->resolved_sym->attr.elemental = 1;
1652 ppc_code->ext.actual = actual;
1653 ppc_code->expr1 = ppc;
94fae14b
PT
1654 /* Since '_copy' is elemental, the scalarizer will take care
1655 of arrays in gfc_trans_call. */
1656 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
1657 gfc_free_statements (ppc_code);
375550c6
JW
1658
1659 if (UNLIMITED_POLY(obj))
1660 {
1661 /* Check if rhs is non-NULL. */
1662 gfc_se src;
1663 gfc_init_se (&src, NULL);
1664 gfc_conv_expr (&src, rhs);
1665 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
63ee5404 1666 tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
375550c6
JW
1667 src.expr, fold_convert (TREE_TYPE (src.expr),
1668 null_pointer_node));
1669 res = build3_loc (input_location, COND_EXPR, TREE_TYPE (res), cond, res,
1670 build_empty_stmt (input_location));
1671 }
1672
94fae14b
PT
1673 return res;
1674}
1675
1676/* Special case for initializing a polymorphic dummy with INTENT(OUT).
1677 A MEMCPY is needed to copy the full data from the default initializer
1678 of the dynamic type. */
1679
1680tree
1681gfc_trans_class_init_assign (gfc_code *code)
1682{
1683 stmtblock_t block;
1684 tree tmp;
1685 gfc_se dst,src,memsz;
1686 gfc_expr *lhs, *rhs, *sz;
1687
1688 gfc_start_block (&block);
1689
1690 lhs = gfc_copy_expr (code->expr1);
94fae14b
PT
1691
1692 rhs = gfc_copy_expr (code->expr1);
1693 gfc_add_vptr_component (rhs);
1694
1695 /* Make sure that the component backend_decls have been built, which
1696 will not have happened if the derived types concerned have not
1697 been referenced. */
1698 gfc_get_derived_type (rhs->ts.u.derived);
1699 gfc_add_def_init_component (rhs);
f3b0bb7a
AV
1700 /* The _def_init is always scalar. */
1701 rhs->rank = 0;
94fae14b
PT
1702
1703 if (code->expr1->ts.type == BT_CLASS
323c5722 1704 && CLASS_DATA (code->expr1)->attr.dimension)
574284e9
AV
1705 {
1706 gfc_array_spec *tmparr = gfc_get_array_spec ();
1707 *tmparr = *CLASS_DATA (code->expr1)->as;
3b582f1f
PT
1708 /* Adding the array ref to the class expression results in correct
1709 indexing to the dynamic type. */
574284e9
AV
1710 gfc_add_full_array_ref (lhs, tmparr);
1711 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
1712 }
94fae14b
PT
1713 else
1714 {
3b582f1f
PT
1715 /* Scalar initialization needs the _data component. */
1716 gfc_add_data_component (lhs);
94fae14b
PT
1717 sz = gfc_copy_expr (code->expr1);
1718 gfc_add_vptr_component (sz);
1719 gfc_add_size_component (sz);
1720
1721 gfc_init_se (&dst, NULL);
1722 gfc_init_se (&src, NULL);
1723 gfc_init_se (&memsz, NULL);
1724 gfc_conv_expr (&dst, lhs);
1725 gfc_conv_expr (&src, rhs);
1726 gfc_conv_expr (&memsz, sz);
1727 gfc_add_block_to_block (&block, &src.pre);
8b704316
PT
1728 src.expr = gfc_build_addr_expr (NULL_TREE, src.expr);
1729
94fae14b 1730 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
375550c6
JW
1731
1732 if (UNLIMITED_POLY(code->expr1))
1733 {
1734 /* Check if _def_init is non-NULL. */
1735 tree cond = fold_build2_loc (input_location, NE_EXPR,
63ee5404 1736 logical_type_node, src.expr,
375550c6
JW
1737 fold_convert (TREE_TYPE (src.expr),
1738 null_pointer_node));
1739 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), cond,
1740 tmp, build_empty_stmt (input_location));
1741 }
94fae14b 1742 }
99c25a87 1743
269ca408
HA
1744 if (code->expr1->symtree->n.sym->attr.dummy
1745 && (code->expr1->symtree->n.sym->attr.optional
1746 || code->expr1->symtree->n.sym->ns->proc_name->attr.entry_master))
99c25a87
TB
1747 {
1748 tree present = gfc_conv_expr_present (code->expr1->symtree->n.sym);
1749 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
1750 present, tmp,
1751 build_empty_stmt (input_location));
1752 }
1753
94fae14b 1754 gfc_add_expr_to_block (&block, tmp);
8b704316 1755
94fae14b
PT
1756 return gfc_finish_block (&block);
1757}
1758
1759
ce8dcc91
PT
1760/* Class valued elemental function calls or class array elements arriving
1761 in gfc_trans_scalar_assign come here. Wherever possible the vptr copy
1762 is used to ensure that the rhs dynamic type is assigned to the lhs. */
1763
1764static bool
1765trans_scalar_class_assign (stmtblock_t *block, gfc_se *lse, gfc_se *rse)
1766{
1767 tree fcn;
1768 tree rse_expr;
1769 tree class_data;
1770 tree tmp;
1771 tree zero;
1772 tree cond;
1773 tree final_cond;
1774 stmtblock_t inner_block;
1775 bool is_descriptor;
1776 bool not_call_expr = TREE_CODE (rse->expr) != CALL_EXPR;
1777 bool not_lhs_array_type;
1778
1779 /* Temporaries arising from depencies in assignment get cast as a
1780 character type of the dynamic size of the rhs. Use the vptr copy
1781 for this case. */
1782 tmp = TREE_TYPE (lse->expr);
1783 not_lhs_array_type = !(tmp && TREE_CODE (tmp) == ARRAY_TYPE
1784 && TYPE_MAX_VALUE (TYPE_DOMAIN (tmp)) != NULL_TREE);
1785
1786 /* Use ordinary assignment if the rhs is not a call expression or
1787 the lhs is not a class entity or an array(ie. character) type. */
1788 if ((not_call_expr && gfc_get_class_from_expr (lse->expr) == NULL_TREE)
1789 && not_lhs_array_type)
1790 return false;
1791
1792 /* Ordinary assignment can be used if both sides are class expressions
1793 since the dynamic type is preserved by copying the vptr. This
1794 should only occur, where temporaries are involved. */
1795 if (GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
1796 && GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
1797 return false;
1798
1799 /* Fix the class expression and the class data of the rhs. */
1800 if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
1801 || not_call_expr)
1802 {
1803 tmp = gfc_get_class_from_expr (rse->expr);
1804 if (tmp == NULL_TREE)
1805 return false;
1806 rse_expr = gfc_evaluate_now (tmp, block);
1807 }
1808 else
1809 rse_expr = gfc_evaluate_now (rse->expr, block);
1810
1811 class_data = gfc_class_data_get (rse_expr);
1812
1813 /* Check that the rhs data is not null. */
1814 is_descriptor = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (class_data));
1815 if (is_descriptor)
1816 class_data = gfc_conv_descriptor_data_get (class_data);
1817 class_data = gfc_evaluate_now (class_data, block);
1818
1819 zero = build_int_cst (TREE_TYPE (class_data), 0);
1820 cond = fold_build2_loc (input_location, NE_EXPR,
1821 logical_type_node,
1822 class_data, zero);
1823
1824 /* Copy the rhs to the lhs. */
1825 fcn = gfc_vptr_copy_get (gfc_class_vptr_get (rse_expr));
1826 fcn = build_fold_indirect_ref_loc (input_location, fcn);
1827 tmp = gfc_evaluate_now (gfc_build_addr_expr (NULL, rse->expr), block);
1828 tmp = is_descriptor ? tmp : class_data;
1829 tmp = build_call_expr_loc (input_location, fcn, 2, tmp,
1830 gfc_build_addr_expr (NULL, lse->expr));
1831 gfc_add_expr_to_block (block, tmp);
1832
1833 /* Only elemental function results need to be finalised and freed. */
1834 if (not_call_expr)
1835 return true;
1836
1837 /* Finalize the class data if needed. */
1838 gfc_init_block (&inner_block);
1839 fcn = gfc_vptr_final_get (gfc_class_vptr_get (rse_expr));
1840 zero = build_int_cst (TREE_TYPE (fcn), 0);
1841 final_cond = fold_build2_loc (input_location, NE_EXPR,
1842 logical_type_node, fcn, zero);
1843 fcn = build_fold_indirect_ref_loc (input_location, fcn);
1844 tmp = build_call_expr_loc (input_location, fcn, 1, class_data);
1845 tmp = build3_v (COND_EXPR, final_cond,
1846 tmp, build_empty_stmt (input_location));
1847 gfc_add_expr_to_block (&inner_block, tmp);
1848
1849 /* Free the class data. */
1850 tmp = gfc_call_free (class_data);
1851 tmp = build3_v (COND_EXPR, cond, tmp,
1852 build_empty_stmt (input_location));
1853 gfc_add_expr_to_block (&inner_block, tmp);
1854
1855 /* Finish the inner block and subject it to the condition on the
1856 class data being non-zero. */
1857 tmp = gfc_finish_block (&inner_block);
1858 tmp = build3_v (COND_EXPR, cond, tmp,
1859 build_empty_stmt (input_location));
1860 gfc_add_expr_to_block (block, tmp);
1861
1862 return true;
1863}
1864
c49ea23d
PT
1865/* End of prototype trans-class.c */
1866
1867
f1fb11f1
TB
1868static void
1869realloc_lhs_warning (bt type, bool array, locus *where)
1870{
73e42eef 1871 if (array && type != BT_CLASS && type != BT_DERIVED && warn_realloc_lhs)
48749dbc
MLI
1872 gfc_warning (OPT_Wrealloc_lhs,
1873 "Code for reallocating the allocatable array at %L will "
f1fb11f1 1874 "be added", where);
73e42eef 1875 else if (warn_realloc_lhs_all)
48749dbc
MLI
1876 gfc_warning (OPT_Wrealloc_lhs_all,
1877 "Code for reallocating the allocatable variable at %L "
f1fb11f1
TB
1878 "will be added", where);
1879}
1880
1881
0a164a3c 1882static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
62ab4a54 1883 gfc_expr *);
6de9cd9a
DN
1884
1885/* Copy the scalarization loop variables. */
1886
1887static void
1888gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
1889{
1890 dest->ss = src->ss;
1891 dest->loop = src->loop;
1892}
1893
1894
f8d0aee5 1895/* Initialize a simple expression holder.
6de9cd9a
DN
1896
1897 Care must be taken when multiple se are created with the same parent.
1898 The child se must be kept in sync. The easiest way is to delay creation
700d4cb0 1899 of a child se until after the previous se has been translated. */
6de9cd9a
DN
1900
1901void
1902gfc_init_se (gfc_se * se, gfc_se * parent)
1903{
1904 memset (se, 0, sizeof (gfc_se));
1905 gfc_init_block (&se->pre);
1906 gfc_init_block (&se->post);
1907
1908 se->parent = parent;
1909
1910 if (parent)
1911 gfc_copy_se_loopvars (se, parent);
1912}
1913
1914
1915/* Advances to the next SS in the chain. Use this rather than setting
f8d0aee5 1916 se->ss = se->ss->next because all the parents needs to be kept in sync.
6de9cd9a
DN
1917 See gfc_init_se. */
1918
1919void
1920gfc_advance_se_ss_chain (gfc_se * se)
1921{
1922 gfc_se *p;
2eace29a 1923 gfc_ss *ss;
6de9cd9a 1924
6e45f57b 1925 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
6de9cd9a
DN
1926
1927 p = se;
1928 /* Walk down the parent chain. */
1929 while (p != NULL)
1930 {
f8d0aee5 1931 /* Simple consistency check. */
4d6a0e36
MM
1932 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
1933 || p->parent->ss->nested_ss == p->ss);
6de9cd9a 1934
2eace29a
MM
1935 /* If we were in a nested loop, the next scalarized expression can be
1936 on the parent ss' next pointer. Thus we should not take the next
1937 pointer blindly, but rather go up one nest level as long as next
1938 is the end of chain. */
1939 ss = p->ss;
1940 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
1941 ss = ss->parent;
1942
1943 p->ss = ss->next;
6de9cd9a
DN
1944
1945 p = p->parent;
1946 }
1947}
1948
1949
1950/* Ensures the result of the expression as either a temporary variable
1951 or a constant so that it can be used repeatedly. */
1952
1953void
1954gfc_make_safe_expr (gfc_se * se)
1955{
1956 tree var;
1957
6615c446 1958 if (CONSTANT_CLASS_P (se->expr))
6de9cd9a
DN
1959 return;
1960
f8d0aee5 1961 /* We need a temporary for this result. */
6de9cd9a 1962 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
726a989a 1963 gfc_add_modify (&se->pre, var, se->expr);
6de9cd9a
DN
1964 se->expr = var;
1965}
1966
1967
1a7bfcc3
PB
1968/* Return an expression which determines if a dummy parameter is present.
1969 Also used for arguments to procedures with multiple entry points. */
6de9cd9a
DN
1970
1971tree
892c7427 1972gfc_conv_expr_present (gfc_symbol * sym, bool use_saved_desc)
6de9cd9a 1973{
892c7427 1974 tree decl, orig_decl, cond;
6de9cd9a 1975
1a7bfcc3 1976 gcc_assert (sym->attr.dummy);
892c7427 1977 orig_decl = decl = gfc_get_symbol_decl (sym);
60f97ac8
TB
1978
1979 /* Intrinsic scalars with VALUE attribute which are passed by value
1980 use a hidden argument to denote the present status. */
1981 if (sym->attr.value && sym->ts.type != BT_CHARACTER
1982 && sym->ts.type != BT_CLASS && sym->ts.type != BT_DERIVED
1983 && !sym->attr.dimension)
1984 {
1985 char name[GFC_MAX_SYMBOL_LEN + 2];
1986 tree tree_name;
1987
1988 gcc_assert (TREE_CODE (decl) == PARM_DECL);
1989 name[0] = '_';
1990 strcpy (&name[1], sym->name);
1991 tree_name = get_identifier (name);
1992
1993 /* Walk function argument list to find hidden arg. */
1994 cond = DECL_ARGUMENTS (DECL_CONTEXT (decl));
1995 for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond))
a2c26c50
TB
1996 if (DECL_NAME (cond) == tree_name
1997 && DECL_ARTIFICIAL (cond))
60f97ac8
TB
1998 break;
1999
2000 gcc_assert (cond);
2001 return cond;
2002 }
2003
892c7427
TB
2004 /* Assumed-shape arrays use a local variable for the array data;
2005 the actual PARAM_DECL is in a saved decl. As the local variable
2006 is NULL, it can be checked instead, unless use_saved_desc is
2007 requested. */
2008
2009 if (use_saved_desc && TREE_CODE (decl) != PARM_DECL)
6de9cd9a 2010 {
6e45f57b 2011 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
6de9cd9a
DN
2012 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
2013 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
2014 }
08857b61 2015
63ee5404 2016 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, decl,
65a9ca82 2017 fold_convert (TREE_TYPE (decl), null_pointer_node));
08857b61
TB
2018
2019 /* Fortran 2008 allows to pass null pointers and non-associated pointers
2020 as actual argument to denote absent dummies. For array descriptors,
16e82b25
TB
2021 we thus also need to check the array descriptor. For BT_CLASS, it
2022 can also occur for scalars and F2003 due to type->class wrapping and
9b110be2 2023 class->class wrapping. Note further that BT_CLASS always uses an
892c7427
TB
2024 array descriptor for arrays, also for explicit-shape/assumed-size.
2025 For assumed-rank arrays, no local variable is generated, hence,
2026 the following also applies with !use_saved_desc. */
16e82b25 2027
892c7427
TB
2028 if ((use_saved_desc || TREE_CODE (orig_decl) == PARM_DECL)
2029 && !sym->attr.allocatable
16e82b25
TB
2030 && ((sym->ts.type != BT_CLASS && !sym->attr.pointer)
2031 || (sym->ts.type == BT_CLASS
2032 && !CLASS_DATA (sym)->attr.allocatable
2033 && !CLASS_DATA (sym)->attr.class_pointer))
2034 && ((gfc_option.allow_std & GFC_STD_F2008) != 0
2035 || sym->ts.type == BT_CLASS))
08857b61
TB
2036 {
2037 tree tmp;
16e82b25
TB
2038
2039 if ((sym->as && (sym->as->type == AS_ASSUMED_SHAPE
2040 || sym->as->type == AS_ASSUMED_RANK
2041 || sym->attr.codimension))
2042 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as))
2043 {
2044 tmp = build_fold_indirect_ref_loc (input_location, decl);
2045 if (sym->ts.type == BT_CLASS)
2046 tmp = gfc_class_data_get (tmp);
2047 tmp = gfc_conv_array_data (tmp);
2048 }
2049 else if (sym->ts.type == BT_CLASS)
2050 tmp = gfc_class_data_get (decl);
2051 else
2052 tmp = NULL_TREE;
2053
2054 if (tmp != NULL_TREE)
2055 {
63ee5404 2056 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
16e82b25
TB
2057 fold_convert (TREE_TYPE (tmp), null_pointer_node));
2058 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
63ee5404 2059 logical_type_node, cond, tmp);
16e82b25 2060 }
08857b61
TB
2061 }
2062
2063 return cond;
6de9cd9a
DN
2064}
2065
2066
e15e9be3
PT
2067/* Converts a missing, dummy argument into a null or zero. */
2068
2069void
be9c3c6e 2070gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
e15e9be3
PT
2071{
2072 tree present;
2073 tree tmp;
2074
2075 present = gfc_conv_expr_present (arg->symtree->n.sym);
33717d59 2076
be9c3c6e
JD
2077 if (kind > 0)
2078 {
9b09c4de 2079 /* Create a temporary and convert it to the correct type. */
be9c3c6e 2080 tmp = gfc_get_int_type (kind);
db3927fb
AH
2081 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
2082 se->expr));
8b704316 2083
9b09c4de 2084 /* Test for a NULL value. */
5d44e5c8
TB
2085 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
2086 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
9b09c4de 2087 tmp = gfc_evaluate_now (tmp, &se->pre);
628c189e 2088 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
9b09c4de
JD
2089 }
2090 else
2091 {
5d44e5c8
TB
2092 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
2093 present, se->expr,
e8160c9a 2094 build_zero_cst (TREE_TYPE (se->expr)));
9b09c4de
JD
2095 tmp = gfc_evaluate_now (tmp, &se->pre);
2096 se->expr = tmp;
be9c3c6e 2097 }
33717d59 2098
e15e9be3
PT
2099 if (ts.type == BT_CHARACTER)
2100 {
c3238e32 2101 tmp = build_int_cst (gfc_charlen_type_node, 0);
65a9ca82
TB
2102 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
2103 present, se->string_length, tmp);
e15e9be3
PT
2104 tmp = gfc_evaluate_now (tmp, &se->pre);
2105 se->string_length = tmp;
2106 }
2107 return;
2108}
2109
2110
ca2940c3
TS
2111/* Get the character length of an expression, looking through gfc_refs
2112 if necessary. */
2113
2114tree
2115gfc_get_expr_charlen (gfc_expr *e)
2116{
2117 gfc_ref *r;
2118 tree length;
d5f48c7c 2119 gfc_se se;
ca2940c3 2120
8b704316 2121 gcc_assert (e->expr_type == EXPR_VARIABLE
ca2940c3 2122 && e->ts.type == BT_CHARACTER);
8b704316 2123
ca2940c3
TS
2124 length = NULL; /* To silence compiler warning. */
2125
bc21d315 2126 if (is_subref_array (e) && e->ts.u.cl->length)
1d6b7f39
PT
2127 {
2128 gfc_se tmpse;
2129 gfc_init_se (&tmpse, NULL);
bc21d315
JW
2130 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
2131 e->ts.u.cl->backend_decl = tmpse.expr;
1d6b7f39
PT
2132 return tmpse.expr;
2133 }
2134
ca2940c3
TS
2135 /* First candidate: if the variable is of type CHARACTER, the
2136 expression's length could be the length of the character
f7b529fa 2137 variable. */
ca2940c3 2138 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
bc21d315 2139 length = e->symtree->n.sym->ts.u.cl->backend_decl;
ca2940c3
TS
2140
2141 /* Look through the reference chain for component references. */
2142 for (r = e->ref; r; r = r->next)
2143 {
2144 switch (r->type)
2145 {
2146 case REF_COMPONENT:
2147 if (r->u.c.component->ts.type == BT_CHARACTER)
bc21d315 2148 length = r->u.c.component->ts.u.cl->backend_decl;
ca2940c3
TS
2149 break;
2150
2151 case REF_ARRAY:
2152 /* Do nothing. */
2153 break;
2154
d5f48c7c
PT
2155 case REF_SUBSTRING:
2156 gfc_init_se (&se, NULL);
2157 gfc_conv_expr_type (&se, r->u.ss.start, gfc_charlen_type_node);
2158 length = se.expr;
2159 gfc_conv_expr_type (&se, r->u.ss.end, gfc_charlen_type_node);
2160 length = fold_build2_loc (input_location, MINUS_EXPR,
2161 gfc_charlen_type_node,
2162 se.expr, length);
2163 length = fold_build2_loc (input_location, PLUS_EXPR,
2164 gfc_charlen_type_node, length,
2165 gfc_index_one_node);
2166 break;
2167
ca2940c3 2168 default:
ca2940c3 2169 gcc_unreachable ();
1d6b7f39 2170 break;
ca2940c3
TS
2171 }
2172 }
2173
2174 gcc_assert (length != NULL);
2175 return length;
2176}
2177
4b7f8314 2178
0c53708e
TB
2179/* Return for an expression the backend decl of the coarray. */
2180
b5116268
TB
2181tree
2182gfc_get_tree_for_caf_expr (gfc_expr *expr)
0c53708e 2183{
7f36b65d 2184 tree caf_decl;
36a84226 2185 bool found = false;
3c9f5092 2186 gfc_ref *ref;
7f36b65d
TB
2187
2188 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
2189
a684fb64 2190 /* Not-implemented diagnostic. */
3c9f5092
AV
2191 if (expr->symtree->n.sym->ts.type == BT_CLASS
2192 && UNLIMITED_POLY (expr->symtree->n.sym)
2193 && CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2194 gfc_error ("Sorry, coindexed access to an unlimited polymorphic object at "
2195 "%L is not supported", &expr->where);
2196
a684fb64
TB
2197 for (ref = expr->ref; ref; ref = ref->next)
2198 if (ref->type == REF_COMPONENT)
2199 {
3c9f5092
AV
2200 if (ref->u.c.component->ts.type == BT_CLASS
2201 && UNLIMITED_POLY (ref->u.c.component)
2202 && CLASS_DATA (ref->u.c.component)->attr.codimension)
2203 gfc_error ("Sorry, coindexed access to an unlimited polymorphic "
2204 "component at %L is not supported", &expr->where);
a684fb64 2205 }
a684fb64 2206
4ccff88b 2207 /* Make sure the backend_decl is present before accessing it. */
3083fc56
AV
2208 caf_decl = expr->symtree->n.sym->backend_decl == NULL_TREE
2209 ? gfc_get_symbol_decl (expr->symtree->n.sym)
2210 : expr->symtree->n.sym->backend_decl;
2211
7f36b65d 2212 if (expr->symtree->n.sym->ts.type == BT_CLASS)
3c9f5092
AV
2213 {
2214 if (expr->ref && expr->ref->type == REF_ARRAY)
2215 {
2216 caf_decl = gfc_class_data_get (caf_decl);
2217 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2218 return caf_decl;
2219 }
2220 for (ref = expr->ref; ref; ref = ref->next)
2221 {
2222 if (ref->type == REF_COMPONENT
2223 && strcmp (ref->u.c.component->name, "_data") != 0)
2224 {
2225 caf_decl = gfc_class_data_get (caf_decl);
2226 if (CLASS_DATA (expr->symtree->n.sym)->attr.codimension)
2227 return caf_decl;
2228 break;
2229 }
2230 else if (ref->type == REF_ARRAY && ref->u.ar.dimen)
2231 break;
2232 }
2233 }
7f36b65d
TB
2234 if (expr->symtree->n.sym->attr.codimension)
2235 return caf_decl;
0c53708e 2236
7f36b65d
TB
2237 /* The following code assumes that the coarray is a component reachable via
2238 only scalar components/variables; the Fortran standard guarantees this. */
0c53708e 2239
7f36b65d
TB
2240 for (ref = expr->ref; ref; ref = ref->next)
2241 if (ref->type == REF_COMPONENT)
2242 {
0c53708e 2243 gfc_component *comp = ref->u.c.component;
0c53708e 2244
7f36b65d
TB
2245 if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
2246 caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
2247 caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
2248 TREE_TYPE (comp->backend_decl), caf_decl,
2249 comp->backend_decl, NULL_TREE);
2250 if (comp->ts.type == BT_CLASS)
3c9f5092
AV
2251 {
2252 caf_decl = gfc_class_data_get (caf_decl);
2253 if (CLASS_DATA (comp)->attr.codimension)
2254 {
2255 found = true;
2256 break;
2257 }
2258 }
7f36b65d
TB
2259 if (comp->attr.codimension)
2260 {
2261 found = true;
2262 break;
2263 }
2264 }
2265 gcc_assert (found && caf_decl);
2266 return caf_decl;
0c53708e
TB
2267}
2268
2269
2c69df3b
TB
2270/* Obtain the Coarray token - and optionally also the offset. */
2271
2272void
3c9f5092
AV
2273gfc_get_caf_token_offset (gfc_se *se, tree *token, tree *offset, tree caf_decl,
2274 tree se_expr, gfc_expr *expr)
2c69df3b
TB
2275{
2276 tree tmp;
2277
2278 /* Coarray token. */
2279 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2280 {
2281 gcc_assert (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl))
2282 == GFC_ARRAY_ALLOCATABLE
2283 || expr->symtree->n.sym->attr.select_type_temporary);
2284 *token = gfc_conv_descriptor_token (caf_decl);
2285 }
2286 else if (DECL_LANG_SPECIFIC (caf_decl)
2287 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
2288 *token = GFC_DECL_TOKEN (caf_decl);
2289 else
2290 {
2291 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (caf_decl))
2292 && GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl)) != NULL_TREE);
2293 *token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (caf_decl));
2294 }
2295
2296 if (offset == NULL)
2297 return;
2298
2299 /* Offset between the coarray base address and the address wanted. */
2300 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl))
2301 && (GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_ALLOCATABLE
2302 || GFC_TYPE_ARRAY_AKIND (TREE_TYPE (caf_decl)) == GFC_ARRAY_POINTER))
2303 *offset = build_int_cst (gfc_array_index_type, 0);
2304 else if (DECL_LANG_SPECIFIC (caf_decl)
2305 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
2306 *offset = GFC_DECL_CAF_OFFSET (caf_decl);
2307 else if (GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl)) != NULL_TREE)
2308 *offset = GFC_TYPE_ARRAY_CAF_OFFSET (TREE_TYPE (caf_decl));
2309 else
2310 *offset = build_int_cst (gfc_array_index_type, 0);
2311
2312 if (POINTER_TYPE_P (TREE_TYPE (se_expr))
2313 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se_expr))))
2314 {
2315 tmp = build_fold_indirect_ref_loc (input_location, se_expr);
2316 tmp = gfc_conv_descriptor_data_get (tmp);
2317 }
2318 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se_expr)))
2319 tmp = gfc_conv_descriptor_data_get (se_expr);
2320 else
2321 {
2322 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se_expr)));
2323 tmp = se_expr;
2324 }
2325
2326 *offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2327 *offset, fold_convert (gfc_array_index_type, tmp));
2328
3c9f5092
AV
2329 if (expr->symtree->n.sym->ts.type == BT_DERIVED
2330 && expr->symtree->n.sym->attr.codimension
2331 && expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
2332 {
2333 gfc_expr *base_expr = gfc_copy_expr (expr);
2334 gfc_ref *ref = base_expr->ref;
2335 gfc_se base_se;
2336
2337 // Iterate through the refs until the last one.
2338 while (ref->next)
2339 ref = ref->next;
2340
2341 if (ref->type == REF_ARRAY
2342 && ref->u.ar.type != AR_FULL)
2343 {
2344 const int ranksum = ref->u.ar.dimen + ref->u.ar.codimen;
2345 int i;
2346 for (i = 0; i < ranksum; ++i)
2347 {
2348 ref->u.ar.start[i] = NULL;
2349 ref->u.ar.end[i] = NULL;
2350 }
2351 ref->u.ar.type = AR_FULL;
2352 }
2353 gfc_init_se (&base_se, NULL);
2354 if (gfc_caf_attr (base_expr).dimension)
2355 {
2356 gfc_conv_expr_descriptor (&base_se, base_expr);
2357 tmp = gfc_conv_descriptor_data_get (base_se.expr);
2358 }
2359 else
2360 {
2361 gfc_conv_expr (&base_se, base_expr);
2362 tmp = base_se.expr;
2363 }
2364
2365 gfc_free_expr (base_expr);
2366 gfc_add_block_to_block (&se->pre, &base_se.pre);
2367 gfc_add_block_to_block (&se->post, &base_se.post);
2368 }
2369 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (caf_decl)))
2c69df3b
TB
2370 tmp = gfc_conv_descriptor_data_get (caf_decl);
2371 else
2372 {
2373 gcc_assert (POINTER_TYPE_P (TREE_TYPE (caf_decl)));
2374 tmp = caf_decl;
2375 }
2376
2377 *offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
2378 fold_convert (gfc_array_index_type, *offset),
2379 fold_convert (gfc_array_index_type, tmp));
2380}
2381
2382
2383/* Convert the coindex of a coarray into an image index; the result is
5d26fda3
TB
2384 image_num = (idx(1)-lcobound(1)+1) + (idx(2)-lcobound(2))*extent(1)
2385 + (idx(3)-lcobound(3))*extend(1)*extent(2) + ... */
2c69df3b
TB
2386
2387tree
2388gfc_caf_get_image_index (stmtblock_t *block, gfc_expr *e, tree desc)
2389{
2390 gfc_ref *ref;
2391 tree lbound, ubound, extent, tmp, img_idx;
2392 gfc_se se;
2393 int i;
2394
2395 for (ref = e->ref; ref; ref = ref->next)
2396 if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
2397 break;
2398 gcc_assert (ref != NULL);
2399
3c9f5092
AV
2400 if (ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE)
2401 {
2402 return build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
2403 integer_zero_node);
2404 }
2405
0f97b81b
JB
2406 img_idx = build_zero_cst (gfc_array_index_type);
2407 extent = build_one_cst (gfc_array_index_type);
2c69df3b
TB
2408 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
2409 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2410 {
2411 gfc_init_se (&se, NULL);
0f97b81b 2412 gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2c69df3b
TB
2413 gfc_add_block_to_block (block, &se.pre);
2414 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
2415 tmp = fold_build2_loc (input_location, MINUS_EXPR,
0f97b81b
JB
2416 TREE_TYPE (lbound), se.expr, lbound);
2417 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2c69df3b 2418 extent, tmp);
0f97b81b
JB
2419 img_idx = fold_build2_loc (input_location, PLUS_EXPR,
2420 TREE_TYPE (tmp), img_idx, tmp);
2c69df3b
TB
2421 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2422 {
2423 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
5d26fda3 2424 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
5d26fda3 2425 extent = fold_build2_loc (input_location, MULT_EXPR,
0f97b81b 2426 TREE_TYPE (tmp), extent, tmp);
2c69df3b
TB
2427 }
2428 }
2429 else
2430 for (i = ref->u.ar.dimen; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
2431 {
2432 gfc_init_se (&se, NULL);
0f97b81b 2433 gfc_conv_expr_type (&se, ref->u.ar.start[i], gfc_array_index_type);
2c69df3b
TB
2434 gfc_add_block_to_block (block, &se.pre);
2435 lbound = GFC_TYPE_ARRAY_LBOUND (TREE_TYPE (desc), i);
2c69df3b 2436 tmp = fold_build2_loc (input_location, MINUS_EXPR,
0f97b81b
JB
2437 TREE_TYPE (lbound), se.expr, lbound);
2438 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
2c69df3b 2439 extent, tmp);
0f97b81b 2440 img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2c69df3b
TB
2441 img_idx, tmp);
2442 if (i < ref->u.ar.dimen + ref->u.ar.codimen - 1)
2443 {
2444 ubound = GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (desc), i);
5d26fda3 2445 tmp = fold_build2_loc (input_location, MINUS_EXPR,
0f97b81b
JB
2446 TREE_TYPE (ubound), ubound, lbound);
2447 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
2448 tmp, build_one_cst (TREE_TYPE (tmp)));
5d26fda3 2449 extent = fold_build2_loc (input_location, MULT_EXPR,
0f97b81b 2450 TREE_TYPE (tmp), extent, tmp);
2c69df3b
TB
2451 }
2452 }
0f97b81b
JB
2453 img_idx = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (img_idx),
2454 img_idx, build_one_cst (TREE_TYPE (img_idx)));
2455 return fold_convert (integer_type_node, img_idx);
2c69df3b
TB
2456}
2457
2458
bc21d315 2459/* For each character array constructor subexpression without a ts.u.cl->length,
4b7f8314
DK
2460 replace it by its first element (if there aren't any elements, the length
2461 should already be set to zero). */
2462
2463static void
2464flatten_array_ctors_without_strlen (gfc_expr* e)
2465{
2466 gfc_actual_arglist* arg;
2467 gfc_constructor* c;
2468
2469 if (!e)
2470 return;
2471
2472 switch (e->expr_type)
2473 {
2474
2475 case EXPR_OP:
8b704316
PT
2476 flatten_array_ctors_without_strlen (e->value.op.op1);
2477 flatten_array_ctors_without_strlen (e->value.op.op2);
4b7f8314
DK
2478 break;
2479
2480 case EXPR_COMPCALL:
2481 /* TODO: Implement as with EXPR_FUNCTION when needed. */
2482 gcc_unreachable ();
2483
2484 case EXPR_FUNCTION:
2485 for (arg = e->value.function.actual; arg; arg = arg->next)
2486 flatten_array_ctors_without_strlen (arg->expr);
2487 break;
2488
2489 case EXPR_ARRAY:
2490
2491 /* We've found what we're looking for. */
bc21d315 2492 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
4b7f8314 2493 {
b7e75771 2494 gfc_constructor *c;
4b7f8314 2495 gfc_expr* new_expr;
b7e75771 2496
4b7f8314
DK
2497 gcc_assert (e->value.constructor);
2498
b7e75771
JD
2499 c = gfc_constructor_first (e->value.constructor);
2500 new_expr = c->expr;
2501 c->expr = NULL;
4b7f8314
DK
2502
2503 flatten_array_ctors_without_strlen (new_expr);
2504 gfc_replace_expr (e, new_expr);
2505 break;
2506 }
2507
2508 /* Otherwise, fall through to handle constructor elements. */
81fea426 2509 gcc_fallthrough ();
4b7f8314 2510 case EXPR_STRUCTURE:
b7e75771
JD
2511 for (c = gfc_constructor_first (e->value.constructor);
2512 c; c = gfc_constructor_next (c))
4b7f8314
DK
2513 flatten_array_ctors_without_strlen (c->expr);
2514 break;
2515
2516 default:
2517 break;
2518
2519 }
2520}
2521
ca2940c3 2522
6de9cd9a 2523/* Generate code to initialize a string length variable. Returns the
4b7f8314
DK
2524 value. For array constructors, cl->length might be NULL and in this case,
2525 the first element of the constructor is needed. expr is the original
2526 expression so we can access it but can be NULL if this is not needed. */
6de9cd9a
DN
2527
2528void
4b7f8314 2529gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
6de9cd9a
DN
2530{
2531 gfc_se se;
6de9cd9a
DN
2532
2533 gfc_init_se (&se, NULL);
4b7f8314 2534
d168c883 2535 if (!cl->length && cl->backend_decl && VAR_P (cl->backend_decl))
597553ab
PT
2536 return;
2537
4b7f8314
DK
2538 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
2539 "flatten" array constructors by taking their first element; all elements
2540 should be the same length or a cl->length should be present. */
2541 if (!cl->length)
2542 {
2543 gfc_expr* expr_flat;
ca32d61b
PT
2544 if (!expr)
2545 return;
4b7f8314
DK
2546 expr_flat = gfc_copy_expr (expr);
2547 flatten_array_ctors_without_strlen (expr_flat);
2548 gfc_resolve_expr (expr_flat);
2549
2550 gfc_conv_expr (&se, expr_flat);
2551 gfc_add_block_to_block (pblock, &se.pre);
2552 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
2553
2554 gfc_free_expr (expr_flat);
2555 return;
2556 }
2557
2558 /* Convert cl->length. */
2559
2560 gcc_assert (cl->length);
2561
d7177ab2 2562 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
65a9ca82 2563 se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
f622221a 2564 se.expr, build_zero_cst (TREE_TYPE (se.expr)));
6de9cd9a
DN
2565 gfc_add_block_to_block (pblock, &se.pre);
2566
7987beec 2567 if (cl->backend_decl && VAR_P (cl->backend_decl))
726a989a 2568 gfc_add_modify (pblock, cl->backend_decl, se.expr);
07368af0
PT
2569 else
2570 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
6de9cd9a
DN
2571}
2572
f8d0aee5 2573
6de9cd9a 2574static void
65713e5b
TB
2575gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
2576 const char *name, locus *where)
6de9cd9a
DN
2577{
2578 tree tmp;
2579 tree type;
65713e5b 2580 tree fault;
6de9cd9a
DN
2581 gfc_se start;
2582 gfc_se end;
65713e5b 2583 char *msg;
eab19a1a 2584 mpz_t length;
6de9cd9a
DN
2585
2586 type = gfc_get_character_type (kind, ref->u.ss.length);
2587 type = build_pointer_type (type);
2588
6de9cd9a 2589 gfc_init_se (&start, se);
d7177ab2 2590 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
6de9cd9a
DN
2591 gfc_add_block_to_block (&se->pre, &start.pre);
2592
2593 if (integer_onep (start.expr))
7ab92584 2594 gfc_conv_string_parameter (se);
6de9cd9a
DN
2595 else
2596 {
10174ddf
MM
2597 tmp = start.expr;
2598 STRIP_NOPS (tmp);
1af5627c 2599 /* Avoid multiple evaluation of substring start. */
10174ddf 2600 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1af5627c
FXC
2601 start.expr = gfc_evaluate_now (start.expr, &se->pre);
2602
6de9cd9a 2603 /* Change the start of the string. */
f4af4019
JH
2604 if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
2605 || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
2606 && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
6de9cd9a
DN
2607 tmp = se->expr;
2608 else
db3927fb
AH
2609 tmp = build_fold_indirect_ref_loc (input_location,
2610 se->expr);
86075aa5
TB
2611 /* For BIND(C), a BT_CHARACTER is not an ARRAY_TYPE. */
2612 if (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
2613 {
2614 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
2615 se->expr = gfc_build_addr_expr (type, tmp);
2616 }
6de9cd9a
DN
2617 }
2618
2619 /* Length = end + 1 - start. */
2620 gfc_init_se (&end, se);
2621 if (ref->u.ss.end == NULL)
2622 end.expr = se->string_length;
2623 else
2624 {
d7177ab2 2625 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
6de9cd9a
DN
2626 gfc_add_block_to_block (&se->pre, &end.pre);
2627 }
10174ddf
MM
2628 tmp = end.expr;
2629 STRIP_NOPS (tmp);
2630 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1af5627c
FXC
2631 end.expr = gfc_evaluate_now (end.expr, &se->pre);
2632
d3d3011f 2633 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
65713e5b 2634 {
65a9ca82 2635 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
63ee5404 2636 logical_type_node, start.expr,
65a9ca82 2637 end.expr);
ad7082e3 2638
65713e5b 2639 /* Check lower bound. */
63ee5404 2640 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
65a9ca82 2641 start.expr,
f622221a 2642 build_one_cst (TREE_TYPE (start.expr)));
65a9ca82 2643 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
63ee5404 2644 logical_type_node, nonempty, fault);
65713e5b 2645 if (name)
1a33dc9e
UB
2646 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) of '%s' "
2647 "is less than one", name);
65713e5b 2648 else
aa326bfb 2649 msg = xasprintf ("Substring out of bounds: lower bound (%%ld) "
1a33dc9e 2650 "is less than one");
0d52899f 2651 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
c8fe94c7
FXC
2652 fold_convert (long_integer_type_node,
2653 start.expr));
cede9502 2654 free (msg);
65713e5b
TB
2655
2656 /* Check upper bound. */
63ee5404 2657 fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
65a9ca82
TB
2658 end.expr, se->string_length);
2659 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
63ee5404 2660 logical_type_node, nonempty, fault);
65713e5b 2661 if (name)
1a33dc9e
UB
2662 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) of '%s' "
2663 "exceeds string length (%%ld)", name);
65713e5b 2664 else
1a33dc9e
UB
2665 msg = xasprintf ("Substring out of bounds: upper bound (%%ld) "
2666 "exceeds string length (%%ld)");
0d52899f 2667 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
c8fe94c7
FXC
2668 fold_convert (long_integer_type_node, end.expr),
2669 fold_convert (long_integer_type_node,
2670 se->string_length));
cede9502 2671 free (msg);
65713e5b
TB
2672 }
2673
eab19a1a 2674 /* Try to calculate the length from the start and end expressions. */
f884552b 2675 if (ref->u.ss.end
eab19a1a
TK
2676 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &length))
2677 {
f622221a 2678 HOST_WIDE_INT i_len;
eab19a1a 2679
f622221a 2680 i_len = gfc_mpz_get_hwi (length) + 1;
eab19a1a
TK
2681 if (i_len < 0)
2682 i_len = 0;
2683
2684 tmp = build_int_cst (gfc_charlen_type_node, i_len);
2685 mpz_clear (length); /* Was initialized by gfc_dep_difference. */
2686 }
f884552b
TK
2687 else
2688 {
2689 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
f622221a
JB
2690 fold_convert (gfc_charlen_type_node, end.expr),
2691 fold_convert (gfc_charlen_type_node, start.expr));
f884552b
TK
2692 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
2693 build_int_cst (gfc_charlen_type_node, 1), tmp);
2694 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
2695 tmp, build_int_cst (gfc_charlen_type_node, 0));
2696 }
2697
93fc8073 2698 se->string_length = tmp;
6de9cd9a
DN
2699}
2700
2701
2702/* Convert a derived type component reference. */
2703
549188ea 2704void
6de9cd9a
DN
2705gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
2706{
2707 gfc_component *c;
2708 tree tmp;
2709 tree decl;
2710 tree field;
f6288c24 2711 tree context;
6de9cd9a
DN
2712
2713 c = ref->u.c.component;
2714
48188959
PT
2715 if (c->backend_decl == NULL_TREE
2716 && ref->u.c.sym != NULL)
2717 gfc_get_derived_type (ref->u.c.sym);
6de9cd9a
DN
2718
2719 field = c->backend_decl;
48188959 2720 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
6de9cd9a 2721 decl = se->expr;
f6288c24 2722 context = DECL_FIELD_CONTEXT (field);
b3c1b8a1
MM
2723
2724 /* Components can correspond to fields of different containing
2725 types, as components are created without context, whereas
2726 a concrete use of a component has the type of decl as context.
2727 So, if the type doesn't match, we search the corresponding
2728 FIELD_DECL in the parent type. To not waste too much time
f6288c24
FR
2729 we cache this result in norestrict_decl.
2730 On the other hand, if the context is a UNION or a MAP (a
2731 RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL. */
b3c1b8a1 2732
e73d3ca6 2733 if (context != TREE_TYPE (decl)
f6288c24
FR
2734 && !( TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
2735 || TREE_CODE (context) == UNION_TYPE)) /* Field is map */
b3c1b8a1
MM
2736 {
2737 tree f2 = c->norestrict_decl;
2738 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
2739 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
2740 if (TREE_CODE (f2) == FIELD_DECL
2741 && DECL_NAME (f2) == DECL_NAME (field))
2742 break;
2743 gcc_assert (f2);
2744 c->norestrict_decl = f2;
2745 field = f2;
2746 }
f04986a9 2747
f3b0bb7a
AV
2748 if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS
2749 && strcmp ("_data", c->name) == 0)
2750 {
2751 /* Found a ref to the _data component. Store the associated ref to
2752 the vptr in se->class_vptr. */
2753 se->class_vptr = gfc_class_vptr_get (decl);
2754 }
2755 else
2756 se->class_vptr = NULL_TREE;
2757
65a9ca82
TB
2758 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
2759 decl, field, NULL_TREE);
6de9cd9a
DN
2760
2761 se->expr = tmp;
2762
9b548517
AV
2763 /* Allocatable deferred char arrays are to be handled by the gfc_deferred_
2764 strlen () conditional below. */
2765 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
21c1a30f 2766 && !c->ts.deferred
276515e6 2767 && !c->attr.pdt_string)
6de9cd9a 2768 {
bc21d315 2769 tmp = c->ts.u.cl->backend_decl;
40f20186 2770 /* Components must always be constant length. */
6e45f57b 2771 gcc_assert (tmp && INTEGER_CST_P (tmp));
6de9cd9a
DN
2772 se->string_length = tmp;
2773 }
2774
2b3dc0db
PT
2775 if (gfc_deferred_strlen (c, &field))
2776 {
2777 tmp = fold_build3_loc (input_location, COMPONENT_REF,
2778 TREE_TYPE (field),
2779 decl, field, NULL_TREE);
2780 se->string_length = tmp;
2781 }
2782
241e79cf
TB
2783 if (((c->attr.pointer || c->attr.allocatable)
2784 && (!c->attr.dimension && !c->attr.codimension)
cf2b3c22 2785 && c->ts.type != BT_CHARACTER)
c74b74a8 2786 || c->attr.proc_pointer)
db3927fb
AH
2787 se->expr = build_fold_indirect_ref_loc (input_location,
2788 se->expr);
6de9cd9a
DN
2789}
2790
2791
7d1f1e61 2792/* This function deals with component references to components of the
62732c30 2793 parent type for derived type extensions. */
549188ea 2794void
7d1f1e61
PT
2795conv_parent_component_references (gfc_se * se, gfc_ref * ref)
2796{
2797 gfc_component *c;
2798 gfc_component *cmp;
2799 gfc_symbol *dt;
2800 gfc_ref parent;
2801
2802 dt = ref->u.c.sym;
2803 c = ref->u.c.component;
2804
86035eec 2805 /* Return if the component is in the parent type. */
0143a784
MM
2806 for (cmp = dt->components; cmp; cmp = cmp->next)
2807 if (strcmp (c->name, cmp->name) == 0)
2808 return;
2809
7d1f1e61
PT
2810 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
2811 parent.type = REF_COMPONENT;
2812 parent.next = NULL;
2813 parent.u.c.sym = dt;
2814 parent.u.c.component = dt->components;
2815
1821bcfc
PT
2816 if (dt->backend_decl == NULL)
2817 gfc_get_derived_type (dt);
2818
0143a784
MM
2819 /* Build the reference and call self. */
2820 gfc_conv_component_ref (se, &parent);
2821 parent.u.c.sym = dt->components->ts.u.derived;
2822 parent.u.c.component = c;
2823 conv_parent_component_references (se, &parent);
7d1f1e61
PT
2824}
2825
a5fbc2f3
PT
2826
2827static void
2828conv_inquiry (gfc_se * se, gfc_ref * ref, gfc_expr *expr, gfc_typespec *ts)
2829{
2830 tree res = se->expr;
2831
2832 switch (ref->u.i)
2833 {
2834 case INQUIRY_RE:
2835 res = fold_build1_loc (input_location, REALPART_EXPR,
2836 TREE_TYPE (TREE_TYPE (res)), res);
2837 break;
2838
2839 case INQUIRY_IM:
2840 res = fold_build1_loc (input_location, IMAGPART_EXPR,
2841 TREE_TYPE (TREE_TYPE (res)), res);
2842 break;
2843
2844 case INQUIRY_KIND:
2845 res = build_int_cst (gfc_typenode_for_spec (&expr->ts),
2846 ts->kind);
2847 break;
2848
2849 case INQUIRY_LEN:
2850 res = fold_convert (gfc_typenode_for_spec (&expr->ts),
2851 se->string_length);
2852 break;
2853
2854 default:
2855 gcc_unreachable ();
2856 }
2857 se->expr = res;
2858}
2859
549188ea
JB
2860/* Dereference VAR where needed if it is a pointer, reference, etc.
2861 according to Fortran semantics. */
2862
2863tree
2864gfc_maybe_dereference_var (gfc_symbol *sym, tree var, bool descriptor_only_p,
2865 bool is_classarray)
2866{
2867 /* Characters are entirely different from other types, they are treated
2868 separately. */
2869 if (sym->ts.type == BT_CHARACTER)
2870 {
2871 /* Dereference character pointer dummy arguments
2872 or results. */
8d57c306
JRFS
2873 if ((sym->attr.pointer || sym->attr.allocatable
2874 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
549188ea
JB
2875 && (sym->attr.dummy
2876 || sym->attr.function
2877 || sym->attr.result))
2878 var = build_fold_indirect_ref_loc (input_location, var);
2879 }
2880 else if (!sym->attr.value)
2881 {
2882 /* Dereference temporaries for class array dummy arguments. */
2883 if (sym->attr.dummy && is_classarray
2884 && GFC_ARRAY_TYPE_P (TREE_TYPE (var)))
2885 {
2886 if (!descriptor_only_p)
2887 var = GFC_DECL_SAVED_DESCRIPTOR (var);
2888
2889 var = build_fold_indirect_ref_loc (input_location, var);
2890 }
2891
2892 /* Dereference non-character scalar dummy arguments. */
2893 if (sym->attr.dummy && !sym->attr.dimension
2894 && !(sym->attr.codimension && sym->attr.allocatable)
2895 && (sym->ts.type != BT_CLASS
2896 || (!CLASS_DATA (sym)->attr.dimension
2897 && !(CLASS_DATA (sym)->attr.codimension
2898 && CLASS_DATA (sym)->attr.allocatable))))
2899 var = build_fold_indirect_ref_loc (input_location, var);
2900
2901 /* Dereference scalar hidden result. */
2902 if (flag_f2c && sym->ts.type == BT_COMPLEX
2903 && (sym->attr.function || sym->attr.result)
2904 && !sym->attr.dimension && !sym->attr.pointer
2905 && !sym->attr.always_explicit)
2906 var = build_fold_indirect_ref_loc (input_location, var);
2907
2908 /* Dereference non-character, non-class pointer variables.
2909 These must be dummies, results, or scalars. */
2910 if (!is_classarray
2911 && (sym->attr.pointer || sym->attr.allocatable
2912 || gfc_is_associate_pointer (sym)
2913 || (sym->as && sym->as->type == AS_ASSUMED_RANK))
2914 && (sym->attr.dummy
2915 || sym->attr.function
2916 || sym->attr.result
2917 || (!sym->attr.dimension
2918 && (!sym->attr.codimension || !sym->attr.allocatable))))
2919 var = build_fold_indirect_ref_loc (input_location, var);
2920 /* Now treat the class array pointer variables accordingly. */
2921 else if (sym->ts.type == BT_CLASS
2922 && sym->attr.dummy
2923 && (CLASS_DATA (sym)->attr.dimension
2924 || CLASS_DATA (sym)->attr.codimension)
2925 && ((CLASS_DATA (sym)->as
2926 && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
2927 || CLASS_DATA (sym)->attr.allocatable
2928 || CLASS_DATA (sym)->attr.class_pointer))
2929 var = build_fold_indirect_ref_loc (input_location, var);
2930 /* And the case where a non-dummy, non-result, non-function,
2931 non-allotable and non-pointer classarray is present. This case was
2932 previously covered by the first if, but with introducing the
2933 condition !is_classarray there, that case has to be covered
2934 explicitly. */
2935 else if (sym->ts.type == BT_CLASS
2936 && !sym->attr.dummy
2937 && !sym->attr.function
2938 && !sym->attr.result
2939 && (CLASS_DATA (sym)->attr.dimension
2940 || CLASS_DATA (sym)->attr.codimension)
2941 && (sym->assoc
2942 || !CLASS_DATA (sym)->attr.allocatable)
2943 && !CLASS_DATA (sym)->attr.class_pointer)
2944 var = build_fold_indirect_ref_loc (input_location, var);
2945 }
2946
2947 return var;
2948}
2949
6de9cd9a
DN
2950/* Return the contents of a variable. Also handles reference/pointer
2951 variables (all Fortran pointer references are implicit). */
2952
2953static void
2954gfc_conv_variable (gfc_se * se, gfc_expr * expr)
2955{
f98cfd3c 2956 gfc_ss *ss;
6de9cd9a
DN
2957 gfc_ref *ref;
2958 gfc_symbol *sym;
80f95228 2959 tree parent_decl = NULL_TREE;
5f20c93a
PT
2960 int parent_flag;
2961 bool return_value;
2962 bool alternate_entry;
2963 bool entry_master;
f3b0bb7a
AV
2964 bool is_classarray;
2965 bool first_time = true;
6de9cd9a
DN
2966
2967 sym = expr->symtree->n.sym;
f3b0bb7a 2968 is_classarray = IS_CLASS_ARRAY (sym);
f98cfd3c
MM
2969 ss = se->ss;
2970 if (ss != NULL)
6de9cd9a 2971 {
a0add3be
MM
2972 gfc_ss_info *ss_info = ss->info;
2973
6de9cd9a 2974 /* Check that something hasn't gone horribly wrong. */
f98cfd3c 2975 gcc_assert (ss != gfc_ss_terminator);
a0add3be 2976 gcc_assert (ss_info->expr == expr);
6de9cd9a
DN
2977
2978 /* A scalarized term. We already know the descriptor. */
1838afec 2979 se->expr = ss_info->data.array.descriptor;
a0add3be 2980 se->string_length = ss_info->string_length;
37ea263a
MM
2981 ref = ss_info->data.array.ref;
2982 if (ref)
2983 gcc_assert (ref->type == REF_ARRAY
2984 && ref->u.ar.type != AR_ELEMENT);
2985 else
2986 gfc_conv_tmp_array_ref (se);
6de9cd9a
DN
2987 }
2988 else
2989 {
d198b59a
JJ
2990 tree se_expr = NULL_TREE;
2991
b122dc6a 2992 se->expr = gfc_get_symbol_decl (sym);
6de9cd9a 2993
5f20c93a
PT
2994 /* Deal with references to a parent results or entries by storing
2995 the current_function_decl and moving to the parent_decl. */
5f20c93a
PT
2996 return_value = sym->attr.function && sym->result == sym;
2997 alternate_entry = sym->attr.function && sym->attr.entry
11a5f608 2998 && sym->result == sym;
5f20c93a 2999 entry_master = sym->attr.result
11a5f608
JJ
3000 && sym->ns->proc_name->attr.entry_master
3001 && !gfc_return_by_reference (sym->ns->proc_name);
80f95228
JW
3002 if (current_function_decl)
3003 parent_decl = DECL_CONTEXT (current_function_decl);
5f20c93a
PT
3004
3005 if ((se->expr == parent_decl && return_value)
11a5f608 3006 || (sym->ns && sym->ns->proc_name
1a492601 3007 && parent_decl
11a5f608
JJ
3008 && sym->ns->proc_name->backend_decl == parent_decl
3009 && (alternate_entry || entry_master)))
5f20c93a
PT
3010 parent_flag = 1;
3011 else
3012 parent_flag = 0;
3013
d198b59a
JJ
3014 /* Special case for assigning the return value of a function.
3015 Self recursive functions must have an explicit return value. */
11a5f608 3016 if (return_value && (se->expr == current_function_decl || parent_flag))
5f20c93a 3017 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
3018
3019 /* Similarly for alternate entry points. */
8b704316 3020 else if (alternate_entry
11a5f608
JJ
3021 && (sym->ns->proc_name->backend_decl == current_function_decl
3022 || parent_flag))
d198b59a
JJ
3023 {
3024 gfc_entry_list *el = NULL;
3025
3026 for (el = sym->ns->entries; el; el = el->next)
3027 if (sym == el->sym)
3028 {
5f20c93a 3029 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
3030 break;
3031 }
3032 }
3033
5f20c93a 3034 else if (entry_master
11a5f608
JJ
3035 && (sym->ns->proc_name->backend_decl == current_function_decl
3036 || parent_flag))
5f20c93a 3037 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
3038
3039 if (se_expr)
3040 se->expr = se_expr;
3041
7bd5dad2
LK
3042 /* Procedure actual arguments. Look out for temporary variables
3043 with the same attributes as function values. */
3044 else if (!sym->attr.temporary
3045 && sym->attr.flavor == FL_PROCEDURE
d198b59a 3046 && se->expr != current_function_decl)
6de9cd9a 3047 {
8fb74da4 3048 if (!sym->attr.dummy && !sym->attr.proc_pointer)
6de9cd9a 3049 {
6e45f57b 3050 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
628c189e 3051 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
6de9cd9a
DN
3052 }
3053 return;
ec09945c
KH
3054 }
3055
549188ea
JB
3056 /* Dereference the expression, where needed. */
3057 se->expr = gfc_maybe_dereference_var (sym, se->expr, se->descriptor_only,
3058 is_classarray);
ec09945c 3059
6de9cd9a
DN
3060 ref = expr->ref;
3061 }
3062
3063 /* For character variables, also get the length. */
3064 if (sym->ts.type == BT_CHARACTER)
3065 {
d48734ef
EE
3066 /* If the character length of an entry isn't set, get the length from
3067 the master function instead. */
bc21d315
JW
3068 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
3069 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
d48734ef 3070 else
bc21d315 3071 se->string_length = sym->ts.u.cl->backend_decl;
6e45f57b 3072 gcc_assert (se->string_length);
6de9cd9a
DN
3073 }
3074
a5fbc2f3 3075 gfc_typespec *ts = &sym->ts;
6de9cd9a
DN
3076 while (ref)
3077 {
3078 switch (ref->type)
3079 {
3080 case REF_ARRAY:
3081 /* Return the descriptor if that's what we want and this is an array
3082 section reference. */
3083 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
3084 return;
3085/* TODO: Pointers to single elements of array sections, eg elemental subs. */
3086 /* Return the descriptor for array pointers and allocations. */
3087 if (se->want_pointer
3088 && ref->next == NULL && (se->descriptor_only))
3089 return;
3090
31f02c77 3091 gfc_conv_array_ref (se, &ref->u.ar, expr, &expr->where);
6de9cd9a
DN
3092 /* Return a pointer to an element. */
3093 break;
3094
3095 case REF_COMPONENT:
a5fbc2f3 3096 ts = &ref->u.c.component->ts;
f3b0bb7a
AV
3097 if (first_time && is_classarray && sym->attr.dummy
3098 && se->descriptor_only
3099 && !CLASS_DATA (sym)->attr.allocatable
3100 && !CLASS_DATA (sym)->attr.class_pointer
3101 && CLASS_DATA (sym)->as
3102 && CLASS_DATA (sym)->as->type != AS_ASSUMED_RANK
3103 && strcmp ("_data", ref->u.c.component->name) == 0)
3104 /* Skip the first ref of a _data component, because for class
3105 arrays that one is already done by introducing a temporary
3106 array descriptor. */
3107 break;
3108
7d1f1e61
PT
3109 if (ref->u.c.sym->attr.extension)
3110 conv_parent_component_references (se, ref);
3111
6de9cd9a 3112 gfc_conv_component_ref (se, ref);
86035eec
TB
3113 if (!ref->next && ref->u.c.sym->attr.codimension
3114 && se->want_pointer && se->descriptor_only)
3115 return;
c49ea23d 3116
6de9cd9a
DN
3117 break;
3118
3119 case REF_SUBSTRING:
65713e5b
TB
3120 gfc_conv_substring (se, ref, expr->ts.kind,
3121 expr->symtree->name, &expr->where);
6de9cd9a
DN
3122 break;
3123
a5fbc2f3
PT
3124 case REF_INQUIRY:
3125 conv_inquiry (se, ref, expr, ts);
3126 break;
3127
6de9cd9a 3128 default:
6e45f57b 3129 gcc_unreachable ();
6de9cd9a
DN
3130 break;
3131 }
f3b0bb7a 3132 first_time = false;
6de9cd9a
DN
3133 ref = ref->next;
3134 }
3135 /* Pointer assignment, allocation or pass by reference. Arrays are handled
f8d0aee5 3136 separately. */
6de9cd9a
DN
3137 if (se->want_pointer)
3138 {
2a573572 3139 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr))
6de9cd9a 3140 gfc_conv_string_parameter (se);
2a573572 3141 else
628c189e 3142 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
6de9cd9a 3143 }
6de9cd9a
DN
3144}
3145
3146
3147/* Unary ops are easy... Or they would be if ! was a valid op. */
3148
3149static void
3150gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
3151{
3152 gfc_se operand;
3153 tree type;
3154
6e45f57b 3155 gcc_assert (expr->ts.type != BT_CHARACTER);
6de9cd9a
DN
3156 /* Initialize the operand. */
3157 gfc_init_se (&operand, se);
58b03ab2 3158 gfc_conv_expr_val (&operand, expr->value.op.op1);
6de9cd9a
DN
3159 gfc_add_block_to_block (&se->pre, &operand.pre);
3160
3161 type = gfc_typenode_for_spec (&expr->ts);
3162
3163 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
3164 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
f8d0aee5 3165 All other unary operators have an equivalent GIMPLE unary operator. */
6de9cd9a 3166 if (code == TRUTH_NOT_EXPR)
65a9ca82
TB
3167 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
3168 build_int_cst (type, 0));
6de9cd9a 3169 else
65a9ca82 3170 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
6de9cd9a
DN
3171
3172}
3173
5b200ac2 3174/* Expand power operator to optimal multiplications when a value is raised
f8d0aee5 3175 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
5b200ac2
FW
3176 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
3177 Programming", 3rd Edition, 1998. */
3178
3179/* This code is mostly duplicated from expand_powi in the backend.
3180 We establish the "optimal power tree" lookup table with the defined size.
3181 The items in the table are the exponents used to calculate the index
3182 exponents. Any integer n less than the value can get an "addition chain",
3183 with the first node being one. */
3184#define POWI_TABLE_SIZE 256
3185
f8d0aee5 3186/* The table is from builtins.c. */
5b200ac2
FW
3187static const unsigned char powi_table[POWI_TABLE_SIZE] =
3188 {
3189 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
3190 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
3191 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
3192 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
3193 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
3194 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
3195 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
3196 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
3197 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
3198 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
3199 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
3200 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
3201 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
3202 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
3203 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
3204 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
3205 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
3206 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
3207 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
3208 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
3209 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
3210 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
3211 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
3212 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
3213 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
3214 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
3215 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
3216 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
3217 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
3218 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
3219 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
3220 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
3221 };
3222
8b704316 3223/* If n is larger than lookup table's max index, we use the "window
f8d0aee5 3224 method". */
5b200ac2
FW
3225#define POWI_WINDOW_SIZE 3
3226
8b704316 3227/* Recursive function to expand the power operator. The temporary
f8d0aee5 3228 values are put in tmpvar. The function returns tmpvar[1] ** n. */
5b200ac2 3229static tree
6f85ab62 3230gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
6de9cd9a 3231{
5b200ac2
FW
3232 tree op0;
3233 tree op1;
6de9cd9a 3234 tree tmp;
5b200ac2 3235 int digit;
6de9cd9a 3236
5b200ac2 3237 if (n < POWI_TABLE_SIZE)
6de9cd9a 3238 {
5b200ac2
FW
3239 if (tmpvar[n])
3240 return tmpvar[n];
6de9cd9a 3241
5b200ac2
FW
3242 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
3243 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
3244 }
3245 else if (n & 1)
3246 {
3247 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
3248 op0 = gfc_conv_powi (se, n - digit, tmpvar);
3249 op1 = gfc_conv_powi (se, digit, tmpvar);
6de9cd9a
DN
3250 }
3251 else
3252 {
5b200ac2
FW
3253 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
3254 op1 = op0;
6de9cd9a
DN
3255 }
3256
65a9ca82 3257 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
5b200ac2 3258 tmp = gfc_evaluate_now (tmp, &se->pre);
6de9cd9a 3259
5b200ac2
FW
3260 if (n < POWI_TABLE_SIZE)
3261 tmpvar[n] = tmp;
6de9cd9a 3262
5b200ac2
FW
3263 return tmp;
3264}
6de9cd9a 3265
f8d0aee5
TS
3266
3267/* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
3268 return 1. Else return 0 and a call to runtime library functions
3269 will have to be built. */
5b200ac2
FW
3270static int
3271gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
3272{
3273 tree cond;
3274 tree tmp;
3275 tree type;
3276 tree vartmp[POWI_TABLE_SIZE];
6f85ab62
FXC
3277 HOST_WIDE_INT m;
3278 unsigned HOST_WIDE_INT n;
5b200ac2 3279 int sgn;
8e6cdc90 3280 wi::tree_to_wide_ref wrhs = wi::to_wide (rhs);
6de9cd9a 3281
6f85ab62
FXC
3282 /* If exponent is too large, we won't expand it anyway, so don't bother
3283 with large integer values. */
807e902e 3284 if (!wi::fits_shwi_p (wrhs))
6f85ab62
FXC
3285 return 0;
3286
807e902e 3287 m = wrhs.to_shwi ();
eb401400
AV
3288 /* Use the wide_int's routine to reliably get the absolute value on all
3289 platforms. Then convert it to a HOST_WIDE_INT like above. */
3290 n = wi::abs (wrhs).to_shwi ();
8b704316 3291
5b200ac2 3292 type = TREE_TYPE (lhs);
5b200ac2 3293 sgn = tree_int_cst_sgn (rhs);
6de9cd9a 3294
6f85ab62
FXC
3295 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
3296 || optimize_size) && (m > 2 || m < -1))
5b200ac2 3297 return 0;
6de9cd9a 3298
5b200ac2
FW
3299 /* rhs == 0 */
3300 if (sgn == 0)
3301 {
3302 se->expr = gfc_build_const (type, integer_one_node);
3303 return 1;
3304 }
6f85ab62 3305
5b200ac2
FW
3306 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
3307 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
3308 {
63ee5404 3309 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
65a9ca82 3310 lhs, build_int_cst (TREE_TYPE (lhs), -1));
63ee5404 3311 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
65a9ca82 3312 lhs, build_int_cst (TREE_TYPE (lhs), 1));
5b200ac2 3313
f8d0aee5 3314 /* If rhs is even,
7ab92584 3315 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
5b200ac2
FW
3316 if ((n & 1) == 0)
3317 {
65a9ca82 3318 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
63ee5404 3319 logical_type_node, tmp, cond);
65a9ca82
TB
3320 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3321 tmp, build_int_cst (type, 1),
3322 build_int_cst (type, 0));
5b200ac2
FW
3323 return 1;
3324 }
f8d0aee5 3325 /* If rhs is odd,
5b200ac2 3326 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
65a9ca82
TB
3327 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
3328 build_int_cst (type, -1),
3329 build_int_cst (type, 0));
3330 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
3331 cond, build_int_cst (type, 1), tmp);
5b200ac2
FW
3332 return 1;
3333 }
6de9cd9a 3334
5b200ac2
FW
3335 memset (vartmp, 0, sizeof (vartmp));
3336 vartmp[1] = lhs;
5b200ac2
FW
3337 if (sgn == -1)
3338 {
3339 tmp = gfc_build_const (type, integer_one_node);
65a9ca82
TB
3340 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
3341 vartmp[1]);
5b200ac2 3342 }
293155b0
TM
3343
3344 se->expr = gfc_conv_powi (se, n, vartmp);
3345
5b200ac2 3346 return 1;
6de9cd9a
DN
3347}
3348
3349
5b200ac2 3350/* Power op (**). Constant integer exponent has special handling. */
6de9cd9a
DN
3351
3352static void
3353gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
3354{
e2cad04b 3355 tree gfc_int4_type_node;
6de9cd9a 3356 int kind;
5b200ac2 3357 int ikind;
995d4d1c 3358 int res_ikind_1, res_ikind_2;
6de9cd9a
DN
3359 gfc_se lse;
3360 gfc_se rse;
166d08bd 3361 tree fndecl = NULL;
6de9cd9a
DN
3362
3363 gfc_init_se (&lse, se);
58b03ab2 3364 gfc_conv_expr_val (&lse, expr->value.op.op1);
20fe2233 3365 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
6de9cd9a
DN
3366 gfc_add_block_to_block (&se->pre, &lse.pre);
3367
3368 gfc_init_se (&rse, se);
58b03ab2 3369 gfc_conv_expr_val (&rse, expr->value.op.op2);
6de9cd9a
DN
3370 gfc_add_block_to_block (&se->pre, &rse.pre);
3371
58b03ab2 3372 if (expr->value.op.op2->ts.type == BT_INTEGER
31c97dfe 3373 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
5b200ac2 3374 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
31c97dfe 3375 return;
6de9cd9a 3376
06b26538
TK
3377 if (INTEGER_CST_P (lse.expr)
3378 && TREE_CODE (TREE_TYPE (rse.expr)) == INTEGER_TYPE)
3379 {
3380 wi::tree_to_wide_ref wlhs = wi::to_wide (lse.expr);
358ebd8f
HA
3381 HOST_WIDE_INT v, w;
3382 int kind, ikind, bit_size;
3383
06b26538 3384 v = wlhs.to_shwi ();
358ebd8f
HA
3385 w = abs (v);
3386
3387 kind = expr->value.op.op1->ts.kind;
3388 ikind = gfc_validate_kind (BT_INTEGER, kind, false);
3389 bit_size = gfc_integer_kinds[ikind].bit_size;
3390
06b26538
TK
3391 if (v == 1)
3392 {
3393 /* 1**something is always 1. */
3394 se->expr = build_int_cst (TREE_TYPE (lse.expr), 1);
3395 return;
3396 }
358ebd8f
HA
3397 else if (v == -1)
3398 {
3399 /* (-1)**n is 1 - ((n & 1) << 1) */
3400 tree type;
3401 tree tmp;
3402
3403 type = TREE_TYPE (lse.expr);
3404 tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3405 rse.expr, build_int_cst (type, 1));
3406 tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3407 tmp, build_int_cst (type, 1));
3408 tmp = fold_build2_loc (input_location, MINUS_EXPR, type,
3409 build_int_cst (type, 1), tmp);
3410 se->expr = tmp;
3411 return;
3412 }
3413 else if (w > 0 && ((w & (w-1)) == 0) && ((w >> (bit_size-1)) == 0))
06b26538 3414 {
358ebd8f
HA
3415 /* Here v is +/- 2**e. The further simplification uses
3416 2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n =
3417 1<<(4*n), etc., but we have to make sure to return zero
3418 if the number of bits is too large. */
06b26538
TK
3419 tree lshift;
3420 tree type;
3421 tree shift;
3422 tree ge;
3423 tree cond;
3424 tree num_bits;
3425 tree cond2;
358ebd8f 3426 tree tmp1;
06b26538
TK
3427
3428 type = TREE_TYPE (lse.expr);
3429
358ebd8f 3430 if (w == 2)
06b26538 3431 shift = rse.expr;
358ebd8f 3432 else if (w == 4)
06b26538
TK
3433 shift = fold_build2_loc (input_location, PLUS_EXPR,
3434 TREE_TYPE (rse.expr),
3435 rse.expr, rse.expr);
06b26538 3436 else
358ebd8f
HA
3437 {
3438 /* use popcount for fast log2(w) */
3439 int e = wi::popcount (w-1);
3440 shift = fold_build2_loc (input_location, MULT_EXPR,
3441 TREE_TYPE (rse.expr),
3442 build_int_cst (TREE_TYPE (rse.expr), e),
3443 rse.expr);
3444 }
06b26538
TK
3445
3446 lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3447 build_int_cst (type, 1), shift);
3448 ge = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3449 rse.expr, build_int_cst (type, 0));
3450 cond = fold_build3_loc (input_location, COND_EXPR, type, ge, lshift,
3451 build_int_cst (type, 0));
3452 num_bits = build_int_cst (TREE_TYPE (rse.expr), TYPE_PRECISION (type));
3453 cond2 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
3454 rse.expr, num_bits);
358ebd8f
HA
3455 tmp1 = fold_build3_loc (input_location, COND_EXPR, type, cond2,
3456 build_int_cst (type, 0), cond);
3457 if (v > 0)
3458 {
3459 se->expr = tmp1;
3460 }
3461 else
3462 {
3463 /* for v < 0, calculate v**n = |v|**n * (-1)**n */
3464 tree tmp2;
3465 tmp2 = fold_build2_loc (input_location, BIT_AND_EXPR, type,
3466 rse.expr, build_int_cst (type, 1));
3467 tmp2 = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3468 tmp2, build_int_cst (type, 1));
3469 tmp2 = fold_build2_loc (input_location, MINUS_EXPR, type,
3470 build_int_cst (type, 1), tmp2);
3471 se->expr = fold_build2_loc (input_location, MULT_EXPR, type,
3472 tmp1, tmp2);
3473 }
06b26538
TK
3474 return;
3475 }
3476 }
3477
e2cad04b
RH
3478 gfc_int4_type_node = gfc_get_int_type (4);
3479
995d4d1c
DK
3480 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
3481 library routine. But in the end, we have to convert the result back
3482 if this case applies -- with res_ikind_K, we keep track whether operand K
3483 falls into this case. */
3484 res_ikind_1 = -1;
3485 res_ikind_2 = -1;
3486
58b03ab2
TS
3487 kind = expr->value.op.op1->ts.kind;
3488 switch (expr->value.op.op2->ts.type)
6de9cd9a
DN
3489 {
3490 case BT_INTEGER:
58b03ab2 3491 ikind = expr->value.op.op2->ts.kind;
5b200ac2
FW
3492 switch (ikind)
3493 {
3494 case 1:
3495 case 2:
3496 rse.expr = convert (gfc_int4_type_node, rse.expr);
995d4d1c 3497 res_ikind_2 = ikind;
5b200ac2
FW
3498 /* Fall through. */
3499
3500 case 4:
3501 ikind = 0;
3502 break;
8b704316 3503
5b200ac2
FW
3504 case 8:
3505 ikind = 1;
3506 break;
3507
644cb69f
FXC
3508 case 16:
3509 ikind = 2;
3510 break;
3511
5b200ac2 3512 default:
6e45f57b 3513 gcc_unreachable ();
5b200ac2
FW
3514 }
3515 switch (kind)
3516 {
3517 case 1:
3518 case 2:
58b03ab2 3519 if (expr->value.op.op1->ts.type == BT_INTEGER)
995d4d1c
DK
3520 {
3521 lse.expr = convert (gfc_int4_type_node, lse.expr);
3522 res_ikind_1 = kind;
3523 }
5b200ac2 3524 else
6e45f57b 3525 gcc_unreachable ();
5b200ac2
FW
3526 /* Fall through. */
3527
3528 case 4:
3529 kind = 0;
3530 break;
8b704316 3531
5b200ac2
FW
3532 case 8:
3533 kind = 1;
3534 break;
3535
644cb69f
FXC
3536 case 10:
3537 kind = 2;
3538 break;
3539
3540 case 16:
3541 kind = 3;
3542 break;
3543
5b200ac2 3544 default:
6e45f57b 3545 gcc_unreachable ();
5b200ac2 3546 }
8b704316 3547
58b03ab2 3548 switch (expr->value.op.op1->ts.type)
5b200ac2
FW
3549 {
3550 case BT_INTEGER:
644cb69f
FXC
3551 if (kind == 3) /* Case 16 was not handled properly above. */
3552 kind = 2;
5b200ac2
FW
3553 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
3554 break;
3555
3556 case BT_REAL:
31c97dfe
JB
3557 /* Use builtins for real ** int4. */
3558 if (ikind == 0)
3559 {
3560 switch (kind)
3561 {
3562 case 0:
e79983f4 3563 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
31c97dfe 3564 break;
8b704316 3565
31c97dfe 3566 case 1:
e79983f4 3567 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
31c97dfe
JB
3568 break;
3569
3570 case 2:
e79983f4 3571 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
31c97dfe
JB
3572 break;
3573
166d08bd 3574 case 3:
8b704316 3575 /* Use the __builtin_powil() only if real(kind=16) is
166d08bd
FXC
3576 actually the C long double type. */
3577 if (!gfc_real16_is_float128)
e79983f4 3578 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
166d08bd
FXC
3579 break;
3580
31c97dfe
JB
3581 default:
3582 gcc_unreachable ();
3583 }
3584 }
166d08bd 3585
8b704316 3586 /* If we don't have a good builtin for this, go for the
166d08bd
FXC
3587 library function. */
3588 if (!fndecl)
31c97dfe 3589 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
5b200ac2
FW
3590 break;
3591
3592 case BT_COMPLEX:
3593 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
3594 break;
3595
3596 default:
6e45f57b 3597 gcc_unreachable ();
5b200ac2
FW
3598 }
3599 break;
6de9cd9a
DN
3600
3601 case BT_REAL:
166d08bd 3602 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
6de9cd9a
DN
3603 break;
3604
3605 case BT_COMPLEX:
166d08bd 3606 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
6de9cd9a
DN
3607 break;
3608
3609 default:
6e45f57b 3610 gcc_unreachable ();
6de9cd9a
DN
3611 break;
3612 }
3613
db3927fb
AH
3614 se->expr = build_call_expr_loc (input_location,
3615 fndecl, 2, lse.expr, rse.expr);
995d4d1c
DK
3616
3617 /* Convert the result back if it is of wrong integer kind. */
3618 if (res_ikind_1 != -1 && res_ikind_2 != -1)
3619 {
3620 /* We want the maximum of both operand kinds as result. */
3621 if (res_ikind_1 < res_ikind_2)
3622 res_ikind_1 = res_ikind_2;
3623 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
3624 }
6de9cd9a
DN
3625}
3626
3627
3628/* Generate code to allocate a string temporary. */
3629
3630tree
3631gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
3632{
3633 tree var;
3634 tree tmp;
6de9cd9a
DN
3635
3636 if (gfc_can_put_var_on_stack (len))
3637 {
3638 /* Create a temporary variable to hold the result. */
65a9ca82 3639 tmp = fold_build2_loc (input_location, MINUS_EXPR,
f622221a
JB
3640 TREE_TYPE (len), len,
3641 build_int_cst (TREE_TYPE (len), 1));
3642 tmp = build_range_type (gfc_charlen_type_node, size_zero_node, tmp);
16a55411
FXC
3643
3644 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
3645 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
3646 else
3647 tmp = build_array_type (TREE_TYPE (type), tmp);
3648
6de9cd9a
DN
3649 var = gfc_create_var (tmp, "str");
3650 var = gfc_build_addr_expr (type, var);
3651 }
3652 else
3653 {
3654 /* Allocate a temporary to hold the result. */
3655 var = gfc_create_var (type, "pstr");
2df0e3c9
TB
3656 gcc_assert (POINTER_TYPE_P (type));
3657 tmp = TREE_TYPE (type);
9c84da22
TB
3658 if (TREE_CODE (tmp) == ARRAY_TYPE)
3659 tmp = TREE_TYPE (tmp);
3660 tmp = TYPE_SIZE_UNIT (tmp);
2df0e3c9
TB
3661 tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
3662 fold_convert (size_type_node, len),
3663 fold_convert (size_type_node, tmp));
3664 tmp = gfc_call_malloc (&se->pre, type, tmp);
726a989a 3665 gfc_add_modify (&se->pre, var, tmp);
6de9cd9a
DN
3666
3667 /* Free the temporary afterwards. */
107051a5 3668 tmp = gfc_call_free (var);
6de9cd9a
DN
3669 gfc_add_expr_to_block (&se->post, tmp);
3670 }
3671
3672 return var;
3673}
3674
3675
3676/* Handle a string concatenation operation. A temporary will be allocated to
3677 hold the result. */
3678
3679static void
3680gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
3681{
374929b2
FXC
3682 gfc_se lse, rse;
3683 tree len, type, var, tmp, fndecl;
6de9cd9a 3684
58b03ab2 3685 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
374929b2 3686 && expr->value.op.op2->ts.type == BT_CHARACTER);
d393bbd7 3687 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
6de9cd9a
DN
3688
3689 gfc_init_se (&lse, se);
58b03ab2 3690 gfc_conv_expr (&lse, expr->value.op.op1);
6de9cd9a
DN
3691 gfc_conv_string_parameter (&lse);
3692 gfc_init_se (&rse, se);
58b03ab2 3693 gfc_conv_expr (&rse, expr->value.op.op2);
6de9cd9a
DN
3694 gfc_conv_string_parameter (&rse);
3695
3696 gfc_add_block_to_block (&se->pre, &lse.pre);
3697 gfc_add_block_to_block (&se->pre, &rse.pre);
3698
bc21d315 3699 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
6de9cd9a
DN
3700 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3701 if (len == NULL_TREE)
3702 {
65a9ca82 3703 len = fold_build2_loc (input_location, PLUS_EXPR,
f622221a
JB
3704 gfc_charlen_type_node,
3705 fold_convert (gfc_charlen_type_node,
3706 lse.string_length),
3707 fold_convert (gfc_charlen_type_node,
3708 rse.string_length));
6de9cd9a
DN
3709 }
3710
3711 type = build_pointer_type (type);
3712
3713 var = gfc_conv_string_tmp (se, type, len);
3714
3715 /* Do the actual concatenation. */
374929b2
FXC
3716 if (expr->ts.kind == 1)
3717 fndecl = gfor_fndecl_concat_string;
3718 else if (expr->ts.kind == 4)
3719 fndecl = gfor_fndecl_concat_string_char4;
3720 else
3721 gcc_unreachable ();
3722
db3927fb
AH
3723 tmp = build_call_expr_loc (input_location,
3724 fndecl, 6, len, var, lse.string_length, lse.expr,
5039610b 3725 rse.string_length, rse.expr);
6de9cd9a
DN
3726 gfc_add_expr_to_block (&se->pre, tmp);
3727
3728 /* Add the cleanup for the operands. */
3729 gfc_add_block_to_block (&se->pre, &rse.post);
3730 gfc_add_block_to_block (&se->pre, &lse.post);
3731
3732 se->expr = var;
3733 se->string_length = len;
3734}
3735
6de9cd9a
DN
3736/* Translates an op expression. Common (binary) cases are handled by this
3737 function, others are passed on. Recursion is used in either case.
3738 We use the fact that (op1.ts == op2.ts) (except for the power
f8d0aee5 3739 operator **).
6de9cd9a 3740 Operators need no special handling for scalarized expressions as long as
f8d0aee5 3741 they call gfc_conv_simple_val to get their operands.
6de9cd9a
DN
3742 Character strings get special handling. */
3743
3744static void
3745gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
3746{
3747 enum tree_code code;
3748 gfc_se lse;
3749 gfc_se rse;
c9ff1de3 3750 tree tmp, type;
6de9cd9a
DN
3751 int lop;
3752 int checkstring;
3753
3754 checkstring = 0;
3755 lop = 0;
a1ee985f 3756 switch (expr->value.op.op)
6de9cd9a 3757 {
2414e1d6 3758 case INTRINSIC_PARENTHESES:
203c7ebf
TB
3759 if ((expr->ts.type == BT_REAL || expr->ts.type == BT_COMPLEX)
3760 && flag_protect_parens)
dedd42d5
RG
3761 {
3762 gfc_conv_unary_op (PAREN_EXPR, se, expr);
3763 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
3764 return;
3765 }
3766
3767 /* Fallthrough. */
3768 case INTRINSIC_UPLUS:
58b03ab2 3769 gfc_conv_expr (se, expr->value.op.op1);
6de9cd9a
DN
3770 return;
3771
3772 case INTRINSIC_UMINUS:
3773 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
3774 return;
3775
3776 case INTRINSIC_NOT:
3777 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
3778 return;
3779
3780 case INTRINSIC_PLUS:
3781 code = PLUS_EXPR;
3782 break;
3783
3784 case INTRINSIC_MINUS:
3785 code = MINUS_EXPR;
3786 break;
3787
3788 case INTRINSIC_TIMES:
3789 code = MULT_EXPR;
3790 break;
3791
3792 case INTRINSIC_DIVIDE:
3793 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
3794 an integer, we must round towards zero, so we use a
3795 TRUNC_DIV_EXPR. */
3796 if (expr->ts.type == BT_INTEGER)
3797 code = TRUNC_DIV_EXPR;
3798 else
3799 code = RDIV_EXPR;
3800 break;
3801
3802 case INTRINSIC_POWER:
3803 gfc_conv_power_op (se, expr);
3804 return;
3805
3806 case INTRINSIC_CONCAT:
3807 gfc_conv_concat_op (se, expr);
3808 return;
3809
3810 case INTRINSIC_AND:
bf9197df 3811 code = flag_frontend_optimize ? TRUTH_ANDIF_EXPR : TRUTH_AND_EXPR;
6de9cd9a
DN
3812 lop = 1;
3813 break;
3814
3815 case INTRINSIC_OR:
bf9197df 3816 code = flag_frontend_optimize ? TRUTH_ORIF_EXPR : TRUTH_OR_EXPR;
6de9cd9a
DN
3817 lop = 1;
3818 break;
3819
3820 /* EQV and NEQV only work on logicals, but since we represent them
eadf906f 3821 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
6de9cd9a 3822 case INTRINSIC_EQ:
3bed9dd0 3823 case INTRINSIC_EQ_OS:
6de9cd9a
DN
3824 case INTRINSIC_EQV:
3825 code = EQ_EXPR;
3826 checkstring = 1;
3827 lop = 1;
3828 break;
3829
3830 case INTRINSIC_NE:
3bed9dd0 3831 case INTRINSIC_NE_OS:
6de9cd9a
DN
3832 case INTRINSIC_NEQV:
3833 code = NE_EXPR;
3834 checkstring = 1;
3835 lop = 1;
3836 break;
3837
3838 case INTRINSIC_GT:
3bed9dd0 3839 case INTRINSIC_GT_OS:
6de9cd9a
DN
3840 code = GT_EXPR;
3841 checkstring = 1;
3842 lop = 1;
3843 break;
3844
3845 case INTRINSIC_GE:
3bed9dd0 3846 case INTRINSIC_GE_OS:
6de9cd9a
DN
3847 code = GE_EXPR;
3848 checkstring = 1;
3849 lop = 1;
3850 break;
3851
3852 case INTRINSIC_LT:
3bed9dd0 3853 case INTRINSIC_LT_OS:
6de9cd9a
DN
3854 code = LT_EXPR;
3855 checkstring = 1;
3856 lop = 1;
3857 break;
3858
3859 case INTRINSIC_LE:
3bed9dd0 3860 case INTRINSIC_LE_OS:
6de9cd9a
DN
3861 code = LE_EXPR;
3862 checkstring = 1;
3863 lop = 1;
3864 break;
3865
3866 case INTRINSIC_USER:
3867 case INTRINSIC_ASSIGN:
3868 /* These should be converted into function calls by the frontend. */
6e45f57b 3869 gcc_unreachable ();
6de9cd9a
DN
3870
3871 default:
40fecdd6 3872 fatal_error (input_location, "Unknown intrinsic op");
6de9cd9a
DN
3873 return;
3874 }
3875
f8d0aee5 3876 /* The only exception to this is **, which is handled separately anyway. */
58b03ab2 3877 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
6de9cd9a 3878
58b03ab2 3879 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
6de9cd9a
DN
3880 checkstring = 0;
3881
3882 /* lhs */
3883 gfc_init_se (&lse, se);
58b03ab2 3884 gfc_conv_expr (&lse, expr->value.op.op1);
6de9cd9a
DN
3885 gfc_add_block_to_block (&se->pre, &lse.pre);
3886
3887 /* rhs */
3888 gfc_init_se (&rse, se);
58b03ab2 3889 gfc_conv_expr (&rse, expr->value.op.op2);
6de9cd9a
DN
3890 gfc_add_block_to_block (&se->pre, &rse.pre);
3891
6de9cd9a
DN
3892 if (checkstring)
3893 {
3894 gfc_conv_string_parameter (&lse);
3895 gfc_conv_string_parameter (&rse);
6de9cd9a 3896
0a821a92 3897 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
374929b2 3898 rse.string_length, rse.expr,
23b10420
JJ
3899 expr->value.op.op1->ts.kind,
3900 code);
ac816b02 3901 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
0a821a92 3902 gfc_add_block_to_block (&lse.post, &rse.post);
6de9cd9a
DN
3903 }
3904
3905 type = gfc_typenode_for_spec (&expr->ts);
3906
3907 if (lop)
3908 {
63ee5404
JB
3909 /* The result of logical ops is always logical_type_node. */
3910 tmp = fold_build2_loc (input_location, code, logical_type_node,
65a9ca82 3911 lse.expr, rse.expr);
6de9cd9a
DN
3912 se->expr = convert (type, tmp);
3913 }
3914 else
65a9ca82 3915 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
6de9cd9a 3916
6de9cd9a
DN
3917 /* Add the post blocks. */
3918 gfc_add_block_to_block (&se->post, &rse.post);
3919 gfc_add_block_to_block (&se->post, &lse.post);
3920}
3921
0a821a92
FW
3922/* If a string's length is one, we convert it to a single character. */
3923
d2886bc7
JJ
3924tree
3925gfc_string_to_single_character (tree len, tree str, int kind)
0a821a92 3926{
0a821a92 3927
8ae1ec92 3928 if (len == NULL
807e902e 3929 || !tree_fits_uhwi_p (len)
9a14c44d 3930 || !POINTER_TYPE_P (TREE_TYPE (str)))
48b19537
JJ
3931 return NULL_TREE;
3932
3933 if (TREE_INT_CST_LOW (len) == 1)
0a821a92 3934 {
d393bbd7 3935 str = fold_convert (gfc_get_pchar_type (kind), str);
48b19537
JJ
3936 return build_fold_indirect_ref_loc (input_location, str);
3937 }
3938
3939 if (kind == 1
3940 && TREE_CODE (str) == ADDR_EXPR
3941 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
3942 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
3943 && array_ref_low_bound (TREE_OPERAND (str, 0))
3944 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
3945 && TREE_INT_CST_LOW (len) > 1
3946 && TREE_INT_CST_LOW (len)
3947 == (unsigned HOST_WIDE_INT)
3948 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
3949 {
3950 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
3951 ret = build_fold_indirect_ref_loc (input_location, ret);
3952 if (TREE_CODE (ret) == INTEGER_CST)
3953 {
3954 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
23b10420 3955 int i, length = TREE_STRING_LENGTH (string_cst);
48b19537
JJ
3956 const char *ptr = TREE_STRING_POINTER (string_cst);
3957
23b10420 3958 for (i = 1; i < length; i++)
48b19537
JJ
3959 if (ptr[i] != ' ')
3960 return NULL_TREE;
3961
3962 return ret;
3963 }
0a821a92
FW
3964 }
3965
3966 return NULL_TREE;
3967}
3968
e032c2a1
CR
3969
3970void
3971gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
3972{
3973
3974 if (sym->backend_decl)
3975 {
3976 /* This becomes the nominal_type in
3977 function.c:assign_parm_find_data_types. */
3978 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
3979 /* This becomes the passed_type in
3980 function.c:assign_parm_find_data_types. C promotes char to
3981 integer for argument passing. */
3982 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
3983
3984 DECL_BY_REFERENCE (sym->backend_decl) = 0;
3985 }
3986
3987 if (expr != NULL)
3988 {
3989 /* If we have a constant character expression, make it into an
3990 integer. */
3991 if ((*expr)->expr_type == EXPR_CONSTANT)
3992 {
3993 gfc_typespec ts;
44000dbb 3994 gfc_clear_ts (&ts);
e032c2a1 3995
b7e75771
JD
3996 *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
3997 (int)(*expr)->value.character.string[0]);
e032c2a1
CR
3998 if ((*expr)->ts.kind != gfc_c_int_kind)
3999 {
8b704316 4000 /* The expr needs to be compatible with a C int. If the
e032c2a1
CR
4001 conversion fails, then the 2 causes an ICE. */
4002 ts.type = BT_INTEGER;
4003 ts.kind = gfc_c_int_kind;
4004 gfc_convert_type (*expr, &ts, 2);
4005 }
4006 }
4007 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
4008 {
4009 if ((*expr)->ref == NULL)
4010 {
d2886bc7 4011 se->expr = gfc_string_to_single_character
e032c2a1 4012 (build_int_cst (integer_type_node, 1),
d393bbd7 4013 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
e032c2a1 4014 gfc_get_symbol_decl
d393bbd7
FXC
4015 ((*expr)->symtree->n.sym)),
4016 (*expr)->ts.kind);
e032c2a1
CR
4017 }
4018 else
4019 {
4020 gfc_conv_variable (se, *expr);
d2886bc7 4021 se->expr = gfc_string_to_single_character
e032c2a1 4022 (build_int_cst (integer_type_node, 1),
d393bbd7
FXC
4023 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4024 se->expr),
4025 (*expr)->ts.kind);
e032c2a1
CR
4026 }
4027 }
4028 }
4029}
4030
23b10420
JJ
4031/* Helper function for gfc_build_compare_string. Return LEN_TRIM value
4032 if STR is a string literal, otherwise return -1. */
4033
4034static int
4035gfc_optimize_len_trim (tree len, tree str, int kind)
4036{
4037 if (kind == 1
4038 && TREE_CODE (str) == ADDR_EXPR
4039 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
4040 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
4041 && array_ref_low_bound (TREE_OPERAND (str, 0))
4042 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
807e902e
KZ
4043 && tree_fits_uhwi_p (len)
4044 && tree_to_uhwi (len) >= 1
4045 && tree_to_uhwi (len)
23b10420
JJ
4046 == (unsigned HOST_WIDE_INT)
4047 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
4048 {
4049 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
4050 folded = build_fold_indirect_ref_loc (input_location, folded);
4051 if (TREE_CODE (folded) == INTEGER_CST)
4052 {
4053 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
4054 int length = TREE_STRING_LENGTH (string_cst);
4055 const char *ptr = TREE_STRING_POINTER (string_cst);
4056
4057 for (; length > 0; length--)
4058 if (ptr[length - 1] != ' ')
4059 break;
4060
4061 return length;
4062 }
4063 }
4064 return -1;
4065}
e032c2a1 4066
01446eb8
TK
4067/* Helper to build a call to memcmp. */
4068
4069static tree
4070build_memcmp_call (tree s1, tree s2, tree n)
4071{
4072 tree tmp;
4073
4074 if (!POINTER_TYPE_P (TREE_TYPE (s1)))
4075 s1 = gfc_build_addr_expr (pvoid_type_node, s1);
4076 else
4077 s1 = fold_convert (pvoid_type_node, s1);
4078
4079 if (!POINTER_TYPE_P (TREE_TYPE (s2)))
4080 s2 = gfc_build_addr_expr (pvoid_type_node, s2);
4081 else
4082 s2 = fold_convert (pvoid_type_node, s2);
4083
4084 n = fold_convert (size_type_node, n);
4085
4086 tmp = build_call_expr_loc (input_location,
4087 builtin_decl_explicit (BUILT_IN_MEMCMP),
4088 3, s1, s2, n);
4089
4090 return fold_convert (integer_type_node, tmp);
4091}
4092
0a821a92
FW
4093/* Compare two strings. If they are all single characters, the result is the
4094 subtraction of them. Otherwise, we build a library call. */
4095
4096tree
23b10420
JJ
4097gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
4098 enum tree_code code)
0a821a92
FW
4099{
4100 tree sc1;
4101 tree sc2;
23b10420 4102 tree fndecl;
0a821a92
FW
4103
4104 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
4105 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
4106
d2886bc7
JJ
4107 sc1 = gfc_string_to_single_character (len1, str1, kind);
4108 sc2 = gfc_string_to_single_character (len2, str2, kind);
0a821a92 4109
0a821a92
FW
4110 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
4111 {
374929b2 4112 /* Deal with single character specially. */
c9ff1de3
FXC
4113 sc1 = fold_convert (integer_type_node, sc1);
4114 sc2 = fold_convert (integer_type_node, sc2);
65a9ca82
TB
4115 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
4116 sc1, sc2);
0a821a92 4117 }
374929b2 4118
23b10420
JJ
4119 if ((code == EQ_EXPR || code == NE_EXPR)
4120 && optimize
4121 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
4122 {
4123 /* If one string is a string literal with LEN_TRIM longer
4124 than the length of the second string, the strings
4125 compare unequal. */
4126 int len = gfc_optimize_len_trim (len1, str1, kind);
4127 if (len > 0 && compare_tree_int (len2, len) < 0)
4128 return integer_one_node;
4129 len = gfc_optimize_len_trim (len2, str2, kind);
4130 if (len > 0 && compare_tree_int (len1, len) < 0)
4131 return integer_one_node;
374929b2
FXC
4132 }
4133
01446eb8
TK
4134 /* We can compare via memcpy if the strings are known to be equal
4135 in length and they are
4136 - kind=1
9b110be2 4137 - kind=4 and the comparison is for (in)equality. */
01446eb8
TK
4138
4139 if (INTEGER_CST_P (len1) && INTEGER_CST_P (len2)
4140 && tree_int_cst_equal (len1, len2)
4141 && (kind == 1 || code == EQ_EXPR || code == NE_EXPR))
4142 {
4143 tree tmp;
4144 tree chartype;
4145
4146 chartype = gfc_get_char_type (kind);
4147 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1),
4148 fold_convert (TREE_TYPE(len1),
4149 TYPE_SIZE_UNIT(chartype)),
4150 len1);
4151 return build_memcmp_call (str1, str2, tmp);
4152 }
4153
23b10420
JJ
4154 /* Build a call for the comparison. */
4155 if (kind == 1)
4156 fndecl = gfor_fndecl_compare_string;
4157 else if (kind == 4)
4158 fndecl = gfor_fndecl_compare_string_char4;
4159 else
4160 gcc_unreachable ();
4161
4162 return build_call_expr_loc (input_location, fndecl, 4,
4163 len1, str1, len2, str2);
0a821a92 4164}
f8d0aee5 4165
23878536
JW
4166
4167/* Return the backend_decl for a procedure pointer component. */
4168
4169static tree
4170get_proc_ptr_comp (gfc_expr *e)
4171{
4172 gfc_se comp_se;
4173 gfc_expr *e2;
c12ee5df
MM
4174 expr_t old_type;
4175
23878536
JW
4176 gfc_init_se (&comp_se, NULL);
4177 e2 = gfc_copy_expr (e);
c12ee5df
MM
4178 /* We have to restore the expr type later so that gfc_free_expr frees
4179 the exact same thing that was allocated.
4180 TODO: This is ugly. */
4181 old_type = e2->expr_type;
23878536
JW
4182 e2->expr_type = EXPR_VARIABLE;
4183 gfc_conv_expr (&comp_se, e2);
c12ee5df 4184 e2->expr_type = old_type;
f43085aa 4185 gfc_free_expr (e2);
23878536
JW
4186 return build_fold_addr_expr_loc (input_location, comp_se.expr);
4187}
4188
4189
94fae14b
PT
4190/* Convert a typebound function reference from a class object. */
4191static void
4192conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
4193{
4194 gfc_ref *ref;
4195 tree var;
4196
d168c883 4197 if (!VAR_P (base_object))
94fae14b
PT
4198 {
4199 var = gfc_create_var (TREE_TYPE (base_object), NULL);
4200 gfc_add_modify (&se->pre, var, base_object);
4201 }
4202 se->expr = gfc_class_vptr_get (base_object);
4203 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
4204 ref = expr->ref;
4205 while (ref && ref->next)
4206 ref = ref->next;
4207 gcc_assert (ref && ref->type == REF_COMPONENT);
4208 if (ref->u.c.sym->attr.extension)
4209 conv_parent_component_references (se, ref);
4210 gfc_conv_component_ref (se, ref);
4211 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
4212}
4213
4214
6de9cd9a 4215static void
378f53c7
TK
4216conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr,
4217 gfc_actual_arglist *actual_args)
6de9cd9a
DN
4218{
4219 tree tmp;
4220
2a573572 4221 if (gfc_is_proc_ptr_comp (expr))
23878536 4222 tmp = get_proc_ptr_comp (expr);
713485cc 4223 else if (sym->attr.dummy)
6de9cd9a
DN
4224 {
4225 tmp = gfc_get_symbol_decl (sym);
8fb74da4 4226 if (sym->attr.proc_pointer)
db3927fb
AH
4227 tmp = build_fold_indirect_ref_loc (input_location,
4228 tmp);
6e45f57b 4229 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
6de9cd9a 4230 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
6de9cd9a
DN
4231 }
4232 else
4233 {
4234 if (!sym->backend_decl)
378f53c7 4235 sym->backend_decl = gfc_get_extern_function_decl (sym, actual_args);
6de9cd9a 4236
704fc850
JW
4237 TREE_USED (sym->backend_decl) = 1;
4238
6de9cd9a 4239 tmp = sym->backend_decl;
686c82b5 4240
7074ea72 4241 if (sym->attr.cray_pointee)
686c82b5
PT
4242 {
4243 /* TODO - make the cray pointee a pointer to a procedure,
4244 assign the pointer to it and use it for the call. This
4245 will do for now! */
4246 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
4247 gfc_get_symbol_decl (sym->cp_pointer));
4248 tmp = gfc_evaluate_now (tmp, &se->pre);
4249 }
4250
0348d6fd
RS
4251 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
4252 {
4253 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
628c189e 4254 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
0348d6fd
RS
4255 }
4256 }
4257 se->expr = tmp;
4258}
4259
4260
0348d6fd
RS
4261/* Initialize MAPPING. */
4262
62ab4a54 4263void
0348d6fd
RS
4264gfc_init_interface_mapping (gfc_interface_mapping * mapping)
4265{
4266 mapping->syms = NULL;
4267 mapping->charlens = NULL;
4268}
4269
4270
4271/* Free all memory held by MAPPING (but not MAPPING itself). */
4272
62ab4a54 4273void
0348d6fd
RS
4274gfc_free_interface_mapping (gfc_interface_mapping * mapping)
4275{
4276 gfc_interface_sym_mapping *sym;
4277 gfc_interface_sym_mapping *nextsym;
4278 gfc_charlen *cl;
4279 gfc_charlen *nextcl;
4280
4281 for (sym = mapping->syms; sym; sym = nextsym)
4282 {
4283 nextsym = sym->next;
b800fd64 4284 sym->new_sym->n.sym->formal = NULL;
7b901ac4 4285 gfc_free_symbol (sym->new_sym->n.sym);
0a164a3c 4286 gfc_free_expr (sym->expr);
cede9502
JM
4287 free (sym->new_sym);
4288 free (sym);
0348d6fd
RS
4289 }
4290 for (cl = mapping->charlens; cl; cl = nextcl)
4291 {
4292 nextcl = cl->next;
4293 gfc_free_expr (cl->length);
cede9502 4294 free (cl);
6de9cd9a
DN
4295 }
4296}
4297
4298
0348d6fd
RS
4299/* Return a copy of gfc_charlen CL. Add the returned structure to
4300 MAPPING so that it will be freed by gfc_free_interface_mapping. */
4301
4302static gfc_charlen *
4303gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
4304 gfc_charlen * cl)
4305{
7b901ac4 4306 gfc_charlen *new_charlen;
0348d6fd 4307
7b901ac4
KG
4308 new_charlen = gfc_get_charlen ();
4309 new_charlen->next = mapping->charlens;
4310 new_charlen->length = gfc_copy_expr (cl->length);
0348d6fd 4311
7b901ac4
KG
4312 mapping->charlens = new_charlen;
4313 return new_charlen;
0348d6fd
RS
4314}
4315
4316
4317/* A subroutine of gfc_add_interface_mapping. Return a descriptorless
4318 array variable that can be used as the actual argument for dummy
4319 argument SYM. Add any initialization code to BLOCK. PACKED is as
4320 for gfc_get_nodesc_array_type and DATA points to the first element
4321 in the passed array. */
4322
4323static tree
4324gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
dcfef7d4 4325 gfc_packed packed, tree data)
0348d6fd
RS
4326{
4327 tree type;
4328 tree var;
4329
4330 type = gfc_typenode_for_spec (&sym->ts);
10174ddf
MM
4331 type = gfc_get_nodesc_array_type (type, sym->as, packed,
4332 !sym->attr.target && !sym->attr.pointer
4333 && !sym->attr.proc_pointer);
0348d6fd 4334
20236f90 4335 var = gfc_create_var (type, "ifm");
726a989a 4336 gfc_add_modify (block, var, fold_convert (type, data));
0348d6fd
RS
4337
4338 return var;
4339}
4340
4341
4342/* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
4343 and offset of descriptorless array type TYPE given that it has the same
4344 size as DESC. Add any set-up code to BLOCK. */
4345
4346static void
4347gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
4348{
4349 int n;
4350 tree dim;
4351 tree offset;
4352 tree tmp;
4353
4354 offset = gfc_index_zero_node;
4355 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
4356 {
dd5797cc 4357 dim = gfc_rank_cst[n];
0348d6fd 4358 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
dd5797cc
PT
4359 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
4360 {
4361 GFC_TYPE_ARRAY_LBOUND (type, n)
568e8e1e 4362 = gfc_conv_descriptor_lbound_get (desc, dim);
dd5797cc 4363 GFC_TYPE_ARRAY_UBOUND (type, n)
568e8e1e 4364 = gfc_conv_descriptor_ubound_get (desc, dim);
dd5797cc
PT
4365 }
4366 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
0348d6fd 4367 {
65a9ca82
TB
4368 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4369 gfc_array_index_type,
4370 gfc_conv_descriptor_ubound_get (desc, dim),
4371 gfc_conv_descriptor_lbound_get (desc, dim));
4372 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4373 gfc_array_index_type,
4374 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
0348d6fd
RS
4375 tmp = gfc_evaluate_now (tmp, block);
4376 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
4377 }
65a9ca82
TB
4378 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4379 GFC_TYPE_ARRAY_LBOUND (type, n),
4380 GFC_TYPE_ARRAY_STRIDE (type, n));
4381 offset = fold_build2_loc (input_location, MINUS_EXPR,
4382 gfc_array_index_type, offset, tmp);
0348d6fd
RS
4383 }
4384 offset = gfc_evaluate_now (offset, block);
4385 GFC_TYPE_ARRAY_OFFSET (type) = offset;
4386}
4387
4388
4389/* Extend MAPPING so that it maps dummy argument SYM to the value stored
4390 in SE. The caller may still use se->expr and se->string_length after
4391 calling this function. */
4392
62ab4a54 4393void
0348d6fd 4394gfc_add_interface_mapping (gfc_interface_mapping * mapping,
0a164a3c
PT
4395 gfc_symbol * sym, gfc_se * se,
4396 gfc_expr *expr)
0348d6fd
RS
4397{
4398 gfc_interface_sym_mapping *sm;
4399 tree desc;
4400 tree tmp;
4401 tree value;
4402 gfc_symbol *new_sym;
4403 gfc_symtree *root;
4404 gfc_symtree *new_symtree;
4405
4406 /* Create a new symbol to represent the actual argument. */
4407 new_sym = gfc_new_symbol (sym->name, NULL);
4408 new_sym->ts = sym->ts;
0a991dec 4409 new_sym->as = gfc_copy_array_spec (sym->as);
0348d6fd
RS
4410 new_sym->attr.referenced = 1;
4411 new_sym->attr.dimension = sym->attr.dimension;
fe4e525c 4412 new_sym->attr.contiguous = sym->attr.contiguous;
d3a9eea2 4413 new_sym->attr.codimension = sym->attr.codimension;
0348d6fd 4414 new_sym->attr.pointer = sym->attr.pointer;
17029ac2 4415 new_sym->attr.allocatable = sym->attr.allocatable;
0348d6fd 4416 new_sym->attr.flavor = sym->attr.flavor;
0a164a3c 4417 new_sym->attr.function = sym->attr.function;
0348d6fd 4418
4d45d495
PT
4419 /* Ensure that the interface is available and that
4420 descriptors are passed for array actual arguments. */
4421 if (sym->attr.flavor == FL_PROCEDURE)
4422 {
b800fd64 4423 new_sym->formal = expr->symtree->n.sym->formal;
4d45d495
PT
4424 new_sym->attr.always_explicit
4425 = expr->symtree->n.sym->attr.always_explicit;
4426 }
4427
0348d6fd
RS
4428 /* Create a fake symtree for it. */
4429 root = NULL;
4430 new_symtree = gfc_new_symtree (&root, sym->name);
4431 new_symtree->n.sym = new_sym;
4432 gcc_assert (new_symtree == root);
4433
4434 /* Create a dummy->actual mapping. */
ece3f663 4435 sm = XCNEW (gfc_interface_sym_mapping);
0348d6fd
RS
4436 sm->next = mapping->syms;
4437 sm->old = sym;
7b901ac4 4438 sm->new_sym = new_symtree;
0a164a3c 4439 sm->expr = gfc_copy_expr (expr);
0348d6fd
RS
4440 mapping->syms = sm;
4441
4442 /* Stabilize the argument's value. */
0a164a3c
PT
4443 if (!sym->attr.function && se)
4444 se->expr = gfc_evaluate_now (se->expr, &se->pre);
0348d6fd
RS
4445
4446 if (sym->ts.type == BT_CHARACTER)
4447 {
4448 /* Create a copy of the dummy argument's length. */
bc21d315
JW
4449 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
4450 sm->expr->ts.u.cl = new_sym->ts.u.cl;
0348d6fd
RS
4451
4452 /* If the length is specified as "*", record the length that
4453 the caller is passing. We should use the callee's length
4454 in all other cases. */
bc21d315 4455 if (!new_sym->ts.u.cl->length && se)
0348d6fd
RS
4456 {
4457 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
bc21d315 4458 new_sym->ts.u.cl->backend_decl = se->string_length;
0348d6fd
RS
4459 }
4460 }
4461
0a164a3c
PT
4462 if (!se)
4463 return;
4464
0348d6fd
RS
4465 /* Use the passed value as-is if the argument is a function. */
4466 if (sym->attr.flavor == FL_PROCEDURE)
4467 value = se->expr;
4468
ac193ee7
LK
4469 /* If the argument is a pass-by-value scalar, use the value as is. */
4470 else if (!sym->attr.dimension && sym->attr.value)
4471 value = se->expr;
4472
0348d6fd
RS
4473 /* If the argument is either a string or a pointer to a string,
4474 convert it to a boundless character type. */
4475 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
4476 {
4477 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
4478 tmp = build_pointer_type (tmp);
4479 if (sym->attr.pointer)
db3927fb
AH
4480 value = build_fold_indirect_ref_loc (input_location,
4481 se->expr);
95cb77e6
WG
4482 else
4483 value = se->expr;
4484 value = fold_convert (tmp, value);
0348d6fd
RS
4485 }
4486
17029ac2
EE
4487 /* If the argument is a scalar, a pointer to an array or an allocatable,
4488 dereference it. */
4489 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
db3927fb
AH
4490 value = build_fold_indirect_ref_loc (input_location,
4491 se->expr);
8b704316
PT
4492
4493 /* For character(*), use the actual argument's descriptor. */
bc21d315 4494 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
db3927fb
AH
4495 value = build_fold_indirect_ref_loc (input_location,
4496 se->expr);
0348d6fd
RS
4497
4498 /* If the argument is an array descriptor, use it to determine
4499 information about the actual argument's shape. */
4500 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
4501 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
4502 {
4503 /* Get the actual argument's descriptor. */
db3927fb
AH
4504 desc = build_fold_indirect_ref_loc (input_location,
4505 se->expr);
0348d6fd
RS
4506
4507 /* Create the replacement variable. */
4508 tmp = gfc_conv_descriptor_data_get (desc);
dcfef7d4
TS
4509 value = gfc_get_interface_mapping_array (&se->pre, sym,
4510 PACKED_NO, tmp);
0348d6fd
RS
4511
4512 /* Use DESC to work out the upper bounds, strides and offset. */
4513 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
4514 }
4515 else
4516 /* Otherwise we have a packed array. */
dcfef7d4
TS
4517 value = gfc_get_interface_mapping_array (&se->pre, sym,
4518 PACKED_FULL, se->expr);
0348d6fd
RS
4519
4520 new_sym->backend_decl = value;
4521}
4522
4523
4524/* Called once all dummy argument mappings have been added to MAPPING,
4525 but before the mapping is used to evaluate expressions. Pre-evaluate
4526 the length of each argument, adding any initialization code to PRE and
4527 any finalization code to POST. */
4528
62ab4a54 4529void
0348d6fd
RS
4530gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
4531 stmtblock_t * pre, stmtblock_t * post)
4532{
4533 gfc_interface_sym_mapping *sym;
4534 gfc_expr *expr;
4535 gfc_se se;
4536
4537 for (sym = mapping->syms; sym; sym = sym->next)
7b901ac4 4538 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
bc21d315 4539 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
0348d6fd 4540 {
bc21d315 4541 expr = sym->new_sym->n.sym->ts.u.cl->length;
0348d6fd
RS
4542 gfc_apply_interface_mapping_to_expr (mapping, expr);
4543 gfc_init_se (&se, NULL);
4544 gfc_conv_expr (&se, expr);
18dd272d 4545 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
0348d6fd
RS
4546 se.expr = gfc_evaluate_now (se.expr, &se.pre);
4547 gfc_add_block_to_block (pre, &se.pre);
4548 gfc_add_block_to_block (post, &se.post);
4549
bc21d315 4550 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
0348d6fd
RS
4551 }
4552}
4553
4554
4555/* Like gfc_apply_interface_mapping_to_expr, but applied to
4556 constructor C. */
4557
4558static void
4559gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
b7e75771 4560 gfc_constructor_base base)
0348d6fd 4561{
b7e75771
JD
4562 gfc_constructor *c;
4563 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
0348d6fd
RS
4564 {
4565 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
4566 if (c->iterator)
4567 {
4568 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
4569 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
4570 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
4571 }
4572 }
4573}
4574
4575
4576/* Like gfc_apply_interface_mapping_to_expr, but applied to
4577 reference REF. */
4578
4579static void
4580gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
4581 gfc_ref * ref)
4582{
4583 int n;
4584
4585 for (; ref; ref = ref->next)
4586 switch (ref->type)
4587 {
4588 case REF_ARRAY:
4589 for (n = 0; n < ref->u.ar.dimen; n++)
4590 {
4591 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
4592 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
4593 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
4594 }
0348d6fd
RS
4595 break;
4596
4597 case REF_COMPONENT:
a5fbc2f3 4598 case REF_INQUIRY:
0348d6fd
RS
4599 break;
4600
4601 case REF_SUBSTRING:
4602 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
4603 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
4604 break;
4605 }
4606}
4607
4608
0a164a3c 4609/* Convert intrinsic function calls into result expressions. */
0a991dec 4610
0a164a3c 4611static bool
0a991dec 4612gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
0a164a3c
PT
4613{
4614 gfc_symbol *sym;
4615 gfc_expr *new_expr;
4616 gfc_expr *arg1;
4617 gfc_expr *arg2;
4618 int d, dup;
4619
4620 arg1 = expr->value.function.actual->expr;
4621 if (expr->value.function.actual->next)
4622 arg2 = expr->value.function.actual->next->expr;
4623 else
4624 arg2 = NULL;
4625
0a991dec 4626 sym = arg1->symtree->n.sym;
0a164a3c
PT
4627
4628 if (sym->attr.dummy)
4629 return false;
4630
4631 new_expr = NULL;
4632
4633 switch (expr->value.function.isym->id)
4634 {
4635 case GFC_ISYM_LEN:
4636 /* TODO figure out why this condition is necessary. */
4637 if (sym->attr.function
bc21d315
JW
4638 && (arg1->ts.u.cl->length == NULL
4639 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
4640 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
0a164a3c
PT
4641 return false;
4642
bc21d315 4643 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
0a164a3c
PT
4644 break;
4645
345bd7eb
PT
4646 case GFC_ISYM_LEN_TRIM:
4647 new_expr = gfc_copy_expr (arg1);
4648 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4649
4650 if (!new_expr)
4651 return false;
4652
4653 gfc_replace_expr (arg1, new_expr);
4654 return true;
4655
0a164a3c 4656 case GFC_ISYM_SIZE:
d3a9eea2 4657 if (!sym->as || sym->as->rank == 0)
0a164a3c
PT
4658 return false;
4659
4660 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4661 {
4662 dup = mpz_get_si (arg2->value.integer);
4663 d = dup - 1;
4664 }
4665 else
4666 {
4667 dup = sym->as->rank;
4668 d = 0;
4669 }
4670
4671 for (; d < dup; d++)
4672 {
4673 gfc_expr *tmp;
0a991dec
DK
4674
4675 if (!sym->as->upper[d] || !sym->as->lower[d])
4676 {
4677 gfc_free_expr (new_expr);
4678 return false;
4679 }
4680
b7e75771
JD
4681 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
4682 gfc_get_int_expr (gfc_default_integer_kind,
4683 NULL, 1));
0a164a3c
PT
4684 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
4685 if (new_expr)
4686 new_expr = gfc_multiply (new_expr, tmp);
4687 else
4688 new_expr = tmp;
4689 }
4690 break;
4691
4692 case GFC_ISYM_LBOUND:
4693 case GFC_ISYM_UBOUND:
4694 /* TODO These implementations of lbound and ubound do not limit if
4695 the size < 0, according to F95's 13.14.53 and 13.14.113. */
4696
d3a9eea2 4697 if (!sym->as || sym->as->rank == 0)
0a164a3c
PT
4698 return false;
4699
4700 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
4701 d = mpz_get_si (arg2->value.integer) - 1;
4702 else
16f681db 4703 return false;
0a164a3c
PT
4704
4705 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
0a991dec
DK
4706 {
4707 if (sym->as->lower[d])
4708 new_expr = gfc_copy_expr (sym->as->lower[d]);
4709 }
0a164a3c 4710 else
0a991dec
DK
4711 {
4712 if (sym->as->upper[d])
4713 new_expr = gfc_copy_expr (sym->as->upper[d]);
4714 }
0a164a3c
PT
4715 break;
4716
4717 default:
4718 break;
4719 }
4720
4721 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
4722 if (!new_expr)
4723 return false;
4724
4725 gfc_replace_expr (expr, new_expr);
4726 return true;
4727}
4728
4729
4730static void
4731gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
4732 gfc_interface_mapping * mapping)
4733{
4734 gfc_formal_arglist *f;
4735 gfc_actual_arglist *actual;
4736
4737 actual = expr->value.function.actual;
4cbc9039 4738 f = gfc_sym_get_dummy_args (map_expr->symtree->n.sym);
0a164a3c
PT
4739
4740 for (; f && actual; f = f->next, actual = actual->next)
4741 {
4742 if (!actual->expr)
4743 continue;
4744
4745 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
4746 }
4747
4748 if (map_expr->symtree->n.sym->attr.dimension)
4749 {
4750 int d;
4751 gfc_array_spec *as;
4752
4753 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
4754
4755 for (d = 0; d < as->rank; d++)
4756 {
4757 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
4758 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
4759 }
4760
4761 expr->value.function.esym->as = as;
4762 }
4763
4764 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
4765 {
bc21d315
JW
4766 expr->value.function.esym->ts.u.cl->length
4767 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
0a164a3c
PT
4768
4769 gfc_apply_interface_mapping_to_expr (mapping,
bc21d315 4770 expr->value.function.esym->ts.u.cl->length);
0a164a3c
PT
4771 }
4772}
4773
4774
0348d6fd
RS
4775/* EXPR is a copy of an expression that appeared in the interface
4776 associated with MAPPING. Walk it recursively looking for references to
4777 dummy arguments that MAPPING maps to actual arguments. Replace each such
4778 reference with a reference to the associated actual argument. */
4779
0a164a3c 4780static void
0348d6fd
RS
4781gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
4782 gfc_expr * expr)
4783{
4784 gfc_interface_sym_mapping *sym;
4785 gfc_actual_arglist *actual;
4786
4787 if (!expr)
0a164a3c 4788 return;
0348d6fd
RS
4789
4790 /* Copying an expression does not copy its length, so do that here. */
bc21d315 4791 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
0348d6fd 4792 {
bc21d315
JW
4793 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
4794 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
0348d6fd
RS
4795 }
4796
4797 /* Apply the mapping to any references. */
4798 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
4799
4800 /* ...and to the expression's symbol, if it has one. */
0a164a3c 4801 /* TODO Find out why the condition on expr->symtree had to be moved into
df2fba9e 4802 the loop rather than being outside it, as originally. */
0a164a3c
PT
4803 for (sym = mapping->syms; sym; sym = sym->next)
4804 if (expr->symtree && sym->old == expr->symtree->n.sym)
4805 {
7b901ac4
KG
4806 if (sym->new_sym->n.sym->backend_decl)
4807 expr->symtree = sym->new_sym;
0a164a3c
PT
4808 else if (sym->expr)
4809 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
4810 }
0348d6fd 4811
0a164a3c 4812 /* ...and to subexpressions in expr->value. */
0348d6fd
RS
4813 switch (expr->expr_type)
4814 {
4815 case EXPR_VARIABLE:
4816 case EXPR_CONSTANT:
4817 case EXPR_NULL:
4818 case EXPR_SUBSTRING:
4819 break;
4820
4821 case EXPR_OP:
4822 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
4823 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
4824 break;
4825
4826 case EXPR_FUNCTION:
0a164a3c
PT
4827 for (actual = expr->value.function.actual; actual; actual = actual->next)
4828 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
4829
36032710 4830 if (expr->value.function.esym == NULL
6a661315 4831 && expr->value.function.isym != NULL
ac80378f
HA
4832 && expr->value.function.actual
4833 && expr->value.function.actual->expr
0a164a3c
PT
4834 && expr->value.function.actual->expr->symtree
4835 && gfc_map_intrinsic_function (expr, mapping))
4836 break;
6a661315 4837
0348d6fd
RS
4838 for (sym = mapping->syms; sym; sym = sym->next)
4839 if (sym->old == expr->value.function.esym)
0a164a3c 4840 {
7b901ac4 4841 expr->value.function.esym = sym->new_sym->n.sym;
0a164a3c 4842 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
7b901ac4 4843 expr->value.function.esym->result = sym->new_sym->n.sym;
0a164a3c 4844 }
0348d6fd
RS
4845 break;
4846
4847 case EXPR_ARRAY:
4848 case EXPR_STRUCTURE:
4849 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
4850 break;
8e1f752a
DK
4851
4852 case EXPR_COMPCALL:
713485cc 4853 case EXPR_PPC:
7e703f01 4854 case EXPR_UNKNOWN:
8e1f752a
DK
4855 gcc_unreachable ();
4856 break;
0348d6fd 4857 }
0a164a3c
PT
4858
4859 return;
0348d6fd
RS
4860}
4861
4862
4863/* Evaluate interface expression EXPR using MAPPING. Store the result
4864 in SE. */
4865
62ab4a54 4866void
0348d6fd
RS
4867gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
4868 gfc_se * se, gfc_expr * expr)
4869{
4870 expr = gfc_copy_expr (expr);
4871 gfc_apply_interface_mapping_to_expr (mapping, expr);
4872 gfc_conv_expr (se, expr);
4873 se->expr = gfc_evaluate_now (se->expr, &se->pre);
4874 gfc_free_expr (expr);
4875}
4876
1d6b7f39 4877
68ea355b
PT
4878/* Returns a reference to a temporary array into which a component of
4879 an actual argument derived type array is copied and then returned
1d6b7f39 4880 after the function call. */
d4feb3d3 4881void
bf09e559
TK
4882gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, int g77,
4883 sym_intent intent, bool formal_ptr,
4884 const gfc_symbol *fsym, const char *proc_name,
1585b483 4885 gfc_symbol *sym, bool check_contiguous)
68ea355b
PT
4886{
4887 gfc_se lse;
4888 gfc_se rse;
4889 gfc_ss *lss;
4890 gfc_ss *rss;
4891 gfc_loopinfo loop;
4892 gfc_loopinfo loop2;
6d63e468 4893 gfc_array_info *info;
68ea355b
PT
4894 tree offset;
4895 tree tmp_index;
4896 tree tmp;
4897 tree base_type;
430f2d1f 4898 tree size;
68ea355b
PT
4899 stmtblock_t body;
4900 int n;
45406a12 4901 int dimen;
bf09e559
TK
4902 gfc_se work_se;
4903 gfc_se *parmse;
4904 bool pass_optional;
4905
4906 pass_optional = fsym && fsym->attr.optional && sym && sym->attr.optional;
4907
1585b483 4908 if (pass_optional || check_contiguous)
bf09e559
TK
4909 {
4910 gfc_init_se (&work_se, NULL);
4911 parmse = &work_se;
4912 }
4913 else
4914 parmse = se;
4915
4916 if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
4917 {
4918 /* We will create a temporary array, so let us warn. */
4919 char * msg;
4920
4921 if (fsym && proc_name)
4922 msg = xasprintf ("An array temporary was created for argument "
4923 "'%s' of procedure '%s'", fsym->name, proc_name);
4924 else
4925 msg = xasprintf ("An array temporary was created");
4926
4927 tmp = build_int_cst (logical_type_node, 1);
4928 gfc_trans_runtime_check (false, true, tmp, &parmse->pre,
4929 &expr->where, msg);
4930 free (msg);
4931 }
68ea355b 4932
68ea355b
PT
4933 gfc_init_se (&lse, NULL);
4934 gfc_init_se (&rse, NULL);
4935
4936 /* Walk the argument expression. */
4937 rss = gfc_walk_expr (expr);
4938
4939 gcc_assert (rss != gfc_ss_terminator);
8b704316 4940
68ea355b
PT
4941 /* Initialize the scalarizer. */
4942 gfc_init_loopinfo (&loop);
4943 gfc_add_ss_to_loop (&loop, rss);
4944
4945 /* Calculate the bounds of the scalarization. */
4946 gfc_conv_ss_startstride (&loop);
4947
4948 /* Build an ss for the temporary. */
bc21d315
JW
4949 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
4950 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
07368af0 4951
68ea355b
PT
4952 base_type = gfc_typenode_for_spec (&expr->ts);
4953 if (GFC_ARRAY_TYPE_P (base_type)
4954 || GFC_DESCRIPTOR_TYPE_P (base_type))
4955 base_type = gfc_get_element_type (base_type);
4956
c49ea23d
PT
4957 if (expr->ts.type == BT_CLASS)
4958 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
4959
a1ae4f43
MM
4960 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
4961 ? expr->ts.u.cl->backend_decl
4962 : NULL),
4963 loop.dimen);
68ea355b 4964
a0add3be 4965 parmse->string_length = loop.temp_ss->info->string_length;
68ea355b
PT
4966
4967 /* Associate the SS with the loop. */
4968 gfc_add_ss_to_loop (&loop, loop.temp_ss);
4969
4970 /* Setup the scalarizing loops. */
bdfd2ff0 4971 gfc_conv_loop_setup (&loop, &expr->where);
68ea355b
PT
4972
4973 /* Pass the temporary descriptor back to the caller. */
1838afec 4974 info = &loop.temp_ss->info->data.array;
68ea355b
PT
4975 parmse->expr = info->descriptor;
4976
4977 /* Setup the gfc_se structures. */
4978 gfc_copy_loopinfo_to_se (&lse, &loop);
4979 gfc_copy_loopinfo_to_se (&rse, &loop);
4980
4981 rse.ss = rss;
4982 lse.ss = loop.temp_ss;
4983 gfc_mark_ss_chain_used (rss, 1);
4984 gfc_mark_ss_chain_used (loop.temp_ss, 1);
4985
4986 /* Start the scalarized loop body. */
4987 gfc_start_scalarized_body (&loop, &body);
4988
4989 /* Translate the expression. */
4990 gfc_conv_expr (&rse, expr);
4991
43a68a9d
PT
4992 /* Reset the offset for the function call since the loop
4993 is zero based on the data pointer. Note that the temp
4994 comes first in the loop chain since it is added second. */
a6b22eea 4995 if (gfc_is_class_array_function (expr))
43a68a9d
PT
4996 {
4997 tmp = loop.ss->loop_chain->info->data.array.descriptor;
4998 gfc_conv_descriptor_offset_set (&loop.pre, tmp,
4999 gfc_index_zero_node);
5000 }
5001
68ea355b 5002 gfc_conv_tmp_array_ref (&lse);
68ea355b 5003
1855915a
PT
5004 if (intent != INTENT_OUT)
5005 {
ed673c00 5006 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
1855915a
PT
5007 gfc_add_expr_to_block (&body, tmp);
5008 gcc_assert (rse.ss == gfc_ss_terminator);
5009 gfc_trans_scalarizing_loops (&loop, &body);
5010 }
8c086c9c
PT
5011 else
5012 {
58b6e047
PT
5013 /* Make sure that the temporary declaration survives by merging
5014 all the loop declarations into the current context. */
5015 for (n = 0; n < loop.dimen; n++)
5016 {
5017 gfc_merge_block_scope (&body);
5018 body = loop.code[loop.order[n]];
5019 }
5020 gfc_merge_block_scope (&body);
8c086c9c 5021 }
68ea355b
PT
5022
5023 /* Add the post block after the second loop, so that any
5024 freeing of allocated memory is done at the right time. */
5025 gfc_add_block_to_block (&parmse->pre, &loop.pre);
5026
5027 /**********Copy the temporary back again.*********/
5028
5029 gfc_init_se (&lse, NULL);
5030 gfc_init_se (&rse, NULL);
5031
5032 /* Walk the argument expression. */
5033 lss = gfc_walk_expr (expr);
5034 rse.ss = loop.temp_ss;
5035 lse.ss = lss;
5036
5037 /* Initialize the scalarizer. */
5038 gfc_init_loopinfo (&loop2);
5039 gfc_add_ss_to_loop (&loop2, lss);
5040
43a68a9d
PT
5041 dimen = rse.ss->dimen;
5042
5043 /* Skip the write-out loop for this case. */
a6b22eea 5044 if (gfc_is_class_array_function (expr))
43a68a9d
PT
5045 goto class_array_fcn;
5046
68ea355b
PT
5047 /* Calculate the bounds of the scalarization. */
5048 gfc_conv_ss_startstride (&loop2);
5049
5050 /* Setup the scalarizing loops. */
bdfd2ff0 5051 gfc_conv_loop_setup (&loop2, &expr->where);
68ea355b
PT
5052
5053 gfc_copy_loopinfo_to_se (&lse, &loop2);
5054 gfc_copy_loopinfo_to_se (&rse, &loop2);
5055
5056 gfc_mark_ss_chain_used (lss, 1);
5057 gfc_mark_ss_chain_used (loop.temp_ss, 1);
5058
5059 /* Declare the variable to hold the temporary offset and start the
5060 scalarized loop body. */
5061 offset = gfc_create_var (gfc_array_index_type, NULL);
5062 gfc_start_scalarized_body (&loop2, &body);
5063
5064 /* Build the offsets for the temporary from the loop variables. The
5065 temporary array has lbounds of zero and strides of one in all
5066 dimensions, so this is very simple. The offset is only computed
5067 outside the innermost loop, so the overall transfer could be
b82feea5 5068 optimized further. */
1838afec 5069 info = &rse.ss->info->data.array;
68ea355b
PT
5070
5071 tmp_index = gfc_index_zero_node;
45406a12 5072 for (n = dimen - 1; n > 0; n--)
68ea355b
PT
5073 {
5074 tree tmp_str;
5075 tmp = rse.loop->loopvar[n];
65a9ca82
TB
5076 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5077 tmp, rse.loop->from[n]);
5078 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5079 tmp, tmp_index);
5080
5081 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
5082 gfc_array_index_type,
5083 rse.loop->to[n-1], rse.loop->from[n-1]);
5084 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
5085 gfc_array_index_type,
5086 tmp_str, gfc_index_one_node);
5087
5088 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
5089 gfc_array_index_type, tmp, tmp_str);
68ea355b
PT
5090 }
5091
65a9ca82
TB
5092 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
5093 gfc_array_index_type,
5094 tmp_index, rse.loop->from[0]);
726a989a 5095 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
68ea355b 5096
65a9ca82
TB
5097 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
5098 gfc_array_index_type,
5099 rse.loop->loopvar[0], offset);
68ea355b
PT
5100
5101 /* Now use the offset for the reference. */
db3927fb
AH
5102 tmp = build_fold_indirect_ref_loc (input_location,
5103 info->data);
1d6b7f39 5104 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
68ea355b
PT
5105
5106 if (expr->ts.type == BT_CHARACTER)
bc21d315 5107 rse.string_length = expr->ts.u.cl->backend_decl;
68ea355b
PT
5108
5109 gfc_conv_expr (&lse, expr);
5110
5111 gcc_assert (lse.ss == gfc_ss_terminator);
5112
ed673c00 5113 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true);
68ea355b 5114 gfc_add_expr_to_block (&body, tmp);
8b704316 5115
68ea355b
PT
5116 /* Generate the copying loops. */
5117 gfc_trans_scalarizing_loops (&loop2, &body);
5118
5119 /* Wrap the whole thing up by adding the second loop to the post-block
1855915a 5120 and following it by the post-block of the first loop. In this way,
68ea355b 5121 if the temporary needs freeing, it is done after use! */
1855915a
PT
5122 if (intent != INTENT_IN)
5123 {
5124 gfc_add_block_to_block (&parmse->post, &loop2.pre);
5125 gfc_add_block_to_block (&parmse->post, &loop2.post);
5126 }
68ea355b 5127
43a68a9d
PT
5128class_array_fcn:
5129
68ea355b
PT
5130 gfc_add_block_to_block (&parmse->post, &loop.post);
5131
5132 gfc_cleanup_loop (&loop);
5133 gfc_cleanup_loop (&loop2);
5134
5135 /* Pass the string length to the argument expression. */
5136 if (expr->ts.type == BT_CHARACTER)
bc21d315 5137 parmse->string_length = expr->ts.u.cl->backend_decl;
68ea355b 5138
430f2d1f
PT
5139 /* Determine the offset for pointer formal arguments and set the
5140 lbounds to one. */
5141 if (formal_ptr)
5142 {
5143 size = gfc_index_one_node;
8b704316 5144 offset = gfc_index_zero_node;
45406a12 5145 for (n = 0; n < dimen; n++)
430f2d1f
PT
5146 {
5147 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
5148 gfc_rank_cst[n]);
65a9ca82
TB
5149 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5150 gfc_array_index_type, tmp,
5151 gfc_index_one_node);
430f2d1f
PT
5152 gfc_conv_descriptor_ubound_set (&parmse->pre,
5153 parmse->expr,
5154 gfc_rank_cst[n],
5155 tmp);
5156 gfc_conv_descriptor_lbound_set (&parmse->pre,
5157 parmse->expr,
5158 gfc_rank_cst[n],
5159 gfc_index_one_node);
5160 size = gfc_evaluate_now (size, &parmse->pre);
65a9ca82
TB
5161 offset = fold_build2_loc (input_location, MINUS_EXPR,
5162 gfc_array_index_type,
5163 offset, size);
430f2d1f 5164 offset = gfc_evaluate_now (offset, &parmse->pre);
65a9ca82
TB
5165 tmp = fold_build2_loc (input_location, MINUS_EXPR,
5166 gfc_array_index_type,
5167 rse.loop->to[n], rse.loop->from[n]);
5168 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5169 gfc_array_index_type,
5170 tmp, gfc_index_one_node);
5171 size = fold_build2_loc (input_location, MULT_EXPR,
5172 gfc_array_index_type, size, tmp);
430f2d1f
PT
5173 }
5174
5175 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
5176 offset);
5177 }
5178
68ea355b
PT
5179 /* We want either the address for the data or the address of the descriptor,
5180 depending on the mode of passing array arguments. */
5181 if (g77)
5182 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
5183 else
628c189e 5184 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
68ea355b 5185
1585b483 5186 /* Basically make this into
8e73afcf 5187
1585b483
TK
5188 if (present)
5189 {
5190 if (contiguous)
5191 {
5192 pointer = a;
5193 }
5194 else
5195 {
5196 parmse->pre();
5197 pointer = parmse->expr;
5198 }
5199 }
5200 else
5201 pointer = NULL;
5202
5203 foo (pointer);
5204 if (present && !contiguous)
5205 se->post();
5206
5207 */
5208
5209 if (pass_optional || check_contiguous)
bf09e559 5210 {
bf09e559
TK
5211 tree type;
5212 stmtblock_t else_block;
5213 tree pre_stmts, post_stmts;
5214 tree pointer;
5215 tree else_stmt;
1585b483
TK
5216 tree present_var = NULL_TREE;
5217 tree cont_var = NULL_TREE;
5218 tree post_cond;
bf09e559 5219
1585b483
TK
5220 type = TREE_TYPE (parmse->expr);
5221 pointer = gfc_create_var (type, "arg_ptr");
bf09e559 5222
1585b483
TK
5223 if (check_contiguous)
5224 {
5225 gfc_se cont_se, array_se;
5226 stmtblock_t if_block, else_block;
5227 tree if_stmt, else_stmt;
5d9c602d
TK
5228 mpz_t size;
5229 bool size_set;
1585b483
TK
5230
5231 cont_var = gfc_create_var (boolean_type_node, "contiguous");
5232
5d9c602d
TK
5233 /* If the size is known to be one at compile-time, set
5234 cont_var to true unconditionally. This may look
5235 inelegant, but we're only doing this during
5236 optimization, so the statements will be optimized away,
5237 and this saves complexity here. */
5238
5239 size_set = gfc_array_size (expr, &size);
5240 if (size_set && mpz_cmp_ui (size, 1) == 0)
5241 {
5242 gfc_add_modify (&se->pre, cont_var,
5243 build_one_cst (boolean_type_node));
5244 }
5245 else
5246 {
5247 /* cont_var = is_contiguous (expr); . */
5248 gfc_init_se (&cont_se, parmse);
5249 gfc_conv_is_contiguous_expr (&cont_se, expr);
5250 gfc_add_block_to_block (&se->pre, &(&cont_se)->pre);
5251 gfc_add_modify (&se->pre, cont_var, cont_se.expr);
5252 gfc_add_block_to_block (&se->pre, &(&cont_se)->post);
5253 }
5254
5255 if (size_set)
5256 mpz_clear (size);
1585b483
TK
5257
5258 /* arrayse->expr = descriptor of a. */
5259 gfc_init_se (&array_se, se);
5260 gfc_conv_expr_descriptor (&array_se, expr);
5261 gfc_add_block_to_block (&se->pre, &(&array_se)->pre);
5262 gfc_add_block_to_block (&se->pre, &(&array_se)->post);
5263
5264 /* if_stmt = { pointer = &a[0]; } . */
5265 gfc_init_block (&if_block);
5266 tmp = gfc_conv_array_data (array_se.expr);
5267 tmp = fold_convert (type, tmp);
5268 gfc_add_modify (&if_block, pointer, tmp);
5269 if_stmt = gfc_finish_block (&if_block);
5270
5271 /* else_stmt = { parmse->pre(); pointer = parmse->expr; } . */
5272 gfc_init_block (&else_block);
5273 gfc_add_block_to_block (&else_block, &parmse->pre);
5274 gfc_add_modify (&else_block, pointer, parmse->expr);
5275 else_stmt = gfc_finish_block (&else_block);
5276
5277 /* And put the above into an if statement. */
5278 pre_stmts = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5d9c602d
TK
5279 gfc_likely (cont_var,
5280 PRED_FORTRAN_CONTIGUOUS),
5281 if_stmt, else_stmt);
1585b483
TK
5282 }
5283 else
5284 {
5285 /* pointer = pramse->expr; . */
5286 gfc_add_modify (&parmse->pre, pointer, parmse->expr);
5287 pre_stmts = gfc_finish_block (&parmse->pre);
5288 }
bf09e559 5289
1585b483
TK
5290 if (pass_optional)
5291 {
5292 present_var = gfc_create_var (boolean_type_node, "present");
bf09e559 5293
1585b483
TK
5294 /* present_var = present(sym); . */
5295 tmp = gfc_conv_expr_present (sym);
5296 tmp = fold_convert (boolean_type_node, tmp);
5297 gfc_add_modify (&se->pre, present_var, tmp);
5298
5299 /* else_stmt = { pointer = NULL; } . */
5300 gfc_init_block (&else_block);
5301 gfc_add_modify (&else_block, pointer, build_int_cst (type, 0));
5302 else_stmt = gfc_finish_block (&else_block);
5303
5d9c602d
TK
5304 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5305 gfc_likely (present_var,
5306 PRED_FORTRAN_ABSENT_DUMMY),
1585b483
TK
5307 pre_stmts, else_stmt);
5308 gfc_add_expr_to_block (&se->pre, tmp);
1585b483
TK
5309 }
5310 else
5311 gfc_add_expr_to_block (&se->pre, pre_stmts);
bf09e559
TK
5312
5313 post_stmts = gfc_finish_block (&parmse->post);
1585b483
TK
5314
5315 /* Put together the post stuff, plus the optional
5316 deallocation. */
5317 if (check_contiguous)
5318 {
5319 /* !cont_var. */
5320 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5321 cont_var,
5322 build_zero_cst (boolean_type_node));
5d9c602d
TK
5323 tmp = gfc_unlikely (tmp, PRED_FORTRAN_CONTIGUOUS);
5324
1585b483 5325 if (pass_optional)
5d9c602d
TK
5326 {
5327 tree present_likely = gfc_likely (present_var,
5328 PRED_FORTRAN_ABSENT_DUMMY);
5329 post_cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
5330 boolean_type_node, present_likely,
5331 tmp);
5332 }
1585b483
TK
5333 else
5334 post_cond = tmp;
5335 }
5336 else
5337 {
5338 gcc_assert (pass_optional);
5339 post_cond = present_var;
5340 }
5341
5342 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, post_cond,
bf09e559
TK
5343 post_stmts, build_empty_stmt (input_location));
5344 gfc_add_expr_to_block (&se->post, tmp);
bf09e559
TK
5345 se->expr = pointer;
5346 }
5347
68ea355b
PT
5348 return;
5349}
5350
0348d6fd 5351
7fcafa71
PT
5352/* Generate the code for argument list functions. */
5353
5354static void
5355conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
5356{
7fcafa71
PT
5357 /* Pass by value for g77 %VAL(arg), pass the address
5358 indirectly for %LOC, else by reference. Thus %REF
5359 is a "do-nothing" and %LOC is the same as an F95
5360 pointer. */
2eb3745a 5361 if (strcmp (name, "%VAL") == 0)
7193e30a 5362 gfc_conv_expr (se, expr);
2eb3745a 5363 else if (strcmp (name, "%LOC") == 0)
7fcafa71
PT
5364 {
5365 gfc_conv_expr_reference (se, expr);
5366 se->expr = gfc_build_addr_expr (NULL, se->expr);
5367 }
2eb3745a 5368 else if (strcmp (name, "%REF") == 0)
7fcafa71
PT
5369 gfc_conv_expr_reference (se, expr);
5370 else
5371 gfc_error ("Unknown argument list function at %L", &expr->where);
5372}
5373
5374
0e1f8c6a
MM
5375/* This function tells whether the middle-end representation of the expression
5376 E given as input may point to data otherwise accessible through a variable
5377 (sub-)reference.
5378 It is assumed that the only expressions that may alias are variables,
5379 and array constructors if ARRAY_MAY_ALIAS is true and some of its elements
5380 may alias.
5381 This function is used to decide whether freeing an expression's allocatable
5382 components is safe or should be avoided.
5383
5384 If ARRAY_MAY_ALIAS is true, an array constructor may alias if some of
5385 its elements are copied from a variable. This ARRAY_MAY_ALIAS trick
5386 is necessary because for array constructors, aliasing depends on how
5387 the array is used:
5388 - If E is an array constructor used as argument to an elemental procedure,
5389 the array, which is generated through shallow copy by the scalarizer,
5390 is used directly and can alias the expressions it was copied from.
5391 - If E is an array constructor used as argument to a non-elemental
5392 procedure,the scalarizer is used in gfc_conv_expr_descriptor to generate
5393 the array as in the previous case, but then that array is used
5394 to initialize a new descriptor through deep copy. There is no alias
5395 possible in that case.
5396 Thus, the ARRAY_MAY_ALIAS flag is necessary to distinguish the two cases
5397 above. */
5398
5399static bool
5400expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
5401{
5402 gfc_constructor *c;
5403
5404 if (e->expr_type == EXPR_VARIABLE)
5405 return true;
5406 else if (e->expr_type == EXPR_FUNCTION)
5407 {
5408 gfc_symbol *proc_ifc = gfc_get_proc_ifc_for_expr (e);
5409
3c9f5092
AV
5410 if (proc_ifc->result != NULL
5411 && ((proc_ifc->result->ts.type == BT_CLASS
5412 && proc_ifc->result->ts.u.derived->attr.is_class
5413 && CLASS_DATA (proc_ifc->result)->attr.class_pointer)
5414 || proc_ifc->result->attr.pointer))
0e1f8c6a
MM
5415 return true;
5416 else
5417 return false;
5418 }
5419 else if (e->expr_type != EXPR_ARRAY || !array_may_alias)
5420 return false;
5421
5422 for (c = gfc_constructor_first (e->value.constructor);
5423 c; c = gfc_constructor_next (c))
5424 if (c->expr
5425 && expr_may_alias_variables (c->expr, array_may_alias))
5426 return true;
5427
5428 return false;
5429}
5430
5431
0e308880
PT
5432/* A helper function to set the dtype for unallocated or unassociated
5433 entities. */
5434
5435static void
5436set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
5437{
5438 tree tmp;
5439 tree desc;
5440 tree cond;
5441 tree type;
5442 stmtblock_t block;
5443
5444 /* TODO Figure out how to handle optional dummies. */
5445 if (e && e->expr_type == EXPR_VARIABLE
5446 && e->symtree->n.sym->attr.optional)
5447 return;
5448
5449 desc = parmse->expr;
5450 if (desc == NULL_TREE)
5451 return;
5452
5453 if (POINTER_TYPE_P (TREE_TYPE (desc)))
5454 desc = build_fold_indirect_ref_loc (input_location, desc);
5455
5456 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
5457 return;
5458
5459 gfc_init_block (&block);
5460 tmp = gfc_conv_descriptor_data_get (desc);
5461 cond = fold_build2_loc (input_location, EQ_EXPR,
5462 logical_type_node, tmp,
5463 build_int_cst (TREE_TYPE (tmp), 0));
5464 tmp = gfc_conv_descriptor_dtype (desc);
5465 type = gfc_get_element_type (TREE_TYPE (desc));
5466 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5467 TREE_TYPE (tmp), tmp,
5468 gfc_get_dtype_rank_type (e->rank, type));
5469 gfc_add_expr_to_block (&block, tmp);
5470 cond = build3_v (COND_EXPR, cond,
5471 gfc_finish_block (&block),
5472 build_empty_stmt (input_location));
5473 gfc_add_expr_to_block (&parmse->pre, cond);
5474}
5475
5476
5477
bbf18dc5
PT
5478/* Provide an interface between gfortran array descriptors and the F2018:18.4
5479 ISO_Fortran_binding array descriptors. */
5480
5481static void
5482gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
5483{
5484 tree tmp;
5485 tree cfi_desc_ptr;
5486 tree gfc_desc_ptr;
5487 tree type;
0d78e4aa 5488 tree cond;
980f185c 5489 tree desc_attr;
bbf18dc5 5490 int attribute;
980f185c 5491 int cfi_attribute;
bbf18dc5
PT
5492 symbol_attribute attr = gfc_expr_attr (e);
5493
5494 /* If this is a full array or a scalar, the allocatable and pointer
5495 attributes can be passed. Otherwise it is 'CFI_attribute_other'*/
5496 attribute = 2;
5497 if (!e->rank || gfc_get_full_arrayspec_from_expr (e))
5498 {
980f185c 5499 if (attr.pointer)
bbf18dc5 5500 attribute = 0;
980f185c 5501 else if (attr.allocatable)
bbf18dc5
PT
5502 attribute = 1;
5503 }
5504
0cbf0368
TB
5505 if (fsym->attr.pointer)
5506 cfi_attribute = 0;
5507 else if (fsym->attr.allocatable)
5508 cfi_attribute = 1;
980f185c 5509 else
0cbf0368 5510 cfi_attribute = 2;
980f185c 5511
db06a76e 5512 if (e->rank != 0)
bbf18dc5 5513 {
0a524296 5514 parmse->force_no_tmp = 1;
9d52e1bb
TK
5515 if (fsym->attr.contiguous
5516 && !gfc_is_simply_contiguous (e, false, true))
5517 gfc_conv_subref_array_arg (parmse, e, false, fsym->attr.intent,
5518 fsym->attr.pointer);
5519 else
5520 gfc_conv_expr_descriptor (parmse, e);
bbf18dc5 5521
92f3a180
PT
5522 if (POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
5523 parmse->expr = build_fold_indirect_ref_loc (input_location,
5524 parmse->expr);
6409a3c0
TB
5525 bool is_artificial = (INDIRECT_REF_P (parmse->expr)
5526 ? DECL_ARTIFICIAL (TREE_OPERAND (parmse->expr, 0))
5527 : DECL_ARTIFICIAL (parmse->expr));
92f3a180 5528
0e308880
PT
5529 /* Unallocated allocatable arrays and unassociated pointer arrays
5530 need their dtype setting if they are argument associated with
5531 assumed rank dummies. */
5532 if (fsym && fsym->as
0e308880
PT
5533 && (gfc_expr_attr (e).pointer
5534 || gfc_expr_attr (e).allocatable))
5535 set_dtype_for_unallocated (parmse, e);
5536
bbf18dc5
PT
5537 /* All the temporary descriptors are marked as DECL_ARTIFICIAL. If
5538 the expression type is different from the descriptor type, then
5539 the offset must be found (eg. to a component ref or substring)
db06a76e
PT
5540 and the dtype updated. Assumed type entities are only allowed
5541 to be dummies in Fortran. They therefore lack the decl specific
5542 appendiges and so must be treated differently from other fortran
5543 entities passed to CFI descriptors in the interface decl. */
5544 type = e->ts.type != BT_ASSUMED ? gfc_typenode_for_spec (&e->ts) :
5545 NULL_TREE;
5546
6409a3c0 5547 if (type && is_artificial
bbf18dc5
PT
5548 && type != gfc_get_element_type (TREE_TYPE (parmse->expr)))
5549 {
5550 /* Obtain the offset to the data. */
5551 gfc_get_dataptr_offset (&parmse->pre, parmse->expr, parmse->expr,
5552 gfc_index_zero_node, true, e);
5553
5554 /* Update the dtype. */
5555 gfc_add_modify (&parmse->pre,
5556 gfc_conv_descriptor_dtype (parmse->expr),
5557 gfc_get_dtype_rank_type (e->rank, type));
5558 }
db06a76e 5559 else if (type == NULL_TREE
6409a3c0 5560 || (!is_subref_array (e) && !is_artificial))
bbf18dc5
PT
5561 {
5562 /* Make sure that the span is set for expressions where it
5563 might not have been done already. */
db06a76e 5564 tmp = gfc_conv_descriptor_elem_len (parmse->expr);
bbf18dc5
PT
5565 tmp = fold_convert (gfc_array_index_type, tmp);
5566 gfc_conv_descriptor_span_set (&parmse->pre, parmse->expr, tmp);
5567 }
5568 }
5569 else
5570 {
5571 gfc_conv_expr (parmse, e);
92f3a180
PT
5572
5573 if (POINTER_TYPE_P (TREE_TYPE (parmse->expr)))
5574 parmse->expr = build_fold_indirect_ref_loc (input_location,
5575 parmse->expr);
5576
bbf18dc5
PT
5577 parmse->expr = gfc_conv_scalar_to_descriptor (parmse,
5578 parmse->expr, attr);
5579 }
5580
980f185c
PT
5581 /* Set the CFI attribute field through a temporary value for the
5582 gfc attribute. */
5583 desc_attr = gfc_conv_descriptor_attribute (parmse->expr);
bbf18dc5 5584 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
980f185c
PT
5585 void_type_node, desc_attr,
5586 build_int_cst (TREE_TYPE (desc_attr), cfi_attribute));
bbf18dc5
PT
5587 gfc_add_expr_to_block (&parmse->pre, tmp);
5588
5589 /* Now pass the gfc_descriptor by reference. */
5590 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5591
fc5a9708
TB
5592 /* Variables to point to the gfc and CFI descriptors; cfi = NULL implies
5593 that the CFI descriptor is allocated by the gfor_fndecl_gfc_to_cfi call. */
bbf18dc5
PT
5594 gfc_desc_ptr = parmse->expr;
5595 cfi_desc_ptr = gfc_create_var (pvoid_type_node, "cfi");
fc5a9708 5596 gfc_add_modify (&parmse->pre, cfi_desc_ptr, null_pointer_node);
bbf18dc5 5597
fc5a9708 5598 /* Allocate the CFI descriptor itself and fill the fields. */
bbf18dc5
PT
5599 tmp = gfc_build_addr_expr (NULL_TREE, cfi_desc_ptr);
5600 tmp = build_call_expr_loc (input_location,
5601 gfor_fndecl_gfc_to_cfi, 2, tmp, gfc_desc_ptr);
5602 gfc_add_expr_to_block (&parmse->pre, tmp);
5603
980f185c
PT
5604 /* Now set the gfc descriptor attribute. */
5605 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
5606 void_type_node, desc_attr,
5607 build_int_cst (TREE_TYPE (desc_attr), attribute));
5608 gfc_add_expr_to_block (&parmse->pre, tmp);
5609
bbf18dc5
PT
5610 /* The CFI descriptor is passed to the bind_C procedure. */
5611 parmse->expr = cfi_desc_ptr;
5612
fc5a9708
TB
5613 /* Free the CFI descriptor. */
5614 tmp = gfc_call_free (cfi_desc_ptr);
5615 gfc_prepend_expr_to_block (&parmse->post, tmp);
5616
0d78e4aa 5617 /* Transfer values back to gfc descriptor. */
0cbf0368
TB
5618 if (cfi_attribute != 2 /* CFI_attribute_other. */
5619 && !fsym->attr.value
5620 && fsym->attr.intent != INTENT_IN)
5621 {
5622 tmp = gfc_build_addr_expr (NULL_TREE, parmse->expr);
5623 tmp = build_call_expr_loc (input_location,
5624 gfor_fndecl_cfi_to_gfc, 2, gfc_desc_ptr, tmp);
5625 gfc_prepend_expr_to_block (&parmse->post, tmp);
5626 }
980f185c
PT
5627
5628 /* Deal with an optional dummy being passed to an optional formal arg
5629 by finishing the pre and post blocks and making their execution
5630 conditional on the dummy being present. */
5631 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
5632 && e->symtree->n.sym->attr.optional)
5633 {
5634 cond = gfc_conv_expr_present (e->symtree->n.sym);
5635 tmp = fold_build2 (MODIFY_EXPR, void_type_node,
5636 cfi_desc_ptr,
5637 build_int_cst (pvoid_type_node, 0));
5638 tmp = build3_v (COND_EXPR, cond,
5639 gfc_finish_block (&parmse->pre), tmp);
5640 gfc_add_expr_to_block (&parmse->pre, tmp);
5641 tmp = build3_v (COND_EXPR, cond,
5642 gfc_finish_block (&parmse->post),
5643 build_empty_stmt (input_location));
5644 gfc_add_expr_to_block (&parmse->post, tmp);
5645 }
bbf18dc5
PT
5646}
5647
5648
6de9cd9a 5649/* Generate code for a procedure call. Note can return se->post != NULL.
dda895f9 5650 If se->direct_byref is set then se->expr contains the return parameter.
713485cc
JW
5651 Return nonzero, if the call has alternate specifiers.
5652 'expr' is only needed for procedure pointer components. */
6de9cd9a 5653
dda895f9 5654int
713485cc 5655gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
0b4f2770 5656 gfc_actual_arglist * args, gfc_expr * expr,
9771b263 5657 vec<tree, va_gc> *append_args)
6de9cd9a 5658{
0348d6fd 5659 gfc_interface_mapping mapping;
9771b263
DN
5660 vec<tree, va_gc> *arglist;
5661 vec<tree, va_gc> *retargs;
6de9cd9a
DN
5662 tree tmp;
5663 tree fntype;
5664 gfc_se parmse;
6d63e468 5665 gfc_array_info *info;
6de9cd9a 5666 int byref;
5046aff5 5667 int parm_kind;
6de9cd9a
DN
5668 tree type;
5669 tree var;
5670 tree len;
94fae14b 5671 tree base_object;
9771b263 5672 vec<tree, va_gc> *stringargs;
60f97ac8 5673 vec<tree, va_gc> *optionalargs;
40c32948 5674 tree result = NULL;
6de9cd9a 5675 gfc_formal_arglist *formal;
0b4f2770 5676 gfc_actual_arglist *arg;
dda895f9 5677 int has_alternate_specifier = 0;
0348d6fd 5678 bool need_interface_mapping;
8e119f1b 5679 bool callee_alloc;
1792349b 5680 bool ulim_copy;
0348d6fd
RS
5681 gfc_typespec ts;
5682 gfc_charlen cl;
e15e9be3
PT
5683 gfc_expr *e;
5684 gfc_symbol *fsym;
f5f701ad 5685 stmtblock_t post;
5046aff5 5686 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
c74b74a8 5687 gfc_component *comp = NULL;
989ea525 5688 int arglen;
1792349b 5689 unsigned int argc;
6de9cd9a 5690
989ea525
NF
5691 arglist = NULL;
5692 retargs = NULL;
5693 stringargs = NULL;
60f97ac8 5694 optionalargs = NULL;
6de9cd9a
DN
5695 var = NULL_TREE;
5696 len = NULL_TREE;
44000dbb 5697 gfc_clear_ts (&ts);
6de9cd9a 5698
2a573572 5699 comp = gfc_get_proc_ptr_comp (expr);
f64edc8b 5700
0e1f8c6a
MM
5701 bool elemental_proc = (comp
5702 && comp->ts.interface
5703 && comp->ts.interface->attr.elemental)
5704 || (comp && comp->attr.elemental)
5705 || sym->attr.elemental;
5706
6de9cd9a
DN
5707 if (se->ss != NULL)
5708 {
0e1f8c6a 5709 if (!elemental_proc)
6de9cd9a 5710 {
bcc4d4e0 5711 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
7a412892 5712 if (se->ss->info->useflags)
f7172b55 5713 {
f64edc8b
JW
5714 gcc_assert ((!comp && gfc_return_by_reference (sym)
5715 && sym->result->attr.dimension)
43a68a9d 5716 || (comp && comp->attr.dimension)
a6b22eea 5717 || gfc_is_class_array_function (expr));
f7172b55 5718 gcc_assert (se->loop != NULL);
f7172b55
PT
5719 /* Access the previously obtained result. */
5720 gfc_conv_tmp_array_ref (se);
f7172b55
PT
5721 return 0;
5722 }
6de9cd9a 5723 }
1838afec 5724 info = &se->ss->info->data.array;
6de9cd9a
DN
5725 }
5726 else
5727 info = NULL;
5728
f5f701ad 5729 gfc_init_block (&post);
0348d6fd 5730 gfc_init_interface_mapping (&mapping);
50dbf0b4
JW
5731 if (!comp)
5732 {
4cbc9039 5733 formal = gfc_sym_get_dummy_args (sym);
50dbf0b4
JW
5734 need_interface_mapping = sym->attr.dimension ||
5735 (sym->ts.type == BT_CHARACTER
5736 && sym->ts.u.cl->length
5737 && sym->ts.u.cl->length->expr_type
5738 != EXPR_CONSTANT);
5739 }
acbdc378 5740 else
50dbf0b4 5741 {
4cbc9039 5742 formal = comp->ts.interface ? comp->ts.interface->formal : NULL;
50dbf0b4
JW
5743 need_interface_mapping = comp->attr.dimension ||
5744 (comp->ts.type == BT_CHARACTER
5745 && comp->ts.u.cl->length
5746 && comp->ts.u.cl->length->expr_type
5747 != EXPR_CONSTANT);
5748 }
5749
94fae14b 5750 base_object = NULL_TREE;
1792349b
AV
5751 /* For _vprt->_copy () routines no formal symbol is present. Nevertheless
5752 is the third and fourth argument to such a function call a value
5753 denoting the number of elements to copy (i.e., most of the time the
5754 length of a deferred length string). */
e520d5f0
PT
5755 ulim_copy = (formal == NULL)
5756 && UNLIMITED_POLY (sym)
5757 && comp && (strcmp ("_copy", comp->name) == 0);
94fae14b 5758
6de9cd9a 5759 /* Evaluate the arguments. */
1792349b
AV
5760 for (arg = args, argc = 0; arg != NULL;
5761 arg = arg->next, formal = formal ? formal->next : NULL, ++argc)
6de9cd9a 5762 {
1312bb90 5763 bool finalized = false;
b3d4011b 5764 bool assumed_length_string = false;
5159b88e 5765 tree derived_array = NULL_TREE;
1312bb90 5766
e15e9be3
PT
5767 e = arg->expr;
5768 fsym = formal ? formal->sym : NULL;
5046aff5 5769 parm_kind = MISSING;
f7172b55 5770
b3d4011b
TB
5771 if (fsym && fsym->ts.type == BT_CHARACTER
5772 && (!fsym->ts.u.cl || !fsym->ts.u.cl->length))
5773 assumed_length_string = true;
c2808389 5774
0e1f8c6a
MM
5775 /* If the procedure requires an explicit interface, the actual
5776 argument is passed according to the corresponding formal
5777 argument. If the corresponding formal argument is a POINTER,
5778 ALLOCATABLE or assumed shape, we do not use g77's calling
5779 convention, and pass the address of the array descriptor
5780 instead. Otherwise we use g77's calling convention, in other words
5781 pass the array data pointer without descriptor. */
5782 bool nodesc_arg = fsym != NULL
5783 && !(fsym->attr.pointer || fsym->attr.allocatable)
5784 && fsym->as
5785 && fsym->as->type != AS_ASSUMED_SHAPE
5786 && fsym->as->type != AS_ASSUMED_RANK;
5787 if (comp)
5788 nodesc_arg = nodesc_arg || !comp->attr.always_explicit;
5789 else
5790 nodesc_arg = nodesc_arg || !sym->attr.always_explicit;
5791
c49ea23d
PT
5792 /* Class array expressions are sometimes coming completely unadorned
5793 with either arrayspec or _data component. Correct that here.
5794 OOP-TODO: Move this to the frontend. */
5795 if (e && e->expr_type == EXPR_VARIABLE
5796 && !e->ref
5797 && e->ts.type == BT_CLASS
16e82b25
TB
5798 && (CLASS_DATA (e)->attr.codimension
5799 || CLASS_DATA (e)->attr.dimension))
c49ea23d
PT
5800 {
5801 gfc_typespec temp_ts = e->ts;
5802 gfc_add_class_array_ref (e);
5803 e->ts = temp_ts;
5804 }
5805
e15e9be3 5806 if (e == NULL)
6de9cd9a 5807 {
6de9cd9a
DN
5808 if (se->ignore_optional)
5809 {
5810 /* Some intrinsics have already been resolved to the correct
5811 parameters. */
5812 continue;
5813 }
5814 else if (arg->label)
5815 {
f7172b55
PT
5816 has_alternate_specifier = 1;
5817 continue;
6de9cd9a
DN
5818 }
5819 else
5820 {
6de9cd9a 5821 gfc_init_se (&parmse, NULL);
60f97ac8
TB
5822
5823 /* For scalar arguments with VALUE attribute which are passed by
5824 value, pass "0" and a hidden argument gives the optional
5825 status. */
5826 if (fsym && fsym->attr.optional && fsym->attr.value
5827 && !fsym->attr.dimension && fsym->ts.type != BT_CHARACTER
5828 && fsym->ts.type != BT_CLASS && fsym->ts.type != BT_DERIVED)
5829 {
5830 parmse.expr = fold_convert (gfc_sym_type (fsym),
5831 integer_zero_node);
5832 vec_safe_push (optionalargs, boolean_false_node);
5833 }
5834 else
5835 {
5836 /* Pass a NULL pointer for an absent arg. */
5837 parmse.expr = null_pointer_node;
5838 if (arg->missing_arg_type == BT_CHARACTER)
5839 parmse.string_length = build_int_cst (gfc_charlen_type_node,
5840 0);
5841 }
6de9cd9a
DN
5842 }
5843 }
3d333a28
TB
5844 else if (arg->expr->expr_type == EXPR_NULL
5845 && fsym && !fsym->attr.pointer
5846 && (fsym->ts.type != BT_CLASS
5847 || !CLASS_DATA (fsym)->attr.class_pointer))
08857b61
TB
5848 {
5849 /* Pass a NULL pointer to denote an absent arg. */
3d333a28
TB
5850 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable
5851 && (fsym->ts.type != BT_CLASS
5852 || !CLASS_DATA (fsym)->attr.allocatable));
08857b61
TB
5853 gfc_init_se (&parmse, NULL);
5854 parmse.expr = null_pointer_node;
5855 if (arg->missing_arg_type == BT_CHARACTER)
5856 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
5857 }
cf2b3c22
TB
5858 else if (fsym && fsym->ts.type == BT_CLASS
5859 && e->ts.type == BT_DERIVED)
5860 {
cf2b3c22
TB
5861 /* The derived type needs to be converted to a temporary
5862 CLASS object. */
5863 gfc_init_se (&parmse, se);
16e82b25
TB
5864 gfc_conv_derived_to_class (&parmse, e, fsym->ts, NULL,
5865 fsym->attr.optional
5866 && e->expr_type == EXPR_VARIABLE
5867 && e->symtree->n.sym->attr.optional,
5868 CLASS_DATA (fsym)->attr.class_pointer
5159b88e
PT
5869 || CLASS_DATA (fsym)->attr.allocatable,
5870 &derived_array);
cf2b3c22 5871 }
4225af22 5872 else if (UNLIMITED_POLY (fsym) && e->ts.type != BT_CLASS
fe03f4fc
HA
5873 && e->ts.type != BT_PROCEDURE
5874 && (gfc_expr_attr (e).flavor != FL_PROCEDURE
5875 || gfc_expr_attr (e).proc != PROC_UNKNOWN))
8b704316
PT
5876 {
5877 /* The intrinsic type needs to be converted to a temporary
5878 CLASS object for the unlimited polymorphic formal. */
ce8dcc91 5879 gfc_find_vtab (&e->ts);
8b704316
PT
5880 gfc_init_se (&parmse, se);
5881 gfc_conv_intrinsic_to_class (&parmse, e, fsym->ts);
ce8dcc91 5882
8b704316 5883 }
7a412892 5884 else if (se->ss && se->ss->info->useflags)
6de9cd9a 5885 {
8b59af5c
MM
5886 gfc_ss *ss;
5887
5888 ss = se->ss;
5889
6de9cd9a 5890 /* An elemental function inside a scalarized loop. */
f7172b55 5891 gfc_init_se (&parmse, se);
5046aff5 5892 parm_kind = ELEMENTAL;
fafcf9e6 5893
1792349b
AV
5894 /* When no fsym is present, ulim_copy is set and this is a third or
5895 fourth argument, use call-by-value instead of by reference to
5896 hand the length properties to the copy routine (i.e., most of the
5897 time this will be a call to a __copy_character_* routine where the
5898 third and fourth arguments are the lengths of a deferred length
5899 char array). */
5900 if ((fsym && fsym->attr.value)
5901 || (ulim_copy && (argc == 2 || argc == 3)))
56c78e5c
PT
5902 gfc_conv_expr (&parmse, e);
5903 else
5904 gfc_conv_expr_reference (&parmse, e);
5905
37ea263a
MM
5906 if (e->ts.type == BT_CHARACTER && !e->rank
5907 && e->expr_type == EXPR_FUNCTION)
5908 parmse.expr = build_fold_indirect_ref_loc (input_location,
5909 parmse.expr);
c49ea23d 5910
5bf5fa56
MM
5911 if (fsym && fsym->ts.type == BT_DERIVED
5912 && gfc_is_class_container_ref (e))
16e82b25
TB
5913 {
5914 parmse.expr = gfc_class_data_get (parmse.expr);
5915
5916 if (fsym->attr.optional && e->expr_type == EXPR_VARIABLE
5917 && e->symtree->n.sym->attr.optional)
5918 {
5919 tree cond = gfc_conv_expr_present (e->symtree->n.sym);
5920 parmse.expr = build3_loc (input_location, COND_EXPR,
5921 TREE_TYPE (parmse.expr),
5922 cond, parmse.expr,
5923 fold_convert (TREE_TYPE (parmse.expr),
5924 null_pointer_node));
5925 }
5926 }
5bf5fa56 5927
8b59af5c
MM
5928 /* If we are passing an absent array as optional dummy to an
5929 elemental procedure, make sure that we pass NULL when the data
5930 pointer is NULL. We need this extra conditional because of
5931 scalarization which passes arrays elements to the procedure,
5932 ignoring the fact that the array can be absent/unallocated/... */
5933 if (ss->info->can_be_null_ref && ss->info->type != GFC_SS_REFERENCE)
5934 {
5935 tree descriptor_data;
5936
5937 descriptor_data = ss->info->data.array.data;
63ee5404 5938 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
8b59af5c
MM
5939 descriptor_data,
5940 fold_convert (TREE_TYPE (descriptor_data),
5941 null_pointer_node));
5942 parmse.expr
5943 = fold_build3_loc (input_location, COND_EXPR,
5944 TREE_TYPE (parmse.expr),
ed9c79e1 5945 gfc_unlikely (tmp, PRED_FORTRAN_ABSENT_DUMMY),
8b704316 5946 fold_convert (TREE_TYPE (parmse.expr),
8b59af5c
MM
5947 null_pointer_node),
5948 parmse.expr);
5949 }
5950
c49ea23d
PT
5951 /* The scalarizer does not repackage the reference to a class
5952 array - instead it returns a pointer to the data element. */
5953 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
16e82b25
TB
5954 gfc_conv_class_to_class (&parmse, e, fsym->ts, true,
5955 fsym->attr.intent != INTENT_IN
5956 && (CLASS_DATA (fsym)->attr.class_pointer
5957 || CLASS_DATA (fsym)->attr.allocatable),
5958 fsym->attr.optional
5959 && e->expr_type == EXPR_VARIABLE
5960 && e->symtree->n.sym->attr.optional,
5961 CLASS_DATA (fsym)->attr.class_pointer
5962 || CLASS_DATA (fsym)->attr.allocatable);
6de9cd9a
DN
5963 }
5964 else
5965 {
2960a368
TB
5966 bool scalar;
5967 gfc_ss *argss;
5968
16e82b25
TB
5969 gfc_init_se (&parmse, NULL);
5970
2960a368
TB
5971 /* Check whether the expression is a scalar or not; we cannot use
5972 e->rank as it can be nonzero for functions arguments. */
e15e9be3 5973 argss = gfc_walk_expr (e);
2960a368
TB
5974 scalar = argss == gfc_ss_terminator;
5975 if (!scalar)
5976 gfc_free_ss_chain (argss);
6de9cd9a 5977
16e82b25
TB
5978 /* Special handling for passing scalar polymorphic coarrays;
5979 otherwise one passes "class->_data.data" instead of "&class". */
5980 if (e->rank == 0 && e->ts.type == BT_CLASS
5981 && fsym && fsym->ts.type == BT_CLASS
5982 && CLASS_DATA (fsym)->attr.codimension
5983 && !CLASS_DATA (fsym)->attr.dimension)
5984 {
5985 gfc_add_class_array_ref (e);
5986 parmse.want_coarray = 1;
5987 scalar = false;
5988 }
5989
2960a368 5990 /* A scalar or transformational function. */
2960a368 5991 if (scalar)
f7172b55 5992 {
686c82b5
PT
5993 if (e->expr_type == EXPR_VARIABLE
5994 && e->symtree->n.sym->attr.cray_pointee
5995 && fsym && fsym->attr.flavor == FL_PROCEDURE)
5996 {
5997 /* The Cray pointer needs to be converted to a pointer to
5998 a type given by the expression. */
5999 gfc_conv_expr (&parmse, e);
6000 type = build_pointer_type (TREE_TYPE (parmse.expr));
6001 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
6002 parmse.expr = convert (type, tmp);
6003 }
bbf18dc5
PT
6004
6005 else if (sym->attr.is_bind_c && e
0d78e4aa 6006 && (is_CFI_desc (fsym, NULL)
b3d4011b
TB
6007 || assumed_length_string))
6008 /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
bbf18dc5
PT
6009 gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
6010
6011 else if (fsym && fsym->attr.value)
06469efd 6012 {
e032c2a1
CR
6013 if (fsym->ts.type == BT_CHARACTER
6014 && fsym->ts.is_c_interop
6015 && fsym->ns->proc_name != NULL
6016 && fsym->ns->proc_name->attr.is_bind_c)
6017 {
6018 parmse.expr = NULL;
6019 gfc_conv_scalar_char_value (fsym, &parmse, &e);
6020 if (parmse.expr == NULL)
6021 gfc_conv_expr (&parmse, e);
6022 }
6023 else
60f97ac8 6024 {
e032c2a1 6025 gfc_conv_expr (&parmse, e);
60f97ac8
TB
6026 if (fsym->attr.optional
6027 && fsym->ts.type != BT_CLASS
6028 && fsym->ts.type != BT_DERIVED)
6029 {
6030 if (e->expr_type != EXPR_VARIABLE
6031 || !e->symtree->n.sym->attr.optional
6032 || e->ref != NULL)
6033 vec_safe_push (optionalargs, boolean_true_node);
6034 else
6035 {
6036 tmp = gfc_conv_expr_present (e->symtree->n.sym);
6037 if (!e->symtree->n.sym->attr.value)
6038 parmse.expr
6039 = fold_build3_loc (input_location, COND_EXPR,
6040 TREE_TYPE (parmse.expr),
6041 tmp, parmse.expr,
6042 fold_convert (TREE_TYPE (parmse.expr),
6043 integer_zero_node));
6044
b0896310
TB
6045 vec_safe_push (optionalargs,
6046 fold_convert (boolean_type_node,
6047 tmp));
60f97ac8
TB
6048 }
6049 }
6050 }
06469efd 6051 }
bbf18dc5 6052
7fcafa71
PT
6053 else if (arg->name && arg->name[0] == '%')
6054 /* Argument list functions %VAL, %LOC and %REF are signalled
6055 through arg->name. */
6056 conv_arglist_function (&parmse, arg->expr, arg->name);
6a661315 6057 else if ((e->expr_type == EXPR_FUNCTION)
e6524a51
TB
6058 && ((e->value.function.esym
6059 && e->value.function.esym->result->attr.pointer)
6060 || (!e->value.function.esym
6061 && e->symtree->n.sym->attr.pointer))
6062 && fsym && fsym->attr.target)
b020cee5
JRFS
6063 /* Make sure the function only gets called once. */
6064 gfc_conv_expr_reference (&parmse, e, false);
a7c0b11d
JW
6065 else if (e->expr_type == EXPR_FUNCTION
6066 && e->symtree->n.sym->result
23878536 6067 && e->symtree->n.sym->result != e->symtree->n.sym
a7c0b11d
JW
6068 && e->symtree->n.sym->result->attr.proc_pointer)
6069 {
6070 /* Functions returning procedure pointers. */
6071 gfc_conv_expr (&parmse, e);
6072 if (fsym && fsym->attr.proc_pointer)
6073 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6074 }
bbf18dc5 6075
06469efd
PT
6076 else
6077 {
16e82b25
TB
6078 if (e->ts.type == BT_CLASS && fsym
6079 && fsym->ts.type == BT_CLASS
6080 && (!CLASS_DATA (fsym)->as
6081 || CLASS_DATA (fsym)->as->type != AS_ASSUMED_RANK)
6082 && CLASS_DATA (e)->attr.codimension)
6083 {
6084 gcc_assert (!CLASS_DATA (fsym)->attr.codimension);
6085 gcc_assert (!CLASS_DATA (fsym)->as);
6086 gfc_add_class_array_ref (e);
6087 parmse.want_coarray = 1;
6088 gfc_conv_expr_reference (&parmse, e);
6089 class_scalar_coarray_to_class (&parmse, e, fsym->ts,
6090 fsym->attr.optional
6091 && e->expr_type == EXPR_VARIABLE);
6092 }
301375fd
BE
6093 else if (e->ts.type == BT_CLASS && fsym
6094 && fsym->ts.type == BT_CLASS
6095 && !CLASS_DATA (fsym)->as
6096 && !CLASS_DATA (e)->as
62c4c81a
BE
6097 && strcmp (fsym->ts.u.derived->name,
6098 e->ts.u.derived->name))
301375fd
BE
6099 {
6100 type = gfc_typenode_for_spec (&fsym->ts);
6101 var = gfc_create_var (type, fsym->name);
6102 gfc_conv_expr (&parmse, e);
6103 if (fsym->attr.optional
6104 && e->expr_type == EXPR_VARIABLE
6105 && e->symtree->n.sym->attr.optional)
6106 {
6107 stmtblock_t block;
6108 tree cond;
6109 tmp = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6110 cond = fold_build2_loc (input_location, NE_EXPR,
63ee5404 6111 logical_type_node, tmp,
301375fd
BE
6112 fold_convert (TREE_TYPE (tmp),
6113 null_pointer_node));
6114 gfc_start_block (&block);
6115 gfc_add_modify (&block, var,
6116 fold_build1_loc (input_location,
6117 VIEW_CONVERT_EXPR,
6118 type, parmse.expr));
6119 gfc_add_expr_to_block (&parmse.pre,
6120 fold_build3_loc (input_location,
6121 COND_EXPR, void_type_node,
6122 cond, gfc_finish_block (&block),
6123 build_empty_stmt (input_location)));
6124 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6125 parmse.expr = build3_loc (input_location, COND_EXPR,
6126 TREE_TYPE (parmse.expr),
6127 cond, parmse.expr,
6128 fold_convert (TREE_TYPE (parmse.expr),
6129 null_pointer_node));
6130 }
6131 else
6132 {
59d7953a
PT
6133 /* Since the internal representation of unlimited
6134 polymorphic expressions includes an extra field
6135 that other class objects do not, a cast to the
6136 formal type does not work. */
6137 if (!UNLIMITED_POLY (e) && UNLIMITED_POLY (fsym))
6138 {
6139 tree efield;
6140
6141 /* Set the _data field. */
6142 tmp = gfc_class_data_get (var);
6143 efield = fold_convert (TREE_TYPE (tmp),
6144 gfc_class_data_get (parmse.expr));
6145 gfc_add_modify (&parmse.pre, tmp, efield);
6146
6147 /* Set the _vptr field. */
6148 tmp = gfc_class_vptr_get (var);
6149 efield = fold_convert (TREE_TYPE (tmp),
6150 gfc_class_vptr_get (parmse.expr));
6151 gfc_add_modify (&parmse.pre, tmp, efield);
6152
6153 /* Set the _len field. */
6154 tmp = gfc_class_len_get (var);
6155 gfc_add_modify (&parmse.pre, tmp,
6156 build_int_cst (TREE_TYPE (tmp), 0));
6157 }
6158 else
6159 {
6160 tmp = fold_build1_loc (input_location,
6161 VIEW_CONVERT_EXPR,
6162 type, parmse.expr);
6163 gfc_add_modify (&parmse.pre, var, tmp);
6164 ;
6165 }
301375fd
BE
6166 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
6167 }
6168 }
16e82b25 6169 else
056e6860
TK
6170 {
6171 bool add_clobber;
6172 add_clobber = fsym && fsym->attr.intent == INTENT_OUT
6173 && !fsym->attr.allocatable && !fsym->attr.pointer
a8b79cc9 6174 && e->symtree && e->symtree->n.sym
5986c254 6175 && !e->symtree->n.sym->attr.dimension
056e6860 6176 && !e->symtree->n.sym->attr.pointer
2df374b3 6177 && !e->symtree->n.sym->attr.allocatable
ee7fb058
TK
6178 /* See PR 41453. */
6179 && !e->symtree->n.sym->attr.dummy
6180 /* FIXME - PR 87395 and PR 41453 */
b093d688 6181 && e->symtree->n.sym->attr.save == SAVE_NONE
c1093623 6182 && !e->symtree->n.sym->attr.associate_var
056e6860
TK
6183 && e->ts.type != BT_CHARACTER && e->ts.type != BT_DERIVED
6184 && e->ts.type != BT_CLASS && !sym->attr.elemental;
6185
6186 gfc_conv_expr_reference (&parmse, e, add_clobber);
6187 }
94fae14b
PT
6188 /* Catch base objects that are not variables. */
6189 if (e->ts.type == BT_CLASS
6190 && e->expr_type != EXPR_VARIABLE
6191 && expr && e == expr->base_expr)
6192 base_object = build_fold_indirect_ref_loc (input_location,
6193 parmse.expr);
6194
c49ea23d
PT
6195 /* A class array element needs converting back to be a
6196 class object, if the formal argument is a class object. */
6197 if (fsym && fsym->ts.type == BT_CLASS
6198 && e->ts.type == BT_CLASS
c62c6622
TB
6199 && ((CLASS_DATA (fsym)->as
6200 && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
6201 || CLASS_DATA (e)->attr.dimension))
16e82b25
TB
6202 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
6203 fsym->attr.intent != INTENT_IN
6204 && (CLASS_DATA (fsym)->attr.class_pointer
6205 || CLASS_DATA (fsym)->attr.allocatable),
6206 fsym->attr.optional
6207 && e->expr_type == EXPR_VARIABLE
6208 && e->symtree->n.sym->attr.optional,
6209 CLASS_DATA (fsym)->attr.class_pointer
6210 || CLASS_DATA (fsym)->attr.allocatable);
c49ea23d 6211
8b704316 6212 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
958dd42b 6213 allocated on entry, it must be deallocated. */
99c25a87
TB
6214 if (fsym && fsym->attr.intent == INTENT_OUT
6215 && (fsym->attr.allocatable
6216 || (fsym->ts.type == BT_CLASS
7df938d6 6217 && CLASS_DATA (fsym)->attr.allocatable)))
958dd42b
TB
6218 {
6219 stmtblock_t block;
99c25a87 6220 tree ptr;
958dd42b
TB
6221
6222 gfc_init_block (&block);
99c25a87
TB
6223 ptr = parmse.expr;
6224 if (e->ts.type == BT_CLASS)
8b704316 6225 ptr = gfc_class_data_get (ptr);
99c25a87 6226
ef292537 6227 tmp = gfc_deallocate_scalar_with_status (ptr, NULL_TREE,
ba85c8c3
AV
6228 NULL_TREE, true,
6229 e, e->ts);
958dd42b 6230 gfc_add_expr_to_block (&block, tmp);
65a9ca82 6231 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
99c25a87 6232 void_type_node, ptr,
65a9ca82 6233 null_pointer_node);
958dd42b
TB
6234 gfc_add_expr_to_block (&block, tmp);
6235
4038d0fb
TB
6236 if (fsym->ts.type == BT_CLASS && UNLIMITED_POLY (fsym))
6237 {
6238 gfc_add_modify (&block, ptr,
6239 fold_convert (TREE_TYPE (ptr),
6240 null_pointer_node));
6241 gfc_add_expr_to_block (&block, tmp);
6242 }
6243 else if (fsym->ts.type == BT_CLASS)
99c25a87
TB
6244 {
6245 gfc_symbol *vtab;
99c25a87
TB
6246 vtab = gfc_find_derived_vtab (fsym->ts.u.derived);
6247 tmp = gfc_get_symbol_decl (vtab);
6248 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
6249 ptr = gfc_class_vptr_get (parmse.expr);
6250 gfc_add_modify (&block, ptr,
6251 fold_convert (TREE_TYPE (ptr), tmp));
6252 gfc_add_expr_to_block (&block, tmp);
6253 }
6254
958dd42b
TB
6255 if (fsym->attr.optional
6256 && e->expr_type == EXPR_VARIABLE
6257 && e->symtree->n.sym->attr.optional)
6258 {
65a9ca82
TB
6259 tmp = fold_build3_loc (input_location, COND_EXPR,
6260 void_type_node,
958dd42b
TB
6261 gfc_conv_expr_present (e->symtree->n.sym),
6262 gfc_finish_block (&block),
6263 build_empty_stmt (input_location));
6264 }
6265 else
6266 tmp = gfc_finish_block (&block);
6267
6268 gfc_add_expr_to_block (&se->pre, tmp);
6269 }
6270
7780fd2a
JW
6271 if (fsym && (fsym->ts.type == BT_DERIVED
6272 || fsym->ts.type == BT_ASSUMED)
6273 && e->ts.type == BT_CLASS
6274 && !CLASS_DATA (e)->attr.dimension
6275 && !CLASS_DATA (e)->attr.codimension)
1312bb90
PT
6276 {
6277 parmse.expr = gfc_class_data_get (parmse.expr);
6278 /* The result is a class temporary, whose _data component
6279 must be freed to avoid a memory leak. */
6280 if (e->expr_type == EXPR_FUNCTION
6281 && CLASS_DATA (e)->attr.allocatable)
6282 {
6283 tree zero;
6284
6285 gfc_expr *var;
6286
6287 /* Borrow the function symbol to make a call to
6288 gfc_add_finalizer_call and then restore it. */
6289 tmp = e->symtree->n.sym->backend_decl;
6290 e->symtree->n.sym->backend_decl
6291 = TREE_OPERAND (parmse.expr, 0);
6292 e->symtree->n.sym->attr.flavor = FL_VARIABLE;
6293 var = gfc_lval_expr_from_sym (e->symtree->n.sym);
6294 finalized = gfc_add_finalizer_call (&parmse.post,
6295 var);
6296 gfc_free_expr (var);
6297 e->symtree->n.sym->backend_decl = tmp;
6298 e->symtree->n.sym->attr.flavor = FL_PROCEDURE;
6299
6300 /* Then free the class _data. */
6301 zero = build_int_cst (TREE_TYPE (parmse.expr), 0);
6302 tmp = fold_build2_loc (input_location, NE_EXPR,
6303 logical_type_node,
6304 parmse.expr, zero);
6305 tmp = build3_v (COND_EXPR, tmp,
6306 gfc_call_free (parmse.expr),
6307 build_empty_stmt (input_location));
6308 gfc_add_expr_to_block (&parmse.post, tmp);
6309 gfc_add_modify (&parmse.post, parmse.expr, zero);
6310 }
6311 }
7780fd2a 6312
c62c6622
TB
6313 /* Wrap scalar variable in a descriptor. We need to convert
6314 the address of a pointer back to the pointer itself before,
6315 we can assign it to the data field. */
6316
6317 if (fsym && fsym->as && fsym->as->type == AS_ASSUMED_RANK
6318 && fsym->ts.type != BT_CLASS && e->expr_type != EXPR_NULL)
6319 {
6320 tmp = parmse.expr;
1af73491
PT
6321 if (TREE_CODE (tmp) == ADDR_EXPR)
6322 tmp = build_fold_indirect_ref_loc (input_location, tmp);
429cb994
TB
6323 parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
6324 fsym->attr);
c62c6622
TB
6325 parmse.expr = gfc_build_addr_expr (NULL_TREE,
6326 parmse.expr);
6327 }
6328 else if (fsym && e->expr_type != EXPR_NULL
8fb74da4
JW
6329 && ((fsym->attr.pointer
6330 && fsym->attr.flavor != FL_PROCEDURE)
7e9c61e8
JW
6331 || (fsym->attr.proc_pointer
6332 && !(e->expr_type == EXPR_VARIABLE
2d300fac
JW
6333 && e->symtree->n.sym->attr.dummy))
6334 || (fsym->attr.proc_pointer
6335 && e->expr_type == EXPR_VARIABLE
2a573572 6336 && gfc_is_proc_ptr_comp (e))
8c6cb782
TB
6337 || (fsym->attr.allocatable
6338 && fsym->attr.flavor != FL_PROCEDURE)))
06469efd
PT
6339 {
6340 /* Scalar pointer dummy args require an extra level of
6341 indirection. The null pointer already contains
6342 this level of indirection. */
6343 parm_kind = SCALAR_POINTER;
628c189e 6344 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
06469efd
PT
6345 }
6346 }
6347 }
c49ea23d
PT
6348 else if (e->ts.type == BT_CLASS
6349 && fsym && fsym->ts.type == BT_CLASS
16e82b25
TB
6350 && (CLASS_DATA (fsym)->attr.dimension
6351 || CLASS_DATA (fsym)->attr.codimension))
c49ea23d
PT
6352 {
6353 /* Pass a class array. */
1cf43a1d 6354 parmse.use_offset = 1;
2960a368 6355 gfc_conv_expr_descriptor (&parmse, e);
4fb5478c
TB
6356
6357 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
6358 allocated on entry, it must be deallocated. */
6359 if (fsym->attr.intent == INTENT_OUT
6360 && CLASS_DATA (fsym)->attr.allocatable)
6361 {
6362 stmtblock_t block;
6363 tree ptr;
6364
6365 gfc_init_block (&block);
6366 ptr = parmse.expr;
6367 ptr = gfc_class_data_get (ptr);
6368
6369 tmp = gfc_deallocate_with_status (ptr, NULL_TREE,
6370 NULL_TREE, NULL_TREE,
6371 NULL_TREE, true, e,
ba85c8c3 6372 GFC_CAF_COARRAY_NOCOARRAY);
4fb5478c
TB
6373 gfc_add_expr_to_block (&block, tmp);
6374 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
6375 void_type_node, ptr,
6376 null_pointer_node);
6377 gfc_add_expr_to_block (&block, tmp);
6378 gfc_reset_vptr (&block, e);
6379
6380 if (fsym->attr.optional
6381 && e->expr_type == EXPR_VARIABLE
6382 && (!e->ref
6383 || (e->ref->type == REF_ARRAY
86eb9e2f 6384 && e->ref->u.ar.type != AR_FULL))
4fb5478c
TB
6385 && e->symtree->n.sym->attr.optional)
6386 {
6387 tmp = fold_build3_loc (input_location, COND_EXPR,
6388 void_type_node,
6389 gfc_conv_expr_present (e->symtree->n.sym),
6390 gfc_finish_block (&block),
6391 build_empty_stmt (input_location));
6392 }
6393 else
6394 tmp = gfc_finish_block (&block);
6395
ef292537
TB
6396 gfc_add_expr_to_block (&se->pre, tmp);
6397 }
4fb5478c 6398
c49ea23d
PT
6399 /* The conversion does not repackage the reference to a class
6400 array - _data descriptor. */
16e82b25
TB
6401 gfc_conv_class_to_class (&parmse, e, fsym->ts, false,
6402 fsym->attr.intent != INTENT_IN
6403 && (CLASS_DATA (fsym)->attr.class_pointer
6404 || CLASS_DATA (fsym)->attr.allocatable),
6405 fsym->attr.optional
6406 && e->expr_type == EXPR_VARIABLE
6407 && e->symtree->n.sym->attr.optional,
6408 CLASS_DATA (fsym)->attr.class_pointer
6409 || CLASS_DATA (fsym)->attr.allocatable);
c49ea23d 6410 }
6de9cd9a
DN
6411 else
6412 {
0b4f2770
MM
6413 /* If the argument is a function call that may not create
6414 a temporary for the result, we have to check that we
8b704316 6415 can do it, i.e. that there is no alias between this
0b4f2770
MM
6416 argument and another one. */
6417 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
6418 {
f1f39033 6419 gfc_expr *iarg;
0b4f2770
MM
6420 sym_intent intent;
6421
6422 if (fsym != NULL)
6423 intent = fsym->attr.intent;
6424 else
6425 intent = INTENT_UNKNOWN;
6426
6427 if (gfc_check_fncall_dependency (e, intent, sym, args,
6428 NOT_ELEMENTAL))
6429 parmse.force_tmp = 1;
f1f39033
PT
6430
6431 iarg = e->value.function.actual->expr;
6432
6433 /* Temporary needed if aliasing due to host association. */
6434 if (sym->attr.contained
6435 && !sym->attr.pure
6436 && !sym->attr.implicit_pure
6437 && !sym->attr.use_assoc
6438 && iarg->expr_type == EXPR_VARIABLE
6439 && sym->ns == iarg->symtree->n.sym->ns)
6440 parmse.force_tmp = 1;
6441
6442 /* Ditto within module. */
6443 if (sym->attr.use_assoc
6444 && !sym->attr.pure
6445 && !sym->attr.implicit_pure
6446 && iarg->expr_type == EXPR_VARIABLE
6447 && sym->module == iarg->symtree->n.sym->module)
6448 parmse.force_tmp = 1;
0b4f2770
MM
6449 }
6450
bbf18dc5 6451 if (sym->attr.is_bind_c && e
b3d4011b
TB
6452 && (is_CFI_desc (fsym, NULL) || assumed_length_string))
6453 /* Implement F2018, 18.3.6, list item (5), bullet point 2. */
bbf18dc5
PT
6454 gfc_conv_gfc_desc_to_cfi_desc (&parmse, e, fsym);
6455
6456 else if (e->expr_type == EXPR_VARIABLE
ff3598bc
PT
6457 && is_subref_array (e)
6458 && !(fsym && fsym->attr.pointer))
68ea355b
PT
6459 /* The actual argument is a component reference to an
6460 array of derived types. In this case, the argument
6461 is converted to a temporary, which is passed and then
6462 written back after the procedure call. */
0e1f8c6a 6463 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
430f2d1f
PT
6464 fsym ? fsym->attr.intent : INTENT_INOUT,
6465 fsym && fsym->attr.pointer);
bbf18dc5 6466
a2c59300
PT
6467 else if (e->ts.type == BT_CLASS && CLASS_DATA (e)->as
6468 && CLASS_DATA (e)->as->type == AS_ASSUMED_SIZE
6469 && nodesc_arg && fsym->ts.type == BT_DERIVED)
6470 /* An assumed size class actual argument being passed to
6471 a 'no descriptor' formal argument just requires the
6472 data pointer to be passed. For class dummy arguments
6473 this is stored in the symbol backend decl.. */
6474 parmse.expr = e->symtree->n.sym->backend_decl;
6475
c49ea23d 6476 else if (gfc_is_class_array_ref (e, NULL)
9b962319 6477 && fsym && fsym->ts.type == BT_DERIVED)
c49ea23d
PT
6478 /* The actual argument is a component reference to an
6479 array of derived types. In this case, the argument
6480 is converted to a temporary, which is passed and then
6481 written back after the procedure call.
6482 OOP-TODO: Insert code so that if the dynamic type is
6483 the same as the declared type, copy-in/copy-out does
6484 not occur. */
0e1f8c6a 6485 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
9b962319
TB
6486 fsym->attr.intent,
6487 fsym->attr.pointer);
43a68a9d 6488
a6b22eea 6489 else if (gfc_is_class_array_function (e)
9b962319 6490 && fsym && fsym->ts.type == BT_DERIVED)
43a68a9d
PT
6491 /* See previous comment. For function actual argument,
6492 the write out is not needed so the intent is set as
6493 intent in. */
6494 {
6495 e->must_finalize = 1;
0e1f8c6a 6496 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
9b962319 6497 INTENT_IN, fsym->attr.pointer);
8558af50
TK
6498 }
6499 else if (fsym && fsym->attr.contiguous
9b962319
TB
6500 && !gfc_is_simply_contiguous (e, false, true)
6501 && gfc_expr_is_variable (e))
8558af50
TK
6502 {
6503 gfc_conv_subref_array_arg (&parmse, e, nodesc_arg,
9b962319
TB
6504 fsym->attr.intent,
6505 fsym->attr.pointer);
43a68a9d 6506 }
68ea355b 6507 else
0e1f8c6a
MM
6508 gfc_conv_array_parameter (&parmse, e, nodesc_arg, fsym,
6509 sym->name, NULL);
42a0e16c 6510
0e308880
PT
6511 /* Unallocated allocatable arrays and unassociated pointer arrays
6512 need their dtype setting if they are argument associated with
f699e0b1 6513 assumed rank dummies, unless already assumed rank. */
0e308880 6514 if (!sym->attr.is_bind_c && e && fsym && fsym->as
f699e0b1
TB
6515 && fsym->as->type == AS_ASSUMED_RANK
6516 && e->rank != -1)
0e308880
PT
6517 {
6518 if (gfc_expr_attr (e).pointer
6519 || gfc_expr_attr (e).allocatable)
6520 set_dtype_for_unallocated (&parmse, e);
6521 else if (e->expr_type == EXPR_VARIABLE
6a07010b
JRFS
6522 && e->ref
6523 && e->ref->u.ar.type == AR_FULL
0e308880
PT
6524 && e->symtree->n.sym->attr.dummy
6525 && e->symtree->n.sym->as
6526 && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE)
6527 {
6528 tree minus_one;
6529 tmp = build_fold_indirect_ref_loc (input_location,
6530 parmse.expr);
6531 minus_one = build_int_cst (gfc_array_index_type, -1);
6532 gfc_conv_descriptor_ubound_set (&parmse.pre, tmp,
6533 gfc_rank_cst[e->rank - 1],
6534 minus_one);
6535 }
6536 }
6537
8b704316 6538 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
745ff31f
TB
6539 allocated on entry, it must be deallocated. */
6540 if (fsym && fsym->attr.allocatable
6541 && fsym->attr.intent == INTENT_OUT)
6542 {
60fc41bd
JW
6543 if (fsym->ts.type == BT_DERIVED
6544 && fsym->ts.u.derived->attr.alloc_comp)
6545 {
6546 // deallocate the components first
6547 tmp = gfc_deallocate_alloc_comp (fsym->ts.u.derived,
6548 parmse.expr, e->rank);
6549 if (tmp != NULL_TREE)
6550 gfc_add_expr_to_block (&se->pre, tmp);
6551 }
6552
1c027944
TB
6553 tmp = parmse.expr;
6554 /* With bind(C), the actual argument is replaced by a bind-C
6555 descriptor; in this case, the data component arrives here,
6556 which shall not be dereferenced, but still freed and
6557 nullified. */
6558 if (TREE_TYPE(tmp) != pvoid_type_node)
6559 tmp = build_fold_indirect_ref_loc (input_location,
6560 parmse.expr);
39da5866
AV
6561 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
6562 tmp = gfc_conv_descriptor_data_get (tmp);
6563 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
6564 NULL_TREE, NULL_TREE, true,
6565 e,
6566 GFC_CAF_COARRAY_NOCOARRAY);
745ff31f
TB
6567 if (fsym->attr.optional
6568 && e->expr_type == EXPR_VARIABLE
6569 && e->symtree->n.sym->attr.optional)
65a9ca82
TB
6570 tmp = fold_build3_loc (input_location, COND_EXPR,
6571 void_type_node,
745ff31f
TB
6572 gfc_conv_expr_present (e->symtree->n.sym),
6573 tmp, build_empty_stmt (input_location));
6574 gfc_add_expr_to_block (&se->pre, tmp);
6575 }
8b704316 6576 }
6de9cd9a
DN
6577 }
6578
34b4bc5c
FXC
6579 /* The case with fsym->attr.optional is that of a user subroutine
6580 with an interface indicating an optional argument. When we call
6581 an intrinsic subroutine, however, fsym is NULL, but we might still
6582 have an optional argument, so we proceed to the substitution
6583 just in case. */
6584 if (e && (fsym == NULL || fsym->attr.optional))
5be38273 6585 {
34b4bc5c 6586 /* If an optional argument is itself an optional dummy argument,
745ff31f
TB
6587 check its presence and substitute a null if absent. This is
6588 only needed when passing an array to an elemental procedure
6589 as then array elements are accessed - or no NULL pointer is
6590 allowed and a "1" or "0" should be passed if not present.
64c2f8de
TB
6591 When passing a non-array-descriptor full array to a
6592 non-array-descriptor dummy, no check is needed. For
6593 array-descriptor actual to array-descriptor dummy, see
6594 PR 41911 for why a check has to be inserted.
6595 fsym == NULL is checked as intrinsics required the descriptor
92f3a180 6596 but do not always set fsym.
2ea47ee9
TK
6597 Also, it is necessary to pass a NULL pointer to library routines
6598 which usually ignore optional arguments, so they can handle
6599 these themselves. */
34b4bc5c 6600 if (e->expr_type == EXPR_VARIABLE
745ff31f 6601 && e->symtree->n.sym->attr.optional
2ea47ee9
TK
6602 && (((e->rank != 0 && elemental_proc)
6603 || e->representation.length || e->ts.type == BT_CHARACTER
6604 || (e->rank != 0
6605 && (fsym == NULL
6606 || (fsym->as
6607 && (fsym->as->type == AS_ASSUMED_SHAPE
6608 || fsym->as->type == AS_ASSUMED_RANK
6609 || fsym->as->type == AS_DEFERRED)))))
6610 || se->ignore_optional))
be9c3c6e
JD
6611 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
6612 e->representation.length);
34b4bc5c
FXC
6613 }
6614
6615 if (fsym && e)
6616 {
6617 /* Obtain the character length of an assumed character length
6618 length procedure from the typespec. */
6619 if (fsym->ts.type == BT_CHARACTER
6620 && parmse.string_length == NULL_TREE
6621 && e->ts.type == BT_PROCEDURE
6622 && e->symtree->n.sym->ts.type == BT_CHARACTER
bc21d315
JW
6623 && e->symtree->n.sym->ts.u.cl->length != NULL
6624 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
5be38273 6625 {
bc21d315
JW
6626 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
6627 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
5be38273 6628 }
5be38273 6629 }
0348d6fd 6630
2c80cb0e 6631 if (fsym && need_interface_mapping && e)
0a164a3c 6632 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
34b4bc5c 6633
6de9cd9a 6634 gfc_add_block_to_block (&se->pre, &parmse.pre);
f5f701ad 6635 gfc_add_block_to_block (&post, &parmse.post);
6de9cd9a 6636
5046aff5 6637 /* Allocated allocatable components of derived types must be
0e1f8c6a
MM
6638 deallocated for non-variable scalars, array arguments to elemental
6639 procedures, and array arguments with descriptor to non-elemental
6640 procedures. As bounds information for descriptorless arrays is no
6641 longer available here, they are dealt with in trans-array.c
6642 (gfc_conv_array_parameter). */
bfa204b8 6643 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
bc21d315 6644 && e->ts.u.derived->attr.alloc_comp
0e1f8c6a
MM
6645 && (e->rank == 0 || elemental_proc || !nodesc_arg)
6646 && !expr_may_alias_variables (e, elemental_proc))
6647 {
5046aff5 6648 int parm_rank;
c16126ac
AV
6649 /* It is known the e returns a structure type with at least one
6650 allocatable component. When e is a function, ensure that the
6651 function is called once only by using a temporary variable. */
6652 if (!DECL_P (parmse.expr))
6653 parmse.expr = gfc_evaluate_now_loc (input_location,
6654 parmse.expr, &se->pre);
6655
6656 if (fsym && fsym->attr.value)
6657 tmp = parmse.expr;
6658 else
6659 tmp = build_fold_indirect_ref_loc (input_location,
6660 parmse.expr);
6661
5046aff5
PT
6662 parm_rank = e->rank;
6663 switch (parm_kind)
6664 {
6665 case (ELEMENTAL):
6666 case (SCALAR):
6667 parm_rank = 0;
6668 break;
6669
6670 case (SCALAR_POINTER):
db3927fb
AH
6671 tmp = build_fold_indirect_ref_loc (input_location,
6672 tmp);
5046aff5 6673 break;
5046aff5
PT
6674 }
6675
a3df90b9
PT
6676 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
6677 {
6678 /* The derived type is passed to gfc_deallocate_alloc_comp.
6679 Therefore, class actuals can be handled correctly but derived
6680 types passed to class formals need the _data component. */
6681 tmp = gfc_class_data_get (tmp);
6682 if (!CLASS_DATA (fsym)->attr.dimension)
6683 tmp = build_fold_indirect_ref_loc (input_location, tmp);
6684 }
6685
7d44f531
PT
6686 if (e->expr_type == EXPR_OP
6687 && e->value.op.op == INTRINSIC_PARENTHESES
6688 && e->value.op.op1->expr_type == EXPR_VARIABLE)
6689 {
6690 tree local_tmp;
6691 local_tmp = gfc_evaluate_now (tmp, &se->pre);
ba85c8c3
AV
6692 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp,
6693 parm_rank, 0);
7d44f531
PT
6694 gfc_add_expr_to_block (&se->post, local_tmp);
6695 }
6696
1312bb90
PT
6697 if (!finalized && !e->must_finalize)
6698 {
e86a02f8
PT
6699 bool scalar_res_outside_loop;
6700 scalar_res_outside_loop = e->expr_type == EXPR_FUNCTION
6701 && parm_rank == 0
6702 && parmse.loop;
6703
5159b88e
PT
6704 /* Scalars passed to an assumed rank argument are converted to
6705 a descriptor. Obtain the data field before deallocating any
6706 allocatable components. */
6707 if (parm_rank == 0 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
6708 tmp = gfc_conv_descriptor_data_get (tmp);
6709
e86a02f8
PT
6710 if (scalar_res_outside_loop)
6711 {
6712 /* Go through the ss chain to find the argument and use
6713 the stored value. */
6714 gfc_ss *tmp_ss = parmse.loop->ss;
6715 for (; tmp_ss; tmp_ss = tmp_ss->next)
6716 if (tmp_ss->info
6717 && tmp_ss->info->expr == e
6718 && tmp_ss->info->data.scalar.value != NULL_TREE)
6719 {
6720 tmp = tmp_ss->info->data.scalar.value;
6721 break;
6722 }
6723 }
6724
5159b88e
PT
6725 STRIP_NOPS (tmp);
6726
6727 if (derived_array != NULL_TREE)
6728 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived,
6729 derived_array,
6730 parm_rank);
6731 else if ((e->ts.type == BT_CLASS
6732 && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
6733 || e->ts.type == BT_DERIVED)
1312bb90
PT
6734 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp,
6735 parm_rank);
6736 else if (e->ts.type == BT_CLASS)
6737 tmp = gfc_deallocate_alloc_comp (CLASS_DATA (e)->ts.u.derived,
6738 tmp, parm_rank);
e86a02f8
PT
6739
6740 if (scalar_res_outside_loop)
6741 gfc_add_expr_to_block (&parmse.loop->post, tmp);
6742 else
6743 gfc_prepend_expr_to_block (&post, tmp);
1312bb90 6744 }
5046aff5
PT
6745 }
6746
20460eb9
TB
6747 /* Add argument checking of passing an unallocated/NULL actual to
6748 a nonallocatable/nonpointer dummy. */
6749
4b41f35e 6750 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
20460eb9 6751 {
48dbbcd6 6752 symbol_attribute attr;
20460eb9
TB
6753 char *msg;
6754 tree cond;
c2d7c39f 6755 tree tmp;
29736377
PT
6756 symbol_attribute fsym_attr;
6757
6758 if (fsym)
6759 {
6760 if (fsym->ts.type == BT_CLASS)
6761 {
6762 fsym_attr = CLASS_DATA (fsym)->attr;
6763 fsym_attr.pointer = fsym_attr.class_pointer;
6764 }
6765 else
6766 fsym_attr = fsym->attr;
6767 }
20460eb9 6768
48dbbcd6
JW
6769 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
6770 attr = gfc_expr_attr (e);
20460eb9
TB
6771 else
6772 goto end_pointer_check;
6773
8d231ff2
TB
6774 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
6775 allocatable to an optional dummy, cf. 12.5.2.12. */
6776 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
6777 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
6778 goto end_pointer_check;
6779
48dbbcd6 6780 if (attr.optional)
4b41f35e
TB
6781 {
6782 /* If the actual argument is an optional pointer/allocatable and
6783 the formal argument takes an nonpointer optional value,
6784 it is invalid to pass a non-present argument on, even
6785 though there is no technical reason for this in gfortran.
6786 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
14c2101d 6787 tree present, null_ptr, type;
4b41f35e 6788
48dbbcd6 6789 if (attr.allocatable
29736377 6790 && (fsym == NULL || !fsym_attr.allocatable))
1a33dc9e
UB
6791 msg = xasprintf ("Allocatable actual argument '%s' is not "
6792 "allocated or not present",
6793 e->symtree->n.sym->name);
48dbbcd6 6794 else if (attr.pointer
29736377 6795 && (fsym == NULL || !fsym_attr.pointer))
1a33dc9e
UB
6796 msg = xasprintf ("Pointer actual argument '%s' is not "
6797 "associated or not present",
6798 e->symtree->n.sym->name);
29736377
PT
6799 else if (attr.proc_pointer && !e->value.function.actual
6800 && (fsym == NULL || !fsym_attr.proc_pointer))
1a33dc9e
UB
6801 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
6802 "associated or not present",
6803 e->symtree->n.sym->name);
4b41f35e
TB
6804 else
6805 goto end_pointer_check;
6806
6807 present = gfc_conv_expr_present (e->symtree->n.sym);
6808 type = TREE_TYPE (present);
65a9ca82 6809 present = fold_build2_loc (input_location, EQ_EXPR,
63ee5404 6810 logical_type_node, present,
65a9ca82
TB
6811 fold_convert (type,
6812 null_pointer_node));
4b41f35e 6813 type = TREE_TYPE (parmse.expr);
65a9ca82 6814 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
63ee5404 6815 logical_type_node, parmse.expr,
65a9ca82
TB
6816 fold_convert (type,
6817 null_pointer_node));
6818 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
63ee5404 6819 logical_type_node, present, null_ptr);
4b41f35e
TB
6820 }
6821 else
6822 {
48dbbcd6 6823 if (attr.allocatable
29736377 6824 && (fsym == NULL || !fsym_attr.allocatable))
1a33dc9e
UB
6825 msg = xasprintf ("Allocatable actual argument '%s' is not "
6826 "allocated", e->symtree->n.sym->name);
48dbbcd6 6827 else if (attr.pointer
29736377 6828 && (fsym == NULL || !fsym_attr.pointer))
1a33dc9e
UB
6829 msg = xasprintf ("Pointer actual argument '%s' is not "
6830 "associated", e->symtree->n.sym->name);
29736377
PT
6831 else if (attr.proc_pointer && !e->value.function.actual
6832 && (fsym == NULL || !fsym_attr.proc_pointer))
1a33dc9e
UB
6833 msg = xasprintf ("Proc-pointer actual argument '%s' is not "
6834 "associated", e->symtree->n.sym->name);
4b41f35e
TB
6835 else
6836 goto end_pointer_check;
6837
c2d7c39f
HA
6838 if (fsym && fsym->ts.type == BT_CLASS)
6839 {
6840 tmp = build_fold_indirect_ref_loc (input_location,
6841 parmse.expr);
6842 tmp = gfc_class_data_get (tmp);
6843 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
6844 tmp = gfc_conv_descriptor_data_get (tmp);
6845 }
6846 else
6847 tmp = parmse.expr;
85ff2938
TB
6848
6849 /* If the argument is passed by value, we need to strip the
6850 INDIRECT_REF. */
c2d7c39f 6851 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
85ff2938 6852 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4b41f35e 6853
65a9ca82 6854 cond = fold_build2_loc (input_location, EQ_EXPR,
63ee5404 6855 logical_type_node, tmp,
85ff2938 6856 fold_convert (TREE_TYPE (tmp),
65a9ca82 6857 null_pointer_node));
4b41f35e 6858 }
8b704316 6859
20460eb9
TB
6860 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
6861 msg);
cede9502 6862 free (msg);
20460eb9
TB
6863 }
6864 end_pointer_check:
6865
8d51f26f
PT
6866 /* Deferred length dummies pass the character length by reference
6867 so that the value can be returned. */
6868 if (parmse.string_length && fsym && fsym->ts.deferred)
6869 {
adbfb3f8
AV
6870 if (INDIRECT_REF_P (parmse.string_length))
6871 /* In chains of functions/procedure calls the string_length already
6872 is a pointer to the variable holding the length. Therefore
6873 remove the deref on call. */
6874 parmse.string_length = TREE_OPERAND (parmse.string_length, 0);
6875 else
6876 {
6877 tmp = parmse.string_length;
d168c883 6878 if (!VAR_P (tmp) && TREE_CODE (tmp) != COMPONENT_REF)
adbfb3f8
AV
6879 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
6880 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
6881 }
8d51f26f 6882 }
20460eb9 6883
e7dc5b4f 6884 /* Character strings are passed as two parameters, a length and a
8b704316
PT
6885 pointer - except for Bind(c) which only passes the pointer.
6886 An unlimited polymorphic formal argument likewise does not
6887 need the length. */
6888 if (parmse.string_length != NULL_TREE
6889 && !sym->attr.is_bind_c
6890 && !(fsym && UNLIMITED_POLY (fsym)))
6891 vec_safe_push (stringargs, parmse.string_length);
6892
6893 /* When calling __copy for character expressions to unlimited
6894 polymorphic entities, the dst argument needs a string length. */
6895 if (sym->name[0] == '_' && e && e->ts.type == BT_CHARACTER
6ba3079d 6896 && startswith (sym->name, "__vtab_CHARACTER")
8b704316 6897 && arg->next && arg->next->expr
0c221916
PT
6898 && (arg->next->expr->ts.type == BT_DERIVED
6899 || arg->next->expr->ts.type == BT_CLASS)
8b704316 6900 && arg->next->expr->ts.u.derived->attr.unlimited_polymorphic)
9771b263 6901 vec_safe_push (stringargs, parmse.string_length);
6de9cd9a 6902
aa13dc3c
TB
6903 /* For descriptorless coarrays and assumed-shape coarray dummies, we
6904 pass the token and the offset as additional arguments. */
f19626cf 6905 if (fsym && e == NULL && flag_coarray == GFC_FCOARRAY_LIB
598cc4fa
TB
6906 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
6907 && !fsym->attr.allocatable)
6908 || (fsym->ts.type == BT_CLASS
6909 && CLASS_DATA (fsym)->attr.codimension
6910 && !CLASS_DATA (fsym)->attr.allocatable)))
0c53708e 6911 {
1cc0e193 6912 /* Token and offset. */
9771b263
DN
6913 vec_safe_push (stringargs, null_pointer_node);
6914 vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
af232d48 6915 gcc_assert (fsym->attr.optional);
0c53708e 6916 }
f19626cf 6917 else if (fsym && flag_coarray == GFC_FCOARRAY_LIB
598cc4fa
TB
6918 && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
6919 && !fsym->attr.allocatable)
6920 || (fsym->ts.type == BT_CLASS
6921 && CLASS_DATA (fsym)->attr.codimension
6922 && !CLASS_DATA (fsym)->attr.allocatable)))
0c53708e
TB
6923 {
6924 tree caf_decl, caf_type;
af232d48 6925 tree offset, tmp2;
0c53708e 6926
b5116268 6927 caf_decl = gfc_get_tree_for_caf_expr (e);
0c53708e
TB
6928 caf_type = TREE_TYPE (caf_decl);
6929
aa13dc3c 6930 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
d7463e5b
TB
6931 && (GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE
6932 || GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_POINTER))
af232d48 6933 tmp = gfc_conv_descriptor_token (caf_decl);
aa13dc3c
TB
6934 else if (DECL_LANG_SPECIFIC (caf_decl)
6935 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
6936 tmp = GFC_DECL_TOKEN (caf_decl);
af232d48
TB
6937 else
6938 {
6939 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
6940 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
6941 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
6942 }
8b704316 6943
9771b263 6944 vec_safe_push (stringargs, tmp);
0c53708e 6945
aa13dc3c
TB
6946 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
6947 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
af232d48 6948 offset = build_int_cst (gfc_array_index_type, 0);
aa13dc3c
TB
6949 else if (DECL_LANG_SPECIFIC (caf_decl)
6950 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
6951 offset = GFC_DECL_CAF_OFFSET (caf_decl);
af232d48 6952 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
0c53708e
TB
6953 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
6954 else
6955 offset = build_int_cst (gfc_array_index_type, 0);
6956
af232d48
TB
6957 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
6958 tmp = gfc_conv_descriptor_data_get (caf_decl);
6959 else
6960 {
6961 gcc_assert (POINTER_TYPE_P (caf_type));
6962 tmp = caf_decl;
6963 }
6964
598cc4fa
TB
6965 tmp2 = fsym->ts.type == BT_CLASS
6966 ? gfc_class_data_get (parmse.expr) : parmse.expr;
6967 if ((fsym->ts.type != BT_CLASS
6968 && (fsym->as->type == AS_ASSUMED_SHAPE
6969 || fsym->as->type == AS_ASSUMED_RANK))
6970 || (fsym->ts.type == BT_CLASS
6971 && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
6972 || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
aa13dc3c 6973 {
598cc4fa
TB
6974 if (fsym->ts.type == BT_CLASS)
6975 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
6976 else
6977 {
6978 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
6979 tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
6980 }
6981 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
aa13dc3c
TB
6982 tmp2 = gfc_conv_descriptor_data_get (tmp2);
6983 }
598cc4fa
TB
6984 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
6985 tmp2 = gfc_conv_descriptor_data_get (tmp2);
af232d48
TB
6986 else
6987 {
598cc4fa 6988 gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
af232d48 6989 }
0c53708e
TB
6990
6991 tmp = fold_build2_loc (input_location, MINUS_EXPR,
6992 gfc_array_index_type,
af232d48
TB
6993 fold_convert (gfc_array_index_type, tmp2),
6994 fold_convert (gfc_array_index_type, tmp));
0c53708e
TB
6995 offset = fold_build2_loc (input_location, PLUS_EXPR,
6996 gfc_array_index_type, offset, tmp);
6997
9771b263 6998 vec_safe_push (stringargs, offset);
0c53708e
TB
6999 }
7000
9771b263 7001 vec_safe_push (arglist, parmse.expr);
6de9cd9a 7002 }
0348d6fd
RS
7003 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
7004
50dbf0b4
JW
7005 if (comp)
7006 ts = comp->ts;
574284e9
AV
7007 else if (sym->ts.type == BT_CLASS)
7008 ts = CLASS_DATA (sym)->ts;
50dbf0b4 7009 else
323c5722 7010 ts = sym->ts;
50dbf0b4 7011
3a73a540
TB
7012 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
7013 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
7014 else if (ts.type == BT_CHARACTER)
0348d6fd 7015 {
50dbf0b4 7016 if (ts.u.cl->length == NULL)
20236f90 7017 {
77f72c95 7018 /* Assumed character length results are not allowed by C418 of the 2003
20236f90 7019 standard and are trapped in resolve.c; except in the case of SPREAD
7f39b34c
PT
7020 (and other intrinsics?) and dummy functions. In the case of SPREAD,
7021 we take the character length of the first argument for the result.
7022 For dummies, we have to look through the formal argument list for
7023 this function and use the character length found there.*/
8ae1ec92 7024 if (ts.deferred)
8d51f26f
PT
7025 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
7026 else if (!sym->attr.dummy)
9771b263 7027 cl.backend_decl = (*stringargs)[0];
7f39b34c
PT
7028 else
7029 {
4cbc9039 7030 formal = gfc_sym_get_dummy_args (sym->ns->proc_name);
7f39b34c
PT
7031 for (; formal; formal = formal->next)
7032 if (strcmp (formal->sym->name, sym->name) == 0)
bc21d315 7033 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
7f39b34c 7034 }
8ae1ec92 7035 len = cl.backend_decl;
7f39b34c 7036 }
958dd42b 7037 else
7f39b34c 7038 {
886c8de1
FXC
7039 tree tmp;
7040
20236f90
PT
7041 /* Calculate the length of the returned string. */
7042 gfc_init_se (&parmse, NULL);
7043 if (need_interface_mapping)
50dbf0b4 7044 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
20236f90 7045 else
50dbf0b4 7046 gfc_conv_expr (&parmse, ts.u.cl->length);
20236f90
PT
7047 gfc_add_block_to_block (&se->pre, &parmse.pre);
7048 gfc_add_block_to_block (&se->post, &parmse.post);
f622221a 7049 tmp = parmse.expr;
983d49dd
JB
7050 /* TODO: It would be better to have the charlens as
7051 gfc_charlen_type_node already when the interface is
7052 created instead of converting it here (see PR 84615). */
65a9ca82 7053 tmp = fold_build2_loc (input_location, MAX_EXPR,
983d49dd
JB
7054 gfc_charlen_type_node,
7055 fold_convert (gfc_charlen_type_node, tmp),
7056 build_zero_cst (gfc_charlen_type_node));
886c8de1 7057 cl.backend_decl = tmp;
20236f90 7058 }
0348d6fd
RS
7059
7060 /* Set up a charlen structure for it. */
7061 cl.next = NULL;
7062 cl.length = NULL;
bc21d315 7063 ts.u.cl = &cl;
0348d6fd
RS
7064
7065 len = cl.backend_decl;
7066 }
0348d6fd 7067
5df445a2
TB
7068 byref = (comp && (comp->attr.dimension
7069 || (comp->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)))
7070 || (!comp && gfc_return_by_reference (sym));
0348d6fd
RS
7071 if (byref)
7072 {
7073 if (se->direct_byref)
fc2d8680 7074 {
df2fba9e 7075 /* Sometimes, too much indirection can be applied; e.g. for
fc2d8680
PT
7076 function_result = array_valued_recursive_function. */
7077 if (TREE_TYPE (TREE_TYPE (se->expr))
7078 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
7079 && GFC_DESCRIPTOR_TYPE_P
7080 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
db3927fb 7081 se->expr = build_fold_indirect_ref_loc (input_location,
574284e9 7082 se->expr);
fc2d8680 7083
597553ab
PT
7084 /* If the lhs of an assignment x = f(..) is allocatable and
7085 f2003 is allowed, we must do the automatic reallocation.
f1f39033 7086 TODO - deal with intrinsics, without using a temporary. */
203c7ebf 7087 if (flag_realloc_lhs
597553ab
PT
7088 && se->ss && se->ss->loop_chain
7089 && se->ss->loop_chain->is_alloc_lhs
7090 && !expr->value.function.isym
7091 && sym->result->as != NULL)
7092 {
7093 /* Evaluate the bounds of the result, if known. */
7094 gfc_set_loop_bounds_from_array_spec (&mapping, se,
7095 sym->result->as);
7096
7097 /* Perform the automatic reallocation. */
7098 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
7099 expr, NULL);
7100 gfc_add_expr_to_block (&se->pre, tmp);
7101
7102 /* Pass the temporary as the first argument. */
7103 result = info->descriptor;
7104 }
7105 else
7106 result = build_fold_indirect_ref_loc (input_location,
7107 se->expr);
9771b263 7108 vec_safe_push (retargs, se->expr);
fc2d8680 7109 }
f64edc8b
JW
7110 else if (comp && comp->attr.dimension)
7111 {
7112 gcc_assert (se->loop && info);
7113
7114 /* Set the type of the array. */
7115 tmp = gfc_typenode_for_spec (&comp->ts);
cb4b9eae 7116 gcc_assert (se->ss->dimen == se->loop->dimen);
f64edc8b
JW
7117
7118 /* Evaluate the bounds of the result, if known. */
7119 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
7120
597553ab
PT
7121 /* If the lhs of an assignment x = f(..) is allocatable and
7122 f2003 is allowed, we must not generate the function call
7123 here but should just send back the results of the mapping.
7124 This is signalled by the function ss being flagged. */
203c7ebf 7125 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
597553ab
PT
7126 {
7127 gfc_free_interface_mapping (&mapping);
7128 return has_alternate_specifier;
7129 }
7130
f64edc8b
JW
7131 /* Create a temporary to store the result. In case the function
7132 returns a pointer, the temporary will be a shallow copy and
7133 mustn't be deallocated. */
7134 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
41645793 7135 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
f44d2277 7136 tmp, NULL_TREE, false,
f98cfd3c
MM
7137 !comp->attr.pointer, callee_alloc,
7138 &se->ss->info->expr->where);
f64edc8b
JW
7139
7140 /* Pass the temporary as the first argument. */
40c32948
PT
7141 result = info->descriptor;
7142 tmp = gfc_build_addr_expr (NULL_TREE, result);
9771b263 7143 vec_safe_push (retargs, tmp);
f64edc8b 7144 }
50dbf0b4 7145 else if (!comp && sym->result->attr.dimension)
0348d6fd
RS
7146 {
7147 gcc_assert (se->loop && info);
7148
7149 /* Set the type of the array. */
7150 tmp = gfc_typenode_for_spec (&ts);
cb4b9eae 7151 gcc_assert (se->ss->dimen == se->loop->dimen);
0348d6fd 7152
62ab4a54
RS
7153 /* Evaluate the bounds of the result, if known. */
7154 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
7155
597553ab
PT
7156 /* If the lhs of an assignment x = f(..) is allocatable and
7157 f2003 is allowed, we must not generate the function call
7158 here but should just send back the results of the mapping.
7159 This is signalled by the function ss being flagged. */
203c7ebf 7160 if (flag_realloc_lhs && se->ss && se->ss->is_alloc_lhs)
597553ab
PT
7161 {
7162 gfc_free_interface_mapping (&mapping);
7163 return has_alternate_specifier;
7164 }
7165
8e119f1b
EE
7166 /* Create a temporary to store the result. In case the function
7167 returns a pointer, the temporary will be a shallow copy and
7168 mustn't be deallocated. */
7169 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
41645793 7170 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
f44d2277 7171 tmp, NULL_TREE, false,
f98cfd3c
MM
7172 !sym->attr.pointer, callee_alloc,
7173 &se->ss->info->expr->where);
0348d6fd 7174
0348d6fd 7175 /* Pass the temporary as the first argument. */
40c32948
PT
7176 result = info->descriptor;
7177 tmp = gfc_build_addr_expr (NULL_TREE, result);
9771b263 7178 vec_safe_push (retargs, tmp);
0348d6fd
RS
7179 }
7180 else if (ts.type == BT_CHARACTER)
7181 {
7182 /* Pass the string length. */
bc21d315 7183 type = gfc_get_character_type (ts.kind, ts.u.cl);
0348d6fd
RS
7184 type = build_pointer_type (type);
7185
b528e427
JB
7186 /* Emit a DECL_EXPR for the VLA type. */
7187 tmp = TREE_TYPE (type);
7188 if (TYPE_SIZE (tmp)
7189 && TREE_CODE (TYPE_SIZE (tmp)) != INTEGER_CST)
7190 {
7191 tmp = build_decl (input_location, TYPE_DECL, NULL_TREE, tmp);
7192 DECL_ARTIFICIAL (tmp) = 1;
7193 DECL_IGNORED_P (tmp) = 1;
7194 tmp = fold_build1_loc (input_location, DECL_EXPR,
7195 TREE_TYPE (tmp), tmp);
7196 gfc_add_expr_to_block (&se->pre, tmp);
7197 }
7198
0348d6fd
RS
7199 /* Return an address to a char[0:len-1]* temporary for
7200 character pointers. */
50dbf0b4
JW
7201 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7202 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
0348d6fd 7203 {
5cc5439e 7204 var = gfc_create_var (type, "pstr");
0348d6fd 7205
11492349
TB
7206 if ((!comp && sym->attr.allocatable)
7207 || (comp && comp->attr.allocatable))
8ae1ec92
AF
7208 {
7209 gfc_add_modify (&se->pre, var,
7210 fold_convert (TREE_TYPE (var),
7211 null_pointer_node));
107051a5 7212 tmp = gfc_call_free (var);
8ae1ec92
AF
7213 gfc_add_expr_to_block (&se->post, tmp);
7214 }
11492349 7215
0348d6fd 7216 /* Provide an address expression for the function arguments. */
628c189e 7217 var = gfc_build_addr_expr (NULL_TREE, var);
0348d6fd
RS
7218 }
7219 else
7220 var = gfc_conv_string_tmp (se, type, len);
7221
9771b263 7222 vec_safe_push (retargs, var);
0348d6fd
RS
7223 }
7224 else
7225 {
c61819ff 7226 gcc_assert (flag_f2c && ts.type == BT_COMPLEX);
0348d6fd
RS
7227
7228 type = gfc_get_complex_type (ts.kind);
628c189e 7229 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
9771b263 7230 vec_safe_push (retargs, var);
0348d6fd
RS
7231 }
7232
8ae1ec92
AF
7233 /* Add the string length to the argument list. */
7234 if (ts.type == BT_CHARACTER && ts.deferred)
8d51f26f
PT
7235 {
7236 tmp = len;
d168c883 7237 if (!VAR_P (tmp))
8d51f26f 7238 tmp = gfc_evaluate_now (len, &se->pre);
afbc5ae8
PT
7239 TREE_STATIC (tmp) = 1;
7240 gfc_add_modify (&se->pre, tmp,
7241 build_int_cst (TREE_TYPE (tmp), 0));
8ae1ec92 7242 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
9771b263 7243 vec_safe_push (retargs, tmp);
8d51f26f 7244 }
8ae1ec92 7245 else if (ts.type == BT_CHARACTER)
9771b263 7246 vec_safe_push (retargs, len);
0348d6fd 7247 }
62ab4a54 7248 gfc_free_interface_mapping (&mapping);
0348d6fd 7249
989ea525 7250 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
60f97ac8
TB
7251 arglen = (vec_safe_length (arglist) + vec_safe_length (optionalargs)
7252 + vec_safe_length (stringargs) + vec_safe_length (append_args));
9771b263 7253 vec_safe_reserve (retargs, arglen);
989ea525 7254
0348d6fd 7255 /* Add the return arguments. */
5c4aa279 7256 vec_safe_splice (retargs, arglist);
6de9cd9a 7257
60f97ac8 7258 /* Add the hidden present status for optional+value to the arguments. */
5c4aa279 7259 vec_safe_splice (retargs, optionalargs);
60f97ac8 7260
6de9cd9a 7261 /* Add the hidden string length parameters to the arguments. */
5c4aa279 7262 vec_safe_splice (retargs, stringargs);
6de9cd9a 7263
5a0aad31
FXC
7264 /* We may want to append extra arguments here. This is used e.g. for
7265 calls to libgfortran_matmul_??, which need extra information. */
5c4aa279
SK
7266 vec_safe_splice (retargs, append_args);
7267
989ea525 7268 arglist = retargs;
5a0aad31 7269
6de9cd9a 7270 /* Generate the actual call. */
94fae14b 7271 if (base_object == NULL_TREE)
378f53c7 7272 conv_function_val (se, sym, expr, args);
94fae14b
PT
7273 else
7274 conv_base_obj_fcn_val (se, base_object, expr);
276ca25d 7275
6de9cd9a 7276 /* If there are alternate return labels, function type should be
dda895f9 7277 integer. Can't modify the type in place though, since it can be shared
276ca25d 7278 with other functions. For dummy arguments, the typing is done to
dd5a833e 7279 this result, even if it has to be repeated for each call. */
dda895f9
JJ
7280 if (has_alternate_specifier
7281 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
7282 {
276ca25d
PT
7283 if (!sym->attr.dummy)
7284 {
7285 TREE_TYPE (sym->backend_decl)
7286 = build_function_type (integer_type_node,
7287 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
628c189e 7288 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
276ca25d
PT
7289 }
7290 else
7291 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
dda895f9 7292 }
6de9cd9a
DN
7293
7294 fntype = TREE_TYPE (TREE_TYPE (se->expr));
989ea525 7295 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
6de9cd9a 7296
26e46e4b
PT
7297 /* Allocatable scalar function results must be freed and nullified
7298 after use. This necessitates the creation of a temporary to
7299 hold the result to prevent duplicate calls. */
7300 if (!byref && sym->ts.type != BT_CHARACTER
d0e7a9fd
JW
7301 && ((sym->attr.allocatable && !sym->attr.dimension && !comp)
7302 || (comp && comp->attr.allocatable && !comp->attr.dimension)))
26e46e4b
PT
7303 {
7304 tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
7305 gfc_add_modify (&se->pre, tmp, se->expr);
7306 se->expr = tmp;
7307 tmp = gfc_call_free (tmp);
7308 gfc_add_expr_to_block (&post, tmp);
7309 gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
7310 }
7311
6d1c50cc
TS
7312 /* If we have a pointer function, but we don't want a pointer, e.g.
7313 something like
7314 x = f()
7315 where f is pointer valued, we have to dereference the result. */
5b130807 7316 if (!se->want_pointer && !byref
463ec822
JW
7317 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7318 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
7319 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
6d1c50cc 7320
973ff4c0
TS
7321 /* f2c calling conventions require a scalar default real function to
7322 return a double precision result. Convert this back to default
7323 real. We only care about the cases that can happen in Fortran 77.
7324 */
c61819ff 7325 if (flag_f2c && sym->ts.type == BT_REAL
973ff4c0
TS
7326 && sym->ts.kind == gfc_default_real_kind
7327 && !sym->attr.always_explicit)
7328 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
7329
f8d0aee5
TS
7330 /* A pure function may still have side-effects - it may modify its
7331 parameters. */
6de9cd9a
DN
7332 TREE_SIDE_EFFECTS (se->expr) = 1;
7333#if 0
7334 if (!sym->attr.pure)
7335 TREE_SIDE_EFFECTS (se->expr) = 1;
7336#endif
7337
fc90a8f2 7338 if (byref)
6de9cd9a 7339 {
fc90a8f2 7340 /* Add the function call to the pre chain. There is no expression. */
6de9cd9a 7341 gfc_add_expr_to_block (&se->pre, se->expr);
fc90a8f2 7342 se->expr = NULL_TREE;
6de9cd9a 7343
fc90a8f2 7344 if (!se->direct_byref)
6de9cd9a 7345 {
c58bb30d 7346 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
6de9cd9a 7347 {
d3d3011f 7348 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
fc90a8f2
PB
7349 {
7350 /* Check the data pointer hasn't been modified. This would
7351 happen in a function returning a pointer. */
4c73896d 7352 tmp = gfc_conv_descriptor_data_get (info->descriptor);
65a9ca82 7353 tmp = fold_build2_loc (input_location, NE_EXPR,
63ee5404 7354 logical_type_node,
65a9ca82 7355 tmp, info->data);
0d52899f
TB
7356 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
7357 gfc_msg_fault);
fc90a8f2
PB
7358 }
7359 se->expr = info->descriptor;
72caba17
PT
7360 /* Bundle in the string length. */
7361 se->string_length = len;
6de9cd9a 7362 }
50dbf0b4 7363 else if (ts.type == BT_CHARACTER)
ec09945c 7364 {
72caba17 7365 /* Dereference for character pointer results. */
50dbf0b4
JW
7366 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
7367 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
7368 se->expr = build_fold_indirect_ref_loc (input_location, var);
ec09945c 7369 else
72caba17
PT
7370 se->expr = var;
7371
8ae1ec92 7372 se->string_length = len;
fc90a8f2
PB
7373 }
7374 else
973ff4c0 7375 {
c61819ff 7376 gcc_assert (ts.type == BT_COMPLEX && flag_f2c);
50dbf0b4 7377 se->expr = build_fold_indirect_ref_loc (input_location, var);
973ff4c0 7378 }
6de9cd9a 7379 }
6de9cd9a 7380 }
dda895f9 7381
574284e9
AV
7382 /* Associate the rhs class object's meta-data with the result, when the
7383 result is a temporary. */
7384 if (args && args->expr && args->expr->ts.type == BT_CLASS
7385 && sym->ts.type == BT_CLASS && result != NULL_TREE && DECL_P (result)
7386 && !GFC_CLASS_TYPE_P (TREE_TYPE (result)))
7387 {
7388 gfc_se parmse;
7389 gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (args->expr);
7390
7391 gfc_init_se (&parmse, NULL);
7392 parmse.data_not_needed = 1;
7393 gfc_conv_expr (&parmse, class_expr);
7394 if (!DECL_LANG_SPECIFIC (result))
7395 gfc_allocate_lang_decl (result);
7396 GFC_DECL_SAVED_DESCRIPTOR (result) = parmse.expr;
7397 gfc_free_expr (class_expr);
643d4436
TB
7398 /* -fcheck= can add diagnostic code, which has to be placed before
7399 the call. */
7400 if (parmse.pre.head != NULL)
7401 gfc_add_expr_to_block (&se->pre, parmse.pre.head);
7402 gcc_assert (parmse.post.head == NULL_TREE);
574284e9
AV
7403 }
7404
f5f701ad
PT
7405 /* Follow the function call with the argument post block. */
7406 if (byref)
40c32948
PT
7407 {
7408 gfc_add_block_to_block (&se->pre, &post);
7409
7410 /* Transformational functions of derived types with allocatable
ef78bc3c
AV
7411 components must have the result allocatable components copied when the
7412 argument is actually given. */
40c32948
PT
7413 arg = expr->value.function.actual;
7414 if (result && arg && expr->rank
ef78bc3c
AV
7415 && expr->value.function.isym
7416 && expr->value.function.isym->transformational
7417 && arg->expr
7418 && arg->expr->ts.type == BT_DERIVED
7419 && arg->expr->ts.u.derived->attr.alloc_comp)
40c32948
PT
7420 {
7421 tree tmp2;
7422 /* Copy the allocatable components. We have to use a
7423 temporary here to prevent source allocatable components
7424 from being corrupted. */
7425 tmp2 = gfc_evaluate_now (result, &se->pre);
7426 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
ba85c8c3 7427 result, tmp2, expr->rank, 0);
40c32948
PT
7428 gfc_add_expr_to_block (&se->pre, tmp);
7429 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
7430 expr->rank);
7431 gfc_add_expr_to_block (&se->pre, tmp);
7432
7433 /* Finally free the temporary's data field. */
7434 tmp = gfc_conv_descriptor_data_get (tmp2);
5d81ddd0
TB
7435 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
7436 NULL_TREE, NULL_TREE, true,
ba85c8c3 7437 NULL, GFC_CAF_COARRAY_NOCOARRAY);
40c32948
PT
7438 gfc_add_expr_to_block (&se->pre, tmp);
7439 }
7440 }
f5f701ad 7441 else
43a68a9d
PT
7442 {
7443 /* For a function with a class array result, save the result as
7444 a temporary, set the info fields needed by the scalarizer and
7445 call the finalization function of the temporary. Note that the
7446 nullification of allocatable components needed by the result
7447 is done in gfc_trans_assignment_1. */
a6b22eea 7448 if (expr && ((gfc_is_class_array_function (expr)
43a68a9d
PT
7449 && se->ss && se->ss->loop)
7450 || gfc_is_alloc_class_scalar_function (expr))
7451 && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
7452 && expr->must_finalize)
7453 {
7454 tree final_fndecl;
7455 tree is_final;
7456 int n;
7457 if (se->ss && se->ss->loop)
7458 {
a6b22eea 7459 gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
43a68a9d
PT
7460 se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
7461 tmp = gfc_class_data_get (se->expr);
7462 info->descriptor = tmp;
7463 info->data = gfc_conv_descriptor_data_get (tmp);
7464 info->offset = gfc_conv_descriptor_offset_get (tmp);
7465 for (n = 0; n < se->ss->loop->dimen; n++)
7466 {
7467 tree dim = gfc_rank_cst[n];
7468 se->ss->loop->to[n] = gfc_conv_descriptor_ubound_get (tmp, dim);
7469 se->ss->loop->from[n] = gfc_conv_descriptor_lbound_get (tmp, dim);
7470 }
7471 }
7472 else
7473 {
7474 /* TODO Eliminate the doubling of temporaries. This
7475 one is necessary to ensure no memory leakage. */
7476 se->expr = gfc_evaluate_now (se->expr, &se->pre);
7477 tmp = gfc_class_data_get (se->expr);
7478 tmp = gfc_conv_scalar_to_descriptor (se, tmp,
7479 CLASS_DATA (expr->value.function.esym->result)->attr);
7480 }
7481
a6b22eea
PT
7482 if ((gfc_is_class_array_function (expr)
7483 || gfc_is_alloc_class_scalar_function (expr))
7484 && CLASS_DATA (expr->value.function.esym->result)->attr.pointer)
7485 goto no_finalization;
7486
34d9d749 7487 final_fndecl = gfc_class_vtab_final_get (se->expr);
43a68a9d 7488 is_final = fold_build2_loc (input_location, NE_EXPR,
63ee5404 7489 logical_type_node,
1312bb90 7490 final_fndecl,
43a68a9d
PT
7491 fold_convert (TREE_TYPE (final_fndecl),
7492 null_pointer_node));
7493 final_fndecl = build_fold_indirect_ref_loc (input_location,
7494 final_fndecl);
7495 tmp = build_call_expr_loc (input_location,
7496 final_fndecl, 3,
7497 gfc_build_addr_expr (NULL, tmp),
34d9d749 7498 gfc_class_vtab_size_get (se->expr),
43a68a9d 7499 boolean_false_node);
1312bb90 7500 tmp = fold_build3_loc (input_location, COND_EXPR,
43a68a9d
PT
7501 void_type_node, is_final, tmp,
7502 build_empty_stmt (input_location));
7503
7504 if (se->ss && se->ss->loop)
7505 {
1312bb90
PT
7506 gfc_prepend_expr_to_block (&se->ss->loop->post, tmp);
7507 tmp = fold_build2_loc (input_location, NE_EXPR,
7508 logical_type_node,
7509 info->data,
7510 fold_convert (TREE_TYPE (info->data),
7511 null_pointer_node));
7512 tmp = fold_build3_loc (input_location, COND_EXPR,
7513 void_type_node, tmp,
7514 gfc_call_free (info->data),
7515 build_empty_stmt (input_location));
43a68a9d
PT
7516 gfc_add_expr_to_block (&se->ss->loop->post, tmp);
7517 }
7518 else
7519 {
1312bb90
PT
7520 tree classdata;
7521 gfc_prepend_expr_to_block (&se->post, tmp);
7522 classdata = gfc_class_data_get (se->expr);
7523 tmp = fold_build2_loc (input_location, NE_EXPR,
7524 logical_type_node,
7525 classdata,
7526 fold_convert (TREE_TYPE (classdata),
7527 null_pointer_node));
7528 tmp = fold_build3_loc (input_location, COND_EXPR,
7529 void_type_node, tmp,
7530 gfc_call_free (classdata),
7531 build_empty_stmt (input_location));
43a68a9d
PT
7532 gfc_add_expr_to_block (&se->post, tmp);
7533 }
43a68a9d
PT
7534 }
7535
1312bb90 7536no_finalization:
43a68a9d
PT
7537 gfc_add_block_to_block (&se->post, &post);
7538 }
f5f701ad 7539
dda895f9 7540 return has_alternate_specifier;
6de9cd9a
DN
7541}
7542
7543
d393bbd7
FXC
7544/* Fill a character string with spaces. */
7545
7546static tree
7547fill_with_spaces (tree start, tree type, tree size)
7548{
7549 stmtblock_t block, loop;
7550 tree i, el, exit_label, cond, tmp;
7551
7552 /* For a simple char type, we can call memset(). */
7553 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
db3927fb 7554 return build_call_expr_loc (input_location,
e79983f4
MM
7555 builtin_decl_explicit (BUILT_IN_MEMSET),
7556 3, start,
d393bbd7
FXC
7557 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
7558 lang_hooks.to_target_charset (' ')),
f622221a 7559 fold_convert (size_type_node, size));
d393bbd7
FXC
7560
7561 /* Otherwise, we use a loop:
7562 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
7563 *el = (type) ' ';
7564 */
7565
7566 /* Initialize variables. */
7567 gfc_init_block (&block);
7568 i = gfc_create_var (sizetype, "i");
726a989a 7569 gfc_add_modify (&block, i, fold_convert (sizetype, size));
d393bbd7 7570 el = gfc_create_var (build_pointer_type (type), "el");
726a989a 7571 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
d393bbd7
FXC
7572 exit_label = gfc_build_label_decl (NULL_TREE);
7573 TREE_USED (exit_label) = 1;
7574
7575
7576 /* Loop body. */
7577 gfc_init_block (&loop);
7578
7579 /* Exit condition. */
63ee5404 7580 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, i,
e8160c9a 7581 build_zero_cst (sizetype));
d393bbd7 7582 tmp = build1_v (GOTO_EXPR, exit_label);
65a9ca82
TB
7583 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
7584 build_empty_stmt (input_location));
d393bbd7
FXC
7585 gfc_add_expr_to_block (&loop, tmp);
7586
7587 /* Assignment. */
65a9ca82
TB
7588 gfc_add_modify (&loop,
7589 fold_build1_loc (input_location, INDIRECT_REF, type, el),
7590 build_int_cst (type, lang_hooks.to_target_charset (' ')));
d393bbd7
FXC
7591
7592 /* Increment loop variables. */
65a9ca82
TB
7593 gfc_add_modify (&loop, i,
7594 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
7595 TYPE_SIZE_UNIT (type)));
7596 gfc_add_modify (&loop, el,
5d49b6a7
RG
7597 fold_build_pointer_plus_loc (input_location,
7598 el, TYPE_SIZE_UNIT (type)));
d393bbd7
FXC
7599
7600 /* Making the loop... actually loop! */
7601 tmp = gfc_finish_block (&loop);
7602 tmp = build1_v (LOOP_EXPR, tmp);
7603 gfc_add_expr_to_block (&block, tmp);
7604
7605 /* The exit label. */
7606 tmp = build1_v (LABEL_EXPR, exit_label);
7607 gfc_add_expr_to_block (&block, tmp);
7608
7609
7610 return gfc_finish_block (&block);
7611}
7612
7613
7b5b57b7
PB
7614/* Generate code to copy a string. */
7615
32be9f94 7616void
5cd8e123 7617gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
d393bbd7 7618 int dkind, tree slength, tree src, int skind)
7b5b57b7 7619{
5cd8e123 7620 tree tmp, dlen, slen;
0a821a92
FW
7621 tree dsc;
7622 tree ssc;
549033f3 7623 tree cond;
b3eb1e0e
FXC
7624 tree cond2;
7625 tree tmp2;
7626 tree tmp3;
7627 tree tmp4;
d393bbd7 7628 tree chartype;
b3eb1e0e 7629 stmtblock_t tempblock;
0a821a92 7630
d393bbd7
FXC
7631 gcc_assert (dkind == skind);
7632
06a54338
TB
7633 if (slength != NULL_TREE)
7634 {
f622221a 7635 slen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, slength), block);
d2886bc7 7636 ssc = gfc_string_to_single_character (slen, src, skind);
06a54338
TB
7637 }
7638 else
7639 {
f622221a 7640 slen = build_one_cst (gfc_charlen_type_node);
06a54338
TB
7641 ssc = src;
7642 }
7643
7644 if (dlength != NULL_TREE)
7645 {
f622221a 7646 dlen = gfc_evaluate_now (fold_convert (gfc_charlen_type_node, dlength), block);
d2886bc7 7647 dsc = gfc_string_to_single_character (dlen, dest, dkind);
06a54338
TB
7648 }
7649 else
7650 {
f622221a 7651 dlen = build_one_cst (gfc_charlen_type_node);
06a54338
TB
7652 dsc = dest;
7653 }
7654
067feae3
PT
7655 /* Assign directly if the types are compatible. */
7656 if (dsc != NULL_TREE && ssc != NULL_TREE
d393bbd7 7657 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
0a821a92 7658 {
726a989a 7659 gfc_add_modify (block, dsc, ssc);
0a821a92
FW
7660 return;
7661 }
7b5b57b7 7662
096308ba
JB
7663 /* The string copy algorithm below generates code like
7664
9f3dcd14
JB
7665 if (destlen > 0)
7666 {
7667 if (srclen < destlen)
7668 {
7669 memmove (dest, src, srclen);
7670 // Pad with spaces.
7671 memset (&dest[srclen], ' ', destlen - srclen);
7672 }
7673 else
7674 {
7675 // Truncate if too long.
7676 memmove (dest, src, destlen);
7677 }
7678 }
096308ba
JB
7679 */
7680
b3eb1e0e 7681 /* Do nothing if the destination length is zero. */
63ee5404 7682 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, dlen,
f622221a 7683 build_zero_cst (TREE_TYPE (dlen)));
549033f3 7684
d393bbd7
FXC
7685 /* For non-default character kinds, we have to multiply the string
7686 length by the base type size. */
7687 chartype = gfc_get_char_type (dkind);
f622221a
JB
7688 slen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (slen),
7689 slen,
7690 fold_convert (TREE_TYPE (slen),
65a9ca82 7691 TYPE_SIZE_UNIT (chartype)));
f622221a
JB
7692 dlen = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (dlen),
7693 dlen,
7694 fold_convert (TREE_TYPE (dlen),
65a9ca82 7695 TYPE_SIZE_UNIT (chartype)));
d393bbd7 7696
9a14c44d 7697 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
06a54338
TB
7698 dest = fold_convert (pvoid_type_node, dest);
7699 else
7700 dest = gfc_build_addr_expr (pvoid_type_node, dest);
7701
9a14c44d 7702 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
06a54338
TB
7703 src = fold_convert (pvoid_type_node, src);
7704 else
7705 src = gfc_build_addr_expr (pvoid_type_node, src);
36cefd39 7706
9f3dcd14 7707 /* Truncate string if source is too long. */
63ee5404 7708 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
096308ba 7709 dlen);
b3eb1e0e 7710
9f3dcd14
JB
7711 /* Copy and pad with spaces. */
7712 tmp3 = build_call_expr_loc (input_location,
7713 builtin_decl_explicit (BUILT_IN_MEMMOVE),
7714 3, dest, src,
7715 fold_convert (size_type_node, slen));
7716
345bd7eb
PT
7717 /* Wstringop-overflow appears at -O3 even though this warning is not
7718 explicitly available in fortran nor can it be switched off. If the
7719 source length is a constant, its negative appears as a very large
7720 postive number and triggers the warning in BUILTIN_MEMSET. Fixing
7721 the result of the MINUS_EXPR suppresses this spurious warning. */
7722 tmp = fold_build2_loc (input_location, MINUS_EXPR,
7723 TREE_TYPE(dlen), dlen, slen);
7724 if (slength && TREE_CONSTANT (slength))
7725 tmp = gfc_evaluate_now (tmp, block);
7726
5d49b6a7 7727 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
345bd7eb 7728 tmp4 = fill_with_spaces (tmp4, chartype, tmp);
b3eb1e0e
FXC
7729
7730 gfc_init_block (&tempblock);
9f3dcd14 7731 gfc_add_expr_to_block (&tempblock, tmp3);
b3eb1e0e
FXC
7732 gfc_add_expr_to_block (&tempblock, tmp4);
7733 tmp3 = gfc_finish_block (&tempblock);
7734
9f3dcd14
JB
7735 /* The truncated memmove if the slen >= dlen. */
7736 tmp2 = build_call_expr_loc (input_location,
7737 builtin_decl_explicit (BUILT_IN_MEMMOVE),
7738 3, dest, src,
7739 fold_convert (size_type_node, dlen));
7740
b3eb1e0e 7741 /* The whole copy_string function is there. */
65a9ca82 7742 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
9f3dcd14 7743 tmp3, tmp2);
65a9ca82
TB
7744 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
7745 build_empty_stmt (input_location));
7b5b57b7
PB
7746 gfc_add_expr_to_block (block, tmp);
7747}
7748
7749
6de9cd9a
DN
7750/* Translate a statement function.
7751 The value of a statement function reference is obtained by evaluating the
7752 expression using the values of the actual arguments for the values of the
7753 corresponding dummy arguments. */
7754
7755static void
7756gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
7757{
7758 gfc_symbol *sym;
7759 gfc_symbol *fsym;
7760 gfc_formal_arglist *fargs;
7761 gfc_actual_arglist *args;
7762 gfc_se lse;
7763 gfc_se rse;
7b5b57b7
PB
7764 gfc_saved_var *saved_vars;
7765 tree *temp_vars;
7766 tree type;
7767 tree tmp;
7768 int n;
6de9cd9a
DN
7769
7770 sym = expr->symtree->n.sym;
7771 args = expr->value.function.actual;
7772 gfc_init_se (&lse, NULL);
7773 gfc_init_se (&rse, NULL);
7774
7b5b57b7 7775 n = 0;
4cbc9039 7776 for (fargs = gfc_sym_get_dummy_args (sym); fargs; fargs = fargs->next)
7b5b57b7 7777 n++;
93acb62c
JB
7778 saved_vars = XCNEWVEC (gfc_saved_var, n);
7779 temp_vars = XCNEWVEC (tree, n);
7b5b57b7 7780
4cbc9039
JW
7781 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7782 fargs = fargs->next, n++)
6de9cd9a
DN
7783 {
7784 /* Each dummy shall be specified, explicitly or implicitly, to be
7785 scalar. */
6e45f57b 7786 gcc_assert (fargs->sym->attr.dimension == 0);
6de9cd9a 7787 fsym = fargs->sym;
6de9cd9a 7788
7b5b57b7 7789 if (fsym->ts.type == BT_CHARACTER)
6de9cd9a 7790 {
7b5b57b7 7791 /* Copy string arguments. */
9a14c44d 7792 tree arglen;
6de9cd9a 7793
9a14c44d 7794 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
bc21d315 7795 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
6de9cd9a 7796
9a14c44d
TB
7797 /* Create a temporary to hold the value. */
7798 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
7799 fsym->ts.u.cl->backend_decl
7800 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
6de9cd9a 7801
9a14c44d
TB
7802 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
7803 temp_vars[n] = gfc_create_var (type, fsym->name);
7804
7805 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
7806
7807 gfc_conv_expr (&rse, args->expr);
7808 gfc_conv_string_parameter (&rse);
7809 gfc_add_block_to_block (&se->pre, &lse.pre);
7810 gfc_add_block_to_block (&se->pre, &rse.pre);
6de9cd9a 7811
9a14c44d 7812 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
d393bbd7 7813 rse.string_length, rse.expr, fsym->ts.kind);
9a14c44d
TB
7814 gfc_add_block_to_block (&se->pre, &lse.post);
7815 gfc_add_block_to_block (&se->pre, &rse.post);
6de9cd9a
DN
7816 }
7817 else
7818 {
7819 /* For everything else, just evaluate the expression. */
9a14c44d
TB
7820
7821 /* Create a temporary to hold the value. */
7822 type = gfc_typenode_for_spec (&fsym->ts);
7823 temp_vars[n] = gfc_create_var (type, fsym->name);
7824
6de9cd9a
DN
7825 gfc_conv_expr (&lse, args->expr);
7826
7827 gfc_add_block_to_block (&se->pre, &lse.pre);
726a989a 7828 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
6de9cd9a
DN
7829 gfc_add_block_to_block (&se->pre, &lse.post);
7830 }
7b5b57b7 7831
6de9cd9a
DN
7832 args = args->next;
7833 }
7b5b57b7
PB
7834
7835 /* Use the temporary variables in place of the real ones. */
4cbc9039
JW
7836 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7837 fargs = fargs->next, n++)
7b5b57b7
PB
7838 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
7839
6de9cd9a 7840 gfc_conv_expr (se, sym->value);
7b5b57b7
PB
7841
7842 if (sym->ts.type == BT_CHARACTER)
7843 {
bc21d315 7844 gfc_conv_const_charlen (sym->ts.u.cl);
7b5b57b7
PB
7845
7846 /* Force the expression to the correct length. */
7847 if (!INTEGER_CST_P (se->string_length)
7848 || tree_int_cst_lt (se->string_length,
bc21d315 7849 sym->ts.u.cl->backend_decl))
7b5b57b7 7850 {
bc21d315 7851 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
7b5b57b7
PB
7852 tmp = gfc_create_var (type, sym->name);
7853 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
bc21d315 7854 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
d393bbd7
FXC
7855 sym->ts.kind, se->string_length, se->expr,
7856 sym->ts.kind);
7b5b57b7
PB
7857 se->expr = tmp;
7858 }
bc21d315 7859 se->string_length = sym->ts.u.cl->backend_decl;
7b5b57b7
PB
7860 }
7861
f8d0aee5 7862 /* Restore the original variables. */
4cbc9039
JW
7863 for (fargs = gfc_sym_get_dummy_args (sym), n = 0; fargs;
7864 fargs = fargs->next, n++)
7b5b57b7 7865 gfc_restore_sym (fargs->sym, &saved_vars[n]);
d7920cf0 7866 free (temp_vars);
cede9502 7867 free (saved_vars);
6de9cd9a
DN
7868}
7869
7870
7871/* Translate a function expression. */
7872
7873static void
7874gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
7875{
7876 gfc_symbol *sym;
7877
7878 if (expr->value.function.isym)
7879 {
7880 gfc_conv_intrinsic_function (se, expr);
7881 return;
7882 }
7883
d00be3a3
SK
7884 /* expr.value.function.esym is the resolved (specific) function symbol for
7885 most functions. However this isn't set for dummy procedures. */
7886 sym = expr->value.function.esym;
7887 if (!sym)
7888 sym = expr->symtree->n.sym;
7889
3b7ea188
FXC
7890 /* The IEEE_ARITHMETIC functions are caught here. */
7891 if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
7892 if (gfc_conv_ieee_arithmetic_function (se, expr))
7893 return;
7894
f8d0aee5 7895 /* We distinguish statement functions from general functions to improve
6de9cd9a 7896 runtime performance. */
d00be3a3 7897 if (sym->attr.proc == PROC_ST_FUNCTION)
6de9cd9a
DN
7898 {
7899 gfc_conv_statement_function (se, expr);
7900 return;
7901 }
7902
9771b263
DN
7903 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
7904 NULL);
6de9cd9a
DN
7905}
7906
f8d0aee5 7907
dfd65514
TB
7908/* Determine whether the given EXPR_CONSTANT is a zero initializer. */
7909
7910static bool
7911is_zero_initializer_p (gfc_expr * expr)
7912{
7913 if (expr->expr_type != EXPR_CONSTANT)
7914 return false;
7915
7916 /* We ignore constants with prescribed memory representations for now. */
7917 if (expr->representation.string)
7918 return false;
7919
7920 switch (expr->ts.type)
7921 {
7922 case BT_INTEGER:
7923 return mpz_cmp_si (expr->value.integer, 0) == 0;
7924
7925 case BT_REAL:
7926 return mpfr_zero_p (expr->value.real)
7927 && MPFR_SIGN (expr->value.real) >= 0;
7928
7929 case BT_LOGICAL:
7930 return expr->value.logical == 0;
7931
7932 case BT_COMPLEX:
7933 return mpfr_zero_p (mpc_realref (expr->value.complex))
7934 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
7935 && mpfr_zero_p (mpc_imagref (expr->value.complex))
7936 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
7937
7938 default:
7939 break;
7940 }
7941 return false;
7942}
7943
7944
6de9cd9a
DN
7945static void
7946gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
7947{
bcc4d4e0
MM
7948 gfc_ss *ss;
7949
7950 ss = se->ss;
7951 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
f98cfd3c 7952 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
6de9cd9a
DN
7953
7954 gfc_conv_tmp_array_ref (se);
6de9cd9a
DN
7955}
7956
7957
597073ac 7958/* Build a static initializer. EXPR is the expression for the initial value.
8b704316 7959 The other parameters describe the variable of the component being
f8d0aee5 7960 initialized. EXPR may be null. */
6de9cd9a 7961
597073ac
PB
7962tree
7963gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
1d0134b3 7964 bool array, bool pointer, bool procptr)
597073ac
PB
7965{
7966 gfc_se se;
7967
5df445a2
TB
7968 if (flag_coarray != GFC_FCOARRAY_LIB && ts->type == BT_DERIVED
7969 && ts->u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
7970 && ts->u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
7971 return build_constructor (type, NULL);
7972
1d0134b3 7973 if (!(expr || pointer || procptr))
597073ac
PB
7974 return NULL_TREE;
7975
3e708b25
CR
7976 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
7977 (these are the only two iso_c_binding derived types that can be
7978 used as initialization expressions). If so, we need to modify
7979 the 'expr' to be that for a (void *). */
dd39f783 7980 if (expr != NULL && expr->ts.type == BT_DERIVED
bc21d315 7981 && expr->ts.is_iso_c && expr->ts.u.derived)
3e708b25 7982 {
eb4a9145
RB
7983 if (TREE_CODE (type) == ARRAY_TYPE)
7984 return build_constructor (type, NULL);
7985 else if (POINTER_TYPE_P (type))
7986 return build_int_cst (type, 0);
7987 else
7988 gcc_unreachable ();
3e708b25 7989 }
8b704316 7990
1d0134b3 7991 if (array && !procptr)
597073ac 7992 {
fa9a7193 7993 tree ctor;
597073ac
PB
7994 /* Arrays need special handling. */
7995 if (pointer)
fa9a7193 7996 ctor = gfc_build_null_descriptor (type);
dfd65514
TB
7997 /* Special case assigning an array to zero. */
7998 else if (is_zero_initializer_p (expr))
fa9a7193 7999 ctor = build_constructor (type, NULL);
597073ac 8000 else
fa9a7193
JH
8001 ctor = gfc_conv_array_initializer (type, expr);
8002 TREE_STATIC (ctor) = 1;
8003 return ctor;
597073ac 8004 }
1d0134b3 8005 else if (pointer || procptr)
80f95228 8006 {
2cc6320d
JW
8007 if (ts->type == BT_CLASS && !procptr)
8008 {
8009 gfc_init_se (&se, NULL);
8010 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
8011 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8012 TREE_STATIC (se.expr) = 1;
8013 return se.expr;
8014 }
8015 else if (!expr || expr->expr_type == EXPR_NULL)
80f95228
JW
8016 return fold_convert (type, null_pointer_node);
8017 else
8018 {
8019 gfc_init_se (&se, NULL);
8020 se.want_pointer = 1;
8021 gfc_conv_expr (&se, expr);
fa9a7193 8022 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
80f95228
JW
8023 return se.expr;
8024 }
8025 }
597073ac
PB
8026 else
8027 {
8028 switch (ts->type)
8029 {
f6288c24 8030 case_bt_struct:
cf2b3c22 8031 case BT_CLASS:
597073ac 8032 gfc_init_se (&se, NULL);
f8dde8af 8033 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
2cc6320d 8034 gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
f8dde8af
JW
8035 else
8036 gfc_conv_structure (&se, expr, 1);
fa9a7193
JH
8037 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
8038 TREE_STATIC (se.expr) = 1;
597073ac
PB
8039 return se.expr;
8040
8041 case BT_CHARACTER:
6e36772b
HA
8042 if (expr->expr_type == EXPR_CONSTANT)
8043 {
8044 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl, expr);
8045 TREE_STATIC (ctor) = 1;
8046 return ctor;
8047 }
597073ac 8048
6e36772b 8049 /* Fallthrough. */
597073ac
PB
8050 default:
8051 gfc_init_se (&se, NULL);
8052 gfc_conv_constant (&se, expr);
fa9a7193 8053 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
597073ac
PB
8054 return se.expr;
8055 }
8056 }
8057}
8b704316 8058
e9cfef64
PB
8059static tree
8060gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
8061{
8062 gfc_se rse;
8063 gfc_se lse;
8064 gfc_ss *rss;
8065 gfc_ss *lss;
08dcec61 8066 gfc_array_info *lss_array;
e9cfef64
PB
8067 stmtblock_t body;
8068 stmtblock_t block;
8069 gfc_loopinfo loop;
8070 int n;
8071 tree tmp;
8072
8073 gfc_start_block (&block);
8074
8075 /* Initialize the scalarizer. */
8076 gfc_init_loopinfo (&loop);
8077
8078 gfc_init_se (&lse, NULL);
8079 gfc_init_se (&rse, NULL);
8080
8081 /* Walk the rhs. */
8082 rss = gfc_walk_expr (expr);
8083 if (rss == gfc_ss_terminator)
26f77530
MM
8084 /* The rhs is scalar. Add a ss for the expression. */
8085 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
e9cfef64
PB
8086
8087 /* Create a SS for the destination. */
66877276
MM
8088 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
8089 GFC_SS_COMPONENT);
1838afec 8090 lss_array = &lss->info->data.array;
08dcec61
MM
8091 lss_array->shape = gfc_get_shape (cm->as->rank);
8092 lss_array->descriptor = dest;
8093 lss_array->data = gfc_conv_array_data (dest);
8094 lss_array->offset = gfc_conv_array_offset (dest);
e9cfef64
PB
8095 for (n = 0; n < cm->as->rank; n++)
8096 {
08dcec61
MM
8097 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
8098 lss_array->stride[n] = gfc_index_one_node;
e9cfef64 8099
08dcec61
MM
8100 mpz_init (lss_array->shape[n]);
8101 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
e9cfef64 8102 cm->as->lower[n]->value.integer);
08dcec61 8103 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
e9cfef64 8104 }
8b704316 8105
e9cfef64
PB
8106 /* Associate the SS with the loop. */
8107 gfc_add_ss_to_loop (&loop, lss);
8108 gfc_add_ss_to_loop (&loop, rss);
8109
8110 /* Calculate the bounds of the scalarization. */
8111 gfc_conv_ss_startstride (&loop);
8112
8113 /* Setup the scalarizing loops. */
bdfd2ff0 8114 gfc_conv_loop_setup (&loop, &expr->where);
e9cfef64
PB
8115
8116 /* Setup the gfc_se structures. */
8117 gfc_copy_loopinfo_to_se (&lse, &loop);
8118 gfc_copy_loopinfo_to_se (&rse, &loop);
8119
8120 rse.ss = rss;
8121 gfc_mark_ss_chain_used (rss, 1);
8122 lse.ss = lss;
8123 gfc_mark_ss_chain_used (lss, 1);
8124
8125 /* Start the scalarized loop body. */
8126 gfc_start_scalarized_body (&loop, &body);
8127
8128 gfc_conv_tmp_array_ref (&lse);
2b052ce2 8129 if (cm->ts.type == BT_CHARACTER)
bc21d315 8130 lse.string_length = cm->ts.u.cl->backend_decl;
2b052ce2 8131
e9cfef64
PB
8132 gfc_conv_expr (&rse, expr);
8133
ed673c00 8134 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
e9cfef64
PB
8135 gfc_add_expr_to_block (&body, tmp);
8136
6e45f57b 8137 gcc_assert (rse.ss == gfc_ss_terminator);
e9cfef64
PB
8138
8139 /* Generate the copying loops. */
8140 gfc_trans_scalarizing_loops (&loop, &body);
8141
8142 /* Wrap the whole thing up. */
8143 gfc_add_block_to_block (&block, &loop.pre);
8144 gfc_add_block_to_block (&block, &loop.post);
8145
08dcec61
MM
8146 gcc_assert (lss_array->shape != NULL);
8147 gfc_free_shape (&lss_array->shape, cm->as->rank);
96654664
PB
8148 gfc_cleanup_loop (&loop);
8149
e9cfef64
PB
8150 return gfc_finish_block (&block);
8151}
8152
5046aff5 8153
b7d1d8b4
PT
8154static tree
8155gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
8156 gfc_expr * expr)
8157{
8158 gfc_se se;
b7d1d8b4
PT
8159 stmtblock_t block;
8160 tree offset;
8161 int n;
8162 tree tmp;
8163 tree tmp2;
8164 gfc_array_spec *as;
8165 gfc_expr *arg = NULL;
8166
8167 gfc_start_block (&block);
8168 gfc_init_se (&se, NULL);
8169
8b704316 8170 /* Get the descriptor for the expressions. */
b7d1d8b4 8171 se.want_pointer = 0;
2960a368 8172 gfc_conv_expr_descriptor (&se, expr);
b7d1d8b4
PT
8173 gfc_add_block_to_block (&block, &se.pre);
8174 gfc_add_modify (&block, dest, se.expr);
8175
8176 /* Deal with arrays of derived types with allocatable components. */
f6288c24 8177 if (gfc_bt_struct (cm->ts.type)
b7d1d8b4 8178 && cm->ts.u.derived->attr.alloc_comp)
ba85c8c3 8179 // TODO: Fix caf_mode
b7d1d8b4
PT
8180 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
8181 se.expr, dest,
ba85c8c3 8182 cm->as->rank, 0);
3cd52c11
PT
8183 else if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED
8184 && CLASS_DATA(cm)->attr.allocatable)
8185 {
8186 if (cm->ts.u.derived->attr.alloc_comp)
ba85c8c3 8187 // TODO: Fix caf_mode
3cd52c11
PT
8188 tmp = gfc_copy_alloc_comp (expr->ts.u.derived,
8189 se.expr, dest,
ba85c8c3 8190 expr->rank, 0);
3cd52c11
PT
8191 else
8192 {
8193 tmp = TREE_TYPE (dest);
8194 tmp = gfc_duplicate_allocatable (dest, se.expr,
fc7d0afb 8195 tmp, expr->rank, NULL_TREE);
3cd52c11
PT
8196 }
8197 }
b7d1d8b4
PT
8198 else
8199 tmp = gfc_duplicate_allocatable (dest, se.expr,
8200 TREE_TYPE(cm->backend_decl),
fc7d0afb 8201 cm->as->rank, NULL_TREE);
b7d1d8b4
PT
8202
8203 gfc_add_expr_to_block (&block, tmp);
8204 gfc_add_block_to_block (&block, &se.post);
8205
8206 if (expr->expr_type != EXPR_VARIABLE)
8207 gfc_conv_descriptor_data_set (&block, se.expr,
8208 null_pointer_node);
8209
8210 /* We need to know if the argument of a conversion function is a
8211 variable, so that the correct lower bound can be used. */
8212 if (expr->expr_type == EXPR_FUNCTION
8213 && expr->value.function.isym
8214 && expr->value.function.isym->conversion
8215 && expr->value.function.actual->expr
8216 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
8217 arg = expr->value.function.actual->expr;
8218
8219 /* Obtain the array spec of full array references. */
8220 if (arg)
8221 as = gfc_get_full_arrayspec_from_expr (arg);
8222 else
8223 as = gfc_get_full_arrayspec_from_expr (expr);
8224
8225 /* Shift the lbound and ubound of temporaries to being unity,
8226 rather than zero, based. Always calculate the offset. */
8227 offset = gfc_conv_descriptor_offset_get (dest);
8228 gfc_add_modify (&block, offset, gfc_index_zero_node);
8229 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
8230
8231 for (n = 0; n < expr->rank; n++)
8232 {
8233 tree span;
8234 tree lbound;
8235
8236 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
8237 TODO It looks as if gfc_conv_expr_descriptor should return
8238 the correct bounds and that the following should not be
8239 necessary. This would simplify gfc_conv_intrinsic_bound
8240 as well. */
8241 if (as && as->lower[n])
8242 {
8243 gfc_se lbse;
8244 gfc_init_se (&lbse, NULL);
8245 gfc_conv_expr (&lbse, as->lower[n]);
8246 gfc_add_block_to_block (&block, &lbse.pre);
8247 lbound = gfc_evaluate_now (lbse.expr, &block);
8248 }
8249 else if (as && arg)
8250 {
8251 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
8252 lbound = gfc_conv_descriptor_lbound_get (tmp,
8253 gfc_rank_cst[n]);
8254 }
8255 else if (as)
8256 lbound = gfc_conv_descriptor_lbound_get (dest,
8257 gfc_rank_cst[n]);
8258 else
8259 lbound = gfc_index_one_node;
8260
8261 lbound = fold_convert (gfc_array_index_type, lbound);
8262
8263 /* Shift the bounds and set the offset accordingly. */
8264 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
65a9ca82
TB
8265 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8266 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
8267 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
8268 span, lbound);
b7d1d8b4
PT
8269 gfc_conv_descriptor_ubound_set (&block, dest,
8270 gfc_rank_cst[n], tmp);
8271 gfc_conv_descriptor_lbound_set (&block, dest,
8272 gfc_rank_cst[n], lbound);
8273
65a9ca82 8274 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
b7d1d8b4
PT
8275 gfc_conv_descriptor_lbound_get (dest,
8276 gfc_rank_cst[n]),
8277 gfc_conv_descriptor_stride_get (dest,
8278 gfc_rank_cst[n]));
8279 gfc_add_modify (&block, tmp2, tmp);
65a9ca82
TB
8280 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8281 offset, tmp2);
b7d1d8b4
PT
8282 gfc_conv_descriptor_offset_set (&block, dest, tmp);
8283 }
8284
8285 if (arg)
8286 {
8287 /* If a conversion expression has a null data pointer
8288 argument, nullify the allocatable component. */
8289 tree non_null_expr;
8290 tree null_expr;
8291
8292 if (arg->symtree->n.sym->attr.allocatable
8293 || arg->symtree->n.sym->attr.pointer)
8294 {
8295 non_null_expr = gfc_finish_block (&block);
8296 gfc_start_block (&block);
8297 gfc_conv_descriptor_data_set (&block, dest,
8298 null_pointer_node);
8299 null_expr = gfc_finish_block (&block);
8300 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
63ee5404 8301 tmp = build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
5d44e5c8 8302 fold_convert (TREE_TYPE (tmp), null_pointer_node));
b7d1d8b4
PT
8303 return build3_v (COND_EXPR, tmp,
8304 null_expr, non_null_expr);
8305 }
8306 }
8307
8308 return gfc_finish_block (&block);
8309}
8310
8311
9b548517
AV
8312/* Allocate or reallocate scalar component, as necessary. */
8313
8314static void
8315alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
8316 tree comp,
8317 gfc_component *cm,
8318 gfc_expr *expr2,
8319 gfc_symbol *sym)
8320{
8321 tree tmp;
3cd52c11 8322 tree ptr;
9b548517
AV
8323 tree size;
8324 tree size_in_bytes;
8325 tree lhs_cl_size = NULL_TREE;
8326
8327 if (!comp)
8328 return;
8329
8330 if (!expr2 || expr2->rank)
8331 return;
8332
8333 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
8334
8335 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8336 {
8337 char name[GFC_MAX_SYMBOL_LEN+9];
8338 gfc_component *strlen;
8339 /* Use the rhs string length and the lhs element size. */
8340 gcc_assert (expr2->ts.type == BT_CHARACTER);
8341 if (!expr2->ts.u.cl->backend_decl)
8342 {
8343 gfc_conv_string_length (expr2->ts.u.cl, expr2, block);
8344 gcc_assert (expr2->ts.u.cl->backend_decl);
8345 }
8346
8347 size = expr2->ts.u.cl->backend_decl;
8348
8349 /* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
8350 component. */
8351 sprintf (name, "_%s_length", cm->name);
f6288c24 8352 strlen = gfc_find_component (sym, name, true, true, NULL);
9b548517
AV
8353 lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
8354 gfc_charlen_type_node,
8355 TREE_OPERAND (comp, 0),
8356 strlen->backend_decl, NULL_TREE);
8357
8358 tmp = TREE_TYPE (gfc_typenode_for_spec (&cm->ts));
8359 tmp = TYPE_SIZE_UNIT (tmp);
8360 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
8361 TREE_TYPE (tmp), tmp,
8362 fold_convert (TREE_TYPE (tmp), size));
8363 }
255388b8
AV
8364 else if (cm->ts.type == BT_CLASS)
8365 {
8366 gcc_assert (expr2->ts.type == BT_CLASS || expr2->ts.type == BT_DERIVED);
8367 if (expr2->ts.type == BT_DERIVED)
8368 {
8369 tmp = gfc_get_symbol_decl (expr2->ts.u.derived);
8370 size = TYPE_SIZE_UNIT (tmp);
8371 }
8372 else
8373 {
8374 gfc_expr *e2vtab;
8375 gfc_se se;
8376 e2vtab = gfc_find_and_cut_at_last_class_ref (expr2);
8377 gfc_add_vptr_component (e2vtab);
8378 gfc_add_size_component (e2vtab);
8379 gfc_init_se (&se, NULL);
8380 gfc_conv_expr (&se, e2vtab);
8381 gfc_add_block_to_block (block, &se.pre);
8382 size = fold_convert (size_type_node, se.expr);
8383 gfc_free_expr (e2vtab);
8384 }
8385 size_in_bytes = size;
8386 }
9b548517
AV
8387 else
8388 {
8389 /* Otherwise use the length in bytes of the rhs. */
8390 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&cm->ts));
8391 size_in_bytes = size;
8392 }
8393
8394 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
8395 size_in_bytes, size_one_node);
8396
8397 if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
8398 {
8399 tmp = build_call_expr_loc (input_location,
8400 builtin_decl_explicit (BUILT_IN_CALLOC),
8401 2, build_one_cst (size_type_node),
8402 size_in_bytes);
8403 tmp = fold_convert (TREE_TYPE (comp), tmp);
8404 gfc_add_modify (block, comp, tmp);
8405 }
8406 else
8407 {
8408 tmp = build_call_expr_loc (input_location,
8409 builtin_decl_explicit (BUILT_IN_MALLOC),
8410 1, size_in_bytes);
3cd52c11
PT
8411 if (GFC_CLASS_TYPE_P (TREE_TYPE (comp)))
8412 ptr = gfc_class_data_get (comp);
8413 else
8414 ptr = comp;
8415 tmp = fold_convert (TREE_TYPE (ptr), tmp);
8416 gfc_add_modify (block, ptr, tmp);
9b548517
AV
8417 }
8418
8419 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8420 /* Update the lhs character length. */
f622221a
JB
8421 gfc_add_modify (block, lhs_cl_size,
8422 fold_convert (TREE_TYPE (lhs_cl_size), size));
9b548517
AV
8423}
8424
8425
e9cfef64
PB
8426/* Assign a single component of a derived type constructor. */
8427
8428static tree
9b548517
AV
8429gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
8430 gfc_symbol *sym, bool init)
e9cfef64
PB
8431{
8432 gfc_se se;
5046aff5 8433 gfc_se lse;
e9cfef64
PB
8434 stmtblock_t block;
8435 tree tmp;
3cd52c11 8436 tree vtab;
e9cfef64
PB
8437
8438 gfc_start_block (&block);
5046aff5 8439
640a4c59 8440 if (cm->attr.pointer || cm->attr.proc_pointer)
e9cfef64 8441 {
9b548517 8442 /* Only care about pointers here, not about allocatables. */
e9cfef64
PB
8443 gfc_init_se (&se, NULL);
8444 /* Pointer component. */
b1dc55ad
TB
8445 if ((cm->attr.dimension || cm->attr.codimension)
8446 && !cm->attr.proc_pointer)
e9cfef64
PB
8447 {
8448 /* Array pointer. */
8449 if (expr->expr_type == EXPR_NULL)
4c73896d 8450 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
e9cfef64
PB
8451 else
8452 {
e9cfef64
PB
8453 se.direct_byref = 1;
8454 se.expr = dest;
2960a368 8455 gfc_conv_expr_descriptor (&se, expr);
e9cfef64
PB
8456 gfc_add_block_to_block (&block, &se.pre);
8457 gfc_add_block_to_block (&block, &se.post);
8458 }
8459 }
8460 else
8461 {
8462 /* Scalar pointers. */
8463 se.want_pointer = 1;
8464 gfc_conv_expr (&se, expr);
8465 gfc_add_block_to_block (&block, &se.pre);
640a4c59
TB
8466
8467 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
8468 && expr->symtree->n.sym->attr.dummy)
8469 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
8470
726a989a 8471 gfc_add_modify (&block, dest,
e9cfef64
PB
8472 fold_convert (TREE_TYPE (dest), se.expr));
8473 gfc_add_block_to_block (&block, &se.post);
8474 }
8475 }
cf2b3c22
TB
8476 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
8477 {
8478 /* NULL initialization for CLASS components. */
8479 tmp = gfc_trans_structure_assign (dest,
9b548517
AV
8480 gfc_class_initializer (&cm->ts, expr),
8481 false);
cf2b3c22
TB
8482 gfc_add_expr_to_block (&block, tmp);
8483 }
b1dc55ad
TB
8484 else if ((cm->attr.dimension || cm->attr.codimension)
8485 && !cm->attr.proc_pointer)
e9cfef64 8486 {
d4b7d0f0 8487 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
5046aff5 8488 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
5bab4c96 8489 else if (cm->attr.allocatable || cm->attr.pdt_array)
28114dad 8490 {
b7d1d8b4 8491 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
28114dad 8492 gfc_add_expr_to_block (&block, tmp);
28114dad 8493 }
5046aff5 8494 else
28114dad 8495 {
5046aff5
PT
8496 tmp = gfc_trans_subarray_assign (dest, cm, expr);
8497 gfc_add_expr_to_block (&block, tmp);
28114dad 8498 }
e9cfef64 8499 }
3cd52c11
PT
8500 else if (cm->ts.type == BT_CLASS
8501 && CLASS_DATA (cm)->attr.dimension
8502 && CLASS_DATA (cm)->attr.allocatable
8503 && expr->ts.type == BT_DERIVED)
8504 {
8505 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
8506 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
8507 tmp = gfc_class_vptr_get (dest);
8508 gfc_add_modify (&block, tmp,
8509 fold_convert (TREE_TYPE (tmp), vtab));
8510 tmp = gfc_class_data_get (dest);
8511 tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
8512 gfc_add_expr_to_block (&block, tmp);
8513 }
29eb509c
AV
8514 else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
8515 {
8516 /* NULL initialization for allocatable components. */
8517 gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
8518 null_pointer_node));
8519 }
9b548517 8520 else if (init && (cm->attr.allocatable
255388b8
AV
8521 || (cm->ts.type == BT_CLASS && CLASS_DATA (cm)->attr.allocatable
8522 && expr->ts.type != BT_CLASS)))
9b548517
AV
8523 {
8524 /* Take care about non-array allocatable components here. The alloc_*
8525 routine below is motivated by the alloc_scalar_allocatable_for_
8526 assignment() routine, but with the realloc portions removed and
8527 different input. */
8528 alloc_scalar_allocatable_for_subcomponent_assignment (&block,
8529 dest,
8530 cm,
8531 expr,
8532 sym);
8533 /* The remainder of these instructions follow the if (cm->attr.pointer)
8534 if (!cm->attr.dimension) part above. */
8535 gfc_init_se (&se, NULL);
8536 gfc_conv_expr (&se, expr);
8537 gfc_add_block_to_block (&block, &se.pre);
8538
8539 if (expr->symtree && expr->symtree->n.sym->attr.proc_pointer
8540 && expr->symtree->n.sym->attr.dummy)
8541 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
3cd52c11
PT
8542
8543 if (cm->ts.type == BT_CLASS && expr->ts.type == BT_DERIVED)
8544 {
8545 tmp = gfc_class_data_get (dest);
8546 tmp = build_fold_indirect_ref_loc (input_location, tmp);
8547 vtab = gfc_get_symbol_decl (gfc_find_vtab (&expr->ts));
8548 vtab = gfc_build_addr_expr (NULL_TREE, vtab);
8549 gfc_add_modify (&block, gfc_class_vptr_get (dest),
8550 fold_convert (TREE_TYPE (gfc_class_vptr_get (dest)), vtab));
8551 }
8552 else
8553 tmp = build_fold_indirect_ref_loc (input_location, dest);
8554
9b548517
AV
8555 /* For deferred strings insert a memcpy. */
8556 if (cm->ts.type == BT_CHARACTER && cm->ts.deferred)
8557 {
8558 tree size;
8559 gcc_assert (se.string_length || expr->ts.u.cl->backend_decl);
8560 size = size_of_string_in_bytes (cm->ts.kind, se.string_length
8561 ? se.string_length
8562 : expr->ts.u.cl->backend_decl);
8563 tmp = gfc_build_memcpy_call (tmp, se.expr, size);
8564 gfc_add_expr_to_block (&block, tmp);
8565 }
8566 else
8567 gfc_add_modify (&block, tmp,
8568 fold_convert (TREE_TYPE (tmp), se.expr));
8569 gfc_add_block_to_block (&block, &se.post);
8570 }
f8da53e0
FR
8571 else if (expr->ts.type == BT_UNION)
8572 {
8573 tree tmp;
8574 gfc_constructor *c = gfc_constructor_first (expr->value.constructor);
8575 /* We mark that the entire union should be initialized with a contrived
8576 EXPR_NULL expression at the beginning. */
f31adad4
FR
8577 if (c != NULL && c->n.component == NULL
8578 && c->expr != NULL && c->expr->expr_type == EXPR_NULL)
f8da53e0
FR
8579 {
8580 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
8581 dest, build_constructor (TREE_TYPE (dest), NULL));
8582 gfc_add_expr_to_block (&block, tmp);
8583 c = gfc_constructor_next (c);
8584 }
8585 /* The following constructor expression, if any, represents a specific
8586 map intializer, as given by the user. */
8587 if (c != NULL && c->expr != NULL)
8588 {
8589 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
8590 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
8591 gfc_add_expr_to_block (&block, tmp);
8592 }
8593 }
8594 else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
e9cfef64 8595 {
3e978d30
PT
8596 if (expr->expr_type != EXPR_STRUCTURE)
8597 {
e24ba4ab 8598 tree dealloc = NULL_TREE;
3e978d30
PT
8599 gfc_init_se (&se, NULL);
8600 gfc_conv_expr (&se, expr);
fe7a047c 8601 gfc_add_block_to_block (&block, &se.pre);
e24ba4ab
MM
8602 /* Prevent repeat evaluations in gfc_copy_alloc_comp by fixing the
8603 expression in a temporary variable and deallocate the allocatable
8604 components. Then we can the copy the expression to the result. */
a878f8e8 8605 if (cm->ts.u.derived->attr.alloc_comp
e24ba4ab
MM
8606 && expr->expr_type != EXPR_VARIABLE)
8607 {
8608 se.expr = gfc_evaluate_now (se.expr, &block);
8609 dealloc = gfc_deallocate_alloc_comp (cm->ts.u.derived, se.expr,
8610 expr->rank);
8611 }
8612 gfc_add_modify (&block, dest,
8613 fold_convert (TREE_TYPE (dest), se.expr));
8614 if (cm->ts.u.derived->attr.alloc_comp
8615 && expr->expr_type != EXPR_NULL)
a878f8e8 8616 {
ba85c8c3 8617 // TODO: Fix caf_mode
a878f8e8 8618 tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
ba85c8c3 8619 dest, expr->rank, 0);
a878f8e8 8620 gfc_add_expr_to_block (&block, tmp);
e24ba4ab
MM
8621 if (dealloc != NULL_TREE)
8622 gfc_add_expr_to_block (&block, dealloc);
a878f8e8 8623 }
fe7a047c 8624 gfc_add_block_to_block (&block, &se.post);
3e978d30
PT
8625 }
8626 else
8627 {
8628 /* Nested constructors. */
9b548517 8629 tmp = gfc_trans_structure_assign (dest, expr, expr->symtree != NULL);
3e978d30
PT
8630 gfc_add_expr_to_block (&block, tmp);
8631 }
e9cfef64 8632 }
2b3dc0db
PT
8633 else if (gfc_deferred_strlen (cm, &tmp))
8634 {
8635 tree strlen;
8636 strlen = tmp;
8637 gcc_assert (strlen);
8638 strlen = fold_build3_loc (input_location, COMPONENT_REF,
8639 TREE_TYPE (strlen),
8640 TREE_OPERAND (dest, 0),
8641 strlen, NULL_TREE);
8642
8643 if (expr->expr_type == EXPR_NULL)
8644 {
8645 tmp = build_int_cst (TREE_TYPE (cm->backend_decl), 0);
8646 gfc_add_modify (&block, dest, tmp);
8647 tmp = build_int_cst (TREE_TYPE (strlen), 0);
8648 gfc_add_modify (&block, strlen, tmp);
8649 }
8650 else
8651 {
8652 tree size;
8653 gfc_init_se (&se, NULL);
8654 gfc_conv_expr (&se, expr);
8655 size = size_of_string_in_bytes (cm->ts.kind, se.string_length);
8656 tmp = build_call_expr_loc (input_location,
8657 builtin_decl_explicit (BUILT_IN_MALLOC),
8658 1, size);
8659 gfc_add_modify (&block, dest,
8660 fold_convert (TREE_TYPE (dest), tmp));
f622221a
JB
8661 gfc_add_modify (&block, strlen,
8662 fold_convert (TREE_TYPE (strlen), se.string_length));
2b3dc0db
PT
8663 tmp = gfc_build_memcpy_call (dest, se.expr, size);
8664 gfc_add_expr_to_block (&block, tmp);
8665 }
8666 }
9b548517 8667 else if (!cm->attr.artificial)
e9cfef64 8668 {
2b3dc0db 8669 /* Scalar component (excluding deferred parameters). */
e9cfef64
PB
8670 gfc_init_se (&se, NULL);
8671 gfc_init_se (&lse, NULL);
8672
8673 gfc_conv_expr (&se, expr);
8674 if (cm->ts.type == BT_CHARACTER)
bc21d315 8675 lse.string_length = cm->ts.u.cl->backend_decl;
e9cfef64 8676 lse.expr = dest;
ed673c00 8677 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, false, false);
e9cfef64
PB
8678 gfc_add_expr_to_block (&block, tmp);
8679 }
8680 return gfc_finish_block (&block);
8681}
8682
13795658 8683/* Assign a derived type constructor to a variable. */
e9cfef64 8684
c16126ac 8685tree
ba85c8c3 8686gfc_trans_structure_assign (tree dest, gfc_expr * expr, bool init, bool coarray)
e9cfef64
PB
8687{
8688 gfc_constructor *c;
8689 gfc_component *cm;
8690 stmtblock_t block;
8691 tree field;
8692 tree tmp;
ba85c8c3 8693 gfc_se se;
e9cfef64
PB
8694
8695 gfc_start_block (&block);
b5dca6ea
TB
8696
8697 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
8698 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
8699 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
8700 {
ba85c8c3 8701 gfc_se lse;
b5dca6ea 8702
b5dca6ea
TB
8703 gfc_init_se (&se, NULL);
8704 gfc_init_se (&lse, NULL);
8705 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
8706 lse.expr = dest;
8707 gfc_add_modify (&block, lse.expr,
8708 fold_convert (TREE_TYPE (lse.expr), se.expr));
8709
8710 return gfc_finish_block (&block);
8b704316 8711 }
b5dca6ea 8712
8eea62d8
PT
8713 /* Make sure that the derived type has been completely built. */
8714 if (!expr->ts.u.derived->backend_decl
8715 || !TYPE_FIELDS (expr->ts.u.derived->backend_decl))
8716 {
8717 tmp = gfc_typenode_for_spec (&expr->ts);
8718 gcc_assert (tmp);
8719 }
8720
8721 cm = expr->ts.u.derived->components;
8722
8723
ba85c8c3
AV
8724 if (coarray)
8725 gfc_init_se (&se, NULL);
8726
b7e75771
JD
8727 for (c = gfc_constructor_first (expr->value.constructor);
8728 c; c = gfc_constructor_next (c), cm = cm->next)
e9cfef64
PB
8729 {
8730 /* Skip absent members in default initializers. */
9b548517 8731 if (!c->expr && !cm->attr.allocatable)
fe7a047c
MM
8732 continue;
8733
ba85c8c3
AV
8734 /* Register the component with the caf-lib before it is initialized.
8735 Register only allocatable components, that are not coarray'ed
8736 components (%comp[*]). Only register when the constructor is not the
8737 null-expression. */
de91486c
AV
8738 if (coarray && !cm->attr.codimension
8739 && (cm->attr.allocatable || cm->attr.pointer)
ba85c8c3
AV
8740 && (!c->expr || c->expr->expr_type == EXPR_NULL))
8741 {
8742 tree token, desc, size;
ba85c8c3
AV
8743 bool is_array = cm->ts.type == BT_CLASS
8744 ? CLASS_DATA (cm)->attr.dimension : cm->attr.dimension;
8745
8746 field = cm->backend_decl;
8747 field = fold_build3_loc (input_location, COMPONENT_REF,
8748 TREE_TYPE (field), dest, field, NULL_TREE);
8749 if (cm->ts.type == BT_CLASS)
8750 field = gfc_class_data_get (field);
8751
8752 token = is_array ? gfc_conv_descriptor_token (field)
8753 : fold_build3_loc (input_location, COMPONENT_REF,
8754 TREE_TYPE (cm->caf_token), dest,
8755 cm->caf_token, NULL_TREE);
8756
8757 if (is_array)
8758 {
8759 /* The _caf_register routine looks at the rank of the array
8760 descriptor to decide whether the data registered is an array
8761 or not. */
8762 int rank = cm->ts.type == BT_CLASS ? CLASS_DATA (cm)->as->rank
8763 : cm->as->rank;
8764 /* When the rank is not known just set a positive rank, which
8765 suffices to recognize the data as array. */
8766 if (rank < 0)
8767 rank = 1;
cbd29d0e 8768 size = build_zero_cst (size_type_node);
ba85c8c3 8769 desc = field;
7fb43006
PT
8770 gfc_add_modify (&block, gfc_conv_descriptor_rank (desc),
8771 build_int_cst (signed_char_type_node, rank));
ba85c8c3
AV
8772 }
8773 else
8774 {
e0396d77
AV
8775 desc = gfc_conv_scalar_to_descriptor (&se, field,
8776 cm->ts.type == BT_CLASS
8777 ? CLASS_DATA (cm)->attr
8778 : cm->attr);
ba85c8c3
AV
8779 size = TYPE_SIZE_UNIT (TREE_TYPE (field));
8780 }
8781 gfc_add_block_to_block (&block, &se.pre);
8782 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register,
8783 7, size, build_int_cst (
8784 integer_type_node,
8785 GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY),
8786 gfc_build_addr_expr (pvoid_type_node,
8787 token),
8788 gfc_build_addr_expr (NULL_TREE, desc),
8789 null_pointer_node, null_pointer_node,
8790 integer_zero_node);
8791 gfc_add_expr_to_block (&block, tmp);
8792 }
e9cfef64 8793 field = cm->backend_decl;
8eea62d8 8794 gcc_assert(field);
65a9ca82
TB
8795 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
8796 dest, field, NULL_TREE);
9b548517
AV
8797 if (!c->expr)
8798 {
8799 gfc_expr *e = gfc_get_null_expr (NULL);
8800 tmp = gfc_trans_subcomponent_assign (tmp, cm, e, expr->ts.u.derived,
8801 init);
8802 gfc_free_expr (e);
8803 }
8804 else
8805 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr,
8806 expr->ts.u.derived, init);
e9cfef64
PB
8807 gfc_add_expr_to_block (&block, tmp);
8808 }
8809 return gfc_finish_block (&block);
8810}
8811
f8da53e0
FR
8812void
8813gfc_conv_union_initializer (vec<constructor_elt, va_gc> *v,
8814 gfc_component *un, gfc_expr *init)
8815{
8816 gfc_constructor *ctor;
8817
8818 if (un->ts.type != BT_UNION || un == NULL || init == NULL)
8819 return;
8820
8821 ctor = gfc_constructor_first (init->value.constructor);
8822
8823 if (ctor == NULL || ctor->expr == NULL)
8824 return;
8825
8826 gcc_assert (init->expr_type == EXPR_STRUCTURE);
8827
8828 /* If we have an 'initialize all' constructor, do it first. */
8829 if (ctor->expr->expr_type == EXPR_NULL)
8830 {
8831 tree union_type = TREE_TYPE (un->backend_decl);
8832 tree val = build_constructor (union_type, NULL);
8833 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
8834 ctor = gfc_constructor_next (ctor);
8835 }
8836
8837 /* Add the map initializer on top. */
8838 if (ctor != NULL && ctor->expr != NULL)
8839 {
8840 gcc_assert (ctor->expr->expr_type == EXPR_STRUCTURE);
8841 tree val = gfc_conv_initializer (ctor->expr, &un->ts,
8842 TREE_TYPE (un->backend_decl),
8843 un->attr.dimension, un->attr.pointer,
8844 un->attr.proc_pointer);
8845 CONSTRUCTOR_APPEND_ELT (v, un->backend_decl, val);
8846 }
8847}
8848
6de9cd9a
DN
8849/* Build an expression for a constructor. If init is nonzero then
8850 this is part of a static variable initializer. */
8851
8852void
8853gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
8854{
8855 gfc_constructor *c;
8856 gfc_component *cm;
6de9cd9a 8857 tree val;
6de9cd9a 8858 tree type;
e9cfef64 8859 tree tmp;
9771b263 8860 vec<constructor_elt, va_gc> *v = NULL;
6de9cd9a 8861
6e45f57b
PB
8862 gcc_assert (se->ss == NULL);
8863 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
6de9cd9a 8864 type = gfc_typenode_for_spec (&expr->ts);
e9cfef64
PB
8865
8866 if (!init)
8867 {
8868 /* Create a temporary variable and fill it in. */
bc21d315 8869 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
9b548517
AV
8870 /* The symtree in expr is NULL, if the code to generate is for
8871 initializing the static members only. */
ba85c8c3
AV
8872 tmp = gfc_trans_structure_assign (se->expr, expr, expr->symtree != NULL,
8873 se->want_coarray);
e9cfef64
PB
8874 gfc_add_expr_to_block (&se->pre, tmp);
8875 return;
8876 }
8877
bc21d315 8878 cm = expr->ts.u.derived->components;
5046aff5 8879
b7e75771
JD
8880 for (c = gfc_constructor_first (expr->value.constructor);
8881 c; c = gfc_constructor_next (c), cm = cm->next)
6de9cd9a 8882 {
5046aff5
PT
8883 /* Skip absent members in default initializers and allocatable
8884 components. Although the latter have a default initializer
8885 of EXPR_NULL,... by default, the static nullify is not needed
8886 since this is done every time we come into scope. */
0f0a4367 8887 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
a2581005 8888 continue;
6de9cd9a 8889
8b704316
PT
8890 if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
8891 && strcmp (cm->name, "_extends") == 0
8892 && cm->initializer->symtree)
7c1dab0d 8893 {
eece1eb9 8894 tree vtab;
7c1dab0d
JW
8895 gfc_symbol *vtabs;
8896 vtabs = cm->initializer->symtree->n.sym;
eece1eb9 8897 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
9d60be38 8898 vtab = unshare_expr_without_location (vtab);
eece1eb9 8899 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
cf2b3c22 8900 }
8b704316
PT
8901 else if (cm->ts.u.derived && strcmp (cm->name, "_size") == 0)
8902 {
8903 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
5ff0f237
RB
8904 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
8905 fold_convert (TREE_TYPE (cm->backend_decl),
8906 val));
8b704316 8907 }
5b384b3d 8908 else if (cm->ts.type == BT_INTEGER && strcmp (cm->name, "_len") == 0)
a2581005
AV
8909 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl,
8910 fold_convert (TREE_TYPE (cm->backend_decl),
8911 integer_zero_node));
f8da53e0
FR
8912 else if (cm->ts.type == BT_UNION)
8913 gfc_conv_union_initializer (v, cm, c->expr);
cf2b3c22
TB
8914 else
8915 {
8916 val = gfc_conv_initializer (c->expr, &cm->ts,
1d0134b3
JW
8917 TREE_TYPE (cm->backend_decl),
8918 cm->attr.dimension, cm->attr.pointer,
8919 cm->attr.proc_pointer);
9d60be38 8920 val = unshare_expr_without_location (val);
6de9cd9a 8921
cf2b3c22
TB
8922 /* Append it to the constructor list. */
8923 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
8924 }
6de9cd9a 8925 }
f8da53e0 8926
4038c495 8927 se->expr = build_constructor (type, v);
8b704316 8928 if (init)
51eed280 8929 TREE_CONSTANT (se->expr) = 1;
6de9cd9a
DN
8930}
8931
8932
f8d0aee5 8933/* Translate a substring expression. */
6de9cd9a
DN
8934
8935static void
8936gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
8937{
8938 gfc_ref *ref;
8939
8940 ref = expr->ref;
8941
9a251aa1 8942 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
6de9cd9a 8943
d393bbd7
FXC
8944 se->expr = gfc_build_wide_string_const (expr->ts.kind,
8945 expr->value.character.length,
8946 expr->value.character.string);
00660189 8947
6de9cd9a 8948 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
9a251aa1 8949 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
6de9cd9a 8950
9a251aa1
FXC
8951 if (ref)
8952 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
6de9cd9a
DN
8953}
8954
8955
a4f5cd44
PB
8956/* Entry point for expression translation. Evaluates a scalar quantity.
8957 EXPR is the expression to be translated, and SE is the state structure if
8958 called from within the scalarized. */
6de9cd9a
DN
8959
8960void
8961gfc_conv_expr (gfc_se * se, gfc_expr * expr)
8962{
bcc4d4e0
MM
8963 gfc_ss *ss;
8964
8965 ss = se->ss;
f98cfd3c 8966 if (ss && ss->info->expr == expr
bcc4d4e0
MM
8967 && (ss->info->type == GFC_SS_SCALAR
8968 || ss->info->type == GFC_SS_REFERENCE))
6de9cd9a 8969 {
a0add3be
MM
8970 gfc_ss_info *ss_info;
8971
8972 ss_info = ss->info;
e9cfef64 8973 /* Substitute a scalar expression evaluated outside the scalarization
14aeb3cd 8974 loop. */
99dd5a29 8975 se->expr = ss_info->data.scalar.value;
14aeb3cd 8976 if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
0192ef20
MM
8977 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
8978
a0add3be 8979 se->string_length = ss_info->string_length;
6de9cd9a
DN
8980 gfc_advance_se_ss_chain (se);
8981 return;
8982 }
8983
a8b3b0b6
CR
8984 /* We need to convert the expressions for the iso_c_binding derived types.
8985 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
8986 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
8987 typespec for the C_PTR and C_FUNPTR symbols, which has already been
8988 updated to be an integer with a kind equal to the size of a (void *). */
5b384b3d
PT
8989 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID
8990 && expr->ts.u.derived->attr.is_bind_c)
a8b3b0b6 8991 {
b5dca6ea
TB
8992 if (expr->expr_type == EXPR_VARIABLE
8993 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
8994 || expr->symtree->n.sym->intmod_sym_id
8995 == ISOCBINDING_NULL_FUNPTR))
a8b3b0b6
CR
8996 {
8997 /* Set expr_type to EXPR_NULL, which will result in
8998 null_pointer_node being used below. */
8999 expr->expr_type = EXPR_NULL;
9000 }
9001 else
9002 {
9003 /* Update the type/kind of the expression to be what the new
9004 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
cadddfdd
TB
9005 expr->ts.type = BT_INTEGER;
9006 expr->ts.f90_type = BT_VOID;
9007 expr->ts.kind = gfc_index_integer_kind;
a8b3b0b6
CR
9008 }
9009 }
c49ea23d 9010
37da591f 9011 gfc_fix_class_refs (expr);
c49ea23d 9012
6de9cd9a
DN
9013 switch (expr->expr_type)
9014 {
9015 case EXPR_OP:
9016 gfc_conv_expr_op (se, expr);
9017 break;
9018
9019 case EXPR_FUNCTION:
9020 gfc_conv_function_expr (se, expr);
9021 break;
9022
9023 case EXPR_CONSTANT:
9024 gfc_conv_constant (se, expr);
9025 break;
9026
9027 case EXPR_VARIABLE:
9028 gfc_conv_variable (se, expr);
9029 break;
9030
9031 case EXPR_NULL:
9032 se->expr = null_pointer_node;
9033 break;
9034
9035 case EXPR_SUBSTRING:
9036 gfc_conv_substring_expr (se, expr);
9037 break;
9038
9039 case EXPR_STRUCTURE:
9040 gfc_conv_structure (se, expr, 0);
9041 break;
9042
9043 case EXPR_ARRAY:
9044 gfc_conv_array_constructor_expr (se, expr);
9045 break;
9046
9047 default:
6e45f57b 9048 gcc_unreachable ();
6de9cd9a
DN
9049 break;
9050 }
9051}
9052
a4f5cd44
PB
9053/* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
9054 of an assignment. */
6de9cd9a
DN
9055void
9056gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
9057{
9058 gfc_conv_expr (se, expr);
a4f5cd44 9059 /* All numeric lvalues should have empty post chains. If not we need to
6de9cd9a 9060 figure out a way of rewriting an lvalue so that it has no post chain. */
a4f5cd44 9061 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
6de9cd9a
DN
9062}
9063
a4f5cd44 9064/* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
417ab240 9065 numeric expressions. Used for scalar values where inserting cleanup code
a4f5cd44 9066 is inconvenient. */
6de9cd9a
DN
9067void
9068gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
9069{
9070 tree val;
9071
6e45f57b 9072 gcc_assert (expr->ts.type != BT_CHARACTER);
6de9cd9a
DN
9073 gfc_conv_expr (se, expr);
9074 if (se->post.head)
9075 {
9076 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
726a989a 9077 gfc_add_modify (&se->pre, val, se->expr);
a4f5cd44
PB
9078 se->expr = val;
9079 gfc_add_block_to_block (&se->pre, &se->post);
6de9cd9a
DN
9080 }
9081}
9082
33717d59 9083/* Helper to translate an expression and convert it to a particular type. */
6de9cd9a
DN
9084void
9085gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
9086{
9087 gfc_conv_expr_val (se, expr);
9088 se->expr = convert (type, se->expr);
9089}
9090
9091
f8d0aee5 9092/* Converts an expression so that it can be passed by reference. Scalar
6de9cd9a
DN
9093 values only. */
9094
9095void
056e6860 9096gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr, bool add_clobber)
6de9cd9a 9097{
bcc4d4e0 9098 gfc_ss *ss;
6de9cd9a
DN
9099 tree var;
9100
bcc4d4e0 9101 ss = se->ss;
f98cfd3c 9102 if (ss && ss->info->expr == expr
bcc4d4e0 9103 && ss->info->type == GFC_SS_REFERENCE)
6de9cd9a 9104 {
991b4da1
PT
9105 /* Returns a reference to the scalar evaluated outside the loop
9106 for this case. */
9107 gfc_conv_expr (se, expr);
da78a067
PT
9108
9109 if (expr->ts.type == BT_CHARACTER
9110 && expr->expr_type != EXPR_FUNCTION)
9111 gfc_conv_string_parameter (se);
c16126ac 9112 else
da78a067
PT
9113 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
9114
6de9cd9a
DN
9115 return;
9116 }
9117
9118 if (expr->ts.type == BT_CHARACTER)
9119 {
9120 gfc_conv_expr (se, expr);
9121 gfc_conv_string_parameter (se);
9122 return;
9123 }
9124
9125 if (expr->expr_type == EXPR_VARIABLE)
9126 {
9127 se->want_pointer = 1;
9128 gfc_conv_expr (se, expr);
9129 if (se->post.head)
9130 {
9131 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
726a989a 9132 gfc_add_modify (&se->pre, var, se->expr);
6de9cd9a
DN
9133 gfc_add_block_to_block (&se->pre, &se->post);
9134 se->expr = var;
9135 }
bd810d63 9136 else if (add_clobber && expr->ref == NULL)
056e6860
TK
9137 {
9138 tree clobber;
9139 tree var;
9140 /* FIXME: This fails if var is passed by reference, see PR
9141 41453. */
9142 var = expr->symtree->n.sym->backend_decl;
9143 clobber = build_clobber (TREE_TYPE (var));
9144 gfc_add_modify (&se->pre, var, clobber);
9145 }
6de9cd9a
DN
9146 return;
9147 }
9148
6a56381b 9149 if (expr->expr_type == EXPR_FUNCTION
e6524a51 9150 && ((expr->value.function.esym
8c727bdf 9151 && expr->value.function.esym->result
e6524a51
TB
9152 && expr->value.function.esym->result->attr.pointer
9153 && !expr->value.function.esym->result->attr.dimension)
9b63dcab 9154 || (!expr->value.function.esym && !expr->ref
e6524a51
TB
9155 && expr->symtree->n.sym->attr.pointer
9156 && !expr->symtree->n.sym->attr.dimension)))
6a56381b
PT
9157 {
9158 se->want_pointer = 1;
9159 gfc_conv_expr (se, expr);
9160 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
726a989a 9161 gfc_add_modify (&se->pre, var, se->expr);
6a56381b
PT
9162 se->expr = var;
9163 return;
9164 }
9165
6de9cd9a
DN
9166 gfc_conv_expr (se, expr);
9167
9168 /* Create a temporary var to hold the value. */
0534fa56
RH
9169 if (TREE_CONSTANT (se->expr))
9170 {
fade9a8e
AP
9171 tree tmp = se->expr;
9172 STRIP_TYPE_NOPS (tmp);
c2255bc4
AH
9173 var = build_decl (input_location,
9174 CONST_DECL, NULL, TREE_TYPE (tmp));
fade9a8e 9175 DECL_INITIAL (var) = tmp;
3e806a3d 9176 TREE_STATIC (var) = 1;
0534fa56
RH
9177 pushdecl (var);
9178 }
9179 else
9180 {
9181 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
726a989a 9182 gfc_add_modify (&se->pre, var, se->expr);
0534fa56 9183 }
1312bb90
PT
9184
9185 if (!expr->must_finalize)
9186 gfc_add_block_to_block (&se->pre, &se->post);
6de9cd9a
DN
9187
9188 /* Take the address of that value. */
628c189e 9189 se->expr = gfc_build_addr_expr (NULL_TREE, var);
6de9cd9a
DN
9190}
9191
9192
574284e9
AV
9193/* Get the _len component for an unlimited polymorphic expression. */
9194
9195static tree
9196trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
9197{
9198 gfc_se se;
9199 gfc_ref *ref = expr->ref;
9200
9201 gfc_init_se (&se, NULL);
9202 while (ref && ref->next)
9203 ref = ref->next;
9204 gfc_add_len_component (expr);
9205 gfc_conv_expr (&se, expr);
9206 gfc_add_block_to_block (block, &se.pre);
9207 gcc_assert (se.post.head == NULL_TREE);
9208 if (ref)
9209 {
9210 gfc_free_ref_list (ref->next);
9211 ref->next = NULL;
9212 }
9213 else
9214 {
9215 gfc_free_ref_list (expr->ref);
9216 expr->ref = NULL;
9217 }
9218 return se.expr;
9219}
9220
9221
9222/* Assign _vptr and _len components as appropriate. BLOCK should be a
9223 statement-list outside of the scalarizer-loop. When code is generated, that
9224 depends on the scalarized expression, it is added to RSE.PRE.
9225 Returns le's _vptr tree and when set the len expressions in to_lenp and
9226 from_lenp to form a le%_vptr%_copy (re, le, [from_lenp, to_lenp])
9227 expression. */
9228
9229static tree
9230trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
9231 gfc_expr * re, gfc_se *rse,
9232 tree * to_lenp, tree * from_lenp)
9233{
9234 gfc_se se;
9235 gfc_expr * vptr_expr;
9236 tree tmp, to_len = NULL_TREE, from_len = NULL_TREE, lhs_vptr;
9237 bool set_vptr = false, temp_rhs = false;
9238 stmtblock_t *pre = block;
ce8dcc91 9239 tree class_expr = NULL_TREE;
574284e9
AV
9240
9241 /* Create a temporary for complicated expressions. */
9242 if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
9243 && rse->expr != NULL_TREE && !DECL_P (rse->expr))
9244 {
ce8dcc91
PT
9245 if (re->ts.type == BT_CLASS && !GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
9246 class_expr = gfc_get_class_from_expr (rse->expr);
9247
9248 if (rse->loop)
9249 pre = &rse->loop->pre;
9250 else
9251 pre = &rse->pre;
9252
9253 if (class_expr != NULL_TREE && UNLIMITED_POLY (re))
9254 {
9255 tmp = TREE_OPERAND (rse->expr, 0);
9256 tmp = gfc_create_var (TREE_TYPE (tmp), "rhs");
9257 gfc_add_modify (&rse->pre, tmp, TREE_OPERAND (rse->expr, 0));
9258 }
9259 else
9260 {
9261 tmp = gfc_create_var (TREE_TYPE (rse->expr), "rhs");
9262 gfc_add_modify (&rse->pre, tmp, rse->expr);
9263 }
9264
574284e9
AV
9265 rse->expr = tmp;
9266 temp_rhs = true;
9267 }
9268
9269 /* Get the _vptr for the left-hand side expression. */
9270 gfc_init_se (&se, NULL);
9271 vptr_expr = gfc_find_and_cut_at_last_class_ref (le);
9272 if (vptr_expr != NULL && gfc_expr_attr (vptr_expr).class_ok)
9273 {
9274 /* Care about _len for unlimited polymorphic entities. */
9275 if (UNLIMITED_POLY (vptr_expr)
9276 || (vptr_expr->ts.type == BT_DERIVED
9277 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9278 to_len = trans_get_upoly_len (block, vptr_expr);
9279 gfc_add_vptr_component (vptr_expr);
9280 set_vptr = true;
9281 }
9282 else
9283 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
9284 se.want_pointer = 1;
9285 gfc_conv_expr (&se, vptr_expr);
9286 gfc_free_expr (vptr_expr);
9287 gfc_add_block_to_block (block, &se.pre);
9288 gcc_assert (se.post.head == NULL_TREE);
9289 lhs_vptr = se.expr;
9290 STRIP_NOPS (lhs_vptr);
9291
9292 /* Set the _vptr only when the left-hand side of the assignment is a
9293 class-object. */
9294 if (set_vptr)
9295 {
9296 /* Get the vptr from the rhs expression only, when it is variable.
9297 Functions are expected to be assigned to a temporary beforehand. */
575b527e 9298 vptr_expr = (re->expr_type == EXPR_VARIABLE && re->ts.type == BT_CLASS)
574284e9
AV
9299 ? gfc_find_and_cut_at_last_class_ref (re)
9300 : NULL;
9301 if (vptr_expr != NULL && vptr_expr->ts.type == BT_CLASS)
9302 {
9303 if (to_len != NULL_TREE)
9304 {
9305 /* Get the _len information from the rhs. */
9306 if (UNLIMITED_POLY (vptr_expr)
9307 || (vptr_expr->ts.type == BT_DERIVED
9308 && vptr_expr->ts.u.derived->attr.unlimited_polymorphic))
9309 from_len = trans_get_upoly_len (block, vptr_expr);
9310 }
9311 gfc_add_vptr_component (vptr_expr);
9312 }
9313 else
9314 {
9315 if (re->expr_type == EXPR_VARIABLE
9316 && DECL_P (re->symtree->n.sym->backend_decl)
9317 && DECL_LANG_SPECIFIC (re->symtree->n.sym->backend_decl)
9318 && GFC_DECL_SAVED_DESCRIPTOR (re->symtree->n.sym->backend_decl)
9319 && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (
9320 re->symtree->n.sym->backend_decl))))
9321 {
9322 vptr_expr = NULL;
9323 se.expr = gfc_class_vptr_get (GFC_DECL_SAVED_DESCRIPTOR (
9324 re->symtree->n.sym->backend_decl));
9325 if (to_len)
9326 from_len = gfc_class_len_get (GFC_DECL_SAVED_DESCRIPTOR (
9327 re->symtree->n.sym->backend_decl));
9328 }
9329 else if (temp_rhs && re->ts.type == BT_CLASS)
9330 {
9331 vptr_expr = NULL;
ce8dcc91
PT
9332 if (class_expr)
9333 tmp = class_expr;
9334 else if (!GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
9335 tmp = gfc_get_class_from_expr (rse->expr);
9336 else
9337 tmp = rse->expr;
9338
9339 se.expr = gfc_class_vptr_get (tmp);
6017b8f0 9340 if (UNLIMITED_POLY (re))
ce8dcc91
PT
9341 from_len = gfc_class_len_get (tmp);
9342
574284e9
AV
9343 }
9344 else if (re->expr_type != EXPR_NULL)
9345 /* Only when rhs is non-NULL use its declared type for vptr
9346 initialisation. */
9347 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&re->ts));
9348 else
9349 /* When the rhs is NULL use the vtab of lhs' declared type. */
9350 vptr_expr = gfc_lval_expr_from_sym (gfc_find_vtab (&le->ts));
9351 }
9352
9353 if (vptr_expr)
9354 {
9355 gfc_init_se (&se, NULL);
9356 se.want_pointer = 1;
9357 gfc_conv_expr (&se, vptr_expr);
9358 gfc_free_expr (vptr_expr);
9359 gfc_add_block_to_block (block, &se.pre);
9360 gcc_assert (se.post.head == NULL_TREE);
9361 }
9362 gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
9363 se.expr));
9364
9365 if (to_len != NULL_TREE)
9366 {
9367 /* The _len component needs to be set. Figure how to get the
9368 value of the right-hand side. */
9369 if (from_len == NULL_TREE)
9370 {
9371 if (rse->string_length != NULL_TREE)
9372 from_len = rse->string_length;
9373 else if (re->ts.type == BT_CHARACTER && re->ts.u.cl->length)
9374 {
574284e9
AV
9375 gfc_init_se (&se, NULL);
9376 gfc_conv_expr (&se, re->ts.u.cl->length);
9377 gfc_add_block_to_block (block, &se.pre);
9378 gcc_assert (se.post.head == NULL_TREE);
9379 from_len = gfc_evaluate_now (se.expr, block);
9380 }
9381 else
f622221a 9382 from_len = build_zero_cst (gfc_charlen_type_node);
574284e9
AV
9383 }
9384 gfc_add_modify (pre, to_len, fold_convert (TREE_TYPE (to_len),
9385 from_len));
9386 }
9387 }
9388
9389 /* Return the _len trees only, when requested. */
9390 if (to_lenp)
9391 *to_lenp = to_len;
9392 if (from_lenp)
9393 *from_lenp = from_len;
9394 return lhs_vptr;
9395}
9396
de91486c
AV
9397
9398/* Assign tokens for pointer components. */
9399
9400static void
9401trans_caf_token_assign (gfc_se *lse, gfc_se *rse, gfc_expr *expr1,
9402 gfc_expr *expr2)
9403{
9404 symbol_attribute lhs_attr, rhs_attr;
9405 tree tmp, lhs_tok, rhs_tok;
9406 /* Flag to indicated component refs on the rhs. */
9407 bool rhs_cr;
9408
9409 lhs_attr = gfc_caf_attr (expr1);
9410 if (expr2->expr_type != EXPR_NULL)
9411 {
9412 rhs_attr = gfc_caf_attr (expr2, false, &rhs_cr);
9413 if (lhs_attr.codimension && rhs_attr.codimension)
9414 {
9415 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
9416 lhs_tok = build_fold_indirect_ref (lhs_tok);
9417
9418 if (rhs_cr)
9419 rhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (rse, expr2);
9420 else
9421 {
9422 tree caf_decl;
9423 caf_decl = gfc_get_tree_for_caf_expr (expr2);
9424 gfc_get_caf_token_offset (rse, &rhs_tok, NULL, caf_decl,
9425 NULL_TREE, NULL);
9426 }
9427 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9428 lhs_tok,
9429 fold_convert (TREE_TYPE (lhs_tok), rhs_tok));
9430 gfc_prepend_expr_to_block (&lse->post, tmp);
9431 }
9432 }
9433 else if (lhs_attr.codimension)
9434 {
9435 lhs_tok = gfc_get_ultimate_alloc_ptr_comps_caf_token (lse, expr1);
9436 lhs_tok = build_fold_indirect_ref (lhs_tok);
9437 tmp = build2_loc (input_location, MODIFY_EXPR, void_type_node,
9438 lhs_tok, null_pointer_node);
9439 gfc_prepend_expr_to_block (&lse->post, tmp);
9440 }
9441}
9442
574284e9 9443
da3723a8
PT
9444/* Do everything that is needed for a CLASS function expr2. */
9445
9446static tree
9447trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
9448 gfc_expr *expr1, gfc_expr *expr2)
9449{
9450 tree expr1_vptr = NULL_TREE;
9451 tree tmp;
9452
9453 gfc_conv_function_expr (rse, expr2);
9454 rse->expr = gfc_evaluate_now (rse->expr, &rse->pre);
9455
9456 if (expr1->ts.type != BT_CLASS)
9457 rse->expr = gfc_class_data_get (rse->expr);
9458 else
9459 {
9460 expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
9461 expr2, rse,
9462 NULL, NULL);
9463 gfc_add_block_to_block (block, &rse->pre);
9464 tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
9465 gfc_add_modify (&lse->pre, tmp, rse->expr);
9466
9467 gfc_add_modify (&lse->pre, expr1_vptr,
9468 fold_convert (TREE_TYPE (expr1_vptr),
9469 gfc_class_vptr_get (tmp)));
9470 rse->expr = gfc_class_data_get (tmp);
9471 }
9472
9473 return expr1_vptr;
9474}
9475
9476
6de9cd9a
DN
9477tree
9478gfc_trans_pointer_assign (gfc_code * code)
9479{
a513927a 9480 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
6de9cd9a
DN
9481}
9482
9483
fc90a8f2
PB
9484/* Generate code for a pointer assignment. */
9485
6de9cd9a
DN
9486tree
9487gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
9488{
9489 gfc_se lse;
9490 gfc_se rse;
6de9cd9a 9491 stmtblock_t block;
8aeca7fd
RS
9492 tree desc;
9493 tree tmp;
da3723a8 9494 tree expr1_vptr = NULL_TREE;
8e73afcf 9495 bool scalar, non_proc_ptr_assign;
2960a368 9496 gfc_ss *ss;
1d6b7f39 9497
6de9cd9a
DN
9498 gfc_start_block (&block);
9499
9500 gfc_init_se (&lse, NULL);
9501
574284e9 9502 /* Usually testing whether this is not a proc pointer assignment. */
8e73afcf
PT
9503 non_proc_ptr_assign = !(gfc_expr_attr (expr1).proc_pointer
9504 && expr2->expr_type == EXPR_VARIABLE
9505 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE);
574284e9 9506
2960a368
TB
9507 /* Check whether the expression is a scalar or not; we cannot use
9508 expr1->rank as it can be nonzero for proc pointers. */
9509 ss = gfc_walk_expr (expr1);
9510 scalar = ss == gfc_ss_terminator;
9511 if (!scalar)
9512 gfc_free_ss_chain (ss);
8b704316 9513
b882aaa8 9514 if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
8e73afcf 9515 && expr2->expr_type != EXPR_FUNCTION && non_proc_ptr_assign)
b882aaa8
TB
9516 {
9517 gfc_add_data_component (expr2);
9518 /* The following is required as gfc_add_data_component doesn't
48aa5c60 9519 update ts.type if there is a trailing REF_ARRAY. */
b882aaa8
TB
9520 expr2->ts.type = BT_DERIVED;
9521 }
9522
2960a368 9523 if (scalar)
6de9cd9a 9524 {
fc90a8f2 9525 /* Scalar pointers. */
6de9cd9a
DN
9526 lse.want_pointer = 1;
9527 gfc_conv_expr (&lse, expr1);
6de9cd9a
DN
9528 gfc_init_se (&rse, NULL);
9529 rse.want_pointer = 1;
da3723a8
PT
9530 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9531 trans_class_pointer_fcn (&block, &lse, &rse, expr1, expr2);
9532 else
9533 gfc_conv_expr (&rse, expr2);
8fb74da4 9534
8e73afcf 9535 if (non_proc_ptr_assign && expr1->ts.type == BT_CLASS)
574284e9
AV
9536 {
9537 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
9538 NULL);
9539 lse.expr = gfc_class_data_get (lse.expr);
9540 }
9541
8fb74da4
JW
9542 if (expr1->symtree->n.sym->attr.proc_pointer
9543 && expr1->symtree->n.sym->attr.dummy)
db3927fb 9544 lse.expr = build_fold_indirect_ref_loc (input_location,
da3723a8 9545 lse.expr);
8fb74da4 9546
c74b74a8
JW
9547 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
9548 && expr2->symtree->n.sym->attr.dummy)
db3927fb 9549 rse.expr = build_fold_indirect_ref_loc (input_location,
da3723a8 9550 rse.expr);
c74b74a8 9551
6de9cd9a
DN
9552 gfc_add_block_to_block (&block, &lse.pre);
9553 gfc_add_block_to_block (&block, &rse.pre);
fb5bc08b
DK
9554
9555 /* Check character lengths if character expression. The test is only
8d51f26f
PT
9556 really added if -fbounds-check is enabled. Exclude deferred
9557 character length lefthand sides. */
50dbf0b4 9558 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
8ae1ec92 9559 && !expr1->ts.deferred
50dbf0b4 9560 && !expr1->symtree->n.sym->attr.proc_pointer
2a573572 9561 && !gfc_is_proc_ptr_comp (expr1))
fb5bc08b
DK
9562 {
9563 gcc_assert (expr2->ts.type == BT_CHARACTER);
9564 gcc_assert (lse.string_length && rse.string_length);
9565 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
9566 lse.string_length, rse.string_length,
9567 &block);
9568 }
9569
8d51f26f
PT
9570 /* The assignment to an deferred character length sets the string
9571 length to that of the rhs. */
8ae1ec92 9572 if (expr1->ts.deferred)
8d51f26f 9573 {
8ae1ec92 9574 if (expr2->expr_type != EXPR_NULL && lse.string_length != NULL)
ee2d3987
JB
9575 gfc_add_modify (&block, lse.string_length,
9576 fold_convert (TREE_TYPE (lse.string_length),
9577 rse.string_length));
8ae1ec92 9578 else if (lse.string_length != NULL)
8d51f26f 9579 gfc_add_modify (&block, lse.string_length,
f622221a 9580 build_zero_cst (TREE_TYPE (lse.string_length)));
8d51f26f
PT
9581 }
9582
726a989a 9583 gfc_add_modify (&block, lse.expr,
b882aaa8 9584 fold_convert (TREE_TYPE (lse.expr), rse.expr));
fb5bc08b 9585
de91486c
AV
9586 /* Also set the tokens for pointer components in derived typed
9587 coarrays. */
9588 if (flag_coarray == GFC_FCOARRAY_LIB)
9589 trans_caf_token_assign (&lse, &rse, expr1, expr2);
9590
6de9cd9a
DN
9591 gfc_add_block_to_block (&block, &rse.post);
9592 gfc_add_block_to_block (&block, &lse.post);
9593 }
9594 else
9595 {
99d821c0
DK
9596 gfc_ref* remap;
9597 bool rank_remap;
fb5bc08b
DK
9598 tree strlen_lhs;
9599 tree strlen_rhs = NULL_TREE;
9600
99d821c0
DK
9601 /* Array pointer. Find the last reference on the LHS and if it is an
9602 array section ref, we're dealing with bounds remapping. In this case,
9603 set it to AR_FULL so that gfc_conv_expr_descriptor does
62732c30 9604 not see it and process the bounds remapping afterwards explicitly. */
99d821c0
DK
9605 for (remap = expr1->ref; remap; remap = remap->next)
9606 if (!remap->next && remap->type == REF_ARRAY
9607 && remap->u.ar.type == AR_SECTION)
2960a368 9608 break;
99d821c0
DK
9609 rank_remap = (remap && remap->u.ar.end[0]);
9610
6573d760
HA
9611 if (remap && expr2->expr_type == EXPR_NULL)
9612 {
9613 gfc_error ("If bounds remapping is specified at %L, "
9614 "the pointer target shall not be NULL", &expr1->where);
9615 return NULL_TREE;
9616 }
9617
b882aaa8 9618 gfc_init_se (&lse, NULL);
2960a368
TB
9619 if (remap)
9620 lse.descriptor_only = 1;
9621 gfc_conv_expr_descriptor (&lse, expr1);
fb5bc08b 9622 strlen_lhs = lse.string_length;
99d821c0
DK
9623 desc = lse.expr;
9624
9625 if (expr2->expr_type == EXPR_NULL)
8aeca7fd 9626 {
8aeca7fd 9627 /* Just set the data pointer to null. */
467f18f3 9628 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
99d821c0
DK
9629 }
9630 else if (rank_remap)
9631 {
9632 /* If we are rank-remapping, just get the RHS's descriptor and
9633 process this later on. */
9634 gfc_init_se (&rse, NULL);
9635 rse.direct_byref = 1;
9636 rse.byref_noassign = 1;
b882aaa8
TB
9637
9638 if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
da3723a8
PT
9639 expr1_vptr = trans_class_pointer_fcn (&block, &lse, &rse,
9640 expr1, expr2);
b882aaa8
TB
9641 else if (expr2->expr_type == EXPR_FUNCTION)
9642 {
9643 tree bound[GFC_MAX_DIMENSIONS];
9644 int i;
9645
9646 for (i = 0; i < expr2->rank; i++)
9647 bound[i] = NULL_TREE;
9648 tmp = gfc_typenode_for_spec (&expr2->ts);
9649 tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
9650 bound, bound, 0,
9651 GFC_ARRAY_POINTER_CONT, false);
9652 tmp = gfc_create_var (tmp, "ptrtemp");
f1b5abfb
TB
9653 rse.descriptor_only = 0;
9654 rse.expr = tmp;
9655 rse.direct_byref = 1;
9656 gfc_conv_expr_descriptor (&rse, expr2);
9657 strlen_rhs = rse.string_length;
b882aaa8
TB
9658 rse.expr = tmp;
9659 }
9660 else
9661 {
9662 gfc_conv_expr_descriptor (&rse, expr2);
9663 strlen_rhs = rse.string_length;
574284e9
AV
9664 if (expr1->ts.type == BT_CLASS)
9665 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
9666 expr2, &rse,
9667 NULL, NULL);
b882aaa8 9668 }
99d821c0
DK
9669 }
9670 else if (expr2->expr_type == EXPR_VARIABLE)
9671 {
9672 /* Assign directly to the LHS's descriptor. */
375e6327 9673 lse.descriptor_only = 0;
fb5bc08b 9674 lse.direct_byref = 1;
2960a368 9675 gfc_conv_expr_descriptor (&lse, expr2);
fb5bc08b 9676 strlen_rhs = lse.string_length;
d514626e 9677 gfc_init_se (&rse, NULL);
1d6b7f39 9678
ff3598bc 9679 if (expr1->ts.type == BT_CLASS)
574284e9
AV
9680 {
9681 rse.expr = NULL_TREE;
d514626e 9682 rse.string_length = strlen_rhs;
574284e9
AV
9683 trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
9684 NULL, NULL);
9685 }
ff3598bc
PT
9686
9687 if (remap == NULL)
9688 {
9689 /* If the target is not a whole array, use the target array
9690 reference for remap. */
9691 for (remap = expr2->ref; remap; remap = remap->next)
9692 if (remap->type == REF_ARRAY
9693 && remap->u.ar.type == AR_FULL
9694 && remap->next)
9695 break;
9696 }
99d821c0 9697 }
b882aaa8
TB
9698 else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
9699 {
9700 gfc_init_se (&rse, NULL);
9701 rse.want_pointer = 1;
9702 gfc_conv_function_expr (&rse, expr2);
9703 if (expr1->ts.type != BT_CLASS)
9704 {
9705 rse.expr = gfc_class_data_get (rse.expr);
9706 gfc_add_modify (&lse.pre, desc, rse.expr);
ff3598bc
PT
9707 /* Set the lhs span. */
9708 tmp = TREE_TYPE (rse.expr);
9709 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
9710 tmp = fold_convert (gfc_array_index_type, tmp);
9711 gfc_conv_descriptor_span_set (&lse.pre, desc, tmp);
9712 }
b882aaa8
TB
9713 else
9714 {
574284e9
AV
9715 expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
9716 expr2, &rse, NULL,
9717 NULL);
029b2d55 9718 gfc_add_block_to_block (&block, &rse.pre);
b882aaa8
TB
9719 tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
9720 gfc_add_modify (&lse.pre, tmp, rse.expr);
9721
574284e9
AV
9722 gfc_add_modify (&lse.pre, expr1_vptr,
9723 fold_convert (TREE_TYPE (expr1_vptr),
b882aaa8
TB
9724 gfc_class_vptr_get (tmp)));
9725 rse.expr = gfc_class_data_get (tmp);
9726 gfc_add_modify (&lse.pre, desc, rse.expr);
9727 }
9728 }
99d821c0
DK
9729 else
9730 {
8aeca7fd
RS
9731 /* Assign to a temporary descriptor and then copy that
9732 temporary to the pointer. */
8aeca7fd 9733 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
375e6327 9734 lse.descriptor_only = 0;
8aeca7fd
RS
9735 lse.expr = tmp;
9736 lse.direct_byref = 1;
2960a368 9737 gfc_conv_expr_descriptor (&lse, expr2);
fb5bc08b 9738 strlen_rhs = lse.string_length;
726a989a 9739 gfc_add_modify (&lse.pre, desc, tmp);
fb5bc08b
DK
9740 }
9741
d514626e
JRFS
9742 if (expr1->ts.type == BT_CHARACTER
9743 && expr1->symtree->n.sym->ts.deferred
9744 && expr1->symtree->n.sym->ts.u.cl->backend_decl
9745 && VAR_P (expr1->symtree->n.sym->ts.u.cl->backend_decl))
9746 {
9747 tmp = expr1->symtree->n.sym->ts.u.cl->backend_decl;
9748 if (expr2->expr_type != EXPR_NULL)
9749 gfc_add_modify (&block, tmp,
9750 fold_convert (TREE_TYPE (tmp), strlen_rhs));
9751 else
9752 gfc_add_modify (&block, tmp, build_zero_cst (TREE_TYPE (tmp)));
9753 }
9754
6de9cd9a 9755 gfc_add_block_to_block (&block, &lse.pre);
99d821c0
DK
9756 if (rank_remap)
9757 gfc_add_block_to_block (&block, &rse.pre);
9758
9759 /* If we do bounds remapping, update LHS descriptor accordingly. */
9760 if (remap)
9761 {
9762 int dim;
9763 gcc_assert (remap->u.ar.dimen == expr1->rank);
9764
9765 if (rank_remap)
9766 {
9767 /* Do rank remapping. We already have the RHS's descriptor
9768 converted in rse and now have to build the correct LHS
9769 descriptor for it. */
9770
ff3598bc 9771 tree dtype, data, span;
99d821c0
DK
9772 tree offs, stride;
9773 tree lbound, ubound;
9774
9775 /* Set dtype. */
9776 dtype = gfc_conv_descriptor_dtype (desc);
9777 tmp = gfc_get_dtype (TREE_TYPE (desc));
9778 gfc_add_modify (&block, dtype, tmp);
9779
9780 /* Copy data pointer. */
9781 data = gfc_conv_descriptor_data_get (rse.expr);
9782 gfc_conv_descriptor_data_set (&block, desc, data);
9783
ff3598bc
PT
9784 /* Copy the span. */
9785 if (TREE_CODE (rse.expr) == VAR_DECL
9786 && GFC_DECL_PTR_ARRAY_P (rse.expr))
9787 span = gfc_conv_descriptor_span_get (rse.expr);
9788 else
9789 {
9790 tmp = TREE_TYPE (rse.expr);
9791 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
9792 span = fold_convert (gfc_array_index_type, tmp);
9793 }
9794 gfc_conv_descriptor_span_set (&block, desc, span);
9795
99d821c0
DK
9796 /* Copy offset but adjust it such that it would correspond
9797 to a lbound of zero. */
9798 offs = gfc_conv_descriptor_offset_get (rse.expr);
9799 for (dim = 0; dim < expr2->rank; ++dim)
9800 {
9801 stride = gfc_conv_descriptor_stride_get (rse.expr,
9802 gfc_rank_cst[dim]);
9803 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
9804 gfc_rank_cst[dim]);
65a9ca82
TB
9805 tmp = fold_build2_loc (input_location, MULT_EXPR,
9806 gfc_array_index_type, stride, lbound);
9807 offs = fold_build2_loc (input_location, PLUS_EXPR,
9808 gfc_array_index_type, offs, tmp);
99d821c0
DK
9809 }
9810 gfc_conv_descriptor_offset_set (&block, desc, offs);
9811
9812 /* Set the bounds as declared for the LHS and calculate strides as
9813 well as another offset update accordingly. */
9814 stride = gfc_conv_descriptor_stride_get (rse.expr,
9815 gfc_rank_cst[0]);
9816 for (dim = 0; dim < expr1->rank; ++dim)
9817 {
9818 gfc_se lower_se;
9819 gfc_se upper_se;
9820
9821 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
9822
9823 /* Convert declared bounds. */
9824 gfc_init_se (&lower_se, NULL);
9825 gfc_init_se (&upper_se, NULL);
9826 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
9827 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
9828
9829 gfc_add_block_to_block (&block, &lower_se.pre);
9830 gfc_add_block_to_block (&block, &upper_se.pre);
9831
9832 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
9833 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
9834
9835 lbound = gfc_evaluate_now (lbound, &block);
9836 ubound = gfc_evaluate_now (ubound, &block);
9837
9838 gfc_add_block_to_block (&block, &lower_se.post);
9839 gfc_add_block_to_block (&block, &upper_se.post);
9840
9841 /* Set bounds in descriptor. */
9842 gfc_conv_descriptor_lbound_set (&block, desc,
9843 gfc_rank_cst[dim], lbound);
9844 gfc_conv_descriptor_ubound_set (&block, desc,
9845 gfc_rank_cst[dim], ubound);
9846
9847 /* Set stride. */
9848 stride = gfc_evaluate_now (stride, &block);
9849 gfc_conv_descriptor_stride_set (&block, desc,
9850 gfc_rank_cst[dim], stride);
9851
9852 /* Update offset. */
9853 offs = gfc_conv_descriptor_offset_get (desc);
65a9ca82
TB
9854 tmp = fold_build2_loc (input_location, MULT_EXPR,
9855 gfc_array_index_type, lbound, stride);
9856 offs = fold_build2_loc (input_location, MINUS_EXPR,
9857 gfc_array_index_type, offs, tmp);
99d821c0
DK
9858 offs = gfc_evaluate_now (offs, &block);
9859 gfc_conv_descriptor_offset_set (&block, desc, offs);
9860
9861 /* Update stride. */
9862 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
65a9ca82
TB
9863 stride = fold_build2_loc (input_location, MULT_EXPR,
9864 gfc_array_index_type, stride, tmp);
99d821c0
DK
9865 }
9866 }
9867 else
9868 {
9869 /* Bounds remapping. Just shift the lower bounds. */
9870
9871 gcc_assert (expr1->rank == expr2->rank);
9872
9873 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
9874 {
9875 gfc_se lbound_se;
9876
99d821c0
DK
9877 gcc_assert (!remap->u.ar.end[dim]);
9878 gfc_init_se (&lbound_se, NULL);
ff3598bc
PT
9879 if (remap->u.ar.start[dim])
9880 {
9881 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
9882 gfc_add_block_to_block (&block, &lbound_se.pre);
9883 }
9884 else
9885 /* This remap arises from a target that is not a whole
9886 array. The start expressions will be NULL but we need
9887 the lbounds to be one. */
9888 lbound_se.expr = gfc_index_one_node;
99d821c0
DK
9889 gfc_conv_shift_descriptor_lbound (&block, desc,
9890 dim, lbound_se.expr);
9891 gfc_add_block_to_block (&block, &lbound_se.post);
9892 }
9893 }
9894 }
fb5bc08b 9895
99d821c0
DK
9896 /* If rank remapping was done, check with -fcheck=bounds that
9897 the target is at least as large as the pointer. */
9898 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
9899 {
9900 tree lsize, rsize;
9901 tree fault;
9902 const char* msg;
9903
9904 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
9905 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
9906
9907 lsize = gfc_evaluate_now (lsize, &block);
9908 rsize = gfc_evaluate_now (rsize, &block);
63ee5404 9909 fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
65a9ca82 9910 rsize, lsize);
99d821c0
DK
9911
9912 msg = _("Target of rank remapping is too small (%ld < %ld)");
9913 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
9914 msg, rsize, lsize);
9915 }
9916
edaff7c9
HA
9917 /* Check string lengths if applicable. The check is only really added
9918 to the output code if -fbounds-check is enabled. */
9919 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
9920 {
9921 gcc_assert (expr2->ts.type == BT_CHARACTER);
9922 gcc_assert (strlen_lhs && strlen_rhs);
9923 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
9924 strlen_lhs, strlen_rhs, &block);
9925 }
9926
6de9cd9a 9927 gfc_add_block_to_block (&block, &lse.post);
99d821c0
DK
9928 if (rank_remap)
9929 gfc_add_block_to_block (&block, &rse.post);
6de9cd9a 9930 }
99d821c0 9931
6de9cd9a
DN
9932 return gfc_finish_block (&block);
9933}
9934
9935
9936/* Makes sure se is suitable for passing as a function string parameter. */
df2fba9e 9937/* TODO: Need to check all callers of this function. It may be abused. */
6de9cd9a
DN
9938
9939void
9940gfc_conv_string_parameter (gfc_se * se)
9941{
9942 tree type;
9943
9944 if (TREE_CODE (se->expr) == STRING_CST)
9945 {
d393bbd7
FXC
9946 type = TREE_TYPE (TREE_TYPE (se->expr));
9947 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
6de9cd9a
DN
9948 return;
9949 }
9950
f4af4019
JH
9951 if ((TREE_CODE (TREE_TYPE (se->expr)) == ARRAY_TYPE
9952 || TREE_CODE (TREE_TYPE (se->expr)) == INTEGER_TYPE)
9953 && TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
6de9cd9a 9954 {
129c14bd 9955 if (TREE_CODE (se->expr) != INDIRECT_REF)
d393bbd7
FXC
9956 {
9957 type = TREE_TYPE (se->expr);
9958 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
9959 }
129c14bd
PT
9960 else
9961 {
9962 type = gfc_get_character_type_len (gfc_default_character_kind,
9963 se->string_length);
9964 type = build_pointer_type (type);
9965 se->expr = gfc_build_addr_expr (type, se->expr);
9966 }
6de9cd9a
DN
9967 }
9968
6e45f57b 9969 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
6de9cd9a
DN
9970}
9971
9972
9973/* Generate code for assignment of scalar variables. Includes character
2b56d6a4 9974 strings and derived types with allocatable components.
2d4a4400
MM
9975 If you know that the LHS has no allocations, set dealloc to false.
9976
9977 DEEP_COPY has no effect if the typespec TS is not a derived type with
9978 allocatable components. Otherwise, if it is set, an explicit copy of each
9979 allocatable component is made. This is necessary as a simple copy of the
9980 whole object would copy array descriptors as is, so that the lhs's
9981 allocatable components would point to the rhs's after the assignment.
9982 Typically, setting DEEP_COPY is necessary if the rhs is a variable, and not
9983 necessary if the rhs is a non-pointer function, as the allocatable components
9984 are not accessible by other means than the function's result after the
9985 function has returned. It is even more subtle when temporaries are involved,
9986 as the two following examples show:
9987 1. When we evaluate an array constructor, a temporary is created. Thus
9988 there is theoretically no alias possible. However, no deep copy is
9989 made for this temporary, so that if the constructor is made of one or
9990 more variable with allocatable components, those components still point
9991 to the variable's: DEEP_COPY should be set for the assignment from the
9992 temporary to the lhs in that case.
9993 2. When assigning a scalar to an array, we evaluate the scalar value out
9994 of the loop, store it into a temporary variable, and assign from that.
9995 In that case, deep copying when assigning to the temporary would be a
9996 waste of resources; however deep copies should happen when assigning from
9997 the temporary to each array element: again DEEP_COPY should be set for
9998 the assignment from the temporary to the lhs. */
6de9cd9a
DN
9999
10000tree
5046aff5 10001gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
ba85c8c3 10002 bool deep_copy, bool dealloc, bool in_coarray)
6de9cd9a 10003{
6de9cd9a 10004 stmtblock_t block;
5046aff5
PT
10005 tree tmp;
10006 tree cond;
6de9cd9a
DN
10007
10008 gfc_init_block (&block);
10009
5046aff5 10010 if (ts.type == BT_CHARACTER)
6de9cd9a 10011 {
06a54338
TB
10012 tree rlen = NULL;
10013 tree llen = NULL;
6de9cd9a 10014
06a54338
TB
10015 if (lse->string_length != NULL_TREE)
10016 {
10017 gfc_conv_string_parameter (lse);
10018 gfc_add_block_to_block (&block, &lse->pre);
10019 llen = lse->string_length;
10020 }
6de9cd9a 10021
06a54338
TB
10022 if (rse->string_length != NULL_TREE)
10023 {
06a54338
TB
10024 gfc_conv_string_parameter (rse);
10025 gfc_add_block_to_block (&block, &rse->pre);
10026 rlen = rse->string_length;
10027 }
6de9cd9a 10028
d393bbd7
FXC
10029 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
10030 rse->expr, ts.kind);
6de9cd9a 10031 }
0b627b58
PT
10032 else if (gfc_bt_struct (ts.type)
10033 && (ts.u.derived->attr.alloc_comp
10034 || (deep_copy && ts.u.derived->attr.pdt_type)))
5046aff5 10035 {
abc2d807 10036 tree tmp_var = NULL_TREE;
5046aff5 10037 cond = NULL_TREE;
2d4a4400 10038
5046aff5 10039 /* Are the rhs and the lhs the same? */
2d4a4400 10040 if (deep_copy)
5046aff5 10041 {
63ee5404 10042 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
65a9ca82
TB
10043 gfc_build_addr_expr (NULL_TREE, lse->expr),
10044 gfc_build_addr_expr (NULL_TREE, rse->expr));
5046aff5
PT
10045 cond = gfc_evaluate_now (cond, &lse->pre);
10046 }
10047
10048 /* Deallocate the lhs allocated components as long as it is not
b8247b13
PT
10049 the same as the rhs. This must be done following the assignment
10050 to prevent deallocating data that could be used in the rhs
10051 expression. */
ed673c00 10052 if (dealloc)
5046aff5 10053 {
abc2d807
TB
10054 tmp_var = gfc_evaluate_now (lse->expr, &lse->pre);
10055 tmp = gfc_deallocate_alloc_comp_no_caf (ts.u.derived, tmp_var, 0);
2d4a4400 10056 if (deep_copy)
c2255bc4
AH
10057 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10058 tmp);
b8247b13 10059 gfc_add_expr_to_block (&lse->post, tmp);
5046aff5 10060 }
28114dad 10061
b8247b13
PT
10062 gfc_add_block_to_block (&block, &rse->pre);
10063 gfc_add_block_to_block (&block, &lse->pre);
5046aff5 10064
726a989a 10065 gfc_add_modify (&block, lse->expr,
5046aff5
PT
10066 fold_convert (TREE_TYPE (lse->expr), rse->expr));
10067
abc2d807 10068 /* Restore pointer address of coarray components. */
b1adb7c4 10069 if (ts.u.derived->attr.coarray_comp && deep_copy && tmp_var != NULL_TREE)
abc2d807 10070 {
abc2d807
TB
10071 tmp = gfc_reassign_alloc_comp_caf (ts.u.derived, tmp_var, lse->expr);
10072 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10073 tmp);
10074 gfc_add_expr_to_block (&block, tmp);
10075 }
10076
5046aff5 10077 /* Do a deep copy if the rhs is a variable, if it is not the
982186b1 10078 same as the lhs. */
2d4a4400 10079 if (deep_copy)
5046aff5 10080 {
ba85c8c3
AV
10081 int caf_mode = in_coarray ? (GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
10082 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY) : 0;
10083 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0,
10084 caf_mode);
c2255bc4
AH
10085 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
10086 tmp);
5046aff5
PT
10087 gfc_add_expr_to_block (&block, tmp);
10088 }
5046aff5 10089 }
ce8dcc91 10090 else if (gfc_bt_struct (ts.type))
fbe7af45
RG
10091 {
10092 gfc_add_block_to_block (&block, &lse->pre);
10093 gfc_add_block_to_block (&block, &rse->pre);
65a9ca82
TB
10094 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10095 TREE_TYPE (lse->expr), rse->expr);
fbe7af45
RG
10096 gfc_add_modify (&block, lse->expr, tmp);
10097 }
ce8dcc91 10098 /* If possible use the rhs vptr copy with trans_scalar_class_assign.... */
9a0e09f3 10099 else if (ts.type == BT_CLASS)
ce8dcc91
PT
10100 {
10101 gfc_add_block_to_block (&block, &lse->pre);
10102 gfc_add_block_to_block (&block, &rse->pre);
9a0e09f3
PT
10103
10104 if (!trans_scalar_class_assign (&block, lse, rse))
10105 {
10106 /* ...otherwise assignment suffices. Note the use of VIEW_CONVERT_EXPR
10107 for the lhs which ensures that class data rhs cast as a string assigns
10108 correctly. */
10109 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
10110 TREE_TYPE (rse->expr), lse->expr);
10111 gfc_add_modify (&block, tmp, rse->expr);
10112 }
ce8dcc91
PT
10113 }
10114 else if (ts.type != BT_CLASS)
6de9cd9a
DN
10115 {
10116 gfc_add_block_to_block (&block, &lse->pre);
10117 gfc_add_block_to_block (&block, &rse->pre);
10118
726a989a 10119 gfc_add_modify (&block, lse->expr,
fbe7af45 10120 fold_convert (TREE_TYPE (lse->expr), rse->expr));
6de9cd9a
DN
10121 }
10122
10123 gfc_add_block_to_block (&block, &lse->post);
10124 gfc_add_block_to_block (&block, &rse->post);
10125
10126 return gfc_finish_block (&block);
10127}
10128
10129
42488c1b
PT
10130/* There are quite a lot of restrictions on the optimisation in using an
10131 array function assign without a temporary. */
6de9cd9a 10132
42488c1b
PT
10133static bool
10134arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
6de9cd9a 10135{
2853e512
PT
10136 gfc_ref * ref;
10137 bool seen_array_ref;
a61a36ab 10138 bool c = false;
42488c1b 10139 gfc_symbol *sym = expr1->symtree->n.sym;
6de9cd9a 10140
43a68a9d 10141 /* Play it safe with class functions assigned to a derived type. */
a6b22eea 10142 if (gfc_is_class_array_function (expr2)
43a68a9d
PT
10143 && expr1->ts.type == BT_DERIVED)
10144 return true;
10145
6de9cd9a
DN
10146 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
10147 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
42488c1b 10148 return true;
6de9cd9a 10149
42488c1b
PT
10150 /* Elemental functions are scalarized so that they don't need a
10151 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
10152 they would need special treatment in gfc_trans_arrayfunc_assign. */
c4abe010
EE
10153 if (expr2->value.function.esym != NULL
10154 && expr2->value.function.esym->attr.elemental)
42488c1b 10155 return true;
6de9cd9a 10156
42488c1b 10157 /* Need a temporary if rhs is not FULL or a contiguous section. */
a61a36ab 10158 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
42488c1b 10159 return true;
a61a36ab 10160
42488c1b 10161 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
7a70c12d 10162 if (gfc_ref_needs_temporary_p (expr1->ref))
42488c1b 10163 return true;
7a70c12d 10164
56ee2f5a 10165 /* Functions returning pointers or allocatables need temporaries. */
7c7e8418
PT
10166 if (gfc_expr_attr (expr2).pointer
10167 || gfc_expr_attr (expr2).allocatable)
42488c1b 10168 return true;
5b0b7251 10169
bab651ad
PT
10170 /* Character array functions need temporaries unless the
10171 character lengths are the same. */
10172 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
10173 {
bc21d315
JW
10174 if (expr1->ts.u.cl->length == NULL
10175 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
42488c1b 10176 return true;
bab651ad 10177
bc21d315
JW
10178 if (expr2->ts.u.cl->length == NULL
10179 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
42488c1b 10180 return true;
bab651ad 10181
bc21d315
JW
10182 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
10183 expr2->ts.u.cl->length->value.integer) != 0)
42488c1b 10184 return true;
bab651ad
PT
10185 }
10186
2853e512
PT
10187 /* Check that no LHS component references appear during an array
10188 reference. This is needed because we do not have the means to
10189 span any arbitrary stride with an array descriptor. This check
10190 is not needed for the rhs because the function result has to be
10191 a complete type. */
10192 seen_array_ref = false;
10193 for (ref = expr1->ref; ref; ref = ref->next)
10194 {
10195 if (ref->type == REF_ARRAY)
10196 seen_array_ref= true;
10197 else if (ref->type == REF_COMPONENT && seen_array_ref)
42488c1b 10198 return true;
2853e512
PT
10199 }
10200
6de9cd9a 10201 /* Check for a dependency. */
1524f80b
RS
10202 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
10203 expr2->value.function.esym,
2b0bd714
MM
10204 expr2->value.function.actual,
10205 NOT_ELEMENTAL))
42488c1b
PT
10206 return true;
10207
10208 /* If we have reached here with an intrinsic function, we do not
7097b041 10209 need a temporary except in the particular case that reallocation
cf3f7b30
TK
10210 on assignment is active and the lhs is allocatable and a target,
10211 or a pointer which may be a subref pointer. FIXME: The last
10212 condition can go away when we use span in the intrinsics
10213 directly.*/
42488c1b 10214 if (expr2->value.function.isym)
cf3f7b30
TK
10215 return (flag_realloc_lhs && sym->attr.allocatable && sym->attr.target)
10216 || (sym->attr.pointer && sym->attr.subref_array_pointer);
42488c1b
PT
10217
10218 /* If the LHS is a dummy, we need a temporary if it is not
10219 INTENT(OUT). */
10220 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
10221 return true;
10222
f1f39033
PT
10223 /* If the lhs has been host_associated, is in common, a pointer or is
10224 a target and the function is not using a RESULT variable, aliasing
10225 can occur and a temporary is needed. */
10226 if ((sym->attr.host_assoc
10227 || sym->attr.in_common
10228 || sym->attr.pointer
10229 || sym->attr.cray_pointee
10230 || sym->attr.target)
10231 && expr2->symtree != NULL
10232 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
10233 return true;
10234
42488c1b
PT
10235 /* A PURE function can unconditionally be called without a temporary. */
10236 if (expr2->value.function.esym != NULL
10237 && expr2->value.function.esym->attr.pure)
10238 return false;
10239
f1f39033
PT
10240 /* Implicit_pure functions are those which could legally be declared
10241 to be PURE. */
10242 if (expr2->value.function.esym != NULL
10243 && expr2->value.function.esym->attr.implicit_pure)
10244 return false;
42488c1b
PT
10245
10246 if (!sym->attr.use_assoc
10247 && !sym->attr.in_common
10248 && !sym->attr.pointer
10249 && !sym->attr.target
f1f39033 10250 && !sym->attr.cray_pointee
42488c1b
PT
10251 && expr2->value.function.esym)
10252 {
10253 /* A temporary is not needed if the function is not contained and
10254 the variable is local or host associated and not a pointer or
1cc0e193 10255 a target. */
42488c1b
PT
10256 if (!expr2->value.function.esym->attr.contained)
10257 return false;
10258
022e30c0
PT
10259 /* A temporary is not needed if the lhs has never been host
10260 associated and the procedure is contained. */
10261 else if (!sym->attr.host_assoc)
10262 return false;
10263
42488c1b
PT
10264 /* A temporary is not needed if the variable is local and not
10265 a pointer, a target or a result. */
10266 if (sym->ns->parent
10267 && expr2->value.function.esym->ns == sym->ns->parent)
10268 return false;
10269 }
10270
10271 /* Default to temporary use. */
10272 return true;
10273}
10274
10275
597553ab
PT
10276/* Provide the loop info so that the lhs descriptor can be built for
10277 reallocatable assignments from extrinsic function calls. */
10278
10279static void
83799a47
MM
10280realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
10281 gfc_loopinfo *loop)
597553ab 10282{
597553ab 10283 /* Signal that the function call should not be made by
1cc0e193 10284 gfc_conv_loop_setup. */
597553ab 10285 se->ss->is_alloc_lhs = 1;
83799a47
MM
10286 gfc_init_loopinfo (loop);
10287 gfc_add_ss_to_loop (loop, *ss);
10288 gfc_add_ss_to_loop (loop, se->ss);
10289 gfc_conv_ss_startstride (loop);
10290 gfc_conv_loop_setup (loop, where);
10291 gfc_copy_loopinfo_to_se (se, loop);
10292 gfc_add_block_to_block (&se->pre, &loop->pre);
10293 gfc_add_block_to_block (&se->pre, &loop->post);
597553ab
PT
10294 se->ss->is_alloc_lhs = 0;
10295}
10296
10297
7de7ae18 10298/* For assignment to a reallocatable lhs from intrinsic functions,
12df8d01
PT
10299 replace the se.expr (ie. the result) with a temporary descriptor.
10300 Null the data field so that the library allocates space for the
10301 result. Free the data of the original descriptor after the function,
10302 in case it appears in an argument expression and transfer the
10303 result to the original descriptor. */
10304
597553ab 10305static void
b972d95b 10306fcncall_realloc_result (gfc_se *se, int rank)
597553ab
PT
10307{
10308 tree desc;
12df8d01 10309 tree res_desc;
597553ab 10310 tree tmp;
b972d95b 10311 tree offset;
7de7ae18 10312 tree zero_cond;
abb276d0
PT
10313 tree not_same_shape;
10314 stmtblock_t shape_block;
b972d95b 10315 int n;
597553ab 10316
12df8d01
PT
10317 /* Use the allocation done by the library. Substitute the lhs
10318 descriptor with a copy, whose data field is nulled.*/
597553ab 10319 desc = build_fold_indirect_ref_loc (input_location, se->expr);
5cda350e
PT
10320 if (POINTER_TYPE_P (TREE_TYPE (desc)))
10321 desc = build_fold_indirect_ref_loc (input_location, desc);
7de7ae18 10322
7097b041
PT
10323 /* Unallocated, the descriptor does not have a dtype. */
10324 tmp = gfc_conv_descriptor_dtype (desc);
10325 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
7de7ae18 10326
12df8d01
PT
10327 res_desc = gfc_evaluate_now (desc, &se->pre);
10328 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
3af52023 10329 se->expr = gfc_build_addr_expr (NULL_TREE, res_desc);
12df8d01 10330
7de7ae18 10331 /* Free the lhs after the function call and copy the result data to
b972d95b 10332 the lhs descriptor. */
597553ab 10333 tmp = gfc_conv_descriptor_data_get (desc);
7de7ae18 10334 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
63ee5404 10335 logical_type_node, tmp,
7de7ae18
PT
10336 build_int_cst (TREE_TYPE (tmp), 0));
10337 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
107051a5 10338 tmp = gfc_call_free (tmp);
12df8d01 10339 gfc_add_expr_to_block (&se->post, tmp);
b972d95b 10340
7de7ae18
PT
10341 tmp = gfc_conv_descriptor_data_get (res_desc);
10342 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
458842fb 10343
abb276d0
PT
10344 /* Check that the shapes are the same between lhs and expression.
10345 The evaluation of the shape is done in 'shape_block' to avoid
10346 unitialized warnings from the lhs bounds. */
10347 not_same_shape = boolean_false_node;
10348 gfc_start_block (&shape_block);
7de7ae18
PT
10349 for (n = 0 ; n < rank; n++)
10350 {
10351 tree tmp1;
10352 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10353 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
10354 tmp = fold_build2_loc (input_location, MINUS_EXPR,
10355 gfc_array_index_type, tmp, tmp1);
10356 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
10357 tmp = fold_build2_loc (input_location, MINUS_EXPR,
10358 gfc_array_index_type, tmp, tmp1);
10359 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
10360 tmp = fold_build2_loc (input_location, PLUS_EXPR,
10361 gfc_array_index_type, tmp, tmp1);
10362 tmp = fold_build2_loc (input_location, NE_EXPR,
63ee5404 10363 logical_type_node, tmp,
7de7ae18 10364 gfc_index_zero_node);
abb276d0
PT
10365 tmp = gfc_evaluate_now (tmp, &shape_block);
10366 if (n == 0)
10367 not_same_shape = tmp;
10368 else
10369 not_same_shape = fold_build2_loc (input_location, TRUTH_OR_EXPR,
10370 logical_type_node, tmp,
10371 not_same_shape);
7de7ae18
PT
10372 }
10373
10374 /* 'zero_cond' being true is equal to lhs not being allocated or the
10375 shapes being different. */
abb276d0
PT
10376 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, logical_type_node,
10377 zero_cond, not_same_shape);
10378 gfc_add_modify (&shape_block, zero_cond, tmp);
10379 tmp = gfc_finish_block (&shape_block);
10380 tmp = build3_v (COND_EXPR, zero_cond,
10381 build_empty_stmt (input_location), tmp);
10382 gfc_add_expr_to_block (&se->post, tmp);
7de7ae18
PT
10383
10384 /* Now reset the bounds returned from the function call to bounds based
10385 on the lhs lbounds, except where the lhs is not allocated or the shapes
10386 of 'variable and 'expr' are different. Set the offset accordingly. */
10387 offset = gfc_index_zero_node;
b972d95b
PT
10388 for (n = 0 ; n < rank; n++)
10389 {
7de7ae18
PT
10390 tree lbound;
10391
10392 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10393 lbound = fold_build3_loc (input_location, COND_EXPR,
10394 gfc_array_index_type, zero_cond,
10395 gfc_index_one_node, lbound);
10396 lbound = gfc_evaluate_now (lbound, &se->post);
10397
10398 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
b972d95b 10399 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7de7ae18 10400 gfc_array_index_type, tmp, lbound);
b972d95b 10401 gfc_conv_descriptor_lbound_set (&se->post, desc,
7de7ae18 10402 gfc_rank_cst[n], lbound);
b972d95b
PT
10403 gfc_conv_descriptor_ubound_set (&se->post, desc,
10404 gfc_rank_cst[n], tmp);
10405
5d24176e
TB
10406 /* Set stride and accumulate the offset. */
10407 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
10408 gfc_conv_descriptor_stride_set (&se->post, desc,
10409 gfc_rank_cst[n], tmp);
7de7ae18 10410 tmp = fold_build2_loc (input_location, MULT_EXPR,
5d24176e 10411 gfc_array_index_type, lbound, tmp);
458842fb 10412 offset = fold_build2_loc (input_location, MINUS_EXPR,
5d24176e 10413 gfc_array_index_type, offset, tmp);
458842fb 10414 offset = gfc_evaluate_now (offset, &se->post);
b972d95b 10415 }
458842fb 10416
b972d95b 10417 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
597553ab
PT
10418}
10419
10420
10421
42488c1b
PT
10422/* Try to translate array(:) = func (...), where func is a transformational
10423 array function, without using a temporary. Returns NULL if this isn't the
10424 case. */
10425
10426static tree
10427gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
10428{
10429 gfc_se se;
2960a368 10430 gfc_ss *ss = NULL;
42488c1b 10431 gfc_component *comp = NULL;
83799a47 10432 gfc_loopinfo loop;
42488c1b
PT
10433
10434 if (arrayfunc_assign_needs_temporary (expr1, expr2))
6de9cd9a
DN
10435 return NULL;
10436
10437 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
10438 functions. */
2a573572 10439 comp = gfc_get_proc_ptr_comp (expr2);
1312bb90
PT
10440
10441 if (!(expr2->value.function.isym
2a573572 10442 || (comp && comp->attr.dimension)
c74b74a8 10443 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
1312bb90
PT
10444 && expr2->value.function.esym->result->attr.dimension)))
10445 return NULL;
6de9cd9a 10446
6de9cd9a
DN
10447 gfc_init_se (&se, NULL);
10448 gfc_start_block (&se.pre);
10449 se.want_pointer = 1;
10450
2960a368 10451 gfc_conv_array_parameter (&se, expr1, false, NULL, NULL, NULL);
6de9cd9a 10452
40c32948
PT
10453 if (expr1->ts.type == BT_DERIVED
10454 && expr1->ts.u.derived->attr.alloc_comp)
10455 {
10456 tree tmp;
abc2d807
TB
10457 tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, se.expr,
10458 expr1->rank);
40c32948
PT
10459 gfc_add_expr_to_block (&se.pre, tmp);
10460 }
10461
6de9cd9a
DN
10462 se.direct_byref = 1;
10463 se.ss = gfc_walk_expr (expr2);
6e45f57b 10464 gcc_assert (se.ss != gfc_ss_terminator);
597553ab
PT
10465
10466 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
10467 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
10468 Clearly, this cannot be done for an allocatable function result, since
10469 the shape of the result is unknown and, in any case, the function must
10470 correctly take care of the reallocation internally. For intrinsic
10471 calls, the array data is freed and the library takes care of allocation.
10472 TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
8b704316 10473 to the library. */
203c7ebf 10474 if (flag_realloc_lhs
597553ab
PT
10475 && gfc_is_reallocatable_lhs (expr1)
10476 && !gfc_expr_attr (expr1).codimension
10477 && !gfc_is_coindexed (expr1)
10478 && !(expr2->value.function.esym
10479 && expr2->value.function.esym->result->attr.allocatable))
10480 {
f1fb11f1
TB
10481 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
10482
597553ab
PT
10483 if (!expr2->value.function.isym)
10484 {
2960a368
TB
10485 ss = gfc_walk_expr (expr1);
10486 gcc_assert (ss != gfc_ss_terminator);
10487
83799a47 10488 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
597553ab
PT
10489 ss->is_alloc_lhs = 1;
10490 }
10491 else
b972d95b 10492 fcncall_realloc_result (&se, expr1->rank);
597553ab
PT
10493 }
10494
6de9cd9a 10495 gfc_conv_function_expr (&se, expr2);
6de9cd9a
DN
10496 gfc_add_block_to_block (&se.pre, &se.post);
10497
c0782a40
TB
10498 if (ss)
10499 gfc_cleanup_loop (&loop);
10500 else
10501 gfc_free_ss_chain (se.ss);
10502
6de9cd9a
DN
10503 return gfc_finish_block (&se.pre);
10504}
10505
6822a10d
RS
10506
10507/* Try to efficiently translate array(:) = 0. Return NULL if this
10508 can't be done. */
10509
10510static tree
10511gfc_trans_zero_assign (gfc_expr * expr)
10512{
10513 tree dest, len, type;
5039610b 10514 tree tmp;
6822a10d
RS
10515 gfc_symbol *sym;
10516
10517 sym = expr->symtree->n.sym;
10518 dest = gfc_get_symbol_decl (sym);
10519
10520 type = TREE_TYPE (dest);
10521 if (POINTER_TYPE_P (type))
10522 type = TREE_TYPE (type);
10523 if (!GFC_ARRAY_TYPE_P (type))
10524 return NULL_TREE;
10525
10526 /* Determine the length of the array. */
10527 len = GFC_TYPE_ARRAY_SIZE (type);
10528 if (!len || TREE_CODE (len) != INTEGER_CST)
10529 return NULL_TREE;
10530
7c57b2f1 10531 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
65a9ca82
TB
10532 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
10533 fold_convert (gfc_array_index_type, tmp));
6822a10d 10534
bfa31dad
RG
10535 /* If we are zeroing a local array avoid taking its address by emitting
10536 a = {} instead. */
6822a10d 10537 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
5d44e5c8 10538 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
9771b263
DN
10539 dest, build_constructor (TREE_TYPE (dest),
10540 NULL));
bfa31dad
RG
10541
10542 /* Convert arguments to the correct types. */
10543 dest = fold_convert (pvoid_type_node, dest);
6822a10d
RS
10544 len = fold_convert (size_type_node, len);
10545
10546 /* Construct call to __builtin_memset. */
db3927fb 10547 tmp = build_call_expr_loc (input_location,
e79983f4
MM
10548 builtin_decl_explicit (BUILT_IN_MEMSET),
10549 3, dest, integer_zero_node, len);
6822a10d
RS
10550 return fold_convert (void_type_node, tmp);
10551}
6de9cd9a 10552
b01e2f88
RS
10553
10554/* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
10555 that constructs the call to __builtin_memcpy. */
10556
12f681a0 10557tree
b01e2f88
RS
10558gfc_build_memcpy_call (tree dst, tree src, tree len)
10559{
5039610b 10560 tree tmp;
b01e2f88
RS
10561
10562 /* Convert arguments to the correct types. */
10563 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
10564 dst = gfc_build_addr_expr (pvoid_type_node, dst);
10565 else
10566 dst = fold_convert (pvoid_type_node, dst);
10567
10568 if (!POINTER_TYPE_P (TREE_TYPE (src)))
10569 src = gfc_build_addr_expr (pvoid_type_node, src);
10570 else
10571 src = fold_convert (pvoid_type_node, src);
10572
10573 len = fold_convert (size_type_node, len);
10574
10575 /* Construct call to __builtin_memcpy. */
db3927fb 10576 tmp = build_call_expr_loc (input_location,
e79983f4
MM
10577 builtin_decl_explicit (BUILT_IN_MEMCPY),
10578 3, dst, src, len);
b01e2f88
RS
10579 return fold_convert (void_type_node, tmp);
10580}
10581
10582
a3018753
RS
10583/* Try to efficiently translate dst(:) = src(:). Return NULL if this
10584 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
10585 source/rhs, both are gfc_full_array_ref_p which have been checked for
10586 dependencies. */
6de9cd9a 10587
a3018753
RS
10588static tree
10589gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
10590{
10591 tree dst, dlen, dtype;
10592 tree src, slen, stype;
7c57b2f1 10593 tree tmp;
a3018753
RS
10594
10595 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
10596 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
10597
10598 dtype = TREE_TYPE (dst);
10599 if (POINTER_TYPE_P (dtype))
10600 dtype = TREE_TYPE (dtype);
10601 stype = TREE_TYPE (src);
10602 if (POINTER_TYPE_P (stype))
10603 stype = TREE_TYPE (stype);
10604
10605 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
10606 return NULL_TREE;
10607
10608 /* Determine the lengths of the arrays. */
10609 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
10610 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
10611 return NULL_TREE;
7c57b2f1 10612 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
65a9ca82
TB
10613 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
10614 dlen, fold_convert (gfc_array_index_type, tmp));
a3018753
RS
10615
10616 slen = GFC_TYPE_ARRAY_SIZE (stype);
10617 if (!slen || TREE_CODE (slen) != INTEGER_CST)
10618 return NULL_TREE;
7c57b2f1 10619 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
65a9ca82
TB
10620 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
10621 slen, fold_convert (gfc_array_index_type, tmp));
a3018753
RS
10622
10623 /* Sanity check that they are the same. This should always be
10624 the case, as we should already have checked for conformance. */
10625 if (!tree_int_cst_equal (slen, dlen))
10626 return NULL_TREE;
10627
b01e2f88
RS
10628 return gfc_build_memcpy_call (dst, src, dlen);
10629}
a3018753 10630
a3018753 10631
b01e2f88
RS
10632/* Try to efficiently translate array(:) = (/ ... /). Return NULL if
10633 this can't be done. EXPR1 is the destination/lhs for which
10634 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
a3018753 10635
b01e2f88
RS
10636static tree
10637gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
10638{
10639 unsigned HOST_WIDE_INT nelem;
10640 tree dst, dtype;
10641 tree src, stype;
10642 tree len;
7c57b2f1 10643 tree tmp;
b01e2f88
RS
10644
10645 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
10646 if (nelem == 0)
10647 return NULL_TREE;
10648
10649 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
10650 dtype = TREE_TYPE (dst);
10651 if (POINTER_TYPE_P (dtype))
10652 dtype = TREE_TYPE (dtype);
10653 if (!GFC_ARRAY_TYPE_P (dtype))
10654 return NULL_TREE;
10655
10656 /* Determine the lengths of the array. */
10657 len = GFC_TYPE_ARRAY_SIZE (dtype);
10658 if (!len || TREE_CODE (len) != INTEGER_CST)
10659 return NULL_TREE;
10660
10661 /* Confirm that the constructor is the same size. */
10662 if (compare_tree_int (len, nelem) != 0)
10663 return NULL_TREE;
10664
7c57b2f1 10665 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
65a9ca82
TB
10666 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
10667 fold_convert (gfc_array_index_type, tmp));
b01e2f88
RS
10668
10669 stype = gfc_typenode_for_spec (&expr2->ts);
10670 src = gfc_build_constant_array_constructor (expr2, stype);
10671
b01e2f88 10672 return gfc_build_memcpy_call (dst, src, len);
a3018753
RS
10673}
10674
10675
0ae6242f
MM
10676/* Tells whether the expression is to be treated as a variable reference. */
10677
711d7c23
MM
10678bool
10679gfc_expr_is_variable (gfc_expr *expr)
0ae6242f
MM
10680{
10681 gfc_expr *arg;
bbeffd6b
MM
10682 gfc_component *comp;
10683 gfc_symbol *func_ifc;
0ae6242f
MM
10684
10685 if (expr->expr_type == EXPR_VARIABLE)
10686 return true;
10687
10688 arg = gfc_get_noncopying_intrinsic_argument (expr);
10689 if (arg)
10690 {
10691 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
711d7c23 10692 return gfc_expr_is_variable (arg);
0ae6242f
MM
10693 }
10694
bbeffd6b
MM
10695 /* A data-pointer-returning function should be considered as a variable
10696 too. */
10697 if (expr->expr_type == EXPR_FUNCTION
10698 && expr->ref == NULL)
10699 {
10700 if (expr->value.function.isym != NULL)
10701 return false;
10702
10703 if (expr->value.function.esym != NULL)
10704 {
10705 func_ifc = expr->value.function.esym;
10706 goto found_ifc;
10707 }
10708 else
10709 {
10710 gcc_assert (expr->symtree);
10711 func_ifc = expr->symtree->n.sym;
10712 goto found_ifc;
10713 }
10714
10715 gcc_unreachable ();
10716 }
10717
10718 comp = gfc_get_proc_ptr_comp (expr);
10719 if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
10720 && comp)
10721 {
10722 func_ifc = comp->ts.interface;
10723 goto found_ifc;
10724 }
10725
10726 if (expr->expr_type == EXPR_COMPCALL)
10727 {
10728 gcc_assert (!expr->value.compcall.tbp->is_generic);
10729 func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
10730 goto found_ifc;
10731 }
10732
0ae6242f 10733 return false;
bbeffd6b
MM
10734
10735found_ifc:
10736 gcc_assert (func_ifc->attr.function
10737 && func_ifc->result != NULL);
10738 return func_ifc->result->attr.pointer;
0ae6242f
MM
10739}
10740
10741
8d51f26f
PT
10742/* Is the lhs OK for automatic reallocation? */
10743
10744static bool
10745is_scalar_reallocatable_lhs (gfc_expr *expr)
10746{
10747 gfc_ref * ref;
10748
10749 /* An allocatable variable with no reference. */
10750 if (expr->symtree->n.sym->attr.allocatable
10751 && !expr->ref)
10752 return true;
10753
49847d75
PT
10754 /* All that can be left are allocatable components. However, we do
10755 not check for allocatable components here because the expression
10756 could be an allocatable component of a pointer component. */
10757 if (expr->symtree->n.sym->ts.type != BT_DERIVED
8d51f26f 10758 && expr->symtree->n.sym->ts.type != BT_CLASS)
8d51f26f
PT
10759 return false;
10760
10761 /* Find an allocatable component ref last. */
10762 for (ref = expr->ref; ref; ref = ref->next)
10763 if (ref->type == REF_COMPONENT
10764 && !ref->next
10765 && ref->u.c.component->attr.allocatable)
10766 return true;
10767
10768 return false;
10769}
10770
10771
10772/* Allocate or reallocate scalar lhs, as necessary. */
10773
10774static void
10775alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
10776 tree string_length,
10777 gfc_expr *expr1,
10778 gfc_expr *expr2)
10779
10780{
10781 tree cond;
10782 tree tmp;
10783 tree size;
10784 tree size_in_bytes;
10785 tree jump_label1;
10786 tree jump_label2;
10787 gfc_se lse;
38217d3e 10788 gfc_ref *ref;
8d51f26f
PT
10789
10790 if (!expr1 || expr1->rank)
10791 return;
10792
10793 if (!expr2 || expr2->rank)
10794 return;
10795
38217d3e
PT
10796 for (ref = expr1->ref; ref; ref = ref->next)
10797 if (ref->type == REF_SUBSTRING)
10798 return;
10799
f1fb11f1
TB
10800 realloc_lhs_warning (expr2->ts.type, false, &expr2->where);
10801
8d51f26f
PT
10802 /* Since this is a scalar lhs, we can afford to do this. That is,
10803 there is no risk of side effects being repeated. */
10804 gfc_init_se (&lse, NULL);
10805 lse.want_pointer = 1;
10806 gfc_conv_expr (&lse, expr1);
8b704316 10807
8d51f26f
PT
10808 jump_label1 = gfc_build_label_decl (NULL_TREE);
10809 jump_label2 = gfc_build_label_decl (NULL_TREE);
10810
10811 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
10812 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
63ee5404 10813 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
8d51f26f
PT
10814 lse.expr, tmp);
10815 tmp = build3_v (COND_EXPR, cond,
10816 build1_v (GOTO_EXPR, jump_label1),
10817 build_empty_stmt (input_location));
10818 gfc_add_expr_to_block (block, tmp);
10819
10820 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10821 {
10822 /* Use the rhs string length and the lhs element size. */
10823 size = string_length;
10824 tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
10825 tmp = TYPE_SIZE_UNIT (tmp);
10826 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
10827 TREE_TYPE (tmp), tmp,
10828 fold_convert (TREE_TYPE (tmp), size));
10829 }
10830 else
10831 {
10832 /* Otherwise use the length in bytes of the rhs. */
10833 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
10834 size_in_bytes = size;
10835 }
10836
6f556b07
TB
10837 size_in_bytes = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
10838 size_in_bytes, size_one_node);
10839
3c9f5092
AV
10840 if (gfc_caf_attr (expr1).codimension && flag_coarray == GFC_FCOARRAY_LIB)
10841 {
10842 tree caf_decl, token;
10843 gfc_se caf_se;
10844 symbol_attribute attr;
10845
10846 gfc_clear_attr (&attr);
10847 gfc_init_se (&caf_se, NULL);
10848
10849 caf_decl = gfc_get_tree_for_caf_expr (expr1);
10850 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl, NULL_TREE,
10851 NULL);
10852 gfc_add_block_to_block (block, &caf_se.pre);
10853 gfc_allocate_allocatable (block, lse.expr, size_in_bytes,
10854 gfc_build_addr_expr (NULL_TREE, token),
10855 NULL_TREE, NULL_TREE, NULL_TREE, jump_label1,
10856 expr1, 1);
10857 }
10858 else if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
4df0f7da
TB
10859 {
10860 tmp = build_call_expr_loc (input_location,
10861 builtin_decl_explicit (BUILT_IN_CALLOC),
10862 2, build_one_cst (size_type_node),
10863 size_in_bytes);
10864 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10865 gfc_add_modify (block, lse.expr, tmp);
10866 }
10867 else
10868 {
10869 tmp = build_call_expr_loc (input_location,
10870 builtin_decl_explicit (BUILT_IN_MALLOC),
10871 1, size_in_bytes);
10872 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10873 gfc_add_modify (block, lse.expr, tmp);
10874 }
10875
8d51f26f
PT
10876 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10877 {
10878 /* Deferred characters need checking for lhs and rhs string
10879 length. Other deferred parameter variables will have to
10880 come here too. */
10881 tmp = build1_v (GOTO_EXPR, jump_label2);
10882 gfc_add_expr_to_block (block, tmp);
10883 }
10884 tmp = build1_v (LABEL_EXPR, jump_label1);
10885 gfc_add_expr_to_block (block, tmp);
10886
10887 /* For a deferred length character, reallocate if lengths of lhs and
10888 rhs are different. */
10889 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10890 {
63ee5404 10891 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
f622221a
JB
10892 lse.string_length,
10893 fold_convert (TREE_TYPE (lse.string_length),
10894 size));
8d51f26f
PT
10895 /* Jump past the realloc if the lengths are the same. */
10896 tmp = build3_v (COND_EXPR, cond,
10897 build1_v (GOTO_EXPR, jump_label2),
10898 build_empty_stmt (input_location));
10899 gfc_add_expr_to_block (block, tmp);
10900 tmp = build_call_expr_loc (input_location,
e79983f4
MM
10901 builtin_decl_explicit (BUILT_IN_REALLOC),
10902 2, fold_convert (pvoid_type_node, lse.expr),
8d51f26f
PT
10903 size_in_bytes);
10904 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
10905 gfc_add_modify (block, lse.expr, tmp);
10906 tmp = build1_v (LABEL_EXPR, jump_label2);
10907 gfc_add_expr_to_block (block, tmp);
10908
10909 /* Update the lhs character length. */
10910 size = string_length;
f622221a
JB
10911 gfc_add_modify (block, lse.string_length,
10912 fold_convert (TREE_TYPE (lse.string_length), size));
8d51f26f
PT
10913 }
10914}
10915
4860a462
TK
10916/* Check for assignments of the type
10917
10918 a = a + 4
10919
10920 to make sure we do not check for reallocation unneccessarily. */
10921
10922
10923static bool
10924is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
10925{
10926 gfc_actual_arglist *a;
10927 gfc_expr *e1, *e2;
10928
10929 switch (expr2->expr_type)
10930 {
10931 case EXPR_VARIABLE:
10932 return gfc_dep_compare_expr (expr1, expr2) == 0;
10933
10934 case EXPR_FUNCTION:
10935 if (expr2->value.function.esym
10936 && expr2->value.function.esym->attr.elemental)
10937 {
10938 for (a = expr2->value.function.actual; a != NULL; a = a->next)
10939 {
10940 e1 = a->expr;
5b338450 10941 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
4860a462 10942 return false;
4ca469cf 10943 }
4860a462
TK
10944 return true;
10945 }
10946 else if (expr2->value.function.isym
10947 && expr2->value.function.isym->elemental)
10948 {
10949 for (a = expr2->value.function.actual; a != NULL; a = a->next)
10950 {
10951 e1 = a->expr;
5b338450 10952 if (e1 && e1->rank > 0 && !is_runtime_conformable (expr1, e1))
4860a462
TK
10953 return false;
10954 }
10955 return true;
10956 }
10957
10958 break;
10959
10960 case EXPR_OP:
10961 switch (expr2->value.op.op)
10962 {
10963 case INTRINSIC_NOT:
10964 case INTRINSIC_UPLUS:
10965 case INTRINSIC_UMINUS:
10966 case INTRINSIC_PARENTHESES:
10967 return is_runtime_conformable (expr1, expr2->value.op.op1);
10968
10969 case INTRINSIC_PLUS:
10970 case INTRINSIC_MINUS:
10971 case INTRINSIC_TIMES:
10972 case INTRINSIC_DIVIDE:
10973 case INTRINSIC_POWER:
10974 case INTRINSIC_AND:
10975 case INTRINSIC_OR:
10976 case INTRINSIC_EQV:
10977 case INTRINSIC_NEQV:
10978 case INTRINSIC_EQ:
10979 case INTRINSIC_NE:
10980 case INTRINSIC_GT:
10981 case INTRINSIC_GE:
10982 case INTRINSIC_LT:
10983 case INTRINSIC_LE:
10984 case INTRINSIC_EQ_OS:
10985 case INTRINSIC_NE_OS:
10986 case INTRINSIC_GT_OS:
10987 case INTRINSIC_GE_OS:
10988 case INTRINSIC_LT_OS:
10989 case INTRINSIC_LE_OS:
10990
10991 e1 = expr2->value.op.op1;
10992 e2 = expr2->value.op.op2;
10993
10994 if (e1->rank == 0 && e2->rank > 0)
10995 return is_runtime_conformable (expr1, e2);
10996 else if (e1->rank > 0 && e2->rank == 0)
10997 return is_runtime_conformable (expr1, e1);
10998 else if (e1->rank > 0 && e2->rank > 0)
10999 return is_runtime_conformable (expr1, e1)
11000 && is_runtime_conformable (expr1, e2);
11001 break;
11002
11003 default:
11004 break;
11005
11006 }
11007
11008 break;
11009
11010 default:
11011 break;
11012 }
11013 return false;
11014}
8d51f26f 11015
574284e9
AV
11016
11017static tree
11018trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
f19dd7b6
AV
11019 gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
11020 bool class_realloc)
574284e9 11021{
ce8dcc91 11022 tree tmp, fcn, stdcopy, to_len, from_len, vptr, old_vptr;
574284e9
AV
11023 vec<tree, va_gc> *args = NULL;
11024
ce8dcc91
PT
11025 /* Store the old vptr so that dynamic types can be compared for
11026 reallocation to occur or not. */
11027 if (class_realloc)
11028 {
11029 tmp = lse->expr;
11030 if (!GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11031 tmp = gfc_get_class_from_expr (tmp);
11032 }
11033
f19dd7b6 11034 vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
574284e9
AV
11035 &from_len);
11036
ce8dcc91 11037 /* Generate (re)allocation of the lhs. */
f19dd7b6
AV
11038 if (class_realloc)
11039 {
ce8dcc91
PT
11040 stmtblock_t alloc, re_alloc;
11041 tree class_han, re, size;
f19dd7b6 11042
ce8dcc91
PT
11043 if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
11044 old_vptr = gfc_evaluate_now (gfc_class_vptr_get (tmp), block);
11045 else
11046 old_vptr = build_int_cst (TREE_TYPE (vptr), 0);
11047
11048 size = gfc_vptr_size_get (vptr);
f19dd7b6
AV
11049 class_han = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11050 ? gfc_class_data_get (lse->expr) : lse->expr;
ce8dcc91
PT
11051
11052 /* Allocate block. */
f19dd7b6 11053 gfc_init_block (&alloc);
ce8dcc91
PT
11054 gfc_allocate_using_malloc (&alloc, class_han, size, NULL_TREE);
11055
11056 /* Reallocate if dynamic types are different. */
11057 gfc_init_block (&re_alloc);
11058 re = build_call_expr_loc (input_location,
11059 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
11060 fold_convert (pvoid_type_node, class_han),
11061 size);
11062 tmp = fold_build2_loc (input_location, NE_EXPR,
11063 logical_type_node, vptr, old_vptr);
11064 re = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11065 tmp, re, build_empty_stmt (input_location));
11066 gfc_add_expr_to_block (&re_alloc, re);
11067
11068 /* Allocate if _data is NULL, reallocate otherwise. */
f19dd7b6 11069 tmp = fold_build2_loc (input_location, EQ_EXPR,
63ee5404 11070 logical_type_node, class_han,
f19dd7b6
AV
11071 build_int_cst (prvoid_type_node, 0));
11072 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
11073 gfc_unlikely (tmp,
11074 PRED_FORTRAN_FAIL_ALLOC),
11075 gfc_finish_block (&alloc),
ce8dcc91 11076 gfc_finish_block (&re_alloc));
f19dd7b6
AV
11077 gfc_add_expr_to_block (&lse->pre, tmp);
11078 }
11079
11080 fcn = gfc_vptr_copy_get (vptr);
574284e9
AV
11081
11082 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr))
11083 ? gfc_class_data_get (rse->expr) : rse->expr;
11084 if (use_vptr_copy)
11085 {
11086 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11087 || INDIRECT_REF_P (tmp)
11088 || (rhs->ts.type == BT_DERIVED
11089 && rhs->ts.u.derived->attr.unlimited_polymorphic
11090 && !rhs->ts.u.derived->attr.pointer
11091 && !rhs->ts.u.derived->attr.allocatable)
11092 || (UNLIMITED_POLY (rhs)
11093 && !CLASS_DATA (rhs)->attr.pointer
11094 && !CLASS_DATA (rhs)->attr.allocatable))
11095 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11096 else
11097 vec_safe_push (args, tmp);
11098 tmp = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11099 ? gfc_class_data_get (lse->expr) : lse->expr;
11100 if (!POINTER_TYPE_P (TREE_TYPE (tmp))
11101 || INDIRECT_REF_P (tmp)
11102 || (lhs->ts.type == BT_DERIVED
11103 && lhs->ts.u.derived->attr.unlimited_polymorphic
11104 && !lhs->ts.u.derived->attr.pointer
11105 && !lhs->ts.u.derived->attr.allocatable)
11106 || (UNLIMITED_POLY (lhs)
11107 && !CLASS_DATA (lhs)->attr.pointer
11108 && !CLASS_DATA (lhs)->attr.allocatable))
11109 vec_safe_push (args, gfc_build_addr_expr (NULL_TREE, tmp));
11110 else
11111 vec_safe_push (args, tmp);
11112
11113 stdcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11114
11115 if (to_len != NULL_TREE && !integer_zerop (from_len))
11116 {
11117 tree extcopy;
11118 vec_safe_push (args, from_len);
11119 vec_safe_push (args, to_len);
11120 extcopy = build_call_vec (TREE_TYPE (TREE_TYPE (fcn)), fcn, args);
11121
11122 tmp = fold_build2_loc (input_location, GT_EXPR,
63ee5404 11123 logical_type_node, from_len,
f622221a 11124 build_zero_cst (TREE_TYPE (from_len)));
574284e9
AV
11125 return fold_build3_loc (input_location, COND_EXPR,
11126 void_type_node, tmp,
11127 extcopy, stdcopy);
11128 }
11129 else
11130 return stdcopy;
11131 }
11132 else
11133 {
11134 tree rhst = GFC_CLASS_TYPE_P (TREE_TYPE (lse->expr))
11135 ? gfc_class_data_get (lse->expr) : lse->expr;
11136 stmtblock_t tblock;
11137 gfc_init_block (&tblock);
11138 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
11139 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
11140 if (!POINTER_TYPE_P (TREE_TYPE (rhst)))
11141 rhst = gfc_build_addr_expr (NULL_TREE, rhst);
11142 /* When coming from a ptr_copy lhs and rhs are swapped. */
11143 gfc_add_modify_loc (input_location, &tblock, rhst,
11144 fold_convert (TREE_TYPE (rhst), tmp));
11145 return gfc_finish_block (&tblock);
11146 }
11147}
11148
a3018753 11149/* Subroutine of gfc_trans_assignment that actually scalarizes the
2b56d6a4
TB
11150 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
11151 init_flag indicates initialization expressions and dealloc that no
574284e9
AV
11152 deallocate prior assignment is needed (if in doubt, set true).
11153 When PTR_COPY is set and expr1 is a class type, then use the _vptr-copy
11154 routine instead of a pointer assignment. Alias resolution is only done,
11155 when MAY_ALIAS is set (the default). This flag is used by ALLOCATE()
11156 where it is known, that newly allocated memory on the lhs can never be
11157 an alias of the rhs. */
a3018753
RS
11158
11159static tree
2b56d6a4 11160gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
574284e9 11161 bool dealloc, bool use_vptr_copy, bool may_alias)
6de9cd9a
DN
11162{
11163 gfc_se lse;
11164 gfc_se rse;
11165 gfc_ss *lss;
11166 gfc_ss *lss_section;
11167 gfc_ss *rss;
11168 gfc_loopinfo loop;
11169 tree tmp;
11170 stmtblock_t block;
11171 stmtblock_t body;
5046aff5 11172 bool l_is_temp;
2c69d527 11173 bool scalar_to_array;
bf0d171a 11174 tree string_length;
3d03ead0 11175 int n;
8c92e452 11176 bool maybe_workshare = false, lhs_refs_comp = false, rhs_refs_comp = false;
574284e9 11177 symbol_attribute lhs_caf_attr, rhs_caf_attr, lhs_attr;
dc9e0b66 11178 bool is_poly_assign;
ce8dcc91 11179 bool realloc_flag;
6de9cd9a 11180
6de9cd9a
DN
11181 /* Assignment of the form lhs = rhs. */
11182 gfc_start_block (&block);
11183
11184 gfc_init_se (&lse, NULL);
11185 gfc_init_se (&rse, NULL);
11186
11187 /* Walk the lhs. */
11188 lss = gfc_walk_expr (expr1);
d1ecece9
TK
11189 if (gfc_is_reallocatable_lhs (expr1))
11190 {
11191 lss->no_bounds_check = 1;
11192 if (!(expr2->expr_type == EXPR_FUNCTION
11193 && expr2->value.function.isym != NULL
11194 && !(expr2->value.function.isym->elemental
11195 || expr2->value.function.isym->conversion)))
11196 lss->is_alloc_lhs = 1;
11197 }
980fa45e
TK
11198 else
11199 lss->no_bounds_check = expr1->no_bounds_check;
567a6e1c 11200
6de9cd9a 11201 rss = NULL;
43a68a9d
PT
11202
11203 if ((expr1->ts.type == BT_DERIVED)
a6b22eea 11204 && (gfc_is_class_array_function (expr2)
43a68a9d
PT
11205 || gfc_is_alloc_class_scalar_function (expr2)))
11206 expr2->must_finalize = 1;
11207
dc9e0b66
AV
11208 /* Checking whether a class assignment is desired is quite complicated and
11209 needed at two locations, so do it once only before the information is
11210 needed. */
11211 lhs_attr = gfc_expr_attr (expr1);
11212 is_poly_assign = (use_vptr_copy || lhs_attr.pointer
11213 || (lhs_attr.allocatable && !lhs_attr.dimension))
11214 && (expr1->ts.type == BT_CLASS
11215 || gfc_is_class_array_ref (expr1, NULL)
11216 || gfc_is_class_scalar_expr (expr1)
11217 || gfc_is_class_array_ref (expr2, NULL)
4225af22
PT
11218 || gfc_is_class_scalar_expr (expr2))
11219 && lhs_attr.flavor != FL_PROCEDURE;
dc9e0b66 11220
ce8dcc91
PT
11221 realloc_flag = flag_realloc_lhs
11222 && gfc_is_reallocatable_lhs (expr1)
11223 && expr2->rank
11224 && !is_runtime_conformable (expr1, expr2);
dc9e0b66 11225
574284e9
AV
11226 /* Only analyze the expressions for coarray properties, when in coarray-lib
11227 mode. */
11228 if (flag_coarray == GFC_FCOARRAY_LIB)
11229 {
8c92e452
AV
11230 lhs_caf_attr = gfc_caf_attr (expr1, false, &lhs_refs_comp);
11231 rhs_caf_attr = gfc_caf_attr (expr2, false, &rhs_refs_comp);
574284e9 11232 }
3c9f5092 11233
6de9cd9a
DN
11234 if (lss != gfc_ss_terminator)
11235 {
11236 /* The assignment needs scalarization. */
11237 lss_section = lss;
11238
11239 /* Find a non-scalar SS from the lhs. */
11240 while (lss_section != gfc_ss_terminator
bcc4d4e0 11241 && lss_section->info->type != GFC_SS_SECTION)
6de9cd9a
DN
11242 lss_section = lss_section->next;
11243
6e45f57b 11244 gcc_assert (lss_section != gfc_ss_terminator);
6de9cd9a
DN
11245
11246 /* Initialize the scalarizer. */
11247 gfc_init_loopinfo (&loop);
11248
11249 /* Walk the rhs. */
11250 rss = gfc_walk_expr (expr2);
11251 if (rss == gfc_ss_terminator)
26f77530
MM
11252 /* The rhs is scalar. Add a ss for the expression. */
11253 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
dc9e0b66
AV
11254 /* When doing a class assign, then the handle to the rhs needs to be a
11255 pointer to allow for polymorphism. */
11256 if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2))
11257 rss->info->type = GFC_SS_REFERENCE;
26f77530 11258
980fa45e 11259 rss->no_bounds_check = expr2->no_bounds_check;
6de9cd9a
DN
11260 /* Associate the SS with the loop. */
11261 gfc_add_ss_to_loop (&loop, lss);
11262 gfc_add_ss_to_loop (&loop, rss);
11263
11264 /* Calculate the bounds of the scalarization. */
11265 gfc_conv_ss_startstride (&loop);
3d03ead0 11266 /* Enable loop reversal. */
aed5574e
PT
11267 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
11268 loop.reverse[n] = GFC_ENABLE_REVERSE;
6de9cd9a 11269 /* Resolve any data dependencies in the statement. */
574284e9
AV
11270 if (may_alias)
11271 gfc_conv_resolve_dependencies (&loop, lss, rss);
6de9cd9a 11272 /* Setup the scalarizing loops. */
bdfd2ff0 11273 gfc_conv_loop_setup (&loop, &expr2->where);
6de9cd9a
DN
11274
11275 /* Setup the gfc_se structures. */
11276 gfc_copy_loopinfo_to_se (&lse, &loop);
11277 gfc_copy_loopinfo_to_se (&rse, &loop);
11278
11279 rse.ss = rss;
11280 gfc_mark_ss_chain_used (rss, 1);
11281 if (loop.temp_ss == NULL)
11282 {
11283 lse.ss = lss;
11284 gfc_mark_ss_chain_used (lss, 1);
11285 }
11286 else
11287 {
11288 lse.ss = loop.temp_ss;
11289 gfc_mark_ss_chain_used (lss, 3);
11290 gfc_mark_ss_chain_used (loop.temp_ss, 3);
11291 }
11292
c26dffff 11293 /* Allow the scalarizer to workshare array assignments. */
57bf3072
JJ
11294 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
11295 == OMPWS_WORKSHARE_FLAG
11296 && loop.temp_ss == NULL)
11297 {
11298 maybe_workshare = true;
11299 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
11300 }
c26dffff 11301
6de9cd9a
DN
11302 /* Start the scalarized loop body. */
11303 gfc_start_scalarized_body (&loop, &body);
11304 }
11305 else
11306 gfc_init_block (&body);
11307
5046aff5
PT
11308 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
11309
6de9cd9a 11310 /* Translate the expression. */
ba85c8c3
AV
11311 rse.want_coarray = flag_coarray == GFC_FCOARRAY_LIB && init_flag
11312 && lhs_caf_attr.codimension;
6de9cd9a
DN
11313 gfc_conv_expr (&rse, expr2);
11314
43a68a9d
PT
11315 /* Deal with the case of a scalar class function assigned to a derived type. */
11316 if (gfc_is_alloc_class_scalar_function (expr2)
11317 && expr1->ts.type == BT_DERIVED)
11318 {
11319 rse.expr = gfc_class_data_get (rse.expr);
11320 rse.expr = build_fold_indirect_ref_loc (input_location, rse.expr);
11321 }
11322
bf0d171a 11323 /* Stabilize a string length for temporaries. */
afbc5ae8 11324 if (expr2->ts.type == BT_CHARACTER && !expr1->ts.deferred
d168c883 11325 && !(VAR_P (rse.string_length)
afbc5ae8
PT
11326 || TREE_CODE (rse.string_length) == PARM_DECL
11327 || TREE_CODE (rse.string_length) == INDIRECT_REF))
bf0d171a 11328 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
78ab5260 11329 else if (expr2->ts.type == BT_CHARACTER)
29a94bf9 11330 {
524cee40
PT
11331 if (expr1->ts.deferred
11332 && gfc_expr_attr (expr1).allocatable
11333 && gfc_check_dependency (expr1, expr2, true))
fb3f5eae
TK
11334 rse.string_length =
11335 gfc_evaluate_now_function_scope (rse.string_length, &rse.pre);
29a94bf9
PT
11336 string_length = rse.string_length;
11337 }
bf0d171a
PT
11338 else
11339 string_length = NULL_TREE;
11340
5046aff5 11341 if (l_is_temp)
6de9cd9a
DN
11342 {
11343 gfc_conv_tmp_array_ref (&lse);
bf0d171a
PT
11344 if (expr2->ts.type == BT_CHARACTER)
11345 lse.string_length = string_length;
6de9cd9a
DN
11346 }
11347 else
afbc5ae8 11348 {
b62df3bf 11349 gfc_conv_expr (&lse, expr1);
afbc5ae8 11350 if (gfc_option.rtcheck & GFC_RTCHECK_MEM
a0909527 11351 && !init_flag
afbc5ae8
PT
11352 && gfc_expr_attr (expr1).allocatable
11353 && expr1->rank
11354 && !expr2->rank)
11355 {
11356 tree cond;
11357 const char* msg;
11358
4ca4d1e9
AV
11359 tmp = INDIRECT_REF_P (lse.expr)
11360 ? gfc_build_addr_expr (NULL_TREE, lse.expr) : lse.expr;
11361
a0909527 11362 /* We should only get array references here. */
4ca4d1e9
AV
11363 gcc_assert (TREE_CODE (tmp) == POINTER_PLUS_EXPR
11364 || TREE_CODE (tmp) == ARRAY_REF);
afbc5ae8 11365
a0909527
PT
11366 /* 'tmp' is either the pointer to the array(POINTER_PLUS_EXPR)
11367 or the array itself(ARRAY_REF). */
4ca4d1e9 11368 tmp = TREE_OPERAND (tmp, 0);
a0909527
PT
11369
11370 /* Provide the address of the array. */
11371 if (TREE_CODE (lse.expr) == ARRAY_REF)
11372 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
afbc5ae8 11373
63ee5404 11374 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
afbc5ae8
PT
11375 tmp, build_int_cst (TREE_TYPE (tmp), 0));
11376 msg = _("Assignment of scalar to unallocated array");
11377 gfc_trans_runtime_check (true, false, cond, &loop.pre,
11378 &expr1->where, msg);
11379 }
96acdb8d 11380
e519d2e8 11381 /* Deallocate the lhs parameterized components if required. */
459e77b8
PT
11382 if (dealloc && expr2->expr_type == EXPR_FUNCTION
11383 && !expr1->symtree->n.sym->attr.associate_var)
96acdb8d
PT
11384 {
11385 if (expr1->ts.type == BT_DERIVED
11386 && expr1->ts.u.derived
11387 && expr1->ts.u.derived->attr.pdt_type)
11388 {
11389 tmp = gfc_deallocate_pdt_comp (expr1->ts.u.derived, lse.expr,
11390 expr1->rank);
11391 gfc_add_expr_to_block (&lse.pre, tmp);
11392 }
11393 else if (expr1->ts.type == BT_CLASS
11394 && CLASS_DATA (expr1)->ts.u.derived
11395 && CLASS_DATA (expr1)->ts.u.derived->attr.pdt_type)
11396 {
11397 tmp = gfc_class_data_get (lse.expr);
11398 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr1)->ts.u.derived,
11399 tmp, expr1->rank);
11400 gfc_add_expr_to_block (&lse.pre, tmp);
11401 }
11402 }
afbc5ae8 11403 }
ec09945c 11404
2c69d527
PT
11405 /* Assignments of scalar derived types with allocatable components
11406 to arrays must be done with a deep copy and the rhs temporary
11407 must have its components deallocated afterwards. */
11408 scalar_to_array = (expr2->ts.type == BT_DERIVED
bc21d315 11409 && expr2->ts.u.derived->attr.alloc_comp
711d7c23 11410 && !gfc_expr_is_variable (expr2)
2c69d527 11411 && expr1->rank && !expr2->rank);
43a68a9d
PT
11412 scalar_to_array |= (expr1->ts.type == BT_DERIVED
11413 && expr1->rank
11414 && expr1->ts.u.derived->attr.alloc_comp
11415 && gfc_is_alloc_class_scalar_function (expr2));
2b56d6a4 11416 if (scalar_to_array && dealloc)
2c69d527 11417 {
abc2d807 11418 tmp = gfc_deallocate_alloc_comp_no_caf (expr2->ts.u.derived, rse.expr, 0);
68180eba 11419 gfc_prepend_expr_to_block (&loop.post, tmp);
2c69d527
PT
11420 }
11421
6052c299
TB
11422 /* When assigning a character function result to a deferred-length variable,
11423 the function call must happen before the (re)allocation of the lhs -
11424 otherwise the character length of the result is not known.
5b4dd015 11425 NOTE 1: This relies on having the exact dependence of the length type
78ab5260 11426 parameter available to the caller; gfortran saves it in the .mod files.
5b4dd015
PT
11427 NOTE 2: Vector array references generate an index temporary that must
11428 not go outside the loop. Otherwise, variables should not generate
11429 a pre block.
11430 NOTE 3: The concatenation operation generates a temporary pointer,
7c4acac3 11431 whose allocation must go to the innermost loop.
5b4dd015 11432 NOTE 4: Elemental functions may generate a temporary, too. */
78ab5260
PT
11433 if (flag_realloc_lhs
11434 && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
11435 && !(lss != gfc_ss_terminator
ad9fe5f3 11436 && rss != gfc_ss_terminator
5b4dd015
PT
11437 && ((expr2->expr_type == EXPR_VARIABLE && expr2->rank)
11438 || (expr2->expr_type == EXPR_FUNCTION
11439 && expr2->value.function.esym != NULL
f435162f 11440 && expr2->value.function.esym->attr.elemental)
7c4acac3
AV
11441 || (expr2->expr_type == EXPR_FUNCTION
11442 && expr2->value.function.isym != NULL
ad9fe5f3
PT
11443 && expr2->value.function.isym->elemental)
11444 || (expr2->expr_type == EXPR_OP
11445 && expr2->value.op.op == INTRINSIC_CONCAT))))
8d51f26f
PT
11446 gfc_add_block_to_block (&block, &rse.pre);
11447
43a68a9d
PT
11448 /* Nullify the allocatable components corresponding to those of the lhs
11449 derived type, so that the finalization of the function result does not
11450 affect the lhs of the assignment. Prepend is used to ensure that the
11451 nullification occurs before the call to the finalizer. In the case of
11452 a scalar to array assignment, this is done in gfc_trans_scalar_assign
11453 as part of the deep copy. */
323c5722 11454 if (!scalar_to_array && expr1->ts.type == BT_DERIVED
a6b22eea 11455 && (gfc_is_class_array_function (expr2)
323c5722 11456 || gfc_is_alloc_class_scalar_function (expr2)))
43a68a9d 11457 {
43a68a9d
PT
11458 tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, rse.expr, 0);
11459 gfc_prepend_expr_to_block (&rse.post, tmp);
11460 if (lss != gfc_ss_terminator && rss == gfc_ss_terminator)
11461 gfc_add_block_to_block (&loop.post, &rse.post);
11462 }
11463
1312bb90
PT
11464 tmp = NULL_TREE;
11465
dc9e0b66 11466 if (is_poly_assign)
0175d45d
PT
11467 {
11468 tmp = trans_class_assignment (&body, expr1, expr2, &lse, &rse,
11469 use_vptr_copy || (lhs_attr.allocatable
11470 && !lhs_attr.dimension),
11471 !realloc_flag && flag_realloc_lhs
11472 && !lhs_attr.pointer);
11473 if (expr2->expr_type == EXPR_FUNCTION
11474 && expr2->ts.type == BT_DERIVED
11475 && expr2->ts.u.derived->attr.alloc_comp)
11476 {
11477 tree tmp2 = gfc_deallocate_alloc_comp (expr2->ts.u.derived,
11478 rse.expr, expr2->rank);
11479 if (lss == gfc_ss_terminator)
11480 gfc_add_expr_to_block (&rse.post, tmp2);
11481 else
11482 gfc_add_expr_to_block (&loop.post, tmp2);
11483 }
11484 }
574284e9
AV
11485 else if (flag_coarray == GFC_FCOARRAY_LIB
11486 && lhs_caf_attr.codimension && rhs_caf_attr.codimension
8c92e452
AV
11487 && ((lhs_caf_attr.allocatable && lhs_refs_comp)
11488 || (rhs_caf_attr.allocatable && rhs_refs_comp)))
3c9f5092 11489 {
8c92e452
AV
11490 /* Only detour to caf_send[get][_by_ref] () when the lhs or rhs is an
11491 allocatable component, because those need to be accessed via the
11492 caf-runtime. No need to check for coindexes here, because resolve
11493 has rewritten those already. */
3c9f5092
AV
11494 gfc_code code;
11495 gfc_actual_arglist a1, a2;
8c92e452
AV
11496 /* Clear the structures to prevent accessing garbage. */
11497 memset (&code, '\0', sizeof (gfc_code));
11498 memset (&a1, '\0', sizeof (gfc_actual_arglist));
11499 memset (&a2, '\0', sizeof (gfc_actual_arglist));
3c9f5092
AV
11500 a1.expr = expr1;
11501 a1.next = &a2;
11502 a2.expr = expr2;
11503 a2.next = NULL;
11504 code.ext.actual = &a1;
11505 code.resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
11506 tmp = gfc_conv_intrinsic_subroutine (&code);
11507 }
1312bb90
PT
11508 else if (!is_poly_assign && expr2->must_finalize
11509 && expr1->ts.type == BT_CLASS
11510 && expr2->ts.type == BT_CLASS)
11511 {
11512 /* This case comes about when the scalarizer provides array element
11513 references. Use the vptr copy function, since this does a deep
ce8dcc91
PT
11514 copy of allocatable components, without which the finalizer call
11515 will deallocate the components. */
1312bb90
PT
11516 tmp = gfc_get_vptr_from_expr (rse.expr);
11517 if (tmp != NULL_TREE)
11518 {
11519 tree fcn = gfc_vptr_copy_get (tmp);
11520 if (POINTER_TYPE_P (TREE_TYPE (fcn)))
11521 fcn = build_fold_indirect_ref_loc (input_location, fcn);
11522 tmp = build_call_expr_loc (input_location,
11523 fcn, 2,
11524 gfc_build_addr_expr (NULL, rse.expr),
11525 gfc_build_addr_expr (NULL, lse.expr));
11526 }
11527 }
11528
11529 /* If nothing else works, do it the old fashioned way! */
11530 if (tmp == NULL_TREE)
3c9f5092
AV
11531 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
11532 gfc_expr_is_variable (expr2)
11533 || scalar_to_array
11534 || expr2->expr_type == EXPR_ARRAY,
ba85c8c3
AV
11535 !(l_is_temp || init_flag) && dealloc,
11536 expr1->symtree->n.sym->attr.codimension);
1312bb90 11537
574284e9
AV
11538 /* Add the pre blocks to the body. */
11539 gfc_add_block_to_block (&body, &rse.pre);
11540 gfc_add_block_to_block (&body, &lse.pre);
6de9cd9a 11541 gfc_add_expr_to_block (&body, tmp);
574284e9
AV
11542 /* Add the post blocks to the body. */
11543 gfc_add_block_to_block (&body, &rse.post);
11544 gfc_add_block_to_block (&body, &lse.post);
6de9cd9a
DN
11545
11546 if (lss == gfc_ss_terminator)
11547 {
8d51f26f 11548 /* F2003: Add the code for reallocation on assignment. */
f19dd7b6
AV
11549 if (flag_realloc_lhs && is_scalar_reallocatable_lhs (expr1)
11550 && !is_poly_assign)
34d9d749 11551 alloc_scalar_allocatable_for_assignment (&block, string_length,
8d51f26f
PT
11552 expr1, expr2);
11553
6de9cd9a
DN
11554 /* Use the scalar assignment as is. */
11555 gfc_add_block_to_block (&block, &body);
11556 }
11557 else
11558 {
6e45f57b
PB
11559 gcc_assert (lse.ss == gfc_ss_terminator
11560 && rse.ss == gfc_ss_terminator);
6de9cd9a 11561
5046aff5 11562 if (l_is_temp)
6de9cd9a
DN
11563 {
11564 gfc_trans_scalarized_loop_boundary (&loop, &body);
11565
11566 /* We need to copy the temporary to the actual lhs. */
11567 gfc_init_se (&lse, NULL);
11568 gfc_init_se (&rse, NULL);
11569 gfc_copy_loopinfo_to_se (&lse, &loop);
11570 gfc_copy_loopinfo_to_se (&rse, &loop);
11571
11572 rse.ss = loop.temp_ss;
11573 lse.ss = lss;
11574
11575 gfc_conv_tmp_array_ref (&rse);
6de9cd9a
DN
11576 gfc_conv_expr (&lse, expr1);
11577
6e45f57b
PB
11578 gcc_assert (lse.ss == gfc_ss_terminator
11579 && rse.ss == gfc_ss_terminator);
6de9cd9a 11580
bf0d171a
PT
11581 if (expr2->ts.type == BT_CHARACTER)
11582 rse.string_length = string_length;
11583
6b591ec0 11584 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
ed673c00 11585 false, dealloc);
6de9cd9a
DN
11586 gfc_add_expr_to_block (&body, tmp);
11587 }
5046aff5 11588
8d51f26f 11589 /* F2003: Allocate or reallocate lhs of allocatable array. */
ce8dcc91 11590 if (realloc_flag)
597553ab 11591 {
f1fb11f1 11592 realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
c26dffff 11593 ompws_flags &= ~OMPWS_SCALARIZER_WS;
597553ab
PT
11594 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
11595 if (tmp != NULL_TREE)
11596 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
11597 }
11598
57bf3072
JJ
11599 if (maybe_workshare)
11600 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
11601
6de9cd9a
DN
11602 /* Generate the copying loops. */
11603 gfc_trans_scalarizing_loops (&loop, &body);
11604
11605 /* Wrap the whole thing up. */
11606 gfc_add_block_to_block (&block, &loop.pre);
11607 gfc_add_block_to_block (&block, &loop.post);
11608
11609 gfc_cleanup_loop (&loop);
11610 }
11611
11612 return gfc_finish_block (&block);
11613}
11614
a3018753 11615
18eaa2c0 11616/* Check whether EXPR is a copyable array. */
a3018753
RS
11617
11618static bool
11619copyable_array_p (gfc_expr * expr)
11620{
18eaa2c0
PT
11621 if (expr->expr_type != EXPR_VARIABLE)
11622 return false;
11623
a3018753 11624 /* First check it's an array. */
18eaa2c0
PT
11625 if (expr->rank < 1 || !expr->ref || expr->ref->next)
11626 return false;
11627
a61a36ab 11628 if (!gfc_full_array_ref_p (expr->ref, NULL))
a3018753
RS
11629 return false;
11630
11631 /* Next check that it's of a simple enough type. */
11632 switch (expr->ts.type)
11633 {
11634 case BT_INTEGER:
11635 case BT_REAL:
11636 case BT_COMPLEX:
11637 case BT_LOGICAL:
11638 return true;
11639
150524cd
RS
11640 case BT_CHARACTER:
11641 return false;
11642
f6288c24 11643 case_bt_struct:
bc21d315 11644 return !expr->ts.u.derived->attr.alloc_comp;
150524cd 11645
a3018753
RS
11646 default:
11647 break;
11648 }
11649
11650 return false;
11651}
11652
11653/* Translate an assignment. */
11654
11655tree
2b56d6a4 11656gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
574284e9 11657 bool dealloc, bool use_vptr_copy, bool may_alias)
a3018753
RS
11658{
11659 tree tmp;
f1f39033 11660
a3018753
RS
11661 /* Special case a single function returning an array. */
11662 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
11663 {
11664 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
11665 if (tmp)
11666 return tmp;
11667 }
11668
11669 /* Special case assigning an array to zero. */
18eaa2c0 11670 if (copyable_array_p (expr1)
a3018753
RS
11671 && is_zero_initializer_p (expr2))
11672 {
11673 tmp = gfc_trans_zero_assign (expr1);
11674 if (tmp)
11675 return tmp;
11676 }
11677
11678 /* Special case copying one array to another. */
18eaa2c0 11679 if (copyable_array_p (expr1)
a3018753 11680 && copyable_array_p (expr2)
a3018753
RS
11681 && gfc_compare_types (&expr1->ts, &expr2->ts)
11682 && !gfc_check_dependency (expr1, expr2, 0))
11683 {
11684 tmp = gfc_trans_array_copy (expr1, expr2);
11685 if (tmp)
11686 return tmp;
11687 }
11688
b01e2f88 11689 /* Special case initializing an array from a constant array constructor. */
18eaa2c0 11690 if (copyable_array_p (expr1)
b01e2f88
RS
11691 && expr2->expr_type == EXPR_ARRAY
11692 && gfc_compare_types (&expr1->ts, &expr2->ts))
11693 {
11694 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
11695 if (tmp)
11696 return tmp;
11697 }
11698
ce8dcc91 11699 if (UNLIMITED_POLY (expr1) && expr1->rank)
75382a96
PT
11700 use_vptr_copy = true;
11701
a3018753 11702 /* Fallback to the scalarizer to generate explicit loops. */
574284e9
AV
11703 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc,
11704 use_vptr_copy, may_alias);
a3018753
RS
11705}
11706
6b591ec0
PT
11707tree
11708gfc_trans_init_assign (gfc_code * code)
11709{
cc03bf7a 11710 return gfc_trans_assignment (code->expr1, code->expr2, true, false, true);
6b591ec0
PT
11711}
11712
6de9cd9a
DN
11713tree
11714gfc_trans_assign (gfc_code * code)
11715{
2b56d6a4 11716 return gfc_trans_assignment (code->expr1, code->expr2, false, true);
6de9cd9a 11717}