]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans-expr.c
trans.h (struct gfc_ss_info): Move can_be_null_ref component from the data::scalar...
[thirdparty/gcc.git] / gcc / fortran / trans-expr.c
CommitLineData
6de9cd9a 1/* Expression translation
f1f39033 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
94fae14b 3 2011, 2012
7d1f1e61 4 Free Software Foundation, Inc.
6de9cd9a
DN
5 Contributed by Paul Brook <paul@nowt.org>
6 and Steven Bosscher <s.bosscher@student.tudelft.nl>
7
9fc4d79b 8This file is part of GCC.
6de9cd9a 9
9fc4d79b
TS
10GCC is free software; you can redistribute it and/or modify it under
11the terms of the GNU General Public License as published by the Free
d234d788 12Software Foundation; either version 3, or (at your option) any later
9fc4d79b 13version.
6de9cd9a 14
9fc4d79b
TS
15GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16WARRANTY; without even the implied warranty of MERCHANTABILITY or
17FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18for more details.
6de9cd9a
DN
19
20You should have received a copy of the GNU General Public License
d234d788
NC
21along with GCC; see the file COPYING3. If not see
22<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
23
24/* trans-expr.c-- generate GENERIC trees for gfc_expr. */
25
26#include "config.h"
27#include "system.h"
28#include "coretypes.h"
29#include "tree.h"
c829d016 30#include "diagnostic-core.h" /* For fatal_error. */
b3eb1e0e 31#include "langhooks.h"
6de9cd9a 32#include "flags.h"
6de9cd9a 33#include "gfortran.h"
0a164a3c 34#include "arith.h"
b7e75771 35#include "constructor.h"
6de9cd9a
DN
36#include "trans.h"
37#include "trans-const.h"
38#include "trans-types.h"
39#include "trans-array.h"
40/* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
41#include "trans-stmt.h"
7a70c12d 42#include "dependency.h"
6de9cd9a 43
c49ea23d
PT
44
45/* This is the seed for an eventual trans-class.c
46
47 The following parameters should not be used directly since they might
48 in future implementations. Use the corresponding APIs. */
49#define CLASS_DATA_FIELD 0
50#define CLASS_VPTR_FIELD 1
51#define VTABLE_HASH_FIELD 0
52#define VTABLE_SIZE_FIELD 1
53#define VTABLE_EXTENDS_FIELD 2
54#define VTABLE_DEF_INIT_FIELD 3
55#define VTABLE_COPY_FIELD 4
56
57
58tree
59gfc_class_data_get (tree decl)
60{
61 tree data;
62 if (POINTER_TYPE_P (TREE_TYPE (decl)))
63 decl = build_fold_indirect_ref_loc (input_location, decl);
64 data = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
65 CLASS_DATA_FIELD);
66 return fold_build3_loc (input_location, COMPONENT_REF,
67 TREE_TYPE (data), decl, data,
68 NULL_TREE);
69}
70
71
72tree
73gfc_class_vptr_get (tree decl)
74{
75 tree vptr;
76 if (POINTER_TYPE_P (TREE_TYPE (decl)))
77 decl = build_fold_indirect_ref_loc (input_location, decl);
78 vptr = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (decl)),
79 CLASS_VPTR_FIELD);
80 return fold_build3_loc (input_location, COMPONENT_REF,
81 TREE_TYPE (vptr), decl, vptr,
82 NULL_TREE);
83}
84
85
86static tree
87gfc_vtable_field_get (tree decl, int field)
88{
89 tree size;
90 tree vptr;
91 vptr = gfc_class_vptr_get (decl);
92 vptr = build_fold_indirect_ref_loc (input_location, vptr);
93 size = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (vptr)),
94 field);
95 size = fold_build3_loc (input_location, COMPONENT_REF,
96 TREE_TYPE (size), vptr, size,
97 NULL_TREE);
98 /* Always return size as an array index type. */
99 if (field == VTABLE_SIZE_FIELD)
100 size = fold_convert (gfc_array_index_type, size);
101 gcc_assert (size);
102 return size;
103}
104
105
106tree
107gfc_vtable_hash_get (tree decl)
108{
109 return gfc_vtable_field_get (decl, VTABLE_HASH_FIELD);
110}
111
112
113tree
114gfc_vtable_size_get (tree decl)
115{
116 return gfc_vtable_field_get (decl, VTABLE_SIZE_FIELD);
117}
118
119
120tree
121gfc_vtable_extends_get (tree decl)
122{
123 return gfc_vtable_field_get (decl, VTABLE_EXTENDS_FIELD);
124}
125
126
127tree
128gfc_vtable_def_init_get (tree decl)
129{
130 return gfc_vtable_field_get (decl, VTABLE_DEF_INIT_FIELD);
131}
132
133
134tree
135gfc_vtable_copy_get (tree decl)
136{
137 return gfc_vtable_field_get (decl, VTABLE_COPY_FIELD);
138}
139
140
141#undef CLASS_DATA_FIELD
142#undef CLASS_VPTR_FIELD
143#undef VTABLE_HASH_FIELD
144#undef VTABLE_SIZE_FIELD
145#undef VTABLE_EXTENDS_FIELD
146#undef VTABLE_DEF_INIT_FIELD
147#undef VTABLE_COPY_FIELD
148
149
150/* Takes a derived type expression and returns the address of a temporary
151 class object of the 'declared' type. */
152static void
153gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e,
154 gfc_typespec class_ts)
155{
156 gfc_symbol *vtab;
157 gfc_ss *ss;
158 tree ctree;
159 tree var;
160 tree tmp;
161
162 /* The derived type needs to be converted to a temporary
163 CLASS object. */
164 tmp = gfc_typenode_for_spec (&class_ts);
165 var = gfc_create_var (tmp, "class");
166
167 /* Set the vptr. */
168 ctree = gfc_class_vptr_get (var);
169
170 /* Remember the vtab corresponds to the derived type
171 not to the class declared type. */
172 vtab = gfc_find_derived_vtab (e->ts.u.derived);
173 gcc_assert (vtab);
174 tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
175 gfc_add_modify (&parmse->pre, ctree,
176 fold_convert (TREE_TYPE (ctree), tmp));
177
178 /* Now set the data field. */
179 ctree = gfc_class_data_get (var);
180
181 if (parmse->ss && parmse->ss->info->useflags)
182 {
183 /* For an array reference in an elemental procedure call we need
184 to retain the ss to provide the scalarized array reference. */
185 gfc_conv_expr_reference (parmse, e);
186 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
187 gfc_add_modify (&parmse->pre, ctree, tmp);
188 }
189 else
190 {
191 ss = gfc_walk_expr (e);
192 if (ss == gfc_ss_terminator)
193 {
194 parmse->ss = NULL;
195 gfc_conv_expr_reference (parmse, e);
196 tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
197 gfc_add_modify (&parmse->pre, ctree, tmp);
198 }
199 else
200 {
201 parmse->ss = ss;
202 gfc_conv_expr_descriptor (parmse, e, ss);
203 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
204 }
205 }
206
207 /* Pass the address of the class object. */
208 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
209}
210
211
212/* Takes a scalarized class array expression and returns the
213 address of a temporary scalar class object of the 'declared'
214 type.
215 OOP-TODO: This could be improved by adding code that branched on
216 the dynamic type being the same as the declared type. In this case
217 the original class expression can be passed directly. */
4daa71b0 218void
c49ea23d
PT
219gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e,
220 gfc_typespec class_ts, bool elemental)
221{
222 tree ctree;
223 tree var;
224 tree tmp;
225 tree vptr;
226 gfc_ref *ref;
227 gfc_ref *class_ref;
228 bool full_array = false;
229
230 class_ref = NULL;
231 for (ref = e->ref; ref; ref = ref->next)
232 {
233 if (ref->type == REF_COMPONENT
234 && ref->u.c.component->ts.type == BT_CLASS)
235 class_ref = ref;
236
237 if (ref->next == NULL)
238 break;
239 }
240
241 if (ref == NULL || class_ref == ref)
242 return;
243
244 /* Test for FULL_ARRAY. */
245 gfc_is_class_array_ref (e, &full_array);
246
247 /* The derived type needs to be converted to a temporary
248 CLASS object. */
249 tmp = gfc_typenode_for_spec (&class_ts);
250 var = gfc_create_var (tmp, "class");
251
252 /* Set the data. */
253 ctree = gfc_class_data_get (var);
254 gfc_add_modify (&parmse->pre, ctree, parmse->expr);
255
256 /* Return the data component, except in the case of scalarized array
257 references, where nullification of the cannot occur and so there
258 is no need. */
259 if (!elemental && full_array)
260 gfc_add_modify (&parmse->post, parmse->expr, ctree);
261
262 /* Set the vptr. */
263 ctree = gfc_class_vptr_get (var);
264
265 /* The vptr is the second field of the actual argument.
266 First we have to find the corresponding class reference. */
267
268 tmp = NULL_TREE;
269 if (class_ref == NULL
270 && e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
271 tmp = e->symtree->n.sym->backend_decl;
272 else
273 {
274 /* Remove everything after the last class reference, convert the
275 expression and then recover its tailend once more. */
276 gfc_se tmpse;
277 ref = class_ref->next;
278 class_ref->next = NULL;
279 gfc_init_se (&tmpse, NULL);
280 gfc_conv_expr (&tmpse, e);
281 class_ref->next = ref;
282 tmp = tmpse.expr;
283 }
284
285 gcc_assert (tmp != NULL_TREE);
286
287 /* Dereference if needs be. */
288 if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
289 tmp = build_fold_indirect_ref_loc (input_location, tmp);
290
291 vptr = gfc_class_vptr_get (tmp);
292 gfc_add_modify (&parmse->pre, ctree,
293 fold_convert (TREE_TYPE (ctree), vptr));
294
295 /* Return the vptr component, except in the case of scalarized array
296 references, where the dynamic type cannot change. */
297 if (!elemental && full_array)
298 gfc_add_modify (&parmse->post, vptr,
299 fold_convert (TREE_TYPE (vptr), ctree));
300
301 /* Pass the address of the class object. */
302 parmse->expr = gfc_build_addr_expr (NULL_TREE, var);
303}
304
94fae14b 305
4daa71b0
PT
306/* Given a class array declaration and an index, returns the address
307 of the referenced element. */
308
309tree
310gfc_get_class_array_ref (tree index, tree class_decl)
311{
312 tree data = gfc_class_data_get (class_decl);
313 tree size = gfc_vtable_size_get (class_decl);
314 tree offset = fold_build2_loc (input_location, MULT_EXPR,
315 gfc_array_index_type,
316 index, size);
317 tree ptr;
318 data = gfc_conv_descriptor_data_get (data);
319 ptr = fold_convert (pvoid_type_node, data);
320 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset);
321 return fold_convert (TREE_TYPE (data), ptr);
322}
323
324
325/* Copies one class expression to another, assuming that if either
326 'to' or 'from' are arrays they are packed. Should 'from' be
327 NULL_TREE, the inialization expression for 'to' is used, assuming
328 that the _vptr is set. */
329
330tree
331gfc_copy_class_to_class (tree from, tree to, tree nelems)
332{
333 tree fcn;
334 tree fcn_type;
335 tree from_data;
336 tree to_data;
337 tree to_ref;
338 tree from_ref;
339 VEC(tree,gc) *args;
340 tree tmp;
341 tree index;
342 stmtblock_t loopbody;
343 stmtblock_t body;
344 gfc_loopinfo loop;
345
346 args = NULL;
347
348 if (from != NULL_TREE)
349 fcn = gfc_vtable_copy_get (from);
350 else
351 fcn = gfc_vtable_copy_get (to);
352
353 fcn_type = TREE_TYPE (TREE_TYPE (fcn));
354
355 if (from != NULL_TREE)
356 from_data = gfc_class_data_get (from);
357 else
358 from_data = gfc_vtable_def_init_get (to);
359
360 to_data = gfc_class_data_get (to);
361
362 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (to_data)))
363 {
364 gfc_init_block (&body);
365 tmp = fold_build2_loc (input_location, MINUS_EXPR,
366 gfc_array_index_type, nelems,
367 gfc_index_one_node);
368 nelems = gfc_evaluate_now (tmp, &body);
369 index = gfc_create_var (gfc_array_index_type, "S");
370
371 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)))
372 {
373 from_ref = gfc_get_class_array_ref (index, from);
374 VEC_safe_push (tree, gc, args, from_ref);
375 }
376 else
377 VEC_safe_push (tree, gc, args, from_data);
378
379 to_ref = gfc_get_class_array_ref (index, to);
380 VEC_safe_push (tree, gc, args, to_ref);
381
382 tmp = build_call_vec (fcn_type, fcn, args);
383
384 /* Build the body of the loop. */
385 gfc_init_block (&loopbody);
386 gfc_add_expr_to_block (&loopbody, tmp);
387
388 /* Build the loop and return. */
389 gfc_init_loopinfo (&loop);
390 loop.dimen = 1;
391 loop.from[0] = gfc_index_zero_node;
392 loop.loopvar[0] = index;
393 loop.to[0] = nelems;
394 gfc_trans_scalarizing_loops (&loop, &loopbody);
395 gfc_add_block_to_block (&body, &loop.pre);
396 tmp = gfc_finish_block (&body);
397 }
398 else
399 {
400 gcc_assert (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (from_data)));
401 VEC_safe_push (tree, gc, args, from_data);
402 VEC_safe_push (tree, gc, args, to_data);
403 tmp = build_call_vec (fcn_type, fcn, args);
404 }
405
406 return tmp;
407}
408
94fae14b
PT
409static tree
410gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
411{
412 gfc_actual_arglist *actual;
413 gfc_expr *ppc;
414 gfc_code *ppc_code;
415 tree res;
416
417 actual = gfc_get_actual_arglist ();
418 actual->expr = gfc_copy_expr (rhs);
419 actual->next = gfc_get_actual_arglist ();
420 actual->next->expr = gfc_copy_expr (lhs);
421 ppc = gfc_copy_expr (obj);
422 gfc_add_vptr_component (ppc);
423 gfc_add_component_ref (ppc, "_copy");
424 ppc_code = gfc_get_code ();
425 ppc_code->resolved_sym = ppc->symtree->n.sym;
426 /* Although '_copy' is set to be elemental in class.c, it is
427 not staying that way. Find out why, sometime.... */
428 ppc_code->resolved_sym->attr.elemental = 1;
429 ppc_code->ext.actual = actual;
430 ppc_code->expr1 = ppc;
431 ppc_code->op = EXEC_CALL;
432 /* Since '_copy' is elemental, the scalarizer will take care
433 of arrays in gfc_trans_call. */
434 res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
435 gfc_free_statements (ppc_code);
436 return res;
437}
438
439/* Special case for initializing a polymorphic dummy with INTENT(OUT).
440 A MEMCPY is needed to copy the full data from the default initializer
441 of the dynamic type. */
442
443tree
444gfc_trans_class_init_assign (gfc_code *code)
445{
446 stmtblock_t block;
447 tree tmp;
448 gfc_se dst,src,memsz;
449 gfc_expr *lhs, *rhs, *sz;
450
451 gfc_start_block (&block);
452
453 lhs = gfc_copy_expr (code->expr1);
454 gfc_add_data_component (lhs);
455
456 rhs = gfc_copy_expr (code->expr1);
457 gfc_add_vptr_component (rhs);
458
459 /* Make sure that the component backend_decls have been built, which
460 will not have happened if the derived types concerned have not
461 been referenced. */
462 gfc_get_derived_type (rhs->ts.u.derived);
463 gfc_add_def_init_component (rhs);
464
465 if (code->expr1->ts.type == BT_CLASS
466 && CLASS_DATA (code->expr1)->attr.dimension)
467 tmp = gfc_trans_class_array_init_assign (rhs, lhs, code->expr1);
468 else
469 {
470 sz = gfc_copy_expr (code->expr1);
471 gfc_add_vptr_component (sz);
472 gfc_add_size_component (sz);
473
474 gfc_init_se (&dst, NULL);
475 gfc_init_se (&src, NULL);
476 gfc_init_se (&memsz, NULL);
477 gfc_conv_expr (&dst, lhs);
478 gfc_conv_expr (&src, rhs);
479 gfc_conv_expr (&memsz, sz);
480 gfc_add_block_to_block (&block, &src.pre);
481 tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz.expr);
482 }
483 gfc_add_expr_to_block (&block, tmp);
484
485 return gfc_finish_block (&block);
486}
487
488
489/* Translate an assignment to a CLASS object
490 (pointer or ordinary assignment). */
491
492tree
493gfc_trans_class_assign (gfc_expr *expr1, gfc_expr *expr2, gfc_exec_op op)
494{
495 stmtblock_t block;
496 tree tmp;
497 gfc_expr *lhs;
498 gfc_expr *rhs;
499 gfc_ref *ref;
500
501 gfc_start_block (&block);
502
503 ref = expr1->ref;
504 while (ref && ref->next)
505 ref = ref->next;
506
507 /* Class valued proc_pointer assignments do not need any further
508 preparation. */
509 if (ref && ref->type == REF_COMPONENT
510 && ref->u.c.component->attr.proc_pointer
511 && expr2->expr_type == EXPR_VARIABLE
512 && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE
513 && op == EXEC_POINTER_ASSIGN)
514 goto assign;
515
516 if (expr2->ts.type != BT_CLASS)
517 {
518 /* Insert an additional assignment which sets the '_vptr' field. */
519 gfc_symbol *vtab = NULL;
520 gfc_symtree *st;
521
522 lhs = gfc_copy_expr (expr1);
523 gfc_add_vptr_component (lhs);
524
525 if (expr2->ts.type == BT_DERIVED)
526 vtab = gfc_find_derived_vtab (expr2->ts.u.derived);
527 else if (expr2->expr_type == EXPR_NULL)
528 vtab = gfc_find_derived_vtab (expr1->ts.u.derived);
529 gcc_assert (vtab);
530
531 rhs = gfc_get_expr ();
532 rhs->expr_type = EXPR_VARIABLE;
533 gfc_find_sym_tree (vtab->name, vtab->ns, 1, &st);
534 rhs->symtree = st;
535 rhs->ts = vtab->ts;
536
537 tmp = gfc_trans_pointer_assignment (lhs, rhs);
538 gfc_add_expr_to_block (&block, tmp);
539
540 gfc_free_expr (lhs);
541 gfc_free_expr (rhs);
542 }
543 else if (CLASS_DATA (expr2)->attr.dimension)
544 {
545 /* Insert an additional assignment which sets the '_vptr' field. */
546 lhs = gfc_copy_expr (expr1);
547 gfc_add_vptr_component (lhs);
548
549 rhs = gfc_copy_expr (expr2);
550 gfc_add_vptr_component (rhs);
551
552 tmp = gfc_trans_pointer_assignment (lhs, rhs);
553 gfc_add_expr_to_block (&block, tmp);
554
555 gfc_free_expr (lhs);
556 gfc_free_expr (rhs);
557 }
558
559 /* Do the actual CLASS assignment. */
560 if (expr2->ts.type == BT_CLASS
561 && !CLASS_DATA (expr2)->attr.dimension)
562 op = EXEC_ASSIGN;
563 else
564 gfc_add_data_component (expr1);
565
566assign:
567
568 if (op == EXEC_ASSIGN)
569 tmp = gfc_trans_assignment (expr1, expr2, false, true);
570 else if (op == EXEC_POINTER_ASSIGN)
571 tmp = gfc_trans_pointer_assignment (expr1, expr2);
572 else
573 gcc_unreachable();
574
575 gfc_add_expr_to_block (&block, tmp);
576
577 return gfc_finish_block (&block);
578}
579
580
c49ea23d
PT
581/* End of prototype trans-class.c */
582
583
e9cfef64 584static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
0a164a3c 585static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
62ab4a54 586 gfc_expr *);
6de9cd9a
DN
587
588/* Copy the scalarization loop variables. */
589
590static void
591gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
592{
593 dest->ss = src->ss;
594 dest->loop = src->loop;
595}
596
597
f8d0aee5 598/* Initialize a simple expression holder.
6de9cd9a
DN
599
600 Care must be taken when multiple se are created with the same parent.
601 The child se must be kept in sync. The easiest way is to delay creation
602 of a child se until after after the previous se has been translated. */
603
604void
605gfc_init_se (gfc_se * se, gfc_se * parent)
606{
607 memset (se, 0, sizeof (gfc_se));
608 gfc_init_block (&se->pre);
609 gfc_init_block (&se->post);
610
611 se->parent = parent;
612
613 if (parent)
614 gfc_copy_se_loopvars (se, parent);
615}
616
617
618/* Advances to the next SS in the chain. Use this rather than setting
f8d0aee5 619 se->ss = se->ss->next because all the parents needs to be kept in sync.
6de9cd9a
DN
620 See gfc_init_se. */
621
622void
623gfc_advance_se_ss_chain (gfc_se * se)
624{
625 gfc_se *p;
2eace29a 626 gfc_ss *ss;
6de9cd9a 627
6e45f57b 628 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
6de9cd9a
DN
629
630 p = se;
631 /* Walk down the parent chain. */
632 while (p != NULL)
633 {
f8d0aee5 634 /* Simple consistency check. */
4d6a0e36
MM
635 gcc_assert (p->parent == NULL || p->parent->ss == p->ss
636 || p->parent->ss->nested_ss == p->ss);
6de9cd9a 637
2eace29a
MM
638 /* If we were in a nested loop, the next scalarized expression can be
639 on the parent ss' next pointer. Thus we should not take the next
640 pointer blindly, but rather go up one nest level as long as next
641 is the end of chain. */
642 ss = p->ss;
643 while (ss->next == gfc_ss_terminator && ss->parent != NULL)
644 ss = ss->parent;
645
646 p->ss = ss->next;
6de9cd9a
DN
647
648 p = p->parent;
649 }
650}
651
652
653/* Ensures the result of the expression as either a temporary variable
654 or a constant so that it can be used repeatedly. */
655
656void
657gfc_make_safe_expr (gfc_se * se)
658{
659 tree var;
660
6615c446 661 if (CONSTANT_CLASS_P (se->expr))
6de9cd9a
DN
662 return;
663
f8d0aee5 664 /* We need a temporary for this result. */
6de9cd9a 665 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
726a989a 666 gfc_add_modify (&se->pre, var, se->expr);
6de9cd9a
DN
667 se->expr = var;
668}
669
670
1a7bfcc3
PB
671/* Return an expression which determines if a dummy parameter is present.
672 Also used for arguments to procedures with multiple entry points. */
6de9cd9a
DN
673
674tree
675gfc_conv_expr_present (gfc_symbol * sym)
676{
08857b61 677 tree decl, cond;
6de9cd9a 678
1a7bfcc3 679 gcc_assert (sym->attr.dummy);
6de9cd9a
DN
680
681 decl = gfc_get_symbol_decl (sym);
682 if (TREE_CODE (decl) != PARM_DECL)
683 {
684 /* Array parameters use a temporary descriptor, we want the real
685 parameter. */
6e45f57b 686 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
6de9cd9a
DN
687 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
688 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
689 }
08857b61 690
65a9ca82
TB
691 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, decl,
692 fold_convert (TREE_TYPE (decl), null_pointer_node));
08857b61
TB
693
694 /* Fortran 2008 allows to pass null pointers and non-associated pointers
695 as actual argument to denote absent dummies. For array descriptors,
696 we thus also need to check the array descriptor. */
697 if (!sym->attr.pointer && !sym->attr.allocatable
698 && sym->as && sym->as->type == AS_ASSUMED_SHAPE
699 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
700 {
701 tree tmp;
702 tmp = build_fold_indirect_ref_loc (input_location, decl);
703 tmp = gfc_conv_array_data (tmp);
65a9ca82
TB
704 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
705 fold_convert (TREE_TYPE (tmp), null_pointer_node));
706 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
707 boolean_type_node, cond, tmp);
08857b61
TB
708 }
709
710 return cond;
6de9cd9a
DN
711}
712
713
e15e9be3
PT
714/* Converts a missing, dummy argument into a null or zero. */
715
716void
be9c3c6e 717gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
e15e9be3
PT
718{
719 tree present;
720 tree tmp;
721
722 present = gfc_conv_expr_present (arg->symtree->n.sym);
33717d59 723
be9c3c6e
JD
724 if (kind > 0)
725 {
9b09c4de 726 /* Create a temporary and convert it to the correct type. */
be9c3c6e 727 tmp = gfc_get_int_type (kind);
db3927fb
AH
728 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
729 se->expr));
9b09c4de
JD
730
731 /* Test for a NULL value. */
5d44e5c8
TB
732 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
733 tmp, fold_convert (TREE_TYPE (tmp), integer_one_node));
9b09c4de 734 tmp = gfc_evaluate_now (tmp, &se->pre);
628c189e 735 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
9b09c4de
JD
736 }
737 else
738 {
5d44e5c8
TB
739 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
740 present, se->expr,
e8160c9a 741 build_zero_cst (TREE_TYPE (se->expr)));
9b09c4de
JD
742 tmp = gfc_evaluate_now (tmp, &se->pre);
743 se->expr = tmp;
be9c3c6e 744 }
33717d59 745
e15e9be3
PT
746 if (ts.type == BT_CHARACTER)
747 {
c3238e32 748 tmp = build_int_cst (gfc_charlen_type_node, 0);
65a9ca82
TB
749 tmp = fold_build3_loc (input_location, COND_EXPR, gfc_charlen_type_node,
750 present, se->string_length, tmp);
e15e9be3
PT
751 tmp = gfc_evaluate_now (tmp, &se->pre);
752 se->string_length = tmp;
753 }
754 return;
755}
756
757
ca2940c3
TS
758/* Get the character length of an expression, looking through gfc_refs
759 if necessary. */
760
761tree
762gfc_get_expr_charlen (gfc_expr *e)
763{
764 gfc_ref *r;
765 tree length;
766
767 gcc_assert (e->expr_type == EXPR_VARIABLE
768 && e->ts.type == BT_CHARACTER);
769
770 length = NULL; /* To silence compiler warning. */
771
bc21d315 772 if (is_subref_array (e) && e->ts.u.cl->length)
1d6b7f39
PT
773 {
774 gfc_se tmpse;
775 gfc_init_se (&tmpse, NULL);
bc21d315
JW
776 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
777 e->ts.u.cl->backend_decl = tmpse.expr;
1d6b7f39
PT
778 return tmpse.expr;
779 }
780
ca2940c3
TS
781 /* First candidate: if the variable is of type CHARACTER, the
782 expression's length could be the length of the character
f7b529fa 783 variable. */
ca2940c3 784 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
bc21d315 785 length = e->symtree->n.sym->ts.u.cl->backend_decl;
ca2940c3
TS
786
787 /* Look through the reference chain for component references. */
788 for (r = e->ref; r; r = r->next)
789 {
790 switch (r->type)
791 {
792 case REF_COMPONENT:
793 if (r->u.c.component->ts.type == BT_CHARACTER)
bc21d315 794 length = r->u.c.component->ts.u.cl->backend_decl;
ca2940c3
TS
795 break;
796
797 case REF_ARRAY:
798 /* Do nothing. */
799 break;
800
801 default:
802 /* We should never got substring references here. These will be
803 broken down by the scalarizer. */
804 gcc_unreachable ();
1d6b7f39 805 break;
ca2940c3
TS
806 }
807 }
808
809 gcc_assert (length != NULL);
810 return length;
811}
812
4b7f8314 813
0c53708e
TB
814/* Return for an expression the backend decl of the coarray. */
815
816static tree
817get_tree_for_caf_expr (gfc_expr *expr)
818{
819 tree caf_decl = NULL_TREE;
820 gfc_ref *ref;
821
822 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
823 if (expr->symtree->n.sym->attr.codimension)
824 caf_decl = expr->symtree->n.sym->backend_decl;
825
826 for (ref = expr->ref; ref; ref = ref->next)
827 if (ref->type == REF_COMPONENT)
828 {
829 gfc_component *comp = ref->u.c.component;
830 if (comp->attr.pointer || comp->attr.allocatable)
831 caf_decl = NULL_TREE;
832 if (comp->attr.codimension)
833 caf_decl = comp->backend_decl;
834 }
835
836 gcc_assert (caf_decl != NULL_TREE);
837 return caf_decl;
838}
839
840
bc21d315 841/* For each character array constructor subexpression without a ts.u.cl->length,
4b7f8314
DK
842 replace it by its first element (if there aren't any elements, the length
843 should already be set to zero). */
844
845static void
846flatten_array_ctors_without_strlen (gfc_expr* e)
847{
848 gfc_actual_arglist* arg;
849 gfc_constructor* c;
850
851 if (!e)
852 return;
853
854 switch (e->expr_type)
855 {
856
857 case EXPR_OP:
858 flatten_array_ctors_without_strlen (e->value.op.op1);
859 flatten_array_ctors_without_strlen (e->value.op.op2);
860 break;
861
862 case EXPR_COMPCALL:
863 /* TODO: Implement as with EXPR_FUNCTION when needed. */
864 gcc_unreachable ();
865
866 case EXPR_FUNCTION:
867 for (arg = e->value.function.actual; arg; arg = arg->next)
868 flatten_array_ctors_without_strlen (arg->expr);
869 break;
870
871 case EXPR_ARRAY:
872
873 /* We've found what we're looking for. */
bc21d315 874 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
4b7f8314 875 {
b7e75771 876 gfc_constructor *c;
4b7f8314 877 gfc_expr* new_expr;
b7e75771 878
4b7f8314
DK
879 gcc_assert (e->value.constructor);
880
b7e75771
JD
881 c = gfc_constructor_first (e->value.constructor);
882 new_expr = c->expr;
883 c->expr = NULL;
4b7f8314
DK
884
885 flatten_array_ctors_without_strlen (new_expr);
886 gfc_replace_expr (e, new_expr);
887 break;
888 }
889
890 /* Otherwise, fall through to handle constructor elements. */
891 case EXPR_STRUCTURE:
b7e75771
JD
892 for (c = gfc_constructor_first (e->value.constructor);
893 c; c = gfc_constructor_next (c))
4b7f8314
DK
894 flatten_array_ctors_without_strlen (c->expr);
895 break;
896
897 default:
898 break;
899
900 }
901}
902
ca2940c3 903
6de9cd9a 904/* Generate code to initialize a string length variable. Returns the
4b7f8314
DK
905 value. For array constructors, cl->length might be NULL and in this case,
906 the first element of the constructor is needed. expr is the original
907 expression so we can access it but can be NULL if this is not needed. */
6de9cd9a
DN
908
909void
4b7f8314 910gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
6de9cd9a
DN
911{
912 gfc_se se;
6de9cd9a
DN
913
914 gfc_init_se (&se, NULL);
4b7f8314 915
597553ab
PT
916 if (!cl->length
917 && cl->backend_decl
918 && TREE_CODE (cl->backend_decl) == VAR_DECL)
919 return;
920
4b7f8314
DK
921 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
922 "flatten" array constructors by taking their first element; all elements
923 should be the same length or a cl->length should be present. */
924 if (!cl->length)
925 {
926 gfc_expr* expr_flat;
927 gcc_assert (expr);
4b7f8314
DK
928 expr_flat = gfc_copy_expr (expr);
929 flatten_array_ctors_without_strlen (expr_flat);
930 gfc_resolve_expr (expr_flat);
931
932 gfc_conv_expr (&se, expr_flat);
933 gfc_add_block_to_block (pblock, &se.pre);
934 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
935
936 gfc_free_expr (expr_flat);
937 return;
938 }
939
940 /* Convert cl->length. */
941
942 gcc_assert (cl->length);
943
d7177ab2 944 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
65a9ca82
TB
945 se.expr = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
946 se.expr, build_int_cst (gfc_charlen_type_node, 0));
6de9cd9a
DN
947 gfc_add_block_to_block (pblock, &se.pre);
948
07368af0 949 if (cl->backend_decl)
726a989a 950 gfc_add_modify (pblock, cl->backend_decl, se.expr);
07368af0
PT
951 else
952 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
6de9cd9a
DN
953}
954
f8d0aee5 955
6de9cd9a 956static void
65713e5b
TB
957gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
958 const char *name, locus *where)
6de9cd9a
DN
959{
960 tree tmp;
961 tree type;
65713e5b 962 tree fault;
6de9cd9a
DN
963 gfc_se start;
964 gfc_se end;
65713e5b 965 char *msg;
6de9cd9a
DN
966
967 type = gfc_get_character_type (kind, ref->u.ss.length);
968 type = build_pointer_type (type);
969
6de9cd9a 970 gfc_init_se (&start, se);
d7177ab2 971 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
6de9cd9a
DN
972 gfc_add_block_to_block (&se->pre, &start.pre);
973
974 if (integer_onep (start.expr))
7ab92584 975 gfc_conv_string_parameter (se);
6de9cd9a
DN
976 else
977 {
10174ddf
MM
978 tmp = start.expr;
979 STRIP_NOPS (tmp);
1af5627c 980 /* Avoid multiple evaluation of substring start. */
10174ddf 981 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1af5627c
FXC
982 start.expr = gfc_evaluate_now (start.expr, &se->pre);
983
6de9cd9a
DN
984 /* Change the start of the string. */
985 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
986 tmp = se->expr;
987 else
db3927fb
AH
988 tmp = build_fold_indirect_ref_loc (input_location,
989 se->expr);
1d6b7f39 990 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
6de9cd9a
DN
991 se->expr = gfc_build_addr_expr (type, tmp);
992 }
993
994 /* Length = end + 1 - start. */
995 gfc_init_se (&end, se);
996 if (ref->u.ss.end == NULL)
997 end.expr = se->string_length;
998 else
999 {
d7177ab2 1000 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
6de9cd9a
DN
1001 gfc_add_block_to_block (&se->pre, &end.pre);
1002 }
10174ddf
MM
1003 tmp = end.expr;
1004 STRIP_NOPS (tmp);
1005 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1af5627c
FXC
1006 end.expr = gfc_evaluate_now (end.expr, &se->pre);
1007
d3d3011f 1008 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
65713e5b 1009 {
65a9ca82
TB
1010 tree nonempty = fold_build2_loc (input_location, LE_EXPR,
1011 boolean_type_node, start.expr,
1012 end.expr);
ad7082e3 1013
65713e5b 1014 /* Check lower bound. */
65a9ca82
TB
1015 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1016 start.expr,
1017 build_int_cst (gfc_charlen_type_node, 1));
1018 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1019 boolean_type_node, nonempty, fault);
65713e5b 1020 if (name)
c8fe94c7 1021 asprintf (&msg, "Substring out of bounds: lower bound (%%ld) of '%s' "
65713e5b
TB
1022 "is less than one", name);
1023 else
c8fe94c7 1024 asprintf (&msg, "Substring out of bounds: lower bound (%%ld)"
65713e5b 1025 "is less than one");
0d52899f 1026 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
c8fe94c7
FXC
1027 fold_convert (long_integer_type_node,
1028 start.expr));
cede9502 1029 free (msg);
65713e5b
TB
1030
1031 /* Check upper bound. */
65a9ca82
TB
1032 fault = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1033 end.expr, se->string_length);
1034 fault = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1035 boolean_type_node, nonempty, fault);
65713e5b 1036 if (name)
c8fe94c7
FXC
1037 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) of '%s' "
1038 "exceeds string length (%%ld)", name);
65713e5b 1039 else
c8fe94c7
FXC
1040 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) "
1041 "exceeds string length (%%ld)");
0d52899f 1042 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
c8fe94c7
FXC
1043 fold_convert (long_integer_type_node, end.expr),
1044 fold_convert (long_integer_type_node,
1045 se->string_length));
cede9502 1046 free (msg);
65713e5b
TB
1047 }
1048
f884552b
TK
1049 /* If the start and end expressions are equal, the length is one. */
1050 if (ref->u.ss.end
1051 && gfc_dep_compare_expr (ref->u.ss.start, ref->u.ss.end) == 0)
1052 tmp = build_int_cst (gfc_charlen_type_node, 1);
1053 else
1054 {
1055 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_charlen_type_node,
1056 end.expr, start.expr);
1057 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_charlen_type_node,
1058 build_int_cst (gfc_charlen_type_node, 1), tmp);
1059 tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_charlen_type_node,
1060 tmp, build_int_cst (gfc_charlen_type_node, 0));
1061 }
1062
93fc8073 1063 se->string_length = tmp;
6de9cd9a
DN
1064}
1065
1066
1067/* Convert a derived type component reference. */
1068
1069static void
1070gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
1071{
1072 gfc_component *c;
1073 tree tmp;
1074 tree decl;
1075 tree field;
1076
1077 c = ref->u.c.component;
1078
6e45f57b 1079 gcc_assert (c->backend_decl);
6de9cd9a
DN
1080
1081 field = c->backend_decl;
6e45f57b 1082 gcc_assert (TREE_CODE (field) == FIELD_DECL);
6de9cd9a 1083 decl = se->expr;
b3c1b8a1
MM
1084
1085 /* Components can correspond to fields of different containing
1086 types, as components are created without context, whereas
1087 a concrete use of a component has the type of decl as context.
1088 So, if the type doesn't match, we search the corresponding
1089 FIELD_DECL in the parent type. To not waste too much time
1090 we cache this result in norestrict_decl. */
1091
1092 if (DECL_FIELD_CONTEXT (field) != TREE_TYPE (decl))
1093 {
1094 tree f2 = c->norestrict_decl;
1095 if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
1096 for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
1097 if (TREE_CODE (f2) == FIELD_DECL
1098 && DECL_NAME (f2) == DECL_NAME (field))
1099 break;
1100 gcc_assert (f2);
1101 c->norestrict_decl = f2;
1102 field = f2;
1103 }
65a9ca82
TB
1104 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
1105 decl, field, NULL_TREE);
6de9cd9a
DN
1106
1107 se->expr = tmp;
1108
50dbf0b4 1109 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer)
6de9cd9a 1110 {
bc21d315 1111 tmp = c->ts.u.cl->backend_decl;
40f20186 1112 /* Components must always be constant length. */
6e45f57b 1113 gcc_assert (tmp && INTEGER_CST_P (tmp));
6de9cd9a
DN
1114 se->string_length = tmp;
1115 }
1116
241e79cf
TB
1117 if (((c->attr.pointer || c->attr.allocatable)
1118 && (!c->attr.dimension && !c->attr.codimension)
cf2b3c22 1119 && c->ts.type != BT_CHARACTER)
c74b74a8 1120 || c->attr.proc_pointer)
db3927fb
AH
1121 se->expr = build_fold_indirect_ref_loc (input_location,
1122 se->expr);
6de9cd9a
DN
1123}
1124
1125
7d1f1e61
PT
1126/* This function deals with component references to components of the
1127 parent type for derived type extensons. */
1128static void
1129conv_parent_component_references (gfc_se * se, gfc_ref * ref)
1130{
1131 gfc_component *c;
1132 gfc_component *cmp;
1133 gfc_symbol *dt;
1134 gfc_ref parent;
1135
1136 dt = ref->u.c.sym;
1137 c = ref->u.c.component;
1138
0143a784
MM
1139 /* Return if the component is not in the parent type. */
1140 for (cmp = dt->components; cmp; cmp = cmp->next)
1141 if (strcmp (c->name, cmp->name) == 0)
1142 return;
1143
7d1f1e61
PT
1144 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
1145 parent.type = REF_COMPONENT;
1146 parent.next = NULL;
1147 parent.u.c.sym = dt;
1148 parent.u.c.component = dt->components;
1149
1821bcfc
PT
1150 if (dt->backend_decl == NULL)
1151 gfc_get_derived_type (dt);
1152
0143a784
MM
1153 /* Build the reference and call self. */
1154 gfc_conv_component_ref (se, &parent);
1155 parent.u.c.sym = dt->components->ts.u.derived;
1156 parent.u.c.component = c;
1157 conv_parent_component_references (se, &parent);
7d1f1e61
PT
1158}
1159
6de9cd9a
DN
1160/* Return the contents of a variable. Also handles reference/pointer
1161 variables (all Fortran pointer references are implicit). */
1162
1163static void
1164gfc_conv_variable (gfc_se * se, gfc_expr * expr)
1165{
f98cfd3c 1166 gfc_ss *ss;
6de9cd9a
DN
1167 gfc_ref *ref;
1168 gfc_symbol *sym;
80f95228 1169 tree parent_decl = NULL_TREE;
5f20c93a
PT
1170 int parent_flag;
1171 bool return_value;
1172 bool alternate_entry;
1173 bool entry_master;
6de9cd9a
DN
1174
1175 sym = expr->symtree->n.sym;
f98cfd3c
MM
1176 ss = se->ss;
1177 if (ss != NULL)
6de9cd9a 1178 {
a0add3be
MM
1179 gfc_ss_info *ss_info = ss->info;
1180
6de9cd9a 1181 /* Check that something hasn't gone horribly wrong. */
f98cfd3c 1182 gcc_assert (ss != gfc_ss_terminator);
a0add3be 1183 gcc_assert (ss_info->expr == expr);
6de9cd9a
DN
1184
1185 /* A scalarized term. We already know the descriptor. */
1838afec 1186 se->expr = ss_info->data.array.descriptor;
a0add3be 1187 se->string_length = ss_info->string_length;
1838afec 1188 for (ref = ss_info->data.array.ref; ref; ref = ref->next)
068e7338
RS
1189 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
1190 break;
6de9cd9a
DN
1191 }
1192 else
1193 {
d198b59a
JJ
1194 tree se_expr = NULL_TREE;
1195
b122dc6a 1196 se->expr = gfc_get_symbol_decl (sym);
6de9cd9a 1197
5f20c93a
PT
1198 /* Deal with references to a parent results or entries by storing
1199 the current_function_decl and moving to the parent_decl. */
5f20c93a
PT
1200 return_value = sym->attr.function && sym->result == sym;
1201 alternate_entry = sym->attr.function && sym->attr.entry
11a5f608 1202 && sym->result == sym;
5f20c93a 1203 entry_master = sym->attr.result
11a5f608
JJ
1204 && sym->ns->proc_name->attr.entry_master
1205 && !gfc_return_by_reference (sym->ns->proc_name);
80f95228
JW
1206 if (current_function_decl)
1207 parent_decl = DECL_CONTEXT (current_function_decl);
5f20c93a
PT
1208
1209 if ((se->expr == parent_decl && return_value)
11a5f608 1210 || (sym->ns && sym->ns->proc_name
1a492601 1211 && parent_decl
11a5f608
JJ
1212 && sym->ns->proc_name->backend_decl == parent_decl
1213 && (alternate_entry || entry_master)))
5f20c93a
PT
1214 parent_flag = 1;
1215 else
1216 parent_flag = 0;
1217
d198b59a
JJ
1218 /* Special case for assigning the return value of a function.
1219 Self recursive functions must have an explicit return value. */
11a5f608 1220 if (return_value && (se->expr == current_function_decl || parent_flag))
5f20c93a 1221 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
1222
1223 /* Similarly for alternate entry points. */
5f20c93a 1224 else if (alternate_entry
11a5f608
JJ
1225 && (sym->ns->proc_name->backend_decl == current_function_decl
1226 || parent_flag))
d198b59a
JJ
1227 {
1228 gfc_entry_list *el = NULL;
1229
1230 for (el = sym->ns->entries; el; el = el->next)
1231 if (sym == el->sym)
1232 {
5f20c93a 1233 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
1234 break;
1235 }
1236 }
1237
5f20c93a 1238 else if (entry_master
11a5f608
JJ
1239 && (sym->ns->proc_name->backend_decl == current_function_decl
1240 || parent_flag))
5f20c93a 1241 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
1242
1243 if (se_expr)
1244 se->expr = se_expr;
1245
6de9cd9a 1246 /* Procedure actual arguments. */
d198b59a
JJ
1247 else if (sym->attr.flavor == FL_PROCEDURE
1248 && se->expr != current_function_decl)
6de9cd9a 1249 {
8fb74da4 1250 if (!sym->attr.dummy && !sym->attr.proc_pointer)
6de9cd9a 1251 {
6e45f57b 1252 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
628c189e 1253 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
6de9cd9a
DN
1254 }
1255 return;
ec09945c
KH
1256 }
1257
1258
1259 /* Dereference the expression, where needed. Since characters
1260 are entirely different from other types, they are treated
1261 separately. */
1262 if (sym->ts.type == BT_CHARACTER)
1263 {
06469efd 1264 /* Dereference character pointer dummy arguments
72caba17 1265 or results. */
ec09945c 1266 if ((sym->attr.pointer || sym->attr.allocatable)
13a9737c
PT
1267 && (sym->attr.dummy
1268 || sym->attr.function
1269 || sym->attr.result))
db3927fb
AH
1270 se->expr = build_fold_indirect_ref_loc (input_location,
1271 se->expr);
06469efd 1272
ec09945c 1273 }
06469efd 1274 else if (!sym->attr.value)
ec09945c 1275 {
badd9e69
TB
1276 /* Dereference non-character scalar dummy arguments. */
1277 if (sym->attr.dummy && !sym->attr.dimension
1278 && !(sym->attr.codimension && sym->attr.allocatable))
db3927fb
AH
1279 se->expr = build_fold_indirect_ref_loc (input_location,
1280 se->expr);
ec09945c 1281
72caba17 1282 /* Dereference scalar hidden result. */
13a9737c 1283 if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
ec09945c 1284 && (sym->attr.function || sym->attr.result)
43e7fd21
FXC
1285 && !sym->attr.dimension && !sym->attr.pointer
1286 && !sym->attr.always_explicit)
db3927fb
AH
1287 se->expr = build_fold_indirect_ref_loc (input_location,
1288 se->expr);
ec09945c 1289
571d54de 1290 /* Dereference non-character pointer variables.
897f1a8b 1291 These must be dummies, results, or scalars. */
571d54de
DK
1292 if ((sym->attr.pointer || sym->attr.allocatable
1293 || gfc_is_associate_pointer (sym))
13a9737c
PT
1294 && (sym->attr.dummy
1295 || sym->attr.function
1296 || sym->attr.result
badd9e69
TB
1297 || (!sym->attr.dimension
1298 && (!sym->attr.codimension || !sym->attr.allocatable))))
db3927fb
AH
1299 se->expr = build_fold_indirect_ref_loc (input_location,
1300 se->expr);
ec09945c
KH
1301 }
1302
6de9cd9a
DN
1303 ref = expr->ref;
1304 }
1305
1306 /* For character variables, also get the length. */
1307 if (sym->ts.type == BT_CHARACTER)
1308 {
d48734ef
EE
1309 /* If the character length of an entry isn't set, get the length from
1310 the master function instead. */
bc21d315
JW
1311 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
1312 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
d48734ef 1313 else
bc21d315 1314 se->string_length = sym->ts.u.cl->backend_decl;
6e45f57b 1315 gcc_assert (se->string_length);
6de9cd9a
DN
1316 }
1317
1318 while (ref)
1319 {
1320 switch (ref->type)
1321 {
1322 case REF_ARRAY:
1323 /* Return the descriptor if that's what we want and this is an array
1324 section reference. */
1325 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
1326 return;
1327/* TODO: Pointers to single elements of array sections, eg elemental subs. */
1328 /* Return the descriptor for array pointers and allocations. */
1329 if (se->want_pointer
1330 && ref->next == NULL && (se->descriptor_only))
1331 return;
1332
dd18a33b 1333 gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
6de9cd9a
DN
1334 /* Return a pointer to an element. */
1335 break;
1336
1337 case REF_COMPONENT:
7d1f1e61
PT
1338 if (ref->u.c.sym->attr.extension)
1339 conv_parent_component_references (se, ref);
1340
6de9cd9a 1341 gfc_conv_component_ref (se, ref);
c49ea23d 1342
6de9cd9a
DN
1343 break;
1344
1345 case REF_SUBSTRING:
65713e5b
TB
1346 gfc_conv_substring (se, ref, expr->ts.kind,
1347 expr->symtree->name, &expr->where);
6de9cd9a
DN
1348 break;
1349
1350 default:
6e45f57b 1351 gcc_unreachable ();
6de9cd9a
DN
1352 break;
1353 }
1354 ref = ref->next;
1355 }
1356 /* Pointer assignment, allocation or pass by reference. Arrays are handled
f8d0aee5 1357 separately. */
6de9cd9a
DN
1358 if (se->want_pointer)
1359 {
50dbf0b4 1360 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr, NULL))
6de9cd9a
DN
1361 gfc_conv_string_parameter (se);
1362 else
628c189e 1363 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
6de9cd9a 1364 }
6de9cd9a
DN
1365}
1366
1367
1368/* Unary ops are easy... Or they would be if ! was a valid op. */
1369
1370static void
1371gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
1372{
1373 gfc_se operand;
1374 tree type;
1375
6e45f57b 1376 gcc_assert (expr->ts.type != BT_CHARACTER);
6de9cd9a
DN
1377 /* Initialize the operand. */
1378 gfc_init_se (&operand, se);
58b03ab2 1379 gfc_conv_expr_val (&operand, expr->value.op.op1);
6de9cd9a
DN
1380 gfc_add_block_to_block (&se->pre, &operand.pre);
1381
1382 type = gfc_typenode_for_spec (&expr->ts);
1383
1384 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
1385 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
f8d0aee5 1386 All other unary operators have an equivalent GIMPLE unary operator. */
6de9cd9a 1387 if (code == TRUTH_NOT_EXPR)
65a9ca82
TB
1388 se->expr = fold_build2_loc (input_location, EQ_EXPR, type, operand.expr,
1389 build_int_cst (type, 0));
6de9cd9a 1390 else
65a9ca82 1391 se->expr = fold_build1_loc (input_location, code, type, operand.expr);
6de9cd9a
DN
1392
1393}
1394
5b200ac2 1395/* Expand power operator to optimal multiplications when a value is raised
f8d0aee5 1396 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
5b200ac2
FW
1397 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
1398 Programming", 3rd Edition, 1998. */
1399
1400/* This code is mostly duplicated from expand_powi in the backend.
1401 We establish the "optimal power tree" lookup table with the defined size.
1402 The items in the table are the exponents used to calculate the index
1403 exponents. Any integer n less than the value can get an "addition chain",
1404 with the first node being one. */
1405#define POWI_TABLE_SIZE 256
1406
f8d0aee5 1407/* The table is from builtins.c. */
5b200ac2
FW
1408static const unsigned char powi_table[POWI_TABLE_SIZE] =
1409 {
1410 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1411 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1412 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1413 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1414 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1415 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1416 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1417 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1418 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1419 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1420 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1421 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1422 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1423 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1424 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1425 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1426 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1427 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1428 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1429 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
1430 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
1431 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
1432 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
1433 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
1434 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
1435 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
1436 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
1437 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
1438 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
1439 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
1440 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
1441 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
1442 };
1443
f8d0aee5
TS
1444/* If n is larger than lookup table's max index, we use the "window
1445 method". */
5b200ac2
FW
1446#define POWI_WINDOW_SIZE 3
1447
f8d0aee5
TS
1448/* Recursive function to expand the power operator. The temporary
1449 values are put in tmpvar. The function returns tmpvar[1] ** n. */
5b200ac2 1450static tree
6f85ab62 1451gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
6de9cd9a 1452{
5b200ac2
FW
1453 tree op0;
1454 tree op1;
6de9cd9a 1455 tree tmp;
5b200ac2 1456 int digit;
6de9cd9a 1457
5b200ac2 1458 if (n < POWI_TABLE_SIZE)
6de9cd9a 1459 {
5b200ac2
FW
1460 if (tmpvar[n])
1461 return tmpvar[n];
6de9cd9a 1462
5b200ac2
FW
1463 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
1464 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
1465 }
1466 else if (n & 1)
1467 {
1468 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
1469 op0 = gfc_conv_powi (se, n - digit, tmpvar);
1470 op1 = gfc_conv_powi (se, digit, tmpvar);
6de9cd9a
DN
1471 }
1472 else
1473 {
5b200ac2
FW
1474 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
1475 op1 = op0;
6de9cd9a
DN
1476 }
1477
65a9ca82 1478 tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (op0), op0, op1);
5b200ac2 1479 tmp = gfc_evaluate_now (tmp, &se->pre);
6de9cd9a 1480
5b200ac2
FW
1481 if (n < POWI_TABLE_SIZE)
1482 tmpvar[n] = tmp;
6de9cd9a 1483
5b200ac2
FW
1484 return tmp;
1485}
6de9cd9a 1486
f8d0aee5
TS
1487
1488/* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
1489 return 1. Else return 0 and a call to runtime library functions
1490 will have to be built. */
5b200ac2
FW
1491static int
1492gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
1493{
1494 tree cond;
1495 tree tmp;
1496 tree type;
1497 tree vartmp[POWI_TABLE_SIZE];
6f85ab62
FXC
1498 HOST_WIDE_INT m;
1499 unsigned HOST_WIDE_INT n;
5b200ac2 1500 int sgn;
6de9cd9a 1501
6f85ab62
FXC
1502 /* If exponent is too large, we won't expand it anyway, so don't bother
1503 with large integer values. */
1504 if (!double_int_fits_in_shwi_p (TREE_INT_CST (rhs)))
1505 return 0;
1506
1507 m = double_int_to_shwi (TREE_INT_CST (rhs));
1508 /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
1509 of the asymmetric range of the integer type. */
1510 n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
1511
5b200ac2 1512 type = TREE_TYPE (lhs);
5b200ac2 1513 sgn = tree_int_cst_sgn (rhs);
6de9cd9a 1514
6f85ab62
FXC
1515 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
1516 || optimize_size) && (m > 2 || m < -1))
5b200ac2 1517 return 0;
6de9cd9a 1518
5b200ac2
FW
1519 /* rhs == 0 */
1520 if (sgn == 0)
1521 {
1522 se->expr = gfc_build_const (type, integer_one_node);
1523 return 1;
1524 }
6f85ab62 1525
5b200ac2
FW
1526 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
1527 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
1528 {
65a9ca82
TB
1529 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1530 lhs, build_int_cst (TREE_TYPE (lhs), -1));
1531 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1532 lhs, build_int_cst (TREE_TYPE (lhs), 1));
5b200ac2 1533
f8d0aee5 1534 /* If rhs is even,
7ab92584 1535 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
5b200ac2
FW
1536 if ((n & 1) == 0)
1537 {
65a9ca82
TB
1538 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1539 boolean_type_node, tmp, cond);
1540 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
1541 tmp, build_int_cst (type, 1),
1542 build_int_cst (type, 0));
5b200ac2
FW
1543 return 1;
1544 }
f8d0aee5 1545 /* If rhs is odd,
5b200ac2 1546 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
65a9ca82
TB
1547 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp,
1548 build_int_cst (type, -1),
1549 build_int_cst (type, 0));
1550 se->expr = fold_build3_loc (input_location, COND_EXPR, type,
1551 cond, build_int_cst (type, 1), tmp);
5b200ac2
FW
1552 return 1;
1553 }
6de9cd9a 1554
5b200ac2
FW
1555 memset (vartmp, 0, sizeof (vartmp));
1556 vartmp[1] = lhs;
5b200ac2
FW
1557 if (sgn == -1)
1558 {
1559 tmp = gfc_build_const (type, integer_one_node);
65a9ca82
TB
1560 vartmp[1] = fold_build2_loc (input_location, RDIV_EXPR, type, tmp,
1561 vartmp[1]);
5b200ac2 1562 }
293155b0
TM
1563
1564 se->expr = gfc_conv_powi (se, n, vartmp);
1565
5b200ac2 1566 return 1;
6de9cd9a
DN
1567}
1568
1569
5b200ac2 1570/* Power op (**). Constant integer exponent has special handling. */
6de9cd9a
DN
1571
1572static void
1573gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
1574{
e2cad04b 1575 tree gfc_int4_type_node;
6de9cd9a 1576 int kind;
5b200ac2 1577 int ikind;
995d4d1c 1578 int res_ikind_1, res_ikind_2;
6de9cd9a
DN
1579 gfc_se lse;
1580 gfc_se rse;
166d08bd 1581 tree fndecl = NULL;
6de9cd9a
DN
1582
1583 gfc_init_se (&lse, se);
58b03ab2 1584 gfc_conv_expr_val (&lse, expr->value.op.op1);
20fe2233 1585 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
6de9cd9a
DN
1586 gfc_add_block_to_block (&se->pre, &lse.pre);
1587
1588 gfc_init_se (&rse, se);
58b03ab2 1589 gfc_conv_expr_val (&rse, expr->value.op.op2);
6de9cd9a
DN
1590 gfc_add_block_to_block (&se->pre, &rse.pre);
1591
58b03ab2 1592 if (expr->value.op.op2->ts.type == BT_INTEGER
31c97dfe 1593 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
5b200ac2 1594 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
31c97dfe 1595 return;
6de9cd9a 1596
e2cad04b
RH
1597 gfc_int4_type_node = gfc_get_int_type (4);
1598
995d4d1c
DK
1599 /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
1600 library routine. But in the end, we have to convert the result back
1601 if this case applies -- with res_ikind_K, we keep track whether operand K
1602 falls into this case. */
1603 res_ikind_1 = -1;
1604 res_ikind_2 = -1;
1605
58b03ab2
TS
1606 kind = expr->value.op.op1->ts.kind;
1607 switch (expr->value.op.op2->ts.type)
6de9cd9a
DN
1608 {
1609 case BT_INTEGER:
58b03ab2 1610 ikind = expr->value.op.op2->ts.kind;
5b200ac2
FW
1611 switch (ikind)
1612 {
1613 case 1:
1614 case 2:
1615 rse.expr = convert (gfc_int4_type_node, rse.expr);
995d4d1c 1616 res_ikind_2 = ikind;
5b200ac2
FW
1617 /* Fall through. */
1618
1619 case 4:
1620 ikind = 0;
1621 break;
1622
1623 case 8:
1624 ikind = 1;
1625 break;
1626
644cb69f
FXC
1627 case 16:
1628 ikind = 2;
1629 break;
1630
5b200ac2 1631 default:
6e45f57b 1632 gcc_unreachable ();
5b200ac2
FW
1633 }
1634 switch (kind)
1635 {
1636 case 1:
1637 case 2:
58b03ab2 1638 if (expr->value.op.op1->ts.type == BT_INTEGER)
995d4d1c
DK
1639 {
1640 lse.expr = convert (gfc_int4_type_node, lse.expr);
1641 res_ikind_1 = kind;
1642 }
5b200ac2 1643 else
6e45f57b 1644 gcc_unreachable ();
5b200ac2
FW
1645 /* Fall through. */
1646
1647 case 4:
1648 kind = 0;
1649 break;
1650
1651 case 8:
1652 kind = 1;
1653 break;
1654
644cb69f
FXC
1655 case 10:
1656 kind = 2;
1657 break;
1658
1659 case 16:
1660 kind = 3;
1661 break;
1662
5b200ac2 1663 default:
6e45f57b 1664 gcc_unreachable ();
5b200ac2
FW
1665 }
1666
58b03ab2 1667 switch (expr->value.op.op1->ts.type)
5b200ac2
FW
1668 {
1669 case BT_INTEGER:
644cb69f
FXC
1670 if (kind == 3) /* Case 16 was not handled properly above. */
1671 kind = 2;
5b200ac2
FW
1672 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
1673 break;
1674
1675 case BT_REAL:
31c97dfe
JB
1676 /* Use builtins for real ** int4. */
1677 if (ikind == 0)
1678 {
1679 switch (kind)
1680 {
1681 case 0:
e79983f4 1682 fndecl = builtin_decl_explicit (BUILT_IN_POWIF);
31c97dfe
JB
1683 break;
1684
1685 case 1:
e79983f4 1686 fndecl = builtin_decl_explicit (BUILT_IN_POWI);
31c97dfe
JB
1687 break;
1688
1689 case 2:
e79983f4 1690 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
31c97dfe
JB
1691 break;
1692
166d08bd
FXC
1693 case 3:
1694 /* Use the __builtin_powil() only if real(kind=16) is
1695 actually the C long double type. */
1696 if (!gfc_real16_is_float128)
e79983f4 1697 fndecl = builtin_decl_explicit (BUILT_IN_POWIL);
166d08bd
FXC
1698 break;
1699
31c97dfe
JB
1700 default:
1701 gcc_unreachable ();
1702 }
1703 }
166d08bd
FXC
1704
1705 /* If we don't have a good builtin for this, go for the
1706 library function. */
1707 if (!fndecl)
31c97dfe 1708 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
5b200ac2
FW
1709 break;
1710
1711 case BT_COMPLEX:
1712 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
1713 break;
1714
1715 default:
6e45f57b 1716 gcc_unreachable ();
5b200ac2
FW
1717 }
1718 break;
6de9cd9a
DN
1719
1720 case BT_REAL:
166d08bd 1721 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
6de9cd9a
DN
1722 break;
1723
1724 case BT_COMPLEX:
166d08bd 1725 fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
6de9cd9a
DN
1726 break;
1727
1728 default:
6e45f57b 1729 gcc_unreachable ();
6de9cd9a
DN
1730 break;
1731 }
1732
db3927fb
AH
1733 se->expr = build_call_expr_loc (input_location,
1734 fndecl, 2, lse.expr, rse.expr);
995d4d1c
DK
1735
1736 /* Convert the result back if it is of wrong integer kind. */
1737 if (res_ikind_1 != -1 && res_ikind_2 != -1)
1738 {
1739 /* We want the maximum of both operand kinds as result. */
1740 if (res_ikind_1 < res_ikind_2)
1741 res_ikind_1 = res_ikind_2;
1742 se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
1743 }
6de9cd9a
DN
1744}
1745
1746
1747/* Generate code to allocate a string temporary. */
1748
1749tree
1750gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
1751{
1752 tree var;
1753 tree tmp;
6de9cd9a
DN
1754
1755 if (gfc_can_put_var_on_stack (len))
1756 {
1757 /* Create a temporary variable to hold the result. */
65a9ca82
TB
1758 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1759 gfc_charlen_type_node, len,
1760 build_int_cst (gfc_charlen_type_node, 1));
7ab92584 1761 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
16a55411
FXC
1762
1763 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
1764 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
1765 else
1766 tmp = build_array_type (TREE_TYPE (type), tmp);
1767
6de9cd9a
DN
1768 var = gfc_create_var (tmp, "str");
1769 var = gfc_build_addr_expr (type, var);
1770 }
1771 else
1772 {
1773 /* Allocate a temporary to hold the result. */
1774 var = gfc_create_var (type, "pstr");
d393bbd7 1775 tmp = gfc_call_malloc (&se->pre, type,
65a9ca82
TB
1776 fold_build2_loc (input_location, MULT_EXPR,
1777 TREE_TYPE (len), len,
1778 fold_convert (TREE_TYPE (len),
1779 TYPE_SIZE (type))));
726a989a 1780 gfc_add_modify (&se->pre, var, tmp);
6de9cd9a
DN
1781
1782 /* Free the temporary afterwards. */
297c3717 1783 tmp = gfc_call_free (convert (pvoid_type_node, var));
6de9cd9a
DN
1784 gfc_add_expr_to_block (&se->post, tmp);
1785 }
1786
1787 return var;
1788}
1789
1790
1791/* Handle a string concatenation operation. A temporary will be allocated to
1792 hold the result. */
1793
1794static void
1795gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
1796{
374929b2
FXC
1797 gfc_se lse, rse;
1798 tree len, type, var, tmp, fndecl;
6de9cd9a 1799
58b03ab2 1800 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
374929b2 1801 && expr->value.op.op2->ts.type == BT_CHARACTER);
d393bbd7 1802 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
6de9cd9a
DN
1803
1804 gfc_init_se (&lse, se);
58b03ab2 1805 gfc_conv_expr (&lse, expr->value.op.op1);
6de9cd9a
DN
1806 gfc_conv_string_parameter (&lse);
1807 gfc_init_se (&rse, se);
58b03ab2 1808 gfc_conv_expr (&rse, expr->value.op.op2);
6de9cd9a
DN
1809 gfc_conv_string_parameter (&rse);
1810
1811 gfc_add_block_to_block (&se->pre, &lse.pre);
1812 gfc_add_block_to_block (&se->pre, &rse.pre);
1813
bc21d315 1814 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
6de9cd9a
DN
1815 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
1816 if (len == NULL_TREE)
1817 {
65a9ca82
TB
1818 len = fold_build2_loc (input_location, PLUS_EXPR,
1819 TREE_TYPE (lse.string_length),
1820 lse.string_length, rse.string_length);
6de9cd9a
DN
1821 }
1822
1823 type = build_pointer_type (type);
1824
1825 var = gfc_conv_string_tmp (se, type, len);
1826
1827 /* Do the actual concatenation. */
374929b2
FXC
1828 if (expr->ts.kind == 1)
1829 fndecl = gfor_fndecl_concat_string;
1830 else if (expr->ts.kind == 4)
1831 fndecl = gfor_fndecl_concat_string_char4;
1832 else
1833 gcc_unreachable ();
1834
db3927fb
AH
1835 tmp = build_call_expr_loc (input_location,
1836 fndecl, 6, len, var, lse.string_length, lse.expr,
5039610b 1837 rse.string_length, rse.expr);
6de9cd9a
DN
1838 gfc_add_expr_to_block (&se->pre, tmp);
1839
1840 /* Add the cleanup for the operands. */
1841 gfc_add_block_to_block (&se->pre, &rse.post);
1842 gfc_add_block_to_block (&se->pre, &lse.post);
1843
1844 se->expr = var;
1845 se->string_length = len;
1846}
1847
6de9cd9a
DN
1848/* Translates an op expression. Common (binary) cases are handled by this
1849 function, others are passed on. Recursion is used in either case.
1850 We use the fact that (op1.ts == op2.ts) (except for the power
f8d0aee5 1851 operator **).
6de9cd9a 1852 Operators need no special handling for scalarized expressions as long as
f8d0aee5 1853 they call gfc_conv_simple_val to get their operands.
6de9cd9a
DN
1854 Character strings get special handling. */
1855
1856static void
1857gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
1858{
1859 enum tree_code code;
1860 gfc_se lse;
1861 gfc_se rse;
c9ff1de3 1862 tree tmp, type;
6de9cd9a
DN
1863 int lop;
1864 int checkstring;
1865
1866 checkstring = 0;
1867 lop = 0;
a1ee985f 1868 switch (expr->value.op.op)
6de9cd9a 1869 {
2414e1d6 1870 case INTRINSIC_PARENTHESES:
72bd130e
TB
1871 if ((expr->ts.type == BT_REAL
1872 || expr->ts.type == BT_COMPLEX)
1873 && gfc_option.flag_protect_parens)
dedd42d5
RG
1874 {
1875 gfc_conv_unary_op (PAREN_EXPR, se, expr);
1876 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
1877 return;
1878 }
1879
1880 /* Fallthrough. */
1881 case INTRINSIC_UPLUS:
58b03ab2 1882 gfc_conv_expr (se, expr->value.op.op1);
6de9cd9a
DN
1883 return;
1884
1885 case INTRINSIC_UMINUS:
1886 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
1887 return;
1888
1889 case INTRINSIC_NOT:
1890 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
1891 return;
1892
1893 case INTRINSIC_PLUS:
1894 code = PLUS_EXPR;
1895 break;
1896
1897 case INTRINSIC_MINUS:
1898 code = MINUS_EXPR;
1899 break;
1900
1901 case INTRINSIC_TIMES:
1902 code = MULT_EXPR;
1903 break;
1904
1905 case INTRINSIC_DIVIDE:
1906 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
1907 an integer, we must round towards zero, so we use a
1908 TRUNC_DIV_EXPR. */
1909 if (expr->ts.type == BT_INTEGER)
1910 code = TRUNC_DIV_EXPR;
1911 else
1912 code = RDIV_EXPR;
1913 break;
1914
1915 case INTRINSIC_POWER:
1916 gfc_conv_power_op (se, expr);
1917 return;
1918
1919 case INTRINSIC_CONCAT:
1920 gfc_conv_concat_op (se, expr);
1921 return;
1922
1923 case INTRINSIC_AND:
1924 code = TRUTH_ANDIF_EXPR;
1925 lop = 1;
1926 break;
1927
1928 case INTRINSIC_OR:
1929 code = TRUTH_ORIF_EXPR;
1930 lop = 1;
1931 break;
1932
1933 /* EQV and NEQV only work on logicals, but since we represent them
eadf906f 1934 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
6de9cd9a 1935 case INTRINSIC_EQ:
3bed9dd0 1936 case INTRINSIC_EQ_OS:
6de9cd9a
DN
1937 case INTRINSIC_EQV:
1938 code = EQ_EXPR;
1939 checkstring = 1;
1940 lop = 1;
1941 break;
1942
1943 case INTRINSIC_NE:
3bed9dd0 1944 case INTRINSIC_NE_OS:
6de9cd9a
DN
1945 case INTRINSIC_NEQV:
1946 code = NE_EXPR;
1947 checkstring = 1;
1948 lop = 1;
1949 break;
1950
1951 case INTRINSIC_GT:
3bed9dd0 1952 case INTRINSIC_GT_OS:
6de9cd9a
DN
1953 code = GT_EXPR;
1954 checkstring = 1;
1955 lop = 1;
1956 break;
1957
1958 case INTRINSIC_GE:
3bed9dd0 1959 case INTRINSIC_GE_OS:
6de9cd9a
DN
1960 code = GE_EXPR;
1961 checkstring = 1;
1962 lop = 1;
1963 break;
1964
1965 case INTRINSIC_LT:
3bed9dd0 1966 case INTRINSIC_LT_OS:
6de9cd9a
DN
1967 code = LT_EXPR;
1968 checkstring = 1;
1969 lop = 1;
1970 break;
1971
1972 case INTRINSIC_LE:
3bed9dd0 1973 case INTRINSIC_LE_OS:
6de9cd9a
DN
1974 code = LE_EXPR;
1975 checkstring = 1;
1976 lop = 1;
1977 break;
1978
1979 case INTRINSIC_USER:
1980 case INTRINSIC_ASSIGN:
1981 /* These should be converted into function calls by the frontend. */
6e45f57b 1982 gcc_unreachable ();
6de9cd9a
DN
1983
1984 default:
1985 fatal_error ("Unknown intrinsic op");
1986 return;
1987 }
1988
f8d0aee5 1989 /* The only exception to this is **, which is handled separately anyway. */
58b03ab2 1990 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
6de9cd9a 1991
58b03ab2 1992 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
6de9cd9a
DN
1993 checkstring = 0;
1994
1995 /* lhs */
1996 gfc_init_se (&lse, se);
58b03ab2 1997 gfc_conv_expr (&lse, expr->value.op.op1);
6de9cd9a
DN
1998 gfc_add_block_to_block (&se->pre, &lse.pre);
1999
2000 /* rhs */
2001 gfc_init_se (&rse, se);
58b03ab2 2002 gfc_conv_expr (&rse, expr->value.op.op2);
6de9cd9a
DN
2003 gfc_add_block_to_block (&se->pre, &rse.pre);
2004
6de9cd9a
DN
2005 if (checkstring)
2006 {
2007 gfc_conv_string_parameter (&lse);
2008 gfc_conv_string_parameter (&rse);
6de9cd9a 2009
0a821a92 2010 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
374929b2 2011 rse.string_length, rse.expr,
23b10420
JJ
2012 expr->value.op.op1->ts.kind,
2013 code);
ac816b02 2014 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
0a821a92 2015 gfc_add_block_to_block (&lse.post, &rse.post);
6de9cd9a
DN
2016 }
2017
2018 type = gfc_typenode_for_spec (&expr->ts);
2019
2020 if (lop)
2021 {
2022 /* The result of logical ops is always boolean_type_node. */
65a9ca82
TB
2023 tmp = fold_build2_loc (input_location, code, boolean_type_node,
2024 lse.expr, rse.expr);
6de9cd9a
DN
2025 se->expr = convert (type, tmp);
2026 }
2027 else
65a9ca82 2028 se->expr = fold_build2_loc (input_location, code, type, lse.expr, rse.expr);
6de9cd9a 2029
6de9cd9a
DN
2030 /* Add the post blocks. */
2031 gfc_add_block_to_block (&se->post, &rse.post);
2032 gfc_add_block_to_block (&se->post, &lse.post);
2033}
2034
0a821a92
FW
2035/* If a string's length is one, we convert it to a single character. */
2036
d2886bc7
JJ
2037tree
2038gfc_string_to_single_character (tree len, tree str, int kind)
0a821a92 2039{
0a821a92 2040
9a14c44d
TB
2041 if (!INTEGER_CST_P (len) || TREE_INT_CST_HIGH (len) != 0
2042 || !POINTER_TYPE_P (TREE_TYPE (str)))
48b19537
JJ
2043 return NULL_TREE;
2044
2045 if (TREE_INT_CST_LOW (len) == 1)
0a821a92 2046 {
d393bbd7 2047 str = fold_convert (gfc_get_pchar_type (kind), str);
48b19537
JJ
2048 return build_fold_indirect_ref_loc (input_location, str);
2049 }
2050
2051 if (kind == 1
2052 && TREE_CODE (str) == ADDR_EXPR
2053 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
2054 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
2055 && array_ref_low_bound (TREE_OPERAND (str, 0))
2056 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
2057 && TREE_INT_CST_LOW (len) > 1
2058 && TREE_INT_CST_LOW (len)
2059 == (unsigned HOST_WIDE_INT)
2060 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
2061 {
2062 tree ret = fold_convert (gfc_get_pchar_type (kind), str);
2063 ret = build_fold_indirect_ref_loc (input_location, ret);
2064 if (TREE_CODE (ret) == INTEGER_CST)
2065 {
2066 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
23b10420 2067 int i, length = TREE_STRING_LENGTH (string_cst);
48b19537
JJ
2068 const char *ptr = TREE_STRING_POINTER (string_cst);
2069
23b10420 2070 for (i = 1; i < length; i++)
48b19537
JJ
2071 if (ptr[i] != ' ')
2072 return NULL_TREE;
2073
2074 return ret;
2075 }
0a821a92
FW
2076 }
2077
2078 return NULL_TREE;
2079}
2080
e032c2a1
CR
2081
2082void
2083gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
2084{
2085
2086 if (sym->backend_decl)
2087 {
2088 /* This becomes the nominal_type in
2089 function.c:assign_parm_find_data_types. */
2090 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
2091 /* This becomes the passed_type in
2092 function.c:assign_parm_find_data_types. C promotes char to
2093 integer for argument passing. */
2094 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
2095
2096 DECL_BY_REFERENCE (sym->backend_decl) = 0;
2097 }
2098
2099 if (expr != NULL)
2100 {
2101 /* If we have a constant character expression, make it into an
2102 integer. */
2103 if ((*expr)->expr_type == EXPR_CONSTANT)
2104 {
2105 gfc_typespec ts;
44000dbb 2106 gfc_clear_ts (&ts);
e032c2a1 2107
b7e75771
JD
2108 *expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
2109 (int)(*expr)->value.character.string[0]);
e032c2a1
CR
2110 if ((*expr)->ts.kind != gfc_c_int_kind)
2111 {
2112 /* The expr needs to be compatible with a C int. If the
2113 conversion fails, then the 2 causes an ICE. */
2114 ts.type = BT_INTEGER;
2115 ts.kind = gfc_c_int_kind;
2116 gfc_convert_type (*expr, &ts, 2);
2117 }
2118 }
2119 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
2120 {
2121 if ((*expr)->ref == NULL)
2122 {
d2886bc7 2123 se->expr = gfc_string_to_single_character
e032c2a1 2124 (build_int_cst (integer_type_node, 1),
d393bbd7 2125 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
e032c2a1 2126 gfc_get_symbol_decl
d393bbd7
FXC
2127 ((*expr)->symtree->n.sym)),
2128 (*expr)->ts.kind);
e032c2a1
CR
2129 }
2130 else
2131 {
2132 gfc_conv_variable (se, *expr);
d2886bc7 2133 se->expr = gfc_string_to_single_character
e032c2a1 2134 (build_int_cst (integer_type_node, 1),
d393bbd7
FXC
2135 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
2136 se->expr),
2137 (*expr)->ts.kind);
e032c2a1
CR
2138 }
2139 }
2140 }
2141}
2142
23b10420
JJ
2143/* Helper function for gfc_build_compare_string. Return LEN_TRIM value
2144 if STR is a string literal, otherwise return -1. */
2145
2146static int
2147gfc_optimize_len_trim (tree len, tree str, int kind)
2148{
2149 if (kind == 1
2150 && TREE_CODE (str) == ADDR_EXPR
2151 && TREE_CODE (TREE_OPERAND (str, 0)) == ARRAY_REF
2152 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (str, 0), 0)) == STRING_CST
2153 && array_ref_low_bound (TREE_OPERAND (str, 0))
2154 == TREE_OPERAND (TREE_OPERAND (str, 0), 1)
2155 && TREE_INT_CST_LOW (len) >= 1
2156 && TREE_INT_CST_LOW (len)
2157 == (unsigned HOST_WIDE_INT)
2158 TREE_STRING_LENGTH (TREE_OPERAND (TREE_OPERAND (str, 0), 0)))
2159 {
2160 tree folded = fold_convert (gfc_get_pchar_type (kind), str);
2161 folded = build_fold_indirect_ref_loc (input_location, folded);
2162 if (TREE_CODE (folded) == INTEGER_CST)
2163 {
2164 tree string_cst = TREE_OPERAND (TREE_OPERAND (str, 0), 0);
2165 int length = TREE_STRING_LENGTH (string_cst);
2166 const char *ptr = TREE_STRING_POINTER (string_cst);
2167
2168 for (; length > 0; length--)
2169 if (ptr[length - 1] != ' ')
2170 break;
2171
2172 return length;
2173 }
2174 }
2175 return -1;
2176}
e032c2a1 2177
0a821a92
FW
2178/* Compare two strings. If they are all single characters, the result is the
2179 subtraction of them. Otherwise, we build a library call. */
2180
2181tree
23b10420
JJ
2182gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind,
2183 enum tree_code code)
0a821a92
FW
2184{
2185 tree sc1;
2186 tree sc2;
23b10420 2187 tree fndecl;
0a821a92
FW
2188
2189 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
2190 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
2191
d2886bc7
JJ
2192 sc1 = gfc_string_to_single_character (len1, str1, kind);
2193 sc2 = gfc_string_to_single_character (len2, str2, kind);
0a821a92 2194
0a821a92
FW
2195 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
2196 {
374929b2 2197 /* Deal with single character specially. */
c9ff1de3
FXC
2198 sc1 = fold_convert (integer_type_node, sc1);
2199 sc2 = fold_convert (integer_type_node, sc2);
65a9ca82
TB
2200 return fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
2201 sc1, sc2);
0a821a92 2202 }
374929b2 2203
23b10420
JJ
2204 if ((code == EQ_EXPR || code == NE_EXPR)
2205 && optimize
2206 && INTEGER_CST_P (len1) && INTEGER_CST_P (len2))
2207 {
2208 /* If one string is a string literal with LEN_TRIM longer
2209 than the length of the second string, the strings
2210 compare unequal. */
2211 int len = gfc_optimize_len_trim (len1, str1, kind);
2212 if (len > 0 && compare_tree_int (len2, len) < 0)
2213 return integer_one_node;
2214 len = gfc_optimize_len_trim (len2, str2, kind);
2215 if (len > 0 && compare_tree_int (len1, len) < 0)
2216 return integer_one_node;
374929b2
FXC
2217 }
2218
23b10420
JJ
2219 /* Build a call for the comparison. */
2220 if (kind == 1)
2221 fndecl = gfor_fndecl_compare_string;
2222 else if (kind == 4)
2223 fndecl = gfor_fndecl_compare_string_char4;
2224 else
2225 gcc_unreachable ();
2226
2227 return build_call_expr_loc (input_location, fndecl, 4,
2228 len1, str1, len2, str2);
0a821a92 2229}
f8d0aee5 2230
23878536
JW
2231
2232/* Return the backend_decl for a procedure pointer component. */
2233
2234static tree
2235get_proc_ptr_comp (gfc_expr *e)
2236{
2237 gfc_se comp_se;
2238 gfc_expr *e2;
c12ee5df
MM
2239 expr_t old_type;
2240
23878536
JW
2241 gfc_init_se (&comp_se, NULL);
2242 e2 = gfc_copy_expr (e);
c12ee5df
MM
2243 /* We have to restore the expr type later so that gfc_free_expr frees
2244 the exact same thing that was allocated.
2245 TODO: This is ugly. */
2246 old_type = e2->expr_type;
23878536
JW
2247 e2->expr_type = EXPR_VARIABLE;
2248 gfc_conv_expr (&comp_se, e2);
c12ee5df 2249 e2->expr_type = old_type;
f43085aa 2250 gfc_free_expr (e2);
23878536
JW
2251 return build_fold_addr_expr_loc (input_location, comp_se.expr);
2252}
2253
2254
94fae14b
PT
2255/* Convert a typebound function reference from a class object. */
2256static void
2257conv_base_obj_fcn_val (gfc_se * se, tree base_object, gfc_expr * expr)
2258{
2259 gfc_ref *ref;
2260 tree var;
2261
2262 if (TREE_CODE (base_object) != VAR_DECL)
2263 {
2264 var = gfc_create_var (TREE_TYPE (base_object), NULL);
2265 gfc_add_modify (&se->pre, var, base_object);
2266 }
2267 se->expr = gfc_class_vptr_get (base_object);
2268 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
2269 ref = expr->ref;
2270 while (ref && ref->next)
2271 ref = ref->next;
2272 gcc_assert (ref && ref->type == REF_COMPONENT);
2273 if (ref->u.c.sym->attr.extension)
2274 conv_parent_component_references (se, ref);
2275 gfc_conv_component_ref (se, ref);
2276 se->expr = build_fold_addr_expr_loc (input_location, se->expr);
2277}
2278
2279
6de9cd9a 2280static void
713485cc 2281conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
6de9cd9a
DN
2282{
2283 tree tmp;
2284
f64edc8b 2285 if (gfc_is_proc_ptr_comp (expr, NULL))
23878536 2286 tmp = get_proc_ptr_comp (expr);
713485cc 2287 else if (sym->attr.dummy)
6de9cd9a
DN
2288 {
2289 tmp = gfc_get_symbol_decl (sym);
8fb74da4 2290 if (sym->attr.proc_pointer)
db3927fb
AH
2291 tmp = build_fold_indirect_ref_loc (input_location,
2292 tmp);
6e45f57b 2293 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
6de9cd9a 2294 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
6de9cd9a
DN
2295 }
2296 else
2297 {
2298 if (!sym->backend_decl)
2299 sym->backend_decl = gfc_get_extern_function_decl (sym);
2300
2301 tmp = sym->backend_decl;
686c82b5 2302
7074ea72 2303 if (sym->attr.cray_pointee)
686c82b5
PT
2304 {
2305 /* TODO - make the cray pointee a pointer to a procedure,
2306 assign the pointer to it and use it for the call. This
2307 will do for now! */
2308 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
2309 gfc_get_symbol_decl (sym->cp_pointer));
2310 tmp = gfc_evaluate_now (tmp, &se->pre);
2311 }
2312
0348d6fd
RS
2313 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
2314 {
2315 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
628c189e 2316 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
0348d6fd
RS
2317 }
2318 }
2319 se->expr = tmp;
2320}
2321
2322
0348d6fd
RS
2323/* Initialize MAPPING. */
2324
62ab4a54 2325void
0348d6fd
RS
2326gfc_init_interface_mapping (gfc_interface_mapping * mapping)
2327{
2328 mapping->syms = NULL;
2329 mapping->charlens = NULL;
2330}
2331
2332
2333/* Free all memory held by MAPPING (but not MAPPING itself). */
2334
62ab4a54 2335void
0348d6fd
RS
2336gfc_free_interface_mapping (gfc_interface_mapping * mapping)
2337{
2338 gfc_interface_sym_mapping *sym;
2339 gfc_interface_sym_mapping *nextsym;
2340 gfc_charlen *cl;
2341 gfc_charlen *nextcl;
2342
2343 for (sym = mapping->syms; sym; sym = nextsym)
2344 {
2345 nextsym = sym->next;
b800fd64 2346 sym->new_sym->n.sym->formal = NULL;
7b901ac4 2347 gfc_free_symbol (sym->new_sym->n.sym);
0a164a3c 2348 gfc_free_expr (sym->expr);
cede9502
JM
2349 free (sym->new_sym);
2350 free (sym);
0348d6fd
RS
2351 }
2352 for (cl = mapping->charlens; cl; cl = nextcl)
2353 {
2354 nextcl = cl->next;
2355 gfc_free_expr (cl->length);
cede9502 2356 free (cl);
6de9cd9a
DN
2357 }
2358}
2359
2360
0348d6fd
RS
2361/* Return a copy of gfc_charlen CL. Add the returned structure to
2362 MAPPING so that it will be freed by gfc_free_interface_mapping. */
2363
2364static gfc_charlen *
2365gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
2366 gfc_charlen * cl)
2367{
7b901ac4 2368 gfc_charlen *new_charlen;
0348d6fd 2369
7b901ac4
KG
2370 new_charlen = gfc_get_charlen ();
2371 new_charlen->next = mapping->charlens;
2372 new_charlen->length = gfc_copy_expr (cl->length);
0348d6fd 2373
7b901ac4
KG
2374 mapping->charlens = new_charlen;
2375 return new_charlen;
0348d6fd
RS
2376}
2377
2378
2379/* A subroutine of gfc_add_interface_mapping. Return a descriptorless
2380 array variable that can be used as the actual argument for dummy
2381 argument SYM. Add any initialization code to BLOCK. PACKED is as
2382 for gfc_get_nodesc_array_type and DATA points to the first element
2383 in the passed array. */
2384
2385static tree
2386gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
dcfef7d4 2387 gfc_packed packed, tree data)
0348d6fd
RS
2388{
2389 tree type;
2390 tree var;
2391
2392 type = gfc_typenode_for_spec (&sym->ts);
10174ddf
MM
2393 type = gfc_get_nodesc_array_type (type, sym->as, packed,
2394 !sym->attr.target && !sym->attr.pointer
2395 && !sym->attr.proc_pointer);
0348d6fd 2396
20236f90 2397 var = gfc_create_var (type, "ifm");
726a989a 2398 gfc_add_modify (block, var, fold_convert (type, data));
0348d6fd
RS
2399
2400 return var;
2401}
2402
2403
2404/* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
2405 and offset of descriptorless array type TYPE given that it has the same
2406 size as DESC. Add any set-up code to BLOCK. */
2407
2408static void
2409gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
2410{
2411 int n;
2412 tree dim;
2413 tree offset;
2414 tree tmp;
2415
2416 offset = gfc_index_zero_node;
2417 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
2418 {
dd5797cc 2419 dim = gfc_rank_cst[n];
0348d6fd 2420 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
dd5797cc
PT
2421 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
2422 {
2423 GFC_TYPE_ARRAY_LBOUND (type, n)
568e8e1e 2424 = gfc_conv_descriptor_lbound_get (desc, dim);
dd5797cc 2425 GFC_TYPE_ARRAY_UBOUND (type, n)
568e8e1e 2426 = gfc_conv_descriptor_ubound_get (desc, dim);
dd5797cc
PT
2427 }
2428 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
0348d6fd 2429 {
65a9ca82
TB
2430 tmp = fold_build2_loc (input_location, MINUS_EXPR,
2431 gfc_array_index_type,
2432 gfc_conv_descriptor_ubound_get (desc, dim),
2433 gfc_conv_descriptor_lbound_get (desc, dim));
2434 tmp = fold_build2_loc (input_location, PLUS_EXPR,
2435 gfc_array_index_type,
2436 GFC_TYPE_ARRAY_LBOUND (type, n), tmp);
0348d6fd
RS
2437 tmp = gfc_evaluate_now (tmp, block);
2438 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
2439 }
65a9ca82
TB
2440 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
2441 GFC_TYPE_ARRAY_LBOUND (type, n),
2442 GFC_TYPE_ARRAY_STRIDE (type, n));
2443 offset = fold_build2_loc (input_location, MINUS_EXPR,
2444 gfc_array_index_type, offset, tmp);
0348d6fd
RS
2445 }
2446 offset = gfc_evaluate_now (offset, block);
2447 GFC_TYPE_ARRAY_OFFSET (type) = offset;
2448}
2449
2450
2451/* Extend MAPPING so that it maps dummy argument SYM to the value stored
2452 in SE. The caller may still use se->expr and se->string_length after
2453 calling this function. */
2454
62ab4a54 2455void
0348d6fd 2456gfc_add_interface_mapping (gfc_interface_mapping * mapping,
0a164a3c
PT
2457 gfc_symbol * sym, gfc_se * se,
2458 gfc_expr *expr)
0348d6fd
RS
2459{
2460 gfc_interface_sym_mapping *sm;
2461 tree desc;
2462 tree tmp;
2463 tree value;
2464 gfc_symbol *new_sym;
2465 gfc_symtree *root;
2466 gfc_symtree *new_symtree;
2467
2468 /* Create a new symbol to represent the actual argument. */
2469 new_sym = gfc_new_symbol (sym->name, NULL);
2470 new_sym->ts = sym->ts;
0a991dec 2471 new_sym->as = gfc_copy_array_spec (sym->as);
0348d6fd
RS
2472 new_sym->attr.referenced = 1;
2473 new_sym->attr.dimension = sym->attr.dimension;
fe4e525c 2474 new_sym->attr.contiguous = sym->attr.contiguous;
d3a9eea2 2475 new_sym->attr.codimension = sym->attr.codimension;
0348d6fd 2476 new_sym->attr.pointer = sym->attr.pointer;
17029ac2 2477 new_sym->attr.allocatable = sym->attr.allocatable;
0348d6fd 2478 new_sym->attr.flavor = sym->attr.flavor;
0a164a3c 2479 new_sym->attr.function = sym->attr.function;
0348d6fd 2480
4d45d495
PT
2481 /* Ensure that the interface is available and that
2482 descriptors are passed for array actual arguments. */
2483 if (sym->attr.flavor == FL_PROCEDURE)
2484 {
b800fd64 2485 new_sym->formal = expr->symtree->n.sym->formal;
4d45d495
PT
2486 new_sym->attr.always_explicit
2487 = expr->symtree->n.sym->attr.always_explicit;
2488 }
2489
0348d6fd
RS
2490 /* Create a fake symtree for it. */
2491 root = NULL;
2492 new_symtree = gfc_new_symtree (&root, sym->name);
2493 new_symtree->n.sym = new_sym;
2494 gcc_assert (new_symtree == root);
2495
2496 /* Create a dummy->actual mapping. */
ece3f663 2497 sm = XCNEW (gfc_interface_sym_mapping);
0348d6fd
RS
2498 sm->next = mapping->syms;
2499 sm->old = sym;
7b901ac4 2500 sm->new_sym = new_symtree;
0a164a3c 2501 sm->expr = gfc_copy_expr (expr);
0348d6fd
RS
2502 mapping->syms = sm;
2503
2504 /* Stabilize the argument's value. */
0a164a3c
PT
2505 if (!sym->attr.function && se)
2506 se->expr = gfc_evaluate_now (se->expr, &se->pre);
0348d6fd
RS
2507
2508 if (sym->ts.type == BT_CHARACTER)
2509 {
2510 /* Create a copy of the dummy argument's length. */
bc21d315
JW
2511 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
2512 sm->expr->ts.u.cl = new_sym->ts.u.cl;
0348d6fd
RS
2513
2514 /* If the length is specified as "*", record the length that
2515 the caller is passing. We should use the callee's length
2516 in all other cases. */
bc21d315 2517 if (!new_sym->ts.u.cl->length && se)
0348d6fd
RS
2518 {
2519 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
bc21d315 2520 new_sym->ts.u.cl->backend_decl = se->string_length;
0348d6fd
RS
2521 }
2522 }
2523
0a164a3c
PT
2524 if (!se)
2525 return;
2526
0348d6fd
RS
2527 /* Use the passed value as-is if the argument is a function. */
2528 if (sym->attr.flavor == FL_PROCEDURE)
2529 value = se->expr;
2530
2531 /* If the argument is either a string or a pointer to a string,
2532 convert it to a boundless character type. */
2533 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
2534 {
2535 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
2536 tmp = build_pointer_type (tmp);
2537 if (sym->attr.pointer)
db3927fb
AH
2538 value = build_fold_indirect_ref_loc (input_location,
2539 se->expr);
95cb77e6
WG
2540 else
2541 value = se->expr;
2542 value = fold_convert (tmp, value);
0348d6fd
RS
2543 }
2544
17029ac2
EE
2545 /* If the argument is a scalar, a pointer to an array or an allocatable,
2546 dereference it. */
2547 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
db3927fb
AH
2548 value = build_fold_indirect_ref_loc (input_location,
2549 se->expr);
ed78a116
PT
2550
2551 /* For character(*), use the actual argument's descriptor. */
bc21d315 2552 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
db3927fb
AH
2553 value = build_fold_indirect_ref_loc (input_location,
2554 se->expr);
0348d6fd
RS
2555
2556 /* If the argument is an array descriptor, use it to determine
2557 information about the actual argument's shape. */
2558 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
2559 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
2560 {
2561 /* Get the actual argument's descriptor. */
db3927fb
AH
2562 desc = build_fold_indirect_ref_loc (input_location,
2563 se->expr);
0348d6fd
RS
2564
2565 /* Create the replacement variable. */
2566 tmp = gfc_conv_descriptor_data_get (desc);
dcfef7d4
TS
2567 value = gfc_get_interface_mapping_array (&se->pre, sym,
2568 PACKED_NO, tmp);
0348d6fd
RS
2569
2570 /* Use DESC to work out the upper bounds, strides and offset. */
2571 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
2572 }
2573 else
2574 /* Otherwise we have a packed array. */
dcfef7d4
TS
2575 value = gfc_get_interface_mapping_array (&se->pre, sym,
2576 PACKED_FULL, se->expr);
0348d6fd
RS
2577
2578 new_sym->backend_decl = value;
2579}
2580
2581
2582/* Called once all dummy argument mappings have been added to MAPPING,
2583 but before the mapping is used to evaluate expressions. Pre-evaluate
2584 the length of each argument, adding any initialization code to PRE and
2585 any finalization code to POST. */
2586
62ab4a54 2587void
0348d6fd
RS
2588gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
2589 stmtblock_t * pre, stmtblock_t * post)
2590{
2591 gfc_interface_sym_mapping *sym;
2592 gfc_expr *expr;
2593 gfc_se se;
2594
2595 for (sym = mapping->syms; sym; sym = sym->next)
7b901ac4 2596 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
bc21d315 2597 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
0348d6fd 2598 {
bc21d315 2599 expr = sym->new_sym->n.sym->ts.u.cl->length;
0348d6fd
RS
2600 gfc_apply_interface_mapping_to_expr (mapping, expr);
2601 gfc_init_se (&se, NULL);
2602 gfc_conv_expr (&se, expr);
18dd272d 2603 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
0348d6fd
RS
2604 se.expr = gfc_evaluate_now (se.expr, &se.pre);
2605 gfc_add_block_to_block (pre, &se.pre);
2606 gfc_add_block_to_block (post, &se.post);
2607
bc21d315 2608 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
0348d6fd
RS
2609 }
2610}
2611
2612
2613/* Like gfc_apply_interface_mapping_to_expr, but applied to
2614 constructor C. */
2615
2616static void
2617gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
b7e75771 2618 gfc_constructor_base base)
0348d6fd 2619{
b7e75771
JD
2620 gfc_constructor *c;
2621 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
0348d6fd
RS
2622 {
2623 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
2624 if (c->iterator)
2625 {
2626 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
2627 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
2628 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
2629 }
2630 }
2631}
2632
2633
2634/* Like gfc_apply_interface_mapping_to_expr, but applied to
2635 reference REF. */
2636
2637static void
2638gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
2639 gfc_ref * ref)
2640{
2641 int n;
2642
2643 for (; ref; ref = ref->next)
2644 switch (ref->type)
2645 {
2646 case REF_ARRAY:
2647 for (n = 0; n < ref->u.ar.dimen; n++)
2648 {
2649 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
2650 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
2651 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
2652 }
2653 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.offset);
2654 break;
2655
2656 case REF_COMPONENT:
2657 break;
2658
2659 case REF_SUBSTRING:
2660 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
2661 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
2662 break;
2663 }
2664}
2665
2666
0a164a3c 2667/* Convert intrinsic function calls into result expressions. */
0a991dec 2668
0a164a3c 2669static bool
0a991dec 2670gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
0a164a3c
PT
2671{
2672 gfc_symbol *sym;
2673 gfc_expr *new_expr;
2674 gfc_expr *arg1;
2675 gfc_expr *arg2;
2676 int d, dup;
2677
2678 arg1 = expr->value.function.actual->expr;
2679 if (expr->value.function.actual->next)
2680 arg2 = expr->value.function.actual->next->expr;
2681 else
2682 arg2 = NULL;
2683
0a991dec 2684 sym = arg1->symtree->n.sym;
0a164a3c
PT
2685
2686 if (sym->attr.dummy)
2687 return false;
2688
2689 new_expr = NULL;
2690
2691 switch (expr->value.function.isym->id)
2692 {
2693 case GFC_ISYM_LEN:
2694 /* TODO figure out why this condition is necessary. */
2695 if (sym->attr.function
bc21d315
JW
2696 && (arg1->ts.u.cl->length == NULL
2697 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
2698 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
0a164a3c
PT
2699 return false;
2700
bc21d315 2701 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
0a164a3c
PT
2702 break;
2703
2704 case GFC_ISYM_SIZE:
d3a9eea2 2705 if (!sym->as || sym->as->rank == 0)
0a164a3c
PT
2706 return false;
2707
2708 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
2709 {
2710 dup = mpz_get_si (arg2->value.integer);
2711 d = dup - 1;
2712 }
2713 else
2714 {
2715 dup = sym->as->rank;
2716 d = 0;
2717 }
2718
2719 for (; d < dup; d++)
2720 {
2721 gfc_expr *tmp;
0a991dec
DK
2722
2723 if (!sym->as->upper[d] || !sym->as->lower[d])
2724 {
2725 gfc_free_expr (new_expr);
2726 return false;
2727 }
2728
b7e75771
JD
2729 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]),
2730 gfc_get_int_expr (gfc_default_integer_kind,
2731 NULL, 1));
0a164a3c
PT
2732 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
2733 if (new_expr)
2734 new_expr = gfc_multiply (new_expr, tmp);
2735 else
2736 new_expr = tmp;
2737 }
2738 break;
2739
2740 case GFC_ISYM_LBOUND:
2741 case GFC_ISYM_UBOUND:
2742 /* TODO These implementations of lbound and ubound do not limit if
2743 the size < 0, according to F95's 13.14.53 and 13.14.113. */
2744
d3a9eea2 2745 if (!sym->as || sym->as->rank == 0)
0a164a3c
PT
2746 return false;
2747
2748 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
2749 d = mpz_get_si (arg2->value.integer) - 1;
2750 else
2751 /* TODO: If the need arises, this could produce an array of
2752 ubound/lbounds. */
2753 gcc_unreachable ();
2754
2755 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
0a991dec
DK
2756 {
2757 if (sym->as->lower[d])
2758 new_expr = gfc_copy_expr (sym->as->lower[d]);
2759 }
0a164a3c 2760 else
0a991dec
DK
2761 {
2762 if (sym->as->upper[d])
2763 new_expr = gfc_copy_expr (sym->as->upper[d]);
2764 }
0a164a3c
PT
2765 break;
2766
2767 default:
2768 break;
2769 }
2770
2771 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
2772 if (!new_expr)
2773 return false;
2774
2775 gfc_replace_expr (expr, new_expr);
2776 return true;
2777}
2778
2779
2780static void
2781gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
2782 gfc_interface_mapping * mapping)
2783{
2784 gfc_formal_arglist *f;
2785 gfc_actual_arglist *actual;
2786
2787 actual = expr->value.function.actual;
2788 f = map_expr->symtree->n.sym->formal;
2789
2790 for (; f && actual; f = f->next, actual = actual->next)
2791 {
2792 if (!actual->expr)
2793 continue;
2794
2795 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
2796 }
2797
2798 if (map_expr->symtree->n.sym->attr.dimension)
2799 {
2800 int d;
2801 gfc_array_spec *as;
2802
2803 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
2804
2805 for (d = 0; d < as->rank; d++)
2806 {
2807 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
2808 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
2809 }
2810
2811 expr->value.function.esym->as = as;
2812 }
2813
2814 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
2815 {
bc21d315
JW
2816 expr->value.function.esym->ts.u.cl->length
2817 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
0a164a3c
PT
2818
2819 gfc_apply_interface_mapping_to_expr (mapping,
bc21d315 2820 expr->value.function.esym->ts.u.cl->length);
0a164a3c
PT
2821 }
2822}
2823
2824
0348d6fd
RS
2825/* EXPR is a copy of an expression that appeared in the interface
2826 associated with MAPPING. Walk it recursively looking for references to
2827 dummy arguments that MAPPING maps to actual arguments. Replace each such
2828 reference with a reference to the associated actual argument. */
2829
0a164a3c 2830static void
0348d6fd
RS
2831gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
2832 gfc_expr * expr)
2833{
2834 gfc_interface_sym_mapping *sym;
2835 gfc_actual_arglist *actual;
2836
2837 if (!expr)
0a164a3c 2838 return;
0348d6fd
RS
2839
2840 /* Copying an expression does not copy its length, so do that here. */
bc21d315 2841 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
0348d6fd 2842 {
bc21d315
JW
2843 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
2844 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
0348d6fd
RS
2845 }
2846
2847 /* Apply the mapping to any references. */
2848 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
2849
2850 /* ...and to the expression's symbol, if it has one. */
0a164a3c 2851 /* TODO Find out why the condition on expr->symtree had to be moved into
df2fba9e 2852 the loop rather than being outside it, as originally. */
0a164a3c
PT
2853 for (sym = mapping->syms; sym; sym = sym->next)
2854 if (expr->symtree && sym->old == expr->symtree->n.sym)
2855 {
7b901ac4
KG
2856 if (sym->new_sym->n.sym->backend_decl)
2857 expr->symtree = sym->new_sym;
0a164a3c
PT
2858 else if (sym->expr)
2859 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
2e49964f
JW
2860 /* Replace base type for polymorphic arguments. */
2861 if (expr->ref && expr->ref->type == REF_COMPONENT
2862 && sym->expr && sym->expr->ts.type == BT_CLASS)
2863 expr->ref->u.c.sym = sym->expr->ts.u.derived;
0a164a3c 2864 }
0348d6fd 2865
0a164a3c 2866 /* ...and to subexpressions in expr->value. */
0348d6fd
RS
2867 switch (expr->expr_type)
2868 {
2869 case EXPR_VARIABLE:
2870 case EXPR_CONSTANT:
2871 case EXPR_NULL:
2872 case EXPR_SUBSTRING:
2873 break;
2874
2875 case EXPR_OP:
2876 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
2877 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
2878 break;
2879
2880 case EXPR_FUNCTION:
0a164a3c
PT
2881 for (actual = expr->value.function.actual; actual; actual = actual->next)
2882 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
2883
36032710 2884 if (expr->value.function.esym == NULL
6a661315 2885 && expr->value.function.isym != NULL
0a164a3c
PT
2886 && expr->value.function.actual->expr->symtree
2887 && gfc_map_intrinsic_function (expr, mapping))
2888 break;
6a661315 2889
0348d6fd
RS
2890 for (sym = mapping->syms; sym; sym = sym->next)
2891 if (sym->old == expr->value.function.esym)
0a164a3c 2892 {
7b901ac4 2893 expr->value.function.esym = sym->new_sym->n.sym;
0a164a3c 2894 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
7b901ac4 2895 expr->value.function.esym->result = sym->new_sym->n.sym;
0a164a3c 2896 }
0348d6fd
RS
2897 break;
2898
2899 case EXPR_ARRAY:
2900 case EXPR_STRUCTURE:
2901 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
2902 break;
8e1f752a
DK
2903
2904 case EXPR_COMPCALL:
713485cc 2905 case EXPR_PPC:
8e1f752a
DK
2906 gcc_unreachable ();
2907 break;
0348d6fd 2908 }
0a164a3c
PT
2909
2910 return;
0348d6fd
RS
2911}
2912
2913
2914/* Evaluate interface expression EXPR using MAPPING. Store the result
2915 in SE. */
2916
62ab4a54 2917void
0348d6fd
RS
2918gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
2919 gfc_se * se, gfc_expr * expr)
2920{
2921 expr = gfc_copy_expr (expr);
2922 gfc_apply_interface_mapping_to_expr (mapping, expr);
2923 gfc_conv_expr (se, expr);
2924 se->expr = gfc_evaluate_now (se->expr, &se->pre);
2925 gfc_free_expr (expr);
2926}
2927
1d6b7f39 2928
68ea355b
PT
2929/* Returns a reference to a temporary array into which a component of
2930 an actual argument derived type array is copied and then returned
1d6b7f39 2931 after the function call. */
d4feb3d3 2932void
430f2d1f
PT
2933gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
2934 sym_intent intent, bool formal_ptr)
68ea355b
PT
2935{
2936 gfc_se lse;
2937 gfc_se rse;
2938 gfc_ss *lss;
2939 gfc_ss *rss;
2940 gfc_loopinfo loop;
2941 gfc_loopinfo loop2;
6d63e468 2942 gfc_array_info *info;
68ea355b
PT
2943 tree offset;
2944 tree tmp_index;
2945 tree tmp;
2946 tree base_type;
430f2d1f 2947 tree size;
68ea355b
PT
2948 stmtblock_t body;
2949 int n;
45406a12 2950 int dimen;
68ea355b
PT
2951
2952 gcc_assert (expr->expr_type == EXPR_VARIABLE);
2953
2954 gfc_init_se (&lse, NULL);
2955 gfc_init_se (&rse, NULL);
2956
2957 /* Walk the argument expression. */
2958 rss = gfc_walk_expr (expr);
2959
2960 gcc_assert (rss != gfc_ss_terminator);
2961
2962 /* Initialize the scalarizer. */
2963 gfc_init_loopinfo (&loop);
2964 gfc_add_ss_to_loop (&loop, rss);
2965
2966 /* Calculate the bounds of the scalarization. */
2967 gfc_conv_ss_startstride (&loop);
2968
2969 /* Build an ss for the temporary. */
bc21d315
JW
2970 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
2971 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
07368af0 2972
68ea355b
PT
2973 base_type = gfc_typenode_for_spec (&expr->ts);
2974 if (GFC_ARRAY_TYPE_P (base_type)
2975 || GFC_DESCRIPTOR_TYPE_P (base_type))
2976 base_type = gfc_get_element_type (base_type);
2977
c49ea23d
PT
2978 if (expr->ts.type == BT_CLASS)
2979 base_type = gfc_typenode_for_spec (&CLASS_DATA (expr)->ts);
2980
a1ae4f43
MM
2981 loop.temp_ss = gfc_get_temp_ss (base_type, ((expr->ts.type == BT_CHARACTER)
2982 ? expr->ts.u.cl->backend_decl
2983 : NULL),
2984 loop.dimen);
68ea355b 2985
a0add3be 2986 parmse->string_length = loop.temp_ss->info->string_length;
68ea355b
PT
2987
2988 /* Associate the SS with the loop. */
2989 gfc_add_ss_to_loop (&loop, loop.temp_ss);
2990
2991 /* Setup the scalarizing loops. */
bdfd2ff0 2992 gfc_conv_loop_setup (&loop, &expr->where);
68ea355b
PT
2993
2994 /* Pass the temporary descriptor back to the caller. */
1838afec 2995 info = &loop.temp_ss->info->data.array;
68ea355b
PT
2996 parmse->expr = info->descriptor;
2997
2998 /* Setup the gfc_se structures. */
2999 gfc_copy_loopinfo_to_se (&lse, &loop);
3000 gfc_copy_loopinfo_to_se (&rse, &loop);
3001
3002 rse.ss = rss;
3003 lse.ss = loop.temp_ss;
3004 gfc_mark_ss_chain_used (rss, 1);
3005 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3006
3007 /* Start the scalarized loop body. */
3008 gfc_start_scalarized_body (&loop, &body);
3009
3010 /* Translate the expression. */
3011 gfc_conv_expr (&rse, expr);
3012
3013 gfc_conv_tmp_array_ref (&lse);
68ea355b 3014
1855915a
PT
3015 if (intent != INTENT_OUT)
3016 {
2b56d6a4 3017 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false, true);
1855915a
PT
3018 gfc_add_expr_to_block (&body, tmp);
3019 gcc_assert (rse.ss == gfc_ss_terminator);
3020 gfc_trans_scalarizing_loops (&loop, &body);
3021 }
8c086c9c
PT
3022 else
3023 {
58b6e047
PT
3024 /* Make sure that the temporary declaration survives by merging
3025 all the loop declarations into the current context. */
3026 for (n = 0; n < loop.dimen; n++)
3027 {
3028 gfc_merge_block_scope (&body);
3029 body = loop.code[loop.order[n]];
3030 }
3031 gfc_merge_block_scope (&body);
8c086c9c 3032 }
68ea355b
PT
3033
3034 /* Add the post block after the second loop, so that any
3035 freeing of allocated memory is done at the right time. */
3036 gfc_add_block_to_block (&parmse->pre, &loop.pre);
3037
3038 /**********Copy the temporary back again.*********/
3039
3040 gfc_init_se (&lse, NULL);
3041 gfc_init_se (&rse, NULL);
3042
3043 /* Walk the argument expression. */
3044 lss = gfc_walk_expr (expr);
3045 rse.ss = loop.temp_ss;
3046 lse.ss = lss;
3047
3048 /* Initialize the scalarizer. */
3049 gfc_init_loopinfo (&loop2);
3050 gfc_add_ss_to_loop (&loop2, lss);
3051
3052 /* Calculate the bounds of the scalarization. */
3053 gfc_conv_ss_startstride (&loop2);
3054
3055 /* Setup the scalarizing loops. */
bdfd2ff0 3056 gfc_conv_loop_setup (&loop2, &expr->where);
68ea355b
PT
3057
3058 gfc_copy_loopinfo_to_se (&lse, &loop2);
3059 gfc_copy_loopinfo_to_se (&rse, &loop2);
3060
3061 gfc_mark_ss_chain_used (lss, 1);
3062 gfc_mark_ss_chain_used (loop.temp_ss, 1);
3063
3064 /* Declare the variable to hold the temporary offset and start the
3065 scalarized loop body. */
3066 offset = gfc_create_var (gfc_array_index_type, NULL);
3067 gfc_start_scalarized_body (&loop2, &body);
3068
3069 /* Build the offsets for the temporary from the loop variables. The
3070 temporary array has lbounds of zero and strides of one in all
3071 dimensions, so this is very simple. The offset is only computed
3072 outside the innermost loop, so the overall transfer could be
b82feea5 3073 optimized further. */
1838afec 3074 info = &rse.ss->info->data.array;
cb4b9eae 3075 dimen = rse.ss->dimen;
68ea355b
PT
3076
3077 tmp_index = gfc_index_zero_node;
45406a12 3078 for (n = dimen - 1; n > 0; n--)
68ea355b
PT
3079 {
3080 tree tmp_str;
3081 tmp = rse.loop->loopvar[n];
65a9ca82
TB
3082 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3083 tmp, rse.loop->from[n]);
3084 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3085 tmp, tmp_index);
3086
3087 tmp_str = fold_build2_loc (input_location, MINUS_EXPR,
3088 gfc_array_index_type,
3089 rse.loop->to[n-1], rse.loop->from[n-1]);
3090 tmp_str = fold_build2_loc (input_location, PLUS_EXPR,
3091 gfc_array_index_type,
3092 tmp_str, gfc_index_one_node);
3093
3094 tmp_index = fold_build2_loc (input_location, MULT_EXPR,
3095 gfc_array_index_type, tmp, tmp_str);
68ea355b
PT
3096 }
3097
65a9ca82
TB
3098 tmp_index = fold_build2_loc (input_location, MINUS_EXPR,
3099 gfc_array_index_type,
3100 tmp_index, rse.loop->from[0]);
726a989a 3101 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
68ea355b 3102
65a9ca82
TB
3103 tmp_index = fold_build2_loc (input_location, PLUS_EXPR,
3104 gfc_array_index_type,
3105 rse.loop->loopvar[0], offset);
68ea355b
PT
3106
3107 /* Now use the offset for the reference. */
db3927fb
AH
3108 tmp = build_fold_indirect_ref_loc (input_location,
3109 info->data);
1d6b7f39 3110 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
68ea355b
PT
3111
3112 if (expr->ts.type == BT_CHARACTER)
bc21d315 3113 rse.string_length = expr->ts.u.cl->backend_decl;
68ea355b
PT
3114
3115 gfc_conv_expr (&lse, expr);
3116
3117 gcc_assert (lse.ss == gfc_ss_terminator);
3118
2b56d6a4 3119 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false, true);
68ea355b
PT
3120 gfc_add_expr_to_block (&body, tmp);
3121
3122 /* Generate the copying loops. */
3123 gfc_trans_scalarizing_loops (&loop2, &body);
3124
3125 /* Wrap the whole thing up by adding the second loop to the post-block
1855915a 3126 and following it by the post-block of the first loop. In this way,
68ea355b 3127 if the temporary needs freeing, it is done after use! */
1855915a
PT
3128 if (intent != INTENT_IN)
3129 {
3130 gfc_add_block_to_block (&parmse->post, &loop2.pre);
3131 gfc_add_block_to_block (&parmse->post, &loop2.post);
3132 }
68ea355b
PT
3133
3134 gfc_add_block_to_block (&parmse->post, &loop.post);
3135
3136 gfc_cleanup_loop (&loop);
3137 gfc_cleanup_loop (&loop2);
3138
3139 /* Pass the string length to the argument expression. */
3140 if (expr->ts.type == BT_CHARACTER)
bc21d315 3141 parmse->string_length = expr->ts.u.cl->backend_decl;
68ea355b 3142
430f2d1f
PT
3143 /* Determine the offset for pointer formal arguments and set the
3144 lbounds to one. */
3145 if (formal_ptr)
3146 {
3147 size = gfc_index_one_node;
3148 offset = gfc_index_zero_node;
45406a12 3149 for (n = 0; n < dimen; n++)
430f2d1f
PT
3150 {
3151 tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
3152 gfc_rank_cst[n]);
65a9ca82
TB
3153 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3154 gfc_array_index_type, tmp,
3155 gfc_index_one_node);
430f2d1f
PT
3156 gfc_conv_descriptor_ubound_set (&parmse->pre,
3157 parmse->expr,
3158 gfc_rank_cst[n],
3159 tmp);
3160 gfc_conv_descriptor_lbound_set (&parmse->pre,
3161 parmse->expr,
3162 gfc_rank_cst[n],
3163 gfc_index_one_node);
3164 size = gfc_evaluate_now (size, &parmse->pre);
65a9ca82
TB
3165 offset = fold_build2_loc (input_location, MINUS_EXPR,
3166 gfc_array_index_type,
3167 offset, size);
430f2d1f 3168 offset = gfc_evaluate_now (offset, &parmse->pre);
65a9ca82
TB
3169 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3170 gfc_array_index_type,
3171 rse.loop->to[n], rse.loop->from[n]);
3172 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3173 gfc_array_index_type,
3174 tmp, gfc_index_one_node);
3175 size = fold_build2_loc (input_location, MULT_EXPR,
3176 gfc_array_index_type, size, tmp);
430f2d1f
PT
3177 }
3178
3179 gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
3180 offset);
3181 }
3182
68ea355b
PT
3183 /* We want either the address for the data or the address of the descriptor,
3184 depending on the mode of passing array arguments. */
3185 if (g77)
3186 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
3187 else
628c189e 3188 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
68ea355b
PT
3189
3190 return;
3191}
3192
0348d6fd 3193
7fcafa71
PT
3194/* Generate the code for argument list functions. */
3195
3196static void
3197conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
3198{
7fcafa71
PT
3199 /* Pass by value for g77 %VAL(arg), pass the address
3200 indirectly for %LOC, else by reference. Thus %REF
3201 is a "do-nothing" and %LOC is the same as an F95
3202 pointer. */
3203 if (strncmp (name, "%VAL", 4) == 0)
7193e30a 3204 gfc_conv_expr (se, expr);
7fcafa71
PT
3205 else if (strncmp (name, "%LOC", 4) == 0)
3206 {
3207 gfc_conv_expr_reference (se, expr);
3208 se->expr = gfc_build_addr_expr (NULL, se->expr);
3209 }
3210 else if (strncmp (name, "%REF", 4) == 0)
3211 gfc_conv_expr_reference (se, expr);
3212 else
3213 gfc_error ("Unknown argument list function at %L", &expr->where);
3214}
3215
3216
08fbe2fe
JW
3217/* The following routine generates code for the intrinsic
3218 procedures from the ISO_C_BINDING module:
3219 * C_LOC (function)
3220 * C_FUNLOC (function)
3221 * C_F_POINTER (subroutine)
3222 * C_F_PROCPOINTER (subroutine)
3223 * C_ASSOCIATED (function)
3224 One exception which is not handled here is C_F_POINTER with non-scalar
3225 arguments. Returns 1 if the call was replaced by inline code (else: 0). */
3226
3227static int
3228conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
3229 gfc_actual_arglist * arg)
3230{
3231 gfc_symbol *fsym;
3232 gfc_ss *argss;
3233
3234 if (sym->intmod_sym_id == ISOCBINDING_LOC)
3235 {
3236 if (arg->expr->rank == 0)
3237 gfc_conv_expr_reference (se, arg->expr);
3238 else
3239 {
3240 int f;
3241 /* This is really the actual arg because no formal arglist is
3242 created for C_LOC. */
3243 fsym = arg->expr->symtree->n.sym;
3244
3245 /* We should want it to do g77 calling convention. */
3246 f = (fsym != NULL)
3247 && !(fsym->attr.pointer || fsym->attr.allocatable)
3248 && fsym->as->type != AS_ASSUMED_SHAPE;
3249 f = f || !sym->attr.always_explicit;
3250
3251 argss = gfc_walk_expr (arg->expr);
3252 gfc_conv_array_parameter (se, arg->expr, argss, f,
3253 NULL, NULL, NULL);
3254 }
3255
3256 /* TODO -- the following two lines shouldn't be necessary, but if
3257 they're removed, a bug is exposed later in the code path.
3258 This workaround was thus introduced, but will have to be
3259 removed; please see PR 35150 for details about the issue. */
3260 se->expr = convert (pvoid_type_node, se->expr);
3261 se->expr = gfc_evaluate_now (se->expr, &se->pre);
3262
3263 return 1;
3264 }
3265 else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC)
3266 {
3267 arg->expr->ts.type = sym->ts.u.derived->ts.type;
3268 arg->expr->ts.f90_type = sym->ts.u.derived->ts.f90_type;
3269 arg->expr->ts.kind = sym->ts.u.derived->ts.kind;
3270 gfc_conv_expr_reference (se, arg->expr);
3271
3272 return 1;
3273 }
3274 else if ((sym->intmod_sym_id == ISOCBINDING_F_POINTER
3275 && arg->next->expr->rank == 0)
3276 || sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)
3277 {
3278 /* Convert c_f_pointer if fptr is a scalar
3279 and convert c_f_procpointer. */
3280 gfc_se cptrse;
3281 gfc_se fptrse;
3282
3283 gfc_init_se (&cptrse, NULL);
3284 gfc_conv_expr (&cptrse, arg->expr);
3285 gfc_add_block_to_block (&se->pre, &cptrse.pre);
3286 gfc_add_block_to_block (&se->post, &cptrse.post);
3287
3288 gfc_init_se (&fptrse, NULL);
3289 if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
3290 || gfc_is_proc_ptr_comp (arg->next->expr, NULL))
3291 fptrse.want_pointer = 1;
3292
3293 gfc_conv_expr (&fptrse, arg->next->expr);
3294 gfc_add_block_to_block (&se->pre, &fptrse.pre);
3295 gfc_add_block_to_block (&se->post, &fptrse.post);
3296
3297 if (arg->next->expr->symtree->n.sym->attr.proc_pointer
3298 && arg->next->expr->symtree->n.sym->attr.dummy)
3299 fptrse.expr = build_fold_indirect_ref_loc (input_location,
3300 fptrse.expr);
3301
65a9ca82
TB
3302 se->expr = fold_build2_loc (input_location, MODIFY_EXPR,
3303 TREE_TYPE (fptrse.expr),
3304 fptrse.expr,
3305 fold_convert (TREE_TYPE (fptrse.expr),
3306 cptrse.expr));
08fbe2fe
JW
3307
3308 return 1;
3309 }
3310 else if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
3311 {
3312 gfc_se arg1se;
3313 gfc_se arg2se;
3314
3315 /* Build the addr_expr for the first argument. The argument is
3316 already an *address* so we don't need to set want_pointer in
3317 the gfc_se. */
3318 gfc_init_se (&arg1se, NULL);
3319 gfc_conv_expr (&arg1se, arg->expr);
3320 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3321 gfc_add_block_to_block (&se->post, &arg1se.post);
3322
3323 /* See if we were given two arguments. */
3324 if (arg->next == NULL)
3325 /* Only given one arg so generate a null and do a
3326 not-equal comparison against the first arg. */
65a9ca82
TB
3327 se->expr = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
3328 arg1se.expr,
3329 fold_convert (TREE_TYPE (arg1se.expr),
3330 null_pointer_node));
08fbe2fe
JW
3331 else
3332 {
3333 tree eq_expr;
3334 tree not_null_expr;
3335
3336 /* Given two arguments so build the arg2se from second arg. */
3337 gfc_init_se (&arg2se, NULL);
3338 gfc_conv_expr (&arg2se, arg->next->expr);
3339 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3340 gfc_add_block_to_block (&se->post, &arg2se.post);
3341
3342 /* Generate test to compare that the two args are equal. */
65a9ca82
TB
3343 eq_expr = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
3344 arg1se.expr, arg2se.expr);
08fbe2fe 3345 /* Generate test to ensure that the first arg is not null. */
65a9ca82
TB
3346 not_null_expr = fold_build2_loc (input_location, NE_EXPR,
3347 boolean_type_node,
3348 arg1se.expr, null_pointer_node);
08fbe2fe
JW
3349
3350 /* Finally, the generated test must check that both arg1 is not
3351 NULL and that it is equal to the second arg. */
65a9ca82
TB
3352 se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
3353 boolean_type_node,
3354 not_null_expr, eq_expr);
08fbe2fe
JW
3355 }
3356
3357 return 1;
3358 }
3359
3360 /* Nothing was done. */
3361 return 0;
3362}
3363
0c53708e 3364
6de9cd9a 3365/* Generate code for a procedure call. Note can return se->post != NULL.
dda895f9 3366 If se->direct_byref is set then se->expr contains the return parameter.
713485cc
JW
3367 Return nonzero, if the call has alternate specifiers.
3368 'expr' is only needed for procedure pointer components. */
6de9cd9a 3369
dda895f9 3370int
713485cc 3371gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
0b4f2770 3372 gfc_actual_arglist * args, gfc_expr * expr,
989ea525 3373 VEC(tree,gc) *append_args)
6de9cd9a 3374{
0348d6fd 3375 gfc_interface_mapping mapping;
989ea525
NF
3376 VEC(tree,gc) *arglist;
3377 VEC(tree,gc) *retargs;
6de9cd9a
DN
3378 tree tmp;
3379 tree fntype;
3380 gfc_se parmse;
3381 gfc_ss *argss;
6d63e468 3382 gfc_array_info *info;
6de9cd9a 3383 int byref;
5046aff5 3384 int parm_kind;
6de9cd9a
DN
3385 tree type;
3386 tree var;
3387 tree len;
94fae14b 3388 tree base_object;
989ea525 3389 VEC(tree,gc) *stringargs;
40c32948 3390 tree result = NULL;
6de9cd9a 3391 gfc_formal_arglist *formal;
0b4f2770 3392 gfc_actual_arglist *arg;
dda895f9 3393 int has_alternate_specifier = 0;
0348d6fd 3394 bool need_interface_mapping;
8e119f1b 3395 bool callee_alloc;
0348d6fd
RS
3396 gfc_typespec ts;
3397 gfc_charlen cl;
e15e9be3
PT
3398 gfc_expr *e;
3399 gfc_symbol *fsym;
f5f701ad 3400 stmtblock_t post;
5046aff5 3401 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
c74b74a8 3402 gfc_component *comp = NULL;
989ea525 3403 int arglen;
6de9cd9a 3404
989ea525
NF
3405 arglist = NULL;
3406 retargs = NULL;
3407 stringargs = NULL;
6de9cd9a
DN
3408 var = NULL_TREE;
3409 len = NULL_TREE;
44000dbb 3410 gfc_clear_ts (&ts);
6de9cd9a 3411
08fbe2fe 3412 if (sym->from_intmod == INTMOD_ISO_C_BINDING
0b4f2770 3413 && conv_isocbinding_procedure (se, sym, args))
08fbe2fe 3414 return 0;
f64edc8b
JW
3415
3416 gfc_is_proc_ptr_comp (expr, &comp);
3417
6de9cd9a
DN
3418 if (se->ss != NULL)
3419 {
1b26c26b 3420 if (!sym->attr.elemental && !(comp && comp->attr.elemental))
6de9cd9a 3421 {
bcc4d4e0 3422 gcc_assert (se->ss->info->type == GFC_SS_FUNCTION);
7a412892 3423 if (se->ss->info->useflags)
f7172b55 3424 {
f64edc8b
JW
3425 gcc_assert ((!comp && gfc_return_by_reference (sym)
3426 && sym->result->attr.dimension)
3427 || (comp && comp->attr.dimension));
f7172b55 3428 gcc_assert (se->loop != NULL);
6de9cd9a 3429
f7172b55
PT
3430 /* Access the previously obtained result. */
3431 gfc_conv_tmp_array_ref (se);
f7172b55
PT
3432 return 0;
3433 }
6de9cd9a 3434 }
1838afec 3435 info = &se->ss->info->data.array;
6de9cd9a
DN
3436 }
3437 else
3438 info = NULL;
3439
f5f701ad 3440 gfc_init_block (&post);
0348d6fd 3441 gfc_init_interface_mapping (&mapping);
50dbf0b4
JW
3442 if (!comp)
3443 {
3444 formal = sym->formal;
3445 need_interface_mapping = sym->attr.dimension ||
3446 (sym->ts.type == BT_CHARACTER
3447 && sym->ts.u.cl->length
3448 && sym->ts.u.cl->length->expr_type
3449 != EXPR_CONSTANT);
3450 }
acbdc378 3451 else
50dbf0b4
JW
3452 {
3453 formal = comp->formal;
3454 need_interface_mapping = comp->attr.dimension ||
3455 (comp->ts.type == BT_CHARACTER
3456 && comp->ts.u.cl->length
3457 && comp->ts.u.cl->length->expr_type
3458 != EXPR_CONSTANT);
3459 }
3460
94fae14b
PT
3461 base_object = NULL_TREE;
3462
6de9cd9a 3463 /* Evaluate the arguments. */
0b4f2770
MM
3464 for (arg = args; arg != NULL;
3465 arg = arg->next, formal = formal ? formal->next : NULL)
6de9cd9a 3466 {
e15e9be3
PT
3467 e = arg->expr;
3468 fsym = formal ? formal->sym : NULL;
5046aff5 3469 parm_kind = MISSING;
f7172b55 3470
c49ea23d
PT
3471 /* Class array expressions are sometimes coming completely unadorned
3472 with either arrayspec or _data component. Correct that here.
3473 OOP-TODO: Move this to the frontend. */
3474 if (e && e->expr_type == EXPR_VARIABLE
3475 && !e->ref
3476 && e->ts.type == BT_CLASS
3477 && CLASS_DATA (e)->attr.dimension)
3478 {
3479 gfc_typespec temp_ts = e->ts;
3480 gfc_add_class_array_ref (e);
3481 e->ts = temp_ts;
3482 }
3483
e15e9be3 3484 if (e == NULL)
6de9cd9a 3485 {
6de9cd9a
DN
3486 if (se->ignore_optional)
3487 {
3488 /* Some intrinsics have already been resolved to the correct
3489 parameters. */
3490 continue;
3491 }
3492 else if (arg->label)
3493 {
f7172b55
PT
3494 has_alternate_specifier = 1;
3495 continue;
6de9cd9a
DN
3496 }
3497 else
3498 {
3499 /* Pass a NULL pointer for an absent arg. */
3500 gfc_init_se (&parmse, NULL);
3501 parmse.expr = null_pointer_node;
f7172b55 3502 if (arg->missing_arg_type == BT_CHARACTER)
c3238e32 3503 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
6de9cd9a
DN
3504 }
3505 }
08857b61
TB
3506 else if (arg->expr->expr_type == EXPR_NULL && fsym && !fsym->attr.pointer)
3507 {
3508 /* Pass a NULL pointer to denote an absent arg. */
3509 gcc_assert (fsym->attr.optional && !fsym->attr.allocatable);
3510 gfc_init_se (&parmse, NULL);
3511 parmse.expr = null_pointer_node;
3512 if (arg->missing_arg_type == BT_CHARACTER)
3513 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
3514 }
cf2b3c22
TB
3515 else if (fsym && fsym->ts.type == BT_CLASS
3516 && e->ts.type == BT_DERIVED)
3517 {
cf2b3c22
TB
3518 /* The derived type needs to be converted to a temporary
3519 CLASS object. */
3520 gfc_init_se (&parmse, se);
7c1dab0d 3521 gfc_conv_derived_to_class (&parmse, e, fsym->ts);
cf2b3c22 3522 }
7a412892 3523 else if (se->ss && se->ss->info->useflags)
6de9cd9a
DN
3524 {
3525 /* An elemental function inside a scalarized loop. */
f7172b55 3526 gfc_init_se (&parmse, se);
5046aff5 3527 parm_kind = ELEMENTAL;
fafcf9e6 3528
887ee29f 3529 if (se->ss->dimen > 0 && e->expr_type == EXPR_VARIABLE
fafcf9e6
MM
3530 && se->ss->info->data.array.ref == NULL)
3531 {
3532 gfc_conv_tmp_array_ref (&parmse);
3533 if (e->ts.type == BT_CHARACTER)
3534 gfc_conv_string_parameter (&parmse);
3535 else
3536 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
3537 }
3538 else
3539 gfc_conv_expr_reference (&parmse, e);
c49ea23d
PT
3540
3541 /* The scalarizer does not repackage the reference to a class
3542 array - instead it returns a pointer to the data element. */
3543 if (fsym && fsym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
3544 gfc_conv_class_to_class (&parmse, e, fsym->ts, true);
6de9cd9a
DN
3545 }
3546 else
3547 {
3548 /* A scalar or transformational function. */
3549 gfc_init_se (&parmse, NULL);
e15e9be3 3550 argss = gfc_walk_expr (e);
6de9cd9a
DN
3551
3552 if (argss == gfc_ss_terminator)
f7172b55 3553 {
686c82b5
PT
3554 if (e->expr_type == EXPR_VARIABLE
3555 && e->symtree->n.sym->attr.cray_pointee
3556 && fsym && fsym->attr.flavor == FL_PROCEDURE)
3557 {
3558 /* The Cray pointer needs to be converted to a pointer to
3559 a type given by the expression. */
3560 gfc_conv_expr (&parmse, e);
3561 type = build_pointer_type (TREE_TYPE (parmse.expr));
3562 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
3563 parmse.expr = convert (type, tmp);
3564 }
3565 else if (fsym && fsym->attr.value)
06469efd 3566 {
e032c2a1
CR
3567 if (fsym->ts.type == BT_CHARACTER
3568 && fsym->ts.is_c_interop
3569 && fsym->ns->proc_name != NULL
3570 && fsym->ns->proc_name->attr.is_bind_c)
3571 {
3572 parmse.expr = NULL;
3573 gfc_conv_scalar_char_value (fsym, &parmse, &e);
3574 if (parmse.expr == NULL)
3575 gfc_conv_expr (&parmse, e);
3576 }
3577 else
3578 gfc_conv_expr (&parmse, e);
06469efd 3579 }
7fcafa71
PT
3580 else if (arg->name && arg->name[0] == '%')
3581 /* Argument list functions %VAL, %LOC and %REF are signalled
3582 through arg->name. */
3583 conv_arglist_function (&parmse, arg->expr, arg->name);
6a661315 3584 else if ((e->expr_type == EXPR_FUNCTION)
e6524a51
TB
3585 && ((e->value.function.esym
3586 && e->value.function.esym->result->attr.pointer)
3587 || (!e->value.function.esym
3588 && e->symtree->n.sym->attr.pointer))
3589 && fsym && fsym->attr.target)
6a661315
PT
3590 {
3591 gfc_conv_expr (&parmse, e);
628c189e 3592 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
6a661315 3593 }
a7c0b11d
JW
3594 else if (e->expr_type == EXPR_FUNCTION
3595 && e->symtree->n.sym->result
23878536 3596 && e->symtree->n.sym->result != e->symtree->n.sym
a7c0b11d
JW
3597 && e->symtree->n.sym->result->attr.proc_pointer)
3598 {
3599 /* Functions returning procedure pointers. */
3600 gfc_conv_expr (&parmse, e);
3601 if (fsym && fsym->attr.proc_pointer)
3602 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
3603 }
06469efd
PT
3604 else
3605 {
3606 gfc_conv_expr_reference (&parmse, e);
958dd42b 3607
94fae14b
PT
3608 /* Catch base objects that are not variables. */
3609 if (e->ts.type == BT_CLASS
3610 && e->expr_type != EXPR_VARIABLE
3611 && expr && e == expr->base_expr)
3612 base_object = build_fold_indirect_ref_loc (input_location,
3613 parmse.expr);
3614
c49ea23d
PT
3615 /* A class array element needs converting back to be a
3616 class object, if the formal argument is a class object. */
3617 if (fsym && fsym->ts.type == BT_CLASS
3618 && e->ts.type == BT_CLASS
3619 && CLASS_DATA (e)->attr.dimension)
3620 gfc_conv_class_to_class (&parmse, e, fsym->ts, false);
3621
45a69325
TB
3622 if (fsym && (fsym->ts.type == BT_DERIVED
3623 || fsym->ts.type == BT_ASSUMED)
38cbc63a
TB
3624 && e->ts.type == BT_CLASS
3625 && !CLASS_DATA (e)->attr.dimension
3626 && !CLASS_DATA (e)->attr.codimension)
3627 parmse.expr = gfc_class_data_get (parmse.expr);
3628
958dd42b
TB
3629 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
3630 allocated on entry, it must be deallocated. */
3631 if (fsym && fsym->attr.allocatable
3632 && fsym->attr.intent == INTENT_OUT)
3633 {
3634 stmtblock_t block;
3635
3636 gfc_init_block (&block);
3637 tmp = gfc_deallocate_with_status (parmse.expr, NULL_TREE,
5d81ddd0
TB
3638 NULL_TREE, NULL_TREE,
3639 NULL_TREE, true, NULL,
3640 false);
958dd42b 3641 gfc_add_expr_to_block (&block, tmp);
65a9ca82
TB
3642 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
3643 void_type_node, parmse.expr,
3644 null_pointer_node);
958dd42b
TB
3645 gfc_add_expr_to_block (&block, tmp);
3646
3647 if (fsym->attr.optional
3648 && e->expr_type == EXPR_VARIABLE
3649 && e->symtree->n.sym->attr.optional)
3650 {
65a9ca82
TB
3651 tmp = fold_build3_loc (input_location, COND_EXPR,
3652 void_type_node,
958dd42b
TB
3653 gfc_conv_expr_present (e->symtree->n.sym),
3654 gfc_finish_block (&block),
3655 build_empty_stmt (input_location));
3656 }
3657 else
3658 tmp = gfc_finish_block (&block);
3659
3660 gfc_add_expr_to_block (&se->pre, tmp);
3661 }
3662
8fb74da4
JW
3663 if (fsym && e->expr_type != EXPR_NULL
3664 && ((fsym->attr.pointer
3665 && fsym->attr.flavor != FL_PROCEDURE)
7e9c61e8
JW
3666 || (fsym->attr.proc_pointer
3667 && !(e->expr_type == EXPR_VARIABLE
2d300fac
JW
3668 && e->symtree->n.sym->attr.dummy))
3669 || (fsym->attr.proc_pointer
3670 && e->expr_type == EXPR_VARIABLE
958dd42b 3671 && gfc_is_proc_ptr_comp (e, NULL))
8c6cb782
TB
3672 || (fsym->attr.allocatable
3673 && fsym->attr.flavor != FL_PROCEDURE)))
06469efd
PT
3674 {
3675 /* Scalar pointer dummy args require an extra level of
3676 indirection. The null pointer already contains
3677 this level of indirection. */
3678 parm_kind = SCALAR_POINTER;
628c189e 3679 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
06469efd
PT
3680 }
3681 }
3682 }
c49ea23d
PT
3683 else if (e->ts.type == BT_CLASS
3684 && fsym && fsym->ts.type == BT_CLASS
3685 && CLASS_DATA (fsym)->attr.dimension)
3686 {
3687 /* Pass a class array. */
3688 gfc_init_se (&parmse, se);
3689 gfc_conv_expr_descriptor (&parmse, e, argss);
3690 /* The conversion does not repackage the reference to a class
3691 array - _data descriptor. */
3692 gfc_conv_class_to_class (&parmse, e, fsym->ts, false);
3693 }
6de9cd9a
DN
3694 else
3695 {
aa08038d
EE
3696 /* If the procedure requires an explicit interface, the actual
3697 argument is passed according to the corresponding formal
3698 argument. If the corresponding formal argument is a POINTER,
3699 ALLOCATABLE or assumed shape, we do not use g77's calling
3700 convention, and pass the address of the array descriptor
3701 instead. Otherwise we use g77's calling convention. */
f7172b55 3702 bool f;
e15e9be3
PT
3703 f = (fsym != NULL)
3704 && !(fsym->attr.pointer || fsym->attr.allocatable)
47b99694 3705 && fsym->as && fsym->as->type != AS_ASSUMED_SHAPE;
9f29c05e
PT
3706 if (comp)
3707 f = f || !comp->attr.always_explicit;
3708 else
3709 f = f || !sym->attr.always_explicit;
1855915a 3710
0b4f2770
MM
3711 /* If the argument is a function call that may not create
3712 a temporary for the result, we have to check that we
3713 can do it, i.e. that there is no alias between this
3714 argument and another one. */
3715 if (gfc_get_noncopying_intrinsic_argument (e) != NULL)
3716 {
f1f39033 3717 gfc_expr *iarg;
0b4f2770
MM
3718 sym_intent intent;
3719
3720 if (fsym != NULL)
3721 intent = fsym->attr.intent;
3722 else
3723 intent = INTENT_UNKNOWN;
3724
3725 if (gfc_check_fncall_dependency (e, intent, sym, args,
3726 NOT_ELEMENTAL))
3727 parmse.force_tmp = 1;
f1f39033
PT
3728
3729 iarg = e->value.function.actual->expr;
3730
3731 /* Temporary needed if aliasing due to host association. */
3732 if (sym->attr.contained
3733 && !sym->attr.pure
3734 && !sym->attr.implicit_pure
3735 && !sym->attr.use_assoc
3736 && iarg->expr_type == EXPR_VARIABLE
3737 && sym->ns == iarg->symtree->n.sym->ns)
3738 parmse.force_tmp = 1;
3739
3740 /* Ditto within module. */
3741 if (sym->attr.use_assoc
3742 && !sym->attr.pure
3743 && !sym->attr.implicit_pure
3744 && iarg->expr_type == EXPR_VARIABLE
3745 && sym->module == iarg->symtree->n.sym->module)
3746 parmse.force_tmp = 1;
0b4f2770
MM
3747 }
3748
e15e9be3 3749 if (e->expr_type == EXPR_VARIABLE
1d6b7f39 3750 && is_subref_array (e))
68ea355b
PT
3751 /* The actual argument is a component reference to an
3752 array of derived types. In this case, the argument
3753 is converted to a temporary, which is passed and then
3754 written back after the procedure call. */
1d6b7f39 3755 gfc_conv_subref_array_arg (&parmse, e, f,
430f2d1f
PT
3756 fsym ? fsym->attr.intent : INTENT_INOUT,
3757 fsym && fsym->attr.pointer);
c49ea23d
PT
3758 else if (gfc_is_class_array_ref (e, NULL)
3759 && fsym && fsym->ts.type == BT_DERIVED)
3760 /* The actual argument is a component reference to an
3761 array of derived types. In this case, the argument
3762 is converted to a temporary, which is passed and then
3763 written back after the procedure call.
3764 OOP-TODO: Insert code so that if the dynamic type is
3765 the same as the declared type, copy-in/copy-out does
3766 not occur. */
3767 gfc_conv_subref_array_arg (&parmse, e, f,
3768 fsym ? fsym->attr.intent : INTENT_INOUT,
3769 fsym && fsym->attr.pointer);
68ea355b 3770 else
0d52899f 3771 gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
7e279142 3772 sym->name, NULL);
42a0e16c 3773
745ff31f
TB
3774 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
3775 allocated on entry, it must be deallocated. */
3776 if (fsym && fsym->attr.allocatable
3777 && fsym->attr.intent == INTENT_OUT)
3778 {
3779 tmp = build_fold_indirect_ref_loc (input_location,
3780 parmse.expr);
5d81ddd0 3781 tmp = gfc_trans_dealloc_allocated (tmp, false);
745ff31f
TB
3782 if (fsym->attr.optional
3783 && e->expr_type == EXPR_VARIABLE
3784 && e->symtree->n.sym->attr.optional)
65a9ca82
TB
3785 tmp = fold_build3_loc (input_location, COND_EXPR,
3786 void_type_node,
745ff31f
TB
3787 gfc_conv_expr_present (e->symtree->n.sym),
3788 tmp, build_empty_stmt (input_location));
3789 gfc_add_expr_to_block (&se->pre, tmp);
3790 }
6de9cd9a
DN
3791 }
3792 }
3793
34b4bc5c
FXC
3794 /* The case with fsym->attr.optional is that of a user subroutine
3795 with an interface indicating an optional argument. When we call
3796 an intrinsic subroutine, however, fsym is NULL, but we might still
3797 have an optional argument, so we proceed to the substitution
3798 just in case. */
3799 if (e && (fsym == NULL || fsym->attr.optional))
5be38273 3800 {
34b4bc5c 3801 /* If an optional argument is itself an optional dummy argument,
745ff31f
TB
3802 check its presence and substitute a null if absent. This is
3803 only needed when passing an array to an elemental procedure
3804 as then array elements are accessed - or no NULL pointer is
3805 allowed and a "1" or "0" should be passed if not present.
64c2f8de
TB
3806 When passing a non-array-descriptor full array to a
3807 non-array-descriptor dummy, no check is needed. For
3808 array-descriptor actual to array-descriptor dummy, see
3809 PR 41911 for why a check has to be inserted.
3810 fsym == NULL is checked as intrinsics required the descriptor
3811 but do not always set fsym. */
34b4bc5c 3812 if (e->expr_type == EXPR_VARIABLE
745ff31f
TB
3813 && e->symtree->n.sym->attr.optional
3814 && ((e->rank > 0 && sym->attr.elemental)
3815 || e->representation.length || e->ts.type == BT_CHARACTER
64c2f8de 3816 || (e->rank > 0
4e141305
JD
3817 && (fsym == NULL
3818 || (fsym-> as
3819 && (fsym->as->type == AS_ASSUMED_SHAPE
3820 || fsym->as->type == AS_DEFERRED))))))
be9c3c6e
JD
3821 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
3822 e->representation.length);
34b4bc5c
FXC
3823 }
3824
3825 if (fsym && e)
3826 {
3827 /* Obtain the character length of an assumed character length
3828 length procedure from the typespec. */
3829 if (fsym->ts.type == BT_CHARACTER
3830 && parmse.string_length == NULL_TREE
3831 && e->ts.type == BT_PROCEDURE
3832 && e->symtree->n.sym->ts.type == BT_CHARACTER
bc21d315
JW
3833 && e->symtree->n.sym->ts.u.cl->length != NULL
3834 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
5be38273 3835 {
bc21d315
JW
3836 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
3837 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
5be38273 3838 }
5be38273 3839 }
0348d6fd 3840
2c80cb0e 3841 if (fsym && need_interface_mapping && e)
0a164a3c 3842 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
34b4bc5c 3843
6de9cd9a 3844 gfc_add_block_to_block (&se->pre, &parmse.pre);
f5f701ad 3845 gfc_add_block_to_block (&post, &parmse.post);
6de9cd9a 3846
5046aff5 3847 /* Allocated allocatable components of derived types must be
2c69d527
PT
3848 deallocated for non-variable scalars. Non-variable arrays are
3849 dealt with in trans-array.c(gfc_conv_array_parameter). */
bfa204b8 3850 if (e && (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS)
bc21d315 3851 && e->ts.u.derived->attr.alloc_comp
47f71eb9 3852 && !(e->symtree && e->symtree->n.sym->attr.pointer)
2c69d527 3853 && (e->expr_type != EXPR_VARIABLE && !e->rank))
5046aff5
PT
3854 {
3855 int parm_rank;
db3927fb
AH
3856 tmp = build_fold_indirect_ref_loc (input_location,
3857 parmse.expr);
5046aff5
PT
3858 parm_rank = e->rank;
3859 switch (parm_kind)
3860 {
3861 case (ELEMENTAL):
3862 case (SCALAR):
3863 parm_rank = 0;
3864 break;
3865
3866 case (SCALAR_POINTER):
db3927fb
AH
3867 tmp = build_fold_indirect_ref_loc (input_location,
3868 tmp);
5046aff5 3869 break;
5046aff5
PT
3870 }
3871
7d44f531
PT
3872 if (e->expr_type == EXPR_OP
3873 && e->value.op.op == INTRINSIC_PARENTHESES
3874 && e->value.op.op1->expr_type == EXPR_VARIABLE)
3875 {
3876 tree local_tmp;
3877 local_tmp = gfc_evaluate_now (tmp, &se->pre);
bc21d315 3878 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
7d44f531
PT
3879 gfc_add_expr_to_block (&se->post, local_tmp);
3880 }
3881
bfa204b8
PT
3882 if (e->ts.type == BT_DERIVED && fsym && fsym->ts.type == BT_CLASS)
3883 {
3884 /* The derived type is passed to gfc_deallocate_alloc_comp.
3885 Therefore, class actuals can handled correctly but derived
3886 types passed to class formals need the _data component. */
3887 tmp = gfc_class_data_get (tmp);
3888 if (!CLASS_DATA (fsym)->attr.dimension)
3889 tmp = build_fold_indirect_ref_loc (input_location, tmp);
3890 }
3891
bc21d315 3892 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
7d44f531 3893
2c69d527 3894 gfc_add_expr_to_block (&se->post, tmp);
5046aff5
PT
3895 }
3896
20460eb9
TB
3897 /* Add argument checking of passing an unallocated/NULL actual to
3898 a nonallocatable/nonpointer dummy. */
3899
4b41f35e 3900 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
20460eb9 3901 {
48dbbcd6 3902 symbol_attribute attr;
20460eb9
TB
3903 char *msg;
3904 tree cond;
3905
48dbbcd6
JW
3906 if (e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
3907 attr = gfc_expr_attr (e);
20460eb9
TB
3908 else
3909 goto end_pointer_check;
3910
8d231ff2
TB
3911 /* In Fortran 2008 it's allowed to pass a NULL pointer/nonallocated
3912 allocatable to an optional dummy, cf. 12.5.2.12. */
3913 if (fsym != NULL && fsym->attr.optional && !attr.proc_pointer
3914 && (gfc_option.allow_std & GFC_STD_F2008) != 0)
3915 goto end_pointer_check;
3916
48dbbcd6 3917 if (attr.optional)
4b41f35e
TB
3918 {
3919 /* If the actual argument is an optional pointer/allocatable and
3920 the formal argument takes an nonpointer optional value,
3921 it is invalid to pass a non-present argument on, even
3922 though there is no technical reason for this in gfortran.
3923 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
14c2101d 3924 tree present, null_ptr, type;
4b41f35e 3925
48dbbcd6 3926 if (attr.allocatable
4b41f35e
TB
3927 && (fsym == NULL || !fsym->attr.allocatable))
3928 asprintf (&msg, "Allocatable actual argument '%s' is not "
3929 "allocated or not present", e->symtree->n.sym->name);
48dbbcd6 3930 else if (attr.pointer
4b41f35e
TB
3931 && (fsym == NULL || !fsym->attr.pointer))
3932 asprintf (&msg, "Pointer actual argument '%s' is not "
3933 "associated or not present",
3934 e->symtree->n.sym->name);
48dbbcd6 3935 else if (attr.proc_pointer
4b41f35e
TB
3936 && (fsym == NULL || !fsym->attr.proc_pointer))
3937 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3938 "associated or not present",
3939 e->symtree->n.sym->name);
3940 else
3941 goto end_pointer_check;
3942
3943 present = gfc_conv_expr_present (e->symtree->n.sym);
3944 type = TREE_TYPE (present);
65a9ca82
TB
3945 present = fold_build2_loc (input_location, EQ_EXPR,
3946 boolean_type_node, present,
3947 fold_convert (type,
3948 null_pointer_node));
4b41f35e 3949 type = TREE_TYPE (parmse.expr);
65a9ca82
TB
3950 null_ptr = fold_build2_loc (input_location, EQ_EXPR,
3951 boolean_type_node, parmse.expr,
3952 fold_convert (type,
3953 null_pointer_node));
3954 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
3955 boolean_type_node, present, null_ptr);
4b41f35e
TB
3956 }
3957 else
3958 {
48dbbcd6 3959 if (attr.allocatable
4b41f35e
TB
3960 && (fsym == NULL || !fsym->attr.allocatable))
3961 asprintf (&msg, "Allocatable actual argument '%s' is not "
3962 "allocated", e->symtree->n.sym->name);
48dbbcd6 3963 else if (attr.pointer
4b41f35e
TB
3964 && (fsym == NULL || !fsym->attr.pointer))
3965 asprintf (&msg, "Pointer actual argument '%s' is not "
3966 "associated", e->symtree->n.sym->name);
48dbbcd6 3967 else if (attr.proc_pointer
4b41f35e
TB
3968 && (fsym == NULL || !fsym->attr.proc_pointer))
3969 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3970 "associated", e->symtree->n.sym->name);
3971 else
3972 goto end_pointer_check;
3973
85ff2938
TB
3974 tmp = parmse.expr;
3975
3976 /* If the argument is passed by value, we need to strip the
3977 INDIRECT_REF. */
3978 if (!POINTER_TYPE_P (TREE_TYPE (parmse.expr)))
3979 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
4b41f35e 3980
65a9ca82 3981 cond = fold_build2_loc (input_location, EQ_EXPR,
85ff2938
TB
3982 boolean_type_node, tmp,
3983 fold_convert (TREE_TYPE (tmp),
65a9ca82 3984 null_pointer_node));
4b41f35e 3985 }
20460eb9
TB
3986
3987 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
3988 msg);
cede9502 3989 free (msg);
20460eb9
TB
3990 }
3991 end_pointer_check:
3992
8d51f26f
PT
3993 /* Deferred length dummies pass the character length by reference
3994 so that the value can be returned. */
3995 if (parmse.string_length && fsym && fsym->ts.deferred)
3996 {
3997 tmp = parmse.string_length;
3998 if (TREE_CODE (tmp) != VAR_DECL)
3999 tmp = gfc_evaluate_now (parmse.string_length, &se->pre);
4000 parmse.string_length = gfc_build_addr_expr (NULL_TREE, tmp);
4001 }
20460eb9 4002
e7dc5b4f 4003 /* Character strings are passed as two parameters, a length and a
7861a5ce
TB
4004 pointer - except for Bind(c) which only passes the pointer. */
4005 if (parmse.string_length != NULL_TREE && !sym->attr.is_bind_c)
989ea525 4006 VEC_safe_push (tree, gc, stringargs, parmse.string_length);
6de9cd9a 4007
aa13dc3c
TB
4008 /* For descriptorless coarrays and assumed-shape coarray dummies, we
4009 pass the token and the offset as additional arguments. */
0c53708e
TB
4010 if (fsym && fsym->attr.codimension
4011 && gfc_option.coarray == GFC_FCOARRAY_LIB
aa13dc3c 4012 && !fsym->attr.allocatable
af232d48 4013 && e == NULL)
0c53708e
TB
4014 {
4015 /* Token and offset. */
4016 VEC_safe_push (tree, gc, stringargs, null_pointer_node);
4017 VEC_safe_push (tree, gc, stringargs,
4018 build_int_cst (gfc_array_index_type, 0));
af232d48 4019 gcc_assert (fsym->attr.optional);
0c53708e
TB
4020 }
4021 else if (fsym && fsym->attr.codimension
aa13dc3c 4022 && !fsym->attr.allocatable
0c53708e
TB
4023 && gfc_option.coarray == GFC_FCOARRAY_LIB)
4024 {
4025 tree caf_decl, caf_type;
af232d48 4026 tree offset, tmp2;
0c53708e 4027
af232d48 4028 caf_decl = get_tree_for_caf_expr (e);
0c53708e
TB
4029 caf_type = TREE_TYPE (caf_decl);
4030
aa13dc3c
TB
4031 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
4032 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
af232d48 4033 tmp = gfc_conv_descriptor_token (caf_decl);
aa13dc3c
TB
4034 else if (DECL_LANG_SPECIFIC (caf_decl)
4035 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
4036 tmp = GFC_DECL_TOKEN (caf_decl);
af232d48
TB
4037 else
4038 {
4039 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
4040 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
4041 tmp = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
4042 }
0c53708e 4043
af232d48 4044 VEC_safe_push (tree, gc, stringargs, tmp);
0c53708e 4045
aa13dc3c
TB
4046 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
4047 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
af232d48 4048 offset = build_int_cst (gfc_array_index_type, 0);
aa13dc3c
TB
4049 else if (DECL_LANG_SPECIFIC (caf_decl)
4050 && GFC_DECL_CAF_OFFSET (caf_decl) != NULL_TREE)
4051 offset = GFC_DECL_CAF_OFFSET (caf_decl);
af232d48 4052 else if (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) != NULL_TREE)
0c53708e
TB
4053 offset = GFC_TYPE_ARRAY_CAF_OFFSET (caf_type);
4054 else
4055 offset = build_int_cst (gfc_array_index_type, 0);
4056
af232d48
TB
4057 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
4058 tmp = gfc_conv_descriptor_data_get (caf_decl);
4059 else
4060 {
4061 gcc_assert (POINTER_TYPE_P (caf_type));
4062 tmp = caf_decl;
4063 }
4064
aa13dc3c
TB
4065 if (fsym->as->type == AS_ASSUMED_SHAPE)
4066 {
4067 gcc_assert (POINTER_TYPE_P (TREE_TYPE (parmse.expr)));
4068 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE
4069 (TREE_TYPE (parmse.expr))));
4070 tmp2 = build_fold_indirect_ref_loc (input_location, parmse.expr);
4071 tmp2 = gfc_conv_descriptor_data_get (tmp2);
4072 }
4073 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse.expr)))
af232d48
TB
4074 tmp2 = gfc_conv_descriptor_data_get (parmse.expr);
4075 else
4076 {
4077 gcc_assert (POINTER_TYPE_P (TREE_TYPE (parmse.expr)));
4078 tmp2 = parmse.expr;
4079 }
0c53708e
TB
4080
4081 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4082 gfc_array_index_type,
af232d48
TB
4083 fold_convert (gfc_array_index_type, tmp2),
4084 fold_convert (gfc_array_index_type, tmp));
0c53708e
TB
4085 offset = fold_build2_loc (input_location, PLUS_EXPR,
4086 gfc_array_index_type, offset, tmp);
4087
4088 VEC_safe_push (tree, gc, stringargs, offset);
4089 }
4090
989ea525 4091 VEC_safe_push (tree, gc, arglist, parmse.expr);
6de9cd9a 4092 }
0348d6fd
RS
4093 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
4094
50dbf0b4
JW
4095 if (comp)
4096 ts = comp->ts;
4097 else
4098 ts = sym->ts;
4099
3a73a540
TB
4100 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
4101 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
4102 else if (ts.type == BT_CHARACTER)
0348d6fd 4103 {
50dbf0b4 4104 if (ts.u.cl->length == NULL)
20236f90
PT
4105 {
4106 /* Assumed character length results are not allowed by 5.1.1.5 of the
4107 standard and are trapped in resolve.c; except in the case of SPREAD
7f39b34c
PT
4108 (and other intrinsics?) and dummy functions. In the case of SPREAD,
4109 we take the character length of the first argument for the result.
4110 For dummies, we have to look through the formal argument list for
4111 this function and use the character length found there.*/
8d51f26f
PT
4112 if (ts.deferred && (sym->attr.allocatable || sym->attr.pointer))
4113 cl.backend_decl = gfc_create_var (gfc_charlen_type_node, "slen");
4114 else if (!sym->attr.dummy)
989ea525 4115 cl.backend_decl = VEC_index (tree, stringargs, 0);
7f39b34c
PT
4116 else
4117 {
4118 formal = sym->ns->proc_name->formal;
4119 for (; formal; formal = formal->next)
4120 if (strcmp (formal->sym->name, sym->name) == 0)
bc21d315 4121 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
7f39b34c
PT
4122 }
4123 }
958dd42b 4124 else
7f39b34c 4125 {
886c8de1
FXC
4126 tree tmp;
4127
20236f90
PT
4128 /* Calculate the length of the returned string. */
4129 gfc_init_se (&parmse, NULL);
4130 if (need_interface_mapping)
50dbf0b4 4131 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
20236f90 4132 else
50dbf0b4 4133 gfc_conv_expr (&parmse, ts.u.cl->length);
20236f90
PT
4134 gfc_add_block_to_block (&se->pre, &parmse.pre);
4135 gfc_add_block_to_block (&se->post, &parmse.post);
886c8de1
FXC
4136
4137 tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
65a9ca82
TB
4138 tmp = fold_build2_loc (input_location, MAX_EXPR,
4139 gfc_charlen_type_node, tmp,
4140 build_int_cst (gfc_charlen_type_node, 0));
886c8de1 4141 cl.backend_decl = tmp;
20236f90 4142 }
0348d6fd
RS
4143
4144 /* Set up a charlen structure for it. */
4145 cl.next = NULL;
4146 cl.length = NULL;
bc21d315 4147 ts.u.cl = &cl;
0348d6fd
RS
4148
4149 len = cl.backend_decl;
4150 }
0348d6fd 4151
50dbf0b4 4152 byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
c74b74a8 4153 || (!comp && gfc_return_by_reference (sym));
0348d6fd
RS
4154 if (byref)
4155 {
4156 if (se->direct_byref)
fc2d8680 4157 {
df2fba9e 4158 /* Sometimes, too much indirection can be applied; e.g. for
fc2d8680
PT
4159 function_result = array_valued_recursive_function. */
4160 if (TREE_TYPE (TREE_TYPE (se->expr))
4161 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
4162 && GFC_DESCRIPTOR_TYPE_P
4163 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
db3927fb
AH
4164 se->expr = build_fold_indirect_ref_loc (input_location,
4165 se->expr);
fc2d8680 4166
597553ab
PT
4167 /* If the lhs of an assignment x = f(..) is allocatable and
4168 f2003 is allowed, we must do the automatic reallocation.
f1f39033 4169 TODO - deal with intrinsics, without using a temporary. */
597553ab
PT
4170 if (gfc_option.flag_realloc_lhs
4171 && se->ss && se->ss->loop_chain
4172 && se->ss->loop_chain->is_alloc_lhs
4173 && !expr->value.function.isym
4174 && sym->result->as != NULL)
4175 {
4176 /* Evaluate the bounds of the result, if known. */
4177 gfc_set_loop_bounds_from_array_spec (&mapping, se,
4178 sym->result->as);
4179
4180 /* Perform the automatic reallocation. */
4181 tmp = gfc_alloc_allocatable_for_assignment (se->loop,
4182 expr, NULL);
4183 gfc_add_expr_to_block (&se->pre, tmp);
4184
4185 /* Pass the temporary as the first argument. */
4186 result = info->descriptor;
4187 }
4188 else
4189 result = build_fold_indirect_ref_loc (input_location,
4190 se->expr);
989ea525 4191 VEC_safe_push (tree, gc, retargs, se->expr);
fc2d8680 4192 }
f64edc8b
JW
4193 else if (comp && comp->attr.dimension)
4194 {
4195 gcc_assert (se->loop && info);
4196
4197 /* Set the type of the array. */
4198 tmp = gfc_typenode_for_spec (&comp->ts);
cb4b9eae 4199 gcc_assert (se->ss->dimen == se->loop->dimen);
f64edc8b
JW
4200
4201 /* Evaluate the bounds of the result, if known. */
4202 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
4203
597553ab
PT
4204 /* If the lhs of an assignment x = f(..) is allocatable and
4205 f2003 is allowed, we must not generate the function call
4206 here but should just send back the results of the mapping.
4207 This is signalled by the function ss being flagged. */
4208 if (gfc_option.flag_realloc_lhs
4209 && se->ss && se->ss->is_alloc_lhs)
4210 {
4211 gfc_free_interface_mapping (&mapping);
4212 return has_alternate_specifier;
4213 }
4214
f64edc8b
JW
4215 /* Create a temporary to store the result. In case the function
4216 returns a pointer, the temporary will be a shallow copy and
4217 mustn't be deallocated. */
4218 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
41645793 4219 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
f44d2277 4220 tmp, NULL_TREE, false,
f98cfd3c
MM
4221 !comp->attr.pointer, callee_alloc,
4222 &se->ss->info->expr->where);
f64edc8b
JW
4223
4224 /* Pass the temporary as the first argument. */
40c32948
PT
4225 result = info->descriptor;
4226 tmp = gfc_build_addr_expr (NULL_TREE, result);
989ea525 4227 VEC_safe_push (tree, gc, retargs, tmp);
f64edc8b 4228 }
50dbf0b4 4229 else if (!comp && sym->result->attr.dimension)
0348d6fd
RS
4230 {
4231 gcc_assert (se->loop && info);
4232
4233 /* Set the type of the array. */
4234 tmp = gfc_typenode_for_spec (&ts);
cb4b9eae 4235 gcc_assert (se->ss->dimen == se->loop->dimen);
0348d6fd 4236
62ab4a54
RS
4237 /* Evaluate the bounds of the result, if known. */
4238 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
4239
597553ab
PT
4240 /* If the lhs of an assignment x = f(..) is allocatable and
4241 f2003 is allowed, we must not generate the function call
4242 here but should just send back the results of the mapping.
4243 This is signalled by the function ss being flagged. */
4244 if (gfc_option.flag_realloc_lhs
4245 && se->ss && se->ss->is_alloc_lhs)
4246 {
4247 gfc_free_interface_mapping (&mapping);
4248 return has_alternate_specifier;
4249 }
4250
8e119f1b
EE
4251 /* Create a temporary to store the result. In case the function
4252 returns a pointer, the temporary will be a shallow copy and
4253 mustn't be deallocated. */
4254 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
41645793 4255 gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
f44d2277 4256 tmp, NULL_TREE, false,
f98cfd3c
MM
4257 !sym->attr.pointer, callee_alloc,
4258 &se->ss->info->expr->where);
0348d6fd 4259
0348d6fd 4260 /* Pass the temporary as the first argument. */
40c32948
PT
4261 result = info->descriptor;
4262 tmp = gfc_build_addr_expr (NULL_TREE, result);
989ea525 4263 VEC_safe_push (tree, gc, retargs, tmp);
0348d6fd
RS
4264 }
4265 else if (ts.type == BT_CHARACTER)
4266 {
4267 /* Pass the string length. */
bc21d315 4268 type = gfc_get_character_type (ts.kind, ts.u.cl);
0348d6fd
RS
4269 type = build_pointer_type (type);
4270
4271 /* Return an address to a char[0:len-1]* temporary for
4272 character pointers. */
50dbf0b4
JW
4273 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
4274 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
0348d6fd 4275 {
5cc5439e 4276 var = gfc_create_var (type, "pstr");
0348d6fd 4277
11492349
TB
4278 if ((!comp && sym->attr.allocatable)
4279 || (comp && comp->attr.allocatable))
4280 gfc_add_modify (&se->pre, var,
4281 fold_convert (TREE_TYPE (var),
4282 null_pointer_node));
4283
0348d6fd 4284 /* Provide an address expression for the function arguments. */
628c189e 4285 var = gfc_build_addr_expr (NULL_TREE, var);
0348d6fd
RS
4286 }
4287 else
4288 var = gfc_conv_string_tmp (se, type, len);
4289
989ea525 4290 VEC_safe_push (tree, gc, retargs, var);
0348d6fd
RS
4291 }
4292 else
4293 {
4294 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
4295
4296 type = gfc_get_complex_type (ts.kind);
628c189e 4297 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
989ea525 4298 VEC_safe_push (tree, gc, retargs, var);
0348d6fd
RS
4299 }
4300
8d51f26f
PT
4301 if (ts.type == BT_CHARACTER && ts.deferred
4302 && (sym->attr.allocatable || sym->attr.pointer))
4303 {
4304 tmp = len;
4305 if (TREE_CODE (tmp) != VAR_DECL)
4306 tmp = gfc_evaluate_now (len, &se->pre);
4307 len = gfc_build_addr_expr (NULL_TREE, tmp);
4308 }
4309
0348d6fd
RS
4310 /* Add the string length to the argument list. */
4311 if (ts.type == BT_CHARACTER)
989ea525 4312 VEC_safe_push (tree, gc, retargs, len);
0348d6fd 4313 }
62ab4a54 4314 gfc_free_interface_mapping (&mapping);
0348d6fd 4315
989ea525
NF
4316 /* We need to glom RETARGS + ARGLIST + STRINGARGS + APPEND_ARGS. */
4317 arglen = (VEC_length (tree, arglist)
4318 + VEC_length (tree, stringargs) + VEC_length (tree, append_args));
4319 VEC_reserve_exact (tree, gc, retargs, arglen);
4320
0348d6fd 4321 /* Add the return arguments. */
989ea525 4322 VEC_splice (tree, retargs, arglist);
6de9cd9a
DN
4323
4324 /* Add the hidden string length parameters to the arguments. */
989ea525 4325 VEC_splice (tree, retargs, stringargs);
6de9cd9a 4326
5a0aad31
FXC
4327 /* We may want to append extra arguments here. This is used e.g. for
4328 calls to libgfortran_matmul_??, which need extra information. */
989ea525
NF
4329 if (!VEC_empty (tree, append_args))
4330 VEC_splice (tree, retargs, append_args);
4331 arglist = retargs;
5a0aad31 4332
6de9cd9a 4333 /* Generate the actual call. */
94fae14b
PT
4334 if (base_object == NULL_TREE)
4335 conv_function_val (se, sym, expr);
4336 else
4337 conv_base_obj_fcn_val (se, base_object, expr);
276ca25d 4338
6de9cd9a 4339 /* If there are alternate return labels, function type should be
dda895f9 4340 integer. Can't modify the type in place though, since it can be shared
276ca25d 4341 with other functions. For dummy arguments, the typing is done to
dd5a833e 4342 this result, even if it has to be repeated for each call. */
dda895f9
JJ
4343 if (has_alternate_specifier
4344 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
4345 {
276ca25d
PT
4346 if (!sym->attr.dummy)
4347 {
4348 TREE_TYPE (sym->backend_decl)
4349 = build_function_type (integer_type_node,
4350 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
628c189e 4351 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
276ca25d
PT
4352 }
4353 else
4354 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
dda895f9 4355 }
6de9cd9a
DN
4356
4357 fntype = TREE_TYPE (TREE_TYPE (se->expr));
989ea525 4358 se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
6de9cd9a 4359
6d1c50cc
TS
4360 /* If we have a pointer function, but we don't want a pointer, e.g.
4361 something like
4362 x = f()
4363 where f is pointer valued, we have to dereference the result. */
5b130807 4364 if (!se->want_pointer && !byref
463ec822
JW
4365 && ((!comp && (sym->attr.pointer || sym->attr.allocatable))
4366 || (comp && (comp->attr.pointer || comp->attr.allocatable))))
4367 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
6d1c50cc 4368
973ff4c0
TS
4369 /* f2c calling conventions require a scalar default real function to
4370 return a double precision result. Convert this back to default
4371 real. We only care about the cases that can happen in Fortran 77.
4372 */
4373 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
4374 && sym->ts.kind == gfc_default_real_kind
4375 && !sym->attr.always_explicit)
4376 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
4377
f8d0aee5
TS
4378 /* A pure function may still have side-effects - it may modify its
4379 parameters. */
6de9cd9a
DN
4380 TREE_SIDE_EFFECTS (se->expr) = 1;
4381#if 0
4382 if (!sym->attr.pure)
4383 TREE_SIDE_EFFECTS (se->expr) = 1;
4384#endif
4385
fc90a8f2 4386 if (byref)
6de9cd9a 4387 {
fc90a8f2 4388 /* Add the function call to the pre chain. There is no expression. */
6de9cd9a 4389 gfc_add_expr_to_block (&se->pre, se->expr);
fc90a8f2 4390 se->expr = NULL_TREE;
6de9cd9a 4391
fc90a8f2 4392 if (!se->direct_byref)
6de9cd9a 4393 {
c58bb30d 4394 if ((sym->attr.dimension && !comp) || (comp && comp->attr.dimension))
6de9cd9a 4395 {
d3d3011f 4396 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
fc90a8f2
PB
4397 {
4398 /* Check the data pointer hasn't been modified. This would
4399 happen in a function returning a pointer. */
4c73896d 4400 tmp = gfc_conv_descriptor_data_get (info->descriptor);
65a9ca82
TB
4401 tmp = fold_build2_loc (input_location, NE_EXPR,
4402 boolean_type_node,
4403 tmp, info->data);
0d52899f
TB
4404 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
4405 gfc_msg_fault);
fc90a8f2
PB
4406 }
4407 se->expr = info->descriptor;
72caba17
PT
4408 /* Bundle in the string length. */
4409 se->string_length = len;
6de9cd9a 4410 }
50dbf0b4 4411 else if (ts.type == BT_CHARACTER)
ec09945c 4412 {
72caba17 4413 /* Dereference for character pointer results. */
50dbf0b4
JW
4414 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
4415 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
4416 se->expr = build_fold_indirect_ref_loc (input_location, var);
ec09945c 4417 else
72caba17
PT
4418 se->expr = var;
4419
8d51f26f
PT
4420 if (!ts.deferred)
4421 se->string_length = len;
4422 else if (sym->attr.allocatable || sym->attr.pointer)
4423 se->string_length = cl.backend_decl;
fc90a8f2
PB
4424 }
4425 else
973ff4c0 4426 {
50dbf0b4
JW
4427 gcc_assert (ts.type == BT_COMPLEX && gfc_option.flag_f2c);
4428 se->expr = build_fold_indirect_ref_loc (input_location, var);
973ff4c0 4429 }
6de9cd9a 4430 }
6de9cd9a 4431 }
dda895f9 4432
f5f701ad
PT
4433 /* Follow the function call with the argument post block. */
4434 if (byref)
40c32948
PT
4435 {
4436 gfc_add_block_to_block (&se->pre, &post);
4437
4438 /* Transformational functions of derived types with allocatable
4439 components must have the result allocatable components copied. */
4440 arg = expr->value.function.actual;
4441 if (result && arg && expr->rank
4442 && expr->value.function.isym
4443 && expr->value.function.isym->transformational
4444 && arg->expr->ts.type == BT_DERIVED
4445 && arg->expr->ts.u.derived->attr.alloc_comp)
4446 {
4447 tree tmp2;
4448 /* Copy the allocatable components. We have to use a
4449 temporary here to prevent source allocatable components
4450 from being corrupted. */
4451 tmp2 = gfc_evaluate_now (result, &se->pre);
4452 tmp = gfc_copy_alloc_comp (arg->expr->ts.u.derived,
4453 result, tmp2, expr->rank);
4454 gfc_add_expr_to_block (&se->pre, tmp);
4455 tmp = gfc_copy_allocatable_data (result, tmp2, TREE_TYPE(tmp2),
4456 expr->rank);
4457 gfc_add_expr_to_block (&se->pre, tmp);
4458
4459 /* Finally free the temporary's data field. */
4460 tmp = gfc_conv_descriptor_data_get (tmp2);
5d81ddd0
TB
4461 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
4462 NULL_TREE, NULL_TREE, true,
4463 NULL, false);
40c32948
PT
4464 gfc_add_expr_to_block (&se->pre, tmp);
4465 }
4466 }
f5f701ad
PT
4467 else
4468 gfc_add_block_to_block (&se->post, &post);
4469
dda895f9 4470 return has_alternate_specifier;
6de9cd9a
DN
4471}
4472
4473
d393bbd7
FXC
4474/* Fill a character string with spaces. */
4475
4476static tree
4477fill_with_spaces (tree start, tree type, tree size)
4478{
4479 stmtblock_t block, loop;
4480 tree i, el, exit_label, cond, tmp;
4481
4482 /* For a simple char type, we can call memset(). */
4483 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
db3927fb 4484 return build_call_expr_loc (input_location,
e79983f4
MM
4485 builtin_decl_explicit (BUILT_IN_MEMSET),
4486 3, start,
d393bbd7
FXC
4487 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
4488 lang_hooks.to_target_charset (' ')),
4489 size);
4490
4491 /* Otherwise, we use a loop:
4492 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
4493 *el = (type) ' ';
4494 */
4495
4496 /* Initialize variables. */
4497 gfc_init_block (&block);
4498 i = gfc_create_var (sizetype, "i");
726a989a 4499 gfc_add_modify (&block, i, fold_convert (sizetype, size));
d393bbd7 4500 el = gfc_create_var (build_pointer_type (type), "el");
726a989a 4501 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
d393bbd7
FXC
4502 exit_label = gfc_build_label_decl (NULL_TREE);
4503 TREE_USED (exit_label) = 1;
4504
4505
4506 /* Loop body. */
4507 gfc_init_block (&loop);
4508
4509 /* Exit condition. */
65a9ca82 4510 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, i,
e8160c9a 4511 build_zero_cst (sizetype));
d393bbd7 4512 tmp = build1_v (GOTO_EXPR, exit_label);
65a9ca82
TB
4513 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
4514 build_empty_stmt (input_location));
d393bbd7
FXC
4515 gfc_add_expr_to_block (&loop, tmp);
4516
4517 /* Assignment. */
65a9ca82
TB
4518 gfc_add_modify (&loop,
4519 fold_build1_loc (input_location, INDIRECT_REF, type, el),
4520 build_int_cst (type, lang_hooks.to_target_charset (' ')));
d393bbd7
FXC
4521
4522 /* Increment loop variables. */
65a9ca82
TB
4523 gfc_add_modify (&loop, i,
4524 fold_build2_loc (input_location, MINUS_EXPR, sizetype, i,
4525 TYPE_SIZE_UNIT (type)));
4526 gfc_add_modify (&loop, el,
5d49b6a7
RG
4527 fold_build_pointer_plus_loc (input_location,
4528 el, TYPE_SIZE_UNIT (type)));
d393bbd7
FXC
4529
4530 /* Making the loop... actually loop! */
4531 tmp = gfc_finish_block (&loop);
4532 tmp = build1_v (LOOP_EXPR, tmp);
4533 gfc_add_expr_to_block (&block, tmp);
4534
4535 /* The exit label. */
4536 tmp = build1_v (LABEL_EXPR, exit_label);
4537 gfc_add_expr_to_block (&block, tmp);
4538
4539
4540 return gfc_finish_block (&block);
4541}
4542
4543
7b5b57b7
PB
4544/* Generate code to copy a string. */
4545
32be9f94 4546void
5cd8e123 4547gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
d393bbd7 4548 int dkind, tree slength, tree src, int skind)
7b5b57b7 4549{
5cd8e123 4550 tree tmp, dlen, slen;
0a821a92
FW
4551 tree dsc;
4552 tree ssc;
549033f3 4553 tree cond;
b3eb1e0e
FXC
4554 tree cond2;
4555 tree tmp2;
4556 tree tmp3;
4557 tree tmp4;
d393bbd7 4558 tree chartype;
b3eb1e0e 4559 stmtblock_t tempblock;
0a821a92 4560
d393bbd7
FXC
4561 gcc_assert (dkind == skind);
4562
06a54338
TB
4563 if (slength != NULL_TREE)
4564 {
4565 slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
d2886bc7 4566 ssc = gfc_string_to_single_character (slen, src, skind);
06a54338
TB
4567 }
4568 else
4569 {
4570 slen = build_int_cst (size_type_node, 1);
4571 ssc = src;
4572 }
4573
4574 if (dlength != NULL_TREE)
4575 {
4576 dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
d2886bc7 4577 dsc = gfc_string_to_single_character (dlen, dest, dkind);
06a54338
TB
4578 }
4579 else
4580 {
4581 dlen = build_int_cst (size_type_node, 1);
4582 dsc = dest;
4583 }
4584
067feae3
PT
4585 /* Assign directly if the types are compatible. */
4586 if (dsc != NULL_TREE && ssc != NULL_TREE
d393bbd7 4587 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
0a821a92 4588 {
726a989a 4589 gfc_add_modify (block, dsc, ssc);
0a821a92
FW
4590 return;
4591 }
7b5b57b7 4592
b3eb1e0e 4593 /* Do nothing if the destination length is zero. */
65a9ca82
TB
4594 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, dlen,
4595 build_int_cst (size_type_node, 0));
549033f3 4596
b3eb1e0e
FXC
4597 /* The following code was previously in _gfortran_copy_string:
4598
4599 // The two strings may overlap so we use memmove.
4600 void
4601 copy_string (GFC_INTEGER_4 destlen, char * dest,
4602 GFC_INTEGER_4 srclen, const char * src)
4603 {
4604 if (srclen >= destlen)
4605 {
4606 // This will truncate if too long.
4607 memmove (dest, src, destlen);
4608 }
4609 else
4610 {
4611 memmove (dest, src, srclen);
4612 // Pad with spaces.
4613 memset (&dest[srclen], ' ', destlen - srclen);
4614 }
4615 }
4616
4617 We're now doing it here for better optimization, but the logic
4618 is the same. */
36cefd39 4619
d393bbd7
FXC
4620 /* For non-default character kinds, we have to multiply the string
4621 length by the base type size. */
4622 chartype = gfc_get_char_type (dkind);
65a9ca82
TB
4623 slen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
4624 fold_convert (size_type_node, slen),
4625 fold_convert (size_type_node,
4626 TYPE_SIZE_UNIT (chartype)));
4627 dlen = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
4628 fold_convert (size_type_node, dlen),
4629 fold_convert (size_type_node,
4630 TYPE_SIZE_UNIT (chartype)));
d393bbd7 4631
9a14c44d 4632 if (dlength && POINTER_TYPE_P (TREE_TYPE (dest)))
06a54338
TB
4633 dest = fold_convert (pvoid_type_node, dest);
4634 else
4635 dest = gfc_build_addr_expr (pvoid_type_node, dest);
4636
9a14c44d 4637 if (slength && POINTER_TYPE_P (TREE_TYPE (src)))
06a54338
TB
4638 src = fold_convert (pvoid_type_node, src);
4639 else
4640 src = gfc_build_addr_expr (pvoid_type_node, src);
36cefd39 4641
b3eb1e0e 4642 /* Truncate string if source is too long. */
65a9ca82
TB
4643 cond2 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, slen,
4644 dlen);
db3927fb 4645 tmp2 = build_call_expr_loc (input_location,
e79983f4
MM
4646 builtin_decl_explicit (BUILT_IN_MEMMOVE),
4647 3, dest, src, dlen);
b3eb1e0e
FXC
4648
4649 /* Else copy and pad with spaces. */
db3927fb 4650 tmp3 = build_call_expr_loc (input_location,
e79983f4
MM
4651 builtin_decl_explicit (BUILT_IN_MEMMOVE),
4652 3, dest, src, slen);
b3eb1e0e 4653
5d49b6a7 4654 tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
d393bbd7 4655 tmp4 = fill_with_spaces (tmp4, chartype,
65a9ca82
TB
4656 fold_build2_loc (input_location, MINUS_EXPR,
4657 TREE_TYPE(dlen), dlen, slen));
b3eb1e0e
FXC
4658
4659 gfc_init_block (&tempblock);
4660 gfc_add_expr_to_block (&tempblock, tmp3);
4661 gfc_add_expr_to_block (&tempblock, tmp4);
4662 tmp3 = gfc_finish_block (&tempblock);
4663
4664 /* The whole copy_string function is there. */
65a9ca82
TB
4665 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
4666 tmp2, tmp3);
4667 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
4668 build_empty_stmt (input_location));
7b5b57b7
PB
4669 gfc_add_expr_to_block (block, tmp);
4670}
4671
4672
6de9cd9a
DN
4673/* Translate a statement function.
4674 The value of a statement function reference is obtained by evaluating the
4675 expression using the values of the actual arguments for the values of the
4676 corresponding dummy arguments. */
4677
4678static void
4679gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
4680{
4681 gfc_symbol *sym;
4682 gfc_symbol *fsym;
4683 gfc_formal_arglist *fargs;
4684 gfc_actual_arglist *args;
4685 gfc_se lse;
4686 gfc_se rse;
7b5b57b7
PB
4687 gfc_saved_var *saved_vars;
4688 tree *temp_vars;
4689 tree type;
4690 tree tmp;
4691 int n;
6de9cd9a
DN
4692
4693 sym = expr->symtree->n.sym;
4694 args = expr->value.function.actual;
4695 gfc_init_se (&lse, NULL);
4696 gfc_init_se (&rse, NULL);
4697
7b5b57b7 4698 n = 0;
6de9cd9a 4699 for (fargs = sym->formal; fargs; fargs = fargs->next)
7b5b57b7 4700 n++;
93acb62c
JB
4701 saved_vars = XCNEWVEC (gfc_saved_var, n);
4702 temp_vars = XCNEWVEC (tree, n);
7b5b57b7
PB
4703
4704 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
6de9cd9a
DN
4705 {
4706 /* Each dummy shall be specified, explicitly or implicitly, to be
4707 scalar. */
6e45f57b 4708 gcc_assert (fargs->sym->attr.dimension == 0);
6de9cd9a 4709 fsym = fargs->sym;
6de9cd9a 4710
7b5b57b7 4711 if (fsym->ts.type == BT_CHARACTER)
6de9cd9a 4712 {
7b5b57b7 4713 /* Copy string arguments. */
9a14c44d 4714 tree arglen;
6de9cd9a 4715
9a14c44d 4716 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
bc21d315 4717 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
6de9cd9a 4718
9a14c44d
TB
4719 /* Create a temporary to hold the value. */
4720 if (fsym->ts.u.cl->backend_decl == NULL_TREE)
4721 fsym->ts.u.cl->backend_decl
4722 = gfc_conv_constant_to_tree (fsym->ts.u.cl->length);
6de9cd9a 4723
9a14c44d
TB
4724 type = gfc_get_character_type (fsym->ts.kind, fsym->ts.u.cl);
4725 temp_vars[n] = gfc_create_var (type, fsym->name);
4726
4727 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
4728
4729 gfc_conv_expr (&rse, args->expr);
4730 gfc_conv_string_parameter (&rse);
4731 gfc_add_block_to_block (&se->pre, &lse.pre);
4732 gfc_add_block_to_block (&se->pre, &rse.pre);
6de9cd9a 4733
9a14c44d 4734 gfc_trans_string_copy (&se->pre, arglen, temp_vars[n], fsym->ts.kind,
d393bbd7 4735 rse.string_length, rse.expr, fsym->ts.kind);
9a14c44d
TB
4736 gfc_add_block_to_block (&se->pre, &lse.post);
4737 gfc_add_block_to_block (&se->pre, &rse.post);
6de9cd9a
DN
4738 }
4739 else
4740 {
4741 /* For everything else, just evaluate the expression. */
9a14c44d
TB
4742
4743 /* Create a temporary to hold the value. */
4744 type = gfc_typenode_for_spec (&fsym->ts);
4745 temp_vars[n] = gfc_create_var (type, fsym->name);
4746
6de9cd9a
DN
4747 gfc_conv_expr (&lse, args->expr);
4748
4749 gfc_add_block_to_block (&se->pre, &lse.pre);
726a989a 4750 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
6de9cd9a
DN
4751 gfc_add_block_to_block (&se->pre, &lse.post);
4752 }
7b5b57b7 4753
6de9cd9a
DN
4754 args = args->next;
4755 }
7b5b57b7
PB
4756
4757 /* Use the temporary variables in place of the real ones. */
4758 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
4759 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
4760
6de9cd9a 4761 gfc_conv_expr (se, sym->value);
7b5b57b7
PB
4762
4763 if (sym->ts.type == BT_CHARACTER)
4764 {
bc21d315 4765 gfc_conv_const_charlen (sym->ts.u.cl);
7b5b57b7
PB
4766
4767 /* Force the expression to the correct length. */
4768 if (!INTEGER_CST_P (se->string_length)
4769 || tree_int_cst_lt (se->string_length,
bc21d315 4770 sym->ts.u.cl->backend_decl))
7b5b57b7 4771 {
bc21d315 4772 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
7b5b57b7
PB
4773 tmp = gfc_create_var (type, sym->name);
4774 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
bc21d315 4775 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
d393bbd7
FXC
4776 sym->ts.kind, se->string_length, se->expr,
4777 sym->ts.kind);
7b5b57b7
PB
4778 se->expr = tmp;
4779 }
bc21d315 4780 se->string_length = sym->ts.u.cl->backend_decl;
7b5b57b7
PB
4781 }
4782
f8d0aee5 4783 /* Restore the original variables. */
7b5b57b7
PB
4784 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
4785 gfc_restore_sym (fargs->sym, &saved_vars[n]);
cede9502 4786 free (saved_vars);
6de9cd9a
DN
4787}
4788
4789
4790/* Translate a function expression. */
4791
4792static void
4793gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
4794{
4795 gfc_symbol *sym;
4796
4797 if (expr->value.function.isym)
4798 {
4799 gfc_conv_intrinsic_function (se, expr);
4800 return;
4801 }
4802
f8d0aee5 4803 /* We distinguish statement functions from general functions to improve
6de9cd9a
DN
4804 runtime performance. */
4805 if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
4806 {
4807 gfc_conv_statement_function (se, expr);
4808 return;
4809 }
4810
4811 /* expr.value.function.esym is the resolved (specific) function symbol for
4812 most functions. However this isn't set for dummy procedures. */
4813 sym = expr->value.function.esym;
4814 if (!sym)
4815 sym = expr->symtree->n.sym;
713485cc 4816
989ea525 4817 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr, NULL);
6de9cd9a
DN
4818}
4819
f8d0aee5 4820
dfd65514
TB
4821/* Determine whether the given EXPR_CONSTANT is a zero initializer. */
4822
4823static bool
4824is_zero_initializer_p (gfc_expr * expr)
4825{
4826 if (expr->expr_type != EXPR_CONSTANT)
4827 return false;
4828
4829 /* We ignore constants with prescribed memory representations for now. */
4830 if (expr->representation.string)
4831 return false;
4832
4833 switch (expr->ts.type)
4834 {
4835 case BT_INTEGER:
4836 return mpz_cmp_si (expr->value.integer, 0) == 0;
4837
4838 case BT_REAL:
4839 return mpfr_zero_p (expr->value.real)
4840 && MPFR_SIGN (expr->value.real) >= 0;
4841
4842 case BT_LOGICAL:
4843 return expr->value.logical == 0;
4844
4845 case BT_COMPLEX:
4846 return mpfr_zero_p (mpc_realref (expr->value.complex))
4847 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
4848 && mpfr_zero_p (mpc_imagref (expr->value.complex))
4849 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
4850
4851 default:
4852 break;
4853 }
4854 return false;
4855}
4856
4857
6de9cd9a
DN
4858static void
4859gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
4860{
bcc4d4e0
MM
4861 gfc_ss *ss;
4862
4863 ss = se->ss;
4864 gcc_assert (ss != NULL && ss != gfc_ss_terminator);
f98cfd3c 4865 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR);
6de9cd9a
DN
4866
4867 gfc_conv_tmp_array_ref (se);
6de9cd9a
DN
4868}
4869
4870
597073ac 4871/* Build a static initializer. EXPR is the expression for the initial value.
f8d0aee5
TS
4872 The other parameters describe the variable of the component being
4873 initialized. EXPR may be null. */
6de9cd9a 4874
597073ac
PB
4875tree
4876gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
1d0134b3 4877 bool array, bool pointer, bool procptr)
597073ac
PB
4878{
4879 gfc_se se;
4880
1d0134b3 4881 if (!(expr || pointer || procptr))
597073ac
PB
4882 return NULL_TREE;
4883
3e708b25
CR
4884 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
4885 (these are the only two iso_c_binding derived types that can be
4886 used as initialization expressions). If so, we need to modify
4887 the 'expr' to be that for a (void *). */
dd39f783 4888 if (expr != NULL && expr->ts.type == BT_DERIVED
bc21d315 4889 && expr->ts.is_iso_c && expr->ts.u.derived)
3e708b25 4890 {
bc21d315 4891 gfc_symbol *derived = expr->ts.u.derived;
3e708b25 4892
3e708b25
CR
4893 /* The derived symbol has already been converted to a (void *). Use
4894 its kind. */
b7e75771 4895 expr = gfc_get_int_expr (derived->ts.kind, NULL, 0);
3e708b25 4896 expr->ts.f90_type = derived->ts.f90_type;
505a36f9
TB
4897
4898 gfc_init_se (&se, NULL);
4899 gfc_conv_constant (&se, expr);
fa9a7193 4900 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
505a36f9 4901 return se.expr;
3e708b25 4902 }
a8b3b0b6 4903
1d0134b3 4904 if (array && !procptr)
597073ac 4905 {
fa9a7193 4906 tree ctor;
597073ac
PB
4907 /* Arrays need special handling. */
4908 if (pointer)
fa9a7193 4909 ctor = gfc_build_null_descriptor (type);
dfd65514
TB
4910 /* Special case assigning an array to zero. */
4911 else if (is_zero_initializer_p (expr))
fa9a7193 4912 ctor = build_constructor (type, NULL);
597073ac 4913 else
fa9a7193
JH
4914 ctor = gfc_conv_array_initializer (type, expr);
4915 TREE_STATIC (ctor) = 1;
4916 return ctor;
597073ac 4917 }
1d0134b3 4918 else if (pointer || procptr)
80f95228
JW
4919 {
4920 if (!expr || expr->expr_type == EXPR_NULL)
4921 return fold_convert (type, null_pointer_node);
4922 else
4923 {
4924 gfc_init_se (&se, NULL);
4925 se.want_pointer = 1;
4926 gfc_conv_expr (&se, expr);
fa9a7193 4927 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
80f95228
JW
4928 return se.expr;
4929 }
4930 }
597073ac
PB
4931 else
4932 {
4933 switch (ts->type)
4934 {
4935 case BT_DERIVED:
cf2b3c22 4936 case BT_CLASS:
597073ac 4937 gfc_init_se (&se, NULL);
f8dde8af
JW
4938 if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
4939 gfc_conv_structure (&se, gfc_class_null_initializer(ts), 1);
4940 else
4941 gfc_conv_structure (&se, expr, 1);
fa9a7193
JH
4942 gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
4943 TREE_STATIC (se.expr) = 1;
597073ac
PB
4944 return se.expr;
4945
4946 case BT_CHARACTER:
fa9a7193
JH
4947 {
4948 tree ctor = gfc_conv_string_init (ts->u.cl->backend_decl,expr);
4949 TREE_STATIC (ctor) = 1;
4950 return ctor;
4951 }
597073ac
PB
4952
4953 default:
4954 gfc_init_se (&se, NULL);
4955 gfc_conv_constant (&se, expr);
fa9a7193 4956 gcc_assert (TREE_CODE (se.expr) != CONSTRUCTOR);
597073ac
PB
4957 return se.expr;
4958 }
4959 }
4960}
4961
e9cfef64
PB
4962static tree
4963gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
4964{
4965 gfc_se rse;
4966 gfc_se lse;
4967 gfc_ss *rss;
4968 gfc_ss *lss;
08dcec61 4969 gfc_array_info *lss_array;
e9cfef64
PB
4970 stmtblock_t body;
4971 stmtblock_t block;
4972 gfc_loopinfo loop;
4973 int n;
4974 tree tmp;
4975
4976 gfc_start_block (&block);
4977
4978 /* Initialize the scalarizer. */
4979 gfc_init_loopinfo (&loop);
4980
4981 gfc_init_se (&lse, NULL);
4982 gfc_init_se (&rse, NULL);
4983
4984 /* Walk the rhs. */
4985 rss = gfc_walk_expr (expr);
4986 if (rss == gfc_ss_terminator)
26f77530
MM
4987 /* The rhs is scalar. Add a ss for the expression. */
4988 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr);
e9cfef64
PB
4989
4990 /* Create a SS for the destination. */
66877276
MM
4991 lss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
4992 GFC_SS_COMPONENT);
1838afec 4993 lss_array = &lss->info->data.array;
08dcec61
MM
4994 lss_array->shape = gfc_get_shape (cm->as->rank);
4995 lss_array->descriptor = dest;
4996 lss_array->data = gfc_conv_array_data (dest);
4997 lss_array->offset = gfc_conv_array_offset (dest);
e9cfef64
PB
4998 for (n = 0; n < cm->as->rank; n++)
4999 {
08dcec61
MM
5000 lss_array->start[n] = gfc_conv_array_lbound (dest, n);
5001 lss_array->stride[n] = gfc_index_one_node;
e9cfef64 5002
08dcec61
MM
5003 mpz_init (lss_array->shape[n]);
5004 mpz_sub (lss_array->shape[n], cm->as->upper[n]->value.integer,
e9cfef64 5005 cm->as->lower[n]->value.integer);
08dcec61 5006 mpz_add_ui (lss_array->shape[n], lss_array->shape[n], 1);
e9cfef64
PB
5007 }
5008
5009 /* Associate the SS with the loop. */
5010 gfc_add_ss_to_loop (&loop, lss);
5011 gfc_add_ss_to_loop (&loop, rss);
5012
5013 /* Calculate the bounds of the scalarization. */
5014 gfc_conv_ss_startstride (&loop);
5015
5016 /* Setup the scalarizing loops. */
bdfd2ff0 5017 gfc_conv_loop_setup (&loop, &expr->where);
e9cfef64
PB
5018
5019 /* Setup the gfc_se structures. */
5020 gfc_copy_loopinfo_to_se (&lse, &loop);
5021 gfc_copy_loopinfo_to_se (&rse, &loop);
5022
5023 rse.ss = rss;
5024 gfc_mark_ss_chain_used (rss, 1);
5025 lse.ss = lss;
5026 gfc_mark_ss_chain_used (lss, 1);
5027
5028 /* Start the scalarized loop body. */
5029 gfc_start_scalarized_body (&loop, &body);
5030
5031 gfc_conv_tmp_array_ref (&lse);
2b052ce2 5032 if (cm->ts.type == BT_CHARACTER)
bc21d315 5033 lse.string_length = cm->ts.u.cl->backend_decl;
2b052ce2 5034
e9cfef64
PB
5035 gfc_conv_expr (&rse, expr);
5036
2b56d6a4 5037 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false, true);
e9cfef64
PB
5038 gfc_add_expr_to_block (&body, tmp);
5039
6e45f57b 5040 gcc_assert (rse.ss == gfc_ss_terminator);
e9cfef64
PB
5041
5042 /* Generate the copying loops. */
5043 gfc_trans_scalarizing_loops (&loop, &body);
5044
5045 /* Wrap the whole thing up. */
5046 gfc_add_block_to_block (&block, &loop.pre);
5047 gfc_add_block_to_block (&block, &loop.post);
5048
08dcec61
MM
5049 gcc_assert (lss_array->shape != NULL);
5050 gfc_free_shape (&lss_array->shape, cm->as->rank);
96654664
PB
5051 gfc_cleanup_loop (&loop);
5052
e9cfef64
PB
5053 return gfc_finish_block (&block);
5054}
5055
5046aff5 5056
b7d1d8b4
PT
5057static tree
5058gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
5059 gfc_expr * expr)
5060{
5061 gfc_se se;
5062 gfc_ss *rss;
5063 stmtblock_t block;
5064 tree offset;
5065 int n;
5066 tree tmp;
5067 tree tmp2;
5068 gfc_array_spec *as;
5069 gfc_expr *arg = NULL;
5070
5071 gfc_start_block (&block);
5072 gfc_init_se (&se, NULL);
5073
5074 /* Get the descriptor for the expressions. */
5075 rss = gfc_walk_expr (expr);
5076 se.want_pointer = 0;
5077 gfc_conv_expr_descriptor (&se, expr, rss);
5078 gfc_add_block_to_block (&block, &se.pre);
5079 gfc_add_modify (&block, dest, se.expr);
5080
5081 /* Deal with arrays of derived types with allocatable components. */
5082 if (cm->ts.type == BT_DERIVED
5083 && cm->ts.u.derived->attr.alloc_comp)
5084 tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
5085 se.expr, dest,
5086 cm->as->rank);
5087 else
5088 tmp = gfc_duplicate_allocatable (dest, se.expr,
5089 TREE_TYPE(cm->backend_decl),
5090 cm->as->rank);
5091
5092 gfc_add_expr_to_block (&block, tmp);
5093 gfc_add_block_to_block (&block, &se.post);
5094
5095 if (expr->expr_type != EXPR_VARIABLE)
5096 gfc_conv_descriptor_data_set (&block, se.expr,
5097 null_pointer_node);
5098
5099 /* We need to know if the argument of a conversion function is a
5100 variable, so that the correct lower bound can be used. */
5101 if (expr->expr_type == EXPR_FUNCTION
5102 && expr->value.function.isym
5103 && expr->value.function.isym->conversion
5104 && expr->value.function.actual->expr
5105 && expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
5106 arg = expr->value.function.actual->expr;
5107
5108 /* Obtain the array spec of full array references. */
5109 if (arg)
5110 as = gfc_get_full_arrayspec_from_expr (arg);
5111 else
5112 as = gfc_get_full_arrayspec_from_expr (expr);
5113
5114 /* Shift the lbound and ubound of temporaries to being unity,
5115 rather than zero, based. Always calculate the offset. */
5116 offset = gfc_conv_descriptor_offset_get (dest);
5117 gfc_add_modify (&block, offset, gfc_index_zero_node);
5118 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
5119
5120 for (n = 0; n < expr->rank; n++)
5121 {
5122 tree span;
5123 tree lbound;
5124
5125 /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
5126 TODO It looks as if gfc_conv_expr_descriptor should return
5127 the correct bounds and that the following should not be
5128 necessary. This would simplify gfc_conv_intrinsic_bound
5129 as well. */
5130 if (as && as->lower[n])
5131 {
5132 gfc_se lbse;
5133 gfc_init_se (&lbse, NULL);
5134 gfc_conv_expr (&lbse, as->lower[n]);
5135 gfc_add_block_to_block (&block, &lbse.pre);
5136 lbound = gfc_evaluate_now (lbse.expr, &block);
5137 }
5138 else if (as && arg)
5139 {
5140 tmp = gfc_get_symbol_decl (arg->symtree->n.sym);
5141 lbound = gfc_conv_descriptor_lbound_get (tmp,
5142 gfc_rank_cst[n]);
5143 }
5144 else if (as)
5145 lbound = gfc_conv_descriptor_lbound_get (dest,
5146 gfc_rank_cst[n]);
5147 else
5148 lbound = gfc_index_one_node;
5149
5150 lbound = fold_convert (gfc_array_index_type, lbound);
5151
5152 /* Shift the bounds and set the offset accordingly. */
5153 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
65a9ca82
TB
5154 span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5155 tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
5156 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5157 span, lbound);
b7d1d8b4
PT
5158 gfc_conv_descriptor_ubound_set (&block, dest,
5159 gfc_rank_cst[n], tmp);
5160 gfc_conv_descriptor_lbound_set (&block, dest,
5161 gfc_rank_cst[n], lbound);
5162
65a9ca82 5163 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
b7d1d8b4
PT
5164 gfc_conv_descriptor_lbound_get (dest,
5165 gfc_rank_cst[n]),
5166 gfc_conv_descriptor_stride_get (dest,
5167 gfc_rank_cst[n]));
5168 gfc_add_modify (&block, tmp2, tmp);
65a9ca82
TB
5169 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5170 offset, tmp2);
b7d1d8b4
PT
5171 gfc_conv_descriptor_offset_set (&block, dest, tmp);
5172 }
5173
5174 if (arg)
5175 {
5176 /* If a conversion expression has a null data pointer
5177 argument, nullify the allocatable component. */
5178 tree non_null_expr;
5179 tree null_expr;
5180
5181 if (arg->symtree->n.sym->attr.allocatable
5182 || arg->symtree->n.sym->attr.pointer)
5183 {
5184 non_null_expr = gfc_finish_block (&block);
5185 gfc_start_block (&block);
5186 gfc_conv_descriptor_data_set (&block, dest,
5187 null_pointer_node);
5188 null_expr = gfc_finish_block (&block);
5189 tmp = gfc_conv_descriptor_data_get (arg->symtree->n.sym->backend_decl);
5d44e5c8
TB
5190 tmp = build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
5191 fold_convert (TREE_TYPE (tmp), null_pointer_node));
b7d1d8b4
PT
5192 return build3_v (COND_EXPR, tmp,
5193 null_expr, non_null_expr);
5194 }
5195 }
5196
5197 return gfc_finish_block (&block);
5198}
5199
5200
e9cfef64
PB
5201/* Assign a single component of a derived type constructor. */
5202
5203static tree
5204gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
5205{
5206 gfc_se se;
5046aff5 5207 gfc_se lse;
e9cfef64
PB
5208 gfc_ss *rss;
5209 stmtblock_t block;
5210 tree tmp;
5211
5212 gfc_start_block (&block);
5046aff5 5213
d4b7d0f0 5214 if (cm->attr.pointer)
e9cfef64
PB
5215 {
5216 gfc_init_se (&se, NULL);
5217 /* Pointer component. */
d4b7d0f0 5218 if (cm->attr.dimension)
e9cfef64
PB
5219 {
5220 /* Array pointer. */
5221 if (expr->expr_type == EXPR_NULL)
4c73896d 5222 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
e9cfef64
PB
5223 else
5224 {
5225 rss = gfc_walk_expr (expr);
5226 se.direct_byref = 1;
5227 se.expr = dest;
5228 gfc_conv_expr_descriptor (&se, expr, rss);
5229 gfc_add_block_to_block (&block, &se.pre);
5230 gfc_add_block_to_block (&block, &se.post);
5231 }
5232 }
5233 else
5234 {
5235 /* Scalar pointers. */
5236 se.want_pointer = 1;
5237 gfc_conv_expr (&se, expr);
5238 gfc_add_block_to_block (&block, &se.pre);
726a989a 5239 gfc_add_modify (&block, dest,
e9cfef64
PB
5240 fold_convert (TREE_TYPE (dest), se.expr));
5241 gfc_add_block_to_block (&block, &se.post);
5242 }
5243 }
cf2b3c22
TB
5244 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
5245 {
5246 /* NULL initialization for CLASS components. */
5247 tmp = gfc_trans_structure_assign (dest,
f8dde8af 5248 gfc_class_null_initializer (&cm->ts));
cf2b3c22
TB
5249 gfc_add_expr_to_block (&block, tmp);
5250 }
b54b7821 5251 else if (cm->attr.dimension && !cm->attr.proc_pointer)
e9cfef64 5252 {
d4b7d0f0 5253 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
5046aff5 5254 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
d4b7d0f0 5255 else if (cm->attr.allocatable)
28114dad 5256 {
b7d1d8b4 5257 tmp = gfc_trans_alloc_subarray_assign (dest, cm, expr);
28114dad 5258 gfc_add_expr_to_block (&block, tmp);
28114dad 5259 }
5046aff5 5260 else
28114dad 5261 {
5046aff5
PT
5262 tmp = gfc_trans_subarray_assign (dest, cm, expr);
5263 gfc_add_expr_to_block (&block, tmp);
28114dad 5264 }
e9cfef64
PB
5265 }
5266 else if (expr->ts.type == BT_DERIVED)
5267 {
3e978d30
PT
5268 if (expr->expr_type != EXPR_STRUCTURE)
5269 {
5270 gfc_init_se (&se, NULL);
5271 gfc_conv_expr (&se, expr);
fe7a047c 5272 gfc_add_block_to_block (&block, &se.pre);
726a989a 5273 gfc_add_modify (&block, dest,
3e978d30 5274 fold_convert (TREE_TYPE (dest), se.expr));
fe7a047c 5275 gfc_add_block_to_block (&block, &se.post);
3e978d30
PT
5276 }
5277 else
5278 {
5279 /* Nested constructors. */
5280 tmp = gfc_trans_structure_assign (dest, expr);
5281 gfc_add_expr_to_block (&block, tmp);
5282 }
e9cfef64
PB
5283 }
5284 else
5285 {
5286 /* Scalar component. */
e9cfef64
PB
5287 gfc_init_se (&se, NULL);
5288 gfc_init_se (&lse, NULL);
5289
5290 gfc_conv_expr (&se, expr);
5291 if (cm->ts.type == BT_CHARACTER)
bc21d315 5292 lse.string_length = cm->ts.u.cl->backend_decl;
e9cfef64 5293 lse.expr = dest;
2b56d6a4 5294 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false, true);
e9cfef64
PB
5295 gfc_add_expr_to_block (&block, tmp);
5296 }
5297 return gfc_finish_block (&block);
5298}
5299
13795658 5300/* Assign a derived type constructor to a variable. */
e9cfef64
PB
5301
5302static tree
5303gfc_trans_structure_assign (tree dest, gfc_expr * expr)
5304{
5305 gfc_constructor *c;
5306 gfc_component *cm;
5307 stmtblock_t block;
5308 tree field;
5309 tree tmp;
5310
5311 gfc_start_block (&block);
bc21d315 5312 cm = expr->ts.u.derived->components;
b5dca6ea
TB
5313
5314 if (expr->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
5315 && (expr->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
5316 || expr->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
5317 {
5318 gfc_se se, lse;
5319
5320 gcc_assert (cm->backend_decl == NULL);
5321 gfc_init_se (&se, NULL);
5322 gfc_init_se (&lse, NULL);
5323 gfc_conv_expr (&se, gfc_constructor_first (expr->value.constructor)->expr);
5324 lse.expr = dest;
5325 gfc_add_modify (&block, lse.expr,
5326 fold_convert (TREE_TYPE (lse.expr), se.expr));
5327
5328 return gfc_finish_block (&block);
5329 }
5330
b7e75771
JD
5331 for (c = gfc_constructor_first (expr->value.constructor);
5332 c; c = gfc_constructor_next (c), cm = cm->next)
e9cfef64
PB
5333 {
5334 /* Skip absent members in default initializers. */
5335 if (!c->expr)
fe7a047c
MM
5336 continue;
5337
e9cfef64 5338 field = cm->backend_decl;
65a9ca82
TB
5339 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
5340 dest, field, NULL_TREE);
e9cfef64
PB
5341 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
5342 gfc_add_expr_to_block (&block, tmp);
5343 }
5344 return gfc_finish_block (&block);
5345}
5346
6de9cd9a
DN
5347/* Build an expression for a constructor. If init is nonzero then
5348 this is part of a static variable initializer. */
5349
5350void
5351gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
5352{
5353 gfc_constructor *c;
5354 gfc_component *cm;
6de9cd9a 5355 tree val;
6de9cd9a 5356 tree type;
e9cfef64 5357 tree tmp;
4038c495 5358 VEC(constructor_elt,gc) *v = NULL;
6de9cd9a 5359
6e45f57b
PB
5360 gcc_assert (se->ss == NULL);
5361 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
6de9cd9a 5362 type = gfc_typenode_for_spec (&expr->ts);
e9cfef64
PB
5363
5364 if (!init)
5365 {
5366 /* Create a temporary variable and fill it in. */
bc21d315 5367 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
e9cfef64
PB
5368 tmp = gfc_trans_structure_assign (se->expr, expr);
5369 gfc_add_expr_to_block (&se->pre, tmp);
5370 return;
5371 }
5372
bc21d315 5373 cm = expr->ts.u.derived->components;
5046aff5 5374
b7e75771
JD
5375 for (c = gfc_constructor_first (expr->value.constructor);
5376 c; c = gfc_constructor_next (c), cm = cm->next)
6de9cd9a 5377 {
5046aff5
PT
5378 /* Skip absent members in default initializers and allocatable
5379 components. Although the latter have a default initializer
5380 of EXPR_NULL,... by default, the static nullify is not needed
5381 since this is done every time we come into scope. */
0f0a4367 5382 if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
6de9cd9a
DN
5383 continue;
5384
b04533af 5385 if (strcmp (cm->name, "_size") == 0)
7c1dab0d
JW
5386 {
5387 val = TYPE_SIZE_UNIT (gfc_get_derived_type (cm->ts.u.derived));
5388 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
5389 }
5390 else if (cm->initializer && cm->initializer->expr_type != EXPR_NULL
b04533af 5391 && strcmp (cm->name, "_extends") == 0)
7c1dab0d 5392 {
eece1eb9 5393 tree vtab;
7c1dab0d
JW
5394 gfc_symbol *vtabs;
5395 vtabs = cm->initializer->symtree->n.sym;
eece1eb9
PT
5396 vtab = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtabs));
5397 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, vtab);
cf2b3c22
TB
5398 }
5399 else
5400 {
5401 val = gfc_conv_initializer (c->expr, &cm->ts,
1d0134b3
JW
5402 TREE_TYPE (cm->backend_decl),
5403 cm->attr.dimension, cm->attr.pointer,
5404 cm->attr.proc_pointer);
6de9cd9a 5405
cf2b3c22
TB
5406 /* Append it to the constructor list. */
5407 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
5408 }
6de9cd9a 5409 }
4038c495 5410 se->expr = build_constructor (type, v);
7e4b97c7 5411 if (init)
51eed280 5412 TREE_CONSTANT (se->expr) = 1;
6de9cd9a
DN
5413}
5414
5415
f8d0aee5 5416/* Translate a substring expression. */
6de9cd9a
DN
5417
5418static void
5419gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
5420{
5421 gfc_ref *ref;
5422
5423 ref = expr->ref;
5424
9a251aa1 5425 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
6de9cd9a 5426
d393bbd7
FXC
5427 se->expr = gfc_build_wide_string_const (expr->ts.kind,
5428 expr->value.character.length,
5429 expr->value.character.string);
00660189 5430
6de9cd9a 5431 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
9a251aa1 5432 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
6de9cd9a 5433
9a251aa1
FXC
5434 if (ref)
5435 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
6de9cd9a
DN
5436}
5437
5438
a4f5cd44
PB
5439/* Entry point for expression translation. Evaluates a scalar quantity.
5440 EXPR is the expression to be translated, and SE is the state structure if
5441 called from within the scalarized. */
6de9cd9a
DN
5442
5443void
5444gfc_conv_expr (gfc_se * se, gfc_expr * expr)
5445{
bcc4d4e0
MM
5446 gfc_ss *ss;
5447
5448 ss = se->ss;
f98cfd3c 5449 if (ss && ss->info->expr == expr
bcc4d4e0
MM
5450 && (ss->info->type == GFC_SS_SCALAR
5451 || ss->info->type == GFC_SS_REFERENCE))
6de9cd9a 5452 {
a0add3be
MM
5453 gfc_ss_info *ss_info;
5454
5455 ss_info = ss->info;
e9cfef64 5456 /* Substitute a scalar expression evaluated outside the scalarization
6de9cd9a 5457 loop. */
99dd5a29 5458 se->expr = ss_info->data.scalar.value;
0192ef20
MM
5459 /* If the reference can be NULL, the value field contains the reference,
5460 not the value the reference points to (see gfc_add_loop_ss_code). */
9bcf7121 5461 if (ss_info->can_be_null_ref)
0192ef20
MM
5462 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
5463
a0add3be 5464 se->string_length = ss_info->string_length;
6de9cd9a
DN
5465 gfc_advance_se_ss_chain (se);
5466 return;
5467 }
5468
a8b3b0b6
CR
5469 /* We need to convert the expressions for the iso_c_binding derived types.
5470 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
5471 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
5472 typespec for the C_PTR and C_FUNPTR symbols, which has already been
5473 updated to be an integer with a kind equal to the size of a (void *). */
bc21d315
JW
5474 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
5475 && expr->ts.u.derived->attr.is_iso_c)
a8b3b0b6 5476 {
b5dca6ea
TB
5477 if (expr->expr_type == EXPR_VARIABLE
5478 && (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
5479 || expr->symtree->n.sym->intmod_sym_id
5480 == ISOCBINDING_NULL_FUNPTR))
a8b3b0b6
CR
5481 {
5482 /* Set expr_type to EXPR_NULL, which will result in
5483 null_pointer_node being used below. */
5484 expr->expr_type = EXPR_NULL;
5485 }
5486 else
5487 {
5488 /* Update the type/kind of the expression to be what the new
5489 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
bc21d315
JW
5490 expr->ts.type = expr->ts.u.derived->ts.type;
5491 expr->ts.f90_type = expr->ts.u.derived->ts.f90_type;
5492 expr->ts.kind = expr->ts.u.derived->ts.kind;
a8b3b0b6
CR
5493 }
5494 }
c49ea23d 5495
37da591f 5496 gfc_fix_class_refs (expr);
c49ea23d 5497
6de9cd9a
DN
5498 switch (expr->expr_type)
5499 {
5500 case EXPR_OP:
5501 gfc_conv_expr_op (se, expr);
5502 break;
5503
5504 case EXPR_FUNCTION:
5505 gfc_conv_function_expr (se, expr);
5506 break;
5507
5508 case EXPR_CONSTANT:
5509 gfc_conv_constant (se, expr);
5510 break;
5511
5512 case EXPR_VARIABLE:
5513 gfc_conv_variable (se, expr);
5514 break;
5515
5516 case EXPR_NULL:
5517 se->expr = null_pointer_node;
5518 break;
5519
5520 case EXPR_SUBSTRING:
5521 gfc_conv_substring_expr (se, expr);
5522 break;
5523
5524 case EXPR_STRUCTURE:
5525 gfc_conv_structure (se, expr, 0);
5526 break;
5527
5528 case EXPR_ARRAY:
5529 gfc_conv_array_constructor_expr (se, expr);
5530 break;
5531
5532 default:
6e45f57b 5533 gcc_unreachable ();
6de9cd9a
DN
5534 break;
5535 }
5536}
5537
a4f5cd44
PB
5538/* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
5539 of an assignment. */
6de9cd9a
DN
5540void
5541gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
5542{
5543 gfc_conv_expr (se, expr);
a4f5cd44 5544 /* All numeric lvalues should have empty post chains. If not we need to
6de9cd9a 5545 figure out a way of rewriting an lvalue so that it has no post chain. */
a4f5cd44 5546 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
6de9cd9a
DN
5547}
5548
a4f5cd44 5549/* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
417ab240 5550 numeric expressions. Used for scalar values where inserting cleanup code
a4f5cd44 5551 is inconvenient. */
6de9cd9a
DN
5552void
5553gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
5554{
5555 tree val;
5556
6e45f57b 5557 gcc_assert (expr->ts.type != BT_CHARACTER);
6de9cd9a
DN
5558 gfc_conv_expr (se, expr);
5559 if (se->post.head)
5560 {
5561 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
726a989a 5562 gfc_add_modify (&se->pre, val, se->expr);
a4f5cd44
PB
5563 se->expr = val;
5564 gfc_add_block_to_block (&se->pre, &se->post);
6de9cd9a
DN
5565 }
5566}
5567
33717d59 5568/* Helper to translate an expression and convert it to a particular type. */
6de9cd9a
DN
5569void
5570gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
5571{
5572 gfc_conv_expr_val (se, expr);
5573 se->expr = convert (type, se->expr);
5574}
5575
5576
f8d0aee5 5577/* Converts an expression so that it can be passed by reference. Scalar
6de9cd9a
DN
5578 values only. */
5579
5580void
5581gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
5582{
bcc4d4e0 5583 gfc_ss *ss;
6de9cd9a
DN
5584 tree var;
5585
bcc4d4e0 5586 ss = se->ss;
f98cfd3c 5587 if (ss && ss->info->expr == expr
bcc4d4e0 5588 && ss->info->type == GFC_SS_REFERENCE)
6de9cd9a 5589 {
991b4da1
PT
5590 /* Returns a reference to the scalar evaluated outside the loop
5591 for this case. */
5592 gfc_conv_expr (se, expr);
591823cc 5593 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
6de9cd9a
DN
5594 return;
5595 }
5596
5597 if (expr->ts.type == BT_CHARACTER)
5598 {
5599 gfc_conv_expr (se, expr);
5600 gfc_conv_string_parameter (se);
5601 return;
5602 }
5603
5604 if (expr->expr_type == EXPR_VARIABLE)
5605 {
5606 se->want_pointer = 1;
5607 gfc_conv_expr (se, expr);
5608 if (se->post.head)
5609 {
5610 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
726a989a 5611 gfc_add_modify (&se->pre, var, se->expr);
6de9cd9a
DN
5612 gfc_add_block_to_block (&se->pre, &se->post);
5613 se->expr = var;
5614 }
5615 return;
5616 }
5617
6a56381b 5618 if (expr->expr_type == EXPR_FUNCTION
e6524a51
TB
5619 && ((expr->value.function.esym
5620 && expr->value.function.esym->result->attr.pointer
5621 && !expr->value.function.esym->result->attr.dimension)
5622 || (!expr->value.function.esym
5623 && expr->symtree->n.sym->attr.pointer
5624 && !expr->symtree->n.sym->attr.dimension)))
6a56381b
PT
5625 {
5626 se->want_pointer = 1;
5627 gfc_conv_expr (se, expr);
5628 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
726a989a 5629 gfc_add_modify (&se->pre, var, se->expr);
6a56381b
PT
5630 se->expr = var;
5631 return;
5632 }
5633
6de9cd9a
DN
5634 gfc_conv_expr (se, expr);
5635
5636 /* Create a temporary var to hold the value. */
0534fa56
RH
5637 if (TREE_CONSTANT (se->expr))
5638 {
fade9a8e
AP
5639 tree tmp = se->expr;
5640 STRIP_TYPE_NOPS (tmp);
c2255bc4
AH
5641 var = build_decl (input_location,
5642 CONST_DECL, NULL, TREE_TYPE (tmp));
fade9a8e 5643 DECL_INITIAL (var) = tmp;
3e806a3d 5644 TREE_STATIC (var) = 1;
0534fa56
RH
5645 pushdecl (var);
5646 }
5647 else
5648 {
5649 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
726a989a 5650 gfc_add_modify (&se->pre, var, se->expr);
0534fa56 5651 }
6de9cd9a
DN
5652 gfc_add_block_to_block (&se->pre, &se->post);
5653
5654 /* Take the address of that value. */
628c189e 5655 se->expr = gfc_build_addr_expr (NULL_TREE, var);
6de9cd9a
DN
5656}
5657
5658
5659tree
5660gfc_trans_pointer_assign (gfc_code * code)
5661{
a513927a 5662 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
6de9cd9a
DN
5663}
5664
5665
fc90a8f2
PB
5666/* Generate code for a pointer assignment. */
5667
6de9cd9a
DN
5668tree
5669gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
5670{
5671 gfc_se lse;
5672 gfc_se rse;
5673 gfc_ss *lss;
5674 gfc_ss *rss;
5675 stmtblock_t block;
8aeca7fd
RS
5676 tree desc;
5677 tree tmp;
1d6b7f39
PT
5678 tree decl;
5679
6de9cd9a
DN
5680 gfc_start_block (&block);
5681
5682 gfc_init_se (&lse, NULL);
5683
5684 lss = gfc_walk_expr (expr1);
5685 rss = gfc_walk_expr (expr2);
5686 if (lss == gfc_ss_terminator)
5687 {
fc90a8f2 5688 /* Scalar pointers. */
6de9cd9a
DN
5689 lse.want_pointer = 1;
5690 gfc_conv_expr (&lse, expr1);
6e45f57b 5691 gcc_assert (rss == gfc_ss_terminator);
6de9cd9a
DN
5692 gfc_init_se (&rse, NULL);
5693 rse.want_pointer = 1;
5694 gfc_conv_expr (&rse, expr2);
8fb74da4
JW
5695
5696 if (expr1->symtree->n.sym->attr.proc_pointer
5697 && expr1->symtree->n.sym->attr.dummy)
db3927fb
AH
5698 lse.expr = build_fold_indirect_ref_loc (input_location,
5699 lse.expr);
8fb74da4 5700
c74b74a8
JW
5701 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
5702 && expr2->symtree->n.sym->attr.dummy)
db3927fb
AH
5703 rse.expr = build_fold_indirect_ref_loc (input_location,
5704 rse.expr);
c74b74a8 5705
6de9cd9a
DN
5706 gfc_add_block_to_block (&block, &lse.pre);
5707 gfc_add_block_to_block (&block, &rse.pre);
fb5bc08b
DK
5708
5709 /* Check character lengths if character expression. The test is only
8d51f26f
PT
5710 really added if -fbounds-check is enabled. Exclude deferred
5711 character length lefthand sides. */
50dbf0b4 5712 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
8d51f26f
PT
5713 && !(expr1->ts.deferred
5714 && (TREE_CODE (lse.string_length) == VAR_DECL))
50dbf0b4
JW
5715 && !expr1->symtree->n.sym->attr.proc_pointer
5716 && !gfc_is_proc_ptr_comp (expr1, NULL))
fb5bc08b
DK
5717 {
5718 gcc_assert (expr2->ts.type == BT_CHARACTER);
5719 gcc_assert (lse.string_length && rse.string_length);
5720 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
5721 lse.string_length, rse.string_length,
5722 &block);
5723 }
5724
8d51f26f
PT
5725 /* The assignment to an deferred character length sets the string
5726 length to that of the rhs. */
5727 if (expr1->ts.deferred && (TREE_CODE (lse.string_length) == VAR_DECL))
5728 {
5729 if (expr2->expr_type != EXPR_NULL)
5730 gfc_add_modify (&block, lse.string_length, rse.string_length);
5731 else
5732 gfc_add_modify (&block, lse.string_length,
5733 build_int_cst (gfc_charlen_type_node, 0));
5734 }
5735
726a989a 5736 gfc_add_modify (&block, lse.expr,
7ab92584 5737 fold_convert (TREE_TYPE (lse.expr), rse.expr));
fb5bc08b 5738
6de9cd9a
DN
5739 gfc_add_block_to_block (&block, &rse.post);
5740 gfc_add_block_to_block (&block, &lse.post);
5741 }
5742 else
5743 {
99d821c0
DK
5744 gfc_ref* remap;
5745 bool rank_remap;
fb5bc08b
DK
5746 tree strlen_lhs;
5747 tree strlen_rhs = NULL_TREE;
5748
99d821c0
DK
5749 /* Array pointer. Find the last reference on the LHS and if it is an
5750 array section ref, we're dealing with bounds remapping. In this case,
5751 set it to AR_FULL so that gfc_conv_expr_descriptor does
5752 not see it and process the bounds remapping afterwards explicitely. */
5753 for (remap = expr1->ref; remap; remap = remap->next)
5754 if (!remap->next && remap->type == REF_ARRAY
5755 && remap->u.ar.type == AR_SECTION)
5756 {
5757 remap->u.ar.type = AR_FULL;
5758 break;
5759 }
5760 rank_remap = (remap && remap->u.ar.end[0]);
5761
6de9cd9a 5762 gfc_conv_expr_descriptor (&lse, expr1, lss);
fb5bc08b 5763 strlen_lhs = lse.string_length;
99d821c0
DK
5764 desc = lse.expr;
5765
5766 if (expr2->expr_type == EXPR_NULL)
8aeca7fd 5767 {
8aeca7fd 5768 /* Just set the data pointer to null. */
467f18f3 5769 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
99d821c0
DK
5770 }
5771 else if (rank_remap)
5772 {
5773 /* If we are rank-remapping, just get the RHS's descriptor and
5774 process this later on. */
5775 gfc_init_se (&rse, NULL);
5776 rse.direct_byref = 1;
5777 rse.byref_noassign = 1;
5778 gfc_conv_expr_descriptor (&rse, expr2, rss);
5779 strlen_rhs = rse.string_length;
5780 }
5781 else if (expr2->expr_type == EXPR_VARIABLE)
5782 {
5783 /* Assign directly to the LHS's descriptor. */
fb5bc08b 5784 lse.direct_byref = 1;
8aeca7fd 5785 gfc_conv_expr_descriptor (&lse, expr2, rss);
fb5bc08b 5786 strlen_rhs = lse.string_length;
1d6b7f39
PT
5787
5788 /* If this is a subreference array pointer assignment, use the rhs
da6b49e1 5789 descriptor element size for the lhs span. */
1d6b7f39
PT
5790 if (expr1->symtree->n.sym->attr.subref_array_pointer)
5791 {
5792 decl = expr1->symtree->n.sym->backend_decl;
da6b49e1
PT
5793 gfc_init_se (&rse, NULL);
5794 rse.descriptor_only = 1;
5795 gfc_conv_expr (&rse, expr2);
5796 tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
5797 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
5798 if (!INTEGER_CST_P (tmp))
fb5bc08b 5799 gfc_add_block_to_block (&lse.post, &rse.pre);
726a989a 5800 gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
1d6b7f39 5801 }
99d821c0
DK
5802 }
5803 else
5804 {
8aeca7fd
RS
5805 /* Assign to a temporary descriptor and then copy that
5806 temporary to the pointer. */
8aeca7fd
RS
5807 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
5808
5809 lse.expr = tmp;
5810 lse.direct_byref = 1;
5811 gfc_conv_expr_descriptor (&lse, expr2, rss);
fb5bc08b 5812 strlen_rhs = lse.string_length;
726a989a 5813 gfc_add_modify (&lse.pre, desc, tmp);
fb5bc08b
DK
5814 }
5815
6de9cd9a 5816 gfc_add_block_to_block (&block, &lse.pre);
99d821c0
DK
5817 if (rank_remap)
5818 gfc_add_block_to_block (&block, &rse.pre);
5819
5820 /* If we do bounds remapping, update LHS descriptor accordingly. */
5821 if (remap)
5822 {
5823 int dim;
5824 gcc_assert (remap->u.ar.dimen == expr1->rank);
5825
5826 if (rank_remap)
5827 {
5828 /* Do rank remapping. We already have the RHS's descriptor
5829 converted in rse and now have to build the correct LHS
5830 descriptor for it. */
5831
5832 tree dtype, data;
5833 tree offs, stride;
5834 tree lbound, ubound;
5835
5836 /* Set dtype. */
5837 dtype = gfc_conv_descriptor_dtype (desc);
5838 tmp = gfc_get_dtype (TREE_TYPE (desc));
5839 gfc_add_modify (&block, dtype, tmp);
5840
5841 /* Copy data pointer. */
5842 data = gfc_conv_descriptor_data_get (rse.expr);
5843 gfc_conv_descriptor_data_set (&block, desc, data);
5844
5845 /* Copy offset but adjust it such that it would correspond
5846 to a lbound of zero. */
5847 offs = gfc_conv_descriptor_offset_get (rse.expr);
5848 for (dim = 0; dim < expr2->rank; ++dim)
5849 {
5850 stride = gfc_conv_descriptor_stride_get (rse.expr,
5851 gfc_rank_cst[dim]);
5852 lbound = gfc_conv_descriptor_lbound_get (rse.expr,
5853 gfc_rank_cst[dim]);
65a9ca82
TB
5854 tmp = fold_build2_loc (input_location, MULT_EXPR,
5855 gfc_array_index_type, stride, lbound);
5856 offs = fold_build2_loc (input_location, PLUS_EXPR,
5857 gfc_array_index_type, offs, tmp);
99d821c0
DK
5858 }
5859 gfc_conv_descriptor_offset_set (&block, desc, offs);
5860
5861 /* Set the bounds as declared for the LHS and calculate strides as
5862 well as another offset update accordingly. */
5863 stride = gfc_conv_descriptor_stride_get (rse.expr,
5864 gfc_rank_cst[0]);
5865 for (dim = 0; dim < expr1->rank; ++dim)
5866 {
5867 gfc_se lower_se;
5868 gfc_se upper_se;
5869
5870 gcc_assert (remap->u.ar.start[dim] && remap->u.ar.end[dim]);
5871
5872 /* Convert declared bounds. */
5873 gfc_init_se (&lower_se, NULL);
5874 gfc_init_se (&upper_se, NULL);
5875 gfc_conv_expr (&lower_se, remap->u.ar.start[dim]);
5876 gfc_conv_expr (&upper_se, remap->u.ar.end[dim]);
5877
5878 gfc_add_block_to_block (&block, &lower_se.pre);
5879 gfc_add_block_to_block (&block, &upper_se.pre);
5880
5881 lbound = fold_convert (gfc_array_index_type, lower_se.expr);
5882 ubound = fold_convert (gfc_array_index_type, upper_se.expr);
5883
5884 lbound = gfc_evaluate_now (lbound, &block);
5885 ubound = gfc_evaluate_now (ubound, &block);
5886
5887 gfc_add_block_to_block (&block, &lower_se.post);
5888 gfc_add_block_to_block (&block, &upper_se.post);
5889
5890 /* Set bounds in descriptor. */
5891 gfc_conv_descriptor_lbound_set (&block, desc,
5892 gfc_rank_cst[dim], lbound);
5893 gfc_conv_descriptor_ubound_set (&block, desc,
5894 gfc_rank_cst[dim], ubound);
5895
5896 /* Set stride. */
5897 stride = gfc_evaluate_now (stride, &block);
5898 gfc_conv_descriptor_stride_set (&block, desc,
5899 gfc_rank_cst[dim], stride);
5900
5901 /* Update offset. */
5902 offs = gfc_conv_descriptor_offset_get (desc);
65a9ca82
TB
5903 tmp = fold_build2_loc (input_location, MULT_EXPR,
5904 gfc_array_index_type, lbound, stride);
5905 offs = fold_build2_loc (input_location, MINUS_EXPR,
5906 gfc_array_index_type, offs, tmp);
99d821c0
DK
5907 offs = gfc_evaluate_now (offs, &block);
5908 gfc_conv_descriptor_offset_set (&block, desc, offs);
5909
5910 /* Update stride. */
5911 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
65a9ca82
TB
5912 stride = fold_build2_loc (input_location, MULT_EXPR,
5913 gfc_array_index_type, stride, tmp);
99d821c0
DK
5914 }
5915 }
5916 else
5917 {
5918 /* Bounds remapping. Just shift the lower bounds. */
5919
5920 gcc_assert (expr1->rank == expr2->rank);
5921
5922 for (dim = 0; dim < remap->u.ar.dimen; ++dim)
5923 {
5924 gfc_se lbound_se;
5925
5926 gcc_assert (remap->u.ar.start[dim]);
5927 gcc_assert (!remap->u.ar.end[dim]);
5928 gfc_init_se (&lbound_se, NULL);
5929 gfc_conv_expr (&lbound_se, remap->u.ar.start[dim]);
5930
5931 gfc_add_block_to_block (&block, &lbound_se.pre);
5932 gfc_conv_shift_descriptor_lbound (&block, desc,
5933 dim, lbound_se.expr);
5934 gfc_add_block_to_block (&block, &lbound_se.post);
5935 }
5936 }
5937 }
fb5bc08b
DK
5938
5939 /* Check string lengths if applicable. The check is only really added
5940 to the output code if -fbounds-check is enabled. */
5941 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
5942 {
5943 gcc_assert (expr2->ts.type == BT_CHARACTER);
5944 gcc_assert (strlen_lhs && strlen_rhs);
5945 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
5946 strlen_lhs, strlen_rhs, &block);
5947 }
5948
99d821c0
DK
5949 /* If rank remapping was done, check with -fcheck=bounds that
5950 the target is at least as large as the pointer. */
5951 if (rank_remap && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
5952 {
5953 tree lsize, rsize;
5954 tree fault;
5955 const char* msg;
5956
5957 lsize = gfc_conv_descriptor_size (lse.expr, expr1->rank);
5958 rsize = gfc_conv_descriptor_size (rse.expr, expr2->rank);
5959
5960 lsize = gfc_evaluate_now (lsize, &block);
5961 rsize = gfc_evaluate_now (rsize, &block);
65a9ca82
TB
5962 fault = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
5963 rsize, lsize);
99d821c0
DK
5964
5965 msg = _("Target of rank remapping is too small (%ld < %ld)");
5966 gfc_trans_runtime_check (true, false, fault, &block, &expr2->where,
5967 msg, rsize, lsize);
5968 }
5969
6de9cd9a 5970 gfc_add_block_to_block (&block, &lse.post);
99d821c0
DK
5971 if (rank_remap)
5972 gfc_add_block_to_block (&block, &rse.post);
6de9cd9a 5973 }
99d821c0 5974
6de9cd9a
DN
5975 return gfc_finish_block (&block);
5976}
5977
5978
5979/* Makes sure se is suitable for passing as a function string parameter. */
df2fba9e 5980/* TODO: Need to check all callers of this function. It may be abused. */
6de9cd9a
DN
5981
5982void
5983gfc_conv_string_parameter (gfc_se * se)
5984{
5985 tree type;
5986
5987 if (TREE_CODE (se->expr) == STRING_CST)
5988 {
d393bbd7
FXC
5989 type = TREE_TYPE (TREE_TYPE (se->expr));
5990 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
6de9cd9a
DN
5991 return;
5992 }
5993
d393bbd7 5994 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
6de9cd9a 5995 {
129c14bd 5996 if (TREE_CODE (se->expr) != INDIRECT_REF)
d393bbd7
FXC
5997 {
5998 type = TREE_TYPE (se->expr);
5999 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
6000 }
129c14bd
PT
6001 else
6002 {
6003 type = gfc_get_character_type_len (gfc_default_character_kind,
6004 se->string_length);
6005 type = build_pointer_type (type);
6006 se->expr = gfc_build_addr_expr (type, se->expr);
6007 }
6de9cd9a
DN
6008 }
6009
6e45f57b 6010 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
6de9cd9a
DN
6011}
6012
6013
6014/* Generate code for assignment of scalar variables. Includes character
2b56d6a4
TB
6015 strings and derived types with allocatable components.
6016 If you know that the LHS has no allocations, set dealloc to false. */
6de9cd9a
DN
6017
6018tree
5046aff5 6019gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
2b56d6a4 6020 bool l_is_temp, bool r_is_var, bool dealloc)
6de9cd9a 6021{
6de9cd9a 6022 stmtblock_t block;
5046aff5
PT
6023 tree tmp;
6024 tree cond;
6de9cd9a
DN
6025
6026 gfc_init_block (&block);
6027
5046aff5 6028 if (ts.type == BT_CHARACTER)
6de9cd9a 6029 {
06a54338
TB
6030 tree rlen = NULL;
6031 tree llen = NULL;
6de9cd9a 6032
06a54338
TB
6033 if (lse->string_length != NULL_TREE)
6034 {
6035 gfc_conv_string_parameter (lse);
6036 gfc_add_block_to_block (&block, &lse->pre);
6037 llen = lse->string_length;
6038 }
6de9cd9a 6039
06a54338
TB
6040 if (rse->string_length != NULL_TREE)
6041 {
6042 gcc_assert (rse->string_length != NULL_TREE);
6043 gfc_conv_string_parameter (rse);
6044 gfc_add_block_to_block (&block, &rse->pre);
6045 rlen = rse->string_length;
6046 }
6de9cd9a 6047
d393bbd7
FXC
6048 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
6049 rse->expr, ts.kind);
6de9cd9a 6050 }
bc21d315 6051 else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
5046aff5
PT
6052 {
6053 cond = NULL_TREE;
6054
6055 /* Are the rhs and the lhs the same? */
6056 if (r_is_var)
6057 {
65a9ca82
TB
6058 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
6059 gfc_build_addr_expr (NULL_TREE, lse->expr),
6060 gfc_build_addr_expr (NULL_TREE, rse->expr));
5046aff5
PT
6061 cond = gfc_evaluate_now (cond, &lse->pre);
6062 }
6063
6064 /* Deallocate the lhs allocated components as long as it is not
b8247b13
PT
6065 the same as the rhs. This must be done following the assignment
6066 to prevent deallocating data that could be used in the rhs
6067 expression. */
2b56d6a4 6068 if (!l_is_temp && dealloc)
5046aff5 6069 {
b8247b13 6070 tmp = gfc_evaluate_now (lse->expr, &lse->pre);
bc21d315 6071 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
5046aff5 6072 if (r_is_var)
c2255bc4
AH
6073 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
6074 tmp);
b8247b13 6075 gfc_add_expr_to_block (&lse->post, tmp);
5046aff5 6076 }
28114dad 6077
b8247b13
PT
6078 gfc_add_block_to_block (&block, &rse->pre);
6079 gfc_add_block_to_block (&block, &lse->pre);
5046aff5 6080
726a989a 6081 gfc_add_modify (&block, lse->expr,
5046aff5
PT
6082 fold_convert (TREE_TYPE (lse->expr), rse->expr));
6083
6084 /* Do a deep copy if the rhs is a variable, if it is not the
982186b1 6085 same as the lhs. */
5046aff5
PT
6086 if (r_is_var)
6087 {
bc21d315 6088 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
c2255bc4
AH
6089 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
6090 tmp);
5046aff5
PT
6091 gfc_add_expr_to_block (&block, tmp);
6092 }
5046aff5 6093 }
566df91a 6094 else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
fbe7af45
RG
6095 {
6096 gfc_add_block_to_block (&block, &lse->pre);
6097 gfc_add_block_to_block (&block, &rse->pre);
65a9ca82
TB
6098 tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
6099 TREE_TYPE (lse->expr), rse->expr);
fbe7af45
RG
6100 gfc_add_modify (&block, lse->expr, tmp);
6101 }
6de9cd9a
DN
6102 else
6103 {
6104 gfc_add_block_to_block (&block, &lse->pre);
6105 gfc_add_block_to_block (&block, &rse->pre);
6106
726a989a 6107 gfc_add_modify (&block, lse->expr,
fbe7af45 6108 fold_convert (TREE_TYPE (lse->expr), rse->expr));
6de9cd9a
DN
6109 }
6110
6111 gfc_add_block_to_block (&block, &lse->post);
6112 gfc_add_block_to_block (&block, &rse->post);
6113
6114 return gfc_finish_block (&block);
6115}
6116
6117
42488c1b
PT
6118/* There are quite a lot of restrictions on the optimisation in using an
6119 array function assign without a temporary. */
6de9cd9a 6120
42488c1b
PT
6121static bool
6122arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
6de9cd9a 6123{
2853e512
PT
6124 gfc_ref * ref;
6125 bool seen_array_ref;
a61a36ab 6126 bool c = false;
42488c1b 6127 gfc_symbol *sym = expr1->symtree->n.sym;
6de9cd9a
DN
6128
6129 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
6130 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
42488c1b 6131 return true;
6de9cd9a 6132
42488c1b
PT
6133 /* Elemental functions are scalarized so that they don't need a
6134 temporary in gfc_trans_assignment_1, so return a true. Otherwise,
6135 they would need special treatment in gfc_trans_arrayfunc_assign. */
c4abe010
EE
6136 if (expr2->value.function.esym != NULL
6137 && expr2->value.function.esym->attr.elemental)
42488c1b 6138 return true;
6de9cd9a 6139
42488c1b 6140 /* Need a temporary if rhs is not FULL or a contiguous section. */
a61a36ab 6141 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
42488c1b 6142 return true;
a61a36ab 6143
42488c1b 6144 /* Need a temporary if EXPR1 can't be expressed as a descriptor. */
7a70c12d 6145 if (gfc_ref_needs_temporary_p (expr1->ref))
42488c1b 6146 return true;
7a70c12d 6147
56ee2f5a
TB
6148 /* Functions returning pointers or allocatables need temporaries. */
6149 c = expr2->value.function.esym
6150 ? (expr2->value.function.esym->attr.pointer
6151 || expr2->value.function.esym->attr.allocatable)
6152 : (expr2->symtree->n.sym->attr.pointer
6153 || expr2->symtree->n.sym->attr.allocatable);
6154 if (c)
42488c1b 6155 return true;
5b0b7251 6156
bab651ad
PT
6157 /* Character array functions need temporaries unless the
6158 character lengths are the same. */
6159 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
6160 {
bc21d315
JW
6161 if (expr1->ts.u.cl->length == NULL
6162 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
42488c1b 6163 return true;
bab651ad 6164
bc21d315
JW
6165 if (expr2->ts.u.cl->length == NULL
6166 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
42488c1b 6167 return true;
bab651ad 6168
bc21d315
JW
6169 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
6170 expr2->ts.u.cl->length->value.integer) != 0)
42488c1b 6171 return true;
bab651ad
PT
6172 }
6173
2853e512
PT
6174 /* Check that no LHS component references appear during an array
6175 reference. This is needed because we do not have the means to
6176 span any arbitrary stride with an array descriptor. This check
6177 is not needed for the rhs because the function result has to be
6178 a complete type. */
6179 seen_array_ref = false;
6180 for (ref = expr1->ref; ref; ref = ref->next)
6181 {
6182 if (ref->type == REF_ARRAY)
6183 seen_array_ref= true;
6184 else if (ref->type == REF_COMPONENT && seen_array_ref)
42488c1b 6185 return true;
2853e512
PT
6186 }
6187
6de9cd9a 6188 /* Check for a dependency. */
1524f80b
RS
6189 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
6190 expr2->value.function.esym,
2b0bd714
MM
6191 expr2->value.function.actual,
6192 NOT_ELEMENTAL))
42488c1b
PT
6193 return true;
6194
6195 /* If we have reached here with an intrinsic function, we do not
7097b041
PT
6196 need a temporary except in the particular case that reallocation
6197 on assignment is active and the lhs is allocatable and a target. */
42488c1b 6198 if (expr2->value.function.isym)
7097b041
PT
6199 return (gfc_option.flag_realloc_lhs
6200 && sym->attr.allocatable
6201 && sym->attr.target);
42488c1b
PT
6202
6203 /* If the LHS is a dummy, we need a temporary if it is not
6204 INTENT(OUT). */
6205 if (sym->attr.dummy && sym->attr.intent != INTENT_OUT)
6206 return true;
6207
f1f39033
PT
6208 /* If the lhs has been host_associated, is in common, a pointer or is
6209 a target and the function is not using a RESULT variable, aliasing
6210 can occur and a temporary is needed. */
6211 if ((sym->attr.host_assoc
6212 || sym->attr.in_common
6213 || sym->attr.pointer
6214 || sym->attr.cray_pointee
6215 || sym->attr.target)
6216 && expr2->symtree != NULL
6217 && expr2->symtree->n.sym == expr2->symtree->n.sym->result)
6218 return true;
6219
42488c1b
PT
6220 /* A PURE function can unconditionally be called without a temporary. */
6221 if (expr2->value.function.esym != NULL
6222 && expr2->value.function.esym->attr.pure)
6223 return false;
6224
f1f39033
PT
6225 /* Implicit_pure functions are those which could legally be declared
6226 to be PURE. */
6227 if (expr2->value.function.esym != NULL
6228 && expr2->value.function.esym->attr.implicit_pure)
6229 return false;
42488c1b
PT
6230
6231 if (!sym->attr.use_assoc
6232 && !sym->attr.in_common
6233 && !sym->attr.pointer
6234 && !sym->attr.target
f1f39033 6235 && !sym->attr.cray_pointee
42488c1b
PT
6236 && expr2->value.function.esym)
6237 {
6238 /* A temporary is not needed if the function is not contained and
6239 the variable is local or host associated and not a pointer or
6240 a target. */
6241 if (!expr2->value.function.esym->attr.contained)
6242 return false;
6243
022e30c0
PT
6244 /* A temporary is not needed if the lhs has never been host
6245 associated and the procedure is contained. */
6246 else if (!sym->attr.host_assoc)
6247 return false;
6248
42488c1b
PT
6249 /* A temporary is not needed if the variable is local and not
6250 a pointer, a target or a result. */
6251 if (sym->ns->parent
6252 && expr2->value.function.esym->ns == sym->ns->parent)
6253 return false;
6254 }
6255
6256 /* Default to temporary use. */
6257 return true;
6258}
6259
6260
597553ab
PT
6261/* Provide the loop info so that the lhs descriptor can be built for
6262 reallocatable assignments from extrinsic function calls. */
6263
6264static void
83799a47
MM
6265realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
6266 gfc_loopinfo *loop)
597553ab 6267{
597553ab
PT
6268 /* Signal that the function call should not be made by
6269 gfc_conv_loop_setup. */
6270 se->ss->is_alloc_lhs = 1;
83799a47
MM
6271 gfc_init_loopinfo (loop);
6272 gfc_add_ss_to_loop (loop, *ss);
6273 gfc_add_ss_to_loop (loop, se->ss);
6274 gfc_conv_ss_startstride (loop);
6275 gfc_conv_loop_setup (loop, where);
6276 gfc_copy_loopinfo_to_se (se, loop);
6277 gfc_add_block_to_block (&se->pre, &loop->pre);
6278 gfc_add_block_to_block (&se->pre, &loop->post);
597553ab
PT
6279 se->ss->is_alloc_lhs = 0;
6280}
6281
6282
7de7ae18 6283/* For assignment to a reallocatable lhs from intrinsic functions,
12df8d01
PT
6284 replace the se.expr (ie. the result) with a temporary descriptor.
6285 Null the data field so that the library allocates space for the
6286 result. Free the data of the original descriptor after the function,
6287 in case it appears in an argument expression and transfer the
6288 result to the original descriptor. */
6289
597553ab 6290static void
b972d95b 6291fcncall_realloc_result (gfc_se *se, int rank)
597553ab
PT
6292{
6293 tree desc;
12df8d01 6294 tree res_desc;
597553ab 6295 tree tmp;
b972d95b 6296 tree offset;
7de7ae18 6297 tree zero_cond;
b972d95b 6298 int n;
597553ab 6299
12df8d01
PT
6300 /* Use the allocation done by the library. Substitute the lhs
6301 descriptor with a copy, whose data field is nulled.*/
597553ab 6302 desc = build_fold_indirect_ref_loc (input_location, se->expr);
5cda350e
PT
6303 if (POINTER_TYPE_P (TREE_TYPE (desc)))
6304 desc = build_fold_indirect_ref_loc (input_location, desc);
7de7ae18 6305
7097b041
PT
6306 /* Unallocated, the descriptor does not have a dtype. */
6307 tmp = gfc_conv_descriptor_dtype (desc);
6308 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
7de7ae18 6309
12df8d01
PT
6310 res_desc = gfc_evaluate_now (desc, &se->pre);
6311 gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
6312 se->expr = gfc_build_addr_expr (TREE_TYPE (se->expr), res_desc);
6313
7de7ae18 6314 /* Free the lhs after the function call and copy the result data to
b972d95b 6315 the lhs descriptor. */
597553ab 6316 tmp = gfc_conv_descriptor_data_get (desc);
7de7ae18
PT
6317 zero_cond = fold_build2_loc (input_location, EQ_EXPR,
6318 boolean_type_node, tmp,
6319 build_int_cst (TREE_TYPE (tmp), 0));
6320 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
597553ab 6321 tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
12df8d01 6322 gfc_add_expr_to_block (&se->post, tmp);
b972d95b 6323
7de7ae18
PT
6324 tmp = gfc_conv_descriptor_data_get (res_desc);
6325 gfc_conv_descriptor_data_set (&se->post, desc, tmp);
458842fb 6326
7de7ae18
PT
6327 /* Check that the shapes are the same between lhs and expression. */
6328 for (n = 0 ; n < rank; n++)
6329 {
6330 tree tmp1;
6331 tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
6332 tmp1 = gfc_conv_descriptor_lbound_get (res_desc, gfc_rank_cst[n]);
6333 tmp = fold_build2_loc (input_location, MINUS_EXPR,
6334 gfc_array_index_type, tmp, tmp1);
6335 tmp1 = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
6336 tmp = fold_build2_loc (input_location, MINUS_EXPR,
6337 gfc_array_index_type, tmp, tmp1);
6338 tmp1 = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
6339 tmp = fold_build2_loc (input_location, PLUS_EXPR,
6340 gfc_array_index_type, tmp, tmp1);
6341 tmp = fold_build2_loc (input_location, NE_EXPR,
6342 boolean_type_node, tmp,
6343 gfc_index_zero_node);
6344 tmp = gfc_evaluate_now (tmp, &se->post);
6345 zero_cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
6346 boolean_type_node, tmp,
6347 zero_cond);
6348 }
6349
6350 /* 'zero_cond' being true is equal to lhs not being allocated or the
6351 shapes being different. */
6352 zero_cond = gfc_evaluate_now (zero_cond, &se->post);
6353
6354 /* Now reset the bounds returned from the function call to bounds based
6355 on the lhs lbounds, except where the lhs is not allocated or the shapes
6356 of 'variable and 'expr' are different. Set the offset accordingly. */
6357 offset = gfc_index_zero_node;
b972d95b
PT
6358 for (n = 0 ; n < rank; n++)
6359 {
7de7ae18
PT
6360 tree lbound;
6361
6362 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
6363 lbound = fold_build3_loc (input_location, COND_EXPR,
6364 gfc_array_index_type, zero_cond,
6365 gfc_index_one_node, lbound);
6366 lbound = gfc_evaluate_now (lbound, &se->post);
6367
6368 tmp = gfc_conv_descriptor_ubound_get (res_desc, gfc_rank_cst[n]);
b972d95b 6369 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7de7ae18 6370 gfc_array_index_type, tmp, lbound);
b972d95b 6371 gfc_conv_descriptor_lbound_set (&se->post, desc,
7de7ae18 6372 gfc_rank_cst[n], lbound);
b972d95b
PT
6373 gfc_conv_descriptor_ubound_set (&se->post, desc,
6374 gfc_rank_cst[n], tmp);
6375
5d24176e
TB
6376 /* Set stride and accumulate the offset. */
6377 tmp = gfc_conv_descriptor_stride_get (res_desc, gfc_rank_cst[n]);
6378 gfc_conv_descriptor_stride_set (&se->post, desc,
6379 gfc_rank_cst[n], tmp);
7de7ae18 6380 tmp = fold_build2_loc (input_location, MULT_EXPR,
5d24176e 6381 gfc_array_index_type, lbound, tmp);
458842fb 6382 offset = fold_build2_loc (input_location, MINUS_EXPR,
5d24176e 6383 gfc_array_index_type, offset, tmp);
458842fb 6384 offset = gfc_evaluate_now (offset, &se->post);
b972d95b 6385 }
458842fb 6386
b972d95b 6387 gfc_conv_descriptor_offset_set (&se->post, desc, offset);
597553ab
PT
6388}
6389
6390
6391
42488c1b
PT
6392/* Try to translate array(:) = func (...), where func is a transformational
6393 array function, without using a temporary. Returns NULL if this isn't the
6394 case. */
6395
6396static tree
6397gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
6398{
6399 gfc_se se;
6400 gfc_ss *ss;
6401 gfc_component *comp = NULL;
83799a47 6402 gfc_loopinfo loop;
42488c1b
PT
6403
6404 if (arrayfunc_assign_needs_temporary (expr1, expr2))
6de9cd9a
DN
6405 return NULL;
6406
6407 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
6408 functions. */
6e45f57b 6409 gcc_assert (expr2->value.function.isym
f64edc8b 6410 || (gfc_is_proc_ptr_comp (expr2, &comp)
37a40b53 6411 && comp && comp->attr.dimension)
c74b74a8 6412 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
37a40b53 6413 && expr2->value.function.esym->result->attr.dimension));
6de9cd9a
DN
6414
6415 ss = gfc_walk_expr (expr1);
6e45f57b 6416 gcc_assert (ss != gfc_ss_terminator);
6de9cd9a
DN
6417 gfc_init_se (&se, NULL);
6418 gfc_start_block (&se.pre);
6419 se.want_pointer = 1;
6420
f7172b55 6421 gfc_conv_array_parameter (&se, expr1, ss, false, NULL, NULL, NULL);
6de9cd9a 6422
40c32948
PT
6423 if (expr1->ts.type == BT_DERIVED
6424 && expr1->ts.u.derived->attr.alloc_comp)
6425 {
6426 tree tmp;
6427 tmp = gfc_deallocate_alloc_comp (expr1->ts.u.derived, se.expr,
6428 expr1->rank);
6429 gfc_add_expr_to_block (&se.pre, tmp);
6430 }
6431
6de9cd9a
DN
6432 se.direct_byref = 1;
6433 se.ss = gfc_walk_expr (expr2);
6e45f57b 6434 gcc_assert (se.ss != gfc_ss_terminator);
597553ab
PT
6435
6436 /* Reallocate on assignment needs the loopinfo for extrinsic functions.
6437 This is signalled to gfc_conv_procedure_call by setting is_alloc_lhs.
6438 Clearly, this cannot be done for an allocatable function result, since
6439 the shape of the result is unknown and, in any case, the function must
6440 correctly take care of the reallocation internally. For intrinsic
6441 calls, the array data is freed and the library takes care of allocation.
6442 TODO: Add logic of trans-array.c: gfc_alloc_allocatable_for_assignment
6443 to the library. */
6444 if (gfc_option.flag_realloc_lhs
6445 && gfc_is_reallocatable_lhs (expr1)
6446 && !gfc_expr_attr (expr1).codimension
6447 && !gfc_is_coindexed (expr1)
6448 && !(expr2->value.function.esym
6449 && expr2->value.function.esym->result->attr.allocatable))
6450 {
6451 if (!expr2->value.function.isym)
6452 {
83799a47 6453 realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
597553ab
PT
6454 ss->is_alloc_lhs = 1;
6455 }
6456 else
b972d95b 6457 fcncall_realloc_result (&se, expr1->rank);
597553ab
PT
6458 }
6459
6de9cd9a 6460 gfc_conv_function_expr (&se, expr2);
6de9cd9a
DN
6461 gfc_add_block_to_block (&se.pre, &se.post);
6462
6463 return gfc_finish_block (&se.pre);
6464}
6465
6822a10d
RS
6466
6467/* Try to efficiently translate array(:) = 0. Return NULL if this
6468 can't be done. */
6469
6470static tree
6471gfc_trans_zero_assign (gfc_expr * expr)
6472{
6473 tree dest, len, type;
5039610b 6474 tree tmp;
6822a10d
RS
6475 gfc_symbol *sym;
6476
6477 sym = expr->symtree->n.sym;
6478 dest = gfc_get_symbol_decl (sym);
6479
6480 type = TREE_TYPE (dest);
6481 if (POINTER_TYPE_P (type))
6482 type = TREE_TYPE (type);
6483 if (!GFC_ARRAY_TYPE_P (type))
6484 return NULL_TREE;
6485
6486 /* Determine the length of the array. */
6487 len = GFC_TYPE_ARRAY_SIZE (type);
6488 if (!len || TREE_CODE (len) != INTEGER_CST)
6489 return NULL_TREE;
6490
7c57b2f1 6491 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
65a9ca82
TB
6492 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
6493 fold_convert (gfc_array_index_type, tmp));
6822a10d 6494
bfa31dad
RG
6495 /* If we are zeroing a local array avoid taking its address by emitting
6496 a = {} instead. */
6822a10d 6497 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
5d44e5c8
TB
6498 return build2_loc (input_location, MODIFY_EXPR, void_type_node,
6499 dest, build_constructor (TREE_TYPE (dest), NULL));
bfa31dad
RG
6500
6501 /* Convert arguments to the correct types. */
6502 dest = fold_convert (pvoid_type_node, dest);
6822a10d
RS
6503 len = fold_convert (size_type_node, len);
6504
6505 /* Construct call to __builtin_memset. */
db3927fb 6506 tmp = build_call_expr_loc (input_location,
e79983f4
MM
6507 builtin_decl_explicit (BUILT_IN_MEMSET),
6508 3, dest, integer_zero_node, len);
6822a10d
RS
6509 return fold_convert (void_type_node, tmp);
6510}
6de9cd9a 6511
b01e2f88
RS
6512
6513/* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
6514 that constructs the call to __builtin_memcpy. */
6515
12f681a0 6516tree
b01e2f88
RS
6517gfc_build_memcpy_call (tree dst, tree src, tree len)
6518{
5039610b 6519 tree tmp;
b01e2f88
RS
6520
6521 /* Convert arguments to the correct types. */
6522 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
6523 dst = gfc_build_addr_expr (pvoid_type_node, dst);
6524 else
6525 dst = fold_convert (pvoid_type_node, dst);
6526
6527 if (!POINTER_TYPE_P (TREE_TYPE (src)))
6528 src = gfc_build_addr_expr (pvoid_type_node, src);
6529 else
6530 src = fold_convert (pvoid_type_node, src);
6531
6532 len = fold_convert (size_type_node, len);
6533
6534 /* Construct call to __builtin_memcpy. */
db3927fb 6535 tmp = build_call_expr_loc (input_location,
e79983f4
MM
6536 builtin_decl_explicit (BUILT_IN_MEMCPY),
6537 3, dst, src, len);
b01e2f88
RS
6538 return fold_convert (void_type_node, tmp);
6539}
6540
6541
a3018753
RS
6542/* Try to efficiently translate dst(:) = src(:). Return NULL if this
6543 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
6544 source/rhs, both are gfc_full_array_ref_p which have been checked for
6545 dependencies. */
6de9cd9a 6546
a3018753
RS
6547static tree
6548gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
6549{
6550 tree dst, dlen, dtype;
6551 tree src, slen, stype;
7c57b2f1 6552 tree tmp;
a3018753
RS
6553
6554 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
6555 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
6556
6557 dtype = TREE_TYPE (dst);
6558 if (POINTER_TYPE_P (dtype))
6559 dtype = TREE_TYPE (dtype);
6560 stype = TREE_TYPE (src);
6561 if (POINTER_TYPE_P (stype))
6562 stype = TREE_TYPE (stype);
6563
6564 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
6565 return NULL_TREE;
6566
6567 /* Determine the lengths of the arrays. */
6568 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
6569 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
6570 return NULL_TREE;
7c57b2f1 6571 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
65a9ca82
TB
6572 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6573 dlen, fold_convert (gfc_array_index_type, tmp));
a3018753
RS
6574
6575 slen = GFC_TYPE_ARRAY_SIZE (stype);
6576 if (!slen || TREE_CODE (slen) != INTEGER_CST)
6577 return NULL_TREE;
7c57b2f1 6578 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
65a9ca82
TB
6579 slen = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6580 slen, fold_convert (gfc_array_index_type, tmp));
a3018753
RS
6581
6582 /* Sanity check that they are the same. This should always be
6583 the case, as we should already have checked for conformance. */
6584 if (!tree_int_cst_equal (slen, dlen))
6585 return NULL_TREE;
6586
b01e2f88
RS
6587 return gfc_build_memcpy_call (dst, src, dlen);
6588}
a3018753 6589
a3018753 6590
b01e2f88
RS
6591/* Try to efficiently translate array(:) = (/ ... /). Return NULL if
6592 this can't be done. EXPR1 is the destination/lhs for which
6593 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
a3018753 6594
b01e2f88
RS
6595static tree
6596gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
6597{
6598 unsigned HOST_WIDE_INT nelem;
6599 tree dst, dtype;
6600 tree src, stype;
6601 tree len;
7c57b2f1 6602 tree tmp;
b01e2f88
RS
6603
6604 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
6605 if (nelem == 0)
6606 return NULL_TREE;
6607
6608 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
6609 dtype = TREE_TYPE (dst);
6610 if (POINTER_TYPE_P (dtype))
6611 dtype = TREE_TYPE (dtype);
6612 if (!GFC_ARRAY_TYPE_P (dtype))
6613 return NULL_TREE;
6614
6615 /* Determine the lengths of the array. */
6616 len = GFC_TYPE_ARRAY_SIZE (dtype);
6617 if (!len || TREE_CODE (len) != INTEGER_CST)
6618 return NULL_TREE;
6619
6620 /* Confirm that the constructor is the same size. */
6621 if (compare_tree_int (len, nelem) != 0)
6622 return NULL_TREE;
6623
7c57b2f1 6624 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
65a9ca82
TB
6625 len = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, len,
6626 fold_convert (gfc_array_index_type, tmp));
b01e2f88
RS
6627
6628 stype = gfc_typenode_for_spec (&expr2->ts);
6629 src = gfc_build_constant_array_constructor (expr2, stype);
6630
6631 stype = TREE_TYPE (src);
6632 if (POINTER_TYPE_P (stype))
6633 stype = TREE_TYPE (stype);
6634
6635 return gfc_build_memcpy_call (dst, src, len);
a3018753
RS
6636}
6637
6638
0ae6242f
MM
6639/* Tells whether the expression is to be treated as a variable reference. */
6640
6641static bool
6642expr_is_variable (gfc_expr *expr)
6643{
6644 gfc_expr *arg;
6645
6646 if (expr->expr_type == EXPR_VARIABLE)
6647 return true;
6648
6649 arg = gfc_get_noncopying_intrinsic_argument (expr);
6650 if (arg)
6651 {
6652 gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
6653 return expr_is_variable (arg);
6654 }
6655
6656 return false;
6657}
6658
6659
8d51f26f
PT
6660/* Is the lhs OK for automatic reallocation? */
6661
6662static bool
6663is_scalar_reallocatable_lhs (gfc_expr *expr)
6664{
6665 gfc_ref * ref;
6666
6667 /* An allocatable variable with no reference. */
6668 if (expr->symtree->n.sym->attr.allocatable
6669 && !expr->ref)
6670 return true;
6671
6672 /* All that can be left are allocatable components. */
6673 if ((expr->symtree->n.sym->ts.type != BT_DERIVED
6674 && expr->symtree->n.sym->ts.type != BT_CLASS)
6675 || !expr->symtree->n.sym->ts.u.derived->attr.alloc_comp)
6676 return false;
6677
6678 /* Find an allocatable component ref last. */
6679 for (ref = expr->ref; ref; ref = ref->next)
6680 if (ref->type == REF_COMPONENT
6681 && !ref->next
6682 && ref->u.c.component->attr.allocatable)
6683 return true;
6684
6685 return false;
6686}
6687
6688
6689/* Allocate or reallocate scalar lhs, as necessary. */
6690
6691static void
6692alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
6693 tree string_length,
6694 gfc_expr *expr1,
6695 gfc_expr *expr2)
6696
6697{
6698 tree cond;
6699 tree tmp;
6700 tree size;
6701 tree size_in_bytes;
6702 tree jump_label1;
6703 tree jump_label2;
6704 gfc_se lse;
6705
6706 if (!expr1 || expr1->rank)
6707 return;
6708
6709 if (!expr2 || expr2->rank)
6710 return;
6711
6712 /* Since this is a scalar lhs, we can afford to do this. That is,
6713 there is no risk of side effects being repeated. */
6714 gfc_init_se (&lse, NULL);
6715 lse.want_pointer = 1;
6716 gfc_conv_expr (&lse, expr1);
6717
6718 jump_label1 = gfc_build_label_decl (NULL_TREE);
6719 jump_label2 = gfc_build_label_decl (NULL_TREE);
6720
6721 /* Do the allocation if the lhs is NULL. Otherwise go to label 1. */
6722 tmp = build_int_cst (TREE_TYPE (lse.expr), 0);
6723 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6724 lse.expr, tmp);
6725 tmp = build3_v (COND_EXPR, cond,
6726 build1_v (GOTO_EXPR, jump_label1),
6727 build_empty_stmt (input_location));
6728 gfc_add_expr_to_block (block, tmp);
6729
6730 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
6731 {
6732 /* Use the rhs string length and the lhs element size. */
6733 size = string_length;
6734 tmp = TREE_TYPE (gfc_typenode_for_spec (&expr1->ts));
6735 tmp = TYPE_SIZE_UNIT (tmp);
6736 size_in_bytes = fold_build2_loc (input_location, MULT_EXPR,
6737 TREE_TYPE (tmp), tmp,
6738 fold_convert (TREE_TYPE (tmp), size));
6739 }
6740 else
6741 {
6742 /* Otherwise use the length in bytes of the rhs. */
6743 size = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
6744 size_in_bytes = size;
6745 }
6746
4df0f7da
TB
6747 if (expr1->ts.type == BT_DERIVED && expr1->ts.u.derived->attr.alloc_comp)
6748 {
6749 tmp = build_call_expr_loc (input_location,
6750 builtin_decl_explicit (BUILT_IN_CALLOC),
6751 2, build_one_cst (size_type_node),
6752 size_in_bytes);
6753 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
6754 gfc_add_modify (block, lse.expr, tmp);
6755 }
6756 else
6757 {
6758 tmp = build_call_expr_loc (input_location,
6759 builtin_decl_explicit (BUILT_IN_MALLOC),
6760 1, size_in_bytes);
6761 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
6762 gfc_add_modify (block, lse.expr, tmp);
6763 }
6764
8d51f26f
PT
6765 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
6766 {
6767 /* Deferred characters need checking for lhs and rhs string
6768 length. Other deferred parameter variables will have to
6769 come here too. */
6770 tmp = build1_v (GOTO_EXPR, jump_label2);
6771 gfc_add_expr_to_block (block, tmp);
6772 }
6773 tmp = build1_v (LABEL_EXPR, jump_label1);
6774 gfc_add_expr_to_block (block, tmp);
6775
6776 /* For a deferred length character, reallocate if lengths of lhs and
6777 rhs are different. */
6778 if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
6779 {
6780 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
6781 expr1->ts.u.cl->backend_decl, size);
6782 /* Jump past the realloc if the lengths are the same. */
6783 tmp = build3_v (COND_EXPR, cond,
6784 build1_v (GOTO_EXPR, jump_label2),
6785 build_empty_stmt (input_location));
6786 gfc_add_expr_to_block (block, tmp);
6787 tmp = build_call_expr_loc (input_location,
e79983f4
MM
6788 builtin_decl_explicit (BUILT_IN_REALLOC),
6789 2, fold_convert (pvoid_type_node, lse.expr),
8d51f26f
PT
6790 size_in_bytes);
6791 tmp = fold_convert (TREE_TYPE (lse.expr), tmp);
6792 gfc_add_modify (block, lse.expr, tmp);
6793 tmp = build1_v (LABEL_EXPR, jump_label2);
6794 gfc_add_expr_to_block (block, tmp);
6795
6796 /* Update the lhs character length. */
6797 size = string_length;
6798 gfc_add_modify (block, expr1->ts.u.cl->backend_decl, size);
6799 }
6800}
6801
6802
a3018753 6803/* Subroutine of gfc_trans_assignment that actually scalarizes the
2b56d6a4
TB
6804 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
6805 init_flag indicates initialization expressions and dealloc that no
6806 deallocate prior assignment is needed (if in doubt, set true). */
a3018753
RS
6807
6808static tree
2b56d6a4
TB
6809gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
6810 bool dealloc)
6de9cd9a
DN
6811{
6812 gfc_se lse;
6813 gfc_se rse;
6814 gfc_ss *lss;
6815 gfc_ss *lss_section;
6816 gfc_ss *rss;
6817 gfc_loopinfo loop;
6818 tree tmp;
6819 stmtblock_t block;
6820 stmtblock_t body;
5046aff5 6821 bool l_is_temp;
2c69d527 6822 bool scalar_to_array;
dafdf269 6823 bool def_clen_func;
bf0d171a 6824 tree string_length;
3d03ead0 6825 int n;
6de9cd9a 6826
6de9cd9a
DN
6827 /* Assignment of the form lhs = rhs. */
6828 gfc_start_block (&block);
6829
6830 gfc_init_se (&lse, NULL);
6831 gfc_init_se (&rse, NULL);
6832
6833 /* Walk the lhs. */
6834 lss = gfc_walk_expr (expr1);
597553ab
PT
6835 if (gfc_is_reallocatable_lhs (expr1)
6836 && !(expr2->expr_type == EXPR_FUNCTION
6837 && expr2->value.function.isym != NULL))
6838 lss->is_alloc_lhs = 1;
6de9cd9a
DN
6839 rss = NULL;
6840 if (lss != gfc_ss_terminator)
6841 {
6842 /* The assignment needs scalarization. */
6843 lss_section = lss;
6844
6845 /* Find a non-scalar SS from the lhs. */
6846 while (lss_section != gfc_ss_terminator
bcc4d4e0 6847 && lss_section->info->type != GFC_SS_SECTION)
6de9cd9a
DN
6848 lss_section = lss_section->next;
6849
6e45f57b 6850 gcc_assert (lss_section != gfc_ss_terminator);
6de9cd9a
DN
6851
6852 /* Initialize the scalarizer. */
6853 gfc_init_loopinfo (&loop);
6854
6855 /* Walk the rhs. */
6856 rss = gfc_walk_expr (expr2);
6857 if (rss == gfc_ss_terminator)
26f77530
MM
6858 /* The rhs is scalar. Add a ss for the expression. */
6859 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
6860
6de9cd9a
DN
6861 /* Associate the SS with the loop. */
6862 gfc_add_ss_to_loop (&loop, lss);
6863 gfc_add_ss_to_loop (&loop, rss);
6864
6865 /* Calculate the bounds of the scalarization. */
6866 gfc_conv_ss_startstride (&loop);
3d03ead0 6867 /* Enable loop reversal. */
aed5574e
PT
6868 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
6869 loop.reverse[n] = GFC_ENABLE_REVERSE;
6de9cd9a 6870 /* Resolve any data dependencies in the statement. */
eca18fb4 6871 gfc_conv_resolve_dependencies (&loop, lss, rss);
6de9cd9a 6872 /* Setup the scalarizing loops. */
bdfd2ff0 6873 gfc_conv_loop_setup (&loop, &expr2->where);
6de9cd9a
DN
6874
6875 /* Setup the gfc_se structures. */
6876 gfc_copy_loopinfo_to_se (&lse, &loop);
6877 gfc_copy_loopinfo_to_se (&rse, &loop);
6878
6879 rse.ss = rss;
6880 gfc_mark_ss_chain_used (rss, 1);
6881 if (loop.temp_ss == NULL)
6882 {
6883 lse.ss = lss;
6884 gfc_mark_ss_chain_used (lss, 1);
6885 }
6886 else
6887 {
6888 lse.ss = loop.temp_ss;
6889 gfc_mark_ss_chain_used (lss, 3);
6890 gfc_mark_ss_chain_used (loop.temp_ss, 3);
6891 }
6892
c26dffff
JJ
6893 /* Allow the scalarizer to workshare array assignments. */
6894 if ((ompws_flags & OMPWS_WORKSHARE_FLAG) && loop.temp_ss == NULL)
6895 ompws_flags |= OMPWS_SCALARIZER_WS;
6896
6de9cd9a
DN
6897 /* Start the scalarized loop body. */
6898 gfc_start_scalarized_body (&loop, &body);
6899 }
6900 else
6901 gfc_init_block (&body);
6902
5046aff5
PT
6903 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
6904
6de9cd9a
DN
6905 /* Translate the expression. */
6906 gfc_conv_expr (&rse, expr2);
6907
bf0d171a
PT
6908 /* Stabilize a string length for temporaries. */
6909 if (expr2->ts.type == BT_CHARACTER)
6910 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
6911 else
6912 string_length = NULL_TREE;
6913
5046aff5 6914 if (l_is_temp)
6de9cd9a
DN
6915 {
6916 gfc_conv_tmp_array_ref (&lse);
bf0d171a
PT
6917 if (expr2->ts.type == BT_CHARACTER)
6918 lse.string_length = string_length;
6de9cd9a
DN
6919 }
6920 else
6921 gfc_conv_expr (&lse, expr1);
ec09945c 6922
2c69d527
PT
6923 /* Assignments of scalar derived types with allocatable components
6924 to arrays must be done with a deep copy and the rhs temporary
6925 must have its components deallocated afterwards. */
6926 scalar_to_array = (expr2->ts.type == BT_DERIVED
bc21d315 6927 && expr2->ts.u.derived->attr.alloc_comp
0ae6242f 6928 && !expr_is_variable (expr2)
2c69d527
PT
6929 && !gfc_is_constant_expr (expr2)
6930 && expr1->rank && !expr2->rank);
2b56d6a4 6931 if (scalar_to_array && dealloc)
2c69d527 6932 {
bc21d315 6933 tmp = gfc_deallocate_alloc_comp (expr2->ts.u.derived, rse.expr, 0);
2c69d527
PT
6934 gfc_add_expr_to_block (&loop.post, tmp);
6935 }
6936
8d51f26f
PT
6937 /* For a deferred character length function, the function call must
6938 happen before the (re)allocation of the lhs, otherwise the character
6939 length of the result is not known. */
dafdf269
PT
6940 def_clen_func = (((expr2->expr_type == EXPR_FUNCTION)
6941 || (expr2->expr_type == EXPR_COMPCALL)
6942 || (expr2->expr_type == EXPR_PPC))
6943 && expr2->ts.deferred);
8d51f26f 6944 if (gfc_option.flag_realloc_lhs
8d51f26f 6945 && expr2->ts.type == BT_CHARACTER
dafdf269
PT
6946 && (def_clen_func || expr2->expr_type == EXPR_OP)
6947 && expr1->ts.deferred)
8d51f26f
PT
6948 gfc_add_block_to_block (&block, &rse.pre);
6949
6b591ec0
PT
6950 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
6951 l_is_temp || init_flag,
73039f89
TB
6952 expr_is_variable (expr2) || scalar_to_array
6953 || expr2->expr_type == EXPR_ARRAY, dealloc);
6de9cd9a
DN
6954 gfc_add_expr_to_block (&body, tmp);
6955
6956 if (lss == gfc_ss_terminator)
6957 {
8d51f26f
PT
6958 /* F2003: Add the code for reallocation on assignment. */
6959 if (gfc_option.flag_realloc_lhs
6960 && is_scalar_reallocatable_lhs (expr1))
6961 alloc_scalar_allocatable_for_assignment (&block, rse.string_length,
6962 expr1, expr2);
6963
6de9cd9a
DN
6964 /* Use the scalar assignment as is. */
6965 gfc_add_block_to_block (&block, &body);
6966 }
6967 else
6968 {
6e45f57b
PB
6969 gcc_assert (lse.ss == gfc_ss_terminator
6970 && rse.ss == gfc_ss_terminator);
6de9cd9a 6971
5046aff5 6972 if (l_is_temp)
6de9cd9a
DN
6973 {
6974 gfc_trans_scalarized_loop_boundary (&loop, &body);
6975
6976 /* We need to copy the temporary to the actual lhs. */
6977 gfc_init_se (&lse, NULL);
6978 gfc_init_se (&rse, NULL);
6979 gfc_copy_loopinfo_to_se (&lse, &loop);
6980 gfc_copy_loopinfo_to_se (&rse, &loop);
6981
6982 rse.ss = loop.temp_ss;
6983 lse.ss = lss;
6984
6985 gfc_conv_tmp_array_ref (&rse);
6de9cd9a
DN
6986 gfc_conv_expr (&lse, expr1);
6987
6e45f57b
PB
6988 gcc_assert (lse.ss == gfc_ss_terminator
6989 && rse.ss == gfc_ss_terminator);
6de9cd9a 6990
bf0d171a
PT
6991 if (expr2->ts.type == BT_CHARACTER)
6992 rse.string_length = string_length;
6993
6b591ec0 6994 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
2b56d6a4 6995 false, false, dealloc);
6de9cd9a
DN
6996 gfc_add_expr_to_block (&body, tmp);
6997 }
5046aff5 6998
8d51f26f 6999 /* F2003: Allocate or reallocate lhs of allocatable array. */
597553ab
PT
7000 if (gfc_option.flag_realloc_lhs
7001 && gfc_is_reallocatable_lhs (expr1)
7002 && !gfc_expr_attr (expr1).codimension
7003 && !gfc_is_coindexed (expr1))
7004 {
c26dffff 7005 ompws_flags &= ~OMPWS_SCALARIZER_WS;
597553ab
PT
7006 tmp = gfc_alloc_allocatable_for_assignment (&loop, expr1, expr2);
7007 if (tmp != NULL_TREE)
7008 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
7009 }
7010
6de9cd9a
DN
7011 /* Generate the copying loops. */
7012 gfc_trans_scalarizing_loops (&loop, &body);
7013
7014 /* Wrap the whole thing up. */
7015 gfc_add_block_to_block (&block, &loop.pre);
7016 gfc_add_block_to_block (&block, &loop.post);
7017
7018 gfc_cleanup_loop (&loop);
7019 }
7020
7021 return gfc_finish_block (&block);
7022}
7023
a3018753 7024
18eaa2c0 7025/* Check whether EXPR is a copyable array. */
a3018753
RS
7026
7027static bool
7028copyable_array_p (gfc_expr * expr)
7029{
18eaa2c0
PT
7030 if (expr->expr_type != EXPR_VARIABLE)
7031 return false;
7032
a3018753 7033 /* First check it's an array. */
18eaa2c0
PT
7034 if (expr->rank < 1 || !expr->ref || expr->ref->next)
7035 return false;
7036
a61a36ab 7037 if (!gfc_full_array_ref_p (expr->ref, NULL))
a3018753
RS
7038 return false;
7039
7040 /* Next check that it's of a simple enough type. */
7041 switch (expr->ts.type)
7042 {
7043 case BT_INTEGER:
7044 case BT_REAL:
7045 case BT_COMPLEX:
7046 case BT_LOGICAL:
7047 return true;
7048
150524cd
RS
7049 case BT_CHARACTER:
7050 return false;
7051
7052 case BT_DERIVED:
bc21d315 7053 return !expr->ts.u.derived->attr.alloc_comp;
150524cd 7054
a3018753
RS
7055 default:
7056 break;
7057 }
7058
7059 return false;
7060}
7061
7062/* Translate an assignment. */
7063
7064tree
2b56d6a4
TB
7065gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
7066 bool dealloc)
a3018753
RS
7067{
7068 tree tmp;
f1f39033 7069
a3018753
RS
7070 /* Special case a single function returning an array. */
7071 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
7072 {
7073 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
7074 if (tmp)
7075 return tmp;
7076 }
7077
7078 /* Special case assigning an array to zero. */
18eaa2c0 7079 if (copyable_array_p (expr1)
a3018753
RS
7080 && is_zero_initializer_p (expr2))
7081 {
7082 tmp = gfc_trans_zero_assign (expr1);
7083 if (tmp)
7084 return tmp;
7085 }
7086
7087 /* Special case copying one array to another. */
18eaa2c0 7088 if (copyable_array_p (expr1)
a3018753 7089 && copyable_array_p (expr2)
a3018753
RS
7090 && gfc_compare_types (&expr1->ts, &expr2->ts)
7091 && !gfc_check_dependency (expr1, expr2, 0))
7092 {
7093 tmp = gfc_trans_array_copy (expr1, expr2);
7094 if (tmp)
7095 return tmp;
7096 }
7097
b01e2f88 7098 /* Special case initializing an array from a constant array constructor. */
18eaa2c0 7099 if (copyable_array_p (expr1)
b01e2f88
RS
7100 && expr2->expr_type == EXPR_ARRAY
7101 && gfc_compare_types (&expr1->ts, &expr2->ts))
7102 {
7103 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
7104 if (tmp)
7105 return tmp;
7106 }
7107
a3018753 7108 /* Fallback to the scalarizer to generate explicit loops. */
2b56d6a4 7109 return gfc_trans_assignment_1 (expr1, expr2, init_flag, dealloc);
a3018753
RS
7110}
7111
6b591ec0
PT
7112tree
7113gfc_trans_init_assign (gfc_code * code)
7114{
2b56d6a4 7115 return gfc_trans_assignment (code->expr1, code->expr2, true, false);
6b591ec0
PT
7116}
7117
6de9cd9a
DN
7118tree
7119gfc_trans_assign (gfc_code * code)
7120{
2b56d6a4 7121 return gfc_trans_assignment (code->expr1, code->expr2, false, true);
6de9cd9a 7122}