]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans-stmt.c
* constexpr.c (cxx_eval_outermost_constant_expr): Update comment.
[thirdparty/gcc.git] / gcc / fortran / trans-stmt.c
CommitLineData
6de9cd9a 1/* Statement translation -- generate GCC trees from gfc_code.
85ec4feb 2 Copyright (C) 2002-2018 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
9fc4d79b 6This file is part of GCC.
6de9cd9a 7
9fc4d79b
TS
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
d234d788 10Software Foundation; either version 3, or (at your option) any later
9fc4d79b 11version.
6de9cd9a 12
9fc4d79b
TS
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
6de9cd9a
DN
17
18You should have received a copy of the GNU General Public License
d234d788
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
21
22
23#include "config.h"
24#include "system.h"
25#include "coretypes.h"
c7131fb2 26#include "options.h"
2adfab87 27#include "tree.h"
6de9cd9a
DN
28#include "gfortran.h"
29#include "trans.h"
2adfab87 30#include "stringpool.h"
2adfab87 31#include "fold-const.h"
6de9cd9a
DN
32#include "trans-stmt.h"
33#include "trans-types.h"
34#include "trans-array.h"
35#include "trans-const.h"
3ded6210 36#include "dependency.h"
6de9cd9a 37
6de9cd9a
DN
38typedef struct iter_info
39{
40 tree var;
41 tree start;
42 tree end;
43 tree step;
44 struct iter_info *next;
45}
46iter_info;
47
6de9cd9a
DN
48typedef struct forall_info
49{
50 iter_info *this_loop;
51 tree mask;
6de9cd9a
DN
52 tree maskindex;
53 int nvar;
54 tree size;
e8d366ec 55 struct forall_info *prev_nest;
2ca4e2c2 56 bool do_concurrent;
6de9cd9a
DN
57}
58forall_info;
59
011daa76
RS
60static void gfc_trans_where_2 (gfc_code *, tree, bool,
61 forall_info *, stmtblock_t *);
6de9cd9a
DN
62
63/* Translate a F95 label number to a LABEL_EXPR. */
64
65tree
66gfc_trans_label_here (gfc_code * code)
67{
68 return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
69}
70
ce2df7c6
FW
71
72/* Given a variable expression which has been ASSIGNed to, find the decl
73 containing the auxiliary variables. For variables in common blocks this
74 is a field_decl. */
75
76void
77gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
78{
79 gcc_assert (expr->symtree->n.sym->attr.assign == 1);
80 gfc_conv_expr (se, expr);
81 /* Deals with variable in common block. Get the field declaration. */
82 if (TREE_CODE (se->expr) == COMPONENT_REF)
83 se->expr = TREE_OPERAND (se->expr, 1);
910450c1
FW
84 /* Deals with dummy argument. Get the parameter declaration. */
85 else if (TREE_CODE (se->expr) == INDIRECT_REF)
86 se->expr = TREE_OPERAND (se->expr, 0);
ce2df7c6
FW
87}
88
6de9cd9a 89/* Translate a label assignment statement. */
ce2df7c6 90
6de9cd9a
DN
91tree
92gfc_trans_label_assign (gfc_code * code)
93{
94 tree label_tree;
95 gfc_se se;
96 tree len;
97 tree addr;
98 tree len_tree;
6de9cd9a
DN
99 int label_len;
100
101 /* Start a new block. */
102 gfc_init_se (&se, NULL);
103 gfc_start_block (&se.pre);
a513927a 104 gfc_conv_label_variable (&se, code->expr1);
ce2df7c6 105
6de9cd9a
DN
106 len = GFC_DECL_STRING_LEN (se.expr);
107 addr = GFC_DECL_ASSIGN_ADDR (se.expr);
108
79bd1948 109 label_tree = gfc_get_label_decl (code->label1);
6de9cd9a 110
f3e7b9d6
TB
111 if (code->label1->defined == ST_LABEL_TARGET
112 || code->label1->defined == ST_LABEL_DO_TARGET)
6de9cd9a
DN
113 {
114 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
f622221a 115 len_tree = build_int_cst (gfc_charlen_type_node, -1);
6de9cd9a
DN
116 }
117 else
118 {
79bd1948 119 gfc_expr *format = code->label1->format;
d393bbd7
FXC
120
121 label_len = format->value.character.length;
df09d1d5 122 len_tree = build_int_cst (gfc_charlen_type_node, label_len);
d393bbd7
FXC
123 label_tree = gfc_build_wide_string_const (format->ts.kind, label_len + 1,
124 format->value.character.string);
b078dfbf 125 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
6de9cd9a
DN
126 }
127
f622221a 128 gfc_add_modify (&se.pre, len, fold_convert (TREE_TYPE (len), len_tree));
726a989a 129 gfc_add_modify (&se.pre, addr, label_tree);
6de9cd9a
DN
130
131 return gfc_finish_block (&se.pre);
132}
133
134/* Translate a GOTO statement. */
135
136tree
137gfc_trans_goto (gfc_code * code)
138{
dd18a33b 139 locus loc = code->loc;
6de9cd9a
DN
140 tree assigned_goto;
141 tree target;
142 tree tmp;
6de9cd9a
DN
143 gfc_se se;
144
79bd1948
SK
145 if (code->label1 != NULL)
146 return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
6de9cd9a
DN
147
148 /* ASSIGNED GOTO. */
149 gfc_init_se (&se, NULL);
150 gfc_start_block (&se.pre);
a513927a 151 gfc_conv_label_variable (&se, code->expr1);
6de9cd9a 152 tmp = GFC_DECL_STRING_LEN (se.expr);
63ee5404 153 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
bc98ed60 154 build_int_cst (TREE_TYPE (tmp), -1));
0d52899f 155 gfc_trans_runtime_check (true, false, tmp, &se.pre, &loc,
c8fe94c7 156 "Assigned label is not a target label");
6de9cd9a
DN
157
158 assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
6de9cd9a 159
916bd5f0
DK
160 /* We're going to ignore a label list. It does not really change the
161 statement's semantics (because it is just a further restriction on
162 what's legal code); before, we were comparing label addresses here, but
163 that's a very fragile business and may break with optimization. So
164 just ignore it. */
165
bc98ed60
TB
166 target = fold_build1_loc (input_location, GOTO_EXPR, void_type_node,
167 assigned_goto);
916bd5f0
DK
168 gfc_add_expr_to_block (&se.pre, target);
169 return gfc_finish_block (&se.pre);
6de9cd9a
DN
170}
171
172
3d79abbd
PB
173/* Translate an ENTRY statement. Just adds a label for this entry point. */
174tree
175gfc_trans_entry (gfc_code * code)
176{
177 return build1_v (LABEL_EXPR, code->ext.entry->label);
178}
179
180
fafcf9e6
MM
181/* Replace a gfc_ss structure by another both in the gfc_se struct
182 and the gfc_loopinfo struct. This is used in gfc_conv_elemental_dependencies
183 to replace a variable ss by the corresponding temporary. */
184
185static void
186replace_ss (gfc_se *se, gfc_ss *old_ss, gfc_ss *new_ss)
187{
188 gfc_ss **sess, **loopss;
189
190 /* The old_ss is a ss for a single variable. */
191 gcc_assert (old_ss->info->type == GFC_SS_SECTION);
192
193 for (sess = &(se->ss); *sess != gfc_ss_terminator; sess = &((*sess)->next))
194 if (*sess == old_ss)
195 break;
196 gcc_assert (*sess != gfc_ss_terminator);
197
198 *sess = new_ss;
199 new_ss->next = old_ss->next;
200
201
202 for (loopss = &(se->loop->ss); *loopss != gfc_ss_terminator;
203 loopss = &((*loopss)->loop_chain))
204 if (*loopss == old_ss)
205 break;
206 gcc_assert (*loopss != gfc_ss_terminator);
207
208 *loopss = new_ss;
209 new_ss->loop_chain = old_ss->loop_chain;
210 new_ss->loop = old_ss->loop;
211
212 gfc_free_ss (old_ss);
213}
214
215
476220e7
PT
216/* Check for dependencies between INTENT(IN) and INTENT(OUT) arguments of
217 elemental subroutines. Make temporaries for output arguments if any such
218 dependencies are found. Output arguments are chosen because internal_unpack
219 can be used, as is, to copy the result back to the variable. */
220static void
221gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
2b0bd714
MM
222 gfc_symbol * sym, gfc_actual_arglist * arg,
223 gfc_dep_check check_variable)
476220e7
PT
224{
225 gfc_actual_arglist *arg0;
226 gfc_expr *e;
227 gfc_formal_arglist *formal;
476220e7
PT
228 gfc_se parmse;
229 gfc_ss *ss;
476220e7 230 gfc_symbol *fsym;
476220e7 231 tree data;
476220e7
PT
232 tree size;
233 tree tmp;
234
235 if (loopse->ss == NULL)
236 return;
237
238 ss = loopse->ss;
239 arg0 = arg;
4cbc9039 240 formal = gfc_sym_get_dummy_args (sym);
476220e7
PT
241
242 /* Loop over all the arguments testing for dependencies. */
243 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
244 {
245 e = arg->expr;
246 if (e == NULL)
247 continue;
248
8b704316 249 /* Obtain the info structure for the current argument. */
476220e7 250 for (ss = loopse->ss; ss && ss != gfc_ss_terminator; ss = ss->next)
fafcf9e6 251 if (ss->info->expr == e)
476220e7 252 break;
476220e7
PT
253
254 /* If there is a dependency, create a temporary and use it
66e4ab31 255 instead of the variable. */
476220e7
PT
256 fsym = formal ? formal->sym : NULL;
257 if (e->expr_type == EXPR_VARIABLE
258 && e->rank && fsym
06bcd751
PT
259 && fsym->attr.intent != INTENT_IN
260 && gfc_check_fncall_dependency (e, fsym->attr.intent,
2b0bd714 261 sym, arg0, check_variable))
476220e7 262 {
79e5286c 263 tree initial, temptype;
12f681a0 264 stmtblock_t temp_post;
fafcf9e6 265 gfc_ss *tmp_ss;
12f681a0 266
fafcf9e6
MM
267 tmp_ss = gfc_get_array_ss (gfc_ss_terminator, NULL, ss->dimen,
268 GFC_SS_SECTION);
269 gfc_mark_ss_chain_used (tmp_ss, 1);
270 tmp_ss->info->expr = ss->info->expr;
271 replace_ss (loopse, ss, tmp_ss);
476220e7 272
12f681a0
DK
273 /* Obtain the argument descriptor for unpacking. */
274 gfc_init_se (&parmse, NULL);
275 parmse.want_pointer = 1;
2960a368 276 gfc_conv_expr_descriptor (&parmse, e);
12f681a0
DK
277 gfc_add_block_to_block (&se->pre, &parmse.pre);
278
eb74e79b
PT
279 /* If we've got INTENT(INOUT) or a derived type with INTENT(OUT),
280 initialize the array temporary with a copy of the values. */
281 if (fsym->attr.intent == INTENT_INOUT
282 || (fsym->ts.type ==BT_DERIVED
283 && fsym->attr.intent == INTENT_OUT))
12f681a0 284 initial = parmse.expr;
866e6d1b
PT
285 /* For class expressions, we always initialize with the copy of
286 the values. */
287 else if (e->ts.type == BT_CLASS)
288 initial = parmse.expr;
12f681a0
DK
289 else
290 initial = NULL_TREE;
291
866e6d1b
PT
292 if (e->ts.type != BT_CLASS)
293 {
294 /* Find the type of the temporary to create; we don't use the type
295 of e itself as this breaks for subcomponent-references in e
296 (where the type of e is that of the final reference, but
297 parmse.expr's type corresponds to the full derived-type). */
298 /* TODO: Fix this somehow so we don't need a temporary of the whole
299 array but instead only the components referenced. */
300 temptype = TREE_TYPE (parmse.expr); /* Pointer to descriptor. */
301 gcc_assert (TREE_CODE (temptype) == POINTER_TYPE);
302 temptype = TREE_TYPE (temptype);
303 temptype = gfc_get_element_type (temptype);
304 }
305
306 else
307 /* For class arrays signal that the size of the dynamic type has to
308 be obtained from the vtable, using the 'initial' expression. */
309 temptype = NULL_TREE;
79e5286c
DK
310
311 /* Generate the temporary. Cleaning up the temporary should be the
312 very last thing done, so we add the code to a new block and add it
313 to se->post as last instructions. */
476220e7
PT
314 size = gfc_create_var (gfc_array_index_type, NULL);
315 data = gfc_create_var (pvoid_type_node, NULL);
12f681a0 316 gfc_init_block (&temp_post);
fafcf9e6 317 tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, tmp_ss,
41645793
MM
318 temptype, initial, false, true,
319 false, &arg->expr->where);
726a989a 320 gfc_add_modify (&se->pre, size, tmp);
fafcf9e6 321 tmp = fold_convert (pvoid_type_node, tmp_ss->info->data.array.data);
726a989a 322 gfc_add_modify (&se->pre, data, tmp);
476220e7 323
fafcf9e6
MM
324 /* Update other ss' delta. */
325 gfc_set_delta (loopse->loop);
476220e7 326
866e6d1b
PT
327 /* Copy the result back using unpack..... */
328 if (e->ts.type != BT_CLASS)
329 tmp = build_call_expr_loc (input_location,
330 gfor_fndecl_in_unpack, 2, parmse.expr, data);
331 else
332 {
333 /* ... except for class results where the copy is
334 unconditional. */
335 tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
336 tmp = gfc_conv_descriptor_data_get (tmp);
337 tmp = build_call_expr_loc (input_location,
338 builtin_decl_explicit (BUILT_IN_MEMCPY),
ee4b6b52
JJ
339 3, tmp, data,
340 fold_convert (size_type_node, size));
866e6d1b 341 }
476220e7
PT
342 gfc_add_expr_to_block (&se->post, tmp);
343
79e5286c 344 /* parmse.pre is already added above. */
476220e7 345 gfc_add_block_to_block (&se->post, &parmse.post);
12f681a0 346 gfc_add_block_to_block (&se->post, &temp_post);
476220e7
PT
347 }
348 }
349}
350
351
9436b221
MM
352/* Get the interface symbol for the procedure corresponding to the given call.
353 We can't get the procedure symbol directly as we have to handle the case
354 of (deferred) type-bound procedures. */
355
356static gfc_symbol *
357get_proc_ifc_for_call (gfc_code *c)
358{
359 gfc_symbol *sym;
360
361 gcc_assert (c->op == EXEC_ASSIGN_CALL || c->op == EXEC_CALL);
362
363 sym = gfc_get_proc_ifc_for_expr (c->expr1);
364
365 /* Fall back/last resort try. */
366 if (sym == NULL)
367 sym = c->resolved_sym;
368
369 return sym;
370}
371
372
6de9cd9a
DN
373/* Translate the CALL statement. Builds a call to an F95 subroutine. */
374
375tree
eb74e79b
PT
376gfc_trans_call (gfc_code * code, bool dependency_check,
377 tree mask, tree count1, bool invert)
6de9cd9a
DN
378{
379 gfc_se se;
48474141 380 gfc_ss * ss;
dda895f9 381 int has_alternate_specifier;
2b0bd714 382 gfc_dep_check check_variable;
eb74e79b
PT
383 tree index = NULL_TREE;
384 tree maskexpr = NULL_TREE;
385 tree tmp;
6de9cd9a
DN
386
387 /* A CALL starts a new block because the actual arguments may have to
388 be evaluated first. */
389 gfc_init_se (&se, NULL);
390 gfc_start_block (&se.pre);
391
6e45f57b 392 gcc_assert (code->resolved_sym);
6de9cd9a 393
48474141
PT
394 ss = gfc_ss_terminator;
395 if (code->resolved_sym->attr.elemental)
17d038cd 396 ss = gfc_walk_elemental_function_args (ss, code->ext.actual,
9436b221 397 get_proc_ifc_for_call (code),
dec131b6 398 GFC_SS_REFERENCE);
6de9cd9a 399
48474141
PT
400 /* Is not an elemental subroutine call with array valued arguments. */
401 if (ss == gfc_ss_terminator)
6de9cd9a 402 {
48474141
PT
403
404 /* Translate the call. */
405 has_alternate_specifier
713485cc 406 = gfc_conv_procedure_call (&se, code->resolved_sym, code->ext.actual,
989ea525 407 code->expr1, NULL);
48474141
PT
408
409 /* A subroutine without side-effect, by definition, does nothing! */
410 TREE_SIDE_EFFECTS (se.expr) = 1;
411
412 /* Chain the pieces together and return the block. */
413 if (has_alternate_specifier)
414 {
415 gfc_code *select_code;
416 gfc_symbol *sym;
417 select_code = code->next;
418 gcc_assert(select_code->op == EXEC_SELECT);
a513927a 419 sym = select_code->expr1->symtree->n.sym;
48474141 420 se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
9ebe2d22
PT
421 if (sym->backend_decl == NULL)
422 sym->backend_decl = gfc_get_symbol_decl (sym);
726a989a 423 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
48474141
PT
424 }
425 else
426 gfc_add_expr_to_block (&se.pre, se.expr);
427
428 gfc_add_block_to_block (&se.pre, &se.post);
6de9cd9a 429 }
48474141 430
6de9cd9a 431 else
48474141
PT
432 {
433 /* An elemental subroutine call with array valued arguments has
434 to be scalarized. */
435 gfc_loopinfo loop;
436 stmtblock_t body;
437 stmtblock_t block;
438 gfc_se loopse;
70e72065 439 gfc_se depse;
48474141
PT
440
441 /* gfc_walk_elemental_function_args renders the ss chain in the
12f681a0 442 reverse order to the actual argument order. */
48474141
PT
443 ss = gfc_reverse_ss (ss);
444
445 /* Initialize the loop. */
446 gfc_init_se (&loopse, NULL);
447 gfc_init_loopinfo (&loop);
448 gfc_add_ss_to_loop (&loop, ss);
449
450 gfc_conv_ss_startstride (&loop);
8b704316
PT
451 /* TODO: gfc_conv_loop_setup generates a temporary for vector
452 subscripts. This could be prevented in the elemental case
453 as temporaries are handled separatedly
2b0bd714 454 (below in gfc_conv_elemental_dependencies). */
88016532
JD
455 if (code->expr1)
456 gfc_conv_loop_setup (&loop, &code->expr1->where);
457 else
458 gfc_conv_loop_setup (&loop, &code->loc);
459
48474141
PT
460 gfc_mark_ss_chain_used (ss, 1);
461
476220e7
PT
462 /* Convert the arguments, checking for dependencies. */
463 gfc_copy_loopinfo_to_se (&loopse, &loop);
464 loopse.ss = ss;
465
06bcd751 466 /* For operator assignment, do dependency checking. */
476220e7 467 if (dependency_check)
2b0bd714
MM
468 check_variable = ELEM_CHECK_VARIABLE;
469 else
470 check_variable = ELEM_DONT_CHECK_VARIABLE;
70e72065
MM
471
472 gfc_init_se (&depse, NULL);
473 gfc_conv_elemental_dependencies (&depse, &loopse, code->resolved_sym,
2b0bd714 474 code->ext.actual, check_variable);
476220e7 475
70e72065
MM
476 gfc_add_block_to_block (&loop.pre, &depse.pre);
477 gfc_add_block_to_block (&loop.post, &depse.post);
478
48474141
PT
479 /* Generate the loop body. */
480 gfc_start_scalarized_body (&loop, &body);
481 gfc_init_block (&block);
48474141 482
eb74e79b
PT
483 if (mask && count1)
484 {
485 /* Form the mask expression according to the mask. */
486 index = count1;
487 maskexpr = gfc_build_array_ref (mask, index, NULL);
488 if (invert)
bc98ed60
TB
489 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
490 TREE_TYPE (maskexpr), maskexpr);
eb74e79b
PT
491 }
492
48474141 493 /* Add the subroutine call to the block. */
eb74e79b 494 gfc_conv_procedure_call (&loopse, code->resolved_sym,
9771b263
DN
495 code->ext.actual, code->expr1,
496 NULL);
eb74e79b
PT
497
498 if (mask && count1)
499 {
500 tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
c2255bc4 501 build_empty_stmt (input_location));
eb74e79b 502 gfc_add_expr_to_block (&loopse.pre, tmp);
bc98ed60
TB
503 tmp = fold_build2_loc (input_location, PLUS_EXPR,
504 gfc_array_index_type,
505 count1, gfc_index_one_node);
eb74e79b
PT
506 gfc_add_modify (&loopse.pre, count1, tmp);
507 }
508 else
509 gfc_add_expr_to_block (&loopse.pre, loopse.expr);
48474141
PT
510
511 gfc_add_block_to_block (&block, &loopse.pre);
512 gfc_add_block_to_block (&block, &loopse.post);
513
514 /* Finish up the loop block and the loop. */
515 gfc_add_expr_to_block (&body, gfc_finish_block (&block));
516 gfc_trans_scalarizing_loops (&loop, &body);
517 gfc_add_block_to_block (&se.pre, &loop.pre);
518 gfc_add_block_to_block (&se.pre, &loop.post);
476220e7 519 gfc_add_block_to_block (&se.pre, &se.post);
48474141
PT
520 gfc_cleanup_loop (&loop);
521 }
6de9cd9a 522
6de9cd9a
DN
523 return gfc_finish_block (&se.pre);
524}
525
526
527/* Translate the RETURN statement. */
528
529tree
d74d8807 530gfc_trans_return (gfc_code * code)
6de9cd9a 531{
a513927a 532 if (code->expr1)
6de9cd9a
DN
533 {
534 gfc_se se;
535 tree tmp;
536 tree result;
537
da4c6ed8 538 /* If code->expr is not NULL, this return statement must appear
d74d8807 539 in a subroutine and current_fake_result_decl has already
6de9cd9a
DN
540 been generated. */
541
5f20c93a 542 result = gfc_get_fake_result_decl (NULL, 0);
6de9cd9a 543 if (!result)
d74d8807 544 {
db30e21c
JM
545 gfc_warning (0,
546 "An alternate return at %L without a * dummy argument",
48749dbc 547 &code->expr1->where);
d74d8807
DK
548 return gfc_generate_return ();
549 }
6de9cd9a
DN
550
551 /* Start a new block for this statement. */
552 gfc_init_se (&se, NULL);
553 gfc_start_block (&se.pre);
554
a513927a 555 gfc_conv_expr (&se, code->expr1);
6de9cd9a 556
ba3ff5c2
DK
557 /* Note that the actually returned expression is a simple value and
558 does not depend on any pointers or such; thus we can clean-up with
559 se.post before returning. */
bc98ed60
TB
560 tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (result),
561 result, fold_convert (TREE_TYPE (result),
562 se.expr));
6de9cd9a 563 gfc_add_expr_to_block (&se.pre, tmp);
ba3ff5c2 564 gfc_add_block_to_block (&se.pre, &se.post);
6de9cd9a 565
d74d8807 566 tmp = gfc_generate_return ();
6de9cd9a 567 gfc_add_expr_to_block (&se.pre, tmp);
6de9cd9a
DN
568 return gfc_finish_block (&se.pre);
569 }
d74d8807
DK
570
571 return gfc_generate_return ();
6de9cd9a
DN
572}
573
574
575/* Translate the PAUSE statement. We have to translate this statement
576 to a runtime library call. */
577
578tree
579gfc_trans_pause (gfc_code * code)
580{
6cc22cf4 581 tree gfc_int8_type_node = gfc_get_int_type (8);
6de9cd9a 582 gfc_se se;
6de9cd9a 583 tree tmp;
6de9cd9a
DN
584
585 /* Start a new block for this statement. */
586 gfc_init_se (&se, NULL);
587 gfc_start_block (&se.pre);
588
589
a513927a 590 if (code->expr1 == NULL)
6de9cd9a 591 {
6cc22cf4 592 tmp = build_int_cst (size_type_node, 0);
db3927fb 593 tmp = build_call_expr_loc (input_location,
6d1b0f92
JD
594 gfor_fndecl_pause_string, 2,
595 build_int_cst (pchar_type_node, 0), tmp);
596 }
597 else if (code->expr1->ts.type == BT_INTEGER)
598 {
599 gfc_conv_expr (&se, code->expr1);
600 tmp = build_call_expr_loc (input_location,
601 gfor_fndecl_pause_numeric, 1,
6cc22cf4 602 fold_convert (gfc_int8_type_node, se.expr));
6de9cd9a
DN
603 }
604 else
605 {
a513927a 606 gfc_conv_expr_reference (&se, code->expr1);
db3927fb
AH
607 tmp = build_call_expr_loc (input_location,
608 gfor_fndecl_pause_string, 2,
6cc22cf4
JB
609 se.expr, fold_convert (size_type_node,
610 se.string_length));
6de9cd9a
DN
611 }
612
6de9cd9a
DN
613 gfc_add_expr_to_block (&se.pre, tmp);
614
615 gfc_add_block_to_block (&se.pre, &se.post);
616
617 return gfc_finish_block (&se.pre);
618}
619
620
621/* Translate the STOP statement. We have to translate this statement
622 to a runtime library call. */
623
624tree
d0a4a61c 625gfc_trans_stop (gfc_code *code, bool error_stop)
6de9cd9a
DN
626{
627 gfc_se se;
6de9cd9a 628 tree tmp;
6de9cd9a
DN
629
630 /* Start a new block for this statement. */
631 gfc_init_se (&se, NULL);
632 gfc_start_block (&se.pre);
633
a513927a 634 if (code->expr1 == NULL)
6de9cd9a 635 {
3f5fabc0 636 tmp = build_int_cst (size_type_node, 0);
6d1b0f92 637 tmp = build_call_expr_loc (input_location,
60386f50 638 error_stop
f19626cf 639 ? (flag_coarray == GFC_FCOARRAY_LIB
60386f50
TB
640 ? gfor_fndecl_caf_error_stop_str
641 : gfor_fndecl_error_stop_string)
0daa7ed9
AF
642 : (flag_coarray == GFC_FCOARRAY_LIB
643 ? gfor_fndecl_caf_stop_str
644 : gfor_fndecl_stop_string),
dffb1e22
JB
645 3, build_int_cst (pchar_type_node, 0), tmp,
646 boolean_false_node);
6d1b0f92
JD
647 }
648 else if (code->expr1->ts.type == BT_INTEGER)
649 {
650 gfc_conv_expr (&se, code->expr1);
db3927fb 651 tmp = build_call_expr_loc (input_location,
60386f50 652 error_stop
f19626cf 653 ? (flag_coarray == GFC_FCOARRAY_LIB
60386f50
TB
654 ? gfor_fndecl_caf_error_stop
655 : gfor_fndecl_error_stop_numeric)
0daa7ed9
AF
656 : (flag_coarray == GFC_FCOARRAY_LIB
657 ? gfor_fndecl_caf_stop_numeric
dffb1e22
JB
658 : gfor_fndecl_stop_numeric), 2,
659 fold_convert (integer_type_node, se.expr),
660 boolean_false_node);
6de9cd9a
DN
661 }
662 else
663 {
a513927a 664 gfc_conv_expr_reference (&se, code->expr1);
db3927fb 665 tmp = build_call_expr_loc (input_location,
60386f50 666 error_stop
f19626cf 667 ? (flag_coarray == GFC_FCOARRAY_LIB
60386f50
TB
668 ? gfor_fndecl_caf_error_stop_str
669 : gfor_fndecl_error_stop_string)
0daa7ed9
AF
670 : (flag_coarray == GFC_FCOARRAY_LIB
671 ? gfor_fndecl_caf_stop_str
672 : gfor_fndecl_stop_string),
dffb1e22
JB
673 3, se.expr, fold_convert (size_type_node,
674 se.string_length),
675 boolean_false_node);
6de9cd9a
DN
676 }
677
6de9cd9a
DN
678 gfc_add_expr_to_block (&se.pre, tmp);
679
680 gfc_add_block_to_block (&se.pre, &se.post);
681
682 return gfc_finish_block (&se.pre);
683}
684
ef78bc3c
AV
685/* Translate the FAIL IMAGE statement. */
686
687tree
688gfc_trans_fail_image (gfc_code *code ATTRIBUTE_UNUSED)
689{
690 if (flag_coarray == GFC_FCOARRAY_LIB)
691 return build_call_expr_loc (input_location,
692 gfor_fndecl_caf_fail_image, 1,
693 build_int_cst (pchar_type_node, 0));
694 else
695 {
696 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
697 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
698 tree tmp = gfc_get_symbol_decl (exsym);
699 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
700 }
701}
702
f8862a1b
DR
703/* Translate the FORM TEAM statement. */
704
705tree
706gfc_trans_form_team (gfc_code *code)
707{
708 if (flag_coarray == GFC_FCOARRAY_LIB)
709 {
710 gfc_se argse;
711 tree team_id,team_type;
712 gfc_init_se (&argse, NULL);
713 gfc_conv_expr_val (&argse, code->expr1);
714 team_id = fold_convert (integer_type_node, argse.expr);
715 gfc_init_se (&argse, NULL);
716 gfc_conv_expr_val (&argse, code->expr2);
717 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
718
719 return build_call_expr_loc (input_location,
720 gfor_fndecl_caf_form_team, 3,
721 team_id, team_type,
722 build_int_cst (integer_type_node, 0));
723 }
724 else
725 {
726 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
727 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
728 tree tmp = gfc_get_symbol_decl (exsym);
729 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
730 }
731}
732
733/* Translate the CHANGE TEAM statement. */
734
735tree
736gfc_trans_change_team (gfc_code *code)
737{
738 if (flag_coarray == GFC_FCOARRAY_LIB)
739 {
740 gfc_se argse;
741 tree team_type;
742
743 gfc_init_se (&argse, NULL);
744 gfc_conv_expr_val (&argse, code->expr1);
745 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
746
747 return build_call_expr_loc (input_location,
748 gfor_fndecl_caf_change_team, 2, team_type,
749 build_int_cst (integer_type_node, 0));
750 }
751 else
752 {
753 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
754 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
755 tree tmp = gfc_get_symbol_decl (exsym);
756 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
757 }
758}
759
760/* Translate the END TEAM statement. */
761
762tree
763gfc_trans_end_team (gfc_code *code ATTRIBUTE_UNUSED)
764{
765 if (flag_coarray == GFC_FCOARRAY_LIB)
766 {
767 return build_call_expr_loc (input_location,
768 gfor_fndecl_caf_end_team, 1,
769 build_int_cst (pchar_type_node, 0));
770 }
771 else
772 {
773 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
774 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
775 tree tmp = gfc_get_symbol_decl (exsym);
776 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
777 }
778}
779
780/* Translate the SYNC TEAM statement. */
781
782tree
783gfc_trans_sync_team (gfc_code *code)
784{
785 if (flag_coarray == GFC_FCOARRAY_LIB)
786 {
787 gfc_se argse;
788 tree team_type;
789
790 gfc_init_se (&argse, NULL);
791 gfc_conv_expr_val (&argse, code->expr1);
792 team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);
793
794 return build_call_expr_loc (input_location,
795 gfor_fndecl_caf_sync_team, 2,
796 team_type,
797 build_int_cst (integer_type_node, 0));
798 }
799 else
800 {
801 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
802 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
803 tree tmp = gfc_get_symbol_decl (exsym);
804 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
805 }
806}
6de9cd9a 807
fea54935 808tree
9f3880d1 809gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
fea54935
TB
810{
811 gfc_se se, argse;
9f3880d1
TB
812 tree stat = NULL_TREE, stat2 = NULL_TREE;
813 tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
fea54935
TB
814
815 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
816 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
f19626cf 817 if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
8b704316 818 return NULL_TREE;
fea54935 819
fea54935
TB
820 if (code->expr2)
821 {
822 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
823 gfc_init_se (&argse, NULL);
824 gfc_conv_expr_val (&argse, code->expr2);
825 stat = argse.expr;
826 }
9f3880d1
TB
827 else if (flag_coarray == GFC_FCOARRAY_LIB)
828 stat = null_pointer_node;
fea54935
TB
829
830 if (code->expr4)
831 {
832 gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
833 gfc_init_se (&argse, NULL);
834 gfc_conv_expr_val (&argse, code->expr4);
835 lock_acquired = argse.expr;
836 }
9f3880d1
TB
837 else if (flag_coarray == GFC_FCOARRAY_LIB)
838 lock_acquired = null_pointer_node;
839
840 gfc_start_block (&se.pre);
841 if (flag_coarray == GFC_FCOARRAY_LIB)
842 {
843 tree tmp, token, image_index, errmsg, errmsg_len;
844 tree index = size_zero_node;
845 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
846
847 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
848 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
849 != INTMOD_ISO_FORTRAN_ENV
850 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
851 != ISOFORTRAN_LOCK_TYPE)
852 {
853 gfc_error ("Sorry, the lock component of derived type at %L is not "
854 "yet supported", &code->expr1->where);
855 return NULL_TREE;
856 }
857
3c9f5092
AV
858 gfc_get_caf_token_offset (&se, &token, NULL, caf_decl, NULL_TREE,
859 code->expr1);
9f3880d1
TB
860
861 if (gfc_is_coindexed (code->expr1))
862 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
863 else
864 image_index = integer_zero_node;
865
866 /* For arrays, obtain the array index. */
867 if (gfc_expr_attr (code->expr1).dimension)
868 {
869 tree desc, tmp, extent, lbound, ubound;
870 gfc_array_ref *ar, ar2;
871 int i;
872
873 /* TODO: Extend this, once DT components are supported. */
874 ar = &code->expr1->ref->u.ar;
875 ar2 = *ar;
876 memset (ar, '\0', sizeof (*ar));
877 ar->as = ar2.as;
878 ar->type = AR_FULL;
879
880 gfc_init_se (&argse, NULL);
881 argse.descriptor_only = 1;
882 gfc_conv_expr_descriptor (&argse, code->expr1);
883 gfc_add_block_to_block (&se.pre, &argse.pre);
884 desc = argse.expr;
885 *ar = ar2;
886
887 extent = integer_one_node;
888 for (i = 0; i < ar->dimen; i++)
889 {
890 gfc_init_se (&argse, NULL);
891 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
892 gfc_add_block_to_block (&argse.pre, &argse.pre);
893 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
894 tmp = fold_build2_loc (input_location, MINUS_EXPR,
895 integer_type_node, argse.expr,
896 fold_convert(integer_type_node, lbound));
897 tmp = fold_build2_loc (input_location, MULT_EXPR,
898 integer_type_node, extent, tmp);
899 index = fold_build2_loc (input_location, PLUS_EXPR,
900 integer_type_node, index, tmp);
901 if (i < ar->dimen - 1)
902 {
903 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
904 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
905 tmp = fold_convert (integer_type_node, tmp);
906 extent = fold_build2_loc (input_location, MULT_EXPR,
907 integer_type_node, extent, tmp);
908 }
909 }
910 }
911
912 /* errmsg. */
913 if (code->expr3)
914 {
915 gfc_init_se (&argse, NULL);
5df445a2 916 argse.want_pointer = 1;
9f3880d1
TB
917 gfc_conv_expr (&argse, code->expr3);
918 gfc_add_block_to_block (&se.pre, &argse.pre);
919 errmsg = argse.expr;
3f5fabc0 920 errmsg_len = fold_convert (size_type_node, argse.string_length);
9f3880d1
TB
921 }
922 else
923 {
924 errmsg = null_pointer_node;
3f5fabc0 925 errmsg_len = build_zero_cst (size_type_node);
9f3880d1
TB
926 }
927
928 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
929 {
930 stat2 = stat;
931 stat = gfc_create_var (integer_type_node, "stat");
932 }
933
934 if (lock_acquired != null_pointer_node
935 && TREE_TYPE (lock_acquired) != integer_type_node)
936 {
937 lock_acquired2 = lock_acquired;
938 lock_acquired = gfc_create_var (integer_type_node, "acquired");
939 }
940
941 if (op == EXEC_LOCK)
942 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
943 token, index, image_index,
944 lock_acquired != null_pointer_node
945 ? gfc_build_addr_expr (NULL, lock_acquired)
946 : lock_acquired,
947 stat != null_pointer_node
948 ? gfc_build_addr_expr (NULL, stat) : stat,
949 errmsg, errmsg_len);
950 else
951 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
952 token, index, image_index,
953 stat != null_pointer_node
954 ? gfc_build_addr_expr (NULL, stat) : stat,
955 errmsg, errmsg_len);
956 gfc_add_expr_to_block (&se.pre, tmp);
957
985f6c79
TB
958 /* It guarantees memory consistency within the same segment */
959 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
960 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
961 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
962 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
963 ASM_VOLATILE_P (tmp) = 1;
964
965 gfc_add_expr_to_block (&se.pre, tmp);
966
9f3880d1
TB
967 if (stat2 != NULL_TREE)
968 gfc_add_modify (&se.pre, stat2,
969 fold_convert (TREE_TYPE (stat2), stat));
970
971 if (lock_acquired2 != NULL_TREE)
972 gfc_add_modify (&se.pre, lock_acquired2,
973 fold_convert (TREE_TYPE (lock_acquired2),
974 lock_acquired));
975
976 return gfc_finish_block (&se.pre);
977 }
fea54935
TB
978
979 if (stat != NULL_TREE)
980 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
981
982 if (lock_acquired != NULL_TREE)
983 gfc_add_modify (&se.pre, lock_acquired,
984 fold_convert (TREE_TYPE (lock_acquired),
985 boolean_true_node));
986
987 return gfc_finish_block (&se.pre);
988}
989
5df445a2
TB
990tree
991gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op)
992{
993 gfc_se se, argse;
994 tree stat = NULL_TREE, stat2 = NULL_TREE;
995 tree until_count = NULL_TREE;
996
997 if (code->expr2)
998 {
999 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1000 gfc_init_se (&argse, NULL);
1001 gfc_conv_expr_val (&argse, code->expr2);
1002 stat = argse.expr;
1003 }
1004 else if (flag_coarray == GFC_FCOARRAY_LIB)
1005 stat = null_pointer_node;
1006
1007 if (code->expr4)
1008 {
1009 gfc_init_se (&argse, NULL);
1010 gfc_conv_expr_val (&argse, code->expr4);
1011 until_count = fold_convert (integer_type_node, argse.expr);
1012 }
1013 else
1014 until_count = integer_one_node;
1015
1016 if (flag_coarray != GFC_FCOARRAY_LIB)
1017 {
1018 gfc_start_block (&se.pre);
1019 gfc_init_se (&argse, NULL);
1020 gfc_conv_expr_val (&argse, code->expr1);
1021
1022 if (op == EXEC_EVENT_POST)
1023 gfc_add_modify (&se.pre, argse.expr,
1024 fold_build2_loc (input_location, PLUS_EXPR,
1025 TREE_TYPE (argse.expr), argse.expr,
1026 build_int_cst (TREE_TYPE (argse.expr), 1)));
1027 else
1028 gfc_add_modify (&se.pre, argse.expr,
1029 fold_build2_loc (input_location, MINUS_EXPR,
1030 TREE_TYPE (argse.expr), argse.expr,
1031 fold_convert (TREE_TYPE (argse.expr),
1032 until_count)));
1033 if (stat != NULL_TREE)
1034 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1035
1036 return gfc_finish_block (&se.pre);
1037 }
1038
1039 gfc_start_block (&se.pre);
1040 tree tmp, token, image_index, errmsg, errmsg_len;
1041 tree index = size_zero_node;
1042 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
1043
1044 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
1045 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
1046 != INTMOD_ISO_FORTRAN_ENV
1047 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
1048 != ISOFORTRAN_EVENT_TYPE)
1049 {
1050 gfc_error ("Sorry, the event component of derived type at %L is not "
1051 "yet supported", &code->expr1->where);
1052 return NULL_TREE;
1053 }
1054
3c9f5092
AV
1055 gfc_init_se (&argse, NULL);
1056 gfc_get_caf_token_offset (&argse, &token, NULL, caf_decl, NULL_TREE,
1057 code->expr1);
1058 gfc_add_block_to_block (&se.pre, &argse.pre);
5df445a2
TB
1059
1060 if (gfc_is_coindexed (code->expr1))
1061 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
1062 else
1063 image_index = integer_zero_node;
1064
1065 /* For arrays, obtain the array index. */
1066 if (gfc_expr_attr (code->expr1).dimension)
1067 {
1068 tree desc, tmp, extent, lbound, ubound;
1069 gfc_array_ref *ar, ar2;
1070 int i;
1071
1072 /* TODO: Extend this, once DT components are supported. */
1073 ar = &code->expr1->ref->u.ar;
1074 ar2 = *ar;
1075 memset (ar, '\0', sizeof (*ar));
1076 ar->as = ar2.as;
1077 ar->type = AR_FULL;
1078
1079 gfc_init_se (&argse, NULL);
1080 argse.descriptor_only = 1;
1081 gfc_conv_expr_descriptor (&argse, code->expr1);
1082 gfc_add_block_to_block (&se.pre, &argse.pre);
1083 desc = argse.expr;
1084 *ar = ar2;
1085
1086 extent = integer_one_node;
1087 for (i = 0; i < ar->dimen; i++)
1088 {
1089 gfc_init_se (&argse, NULL);
1090 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
1091 gfc_add_block_to_block (&argse.pre, &argse.pre);
1092 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
1093 tmp = fold_build2_loc (input_location, MINUS_EXPR,
1094 integer_type_node, argse.expr,
1095 fold_convert(integer_type_node, lbound));
1096 tmp = fold_build2_loc (input_location, MULT_EXPR,
1097 integer_type_node, extent, tmp);
1098 index = fold_build2_loc (input_location, PLUS_EXPR,
cbd29d0e
AS
1099 gfc_array_index_type, index,
1100 fold_convert (gfc_array_index_type, tmp));
5df445a2
TB
1101 if (i < ar->dimen - 1)
1102 {
1103 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
1104 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
1105 tmp = fold_convert (integer_type_node, tmp);
1106 extent = fold_build2_loc (input_location, MULT_EXPR,
1107 integer_type_node, extent, tmp);
1108 }
1109 }
1110 }
1111
1112 /* errmsg. */
1113 if (code->expr3)
1114 {
1115 gfc_init_se (&argse, NULL);
1116 argse.want_pointer = 1;
1117 gfc_conv_expr (&argse, code->expr3);
1118 gfc_add_block_to_block (&se.pre, &argse.pre);
1119 errmsg = argse.expr;
3f5fabc0 1120 errmsg_len = fold_convert (size_type_node, argse.string_length);
5df445a2
TB
1121 }
1122 else
1123 {
1124 errmsg = null_pointer_node;
3f5fabc0 1125 errmsg_len = build_zero_cst (size_type_node);
5df445a2
TB
1126 }
1127
1128 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
1129 {
1130 stat2 = stat;
1131 stat = gfc_create_var (integer_type_node, "stat");
1132 }
1133
cbd29d0e 1134 index = fold_convert (size_type_node, index);
5df445a2
TB
1135 if (op == EXEC_EVENT_POST)
1136 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_post, 6,
1137 token, index, image_index,
1138 stat != null_pointer_node
1139 ? gfc_build_addr_expr (NULL, stat) : stat,
1140 errmsg, errmsg_len);
1141 else
1142 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_wait, 6,
1143 token, index, until_count,
1144 stat != null_pointer_node
1145 ? gfc_build_addr_expr (NULL, stat) : stat,
1146 errmsg, errmsg_len);
1147 gfc_add_expr_to_block (&se.pre, tmp);
1148
985f6c79
TB
1149 /* It guarantees memory consistency within the same segment */
1150 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1151 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1152 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1153 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1154 ASM_VOLATILE_P (tmp) = 1;
1155 gfc_add_expr_to_block (&se.pre, tmp);
1156
5df445a2
TB
1157 if (stat2 != NULL_TREE)
1158 gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat));
1159
1160 return gfc_finish_block (&se.pre);
1161}
fea54935 1162
d0a4a61c 1163tree
60386f50 1164gfc_trans_sync (gfc_code *code, gfc_exec_op type)
d0a4a61c 1165{
60386f50
TB
1166 gfc_se se, argse;
1167 tree tmp;
1168 tree images = NULL_TREE, stat = NULL_TREE,
1169 errmsg = NULL_TREE, errmsglen = NULL_TREE;
d0a4a61c 1170
60386f50
TB
1171 /* Short cut: For single images without bound checking or without STAT=,
1172 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
1173 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
f19626cf 1174 && flag_coarray != GFC_FCOARRAY_LIB)
8b704316 1175 return NULL_TREE;
60386f50
TB
1176
1177 gfc_init_se (&se, NULL);
1178 gfc_start_block (&se.pre);
1179
1180 if (code->expr1 && code->expr1->rank == 0)
d0a4a61c 1181 {
60386f50
TB
1182 gfc_init_se (&argse, NULL);
1183 gfc_conv_expr_val (&argse, code->expr1);
1184 images = argse.expr;
1185 }
1186
1187 if (code->expr2)
1188 {
1189 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1190 gfc_init_se (&argse, NULL);
1191 gfc_conv_expr_val (&argse, code->expr2);
1192 stat = argse.expr;
1193 }
f5c01f5b
DC
1194 else
1195 stat = null_pointer_node;
60386f50 1196
9315dff0 1197 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
60386f50
TB
1198 {
1199 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
1200 gfc_init_se (&argse, NULL);
5df445a2 1201 argse.want_pointer = 1;
60386f50
TB
1202 gfc_conv_expr (&argse, code->expr3);
1203 gfc_conv_string_parameter (&argse);
f5c01f5b 1204 errmsg = gfc_build_addr_expr (NULL, argse.expr);
3f5fabc0 1205 errmsglen = fold_convert (size_type_node, argse.string_length);
60386f50 1206 }
9315dff0 1207 else if (flag_coarray == GFC_FCOARRAY_LIB)
60386f50
TB
1208 {
1209 errmsg = null_pointer_node;
3f5fabc0 1210 errmsglen = build_int_cst (size_type_node, 0);
d0a4a61c
TB
1211 }
1212
1213 /* Check SYNC IMAGES(imageset) for valid image index.
1cc0e193 1214 FIXME: Add a check for image-set arrays. */
d0a4a61c
TB
1215 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1216 && code->expr1->rank == 0)
1217 {
1218 tree cond;
f19626cf 1219 if (flag_coarray != GFC_FCOARRAY_LIB)
63ee5404 1220 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
60386f50
TB
1221 images, build_int_cst (TREE_TYPE (images), 1));
1222 else
1223 {
1224 tree cond2;
a8a5f4a9
TB
1225 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
1226 2, integer_zero_node,
1227 build_int_cst (integer_type_node, -1));
63ee5404 1228 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
a8a5f4a9 1229 images, tmp);
63ee5404 1230 cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
60386f50
TB
1231 images,
1232 build_int_cst (TREE_TYPE (images), 1));
45d5889a 1233 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
63ee5404 1234 logical_type_node, cond, cond2);
60386f50 1235 }
d0a4a61c
TB
1236 gfc_trans_runtime_check (true, false, cond, &se.pre,
1237 &code->expr1->where, "Invalid image number "
1238 "%d in SYNC IMAGES",
74c49505 1239 fold_convert (integer_type_node, images));
d0a4a61c
TB
1240 }
1241
985f6c79
TB
1242 /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the
1243 image control statements SYNC IMAGES and SYNC ALL. */
1244 if (flag_coarray == GFC_FCOARRAY_LIB)
1245 {
1246 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1247 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1248 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1249 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1250 ASM_VOLATILE_P (tmp) = 1;
1251 gfc_add_expr_to_block (&se.pre, tmp);
1252 }
1253
9315dff0 1254 if (flag_coarray != GFC_FCOARRAY_LIB)
d0a4a61c 1255 {
60386f50
TB
1256 /* Set STAT to zero. */
1257 if (code->expr2)
1258 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1259 }
9315dff0 1260 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
60386f50 1261 {
f5c01f5b
DC
1262 /* SYNC ALL => stat == null_pointer_node
1263 SYNC ALL(stat=s) => stat has an integer type
1264
1265 If "stat" has the wrong integer type, use a temp variable of
1266 the right type and later cast the result back into "stat". */
1267 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1268 {
1269 if (TREE_TYPE (stat) == integer_type_node)
1270 stat = gfc_build_addr_expr (NULL, stat);
8b704316 1271
9315dff0
AF
1272 if(type == EXEC_SYNC_MEMORY)
1273 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
1274 3, stat, errmsg, errmsglen);
1275 else
1276 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1277 3, stat, errmsg, errmsglen);
1278
f5c01f5b
DC
1279 gfc_add_expr_to_block (&se.pre, tmp);
1280 }
60386f50 1281 else
f5c01f5b
DC
1282 {
1283 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1284
1285 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1286 3, gfc_build_addr_expr (NULL, tmp_stat),
1287 errmsg, errmsglen);
1288 gfc_add_expr_to_block (&se.pre, tmp);
8b704316 1289
f5c01f5b
DC
1290 gfc_add_modify (&se.pre, stat,
1291 fold_convert (TREE_TYPE (stat), tmp_stat));
1292 }
60386f50
TB
1293 }
1294 else
1295 {
1296 tree len;
1297
1298 gcc_assert (type == EXEC_SYNC_IMAGES);
1299
1300 if (!code->expr1)
1301 {
1302 len = build_int_cst (integer_type_node, -1);
1303 images = null_pointer_node;
1304 }
1305 else if (code->expr1->rank == 0)
1306 {
1307 len = build_int_cst (integer_type_node, 1);
1308 images = gfc_build_addr_expr (NULL_TREE, images);
1309 }
1310 else
1311 {
1312 /* FIXME. */
1313 if (code->expr1->ts.kind != gfc_c_int_kind)
29e0597e
TB
1314 gfc_fatal_error ("Sorry, only support for integer kind %d "
1315 "implemented for image-set at %L",
1316 gfc_c_int_kind, &code->expr1->where);
60386f50 1317
2960a368 1318 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
60386f50
TB
1319 images = se.expr;
1320
1321 tmp = gfc_typenode_for_spec (&code->expr1->ts);
1322 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
1323 tmp = gfc_get_element_type (tmp);
1324
1325 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1326 TREE_TYPE (len), len,
1327 fold_convert (TREE_TYPE (len),
1328 TYPE_SIZE_UNIT (tmp)));
1329 len = fold_convert (integer_type_node, len);
1330 }
1331
f5c01f5b
DC
1332 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1333 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1334
1335 If "stat" has the wrong integer type, use a temp variable of
1336 the right type and later cast the result back into "stat". */
1337 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1338 {
1339 if (TREE_TYPE (stat) == integer_type_node)
1340 stat = gfc_build_addr_expr (NULL, stat);
1341
8b704316 1342 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
f5c01f5b
DC
1343 5, fold_convert (integer_type_node, len),
1344 images, stat, errmsg, errmsglen);
1345 gfc_add_expr_to_block (&se.pre, tmp);
1346 }
60386f50 1347 else
f5c01f5b
DC
1348 {
1349 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1350
8b704316 1351 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
f5c01f5b
DC
1352 5, fold_convert (integer_type_node, len),
1353 images, gfc_build_addr_expr (NULL, tmp_stat),
1354 errmsg, errmsglen);
1355 gfc_add_expr_to_block (&se.pre, tmp);
1356
8b704316 1357 gfc_add_modify (&se.pre, stat,
f5c01f5b
DC
1358 fold_convert (TREE_TYPE (stat), tmp_stat));
1359 }
d0a4a61c
TB
1360 }
1361
60386f50 1362 return gfc_finish_block (&se.pre);
d0a4a61c
TB
1363}
1364
1365
6de9cd9a
DN
1366/* Generate GENERIC for the IF construct. This function also deals with
1367 the simple IF statement, because the front end translates the IF
1368 statement into an IF construct.
1369
1370 We translate:
1371
1372 IF (cond) THEN
1373 then_clause
1374 ELSEIF (cond2)
1375 elseif_clause
1376 ELSE
1377 else_clause
1378 ENDIF
1379
1380 into:
1381
1382 pre_cond_s;
1383 if (cond_s)
1384 {
1385 then_clause;
1386 }
1387 else
1388 {
1389 pre_cond_s
1390 if (cond_s)
1391 {
1392 elseif_clause
1393 }
1394 else
1395 {
1396 else_clause;
1397 }
1398 }
1399
1400 where COND_S is the simplified version of the predicate. PRE_COND_S
1401 are the pre side-effects produced by the translation of the
1402 conditional.
1403 We need to build the chain recursively otherwise we run into
1404 problems with folding incomplete statements. */
1405
1406static tree
1407gfc_trans_if_1 (gfc_code * code)
1408{
1409 gfc_se if_se;
1410 tree stmt, elsestmt;
e84589e1 1411 locus saved_loc;
55bd9c35 1412 location_t loc;
6de9cd9a
DN
1413
1414 /* Check for an unconditional ELSE clause. */
a513927a 1415 if (!code->expr1)
6de9cd9a
DN
1416 return gfc_trans_code (code->next);
1417
1418 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1419 gfc_init_se (&if_se, NULL);
1420 gfc_start_block (&if_se.pre);
1421
1422 /* Calculate the IF condition expression. */
e84589e1
TB
1423 if (code->expr1->where.lb)
1424 {
1425 gfc_save_backend_locus (&saved_loc);
1426 gfc_set_backend_locus (&code->expr1->where);
1427 }
1428
a513927a 1429 gfc_conv_expr_val (&if_se, code->expr1);
6de9cd9a 1430
e84589e1
TB
1431 if (code->expr1->where.lb)
1432 gfc_restore_backend_locus (&saved_loc);
1433
6de9cd9a
DN
1434 /* Translate the THEN clause. */
1435 stmt = gfc_trans_code (code->next);
1436
1437 /* Translate the ELSE clause. */
1438 if (code->block)
1439 elsestmt = gfc_trans_if_1 (code->block);
1440 else
c2255bc4 1441 elsestmt = build_empty_stmt (input_location);
6de9cd9a
DN
1442
1443 /* Build the condition expression and add it to the condition block. */
55bd9c35
TB
1444 loc = code->expr1->where.lb ? code->expr1->where.lb->location : input_location;
1445 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1446 elsestmt);
8b704316 1447
6de9cd9a
DN
1448 gfc_add_expr_to_block (&if_se.pre, stmt);
1449
1450 /* Finish off this statement. */
1451 return gfc_finish_block (&if_se.pre);
1452}
1453
1454tree
1455gfc_trans_if (gfc_code * code)
1456{
e5ca9693
DK
1457 stmtblock_t body;
1458 tree exit_label;
1459
1460 /* Create exit label so it is available for trans'ing the body code. */
1461 exit_label = gfc_build_label_decl (NULL_TREE);
1462 code->exit_label = exit_label;
1463
1464 /* Translate the actual code in code->block. */
1465 gfc_init_block (&body);
1466 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1467
1468 /* Add exit label. */
1469 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
6de9cd9a 1470
e5ca9693 1471 return gfc_finish_block (&body);
6de9cd9a
DN
1472}
1473
1474
fa951694 1475/* Translate an arithmetic IF expression.
6de9cd9a
DN
1476
1477 IF (cond) label1, label2, label3 translates to
1478
1479 if (cond <= 0)
1480 {
1481 if (cond < 0)
1482 goto label1;
1483 else // cond == 0
1484 goto label2;
1485 }
1486 else // cond > 0
1487 goto label3;
442c1644
CY
1488
1489 An optimized version can be generated in case of equal labels.
1490 E.g., if label1 is equal to label2, we can translate it to
1491
1492 if (cond <= 0)
1493 goto label1;
1494 else
1495 goto label3;
6de9cd9a
DN
1496*/
1497
1498tree
1499gfc_trans_arithmetic_if (gfc_code * code)
1500{
1501 gfc_se se;
1502 tree tmp;
1503 tree branch1;
1504 tree branch2;
1505 tree zero;
1506
1507 /* Start a new block. */
1508 gfc_init_se (&se, NULL);
1509 gfc_start_block (&se.pre);
1510
1511 /* Pre-evaluate COND. */
a513927a 1512 gfc_conv_expr_val (&se, code->expr1);
5ec1334b 1513 se.expr = gfc_evaluate_now (se.expr, &se.pre);
6de9cd9a
DN
1514
1515 /* Build something to compare with. */
1516 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1517
79bd1948 1518 if (code->label1->value != code->label2->value)
442c1644
CY
1519 {
1520 /* If (cond < 0) take branch1 else take branch2.
1521 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
79bd1948 1522 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
442c1644
CY
1523 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1524
79bd1948 1525 if (code->label1->value != code->label3->value)
63ee5404 1526 tmp = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
bc98ed60 1527 se.expr, zero);
442c1644 1528 else
63ee5404 1529 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
bc98ed60 1530 se.expr, zero);
6de9cd9a 1531
bc98ed60
TB
1532 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1533 tmp, branch1, branch2);
442c1644
CY
1534 }
1535 else
79bd1948 1536 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
6de9cd9a 1537
79bd1948 1538 if (code->label1->value != code->label3->value
442c1644
CY
1539 && code->label2->value != code->label3->value)
1540 {
1541 /* if (cond <= 0) take branch1 else take branch2. */
1542 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
63ee5404 1543 tmp = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
bc98ed60
TB
1544 se.expr, zero);
1545 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1546 tmp, branch1, branch2);
442c1644 1547 }
6de9cd9a
DN
1548
1549 /* Append the COND_EXPR to the evaluation of COND, and return. */
1550 gfc_add_expr_to_block (&se.pre, branch1);
1551 return gfc_finish_block (&se.pre);
1552}
1553
1554
1cc0e193 1555/* Translate a CRITICAL block. */
d0a4a61c
TB
1556tree
1557gfc_trans_critical (gfc_code *code)
1558{
1559 stmtblock_t block;
bc0229f9 1560 tree tmp, token = NULL_TREE;
d0a4a61c
TB
1561
1562 gfc_start_block (&block);
60386f50 1563
f19626cf 1564 if (flag_coarray == GFC_FCOARRAY_LIB)
60386f50 1565 {
bc0229f9
TB
1566 token = gfc_get_symbol_decl (code->resolved_sym);
1567 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1568 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1569 token, integer_zero_node, integer_one_node,
9de8e7af 1570 null_pointer_node, null_pointer_node,
bc0229f9 1571 null_pointer_node, integer_zero_node);
60386f50 1572 gfc_add_expr_to_block (&block, tmp);
985f6c79
TB
1573
1574 /* It guarantees memory consistency within the same segment */
1575 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1576 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1577 gfc_build_string_const (1, ""),
1578 NULL_TREE, NULL_TREE,
1579 tree_cons (NULL_TREE, tmp, NULL_TREE),
1580 NULL_TREE);
1581 ASM_VOLATILE_P (tmp) = 1;
afbc5ae8 1582
985f6c79 1583 gfc_add_expr_to_block (&block, tmp);
60386f50
TB
1584 }
1585
d0a4a61c
TB
1586 tmp = gfc_trans_code (code->block->next);
1587 gfc_add_expr_to_block (&block, tmp);
1588
f19626cf 1589 if (flag_coarray == GFC_FCOARRAY_LIB)
60386f50 1590 {
bc0229f9
TB
1591 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1592 token, integer_zero_node, integer_one_node,
1593 null_pointer_node, null_pointer_node,
1594 integer_zero_node);
60386f50 1595 gfc_add_expr_to_block (&block, tmp);
60386f50 1596
985f6c79
TB
1597 /* It guarantees memory consistency within the same segment */
1598 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1599 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1600 gfc_build_string_const (1, ""),
1601 NULL_TREE, NULL_TREE,
1602 tree_cons (NULL_TREE, tmp, NULL_TREE),
1603 NULL_TREE);
1604 ASM_VOLATILE_P (tmp) = 1;
1605
1606 gfc_add_expr_to_block (&block, tmp);
1607 }
60386f50 1608
d0a4a61c
TB
1609 return gfc_finish_block (&block);
1610}
1611
1612
5b384b3d
PT
1613/* Return true, when the class has a _len component. */
1614
1615static bool
1616class_has_len_component (gfc_symbol *sym)
1617{
1618 gfc_component *comp = sym->ts.u.derived->components;
1619 while (comp)
1620 {
1621 if (strcmp (comp->name, "_len") == 0)
1622 return true;
1623 comp = comp->next;
1624 }
1625 return false;
1626}
1627
1628
6312ef45
JW
1629/* Do proper initialization for ASSOCIATE names. */
1630
1631static void
1632trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1633{
1634 gfc_expr *e;
1635 tree tmp;
c49ea23d 1636 bool class_target;
8b704316 1637 bool unlimited;
8f75db9f
PT
1638 tree desc;
1639 tree offset;
1640 tree dim;
1641 int n;
5b384b3d
PT
1642 tree charlen;
1643 bool need_len_assign;
ff3598bc
PT
1644 bool whole_array = true;
1645 gfc_ref *ref;
707905d0 1646 symbol_attribute attr;
6312ef45
JW
1647
1648 gcc_assert (sym->assoc);
1649 e = sym->assoc->target;
1650
c49ea23d
PT
1651 class_target = (e->expr_type == EXPR_VARIABLE)
1652 && (gfc_is_class_scalar_expr (e)
1653 || gfc_is_class_array_ref (e, NULL));
1654
8b704316
PT
1655 unlimited = UNLIMITED_POLY (e);
1656
ff3598bc
PT
1657 for (ref = e->ref; ref; ref = ref->next)
1658 if (ref->type == REF_ARRAY
1659 && ref->u.ar.type == AR_FULL
1660 && ref->next)
1661 {
1662 whole_array = false;
1663 break;
1664 }
1665
5b384b3d
PT
1666 /* Assignments to the string length need to be generated, when
1667 ( sym is a char array or
1668 sym has a _len component)
1669 and the associated expression is unlimited polymorphic, which is
1670 not (yet) correctly in 'unlimited', because for an already associated
1671 BT_DERIVED the u-poly flag is not set, i.e.,
1672 __tmp_CHARACTER_0_1 => w => arg
1673 ^ generated temp ^ from code, the w does not have the u-poly
1674 flag set, where UNLIMITED_POLY(e) expects it. */
1675 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1676 && e->ts.u.derived->attr.unlimited_polymorphic))
1677 && (sym->ts.type == BT_CHARACTER
1678 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1679 && class_has_len_component (sym))));
6312ef45
JW
1680 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1681 to array temporary) for arrays with either unknown shape or if associating
1682 to a variable. */
c49ea23d 1683 if (sym->attr.dimension && !class_target
6312ef45
JW
1684 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1685 {
1686 gfc_se se;
6312ef45 1687 tree desc;
bcac046f 1688 bool cst_array_ctor;
6312ef45
JW
1689
1690 desc = sym->backend_decl;
bcac046f 1691 cst_array_ctor = e->expr_type == EXPR_ARRAY
84ee745e
PT
1692 && gfc_constant_array_constructor_p (e->value.constructor)
1693 && e->ts.type != BT_CHARACTER;
6312ef45
JW
1694
1695 /* If association is to an expression, evaluate it and create temporary.
1696 Otherwise, get descriptor of target for pointer assignment. */
1697 gfc_init_se (&se, NULL);
bcac046f 1698 if (sym->assoc->variable || cst_array_ctor)
6312ef45
JW
1699 {
1700 se.direct_byref = 1;
1cf43a1d 1701 se.use_offset = 1;
6312ef45
JW
1702 se.expr = desc;
1703 }
1cf43a1d 1704
2960a368 1705 gfc_conv_expr_descriptor (&se, e);
6312ef45 1706
707905d0
PT
1707 if (sym->ts.type == BT_CHARACTER
1708 && sym->ts.deferred
1709 && !sym->attr.select_type_temporary
1710 && VAR_P (sym->ts.u.cl->backend_decl)
1711 && se.string_length != sym->ts.u.cl->backend_decl)
1712 {
1713 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
f622221a 1714 fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
707905d0
PT
1715 se.string_length));
1716 }
1717
6312ef45
JW
1718 /* If we didn't already do the pointer assignment, set associate-name
1719 descriptor to the one generated for the temporary. */
ff3598bc
PT
1720 if ((!sym->assoc->variable && !cst_array_ctor)
1721 || !whole_array)
6312ef45
JW
1722 {
1723 int dim;
1724
ff3598bc
PT
1725 if (whole_array)
1726 gfc_add_modify (&se.pre, desc, se.expr);
6312ef45
JW
1727
1728 /* The generated descriptor has lower bound zero (as array
1729 temporary), shift bounds so we get lower bounds of 1. */
1730 for (dim = 0; dim < e->rank; ++dim)
1731 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1732 dim, gfc_index_one_node);
1733 }
1734
68b1c5e1
PT
1735 /* If this is a subreference array pointer associate name use the
1736 associate variable element size for the value of 'span'. */
1737 if (sym->attr.subref_array_pointer)
1738 {
1739 gcc_assert (e->expr_type == EXPR_VARIABLE);
f82f425b
PT
1740 tmp = gfc_get_array_span (se.expr, e);
1741
ff3598bc 1742 gfc_conv_descriptor_span_set (&se.pre, desc, tmp);
68b1c5e1
PT
1743 }
1744
0b627b58
PT
1745 if (e->expr_type == EXPR_FUNCTION
1746 && sym->ts.type == BT_DERIVED
1747 && sym->ts.u.derived
1748 && sym->ts.u.derived->attr.pdt_type)
1749 {
1750 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, se.expr,
1751 sym->as->rank);
1752 gfc_add_expr_to_block (&se.post, tmp);
1753 }
1754
6312ef45
JW
1755 /* Done, register stuff as init / cleanup code. */
1756 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1757 gfc_finish_block (&se.post));
1758 }
1759
8b704316
PT
1760 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1761 arrays to be assigned directly. */
1762 else if (class_target && sym->attr.dimension
1763 && (sym->ts.type == BT_DERIVED || unlimited))
c49ea23d
PT
1764 {
1765 gfc_se se;
1766
1767 gfc_init_se (&se, NULL);
102344e2 1768 se.descriptor_only = 1;
f3b0bb7a
AV
1769 /* In a select type the (temporary) associate variable shall point to
1770 a standard fortran array (lower bound == 1), but conv_expr ()
1771 just maps to the input array in the class object, whose lbound may
1772 be arbitrary. conv_expr_descriptor solves this by inserting a
1773 temporary array descriptor. */
1774 gfc_conv_expr_descriptor (&se, e);
c49ea23d 1775
f3b0bb7a
AV
1776 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1777 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
c49ea23d
PT
1778 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1779
f3b0bb7a
AV
1780 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1781 {
1782 if (INDIRECT_REF_P (se.expr))
1783 tmp = TREE_OPERAND (se.expr, 0);
1784 else
1785 tmp = se.expr;
1786
1787 gfc_add_modify (&se.pre, sym->backend_decl,
1788 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1789 }
1790 else
1791 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
8b704316
PT
1792
1793 if (unlimited)
1794 {
1795 /* Recover the dtype, which has been overwritten by the
1796 assignment from an unlimited polymorphic object. */
1797 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1798 gfc_add_modify (&se.pre, tmp,
1799 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1800 }
1801
f3b0bb7a 1802 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
c49ea23d
PT
1803 gfc_finish_block (&se.post));
1804 }
1805
6312ef45
JW
1806 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1807 else if (gfc_is_associate_pointer (sym))
1808 {
1809 gfc_se se;
1810
1811 gcc_assert (!sym->attr.dimension);
1812
1813 gfc_init_se (&se, NULL);
8f75db9f
PT
1814
1815 /* Class associate-names come this way because they are
1816 unconditionally associate pointers and the symbol is scalar. */
1817 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
1818 {
5b384b3d 1819 tree target_expr;
8f75db9f 1820 /* For a class array we need a descriptor for the selector. */
2960a368 1821 gfc_conv_expr_descriptor (&se, e);
5b384b3d
PT
1822 /* Needed to get/set the _len component below. */
1823 target_expr = se.expr;
8f75db9f 1824
8b704316 1825 /* Obtain a temporary class container for the result. */
16e82b25 1826 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
8f75db9f
PT
1827 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1828
1829 /* Set the offset. */
1830 desc = gfc_class_data_get (se.expr);
1831 offset = gfc_index_zero_node;
1832 for (n = 0; n < e->rank; n++)
1833 {
1834 dim = gfc_rank_cst[n];
1835 tmp = fold_build2_loc (input_location, MULT_EXPR,
1836 gfc_array_index_type,
1837 gfc_conv_descriptor_stride_get (desc, dim),
1838 gfc_conv_descriptor_lbound_get (desc, dim));
1839 offset = fold_build2_loc (input_location, MINUS_EXPR,
1840 gfc_array_index_type,
1841 offset, tmp);
1842 }
5b384b3d
PT
1843 if (need_len_assign)
1844 {
f3b0bb7a
AV
1845 if (e->symtree
1846 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
1847 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl))
1848 /* Use the original class descriptor stored in the saved
1849 descriptor to get the target_expr. */
1850 target_expr =
1851 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
1852 else
1853 /* Strip the _data component from the target_expr. */
1854 target_expr = TREE_OPERAND (target_expr, 0);
1855 /* Add a reference to the _len comp to the target expr. */
1856 tmp = gfc_class_len_get (target_expr);
5b384b3d
PT
1857 /* Get the component-ref for the temp structure's _len comp. */
1858 charlen = gfc_class_len_get (se.expr);
026c3cfd 1859 /* Add the assign to the beginning of the block... */
5b384b3d
PT
1860 gfc_add_modify (&se.pre, charlen,
1861 fold_convert (TREE_TYPE (charlen), tmp));
1862 /* and the oposite way at the end of the block, to hand changes
1863 on the string length back. */
1864 gfc_add_modify (&se.post, tmp,
1865 fold_convert (TREE_TYPE (tmp), charlen));
1866 /* Length assignment done, prevent adding it again below. */
1867 need_len_assign = false;
1868 }
8f75db9f
PT
1869 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
1870 }
1871 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
1872 && CLASS_DATA (e)->attr.dimension)
1873 {
1874 /* This is bound to be a class array element. */
1875 gfc_conv_expr_reference (&se, e);
8b704316 1876 /* Get the _vptr component of the class object. */
8f75db9f
PT
1877 tmp = gfc_get_vptr_from_expr (se.expr);
1878 /* Obtain a temporary class container for the result. */
16e82b25 1879 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
8f75db9f
PT
1880 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1881 }
1882 else
5b384b3d
PT
1883 {
1884 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1885 which has the string length included. For CHARACTERS it is still
1886 needed and will be done at the end of this routine. */
1887 gfc_conv_expr (&se, e);
1888 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
1889 }
6312ef45 1890
707905d0
PT
1891 if (sym->ts.type == BT_CHARACTER
1892 && sym->ts.deferred
1893 && !sym->attr.select_type_temporary
1894 && VAR_P (sym->ts.u.cl->backend_decl)
1895 && se.string_length != sym->ts.u.cl->backend_decl)
1896 {
1897 gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
f622221a 1898 fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
707905d0
PT
1899 se.string_length));
1900 if (e->expr_type == EXPR_FUNCTION)
1901 {
1902 tmp = gfc_call_free (sym->backend_decl);
1903 gfc_add_expr_to_block (&se.post, tmp);
1904 }
1905 }
1906
1907 attr = gfc_expr_attr (e);
1908 if (sym->ts.type == BT_CHARACTER && e->ts.type == BT_CHARACTER
b14a13fa
PT
1909 && (attr.allocatable || attr.pointer || attr.dummy)
1910 && POINTER_TYPE_P (TREE_TYPE (se.expr)))
707905d0
PT
1911 {
1912 /* These are pointer types already. */
1913 tmp = fold_convert (TREE_TYPE (sym->backend_decl), se.expr);
1914 }
1915 else
1916 {
1917 tmp = TREE_TYPE (sym->backend_decl);
1918 tmp = gfc_build_addr_expr (tmp, se.expr);
1919 }
1920
6312ef45 1921 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
8b704316 1922
6312ef45
JW
1923 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
1924 gfc_finish_block (&se.post));
1925 }
1926
1927 /* Do a simple assignment. This is for scalar expressions, where we
1928 can simply use expression assignment. */
1929 else
1930 {
1931 gfc_expr *lhs;
0b627b58 1932 tree res;
a8399af8
PT
1933 gfc_se se;
1934
1935 gfc_init_se (&se, NULL);
1936
1937 /* resolve.c converts some associate names to allocatable so that
1938 allocation can take place automatically in gfc_trans_assignment.
1939 The frontend prevents them from being either allocated,
1940 deallocated or reallocated. */
1941 if (sym->attr.allocatable)
1942 {
1943 tmp = sym->backend_decl;
1944 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
1945 tmp = gfc_conv_descriptor_data_get (tmp);
1946 gfc_add_modify (&se.pre, tmp, fold_convert (TREE_TYPE (tmp),
1947 null_pointer_node));
1948 }
6312ef45
JW
1949
1950 lhs = gfc_lval_expr_from_sym (sym);
0b627b58 1951 res = gfc_trans_assignment (lhs, e, false, true);
a8399af8 1952 gfc_add_expr_to_block (&se.pre, res);
0b627b58
PT
1953
1954 tmp = sym->backend_decl;
1955 if (e->expr_type == EXPR_FUNCTION
1956 && sym->ts.type == BT_DERIVED
1957 && sym->ts.u.derived
1958 && sym->ts.u.derived->attr.pdt_type)
1959 {
1960 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, tmp,
1961 0);
1962 }
1963 else if (e->expr_type == EXPR_FUNCTION
1964 && sym->ts.type == BT_CLASS
1965 && CLASS_DATA (sym)->ts.u.derived
1966 && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type)
1967 {
1968 tmp = gfc_class_data_get (tmp);
1969 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (sym)->ts.u.derived,
1970 tmp, 0);
1971 }
a8399af8
PT
1972 else if (sym->attr.allocatable)
1973 {
1974 tmp = sym->backend_decl;
1975
1976 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
1977 tmp = gfc_conv_descriptor_data_get (tmp);
1978
1979 /* A simple call to free suffices here. */
1980 tmp = gfc_call_free (tmp);
1981
1982 /* Make sure that reallocation on assignment cannot occur. */
1983 sym->attr.allocatable = 0;
1984 }
1985 else
1986 tmp = NULL_TREE;
0b627b58 1987
a8399af8 1988 res = gfc_finish_block (&se.pre);
0b627b58 1989 gfc_add_init_cleanup (block, res, tmp);
a8399af8 1990 gfc_free_expr (lhs);
6312ef45 1991 }
8b704316 1992
5b384b3d
PT
1993 /* Set the stringlength, when needed. */
1994 if (need_len_assign)
8b704316 1995 {
8b704316
PT
1996 gfc_se se;
1997 gfc_init_se (&se, NULL);
5b384b3d
PT
1998 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1999 {
707905d0 2000 /* Deferred strings are dealt with in the preceeding. */
5b384b3d
PT
2001 gcc_assert (!e->symtree->n.sym->ts.deferred);
2002 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
2003 }
6017b8f0 2004 else if (e->symtree->n.sym->attr.function
a7d3cd40 2005 && e->symtree->n.sym == e->symtree->n.sym->result)
6017b8f0
PT
2006 {
2007 tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
2008 tmp = gfc_class_len_get (tmp);
2009 }
5b384b3d
PT
2010 else
2011 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
8b704316 2012 gfc_get_symbol_decl (sym);
5b384b3d
PT
2013 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
2014 : gfc_class_len_get (sym->backend_decl);
2015 /* Prevent adding a noop len= len. */
2016 if (tmp != charlen)
2017 {
2018 gfc_add_modify (&se.pre, charlen,
2019 fold_convert (TREE_TYPE (charlen), tmp));
2020 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
2021 gfc_finish_block (&se.post));
2022 }
8b704316 2023 }
6312ef45
JW
2024}
2025
2026
9abe5e56
DK
2027/* Translate a BLOCK construct. This is basically what we would do for a
2028 procedure body. */
2029
2030tree
2031gfc_trans_block_construct (gfc_code* code)
2032{
2033 gfc_namespace* ns;
2034 gfc_symbol* sym;
e5ca9693
DK
2035 gfc_wrapped_block block;
2036 tree exit_label;
2037 stmtblock_t body;
6312ef45 2038 gfc_association_list *ass;
9abe5e56 2039
03af1e4c 2040 ns = code->ext.block.ns;
9abe5e56
DK
2041 gcc_assert (ns);
2042 sym = ns->proc_name;
2043 gcc_assert (sym);
2044
e5ca9693 2045 /* Process local variables. */
9abe5e56
DK
2046 gcc_assert (!sym->tlink);
2047 sym->tlink = sym;
6312ef45 2048 gfc_process_block_locals (ns);
9abe5e56 2049
e5ca9693
DK
2050 /* Generate code including exit-label. */
2051 gfc_init_block (&body);
2052 exit_label = gfc_build_label_decl (NULL_TREE);
2053 code->exit_label = exit_label;
41dbbb37 2054
dc7a8b4b 2055 finish_oacc_declare (ns, sym, true);
41dbbb37 2056
e5ca9693
DK
2057 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
2058 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
2059
2060 /* Finish everything. */
2061 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
2062 gfc_trans_deferred_vars (sym, &block);
6312ef45
JW
2063 for (ass = code->ext.block.assoc; ass; ass = ass->next)
2064 trans_associate_var (ass->st->n.sym, &block);
8b704316 2065
e5ca9693 2066 return gfc_finish_wrapped_block (&block);
9abe5e56
DK
2067}
2068
1c122092
ML
2069/* Translate the simple DO construct in a C-style manner.
2070 This is where the loop variable has integer type and step +-1.
2071 Following code will generate infinite loop in case where TO is INT_MAX
2072 (for +1 step) or INT_MIN (for -1 step)
9abe5e56 2073
fbdad37d
PB
2074 We translate a do loop from:
2075
2076 DO dovar = from, to, step
2077 body
2078 END DO
2079
2080 to:
2081
2082 [Evaluate loop bounds and step]
1c122092
ML
2083 dovar = from;
2084 for (;;)
2085 {
2086 if (dovar > to)
2087 goto end_label;
2088 body;
2089 cycle_label:
2090 dovar += step;
fbdad37d 2091 }
1c122092 2092 end_label:
fbdad37d 2093
1c122092
ML
2094 This helps the optimizers by avoiding the extra pre-header condition and
2095 we save a register as we just compare the updated IV (not a value in
2096 previous step). */
fbdad37d
PB
2097
2098static tree
2099gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
bc51e726 2100 tree from, tree to, tree step, tree exit_cond)
fbdad37d
PB
2101{
2102 stmtblock_t body;
2103 tree type;
2104 tree cond;
2105 tree tmp;
33abc845 2106 tree saved_dovar = NULL;
fbdad37d
PB
2107 tree cycle_label;
2108 tree exit_label;
55bd9c35 2109 location_t loc;
fbdad37d 2110 type = TREE_TYPE (dovar);
1c122092 2111 bool is_step_positive = tree_int_cst_sgn (step) > 0;
fbdad37d 2112
55bd9c35
TB
2113 loc = code->ext.iterator->start->where.lb->location;
2114
fbdad37d 2115 /* Initialize the DO variable: dovar = from. */
8594f636 2116 gfc_add_modify_loc (loc, pblock, dovar,
1c122092 2117 fold_convert (TREE_TYPE (dovar), from));
8b704316 2118
1cc0e193 2119 /* Save value for do-tinkering checking. */
33abc845
TB
2120 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2121 {
2122 saved_dovar = gfc_create_var (type, ".saved_dovar");
55bd9c35 2123 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
33abc845 2124 }
fbdad37d
PB
2125
2126 /* Cycle and exit statements are implemented with gotos. */
2127 cycle_label = gfc_build_label_decl (NULL_TREE);
2128 exit_label = gfc_build_label_decl (NULL_TREE);
2129
1c122092 2130 /* Put the labels where they can be found later. See gfc_trans_do(). */
e5ca9693
DK
2131 code->cycle_label = cycle_label;
2132 code->exit_label = exit_label;
fbdad37d
PB
2133
2134 /* Loop body. */
2135 gfc_start_block (&body);
2136
1c122092
ML
2137 /* Exit the loop if there is an I/O result condition or error. */
2138 if (exit_cond)
2139 {
2140 tmp = build1_v (GOTO_EXPR, exit_label);
2141 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2142 exit_cond, tmp,
2143 build_empty_stmt (loc));
2144 gfc_add_expr_to_block (&body, tmp);
2145 }
2146
2147 /* Evaluate the loop condition. */
2148 if (is_step_positive)
63ee5404 2149 cond = fold_build2_loc (loc, GT_EXPR, logical_type_node, dovar,
1c122092
ML
2150 fold_convert (type, to));
2151 else
63ee5404 2152 cond = fold_build2_loc (loc, LT_EXPR, logical_type_node, dovar,
1c122092
ML
2153 fold_convert (type, to));
2154
2155 cond = gfc_evaluate_now_loc (loc, cond, &body);
170a8bd6
EB
2156 if (code->ext.iterator->unroll && cond != error_mark_node)
2157 cond
2158 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2159 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2160 build_int_cst (integer_type_node, code->ext.iterator->unroll));
1c122092
ML
2161
2162 /* The loop exit. */
2163 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2164 TREE_USED (exit_label) = 1;
2165 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2166 cond, tmp, build_empty_stmt (loc));
2167 gfc_add_expr_to_block (&body, tmp);
2168
2169 /* Check whether the induction variable is equal to INT_MAX
2170 (respectively to INT_MIN). */
2171 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2172 {
2173 tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
2174 : TYPE_MIN_VALUE (type);
2175
63ee5404 2176 tmp = fold_build2_loc (loc, EQ_EXPR, logical_type_node,
1c122092
ML
2177 dovar, boundary);
2178 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2179 "Loop iterates infinitely");
2180 }
2181
fbdad37d 2182 /* Main loop body. */
bc51e726 2183 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
fbdad37d
PB
2184 gfc_add_expr_to_block (&body, tmp);
2185
2186 /* Label for cycle statements (if needed). */
2187 if (TREE_USED (cycle_label))
2188 {
2189 tmp = build1_v (LABEL_EXPR, cycle_label);
2190 gfc_add_expr_to_block (&body, tmp);
2191 }
2192
1cc0e193 2193 /* Check whether someone has modified the loop variable. */
33abc845
TB
2194 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2195 {
63ee5404 2196 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node,
bc98ed60 2197 dovar, saved_dovar);
33abc845
TB
2198 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2199 "Loop variable has been modified");
2200 }
2201
fbdad37d 2202 /* Increment the loop variable. */
55bd9c35
TB
2203 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2204 gfc_add_modify_loc (loc, &body, dovar, tmp);
fbdad37d 2205
33abc845 2206 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
55bd9c35 2207 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
33abc845 2208
fbdad37d
PB
2209 /* Finish the loop body. */
2210 tmp = gfc_finish_block (&body);
55bd9c35 2211 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
fbdad37d 2212
fbdad37d
PB
2213 gfc_add_expr_to_block (pblock, tmp);
2214
2215 /* Add the exit label. */
2216 tmp = build1_v (LABEL_EXPR, exit_label);
2217 gfc_add_expr_to_block (pblock, tmp);
2218
2219 return gfc_finish_block (pblock);
2220}
2221
6de9cd9a
DN
2222/* Translate the DO construct. This obviously is one of the most
2223 important ones to get right with any compiler, but especially
2224 so for Fortran.
2225
fbdad37d
PB
2226 We special case some loop forms as described in gfc_trans_simple_do.
2227 For other cases we implement them with a separate loop count,
2228 as described in the standard.
6de9cd9a
DN
2229
2230 We translate a do loop from:
2231
2232 DO dovar = from, to, step
2233 body
2234 END DO
2235
2236 to:
2237
fbdad37d 2238 [evaluate loop bounds and step]
5d148c08
FXC
2239 empty = (step > 0 ? to < from : to > from);
2240 countm1 = (to - from) / step;
fbdad37d 2241 dovar = from;
5d148c08 2242 if (empty) goto exit_label;
fbdad37d 2243 for (;;)
6de9cd9a
DN
2244 {
2245 body;
2246cycle_label:
fbdad37d 2247 dovar += step
8c01de7f 2248 countm1t = countm1;
76dac339 2249 countm1--;
8c01de7f 2250 if (countm1t == 0) goto exit_label;
6de9cd9a
DN
2251 }
2252exit_label:
2253
5d148c08
FXC
2254 countm1 is an unsigned integer. It is equal to the loop count minus one,
2255 because the loop count itself can overflow. */
6de9cd9a
DN
2256
2257tree
bc51e726 2258gfc_trans_do (gfc_code * code, tree exit_cond)
6de9cd9a
DN
2259{
2260 gfc_se se;
2261 tree dovar;
33abc845 2262 tree saved_dovar = NULL;
6de9cd9a
DN
2263 tree from;
2264 tree to;
2265 tree step;
5d148c08 2266 tree countm1;
6de9cd9a 2267 tree type;
5d148c08 2268 tree utype;
6de9cd9a
DN
2269 tree cond;
2270 tree cycle_label;
2271 tree exit_label;
2272 tree tmp;
2273 stmtblock_t block;
2274 stmtblock_t body;
55bd9c35 2275 location_t loc;
6de9cd9a
DN
2276
2277 gfc_start_block (&block);
2278
55bd9c35
TB
2279 loc = code->ext.iterator->start->where.lb->location;
2280
fbdad37d 2281 /* Evaluate all the expressions in the iterator. */
6de9cd9a
DN
2282 gfc_init_se (&se, NULL);
2283 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
2284 gfc_add_block_to_block (&block, &se.pre);
2285 dovar = se.expr;
2286 type = TREE_TYPE (dovar);
2287
2288 gfc_init_se (&se, NULL);
8d5cfa27 2289 gfc_conv_expr_val (&se, code->ext.iterator->start);
6de9cd9a 2290 gfc_add_block_to_block (&block, &se.pre);
fbdad37d 2291 from = gfc_evaluate_now (se.expr, &block);
6de9cd9a
DN
2292
2293 gfc_init_se (&se, NULL);
8d5cfa27 2294 gfc_conv_expr_val (&se, code->ext.iterator->end);
6de9cd9a 2295 gfc_add_block_to_block (&block, &se.pre);
fbdad37d 2296 to = gfc_evaluate_now (se.expr, &block);
6de9cd9a
DN
2297
2298 gfc_init_se (&se, NULL);
8d5cfa27 2299 gfc_conv_expr_val (&se, code->ext.iterator->step);
6de9cd9a 2300 gfc_add_block_to_block (&block, &se.pre);
fbdad37d
PB
2301 step = gfc_evaluate_now (se.expr, &block);
2302
33abc845
TB
2303 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2304 {
63ee5404 2305 tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, step,
e8160c9a 2306 build_zero_cst (type));
33abc845
TB
2307 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
2308 "DO step value is zero");
2309 }
2310
fbdad37d
PB
2311 /* Special case simple loops. */
2312 if (TREE_CODE (type) == INTEGER_TYPE
2313 && (integer_onep (step)
2314 || tree_int_cst_equal (step, integer_minus_one_node)))
1c122092
ML
2315 return gfc_trans_simple_do (code, &block, dovar, from, to, step,
2316 exit_cond);
6de9cd9a 2317
8d5cfa27 2318 if (TREE_CODE (type) == INTEGER_TYPE)
c0b29099
JJ
2319 utype = unsigned_type_for (type);
2320 else
2321 utype = unsigned_type_for (gfc_array_index_type);
2322 countm1 = gfc_create_var (utype, "countm1");
5d148c08 2323
c0b29099
JJ
2324 /* Cycle and exit statements are implemented with gotos. */
2325 cycle_label = gfc_build_label_decl (NULL_TREE);
2326 exit_label = gfc_build_label_decl (NULL_TREE);
2327 TREE_USED (exit_label) = 1;
2328
e5ca9693
DK
2329 /* Put these labels where they can be found later. */
2330 code->cycle_label = cycle_label;
2331 code->exit_label = exit_label;
2332
c0b29099
JJ
2333 /* Initialize the DO variable: dovar = from. */
2334 gfc_add_modify (&block, dovar, from);
2335
1cc0e193 2336 /* Save value for do-tinkering checking. */
33abc845
TB
2337 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2338 {
2339 saved_dovar = gfc_create_var (type, ".saved_dovar");
55bd9c35 2340 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
33abc845
TB
2341 }
2342
c0b29099
JJ
2343 /* Initialize loop count and jump to exit label if the loop is empty.
2344 This code is executed before we enter the loop body. We generate:
2345 if (step > 0)
2346 {
d17271de 2347 countm1 = (to - from) / step;
8146bb58
TK
2348 if (to < from)
2349 goto exit_label;
c0b29099
JJ
2350 }
2351 else
2352 {
d17271de 2353 countm1 = (from - to) / -step;
8146bb58
TK
2354 if (to > from)
2355 goto exit_label;
2356 }
c5e7e996 2357 */
8146bb58 2358
c0b29099
JJ
2359 if (TREE_CODE (type) == INTEGER_TYPE)
2360 {
c5e7e996 2361 tree pos, neg, tou, fromu, stepu, tmp2;
8146bb58 2362
c5e7e996
RB
2363 /* The distance from FROM to TO cannot always be represented in a signed
2364 type, thus use unsigned arithmetic, also to avoid any undefined
2365 overflow issues. */
2366 tou = fold_convert (utype, to);
2367 fromu = fold_convert (utype, from);
2368 stepu = fold_convert (utype, step);
5d148c08 2369
c5e7e996
RB
2370 /* For a positive step, when to < from, exit, otherwise compute
2371 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
63ee5404 2372 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, to, from);
c5e7e996
RB
2373 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2374 fold_build2_loc (loc, MINUS_EXPR, utype,
2375 tou, fromu),
2376 stepu);
d17271de
RB
2377 pos = build2 (COMPOUND_EXPR, void_type_node,
2378 fold_build2 (MODIFY_EXPR, void_type_node,
2379 countm1, tmp2),
7119f1b1
ML
2380 build3_loc (loc, COND_EXPR, void_type_node,
2381 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
d17271de
RB
2382 build1_loc (loc, GOTO_EXPR, void_type_node,
2383 exit_label), NULL_TREE));
c5e7e996
RB
2384
2385 /* For a negative step, when to > from, exit, otherwise compute
2386 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
63ee5404 2387 tmp = fold_build2_loc (loc, GT_EXPR, logical_type_node, to, from);
c5e7e996
RB
2388 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2389 fold_build2_loc (loc, MINUS_EXPR, utype,
2390 fromu, tou),
2391 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
d17271de
RB
2392 neg = build2 (COMPOUND_EXPR, void_type_node,
2393 fold_build2 (MODIFY_EXPR, void_type_node,
2394 countm1, tmp2),
7119f1b1
ML
2395 build3_loc (loc, COND_EXPR, void_type_node,
2396 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
d17271de
RB
2397 build1_loc (loc, GOTO_EXPR, void_type_node,
2398 exit_label), NULL_TREE));
8146bb58 2399
63ee5404 2400 tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, step,
c5e7e996
RB
2401 build_int_cst (TREE_TYPE (step), 0));
2402 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
8146bb58 2403
c0b29099 2404 gfc_add_expr_to_block (&block, tmp);
8d5cfa27
SK
2405 }
2406 else
2407 {
c5e7e996
RB
2408 tree pos_step;
2409
8d5cfa27
SK
2410 /* TODO: We could use the same width as the real type.
2411 This would probably cause more problems that it solves
2412 when we implement "long double" types. */
c0b29099 2413
55bd9c35
TB
2414 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
2415 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
2416 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
c0b29099
JJ
2417 gfc_add_modify (&block, countm1, tmp);
2418
2419 /* We need a special check for empty loops:
2420 empty = (step > 0 ? to < from : to > from); */
63ee5404 2421 pos_step = fold_build2_loc (loc, GT_EXPR, logical_type_node, step,
c5e7e996 2422 build_zero_cst (type));
63ee5404 2423 tmp = fold_build3_loc (loc, COND_EXPR, logical_type_node, pos_step,
55bd9c35 2424 fold_build2_loc (loc, LT_EXPR,
63ee5404 2425 logical_type_node, to, from),
55bd9c35 2426 fold_build2_loc (loc, GT_EXPR,
63ee5404 2427 logical_type_node, to, from));
c0b29099 2428 /* If the loop is empty, go directly to the exit label. */
55bd9c35 2429 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
c0b29099 2430 build1_v (GOTO_EXPR, exit_label),
c2255bc4 2431 build_empty_stmt (input_location));
c0b29099 2432 gfc_add_expr_to_block (&block, tmp);
8d5cfa27 2433 }
5d148c08 2434
6de9cd9a
DN
2435 /* Loop body. */
2436 gfc_start_block (&body);
2437
6de9cd9a 2438 /* Main loop body. */
bc51e726 2439 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
6de9cd9a
DN
2440 gfc_add_expr_to_block (&body, tmp);
2441
2442 /* Label for cycle statements (if needed). */
2443 if (TREE_USED (cycle_label))
2444 {
2445 tmp = build1_v (LABEL_EXPR, cycle_label);
2446 gfc_add_expr_to_block (&body, tmp);
2447 }
2448
1cc0e193 2449 /* Check whether someone has modified the loop variable. */
33abc845
TB
2450 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2451 {
63ee5404 2452 tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node, dovar,
bc98ed60 2453 saved_dovar);
33abc845
TB
2454 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2455 "Loop variable has been modified");
2456 }
2457
bc51e726
JD
2458 /* Exit the loop if there is an I/O result condition or error. */
2459 if (exit_cond)
2460 {
2461 tmp = build1_v (GOTO_EXPR, exit_label);
55bd9c35 2462 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
bc98ed60
TB
2463 exit_cond, tmp,
2464 build_empty_stmt (input_location));
bc51e726
JD
2465 gfc_add_expr_to_block (&body, tmp);
2466 }
2467
244974bd 2468 /* Increment the loop variable. */
55bd9c35
TB
2469 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2470 gfc_add_modify_loc (loc, &body, dovar, tmp);
244974bd 2471
33abc845 2472 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
55bd9c35 2473 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
33abc845 2474
8c01de7f
JJ
2475 /* Initialize countm1t. */
2476 tree countm1t = gfc_create_var (utype, "countm1t");
2477 gfc_add_modify_loc (loc, &body, countm1t, countm1);
5d148c08 2478
6de9cd9a 2479 /* Decrement the loop count. */
55bd9c35 2480 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
bc98ed60 2481 build_int_cst (utype, 1));
55bd9c35 2482 gfc_add_modify_loc (loc, &body, countm1, tmp);
6de9cd9a 2483
8c01de7f 2484 /* End with the loop condition. Loop until countm1t == 0. */
63ee5404 2485 cond = fold_build2_loc (loc, EQ_EXPR, logical_type_node, countm1t,
8c01de7f 2486 build_int_cst (utype, 0));
170a8bd6
EB
2487 if (code->ext.iterator->unroll && cond != error_mark_node)
2488 cond
2489 = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2490 build_int_cst (integer_type_node, annot_expr_unroll_kind),
2491 build_int_cst (integer_type_node, code->ext.iterator->unroll));
8c01de7f
JJ
2492 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2493 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2494 cond, tmp, build_empty_stmt (loc));
2495 gfc_add_expr_to_block (&body, tmp);
2496
6de9cd9a
DN
2497 /* End of loop body. */
2498 tmp = gfc_finish_block (&body);
2499
2500 /* The for loop itself. */
55bd9c35 2501 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
6de9cd9a
DN
2502 gfc_add_expr_to_block (&block, tmp);
2503
2504 /* Add the exit label. */
2505 tmp = build1_v (LABEL_EXPR, exit_label);
2506 gfc_add_expr_to_block (&block, tmp);
2507
2508 return gfc_finish_block (&block);
2509}
2510
2511
2512/* Translate the DO WHILE construct.
2513
2514 We translate
2515
2516 DO WHILE (cond)
2517 body
2518 END DO
2519
2520 to:
2521
2522 for ( ; ; )
2523 {
2524 pre_cond;
2525 if (! cond) goto exit_label;
2526 body;
2527cycle_label:
2528 }
2529exit_label:
2530
2531 Because the evaluation of the exit condition `cond' may have side
2532 effects, we can't do much for empty loop bodies. The backend optimizers
2533 should be smart enough to eliminate any dead loops. */
2534
2535tree
2536gfc_trans_do_while (gfc_code * code)
2537{
2538 gfc_se cond;
2539 tree tmp;
2540 tree cycle_label;
2541 tree exit_label;
2542 stmtblock_t block;
2543
2544 /* Everything we build here is part of the loop body. */
2545 gfc_start_block (&block);
2546
2547 /* Cycle and exit statements are implemented with gotos. */
2548 cycle_label = gfc_build_label_decl (NULL_TREE);
2549 exit_label = gfc_build_label_decl (NULL_TREE);
2550
2551 /* Put the labels where they can be found later. See gfc_trans_do(). */
e5ca9693
DK
2552 code->cycle_label = cycle_label;
2553 code->exit_label = exit_label;
6de9cd9a
DN
2554
2555 /* Create a GIMPLE version of the exit condition. */
2556 gfc_init_se (&cond, NULL);
a513927a 2557 gfc_conv_expr_val (&cond, code->expr1);
6de9cd9a 2558 gfc_add_block_to_block (&block, &cond.pre);
55bd9c35 2559 cond.expr = fold_build1_loc (code->expr1->where.lb->location,
1d636855 2560 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
6de9cd9a
DN
2561
2562 /* Build "IF (! cond) GOTO exit_label". */
2563 tmp = build1_v (GOTO_EXPR, exit_label);
2564 TREE_USED (exit_label) = 1;
55bd9c35
TB
2565 tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
2566 void_type_node, cond.expr, tmp,
2567 build_empty_stmt (code->expr1->where.lb->location));
6de9cd9a
DN
2568 gfc_add_expr_to_block (&block, tmp);
2569
2570 /* The main body of the loop. */
2571 tmp = gfc_trans_code (code->block->next);
2572 gfc_add_expr_to_block (&block, tmp);
2573
2574 /* Label for cycle statements (if needed). */
2575 if (TREE_USED (cycle_label))
2576 {
2577 tmp = build1_v (LABEL_EXPR, cycle_label);
2578 gfc_add_expr_to_block (&block, tmp);
2579 }
2580
2581 /* End of loop body. */
2582 tmp = gfc_finish_block (&block);
2583
2584 gfc_init_block (&block);
2585 /* Build the loop. */
55bd9c35
TB
2586 tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2587 void_type_node, tmp);
6de9cd9a
DN
2588 gfc_add_expr_to_block (&block, tmp);
2589
2590 /* Add the exit label. */
2591 tmp = build1_v (LABEL_EXPR, exit_label);
2592 gfc_add_expr_to_block (&block, tmp);
2593
2594 return gfc_finish_block (&block);
2595}
2596
2597
dfd6231e
PT
2598/* Deal with the particular case of SELECT_TYPE, where the vtable
2599 addresses are used for the selection. Since these are not sorted,
2600 the selection has to be made by a series of if statements. */
2601
2602static tree
2603gfc_trans_select_type_cases (gfc_code * code)
2604{
2605 gfc_code *c;
2606 gfc_case *cp;
2607 tree tmp;
2608 tree cond;
2609 tree low;
2610 tree high;
2611 gfc_se se;
2612 gfc_se cse;
2613 stmtblock_t block;
2614 stmtblock_t body;
2615 bool def = false;
2616 gfc_expr *e;
2617 gfc_start_block (&block);
2618
2619 /* Calculate the switch expression. */
2620 gfc_init_se (&se, NULL);
2621 gfc_conv_expr_val (&se, code->expr1);
2622 gfc_add_block_to_block (&block, &se.pre);
2623
2624 /* Generate an expression for the selector hash value, for
2625 use to resolve character cases. */
2626 e = gfc_copy_expr (code->expr1->value.function.actual->expr);
2627 gfc_add_hash_component (e);
2628
2629 TREE_USED (code->exit_label) = 0;
2630
2631repeat:
2632 for (c = code->block; c; c = c->block)
2633 {
2634 cp = c->ext.block.case_list;
2635
2636 /* Assume it's the default case. */
2637 low = NULL_TREE;
2638 high = NULL_TREE;
2639 tmp = NULL_TREE;
2640
2641 /* Put the default case at the end. */
2642 if ((!def && !cp->low) || (def && cp->low))
2643 continue;
2644
2645 if (cp->low && (cp->ts.type == BT_CLASS
2646 || cp->ts.type == BT_DERIVED))
2647 {
2648 gfc_init_se (&cse, NULL);
2649 gfc_conv_expr_val (&cse, cp->low);
2650 gfc_add_block_to_block (&block, &cse.pre);
2651 low = cse.expr;
2652 }
2653 else if (cp->ts.type != BT_UNKNOWN)
2654 {
2655 gcc_assert (cp->high);
2656 gfc_init_se (&cse, NULL);
2657 gfc_conv_expr_val (&cse, cp->high);
2658 gfc_add_block_to_block (&block, &cse.pre);
2659 high = cse.expr;
2660 }
2661
2662 gfc_init_block (&body);
2663
2664 /* Add the statements for this case. */
2665 tmp = gfc_trans_code (c->next);
2666 gfc_add_expr_to_block (&body, tmp);
2667
2668 /* Break to the end of the SELECT TYPE construct. The default
2669 case just falls through. */
2670 if (!def)
2671 {
2672 TREE_USED (code->exit_label) = 1;
2673 tmp = build1_v (GOTO_EXPR, code->exit_label);
2674 gfc_add_expr_to_block (&body, tmp);
2675 }
2676
2677 tmp = gfc_finish_block (&body);
2678
2679 if (low != NULL_TREE)
2680 {
2681 /* Compare vtable pointers. */
2682 cond = fold_build2_loc (input_location, EQ_EXPR,
2683 TREE_TYPE (se.expr), se.expr, low);
2684 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2685 cond, tmp,
2686 build_empty_stmt (input_location));
2687 }
2688 else if (high != NULL_TREE)
2689 {
2690 /* Compare hash values for character cases. */
2691 gfc_init_se (&cse, NULL);
2692 gfc_conv_expr_val (&cse, e);
2693 gfc_add_block_to_block (&block, &cse.pre);
2694
2695 cond = fold_build2_loc (input_location, EQ_EXPR,
2696 TREE_TYPE (se.expr), high, cse.expr);
2697 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2698 cond, tmp,
2699 build_empty_stmt (input_location));
2700 }
2701
2702 gfc_add_expr_to_block (&block, tmp);
2703 }
2704
2705 if (!def)
2706 {
2707 def = true;
2708 goto repeat;
2709 }
2710
2711 gfc_free_expr (e);
2712
2713 return gfc_finish_block (&block);
2714}
2715
2716
6de9cd9a
DN
2717/* Translate the SELECT CASE construct for INTEGER case expressions,
2718 without killing all potential optimizations. The problem is that
2719 Fortran allows unbounded cases, but the back-end does not, so we
2720 need to intercept those before we enter the equivalent SWITCH_EXPR
2721 we can build.
2722
2723 For example, we translate this,
2724
2725 SELECT CASE (expr)
2726 CASE (:100,101,105:115)
2727 block_1
2728 CASE (190:199,200:)
2729 block_2
2730 CASE (300)
2731 block_3
2732 CASE DEFAULT
2733 block_4
2734 END SELECT
2735
2736 to the GENERIC equivalent,
2737
2738 switch (expr)
2739 {
2740 case (minimum value for typeof(expr) ... 100:
2741 case 101:
2742 case 105 ... 114:
2743 block1:
2744 goto end_label;
2745
2746 case 200 ... (maximum value for typeof(expr):
2747 case 190 ... 199:
2748 block2;
2749 goto end_label;
2750
2751 case 300:
2752 block_3;
2753 goto end_label;
2754
2755 default:
2756 block_4;
2757 goto end_label;
2758 }
2759
2760 end_label: */
2761
2762static tree
2763gfc_trans_integer_select (gfc_code * code)
2764{
2765 gfc_code *c;
2766 gfc_case *cp;
2767 tree end_label;
2768 tree tmp;
2769 gfc_se se;
2770 stmtblock_t block;
2771 stmtblock_t body;
2772
2773 gfc_start_block (&block);
2774
2775 /* Calculate the switch expression. */
2776 gfc_init_se (&se, NULL);
a513927a 2777 gfc_conv_expr_val (&se, code->expr1);
6de9cd9a
DN
2778 gfc_add_block_to_block (&block, &se.pre);
2779
2780 end_label = gfc_build_label_decl (NULL_TREE);
2781
2782 gfc_init_block (&body);
2783
2784 for (c = code->block; c; c = c->block)
2785 {
29a63d67 2786 for (cp = c->ext.block.case_list; cp; cp = cp->next)
6de9cd9a
DN
2787 {
2788 tree low, high;
2789 tree label;
2790
2791 /* Assume it's the default case. */
2792 low = high = NULL_TREE;
2793
2794 if (cp->low)
2795 {
20585ad6
BM
2796 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2797 cp->low->ts.kind);
6de9cd9a
DN
2798
2799 /* If there's only a lower bound, set the high bound to the
2800 maximum value of the case expression. */
2801 if (!cp->high)
2802 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
2803 }
2804
2805 if (cp->high)
2806 {
2807 /* Three cases are possible here:
2808
2809 1) There is no lower bound, e.g. CASE (:N).
2810 2) There is a lower bound .NE. high bound, that is
2811 a case range, e.g. CASE (N:M) where M>N (we make
2812 sure that M>N during type resolution).
2813 3) There is a lower bound, and it has the same value
2814 as the high bound, e.g. CASE (N:N). This is our
2815 internal representation of CASE(N).
2816
2817 In the first and second case, we need to set a value for
e2ae1407 2818 high. In the third case, we don't because the GCC middle
6de9cd9a
DN
2819 end represents a single case value by just letting high be
2820 a NULL_TREE. We can't do that because we need to be able
2821 to represent unbounded cases. */
2822
2823 if (!cp->low
b2954e12
SK
2824 || (mpz_cmp (cp->low->value.integer,
2825 cp->high->value.integer) != 0))
20585ad6
BM
2826 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2827 cp->high->ts.kind);
6de9cd9a
DN
2828
2829 /* Unbounded case. */
2830 if (!cp->low)
2831 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2832 }
2833
2834 /* Build a label. */
c006df4e 2835 label = gfc_build_label_decl (NULL_TREE);
6de9cd9a
DN
2836
2837 /* Add this case label.
2838 Add parameter 'label', make it match GCC backend. */
3d528853 2839 tmp = build_case_label (low, high, label);
6de9cd9a
DN
2840 gfc_add_expr_to_block (&body, tmp);
2841 }
2842
2843 /* Add the statements for this case. */
2844 tmp = gfc_trans_code (c->next);
2845 gfc_add_expr_to_block (&body, tmp);
2846
2847 /* Break to the end of the construct. */
2848 tmp = build1_v (GOTO_EXPR, end_label);
2849 gfc_add_expr_to_block (&body, tmp);
2850 }
2851
2852 tmp = gfc_finish_block (&body);
9e851845 2853 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, se.expr, tmp);
6de9cd9a
DN
2854 gfc_add_expr_to_block (&block, tmp);
2855
2856 tmp = build1_v (LABEL_EXPR, end_label);
2857 gfc_add_expr_to_block (&block, tmp);
2858
2859 return gfc_finish_block (&block);
2860}
2861
2862
2863/* Translate the SELECT CASE construct for LOGICAL case expressions.
2864
2865 There are only two cases possible here, even though the standard
2866 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2867 .FALSE., and DEFAULT.
2868
2869 We never generate more than two blocks here. Instead, we always
2870 try to eliminate the DEFAULT case. This way, we can translate this
2871 kind of SELECT construct to a simple
2872
2873 if {} else {};
2874
2875 expression in GENERIC. */
2876
2877static tree
2878gfc_trans_logical_select (gfc_code * code)
2879{
2880 gfc_code *c;
2881 gfc_code *t, *f, *d;
2882 gfc_case *cp;
2883 gfc_se se;
2884 stmtblock_t block;
2885
2886 /* Assume we don't have any cases at all. */
2887 t = f = d = NULL;
2888
2889 /* Now see which ones we actually do have. We can have at most two
2890 cases in a single case list: one for .TRUE. and one for .FALSE.
2891 The default case is always separate. If the cases for .TRUE. and
2892 .FALSE. are in the same case list, the block for that case list
2893 always executed, and we don't generate code a COND_EXPR. */
2894 for (c = code->block; c; c = c->block)
2895 {
29a63d67 2896 for (cp = c->ext.block.case_list; cp; cp = cp->next)
6de9cd9a
DN
2897 {
2898 if (cp->low)
2899 {
2900 if (cp->low->value.logical == 0) /* .FALSE. */
2901 f = c;
2902 else /* if (cp->value.logical != 0), thus .TRUE. */
2903 t = c;
2904 }
2905 else
2906 d = c;
2907 }
2908 }
2909
2910 /* Start a new block. */
2911 gfc_start_block (&block);
2912
2913 /* Calculate the switch expression. We always need to do this
2914 because it may have side effects. */
2915 gfc_init_se (&se, NULL);
a513927a 2916 gfc_conv_expr_val (&se, code->expr1);
6de9cd9a
DN
2917 gfc_add_block_to_block (&block, &se.pre);
2918
2919 if (t == f && t != NULL)
2920 {
2921 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2922 translate the code for these cases, append it to the current
2923 block. */
2924 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
2925 }
2926 else
2927 {
61ead135 2928 tree true_tree, false_tree, stmt;
6de9cd9a 2929
c2255bc4
AH
2930 true_tree = build_empty_stmt (input_location);
2931 false_tree = build_empty_stmt (input_location);
6de9cd9a
DN
2932
2933 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2934 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2935 make the missing case the default case. */
2936 if (t != NULL && f != NULL)
2937 d = NULL;
2938 else if (d != NULL)
2939 {
2940 if (t == NULL)
2941 t = d;
2942 else
2943 f = d;
2944 }
2945
2946 /* Translate the code for each of these blocks, and append it to
2947 the current block. */
2948 if (t != NULL)
2949 true_tree = gfc_trans_code (t->next);
2950
2951 if (f != NULL)
2952 false_tree = gfc_trans_code (f->next);
2953
bc98ed60
TB
2954 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2955 se.expr, true_tree, false_tree);
61ead135 2956 gfc_add_expr_to_block (&block, stmt);
6de9cd9a
DN
2957 }
2958
2959 return gfc_finish_block (&block);
2960}
2961
2962
d2886bc7
JJ
2963/* The jump table types are stored in static variables to avoid
2964 constructing them from scratch every single time. */
2965static GTY(()) tree select_struct[2];
2966
6de9cd9a
DN
2967/* Translate the SELECT CASE construct for CHARACTER case expressions.
2968 Instead of generating compares and jumps, it is far simpler to
2969 generate a data structure describing the cases in order and call a
2970 library subroutine that locates the right case.
2971 This is particularly true because this is the only case where we
2972 might have to dispose of a temporary.
2973 The library subroutine returns a pointer to jump to or NULL if no
2974 branches are to be taken. */
2975
2976static tree
2977gfc_trans_character_select (gfc_code *code)
2978{
8748ad99 2979 tree init, end_label, tmp, type, case_num, label, fndecl;
6de9cd9a
DN
2980 stmtblock_t block, body;
2981 gfc_case *cp, *d;
2982 gfc_code *c;
d2886bc7 2983 gfc_se se, expr1se;
d393bbd7 2984 int n, k;
9771b263 2985 vec<constructor_elt, va_gc> *inits = NULL;
d393bbd7 2986
d2886bc7
JJ
2987 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2988
d393bbd7
FXC
2989 /* The jump table types are stored in static variables to avoid
2990 constructing them from scratch every single time. */
d393bbd7
FXC
2991 static tree ss_string1[2], ss_string1_len[2];
2992 static tree ss_string2[2], ss_string2_len[2];
2993 static tree ss_target[2];
2994
29a63d67 2995 cp = code->block->ext.block.case_list;
d2886bc7
JJ
2996 while (cp->left != NULL)
2997 cp = cp->left;
2998
2999 /* Generate the body */
3000 gfc_start_block (&block);
3001 gfc_init_se (&expr1se, NULL);
3002 gfc_conv_expr_reference (&expr1se, code->expr1);
3003
3004 gfc_add_block_to_block (&block, &expr1se.pre);
3005
3006 end_label = gfc_build_label_decl (NULL_TREE);
3007
3008 gfc_init_block (&body);
3009
3010 /* Attempt to optimize length 1 selects. */
86e033e2 3011 if (integer_onep (expr1se.string_length))
d2886bc7
JJ
3012 {
3013 for (d = cp; d; d = d->right)
3014 {
f622221a 3015 gfc_charlen_t i;
d2886bc7
JJ
3016 if (d->low)
3017 {
3018 gcc_assert (d->low->expr_type == EXPR_CONSTANT
3019 && d->low->ts.type == BT_CHARACTER);
3020 if (d->low->value.character.length > 1)
3021 {
3022 for (i = 1; i < d->low->value.character.length; i++)
3023 if (d->low->value.character.string[i] != ' ')
3024 break;
3025 if (i != d->low->value.character.length)
3026 {
3027 if (optimize && d->high && i == 1)
3028 {
3029 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3030 && d->high->ts.type == BT_CHARACTER);
3031 if (d->high->value.character.length > 1
3032 && (d->low->value.character.string[0]
3033 == d->high->value.character.string[0])
3034 && d->high->value.character.string[1] != ' '
3035 && ((d->low->value.character.string[1] < ' ')
3036 == (d->high->value.character.string[1]
3037 < ' ')))
3038 continue;
3039 }
3040 break;
3041 }
3042 }
3043 }
3044 if (d->high)
3045 {
3046 gcc_assert (d->high->expr_type == EXPR_CONSTANT
3047 && d->high->ts.type == BT_CHARACTER);
3048 if (d->high->value.character.length > 1)
3049 {
3050 for (i = 1; i < d->high->value.character.length; i++)
3051 if (d->high->value.character.string[i] != ' ')
3052 break;
3053 if (i != d->high->value.character.length)
3054 break;
3055 }
3056 }
3057 }
3058 if (d == NULL)
3059 {
3060 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
3061
3062 for (c = code->block; c; c = c->block)
3063 {
29a63d67 3064 for (cp = c->ext.block.case_list; cp; cp = cp->next)
d2886bc7
JJ
3065 {
3066 tree low, high;
3067 tree label;
3068 gfc_char_t r;
3069
3070 /* Assume it's the default case. */
3071 low = high = NULL_TREE;
3072
3073 if (cp->low)
3074 {
3075 /* CASE ('ab') or CASE ('ab':'az') will never match
3076 any length 1 character. */
3077 if (cp->low->value.character.length > 1
3078 && cp->low->value.character.string[1] != ' ')
3079 continue;
3080
3081 if (cp->low->value.character.length > 0)
3082 r = cp->low->value.character.string[0];
3083 else
3084 r = ' ';
3085 low = build_int_cst (ctype, r);
3086
3087 /* If there's only a lower bound, set the high bound
3088 to the maximum value of the case expression. */
3089 if (!cp->high)
3090 high = TYPE_MAX_VALUE (ctype);
3091 }
3092
3093 if (cp->high)
3094 {
3095 if (!cp->low
3096 || (cp->low->value.character.string[0]
3097 != cp->high->value.character.string[0]))
3098 {
3099 if (cp->high->value.character.length > 0)
3100 r = cp->high->value.character.string[0];
3101 else
3102 r = ' ';
3103 high = build_int_cst (ctype, r);
3104 }
3105
3106 /* Unbounded case. */
3107 if (!cp->low)
3108 low = TYPE_MIN_VALUE (ctype);
3109 }
3110
3111 /* Build a label. */
3112 label = gfc_build_label_decl (NULL_TREE);
3113
3114 /* Add this case label.
3115 Add parameter 'label', make it match GCC backend. */
3d528853 3116 tmp = build_case_label (low, high, label);
d2886bc7
JJ
3117 gfc_add_expr_to_block (&body, tmp);
3118 }
3119
3120 /* Add the statements for this case. */
3121 tmp = gfc_trans_code (c->next);
3122 gfc_add_expr_to_block (&body, tmp);
3123
3124 /* Break to the end of the construct. */
3125 tmp = build1_v (GOTO_EXPR, end_label);
3126 gfc_add_expr_to_block (&body, tmp);
3127 }
3128
3129 tmp = gfc_string_to_single_character (expr1se.string_length,
3130 expr1se.expr,
3131 code->expr1->ts.kind);
3132 case_num = gfc_create_var (ctype, "case_num");
3133 gfc_add_modify (&block, case_num, tmp);
3134
3135 gfc_add_block_to_block (&block, &expr1se.post);
3136
3137 tmp = gfc_finish_block (&body);
9e851845
JJ
3138 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3139 case_num, tmp);
d2886bc7
JJ
3140 gfc_add_expr_to_block (&block, tmp);
3141
3142 tmp = build1_v (LABEL_EXPR, end_label);
3143 gfc_add_expr_to_block (&block, tmp);
3144
3145 return gfc_finish_block (&block);
3146 }
3147 }
6de9cd9a 3148
a513927a 3149 if (code->expr1->ts.kind == 1)
d393bbd7 3150 k = 0;
a513927a 3151 else if (code->expr1->ts.kind == 4)
d393bbd7
FXC
3152 k = 1;
3153 else
3154 gcc_unreachable ();
6de9cd9a 3155
d393bbd7 3156 if (select_struct[k] == NULL)
6de9cd9a 3157 {
dfd6ece2 3158 tree *chain = NULL;
d393bbd7 3159 select_struct[k] = make_node (RECORD_TYPE);
e2cad04b 3160
a513927a 3161 if (code->expr1->ts.kind == 1)
d393bbd7 3162 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
a513927a 3163 else if (code->expr1->ts.kind == 4)
d393bbd7
FXC
3164 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
3165 else
3166 gcc_unreachable ();
6de9cd9a
DN
3167
3168#undef ADD_FIELD
35151cd5
MM
3169#define ADD_FIELD(NAME, TYPE) \
3170 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
3171 get_identifier (stringize(NAME)), \
3172 TYPE, \
3173 &chain)
6de9cd9a 3174
d393bbd7
FXC
3175 ADD_FIELD (string1, pchartype);
3176 ADD_FIELD (string1_len, gfc_charlen_type_node);
6de9cd9a 3177
d393bbd7
FXC
3178 ADD_FIELD (string2, pchartype);
3179 ADD_FIELD (string2_len, gfc_charlen_type_node);
6de9cd9a 3180
dd52ecb0 3181 ADD_FIELD (target, integer_type_node);
6de9cd9a
DN
3182#undef ADD_FIELD
3183
d393bbd7 3184 gfc_finish_type (select_struct[k]);
6de9cd9a
DN
3185 }
3186
6de9cd9a
DN
3187 n = 0;
3188 for (d = cp; d; d = d->right)
3189 d->n = n++;
3190
6de9cd9a
DN
3191 for (c = code->block; c; c = c->block)
3192 {
29a63d67 3193 for (d = c->ext.block.case_list; d; d = d->next)
6de9cd9a 3194 {
2b8327ce 3195 label = gfc_build_label_decl (NULL_TREE);
3d528853
NF
3196 tmp = build_case_label ((d->low == NULL && d->high == NULL)
3197 ? NULL
3198 : build_int_cst (integer_type_node, d->n),
3199 NULL, label);
6de9cd9a
DN
3200 gfc_add_expr_to_block (&body, tmp);
3201 }
3202
3203 tmp = gfc_trans_code (c->next);
3204 gfc_add_expr_to_block (&body, tmp);
3205
923ab88c 3206 tmp = build1_v (GOTO_EXPR, end_label);
6de9cd9a
DN
3207 gfc_add_expr_to_block (&body, tmp);
3208 }
3209
3210 /* Generate the structure describing the branches */
d2886bc7 3211 for (d = cp; d; d = d->right)
6de9cd9a 3212 {
9771b263 3213 vec<constructor_elt, va_gc> *node = NULL;
6de9cd9a
DN
3214
3215 gfc_init_se (&se, NULL);
3216
3217 if (d->low == NULL)
3218 {
8748ad99 3219 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
f622221a 3220 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], build_zero_cst (gfc_charlen_type_node));
6de9cd9a
DN
3221 }
3222 else
3223 {
3224 gfc_conv_expr_reference (&se, d->low);
3225
8748ad99
NF
3226 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
3227 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
6de9cd9a
DN
3228 }
3229
3230 if (d->high == NULL)
3231 {
8748ad99 3232 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
f622221a 3233 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], build_zero_cst (gfc_charlen_type_node));
6de9cd9a
DN
3234 }
3235 else
3236 {
3237 gfc_init_se (&se, NULL);
3238 gfc_conv_expr_reference (&se, d->high);
3239
8748ad99
NF
3240 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
3241 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
6de9cd9a
DN
3242 }
3243
8748ad99
NF
3244 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
3245 build_int_cst (integer_type_node, d->n));
6de9cd9a 3246
8748ad99
NF
3247 tmp = build_constructor (select_struct[k], node);
3248 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
6de9cd9a
DN
3249 }
3250
d393bbd7 3251 type = build_array_type (select_struct[k],
df09d1d5 3252 build_index_type (size_int (n-1)));
6de9cd9a 3253
8748ad99 3254 init = build_constructor (type, inits);
6de9cd9a 3255 TREE_CONSTANT (init) = 1;
6de9cd9a
DN
3256 TREE_STATIC (init) = 1;
3257 /* Create a static variable to hold the jump table. */
3258 tmp = gfc_create_var (type, "jumptable");
3259 TREE_CONSTANT (tmp) = 1;
6de9cd9a 3260 TREE_STATIC (tmp) = 1;
0f0707d1 3261 TREE_READONLY (tmp) = 1;
6de9cd9a
DN
3262 DECL_INITIAL (tmp) = init;
3263 init = tmp;
3264
5039610b 3265 /* Build the library call */
6de9cd9a 3266 init = gfc_build_addr_expr (pvoid_type_node, init);
6de9cd9a 3267
a513927a 3268 if (code->expr1->ts.kind == 1)
d393bbd7 3269 fndecl = gfor_fndecl_select_string;
a513927a 3270 else if (code->expr1->ts.kind == 4)
d393bbd7
FXC
3271 fndecl = gfor_fndecl_select_string_char4;
3272 else
3273 gcc_unreachable ();
3274
db3927fb 3275 tmp = build_call_expr_loc (input_location,
df09d1d5
RG
3276 fndecl, 4, init,
3277 build_int_cst (gfc_charlen_type_node, n),
d2886bc7 3278 expr1se.expr, expr1se.string_length);
dd52ecb0 3279 case_num = gfc_create_var (integer_type_node, "case_num");
726a989a 3280 gfc_add_modify (&block, case_num, tmp);
dc6c7714 3281
d2886bc7 3282 gfc_add_block_to_block (&block, &expr1se.post);
dc6c7714 3283
6de9cd9a 3284 tmp = gfc_finish_block (&body);
9e851845
JJ
3285 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
3286 case_num, tmp);
6de9cd9a 3287 gfc_add_expr_to_block (&block, tmp);
2b8327ce 3288
923ab88c 3289 tmp = build1_v (LABEL_EXPR, end_label);
6de9cd9a
DN
3290 gfc_add_expr_to_block (&block, tmp);
3291
6de9cd9a
DN
3292 return gfc_finish_block (&block);
3293}
3294
3295
3296/* Translate the three variants of the SELECT CASE construct.
3297
3298 SELECT CASEs with INTEGER case expressions can be translated to an
3299 equivalent GENERIC switch statement, and for LOGICAL case
3300 expressions we build one or two if-else compares.
3301
3302 SELECT CASEs with CHARACTER case expressions are a whole different
3303 story, because they don't exist in GENERIC. So we sort them and
3304 do a binary search at runtime.
3305
3306 Fortran has no BREAK statement, and it does not allow jumps from
3307 one case block to another. That makes things a lot easier for
3308 the optimizers. */
3309
3310tree
3311gfc_trans_select (gfc_code * code)
3312{
e5ca9693
DK
3313 stmtblock_t block;
3314 tree body;
3315 tree exit_label;
3316
a513927a 3317 gcc_assert (code && code->expr1);
e5ca9693
DK
3318 gfc_init_block (&block);
3319
3320 /* Build the exit label and hang it in. */
3321 exit_label = gfc_build_label_decl (NULL_TREE);
3322 code->exit_label = exit_label;
6de9cd9a
DN
3323
3324 /* Empty SELECT constructs are legal. */
3325 if (code->block == NULL)
e5ca9693 3326 body = build_empty_stmt (input_location);
6de9cd9a
DN
3327
3328 /* Select the correct translation function. */
e5ca9693
DK
3329 else
3330 switch (code->expr1->ts.type)
3331 {
3332 case BT_LOGICAL:
3333 body = gfc_trans_logical_select (code);
3334 break;
3335
3336 case BT_INTEGER:
3337 body = gfc_trans_integer_select (code);
3338 break;
3339
3340 case BT_CHARACTER:
3341 body = gfc_trans_character_select (code);
3342 break;
3343
3344 default:
3345 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
3346 /* Not reached */
3347 }
3348
3349 /* Build everything together. */
3350 gfc_add_expr_to_block (&block, body);
3351 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3352
dfd6231e
PT
3353 return gfc_finish_block (&block);
3354}
3355
3356tree
3357gfc_trans_select_type (gfc_code * code)
3358{
3359 stmtblock_t block;
3360 tree body;
3361 tree exit_label;
3362
3363 gcc_assert (code && code->expr1);
3364 gfc_init_block (&block);
3365
3366 /* Build the exit label and hang it in. */
3367 exit_label = gfc_build_label_decl (NULL_TREE);
3368 code->exit_label = exit_label;
3369
3370 /* Empty SELECT constructs are legal. */
3371 if (code->block == NULL)
3372 body = build_empty_stmt (input_location);
3373 else
3374 body = gfc_trans_select_type_cases (code);
3375
3376 /* Build everything together. */
3377 gfc_add_expr_to_block (&block, body);
3378
3379 if (TREE_USED (exit_label))
3380 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3381
e5ca9693 3382 return gfc_finish_block (&block);
6de9cd9a
DN
3383}
3384
3385
640670c7
PT
3386/* Traversal function to substitute a replacement symtree if the symbol
3387 in the expression is the same as that passed. f == 2 signals that
3388 that variable itself is not to be checked - only the references.
3389 This group of functions is used when the variable expression in a
3390 FORALL assignment has internal references. For example:
3391 FORALL (i = 1:4) p(p(i)) = i
3392 The only recourse here is to store a copy of 'p' for the index
3393 expression. */
3394
3395static gfc_symtree *new_symtree;
3396static gfc_symtree *old_symtree;
3397
3398static bool
3399forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
3400{
908a2235
PT
3401 if (expr->expr_type != EXPR_VARIABLE)
3402 return false;
640670c7
PT
3403
3404 if (*f == 2)
3405 *f = 1;
3406 else if (expr->symtree->n.sym == sym)
3407 expr->symtree = new_symtree;
3408
3409 return false;
3410}
3411
3412static void
3413forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
3414{
3415 gfc_traverse_expr (e, sym, forall_replace, f);
3416}
3417
3418static bool
3419forall_restore (gfc_expr *expr,
3420 gfc_symbol *sym ATTRIBUTE_UNUSED,
3421 int *f ATTRIBUTE_UNUSED)
3422{
908a2235
PT
3423 if (expr->expr_type != EXPR_VARIABLE)
3424 return false;
640670c7
PT
3425
3426 if (expr->symtree == new_symtree)
3427 expr->symtree = old_symtree;
3428
3429 return false;
3430}
3431
3432static void
3433forall_restore_symtree (gfc_expr *e)
3434{
3435 gfc_traverse_expr (e, NULL, forall_restore, 0);
3436}
3437
3438static void
3439forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3440{
3441 gfc_se tse;
3442 gfc_se rse;
3443 gfc_expr *e;
3444 gfc_symbol *new_sym;
3445 gfc_symbol *old_sym;
3446 gfc_symtree *root;
3447 tree tmp;
3448
3449 /* Build a copy of the lvalue. */
a513927a 3450 old_symtree = c->expr1->symtree;
640670c7
PT
3451 old_sym = old_symtree->n.sym;
3452 e = gfc_lval_expr_from_sym (old_sym);
3453 if (old_sym->attr.dimension)
3454 {
3455 gfc_init_se (&tse, NULL);
430f2d1f 3456 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
640670c7
PT
3457 gfc_add_block_to_block (pre, &tse.pre);
3458 gfc_add_block_to_block (post, &tse.post);
db3927fb 3459 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
640670c7 3460
7bd5dad2 3461 if (c->expr1->ref->u.ar.type != AR_SECTION)
640670c7
PT
3462 {
3463 /* Use the variable offset for the temporary. */
568e8e1e
PT
3464 tmp = gfc_conv_array_offset (old_sym->backend_decl);
3465 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
640670c7
PT
3466 }
3467 }
3468 else
3469 {
3470 gfc_init_se (&tse, NULL);
3471 gfc_init_se (&rse, NULL);
3472 gfc_conv_expr (&rse, e);
3473 if (e->ts.type == BT_CHARACTER)
3474 {
3475 tse.string_length = rse.string_length;
3476 tmp = gfc_get_character_type_len (gfc_default_character_kind,
3477 tse.string_length);
3478 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
3479 rse.string_length);
3480 gfc_add_block_to_block (pre, &tse.pre);
3481 gfc_add_block_to_block (post, &tse.post);
3482 }
3483 else
3484 {
3485 tmp = gfc_typenode_for_spec (&e->ts);
3486 tse.expr = gfc_create_var (tmp, "temp");
3487 }
3488
ed673c00
MM
3489 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
3490 e->expr_type == EXPR_VARIABLE, false);
640670c7
PT
3491 gfc_add_expr_to_block (pre, tmp);
3492 }
3493 gfc_free_expr (e);
3494
3495 /* Create a new symbol to represent the lvalue. */
3496 new_sym = gfc_new_symbol (old_sym->name, NULL);
3497 new_sym->ts = old_sym->ts;
3498 new_sym->attr.referenced = 1;
59e36b72 3499 new_sym->attr.temporary = 1;
640670c7
PT
3500 new_sym->attr.dimension = old_sym->attr.dimension;
3501 new_sym->attr.flavor = old_sym->attr.flavor;
3502
3503 /* Use the temporary as the backend_decl. */
3504 new_sym->backend_decl = tse.expr;
3505
3506 /* Create a fake symtree for it. */
3507 root = NULL;
3508 new_symtree = gfc_new_symtree (&root, old_sym->name);
3509 new_symtree->n.sym = new_sym;
3510 gcc_assert (new_symtree == root);
3511
3512 /* Go through the expression reference replacing the old_symtree
3513 with the new. */
a513927a 3514 forall_replace_symtree (c->expr1, old_sym, 2);
640670c7
PT
3515
3516 /* Now we have made this temporary, we might as well use it for
3517 the right hand side. */
3518 forall_replace_symtree (c->expr2, old_sym, 1);
3519}
3520
3521
3522/* Handles dependencies in forall assignments. */
3523static int
3524check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3525{
3526 gfc_ref *lref;
3527 gfc_ref *rref;
3528 int need_temp;
3529 gfc_symbol *lsym;
3530
a513927a
SK
3531 lsym = c->expr1->symtree->n.sym;
3532 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
640670c7
PT
3533
3534 /* Now check for dependencies within the 'variable'
3535 expression itself. These are treated by making a complete
3536 copy of variable and changing all the references to it
3537 point to the copy instead. Note that the shallow copy of
3538 the variable will not suffice for derived types with
3539 pointer components. We therefore leave these to their
3540 own devices. */
3541 if (lsym->ts.type == BT_DERIVED
bc21d315 3542 && lsym->ts.u.derived->attr.pointer_comp)
640670c7
PT
3543 return need_temp;
3544
3545 new_symtree = NULL;
524af0d6 3546 if (find_forall_index (c->expr1, lsym, 2))
640670c7
PT
3547 {
3548 forall_make_variable_temp (c, pre, post);
3549 need_temp = 0;
3550 }
3551
3552 /* Substrings with dependencies are treated in the same
3553 way. */
a513927a
SK
3554 if (c->expr1->ts.type == BT_CHARACTER
3555 && c->expr1->ref
640670c7
PT
3556 && c->expr2->expr_type == EXPR_VARIABLE
3557 && lsym == c->expr2->symtree->n.sym)
3558 {
a513927a 3559 for (lref = c->expr1->ref; lref; lref = lref->next)
640670c7
PT
3560 if (lref->type == REF_SUBSTRING)
3561 break;
3562 for (rref = c->expr2->ref; rref; rref = rref->next)
3563 if (rref->type == REF_SUBSTRING)
3564 break;
3565
3566 if (rref && lref
3567 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
3568 {
3569 forall_make_variable_temp (c, pre, post);
3570 need_temp = 0;
3571 }
3572 }
3573 return need_temp;
3574}
3575
3576
3577static void
3578cleanup_forall_symtrees (gfc_code *c)
3579{
a513927a 3580 forall_restore_symtree (c->expr1);
640670c7 3581 forall_restore_symtree (c->expr2);
cede9502
JM
3582 free (new_symtree->n.sym);
3583 free (new_symtree);
640670c7
PT
3584}
3585
3586
bfcabc6c
RS
3587/* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
3588 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
3589 indicates whether we should generate code to test the FORALLs mask
3590 array. OUTER is the loop header to be used for initializing mask
3591 indices.
3592
3593 The generated loop format is:
6de9cd9a
DN
3594 count = (end - start + step) / step
3595 loopvar = start
3596 while (1)
3597 {
3598 if (count <=0 )
3599 goto end_of_loop
3600 <body>
3601 loopvar += step
3602 count --
3603 }
3604 end_of_loop: */
3605
3606static tree
bfcabc6c
RS
3607gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
3608 int mask_flag, stmtblock_t *outer)
6de9cd9a 3609{
bfcabc6c 3610 int n, nvar;
6de9cd9a
DN
3611 tree tmp;
3612 tree cond;
3613 stmtblock_t block;
3614 tree exit_label;
3615 tree count;
fcf3be37 3616 tree var, start, end, step;
6de9cd9a
DN
3617 iter_info *iter;
3618
bfcabc6c
RS
3619 /* Initialize the mask index outside the FORALL nest. */
3620 if (mask_flag && forall_tmp->mask)
726a989a 3621 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
bfcabc6c 3622
6de9cd9a 3623 iter = forall_tmp->this_loop;
bfcabc6c 3624 nvar = forall_tmp->nvar;
6de9cd9a
DN
3625 for (n = 0; n < nvar; n++)
3626 {
3627 var = iter->var;
3628 start = iter->start;
3629 end = iter->end;
3630 step = iter->step;
3631
3632 exit_label = gfc_build_label_decl (NULL_TREE);
3633 TREE_USED (exit_label) = 1;
3634
3635 /* The loop counter. */
3636 count = gfc_create_var (TREE_TYPE (var), "count");
3637
3638 /* The body of the loop. */
3639 gfc_init_block (&block);
3640
3641 /* The exit condition. */
63ee5404 3642 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
bc98ed60 3643 count, build_int_cst (TREE_TYPE (count), 0));
f0caea48 3644
bc436e10
TK
3645 /* PR 83064 means that we cannot use annot_expr_parallel_kind until
3646 the autoparallelizer can hande this. */
3647 if (forall_tmp->do_concurrent)
ac9effed 3648 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
2ca4e2c2 3649 build_int_cst (integer_type_node,
bc436e10 3650 annot_expr_ivdep_kind),
ac9effed 3651 integer_zero_node);
2ca4e2c2 3652
6de9cd9a 3653 tmp = build1_v (GOTO_EXPR, exit_label);
bc98ed60
TB
3654 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3655 cond, tmp, build_empty_stmt (input_location));
6de9cd9a
DN
3656 gfc_add_expr_to_block (&block, tmp);
3657
3658 /* The main loop body. */
3659 gfc_add_expr_to_block (&block, body);
3660
3661 /* Increment the loop variable. */
bc98ed60
TB
3662 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3663 step);
726a989a 3664 gfc_add_modify (&block, var, tmp);
6de9cd9a 3665
a8e12e4d
TS
3666 /* Advance to the next mask element. Only do this for the
3667 innermost loop. */
fcf3be37
JJ
3668 if (n == 0 && mask_flag && forall_tmp->mask)
3669 {
3670 tree maskindex = forall_tmp->maskindex;
bc98ed60
TB
3671 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3672 maskindex, gfc_index_one_node);
726a989a 3673 gfc_add_modify (&block, maskindex, tmp);
fcf3be37
JJ
3674 }
3675
6de9cd9a 3676 /* Decrement the loop counter. */
bc98ed60
TB
3677 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3678 build_int_cst (TREE_TYPE (var), 1));
726a989a 3679 gfc_add_modify (&block, count, tmp);
6de9cd9a
DN
3680
3681 body = gfc_finish_block (&block);
3682
3683 /* Loop var initialization. */
3684 gfc_init_block (&block);
726a989a 3685 gfc_add_modify (&block, var, start);
6de9cd9a 3686
fcf3be37 3687
6de9cd9a 3688 /* Initialize the loop counter. */
bc98ed60
TB
3689 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
3690 start);
3691 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
3692 tmp);
3693 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
3694 tmp, step);
726a989a 3695 gfc_add_modify (&block, count, tmp);
6de9cd9a
DN
3696
3697 /* The loop expression. */
923ab88c 3698 tmp = build1_v (LOOP_EXPR, body);
6de9cd9a
DN
3699 gfc_add_expr_to_block (&block, tmp);
3700
3701 /* The exit label. */
3702 tmp = build1_v (LABEL_EXPR, exit_label);
3703 gfc_add_expr_to_block (&block, tmp);
3704
3705 body = gfc_finish_block (&block);
3706 iter = iter->next;
3707 }
3708 return body;
3709}
3710
3711
bfcabc6c
RS
3712/* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3713 is nonzero, the body is controlled by all masks in the forall nest.
3714 Otherwise, the innermost loop is not controlled by it's mask. This
3715 is used for initializing that mask. */
6de9cd9a
DN
3716
3717static tree
3718gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
bfcabc6c 3719 int mask_flag)
6de9cd9a
DN
3720{
3721 tree tmp;
bfcabc6c 3722 stmtblock_t header;
6de9cd9a 3723 forall_info *forall_tmp;
bfcabc6c
RS
3724 tree mask, maskindex;
3725
3726 gfc_start_block (&header);
6de9cd9a
DN
3727
3728 forall_tmp = nested_forall_info;
bfcabc6c 3729 while (forall_tmp != NULL)
6de9cd9a 3730 {
bfcabc6c
RS
3731 /* Generate body with masks' control. */
3732 if (mask_flag)
6de9cd9a 3733 {
bfcabc6c
RS
3734 mask = forall_tmp->mask;
3735 maskindex = forall_tmp->maskindex;
6de9cd9a 3736
bfcabc6c
RS
3737 /* If a mask was specified make the assignment conditional. */
3738 if (mask)
3739 {
1d6b7f39 3740 tmp = gfc_build_array_ref (mask, maskindex, NULL);
c2255bc4
AH
3741 body = build3_v (COND_EXPR, tmp, body,
3742 build_empty_stmt (input_location));
6de9cd9a 3743 }
6de9cd9a 3744 }
bfcabc6c 3745 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
e8d366ec 3746 forall_tmp = forall_tmp->prev_nest;
bfcabc6c 3747 mask_flag = 1;
6de9cd9a
DN
3748 }
3749
bfcabc6c
RS
3750 gfc_add_expr_to_block (&header, body);
3751 return gfc_finish_block (&header);
6de9cd9a
DN
3752}
3753
3754
3755/* Allocate data for holding a temporary array. Returns either a local
3756 temporary array or a pointer variable. */
3757
3758static tree
3759gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
3760 tree elem_type)
3761{
3762 tree tmpvar;
3763 tree type;
3764 tree tmp;
6de9cd9a
DN
3765
3766 if (INTEGER_CST_P (size))
bc98ed60
TB
3767 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3768 size, gfc_index_one_node);
6de9cd9a
DN
3769 else
3770 tmp = NULL_TREE;
3771
7ab92584 3772 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
6de9cd9a 3773 type = build_array_type (elem_type, type);
55250ed7 3774 if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
6de9cd9a 3775 {
6de9cd9a
DN
3776 tmpvar = gfc_create_var (type, "temp");
3777 *pdata = NULL_TREE;
3778 }
3779 else
3780 {
3781 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
3782 *pdata = convert (pvoid_type_node, tmpvar);
3783
1529b8d9 3784 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
726a989a 3785 gfc_add_modify (pblock, tmpvar, tmp);
6de9cd9a
DN
3786 }
3787 return tmpvar;
3788}
3789
3790
3791/* Generate codes to copy the temporary to the actual lhs. */
3792
3793static tree
8de1f441 3794generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
7bd5dad2
LK
3795 tree count1,
3796 gfc_ss *lss, gfc_ss *rss,
3797 tree wheremask, bool invert)
6de9cd9a 3798{
7bd5dad2
LK
3799 stmtblock_t block, body1;
3800 gfc_loopinfo loop;
3801 gfc_se lse;
3802 gfc_se rse;
011daa76 3803 tree tmp;
6de9cd9a
DN
3804 tree wheremaskexpr;
3805
7bd5dad2 3806 (void) rss; /* TODO: unused. */
6de9cd9a 3807
7bd5dad2 3808 gfc_start_block (&block);
6de9cd9a 3809
7bd5dad2
LK
3810 gfc_init_se (&rse, NULL);
3811 gfc_init_se (&lse, NULL);
6de9cd9a 3812
7bd5dad2
LK
3813 if (lss == gfc_ss_terminator)
3814 {
3815 gfc_init_block (&body1);
6de9cd9a 3816 gfc_conv_expr (&lse, expr);
7bd5dad2 3817 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
6de9cd9a
DN
3818 }
3819 else
3820 {
7bd5dad2
LK
3821 /* Initialize the loop. */
3822 gfc_init_loopinfo (&loop);
6de9cd9a 3823
7bd5dad2
LK
3824 /* We may need LSS to determine the shape of the expression. */
3825 gfc_add_ss_to_loop (&loop, lss);
6de9cd9a 3826
7bd5dad2
LK
3827 gfc_conv_ss_startstride (&loop);
3828 gfc_conv_loop_setup (&loop, &expr->where);
6de9cd9a
DN
3829
3830 gfc_mark_ss_chain_used (lss, 1);
7bd5dad2
LK
3831 /* Start the loop body. */
3832 gfc_start_scalarized_body (&loop, &body1);
6de9cd9a 3833
7bd5dad2
LK
3834 /* Translate the expression. */
3835 gfc_copy_loopinfo_to_se (&lse, &loop);
6de9cd9a 3836 lse.ss = lss;
7bd5dad2 3837 gfc_conv_expr (&lse, expr);
6de9cd9a
DN
3838
3839 /* Form the expression of the temporary. */
7bd5dad2
LK
3840 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3841 }
6de9cd9a 3842
7bd5dad2
LK
3843 /* Use the scalar assignment. */
3844 rse.string_length = lse.string_length;
3845 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts,
3846 expr->expr_type == EXPR_VARIABLE, false);
6de9cd9a 3847
7bd5dad2
LK
3848 /* Form the mask expression according to the mask tree list. */
3849 if (wheremask)
3850 {
3851 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3852 if (invert)
3853 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3854 TREE_TYPE (wheremaskexpr),
3855 wheremaskexpr);
3856 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3857 wheremaskexpr, tmp,
3858 build_empty_stmt (input_location));
3859 }
6de9cd9a 3860
7bd5dad2 3861 gfc_add_expr_to_block (&body1, tmp);
6de9cd9a 3862
7bd5dad2
LK
3863 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3864 count1, gfc_index_one_node);
3865 gfc_add_modify (&body1, count1, tmp);
6de9cd9a 3866
7bd5dad2
LK
3867 if (lss == gfc_ss_terminator)
3868 gfc_add_block_to_block (&block, &body1);
3869 else
3870 {
6de9cd9a
DN
3871 /* Increment count3. */
3872 if (count3)
8de1f441 3873 {
bc98ed60 3874 tmp = fold_build2_loc (input_location, PLUS_EXPR,
7bd5dad2
LK
3875 gfc_array_index_type,
3876 count3, gfc_index_one_node);
3877 gfc_add_modify (&body1, count3, tmp);
8de1f441 3878 }
6de9cd9a
DN
3879
3880 /* Generate the copying loops. */
7bd5dad2
LK
3881 gfc_trans_scalarizing_loops (&loop, &body1);
3882
3883 gfc_add_block_to_block (&block, &loop.pre);
3884 gfc_add_block_to_block (&block, &loop.post);
6de9cd9a 3885
7bd5dad2
LK
3886 gfc_cleanup_loop (&loop);
3887 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3888 as tree nodes in SS may not be valid in different scope. */
6de9cd9a 3889 }
7bd5dad2
LK
3890
3891 tmp = gfc_finish_block (&block);
6de9cd9a
DN
3892 return tmp;
3893}
3894
3895
011daa76
RS
3896/* Generate codes to copy rhs to the temporary. TMP1 is the address of
3897 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3898 and should not be freed. WHEREMASK is the conditional execution mask
3899 whose sense may be inverted by INVERT. */
6de9cd9a
DN
3900
3901static tree
8de1f441
JJ
3902generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3903 tree count1, gfc_ss *lss, gfc_ss *rss,
011daa76 3904 tree wheremask, bool invert)
6de9cd9a
DN
3905{
3906 stmtblock_t block, body1;
3907 gfc_loopinfo loop;
3908 gfc_se lse;
3909 gfc_se rse;
011daa76 3910 tree tmp;
6de9cd9a
DN
3911 tree wheremaskexpr;
3912
3913 gfc_start_block (&block);
3914
3915 gfc_init_se (&rse, NULL);
3916 gfc_init_se (&lse, NULL);
3917
3918 if (lss == gfc_ss_terminator)
3919 {
3920 gfc_init_block (&body1);
3921 gfc_conv_expr (&rse, expr2);
1d6b7f39 3922 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
6de9cd9a
DN
3923 }
3924 else
3925 {
1f2959f0 3926 /* Initialize the loop. */
6de9cd9a
DN
3927 gfc_init_loopinfo (&loop);
3928
3929 /* We may need LSS to determine the shape of the expression. */
3930 gfc_add_ss_to_loop (&loop, lss);
3931 gfc_add_ss_to_loop (&loop, rss);
3932
3933 gfc_conv_ss_startstride (&loop);
bdfd2ff0 3934 gfc_conv_loop_setup (&loop, &expr2->where);
6de9cd9a
DN
3935
3936 gfc_mark_ss_chain_used (rss, 1);
3937 /* Start the loop body. */
3938 gfc_start_scalarized_body (&loop, &body1);
3939
3940 /* Translate the expression. */
3941 gfc_copy_loopinfo_to_se (&rse, &loop);
3942 rse.ss = rss;
3943 gfc_conv_expr (&rse, expr2);
3944
3945 /* Form the expression of the temporary. */
1d6b7f39 3946 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
6de9cd9a
DN
3947 }
3948
3949 /* Use the scalar assignment. */
5046aff5 3950 lse.string_length = rse.string_length;
ed673c00
MM
3951 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
3952 expr2->expr_type == EXPR_VARIABLE, false);
6de9cd9a
DN
3953
3954 /* Form the mask expression according to the mask tree list. */
3955 if (wheremask)
3956 {
1d6b7f39 3957 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
011daa76 3958 if (invert)
bc98ed60
TB
3959 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3960 TREE_TYPE (wheremaskexpr),
3961 wheremaskexpr);
3962 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3963 wheremaskexpr, tmp,
3964 build_empty_stmt (input_location));
6de9cd9a
DN
3965 }
3966
3967 gfc_add_expr_to_block (&body1, tmp);
3968
3969 if (lss == gfc_ss_terminator)
3970 {
3971 gfc_add_block_to_block (&block, &body1);
8de1f441
JJ
3972
3973 /* Increment count1. */
bc98ed60
TB
3974 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3975 count1, gfc_index_one_node);
726a989a 3976 gfc_add_modify (&block, count1, tmp);
6de9cd9a
DN
3977 }
3978 else
3979 {
8de1f441 3980 /* Increment count1. */
bc98ed60
TB
3981 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3982 count1, gfc_index_one_node);
726a989a 3983 gfc_add_modify (&body1, count1, tmp);
6de9cd9a
DN
3984
3985 /* Increment count3. */
3986 if (count3)
8de1f441 3987 {
bc98ed60
TB
3988 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3989 gfc_array_index_type,
3990 count3, gfc_index_one_node);
726a989a 3991 gfc_add_modify (&body1, count3, tmp);
8de1f441 3992 }
6de9cd9a
DN
3993
3994 /* Generate the copying loops. */
3995 gfc_trans_scalarizing_loops (&loop, &body1);
3996
3997 gfc_add_block_to_block (&block, &loop.pre);
3998 gfc_add_block_to_block (&block, &loop.post);
3999
4000 gfc_cleanup_loop (&loop);
4001 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
8de1f441 4002 as tree nodes in SS may not be valid in different scope. */
6de9cd9a 4003 }
6de9cd9a
DN
4004
4005 tmp = gfc_finish_block (&block);
4006 return tmp;
4007}
4008
4009
4010/* Calculate the size of temporary needed in the assignment inside forall.
4011 LSS and RSS are filled in this function. */
4012
4013static tree
4014compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
4015 stmtblock_t * pblock,
4016 gfc_ss **lss, gfc_ss **rss)
4017{
4018 gfc_loopinfo loop;
4019 tree size;
4020 int i;
ca86ddcc 4021 int save_flag;
6de9cd9a
DN
4022 tree tmp;
4023
4024 *lss = gfc_walk_expr (expr1);
4025 *rss = NULL;
4026
7ab92584 4027 size = gfc_index_one_node;
6de9cd9a
DN
4028 if (*lss != gfc_ss_terminator)
4029 {
4030 gfc_init_loopinfo (&loop);
4031
4032 /* Walk the RHS of the expression. */
4033 *rss = gfc_walk_expr (expr2);
4034 if (*rss == gfc_ss_terminator)
26f77530
MM
4035 /* The rhs is scalar. Add a ss for the expression. */
4036 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
6de9cd9a
DN
4037
4038 /* Associate the SS with the loop. */
4039 gfc_add_ss_to_loop (&loop, *lss);
4040 /* We don't actually need to add the rhs at this point, but it might
4041 make guessing the loop bounds a bit easier. */
4042 gfc_add_ss_to_loop (&loop, *rss);
4043
4044 /* We only want the shape of the expression, not rest of the junk
4045 generated by the scalarizer. */
4046 loop.array_parameter = 1;
4047
4048 /* Calculate the bounds of the scalarization. */
d3d3011f 4049 save_flag = gfc_option.rtcheck;
c3fb8214 4050 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
6de9cd9a 4051 gfc_conv_ss_startstride (&loop);
d3d3011f 4052 gfc_option.rtcheck = save_flag;
bdfd2ff0 4053 gfc_conv_loop_setup (&loop, &expr2->where);
6de9cd9a
DN
4054
4055 /* Figure out how many elements we need. */
4056 for (i = 0; i < loop.dimen; i++)
4057 {
bc98ed60
TB
4058 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4059 gfc_array_index_type,
4060 gfc_index_one_node, loop.from[i]);
4061 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4062 gfc_array_index_type, tmp, loop.to[i]);
4063 size = fold_build2_loc (input_location, MULT_EXPR,
4064 gfc_array_index_type, size, tmp);
6de9cd9a
DN
4065 }
4066 gfc_add_block_to_block (pblock, &loop.pre);
4067 size = gfc_evaluate_now (size, pblock);
4068 gfc_add_block_to_block (pblock, &loop.post);
4069
4070 /* TODO: write a function that cleans up a loopinfo without freeing
4071 the SS chains. Currently a NOP. */
4072 }
4073
4074 return size;
4075}
4076
4077
2ad62c9b
RS
4078/* Calculate the overall iterator number of the nested forall construct.
4079 This routine actually calculates the number of times the body of the
4080 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
4081 that by the expression INNER_SIZE. The BLOCK argument specifies the
4082 block in which to calculate the result, and the optional INNER_SIZE_BODY
4083 argument contains any statements that need to executed (inside the loop)
4084 to initialize or calculate INNER_SIZE. */
6de9cd9a
DN
4085
4086static tree
4087compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
8de1f441 4088 stmtblock_t *inner_size_body, stmtblock_t *block)
6de9cd9a 4089{
2ad62c9b 4090 forall_info *forall_tmp = nested_forall_info;
6de9cd9a
DN
4091 tree tmp, number;
4092 stmtblock_t body;
4093
2ad62c9b
RS
4094 /* We can eliminate the innermost unconditional loops with constant
4095 array bounds. */
3bf783b7
RS
4096 if (INTEGER_CST_P (inner_size))
4097 {
2ad62c9b 4098 while (forall_tmp
8b704316 4099 && !forall_tmp->mask
2ad62c9b 4100 && INTEGER_CST_P (forall_tmp->size))
3bf783b7 4101 {
bc98ed60
TB
4102 inner_size = fold_build2_loc (input_location, MULT_EXPR,
4103 gfc_array_index_type,
4104 inner_size, forall_tmp->size);
2ad62c9b 4105 forall_tmp = forall_tmp->prev_nest;
3bf783b7 4106 }
2ad62c9b
RS
4107
4108 /* If there are no loops left, we have our constant result. */
4109 if (!forall_tmp)
4110 return inner_size;
3bf783b7 4111 }
2ad62c9b
RS
4112
4113 /* Otherwise, create a temporary variable to compute the result. */
6de9cd9a 4114 number = gfc_create_var (gfc_array_index_type, "num");
726a989a 4115 gfc_add_modify (block, number, gfc_index_zero_node);
6de9cd9a
DN
4116
4117 gfc_start_block (&body);
8de1f441
JJ
4118 if (inner_size_body)
4119 gfc_add_block_to_block (&body, inner_size_body);
2ad62c9b 4120 if (forall_tmp)
bc98ed60
TB
4121 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4122 gfc_array_index_type, number, inner_size);
6de9cd9a
DN
4123 else
4124 tmp = inner_size;
726a989a 4125 gfc_add_modify (&body, number, tmp);
6de9cd9a
DN
4126 tmp = gfc_finish_block (&body);
4127
4128 /* Generate loops. */
2ad62c9b
RS
4129 if (forall_tmp != NULL)
4130 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
6de9cd9a
DN
4131
4132 gfc_add_expr_to_block (block, tmp);
4133
4134 return number;
4135}
4136
4137
8de1f441
JJ
4138/* Allocate temporary for forall construct. SIZE is the size of temporary
4139 needed. PTEMP1 is returned for space free. */
6de9cd9a
DN
4140
4141static tree
8de1f441
JJ
4142allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
4143 tree * ptemp1)
6de9cd9a 4144{
bfcabc6c 4145 tree bytesize;
6de9cd9a 4146 tree unit;
6de9cd9a 4147 tree tmp;
6de9cd9a 4148
7c57b2f1 4149 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
bfcabc6c 4150 if (!integer_onep (unit))
bc98ed60
TB
4151 bytesize = fold_build2_loc (input_location, MULT_EXPR,
4152 gfc_array_index_type, size, unit);
bfcabc6c
RS
4153 else
4154 bytesize = size;
6de9cd9a
DN
4155
4156 *ptemp1 = NULL;
bfcabc6c 4157 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
6de9cd9a
DN
4158
4159 if (*ptemp1)
db3927fb 4160 tmp = build_fold_indirect_ref_loc (input_location, tmp);
6de9cd9a
DN
4161 return tmp;
4162}
4163
4164
8de1f441
JJ
4165/* Allocate temporary for forall construct according to the information in
4166 nested_forall_info. INNER_SIZE is the size of temporary needed in the
4167 assignment inside forall. PTEMP1 is returned for space free. */
4168
4169static tree
4170allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
4171 tree inner_size, stmtblock_t * inner_size_body,
4172 stmtblock_t * block, tree * ptemp1)
4173{
4174 tree size;
4175
4176 /* Calculate the total size of temporary needed in forall construct. */
4177 size = compute_overall_iter_number (nested_forall_info, inner_size,
4178 inner_size_body, block);
4179
4180 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
4181}
4182
4183
4184/* Handle assignments inside forall which need temporary.
4185
4186 forall (i=start:end:stride; maskexpr)
4187 e<i> = f<i>
4188 end forall
4189 (where e,f<i> are arbitrary expressions possibly involving i
4190 and there is a dependency between e<i> and f<i>)
4191 Translates to:
4192 masktmp(:) = maskexpr(:)
4193
4194 maskindex = 0;
4195 count1 = 0;
4196 num = 0;
4197 for (i = start; i <= end; i += stride)
4198 num += SIZE (f<i>)
4199 count1 = 0;
4200 ALLOCATE (tmp(num))
4201 for (i = start; i <= end; i += stride)
4202 {
4203 if (masktmp[maskindex++])
4204 tmp[count1++] = f<i>
4205 }
4206 maskindex = 0;
4207 count1 = 0;
4208 for (i = start; i <= end; i += stride)
4209 {
4210 if (masktmp[maskindex++])
4211 e<i> = tmp[count1++]
4212 }
4213 DEALLOCATE (tmp)
4214 */
6de9cd9a 4215static void
011daa76
RS
4216gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4217 tree wheremask, bool invert,
6de9cd9a
DN
4218 forall_info * nested_forall_info,
4219 stmtblock_t * block)
4220{
4221 tree type;
4222 tree inner_size;
4223 gfc_ss *lss, *rss;
8de1f441 4224 tree count, count1;
6de9cd9a
DN
4225 tree tmp, tmp1;
4226 tree ptemp1;
8de1f441 4227 stmtblock_t inner_size_body;
6de9cd9a 4228
8de1f441
JJ
4229 /* Create vars. count1 is the current iterator number of the nested
4230 forall. */
6de9cd9a 4231 count1 = gfc_create_var (gfc_array_index_type, "count1");
6de9cd9a
DN
4232
4233 /* Count is the wheremask index. */
4234 if (wheremask)
4235 {
4236 count = gfc_create_var (gfc_array_index_type, "count");
726a989a 4237 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a
DN
4238 }
4239 else
4240 count = NULL;
4241
4242 /* Initialize count1. */
726a989a 4243 gfc_add_modify (block, count1, gfc_index_zero_node);
6de9cd9a
DN
4244
4245 /* Calculate the size of temporary needed in the assignment. Return loop, lss
4246 and rss which are used in function generate_loop_for_rhs_to_temp(). */
6de9cd9a 4247 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
7bd5dad2 4248 if (expr1->ts.type == BT_CHARACTER)
640670c7 4249 {
7bd5dad2
LK
4250 type = NULL;
4251 if (expr1->ref && expr1->ref->type == REF_SUBSTRING)
640670c7 4252 {
7bd5dad2
LK
4253 gfc_se ssse;
4254 gfc_init_se (&ssse, NULL);
4255 gfc_conv_expr (&ssse, expr1);
4256 type = gfc_get_character_type_len (gfc_default_character_kind,
4257 ssse.string_length);
4258 }
4259 else
4260 {
4261 if (!expr1->ts.u.cl->backend_decl)
4262 {
4263 gfc_se tse;
4264 gcc_assert (expr1->ts.u.cl->length);
4265 gfc_init_se (&tse, NULL);
4266 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
4267 expr1->ts.u.cl->backend_decl = tse.expr;
4268 }
4269 type = gfc_get_character_type_len (gfc_default_character_kind,
4270 expr1->ts.u.cl->backend_decl);
640670c7 4271 }
640670c7
PT
4272 }
4273 else
4274 type = gfc_typenode_for_spec (&expr1->ts);
6de9cd9a 4275
7bd5dad2
LK
4276 gfc_init_block (&inner_size_body);
4277 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4278 &lss, &rss);
4279
6de9cd9a 4280 /* Allocate temporary for nested forall construct according to the
f7b529fa 4281 information in nested_forall_info and inner_size. */
8de1f441
JJ
4282 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
4283 &inner_size_body, block, &ptemp1);
6de9cd9a 4284
6de9cd9a 4285 /* Generate codes to copy rhs to the temporary . */
8de1f441 4286 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
011daa76 4287 wheremask, invert);
6de9cd9a 4288
1f2959f0 4289 /* Generate body and loops according to the information in
6de9cd9a 4290 nested_forall_info. */
bfcabc6c 4291 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4292 gfc_add_expr_to_block (block, tmp);
4293
4294 /* Reset count1. */
726a989a 4295 gfc_add_modify (block, count1, gfc_index_zero_node);
6de9cd9a 4296
6de9cd9a
DN
4297 /* Reset count. */
4298 if (wheremask)
726a989a 4299 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a 4300
7bd5dad2
LK
4301 /* TODO: Second call to compute_inner_temp_size to initialize lss and
4302 rss; there must be a better way. */
4303 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4304 &lss, &rss);
4305
6de9cd9a 4306 /* Generate codes to copy the temporary to lhs. */
011daa76 4307 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
7bd5dad2 4308 lss, rss,
011daa76 4309 wheremask, invert);
6de9cd9a 4310
1f2959f0 4311 /* Generate body and loops according to the information in
6de9cd9a 4312 nested_forall_info. */
bfcabc6c 4313 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4314 gfc_add_expr_to_block (block, tmp);
4315
4316 if (ptemp1)
4317 {
4318 /* Free the temporary. */
1529b8d9 4319 tmp = gfc_call_free (ptemp1);
6de9cd9a
DN
4320 gfc_add_expr_to_block (block, tmp);
4321 }
4322}
4323
4324
4325/* Translate pointer assignment inside FORALL which need temporary. */
4326
4327static void
4328gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4329 forall_info * nested_forall_info,
4330 stmtblock_t * block)
4331{
4332 tree type;
4333 tree inner_size;
4334 gfc_ss *lss, *rss;
4335 gfc_se lse;
4336 gfc_se rse;
6d63e468 4337 gfc_array_info *info;
6de9cd9a
DN
4338 gfc_loopinfo loop;
4339 tree desc;
4340 tree parm;
4341 tree parmtype;
4342 stmtblock_t body;
4343 tree count;
4344 tree tmp, tmp1, ptemp1;
6de9cd9a
DN
4345
4346 count = gfc_create_var (gfc_array_index_type, "count");
726a989a 4347 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a 4348
932ebb94 4349 inner_size = gfc_index_one_node;
6de9cd9a
DN
4350 lss = gfc_walk_expr (expr1);
4351 rss = gfc_walk_expr (expr2);
4352 if (lss == gfc_ss_terminator)
4353 {
4354 type = gfc_typenode_for_spec (&expr1->ts);
4355 type = build_pointer_type (type);
4356
4357 /* Allocate temporary for nested forall construct according to the
4358 information in nested_forall_info and inner_size. */
8de1f441
JJ
4359 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
4360 inner_size, NULL, block, &ptemp1);
6de9cd9a
DN
4361 gfc_start_block (&body);
4362 gfc_init_se (&lse, NULL);
1d6b7f39 4363 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
6de9cd9a
DN
4364 gfc_init_se (&rse, NULL);
4365 rse.want_pointer = 1;
4366 gfc_conv_expr (&rse, expr2);
4367 gfc_add_block_to_block (&body, &rse.pre);
726a989a 4368 gfc_add_modify (&body, lse.expr,
cc2804f1 4369 fold_convert (TREE_TYPE (lse.expr), rse.expr));
6de9cd9a
DN
4370 gfc_add_block_to_block (&body, &rse.post);
4371
4372 /* Increment count. */
bc98ed60
TB
4373 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4374 count, gfc_index_one_node);
726a989a 4375 gfc_add_modify (&body, count, tmp);
6de9cd9a
DN
4376
4377 tmp = gfc_finish_block (&body);
4378
1f2959f0 4379 /* Generate body and loops according to the information in
6de9cd9a 4380 nested_forall_info. */
bfcabc6c 4381 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4382 gfc_add_expr_to_block (block, tmp);
4383
4384 /* Reset count. */
726a989a 4385 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a 4386
6de9cd9a
DN
4387 gfc_start_block (&body);
4388 gfc_init_se (&lse, NULL);
4389 gfc_init_se (&rse, NULL);
1d6b7f39 4390 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
6de9cd9a
DN
4391 lse.want_pointer = 1;
4392 gfc_conv_expr (&lse, expr1);
4393 gfc_add_block_to_block (&body, &lse.pre);
726a989a 4394 gfc_add_modify (&body, lse.expr, rse.expr);
6de9cd9a
DN
4395 gfc_add_block_to_block (&body, &lse.post);
4396 /* Increment count. */
bc98ed60
TB
4397 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4398 count, gfc_index_one_node);
726a989a 4399 gfc_add_modify (&body, count, tmp);
6de9cd9a
DN
4400 tmp = gfc_finish_block (&body);
4401
1f2959f0 4402 /* Generate body and loops according to the information in
6de9cd9a 4403 nested_forall_info. */
bfcabc6c 4404 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4405 gfc_add_expr_to_block (block, tmp);
4406 }
4407 else
4408 {
4409 gfc_init_loopinfo (&loop);
4410
4411 /* Associate the SS with the loop. */
4412 gfc_add_ss_to_loop (&loop, rss);
4413
4414 /* Setup the scalarizing loops and bounds. */
4415 gfc_conv_ss_startstride (&loop);
4416
bdfd2ff0 4417 gfc_conv_loop_setup (&loop, &expr2->where);
6de9cd9a 4418
1838afec 4419 info = &rss->info->data.array;
6de9cd9a
DN
4420 desc = info->descriptor;
4421
4422 /* Make a new descriptor. */
4423 parmtype = gfc_get_element_type (TREE_TYPE (desc));
f33beee9 4424 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
fad0afd7 4425 loop.from, loop.to, 1,
10174ddf 4426 GFC_ARRAY_UNKNOWN, true);
6de9cd9a
DN
4427
4428 /* Allocate temporary for nested forall construct. */
4429 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
8de1f441 4430 inner_size, NULL, block, &ptemp1);
6de9cd9a
DN
4431 gfc_start_block (&body);
4432 gfc_init_se (&lse, NULL);
1d6b7f39 4433 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
6de9cd9a 4434 lse.direct_byref = 1;
2960a368 4435 gfc_conv_expr_descriptor (&lse, expr2);
6de9cd9a
DN
4436
4437 gfc_add_block_to_block (&body, &lse.pre);
4438 gfc_add_block_to_block (&body, &lse.post);
4439
4440 /* Increment count. */
bc98ed60
TB
4441 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4442 count, gfc_index_one_node);
726a989a 4443 gfc_add_modify (&body, count, tmp);
6de9cd9a
DN
4444
4445 tmp = gfc_finish_block (&body);
4446
1f2959f0 4447 /* Generate body and loops according to the information in
6de9cd9a 4448 nested_forall_info. */
bfcabc6c 4449 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4450 gfc_add_expr_to_block (block, tmp);
4451
4452 /* Reset count. */
726a989a 4453 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a 4454
1d6b7f39 4455 parm = gfc_build_array_ref (tmp1, count, NULL);
6de9cd9a 4456 gfc_init_se (&lse, NULL);
2960a368 4457 gfc_conv_expr_descriptor (&lse, expr1);
726a989a 4458 gfc_add_modify (&lse.pre, lse.expr, parm);
6de9cd9a
DN
4459 gfc_start_block (&body);
4460 gfc_add_block_to_block (&body, &lse.pre);
4461 gfc_add_block_to_block (&body, &lse.post);
4462
4463 /* Increment count. */
bc98ed60
TB
4464 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4465 count, gfc_index_one_node);
726a989a 4466 gfc_add_modify (&body, count, tmp);
6de9cd9a
DN
4467
4468 tmp = gfc_finish_block (&body);
4469
bfcabc6c 4470 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
6de9cd9a
DN
4471 gfc_add_expr_to_block (block, tmp);
4472 }
4473 /* Free the temporary. */
4474 if (ptemp1)
4475 {
1529b8d9 4476 tmp = gfc_call_free (ptemp1);
6de9cd9a
DN
4477 gfc_add_expr_to_block (block, tmp);
4478 }
4479}
4480
4481
4482/* FORALL and WHERE statements are really nasty, especially when you nest
4483 them. All the rhs of a forall assignment must be evaluated before the
4484 actual assignments are performed. Presumably this also applies to all the
4485 assignments in an inner where statement. */
4486
4487/* Generate code for a FORALL statement. Any temporaries are allocated as a
4488 linear array, relying on the fact that we process in the same order in all
4489 loops.
4490
4491 forall (i=start:end:stride; maskexpr)
4492 e<i> = f<i>
4493 g<i> = h<i>
4494 end forall
e7dc5b4f 4495 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
6de9cd9a 4496 Translates to:
8de1f441 4497 count = ((end + 1 - start) / stride)
6de9cd9a
DN
4498 masktmp(:) = maskexpr(:)
4499
4500 maskindex = 0;
4501 for (i = start; i <= end; i += stride)
4502 {
4503 if (masktmp[maskindex++])
4504 e<i> = f<i>
4505 }
4506 maskindex = 0;
4507 for (i = start; i <= end; i += stride)
4508 {
4509 if (masktmp[maskindex++])
cafa34aa 4510 g<i> = h<i>
6de9cd9a
DN
4511 }
4512
4513 Note that this code only works when there are no dependencies.
4514 Forall loop with array assignments and data dependencies are a real pain,
4515 because the size of the temporary cannot always be determined before the
1f2959f0 4516 loop is executed. This problem is compounded by the presence of nested
6de9cd9a
DN
4517 FORALL constructs.
4518 */
4519
4520static tree
4521gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
4522{
640670c7
PT
4523 stmtblock_t pre;
4524 stmtblock_t post;
6de9cd9a
DN
4525 stmtblock_t block;
4526 stmtblock_t body;
4527 tree *var;
4528 tree *start;
4529 tree *end;
4530 tree *step;
4531 gfc_expr **varexpr;
4532 tree tmp;
4533 tree assign;
4534 tree size;
6de9cd9a
DN
4535 tree maskindex;
4536 tree mask;
4537 tree pmask;
8c6a85e3 4538 tree cycle_label = NULL_TREE;
6de9cd9a
DN
4539 int n;
4540 int nvar;
4541 int need_temp;
4542 gfc_forall_iterator *fa;
4543 gfc_se se;
4544 gfc_code *c;
7b5b57b7 4545 gfc_saved_var *saved_vars;
bfcabc6c
RS
4546 iter_info *this_forall;
4547 forall_info *info;
e35a0e64
RS
4548 bool need_mask;
4549
4550 /* Do nothing if the mask is false. */
a513927a
SK
4551 if (code->expr1
4552 && code->expr1->expr_type == EXPR_CONSTANT
4553 && !code->expr1->value.logical)
c2255bc4 4554 return build_empty_stmt (input_location);
6de9cd9a
DN
4555
4556 n = 0;
4557 /* Count the FORALL index number. */
4558 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4559 n++;
4560 nvar = n;
4561
4562 /* Allocate the space for var, start, end, step, varexpr. */
93acb62c
JB
4563 var = XCNEWVEC (tree, nvar);
4564 start = XCNEWVEC (tree, nvar);
4565 end = XCNEWVEC (tree, nvar);
4566 step = XCNEWVEC (tree, nvar);
4567 varexpr = XCNEWVEC (gfc_expr *, nvar);
4568 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
6de9cd9a
DN
4569
4570 /* Allocate the space for info. */
93acb62c 4571 info = XCNEW (forall_info);
bfcabc6c 4572
640670c7
PT
4573 gfc_start_block (&pre);
4574 gfc_init_block (&post);
4575 gfc_init_block (&block);
bfcabc6c 4576
6de9cd9a
DN
4577 n = 0;
4578 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4579 {
4580 gfc_symbol *sym = fa->var->symtree->n.sym;
4581
bfcabc6c 4582 /* Allocate space for this_forall. */
93acb62c 4583 this_forall = XCNEW (iter_info);
6de9cd9a 4584
6de9cd9a
DN
4585 /* Create a temporary variable for the FORALL index. */
4586 tmp = gfc_typenode_for_spec (&sym->ts);
4587 var[n] = gfc_create_var (tmp, sym->name);
7b5b57b7
PB
4588 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
4589
6de9cd9a
DN
4590 /* Record it in this_forall. */
4591 this_forall->var = var[n];
4592
4593 /* Replace the index symbol's backend_decl with the temporary decl. */
4594 sym->backend_decl = var[n];
4595
4596 /* Work out the start, end and stride for the loop. */
4597 gfc_init_se (&se, NULL);
4598 gfc_conv_expr_val (&se, fa->start);
4599 /* Record it in this_forall. */
4600 this_forall->start = se.expr;
4601 gfc_add_block_to_block (&block, &se.pre);
4602 start[n] = se.expr;
4603
4604 gfc_init_se (&se, NULL);
4605 gfc_conv_expr_val (&se, fa->end);
4606 /* Record it in this_forall. */
4607 this_forall->end = se.expr;
4608 gfc_make_safe_expr (&se);
4609 gfc_add_block_to_block (&block, &se.pre);
4610 end[n] = se.expr;
4611
4612 gfc_init_se (&se, NULL);
4613 gfc_conv_expr_val (&se, fa->stride);
4614 /* Record it in this_forall. */
4615 this_forall->step = se.expr;
4616 gfc_make_safe_expr (&se);
4617 gfc_add_block_to_block (&block, &se.pre);
4618 step[n] = se.expr;
4619
4620 /* Set the NEXT field of this_forall to NULL. */
4621 this_forall->next = NULL;
4622 /* Link this_forall to the info construct. */
bfcabc6c 4623 if (info->this_loop)
6de9cd9a 4624 {
bfcabc6c 4625 iter_info *iter_tmp = info->this_loop;
6de9cd9a
DN
4626 while (iter_tmp->next != NULL)
4627 iter_tmp = iter_tmp->next;
4628 iter_tmp->next = this_forall;
4629 }
bfcabc6c
RS
4630 else
4631 info->this_loop = this_forall;
6de9cd9a
DN
4632
4633 n++;
4634 }
4635 nvar = n;
4636
bfcabc6c 4637 /* Calculate the size needed for the current forall level. */
7ab92584 4638 size = gfc_index_one_node;
6de9cd9a
DN
4639 for (n = 0; n < nvar; n++)
4640 {
6de9cd9a 4641 /* size = (end + step - start) / step. */
8b704316 4642 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
bc98ed60
TB
4643 step[n], start[n]);
4644 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
4645 end[n], tmp);
4646 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
4647 tmp, step[n]);
6de9cd9a
DN
4648 tmp = convert (gfc_array_index_type, tmp);
4649
bc98ed60
TB
4650 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4651 size, tmp);
6de9cd9a
DN
4652 }
4653
4654 /* Record the nvar and size of current forall level. */
4655 info->nvar = nvar;
4656 info->size = size;
4657
a513927a 4658 if (code->expr1)
e35a0e64
RS
4659 {
4660 /* If the mask is .true., consider the FORALL unconditional. */
a513927a
SK
4661 if (code->expr1->expr_type == EXPR_CONSTANT
4662 && code->expr1->value.logical)
e35a0e64
RS
4663 need_mask = false;
4664 else
4665 need_mask = true;
4666 }
4667 else
4668 need_mask = false;
4669
4670 /* First we need to allocate the mask. */
4671 if (need_mask)
bfcabc6c
RS
4672 {
4673 /* As the mask array can be very big, prefer compact boolean types. */
4674 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4675 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
4676 size, NULL, &block, &pmask);
4677 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
4678
4679 /* Record them in the info structure. */
4680 info->maskindex = maskindex;
4681 info->mask = mask;
4682 }
6de9cd9a
DN
4683 else
4684 {
bfcabc6c
RS
4685 /* No mask was specified. */
4686 maskindex = NULL_TREE;
4687 mask = pmask = NULL_TREE;
4688 }
4689
4690 /* Link the current forall level to nested_forall_info. */
e8d366ec
RS
4691 info->prev_nest = nested_forall_info;
4692 nested_forall_info = info;
6de9cd9a
DN
4693
4694 /* Copy the mask into a temporary variable if required.
f7b529fa 4695 For now we assume a mask temporary is needed. */
e35a0e64 4696 if (need_mask)
6de9cd9a 4697 {
bfcabc6c
RS
4698 /* As the mask array can be very big, prefer compact boolean types. */
4699 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
6de9cd9a 4700
726a989a 4701 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
6de9cd9a
DN
4702
4703 /* Start of mask assignment loop body. */
4704 gfc_start_block (&body);
4705
4706 /* Evaluate the mask expression. */
4707 gfc_init_se (&se, NULL);
a513927a 4708 gfc_conv_expr_val (&se, code->expr1);
6de9cd9a
DN
4709 gfc_add_block_to_block (&body, &se.pre);
4710
4711 /* Store the mask. */
bfcabc6c 4712 se.expr = convert (mask_type, se.expr);
6de9cd9a 4713
1d6b7f39 4714 tmp = gfc_build_array_ref (mask, maskindex, NULL);
726a989a 4715 gfc_add_modify (&body, tmp, se.expr);
6de9cd9a
DN
4716
4717 /* Advance to the next mask element. */
bc98ed60
TB
4718 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4719 maskindex, gfc_index_one_node);
726a989a 4720 gfc_add_modify (&body, maskindex, tmp);
6de9cd9a
DN
4721
4722 /* Generate the loops. */
4723 tmp = gfc_finish_block (&body);
bfcabc6c 4724 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
6de9cd9a
DN
4725 gfc_add_expr_to_block (&block, tmp);
4726 }
6de9cd9a 4727
8c6a85e3
TB
4728 if (code->op == EXEC_DO_CONCURRENT)
4729 {
4730 gfc_init_block (&body);
4731 cycle_label = gfc_build_label_decl (NULL_TREE);
4732 code->cycle_label = cycle_label;
4733 tmp = gfc_trans_code (code->block->next);
4734 gfc_add_expr_to_block (&body, tmp);
4735
4736 if (TREE_USED (cycle_label))
4737 {
4738 tmp = build1_v (LABEL_EXPR, cycle_label);
4739 gfc_add_expr_to_block (&body, tmp);
4740 }
4741
4742 tmp = gfc_finish_block (&body);
2ca4e2c2 4743 nested_forall_info->do_concurrent = true;
8c6a85e3
TB
4744 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4745 gfc_add_expr_to_block (&block, tmp);
4746 goto done;
4747 }
4748
6de9cd9a
DN
4749 c = code->block->next;
4750
4751 /* TODO: loop merging in FORALL statements. */
4752 /* Now that we've got a copy of the mask, generate the assignment loops. */
4753 while (c)
4754 {
4755 switch (c->op)
4756 {
4757 case EXEC_ASSIGN:
640670c7
PT
4758 /* A scalar or array assignment. DO the simple check for
4759 lhs to rhs dependencies. These make a temporary for the
4760 rhs and form a second forall block to copy to variable. */
4761 need_temp = check_forall_dependencies(c, &pre, &post);
4762
69de3b83 4763 /* Temporaries due to array assignment data dependencies introduce
6de9cd9a 4764 no end of problems. */
7bd5dad2
LK
4765 if (need_temp || flag_test_forall_temp)
4766 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
6de9cd9a
DN
4767 nested_forall_info, &block);
4768 else
4769 {
4770 /* Use the normal assignment copying routines. */
2b56d6a4 4771 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
6de9cd9a 4772
6de9cd9a 4773 /* Generate body and loops. */
bfcabc6c
RS
4774 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4775 assign, 1);
6de9cd9a
DN
4776 gfc_add_expr_to_block (&block, tmp);
4777 }
4778
640670c7
PT
4779 /* Cleanup any temporary symtrees that have been made to deal
4780 with dependencies. */
4781 if (new_symtree)
4782 cleanup_forall_symtrees (c);
4783
6de9cd9a
DN
4784 break;
4785
4786 case EXEC_WHERE:
6de9cd9a 4787 /* Translate WHERE or WHERE construct nested in FORALL. */
011daa76 4788 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
3891cee2 4789 break;
6de9cd9a
DN
4790
4791 /* Pointer assignment inside FORALL. */
4792 case EXEC_POINTER_ASSIGN:
a513927a 4793 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
7bd5dad2
LK
4794 /* Avoid cases where a temporary would never be needed and where
4795 the temp code is guaranteed to fail. */
4796 if (need_temp
4797 || (flag_test_forall_temp
4798 && c->expr2->expr_type != EXPR_CONSTANT
4799 && c->expr2->expr_type != EXPR_NULL))
a513927a 4800 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
6de9cd9a
DN
4801 nested_forall_info, &block);
4802 else
4803 {
4804 /* Use the normal assignment copying routines. */
a513927a 4805 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
6de9cd9a 4806
6de9cd9a 4807 /* Generate body and loops. */
bfcabc6c
RS
4808 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4809 assign, 1);
6de9cd9a
DN
4810 gfc_add_expr_to_block (&block, tmp);
4811 }
4812 break;
4813
4814 case EXEC_FORALL:
4815 tmp = gfc_trans_forall_1 (c, nested_forall_info);
4816 gfc_add_expr_to_block (&block, tmp);
4817 break;
4818
48474141
PT
4819 /* Explicit subroutine calls are prevented by the frontend but interface
4820 assignments can legitimately produce them. */
476220e7 4821 case EXEC_ASSIGN_CALL:
eb74e79b 4822 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
bfcabc6c 4823 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
48474141
PT
4824 gfc_add_expr_to_block (&block, tmp);
4825 break;
4826
6de9cd9a 4827 default:
6e45f57b 4828 gcc_unreachable ();
6de9cd9a
DN
4829 }
4830
4831 c = c->next;
4832 }
4833
8c6a85e3 4834done:
7b5b57b7
PB
4835 /* Restore the original index variables. */
4836 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
4837 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
6de9cd9a
DN
4838
4839 /* Free the space for var, start, end, step, varexpr. */
cede9502
JM
4840 free (var);
4841 free (start);
4842 free (end);
4843 free (step);
4844 free (varexpr);
4845 free (saved_vars);
6de9cd9a 4846
3231fe90
MM
4847 for (this_forall = info->this_loop; this_forall;)
4848 {
4849 iter_info *next = this_forall->next;
cede9502 4850 free (this_forall);
3231fe90
MM
4851 this_forall = next;
4852 }
4853
e8d366ec 4854 /* Free the space for this forall_info. */
cede9502 4855 free (info);
e8d366ec 4856
6de9cd9a
DN
4857 if (pmask)
4858 {
4859 /* Free the temporary for the mask. */
1529b8d9 4860 tmp = gfc_call_free (pmask);
6de9cd9a
DN
4861 gfc_add_expr_to_block (&block, tmp);
4862 }
4863 if (maskindex)
4864 pushdecl (maskindex);
4865
640670c7
PT
4866 gfc_add_block_to_block (&pre, &block);
4867 gfc_add_block_to_block (&pre, &post);
4868
4869 return gfc_finish_block (&pre);
6de9cd9a
DN
4870}
4871
4872
4873/* Translate the FORALL statement or construct. */
4874
4875tree gfc_trans_forall (gfc_code * code)
4876{
4877 return gfc_trans_forall_1 (code, NULL);
4878}
4879
4880
8c6a85e3
TB
4881/* Translate the DO CONCURRENT construct. */
4882
4883tree gfc_trans_do_concurrent (gfc_code * code)
4884{
4885 return gfc_trans_forall_1 (code, NULL);
4886}
4887
4888
6de9cd9a
DN
4889/* Evaluate the WHERE mask expression, copy its value to a temporary.
4890 If the WHERE construct is nested in FORALL, compute the overall temporary
4891 needed by the WHERE mask expression multiplied by the iterator number of
4892 the nested forall.
4893 ME is the WHERE mask expression.
011daa76
RS
4894 MASK is the current execution mask upon input, whose sense may or may
4895 not be inverted as specified by the INVERT argument.
3891cee2
RS
4896 CMASK is the updated execution mask on output, or NULL if not required.
4897 PMASK is the pending execution mask on output, or NULL if not required.
4898 BLOCK is the block in which to place the condition evaluation loops. */
6de9cd9a 4899
3891cee2 4900static void
6de9cd9a 4901gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
011daa76 4902 tree mask, bool invert, tree cmask, tree pmask,
3891cee2 4903 tree mask_type, stmtblock_t * block)
6de9cd9a
DN
4904{
4905 tree tmp, tmp1;
4906 gfc_ss *lss, *rss;
4907 gfc_loopinfo loop;
3891cee2
RS
4908 stmtblock_t body, body1;
4909 tree count, cond, mtmp;
6de9cd9a 4910 gfc_se lse, rse;
6de9cd9a
DN
4911
4912 gfc_init_loopinfo (&loop);
4913
3891cee2
RS
4914 lss = gfc_walk_expr (me);
4915 rss = gfc_walk_expr (me);
6de9cd9a
DN
4916
4917 /* Variable to index the temporary. */
4918 count = gfc_create_var (gfc_array_index_type, "count");
1f2959f0 4919 /* Initialize count. */
726a989a 4920 gfc_add_modify (block, count, gfc_index_zero_node);
6de9cd9a
DN
4921
4922 gfc_start_block (&body);
4923
4924 gfc_init_se (&rse, NULL);
4925 gfc_init_se (&lse, NULL);
4926
4927 if (lss == gfc_ss_terminator)
4928 {
4929 gfc_init_block (&body1);
4930 }
4931 else
4932 {
1f2959f0 4933 /* Initialize the loop. */
6de9cd9a
DN
4934 gfc_init_loopinfo (&loop);
4935
4936 /* We may need LSS to determine the shape of the expression. */
4937 gfc_add_ss_to_loop (&loop, lss);
4938 gfc_add_ss_to_loop (&loop, rss);
4939
4940 gfc_conv_ss_startstride (&loop);
bdfd2ff0 4941 gfc_conv_loop_setup (&loop, &me->where);
6de9cd9a
DN
4942
4943 gfc_mark_ss_chain_used (rss, 1);
4944 /* Start the loop body. */
4945 gfc_start_scalarized_body (&loop, &body1);
4946
4947 /* Translate the expression. */
4948 gfc_copy_loopinfo_to_se (&rse, &loop);
4949 rse.ss = rss;
4950 gfc_conv_expr (&rse, me);
4951 }
6de9cd9a 4952
b82feea5 4953 /* Variable to evaluate mask condition. */
3891cee2
RS
4954 cond = gfc_create_var (mask_type, "cond");
4955 if (mask && (cmask || pmask))
4956 mtmp = gfc_create_var (mask_type, "mask");
4957 else mtmp = NULL_TREE;
4958
4959 gfc_add_block_to_block (&body1, &lse.pre);
4960 gfc_add_block_to_block (&body1, &rse.pre);
6de9cd9a 4961
726a989a 4962 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
3891cee2
RS
4963
4964 if (mask && (cmask || pmask))
42e73749 4965 {
1d6b7f39 4966 tmp = gfc_build_array_ref (mask, count, NULL);
011daa76 4967 if (invert)
bc98ed60 4968 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
726a989a 4969 gfc_add_modify (&body1, mtmp, tmp);
42e73749 4970 }
6de9cd9a 4971
3891cee2
RS
4972 if (cmask)
4973 {
1d6b7f39 4974 tmp1 = gfc_build_array_ref (cmask, count, NULL);
3891cee2
RS
4975 tmp = cond;
4976 if (mask)
bc98ed60
TB
4977 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4978 mtmp, tmp);
726a989a 4979 gfc_add_modify (&body1, tmp1, tmp);
3891cee2
RS
4980 }
4981
4982 if (pmask)
4983 {
1d6b7f39 4984 tmp1 = gfc_build_array_ref (pmask, count, NULL);
bc98ed60 4985 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
3891cee2 4986 if (mask)
bc98ed60
TB
4987 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4988 tmp);
726a989a 4989 gfc_add_modify (&body1, tmp1, tmp);
3891cee2
RS
4990 }
4991
4992 gfc_add_block_to_block (&body1, &lse.post);
4993 gfc_add_block_to_block (&body1, &rse.post);
4994
4995 if (lss == gfc_ss_terminator)
6de9cd9a
DN
4996 {
4997 gfc_add_block_to_block (&body, &body1);
4998 }
4999 else
5000 {
5001 /* Increment count. */
bc98ed60
TB
5002 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5003 count, gfc_index_one_node);
726a989a 5004 gfc_add_modify (&body1, count, tmp1);
6de9cd9a
DN
5005
5006 /* Generate the copying loops. */
5007 gfc_trans_scalarizing_loops (&loop, &body1);
5008
5009 gfc_add_block_to_block (&body, &loop.pre);
5010 gfc_add_block_to_block (&body, &loop.post);
5011
5012 gfc_cleanup_loop (&loop);
5013 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
5014 as tree nodes in SS may not be valid in different scope. */
5015 }
5016
5017 tmp1 = gfc_finish_block (&body);
5018 /* If the WHERE construct is inside FORALL, fill the full temporary. */
5019 if (nested_forall_info != NULL)
bfcabc6c 5020 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
6de9cd9a
DN
5021
5022 gfc_add_expr_to_block (block, tmp1);
6de9cd9a
DN
5023}
5024
5025
5026/* Translate an assignment statement in a WHERE statement or construct
5027 statement. The MASK expression is used to control which elements
011daa76
RS
5028 of EXPR1 shall be assigned. The sense of MASK is specified by
5029 INVERT. */
6de9cd9a
DN
5030
5031static tree
011daa76
RS
5032gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
5033 tree mask, bool invert,
a00b8d1a 5034 tree count1, tree count2,
eb74e79b 5035 gfc_code *cnext)
6de9cd9a
DN
5036{
5037 gfc_se lse;
5038 gfc_se rse;
5039 gfc_ss *lss;
5040 gfc_ss *lss_section;
5041 gfc_ss *rss;
5042
5043 gfc_loopinfo loop;
5044 tree tmp;
5045 stmtblock_t block;
5046 stmtblock_t body;
3c90c9ae 5047 tree index, maskexpr;
6de9cd9a 5048
1cc0e193 5049 /* A defined assignment. */
eb74e79b
PT
5050 if (cnext && cnext->resolved_sym)
5051 return gfc_trans_call (cnext, true, mask, count1, invert);
5052
6de9cd9a
DN
5053#if 0
5054 /* TODO: handle this special case.
5055 Special case a single function returning an array. */
5056 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
5057 {
5058 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
5059 if (tmp)
5060 return tmp;
5061 }
5062#endif
5063
5064 /* Assignment of the form lhs = rhs. */
5065 gfc_start_block (&block);
5066
5067 gfc_init_se (&lse, NULL);
5068 gfc_init_se (&rse, NULL);
5069
5070 /* Walk the lhs. */
5071 lss = gfc_walk_expr (expr1);
5072 rss = NULL;
5073
5074 /* In each where-assign-stmt, the mask-expr and the variable being
5075 defined shall be arrays of the same shape. */
6e45f57b 5076 gcc_assert (lss != gfc_ss_terminator);
6de9cd9a
DN
5077
5078 /* The assignment needs scalarization. */
5079 lss_section = lss;
5080
5081 /* Find a non-scalar SS from the lhs. */
5082 while (lss_section != gfc_ss_terminator
bcc4d4e0 5083 && lss_section->info->type != GFC_SS_SECTION)
6de9cd9a
DN
5084 lss_section = lss_section->next;
5085
6e45f57b 5086 gcc_assert (lss_section != gfc_ss_terminator);
6de9cd9a
DN
5087
5088 /* Initialize the scalarizer. */
5089 gfc_init_loopinfo (&loop);
5090
5091 /* Walk the rhs. */
5092 rss = gfc_walk_expr (expr2);
5093 if (rss == gfc_ss_terminator)
26f77530
MM
5094 {
5095 /* The rhs is scalar. Add a ss for the expression. */
5096 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
42d0058e 5097 rss->info->where = 1;
6de9cd9a
DN
5098 }
5099
5100 /* Associate the SS with the loop. */
5101 gfc_add_ss_to_loop (&loop, lss);
5102 gfc_add_ss_to_loop (&loop, rss);
5103
5104 /* Calculate the bounds of the scalarization. */
5105 gfc_conv_ss_startstride (&loop);
5106
5107 /* Resolve any data dependencies in the statement. */
5108 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
5109
5110 /* Setup the scalarizing loops. */
bdfd2ff0 5111 gfc_conv_loop_setup (&loop, &expr2->where);
6de9cd9a
DN
5112
5113 /* Setup the gfc_se structures. */
5114 gfc_copy_loopinfo_to_se (&lse, &loop);
5115 gfc_copy_loopinfo_to_se (&rse, &loop);
5116
5117 rse.ss = rss;
5118 gfc_mark_ss_chain_used (rss, 1);
5119 if (loop.temp_ss == NULL)
5120 {
5121 lse.ss = lss;
5122 gfc_mark_ss_chain_used (lss, 1);
5123 }
5124 else
5125 {
5126 lse.ss = loop.temp_ss;
5127 gfc_mark_ss_chain_used (lss, 3);
5128 gfc_mark_ss_chain_used (loop.temp_ss, 3);
5129 }
5130
5131 /* Start the scalarized loop body. */
5132 gfc_start_scalarized_body (&loop, &body);
5133
5134 /* Translate the expression. */
5135 gfc_conv_expr (&rse, expr2);
5136 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
3db5d687 5137 gfc_conv_tmp_array_ref (&lse);
6de9cd9a
DN
5138 else
5139 gfc_conv_expr (&lse, expr1);
5140
3c90c9ae 5141 /* Form the mask expression according to the mask. */
6de9cd9a 5142 index = count1;
1d6b7f39 5143 maskexpr = gfc_build_array_ref (mask, index, NULL);
011daa76 5144 if (invert)
bc98ed60
TB
5145 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5146 TREE_TYPE (maskexpr), maskexpr);
6de9cd9a 5147
6de9cd9a 5148 /* Use the scalar assignment as is. */
eb74e79b 5149 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
ed673c00 5150 false, loop.temp_ss == NULL);
a00b8d1a 5151
c2255bc4 5152 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
6de9cd9a
DN
5153
5154 gfc_add_expr_to_block (&body, tmp);
5155
5156 if (lss == gfc_ss_terminator)
5157 {
5158 /* Increment count1. */
bc98ed60
TB
5159 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5160 count1, gfc_index_one_node);
726a989a 5161 gfc_add_modify (&body, count1, tmp);
6de9cd9a
DN
5162
5163 /* Use the scalar assignment as is. */
5164 gfc_add_block_to_block (&block, &body);
5165 }
5166 else
5167 {
6e45f57b
PB
5168 gcc_assert (lse.ss == gfc_ss_terminator
5169 && rse.ss == gfc_ss_terminator);
6de9cd9a
DN
5170
5171 if (loop.temp_ss != NULL)
5172 {
5173 /* Increment count1 before finish the main body of a scalarized
5174 expression. */
bc98ed60
TB
5175 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5176 gfc_array_index_type, count1, gfc_index_one_node);
726a989a 5177 gfc_add_modify (&body, count1, tmp);
6de9cd9a
DN
5178 gfc_trans_scalarized_loop_boundary (&loop, &body);
5179
5180 /* We need to copy the temporary to the actual lhs. */
5181 gfc_init_se (&lse, NULL);
5182 gfc_init_se (&rse, NULL);
5183 gfc_copy_loopinfo_to_se (&lse, &loop);
5184 gfc_copy_loopinfo_to_se (&rse, &loop);
5185
5186 rse.ss = loop.temp_ss;
5187 lse.ss = lss;
5188
5189 gfc_conv_tmp_array_ref (&rse);
6de9cd9a
DN
5190 gfc_conv_expr (&lse, expr1);
5191
6e45f57b
PB
5192 gcc_assert (lse.ss == gfc_ss_terminator
5193 && rse.ss == gfc_ss_terminator);
6de9cd9a
DN
5194
5195 /* Form the mask expression according to the mask tree list. */
5196 index = count2;
1d6b7f39 5197 maskexpr = gfc_build_array_ref (mask, index, NULL);
011daa76 5198 if (invert)
bc98ed60
TB
5199 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
5200 TREE_TYPE (maskexpr), maskexpr);
6de9cd9a 5201
6de9cd9a 5202 /* Use the scalar assignment as is. */
ed673c00 5203 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
c2255bc4
AH
5204 tmp = build3_v (COND_EXPR, maskexpr, tmp,
5205 build_empty_stmt (input_location));
6de9cd9a 5206 gfc_add_expr_to_block (&body, tmp);
7ab92584 5207
6de9cd9a 5208 /* Increment count2. */
bc98ed60
TB
5209 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5210 gfc_array_index_type, count2,
5211 gfc_index_one_node);
726a989a 5212 gfc_add_modify (&body, count2, tmp);
6de9cd9a
DN
5213 }
5214 else
5215 {
5216 /* Increment count1. */
bc98ed60
TB
5217 tmp = fold_build2_loc (input_location, PLUS_EXPR,
5218 gfc_array_index_type, count1,
5219 gfc_index_one_node);
726a989a 5220 gfc_add_modify (&body, count1, tmp);
6de9cd9a
DN
5221 }
5222
5223 /* Generate the copying loops. */
5224 gfc_trans_scalarizing_loops (&loop, &body);
5225
5226 /* Wrap the whole thing up. */
5227 gfc_add_block_to_block (&block, &loop.pre);
5228 gfc_add_block_to_block (&block, &loop.post);
5229 gfc_cleanup_loop (&loop);
5230 }
5231
5232 return gfc_finish_block (&block);
5233}
5234
5235
5236/* Translate the WHERE construct or statement.
aa9c57ec 5237 This function can be called iteratively to translate the nested WHERE
6de9cd9a 5238 construct or statement.
3891cee2 5239 MASK is the control mask. */
6de9cd9a
DN
5240
5241static void
011daa76 5242gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
3891cee2 5243 forall_info * nested_forall_info, stmtblock_t * block)
6de9cd9a 5244{
3891cee2
RS
5245 stmtblock_t inner_size_body;
5246 tree inner_size, size;
5247 gfc_ss *lss, *rss;
5248 tree mask_type;
6de9cd9a
DN
5249 gfc_expr *expr1;
5250 gfc_expr *expr2;
5251 gfc_code *cblock;
5252 gfc_code *cnext;
3891cee2 5253 tree tmp;
ae772c2d 5254 tree cond;
6de9cd9a 5255 tree count1, count2;
011daa76
RS
5256 bool need_cmask;
5257 bool need_pmask;
6de9cd9a 5258 int need_temp;
3891cee2
RS
5259 tree pcmask = NULL_TREE;
5260 tree ppmask = NULL_TREE;
5261 tree cmask = NULL_TREE;
5262 tree pmask = NULL_TREE;
a00b8d1a 5263 gfc_actual_arglist *arg;
6de9cd9a
DN
5264
5265 /* the WHERE statement or the WHERE construct statement. */
5266 cblock = code->block;
3891cee2 5267
3891cee2
RS
5268 /* As the mask array can be very big, prefer compact boolean types. */
5269 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5270
011daa76
RS
5271 /* Determine which temporary masks are needed. */
5272 if (!cblock->block)
90f58ec8 5273 {
011daa76
RS
5274 /* One clause: No ELSEWHEREs. */
5275 need_cmask = (cblock->next != 0);
5276 need_pmask = false;
90f58ec8 5277 }
011daa76 5278 else if (cblock->block->block)
90f58ec8 5279 {
011daa76
RS
5280 /* Three or more clauses: Conditional ELSEWHEREs. */
5281 need_cmask = true;
5282 need_pmask = true;
90f58ec8 5283 }
011daa76
RS
5284 else if (cblock->next)
5285 {
5286 /* Two clauses, the first non-empty. */
5287 need_cmask = true;
5288 need_pmask = (mask != NULL_TREE
5289 && cblock->block->next != 0);
5290 }
5291 else if (!cblock->block->next)
3891cee2 5292 {
011daa76
RS
5293 /* Two clauses, both empty. */
5294 need_cmask = false;
5295 need_pmask = false;
5296 }
5297 /* Two clauses, the first empty, the second non-empty. */
5298 else if (mask)
5299 {
a513927a 5300 need_cmask = (cblock->block->expr1 != 0);
011daa76 5301 need_pmask = true;
3891cee2
RS
5302 }
5303 else
5304 {
011daa76
RS
5305 need_cmask = true;
5306 need_pmask = false;
5307 }
5308
5309 if (need_cmask || need_pmask)
5310 {
5311 /* Calculate the size of temporary needed by the mask-expr. */
5312 gfc_init_block (&inner_size_body);
a513927a 5313 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
011daa76
RS
5314 &inner_size_body, &lss, &rss);
5315
fcba5509
MM
5316 gfc_free_ss_chain (lss);
5317 gfc_free_ss_chain (rss);
5318
011daa76
RS
5319 /* Calculate the total size of temporary needed. */
5320 size = compute_overall_iter_number (nested_forall_info, inner_size,
5321 &inner_size_body, block);
5322
ae772c2d 5323 /* Check whether the size is negative. */
63ee5404 5324 cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, size,
bc98ed60
TB
5325 gfc_index_zero_node);
5326 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
5327 cond, gfc_index_zero_node, size);
ae772c2d
PT
5328 size = gfc_evaluate_now (size, block);
5329
011daa76
RS
5330 /* Allocate temporary for WHERE mask if needed. */
5331 if (need_cmask)
5332 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5333 &pcmask);
5334
5335 /* Allocate temporary for !mask if needed. */
5336 if (need_pmask)
5337 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5338 &ppmask);
3891cee2
RS
5339 }
5340
6de9cd9a
DN
5341 while (cblock)
5342 {
011daa76
RS
5343 /* Each time around this loop, the where clause is conditional
5344 on the value of mask and invert, which are updated at the
5345 bottom of the loop. */
5346
6de9cd9a 5347 /* Has mask-expr. */
a513927a 5348 if (cblock->expr1)
6de9cd9a 5349 {
90f58ec8
RS
5350 /* Ensure that the WHERE mask will be evaluated exactly once.
5351 If there are no statements in this WHERE/ELSEWHERE clause,
5352 then we don't need to update the control mask (cmask).
5353 If this is the last clause of the WHERE construct, then
3891cee2 5354 we don't need to update the pending control mask (pmask). */
011daa76 5355 if (mask)
a513927a 5356 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
011daa76
RS
5357 mask, invert,
5358 cblock->next ? cmask : NULL_TREE,
5359 cblock->block ? pmask : NULL_TREE,
5360 mask_type, block);
5361 else
a513927a 5362 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
011daa76
RS
5363 NULL_TREE, false,
5364 (cblock->next || cblock->block)
5365 ? cmask : NULL_TREE,
5366 NULL_TREE, mask_type, block);
6de9cd9a 5367
011daa76 5368 invert = false;
6de9cd9a 5369 }
90f58ec8 5370 /* It's a final elsewhere-stmt. No mask-expr is present. */
6de9cd9a 5371 else
3891cee2 5372 cmask = mask;
6de9cd9a 5373
011daa76
RS
5374 /* The body of this where clause are controlled by cmask with
5375 sense specified by invert. */
5376
6de9cd9a
DN
5377 /* Get the assignment statement of a WHERE statement, or the first
5378 statement in where-body-construct of a WHERE construct. */
5379 cnext = cblock->next;
5380 while (cnext)
5381 {
5382 switch (cnext->op)
5383 {
5384 /* WHERE assignment statement. */
a00b8d1a
PT
5385 case EXEC_ASSIGN_CALL:
5386
5387 arg = cnext->ext.actual;
5388 expr1 = expr2 = NULL;
5389 for (; arg; arg = arg->next)
5390 {
5391 if (!arg->expr)
5392 continue;
5393 if (expr1 == NULL)
5394 expr1 = arg->expr;
5395 else
5396 expr2 = arg->expr;
5397 }
5398 goto evaluate;
5399
6de9cd9a 5400 case EXEC_ASSIGN:
a513927a 5401 expr1 = cnext->expr1;
6de9cd9a 5402 expr2 = cnext->expr2;
a00b8d1a 5403 evaluate:
6de9cd9a
DN
5404 if (nested_forall_info != NULL)
5405 {
3ded6210 5406 need_temp = gfc_check_dependency (expr1, expr2, 0);
7bd5dad2
LK
5407 if ((need_temp || flag_test_forall_temp)
5408 && cnext->op != EXEC_ASSIGN_CALL)
011daa76
RS
5409 gfc_trans_assign_need_temp (expr1, expr2,
5410 cmask, invert,
6de9cd9a
DN
5411 nested_forall_info, block);
5412 else
5413 {
5414 /* Variables to control maskexpr. */
5415 count1 = gfc_create_var (gfc_array_index_type, "count1");
5416 count2 = gfc_create_var (gfc_array_index_type, "count2");
726a989a
RB
5417 gfc_add_modify (block, count1, gfc_index_zero_node);
5418 gfc_add_modify (block, count2, gfc_index_zero_node);
6de9cd9a 5419
011daa76
RS
5420 tmp = gfc_trans_where_assign (expr1, expr2,
5421 cmask, invert,
a00b8d1a 5422 count1, count2,
eb74e79b 5423 cnext);
8de1f441 5424
6de9cd9a 5425 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
bfcabc6c 5426 tmp, 1);
6de9cd9a
DN
5427 gfc_add_expr_to_block (block, tmp);
5428 }
5429 }
5430 else
5431 {
5432 /* Variables to control maskexpr. */
5433 count1 = gfc_create_var (gfc_array_index_type, "count1");
5434 count2 = gfc_create_var (gfc_array_index_type, "count2");
726a989a
RB
5435 gfc_add_modify (block, count1, gfc_index_zero_node);
5436 gfc_add_modify (block, count2, gfc_index_zero_node);
6de9cd9a 5437
011daa76
RS
5438 tmp = gfc_trans_where_assign (expr1, expr2,
5439 cmask, invert,
a00b8d1a 5440 count1, count2,
eb74e79b 5441 cnext);
6de9cd9a
DN
5442 gfc_add_expr_to_block (block, tmp);
5443
5444 }
5445 break;
5446
5447 /* WHERE or WHERE construct is part of a where-body-construct. */
5448 case EXEC_WHERE:
011daa76
RS
5449 gfc_trans_where_2 (cnext, cmask, invert,
5450 nested_forall_info, block);
3891cee2 5451 break;
6de9cd9a
DN
5452
5453 default:
6e45f57b 5454 gcc_unreachable ();
6de9cd9a
DN
5455 }
5456
5457 /* The next statement within the same where-body-construct. */
5458 cnext = cnext->next;
5459 }
5460 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
5461 cblock = cblock->block;
011daa76
RS
5462 if (mask == NULL_TREE)
5463 {
5464 /* If we're the initial WHERE, we can simply invert the sense
5465 of the current mask to obtain the "mask" for the remaining
5466 ELSEWHEREs. */
5467 invert = true;
5468 mask = cmask;
5469 }
5470 else
5471 {
5472 /* Otherwise, for nested WHERE's we need to use the pending mask. */
5473 invert = false;
5474 mask = pmask;
5475 }
6de9cd9a 5476 }
3891cee2
RS
5477
5478 /* If we allocated a pending mask array, deallocate it now. */
5479 if (ppmask)
5480 {
1529b8d9 5481 tmp = gfc_call_free (ppmask);
3891cee2
RS
5482 gfc_add_expr_to_block (block, tmp);
5483 }
5484
5485 /* If we allocated a current mask array, deallocate it now. */
5486 if (pcmask)
5487 {
1529b8d9 5488 tmp = gfc_call_free (pcmask);
3891cee2
RS
5489 gfc_add_expr_to_block (block, tmp);
5490 }
6de9cd9a
DN
5491}
5492
3ded6210
RS
5493/* Translate a simple WHERE construct or statement without dependencies.
5494 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
5495 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
5496 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
5497
5498static tree
5499gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
5500{
5501 stmtblock_t block, body;
5502 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
5503 tree tmp, cexpr, tstmt, estmt;
5504 gfc_ss *css, *tdss, *tsss;
5505 gfc_se cse, tdse, tsse, edse, esse;
5506 gfc_loopinfo loop;
5507 gfc_ss *edss = 0;
5508 gfc_ss *esss = 0;
57bf3072 5509 bool maybe_workshare = false;
3ded6210 5510
34d01e1d 5511 /* Allow the scalarizer to workshare simple where loops. */
57bf3072
JJ
5512 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
5513 == OMPWS_WORKSHARE_FLAG)
5514 {
5515 maybe_workshare = true;
5516 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
5517 }
34d01e1d 5518
a513927a
SK
5519 cond = cblock->expr1;
5520 tdst = cblock->next->expr1;
3ded6210 5521 tsrc = cblock->next->expr2;
a513927a 5522 edst = eblock ? eblock->next->expr1 : NULL;
3ded6210
RS
5523 esrc = eblock ? eblock->next->expr2 : NULL;
5524
5525 gfc_start_block (&block);
5526 gfc_init_loopinfo (&loop);
5527
5528 /* Handle the condition. */
5529 gfc_init_se (&cse, NULL);
5530 css = gfc_walk_expr (cond);
5531 gfc_add_ss_to_loop (&loop, css);
5532
5533 /* Handle the then-clause. */
5534 gfc_init_se (&tdse, NULL);
5535 gfc_init_se (&tsse, NULL);
5536 tdss = gfc_walk_expr (tdst);
5537 tsss = gfc_walk_expr (tsrc);
5538 if (tsss == gfc_ss_terminator)
5539 {
26f77530 5540 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
42d0058e 5541 tsss->info->where = 1;
3ded6210
RS
5542 }
5543 gfc_add_ss_to_loop (&loop, tdss);
5544 gfc_add_ss_to_loop (&loop, tsss);
5545
5546 if (eblock)
5547 {
5548 /* Handle the else clause. */
5549 gfc_init_se (&edse, NULL);
5550 gfc_init_se (&esse, NULL);
5551 edss = gfc_walk_expr (edst);
5552 esss = gfc_walk_expr (esrc);
5553 if (esss == gfc_ss_terminator)
5554 {
26f77530 5555 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
42d0058e 5556 esss->info->where = 1;
3ded6210
RS
5557 }
5558 gfc_add_ss_to_loop (&loop, edss);
5559 gfc_add_ss_to_loop (&loop, esss);
5560 }
5561
5562 gfc_conv_ss_startstride (&loop);
bdfd2ff0 5563 gfc_conv_loop_setup (&loop, &tdst->where);
3ded6210
RS
5564
5565 gfc_mark_ss_chain_used (css, 1);
5566 gfc_mark_ss_chain_used (tdss, 1);
5567 gfc_mark_ss_chain_used (tsss, 1);
5568 if (eblock)
5569 {
5570 gfc_mark_ss_chain_used (edss, 1);
5571 gfc_mark_ss_chain_used (esss, 1);
5572 }
5573
5574 gfc_start_scalarized_body (&loop, &body);
5575
5576 gfc_copy_loopinfo_to_se (&cse, &loop);
5577 gfc_copy_loopinfo_to_se (&tdse, &loop);
5578 gfc_copy_loopinfo_to_se (&tsse, &loop);
5579 cse.ss = css;
5580 tdse.ss = tdss;
5581 tsse.ss = tsss;
5582 if (eblock)
5583 {
5584 gfc_copy_loopinfo_to_se (&edse, &loop);
5585 gfc_copy_loopinfo_to_se (&esse, &loop);
5586 edse.ss = edss;
5587 esse.ss = esss;
5588 }
5589
5590 gfc_conv_expr (&cse, cond);
5591 gfc_add_block_to_block (&body, &cse.pre);
5592 cexpr = cse.expr;
5593
5594 gfc_conv_expr (&tsse, tsrc);
5595 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
3db5d687 5596 gfc_conv_tmp_array_ref (&tdse);
3ded6210
RS
5597 else
5598 gfc_conv_expr (&tdse, tdst);
5599
5600 if (eblock)
5601 {
5602 gfc_conv_expr (&esse, esrc);
5603 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
3db5d687 5604 gfc_conv_tmp_array_ref (&edse);
3ded6210 5605 else
3db5d687 5606 gfc_conv_expr (&edse, edst);
3ded6210
RS
5607 }
5608
ed673c00
MM
5609 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
5610 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
2b56d6a4 5611 false, true)
c2255bc4 5612 : build_empty_stmt (input_location);
3ded6210
RS
5613 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
5614 gfc_add_expr_to_block (&body, tmp);
5615 gfc_add_block_to_block (&body, &cse.post);
5616
57bf3072
JJ
5617 if (maybe_workshare)
5618 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
3ded6210
RS
5619 gfc_trans_scalarizing_loops (&loop, &body);
5620 gfc_add_block_to_block (&block, &loop.pre);
5621 gfc_add_block_to_block (&block, &loop.post);
5622 gfc_cleanup_loop (&loop);
5623
5624 return gfc_finish_block (&block);
5625}
6de9cd9a
DN
5626
5627/* As the WHERE or WHERE construct statement can be nested, we call
5628 gfc_trans_where_2 to do the translation, and pass the initial
f7b529fa 5629 NULL values for both the control mask and the pending control mask. */
6de9cd9a
DN
5630
5631tree
5632gfc_trans_where (gfc_code * code)
5633{
5634 stmtblock_t block;
3ded6210
RS
5635 gfc_code *cblock;
5636 gfc_code *eblock;
6de9cd9a 5637
3ded6210
RS
5638 cblock = code->block;
5639 if (cblock->next
5640 && cblock->next->op == EXEC_ASSIGN
5641 && !cblock->next->next)
5642 {
5643 eblock = cblock->block;
5644 if (!eblock)
5645 {
5646 /* A simple "WHERE (cond) x = y" statement or block is
5647 dependence free if cond is not dependent upon writing x,
5648 and the source y is unaffected by the destination x. */
a513927a
SK
5649 if (!gfc_check_dependency (cblock->next->expr1,
5650 cblock->expr1, 0)
5651 && !gfc_check_dependency (cblock->next->expr1,
3ded6210
RS
5652 cblock->next->expr2, 0))
5653 return gfc_trans_where_3 (cblock, NULL);
5654 }
a513927a 5655 else if (!eblock->expr1
3ded6210
RS
5656 && !eblock->block
5657 && eblock->next
5658 && eblock->next->op == EXEC_ASSIGN
5659 && !eblock->next->next)
5660 {
5661 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
5662 block is dependence free if cond is not dependent on writes
5663 to x1 and x2, y1 is not dependent on writes to x2, and y2
5664 is not dependent on writes to x1, and both y's are not
ae772c2d
PT
5665 dependent upon their own x's. In addition to this, the
5666 final two dependency checks below exclude all but the same
5667 array reference if the where and elswhere destinations
5668 are the same. In short, this is VERY conservative and this
5669 is needed because the two loops, required by the standard
5670 are coalesced in gfc_trans_where_3. */
524af0d6 5671 if (!gfc_check_dependency (cblock->next->expr1,
a513927a 5672 cblock->expr1, 0)
524af0d6 5673 && !gfc_check_dependency (eblock->next->expr1,
a513927a 5674 cblock->expr1, 0)
524af0d6 5675 && !gfc_check_dependency (cblock->next->expr1,
ae772c2d 5676 eblock->next->expr2, 1)
524af0d6 5677 && !gfc_check_dependency (eblock->next->expr1,
ae772c2d 5678 cblock->next->expr2, 1)
524af0d6 5679 && !gfc_check_dependency (cblock->next->expr1,
ae772c2d 5680 cblock->next->expr2, 1)
524af0d6 5681 && !gfc_check_dependency (eblock->next->expr1,
ae772c2d 5682 eblock->next->expr2, 1)
524af0d6 5683 && !gfc_check_dependency (cblock->next->expr1,
a513927a 5684 eblock->next->expr1, 0)
524af0d6 5685 && !gfc_check_dependency (eblock->next->expr1,
a513927a 5686 cblock->next->expr1, 0))
3ded6210
RS
5687 return gfc_trans_where_3 (cblock, eblock);
5688 }
5689 }
5690
6de9cd9a 5691 gfc_start_block (&block);
6de9cd9a 5692
011daa76 5693 gfc_trans_where_2 (code, NULL, false, NULL, &block);
6de9cd9a 5694
6de9cd9a
DN
5695 return gfc_finish_block (&block);
5696}
5697
5698
5699/* CYCLE a DO loop. The label decl has already been created by
5700 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5701 node at the head of the loop. We must mark the label as used. */
5702
5703tree
5704gfc_trans_cycle (gfc_code * code)
5705{
5706 tree cycle_label;
5707
e5ca9693
DK
5708 cycle_label = code->ext.which_construct->cycle_label;
5709 gcc_assert (cycle_label);
5710
6de9cd9a
DN
5711 TREE_USED (cycle_label) = 1;
5712 return build1_v (GOTO_EXPR, cycle_label);
5713}
5714
5715
e7dc5b4f 5716/* EXIT a DO loop. Similar to CYCLE, but now the label is in
6de9cd9a
DN
5717 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5718 loop. */
5719
5720tree
5721gfc_trans_exit (gfc_code * code)
5722{
5723 tree exit_label;
5724
e5ca9693
DK
5725 exit_label = code->ext.which_construct->exit_label;
5726 gcc_assert (exit_label);
5727
6de9cd9a
DN
5728 TREE_USED (exit_label) = 1;
5729 return build1_v (GOTO_EXPR, exit_label);
5730}
5731
5732
cc03bf7a
AV
5733/* Get the initializer expression for the code and expr of an allocate.
5734 When no initializer is needed return NULL. */
5735
5736static gfc_expr *
5737allocate_get_initializer (gfc_code * code, gfc_expr * expr)
5738{
5739 if (!gfc_bt_struct (expr->ts.type) && expr->ts.type != BT_CLASS)
5740 return NULL;
5741
5742 /* An explicit type was given in allocate ( T:: object). */
5743 if (code->ext.alloc.ts.type == BT_DERIVED
5744 && (code->ext.alloc.ts.u.derived->attr.alloc_comp
5745 || gfc_has_default_initializer (code->ext.alloc.ts.u.derived)))
5746 return gfc_default_initializer (&code->ext.alloc.ts);
5747
5748 if (gfc_bt_struct (expr->ts.type)
5749 && (expr->ts.u.derived->attr.alloc_comp
5750 || gfc_has_default_initializer (expr->ts.u.derived)))
5751 return gfc_default_initializer (&expr->ts);
5752
5753 if (expr->ts.type == BT_CLASS
5754 && (CLASS_DATA (expr)->ts.u.derived->attr.alloc_comp
5755 || gfc_has_default_initializer (CLASS_DATA (expr)->ts.u.derived)))
5756 return gfc_default_initializer (&CLASS_DATA (expr)->ts);
5757
5758 return NULL;
5759}
5760
6de9cd9a
DN
5761/* Translate the ALLOCATE statement. */
5762
5763tree
5764gfc_trans_allocate (gfc_code * code)
5765{
5766 gfc_alloc *al;
cc03bf7a 5767 gfc_expr *expr, *e3rhs = NULL, *init_expr;
34d9d749 5768 gfc_se se, se_sz;
6de9cd9a
DN
5769 tree tmp;
5770 tree parm;
6de9cd9a 5771 tree stat;
8f992d64
DC
5772 tree errmsg;
5773 tree errlen;
5774 tree label_errmsg;
5775 tree label_finish;
60f5ed26 5776 tree memsz;
34d9d749
AV
5777 tree al_vptr, al_len;
5778 /* If an expr3 is present, then store the tree for accessing its
5779 _vptr, and _len components in the variables, respectively. The
5780 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5781 the trees may be the NULL_TREE indicating that this is not
5782 available for expr3's type. */
5783 tree expr3, expr3_vptr, expr3_len, expr3_esize;
1792349b
AV
5784 /* Classify what expr3 stores. */
5785 enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
6de9cd9a 5786 stmtblock_t block;
90cf3ecc 5787 stmtblock_t post;
1312bb90 5788 stmtblock_t final_block;
4daa71b0 5789 tree nelems;
525a5e33
AV
5790 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray;
5791 bool needs_caf_sync, caf_refs_comp;
db7ffcab 5792 gfc_symtree *newsym = NULL;
525a5e33 5793 symbol_attribute caf_attr;
5bab4c96 5794 gfc_actual_arglist *param_list;
6de9cd9a 5795
cf2b3c22 5796 if (!code->ext.alloc.list)
6de9cd9a
DN
5797 return NULL_TREE;
5798
34d9d749
AV
5799 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5800 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
8f992d64 5801 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
1792349b 5802 e3_is = E3_UNSET;
525a5e33 5803 is_coarray = needs_caf_sync = false;
3759634f 5804
90cf3ecc
PT
5805 gfc_init_block (&block);
5806 gfc_init_block (&post);
1312bb90 5807 gfc_init_block (&final_block);
6de9cd9a 5808
8f992d64
DC
5809 /* STAT= (and maybe ERRMSG=) is present. */
5810 if (code->expr1)
6de9cd9a 5811 {
8f992d64 5812 /* STAT=. */
e2cad04b 5813 tree gfc_int4_type_node = gfc_get_int_type (4);
6de9cd9a 5814 stat = gfc_create_var (gfc_int4_type_node, "stat");
6de9cd9a 5815
8f992d64
DC
5816 /* ERRMSG= only makes sense with STAT=. */
5817 if (code->expr2)
5818 {
5819 gfc_init_se (&se, NULL);
5d81ddd0 5820 se.want_pointer = 1;
8f992d64 5821 gfc_conv_expr_lhs (&se, code->expr2);
5d81ddd0
TB
5822 errmsg = se.expr;
5823 errlen = se.string_length;
8f992d64
DC
5824 }
5825 else
5826 {
5827 errmsg = null_pointer_node;
5828 errlen = build_int_cst (gfc_charlen_type_node, 0);
5829 }
5830
5831 /* GOTO destinations. */
5832 label_errmsg = gfc_build_label_decl (NULL_TREE);
5833 label_finish = gfc_build_label_decl (NULL_TREE);
5d81ddd0 5834 TREE_USED (label_finish) = 0;
6de9cd9a 5835 }
6de9cd9a 5836
db7ffcab
AV
5837 /* When an expr3 is present evaluate it only once. The standards prevent a
5838 dependency of expr3 on the objects in the allocate list. An expr3 can
5839 be pre-evaluated in all cases. One just has to make sure, to use the
5840 correct way, i.e., to get the descriptor or to get a reference
5841 expression. */
34d9d749
AV
5842 if (code->expr3)
5843 {
139d4065
AV
5844 bool vtab_needed = false, temp_var_needed = false,
5845 temp_obj_created = false;
ffaf9305
AV
5846
5847 is_coarray = gfc_is_coarray (code->expr3);
34d9d749 5848
1312bb90
PT
5849 if (code->expr3->expr_type == EXPR_FUNCTION && !code->expr3->mold
5850 && (gfc_is_class_array_function (code->expr3)
5851 || gfc_is_alloc_class_scalar_function (code->expr3)))
5852 code->expr3->must_finalize = 1;
5853
34d9d749
AV
5854 /* Figure whether we need the vtab from expr3. */
5855 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
5856 al = al->next)
5857 vtab_needed = (al->expr->ts.type == BT_CLASS);
5858
1792349b 5859 gfc_init_se (&se, NULL);
db7ffcab 5860 /* When expr3 is a variable, i.e., a very simple expression,
34d9d749 5861 then convert it once here. */
db7ffcab
AV
5862 if (code->expr3->expr_type == EXPR_VARIABLE
5863 || code->expr3->expr_type == EXPR_ARRAY
5864 || code->expr3->expr_type == EXPR_CONSTANT)
5865 {
5866 if (!code->expr3->mold
5867 || code->expr3->ts.type == BT_CHARACTER
1792349b
AV
5868 || vtab_needed
5869 || code->ext.alloc.arr_spec_from_expr3)
34d9d749 5870 {
1792349b
AV
5871 /* Convert expr3 to a tree. For all "simple" expression just
5872 get the descriptor or the reference, respectively, depending
5873 on the rank of the expr. */
5874 if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
440f9408
AV
5875 gfc_conv_expr_descriptor (&se, code->expr3);
5876 else
1c645536
AV
5877 {
5878 gfc_conv_expr_reference (&se, code->expr3);
5879
5880 /* gfc_conv_expr_reference wraps POINTER_PLUS_EXPR in a
5881 NOP_EXPR, which prevents gfortran from getting the vptr
5882 from the source=-expression. Remove the NOP_EXPR and go
5883 with the POINTER_PLUS_EXPR in this case. */
5884 if (code->expr3->ts.type == BT_CLASS
5885 && TREE_CODE (se.expr) == NOP_EXPR
781d83d9
AV
5886 && (TREE_CODE (TREE_OPERAND (se.expr, 0))
5887 == POINTER_PLUS_EXPR
5888 || is_coarray))
1c645536
AV
5889 se.expr = TREE_OPERAND (se.expr, 0);
5890 }
1792349b
AV
5891 /* Create a temp variable only for component refs to prevent
5892 having to go through the full deref-chain each time and to
5893 simplfy computation of array properties. */
5894 temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
db7ffcab 5895 }
db7ffcab
AV
5896 }
5897 else
5898 {
1792349b 5899 /* In all other cases evaluate the expr3. */
db7ffcab
AV
5900 symbol_attribute attr;
5901 /* Get the descriptor for all arrays, that are not allocatable or
b8ac4f3b
AV
5902 pointer, because the latter are descriptors already.
5903 The exception are function calls returning a class object:
5904 The descriptor is stored in their results _data component, which
5905 is easier to access, when first a temporary variable for the
5906 result is created and the descriptor retrieved from there. */
db7ffcab 5907 attr = gfc_expr_attr (code->expr3);
b8ac4f3b
AV
5908 if (code->expr3->rank != 0
5909 && ((!attr.allocatable && !attr.pointer)
5910 || (code->expr3->expr_type == EXPR_FUNCTION
574284e9
AV
5911 && (code->expr3->ts.type != BT_CLASS
5912 || (code->expr3->value.function.isym
5913 && code->expr3->value.function.isym
5914 ->transformational)))))
db7ffcab
AV
5915 gfc_conv_expr_descriptor (&se, code->expr3);
5916 else
5917 gfc_conv_expr_reference (&se, code->expr3);
5918 if (code->expr3->ts.type == BT_CLASS)
5919 gfc_conv_class_to_class (&se, code->expr3,
5920 code->expr3->ts,
5921 false, true,
5922 false, false);
139d4065 5923 temp_obj_created = temp_var_needed = !VAR_P (se.expr);
1792349b
AV
5924 }
5925 gfc_add_block_to_block (&block, &se.pre);
1312bb90
PT
5926 if (code->expr3->must_finalize)
5927 gfc_add_block_to_block (&final_block, &se.post);
5928 else
5929 gfc_add_block_to_block (&post, &se.post);
64e56ab0
AV
5930
5931 /* Special case when string in expr3 is zero. */
5932 if (code->expr3->ts.type == BT_CHARACTER
5933 && integer_zerop (se.string_length))
5934 {
5935 gfc_init_se (&se, NULL);
5936 temp_var_needed = false;
f622221a 5937 expr3_len = build_zero_cst (gfc_charlen_type_node);
64e56ab0
AV
5938 e3_is = E3_MOLD;
5939 }
1792349b
AV
5940 /* Prevent aliasing, i.e., se.expr may be already a
5941 variable declaration. */
64e56ab0 5942 else if (se.expr != NULL_TREE && temp_var_needed)
1792349b 5943 {
b8ac4f3b 5944 tree var, desc;
781d83d9 5945 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) || is_coarray ?
1792349b
AV
5946 se.expr
5947 : build_fold_indirect_ref_loc (input_location, se.expr);
b8ac4f3b
AV
5948
5949 /* Get the array descriptor and prepare it to be assigned to the
5950 temporary variable var. For classes the array descriptor is
5951 in the _data component and the object goes into the
5952 GFC_DECL_SAVED_DESCRIPTOR. */
5953 if (code->expr3->ts.type == BT_CLASS
5954 && code->expr3->rank != 0)
5955 {
5956 /* When an array_ref was in expr3, then the descriptor is the
5957 first operand. */
781d83d9 5958 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
b8ac4f3b
AV
5959 {
5960 desc = TREE_OPERAND (tmp, 0);
5961 }
5962 else
5963 {
5964 desc = tmp;
5965 tmp = gfc_class_data_get (tmp);
5966 }
92c5266b
AV
5967 if (code->ext.alloc.arr_spec_from_expr3)
5968 e3_is = E3_DESC;
b8ac4f3b
AV
5969 }
5970 else
781d83d9
AV
5971 desc = !is_coarray ? se.expr
5972 : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
1792349b
AV
5973 /* We need a regular (non-UID) symbol here, therefore give a
5974 prefix. */
5975 var = gfc_create_var (TREE_TYPE (tmp), "source");
781d83d9 5976 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
db7ffcab 5977 {
1792349b 5978 gfc_allocate_lang_decl (var);
b8ac4f3b 5979 GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
1792349b
AV
5980 }
5981 gfc_add_modify_loc (input_location, &block, var, tmp);
26e46e4b 5982
1792349b 5983 expr3 = var;
db7ffcab 5984 if (se.string_length)
1792349b 5985 /* Evaluate it assuming that it also is complicated like expr3. */
db7ffcab 5986 expr3_len = gfc_evaluate_now (se.string_length, &block);
34d9d749 5987 }
1792349b
AV
5988 else
5989 {
5990 expr3 = se.expr;
5991 expr3_len = se.string_length;
5992 }
3cae214f
PT
5993
5994 /* Deallocate any allocatable components in expressions that use a
139d4065
AV
5995 temporary object, i.e. are not a simple alias of to an EXPR_VARIABLE.
5996 E.g. temporaries of a function call need freeing of their components
5997 here. */
3cae214f
PT
5998 if ((code->expr3->ts.type == BT_DERIVED
5999 || code->expr3->ts.type == BT_CLASS)
139d4065 6000 && (code->expr3->expr_type != EXPR_VARIABLE || temp_obj_created)
3cae214f
PT
6001 && code->expr3->ts.u.derived->attr.alloc_comp)
6002 {
6003 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
6004 expr3, code->expr3->rank);
6005 gfc_prepend_expr_to_block (&post, tmp);
6006 }
6007
1792349b 6008 /* Store what the expr3 is to be used for. */
b8ac4f3b
AV
6009 if (e3_is == E3_UNSET)
6010 e3_is = expr3 != NULL_TREE ?
6011 (code->ext.alloc.arr_spec_from_expr3 ?
6012 E3_DESC
6013 : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
6014 : E3_UNSET;
34d9d749
AV
6015
6016 /* Figure how to get the _vtab entry. This also obtains the tree
6017 expression for accessing the _len component, because only
6018 unlimited polymorphic objects, which are a subcategory of class
6019 types, have a _len component. */
6020 if (code->expr3->ts.type == BT_CLASS)
6021 {
6022 gfc_expr *rhs;
b8ac4f3b
AV
6023 tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
6024 build_fold_indirect_ref (expr3): expr3;
db7ffcab
AV
6025 /* Polymorphic SOURCE: VPTR must be determined at run time.
6026 expr3 may be a temporary array declaration, therefore check for
6027 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
b8ac4f3b 6028 if (tmp != NULL_TREE
b8ac4f3b
AV
6029 && (e3_is == E3_DESC
6030 || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
6031 && (VAR_P (tmp) || !code->expr3->ref))
6032 || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
34d9d749 6033 tmp = gfc_class_vptr_get (expr3);
34d9d749
AV
6034 else
6035 {
6036 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6037 gfc_add_vptr_component (rhs);
6038 gfc_init_se (&se, NULL);
6039 se.want_pointer = 1;
6040 gfc_conv_expr (&se, rhs);
6041 tmp = se.expr;
6042 gfc_free_expr (rhs);
6043 }
6044 /* Set the element size. */
6045 expr3_esize = gfc_vptr_size_get (tmp);
6046 if (vtab_needed)
6047 expr3_vptr = tmp;
6048 /* Initialize the ref to the _len component. */
6049 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
6050 {
6051 /* Same like for retrieving the _vptr. */
6052 if (expr3 != NULL_TREE && !code->expr3->ref)
1792349b 6053 expr3_len = gfc_class_len_get (expr3);
34d9d749
AV
6054 else
6055 {
6056 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
6057 gfc_add_len_component (rhs);
6058 gfc_init_se (&se, NULL);
6059 gfc_conv_expr (&se, rhs);
6060 expr3_len = se.expr;
6061 gfc_free_expr (rhs);
6062 }
6063 }
6064 }
6065 else
6066 {
6067 /* When the object to allocate is polymorphic type, then it
6068 needs its vtab set correctly, so deduce the required _vtab
6069 and _len from the source expression. */
6070 if (vtab_needed)
6071 {
6072 /* VPTR is fixed at compile time. */
6073 gfc_symbol *vtab;
90cf3ecc 6074
34d9d749
AV
6075 vtab = gfc_find_vtab (&code->expr3->ts);
6076 gcc_assert (vtab);
6077 expr3_vptr = gfc_get_symbol_decl (vtab);
6078 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
6079 expr3_vptr);
6080 }
6081 /* _len component needs to be set, when ts is a character
6082 array. */
6083 if (expr3_len == NULL_TREE
6084 && code->expr3->ts.type == BT_CHARACTER)
6085 {
6086 if (code->expr3->ts.u.cl
6087 && code->expr3->ts.u.cl->length)
6088 {
6089 gfc_init_se (&se, NULL);
6090 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
6091 gfc_add_block_to_block (&block, &se.pre);
6092 expr3_len = gfc_evaluate_now (se.expr, &block);
6093 }
6094 gcc_assert (expr3_len);
6095 }
6096 /* For character arrays only the kind's size is needed, because
6097 the array mem_size is _len * (elem_size = kind_size).
6098 For all other get the element size in the normal way. */
6099 if (code->expr3->ts.type == BT_CHARACTER)
6100 expr3_esize = TYPE_SIZE_UNIT (
6101 gfc_get_char_type (code->expr3->ts.kind));
6102 else
6103 expr3_esize = TYPE_SIZE_UNIT (
6104 gfc_typenode_for_spec (&code->expr3->ts));
6105 }
6106 gcc_assert (expr3_esize);
6107 expr3_esize = fold_convert (sizetype, expr3_esize);
1792349b 6108 if (e3_is == E3_MOLD)
64e56ab0
AV
6109 /* The expr3 is no longer valid after this point. */
6110 expr3 = NULL_TREE;
34d9d749
AV
6111 }
6112 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6113 {
6114 /* Compute the explicit typespec given only once for all objects
6115 to allocate. */
6116 if (code->ext.alloc.ts.type != BT_CHARACTER)
6117 expr3_esize = TYPE_SIZE_UNIT (
6118 gfc_typenode_for_spec (&code->ext.alloc.ts));
8cd119d8 6119 else if (code->ext.alloc.ts.u.cl->length != NULL)
34d9d749
AV
6120 {
6121 gfc_expr *sz;
34d9d749
AV
6122 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
6123 gfc_init_se (&se_sz, NULL);
6124 gfc_conv_expr (&se_sz, sz);
6125 gfc_free_expr (sz);
6126 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
6127 tmp = TYPE_SIZE_UNIT (tmp);
6128 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
69aaea06 6129 gfc_add_block_to_block (&block, &se_sz.pre);
34d9d749
AV
6130 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
6131 TREE_TYPE (se_sz.expr),
6132 tmp, se_sz.expr);
69aaea06 6133 expr3_esize = gfc_evaluate_now (expr3_esize, &block);
34d9d749 6134 }
8cd119d8
PT
6135 else
6136 expr3_esize = NULL_TREE;
34d9d749
AV
6137 }
6138
574284e9
AV
6139 /* The routine gfc_trans_assignment () already implements all
6140 techniques needed. Unfortunately we may have a temporary
6141 variable for the source= expression here. When that is the
6142 case convert this variable into a temporary gfc_expr of type
6143 EXPR_VARIABLE and used it as rhs for the assignment. The
6144 advantage is, that we get scalarizer support for free,
6145 don't have to take care about scalar to array treatment and
6146 will benefit of every enhancements gfc_trans_assignment ()
6147 gets.
6148 No need to check whether e3_is is E3_UNSET, because that is
6149 done by expr3 != NULL_TREE.
6150 Exclude variables since the following block does not handle
6151 array sections. In any case, there is no harm in sending
6152 variables to gfc_trans_assignment because there is no
6153 evaluation of variables. */
6154 if (code->expr3)
6155 {
6156 if (code->expr3->expr_type != EXPR_VARIABLE
6157 && e3_is != E3_MOLD && expr3 != NULL_TREE
6158 && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
6159 {
6160 /* Build a temporary symtree and symbol. Do not add it to the current
6161 namespace to prevent accidently modifying a colliding
6162 symbol's as. */
6163 newsym = XCNEW (gfc_symtree);
6164 /* The name of the symtree should be unique, because gfc_create_var ()
6165 took care about generating the identifier. */
51f03c6b
JJ
6166 newsym->name
6167 = gfc_get_string ("%s", IDENTIFIER_POINTER (DECL_NAME (expr3)));
574284e9
AV
6168 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
6169 /* The backend_decl is known. It is expr3, which is inserted
6170 here. */
6171 newsym->n.sym->backend_decl = expr3;
6172 e3rhs = gfc_get_expr ();
6173 e3rhs->rank = code->expr3->rank;
6174 e3rhs->symtree = newsym;
6175 /* Mark the symbol referenced or gfc_trans_assignment will bug. */
6176 newsym->n.sym->attr.referenced = 1;
6177 e3rhs->expr_type = EXPR_VARIABLE;
6178 e3rhs->where = code->expr3->where;
6179 /* Set the symbols type, upto it was BT_UNKNOWN. */
6180 if (IS_CLASS_ARRAY (code->expr3)
6181 && code->expr3->expr_type == EXPR_FUNCTION
6182 && code->expr3->value.function.isym
6183 && code->expr3->value.function.isym->transformational)
6184 {
6185 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6186 }
6187 else if (code->expr3->ts.type == BT_CLASS
6188 && !GFC_CLASS_TYPE_P (TREE_TYPE (expr3)))
6189 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
6190 else
6191 e3rhs->ts = code->expr3->ts;
6192 newsym->n.sym->ts = e3rhs->ts;
6193 /* Check whether the expr3 is array valued. */
6194 if (e3rhs->rank)
6195 {
6196 gfc_array_spec *arr;
6197 arr = gfc_get_array_spec ();
6198 arr->rank = e3rhs->rank;
6199 arr->type = AS_DEFERRED;
6200 /* Set the dimension and pointer attribute for arrays
6201 to be on the safe side. */
6202 newsym->n.sym->attr.dimension = 1;
6203 newsym->n.sym->attr.pointer = 1;
6204 newsym->n.sym->as = arr;
6205 if (IS_CLASS_ARRAY (code->expr3)
6206 && code->expr3->expr_type == EXPR_FUNCTION
6207 && code->expr3->value.function.isym
6208 && code->expr3->value.function.isym->transformational)
6209 {
6210 gfc_array_spec *tarr;
6211 tarr = gfc_get_array_spec ();
6212 *tarr = *arr;
6213 e3rhs->ts.u.derived->as = tarr;
6214 }
6215 gfc_add_full_array_ref (e3rhs, arr);
6216 }
6217 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
6218 newsym->n.sym->attr.pointer = 1;
6219 /* The string length is known, too. Set it for char arrays. */
6220 if (e3rhs->ts.type == BT_CHARACTER)
6221 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
6222 gfc_commit_symbol (newsym->n.sym);
6223 }
6224 else
6225 e3rhs = gfc_copy_expr (code->expr3);
6226 }
6227
34d9d749 6228 /* Loop over all objects to allocate. */
cf2b3c22 6229 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6de9cd9a 6230 {
f43085aa 6231 expr = gfc_copy_expr (al->expr);
34d9d749
AV
6232 /* UNLIMITED_POLY () needs the _data component to be set, when
6233 expr is a unlimited polymorphic object. But the _data component
6234 has not been set yet, so check the derived type's attr for the
6235 unlimited polymorphic flag to be safe. */
6236 upoly_expr = UNLIMITED_POLY (expr)
6237 || (expr->ts.type == BT_DERIVED
6238 && expr->ts.u.derived->attr.unlimited_polymorphic);
6239 gfc_init_se (&se, NULL);
f43085aa 6240
34d9d749
AV
6241 /* For class types prepare the expressions to ref the _vptr
6242 and the _len component. The latter for unlimited polymorphic
6243 types only. */
f43085aa 6244 if (expr->ts.type == BT_CLASS)
34d9d749
AV
6245 {
6246 gfc_expr *expr_ref_vptr, *expr_ref_len;
6247 gfc_add_data_component (expr);
6248 /* Prep the vptr handle. */
6249 expr_ref_vptr = gfc_copy_expr (al->expr);
6250 gfc_add_vptr_component (expr_ref_vptr);
6251 se.want_pointer = 1;
6252 gfc_conv_expr (&se, expr_ref_vptr);
6253 al_vptr = se.expr;
6254 se.want_pointer = 0;
6255 gfc_free_expr (expr_ref_vptr);
6256 /* Allocated unlimited polymorphic objects always have a _len
6257 component. */
6258 if (upoly_expr)
6259 {
6260 expr_ref_len = gfc_copy_expr (al->expr);
6261 gfc_add_len_component (expr_ref_len);
6262 gfc_conv_expr (&se, expr_ref_len);
6263 al_len = se.expr;
6264 gfc_free_expr (expr_ref_len);
6265 }
6266 else
6267 /* In a loop ensure that all loop variable dependent variables
6268 are initialized at the same spot in all execution paths. */
6269 al_len = NULL_TREE;
6270 }
6271 else
6272 al_vptr = al_len = NULL_TREE;
6de9cd9a
DN
6273
6274 se.want_pointer = 1;
6275 se.descriptor_only = 1;
78ab5260 6276
6de9cd9a 6277 gfc_conv_expr (&se, expr);
34d9d749
AV
6278 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6279 /* se.string_length now stores the .string_length variable of expr
6280 needed to allocate character(len=:) arrays. */
6281 al_len = se.string_length;
6282
6283 al_len_needs_set = al_len != NULL_TREE;
6284 /* When allocating an array one can not use much of the
6285 pre-evaluated expr3 expressions, because for most of them the
6286 scalarizer is needed which is not available in the pre-evaluation
6287 step. Therefore gfc_array_allocate () is responsible (and able)
6288 to handle the complete array allocation. Only the element size
6289 needs to be provided, which is done most of the time by the
6290 pre-evaluation step. */
4daa71b0 6291 nelems = NULL_TREE;
764d5c7b
AV
6292 if (expr3_len && (code->expr3->ts.type == BT_CHARACTER
6293 || code->expr3->ts.type == BT_CLASS))
6294 {
6295 /* When al is an array, then the element size for each element
6296 in the array is needed, which is the product of the len and
6297 esize for char arrays. For unlimited polymorphics len can be
6298 zero, therefore take the maximum of len and one. */
6299 tmp = fold_build2_loc (input_location, MAX_EXPR,
6300 TREE_TYPE (expr3_len),
6301 expr3_len, fold_convert (TREE_TYPE (expr3_len),
6302 integer_one_node));
6303 tmp = fold_build2_loc (input_location, MULT_EXPR,
6304 TREE_TYPE (expr3_esize), expr3_esize,
6305 fold_convert (TREE_TYPE (expr3_esize), tmp));
6306 }
34d9d749
AV
6307 else
6308 tmp = expr3_esize;
6309 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
1792349b
AV
6310 label_finish, tmp, &nelems,
6311 e3rhs ? e3rhs : code->expr3,
6312 e3_is == E3_DESC ? expr3 : NULL_TREE,
6313 code->expr3 != NULL && e3_is == E3_DESC
6314 && code->expr3->expr_type == EXPR_ARRAY))
6de9cd9a 6315 {
34d9d749
AV
6316 /* A scalar or derived type. First compute the size to
6317 allocate.
cf2b3c22 6318
34d9d749
AV
6319 expr3_len is set when expr3 is an unlimited polymorphic
6320 object or a deferred length string. */
6321 if (expr3_len != NULL_TREE)
8d51f26f 6322 {
34d9d749
AV
6323 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
6324 tmp = fold_build2_loc (input_location, MULT_EXPR,
6325 TREE_TYPE (expr3_esize),
6326 expr3_esize, tmp);
6327 if (code->expr3->ts.type != BT_CLASS)
6328 /* expr3 is a deferred length string, i.e., we are
6329 done. */
6330 memsz = tmp;
8d51f26f 6331 else
5b384b3d 6332 {
34d9d749
AV
6333 /* For unlimited polymorphic enties build
6334 (len > 0) ? element_size * len : element_size
6335 to compute the number of bytes to allocate.
6336 This allows the allocation of unlimited polymorphic
6337 objects from an expr3 that is also unlimited
6338 polymorphic and stores a _len dependent object,
6339 e.g., a string. */
6340 memsz = fold_build2_loc (input_location, GT_EXPR,
63ee5404 6341 logical_type_node, expr3_len,
f622221a
JB
6342 build_zero_cst
6343 (TREE_TYPE (expr3_len)));
34d9d749
AV
6344 memsz = fold_build3_loc (input_location, COND_EXPR,
6345 TREE_TYPE (expr3_esize),
6346 memsz, tmp, expr3_esize);
5b384b3d 6347 }
8d51f26f 6348 }
34d9d749
AV
6349 else if (expr3_esize != NULL_TREE)
6350 /* Any other object in expr3 just needs element size in
6351 bytes. */
6352 memsz = expr3_esize;
6353 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6354 || (upoly_expr
6355 && code->ext.alloc.ts.type == BT_CHARACTER))
2573aab9 6356 {
34d9d749
AV
6357 /* Allocating deferred length char arrays need the length
6358 to allocate in the alloc_type_spec. But also unlimited
6359 polymorphic objects may be allocated as char arrays.
6360 Both are handled here. */
2573aab9
TB
6361 gfc_init_se (&se_sz, NULL);
6362 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6363 gfc_add_block_to_block (&se.pre, &se_sz.pre);
6364 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
6365 gfc_add_block_to_block (&se.pre, &se_sz.post);
34d9d749
AV
6366 expr3_len = se_sz.expr;
6367 tmp_expr3_len_flag = true;
6368 tmp = TYPE_SIZE_UNIT (
6369 gfc_get_char_type (code->ext.alloc.ts.kind));
2573aab9 6370 memsz = fold_build2_loc (input_location, MULT_EXPR,
34d9d749
AV
6371 TREE_TYPE (tmp),
6372 fold_convert (TREE_TYPE (tmp),
6373 expr3_len),
6374 tmp);
2573aab9 6375 }
34d9d749 6376 else if (expr->ts.type == BT_CHARACTER)
8d51f26f 6377 {
34d9d749
AV
6378 /* Compute the number of bytes needed to allocate a fixed
6379 length char array. */
6380 gcc_assert (se.string_length != NULL_TREE);
6381 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
8d51f26f
PT
6382 memsz = fold_build2_loc (input_location, MULT_EXPR,
6383 TREE_TYPE (tmp), tmp,
34d9d749
AV
6384 fold_convert (TREE_TYPE (tmp),
6385 se.string_length));
8d51f26f 6386 }
34d9d749
AV
6387 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6388 /* Handle all types, where the alloc_type_spec is set. */
6389 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
6390 else
6391 /* Handle size computation of the type declared to alloc. */
6f3d1a5e 6392 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
90cf3ecc 6393
525a5e33
AV
6394 /* Store the caf-attributes for latter use. */
6395 if (flag_coarray == GFC_FCOARRAY_LIB
6396 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6397 .codimension)
3c9f5092
AV
6398 {
6399 /* Scalar allocatable components in coarray'ed derived types make
6400 it here and are treated now. */
6401 tree caf_decl, token;
6402 gfc_se caf_se;
6403
ffaf9305 6404 is_coarray = true;
525a5e33
AV
6405 /* Set flag, to add synchronize after the allocate. */
6406 needs_caf_sync = needs_caf_sync
6407 || caf_attr.coarray_comp || !caf_refs_comp;
ffaf9305 6408
3c9f5092
AV
6409 gfc_init_se (&caf_se, NULL);
6410
6411 caf_decl = gfc_get_tree_for_caf_expr (expr);
6412 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl,
6413 NULL_TREE, NULL);
6414 gfc_add_block_to_block (&se.pre, &caf_se.pre);
6415 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6416 gfc_build_addr_expr (NULL_TREE, token),
6417 NULL_TREE, NULL_TREE, NULL_TREE,
6418 label_finish, expr, 1);
6419 }
5b130807 6420 /* Allocate - for non-pointers with re-alloc checking. */
3c9f5092
AV
6421 else if (gfc_expr_attr (expr).allocatable)
6422 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6423 NULL_TREE, stat, errmsg, errlen,
6424 label_finish, expr, 0);
90cf3ecc 6425 else
4f13e17f 6426 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
6de9cd9a 6427 }
34d9d749
AV
6428 else
6429 {
ffaf9305
AV
6430 /* Allocating coarrays needs a sync after the allocate executed.
6431 Set the flag to add the sync after all objects are allocated. */
525a5e33
AV
6432 if (flag_coarray == GFC_FCOARRAY_LIB
6433 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6434 .codimension)
6435 {
6436 is_coarray = true;
6437 needs_caf_sync = needs_caf_sync
6438 || caf_attr.coarray_comp || !caf_refs_comp;
6439 }
ffaf9305 6440
34d9d749
AV
6441 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6442 && expr3_len != NULL_TREE)
6443 {
6444 /* Arrays need to have a _len set before the array
6445 descriptor is filled. */
6446 gfc_add_modify (&block, al_len,
6447 fold_convert (TREE_TYPE (al_len), expr3_len));
6448 /* Prevent setting the length twice. */
6449 al_len_needs_set = false;
6450 }
afbc5ae8 6451 else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
323c5722 6452 && code->ext.alloc.ts.u.cl->length)
afbc5ae8
PT
6453 {
6454 /* Cover the cases where a string length is explicitly
6455 specified by a type spec for deferred length character
6456 arrays or unlimited polymorphic objects without a
6457 source= or mold= expression. */
6458 gfc_init_se (&se_sz, NULL);
6459 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
69aaea06 6460 gfc_add_block_to_block (&block, &se_sz.pre);
afbc5ae8
PT
6461 gfc_add_modify (&block, al_len,
6462 fold_convert (TREE_TYPE (al_len),
6463 se_sz.expr));
6464 al_len_needs_set = false;
6465 }
34d9d749 6466 }
6de9cd9a 6467
90cf3ecc 6468 gfc_add_block_to_block (&block, &se.pre);
cf2b3c22 6469
8f992d64
DC
6470 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
6471 if (code->expr1)
6472 {
5d81ddd0 6473 tmp = build1_v (GOTO_EXPR, label_errmsg);
8f992d64 6474 parm = fold_build2_loc (input_location, NE_EXPR,
63ee5404 6475 logical_type_node, stat,
8f992d64
DC
6476 build_int_cst (TREE_TYPE (stat), 0));
6477 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
ed9c79e1
JJ
6478 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
6479 tmp, build_empty_stmt (input_location));
8f992d64
DC
6480 gfc_add_expr_to_block (&block, tmp);
6481 }
8b704316 6482
574284e9
AV
6483 /* Set the vptr only when no source= is set. When source= is set, then
6484 the trans_assignment below will set the vptr. */
6485 if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold))
c49ea23d 6486 {
34d9d749
AV
6487 if (expr3_vptr != NULL_TREE)
6488 /* The vtab is already known, so just assign it. */
6489 gfc_add_modify (&block, al_vptr,
6490 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
c49ea23d
PT
6491 else
6492 {
6493 /* VPTR is fixed at compile time. */
6494 gfc_symbol *vtab;
6495 gfc_typespec *ts;
34d9d749 6496
c49ea23d 6497 if (code->expr3)
34d9d749
AV
6498 /* Although expr3 is pre-evaluated above, it may happen,
6499 that for arrays or in mold= cases the pre-evaluation
6500 was not successful. In these rare cases take the vtab
6501 from the typespec of expr3 here. */
c49ea23d 6502 ts = &code->expr3->ts;
34d9d749
AV
6503 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
6504 /* The alloc_type_spec gives the type to allocate or the
6505 al is unlimited polymorphic, which enforces the use of
6506 an alloc_type_spec that is not necessarily a BT_DERIVED. */
c49ea23d 6507 ts = &code->ext.alloc.ts;
c49ea23d 6508 else
34d9d749
AV
6509 /* Prepare for setting the vtab as declared. */
6510 ts = &expr->ts;
6511
6512 vtab = gfc_find_vtab (ts);
6513 gcc_assert (vtab);
6514 tmp = gfc_build_addr_expr (NULL_TREE,
6515 gfc_get_symbol_decl (vtab));
6516 gfc_add_modify (&block, al_vptr,
6517 fold_convert (TREE_TYPE (al_vptr), tmp));
c49ea23d 6518 }
c49ea23d
PT
6519 }
6520
34d9d749
AV
6521 /* Add assignment for string length. */
6522 if (al_len != NULL_TREE && al_len_needs_set)
6523 {
6524 if (expr3_len != NULL_TREE)
6525 {
6526 gfc_add_modify (&block, al_len,
6527 fold_convert (TREE_TYPE (al_len),
6528 expr3_len));
6529 /* When tmp_expr3_len_flag is set, then expr3_len is
6530 abused to carry the length information from the
6531 alloc_type. Clear it to prevent setting incorrect len
6532 information in future loop iterations. */
6533 if (tmp_expr3_len_flag)
6534 /* No need to reset tmp_expr3_len_flag, because the
6535 presence of an expr3 can not change within in the
6536 loop. */
6537 expr3_len = NULL_TREE;
6538 }
6539 else if (code->ext.alloc.ts.type == BT_CHARACTER
323c5722 6540 && code->ext.alloc.ts.u.cl->length)
34d9d749
AV
6541 {
6542 /* Cover the cases where a string length is explicitly
6543 specified by a type spec for deferred length character
6544 arrays or unlimited polymorphic objects without a
6545 source= or mold= expression. */
69aaea06
AV
6546 if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
6547 {
6548 gfc_init_se (&se_sz, NULL);
6549 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6550 gfc_add_block_to_block (&block, &se_sz.pre);
6551 gfc_add_modify (&block, al_len,
6552 fold_convert (TREE_TYPE (al_len),
6553 se_sz.expr));
6554 }
6555 else
6556 gfc_add_modify (&block, al_len,
6557 fold_convert (TREE_TYPE (al_len),
6558 expr3_esize));
34d9d749
AV
6559 }
6560 else
6561 /* No length information needed, because type to allocate
6562 has no length. Set _len to 0. */
6563 gfc_add_modify (&block, al_len,
6564 fold_convert (TREE_TYPE (al_len),
6565 integer_zero_node));
6566 }
cc03bf7a
AV
6567
6568 init_expr = NULL;
64e56ab0 6569 if (code->expr3 && !code->expr3->mold && e3_is != E3_MOLD)
cf2b3c22 6570 {
db7ffcab 6571 /* Initialization via SOURCE block (or static default initializer).
574284e9
AV
6572 Switch off automatic reallocation since we have just done the
6573 ALLOCATE. */
6574 int realloc_lhs = flag_realloc_lhs;
6575 gfc_expr *init_expr = gfc_expr_to_initialize (expr);
6576 gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
6577 flag_realloc_lhs = 0;
6578 tmp = gfc_trans_assignment (init_expr, rhs, false, false, true,
6579 false);
6580 flag_realloc_lhs = realloc_lhs;
6581 /* Free the expression allocated for init_expr. */
6582 gfc_free_expr (init_expr);
6583 if (rhs != e3rhs)
6584 gfc_free_expr (rhs);
f43085aa
JW
6585 gfc_add_expr_to_block (&block, tmp);
6586 }
5bab4c96
PT
6587 /* Set KIND and LEN PDT components and allocate those that are
6588 parameterized. */
6589 else if (expr->ts.type == BT_DERIVED
6590 && expr->ts.u.derived->attr.pdt_type)
6591 {
6592 if (code->expr3 && code->expr3->param_list)
6593 param_list = code->expr3->param_list;
6594 else if (expr->param_list)
6595 param_list = expr->param_list;
6596 else
6597 param_list = expr->symtree->n.sym->param_list;
6598 tmp = gfc_allocate_pdt_comp (expr->ts.u.derived, se.expr,
6599 expr->rank, param_list);
6600 gfc_add_expr_to_block (&block, tmp);
6601 }
6602 /* Ditto for CLASS expressions. */
6603 else if (expr->ts.type == BT_CLASS
6604 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type)
6605 {
6606 if (code->expr3 && code->expr3->param_list)
6607 param_list = code->expr3->param_list;
6608 else if (expr->param_list)
6609 param_list = expr->param_list;
6610 else
6611 param_list = expr->symtree->n.sym->param_list;
6612 tmp = gfc_allocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
6613 se.expr, expr->rank, param_list);
6614 gfc_add_expr_to_block (&block, tmp);
6615 }
574284e9
AV
6616 else if (code->expr3 && code->expr3->mold
6617 && code->expr3->ts.type == BT_CLASS)
50f30801 6618 {
574284e9
AV
6619 /* Use class_init_assign to initialize expr. */
6620 gfc_code *ini;
6621 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6622 ini->expr1 = gfc_find_and_cut_at_last_class_ref (expr);
6623 tmp = gfc_trans_class_init_assign (ini);
6624 gfc_free_statements (ini);
b6ff8128 6625 gfc_add_expr_to_block (&block, tmp);
50f30801 6626 }
cc03bf7a
AV
6627 else if ((init_expr = allocate_get_initializer (code, expr)))
6628 {
6629 /* Use class_init_assign to initialize expr. */
6630 gfc_code *ini;
6631 int realloc_lhs = flag_realloc_lhs;
6632 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6633 ini->expr1 = gfc_expr_to_initialize (expr);
6634 ini->expr2 = init_expr;
6635 flag_realloc_lhs = 0;
6636 tmp= gfc_trans_init_assign (ini);
6637 flag_realloc_lhs = realloc_lhs;
6638 gfc_free_statements (ini);
6639 /* Init_expr is freeed by above free_statements, just need to null
6640 it here. */
6641 init_expr = NULL;
6642 gfc_add_expr_to_block (&block, tmp);
6643 }
f43085aa 6644
de91486c
AV
6645 /* Nullify all pointers in derived type coarrays. This registers a
6646 token for them which allows their allocation. */
6647 if (is_coarray)
6648 {
6649 gfc_symbol *type = NULL;
6650 symbol_attribute caf_attr;
6651 int rank = 0;
6652 if (code->ext.alloc.ts.type == BT_DERIVED
6653 && code->ext.alloc.ts.u.derived->attr.pointer_comp)
6654 {
6655 type = code->ext.alloc.ts.u.derived;
6656 rank = type->attr.dimension ? type->as->rank : 0;
6657 gfc_clear_attr (&caf_attr);
6658 }
6659 else if (expr->ts.type == BT_DERIVED
6660 && expr->ts.u.derived->attr.pointer_comp)
6661 {
6662 type = expr->ts.u.derived;
6663 rank = expr->rank;
6664 caf_attr = gfc_caf_attr (expr, true);
6665 }
6666
6667 /* Initialize the tokens of pointer components in derived type
6668 coarrays. */
6669 if (type)
6670 {
6671 tmp = (caf_attr.codimension && !caf_attr.dimension)
6672 ? gfc_conv_descriptor_data_get (se.expr) : se.expr;
6673 tmp = gfc_nullify_alloc_comp (type, tmp, rank,
6674 GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
6675 gfc_add_expr_to_block (&block, tmp);
6676 }
6677 }
6678
574284e9 6679 gfc_free_expr (expr);
34d9d749 6680 } // for-loop
6de9cd9a 6681
db7ffcab
AV
6682 if (e3rhs)
6683 {
6684 if (newsym)
6685 {
6686 gfc_free_symbol (newsym->n.sym);
6687 XDELETE (newsym);
6688 }
6689 gfc_free_expr (e3rhs);
6690 }
5d81ddd0 6691 /* STAT. */
a513927a 6692 if (code->expr1)
6de9cd9a 6693 {
8f992d64 6694 tmp = build1_v (LABEL_EXPR, label_errmsg);
6de9cd9a 6695 gfc_add_expr_to_block (&block, tmp);
6de9cd9a
DN
6696 }
6697
5d81ddd0
TB
6698 /* ERRMSG - only useful if STAT is present. */
6699 if (code->expr1 && code->expr2)
3759634f 6700 {
3759634f 6701 const char *msg = "Attempt to allocate an allocated object";
5d81ddd0
TB
6702 tree slen, dlen, errmsg_str;
6703 stmtblock_t errmsg_block;
3759634f 6704
5d81ddd0 6705 gfc_init_block (&errmsg_block);
3759634f 6706
5d81ddd0
TB
6707 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6708 gfc_add_modify (&errmsg_block, errmsg_str,
3759634f
SK
6709 gfc_build_addr_expr (pchar_type_node,
6710 gfc_build_localized_cstring_const (msg)));
6711
f622221a 6712 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
3759634f 6713 dlen = gfc_get_expr_charlen (code->expr2);
34d9d749
AV
6714 slen = fold_build2_loc (input_location, MIN_EXPR,
6715 TREE_TYPE (slen), dlen, slen);
3759634f 6716
34d9d749
AV
6717 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
6718 code->expr2->ts.kind,
6719 slen, errmsg_str,
6720 gfc_default_character_kind);
5d81ddd0 6721 dlen = gfc_finish_block (&errmsg_block);
3759634f 6722
63ee5404 6723 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
34d9d749 6724 stat, build_int_cst (TREE_TYPE (stat), 0));
3759634f 6725
34d9d749
AV
6726 tmp = build3_v (COND_EXPR, tmp,
6727 dlen, build_empty_stmt (input_location));
3759634f
SK
6728
6729 gfc_add_expr_to_block (&block, tmp);
6730 }
6731
8f992d64
DC
6732 /* STAT block. */
6733 if (code->expr1)
6734 {
5d81ddd0
TB
6735 if (TREE_USED (label_finish))
6736 {
6737 tmp = build1_v (LABEL_EXPR, label_finish);
6738 gfc_add_expr_to_block (&block, tmp);
6739 }
6740
8f992d64
DC
6741 gfc_init_se (&se, NULL);
6742 gfc_conv_expr_lhs (&se, code->expr1);
6743 tmp = convert (TREE_TYPE (se.expr), stat);
6744 gfc_add_modify (&block, se.expr, tmp);
6745 }
6746
525a5e33 6747 if (needs_caf_sync)
ffaf9305
AV
6748 {
6749 /* Add a sync all after the allocation has been executed. */
6750 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
6751 3, null_pointer_node, null_pointer_node,
6752 integer_zero_node);
6753 gfc_add_expr_to_block (&post, tmp);
6754 }
6755
90cf3ecc
PT
6756 gfc_add_block_to_block (&block, &se.post);
6757 gfc_add_block_to_block (&block, &post);
1312bb90
PT
6758 if (code->expr3 && code->expr3->must_finalize)
6759 gfc_add_block_to_block (&block, &final_block);
90cf3ecc 6760
6de9cd9a
DN
6761 return gfc_finish_block (&block);
6762}
6763
6764
3759634f
SK
6765/* Translate a DEALLOCATE statement. */
6766
6de9cd9a 6767tree
3759634f 6768gfc_trans_deallocate (gfc_code *code)
6de9cd9a
DN
6769{
6770 gfc_se se;
6771 gfc_alloc *al;
5d81ddd0
TB
6772 tree apstat, pstat, stat, errmsg, errlen, tmp;
6773 tree label_finish, label_errmsg;
6de9cd9a
DN
6774 stmtblock_t block;
6775
5d81ddd0
TB
6776 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
6777 label_finish = label_errmsg = NULL_TREE;
3759634f 6778
6de9cd9a
DN
6779 gfc_start_block (&block);
6780
3759634f
SK
6781 /* Count the number of failed deallocations. If deallocate() was
6782 called with STAT= , then set STAT to the count. If deallocate
6783 was called with ERRMSG, then set ERRMG to a string. */
5d81ddd0 6784 if (code->expr1)
364667a1
SK
6785 {
6786 tree gfc_int4_type_node = gfc_get_int_type (4);
6787
364667a1 6788 stat = gfc_create_var (gfc_int4_type_node, "stat");
628c189e 6789 pstat = gfc_build_addr_expr (NULL_TREE, stat);
364667a1 6790
5d81ddd0
TB
6791 /* GOTO destinations. */
6792 label_errmsg = gfc_build_label_decl (NULL_TREE);
6793 label_finish = gfc_build_label_decl (NULL_TREE);
6794 TREE_USED (label_finish) = 0;
6795 }
364667a1 6796
5d81ddd0
TB
6797 /* Set ERRMSG - only needed if STAT is available. */
6798 if (code->expr1 && code->expr2)
6799 {
6800 gfc_init_se (&se, NULL);
6801 se.want_pointer = 1;
6802 gfc_conv_expr_lhs (&se, code->expr2);
6803 errmsg = se.expr;
6804 errlen = se.string_length;
364667a1 6805 }
364667a1 6806
cf2b3c22 6807 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6de9cd9a 6808 {
0d87fa8c 6809 gfc_expr *expr = gfc_copy_expr (al->expr);
ba85c8c3
AV
6810 bool is_coarray = false, is_coarray_array = false;
6811 int caf_mode = 0;
6812
6e45f57b 6813 gcc_assert (expr->expr_type == EXPR_VARIABLE);
6de9cd9a 6814
0d87fa8c
JW
6815 if (expr->ts.type == BT_CLASS)
6816 gfc_add_data_component (expr);
6817
6de9cd9a
DN
6818 gfc_init_se (&se, NULL);
6819 gfc_start_block (&se.pre);
6820
6821 se.want_pointer = 1;
6822 se.descriptor_only = 1;
6823 gfc_conv_expr (&se, expr);
6824
5bab4c96
PT
6825 /* Deallocate PDT components that are parameterized. */
6826 tmp = NULL;
6827 if (expr->ts.type == BT_DERIVED
6828 && expr->ts.u.derived->attr.pdt_type
6829 && expr->symtree->n.sym->param_list)
6830 tmp = gfc_deallocate_pdt_comp (expr->ts.u.derived, se.expr, expr->rank);
6831 else if (expr->ts.type == BT_CLASS
6832 && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type
6833 && expr->symtree->n.sym->param_list)
6834 tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
6835 se.expr, expr->rank);
6836
6837 if (tmp)
6838 gfc_add_expr_to_block (&block, tmp);
6839
de91486c
AV
6840 if (flag_coarray == GFC_FCOARRAY_LIB
6841 || flag_coarray == GFC_FCOARRAY_SINGLE)
ba85c8c3
AV
6842 {
6843 bool comp_ref;
6844 symbol_attribute caf_attr = gfc_caf_attr (expr, false, &comp_ref);
6845 if (caf_attr.codimension)
6846 {
6847 is_coarray = true;
6848 is_coarray_array = caf_attr.dimension || !comp_ref
6849 || caf_attr.coarray_comp;
6850
de91486c
AV
6851 if (flag_coarray == GFC_FCOARRAY_LIB)
6852 /* When the expression to deallocate is referencing a
6853 component, then only deallocate it, but do not
6854 deregister. */
6855 caf_mode = GFC_STRUCTURE_CAF_MODE_IN_COARRAY
6856 | (comp_ref && !caf_attr.coarray_comp
6857 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0);
ba85c8c3
AV
6858 }
6859 }
ba85c8c3
AV
6860
6861 if (expr->rank || is_coarray_array)
2c807128 6862 {
ec6a7096
PT
6863 gfc_ref *ref;
6864
ba85c8c3
AV
6865 if (gfc_bt_struct (expr->ts.type)
6866 && expr->ts.u.derived->attr.alloc_comp
ef292537 6867 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
5046aff5 6868 {
2c807128 6869 gfc_ref *last = NULL;
ec6a7096 6870
2c807128
JW
6871 for (ref = expr->ref; ref; ref = ref->next)
6872 if (ref->type == REF_COMPONENT)
6873 last = ref;
6874
6875 /* Do not deallocate the components of a derived type
34d9d749 6876 ultimate pointer component. */
2c807128
JW
6877 if (!(last && last->u.c.component->attr.pointer)
6878 && !(!last && expr->symtree->n.sym->attr.pointer))
6879 {
ba85c8c3 6880 if (is_coarray && expr->rank == 0
eb401400
AV
6881 && (!last || !last->u.c.component->attr.dimension)
6882 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
ba85c8c3
AV
6883 {
6884 /* Add the ref to the data member only, when this is not
6885 a regular array or deallocate_alloc_comp will try to
6886 add another one. */
6887 tmp = gfc_conv_descriptor_data_get (se.expr);
6888 }
6889 else
6890 tmp = se.expr;
6891 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp,
6892 expr->rank, caf_mode);
2c807128
JW
6893 gfc_add_expr_to_block (&se.pre, tmp);
6894 }
5046aff5 6895 }
ec6a7096
PT
6896
6897 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6898 {
ba85c8c3
AV
6899 gfc_coarray_deregtype caf_dtype;
6900
6901 if (is_coarray)
6902 caf_dtype = gfc_caf_is_dealloc_only (caf_mode)
6903 ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
6904 : GFC_CAF_COARRAY_DEREGISTER;
6905 else
6906 caf_dtype = GFC_CAF_COARRAY_NOCOARRAY;
39da5866
AV
6907 tmp = gfc_deallocate_with_status (se.expr, pstat, errmsg, errlen,
6908 label_finish, false, expr,
6909 caf_dtype);
ec6a7096
PT
6910 gfc_add_expr_to_block (&se.pre, tmp);
6911 }
6912 else if (TREE_CODE (se.expr) == COMPONENT_REF
6913 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
6914 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
6915 == RECORD_TYPE)
6916 {
6917 /* class.c(finalize_component) generates these, when a
6918 finalizable entity has a non-allocatable derived type array
6919 component, which has allocatable components. Obtain the
6920 derived type of the array and deallocate the allocatable
6921 components. */
6922 for (ref = expr->ref; ref; ref = ref->next)
6923 {
6924 if (ref->u.c.component->attr.dimension
6925 && ref->u.c.component->ts.type == BT_DERIVED)
6926 break;
6927 }
6928
6929 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
6930 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
6931 NULL))
6932 {
6933 tmp = gfc_deallocate_alloc_comp
6934 (ref->u.c.component->ts.u.derived,
6935 se.expr, expr->rank);
6936 gfc_add_expr_to_block (&se.pre, tmp);
6937 }
6938 }
6939
4fb5478c 6940 if (al->expr->ts.type == BT_CLASS)
34d9d749
AV
6941 {
6942 gfc_reset_vptr (&se.pre, al->expr);
6943 if (UNLIMITED_POLY (al->expr)
6944 || (al->expr->ts.type == BT_DERIVED
6945 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6946 /* Clear _len, too. */
6947 gfc_reset_len (&se.pre, al->expr);
6948 }
5046aff5 6949 }
6de9cd9a
DN
6950 else
6951 {
ba85c8c3
AV
6952 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, label_finish,
6953 false, al->expr,
6954 al->expr->ts, is_coarray);
54200abb
RG
6955 gfc_add_expr_to_block (&se.pre, tmp);
6956
0d87fa8c 6957 /* Set to zero after deallocation. */
bc98ed60
TB
6958 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6959 se.expr,
6960 build_int_cst (TREE_TYPE (se.expr), 0));
0d87fa8c 6961 gfc_add_expr_to_block (&se.pre, tmp);
8b704316 6962
0d87fa8c 6963 if (al->expr->ts.type == BT_CLASS)
34d9d749
AV
6964 {
6965 gfc_reset_vptr (&se.pre, al->expr);
6966 if (UNLIMITED_POLY (al->expr)
6967 || (al->expr->ts.type == BT_DERIVED
6968 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6969 /* Clear _len, too. */
6970 gfc_reset_len (&se.pre, al->expr);
6971 }
6de9cd9a 6972 }
364667a1 6973
5d81ddd0 6974 if (code->expr1)
364667a1 6975 {
5d81ddd0
TB
6976 tree cond;
6977
63ee5404 6978 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
5d81ddd0
TB
6979 build_int_cst (TREE_TYPE (stat), 0));
6980 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
ed9c79e1 6981 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
5d81ddd0
TB
6982 build1_v (GOTO_EXPR, label_errmsg),
6983 build_empty_stmt (input_location));
6984 gfc_add_expr_to_block (&se.pre, tmp);
364667a1
SK
6985 }
6986
6de9cd9a
DN
6987 tmp = gfc_finish_block (&se.pre);
6988 gfc_add_expr_to_block (&block, tmp);
0d87fa8c 6989 gfc_free_expr (expr);
364667a1
SK
6990 }
6991
a513927a 6992 if (code->expr1)
364667a1 6993 {
5d81ddd0
TB
6994 tmp = build1_v (LABEL_EXPR, label_errmsg);
6995 gfc_add_expr_to_block (&block, tmp);
6de9cd9a
DN
6996 }
6997
5d81ddd0
TB
6998 /* Set ERRMSG - only needed if STAT is available. */
6999 if (code->expr1 && code->expr2)
3759634f 7000 {
3759634f 7001 const char *msg = "Attempt to deallocate an unallocated object";
5d81ddd0
TB
7002 stmtblock_t errmsg_block;
7003 tree errmsg_str, slen, dlen, cond;
3759634f 7004
5d81ddd0 7005 gfc_init_block (&errmsg_block);
3759634f 7006
5d81ddd0
TB
7007 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
7008 gfc_add_modify (&errmsg_block, errmsg_str,
3759634f
SK
7009 gfc_build_addr_expr (pchar_type_node,
7010 gfc_build_localized_cstring_const (msg)));
f622221a 7011 slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
3759634f 7012 dlen = gfc_get_expr_charlen (code->expr2);
3759634f 7013
5d81ddd0
TB
7014 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
7015 slen, errmsg_str, gfc_default_character_kind);
7016 tmp = gfc_finish_block (&errmsg_block);
3759634f 7017
63ee5404 7018 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
5d81ddd0
TB
7019 build_int_cst (TREE_TYPE (stat), 0));
7020 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
ed9c79e1 7021 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
5d81ddd0 7022 build_empty_stmt (input_location));
3759634f 7023
5d81ddd0
TB
7024 gfc_add_expr_to_block (&block, tmp);
7025 }
3759634f 7026
5d81ddd0
TB
7027 if (code->expr1 && TREE_USED (label_finish))
7028 {
7029 tmp = build1_v (LABEL_EXPR, label_finish);
3759634f
SK
7030 gfc_add_expr_to_block (&block, tmp);
7031 }
7032
5d81ddd0
TB
7033 /* Set STAT. */
7034 if (code->expr1)
7035 {
7036 gfc_init_se (&se, NULL);
7037 gfc_conv_expr_lhs (&se, code->expr1);
7038 tmp = convert (TREE_TYPE (se.expr), stat);
7039 gfc_add_modify (&block, se.expr, tmp);
7040 }
7041
6de9cd9a
DN
7042 return gfc_finish_block (&block);
7043}
7044
d2886bc7 7045#include "gt-fortran-trans-stmt.h"