]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans-expr.c
PR c++/42115
[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
8bedd8d9 2536/* The following routine generates code for the intrinsic
2537 procedures from the ISO_C_BINDING module:
2538 * C_LOC (function)
2539 * C_FUNLOC (function)
2540 * C_F_POINTER (subroutine)
2541 * C_F_PROCPOINTER (subroutine)
2542 * C_ASSOCIATED (function)
2543 One exception which is not handled here is C_F_POINTER with non-scalar
2544 arguments. Returns 1 if the call was replaced by inline code (else: 0). */
2545
2546static int
2547conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
2548 gfc_actual_arglist * arg)
2549{
2550 gfc_symbol *fsym;
2551 gfc_ss *argss;
2552
2553 if (sym->intmod_sym_id == ISOCBINDING_LOC)
2554 {
2555 if (arg->expr->rank == 0)
2556 gfc_conv_expr_reference (se, arg->expr);
2557 else
2558 {
2559 int f;
2560 /* This is really the actual arg because no formal arglist is
2561 created for C_LOC. */
2562 fsym = arg->expr->symtree->n.sym;
2563
2564 /* We should want it to do g77 calling convention. */
2565 f = (fsym != NULL)
2566 && !(fsym->attr.pointer || fsym->attr.allocatable)
2567 && fsym->as->type != AS_ASSUMED_SHAPE;
2568 f = f || !sym->attr.always_explicit;
2569
2570 argss = gfc_walk_expr (arg->expr);
2571 gfc_conv_array_parameter (se, arg->expr, argss, f,
2572 NULL, NULL, NULL);
2573 }
2574
2575 /* TODO -- the following two lines shouldn't be necessary, but if
2576 they're removed, a bug is exposed later in the code path.
2577 This workaround was thus introduced, but will have to be
2578 removed; please see PR 35150 for details about the issue. */
2579 se->expr = convert (pvoid_type_node, se->expr);
2580 se->expr = gfc_evaluate_now (se->expr, &se->pre);
2581
2582 return 1;
2583 }
2584 else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC)
2585 {
2586 arg->expr->ts.type = sym->ts.u.derived->ts.type;
2587 arg->expr->ts.f90_type = sym->ts.u.derived->ts.f90_type;
2588 arg->expr->ts.kind = sym->ts.u.derived->ts.kind;
2589 gfc_conv_expr_reference (se, arg->expr);
2590
2591 return 1;
2592 }
2593 else if ((sym->intmod_sym_id == ISOCBINDING_F_POINTER
2594 && arg->next->expr->rank == 0)
2595 || sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)
2596 {
2597 /* Convert c_f_pointer if fptr is a scalar
2598 and convert c_f_procpointer. */
2599 gfc_se cptrse;
2600 gfc_se fptrse;
2601
2602 gfc_init_se (&cptrse, NULL);
2603 gfc_conv_expr (&cptrse, arg->expr);
2604 gfc_add_block_to_block (&se->pre, &cptrse.pre);
2605 gfc_add_block_to_block (&se->post, &cptrse.post);
2606
2607 gfc_init_se (&fptrse, NULL);
2608 if (sym->intmod_sym_id == ISOCBINDING_F_POINTER
2609 || gfc_is_proc_ptr_comp (arg->next->expr, NULL))
2610 fptrse.want_pointer = 1;
2611
2612 gfc_conv_expr (&fptrse, arg->next->expr);
2613 gfc_add_block_to_block (&se->pre, &fptrse.pre);
2614 gfc_add_block_to_block (&se->post, &fptrse.post);
2615
2616 if (arg->next->expr->symtree->n.sym->attr.proc_pointer
2617 && arg->next->expr->symtree->n.sym->attr.dummy)
2618 fptrse.expr = build_fold_indirect_ref_loc (input_location,
2619 fptrse.expr);
2620
2621 se->expr = fold_build2 (MODIFY_EXPR, TREE_TYPE (fptrse.expr),
2622 fptrse.expr,
2623 fold_convert (TREE_TYPE (fptrse.expr),
2624 cptrse.expr));
2625
2626 return 1;
2627 }
2628 else if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
2629 {
2630 gfc_se arg1se;
2631 gfc_se arg2se;
2632
2633 /* Build the addr_expr for the first argument. The argument is
2634 already an *address* so we don't need to set want_pointer in
2635 the gfc_se. */
2636 gfc_init_se (&arg1se, NULL);
2637 gfc_conv_expr (&arg1se, arg->expr);
2638 gfc_add_block_to_block (&se->pre, &arg1se.pre);
2639 gfc_add_block_to_block (&se->post, &arg1se.post);
2640
2641 /* See if we were given two arguments. */
2642 if (arg->next == NULL)
2643 /* Only given one arg so generate a null and do a
2644 not-equal comparison against the first arg. */
2645 se->expr = fold_build2 (NE_EXPR, boolean_type_node, arg1se.expr,
2646 fold_convert (TREE_TYPE (arg1se.expr),
2647 null_pointer_node));
2648 else
2649 {
2650 tree eq_expr;
2651 tree not_null_expr;
2652
2653 /* Given two arguments so build the arg2se from second arg. */
2654 gfc_init_se (&arg2se, NULL);
2655 gfc_conv_expr (&arg2se, arg->next->expr);
2656 gfc_add_block_to_block (&se->pre, &arg2se.pre);
2657 gfc_add_block_to_block (&se->post, &arg2se.post);
2658
2659 /* Generate test to compare that the two args are equal. */
2660 eq_expr = fold_build2 (EQ_EXPR, boolean_type_node,
2661 arg1se.expr, arg2se.expr);
2662 /* Generate test to ensure that the first arg is not null. */
2663 not_null_expr = fold_build2 (NE_EXPR, boolean_type_node,
2664 arg1se.expr, null_pointer_node);
2665
2666 /* Finally, the generated test must check that both arg1 is not
2667 NULL and that it is equal to the second arg. */
2668 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2669 not_null_expr, eq_expr);
2670 }
2671
2672 return 1;
2673 }
2674
2675 /* Nothing was done. */
2676 return 0;
2677}
2678
2679
4ee9c684 2680/* Generate code for a procedure call. Note can return se->post != NULL.
079d21d5 2681 If se->direct_byref is set then se->expr contains the return parameter.
64e93293 2682 Return nonzero, if the call has alternate specifiers.
2683 'expr' is only needed for procedure pointer components. */
4ee9c684 2684
079d21d5 2685int
64e93293 2686gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
2687 gfc_actual_arglist * arg, gfc_expr * expr,
2688 tree append_args)
4ee9c684 2689{
08569428 2690 gfc_interface_mapping mapping;
4ee9c684 2691 tree arglist;
08569428 2692 tree retargs;
4ee9c684 2693 tree tmp;
2694 tree fntype;
2695 gfc_se parmse;
2696 gfc_ss *argss;
2697 gfc_ss_info *info;
2698 int byref;
2294b616 2699 int parm_kind;
4ee9c684 2700 tree type;
2701 tree var;
2702 tree len;
2703 tree stringargs;
2704 gfc_formal_arglist *formal;
079d21d5 2705 int has_alternate_specifier = 0;
08569428 2706 bool need_interface_mapping;
d4ef6f9d 2707 bool callee_alloc;
08569428 2708 gfc_typespec ts;
2709 gfc_charlen cl;
bd24f178 2710 gfc_expr *e;
2711 gfc_symbol *fsym;
10b07432 2712 stmtblock_t post;
2294b616 2713 enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
85d1c108 2714 gfc_component *comp = NULL;
4ee9c684 2715
2716 arglist = NULL_TREE;
08569428 2717 retargs = NULL_TREE;
4ee9c684 2718 stringargs = NULL_TREE;
2719 var = NULL_TREE;
2720 len = NULL_TREE;
52179f31 2721 gfc_clear_ts (&ts);
4ee9c684 2722
8bedd8d9 2723 if (sym->from_intmod == INTMOD_ISO_C_BINDING
2724 && conv_isocbinding_procedure (se, sym, arg))
2725 return 0;
ff70e443 2726
2727 gfc_is_proc_ptr_comp (expr, &comp);
2728
4ee9c684 2729 if (se->ss != NULL)
2730 {
2731 if (!sym->attr.elemental)
2732 {
22d678e8 2733 gcc_assert (se->ss->type == GFC_SS_FUNCTION);
4ee9c684 2734 if (se->ss->useflags)
2735 {
ff70e443 2736 gcc_assert ((!comp && gfc_return_by_reference (sym)
2737 && sym->result->attr.dimension)
2738 || (comp && comp->attr.dimension));
22d678e8 2739 gcc_assert (se->loop != NULL);
4ee9c684 2740
2741 /* Access the previously obtained result. */
2742 gfc_conv_tmp_array_ref (se);
2743 gfc_advance_se_ss_chain (se);
079d21d5 2744 return 0;
4ee9c684 2745 }
2746 }
2747 info = &se->ss->data.info;
2748 }
2749 else
2750 info = NULL;
2751
10b07432 2752 gfc_init_block (&post);
08569428 2753 gfc_init_interface_mapping (&mapping);
1d84f30a 2754 if (!comp)
2755 {
2756 formal = sym->formal;
2757 need_interface_mapping = sym->attr.dimension ||
2758 (sym->ts.type == BT_CHARACTER
2759 && sym->ts.u.cl->length
2760 && sym->ts.u.cl->length->expr_type
2761 != EXPR_CONSTANT);
2762 }
452a3743 2763 else
1d84f30a 2764 {
2765 formal = comp->formal;
2766 need_interface_mapping = comp->attr.dimension ||
2767 (comp->ts.type == BT_CHARACTER
2768 && comp->ts.u.cl->length
2769 && comp->ts.u.cl->length->expr_type
2770 != EXPR_CONSTANT);
2771 }
2772
4ee9c684 2773 /* Evaluate the arguments. */
2774 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
2775 {
bd24f178 2776 e = arg->expr;
2777 fsym = formal ? formal->sym : NULL;
2294b616 2778 parm_kind = MISSING;
bd24f178 2779 if (e == NULL)
4ee9c684 2780 {
2781
2782 if (se->ignore_optional)
2783 {
2784 /* Some intrinsics have already been resolved to the correct
2785 parameters. */
2786 continue;
2787 }
2788 else if (arg->label)
2789 {
2790 has_alternate_specifier = 1;
2791 continue;
2792 }
2793 else
2794 {
2795 /* Pass a NULL pointer for an absent arg. */
2796 gfc_init_se (&parmse, NULL);
2797 parmse.expr = null_pointer_node;
0fe9e56f 2798 if (arg->missing_arg_type == BT_CHARACTER)
7d3075f6 2799 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
4ee9c684 2800 }
2801 }
1de1b1a9 2802 else if (fsym && fsym->ts.type == BT_CLASS
2803 && e->ts.type == BT_DERIVED)
2804 {
2805 tree data;
2806 tree vindex;
39f3dea0 2807 tree size;
1de1b1a9 2808
2809 /* The derived type needs to be converted to a temporary
2810 CLASS object. */
2811 gfc_init_se (&parmse, se);
2812 type = gfc_typenode_for_spec (&fsym->ts);
2813 var = gfc_create_var (type, "class");
2814
2815 /* Get the components. */
2816 tmp = fsym->ts.u.derived->components->backend_decl;
2817 data = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
2818 var, tmp, NULL_TREE);
2819 tmp = fsym->ts.u.derived->components->next->backend_decl;
2820 vindex = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
39f3dea0 2821 var, tmp, NULL_TREE);
2822 tmp = fsym->ts.u.derived->components->next->next->backend_decl;
2823 size = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
1de1b1a9 2824 var, tmp, NULL_TREE);
2825
2826 /* Set the vindex. */
39f3dea0 2827 tmp = build_int_cst (TREE_TYPE (vindex), e->ts.u.derived->vindex);
1de1b1a9 2828 gfc_add_modify (&parmse.pre, vindex, tmp);
2829
39f3dea0 2830 /* Set the size. */
2831 tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&e->ts));
2832 gfc_add_modify (&parmse.pre, size,
2833 fold_convert (TREE_TYPE (size), tmp));
2834
1de1b1a9 2835 /* Now set the data field. */
2836 argss = gfc_walk_expr (e);
2837 if (argss == gfc_ss_terminator)
2838 {
2839 gfc_conv_expr_reference (&parmse, e);
2840 tmp = fold_convert (TREE_TYPE (data),
2841 parmse.expr);
2842 gfc_add_modify (&parmse.pre, data, tmp);
2843 }
2844 else
2845 {
2846 gfc_conv_expr (&parmse, e);
2847 gfc_add_modify (&parmse.pre, data, parmse.expr);
2848 }
2849
2850 /* Pass the address of the class object. */
2851 parmse.expr = gfc_build_addr_expr (NULL_TREE, var);
2852 }
4ee9c684 2853 else if (se->ss && se->ss->useflags)
2854 {
2855 /* An elemental function inside a scalarized loop. */
2856 gfc_init_se (&parmse, se);
bd24f178 2857 gfc_conv_expr_reference (&parmse, e);
2294b616 2858 parm_kind = ELEMENTAL;
4ee9c684 2859 }
2860 else
2861 {
2862 /* A scalar or transformational function. */
2863 gfc_init_se (&parmse, NULL);
bd24f178 2864 argss = gfc_walk_expr (e);
4ee9c684 2865
2866 if (argss == gfc_ss_terminator)
c5d33754 2867 {
623416e8 2868 if (e->expr_type == EXPR_VARIABLE
2869 && e->symtree->n.sym->attr.cray_pointee
2870 && fsym && fsym->attr.flavor == FL_PROCEDURE)
2871 {
2872 /* The Cray pointer needs to be converted to a pointer to
2873 a type given by the expression. */
2874 gfc_conv_expr (&parmse, e);
2875 type = build_pointer_type (TREE_TYPE (parmse.expr));
2876 tmp = gfc_get_symbol_decl (e->symtree->n.sym->cp_pointer);
2877 parmse.expr = convert (type, tmp);
2878 }
2879 else if (fsym && fsym->attr.value)
8f6339b6 2880 {
4c47c8b7 2881 if (fsym->ts.type == BT_CHARACTER
2882 && fsym->ts.is_c_interop
2883 && fsym->ns->proc_name != NULL
2884 && fsym->ns->proc_name->attr.is_bind_c)
2885 {
2886 parmse.expr = NULL;
2887 gfc_conv_scalar_char_value (fsym, &parmse, &e);
2888 if (parmse.expr == NULL)
2889 gfc_conv_expr (&parmse, e);
2890 }
2891 else
2892 gfc_conv_expr (&parmse, e);
8f6339b6 2893 }
8d7cdc4d 2894 else if (arg->name && arg->name[0] == '%')
2895 /* Argument list functions %VAL, %LOC and %REF are signalled
2896 through arg->name. */
2897 conv_arglist_function (&parmse, arg->expr, arg->name);
7f7ca309 2898 else if ((e->expr_type == EXPR_FUNCTION)
7035e057 2899 && ((e->value.function.esym
2900 && e->value.function.esym->result->attr.pointer)
2901 || (!e->value.function.esym
2902 && e->symtree->n.sym->attr.pointer))
2903 && fsym && fsym->attr.target)
7f7ca309 2904 {
2905 gfc_conv_expr (&parmse, e);
86f2ad37 2906 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
7f7ca309 2907 }
eee4a6d8 2908 else if (e->expr_type == EXPR_FUNCTION
2909 && e->symtree->n.sym->result
0fd53ac9 2910 && e->symtree->n.sym->result != e->symtree->n.sym
eee4a6d8 2911 && e->symtree->n.sym->result->attr.proc_pointer)
2912 {
2913 /* Functions returning procedure pointers. */
2914 gfc_conv_expr (&parmse, e);
2915 if (fsym && fsym->attr.proc_pointer)
2916 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
2917 }
8f6339b6 2918 else
2919 {
2920 gfc_conv_expr_reference (&parmse, e);
5176859a 2921
2922 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
2923 allocated on entry, it must be deallocated. */
2924 if (fsym && fsym->attr.allocatable
2925 && fsym->attr.intent == INTENT_OUT)
2926 {
2927 stmtblock_t block;
2928
2929 gfc_init_block (&block);
2930 tmp = gfc_deallocate_with_status (parmse.expr, NULL_TREE,
2931 true, NULL);
2932 gfc_add_expr_to_block (&block, tmp);
2933 tmp = fold_build2 (MODIFY_EXPR, void_type_node,
2934 parmse.expr, null_pointer_node);
2935 gfc_add_expr_to_block (&block, tmp);
2936
2937 if (fsym->attr.optional
2938 && e->expr_type == EXPR_VARIABLE
2939 && e->symtree->n.sym->attr.optional)
2940 {
2941 tmp = fold_build3 (COND_EXPR, void_type_node,
2942 gfc_conv_expr_present (e->symtree->n.sym),
2943 gfc_finish_block (&block),
2944 build_empty_stmt (input_location));
2945 }
2946 else
2947 tmp = gfc_finish_block (&block);
2948
2949 gfc_add_expr_to_block (&se->pre, tmp);
2950 }
2951
cad0ddcf 2952 if (fsym && e->expr_type != EXPR_NULL
2953 && ((fsym->attr.pointer
2954 && fsym->attr.flavor != FL_PROCEDURE)
4651cfdd 2955 || (fsym->attr.proc_pointer
2956 && !(e->expr_type == EXPR_VARIABLE
cf046737 2957 && e->symtree->n.sym->attr.dummy))
0fd53ac9 2958 || (e->expr_type == EXPR_VARIABLE
5176859a 2959 && gfc_is_proc_ptr_comp (e, NULL))
2960 || fsym->attr.allocatable))
8f6339b6 2961 {
2962 /* Scalar pointer dummy args require an extra level of
2963 indirection. The null pointer already contains
2964 this level of indirection. */
2965 parm_kind = SCALAR_POINTER;
86f2ad37 2966 parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
8f6339b6 2967 }
2968 }
2969 }
4ee9c684 2970 else
2971 {
7d19e94d 2972 /* If the procedure requires an explicit interface, the actual
2973 argument is passed according to the corresponding formal
2974 argument. If the corresponding formal argument is a POINTER,
2975 ALLOCATABLE or assumed shape, we do not use g77's calling
2976 convention, and pass the address of the array descriptor
2977 instead. Otherwise we use g77's calling convention. */
4ee9c684 2978 int f;
bd24f178 2979 f = (fsym != NULL)
2980 && !(fsym->attr.pointer || fsym->attr.allocatable)
2981 && fsym->as->type != AS_ASSUMED_SHAPE;
4ee9c684 2982 f = f || !sym->attr.always_explicit;
35d9c496 2983
bd24f178 2984 if (e->expr_type == EXPR_VARIABLE
1033248c 2985 && is_subref_array (e))
858f9894 2986 /* The actual argument is a component reference to an
2987 array of derived types. In this case, the argument
2988 is converted to a temporary, which is passed and then
2989 written back after the procedure call. */
1033248c 2990 gfc_conv_subref_array_arg (&parmse, e, f,
b8a51d79 2991 fsym ? fsym->attr.intent : INTENT_INOUT);
858f9894 2992 else
da6ffc6d 2993 gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
bc56d052 2994 sym->name, NULL);
ab19f982 2995
d99419eb 2996 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
2997 allocated on entry, it must be deallocated. */
2998 if (fsym && fsym->attr.allocatable
2999 && fsym->attr.intent == INTENT_OUT)
3000 {
3001 tmp = build_fold_indirect_ref_loc (input_location,
3002 parmse.expr);
3003 tmp = gfc_trans_dealloc_allocated (tmp);
3004 if (fsym->attr.optional
3005 && e->expr_type == EXPR_VARIABLE
3006 && e->symtree->n.sym->attr.optional)
3007 tmp = fold_build3 (COND_EXPR, void_type_node,
3008 gfc_conv_expr_present (e->symtree->n.sym),
3009 tmp, build_empty_stmt (input_location));
3010 gfc_add_expr_to_block (&se->pre, tmp);
3011 }
4ee9c684 3012 }
3013 }
3014
3d3b790d 3015 /* The case with fsym->attr.optional is that of a user subroutine
3016 with an interface indicating an optional argument. When we call
3017 an intrinsic subroutine, however, fsym is NULL, but we might still
3018 have an optional argument, so we proceed to the substitution
3019 just in case. */
3020 if (e && (fsym == NULL || fsym->attr.optional))
d45fced7 3021 {
3d3b790d 3022 /* If an optional argument is itself an optional dummy argument,
d99419eb 3023 check its presence and substitute a null if absent. This is
3024 only needed when passing an array to an elemental procedure
3025 as then array elements are accessed - or no NULL pointer is
3026 allowed and a "1" or "0" should be passed if not present.
b460b386 3027 When passing a non-array-descriptor full array to a
3028 non-array-descriptor dummy, no check is needed. For
3029 array-descriptor actual to array-descriptor dummy, see
3030 PR 41911 for why a check has to be inserted.
3031 fsym == NULL is checked as intrinsics required the descriptor
3032 but do not always set fsym. */
3d3b790d 3033 if (e->expr_type == EXPR_VARIABLE
d99419eb 3034 && e->symtree->n.sym->attr.optional
3035 && ((e->rank > 0 && sym->attr.elemental)
3036 || e->representation.length || e->ts.type == BT_CHARACTER
b460b386 3037 || (e->rank > 0
3038 && (fsym == NULL || fsym->as->type == AS_ASSUMED_SHAPE
3039 || fsym->as->type == AS_DEFERRED))))
2abe085f 3040 gfc_conv_missing_dummy (&parmse, e, fsym ? fsym->ts : e->ts,
3041 e->representation.length);
3d3b790d 3042 }
3043
3044 if (fsym && e)
3045 {
3046 /* Obtain the character length of an assumed character length
3047 length procedure from the typespec. */
3048 if (fsym->ts.type == BT_CHARACTER
3049 && parmse.string_length == NULL_TREE
3050 && e->ts.type == BT_PROCEDURE
3051 && e->symtree->n.sym->ts.type == BT_CHARACTER
eeebe20b 3052 && e->symtree->n.sym->ts.u.cl->length != NULL
3053 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
d45fced7 3054 {
eeebe20b 3055 gfc_conv_const_charlen (e->symtree->n.sym->ts.u.cl);
3056 parmse.string_length = e->symtree->n.sym->ts.u.cl->backend_decl;
d45fced7 3057 }
d45fced7 3058 }
08569428 3059
079d3acc 3060 if (fsym && need_interface_mapping && e)
fd149f95 3061 gfc_add_interface_mapping (&mapping, fsym, &parmse, e);
3d3b790d 3062
4ee9c684 3063 gfc_add_block_to_block (&se->pre, &parmse.pre);
10b07432 3064 gfc_add_block_to_block (&post, &parmse.post);
4ee9c684 3065
2294b616 3066 /* Allocated allocatable components of derived types must be
8714fc76 3067 deallocated for non-variable scalars. Non-variable arrays are
3068 dealt with in trans-array.c(gfc_conv_array_parameter). */
2294b616 3069 if (e && e->ts.type == BT_DERIVED
eeebe20b 3070 && e->ts.u.derived->attr.alloc_comp
cc2f46ba 3071 && !(e->symtree && e->symtree->n.sym->attr.pointer)
8714fc76 3072 && (e->expr_type != EXPR_VARIABLE && !e->rank))
2294b616 3073 {
3074 int parm_rank;
389dd41b 3075 tmp = build_fold_indirect_ref_loc (input_location,
3076 parmse.expr);
2294b616 3077 parm_rank = e->rank;
3078 switch (parm_kind)
3079 {
3080 case (ELEMENTAL):
3081 case (SCALAR):
3082 parm_rank = 0;
3083 break;
3084
3085 case (SCALAR_POINTER):
389dd41b 3086 tmp = build_fold_indirect_ref_loc (input_location,
3087 tmp);
2294b616 3088 break;
2294b616 3089 }
3090
e5387fb9 3091 if (e->expr_type == EXPR_OP
3092 && e->value.op.op == INTRINSIC_PARENTHESES
3093 && e->value.op.op1->expr_type == EXPR_VARIABLE)
3094 {
3095 tree local_tmp;
3096 local_tmp = gfc_evaluate_now (tmp, &se->pre);
eeebe20b 3097 local_tmp = gfc_copy_alloc_comp (e->ts.u.derived, local_tmp, tmp, parm_rank);
e5387fb9 3098 gfc_add_expr_to_block (&se->post, local_tmp);
3099 }
3100
eeebe20b 3101 tmp = gfc_deallocate_alloc_comp (e->ts.u.derived, tmp, parm_rank);
e5387fb9 3102
8714fc76 3103 gfc_add_expr_to_block (&se->post, tmp);
2294b616 3104 }
3105
91cf6ba3 3106 /* Add argument checking of passing an unallocated/NULL actual to
3107 a nonallocatable/nonpointer dummy. */
3108
40474135 3109 if (gfc_option.rtcheck & GFC_RTCHECK_POINTER && e != NULL)
91cf6ba3 3110 {
40474135 3111 symbol_attribute *attr;
91cf6ba3 3112 char *msg;
3113 tree cond;
3114
3115 if (e->expr_type == EXPR_VARIABLE)
40474135 3116 attr = &e->symtree->n.sym->attr;
91cf6ba3 3117 else if (e->expr_type == EXPR_FUNCTION)
40474135 3118 {
3119 /* For intrinsic functions, the gfc_attr are not available. */
3120 if (e->symtree->n.sym->attr.generic && e->value.function.isym)
3121 goto end_pointer_check;
91cf6ba3 3122
40474135 3123 if (e->symtree->n.sym->attr.generic)
3124 attr = &e->value.function.esym->attr;
3125 else
3126 attr = &e->symtree->n.sym->result->attr;
3127 }
91cf6ba3 3128 else
3129 goto end_pointer_check;
3130
40474135 3131 if (attr->optional)
3132 {
3133 /* If the actual argument is an optional pointer/allocatable and
3134 the formal argument takes an nonpointer optional value,
3135 it is invalid to pass a non-present argument on, even
3136 though there is no technical reason for this in gfortran.
3137 See Fortran 2003, Section 12.4.1.6 item (7)+(8). */
3138 tree present, nullptr, type;
3139
3140 if (attr->allocatable
3141 && (fsym == NULL || !fsym->attr.allocatable))
3142 asprintf (&msg, "Allocatable actual argument '%s' is not "
3143 "allocated or not present", e->symtree->n.sym->name);
3144 else if (attr->pointer
3145 && (fsym == NULL || !fsym->attr.pointer))
3146 asprintf (&msg, "Pointer actual argument '%s' is not "
3147 "associated or not present",
3148 e->symtree->n.sym->name);
3149 else if (attr->proc_pointer
3150 && (fsym == NULL || !fsym->attr.proc_pointer))
3151 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3152 "associated or not present",
3153 e->symtree->n.sym->name);
3154 else
3155 goto end_pointer_check;
3156
3157 present = gfc_conv_expr_present (e->symtree->n.sym);
3158 type = TREE_TYPE (present);
3159 present = fold_build2 (EQ_EXPR, boolean_type_node, present,
3160 fold_convert (type, null_pointer_node));
3161 type = TREE_TYPE (parmse.expr);
3162 nullptr = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3163 fold_convert (type, null_pointer_node));
3164 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node,
3165 present, nullptr);
3166 }
3167 else
3168 {
3169 if (attr->allocatable
3170 && (fsym == NULL || !fsym->attr.allocatable))
3171 asprintf (&msg, "Allocatable actual argument '%s' is not "
3172 "allocated", e->symtree->n.sym->name);
3173 else if (attr->pointer
3174 && (fsym == NULL || !fsym->attr.pointer))
3175 asprintf (&msg, "Pointer actual argument '%s' is not "
3176 "associated", e->symtree->n.sym->name);
3177 else if (attr->proc_pointer
3178 && (fsym == NULL || !fsym->attr.proc_pointer))
3179 asprintf (&msg, "Proc-pointer actual argument '%s' is not "
3180 "associated", e->symtree->n.sym->name);
3181 else
3182 goto end_pointer_check;
3183
3184
3185 cond = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
3186 fold_convert (TREE_TYPE (parmse.expr),
3187 null_pointer_node));
3188 }
91cf6ba3 3189
3190 gfc_trans_runtime_check (true, false, cond, &se->pre, &e->where,
3191 msg);
3192 gfc_free (msg);
3193 }
3194 end_pointer_check:
3195
3196
7b3423b9 3197 /* Character strings are passed as two parameters, a length and a
465e4a95 3198 pointer - except for Bind(c) which only passes the pointer. */
3199 if (parmse.string_length != NULL_TREE && !sym->attr.is_bind_c)
4ee9c684 3200 stringargs = gfc_chainon_list (stringargs, parmse.string_length);
3201
3202 arglist = gfc_chainon_list (arglist, parmse.expr);
3203 }
08569428 3204 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
3205
1d84f30a 3206 if (comp)
3207 ts = comp->ts;
3208 else
3209 ts = sym->ts;
3210
ff2093c8 3211 if (ts.type == BT_CHARACTER && sym->attr.is_bind_c)
3212 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
3213 else if (ts.type == BT_CHARACTER)
08569428 3214 {
1d84f30a 3215 if (ts.u.cl->length == NULL)
5e8cd291 3216 {
3217 /* Assumed character length results are not allowed by 5.1.1.5 of the
3218 standard and are trapped in resolve.c; except in the case of SPREAD
cce7ac71 3219 (and other intrinsics?) and dummy functions. In the case of SPREAD,
3220 we take the character length of the first argument for the result.
3221 For dummies, we have to look through the formal argument list for
3222 this function and use the character length found there.*/
3223 if (!sym->attr.dummy)
3224 cl.backend_decl = TREE_VALUE (stringargs);
3225 else
3226 {
3227 formal = sym->ns->proc_name->formal;
3228 for (; formal; formal = formal->next)
3229 if (strcmp (formal->sym->name, sym->name) == 0)
eeebe20b 3230 cl.backend_decl = formal->sym->ts.u.cl->backend_decl;
cce7ac71 3231 }
3232 }
5176859a 3233 else
cce7ac71 3234 {
a0ab480a 3235 tree tmp;
3236
5e8cd291 3237 /* Calculate the length of the returned string. */
3238 gfc_init_se (&parmse, NULL);
3239 if (need_interface_mapping)
1d84f30a 3240 gfc_apply_interface_mapping (&mapping, &parmse, ts.u.cl->length);
5e8cd291 3241 else
1d84f30a 3242 gfc_conv_expr (&parmse, ts.u.cl->length);
5e8cd291 3243 gfc_add_block_to_block (&se->pre, &parmse.pre);
3244 gfc_add_block_to_block (&se->post, &parmse.post);
a0ab480a 3245
3246 tmp = fold_convert (gfc_charlen_type_node, parmse.expr);
3247 tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
3248 build_int_cst (gfc_charlen_type_node, 0));
3249 cl.backend_decl = tmp;
5e8cd291 3250 }
08569428 3251
3252 /* Set up a charlen structure for it. */
3253 cl.next = NULL;
3254 cl.length = NULL;
eeebe20b 3255 ts.u.cl = &cl;
08569428 3256
3257 len = cl.backend_decl;
3258 }
08569428 3259
1d84f30a 3260 byref = (comp && (comp->attr.dimension || comp->ts.type == BT_CHARACTER))
85d1c108 3261 || (!comp && gfc_return_by_reference (sym));
08569428 3262 if (byref)
3263 {
3264 if (se->direct_byref)
67135eee 3265 {
69b1505f 3266 /* Sometimes, too much indirection can be applied; e.g. for
67135eee 3267 function_result = array_valued_recursive_function. */
3268 if (TREE_TYPE (TREE_TYPE (se->expr))
3269 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
3270 && GFC_DESCRIPTOR_TYPE_P
3271 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))))
389dd41b 3272 se->expr = build_fold_indirect_ref_loc (input_location,
3273 se->expr);
67135eee 3274
3275 retargs = gfc_chainon_list (retargs, se->expr);
3276 }
ff70e443 3277 else if (comp && comp->attr.dimension)
3278 {
3279 gcc_assert (se->loop && info);
3280
3281 /* Set the type of the array. */
3282 tmp = gfc_typenode_for_spec (&comp->ts);
3283 info->dimen = se->loop->dimen;
3284
3285 /* Evaluate the bounds of the result, if known. */
3286 gfc_set_loop_bounds_from_array_spec (&mapping, se, comp->as);
3287
3288 /* Create a temporary to store the result. In case the function
3289 returns a pointer, the temporary will be a shallow copy and
3290 mustn't be deallocated. */
3291 callee_alloc = comp->attr.allocatable || comp->attr.pointer;
3292 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
3293 NULL_TREE, false, !comp->attr.pointer,
3294 callee_alloc, &se->ss->expr->where);
3295
3296 /* Pass the temporary as the first argument. */
3297 tmp = info->descriptor;
3298 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
3299 retargs = gfc_chainon_list (retargs, tmp);
3300 }
1d84f30a 3301 else if (!comp && sym->result->attr.dimension)
08569428 3302 {
3303 gcc_assert (se->loop && info);
3304
3305 /* Set the type of the array. */
3306 tmp = gfc_typenode_for_spec (&ts);
3307 info->dimen = se->loop->dimen;
3308
f45a476e 3309 /* Evaluate the bounds of the result, if known. */
3310 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
3311
d4ef6f9d 3312 /* Create a temporary to store the result. In case the function
3313 returns a pointer, the temporary will be a shallow copy and
3314 mustn't be deallocated. */
3315 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
3316 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
7a2a9daf 3317 NULL_TREE, false, !sym->attr.pointer,
3318 callee_alloc, &se->ss->expr->where);
08569428 3319
08569428 3320 /* Pass the temporary as the first argument. */
3321 tmp = info->descriptor;
86f2ad37 3322 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
08569428 3323 retargs = gfc_chainon_list (retargs, tmp);
3324 }
3325 else if (ts.type == BT_CHARACTER)
3326 {
3327 /* Pass the string length. */
eeebe20b 3328 type = gfc_get_character_type (ts.kind, ts.u.cl);
08569428 3329 type = build_pointer_type (type);
3330
3331 /* Return an address to a char[0:len-1]* temporary for
3332 character pointers. */
1d84f30a 3333 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3334 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
08569428 3335 {
eeaa887f 3336 var = gfc_create_var (type, "pstr");
08569428 3337
3338 /* Provide an address expression for the function arguments. */
86f2ad37 3339 var = gfc_build_addr_expr (NULL_TREE, var);
08569428 3340 }
3341 else
3342 var = gfc_conv_string_tmp (se, type, len);
3343
3344 retargs = gfc_chainon_list (retargs, var);
3345 }
3346 else
3347 {
3348 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
3349
3350 type = gfc_get_complex_type (ts.kind);
86f2ad37 3351 var = gfc_build_addr_expr (NULL_TREE, gfc_create_var (type, "cmplx"));
08569428 3352 retargs = gfc_chainon_list (retargs, var);
3353 }
3354
3355 /* Add the string length to the argument list. */
3356 if (ts.type == BT_CHARACTER)
3357 retargs = gfc_chainon_list (retargs, len);
3358 }
f45a476e 3359 gfc_free_interface_mapping (&mapping);
08569428 3360
3361 /* Add the return arguments. */
3362 arglist = chainon (retargs, arglist);
4ee9c684 3363
3364 /* Add the hidden string length parameters to the arguments. */
3365 arglist = chainon (arglist, stringargs);
3366
4e8e57b0 3367 /* We may want to append extra arguments here. This is used e.g. for
3368 calls to libgfortran_matmul_??, which need extra information. */
3369 if (append_args != NULL_TREE)
3370 arglist = chainon (arglist, append_args);
3371
4ee9c684 3372 /* Generate the actual call. */
64e93293 3373 conv_function_val (se, sym, expr);
57dd95f2 3374
4ee9c684 3375 /* If there are alternate return labels, function type should be
079d21d5 3376 integer. Can't modify the type in place though, since it can be shared
57dd95f2 3377 with other functions. For dummy arguments, the typing is done to
3378 to this result, even if it has to be repeated for each call. */
079d21d5 3379 if (has_alternate_specifier
3380 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
3381 {
57dd95f2 3382 if (!sym->attr.dummy)
3383 {
3384 TREE_TYPE (sym->backend_decl)
3385 = build_function_type (integer_type_node,
3386 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
86f2ad37 3387 se->expr = gfc_build_addr_expr (NULL_TREE, sym->backend_decl);
57dd95f2 3388 }
3389 else
3390 TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
079d21d5 3391 }
4ee9c684 3392
3393 fntype = TREE_TYPE (TREE_TYPE (se->expr));
c2f47e15 3394 se->expr = build_call_list (TREE_TYPE (fntype), se->expr, arglist);
4ee9c684 3395
fa069004 3396 /* If we have a pointer function, but we don't want a pointer, e.g.
3397 something like
3398 x = f()
3399 where f is pointer valued, we have to dereference the result. */
64e93293 3400 if (!se->want_pointer && !byref && sym->attr.pointer
ff70e443 3401 && !gfc_is_proc_ptr_comp (expr, NULL))
389dd41b 3402 se->expr = build_fold_indirect_ref_loc (input_location,
3403 se->expr);
fa069004 3404
bdaed7d2 3405 /* f2c calling conventions require a scalar default real function to
3406 return a double precision result. Convert this back to default
3407 real. We only care about the cases that can happen in Fortran 77.
3408 */
3409 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
3410 && sym->ts.kind == gfc_default_real_kind
3411 && !sym->attr.always_explicit)
3412 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
3413
f888a3fb 3414 /* A pure function may still have side-effects - it may modify its
3415 parameters. */
4ee9c684 3416 TREE_SIDE_EFFECTS (se->expr) = 1;
3417#if 0
3418 if (!sym->attr.pure)
3419 TREE_SIDE_EFFECTS (se->expr) = 1;
3420#endif
3421
4396343e 3422 if (byref)
4ee9c684 3423 {
4396343e 3424 /* Add the function call to the pre chain. There is no expression. */
4ee9c684 3425 gfc_add_expr_to_block (&se->pre, se->expr);
4396343e 3426 se->expr = NULL_TREE;
4ee9c684 3427
4396343e 3428 if (!se->direct_byref)
4ee9c684 3429 {
ff70e443 3430 if (sym->attr.dimension || (comp && comp->attr.dimension))
4ee9c684 3431 {
ad8ed98e 3432 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
4396343e 3433 {
3434 /* Check the data pointer hasn't been modified. This would
3435 happen in a function returning a pointer. */
94be45c9 3436 tmp = gfc_conv_descriptor_data_get (info->descriptor);
0eed5ee7 3437 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3438 tmp, info->data);
da6ffc6d 3439 gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
3440 gfc_msg_fault);
4396343e 3441 }
3442 se->expr = info->descriptor;
bf7e666b 3443 /* Bundle in the string length. */
3444 se->string_length = len;
4ee9c684 3445 }
1d84f30a 3446 else if (ts.type == BT_CHARACTER)
544c333b 3447 {
bf7e666b 3448 /* Dereference for character pointer results. */
1d84f30a 3449 if ((!comp && (sym->attr.pointer || sym->attr.allocatable))
3450 || (comp && (comp->attr.pointer || comp->attr.allocatable)))
3451 se->expr = build_fold_indirect_ref_loc (input_location, var);
544c333b 3452 else
bf7e666b 3453 se->expr = var;
3454
4396343e 3455 se->string_length = len;
3456 }
3457 else
bdaed7d2 3458 {
1d84f30a 3459 gcc_assert (ts.type == BT_COMPLEX && gfc_option.flag_f2c);
3460 se->expr = build_fold_indirect_ref_loc (input_location, var);
bdaed7d2 3461 }
4ee9c684 3462 }
4ee9c684 3463 }
079d21d5 3464
10b07432 3465 /* Follow the function call with the argument post block. */
3466 if (byref)
3467 gfc_add_block_to_block (&se->pre, &post);
3468 else
3469 gfc_add_block_to_block (&se->post, &post);
3470
079d21d5 3471 return has_alternate_specifier;
4ee9c684 3472}
3473
3474
b44437b9 3475/* Fill a character string with spaces. */
3476
3477static tree
3478fill_with_spaces (tree start, tree type, tree size)
3479{
3480 stmtblock_t block, loop;
3481 tree i, el, exit_label, cond, tmp;
3482
3483 /* For a simple char type, we can call memset(). */
3484 if (compare_tree_int (TYPE_SIZE_UNIT (type), 1) == 0)
389dd41b 3485 return build_call_expr_loc (input_location,
3486 built_in_decls[BUILT_IN_MEMSET], 3, start,
b44437b9 3487 build_int_cst (gfc_get_int_type (gfc_c_int_kind),
3488 lang_hooks.to_target_charset (' ')),
3489 size);
3490
3491 /* Otherwise, we use a loop:
3492 for (el = start, i = size; i > 0; el--, i+= TYPE_SIZE_UNIT (type))
3493 *el = (type) ' ';
3494 */
3495
3496 /* Initialize variables. */
3497 gfc_init_block (&block);
3498 i = gfc_create_var (sizetype, "i");
75a70cf9 3499 gfc_add_modify (&block, i, fold_convert (sizetype, size));
b44437b9 3500 el = gfc_create_var (build_pointer_type (type), "el");
75a70cf9 3501 gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
b44437b9 3502 exit_label = gfc_build_label_decl (NULL_TREE);
3503 TREE_USED (exit_label) = 1;
3504
3505
3506 /* Loop body. */
3507 gfc_init_block (&loop);
3508
3509 /* Exit condition. */
3510 cond = fold_build2 (LE_EXPR, boolean_type_node, i,
3511 fold_convert (sizetype, integer_zero_node));
3512 tmp = build1_v (GOTO_EXPR, exit_label);
e60a6f7b 3513 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3514 build_empty_stmt (input_location));
b44437b9 3515 gfc_add_expr_to_block (&loop, tmp);
3516
3517 /* Assignment. */
75a70cf9 3518 gfc_add_modify (&loop, fold_build1 (INDIRECT_REF, type, el),
b44437b9 3519 build_int_cst (type,
3520 lang_hooks.to_target_charset (' ')));
3521
3522 /* Increment loop variables. */
75a70cf9 3523 gfc_add_modify (&loop, i, fold_build2 (MINUS_EXPR, sizetype, i,
b44437b9 3524 TYPE_SIZE_UNIT (type)));
75a70cf9 3525 gfc_add_modify (&loop, el, fold_build2 (POINTER_PLUS_EXPR,
b44437b9 3526 TREE_TYPE (el), el,
3527 TYPE_SIZE_UNIT (type)));
3528
3529 /* Making the loop... actually loop! */
3530 tmp = gfc_finish_block (&loop);
3531 tmp = build1_v (LOOP_EXPR, tmp);
3532 gfc_add_expr_to_block (&block, tmp);
3533
3534 /* The exit label. */
3535 tmp = build1_v (LABEL_EXPR, exit_label);
3536 gfc_add_expr_to_block (&block, tmp);
3537
3538
3539 return gfc_finish_block (&block);
3540}
3541
3542
dbe60343 3543/* Generate code to copy a string. */
3544
88137677 3545void
72038310 3546gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
b44437b9 3547 int dkind, tree slength, tree src, int skind)
dbe60343 3548{
72038310 3549 tree tmp, dlen, slen;
77100724 3550 tree dsc;
3551 tree ssc;
2810b378 3552 tree cond;
59b9dcbd 3553 tree cond2;
3554 tree tmp2;
3555 tree tmp3;
3556 tree tmp4;
b44437b9 3557 tree chartype;
59b9dcbd 3558 stmtblock_t tempblock;
77100724 3559
b44437b9 3560 gcc_assert (dkind == skind);
3561
891beb95 3562 if (slength != NULL_TREE)
3563 {
3564 slen = fold_convert (size_type_node, gfc_evaluate_now (slength, block));
b44437b9 3565 ssc = string_to_single_character (slen, src, skind);
891beb95 3566 }
3567 else
3568 {
3569 slen = build_int_cst (size_type_node, 1);
3570 ssc = src;
3571 }
3572
3573 if (dlength != NULL_TREE)
3574 {
3575 dlen = fold_convert (size_type_node, gfc_evaluate_now (dlength, block));
b44437b9 3576 dsc = string_to_single_character (slen, dest, dkind);
891beb95 3577 }
3578 else
3579 {
3580 dlen = build_int_cst (size_type_node, 1);
3581 dsc = dest;
3582 }
3583
3584 if (slength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (src)))
b44437b9 3585 ssc = string_to_single_character (slen, src, skind);
891beb95 3586 if (dlength != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (dest)))
b44437b9 3587 dsc = string_to_single_character (dlen, dest, dkind);
891beb95 3588
72038310 3589
680e3123 3590 /* Assign directly if the types are compatible. */
3591 if (dsc != NULL_TREE && ssc != NULL_TREE
b44437b9 3592 && TREE_TYPE (dsc) == TREE_TYPE (ssc))
77100724 3593 {
75a70cf9 3594 gfc_add_modify (block, dsc, ssc);
77100724 3595 return;
3596 }
dbe60343 3597
59b9dcbd 3598 /* Do nothing if the destination length is zero. */
2810b378 3599 cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
57e3c827 3600 build_int_cst (size_type_node, 0));
2810b378 3601
59b9dcbd 3602 /* The following code was previously in _gfortran_copy_string:
3603
3604 // The two strings may overlap so we use memmove.
3605 void
3606 copy_string (GFC_INTEGER_4 destlen, char * dest,
3607 GFC_INTEGER_4 srclen, const char * src)
3608 {
3609 if (srclen >= destlen)
3610 {
3611 // This will truncate if too long.
3612 memmove (dest, src, destlen);
3613 }
3614 else
3615 {
3616 memmove (dest, src, srclen);
3617 // Pad with spaces.
3618 memset (&dest[srclen], ' ', destlen - srclen);
3619 }
3620 }
3621
3622 We're now doing it here for better optimization, but the logic
3623 is the same. */
ceeda734 3624
b44437b9 3625 /* For non-default character kinds, we have to multiply the string
3626 length by the base type size. */
3627 chartype = gfc_get_char_type (dkind);
abb1d33a 3628 slen = fold_build2 (MULT_EXPR, size_type_node,
3629 fold_convert (size_type_node, slen),
3630 fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
3631 dlen = fold_build2 (MULT_EXPR, size_type_node,
3632 fold_convert (size_type_node, dlen),
3633 fold_convert (size_type_node, TYPE_SIZE_UNIT (chartype)));
b44437b9 3634
891beb95 3635 if (dlength)
3636 dest = fold_convert (pvoid_type_node, dest);
3637 else
3638 dest = gfc_build_addr_expr (pvoid_type_node, dest);
3639
3640 if (slength)
3641 src = fold_convert (pvoid_type_node, src);
3642 else
3643 src = gfc_build_addr_expr (pvoid_type_node, src);
ceeda734 3644
59b9dcbd 3645 /* Truncate string if source is too long. */
3646 cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
389dd41b 3647 tmp2 = build_call_expr_loc (input_location,
3648 built_in_decls[BUILT_IN_MEMMOVE],
c2f47e15 3649 3, dest, src, dlen);
59b9dcbd 3650
3651 /* Else copy and pad with spaces. */
389dd41b 3652 tmp3 = build_call_expr_loc (input_location,
3653 built_in_decls[BUILT_IN_MEMMOVE],
c2f47e15 3654 3, dest, src, slen);
59b9dcbd 3655
f6313358 3656 tmp4 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest,
0de36bdb 3657 fold_convert (sizetype, slen));
b44437b9 3658 tmp4 = fill_with_spaces (tmp4, chartype,
3659 fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
3660 dlen, slen));
59b9dcbd 3661
3662 gfc_init_block (&tempblock);
3663 gfc_add_expr_to_block (&tempblock, tmp3);
3664 gfc_add_expr_to_block (&tempblock, tmp4);
3665 tmp3 = gfc_finish_block (&tempblock);
3666
3667 /* The whole copy_string function is there. */
3668 tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
e60a6f7b 3669 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3670 build_empty_stmt (input_location));
dbe60343 3671 gfc_add_expr_to_block (block, tmp);
3672}
3673
3674
4ee9c684 3675/* Translate a statement function.
3676 The value of a statement function reference is obtained by evaluating the
3677 expression using the values of the actual arguments for the values of the
3678 corresponding dummy arguments. */
3679
3680static void
3681gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
3682{
3683 gfc_symbol *sym;
3684 gfc_symbol *fsym;
3685 gfc_formal_arglist *fargs;
3686 gfc_actual_arglist *args;
3687 gfc_se lse;
3688 gfc_se rse;
dbe60343 3689 gfc_saved_var *saved_vars;
3690 tree *temp_vars;
3691 tree type;
3692 tree tmp;
3693 int n;
4ee9c684 3694
3695 sym = expr->symtree->n.sym;
3696 args = expr->value.function.actual;
3697 gfc_init_se (&lse, NULL);
3698 gfc_init_se (&rse, NULL);
3699
dbe60343 3700 n = 0;
4ee9c684 3701 for (fargs = sym->formal; fargs; fargs = fargs->next)
dbe60343 3702 n++;
3703 saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
3704 temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
3705
3706 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
4ee9c684 3707 {
3708 /* Each dummy shall be specified, explicitly or implicitly, to be
3709 scalar. */
22d678e8 3710 gcc_assert (fargs->sym->attr.dimension == 0);
4ee9c684 3711 fsym = fargs->sym;
4ee9c684 3712
dbe60343 3713 /* Create a temporary to hold the value. */
3714 type = gfc_typenode_for_spec (&fsym->ts);
3715 temp_vars[n] = gfc_create_var (type, fsym->name);
3716
3717 if (fsym->ts.type == BT_CHARACTER)
4ee9c684 3718 {
dbe60343 3719 /* Copy string arguments. */
3720 tree arglen;
4ee9c684 3721
eeebe20b 3722 gcc_assert (fsym->ts.u.cl && fsym->ts.u.cl->length
3723 && fsym->ts.u.cl->length->expr_type == EXPR_CONSTANT);
4ee9c684 3724
dbe60343 3725 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3726 tmp = gfc_build_addr_expr (build_pointer_type (type),
3727 temp_vars[n]);
4ee9c684 3728
3729 gfc_conv_expr (&rse, args->expr);
3730 gfc_conv_string_parameter (&rse);
4ee9c684 3731 gfc_add_block_to_block (&se->pre, &lse.pre);
3732 gfc_add_block_to_block (&se->pre, &rse.pre);
3733
b44437b9 3734 gfc_trans_string_copy (&se->pre, arglen, tmp, fsym->ts.kind,
3735 rse.string_length, rse.expr, fsym->ts.kind);
4ee9c684 3736 gfc_add_block_to_block (&se->pre, &lse.post);
3737 gfc_add_block_to_block (&se->pre, &rse.post);
3738 }
3739 else
3740 {
3741 /* For everything else, just evaluate the expression. */
4ee9c684 3742 gfc_conv_expr (&lse, args->expr);
3743
3744 gfc_add_block_to_block (&se->pre, &lse.pre);
75a70cf9 3745 gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
4ee9c684 3746 gfc_add_block_to_block (&se->pre, &lse.post);
3747 }
dbe60343 3748
4ee9c684 3749 args = args->next;
3750 }
dbe60343 3751
3752 /* Use the temporary variables in place of the real ones. */
3753 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3754 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
3755
4ee9c684 3756 gfc_conv_expr (se, sym->value);
dbe60343 3757
3758 if (sym->ts.type == BT_CHARACTER)
3759 {
eeebe20b 3760 gfc_conv_const_charlen (sym->ts.u.cl);
dbe60343 3761
3762 /* Force the expression to the correct length. */
3763 if (!INTEGER_CST_P (se->string_length)
3764 || tree_int_cst_lt (se->string_length,
eeebe20b 3765 sym->ts.u.cl->backend_decl))
dbe60343 3766 {
eeebe20b 3767 type = gfc_get_character_type (sym->ts.kind, sym->ts.u.cl);
dbe60343 3768 tmp = gfc_create_var (type, sym->name);
3769 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
eeebe20b 3770 gfc_trans_string_copy (&se->pre, sym->ts.u.cl->backend_decl, tmp,
b44437b9 3771 sym->ts.kind, se->string_length, se->expr,
3772 sym->ts.kind);
dbe60343 3773 se->expr = tmp;
3774 }
eeebe20b 3775 se->string_length = sym->ts.u.cl->backend_decl;
dbe60343 3776 }
3777
f888a3fb 3778 /* Restore the original variables. */
dbe60343 3779 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
3780 gfc_restore_sym (fargs->sym, &saved_vars[n]);
3781 gfc_free (saved_vars);
4ee9c684 3782}
3783
3784
3785/* Translate a function expression. */
3786
3787static void
3788gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
3789{
3790 gfc_symbol *sym;
3791
3792 if (expr->value.function.isym)
3793 {
3794 gfc_conv_intrinsic_function (se, expr);
3795 return;
3796 }
3797
f888a3fb 3798 /* We distinguish statement functions from general functions to improve
4ee9c684 3799 runtime performance. */
3800 if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
3801 {
3802 gfc_conv_statement_function (se, expr);
3803 return;
3804 }
3805
3806 /* expr.value.function.esym is the resolved (specific) function symbol for
3807 most functions. However this isn't set for dummy procedures. */
3808 sym = expr->value.function.esym;
3809 if (!sym)
3810 sym = expr->symtree->n.sym;
64e93293 3811
3812 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
3813 NULL_TREE);
4ee9c684 3814}
3815
f888a3fb 3816
4ee9c684 3817static void
3818gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
3819{
22d678e8 3820 gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
3821 gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
4ee9c684 3822
3823 gfc_conv_tmp_array_ref (se);
3824 gfc_advance_se_ss_chain (se);
3825}
3826
3827
bda1f152 3828/* Build a static initializer. EXPR is the expression for the initial value.
f888a3fb 3829 The other parameters describe the variable of the component being
3830 initialized. EXPR may be null. */
4ee9c684 3831
bda1f152 3832tree
3833gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
3834 bool array, bool pointer)
3835{
3836 gfc_se se;
3837
3838 if (!(expr || pointer))
3839 return NULL_TREE;
3840
cf65c534 3841 /* Check if we have ISOCBINDING_NULL_PTR or ISOCBINDING_NULL_FUNPTR
3842 (these are the only two iso_c_binding derived types that can be
3843 used as initialization expressions). If so, we need to modify
3844 the 'expr' to be that for a (void *). */
3e77b51f 3845 if (expr != NULL && expr->ts.type == BT_DERIVED
eeebe20b 3846 && expr->ts.is_iso_c && expr->ts.u.derived)
cf65c534 3847 {
eeebe20b 3848 gfc_symbol *derived = expr->ts.u.derived;
cf65c534 3849
c5d33754 3850 expr = gfc_int_expr (0);
cf65c534 3851
3852 /* The derived symbol has already been converted to a (void *). Use
3853 its kind. */
3854 expr->ts.f90_type = derived->ts.f90_type;
3855 expr->ts.kind = derived->ts.kind;
3856 }
c5d33754 3857
bda1f152 3858 if (array)
3859 {
3860 /* Arrays need special handling. */
3861 if (pointer)
3862 return gfc_build_null_descriptor (type);
3863 else
3864 return gfc_conv_array_initializer (type, expr);
3865 }
3866 else if (pointer)
3867 return fold_convert (type, null_pointer_node);
3868 else
3869 {
3870 switch (ts->type)
3871 {
3872 case BT_DERIVED:
1de1b1a9 3873 case BT_CLASS:
bda1f152 3874 gfc_init_se (&se, NULL);
3875 gfc_conv_structure (&se, expr, 1);
3876 return se.expr;
3877
3878 case BT_CHARACTER:
eeebe20b 3879 return gfc_conv_string_init (ts->u.cl->backend_decl,expr);
bda1f152 3880
3881 default:
3882 gfc_init_se (&se, NULL);
3883 gfc_conv_constant (&se, expr);
3884 return se.expr;
3885 }
3886 }
3887}
3888
9a0aec1d 3889static tree
3890gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3891{
3892 gfc_se rse;
3893 gfc_se lse;
3894 gfc_ss *rss;
3895 gfc_ss *lss;
3896 stmtblock_t body;
3897 stmtblock_t block;
3898 gfc_loopinfo loop;
3899 int n;
3900 tree tmp;
3901
3902 gfc_start_block (&block);
3903
3904 /* Initialize the scalarizer. */
3905 gfc_init_loopinfo (&loop);
3906
3907 gfc_init_se (&lse, NULL);
3908 gfc_init_se (&rse, NULL);
3909
3910 /* Walk the rhs. */
3911 rss = gfc_walk_expr (expr);
3912 if (rss == gfc_ss_terminator)
3913 {
3914 /* The rhs is scalar. Add a ss for the expression. */
3915 rss = gfc_get_ss ();
3916 rss->next = gfc_ss_terminator;
3917 rss->type = GFC_SS_SCALAR;
3918 rss->expr = expr;
3919 }
3920
3921 /* Create a SS for the destination. */
3922 lss = gfc_get_ss ();
3923 lss->type = GFC_SS_COMPONENT;
3924 lss->expr = NULL;
3925 lss->shape = gfc_get_shape (cm->as->rank);
3926 lss->next = gfc_ss_terminator;
3927 lss->data.info.dimen = cm->as->rank;
3928 lss->data.info.descriptor = dest;
3929 lss->data.info.data = gfc_conv_array_data (dest);
3930 lss->data.info.offset = gfc_conv_array_offset (dest);
3931 for (n = 0; n < cm->as->rank; n++)
3932 {
3933 lss->data.info.dim[n] = n;
3934 lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
3935 lss->data.info.stride[n] = gfc_index_one_node;
3936
3937 mpz_init (lss->shape[n]);
3938 mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
3939 cm->as->lower[n]->value.integer);
3940 mpz_add_ui (lss->shape[n], lss->shape[n], 1);
3941 }
3942
3943 /* Associate the SS with the loop. */
3944 gfc_add_ss_to_loop (&loop, lss);
3945 gfc_add_ss_to_loop (&loop, rss);
3946
3947 /* Calculate the bounds of the scalarization. */
3948 gfc_conv_ss_startstride (&loop);
3949
3950 /* Setup the scalarizing loops. */
92f4d1c4 3951 gfc_conv_loop_setup (&loop, &expr->where);
9a0aec1d 3952
3953 /* Setup the gfc_se structures. */
3954 gfc_copy_loopinfo_to_se (&lse, &loop);
3955 gfc_copy_loopinfo_to_se (&rse, &loop);
3956
3957 rse.ss = rss;
3958 gfc_mark_ss_chain_used (rss, 1);
3959 lse.ss = lss;
3960 gfc_mark_ss_chain_used (lss, 1);
3961
3962 /* Start the scalarized loop body. */
3963 gfc_start_scalarized_body (&loop, &body);
3964
3965 gfc_conv_tmp_array_ref (&lse);
dc5fe211 3966 if (cm->ts.type == BT_CHARACTER)
eeebe20b 3967 lse.string_length = cm->ts.u.cl->backend_decl;
dc5fe211 3968
9a0aec1d 3969 gfc_conv_expr (&rse, expr);
3970
2294b616 3971 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts, true, false);
9a0aec1d 3972 gfc_add_expr_to_block (&body, tmp);
3973
22d678e8 3974 gcc_assert (rse.ss == gfc_ss_terminator);
9a0aec1d 3975
3976 /* Generate the copying loops. */
3977 gfc_trans_scalarizing_loops (&loop, &body);
3978
3979 /* Wrap the whole thing up. */
3980 gfc_add_block_to_block (&block, &loop.pre);
3981 gfc_add_block_to_block (&block, &loop.post);
3982
9a0aec1d 3983 for (n = 0; n < cm->as->rank; n++)
3984 mpz_clear (lss->shape[n]);
3985 gfc_free (lss->shape);
3986
6cf06ccd 3987 gfc_cleanup_loop (&loop);
3988
9a0aec1d 3989 return gfc_finish_block (&block);
3990}
3991
2294b616 3992
9a0aec1d 3993/* Assign a single component of a derived type constructor. */
3994
3995static tree
3996gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
3997{
3998 gfc_se se;
2294b616 3999 gfc_se lse;
9a0aec1d 4000 gfc_ss *rss;
4001 stmtblock_t block;
4002 tree tmp;
2294b616 4003 tree offset;
4004 int n;
9a0aec1d 4005
4006 gfc_start_block (&block);
2294b616 4007
3be2b8d5 4008 if (cm->attr.pointer)
9a0aec1d 4009 {
4010 gfc_init_se (&se, NULL);
4011 /* Pointer component. */
3be2b8d5 4012 if (cm->attr.dimension)
9a0aec1d 4013 {
4014 /* Array pointer. */
4015 if (expr->expr_type == EXPR_NULL)
94be45c9 4016 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
9a0aec1d 4017 else
4018 {
4019 rss = gfc_walk_expr (expr);
4020 se.direct_byref = 1;
4021 se.expr = dest;
4022 gfc_conv_expr_descriptor (&se, expr, rss);
4023 gfc_add_block_to_block (&block, &se.pre);
4024 gfc_add_block_to_block (&block, &se.post);
4025 }
4026 }
4027 else
4028 {
4029 /* Scalar pointers. */
4030 se.want_pointer = 1;
4031 gfc_conv_expr (&se, expr);
4032 gfc_add_block_to_block (&block, &se.pre);
75a70cf9 4033 gfc_add_modify (&block, dest,
9a0aec1d 4034 fold_convert (TREE_TYPE (dest), se.expr));
4035 gfc_add_block_to_block (&block, &se.post);
4036 }
4037 }
1de1b1a9 4038 else if (cm->ts.type == BT_CLASS && expr->expr_type == EXPR_NULL)
4039 {
4040 /* NULL initialization for CLASS components. */
4041 tmp = gfc_trans_structure_assign (dest,
4042 gfc_default_initializer (&cm->ts));
4043 gfc_add_expr_to_block (&block, tmp);
4044 }
3be2b8d5 4045 else if (cm->attr.dimension)
9a0aec1d 4046 {
3be2b8d5 4047 if (cm->attr.allocatable && expr->expr_type == EXPR_NULL)
2294b616 4048 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
3be2b8d5 4049 else if (cm->attr.allocatable)
6826be54 4050 {
4051 tree tmp2;
2294b616 4052
4053 gfc_init_se (&se, NULL);
4054
4055 rss = gfc_walk_expr (expr);
6826be54 4056 se.want_pointer = 0;
4057 gfc_conv_expr_descriptor (&se, expr, rss);
2294b616 4058 gfc_add_block_to_block (&block, &se.pre);
bb982f66 4059 gfc_add_modify (&block, dest, se.expr);
2294b616 4060
eeebe20b 4061 if (cm->ts.type == BT_DERIVED && cm->ts.u.derived->attr.alloc_comp)
4062 tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr, dest,
2294b616 4063 cm->as->rank);
4064 else
6826be54 4065 tmp = gfc_duplicate_allocatable (dest, se.expr,
2294b616 4066 TREE_TYPE(cm->backend_decl),
4067 cm->as->rank);
4068
6826be54 4069 gfc_add_expr_to_block (&block, tmp);
6826be54 4070 gfc_add_block_to_block (&block, &se.post);
8714fc76 4071
4072 if (expr->expr_type != EXPR_VARIABLE)
4073 gfc_conv_descriptor_data_set (&block, se.expr, null_pointer_node);
6826be54 4074
4075 /* Shift the lbound and ubound of temporaries to being unity, rather
4076 than zero, based. Calculate the offset for all cases. */
6b1a9af3 4077 offset = gfc_conv_descriptor_offset_get (dest);
75a70cf9 4078 gfc_add_modify (&block, offset, gfc_index_zero_node);
6826be54 4079 tmp2 =gfc_create_var (gfc_array_index_type, NULL);
4080 for (n = 0; n < expr->rank; n++)
4081 {
4082 if (expr->expr_type != EXPR_VARIABLE
4083 && expr->expr_type != EXPR_CONSTANT)
4084 {
4085 tree span;
6b1a9af3 4086 tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
6826be54 4087 span = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp,
6b1a9af3 4088 gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
4089 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4090 span, gfc_index_one_node);
4091 gfc_conv_descriptor_ubound_set (&block, dest, gfc_rank_cst[n],
4092 tmp);
4093 gfc_conv_descriptor_lbound_set (&block, dest, gfc_rank_cst[n],
4094 gfc_index_one_node);
6826be54 4095 }
4096 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
6b1a9af3 4097 gfc_conv_descriptor_lbound_get (dest,
2294b616 4098 gfc_rank_cst[n]),
6b1a9af3 4099 gfc_conv_descriptor_stride_get (dest,
2294b616 4100 gfc_rank_cst[n]));
75a70cf9 4101 gfc_add_modify (&block, tmp2, tmp);
6826be54 4102 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
6b1a9af3 4103 gfc_conv_descriptor_offset_set (&block, dest, tmp);
6826be54 4104 }
8714fc76 4105
4106 if (expr->expr_type == EXPR_FUNCTION
4107 && expr->value.function.isym
4108 && expr->value.function.isym->conversion
4109 && expr->value.function.actual->expr
4110 && expr->value.function.actual->expr->expr_type
4111 == EXPR_VARIABLE)
4112 {
4113 /* If a conversion expression has a null data pointer
4114 argument, nullify the allocatable component. */
4115 gfc_symbol *s;
4116 tree non_null_expr;
4117 tree null_expr;
4118 s = expr->value.function.actual->expr->symtree->n.sym;
4119 if (s->attr.allocatable || s->attr.pointer)
4120 {
4121 non_null_expr = gfc_finish_block (&block);
4122 gfc_start_block (&block);
4123 gfc_conv_descriptor_data_set (&block, dest,
4124 null_pointer_node);
4125 null_expr = gfc_finish_block (&block);
4126 tmp = gfc_conv_descriptor_data_get (s->backend_decl);
4127 tmp = build2 (EQ_EXPR, boolean_type_node, tmp,
4128 fold_convert (TREE_TYPE (tmp),
4129 null_pointer_node));
4130 return build3_v (COND_EXPR, tmp, null_expr,
4131 non_null_expr);
4132 }
4133 }
6826be54 4134 }
2294b616 4135 else
6826be54 4136 {
2294b616 4137 tmp = gfc_trans_subarray_assign (dest, cm, expr);
4138 gfc_add_expr_to_block (&block, tmp);
6826be54 4139 }
9a0aec1d 4140 }
4141 else if (expr->ts.type == BT_DERIVED)
4142 {
d95efb59 4143 if (expr->expr_type != EXPR_STRUCTURE)
4144 {
4145 gfc_init_se (&se, NULL);
4146 gfc_conv_expr (&se, expr);
0029c45c 4147 gfc_add_block_to_block (&block, &se.pre);
75a70cf9 4148 gfc_add_modify (&block, dest,
d95efb59 4149 fold_convert (TREE_TYPE (dest), se.expr));
0029c45c 4150 gfc_add_block_to_block (&block, &se.post);
d95efb59 4151 }
4152 else
4153 {
4154 /* Nested constructors. */
4155 tmp = gfc_trans_structure_assign (dest, expr);
4156 gfc_add_expr_to_block (&block, tmp);
4157 }
9a0aec1d 4158 }
4159 else
4160 {
4161 /* Scalar component. */
9a0aec1d 4162 gfc_init_se (&se, NULL);
4163 gfc_init_se (&lse, NULL);
4164
4165 gfc_conv_expr (&se, expr);
4166 if (cm->ts.type == BT_CHARACTER)
eeebe20b 4167 lse.string_length = cm->ts.u.cl->backend_decl;
9a0aec1d 4168 lse.expr = dest;
2294b616 4169 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false);
9a0aec1d 4170 gfc_add_expr_to_block (&block, tmp);
4171 }
4172 return gfc_finish_block (&block);
4173}
4174
39fca56b 4175/* Assign a derived type constructor to a variable. */
9a0aec1d 4176
4177static tree
4178gfc_trans_structure_assign (tree dest, gfc_expr * expr)
4179{
4180 gfc_constructor *c;
4181 gfc_component *cm;
4182 stmtblock_t block;
4183 tree field;
4184 tree tmp;
4185
4186 gfc_start_block (&block);
eeebe20b 4187 cm = expr->ts.u.derived->components;
9a0aec1d 4188 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
4189 {
4190 /* Skip absent members in default initializers. */
4191 if (!c->expr)
0029c45c 4192 continue;
4193
9a0aec1d 4194 field = cm->backend_decl;
f75d6b8a 4195 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field),
4196 dest, field, NULL_TREE);
9a0aec1d 4197 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
4198 gfc_add_expr_to_block (&block, tmp);
4199 }
4200 return gfc_finish_block (&block);
4201}
4202
4ee9c684 4203/* Build an expression for a constructor. If init is nonzero then
4204 this is part of a static variable initializer. */
4205
4206void
4207gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
4208{
4209 gfc_constructor *c;
4210 gfc_component *cm;
4ee9c684 4211 tree val;
4ee9c684 4212 tree type;
9a0aec1d 4213 tree tmp;
c75b4594 4214 VEC(constructor_elt,gc) *v = NULL;
4ee9c684 4215
22d678e8 4216 gcc_assert (se->ss == NULL);
4217 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
4ee9c684 4218 type = gfc_typenode_for_spec (&expr->ts);
9a0aec1d 4219
4220 if (!init)
4221 {
4222 /* Create a temporary variable and fill it in. */
eeebe20b 4223 se->expr = gfc_create_var (type, expr->ts.u.derived->name);
9a0aec1d 4224 tmp = gfc_trans_structure_assign (se->expr, expr);
4225 gfc_add_expr_to_block (&se->pre, tmp);
4226 return;
4227 }
4228
eeebe20b 4229 cm = expr->ts.u.derived->components;
2294b616 4230
4ee9c684 4231 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
4232 {
2294b616 4233 /* Skip absent members in default initializers and allocatable
4234 components. Although the latter have a default initializer
4235 of EXPR_NULL,... by default, the static nullify is not needed
4236 since this is done every time we come into scope. */
3be2b8d5 4237 if (!c->expr || cm->attr.allocatable)
4ee9c684 4238 continue;
4239
1de1b1a9 4240 if (cm->ts.type == BT_CLASS)
4241 {
4242 val = gfc_conv_initializer (c->expr, &cm->ts,
4243 TREE_TYPE (cm->ts.u.derived->components->backend_decl),
4244 cm->ts.u.derived->components->attr.dimension,
4245 cm->ts.u.derived->components->attr.pointer);
4246
4247 /* Append it to the constructor list. */
4248 CONSTRUCTOR_APPEND_ELT (v, cm->ts.u.derived->components->backend_decl,
4249 val);
4250 }
4251 else
4252 {
4253 val = gfc_conv_initializer (c->expr, &cm->ts,
4254 TREE_TYPE (cm->backend_decl), cm->attr.dimension,
4255 cm->attr.pointer || cm->attr.proc_pointer);
4ee9c684 4256
1de1b1a9 4257 /* Append it to the constructor list. */
4258 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
4259 }
4ee9c684 4260 }
c75b4594 4261 se->expr = build_constructor (type, v);
8b8484b4 4262 if (init)
c7d4e749 4263 TREE_CONSTANT (se->expr) = 1;
4ee9c684 4264}
4265
4266
f888a3fb 4267/* Translate a substring expression. */
4ee9c684 4268
4269static void
4270gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
4271{
4272 gfc_ref *ref;
4273
4274 ref = expr->ref;
4275
24756408 4276 gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);
4ee9c684 4277
b44437b9 4278 se->expr = gfc_build_wide_string_const (expr->ts.kind,
4279 expr->value.character.length,
4280 expr->value.character.string);
c32f863c 4281
4ee9c684 4282 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
24756408 4283 TYPE_STRING_FLAG (TREE_TYPE (se->expr)) = 1;
4ee9c684 4284
24756408 4285 if (ref)
4286 gfc_conv_substring (se, ref, expr->ts.kind, NULL, &expr->where);
4ee9c684 4287}
4288
4289
7b7afa03 4290/* Entry point for expression translation. Evaluates a scalar quantity.
4291 EXPR is the expression to be translated, and SE is the state structure if
4292 called from within the scalarized. */
4ee9c684 4293
4294void
4295gfc_conv_expr (gfc_se * se, gfc_expr * expr)
4296{
4297 if (se->ss && se->ss->expr == expr
4298 && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
4299 {
9a0aec1d 4300 /* Substitute a scalar expression evaluated outside the scalarization
4ee9c684 4301 loop. */
4302 se->expr = se->ss->data.scalar.expr;
7949cb07 4303 se->string_length = se->ss->string_length;
4ee9c684 4304 gfc_advance_se_ss_chain (se);
4305 return;
4306 }
4307
c5d33754 4308 /* We need to convert the expressions for the iso_c_binding derived types.
4309 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
4310 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
4311 typespec for the C_PTR and C_FUNPTR symbols, which has already been
4312 updated to be an integer with a kind equal to the size of a (void *). */
eeebe20b 4313 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived
4314 && expr->ts.u.derived->attr.is_iso_c)
c5d33754 4315 {
4316 if (expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_PTR
4317 || expr->symtree->n.sym->intmod_sym_id == ISOCBINDING_NULL_FUNPTR)
4318 {
4319 /* Set expr_type to EXPR_NULL, which will result in
4320 null_pointer_node being used below. */
4321 expr->expr_type = EXPR_NULL;
4322 }
4323 else
4324 {
4325 /* Update the type/kind of the expression to be what the new
4326 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
eeebe20b 4327 expr->ts.type = expr->ts.u.derived->ts.type;
4328 expr->ts.f90_type = expr->ts.u.derived->ts.f90_type;
4329 expr->ts.kind = expr->ts.u.derived->ts.kind;
c5d33754 4330 }
4331 }
4332
4ee9c684 4333 switch (expr->expr_type)
4334 {
4335 case EXPR_OP:
4336 gfc_conv_expr_op (se, expr);
4337 break;
4338
4339 case EXPR_FUNCTION:
4340 gfc_conv_function_expr (se, expr);
4341 break;
4342
4343 case EXPR_CONSTANT:
4344 gfc_conv_constant (se, expr);
4345 break;
4346
4347 case EXPR_VARIABLE:
4348 gfc_conv_variable (se, expr);
4349 break;
4350
4351 case EXPR_NULL:
4352 se->expr = null_pointer_node;
4353 break;
4354
4355 case EXPR_SUBSTRING:
4356 gfc_conv_substring_expr (se, expr);
4357 break;
4358
4359 case EXPR_STRUCTURE:
4360 gfc_conv_structure (se, expr, 0);
4361 break;
4362
4363 case EXPR_ARRAY:
4364 gfc_conv_array_constructor_expr (se, expr);
4365 break;
4366
4367 default:
22d678e8 4368 gcc_unreachable ();
4ee9c684 4369 break;
4370 }
4371}
4372
7b7afa03 4373/* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
4374 of an assignment. */
4ee9c684 4375void
4376gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
4377{
4378 gfc_conv_expr (se, expr);
7b7afa03 4379 /* All numeric lvalues should have empty post chains. If not we need to
4ee9c684 4380 figure out a way of rewriting an lvalue so that it has no post chain. */
7b7afa03 4381 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
4ee9c684 4382}
4383
7b7afa03 4384/* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
d4163395 4385 numeric expressions. Used for scalar values where inserting cleanup code
7b7afa03 4386 is inconvenient. */
4ee9c684 4387void
4388gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
4389{
4390 tree val;
4391
22d678e8 4392 gcc_assert (expr->ts.type != BT_CHARACTER);
4ee9c684 4393 gfc_conv_expr (se, expr);
4394 if (se->post.head)
4395 {
4396 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
75a70cf9 4397 gfc_add_modify (&se->pre, val, se->expr);
7b7afa03 4398 se->expr = val;
4399 gfc_add_block_to_block (&se->pre, &se->post);
4ee9c684 4400 }
4401}
4402
24146844 4403/* Helper to translate an expression and convert it to a particular type. */
4ee9c684 4404void
4405gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
4406{
4407 gfc_conv_expr_val (se, expr);
4408 se->expr = convert (type, se->expr);
4409}
4410
4411
f888a3fb 4412/* Converts an expression so that it can be passed by reference. Scalar
4ee9c684 4413 values only. */
4414
4415void
4416gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
4417{
4418 tree var;
4419
4420 if (se->ss && se->ss->expr == expr
4421 && se->ss->type == GFC_SS_REFERENCE)
4422 {
4423 se->expr = se->ss->data.scalar.expr;
7949cb07 4424 se->string_length = se->ss->string_length;
4ee9c684 4425 gfc_advance_se_ss_chain (se);
4426 return;
4427 }
4428
4429 if (expr->ts.type == BT_CHARACTER)
4430 {
4431 gfc_conv_expr (se, expr);
4432 gfc_conv_string_parameter (se);
4433 return;
4434 }
4435
4436 if (expr->expr_type == EXPR_VARIABLE)
4437 {
4438 se->want_pointer = 1;
4439 gfc_conv_expr (se, expr);
4440 if (se->post.head)
4441 {
4442 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
75a70cf9 4443 gfc_add_modify (&se->pre, var, se->expr);
4ee9c684 4444 gfc_add_block_to_block (&se->pre, &se->post);
4445 se->expr = var;
4446 }
4447 return;
4448 }
4449
4047f0ad 4450 if (expr->expr_type == EXPR_FUNCTION
7035e057 4451 && ((expr->value.function.esym
4452 && expr->value.function.esym->result->attr.pointer
4453 && !expr->value.function.esym->result->attr.dimension)
4454 || (!expr->value.function.esym
4455 && expr->symtree->n.sym->attr.pointer
4456 && !expr->symtree->n.sym->attr.dimension)))
4047f0ad 4457 {
4458 se->want_pointer = 1;
4459 gfc_conv_expr (se, expr);
4460 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
75a70cf9 4461 gfc_add_modify (&se->pre, var, se->expr);
4047f0ad 4462 se->expr = var;
4463 return;
4464 }
4465
4466
4ee9c684 4467 gfc_conv_expr (se, expr);
4468
4469 /* Create a temporary var to hold the value. */
e67e5e1f 4470 if (TREE_CONSTANT (se->expr))
4471 {
0f9dc66f 4472 tree tmp = se->expr;
4473 STRIP_TYPE_NOPS (tmp);
e60a6f7b 4474 var = build_decl (input_location,
4475 CONST_DECL, NULL, TREE_TYPE (tmp));
0f9dc66f 4476 DECL_INITIAL (var) = tmp;
f79c8ea7 4477 TREE_STATIC (var) = 1;
e67e5e1f 4478 pushdecl (var);
4479 }
4480 else
4481 {
4482 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
75a70cf9 4483 gfc_add_modify (&se->pre, var, se->expr);
e67e5e1f 4484 }
4ee9c684 4485 gfc_add_block_to_block (&se->pre, &se->post);
4486
4487 /* Take the address of that value. */
86f2ad37 4488 se->expr = gfc_build_addr_expr (NULL_TREE, var);
4ee9c684 4489}
4490
4491
4492tree
4493gfc_trans_pointer_assign (gfc_code * code)
4494{
578d3f19 4495 return gfc_trans_pointer_assignment (code->expr1, code->expr2);
4ee9c684 4496}
4497
4498
4396343e 4499/* Generate code for a pointer assignment. */
4500
4ee9c684 4501tree
4502gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
4503{
4504 gfc_se lse;
4505 gfc_se rse;
4506 gfc_ss *lss;
4507 gfc_ss *rss;
4508 stmtblock_t block;
7853829d 4509 tree desc;
4510 tree tmp;
1033248c 4511 tree decl;
4512
4ee9c684 4513 gfc_start_block (&block);
4514
4515 gfc_init_se (&lse, NULL);
4516
4517 lss = gfc_walk_expr (expr1);
4518 rss = gfc_walk_expr (expr2);
4519 if (lss == gfc_ss_terminator)
4520 {
4396343e 4521 /* Scalar pointers. */
4ee9c684 4522 lse.want_pointer = 1;
4523 gfc_conv_expr (&lse, expr1);
22d678e8 4524 gcc_assert (rss == gfc_ss_terminator);
4ee9c684 4525 gfc_init_se (&rse, NULL);
4526 rse.want_pointer = 1;
4527 gfc_conv_expr (&rse, expr2);
cad0ddcf 4528
4529 if (expr1->symtree->n.sym->attr.proc_pointer
4530 && expr1->symtree->n.sym->attr.dummy)
389dd41b 4531 lse.expr = build_fold_indirect_ref_loc (input_location,
4532 lse.expr);
cad0ddcf 4533
85d1c108 4534 if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
4535 && expr2->symtree->n.sym->attr.dummy)
389dd41b 4536 rse.expr = build_fold_indirect_ref_loc (input_location,
4537 rse.expr);
85d1c108 4538
4ee9c684 4539 gfc_add_block_to_block (&block, &lse.pre);
4540 gfc_add_block_to_block (&block, &rse.pre);
9c5786bd 4541
4542 /* Check character lengths if character expression. The test is only
4543 really added if -fbounds-check is enabled. */
1d84f30a 4544 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL
4545 && !expr1->symtree->n.sym->attr.proc_pointer
4546 && !gfc_is_proc_ptr_comp (expr1, NULL))
9c5786bd 4547 {
4548 gcc_assert (expr2->ts.type == BT_CHARACTER);
4549 gcc_assert (lse.string_length && rse.string_length);
4550 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4551 lse.string_length, rse.string_length,
4552 &block);
4553 }
4554
75a70cf9 4555 gfc_add_modify (&block, lse.expr,
260abd71 4556 fold_convert (TREE_TYPE (lse.expr), rse.expr));
9c5786bd 4557
4ee9c684 4558 gfc_add_block_to_block (&block, &rse.post);
4559 gfc_add_block_to_block (&block, &lse.post);
4560 }
4561 else
4562 {
9c5786bd 4563 tree strlen_lhs;
4564 tree strlen_rhs = NULL_TREE;
4565
4396343e 4566 /* Array pointer. */
4ee9c684 4567 gfc_conv_expr_descriptor (&lse, expr1, lss);
9c5786bd 4568 strlen_lhs = lse.string_length;
7853829d 4569 switch (expr2->expr_type)
4570 {
4571 case EXPR_NULL:
4572 /* Just set the data pointer to null. */
ca122904 4573 gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
7853829d 4574 break;
4575
4576 case EXPR_VARIABLE:
4577 /* Assign directly to the pointer's descriptor. */
9c5786bd 4578 lse.direct_byref = 1;
7853829d 4579 gfc_conv_expr_descriptor (&lse, expr2, rss);
9c5786bd 4580 strlen_rhs = lse.string_length;
1033248c 4581
4582 /* If this is a subreference array pointer assignment, use the rhs
8192caf4 4583 descriptor element size for the lhs span. */
1033248c 4584 if (expr1->symtree->n.sym->attr.subref_array_pointer)
4585 {
4586 decl = expr1->symtree->n.sym->backend_decl;
8192caf4 4587 gfc_init_se (&rse, NULL);
4588 rse.descriptor_only = 1;
4589 gfc_conv_expr (&rse, expr2);
4590 tmp = gfc_get_element_type (TREE_TYPE (rse.expr));
4591 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
4592 if (!INTEGER_CST_P (tmp))
9c5786bd 4593 gfc_add_block_to_block (&lse.post, &rse.pre);
75a70cf9 4594 gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
1033248c 4595 }
4596
7853829d 4597 break;
4598
4599 default:
4600 /* Assign to a temporary descriptor and then copy that
4601 temporary to the pointer. */
4602 desc = lse.expr;
4603 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
4604
4605 lse.expr = tmp;
4606 lse.direct_byref = 1;
4607 gfc_conv_expr_descriptor (&lse, expr2, rss);
9c5786bd 4608 strlen_rhs = lse.string_length;
75a70cf9 4609 gfc_add_modify (&lse.pre, desc, tmp);
7853829d 4610 break;
9c5786bd 4611 }
4612
4ee9c684 4613 gfc_add_block_to_block (&block, &lse.pre);
9c5786bd 4614
4615 /* Check string lengths if applicable. The check is only really added
4616 to the output code if -fbounds-check is enabled. */
4617 if (expr1->ts.type == BT_CHARACTER && expr2->expr_type != EXPR_NULL)
4618 {
4619 gcc_assert (expr2->ts.type == BT_CHARACTER);
4620 gcc_assert (strlen_lhs && strlen_rhs);
4621 gfc_trans_same_strlen_check ("pointer assignment", &expr1->where,
4622 strlen_lhs, strlen_rhs, &block);
4623 }
4624
4ee9c684 4625 gfc_add_block_to_block (&block, &lse.post);
4626 }
4627 return gfc_finish_block (&block);
4628}
4629
4630
4631/* Makes sure se is suitable for passing as a function string parameter. */
69b1505f 4632/* TODO: Need to check all callers of this function. It may be abused. */
4ee9c684 4633
4634void
4635gfc_conv_string_parameter (gfc_se * se)
4636{
4637 tree type;
4638
4639 if (TREE_CODE (se->expr) == STRING_CST)
4640 {
b44437b9 4641 type = TREE_TYPE (TREE_TYPE (se->expr));
4642 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4ee9c684 4643 return;
4644 }
4645
b44437b9 4646 if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
4ee9c684 4647 {
230c8f37 4648 if (TREE_CODE (se->expr) != INDIRECT_REF)
b44437b9 4649 {
4650 type = TREE_TYPE (se->expr);
4651 se->expr = gfc_build_addr_expr (build_pointer_type (type), se->expr);
4652 }
230c8f37 4653 else
4654 {
4655 type = gfc_get_character_type_len (gfc_default_character_kind,
4656 se->string_length);
4657 type = build_pointer_type (type);
4658 se->expr = gfc_build_addr_expr (type, se->expr);
4659 }
4ee9c684 4660 }
4661
22d678e8 4662 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
4663 gcc_assert (se->string_length
4ee9c684 4664 && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
4665}
4666
4667
4668/* Generate code for assignment of scalar variables. Includes character
2294b616 4669 strings and derived types with allocatable components. */
4ee9c684 4670
4671tree
2294b616 4672gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
4673 bool l_is_temp, bool r_is_var)
4ee9c684 4674{
4ee9c684 4675 stmtblock_t block;
2294b616 4676 tree tmp;
4677 tree cond;
4ee9c684 4678
4679 gfc_init_block (&block);
4680
2294b616 4681 if (ts.type == BT_CHARACTER)
4ee9c684 4682 {
891beb95 4683 tree rlen = NULL;
4684 tree llen = NULL;
4ee9c684 4685
891beb95 4686 if (lse->string_length != NULL_TREE)
4687 {
4688 gfc_conv_string_parameter (lse);
4689 gfc_add_block_to_block (&block, &lse->pre);
4690 llen = lse->string_length;
4691 }
4ee9c684 4692
891beb95 4693 if (rse->string_length != NULL_TREE)
4694 {
4695 gcc_assert (rse->string_length != NULL_TREE);
4696 gfc_conv_string_parameter (rse);
4697 gfc_add_block_to_block (&block, &rse->pre);
4698 rlen = rse->string_length;
4699 }
4ee9c684 4700
b44437b9 4701 gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
4702 rse->expr, ts.kind);
4ee9c684 4703 }
eeebe20b 4704 else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
2294b616 4705 {
4706 cond = NULL_TREE;
4707
4708 /* Are the rhs and the lhs the same? */
4709 if (r_is_var)
4710 {
4711 cond = fold_build2 (EQ_EXPR, boolean_type_node,
86f2ad37 4712 gfc_build_addr_expr (NULL_TREE, lse->expr),
4713 gfc_build_addr_expr (NULL_TREE, rse->expr));
2294b616 4714 cond = gfc_evaluate_now (cond, &lse->pre);
4715 }
4716
4717 /* Deallocate the lhs allocated components as long as it is not
89032e9a 4718 the same as the rhs. This must be done following the assignment
4719 to prevent deallocating data that could be used in the rhs
4720 expression. */
2294b616 4721 if (!l_is_temp)
4722 {
89032e9a 4723 tmp = gfc_evaluate_now (lse->expr, &lse->pre);
eeebe20b 4724 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
2294b616 4725 if (r_is_var)
e60a6f7b 4726 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4727 tmp);
89032e9a 4728 gfc_add_expr_to_block (&lse->post, tmp);
2294b616 4729 }
6826be54 4730
89032e9a 4731 gfc_add_block_to_block (&block, &rse->pre);
4732 gfc_add_block_to_block (&block, &lse->pre);
2294b616 4733
75a70cf9 4734 gfc_add_modify (&block, lse->expr,
2294b616 4735 fold_convert (TREE_TYPE (lse->expr), rse->expr));
4736
4737 /* Do a deep copy if the rhs is a variable, if it is not the
540338c6 4738 same as the lhs. */
2294b616 4739 if (r_is_var)
4740 {
eeebe20b 4741 tmp = gfc_copy_alloc_comp (ts.u.derived, rse->expr, lse->expr, 0);
e60a6f7b 4742 tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
4743 tmp);
2294b616 4744 gfc_add_expr_to_block (&block, tmp);
4745 }
2294b616 4746 }
15f80871 4747 else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
816767a6 4748 {
4749 gfc_add_block_to_block (&block, &lse->pre);
4750 gfc_add_block_to_block (&block, &rse->pre);
49974242 4751 tmp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lse->expr), rse->expr);
816767a6 4752 gfc_add_modify (&block, lse->expr, tmp);
4753 }
4ee9c684 4754 else
4755 {
4756 gfc_add_block_to_block (&block, &lse->pre);
4757 gfc_add_block_to_block (&block, &rse->pre);
4758
75a70cf9 4759 gfc_add_modify (&block, lse->expr,
816767a6 4760 fold_convert (TREE_TYPE (lse->expr), rse->expr));
4ee9c684 4761 }
4762
4763 gfc_add_block_to_block (&block, &lse->post);
4764 gfc_add_block_to_block (&block, &rse->post);
4765
4766 return gfc_finish_block (&block);
4767}
4768
4769
4770/* Try to translate array(:) = func (...), where func is a transformational
4771 array function, without using a temporary. Returns NULL is this isn't the
4772 case. */
4773
4774static tree
4775gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
4776{
4777 gfc_se se;
4778 gfc_ss *ss;
70464f87 4779 gfc_ref * ref;
4780 bool seen_array_ref;
8d60cc46 4781 bool c = false;
85d1c108 4782 gfc_component *comp = NULL;
4ee9c684 4783
4784 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
4785 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
4786 return NULL;
4787
4788 /* Elemental functions don't need a temporary anyway. */
08349c53 4789 if (expr2->value.function.esym != NULL
4790 && expr2->value.function.esym->attr.elemental)
4ee9c684 4791 return NULL;
4792
8d60cc46 4793 /* Fail if rhs is not FULL or a contiguous section. */
4794 if (expr1->ref && !(gfc_full_array_ref_p (expr1->ref, &c) || c))
4795 return NULL;
4796
c99d633f 4797 /* Fail if EXPR1 can't be expressed as a descriptor. */
4798 if (gfc_ref_needs_temporary_p (expr1->ref))
4799 return NULL;
4800
34da51b6 4801 /* Functions returning pointers need temporaries. */
d4ef6f9d 4802 if (expr2->symtree->n.sym->attr.pointer
4803 || expr2->symtree->n.sym->attr.allocatable)
34da51b6 4804 return NULL;
4805
5065911e 4806 /* Character array functions need temporaries unless the
4807 character lengths are the same. */
4808 if (expr2->ts.type == BT_CHARACTER && expr2->rank > 0)
4809 {
eeebe20b 4810 if (expr1->ts.u.cl->length == NULL
4811 || expr1->ts.u.cl->length->expr_type != EXPR_CONSTANT)
5065911e 4812 return NULL;
4813
eeebe20b 4814 if (expr2->ts.u.cl->length == NULL
4815 || expr2->ts.u.cl->length->expr_type != EXPR_CONSTANT)
5065911e 4816 return NULL;
4817
eeebe20b 4818 if (mpz_cmp (expr1->ts.u.cl->length->value.integer,
4819 expr2->ts.u.cl->length->value.integer) != 0)
5065911e 4820 return NULL;
4821 }
4822
70464f87 4823 /* Check that no LHS component references appear during an array
4824 reference. This is needed because we do not have the means to
4825 span any arbitrary stride with an array descriptor. This check
4826 is not needed for the rhs because the function result has to be
4827 a complete type. */
4828 seen_array_ref = false;
4829 for (ref = expr1->ref; ref; ref = ref->next)
4830 {
4831 if (ref->type == REF_ARRAY)
4832 seen_array_ref= true;
4833 else if (ref->type == REF_COMPONENT && seen_array_ref)
4834 return NULL;
4835 }
4836
4ee9c684 4837 /* Check for a dependency. */
018ef8b8 4838 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
4839 expr2->value.function.esym,
74e83bb9 4840 expr2->value.function.actual,
4841 NOT_ELEMENTAL))
4ee9c684 4842 return NULL;
4843
4844 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
4845 functions. */
22d678e8 4846 gcc_assert (expr2->value.function.isym
ff70e443 4847 || (gfc_is_proc_ptr_comp (expr2, &comp)
88a37d69 4848 && comp && comp->attr.dimension)
85d1c108 4849 || (!comp && gfc_return_by_reference (expr2->value.function.esym)
88a37d69 4850 && expr2->value.function.esym->result->attr.dimension));
4ee9c684 4851
4852 ss = gfc_walk_expr (expr1);
22d678e8 4853 gcc_assert (ss != gfc_ss_terminator);
4ee9c684 4854 gfc_init_se (&se, NULL);
4855 gfc_start_block (&se.pre);
4856 se.want_pointer = 1;
4857
bc56d052 4858 gfc_conv_array_parameter (&se, expr1, ss, 0, NULL, NULL, NULL);
4ee9c684 4859
4860 se.direct_byref = 1;
4861 se.ss = gfc_walk_expr (expr2);
22d678e8 4862 gcc_assert (se.ss != gfc_ss_terminator);
4ee9c684 4863 gfc_conv_function_expr (&se, expr2);
4ee9c684 4864 gfc_add_block_to_block (&se.pre, &se.post);
4865
4866 return gfc_finish_block (&se.pre);
4867}
4868
67313c34 4869/* Determine whether the given EXPR_CONSTANT is a zero initializer. */
4870
4871static bool
4872is_zero_initializer_p (gfc_expr * expr)
4873{
4874 if (expr->expr_type != EXPR_CONSTANT)
4875 return false;
667787ce 4876
4877 /* We ignore constants with prescribed memory representations for now. */
4878 if (expr->representation.string)
67313c34 4879 return false;
4880
4881 switch (expr->ts.type)
4882 {
4883 case BT_INTEGER:
4884 return mpz_cmp_si (expr->value.integer, 0) == 0;
4885
4886 case BT_REAL:
4887 return mpfr_zero_p (expr->value.real)
4888 && MPFR_SIGN (expr->value.real) >= 0;
4889
4890 case BT_LOGICAL:
4891 return expr->value.logical == 0;
4892
4893 case BT_COMPLEX:
f8e9f06c 4894 return mpfr_zero_p (mpc_realref (expr->value.complex))
4895 && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
4896 && mpfr_zero_p (mpc_imagref (expr->value.complex))
4897 && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
67313c34 4898
4899 default:
4900 break;
4901 }
4902 return false;
4903}
4904
4905/* Try to efficiently translate array(:) = 0. Return NULL if this
4906 can't be done. */
4907
4908static tree
4909gfc_trans_zero_assign (gfc_expr * expr)
4910{
4911 tree dest, len, type;
c2f47e15 4912 tree tmp;
67313c34 4913 gfc_symbol *sym;
4914
4915 sym = expr->symtree->n.sym;
4916 dest = gfc_get_symbol_decl (sym);
4917
4918 type = TREE_TYPE (dest);
4919 if (POINTER_TYPE_P (type))
4920 type = TREE_TYPE (type);
4921 if (!GFC_ARRAY_TYPE_P (type))
4922 return NULL_TREE;
4923
4924 /* Determine the length of the array. */
4925 len = GFC_TYPE_ARRAY_SIZE (type);
4926 if (!len || TREE_CODE (len) != INTEGER_CST)
4927 return NULL_TREE;
4928
db867224 4929 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
67313c34 4930 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
db867224 4931 fold_convert (gfc_array_index_type, tmp));
67313c34 4932
1d9f9adc 4933 /* If we are zeroing a local array avoid taking its address by emitting
4934 a = {} instead. */
67313c34 4935 if (!POINTER_TYPE_P (TREE_TYPE (dest)))
1d9f9adc 4936 return build2 (MODIFY_EXPR, void_type_node,
4937 dest, build_constructor (TREE_TYPE (dest), NULL));
4938
4939 /* Convert arguments to the correct types. */
4940 dest = fold_convert (pvoid_type_node, dest);
67313c34 4941 len = fold_convert (size_type_node, len);
4942
4943 /* Construct call to __builtin_memset. */
389dd41b 4944 tmp = build_call_expr_loc (input_location,
4945 built_in_decls[BUILT_IN_MEMSET],
c2f47e15 4946 3, dest, integer_zero_node, len);
67313c34 4947 return fold_convert (void_type_node, tmp);
4948}
4ee9c684 4949
538374c5 4950
4951/* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
4952 that constructs the call to __builtin_memcpy. */
4953
7a2a9daf 4954tree
538374c5 4955gfc_build_memcpy_call (tree dst, tree src, tree len)
4956{
c2f47e15 4957 tree tmp;
538374c5 4958
4959 /* Convert arguments to the correct types. */
4960 if (!POINTER_TYPE_P (TREE_TYPE (dst)))
4961 dst = gfc_build_addr_expr (pvoid_type_node, dst);
4962 else
4963 dst = fold_convert (pvoid_type_node, dst);
4964
4965 if (!POINTER_TYPE_P (TREE_TYPE (src)))
4966 src = gfc_build_addr_expr (pvoid_type_node, src);
4967 else
4968 src = fold_convert (pvoid_type_node, src);
4969
4970 len = fold_convert (size_type_node, len);
4971
4972 /* Construct call to __builtin_memcpy. */
389dd41b 4973 tmp = build_call_expr_loc (input_location,
4974 built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len);
538374c5 4975 return fold_convert (void_type_node, tmp);
4976}
4977
4978
1372ec9a 4979/* Try to efficiently translate dst(:) = src(:). Return NULL if this
4980 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
4981 source/rhs, both are gfc_full_array_ref_p which have been checked for
4982 dependencies. */
4ee9c684 4983
1372ec9a 4984static tree
4985gfc_trans_array_copy (gfc_expr * expr1, gfc_expr * expr2)
4986{
4987 tree dst, dlen, dtype;
4988 tree src, slen, stype;
db867224 4989 tree tmp;
1372ec9a 4990
4991 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
4992 src = gfc_get_symbol_decl (expr2->symtree->n.sym);
4993
4994 dtype = TREE_TYPE (dst);
4995 if (POINTER_TYPE_P (dtype))
4996 dtype = TREE_TYPE (dtype);
4997 stype = TREE_TYPE (src);
4998 if (POINTER_TYPE_P (stype))
4999 stype = TREE_TYPE (stype);
5000
5001 if (!GFC_ARRAY_TYPE_P (dtype) || !GFC_ARRAY_TYPE_P (stype))
5002 return NULL_TREE;
5003
5004 /* Determine the lengths of the arrays. */
5005 dlen = GFC_TYPE_ARRAY_SIZE (dtype);
5006 if (!dlen || TREE_CODE (dlen) != INTEGER_CST)
5007 return NULL_TREE;
db867224 5008 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
1372ec9a 5009 dlen = fold_build2 (MULT_EXPR, gfc_array_index_type, dlen,
db867224 5010 fold_convert (gfc_array_index_type, tmp));
1372ec9a 5011
5012 slen = GFC_TYPE_ARRAY_SIZE (stype);
5013 if (!slen || TREE_CODE (slen) != INTEGER_CST)
5014 return NULL_TREE;
db867224 5015 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (stype));
1372ec9a 5016 slen = fold_build2 (MULT_EXPR, gfc_array_index_type, slen,
db867224 5017 fold_convert (gfc_array_index_type, tmp));
1372ec9a 5018
5019 /* Sanity check that they are the same. This should always be
5020 the case, as we should already have checked for conformance. */
5021 if (!tree_int_cst_equal (slen, dlen))
5022 return NULL_TREE;
5023
538374c5 5024 return gfc_build_memcpy_call (dst, src, dlen);
5025}
1372ec9a 5026
1372ec9a 5027
538374c5 5028/* Try to efficiently translate array(:) = (/ ... /). Return NULL if
5029 this can't be done. EXPR1 is the destination/lhs for which
5030 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
1372ec9a 5031
538374c5 5032static tree
5033gfc_trans_array_constructor_copy (gfc_expr * expr1, gfc_expr * expr2)
5034{
5035 unsigned HOST_WIDE_INT nelem;
5036 tree dst, dtype;
5037 tree src, stype;
5038 tree len;
db867224 5039 tree tmp;
538374c5 5040
5041 nelem = gfc_constant_array_constructor_p (expr2->value.constructor);
5042 if (nelem == 0)
5043 return NULL_TREE;
5044
5045 dst = gfc_get_symbol_decl (expr1->symtree->n.sym);
5046 dtype = TREE_TYPE (dst);
5047 if (POINTER_TYPE_P (dtype))
5048 dtype = TREE_TYPE (dtype);
5049 if (!GFC_ARRAY_TYPE_P (dtype))
5050 return NULL_TREE;
5051
5052 /* Determine the lengths of the array. */
5053 len = GFC_TYPE_ARRAY_SIZE (dtype);
5054 if (!len || TREE_CODE (len) != INTEGER_CST)
5055 return NULL_TREE;
5056
5057 /* Confirm that the constructor is the same size. */
5058 if (compare_tree_int (len, nelem) != 0)
5059 return NULL_TREE;
5060
db867224 5061 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (dtype));
538374c5 5062 len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
db867224 5063 fold_convert (gfc_array_index_type, tmp));
538374c5 5064
5065 stype = gfc_typenode_for_spec (&expr2->ts);
5066 src = gfc_build_constant_array_constructor (expr2, stype);
5067
5068 stype = TREE_TYPE (src);
5069 if (POINTER_TYPE_P (stype))
5070 stype = TREE_TYPE (stype);
5071
5072 return gfc_build_memcpy_call (dst, src, len);
1372ec9a 5073}
5074
5075
5076/* Subroutine of gfc_trans_assignment that actually scalarizes the
52f5c19d 5077 assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS. */
1372ec9a 5078
5079static tree
5080gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
4ee9c684 5081{
5082 gfc_se lse;
5083 gfc_se rse;
5084 gfc_ss *lss;
5085 gfc_ss *lss_section;
5086 gfc_ss *rss;
5087 gfc_loopinfo loop;
5088 tree tmp;
5089 stmtblock_t block;
5090 stmtblock_t body;
2294b616 5091 bool l_is_temp;
8714fc76 5092 bool scalar_to_array;
bd619047 5093 tree string_length;
4ee9c684 5094
4ee9c684 5095 /* Assignment of the form lhs = rhs. */
5096 gfc_start_block (&block);
5097
5098 gfc_init_se (&lse, NULL);
5099 gfc_init_se (&rse, NULL);
5100
5101 /* Walk the lhs. */
5102 lss = gfc_walk_expr (expr1);
5103 rss = NULL;
5104 if (lss != gfc_ss_terminator)
5105 {
e2720a06 5106 /* Allow the scalarizer to workshare array assignments. */
5107 if (ompws_flags & OMPWS_WORKSHARE_FLAG)
5108 ompws_flags |= OMPWS_SCALARIZER_WS;
5109
4ee9c684 5110 /* The assignment needs scalarization. */
5111 lss_section = lss;
5112
5113 /* Find a non-scalar SS from the lhs. */
5114 while (lss_section != gfc_ss_terminator
5115 && lss_section->type != GFC_SS_SECTION)
5116 lss_section = lss_section->next;
5117
22d678e8 5118 gcc_assert (lss_section != gfc_ss_terminator);
4ee9c684 5119
5120 /* Initialize the scalarizer. */
5121 gfc_init_loopinfo (&loop);
5122
5123 /* Walk the rhs. */
5124 rss = gfc_walk_expr (expr2);
5125 if (rss == gfc_ss_terminator)
5126 {
5127 /* The rhs is scalar. Add a ss for the expression. */
5128 rss = gfc_get_ss ();
5129 rss->next = gfc_ss_terminator;
5130 rss->type = GFC_SS_SCALAR;
5131 rss->expr = expr2;
5132 }
5133 /* Associate the SS with the loop. */
5134 gfc_add_ss_to_loop (&loop, lss);
5135 gfc_add_ss_to_loop (&loop, rss);
5136
5137 /* Calculate the bounds of the scalarization. */
5138 gfc_conv_ss_startstride (&loop);
5139 /* Resolve any data dependencies in the statement. */
376a3611 5140 gfc_conv_resolve_dependencies (&loop, lss, rss);
4ee9c684 5141 /* Setup the scalarizing loops. */
92f4d1c4 5142 gfc_conv_loop_setup (&loop, &expr2->where);
4ee9c684 5143
5144 /* Setup the gfc_se structures. */
5145 gfc_copy_loopinfo_to_se (&lse, &loop);
5146 gfc_copy_loopinfo_to_se (&rse, &loop);
5147
5148 rse.ss = rss;
5149 gfc_mark_ss_chain_used (rss, 1);
5150 if (loop.temp_ss == NULL)
5151 {
5152 lse.ss = lss;
5153 gfc_mark_ss_chain_used (lss, 1);
5154 }
5155 else
5156 {
5157 lse.ss = loop.temp_ss;
5158 gfc_mark_ss_chain_used (lss, 3);
5159 gfc_mark_ss_chain_used (loop.temp_ss, 3);
5160 }
5161
5162 /* Start the scalarized loop body. */
5163 gfc_start_scalarized_body (&loop, &body);
5164 }
5165 else
5166 gfc_init_block (&body);
5167
2294b616 5168 l_is_temp = (lss != gfc_ss_terminator && loop.temp_ss != NULL);
5169
4ee9c684 5170 /* Translate the expression. */
5171 gfc_conv_expr (&rse, expr2);
5172
bd619047 5173 /* Stabilize a string length for temporaries. */
5174 if (expr2->ts.type == BT_CHARACTER)
5175 string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
5176 else
5177 string_length = NULL_TREE;
5178
2294b616 5179 if (l_is_temp)
4ee9c684 5180 {
5181 gfc_conv_tmp_array_ref (&lse);
5182 gfc_advance_se_ss_chain (&lse);
bd619047 5183 if (expr2->ts.type == BT_CHARACTER)
5184 lse.string_length = string_length;
4ee9c684 5185 }
5186 else
5187 gfc_conv_expr (&lse, expr1);
544c333b 5188
8714fc76 5189 /* Assignments of scalar derived types with allocatable components
5190 to arrays must be done with a deep copy and the rhs temporary
5191 must have its components deallocated afterwards. */
5192 scalar_to_array = (expr2->ts.type == BT_DERIVED
eeebe20b 5193 && expr2->ts.u.derived->attr.alloc_comp
8714fc76 5194 && expr2->expr_type != EXPR_VARIABLE
5195 && !gfc_is_constant_expr (expr2)
5196 && expr1->rank && !expr2->rank);
5197 if (scalar_to_array)
5198 {
eeebe20b 5199 tmp = gfc_deallocate_alloc_comp (expr2->ts.u.derived, rse.expr, 0);
8714fc76 5200 gfc_add_expr_to_block (&loop.post, tmp);
5201 }
5202
b9cd8c56 5203 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5204 l_is_temp || init_flag,
8714fc76 5205 (expr2->expr_type == EXPR_VARIABLE)
5206 || scalar_to_array);
4ee9c684 5207 gfc_add_expr_to_block (&body, tmp);
5208
5209 if (lss == gfc_ss_terminator)
5210 {
5211 /* Use the scalar assignment as is. */
5212 gfc_add_block_to_block (&block, &body);
5213 }
5214 else
5215 {
22d678e8 5216 gcc_assert (lse.ss == gfc_ss_terminator
5217 && rse.ss == gfc_ss_terminator);
4ee9c684 5218
2294b616 5219 if (l_is_temp)
4ee9c684 5220 {
5221 gfc_trans_scalarized_loop_boundary (&loop, &body);
5222
5223 /* We need to copy the temporary to the actual lhs. */
5224 gfc_init_se (&lse, NULL);
5225 gfc_init_se (&rse, NULL);
5226 gfc_copy_loopinfo_to_se (&lse, &loop);
5227 gfc_copy_loopinfo_to_se (&rse, &loop);
5228
5229 rse.ss = loop.temp_ss;
5230 lse.ss = lss;
5231
5232 gfc_conv_tmp_array_ref (&rse);
5233 gfc_advance_se_ss_chain (&rse);
5234 gfc_conv_expr (&lse, expr1);
5235
22d678e8 5236 gcc_assert (lse.ss == gfc_ss_terminator
5237 && rse.ss == gfc_ss_terminator);
4ee9c684 5238
bd619047 5239 if (expr2->ts.type == BT_CHARACTER)
5240 rse.string_length = string_length;
5241
b9cd8c56 5242 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
5243 false, false);
4ee9c684 5244 gfc_add_expr_to_block (&body, tmp);
5245 }
2294b616 5246
4ee9c684 5247 /* Generate the copying loops. */
5248 gfc_trans_scalarizing_loops (&loop, &body);
5249
5250 /* Wrap the whole thing up. */
5251 gfc_add_block_to_block (&block, &loop.pre);
5252 gfc_add_block_to_block (&block, &loop.post);
5253
5254 gfc_cleanup_loop (&loop);
5255 }
5256
5257 return gfc_finish_block (&block);
5258}
5259
1372ec9a 5260
62e711cd 5261/* Check whether EXPR is a copyable array. */
1372ec9a 5262
5263static bool
5264copyable_array_p (gfc_expr * expr)
5265{
62e711cd 5266 if (expr->expr_type != EXPR_VARIABLE)
5267 return false;
5268
1372ec9a 5269 /* First check it's an array. */
62e711cd 5270 if (expr->rank < 1 || !expr->ref || expr->ref->next)
5271 return false;
5272
8d60cc46 5273 if (!gfc_full_array_ref_p (expr->ref, NULL))
1372ec9a 5274 return false;
5275
5276 /* Next check that it's of a simple enough type. */
5277 switch (expr->ts.type)
5278 {
5279 case BT_INTEGER:
5280 case BT_REAL:
5281 case BT_COMPLEX:
5282 case BT_LOGICAL:
5283 return true;
5284
6fc8b651 5285 case BT_CHARACTER:
5286 return false;
5287
5288 case BT_DERIVED:
eeebe20b 5289 return !expr->ts.u.derived->attr.alloc_comp;
6fc8b651 5290
1372ec9a 5291 default:
5292 break;
5293 }
5294
5295 return false;
5296}
5297
5298/* Translate an assignment. */
5299
5300tree
5301gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
5302{
5303 tree tmp;
5304
5305 /* Special case a single function returning an array. */
5306 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5307 {
5308 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5309 if (tmp)
5310 return tmp;
5311 }
5312
5313 /* Special case assigning an array to zero. */
62e711cd 5314 if (copyable_array_p (expr1)
1372ec9a 5315 && is_zero_initializer_p (expr2))
5316 {
5317 tmp = gfc_trans_zero_assign (expr1);
5318 if (tmp)
5319 return tmp;
5320 }
5321
5322 /* Special case copying one array to another. */
62e711cd 5323 if (copyable_array_p (expr1)
1372ec9a 5324 && copyable_array_p (expr2)
1372ec9a 5325 && gfc_compare_types (&expr1->ts, &expr2->ts)
5326 && !gfc_check_dependency (expr1, expr2, 0))
5327 {
5328 tmp = gfc_trans_array_copy (expr1, expr2);
5329 if (tmp)
5330 return tmp;
5331 }
5332
538374c5 5333 /* Special case initializing an array from a constant array constructor. */
62e711cd 5334 if (copyable_array_p (expr1)
538374c5 5335 && expr2->expr_type == EXPR_ARRAY
5336 && gfc_compare_types (&expr1->ts, &expr2->ts))
5337 {
5338 tmp = gfc_trans_array_constructor_copy (expr1, expr2);
5339 if (tmp)
5340 return tmp;
5341 }
5342
1372ec9a 5343 /* Fallback to the scalarizer to generate explicit loops. */
5344 return gfc_trans_assignment_1 (expr1, expr2, init_flag);
5345}
5346
b9cd8c56 5347tree
5348gfc_trans_init_assign (gfc_code * code)
5349{
578d3f19 5350 return gfc_trans_assignment (code->expr1, code->expr2, true);
b9cd8c56 5351}
5352
4ee9c684 5353tree
5354gfc_trans_assign (gfc_code * code)
5355{
578d3f19 5356 return gfc_trans_assignment (code->expr1, code->expr2, false);
4ee9c684 5357}
39f3dea0 5358
5359
5360/* Translate an assignment to a CLASS object
5361 (pointer or ordinary assignment). */
5362
5363tree
5364gfc_trans_class_assign (gfc_code *code)
5365{
5366 stmtblock_t block;
5367 tree tmp;
5368
5369 gfc_start_block (&block);
5370
5371 if (code->expr2->ts.type != BT_CLASS)
5372 {
5373 /* Insert an additional assignment which sets the '$vindex' field. */
5374 gfc_expr *lhs,*rhs;
5375 lhs = gfc_copy_expr (code->expr1);
5376 gfc_add_component_ref (lhs, "$vindex");
5377 if (code->expr2->ts.type == BT_DERIVED)
5378 /* vindex is constant, determined at compile time. */
5379 rhs = gfc_int_expr (code->expr2->ts.u.derived->vindex);
5380 else if (code->expr2->expr_type == EXPR_NULL)
5381 rhs = gfc_int_expr (0);
5382 else
5383 gcc_unreachable ();
5384 tmp = gfc_trans_assignment (lhs, rhs, false);
5385 gfc_add_expr_to_block (&block, tmp);
5386
5387 /* Insert another assignment which sets the '$size' field. */
5388 lhs = gfc_copy_expr (code->expr1);
5389 gfc_add_component_ref (lhs, "$size");
5390 if (code->expr2->ts.type == BT_DERIVED)
5391 {
5392 /* Size is fixed at compile time. */
5393 gfc_se lse;
5394 gfc_init_se (&lse, NULL);
5395 gfc_conv_expr (&lse, lhs);
5396 tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->expr2->ts));
5397 gfc_add_modify (&block, lse.expr,
5398 fold_convert (TREE_TYPE (lse.expr), tmp));
5399 }
5400 else if (code->expr2->expr_type == EXPR_NULL)
5401 {
5402 rhs = gfc_int_expr (0);
5403 tmp = gfc_trans_assignment (lhs, rhs, false);
5404 gfc_add_expr_to_block (&block, tmp);
5405 }
5406 else
5407 gcc_unreachable ();
5408
5409 gfc_free_expr (lhs);
5410 gfc_free_expr (rhs);
5411 }
5412
5413 /* Do the actual CLASS assignment. */
5414 if (code->expr2->ts.type == BT_CLASS)
5415 code->op = EXEC_ASSIGN;
5416 else
5417 gfc_add_component_ref (code->expr1, "$data");
5418
5419 if (code->op == EXEC_ASSIGN)
5420 tmp = gfc_trans_assign (code);
5421 else if (code->op == EXEC_POINTER_ASSIGN)
5422 tmp = gfc_trans_pointer_assign (code);
5423 else
5424 gcc_unreachable();
5425
5426 gfc_add_expr_to_block (&block, tmp);
5427
5428 return gfc_finish_block (&block);
5429}