]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans-expr.c
2009-11-19 Tobias Burnus <burnus@net-b.de>
[thirdparty/gcc.git] / gcc / fortran / trans-expr.c
CommitLineData
4ee9c684 1/* Expression translation
cfaf579d 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
ea94d76d 3 Free Software Foundation, Inc.
4ee9c684 4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6
c84b470d 7This file is part of GCC.
4ee9c684 8
c84b470d 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
bdabe786 11Software Foundation; either version 3, or (at your option) any later
c84b470d 12version.
4ee9c684 13
c84b470d 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.
4ee9c684 18
19You should have received a copy of the GNU General Public License
bdabe786 20along with GCC; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
4ee9c684 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"
4ee9c684 30#include "ggc.h"
31#include "toplev.h"
32#include "real.h"
75a70cf9 33#include "gimple.h"
59b9dcbd 34#include "langhooks.h"
4ee9c684 35#include "flags.h"
4ee9c684 36#include "gfortran.h"
fd149f95 37#include "arith.h"
4ee9c684 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"
c99d633f 44#include "dependency.h"
4ee9c684 45
9a0aec1d 46static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
fd149f95 47static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
f45a476e 48 gfc_expr *);
4ee9c684 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
f888a3fb 60/* Initialize a simple expression holder.
4ee9c684 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
f888a3fb 81 se->ss = se->ss->next because all the parents needs to be kept in sync.
4ee9c684 82 See gfc_init_se. */
83
84void
85gfc_advance_se_ss_chain (gfc_se * se)
86{
87 gfc_se *p;
88
22d678e8 89 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
4ee9c684 90
91 p = se;
92 /* Walk down the parent chain. */
93 while (p != NULL)
94 {
f888a3fb 95 /* Simple consistency check. */
22d678e8 96 gcc_assert (p->parent == NULL || p->parent->ss == p->ss);
4ee9c684 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
ce45a448 113 if (CONSTANT_CLASS_P (se->expr))
4ee9c684 114 return;
115
f888a3fb 116 /* We need a temporary for this result. */
4ee9c684 117 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
75a70cf9 118 gfc_add_modify (&se->pre, var, se->expr);
4ee9c684 119 se->expr = var;
120}
121
122
5cb9d0d8 123/* Return an expression which determines if a dummy parameter is present.
124 Also used for arguments to procedures with multiple entry points. */
4ee9c684 125
126tree
127gfc_conv_expr_present (gfc_symbol * sym)
128{
129 tree decl;
130
5cb9d0d8 131 gcc_assert (sym->attr.dummy);
4ee9c684 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. */
22d678e8 138 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
4ee9c684 139 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
140 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
141 }
f75d6b8a 142 return fold_build2 (NE_EXPR, boolean_type_node, decl,
143 fold_convert (TREE_TYPE (decl), null_pointer_node));
4ee9c684 144}
145
146
bd24f178 147/* Converts a missing, dummy argument into a null or zero. */
148
149void
2abe085f 150gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts, int kind)
bd24f178 151{
152 tree present;
153 tree tmp;
154
155 present = gfc_conv_expr_present (arg->symtree->n.sym);
24146844 156
2abe085f 157 if (kind > 0)
158 {
52c2abc3 159 /* Create a temporary and convert it to the correct type. */
2abe085f 160 tmp = gfc_get_int_type (kind);
389dd41b 161 tmp = fold_convert (tmp, build_fold_indirect_ref_loc (input_location,
162 se->expr));
52c2abc3 163
164 /* Test for a NULL value. */
55f62e9d 165 tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present, tmp,
166 fold_convert (TREE_TYPE (tmp), integer_one_node));
52c2abc3 167 tmp = gfc_evaluate_now (tmp, &se->pre);
86f2ad37 168 se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
52c2abc3 169 }
170 else
171 {
172 tmp = build3 (COND_EXPR, TREE_TYPE (se->expr), present, se->expr,
173 fold_convert (TREE_TYPE (se->expr), integer_zero_node));
174 tmp = gfc_evaluate_now (tmp, &se->pre);
175 se->expr = tmp;
2abe085f 176 }
24146844 177
bd24f178 178 if (ts.type == BT_CHARACTER)
179 {
7d3075f6 180 tmp = build_int_cst (gfc_charlen_type_node, 0);
f75d6b8a 181 tmp = fold_build3 (COND_EXPR, gfc_charlen_type_node,
182 present, se->string_length, tmp);
bd24f178 183 tmp = gfc_evaluate_now (tmp, &se->pre);
184 se->string_length = tmp;
185 }
186 return;
187}
188
189
6bf678b8 190/* Get the character length of an expression, looking through gfc_refs
191 if necessary. */
192
193tree
194gfc_get_expr_charlen (gfc_expr *e)
195{
196 gfc_ref *r;
197 tree length;
198
199 gcc_assert (e->expr_type == EXPR_VARIABLE
200 && e->ts.type == BT_CHARACTER);
201
202 length = NULL; /* To silence compiler warning. */
203
eeebe20b 204 if (is_subref_array (e) && e->ts.u.cl->length)
1033248c 205 {
206 gfc_se tmpse;
207 gfc_init_se (&tmpse, NULL);
eeebe20b 208 gfc_conv_expr_type (&tmpse, e->ts.u.cl->length, gfc_charlen_type_node);
209 e->ts.u.cl->backend_decl = tmpse.expr;
1033248c 210 return tmpse.expr;
211 }
212
6bf678b8 213 /* First candidate: if the variable is of type CHARACTER, the
214 expression's length could be the length of the character
b14e2757 215 variable. */
6bf678b8 216 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
eeebe20b 217 length = e->symtree->n.sym->ts.u.cl->backend_decl;
6bf678b8 218
219 /* Look through the reference chain for component references. */
220 for (r = e->ref; r; r = r->next)
221 {
222 switch (r->type)
223 {
224 case REF_COMPONENT:
225 if (r->u.c.component->ts.type == BT_CHARACTER)
eeebe20b 226 length = r->u.c.component->ts.u.cl->backend_decl;
6bf678b8 227 break;
228
229 case REF_ARRAY:
230 /* Do nothing. */
231 break;
232
233 default:
234 /* We should never got substring references here. These will be
235 broken down by the scalarizer. */
236 gcc_unreachable ();
1033248c 237 break;
6bf678b8 238 }
239 }
240
241 gcc_assert (length != NULL);
242 return length;
243}
244
d778204a 245
eeebe20b 246/* For each character array constructor subexpression without a ts.u.cl->length,
d778204a 247 replace it by its first element (if there aren't any elements, the length
248 should already be set to zero). */
249
250static void
251flatten_array_ctors_without_strlen (gfc_expr* e)
252{
253 gfc_actual_arglist* arg;
254 gfc_constructor* c;
255
256 if (!e)
257 return;
258
259 switch (e->expr_type)
260 {
261
262 case EXPR_OP:
263 flatten_array_ctors_without_strlen (e->value.op.op1);
264 flatten_array_ctors_without_strlen (e->value.op.op2);
265 break;
266
267 case EXPR_COMPCALL:
268 /* TODO: Implement as with EXPR_FUNCTION when needed. */
269 gcc_unreachable ();
270
271 case EXPR_FUNCTION:
272 for (arg = e->value.function.actual; arg; arg = arg->next)
273 flatten_array_ctors_without_strlen (arg->expr);
274 break;
275
276 case EXPR_ARRAY:
277
278 /* We've found what we're looking for. */
eeebe20b 279 if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
d778204a 280 {
281 gfc_expr* new_expr;
282 gcc_assert (e->value.constructor);
283
284 new_expr = e->value.constructor->expr;
285 e->value.constructor->expr = NULL;
286
287 flatten_array_ctors_without_strlen (new_expr);
288 gfc_replace_expr (e, new_expr);
289 break;
290 }
291
292 /* Otherwise, fall through to handle constructor elements. */
293 case EXPR_STRUCTURE:
294 for (c = e->value.constructor; c; c = c->next)
295 flatten_array_ctors_without_strlen (c->expr);
296 break;
297
298 default:
299 break;
300
301 }
302}
303
6bf678b8 304
4ee9c684 305/* Generate code to initialize a string length variable. Returns the
d778204a 306 value. For array constructors, cl->length might be NULL and in this case,
307 the first element of the constructor is needed. expr is the original
308 expression so we can access it but can be NULL if this is not needed. */
4ee9c684 309
310void
d778204a 311gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
4ee9c684 312{
313 gfc_se se;
4ee9c684 314
315 gfc_init_se (&se, NULL);
d778204a 316
317 /* If cl->length is NULL, use gfc_conv_expr to obtain the string length but
318 "flatten" array constructors by taking their first element; all elements
319 should be the same length or a cl->length should be present. */
320 if (!cl->length)
321 {
322 gfc_expr* expr_flat;
323 gcc_assert (expr);
324
325 expr_flat = gfc_copy_expr (expr);
326 flatten_array_ctors_without_strlen (expr_flat);
327 gfc_resolve_expr (expr_flat);
328
329 gfc_conv_expr (&se, expr_flat);
330 gfc_add_block_to_block (pblock, &se.pre);
331 cl->backend_decl = convert (gfc_charlen_type_node, se.string_length);
332
333 gfc_free_expr (expr_flat);
334 return;
335 }
336
337 /* Convert cl->length. */
338
339 gcc_assert (cl->length);
340
9ad09405 341 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
a0ab480a 342 se.expr = fold_build2 (MAX_EXPR, gfc_charlen_type_node, se.expr,
343 build_int_cst (gfc_charlen_type_node, 0));
4ee9c684 344 gfc_add_block_to_block (pblock, &se.pre);
345
0ff77f4e 346 if (cl->backend_decl)
75a70cf9 347 gfc_add_modify (pblock, cl->backend_decl, se.expr);
0ff77f4e 348 else
349 cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
4ee9c684 350}
351
f888a3fb 352
4ee9c684 353static void
ee3729de 354gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
355 const char *name, locus *where)
4ee9c684 356{
357 tree tmp;
358 tree type;
359 tree var;
ee3729de 360 tree fault;
4ee9c684 361 gfc_se start;
362 gfc_se end;
ee3729de 363 char *msg;
4ee9c684 364
365 type = gfc_get_character_type (kind, ref->u.ss.length);
366 type = build_pointer_type (type);
367
368 var = NULL_TREE;
369 gfc_init_se (&start, se);
9ad09405 370 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
4ee9c684 371 gfc_add_block_to_block (&se->pre, &start.pre);
372
373 if (integer_onep (start.expr))
260abd71 374 gfc_conv_string_parameter (se);
4ee9c684 375 else
376 {
e1b3b79b 377 tmp = start.expr;
378 STRIP_NOPS (tmp);
1bfb5669 379 /* Avoid multiple evaluation of substring start. */
e1b3b79b 380 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1bfb5669 381 start.expr = gfc_evaluate_now (start.expr, &se->pre);
382
4ee9c684 383 /* Change the start of the string. */
384 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
385 tmp = se->expr;
386 else
389dd41b 387 tmp = build_fold_indirect_ref_loc (input_location,
388 se->expr);
1033248c 389 tmp = gfc_build_array_ref (tmp, start.expr, NULL);
4ee9c684 390 se->expr = gfc_build_addr_expr (type, tmp);
391 }
392
393 /* Length = end + 1 - start. */
394 gfc_init_se (&end, se);
395 if (ref->u.ss.end == NULL)
396 end.expr = se->string_length;
397 else
398 {
9ad09405 399 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
4ee9c684 400 gfc_add_block_to_block (&se->pre, &end.pre);
401 }
e1b3b79b 402 tmp = end.expr;
403 STRIP_NOPS (tmp);
404 if (!CONSTANT_CLASS_P (tmp) && !DECL_P (tmp))
1bfb5669 405 end.expr = gfc_evaluate_now (end.expr, &se->pre);
406
ad8ed98e 407 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
ee3729de 408 {
53e60566 409 tree nonempty = fold_build2 (LE_EXPR, boolean_type_node,
410 start.expr, end.expr);
411
ee3729de 412 /* Check lower bound. */
413 fault = fold_build2 (LT_EXPR, boolean_type_node, start.expr,
414 build_int_cst (gfc_charlen_type_node, 1));
53e60566 415 fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
416 nonempty, fault);
ee3729de 417 if (name)
399aecc1 418 asprintf (&msg, "Substring out of bounds: lower bound (%%ld) of '%s' "
ee3729de 419 "is less than one", name);
420 else
399aecc1 421 asprintf (&msg, "Substring out of bounds: lower bound (%%ld)"
ee3729de 422 "is less than one");
da6ffc6d 423 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
399aecc1 424 fold_convert (long_integer_type_node,
425 start.expr));
ee3729de 426 gfc_free (msg);
427
428 /* Check upper bound. */
429 fault = fold_build2 (GT_EXPR, boolean_type_node, end.expr,
430 se->string_length);
53e60566 431 fault = fold_build2 (TRUTH_ANDIF_EXPR, boolean_type_node,
432 nonempty, fault);
ee3729de 433 if (name)
399aecc1 434 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) of '%s' "
435 "exceeds string length (%%ld)", name);
ee3729de 436 else
399aecc1 437 asprintf (&msg, "Substring out of bounds: upper bound (%%ld) "
438 "exceeds string length (%%ld)");
da6ffc6d 439 gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
399aecc1 440 fold_convert (long_integer_type_node, end.expr),
441 fold_convert (long_integer_type_node,
442 se->string_length));
ee3729de 443 gfc_free (msg);
444 }
445
ce825331 446 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node,
e1b3b79b 447 end.expr, start.expr);
448 tmp = fold_build2 (PLUS_EXPR, gfc_charlen_type_node,
449 build_int_cst (gfc_charlen_type_node, 1), tmp);
2810b378 450 tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
451 build_int_cst (gfc_charlen_type_node, 0));
ce825331 452 se->string_length = tmp;
4ee9c684 453}
454
455
456/* Convert a derived type component reference. */
457
458static void
459gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
460{
461 gfc_component *c;
462 tree tmp;
463 tree decl;
464 tree field;
465
466 c = ref->u.c.component;
467
22d678e8 468 gcc_assert (c->backend_decl);
4ee9c684 469
470 field = c->backend_decl;
22d678e8 471 gcc_assert (TREE_CODE (field) == FIELD_DECL);
4ee9c684 472 decl = se->expr;
f75d6b8a 473 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
4ee9c684 474
475 se->expr = tmp;
476
1d84f30a 477 if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer)
4ee9c684 478 {
eeebe20b 479 tmp = c->ts.u.cl->backend_decl;
7949cb07 480 /* Components must always be constant length. */
22d678e8 481 gcc_assert (tmp && INTEGER_CST_P (tmp));
4ee9c684 482 se->string_length = tmp;
483 }
484
1de1b1a9 485 if (((c->attr.pointer || c->attr.allocatable) && c->attr.dimension == 0
486 && c->ts.type != BT_CHARACTER)
85d1c108 487 || c->attr.proc_pointer)
389dd41b 488 se->expr = build_fold_indirect_ref_loc (input_location,
489 se->expr);
4ee9c684 490}
491
492
ea94d76d 493/* This function deals with component references to components of the
494 parent type for derived type extensons. */
495static void
496conv_parent_component_references (gfc_se * se, gfc_ref * ref)
497{
498 gfc_component *c;
499 gfc_component *cmp;
500 gfc_symbol *dt;
501 gfc_ref parent;
502
503 dt = ref->u.c.sym;
504 c = ref->u.c.component;
505
506 /* Build a gfc_ref to recursively call gfc_conv_component_ref. */
507 parent.type = REF_COMPONENT;
508 parent.next = NULL;
509 parent.u.c.sym = dt;
510 parent.u.c.component = dt->components;
511
512 if (dt->attr.extension && dt->components)
513 {
1de1b1a9 514 if (dt->attr.is_class)
515 cmp = dt->components;
516 else
517 cmp = dt->components->next;
ea94d76d 518 /* Return if the component is not in the parent type. */
1de1b1a9 519 for (; cmp; cmp = cmp->next)
ea94d76d 520 if (strcmp (c->name, cmp->name) == 0)
521 return;
522
523 /* Otherwise build the reference and call self. */
524 gfc_conv_component_ref (se, &parent);
eeebe20b 525 parent.u.c.sym = dt->components->ts.u.derived;
ea94d76d 526 parent.u.c.component = c;
527 conv_parent_component_references (se, &parent);
528 }
529}
530
4ee9c684 531/* Return the contents of a variable. Also handles reference/pointer
532 variables (all Fortran pointer references are implicit). */
533
534static void
535gfc_conv_variable (gfc_se * se, gfc_expr * expr)
536{
537 gfc_ref *ref;
538 gfc_symbol *sym;
c750cc52 539 tree parent_decl;
540 int parent_flag;
541 bool return_value;
542 bool alternate_entry;
543 bool entry_master;
4ee9c684 544
545 sym = expr->symtree->n.sym;
546 if (se->ss != NULL)
547 {
548 /* Check that something hasn't gone horribly wrong. */
22d678e8 549 gcc_assert (se->ss != gfc_ss_terminator);
550 gcc_assert (se->ss->expr == expr);
4ee9c684 551
552 /* A scalarized term. We already know the descriptor. */
553 se->expr = se->ss->data.info.descriptor;
7949cb07 554 se->string_length = se->ss->string_length;
598d8efb 555 for (ref = se->ss->data.info.ref; ref; ref = ref->next)
556 if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
557 break;
4ee9c684 558 }
559 else
560 {
c6871095 561 tree se_expr = NULL_TREE;
562
b7bf3f81 563 se->expr = gfc_get_symbol_decl (sym);
4ee9c684 564
c750cc52 565 /* Deal with references to a parent results or entries by storing
566 the current_function_decl and moving to the parent_decl. */
c750cc52 567 return_value = sym->attr.function && sym->result == sym;
568 alternate_entry = sym->attr.function && sym->attr.entry
b01f72f3 569 && sym->result == sym;
c750cc52 570 entry_master = sym->attr.result
b01f72f3 571 && sym->ns->proc_name->attr.entry_master
572 && !gfc_return_by_reference (sym->ns->proc_name);
c750cc52 573 parent_decl = DECL_CONTEXT (current_function_decl);
574
575 if ((se->expr == parent_decl && return_value)
b01f72f3 576 || (sym->ns && sym->ns->proc_name
d77f260f 577 && parent_decl
b01f72f3 578 && sym->ns->proc_name->backend_decl == parent_decl
579 && (alternate_entry || entry_master)))
c750cc52 580 parent_flag = 1;
581 else
582 parent_flag = 0;
583
c6871095 584 /* Special case for assigning the return value of a function.
585 Self recursive functions must have an explicit return value. */
b01f72f3 586 if (return_value && (se->expr == current_function_decl || parent_flag))
c750cc52 587 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
c6871095 588
589 /* Similarly for alternate entry points. */
c750cc52 590 else if (alternate_entry
b01f72f3 591 && (sym->ns->proc_name->backend_decl == current_function_decl
592 || parent_flag))
c6871095 593 {
594 gfc_entry_list *el = NULL;
595
596 for (el = sym->ns->entries; el; el = el->next)
597 if (sym == el->sym)
598 {
c750cc52 599 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
c6871095 600 break;
601 }
602 }
603
c750cc52 604 else if (entry_master
b01f72f3 605 && (sym->ns->proc_name->backend_decl == current_function_decl
606 || parent_flag))
c750cc52 607 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
c6871095 608
609 if (se_expr)
610 se->expr = se_expr;
611
4ee9c684 612 /* Procedure actual arguments. */
c6871095 613 else if (sym->attr.flavor == FL_PROCEDURE
614 && se->expr != current_function_decl)
4ee9c684 615 {
cad0ddcf 616 if (!sym->attr.dummy && !sym->attr.proc_pointer)
4ee9c684 617 {
22d678e8 618 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
86f2ad37 619 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
4ee9c684 620 }
621 return;
544c333b 622 }
623
624
625 /* Dereference the expression, where needed. Since characters
626 are entirely different from other types, they are treated
627 separately. */
628 if (sym->ts.type == BT_CHARACTER)
629 {
8f6339b6 630 /* Dereference character pointer dummy arguments
bf7e666b 631 or results. */
544c333b 632 if ((sym->attr.pointer || sym->attr.allocatable)
4442ee19 633 && (sym->attr.dummy
634 || sym->attr.function
635 || sym->attr.result))
389dd41b 636 se->expr = build_fold_indirect_ref_loc (input_location,
637 se->expr);
8f6339b6 638
544c333b 639 }
8f6339b6 640 else if (!sym->attr.value)
544c333b 641 {
747a9f62 642 /* Dereference non-character scalar dummy arguments. */
4442ee19 643 if (sym->attr.dummy && !sym->attr.dimension)
389dd41b 644 se->expr = build_fold_indirect_ref_loc (input_location,
645 se->expr);
544c333b 646
bf7e666b 647 /* Dereference scalar hidden result. */
4442ee19 648 if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
544c333b 649 && (sym->attr.function || sym->attr.result)
36efa756 650 && !sym->attr.dimension && !sym->attr.pointer
651 && !sym->attr.always_explicit)
389dd41b 652 se->expr = build_fold_indirect_ref_loc (input_location,
653 se->expr);
544c333b 654
655 /* Dereference non-character pointer variables.
747a9f62 656 These must be dummies, results, or scalars. */
544c333b 657 if ((sym->attr.pointer || sym->attr.allocatable)
4442ee19 658 && (sym->attr.dummy
659 || sym->attr.function
660 || sym->attr.result
661 || !sym->attr.dimension))
389dd41b 662 se->expr = build_fold_indirect_ref_loc (input_location,
663 se->expr);
544c333b 664 }
665
4ee9c684 666 ref = expr->ref;
667 }
668
669 /* For character variables, also get the length. */
670 if (sym->ts.type == BT_CHARACTER)
671 {
7af6a4af 672 /* If the character length of an entry isn't set, get the length from
673 the master function instead. */
eeebe20b 674 if (sym->attr.entry && !sym->ts.u.cl->backend_decl)
675 se->string_length = sym->ns->proc_name->ts.u.cl->backend_decl;
7af6a4af 676 else
eeebe20b 677 se->string_length = sym->ts.u.cl->backend_decl;
22d678e8 678 gcc_assert (se->string_length);
4ee9c684 679 }
680
681 while (ref)
682 {
683 switch (ref->type)
684 {
685 case REF_ARRAY:
686 /* Return the descriptor if that's what we want and this is an array
687 section reference. */
688 if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
689 return;
690/* TODO: Pointers to single elements of array sections, eg elemental subs. */
691 /* Return the descriptor for array pointers and allocations. */
692 if (se->want_pointer
693 && ref->next == NULL && (se->descriptor_only))
694 return;
695
97c2a00c 696 gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
4ee9c684 697 /* Return a pointer to an element. */
698 break;
699
700 case REF_COMPONENT:
ea94d76d 701 if (ref->u.c.sym->attr.extension)
702 conv_parent_component_references (se, ref);
703
4ee9c684 704 gfc_conv_component_ref (se, ref);
705 break;
706
707 case REF_SUBSTRING:
ee3729de 708 gfc_conv_substring (se, ref, expr->ts.kind,
709 expr->symtree->name, &expr->where);
4ee9c684 710 break;
711
712 default:
22d678e8 713 gcc_unreachable ();
4ee9c684 714 break;
715 }
716 ref = ref->next;
717 }
718 /* Pointer assignment, allocation or pass by reference. Arrays are handled
f888a3fb 719 separately. */
4ee9c684 720 if (se->want_pointer)
721 {
1d84f30a 722 if (expr->ts.type == BT_CHARACTER && !gfc_is_proc_ptr_comp (expr, NULL))
4ee9c684 723 gfc_conv_string_parameter (se);
724 else
86f2ad37 725 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
4ee9c684 726 }
4ee9c684 727}
728
729
730/* Unary ops are easy... Or they would be if ! was a valid op. */
731
732static void
733gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
734{
735 gfc_se operand;
736 tree type;
737
22d678e8 738 gcc_assert (expr->ts.type != BT_CHARACTER);
4ee9c684 739 /* Initialize the operand. */
740 gfc_init_se (&operand, se);
9b773341 741 gfc_conv_expr_val (&operand, expr->value.op.op1);
4ee9c684 742 gfc_add_block_to_block (&se->pre, &operand.pre);
743
744 type = gfc_typenode_for_spec (&expr->ts);
745
746 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
747 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
f888a3fb 748 All other unary operators have an equivalent GIMPLE unary operator. */
4ee9c684 749 if (code == TRUTH_NOT_EXPR)
751ff693 750 se->expr = fold_build2 (EQ_EXPR, type, operand.expr,
751 build_int_cst (type, 0));
4ee9c684 752 else
751ff693 753 se->expr = fold_build1 (code, type, operand.expr);
4ee9c684 754
755}
756
76834664 757/* Expand power operator to optimal multiplications when a value is raised
f888a3fb 758 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
76834664 759 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
760 Programming", 3rd Edition, 1998. */
761
762/* This code is mostly duplicated from expand_powi in the backend.
763 We establish the "optimal power tree" lookup table with the defined size.
764 The items in the table are the exponents used to calculate the index
765 exponents. Any integer n less than the value can get an "addition chain",
766 with the first node being one. */
767#define POWI_TABLE_SIZE 256
768
f888a3fb 769/* The table is from builtins.c. */
76834664 770static const unsigned char powi_table[POWI_TABLE_SIZE] =
771 {
772 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
773 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
774 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
775 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
776 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
777 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
778 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
779 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
780 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
781 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
782 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
783 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
784 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
785 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
786 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
787 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
788 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
789 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
790 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
791 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
792 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
793 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
794 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
795 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
796 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
797 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
798 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
799 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
800 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
801 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
802 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
803 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
804 };
805
f888a3fb 806/* If n is larger than lookup table's max index, we use the "window
807 method". */
76834664 808#define POWI_WINDOW_SIZE 3
809
f888a3fb 810/* Recursive function to expand the power operator. The temporary
811 values are put in tmpvar. The function returns tmpvar[1] ** n. */
76834664 812static tree
6929935b 813gfc_conv_powi (gfc_se * se, unsigned HOST_WIDE_INT n, tree * tmpvar)
4ee9c684 814{
76834664 815 tree op0;
816 tree op1;
4ee9c684 817 tree tmp;
76834664 818 int digit;
4ee9c684 819
76834664 820 if (n < POWI_TABLE_SIZE)
4ee9c684 821 {
76834664 822 if (tmpvar[n])
823 return tmpvar[n];
4ee9c684 824
76834664 825 op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
826 op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
827 }
828 else if (n & 1)
829 {
830 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
831 op0 = gfc_conv_powi (se, n - digit, tmpvar);
832 op1 = gfc_conv_powi (se, digit, tmpvar);
4ee9c684 833 }
834 else
835 {
76834664 836 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
837 op1 = op0;
4ee9c684 838 }
839
318c9b27 840 tmp = fold_build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1);
76834664 841 tmp = gfc_evaluate_now (tmp, &se->pre);
4ee9c684 842
76834664 843 if (n < POWI_TABLE_SIZE)
844 tmpvar[n] = tmp;
4ee9c684 845
76834664 846 return tmp;
847}
4ee9c684 848
f888a3fb 849
850/* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
851 return 1. Else return 0 and a call to runtime library functions
852 will have to be built. */
76834664 853static int
854gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
855{
856 tree cond;
857 tree tmp;
858 tree type;
859 tree vartmp[POWI_TABLE_SIZE];
6929935b 860 HOST_WIDE_INT m;
861 unsigned HOST_WIDE_INT n;
76834664 862 int sgn;
4ee9c684 863
6929935b 864 /* If exponent is too large, we won't expand it anyway, so don't bother
865 with large integer values. */
866 if (!double_int_fits_in_shwi_p (TREE_INT_CST (rhs)))
867 return 0;
868
869 m = double_int_to_shwi (TREE_INT_CST (rhs));
870 /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
871 of the asymmetric range of the integer type. */
872 n = (unsigned HOST_WIDE_INT) (m < 0 ? -m : m);
873
76834664 874 type = TREE_TYPE (lhs);
76834664 875 sgn = tree_int_cst_sgn (rhs);
4ee9c684 876
6929935b 877 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
878 || optimize_size) && (m > 2 || m < -1))
76834664 879 return 0;
4ee9c684 880
76834664 881 /* rhs == 0 */
882 if (sgn == 0)
883 {
884 se->expr = gfc_build_const (type, integer_one_node);
885 return 1;
886 }
6929935b 887
76834664 888 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
889 if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
890 {
f75d6b8a 891 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
892 lhs, build_int_cst (TREE_TYPE (lhs), -1));
893 cond = fold_build2 (EQ_EXPR, boolean_type_node,
894 lhs, build_int_cst (TREE_TYPE (lhs), 1));
76834664 895
f888a3fb 896 /* If rhs is even,
260abd71 897 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
76834664 898 if ((n & 1) == 0)
899 {
f75d6b8a 900 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
901 se->expr = fold_build3 (COND_EXPR, type,
902 tmp, build_int_cst (type, 1),
903 build_int_cst (type, 0));
76834664 904 return 1;
905 }
f888a3fb 906 /* If rhs is odd,
76834664 907 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
f75d6b8a 908 tmp = fold_build3 (COND_EXPR, type, tmp, build_int_cst (type, -1),
909 build_int_cst (type, 0));
910 se->expr = fold_build3 (COND_EXPR, type,
911 cond, build_int_cst (type, 1), tmp);
76834664 912 return 1;
913 }
4ee9c684 914
76834664 915 memset (vartmp, 0, sizeof (vartmp));
916 vartmp[1] = lhs;
76834664 917 if (sgn == -1)
918 {
919 tmp = gfc_build_const (type, integer_one_node);
f75d6b8a 920 vartmp[1] = fold_build2 (RDIV_EXPR, type, tmp, vartmp[1]);
76834664 921 }
f5efe504 922
923 se->expr = gfc_conv_powi (se, n, vartmp);
924
76834664 925 return 1;
4ee9c684 926}
927
928
76834664 929/* Power op (**). Constant integer exponent has special handling. */
4ee9c684 930
931static void
932gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
933{
90ba9145 934 tree gfc_int4_type_node;
4ee9c684 935 int kind;
76834664 936 int ikind;
4ee9c684 937 gfc_se lse;
938 gfc_se rse;
939 tree fndecl;
4ee9c684 940
941 gfc_init_se (&lse, se);
9b773341 942 gfc_conv_expr_val (&lse, expr->value.op.op1);
7f0345dc 943 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
4ee9c684 944 gfc_add_block_to_block (&se->pre, &lse.pre);
945
946 gfc_init_se (&rse, se);
9b773341 947 gfc_conv_expr_val (&rse, expr->value.op.op2);
4ee9c684 948 gfc_add_block_to_block (&se->pre, &rse.pre);
949
9b773341 950 if (expr->value.op.op2->ts.type == BT_INTEGER
150c0c39 951 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
76834664 952 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
150c0c39 953 return;
4ee9c684 954
90ba9145 955 gfc_int4_type_node = gfc_get_int_type (4);
956
9b773341 957 kind = expr->value.op.op1->ts.kind;
958 switch (expr->value.op.op2->ts.type)
4ee9c684 959 {
960 case BT_INTEGER:
9b773341 961 ikind = expr->value.op.op2->ts.kind;
76834664 962 switch (ikind)
963 {
964 case 1:
965 case 2:
966 rse.expr = convert (gfc_int4_type_node, rse.expr);
967 /* Fall through. */
968
969 case 4:
970 ikind = 0;
971 break;
972
973 case 8:
974 ikind = 1;
975 break;
976
920e54ef 977 case 16:
978 ikind = 2;
979 break;
980
76834664 981 default:
22d678e8 982 gcc_unreachable ();
76834664 983 }
984 switch (kind)
985 {
986 case 1:
987 case 2:
9b773341 988 if (expr->value.op.op1->ts.type == BT_INTEGER)
76834664 989 lse.expr = convert (gfc_int4_type_node, lse.expr);
990 else
22d678e8 991 gcc_unreachable ();
76834664 992 /* Fall through. */
993
994 case 4:
995 kind = 0;
996 break;
997
998 case 8:
999 kind = 1;
1000 break;
1001
920e54ef 1002 case 10:
1003 kind = 2;
1004 break;
1005
1006 case 16:
1007 kind = 3;
1008 break;
1009
76834664 1010 default:
22d678e8 1011 gcc_unreachable ();
76834664 1012 }
1013
9b773341 1014 switch (expr->value.op.op1->ts.type)
76834664 1015 {
1016 case BT_INTEGER:
920e54ef 1017 if (kind == 3) /* Case 16 was not handled properly above. */
1018 kind = 2;
76834664 1019 fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
1020 break;
1021
1022 case BT_REAL:
150c0c39 1023 /* Use builtins for real ** int4. */
1024 if (ikind == 0)
1025 {
1026 switch (kind)
1027 {
1028 case 0:
1029 fndecl = built_in_decls[BUILT_IN_POWIF];
1030 break;
1031
1032 case 1:
1033 fndecl = built_in_decls[BUILT_IN_POWI];
1034 break;
1035
1036 case 2:
1037 case 3:
1038 fndecl = built_in_decls[BUILT_IN_POWIL];
1039 break;
1040
1041 default:
1042 gcc_unreachable ();
1043 }
1044 }
1045 else
1046 fndecl = gfor_fndecl_math_powi[kind][ikind].real;
76834664 1047 break;
1048
1049 case BT_COMPLEX:
1050 fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
1051 break;
1052
1053 default:
22d678e8 1054 gcc_unreachable ();
76834664 1055 }
1056 break;
4ee9c684 1057
1058 case BT_REAL:
1059 switch (kind)
1060 {
1061 case 4:
76834664 1062 fndecl = built_in_decls[BUILT_IN_POWF];
4ee9c684 1063 break;
1064 case 8:
76834664 1065 fndecl = built_in_decls[BUILT_IN_POW];
4ee9c684 1066 break;
920e54ef 1067 case 10:
1068 case 16:
1069 fndecl = built_in_decls[BUILT_IN_POWL];
1070 break;
4ee9c684 1071 default:
22d678e8 1072 gcc_unreachable ();
4ee9c684 1073 }
1074 break;
1075
1076 case BT_COMPLEX:
1077 switch (kind)
1078 {
1079 case 4:
6aee6ac8 1080 fndecl = built_in_decls[BUILT_IN_CPOWF];
4ee9c684 1081 break;
1082 case 8:
6aee6ac8 1083 fndecl = built_in_decls[BUILT_IN_CPOW];
4ee9c684 1084 break;
920e54ef 1085 case 10:
920e54ef 1086 case 16:
6aee6ac8 1087 fndecl = built_in_decls[BUILT_IN_CPOWL];
920e54ef 1088 break;
4ee9c684 1089 default:
22d678e8 1090 gcc_unreachable ();
4ee9c684 1091 }
1092 break;
1093
1094 default:
22d678e8 1095 gcc_unreachable ();
4ee9c684 1096 break;
1097 }
1098
389dd41b 1099 se->expr = build_call_expr_loc (input_location,
1100 fndecl, 2, lse.expr, rse.expr);
4ee9c684 1101}
1102
1103
1104/* Generate code to allocate a string temporary. */
1105
1106tree
1107gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
1108{
1109 tree var;
1110 tree tmp;
4ee9c684 1111
f76d4106 1112 gcc_assert (types_compatible_p (TREE_TYPE (len), gfc_charlen_type_node));
260abd71 1113
4ee9c684 1114 if (gfc_can_put_var_on_stack (len))
1115 {
1116 /* Create a temporary variable to hold the result. */
318c9b27 1117 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
7d3075f6 1118 build_int_cst (gfc_charlen_type_node, 1));
260abd71 1119 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
51bd6479 1120
1121 if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
1122 tmp = build_array_type (TREE_TYPE (TREE_TYPE (type)), tmp);
1123 else
1124 tmp = build_array_type (TREE_TYPE (type), tmp);
1125
4ee9c684 1126 var = gfc_create_var (tmp, "str");
1127 var = gfc_build_addr_expr (type, var);
1128 }
1129 else
1130 {
1131 /* Allocate a temporary to hold the result. */
1132 var = gfc_create_var (type, "pstr");
b44437b9 1133 tmp = gfc_call_malloc (&se->pre, type,
1134 fold_build2 (MULT_EXPR, TREE_TYPE (len), len,
1135 fold_convert (TREE_TYPE (len),
1136 TYPE_SIZE (type))));
75a70cf9 1137 gfc_add_modify (&se->pre, var, tmp);
4ee9c684 1138
1139 /* Free the temporary afterwards. */
6a2a96d6 1140 tmp = gfc_call_free (convert (pvoid_type_node, var));
4ee9c684 1141 gfc_add_expr_to_block (&se->post, tmp);
1142 }
1143
1144 return var;
1145}
1146
1147
1148/* Handle a string concatenation operation. A temporary will be allocated to
1149 hold the result. */
1150
1151static void
1152gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
1153{
40b806de 1154 gfc_se lse, rse;
1155 tree len, type, var, tmp, fndecl;
4ee9c684 1156
9b773341 1157 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
40b806de 1158 && expr->value.op.op2->ts.type == BT_CHARACTER);
b44437b9 1159 gcc_assert (expr->value.op.op1->ts.kind == expr->value.op.op2->ts.kind);
4ee9c684 1160
1161 gfc_init_se (&lse, se);
9b773341 1162 gfc_conv_expr (&lse, expr->value.op.op1);
4ee9c684 1163 gfc_conv_string_parameter (&lse);
1164 gfc_init_se (&rse, se);
9b773341 1165 gfc_conv_expr (&rse, expr->value.op.op2);
4ee9c684 1166 gfc_conv_string_parameter (&rse);
1167
1168 gfc_add_block_to_block (&se->pre, &lse.pre);
1169 gfc_add_block_to_block (&se->pre, &rse.pre);
1170
eeebe20b 1171 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
4ee9c684 1172 len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
1173 if (len == NULL_TREE)
1174 {
318c9b27 1175 len = fold_build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
1176 lse.string_length, rse.string_length);
4ee9c684 1177 }
1178
1179 type = build_pointer_type (type);
1180
1181 var = gfc_conv_string_tmp (se, type, len);
1182
1183 /* Do the actual concatenation. */
40b806de 1184 if (expr->ts.kind == 1)
1185 fndecl = gfor_fndecl_concat_string;
1186 else if (expr->ts.kind == 4)
1187 fndecl = gfor_fndecl_concat_string_char4;
1188 else
1189 gcc_unreachable ();
1190
389dd41b 1191 tmp = build_call_expr_loc (input_location,
1192 fndecl, 6, len, var, lse.string_length, lse.expr,
c2f47e15 1193 rse.string_length, rse.expr);
4ee9c684 1194 gfc_add_expr_to_block (&se->pre, tmp);
1195
1196 /* Add the cleanup for the operands. */
1197 gfc_add_block_to_block (&se->pre, &rse.post);
1198 gfc_add_block_to_block (&se->pre, &lse.post);
1199
1200 se->expr = var;
1201 se->string_length = len;
1202}
1203
4ee9c684 1204/* Translates an op expression. Common (binary) cases are handled by this
1205 function, others are passed on. Recursion is used in either case.
1206 We use the fact that (op1.ts == op2.ts) (except for the power
f888a3fb 1207 operator **).
4ee9c684 1208 Operators need no special handling for scalarized expressions as long as
f888a3fb 1209 they call gfc_conv_simple_val to get their operands.
4ee9c684 1210 Character strings get special handling. */
1211
1212static void
1213gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
1214{
1215 enum tree_code code;
1216 gfc_se lse;
1217 gfc_se rse;
f20cadb1 1218 tree tmp, type;
4ee9c684 1219 int lop;
1220 int checkstring;
1221
1222 checkstring = 0;
1223 lop = 0;
dcb1b019 1224 switch (expr->value.op.op)
4ee9c684 1225 {
42b215cc 1226 case INTRINSIC_PARENTHESES:
751ff693 1227 if (expr->ts.type == BT_REAL
1228 || expr->ts.type == BT_COMPLEX)
1229 {
1230 gfc_conv_unary_op (PAREN_EXPR, se, expr);
1231 gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
1232 return;
1233 }
1234
1235 /* Fallthrough. */
1236 case INTRINSIC_UPLUS:
9b773341 1237 gfc_conv_expr (se, expr->value.op.op1);
4ee9c684 1238 return;
1239
1240 case INTRINSIC_UMINUS:
1241 gfc_conv_unary_op (NEGATE_EXPR, se, expr);
1242 return;
1243
1244 case INTRINSIC_NOT:
1245 gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
1246 return;
1247
1248 case INTRINSIC_PLUS:
1249 code = PLUS_EXPR;
1250 break;
1251
1252 case INTRINSIC_MINUS:
1253 code = MINUS_EXPR;
1254 break;
1255
1256 case INTRINSIC_TIMES:
1257 code = MULT_EXPR;
1258 break;
1259
1260 case INTRINSIC_DIVIDE:
1261 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
1262 an integer, we must round towards zero, so we use a
1263 TRUNC_DIV_EXPR. */
1264 if (expr->ts.type == BT_INTEGER)
1265 code = TRUNC_DIV_EXPR;
1266 else
1267 code = RDIV_EXPR;
1268 break;
1269
1270 case INTRINSIC_POWER:
1271 gfc_conv_power_op (se, expr);
1272 return;
1273
1274 case INTRINSIC_CONCAT:
1275 gfc_conv_concat_op (se, expr);
1276 return;
1277
1278 case INTRINSIC_AND:
1279 code = TRUTH_ANDIF_EXPR;
1280 lop = 1;
1281 break;
1282
1283 case INTRINSIC_OR:
1284 code = TRUTH_ORIF_EXPR;
1285 lop = 1;
1286 break;
1287
1288 /* EQV and NEQV only work on logicals, but since we represent them
88bce636 1289 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
4ee9c684 1290 case INTRINSIC_EQ:
f47957c7 1291 case INTRINSIC_EQ_OS:
4ee9c684 1292 case INTRINSIC_EQV:
1293 code = EQ_EXPR;
1294 checkstring = 1;
1295 lop = 1;
1296 break;
1297
1298 case INTRINSIC_NE:
f47957c7 1299 case INTRINSIC_NE_OS:
4ee9c684 1300 case INTRINSIC_NEQV:
1301 code = NE_EXPR;
1302 checkstring = 1;
1303 lop = 1;
1304 break;
1305
1306 case INTRINSIC_GT:
f47957c7 1307 case INTRINSIC_GT_OS:
4ee9c684 1308 code = GT_EXPR;
1309 checkstring = 1;
1310 lop = 1;
1311 break;
1312
1313 case INTRINSIC_GE:
f47957c7 1314 case INTRINSIC_GE_OS:
4ee9c684 1315 code = GE_EXPR;
1316 checkstring = 1;
1317 lop = 1;
1318 break;
1319
1320 case INTRINSIC_LT:
f47957c7 1321 case INTRINSIC_LT_OS:
4ee9c684 1322 code = LT_EXPR;
1323 checkstring = 1;
1324 lop = 1;
1325 break;
1326
1327 case INTRINSIC_LE:
f47957c7 1328 case INTRINSIC_LE_OS:
4ee9c684 1329 code = LE_EXPR;
1330 checkstring = 1;
1331 lop = 1;
1332 break;
1333
1334 case INTRINSIC_USER:
1335 case INTRINSIC_ASSIGN:
1336 /* These should be converted into function calls by the frontend. */
22d678e8 1337 gcc_unreachable ();
4ee9c684 1338
1339 default:
1340 fatal_error ("Unknown intrinsic op");
1341 return;
1342 }
1343
f888a3fb 1344 /* The only exception to this is **, which is handled separately anyway. */
9b773341 1345 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
4ee9c684 1346
9b773341 1347 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
4ee9c684 1348 checkstring = 0;
1349
1350 /* lhs */
1351 gfc_init_se (&lse, se);
9b773341 1352 gfc_conv_expr (&lse, expr->value.op.op1);
4ee9c684 1353 gfc_add_block_to_block (&se->pre, &lse.pre);
1354
1355 /* rhs */
1356 gfc_init_se (&rse, se);
9b773341 1357 gfc_conv_expr (&rse, expr->value.op.op2);
4ee9c684 1358 gfc_add_block_to_block (&se->pre, &rse.pre);
1359
4ee9c684 1360 if (checkstring)
1361 {
1362 gfc_conv_string_parameter (&lse);
1363 gfc_conv_string_parameter (&rse);
4ee9c684 1364
77100724 1365 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
40b806de 1366 rse.string_length, rse.expr,
1367 expr->value.op.op1->ts.kind);
57e3c827 1368 rse.expr = build_int_cst (TREE_TYPE (lse.expr), 0);
77100724 1369 gfc_add_block_to_block (&lse.post, &rse.post);
4ee9c684 1370 }
1371
1372 type = gfc_typenode_for_spec (&expr->ts);
1373
1374 if (lop)
1375 {
1376 /* The result of logical ops is always boolean_type_node. */
f20cadb1 1377 tmp = fold_build2 (code, boolean_type_node, lse.expr, rse.expr);
4ee9c684 1378 se->expr = convert (type, tmp);
1379 }
1380 else
318c9b27 1381 se->expr = fold_build2 (code, type, lse.expr, rse.expr);
4ee9c684 1382
4ee9c684 1383 /* Add the post blocks. */
1384 gfc_add_block_to_block (&se->post, &rse.post);
1385 gfc_add_block_to_block (&se->post, &lse.post);
1386}
1387
77100724 1388/* If a string's length is one, we convert it to a single character. */
1389
1390static tree
b44437b9 1391string_to_single_character (tree len, tree str, int kind)
77100724 1392{
1393 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
1394
1395 if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1
b44437b9 1396 && TREE_INT_CST_HIGH (len) == 0)
77100724 1397 {
b44437b9 1398 str = fold_convert (gfc_get_pchar_type (kind), str);
389dd41b 1399 return build_fold_indirect_ref_loc (input_location,
1400 str);
77100724 1401 }
1402
1403 return NULL_TREE;
1404}
1405
4c47c8b7 1406
1407void
1408gfc_conv_scalar_char_value (gfc_symbol *sym, gfc_se *se, gfc_expr **expr)
1409{
1410
1411 if (sym->backend_decl)
1412 {
1413 /* This becomes the nominal_type in
1414 function.c:assign_parm_find_data_types. */
1415 TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
1416 /* This becomes the passed_type in
1417 function.c:assign_parm_find_data_types. C promotes char to
1418 integer for argument passing. */
1419 DECL_ARG_TYPE (sym->backend_decl) = unsigned_type_node;
1420
1421 DECL_BY_REFERENCE (sym->backend_decl) = 0;
1422 }
1423
1424 if (expr != NULL)
1425 {
1426 /* If we have a constant character expression, make it into an
1427 integer. */
1428 if ((*expr)->expr_type == EXPR_CONSTANT)
1429 {
1430 gfc_typespec ts;
52179f31 1431 gfc_clear_ts (&ts);
4c47c8b7 1432
1433 *expr = gfc_int_expr ((int)(*expr)->value.character.string[0]);
1434 if ((*expr)->ts.kind != gfc_c_int_kind)
1435 {
1436 /* The expr needs to be compatible with a C int. If the
1437 conversion fails, then the 2 causes an ICE. */
1438 ts.type = BT_INTEGER;
1439 ts.kind = gfc_c_int_kind;
1440 gfc_convert_type (*expr, &ts, 2);
1441 }
1442 }
1443 else if (se != NULL && (*expr)->expr_type == EXPR_VARIABLE)
1444 {
1445 if ((*expr)->ref == NULL)
1446 {
b44437b9 1447 se->expr = string_to_single_character
4c47c8b7 1448 (build_int_cst (integer_type_node, 1),
b44437b9 1449 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
4c47c8b7 1450 gfc_get_symbol_decl
b44437b9 1451 ((*expr)->symtree->n.sym)),
1452 (*expr)->ts.kind);
4c47c8b7 1453 }
1454 else
1455 {
1456 gfc_conv_variable (se, *expr);
b44437b9 1457 se->expr = string_to_single_character
4c47c8b7 1458 (build_int_cst (integer_type_node, 1),
b44437b9 1459 gfc_build_addr_expr (gfc_get_pchar_type ((*expr)->ts.kind),
1460 se->expr),
1461 (*expr)->ts.kind);
4c47c8b7 1462 }
1463 }
1464 }
1465}
1466
1467
77100724 1468/* Compare two strings. If they are all single characters, the result is the
1469 subtraction of them. Otherwise, we build a library call. */
1470
1471tree
40b806de 1472gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2, int kind)
77100724 1473{
1474 tree sc1;
1475 tree sc2;
77100724 1476 tree tmp;
1477
1478 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
1479 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
1480
b44437b9 1481 sc1 = string_to_single_character (len1, str1, kind);
1482 sc2 = string_to_single_character (len2, str2, kind);
77100724 1483
77100724 1484 if (sc1 != NULL_TREE && sc2 != NULL_TREE)
1485 {
40b806de 1486 /* Deal with single character specially. */
f20cadb1 1487 sc1 = fold_convert (integer_type_node, sc1);
1488 sc2 = fold_convert (integer_type_node, sc2);
1489 tmp = fold_build2 (MINUS_EXPR, integer_type_node, sc1, sc2);
77100724 1490 }
40b806de 1491 else
1492 {
1493 /* Build a call for the comparison. */
1494 tree fndecl;
1495
1496 if (kind == 1)
1497 fndecl = gfor_fndecl_compare_string;
1498 else if (kind == 4)
1499 fndecl = gfor_fndecl_compare_string_char4;
1500 else
1501 gcc_unreachable ();
1502
389dd41b 1503 tmp = build_call_expr_loc (input_location,
1504 fndecl, 4, len1, str1, len2, str2);
40b806de 1505 }
1506
77100724 1507 return tmp;
1508}
f888a3fb 1509
0fd53ac9 1510
1511/* Return the backend_decl for a procedure pointer component. */
1512
1513static tree
1514get_proc_ptr_comp (gfc_expr *e)
1515{
1516 gfc_se comp_se;
1517 gfc_expr *e2;
1518 gfc_init_se (&comp_se, NULL);
1519 e2 = gfc_copy_expr (e);
1520 e2->expr_type = EXPR_VARIABLE;
1521 gfc_conv_expr (&comp_se, e2);
39f3dea0 1522 gfc_free_expr (e2);
0fd53ac9 1523 return build_fold_addr_expr_loc (input_location, comp_se.expr);
1524}
1525
1526
d94c1385 1527/* Select a class typebound procedure at runtime. */
1528static void
1529select_class_proc (gfc_se *se, gfc_class_esym_list *elist,
f3f303c6 1530 tree declared, gfc_expr *expr)
d94c1385 1531{
1532 tree end_label;
1533 tree label;
1534 tree tmp;
1535 tree vindex;
1536 stmtblock_t body;
1537 gfc_class_esym_list *next_elist, *tmp_elist;
f3f303c6 1538 gfc_se tmpse;
d94c1385 1539
f3f303c6 1540 /* Convert the vindex expression. */
1541 gfc_init_se (&tmpse, NULL);
1542 gfc_conv_expr (&tmpse, elist->vindex);
1543 gfc_add_block_to_block (&se->pre, &tmpse.pre);
1544 vindex = gfc_evaluate_now (tmpse.expr, &se->pre);
1545 gfc_add_block_to_block (&se->post, &tmpse.post);
d94c1385 1546
f3f303c6 1547 /* Fix the function type to be that of the declared type method. */
d94c1385 1548 declared = gfc_create_var (TREE_TYPE (declared), "method");
1549
1550 end_label = gfc_build_label_decl (NULL_TREE);
1551
1552 gfc_init_block (&body);
1553
1554 /* Go through the list of extensions. */
1555 for (; elist; elist = next_elist)
1556 {
1557 /* This case has already been added. */
1558 if (elist->derived == NULL)
1559 goto free_elist;
1560
1561 /* Run through the chain picking up all the cases that call the
1562 same procedure. */
1563 tmp_elist = elist;
1564 for (; elist; elist = elist->next)
1565 {
1566 tree cval;
1567
1568 if (elist->esym != tmp_elist->esym)
1569 continue;
1570
1571 cval = build_int_cst (TREE_TYPE (vindex),
1572 elist->derived->vindex);
1573 /* Build a label for the vindex value. */
1574 label = gfc_build_label_decl (NULL_TREE);
1575 tmp = fold_build3 (CASE_LABEL_EXPR, void_type_node,
1576 cval, NULL_TREE, label);
1577 gfc_add_expr_to_block (&body, tmp);
1578
1579 /* Null the reference the derived type so that this case is
1580 not used again. */
1581 elist->derived = NULL;
1582 }
1583
1584 elist = tmp_elist;
1585
1586 /* Get a pointer to the procedure, */
1587 tmp = gfc_get_symbol_decl (elist->esym);
1588 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1589 {
1590 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1591 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1592 }
1593
1594 /* Assign the pointer to the appropriate procedure. */
1595 gfc_add_modify (&body, declared,
1596 fold_convert (TREE_TYPE (declared), tmp));
1597
1598 /* Break to the end of the construct. */
1599 tmp = build1_v (GOTO_EXPR, end_label);
1600 gfc_add_expr_to_block (&body, tmp);
1601
1602 /* Free the elists as we go; freeing them in gfc_free_expr causes
1603 segfaults because it occurs too early and too often. */
1604 free_elist:
1605 next_elist = elist->next;
f3f303c6 1606 if (elist->vindex)
1607 gfc_free_expr (elist->vindex);
d94c1385 1608 gfc_free (elist);
1609 elist = NULL;
1610 }
1611
1612 /* Default is an error. */
1613 label = gfc_build_label_decl (NULL_TREE);
1614 tmp = fold_build3 (CASE_LABEL_EXPR, void_type_node,
1615 NULL_TREE, NULL_TREE, label);
1616 gfc_add_expr_to_block (&body, tmp);
f3f303c6 1617 tmp = gfc_trans_runtime_error (true, &expr->where,
d94c1385 1618 "internal error: bad vindex in dynamic dispatch");
1619 gfc_add_expr_to_block (&body, tmp);
1620
1621 /* Write the switch expression. */
1622 tmp = gfc_finish_block (&body);
1623 tmp = build3_v (SWITCH_EXPR, vindex, tmp, NULL_TREE);
1624 gfc_add_expr_to_block (&se->pre, tmp);
1625
1626 tmp = build1_v (LABEL_EXPR, end_label);
1627 gfc_add_expr_to_block (&se->pre, tmp);
1628
1629 se->expr = declared;
1630 return;
1631}
1632
1633
4ee9c684 1634static void
64e93293 1635conv_function_val (gfc_se * se, gfc_symbol * sym, gfc_expr * expr)
4ee9c684 1636{
1637 tree tmp;
1638
d94c1385 1639 if (expr && expr->symtree
1640 && expr->value.function.class_esym)
1641 {
1642 if (!sym->backend_decl)
1643 sym->backend_decl = gfc_get_extern_function_decl (sym);
1644
1645 tmp = sym->backend_decl;
1646
1647 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1648 {
1649 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1650 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1651 }
1652
1653 select_class_proc (se, expr->value.function.class_esym,
f3f303c6 1654 tmp, expr);
d94c1385 1655 return;
1656 }
1657
ff70e443 1658 if (gfc_is_proc_ptr_comp (expr, NULL))
0fd53ac9 1659 tmp = get_proc_ptr_comp (expr);
64e93293 1660 else if (sym->attr.dummy)
4ee9c684 1661 {
1662 tmp = gfc_get_symbol_decl (sym);
cad0ddcf 1663 if (sym->attr.proc_pointer)
389dd41b 1664 tmp = build_fold_indirect_ref_loc (input_location,
1665 tmp);
22d678e8 1666 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
4ee9c684 1667 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
4ee9c684 1668 }
1669 else
1670 {
1671 if (!sym->backend_decl)
1672 sym->backend_decl = gfc_get_extern_function_decl (sym);
1673
1674 tmp = sym->backend_decl;
623416e8 1675
a7c1e504 1676 if (sym->attr.cray_pointee)
623416e8 1677 {
1678 /* TODO - make the cray pointee a pointer to a procedure,
1679 assign the pointer to it and use it for the call. This
1680 will do for now! */
1681 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
1682 gfc_get_symbol_decl (sym->cp_pointer));
1683 tmp = gfc_evaluate_now (tmp, &se->pre);
1684 }
1685
08569428 1686 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1687 {
1688 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
86f2ad37 1689 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
08569428 1690 }
1691 }
1692 se->expr = tmp;
1693}
1694
1695
08569428 1696/* Initialize MAPPING. */
1697
f45a476e 1698void
08569428 1699gfc_init_interface_mapping (gfc_interface_mapping * mapping)
1700{
1701 mapping->syms = NULL;
1702 mapping->charlens = NULL;
1703}
1704
1705
1706/* Free all memory held by MAPPING (but not MAPPING itself). */
1707
f45a476e 1708void
08569428 1709gfc_free_interface_mapping (gfc_interface_mapping * mapping)
1710{
1711 gfc_interface_sym_mapping *sym;
1712 gfc_interface_sym_mapping *nextsym;
1713 gfc_charlen *cl;
1714 gfc_charlen *nextcl;
1715
1716 for (sym = mapping->syms; sym; sym = nextsym)
1717 {
1718 nextsym = sym->next;
c71c6bca 1719 sym->new_sym->n.sym->formal = NULL;
c1977dbe 1720 gfc_free_symbol (sym->new_sym->n.sym);
fd149f95 1721 gfc_free_expr (sym->expr);
c1977dbe 1722 gfc_free (sym->new_sym);
08569428 1723 gfc_free (sym);
1724 }
1725 for (cl = mapping->charlens; cl; cl = nextcl)
1726 {
1727 nextcl = cl->next;
1728 gfc_free_expr (cl->length);
1729 gfc_free (cl);
4ee9c684 1730 }
1731}
1732
1733
08569428 1734/* Return a copy of gfc_charlen CL. Add the returned structure to
1735 MAPPING so that it will be freed by gfc_free_interface_mapping. */
1736
1737static gfc_charlen *
1738gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
1739 gfc_charlen * cl)
1740{
c1977dbe 1741 gfc_charlen *new_charlen;
08569428 1742
c1977dbe 1743 new_charlen = gfc_get_charlen ();
1744 new_charlen->next = mapping->charlens;
1745 new_charlen->length = gfc_copy_expr (cl->length);
08569428 1746
c1977dbe 1747 mapping->charlens = new_charlen;
1748 return new_charlen;
08569428 1749}
1750
1751
1752/* A subroutine of gfc_add_interface_mapping. Return a descriptorless
1753 array variable that can be used as the actual argument for dummy
1754 argument SYM. Add any initialization code to BLOCK. PACKED is as
1755 for gfc_get_nodesc_array_type and DATA points to the first element
1756 in the passed array. */
1757
1758static tree
1759gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
3d8dea5a 1760 gfc_packed packed, tree data)
08569428 1761{
1762 tree type;
1763 tree var;
1764
1765 type = gfc_typenode_for_spec (&sym->ts);
e1b3b79b 1766 type = gfc_get_nodesc_array_type (type, sym->as, packed,
1767 !sym->attr.target && !sym->attr.pointer
1768 && !sym->attr.proc_pointer);
08569428 1769
5e8cd291 1770 var = gfc_create_var (type, "ifm");
75a70cf9 1771 gfc_add_modify (block, var, fold_convert (type, data));
08569428 1772
1773 return var;
1774}
1775
1776
1777/* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
1778 and offset of descriptorless array type TYPE given that it has the same
1779 size as DESC. Add any set-up code to BLOCK. */
1780
1781static void
1782gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
1783{
1784 int n;
1785 tree dim;
1786 tree offset;
1787 tree tmp;
1788
1789 offset = gfc_index_zero_node;
1790 for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
1791 {
926b9532 1792 dim = gfc_rank_cst[n];
08569428 1793 GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
926b9532 1794 if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
1795 {
1796 GFC_TYPE_ARRAY_LBOUND (type, n)
6b1a9af3 1797 = gfc_conv_descriptor_lbound_get (desc, dim);
926b9532 1798 GFC_TYPE_ARRAY_UBOUND (type, n)
6b1a9af3 1799 = gfc_conv_descriptor_ubound_get (desc, dim);
926b9532 1800 }
1801 else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
08569428 1802 {
08569428 1803 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
6b1a9af3 1804 gfc_conv_descriptor_ubound_get (desc, dim),
1805 gfc_conv_descriptor_lbound_get (desc, dim));
08569428 1806 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1807 GFC_TYPE_ARRAY_LBOUND (type, n),
1808 tmp);
1809 tmp = gfc_evaluate_now (tmp, block);
1810 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
1811 }
1812 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
1813 GFC_TYPE_ARRAY_LBOUND (type, n),
1814 GFC_TYPE_ARRAY_STRIDE (type, n));
1815 offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
1816 }
1817 offset = gfc_evaluate_now (offset, block);
1818 GFC_TYPE_ARRAY_OFFSET (type) = offset;
1819}
1820
1821
1822/* Extend MAPPING so that it maps dummy argument SYM to the value stored
1823 in SE. The caller may still use se->expr and se->string_length after
1824 calling this function. */
1825
f45a476e 1826void
08569428 1827gfc_add_interface_mapping (gfc_interface_mapping * mapping,
fd149f95 1828 gfc_symbol * sym, gfc_se * se,
1829 gfc_expr *expr)
08569428 1830{
1831 gfc_interface_sym_mapping *sm;
1832 tree desc;
1833 tree tmp;
1834 tree value;
1835 gfc_symbol *new_sym;
1836 gfc_symtree *root;
1837 gfc_symtree *new_symtree;
1838
1839 /* Create a new symbol to represent the actual argument. */
1840 new_sym = gfc_new_symbol (sym->name, NULL);
1841 new_sym->ts = sym->ts;
079aab8b 1842 new_sym->as = gfc_copy_array_spec (sym->as);
08569428 1843 new_sym->attr.referenced = 1;
1844 new_sym->attr.dimension = sym->attr.dimension;
1845 new_sym->attr.pointer = sym->attr.pointer;
76845580 1846 new_sym->attr.allocatable = sym->attr.allocatable;
08569428 1847 new_sym->attr.flavor = sym->attr.flavor;
fd149f95 1848 new_sym->attr.function = sym->attr.function;
08569428 1849
dc1a7e64 1850 /* Ensure that the interface is available and that
1851 descriptors are passed for array actual arguments. */
1852 if (sym->attr.flavor == FL_PROCEDURE)
1853 {
c71c6bca 1854 new_sym->formal = expr->symtree->n.sym->formal;
dc1a7e64 1855 new_sym->attr.always_explicit
1856 = expr->symtree->n.sym->attr.always_explicit;
1857 }
1858
08569428 1859 /* Create a fake symtree for it. */
1860 root = NULL;
1861 new_symtree = gfc_new_symtree (&root, sym->name);
1862 new_symtree->n.sym = new_sym;
1863 gcc_assert (new_symtree == root);
1864
1865 /* Create a dummy->actual mapping. */
48d8ad5a 1866 sm = XCNEW (gfc_interface_sym_mapping);
08569428 1867 sm->next = mapping->syms;
1868 sm->old = sym;
c1977dbe 1869 sm->new_sym = new_symtree;
fd149f95 1870 sm->expr = gfc_copy_expr (expr);
08569428 1871 mapping->syms = sm;
1872
1873 /* Stabilize the argument's value. */
fd149f95 1874 if (!sym->attr.function && se)
1875 se->expr = gfc_evaluate_now (se->expr, &se->pre);
08569428 1876
1877 if (sym->ts.type == BT_CHARACTER)
1878 {
1879 /* Create a copy of the dummy argument's length. */
eeebe20b 1880 new_sym->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.u.cl);
1881 sm->expr->ts.u.cl = new_sym->ts.u.cl;
08569428 1882
1883 /* If the length is specified as "*", record the length that
1884 the caller is passing. We should use the callee's length
1885 in all other cases. */
eeebe20b 1886 if (!new_sym->ts.u.cl->length && se)
08569428 1887 {
1888 se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
eeebe20b 1889 new_sym->ts.u.cl->backend_decl = se->string_length;
08569428 1890 }
1891 }
1892
fd149f95 1893 if (!se)
1894 return;
1895
08569428 1896 /* Use the passed value as-is if the argument is a function. */
1897 if (sym->attr.flavor == FL_PROCEDURE)
1898 value = se->expr;
1899
1900 /* If the argument is either a string or a pointer to a string,
1901 convert it to a boundless character type. */
1902 else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
1903 {
1904 tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
1905 tmp = build_pointer_type (tmp);
1906 if (sym->attr.pointer)
389dd41b 1907 value = build_fold_indirect_ref_loc (input_location,
1908 se->expr);
e042ae37 1909 else
1910 value = se->expr;
1911 value = fold_convert (tmp, value);
08569428 1912 }
1913
76845580 1914 /* If the argument is a scalar, a pointer to an array or an allocatable,
1915 dereference it. */
1916 else if (!sym->attr.dimension || sym->attr.pointer || sym->attr.allocatable)
389dd41b 1917 value = build_fold_indirect_ref_loc (input_location,
1918 se->expr);
e3071e62 1919
1920 /* For character(*), use the actual argument's descriptor. */
eeebe20b 1921 else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.u.cl->length)
389dd41b 1922 value = build_fold_indirect_ref_loc (input_location,
1923 se->expr);
08569428 1924
1925 /* If the argument is an array descriptor, use it to determine
1926 information about the actual argument's shape. */
1927 else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
1928 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
1929 {
1930 /* Get the actual argument's descriptor. */
389dd41b 1931 desc = build_fold_indirect_ref_loc (input_location,
1932 se->expr);
08569428 1933
1934 /* Create the replacement variable. */
1935 tmp = gfc_conv_descriptor_data_get (desc);
3d8dea5a 1936 value = gfc_get_interface_mapping_array (&se->pre, sym,
1937 PACKED_NO, tmp);
08569428 1938
1939 /* Use DESC to work out the upper bounds, strides and offset. */
1940 gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
1941 }
1942 else
1943 /* Otherwise we have a packed array. */
3d8dea5a 1944 value = gfc_get_interface_mapping_array (&se->pre, sym,
1945 PACKED_FULL, se->expr);
08569428 1946
1947 new_sym->backend_decl = value;
1948}
1949
1950
1951/* Called once all dummy argument mappings have been added to MAPPING,
1952 but before the mapping is used to evaluate expressions. Pre-evaluate
1953 the length of each argument, adding any initialization code to PRE and
1954 any finalization code to POST. */
1955
f45a476e 1956void
08569428 1957gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
1958 stmtblock_t * pre, stmtblock_t * post)
1959{
1960 gfc_interface_sym_mapping *sym;
1961 gfc_expr *expr;
1962 gfc_se se;
1963
1964 for (sym = mapping->syms; sym; sym = sym->next)
c1977dbe 1965 if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
eeebe20b 1966 && !sym->new_sym->n.sym->ts.u.cl->backend_decl)
08569428 1967 {
eeebe20b 1968 expr = sym->new_sym->n.sym->ts.u.cl->length;
08569428 1969 gfc_apply_interface_mapping_to_expr (mapping, expr);
1970 gfc_init_se (&se, NULL);
1971 gfc_conv_expr (&se, expr);
12f4af3f 1972 se.expr = fold_convert (gfc_charlen_type_node, se.expr);
08569428 1973 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1974 gfc_add_block_to_block (pre, &se.pre);
1975 gfc_add_block_to_block (post, &se.post);
1976
eeebe20b 1977 sym->new_sym->n.sym->ts.u.cl->backend_decl = se.expr;
08569428 1978 }
1979}
1980
1981
1982/* Like gfc_apply_interface_mapping_to_expr, but applied to
1983 constructor C. */
1984
1985static void
1986gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
1987 gfc_constructor * c)
1988{
1989 for (; c; c = c->next)
1990 {
1991 gfc_apply_interface_mapping_to_expr (mapping, c->expr);
1992 if (c->iterator)
1993 {
1994 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
1995 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
1996 gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
1997 }
1998 }
1999}
2000
2001
2002/* Like gfc_apply_interface_mapping_to_expr, but applied to
2003 reference REF. */
2004
2005static void
2006gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
2007 gfc_ref * ref)
2008{
2009 int n;
2010
2011 for (; ref; ref = ref->next)
2012 switch (ref->type)
2013 {
2014 case REF_ARRAY:
2015 for (n = 0; n < ref->u.ar.dimen; n++)
2016 {
2017 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
2018 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
2019 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
2020 }
2021 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.offset);
2022 break;
2023
2024 case REF_COMPONENT:
2025 break;
2026
2027 case REF_SUBSTRING:
2028 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
2029 gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
2030 break;
2031 }
2032}
2033
2034
fd149f95 2035/* Convert intrinsic function calls into result expressions. */
079aab8b 2036
fd149f95 2037static bool
079aab8b 2038gfc_map_intrinsic_function (gfc_expr *expr, gfc_interface_mapping *mapping)
fd149f95 2039{
2040 gfc_symbol *sym;
2041 gfc_expr *new_expr;
2042 gfc_expr *arg1;
2043 gfc_expr *arg2;
2044 int d, dup;
2045
2046 arg1 = expr->value.function.actual->expr;
2047 if (expr->value.function.actual->next)
2048 arg2 = expr->value.function.actual->next->expr;
2049 else
2050 arg2 = NULL;
2051
079aab8b 2052 sym = arg1->symtree->n.sym;
fd149f95 2053
2054 if (sym->attr.dummy)
2055 return false;
2056
2057 new_expr = NULL;
2058
2059 switch (expr->value.function.isym->id)
2060 {
2061 case GFC_ISYM_LEN:
2062 /* TODO figure out why this condition is necessary. */
2063 if (sym->attr.function
eeebe20b 2064 && (arg1->ts.u.cl->length == NULL
2065 || (arg1->ts.u.cl->length->expr_type != EXPR_CONSTANT
2066 && arg1->ts.u.cl->length->expr_type != EXPR_VARIABLE)))
fd149f95 2067 return false;
2068
eeebe20b 2069 new_expr = gfc_copy_expr (arg1->ts.u.cl->length);
fd149f95 2070 break;
2071
2072 case GFC_ISYM_SIZE:
2073 if (!sym->as)
2074 return false;
2075
2076 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
2077 {
2078 dup = mpz_get_si (arg2->value.integer);
2079 d = dup - 1;
2080 }
2081 else
2082 {
2083 dup = sym->as->rank;
2084 d = 0;
2085 }
2086
2087 for (; d < dup; d++)
2088 {
2089 gfc_expr *tmp;
079aab8b 2090
2091 if (!sym->as->upper[d] || !sym->as->lower[d])
2092 {
2093 gfc_free_expr (new_expr);
2094 return false;
2095 }
2096
fd149f95 2097 tmp = gfc_add (gfc_copy_expr (sym->as->upper[d]), gfc_int_expr (1));
2098 tmp = gfc_subtract (tmp, gfc_copy_expr (sym->as->lower[d]));
2099 if (new_expr)
2100 new_expr = gfc_multiply (new_expr, tmp);
2101 else
2102 new_expr = tmp;
2103 }
2104 break;
2105
2106 case GFC_ISYM_LBOUND:
2107 case GFC_ISYM_UBOUND:
2108 /* TODO These implementations of lbound and ubound do not limit if
2109 the size < 0, according to F95's 13.14.53 and 13.14.113. */
2110
2111 if (!sym->as)
2112 return false;
2113
2114 if (arg2 && arg2->expr_type == EXPR_CONSTANT)
2115 d = mpz_get_si (arg2->value.integer) - 1;
2116 else
2117 /* TODO: If the need arises, this could produce an array of
2118 ubound/lbounds. */
2119 gcc_unreachable ();
2120
2121 if (expr->value.function.isym->id == GFC_ISYM_LBOUND)
079aab8b 2122 {
2123 if (sym->as->lower[d])
2124 new_expr = gfc_copy_expr (sym->as->lower[d]);
2125 }
fd149f95 2126 else
079aab8b 2127 {
2128 if (sym->as->upper[d])
2129 new_expr = gfc_copy_expr (sym->as->upper[d]);
2130 }
fd149f95 2131 break;
2132
2133 default:
2134 break;
2135 }
2136
2137 gfc_apply_interface_mapping_to_expr (mapping, new_expr);
2138 if (!new_expr)
2139 return false;
2140
2141 gfc_replace_expr (expr, new_expr);
2142 return true;
2143}
2144
2145
2146static void
2147gfc_map_fcn_formal_to_actual (gfc_expr *expr, gfc_expr *map_expr,
2148 gfc_interface_mapping * mapping)
2149{
2150 gfc_formal_arglist *f;
2151 gfc_actual_arglist *actual;
2152
2153 actual = expr->value.function.actual;
2154 f = map_expr->symtree->n.sym->formal;
2155
2156 for (; f && actual; f = f->next, actual = actual->next)
2157 {
2158 if (!actual->expr)
2159 continue;
2160
2161 gfc_add_interface_mapping (mapping, f->sym, NULL, actual->expr);
2162 }
2163
2164 if (map_expr->symtree->n.sym->attr.dimension)
2165 {
2166 int d;
2167 gfc_array_spec *as;
2168
2169 as = gfc_copy_array_spec (map_expr->symtree->n.sym->as);
2170
2171 for (d = 0; d < as->rank; d++)
2172 {
2173 gfc_apply_interface_mapping_to_expr (mapping, as->lower[d]);
2174 gfc_apply_interface_mapping_to_expr (mapping, as->upper[d]);
2175 }
2176
2177 expr->value.function.esym->as = as;
2178 }
2179
2180 if (map_expr->symtree->n.sym->ts.type == BT_CHARACTER)
2181 {
eeebe20b 2182 expr->value.function.esym->ts.u.cl->length
2183 = gfc_copy_expr (map_expr->symtree->n.sym->ts.u.cl->length);
fd149f95 2184
2185 gfc_apply_interface_mapping_to_expr (mapping,
eeebe20b 2186 expr->value.function.esym->ts.u.cl->length);
fd149f95 2187 }
2188}
2189
2190
08569428 2191/* EXPR is a copy of an expression that appeared in the interface
2192 associated with MAPPING. Walk it recursively looking for references to
2193 dummy arguments that MAPPING maps to actual arguments. Replace each such
2194 reference with a reference to the associated actual argument. */
2195
fd149f95 2196static void
08569428 2197gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
2198 gfc_expr * expr)
2199{
2200 gfc_interface_sym_mapping *sym;
2201 gfc_actual_arglist *actual;
2202
2203 if (!expr)
fd149f95 2204 return;
08569428 2205
2206 /* Copying an expression does not copy its length, so do that here. */
eeebe20b 2207 if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
08569428 2208 {
eeebe20b 2209 expr->ts.u.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.u.cl);
2210 gfc_apply_interface_mapping_to_expr (mapping, expr->ts.u.cl->length);
08569428 2211 }
2212
2213 /* Apply the mapping to any references. */
2214 gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
2215
2216 /* ...and to the expression's symbol, if it has one. */
fd149f95 2217 /* TODO Find out why the condition on expr->symtree had to be moved into
69b1505f 2218 the loop rather than being outside it, as originally. */
fd149f95 2219 for (sym = mapping->syms; sym; sym = sym->next)
2220 if (expr->symtree && sym->old == expr->symtree->n.sym)
2221 {
c1977dbe 2222 if (sym->new_sym->n.sym->backend_decl)
2223 expr->symtree = sym->new_sym;
fd149f95 2224 else if (sym->expr)
2225 gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
2226 }
08569428 2227
fd149f95 2228 /* ...and to subexpressions in expr->value. */
08569428 2229 switch (expr->expr_type)
2230 {
2231 case EXPR_VARIABLE:
2232 case EXPR_CONSTANT:
2233 case EXPR_NULL:
2234 case EXPR_SUBSTRING:
2235 break;
2236
2237 case EXPR_OP:
2238 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
2239 gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
2240 break;
2241
2242 case EXPR_FUNCTION:
fd149f95 2243 for (actual = expr->value.function.actual; actual; actual = actual->next)
2244 gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
2245
7f8c8ede 2246 if (expr->value.function.esym == NULL
7f7ca309 2247 && expr->value.function.isym != NULL
fd149f95 2248 && expr->value.function.actual->expr->symtree
2249 && gfc_map_intrinsic_function (expr, mapping))
2250 break;
7f7ca309 2251
08569428 2252 for (sym = mapping->syms; sym; sym = sym->next)
2253 if (sym->old == expr->value.function.esym)
fd149f95 2254 {
c1977dbe 2255 expr->value.function.esym = sym->new_sym->n.sym;
fd149f95 2256 gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
c1977dbe 2257 expr->value.function.esym->result = sym->new_sym->n.sym;
fd149f95 2258 }
08569428 2259 break;
2260
2261 case EXPR_ARRAY:
2262 case EXPR_STRUCTURE:
2263 gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
2264 break;
930fe1de 2265
2266 case EXPR_COMPCALL:
64e93293 2267 case EXPR_PPC:
930fe1de 2268 gcc_unreachable ();
2269 break;
08569428 2270 }
fd149f95 2271
2272 return;
08569428 2273}
2274
2275
2276/* Evaluate interface expression EXPR using MAPPING. Store the result
2277 in SE. */
2278
f45a476e 2279void
08569428 2280gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
2281 gfc_se * se, gfc_expr * expr)
2282{
2283 expr = gfc_copy_expr (expr);
2284 gfc_apply_interface_mapping_to_expr (mapping, expr);
2285 gfc_conv_expr (se, expr);
2286 se->expr = gfc_evaluate_now (se->expr, &se->pre);
2287 gfc_free_expr (expr);
2288}
2289
1033248c 2290
858f9894 2291/* Returns a reference to a temporary array into which a component of
2292 an actual argument derived type array is copied and then returned
1033248c 2293 after the function call. */
2ecf364f 2294void
1033248c 2295gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr,
2296 int g77, sym_intent intent)
858f9894 2297{
2298 gfc_se lse;
2299 gfc_se rse;
2300 gfc_ss *lss;
2301 gfc_ss *rss;
2302 gfc_loopinfo loop;
2303 gfc_loopinfo loop2;
2304 gfc_ss_info *info;
2305 tree offset;
2306 tree tmp_index;
2307 tree tmp;
2308 tree base_type;
2309 stmtblock_t body;
2310 int n;
2311
2312 gcc_assert (expr->expr_type == EXPR_VARIABLE);
2313
2314 gfc_init_se (&lse, NULL);
2315 gfc_init_se (&rse, NULL);
2316
2317 /* Walk the argument expression. */
2318 rss = gfc_walk_expr (expr);
2319
2320 gcc_assert (rss != gfc_ss_terminator);
2321
2322 /* Initialize the scalarizer. */
2323 gfc_init_loopinfo (&loop);
2324 gfc_add_ss_to_loop (&loop, rss);
2325
2326 /* Calculate the bounds of the scalarization. */
2327 gfc_conv_ss_startstride (&loop);
2328
2329 /* Build an ss for the temporary. */
eeebe20b 2330 if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
2331 gfc_conv_string_length (expr->ts.u.cl, expr, &parmse->pre);
0ff77f4e 2332
858f9894 2333 base_type = gfc_typenode_for_spec (&expr->ts);
2334 if (GFC_ARRAY_TYPE_P (base_type)
2335 || GFC_DESCRIPTOR_TYPE_P (base_type))
2336 base_type = gfc_get_element_type (base_type);
2337
2338 loop.temp_ss = gfc_get_ss ();;
2339 loop.temp_ss->type = GFC_SS_TEMP;
2340 loop.temp_ss->data.temp.type = base_type;
2341
2342 if (expr->ts.type == BT_CHARACTER)
eeebe20b 2343 loop.temp_ss->string_length = expr->ts.u.cl->backend_decl;
0ff77f4e 2344 else
2345 loop.temp_ss->string_length = NULL;
858f9894 2346
0ff77f4e 2347 parmse->string_length = loop.temp_ss->string_length;
858f9894 2348 loop.temp_ss->data.temp.dimen = loop.dimen;
2349 loop.temp_ss->next = gfc_ss_terminator;
2350
2351 /* Associate the SS with the loop. */
2352 gfc_add_ss_to_loop (&loop, loop.temp_ss);
2353
2354 /* Setup the scalarizing loops. */
92f4d1c4 2355 gfc_conv_loop_setup (&loop, &expr->where);
858f9894 2356
2357 /* Pass the temporary descriptor back to the caller. */
2358 info = &loop.temp_ss->data.info;
2359 parmse->expr = info->descriptor;
2360
2361 /* Setup the gfc_se structures. */
2362 gfc_copy_loopinfo_to_se (&lse, &loop);
2363 gfc_copy_loopinfo_to_se (&rse, &loop);
2364
2365 rse.ss = rss;
2366 lse.ss = loop.temp_ss;
2367 gfc_mark_ss_chain_used (rss, 1);
2368 gfc_mark_ss_chain_used (loop.temp_ss, 1);
2369
2370 /* Start the scalarized loop body. */
2371 gfc_start_scalarized_body (&loop, &body);
2372
2373 /* Translate the expression. */
2374 gfc_conv_expr (&rse, expr);
2375
2376 gfc_conv_tmp_array_ref (&lse);
2377 gfc_advance_se_ss_chain (&lse);
2378
35d9c496 2379 if (intent != INTENT_OUT)
2380 {
2294b616 2381 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, false);
35d9c496 2382 gfc_add_expr_to_block (&body, tmp);
2383 gcc_assert (rse.ss == gfc_ss_terminator);
2384 gfc_trans_scalarizing_loops (&loop, &body);
2385 }
e8325fb3 2386 else
2387 {
54ad1b4d 2388 /* Make sure that the temporary declaration survives by merging
2389 all the loop declarations into the current context. */
2390 for (n = 0; n < loop.dimen; n++)
2391 {
2392 gfc_merge_block_scope (&body);
2393 body = loop.code[loop.order[n]];
2394 }
2395 gfc_merge_block_scope (&body);
e8325fb3 2396 }
858f9894 2397
2398 /* Add the post block after the second loop, so that any
2399 freeing of allocated memory is done at the right time. */
2400 gfc_add_block_to_block (&parmse->pre, &loop.pre);
2401
2402 /**********Copy the temporary back again.*********/
2403
2404 gfc_init_se (&lse, NULL);
2405 gfc_init_se (&rse, NULL);
2406
2407 /* Walk the argument expression. */
2408 lss = gfc_walk_expr (expr);
2409 rse.ss = loop.temp_ss;
2410 lse.ss = lss;
2411
2412 /* Initialize the scalarizer. */
2413 gfc_init_loopinfo (&loop2);
2414 gfc_add_ss_to_loop (&loop2, lss);
2415
2416 /* Calculate the bounds of the scalarization. */
2417 gfc_conv_ss_startstride (&loop2);
2418
2419 /* Setup the scalarizing loops. */
92f4d1c4 2420 gfc_conv_loop_setup (&loop2, &expr->where);
858f9894 2421
2422 gfc_copy_loopinfo_to_se (&lse, &loop2);
2423 gfc_copy_loopinfo_to_se (&rse, &loop2);
2424
2425 gfc_mark_ss_chain_used (lss, 1);
2426 gfc_mark_ss_chain_used (loop.temp_ss, 1);
2427
2428 /* Declare the variable to hold the temporary offset and start the
2429 scalarized loop body. */
2430 offset = gfc_create_var (gfc_array_index_type, NULL);
2431 gfc_start_scalarized_body (&loop2, &body);
2432
2433 /* Build the offsets for the temporary from the loop variables. The
2434 temporary array has lbounds of zero and strides of one in all
2435 dimensions, so this is very simple. The offset is only computed
2436 outside the innermost loop, so the overall transfer could be
179eba08 2437 optimized further. */
858f9894 2438 info = &rse.ss->data.info;
2439
2440 tmp_index = gfc_index_zero_node;
2441 for (n = info->dimen - 1; n > 0; n--)
2442 {
2443 tree tmp_str;
2444 tmp = rse.loop->loopvar[n];
2445 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2446 tmp, rse.loop->from[n]);
2447 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2448 tmp, tmp_index);
2449
2450 tmp_str = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2451 rse.loop->to[n-1], rse.loop->from[n-1]);
2452 tmp_str = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2453 tmp_str, gfc_index_one_node);
2454
2455 tmp_index = fold_build2 (MULT_EXPR, gfc_array_index_type,
2456 tmp, tmp_str);
2457 }
2458
2459 tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2460 tmp_index, rse.loop->from[0]);
75a70cf9 2461 gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
858f9894 2462
2463 tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2464 rse.loop->loopvar[0], offset);
2465
2466 /* Now use the offset for the reference. */
389dd41b 2467 tmp = build_fold_indirect_ref_loc (input_location,
2468 info->data);
1033248c 2469 rse.expr = gfc_build_array_ref (tmp, tmp_index, NULL);
858f9894 2470
2471 if (expr->ts.type == BT_CHARACTER)
eeebe20b 2472 rse.string_length = expr->ts.u.cl->backend_decl;
858f9894 2473
2474 gfc_conv_expr (&lse, expr);
2475
2476 gcc_assert (lse.ss == gfc_ss_terminator);
2477
2294b616 2478 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, false);
858f9894 2479 gfc_add_expr_to_block (&body, tmp);
2480
2481 /* Generate the copying loops. */
2482 gfc_trans_scalarizing_loops (&loop2, &body);
2483
2484 /* Wrap the whole thing up by adding the second loop to the post-block
35d9c496 2485 and following it by the post-block of the first loop. In this way,
858f9894 2486 if the temporary needs freeing, it is done after use! */
35d9c496 2487 if (intent != INTENT_IN)
2488 {
2489 gfc_add_block_to_block (&parmse->post, &loop2.pre);
2490 gfc_add_block_to_block (&parmse->post, &loop2.post);
2491 }
858f9894 2492
2493 gfc_add_block_to_block (&parmse->post, &loop.post);
2494
2495 gfc_cleanup_loop (&loop);
2496 gfc_cleanup_loop (&loop2);
2497
2498 /* Pass the string length to the argument expression. */
2499 if (expr->ts.type == BT_CHARACTER)
eeebe20b 2500 parmse->string_length = expr->ts.u.cl->backend_decl;
858f9894 2501
2502 /* We want either the address for the data or the address of the descriptor,
2503 depending on the mode of passing array arguments. */
2504 if (g77)
2505 parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
2506 else
86f2ad37 2507 parmse->expr = gfc_build_addr_expr (NULL_TREE, parmse->expr);
858f9894 2508
2509 return;
2510}
2511
08569428 2512
8d7cdc4d 2513/* Generate the code for argument list functions. */
2514
2515static void
2516conv_arglist_function (gfc_se *se, gfc_expr *expr, const char *name)
2517{
8d7cdc4d 2518 /* Pass by value for g77 %VAL(arg), pass the address
2519 indirectly for %LOC, else by reference. Thus %REF
2520 is a "do-nothing" and %LOC is the same as an F95
2521 pointer. */
2522 if (strncmp (name, "%VAL", 4) == 0)
b8128c7b 2523 gfc_conv_expr (se, expr);
8d7cdc4d 2524 else if (strncmp (name, "%LOC", 4) == 0)
2525 {
2526 gfc_conv_expr_reference (se, expr);
2527 se->expr = gfc_build_addr_expr (NULL, se->expr);
2528 }
2529 else if (strncmp (name, "%REF", 4) == 0)
2530 gfc_conv_expr_reference (se, expr);
2531 else
2532 gfc_error ("Unknown argument list function at %L", &expr->where);
2533}
2534
2535
4ee9c684 2536/* Generate code for a procedure call. Note can return se->post != NULL.
079d21d5 2537 If se->direct_byref is set then se->expr contains the return parameter.
64e93293 2538 Return nonzero, if the call has alternate specifiers.
2539 'expr' is only needed for procedure pointer components. */
4ee9c684 2540
079d21d5 2541int
64e93293 2542gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
2543 gfc_actual_arglist * arg, gfc_expr * expr,
2544 tree append_args)
4ee9c684 2545{
08569428 2546 gfc_interface_mapping mapping;
4ee9c684 2547 tree arglist;
08569428 2548 tree retargs;
4ee9c684 2549 tree tmp;
2550 tree fntype;
2551 gfc_se parmse;
2552 gfc_ss *argss;
2553 gfc_ss_info *info;
2554 int byref;
2294b616 2555 int parm_kind;
4ee9c684 2556 tree type;
2557 tree var;
2558 tree len;
2559 tree stringargs;
2560 gfc_formal_arglist *formal;
079d21d5 2561 int has_alternate_specifier = 0;
08569428 2562 bool need_interface_mapping;
d4ef6f9d 2563 bool callee_alloc;
08569428 2564 gfc_typespec ts;
2565 gfc_charlen cl;
bd24f178 2566 gfc_expr *e;
2567 gfc_symbol *fsym;
10b07432 2568 stmtblock_t post;
2294b616 2569 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
85d1c108 2570 gfc_component *comp = NULL;
4ee9c684 2571
2572 arglist = NULL_TREE;
08569428 2573 retargs = NULL_TREE;
4ee9c684 2574 stringargs = NULL_TREE;
2575 var = NULL_TREE;
2576 len = NULL_TREE;
52179f31 2577 gfc_clear_ts (&ts);
4ee9c684 2578
513a2ff6 2579 if (sym->from_intmod == INTMOD_ISO_C_BINDING)
43c61a0d 2580 {
513a2ff6 2581 if (sym->intmod_sym_id == ISOCBINDING_LOC)
43c61a0d 2582 {
513a2ff6 2583 if (arg->expr->rank == 0)
2584 gfc_conv_expr_reference (se, arg->expr);
2585 else
2586 {
2587 int f;
2588 /* This is really the actual arg because no formal arglist is
2589 created for C_LOC. */
2590 fsym = arg->expr->symtree->n.sym;
2591
2592 /* We should want it to do g77 calling convention. */
2593 f = (fsym != NULL)
2594 && !(fsym->attr.pointer || fsym->attr.allocatable)
2595 && fsym->as->type != AS_ASSUMED_SHAPE;
2596 f = f || !sym->attr.always_explicit;
2597
2598 argss = gfc_walk_expr (arg->expr);
bc56d052 2599 gfc_conv_array_parameter (se, arg->expr, argss, f,
2600 NULL, NULL, NULL);
513a2ff6 2601 }
2602
6b956f99 2603 /* TODO -- the following two lines shouldn't be necessary, but
2604 they're removed a bug is exposed later in the codepath.
2605 This is workaround was thus introduced, but will have to be
2606 removed; please see PR 35150 for details about the issue. */
2607 se->expr = convert (pvoid_type_node, se->expr);
2608 se->expr = gfc_evaluate_now (se->expr, &se->pre);
2609
513a2ff6 2610 return 0;
43c61a0d 2611 }
513a2ff6 2612 else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC)
43c61a0d 2613 {
eeebe20b 2614 arg->expr->ts.type = sym->ts.u.derived->ts.type;
2615 arg->expr->ts.f90_type = sym->ts.u.derived->ts.f90_type;
2616 arg->expr->ts.kind = sym->ts.u.derived->ts.kind;
513a2ff6 2617 gfc_conv_expr_reference (se, arg->expr);
2618
2cbaf336 2619 return 0;
2620 }
2621 else if ((sym->intmod_sym_id == ISOCBINDING_F_POINTER
2622 && arg->next->expr->rank == 0)
2623 || sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)
2624 {
2625 /* Convert c_f_pointer if fptr is a scalar
2626 and convert c_f_procpointer. */
2627 gfc_se cptrse;
2628 gfc_se fptrse;
2629
2630 gfc_init_se (&cptrse, NULL);
2631 gfc_conv_expr (&cptrse, arg->expr);
2632 gfc_add_block_to_block (&se->pre, &cptrse.pre);
2633 gfc_add_block_to_block (&se->post, &cptrse.post);
2634
2635 gfc_init_se (&fptrse, NULL);
64e93293 2636 if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
ff70e443 2637 || gfc_is_proc_ptr_comp (arg->next->expr, NULL))
64e93293 2638 fptrse.want_pointer = 1;
2cbaf336 2639
2640 gfc_conv_expr (&fptrse, arg->next->expr);
2641 gfc_add_block_to_block (&se->pre, &fptrse.pre);
2642 gfc_add_block_to_block (&se->post, &fptrse.post);
19b7a51e 2643
2644 if (arg->next->expr->symtree->n.sym->attr.proc_pointer
2645 && arg->next->expr->symtree->n.sym->attr.dummy)
2646 fptrse.expr = build_fold_indirect_ref_loc (input_location,
2647 fptrse.expr);
2648
2649 se->expr = fold_build2 (MODIFY_EXPR, TREE_TYPE (fptrse.expr),
2650 fptrse.expr,
2651 fold_convert (TREE_TYPE (fptrse.expr),
2652 cptrse.expr));
2cbaf336 2653
32e8ed46 2654 return 0;
2655 }
2656 else if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
2657 {
2658 gfc_se arg1se;
2659 gfc_se arg2se;
2660
2661 /* Build the addr_expr for the first argument. The argument is
2662 already an *address* so we don't need to set want_pointer in
2663 the gfc_se. */
2664 gfc_init_se (&arg1se, NULL);
2665 gfc_conv_expr (&arg1se, arg->expr);
2666 gfc_add_block_to_block (&se->pre, &arg1se.pre);
2667 gfc_add_block_to_block (&se->post, &arg1se.post);
2668
2669 /* See if we were given two arguments. */
2670 if (arg->next == NULL)
2671 /* Only given one arg so generate a null and do a
2672 not-equal comparison against the first arg. */
f75d6b8a 2673 se->expr = fold_build2 (NE_EXPR, boolean_type_node, arg1se.expr,
2674 fold_convert (TREE_TYPE (arg1se.expr),
2675 null_pointer_node));
32e8ed46 2676 else
2677 {
2678 tree eq_expr;
2679 tree not_null_expr;
2680
2681 /* Given two arguments so build the arg2se from second arg. */
2682 gfc_init_se (&arg2se, NULL);
2683 gfc_conv_expr (&arg2se, arg->next->expr);
2684 gfc_add_block_to_block (&se->pre, &arg2se.pre);
2685 gfc_add_block_to_block (&se->post, &arg2se.post);
2686
2687 /* Generate test to compare that the two args are equal. */
f75d6b8a 2688 eq_expr = fold_build2 (EQ_EXPR, boolean_type_node,
2689 arg1se.expr, arg2se.expr);
32e8ed46 2690 /* Generate test to ensure that the first arg is not null. */
f75d6b8a 2691 not_null_expr = fold_build2 (NE_EXPR, boolean_type_node,
2692 arg1se.expr, null_pointer_node);
32e8ed46 2693
2694 /* Finally, the generated test must check that both arg1 is not
2695 NULL and that it is equal to the second arg. */
f75d6b8a 2696 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2697 not_null_expr, eq_expr);
32e8ed46 2698 }
2699
513a2ff6 2700 return 0;
43c61a0d 2701 }
43c61a0d 2702 }
ff70e443 2703
2704 gfc_is_proc_ptr_comp (expr, &comp);
2705
4ee9c684 2706 if (se->ss != NULL)
2707 {
2708 if (!sym->attr.elemental)
2709 {
22d678e8 2710 gcc_assert (se->ss->type == GFC_SS_FUNCTION);
4ee9c684 2711 if (se->ss->useflags)
2712 {
ff70e443 2713 gcc_assert ((!comp && gfc_return_by_reference (sym)
2714 && sym->result->attr.dimension)
2715 || (comp && comp->attr.dimension));
22d678e8 2716 gcc_assert (se->loop != NULL);
4ee9c684 2717
2718 /* Access the previously obtained result. */
2719 gfc_conv_tmp_array_ref (se);
2720 gfc_advance_se_ss_chain (se);
079d21d5 2721 return 0;
4ee9c684 2722 }
2723 }
2724 info = &se->ss->data.info;
2725 }
2726 else
2727 info = NULL;
2728
10b07432 2729 gfc_init_block (&post);
08569428 2730 gfc_init_interface_mapping (&mapping);
1d84f30a 2731 if (!comp)
2732 {
2733 formal = sym->formal;
2734 need_interface_mapping = sym->attr.dimension ||
2735 (sym->ts.type == BT_CHARACTER
2736 && sym->ts.u.cl->length
2737 && sym->ts.u.cl->length->expr_type
2738 != EXPR_CONSTANT);
2739 }
452a3743 2740 else
1d84f30a 2741 {
2742 formal = comp->formal;
2743 need_interface_mapping = comp->attr.dimension ||
2744 (comp->ts.type == BT_CHARACTER
2745 && comp->ts.u.cl->length
2746 && comp->ts.u.cl->length->expr_type
2747 != EXPR_CONSTANT);
2748 }
2749
4ee9c684 2750 /* Evaluate the arguments. */
2751 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
2752 {
bd24f178 2753 e = arg->expr;
2754 fsym = formal ? formal->sym : NULL;
2294b616 2755 parm_kind = MISSING;
bd24f178 2756 if (e == NULL)
4ee9c684 2757 {
2758
2759 if (se->ignore_optional)
2760 {
2761 /* Some intrinsics have already been resolved to the correct
2762 parameters. */
2763 continue;
2764 }
2765 else if (arg->label)
2766 {
2767 has_alternate_specifier = 1;
2768 continue;
2769 }
2770 else
2771 {
2772 /* Pass a NULL pointer for an absent arg. */
2773 gfc_init_se (&parmse, NULL);
2774 parmse.expr = null_pointer_node;
0fe9e56f 2775 if (arg->missing_arg_type == BT_CHARACTER)
7d3075f6 2776 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
4ee9c684 2777 }
2778 }
1de1b1a9 2779 else if (fsym && fsym->ts.type == BT_CLASS
2780 && e->ts.type == BT_DERIVED)
2781 {
2782 tree data;
2783 tree vindex;
39f3dea0 2784 tree size;
1de1b1a9 2785
2786 /* The derived type needs to be converted to a temporary
2787 CLASS object. */
2788 gfc_init_se (&parmse, se);
2789 type = gfc_typenode_for_spec (&fsym->ts);
2790 var = gfc_create_var (type, "class");
2791
2792 /* Get the components. */
2793 tmp = fsym->ts.u.derived->components->backend_decl;
2794 data = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
2795 var, tmp, NULL_TREE);
2796 tmp = fsym->ts.u.derived->components->next->backend_decl;
2797 vindex = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
39f3dea0 2798 var, tmp, NULL_TREE);
2799 tmp = fsym->ts.u.derived->components->next->next->backend_decl;
2800 size = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
1de1b1a9 2801 var, tmp, NULL_TREE);
2802
2803 /* Set the vindex. */
39f3dea0 2804 tmp = build_int_cst (TREE_TYPE (vindex), e->ts.u.derived->vindex);
1de1b1a9 2805 gfc_add_modify (&parmse.pre, vindex, tmp);
2806
39f3dea0 2807 /* Set the size. */
2808 tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&e->ts));
2809 gfc_add_modify (&parmse.pre, size,
2810 fold_convert (TREE_TYPE (size), tmp));
2811
1de1b1a9 2812 /* Now set the data field. */
2813 argss = gfc_walk_expr (e);
2814 if (argss == gfc_ss_terminator)
2815 {
2816 gfc_conv_expr_reference (&parmse, e);
2817 tmp = fold_convert (TREE_TYPE (data),
2818 parmse.expr);
2819 gfc_add_modify (&parmse.pre, data, tmp);
2820 }
2821 else
2822 {
2823 gfc_conv_expr (&parmse, e);
2824 gfc_add_modify (&parmse.pre, data, parmse.expr);
2825 }
2826
2827 /* Pass the address of the class object. */
2828 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
2829 }
4ee9c684 2830 else if (se->ss && se->ss->useflags)
2831 {
2832 /* An elemental function inside a scalarized loop. */
2833 gfc_init_se (&parmse, se);
bd24f178 2834 gfc_conv_expr_reference (&parmse, e);
2294b616 2835 parm_kind = ELEMENTAL;
4ee9c684 2836 }
2837 else
2838 {
2839 /* A scalar or transformational function. */
2840 gfc_init_se (&parmse, NULL);
bd24f178 2841 argss = gfc_walk_expr (e);
4ee9c684 2842
2843 if (argss == gfc_ss_terminator)
c5d33754 2844 {
623416e8 2845 if (e->expr_type == EXPR_VARIABLE
2846 && e->symtree->n.sym->attr.cray_pointee
2847 && fsym && fsym->attr.flavor == FL_PROCEDURE)
2848 {
2849 /* The Cray pointer needs to be converted to a pointer to
2850 a type given by the expression. */
2851 gfc_conv_expr (&parmse, e);
2852 type = build_pointer_type (TREE_TYPE (parmse.expr));
2853 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
2854 parmse.expr = convert (type, tmp);
2855 }
2856 else if (fsym && fsym->attr.value)
8f6339b6 2857 {
4c47c8b7 2858 if (fsym->ts.type == BT_CHARACTER
2859 && fsym->ts.is_c_interop
2860 && fsym->ns->proc_name != NULL
2861 && fsym->ns->proc_name->attr.is_bind_c)
2862 {
2863 parmse.expr = NULL;
2864 gfc_conv_scalar_char_value (fsym, &parmse, &e);
2865 if (parmse.expr == NULL)
2866 gfc_conv_expr (&parmse, e);
2867 }
2868 else
2869 gfc_conv_expr (&parmse, e);
8f6339b6 2870 }
8d7cdc4d 2871 else if (arg->name && arg->name[0] == '%')
2872 /* Argument list functions %VAL, %LOC and %REF are signalled
2873 through arg->name. */
2874 conv_arglist_function (&parmse, arg->expr, arg->name);
7f7ca309 2875 else if ((e->expr_type == EXPR_FUNCTION)
7035e057 2876 && ((e->value.function.esym
2877 && e->value.function.esym->result->attr.pointer)
2878 || (!e->value.function.esym
2879 && e->symtree->n.sym->attr.pointer))
2880 && fsym && fsym->attr.target)
7f7ca309 2881 {
2882 gfc_conv_expr (&parmse, e);
86f2ad37 2883 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
7f7ca309 2884 }
eee4a6d8 2885 else if (e->expr_type == EXPR_FUNCTION
2886 && e->symtree->n.sym->result
0fd53ac9 2887 && e->symtree->n.sym->result != e->symtree->n.sym
eee4a6d8 2888 && e->symtree->n.sym->result->attr.proc_pointer)
2889 {
2890 /* Functions returning procedure pointers. */
2891 gfc_conv_expr (&parmse, e);
2892 if (fsym && fsym->attr.proc_pointer)
2893 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
2894 }
8f6339b6 2895 else
2896 {
2897 gfc_conv_expr_reference (&parmse, e);
5176859a 2898
2899 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
2900 allocated on entry, it must be deallocated. */
2901 if (fsym && fsym->attr.allocatable
2902 && fsym->attr.intent == INTENT_OUT)
2903 {
2904 stmtblock_t block;
2905
2906 gfc_init_block (&block);
2907 tmp = gfc_deallocate_with_status (parmse.expr, NULL_TREE,
2908 true, NULL);
2909 gfc_add_expr_to_block (&block, tmp);
2910 tmp = fold_build2 (MODIFY_EXPR, void_type_node,
2911 parmse.expr, null_pointer_node);
2912 gfc_add_expr_to_block (&block, tmp);
2913
2914 if (fsym->attr.optional
2915 && e->expr_type == EXPR_VARIABLE
2916 && e->symtree->n.sym->attr.optional)
2917 {
2918 tmp = fold_build3 (COND_EXPR, void_type_node,
2919 gfc_conv_expr_present (e->symtree->n.sym),
2920 gfc_finish_block (&block),
2921 build_empty_stmt (input_location));
2922 }
2923 else
2924 tmp = gfc_finish_block (&block);
2925
2926 gfc_add_expr_to_block (&se->pre, tmp);
2927 }
2928
cad0ddcf 2929 if (fsym && e->expr_type != EXPR_NULL
2930 && ((fsym->attr.pointer
2931 && fsym->attr.flavor != FL_PROCEDURE)
4651cfdd 2932 || (fsym->attr.proc_pointer
2933 && !(e->expr_type == EXPR_VARIABLE
cf046737 2934 && e->symtree->n.sym->attr.dummy))
0fd53ac9 2935 || (e->expr_type == EXPR_VARIABLE
5176859a 2936 && gfc_is_proc_ptr_comp (e, NULL))
2937 || fsym->attr.allocatable))
8f6339b6 2938 {
2939 /* Scalar pointer dummy args require an extra level of
2940 indirection. The null pointer already contains
2941 this level of indirection. */
2942 parm_kind = SCALAR_POINTER;
86f2ad37 2943 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
8f6339b6 2944 }
2945 }
2946 }
4ee9c684 2947 else
2948 {
7d19e94d 2949 /* If the procedure requires an explicit interface, the actual
2950 argument is passed according to the corresponding formal
2951 argument. If the corresponding formal argument is a POINTER,
2952 ALLOCATABLE or assumed shape, we do not use g77's calling
2953 convention, and pass the address of the array descriptor
2954 instead. Otherwise we use g77's calling convention. */
4ee9c684 2955 int f;
bd24f178 2956 f = (fsym != NULL)
2957 && !(fsym->attr.pointer || fsym->attr.allocatable)
2958 && fsym->as->type != AS_ASSUMED_SHAPE;
4ee9c684 2959 f = f || !sym->attr.always_explicit;
35d9c496 2960
bd24f178 2961 if (e->expr_type == EXPR_VARIABLE
1033248c 2962 && is_subref_array (e))
858f9894 2963 /* The actual argument is a component reference to an
2964 array of derived types. In this case, the argument
2965 is converted to a temporary, which is passed and then
2966 written back after the procedure call. */
1033248c 2967 gfc_conv_subref_array_arg (&parmse, e, f,
b8a51d79 2968 fsym ? fsym->attr.intent : INTENT_INOUT);
858f9894 2969 else
da6ffc6d 2970 gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
bc56d052 2971 sym->name, NULL);
ab19f982 2972
d99419eb 2973 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
2974 allocated on entry, it must be deallocated. */
2975 if (fsym && fsym->attr.allocatable
2976 && fsym->attr.intent == INTENT_OUT)
2977 {
2978 tmp = build_fold_indirect_ref_loc (input_location,
2979 parmse.expr);
2980 tmp = gfc_trans_dealloc_allocated (tmp);
2981 if (fsym->attr.optional
2982 && e->expr_type == EXPR_VARIABLE
2983 && e->symtree->n.sym->attr.optional)
2984 tmp = fold_build3 (COND_EXPR, void_type_node,
2985 gfc_conv_expr_present (e->symtree->n.sym),
2986 tmp, build_empty_stmt (input_location));
2987 gfc_add_expr_to_block (&se->pre, tmp);
2988 }
4ee9c684 2989 }
2990 }
2991
3d3b790d 2992 /* The case with fsym->attr.optional is that of a user subroutine
2993 with an interface indicating an optional argument. When we call
2994 an intrinsic subroutine, however, fsym is NULL, but we might still
2995 have an optional argument, so we proceed to the substitution
2996 just in case. */
2997 if (e && (fsym == NULL || fsym->attr.optional))
d45fced7 2998 {
3d3b790d 2999 /* If an optional argument is itself an optional dummy argument,
d99419eb 3000 check its presence and substitute a null if absent. This is
3001 only needed when passing an array to an elemental procedure
3002 as then array elements are accessed - or no NULL pointer is
3003 allowed and a "1" or "0" should be passed if not present.
b460b386 3004 When passing a non-array-descriptor full array to a
3005 non-array-descriptor dummy, no check is needed. For
3006 array-descriptor actual to array-descriptor dummy, see
3007 PR 41911 for why a check has to be inserted.
3008 fsym == NULL is checked as intrinsics required the descriptor
3009 but do not always set fsym. */
3d3b790d 3010 if (e->expr_type == EXPR_VARIABLE
d99419eb 3011 && e->symtree->n.sym->attr.optional
3012 && ((e->rank > 0 && sym->attr.elemental)
3013 || e->representation.length || e->ts.type == BT_CHARACTER
b460b386 3014 || (e->rank > 0
3015 && (fsym == NULL || fsym->as->type == AS_ASSUMED_SHAPE
3016 || fsym->as->type == AS_DEFERRED))))
2abe085f 3017 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
3018 e->representation.length);
3d3b790d 3019 }
3020
3021 if (fsym && e)
3022 {
3023 /* Obtain the character length of an assumed character length
3024 length procedure from the typespec. */
3025 if (fsym->ts.type == BT_CHARACTER
3026 && parmse.string_length == NULL_TREE
3027 && e->ts.type == BT_PROCEDURE
3028 && e->symtree->n.sym->ts.type == BT_CHARACTER
eeebe20b 3029 && e->symtree->n.sym->ts.u.cl->length != NULL
3030 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
d45fced7 3031 {
eeebe20b 3032 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
3033 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
d45fced7 3034 }
d45fced7 3035 }
08569428 3036
079d3acc 3037 if (fsym && need_interface_mapping && e)
fd149f95 3038 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
3d3b790d 3039
4ee9c684 3040 gfc_add_block_to_block (&se->pre, &parmse.pre);
10b07432 3041 gfc_add_block_to_block (&post, &parmse.post);
4ee9c684 3042
2294b616 3043 /* Allocated allocatable components of derived types must be
8714fc76 3044 deallocated for non-variable scalars. Non-variable arrays are
3045 dealt with in trans-array.c(gfc_conv_array_parameter). */
2294b616 3046 if (e && e->ts.type == BT_DERIVED
eeebe20b 3047 && e->ts.u.derived->attr.alloc_comp
cc2f46ba 3048 && !(e->symtree && e->symtree->n.sym->attr.pointer)
8714fc76 3049 && (e->expr_type != EXPR_VARIABLE && !e->rank))
2294b616 3050 {
3051 int parm_rank;
389dd41b 3052 tmp = build_fold_indirect_ref_loc (input_location,
3053 parmse.expr);
2294b616 3054 parm_rank = e->rank;
3055 switch (parm_kind)
3056 {
3057 case (ELEMENTAL):
3058 case (SCALAR):
3059 parm_rank = 0;
3060 break;
3061
3062 case (SCALAR_POINTER):
389dd41b 3063 tmp = build_fold_indirect_ref_loc (input_location,
3064 tmp);
2294b616 3065 break;
2294b616 3066 }
3067
e5387fb9 3068 if (e->expr_type == EXPR_OP
3069 && e->value.op.op == INTRINSIC_PARENTHESES
3070 && e->value.op.op1->expr_type == EXPR_VARIABLE)
3071 {
3072 tree local_tmp;
3073 local_tmp = gfc_evaluate_now (tmp, &se->pre);
eeebe20b 3074 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
e5387fb9 3075 gfc_add_expr_to_block (&se->post, local_tmp);
3076 }
3077
eeebe20b 3078 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
e5387fb9 3079
8714fc76 3080 gfc_add_expr_to_block (&se->post, tmp);
2294b616 3081 }
3082
91cf6ba3 3083 /* Add argument checking of passing an unallocated/NULL actual to
3084 a nonallocatable/nonpointer dummy. */
3085
40474135 3086 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
91cf6ba3 3087 {
40474135 3088 symbol_attribute *attr;
91cf6ba3 3089 char *msg;
3090 tree cond;
3091
3092 if (e->expr_type == EXPR_VARIABLE)
40474135 3093 attr = &e->symtree->n.sym->attr;
91cf6ba3 3094 else if (e->expr_type == EXPR_FUNCTION)
40474135 3095 {
3096 /* For intrinsic functions, the gfc_attr are not available. */
3097 if (e->symtree->n.sym->attr.generic && e->value.function.isym)
3098 goto end_pointer_check;
91cf6ba3 3099
40474135 3100 if (e->symtree->n.sym->attr.generic)
3101 attr = &e->value.function.esym->attr;
3102 else
3103 attr = &e->symtree->n.sym->result->attr;
3104 }
91cf6ba3 3105 else
3106 goto end_pointer_check;
3107
40474135 3108 if (attr->optional)
3109 {
3110 /* If the actual argument is an optional pointer/allocatable and
3111 the formal argument takes an nonpointer optional value,
3112 it is invalid to pass a non-present argument on, even
3113 though there is no technical reason for this in gfortran.
3114 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
3115 tree present, nullptr, type;
3116
3117 if (attr->allocatable
3118 && (fsym == NULL || !fsym->attr.allocatable))
3119 asprintf (&msg, "Allocatable actual argument '%s' is not "
3120 "allocated or not present", e->symtree->n.sym->name);
3121 else if (attr->pointer
3122 && (fsym == NULL || !fsym->attr.pointer))
3123 asprintf (&msg, "Pointer actual argument '%s' is not "
3124 "associated or not present",
3125 e->symtree->n.sym->name);
3126 else if (attr->proc_pointer
3127 && (fsym == NULL || !fsym->attr.proc_pointer))
3128 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3129 "associated or not present",
3130 e->symtree->n.sym->name);
3131 else
3132 goto end_pointer_check;
3133
3134 present = gfc_conv_expr_present (e->symtree->n.sym);
3135 type = TREE_TYPE (present);
3136 present = fold_build2 (EQ_EXPR, boolean_type_node, present,
3137 fold_convert (type, null_pointer_node));
3138 type = TREE_TYPE (parmse.expr);
3139 nullptr = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3140 fold_convert (type, null_pointer_node));
3141 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node,
3142 present, nullptr);
3143 }
3144 else
3145 {
3146 if (attr->allocatable
3147 && (fsym == NULL || !fsym->attr.allocatable))
3148 asprintf (&msg, "Allocatable actual argument '%s' is not "
3149 "allocated", e->symtree->n.sym->name);
3150 else if (attr->pointer
3151 && (fsym == NULL || !fsym->attr.pointer))
3152 asprintf (&msg, "Pointer actual argument '%s' is not "
3153 "associated", e->symtree->n.sym->name);
3154 else if (attr->proc_pointer
3155 && (fsym == NULL || !fsym->attr.proc_pointer))
3156 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3157 "associated", e->symtree->n.sym->name);
3158 else
3159 goto end_pointer_check;
3160
3161
3162 cond = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3163 fold_convert (TREE_TYPE (parmse.expr),
3164 null_pointer_node));
3165 }
91cf6ba3 3166
3167 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
3168 msg);
3169 gfc_free (msg);
3170 }
3171 end_pointer_check:
3172
3173
7b3423b9 3174 /* Character strings are passed as two parameters, a length and a
465e4a95 3175 pointer - except for Bind(c) which only passes the pointer. */
3176 if (parmse.string_length != NULL_TREE && !sym->attr.is_bind_c)
4ee9c684 3177 stringargs = gfc_chainon_list (stringargs, parmse.string_length);
3178
3179 arglist = gfc_chainon_list (arglist, parmse.expr);
3180 }
08569428 3181 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
3182
1d84f30a 3183 if (comp)
3184 ts = comp->ts;
3185 else
3186 ts = sym->ts;
3187
ff2093c8 3188 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
3189 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
3190 else if (ts.type == BT_CHARACTER)
08569428 3191 {
1d84f30a 3192 if (ts.u.cl->length == NULL)
5e8cd291 3193 {
3194 /* Assumed character length results are not allowed by 5.1.1.5 of the
3195 standard and are trapped in resolve.c; except in the case of SPREAD
cce7ac71 3196 (and other intrinsics?) and dummy functions. In the case of SPREAD,
3197 we take the character length of the first argument for the result.
3198 For dummies, we have to look through the formal argument list for
3199 this function and use the character length found there.*/
3200 if (!sym->attr.dummy)
3201 cl.backend_decl = TREE_VALUE (stringargs);
3202 else
3203 {
3204 formal = sym->ns->proc_name->formal;
3205 for (; formal; formal = formal->next)
3206 if (strcmp (formal->sym->name, sym->name) == 0)
eeebe20b 3207 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
cce7ac71 3208 }
3209 }
5176859a 3210 else
cce7ac71 3211 {
a0ab480a 3212 tree tmp;
3213
5e8cd291 3214 /* Calculate the length of the returned string. */
3215 gfc_init_se (&parmse, NULL);
3216 if (need_interface_mapping)
1d84f30a 3217 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
5e8cd291 3218 else
1d84f30a 3219 gfc_conv_expr (&parmse, ts.u.cl->length);
5e8cd291 3220 gfc_add_block_to_block (&se->pre, &parmse.pre);
3221 gfc_add_block_to_block (&se->post, &parmse.post);
a0ab480a 3222
3223 tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
3224 tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
3225 build_int_cst (gfc_charlen_type_node, 0));
3226 cl.backend_decl = tmp;
5e8cd291 3227 }
08569428 3228
3229 /* Set up a charlen structure for it. */
3230 cl.next = NULL;
3231 cl.length = NULL;
eeebe20b 3232 ts.u.cl = &cl;
08569428 3233
3234 len = cl.backend_decl;
3235 }
08569428 3236
1d84f30a 3237 byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
85d1c108 3238 || (!comp && gfc_return_by_reference (sym));
08569428 3239 if (byref)
3240 {
3241 if (se->direct_byref)
67135eee 3242 {
69b1505f 3243 /* Sometimes, too much indirection can be applied; e.g. for
67135eee 3244 function_result = array_valued_recursive_function. */
3245 if (TREE_TYPE (TREE_TYPE (se->expr))
3246 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
3247 && GFC_DESCRIPTOR_TYPE_P
3248 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
389dd41b 3249 se->expr = build_fold_indirect_ref_loc (input_location,
3250 se->expr);
67135eee 3251
3252 retargs = gfc_chainon_list (retargs, se->expr);
3253 }
ff70e443 3254 else if (comp && comp->attr.dimension)
3255 {
3256 gcc_assert (se->loop && info);
3257
3258 /* Set the type of the array. */
3259 tmp = gfc_typenode_for_spec (&comp->ts);
3260 info->dimen = se->loop->dimen;
3261
3262 /* Evaluate the bounds of the result, if known. */
3263 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
3264
3265 /* Create a temporary to store the result. In case the function
3266 returns a pointer, the temporary will be a shallow copy and
3267 mustn't be deallocated. */
3268 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
3269 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
3270 NULL_TREE, false, !comp->attr.pointer,
3271 callee_alloc, &se->ss->expr->where);
3272
3273 /* Pass the temporary as the first argument. */
3274 tmp = info->descriptor;
3275 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3276 retargs = gfc_chainon_list (retargs, tmp);
3277 }
1d84f30a 3278 else if (!comp && sym->result->attr.dimension)
08569428 3279 {
3280 gcc_assert (se->loop && info);
3281
3282 /* Set the type of the array. */
3283 tmp = gfc_typenode_for_spec (&ts);
3284 info->dimen = se->loop->dimen;
3285
f45a476e 3286 /* Evaluate the bounds of the result, if known. */
3287 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
3288
d4ef6f9d 3289 /* Create a temporary to store the result. In case the function
3290 returns a pointer, the temporary will be a shallow copy and
3291 mustn't be deallocated. */
3292 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
3293 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
7a2a9daf 3294 NULL_TREE, false, !sym->attr.pointer,
3295 callee_alloc, &se->ss->expr->where);
08569428 3296
08569428 3297 /* Pass the temporary as the first argument. */
3298 tmp = info->descriptor;
86f2ad37 3299 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
08569428 3300 retargs = gfc_chainon_list (retargs, tmp);
3301 }
3302 else if (ts.type == BT_CHARACTER)
3303 {
3304 /* Pass the string length. */
eeebe20b 3305 type = gfc_get_character_type (ts.kind, ts.u.cl);
08569428 3306 type = build_pointer_type (type);
3307
3308 /* Return an address to a char[0:len-1]* temporary for
3309 character pointers. */
1d84f30a 3310 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3311 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
08569428 3312 {
eeaa887f 3313 var = gfc_create_var (type, "pstr");
08569428 3314
3315 /* Provide an address expression for the function arguments. */
86f2ad37 3316 var = gfc_build_addr_expr (NULL_TREE, var);
08569428 3317 }
3318 else
3319 var = gfc_conv_string_tmp (se, type, len);
3320
3321 retargs = gfc_chainon_list (retargs, var);
3322 }
3323 else
3324 {
3325 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
3326
3327 type = gfc_get_complex_type (ts.kind);
86f2ad37 3328 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
08569428 3329 retargs = gfc_chainon_list (retargs, var);
3330 }
3331
3332 /* Add the string length to the argument list. */
3333 if (ts.type == BT_CHARACTER)
3334 retargs = gfc_chainon_list (retargs, len);
3335 }
f45a476e 3336 gfc_free_interface_mapping (&mapping);
08569428 3337
3338 /* Add the return arguments. */
3339 arglist = chainon (retargs, arglist);
4ee9c684 3340
3341 /* Add the hidden string length parameters to the arguments. */
3342 arglist = chainon (arglist, stringargs);
3343
4e8e57b0 3344 /* We may want to append extra arguments here. This is used e.g. for
3345 calls to libgfortran_matmul_??, which need extra information. */
3346 if (append_args != NULL_TREE)
3347 arglist = chainon (arglist, append_args);
3348
4ee9c684 3349 /* Generate the actual call. */
64e93293 3350 conv_function_val (se, sym, expr);
57dd95f2 3351
4ee9c684 3352 /* If there are alternate return labels, function type should be
079d21d5 3353 integer. Can't modify the type in place though, since it can be shared
57dd95f2 3354 with other functions. For dummy arguments, the typing is done to
3355 to this result, even if it has to be repeated for each call. */
079d21d5 3356 if (has_alternate_specifier
3357 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
3358 {
57dd95f2 3359 if (!sym->attr.dummy)
3360 {
3361 TREE_TYPE (sym->backend_decl)
3362 = build_function_type (integer_type_node,
3363 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
86f2ad37 3364 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
57dd95f2 3365 }
3366 else
3367 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
079d21d5 3368 }
4ee9c684 3369
3370 fntype = TREE_TYPE (TREE_TYPE (se->expr));
c2f47e15 3371 se->expr = build_call_list (TREE_TYPE (fntype), se->expr, arglist);
4ee9c684 3372
fa069004 3373 /* If we have a pointer function, but we don't want a pointer, e.g.
3374 something like
3375 x = f()
3376 where f is pointer valued, we have to dereference the result. */
64e93293 3377 if (!se->want_pointer && !byref && sym->attr.pointer
ff70e443 3378 && !gfc_is_proc_ptr_comp (expr, NULL))
389dd41b 3379 se->expr = build_fold_indirect_ref_loc (input_location,
3380 se->expr);
fa069004 3381
bdaed7d2 3382 /* f2c calling conventions require a scalar default real function to
3383 return a double precision result. Convert this back to default
3384 real. We only care about the cases that can happen in Fortran 77.
3385 */
3386 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
3387 && sym->ts.kind == gfc_default_real_kind
3388 && !sym->attr.always_explicit)
3389 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
3390
f888a3fb 3391 /* A pure function may still have side-effects - it may modify its
3392 parameters. */
4ee9c684 3393 TREE_SIDE_EFFECTS (se->expr) = 1;
3394#if 0
3395 if (!sym->attr.pure)
3396 TREE_SIDE_EFFECTS (se->expr) = 1;
3397#endif
3398
4396343e 3399 if (byref)
4ee9c684 3400 {
4396343e 3401 /* Add the function call to the pre chain. There is no expression. */
4ee9c684 3402 gfc_add_expr_to_block (&se->pre, se->expr);
4396343e 3403 se->expr = NULL_TREE;
4ee9c684 3404
4396343e 3405 if (!se->direct_byref)
4ee9c684 3406 {
ff70e443 3407 if (sym->attr.dimension || (comp && comp->attr.dimension))
4ee9c684 3408 {
ad8ed98e 3409 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
4396343e 3410 {
3411 /* Check the data pointer hasn't been modified. This would
3412 happen in a function returning a pointer. */
94be45c9 3413 tmp = gfc_conv_descriptor_data_get (info->descriptor);
0eed5ee7 3414 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3415 tmp, info->data);
da6ffc6d 3416 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
3417 gfc_msg_fault);
4396343e 3418 }
3419 se->expr = info->descriptor;
bf7e666b 3420 /* Bundle in the string length. */
3421 se->string_length = len;
4ee9c684 3422 }
1d84f30a 3423 else if (ts.type == BT_CHARACTER)
544c333b 3424 {
bf7e666b 3425 /* Dereference for character pointer results. */
1d84f30a 3426 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3427 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
3428 se->expr = build_fold_indirect_ref_loc (input_location, var);
544c333b 3429 else
bf7e666b 3430 se->expr = var;
3431
4396343e 3432 se->string_length = len;
3433 }
3434 else
bdaed7d2 3435 {
1d84f30a 3436 gcc_assert (ts.type == BT_COMPLEX && gfc_option.flag_f2c);
3437 se->expr = build_fold_indirect_ref_loc (input_location, var);
bdaed7d2 3438 }
4ee9c684 3439 }
4ee9c684 3440 }
079d21d5 3441
10b07432 3442 /* Follow the function call with the argument post block. */
3443 if (byref)
3444 gfc_add_block_to_block (&se->pre, &post);
3445 else
3446 gfc_add_block_to_block (&se->post, &post);
3447
079d21d5 3448 return has_alternate_specifier;
4ee9c684 3449}
3450
3451
b44437b9 3452/* Fill a character string with spaces. */
3453
3454static tree
3455fill_with_spaces (tree start, tree type, tree size)
3456{
3457 stmtblock_t block, loop;
3458 tree i, el, exit_label, cond, tmp;
3459
3460 /* For a simple char type, we can call memset(). */
3461 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
389dd41b 3462 return build_call_expr_loc (input_location,
3463 built_in_decls[BUILT_IN_MEMSET], 3, start,
b44437b9 3464 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
3465 lang_hooks.to_target_charset (' ')),
3466 size);
3467
3468 /* Otherwise, we use a loop:
3469 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
3470 *el = (type) ' ';
3471 */
3472
3473 /* Initialize variables. */
3474 gfc_init_block (&block);
3475 i = gfc_create_var (sizetype, "i");
75a70cf9 3476 gfc_add_modify (&block, i, fold_convert (sizetype, size));
b44437b9 3477 el = gfc_create_var (build_pointer_type (type), "el");
75a70cf9 3478 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
b44437b9 3479 exit_label = gfc_build_label_decl (NULL_TREE);
3480 TREE_USED (exit_label) = 1;
3481
3482
3483 /* Loop body. */
3484 gfc_init_block (&loop);
3485
3486 /* Exit condition. */
3487 cond = fold_build2 (LE_EXPR, boolean_type_node, i,
3488 fold_convert (sizetype, integer_zero_node));
3489 tmp = build1_v (GOTO_EXPR, exit_label);
e60a6f7b 3490 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3491 build_empty_stmt (input_location));
b44437b9 3492 gfc_add_expr_to_block (&loop, tmp);
3493
3494 /* Assignment. */
75a70cf9 3495 gfc_add_modify (&loop, fold_build1 (INDIRECT_REF, type, el),
b44437b9 3496 build_int_cst (type,
3497 lang_hooks.to_target_charset (' ')));
3498
3499 /* Increment loop variables. */
75a70cf9 3500 gfc_add_modify (&loop, i, fold_build2 (MINUS_EXPR, sizetype, i,
b44437b9 3501 TYPE_SIZE_UNIT (type)));
75a70cf9 3502 gfc_add_modify (&loop, el, fold_build2 (POINTER_PLUS_EXPR,
b44437b9 3503 TREE_TYPE (el), el,
3504 TYPE_SIZE_UNIT (type)));
3505
3506 /* Making the loop... actually loop! */
3507 tmp = gfc_finish_block (&loop);
3508 tmp = build1_v (LOOP_EXPR, tmp);
3509 gfc_add_expr_to_block (&block, tmp);
3510
3511 /* The exit label. */
3512 tmp = build1_v (LABEL_EXPR, exit_label);
3513 gfc_add_expr_to_block (&block, tmp);
3514
3515
3516 return gfc_finish_block (&block);
3517}
3518
3519
dbe60343 3520/* Generate code to copy a string. */
3521
88137677 3522void
72038310 3523gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
b44437b9 3524 int dkind, tree slength, tree src, int skind)
dbe60343 3525{
72038310 3526 tree tmp, dlen, slen;
77100724 3527 tree dsc;
3528 tree ssc;
2810b378 3529 tree cond;
59b9dcbd 3530 tree cond2;
3531 tree tmp2;
3532 tree tmp3;
3533 tree tmp4;
b44437b9 3534 tree chartype;
59b9dcbd 3535 stmtblock_t tempblock;
77100724 3536
b44437b9 3537 gcc_assert (dkind == skind);
3538
891beb95 3539 if (slength != NULL_TREE)
3540 {
3541 slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
b44437b9 3542 ssc = string_to_single_character (slen, src, skind);
891beb95 3543 }
3544 else
3545 {
3546 slen = build_int_cst (size_type_node, 1);
3547 ssc = src;
3548 }
3549
3550 if (dlength != NULL_TREE)
3551 {
3552 dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
b44437b9 3553 dsc = string_to_single_character (slen, dest, dkind);
891beb95 3554 }
3555 else
3556 {
3557 dlen = build_int_cst (size_type_node, 1);
3558 dsc = dest;
3559 }
3560
3561 if (slength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (src)))
b44437b9 3562 ssc = string_to_single_character (slen, src, skind);
891beb95 3563 if (dlength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (dest)))
b44437b9 3564 dsc = string_to_single_character (dlen, dest, dkind);
891beb95 3565
72038310 3566
680e3123 3567 /* Assign directly if the types are compatible. */
3568 if (dsc != NULL_TREE && ssc != NULL_TREE
b44437b9 3569 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
77100724 3570 {
75a70cf9 3571 gfc_add_modify (block, dsc, ssc);
77100724 3572 return;
3573 }
dbe60343 3574
59b9dcbd 3575 /* Do nothing if the destination length is zero. */
2810b378 3576 cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
57e3c827 3577 build_int_cst (size_type_node, 0));
2810b378 3578
59b9dcbd 3579 /* The following code was previously in _gfortran_copy_string:
3580
3581 // The two strings may overlap so we use memmove.
3582 void
3583 copy_string (GFC_INTEGER_4 destlen, char * dest,
3584 GFC_INTEGER_4 srclen, const char * src)
3585 {
3586 if (srclen >= destlen)
3587 {
3588 // This will truncate if too long.
3589 memmove (dest, src, destlen);
3590 }
3591 else
3592 {
3593 memmove (dest, src, srclen);
3594 // Pad with spaces.
3595 memset (&dest[srclen], ' ', destlen - srclen);
3596 }
3597 }
3598
3599 We're now doing it here for better optimization, but the logic
3600 is the same. */
ceeda734 3601
b44437b9 3602 /* For non-default character kinds, we have to multiply the string
3603 length by the base type size. */
3604 chartype = gfc_get_char_type (dkind);
abb1d33a 3605 slen = fold_build2 (MULT_EXPR, size_type_node,
3606 fold_convert (size_type_node, slen),
3607 fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
3608 dlen = fold_build2 (MULT_EXPR, size_type_node,
3609 fold_convert (size_type_node, dlen),
3610 fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
b44437b9 3611
891beb95 3612 if (dlength)
3613 dest = fold_convert (pvoid_type_node, dest);
3614 else
3615 dest = gfc_build_addr_expr (pvoid_type_node, dest);
3616
3617 if (slength)
3618 src = fold_convert (pvoid_type_node, src);
3619 else
3620 src = gfc_build_addr_expr (pvoid_type_node, src);
ceeda734 3621
59b9dcbd 3622 /* Truncate string if source is too long. */
3623 cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
389dd41b 3624 tmp2 = build_call_expr_loc (input_location,
3625 built_in_decls[BUILT_IN_MEMMOVE],
c2f47e15 3626 3, dest, src, dlen);
59b9dcbd 3627
3628 /* Else copy and pad with spaces. */
389dd41b 3629 tmp3 = build_call_expr_loc (input_location,
3630 built_in_decls[BUILT_IN_MEMMOVE],
c2f47e15 3631 3, dest, src, slen);
59b9dcbd 3632
f6313358 3633 tmp4 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest,
0de36bdb 3634 fold_convert (sizetype, slen));
b44437b9 3635 tmp4 = fill_with_spaces (tmp4, chartype,
3636 fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
3637 dlen, slen));
59b9dcbd 3638
3639 gfc_init_block (&tempblock);
3640 gfc_add_expr_to_block (&tempblock, tmp3);
3641 gfc_add_expr_to_block (&tempblock, tmp4);
3642 tmp3 = gfc_finish_block (&tempblock);
3643
3644 /* The whole copy_string function is there. */
3645 tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
e60a6f7b 3646 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3647 build_empty_stmt (input_location));
dbe60343 3648 gfc_add_expr_to_block (block, tmp);
3649}
3650
3651
4ee9c684 3652/* Translate a statement function.
3653 The value of a statement function reference is obtained by evaluating the
3654 expression using the values of the actual arguments for the values of the
3655 corresponding dummy arguments. */
3656
3657static void
3658gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
3659{
3660 gfc_symbol *sym;
3661 gfc_symbol *fsym;
3662 gfc_formal_arglist *fargs;
3663 gfc_actual_arglist *args;
3664 gfc_se lse;
3665 gfc_se rse;
dbe60343 3666 gfc_saved_var *saved_vars;
3667 tree *temp_vars;
3668 tree type;
3669 tree tmp;
3670 int n;
4ee9c684 3671
3672 sym = expr->symtree->n.sym;
3673 args = expr->value.function.actual;
3674 gfc_init_se (&lse, NULL);
3675 gfc_init_se (&rse, NULL);
3676
dbe60343 3677 n = 0;
4ee9c684 3678 for (fargs = sym->formal; fargs; fargs = fargs->next)
dbe60343 3679 n++;
3680 saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
3681 temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
3682
3683 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
4ee9c684 3684 {
3685 /* Each dummy shall be specified, explicitly or implicitly, to be
3686 scalar. */
22d678e8 3687 gcc_assert (fargs->sym->attr.dimension == 0);
4ee9c684 3688 fsym = fargs->sym;
4ee9c684 3689
dbe60343 3690 /* Create a temporary to hold the value. */
3691 type = gfc_typenode_for_spec (&fsym->ts);
3692 temp_vars[n] = gfc_create_var (type, fsym->name);
3693
3694 if (fsym->ts.type == BT_CHARACTER)
4ee9c684 3695 {
dbe60343 3696 /* Copy string arguments. */
3697 tree arglen;
4ee9c684 3698
eeebe20b 3699 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
3700 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
4ee9c684 3701
dbe60343 3702 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3703 tmp = gfc_build_addr_expr (build_pointer_type (type),
3704 temp_vars[n]);
4ee9c684 3705
3706 gfc_conv_expr (&rse, args->expr);
3707 gfc_conv_string_parameter (&rse);
4ee9c684 3708 gfc_add_block_to_block (&se->pre, &lse.pre);
3709 gfc_add_block_to_block (&se->pre, &rse.pre);
3710
b44437b9 3711 gfc_trans_string_copy (&se->pre, arglen, tmp, fsym->ts.kind,
3712 rse.string_length, rse.expr, fsym->ts.kind);
4ee9c684 3713 gfc_add_block_to_block (&se->pre, &lse.post);
3714 gfc_add_block_to_block (&se->pre, &rse.post);
3715 }
3716 else
3717 {
3718 /* For everything else, just evaluate the expression. */
4ee9c684 3719 gfc_conv_expr (&lse, args->expr);
3720
3721 gfc_add_block_to_block (&se->pre, &lse.pre);
75a70cf9 3722 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
4ee9c684 3723 gfc_add_block_to_block (&se->pre, &lse.post);
3724 }
dbe60343 3725
4ee9c684 3726 args = args->next;
3727 }
dbe60343 3728
3729 /* Use the temporary variables in place of the real ones. */
3730 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3731 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
3732
4ee9c684 3733 gfc_conv_expr (se, sym->value);
dbe60343 3734
3735 if (sym->ts.type == BT_CHARACTER)
3736 {
eeebe20b 3737 gfc_conv_const_charlen (sym->ts.u.cl);
dbe60343 3738
3739 /* Force the expression to the correct length. */
3740 if (!INTEGER_CST_P (se->string_length)
3741 || tree_int_cst_lt (se->string_length,
eeebe20b 3742 sym->ts.u.cl->backend_decl))
dbe60343 3743 {
eeebe20b 3744 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
dbe60343 3745 tmp = gfc_create_var (type, sym->name);
3746 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
eeebe20b 3747 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
b44437b9 3748 sym->ts.kind, se->string_length, se->expr,
3749 sym->ts.kind);
dbe60343 3750 se->expr = tmp;
3751 }
eeebe20b 3752 se->string_length = sym->ts.u.cl->backend_decl;
dbe60343 3753 }
3754
f888a3fb 3755 /* Restore the original variables. */
dbe60343 3756 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3757 gfc_restore_sym (fargs->sym, &saved_vars[n]);
3758 gfc_free (saved_vars);
4ee9c684 3759}
3760
3761
3762/* Translate a function expression. */
3763
3764static void
3765gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
3766{
3767 gfc_symbol *sym;
3768
3769 if (expr->value.function.isym)
3770 {
3771 gfc_conv_intrinsic_function (se, expr);
3772 return;
3773 }
3774
f888a3fb 3775 /* We distinguish statement functions from general functions to improve
4ee9c684 3776 runtime performance. */
3777 if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
3778 {
3779 gfc_conv_statement_function (se, expr);
3780 return;
3781 }
3782
3783 /* expr.value.function.esym is the resolved (specific) function symbol for
3784 most functions. However this isn't set for dummy procedures. */
3785 sym = expr->value.function.esym;
3786 if (!sym)
3787 sym = expr->symtree->n.sym;
64e93293 3788
3789 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
3790 NULL_TREE);
4ee9c684 3791}
3792
f888a3fb 3793
4ee9c684 3794static void
3795gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
3796{
22d678e8 3797 gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
3798 gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
4ee9c684 3799
3800 gfc_conv_tmp_array_ref (se);
3801 gfc_advance_se_ss_chain (se);
3802}
3803
3804
bda1f152 3805/* Build a static initializer. EXPR is the expression for the initial value.
f888a3fb 3806 The other parameters describe the variable of the component being
3807 initialized. EXPR may be null. */
4ee9c684 3808
bda1f152 3809tree
3810gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
3811 bool array, bool pointer)
3812{
3813 gfc_se se;
3814
3815 if (!(expr || pointer))
3816 return NULL_TREE;
3817
cf65c534 3818 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
3819 (these are the only two iso_c_binding derived types that can be
3820 used as initialization expressions). If so, we need to modify
3821 the 'expr' to be that for a (void *). */
3e77b51f 3822 if (expr != NULL && expr->ts.type == BT_DERIVED
eeebe20b 3823 && expr->ts.is_iso_c && expr->ts.u.derived)
cf65c534 3824 {
eeebe20b 3825 gfc_symbol *derived = expr->ts.u.derived;
cf65c534 3826
c5d33754 3827 expr = gfc_int_expr (0);
cf65c534 3828
3829 /* The derived symbol has already been converted to a (void *). Use
3830 its kind. */
3831 expr->ts.f90_type = derived->ts.f90_type;
3832 expr->ts.kind = derived->ts.kind;
3833 }
c5d33754 3834
bda1f152 3835 if (array)
3836 {
3837 /* Arrays need special handling. */
3838 if (pointer)
3839 return gfc_build_null_descriptor (type);
3840 else
3841 return gfc_conv_array_initializer (type, expr);
3842 }
3843 else if (pointer)
3844 return fold_convert (type, null_pointer_node);
3845 else
3846 {
3847 switch (ts->type)
3848 {
3849 case BT_DERIVED:
1de1b1a9 3850 case BT_CLASS:
bda1f152 3851 gfc_init_se (&se, NULL);
3852 gfc_conv_structure (&se, expr, 1);
3853 return se.expr;
3854
3855 case BT_CHARACTER:
eeebe20b 3856 return gfc_conv_string_init (ts->u.cl->backend_decl,expr);
bda1f152 3857
3858 default:
3859 gfc_init_se (&se, NULL);
3860 gfc_conv_constant (&se, expr);
3861 return se.expr;
3862 }
3863 }
3864}
3865
9a0aec1d 3866static tree
3867gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3868{
3869 gfc_se rse;
3870 gfc_se lse;
3871 gfc_ss *rss;
3872 gfc_ss *lss;
3873 stmtblock_t body;
3874 stmtblock_t block;
3875 gfc_loopinfo loop;
3876 int n;
3877 tree tmp;
3878
3879 gfc_start_block (&block);
3880
3881 /* Initialize the scalarizer. */
3882 gfc_init_loopinfo (&loop);
3883
3884 gfc_init_se (&lse, NULL);
3885 gfc_init_se (&rse, NULL);
3886
3887 /* Walk the rhs. */
3888 rss = gfc_walk_expr (expr);
3889 if (rss == gfc_ss_terminator)
3890 {
3891 /* The rhs is scalar. Add a ss for the expression. */
3892 rss = gfc_get_ss ();
3893 rss->next = gfc_ss_terminator;
3894 rss->type = GFC_SS_SCALAR;
3895 rss->expr = expr;
3896 }
3897
3898 /* Create a SS for the destination. */
3899 lss = gfc_get_ss ();
3900 lss->type = GFC_SS_COMPONENT;
3901 lss->expr = NULL;
3902 lss->shape = gfc_get_shape (cm->as->rank);
3903 lss->next = gfc_ss_terminator;
3904 lss->data.info.dimen = cm->as->rank;
3905 lss->data.info.descriptor = dest;
3906 lss->data.info.data = gfc_conv_array_data (dest);
3907 lss->data.info.offset = gfc_conv_array_offset (dest);
3908 for (n = 0; n < cm->as->rank; n++)
3909 {
3910 lss->data.info.dim[n] = n;
3911 lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
3912 lss->data.info.stride[n] = gfc_index_one_node;
3913
3914 mpz_init (lss->shape[n]);
3915 mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
3916 cm->as->lower[n]->value.integer);
3917 mpz_add_ui (lss->shape[n], lss->shape[n], 1);
3918 }
3919
3920 /* Associate the SS with the loop. */
3921 gfc_add_ss_to_loop (&loop, lss);
3922 gfc_add_ss_to_loop (&loop, rss);
3923
3924 /* Calculate the bounds of the scalarization. */
3925 gfc_conv_ss_startstride (&loop);
3926
3927 /* Setup the scalarizing loops. */
92f4d1c4 3928 gfc_conv_loop_setup (&loop, &expr->where);
9a0aec1d 3929
3930 /* Setup the gfc_se structures. */
3931 gfc_copy_loopinfo_to_se (&lse, &loop);
3932 gfc_copy_loopinfo_to_se (&rse, &loop);
3933
3934 rse.ss = rss;
3935 gfc_mark_ss_chain_used (rss, 1);
3936 lse.ss = lss;
3937 gfc_mark_ss_chain_used (lss, 1);
3938
3939 /* Start the scalarized loop body. */
3940 gfc_start_scalarized_body (&loop, &body);
3941
3942 gfc_conv_tmp_array_ref (&lse);
dc5fe211 3943 if (cm->ts.type == BT_CHARACTER)
eeebe20b 3944 lse.string_length = cm->ts.u.cl->backend_decl;
dc5fe211 3945
9a0aec1d 3946 gfc_conv_expr (&rse, expr);
3947
2294b616 3948 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
9a0aec1d 3949 gfc_add_expr_to_block (&body, tmp);
3950
22d678e8 3951 gcc_assert (rse.ss == gfc_ss_terminator);
9a0aec1d 3952
3953 /* Generate the copying loops. */
3954 gfc_trans_scalarizing_loops (&loop, &body);
3955
3956 /* Wrap the whole thing up. */
3957 gfc_add_block_to_block (&block, &loop.pre);
3958 gfc_add_block_to_block (&block, &loop.post);
3959
9a0aec1d 3960 for (n = 0; n < cm->as->rank; n++)
3961 mpz_clear (lss->shape[n]);
3962 gfc_free (lss->shape);
3963
6cf06ccd 3964 gfc_cleanup_loop (&loop);
3965
9a0aec1d 3966 return gfc_finish_block (&block);
3967}
3968
2294b616 3969
9a0aec1d 3970/* Assign a single component of a derived type constructor. */
3971
3972static tree
3973gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3974{
3975 gfc_se se;
2294b616 3976 gfc_se lse;
9a0aec1d 3977 gfc_ss *rss;
3978 stmtblock_t block;
3979 tree tmp;
2294b616 3980 tree offset;
3981 int n;
9a0aec1d 3982
3983 gfc_start_block (&block);
2294b616 3984
3be2b8d5 3985 if (cm->attr.pointer)
9a0aec1d 3986 {
3987 gfc_init_se (&se, NULL);
3988 /* Pointer component. */
3be2b8d5 3989 if (cm->attr.dimension)
9a0aec1d 3990 {
3991 /* Array pointer. */
3992 if (expr->expr_type == EXPR_NULL)
94be45c9 3993 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
9a0aec1d 3994 else
3995 {
3996 rss = gfc_walk_expr (expr);
3997 se.direct_byref = 1;
3998 se.expr = dest;
3999 gfc_conv_expr_descriptor (&se, expr, rss);
4000 gfc_add_block_to_block (&block, &se.pre);
4001 gfc_add_block_to_block (&block, &se.post);
4002 }
4003 }
4004 else
4005 {
4006 /* Scalar pointers. */
4007 se.want_pointer = 1;
4008 gfc_conv_expr (&se, expr);
4009 gfc_add_block_to_block (&block, &se.pre);
75a70cf9 4010 gfc_add_modify (&block, dest,
9a0aec1d 4011 fold_convert (TREE_TYPE (dest), se.expr));
4012 gfc_add_block_to_block (&block, &se.post);
4013 }
4014 }
1de1b1a9 4015 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
4016 {
4017 /* NULL initialization for CLASS components. */
4018 tmp = gfc_trans_structure_assign (dest,
4019 gfc_default_initializer (&cm->ts));
4020 gfc_add_expr_to_block (&block, tmp);
4021 }
3be2b8d5 4022 else if (cm->attr.dimension)
9a0aec1d 4023 {
3be2b8d5 4024 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
2294b616 4025 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
3be2b8d5 4026 else if (cm->attr.allocatable)
6826be54 4027 {
4028 tree tmp2;
2294b616 4029
4030 gfc_init_se (&se, NULL);
4031
4032 rss = gfc_walk_expr (expr);
6826be54 4033 se.want_pointer = 0;
4034 gfc_conv_expr_descriptor (&se, expr, rss);
2294b616 4035 gfc_add_block_to_block (&block, &se.pre);
bb982f66 4036 gfc_add_modify (&block, dest, se.expr);
2294b616 4037
eeebe20b 4038 if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
4039 tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr, dest,
2294b616 4040 cm->as->rank);
4041 else
6826be54 4042 tmp = gfc_duplicate_allocatable (dest, se.expr,
2294b616 4043 TREE_TYPE(cm->backend_decl),
4044 cm->as->rank);
4045
6826be54 4046 gfc_add_expr_to_block (&block, tmp);
6826be54 4047 gfc_add_block_to_block (&block, &se.post);
8714fc76 4048
4049 if (expr->expr_type != EXPR_VARIABLE)
4050 gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
6826be54 4051
4052 /* Shift the lbound and ubound of temporaries to being unity, rather
4053 than zero, based. Calculate the offset for all cases. */
6b1a9af3 4054 offset = gfc_conv_descriptor_offset_get (dest);
75a70cf9 4055 gfc_add_modify (&block, offset, gfc_index_zero_node);
6826be54 4056 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
4057 for (n = 0; n < expr->rank; n++)
4058 {
4059 if (expr->expr_type != EXPR_VARIABLE
4060 && expr->expr_type != EXPR_CONSTANT)
4061 {
4062 tree span;
6b1a9af3 4063 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
6826be54 4064 span = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp,
6b1a9af3 4065 gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
4066 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4067 span, gfc_index_one_node);
4068 gfc_conv_descriptor_ubound_set (&block, dest, gfc_rank_cst[n],
4069 tmp);
4070 gfc_conv_descriptor_lbound_set (&block, dest, gfc_rank_cst[n],
4071 gfc_index_one_node);
6826be54 4072 }
4073 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
6b1a9af3 4074 gfc_conv_descriptor_lbound_get (dest,
2294b616 4075 gfc_rank_cst[n]),
6b1a9af3 4076 gfc_conv_descriptor_stride_get (dest,
2294b616 4077 gfc_rank_cst[n]));
75a70cf9 4078 gfc_add_modify (&block, tmp2, tmp);
6826be54 4079 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
6b1a9af3 4080 gfc_conv_descriptor_offset_set (&block, dest, tmp);
6826be54 4081 }
8714fc76 4082
4083 if (expr->expr_type == EXPR_FUNCTION
4084 && expr->value.function.isym
4085 && expr->value.function.isym->conversion
4086 && expr->value.function.actual->expr
4087 && expr->value.function.actual->expr->expr_type
4088 == EXPR_VARIABLE)
4089 {
4090 /* If a conversion expression has a null data pointer
4091 argument, nullify the allocatable component. */
4092 gfc_symbol *s;
4093 tree non_null_expr;
4094 tree null_expr;
4095 s = expr->value.function.actual->expr->symtree->n.sym;
4096 if (s->attr.allocatable || s->attr.pointer)
4097 {
4098 non_null_expr = gfc_finish_block (&block);
4099 gfc_start_block (&block);
4100 gfc_conv_descriptor_data_set (&block, dest,
4101 null_pointer_node);
4102 null_expr = gfc_finish_block (&block);
4103 tmp = gfc_conv_descriptor_data_get (s->backend_decl);
4104 tmp = build2 (EQ_EXPR, boolean_type_node, tmp,
4105 fold_convert (TREE_TYPE (tmp),
4106 null_pointer_node));
4107 return build3_v (COND_EXPR, tmp, null_expr,
4108 non_null_expr);
4109 }
4110 }
6826be54 4111 }
2294b616 4112 else
6826be54 4113 {
2294b616 4114 tmp = gfc_trans_subarray_assign (dest, cm, expr);
4115 gfc_add_expr_to_block (&block, tmp);
6826be54 4116 }
9a0aec1d 4117 }
4118 else if (expr->ts.type == BT_DERIVED)
4119 {
d95efb59 4120 if (expr->expr_type != EXPR_STRUCTURE)
4121 {
4122 gfc_init_se (&se, NULL);
4123 gfc_conv_expr (&se, expr);
0029c45c 4124 gfc_add_block_to_block (&block, &se.pre);
75a70cf9 4125 gfc_add_modify (&block, dest,
d95efb59 4126 fold_convert (TREE_TYPE (dest), se.expr));
0029c45c 4127 gfc_add_block_to_block (&block, &se.post);
d95efb59 4128 }
4129 else
4130 {
4131 /* Nested constructors. */
4132 tmp = gfc_trans_structure_assign (dest, expr);
4133 gfc_add_expr_to_block (&block, tmp);
4134 }
9a0aec1d 4135 }
4136 else
4137 {
4138 /* Scalar component. */
9a0aec1d 4139 gfc_init_se (&se, NULL);
4140 gfc_init_se (&lse, NULL);
4141
4142 gfc_conv_expr (&se, expr);
4143 if (cm->ts.type == BT_CHARACTER)
eeebe20b 4144 lse.string_length = cm->ts.u.cl->backend_decl;
9a0aec1d 4145 lse.expr = dest;
2294b616 4146 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false);
9a0aec1d 4147 gfc_add_expr_to_block (&block, tmp);
4148 }
4149 return gfc_finish_block (&block);
4150}
4151
39fca56b 4152/* Assign a derived type constructor to a variable. */
9a0aec1d 4153
4154static tree
4155gfc_trans_structure_assign (tree dest, gfc_expr * expr)
4156{
4157 gfc_constructor *c;
4158 gfc_component *cm;
4159 stmtblock_t block;
4160 tree field;
4161 tree tmp;
4162
4163 gfc_start_block (&block);
eeebe20b 4164 cm = expr->ts.u.derived->components;
9a0aec1d 4165 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
4166 {
4167 /* Skip absent members in default initializers. */
4168 if (!c->expr)
0029c45c 4169 continue;
4170
9a0aec1d 4171 field = cm->backend_decl;
f75d6b8a 4172 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field),
4173 dest, field, NULL_TREE);
9a0aec1d 4174 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
4175 gfc_add_expr_to_block (&block, tmp);
4176 }
4177 return gfc_finish_block (&block);
4178}
4179
4ee9c684 4180/* Build an expression for a constructor. If init is nonzero then
4181 this is part of a static variable initializer. */
4182
4183void
4184gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
4185{
4186 gfc_constructor *c;
4187 gfc_component *cm;
4ee9c684 4188 tree val;
4ee9c684 4189 tree type;
9a0aec1d 4190 tree tmp;
c75b4594 4191 VEC(constructor_elt,gc) *v = NULL;
4ee9c684 4192
22d678e8 4193 gcc_assert (se->ss == NULL);
4194 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
4ee9c684 4195 type = gfc_typenode_for_spec (&expr->ts);
9a0aec1d 4196
4197 if (!init)
4198 {
4199 /* Create a temporary variable and fill it in. */
eeebe20b 4200 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
9a0aec1d 4201 tmp = gfc_trans_structure_assign (se->expr, expr);
4202 gfc_add_expr_to_block (&se->pre, tmp);
4203 return;
4204 }
4205
eeebe20b 4206 cm = expr->ts.u.derived->components;
2294b616 4207
4ee9c684 4208 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
4209 {
2294b616 4210 /* Skip absent members in default initializers and allocatable
4211 components. Although the latter have a default initializer
4212 of EXPR_NULL,... by default, the static nullify is not needed
4213 since this is done every time we come into scope. */
3be2b8d5 4214 if (!c->expr || cm->attr.allocatable)
4ee9c684 4215 continue;
4216
1de1b1a9 4217 if (cm->ts.type == BT_CLASS)
4218 {
4219 val = gfc_conv_initializer (c->expr, &cm->ts,
4220 TREE_TYPE (cm->ts.u.derived->components->backend_decl),
4221 cm->ts.u.derived->components->attr.dimension,
4222 cm->ts.u.derived->components->attr.pointer);
4223
4224 /* Append it to the constructor list. */
4225 CONSTRUCTOR_APPEND_ELT (v, cm->ts.u.derived->components->backend_decl,
4226 val);
4227 }
4228 else
4229 {
4230 val = gfc_conv_initializer (c->expr, &cm->ts,
4231 TREE_TYPE (cm->backend_decl), cm->attr.dimension,
4232 cm->attr.pointer || cm->attr.proc_pointer);
4ee9c684 4233
1de1b1a9 4234 /* Append it to the constructor list. */
4235 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
4236 }
4ee9c684 4237 }
c75b4594 4238 se->expr = build_constructor (type, v);
8b8484b4 4239 if (init)
c7d4e749 4240 TREE_CONSTANT (se->expr) = 1;
4ee9c684 4241}
4242
4243
f888a3fb 4244/* Translate a substring expression. */
4ee9c684 4245
4246static void
4247gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
4248{
4249 gfc_ref *ref;
4250
4251 ref = expr->ref;
4252
24756408 4253 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
4ee9c684 4254
b44437b9 4255 se->expr = gfc_build_wide_string_const (expr->ts.kind,
4256 expr->value.character.length,
4257 expr->value.character.string);
c32f863c 4258
4ee9c684 4259 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
24756408 4260 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
4ee9c684 4261
24756408 4262 if (ref)
4263 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
4ee9c684 4264}
4265
4266
7b7afa03 4267/* Entry point for expression translation. Evaluates a scalar quantity.
4268 EXPR is the expression to be translated, and SE is the state structure if
4269 called from within the scalarized. */
4ee9c684 4270
4271void
4272gfc_conv_expr (gfc_se * se, gfc_expr * expr)
4273{
4274 if (se->ss && se->ss->expr == expr
4275 && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
4276 {
9a0aec1d 4277 /* Substitute a scalar expression evaluated outside the scalarization
4ee9c684 4278 loop. */
4279 se->expr = se->ss->data.scalar.expr;
7949cb07 4280 se->string_length = se->ss->string_length;
4ee9c684 4281 gfc_advance_se_ss_chain (se);
4282 return;
4283 }
4284
c5d33754 4285 /* We need to convert the expressions for the iso_c_binding derived types.
4286 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
4287 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
4288 typespec for the C_PTR and C_FUNPTR symbols, which has already been
4289 updated to be an integer with a kind equal to the size of a (void *). */
eeebe20b 4290 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
4291 && expr->ts.u.derived->attr.is_iso_c)
c5d33754 4292 {
4293 if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
4294 || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
4295 {
4296 /* Set expr_type to EXPR_NULL, which will result in
4297 null_pointer_node being used below. */
4298 expr->expr_type = EXPR_NULL;
4299 }
4300 else
4301 {
4302 /* Update the type/kind of the expression to be what the new
4303 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
eeebe20b 4304 expr->ts.type = expr->ts.u.derived->ts.type;
4305 expr->ts.f90_type = expr->ts.u.derived->ts.f90_type;
4306 expr->ts.kind = expr->ts.u.derived->ts.kind;
c5d33754 4307 }
4308 }
4309
4ee9c684 4310 switch (expr->expr_type)
4311 {
4312 case EXPR_OP:
4313 gfc_conv_expr_op (se, expr);
4314 break;
4315
4316 case EXPR_FUNCTION:
4317 gfc_conv_function_expr (se, expr);
4318 break;
4319
4320 case EXPR_CONSTANT:
4321 gfc_conv_constant (se, expr);
4322 break;
4323
4324 case EXPR_VARIABLE:
4325 gfc_conv_variable (se, expr);
4326 break;
4327
4328 case EXPR_NULL:
4329 se->expr = null_pointer_node;
4330 break;
4331
4332 case EXPR_SUBSTRING:
4333 gfc_conv_substring_expr (se, expr);
4334 break;
4335
4336 case EXPR_STRUCTURE:
4337 gfc_conv_structure (se, expr, 0);
4338 break;
4339
4340 case EXPR_ARRAY:
4341 gfc_conv_array_constructor_expr (se, expr);
4342 break;
4343
4344 default:
22d678e8 4345 gcc_unreachable ();
4ee9c684 4346 break;
4347 }
4348}
4349
7b7afa03 4350/* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
4351 of an assignment. */
4ee9c684 4352void
4353gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
4354{
4355 gfc_conv_expr (se, expr);
7b7afa03 4356 /* All numeric lvalues should have empty post chains. If not we need to
4ee9c684 4357 figure out a way of rewriting an lvalue so that it has no post chain. */
7b7afa03 4358 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
4ee9c684 4359}
4360
7b7afa03 4361/* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
d4163395 4362 numeric expressions. Used for scalar values where inserting cleanup code
7b7afa03 4363 is inconvenient. */
4ee9c684 4364void
4365gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
4366{
4367 tree val;
4368
22d678e8 4369 gcc_assert (expr->ts.type != BT_CHARACTER);
4ee9c684 4370 gfc_conv_expr (se, expr);
4371 if (se->post.head)
4372 {
4373 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
75a70cf9 4374 gfc_add_modify (&se->pre, val, se->expr);
7b7afa03 4375 se->expr = val;
4376 gfc_add_block_to_block (&se->pre, &se->post);
4ee9c684 4377 }
4378}
4379
24146844 4380/* Helper to translate an expression and convert it to a particular type. */
4ee9c684 4381void
4382gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
4383{
4384 gfc_conv_expr_val (se, expr);
4385 se->expr = convert (type, se->expr);
4386}
4387
4388
f888a3fb 4389/* Converts an expression so that it can be passed by reference. Scalar
4ee9c684 4390 values only. */
4391
4392void
4393gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
4394{
4395 tree var;
4396
4397 if (se->ss && se->ss->expr == expr
4398 && se->ss->type == GFC_SS_REFERENCE)
4399 {
4400 se->expr = se->ss->data.scalar.expr;
7949cb07 4401 se->string_length = se->ss->string_length;
4ee9c684 4402 gfc_advance_se_ss_chain (se);
4403 return;
4404 }
4405
4406 if (expr->ts.type == BT_CHARACTER)
4407 {
4408 gfc_conv_expr (se, expr);
4409 gfc_conv_string_parameter (se);
4410 return;
4411 }
4412
4413 if (expr->expr_type == EXPR_VARIABLE)
4414 {
4415 se->want_pointer = 1;
4416 gfc_conv_expr (se, expr);
4417 if (se->post.head)
4418 {
4419 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
75a70cf9 4420 gfc_add_modify (&se->pre, var, se->expr);
4ee9c684 4421 gfc_add_block_to_block (&se->pre, &se->post);
4422 se->expr = var;
4423 }
4424 return;
4425 }
4426
4047f0ad 4427 if (expr->expr_type == EXPR_FUNCTION
7035e057 4428 && ((expr->value.function.esym
4429 && expr->value.function.esym->result->attr.pointer
4430 && !expr->value.function.esym->result->attr.dimension)
4431 || (!expr->value.function.esym
4432 && expr->symtree->n.sym->attr.pointer
4433 && !expr->symtree->n.sym->attr.dimension)))
4047f0ad 4434 {
4435 se->want_pointer = 1;
4436 gfc_conv_expr (se, expr);
4437 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
75a70cf9 4438 gfc_add_modify (&se->pre, var, se->expr);
4047f0ad 4439 se->expr = var;
4440 return;
4441 }
4442
4443
4ee9c684 4444 gfc_conv_expr (se, expr);
4445
4446 /* Create a temporary var to hold the value. */
e67e5e1f 4447 if (TREE_CONSTANT (se->expr))
4448 {
0f9dc66f 4449 tree tmp = se->expr;
4450 STRIP_TYPE_NOPS (tmp);
e60a6f7b 4451 var = build_decl (input_location,
4452 CONST_DECL, NULL, TREE_TYPE (tmp));
0f9dc66f 4453 DECL_INITIAL (var) = tmp;
f79c8ea7 4454 TREE_STATIC (var) = 1;
e67e5e1f 4455 pushdecl (var);
4456 }
4457 else
4458 {
4459 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
75a70cf9 4460 gfc_add_modify (&se->pre, var, se->expr);
e67e5e1f 4461 }
4ee9c684 4462 gfc_add_block_to_block (&se->pre, &se->post);
4463
4464 /* Take the address of that value. */
86f2ad37 4465 se->expr = gfc_build_addr_expr (NULL_TREE, var);
4ee9c684 4466}
4467
4468
4469tree
4470gfc_trans_pointer_assign (gfc_code * code)
4471{
578d3f19 4472 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
4ee9c684 4473}
4474
4475
4396343e 4476/* Generate code for a pointer assignment. */
4477
4ee9c684 4478tree
4479gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
4480{
4481 gfc_se lse;
4482 gfc_se rse;
4483 gfc_ss *lss;
4484 gfc_ss *rss;
4485 stmtblock_t block;
7853829d 4486 tree desc;
4487 tree tmp;
1033248c 4488 tree decl;
4489
4ee9c684 4490 gfc_start_block (&block);
4491
4492 gfc_init_se (&lse, NULL);
4493
4494 lss = gfc_walk_expr (expr1);
4495 rss = gfc_walk_expr (expr2);
4496 if (lss == gfc_ss_terminator)
4497 {
4396343e 4498 /* Scalar pointers. */
4ee9c684 4499 lse.want_pointer = 1;
4500 gfc_conv_expr (&lse, expr1);
22d678e8 4501 gcc_assert (rss == gfc_ss_terminator);
4ee9c684 4502 gfc_init_se (&rse, NULL);
4503 rse.want_pointer = 1;
4504 gfc_conv_expr (&rse, expr2);
cad0ddcf 4505
4506 if (expr1->symtree->n.sym->attr.proc_pointer
4507 && expr1->symtree->n.sym->attr.dummy)
389dd41b 4508 lse.expr = build_fold_indirect_ref_loc (input_location,
4509 lse.expr);
cad0ddcf 4510
85d1c108 4511 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
4512 && expr2->symtree->n.sym->attr.dummy)
389dd41b 4513 rse.expr = build_fold_indirect_ref_loc (input_location,
4514 rse.expr);
85d1c108 4515
4ee9c684 4516 gfc_add_block_to_block (&block, &lse.pre);
4517 gfc_add_block_to_block (&block, &rse.pre);
9c5786bd 4518
4519 /* Check character lengths if character expression. The test is only
4520 really added if -fbounds-check is enabled. */
1d84f30a 4521 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
4522 && !expr1->symtree->n.sym->attr.proc_pointer
4523 && !gfc_is_proc_ptr_comp (expr1, NULL))
9c5786bd 4524 {
4525 gcc_assert (expr2->ts.type == BT_CHARACTER);
4526 gcc_assert (lse.string_length && rse.string_length);
4527 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4528 lse.string_length, rse.string_length,
4529 &block);
4530 }
4531
75a70cf9 4532 gfc_add_modify (&block, lse.expr,
260abd71 4533 fold_convert (TREE_TYPE (lse.expr), rse.expr));
9c5786bd 4534
4ee9c684 4535 gfc_add_block_to_block (&block, &rse.post);
4536 gfc_add_block_to_block (&block, &lse.post);
4537 }
4538 else
4539 {
9c5786bd 4540 tree strlen_lhs;
4541 tree strlen_rhs = NULL_TREE;
4542
4396343e 4543 /* Array pointer. */
4ee9c684 4544 gfc_conv_expr_descriptor (&lse, expr1, lss);
9c5786bd 4545 strlen_lhs = lse.string_length;
7853829d 4546 switch (expr2->expr_type)
4547 {
4548 case EXPR_NULL:
4549 /* Just set the data pointer to null. */
ca122904 4550 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
7853829d 4551 break;
4552
4553 case EXPR_VARIABLE:
4554 /* Assign directly to the pointer's descriptor. */
9c5786bd 4555 lse.direct_byref = 1;
7853829d 4556 gfc_conv_expr_descriptor (&lse, expr2, rss);
9c5786bd 4557 strlen_rhs = lse.string_length;
1033248c 4558
4559 /* If this is a subreference array pointer assignment, use the rhs
8192caf4 4560 descriptor element size for the lhs span. */
1033248c 4561 if (expr1->symtree->n.sym->attr.subref_array_pointer)
4562 {
4563 decl = expr1->symtree->n.sym->backend_decl;
8192caf4 4564 gfc_init_se (&rse, NULL);
4565 rse.descriptor_only = 1;
4566 gfc_conv_expr (&rse, expr2);
4567 tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
4568 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
4569 if (!INTEGER_CST_P (tmp))
9c5786bd 4570 gfc_add_block_to_block (&lse.post, &rse.pre);
75a70cf9 4571 gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
1033248c 4572 }
4573
7853829d 4574 break;
4575
4576 default:
4577 /* Assign to a temporary descriptor and then copy that
4578 temporary to the pointer. */
4579 desc = lse.expr;
4580 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
4581
4582 lse.expr = tmp;
4583 lse.direct_byref = 1;
4584 gfc_conv_expr_descriptor (&lse, expr2, rss);
9c5786bd 4585 strlen_rhs = lse.string_length;
75a70cf9 4586 gfc_add_modify (&lse.pre, desc, tmp);
7853829d 4587 break;
9c5786bd 4588 }
4589
4ee9c684 4590 gfc_add_block_to_block (&block, &lse.pre);
9c5786bd 4591
4592 /* Check string lengths if applicable. The check is only really added
4593 to the output code if -fbounds-check is enabled. */
4594 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
4595 {
4596 gcc_assert (expr2->ts.type == BT_CHARACTER);
4597 gcc_assert (strlen_lhs && strlen_rhs);
4598 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4599 strlen_lhs, strlen_rhs, &block);
4600 }
4601
4ee9c684 4602 gfc_add_block_to_block (&block, &lse.post);
4603 }
4604 return gfc_finish_block (&block);
4605}
4606
4607
4608/* Makes sure se is suitable for passing as a function string parameter. */
69b1505f 4609/* TODO: Need to check all callers of this function. It may be abused. */
4ee9c684 4610
4611void
4612gfc_conv_string_parameter (gfc_se * se)
4613{
4614 tree type;
4615
4616 if (TREE_CODE (se->expr) == STRING_CST)
4617 {
b44437b9 4618 type = TREE_TYPE (TREE_TYPE (se->expr));
4619 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4ee9c684 4620 return;
4621 }
4622
b44437b9 4623 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
4ee9c684 4624 {
230c8f37 4625 if (TREE_CODE (se->expr) != INDIRECT_REF)
b44437b9 4626 {
4627 type = TREE_TYPE (se->expr);
4628 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4629 }
230c8f37 4630 else
4631 {
4632 type = gfc_get_character_type_len (gfc_default_character_kind,
4633 se->string_length);
4634 type = build_pointer_type (type);
4635 se->expr = gfc_build_addr_expr (type, se->expr);
4636 }
4ee9c684 4637 }
4638
22d678e8 4639 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
4640 gcc_assert (se->string_length
4ee9c684 4641 && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
4642}
4643
4644
4645/* Generate code for assignment of scalar variables. Includes character
2294b616 4646 strings and derived types with allocatable components. */
4ee9c684 4647
4648tree
2294b616 4649gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
4650 bool l_is_temp, bool r_is_var)
4ee9c684 4651{
4ee9c684 4652 stmtblock_t block;
2294b616 4653 tree tmp;
4654 tree cond;
4ee9c684 4655
4656 gfc_init_block (&block);
4657
2294b616 4658 if (ts.type == BT_CHARACTER)
4ee9c684 4659 {
891beb95 4660 tree rlen = NULL;
4661 tree llen = NULL;
4ee9c684 4662
891beb95 4663 if (lse->string_length != NULL_TREE)
4664 {
4665 gfc_conv_string_parameter (lse);
4666 gfc_add_block_to_block (&block, &lse->pre);
4667 llen = lse->string_length;
4668 }
4ee9c684 4669
891beb95 4670 if (rse->string_length != NULL_TREE)
4671 {
4672 gcc_assert (rse->string_length != NULL_TREE);
4673 gfc_conv_string_parameter (rse);
4674 gfc_add_block_to_block (&block, &rse->pre);
4675 rlen = rse->string_length;
4676 }
4ee9c684 4677
b44437b9 4678 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
4679 rse->expr, ts.kind);
4ee9c684 4680 }
eeebe20b 4681 else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
2294b616 4682 {
4683 cond = NULL_TREE;
4684
4685 /* Are the rhs and the lhs the same? */
4686 if (r_is_var)
4687 {
4688 cond = fold_build2 (EQ_EXPR, boolean_type_node,
86f2ad37 4689 gfc_build_addr_expr (NULL_TREE, lse->expr),
4690 gfc_build_addr_expr (NULL_TREE, rse->expr));
2294b616 4691 cond = gfc_evaluate_now (cond, &lse->pre);
4692 }
4693
4694 /* Deallocate the lhs allocated components as long as it is not
89032e9a 4695 the same as the rhs. This must be done following the assignment
4696 to prevent deallocating data that could be used in the rhs
4697 expression. */
2294b616 4698 if (!l_is_temp)
4699 {
89032e9a 4700 tmp = gfc_evaluate_now (lse->expr, &lse->pre);
eeebe20b 4701 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
2294b616 4702 if (r_is_var)
e60a6f7b 4703 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4704 tmp);
89032e9a 4705 gfc_add_expr_to_block (&lse->post, tmp);
2294b616 4706 }
6826be54 4707
89032e9a 4708 gfc_add_block_to_block (&block, &rse->pre);
4709 gfc_add_block_to_block (&block, &lse->pre);
2294b616 4710
75a70cf9 4711 gfc_add_modify (&block, lse->expr,
2294b616 4712 fold_convert (TREE_TYPE (lse->expr), rse->expr));
4713
4714 /* Do a deep copy if the rhs is a variable, if it is not the
540338c6 4715 same as the lhs. */
2294b616 4716 if (r_is_var)
4717 {
eeebe20b 4718 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
e60a6f7b 4719 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4720 tmp);
2294b616 4721 gfc_add_expr_to_block (&block, tmp);
4722 }
2294b616 4723 }
15f80871 4724 else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
816767a6 4725 {
4726 gfc_add_block_to_block (&block, &lse->pre);
4727 gfc_add_block_to_block (&block, &rse->pre);
49974242 4728 tmp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lse->expr), rse->expr);
816767a6 4729 gfc_add_modify (&block, lse->expr, tmp);
4730 }
4ee9c684 4731 else
4732 {
4733 gfc_add_block_to_block (&block, &lse->pre);
4734 gfc_add_block_to_block (&block, &rse->pre);
4735
75a70cf9 4736 gfc_add_modify (&block, lse->expr,
816767a6 4737 fold_convert (TREE_TYPE (lse->expr), rse->expr));
4ee9c684 4738 }
4739
4740 gfc_add_block_to_block (&block, &lse->post);
4741 gfc_add_block_to_block (&block, &rse->post);
4742
4743 return gfc_finish_block (&block);
4744}
4745
4746
4747/* Try to translate array(:) = func (...), where func is a transformational
4748 array function, without using a temporary. Returns NULL is this isn't the
4749 case. */
4750
4751static tree
4752gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
4753{
4754 gfc_se se;
4755 gfc_ss *ss;
70464f87 4756 gfc_ref * ref;
4757 bool seen_array_ref;
8d60cc46 4758 bool c = false;
85d1c108 4759 gfc_component *comp = NULL;
4ee9c684 4760
4761 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
4762 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
4763 return NULL;
4764
4765 /* Elemental functions don't need a temporary anyway. */
08349c53 4766 if (expr2->value.function.esym != NULL
4767 && expr2->value.function.esym->attr.elemental)
4ee9c684 4768 return NULL;
4769
8d60cc46 4770 /* Fail if rhs is not FULL or a contiguous section. */
4771 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
4772 return NULL;
4773
c99d633f 4774 /* Fail if EXPR1 can't be expressed as a descriptor. */
4775 if (gfc_ref_needs_temporary_p (expr1->ref))
4776 return NULL;
4777
34da51b6 4778 /* Functions returning pointers need temporaries. */
d4ef6f9d 4779 if (expr2->symtree->n.sym->attr.pointer
4780 || expr2->symtree->n.sym->attr.allocatable)
34da51b6 4781 return NULL;
4782
5065911e 4783 /* Character array functions need temporaries unless the
4784 character lengths are the same. */
4785 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
4786 {
eeebe20b 4787 if (expr1->ts.u.cl->length == NULL
4788 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
5065911e 4789 return NULL;
4790
eeebe20b 4791 if (expr2->ts.u.cl->length == NULL
4792 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
5065911e 4793 return NULL;
4794
eeebe20b 4795 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
4796 expr2->ts.u.cl->length->value.integer) != 0)
5065911e 4797 return NULL;
4798 }
4799
70464f87 4800 /* Check that no LHS component references appear during an array
4801 reference. This is needed because we do not have the means to
4802 span any arbitrary stride with an array descriptor. This check
4803 is not needed for the rhs because the function result has to be
4804 a complete type. */
4805 seen_array_ref = false;
4806 for (ref = expr1->ref; ref; ref = ref->next)
4807 {
4808 if (ref->type == REF_ARRAY)
4809 seen_array_ref= true;
4810 else if (ref->type == REF_COMPONENT && seen_array_ref)
4811 return NULL;
4812 }
4813
4ee9c684 4814 /* Check for a dependency. */
018ef8b8 4815 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
4816 expr2->value.function.esym,
74e83bb9 4817 expr2->value.function.actual,
4818 NOT_ELEMENTAL))
4ee9c684 4819 return NULL;
4820
4821 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
4822 functions. */
22d678e8 4823 gcc_assert (expr2->value.function.isym
ff70e443 4824 || (gfc_is_proc_ptr_comp (expr2, &comp)
88a37d69 4825 && comp && comp->attr.dimension)
85d1c108 4826 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
88a37d69 4827 && expr2->value.function.esym->result->attr.dimension));
4ee9c684 4828
4829 ss = gfc_walk_expr (expr1);
22d678e8 4830 gcc_assert (ss != gfc_ss_terminator);
4ee9c684 4831 gfc_init_se (&se, NULL);
4832 gfc_start_block (&se.pre);
4833 se.want_pointer = 1;
4834
bc56d052 4835 gfc_conv_array_parameter (&se, expr1, ss, 0, NULL, NULL, NULL);
4ee9c684 4836
4837 se.direct_byref = 1;
4838 se.ss = gfc_walk_expr (expr2);
22d678e8 4839 gcc_assert (se.ss != gfc_ss_terminator);
4ee9c684 4840 gfc_conv_function_expr (&se, expr2);
4ee9c684 4841 gfc_add_block_to_block (&se.pre, &se.post);
4842
4843 return gfc_finish_block (&se.pre);
4844}
4845
67313c34 4846/* Determine whether the given EXPR_CONSTANT is a zero initializer. */
4847
4848static bool
4849is_zero_initializer_p (gfc_expr * expr)
4850{
4851 if (expr->expr_type != EXPR_CONSTANT)
4852 return false;
667787ce 4853
4854 /* We ignore constants with prescribed memory representations for now. */
4855 if (expr->representation.string)
67313c34 4856 return false;
4857
4858 switch (expr->ts.type)
4859 {
4860 case BT_INTEGER:
4861 return mpz_cmp_si (expr->value.integer, 0) == 0;
4862
4863 case BT_REAL:
4864 return mpfr_zero_p (expr->value.real)
4865 && MPFR_SIGN (expr->value.real) >= 0;
4866
4867 case BT_LOGICAL:
4868 return expr->value.logical == 0;
4869
4870 case BT_COMPLEX:
f8e9f06c 4871 return mpfr_zero_p (mpc_realref (expr->value.complex))
4872 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
4873 && mpfr_zero_p (mpc_imagref (expr->value.complex))
4874 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
67313c34 4875
4876 default:
4877 break;
4878 }
4879 return false;
4880}
4881
4882/* Try to efficiently translate array(:) = 0. Return NULL if this
4883 can't be done. */
4884
4885static tree
4886gfc_trans_zero_assign (gfc_expr * expr)
4887{
4888 tree dest, len, type;
c2f47e15 4889 tree tmp;
67313c34 4890 gfc_symbol *sym;
4891
4892 sym = expr->symtree->n.sym;
4893 dest = gfc_get_symbol_decl (sym);
4894
4895 type = TREE_TYPE (dest);
4896 if (POINTER_TYPE_P (type))
4897 type = TREE_TYPE (type);
4898 if (!GFC_ARRAY_TYPE_P (type))
4899 return NULL_TREE;
4900
4901 /* Determine the length of the array. */
4902 len = GFC_TYPE_ARRAY_SIZE (type);
4903 if (!len || TREE_CODE (len) != INTEGER_CST)
4904 return NULL_TREE;
4905
db867224 4906 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
67313c34 4907 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
db867224 4908 fold_convert (gfc_array_index_type, tmp));
67313c34 4909
1d9f9adc 4910 /* If we are zeroing a local array avoid taking its address by emitting
4911 a = {} instead. */
67313c34 4912 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
1d9f9adc 4913 return build2 (MODIFY_EXPR, void_type_node,
4914 dest, build_constructor (TREE_TYPE (dest), NULL));
4915
4916 /* Convert arguments to the correct types. */
4917 dest = fold_convert (pvoid_type_node, dest);
67313c34 4918 len = fold_convert (size_type_node, len);
4919
4920 /* Construct call to __builtin_memset. */
389dd41b 4921 tmp = build_call_expr_loc (input_location,
4922 built_in_decls[BUILT_IN_MEMSET],
c2f47e15 4923 3, dest, integer_zero_node, len);
67313c34 4924 return fold_convert (void_type_node, tmp);
4925}
4ee9c684 4926
538374c5 4927
4928/* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
4929 that constructs the call to __builtin_memcpy. */
4930
7a2a9daf 4931tree
538374c5 4932gfc_build_memcpy_call (tree dst, tree src, tree len)
4933{
c2f47e15 4934 tree tmp;
538374c5 4935
4936 /* Convert arguments to the correct types. */
4937 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
4938 dst = gfc_build_addr_expr (pvoid_type_node, dst);
4939 else
4940 dst = fold_convert (pvoid_type_node, dst);
4941
4942 if (!POINTER_TYPE_P (TREE_TYPE (src)))
4943 src = gfc_build_addr_expr (pvoid_type_node, src);
4944 else
4945 src = fold_convert (pvoid_type_node, src);
4946
4947 len = fold_convert (size_type_node, len);
4948
4949 /* Construct call to __builtin_memcpy. */
389dd41b 4950 tmp = build_call_expr_loc (input_location,
4951 built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len);
538374c5 4952 return fold_convert (void_type_node, tmp);
4953}
4954
4955
1372ec9a 4956/* Try to efficiently translate dst(:) = src(:). Return NULL if this
4957 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
4958 source/rhs, both are gfc_full_array_ref_p which have been checked for
4959 dependencies. */
4ee9c684 4960
1372ec9a 4961static tree
4962gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
4963{
4964 tree dst, dlen, dtype;
4965 tree src, slen, stype;
db867224 4966 tree tmp;
1372ec9a 4967
4968 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
4969 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
4970
4971 dtype = TREE_TYPE (dst);
4972 if (POINTER_TYPE_P (dtype))
4973 dtype = TREE_TYPE (dtype);
4974 stype = TREE_TYPE (src);
4975 if (POINTER_TYPE_P (stype))
4976 stype = TREE_TYPE (stype);
4977
4978 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
4979 return NULL_TREE;
4980
4981 /* Determine the lengths of the arrays. */
4982 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
4983 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
4984 return NULL_TREE;
db867224 4985 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
1372ec9a 4986 dlen = fold_build2 (MULT_EXPR, gfc_array_index_type, dlen,
db867224 4987 fold_convert (gfc_array_index_type, tmp));
1372ec9a 4988
4989 slen = GFC_TYPE_ARRAY_SIZE (stype);
4990 if (!slen || TREE_CODE (slen) != INTEGER_CST)
4991 return NULL_TREE;
db867224 4992 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
1372ec9a 4993 slen = fold_build2 (MULT_EXPR, gfc_array_index_type, slen,
db867224 4994 fold_convert (gfc_array_index_type, tmp));
1372ec9a 4995
4996 /* Sanity check that they are the same. This should always be
4997 the case, as we should already have checked for conformance. */
4998 if (!tree_int_cst_equal (slen, dlen))
4999 return NULL_TREE;
5000
538374c5 5001 return gfc_build_memcpy_call (dst, src, dlen);
5002}
1372ec9a 5003
1372ec9a 5004
538374c5 5005/* Try to efficiently translate array(:) = (/ ... /). Return NULL if
5006 this can't be done. EXPR1 is the destination/lhs for which
5007 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
1372ec9a 5008
538374c5 5009static tree
5010gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
5011{
5012 unsigned HOST_WIDE_INT nelem;
5013 tree dst, dtype;
5014 tree src, stype;
5015 tree len;
db867224 5016 tree tmp;
538374c5 5017
5018 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
5019 if (nelem == 0)
5020 return NULL_TREE;
5021
5022 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
5023 dtype = TREE_TYPE (dst);
5024 if (POINTER_TYPE_P (dtype))
5025 dtype = TREE_TYPE (dtype);
5026 if (!GFC_ARRAY_TYPE_P (dtype))
5027 return NULL_TREE;
5028
5029 /* Determine the lengths of the array. */
5030 len = GFC_TYPE_ARRAY_SIZE (dtype);
5031 if (!len || TREE_CODE (len) != INTEGER_CST)
5032 return NULL_TREE;
5033
5034 /* Confirm that the constructor is the same size. */
5035 if (compare_tree_int (len, nelem) != 0)
5036 return NULL_TREE;
5037
db867224 5038 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
538374c5 5039 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
db867224 5040 fold_convert (gfc_array_index_type, tmp));
538374c5 5041
5042 stype = gfc_typenode_for_spec (&expr2->ts);
5043 src = gfc_build_constant_array_constructor (expr2, stype);
5044
5045 stype = TREE_TYPE (src);
5046 if (POINTER_TYPE_P (stype))
5047 stype = TREE_TYPE (stype);
5048
5049 return gfc_build_memcpy_call (dst, src, len);
1372ec9a 5050}
5051
5052
5053/* Subroutine of gfc_trans_assignment that actually scalarizes the
52f5c19d 5054 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS. */
1372ec9a 5055
5056static tree
5057gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
4ee9c684 5058{
5059 gfc_se lse;
5060 gfc_se rse;
5061 gfc_ss *lss;
5062 gfc_ss *lss_section;
5063 gfc_ss *rss;
5064 gfc_loopinfo loop;
5065 tree tmp;
5066 stmtblock_t block;
5067 stmtblock_t body;
2294b616 5068 bool l_is_temp;
8714fc76 5069 bool scalar_to_array;
bd619047 5070 tree string_length;
4ee9c684 5071
4ee9c684 5072 /* Assignment of the form lhs = rhs. */
5073 gfc_start_block (&block);
5074
5075 gfc_init_se (&lse, NULL);
5076 gfc_init_se (&rse, NULL);
5077
5078 /* Walk the lhs. */
5079 lss = gfc_walk_expr (expr1);
5080 rss = NULL;
5081 if (lss != gfc_ss_terminator)
5082 {
e2720a06 5083 /* Allow the scalarizer to workshare array assignments. */
5084 if (ompws_flags & OMPWS_WORKSHARE_FLAG)
5085 ompws_flags |= OMPWS_SCALARIZER_WS;
5086
4ee9c684 5087 /* The assignment needs scalarization. */
5088 lss_section = lss;
5089
5090 /* Find a non-scalar SS from the lhs. */
5091 while (lss_section != gfc_ss_terminator
5092 && lss_section->type != GFC_SS_SECTION)
5093 lss_section = lss_section->next;
5094
22d678e8 5095 gcc_assert (lss_section != gfc_ss_terminator);
4ee9c684 5096
5097 /* Initialize the scalarizer. */
5098 gfc_init_loopinfo (&loop);
5099
5100 /* Walk the rhs. */
5101 rss = gfc_walk_expr (expr2);
5102 if (rss == gfc_ss_terminator)
5103 {
5104 /* The rhs is scalar. Add a ss for the expression. */
5105 rss = gfc_get_ss ();
5106 rss->next = gfc_ss_terminator;
5107 rss->type = GFC_SS_SCALAR;
5108 rss->expr = expr2;
5109 }
5110 /* Associate the SS with the loop. */
5111 gfc_add_ss_to_loop (&loop, lss);
5112 gfc_add_ss_to_loop (&loop, rss);
5113
5114 /* Calculate the bounds of the scalarization. */
5115 gfc_conv_ss_startstride (&loop);
5116 /* Resolve any data dependencies in the statement. */
376a3611 5117 gfc_conv_resolve_dependencies (&loop, lss, rss);
4ee9c684 5118 /* Setup the scalarizing loops. */
92f4d1c4 5119 gfc_conv_loop_setup (&loop, &expr2->where);
4ee9c684 5120
5121 /* Setup the gfc_se structures. */
5122 gfc_copy_loopinfo_to_se (&lse, &loop);
5123 gfc_copy_loopinfo_to_se (&rse, &loop);
5124
5125 rse.ss = rss;
5126 gfc_mark_ss_chain_used (rss, 1);
5127 if (loop.temp_ss == NULL)
5128 {
5129 lse.ss = lss;
5130 gfc_mark_ss_chain_used (lss, 1);
5131 }
5132 else
5133 {
5134 lse.ss = loop.temp_ss;
5135 gfc_mark_ss_chain_used (lss, 3);
5136 gfc_mark_ss_chain_used (loop.temp_ss, 3);
5137 }
5138
5139 /* Start the scalarized loop body. */
5140 gfc_start_scalarized_body (&loop, &body);
5141 }
5142 else
5143 gfc_init_block (&body);
5144
2294b616 5145 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
5146
4ee9c684 5147 /* Translate the expression. */
5148 gfc_conv_expr (&rse, expr2);
5149
bd619047 5150 /* Stabilize a string length for temporaries. */
5151 if (expr2->ts.type == BT_CHARACTER)
5152 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
5153 else
5154 string_length = NULL_TREE;
5155
2294b616 5156 if (l_is_temp)
4ee9c684 5157 {
5158 gfc_conv_tmp_array_ref (&lse);
5159 gfc_advance_se_ss_chain (&lse);
bd619047 5160 if (expr2->ts.type == BT_CHARACTER)
5161 lse.string_length = string_length;
4ee9c684 5162 }
5163 else
5164 gfc_conv_expr (&lse, expr1);
544c333b 5165
8714fc76 5166 /* Assignments of scalar derived types with allocatable components
5167 to arrays must be done with a deep copy and the rhs temporary
5168 must have its components deallocated afterwards. */
5169 scalar_to_array = (expr2->ts.type == BT_DERIVED
eeebe20b 5170 && expr2->ts.u.derived->attr.alloc_comp
8714fc76 5171 && expr2->expr_type != EXPR_VARIABLE
5172 && !gfc_is_constant_expr (expr2)
5173 && expr1->rank && !expr2->rank);
5174 if (scalar_to_array)
5175 {
eeebe20b 5176 tmp = gfc_deallocate_alloc_comp (expr2->ts.u.derived, rse.expr, 0);
8714fc76 5177 gfc_add_expr_to_block (&loop.post, tmp);
5178 }
5179
b9cd8c56 5180 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5181 l_is_temp || init_flag,
8714fc76 5182 (expr2->expr_type == EXPR_VARIABLE)
5183 || scalar_to_array);
4ee9c684 5184 gfc_add_expr_to_block (&body, tmp);
5185
5186 if (lss == gfc_ss_terminator)
5187 {
5188 /* Use the scalar assignment as is. */
5189 gfc_add_block_to_block (&block, &body);
5190 }
5191 else
5192 {
22d678e8 5193 gcc_assert (lse.ss == gfc_ss_terminator
5194 && rse.ss == gfc_ss_terminator);
4ee9c684 5195
2294b616 5196 if (l_is_temp)
4ee9c684 5197 {
5198 gfc_trans_scalarized_loop_boundary (&loop, &body);
5199
5200 /* We need to copy the temporary to the actual lhs. */
5201 gfc_init_se (&lse, NULL);
5202 gfc_init_se (&rse, NULL);
5203 gfc_copy_loopinfo_to_se (&lse, &loop);
5204 gfc_copy_loopinfo_to_se (&rse, &loop);
5205
5206 rse.ss = loop.temp_ss;
5207 lse.ss = lss;
5208
5209 gfc_conv_tmp_array_ref (&rse);
5210 gfc_advance_se_ss_chain (&rse);
5211 gfc_conv_expr (&lse, expr1);
5212
22d678e8 5213 gcc_assert (lse.ss == gfc_ss_terminator
5214 && rse.ss == gfc_ss_terminator);
4ee9c684 5215
bd619047 5216 if (expr2->ts.type == BT_CHARACTER)
5217 rse.string_length = string_length;
5218
b9cd8c56 5219 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5220 false, false);
4ee9c684 5221 gfc_add_expr_to_block (&body, tmp);
5222 }
2294b616 5223
4ee9c684 5224 /* Generate the copying loops. */
5225 gfc_trans_scalarizing_loops (&loop, &body);
5226
5227 /* Wrap the whole thing up. */
5228 gfc_add_block_to_block (&block, &loop.pre);
5229 gfc_add_block_to_block (&block, &loop.post);
5230
5231 gfc_cleanup_loop (&loop);
5232 }
5233
5234 return gfc_finish_block (&block);
5235}
5236
1372ec9a 5237
62e711cd 5238/* Check whether EXPR is a copyable array. */
1372ec9a 5239
5240static bool
5241copyable_array_p (gfc_expr * expr)
5242{
62e711cd 5243 if (expr->expr_type != EXPR_VARIABLE)
5244 return false;
5245
1372ec9a 5246 /* First check it's an array. */
62e711cd 5247 if (expr->rank < 1 || !expr->ref || expr->ref->next)
5248 return false;
5249
8d60cc46 5250 if (!gfc_full_array_ref_p (expr->ref, NULL))
1372ec9a 5251 return false;
5252
5253 /* Next check that it's of a simple enough type. */
5254 switch (expr->ts.type)
5255 {
5256 case BT_INTEGER:
5257 case BT_REAL:
5258 case BT_COMPLEX:
5259 case BT_LOGICAL:
5260 return true;
5261
6fc8b651 5262 case BT_CHARACTER:
5263 return false;
5264
5265 case BT_DERIVED:
eeebe20b 5266 return !expr->ts.u.derived->attr.alloc_comp;
6fc8b651 5267
1372ec9a 5268 default:
5269 break;
5270 }
5271
5272 return false;
5273}
5274
5275/* Translate an assignment. */
5276
5277tree
5278gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
5279{
5280 tree tmp;
5281
5282 /* Special case a single function returning an array. */
5283 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5284 {
5285 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5286 if (tmp)
5287 return tmp;
5288 }
5289
5290 /* Special case assigning an array to zero. */
62e711cd 5291 if (copyable_array_p (expr1)
1372ec9a 5292 && is_zero_initializer_p (expr2))
5293 {
5294 tmp = gfc_trans_zero_assign (expr1);
5295 if (tmp)
5296 return tmp;
5297 }
5298
5299 /* Special case copying one array to another. */
62e711cd 5300 if (copyable_array_p (expr1)
1372ec9a 5301 && copyable_array_p (expr2)
1372ec9a 5302 && gfc_compare_types (&expr1->ts, &expr2->ts)
5303 && !gfc_check_dependency (expr1, expr2, 0))
5304 {
5305 tmp = gfc_trans_array_copy (expr1, expr2);
5306 if (tmp)
5307 return tmp;
5308 }
5309
538374c5 5310 /* Special case initializing an array from a constant array constructor. */
62e711cd 5311 if (copyable_array_p (expr1)
538374c5 5312 && expr2->expr_type == EXPR_ARRAY
5313 && gfc_compare_types (&expr1->ts, &expr2->ts))
5314 {
5315 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
5316 if (tmp)
5317 return tmp;
5318 }
5319
1372ec9a 5320 /* Fallback to the scalarizer to generate explicit loops. */
5321 return gfc_trans_assignment_1 (expr1, expr2, init_flag);
5322}
5323
b9cd8c56 5324tree
5325gfc_trans_init_assign (gfc_code * code)
5326{
578d3f19 5327 return gfc_trans_assignment (code->expr1, code->expr2, true);
b9cd8c56 5328}
5329
4ee9c684 5330tree
5331gfc_trans_assign (gfc_code * code)
5332{
578d3f19 5333 return gfc_trans_assignment (code->expr1, code->expr2, false);
4ee9c684 5334}
39f3dea0 5335
5336
5337/* Translate an assignment to a CLASS object
5338 (pointer or ordinary assignment). */
5339
5340tree
5341gfc_trans_class_assign (gfc_code *code)
5342{
5343 stmtblock_t block;
5344 tree tmp;
5345
5346 gfc_start_block (&block);
5347
5348 if (code->expr2->ts.type != BT_CLASS)
5349 {
5350 /* Insert an additional assignment which sets the '$vindex' field. */
5351 gfc_expr *lhs,*rhs;
5352 lhs = gfc_copy_expr (code->expr1);
5353 gfc_add_component_ref (lhs, "$vindex");
5354 if (code->expr2->ts.type == BT_DERIVED)
5355 /* vindex is constant, determined at compile time. */
5356 rhs = gfc_int_expr (code->expr2->ts.u.derived->vindex);
5357 else if (code->expr2->expr_type == EXPR_NULL)
5358 rhs = gfc_int_expr (0);
5359 else
5360 gcc_unreachable ();
5361 tmp = gfc_trans_assignment (lhs, rhs, false);
5362 gfc_add_expr_to_block (&block, tmp);
5363
5364 /* Insert another assignment which sets the '$size' field. */
5365 lhs = gfc_copy_expr (code->expr1);
5366 gfc_add_component_ref (lhs, "$size");
5367 if (code->expr2->ts.type == BT_DERIVED)
5368 {
5369 /* Size is fixed at compile time. */
5370 gfc_se lse;
5371 gfc_init_se (&lse, NULL);
5372 gfc_conv_expr (&lse, lhs);
5373 tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->expr2->ts));
5374 gfc_add_modify (&block, lse.expr,
5375 fold_convert (TREE_TYPE (lse.expr), tmp));
5376 }
5377 else if (code->expr2->expr_type == EXPR_NULL)
5378 {
5379 rhs = gfc_int_expr (0);
5380 tmp = gfc_trans_assignment (lhs, rhs, false);
5381 gfc_add_expr_to_block (&block, tmp);
5382 }
5383 else
5384 gcc_unreachable ();
5385
5386 gfc_free_expr (lhs);
5387 gfc_free_expr (rhs);
5388 }
5389
5390 /* Do the actual CLASS assignment. */
5391 if (code->expr2->ts.type == BT_CLASS)
5392 code->op = EXEC_ASSIGN;
5393 else
5394 gfc_add_component_ref (code->expr1, "$data");
5395
5396 if (code->op == EXEC_ASSIGN)
5397 tmp = gfc_trans_assign (code);
5398 else if (code->op == EXEC_POINTER_ASSIGN)
5399 tmp = gfc_trans_pointer_assign (code);
5400 else
5401 gcc_unreachable();
5402
5403 gfc_add_expr_to_block (&block, tmp);
5404
5405 return gfc_finish_block (&block);
5406}