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