Revert r244448
[platform/upstream/gcc.git] / gcc / fortran / trans-stmt.c
1 /* Statement translation -- generate GCC trees from gfc_code.
2    Copyright (C) 2002-2017 Free Software Foundation, Inc.
3    Contributed by Paul Brook <paul@nowt.org>
4    and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "options.h"
27 #include "tree.h"
28 #include "gfortran.h"
29 #include "trans.h"
30 #include "stringpool.h"
31 #include "fold-const.h"
32 #include "trans-stmt.h"
33 #include "trans-types.h"
34 #include "trans-array.h"
35 #include "trans-const.h"
36 #include "dependency.h"
37
38 typedef struct iter_info
39 {
40   tree var;
41   tree start;
42   tree end;
43   tree step;
44   struct iter_info *next;
45 }
46 iter_info;
47
48 typedef struct forall_info
49 {
50   iter_info *this_loop;
51   tree mask;
52   tree maskindex;
53   int nvar;
54   tree size;
55   struct forall_info  *prev_nest;
56   bool do_concurrent;
57 }
58 forall_info;
59
60 static void gfc_trans_where_2 (gfc_code *, tree, bool,
61                                forall_info *, stmtblock_t *);
62
63 /* Translate a F95 label number to a LABEL_EXPR.  */
64
65 tree
66 gfc_trans_label_here (gfc_code * code)
67 {
68   return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
69 }
70
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
76 void
77 gfc_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);
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);
87 }
88
89 /* Translate a label assignment statement.  */
90
91 tree
92 gfc_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;
99   int label_len;
100
101   /* Start a new block.  */
102   gfc_init_se (&se, NULL);
103   gfc_start_block (&se.pre);
104   gfc_conv_label_variable (&se, code->expr1);
105
106   len = GFC_DECL_STRING_LEN (se.expr);
107   addr = GFC_DECL_ASSIGN_ADDR (se.expr);
108
109   label_tree = gfc_get_label_decl (code->label1);
110
111   if (code->label1->defined == ST_LABEL_TARGET
112       || code->label1->defined == ST_LABEL_DO_TARGET)
113     {
114       label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
115       len_tree = integer_minus_one_node;
116     }
117   else
118     {
119       gfc_expr *format = code->label1->format;
120
121       label_len = format->value.character.length;
122       len_tree = build_int_cst (gfc_charlen_type_node, label_len);
123       label_tree = gfc_build_wide_string_const (format->ts.kind, label_len + 1,
124                                                 format->value.character.string);
125       label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
126     }
127
128   gfc_add_modify (&se.pre, len, len_tree);
129   gfc_add_modify (&se.pre, addr, label_tree);
130
131   return gfc_finish_block (&se.pre);
132 }
133
134 /* Translate a GOTO statement.  */
135
136 tree
137 gfc_trans_goto (gfc_code * code)
138 {
139   locus loc = code->loc;
140   tree assigned_goto;
141   tree target;
142   tree tmp;
143   gfc_se se;
144
145   if (code->label1 != NULL)
146     return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
147
148   /* ASSIGNED GOTO.  */
149   gfc_init_se (&se, NULL);
150   gfc_start_block (&se.pre);
151   gfc_conv_label_variable (&se, code->expr1);
152   tmp = GFC_DECL_STRING_LEN (se.expr);
153   tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
154                          build_int_cst (TREE_TYPE (tmp), -1));
155   gfc_trans_runtime_check (true, false, tmp, &se.pre, &loc,
156                            "Assigned label is not a target label");
157
158   assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
159
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
166   target = fold_build1_loc (input_location, GOTO_EXPR, void_type_node,
167                             assigned_goto);
168   gfc_add_expr_to_block (&se.pre, target);
169   return gfc_finish_block (&se.pre);
170 }
171
172
173 /* Translate an ENTRY statement.  Just adds a label for this entry point.  */
174 tree
175 gfc_trans_entry (gfc_code * code)
176 {
177   return build1_v (LABEL_EXPR, code->ext.entry->label);
178 }
179
180
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
185 static void
186 replace_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
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.  */
220 static void
221 gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
222                                  gfc_symbol * sym, gfc_actual_arglist * arg,
223                                  gfc_dep_check check_variable)
224 {
225   gfc_actual_arglist *arg0;
226   gfc_expr *e;
227   gfc_formal_arglist *formal;
228   gfc_se parmse;
229   gfc_ss *ss;
230   gfc_symbol *fsym;
231   tree data;
232   tree size;
233   tree tmp;
234
235   if (loopse->ss == NULL)
236     return;
237
238   ss = loopse->ss;
239   arg0 = arg;
240   formal = gfc_sym_get_dummy_args (sym);
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
249       /* Obtain the info structure for the current argument.  */
250       for (ss = loopse->ss; ss && ss != gfc_ss_terminator; ss = ss->next)
251         if (ss->info->expr == e)
252           break;
253
254       /* If there is a dependency, create a temporary and use it
255          instead of the variable.  */
256       fsym = formal ? formal->sym : NULL;
257       if (e->expr_type == EXPR_VARIABLE
258             && e->rank && fsym
259             && fsym->attr.intent != INTENT_IN
260             && gfc_check_fncall_dependency (e, fsym->attr.intent,
261                                             sym, arg0, check_variable))
262         {
263           tree initial, temptype;
264           stmtblock_t temp_post;
265           gfc_ss *tmp_ss;
266
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);
272
273           /* Obtain the argument descriptor for unpacking.  */
274           gfc_init_se (&parmse, NULL);
275           parmse.want_pointer = 1;
276           gfc_conv_expr_descriptor (&parmse, e);
277           gfc_add_block_to_block (&se->pre, &parmse.pre);
278
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))
284             initial = parmse.expr;
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;
289           else
290             initial = NULL_TREE;
291
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;
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.  */
314           size = gfc_create_var (gfc_array_index_type, NULL);
315           data = gfc_create_var (pvoid_type_node, NULL);
316           gfc_init_block (&temp_post);
317           tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, tmp_ss,
318                                              temptype, initial, false, true,
319                                              false, &arg->expr->where);
320           gfc_add_modify (&se->pre, size, tmp);
321           tmp = fold_convert (pvoid_type_node, tmp_ss->info->data.array.data);
322           gfc_add_modify (&se->pre, data, tmp);
323
324           /* Update other ss' delta.  */
325           gfc_set_delta (loopse->loop);
326
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),
339                                          3, tmp, data,
340                                          fold_convert (size_type_node, size));
341             }
342           gfc_add_expr_to_block (&se->post, tmp);
343
344           /* parmse.pre is already added above.  */
345           gfc_add_block_to_block (&se->post, &parmse.post);
346           gfc_add_block_to_block (&se->post, &temp_post);
347         }
348     }
349 }
350
351
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
356 static gfc_symbol *
357 get_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
373 /* Translate the CALL statement.  Builds a call to an F95 subroutine.  */
374
375 tree
376 gfc_trans_call (gfc_code * code, bool dependency_check,
377                 tree mask, tree count1, bool invert)
378 {
379   gfc_se se;
380   gfc_ss * ss;
381   int has_alternate_specifier;
382   gfc_dep_check check_variable;
383   tree index = NULL_TREE;
384   tree maskexpr = NULL_TREE;
385   tree tmp;
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
392   gcc_assert (code->resolved_sym);
393
394   ss = gfc_ss_terminator;
395   if (code->resolved_sym->attr.elemental)
396     ss = gfc_walk_elemental_function_args (ss, code->ext.actual,
397                                            get_proc_ifc_for_call (code),
398                                            GFC_SS_REFERENCE);
399
400   /* Is not an elemental subroutine call with array valued arguments.  */
401   if (ss == gfc_ss_terminator)
402     {
403
404       /* Translate the call.  */
405       has_alternate_specifier
406         = gfc_conv_procedure_call (&se, code->resolved_sym, code->ext.actual,
407                                   code->expr1, NULL);
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);
419           sym = select_code->expr1->symtree->n.sym;
420           se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
421           if (sym->backend_decl == NULL)
422             sym->backend_decl = gfc_get_symbol_decl (sym);
423           gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
424         }
425       else
426         gfc_add_expr_to_block (&se.pre, se.expr);
427
428       gfc_add_block_to_block (&se.pre, &se.post);
429     }
430
431   else
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;
439       gfc_se depse;
440
441       /* gfc_walk_elemental_function_args renders the ss chain in the
442          reverse order to the actual argument order.  */
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);
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
454          (below in gfc_conv_elemental_dependencies).  */
455       gfc_conv_loop_setup (&loop, &code->expr1->where);
456       gfc_mark_ss_chain_used (ss, 1);
457
458       /* Convert the arguments, checking for dependencies.  */
459       gfc_copy_loopinfo_to_se (&loopse, &loop);
460       loopse.ss = ss;
461
462       /* For operator assignment, do dependency checking.  */
463       if (dependency_check)
464         check_variable = ELEM_CHECK_VARIABLE;
465       else
466         check_variable = ELEM_DONT_CHECK_VARIABLE;
467
468       gfc_init_se (&depse, NULL);
469       gfc_conv_elemental_dependencies (&depse, &loopse, code->resolved_sym,
470                                        code->ext.actual, check_variable);
471
472       gfc_add_block_to_block (&loop.pre,  &depse.pre);
473       gfc_add_block_to_block (&loop.post, &depse.post);
474
475       /* Generate the loop body.  */
476       gfc_start_scalarized_body (&loop, &body);
477       gfc_init_block (&block);
478
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)
485             maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
486                                         TREE_TYPE (maskexpr), maskexpr);
487         }
488
489       /* Add the subroutine call to the block.  */
490       gfc_conv_procedure_call (&loopse, code->resolved_sym,
491                                code->ext.actual, code->expr1,
492                                NULL);
493
494       if (mask && count1)
495         {
496           tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
497                           build_empty_stmt (input_location));
498           gfc_add_expr_to_block (&loopse.pre, tmp);
499           tmp = fold_build2_loc (input_location, PLUS_EXPR,
500                                  gfc_array_index_type,
501                                  count1, gfc_index_one_node);
502           gfc_add_modify (&loopse.pre, count1, tmp);
503         }
504       else
505         gfc_add_expr_to_block (&loopse.pre, loopse.expr);
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);
515       gfc_add_block_to_block (&se.pre, &se.post);
516       gfc_cleanup_loop (&loop);
517     }
518
519   return gfc_finish_block (&se.pre);
520 }
521
522
523 /* Translate the RETURN statement.  */
524
525 tree
526 gfc_trans_return (gfc_code * code)
527 {
528   if (code->expr1)
529     {
530       gfc_se se;
531       tree tmp;
532       tree result;
533
534       /* If code->expr is not NULL, this return statement must appear
535          in a subroutine and current_fake_result_decl has already
536          been generated.  */
537
538       result = gfc_get_fake_result_decl (NULL, 0);
539       if (!result)
540         {
541           gfc_warning (0,
542                        "An alternate return at %L without a * dummy argument",
543                        &code->expr1->where);
544           return gfc_generate_return ();
545         }
546
547       /* Start a new block for this statement.  */
548       gfc_init_se (&se, NULL);
549       gfc_start_block (&se.pre);
550
551       gfc_conv_expr (&se, code->expr1);
552
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.  */
556       tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (result),
557                              result, fold_convert (TREE_TYPE (result),
558                              se.expr));
559       gfc_add_expr_to_block (&se.pre, tmp);
560       gfc_add_block_to_block (&se.pre, &se.post);
561
562       tmp = gfc_generate_return ();
563       gfc_add_expr_to_block (&se.pre, tmp);
564       return gfc_finish_block (&se.pre);
565     }
566
567   return gfc_generate_return ();
568 }
569
570
571 /* Translate the PAUSE statement.  We have to translate this statement
572    to a runtime library call.  */
573
574 tree
575 gfc_trans_pause (gfc_code * code)
576 {
577   tree gfc_int4_type_node = gfc_get_int_type (4);
578   gfc_se se;
579   tree tmp;
580
581   /* Start a new block for this statement.  */
582   gfc_init_se (&se, NULL);
583   gfc_start_block (&se.pre);
584
585
586   if (code->expr1 == NULL)
587     {
588       tmp = build_int_cst (gfc_int4_type_node, 0);
589       tmp = build_call_expr_loc (input_location,
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));
599     }
600   else
601     {
602       gfc_conv_expr_reference (&se, code->expr1);
603       tmp = build_call_expr_loc (input_location,
604                              gfor_fndecl_pause_string, 2,
605                              se.expr, se.string_length);
606     }
607
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
619 tree
620 gfc_trans_stop (gfc_code *code, bool error_stop)
621 {
622   tree gfc_int4_type_node = gfc_get_int_type (4);
623   gfc_se se;
624   tree tmp;
625
626   /* Start a new block for this statement.  */
627   gfc_init_se (&se, NULL);
628   gfc_start_block (&se.pre);
629
630   if (code->expr1 == NULL)
631     {
632       tmp = build_int_cst (gfc_int4_type_node, 0);
633       tmp = build_call_expr_loc (input_location,
634                                  error_stop
635                                  ? (flag_coarray == GFC_FCOARRAY_LIB
636                                     ? gfor_fndecl_caf_error_stop_str
637                                     : gfor_fndecl_error_stop_string)
638                                  : (flag_coarray == GFC_FCOARRAY_LIB
639                                     ? gfor_fndecl_caf_stop_str
640                                     : gfor_fndecl_stop_string),
641                                  2, build_int_cst (pchar_type_node, 0), tmp);
642     }
643   else if (code->expr1->ts.type == BT_INTEGER)
644     {
645       gfc_conv_expr (&se, code->expr1);
646       tmp = build_call_expr_loc (input_location,
647                                  error_stop
648                                  ? (flag_coarray == GFC_FCOARRAY_LIB
649                                     ? gfor_fndecl_caf_error_stop
650                                     : gfor_fndecl_error_stop_numeric)
651                                  : (flag_coarray == GFC_FCOARRAY_LIB
652                                     ? gfor_fndecl_caf_stop_numeric
653                                     : gfor_fndecl_stop_numeric), 1,
654                                  fold_convert (gfc_int4_type_node, se.expr));
655     }
656   else
657     {
658       gfc_conv_expr_reference (&se, code->expr1);
659       tmp = build_call_expr_loc (input_location,
660                                  error_stop
661                                  ? (flag_coarray == GFC_FCOARRAY_LIB
662                                     ? gfor_fndecl_caf_error_stop_str
663                                     : gfor_fndecl_error_stop_string)
664                                  : (flag_coarray == GFC_FCOARRAY_LIB
665                                     ? gfor_fndecl_caf_stop_str
666                                     : gfor_fndecl_stop_string),
667                                  2, se.expr, se.string_length);
668     }
669
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
678 tree
679 gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
680 {
681   gfc_se se, argse;
682   tree stat = NULL_TREE, stat2 = NULL_TREE;
683   tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
684
685   /* Short cut: For single images without STAT= or LOCK_ACQUIRED
686      return early. (ERRMSG= is always untouched for -fcoarray=single.)  */
687   if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
688     return NULL_TREE;
689
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     }
697   else if (flag_coarray == GFC_FCOARRAY_LIB)
698     stat = null_pointer_node;
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     }
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
728       gfc_get_caf_token_offset (&se, &token, NULL, caf_decl, NULL_TREE,
729                                 code->expr1);
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);
786           argse.want_pointer = 1;
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
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
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     }
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
860 tree
861 gfc_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
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);
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
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
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 }
1030
1031 tree
1032 gfc_trans_sync (gfc_code *code, gfc_exec_op type)
1033 {
1034   gfc_se se, argse;
1035   tree tmp;
1036   tree images = NULL_TREE, stat = NULL_TREE,
1037        errmsg = NULL_TREE, errmsglen = NULL_TREE;
1038
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)
1042       && flag_coarray != GFC_FCOARRAY_LIB)
1043     return NULL_TREE;
1044
1045   gfc_init_se (&se, NULL);
1046   gfc_start_block (&se.pre);
1047
1048   if (code->expr1 && code->expr1->rank == 0)
1049     {
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     }
1062   else
1063     stat = null_pointer_node;
1064
1065   if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
1066     {
1067       gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
1068       gfc_init_se (&argse, NULL);
1069       argse.want_pointer = 1;
1070       gfc_conv_expr (&argse, code->expr3);
1071       gfc_conv_string_parameter (&argse);
1072       errmsg = gfc_build_addr_expr (NULL, argse.expr);
1073       errmsglen = argse.string_length;
1074     }
1075   else if (flag_coarray == GFC_FCOARRAY_LIB)
1076     {
1077       errmsg = null_pointer_node;
1078       errmsglen = build_int_cst (integer_type_node, 0);
1079     }
1080
1081   /* Check SYNC IMAGES(imageset) for valid image index.
1082      FIXME: Add a check for image-set arrays.  */
1083   if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1084       && code->expr1->rank == 0)
1085     {
1086       tree cond;
1087       if (flag_coarray != GFC_FCOARRAY_LIB)
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;
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));
1096           cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1097                                   images, tmp);
1098           cond2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1099                                    images,
1100                                    build_int_cst (TREE_TYPE (images), 1));
1101           cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1102                                   boolean_type_node, cond, cond2);
1103         }
1104       gfc_trans_runtime_check (true, false, cond, &se.pre,
1105                                &code->expr1->where, "Invalid image number "
1106                                "%d in SYNC IMAGES",
1107                                fold_convert (integer_type_node, images));
1108     }
1109
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
1122   if (flag_coarray != GFC_FCOARRAY_LIB)
1123     {
1124       /* Set STAT to zero.  */
1125       if (code->expr2)
1126         gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1127     }
1128   else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
1129     {
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);
1139
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
1147           gfc_add_expr_to_block (&se.pre, tmp);
1148         }
1149       else
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);
1157
1158           gfc_add_modify (&se.pre, stat,
1159                           fold_convert (TREE_TYPE (stat), tmp_stat));
1160         }
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)
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);
1185
1186           gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
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
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
1210           tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1211                                      5, fold_convert (integer_type_node, len),
1212                                      images, stat, errmsg, errmsglen);
1213           gfc_add_expr_to_block (&se.pre, tmp);
1214         }
1215       else
1216         {
1217           tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1218
1219           tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
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
1225           gfc_add_modify (&se.pre, stat,
1226                           fold_convert (TREE_TYPE (stat), tmp_stat));
1227         }
1228     }
1229
1230   return gfc_finish_block (&se.pre);
1231 }
1232
1233
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
1274 static tree
1275 gfc_trans_if_1 (gfc_code * code)
1276 {
1277   gfc_se if_se;
1278   tree stmt, elsestmt;
1279   locus saved_loc;
1280   location_t loc;
1281
1282   /* Check for an unconditional ELSE clause.  */
1283   if (!code->expr1)
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.  */
1291   if (code->expr1->where.lb)
1292     {
1293       gfc_save_backend_locus (&saved_loc);
1294       gfc_set_backend_locus (&code->expr1->where);
1295     }
1296
1297   gfc_conv_expr_val (&if_se, code->expr1);
1298
1299   if (code->expr1->where.lb)
1300     gfc_restore_backend_locus (&saved_loc);
1301
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
1309     elsestmt = build_empty_stmt (input_location);
1310
1311   /* Build the condition expression and add it to the condition block.  */
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);
1315
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
1322 tree
1323 gfc_trans_if (gfc_code * code)
1324 {
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));
1338
1339   return gfc_finish_block (&body);
1340 }
1341
1342
1343 /* Translate an arithmetic IF expression.
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;
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;
1364 */
1365
1366 tree
1367 gfc_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.  */
1380   gfc_conv_expr_val (&se, code->expr1);
1381   se.expr = gfc_evaluate_now (se.expr, &se.pre);
1382
1383   /* Build something to compare with.  */
1384   zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1385
1386   if (code->label1->value != code->label2->value)
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.  */
1390       branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1391       branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1392
1393       if (code->label1->value != code->label3->value)
1394         tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1395                                se.expr, zero);
1396       else
1397         tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1398                                se.expr, zero);
1399
1400       branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1401                                  tmp, branch1, branch2);
1402     }
1403   else
1404     branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1405
1406   if (code->label1->value != code->label3->value
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));
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);
1415     }
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
1423 /* Translate a CRITICAL block.  */
1424 tree
1425 gfc_trans_critical (gfc_code *code)
1426 {
1427   stmtblock_t block;
1428   tree tmp, token = NULL_TREE;
1429
1430   gfc_start_block (&block);
1431
1432   if (flag_coarray == GFC_FCOARRAY_LIB)
1433     {
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,
1438                                  null_pointer_node, null_pointer_node,
1439                                  null_pointer_node, integer_zero_node);
1440       gfc_add_expr_to_block (&block, tmp);
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;
1450
1451       gfc_add_expr_to_block (&block, tmp);
1452     }
1453
1454   tmp = gfc_trans_code (code->block->next);
1455   gfc_add_expr_to_block (&block, tmp);
1456
1457   if (flag_coarray == GFC_FCOARRAY_LIB)
1458     {
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);
1463       gfc_add_expr_to_block (&block, tmp);
1464
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     }
1476
1477   return gfc_finish_block (&block);
1478 }
1479
1480
1481 /* Return true, when the class has a _len component.  */
1482
1483 static bool
1484 class_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
1497 /* Do proper initialization for ASSOCIATE names.  */
1498
1499 static void
1500 trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1501 {
1502   gfc_expr *e;
1503   tree tmp;
1504   bool class_target;
1505   bool unlimited;
1506   tree desc;
1507   tree offset;
1508   tree dim;
1509   int n;
1510   tree charlen;
1511   bool need_len_assign;
1512
1513   gcc_assert (sym->assoc);
1514   e = sym->assoc->target;
1515
1516   class_target = (e->expr_type == EXPR_VARIABLE)
1517                     && (gfc_is_class_scalar_expr (e)
1518                         || gfc_is_class_array_ref (e, NULL));
1519
1520   unlimited = UNLIMITED_POLY (e);
1521
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))));
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.  */
1539   if (sym->attr.dimension && !class_target
1540       && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1541     {
1542       gfc_se se;
1543       tree desc;
1544       bool cst_array_ctor;
1545
1546       desc = sym->backend_decl;
1547       cst_array_ctor = e->expr_type == EXPR_ARRAY
1548               && gfc_constant_array_constructor_p (e->value.constructor);
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);
1553       if (sym->assoc->variable || cst_array_ctor)
1554         {
1555           se.direct_byref = 1;
1556           se.use_offset = 1;
1557           se.expr = desc;
1558         }
1559
1560       gfc_conv_expr_descriptor (&se, e);
1561
1562       /* If we didn't already do the pointer assignment, set associate-name
1563          descriptor to the one generated for the temporary.  */
1564       if (!sym->assoc->variable && !cst_array_ctor)
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
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);
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;
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
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
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))
1599     {
1600       gfc_se se;
1601
1602       gfc_init_se (&se, NULL);
1603       se.descriptor_only = 1;
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);
1610
1611       gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1612                   || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
1613       gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1614
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);
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
1637       gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1638                             gfc_finish_block (&se.post));
1639     }
1640
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);
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         {
1654           tree target_expr;
1655           /* For a class array we need a descriptor for the selector.  */
1656           gfc_conv_expr_descriptor (&se, e);
1657           /* Needed to get/set the _len component below.  */
1658           target_expr = se.expr;
1659
1660           /* Obtain a temporary class container for the result.  */
1661           gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
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             }
1678           if (need_len_assign)
1679             {
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);
1692               /* Get the component-ref for the temp structure's _len comp.  */
1693               charlen = gfc_class_len_get (se.expr);
1694               /* Add the assign to the beginning of the block...  */
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             }
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);
1711           /* Get the _vptr component of the class object.  */
1712           tmp = gfc_get_vptr_from_expr (se.expr);
1713           /* Obtain a temporary class container for the result.  */
1714           gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
1715           se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1716         }
1717       else
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         }
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);
1729
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     }
1744
1745   /* Set the stringlength, when needed.  */
1746   if (need_len_assign)
1747     {
1748       gfc_se se;
1749       gfc_init_se (&se, NULL);
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));
1758       gfc_get_symbol_decl (sym);
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         }
1769     }
1770 }
1771
1772
1773 /* Translate a BLOCK construct.  This is basically what we would do for a
1774    procedure body.  */
1775
1776 tree
1777 gfc_trans_block_construct (gfc_code* code)
1778 {
1779   gfc_namespace* ns;
1780   gfc_symbol* sym;
1781   gfc_wrapped_block block;
1782   tree exit_label;
1783   stmtblock_t body;
1784   gfc_association_list *ass;
1785
1786   ns = code->ext.block.ns;
1787   gcc_assert (ns);
1788   sym = ns->proc_name;
1789   gcc_assert (sym);
1790
1791   /* Process local variables.  */
1792   gcc_assert (!sym->tlink);
1793   sym->tlink = sym;
1794   gfc_process_block_locals (ns);
1795
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;
1800
1801   finish_oacc_declare (ns, sym, true);
1802
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);
1809   for (ass = code->ext.block.assoc; ass; ass = ass->next)
1810     trans_associate_var (ass->st->n.sym, &block);
1811
1812   return gfc_finish_wrapped_block (&block);
1813 }
1814
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)
1819
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]
1829     dovar = from;
1830     for (;;)
1831       {
1832         if (dovar > to)
1833           goto end_label;
1834         body;
1835         cycle_label:
1836         dovar += step;
1837       }
1838     end_label:
1839
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).  */
1843
1844 static tree
1845 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
1846                      tree from, tree to, tree step, tree exit_cond)
1847 {
1848   stmtblock_t body;
1849   tree type;
1850   tree cond;
1851   tree tmp;
1852   tree saved_dovar = NULL;
1853   tree cycle_label;
1854   tree exit_label;
1855   location_t loc;
1856   type = TREE_TYPE (dovar);
1857   bool is_step_positive = tree_int_cst_sgn (step) > 0;
1858
1859   loc = code->ext.iterator->start->where.lb->location;
1860
1861   /* Initialize the DO variable: dovar = from.  */
1862   gfc_add_modify_loc (loc, pblock, dovar,
1863                       fold_convert (TREE_TYPE (dovar), from));
1864
1865   /* Save value for do-tinkering checking.  */
1866   if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1867     {
1868       saved_dovar = gfc_create_var (type, ".saved_dovar");
1869       gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
1870     }
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
1876   /* Put the labels where they can be found later.  See gfc_trans_do().  */
1877   code->cycle_label = cycle_label;
1878   code->exit_label = exit_label;
1879
1880   /* Loop body.  */
1881   gfc_start_block (&body);
1882
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
1923   /* Main loop body.  */
1924   tmp = gfc_trans_code_cond (code->block->next, exit_cond);
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
1934   /* Check whether someone has modified the loop variable.  */
1935   if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1936     {
1937       tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node,
1938                              dovar, saved_dovar);
1939       gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1940                                "Loop variable has been modified");
1941     }
1942
1943   /* Increment the loop variable.  */
1944   tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
1945   gfc_add_modify_loc (loc, &body, dovar, tmp);
1946
1947   if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1948     gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
1949
1950   /* Finish the loop body.  */
1951   tmp = gfc_finish_block (&body);
1952   tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
1953
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
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
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.
1970
1971    We translate a do loop from:
1972
1973    DO dovar = from, to, step
1974       body
1975    END DO
1976
1977    to:
1978
1979    [evaluate loop bounds and step]
1980    empty = (step > 0 ? to < from : to > from);
1981    countm1 = (to - from) / step;
1982    dovar = from;
1983    if (empty) goto exit_label;
1984    for (;;)
1985      {
1986        body;
1987 cycle_label:
1988        dovar += step
1989        countm1t = countm1;
1990        countm1--;
1991        if (countm1t == 0) goto exit_label;
1992      }
1993 exit_label:
1994
1995    countm1 is an unsigned integer.  It is equal to the loop count minus one,
1996    because the loop count itself can overflow.  */
1997
1998 tree
1999 gfc_trans_do (gfc_code * code, tree exit_cond)
2000 {
2001   gfc_se se;
2002   tree dovar;
2003   tree saved_dovar = NULL;
2004   tree from;
2005   tree to;
2006   tree step;
2007   tree countm1;
2008   tree type;
2009   tree utype;
2010   tree cond;
2011   tree cycle_label;
2012   tree exit_label;
2013   tree tmp;
2014   stmtblock_t block;
2015   stmtblock_t body;
2016   location_t loc;
2017
2018   gfc_start_block (&block);
2019
2020   loc = code->ext.iterator->start->where.lb->location;
2021
2022   /* Evaluate all the expressions in the iterator.  */
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);
2030   gfc_conv_expr_val (&se, code->ext.iterator->start);
2031   gfc_add_block_to_block (&block, &se.pre);
2032   from = gfc_evaluate_now (se.expr, &block);
2033
2034   gfc_init_se (&se, NULL);
2035   gfc_conv_expr_val (&se, code->ext.iterator->end);
2036   gfc_add_block_to_block (&block, &se.pre);
2037   to = gfc_evaluate_now (se.expr, &block);
2038
2039   gfc_init_se (&se, NULL);
2040   gfc_conv_expr_val (&se, code->ext.iterator->step);
2041   gfc_add_block_to_block (&block, &se.pre);
2042   step = gfc_evaluate_now (se.expr, &block);
2043
2044   if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2045     {
2046       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, step,
2047                              build_zero_cst (type));
2048       gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
2049                                "DO step value is zero");
2050     }
2051
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)))
2056     return gfc_trans_simple_do (code, &block, dovar, from, to, step,
2057                                 exit_cond);
2058
2059   if (TREE_CODE (type) == INTEGER_TYPE)
2060     utype = unsigned_type_for (type);
2061   else
2062     utype = unsigned_type_for (gfc_array_index_type);
2063   countm1 = gfc_create_var (utype, "countm1");
2064
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
2070   /* Put these labels where they can be found later.  */
2071   code->cycle_label = cycle_label;
2072   code->exit_label = exit_label;
2073
2074   /* Initialize the DO variable: dovar = from.  */
2075   gfc_add_modify (&block, dovar, from);
2076
2077   /* Save value for do-tinkering checking.  */
2078   if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2079     {
2080       saved_dovar = gfc_create_var (type, ".saved_dovar");
2081       gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
2082     }
2083
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        {
2088          countm1 = (to - from) / step;
2089          if (to < from)
2090            goto exit_label;
2091        }
2092      else
2093        {
2094          countm1 = (from - to) / -step;
2095          if (to > from)
2096            goto exit_label;
2097        }
2098    */
2099
2100   if (TREE_CODE (type) == INTEGER_TYPE)
2101     {
2102       tree pos, neg, tou, fromu, stepu, tmp2;
2103
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);
2110
2111       /* For a positive step, when to < from, exit, otherwise compute
2112          countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step  */
2113       tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, to, from);
2114       tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2115                               fold_build2_loc (loc, MINUS_EXPR, utype,
2116                                                tou, fromu),
2117                               stepu);
2118       pos = build2 (COMPOUND_EXPR, void_type_node,
2119                     fold_build2 (MODIFY_EXPR, void_type_node,
2120                                  countm1, tmp2),
2121                     build3_loc (loc, COND_EXPR, void_type_node,
2122                                 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2123                                 build1_loc (loc, GOTO_EXPR, void_type_node,
2124                                             exit_label), NULL_TREE));
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));
2133       neg = build2 (COMPOUND_EXPR, void_type_node,
2134                     fold_build2 (MODIFY_EXPR, void_type_node,
2135                                  countm1, tmp2),
2136                     build3_loc (loc, COND_EXPR, void_type_node,
2137                                 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2138                                 build1_loc (loc, GOTO_EXPR, void_type_node,
2139                                             exit_label), NULL_TREE));
2140
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);
2144
2145       gfc_add_expr_to_block (&block, tmp);
2146     }
2147   else
2148     {
2149       tree pos_step;
2150
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.  */
2154
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);
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);  */
2162       pos_step = fold_build2_loc (loc, GT_EXPR, boolean_type_node, step,
2163                                   build_zero_cst (type));
2164       tmp = fold_build3_loc (loc, COND_EXPR, boolean_type_node, pos_step,
2165                              fold_build2_loc (loc, LT_EXPR,
2166                                               boolean_type_node, to, from),
2167                              fold_build2_loc (loc, GT_EXPR,
2168                                               boolean_type_node, to, from));
2169       /* If the loop is empty, go directly to the exit label.  */
2170       tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
2171                          build1_v (GOTO_EXPR, exit_label),
2172                          build_empty_stmt (input_location));
2173       gfc_add_expr_to_block (&block, tmp);
2174     }
2175
2176   /* Loop body.  */
2177   gfc_start_block (&body);
2178
2179   /* Main loop body.  */
2180   tmp = gfc_trans_code_cond (code->block->next, exit_cond);
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
2190   /* Check whether someone has modified the loop variable.  */
2191   if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2192     {
2193       tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node, dovar,
2194                              saved_dovar);
2195       gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2196                                "Loop variable has been modified");
2197     }
2198
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);
2203       tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2204                              exit_cond, tmp,
2205                              build_empty_stmt (input_location));
2206       gfc_add_expr_to_block (&body, tmp);
2207     }
2208
2209   /* Increment the loop variable.  */
2210   tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2211   gfc_add_modify_loc (loc, &body, dovar, tmp);
2212
2213   if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2214     gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2215
2216   /* Initialize countm1t.  */
2217   tree countm1t = gfc_create_var (utype, "countm1t");
2218   gfc_add_modify_loc (loc, &body, countm1t, countm1);
2219
2220   /* Decrement the loop count.  */
2221   tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
2222                          build_int_cst (utype, 1));
2223   gfc_add_modify_loc (loc, &body, countm1, tmp);
2224
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
2233   /* End of loop body.  */
2234   tmp = gfc_finish_block (&body);
2235
2236   /* The for loop itself.  */
2237   tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
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;
2263 cycle_label:
2264      }
2265 exit_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
2271 tree
2272 gfc_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().  */
2288   code->cycle_label = cycle_label;
2289   code->exit_label = exit_label;
2290
2291   /* Create a GIMPLE version of the exit condition.  */
2292   gfc_init_se (&cond, NULL);
2293   gfc_conv_expr_val (&cond, code->expr1);
2294   gfc_add_block_to_block (&block, &cond.pre);
2295   cond.expr = fold_build1_loc (code->expr1->where.lb->location,
2296                                TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
2297
2298   /* Build "IF (! cond) GOTO exit_label".  */
2299   tmp = build1_v (GOTO_EXPR, exit_label);
2300   TREE_USED (exit_label) = 1;
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));
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.  */
2322   tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2323                          void_type_node, tmp);
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
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
2338 static tree
2339 gfc_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
2367 repeat:
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
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
2498 static tree
2499 gfc_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);
2513   gfc_conv_expr_val (&se, code->expr1);
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     {
2522       for (cp = c->ext.block.case_list; cp; cp = cp->next)
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             {
2532               low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2533                                           cp->low->ts.kind);
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
2554                  high.  In the third case, we don't because the GCC middle
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))
2563                 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2564                                              cp->high->ts.kind);
2565
2566               /* Unbounded case.  */
2567               if (!cp->low)
2568                 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2569             }
2570
2571           /* Build a label.  */
2572           label = gfc_build_label_decl (NULL_TREE);
2573
2574           /* Add this case label.
2575              Add parameter 'label', make it match GCC backend.  */
2576           tmp = build_case_label (low, high, label);
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);
2590   tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2591                          se.expr, tmp, NULL_TREE);
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
2615 static tree
2616 gfc_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     {
2634       for (cp = c->ext.block.case_list; cp; cp = cp->next)
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);
2654   gfc_conv_expr_val (&se, code->expr1);
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     {
2666       tree true_tree, false_tree, stmt;
2667
2668       true_tree = build_empty_stmt (input_location);
2669       false_tree = build_empty_stmt (input_location);
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
2692       stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2693                               se.expr, true_tree, false_tree);
2694       gfc_add_expr_to_block (&block, stmt);
2695     }
2696
2697   return gfc_finish_block (&block);
2698 }
2699
2700
2701 /* The jump table types are stored in static variables to avoid
2702    constructing them from scratch every single time.  */
2703 static GTY(()) tree select_struct[2];
2704
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
2714 static tree
2715 gfc_trans_character_select (gfc_code *code)
2716 {
2717   tree init, end_label, tmp, type, case_num, label, fndecl;
2718   stmtblock_t block, body;
2719   gfc_case *cp, *d;
2720   gfc_code *c;
2721   gfc_se se, expr1se;
2722   int n, k;
2723   vec<constructor_elt, va_gc> *inits = NULL;
2724
2725   tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2726
2727   /* The jump table types are stored in static variables to avoid
2728      constructing them from scratch every single time.  */
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
2733   cp = code->block->ext.block.case_list;
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.  */
2749   if (integer_onep (expr1se.string_length))
2750     {
2751       for (d = cp; d; d = d->right)
2752         {
2753           int i;
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             {
2802               for (cp = c->ext.block.case_list; cp; cp = cp->next)
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.  */
2854                   tmp = build_case_label (low, high, label);
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);
2876           tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2877                                  case_num, tmp, NULL_TREE);
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     }
2886
2887   if (code->expr1->ts.kind == 1)
2888     k = 0;
2889   else if (code->expr1->ts.kind == 4)
2890     k = 1;
2891   else
2892     gcc_unreachable ();
2893
2894   if (select_struct[k] == NULL)
2895     {
2896       tree *chain = NULL;
2897       select_struct[k] = make_node (RECORD_TYPE);
2898
2899       if (code->expr1->ts.kind == 1)
2900         TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
2901       else if (code->expr1->ts.kind == 4)
2902         TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
2903       else
2904         gcc_unreachable ();
2905
2906 #undef ADD_FIELD
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)
2912
2913       ADD_FIELD (string1, pchartype);
2914       ADD_FIELD (string1_len, gfc_charlen_type_node);
2915
2916       ADD_FIELD (string2, pchartype);
2917       ADD_FIELD (string2_len, gfc_charlen_type_node);
2918
2919       ADD_FIELD (target, integer_type_node);
2920 #undef ADD_FIELD
2921
2922       gfc_finish_type (select_struct[k]);
2923     }
2924
2925   n = 0;
2926   for (d = cp; d; d = d->right)
2927     d->n = n++;
2928
2929   for (c = code->block; c; c = c->block)
2930     {
2931       for (d = c->ext.block.case_list; d; d = d->next)
2932         {
2933           label = gfc_build_label_decl (NULL_TREE);
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);
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
2944       tmp = build1_v (GOTO_EXPR, end_label);
2945       gfc_add_expr_to_block (&body, tmp);
2946     }
2947
2948   /* Generate the structure describing the branches */
2949   for (d = cp; d; d = d->right)
2950     {
2951       vec<constructor_elt, va_gc> *node = NULL;
2952
2953       gfc_init_se (&se, NULL);
2954
2955       if (d->low == NULL)
2956         {
2957           CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
2958           CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], integer_zero_node);
2959         }
2960       else
2961         {
2962           gfc_conv_expr_reference (&se, d->low);
2963
2964           CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
2965           CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
2966         }
2967
2968       if (d->high == NULL)
2969         {
2970           CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
2971           CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], integer_zero_node);
2972         }
2973       else
2974         {
2975           gfc_init_se (&se, NULL);
2976           gfc_conv_expr_reference (&se, d->high);
2977
2978           CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
2979           CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
2980         }
2981
2982       CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
2983                               build_int_cst (integer_type_node, d->n));
2984
2985       tmp = build_constructor (select_struct[k], node);
2986       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
2987     }
2988
2989   type = build_array_type (select_struct[k],
2990                            build_index_type (size_int (n-1)));
2991
2992   init = build_constructor (type, inits);
2993   TREE_CONSTANT (init) = 1;
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;
2998   TREE_STATIC (tmp) = 1;
2999   TREE_READONLY (tmp) = 1;
3000   DECL_INITIAL (tmp) = init;
3001   init = tmp;
3002
3003   /* Build the library call */
3004   init = gfc_build_addr_expr (pvoid_type_node, init);
3005
3006   if (code->expr1->ts.kind == 1)
3007     fndecl = gfor_fndecl_select_string;
3008   else if (code->expr1->ts.kind == 4)
3009     fndecl = gfor_fndecl_select_string_char4;
3010   else
3011     gcc_unreachable ();
3012
3013   tmp = build_call_expr_loc (input_location,
3014                          fndecl, 4, init,
3015                          build_int_cst (gfc_charlen_type_node, n),
3016                          expr1se.expr, expr1se.string_length);
3017   case_num = gfc_create_var (integer_type_node, "case_num");
3018   gfc_add_modify (&block, case_num, tmp);
3019
3020   gfc_add_block_to_block (&block, &expr1se.post);
3021
3022   tmp = gfc_finish_block (&body);
3023   tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
3024                          case_num, tmp, NULL_TREE);
3025   gfc_add_expr_to_block (&block, tmp);
3026
3027   tmp = build1_v (LABEL_EXPR, end_label);
3028   gfc_add_expr_to_block (&block, tmp);
3029
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
3048 tree
3049 gfc_trans_select (gfc_code * code)
3050 {
3051   stmtblock_t block;
3052   tree body;
3053   tree exit_label;
3054
3055   gcc_assert (code && code->expr1);
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;
3061
3062   /* Empty SELECT constructs are legal.  */
3063   if (code->block == NULL)
3064     body = build_empty_stmt (input_location);
3065
3066   /* Select the correct translation function.  */
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
3091   return gfc_finish_block (&block);
3092 }
3093
3094 tree
3095 gfc_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
3120   return gfc_finish_block (&block);
3121 }
3122
3123
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
3133 static gfc_symtree *new_symtree;
3134 static gfc_symtree *old_symtree;
3135
3136 static bool
3137 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
3138 {
3139   if (expr->expr_type != EXPR_VARIABLE)
3140     return false;
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
3150 static void
3151 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
3152 {
3153   gfc_traverse_expr (e, sym, forall_replace, f);
3154 }
3155
3156 static bool
3157 forall_restore (gfc_expr *expr,
3158                 gfc_symbol *sym ATTRIBUTE_UNUSED,
3159                 int *f ATTRIBUTE_UNUSED)
3160 {
3161   if (expr->expr_type != EXPR_VARIABLE)
3162     return false;
3163
3164   if (expr->symtree == new_symtree)
3165     expr->symtree = old_symtree;
3166
3167   return false;
3168 }
3169
3170 static void
3171 forall_restore_symtree (gfc_expr *e)
3172 {
3173   gfc_traverse_expr (e, NULL, forall_restore, 0);
3174 }
3175
3176 static void
3177 forall_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.  */
3188   old_symtree = c->expr1->symtree;
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);
3194       gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
3195       gfc_add_block_to_block (pre, &tse.pre);
3196       gfc_add_block_to_block (post, &tse.post);
3197       tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
3198
3199       if (e->ts.type != BT_CHARACTER)
3200         {
3201           /* Use the variable offset for the temporary.  */
3202           tmp = gfc_conv_array_offset (old_sym->backend_decl);
3203           gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
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
3227       tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
3228                                      e->expr_type == EXPR_VARIABLE, false);
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;
3237   new_sym->attr.temporary = 1;
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.  */
3252   forall_replace_symtree (c->expr1, old_sym, 2);
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.  */
3261 static int
3262 check_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
3269   lsym = c->expr1->symtree->n.sym;
3270   need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
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
3280         && lsym->ts.u.derived->attr.pointer_comp)
3281     return need_temp;
3282
3283   new_symtree = NULL;
3284   if (find_forall_index (c->expr1, lsym, 2))
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.  */
3292   if (c->expr1->ts.type == BT_CHARACTER
3293         && c->expr1->ref
3294         && c->expr2->expr_type == EXPR_VARIABLE
3295         && lsym == c->expr2->symtree->n.sym)
3296     {
3297       for (lref = c->expr1->ref; lref; lref = lref->next)
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
3315 static void
3316 cleanup_forall_symtrees (gfc_code *c)
3317 {
3318   forall_restore_symtree (c->expr1);
3319   forall_restore_symtree (c->expr2);
3320   free (new_symtree->n.sym);
3321   free (new_symtree);
3322 }
3323
3324
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:
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
3344 static tree
3345 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
3346                        int mask_flag, stmtblock_t *outer)
3347 {
3348   int n, nvar;
3349   tree tmp;
3350   tree cond;
3351   stmtblock_t block;
3352   tree exit_label;
3353   tree count;
3354   tree var, start, end, step;
3355   iter_info *iter;
3356
3357   /* Initialize the mask index outside the FORALL nest.  */
3358   if (mask_flag && forall_tmp->mask)
3359     gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
3360
3361   iter = forall_tmp->this_loop;
3362   nvar = forall_tmp->nvar;
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.  */
3380       cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3381                               count, build_int_cst (TREE_TYPE (count), 0));
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
3387       tmp = build1_v (GOTO_EXPR, exit_label);
3388       tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3389                              cond, tmp, build_empty_stmt (input_location));
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.  */
3396       tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3397                              step);
3398       gfc_add_modify (&block, var, tmp);
3399
3400       /* Advance to the next mask element.  Only do this for the
3401          innermost loop.  */
3402       if (n == 0 && mask_flag && forall_tmp->mask)
3403         {
3404           tree maskindex = forall_tmp->maskindex;
3405           tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3406                                  maskindex, gfc_index_one_node);
3407           gfc_add_modify (&block, maskindex, tmp);
3408         }
3409
3410       /* Decrement the loop counter.  */
3411       tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3412                              build_int_cst (TREE_TYPE (var), 1));
3413       gfc_add_modify (&block, count, tmp);
3414
3415       body = gfc_finish_block (&block);
3416
3417       /* Loop var initialization.  */
3418       gfc_init_block (&block);
3419       gfc_add_modify (&block, var, start);
3420
3421
3422       /* Initialize the loop counter.  */
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);
3429       gfc_add_modify (&block, count, tmp);
3430
3431       /* The loop expression.  */
3432       tmp = build1_v (LOOP_EXPR, body);
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
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.  */
3450
3451 static tree
3452 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
3453                               int mask_flag)
3454 {
3455   tree tmp;
3456   stmtblock_t header;
3457   forall_info *forall_tmp;
3458   tree mask, maskindex;
3459
3460   gfc_start_block (&header);
3461
3462   forall_tmp = nested_forall_info;
3463   while (forall_tmp != NULL)
3464     {
3465       /* Generate body with masks' control.  */
3466       if (mask_flag)
3467         {
3468           mask = forall_tmp->mask;
3469           maskindex = forall_tmp->maskindex;
3470
3471           /* If a mask was specified make the assignment conditional.  */
3472           if (mask)
3473             {
3474               tmp = gfc_build_array_ref (mask, maskindex, NULL);
3475               body = build3_v (COND_EXPR, tmp, body,
3476                                build_empty_stmt (input_location));
3477             }
3478         }
3479       body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
3480       forall_tmp = forall_tmp->prev_nest;
3481       mask_flag = 1;
3482     }
3483
3484   gfc_add_expr_to_block (&header, body);
3485   return gfc_finish_block (&header);
3486 }
3487
3488
3489 /* Allocate data for holding a temporary array.  Returns either a local
3490    temporary array or a pointer variable.  */
3491
3492 static tree
3493 gfc_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;
3499
3500   if (INTEGER_CST_P (size))
3501     tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3502                            size, gfc_index_one_node);
3503   else
3504     tmp = NULL_TREE;
3505
3506   type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
3507   type = build_array_type (elem_type, type);
3508   if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
3509     {
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
3518       tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
3519       gfc_add_modify (pblock, tmpvar, tmp);
3520     }
3521   return tmpvar;
3522 }
3523
3524
3525 /* Generate codes to copy the temporary to the actual lhs.  */
3526
3527 static tree
3528 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
3529                                tree count1, tree wheremask, bool invert)
3530 {
3531   gfc_ss *lss;
3532   gfc_se lse, rse;
3533   stmtblock_t block, body;
3534   gfc_loopinfo loop1;
3535   tree tmp;
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.  */
3551       tmp = gfc_build_array_ref (tmp1, count1, NULL);
3552
3553       /* Use the scalar assignment as is.  */
3554       gfc_add_block_to_block (&block, &lse.pre);
3555       gfc_add_modify (&block, lse.expr, tmp);
3556       gfc_add_block_to_block (&block, &lse.post);
3557
3558       /* Increment the count1.  */
3559       tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3560                              count1, gfc_index_one_node);
3561       gfc_add_modify (&block, count1, tmp);
3562
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.  */
3579       gfc_conv_loop_setup (&loop1, &expr->where);
3580
3581       gfc_mark_ss_chain_used (lss, 1);
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)
3592         rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3593       /* Translate expr.  */
3594       gfc_conv_expr (&lse, expr);
3595
3596       /* Use the scalar assignment.  */
3597       rse.string_length = lse.string_length;
3598       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, true);
3599
3600       /* Form the mask expression according to the mask tree list.  */
3601       if (wheremask)
3602         {
3603           wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3604           if (invert)
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));
3611        }
3612
3613       gfc_add_expr_to_block (&body, tmp);
3614
3615       /* Increment count1.  */
3616       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3617                              count1, gfc_index_one_node);
3618       gfc_add_modify (&body, count1, tmp);
3619
3620       /* Increment count3.  */
3621       if (count3)
3622         {
3623           tmp = fold_build2_loc (input_location, PLUS_EXPR,
3624                                  gfc_array_index_type, count3,
3625                                  gfc_index_one_node);
3626           gfc_add_modify (&body, count3, tmp);
3627         }
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
3635       tmp = gfc_finish_block (&block);
3636     }
3637   return tmp;
3638 }
3639
3640
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.  */
3645
3646 static tree
3647 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3648                                tree count1, gfc_ss *lss, gfc_ss *rss,
3649                                tree wheremask, bool invert)
3650 {
3651   stmtblock_t block, body1;
3652   gfc_loopinfo loop;
3653   gfc_se lse;
3654   gfc_se rse;
3655   tree tmp;
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);
3667       lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3668     }
3669   else
3670     {
3671       /* Initialize the loop.  */
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);
3679       gfc_conv_loop_setup (&loop, &expr2->where);
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.  */
3691       lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3692     }
3693
3694   /* Use the scalar assignment.  */
3695   lse.string_length = rse.string_length;
3696   tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
3697                                  expr2->expr_type == EXPR_VARIABLE, false);
3698
3699   /* Form the mask expression according to the mask tree list.  */
3700   if (wheremask)
3701     {
3702       wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3703       if (invert)
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));
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);
3717
3718       /* Increment count1.  */
3719       tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3720                              count1, gfc_index_one_node);
3721       gfc_add_modify (&block, count1, tmp);
3722     }
3723   else
3724     {
3725       /* Increment count1.  */
3726       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3727                              count1, gfc_index_one_node);
3728       gfc_add_modify (&body1, count1, tmp);
3729
3730       /* Increment count3.  */
3731       if (count3)
3732         {
3733           tmp = fold_build2_loc (input_location, PLUS_EXPR,
3734                                  gfc_array_index_type,
3735                                  count3, gfc_index_one_node);
3736           gfc_add_modify (&body1, count3, tmp);
3737         }
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
3747          as tree nodes in SS may not be valid in different scope.  */
3748     }
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
3758 static tree
3759 compute_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;
3766   int save_flag;
3767   tree tmp;
3768
3769   *lss = gfc_walk_expr (expr1);
3770   *rss = NULL;
3771
3772   size = gfc_index_one_node;
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)
3780         /* The rhs is scalar.  Add a ss for the expression.  */
3781         *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
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.  */
3794       save_flag = gfc_option.rtcheck;
3795       gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
3796       gfc_conv_ss_startstride (&loop);
3797       gfc_option.rtcheck = save_flag;
3798       gfc_conv_loop_setup (&loop, &expr2->where);
3799
3800       /* Figure out how many elements we need.  */
3801       for (i = 0; i < loop.dimen; i++)
3802         {
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);
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
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.  */
3830
3831 static tree
3832 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
3833                              stmtblock_t *inner_size_body, stmtblock_t *block)
3834 {
3835   forall_info *forall_tmp = nested_forall_info;
3836   tree tmp, number;
3837   stmtblock_t body;
3838
3839   /* We can eliminate the innermost unconditional loops with constant
3840      array bounds.  */
3841   if (INTEGER_CST_P (inner_size))
3842     {
3843       while (forall_tmp
3844              && !forall_tmp->mask
3845              && INTEGER_CST_P (forall_tmp->size))
3846         {
3847           inner_size = fold_build2_loc (input_location, MULT_EXPR,
3848                                         gfc_array_index_type,
3849                                         inner_size, forall_tmp->size);
3850           forall_tmp = forall_tmp->prev_nest;
3851         }
3852
3853       /* If there are no loops left, we have our constant result.  */
3854       if (!forall_tmp)
3855         return inner_size;
3856     }
3857
3858   /* Otherwise, create a temporary variable to compute the result.  */
3859   number = gfc_create_var (gfc_array_index_type, "num");
3860   gfc_add_modify (block, number, gfc_index_zero_node);
3861
3862   gfc_start_block (&body);
3863   if (inner_size_body)
3864     gfc_add_block_to_block (&body, inner_size_body);
3865   if (forall_tmp)
3866     tmp = fold_build2_loc (input_location, PLUS_EXPR,
3867                            gfc_array_index_type, number, inner_size);
3868   else
3869     tmp = inner_size;
3870   gfc_add_modify (&body, number, tmp);
3871   tmp = gfc_finish_block (&body);
3872
3873   /* Generate loops.  */
3874   if (forall_tmp != NULL)
3875     tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
3876
3877   gfc_add_expr_to_block (block, tmp);
3878
3879   return number;
3880 }
3881
3882
3883 /* Allocate temporary for forall construct.  SIZE is the size of temporary
3884    needed.  PTEMP1 is returned for space free.  */
3885
3886 static tree
3887 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
3888                                  tree * ptemp1)
3889 {
3890   tree bytesize;
3891   tree unit;
3892   tree tmp;
3893
3894   unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
3895   if (!integer_onep (unit))
3896     bytesize = fold_build2_loc (input_location, MULT_EXPR,
3897                                 gfc_array_index_type, size, unit);
3898   else
3899     bytesize = size;
3900
3901   *ptemp1 = NULL;
3902   tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
3903
3904   if (*ptemp1)
3905     tmp = build_fold_indirect_ref_loc (input_location, tmp);
3906   return tmp;
3907 }
3908
3909
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
3914 static tree
3915 allocate_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   */
3960 static void
3961 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
3962                             tree wheremask, bool invert,
3963                             forall_info * nested_forall_info,
3964                             stmtblock_t * block)
3965 {
3966   tree type;
3967   tree inner_size;
3968   gfc_ss *lss, *rss;
3969   tree count, count1;
3970   tree tmp, tmp1;
3971   tree ptemp1;
3972   stmtblock_t inner_size_body;
3973
3974   /* Create vars. count1 is the current iterator number of the nested
3975      forall.  */
3976   count1 = gfc_create_var (gfc_array_index_type, "count1");
3977
3978   /* Count is the wheremask index.  */
3979   if (wheremask)
3980     {
3981       count = gfc_create_var (gfc_array_index_type, "count");
3982       gfc_add_modify (block, count, gfc_index_zero_node);
3983     }
3984   else
3985     count = NULL;
3986
3987   /* Initialize count1.  */
3988   gfc_add_modify (block, count1, gfc_index_zero_node);
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().  */
3992   gfc_init_block (&inner_size_body);
3993   inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
3994                                         &lss, &rss);
3995
3996   /* The type of LHS. Used in function allocate_temp_for_forall_nest */
3997   if (expr1->ts.type == BT_CHARACTER && expr1->ts.u.cl->length)
3998     {
3999       if (!expr1->ts.u.cl->backend_decl)
4000         {
4001           gfc_se tse;
4002           gfc_init_se (&tse, NULL);
4003           gfc_conv_expr (&tse, expr1->ts.u.cl->length);
4004           expr1->ts.u.cl->backend_decl = tse.expr;
4005         }
4006       type = gfc_get_character_type_len (gfc_default_character_kind,
4007                                          expr1->ts.u.cl->backend_decl);
4008     }
4009   else
4010     type = gfc_typenode_for_spec (&expr1->ts);
4011
4012   /* Allocate temporary for nested forall construct according to the
4013      information in nested_forall_info and inner_size.  */
4014   tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
4015                                         &inner_size_body, block, &ptemp1);
4016
4017   /* Generate codes to copy rhs to the temporary .  */
4018   tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
4019                                        wheremask, invert);
4020
4021   /* Generate body and loops according to the information in
4022      nested_forall_info.  */
4023   tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4024   gfc_add_expr_to_block (block, tmp);
4025
4026   /* Reset count1.  */
4027   gfc_add_modify (block, count1, gfc_index_zero_node);
4028
4029   /* Reset count.  */
4030   if (wheremask)
4031     gfc_add_modify (block, count, gfc_index_zero_node);
4032
4033   /* Generate codes to copy the temporary to lhs.  */
4034   tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
4035                                        wheremask, invert);
4036
4037   /* Generate body and loops according to the information in
4038      nested_forall_info.  */
4039   tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4040   gfc_add_expr_to_block (block, tmp);
4041
4042   if (ptemp1)
4043     {
4044       /* Free the temporary.  */
4045       tmp = gfc_call_free (ptemp1);
4046       gfc_add_expr_to_block (block, tmp);
4047     }
4048 }
4049
4050
4051 /* Translate pointer assignment inside FORALL which need temporary.  */
4052
4053 static void
4054 gfc_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;
4063   gfc_array_info *info;
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;
4071
4072   count = gfc_create_var (gfc_array_index_type, "count");
4073   gfc_add_modify (block, count, gfc_index_zero_node);
4074
4075   inner_size = gfc_index_one_node;
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.  */
4085       tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
4086                                             inner_size, NULL, block, &ptemp1);
4087       gfc_start_block (&body);
4088       gfc_init_se (&lse, NULL);
4089       lse.expr = gfc_build_array_ref (tmp1, count, NULL);
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);
4094       gfc_add_modify (&body, lse.expr,
4095                            fold_convert (TREE_TYPE (lse.expr), rse.expr));
4096       gfc_add_block_to_block (&body, &rse.post);
4097
4098       /* Increment count.  */
4099       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4100                              count, gfc_index_one_node);
4101       gfc_add_modify (&body, count, tmp);
4102
4103       tmp = gfc_finish_block (&body);
4104
4105       /* Generate body and loops according to the information in
4106          nested_forall_info.  */
4107       tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4108       gfc_add_expr_to_block (block, tmp);
4109
4110       /* Reset count.  */
4111       gfc_add_modify (block, count, gfc_index_zero_node);
4112
4113       gfc_start_block (&body);
4114       gfc_init_se (&lse, NULL);
4115       gfc_init_se (&rse, NULL);
4116       rse.expr = gfc_build_array_ref (tmp1, count, NULL);
4117       lse.want_pointer = 1;
4118       gfc_conv_expr (&lse, expr1);
4119       gfc_add_block_to_block (&body, &lse.pre);
4120       gfc_add_modify (&body, lse.expr, rse.expr);
4121       gfc_add_block_to_block (&body, &lse.post);
4122       /* Increment count.  */
4123       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4124                              count, gfc_index_one_node);
4125       gfc_add_modify (&body, count, tmp);
4126       tmp = gfc_finish_block (&body);
4127
4128       /* Generate body and loops according to the information in
4129          nested_forall_info.  */
4130       tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
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
4143       gfc_conv_loop_setup (&loop, &expr2->where);
4144
4145       info = &rss->info->data.array;
4146       desc = info->descriptor;
4147
4148       /* Make a new descriptor.  */
4149       parmtype = gfc_get_element_type (TREE_TYPE (desc));
4150       parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
4151                                             loop.from, loop.to, 1,
4152                                             GFC_ARRAY_UNKNOWN, true);
4153
4154       /* Allocate temporary for nested forall construct.  */
4155       tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
4156                                             inner_size, NULL, block, &ptemp1);
4157       gfc_start_block (&body);
4158       gfc_init_se (&lse, NULL);
4159       lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4160       lse.direct_byref = 1;
4161       gfc_conv_expr_descriptor (&lse, expr2);
4162
4163       gfc_add_block_to_block (&body, &lse.pre);
4164       gfc_add_block_to_block (&body, &lse.post);
4165
4166       /* Increment count.  */
4167       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4168                              count, gfc_index_one_node);
4169       gfc_add_modify (&body, count, tmp);
4170
4171       tmp = gfc_finish_block (&body);
4172
4173       /* Generate body and loops according to the information in
4174          nested_forall_info.  */
4175       tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4176       gfc_add_expr_to_block (block, tmp);
4177
4178       /* Reset count.  */
4179       gfc_add_modify (block, count, gfc_index_zero_node);
4180
4181       parm = gfc_build_array_ref (tmp1, count, NULL);
4182       gfc_init_se (&lse, NULL);
4183       gfc_conv_expr_descriptor (&lse, expr1);
4184       gfc_add_modify (&lse.pre, lse.expr, parm);
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.  */
4190       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4191                              count, gfc_index_one_node);
4192       gfc_add_modify (&body, count, tmp);
4193
4194       tmp = gfc_finish_block (&body);
4195
4196       tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4197       gfc_add_expr_to_block (block, tmp);
4198     }
4199   /* Free the temporary.  */
4200   if (ptemp1)
4201     {
4202       tmp = gfc_call_free (ptemp1);
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
4221    (where e,f,g,h<i> are arbitrary expressions possibly involving i)
4222    Translates to:
4223     count = ((end + 1 - start) / stride)
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++])
4236           g<i> = h<i>
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
4242     loop is executed.  This problem is compounded by the presence of nested
4243     FORALL constructs.
4244  */
4245
4246 static tree
4247 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
4248 {
4249   stmtblock_t pre;
4250   stmtblock_t post;
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;
4261   tree maskindex;
4262   tree mask;
4263   tree pmask;
4264   tree cycle_label = NULL_TREE;
4265   int n;
4266   int nvar;
4267   int need_temp;
4268   gfc_forall_iterator *fa;
4269   gfc_se se;
4270   gfc_code *c;
4271   gfc_saved_var *saved_vars;
4272   iter_info *this_forall;
4273   forall_info *info;
4274   bool need_mask;
4275
4276   /* Do nothing if the mask is false.  */
4277   if (code->expr1
4278       && code->expr1->expr_type == EXPR_CONSTANT
4279       && !code->expr1->value.logical)
4280     return build_empty_stmt (input_location);
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.  */
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);
4295
4296   /* Allocate the space for info.  */
4297   info = XCNEW (forall_info);
4298
4299   gfc_start_block (&pre);
4300   gfc_init_block (&post);
4301   gfc_init_block (&block);
4302
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
4308       /* Allocate space for this_forall.  */
4309       this_forall = XCNEW (iter_info);
4310
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);
4314       gfc_shadow_sym (sym, var[n], &saved_vars[n]);
4315
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.  */
4349       if (info->this_loop)
4350         {
4351           iter_info *iter_tmp = info->this_loop;
4352           while (iter_tmp->next != NULL)
4353             iter_tmp = iter_tmp->next;
4354           iter_tmp->next = this_forall;
4355         }
4356       else
4357         info->this_loop = this_forall;
4358
4359       n++;
4360     }
4361   nvar = n;
4362
4363   /* Calculate the size needed for the current forall level.  */
4364   size = gfc_index_one_node;
4365   for (n = 0; n < nvar; n++)
4366     {
4367       /* size = (end + step - start) / step.  */
4368       tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
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]);
4374       tmp = convert (gfc_array_index_type, tmp);
4375
4376       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4377                               size, tmp);
4378     }
4379
4380   /* Record the nvar and size of current forall level.  */
4381   info->nvar = nvar;
4382   info->size = size;
4383
4384   if (code->expr1)
4385     {
4386       /* If the mask is .true., consider the FORALL unconditional.  */
4387       if (code->expr1->expr_type == EXPR_CONSTANT
4388           && code->expr1->value.logical)
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)
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     }
4409   else
4410     {
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.  */
4417   info->prev_nest = nested_forall_info;
4418   nested_forall_info = info;
4419
4420   /* Copy the mask into a temporary variable if required.
4421      For now we assume a mask temporary is needed.  */
4422   if (need_mask)
4423     {
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);
4426
4427       gfc_add_modify (&block, maskindex, gfc_index_zero_node);
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);
4434       gfc_conv_expr_val (&se, code->expr1);
4435       gfc_add_block_to_block (&body, &se.pre);
4436
4437       /* Store the mask.  */
4438       se.expr = convert (mask_type, se.expr);
4439
4440       tmp = gfc_build_array_ref (mask, maskindex, NULL);
4441       gfc_add_modify (&body, tmp, se.expr);
4442
4443       /* Advance to the next mask element.  */
4444       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4445                              maskindex, gfc_index_one_node);
4446       gfc_add_modify (&body, maskindex, tmp);
4447
4448       /* Generate the loops.  */
4449       tmp = gfc_finish_block (&body);
4450       tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
4451       gfc_add_expr_to_block (&block, tmp);
4452     }
4453
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);
4469       nested_forall_info->do_concurrent = true;
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
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:
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
4489           /* Temporaries due to array assignment data dependencies introduce
4490              no end of problems.  */
4491           if (need_temp)
4492             gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
4493                                         nested_forall_info, &block);
4494           else
4495             {
4496               /* Use the normal assignment copying routines.  */
4497               assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
4498
4499               /* Generate body and loops.  */
4500               tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4501                                                   assign, 1);
4502               gfc_add_expr_to_block (&block, tmp);
4503             }
4504
4505           /* Cleanup any temporary symtrees that have been made to deal
4506              with dependencies.  */
4507           if (new_symtree)
4508             cleanup_forall_symtrees (c);
4509
4510           break;
4511
4512         case EXEC_WHERE:
4513           /* Translate WHERE or WHERE construct nested in FORALL.  */
4514           gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
4515           break;
4516
4517         /* Pointer assignment inside FORALL.  */
4518         case EXEC_POINTER_ASSIGN:
4519           need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
4520           if (need_temp)
4521             gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
4522                                                 nested_forall_info, &block);
4523           else
4524             {
4525               /* Use the normal assignment copying routines.  */
4526               assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
4527
4528               /* Generate body and loops.  */
4529               tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4530                                                   assign, 1);
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
4540         /* Explicit subroutine calls are prevented by the frontend but interface
4541            assignments can legitimately produce them.  */
4542         case EXEC_ASSIGN_CALL:
4543           assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
4544           tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
4545           gfc_add_expr_to_block (&block, tmp);
4546           break;
4547
4548         default:
4549           gcc_unreachable ();
4550         }
4551
4552       c = c->next;
4553     }
4554
4555 done:
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]);
4559
4560   /* Free the space for var, start, end, step, varexpr.  */
4561   free (var);
4562   free (start);
4563   free (end);
4564   free (step);
4565   free (varexpr);
4566   free (saved_vars);
4567
4568   for (this_forall = info->this_loop; this_forall;)
4569     {
4570       iter_info *next = this_forall->next;
4571       free (this_forall);
4572       this_forall = next;
4573     }
4574
4575   /* Free the space for this forall_info.  */
4576   free (info);
4577
4578   if (pmask)
4579     {
4580       /* Free the temporary for the mask.  */
4581       tmp = gfc_call_free (pmask);
4582       gfc_add_expr_to_block (&block, tmp);
4583     }
4584   if (maskindex)
4585     pushdecl (maskindex);
4586
4587   gfc_add_block_to_block (&pre, &block);
4588   gfc_add_block_to_block (&pre, &post);
4589
4590   return gfc_finish_block (&pre);
4591 }
4592
4593
4594 /* Translate the FORALL statement or construct.  */
4595
4596 tree gfc_trans_forall (gfc_code * code)
4597 {
4598   return gfc_trans_forall_1 (code, NULL);
4599 }
4600
4601
4602 /* Translate the DO CONCURRENT construct.  */
4603
4604 tree gfc_trans_do_concurrent (gfc_code * code)
4605 {
4606   return gfc_trans_forall_1 (code, NULL);
4607 }
4608
4609
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.
4615    MASK is the current execution mask upon input, whose sense may or may
4616    not be inverted as specified by the INVERT argument.
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.  */
4620
4621 static void
4622 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
4623                          tree mask, bool invert, tree cmask, tree pmask,
4624                          tree mask_type, stmtblock_t * block)
4625 {
4626   tree tmp, tmp1;
4627   gfc_ss *lss, *rss;
4628   gfc_loopinfo loop;
4629   stmtblock_t body, body1;
4630   tree count, cond, mtmp;
4631   gfc_se lse, rse;
4632
4633   gfc_init_loopinfo (&loop);
4634
4635   lss = gfc_walk_expr (me);
4636   rss = gfc_walk_expr (me);
4637
4638   /* Variable to index the temporary.  */
4639   count = gfc_create_var (gfc_array_index_type, "count");
4640   /* Initialize count.  */
4641   gfc_add_modify (block, count, gfc_index_zero_node);
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     {
4654       /* Initialize the loop.  */
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);
4662       gfc_conv_loop_setup (&loop, &me->where);
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     }
4673
4674   /* Variable to evaluate mask condition.  */
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);
4682
4683   gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
4684
4685   if (mask && (cmask || pmask))
4686     {
4687       tmp = gfc_build_array_ref (mask, count, NULL);
4688       if (invert)
4689         tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
4690       gfc_add_modify (&body1, mtmp, tmp);
4691     }
4692
4693   if (cmask)
4694     {
4695       tmp1 = gfc_build_array_ref (cmask, count, NULL);
4696       tmp = cond;
4697       if (mask)
4698         tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4699                                mtmp, tmp);
4700       gfc_add_modify (&body1, tmp1, tmp);
4701     }
4702
4703   if (pmask)
4704     {
4705       tmp1 = gfc_build_array_ref (pmask, count, NULL);
4706       tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
4707       if (mask)
4708         tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4709                                tmp);
4710       gfc_add_modify (&body1, tmp1, tmp);
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)
4717     {
4718       gfc_add_block_to_block (&body, &body1);
4719     }
4720   else
4721     {
4722       /* Increment count.  */
4723       tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4724                               count, gfc_index_one_node);
4725       gfc_add_modify (&body1, count, tmp1);
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)
4741     tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
4742
4743   gfc_add_expr_to_block (block, tmp1);
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
4749    of EXPR1 shall be assigned.  The sense of MASK is specified by
4750    INVERT.  */
4751
4752 static tree
4753 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
4754                         tree mask, bool invert,
4755                         tree count1, tree count2,
4756                         gfc_code *cnext)
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;
4768   tree index, maskexpr;
4769
4770   /* A defined assignment.  */
4771   if (cnext && cnext->resolved_sym)
4772     return gfc_trans_call (cnext, true, mask, count1, invert);
4773
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.  */
4797   gcc_assert (lss != gfc_ss_terminator);
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
4804          && lss_section->info->type != GFC_SS_SECTION)
4805     lss_section = lss_section->next;
4806
4807   gcc_assert (lss_section != gfc_ss_terminator);
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)
4815     {
4816       /* The rhs is scalar.  Add a ss for the expression.  */
4817       rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4818       rss->info->where = 1;
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.  */
4832   gfc_conv_loop_setup (&loop, &expr2->where);
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)
4858     gfc_conv_tmp_array_ref (&lse);
4859   else
4860     gfc_conv_expr (&lse, expr1);
4861
4862   /* Form the mask expression according to the mask.  */
4863   index = count1;
4864   maskexpr = gfc_build_array_ref (mask, index, NULL);
4865   if (invert)
4866     maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4867                                 TREE_TYPE (maskexpr), maskexpr);
4868
4869   /* Use the scalar assignment as is.  */
4870   tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
4871                                  false, loop.temp_ss == NULL);
4872
4873   tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
4874
4875   gfc_add_expr_to_block (&body, tmp);
4876
4877   if (lss == gfc_ss_terminator)
4878     {
4879       /* Increment count1.  */
4880       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4881                              count1, gfc_index_one_node);
4882       gfc_add_modify (&body, count1, tmp);
4883
4884       /* Use the scalar assignment as is.  */
4885       gfc_add_block_to_block (&block, &body);
4886     }
4887   else
4888     {
4889       gcc_assert (lse.ss == gfc_ss_terminator
4890                   && rse.ss == gfc_ss_terminator);
4891
4892       if (loop.temp_ss != NULL)
4893         {
4894           /* Increment count1 before finish the main body of a scalarized
4895              expression.  */
4896           tmp = fold_build2_loc (input_location, PLUS_EXPR,
4897                                  gfc_array_index_type, count1, gfc_index_one_node);
4898           gfc_add_modify (&body, count1, tmp);
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);
4911           gfc_conv_expr (&lse, expr1);
4912
4913           gcc_assert (lse.ss == gfc_ss_terminator
4914                       && rse.ss == gfc_ss_terminator);
4915
4916           /* Form the mask expression according to the mask tree list.  */
4917           index = count2;
4918           maskexpr = gfc_build_array_ref (mask, index, NULL);
4919           if (invert)
4920             maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4921                                         TREE_TYPE (maskexpr), maskexpr);
4922
4923           /* Use the scalar assignment as is.  */
4924           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
4925           tmp = build3_v (COND_EXPR, maskexpr, tmp,
4926                           build_empty_stmt (input_location));
4927           gfc_add_expr_to_block (&body, tmp);
4928
4929           /* Increment count2.  */
4930           tmp = fold_build2_loc (input_location, PLUS_EXPR,
4931                                  gfc_array_index_type, count2,
4932                                  gfc_index_one_node);
4933           gfc_add_modify (&body, count2, tmp);
4934         }
4935       else
4936         {
4937           /* Increment count1.  */
4938           tmp = fold_build2_loc (input_location, PLUS_EXPR,
4939                                  gfc_array_index_type, count1,
4940                                  gfc_index_one_node);
4941           gfc_add_modify (&body, count1, tmp);
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.
4958    This function can be called iteratively to translate the nested WHERE
4959    construct or statement.
4960    MASK is the control mask.  */
4961
4962 static void
4963 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
4964                    forall_info * nested_forall_info, stmtblock_t * block)
4965 {
4966   stmtblock_t inner_size_body;
4967   tree inner_size, size;
4968   gfc_ss *lss, *rss;
4969   tree mask_type;
4970   gfc_expr *expr1;
4971   gfc_expr *expr2;
4972   gfc_code *cblock;
4973   gfc_code *cnext;
4974   tree tmp;
4975   tree cond;
4976   tree count1, count2;
4977   bool need_cmask;
4978   bool need_pmask;
4979   int need_temp;
4980   tree pcmask = NULL_TREE;
4981   tree ppmask = NULL_TREE;
4982   tree cmask = NULL_TREE;
4983   tree pmask = NULL_TREE;
4984   gfc_actual_arglist *arg;
4985
4986   /* the WHERE statement or the WHERE construct statement.  */
4987   cblock = code->block;
4988
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
4992   /* Determine which temporary masks are needed.  */
4993   if (!cblock->block)
4994     {
4995       /* One clause: No ELSEWHEREs.  */
4996       need_cmask = (cblock->next != 0);
4997       need_pmask = false;
4998     }
4999   else if (cblock->block->block)
5000     {
5001       /* Three or more clauses: Conditional ELSEWHEREs.  */
5002       need_cmask = true;
5003       need_pmask = true;
5004     }
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)
5013     {
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     {
5021       need_cmask = (cblock->block->expr1 != 0);
5022       need_pmask = true;
5023     }
5024   else
5025     {
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);
5034       inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
5035                                             &inner_size_body, &lss, &rss);
5036
5037       gfc_free_ss_chain (lss);
5038       gfc_free_ss_chain (rss);
5039
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
5044       /* Check whether the size is negative.  */
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);
5049       size = gfc_evaluate_now (size, block);
5050
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);
5060     }
5061
5062   while (cblock)
5063     {
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
5068       /* Has mask-expr.  */
5069       if (cblock->expr1)
5070         {
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
5075              we don't need to update the pending control mask (pmask).  */
5076           if (mask)
5077             gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5078                                      mask, invert,
5079                                      cblock->next  ? cmask : NULL_TREE,
5080                                      cblock->block ? pmask : NULL_TREE,
5081                                      mask_type, block);
5082           else
5083             gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5084                                      NULL_TREE, false,
5085                                      (cblock->next || cblock->block)
5086                                      ? cmask : NULL_TREE,
5087                                      NULL_TREE, mask_type, block);
5088
5089           invert = false;
5090         }
5091       /* It's a final elsewhere-stmt. No mask-expr is present.  */
5092       else
5093         cmask = mask;
5094
5095       /* The body of this where clause are controlled by cmask with
5096          sense specified by invert.  */
5097
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.  */
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
5121             case EXEC_ASSIGN:
5122               expr1 = cnext->expr1;
5123               expr2 = cnext->expr2;
5124     evaluate:
5125               if (nested_forall_info != NULL)
5126                 {
5127                   need_temp = gfc_check_dependency (expr1, expr2, 0);
5128                   if (need_temp && cnext->op != EXEC_ASSIGN_CALL)
5129                     gfc_trans_assign_need_temp (expr1, expr2,
5130                                                 cmask, invert,
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");
5137                       gfc_add_modify (block, count1, gfc_index_zero_node);
5138                       gfc_add_modify (block, count2, gfc_index_zero_node);
5139
5140                       tmp = gfc_trans_where_assign (expr1, expr2,
5141                                                     cmask, invert,
5142                                                     count1, count2,
5143                                                     cnext);
5144
5145                       tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5146                                                           tmp, 1);
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");
5155                   gfc_add_modify (block, count1, gfc_index_zero_node);
5156                   gfc_add_modify (block, count2, gfc_index_zero_node);
5157
5158                   tmp = gfc_trans_where_assign (expr1, expr2,
5159                                                 cmask, invert,
5160                                                 count1, count2,
5161                                                 cnext);
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:
5169               gfc_trans_where_2 (cnext, cmask, invert,
5170                                  nested_forall_info, block);
5171               break;
5172
5173             default:
5174               gcc_unreachable ();
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;
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       }
5196   }
5197
5198   /* If we allocated a pending mask array, deallocate it now.  */
5199   if (ppmask)
5200     {
5201       tmp = gfc_call_free (ppmask);
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     {
5208       tmp = gfc_call_free (pcmask);
5209       gfc_add_expr_to_block (block, tmp);
5210     }
5211 }
5212
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
5218 static tree
5219 gfc_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;
5229   bool maybe_workshare = false;
5230
5231   /* Allow the scalarizer to workshare simple where loops.  */
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     }
5238
5239   cond = cblock->expr1;
5240   tdst = cblock->next->expr1;
5241   tsrc = cblock->next->expr2;
5242   edst = eblock ? eblock->next->expr1 : NULL;
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     {
5260       tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
5261       tsss->info->where = 1;
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         {
5275           esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
5276           esss->info->where = 1;
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);
5283   gfc_conv_loop_setup (&loop, &tdst->where);
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)
5316     gfc_conv_tmp_array_ref (&tdse);
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)
5324         gfc_conv_tmp_array_ref (&edse);
5325       else
5326         gfc_conv_expr (&edse, edst);
5327     }
5328
5329   tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
5330   estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
5331                                             false, true)
5332                  : build_empty_stmt (input_location);
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
5337   if (maybe_workshare)
5338     ompws_flags &= ~OMPWS_SCALARIZER_BODY;
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 }
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
5349    NULL values for both the control mask and the pending control mask.  */
5350
5351 tree
5352 gfc_trans_where (gfc_code * code)
5353 {
5354   stmtblock_t block;
5355   gfc_code *cblock;
5356   gfc_code *eblock;
5357
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.  */
5369           if (!gfc_check_dependency (cblock->next->expr1,
5370                                      cblock->expr1, 0)
5371               && !gfc_check_dependency (cblock->next->expr1,
5372                                         cblock->next->expr2, 0))
5373             return gfc_trans_where_3 (cblock, NULL);
5374         }
5375       else if (!eblock->expr1
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
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.  */
5391           if (!gfc_check_dependency (cblock->next->expr1,
5392                                     cblock->expr1, 0)
5393               && !gfc_check_dependency (eblock->next->expr1,
5394                                        cblock->expr1, 0)
5395               && !gfc_check_dependency (cblock->next->expr1,
5396                                        eblock->next->expr2, 1)
5397               && !gfc_check_dependency (eblock->next->expr1,
5398                                        cblock->next->expr2, 1)
5399               && !gfc_check_dependency (cblock->next->expr1,
5400                                        cblock->next->expr2, 1)
5401               && !gfc_check_dependency (eblock->next->expr1,
5402                                        eblock->next->expr2, 1)
5403               && !gfc_check_dependency (cblock->next->expr1,
5404                                        eblock->next->expr1, 0)
5405               && !gfc_check_dependency (eblock->next->expr1,
5406                                        cblock->next->expr1, 0))
5407             return gfc_trans_where_3 (cblock, eblock);
5408         }
5409     }
5410
5411   gfc_start_block (&block);
5412
5413   gfc_trans_where_2 (code, NULL, false, NULL, &block);
5414
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
5423 tree
5424 gfc_trans_cycle (gfc_code * code)
5425 {
5426   tree cycle_label;
5427
5428   cycle_label = code->ext.which_construct->cycle_label;
5429   gcc_assert (cycle_label);
5430
5431   TREE_USED (cycle_label) = 1;
5432   return build1_v (GOTO_EXPR, cycle_label);
5433 }
5434
5435
5436 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
5437    TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5438    loop.  */
5439
5440 tree
5441 gfc_trans_exit (gfc_code * code)
5442 {
5443   tree exit_label;
5444
5445   exit_label = code->ext.which_construct->exit_label;
5446   gcc_assert (exit_label);
5447
5448   TREE_USED (exit_label) = 1;
5449   return build1_v (GOTO_EXPR, exit_label);
5450 }
5451
5452
5453 /* Get the initializer expression for the code and expr of an allocate.
5454    When no initializer is needed return NULL.  */
5455
5456 static gfc_expr *
5457 allocate_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
5481 /* Translate the ALLOCATE statement.  */
5482
5483 tree
5484 gfc_trans_allocate (gfc_code * code)
5485 {
5486   gfc_alloc *al;
5487   gfc_expr *expr, *e3rhs = NULL, *init_expr;
5488   gfc_se se, se_sz;
5489   tree tmp;
5490   tree parm;
5491   tree stat;
5492   tree errmsg;
5493   tree errlen;
5494   tree label_errmsg;
5495   tree label_finish;
5496   tree memsz;
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;
5504   /* Classify what expr3 stores.  */
5505   enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
5506   stmtblock_t block;
5507   stmtblock_t post;
5508   tree nelems;
5509   bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray ;
5510   gfc_symtree *newsym = NULL;
5511
5512   if (!code->ext.alloc.list)
5513     return NULL_TREE;
5514
5515   stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5516   expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
5517   label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
5518   e3_is = E3_UNSET;
5519   is_coarray = false;
5520
5521   gfc_init_block (&block);
5522   gfc_init_block (&post);
5523
5524   /* STAT= (and maybe ERRMSG=) is present.  */
5525   if (code->expr1)
5526     {
5527       /* STAT=.  */
5528       tree gfc_int4_type_node = gfc_get_int_type (4);
5529       stat = gfc_create_var (gfc_int4_type_node, "stat");
5530
5531       /* ERRMSG= only makes sense with STAT=.  */
5532       if (code->expr2)
5533         {
5534           gfc_init_se (&se, NULL);
5535           se.want_pointer = 1;
5536           gfc_conv_expr_lhs (&se, code->expr2);
5537           errmsg = se.expr;
5538           errlen = se.string_length;
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);
5549       TREE_USED (label_finish) = 0;
5550     }
5551
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.  */
5557   if (code->expr3)
5558     {
5559       bool vtab_needed = false, temp_var_needed = false;
5560
5561       is_coarray = gfc_is_coarray (code->expr3);
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
5568       gfc_init_se (&se, NULL);
5569       /* When expr3 is a variable, i.e., a very simple expression,
5570              then convert it once here.  */
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
5577               || vtab_needed
5578               || code->ext.alloc.arr_spec_from_expr3)
5579             {
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)
5584                 gfc_conv_expr_descriptor (&se, code->expr3);
5585               else
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
5595                       && (TREE_CODE (TREE_OPERAND (se.expr, 0))
5596                                                             == POINTER_PLUS_EXPR
5597                           || is_coarray))
5598                     se.expr = TREE_OPERAND (se.expr, 0);
5599                 }
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;
5604             }
5605         }
5606       else
5607         {
5608           /* In all other cases evaluate the expr3.  */
5609           symbol_attribute attr;
5610           /* Get the descriptor for all arrays, that are not allocatable or
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.  */
5616           attr = gfc_expr_attr (code->expr3);
5617           if (code->expr3->rank != 0
5618               && ((!attr.allocatable && !attr.pointer)
5619                   || (code->expr3->expr_type == EXPR_FUNCTION
5620                       && (code->expr3->ts.type != BT_CLASS
5621                           || (code->expr3->value.function.isym
5622                               && code->expr3->value.function.isym
5623                                                          ->transformational)))))
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);
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);
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;
5643           expr3_len = integer_zero_node;
5644           e3_is = E3_MOLD;
5645         }
5646       /* Prevent aliasing, i.e., se.expr may be already a
5647              variable declaration.  */
5648       else if (se.expr != NULL_TREE && temp_var_needed)
5649         {
5650           tree var, desc;
5651           tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) || is_coarray ?
5652                 se.expr
5653               : build_fold_indirect_ref_loc (input_location, se.expr);
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.  */
5664               if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5665                 {
5666                   desc = TREE_OPERAND (tmp, 0);
5667                 }
5668               else
5669                 {
5670                   desc = tmp;
5671                   tmp = gfc_class_data_get (tmp);
5672                 }
5673               if (code->ext.alloc.arr_spec_from_expr3)
5674                 e3_is = E3_DESC;
5675             }
5676           else
5677             desc = !is_coarray ? se.expr
5678                                : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
5679           /* We need a regular (non-UID) symbol here, therefore give a
5680              prefix.  */
5681           var = gfc_create_var (TREE_TYPE (tmp), "source");
5682           if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5683             {
5684               gfc_allocate_lang_decl (var);
5685               GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
5686             }
5687           gfc_add_modify_loc (input_location, &block, var, tmp);
5688
5689           expr3 = var;
5690           if (se.string_length)
5691             /* Evaluate it assuming that it also is complicated like expr3.  */
5692             expr3_len = gfc_evaluate_now (se.string_length, &block);
5693         }
5694       else
5695         {
5696           expr3 = se.expr;
5697           expr3_len = se.string_length;
5698         }
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
5713       /* Store what the expr3 is to be used for.  */
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;
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;
5728           tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
5729                 build_fold_indirect_ref (expr3): expr3;
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.  */
5733           if (tmp != NULL_TREE
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))))
5738             tmp = gfc_class_vptr_get (expr3);
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)
5758                 expr3_len = gfc_class_len_get (expr3);
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;
5779
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);
5813       if (e3_is == E3_MOLD)
5814         /* The expr3 is no longer valid after this point.  */
5815         expr3 = NULL_TREE;
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);
5835           gfc_add_block_to_block (&block, &se_sz.pre);
5836           expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
5837                                          TREE_TYPE (se_sz.expr),
5838                                          tmp, se_sz.expr);
5839           expr3_esize = gfc_evaluate_now (expr3_esize, &block);
5840         }
5841     }
5842
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
5932   /* Loop over all objects to allocate.  */
5933   for (al = code->ext.alloc.list; al != NULL; al = al->next)
5934     {
5935       expr = gfc_copy_expr (al->expr);
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);
5944
5945       /* For class types prepare the expressions to ref the _vptr
5946          and the _len component.  The latter for unlimited polymorphic
5947          types only.  */
5948       if (expr->ts.type == BT_CLASS)
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;
5977
5978       se.want_pointer = 1;
5979       se.descriptor_only = 1;
5980
5981       gfc_conv_expr (&se, expr);
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.  */
5995       nelems = NULL_TREE;
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,
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))
6012         {
6013           /* A scalar or derived type.  First compute the size to
6014              allocate.
6015
6016              expr3_len is set when expr3 is an unlimited polymorphic
6017              object or a deferred length string.  */
6018           if (expr3_len != NULL_TREE)
6019             {
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;
6028               else
6029                 {
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,
6039                                            integer_zero_node);
6040                   memsz = fold_build3_loc (input_location, COND_EXPR,
6041                                          TREE_TYPE (expr3_esize),
6042                                          memsz, tmp, expr3_esize);
6043                 }
6044             }
6045           else if (expr3_esize != NULL_TREE)
6046             /* Any other object in expr3 just needs element size in
6047                bytes.  */
6048             memsz = expr3_esize;
6049           else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6050                    || (upoly_expr
6051                        && code->ext.alloc.ts.type == BT_CHARACTER))
6052             {
6053               /* Allocating deferred length char arrays need the length
6054                  to allocate in the alloc_type_spec.  But also unlimited
6055                  polymorphic objects may be allocated as char arrays.
6056                  Both are handled here.  */
6057               gfc_init_se (&se_sz, NULL);
6058               gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6059               gfc_add_block_to_block (&se.pre, &se_sz.pre);
6060               se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
6061               gfc_add_block_to_block (&se.pre, &se_sz.post);
6062               expr3_len = se_sz.expr;
6063               tmp_expr3_len_flag = true;
6064               tmp = TYPE_SIZE_UNIT (
6065                     gfc_get_char_type (code->ext.alloc.ts.kind));
6066               memsz = fold_build2_loc (input_location, MULT_EXPR,
6067                                        TREE_TYPE (tmp),
6068                                        fold_convert (TREE_TYPE (tmp),
6069                                                      expr3_len),
6070                                        tmp);
6071             }
6072           else if (expr->ts.type == BT_CHARACTER)
6073             {
6074               /* Compute the number of bytes needed to allocate a fixed
6075                  length char array.  */
6076               gcc_assert (se.string_length != NULL_TREE);
6077               tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
6078               memsz = fold_build2_loc (input_location, MULT_EXPR,
6079                                        TREE_TYPE (tmp), tmp,
6080                                        fold_convert (TREE_TYPE (tmp),
6081                                                      se.string_length));
6082             }
6083           else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6084             /* Handle all types, where the alloc_type_spec is set.  */
6085             memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
6086           else
6087             /* Handle size computation of the type declared to alloc.  */
6088             memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
6089
6090           if (gfc_caf_attr (expr).codimension
6091               && flag_coarray == GFC_FCOARRAY_LIB)
6092             {
6093               /* Scalar allocatable components in coarray'ed derived types make
6094                  it here and are treated now.  */
6095               tree caf_decl, token;
6096               gfc_se caf_se;
6097
6098               /* Set flag, to add synchronize after the allocate.  */
6099               is_coarray = true;
6100
6101               gfc_init_se (&caf_se, NULL);
6102
6103               caf_decl = gfc_get_tree_for_caf_expr (expr);
6104               gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl,
6105                                         NULL_TREE, NULL);
6106               gfc_add_block_to_block (&se.pre, &caf_se.pre);
6107               gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6108                                         gfc_build_addr_expr (NULL_TREE, token),
6109                                         NULL_TREE, NULL_TREE, NULL_TREE,
6110                                         label_finish, expr, 1);
6111             }
6112           /* Allocate - for non-pointers with re-alloc checking.  */
6113           else if (gfc_expr_attr (expr).allocatable)
6114             gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6115                                       NULL_TREE, stat, errmsg, errlen,
6116                                       label_finish, expr, 0);
6117           else
6118             gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
6119         }
6120       else
6121         {
6122           /* Allocating coarrays needs a sync after the allocate executed.
6123              Set the flag to add the sync after all objects are allocated.  */
6124           is_coarray = is_coarray || (gfc_caf_attr (expr).codimension
6125                                       && flag_coarray == GFC_FCOARRAY_LIB);
6126
6127           if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6128               && expr3_len != NULL_TREE)
6129             {
6130               /* Arrays need to have a _len set before the array
6131                  descriptor is filled.  */
6132               gfc_add_modify (&block, al_len,
6133                               fold_convert (TREE_TYPE (al_len), expr3_len));
6134               /* Prevent setting the length twice.  */
6135               al_len_needs_set = false;
6136             }
6137           else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6138               && code->ext.alloc.ts.u.cl->length)
6139             {
6140               /* Cover the cases where a string length is explicitly
6141                  specified by a type spec for deferred length character
6142                  arrays or unlimited polymorphic objects without a
6143                  source= or mold= expression.  */
6144               gfc_init_se (&se_sz, NULL);
6145               gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6146               gfc_add_block_to_block (&block, &se_sz.pre);
6147               gfc_add_modify (&block, al_len,
6148                               fold_convert (TREE_TYPE (al_len),
6149                                             se_sz.expr));
6150               al_len_needs_set = false;
6151             }
6152         }
6153
6154       gfc_add_block_to_block (&block, &se.pre);
6155
6156       /* Error checking -- Note: ERRMSG only makes sense with STAT.  */
6157       if (code->expr1)
6158         {
6159           tmp = build1_v (GOTO_EXPR, label_errmsg);
6160           parm = fold_build2_loc (input_location, NE_EXPR,
6161                                   boolean_type_node, stat,
6162                                   build_int_cst (TREE_TYPE (stat), 0));
6163           tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6164                                  gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
6165                                  tmp, build_empty_stmt (input_location));
6166           gfc_add_expr_to_block (&block, tmp);
6167         }
6168
6169       /* Set the vptr only when no source= is set.  When source= is set, then
6170          the trans_assignment below will set the vptr.  */
6171       if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold))
6172         {
6173           if (expr3_vptr != NULL_TREE)
6174             /* The vtab is already known, so just assign it.  */
6175             gfc_add_modify (&block, al_vptr,
6176                             fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
6177           else
6178             {
6179               /* VPTR is fixed at compile time.  */
6180               gfc_symbol *vtab;
6181               gfc_typespec *ts;
6182
6183               if (code->expr3)
6184                 /* Although expr3 is pre-evaluated above, it may happen,
6185                    that for arrays or in mold= cases the pre-evaluation
6186                    was not successful.  In these rare cases take the vtab
6187                    from the typespec of expr3 here.  */
6188                 ts = &code->expr3->ts;
6189               else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
6190                 /* The alloc_type_spec gives the type to allocate or the
6191                    al is unlimited polymorphic, which enforces the use of
6192                    an alloc_type_spec that is not necessarily a BT_DERIVED.  */
6193                 ts = &code->ext.alloc.ts;
6194               else
6195                 /* Prepare for setting the vtab as declared.  */
6196                 ts = &expr->ts;
6197
6198               vtab = gfc_find_vtab (ts);
6199               gcc_assert (vtab);
6200               tmp = gfc_build_addr_expr (NULL_TREE,
6201                                          gfc_get_symbol_decl (vtab));
6202               gfc_add_modify (&block, al_vptr,
6203                               fold_convert (TREE_TYPE (al_vptr), tmp));
6204             }
6205         }
6206
6207       /* Add assignment for string length.  */
6208       if (al_len != NULL_TREE && al_len_needs_set)
6209         {
6210           if (expr3_len != NULL_TREE)
6211             {
6212               gfc_add_modify (&block, al_len,
6213                               fold_convert (TREE_TYPE (al_len),
6214                                             expr3_len));
6215               /* When tmp_expr3_len_flag is set, then expr3_len is
6216                  abused to carry the length information from the
6217                  alloc_type.  Clear it to prevent setting incorrect len
6218                  information in future loop iterations.  */
6219               if (tmp_expr3_len_flag)
6220                 /* No need to reset tmp_expr3_len_flag, because the
6221                    presence of an expr3 can not change within in the
6222                    loop.  */
6223                 expr3_len = NULL_TREE;
6224             }
6225           else if (code->ext.alloc.ts.type == BT_CHARACTER
6226               && code->ext.alloc.ts.u.cl->length)
6227             {
6228               /* Cover the cases where a string length is explicitly
6229                  specified by a type spec for deferred length character
6230                  arrays or unlimited polymorphic objects without a
6231                  source= or mold= expression.  */
6232               if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
6233                 {
6234                   gfc_init_se (&se_sz, NULL);
6235                   gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6236                   gfc_add_block_to_block (&block, &se_sz.pre);
6237                   gfc_add_modify (&block, al_len,
6238                                   fold_convert (TREE_TYPE (al_len),
6239                                                 se_sz.expr));
6240                 }
6241               else
6242                 gfc_add_modify (&block, al_len,
6243                                 fold_convert (TREE_TYPE (al_len),
6244                                               expr3_esize));
6245             }
6246           else
6247             /* No length information needed, because type to allocate
6248                has no length.  Set _len to 0.  */
6249             gfc_add_modify (&block, al_len,
6250                             fold_convert (TREE_TYPE (al_len),
6251                                           integer_zero_node));
6252         }
6253
6254       init_expr = NULL;
6255       if (code->expr3 && !code->expr3->mold && e3_is != E3_MOLD)
6256         {
6257           /* Initialization via SOURCE block (or static default initializer).
6258              Switch off automatic reallocation since we have just done the
6259              ALLOCATE.  */
6260           int realloc_lhs = flag_realloc_lhs;
6261           gfc_expr *init_expr = gfc_expr_to_initialize (expr);
6262           gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
6263           flag_realloc_lhs = 0;
6264           tmp = gfc_trans_assignment (init_expr, rhs, false, false, true,
6265                                       false);
6266           flag_realloc_lhs = realloc_lhs;
6267           /* Free the expression allocated for init_expr.  */
6268           gfc_free_expr (init_expr);
6269           if (rhs != e3rhs)
6270             gfc_free_expr (rhs);
6271           gfc_add_expr_to_block (&block, tmp);
6272         }
6273       else if (code->expr3 && code->expr3->mold
6274                && code->expr3->ts.type == BT_CLASS)
6275         {
6276           /* Use class_init_assign to initialize expr.  */
6277           gfc_code *ini;
6278           ini = gfc_get_code (EXEC_INIT_ASSIGN);
6279           ini->expr1 = gfc_find_and_cut_at_last_class_ref (expr);
6280           tmp = gfc_trans_class_init_assign (ini);
6281           gfc_free_statements (ini);
6282           gfc_add_expr_to_block (&block, tmp);
6283         }
6284       else if ((init_expr = allocate_get_initializer (code, expr)))
6285         {
6286           /* Use class_init_assign to initialize expr.  */
6287           gfc_code *ini;
6288           int realloc_lhs = flag_realloc_lhs;
6289           ini = gfc_get_code (EXEC_INIT_ASSIGN);
6290           ini->expr1 = gfc_expr_to_initialize (expr);
6291           ini->expr2 = init_expr;
6292           flag_realloc_lhs = 0;
6293           tmp= gfc_trans_init_assign (ini);
6294           flag_realloc_lhs = realloc_lhs;
6295           gfc_free_statements (ini);
6296           /* Init_expr is freeed by above free_statements, just need to null
6297              it here.  */
6298           init_expr = NULL;
6299           gfc_add_expr_to_block (&block, tmp);
6300         }
6301
6302       /* Nullify all pointers in derived type coarrays.  This registers a
6303          token for them which allows their allocation.  */
6304       if (is_coarray)
6305         {
6306           gfc_symbol *type = NULL;
6307           symbol_attribute caf_attr;
6308           int rank = 0;
6309           if (code->ext.alloc.ts.type == BT_DERIVED
6310               && code->ext.alloc.ts.u.derived->attr.pointer_comp)
6311             {
6312               type = code->ext.alloc.ts.u.derived;
6313               rank = type->attr.dimension ? type->as->rank : 0;
6314               gfc_clear_attr (&caf_attr);
6315             }
6316           else if (expr->ts.type == BT_DERIVED
6317                    && expr->ts.u.derived->attr.pointer_comp)
6318             {
6319               type = expr->ts.u.derived;
6320               rank = expr->rank;
6321               caf_attr = gfc_caf_attr (expr, true);
6322             }
6323
6324           /* Initialize the tokens of pointer components in derived type
6325              coarrays.  */
6326           if (type)
6327             {
6328               tmp = (caf_attr.codimension && !caf_attr.dimension)
6329                   ? gfc_conv_descriptor_data_get (se.expr) : se.expr;
6330               tmp = gfc_nullify_alloc_comp (type, tmp, rank,
6331                                             GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
6332               gfc_add_expr_to_block (&block, tmp);
6333             }
6334         }
6335
6336       gfc_free_expr (expr);
6337     } // for-loop
6338
6339   if (e3rhs)
6340     {
6341       if (newsym)
6342         {
6343           gfc_free_symbol (newsym->n.sym);
6344           XDELETE (newsym);
6345         }
6346       gfc_free_expr (e3rhs);
6347     }
6348   /* STAT.  */
6349   if (code->expr1)
6350     {
6351       tmp = build1_v (LABEL_EXPR, label_errmsg);
6352       gfc_add_expr_to_block (&block, tmp);
6353     }
6354
6355   /* ERRMSG - only useful if STAT is present.  */
6356   if (code->expr1 && code->expr2)
6357     {
6358       const char *msg = "Attempt to allocate an allocated object";
6359       tree slen, dlen, errmsg_str;
6360       stmtblock_t errmsg_block;
6361
6362       gfc_init_block (&errmsg_block);
6363
6364       errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6365       gfc_add_modify (&errmsg_block, errmsg_str,
6366                 gfc_build_addr_expr (pchar_type_node,
6367                         gfc_build_localized_cstring_const (msg)));
6368
6369       slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6370       dlen = gfc_get_expr_charlen (code->expr2);
6371       slen = fold_build2_loc (input_location, MIN_EXPR,
6372                               TREE_TYPE (slen), dlen, slen);
6373
6374       gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
6375                              code->expr2->ts.kind,
6376                              slen, errmsg_str,
6377                              gfc_default_character_kind);
6378       dlen = gfc_finish_block (&errmsg_block);
6379
6380       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6381                              stat, build_int_cst (TREE_TYPE (stat), 0));
6382
6383       tmp = build3_v (COND_EXPR, tmp,
6384                       dlen, build_empty_stmt (input_location));
6385
6386       gfc_add_expr_to_block (&block, tmp);
6387     }
6388
6389   /* STAT block.  */
6390   if (code->expr1)
6391     {
6392       if (TREE_USED (label_finish))
6393         {
6394           tmp = build1_v (LABEL_EXPR, label_finish);
6395           gfc_add_expr_to_block (&block, tmp);
6396         }
6397
6398       gfc_init_se (&se, NULL);
6399       gfc_conv_expr_lhs (&se, code->expr1);
6400       tmp = convert (TREE_TYPE (se.expr), stat);
6401       gfc_add_modify (&block, se.expr, tmp);
6402     }
6403
6404   if (is_coarray && flag_coarray == GFC_FCOARRAY_LIB)
6405     {
6406       /* Add a sync all after the allocation has been executed.  */
6407       tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
6408                                  3, null_pointer_node, null_pointer_node,
6409                                  integer_zero_node);
6410       gfc_add_expr_to_block (&post, tmp);
6411     }
6412
6413   gfc_add_block_to_block (&block, &se.post);
6414   gfc_add_block_to_block (&block, &post);
6415
6416   return gfc_finish_block (&block);
6417 }
6418
6419
6420 /* Translate a DEALLOCATE statement.  */
6421
6422 tree
6423 gfc_trans_deallocate (gfc_code *code)
6424 {
6425   gfc_se se;
6426   gfc_alloc *al;
6427   tree apstat, pstat, stat, errmsg, errlen, tmp;
6428   tree label_finish, label_errmsg;
6429   stmtblock_t block;
6430
6431   pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
6432   label_finish = label_errmsg = NULL_TREE;
6433
6434   gfc_start_block (&block);
6435
6436   /* Count the number of failed deallocations.  If deallocate() was
6437      called with STAT= , then set STAT to the count.  If deallocate
6438      was called with ERRMSG, then set ERRMG to a string.  */
6439   if (code->expr1)
6440     {
6441       tree gfc_int4_type_node = gfc_get_int_type (4);
6442
6443       stat = gfc_create_var (gfc_int4_type_node, "stat");
6444       pstat = gfc_build_addr_expr (NULL_TREE, stat);
6445
6446       /* GOTO destinations.  */
6447       label_errmsg = gfc_build_label_decl (NULL_TREE);
6448       label_finish = gfc_build_label_decl (NULL_TREE);
6449       TREE_USED (label_finish) = 0;
6450     }
6451
6452   /* Set ERRMSG - only needed if STAT is available.  */
6453   if (code->expr1 && code->expr2)
6454     {
6455       gfc_init_se (&se, NULL);
6456       se.want_pointer = 1;
6457       gfc_conv_expr_lhs (&se, code->expr2);
6458       errmsg = se.expr;
6459       errlen = se.string_length;
6460     }
6461
6462   for (al = code->ext.alloc.list; al != NULL; al = al->next)
6463     {
6464       gfc_expr *expr = gfc_copy_expr (al->expr);
6465       bool is_coarray = false, is_coarray_array = false;
6466       int caf_mode = 0;
6467
6468       gcc_assert (expr->expr_type == EXPR_VARIABLE);
6469
6470       if (expr->ts.type == BT_CLASS)
6471         gfc_add_data_component (expr);
6472
6473       gfc_init_se (&se, NULL);
6474       gfc_start_block (&se.pre);
6475
6476       se.want_pointer = 1;
6477       se.descriptor_only = 1;
6478       gfc_conv_expr (&se, expr);
6479
6480       if (flag_coarray == GFC_FCOARRAY_LIB
6481           || flag_coarray == GFC_FCOARRAY_SINGLE)
6482         {
6483           bool comp_ref;
6484           symbol_attribute caf_attr = gfc_caf_attr (expr, false, &comp_ref);
6485           if (caf_attr.codimension)
6486             {
6487               is_coarray = true;
6488               is_coarray_array = caf_attr.dimension || !comp_ref
6489                   || caf_attr.coarray_comp;
6490
6491               if (flag_coarray == GFC_FCOARRAY_LIB)
6492                 /* When the expression to deallocate is referencing a
6493                    component, then only deallocate it, but do not
6494                    deregister.  */
6495                 caf_mode = GFC_STRUCTURE_CAF_MODE_IN_COARRAY
6496                     | (comp_ref && !caf_attr.coarray_comp
6497                        ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0);
6498             }
6499         }
6500
6501       if (expr->rank || is_coarray_array)
6502         {
6503           gfc_ref *ref;
6504
6505           if (gfc_bt_struct (expr->ts.type)
6506               && expr->ts.u.derived->attr.alloc_comp
6507               && !gfc_is_finalizable (expr->ts.u.derived, NULL))
6508             {
6509               gfc_ref *last = NULL;
6510
6511               for (ref = expr->ref; ref; ref = ref->next)
6512                 if (ref->type == REF_COMPONENT)
6513                   last = ref;
6514
6515               /* Do not deallocate the components of a derived type
6516                  ultimate pointer component.  */
6517               if (!(last && last->u.c.component->attr.pointer)
6518                     && !(!last && expr->symtree->n.sym->attr.pointer))
6519                 {
6520                   if (is_coarray && expr->rank == 0
6521                       && (!last || !last->u.c.component->attr.dimension)
6522                       && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6523                     {
6524                       /* Add the ref to the data member only, when this is not
6525                          a regular array or deallocate_alloc_comp will try to
6526                          add another one.  */
6527                       tmp = gfc_conv_descriptor_data_get (se.expr);
6528                     }
6529                   else
6530                     tmp = se.expr;
6531                   tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp,
6532                                                    expr->rank, caf_mode);
6533                   gfc_add_expr_to_block (&se.pre, tmp);
6534                 }
6535             }
6536
6537           if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6538             {
6539               gfc_coarray_deregtype caf_dtype;
6540
6541               if (is_coarray)
6542                 caf_dtype = gfc_caf_is_dealloc_only (caf_mode)
6543                     ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
6544                     : GFC_CAF_COARRAY_DEREGISTER;
6545               else
6546                 caf_dtype = GFC_CAF_COARRAY_NOCOARRAY;
6547               tmp = gfc_deallocate_with_status (se.expr, pstat, errmsg, errlen,
6548                                                 label_finish, false, expr,
6549                                                 caf_dtype);
6550               gfc_add_expr_to_block (&se.pre, tmp);
6551             }
6552           else if (TREE_CODE (se.expr) == COMPONENT_REF
6553                    && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
6554                    && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
6555                         == RECORD_TYPE)
6556             {
6557               /* class.c(finalize_component) generates these, when a
6558                  finalizable entity has a non-allocatable derived type array
6559                  component, which has allocatable components. Obtain the
6560                  derived type of the array and deallocate the allocatable
6561                  components. */
6562               for (ref = expr->ref; ref; ref = ref->next)
6563                 {
6564                   if (ref->u.c.component->attr.dimension
6565                       && ref->u.c.component->ts.type == BT_DERIVED)
6566                     break;
6567                 }
6568
6569               if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
6570                   && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
6571                                           NULL))
6572                 {
6573                   tmp = gfc_deallocate_alloc_comp
6574                                 (ref->u.c.component->ts.u.derived,
6575                                  se.expr, expr->rank);
6576                   gfc_add_expr_to_block (&se.pre, tmp);
6577                 }
6578             }
6579
6580           if (al->expr->ts.type == BT_CLASS)
6581             {
6582               gfc_reset_vptr (&se.pre, al->expr);
6583               if (UNLIMITED_POLY (al->expr)
6584                   || (al->expr->ts.type == BT_DERIVED
6585                       && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6586                 /* Clear _len, too.  */
6587                 gfc_reset_len (&se.pre, al->expr);
6588             }
6589         }
6590       else
6591         {
6592           tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, label_finish,
6593                                                    false, al->expr,
6594                                                    al->expr->ts, is_coarray);
6595           gfc_add_expr_to_block (&se.pre, tmp);
6596
6597           /* Set to zero after deallocation.  */
6598           tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6599                                  se.expr,
6600                                  build_int_cst (TREE_TYPE (se.expr), 0));
6601           gfc_add_expr_to_block (&se.pre, tmp);
6602
6603           if (al->expr->ts.type == BT_CLASS)
6604             {
6605               gfc_reset_vptr (&se.pre, al->expr);
6606               if (UNLIMITED_POLY (al->expr)
6607                   || (al->expr->ts.type == BT_DERIVED
6608                       && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6609                 /* Clear _len, too.  */
6610                 gfc_reset_len (&se.pre, al->expr);
6611             }
6612         }
6613
6614       if (code->expr1)
6615         {
6616           tree cond;
6617
6618           cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6619                                   build_int_cst (TREE_TYPE (stat), 0));
6620           tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6621                                  gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
6622                                  build1_v (GOTO_EXPR, label_errmsg),
6623                                  build_empty_stmt (input_location));
6624           gfc_add_expr_to_block (&se.pre, tmp);
6625         }
6626
6627       tmp = gfc_finish_block (&se.pre);
6628       gfc_add_expr_to_block (&block, tmp);
6629       gfc_free_expr (expr);
6630     }
6631
6632   if (code->expr1)
6633     {
6634       tmp = build1_v (LABEL_EXPR, label_errmsg);
6635       gfc_add_expr_to_block (&block, tmp);
6636     }
6637
6638   /* Set ERRMSG - only needed if STAT is available.  */
6639   if (code->expr1 && code->expr2)
6640     {
6641       const char *msg = "Attempt to deallocate an unallocated object";
6642       stmtblock_t errmsg_block;
6643       tree errmsg_str, slen, dlen, cond;
6644
6645       gfc_init_block (&errmsg_block);
6646
6647       errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6648       gfc_add_modify (&errmsg_block, errmsg_str,
6649                 gfc_build_addr_expr (pchar_type_node,
6650                         gfc_build_localized_cstring_const (msg)));
6651       slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6652       dlen = gfc_get_expr_charlen (code->expr2);
6653
6654       gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
6655                              slen, errmsg_str, gfc_default_character_kind);
6656       tmp = gfc_finish_block (&errmsg_block);
6657
6658       cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6659                              build_int_cst (TREE_TYPE (stat), 0));
6660       tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6661                              gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
6662                              build_empty_stmt (input_location));
6663
6664       gfc_add_expr_to_block (&block, tmp);
6665     }
6666
6667   if (code->expr1 && TREE_USED (label_finish))
6668     {
6669       tmp = build1_v (LABEL_EXPR, label_finish);
6670       gfc_add_expr_to_block (&block, tmp);
6671     }
6672
6673   /* Set STAT.  */
6674   if (code->expr1)
6675     {
6676       gfc_init_se (&se, NULL);
6677       gfc_conv_expr_lhs (&se, code->expr1);
6678       tmp = convert (TREE_TYPE (se.expr), stat);
6679       gfc_add_modify (&block, se.expr, tmp);
6680     }
6681
6682   return gfc_finish_block (&block);
6683 }
6684
6685 #include "gt-fortran-trans-stmt.h"