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