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