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