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