]> gcc.gnu.org Git - gcc.git/blame - gcc/fortran/trans-expr.c
re PR fortran/34658 (save / common)
[gcc.git] / gcc / fortran / trans-expr.c
CommitLineData
6de9cd9a 1/* Expression translation
710a179f
TS
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software
3 Foundation, Inc.
6de9cd9a
DN
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6
9fc4d79b 7This file is part of GCC.
6de9cd9a 8
9fc4d79b
TS
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
d234d788 11Software Foundation; either version 3, or (at your option) any later
9fc4d79b 12version.
6de9cd9a 13
9fc4d79b
TS
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
6de9cd9a
DN
18
19You should have received a copy of the GNU General Public License
d234d788
NC
20along with GCC; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
22
23/* trans-expr.c-- generate GENERIC trees for gfc_expr. */
24
25#include "config.h"
26#include "system.h"
27#include "coretypes.h"
28#include "tree.h"
29#include "convert.h"
6de9cd9a
DN
30#include "ggc.h"
31#include "toplev.h"
32#include "real.h"
eadf906f 33#include "tree-gimple.h"
b3eb1e0e 34#include "langhooks.h"
6de9cd9a 35#include "flags.h"
6de9cd9a 36#include "gfortran.h"
0a164a3c 37#include "arith.h"
6de9cd9a
DN
38#include "trans.h"
39#include "trans-const.h"
40#include "trans-types.h"
41#include "trans-array.h"
42/* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
43#include "trans-stmt.h"
7a70c12d 44#include "dependency.h"
6de9cd9a 45
e9cfef64 46static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
0a164a3c 47static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
62ab4a54 48 gfc_expr *);
6de9cd9a
DN
49
50/* Copy the scalarization loop variables. */
51
52static void
53gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
54{
55 dest->ss = src->ss;
56 dest->loop = src->loop;
57}
58
59
f8d0aee5 60/* Initialize a simple expression holder.
6de9cd9a
DN
61
62 Care must be taken when multiple se are created with the same parent.
63 The child se must be kept in sync. The easiest way is to delay creation
64 of a child se until after after the previous se has been translated. */
65
66void
67gfc_init_se (gfc_se * se, gfc_se * parent)
68{
69 memset (se, 0, sizeof (gfc_se));
70 gfc_init_block (&se->pre);
71 gfc_init_block (&se->post);
72
73 se->parent = parent;
74
75 if (parent)
76 gfc_copy_se_loopvars (se, parent);
77}
78
79
80/* Advances to the next SS in the chain. Use this rather than setting
f8d0aee5 81 se->ss = se->ss->next because all the parents needs to be kept in sync.
6de9cd9a
DN
82 See gfc_init_se. */
83
84void
85gfc_advance_se_ss_chain (gfc_se * se)
86{
87 gfc_se *p;
88
6e45f57b 89 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
6de9cd9a
DN
90
91 p = se;
92 /* Walk down the parent chain. */
93 while (p != NULL)
94 {
f8d0aee5 95 /* Simple consistency check. */
6e45f57b 96 gcc_assert (p->parent == NULL || p->parent->ss == p->ss);
6de9cd9a
DN
97
98 p->ss = p->ss->next;
99
100 p = p->parent;
101 }
102}
103
104
105/* Ensures the result of the expression as either a temporary variable
106 or a constant so that it can be used repeatedly. */
107
108void
109gfc_make_safe_expr (gfc_se * se)
110{
111 tree var;
112
6615c446 113 if (CONSTANT_CLASS_P (se->expr))
6de9cd9a
DN
114 return;
115
f8d0aee5 116 /* We need a temporary for this result. */
6de9cd9a
DN
117 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
118 gfc_add_modify_expr (&se->pre, var, se->expr);
119 se->expr = var;
120}
121
122
1a7bfcc3
PB
123/* Return an expression which determines if a dummy parameter is present.
124 Also used for arguments to procedures with multiple entry points. */
6de9cd9a
DN
125
126tree
127gfc_conv_expr_present (gfc_symbol * sym)
128{
129 tree decl;
130
1a7bfcc3 131 gcc_assert (sym->attr.dummy);
6de9cd9a
DN
132
133 decl = gfc_get_symbol_decl (sym);
134 if (TREE_CODE (decl) != PARM_DECL)
135 {
136 /* Array parameters use a temporary descriptor, we want the real
137 parameter. */
6e45f57b 138 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
6de9cd9a
DN
139 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
140 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
141 }
923ab88c
TS
142 return build2 (NE_EXPR, boolean_type_node, decl,
143 fold_convert (TREE_TYPE (decl), null_pointer_node));
6de9cd9a
DN
144}
145
146
e15e9be3
PT
147/* Converts a missing, dummy argument into a null or zero. */
148
149void
be9c3c6e 150gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
e15e9be3
PT
151{
152 tree present;
153 tree tmp;
154
155 present = gfc_conv_expr_present (arg->symtree->n.sym);
33717d59 156
e76e6ce3 157 tmp = build3 (COND_EXPR, TREE_TYPE (se->expr), present, se->expr,
be9c3c6e 158 fold_convert (TREE_TYPE (se->expr), integer_zero_node));
e15e9be3 159 tmp = gfc_evaluate_now (tmp, &se->pre);
be9c3c6e
JD
160
161 if (kind > 0)
162 {
163 tmp = gfc_get_int_type (kind);
164 tmp = fold_convert (tmp, se->expr);
165 tmp = gfc_evaluate_now (tmp, &se->pre);
166 }
167
e15e9be3 168 se->expr = tmp;
33717d59 169
e15e9be3
PT
170 if (ts.type == BT_CHARACTER)
171 {
c3238e32 172 tmp = build_int_cst (gfc_charlen_type_node, 0);
e15e9be3
PT
173 tmp = build3 (COND_EXPR, gfc_charlen_type_node, present,
174 se->string_length, tmp);
175 tmp = gfc_evaluate_now (tmp, &se->pre);
176 se->string_length = tmp;
177 }
178 return;
179}
180
181
ca2940c3
TS
182/* Get the character length of an expression, looking through gfc_refs
183 if necessary. */
184
185tree
186gfc_get_expr_charlen (gfc_expr *e)
187{
188 gfc_ref *r;
189 tree length;
190
191 gcc_assert (e->expr_type == EXPR_VARIABLE
192 && e->ts.type == BT_CHARACTER);
193
194 length = NULL; /* To silence compiler warning. */
195
1d6b7f39
PT
196 if (is_subref_array (e) && e->ts.cl->length)
197 {
198 gfc_se tmpse;
199 gfc_init_se (&tmpse, NULL);
200 gfc_conv_expr_type (&tmpse, e->ts.cl->length, gfc_charlen_type_node);
201 e->ts.cl->backend_decl = tmpse.expr;
202 return tmpse.expr;
203 }
204
ca2940c3
TS
205 /* First candidate: if the variable is of type CHARACTER, the
206 expression's length could be the length of the character
f7b529fa 207 variable. */
ca2940c3
TS
208 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
209 length = e->symtree->n.sym->ts.cl->backend_decl;
210
211 /* Look through the reference chain for component references. */
212 for (r = e->ref; r; r = r->next)
213 {
214 switch (r->type)
215 {
216 case REF_COMPONENT:
217 if (r->u.c.component->ts.type == BT_CHARACTER)
218 length = r->u.c.component->ts.cl->backend_decl;
219 break;
220
221 case REF_ARRAY:
222 /* Do nothing. */
223 break;
224
225 default:
226 /* We should never got substring references here. These will be
227 broken down by the scalarizer. */
228 gcc_unreachable ();
1d6b7f39 229 break;
ca2940c3
TS
230 }
231 }
232
233 gcc_assert (length != NULL);
234 return length;
235}
236
237
238
6de9cd9a
DN
239/* Generate code to initialize a string length variable. Returns the
240 value. */
241
242void
07368af0 243gfc_conv_string_length (gfc_charlen * cl, stmtblock_t * pblock)
6de9cd9a
DN
244{
245 gfc_se se;
6de9cd9a
DN
246
247 gfc_init_se (&se, NULL);
d7177ab2 248 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
886c8de1
FXC
249 se.expr = fold_build2 (MAX_EXPR, gfc_charlen_type_node, se.expr,
250 build_int_cst (gfc_charlen_type_node, 0));
6de9cd9a
DN
251 gfc_add_block_to_block (pblock, &se.pre);
252
07368af0
PT
253 if (cl->backend_decl)
254 gfc_add_modify_expr (pblock, cl->backend_decl, se.expr);
255 else
256 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
6de9cd9a
DN
257}
258
f8d0aee5 259
6de9cd9a 260static void
65713e5b
TB
261gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
262 const char *name, locus *where)
6de9cd9a
DN
263{
264 tree tmp;
265 tree type;
266 tree var;
65713e5b 267 tree fault;
6de9cd9a
DN
268 gfc_se start;
269 gfc_se end;
65713e5b 270 char *msg;
6de9cd9a
DN
271
272 type = gfc_get_character_type (kind, ref->u.ss.length);
273 type = build_pointer_type (type);
274
275 var = NULL_TREE;
276 gfc_init_se (&start, se);
d7177ab2 277 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
6de9cd9a
DN
278 gfc_add_block_to_block (&se->pre, &start.pre);
279
280 if (integer_onep (start.expr))
7ab92584 281 gfc_conv_string_parameter (se);
6de9cd9a
DN
282 else
283 {
1af5627c
FXC
284 /* Avoid multiple evaluation of substring start. */
285 if (!CONSTANT_CLASS_P (start.expr) && !DECL_P (start.expr))
286 start.expr = gfc_evaluate_now (start.expr, &se->pre);
287
6de9cd9a
DN
288 /* Change the start of the string. */
289 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
290 tmp = se->expr;
291 else
38611275 292 tmp = build_fold_indirect_ref (se->expr);
1d6b7f39 293 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
6de9cd9a
DN
294 se->expr = gfc_build_addr_expr (type, tmp);
295 }
296
297 /* Length = end + 1 - start. */
298 gfc_init_se (&end, se);
299 if (ref->u.ss.end == NULL)
300 end.expr = se->string_length;
301 else
302 {
d7177ab2 303 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
6de9cd9a
DN
304 gfc_add_block_to_block (&se->pre, &end.pre);
305 }
1af5627c
FXC
306 if (!CONSTANT_CLASS_P (end.expr) && !DECL_P (end.expr))
307 end.expr = gfc_evaluate_now (end.expr, &se->pre);
308
65713e5b
TB
309 if (flag_bounds_check)
310 {
ad7082e3
TS
311 tree nonempty = fold_build2 (LE_EXPR, boolean_type_node,
312 start.expr, end.expr);
313
65713e5b
TB
314 /* Check lower bound. */
315 fault = fold_build2 (LT_EXPR, boolean_type_node, start.expr,
316 build_int_cst (gfc_charlen_type_node, 1));
ad7082e3
TS
317 fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
318 nonempty, fault);
65713e5b 319 if (name)
c8fe94c7 320 asprintf (&msg, "Substring out of bounds: lower bound (%%ld) of '%s' "
65713e5b
TB
321 "is less than one", name);
322 else
c8fe94c7 323 asprintf (&msg, "Substring out of bounds: lower bound (%%ld)"
65713e5b 324 "is less than one");
c8fe94c7
FXC
325 gfc_trans_runtime_check (fault, &se->pre, where, msg,
326 fold_convert (long_integer_type_node,
327 start.expr));
65713e5b
TB
328 gfc_free (msg);
329
330 /* Check upper bound. */
331 fault = fold_build2 (GT_EXPR, boolean_type_node, end.expr,
332 se->string_length);
ad7082e3
TS
333 fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
334 nonempty, fault);
65713e5b 335 if (name)
c8fe94c7
FXC
336 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) of '%s' "
337 "exceeds string length (%%ld)", name);
65713e5b 338 else
c8fe94c7
FXC
339 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) "
340 "exceeds string length (%%ld)");
341 gfc_trans_runtime_check (fault, &se->pre, where, msg,
342 fold_convert (long_integer_type_node, end.expr),
343 fold_convert (long_integer_type_node,
344 se->string_length));
65713e5b
TB
345 gfc_free (msg);
346 }
347
93fc8073
RG
348 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node,
349 build_int_cst (gfc_charlen_type_node, 1),
350 start.expr);
351 tmp = fold_build2 (PLUS_EXPR, gfc_charlen_type_node, end.expr, tmp);
549033f3
FXC
352 tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
353 build_int_cst (gfc_charlen_type_node, 0));
93fc8073 354 se->string_length = tmp;
6de9cd9a
DN
355}
356
357
358/* Convert a derived type component reference. */
359
360static void
361gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
362{
363 gfc_component *c;
364 tree tmp;
365 tree decl;
366 tree field;
367
368 c = ref->u.c.component;
369
6e45f57b 370 gcc_assert (c->backend_decl);
6de9cd9a
DN
371
372 field = c->backend_decl;
6e45f57b 373 gcc_assert (TREE_CODE (field) == FIELD_DECL);
6de9cd9a 374 decl = se->expr;
923ab88c 375 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
6de9cd9a
DN
376
377 se->expr = tmp;
378
379 if (c->ts.type == BT_CHARACTER)
380 {
381 tmp = c->ts.cl->backend_decl;
40f20186 382 /* Components must always be constant length. */
6e45f57b 383 gcc_assert (tmp && INTEGER_CST_P (tmp));
6de9cd9a
DN
384 se->string_length = tmp;
385 }
386
2b052ce2 387 if (c->pointer && c->dimension == 0 && c->ts.type != BT_CHARACTER)
38611275 388 se->expr = build_fold_indirect_ref (se->expr);
6de9cd9a
DN
389}
390
391
392/* Return the contents of a variable. Also handles reference/pointer
393 variables (all Fortran pointer references are implicit). */
394
395static void
396gfc_conv_variable (gfc_se * se, gfc_expr * expr)
397{
398 gfc_ref *ref;
399 gfc_symbol *sym;
5f20c93a
PT
400 tree parent_decl;
401 int parent_flag;
402 bool return_value;
403 bool alternate_entry;
404 bool entry_master;
6de9cd9a
DN
405
406 sym = expr->symtree->n.sym;
407 if (se->ss != NULL)
408 {
409 /* Check that something hasn't gone horribly wrong. */
6e45f57b
PB
410 gcc_assert (se->ss != gfc_ss_terminator);
411 gcc_assert (se->ss->expr == expr);
6de9cd9a
DN
412
413 /* A scalarized term. We already know the descriptor. */
414 se->expr = se->ss->data.info.descriptor;
40f20186 415 se->string_length = se->ss->string_length;
068e7338
RS
416 for (ref = se->ss->data.info.ref; ref; ref = ref->next)
417 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
418 break;
6de9cd9a
DN
419 }
420 else
421 {
d198b59a
JJ
422 tree se_expr = NULL_TREE;
423
b122dc6a 424 se->expr = gfc_get_symbol_decl (sym);
6de9cd9a 425
5f20c93a
PT
426 /* Deal with references to a parent results or entries by storing
427 the current_function_decl and moving to the parent_decl. */
5f20c93a
PT
428 return_value = sym->attr.function && sym->result == sym;
429 alternate_entry = sym->attr.function && sym->attr.entry
11a5f608 430 && sym->result == sym;
5f20c93a 431 entry_master = sym->attr.result
11a5f608
JJ
432 && sym->ns->proc_name->attr.entry_master
433 && !gfc_return_by_reference (sym->ns->proc_name);
5f20c93a
PT
434 parent_decl = DECL_CONTEXT (current_function_decl);
435
436 if ((se->expr == parent_decl && return_value)
11a5f608 437 || (sym->ns && sym->ns->proc_name
1a492601 438 && parent_decl
11a5f608
JJ
439 && sym->ns->proc_name->backend_decl == parent_decl
440 && (alternate_entry || entry_master)))
5f20c93a
PT
441 parent_flag = 1;
442 else
443 parent_flag = 0;
444
d198b59a
JJ
445 /* Special case for assigning the return value of a function.
446 Self recursive functions must have an explicit return value. */
11a5f608 447 if (return_value && (se->expr == current_function_decl || parent_flag))
5f20c93a 448 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
449
450 /* Similarly for alternate entry points. */
5f20c93a 451 else if (alternate_entry
11a5f608
JJ
452 && (sym->ns->proc_name->backend_decl == current_function_decl
453 || parent_flag))
d198b59a
JJ
454 {
455 gfc_entry_list *el = NULL;
456
457 for (el = sym->ns->entries; el; el = el->next)
458 if (sym == el->sym)
459 {
5f20c93a 460 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
461 break;
462 }
463 }
464
5f20c93a 465 else if (entry_master
11a5f608
JJ
466 && (sym->ns->proc_name->backend_decl == current_function_decl
467 || parent_flag))
5f20c93a 468 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
469
470 if (se_expr)
471 se->expr = se_expr;
472
6de9cd9a 473 /* Procedure actual arguments. */
d198b59a
JJ
474 else if (sym->attr.flavor == FL_PROCEDURE
475 && se->expr != current_function_decl)
6de9cd9a 476 {
6e45f57b 477 gcc_assert (se->want_pointer);
6de9cd9a
DN
478 if (!sym->attr.dummy)
479 {
6e45f57b 480 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
488ce07b 481 se->expr = build_fold_addr_expr (se->expr);
6de9cd9a
DN
482 }
483 return;
ec09945c
KH
484 }
485
486
487 /* Dereference the expression, where needed. Since characters
488 are entirely different from other types, they are treated
489 separately. */
490 if (sym->ts.type == BT_CHARACTER)
491 {
06469efd 492 /* Dereference character pointer dummy arguments
72caba17 493 or results. */
ec09945c 494 if ((sym->attr.pointer || sym->attr.allocatable)
13a9737c
PT
495 && (sym->attr.dummy
496 || sym->attr.function
497 || sym->attr.result))
38611275 498 se->expr = build_fold_indirect_ref (se->expr);
06469efd 499
ec09945c 500 }
06469efd 501 else if (!sym->attr.value)
ec09945c 502 {
897f1a8b 503 /* Dereference non-character scalar dummy arguments. */
13a9737c 504 if (sym->attr.dummy && !sym->attr.dimension)
38611275 505 se->expr = build_fold_indirect_ref (se->expr);
ec09945c 506
72caba17 507 /* Dereference scalar hidden result. */
13a9737c 508 if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
ec09945c 509 && (sym->attr.function || sym->attr.result)
b49a3de7 510 && !sym->attr.dimension && !sym->attr.pointer)
38611275 511 se->expr = build_fold_indirect_ref (se->expr);
ec09945c
KH
512
513 /* Dereference non-character pointer variables.
897f1a8b 514 These must be dummies, results, or scalars. */
ec09945c 515 if ((sym->attr.pointer || sym->attr.allocatable)
13a9737c
PT
516 && (sym->attr.dummy
517 || sym->attr.function
518 || sym->attr.result
519 || !sym->attr.dimension))
38611275 520 se->expr = build_fold_indirect_ref (se->expr);
ec09945c
KH
521 }
522
6de9cd9a
DN
523 ref = expr->ref;
524 }
525
526 /* For character variables, also get the length. */
527 if (sym->ts.type == BT_CHARACTER)
528 {
d48734ef
EE
529 /* If the character length of an entry isn't set, get the length from
530 the master function instead. */
531 if (sym->attr.entry && !sym->ts.cl->backend_decl)
532 se->string_length = sym->ns->proc_name->ts.cl->backend_decl;
533 else
534 se->string_length = sym->ts.cl->backend_decl;
6e45f57b 535 gcc_assert (se->string_length);
6de9cd9a
DN
536 }
537
538 while (ref)
539 {
540 switch (ref->type)
541 {
542 case REF_ARRAY:
543 /* Return the descriptor if that's what we want and this is an array
544 section reference. */
545 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
546 return;
547/* TODO: Pointers to single elements of array sections, eg elemental subs. */
548 /* Return the descriptor for array pointers and allocations. */
549 if (se->want_pointer
550 && ref->next == NULL && (se->descriptor_only))
551 return;
552
dd18a33b 553 gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
6de9cd9a
DN
554 /* Return a pointer to an element. */
555 break;
556
557 case REF_COMPONENT:
558 gfc_conv_component_ref (se, ref);
559 break;
560
561 case REF_SUBSTRING:
65713e5b
TB
562 gfc_conv_substring (se, ref, expr->ts.kind,
563 expr->symtree->name, &expr->where);
6de9cd9a
DN
564 break;
565
566 default:
6e45f57b 567 gcc_unreachable ();
6de9cd9a
DN
568 break;
569 }
570 ref = ref->next;
571 }
572 /* Pointer assignment, allocation or pass by reference. Arrays are handled
f8d0aee5 573 separately. */
6de9cd9a
DN
574 if (se->want_pointer)
575 {
576 if (expr->ts.type == BT_CHARACTER)
577 gfc_conv_string_parameter (se);
578 else
488ce07b 579 se->expr = build_fold_addr_expr (se->expr);
6de9cd9a 580 }
6de9cd9a
DN
581}
582
583
584/* Unary ops are easy... Or they would be if ! was a valid op. */
585
586static void
587gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
588{
589 gfc_se operand;
590 tree type;
591
6e45f57b 592 gcc_assert (expr->ts.type != BT_CHARACTER);
6de9cd9a
DN
593 /* Initialize the operand. */
594 gfc_init_se (&operand, se);
58b03ab2 595 gfc_conv_expr_val (&operand, expr->value.op.op1);
6de9cd9a
DN
596 gfc_add_block_to_block (&se->pre, &operand.pre);
597
598 type = gfc_typenode_for_spec (&expr->ts);
599
600 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
601 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
f8d0aee5 602 All other unary operators have an equivalent GIMPLE unary operator. */
6de9cd9a 603 if (code == TRUTH_NOT_EXPR)
923ab88c 604 se->expr = build2 (EQ_EXPR, type, operand.expr,
c3238e32 605 build_int_cst (type, 0));
6de9cd9a
DN
606 else
607 se->expr = build1 (code, type, operand.expr);
608
609}
610
5b200ac2 611/* Expand power operator to optimal multiplications when a value is raised
f8d0aee5 612 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
5b200ac2
FW
613 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
614 Programming", 3rd Edition, 1998. */
615
616/* This code is mostly duplicated from expand_powi in the backend.
617 We establish the "optimal power tree" lookup table with the defined size.
618 The items in the table are the exponents used to calculate the index
619 exponents. Any integer n less than the value can get an "addition chain",
620 with the first node being one. */
621#define POWI_TABLE_SIZE 256
622
f8d0aee5 623/* The table is from builtins.c. */
5b200ac2
FW
624static const unsigned char powi_table[POWI_TABLE_SIZE] =
625 {
626 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
627 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
628 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
629 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
630 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
631 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
632 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
633 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
634 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
635 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
636 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
637 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
638 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
639 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
640 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
641 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
642 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
643 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
644 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
645 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
646 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
647 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
648 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
649 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
650 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
651 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
652 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
653 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
654 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
655 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
656 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
657 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
658 };
659
f8d0aee5
TS
660/* If n is larger than lookup table's max index, we use the "window
661 method". */
5b200ac2
FW
662#define POWI_WINDOW_SIZE 3
663
f8d0aee5
TS
664/* Recursive function to expand the power operator. The temporary
665 values are put in tmpvar. The function returns tmpvar[1] ** n. */
5b200ac2 666static tree
6f85ab62 667gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
6de9cd9a 668{
5b200ac2
FW
669 tree op0;
670 tree op1;
6de9cd9a 671 tree tmp;
5b200ac2 672 int digit;
6de9cd9a 673
5b200ac2 674 if (n < POWI_TABLE_SIZE)
6de9cd9a 675 {
5b200ac2
FW
676 if (tmpvar[n])
677 return tmpvar[n];
6de9cd9a 678
5b200ac2
FW
679 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
680 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
681 }
682 else if (n & 1)
683 {
684 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
685 op0 = gfc_conv_powi (se, n - digit, tmpvar);
686 op1 = gfc_conv_powi (se, digit, tmpvar);
6de9cd9a
DN
687 }
688 else
689 {
5b200ac2
FW
690 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
691 op1 = op0;
6de9cd9a
DN
692 }
693
10c7a96f 694 tmp = fold_build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1);
5b200ac2 695 tmp = gfc_evaluate_now (tmp, &se->pre);
6de9cd9a 696
5b200ac2
FW
697 if (n < POWI_TABLE_SIZE)
698 tmpvar[n] = tmp;
6de9cd9a 699
5b200ac2
FW
700 return tmp;
701}
6de9cd9a 702
f8d0aee5
TS
703
704/* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
705 return 1. Else return 0 and a call to runtime library functions
706 will have to be built. */
5b200ac2
FW
707static int
708gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
709{
710 tree cond;
711 tree tmp;
712 tree type;
713 tree vartmp[POWI_TABLE_SIZE];
6f85ab62
FXC
714 HOST_WIDE_INT m;
715 unsigned HOST_WIDE_INT n;
5b200ac2 716 int sgn;
6de9cd9a 717
6f85ab62
FXC
718 /* If exponent is too large, we won't expand it anyway, so don't bother
719 with large integer values. */
720 if (!double_int_fits_in_shwi_p (TREE_INT_CST (rhs)))
721 return 0;
722
723 m = double_int_to_shwi (TREE_INT_CST (rhs));
724 /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
725 of the asymmetric range of the integer type. */
726 n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
727
5b200ac2 728 type = TREE_TYPE (lhs);
5b200ac2 729 sgn = tree_int_cst_sgn (rhs);
6de9cd9a 730
6f85ab62
FXC
731 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
732 || optimize_size) && (m > 2 || m < -1))
5b200ac2 733 return 0;
6de9cd9a 734
5b200ac2
FW
735 /* rhs == 0 */
736 if (sgn == 0)
737 {
738 se->expr = gfc_build_const (type, integer_one_node);
739 return 1;
740 }
6f85ab62 741
5b200ac2
FW
742 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
743 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
744 {
923ab88c 745 tmp = build2 (EQ_EXPR, boolean_type_node, lhs,
c3238e32 746 build_int_cst (TREE_TYPE (lhs), -1));
923ab88c 747 cond = build2 (EQ_EXPR, boolean_type_node, lhs,
c3238e32 748 build_int_cst (TREE_TYPE (lhs), 1));
5b200ac2 749
f8d0aee5 750 /* If rhs is even,
7ab92584 751 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
5b200ac2
FW
752 if ((n & 1) == 0)
753 {
923ab88c 754 tmp = build2 (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
c3238e32
FXC
755 se->expr = build3 (COND_EXPR, type, tmp, build_int_cst (type, 1),
756 build_int_cst (type, 0));
5b200ac2
FW
757 return 1;
758 }
f8d0aee5 759 /* If rhs is odd,
5b200ac2 760 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
c3238e32
FXC
761 tmp = build3 (COND_EXPR, type, tmp, build_int_cst (type, -1),
762 build_int_cst (type, 0));
763 se->expr = build3 (COND_EXPR, type, cond, build_int_cst (type, 1), tmp);
5b200ac2
FW
764 return 1;
765 }
6de9cd9a 766
5b200ac2
FW
767 memset (vartmp, 0, sizeof (vartmp));
768 vartmp[1] = lhs;
5b200ac2
FW
769 if (sgn == -1)
770 {
771 tmp = gfc_build_const (type, integer_one_node);
923ab88c 772 vartmp[1] = build2 (RDIV_EXPR, type, tmp, vartmp[1]);
5b200ac2 773 }
293155b0
TM
774
775 se->expr = gfc_conv_powi (se, n, vartmp);
776
5b200ac2 777 return 1;
6de9cd9a
DN
778}
779
780
5b200ac2 781/* Power op (**). Constant integer exponent has special handling. */
6de9cd9a
DN
782
783static void
784gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
785{
e2cad04b 786 tree gfc_int4_type_node;
6de9cd9a 787 int kind;
5b200ac2 788 int ikind;
6de9cd9a
DN
789 gfc_se lse;
790 gfc_se rse;
791 tree fndecl;
6de9cd9a
DN
792
793 gfc_init_se (&lse, se);
58b03ab2 794 gfc_conv_expr_val (&lse, expr->value.op.op1);
20fe2233 795 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
6de9cd9a
DN
796 gfc_add_block_to_block (&se->pre, &lse.pre);
797
798 gfc_init_se (&rse, se);
58b03ab2 799 gfc_conv_expr_val (&rse, expr->value.op.op2);
6de9cd9a
DN
800 gfc_add_block_to_block (&se->pre, &rse.pre);
801
58b03ab2 802 if (expr->value.op.op2->ts.type == BT_INTEGER
31c97dfe 803 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
5b200ac2 804 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
31c97dfe 805 return;
6de9cd9a 806
e2cad04b
RH
807 gfc_int4_type_node = gfc_get_int_type (4);
808
58b03ab2
TS
809 kind = expr->value.op.op1->ts.kind;
810 switch (expr->value.op.op2->ts.type)
6de9cd9a
DN
811 {
812 case BT_INTEGER:
58b03ab2 813 ikind = expr->value.op.op2->ts.kind;
5b200ac2
FW
814 switch (ikind)
815 {
816 case 1:
817 case 2:
818 rse.expr = convert (gfc_int4_type_node, rse.expr);
819 /* Fall through. */
820
821 case 4:
822 ikind = 0;
823 break;
824
825 case 8:
826 ikind = 1;
827 break;
828
644cb69f
FXC
829 case 16:
830 ikind = 2;
831 break;
832
5b200ac2 833 default:
6e45f57b 834 gcc_unreachable ();
5b200ac2
FW
835 }
836 switch (kind)
837 {
838 case 1:
839 case 2:
58b03ab2 840 if (expr->value.op.op1->ts.type == BT_INTEGER)
5b200ac2
FW
841 lse.expr = convert (gfc_int4_type_node, lse.expr);
842 else
6e45f57b 843 gcc_unreachable ();
5b200ac2
FW
844 /* Fall through. */
845
846 case 4:
847 kind = 0;
848 break;
849
850 case 8:
851 kind = 1;
852 break;
853
644cb69f
FXC
854 case 10:
855 kind = 2;
856 break;
857
858 case 16:
859 kind = 3;
860 break;
861
5b200ac2 862 default:
6e45f57b 863 gcc_unreachable ();
5b200ac2
FW
864 }
865
58b03ab2 866 switch (expr->value.op.op1->ts.type)
5b200ac2
FW
867 {
868 case BT_INTEGER:
644cb69f
FXC
869 if (kind == 3) /* Case 16 was not handled properly above. */
870 kind = 2;
5b200ac2
FW
871 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
872 break;
873
874 case BT_REAL:
31c97dfe
JB
875 /* Use builtins for real ** int4. */
876 if (ikind == 0)
877 {
878 switch (kind)
879 {
880 case 0:
881 fndecl = built_in_decls[BUILT_IN_POWIF];
882 break;
883
884 case 1:
885 fndecl = built_in_decls[BUILT_IN_POWI];
886 break;
887
888 case 2:
889 case 3:
890 fndecl = built_in_decls[BUILT_IN_POWIL];
891 break;
892
893 default:
894 gcc_unreachable ();
895 }
896 }
897 else
898 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
5b200ac2
FW
899 break;
900
901 case BT_COMPLEX:
902 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
903 break;
904
905 default:
6e45f57b 906 gcc_unreachable ();
5b200ac2
FW
907 }
908 break;
6de9cd9a
DN
909
910 case BT_REAL:
911 switch (kind)
912 {
913 case 4:
5b200ac2 914 fndecl = built_in_decls[BUILT_IN_POWF];
6de9cd9a
DN
915 break;
916 case 8:
5b200ac2 917 fndecl = built_in_decls[BUILT_IN_POW];
6de9cd9a 918 break;
644cb69f
FXC
919 case 10:
920 case 16:
921 fndecl = built_in_decls[BUILT_IN_POWL];
922 break;
6de9cd9a 923 default:
6e45f57b 924 gcc_unreachable ();
6de9cd9a
DN
925 }
926 break;
927
928 case BT_COMPLEX:
929 switch (kind)
930 {
931 case 4:
932 fndecl = gfor_fndecl_math_cpowf;
933 break;
934 case 8:
935 fndecl = gfor_fndecl_math_cpow;
936 break;
644cb69f
FXC
937 case 10:
938 fndecl = gfor_fndecl_math_cpowl10;
939 break;
940 case 16:
941 fndecl = gfor_fndecl_math_cpowl16;
942 break;
6de9cd9a 943 default:
6e45f57b 944 gcc_unreachable ();
6de9cd9a
DN
945 }
946 break;
947
948 default:
6e45f57b 949 gcc_unreachable ();
6de9cd9a
DN
950 break;
951 }
952
5039610b 953 se->expr = build_call_expr (fndecl, 2, lse.expr, rse.expr);
6de9cd9a
DN
954}
955
956
957/* Generate code to allocate a string temporary. */
958
959tree
960gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
961{
962 tree var;
963 tree tmp;
6de9cd9a 964
6e45f57b 965 gcc_assert (TREE_TYPE (len) == gfc_charlen_type_node);
7ab92584 966
6de9cd9a
DN
967 if (gfc_can_put_var_on_stack (len))
968 {
969 /* Create a temporary variable to hold the result. */
10c7a96f 970 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
c3238e32 971 build_int_cst (gfc_charlen_type_node, 1));
7ab92584 972 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
6de9cd9a
DN
973 tmp = build_array_type (gfc_character1_type_node, tmp);
974 var = gfc_create_var (tmp, "str");
975 var = gfc_build_addr_expr (type, var);
976 }
977 else
978 {
979 /* Allocate a temporary to hold the result. */
980 var = gfc_create_var (type, "pstr");
1529b8d9 981 tmp = gfc_call_malloc (&se->pre, type, len);
6de9cd9a
DN
982 gfc_add_modify_expr (&se->pre, var, tmp);
983
984 /* Free the temporary afterwards. */
1529b8d9 985 tmp = gfc_call_free (convert (pvoid_type_node, var));
6de9cd9a
DN
986 gfc_add_expr_to_block (&se->post, tmp);
987 }
988
989 return var;
990}
991
992
993/* Handle a string concatenation operation. A temporary will be allocated to
994 hold the result. */
995
996static void
997gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
998{
999 gfc_se lse;
1000 gfc_se rse;
1001 tree len;
1002 tree type;
1003 tree var;
6de9cd9a
DN
1004 tree tmp;
1005
58b03ab2
TS
1006 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
1007 && expr->value.op.op2->ts.type == BT_CHARACTER);
6de9cd9a
DN
1008
1009 gfc_init_se (&lse, se);
58b03ab2 1010 gfc_conv_expr (&lse, expr->value.op.op1);
6de9cd9a
DN
1011 gfc_conv_string_parameter (&lse);
1012 gfc_init_se (&rse, se);
58b03ab2 1013 gfc_conv_expr (&rse, expr->value.op.op2);
6de9cd9a
DN
1014 gfc_conv_string_parameter (&rse);
1015
1016 gfc_add_block_to_block (&se->pre, &lse.pre);
1017 gfc_add_block_to_block (&se->pre, &rse.pre);
1018
1019 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
1020 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
1021 if (len == NULL_TREE)
1022 {
10c7a96f
SB
1023 len = fold_build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
1024 lse.string_length, rse.string_length);
6de9cd9a
DN
1025 }
1026
1027 type = build_pointer_type (type);
1028
1029 var = gfc_conv_string_tmp (se, type, len);
1030
1031 /* Do the actual concatenation. */
5039610b
SL
1032 tmp = build_call_expr (gfor_fndecl_concat_string, 6,
1033 len, var,
1034 lse.string_length, lse.expr,
1035 rse.string_length, rse.expr);
6de9cd9a
DN
1036 gfc_add_expr_to_block (&se->pre, tmp);
1037
1038 /* Add the cleanup for the operands. */
1039 gfc_add_block_to_block (&se->pre, &rse.post);
1040 gfc_add_block_to_block (&se->pre, &lse.post);
1041
1042 se->expr = var;
1043 se->string_length = len;
1044}
1045
6de9cd9a
DN
1046/* Translates an op expression. Common (binary) cases are handled by this
1047 function, others are passed on. Recursion is used in either case.
1048 We use the fact that (op1.ts == op2.ts) (except for the power
f8d0aee5 1049 operator **).
6de9cd9a 1050 Operators need no special handling for scalarized expressions as long as
f8d0aee5 1051 they call gfc_conv_simple_val to get their operands.
6de9cd9a
DN
1052 Character strings get special handling. */
1053
1054static void
1055gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
1056{
1057 enum tree_code code;
1058 gfc_se lse;
1059 gfc_se rse;
c9ff1de3 1060 tree tmp, type;
6de9cd9a
DN
1061 int lop;
1062 int checkstring;
1063
1064 checkstring = 0;
1065 lop = 0;
58b03ab2 1066 switch (expr->value.op.operator)
6de9cd9a
DN
1067 {
1068 case INTRINSIC_UPLUS:
2414e1d6 1069 case INTRINSIC_PARENTHESES:
58b03ab2 1070 gfc_conv_expr (se, expr->value.op.op1);
6de9cd9a
DN
1071 return;
1072
1073 case INTRINSIC_UMINUS:
1074 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
1075 return;
1076
1077 case INTRINSIC_NOT:
1078 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
1079 return;
1080
1081 case INTRINSIC_PLUS:
1082 code = PLUS_EXPR;
1083 break;
1084
1085 case INTRINSIC_MINUS:
1086 code = MINUS_EXPR;
1087 break;
1088
1089 case INTRINSIC_TIMES:
1090 code = MULT_EXPR;
1091 break;
1092
1093 case INTRINSIC_DIVIDE:
1094 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
1095 an integer, we must round towards zero, so we use a
1096 TRUNC_DIV_EXPR. */
1097 if (expr->ts.type == BT_INTEGER)
1098 code = TRUNC_DIV_EXPR;
1099 else
1100 code = RDIV_EXPR;
1101 break;
1102
1103 case INTRINSIC_POWER:
1104 gfc_conv_power_op (se, expr);
1105 return;
1106
1107 case INTRINSIC_CONCAT:
1108 gfc_conv_concat_op (se, expr);
1109 return;
1110
1111 case INTRINSIC_AND:
1112 code = TRUTH_ANDIF_EXPR;
1113 lop = 1;
1114 break;
1115
1116 case INTRINSIC_OR:
1117 code = TRUTH_ORIF_EXPR;
1118 lop = 1;
1119 break;
1120
1121 /* EQV and NEQV only work on logicals, but since we represent them
eadf906f 1122 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
6de9cd9a 1123 case INTRINSIC_EQ:
3bed9dd0 1124 case INTRINSIC_EQ_OS:
6de9cd9a
DN
1125 case INTRINSIC_EQV:
1126 code = EQ_EXPR;
1127 checkstring = 1;
1128 lop = 1;
1129 break;
1130
1131 case INTRINSIC_NE:
3bed9dd0 1132 case INTRINSIC_NE_OS:
6de9cd9a
DN
1133 case INTRINSIC_NEQV:
1134 code = NE_EXPR;
1135 checkstring = 1;
1136 lop = 1;
1137 break;
1138
1139 case INTRINSIC_GT:
3bed9dd0 1140 case INTRINSIC_GT_OS:
6de9cd9a
DN
1141 code = GT_EXPR;
1142 checkstring = 1;
1143 lop = 1;
1144 break;
1145
1146 case INTRINSIC_GE:
3bed9dd0 1147 case INTRINSIC_GE_OS:
6de9cd9a
DN
1148 code = GE_EXPR;
1149 checkstring = 1;
1150 lop = 1;
1151 break;
1152
1153 case INTRINSIC_LT:
3bed9dd0 1154 case INTRINSIC_LT_OS:
6de9cd9a
DN
1155 code = LT_EXPR;
1156 checkstring = 1;
1157 lop = 1;
1158 break;
1159
1160 case INTRINSIC_LE:
3bed9dd0 1161 case INTRINSIC_LE_OS:
6de9cd9a
DN
1162 code = LE_EXPR;
1163 checkstring = 1;
1164 lop = 1;
1165 break;
1166
1167 case INTRINSIC_USER:
1168 case INTRINSIC_ASSIGN:
1169 /* These should be converted into function calls by the frontend. */
6e45f57b 1170 gcc_unreachable ();
6de9cd9a
DN
1171
1172 default:
1173 fatal_error ("Unknown intrinsic op");
1174 return;
1175 }
1176
f8d0aee5 1177 /* The only exception to this is **, which is handled separately anyway. */
58b03ab2 1178 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
6de9cd9a 1179
58b03ab2 1180 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
6de9cd9a
DN
1181 checkstring = 0;
1182
1183 /* lhs */
1184 gfc_init_se (&lse, se);
58b03ab2 1185 gfc_conv_expr (&lse, expr->value.op.op1);
6de9cd9a
DN
1186 gfc_add_block_to_block (&se->pre, &lse.pre);
1187
1188 /* rhs */
1189 gfc_init_se (&rse, se);
58b03ab2 1190 gfc_conv_expr (&rse, expr->value.op.op2);
6de9cd9a
DN
1191 gfc_add_block_to_block (&se->pre, &rse.pre);
1192
6de9cd9a
DN
1193 if (checkstring)
1194 {
1195 gfc_conv_string_parameter (&lse);
1196 gfc_conv_string_parameter (&rse);
6de9cd9a 1197
0a821a92
FW
1198 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
1199 rse.string_length, rse.expr);
ac816b02 1200 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
0a821a92 1201 gfc_add_block_to_block (&lse.post, &rse.post);
6de9cd9a
DN
1202 }
1203
1204 type = gfc_typenode_for_spec (&expr->ts);
1205
1206 if (lop)
1207 {
1208 /* The result of logical ops is always boolean_type_node. */
c9ff1de3 1209 tmp = fold_build2 (code, boolean_type_node, lse.expr, rse.expr);
6de9cd9a
DN
1210 se->expr = convert (type, tmp);
1211 }
1212 else
10c7a96f 1213 se->expr = fold_build2 (code, type, lse.expr, rse.expr);
6de9cd9a 1214
6de9cd9a
DN
1215 /* Add the post blocks. */
1216 gfc_add_block_to_block (&se->post, &rse.post);
1217 gfc_add_block_to_block (&se->post, &lse.post);
1218}
1219
0a821a92
FW
1220/* If a string's length is one, we convert it to a single character. */
1221
1222static tree
1223gfc_to_single_character (tree len, tree str)
1224{
1225 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
1226
1227 if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1
1228 && TREE_INT_CST_HIGH (len) == 0)
1229 {
1230 str = fold_convert (pchar_type_node, str);
1231 return build_fold_indirect_ref (str);
1232 }
1233
1234 return NULL_TREE;
1235}
1236
e032c2a1
CR
1237
1238void
1239gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
1240{
1241
1242 if (sym->backend_decl)
1243 {
1244 /* This becomes the nominal_type in
1245 function.c:assign_parm_find_data_types. */
1246 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
1247 /* This becomes the passed_type in
1248 function.c:assign_parm_find_data_types. C promotes char to
1249 integer for argument passing. */
1250 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
1251
1252 DECL_BY_REFERENCE (sym->backend_decl) = 0;
1253 }
1254
1255 if (expr != NULL)
1256 {
1257 /* If we have a constant character expression, make it into an
1258 integer. */
1259 if ((*expr)->expr_type == EXPR_CONSTANT)
1260 {
1261 gfc_typespec ts;
1262
1263 *expr = gfc_int_expr ((int)(*expr)->value.character.string[0]);
1264 if ((*expr)->ts.kind != gfc_c_int_kind)
1265 {
1266 /* The expr needs to be compatible with a C int. If the
1267 conversion fails, then the 2 causes an ICE. */
1268 ts.type = BT_INTEGER;
1269 ts.kind = gfc_c_int_kind;
1270 gfc_convert_type (*expr, &ts, 2);
1271 }
1272 }
1273 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
1274 {
1275 if ((*expr)->ref == NULL)
1276 {
1277 se->expr = gfc_to_single_character
1278 (build_int_cst (integer_type_node, 1),
1279 gfc_build_addr_expr (pchar_type_node,
1280 gfc_get_symbol_decl
1281 ((*expr)->symtree->n.sym)));
1282 }
1283 else
1284 {
1285 gfc_conv_variable (se, *expr);
1286 se->expr = gfc_to_single_character
1287 (build_int_cst (integer_type_node, 1),
1288 gfc_build_addr_expr (pchar_type_node, se->expr));
1289 }
1290 }
1291 }
1292}
1293
1294
0a821a92
FW
1295/* Compare two strings. If they are all single characters, the result is the
1296 subtraction of them. Otherwise, we build a library call. */
1297
1298tree
1299gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2)
1300{
1301 tree sc1;
1302 tree sc2;
0a821a92
FW
1303 tree tmp;
1304
1305 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
1306 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
1307
0a821a92
FW
1308 sc1 = gfc_to_single_character (len1, str1);
1309 sc2 = gfc_to_single_character (len2, str2);
1310
1311 /* Deal with single character specially. */
1312 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
1313 {
c9ff1de3
FXC
1314 sc1 = fold_convert (integer_type_node, sc1);
1315 sc2 = fold_convert (integer_type_node, sc2);
1316 tmp = fold_build2 (MINUS_EXPR, integer_type_node, sc1, sc2);
0a821a92
FW
1317 }
1318 else
5039610b
SL
1319 /* Build a call for the comparison. */
1320 tmp = build_call_expr (gfor_fndecl_compare_string, 4,
1321 len1, str1, len2, str2);
0a821a92
FW
1322 return tmp;
1323}
f8d0aee5 1324
6de9cd9a
DN
1325static void
1326gfc_conv_function_val (gfc_se * se, gfc_symbol * sym)
1327{
1328 tree tmp;
1329
1330 if (sym->attr.dummy)
1331 {
1332 tmp = gfc_get_symbol_decl (sym);
6e45f57b 1333 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
6de9cd9a 1334 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
6de9cd9a
DN
1335 }
1336 else
1337 {
1338 if (!sym->backend_decl)
1339 sym->backend_decl = gfc_get_extern_function_decl (sym);
1340
1341 tmp = sym->backend_decl;
7074ea72
AL
1342 if (sym->attr.cray_pointee)
1343 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
1344 gfc_get_symbol_decl (sym->cp_pointer));
0348d6fd
RS
1345 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1346 {
1347 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
488ce07b 1348 tmp = build_fold_addr_expr (tmp);
0348d6fd
RS
1349 }
1350 }
1351 se->expr = tmp;
1352}
1353
1354
a00b8d1a
PT
1355/* Translate the call for an elemental subroutine call used in an operator
1356 assignment. This is a simplified version of gfc_conv_function_call. */
1357
1358tree
1359gfc_conv_operator_assign (gfc_se *lse, gfc_se *rse, gfc_symbol *sym)
1360{
1361 tree args;
1362 tree tmp;
1363 gfc_se se;
1364 stmtblock_t block;
1365
1366 /* Only elemental subroutines with two arguments. */
1367 gcc_assert (sym->attr.elemental && sym->attr.subroutine);
1368 gcc_assert (sym->formal->next->next == NULL);
1369
1370 gfc_init_block (&block);
1371
1372 gfc_add_block_to_block (&block, &lse->pre);
1373 gfc_add_block_to_block (&block, &rse->pre);
1374
1375 /* Build the argument list for the call, including hidden string lengths. */
1376 args = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (lse->expr));
1377 args = gfc_chainon_list (args, build_fold_addr_expr (rse->expr));
1378 if (lse->string_length != NULL_TREE)
1379 args = gfc_chainon_list (args, lse->string_length);
1380 if (rse->string_length != NULL_TREE)
1381 args = gfc_chainon_list (args, rse->string_length);
1382
1383 /* Build the function call. */
1384 gfc_init_se (&se, NULL);
1385 gfc_conv_function_val (&se, sym);
1386 tmp = TREE_TYPE (TREE_TYPE (TREE_TYPE (se.expr)));
5039610b 1387 tmp = build_call_list (tmp, se.expr, args);
a00b8d1a
PT
1388 gfc_add_expr_to_block (&block, tmp);
1389
1390 gfc_add_block_to_block (&block, &lse->post);
1391 gfc_add_block_to_block (&block, &rse->post);
1392
1393 return gfc_finish_block (&block);
1394}
1395
1396
0348d6fd
RS
1397/* Initialize MAPPING. */
1398
62ab4a54 1399void
0348d6fd
RS
1400gfc_init_interface_mapping (gfc_interface_mapping * mapping)
1401{
1402 mapping->syms = NULL;
1403 mapping->charlens = NULL;
1404}
1405
1406
1407/* Free all memory held by MAPPING (but not MAPPING itself). */
1408
62ab4a54 1409void
0348d6fd
RS
1410gfc_free_interface_mapping (gfc_interface_mapping * mapping)
1411{
1412 gfc_interface_sym_mapping *sym;
1413 gfc_interface_sym_mapping *nextsym;
1414 gfc_charlen *cl;
1415 gfc_charlen *nextcl;
1416
1417 for (sym = mapping->syms; sym; sym = nextsym)
1418 {
1419 nextsym = sym->next;
1420 gfc_free_symbol (sym->new->n.sym);
0a164a3c 1421 gfc_free_expr (sym->expr);
0348d6fd
RS
1422 gfc_free (sym->new);
1423 gfc_free (sym);
1424 }
1425 for (cl = mapping->charlens; cl; cl = nextcl)
1426 {
1427 nextcl = cl->next;
1428 gfc_free_expr (cl->length);
1429 gfc_free (cl);
6de9cd9a
DN
1430 }
1431}
1432
1433
0348d6fd
RS
1434/* Return a copy of gfc_charlen CL. Add the returned structure to
1435 MAPPING so that it will be freed by gfc_free_interface_mapping. */
1436
1437static gfc_charlen *
1438gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
1439 gfc_charlen * cl)
1440{
1441 gfc_charlen *new;
1442
1443 new = gfc_get_charlen ();
1444 new->next = mapping->charlens;
1445 new->length = gfc_copy_expr (cl->length);
1446
1447 mapping->charlens = new;
1448 return new;
1449}
1450
1451
1452/* A subroutine of gfc_add_interface_mapping. Return a descriptorless
1453 array variable that can be used as the actual argument for dummy
1454 argument SYM. Add any initialization code to BLOCK. PACKED is as
1455 for gfc_get_nodesc_array_type and DATA points to the first element
1456 in the passed array. */
1457
1458static tree
1459gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
dcfef7d4 1460 gfc_packed packed, tree data)
0348d6fd
RS
1461{
1462 tree type;
1463 tree var;
1464
1465 type = gfc_typenode_for_spec (&sym->ts);
1466 type = gfc_get_nodesc_array_type (type, sym->as, packed);
1467
20236f90 1468 var = gfc_create_var (type, "ifm");
0348d6fd
RS
1469 gfc_add_modify_expr (block, var, fold_convert (type, data));
1470
1471 return var;
1472}
1473
1474
1475/* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
1476 and offset of descriptorless array type TYPE given that it has the same
1477 size as DESC. Add any set-up code to BLOCK. */
1478
1479static void
1480gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
1481{
1482 int n;
1483 tree dim;
1484 tree offset;
1485 tree tmp;
1486
1487 offset = gfc_index_zero_node;
1488 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
1489 {
dd5797cc 1490 dim = gfc_rank_cst[n];
0348d6fd 1491 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
dd5797cc
PT
1492 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
1493 {
1494 GFC_TYPE_ARRAY_LBOUND (type, n)
1495 = gfc_conv_descriptor_lbound (desc, dim);
1496 GFC_TYPE_ARRAY_UBOUND (type, n)
1497 = gfc_conv_descriptor_ubound (desc, dim);
1498 }
1499 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
0348d6fd 1500 {
0348d6fd
RS
1501 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1502 gfc_conv_descriptor_ubound (desc, dim),
1503 gfc_conv_descriptor_lbound (desc, dim));
1504 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1505 GFC_TYPE_ARRAY_LBOUND (type, n),
1506 tmp);
1507 tmp = gfc_evaluate_now (tmp, block);
1508 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
1509 }
1510 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
1511 GFC_TYPE_ARRAY_LBOUND (type, n),
1512 GFC_TYPE_ARRAY_STRIDE (type, n));
1513 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
1514 }
1515 offset = gfc_evaluate_now (offset, block);
1516 GFC_TYPE_ARRAY_OFFSET (type) = offset;
1517}
1518
1519
1520/* Extend MAPPING so that it maps dummy argument SYM to the value stored
1521 in SE. The caller may still use se->expr and se->string_length after
1522 calling this function. */
1523
62ab4a54 1524void
0348d6fd 1525gfc_add_interface_mapping (gfc_interface_mapping * mapping,
0a164a3c
PT
1526 gfc_symbol * sym, gfc_se * se,
1527 gfc_expr *expr)
0348d6fd
RS
1528{
1529 gfc_interface_sym_mapping *sm;
1530 tree desc;
1531 tree tmp;
1532 tree value;
1533 gfc_symbol *new_sym;
1534 gfc_symtree *root;
1535 gfc_symtree *new_symtree;
1536
1537 /* Create a new symbol to represent the actual argument. */
1538 new_sym = gfc_new_symbol (sym->name, NULL);
1539 new_sym->ts = sym->ts;
1540 new_sym->attr.referenced = 1;
1541 new_sym->attr.dimension = sym->attr.dimension;
1542 new_sym->attr.pointer = sym->attr.pointer;
17029ac2 1543 new_sym->attr.allocatable = sym->attr.allocatable;
0348d6fd 1544 new_sym->attr.flavor = sym->attr.flavor;
0a164a3c 1545 new_sym->attr.function = sym->attr.function;
0348d6fd
RS
1546
1547 /* Create a fake symtree for it. */
1548 root = NULL;
1549 new_symtree = gfc_new_symtree (&root, sym->name);
1550 new_symtree->n.sym = new_sym;
1551 gcc_assert (new_symtree == root);
1552
1553 /* Create a dummy->actual mapping. */
1554 sm = gfc_getmem (sizeof (*sm));
1555 sm->next = mapping->syms;
1556 sm->old = sym;
1557 sm->new = new_symtree;
0a164a3c 1558 sm->expr = gfc_copy_expr (expr);
0348d6fd
RS
1559 mapping->syms = sm;
1560
1561 /* Stabilize the argument's value. */
0a164a3c
PT
1562 if (!sym->attr.function && se)
1563 se->expr = gfc_evaluate_now (se->expr, &se->pre);
0348d6fd
RS
1564
1565 if (sym->ts.type == BT_CHARACTER)
1566 {
1567 /* Create a copy of the dummy argument's length. */
1568 new_sym->ts.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.cl);
0a164a3c 1569 sm->expr->ts.cl = new_sym->ts.cl;
0348d6fd
RS
1570
1571 /* If the length is specified as "*", record the length that
1572 the caller is passing. We should use the callee's length
1573 in all other cases. */
0a164a3c 1574 if (!new_sym->ts.cl->length && se)
0348d6fd
RS
1575 {
1576 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
1577 new_sym->ts.cl->backend_decl = se->string_length;
1578 }
1579 }
1580
0a164a3c
PT
1581 if (!se)
1582 return;
1583
0348d6fd
RS
1584 /* Use the passed value as-is if the argument is a function. */
1585 if (sym->attr.flavor == FL_PROCEDURE)
1586 value = se->expr;
1587
1588 /* If the argument is either a string or a pointer to a string,
1589 convert it to a boundless character type. */
1590 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
1591 {
1592 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
1593 tmp = build_pointer_type (tmp);
1594 if (sym->attr.pointer)
95cb77e6
WG
1595 value = build_fold_indirect_ref (se->expr);
1596 else
1597 value = se->expr;
1598 value = fold_convert (tmp, value);
0348d6fd
RS
1599 }
1600
17029ac2
EE
1601 /* If the argument is a scalar, a pointer to an array or an allocatable,
1602 dereference it. */
1603 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
38611275 1604 value = build_fold_indirect_ref (se->expr);
ed78a116
PT
1605
1606 /* For character(*), use the actual argument's descriptor. */
1607 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.cl->length)
1608 value = build_fold_indirect_ref (se->expr);
0348d6fd
RS
1609
1610 /* If the argument is an array descriptor, use it to determine
1611 information about the actual argument's shape. */
1612 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
1613 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
1614 {
1615 /* Get the actual argument's descriptor. */
38611275 1616 desc = build_fold_indirect_ref (se->expr);
0348d6fd
RS
1617
1618 /* Create the replacement variable. */
1619 tmp = gfc_conv_descriptor_data_get (desc);
dcfef7d4
TS
1620 value = gfc_get_interface_mapping_array (&se->pre, sym,
1621 PACKED_NO, tmp);
0348d6fd
RS
1622
1623 /* Use DESC to work out the upper bounds, strides and offset. */
1624 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
1625 }
1626 else
1627 /* Otherwise we have a packed array. */
dcfef7d4
TS
1628 value = gfc_get_interface_mapping_array (&se->pre, sym,
1629 PACKED_FULL, se->expr);
0348d6fd
RS
1630
1631 new_sym->backend_decl = value;
1632}
1633
1634
1635/* Called once all dummy argument mappings have been added to MAPPING,
1636 but before the mapping is used to evaluate expressions. Pre-evaluate
1637 the length of each argument, adding any initialization code to PRE and
1638 any finalization code to POST. */
1639
62ab4a54 1640void
0348d6fd
RS
1641gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
1642 stmtblock_t * pre, stmtblock_t * post)
1643{
1644 gfc_interface_sym_mapping *sym;
1645 gfc_expr *expr;
1646 gfc_se se;
1647
1648 for (sym = mapping->syms; sym; sym = sym->next)
1649 if (sym->new->n.sym->ts.type == BT_CHARACTER
1650 && !sym->new->n.sym->ts.cl->backend_decl)
1651 {
1652 expr = sym->new->n.sym->ts.cl->length;
1653 gfc_apply_interface_mapping_to_expr (mapping, expr);
1654 gfc_init_se (&se, NULL);
1655 gfc_conv_expr (&se, expr);
1656
1657 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1658 gfc_add_block_to_block (pre, &se.pre);
1659 gfc_add_block_to_block (post, &se.post);
1660
1661 sym->new->n.sym->ts.cl->backend_decl = se.expr;
1662 }
1663}
1664
1665
1666/* Like gfc_apply_interface_mapping_to_expr, but applied to
1667 constructor C. */
1668
1669static void
1670gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
1671 gfc_constructor * c)
1672{
1673 for (; c; c = c->next)
1674 {
1675 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
1676 if (c->iterator)
1677 {
1678 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
1679 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
1680 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
1681 }
1682 }
1683}
1684
1685
1686/* Like gfc_apply_interface_mapping_to_expr, but applied to
1687 reference REF. */
1688
1689static void
1690gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
1691 gfc_ref * ref)
1692{
1693 int n;
1694
1695 for (; ref; ref = ref->next)
1696 switch (ref->type)
1697 {
1698 case REF_ARRAY:
1699 for (n = 0; n < ref->u.ar.dimen; n++)
1700 {
1701 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
1702 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
1703 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
1704 }
1705 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.offset);
1706 break;
1707
1708 case REF_COMPONENT:
1709 break;
1710
1711 case REF_SUBSTRING:
1712 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
1713 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
1714 break;
1715 }
1716}
1717
1718
0a164a3c
PT
1719/* Convert intrinsic function calls into result expressions. */
1720static bool
1721gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping * mapping)
1722{
1723 gfc_symbol *sym;
1724 gfc_expr *new_expr;
1725 gfc_expr *arg1;
1726 gfc_expr *arg2;
1727 int d, dup;
1728
1729 arg1 = expr->value.function.actual->expr;
1730 if (expr->value.function.actual->next)
1731 arg2 = expr->value.function.actual->next->expr;
1732 else
1733 arg2 = NULL;
1734
1735 sym = arg1->symtree->n.sym;
1736
1737 if (sym->attr.dummy)
1738 return false;
1739
1740 new_expr = NULL;
1741
1742 switch (expr->value.function.isym->id)
1743 {
1744 case GFC_ISYM_LEN:
1745 /* TODO figure out why this condition is necessary. */
1746 if (sym->attr.function
1747 && arg1->ts.cl->length->expr_type != EXPR_CONSTANT
1748 && arg1->ts.cl->length->expr_type != EXPR_VARIABLE)
1749 return false;
1750
1751 new_expr = gfc_copy_expr (arg1->ts.cl->length);
1752 break;
1753
1754 case GFC_ISYM_SIZE:
1755 if (!sym->as)
1756 return false;
1757
1758 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
1759 {
1760 dup = mpz_get_si (arg2->value.integer);
1761 d = dup - 1;
1762 }
1763 else
1764 {
1765 dup = sym->as->rank;
1766 d = 0;
1767 }
1768
1769 for (; d < dup; d++)
1770 {
1771 gfc_expr *tmp;
1772 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]), gfc_int_expr (1));
1773 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
1774 if (new_expr)
1775 new_expr = gfc_multiply (new_expr, tmp);
1776 else
1777 new_expr = tmp;
1778 }
1779 break;
1780
1781 case GFC_ISYM_LBOUND:
1782 case GFC_ISYM_UBOUND:
1783 /* TODO These implementations of lbound and ubound do not limit if
1784 the size < 0, according to F95's 13.14.53 and 13.14.113. */
1785
1786 if (!sym->as)
1787 return false;
1788
1789 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
1790 d = mpz_get_si (arg2->value.integer) - 1;
1791 else
1792 /* TODO: If the need arises, this could produce an array of
1793 ubound/lbounds. */
1794 gcc_unreachable ();
1795
1796 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
1797 new_expr = gfc_copy_expr (sym->as->lower[d]);
1798 else
1799 new_expr = gfc_copy_expr (sym->as->upper[d]);
1800 break;
1801
1802 default:
1803 break;
1804 }
1805
1806 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
1807 if (!new_expr)
1808 return false;
1809
1810 gfc_replace_expr (expr, new_expr);
1811 return true;
1812}
1813
1814
1815static void
1816gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
1817 gfc_interface_mapping * mapping)
1818{
1819 gfc_formal_arglist *f;
1820 gfc_actual_arglist *actual;
1821
1822 actual = expr->value.function.actual;
1823 f = map_expr->symtree->n.sym->formal;
1824
1825 for (; f && actual; f = f->next, actual = actual->next)
1826 {
1827 if (!actual->expr)
1828 continue;
1829
1830 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
1831 }
1832
1833 if (map_expr->symtree->n.sym->attr.dimension)
1834 {
1835 int d;
1836 gfc_array_spec *as;
1837
1838 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
1839
1840 for (d = 0; d < as->rank; d++)
1841 {
1842 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
1843 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
1844 }
1845
1846 expr->value.function.esym->as = as;
1847 }
1848
1849 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
1850 {
1851 expr->value.function.esym->ts.cl->length
1852 = gfc_copy_expr (map_expr->symtree->n.sym->ts.cl->length);
1853
1854 gfc_apply_interface_mapping_to_expr (mapping,
1855 expr->value.function.esym->ts.cl->length);
1856 }
1857}
1858
1859
0348d6fd
RS
1860/* EXPR is a copy of an expression that appeared in the interface
1861 associated with MAPPING. Walk it recursively looking for references to
1862 dummy arguments that MAPPING maps to actual arguments. Replace each such
1863 reference with a reference to the associated actual argument. */
1864
0a164a3c 1865static void
0348d6fd
RS
1866gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
1867 gfc_expr * expr)
1868{
1869 gfc_interface_sym_mapping *sym;
1870 gfc_actual_arglist *actual;
1871
1872 if (!expr)
0a164a3c 1873 return;
0348d6fd
RS
1874
1875 /* Copying an expression does not copy its length, so do that here. */
1876 if (expr->ts.type == BT_CHARACTER && expr->ts.cl)
1877 {
1878 expr->ts.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.cl);
1879 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.cl->length);
1880 }
1881
1882 /* Apply the mapping to any references. */
1883 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
1884
1885 /* ...and to the expression's symbol, if it has one. */
0a164a3c
PT
1886 /* TODO Find out why the condition on expr->symtree had to be moved into
1887 the loop rather than being ouside it, as originally. */
1888 for (sym = mapping->syms; sym; sym = sym->next)
1889 if (expr->symtree && sym->old == expr->symtree->n.sym)
1890 {
1891 if (sym->new->n.sym->backend_decl)
1892 expr->symtree = sym->new;
1893 else if (sym->expr)
1894 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
1895 }
0348d6fd 1896
0a164a3c 1897 /* ...and to subexpressions in expr->value. */
0348d6fd
RS
1898 switch (expr->expr_type)
1899 {
1900 case EXPR_VARIABLE:
1901 case EXPR_CONSTANT:
1902 case EXPR_NULL:
1903 case EXPR_SUBSTRING:
1904 break;
1905
1906 case EXPR_OP:
1907 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
1908 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
1909 break;
1910
1911 case EXPR_FUNCTION:
0a164a3c
PT
1912 for (actual = expr->value.function.actual; actual; actual = actual->next)
1913 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
1914
36032710 1915 if (expr->value.function.esym == NULL
6a661315 1916 && expr->value.function.isym != NULL
0a164a3c
PT
1917 && expr->value.function.actual->expr->symtree
1918 && gfc_map_intrinsic_function (expr, mapping))
1919 break;
6a661315 1920
0348d6fd
RS
1921 for (sym = mapping->syms; sym; sym = sym->next)
1922 if (sym->old == expr->value.function.esym)
0a164a3c
PT
1923 {
1924 expr->value.function.esym = sym->new->n.sym;
1925 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
1926 expr->value.function.esym->result = sym->new->n.sym;
1927 }
0348d6fd
RS
1928 break;
1929
1930 case EXPR_ARRAY:
1931 case EXPR_STRUCTURE:
1932 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
1933 break;
1934 }
0a164a3c
PT
1935
1936 return;
0348d6fd
RS
1937}
1938
1939
1940/* Evaluate interface expression EXPR using MAPPING. Store the result
1941 in SE. */
1942
62ab4a54 1943void
0348d6fd
RS
1944gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
1945 gfc_se * se, gfc_expr * expr)
1946{
1947 expr = gfc_copy_expr (expr);
1948 gfc_apply_interface_mapping_to_expr (mapping, expr);
1949 gfc_conv_expr (se, expr);
1950 se->expr = gfc_evaluate_now (se->expr, &se->pre);
1951 gfc_free_expr (expr);
1952}
1953
1d6b7f39 1954
68ea355b
PT
1955/* Returns a reference to a temporary array into which a component of
1956 an actual argument derived type array is copied and then returned
1d6b7f39 1957 after the function call. */
d4feb3d3 1958void
1d6b7f39
PT
1959gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr,
1960 int g77, sym_intent intent)
68ea355b
PT
1961{
1962 gfc_se lse;
1963 gfc_se rse;
1964 gfc_ss *lss;
1965 gfc_ss *rss;
1966 gfc_loopinfo loop;
1967 gfc_loopinfo loop2;
1968 gfc_ss_info *info;
1969 tree offset;
1970 tree tmp_index;
1971 tree tmp;
1972 tree base_type;
1973 stmtblock_t body;
1974 int n;
1975
1976 gcc_assert (expr->expr_type == EXPR_VARIABLE);
1977
1978 gfc_init_se (&lse, NULL);
1979 gfc_init_se (&rse, NULL);
1980
1981 /* Walk the argument expression. */
1982 rss = gfc_walk_expr (expr);
1983
1984 gcc_assert (rss != gfc_ss_terminator);
1985
1986 /* Initialize the scalarizer. */
1987 gfc_init_loopinfo (&loop);
1988 gfc_add_ss_to_loop (&loop, rss);
1989
1990 /* Calculate the bounds of the scalarization. */
1991 gfc_conv_ss_startstride (&loop);
1992
1993 /* Build an ss for the temporary. */
07368af0
PT
1994 if (expr->ts.type == BT_CHARACTER && !expr->ts.cl->backend_decl)
1995 gfc_conv_string_length (expr->ts.cl, &parmse->pre);
1996
68ea355b
PT
1997 base_type = gfc_typenode_for_spec (&expr->ts);
1998 if (GFC_ARRAY_TYPE_P (base_type)
1999 || GFC_DESCRIPTOR_TYPE_P (base_type))
2000 base_type = gfc_get_element_type (base_type);
2001
2002 loop.temp_ss = gfc_get_ss ();;
2003 loop.temp_ss->type = GFC_SS_TEMP;
2004 loop.temp_ss->data.temp.type = base_type;
2005
2006 if (expr->ts.type == BT_CHARACTER)
07368af0
PT
2007 loop.temp_ss->string_length = expr->ts.cl->backend_decl;
2008 else
2009 loop.temp_ss->string_length = NULL;
68ea355b 2010
07368af0 2011 parmse->string_length = loop.temp_ss->string_length;
68ea355b
PT
2012 loop.temp_ss->data.temp.dimen = loop.dimen;
2013 loop.temp_ss->next = gfc_ss_terminator;
2014
2015 /* Associate the SS with the loop. */
2016 gfc_add_ss_to_loop (&loop, loop.temp_ss);
2017
2018 /* Setup the scalarizing loops. */
2019 gfc_conv_loop_setup (&loop);
2020
2021 /* Pass the temporary descriptor back to the caller. */
2022 info = &loop.temp_ss->data.info;
2023 parmse->expr = info->descriptor;
2024
2025 /* Setup the gfc_se structures. */
2026 gfc_copy_loopinfo_to_se (&lse, &loop);
2027 gfc_copy_loopinfo_to_se (&rse, &loop);
2028
2029 rse.ss = rss;
2030 lse.ss = loop.temp_ss;
2031 gfc_mark_ss_chain_used (rss, 1);
2032 gfc_mark_ss_chain_used (loop.temp_ss, 1);
2033
2034 /* Start the scalarized loop body. */
2035 gfc_start_scalarized_body (&loop, &body);
2036
2037 /* Translate the expression. */
2038 gfc_conv_expr (&rse, expr);
2039
2040 gfc_conv_tmp_array_ref (&lse);
2041 gfc_advance_se_ss_chain (&lse);
2042
1855915a
PT
2043 if (intent != INTENT_OUT)
2044 {
5046aff5 2045 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false);
1855915a
PT
2046 gfc_add_expr_to_block (&body, tmp);
2047 gcc_assert (rse.ss == gfc_ss_terminator);
2048 gfc_trans_scalarizing_loops (&loop, &body);
2049 }
8c086c9c
PT
2050 else
2051 {
58b6e047
PT
2052 /* Make sure that the temporary declaration survives by merging
2053 all the loop declarations into the current context. */
2054 for (n = 0; n < loop.dimen; n++)
2055 {
2056 gfc_merge_block_scope (&body);
2057 body = loop.code[loop.order[n]];
2058 }
2059 gfc_merge_block_scope (&body);
8c086c9c 2060 }
68ea355b
PT
2061
2062 /* Add the post block after the second loop, so that any
2063 freeing of allocated memory is done at the right time. */
2064 gfc_add_block_to_block (&parmse->pre, &loop.pre);
2065
2066 /**********Copy the temporary back again.*********/
2067
2068 gfc_init_se (&lse, NULL);
2069 gfc_init_se (&rse, NULL);
2070
2071 /* Walk the argument expression. */
2072 lss = gfc_walk_expr (expr);
2073 rse.ss = loop.temp_ss;
2074 lse.ss = lss;
2075
2076 /* Initialize the scalarizer. */
2077 gfc_init_loopinfo (&loop2);
2078 gfc_add_ss_to_loop (&loop2, lss);
2079
2080 /* Calculate the bounds of the scalarization. */
2081 gfc_conv_ss_startstride (&loop2);
2082
2083 /* Setup the scalarizing loops. */
2084 gfc_conv_loop_setup (&loop2);
2085
2086 gfc_copy_loopinfo_to_se (&lse, &loop2);
2087 gfc_copy_loopinfo_to_se (&rse, &loop2);
2088
2089 gfc_mark_ss_chain_used (lss, 1);
2090 gfc_mark_ss_chain_used (loop.temp_ss, 1);
2091
2092 /* Declare the variable to hold the temporary offset and start the
2093 scalarized loop body. */
2094 offset = gfc_create_var (gfc_array_index_type, NULL);
2095 gfc_start_scalarized_body (&loop2, &body);
2096
2097 /* Build the offsets for the temporary from the loop variables. The
2098 temporary array has lbounds of zero and strides of one in all
2099 dimensions, so this is very simple. The offset is only computed
2100 outside the innermost loop, so the overall transfer could be
b82feea5 2101 optimized further. */
68ea355b
PT
2102 info = &rse.ss->data.info;
2103
2104 tmp_index = gfc_index_zero_node;
2105 for (n = info->dimen - 1; n > 0; n--)
2106 {
2107 tree tmp_str;
2108 tmp = rse.loop->loopvar[n];
2109 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2110 tmp, rse.loop->from[n]);
2111 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2112 tmp, tmp_index);
2113
2114 tmp_str = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2115 rse.loop->to[n-1], rse.loop->from[n-1]);
2116 tmp_str = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2117 tmp_str, gfc_index_one_node);
2118
2119 tmp_index = fold_build2 (MULT_EXPR, gfc_array_index_type,
2120 tmp, tmp_str);
2121 }
2122
2123 tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2124 tmp_index, rse.loop->from[0]);
2125 gfc_add_modify_expr (&rse.loop->code[0], offset, tmp_index);
2126
2127 tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2128 rse.loop->loopvar[0], offset);
2129
2130 /* Now use the offset for the reference. */
2131 tmp = build_fold_indirect_ref (info->data);
1d6b7f39 2132 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
68ea355b
PT
2133
2134 if (expr->ts.type == BT_CHARACTER)
2135 rse.string_length = expr->ts.cl->backend_decl;
2136
2137 gfc_conv_expr (&lse, expr);
2138
2139 gcc_assert (lse.ss == gfc_ss_terminator);
2140
5046aff5 2141 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
68ea355b
PT
2142 gfc_add_expr_to_block (&body, tmp);
2143
2144 /* Generate the copying loops. */
2145 gfc_trans_scalarizing_loops (&loop2, &body);
2146
2147 /* Wrap the whole thing up by adding the second loop to the post-block
1855915a 2148 and following it by the post-block of the first loop. In this way,
68ea355b 2149 if the temporary needs freeing, it is done after use! */
1855915a
PT
2150 if (intent != INTENT_IN)
2151 {
2152 gfc_add_block_to_block (&parmse->post, &loop2.pre);
2153 gfc_add_block_to_block (&parmse->post, &loop2.post);
2154 }
68ea355b
PT
2155
2156 gfc_add_block_to_block (&parmse->post, &loop.post);
2157
2158 gfc_cleanup_loop (&loop);
2159 gfc_cleanup_loop (&loop2);
2160
2161 /* Pass the string length to the argument expression. */
2162 if (expr->ts.type == BT_CHARACTER)
2163 parmse->string_length = expr->ts.cl->backend_decl;
2164
2165 /* We want either the address for the data or the address of the descriptor,
2166 depending on the mode of passing array arguments. */
2167 if (g77)
2168 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
2169 else
2170 parmse->expr = build_fold_addr_expr (parmse->expr);
2171
2172 return;
2173}
2174
0348d6fd 2175
7fcafa71
PT
2176/* Generate the code for argument list functions. */
2177
2178static void
2179conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
2180{
7fcafa71
PT
2181 /* Pass by value for g77 %VAL(arg), pass the address
2182 indirectly for %LOC, else by reference. Thus %REF
2183 is a "do-nothing" and %LOC is the same as an F95
2184 pointer. */
2185 if (strncmp (name, "%VAL", 4) == 0)
7193e30a 2186 gfc_conv_expr (se, expr);
7fcafa71
PT
2187 else if (strncmp (name, "%LOC", 4) == 0)
2188 {
2189 gfc_conv_expr_reference (se, expr);
2190 se->expr = gfc_build_addr_expr (NULL, se->expr);
2191 }
2192 else if (strncmp (name, "%REF", 4) == 0)
2193 gfc_conv_expr_reference (se, expr);
2194 else
2195 gfc_error ("Unknown argument list function at %L", &expr->where);
2196}
2197
2198
6de9cd9a 2199/* Generate code for a procedure call. Note can return se->post != NULL.
dda895f9 2200 If se->direct_byref is set then se->expr contains the return parameter.
49de9e73 2201 Return nonzero, if the call has alternate specifiers. */
6de9cd9a 2202
dda895f9 2203int
6de9cd9a 2204gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
5a0aad31 2205 gfc_actual_arglist * arg, tree append_args)
6de9cd9a 2206{
0348d6fd 2207 gfc_interface_mapping mapping;
6de9cd9a 2208 tree arglist;
0348d6fd 2209 tree retargs;
6de9cd9a
DN
2210 tree tmp;
2211 tree fntype;
2212 gfc_se parmse;
2213 gfc_ss *argss;
2214 gfc_ss_info *info;
2215 int byref;
5046aff5 2216 int parm_kind;
6de9cd9a
DN
2217 tree type;
2218 tree var;
2219 tree len;
2220 tree stringargs;
2221 gfc_formal_arglist *formal;
dda895f9 2222 int has_alternate_specifier = 0;
0348d6fd 2223 bool need_interface_mapping;
8e119f1b 2224 bool callee_alloc;
0348d6fd
RS
2225 gfc_typespec ts;
2226 gfc_charlen cl;
e15e9be3
PT
2227 gfc_expr *e;
2228 gfc_symbol *fsym;
f5f701ad 2229 stmtblock_t post;
5046aff5 2230 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
6de9cd9a
DN
2231
2232 arglist = NULL_TREE;
0348d6fd 2233 retargs = NULL_TREE;
6de9cd9a
DN
2234 stringargs = NULL_TREE;
2235 var = NULL_TREE;
2236 len = NULL_TREE;
2237
089db47d 2238 if (sym->from_intmod == INTMOD_ISO_C_BINDING)
972345f2 2239 {
089db47d 2240 if (sym->intmod_sym_id == ISOCBINDING_LOC)
972345f2 2241 {
089db47d
CR
2242 if (arg->expr->rank == 0)
2243 gfc_conv_expr_reference (se, arg->expr);
2244 else
2245 {
2246 int f;
2247 /* This is really the actual arg because no formal arglist is
2248 created for C_LOC. */
2249 fsym = arg->expr->symtree->n.sym;
2250
2251 /* We should want it to do g77 calling convention. */
2252 f = (fsym != NULL)
2253 && !(fsym->attr.pointer || fsym->attr.allocatable)
2254 && fsym->as->type != AS_ASSUMED_SHAPE;
2255 f = f || !sym->attr.always_explicit;
2256
2257 argss = gfc_walk_expr (arg->expr);
2258 gfc_conv_array_parameter (se, arg->expr, argss, f);
2259 }
2260
2261 return 0;
972345f2 2262 }
089db47d 2263 else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC)
972345f2 2264 {
089db47d
CR
2265 arg->expr->ts.type = sym->ts.derived->ts.type;
2266 arg->expr->ts.f90_type = sym->ts.derived->ts.f90_type;
2267 arg->expr->ts.kind = sym->ts.derived->ts.kind;
2268 gfc_conv_expr_reference (se, arg->expr);
2269
9fd25b5c
CR
2270 return 0;
2271 }
2272 else if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
2273 {
2274 gfc_se arg1se;
2275 gfc_se arg2se;
2276
2277 /* Build the addr_expr for the first argument. The argument is
2278 already an *address* so we don't need to set want_pointer in
2279 the gfc_se. */
2280 gfc_init_se (&arg1se, NULL);
2281 gfc_conv_expr (&arg1se, arg->expr);
2282 gfc_add_block_to_block (&se->pre, &arg1se.pre);
2283 gfc_add_block_to_block (&se->post, &arg1se.post);
2284
2285 /* See if we were given two arguments. */
2286 if (arg->next == NULL)
2287 /* Only given one arg so generate a null and do a
2288 not-equal comparison against the first arg. */
2289 se->expr = build2 (NE_EXPR, boolean_type_node, arg1se.expr,
2290 fold_convert (TREE_TYPE (arg1se.expr),
2291 null_pointer_node));
2292 else
2293 {
2294 tree eq_expr;
2295 tree not_null_expr;
2296
2297 /* Given two arguments so build the arg2se from second arg. */
2298 gfc_init_se (&arg2se, NULL);
2299 gfc_conv_expr (&arg2se, arg->next->expr);
2300 gfc_add_block_to_block (&se->pre, &arg2se.pre);
2301 gfc_add_block_to_block (&se->post, &arg2se.post);
2302
2303 /* Generate test to compare that the two args are equal. */
2304 eq_expr = build2 (EQ_EXPR, boolean_type_node, arg1se.expr,
2305 arg2se.expr);
2306 /* Generate test to ensure that the first arg is not null. */
2307 not_null_expr = build2 (NE_EXPR, boolean_type_node, arg1se.expr,
2308 null_pointer_node);
2309
2310 /* Finally, the generated test must check that both arg1 is not
2311 NULL and that it is equal to the second arg. */
2312 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
2313 not_null_expr, eq_expr);
2314 }
2315
089db47d 2316 return 0;
972345f2 2317 }
972345f2
CR
2318 }
2319
6de9cd9a
DN
2320 if (se->ss != NULL)
2321 {
2322 if (!sym->attr.elemental)
2323 {
6e45f57b 2324 gcc_assert (se->ss->type == GFC_SS_FUNCTION);
6de9cd9a
DN
2325 if (se->ss->useflags)
2326 {
6e45f57b 2327 gcc_assert (gfc_return_by_reference (sym)
6de9cd9a 2328 && sym->result->attr.dimension);
6e45f57b 2329 gcc_assert (se->loop != NULL);
6de9cd9a
DN
2330
2331 /* Access the previously obtained result. */
2332 gfc_conv_tmp_array_ref (se);
2333 gfc_advance_se_ss_chain (se);
dda895f9 2334 return 0;
6de9cd9a
DN
2335 }
2336 }
2337 info = &se->ss->data.info;
2338 }
2339 else
2340 info = NULL;
2341
f5f701ad 2342 gfc_init_block (&post);
0348d6fd 2343 gfc_init_interface_mapping (&mapping);
62ab4a54 2344 need_interface_mapping = ((sym->ts.type == BT_CHARACTER
20236f90
PT
2345 && sym->ts.cl->length
2346 && sym->ts.cl->length->expr_type
2347 != EXPR_CONSTANT)
2348 || sym->attr.dimension);
6de9cd9a
DN
2349 formal = sym->formal;
2350 /* Evaluate the arguments. */
2351 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
2352 {
e15e9be3
PT
2353 e = arg->expr;
2354 fsym = formal ? formal->sym : NULL;
5046aff5 2355 parm_kind = MISSING;
e15e9be3 2356 if (e == NULL)
6de9cd9a
DN
2357 {
2358
2359 if (se->ignore_optional)
2360 {
2361 /* Some intrinsics have already been resolved to the correct
2362 parameters. */
2363 continue;
2364 }
2365 else if (arg->label)
2366 {
2367 has_alternate_specifier = 1;
2368 continue;
2369 }
2370 else
2371 {
2372 /* Pass a NULL pointer for an absent arg. */
2373 gfc_init_se (&parmse, NULL);
2374 parmse.expr = null_pointer_node;
1600fe22 2375 if (arg->missing_arg_type == BT_CHARACTER)
c3238e32 2376 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
6de9cd9a
DN
2377 }
2378 }
2379 else if (se->ss && se->ss->useflags)
2380 {
2381 /* An elemental function inside a scalarized loop. */
2382 gfc_init_se (&parmse, se);
e15e9be3 2383 gfc_conv_expr_reference (&parmse, e);
5046aff5 2384 parm_kind = ELEMENTAL;
6de9cd9a
DN
2385 }
2386 else
2387 {
2388 /* A scalar or transformational function. */
2389 gfc_init_se (&parmse, NULL);
e15e9be3 2390 argss = gfc_walk_expr (e);
6de9cd9a
DN
2391
2392 if (argss == gfc_ss_terminator)
a8b3b0b6 2393 {
06469efd
PT
2394 if (fsym && fsym->attr.value)
2395 {
e032c2a1
CR
2396 if (fsym->ts.type == BT_CHARACTER
2397 && fsym->ts.is_c_interop
2398 && fsym->ns->proc_name != NULL
2399 && fsym->ns->proc_name->attr.is_bind_c)
2400 {
2401 parmse.expr = NULL;
2402 gfc_conv_scalar_char_value (fsym, &parmse, &e);
2403 if (parmse.expr == NULL)
2404 gfc_conv_expr (&parmse, e);
2405 }
2406 else
2407 gfc_conv_expr (&parmse, e);
06469efd 2408 }
7fcafa71
PT
2409 else if (arg->name && arg->name[0] == '%')
2410 /* Argument list functions %VAL, %LOC and %REF are signalled
2411 through arg->name. */
2412 conv_arglist_function (&parmse, arg->expr, arg->name);
6a661315
PT
2413 else if ((e->expr_type == EXPR_FUNCTION)
2414 && e->symtree->n.sym->attr.pointer
2415 && fsym && fsym->attr.target)
2416 {
2417 gfc_conv_expr (&parmse, e);
2418 parmse.expr = build_fold_addr_expr (parmse.expr);
2419 }
06469efd
PT
2420 else
2421 {
2422 gfc_conv_expr_reference (&parmse, e);
2423 if (fsym && fsym->attr.pointer
6a661315
PT
2424 && fsym->attr.flavor != FL_PROCEDURE
2425 && e->expr_type != EXPR_NULL)
06469efd
PT
2426 {
2427 /* Scalar pointer dummy args require an extra level of
2428 indirection. The null pointer already contains
2429 this level of indirection. */
2430 parm_kind = SCALAR_POINTER;
2431 parmse.expr = build_fold_addr_expr (parmse.expr);
2432 }
2433 }
2434 }
6de9cd9a
DN
2435 else
2436 {
aa08038d
EE
2437 /* If the procedure requires an explicit interface, the actual
2438 argument is passed according to the corresponding formal
2439 argument. If the corresponding formal argument is a POINTER,
2440 ALLOCATABLE or assumed shape, we do not use g77's calling
2441 convention, and pass the address of the array descriptor
2442 instead. Otherwise we use g77's calling convention. */
6de9cd9a 2443 int f;
e15e9be3
PT
2444 f = (fsym != NULL)
2445 && !(fsym->attr.pointer || fsym->attr.allocatable)
2446 && fsym->as->type != AS_ASSUMED_SHAPE;
6de9cd9a 2447 f = f || !sym->attr.always_explicit;
1855915a 2448
e15e9be3 2449 if (e->expr_type == EXPR_VARIABLE
1d6b7f39 2450 && is_subref_array (e))
68ea355b
PT
2451 /* The actual argument is a component reference to an
2452 array of derived types. In this case, the argument
2453 is converted to a temporary, which is passed and then
2454 written back after the procedure call. */
1d6b7f39 2455 gfc_conv_subref_array_arg (&parmse, e, f,
72af9f0b 2456 fsym ? fsym->attr.intent : INTENT_INOUT);
68ea355b 2457 else
e15e9be3 2458 gfc_conv_array_parameter (&parmse, e, argss, f);
42a0e16c
PT
2459
2460 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
2461 allocated on entry, it must be deallocated. */
e15e9be3
PT
2462 if (fsym && fsym->attr.allocatable
2463 && fsym->attr.intent == INTENT_OUT)
42a0e16c 2464 {
5dba0fb8 2465 tmp = build_fold_indirect_ref (parmse.expr);
763ccd45 2466 tmp = gfc_trans_dealloc_allocated (tmp);
42a0e16c
PT
2467 gfc_add_expr_to_block (&se->pre, tmp);
2468 }
2469
6de9cd9a
DN
2470 }
2471 }
2472
34b4bc5c
FXC
2473 /* The case with fsym->attr.optional is that of a user subroutine
2474 with an interface indicating an optional argument. When we call
2475 an intrinsic subroutine, however, fsym is NULL, but we might still
2476 have an optional argument, so we proceed to the substitution
2477 just in case. */
2478 if (e && (fsym == NULL || fsym->attr.optional))
5be38273 2479 {
34b4bc5c
FXC
2480 /* If an optional argument is itself an optional dummy argument,
2481 check its presence and substitute a null if absent. */
2482 if (e->expr_type == EXPR_VARIABLE
2483 && e->symtree->n.sym->attr.optional)
be9c3c6e
JD
2484 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
2485 e->representation.length);
34b4bc5c
FXC
2486 }
2487
2488 if (fsym && e)
2489 {
2490 /* Obtain the character length of an assumed character length
2491 length procedure from the typespec. */
2492 if (fsym->ts.type == BT_CHARACTER
2493 && parmse.string_length == NULL_TREE
2494 && e->ts.type == BT_PROCEDURE
2495 && e->symtree->n.sym->ts.type == BT_CHARACTER
2496 && e->symtree->n.sym->ts.cl->length != NULL)
5be38273 2497 {
34b4bc5c
FXC
2498 gfc_conv_const_charlen (e->symtree->n.sym->ts.cl);
2499 parmse.string_length = e->symtree->n.sym->ts.cl->backend_decl;
5be38273 2500 }
5be38273 2501 }
0348d6fd 2502
34b4bc5c 2503 if (fsym && need_interface_mapping)
0a164a3c 2504 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
34b4bc5c 2505
6de9cd9a 2506 gfc_add_block_to_block (&se->pre, &parmse.pre);
f5f701ad 2507 gfc_add_block_to_block (&post, &parmse.post);
6de9cd9a 2508
5046aff5
PT
2509 /* Allocated allocatable components of derived types must be
2510 deallocated for INTENT(OUT) dummy arguments and non-variable
2511 scalars. Non-variable arrays are dealt with in trans-array.c
2512 (gfc_conv_array_parameter). */
2513 if (e && e->ts.type == BT_DERIVED
2514 && e->ts.derived->attr.alloc_comp
2515 && ((formal && formal->sym->attr.intent == INTENT_OUT)
2516 ||
2517 (e->expr_type != EXPR_VARIABLE && !e->rank)))
2518 {
2519 int parm_rank;
2520 tmp = build_fold_indirect_ref (parmse.expr);
2521 parm_rank = e->rank;
2522 switch (parm_kind)
2523 {
2524 case (ELEMENTAL):
2525 case (SCALAR):
2526 parm_rank = 0;
2527 break;
2528
2529 case (SCALAR_POINTER):
2530 tmp = build_fold_indirect_ref (tmp);
2531 break;
2532 case (ARRAY):
2533 tmp = parmse.expr;
2534 break;
2535 }
2536
2537 tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank);
2538 if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional)
2539 tmp = build3_v (COND_EXPR, gfc_conv_expr_present (e->symtree->n.sym),
2540 tmp, build_empty_stmt ());
2541
2542 if (e->expr_type != EXPR_VARIABLE)
2543 /* Don't deallocate non-variables until they have been used. */
2544 gfc_add_expr_to_block (&se->post, tmp);
2545 else
2546 {
2547 gcc_assert (formal && formal->sym->attr.intent == INTENT_OUT);
2548 gfc_add_expr_to_block (&se->pre, tmp);
2549 }
2550 }
2551
e7dc5b4f 2552 /* Character strings are passed as two parameters, a length and a
7861a5ce
TB
2553 pointer - except for Bind(c) which only passes the pointer. */
2554 if (parmse.string_length != NULL_TREE && !sym->attr.is_bind_c)
6de9cd9a
DN
2555 stringargs = gfc_chainon_list (stringargs, parmse.string_length);
2556
2557 arglist = gfc_chainon_list (arglist, parmse.expr);
2558 }
0348d6fd
RS
2559 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
2560
2561 ts = sym->ts;
06a54338 2562 if (ts.type == BT_CHARACTER && !sym->attr.is_bind_c)
0348d6fd 2563 {
20236f90
PT
2564 if (sym->ts.cl->length == NULL)
2565 {
2566 /* Assumed character length results are not allowed by 5.1.1.5 of the
2567 standard and are trapped in resolve.c; except in the case of SPREAD
7f39b34c
PT
2568 (and other intrinsics?) and dummy functions. In the case of SPREAD,
2569 we take the character length of the first argument for the result.
2570 For dummies, we have to look through the formal argument list for
2571 this function and use the character length found there.*/
2572 if (!sym->attr.dummy)
2573 cl.backend_decl = TREE_VALUE (stringargs);
2574 else
2575 {
2576 formal = sym->ns->proc_name->formal;
2577 for (; formal; formal = formal->next)
2578 if (strcmp (formal->sym->name, sym->name) == 0)
2579 cl.backend_decl = formal->sym->ts.cl->backend_decl;
2580 }
2581 }
2582 else
2583 {
886c8de1
FXC
2584 tree tmp;
2585
20236f90
PT
2586 /* Calculate the length of the returned string. */
2587 gfc_init_se (&parmse, NULL);
2588 if (need_interface_mapping)
2589 gfc_apply_interface_mapping (&mapping, &parmse, sym->ts.cl->length);
2590 else
2591 gfc_conv_expr (&parmse, sym->ts.cl->length);
2592 gfc_add_block_to_block (&se->pre, &parmse.pre);
2593 gfc_add_block_to_block (&se->post, &parmse.post);
886c8de1
FXC
2594
2595 tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
2596 tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
2597 build_int_cst (gfc_charlen_type_node, 0));
2598 cl.backend_decl = tmp;
20236f90 2599 }
0348d6fd
RS
2600
2601 /* Set up a charlen structure for it. */
2602 cl.next = NULL;
2603 cl.length = NULL;
0348d6fd
RS
2604 ts.cl = &cl;
2605
2606 len = cl.backend_decl;
2607 }
0348d6fd
RS
2608
2609 byref = gfc_return_by_reference (sym);
2610 if (byref)
2611 {
2612 if (se->direct_byref)
fc2d8680
PT
2613 {
2614 /* Sometimes, too much indirection can be applied; eg. for
2615 function_result = array_valued_recursive_function. */
2616 if (TREE_TYPE (TREE_TYPE (se->expr))
2617 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
2618 && GFC_DESCRIPTOR_TYPE_P
2619 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
2620 se->expr = build_fold_indirect_ref (se->expr);
2621
2622 retargs = gfc_chainon_list (retargs, se->expr);
2623 }
0348d6fd
RS
2624 else if (sym->result->attr.dimension)
2625 {
2626 gcc_assert (se->loop && info);
2627
2628 /* Set the type of the array. */
2629 tmp = gfc_typenode_for_spec (&ts);
2630 info->dimen = se->loop->dimen;
2631
62ab4a54
RS
2632 /* Evaluate the bounds of the result, if known. */
2633 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
2634
8e119f1b
EE
2635 /* Create a temporary to store the result. In case the function
2636 returns a pointer, the temporary will be a shallow copy and
2637 mustn't be deallocated. */
2638 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
2639 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
999ffb1a 2640 false, !sym->attr.pointer, callee_alloc);
0348d6fd 2641
0348d6fd
RS
2642 /* Pass the temporary as the first argument. */
2643 tmp = info->descriptor;
488ce07b 2644 tmp = build_fold_addr_expr (tmp);
0348d6fd
RS
2645 retargs = gfc_chainon_list (retargs, tmp);
2646 }
2647 else if (ts.type == BT_CHARACTER)
2648 {
2649 /* Pass the string length. */
2650 type = gfc_get_character_type (ts.kind, ts.cl);
2651 type = build_pointer_type (type);
2652
2653 /* Return an address to a char[0:len-1]* temporary for
2654 character pointers. */
2655 if (sym->attr.pointer || sym->attr.allocatable)
2656 {
2657 /* Build char[0:len-1] * pstr. */
2658 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
2659 build_int_cst (gfc_charlen_type_node, 1));
2660 tmp = build_range_type (gfc_array_index_type,
2661 gfc_index_zero_node, tmp);
2662 tmp = build_array_type (gfc_character1_type_node, tmp);
2663 var = gfc_create_var (build_pointer_type (tmp), "pstr");
2664
2665 /* Provide an address expression for the function arguments. */
488ce07b 2666 var = build_fold_addr_expr (var);
0348d6fd
RS
2667 }
2668 else
2669 var = gfc_conv_string_tmp (se, type, len);
2670
2671 retargs = gfc_chainon_list (retargs, var);
2672 }
2673 else
2674 {
2675 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
2676
2677 type = gfc_get_complex_type (ts.kind);
488ce07b 2678 var = build_fold_addr_expr (gfc_create_var (type, "cmplx"));
0348d6fd
RS
2679 retargs = gfc_chainon_list (retargs, var);
2680 }
2681
2682 /* Add the string length to the argument list. */
2683 if (ts.type == BT_CHARACTER)
2684 retargs = gfc_chainon_list (retargs, len);
2685 }
62ab4a54 2686 gfc_free_interface_mapping (&mapping);
0348d6fd
RS
2687
2688 /* Add the return arguments. */
2689 arglist = chainon (retargs, arglist);
6de9cd9a
DN
2690
2691 /* Add the hidden string length parameters to the arguments. */
2692 arglist = chainon (arglist, stringargs);
2693
5a0aad31
FXC
2694 /* We may want to append extra arguments here. This is used e.g. for
2695 calls to libgfortran_matmul_??, which need extra information. */
2696 if (append_args != NULL_TREE)
2697 arglist = chainon (arglist, append_args);
2698
6de9cd9a
DN
2699 /* Generate the actual call. */
2700 gfc_conv_function_val (se, sym);
276ca25d 2701
6de9cd9a 2702 /* If there are alternate return labels, function type should be
dda895f9 2703 integer. Can't modify the type in place though, since it can be shared
276ca25d
PT
2704 with other functions. For dummy arguments, the typing is done to
2705 to this result, even if it has to be repeated for each call. */
dda895f9
JJ
2706 if (has_alternate_specifier
2707 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
2708 {
276ca25d
PT
2709 if (!sym->attr.dummy)
2710 {
2711 TREE_TYPE (sym->backend_decl)
2712 = build_function_type (integer_type_node,
2713 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
2714 se->expr = build_fold_addr_expr (sym->backend_decl);
2715 }
2716 else
2717 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
dda895f9 2718 }
6de9cd9a
DN
2719
2720 fntype = TREE_TYPE (TREE_TYPE (se->expr));
5039610b 2721 se->expr = build_call_list (TREE_TYPE (fntype), se->expr, arglist);
6de9cd9a 2722
6d1c50cc
TS
2723 /* If we have a pointer function, but we don't want a pointer, e.g.
2724 something like
2725 x = f()
2726 where f is pointer valued, we have to dereference the result. */
973ff4c0 2727 if (!se->want_pointer && !byref && sym->attr.pointer)
38611275 2728 se->expr = build_fold_indirect_ref (se->expr);
6d1c50cc 2729
973ff4c0
TS
2730 /* f2c calling conventions require a scalar default real function to
2731 return a double precision result. Convert this back to default
2732 real. We only care about the cases that can happen in Fortran 77.
2733 */
2734 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
2735 && sym->ts.kind == gfc_default_real_kind
2736 && !sym->attr.always_explicit)
2737 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
2738
f8d0aee5
TS
2739 /* A pure function may still have side-effects - it may modify its
2740 parameters. */
6de9cd9a
DN
2741 TREE_SIDE_EFFECTS (se->expr) = 1;
2742#if 0
2743 if (!sym->attr.pure)
2744 TREE_SIDE_EFFECTS (se->expr) = 1;
2745#endif
2746
fc90a8f2 2747 if (byref)
6de9cd9a 2748 {
fc90a8f2 2749 /* Add the function call to the pre chain. There is no expression. */
6de9cd9a 2750 gfc_add_expr_to_block (&se->pre, se->expr);
fc90a8f2 2751 se->expr = NULL_TREE;
6de9cd9a 2752
fc90a8f2 2753 if (!se->direct_byref)
6de9cd9a 2754 {
09e7f686 2755 if (sym->attr.dimension)
6de9cd9a 2756 {
fc90a8f2
PB
2757 if (flag_bounds_check)
2758 {
2759 /* Check the data pointer hasn't been modified. This would
2760 happen in a function returning a pointer. */
4c73896d 2761 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3f2ec06a
RG
2762 tmp = fold_build2 (NE_EXPR, boolean_type_node,
2763 tmp, info->data);
c8fe94c7 2764 gfc_trans_runtime_check (tmp, &se->pre, NULL, gfc_msg_fault);
fc90a8f2
PB
2765 }
2766 se->expr = info->descriptor;
72caba17
PT
2767 /* Bundle in the string length. */
2768 se->string_length = len;
6de9cd9a 2769 }
fc90a8f2 2770 else if (sym->ts.type == BT_CHARACTER)
ec09945c 2771 {
72caba17
PT
2772 /* Dereference for character pointer results. */
2773 if (sym->attr.pointer || sym->attr.allocatable)
38611275 2774 se->expr = build_fold_indirect_ref (var);
ec09945c 2775 else
72caba17
PT
2776 se->expr = var;
2777
fc90a8f2
PB
2778 se->string_length = len;
2779 }
2780 else
973ff4c0
TS
2781 {
2782 gcc_assert (sym->ts.type == BT_COMPLEX && gfc_option.flag_f2c);
38611275 2783 se->expr = build_fold_indirect_ref (var);
973ff4c0 2784 }
6de9cd9a 2785 }
6de9cd9a 2786 }
dda895f9 2787
f5f701ad
PT
2788 /* Follow the function call with the argument post block. */
2789 if (byref)
2790 gfc_add_block_to_block (&se->pre, &post);
2791 else
2792 gfc_add_block_to_block (&se->post, &post);
2793
dda895f9 2794 return has_alternate_specifier;
6de9cd9a
DN
2795}
2796
2797
7b5b57b7
PB
2798/* Generate code to copy a string. */
2799
2800static void
5cd8e123
SK
2801gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
2802 tree slength, tree src)
7b5b57b7 2803{
5cd8e123 2804 tree tmp, dlen, slen;
0a821a92
FW
2805 tree dsc;
2806 tree ssc;
549033f3 2807 tree cond;
b3eb1e0e
FXC
2808 tree cond2;
2809 tree tmp2;
2810 tree tmp3;
2811 tree tmp4;
2812 stmtblock_t tempblock;
0a821a92 2813
06a54338
TB
2814 if (slength != NULL_TREE)
2815 {
2816 slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
2817 ssc = gfc_to_single_character (slen, src);
2818 }
2819 else
2820 {
2821 slen = build_int_cst (size_type_node, 1);
2822 ssc = src;
2823 }
2824
2825 if (dlength != NULL_TREE)
2826 {
2827 dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
2828 dsc = gfc_to_single_character (slen, dest);
2829 }
2830 else
2831 {
2832 dlen = build_int_cst (size_type_node, 1);
2833 dsc = dest;
2834 }
2835
2836 if (slength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (src)))
2837 ssc = gfc_to_single_character (slen, src);
2838 if (dlength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (dest)))
2839 dsc = gfc_to_single_character (dlen, dest);
2840
5cd8e123 2841
0a821a92
FW
2842 if (dsc != NULL_TREE && ssc != NULL_TREE)
2843 {
2844 gfc_add_modify_expr (block, dsc, ssc);
2845 return;
2846 }
7b5b57b7 2847
b3eb1e0e 2848 /* Do nothing if the destination length is zero. */
549033f3 2849 cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
ac816b02 2850 build_int_cst (size_type_node, 0));
549033f3 2851
b3eb1e0e
FXC
2852 /* The following code was previously in _gfortran_copy_string:
2853
2854 // The two strings may overlap so we use memmove.
2855 void
2856 copy_string (GFC_INTEGER_4 destlen, char * dest,
2857 GFC_INTEGER_4 srclen, const char * src)
2858 {
2859 if (srclen >= destlen)
2860 {
2861 // This will truncate if too long.
2862 memmove (dest, src, destlen);
2863 }
2864 else
2865 {
2866 memmove (dest, src, srclen);
2867 // Pad with spaces.
2868 memset (&dest[srclen], ' ', destlen - srclen);
2869 }
2870 }
2871
2872 We're now doing it here for better optimization, but the logic
2873 is the same. */
36cefd39 2874
06a54338
TB
2875 if (dlength)
2876 dest = fold_convert (pvoid_type_node, dest);
2877 else
2878 dest = gfc_build_addr_expr (pvoid_type_node, dest);
2879
2880 if (slength)
2881 src = fold_convert (pvoid_type_node, src);
2882 else
2883 src = gfc_build_addr_expr (pvoid_type_node, src);
36cefd39 2884
b3eb1e0e
FXC
2885 /* Truncate string if source is too long. */
2886 cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
5039610b
SL
2887 tmp2 = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE],
2888 3, dest, src, dlen);
b3eb1e0e
FXC
2889
2890 /* Else copy and pad with spaces. */
5039610b
SL
2891 tmp3 = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE],
2892 3, dest, src, slen);
b3eb1e0e 2893
96d9bb07 2894 tmp4 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest,
5be014d5 2895 fold_convert (sizetype, slen));
5039610b
SL
2896 tmp4 = build_call_expr (built_in_decls[BUILT_IN_MEMSET], 3,
2897 tmp4,
2898 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
2899 lang_hooks.to_target_charset (' ')),
2900 fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
2901 dlen, slen));
b3eb1e0e
FXC
2902
2903 gfc_init_block (&tempblock);
2904 gfc_add_expr_to_block (&tempblock, tmp3);
2905 gfc_add_expr_to_block (&tempblock, tmp4);
2906 tmp3 = gfc_finish_block (&tempblock);
2907
2908 /* The whole copy_string function is there. */
2909 tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
549033f3 2910 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
7b5b57b7
PB
2911 gfc_add_expr_to_block (block, tmp);
2912}
2913
2914
6de9cd9a
DN
2915/* Translate a statement function.
2916 The value of a statement function reference is obtained by evaluating the
2917 expression using the values of the actual arguments for the values of the
2918 corresponding dummy arguments. */
2919
2920static void
2921gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
2922{
2923 gfc_symbol *sym;
2924 gfc_symbol *fsym;
2925 gfc_formal_arglist *fargs;
2926 gfc_actual_arglist *args;
2927 gfc_se lse;
2928 gfc_se rse;
7b5b57b7
PB
2929 gfc_saved_var *saved_vars;
2930 tree *temp_vars;
2931 tree type;
2932 tree tmp;
2933 int n;
6de9cd9a
DN
2934
2935 sym = expr->symtree->n.sym;
2936 args = expr->value.function.actual;
2937 gfc_init_se (&lse, NULL);
2938 gfc_init_se (&rse, NULL);
2939
7b5b57b7 2940 n = 0;
6de9cd9a 2941 for (fargs = sym->formal; fargs; fargs = fargs->next)
7b5b57b7
PB
2942 n++;
2943 saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
2944 temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
2945
2946 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
6de9cd9a
DN
2947 {
2948 /* Each dummy shall be specified, explicitly or implicitly, to be
2949 scalar. */
6e45f57b 2950 gcc_assert (fargs->sym->attr.dimension == 0);
6de9cd9a 2951 fsym = fargs->sym;
6de9cd9a 2952
7b5b57b7
PB
2953 /* Create a temporary to hold the value. */
2954 type = gfc_typenode_for_spec (&fsym->ts);
2955 temp_vars[n] = gfc_create_var (type, fsym->name);
2956
2957 if (fsym->ts.type == BT_CHARACTER)
6de9cd9a 2958 {
7b5b57b7
PB
2959 /* Copy string arguments. */
2960 tree arglen;
6de9cd9a 2961
6e45f57b 2962 gcc_assert (fsym->ts.cl && fsym->ts.cl->length
6de9cd9a
DN
2963 && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
2964
7b5b57b7
PB
2965 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2966 tmp = gfc_build_addr_expr (build_pointer_type (type),
2967 temp_vars[n]);
6de9cd9a
DN
2968
2969 gfc_conv_expr (&rse, args->expr);
2970 gfc_conv_string_parameter (&rse);
6de9cd9a
DN
2971 gfc_add_block_to_block (&se->pre, &lse.pre);
2972 gfc_add_block_to_block (&se->pre, &rse.pre);
2973
7b5b57b7
PB
2974 gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
2975 rse.expr);
6de9cd9a
DN
2976 gfc_add_block_to_block (&se->pre, &lse.post);
2977 gfc_add_block_to_block (&se->pre, &rse.post);
2978 }
2979 else
2980 {
2981 /* For everything else, just evaluate the expression. */
6de9cd9a
DN
2982 gfc_conv_expr (&lse, args->expr);
2983
2984 gfc_add_block_to_block (&se->pre, &lse.pre);
7b5b57b7 2985 gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
6de9cd9a
DN
2986 gfc_add_block_to_block (&se->pre, &lse.post);
2987 }
7b5b57b7 2988
6de9cd9a
DN
2989 args = args->next;
2990 }
7b5b57b7
PB
2991
2992 /* Use the temporary variables in place of the real ones. */
2993 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2994 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
2995
6de9cd9a 2996 gfc_conv_expr (se, sym->value);
7b5b57b7
PB
2997
2998 if (sym->ts.type == BT_CHARACTER)
2999 {
3000 gfc_conv_const_charlen (sym->ts.cl);
3001
3002 /* Force the expression to the correct length. */
3003 if (!INTEGER_CST_P (se->string_length)
3004 || tree_int_cst_lt (se->string_length,
3005 sym->ts.cl->backend_decl))
3006 {
3007 type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
3008 tmp = gfc_create_var (type, sym->name);
3009 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
3010 gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
3011 se->string_length, se->expr);
3012 se->expr = tmp;
3013 }
3014 se->string_length = sym->ts.cl->backend_decl;
3015 }
3016
f8d0aee5 3017 /* Restore the original variables. */
7b5b57b7
PB
3018 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3019 gfc_restore_sym (fargs->sym, &saved_vars[n]);
3020 gfc_free (saved_vars);
6de9cd9a
DN
3021}
3022
3023
3024/* Translate a function expression. */
3025
3026static void
3027gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
3028{
3029 gfc_symbol *sym;
3030
3031 if (expr->value.function.isym)
3032 {
3033 gfc_conv_intrinsic_function (se, expr);
3034 return;
3035 }
3036
f8d0aee5 3037 /* We distinguish statement functions from general functions to improve
6de9cd9a
DN
3038 runtime performance. */
3039 if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
3040 {
3041 gfc_conv_statement_function (se, expr);
3042 return;
3043 }
3044
3045 /* expr.value.function.esym is the resolved (specific) function symbol for
3046 most functions. However this isn't set for dummy procedures. */
3047 sym = expr->value.function.esym;
3048 if (!sym)
3049 sym = expr->symtree->n.sym;
5a0aad31 3050 gfc_conv_function_call (se, sym, expr->value.function.actual, NULL_TREE);
6de9cd9a
DN
3051}
3052
f8d0aee5 3053
6de9cd9a
DN
3054static void
3055gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
3056{
6e45f57b
PB
3057 gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
3058 gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
6de9cd9a
DN
3059
3060 gfc_conv_tmp_array_ref (se);
3061 gfc_advance_se_ss_chain (se);
3062}
3063
3064
597073ac 3065/* Build a static initializer. EXPR is the expression for the initial value.
f8d0aee5
TS
3066 The other parameters describe the variable of the component being
3067 initialized. EXPR may be null. */
6de9cd9a 3068
597073ac
PB
3069tree
3070gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
3071 bool array, bool pointer)
3072{
3073 gfc_se se;
3074
3075 if (!(expr || pointer))
3076 return NULL_TREE;
3077
3e708b25
CR
3078 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
3079 (these are the only two iso_c_binding derived types that can be
3080 used as initialization expressions). If so, we need to modify
3081 the 'expr' to be that for a (void *). */
dd39f783
TB
3082 if (expr != NULL && expr->ts.type == BT_DERIVED
3083 && expr->ts.is_iso_c && expr->ts.derived)
3e708b25
CR
3084 {
3085 gfc_symbol *derived = expr->ts.derived;
3086
a8b3b0b6 3087 expr = gfc_int_expr (0);
3e708b25
CR
3088
3089 /* The derived symbol has already been converted to a (void *). Use
3090 its kind. */
3091 expr->ts.f90_type = derived->ts.f90_type;
3092 expr->ts.kind = derived->ts.kind;
3093 }
a8b3b0b6 3094
597073ac
PB
3095 if (array)
3096 {
3097 /* Arrays need special handling. */
3098 if (pointer)
3099 return gfc_build_null_descriptor (type);
3100 else
3101 return gfc_conv_array_initializer (type, expr);
3102 }
3103 else if (pointer)
3104 return fold_convert (type, null_pointer_node);
3105 else
3106 {
3107 switch (ts->type)
3108 {
3109 case BT_DERIVED:
3110 gfc_init_se (&se, NULL);
3111 gfc_conv_structure (&se, expr, 1);
3112 return se.expr;
3113
3114 case BT_CHARACTER:
3115 return gfc_conv_string_init (ts->cl->backend_decl,expr);
3116
3117 default:
3118 gfc_init_se (&se, NULL);
3119 gfc_conv_constant (&se, expr);
3120 return se.expr;
3121 }
3122 }
3123}
3124
e9cfef64
PB
3125static tree
3126gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3127{
3128 gfc_se rse;
3129 gfc_se lse;
3130 gfc_ss *rss;
3131 gfc_ss *lss;
3132 stmtblock_t body;
3133 stmtblock_t block;
3134 gfc_loopinfo loop;
3135 int n;
3136 tree tmp;
3137
3138 gfc_start_block (&block);
3139
3140 /* Initialize the scalarizer. */
3141 gfc_init_loopinfo (&loop);
3142
3143 gfc_init_se (&lse, NULL);
3144 gfc_init_se (&rse, NULL);
3145
3146 /* Walk the rhs. */
3147 rss = gfc_walk_expr (expr);
3148 if (rss == gfc_ss_terminator)
3149 {
3150 /* The rhs is scalar. Add a ss for the expression. */
3151 rss = gfc_get_ss ();
3152 rss->next = gfc_ss_terminator;
3153 rss->type = GFC_SS_SCALAR;
3154 rss->expr = expr;
3155 }
3156
3157 /* Create a SS for the destination. */
3158 lss = gfc_get_ss ();
3159 lss->type = GFC_SS_COMPONENT;
3160 lss->expr = NULL;
3161 lss->shape = gfc_get_shape (cm->as->rank);
3162 lss->next = gfc_ss_terminator;
3163 lss->data.info.dimen = cm->as->rank;
3164 lss->data.info.descriptor = dest;
3165 lss->data.info.data = gfc_conv_array_data (dest);
3166 lss->data.info.offset = gfc_conv_array_offset (dest);
3167 for (n = 0; n < cm->as->rank; n++)
3168 {
3169 lss->data.info.dim[n] = n;
3170 lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
3171 lss->data.info.stride[n] = gfc_index_one_node;
3172
3173 mpz_init (lss->shape[n]);
3174 mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
3175 cm->as->lower[n]->value.integer);
3176 mpz_add_ui (lss->shape[n], lss->shape[n], 1);
3177 }
3178
3179 /* Associate the SS with the loop. */
3180 gfc_add_ss_to_loop (&loop, lss);
3181 gfc_add_ss_to_loop (&loop, rss);
3182
3183 /* Calculate the bounds of the scalarization. */
3184 gfc_conv_ss_startstride (&loop);
3185
3186 /* Setup the scalarizing loops. */
3187 gfc_conv_loop_setup (&loop);
3188
3189 /* Setup the gfc_se structures. */
3190 gfc_copy_loopinfo_to_se (&lse, &loop);
3191 gfc_copy_loopinfo_to_se (&rse, &loop);
3192
3193 rse.ss = rss;
3194 gfc_mark_ss_chain_used (rss, 1);
3195 lse.ss = lss;
3196 gfc_mark_ss_chain_used (lss, 1);
3197
3198 /* Start the scalarized loop body. */
3199 gfc_start_scalarized_body (&loop, &body);
3200
3201 gfc_conv_tmp_array_ref (&lse);
2b052ce2
PT
3202 if (cm->ts.type == BT_CHARACTER)
3203 lse.string_length = cm->ts.cl->backend_decl;
3204
e9cfef64
PB
3205 gfc_conv_expr (&rse, expr);
3206
5046aff5 3207 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
e9cfef64
PB
3208 gfc_add_expr_to_block (&body, tmp);
3209
6e45f57b 3210 gcc_assert (rse.ss == gfc_ss_terminator);
e9cfef64
PB
3211
3212 /* Generate the copying loops. */
3213 gfc_trans_scalarizing_loops (&loop, &body);
3214
3215 /* Wrap the whole thing up. */
3216 gfc_add_block_to_block (&block, &loop.pre);
3217 gfc_add_block_to_block (&block, &loop.post);
3218
e9cfef64
PB
3219 for (n = 0; n < cm->as->rank; n++)
3220 mpz_clear (lss->shape[n]);
3221 gfc_free (lss->shape);
3222
96654664
PB
3223 gfc_cleanup_loop (&loop);
3224
e9cfef64
PB
3225 return gfc_finish_block (&block);
3226}
3227
5046aff5 3228
e9cfef64
PB
3229/* Assign a single component of a derived type constructor. */
3230
3231static tree
3232gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3233{
3234 gfc_se se;
5046aff5 3235 gfc_se lse;
e9cfef64
PB
3236 gfc_ss *rss;
3237 stmtblock_t block;
3238 tree tmp;
5046aff5
PT
3239 tree offset;
3240 int n;
e9cfef64
PB
3241
3242 gfc_start_block (&block);
5046aff5 3243
e9cfef64
PB
3244 if (cm->pointer)
3245 {
3246 gfc_init_se (&se, NULL);
3247 /* Pointer component. */
3248 if (cm->dimension)
3249 {
3250 /* Array pointer. */
3251 if (expr->expr_type == EXPR_NULL)
4c73896d 3252 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
e9cfef64
PB
3253 else
3254 {
3255 rss = gfc_walk_expr (expr);
3256 se.direct_byref = 1;
3257 se.expr = dest;
3258 gfc_conv_expr_descriptor (&se, expr, rss);
3259 gfc_add_block_to_block (&block, &se.pre);
3260 gfc_add_block_to_block (&block, &se.post);
3261 }
3262 }
3263 else
3264 {
3265 /* Scalar pointers. */
3266 se.want_pointer = 1;
3267 gfc_conv_expr (&se, expr);
3268 gfc_add_block_to_block (&block, &se.pre);
3269 gfc_add_modify_expr (&block, dest,
3270 fold_convert (TREE_TYPE (dest), se.expr));
3271 gfc_add_block_to_block (&block, &se.post);
3272 }
3273 }
3274 else if (cm->dimension)
3275 {
5046aff5
PT
3276 if (cm->allocatable && expr->expr_type == EXPR_NULL)
3277 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
3278 else if (cm->allocatable)
28114dad
PT
3279 {
3280 tree tmp2;
5046aff5
PT
3281
3282 gfc_init_se (&se, NULL);
3283
3284 rss = gfc_walk_expr (expr);
28114dad
PT
3285 se.want_pointer = 0;
3286 gfc_conv_expr_descriptor (&se, expr, rss);
5046aff5
PT
3287 gfc_add_block_to_block (&block, &se.pre);
3288
3289 tmp = fold_convert (TREE_TYPE (dest), se.expr);
3290 gfc_add_modify_expr (&block, dest, tmp);
3291
28114dad 3292 if (cm->ts.type == BT_DERIVED && cm->ts.derived->attr.alloc_comp)
5046aff5
PT
3293 tmp = gfc_copy_alloc_comp (cm->ts.derived, se.expr, dest,
3294 cm->as->rank);
3295 else
28114dad 3296 tmp = gfc_duplicate_allocatable (dest, se.expr,
5046aff5
PT
3297 TREE_TYPE(cm->backend_decl),
3298 cm->as->rank);
3299
28114dad 3300 gfc_add_expr_to_block (&block, tmp);
5046aff5 3301
28114dad
PT
3302 gfc_add_block_to_block (&block, &se.post);
3303 gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
3304
3305 /* Shift the lbound and ubound of temporaries to being unity, rather
3306 than zero, based. Calculate the offset for all cases. */
3307 offset = gfc_conv_descriptor_offset (dest);
3308 gfc_add_modify_expr (&block, offset, gfc_index_zero_node);
3309 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
3310 for (n = 0; n < expr->rank; n++)
3311 {
3312 if (expr->expr_type != EXPR_VARIABLE
3313 && expr->expr_type != EXPR_CONSTANT)
3314 {
3315 tree span;
3316 tmp = gfc_conv_descriptor_ubound (dest, gfc_rank_cst[n]);
3317 span = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp,
3318 gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]));
3319 gfc_add_modify_expr (&block, tmp,
3320 fold_build2 (PLUS_EXPR,
3321 gfc_array_index_type,
3322 span, gfc_index_one_node));
3323 tmp = gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]);
3324 gfc_add_modify_expr (&block, tmp, gfc_index_one_node);
3325 }
3326 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3327 gfc_conv_descriptor_lbound (dest,
5046aff5 3328 gfc_rank_cst[n]),
28114dad 3329 gfc_conv_descriptor_stride (dest,
5046aff5 3330 gfc_rank_cst[n]));
28114dad
PT
3331 gfc_add_modify_expr (&block, tmp2, tmp);
3332 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
3333 gfc_add_modify_expr (&block, offset, tmp);
3334 }
3335 }
5046aff5 3336 else
28114dad 3337 {
5046aff5
PT
3338 tmp = gfc_trans_subarray_assign (dest, cm, expr);
3339 gfc_add_expr_to_block (&block, tmp);
28114dad 3340 }
e9cfef64
PB
3341 }
3342 else if (expr->ts.type == BT_DERIVED)
3343 {
3e978d30
PT
3344 if (expr->expr_type != EXPR_STRUCTURE)
3345 {
3346 gfc_init_se (&se, NULL);
3347 gfc_conv_expr (&se, expr);
3348 gfc_add_modify_expr (&block, dest,
3349 fold_convert (TREE_TYPE (dest), se.expr));
3350 }
3351 else
3352 {
3353 /* Nested constructors. */
3354 tmp = gfc_trans_structure_assign (dest, expr);
3355 gfc_add_expr_to_block (&block, tmp);
3356 }
e9cfef64
PB
3357 }
3358 else
3359 {
3360 /* Scalar component. */
e9cfef64
PB
3361 gfc_init_se (&se, NULL);
3362 gfc_init_se (&lse, NULL);
3363
3364 gfc_conv_expr (&se, expr);
3365 if (cm->ts.type == BT_CHARACTER)
3366 lse.string_length = cm->ts.cl->backend_decl;
3367 lse.expr = dest;
5046aff5 3368 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false);
e9cfef64
PB
3369 gfc_add_expr_to_block (&block, tmp);
3370 }
3371 return gfc_finish_block (&block);
3372}
3373
13795658 3374/* Assign a derived type constructor to a variable. */
e9cfef64
PB
3375
3376static tree
3377gfc_trans_structure_assign (tree dest, gfc_expr * expr)
3378{
3379 gfc_constructor *c;
3380 gfc_component *cm;
3381 stmtblock_t block;
3382 tree field;
3383 tree tmp;
3384
3385 gfc_start_block (&block);
3386 cm = expr->ts.derived->components;
3387 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
3388 {
3389 /* Skip absent members in default initializers. */
3390 if (!c->expr)
3391 continue;
3392
9dc35956
CR
3393 /* Update the type/kind of the expression if it represents either
3394 C_NULL_PTR or C_NULL_FUNPTR. This is done here because this may
3395 be the first place reached for initializing output variables that
3396 have components of type C_PTR/C_FUNPTR that are initialized. */
3397 if (c->expr->ts.type == BT_DERIVED && c->expr->ts.derived
3398 && c->expr->ts.derived->attr.is_iso_c)
3399 {
3400 c->expr->expr_type = EXPR_NULL;
3401 c->expr->ts.type = c->expr->ts.derived->ts.type;
3402 c->expr->ts.f90_type = c->expr->ts.derived->ts.f90_type;
3403 c->expr->ts.kind = c->expr->ts.derived->ts.kind;
3404 }
3405
e9cfef64 3406 field = cm->backend_decl;
923ab88c 3407 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), dest, field, NULL_TREE);
e9cfef64
PB
3408 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
3409 gfc_add_expr_to_block (&block, tmp);
3410 }
3411 return gfc_finish_block (&block);
3412}
3413
6de9cd9a
DN
3414/* Build an expression for a constructor. If init is nonzero then
3415 this is part of a static variable initializer. */
3416
3417void
3418gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
3419{
3420 gfc_constructor *c;
3421 gfc_component *cm;
6de9cd9a 3422 tree val;
6de9cd9a 3423 tree type;
e9cfef64 3424 tree tmp;
4038c495 3425 VEC(constructor_elt,gc) *v = NULL;
6de9cd9a 3426
6e45f57b
PB
3427 gcc_assert (se->ss == NULL);
3428 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
6de9cd9a 3429 type = gfc_typenode_for_spec (&expr->ts);
e9cfef64
PB
3430
3431 if (!init)
3432 {
3433 /* Create a temporary variable and fill it in. */
3434 se->expr = gfc_create_var (type, expr->ts.derived->name);
3435 tmp = gfc_trans_structure_assign (se->expr, expr);
3436 gfc_add_expr_to_block (&se->pre, tmp);
3437 return;
3438 }
3439
6de9cd9a 3440 cm = expr->ts.derived->components;
5046aff5 3441
6de9cd9a
DN
3442 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
3443 {
5046aff5
PT
3444 /* Skip absent members in default initializers and allocatable
3445 components. Although the latter have a default initializer
3446 of EXPR_NULL,... by default, the static nullify is not needed
3447 since this is done every time we come into scope. */
3448 if (!c->expr || cm->allocatable)
6de9cd9a
DN
3449 continue;
3450
e9cfef64
PB
3451 val = gfc_conv_initializer (c->expr, &cm->ts,
3452 TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
6de9cd9a 3453
4038c495
GB
3454 /* Append it to the constructor list. */
3455 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
6de9cd9a 3456 }
4038c495 3457 se->expr = build_constructor (type, v);
7e4b97c7
TB
3458 if (init)
3459 {
3460 TREE_CONSTANT(se->expr) = 1;
3461 TREE_INVARIANT(se->expr) = 1;
3462 }
6de9cd9a
DN
3463}
3464
3465
f8d0aee5 3466/* Translate a substring expression. */
6de9cd9a
DN
3467
3468static void
3469gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
3470{
3471 gfc_ref *ref;
3472
3473 ref = expr->ref;
3474
9a251aa1 3475 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
6de9cd9a 3476
9a251aa1
FXC
3477 se->expr = gfc_build_string_const (expr->value.character.length,
3478 expr->value.character.string);
6de9cd9a 3479 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
9a251aa1 3480 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
6de9cd9a 3481
9a251aa1
FXC
3482 if (ref)
3483 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
6de9cd9a
DN
3484}
3485
3486
a4f5cd44
PB
3487/* Entry point for expression translation. Evaluates a scalar quantity.
3488 EXPR is the expression to be translated, and SE is the state structure if
3489 called from within the scalarized. */
6de9cd9a
DN
3490
3491void
3492gfc_conv_expr (gfc_se * se, gfc_expr * expr)
3493{
3494 if (se->ss && se->ss->expr == expr
3495 && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
3496 {
e9cfef64 3497 /* Substitute a scalar expression evaluated outside the scalarization
6de9cd9a
DN
3498 loop. */
3499 se->expr = se->ss->data.scalar.expr;
40f20186 3500 se->string_length = se->ss->string_length;
6de9cd9a
DN
3501 gfc_advance_se_ss_chain (se);
3502 return;
3503 }
3504
a8b3b0b6
CR
3505 /* We need to convert the expressions for the iso_c_binding derived types.
3506 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
3507 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
3508 typespec for the C_PTR and C_FUNPTR symbols, which has already been
3509 updated to be an integer with a kind equal to the size of a (void *). */
3510 if (expr->ts.type == BT_DERIVED && expr->ts.derived
3511 && expr->ts.derived->attr.is_iso_c)
3512 {
3513 if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
3514 || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
3515 {
3516 /* Set expr_type to EXPR_NULL, which will result in
3517 null_pointer_node being used below. */
3518 expr->expr_type = EXPR_NULL;
3519 }
3520 else
3521 {
3522 /* Update the type/kind of the expression to be what the new
3523 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
3524 expr->ts.type = expr->ts.derived->ts.type;
3525 expr->ts.f90_type = expr->ts.derived->ts.f90_type;
3526 expr->ts.kind = expr->ts.derived->ts.kind;
3527 }
3528 }
3529
6de9cd9a
DN
3530 switch (expr->expr_type)
3531 {
3532 case EXPR_OP:
3533 gfc_conv_expr_op (se, expr);
3534 break;
3535
3536 case EXPR_FUNCTION:
3537 gfc_conv_function_expr (se, expr);
3538 break;
3539
3540 case EXPR_CONSTANT:
3541 gfc_conv_constant (se, expr);
3542 break;
3543
3544 case EXPR_VARIABLE:
3545 gfc_conv_variable (se, expr);
3546 break;
3547
3548 case EXPR_NULL:
3549 se->expr = null_pointer_node;
3550 break;
3551
3552 case EXPR_SUBSTRING:
3553 gfc_conv_substring_expr (se, expr);
3554 break;
3555
3556 case EXPR_STRUCTURE:
3557 gfc_conv_structure (se, expr, 0);
3558 break;
3559
3560 case EXPR_ARRAY:
3561 gfc_conv_array_constructor_expr (se, expr);
3562 break;
3563
3564 default:
6e45f57b 3565 gcc_unreachable ();
6de9cd9a
DN
3566 break;
3567 }
3568}
3569
a4f5cd44
PB
3570/* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
3571 of an assignment. */
6de9cd9a
DN
3572void
3573gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
3574{
3575 gfc_conv_expr (se, expr);
a4f5cd44 3576 /* All numeric lvalues should have empty post chains. If not we need to
6de9cd9a 3577 figure out a way of rewriting an lvalue so that it has no post chain. */
a4f5cd44 3578 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
6de9cd9a
DN
3579}
3580
a4f5cd44 3581/* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
417ab240 3582 numeric expressions. Used for scalar values where inserting cleanup code
a4f5cd44 3583 is inconvenient. */
6de9cd9a
DN
3584void
3585gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
3586{
3587 tree val;
3588
6e45f57b 3589 gcc_assert (expr->ts.type != BT_CHARACTER);
6de9cd9a
DN
3590 gfc_conv_expr (se, expr);
3591 if (se->post.head)
3592 {
3593 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
3594 gfc_add_modify_expr (&se->pre, val, se->expr);
a4f5cd44
PB
3595 se->expr = val;
3596 gfc_add_block_to_block (&se->pre, &se->post);
6de9cd9a
DN
3597 }
3598}
3599
33717d59 3600/* Helper to translate an expression and convert it to a particular type. */
6de9cd9a
DN
3601void
3602gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
3603{
3604 gfc_conv_expr_val (se, expr);
3605 se->expr = convert (type, se->expr);
3606}
3607
3608
f8d0aee5 3609/* Converts an expression so that it can be passed by reference. Scalar
6de9cd9a
DN
3610 values only. */
3611
3612void
3613gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
3614{
3615 tree var;
3616
3617 if (se->ss && se->ss->expr == expr
3618 && se->ss->type == GFC_SS_REFERENCE)
3619 {
3620 se->expr = se->ss->data.scalar.expr;
40f20186 3621 se->string_length = se->ss->string_length;
6de9cd9a
DN
3622 gfc_advance_se_ss_chain (se);
3623 return;
3624 }
3625
3626 if (expr->ts.type == BT_CHARACTER)
3627 {
3628 gfc_conv_expr (se, expr);
3629 gfc_conv_string_parameter (se);
3630 return;
3631 }
3632
3633 if (expr->expr_type == EXPR_VARIABLE)
3634 {
3635 se->want_pointer = 1;
3636 gfc_conv_expr (se, expr);
3637 if (se->post.head)
3638 {
3639 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3640 gfc_add_modify_expr (&se->pre, var, se->expr);
3641 gfc_add_block_to_block (&se->pre, &se->post);
3642 se->expr = var;
3643 }
3644 return;
3645 }
3646
6a56381b
PT
3647 if (expr->expr_type == EXPR_FUNCTION
3648 && expr->symtree->n.sym->attr.pointer
3649 && !expr->symtree->n.sym->attr.dimension)
3650 {
3651 se->want_pointer = 1;
3652 gfc_conv_expr (se, expr);
3653 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3654 gfc_add_modify_expr (&se->pre, var, se->expr);
3655 se->expr = var;
3656 return;
3657 }
3658
3659
6de9cd9a
DN
3660 gfc_conv_expr (se, expr);
3661
3662 /* Create a temporary var to hold the value. */
0534fa56
RH
3663 if (TREE_CONSTANT (se->expr))
3664 {
fade9a8e
AP
3665 tree tmp = se->expr;
3666 STRIP_TYPE_NOPS (tmp);
3667 var = build_decl (CONST_DECL, NULL, TREE_TYPE (tmp));
3668 DECL_INITIAL (var) = tmp;
3e806a3d 3669 TREE_STATIC (var) = 1;
0534fa56
RH
3670 pushdecl (var);
3671 }
3672 else
3673 {
3674 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
3675 gfc_add_modify_expr (&se->pre, var, se->expr);
3676 }
6de9cd9a
DN
3677 gfc_add_block_to_block (&se->pre, &se->post);
3678
3679 /* Take the address of that value. */
488ce07b 3680 se->expr = build_fold_addr_expr (var);
6de9cd9a
DN
3681}
3682
3683
3684tree
3685gfc_trans_pointer_assign (gfc_code * code)
3686{
3687 return gfc_trans_pointer_assignment (code->expr, code->expr2);
3688}
3689
3690
fc90a8f2
PB
3691/* Generate code for a pointer assignment. */
3692
6de9cd9a
DN
3693tree
3694gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
3695{
3696 gfc_se lse;
3697 gfc_se rse;
3698 gfc_ss *lss;
3699 gfc_ss *rss;
3700 stmtblock_t block;
8aeca7fd
RS
3701 tree desc;
3702 tree tmp;
1d6b7f39
PT
3703 tree decl;
3704
6de9cd9a
DN
3705
3706 gfc_start_block (&block);
3707
3708 gfc_init_se (&lse, NULL);
3709
3710 lss = gfc_walk_expr (expr1);
3711 rss = gfc_walk_expr (expr2);
3712 if (lss == gfc_ss_terminator)
3713 {
fc90a8f2 3714 /* Scalar pointers. */
6de9cd9a
DN
3715 lse.want_pointer = 1;
3716 gfc_conv_expr (&lse, expr1);
6e45f57b 3717 gcc_assert (rss == gfc_ss_terminator);
6de9cd9a
DN
3718 gfc_init_se (&rse, NULL);
3719 rse.want_pointer = 1;
3720 gfc_conv_expr (&rse, expr2);
3721 gfc_add_block_to_block (&block, &lse.pre);
3722 gfc_add_block_to_block (&block, &rse.pre);
7ab92584
SB
3723 gfc_add_modify_expr (&block, lse.expr,
3724 fold_convert (TREE_TYPE (lse.expr), rse.expr));
6de9cd9a
DN
3725 gfc_add_block_to_block (&block, &rse.post);
3726 gfc_add_block_to_block (&block, &lse.post);
3727 }
3728 else
3729 {
fc90a8f2 3730 /* Array pointer. */
6de9cd9a 3731 gfc_conv_expr_descriptor (&lse, expr1, lss);
8aeca7fd
RS
3732 switch (expr2->expr_type)
3733 {
3734 case EXPR_NULL:
3735 /* Just set the data pointer to null. */
467f18f3 3736 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
8aeca7fd
RS
3737 break;
3738
3739 case EXPR_VARIABLE:
3740 /* Assign directly to the pointer's descriptor. */
6de9cd9a 3741 lse.direct_byref = 1;
8aeca7fd 3742 gfc_conv_expr_descriptor (&lse, expr2, rss);
1d6b7f39
PT
3743
3744 /* If this is a subreference array pointer assignment, use the rhs
da6b49e1 3745 descriptor element size for the lhs span. */
1d6b7f39
PT
3746 if (expr1->symtree->n.sym->attr.subref_array_pointer)
3747 {
3748 decl = expr1->symtree->n.sym->backend_decl;
da6b49e1
PT
3749 gfc_init_se (&rse, NULL);
3750 rse.descriptor_only = 1;
3751 gfc_conv_expr (&rse, expr2);
3752 tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
3753 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
3754 if (!INTEGER_CST_P (tmp))
3755 gfc_add_block_to_block (&lse.post, &rse.pre);
1d6b7f39
PT
3756 gfc_add_modify_expr (&lse.post, GFC_DECL_SPAN(decl), tmp);
3757 }
3758
8aeca7fd
RS
3759 break;
3760
3761 default:
3762 /* Assign to a temporary descriptor and then copy that
3763 temporary to the pointer. */
3764 desc = lse.expr;
3765 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
3766
3767 lse.expr = tmp;
3768 lse.direct_byref = 1;
3769 gfc_conv_expr_descriptor (&lse, expr2, rss);
3770 gfc_add_modify_expr (&lse.pre, desc, tmp);
3771 break;
6de9cd9a
DN
3772 }
3773 gfc_add_block_to_block (&block, &lse.pre);
3774 gfc_add_block_to_block (&block, &lse.post);
3775 }
3776 return gfc_finish_block (&block);
3777}
3778
3779
3780/* Makes sure se is suitable for passing as a function string parameter. */
3781/* TODO: Need to check all callers fo this function. It may be abused. */
3782
3783void
3784gfc_conv_string_parameter (gfc_se * se)
3785{
3786 tree type;
3787
3788 if (TREE_CODE (se->expr) == STRING_CST)
3789 {
3790 se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3791 return;
3792 }
3793
3794 type = TREE_TYPE (se->expr);
3795 if (TYPE_STRING_FLAG (type))
3796 {
129c14bd
PT
3797 if (TREE_CODE (se->expr) != INDIRECT_REF)
3798 se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3799 else
3800 {
3801 type = gfc_get_character_type_len (gfc_default_character_kind,
3802 se->string_length);
3803 type = build_pointer_type (type);
3804 se->expr = gfc_build_addr_expr (type, se->expr);
3805 }
6de9cd9a
DN
3806 }
3807
6e45f57b
PB
3808 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
3809 gcc_assert (se->string_length
6de9cd9a
DN
3810 && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
3811}
3812
3813
3814/* Generate code for assignment of scalar variables. Includes character
5046aff5 3815 strings and derived types with allocatable components. */
6de9cd9a
DN
3816
3817tree
5046aff5
PT
3818gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
3819 bool l_is_temp, bool r_is_var)
6de9cd9a 3820{
6de9cd9a 3821 stmtblock_t block;
5046aff5
PT
3822 tree tmp;
3823 tree cond;
6de9cd9a
DN
3824
3825 gfc_init_block (&block);
3826
5046aff5 3827 if (ts.type == BT_CHARACTER)
6de9cd9a 3828 {
06a54338
TB
3829 tree rlen = NULL;
3830 tree llen = NULL;
6de9cd9a 3831
06a54338
TB
3832 if (lse->string_length != NULL_TREE)
3833 {
3834 gfc_conv_string_parameter (lse);
3835 gfc_add_block_to_block (&block, &lse->pre);
3836 llen = lse->string_length;
3837 }
6de9cd9a 3838
06a54338
TB
3839 if (rse->string_length != NULL_TREE)
3840 {
3841 gcc_assert (rse->string_length != NULL_TREE);
3842 gfc_conv_string_parameter (rse);
3843 gfc_add_block_to_block (&block, &rse->pre);
3844 rlen = rse->string_length;
3845 }
6de9cd9a 3846
06a54338 3847 gfc_trans_string_copy (&block, llen, lse->expr, rlen, rse->expr);
6de9cd9a 3848 }
5046aff5
PT
3849 else if (ts.type == BT_DERIVED && ts.derived->attr.alloc_comp)
3850 {
3851 cond = NULL_TREE;
3852
3853 /* Are the rhs and the lhs the same? */
3854 if (r_is_var)
3855 {
3856 cond = fold_build2 (EQ_EXPR, boolean_type_node,
3857 build_fold_addr_expr (lse->expr),
3858 build_fold_addr_expr (rse->expr));
3859 cond = gfc_evaluate_now (cond, &lse->pre);
3860 }
3861
3862 /* Deallocate the lhs allocated components as long as it is not
b8247b13
PT
3863 the same as the rhs. This must be done following the assignment
3864 to prevent deallocating data that could be used in the rhs
3865 expression. */
5046aff5
PT
3866 if (!l_is_temp)
3867 {
b8247b13
PT
3868 tmp = gfc_evaluate_now (lse->expr, &lse->pre);
3869 tmp = gfc_deallocate_alloc_comp (ts.derived, tmp, 0);
5046aff5
PT
3870 if (r_is_var)
3871 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
b8247b13 3872 gfc_add_expr_to_block (&lse->post, tmp);
5046aff5 3873 }
28114dad 3874
b8247b13
PT
3875 gfc_add_block_to_block (&block, &rse->pre);
3876 gfc_add_block_to_block (&block, &lse->pre);
5046aff5
PT
3877
3878 gfc_add_modify_expr (&block, lse->expr,
3879 fold_convert (TREE_TYPE (lse->expr), rse->expr));
3880
3881 /* Do a deep copy if the rhs is a variable, if it is not the
982186b1 3882 same as the lhs. */
5046aff5
PT
3883 if (r_is_var)
3884 {
3885 tmp = gfc_copy_alloc_comp (ts.derived, rse->expr, lse->expr, 0);
3886 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
3887 gfc_add_expr_to_block (&block, tmp);
3888 }
5046aff5 3889 }
6de9cd9a
DN
3890 else
3891 {
3892 gfc_add_block_to_block (&block, &lse->pre);
3893 gfc_add_block_to_block (&block, &rse->pre);
3894
7ab92584
SB
3895 gfc_add_modify_expr (&block, lse->expr,
3896 fold_convert (TREE_TYPE (lse->expr), rse->expr));
6de9cd9a
DN
3897 }
3898
3899 gfc_add_block_to_block (&block, &lse->post);
3900 gfc_add_block_to_block (&block, &rse->post);
3901
3902 return gfc_finish_block (&block);
3903}
3904
3905
3906/* Try to translate array(:) = func (...), where func is a transformational
3907 array function, without using a temporary. Returns NULL is this isn't the
3908 case. */
3909
3910static tree
3911gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
3912{
3913 gfc_se se;
3914 gfc_ss *ss;
2853e512
PT
3915 gfc_ref * ref;
3916 bool seen_array_ref;
6de9cd9a
DN
3917
3918 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
3919 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
3920 return NULL;
3921
3922 /* Elemental functions don't need a temporary anyway. */
c4abe010
EE
3923 if (expr2->value.function.esym != NULL
3924 && expr2->value.function.esym->attr.elemental)
6de9cd9a
DN
3925 return NULL;
3926
7a70c12d
RS
3927 /* Fail if EXPR1 can't be expressed as a descriptor. */
3928 if (gfc_ref_needs_temporary_p (expr1->ref))
3929 return NULL;
3930
5b0b7251 3931 /* Functions returning pointers need temporaries. */
8e119f1b
EE
3932 if (expr2->symtree->n.sym->attr.pointer
3933 || expr2->symtree->n.sym->attr.allocatable)
5b0b7251
EE
3934 return NULL;
3935
bab651ad
PT
3936 /* Character array functions need temporaries unless the
3937 character lengths are the same. */
3938 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
3939 {
3940 if (expr1->ts.cl->length == NULL
3941 || expr1->ts.cl->length->expr_type != EXPR_CONSTANT)
3942 return NULL;
3943
3944 if (expr2->ts.cl->length == NULL
3945 || expr2->ts.cl->length->expr_type != EXPR_CONSTANT)
3946 return NULL;
3947
3948 if (mpz_cmp (expr1->ts.cl->length->value.integer,
3949 expr2->ts.cl->length->value.integer) != 0)
3950 return NULL;
3951 }
3952
2853e512
PT
3953 /* Check that no LHS component references appear during an array
3954 reference. This is needed because we do not have the means to
3955 span any arbitrary stride with an array descriptor. This check
3956 is not needed for the rhs because the function result has to be
3957 a complete type. */
3958 seen_array_ref = false;
3959 for (ref = expr1->ref; ref; ref = ref->next)
3960 {
3961 if (ref->type == REF_ARRAY)
3962 seen_array_ref= true;
3963 else if (ref->type == REF_COMPONENT && seen_array_ref)
3964 return NULL;
3965 }
3966
6de9cd9a 3967 /* Check for a dependency. */
1524f80b
RS
3968 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
3969 expr2->value.function.esym,
3970 expr2->value.function.actual))
6de9cd9a
DN
3971 return NULL;
3972
3973 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
3974 functions. */
6e45f57b 3975 gcc_assert (expr2->value.function.isym
c0c07d7b
TS
3976 || (gfc_return_by_reference (expr2->value.function.esym)
3977 && expr2->value.function.esym->result->attr.dimension));
6de9cd9a
DN
3978
3979 ss = gfc_walk_expr (expr1);
6e45f57b 3980 gcc_assert (ss != gfc_ss_terminator);
6de9cd9a
DN
3981 gfc_init_se (&se, NULL);
3982 gfc_start_block (&se.pre);
3983 se.want_pointer = 1;
3984
3985 gfc_conv_array_parameter (&se, expr1, ss, 0);
3986
3987 se.direct_byref = 1;
3988 se.ss = gfc_walk_expr (expr2);
6e45f57b 3989 gcc_assert (se.ss != gfc_ss_terminator);
6de9cd9a 3990 gfc_conv_function_expr (&se, expr2);
6de9cd9a
DN
3991 gfc_add_block_to_block (&se.pre, &se.post);
3992
3993 return gfc_finish_block (&se.pre);
3994}
3995
6822a10d
RS
3996/* Determine whether the given EXPR_CONSTANT is a zero initializer. */
3997
3998static bool
3999is_zero_initializer_p (gfc_expr * expr)
4000{
4001 if (expr->expr_type != EXPR_CONSTANT)
4002 return false;
20585ad6
BM
4003
4004 /* We ignore constants with prescribed memory representations for now. */
4005 if (expr->representation.string)
6822a10d
RS
4006 return false;
4007
4008 switch (expr->ts.type)
4009 {
4010 case BT_INTEGER:
4011 return mpz_cmp_si (expr->value.integer, 0) == 0;
4012
4013 case BT_REAL:
4014 return mpfr_zero_p (expr->value.real)
4015 && MPFR_SIGN (expr->value.real) >= 0;
4016
4017 case BT_LOGICAL:
4018 return expr->value.logical == 0;
4019
4020 case BT_COMPLEX:
4021 return mpfr_zero_p (expr->value.complex.r)
4022 && MPFR_SIGN (expr->value.complex.r) >= 0
4023 && mpfr_zero_p (expr->value.complex.i)
4024 && MPFR_SIGN (expr->value.complex.i) >= 0;
4025
4026 default:
4027 break;
4028 }
4029 return false;
4030}
4031
4032/* Try to efficiently translate array(:) = 0. Return NULL if this
4033 can't be done. */
4034
4035static tree
4036gfc_trans_zero_assign (gfc_expr * expr)
4037{
4038 tree dest, len, type;
5039610b 4039 tree tmp;
6822a10d
RS
4040 gfc_symbol *sym;
4041
4042 sym = expr->symtree->n.sym;
4043 dest = gfc_get_symbol_decl (sym);
4044
4045 type = TREE_TYPE (dest);
4046 if (POINTER_TYPE_P (type))
4047 type = TREE_TYPE (type);
4048 if (!GFC_ARRAY_TYPE_P (type))
4049 return NULL_TREE;
4050
4051 /* Determine the length of the array. */
4052 len = GFC_TYPE_ARRAY_SIZE (type);
4053 if (!len || TREE_CODE (len) != INTEGER_CST)
4054 return NULL_TREE;
4055
7c57b2f1 4056 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
6822a10d 4057 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
7c57b2f1 4058 fold_convert (gfc_array_index_type, tmp));
6822a10d
RS
4059
4060 /* Convert arguments to the correct types. */
4061 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
4062 dest = gfc_build_addr_expr (pvoid_type_node, dest);
4063 else
4064 dest = fold_convert (pvoid_type_node, dest);
4065 len = fold_convert (size_type_node, len);
4066
4067 /* Construct call to __builtin_memset. */
5039610b
SL
4068 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMSET],
4069 3, dest, integer_zero_node, len);
6822a10d
RS
4070 return fold_convert (void_type_node, tmp);
4071}
6de9cd9a 4072
b01e2f88
RS
4073
4074/* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
4075 that constructs the call to __builtin_memcpy. */
4076
4077static tree
4078gfc_build_memcpy_call (tree dst, tree src, tree len)
4079{
5039610b 4080 tree tmp;
b01e2f88
RS
4081
4082 /* Convert arguments to the correct types. */
4083 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
4084 dst = gfc_build_addr_expr (pvoid_type_node, dst);
4085 else
4086 dst = fold_convert (pvoid_type_node, dst);
4087
4088 if (!POINTER_TYPE_P (TREE_TYPE (src)))
4089 src = gfc_build_addr_expr (pvoid_type_node, src);
4090 else
4091 src = fold_convert (pvoid_type_node, src);
4092
4093 len = fold_convert (size_type_node, len);
4094
4095 /* Construct call to __builtin_memcpy. */
5039610b 4096 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len);
b01e2f88
RS
4097 return fold_convert (void_type_node, tmp);
4098}
4099
4100
a3018753
RS
4101/* Try to efficiently translate dst(:) = src(:). Return NULL if this
4102 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
4103 source/rhs, both are gfc_full_array_ref_p which have been checked for
4104 dependencies. */
6de9cd9a 4105
a3018753
RS
4106static tree
4107gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
4108{
4109 tree dst, dlen, dtype;
4110 tree src, slen, stype;
7c57b2f1 4111 tree tmp;
a3018753
RS
4112
4113 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
4114 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
4115
4116 dtype = TREE_TYPE (dst);
4117 if (POINTER_TYPE_P (dtype))
4118 dtype = TREE_TYPE (dtype);
4119 stype = TREE_TYPE (src);
4120 if (POINTER_TYPE_P (stype))
4121 stype = TREE_TYPE (stype);
4122
4123 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
4124 return NULL_TREE;
4125
4126 /* Determine the lengths of the arrays. */
4127 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
4128 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
4129 return NULL_TREE;
7c57b2f1 4130 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
a3018753 4131 dlen = fold_build2 (MULT_EXPR, gfc_array_index_type, dlen,
7c57b2f1 4132 fold_convert (gfc_array_index_type, tmp));
a3018753
RS
4133
4134 slen = GFC_TYPE_ARRAY_SIZE (stype);
4135 if (!slen || TREE_CODE (slen) != INTEGER_CST)
4136 return NULL_TREE;
7c57b2f1 4137 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
a3018753 4138 slen = fold_build2 (MULT_EXPR, gfc_array_index_type, slen,
7c57b2f1 4139 fold_convert (gfc_array_index_type, tmp));
a3018753
RS
4140
4141 /* Sanity check that they are the same. This should always be
4142 the case, as we should already have checked for conformance. */
4143 if (!tree_int_cst_equal (slen, dlen))
4144 return NULL_TREE;
4145
b01e2f88
RS
4146 return gfc_build_memcpy_call (dst, src, dlen);
4147}
a3018753 4148
a3018753 4149
b01e2f88
RS
4150/* Try to efficiently translate array(:) = (/ ... /). Return NULL if
4151 this can't be done. EXPR1 is the destination/lhs for which
4152 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
a3018753 4153
b01e2f88
RS
4154static tree
4155gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
4156{
4157 unsigned HOST_WIDE_INT nelem;
4158 tree dst, dtype;
4159 tree src, stype;
4160 tree len;
7c57b2f1 4161 tree tmp;
b01e2f88
RS
4162
4163 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
4164 if (nelem == 0)
4165 return NULL_TREE;
4166
4167 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
4168 dtype = TREE_TYPE (dst);
4169 if (POINTER_TYPE_P (dtype))
4170 dtype = TREE_TYPE (dtype);
4171 if (!GFC_ARRAY_TYPE_P (dtype))
4172 return NULL_TREE;
4173
4174 /* Determine the lengths of the array. */
4175 len = GFC_TYPE_ARRAY_SIZE (dtype);
4176 if (!len || TREE_CODE (len) != INTEGER_CST)
4177 return NULL_TREE;
4178
4179 /* Confirm that the constructor is the same size. */
4180 if (compare_tree_int (len, nelem) != 0)
4181 return NULL_TREE;
4182
7c57b2f1 4183 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
b01e2f88 4184 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
7c57b2f1 4185 fold_convert (gfc_array_index_type, tmp));
b01e2f88
RS
4186
4187 stype = gfc_typenode_for_spec (&expr2->ts);
4188 src = gfc_build_constant_array_constructor (expr2, stype);
4189
4190 stype = TREE_TYPE (src);
4191 if (POINTER_TYPE_P (stype))
4192 stype = TREE_TYPE (stype);
4193
4194 return gfc_build_memcpy_call (dst, src, len);
a3018753
RS
4195}
4196
4197
4198/* Subroutine of gfc_trans_assignment that actually scalarizes the
4199 assignment. EXPR1 is the destination/RHS and EXPR2 is the source/LHS. */
4200
4201static tree
4202gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
6de9cd9a
DN
4203{
4204 gfc_se lse;
4205 gfc_se rse;
4206 gfc_ss *lss;
4207 gfc_ss *lss_section;
4208 gfc_ss *rss;
4209 gfc_loopinfo loop;
4210 tree tmp;
4211 stmtblock_t block;
4212 stmtblock_t body;
5046aff5 4213 bool l_is_temp;
6de9cd9a 4214
6de9cd9a
DN
4215 /* Assignment of the form lhs = rhs. */
4216 gfc_start_block (&block);
4217
4218 gfc_init_se (&lse, NULL);
4219 gfc_init_se (&rse, NULL);
4220
4221 /* Walk the lhs. */
4222 lss = gfc_walk_expr (expr1);
4223 rss = NULL;
4224 if (lss != gfc_ss_terminator)
4225 {
4226 /* The assignment needs scalarization. */
4227 lss_section = lss;
4228
4229 /* Find a non-scalar SS from the lhs. */
4230 while (lss_section != gfc_ss_terminator
4231 && lss_section->type != GFC_SS_SECTION)
4232 lss_section = lss_section->next;
4233
6e45f57b 4234 gcc_assert (lss_section != gfc_ss_terminator);
6de9cd9a
DN
4235
4236 /* Initialize the scalarizer. */
4237 gfc_init_loopinfo (&loop);
4238
4239 /* Walk the rhs. */
4240 rss = gfc_walk_expr (expr2);
4241 if (rss == gfc_ss_terminator)
4242 {
4243 /* The rhs is scalar. Add a ss for the expression. */
4244 rss = gfc_get_ss ();
4245 rss->next = gfc_ss_terminator;
4246 rss->type = GFC_SS_SCALAR;
4247 rss->expr = expr2;
4248 }
4249 /* Associate the SS with the loop. */
4250 gfc_add_ss_to_loop (&loop, lss);
4251 gfc_add_ss_to_loop (&loop, rss);
4252
4253 /* Calculate the bounds of the scalarization. */
4254 gfc_conv_ss_startstride (&loop);
4255 /* Resolve any data dependencies in the statement. */
eca18fb4 4256 gfc_conv_resolve_dependencies (&loop, lss, rss);
6de9cd9a
DN
4257 /* Setup the scalarizing loops. */
4258 gfc_conv_loop_setup (&loop);
4259
4260 /* Setup the gfc_se structures. */
4261 gfc_copy_loopinfo_to_se (&lse, &loop);
4262 gfc_copy_loopinfo_to_se (&rse, &loop);
4263
4264 rse.ss = rss;
4265 gfc_mark_ss_chain_used (rss, 1);
4266 if (loop.temp_ss == NULL)
4267 {
4268 lse.ss = lss;
4269 gfc_mark_ss_chain_used (lss, 1);
4270 }
4271 else
4272 {
4273 lse.ss = loop.temp_ss;
4274 gfc_mark_ss_chain_used (lss, 3);
4275 gfc_mark_ss_chain_used (loop.temp_ss, 3);
4276 }
4277
4278 /* Start the scalarized loop body. */
4279 gfc_start_scalarized_body (&loop, &body);
4280 }
4281 else
4282 gfc_init_block (&body);
4283
5046aff5
PT
4284 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
4285
6de9cd9a
DN
4286 /* Translate the expression. */
4287 gfc_conv_expr (&rse, expr2);
4288
5046aff5 4289 if (l_is_temp)
6de9cd9a
DN
4290 {
4291 gfc_conv_tmp_array_ref (&lse);
4292 gfc_advance_se_ss_chain (&lse);
4293 }
4294 else
4295 gfc_conv_expr (&lse, expr1);
ec09945c 4296
6b591ec0
PT
4297 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
4298 l_is_temp || init_flag,
5046aff5 4299 expr2->expr_type == EXPR_VARIABLE);
6de9cd9a
DN
4300 gfc_add_expr_to_block (&body, tmp);
4301
4302 if (lss == gfc_ss_terminator)
4303 {
4304 /* Use the scalar assignment as is. */
4305 gfc_add_block_to_block (&block, &body);
4306 }
4307 else
4308 {
6e45f57b
PB
4309 gcc_assert (lse.ss == gfc_ss_terminator
4310 && rse.ss == gfc_ss_terminator);
6de9cd9a 4311
5046aff5 4312 if (l_is_temp)
6de9cd9a
DN
4313 {
4314 gfc_trans_scalarized_loop_boundary (&loop, &body);
4315
4316 /* We need to copy the temporary to the actual lhs. */
4317 gfc_init_se (&lse, NULL);
4318 gfc_init_se (&rse, NULL);
4319 gfc_copy_loopinfo_to_se (&lse, &loop);
4320 gfc_copy_loopinfo_to_se (&rse, &loop);
4321
4322 rse.ss = loop.temp_ss;
4323 lse.ss = lss;
4324
4325 gfc_conv_tmp_array_ref (&rse);
4326 gfc_advance_se_ss_chain (&rse);
4327 gfc_conv_expr (&lse, expr1);
4328
6e45f57b
PB
4329 gcc_assert (lse.ss == gfc_ss_terminator
4330 && rse.ss == gfc_ss_terminator);
6de9cd9a 4331
6b591ec0
PT
4332 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
4333 false, false);
6de9cd9a
DN
4334 gfc_add_expr_to_block (&body, tmp);
4335 }
5046aff5 4336
6de9cd9a
DN
4337 /* Generate the copying loops. */
4338 gfc_trans_scalarizing_loops (&loop, &body);
4339
4340 /* Wrap the whole thing up. */
4341 gfc_add_block_to_block (&block, &loop.pre);
4342 gfc_add_block_to_block (&block, &loop.post);
4343
4344 gfc_cleanup_loop (&loop);
4345 }
4346
4347 return gfc_finish_block (&block);
4348}
4349
a3018753 4350
18eaa2c0 4351/* Check whether EXPR is a copyable array. */
a3018753
RS
4352
4353static bool
4354copyable_array_p (gfc_expr * expr)
4355{
18eaa2c0
PT
4356 if (expr->expr_type != EXPR_VARIABLE)
4357 return false;
4358
a3018753 4359 /* First check it's an array. */
18eaa2c0
PT
4360 if (expr->rank < 1 || !expr->ref || expr->ref->next)
4361 return false;
4362
4363 if (!gfc_full_array_ref_p (expr->ref))
a3018753
RS
4364 return false;
4365
4366 /* Next check that it's of a simple enough type. */
4367 switch (expr->ts.type)
4368 {
4369 case BT_INTEGER:
4370 case BT_REAL:
4371 case BT_COMPLEX:
4372 case BT_LOGICAL:
4373 return true;
4374
150524cd
RS
4375 case BT_CHARACTER:
4376 return false;
4377
4378 case BT_DERIVED:
4379 return !expr->ts.derived->attr.alloc_comp;
4380
a3018753
RS
4381 default:
4382 break;
4383 }
4384
4385 return false;
4386}
4387
4388/* Translate an assignment. */
4389
4390tree
4391gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
4392{
4393 tree tmp;
4394
4395 /* Special case a single function returning an array. */
4396 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
4397 {
4398 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
4399 if (tmp)
4400 return tmp;
4401 }
4402
4403 /* Special case assigning an array to zero. */
18eaa2c0 4404 if (copyable_array_p (expr1)
a3018753
RS
4405 && is_zero_initializer_p (expr2))
4406 {
4407 tmp = gfc_trans_zero_assign (expr1);
4408 if (tmp)
4409 return tmp;
4410 }
4411
4412 /* Special case copying one array to another. */
18eaa2c0 4413 if (copyable_array_p (expr1)
a3018753 4414 && copyable_array_p (expr2)
a3018753
RS
4415 && gfc_compare_types (&expr1->ts, &expr2->ts)
4416 && !gfc_check_dependency (expr1, expr2, 0))
4417 {
4418 tmp = gfc_trans_array_copy (expr1, expr2);
4419 if (tmp)
4420 return tmp;
4421 }
4422
b01e2f88 4423 /* Special case initializing an array from a constant array constructor. */
18eaa2c0 4424 if (copyable_array_p (expr1)
b01e2f88
RS
4425 && expr2->expr_type == EXPR_ARRAY
4426 && gfc_compare_types (&expr1->ts, &expr2->ts))
4427 {
4428 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
4429 if (tmp)
4430 return tmp;
4431 }
4432
a3018753
RS
4433 /* Fallback to the scalarizer to generate explicit loops. */
4434 return gfc_trans_assignment_1 (expr1, expr2, init_flag);
4435}
4436
6b591ec0
PT
4437tree
4438gfc_trans_init_assign (gfc_code * code)
4439{
4440 return gfc_trans_assignment (code->expr, code->expr2, true);
4441}
4442
6de9cd9a
DN
4443tree
4444gfc_trans_assign (gfc_code * code)
4445{
6b591ec0 4446 return gfc_trans_assignment (code->expr, code->expr2, false);
6de9cd9a 4447}
This page took 1.72349 seconds and 5 git commands to generate.