7e6cea15c6a00942f53434cf244dc8da7a174cd1
[platform/upstream/gcc.git] / gcc / fortran / trans-array.c
1 /* Array translation routines
2    Copyright (C) 2002-2018 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 /* trans-array.c-- Various array related code, including scalarization,
23                    allocation, initialization and other support routines.  */
24
25 /* How the scalarizer works.
26    In gfortran, array expressions use the same core routines as scalar
27    expressions.
28    First, a Scalarization State (SS) chain is built.  This is done by walking
29    the expression tree, and building a linear list of the terms in the
30    expression.  As the tree is walked, scalar subexpressions are translated.
31
32    The scalarization parameters are stored in a gfc_loopinfo structure.
33    First the start and stride of each term is calculated by
34    gfc_conv_ss_startstride.  During this process the expressions for the array
35    descriptors and data pointers are also translated.
36
37    If the expression is an assignment, we must then resolve any dependencies.
38    In Fortran all the rhs values of an assignment must be evaluated before
39    any assignments take place.  This can require a temporary array to store the
40    values.  We also require a temporary when we are passing array expressions
41    or vector subscripts as procedure parameters.
42
43    Array sections are passed without copying to a temporary.  These use the
44    scalarizer to determine the shape of the section.  The flag
45    loop->array_parameter tells the scalarizer that the actual values and loop
46    variables will not be required.
47
48    The function gfc_conv_loop_setup generates the scalarization setup code.
49    It determines the range of the scalarizing loop variables.  If a temporary
50    is required, this is created and initialized.  Code for scalar expressions
51    taken outside the loop is also generated at this time.  Next the offset and
52    scaling required to translate from loop variables to array indices for each
53    term is calculated.
54
55    A call to gfc_start_scalarized_body marks the start of the scalarized
56    expression.  This creates a scope and declares the loop variables.  Before
57    calling this gfc_make_ss_chain_used must be used to indicate which terms
58    will be used inside this loop.
59
60    The scalar gfc_conv_* functions are then used to build the main body of the
61    scalarization loop.  Scalarization loop variables and precalculated scalar
62    values are automatically substituted.  Note that gfc_advance_se_ss_chain
63    must be used, rather than changing the se->ss directly.
64
65    For assignment expressions requiring a temporary two sub loops are
66    generated.  The first stores the result of the expression in the temporary,
67    the second copies it to the result.  A call to
68    gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
69    the start of the copying loop.  The temporary may be less than full rank.
70
71    Finally gfc_trans_scalarizing_loops is called to generate the implicit do
72    loops.  The loops are added to the pre chain of the loopinfo.  The post
73    chain may still contain cleanup code.
74
75    After the loop code has been added into its parent scope gfc_cleanup_loop
76    is called to free all the SS allocated by the scalarizer.  */
77
78 #include "config.h"
79 #include "system.h"
80 #include "coretypes.h"
81 #include "options.h"
82 #include "tree.h"
83 #include "gfortran.h"
84 #include "gimple-expr.h"
85 #include "trans.h"
86 #include "fold-const.h"
87 #include "constructor.h"
88 #include "trans-types.h"
89 #include "trans-array.h"
90 #include "trans-const.h"
91 #include "dependency.h"
92
93 static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor_base);
94
95 /* The contents of this structure aren't actually used, just the address.  */
96 static gfc_ss gfc_ss_terminator_var;
97 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
98
99
100 static tree
101 gfc_array_dataptr_type (tree desc)
102 {
103   return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
104 }
105
106
107 /* Build expressions to access the members of an array descriptor.
108    It's surprisingly easy to mess up here, so never access
109    an array descriptor by "brute force", always use these
110    functions.  This also avoids problems if we change the format
111    of an array descriptor.
112
113    To understand these magic numbers, look at the comments
114    before gfc_build_array_type() in trans-types.c.
115
116    The code within these defines should be the only code which knows the format
117    of an array descriptor.
118
119    Any code just needing to read obtain the bounds of an array should use
120    gfc_conv_array_* rather than the following functions as these will return
121    know constant values, and work with arrays which do not have descriptors.
122
123    Don't forget to #undef these!  */
124
125 #define DATA_FIELD 0
126 #define OFFSET_FIELD 1
127 #define DTYPE_FIELD 2
128 #define SPAN_FIELD 3
129 #define DIMENSION_FIELD 4
130 #define CAF_TOKEN_FIELD 5
131
132 #define STRIDE_SUBFIELD 0
133 #define LBOUND_SUBFIELD 1
134 #define UBOUND_SUBFIELD 2
135
136 /* This provides READ-ONLY access to the data field.  The field itself
137    doesn't have the proper type.  */
138
139 tree
140 gfc_conv_descriptor_data_get (tree desc)
141 {
142   tree field, type, t;
143
144   type = TREE_TYPE (desc);
145   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
146
147   field = TYPE_FIELDS (type);
148   gcc_assert (DATA_FIELD == 0);
149
150   t = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), desc,
151                        field, NULL_TREE);
152   t = fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), t);
153
154   return t;
155 }
156
157 /* This provides WRITE access to the data field.
158
159    TUPLES_P is true if we are generating tuples.
160
161    This function gets called through the following macros:
162      gfc_conv_descriptor_data_set
163      gfc_conv_descriptor_data_set.  */
164
165 void
166 gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
167 {
168   tree field, type, t;
169
170   type = TREE_TYPE (desc);
171   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
172
173   field = TYPE_FIELDS (type);
174   gcc_assert (DATA_FIELD == 0);
175
176   t = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), desc,
177                        field, NULL_TREE);
178   gfc_add_modify (block, t, fold_convert (TREE_TYPE (field), value));
179 }
180
181
182 /* This provides address access to the data field.  This should only be
183    used by array allocation, passing this on to the runtime.  */
184
185 tree
186 gfc_conv_descriptor_data_addr (tree desc)
187 {
188   tree field, type, t;
189
190   type = TREE_TYPE (desc);
191   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
192
193   field = TYPE_FIELDS (type);
194   gcc_assert (DATA_FIELD == 0);
195
196   t = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), desc,
197                        field, NULL_TREE);
198   return gfc_build_addr_expr (NULL_TREE, t);
199 }
200
201 static tree
202 gfc_conv_descriptor_offset (tree desc)
203 {
204   tree type;
205   tree field;
206
207   type = TREE_TYPE (desc);
208   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
209
210   field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
211   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
212
213   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
214                           desc, field, NULL_TREE);
215 }
216
217 tree
218 gfc_conv_descriptor_offset_get (tree desc)
219 {
220   return gfc_conv_descriptor_offset (desc);
221 }
222
223 void
224 gfc_conv_descriptor_offset_set (stmtblock_t *block, tree desc,
225                                 tree value)
226 {
227   tree t = gfc_conv_descriptor_offset (desc);
228   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
229 }
230
231
232 tree
233 gfc_conv_descriptor_dtype (tree desc)
234 {
235   tree field;
236   tree type;
237
238   type = TREE_TYPE (desc);
239   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
240
241   field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
242   gcc_assert (field != NULL_TREE
243               && TREE_TYPE (field) == get_dtype_type_node ());
244
245   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
246                           desc, field, NULL_TREE);
247 }
248
249 static tree
250 gfc_conv_descriptor_span (tree desc)
251 {
252   tree type;
253   tree field;
254
255   type = TREE_TYPE (desc);
256   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
257
258   field = gfc_advance_chain (TYPE_FIELDS (type), SPAN_FIELD);
259   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
260
261   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
262                           desc, field, NULL_TREE);
263 }
264
265 tree
266 gfc_conv_descriptor_span_get (tree desc)
267 {
268   return gfc_conv_descriptor_span (desc);
269 }
270
271 void
272 gfc_conv_descriptor_span_set (stmtblock_t *block, tree desc,
273                                 tree value)
274 {
275   tree t = gfc_conv_descriptor_span (desc);
276   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
277 }
278
279
280 tree
281 gfc_conv_descriptor_rank (tree desc)
282 {
283   tree tmp;
284   tree dtype;
285
286   dtype = gfc_conv_descriptor_dtype (desc);
287   tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), GFC_DTYPE_RANK);
288   gcc_assert (tmp!= NULL_TREE
289               && TREE_TYPE (tmp) == signed_char_type_node);
290   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp),
291                           dtype, tmp, NULL_TREE);
292 }
293
294
295 tree
296 gfc_get_descriptor_dimension (tree desc)
297 {
298   tree type, field;
299
300   type = TREE_TYPE (desc);
301   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
302
303   field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
304   gcc_assert (field != NULL_TREE
305           && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
306           && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
307
308   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
309                           desc, field, NULL_TREE);
310 }
311
312
313 static tree
314 gfc_conv_descriptor_dimension (tree desc, tree dim)
315 {
316   tree tmp;
317
318   tmp = gfc_get_descriptor_dimension (desc);
319
320   return gfc_build_array_ref (tmp, dim, NULL);
321 }
322
323
324 tree
325 gfc_conv_descriptor_token (tree desc)
326 {
327   tree type;
328   tree field;
329
330   type = TREE_TYPE (desc);
331   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
332   gcc_assert (flag_coarray == GFC_FCOARRAY_LIB);
333   field = gfc_advance_chain (TYPE_FIELDS (type), CAF_TOKEN_FIELD);
334
335   /* Should be a restricted pointer - except in the finalization wrapper.  */
336   gcc_assert (field != NULL_TREE
337               && (TREE_TYPE (field) == prvoid_type_node
338                   || TREE_TYPE (field) == pvoid_type_node));
339
340   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
341                           desc, field, NULL_TREE);
342 }
343
344
345 static tree
346 gfc_conv_descriptor_stride (tree desc, tree dim)
347 {
348   tree tmp;
349   tree field;
350
351   tmp = gfc_conv_descriptor_dimension (desc, dim);
352   field = TYPE_FIELDS (TREE_TYPE (tmp));
353   field = gfc_advance_chain (field, STRIDE_SUBFIELD);
354   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
355
356   tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
357                          tmp, field, NULL_TREE);
358   return tmp;
359 }
360
361 tree
362 gfc_conv_descriptor_stride_get (tree desc, tree dim)
363 {
364   tree type = TREE_TYPE (desc);
365   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
366   if (integer_zerop (dim)
367       && (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE
368           ||GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE_CONT
369           ||GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_RANK_CONT
370           ||GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT))
371     return gfc_index_one_node;
372
373   return gfc_conv_descriptor_stride (desc, dim);
374 }
375
376 void
377 gfc_conv_descriptor_stride_set (stmtblock_t *block, tree desc,
378                                 tree dim, tree value)
379 {
380   tree t = gfc_conv_descriptor_stride (desc, dim);
381   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
382 }
383
384 static tree
385 gfc_conv_descriptor_lbound (tree desc, tree dim)
386 {
387   tree tmp;
388   tree field;
389
390   tmp = gfc_conv_descriptor_dimension (desc, dim);
391   field = TYPE_FIELDS (TREE_TYPE (tmp));
392   field = gfc_advance_chain (field, LBOUND_SUBFIELD);
393   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
394
395   tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
396                          tmp, field, NULL_TREE);
397   return tmp;
398 }
399
400 tree
401 gfc_conv_descriptor_lbound_get (tree desc, tree dim)
402 {
403   return gfc_conv_descriptor_lbound (desc, dim);
404 }
405
406 void
407 gfc_conv_descriptor_lbound_set (stmtblock_t *block, tree desc,
408                                 tree dim, tree value)
409 {
410   tree t = gfc_conv_descriptor_lbound (desc, dim);
411   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
412 }
413
414 static tree
415 gfc_conv_descriptor_ubound (tree desc, tree dim)
416 {
417   tree tmp;
418   tree field;
419
420   tmp = gfc_conv_descriptor_dimension (desc, dim);
421   field = TYPE_FIELDS (TREE_TYPE (tmp));
422   field = gfc_advance_chain (field, UBOUND_SUBFIELD);
423   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
424
425   tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
426                          tmp, field, NULL_TREE);
427   return tmp;
428 }
429
430 tree
431 gfc_conv_descriptor_ubound_get (tree desc, tree dim)
432 {
433   return gfc_conv_descriptor_ubound (desc, dim);
434 }
435
436 void
437 gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree desc,
438                                 tree dim, tree value)
439 {
440   tree t = gfc_conv_descriptor_ubound (desc, dim);
441   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
442 }
443
444 /* Build a null array descriptor constructor.  */
445
446 tree
447 gfc_build_null_descriptor (tree type)
448 {
449   tree field;
450   tree tmp;
451
452   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
453   gcc_assert (DATA_FIELD == 0);
454   field = TYPE_FIELDS (type);
455
456   /* Set a NULL data pointer.  */
457   tmp = build_constructor_single (type, field, null_pointer_node);
458   TREE_CONSTANT (tmp) = 1;
459   /* All other fields are ignored.  */
460
461   return tmp;
462 }
463
464
465 /* Modify a descriptor such that the lbound of a given dimension is the value
466    specified.  This also updates ubound and offset accordingly.  */
467
468 void
469 gfc_conv_shift_descriptor_lbound (stmtblock_t* block, tree desc,
470                                   int dim, tree new_lbound)
471 {
472   tree offs, ubound, lbound, stride;
473   tree diff, offs_diff;
474
475   new_lbound = fold_convert (gfc_array_index_type, new_lbound);
476
477   offs = gfc_conv_descriptor_offset_get (desc);
478   lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
479   ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
480   stride = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[dim]);
481
482   /* Get difference (new - old) by which to shift stuff.  */
483   diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
484                           new_lbound, lbound);
485
486   /* Shift ubound and offset accordingly.  This has to be done before
487      updating the lbound, as they depend on the lbound expression!  */
488   ubound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
489                             ubound, diff);
490   gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[dim], ubound);
491   offs_diff = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
492                                diff, stride);
493   offs = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
494                           offs, offs_diff);
495   gfc_conv_descriptor_offset_set (block, desc, offs);
496
497   /* Finally set lbound to value we want.  */
498   gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[dim], new_lbound);
499 }
500
501
502 /* Obtain offsets for trans-types.c(gfc_get_array_descr_info).  */
503
504 void
505 gfc_get_descriptor_offsets_for_info (const_tree desc_type, tree *data_off,
506                                      tree *dtype_off, tree *dim_off,
507                                      tree *dim_size, tree *stride_suboff,
508                                      tree *lower_suboff, tree *upper_suboff)
509 {
510   tree field;
511   tree type;
512
513   type = TYPE_MAIN_VARIANT (desc_type);
514   field = gfc_advance_chain (TYPE_FIELDS (type), DATA_FIELD);
515   *data_off = byte_position (field);
516   field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
517   *dtype_off = byte_position (field);
518   field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
519   *dim_off = byte_position (field);
520   type = TREE_TYPE (TREE_TYPE (field));
521   *dim_size = TYPE_SIZE_UNIT (type);
522   field = gfc_advance_chain (TYPE_FIELDS (type), STRIDE_SUBFIELD);
523   *stride_suboff = byte_position (field);
524   field = gfc_advance_chain (TYPE_FIELDS (type), LBOUND_SUBFIELD);
525   *lower_suboff = byte_position (field);
526   field = gfc_advance_chain (TYPE_FIELDS (type), UBOUND_SUBFIELD);
527   *upper_suboff = byte_position (field);
528 }
529
530
531 /* Cleanup those #defines.  */
532
533 #undef DATA_FIELD
534 #undef OFFSET_FIELD
535 #undef DTYPE_FIELD
536 #undef SPAN_FIELD
537 #undef DIMENSION_FIELD
538 #undef CAF_TOKEN_FIELD
539 #undef STRIDE_SUBFIELD
540 #undef LBOUND_SUBFIELD
541 #undef UBOUND_SUBFIELD
542
543
544 /* Mark a SS chain as used.  Flags specifies in which loops the SS is used.
545    flags & 1 = Main loop body.
546    flags & 2 = temp copy loop.  */
547
548 void
549 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
550 {
551   for (; ss != gfc_ss_terminator; ss = ss->next)
552     ss->info->useflags = flags;
553 }
554
555
556 /* Free a gfc_ss chain.  */
557
558 void
559 gfc_free_ss_chain (gfc_ss * ss)
560 {
561   gfc_ss *next;
562
563   while (ss != gfc_ss_terminator)
564     {
565       gcc_assert (ss != NULL);
566       next = ss->next;
567       gfc_free_ss (ss);
568       ss = next;
569     }
570 }
571
572
573 static void
574 free_ss_info (gfc_ss_info *ss_info)
575 {
576   int n;
577
578   ss_info->refcount--;
579   if (ss_info->refcount > 0)
580     return;
581
582   gcc_assert (ss_info->refcount == 0);
583
584   switch (ss_info->type)
585     {
586     case GFC_SS_SECTION:
587       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
588         if (ss_info->data.array.subscript[n])
589           gfc_free_ss_chain (ss_info->data.array.subscript[n]);
590       break;
591
592     default:
593       break;
594     }
595
596   free (ss_info);
597 }
598
599
600 /* Free a SS.  */
601
602 void
603 gfc_free_ss (gfc_ss * ss)
604 {
605   free_ss_info (ss->info);
606   free (ss);
607 }
608
609
610 /* Creates and initializes an array type gfc_ss struct.  */
611
612 gfc_ss *
613 gfc_get_array_ss (gfc_ss *next, gfc_expr *expr, int dimen, gfc_ss_type type)
614 {
615   gfc_ss *ss;
616   gfc_ss_info *ss_info;
617   int i;
618
619   ss_info = gfc_get_ss_info ();
620   ss_info->refcount++;
621   ss_info->type = type;
622   ss_info->expr = expr;
623
624   ss = gfc_get_ss ();
625   ss->info = ss_info;
626   ss->next = next;
627   ss->dimen = dimen;
628   for (i = 0; i < ss->dimen; i++)
629     ss->dim[i] = i;
630
631   return ss;
632 }
633
634
635 /* Creates and initializes a temporary type gfc_ss struct.  */
636
637 gfc_ss *
638 gfc_get_temp_ss (tree type, tree string_length, int dimen)
639 {
640   gfc_ss *ss;
641   gfc_ss_info *ss_info;
642   int i;
643
644   ss_info = gfc_get_ss_info ();
645   ss_info->refcount++;
646   ss_info->type = GFC_SS_TEMP;
647   ss_info->string_length = string_length;
648   ss_info->data.temp.type = type;
649
650   ss = gfc_get_ss ();
651   ss->info = ss_info;
652   ss->next = gfc_ss_terminator;
653   ss->dimen = dimen;
654   for (i = 0; i < ss->dimen; i++)
655     ss->dim[i] = i;
656
657   return ss;
658 }
659
660
661 /* Creates and initializes a scalar type gfc_ss struct.  */
662
663 gfc_ss *
664 gfc_get_scalar_ss (gfc_ss *next, gfc_expr *expr)
665 {
666   gfc_ss *ss;
667   gfc_ss_info *ss_info;
668
669   ss_info = gfc_get_ss_info ();
670   ss_info->refcount++;
671   ss_info->type = GFC_SS_SCALAR;
672   ss_info->expr = expr;
673
674   ss = gfc_get_ss ();
675   ss->info = ss_info;
676   ss->next = next;
677
678   return ss;
679 }
680
681
682 /* Free all the SS associated with a loop.  */
683
684 void
685 gfc_cleanup_loop (gfc_loopinfo * loop)
686 {
687   gfc_loopinfo *loop_next, **ploop;
688   gfc_ss *ss;
689   gfc_ss *next;
690
691   ss = loop->ss;
692   while (ss != gfc_ss_terminator)
693     {
694       gcc_assert (ss != NULL);
695       next = ss->loop_chain;
696       gfc_free_ss (ss);
697       ss = next;
698     }
699
700   /* Remove reference to self in the parent loop.  */
701   if (loop->parent)
702     for (ploop = &loop->parent->nested; *ploop; ploop = &(*ploop)->next)
703       if (*ploop == loop)
704         {
705           *ploop = loop->next;
706           break;
707         }
708
709   /* Free non-freed nested loops.  */
710   for (loop = loop->nested; loop; loop = loop_next)
711     {
712       loop_next = loop->next;
713       gfc_cleanup_loop (loop);
714       free (loop);
715     }
716 }
717
718
719 static void
720 set_ss_loop (gfc_ss *ss, gfc_loopinfo *loop)
721 {
722   int n;
723
724   for (; ss != gfc_ss_terminator; ss = ss->next)
725     {
726       ss->loop = loop;
727
728       if (ss->info->type == GFC_SS_SCALAR
729           || ss->info->type == GFC_SS_REFERENCE
730           || ss->info->type == GFC_SS_TEMP)
731         continue;
732
733       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
734         if (ss->info->data.array.subscript[n] != NULL)
735           set_ss_loop (ss->info->data.array.subscript[n], loop);
736     }
737 }
738
739
740 /* Associate a SS chain with a loop.  */
741
742 void
743 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
744 {
745   gfc_ss *ss;
746   gfc_loopinfo *nested_loop;
747
748   if (head == gfc_ss_terminator)
749     return;
750
751   set_ss_loop (head, loop);
752
753   ss = head;
754   for (; ss && ss != gfc_ss_terminator; ss = ss->next)
755     {
756       if (ss->nested_ss)
757         {
758           nested_loop = ss->nested_ss->loop;
759
760           /* More than one ss can belong to the same loop.  Hence, we add the
761              loop to the chain only if it is different from the previously
762              added one, to avoid duplicate nested loops.  */
763           if (nested_loop != loop->nested)
764             {
765               gcc_assert (nested_loop->parent == NULL);
766               nested_loop->parent = loop;
767
768               gcc_assert (nested_loop->next == NULL);
769               nested_loop->next = loop->nested;
770               loop->nested = nested_loop;
771             }
772           else
773             gcc_assert (nested_loop->parent == loop);
774         }
775
776       if (ss->next == gfc_ss_terminator)
777         ss->loop_chain = loop->ss;
778       else
779         ss->loop_chain = ss->next;
780     }
781   gcc_assert (ss == gfc_ss_terminator);
782   loop->ss = head;
783 }
784
785
786 /* Returns true if the expression is an array pointer.  */
787
788 static bool
789 is_pointer_array (tree expr)
790 {
791   if (expr == NULL_TREE
792       || !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (expr))
793       || GFC_CLASS_TYPE_P (TREE_TYPE (expr)))
794     return false;
795
796   if (TREE_CODE (expr) == VAR_DECL
797       && GFC_DECL_PTR_ARRAY_P (expr))
798     return true;
799
800   if (TREE_CODE (expr) == PARM_DECL
801       && GFC_DECL_PTR_ARRAY_P (expr))
802     return true;
803
804   if (TREE_CODE (expr) == INDIRECT_REF
805       && GFC_DECL_PTR_ARRAY_P (TREE_OPERAND (expr, 0)))
806     return true;
807
808   /* The field declaration is marked as an pointer array.  */
809   if (TREE_CODE (expr) == COMPONENT_REF
810       && GFC_DECL_PTR_ARRAY_P (TREE_OPERAND (expr, 1))
811       && !GFC_CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1))))
812     return true;
813
814   return false;
815 }
816
817
818 /* Return the span of an array.  */
819
820 tree
821 gfc_get_array_span (tree desc, gfc_expr *expr)
822 {
823   tree tmp;
824
825   if (is_pointer_array (desc))
826     /* This will have the span field set.  */
827     tmp = gfc_conv_descriptor_span_get (desc);
828   else if (TREE_CODE (desc) == COMPONENT_REF
829            && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))
830            && GFC_CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (desc, 0))))
831     {
832       /* The descriptor is a class _data field and so use the vtable
833          size for the receiving span field.  */
834       tmp = gfc_get_vptr_from_expr (desc);
835       tmp = gfc_vptr_size_get (tmp);
836     }
837   else if (expr && expr->expr_type == EXPR_VARIABLE
838            && expr->symtree->n.sym->ts.type == BT_CLASS
839            && expr->ref->type == REF_COMPONENT
840            && expr->ref->next->type == REF_ARRAY
841            && expr->ref->next->next == NULL
842            && CLASS_DATA (expr->symtree->n.sym)->attr.dimension)
843     {
844       /* Dummys come in sometimes with the descriptor detached from
845          the class field or declaration.  */
846       tmp = gfc_class_vptr_get (expr->symtree->n.sym->backend_decl);
847       tmp = gfc_vptr_size_get (tmp);
848     }
849   else
850     {
851       /* If none of the fancy stuff works, the span is the element
852          size of the array.  */
853       tmp = gfc_get_element_type (TREE_TYPE (desc));
854       tmp = fold_convert (gfc_array_index_type,
855                           size_in_bytes (tmp));
856     }
857   return tmp;
858 }
859
860
861 /* Generate an initializer for a static pointer or allocatable array.  */
862
863 void
864 gfc_trans_static_array_pointer (gfc_symbol * sym)
865 {
866   tree type;
867
868   gcc_assert (TREE_STATIC (sym->backend_decl));
869   /* Just zero the data member.  */
870   type = TREE_TYPE (sym->backend_decl);
871   DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
872 }
873
874
875 /* If the bounds of SE's loop have not yet been set, see if they can be
876    determined from array spec AS, which is the array spec of a called
877    function.  MAPPING maps the callee's dummy arguments to the values
878    that the caller is passing.  Add any initialization and finalization
879    code to SE.  */
880
881 void
882 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
883                                      gfc_se * se, gfc_array_spec * as)
884 {
885   int n, dim, total_dim;
886   gfc_se tmpse;
887   gfc_ss *ss;
888   tree lower;
889   tree upper;
890   tree tmp;
891
892   total_dim = 0;
893
894   if (!as || as->type != AS_EXPLICIT)
895     return;
896
897   for (ss = se->ss; ss; ss = ss->parent)
898     {
899       total_dim += ss->loop->dimen;
900       for (n = 0; n < ss->loop->dimen; n++)
901         {
902           /* The bound is known, nothing to do.  */
903           if (ss->loop->to[n] != NULL_TREE)
904             continue;
905
906           dim = ss->dim[n];
907           gcc_assert (dim < as->rank);
908           gcc_assert (ss->loop->dimen <= as->rank);
909
910           /* Evaluate the lower bound.  */
911           gfc_init_se (&tmpse, NULL);
912           gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
913           gfc_add_block_to_block (&se->pre, &tmpse.pre);
914           gfc_add_block_to_block (&se->post, &tmpse.post);
915           lower = fold_convert (gfc_array_index_type, tmpse.expr);
916
917           /* ...and the upper bound.  */
918           gfc_init_se (&tmpse, NULL);
919           gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
920           gfc_add_block_to_block (&se->pre, &tmpse.pre);
921           gfc_add_block_to_block (&se->post, &tmpse.post);
922           upper = fold_convert (gfc_array_index_type, tmpse.expr);
923
924           /* Set the upper bound of the loop to UPPER - LOWER.  */
925           tmp = fold_build2_loc (input_location, MINUS_EXPR,
926                                  gfc_array_index_type, upper, lower);
927           tmp = gfc_evaluate_now (tmp, &se->pre);
928           ss->loop->to[n] = tmp;
929         }
930     }
931
932   gcc_assert (total_dim == as->rank);
933 }
934
935
936 /* Generate code to allocate an array temporary, or create a variable to
937    hold the data.  If size is NULL, zero the descriptor so that the
938    callee will allocate the array.  If DEALLOC is true, also generate code to
939    free the array afterwards.
940
941    If INITIAL is not NULL, it is packed using internal_pack and the result used
942    as data instead of allocating a fresh, unitialized area of memory.
943
944    Initialization code is added to PRE and finalization code to POST.
945    DYNAMIC is true if the caller may want to extend the array later
946    using realloc.  This prevents us from putting the array on the stack.  */
947
948 static void
949 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
950                                   gfc_array_info * info, tree size, tree nelem,
951                                   tree initial, bool dynamic, bool dealloc)
952 {
953   tree tmp;
954   tree desc;
955   bool onstack;
956
957   desc = info->descriptor;
958   info->offset = gfc_index_zero_node;
959   if (size == NULL_TREE || integer_zerop (size))
960     {
961       /* A callee allocated array.  */
962       gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
963       onstack = FALSE;
964     }
965   else
966     {
967       /* Allocate the temporary.  */
968       onstack = !dynamic && initial == NULL_TREE
969                          && (flag_stack_arrays
970                              || gfc_can_put_var_on_stack (size));
971
972       if (onstack)
973         {
974           /* Make a temporary variable to hold the data.  */
975           tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (nelem),
976                                  nelem, gfc_index_one_node);
977           tmp = gfc_evaluate_now (tmp, pre);
978           tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
979                                   tmp);
980           tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
981                                   tmp);
982           tmp = gfc_create_var (tmp, "A");
983           /* If we're here only because of -fstack-arrays we have to
984              emit a DECL_EXPR to make the gimplifier emit alloca calls.  */
985           if (!gfc_can_put_var_on_stack (size))
986             gfc_add_expr_to_block (pre,
987                                    fold_build1_loc (input_location,
988                                                     DECL_EXPR, TREE_TYPE (tmp),
989                                                     tmp));
990           tmp = gfc_build_addr_expr (NULL_TREE, tmp);
991           gfc_conv_descriptor_data_set (pre, desc, tmp);
992         }
993       else
994         {
995           /* Allocate memory to hold the data or call internal_pack.  */
996           if (initial == NULL_TREE)
997             {
998               tmp = gfc_call_malloc (pre, NULL, size);
999               tmp = gfc_evaluate_now (tmp, pre);
1000             }
1001           else
1002             {
1003               tree packed;
1004               tree source_data;
1005               tree was_packed;
1006               stmtblock_t do_copying;
1007
1008               tmp = TREE_TYPE (initial); /* Pointer to descriptor.  */
1009               gcc_assert (TREE_CODE (tmp) == POINTER_TYPE);
1010               tmp = TREE_TYPE (tmp); /* The descriptor itself.  */
1011               tmp = gfc_get_element_type (tmp);
1012               gcc_assert (tmp == gfc_get_element_type (TREE_TYPE (desc)));
1013               packed = gfc_create_var (build_pointer_type (tmp), "data");
1014
1015               tmp = build_call_expr_loc (input_location,
1016                                      gfor_fndecl_in_pack, 1, initial);
1017               tmp = fold_convert (TREE_TYPE (packed), tmp);
1018               gfc_add_modify (pre, packed, tmp);
1019
1020               tmp = build_fold_indirect_ref_loc (input_location,
1021                                              initial);
1022               source_data = gfc_conv_descriptor_data_get (tmp);
1023
1024               /* internal_pack may return source->data without any allocation
1025                  or copying if it is already packed.  If that's the case, we
1026                  need to allocate and copy manually.  */
1027
1028               gfc_start_block (&do_copying);
1029               tmp = gfc_call_malloc (&do_copying, NULL, size);
1030               tmp = fold_convert (TREE_TYPE (packed), tmp);
1031               gfc_add_modify (&do_copying, packed, tmp);
1032               tmp = gfc_build_memcpy_call (packed, source_data, size);
1033               gfc_add_expr_to_block (&do_copying, tmp);
1034
1035               was_packed = fold_build2_loc (input_location, EQ_EXPR,
1036                                             logical_type_node, packed,
1037                                             source_data);
1038               tmp = gfc_finish_block (&do_copying);
1039               tmp = build3_v (COND_EXPR, was_packed, tmp,
1040                               build_empty_stmt (input_location));
1041               gfc_add_expr_to_block (pre, tmp);
1042
1043               tmp = fold_convert (pvoid_type_node, packed);
1044             }
1045
1046           gfc_conv_descriptor_data_set (pre, desc, tmp);
1047         }
1048     }
1049   info->data = gfc_conv_descriptor_data_get (desc);
1050
1051   /* The offset is zero because we create temporaries with a zero
1052      lower bound.  */
1053   gfc_conv_descriptor_offset_set (pre, desc, gfc_index_zero_node);
1054
1055   if (dealloc && !onstack)
1056     {
1057       /* Free the temporary.  */
1058       tmp = gfc_conv_descriptor_data_get (desc);
1059       tmp = gfc_call_free (tmp);
1060       gfc_add_expr_to_block (post, tmp);
1061     }
1062 }
1063
1064
1065 /* Get the scalarizer array dimension corresponding to actual array dimension
1066    given by ARRAY_DIM.
1067
1068    For example, if SS represents the array ref a(1,:,:,1), it is a
1069    bidimensional scalarizer array, and the result would be 0 for ARRAY_DIM=1,
1070    and 1 for ARRAY_DIM=2.
1071    If SS represents transpose(a(:,1,1,:)), it is again a bidimensional
1072    scalarizer array, and the result would be 1 for ARRAY_DIM=0 and 0 for
1073    ARRAY_DIM=3.
1074    If SS represents sum(a(:,:,:,1), dim=1), it is a 2+1-dimensional scalarizer
1075    array.  If called on the inner ss, the result would be respectively 0,1,2 for
1076    ARRAY_DIM=0,1,2.  If called on the outer ss, the result would be 0,1
1077    for ARRAY_DIM=1,2.  */
1078
1079 static int
1080 get_scalarizer_dim_for_array_dim (gfc_ss *ss, int array_dim)
1081 {
1082   int array_ref_dim;
1083   int n;
1084
1085   array_ref_dim = 0;
1086
1087   for (; ss; ss = ss->parent)
1088     for (n = 0; n < ss->dimen; n++)
1089       if (ss->dim[n] < array_dim)
1090         array_ref_dim++;
1091
1092   return array_ref_dim;
1093 }
1094
1095
1096 static gfc_ss *
1097 innermost_ss (gfc_ss *ss)
1098 {
1099   while (ss->nested_ss != NULL)
1100     ss = ss->nested_ss;
1101
1102   return ss;
1103 }
1104
1105
1106
1107 /* Get the array reference dimension corresponding to the given loop dimension.
1108    It is different from the true array dimension given by the dim array in
1109    the case of a partial array reference (i.e. a(:,:,1,:) for example)
1110    It is different from the loop dimension in the case of a transposed array.
1111    */
1112
1113 static int
1114 get_array_ref_dim_for_loop_dim (gfc_ss *ss, int loop_dim)
1115 {
1116   return get_scalarizer_dim_for_array_dim (innermost_ss (ss),
1117                                            ss->dim[loop_dim]);
1118 }
1119
1120
1121 /* Generate code to create and initialize the descriptor for a temporary
1122    array.  This is used for both temporaries needed by the scalarizer, and
1123    functions returning arrays.  Adjusts the loop variables to be
1124    zero-based, and calculates the loop bounds for callee allocated arrays.
1125    Allocate the array unless it's callee allocated (we have a callee
1126    allocated array if 'callee_alloc' is true, or if loop->to[n] is
1127    NULL_TREE for any n).  Also fills in the descriptor, data and offset
1128    fields of info if known.  Returns the size of the array, or NULL for a
1129    callee allocated array.
1130
1131    'eltype' == NULL signals that the temporary should be a class object.
1132    The 'initial' expression is used to obtain the size of the dynamic
1133    type; otherwise the allocation and initialization proceeds as for any
1134    other expression
1135
1136    PRE, POST, INITIAL, DYNAMIC and DEALLOC are as for
1137    gfc_trans_allocate_array_storage.  */
1138
1139 tree
1140 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss,
1141                              tree eltype, tree initial, bool dynamic,
1142                              bool dealloc, bool callee_alloc, locus * where)
1143 {
1144   gfc_loopinfo *loop;
1145   gfc_ss *s;
1146   gfc_array_info *info;
1147   tree from[GFC_MAX_DIMENSIONS], to[GFC_MAX_DIMENSIONS];
1148   tree type;
1149   tree desc;
1150   tree tmp;
1151   tree size;
1152   tree nelem;
1153   tree cond;
1154   tree or_expr;
1155   tree class_expr = NULL_TREE;
1156   int n, dim, tmp_dim;
1157   int total_dim = 0;
1158
1159   /* This signals a class array for which we need the size of the
1160      dynamic type.  Generate an eltype and then the class expression.  */
1161   if (eltype == NULL_TREE && initial)
1162     {
1163       gcc_assert (POINTER_TYPE_P (TREE_TYPE (initial)));
1164       class_expr = build_fold_indirect_ref_loc (input_location, initial);
1165       eltype = TREE_TYPE (class_expr);
1166       eltype = gfc_get_element_type (eltype);
1167       /* Obtain the structure (class) expression.  */
1168       class_expr = TREE_OPERAND (class_expr, 0);
1169       gcc_assert (class_expr);
1170     }
1171
1172   memset (from, 0, sizeof (from));
1173   memset (to, 0, sizeof (to));
1174
1175   info = &ss->info->data.array;
1176
1177   gcc_assert (ss->dimen > 0);
1178   gcc_assert (ss->loop->dimen == ss->dimen);
1179
1180   if (warn_array_temporaries && where)
1181     gfc_warning (OPT_Warray_temporaries,
1182                  "Creating array temporary at %L", where);
1183
1184   /* Set the lower bound to zero.  */
1185   for (s = ss; s; s = s->parent)
1186     {
1187       loop = s->loop;
1188
1189       total_dim += loop->dimen;
1190       for (n = 0; n < loop->dimen; n++)
1191         {
1192           dim = s->dim[n];
1193
1194           /* Callee allocated arrays may not have a known bound yet.  */
1195           if (loop->to[n])
1196             loop->to[n] = gfc_evaluate_now (
1197                         fold_build2_loc (input_location, MINUS_EXPR,
1198                                          gfc_array_index_type,
1199                                          loop->to[n], loop->from[n]),
1200                         pre);
1201           loop->from[n] = gfc_index_zero_node;
1202
1203           /* We have just changed the loop bounds, we must clear the
1204              corresponding specloop, so that delta calculation is not skipped
1205              later in gfc_set_delta.  */
1206           loop->specloop[n] = NULL;
1207
1208           /* We are constructing the temporary's descriptor based on the loop
1209              dimensions.  As the dimensions may be accessed in arbitrary order
1210              (think of transpose) the size taken from the n'th loop may not map
1211              to the n'th dimension of the array.  We need to reconstruct loop
1212              infos in the right order before using it to set the descriptor
1213              bounds.  */
1214           tmp_dim = get_scalarizer_dim_for_array_dim (ss, dim);
1215           from[tmp_dim] = loop->from[n];
1216           to[tmp_dim] = loop->to[n];
1217
1218           info->delta[dim] = gfc_index_zero_node;
1219           info->start[dim] = gfc_index_zero_node;
1220           info->end[dim] = gfc_index_zero_node;
1221           info->stride[dim] = gfc_index_one_node;
1222         }
1223     }
1224
1225   /* Initialize the descriptor.  */
1226   type =
1227     gfc_get_array_type_bounds (eltype, total_dim, 0, from, to, 1,
1228                                GFC_ARRAY_UNKNOWN, true);
1229   desc = gfc_create_var (type, "atmp");
1230   GFC_DECL_PACKED_ARRAY (desc) = 1;
1231
1232   info->descriptor = desc;
1233   size = gfc_index_one_node;
1234
1235   /* Emit a DECL_EXPR for the variable sized array type in
1236      GFC_TYPE_ARRAY_DATAPTR_TYPE so the gimplification of its type
1237      sizes works correctly.  */
1238   tree arraytype = TREE_TYPE (GFC_TYPE_ARRAY_DATAPTR_TYPE (type));
1239   if (! TYPE_NAME (arraytype))
1240     TYPE_NAME (arraytype) = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
1241                                         NULL_TREE, arraytype);
1242   gfc_add_expr_to_block (pre, build1 (DECL_EXPR,
1243                                       arraytype, TYPE_NAME (arraytype)));
1244
1245   /* Fill in the array dtype.  */
1246   tmp = gfc_conv_descriptor_dtype (desc);
1247   gfc_add_modify (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
1248
1249   /*
1250      Fill in the bounds and stride.  This is a packed array, so:
1251
1252      size = 1;
1253      for (n = 0; n < rank; n++)
1254        {
1255          stride[n] = size
1256          delta = ubound[n] + 1 - lbound[n];
1257          size = size * delta;
1258        }
1259      size = size * sizeof(element);
1260   */
1261
1262   or_expr = NULL_TREE;
1263
1264   /* If there is at least one null loop->to[n], it is a callee allocated
1265      array.  */
1266   for (n = 0; n < total_dim; n++)
1267     if (to[n] == NULL_TREE)
1268       {
1269         size = NULL_TREE;
1270         break;
1271       }
1272
1273   if (size == NULL_TREE)
1274     for (s = ss; s; s = s->parent)
1275       for (n = 0; n < s->loop->dimen; n++)
1276         {
1277           dim = get_scalarizer_dim_for_array_dim (ss, s->dim[n]);
1278
1279           /* For a callee allocated array express the loop bounds in terms
1280              of the descriptor fields.  */
1281           tmp = fold_build2_loc (input_location,
1282                 MINUS_EXPR, gfc_array_index_type,
1283                 gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]),
1284                 gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]));
1285           s->loop->to[n] = tmp;
1286         }
1287   else
1288     {
1289       for (n = 0; n < total_dim; n++)
1290         {
1291           /* Store the stride and bound components in the descriptor.  */
1292           gfc_conv_descriptor_stride_set (pre, desc, gfc_rank_cst[n], size);
1293
1294           gfc_conv_descriptor_lbound_set (pre, desc, gfc_rank_cst[n],
1295                                           gfc_index_zero_node);
1296
1297           gfc_conv_descriptor_ubound_set (pre, desc, gfc_rank_cst[n], to[n]);
1298
1299           tmp = fold_build2_loc (input_location, PLUS_EXPR,
1300                                  gfc_array_index_type,
1301                                  to[n], gfc_index_one_node);
1302
1303           /* Check whether the size for this dimension is negative.  */
1304           cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
1305                                   tmp, gfc_index_zero_node);
1306           cond = gfc_evaluate_now (cond, pre);
1307
1308           if (n == 0)
1309             or_expr = cond;
1310           else
1311             or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1312                                        logical_type_node, or_expr, cond);
1313
1314           size = fold_build2_loc (input_location, MULT_EXPR,
1315                                   gfc_array_index_type, size, tmp);
1316           size = gfc_evaluate_now (size, pre);
1317         }
1318     }
1319
1320   /* Get the size of the array.  */
1321   if (size && !callee_alloc)
1322     {
1323       tree elemsize;
1324       /* If or_expr is true, then the extent in at least one
1325          dimension is zero and the size is set to zero.  */
1326       size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
1327                               or_expr, gfc_index_zero_node, size);
1328
1329       nelem = size;
1330       if (class_expr == NULL_TREE)
1331         elemsize = fold_convert (gfc_array_index_type,
1332                         TYPE_SIZE_UNIT (gfc_get_element_type (type)));
1333       else
1334         elemsize = gfc_class_vtab_size_get (class_expr);
1335
1336       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
1337                               size, elemsize);
1338     }
1339   else
1340     {
1341       nelem = size;
1342       size = NULL_TREE;
1343     }
1344
1345   gfc_trans_allocate_array_storage (pre, post, info, size, nelem, initial,
1346                                     dynamic, dealloc);
1347
1348   while (ss->parent)
1349     ss = ss->parent;
1350
1351   if (ss->dimen > ss->loop->temp_dim)
1352     ss->loop->temp_dim = ss->dimen;
1353
1354   return size;
1355 }
1356
1357
1358 /* Return the number of iterations in a loop that starts at START,
1359    ends at END, and has step STEP.  */
1360
1361 static tree
1362 gfc_get_iteration_count (tree start, tree end, tree step)
1363 {
1364   tree tmp;
1365   tree type;
1366
1367   type = TREE_TYPE (step);
1368   tmp = fold_build2_loc (input_location, MINUS_EXPR, type, end, start);
1369   tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, type, tmp, step);
1370   tmp = fold_build2_loc (input_location, PLUS_EXPR, type, tmp,
1371                          build_int_cst (type, 1));
1372   tmp = fold_build2_loc (input_location, MAX_EXPR, type, tmp,
1373                          build_int_cst (type, 0));
1374   return fold_convert (gfc_array_index_type, tmp);
1375 }
1376
1377
1378 /* Extend the data in array DESC by EXTRA elements.  */
1379
1380 static void
1381 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
1382 {
1383   tree arg0, arg1;
1384   tree tmp;
1385   tree size;
1386   tree ubound;
1387
1388   if (integer_zerop (extra))
1389     return;
1390
1391   ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
1392
1393   /* Add EXTRA to the upper bound.  */
1394   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1395                          ubound, extra);
1396   gfc_conv_descriptor_ubound_set (pblock, desc, gfc_rank_cst[0], tmp);
1397
1398   /* Get the value of the current data pointer.  */
1399   arg0 = gfc_conv_descriptor_data_get (desc);
1400
1401   /* Calculate the new array size.  */
1402   size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
1403   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1404                          ubound, gfc_index_one_node);
1405   arg1 = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
1406                           fold_convert (size_type_node, tmp),
1407                           fold_convert (size_type_node, size));
1408
1409   /* Call the realloc() function.  */
1410   tmp = gfc_call_realloc (pblock, arg0, arg1);
1411   gfc_conv_descriptor_data_set (pblock, desc, tmp);
1412 }
1413
1414
1415 /* Return true if the bounds of iterator I can only be determined
1416    at run time.  */
1417
1418 static inline bool
1419 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
1420 {
1421   return (i->start->expr_type != EXPR_CONSTANT
1422           || i->end->expr_type != EXPR_CONSTANT
1423           || i->step->expr_type != EXPR_CONSTANT);
1424 }
1425
1426
1427 /* Split the size of constructor element EXPR into the sum of two terms,
1428    one of which can be determined at compile time and one of which must
1429    be calculated at run time.  Set *SIZE to the former and return true
1430    if the latter might be nonzero.  */
1431
1432 static bool
1433 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
1434 {
1435   if (expr->expr_type == EXPR_ARRAY)
1436     return gfc_get_array_constructor_size (size, expr->value.constructor);
1437   else if (expr->rank > 0)
1438     {
1439       /* Calculate everything at run time.  */
1440       mpz_set_ui (*size, 0);
1441       return true;
1442     }
1443   else
1444     {
1445       /* A single element.  */
1446       mpz_set_ui (*size, 1);
1447       return false;
1448     }
1449 }
1450
1451
1452 /* Like gfc_get_array_constructor_element_size, but applied to the whole
1453    of array constructor C.  */
1454
1455 static bool
1456 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor_base base)
1457 {
1458   gfc_constructor *c;
1459   gfc_iterator *i;
1460   mpz_t val;
1461   mpz_t len;
1462   bool dynamic;
1463
1464   mpz_set_ui (*size, 0);
1465   mpz_init (len);
1466   mpz_init (val);
1467
1468   dynamic = false;
1469   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1470     {
1471       i = c->iterator;
1472       if (i && gfc_iterator_has_dynamic_bounds (i))
1473         dynamic = true;
1474       else
1475         {
1476           dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
1477           if (i)
1478             {
1479               /* Multiply the static part of the element size by the
1480                  number of iterations.  */
1481               mpz_sub (val, i->end->value.integer, i->start->value.integer);
1482               mpz_fdiv_q (val, val, i->step->value.integer);
1483               mpz_add_ui (val, val, 1);
1484               if (mpz_sgn (val) > 0)
1485                 mpz_mul (len, len, val);
1486               else
1487                 mpz_set_ui (len, 0);
1488             }
1489           mpz_add (*size, *size, len);
1490         }
1491     }
1492   mpz_clear (len);
1493   mpz_clear (val);
1494   return dynamic;
1495 }
1496
1497
1498 /* Make sure offset is a variable.  */
1499
1500 static void
1501 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
1502                          tree * offsetvar)
1503 {
1504   /* We should have already created the offset variable.  We cannot
1505      create it here because we may be in an inner scope.  */
1506   gcc_assert (*offsetvar != NULL_TREE);
1507   gfc_add_modify (pblock, *offsetvar, *poffset);
1508   *poffset = *offsetvar;
1509   TREE_USED (*offsetvar) = 1;
1510 }
1511
1512
1513 /* Variables needed for bounds-checking.  */
1514 static bool first_len;
1515 static tree first_len_val;
1516 static bool typespec_chararray_ctor;
1517
1518 static void
1519 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
1520                               tree offset, gfc_se * se, gfc_expr * expr)
1521 {
1522   tree tmp;
1523
1524   gfc_conv_expr (se, expr);
1525
1526   /* Store the value.  */
1527   tmp = build_fold_indirect_ref_loc (input_location,
1528                                  gfc_conv_descriptor_data_get (desc));
1529   tmp = gfc_build_array_ref (tmp, offset, NULL);
1530
1531   if (expr->ts.type == BT_CHARACTER)
1532     {
1533       int i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
1534       tree esize;
1535
1536       esize = size_in_bytes (gfc_get_element_type (TREE_TYPE (desc)));
1537       esize = fold_convert (gfc_charlen_type_node, esize);
1538       esize = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1539                                TREE_TYPE (esize), esize,
1540                                build_int_cst (TREE_TYPE (esize),
1541                                           gfc_character_kinds[i].bit_size / 8));
1542
1543       gfc_conv_string_parameter (se);
1544       if (POINTER_TYPE_P (TREE_TYPE (tmp)))
1545         {
1546           /* The temporary is an array of pointers.  */
1547           se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1548           gfc_add_modify (&se->pre, tmp, se->expr);
1549         }
1550       else
1551         {
1552           /* The temporary is an array of string values.  */
1553           tmp = gfc_build_addr_expr (gfc_get_pchar_type (expr->ts.kind), tmp);
1554           /* We know the temporary and the value will be the same length,
1555              so can use memcpy.  */
1556           gfc_trans_string_copy (&se->pre, esize, tmp, expr->ts.kind,
1557                                  se->string_length, se->expr, expr->ts.kind);
1558         }
1559       if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !typespec_chararray_ctor)
1560         {
1561           if (first_len)
1562             {
1563               gfc_add_modify (&se->pre, first_len_val,
1564                               fold_convert (TREE_TYPE (first_len_val),
1565                                             se->string_length));
1566               first_len = false;
1567             }
1568           else
1569             {
1570               /* Verify that all constructor elements are of the same
1571                  length.  */
1572               tree rhs = fold_convert (TREE_TYPE (first_len_val),
1573                                        se->string_length);
1574               tree cond = fold_build2_loc (input_location, NE_EXPR,
1575                                            logical_type_node, first_len_val,
1576                                            rhs);
1577               gfc_trans_runtime_check
1578                 (true, false, cond, &se->pre, &expr->where,
1579                  "Different CHARACTER lengths (%ld/%ld) in array constructor",
1580                  fold_convert (long_integer_type_node, first_len_val),
1581                  fold_convert (long_integer_type_node, se->string_length));
1582             }
1583         }
1584     }
1585   else if (GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
1586            && !GFC_CLASS_TYPE_P (gfc_get_element_type (TREE_TYPE (desc))))
1587     {
1588       /* Assignment of a CLASS array constructor to a derived type array.  */
1589       if (expr->expr_type == EXPR_FUNCTION)
1590         se->expr = gfc_evaluate_now (se->expr, pblock);
1591       se->expr = gfc_class_data_get (se->expr);
1592       se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
1593       se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1594       gfc_add_modify (&se->pre, tmp, se->expr);
1595     }
1596   else
1597     {
1598       /* TODO: Should the frontend already have done this conversion?  */
1599       se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1600       gfc_add_modify (&se->pre, tmp, se->expr);
1601     }
1602
1603   gfc_add_block_to_block (pblock, &se->pre);
1604   gfc_add_block_to_block (pblock, &se->post);
1605 }
1606
1607
1608 /* Add the contents of an array to the constructor.  DYNAMIC is as for
1609    gfc_trans_array_constructor_value.  */
1610
1611 static void
1612 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
1613                                       tree type ATTRIBUTE_UNUSED,
1614                                       tree desc, gfc_expr * expr,
1615                                       tree * poffset, tree * offsetvar,
1616                                       bool dynamic)
1617 {
1618   gfc_se se;
1619   gfc_ss *ss;
1620   gfc_loopinfo loop;
1621   stmtblock_t body;
1622   tree tmp;
1623   tree size;
1624   int n;
1625
1626   /* We need this to be a variable so we can increment it.  */
1627   gfc_put_offset_into_var (pblock, poffset, offsetvar);
1628
1629   gfc_init_se (&se, NULL);
1630
1631   /* Walk the array expression.  */
1632   ss = gfc_walk_expr (expr);
1633   gcc_assert (ss != gfc_ss_terminator);
1634
1635   /* Initialize the scalarizer.  */
1636   gfc_init_loopinfo (&loop);
1637   gfc_add_ss_to_loop (&loop, ss);
1638
1639   /* Initialize the loop.  */
1640   gfc_conv_ss_startstride (&loop);
1641   gfc_conv_loop_setup (&loop, &expr->where);
1642
1643   /* Make sure the constructed array has room for the new data.  */
1644   if (dynamic)
1645     {
1646       /* Set SIZE to the total number of elements in the subarray.  */
1647       size = gfc_index_one_node;
1648       for (n = 0; n < loop.dimen; n++)
1649         {
1650           tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
1651                                          gfc_index_one_node);
1652           size = fold_build2_loc (input_location, MULT_EXPR,
1653                                   gfc_array_index_type, size, tmp);
1654         }
1655
1656       /* Grow the constructed array by SIZE elements.  */
1657       gfc_grow_array (&loop.pre, desc, size);
1658     }
1659
1660   /* Make the loop body.  */
1661   gfc_mark_ss_chain_used (ss, 1);
1662   gfc_start_scalarized_body (&loop, &body);
1663   gfc_copy_loopinfo_to_se (&se, &loop);
1664   se.ss = ss;
1665
1666   gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
1667   gcc_assert (se.ss == gfc_ss_terminator);
1668
1669   /* Increment the offset.  */
1670   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1671                          *poffset, gfc_index_one_node);
1672   gfc_add_modify (&body, *poffset, tmp);
1673
1674   /* Finish the loop.  */
1675   gfc_trans_scalarizing_loops (&loop, &body);
1676   gfc_add_block_to_block (&loop.pre, &loop.post);
1677   tmp = gfc_finish_block (&loop.pre);
1678   gfc_add_expr_to_block (pblock, tmp);
1679
1680   gfc_cleanup_loop (&loop);
1681 }
1682
1683
1684 /* Assign the values to the elements of an array constructor.  DYNAMIC
1685    is true if descriptor DESC only contains enough data for the static
1686    size calculated by gfc_get_array_constructor_size.  When true, memory
1687    for the dynamic parts must be allocated using realloc.  */
1688
1689 static void
1690 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
1691                                    tree desc, gfc_constructor_base base,
1692                                    tree * poffset, tree * offsetvar,
1693                                    bool dynamic)
1694 {
1695   tree tmp;
1696   tree start = NULL_TREE;
1697   tree end = NULL_TREE;
1698   tree step = NULL_TREE;
1699   stmtblock_t body;
1700   gfc_se se;
1701   mpz_t size;
1702   gfc_constructor *c;
1703
1704   tree shadow_loopvar = NULL_TREE;
1705   gfc_saved_var saved_loopvar;
1706
1707   mpz_init (size);
1708   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1709     {
1710       /* If this is an iterator or an array, the offset must be a variable.  */
1711       if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
1712         gfc_put_offset_into_var (pblock, poffset, offsetvar);
1713
1714       /* Shadowing the iterator avoids changing its value and saves us from
1715          keeping track of it. Further, it makes sure that there's always a
1716          backend-decl for the symbol, even if there wasn't one before,
1717          e.g. in the case of an iterator that appears in a specification
1718          expression in an interface mapping.  */
1719       if (c->iterator)
1720         {
1721           gfc_symbol *sym;
1722           tree type;
1723
1724           /* Evaluate loop bounds before substituting the loop variable
1725              in case they depend on it.  Such a case is invalid, but it is
1726              not more expensive to do the right thing here.
1727              See PR 44354.  */
1728           gfc_init_se (&se, NULL);
1729           gfc_conv_expr_val (&se, c->iterator->start);
1730           gfc_add_block_to_block (pblock, &se.pre);
1731           start = gfc_evaluate_now (se.expr, pblock);
1732
1733           gfc_init_se (&se, NULL);
1734           gfc_conv_expr_val (&se, c->iterator->end);
1735           gfc_add_block_to_block (pblock, &se.pre);
1736           end = gfc_evaluate_now (se.expr, pblock);
1737
1738           gfc_init_se (&se, NULL);
1739           gfc_conv_expr_val (&se, c->iterator->step);
1740           gfc_add_block_to_block (pblock, &se.pre);
1741           step = gfc_evaluate_now (se.expr, pblock);
1742
1743           sym = c->iterator->var->symtree->n.sym;
1744           type = gfc_typenode_for_spec (&sym->ts);
1745
1746           shadow_loopvar = gfc_create_var (type, "shadow_loopvar");
1747           gfc_shadow_sym (sym, shadow_loopvar, &saved_loopvar);
1748         }
1749
1750       gfc_start_block (&body);
1751
1752       if (c->expr->expr_type == EXPR_ARRAY)
1753         {
1754           /* Array constructors can be nested.  */
1755           gfc_trans_array_constructor_value (&body, type, desc,
1756                                              c->expr->value.constructor,
1757                                              poffset, offsetvar, dynamic);
1758         }
1759       else if (c->expr->rank > 0)
1760         {
1761           gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
1762                                                 poffset, offsetvar, dynamic);
1763         }
1764       else
1765         {
1766           /* This code really upsets the gimplifier so don't bother for now.  */
1767           gfc_constructor *p;
1768           HOST_WIDE_INT n;
1769           HOST_WIDE_INT size;
1770
1771           p = c;
1772           n = 0;
1773           while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1774             {
1775               p = gfc_constructor_next (p);
1776               n++;
1777             }
1778           if (n < 4)
1779             {
1780               /* Scalar values.  */
1781               gfc_init_se (&se, NULL);
1782               gfc_trans_array_ctor_element (&body, desc, *poffset,
1783                                             &se, c->expr);
1784
1785               *poffset = fold_build2_loc (input_location, PLUS_EXPR,
1786                                           gfc_array_index_type,
1787                                           *poffset, gfc_index_one_node);
1788             }
1789           else
1790             {
1791               /* Collect multiple scalar constants into a constructor.  */
1792               vec<constructor_elt, va_gc> *v = NULL;
1793               tree init;
1794               tree bound;
1795               tree tmptype;
1796               HOST_WIDE_INT idx = 0;
1797
1798               p = c;
1799               /* Count the number of consecutive scalar constants.  */
1800               while (p && !(p->iterator
1801                             || p->expr->expr_type != EXPR_CONSTANT))
1802                 {
1803                   gfc_init_se (&se, NULL);
1804                   gfc_conv_constant (&se, p->expr);
1805
1806                   if (c->expr->ts.type != BT_CHARACTER)
1807                     se.expr = fold_convert (type, se.expr);
1808                   /* For constant character array constructors we build
1809                      an array of pointers.  */
1810                   else if (POINTER_TYPE_P (type))
1811                     se.expr = gfc_build_addr_expr
1812                                 (gfc_get_pchar_type (p->expr->ts.kind),
1813                                  se.expr);
1814
1815                   CONSTRUCTOR_APPEND_ELT (v,
1816                                           build_int_cst (gfc_array_index_type,
1817                                                          idx++),
1818                                           se.expr);
1819                   c = p;
1820                   p = gfc_constructor_next (p);
1821                 }
1822
1823               bound = size_int (n - 1);
1824               /* Create an array type to hold them.  */
1825               tmptype = build_range_type (gfc_array_index_type,
1826                                           gfc_index_zero_node, bound);
1827               tmptype = build_array_type (type, tmptype);
1828
1829               init = build_constructor (tmptype, v);
1830               TREE_CONSTANT (init) = 1;
1831               TREE_STATIC (init) = 1;
1832               /* Create a static variable to hold the data.  */
1833               tmp = gfc_create_var (tmptype, "data");
1834               TREE_STATIC (tmp) = 1;
1835               TREE_CONSTANT (tmp) = 1;
1836               TREE_READONLY (tmp) = 1;
1837               DECL_INITIAL (tmp) = init;
1838               init = tmp;
1839
1840               /* Use BUILTIN_MEMCPY to assign the values.  */
1841               tmp = gfc_conv_descriptor_data_get (desc);
1842               tmp = build_fold_indirect_ref_loc (input_location,
1843                                              tmp);
1844               tmp = gfc_build_array_ref (tmp, *poffset, NULL);
1845               tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1846               init = gfc_build_addr_expr (NULL_TREE, init);
1847
1848               size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1849               bound = build_int_cst (size_type_node, n * size);
1850               tmp = build_call_expr_loc (input_location,
1851                                          builtin_decl_explicit (BUILT_IN_MEMCPY),
1852                                          3, tmp, init, bound);
1853               gfc_add_expr_to_block (&body, tmp);
1854
1855               *poffset = fold_build2_loc (input_location, PLUS_EXPR,
1856                                       gfc_array_index_type, *poffset,
1857                                       build_int_cst (gfc_array_index_type, n));
1858             }
1859           if (!INTEGER_CST_P (*poffset))
1860             {
1861               gfc_add_modify (&body, *offsetvar, *poffset);
1862               *poffset = *offsetvar;
1863             }
1864         }
1865
1866       /* The frontend should already have done any expansions
1867          at compile-time.  */
1868       if (!c->iterator)
1869         {
1870           /* Pass the code as is.  */
1871           tmp = gfc_finish_block (&body);
1872           gfc_add_expr_to_block (pblock, tmp);
1873         }
1874       else
1875         {
1876           /* Build the implied do-loop.  */
1877           stmtblock_t implied_do_block;
1878           tree cond;
1879           tree exit_label;
1880           tree loopbody;
1881           tree tmp2;
1882
1883           loopbody = gfc_finish_block (&body);
1884
1885           /* Create a new block that holds the implied-do loop. A temporary
1886              loop-variable is used.  */
1887           gfc_start_block(&implied_do_block);
1888
1889           /* Initialize the loop.  */
1890           gfc_add_modify (&implied_do_block, shadow_loopvar, start);
1891
1892           /* If this array expands dynamically, and the number of iterations
1893              is not constant, we won't have allocated space for the static
1894              part of C->EXPR's size.  Do that now.  */
1895           if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1896             {
1897               /* Get the number of iterations.  */
1898               tmp = gfc_get_iteration_count (shadow_loopvar, end, step);
1899
1900               /* Get the static part of C->EXPR's size.  */
1901               gfc_get_array_constructor_element_size (&size, c->expr);
1902               tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1903
1904               /* Grow the array by TMP * TMP2 elements.  */
1905               tmp = fold_build2_loc (input_location, MULT_EXPR,
1906                                      gfc_array_index_type, tmp, tmp2);
1907               gfc_grow_array (&implied_do_block, desc, tmp);
1908             }
1909
1910           /* Generate the loop body.  */
1911           exit_label = gfc_build_label_decl (NULL_TREE);
1912           gfc_start_block (&body);
1913
1914           /* Generate the exit condition.  Depending on the sign of
1915              the step variable we have to generate the correct
1916              comparison.  */
1917           tmp = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
1918                                  step, build_int_cst (TREE_TYPE (step), 0));
1919           cond = fold_build3_loc (input_location, COND_EXPR,
1920                       logical_type_node, tmp,
1921                       fold_build2_loc (input_location, GT_EXPR,
1922                                        logical_type_node, shadow_loopvar, end),
1923                       fold_build2_loc (input_location, LT_EXPR,
1924                                        logical_type_node, shadow_loopvar, end));
1925           tmp = build1_v (GOTO_EXPR, exit_label);
1926           TREE_USED (exit_label) = 1;
1927           tmp = build3_v (COND_EXPR, cond, tmp,
1928                           build_empty_stmt (input_location));
1929           gfc_add_expr_to_block (&body, tmp);
1930
1931           /* The main loop body.  */
1932           gfc_add_expr_to_block (&body, loopbody);
1933
1934           /* Increase loop variable by step.  */
1935           tmp = fold_build2_loc (input_location, PLUS_EXPR,
1936                                  TREE_TYPE (shadow_loopvar), shadow_loopvar,
1937                                  step);
1938           gfc_add_modify (&body, shadow_loopvar, tmp);
1939
1940           /* Finish the loop.  */
1941           tmp = gfc_finish_block (&body);
1942           tmp = build1_v (LOOP_EXPR, tmp);
1943           gfc_add_expr_to_block (&implied_do_block, tmp);
1944
1945           /* Add the exit label.  */
1946           tmp = build1_v (LABEL_EXPR, exit_label);
1947           gfc_add_expr_to_block (&implied_do_block, tmp);
1948
1949           /* Finish the implied-do loop.  */
1950           tmp = gfc_finish_block(&implied_do_block);
1951           gfc_add_expr_to_block(pblock, tmp);
1952
1953           gfc_restore_sym (c->iterator->var->symtree->n.sym, &saved_loopvar);
1954         }
1955     }
1956   mpz_clear (size);
1957 }
1958
1959
1960 /* The array constructor code can create a string length with an operand
1961    in the form of a temporary variable.  This variable will retain its
1962    context (current_function_decl).  If we store this length tree in a
1963    gfc_charlen structure which is shared by a variable in another
1964    context, the resulting gfc_charlen structure with a variable in a
1965    different context, we could trip the assertion in expand_expr_real_1
1966    when it sees that a variable has been created in one context and
1967    referenced in another.
1968
1969    If this might be the case, we create a new gfc_charlen structure and
1970    link it into the current namespace.  */
1971
1972 static void
1973 store_backend_decl (gfc_charlen **clp, tree len, bool force_new_cl)
1974 {
1975   if (force_new_cl)
1976     {
1977       gfc_charlen *new_cl = gfc_new_charlen (gfc_current_ns, *clp);
1978       *clp = new_cl;
1979     }
1980   (*clp)->backend_decl = len;
1981 }
1982
1983 /* A catch-all to obtain the string length for anything that is not
1984    a substring of non-constant length, a constant, array or variable.  */
1985
1986 static void
1987 get_array_ctor_all_strlen (stmtblock_t *block, gfc_expr *e, tree *len)
1988 {
1989   gfc_se se;
1990
1991   /* Don't bother if we already know the length is a constant.  */
1992   if (*len && INTEGER_CST_P (*len))
1993     return;
1994
1995   if (!e->ref && e->ts.u.cl && e->ts.u.cl->length
1996         && e->ts.u.cl->length->expr_type == EXPR_CONSTANT)
1997     {
1998       /* This is easy.  */
1999       gfc_conv_const_charlen (e->ts.u.cl);
2000       *len = e->ts.u.cl->backend_decl;
2001     }
2002   else
2003     {
2004       /* Otherwise, be brutal even if inefficient.  */
2005       gfc_init_se (&se, NULL);
2006
2007       /* No function call, in case of side effects.  */
2008       se.no_function_call = 1;
2009       if (e->rank == 0)
2010         gfc_conv_expr (&se, e);
2011       else
2012         gfc_conv_expr_descriptor (&se, e);
2013
2014       /* Fix the value.  */
2015       *len = gfc_evaluate_now (se.string_length, &se.pre);
2016
2017       gfc_add_block_to_block (block, &se.pre);
2018       gfc_add_block_to_block (block, &se.post);
2019
2020       store_backend_decl (&e->ts.u.cl, *len, true);
2021     }
2022 }
2023
2024
2025 /* Figure out the string length of a variable reference expression.
2026    Used by get_array_ctor_strlen.  */
2027
2028 static void
2029 get_array_ctor_var_strlen (stmtblock_t *block, gfc_expr * expr, tree * len)
2030 {
2031   gfc_ref *ref;
2032   gfc_typespec *ts;
2033   mpz_t char_len;
2034
2035   /* Don't bother if we already know the length is a constant.  */
2036   if (*len && INTEGER_CST_P (*len))
2037     return;
2038
2039   ts = &expr->symtree->n.sym->ts;
2040   for (ref = expr->ref; ref; ref = ref->next)
2041     {
2042       switch (ref->type)
2043         {
2044         case REF_ARRAY:
2045           /* Array references don't change the string length.  */
2046           break;
2047
2048         case REF_COMPONENT:
2049           /* Use the length of the component.  */
2050           ts = &ref->u.c.component->ts;
2051           break;
2052
2053         case REF_SUBSTRING:
2054           if (ref->u.ss.start->expr_type != EXPR_CONSTANT
2055               || ref->u.ss.end->expr_type != EXPR_CONSTANT)
2056             {
2057               /* Note that this might evaluate expr.  */
2058               get_array_ctor_all_strlen (block, expr, len);
2059               return;
2060             }
2061           mpz_init_set_ui (char_len, 1);
2062           mpz_add (char_len, char_len, ref->u.ss.end->value.integer);
2063           mpz_sub (char_len, char_len, ref->u.ss.start->value.integer);
2064           *len = gfc_conv_mpz_to_tree_type (char_len, gfc_charlen_type_node);
2065           mpz_clear (char_len);
2066           return;
2067
2068         default:
2069          gcc_unreachable ();
2070         }
2071     }
2072
2073   *len = ts->u.cl->backend_decl;
2074 }
2075
2076
2077 /* Figure out the string length of a character array constructor.
2078    If len is NULL, don't calculate the length; this happens for recursive calls
2079    when a sub-array-constructor is an element but not at the first position,
2080    so when we're not interested in the length.
2081    Returns TRUE if all elements are character constants.  */
2082
2083 bool
2084 get_array_ctor_strlen (stmtblock_t *block, gfc_constructor_base base, tree * len)
2085 {
2086   gfc_constructor *c;
2087   bool is_const;
2088
2089   is_const = TRUE;
2090
2091   if (gfc_constructor_first (base) == NULL)
2092     {
2093       if (len)
2094         *len = build_int_cstu (gfc_charlen_type_node, 0);
2095       return is_const;
2096     }
2097
2098   /* Loop over all constructor elements to find out is_const, but in len we
2099      want to store the length of the first, not the last, element.  We can
2100      of course exit the loop as soon as is_const is found to be false.  */
2101   for (c = gfc_constructor_first (base);
2102        c && is_const; c = gfc_constructor_next (c))
2103     {
2104       switch (c->expr->expr_type)
2105         {
2106         case EXPR_CONSTANT:
2107           if (len && !(*len && INTEGER_CST_P (*len)))
2108             *len = build_int_cstu (gfc_charlen_type_node,
2109                                    c->expr->value.character.length);
2110           break;
2111
2112         case EXPR_ARRAY:
2113           if (!get_array_ctor_strlen (block, c->expr->value.constructor, len))
2114             is_const = false;
2115           break;
2116
2117         case EXPR_VARIABLE:
2118           is_const = false;
2119           if (len)
2120             get_array_ctor_var_strlen (block, c->expr, len);
2121           break;
2122
2123         default:
2124           is_const = false;
2125           if (len)
2126             get_array_ctor_all_strlen (block, c->expr, len);
2127           break;
2128         }
2129
2130       /* After the first iteration, we don't want the length modified.  */
2131       len = NULL;
2132     }
2133
2134   return is_const;
2135 }
2136
2137 /* Check whether the array constructor C consists entirely of constant
2138    elements, and if so returns the number of those elements, otherwise
2139    return zero.  Note, an empty or NULL array constructor returns zero.  */
2140
2141 unsigned HOST_WIDE_INT
2142 gfc_constant_array_constructor_p (gfc_constructor_base base)
2143 {
2144   unsigned HOST_WIDE_INT nelem = 0;
2145
2146   gfc_constructor *c = gfc_constructor_first (base);
2147   while (c)
2148     {
2149       if (c->iterator
2150           || c->expr->rank > 0
2151           || c->expr->expr_type != EXPR_CONSTANT)
2152         return 0;
2153       c = gfc_constructor_next (c);
2154       nelem++;
2155     }
2156   return nelem;
2157 }
2158
2159
2160 /* Given EXPR, the constant array constructor specified by an EXPR_ARRAY,
2161    and the tree type of it's elements, TYPE, return a static constant
2162    variable that is compile-time initialized.  */
2163
2164 tree
2165 gfc_build_constant_array_constructor (gfc_expr * expr, tree type)
2166 {
2167   tree tmptype, init, tmp;
2168   HOST_WIDE_INT nelem;
2169   gfc_constructor *c;
2170   gfc_array_spec as;
2171   gfc_se se;
2172   int i;
2173   vec<constructor_elt, va_gc> *v = NULL;
2174
2175   /* First traverse the constructor list, converting the constants
2176      to tree to build an initializer.  */
2177   nelem = 0;
2178   c = gfc_constructor_first (expr->value.constructor);
2179   while (c)
2180     {
2181       gfc_init_se (&se, NULL);
2182       gfc_conv_constant (&se, c->expr);
2183       if (c->expr->ts.type != BT_CHARACTER)
2184         se.expr = fold_convert (type, se.expr);
2185       else if (POINTER_TYPE_P (type))
2186         se.expr = gfc_build_addr_expr (gfc_get_pchar_type (c->expr->ts.kind),
2187                                        se.expr);
2188       CONSTRUCTOR_APPEND_ELT (v, build_int_cst (gfc_array_index_type, nelem),
2189                               se.expr);
2190       c = gfc_constructor_next (c);
2191       nelem++;
2192     }
2193
2194   /* Next determine the tree type for the array.  We use the gfortran
2195      front-end's gfc_get_nodesc_array_type in order to create a suitable
2196      GFC_ARRAY_TYPE_P that may be used by the scalarizer.  */
2197
2198   memset (&as, 0, sizeof (gfc_array_spec));
2199
2200   as.rank = expr->rank;
2201   as.type = AS_EXPLICIT;
2202   if (!expr->shape)
2203     {
2204       as.lower[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
2205       as.upper[0] = gfc_get_int_expr (gfc_default_integer_kind,
2206                                       NULL, nelem - 1);
2207     }
2208   else
2209     for (i = 0; i < expr->rank; i++)
2210       {
2211         int tmp = (int) mpz_get_si (expr->shape[i]);
2212         as.lower[i] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
2213         as.upper[i] = gfc_get_int_expr (gfc_default_integer_kind,
2214                                         NULL, tmp - 1);
2215       }
2216
2217   tmptype = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC, true);
2218
2219   /* as is not needed anymore.  */
2220   for (i = 0; i < as.rank + as.corank; i++)
2221     {
2222       gfc_free_expr (as.lower[i]);
2223       gfc_free_expr (as.upper[i]);
2224     }
2225
2226   init = build_constructor (tmptype, v);
2227
2228   TREE_CONSTANT (init) = 1;
2229   TREE_STATIC (init) = 1;
2230
2231   tmp = build_decl (input_location, VAR_DECL, create_tmp_var_name ("A"),
2232                     tmptype);
2233   DECL_ARTIFICIAL (tmp) = 1;
2234   DECL_IGNORED_P (tmp) = 1;
2235   TREE_STATIC (tmp) = 1;
2236   TREE_CONSTANT (tmp) = 1;
2237   TREE_READONLY (tmp) = 1;
2238   DECL_INITIAL (tmp) = init;
2239   pushdecl (tmp);
2240
2241   return tmp;
2242 }
2243
2244
2245 /* Translate a constant EXPR_ARRAY array constructor for the scalarizer.
2246    This mostly initializes the scalarizer state info structure with the
2247    appropriate values to directly use the array created by the function
2248    gfc_build_constant_array_constructor.  */
2249
2250 static void
2251 trans_constant_array_constructor (gfc_ss * ss, tree type)
2252 {
2253   gfc_array_info *info;
2254   tree tmp;
2255   int i;
2256
2257   tmp = gfc_build_constant_array_constructor (ss->info->expr, type);
2258
2259   info = &ss->info->data.array;
2260
2261   info->descriptor = tmp;
2262   info->data = gfc_build_addr_expr (NULL_TREE, tmp);
2263   info->offset = gfc_index_zero_node;
2264
2265   for (i = 0; i < ss->dimen; i++)
2266     {
2267       info->delta[i] = gfc_index_zero_node;
2268       info->start[i] = gfc_index_zero_node;
2269       info->end[i] = gfc_index_zero_node;
2270       info->stride[i] = gfc_index_one_node;
2271     }
2272 }
2273
2274
2275 static int
2276 get_rank (gfc_loopinfo *loop)
2277 {
2278   int rank;
2279
2280   rank = 0;
2281   for (; loop; loop = loop->parent)
2282     rank += loop->dimen;
2283
2284   return rank;
2285 }
2286
2287
2288 /* Helper routine of gfc_trans_array_constructor to determine if the
2289    bounds of the loop specified by LOOP are constant and simple enough
2290    to use with trans_constant_array_constructor.  Returns the
2291    iteration count of the loop if suitable, and NULL_TREE otherwise.  */
2292
2293 static tree
2294 constant_array_constructor_loop_size (gfc_loopinfo * l)
2295 {
2296   gfc_loopinfo *loop;
2297   tree size = gfc_index_one_node;
2298   tree tmp;
2299   int i, total_dim;
2300
2301   total_dim = get_rank (l);
2302
2303   for (loop = l; loop; loop = loop->parent)
2304     {
2305       for (i = 0; i < loop->dimen; i++)
2306         {
2307           /* If the bounds aren't constant, return NULL_TREE.  */
2308           if (!INTEGER_CST_P (loop->from[i]) || !INTEGER_CST_P (loop->to[i]))
2309             return NULL_TREE;
2310           if (!integer_zerop (loop->from[i]))
2311             {
2312               /* Only allow nonzero "from" in one-dimensional arrays.  */
2313               if (total_dim != 1)
2314                 return NULL_TREE;
2315               tmp = fold_build2_loc (input_location, MINUS_EXPR,
2316                                      gfc_array_index_type,
2317                                      loop->to[i], loop->from[i]);
2318             }
2319           else
2320             tmp = loop->to[i];
2321           tmp = fold_build2_loc (input_location, PLUS_EXPR,
2322                                  gfc_array_index_type, tmp, gfc_index_one_node);
2323           size = fold_build2_loc (input_location, MULT_EXPR,
2324                                   gfc_array_index_type, size, tmp);
2325         }
2326     }
2327
2328   return size;
2329 }
2330
2331
2332 static tree *
2333 get_loop_upper_bound_for_array (gfc_ss *array, int array_dim)
2334 {
2335   gfc_ss *ss;
2336   int n;
2337
2338   gcc_assert (array->nested_ss == NULL);
2339
2340   for (ss = array; ss; ss = ss->parent)
2341     for (n = 0; n < ss->loop->dimen; n++)
2342       if (array_dim == get_array_ref_dim_for_loop_dim (ss, n))
2343         return &(ss->loop->to[n]);
2344
2345   gcc_unreachable ();
2346 }
2347
2348
2349 static gfc_loopinfo *
2350 outermost_loop (gfc_loopinfo * loop)
2351 {
2352   while (loop->parent != NULL)
2353     loop = loop->parent;
2354
2355   return loop;
2356 }
2357
2358
2359 /* Array constructors are handled by constructing a temporary, then using that
2360    within the scalarization loop.  This is not optimal, but seems by far the
2361    simplest method.  */
2362
2363 static void
2364 trans_array_constructor (gfc_ss * ss, locus * where)
2365 {
2366   gfc_constructor_base c;
2367   tree offset;
2368   tree offsetvar;
2369   tree desc;
2370   tree type;
2371   tree tmp;
2372   tree *loop_ubound0;
2373   bool dynamic;
2374   bool old_first_len, old_typespec_chararray_ctor;
2375   tree old_first_len_val;
2376   gfc_loopinfo *loop, *outer_loop;
2377   gfc_ss_info *ss_info;
2378   gfc_expr *expr;
2379   gfc_ss *s;
2380   tree neg_len;
2381   char *msg;
2382
2383   /* Save the old values for nested checking.  */
2384   old_first_len = first_len;
2385   old_first_len_val = first_len_val;
2386   old_typespec_chararray_ctor = typespec_chararray_ctor;
2387
2388   loop = ss->loop;
2389   outer_loop = outermost_loop (loop);
2390   ss_info = ss->info;
2391   expr = ss_info->expr;
2392
2393   /* Do bounds-checking here and in gfc_trans_array_ctor_element only if no
2394      typespec was given for the array constructor.  */
2395   typespec_chararray_ctor = (expr->ts.type == BT_CHARACTER
2396                              && expr->ts.u.cl
2397                              && expr->ts.u.cl->length_from_typespec);
2398
2399   if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2400       && expr->ts.type == BT_CHARACTER && !typespec_chararray_ctor)
2401     {
2402       first_len_val = gfc_create_var (gfc_charlen_type_node, "len");
2403       first_len = true;
2404     }
2405
2406   gcc_assert (ss->dimen == ss->loop->dimen);
2407
2408   c = expr->value.constructor;
2409   if (expr->ts.type == BT_CHARACTER)
2410     {
2411       bool const_string;
2412       bool force_new_cl = false;
2413
2414       /* get_array_ctor_strlen walks the elements of the constructor, if a
2415          typespec was given, we already know the string length and want the one
2416          specified there.  */
2417       if (typespec_chararray_ctor && expr->ts.u.cl->length
2418           && expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
2419         {
2420           gfc_se length_se;
2421
2422           const_string = false;
2423           gfc_init_se (&length_se, NULL);
2424           gfc_conv_expr_type (&length_se, expr->ts.u.cl->length,
2425                               gfc_charlen_type_node);
2426           ss_info->string_length = length_se.expr;
2427
2428           /* Check if the character length is negative.  If it is, then
2429              set LEN = 0.  */
2430           neg_len = fold_build2_loc (input_location, LT_EXPR,
2431                                      logical_type_node, ss_info->string_length,
2432                                      build_zero_cst (TREE_TYPE
2433                                                      (ss_info->string_length)));
2434           /* Print a warning if bounds checking is enabled.  */
2435           if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2436             {
2437               msg = xasprintf ("Negative character length treated as LEN = 0");
2438               gfc_trans_runtime_check (false, true, neg_len, &length_se.pre,
2439                                        where, msg);
2440               free (msg);
2441             }
2442
2443           ss_info->string_length
2444             = fold_build3_loc (input_location, COND_EXPR,
2445                                gfc_charlen_type_node, neg_len,
2446                                build_zero_cst
2447                                (TREE_TYPE (ss_info->string_length)),
2448                                ss_info->string_length);
2449           ss_info->string_length = gfc_evaluate_now (ss_info->string_length,
2450                                                      &length_se.pre);
2451
2452           gfc_add_block_to_block (&outer_loop->pre, &length_se.pre);
2453           gfc_add_block_to_block (&outer_loop->post, &length_se.post);
2454         }
2455       else
2456         {
2457           const_string = get_array_ctor_strlen (&outer_loop->pre, c,
2458                                                 &ss_info->string_length);
2459           force_new_cl = true;
2460         }
2461
2462       /* Complex character array constructors should have been taken care of
2463          and not end up here.  */
2464       gcc_assert (ss_info->string_length);
2465
2466       store_backend_decl (&expr->ts.u.cl, ss_info->string_length, force_new_cl);
2467
2468       type = gfc_get_character_type_len (expr->ts.kind, ss_info->string_length);
2469       if (const_string)
2470         type = build_pointer_type (type);
2471     }
2472   else
2473     type = gfc_typenode_for_spec (expr->ts.type == BT_CLASS
2474                                   ? &CLASS_DATA (expr)->ts : &expr->ts);
2475
2476   /* See if the constructor determines the loop bounds.  */
2477   dynamic = false;
2478
2479   loop_ubound0 = get_loop_upper_bound_for_array (ss, 0);
2480
2481   if (expr->shape && get_rank (loop) > 1 && *loop_ubound0 == NULL_TREE)
2482     {
2483       /* We have a multidimensional parameter.  */
2484       for (s = ss; s; s = s->parent)
2485         {
2486           int n;
2487           for (n = 0; n < s->loop->dimen; n++)
2488             {
2489               s->loop->from[n] = gfc_index_zero_node;
2490               s->loop->to[n] = gfc_conv_mpz_to_tree (expr->shape[s->dim[n]],
2491                                                      gfc_index_integer_kind);
2492               s->loop->to[n] = fold_build2_loc (input_location, MINUS_EXPR,
2493                                                 gfc_array_index_type,
2494                                                 s->loop->to[n],
2495                                                 gfc_index_one_node);
2496             }
2497         }
2498     }
2499
2500   if (*loop_ubound0 == NULL_TREE)
2501     {
2502       mpz_t size;
2503
2504       /* We should have a 1-dimensional, zero-based loop.  */
2505       gcc_assert (loop->parent == NULL && loop->nested == NULL);
2506       gcc_assert (loop->dimen == 1);
2507       gcc_assert (integer_zerop (loop->from[0]));
2508
2509       /* Split the constructor size into a static part and a dynamic part.
2510          Allocate the static size up-front and record whether the dynamic
2511          size might be nonzero.  */
2512       mpz_init (size);
2513       dynamic = gfc_get_array_constructor_size (&size, c);
2514       mpz_sub_ui (size, size, 1);
2515       loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
2516       mpz_clear (size);
2517     }
2518
2519   /* Special case constant array constructors.  */
2520   if (!dynamic)
2521     {
2522       unsigned HOST_WIDE_INT nelem = gfc_constant_array_constructor_p (c);
2523       if (nelem > 0)
2524         {
2525           tree size = constant_array_constructor_loop_size (loop);
2526           if (size && compare_tree_int (size, nelem) == 0)
2527             {
2528               trans_constant_array_constructor (ss, type);
2529               goto finish;
2530             }
2531         }
2532     }
2533
2534   gfc_trans_create_temp_array (&outer_loop->pre, &outer_loop->post, ss, type,
2535                                NULL_TREE, dynamic, true, false, where);
2536
2537   desc = ss_info->data.array.descriptor;
2538   offset = gfc_index_zero_node;
2539   offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
2540   TREE_NO_WARNING (offsetvar) = 1;
2541   TREE_USED (offsetvar) = 0;
2542   gfc_trans_array_constructor_value (&outer_loop->pre, type, desc, c,
2543                                      &offset, &offsetvar, dynamic);
2544
2545   /* If the array grows dynamically, the upper bound of the loop variable
2546      is determined by the array's final upper bound.  */
2547   if (dynamic)
2548     {
2549       tmp = fold_build2_loc (input_location, MINUS_EXPR,
2550                              gfc_array_index_type,
2551                              offsetvar, gfc_index_one_node);
2552       tmp = gfc_evaluate_now (tmp, &outer_loop->pre);
2553       gfc_conv_descriptor_ubound_set (&loop->pre, desc, gfc_rank_cst[0], tmp);
2554       if (*loop_ubound0 && VAR_P (*loop_ubound0))
2555         gfc_add_modify (&outer_loop->pre, *loop_ubound0, tmp);
2556       else
2557         *loop_ubound0 = tmp;
2558     }
2559
2560   if (TREE_USED (offsetvar))
2561     pushdecl (offsetvar);
2562   else
2563     gcc_assert (INTEGER_CST_P (offset));
2564
2565 #if 0
2566   /* Disable bound checking for now because it's probably broken.  */
2567   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2568     {
2569       gcc_unreachable ();
2570     }
2571 #endif
2572
2573 finish:
2574   /* Restore old values of globals.  */
2575   first_len = old_first_len;
2576   first_len_val = old_first_len_val;
2577   typespec_chararray_ctor = old_typespec_chararray_ctor;
2578 }
2579
2580
2581 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
2582    called after evaluating all of INFO's vector dimensions.  Go through
2583    each such vector dimension and see if we can now fill in any missing
2584    loop bounds.  */
2585
2586 static void
2587 set_vector_loop_bounds (gfc_ss * ss)
2588 {
2589   gfc_loopinfo *loop, *outer_loop;
2590   gfc_array_info *info;
2591   gfc_se se;
2592   tree tmp;
2593   tree desc;
2594   tree zero;
2595   int n;
2596   int dim;
2597
2598   outer_loop = outermost_loop (ss->loop);
2599
2600   info = &ss->info->data.array;
2601
2602   for (; ss; ss = ss->parent)
2603     {
2604       loop = ss->loop;
2605
2606       for (n = 0; n < loop->dimen; n++)
2607         {
2608           dim = ss->dim[n];
2609           if (info->ref->u.ar.dimen_type[dim] != DIMEN_VECTOR
2610               || loop->to[n] != NULL)
2611             continue;
2612
2613           /* Loop variable N indexes vector dimension DIM, and we don't
2614              yet know the upper bound of loop variable N.  Set it to the
2615              difference between the vector's upper and lower bounds.  */
2616           gcc_assert (loop->from[n] == gfc_index_zero_node);
2617           gcc_assert (info->subscript[dim]
2618                       && info->subscript[dim]->info->type == GFC_SS_VECTOR);
2619
2620           gfc_init_se (&se, NULL);
2621           desc = info->subscript[dim]->info->data.array.descriptor;
2622           zero = gfc_rank_cst[0];
2623           tmp = fold_build2_loc (input_location, MINUS_EXPR,
2624                              gfc_array_index_type,
2625                              gfc_conv_descriptor_ubound_get (desc, zero),
2626                              gfc_conv_descriptor_lbound_get (desc, zero));
2627           tmp = gfc_evaluate_now (tmp, &outer_loop->pre);
2628           loop->to[n] = tmp;
2629         }
2630     }
2631 }
2632
2633
2634 /* Tells whether a scalar argument to an elemental procedure is saved out
2635    of a scalarization loop as a value or as a reference.  */
2636
2637 bool
2638 gfc_scalar_elemental_arg_saved_as_reference (gfc_ss_info * ss_info)
2639 {
2640   if (ss_info->type != GFC_SS_REFERENCE)
2641     return false;
2642
2643   /* If the actual argument can be absent (in other words, it can
2644      be a NULL reference), don't try to evaluate it; pass instead
2645      the reference directly.  */
2646   if (ss_info->can_be_null_ref)
2647     return true;
2648
2649   /* If the expression is of polymorphic type, it's actual size is not known,
2650      so we avoid copying it anywhere.  */
2651   if (ss_info->data.scalar.dummy_arg
2652       && ss_info->data.scalar.dummy_arg->ts.type == BT_CLASS
2653       && ss_info->expr->ts.type == BT_CLASS)
2654     return true;
2655
2656   /* If the expression is a data reference of aggregate type,
2657      and the data reference is not used on the left hand side,
2658      avoid a copy by saving a reference to the content.  */
2659   if (!ss_info->data.scalar.needs_temporary
2660       && (ss_info->expr->ts.type == BT_DERIVED
2661           || ss_info->expr->ts.type == BT_CLASS)
2662       && gfc_expr_is_variable (ss_info->expr))
2663     return true;
2664
2665   /* Otherwise the expression is evaluated to a temporary variable before the
2666      scalarization loop.  */
2667   return false;
2668 }
2669
2670
2671 /* Add the pre and post chains for all the scalar expressions in a SS chain
2672    to loop.  This is called after the loop parameters have been calculated,
2673    but before the actual scalarizing loops.  */
2674
2675 static void
2676 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript,
2677                       locus * where)
2678 {
2679   gfc_loopinfo *nested_loop, *outer_loop;
2680   gfc_se se;
2681   gfc_ss_info *ss_info;
2682   gfc_array_info *info;
2683   gfc_expr *expr;
2684   int n;
2685
2686   /* Don't evaluate the arguments for realloc_lhs_loop_for_fcn_call; otherwise,
2687      arguments could get evaluated multiple times.  */
2688   if (ss->is_alloc_lhs)
2689     return;
2690
2691   outer_loop = outermost_loop (loop);
2692
2693   /* TODO: This can generate bad code if there are ordering dependencies,
2694      e.g., a callee allocated function and an unknown size constructor.  */
2695   gcc_assert (ss != NULL);
2696
2697   for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
2698     {
2699       gcc_assert (ss);
2700
2701       /* Cross loop arrays are handled from within the most nested loop.  */
2702       if (ss->nested_ss != NULL)
2703         continue;
2704
2705       ss_info = ss->info;
2706       expr = ss_info->expr;
2707       info = &ss_info->data.array;
2708
2709       switch (ss_info->type)
2710         {
2711         case GFC_SS_SCALAR:
2712           /* Scalar expression.  Evaluate this now.  This includes elemental
2713              dimension indices, but not array section bounds.  */
2714           gfc_init_se (&se, NULL);
2715           gfc_conv_expr (&se, expr);
2716           gfc_add_block_to_block (&outer_loop->pre, &se.pre);
2717
2718           if (expr->ts.type != BT_CHARACTER
2719               && !gfc_is_alloc_class_scalar_function (expr))
2720             {
2721               /* Move the evaluation of scalar expressions outside the
2722                  scalarization loop, except for WHERE assignments.  */
2723               if (subscript)
2724                 se.expr = convert(gfc_array_index_type, se.expr);
2725               if (!ss_info->where)
2726                 se.expr = gfc_evaluate_now (se.expr, &outer_loop->pre);
2727               gfc_add_block_to_block (&outer_loop->pre, &se.post);
2728             }
2729           else
2730             gfc_add_block_to_block (&outer_loop->post, &se.post);
2731
2732           ss_info->data.scalar.value = se.expr;
2733           ss_info->string_length = se.string_length;
2734           break;
2735
2736         case GFC_SS_REFERENCE:
2737           /* Scalar argument to elemental procedure.  */
2738           gfc_init_se (&se, NULL);
2739           if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
2740             gfc_conv_expr_reference (&se, expr);
2741           else
2742             {
2743               /* Evaluate the argument outside the loop and pass
2744                  a reference to the value.  */
2745               gfc_conv_expr (&se, expr);
2746             }
2747
2748           /* Ensure that a pointer to the string is stored.  */
2749           if (expr->ts.type == BT_CHARACTER)
2750             gfc_conv_string_parameter (&se);
2751
2752           gfc_add_block_to_block (&outer_loop->pre, &se.pre);
2753           gfc_add_block_to_block (&outer_loop->post, &se.post);
2754           if (gfc_is_class_scalar_expr (expr))
2755             /* This is necessary because the dynamic type will always be
2756                large than the declared type.  In consequence, assigning
2757                the value to a temporary could segfault.
2758                OOP-TODO: see if this is generally correct or is the value
2759                has to be written to an allocated temporary, whose address
2760                is passed via ss_info.  */
2761             ss_info->data.scalar.value = se.expr;
2762           else
2763             ss_info->data.scalar.value = gfc_evaluate_now (se.expr,
2764                                                            &outer_loop->pre);
2765
2766           ss_info->string_length = se.string_length;
2767           break;
2768
2769         case GFC_SS_SECTION:
2770           /* Add the expressions for scalar and vector subscripts.  */
2771           for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2772             if (info->subscript[n])
2773               gfc_add_loop_ss_code (loop, info->subscript[n], true, where);
2774
2775           set_vector_loop_bounds (ss);
2776           break;
2777
2778         case GFC_SS_VECTOR:
2779           /* Get the vector's descriptor and store it in SS.  */
2780           gfc_init_se (&se, NULL);
2781           gfc_conv_expr_descriptor (&se, expr);
2782           gfc_add_block_to_block (&outer_loop->pre, &se.pre);
2783           gfc_add_block_to_block (&outer_loop->post, &se.post);
2784           info->descriptor = se.expr;
2785           break;
2786
2787         case GFC_SS_INTRINSIC:
2788           gfc_add_intrinsic_ss_code (loop, ss);
2789           break;
2790
2791         case GFC_SS_FUNCTION:
2792           /* Array function return value.  We call the function and save its
2793              result in a temporary for use inside the loop.  */
2794           gfc_init_se (&se, NULL);
2795           se.loop = loop;
2796           se.ss = ss;
2797           if (gfc_is_class_array_function (expr))
2798             expr->must_finalize = 1;
2799           gfc_conv_expr (&se, expr);
2800           gfc_add_block_to_block (&outer_loop->pre, &se.pre);
2801           gfc_add_block_to_block (&outer_loop->post, &se.post);
2802           ss_info->string_length = se.string_length;
2803           break;
2804
2805         case GFC_SS_CONSTRUCTOR:
2806           if (expr->ts.type == BT_CHARACTER
2807               && ss_info->string_length == NULL
2808               && expr->ts.u.cl
2809               && expr->ts.u.cl->length
2810               && expr->ts.u.cl->length->expr_type == EXPR_CONSTANT)
2811             {
2812               gfc_init_se (&se, NULL);
2813               gfc_conv_expr_type (&se, expr->ts.u.cl->length,
2814                                   gfc_charlen_type_node);
2815               ss_info->string_length = se.expr;
2816               gfc_add_block_to_block (&outer_loop->pre, &se.pre);
2817               gfc_add_block_to_block (&outer_loop->post, &se.post);
2818             }
2819           trans_array_constructor (ss, where);
2820           break;
2821
2822         case GFC_SS_TEMP:
2823         case GFC_SS_COMPONENT:
2824           /* Do nothing.  These are handled elsewhere.  */
2825           break;
2826
2827         default:
2828           gcc_unreachable ();
2829         }
2830     }
2831
2832   if (!subscript)
2833     for (nested_loop = loop->nested; nested_loop;
2834          nested_loop = nested_loop->next)
2835       gfc_add_loop_ss_code (nested_loop, nested_loop->ss, subscript, where);
2836 }
2837
2838
2839 /* Translate expressions for the descriptor and data pointer of a SS.  */
2840 /*GCC ARRAYS*/
2841
2842 static void
2843 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
2844 {
2845   gfc_se se;
2846   gfc_ss_info *ss_info;
2847   gfc_array_info *info;
2848   tree tmp;
2849
2850   ss_info = ss->info;
2851   info = &ss_info->data.array;
2852
2853   /* Get the descriptor for the array to be scalarized.  */
2854   gcc_assert (ss_info->expr->expr_type == EXPR_VARIABLE);
2855   gfc_init_se (&se, NULL);
2856   se.descriptor_only = 1;
2857   gfc_conv_expr_lhs (&se, ss_info->expr);
2858   gfc_add_block_to_block (block, &se.pre);
2859   info->descriptor = se.expr;
2860   ss_info->string_length = se.string_length;
2861
2862   if (base)
2863     {
2864       if (ss_info->expr->ts.type == BT_CHARACTER && !ss_info->expr->ts.deferred
2865           && ss_info->expr->ts.u.cl->length == NULL)
2866         {
2867           /* Emit a DECL_EXPR for the variable sized array type in
2868              GFC_TYPE_ARRAY_DATAPTR_TYPE so the gimplification of its type
2869              sizes works correctly.  */
2870           tree arraytype = TREE_TYPE (
2871                 GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (info->descriptor)));
2872           if (! TYPE_NAME (arraytype))
2873             TYPE_NAME (arraytype) = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
2874                                                 NULL_TREE, arraytype);
2875           gfc_add_expr_to_block (block, build1 (DECL_EXPR, arraytype,
2876                                                 TYPE_NAME (arraytype)));
2877         }
2878       /* Also the data pointer.  */
2879       tmp = gfc_conv_array_data (se.expr);
2880       /* If this is a variable or address of a variable we use it directly.
2881          Otherwise we must evaluate it now to avoid breaking dependency
2882          analysis by pulling the expressions for elemental array indices
2883          inside the loop.  */
2884       if (!(DECL_P (tmp)
2885             || (TREE_CODE (tmp) == ADDR_EXPR
2886                 && DECL_P (TREE_OPERAND (tmp, 0)))))
2887         tmp = gfc_evaluate_now (tmp, block);
2888       info->data = tmp;
2889
2890       tmp = gfc_conv_array_offset (se.expr);
2891       info->offset = gfc_evaluate_now (tmp, block);
2892
2893       /* Make absolutely sure that the saved_offset is indeed saved
2894          so that the variable is still accessible after the loops
2895          are translated.  */
2896       info->saved_offset = info->offset;
2897     }
2898 }
2899
2900
2901 /* Initialize a gfc_loopinfo structure.  */
2902
2903 void
2904 gfc_init_loopinfo (gfc_loopinfo * loop)
2905 {
2906   int n;
2907
2908   memset (loop, 0, sizeof (gfc_loopinfo));
2909   gfc_init_block (&loop->pre);
2910   gfc_init_block (&loop->post);
2911
2912   /* Initially scalarize in order and default to no loop reversal.  */
2913   for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
2914     {
2915       loop->order[n] = n;
2916       loop->reverse[n] = GFC_INHIBIT_REVERSE;
2917     }
2918
2919   loop->ss = gfc_ss_terminator;
2920 }
2921
2922
2923 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
2924    chain.  */
2925
2926 void
2927 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
2928 {
2929   se->loop = loop;
2930 }
2931
2932
2933 /* Return an expression for the data pointer of an array.  */
2934
2935 tree
2936 gfc_conv_array_data (tree descriptor)
2937 {
2938   tree type;
2939
2940   type = TREE_TYPE (descriptor);
2941   if (GFC_ARRAY_TYPE_P (type))
2942     {
2943       if (TREE_CODE (type) == POINTER_TYPE)
2944         return descriptor;
2945       else
2946         {
2947           /* Descriptorless arrays.  */
2948           return gfc_build_addr_expr (NULL_TREE, descriptor);
2949         }
2950     }
2951   else
2952     return gfc_conv_descriptor_data_get (descriptor);
2953 }
2954
2955
2956 /* Return an expression for the base offset of an array.  */
2957
2958 tree
2959 gfc_conv_array_offset (tree descriptor)
2960 {
2961   tree type;
2962
2963   type = TREE_TYPE (descriptor);
2964   if (GFC_ARRAY_TYPE_P (type))
2965     return GFC_TYPE_ARRAY_OFFSET (type);
2966   else
2967     return gfc_conv_descriptor_offset_get (descriptor);
2968 }
2969
2970
2971 /* Get an expression for the array stride.  */
2972
2973 tree
2974 gfc_conv_array_stride (tree descriptor, int dim)
2975 {
2976   tree tmp;
2977   tree type;
2978
2979   type = TREE_TYPE (descriptor);
2980
2981   /* For descriptorless arrays use the array size.  */
2982   tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
2983   if (tmp != NULL_TREE)
2984     return tmp;
2985
2986   tmp = gfc_conv_descriptor_stride_get (descriptor, gfc_rank_cst[dim]);
2987   return tmp;
2988 }
2989
2990
2991 /* Like gfc_conv_array_stride, but for the lower bound.  */
2992
2993 tree
2994 gfc_conv_array_lbound (tree descriptor, int dim)
2995 {
2996   tree tmp;
2997   tree type;
2998
2999   type = TREE_TYPE (descriptor);
3000
3001   tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
3002   if (tmp != NULL_TREE)
3003     return tmp;
3004
3005   tmp = gfc_conv_descriptor_lbound_get (descriptor, gfc_rank_cst[dim]);
3006   return tmp;
3007 }
3008
3009
3010 /* Like gfc_conv_array_stride, but for the upper bound.  */
3011
3012 tree
3013 gfc_conv_array_ubound (tree descriptor, int dim)
3014 {
3015   tree tmp;
3016   tree type;
3017
3018   type = TREE_TYPE (descriptor);
3019
3020   tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
3021   if (tmp != NULL_TREE)
3022     return tmp;
3023
3024   /* This should only ever happen when passing an assumed shape array
3025      as an actual parameter.  The value will never be used.  */
3026   if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
3027     return gfc_index_zero_node;
3028
3029   tmp = gfc_conv_descriptor_ubound_get (descriptor, gfc_rank_cst[dim]);
3030   return tmp;
3031 }
3032
3033
3034 /* Generate code to perform an array index bound check.  */
3035
3036 static tree
3037 trans_array_bound_check (gfc_se * se, gfc_ss *ss, tree index, int n,
3038                          locus * where, bool check_upper)
3039 {
3040   tree fault;
3041   tree tmp_lo, tmp_up;
3042   tree descriptor;
3043   char *msg;
3044   const char * name = NULL;
3045
3046   if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
3047     return index;
3048
3049   descriptor = ss->info->data.array.descriptor;
3050
3051   index = gfc_evaluate_now (index, &se->pre);
3052
3053   /* We find a name for the error message.  */
3054   name = ss->info->expr->symtree->n.sym->name;
3055   gcc_assert (name != NULL);
3056
3057   if (VAR_P (descriptor))
3058     name = IDENTIFIER_POINTER (DECL_NAME (descriptor));
3059
3060   /* If upper bound is present, include both bounds in the error message.  */
3061   if (check_upper)
3062     {
3063       tmp_lo = gfc_conv_array_lbound (descriptor, n);
3064       tmp_up = gfc_conv_array_ubound (descriptor, n);
3065
3066       if (name)
3067         msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
3068                          "outside of expected range (%%ld:%%ld)", n+1, name);
3069       else
3070         msg = xasprintf ("Index '%%ld' of dimension %d "
3071                          "outside of expected range (%%ld:%%ld)", n+1);
3072
3073       fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
3074                                index, tmp_lo);
3075       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
3076                                fold_convert (long_integer_type_node, index),
3077                                fold_convert (long_integer_type_node, tmp_lo),
3078                                fold_convert (long_integer_type_node, tmp_up));
3079       fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
3080                                index, tmp_up);
3081       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
3082                                fold_convert (long_integer_type_node, index),
3083                                fold_convert (long_integer_type_node, tmp_lo),
3084                                fold_convert (long_integer_type_node, tmp_up));
3085       free (msg);
3086     }
3087   else
3088     {
3089       tmp_lo = gfc_conv_array_lbound (descriptor, n);
3090
3091       if (name)
3092         msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
3093                          "below lower bound of %%ld", n+1, name);
3094       else
3095         msg = xasprintf ("Index '%%ld' of dimension %d "
3096                          "below lower bound of %%ld", n+1);
3097
3098       fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
3099                                index, tmp_lo);
3100       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
3101                                fold_convert (long_integer_type_node, index),
3102                                fold_convert (long_integer_type_node, tmp_lo));
3103       free (msg);
3104     }
3105
3106   return index;
3107 }
3108
3109
3110 /* Return the offset for an index.  Performs bound checking for elemental
3111    dimensions.  Single element references are processed separately.
3112    DIM is the array dimension, I is the loop dimension.  */
3113
3114 static tree
3115 conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i,
3116                          gfc_array_ref * ar, tree stride)
3117 {
3118   gfc_array_info *info;
3119   tree index;
3120   tree desc;
3121   tree data;
3122
3123   info = &ss->info->data.array;
3124
3125   /* Get the index into the array for this dimension.  */
3126   if (ar)
3127     {
3128       gcc_assert (ar->type != AR_ELEMENT);
3129       switch (ar->dimen_type[dim])
3130         {
3131         case DIMEN_THIS_IMAGE:
3132           gcc_unreachable ();
3133           break;
3134         case DIMEN_ELEMENT:
3135           /* Elemental dimension.  */
3136           gcc_assert (info->subscript[dim]
3137                       && info->subscript[dim]->info->type == GFC_SS_SCALAR);
3138           /* We've already translated this value outside the loop.  */
3139           index = info->subscript[dim]->info->data.scalar.value;
3140
3141           index = trans_array_bound_check (se, ss, index, dim, &ar->where,
3142                                            ar->as->type != AS_ASSUMED_SIZE
3143                                            || dim < ar->dimen - 1);
3144           break;
3145
3146         case DIMEN_VECTOR:
3147           gcc_assert (info && se->loop);
3148           gcc_assert (info->subscript[dim]
3149                       && info->subscript[dim]->info->type == GFC_SS_VECTOR);
3150           desc = info->subscript[dim]->info->data.array.descriptor;
3151
3152           /* Get a zero-based index into the vector.  */
3153           index = fold_build2_loc (input_location, MINUS_EXPR,
3154                                    gfc_array_index_type,
3155                                    se->loop->loopvar[i], se->loop->from[i]);
3156
3157           /* Multiply the index by the stride.  */
3158           index = fold_build2_loc (input_location, MULT_EXPR,
3159                                    gfc_array_index_type,
3160                                    index, gfc_conv_array_stride (desc, 0));
3161
3162           /* Read the vector to get an index into info->descriptor.  */
3163           data = build_fold_indirect_ref_loc (input_location,
3164                                           gfc_conv_array_data (desc));
3165           index = gfc_build_array_ref (data, index, NULL);
3166           index = gfc_evaluate_now (index, &se->pre);
3167           index = fold_convert (gfc_array_index_type, index);
3168
3169           /* Do any bounds checking on the final info->descriptor index.  */
3170           index = trans_array_bound_check (se, ss, index, dim, &ar->where,
3171                                            ar->as->type != AS_ASSUMED_SIZE
3172                                            || dim < ar->dimen - 1);
3173           break;
3174
3175         case DIMEN_RANGE:
3176           /* Scalarized dimension.  */
3177           gcc_assert (info && se->loop);
3178
3179           /* Multiply the loop variable by the stride and delta.  */
3180           index = se->loop->loopvar[i];
3181           if (!integer_onep (info->stride[dim]))
3182             index = fold_build2_loc (input_location, MULT_EXPR,
3183                                      gfc_array_index_type, index,
3184                                      info->stride[dim]);
3185           if (!integer_zerop (info->delta[dim]))
3186             index = fold_build2_loc (input_location, PLUS_EXPR,
3187                                      gfc_array_index_type, index,
3188                                      info->delta[dim]);
3189           break;
3190
3191         default:
3192           gcc_unreachable ();
3193         }
3194     }
3195   else
3196     {
3197       /* Temporary array or derived type component.  */
3198       gcc_assert (se->loop);
3199       index = se->loop->loopvar[se->loop->order[i]];
3200
3201       /* Pointer functions can have stride[0] different from unity.
3202          Use the stride returned by the function call and stored in
3203          the descriptor for the temporary.  */
3204       if (se->ss && se->ss->info->type == GFC_SS_FUNCTION
3205           && se->ss->info->expr
3206           && se->ss->info->expr->symtree
3207           && se->ss->info->expr->symtree->n.sym->result
3208           && se->ss->info->expr->symtree->n.sym->result->attr.pointer)
3209         stride = gfc_conv_descriptor_stride_get (info->descriptor,
3210                                                  gfc_rank_cst[dim]);
3211
3212       if (info->delta[dim] && !integer_zerop (info->delta[dim]))
3213         index = fold_build2_loc (input_location, PLUS_EXPR,
3214                                  gfc_array_index_type, index, info->delta[dim]);
3215     }
3216
3217   /* Multiply by the stride.  */
3218   if (stride != NULL && !integer_onep (stride))
3219     index = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3220                              index, stride);
3221
3222   return index;
3223 }
3224
3225
3226 /* Build a scalarized array reference using the vptr 'size'.  */
3227
3228 static bool
3229 build_class_array_ref (gfc_se *se, tree base, tree index)
3230 {
3231   tree type;
3232   tree size;
3233   tree offset;
3234   tree decl = NULL_TREE;
3235   tree tmp;
3236   gfc_expr *expr = se->ss->info->expr;
3237   gfc_ref *ref;
3238   gfc_ref *class_ref = NULL;
3239   gfc_typespec *ts;
3240
3241   if (se->expr && DECL_P (se->expr) && DECL_LANG_SPECIFIC (se->expr)
3242       && GFC_DECL_SAVED_DESCRIPTOR (se->expr)
3243       && GFC_CLASS_TYPE_P (TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (se->expr))))
3244     decl = se->expr;
3245   else
3246     {
3247       if (expr == NULL
3248           || (expr->ts.type != BT_CLASS
3249               && !gfc_is_class_array_function (expr)
3250               && !gfc_is_class_array_ref (expr, NULL)))
3251         return false;
3252
3253       if (expr->symtree && expr->symtree->n.sym->ts.type == BT_CLASS)
3254         ts = &expr->symtree->n.sym->ts;
3255       else
3256         ts = NULL;
3257
3258       for (ref = expr->ref; ref; ref = ref->next)
3259         {
3260           if (ref->type == REF_COMPONENT
3261               && ref->u.c.component->ts.type == BT_CLASS
3262               && ref->next && ref->next->type == REF_COMPONENT
3263               && strcmp (ref->next->u.c.component->name, "_data") == 0
3264               && ref->next->next
3265               && ref->next->next->type == REF_ARRAY
3266               && ref->next->next->u.ar.type != AR_ELEMENT)
3267             {
3268               ts = &ref->u.c.component->ts;
3269               class_ref = ref;
3270               break;
3271             }
3272         }
3273
3274       if (ts == NULL)
3275         return false;
3276     }
3277
3278   if (class_ref == NULL && expr && expr->symtree->n.sym->attr.function
3279       && expr->symtree->n.sym == expr->symtree->n.sym->result
3280       && expr->symtree->n.sym->backend_decl == current_function_decl)
3281     {
3282       decl = gfc_get_fake_result_decl (expr->symtree->n.sym, 0);
3283     }
3284   else if (expr && gfc_is_class_array_function (expr))
3285     {
3286       size = NULL_TREE;
3287       decl = NULL_TREE;
3288       for (tmp = base; tmp; tmp = TREE_OPERAND (tmp, 0))
3289         {
3290           tree type;
3291           type = TREE_TYPE (tmp);
3292           while (type)
3293             {
3294               if (GFC_CLASS_TYPE_P (type))
3295                 decl = tmp;
3296               if (type != TYPE_CANONICAL (type))
3297                 type = TYPE_CANONICAL (type);
3298               else
3299                 type = NULL_TREE;
3300             }
3301           if (VAR_P (tmp))
3302             break;
3303         }
3304
3305       if (decl == NULL_TREE)
3306         return false;
3307
3308       se->class_vptr = gfc_evaluate_now (gfc_class_vptr_get (decl), &se->pre);
3309     }
3310   else if (class_ref == NULL)
3311     {
3312       if (decl == NULL_TREE)
3313         decl = expr->symtree->n.sym->backend_decl;
3314       /* For class arrays the tree containing the class is stored in
3315          GFC_DECL_SAVED_DESCRIPTOR of the sym's backend_decl.
3316          For all others it's sym's backend_decl directly.  */
3317       if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
3318         decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
3319     }
3320   else
3321     {
3322       /* Remove everything after the last class reference, convert the
3323          expression and then recover its tailend once more.  */
3324       gfc_se tmpse;
3325       ref = class_ref->next;
3326       class_ref->next = NULL;
3327       gfc_init_se (&tmpse, NULL);
3328       gfc_conv_expr (&tmpse, expr);
3329       gfc_add_block_to_block (&se->pre, &tmpse.pre);
3330       decl = tmpse.expr;
3331       class_ref->next = ref;
3332     }
3333
3334   if (POINTER_TYPE_P (TREE_TYPE (decl)))
3335     decl = build_fold_indirect_ref_loc (input_location, decl);
3336
3337   if (!GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
3338     return false;
3339
3340   size = gfc_class_vtab_size_get (decl);
3341
3342   /* For unlimited polymorphic entities then _len component needs to be
3343      multiplied with the size.  If no _len component is present, then
3344      gfc_class_len_or_zero_get () return a zero_node.  */
3345   tmp = gfc_class_len_or_zero_get (decl);
3346   if (!integer_zerop (tmp))
3347     size = fold_build2 (MULT_EXPR, TREE_TYPE (index),
3348                         fold_convert (TREE_TYPE (index), size),
3349                         fold_build2 (MAX_EXPR, TREE_TYPE (index),
3350                                      fold_convert (TREE_TYPE (index), tmp),
3351                                      fold_convert (TREE_TYPE (index),
3352                                                    integer_one_node)));
3353   else
3354     size = fold_convert (TREE_TYPE (index), size);
3355
3356   /* Build the address of the element.  */
3357   type = TREE_TYPE (TREE_TYPE (base));
3358   offset = fold_build2_loc (input_location, MULT_EXPR,
3359                             gfc_array_index_type,
3360                             index, size);
3361   tmp = gfc_build_addr_expr (pvoid_type_node, base);
3362   tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
3363   tmp = fold_convert (build_pointer_type (type), tmp);
3364
3365   /* Return the element in the se expression.  */
3366   se->expr = build_fold_indirect_ref_loc (input_location, tmp);
3367   return true;
3368 }
3369
3370
3371 /* Build a scalarized reference to an array.  */
3372
3373 static void
3374 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
3375 {
3376   gfc_array_info *info;
3377   tree decl = NULL_TREE;
3378   tree index;
3379   tree base;
3380   gfc_ss *ss;
3381   gfc_expr *expr;
3382   int n;
3383
3384   ss = se->ss;
3385   expr = ss->info->expr;
3386   info = &ss->info->data.array;
3387   if (ar)
3388     n = se->loop->order[0];
3389   else
3390     n = 0;
3391
3392   index = conv_array_index_offset (se, ss, ss->dim[n], n, ar, info->stride0);
3393   /* Add the offset for this dimension to the stored offset for all other
3394      dimensions.  */
3395   if (info->offset && !integer_zerop (info->offset))
3396     index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3397                              index, info->offset);
3398
3399   base = build_fold_indirect_ref_loc (input_location, info->data);
3400
3401   /* Use the vptr 'size' field to access the element of a class array.  */
3402   if (build_class_array_ref (se, base, index))
3403     return;
3404
3405   if (expr && ((is_subref_array (expr)
3406                 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (info->descriptor)))
3407                || (expr->ts.deferred && (expr->expr_type == EXPR_VARIABLE
3408                                          || expr->expr_type == EXPR_FUNCTION))))
3409     decl = expr->symtree->n.sym->backend_decl;
3410
3411   /* A pointer array component can be detected from its field decl. Fix
3412      the descriptor, mark the resulting variable decl and pass it to
3413      gfc_build_array_ref.  */
3414   if (is_pointer_array (info->descriptor))
3415     {
3416       if (TREE_CODE (info->descriptor) == COMPONENT_REF)
3417         {
3418           decl = gfc_evaluate_now (info->descriptor, &se->pre);
3419           GFC_DECL_PTR_ARRAY_P (decl) = 1;
3420           TREE_USED (decl) = 1;
3421         }
3422       else if (TREE_CODE (info->descriptor) == INDIRECT_REF)
3423         decl = TREE_OPERAND (info->descriptor, 0);
3424
3425       if (decl == NULL_TREE)
3426         decl = info->descriptor;
3427     }
3428
3429   se->expr = gfc_build_array_ref (base, index, decl);
3430 }
3431
3432
3433 /* Translate access of temporary array.  */
3434
3435 void
3436 gfc_conv_tmp_array_ref (gfc_se * se)
3437 {
3438   se->string_length = se->ss->info->string_length;
3439   gfc_conv_scalarized_array_ref (se, NULL);
3440   gfc_advance_se_ss_chain (se);
3441 }
3442
3443 /* Add T to the offset pair *OFFSET, *CST_OFFSET.  */
3444
3445 static void
3446 add_to_offset (tree *cst_offset, tree *offset, tree t)
3447 {
3448   if (TREE_CODE (t) == INTEGER_CST)
3449     *cst_offset = int_const_binop (PLUS_EXPR, *cst_offset, t);
3450   else
3451     {
3452       if (!integer_zerop (*offset))
3453         *offset = fold_build2_loc (input_location, PLUS_EXPR,
3454                                    gfc_array_index_type, *offset, t);
3455       else
3456         *offset = t;
3457     }
3458 }
3459
3460
3461 static tree
3462 build_array_ref (tree desc, tree offset, tree decl, tree vptr)
3463 {
3464   tree tmp;
3465   tree type;
3466   tree cdesc;
3467
3468   /* For class arrays the class declaration is stored in the saved
3469      descriptor.  */
3470   if (INDIRECT_REF_P (desc)
3471       && DECL_LANG_SPECIFIC (TREE_OPERAND (desc, 0))
3472       && GFC_DECL_SAVED_DESCRIPTOR (TREE_OPERAND (desc, 0)))
3473     cdesc = gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (
3474                                   TREE_OPERAND (desc, 0)));
3475   else
3476     cdesc = desc;
3477
3478   /* Class container types do not always have the GFC_CLASS_TYPE_P
3479      but the canonical type does.  */
3480   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (cdesc))
3481       && TREE_CODE (cdesc) == COMPONENT_REF)
3482     {
3483       type = TREE_TYPE (TREE_OPERAND (cdesc, 0));
3484       if (TYPE_CANONICAL (type)
3485           && GFC_CLASS_TYPE_P (TYPE_CANONICAL (type)))
3486         vptr = gfc_class_vptr_get (TREE_OPERAND (cdesc, 0));
3487     }
3488
3489   tmp = gfc_conv_array_data (desc);
3490   tmp = build_fold_indirect_ref_loc (input_location, tmp);
3491   tmp = gfc_build_array_ref (tmp, offset, decl, vptr);
3492   return tmp;
3493 }
3494
3495
3496 /* Build an array reference.  se->expr already holds the array descriptor.
3497    This should be either a variable, indirect variable reference or component
3498    reference.  For arrays which do not have a descriptor, se->expr will be
3499    the data pointer.
3500    a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
3501
3502 void
3503 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr,
3504                     locus * where)
3505 {
3506   int n;
3507   tree offset, cst_offset;
3508   tree tmp;
3509   tree stride;
3510   tree decl = NULL_TREE;
3511   gfc_se indexse;
3512   gfc_se tmpse;
3513   gfc_symbol * sym = expr->symtree->n.sym;
3514   char *var_name = NULL;
3515
3516   if (ar->dimen == 0)
3517     {
3518       gcc_assert (ar->codimen);
3519
3520       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr)))
3521         se->expr = build_fold_indirect_ref (gfc_conv_array_data (se->expr));
3522       else
3523         {
3524           if (GFC_ARRAY_TYPE_P (TREE_TYPE (se->expr))
3525               && TREE_CODE (TREE_TYPE (se->expr)) == POINTER_TYPE)
3526             se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
3527
3528           /* Use the actual tree type and not the wrapped coarray.  */
3529           if (!se->want_pointer)
3530             se->expr = fold_convert (TYPE_MAIN_VARIANT (TREE_TYPE (se->expr)),
3531                                      se->expr);
3532         }
3533
3534       return;
3535     }
3536
3537   /* Handle scalarized references separately.  */
3538   if (ar->type != AR_ELEMENT)
3539     {
3540       gfc_conv_scalarized_array_ref (se, ar);
3541       gfc_advance_se_ss_chain (se);
3542       return;
3543     }
3544
3545   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3546     {
3547       size_t len;
3548       gfc_ref *ref;
3549
3550       len = strlen (sym->name) + 1;
3551       for (ref = expr->ref; ref; ref = ref->next)
3552         {
3553           if (ref->type == REF_ARRAY && &ref->u.ar == ar)
3554             break;
3555           if (ref->type == REF_COMPONENT)
3556             len += 2 + strlen (ref->u.c.component->name);
3557         }
3558
3559       var_name = XALLOCAVEC (char, len);
3560       strcpy (var_name, sym->name);
3561
3562       for (ref = expr->ref; ref; ref = ref->next)
3563         {
3564           if (ref->type == REF_ARRAY && &ref->u.ar == ar)
3565             break;
3566           if (ref->type == REF_COMPONENT)
3567             {
3568               strcat (var_name, "%%");
3569               strcat (var_name, ref->u.c.component->name);
3570             }
3571         }
3572     }
3573
3574   cst_offset = offset = gfc_index_zero_node;
3575   add_to_offset (&cst_offset, &offset, gfc_conv_array_offset (se->expr));
3576
3577   /* Calculate the offsets from all the dimensions.  Make sure to associate
3578      the final offset so that we form a chain of loop invariant summands.  */
3579   for (n = ar->dimen - 1; n >= 0; n--)
3580     {
3581       /* Calculate the index for this dimension.  */
3582       gfc_init_se (&indexse, se);
3583       gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
3584       gfc_add_block_to_block (&se->pre, &indexse.pre);
3585
3586       if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3587         {
3588           /* Check array bounds.  */
3589           tree cond;
3590           char *msg;
3591
3592           /* Evaluate the indexse.expr only once.  */
3593           indexse.expr = save_expr (indexse.expr);
3594
3595           /* Lower bound.  */
3596           tmp = gfc_conv_array_lbound (se->expr, n);
3597           if (sym->attr.temporary)
3598             {
3599               gfc_init_se (&tmpse, se);
3600               gfc_conv_expr_type (&tmpse, ar->as->lower[n],
3601                                   gfc_array_index_type);
3602               gfc_add_block_to_block (&se->pre, &tmpse.pre);
3603               tmp = tmpse.expr;
3604             }
3605
3606           cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
3607                                   indexse.expr, tmp);
3608           msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
3609                            "below lower bound of %%ld", n+1, var_name);
3610           gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
3611                                    fold_convert (long_integer_type_node,
3612                                                  indexse.expr),
3613                                    fold_convert (long_integer_type_node, tmp));
3614           free (msg);
3615
3616           /* Upper bound, but not for the last dimension of assumed-size
3617              arrays.  */
3618           if (n < ar->dimen - 1 || ar->as->type != AS_ASSUMED_SIZE)
3619             {
3620               tmp = gfc_conv_array_ubound (se->expr, n);
3621               if (sym->attr.temporary)
3622                 {
3623                   gfc_init_se (&tmpse, se);
3624                   gfc_conv_expr_type (&tmpse, ar->as->upper[n],
3625                                       gfc_array_index_type);
3626                   gfc_add_block_to_block (&se->pre, &tmpse.pre);
3627                   tmp = tmpse.expr;
3628                 }
3629
3630               cond = fold_build2_loc (input_location, GT_EXPR,
3631                                       logical_type_node, indexse.expr, tmp);
3632               msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
3633                                "above upper bound of %%ld", n+1, var_name);
3634               gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
3635                                    fold_convert (long_integer_type_node,
3636                                                  indexse.expr),
3637                                    fold_convert (long_integer_type_node, tmp));
3638               free (msg);
3639             }
3640         }
3641
3642       /* Multiply the index by the stride.  */
3643       stride = gfc_conv_array_stride (se->expr, n);
3644       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3645                              indexse.expr, stride);
3646
3647       /* And add it to the total.  */
3648       add_to_offset (&cst_offset, &offset, tmp);
3649     }
3650
3651   if (!integer_zerop (cst_offset))
3652     offset = fold_build2_loc (input_location, PLUS_EXPR,
3653                               gfc_array_index_type, offset, cst_offset);
3654
3655   /* A pointer array component can be detected from its field decl. Fix
3656      the descriptor, mark the resulting variable decl and pass it to
3657      build_array_ref.  */
3658   if (!expr->ts.deferred && !sym->attr.codimension
3659       && is_pointer_array (se->expr))
3660     {
3661       if (TREE_CODE (se->expr) == COMPONENT_REF)
3662         {
3663           decl = gfc_evaluate_now (se->expr, &se->pre);
3664           GFC_DECL_PTR_ARRAY_P (decl) = 1;
3665           TREE_USED (decl) = 1;
3666         }
3667       else if (TREE_CODE (se->expr) == INDIRECT_REF)
3668         decl = TREE_OPERAND (se->expr, 0);
3669       else
3670         decl = se->expr;
3671     }
3672   else if (expr->ts.deferred
3673            || (sym->ts.type == BT_CHARACTER
3674                && sym->attr.select_type_temporary))
3675     decl = sym->backend_decl;
3676   else if (sym->ts.type == BT_CLASS)
3677     decl = NULL_TREE;
3678
3679   se->expr = build_array_ref (se->expr, offset, decl, se->class_vptr);
3680 }
3681
3682
3683 /* Add the offset corresponding to array's ARRAY_DIM dimension and loop's
3684    LOOP_DIM dimension (if any) to array's offset.  */
3685
3686 static void
3687 add_array_offset (stmtblock_t *pblock, gfc_loopinfo *loop, gfc_ss *ss,
3688                   gfc_array_ref *ar, int array_dim, int loop_dim)
3689 {
3690   gfc_se se;
3691   gfc_array_info *info;
3692   tree stride, index;
3693
3694   info = &ss->info->data.array;
3695
3696   gfc_init_se (&se, NULL);
3697   se.loop = loop;
3698   se.expr = info->descriptor;
3699   stride = gfc_conv_array_stride (info->descriptor, array_dim);
3700   index = conv_array_index_offset (&se, ss, array_dim, loop_dim, ar, stride);
3701   gfc_add_block_to_block (pblock, &se.pre);
3702
3703   info->offset = fold_build2_loc (input_location, PLUS_EXPR,
3704                                   gfc_array_index_type,
3705                                   info->offset, index);
3706   info->offset = gfc_evaluate_now (info->offset, pblock);
3707 }
3708
3709
3710 /* Generate the code to be executed immediately before entering a
3711    scalarization loop.  */
3712
3713 static void
3714 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
3715                          stmtblock_t * pblock)
3716 {
3717   tree stride;
3718   gfc_ss_info *ss_info;
3719   gfc_array_info *info;
3720   gfc_ss_type ss_type;
3721   gfc_ss *ss, *pss;
3722   gfc_loopinfo *ploop;
3723   gfc_array_ref *ar;
3724   int i;
3725
3726   /* This code will be executed before entering the scalarization loop
3727      for this dimension.  */
3728   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3729     {
3730       ss_info = ss->info;
3731
3732       if ((ss_info->useflags & flag) == 0)
3733         continue;
3734
3735       ss_type = ss_info->type;
3736       if (ss_type != GFC_SS_SECTION
3737           && ss_type != GFC_SS_FUNCTION
3738           && ss_type != GFC_SS_CONSTRUCTOR
3739           && ss_type != GFC_SS_COMPONENT)
3740         continue;
3741
3742       info = &ss_info->data.array;
3743
3744       gcc_assert (dim < ss->dimen);
3745       gcc_assert (ss->dimen == loop->dimen);
3746
3747       if (info->ref)
3748         ar = &info->ref->u.ar;
3749       else
3750         ar = NULL;
3751
3752       if (dim == loop->dimen - 1 && loop->parent != NULL)
3753         {
3754           /* If we are in the outermost dimension of this loop, the previous
3755              dimension shall be in the parent loop.  */
3756           gcc_assert (ss->parent != NULL);
3757
3758           pss = ss->parent;
3759           ploop = loop->parent;
3760
3761           /* ss and ss->parent are about the same array.  */
3762           gcc_assert (ss_info == pss->info);
3763         }
3764       else
3765         {
3766           ploop = loop;
3767           pss = ss;
3768         }
3769
3770       if (dim == loop->dimen - 1)
3771         i = 0;
3772       else
3773         i = dim + 1;
3774
3775       /* For the time being, there is no loop reordering.  */
3776       gcc_assert (i == ploop->order[i]);
3777       i = ploop->order[i];
3778
3779       if (dim == loop->dimen - 1 && loop->parent == NULL)
3780         {
3781           stride = gfc_conv_array_stride (info->descriptor,
3782                                           innermost_ss (ss)->dim[i]);
3783
3784           /* Calculate the stride of the innermost loop.  Hopefully this will
3785              allow the backend optimizers to do their stuff more effectively.
3786            */
3787           info->stride0 = gfc_evaluate_now (stride, pblock);
3788
3789           /* For the outermost loop calculate the offset due to any
3790              elemental dimensions.  It will have been initialized with the
3791              base offset of the array.  */
3792           if (info->ref)
3793             {
3794               for (i = 0; i < ar->dimen; i++)
3795                 {
3796                   if (ar->dimen_type[i] != DIMEN_ELEMENT)
3797                     continue;
3798
3799                   add_array_offset (pblock, loop, ss, ar, i, /* unused */ -1);
3800                 }
3801             }
3802         }
3803       else
3804         /* Add the offset for the previous loop dimension.  */
3805         add_array_offset (pblock, ploop, ss, ar, pss->dim[i], i);
3806
3807       /* Remember this offset for the second loop.  */
3808       if (dim == loop->temp_dim - 1 && loop->parent == NULL)
3809         info->saved_offset = info->offset;
3810     }
3811 }
3812
3813
3814 /* Start a scalarized expression.  Creates a scope and declares loop
3815    variables.  */
3816
3817 void
3818 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
3819 {
3820   int dim;
3821   int n;
3822   int flags;
3823
3824   gcc_assert (!loop->array_parameter);
3825
3826   for (dim = loop->dimen - 1; dim >= 0; dim--)
3827     {
3828       n = loop->order[dim];
3829
3830       gfc_start_block (&loop->code[n]);
3831
3832       /* Create the loop variable.  */
3833       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
3834
3835       if (dim < loop->temp_dim)
3836         flags = 3;
3837       else
3838         flags = 1;
3839       /* Calculate values that will be constant within this loop.  */
3840       gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
3841     }
3842   gfc_start_block (pbody);
3843 }
3844
3845
3846 /* Generates the actual loop code for a scalarization loop.  */
3847
3848 void
3849 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
3850                                stmtblock_t * pbody)
3851 {
3852   stmtblock_t block;
3853   tree cond;
3854   tree tmp;
3855   tree loopbody;
3856   tree exit_label;
3857   tree stmt;
3858   tree init;
3859   tree incr;
3860
3861   if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS
3862                       | OMPWS_SCALARIZER_BODY))
3863       == (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)
3864       && n == loop->dimen - 1)
3865     {
3866       /* We create an OMP_FOR construct for the outermost scalarized loop.  */
3867       init = make_tree_vec (1);
3868       cond = make_tree_vec (1);
3869       incr = make_tree_vec (1);
3870
3871       /* Cycle statement is implemented with a goto.  Exit statement must not
3872          be present for this loop.  */
3873       exit_label = gfc_build_label_decl (NULL_TREE);
3874       TREE_USED (exit_label) = 1;
3875
3876       /* Label for cycle statements (if needed).  */
3877       tmp = build1_v (LABEL_EXPR, exit_label);
3878       gfc_add_expr_to_block (pbody, tmp);
3879
3880       stmt = make_node (OMP_FOR);
3881
3882       TREE_TYPE (stmt) = void_type_node;
3883       OMP_FOR_BODY (stmt) = loopbody = gfc_finish_block (pbody);
3884
3885       OMP_FOR_CLAUSES (stmt) = build_omp_clause (input_location,
3886                                                  OMP_CLAUSE_SCHEDULE);
3887       OMP_CLAUSE_SCHEDULE_KIND (OMP_FOR_CLAUSES (stmt))
3888         = OMP_CLAUSE_SCHEDULE_STATIC;
3889       if (ompws_flags & OMPWS_NOWAIT)
3890         OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (stmt))
3891           = build_omp_clause (input_location, OMP_CLAUSE_NOWAIT);
3892
3893       /* Initialize the loopvar.  */
3894       TREE_VEC_ELT (init, 0) = build2_v (MODIFY_EXPR, loop->loopvar[n],
3895                                          loop->from[n]);
3896       OMP_FOR_INIT (stmt) = init;
3897       /* The exit condition.  */
3898       TREE_VEC_ELT (cond, 0) = build2_loc (input_location, LE_EXPR,
3899                                            logical_type_node,
3900                                            loop->loopvar[n], loop->to[n]);
3901       SET_EXPR_LOCATION (TREE_VEC_ELT (cond, 0), input_location);
3902       OMP_FOR_COND (stmt) = cond;
3903       /* Increment the loopvar.  */
3904       tmp = build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3905                         loop->loopvar[n], gfc_index_one_node);
3906       TREE_VEC_ELT (incr, 0) = fold_build2_loc (input_location, MODIFY_EXPR,
3907           void_type_node, loop->loopvar[n], tmp);
3908       OMP_FOR_INCR (stmt) = incr;
3909
3910       ompws_flags &= ~OMPWS_CURR_SINGLEUNIT;
3911       gfc_add_expr_to_block (&loop->code[n], stmt);
3912     }
3913   else
3914     {
3915       bool reverse_loop = (loop->reverse[n] == GFC_REVERSE_SET)
3916                              && (loop->temp_ss == NULL);
3917
3918       loopbody = gfc_finish_block (pbody);
3919
3920       if (reverse_loop)
3921         std::swap (loop->from[n], loop->to[n]);
3922
3923       /* Initialize the loopvar.  */
3924       if (loop->loopvar[n] != loop->from[n])
3925         gfc_add_modify (&loop->code[n], loop->loopvar[n], loop->from[n]);
3926
3927       exit_label = gfc_build_label_decl (NULL_TREE);
3928
3929       /* Generate the loop body.  */
3930       gfc_init_block (&block);
3931
3932       /* The exit condition.  */
3933       cond = fold_build2_loc (input_location, reverse_loop ? LT_EXPR : GT_EXPR,
3934                           logical_type_node, loop->loopvar[n], loop->to[n]);
3935       tmp = build1_v (GOTO_EXPR, exit_label);
3936       TREE_USED (exit_label) = 1;
3937       tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
3938       gfc_add_expr_to_block (&block, tmp);
3939
3940       /* The main body.  */
3941       gfc_add_expr_to_block (&block, loopbody);
3942
3943       /* Increment the loopvar.  */
3944       tmp = fold_build2_loc (input_location,
3945                              reverse_loop ? MINUS_EXPR : PLUS_EXPR,
3946                              gfc_array_index_type, loop->loopvar[n],
3947                              gfc_index_one_node);
3948
3949       gfc_add_modify (&block, loop->loopvar[n], tmp);
3950
3951       /* Build the loop.  */
3952       tmp = gfc_finish_block (&block);
3953       tmp = build1_v (LOOP_EXPR, tmp);
3954       gfc_add_expr_to_block (&loop->code[n], tmp);
3955
3956       /* Add the exit label.  */
3957       tmp = build1_v (LABEL_EXPR, exit_label);
3958       gfc_add_expr_to_block (&loop->code[n], tmp);
3959     }
3960
3961 }
3962
3963
3964 /* Finishes and generates the loops for a scalarized expression.  */
3965
3966 void
3967 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
3968 {
3969   int dim;
3970   int n;
3971   gfc_ss *ss;
3972   stmtblock_t *pblock;
3973   tree tmp;
3974
3975   pblock = body;
3976   /* Generate the loops.  */
3977   for (dim = 0; dim < loop->dimen; dim++)
3978     {
3979       n = loop->order[dim];
3980       gfc_trans_scalarized_loop_end (loop, n, pblock);
3981       loop->loopvar[n] = NULL_TREE;
3982       pblock = &loop->code[n];
3983     }
3984
3985   tmp = gfc_finish_block (pblock);
3986   gfc_add_expr_to_block (&loop->pre, tmp);
3987
3988   /* Clear all the used flags.  */
3989   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3990     if (ss->parent == NULL)
3991       ss->info->useflags = 0;
3992 }
3993
3994
3995 /* Finish the main body of a scalarized expression, and start the secondary
3996    copying body.  */
3997
3998 void
3999 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
4000 {
4001   int dim;
4002   int n;
4003   stmtblock_t *pblock;
4004   gfc_ss *ss;
4005
4006   pblock = body;
4007   /* We finish as many loops as are used by the temporary.  */
4008   for (dim = 0; dim < loop->temp_dim - 1; dim++)
4009     {
4010       n = loop->order[dim];
4011       gfc_trans_scalarized_loop_end (loop, n, pblock);
4012       loop->loopvar[n] = NULL_TREE;
4013       pblock = &loop->code[n];
4014     }
4015
4016   /* We don't want to finish the outermost loop entirely.  */
4017   n = loop->order[loop->temp_dim - 1];
4018   gfc_trans_scalarized_loop_end (loop, n, pblock);
4019
4020   /* Restore the initial offsets.  */
4021   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4022     {
4023       gfc_ss_type ss_type;
4024       gfc_ss_info *ss_info;
4025
4026       ss_info = ss->info;
4027
4028       if ((ss_info->useflags & 2) == 0)
4029         continue;
4030
4031       ss_type = ss_info->type;
4032       if (ss_type != GFC_SS_SECTION
4033           && ss_type != GFC_SS_FUNCTION
4034           && ss_type != GFC_SS_CONSTRUCTOR
4035           && ss_type != GFC_SS_COMPONENT)
4036         continue;
4037
4038       ss_info->data.array.offset = ss_info->data.array.saved_offset;
4039     }
4040
4041   /* Restart all the inner loops we just finished.  */
4042   for (dim = loop->temp_dim - 2; dim >= 0; dim--)
4043     {
4044       n = loop->order[dim];
4045
4046       gfc_start_block (&loop->code[n]);
4047
4048       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
4049
4050       gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
4051     }
4052
4053   /* Start a block for the secondary copying code.  */
4054   gfc_start_block (body);
4055 }
4056
4057
4058 /* Precalculate (either lower or upper) bound of an array section.
4059      BLOCK: Block in which the (pre)calculation code will go.
4060      BOUNDS[DIM]: Where the bound value will be stored once evaluated.
4061      VALUES[DIM]: Specified bound (NULL <=> unspecified).
4062      DESC: Array descriptor from which the bound will be picked if unspecified
4063        (either lower or upper bound according to LBOUND).  */
4064
4065 static void
4066 evaluate_bound (stmtblock_t *block, tree *bounds, gfc_expr ** values,
4067                 tree desc, int dim, bool lbound, bool deferred)
4068 {
4069   gfc_se se;
4070   gfc_expr * input_val = values[dim];
4071   tree *output = &bounds[dim];
4072
4073
4074   if (input_val)
4075     {
4076       /* Specified section bound.  */
4077       gfc_init_se (&se, NULL);
4078       gfc_conv_expr_type (&se, input_val, gfc_array_index_type);
4079       gfc_add_block_to_block (block, &se.pre);
4080       *output = se.expr;
4081     }
4082   else if (deferred && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
4083     {
4084       /* The gfc_conv_array_lbound () routine returns a constant zero for
4085          deferred length arrays, which in the scalarizer wreaks havoc, when
4086          copying to a (newly allocated) one-based array.
4087          Keep returning the actual result in sync for both bounds.  */
4088       *output = lbound ? gfc_conv_descriptor_lbound_get (desc,
4089                                                          gfc_rank_cst[dim]):
4090                          gfc_conv_descriptor_ubound_get (desc,
4091                                                          gfc_rank_cst[dim]);
4092     }
4093   else
4094     {
4095       /* No specific bound specified so use the bound of the array.  */
4096       *output = lbound ? gfc_conv_array_lbound (desc, dim) :
4097                          gfc_conv_array_ubound (desc, dim);
4098     }
4099   *output = gfc_evaluate_now (*output, block);
4100 }
4101
4102
4103 /* Calculate the lower bound of an array section.  */
4104
4105 static void
4106 gfc_conv_section_startstride (stmtblock_t * block, gfc_ss * ss, int dim)
4107 {
4108   gfc_expr *stride = NULL;
4109   tree desc;
4110   gfc_se se;
4111   gfc_array_info *info;
4112   gfc_array_ref *ar;
4113
4114   gcc_assert (ss->info->type == GFC_SS_SECTION);
4115
4116   info = &ss->info->data.array;
4117   ar = &info->ref->u.ar;
4118
4119   if (ar->dimen_type[dim] == DIMEN_VECTOR)
4120     {
4121       /* We use a zero-based index to access the vector.  */
4122       info->start[dim] = gfc_index_zero_node;
4123       info->end[dim] = NULL;
4124       info->stride[dim] = gfc_index_one_node;
4125       return;
4126     }
4127
4128   gcc_assert (ar->dimen_type[dim] == DIMEN_RANGE
4129               || ar->dimen_type[dim] == DIMEN_THIS_IMAGE);
4130   desc = info->descriptor;
4131   stride = ar->stride[dim];
4132
4133
4134   /* Calculate the start of the range.  For vector subscripts this will
4135      be the range of the vector.  */
4136   evaluate_bound (block, info->start, ar->start, desc, dim, true,
4137                   ar->as->type == AS_DEFERRED);
4138
4139   /* Similarly calculate the end.  Although this is not used in the
4140      scalarizer, it is needed when checking bounds and where the end
4141      is an expression with side-effects.  */
4142   evaluate_bound (block, info->end, ar->end, desc, dim, false,
4143                   ar->as->type == AS_DEFERRED);
4144
4145
4146   /* Calculate the stride.  */
4147   if (stride == NULL)
4148     info->stride[dim] = gfc_index_one_node;
4149   else
4150     {
4151       gfc_init_se (&se, NULL);
4152       gfc_conv_expr_type (&se, stride, gfc_array_index_type);
4153       gfc_add_block_to_block (block, &se.pre);
4154       info->stride[dim] = gfc_evaluate_now (se.expr, block);
4155     }
4156 }
4157
4158
4159 /* Calculates the range start and stride for a SS chain.  Also gets the
4160    descriptor and data pointer.  The range of vector subscripts is the size
4161    of the vector.  Array bounds are also checked.  */
4162
4163 void
4164 gfc_conv_ss_startstride (gfc_loopinfo * loop)
4165 {
4166   int n;
4167   tree tmp;
4168   gfc_ss *ss;
4169   tree desc;
4170
4171   gfc_loopinfo * const outer_loop = outermost_loop (loop);
4172
4173   loop->dimen = 0;
4174   /* Determine the rank of the loop.  */
4175   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4176     {
4177       switch (ss->info->type)
4178         {
4179         case GFC_SS_SECTION:
4180         case GFC_SS_CONSTRUCTOR:
4181         case GFC_SS_FUNCTION:
4182         case GFC_SS_COMPONENT:
4183           loop->dimen = ss->dimen;
4184           goto done;
4185
4186         /* As usual, lbound and ubound are exceptions!.  */
4187         case GFC_SS_INTRINSIC:
4188           switch (ss->info->expr->value.function.isym->id)
4189             {
4190             case GFC_ISYM_LBOUND:
4191             case GFC_ISYM_UBOUND:
4192             case GFC_ISYM_LCOBOUND:
4193             case GFC_ISYM_UCOBOUND:
4194             case GFC_ISYM_THIS_IMAGE:
4195               loop->dimen = ss->dimen;
4196               goto done;
4197
4198             default:
4199               break;
4200             }
4201
4202         default:
4203           break;
4204         }
4205     }
4206
4207   /* We should have determined the rank of the expression by now.  If
4208      not, that's bad news.  */
4209   gcc_unreachable ();
4210
4211 done:
4212   /* Loop over all the SS in the chain.  */
4213   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4214     {
4215       gfc_ss_info *ss_info;
4216       gfc_array_info *info;
4217       gfc_expr *expr;
4218
4219       ss_info = ss->info;
4220       expr = ss_info->expr;
4221       info = &ss_info->data.array;
4222
4223       if (expr && expr->shape && !info->shape)
4224         info->shape = expr->shape;
4225
4226       switch (ss_info->type)
4227         {
4228         case GFC_SS_SECTION:
4229           /* Get the descriptor for the array.  If it is a cross loops array,
4230              we got the descriptor already in the outermost loop.  */
4231           if (ss->parent == NULL)
4232             gfc_conv_ss_descriptor (&outer_loop->pre, ss,
4233                                     !loop->array_parameter);
4234
4235           for (n = 0; n < ss->dimen; n++)
4236             gfc_conv_section_startstride (&outer_loop->pre, ss, ss->dim[n]);
4237           break;
4238
4239         case GFC_SS_INTRINSIC:
4240           switch (expr->value.function.isym->id)
4241             {
4242             /* Fall through to supply start and stride.  */
4243             case GFC_ISYM_LBOUND:
4244             case GFC_ISYM_UBOUND:
4245               {
4246                 gfc_expr *arg;
4247
4248                 /* This is the variant without DIM=...  */
4249                 gcc_assert (expr->value.function.actual->next->expr == NULL);
4250
4251                 arg = expr->value.function.actual->expr;
4252                 if (arg->rank == -1)
4253                   {
4254                     gfc_se se;
4255                     tree rank, tmp;
4256
4257                     /* The rank (hence the return value's shape) is unknown,
4258                        we have to retrieve it.  */
4259                     gfc_init_se (&se, NULL);
4260                     se.descriptor_only = 1;
4261                     gfc_conv_expr (&se, arg);
4262                     /* This is a bare variable, so there is no preliminary
4263                        or cleanup code.  */
4264                     gcc_assert (se.pre.head == NULL_TREE
4265                                 && se.post.head == NULL_TREE);
4266                     rank = gfc_conv_descriptor_rank (se.expr);
4267                     tmp = fold_build2_loc (input_location, MINUS_EXPR,
4268                                            gfc_array_index_type,
4269                                            fold_convert (gfc_array_index_type,
4270                                                          rank),
4271                                            gfc_index_one_node);
4272                     info->end[0] = gfc_evaluate_now (tmp, &outer_loop->pre);
4273                     info->start[0] = gfc_index_zero_node;
4274                     info->stride[0] = gfc_index_one_node;
4275                     continue;
4276                   }
4277                   /* Otherwise fall through GFC_SS_FUNCTION.  */
4278                   gcc_fallthrough ();
4279               }
4280             case GFC_ISYM_LCOBOUND:
4281             case GFC_ISYM_UCOBOUND:
4282             case GFC_ISYM_THIS_IMAGE:
4283               break;
4284
4285             default:
4286               continue;
4287             }
4288
4289           /* FALLTHRU */
4290         case GFC_SS_CONSTRUCTOR:
4291         case GFC_SS_FUNCTION:
4292           for (n = 0; n < ss->dimen; n++)
4293             {
4294               int dim = ss->dim[n];
4295
4296               info->start[dim]  = gfc_index_zero_node;
4297               info->end[dim]    = gfc_index_zero_node;
4298               info->stride[dim] = gfc_index_one_node;
4299             }
4300           break;
4301
4302         default:
4303           break;
4304         }
4305     }
4306
4307   /* The rest is just runtime bound checking.  */
4308   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
4309     {
4310       stmtblock_t block;
4311       tree lbound, ubound;
4312       tree end;
4313       tree size[GFC_MAX_DIMENSIONS];
4314       tree stride_pos, stride_neg, non_zerosized, tmp2, tmp3;
4315       gfc_array_info *info;
4316       char *msg;
4317       int dim;
4318
4319       gfc_start_block (&block);
4320
4321       for (n = 0; n < loop->dimen; n++)
4322         size[n] = NULL_TREE;
4323
4324       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4325         {
4326           stmtblock_t inner;
4327           gfc_ss_info *ss_info;
4328           gfc_expr *expr;
4329           locus *expr_loc;
4330           const char *expr_name;
4331
4332           ss_info = ss->info;
4333           if (ss_info->type != GFC_SS_SECTION)
4334             continue;
4335
4336           /* Catch allocatable lhs in f2003.  */
4337           if (flag_realloc_lhs && ss->is_alloc_lhs)
4338             continue;
4339
4340           expr = ss_info->expr;
4341           expr_loc = &expr->where;
4342           expr_name = expr->symtree->name;
4343
4344           gfc_start_block (&inner);
4345
4346           /* TODO: range checking for mapped dimensions.  */
4347           info = &ss_info->data.array;
4348
4349           /* This code only checks ranges.  Elemental and vector
4350              dimensions are checked later.  */
4351           for (n = 0; n < loop->dimen; n++)
4352             {
4353               bool check_upper;
4354
4355               dim = ss->dim[n];
4356               if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
4357                 continue;
4358
4359               if (dim == info->ref->u.ar.dimen - 1
4360                   && info->ref->u.ar.as->type == AS_ASSUMED_SIZE)
4361                 check_upper = false;
4362               else
4363                 check_upper = true;
4364
4365               /* Zero stride is not allowed.  */
4366               tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
4367                                      info->stride[dim], gfc_index_zero_node);
4368               msg = xasprintf ("Zero stride is not allowed, for dimension %d "
4369                                "of array '%s'", dim + 1, expr_name);
4370               gfc_trans_runtime_check (true, false, tmp, &inner,
4371                                        expr_loc, msg);
4372               free (msg);
4373
4374               desc = info->descriptor;
4375
4376               /* This is the run-time equivalent of resolve.c's
4377                  check_dimension().  The logical is more readable there
4378                  than it is here, with all the trees.  */
4379               lbound = gfc_conv_array_lbound (desc, dim);
4380               end = info->end[dim];
4381               if (check_upper)
4382                 ubound = gfc_conv_array_ubound (desc, dim);
4383               else
4384                 ubound = NULL;
4385
4386               /* non_zerosized is true when the selected range is not
4387                  empty.  */
4388               stride_pos = fold_build2_loc (input_location, GT_EXPR,
4389                                         logical_type_node, info->stride[dim],
4390                                         gfc_index_zero_node);
4391               tmp = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
4392                                      info->start[dim], end);
4393               stride_pos = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4394                                             logical_type_node, stride_pos, tmp);
4395
4396               stride_neg = fold_build2_loc (input_location, LT_EXPR,
4397                                      logical_type_node,
4398                                      info->stride[dim], gfc_index_zero_node);
4399               tmp = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
4400                                      info->start[dim], end);
4401               stride_neg = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4402                                             logical_type_node,
4403                                             stride_neg, tmp);
4404               non_zerosized = fold_build2_loc (input_location, TRUTH_OR_EXPR,
4405                                                logical_type_node,
4406                                                stride_pos, stride_neg);
4407
4408               /* Check the start of the range against the lower and upper
4409                  bounds of the array, if the range is not empty.
4410                  If upper bound is present, include both bounds in the
4411                  error message.  */
4412               if (check_upper)
4413                 {
4414                   tmp = fold_build2_loc (input_location, LT_EXPR,
4415                                          logical_type_node,
4416                                          info->start[dim], lbound);
4417                   tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4418                                          logical_type_node,
4419                                          non_zerosized, tmp);
4420                   tmp2 = fold_build2_loc (input_location, GT_EXPR,
4421                                           logical_type_node,
4422                                           info->start[dim], ubound);
4423                   tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4424                                           logical_type_node,
4425                                           non_zerosized, tmp2);
4426                   msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
4427                                    "outside of expected range (%%ld:%%ld)",
4428                                    dim + 1, expr_name);
4429                   gfc_trans_runtime_check (true, false, tmp, &inner,
4430                                            expr_loc, msg,
4431                      fold_convert (long_integer_type_node, info->start[dim]),
4432                      fold_convert (long_integer_type_node, lbound),
4433                      fold_convert (long_integer_type_node, ubound));
4434                   gfc_trans_runtime_check (true, false, tmp2, &inner,
4435                                            expr_loc, msg,
4436                      fold_convert (long_integer_type_node, info->start[dim]),
4437                      fold_convert (long_integer_type_node, lbound),
4438                      fold_convert (long_integer_type_node, ubound));
4439                   free (msg);
4440                 }
4441               else
4442                 {
4443                   tmp = fold_build2_loc (input_location, LT_EXPR,
4444                                          logical_type_node,
4445                                          info->start[dim], lbound);
4446                   tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4447                                          logical_type_node, non_zerosized, tmp);
4448                   msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
4449                                    "below lower bound of %%ld",
4450                                    dim + 1, expr_name);
4451                   gfc_trans_runtime_check (true, false, tmp, &inner,
4452                                            expr_loc, msg,
4453                      fold_convert (long_integer_type_node, info->start[dim]),
4454                      fold_convert (long_integer_type_node, lbound));
4455                   free (msg);
4456                 }
4457
4458               /* Compute the last element of the range, which is not
4459                  necessarily "end" (think 0:5:3, which doesn't contain 5)
4460                  and check it against both lower and upper bounds.  */
4461
4462               tmp = fold_build2_loc (input_location, MINUS_EXPR,
4463                                      gfc_array_index_type, end,
4464                                      info->start[dim]);
4465               tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
4466                                      gfc_array_index_type, tmp,
4467                                      info->stride[dim]);
4468               tmp = fold_build2_loc (input_location, MINUS_EXPR,
4469                                      gfc_array_index_type, end, tmp);
4470               tmp2 = fold_build2_loc (input_location, LT_EXPR,
4471                                       logical_type_node, tmp, lbound);
4472               tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4473                                       logical_type_node, non_zerosized, tmp2);
4474               if (check_upper)
4475                 {
4476                   tmp3 = fold_build2_loc (input_location, GT_EXPR,
4477                                           logical_type_node, tmp, ubound);
4478                   tmp3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4479                                           logical_type_node, non_zerosized, tmp3);
4480                   msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
4481                                    "outside of expected range (%%ld:%%ld)",
4482                                    dim + 1, expr_name);
4483                   gfc_trans_runtime_check (true, false, tmp2, &inner,
4484                                            expr_loc, msg,
4485                      fold_convert (long_integer_type_node, tmp),
4486                      fold_convert (long_integer_type_node, ubound),
4487                      fold_convert (long_integer_type_node, lbound));
4488                   gfc_trans_runtime_check (true, false, tmp3, &inner,
4489                                            expr_loc, msg,
4490                      fold_convert (long_integer_type_node, tmp),
4491                      fold_convert (long_integer_type_node, ubound),
4492                      fold_convert (long_integer_type_node, lbound));
4493                   free (msg);
4494                 }
4495               else
4496                 {
4497                   msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
4498                                    "below lower bound of %%ld",
4499                                    dim + 1, expr_name);
4500                   gfc_trans_runtime_check (true, false, tmp2, &inner,
4501                                            expr_loc, msg,
4502                      fold_convert (long_integer_type_node, tmp),
4503                      fold_convert (long_integer_type_node, lbound));
4504                   free (msg);
4505                 }
4506
4507               /* Check the section sizes match.  */
4508               tmp = fold_build2_loc (input_location, MINUS_EXPR,
4509                                      gfc_array_index_type, end,
4510                                      info->start[dim]);
4511               tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR,
4512                                      gfc_array_index_type, tmp,
4513                                      info->stride[dim]);
4514               tmp = fold_build2_loc (input_location, PLUS_EXPR,
4515                                      gfc_array_index_type,
4516                                      gfc_index_one_node, tmp);
4517               tmp = fold_build2_loc (input_location, MAX_EXPR,
4518                                      gfc_array_index_type, tmp,
4519                                      build_int_cst (gfc_array_index_type, 0));
4520               /* We remember the size of the first section, and check all the
4521                  others against this.  */
4522               if (size[n])
4523                 {
4524                   tmp3 = fold_build2_loc (input_location, NE_EXPR,
4525                                           logical_type_node, tmp, size[n]);
4526                   msg = xasprintf ("Array bound mismatch for dimension %d "
4527                                    "of array '%s' (%%ld/%%ld)",
4528                                    dim + 1, expr_name);
4529
4530                   gfc_trans_runtime_check (true, false, tmp3, &inner,
4531                                            expr_loc, msg,
4532                         fold_convert (long_integer_type_node, tmp),
4533                         fold_convert (long_integer_type_node, size[n]));
4534
4535                   free (msg);
4536                 }
4537               else
4538                 size[n] = gfc_evaluate_now (tmp, &inner);
4539             }
4540
4541           tmp = gfc_finish_block (&inner);
4542
4543           /* For optional arguments, only check bounds if the argument is
4544              present.  */
4545           if (expr->symtree->n.sym->attr.optional
4546               || expr->symtree->n.sym->attr.not_always_present)
4547             tmp = build3_v (COND_EXPR,
4548                             gfc_conv_expr_present (expr->symtree->n.sym),
4549                             tmp, build_empty_stmt (input_location));
4550
4551           gfc_add_expr_to_block (&block, tmp);
4552
4553         }
4554
4555       tmp = gfc_finish_block (&block);
4556       gfc_add_expr_to_block (&outer_loop->pre, tmp);
4557     }
4558
4559   for (loop = loop->nested; loop; loop = loop->next)
4560     gfc_conv_ss_startstride (loop);
4561 }
4562
4563 /* Return true if both symbols could refer to the same data object.  Does
4564    not take account of aliasing due to equivalence statements.  */
4565
4566 static int
4567 symbols_could_alias (gfc_symbol *lsym, gfc_symbol *rsym, bool lsym_pointer,
4568                      bool lsym_target, bool rsym_pointer, bool rsym_target)
4569 {
4570   /* Aliasing isn't possible if the symbols have different base types.  */
4571   if (gfc_compare_types (&lsym->ts, &rsym->ts) == 0)
4572     return 0;
4573
4574   /* Pointers can point to other pointers and target objects.  */
4575
4576   if ((lsym_pointer && (rsym_pointer || rsym_target))
4577       || (rsym_pointer && (lsym_pointer || lsym_target)))
4578     return 1;
4579
4580   /* Special case: Argument association, cf. F90 12.4.1.6, F2003 12.4.1.7
4581      and F2008 12.5.2.13 items 3b and 4b. The pointer case (a) is already
4582      checked above.  */
4583   if (lsym_target && rsym_target
4584       && ((lsym->attr.dummy && !lsym->attr.contiguous
4585            && (!lsym->attr.dimension || lsym->as->type == AS_ASSUMED_SHAPE))
4586           || (rsym->attr.dummy && !rsym->attr.contiguous
4587               && (!rsym->attr.dimension
4588                   || rsym->as->type == AS_ASSUMED_SHAPE))))
4589     return 1;
4590
4591   return 0;
4592 }
4593
4594
4595 /* Return true if the two SS could be aliased, i.e. both point to the same data
4596    object.  */
4597 /* TODO: resolve aliases based on frontend expressions.  */
4598
4599 static int
4600 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
4601 {
4602   gfc_ref *lref;
4603   gfc_ref *rref;
4604   gfc_expr *lexpr, *rexpr;
4605   gfc_symbol *lsym;
4606   gfc_symbol *rsym;
4607   bool lsym_pointer, lsym_target, rsym_pointer, rsym_target;
4608
4609   lexpr = lss->info->expr;
4610   rexpr = rss->info->expr;
4611
4612   lsym = lexpr->symtree->n.sym;
4613   rsym = rexpr->symtree->n.sym;
4614
4615   lsym_pointer = lsym->attr.pointer;
4616   lsym_target = lsym->attr.target;
4617   rsym_pointer = rsym->attr.pointer;
4618   rsym_target = rsym->attr.target;
4619
4620   if (symbols_could_alias (lsym, rsym, lsym_pointer, lsym_target,
4621                            rsym_pointer, rsym_target))
4622     return 1;
4623
4624   if (rsym->ts.type != BT_DERIVED && rsym->ts.type != BT_CLASS
4625       && lsym->ts.type != BT_DERIVED && lsym->ts.type != BT_CLASS)
4626     return 0;
4627
4628   /* For derived types we must check all the component types.  We can ignore
4629      array references as these will have the same base type as the previous
4630      component ref.  */
4631   for (lref = lexpr->ref; lref != lss->info->data.array.ref; lref = lref->next)
4632     {
4633       if (lref->type != REF_COMPONENT)
4634         continue;
4635
4636       lsym_pointer = lsym_pointer || lref->u.c.sym->attr.pointer;
4637       lsym_target  = lsym_target  || lref->u.c.sym->attr.target;
4638
4639       if (symbols_could_alias (lref->u.c.sym, rsym, lsym_pointer, lsym_target,
4640                                rsym_pointer, rsym_target))
4641         return 1;
4642
4643       if ((lsym_pointer && (rsym_pointer || rsym_target))
4644           || (rsym_pointer && (lsym_pointer || lsym_target)))
4645         {
4646           if (gfc_compare_types (&lref->u.c.component->ts,
4647                                  &rsym->ts))
4648             return 1;
4649         }
4650
4651       for (rref = rexpr->ref; rref != rss->info->data.array.ref;
4652            rref = rref->next)
4653         {
4654           if (rref->type != REF_COMPONENT)
4655             continue;
4656
4657           rsym_pointer = rsym_pointer || rref->u.c.sym->attr.pointer;
4658           rsym_target  = lsym_target  || rref->u.c.sym->attr.target;
4659
4660           if (symbols_could_alias (lref->u.c.sym, rref->u.c.sym,
4661                                    lsym_pointer, lsym_target,
4662                                    rsym_pointer, rsym_target))
4663             return 1;
4664
4665           if ((lsym_pointer && (rsym_pointer || rsym_target))
4666               || (rsym_pointer && (lsym_pointer || lsym_target)))
4667             {
4668               if (gfc_compare_types (&lref->u.c.component->ts,
4669                                      &rref->u.c.sym->ts))
4670                 return 1;
4671               if (gfc_compare_types (&lref->u.c.sym->ts,
4672                                      &rref->u.c.component->ts))
4673                 return 1;
4674               if (gfc_compare_types (&lref->u.c.component->ts,
4675                                      &rref->u.c.component->ts))
4676                 return 1;
4677             }
4678         }
4679     }
4680
4681   lsym_pointer = lsym->attr.pointer;
4682   lsym_target = lsym->attr.target;
4683   lsym_pointer = lsym->attr.pointer;
4684   lsym_target = lsym->attr.target;
4685
4686   for (rref = rexpr->ref; rref != rss->info->data.array.ref; rref = rref->next)
4687     {
4688       if (rref->type != REF_COMPONENT)
4689         break;
4690
4691       rsym_pointer = rsym_pointer || rref->u.c.sym->attr.pointer;
4692       rsym_target  = lsym_target  || rref->u.c.sym->attr.target;
4693
4694       if (symbols_could_alias (rref->u.c.sym, lsym,
4695                                lsym_pointer, lsym_target,
4696                                rsym_pointer, rsym_target))
4697         return 1;
4698
4699       if ((lsym_pointer && (rsym_pointer || rsym_target))
4700           || (rsym_pointer && (lsym_pointer || lsym_target)))
4701         {
4702           if (gfc_compare_types (&lsym->ts, &rref->u.c.component->ts))
4703             return 1;
4704         }
4705     }
4706
4707   return 0;
4708 }
4709
4710
4711 /* Resolve array data dependencies.  Creates a temporary if required.  */
4712 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
4713    dependency.c.  */
4714
4715 void
4716 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
4717                                gfc_ss * rss)
4718 {
4719   gfc_ss *ss;
4720   gfc_ref *lref;
4721   gfc_ref *rref;
4722   gfc_ss_info *ss_info;
4723   gfc_expr *dest_expr;
4724   gfc_expr *ss_expr;
4725   int nDepend = 0;
4726   int i, j;
4727
4728   loop->temp_ss = NULL;
4729   dest_expr = dest->info->expr;
4730
4731   for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
4732     {
4733       ss_info = ss->info;
4734       ss_expr = ss_info->expr;
4735
4736       if (ss_info->array_outer_dependency)
4737         {
4738           nDepend = 1;
4739           break;
4740         }
4741
4742       if (ss_info->type != GFC_SS_SECTION)
4743         {
4744           if (flag_realloc_lhs
4745               && dest_expr != ss_expr
4746               && gfc_is_reallocatable_lhs (dest_expr)
4747               && ss_expr->rank)
4748             nDepend = gfc_check_dependency (dest_expr, ss_expr, true);
4749
4750           /* Check for cases like   c(:)(1:2) = c(2)(2:3)  */
4751           if (!nDepend && dest_expr->rank > 0
4752               && dest_expr->ts.type == BT_CHARACTER
4753               && ss_expr->expr_type == EXPR_VARIABLE)
4754
4755             nDepend = gfc_check_dependency (dest_expr, ss_expr, false);
4756
4757           if (ss_info->type == GFC_SS_REFERENCE
4758               && gfc_check_dependency (dest_expr, ss_expr, false))
4759             ss_info->data.scalar.needs_temporary = 1;
4760
4761           if (nDepend)
4762             break;
4763           else
4764             continue;
4765         }
4766
4767       if (dest_expr->symtree->n.sym != ss_expr->symtree->n.sym)
4768         {
4769           if (gfc_could_be_alias (dest, ss)
4770               || gfc_are_equivalenced_arrays (dest_expr, ss_expr))
4771             {
4772               nDepend = 1;
4773               break;
4774             }
4775         }
4776       else
4777         {
4778           lref = dest_expr->ref;
4779           rref = ss_expr->ref;
4780
4781           nDepend = gfc_dep_resolver (lref, rref, &loop->reverse[0]);
4782
4783           if (nDepend == 1)
4784             break;
4785
4786           for (i = 0; i < dest->dimen; i++)
4787             for (j = 0; j < ss->dimen; j++)
4788               if (i != j
4789                   && dest->dim[i] == ss->dim[j])
4790                 {
4791                   /* If we don't access array elements in the same order,
4792                      there is a dependency.  */
4793                   nDepend = 1;
4794                   goto temporary;
4795                 }
4796 #if 0
4797           /* TODO : loop shifting.  */
4798           if (nDepend == 1)
4799             {
4800               /* Mark the dimensions for LOOP SHIFTING */
4801               for (n = 0; n < loop->dimen; n++)
4802                 {
4803                   int dim = dest->data.info.dim[n];
4804
4805                   if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
4806                     depends[n] = 2;
4807                   else if (! gfc_is_same_range (&lref->u.ar,
4808                                                 &rref->u.ar, dim, 0))
4809                     depends[n] = 1;
4810                  }
4811
4812               /* Put all the dimensions with dependencies in the
4813                  innermost loops.  */
4814               dim = 0;
4815               for (n = 0; n < loop->dimen; n++)
4816                 {
4817                   gcc_assert (loop->order[n] == n);
4818                   if (depends[n])
4819                   loop->order[dim++] = n;
4820                 }
4821               for (n = 0; n < loop->dimen; n++)
4822                 {
4823                   if (! depends[n])
4824                   loop->order[dim++] = n;
4825                 }
4826
4827               gcc_assert (dim == loop->dimen);
4828               break;
4829             }
4830 #endif
4831         }
4832     }
4833
4834 temporary:
4835
4836   if (nDepend == 1)
4837     {
4838       tree base_type = gfc_typenode_for_spec (&dest_expr->ts);
4839       if (GFC_ARRAY_TYPE_P (base_type)
4840           || GFC_DESCRIPTOR_TYPE_P (base_type))
4841         base_type = gfc_get_element_type (base_type);
4842       loop->temp_ss = gfc_get_temp_ss (base_type, dest->info->string_length,
4843                                        loop->dimen);
4844       gfc_add_ss_to_loop (loop, loop->temp_ss);
4845     }
4846   else
4847     loop->temp_ss = NULL;
4848 }
4849
4850
4851 /* Browse through each array's information from the scalarizer and set the loop
4852    bounds according to the "best" one (per dimension), i.e. the one which
4853    provides the most information (constant bounds, shape, etc.).  */
4854
4855 static void
4856 set_loop_bounds (gfc_loopinfo *loop)
4857 {
4858   int n, dim, spec_dim;
4859   gfc_array_info *info;
4860   gfc_array_info *specinfo;
4861   gfc_ss *ss;
4862   tree tmp;
4863   gfc_ss **loopspec;
4864   bool dynamic[GFC_MAX_DIMENSIONS];
4865   mpz_t *cshape;
4866   mpz_t i;
4867   bool nonoptional_arr;
4868
4869   gfc_loopinfo * const outer_loop = outermost_loop (loop);
4870
4871   loopspec = loop->specloop;
4872
4873   mpz_init (i);
4874   for (n = 0; n < loop->dimen; n++)
4875     {
4876       loopspec[n] = NULL;
4877       dynamic[n] = false;
4878
4879       /* If there are both optional and nonoptional array arguments, scalarize
4880          over the nonoptional; otherwise, it does not matter as then all
4881          (optional) arrays have to be present per F2008, 125.2.12p3(6).  */
4882
4883       nonoptional_arr = false;
4884
4885       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4886         if (ss->info->type != GFC_SS_SCALAR && ss->info->type != GFC_SS_TEMP
4887             && ss->info->type != GFC_SS_REFERENCE && !ss->info->can_be_null_ref)
4888           {
4889             nonoptional_arr = true;
4890             break;
4891           }
4892
4893       /* We use one SS term, and use that to determine the bounds of the
4894          loop for this dimension.  We try to pick the simplest term.  */
4895       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4896         {
4897           gfc_ss_type ss_type;
4898
4899           ss_type = ss->info->type;
4900           if (ss_type == GFC_SS_SCALAR
4901               || ss_type == GFC_SS_TEMP
4902               || ss_type == GFC_SS_REFERENCE
4903               || (ss->info->can_be_null_ref && nonoptional_arr))
4904             continue;
4905
4906           info = &ss->info->data.array;
4907           dim = ss->dim[n];
4908
4909           if (loopspec[n] != NULL)
4910             {
4911               specinfo = &loopspec[n]->info->data.array;
4912               spec_dim = loopspec[n]->dim[n];
4913             }
4914           else
4915             {
4916               /* Silence uninitialized warnings.  */
4917               specinfo = NULL;
4918               spec_dim = 0;
4919             }
4920
4921           if (info->shape)
4922             {
4923               gcc_assert (info->shape[dim]);
4924               /* The frontend has worked out the size for us.  */
4925               if (!loopspec[n]
4926                   || !specinfo->shape
4927                   || !integer_zerop (specinfo->start[spec_dim]))
4928                 /* Prefer zero-based descriptors if possible.  */
4929                 loopspec[n] = ss;
4930               continue;
4931             }
4932
4933           if (ss_type == GFC_SS_CONSTRUCTOR)
4934             {
4935               gfc_constructor_base base;
4936               /* An unknown size constructor will always be rank one.
4937                  Higher rank constructors will either have known shape,
4938                  or still be wrapped in a call to reshape.  */
4939               gcc_assert (loop->dimen == 1);
4940
4941               /* Always prefer to use the constructor bounds if the size
4942                  can be determined at compile time.  Prefer not to otherwise,
4943                  since the general case involves realloc, and it's better to
4944                  avoid that overhead if possible.  */
4945               base = ss->info->expr->value.constructor;
4946               dynamic[n] = gfc_get_array_constructor_size (&i, base);
4947               if (!dynamic[n] || !loopspec[n])
4948                 loopspec[n] = ss;
4949               continue;
4950             }
4951
4952           /* Avoid using an allocatable lhs in an assignment, since
4953              there might be a reallocation coming.  */
4954           if (loopspec[n] && ss->is_alloc_lhs)
4955             continue;
4956
4957           if (!loopspec[n])
4958             loopspec[n] = ss;
4959           /* Criteria for choosing a loop specifier (most important first):
4960              doesn't need realloc
4961              stride of one
4962              known stride
4963              known lower bound
4964              known upper bound
4965            */
4966           else if (loopspec[n]->info->type == GFC_SS_CONSTRUCTOR && dynamic[n])
4967             loopspec[n] = ss;
4968           else if (integer_onep (info->stride[dim])
4969                    && !integer_onep (specinfo->stride[spec_dim]))
4970             loopspec[n] = ss;
4971           else if (INTEGER_CST_P (info->stride[dim])
4972                    && !INTEGER_CST_P (specinfo->stride[spec_dim]))
4973             loopspec[n] = ss;
4974           else if (INTEGER_CST_P (info->start[dim])
4975                    && !INTEGER_CST_P (specinfo->start[spec_dim])
4976                    && integer_onep (info->stride[dim])
4977                       == integer_onep (specinfo->stride[spec_dim])
4978                    && INTEGER_CST_P (info->stride[dim])
4979                       == INTEGER_CST_P (specinfo->stride[spec_dim]))
4980             loopspec[n] = ss;
4981           /* We don't work out the upper bound.
4982              else if (INTEGER_CST_P (info->finish[n])
4983              && ! INTEGER_CST_P (specinfo->finish[n]))
4984              loopspec[n] = ss; */
4985         }
4986
4987       /* We should have found the scalarization loop specifier.  If not,
4988          that's bad news.  */
4989       gcc_assert (loopspec[n]);
4990
4991       info = &loopspec[n]->info->data.array;
4992       dim = loopspec[n]->dim[n];
4993
4994       /* Set the extents of this range.  */
4995       cshape = info->shape;
4996       if (cshape && INTEGER_CST_P (info->start[dim])
4997           && INTEGER_CST_P (info->stride[dim]))
4998         {
4999           loop->from[n] = info->start[dim];
5000           mpz_set (i, cshape[get_array_ref_dim_for_loop_dim (loopspec[n], n)]);
5001           mpz_sub_ui (i, i, 1);
5002           /* To = from + (size - 1) * stride.  */
5003           tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
5004           if (!integer_onep (info->stride[dim]))
5005             tmp = fold_build2_loc (input_location, MULT_EXPR,
5006                                    gfc_array_index_type, tmp,
5007                                    info->stride[dim]);
5008           loop->to[n] = fold_build2_loc (input_location, PLUS_EXPR,
5009                                          gfc_array_index_type,
5010                                          loop->from[n], tmp);
5011         }
5012       else
5013         {
5014           loop->from[n] = info->start[dim];
5015           switch (loopspec[n]->info->type)
5016             {
5017             case GFC_SS_CONSTRUCTOR:
5018               /* The upper bound is calculated when we expand the
5019                  constructor.  */
5020               gcc_assert (loop->to[n] == NULL_TREE);
5021               break;
5022
5023             case GFC_SS_SECTION:
5024               /* Use the end expression if it exists and is not constant,
5025                  so that it is only evaluated once.  */
5026               loop->to[n] = info->end[dim];
5027               break;
5028
5029             case GFC_SS_FUNCTION:
5030               /* The loop bound will be set when we generate the call.  */
5031               gcc_assert (loop->to[n] == NULL_TREE);
5032               break;
5033
5034             case GFC_SS_INTRINSIC:
5035               {
5036                 gfc_expr *expr = loopspec[n]->info->expr;
5037
5038                 /* The {l,u}bound of an assumed rank.  */
5039                 gcc_assert ((expr->value.function.isym->id == GFC_ISYM_LBOUND
5040                              || expr->value.function.isym->id == GFC_ISYM_UBOUND)
5041                              && expr->value.function.actual->next->expr == NULL
5042                              && expr->value.function.actual->expr->rank == -1);
5043
5044                 loop->to[n] = info->end[dim];
5045                 break;
5046               }
5047
5048             case GFC_SS_COMPONENT:
5049               {
5050                 if (info->end[dim] != NULL_TREE)
5051                   {
5052                     loop->to[n] = info->end[dim];
5053                     break;
5054                   }
5055                 else
5056                   gcc_unreachable ();
5057               }
5058
5059             default:
5060               gcc_unreachable ();
5061             }
5062         }
5063
5064       /* Transform everything so we have a simple incrementing variable.  */
5065       if (integer_onep (info->stride[dim]))
5066         info->delta[dim] = gfc_index_zero_node;
5067       else
5068         {
5069           /* Set the delta for this section.  */
5070           info->delta[dim] = gfc_evaluate_now (loop->from[n], &outer_loop->pre);
5071           /* Number of iterations is (end - start + step) / step.
5072              with start = 0, this simplifies to
5073              last = end / step;
5074              for (i = 0; i<=last; i++){...};  */
5075           tmp = fold_build2_loc (input_location, MINUS_EXPR,
5076                                  gfc_array_index_type, loop->to[n],
5077                                  loop->from[n]);
5078           tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR,
5079                                  gfc_array_index_type, tmp, info->stride[dim]);
5080           tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
5081                                  tmp, build_int_cst (gfc_array_index_type, -1));
5082           loop->to[n] = gfc_evaluate_now (tmp, &outer_loop->pre);
5083           /* Make the loop variable start at 0.  */
5084           loop->from[n] = gfc_index_zero_node;
5085         }
5086     }
5087   mpz_clear (i);
5088
5089   for (loop = loop->nested; loop; loop = loop->next)
5090     set_loop_bounds (loop);
5091 }
5092
5093
5094 /* Initialize the scalarization loop.  Creates the loop variables.  Determines
5095    the range of the loop variables.  Creates a temporary if required.
5096    Also generates code for scalar expressions which have been
5097    moved outside the loop.  */
5098
5099 void
5100 gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
5101 {
5102   gfc_ss *tmp_ss;
5103   tree tmp;
5104
5105   set_loop_bounds (loop);
5106
5107   /* Add all the scalar code that can be taken out of the loops.
5108      This may include calculating the loop bounds, so do it before
5109      allocating the temporary.  */
5110   gfc_add_loop_ss_code (loop, loop->ss, false, where);
5111
5112   tmp_ss = loop->temp_ss;
5113   /* If we want a temporary then create it.  */
5114   if (tmp_ss != NULL)
5115     {
5116       gfc_ss_info *tmp_ss_info;
5117
5118       tmp_ss_info = tmp_ss->info;
5119       gcc_assert (tmp_ss_info->type == GFC_SS_TEMP);
5120       gcc_assert (loop->parent == NULL);
5121
5122       /* Make absolutely sure that this is a complete type.  */
5123       if (tmp_ss_info->string_length)
5124         tmp_ss_info->data.temp.type
5125                 = gfc_get_character_type_len_for_eltype
5126                         (TREE_TYPE (tmp_ss_info->data.temp.type),
5127                          tmp_ss_info->string_length);
5128
5129       tmp = tmp_ss_info->data.temp.type;
5130       memset (&tmp_ss_info->data.array, 0, sizeof (gfc_array_info));
5131       tmp_ss_info->type = GFC_SS_SECTION;
5132
5133       gcc_assert (tmp_ss->dimen != 0);
5134
5135       gfc_trans_create_temp_array (&loop->pre, &loop->post, tmp_ss, tmp,
5136                                    NULL_TREE, false, true, false, where);
5137     }
5138
5139   /* For array parameters we don't have loop variables, so don't calculate the
5140      translations.  */
5141   if (!loop->array_parameter)
5142     gfc_set_delta (loop);
5143 }
5144
5145
5146 /* Calculates how to transform from loop variables to array indices for each
5147    array: once loop bounds are chosen, sets the difference (DELTA field) between
5148    loop bounds and array reference bounds, for each array info.  */
5149
5150 void
5151 gfc_set_delta (gfc_loopinfo *loop)
5152 {
5153   gfc_ss *ss, **loopspec;
5154   gfc_array_info *info;
5155   tree tmp;
5156   int n, dim;
5157
5158   gfc_loopinfo * const outer_loop = outermost_loop (loop);
5159
5160   loopspec = loop->specloop;
5161
5162   /* Calculate the translation from loop variables to array indices.  */
5163   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
5164     {
5165       gfc_ss_type ss_type;
5166
5167       ss_type = ss->info->type;
5168       if (ss_type != GFC_SS_SECTION
5169           && ss_type != GFC_SS_COMPONENT
5170           && ss_type != GFC_SS_CONSTRUCTOR)
5171         continue;
5172
5173       info = &ss->info->data.array;
5174
5175       for (n = 0; n < ss->dimen; n++)
5176         {
5177           /* If we are specifying the range the delta is already set.  */
5178           if (loopspec[n] != ss)
5179             {
5180               dim = ss->dim[n];
5181
5182               /* Calculate the offset relative to the loop variable.
5183                  First multiply by the stride.  */
5184               tmp = loop->from[n];
5185               if (!integer_onep (info->stride[dim]))
5186                 tmp = fold_build2_loc (input_location, MULT_EXPR,
5187                                        gfc_array_index_type,
5188                                        tmp, info->stride[dim]);
5189
5190               /* Then subtract this from our starting value.  */
5191               tmp = fold_build2_loc (input_location, MINUS_EXPR,
5192                                      gfc_array_index_type,
5193                                      info->start[dim], tmp);
5194
5195               info->delta[dim] = gfc_evaluate_now (tmp, &outer_loop->pre);
5196             }
5197         }
5198     }
5199
5200   for (loop = loop->nested; loop; loop = loop->next)
5201     gfc_set_delta (loop);
5202 }
5203
5204
5205 /* Calculate the size of a given array dimension from the bounds.  This
5206    is simply (ubound - lbound + 1) if this expression is positive
5207    or 0 if it is negative (pick either one if it is zero).  Optionally
5208    (if or_expr is present) OR the (expression != 0) condition to it.  */
5209
5210 tree
5211 gfc_conv_array_extent_dim (tree lbound, tree ubound, tree* or_expr)
5212 {
5213   tree res;
5214   tree cond;
5215
5216   /* Calculate (ubound - lbound + 1).  */
5217   res = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5218                          ubound, lbound);
5219   res = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, res,
5220                          gfc_index_one_node);
5221
5222   /* Check whether the size for this dimension is negative.  */
5223   cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, res,
5224                           gfc_index_zero_node);
5225   res = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
5226                          gfc_index_zero_node, res);
5227
5228   /* Build OR expression.  */
5229   if (or_expr)
5230     *or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
5231                                 logical_type_node, *or_expr, cond);
5232
5233   return res;
5234 }
5235
5236
5237 /* For an array descriptor, get the total number of elements.  This is just
5238    the product of the extents along from_dim to to_dim.  */
5239
5240 static tree
5241 gfc_conv_descriptor_size_1 (tree desc, int from_dim, int to_dim)
5242 {
5243   tree res;
5244   int dim;
5245
5246   res = gfc_index_one_node;
5247
5248   for (dim = from_dim; dim < to_dim; ++dim)
5249     {
5250       tree lbound;
5251       tree ubound;
5252       tree extent;
5253
5254       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
5255       ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
5256
5257       extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
5258       res = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5259                              res, extent);
5260     }
5261
5262   return res;
5263 }
5264
5265
5266 /* Full size of an array.  */
5267
5268 tree
5269 gfc_conv_descriptor_size (tree desc, int rank)
5270 {
5271   return gfc_conv_descriptor_size_1 (desc, 0, rank);
5272 }
5273
5274
5275 /* Size of a coarray for all dimensions but the last.  */
5276
5277 tree
5278 gfc_conv_descriptor_cosize (tree desc, int rank, int corank)
5279 {
5280   return gfc_conv_descriptor_size_1 (desc, rank, rank + corank - 1);
5281 }
5282
5283
5284 /* Fills in an array descriptor, and returns the size of the array.
5285    The size will be a simple_val, ie a variable or a constant.  Also
5286    calculates the offset of the base.  The pointer argument overflow,
5287    which should be of integer type, will increase in value if overflow
5288    occurs during the size calculation.  Returns the size of the array.
5289    {
5290     stride = 1;
5291     offset = 0;
5292     for (n = 0; n < rank; n++)
5293       {
5294         a.lbound[n] = specified_lower_bound;
5295         offset = offset + a.lbond[n] * stride;
5296         size = 1 - lbound;
5297         a.ubound[n] = specified_upper_bound;
5298         a.stride[n] = stride;
5299         size = size >= 0 ? ubound + size : 0; //size = ubound + 1 - lbound
5300         overflow += size == 0 ? 0: (MAX/size < stride ? 1: 0);
5301         stride = stride * size;
5302       }
5303     for (n = rank; n < rank+corank; n++)
5304       (Set lcobound/ucobound as above.)
5305     element_size = sizeof (array element);
5306     if (!rank)
5307       return element_size
5308     stride = (size_t) stride;
5309     overflow += element_size == 0 ? 0: (MAX/element_size < stride ? 1: 0);
5310     stride = stride * element_size;
5311     return (stride);
5312    }  */
5313 /*GCC ARRAYS*/
5314
5315 static tree
5316 gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
5317                      gfc_expr ** lower, gfc_expr ** upper, stmtblock_t * pblock,
5318                      stmtblock_t * descriptor_block, tree * overflow,
5319                      tree expr3_elem_size, tree *nelems, gfc_expr *expr3,
5320                      tree expr3_desc, bool e3_is_array_constr, gfc_expr *expr)
5321 {
5322   tree type;
5323   tree tmp;
5324   tree size;
5325   tree offset;
5326   tree stride;
5327   tree element_size;
5328   tree or_expr;
5329   tree thencase;
5330   tree elsecase;
5331   tree cond;
5332   tree var;
5333   stmtblock_t thenblock;
5334   stmtblock_t elseblock;
5335   gfc_expr *ubound;
5336   gfc_se se;
5337   int n;
5338
5339   type = TREE_TYPE (descriptor);
5340
5341   stride = gfc_index_one_node;
5342   offset = gfc_index_zero_node;
5343
5344   /* Set the dtype before the alloc, because registration of coarrays needs
5345      it initialized.  */
5346   if (expr->ts.type == BT_CHARACTER
5347       && expr->ts.deferred
5348       && VAR_P (expr->ts.u.cl->backend_decl))
5349     {
5350       type = gfc_typenode_for_spec (&expr->ts);
5351       tmp = gfc_conv_descriptor_dtype (descriptor);
5352       gfc_add_modify (pblock, tmp, gfc_get_dtype_rank_type (rank, type));
5353     }
5354   else
5355     {
5356       tmp = gfc_conv_descriptor_dtype (descriptor);
5357       gfc_add_modify (pblock, tmp, gfc_get_dtype (type));
5358     }
5359
5360   or_expr = logical_false_node;
5361
5362   for (n = 0; n < rank; n++)
5363     {
5364       tree conv_lbound;
5365       tree conv_ubound;
5366
5367       /* We have 3 possibilities for determining the size of the array:
5368          lower == NULL    => lbound = 1, ubound = upper[n]
5369          upper[n] = NULL  => lbound = 1, ubound = lower[n]
5370          upper[n] != NULL => lbound = lower[n], ubound = upper[n]  */
5371       ubound = upper[n];
5372
5373       /* Set lower bound.  */
5374       gfc_init_se (&se, NULL);
5375       if (expr3_desc != NULL_TREE)
5376         {
5377           if (e3_is_array_constr)
5378             /* The lbound of a constant array [] starts at zero, but when
5379                allocating it, the standard expects the array to start at
5380                one.  */
5381             se.expr = gfc_index_one_node;
5382           else
5383             se.expr = gfc_conv_descriptor_lbound_get (expr3_desc,
5384                                                       gfc_rank_cst[n]);
5385         }
5386       else if (lower == NULL)
5387         se.expr = gfc_index_one_node;
5388       else
5389         {
5390           gcc_assert (lower[n]);
5391           if (ubound)
5392             {
5393               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
5394               gfc_add_block_to_block (pblock, &se.pre);
5395             }
5396           else
5397             {
5398               se.expr = gfc_index_one_node;
5399               ubound = lower[n];
5400             }
5401         }
5402       gfc_conv_descriptor_lbound_set (descriptor_block, descriptor,
5403                                       gfc_rank_cst[n], se.expr);
5404       conv_lbound = se.expr;
5405
5406       /* Work out the offset for this component.  */
5407       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5408                              se.expr, stride);
5409       offset = fold_build2_loc (input_location, MINUS_EXPR,
5410                                 gfc_array_index_type, offset, tmp);
5411
5412       /* Set upper bound.  */
5413       gfc_init_se (&se, NULL);
5414       if (expr3_desc != NULL_TREE)
5415         {
5416           if (e3_is_array_constr)
5417             {
5418               /* The lbound of a constant array [] starts at zero, but when
5419                allocating it, the standard expects the array to start at
5420                one.  Therefore fix the upper bound to be
5421                (desc.ubound - desc.lbound)+ 1.  */
5422               tmp = fold_build2_loc (input_location, MINUS_EXPR,
5423                                      gfc_array_index_type,
5424                                      gfc_conv_descriptor_ubound_get (
5425                                        expr3_desc, gfc_rank_cst[n]),
5426                                      gfc_conv_descriptor_lbound_get (
5427                                        expr3_desc, gfc_rank_cst[n]));
5428               tmp = fold_build2_loc (input_location, PLUS_EXPR,
5429                                      gfc_array_index_type, tmp,
5430                                      gfc_index_one_node);
5431               se.expr = gfc_evaluate_now (tmp, pblock);
5432             }
5433           else
5434             se.expr = gfc_conv_descriptor_ubound_get (expr3_desc,
5435                                                       gfc_rank_cst[n]);
5436         }
5437       else
5438         {
5439           gcc_assert (ubound);
5440           gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
5441           gfc_add_block_to_block (pblock, &se.pre);
5442           if (ubound->expr_type == EXPR_FUNCTION)
5443             se.expr = gfc_evaluate_now (se.expr, pblock);
5444         }
5445       gfc_conv_descriptor_ubound_set (descriptor_block, descriptor,
5446                                       gfc_rank_cst[n], se.expr);
5447       conv_ubound = se.expr;
5448
5449       /* Store the stride.  */
5450       gfc_conv_descriptor_stride_set (descriptor_block, descriptor,
5451                                       gfc_rank_cst[n], stride);
5452
5453       /* Calculate size and check whether extent is negative.  */
5454       size = gfc_conv_array_extent_dim (conv_lbound, conv_ubound, &or_expr);
5455       size = gfc_evaluate_now (size, pblock);
5456
5457       /* Check whether multiplying the stride by the number of
5458          elements in this dimension would overflow. We must also check
5459          whether the current dimension has zero size in order to avoid
5460          division by zero.
5461       */
5462       tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
5463                              gfc_array_index_type,
5464                              fold_convert (gfc_array_index_type,
5465                                            TYPE_MAX_VALUE (gfc_array_index_type)),
5466                                            size);
5467       cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR,
5468                                             logical_type_node, tmp, stride),
5469                            PRED_FORTRAN_OVERFLOW);
5470       tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
5471                              integer_one_node, integer_zero_node);
5472       cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR,
5473                                             logical_type_node, size,
5474                                             gfc_index_zero_node),
5475                            PRED_FORTRAN_SIZE_ZERO);
5476       tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
5477                              integer_zero_node, tmp);
5478       tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
5479                              *overflow, tmp);
5480       *overflow = gfc_evaluate_now (tmp, pblock);
5481
5482       /* Multiply the stride by the number of elements in this dimension.  */
5483       stride = fold_build2_loc (input_location, MULT_EXPR,
5484                                 gfc_array_index_type, stride, size);
5485       stride = gfc_evaluate_now (stride, pblock);
5486     }
5487
5488   for (n = rank; n < rank + corank; n++)
5489     {
5490       ubound = upper[n];
5491
5492       /* Set lower bound.  */
5493       gfc_init_se (&se, NULL);
5494       if (lower == NULL || lower[n] == NULL)
5495         {
5496           gcc_assert (n == rank + corank - 1);
5497           se.expr = gfc_index_one_node;
5498         }
5499       else
5500         {
5501           if (ubound || n == rank + corank - 1)
5502             {
5503               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
5504               gfc_add_block_to_block (pblock, &se.pre);
5505             }
5506           else
5507             {
5508               se.expr = gfc_index_one_node;
5509               ubound = lower[n];
5510             }
5511         }
5512       gfc_conv_descriptor_lbound_set (descriptor_block, descriptor,
5513                                       gfc_rank_cst[n], se.expr);
5514
5515       if (n < rank + corank - 1)
5516         {
5517           gfc_init_se (&se, NULL);
5518           gcc_assert (ubound);
5519           gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
5520           gfc_add_block_to_block (pblock, &se.pre);
5521           gfc_conv_descriptor_ubound_set (descriptor_block, descriptor,
5522                                           gfc_rank_cst[n], se.expr);
5523         }
5524     }
5525
5526   /* The stride is the number of elements in the array, so multiply by the
5527      size of an element to get the total size.  Obviously, if there is a
5528      SOURCE expression (expr3) we must use its element size.  */
5529   if (expr3_elem_size != NULL_TREE)
5530     tmp = expr3_elem_size;
5531   else if (expr3 != NULL)
5532     {
5533       if (expr3->ts.type == BT_CLASS)
5534         {
5535           gfc_se se_sz;
5536           gfc_expr *sz = gfc_copy_expr (expr3);
5537           gfc_add_vptr_component (sz);
5538           gfc_add_size_component (sz);
5539           gfc_init_se (&se_sz, NULL);
5540           gfc_conv_expr (&se_sz, sz);
5541           gfc_free_expr (sz);
5542           tmp = se_sz.expr;
5543         }
5544       else
5545         {
5546           tmp = gfc_typenode_for_spec (&expr3->ts);
5547           tmp = TYPE_SIZE_UNIT (tmp);
5548         }
5549     }
5550   else
5551     tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
5552
5553   /* Convert to size_t.  */
5554   element_size = fold_convert (size_type_node, tmp);
5555
5556   if (rank == 0)
5557     return element_size;
5558
5559   *nelems = gfc_evaluate_now (stride, pblock);
5560   stride = fold_convert (size_type_node, stride);
5561
5562   /* First check for overflow. Since an array of type character can
5563      have zero element_size, we must check for that before
5564      dividing.  */
5565   tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
5566                          size_type_node,
5567                          TYPE_MAX_VALUE (size_type_node), element_size);
5568   cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR,
5569                                         logical_type_node, tmp, stride),
5570                        PRED_FORTRAN_OVERFLOW);
5571   tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
5572                          integer_one_node, integer_zero_node);
5573   cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR,
5574                                         logical_type_node, element_size,
5575                                         build_int_cst (size_type_node, 0)),
5576                        PRED_FORTRAN_SIZE_ZERO);
5577   tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
5578                          integer_zero_node, tmp);
5579   tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
5580                          *overflow, tmp);
5581   *overflow = gfc_evaluate_now (tmp, pblock);
5582
5583   size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
5584                           stride, element_size);
5585
5586   if (poffset != NULL)
5587     {
5588       offset = gfc_evaluate_now (offset, pblock);
5589       *poffset = offset;
5590     }
5591
5592   if (integer_zerop (or_expr))
5593     return size;
5594   if (integer_onep (or_expr))
5595     return build_int_cst (size_type_node, 0);
5596
5597   var = gfc_create_var (TREE_TYPE (size), "size");
5598   gfc_start_block (&thenblock);
5599   gfc_add_modify (&thenblock, var, build_int_cst (size_type_node, 0));
5600   thencase = gfc_finish_block (&thenblock);
5601
5602   gfc_start_block (&elseblock);
5603   gfc_add_modify (&elseblock, var, size);
5604   elsecase = gfc_finish_block (&elseblock);
5605
5606   tmp = gfc_evaluate_now (or_expr, pblock);
5607   tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
5608   gfc_add_expr_to_block (pblock, tmp);
5609
5610   return var;
5611 }
5612
5613
5614 /* Retrieve the last ref from the chain.  This routine is specific to
5615    gfc_array_allocate ()'s needs.  */
5616
5617 bool
5618 retrieve_last_ref (gfc_ref **ref_in, gfc_ref **prev_ref_in)
5619 {
5620   gfc_ref *ref, *prev_ref;
5621
5622   ref = *ref_in;
5623   /* Prevent warnings for uninitialized variables.  */
5624   prev_ref = *prev_ref_in;
5625   while (ref && ref->next != NULL)
5626     {
5627       gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT
5628                   || (ref->u.ar.dimen == 0 && ref->u.ar.codimen > 0));
5629       prev_ref = ref;
5630       ref = ref->next;
5631     }
5632
5633   if (ref == NULL || ref->type != REF_ARRAY)
5634     return false;
5635
5636   *ref_in = ref;
5637   *prev_ref_in = prev_ref;
5638   return true;
5639 }
5640
5641 /* Initializes the descriptor and generates a call to _gfor_allocate.  Does
5642    the work for an ALLOCATE statement.  */
5643 /*GCC ARRAYS*/
5644
5645 bool
5646 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
5647                     tree errlen, tree label_finish, tree expr3_elem_size,
5648                     tree *nelems, gfc_expr *expr3, tree e3_arr_desc,
5649                     bool e3_is_array_constr)
5650 {
5651   tree tmp;
5652   tree pointer;
5653   tree offset = NULL_TREE;
5654   tree token = NULL_TREE;
5655   tree size;
5656   tree msg;
5657   tree error = NULL_TREE;
5658   tree overflow; /* Boolean storing whether size calculation overflows.  */
5659   tree var_overflow = NULL_TREE;
5660   tree cond;
5661   tree set_descriptor;
5662   stmtblock_t set_descriptor_block;
5663   stmtblock_t elseblock;
5664   gfc_expr **lower;
5665   gfc_expr **upper;
5666   gfc_ref *ref, *prev_ref = NULL, *coref;
5667   bool allocatable, coarray, dimension, alloc_w_e3_arr_spec = false,
5668       non_ulimate_coarray_ptr_comp;
5669
5670   ref = expr->ref;
5671
5672   /* Find the last reference in the chain.  */
5673   if (!retrieve_last_ref (&ref, &prev_ref))
5674     return false;
5675
5676   /* Take the allocatable and coarray properties solely from the expr-ref's
5677      attributes and not from source=-expression.  */
5678   if (!prev_ref)
5679     {
5680       allocatable = expr->symtree->n.sym->attr.allocatable;
5681       dimension = expr->symtree->n.sym->attr.dimension;
5682       non_ulimate_coarray_ptr_comp = false;
5683     }
5684   else
5685     {
5686       allocatable = prev_ref->u.c.component->attr.allocatable;
5687       /* Pointer components in coarrayed derived types must be treated
5688          specially in that they are registered without a check if the are
5689          already associated.  This does not hold for ultimate coarray
5690          pointers.  */
5691       non_ulimate_coarray_ptr_comp = (prev_ref->u.c.component->attr.pointer
5692               && !prev_ref->u.c.component->attr.codimension);
5693       dimension = prev_ref->u.c.component->attr.dimension;
5694     }
5695
5696   /* For allocatable/pointer arrays in derived types, one of the refs has to be
5697      a coarray.  In this case it does not matter whether we are on this_image
5698      or not.  */
5699   coarray = false;
5700   for (coref = expr->ref; coref; coref = coref->next)
5701     if (coref->type == REF_ARRAY && coref->u.ar.codimen > 0)
5702       {
5703         coarray = true;
5704         break;
5705       }
5706
5707   if (!dimension)
5708     gcc_assert (coarray);
5709
5710   if (ref->u.ar.type == AR_FULL && expr3 != NULL)
5711     {
5712       gfc_ref *old_ref = ref;
5713       /* F08:C633: Array shape from expr3.  */
5714       ref = expr3->ref;
5715
5716       /* Find the last reference in the chain.  */
5717       if (!retrieve_last_ref (&ref, &prev_ref))
5718         {
5719           if (expr3->expr_type == EXPR_FUNCTION
5720               && gfc_expr_attr (expr3).dimension)
5721             ref = old_ref;
5722           else
5723             return false;
5724         }
5725       alloc_w_e3_arr_spec = true;
5726     }
5727
5728   /* Figure out the size of the array.  */
5729   switch (ref->u.ar.type)
5730     {
5731     case AR_ELEMENT:
5732       if (!coarray)
5733         {
5734           lower = NULL;
5735           upper = ref->u.ar.start;
5736           break;
5737         }
5738       /* Fall through.  */
5739
5740     case AR_SECTION:
5741       lower = ref->u.ar.start;
5742       upper = ref->u.ar.end;
5743       break;
5744
5745     case AR_FULL:
5746       gcc_assert (ref->u.ar.as->type == AS_EXPLICIT
5747                   || alloc_w_e3_arr_spec);
5748
5749       lower = ref->u.ar.as->lower;
5750       upper = ref->u.ar.as->upper;
5751       break;
5752
5753     default:
5754       gcc_unreachable ();
5755       break;
5756     }
5757
5758   overflow = integer_zero_node;
5759
5760   gfc_init_block (&set_descriptor_block);
5761   /* Take the corank only from the actual ref and not from the coref.  The
5762      later will mislead the generation of the array dimensions for allocatable/
5763      pointer components in derived types.  */
5764   size = gfc_array_init_size (se->expr, alloc_w_e3_arr_spec ? expr->rank
5765                                                            : ref->u.ar.as->rank,
5766                               coarray ? ref->u.ar.as->corank : 0,
5767                               &offset, lower, upper,
5768                               &se->pre, &set_descriptor_block, &overflow,
5769                               expr3_elem_size, nelems, expr3, e3_arr_desc,
5770                               e3_is_array_constr, expr);
5771
5772   if (dimension)
5773     {
5774       var_overflow = gfc_create_var (integer_type_node, "overflow");
5775       gfc_add_modify (&se->pre, var_overflow, overflow);
5776
5777       if (status == NULL_TREE)
5778         {
5779           /* Generate the block of code handling overflow.  */
5780           msg = gfc_build_addr_expr (pchar_type_node,
5781                     gfc_build_localized_cstring_const
5782                         ("Integer overflow when calculating the amount of "
5783                          "memory to allocate"));
5784           error = build_call_expr_loc (input_location,
5785                                        gfor_fndecl_runtime_error, 1, msg);
5786         }
5787       else
5788         {
5789           tree status_type = TREE_TYPE (status);
5790           stmtblock_t set_status_block;
5791
5792           gfc_start_block (&set_status_block);
5793           gfc_add_modify (&set_status_block, status,
5794                           build_int_cst (status_type, LIBERROR_ALLOCATION));
5795           error = gfc_finish_block (&set_status_block);
5796         }
5797     }
5798
5799   gfc_start_block (&elseblock);
5800
5801   /* Allocate memory to store the data.  */
5802   if (POINTER_TYPE_P (TREE_TYPE (se->expr)))
5803     se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
5804
5805   if (coarray && flag_coarray == GFC_FCOARRAY_LIB)
5806     {
5807       pointer = non_ulimate_coarray_ptr_comp ? se->expr
5808                                       : gfc_conv_descriptor_data_get (se->expr);
5809       token = gfc_conv_descriptor_token (se->expr);
5810       token = gfc_build_addr_expr (NULL_TREE, token);
5811     }
5812   else
5813     pointer = gfc_conv_descriptor_data_get (se->expr);
5814   STRIP_NOPS (pointer);
5815
5816   /* The allocatable variant takes the old pointer as first argument.  */
5817   if (allocatable)
5818     gfc_allocate_allocatable (&elseblock, pointer, size, token,
5819                               status, errmsg, errlen, label_finish, expr,
5820                               coref != NULL ? coref->u.ar.as->corank : 0);
5821   else if (non_ulimate_coarray_ptr_comp && token)
5822     /* The token is set only for GFC_FCOARRAY_LIB mode.  */
5823     gfc_allocate_using_caf_lib (&elseblock, pointer, size, token, status,
5824                                 errmsg, errlen,
5825                                 GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY);
5826   else
5827     gfc_allocate_using_malloc (&elseblock, pointer, size, status);
5828
5829   if (dimension)
5830     {
5831       cond = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
5832                            logical_type_node, var_overflow, integer_zero_node),
5833                            PRED_FORTRAN_OVERFLOW);
5834       tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
5835                              error, gfc_finish_block (&elseblock));
5836     }
5837   else
5838     tmp = gfc_finish_block (&elseblock);
5839
5840   gfc_add_expr_to_block (&se->pre, tmp);
5841
5842   /* Update the array descriptors.  */
5843   if (dimension)
5844     gfc_conv_descriptor_offset_set (&set_descriptor_block, se->expr, offset);
5845
5846   /* Pointer arrays need the span field to be set.  */
5847   if (is_pointer_array (se->expr)
5848       || (expr->ts.type == BT_CLASS
5849           && CLASS_DATA (expr)->attr.class_pointer))
5850     {
5851       if (expr3 && expr3_elem_size != NULL_TREE)
5852         tmp = expr3_elem_size;
5853       else
5854         tmp = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (se->expr)));
5855       tmp = fold_convert (gfc_array_index_type, tmp);
5856       gfc_conv_descriptor_span_set (&set_descriptor_block, se->expr, tmp);
5857     }
5858
5859   set_descriptor = gfc_finish_block (&set_descriptor_block);
5860   if (status != NULL_TREE)
5861     {
5862       cond = fold_build2_loc (input_location, EQ_EXPR,
5863                           logical_type_node, status,
5864                           build_int_cst (TREE_TYPE (status), 0));
5865       gfc_add_expr_to_block (&se->pre,
5866                  fold_build3_loc (input_location, COND_EXPR, void_type_node,
5867                                   cond,
5868                                   set_descriptor,
5869                                   build_empty_stmt (input_location)));
5870     }
5871   else
5872       gfc_add_expr_to_block (&se->pre, set_descriptor);
5873
5874   return true;
5875 }
5876
5877
5878 /* Create an array constructor from an initialization expression.
5879    We assume the frontend already did any expansions and conversions.  */
5880
5881 tree
5882 gfc_conv_array_initializer (tree type, gfc_expr * expr)
5883 {
5884   gfc_constructor *c;
5885   tree tmp;
5886   offset_int wtmp;
5887   gfc_se se;
5888   tree index, range;
5889   vec<constructor_elt, va_gc> *v = NULL;
5890
5891   if (expr->expr_type == EXPR_VARIABLE
5892       && expr->symtree->n.sym->attr.flavor == FL_PARAMETER
5893       && expr->symtree->n.sym->value)
5894     expr = expr->symtree->n.sym->value;
5895
5896   switch (expr->expr_type)
5897     {
5898     case EXPR_CONSTANT:
5899     case EXPR_STRUCTURE:
5900       /* A single scalar or derived type value.  Create an array with all
5901          elements equal to that value.  */
5902       gfc_init_se (&se, NULL);
5903
5904       if (expr->expr_type == EXPR_CONSTANT)
5905         gfc_conv_constant (&se, expr);
5906       else
5907         gfc_conv_structure (&se, expr, 1);
5908
5909       wtmp = wi::to_offset (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1;
5910       /* This will probably eat buckets of memory for large arrays.  */
5911       while (wtmp != 0)
5912         {
5913           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
5914           wtmp -= 1;
5915         }
5916       break;
5917
5918     case EXPR_ARRAY:
5919       /* Create a vector of all the elements.  */
5920       for (c = gfc_constructor_first (expr->value.constructor);
5921            c; c = gfc_constructor_next (c))
5922         {
5923           if (c->iterator)
5924             {
5925               /* Problems occur when we get something like
5926                  integer :: a(lots) = (/(i, i=1, lots)/)  */
5927               gfc_fatal_error ("The number of elements in the array "
5928                                "constructor at %L requires an increase of "
5929                                "the allowed %d upper limit. See "
5930                                "%<-fmax-array-constructor%> option",
5931                                &expr->where, flag_max_array_constructor);
5932               return NULL_TREE;
5933             }
5934           if (mpz_cmp_si (c->offset, 0) != 0)
5935             index = gfc_conv_mpz_to_tree (c->offset, gfc_index_integer_kind);
5936           else
5937             index = NULL_TREE;
5938
5939           if (mpz_cmp_si (c->repeat, 1) > 0)
5940             {
5941               tree tmp1, tmp2;
5942               mpz_t maxval;
5943
5944               mpz_init (maxval);
5945               mpz_add (maxval, c->offset, c->repeat);
5946               mpz_sub_ui (maxval, maxval, 1);
5947               tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
5948               if (mpz_cmp_si (c->offset, 0) != 0)
5949                 {
5950                   mpz_add_ui (maxval, c->offset, 1);
5951                   tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
5952                 }
5953               else
5954                 tmp1 = gfc_conv_mpz_to_tree (c->offset, gfc_index_integer_kind);
5955
5956               range = fold_build2 (RANGE_EXPR, gfc_array_index_type, tmp1, tmp2);
5957               mpz_clear (maxval);
5958             }
5959           else
5960             range = NULL;
5961
5962           gfc_init_se (&se, NULL);
5963           switch (c->expr->expr_type)
5964             {
5965             case EXPR_CONSTANT:
5966               gfc_conv_constant (&se, c->expr);
5967               break;
5968
5969             case EXPR_STRUCTURE:
5970               gfc_conv_structure (&se, c->expr, 1);
5971               break;
5972
5973             default:
5974               /* Catch those occasional beasts that do not simplify
5975                  for one reason or another, assuming that if they are
5976                  standard defying the frontend will catch them.  */
5977               gfc_conv_expr (&se, c->expr);
5978               break;
5979             }
5980
5981           if (range == NULL_TREE)
5982             CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
5983           else
5984             {
5985               if (index != NULL_TREE)
5986                 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
5987               CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
5988             }
5989         }
5990       break;
5991
5992     case EXPR_NULL:
5993       return gfc_build_null_descriptor (type);
5994
5995     default:
5996       gcc_unreachable ();
5997     }
5998
5999   /* Create a constructor from the list of elements.  */
6000   tmp = build_constructor (type, v);
6001   TREE_CONSTANT (tmp) = 1;
6002   return tmp;
6003 }
6004
6005
6006 /* Generate code to evaluate non-constant coarray cobounds.  */
6007
6008 void
6009 gfc_trans_array_cobounds (tree type, stmtblock_t * pblock,
6010                           const gfc_symbol *sym)
6011 {
6012   int dim;
6013   tree ubound;
6014   tree lbound;
6015   gfc_se se;
6016   gfc_array_spec *as;
6017
6018   as = IS_CLASS_ARRAY (sym) ? CLASS_DATA (sym)->as : sym->as;
6019
6020   for (dim = as->rank; dim < as->rank + as->corank; dim++)
6021     {
6022       /* Evaluate non-constant array bound expressions.  */
6023       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
6024       if (as->lower[dim] && !INTEGER_CST_P (lbound))
6025         {
6026           gfc_init_se (&se, NULL);
6027           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
6028           gfc_add_block_to_block (pblock, &se.pre);
6029           gfc_add_modify (pblock, lbound, se.expr);
6030         }
6031       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
6032       if (as->upper[dim] && !INTEGER_CST_P (ubound))
6033         {
6034           gfc_init_se (&se, NULL);
6035           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
6036           gfc_add_block_to_block (pblock, &se.pre);
6037           gfc_add_modify (pblock, ubound, se.expr);
6038         }
6039     }
6040 }
6041
6042
6043 /* Generate code to evaluate non-constant array bounds.  Sets *poffset and
6044    returns the size (in elements) of the array.  */
6045
6046 static tree
6047 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
6048                         stmtblock_t * pblock)
6049 {
6050   gfc_array_spec *as;
6051   tree size;
6052   tree stride;
6053   tree offset;
6054   tree ubound;
6055   tree lbound;
6056   tree tmp;
6057   gfc_se se;
6058
6059   int dim;
6060
6061   as = IS_CLASS_ARRAY (sym) ? CLASS_DATA (sym)->as : sym->as;
6062
6063   size = gfc_index_one_node;
6064   offset = gfc_index_zero_node;
6065   for (dim = 0; dim < as->rank; dim++)
6066     {
6067       /* Evaluate non-constant array bound expressions.  */
6068       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
6069       if (as->lower[dim] && !INTEGER_CST_P (lbound))
6070         {
6071           gfc_init_se (&se, NULL);
6072           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
6073           gfc_add_block_to_block (pblock, &se.pre);
6074           gfc_add_modify (pblock, lbound, se.expr);
6075         }
6076       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
6077       if (as->upper[dim] && !INTEGER_CST_P (ubound))
6078         {
6079           gfc_init_se (&se, NULL);
6080           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
6081           gfc_add_block_to_block (pblock, &se.pre);
6082           gfc_add_modify (pblock, ubound, se.expr);
6083         }
6084       /* The offset of this dimension.  offset = offset - lbound * stride.  */
6085       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6086                              lbound, size);
6087       offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
6088                                 offset, tmp);
6089
6090       /* The size of this dimension, and the stride of the next.  */
6091       if (dim + 1 < as->rank)
6092         stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
6093       else
6094         stride = GFC_TYPE_ARRAY_SIZE (type);
6095
6096       if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
6097         {
6098           /* Calculate stride = size * (ubound + 1 - lbound).  */
6099           tmp = fold_build2_loc (input_location, MINUS_EXPR,
6100                                  gfc_array_index_type,
6101                                  gfc_index_one_node, lbound);
6102           tmp = fold_build2_loc (input_location, PLUS_EXPR,
6103                                  gfc_array_index_type, ubound, tmp);
6104           tmp = fold_build2_loc (input_location, MULT_EXPR,
6105                                  gfc_array_index_type, size, tmp);
6106           if (stride)
6107             gfc_add_modify (pblock, stride, tmp);
6108           else
6109             stride = gfc_evaluate_now (tmp, pblock);
6110
6111           /* Make sure that negative size arrays are translated
6112              to being zero size.  */
6113           tmp = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
6114                                  stride, gfc_index_zero_node);
6115           tmp = fold_build3_loc (input_location, COND_EXPR,
6116                                  gfc_array_index_type, tmp,
6117                                  stride, gfc_index_zero_node);
6118           gfc_add_modify (pblock, stride, tmp);
6119         }
6120
6121       size = stride;
6122     }
6123
6124   gfc_trans_array_cobounds (type, pblock, sym);
6125   gfc_trans_vla_type_sizes (sym, pblock);
6126
6127   *poffset = offset;
6128   return size;
6129 }
6130
6131
6132 /* Generate code to initialize/allocate an array variable.  */
6133
6134 void
6135 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
6136                                  gfc_wrapped_block * block)
6137 {
6138   stmtblock_t init;
6139   tree type;
6140   tree tmp = NULL_TREE;
6141   tree size;
6142   tree offset;
6143   tree space;
6144   tree inittree;
6145   bool onstack;
6146
6147   gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
6148
6149   /* Do nothing for USEd variables.  */
6150   if (sym->attr.use_assoc)
6151     return;
6152
6153   type = TREE_TYPE (decl);
6154   gcc_assert (GFC_ARRAY_TYPE_P (type));
6155   onstack = TREE_CODE (type) != POINTER_TYPE;
6156
6157   gfc_init_block (&init);
6158
6159   /* Evaluate character string length.  */
6160   if (sym->ts.type == BT_CHARACTER
6161       && onstack && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
6162     {
6163       gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
6164
6165       gfc_trans_vla_type_sizes (sym, &init);
6166
6167       /* Emit a DECL_EXPR for this variable, which will cause the
6168          gimplifier to allocate storage, and all that good stuff.  */
6169       tmp = fold_build1_loc (input_location, DECL_EXPR, TREE_TYPE (decl), decl);
6170       gfc_add_expr_to_block (&init, tmp);
6171     }
6172
6173   if (onstack)
6174     {
6175       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
6176       return;
6177     }
6178
6179   type = TREE_TYPE (type);
6180
6181   gcc_assert (!sym->attr.use_assoc);
6182   gcc_assert (!TREE_STATIC (decl));
6183   gcc_assert (!sym->module);
6184
6185   if (sym->ts.type == BT_CHARACTER
6186       && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
6187     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
6188
6189   size = gfc_trans_array_bounds (type, sym, &offset, &init);
6190
6191   /* Don't actually allocate space for Cray Pointees.  */
6192   if (sym->attr.cray_pointee)
6193     {
6194       if (VAR_P (GFC_TYPE_ARRAY_OFFSET (type)))
6195         gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
6196
6197       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
6198       return;
6199     }
6200
6201   if (flag_stack_arrays)
6202     {
6203       gcc_assert (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE);
6204       space = build_decl (sym->declared_at.lb->location,
6205                           VAR_DECL, create_tmp_var_name ("A"),
6206                           TREE_TYPE (TREE_TYPE (decl)));
6207       gfc_trans_vla_type_sizes (sym, &init);
6208     }
6209   else
6210     {
6211       /* The size is the number of elements in the array, so multiply by the
6212          size of an element to get the total size.  */
6213       tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
6214       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6215                               size, fold_convert (gfc_array_index_type, tmp));
6216
6217       /* Allocate memory to hold the data.  */
6218       tmp = gfc_call_malloc (&init, TREE_TYPE (decl), size);
6219       gfc_add_modify (&init, decl, tmp);
6220
6221       /* Free the temporary.  */
6222       tmp = gfc_call_free (decl);
6223       space = NULL_TREE;
6224     }
6225
6226   /* Set offset of the array.  */
6227   if (VAR_P (GFC_TYPE_ARRAY_OFFSET (type)))
6228     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
6229
6230   /* Automatic arrays should not have initializers.  */
6231   gcc_assert (!sym->value);
6232
6233   inittree = gfc_finish_block (&init);
6234
6235   if (space)
6236     {
6237       tree addr;
6238       pushdecl (space);
6239
6240       /* Don't create new scope, emit the DECL_EXPR in exactly the scope
6241          where also space is located.  */
6242       gfc_init_block (&init);
6243       tmp = fold_build1_loc (input_location, DECL_EXPR,
6244                              TREE_TYPE (space), space);
6245       gfc_add_expr_to_block (&init, tmp);
6246       addr = fold_build1_loc (sym->declared_at.lb->location,
6247                               ADDR_EXPR, TREE_TYPE (decl), space);
6248       gfc_add_modify (&init, decl, addr);
6249       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
6250       tmp = NULL_TREE;
6251     }
6252   gfc_add_init_cleanup (block, inittree, tmp);
6253 }
6254
6255
6256 /* Generate entry and exit code for g77 calling convention arrays.  */
6257
6258 void
6259 gfc_trans_g77_array (gfc_symbol * sym, gfc_wrapped_block * block)
6260 {
6261   tree parm;
6262   tree type;
6263   locus loc;
6264   tree offset;
6265   tree tmp;
6266   tree stmt;
6267   stmtblock_t init;
6268
6269   gfc_save_backend_locus (&loc);
6270   gfc_set_backend_locus (&sym->declared_at);
6271
6272   /* Descriptor type.  */
6273   parm = sym->backend_decl;
6274   type = TREE_TYPE (parm);
6275   gcc_assert (GFC_ARRAY_TYPE_P (type));
6276
6277   gfc_start_block (&init);
6278
6279   if (sym->ts.type == BT_CHARACTER
6280       && VAR_P (sym->ts.u.cl->backend_decl))
6281     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
6282
6283   /* Evaluate the bounds of the array.  */
6284   gfc_trans_array_bounds (type, sym, &offset, &init);
6285
6286   /* Set the offset.  */
6287   if (VAR_P (GFC_TYPE_ARRAY_OFFSET (type)))
6288     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
6289
6290   /* Set the pointer itself if we aren't using the parameter directly.  */
6291   if (TREE_CODE (parm) != PARM_DECL)
6292     {
6293       tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
6294       gfc_add_modify (&init, parm, tmp);
6295     }
6296   stmt = gfc_finish_block (&init);
6297
6298   gfc_restore_backend_locus (&loc);
6299
6300   /* Add the initialization code to the start of the function.  */
6301
6302   if (sym->attr.optional || sym->attr.not_always_present)
6303     {
6304       tmp = gfc_conv_expr_present (sym);
6305       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
6306     }
6307
6308   gfc_add_init_cleanup (block, stmt, NULL_TREE);
6309 }
6310
6311
6312 /* Modify the descriptor of an array parameter so that it has the
6313    correct lower bound.  Also move the upper bound accordingly.
6314    If the array is not packed, it will be copied into a temporary.
6315    For each dimension we set the new lower and upper bounds.  Then we copy the
6316    stride and calculate the offset for this dimension.  We also work out
6317    what the stride of a packed array would be, and see it the two match.
6318    If the array need repacking, we set the stride to the values we just
6319    calculated, recalculate the offset and copy the array data.
6320    Code is also added to copy the data back at the end of the function.
6321    */
6322
6323 void
6324 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc,
6325                             gfc_wrapped_block * block)
6326 {
6327   tree size;
6328   tree type;
6329   tree offset;
6330   locus loc;
6331   stmtblock_t init;
6332   tree stmtInit, stmtCleanup;
6333   tree lbound;
6334   tree ubound;
6335   tree dubound;
6336   tree dlbound;
6337   tree dumdesc;
6338   tree tmp;
6339   tree stride, stride2;
6340   tree stmt_packed;
6341   tree stmt_unpacked;
6342   tree partial;
6343   gfc_se se;
6344   int n;
6345   int checkparm;
6346   int no_repack;
6347   bool optional_arg;
6348   gfc_array_spec *as;
6349   bool is_classarray = IS_CLASS_ARRAY (sym);
6350
6351   /* Do nothing for pointer and allocatable arrays.  */
6352   if ((sym->ts.type != BT_CLASS && sym->attr.pointer)
6353       || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.class_pointer)
6354       || sym->attr.allocatable
6355       || (is_classarray && CLASS_DATA (sym)->attr.allocatable))
6356     return;
6357
6358   if (!is_classarray && sym->attr.dummy && gfc_is_nodesc_array (sym))
6359     {
6360       gfc_trans_g77_array (sym, block);
6361       return;
6362     }
6363
6364   loc.nextc = NULL;
6365   gfc_save_backend_locus (&loc);
6366   /* loc.nextc is not set by save_backend_locus but the location routines
6367      depend on it.  */
6368   if (loc.nextc == NULL)
6369     loc.nextc = loc.lb->line;
6370   gfc_set_backend_locus (&sym->declared_at);
6371
6372   /* Descriptor type.  */
6373   type = TREE_TYPE (tmpdesc);
6374   gcc_assert (GFC_ARRAY_TYPE_P (type));
6375   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
6376   if (is_classarray)
6377     /* For a class array the dummy array descriptor is in the _class
6378        component.  */
6379     dumdesc = gfc_class_data_get (dumdesc);
6380   else
6381     dumdesc = build_fold_indirect_ref_loc (input_location, dumdesc);
6382   as = IS_CLASS_ARRAY (sym) ? CLASS_DATA (sym)->as : sym->as;
6383   gfc_start_block (&init);
6384
6385   if (sym->ts.type == BT_CHARACTER
6386       && VAR_P (sym->ts.u.cl->backend_decl))
6387     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
6388
6389   checkparm = (as->type == AS_EXPLICIT
6390                && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS));
6391
6392   no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
6393                 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
6394
6395   if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
6396     {
6397       /* For non-constant shape arrays we only check if the first dimension
6398          is contiguous.  Repacking higher dimensions wouldn't gain us
6399          anything as we still don't know the array stride.  */
6400       partial = gfc_create_var (logical_type_node, "partial");
6401       TREE_USED (partial) = 1;
6402       tmp = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
6403       tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
6404                              gfc_index_one_node);
6405       gfc_add_modify (&init, partial, tmp);
6406     }
6407   else
6408     partial = NULL_TREE;
6409
6410   /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
6411      here, however I think it does the right thing.  */
6412   if (no_repack)
6413     {
6414       /* Set the first stride.  */
6415       stride = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
6416       stride = gfc_evaluate_now (stride, &init);
6417
6418       tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
6419                              stride, gfc_index_zero_node);
6420       tmp = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
6421                              tmp, gfc_index_one_node, stride);
6422       stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
6423       gfc_add_modify (&init, stride, tmp);
6424
6425       /* Allow the user to disable array repacking.  */
6426       stmt_unpacked = NULL_TREE;
6427     }
6428   else
6429     {
6430       gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
6431       /* A library call to repack the array if necessary.  */
6432       tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
6433       stmt_unpacked = build_call_expr_loc (input_location,
6434                                        gfor_fndecl_in_pack, 1, tmp);
6435
6436       stride = gfc_index_one_node;
6437
6438       if (warn_array_temporaries)
6439         gfc_warning (OPT_Warray_temporaries,
6440                      "Creating array temporary at %L", &loc);
6441     }
6442
6443   /* This is for the case where the array data is used directly without
6444      calling the repack function.  */
6445   if (no_repack || partial != NULL_TREE)
6446     stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
6447   else
6448     stmt_packed = NULL_TREE;
6449
6450   /* Assign the data pointer.  */
6451   if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
6452     {
6453       /* Don't repack unknown shape arrays when the first stride is 1.  */
6454       tmp = fold_build3_loc (input_location, COND_EXPR, TREE_TYPE (stmt_packed),
6455                              partial, stmt_packed, stmt_unpacked);
6456     }
6457   else
6458     tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
6459   gfc_add_modify (&init, tmpdesc, fold_convert (type, tmp));
6460
6461   offset = gfc_index_zero_node;
6462   size = gfc_index_one_node;
6463
6464   /* Evaluate the bounds of the array.  */
6465   for (n = 0; n < as->rank; n++)
6466     {
6467       if (checkparm || !as->upper[n])
6468         {
6469           /* Get the bounds of the actual parameter.  */
6470           dubound = gfc_conv_descriptor_ubound_get (dumdesc, gfc_rank_cst[n]);
6471           dlbound = gfc_conv_descriptor_lbound_get (dumdesc, gfc_rank_cst[n]);
6472         }
6473       else
6474         {
6475           dubound = NULL_TREE;
6476           dlbound = NULL_TREE;
6477         }
6478
6479       lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
6480       if (!INTEGER_CST_P (lbound))
6481         {
6482           gfc_init_se (&se, NULL);
6483           gfc_conv_expr_type (&se, as->lower[n],
6484                               gfc_array_index_type);
6485           gfc_add_block_to_block (&init, &se.pre);
6486           gfc_add_modify (&init, lbound, se.expr);
6487         }
6488
6489       ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
6490       /* Set the desired upper bound.  */
6491       if (as->upper[n])
6492         {
6493           /* We know what we want the upper bound to be.  */
6494           if (!INTEGER_CST_P (ubound))
6495             {
6496               gfc_init_se (&se, NULL);
6497               gfc_conv_expr_type (&se, as->upper[n],
6498                                   gfc_array_index_type);
6499               gfc_add_block_to_block (&init, &se.pre);
6500               gfc_add_modify (&init, ubound, se.expr);
6501             }
6502
6503           /* Check the sizes match.  */
6504           if (checkparm)
6505             {
6506               /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)).  */
6507               char * msg;
6508               tree temp;
6509
6510               temp = fold_build2_loc (input_location, MINUS_EXPR,
6511                                       gfc_array_index_type, ubound, lbound);
6512               temp = fold_build2_loc (input_location, PLUS_EXPR,
6513                                       gfc_array_index_type,
6514                                       gfc_index_one_node, temp);
6515               stride2 = fold_build2_loc (input_location, MINUS_EXPR,
6516                                          gfc_array_index_type, dubound,
6517                                          dlbound);
6518               stride2 = fold_build2_loc (input_location, PLUS_EXPR,
6519                                          gfc_array_index_type,
6520                                          gfc_index_one_node, stride2);
6521               tmp = fold_build2_loc (input_location, NE_EXPR,
6522                                      gfc_array_index_type, temp, stride2);
6523               msg = xasprintf ("Dimension %d of array '%s' has extent "
6524                                "%%ld instead of %%ld", n+1, sym->name);
6525
6526               gfc_trans_runtime_check (true, false, tmp, &init, &loc, msg,
6527                         fold_convert (long_integer_type_node, temp),
6528                         fold_convert (long_integer_type_node, stride2));
6529
6530               free (msg);
6531             }
6532         }
6533       else
6534         {
6535           /* For assumed shape arrays move the upper bound by the same amount
6536              as the lower bound.  */
6537           tmp = fold_build2_loc (input_location, MINUS_EXPR,
6538                                  gfc_array_index_type, dubound, dlbound);
6539           tmp = fold_build2_loc (input_location, PLUS_EXPR,
6540                                  gfc_array_index_type, tmp, lbound);
6541           gfc_add_modify (&init, ubound, tmp);
6542         }
6543       /* The offset of this dimension.  offset = offset - lbound * stride.  */
6544       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6545                              lbound, stride);
6546       offset = fold_build2_loc (input_location, MINUS_EXPR,
6547                                 gfc_array_index_type, offset, tmp);
6548
6549       /* The size of this dimension, and the stride of the next.  */
6550       if (n + 1 < as->rank)
6551         {
6552           stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
6553
6554           if (no_repack || partial != NULL_TREE)
6555             stmt_unpacked =
6556               gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[n+1]);
6557
6558           /* Figure out the stride if not a known constant.  */
6559           if (!INTEGER_CST_P (stride))
6560             {
6561               if (no_repack)
6562                 stmt_packed = NULL_TREE;
6563               else
6564                 {
6565                   /* Calculate stride = size * (ubound + 1 - lbound).  */
6566                   tmp = fold_build2_loc (input_location, MINUS_EXPR,
6567                                          gfc_array_index_type,
6568                                          gfc_index_one_node, lbound);
6569                   tmp = fold_build2_loc (input_location, PLUS_EXPR,
6570                                          gfc_array_index_type, ubound, tmp);
6571                   size = fold_build2_loc (input_location, MULT_EXPR,
6572                                           gfc_array_index_type, size, tmp);
6573                   stmt_packed = size;
6574                 }
6575
6576               /* Assign the stride.  */
6577               if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
6578                 tmp = fold_build3_loc (input_location, COND_EXPR,
6579                                        gfc_array_index_type, partial,
6580                                        stmt_unpacked, stmt_packed);
6581               else
6582                 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
6583               gfc_add_modify (&init, stride, tmp);
6584             }
6585         }
6586       else
6587         {
6588           stride = GFC_TYPE_ARRAY_SIZE (type);
6589
6590           if (stride && !INTEGER_CST_P (stride))
6591             {
6592               /* Calculate size = stride * (ubound + 1 - lbound).  */
6593               tmp = fold_build2_loc (input_location, MINUS_EXPR,
6594                                      gfc_array_index_type,
6595                                      gfc_index_one_node, lbound);
6596               tmp = fold_build2_loc (input_location, PLUS_EXPR,
6597                                      gfc_array_index_type,
6598                                      ubound, tmp);
6599               tmp = fold_build2_loc (input_location, MULT_EXPR,
6600                                      gfc_array_index_type,
6601                                      GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
6602               gfc_add_modify (&init, stride, tmp);
6603             }
6604         }
6605     }
6606
6607   gfc_trans_array_cobounds (type, &init, sym);
6608
6609   /* Set the offset.  */
6610   if (VAR_P (GFC_TYPE_ARRAY_OFFSET (type)))
6611     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
6612
6613   gfc_trans_vla_type_sizes (sym, &init);
6614
6615   stmtInit = gfc_finish_block (&init);
6616
6617   /* Only do the entry/initialization code if the arg is present.  */
6618   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
6619   optional_arg = (sym->attr.optional
6620                   || (sym->ns->proc_name->attr.entry_master
6621                       && sym->attr.dummy));
6622   if (optional_arg)
6623     {
6624       tmp = gfc_conv_expr_present (sym);
6625       stmtInit = build3_v (COND_EXPR, tmp, stmtInit,
6626                            build_empty_stmt (input_location));
6627     }
6628
6629   /* Cleanup code.  */
6630   if (no_repack)
6631     stmtCleanup = NULL_TREE;
6632   else
6633     {
6634       stmtblock_t cleanup;
6635       gfc_start_block (&cleanup);
6636
6637       if (sym->attr.intent != INTENT_IN)
6638         {
6639           /* Copy the data back.  */
6640           tmp = build_call_expr_loc (input_location,
6641                                  gfor_fndecl_in_unpack, 2, dumdesc, tmpdesc);
6642           gfc_add_expr_to_block (&cleanup, tmp);
6643         }
6644
6645       /* Free the temporary.  */
6646       tmp = gfc_call_free (tmpdesc);
6647       gfc_add_expr_to_block (&cleanup, tmp);
6648
6649       stmtCleanup = gfc_finish_block (&cleanup);
6650
6651       /* Only do the cleanup if the array was repacked.  */
6652       if (is_classarray)
6653         /* For a class array the dummy array descriptor is in the _class
6654            component.  */
6655         tmp = gfc_class_data_get (dumdesc);
6656       else
6657         tmp = build_fold_indirect_ref_loc (input_location, dumdesc);
6658       tmp = gfc_conv_descriptor_data_get (tmp);
6659       tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
6660                              tmp, tmpdesc);
6661       stmtCleanup = build3_v (COND_EXPR, tmp, stmtCleanup,
6662                               build_empty_stmt (input_location));
6663
6664       if (optional_arg)
6665         {
6666           tmp = gfc_conv_expr_present (sym);
6667           stmtCleanup = build3_v (COND_EXPR, tmp, stmtCleanup,
6668                                   build_empty_stmt (input_location));
6669         }
6670     }
6671
6672   /* We don't need to free any memory allocated by internal_pack as it will
6673      be freed at the end of the function by pop_context.  */
6674   gfc_add_init_cleanup (block, stmtInit, stmtCleanup);
6675
6676   gfc_restore_backend_locus (&loc);
6677 }
6678
6679
6680 /* Calculate the overall offset, including subreferences.  */
6681 static void
6682 gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
6683                         bool subref, gfc_expr *expr)
6684 {
6685   tree tmp;
6686   tree field;
6687   tree stride;
6688   tree index;
6689   gfc_ref *ref;
6690   gfc_se start;
6691   int n;
6692
6693   /* If offset is NULL and this is not a subreferenced array, there is
6694      nothing to do.  */
6695   if (offset == NULL_TREE)
6696     {
6697       if (subref)
6698         offset = gfc_index_zero_node;
6699       else
6700         return;
6701     }
6702
6703   tmp = build_array_ref (desc, offset, NULL, NULL);
6704
6705   /* Offset the data pointer for pointer assignments from arrays with
6706      subreferences; e.g. my_integer => my_type(:)%integer_component.  */
6707   if (subref)
6708     {
6709       /* Go past the array reference.  */
6710       for (ref = expr->ref; ref; ref = ref->next)
6711         if (ref->type == REF_ARRAY &&
6712               ref->u.ar.type != AR_ELEMENT)
6713           {
6714             ref = ref->next;
6715             break;
6716           }
6717
6718       /* Calculate the offset for each subsequent subreference.  */
6719       for (; ref; ref = ref->next)
6720         {
6721           switch (ref->type)
6722             {
6723             case REF_COMPONENT:
6724               field = ref->u.c.component->backend_decl;
6725               gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
6726               tmp = fold_build3_loc (input_location, COMPONENT_REF,
6727                                      TREE_TYPE (field),
6728                                      tmp, field, NULL_TREE);
6729               break;
6730
6731             case REF_SUBSTRING:
6732               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
6733               gfc_init_se (&start, NULL);
6734               gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
6735               gfc_add_block_to_block (block, &start.pre);
6736               tmp = gfc_build_array_ref (tmp, start.expr, NULL);
6737               break;
6738
6739             case REF_ARRAY:
6740               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE
6741                             && ref->u.ar.type == AR_ELEMENT);
6742
6743               /* TODO - Add bounds checking.  */
6744               stride = gfc_index_one_node;
6745               index = gfc_index_zero_node;
6746               for (n = 0; n < ref->u.ar.dimen; n++)
6747                 {
6748                   tree itmp;
6749                   tree jtmp;
6750
6751                   /* Update the index.  */
6752                   gfc_init_se (&start, NULL);
6753                   gfc_conv_expr_type (&start, ref->u.ar.start[n], gfc_array_index_type);
6754                   itmp = gfc_evaluate_now (start.expr, block);
6755                   gfc_init_se (&start, NULL);
6756                   gfc_conv_expr_type (&start, ref->u.ar.as->lower[n], gfc_array_index_type);
6757                   jtmp = gfc_evaluate_now (start.expr, block);
6758                   itmp = fold_build2_loc (input_location, MINUS_EXPR,
6759                                           gfc_array_index_type, itmp, jtmp);
6760                   itmp = fold_build2_loc (input_location, MULT_EXPR,
6761                                           gfc_array_index_type, itmp, stride);
6762                   index = fold_build2_loc (input_location, PLUS_EXPR,
6763                                           gfc_array_index_type, itmp, index);
6764                   index = gfc_evaluate_now (index, block);
6765
6766                   /* Update the stride.  */
6767                   gfc_init_se (&start, NULL);
6768                   gfc_conv_expr_type (&start, ref->u.ar.as->upper[n], gfc_array_index_type);
6769                   itmp =  fold_build2_loc (input_location, MINUS_EXPR,
6770                                            gfc_array_index_type, start.expr,
6771                                            jtmp);
6772                   itmp =  fold_build2_loc (input_location, PLUS_EXPR,
6773                                            gfc_array_index_type,
6774                                            gfc_index_one_node, itmp);
6775                   stride =  fold_build2_loc (input_location, MULT_EXPR,
6776                                              gfc_array_index_type, stride, itmp);
6777                   stride = gfc_evaluate_now (stride, block);
6778                 }
6779
6780               /* Apply the index to obtain the array element.  */
6781               tmp = gfc_build_array_ref (tmp, index, NULL);
6782               break;
6783
6784             default:
6785               gcc_unreachable ();
6786               break;
6787             }
6788         }
6789     }
6790
6791   /* Set the target data pointer.  */
6792   offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
6793   gfc_conv_descriptor_data_set (block, parm, offset);
6794 }
6795
6796
6797 /* gfc_conv_expr_descriptor needs the string length an expression
6798    so that the size of the temporary can be obtained.  This is done
6799    by adding up the string lengths of all the elements in the
6800    expression.  Function with non-constant expressions have their
6801    string lengths mapped onto the actual arguments using the
6802    interface mapping machinery in trans-expr.c.  */
6803 static void
6804 get_array_charlen (gfc_expr *expr, gfc_se *se)
6805 {
6806   gfc_interface_mapping mapping;
6807   gfc_formal_arglist *formal;
6808   gfc_actual_arglist *arg;
6809   gfc_se tse;
6810
6811   if (expr->ts.u.cl->length
6812         && gfc_is_constant_expr (expr->ts.u.cl->length))
6813     {
6814       if (!expr->ts.u.cl->backend_decl)
6815         gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
6816       return;
6817     }
6818
6819   switch (expr->expr_type)
6820     {
6821     case EXPR_OP:
6822       get_array_charlen (expr->value.op.op1, se);
6823
6824       /* For parentheses the expression ts.u.cl is identical.  */
6825       if (expr->value.op.op == INTRINSIC_PARENTHESES)
6826         return;
6827
6828      expr->ts.u.cl->backend_decl =
6829                 gfc_create_var (gfc_charlen_type_node, "sln");
6830
6831       if (expr->value.op.op2)
6832         {
6833           get_array_charlen (expr->value.op.op2, se);
6834
6835           gcc_assert (expr->value.op.op == INTRINSIC_CONCAT);
6836
6837           /* Add the string lengths and assign them to the expression
6838              string length backend declaration.  */
6839           gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
6840                           fold_build2_loc (input_location, PLUS_EXPR,
6841                                 gfc_charlen_type_node,
6842                                 expr->value.op.op1->ts.u.cl->backend_decl,
6843                                 expr->value.op.op2->ts.u.cl->backend_decl));
6844         }
6845       else
6846         gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
6847                         expr->value.op.op1->ts.u.cl->backend_decl);
6848       break;
6849
6850     case EXPR_FUNCTION:
6851       if (expr->value.function.esym == NULL
6852             || expr->ts.u.cl->length->expr_type == EXPR_CONSTANT)
6853         {
6854           gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
6855           break;
6856         }
6857
6858       /* Map expressions involving the dummy arguments onto the actual
6859          argument expressions.  */
6860       gfc_init_interface_mapping (&mapping);
6861       formal = gfc_sym_get_dummy_args (expr->symtree->n.sym);
6862       arg = expr->value.function.actual;
6863
6864       /* Set se = NULL in the calls to the interface mapping, to suppress any
6865          backend stuff.  */
6866       for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
6867         {
6868           if (!arg->expr)
6869             continue;
6870           if (formal->sym)
6871           gfc_add_interface_mapping (&mapping, formal->sym, NULL, arg->expr);
6872         }
6873
6874       gfc_init_se (&tse, NULL);
6875
6876       /* Build the expression for the character length and convert it.  */
6877       gfc_apply_interface_mapping (&mapping, &tse, expr->ts.u.cl->length);
6878
6879       gfc_add_block_to_block (&se->pre, &tse.pre);
6880       gfc_add_block_to_block (&se->post, &tse.post);
6881       tse.expr = fold_convert (gfc_charlen_type_node, tse.expr);
6882       tse.expr = fold_build2_loc (input_location, MAX_EXPR,
6883                                   TREE_TYPE (tse.expr), tse.expr,
6884                                   build_zero_cst (TREE_TYPE (tse.expr)));
6885       expr->ts.u.cl->backend_decl = tse.expr;
6886       gfc_free_interface_mapping (&mapping);
6887       break;
6888
6889     default:
6890       gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
6891       break;
6892     }
6893 }
6894
6895
6896 /* Helper function to check dimensions.  */
6897 static bool
6898 transposed_dims (gfc_ss *ss)
6899 {
6900   int n;
6901
6902   for (n = 0; n < ss->dimen; n++)
6903     if (ss->dim[n] != n)
6904       return true;
6905   return false;
6906 }
6907
6908
6909 /* Convert the last ref of a scalar coarray from an AR_ELEMENT to an
6910    AR_FULL, suitable for the scalarizer.  */
6911
6912 static gfc_ss *
6913 walk_coarray (gfc_expr *e)
6914 {
6915   gfc_ss *ss;
6916
6917   gcc_assert (gfc_get_corank (e) > 0);
6918
6919   ss = gfc_walk_expr (e);
6920
6921   /* Fix scalar coarray.  */
6922   if (ss == gfc_ss_terminator)
6923     {
6924       gfc_ref *ref;
6925
6926       ref = e->ref;
6927       while (ref)
6928         {
6929           if (ref->type == REF_ARRAY
6930               && ref->u.ar.codimen > 0)
6931             break;
6932
6933           ref = ref->next;
6934         }
6935
6936       gcc_assert (ref != NULL);
6937       if (ref->u.ar.type == AR_ELEMENT)
6938         ref->u.ar.type = AR_SECTION;
6939       ss = gfc_reverse_ss (gfc_walk_array_ref (ss, e, ref));
6940     }
6941
6942   return ss;
6943 }
6944
6945
6946 /* Convert an array for passing as an actual argument.  Expressions and
6947    vector subscripts are evaluated and stored in a temporary, which is then
6948    passed.  For whole arrays the descriptor is passed.  For array sections
6949    a modified copy of the descriptor is passed, but using the original data.
6950
6951    This function is also used for array pointer assignments, and there
6952    are three cases:
6953
6954      - se->want_pointer && !se->direct_byref
6955          EXPR is an actual argument.  On exit, se->expr contains a
6956          pointer to the array descriptor.
6957
6958      - !se->want_pointer && !se->direct_byref
6959          EXPR is an actual argument to an intrinsic function or the
6960          left-hand side of a pointer assignment.  On exit, se->expr
6961          contains the descriptor for EXPR.
6962
6963      - !se->want_pointer && se->direct_byref
6964          EXPR is the right-hand side of a pointer assignment and
6965          se->expr is the descriptor for the previously-evaluated
6966          left-hand side.  The function creates an assignment from
6967          EXPR to se->expr.
6968
6969
6970    The se->force_tmp flag disables the non-copying descriptor optimization
6971    that is used for transpose. It may be used in cases where there is an
6972    alias between the transpose argument and another argument in the same
6973    function call.  */
6974
6975 void
6976 gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
6977 {
6978   gfc_ss *ss;
6979   gfc_ss_type ss_type;
6980   gfc_ss_info *ss_info;
6981   gfc_loopinfo loop;
6982   gfc_array_info *info;
6983   int need_tmp;
6984   int n;
6985   tree tmp;
6986   tree desc;
6987   stmtblock_t block;
6988   tree start;
6989   tree offset;
6990   int full;
6991   bool subref_array_target = false;
6992   gfc_expr *arg, *ss_expr;
6993
6994   if (se->want_coarray)
6995     ss = walk_coarray (expr);
6996   else
6997     ss = gfc_walk_expr (expr);
6998
6999   gcc_assert (ss != NULL);
7000   gcc_assert (ss != gfc_ss_terminator);
7001
7002   ss_info = ss->info;
7003   ss_type = ss_info->type;
7004   ss_expr = ss_info->expr;
7005
7006   /* Special case: TRANSPOSE which needs no temporary.  */
7007   while (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym
7008          && (arg = gfc_get_noncopying_intrinsic_argument (expr)) != NULL)
7009     {
7010       /* This is a call to transpose which has already been handled by the
7011          scalarizer, so that we just need to get its argument's descriptor.  */
7012       gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
7013       expr = expr->value.function.actual->expr;
7014     }
7015
7016   /* Special case things we know we can pass easily.  */
7017   switch (expr->expr_type)
7018     {
7019     case EXPR_VARIABLE:
7020       /* If we have a linear array section, we can pass it directly.
7021          Otherwise we need to copy it into a temporary.  */
7022
7023       gcc_assert (ss_type == GFC_SS_SECTION);
7024       gcc_assert (ss_expr == expr);
7025       info = &ss_info->data.array;
7026
7027       /* Get the descriptor for the array.  */
7028       gfc_conv_ss_descriptor (&se->pre, ss, 0);
7029       desc = info->descriptor;
7030
7031       subref_array_target = se->direct_byref && is_subref_array (expr);
7032       need_tmp = gfc_ref_needs_temporary_p (expr->ref)
7033                         && !subref_array_target;
7034
7035       if (se->force_tmp)
7036         need_tmp = 1;
7037
7038       if (need_tmp)
7039         full = 0;
7040       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
7041         {
7042           /* Create a new descriptor if the array doesn't have one.  */
7043           full = 0;
7044         }
7045       else if (info->ref->u.ar.type == AR_FULL || se->descriptor_only)
7046         full = 1;
7047       else if (se->direct_byref)
7048         full = 0;
7049       else
7050         full = gfc_full_array_ref_p (info->ref, NULL);
7051
7052       if (full && !transposed_dims (ss))
7053         {
7054           if (se->direct_byref && !se->byref_noassign)
7055             {
7056               /* Copy the descriptor for pointer assignments.  */
7057               gfc_add_modify (&se->pre, se->expr, desc);
7058
7059               /* Add any offsets from subreferences.  */
7060               gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE,
7061                                       subref_array_target, expr);
7062
7063               /* ....and set the span field.  */
7064               tmp = gfc_get_array_span (desc, expr);
7065               gfc_conv_descriptor_span_set (&se->pre, se->expr, tmp);
7066             }
7067           else if (se->want_pointer)
7068             {
7069               /* We pass full arrays directly.  This means that pointers and
7070                  allocatable arrays should also work.  */
7071               se->expr = gfc_build_addr_expr (NULL_TREE, desc);
7072             }
7073           else
7074             {
7075               se->expr = desc;
7076             }
7077
7078           if (expr->ts.type == BT_CHARACTER)
7079             se->string_length = gfc_get_expr_charlen (expr);
7080
7081           gfc_free_ss_chain (ss);
7082           return;
7083         }
7084       break;
7085
7086     case EXPR_FUNCTION:
7087       /* A transformational function return value will be a temporary
7088          array descriptor.  We still need to go through the scalarizer
7089          to create the descriptor.  Elemental functions are handled as
7090          arbitrary expressions, i.e. copy to a temporary.  */
7091
7092       if (se->direct_byref)
7093         {
7094           gcc_assert (ss_type == GFC_SS_FUNCTION && ss_expr == expr);
7095
7096           /* For pointer assignments pass the descriptor directly.  */
7097           if (se->ss == NULL)
7098             se->ss = ss;
7099           else
7100             gcc_assert (se->ss == ss);
7101
7102           if (!is_pointer_array (se->expr))
7103             {
7104               tmp = gfc_get_element_type (TREE_TYPE (se->expr));
7105               tmp = fold_convert (gfc_array_index_type,
7106                                   size_in_bytes (tmp));
7107               gfc_conv_descriptor_span_set (&se->pre, se->expr, tmp);
7108             }
7109
7110           se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
7111           gfc_conv_expr (se, expr);
7112
7113           gfc_free_ss_chain (ss);
7114           return;
7115         }
7116
7117       if (ss_expr != expr || ss_type != GFC_SS_FUNCTION)
7118         {
7119           if (ss_expr != expr)
7120             /* Elemental function.  */
7121             gcc_assert ((expr->value.function.esym != NULL
7122                          && expr->value.function.esym->attr.elemental)
7123                         || (expr->value.function.isym != NULL
7124                             && expr->value.function.isym->elemental)
7125                         || gfc_inline_intrinsic_function_p (expr));
7126           else
7127             gcc_assert (ss_type == GFC_SS_INTRINSIC);
7128
7129           need_tmp = 1;
7130           if (expr->ts.type == BT_CHARACTER
7131                 && expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
7132             get_array_charlen (expr, se);
7133
7134           info = NULL;
7135         }
7136       else
7137         {
7138           /* Transformational function.  */
7139           info = &ss_info->data.array;
7140           need_tmp = 0;
7141         }
7142       break;
7143
7144     case EXPR_ARRAY:
7145       /* Constant array constructors don't need a temporary.  */
7146       if (ss_type == GFC_SS_CONSTRUCTOR
7147           && expr->ts.type != BT_CHARACTER
7148           && gfc_constant_array_constructor_p (expr->value.constructor))
7149         {
7150           need_tmp = 0;
7151           info = &ss_info->data.array;
7152         }
7153       else
7154         {
7155           need_tmp = 1;
7156           info = NULL;
7157         }
7158       break;
7159
7160     default:
7161       /* Something complicated.  Copy it into a temporary.  */
7162       need_tmp = 1;
7163       info = NULL;
7164       break;
7165     }
7166
7167   /* If we are creating a temporary, we don't need to bother about aliases
7168      anymore.  */
7169   if (need_tmp)
7170     se->force_tmp = 0;
7171
7172   gfc_init_loopinfo (&loop);
7173
7174   /* Associate the SS with the loop.  */
7175   gfc_add_ss_to_loop (&loop, ss);
7176
7177   /* Tell the scalarizer not to bother creating loop variables, etc.  */
7178   if (!need_tmp)
7179     loop.array_parameter = 1;
7180   else
7181     /* The right-hand side of a pointer assignment mustn't use a temporary.  */
7182     gcc_assert (!se->direct_byref);
7183
7184   /* Setup the scalarizing loops and bounds.  */
7185   gfc_conv_ss_startstride (&loop);
7186
7187   if (need_tmp)
7188     {
7189       if (expr->ts.type == BT_CHARACTER && !expr->ts.u.cl->backend_decl)
7190         get_array_charlen (expr, se);
7191
7192       /* Tell the scalarizer to make a temporary.  */
7193       loop.temp_ss = gfc_get_temp_ss (gfc_typenode_for_spec (&expr->ts),
7194                                       ((expr->ts.type == BT_CHARACTER)
7195                                        ? expr->ts.u.cl->backend_decl
7196                                        : NULL),
7197                                       loop.dimen);
7198
7199       se->string_length = loop.temp_ss->info->string_length;
7200       gcc_assert (loop.temp_ss->dimen == loop.dimen);
7201       gfc_add_ss_to_loop (&loop, loop.temp_ss);
7202     }
7203
7204   gfc_conv_loop_setup (&loop, & expr->where);
7205
7206   if (need_tmp)
7207     {
7208       /* Copy into a temporary and pass that.  We don't need to copy the data
7209          back because expressions and vector subscripts must be INTENT_IN.  */
7210       /* TODO: Optimize passing function return values.  */
7211       gfc_se lse;
7212       gfc_se rse;
7213       bool deep_copy;
7214
7215       /* Start the copying loops.  */
7216       gfc_mark_ss_chain_used (loop.temp_ss, 1);
7217       gfc_mark_ss_chain_used (ss, 1);
7218       gfc_start_scalarized_body (&loop, &block);
7219
7220       /* Copy each data element.  */
7221       gfc_init_se (&lse, NULL);
7222       gfc_copy_loopinfo_to_se (&lse, &loop);
7223       gfc_init_se (&rse, NULL);
7224       gfc_copy_loopinfo_to_se (&rse, &loop);
7225
7226       lse.ss = loop.temp_ss;
7227       rse.ss = ss;
7228
7229       gfc_conv_scalarized_array_ref (&lse, NULL);
7230       if (expr->ts.type == BT_CHARACTER)
7231         {
7232           gfc_conv_expr (&rse, expr);
7233           if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
7234             rse.expr = build_fold_indirect_ref_loc (input_location,
7235                                                 rse.expr);
7236         }
7237       else
7238         gfc_conv_expr_val (&rse, expr);
7239
7240       gfc_add_block_to_block (&block, &rse.pre);
7241       gfc_add_block_to_block (&block, &lse.pre);
7242
7243       lse.string_length = rse.string_length;
7244
7245       deep_copy = !se->data_not_needed
7246                   && (expr->expr_type == EXPR_VARIABLE
7247                       || expr->expr_type == EXPR_ARRAY);
7248       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts,
7249                                      deep_copy, false);
7250       gfc_add_expr_to_block (&block, tmp);
7251
7252       /* Finish the copying loops.  */
7253       gfc_trans_scalarizing_loops (&loop, &block);
7254
7255       desc = loop.temp_ss->info->data.array.descriptor;
7256     }
7257   else if (expr->expr_type == EXPR_FUNCTION && !transposed_dims (ss))
7258     {
7259       desc = info->descriptor;
7260       se->string_length = ss_info->string_length;
7261     }
7262   else
7263     {
7264       /* We pass sections without copying to a temporary.  Make a new
7265          descriptor and point it at the section we want.  The loop variable
7266          limits will be the limits of the section.
7267          A function may decide to repack the array to speed up access, but
7268          we're not bothered about that here.  */
7269       int dim, ndim, codim;
7270       tree parm;
7271       tree parmtype;
7272       tree stride;
7273       tree from;
7274       tree to;
7275       tree base;
7276       bool onebased = false, rank_remap;
7277
7278       ndim = info->ref ? info->ref->u.ar.dimen : ss->dimen;
7279       rank_remap = ss->dimen < ndim;
7280
7281       if (se->want_coarray)
7282         {
7283           gfc_array_ref *ar = &info->ref->u.ar;
7284
7285           codim = gfc_get_corank (expr);
7286           for (n = 0; n < codim - 1; n++)
7287             {
7288               /* Make sure we are not lost somehow.  */
7289               gcc_assert (ar->dimen_type[n + ndim] == DIMEN_THIS_IMAGE);
7290
7291               /* Make sure the call to gfc_conv_section_startstride won't
7292                  generate unnecessary code to calculate stride.  */
7293               gcc_assert (ar->stride[n + ndim] == NULL);
7294
7295               gfc_conv_section_startstride (&loop.pre, ss, n + ndim);
7296               loop.from[n + loop.dimen] = info->start[n + ndim];
7297               loop.to[n + loop.dimen]   = info->end[n + ndim];
7298             }
7299
7300           gcc_assert (n == codim - 1);
7301           evaluate_bound (&loop.pre, info->start, ar->start,
7302                           info->descriptor, n + ndim, true,
7303                           ar->as->type == AS_DEFERRED);
7304           loop.from[n + loop.dimen] = info->start[n + ndim];
7305         }
7306       else
7307         codim = 0;
7308
7309       /* Set the string_length for a character array.  */
7310       if (expr->ts.type == BT_CHARACTER)
7311         se->string_length =  gfc_get_expr_charlen (expr);
7312
7313       /* If we have an array section or are assigning make sure that
7314          the lower bound is 1.  References to the full
7315          array should otherwise keep the original bounds.  */
7316       if ((!info->ref || info->ref->u.ar.type != AR_FULL) && !se->want_pointer)
7317         for (dim = 0; dim < loop.dimen; dim++)
7318           if (!integer_onep (loop.from[dim]))
7319             {
7320               tmp = fold_build2_loc (input_location, MINUS_EXPR,
7321                                      gfc_array_index_type, gfc_index_one_node,
7322                                      loop.from[dim]);
7323               loop.to[dim] = fold_build2_loc (input_location, PLUS_EXPR,
7324                                               gfc_array_index_type,
7325                                               loop.to[dim], tmp);
7326               loop.from[dim] = gfc_index_one_node;
7327             }
7328
7329       desc = info->descriptor;
7330       if (se->direct_byref && !se->byref_noassign)
7331         {
7332           /* For pointer assignments we fill in the destination....  */
7333           parm = se->expr;
7334           parmtype = TREE_TYPE (parm);
7335
7336           /* ....and set the span field.  */
7337           tmp = gfc_get_array_span (desc, expr);
7338           gfc_conv_descriptor_span_set (&loop.pre, parm, tmp);
7339         }
7340       else
7341         {
7342           /* Otherwise make a new one.  */
7343           if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
7344             parmtype = gfc_typenode_for_spec (&expr->ts);
7345           else
7346             parmtype = gfc_get_element_type (TREE_TYPE (desc));
7347
7348           parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, codim,
7349                                                 loop.from, loop.to, 0,
7350                                                 GFC_ARRAY_UNKNOWN, false);
7351           parm = gfc_create_var (parmtype, "parm");
7352
7353           /* When expression is a class object, then add the class' handle to
7354              the parm_decl.  */
7355           if (expr->ts.type == BT_CLASS && expr->expr_type == EXPR_VARIABLE)
7356             {
7357               gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (expr);
7358               gfc_se classse;
7359
7360               /* class_expr can be NULL, when no _class ref is in expr.
7361                  We must not fix this here with a gfc_fix_class_ref ().  */
7362               if (class_expr)
7363                 {
7364                   gfc_init_se (&classse, NULL);
7365                   gfc_conv_expr (&classse, class_expr);
7366                   gfc_free_expr (class_expr);
7367
7368                   gcc_assert (classse.pre.head == NULL_TREE
7369                               && classse.post.head == NULL_TREE);
7370                   gfc_allocate_lang_decl (parm);
7371                   GFC_DECL_SAVED_DESCRIPTOR (parm) = classse.expr;
7372                 }
7373             }
7374         }
7375
7376       offset = gfc_index_zero_node;
7377
7378       /* The following can be somewhat confusing.  We have two
7379          descriptors, a new one and the original array.
7380          {parm, parmtype, dim} refer to the new one.
7381          {desc, type, n, loop} refer to the original, which maybe
7382          a descriptorless array.
7383          The bounds of the scalarization are the bounds of the section.
7384          We don't have to worry about numeric overflows when calculating
7385          the offsets because all elements are within the array data.  */
7386
7387       /* Set the dtype.  */
7388       tmp = gfc_conv_descriptor_dtype (parm);
7389       gfc_add_modify (&loop.pre, tmp, gfc_get_dtype (parmtype));
7390
7391       /* Set offset for assignments to pointer only to zero if it is not
7392          the full array.  */
7393       if ((se->direct_byref || se->use_offset)
7394           && ((info->ref && info->ref->u.ar.type != AR_FULL)
7395               || (expr->expr_type == EXPR_ARRAY && se->use_offset)))
7396         base = gfc_index_zero_node;
7397       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
7398         base = gfc_evaluate_now (gfc_conv_array_offset (desc), &loop.pre);
7399       else
7400         base = NULL_TREE;
7401
7402       for (n = 0; n < ndim; n++)
7403         {
7404           stride = gfc_conv_array_stride (desc, n);
7405
7406           /* Work out the offset.  */
7407           if (info->ref
7408               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
7409             {
7410               gcc_assert (info->subscript[n]
7411                           && info->subscript[n]->info->type == GFC_SS_SCALAR);
7412               start = info->subscript[n]->info->data.scalar.value;
7413             }
7414           else
7415             {
7416               /* Evaluate and remember the start of the section.  */
7417               start = info->start[n];
7418               stride = gfc_evaluate_now (stride, &loop.pre);
7419             }
7420
7421           tmp = gfc_conv_array_lbound (desc, n);
7422           tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp),
7423                                  start, tmp);
7424           tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
7425                                  tmp, stride);
7426           offset = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
7427                                     offset, tmp);
7428
7429           if (info->ref
7430               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
7431             {
7432               /* For elemental dimensions, we only need the offset.  */
7433               continue;
7434             }
7435
7436           /* Vector subscripts need copying and are handled elsewhere.  */
7437           if (info->ref)
7438             gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
7439
7440           /* look for the corresponding scalarizer dimension: dim.  */
7441           for (dim = 0; dim < ndim; dim++)
7442             if (ss->dim[dim] == n)
7443               break;
7444
7445           /* loop exited early: the DIM being looked for has been found.  */
7446           gcc_assert (dim < ndim);
7447
7448           /* Set the new lower bound.  */
7449           from = loop.from[dim];
7450           to = loop.to[dim];
7451
7452           onebased = integer_onep (from);
7453           gfc_conv_descriptor_lbound_set (&loop.pre, parm,
7454                                           gfc_rank_cst[dim], from);
7455
7456           /* Set the new upper bound.  */
7457           gfc_conv_descriptor_ubound_set (&loop.pre, parm,
7458                                           gfc_rank_cst[dim], to);
7459
7460           /* Multiply the stride by the section stride to get the
7461              total stride.  */
7462           stride = fold_build2_loc (input_location, MULT_EXPR,
7463                                     gfc_array_index_type,
7464                                     stride, info->stride[n]);
7465
7466           if ((se->direct_byref || se->use_offset)
7467               && ((info->ref && info->ref->u.ar.type != AR_FULL)
7468                   || (expr->expr_type == EXPR_ARRAY && se->use_offset)))
7469             {
7470               base = fold_build2_loc (input_location, MINUS_EXPR,
7471                                       TREE_TYPE (base), base, stride);
7472             }
7473           else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)) || se->use_offset)
7474             {
7475               bool toonebased;
7476               tmp = gfc_conv_array_lbound (desc, n);
7477               toonebased = integer_onep (tmp);
7478               // lb(arr) - from (- start + 1)
7479               tmp = fold_build2_loc (input_location, MINUS_EXPR,
7480                                      TREE_TYPE (base), tmp, from);
7481               if (onebased && toonebased)
7482                 {
7483                   tmp = fold_build2_loc (input_location, MINUS_EXPR,
7484                                          TREE_TYPE (base), tmp, start);
7485                   tmp = fold_build2_loc (input_location, PLUS_EXPR,
7486                                          TREE_TYPE (base), tmp,
7487                                          gfc_index_one_node);
7488                 }
7489               tmp = fold_build2_loc (input_location, MULT_EXPR,
7490                                      TREE_TYPE (base), tmp,
7491                                      gfc_conv_array_stride (desc, n));
7492               base = fold_build2_loc (input_location, PLUS_EXPR,
7493                                      TREE_TYPE (base), tmp, base);
7494             }
7495
7496           /* Store the new stride.  */
7497           gfc_conv_descriptor_stride_set (&loop.pre, parm,
7498                                           gfc_rank_cst[dim], stride);
7499         }
7500
7501       for (n = loop.dimen; n < loop.dimen + codim; n++)
7502         {
7503           from = loop.from[n];
7504           to = loop.to[n];
7505           gfc_conv_descriptor_lbound_set (&loop.pre, parm,
7506                                           gfc_rank_cst[n], from);
7507           if (n < loop.dimen + codim - 1)
7508             gfc_conv_descriptor_ubound_set (&loop.pre, parm,
7509                                             gfc_rank_cst[n], to);
7510         }
7511
7512       if (se->data_not_needed)
7513         gfc_conv_descriptor_data_set (&loop.pre, parm,
7514                                       gfc_index_zero_node);
7515       else
7516         /* Point the data pointer at the 1st element in the section.  */
7517         gfc_get_dataptr_offset (&loop.pre, parm, desc, offset,
7518                                 subref_array_target, expr);
7519
7520       /* Force the offset to be -1, when the lower bound of the highest
7521          dimension is one and the symbol is present and is not a
7522          pointer/allocatable or associated.  */
7523       if (((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
7524            && !se->data_not_needed)
7525           || (se->use_offset && base != NULL_TREE))
7526         {
7527           /* Set the offset depending on base.  */
7528           tmp = rank_remap && !se->direct_byref ?
7529                 fold_build2_loc (input_location, PLUS_EXPR,
7530                                  gfc_array_index_type, base,
7531                                  offset)
7532               : base;
7533           gfc_conv_descriptor_offset_set (&loop.pre, parm, tmp);
7534         }
7535       else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))
7536                && !se->data_not_needed
7537                && (!rank_remap || se->use_offset))
7538         {
7539           gfc_conv_descriptor_offset_set (&loop.pre, parm,
7540                                          gfc_conv_descriptor_offset_get (desc));
7541         }
7542       else if (onebased && (!rank_remap || se->use_offset)
7543           && expr->symtree
7544           && !(expr->symtree->n.sym && expr->symtree->n.sym->ts.type == BT_CLASS
7545                && !CLASS_DATA (expr->symtree->n.sym)->attr.class_pointer)
7546           && !expr->symtree->n.sym->attr.allocatable
7547           && !expr->symtree->n.sym->attr.pointer
7548           && !expr->symtree->n.sym->attr.host_assoc
7549           && !expr->symtree->n.sym->attr.use_assoc)
7550         {
7551           /* Set the offset to -1.  */
7552           mpz_t minus_one;
7553           mpz_init_set_si (minus_one, -1);
7554           tmp = gfc_conv_mpz_to_tree (minus_one, gfc_index_integer_kind);
7555           gfc_conv_descriptor_offset_set (&loop.pre, parm, tmp);
7556         }
7557       else
7558         {
7559           /* Only the callee knows what the correct offset it, so just set
7560              it to zero here.  */
7561           gfc_conv_descriptor_offset_set (&loop.pre, parm, gfc_index_zero_node);
7562         }
7563       desc = parm;
7564     }
7565
7566   /* For class arrays add the class tree into the saved descriptor to
7567      enable getting of _vptr and the like.  */
7568   if (expr->expr_type == EXPR_VARIABLE && VAR_P (desc)
7569       && IS_CLASS_ARRAY (expr->symtree->n.sym))
7570     {
7571       gfc_allocate_lang_decl (desc);
7572       GFC_DECL_SAVED_DESCRIPTOR (desc) =
7573           DECL_LANG_SPECIFIC (expr->symtree->n.sym->backend_decl) ?
7574             GFC_DECL_SAVED_DESCRIPTOR (expr->symtree->n.sym->backend_decl)
7575           : expr->symtree->n.sym->backend_decl;
7576     }
7577   else if (expr->expr_type == EXPR_ARRAY && VAR_P (desc)
7578            && IS_CLASS_ARRAY (expr))
7579     {
7580       tree vtype;
7581       gfc_allocate_lang_decl (desc);
7582       tmp = gfc_create_var (expr->ts.u.derived->backend_decl, "class");
7583       GFC_DECL_SAVED_DESCRIPTOR (desc) = tmp;
7584       vtype = gfc_class_vptr_get (tmp);
7585       gfc_add_modify (&se->pre, vtype,
7586                       gfc_build_addr_expr (TREE_TYPE (vtype),
7587                                       gfc_find_vtab (&expr->ts)->backend_decl));
7588     }
7589   if (!se->direct_byref || se->byref_noassign)
7590     {
7591       /* Get a pointer to the new descriptor.  */
7592       if (se->want_pointer)
7593         se->expr = gfc_build_addr_expr (NULL_TREE, desc);
7594       else
7595         se->expr = desc;
7596     }
7597
7598   gfc_add_block_to_block (&se->pre, &loop.pre);
7599   gfc_add_block_to_block (&se->post, &loop.post);
7600
7601   /* Cleanup the scalarizer.  */
7602   gfc_cleanup_loop (&loop);
7603 }
7604
7605 /* Helper function for gfc_conv_array_parameter if array size needs to be
7606    computed.  */
7607
7608 static void
7609 array_parameter_size (tree desc, gfc_expr *expr, tree *size)
7610 {
7611   tree elem;
7612   if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
7613     *size = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (desc));
7614   else if (expr->rank > 1)
7615     *size = build_call_expr_loc (input_location,
7616                              gfor_fndecl_size0, 1,
7617                              gfc_build_addr_expr (NULL, desc));
7618   else
7619     {
7620       tree ubound = gfc_conv_descriptor_ubound_get (desc, gfc_index_zero_node);
7621       tree lbound = gfc_conv_descriptor_lbound_get (desc, gfc_index_zero_node);
7622
7623       *size = fold_build2_loc (input_location, MINUS_EXPR,
7624                                gfc_array_index_type, ubound, lbound);
7625       *size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
7626                                *size, gfc_index_one_node);
7627       *size = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
7628                                *size, gfc_index_zero_node);
7629     }
7630   elem = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
7631   *size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7632                            *size, fold_convert (gfc_array_index_type, elem));
7633 }
7634
7635 /* Convert an array for passing as an actual parameter.  */
7636 /* TODO: Optimize passing g77 arrays.  */
7637
7638 void
7639 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, bool g77,
7640                           const gfc_symbol *fsym, const char *proc_name,
7641                           tree *size)
7642 {
7643   tree ptr;
7644   tree desc;
7645   tree tmp = NULL_TREE;
7646   tree stmt;
7647   tree parent = DECL_CONTEXT (current_function_decl);
7648   bool full_array_var;
7649   bool this_array_result;
7650   bool contiguous;
7651   bool no_pack;
7652   bool array_constructor;
7653   bool good_allocatable;
7654   bool ultimate_ptr_comp;
7655   bool ultimate_alloc_comp;
7656   gfc_symbol *sym;
7657   stmtblock_t block;
7658   gfc_ref *ref;
7659
7660   ultimate_ptr_comp = false;
7661   ultimate_alloc_comp = false;
7662
7663   for (ref = expr->ref; ref; ref = ref->next)
7664     {
7665       if (ref->next == NULL)
7666         break;
7667
7668       if (ref->type == REF_COMPONENT)
7669         {
7670           ultimate_ptr_comp = ref->u.c.component->attr.pointer;
7671           ultimate_alloc_comp = ref->u.c.component->attr.allocatable;
7672         }
7673     }
7674
7675   full_array_var = false;
7676   contiguous = false;
7677
7678   if (expr->expr_type == EXPR_VARIABLE && ref && !ultimate_ptr_comp)
7679     full_array_var = gfc_full_array_ref_p (ref, &contiguous);
7680
7681   sym = full_array_var ? expr->symtree->n.sym : NULL;
7682
7683   /* The symbol should have an array specification.  */
7684   gcc_assert (!sym || sym->as || ref->u.ar.as);
7685
7686   if (expr->expr_type == EXPR_ARRAY && expr->ts.type == BT_CHARACTER)
7687     {
7688       get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp);
7689       expr->ts.u.cl->backend_decl = tmp;
7690       se->string_length = tmp;
7691     }
7692
7693   /* Is this the result of the enclosing procedure?  */
7694   this_array_result = (full_array_var && sym->attr.flavor == FL_PROCEDURE);
7695   if (this_array_result
7696         && (sym->backend_decl != current_function_decl)
7697         && (sym->backend_decl != parent))
7698     this_array_result = false;
7699
7700   /* Passing address of the array if it is not pointer or assumed-shape.  */
7701   if (full_array_var && g77 && !this_array_result
7702       && sym->ts.type != BT_DERIVED && sym->ts.type != BT_CLASS)
7703     {
7704       tmp = gfc_get_symbol_decl (sym);
7705
7706       if (sym->ts.type == BT_CHARACTER)
7707         se->string_length = sym->ts.u.cl->backend_decl;
7708
7709       if (!sym->attr.pointer
7710           && sym->as
7711           && sym->as->type != AS_ASSUMED_SHAPE
7712           && sym->as->type != AS_DEFERRED
7713           && sym->as->type != AS_ASSUMED_RANK
7714           && !sym->attr.allocatable)
7715         {
7716           /* Some variables are declared directly, others are declared as
7717              pointers and allocated on the heap.  */
7718           if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
7719             se->expr = tmp;
7720           else
7721             se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
7722           if (size)
7723             array_parameter_size (tmp, expr, size);
7724           return;
7725         }
7726
7727       if (sym->attr.allocatable)
7728         {
7729           if (sym->attr.dummy || sym->attr.result)
7730             {
7731               gfc_conv_expr_descriptor (se, expr);
7732               tmp = se->expr;
7733             }
7734           if (size)
7735             array_parameter_size (tmp, expr, size);
7736           se->expr = gfc_conv_array_data (tmp);
7737           return;
7738         }
7739     }
7740
7741   /* A convenient reduction in scope.  */
7742   contiguous = g77 && !this_array_result && contiguous;
7743
7744   /* There is no need to pack and unpack the array, if it is contiguous
7745      and not a deferred- or assumed-shape array, or if it is simply
7746      contiguous.  */
7747   no_pack = ((sym && sym->as
7748                   && !sym->attr.pointer
7749                   && sym->as->type != AS_DEFERRED
7750                   && sym->as->type != AS_ASSUMED_RANK
7751                   && sym->as->type != AS_ASSUMED_SHAPE)
7752                       ||
7753              (ref && ref->u.ar.as
7754                   && ref->u.ar.as->type != AS_DEFERRED
7755                   && ref->u.ar.as->type != AS_ASSUMED_RANK
7756                   && ref->u.ar.as->type != AS_ASSUMED_SHAPE)
7757                       ||
7758              gfc_is_simply_contiguous (expr, false, true));
7759
7760   no_pack = contiguous && no_pack;
7761
7762   /* Array constructors are always contiguous and do not need packing.  */
7763   array_constructor = g77 && !this_array_result && expr->expr_type == EXPR_ARRAY;
7764
7765   /* Same is true of contiguous sections from allocatable variables.  */
7766   good_allocatable = contiguous
7767                        && expr->symtree
7768                        && expr->symtree->n.sym->attr.allocatable;
7769
7770   /* Or ultimate allocatable components.  */
7771   ultimate_alloc_comp = contiguous && ultimate_alloc_comp;
7772
7773   if (no_pack || array_constructor || good_allocatable || ultimate_alloc_comp)
7774     {
7775       gfc_conv_expr_descriptor (se, expr);
7776       /* Deallocate the allocatable components of structures that are
7777          not variable.  */
7778       if ((expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS)
7779            && expr->ts.u.derived->attr.alloc_comp
7780            && expr->expr_type != EXPR_VARIABLE)
7781         {
7782           tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, se->expr, expr->rank);
7783
7784           /* The components shall be deallocated before their containing entity.  */
7785           gfc_prepend_expr_to_block (&se->post, tmp);
7786         }
7787       if (expr->ts.type == BT_CHARACTER)
7788         se->string_length = expr->ts.u.cl->backend_decl;
7789       if (size)
7790         array_parameter_size (se->expr, expr, size);
7791       se->expr = gfc_conv_array_data (se->expr);
7792       return;
7793     }
7794
7795   if (this_array_result)
7796     {
7797       /* Result of the enclosing function.  */
7798       gfc_conv_expr_descriptor (se, expr);
7799       if (size)
7800         array_parameter_size (se->expr, expr, size);
7801       se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
7802
7803       if (g77 && TREE_TYPE (TREE_TYPE (se->expr)) != NULL_TREE
7804               && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
7805         se->expr = gfc_conv_array_data (build_fold_indirect_ref_loc (input_location,
7806                                                                  se->expr));
7807
7808       return;
7809     }
7810   else
7811     {
7812       /* Every other type of array.  */
7813       se->want_pointer = 1;
7814       gfc_conv_expr_descriptor (se, expr);
7815
7816       if (size)
7817         array_parameter_size (build_fold_indirect_ref_loc (input_location,
7818                                                        se->expr),
7819                                   expr, size);
7820     }
7821
7822   /* Deallocate the allocatable components of structures that are
7823      not variable, for descriptorless arguments.
7824      Arguments with a descriptor are handled in gfc_conv_procedure_call.  */
7825   if (g77 && (expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS)
7826           && expr->ts.u.derived->attr.alloc_comp
7827           && expr->expr_type != EXPR_VARIABLE)
7828     {
7829       tmp = build_fold_indirect_ref_loc (input_location, se->expr);
7830       tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp, expr->rank);
7831
7832       /* The components shall be deallocated before their containing entity.  */
7833       gfc_prepend_expr_to_block (&se->post, tmp);
7834     }
7835
7836   if (g77 || (fsym && fsym->attr.contiguous
7837               && !gfc_is_simply_contiguous (expr, false, true)))
7838     {
7839       tree origptr = NULL_TREE;
7840
7841       desc = se->expr;
7842
7843       /* For contiguous arrays, save the original value of the descriptor.  */
7844       if (!g77)
7845         {
7846           origptr = gfc_create_var (pvoid_type_node, "origptr");
7847           tmp = build_fold_indirect_ref_loc (input_location, desc);
7848           tmp = gfc_conv_array_data (tmp);
7849           tmp = fold_build2_loc (input_location, MODIFY_EXPR,
7850                                  TREE_TYPE (origptr), origptr,
7851                                  fold_convert (TREE_TYPE (origptr), tmp));
7852           gfc_add_expr_to_block (&se->pre, tmp);
7853         }
7854
7855       /* Repack the array.  */
7856       if (warn_array_temporaries)
7857         {
7858           if (fsym)
7859             gfc_warning (OPT_Warray_temporaries,
7860                          "Creating array temporary at %L for argument %qs",
7861                          &expr->where, fsym->name);
7862           else
7863             gfc_warning (OPT_Warray_temporaries,
7864                          "Creating array temporary at %L", &expr->where);
7865         }
7866
7867       ptr = build_call_expr_loc (input_location,
7868                              gfor_fndecl_in_pack, 1, desc);
7869
7870       if (fsym && fsym->attr.optional && sym && sym->attr.optional)
7871         {
7872           tmp = gfc_conv_expr_present (sym);
7873           ptr = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
7874                         tmp, fold_convert (TREE_TYPE (se->expr), ptr),
7875                         fold_convert (TREE_TYPE (se->expr), null_pointer_node));
7876         }
7877
7878       ptr = gfc_evaluate_now (ptr, &se->pre);
7879
7880       /* Use the packed data for the actual argument, except for contiguous arrays,
7881          where the descriptor's data component is set.  */
7882       if (g77)
7883         se->expr = ptr;
7884       else
7885         {
7886           tmp = build_fold_indirect_ref_loc (input_location, desc);
7887
7888           gfc_ss * ss = gfc_walk_expr (expr);
7889           if (!transposed_dims (ss))
7890             gfc_conv_descriptor_data_set (&se->pre, tmp, ptr);
7891           else
7892             {
7893               tree old_field, new_field;
7894
7895               /* The original descriptor has transposed dims so we can't reuse
7896                  it directly; we have to create a new one.  */
7897               tree old_desc = tmp;
7898               tree new_desc = gfc_create_var (TREE_TYPE (old_desc), "arg_desc");
7899
7900               old_field = gfc_conv_descriptor_dtype (old_desc);
7901               new_field = gfc_conv_descriptor_dtype (new_desc);
7902               gfc_add_modify (&se->pre, new_field, old_field);
7903
7904               old_field = gfc_conv_descriptor_offset (old_desc);
7905               new_field = gfc_conv_descriptor_offset (new_desc);
7906               gfc_add_modify (&se->pre, new_field, old_field);
7907
7908               for (int i = 0; i < expr->rank; i++)
7909                 {
7910                   old_field = gfc_conv_descriptor_dimension (old_desc,
7911                         gfc_rank_cst[get_array_ref_dim_for_loop_dim (ss, i)]);
7912                   new_field = gfc_conv_descriptor_dimension (new_desc,
7913                         gfc_rank_cst[i]);
7914                   gfc_add_modify (&se->pre, new_field, old_field);
7915                 }
7916
7917               if (flag_coarray == GFC_FCOARRAY_LIB
7918                   && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (old_desc))
7919                   && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (old_desc))
7920                      == GFC_ARRAY_ALLOCATABLE)
7921                 {
7922                   old_field = gfc_conv_descriptor_token (old_desc);
7923                   new_field = gfc_conv_descriptor_token (new_desc);
7924                   gfc_add_modify (&se->pre, new_field, old_field);
7925                 }
7926
7927               gfc_conv_descriptor_data_set (&se->pre, new_desc, ptr);
7928               se->expr = gfc_build_addr_expr (NULL_TREE, new_desc);
7929             }
7930           gfc_free_ss (ss);
7931         }
7932
7933       if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
7934         {
7935           char * msg;
7936
7937           if (fsym && proc_name)
7938             msg = xasprintf ("An array temporary was created for argument "
7939                              "'%s' of procedure '%s'", fsym->name, proc_name);
7940           else
7941             msg = xasprintf ("An array temporary was created");
7942
7943           tmp = build_fold_indirect_ref_loc (input_location,
7944                                          desc);
7945           tmp = gfc_conv_array_data (tmp);
7946           tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
7947                                  fold_convert (TREE_TYPE (tmp), ptr), tmp);
7948
7949           if (fsym && fsym->attr.optional && sym && sym->attr.optional)
7950             tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
7951                                    logical_type_node,
7952                                    gfc_conv_expr_present (sym), tmp);
7953
7954           gfc_trans_runtime_check (false, true, tmp, &se->pre,
7955                                    &expr->where, msg);
7956           free (msg);
7957         }
7958
7959       gfc_start_block (&block);
7960
7961       /* Copy the data back.  */
7962       if (fsym == NULL || fsym->attr.intent != INTENT_IN)
7963         {
7964           tmp = build_call_expr_loc (input_location,
7965                                  gfor_fndecl_in_unpack, 2, desc, ptr);
7966           gfc_add_expr_to_block (&block, tmp);
7967         }
7968
7969       /* Free the temporary.  */
7970       tmp = gfc_call_free (ptr);
7971       gfc_add_expr_to_block (&block, tmp);
7972
7973       stmt = gfc_finish_block (&block);
7974
7975       gfc_init_block (&block);
7976       /* Only if it was repacked.  This code needs to be executed before the
7977          loop cleanup code.  */
7978       tmp = build_fold_indirect_ref_loc (input_location,
7979                                      desc);
7980       tmp = gfc_conv_array_data (tmp);
7981       tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
7982                              fold_convert (TREE_TYPE (tmp), ptr), tmp);
7983
7984       if (fsym && fsym->attr.optional && sym && sym->attr.optional)
7985         tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
7986                                logical_type_node,
7987                                gfc_conv_expr_present (sym), tmp);
7988
7989       tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
7990
7991       gfc_add_expr_to_block (&block, tmp);
7992       gfc_add_block_to_block (&block, &se->post);
7993
7994       gfc_init_block (&se->post);
7995
7996       /* Reset the descriptor pointer.  */
7997       if (!g77)
7998         {
7999           tmp = build_fold_indirect_ref_loc (input_location, desc);
8000           gfc_conv_descriptor_data_set (&se->post, tmp, origptr);
8001         }
8002
8003       gfc_add_block_to_block (&se->post, &block);
8004     }
8005 }
8006
8007
8008 /* This helper function calculates the size in words of a full array.  */
8009
8010 tree
8011 gfc_full_array_size (stmtblock_t *block, tree decl, int rank)
8012 {
8013   tree idx;
8014   tree nelems;
8015   tree tmp;
8016   idx = gfc_rank_cst[rank - 1];
8017   nelems = gfc_conv_descriptor_ubound_get (decl, idx);
8018   tmp = gfc_conv_descriptor_lbound_get (decl, idx);
8019   tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8020                          nelems, tmp);
8021   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
8022                          tmp, gfc_index_one_node);
8023   tmp = gfc_evaluate_now (tmp, block);
8024
8025   nelems = gfc_conv_descriptor_stride_get (decl, idx);
8026   tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
8027                          nelems, tmp);
8028   return gfc_evaluate_now (tmp, block);
8029 }
8030
8031
8032 /* Allocate dest to the same size as src, and copy src -> dest.
8033    If no_malloc is set, only the copy is done.  */
8034
8035 static tree
8036 duplicate_allocatable (tree dest, tree src, tree type, int rank,
8037                        bool no_malloc, bool no_memcpy, tree str_sz,
8038                        tree add_when_allocated)
8039 {
8040   tree tmp;
8041   tree size;
8042   tree nelems;
8043   tree null_cond;
8044   tree null_data;
8045   stmtblock_t block;
8046
8047   /* If the source is null, set the destination to null.  Then,
8048      allocate memory to the destination.  */
8049   gfc_init_block (&block);
8050
8051   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest)))
8052     {
8053       gfc_add_modify (&block, dest, fold_convert (type, null_pointer_node));
8054       null_data = gfc_finish_block (&block);
8055
8056       gfc_init_block (&block);
8057       if (str_sz != NULL_TREE)
8058         size = str_sz;
8059       else
8060         size = TYPE_SIZE_UNIT (TREE_TYPE (type));
8061
8062       if (!no_malloc)
8063         {
8064           tmp = gfc_call_malloc (&block, type, size);
8065           gfc_add_modify (&block, dest, fold_convert (type, tmp));
8066         }
8067
8068       if (!no_memcpy)
8069         {
8070           tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
8071           tmp = build_call_expr_loc (input_location, tmp, 3, dest, src,
8072                                      fold_convert (size_type_node, size));
8073           gfc_add_expr_to_block (&block, tmp);
8074         }
8075     }
8076   else
8077     {
8078       gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8079       null_data = gfc_finish_block (&block);
8080
8081       gfc_init_block (&block);
8082       if (rank)
8083         nelems = gfc_full_array_size (&block, src, rank);
8084       else
8085         nelems = gfc_index_one_node;
8086
8087       if (str_sz != NULL_TREE)
8088         tmp = fold_convert (gfc_array_index_type, str_sz);
8089       else
8090         tmp = fold_convert (gfc_array_index_type,
8091                             TYPE_SIZE_UNIT (gfc_get_element_type (type)));
8092       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
8093                               nelems, tmp);
8094       if (!no_malloc)
8095         {
8096           tmp = TREE_TYPE (gfc_conv_descriptor_data_get (src));
8097           tmp = gfc_call_malloc (&block, tmp, size);
8098           gfc_conv_descriptor_data_set (&block, dest, tmp);
8099         }
8100
8101       /* We know the temporary and the value will be the same length,
8102          so can use memcpy.  */
8103       if (!no_memcpy)
8104         {
8105           tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
8106           tmp = build_call_expr_loc (input_location, tmp, 3,
8107                                      gfc_conv_descriptor_data_get (dest),
8108                                      gfc_conv_descriptor_data_get (src),
8109                                      fold_convert (size_type_node, size));
8110           gfc_add_expr_to_block (&block, tmp);
8111         }
8112     }
8113
8114   gfc_add_expr_to_block (&block, add_when_allocated);
8115   tmp = gfc_finish_block (&block);
8116
8117   /* Null the destination if the source is null; otherwise do
8118      the allocate and copy.  */
8119   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (src)))
8120     null_cond = src;
8121   else
8122     null_cond = gfc_conv_descriptor_data_get (src);
8123
8124   null_cond = convert (pvoid_type_node, null_cond);
8125   null_cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
8126                                null_cond, null_pointer_node);
8127   return build3_v (COND_EXPR, null_cond, tmp, null_data);
8128 }
8129
8130
8131 /* Allocate dest to the same size as src, and copy data src -> dest.  */
8132
8133 tree
8134 gfc_duplicate_allocatable (tree dest, tree src, tree type, int rank,
8135                            tree add_when_allocated)
8136 {
8137   return duplicate_allocatable (dest, src, type, rank, false, false,
8138                                 NULL_TREE, add_when_allocated);
8139 }
8140
8141
8142 /* Copy data src -> dest.  */
8143
8144 tree
8145 gfc_copy_allocatable_data (tree dest, tree src, tree type, int rank)
8146 {
8147   return duplicate_allocatable (dest, src, type, rank, true, false,
8148                                 NULL_TREE, NULL_TREE);
8149 }
8150
8151 /* Allocate dest to the same size as src, but don't copy anything.  */
8152
8153 tree
8154 gfc_duplicate_allocatable_nocopy (tree dest, tree src, tree type, int rank)
8155 {
8156   return duplicate_allocatable (dest, src, type, rank, false, true,
8157                                 NULL_TREE, NULL_TREE);
8158 }
8159
8160
8161 static tree
8162 duplicate_allocatable_coarray (tree dest, tree dest_tok, tree src,
8163                                tree type, int rank)
8164 {
8165   tree tmp;
8166   tree size;
8167   tree nelems;
8168   tree null_cond;
8169   tree null_data;
8170   stmtblock_t block, globalblock;
8171
8172   /* If the source is null, set the destination to null.  Then,
8173      allocate memory to the destination.  */
8174   gfc_init_block (&block);
8175   gfc_init_block (&globalblock);
8176
8177   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest)))
8178     {
8179       gfc_se se;
8180       symbol_attribute attr;
8181       tree dummy_desc;
8182
8183       gfc_init_se (&se, NULL);
8184       gfc_clear_attr (&attr);
8185       attr.allocatable = 1;
8186       dummy_desc = gfc_conv_scalar_to_descriptor (&se, dest, attr);
8187       gfc_add_block_to_block (&globalblock, &se.pre);
8188       size = TYPE_SIZE_UNIT (TREE_TYPE (type));
8189
8190       gfc_add_modify (&block, dest, fold_convert (type, null_pointer_node));
8191       gfc_allocate_using_caf_lib (&block, dummy_desc, size,
8192                                   gfc_build_addr_expr (NULL_TREE, dest_tok),
8193                                   NULL_TREE, NULL_TREE, NULL_TREE,
8194                                   GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY);
8195       null_data = gfc_finish_block (&block);
8196
8197       gfc_init_block (&block);
8198
8199       gfc_allocate_using_caf_lib (&block, dummy_desc,
8200                                   fold_convert (size_type_node, size),
8201                                   gfc_build_addr_expr (NULL_TREE, dest_tok),
8202                                   NULL_TREE, NULL_TREE, NULL_TREE,
8203                                   GFC_CAF_COARRAY_ALLOC);
8204
8205       tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
8206       tmp = build_call_expr_loc (input_location, tmp, 3, dest, src,
8207                                  fold_convert (size_type_node, size));
8208       gfc_add_expr_to_block (&block, tmp);
8209     }
8210   else
8211     {
8212       /* Set the rank or unitialized memory access may be reported.  */
8213       tmp = gfc_conv_descriptor_rank (dest);
8214       gfc_add_modify (&globalblock, tmp, build_int_cst (TREE_TYPE (tmp), rank));
8215
8216       if (rank)
8217         nelems = gfc_full_array_size (&block, src, rank);
8218       else
8219         nelems = integer_one_node;
8220
8221       tmp = fold_convert (size_type_node,
8222                           TYPE_SIZE_UNIT (gfc_get_element_type (type)));
8223       size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
8224                               fold_convert (size_type_node, nelems), tmp);
8225
8226       gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8227       gfc_allocate_using_caf_lib (&block, dest, fold_convert (size_type_node,
8228                                                               size),
8229                                   gfc_build_addr_expr (NULL_TREE, dest_tok),
8230                                   NULL_TREE, NULL_TREE, NULL_TREE,
8231                                   GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY);
8232       null_data = gfc_finish_block (&block);
8233
8234       gfc_init_block (&block);
8235       gfc_allocate_using_caf_lib (&block, dest,
8236                                   fold_convert (size_type_node, size),
8237                                   gfc_build_addr_expr (NULL_TREE, dest_tok),
8238                                   NULL_TREE, NULL_TREE, NULL_TREE,
8239                                   GFC_CAF_COARRAY_ALLOC);
8240
8241       tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
8242       tmp = build_call_expr_loc (input_location, tmp, 3,
8243                                  gfc_conv_descriptor_data_get (dest),
8244                                  gfc_conv_descriptor_data_get (src),
8245                                  fold_convert (size_type_node, size));
8246       gfc_add_expr_to_block (&block, tmp);
8247     }
8248
8249   tmp = gfc_finish_block (&block);
8250
8251   /* Null the destination if the source is null; otherwise do
8252      the register and copy.  */
8253   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (src)))
8254     null_cond = src;
8255   else
8256     null_cond = gfc_conv_descriptor_data_get (src);
8257
8258   null_cond = convert (pvoid_type_node, null_cond);
8259   null_cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
8260                                null_cond, null_pointer_node);
8261   gfc_add_expr_to_block (&globalblock, build3_v (COND_EXPR, null_cond, tmp,
8262                                                  null_data));
8263   return gfc_finish_block (&globalblock);
8264 }
8265
8266
8267 /* Helper function to abstract whether coarray processing is enabled.  */
8268
8269 static bool
8270 caf_enabled (int caf_mode)
8271 {
8272   return (caf_mode & GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY)
8273       == GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY;
8274 }
8275
8276
8277 /* Helper function to abstract whether coarray processing is enabled
8278    and we are in a derived type coarray.  */
8279
8280 static bool
8281 caf_in_coarray (int caf_mode)
8282 {
8283   static const int pat = GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
8284                          | GFC_STRUCTURE_CAF_MODE_IN_COARRAY;
8285   return (caf_mode & pat) == pat;
8286 }
8287
8288
8289 /* Helper function to abstract whether coarray is to deallocate only.  */
8290
8291 bool
8292 gfc_caf_is_dealloc_only (int caf_mode)
8293 {
8294   return (caf_mode & GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY)
8295       == GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY;
8296 }
8297
8298
8299 /* Recursively traverse an object of derived type, generating code to
8300    deallocate, nullify or copy allocatable components.  This is the work horse
8301    function for the functions named in this enum.  */
8302
8303 enum {DEALLOCATE_ALLOC_COMP = 1, NULLIFY_ALLOC_COMP,
8304       COPY_ALLOC_COMP, COPY_ONLY_ALLOC_COMP, REASSIGN_CAF_COMP,
8305       ALLOCATE_PDT_COMP, DEALLOCATE_PDT_COMP, CHECK_PDT_DUMMY};
8306
8307 static gfc_actual_arglist *pdt_param_list;
8308
8309 static tree
8310 structure_alloc_comps (gfc_symbol * der_type, tree decl,
8311                        tree dest, int rank, int purpose, int caf_mode)
8312 {
8313   gfc_component *c;
8314   gfc_loopinfo loop;
8315   stmtblock_t fnblock;
8316   stmtblock_t loopbody;
8317   stmtblock_t tmpblock;
8318   tree decl_type;
8319   tree tmp;
8320   tree comp;
8321   tree dcmp;
8322   tree nelems;
8323   tree index;
8324   tree var;
8325   tree cdecl;
8326   tree ctype;
8327   tree vref, dref;
8328   tree null_cond = NULL_TREE;
8329   tree add_when_allocated;
8330   tree dealloc_fndecl;
8331   tree caf_token;
8332   gfc_symbol *vtab;
8333   int caf_dereg_mode;
8334   symbol_attribute *attr;
8335   bool deallocate_called;
8336
8337   gfc_init_block (&fnblock);
8338
8339   decl_type = TREE_TYPE (decl);
8340
8341   if ((POINTER_TYPE_P (decl_type))
8342         || (TREE_CODE (decl_type) == REFERENCE_TYPE && rank == 0))
8343     {
8344       decl = build_fold_indirect_ref_loc (input_location, decl);
8345       /* Deref dest in sync with decl, but only when it is not NULL.  */
8346       if (dest)
8347         dest = build_fold_indirect_ref_loc (input_location, dest);
8348
8349       /* Update the decl_type because it got dereferenced.  */
8350       decl_type = TREE_TYPE (decl);
8351     }
8352
8353   /* If this is an array of derived types with allocatable components
8354      build a loop and recursively call this function.  */
8355   if (TREE_CODE (decl_type) == ARRAY_TYPE
8356       || (GFC_DESCRIPTOR_TYPE_P (decl_type) && rank != 0))
8357     {
8358       tmp = gfc_conv_array_data (decl);
8359       var = build_fold_indirect_ref_loc (input_location, tmp);
8360
8361       /* Get the number of elements - 1 and set the counter.  */
8362       if (GFC_DESCRIPTOR_TYPE_P (decl_type))
8363         {
8364           /* Use the descriptor for an allocatable array.  Since this
8365              is a full array reference, we only need the descriptor
8366              information from dimension = rank.  */
8367           tmp = gfc_full_array_size (&fnblock, decl, rank);
8368           tmp = fold_build2_loc (input_location, MINUS_EXPR,
8369                                  gfc_array_index_type, tmp,
8370                                  gfc_index_one_node);
8371
8372           null_cond = gfc_conv_descriptor_data_get (decl);
8373           null_cond = fold_build2_loc (input_location, NE_EXPR,
8374                                        logical_type_node, null_cond,
8375                                        build_int_cst (TREE_TYPE (null_cond), 0));
8376         }
8377       else
8378         {
8379           /*  Otherwise use the TYPE_DOMAIN information.  */
8380           tmp = array_type_nelts (decl_type);
8381           tmp = fold_convert (gfc_array_index_type, tmp);
8382         }
8383
8384       /* Remember that this is, in fact, the no. of elements - 1.  */
8385       nelems = gfc_evaluate_now (tmp, &fnblock);
8386       index = gfc_create_var (gfc_array_index_type, "S");
8387
8388       /* Build the body of the loop.  */
8389       gfc_init_block (&loopbody);
8390
8391       vref = gfc_build_array_ref (var, index, NULL);
8392
8393       if ((purpose == COPY_ALLOC_COMP || purpose == COPY_ONLY_ALLOC_COMP)
8394           && !caf_enabled (caf_mode))
8395         {
8396           tmp = build_fold_indirect_ref_loc (input_location,
8397                                          gfc_conv_array_data (dest));
8398           dref = gfc_build_array_ref (tmp, index, NULL);
8399           tmp = structure_alloc_comps (der_type, vref, dref, rank,
8400                                        COPY_ALLOC_COMP, 0);
8401         }
8402       else
8403         tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose,
8404                                      caf_mode);
8405
8406       gfc_add_expr_to_block (&loopbody, tmp);
8407
8408       /* Build the loop and return.  */
8409       gfc_init_loopinfo (&loop);
8410       loop.dimen = 1;
8411       loop.from[0] = gfc_index_zero_node;
8412       loop.loopvar[0] = index;
8413       loop.to[0] = nelems;
8414       gfc_trans_scalarizing_loops (&loop, &loopbody);
8415       gfc_add_block_to_block (&fnblock, &loop.pre);
8416
8417       tmp = gfc_finish_block (&fnblock);
8418       /* When copying allocateable components, the above implements the
8419          deep copy.  Nevertheless is a deep copy only allowed, when the current
8420          component is allocated, for which code will be generated in
8421          gfc_duplicate_allocatable (), where the deep copy code is just added
8422          into the if's body, by adding tmp (the deep copy code) as last
8423          argument to gfc_duplicate_allocatable ().  */
8424       if (purpose == COPY_ALLOC_COMP
8425           && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest)))
8426         tmp = gfc_duplicate_allocatable (dest, decl, decl_type, rank,
8427                                          tmp);
8428       else if (null_cond != NULL_TREE)
8429         tmp = build3_v (COND_EXPR, null_cond, tmp,
8430                         build_empty_stmt (input_location));
8431
8432       return tmp;
8433     }
8434
8435   if (purpose == DEALLOCATE_ALLOC_COMP && der_type->attr.pdt_type)
8436     {
8437       tmp = structure_alloc_comps (der_type, decl, NULL_TREE, rank,
8438                                    DEALLOCATE_PDT_COMP, 0);
8439       gfc_add_expr_to_block (&fnblock, tmp);
8440     }
8441   else if (purpose == ALLOCATE_PDT_COMP && der_type->attr.alloc_comp)
8442     {
8443       tmp = structure_alloc_comps (der_type, decl, NULL_TREE, rank,
8444                                    NULLIFY_ALLOC_COMP, 0);
8445       gfc_add_expr_to_block (&fnblock, tmp);
8446     }
8447
8448   /* Otherwise, act on the components or recursively call self to
8449      act on a chain of components.  */
8450   for (c = der_type->components; c; c = c->next)
8451     {
8452       bool cmp_has_alloc_comps = (c->ts.type == BT_DERIVED
8453                                   || c->ts.type == BT_CLASS)
8454                                     && c->ts.u.derived->attr.alloc_comp;
8455       bool same_type = (c->ts.type == BT_DERIVED && der_type == c->ts.u.derived)
8456         || (c->ts.type == BT_CLASS && der_type == CLASS_DATA (c)->ts.u.derived);
8457
8458       bool is_pdt_type = c->ts.type == BT_DERIVED
8459                          && c->ts.u.derived->attr.pdt_type;
8460
8461       cdecl = c->backend_decl;
8462       ctype = TREE_TYPE (cdecl);
8463
8464       switch (purpose)
8465         {
8466         case DEALLOCATE_ALLOC_COMP:
8467
8468           gfc_init_block (&tmpblock);
8469
8470           comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
8471                                   decl, cdecl, NULL_TREE);
8472
8473           /* Shortcut to get the attributes of the component.  */
8474           if (c->ts.type == BT_CLASS)
8475             {
8476               attr = &CLASS_DATA (c)->attr;
8477               if (attr->class_pointer)
8478                 continue;
8479             }
8480           else
8481             {
8482               attr = &c->attr;
8483               if (attr->pointer)
8484                 continue;
8485             }
8486
8487           if ((c->ts.type == BT_DERIVED && !c->attr.pointer)
8488              || (c->ts.type == BT_CLASS && !CLASS_DATA (c)->attr.class_pointer))
8489             /* Call the finalizer, which will free the memory and nullify the
8490                pointer of an array.  */
8491             deallocate_called = gfc_add_comp_finalizer_call (&tmpblock, comp, c,
8492                                                          caf_enabled (caf_mode))
8493                 && attr->dimension;
8494           else
8495             deallocate_called = false;
8496
8497           /* Add the _class ref for classes.  */
8498           if (c->ts.type == BT_CLASS && attr->allocatable)
8499             comp = gfc_class_data_get (comp);
8500
8501           add_when_allocated = NULL_TREE;
8502           if (cmp_has_alloc_comps
8503               && !c->attr.pointer && !c->attr.proc_pointer
8504               && !same_type
8505               && !deallocate_called)
8506             {
8507               /* Add checked deallocation of the components.  This code is
8508                  obviously added because the finalizer is not trusted to free
8509                  all memory.  */
8510               if (c->ts.type == BT_CLASS)
8511                 {
8512                   rank = CLASS_DATA (c)->as ? CLASS_DATA (c)->as->rank : 0;
8513                   add_when_allocated
8514                       = structure_alloc_comps (CLASS_DATA (c)->ts.u.derived,
8515                                                comp, NULL_TREE, rank, purpose,
8516                                                caf_mode);
8517                 }
8518               else
8519                 {
8520                   rank = c->as ? c->as->rank : 0;
8521                   add_when_allocated = structure_alloc_comps (c->ts.u.derived,
8522                                                               comp, NULL_TREE,
8523                                                               rank, purpose,
8524                                                               caf_mode);
8525                 }
8526             }
8527
8528           if (attr->allocatable && !same_type
8529               && (!attr->codimension || caf_enabled (caf_mode)))
8530             {
8531               /* Handle all types of components besides components of the
8532                  same_type as the current one, because those would create an
8533                  endless loop.  */
8534               caf_dereg_mode
8535                   = (caf_in_coarray (caf_mode) || attr->codimension)
8536                   ? (gfc_caf_is_dealloc_only (caf_mode)
8537                      ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
8538                      : GFC_CAF_COARRAY_DEREGISTER)
8539                   : GFC_CAF_COARRAY_NOCOARRAY;
8540
8541               caf_token = NULL_TREE;
8542               /* Coarray components are handled directly by
8543                  deallocate_with_status.  */
8544               if (!attr->codimension
8545                   && caf_dereg_mode != GFC_CAF_COARRAY_NOCOARRAY)
8546                 {
8547                   if (c->caf_token)
8548                     caf_token = fold_build3_loc (input_location, COMPONENT_REF,
8549                                                  TREE_TYPE (c->caf_token),
8550                                                  decl, c->caf_token, NULL_TREE);
8551                   else if (attr->dimension && !attr->proc_pointer)
8552                     caf_token = gfc_conv_descriptor_token (comp);
8553                 }
8554               if (attr->dimension && !attr->codimension && !attr->proc_pointer)
8555                 /* When this is an array but not in conjunction with a coarray
8556                    then add the data-ref.  For coarray'ed arrays the data-ref
8557                    is added by deallocate_with_status.  */
8558                 comp = gfc_conv_descriptor_data_get (comp);
8559
8560               tmp = gfc_deallocate_with_status (comp, NULL_TREE, NULL_TREE,
8561                                                 NULL_TREE, NULL_TREE, true,
8562                                                 NULL, caf_dereg_mode,
8563                                                 add_when_allocated, caf_token);
8564
8565               gfc_add_expr_to_block (&tmpblock, tmp);
8566             }
8567           else if (attr->allocatable && !attr->codimension
8568                    && !deallocate_called)
8569             {
8570               /* Case of recursive allocatable derived types.  */
8571               tree is_allocated;
8572               tree ubound;
8573               tree cdesc;
8574               stmtblock_t dealloc_block;
8575
8576               gfc_init_block (&dealloc_block);
8577               if (add_when_allocated)
8578                 gfc_add_expr_to_block (&dealloc_block, add_when_allocated);
8579
8580               /* Convert the component into a rank 1 descriptor type.  */
8581               if (attr->dimension)
8582                 {
8583                   tmp = gfc_get_element_type (TREE_TYPE (comp));
8584                   ubound = gfc_full_array_size (&dealloc_block, comp,
8585                                                 c->ts.type == BT_CLASS
8586                                                 ? CLASS_DATA (c)->as->rank
8587                                                 : c->as->rank);
8588                 }
8589               else
8590                 {
8591                   tmp = TREE_TYPE (comp);
8592                   ubound = build_int_cst (gfc_array_index_type, 1);
8593                 }
8594
8595               cdesc = gfc_get_array_type_bounds (tmp, 1, 0, &gfc_index_one_node,
8596                                                  &ubound, 1,
8597                                                  GFC_ARRAY_ALLOCATABLE, false);
8598
8599               cdesc = gfc_create_var (cdesc, "cdesc");
8600               DECL_ARTIFICIAL (cdesc) = 1;
8601
8602               gfc_add_modify (&dealloc_block, gfc_conv_descriptor_dtype (cdesc),
8603                               gfc_get_dtype_rank_type (1, tmp));
8604               gfc_conv_descriptor_lbound_set (&dealloc_block, cdesc,
8605                                               gfc_index_zero_node,
8606                                               gfc_index_one_node);
8607               gfc_conv_descriptor_stride_set (&dealloc_block, cdesc,
8608                                               gfc_index_zero_node,
8609                                               gfc_index_one_node);
8610               gfc_conv_descriptor_ubound_set (&dealloc_block, cdesc,
8611                                               gfc_index_zero_node, ubound);
8612
8613               if (attr->dimension)
8614                 comp = gfc_conv_descriptor_data_get (comp);
8615
8616               gfc_conv_descriptor_data_set (&dealloc_block, cdesc, comp);
8617
8618               /* Now call the deallocator.  */
8619               vtab = gfc_find_vtab (&c->ts);
8620               if (vtab->backend_decl == NULL)
8621                 gfc_get_symbol_decl (vtab);
8622               tmp = gfc_build_addr_expr (NULL_TREE, vtab->backend_decl);
8623               dealloc_fndecl = gfc_vptr_deallocate_get (tmp);
8624               dealloc_fndecl = build_fold_indirect_ref_loc (input_location,
8625                                                             dealloc_fndecl);
8626               tmp = build_int_cst (TREE_TYPE (comp), 0);
8627               is_allocated = fold_build2_loc (input_location, NE_EXPR,
8628                                               logical_type_node, tmp,
8629                                               comp);
8630               cdesc = gfc_build_addr_expr (NULL_TREE, cdesc);
8631
8632               tmp = build_call_expr_loc (input_location,
8633                                          dealloc_fndecl, 1,
8634                                          cdesc);
8635               gfc_add_expr_to_block (&dealloc_block, tmp);
8636
8637               tmp = gfc_finish_block (&dealloc_block);
8638
8639               tmp = fold_build3_loc (input_location, COND_EXPR,
8640                                      void_type_node, is_allocated, tmp,
8641                                      build_empty_stmt (input_location));
8642
8643               gfc_add_expr_to_block (&tmpblock, tmp);
8644             }
8645           else if (add_when_allocated)
8646             gfc_add_expr_to_block (&tmpblock, add_when_allocated);
8647
8648           if (c->ts.type == BT_CLASS && attr->allocatable
8649               && (!attr->codimension || !caf_enabled (caf_mode)))
8650             {
8651               /* Finally, reset the vptr to the declared type vtable and, if
8652                  necessary reset the _len field.
8653
8654                  First recover the reference to the component and obtain
8655                  the vptr.  */
8656               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
8657                                       decl, cdecl, NULL_TREE);
8658               tmp = gfc_class_vptr_get (comp);
8659
8660               if (UNLIMITED_POLY (c))
8661                 {
8662                   /* Both vptr and _len field should be nulled.  */
8663                   gfc_add_modify (&tmpblock, tmp,
8664                                   build_int_cst (TREE_TYPE (tmp), 0));
8665                   tmp = gfc_class_len_get (comp);
8666                   gfc_add_modify (&tmpblock, tmp,
8667                                   build_int_cst (TREE_TYPE (tmp), 0));
8668                 }
8669               else
8670                 {
8671                   /* Build the vtable address and set the vptr with it.  */
8672                   tree vtab;
8673                   gfc_symbol *vtable;
8674                   vtable = gfc_find_derived_vtab (c->ts.u.derived);
8675                   vtab = vtable->backend_decl;
8676                   if (vtab == NULL_TREE)
8677                     vtab = gfc_get_symbol_decl (vtable);
8678                   vtab = gfc_build_addr_expr (NULL, vtab);
8679                   vtab = fold_convert (TREE_TYPE (tmp), vtab);
8680                   gfc_add_modify (&tmpblock, tmp, vtab);
8681                 }
8682             }
8683
8684           /* Now add the deallocation of this component.  */
8685           gfc_add_block_to_block (&fnblock, &tmpblock);
8686           break;
8687
8688         case NULLIFY_ALLOC_COMP:
8689           /* Nullify
8690              - allocatable components (regular or in class)
8691              - components that have allocatable components
8692              - pointer components when in a coarray.
8693              Skip everything else especially proc_pointers, which may come
8694              coupled with the regular pointer attribute.  */
8695           if (c->attr.proc_pointer
8696               || !(c->attr.allocatable || (c->ts.type == BT_CLASS
8697                                            && CLASS_DATA (c)->attr.allocatable)
8698                    || (cmp_has_alloc_comps
8699                        && ((c->ts.type == BT_DERIVED && !c->attr.pointer)
8700                            || (c->ts.type == BT_CLASS
8701                                && !CLASS_DATA (c)->attr.class_pointer)))
8702                    || (caf_in_coarray (caf_mode) && c->attr.pointer)))
8703             continue;
8704
8705           /* Process class components first, because they always have the
8706              pointer-attribute set which would be caught wrong else.  */
8707           if (c->ts.type == BT_CLASS
8708               && (CLASS_DATA (c)->attr.allocatable
8709                   || CLASS_DATA (c)->attr.class_pointer))
8710             {
8711               /* Allocatable CLASS components.  */
8712               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
8713                                       decl, cdecl, NULL_TREE);
8714
8715               comp = gfc_class_data_get (comp);
8716               if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)))
8717                 gfc_conv_descriptor_data_set (&fnblock, comp,
8718                                               null_pointer_node);
8719               else
8720                 {
8721                   tmp = fold_build2_loc (input_location, MODIFY_EXPR,
8722                                          void_type_node, comp,
8723                                          build_int_cst (TREE_TYPE (comp), 0));
8724                   gfc_add_expr_to_block (&fnblock, tmp);
8725                 }
8726               cmp_has_alloc_comps = false;
8727             }
8728           /* Coarrays need the component to be nulled before the api-call
8729              is made.  */
8730           else if (c->attr.pointer || c->attr.allocatable)
8731             {
8732               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
8733                                       decl, cdecl, NULL_TREE);
8734               if (c->attr.dimension || c->attr.codimension)
8735                 gfc_conv_descriptor_data_set (&fnblock, comp,
8736                                               null_pointer_node);
8737               else
8738                 gfc_add_modify (&fnblock, comp,
8739                                 build_int_cst (TREE_TYPE (comp), 0));
8740               if (gfc_deferred_strlen (c, &comp))
8741                 {
8742                   comp = fold_build3_loc (input_location, COMPONENT_REF,
8743                                           TREE_TYPE (comp),
8744                                           decl, comp, NULL_TREE);
8745                   tmp = fold_build2_loc (input_location, MODIFY_EXPR,
8746                                          TREE_TYPE (comp), comp,
8747                                          build_int_cst (TREE_TYPE (comp), 0));
8748                   gfc_add_expr_to_block (&fnblock, tmp);
8749                 }
8750               cmp_has_alloc_comps = false;
8751             }
8752
8753           if (flag_coarray == GFC_FCOARRAY_LIB && caf_in_coarray (caf_mode))
8754             {
8755               /* Register a component of a derived type coarray with the
8756                  coarray library.  Do not register ultimate component
8757                  coarrays here.  They are treated like regular coarrays and
8758                  are either allocated on all images or on none.  */
8759               tree token;
8760
8761               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
8762                                       decl, cdecl, NULL_TREE);
8763               if (c->attr.dimension)
8764                 {
8765                   /* Set the dtype, because caf_register needs it.  */
8766                   gfc_add_modify (&fnblock, gfc_conv_descriptor_dtype (comp),
8767                                   gfc_get_dtype (TREE_TYPE (comp)));
8768                   tmp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
8769                                          decl, cdecl, NULL_TREE);
8770                   token = gfc_conv_descriptor_token (tmp);
8771                 }
8772               else
8773                 {
8774                   gfc_se se;
8775
8776                   gfc_init_se (&se, NULL);
8777                   token = fold_build3_loc (input_location, COMPONENT_REF,
8778                                            pvoid_type_node, decl, c->caf_token,
8779                                            NULL_TREE);
8780                   comp = gfc_conv_scalar_to_descriptor (&se, comp,
8781                                                         c->ts.type == BT_CLASS
8782                                                         ? CLASS_DATA (c)->attr
8783                                                         : c->attr);
8784                   gfc_add_block_to_block (&fnblock, &se.pre);
8785                 }
8786
8787               gfc_allocate_using_caf_lib (&fnblock, comp, size_zero_node,
8788                                           gfc_build_addr_expr (NULL_TREE,
8789                                                                token),
8790                                           NULL_TREE, NULL_TREE, NULL_TREE,
8791                                           GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY);
8792             }
8793
8794           if (cmp_has_alloc_comps)
8795             {
8796               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
8797                                       decl, cdecl, NULL_TREE);
8798               rank = c->as ? c->as->rank : 0;
8799               tmp = structure_alloc_comps (c->ts.u.derived, comp, NULL_TREE,
8800                                            rank, purpose, caf_mode);
8801               gfc_add_expr_to_block (&fnblock, tmp);
8802             }
8803           break;
8804
8805         case REASSIGN_CAF_COMP:
8806           if (caf_enabled (caf_mode)
8807               && (c->attr.codimension
8808                   || (c->ts.type == BT_CLASS
8809                       && (CLASS_DATA (c)->attr.coarray_comp
8810                           || caf_in_coarray (caf_mode)))
8811                   || (c->ts.type == BT_DERIVED
8812                       && (c->ts.u.derived->attr.coarray_comp
8813                           || caf_in_coarray (caf_mode))))
8814               && !same_type)
8815             {
8816               comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
8817                                       decl, cdecl, NULL_TREE);
8818               dcmp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
8819                                       dest, cdecl, NULL_TREE);
8820
8821               if (c->attr.codimension)
8822                 {
8823                   if (c->ts.type == BT_CLASS)
8824                     {
8825                       comp = gfc_class_data_get (comp);
8826                       dcmp = gfc_class_data_get (dcmp);
8827                     }
8828                   gfc_conv_descriptor_data_set (&fnblock, dcmp,
8829                                            gfc_conv_descriptor_data_get (comp));
8830                 }
8831               else
8832                 {
8833                   tmp = structure_alloc_comps (c->ts.u.derived, comp, dcmp,
8834                                                rank, purpose, caf_mode
8835                                            | GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
8836                   gfc_add_expr_to_block (&fnblock, tmp);
8837                 }
8838             }
8839           break;
8840
8841         case COPY_ALLOC_COMP:
8842           if (c->attr.pointer)
8843             continue;
8844
8845           /* We need source and destination components.  */
8846           comp = fold_build3_loc (input_location, COMPONENT_REF, ctype, decl,
8847                                   cdecl, NULL_TREE);
8848           dcmp = fold_build3_loc (input_location, COMPONENT_REF, ctype, dest,
8849                                   cdecl, NULL_TREE);
8850           dcmp = fold_convert (TREE_TYPE (comp), dcmp);
8851
8852           if (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.allocatable)
8853             {
8854               tree ftn_tree;
8855               tree size;
8856               tree dst_data;
8857               tree src_data;
8858               tree null_data;
8859
8860               dst_data = gfc_class_data_get (dcmp);
8861               src_data = gfc_class_data_get (comp);
8862               size = fold_convert (size_type_node,
8863                                    gfc_class_vtab_size_get (comp));
8864
8865               if (CLASS_DATA (c)->attr.dimension)
8866                 {
8867                   nelems = gfc_conv_descriptor_size (src_data,
8868                                                      CLASS_DATA (c)->as->rank);
8869                   size = fold_build2_loc (input_location, MULT_EXPR,
8870                                           size_type_node, size,
8871                                           fold_convert (size_type_node,
8872                                                         nelems));
8873                 }
8874               else
8875                 nelems = build_int_cst (size_type_node, 1);
8876
8877               if (CLASS_DATA (c)->attr.dimension
8878                   || CLASS_DATA (c)->attr.codimension)
8879                 {
8880                   src_data = gfc_conv_descriptor_data_get (src_data);
8881                   dst_data = gfc_conv_descriptor_data_get (dst_data);
8882                 }
8883
8884               gfc_init_block (&tmpblock);
8885
8886               gfc_add_modify (&tmpblock, gfc_class_vptr_get (dcmp),
8887                               gfc_class_vptr_get (comp));
8888
8889               /* Copy the unlimited '_len' field. If it is greater than zero
8890                  (ie. a character(_len)), multiply it by size and use this
8891                  for the malloc call.  */
8892               if (UNLIMITED_POLY (c))
8893                 {
8894                   tree ctmp;
8895                   gfc_add_modify (&tmpblock, gfc_class_len_get (dcmp),
8896                                   gfc_class_len_get (comp));
8897
8898                   size = gfc_evaluate_now (size, &tmpblock);
8899                   tmp = gfc_class_len_get (comp);
8900                   ctmp = fold_build2_loc (input_location, MULT_EXPR,
8901                                           size_type_node, size,
8902                                           fold_convert (size_type_node, tmp));
8903                   tmp = fold_build2_loc (input_location, GT_EXPR,
8904                                          logical_type_node, tmp,
8905                                          build_zero_cst (TREE_TYPE (tmp)));
8906                   size = fold_build3_loc (input_location, COND_EXPR,
8907                                           size_type_node, tmp, ctmp, size);
8908                   size = gfc_evaluate_now (size, &tmpblock);
8909                 }
8910
8911               /* Coarray component have to have the same allocation status and
8912                  shape/type-parameter/effective-type on the LHS and RHS of an
8913                  intrinsic assignment. Hence, we did not deallocated them - and
8914                  do not allocate them here.  */
8915               if (!CLASS_DATA (c)->attr.codimension)
8916                 {
8917                   ftn_tree = builtin_decl_explicit (BUILT_IN_MALLOC);
8918                   tmp = build_call_expr_loc (input_location, ftn_tree, 1, size);
8919                   gfc_add_modify (&tmpblock, dst_data,
8920                                   fold_convert (TREE_TYPE (dst_data), tmp));
8921                 }
8922
8923               tmp = gfc_copy_class_to_class (comp, dcmp, nelems,
8924                                              UNLIMITED_POLY (c));
8925               gfc_add_expr_to_block (&tmpblock, tmp);
8926               tmp = gfc_finish_block (&tmpblock);
8927
8928               gfc_init_block (&tmpblock);
8929               gfc_add_modify (&tmpblock, dst_data,
8930                               fold_convert (TREE_TYPE (dst_data),
8931                                             null_pointer_node));
8932               null_data = gfc_finish_block (&tmpblock);
8933
8934               null_cond = fold_build2_loc (input_location, NE_EXPR,
8935                                            logical_type_node, src_data,
8936                                            null_pointer_node);
8937
8938               gfc_add_expr_to_block (&fnblock, build3_v (COND_EXPR, null_cond,
8939                                                          tmp, null_data));
8940               continue;
8941             }
8942
8943           /* To implement guarded deep copy, i.e., deep copy only allocatable
8944              components that are really allocated, the deep copy code has to
8945              be generated first and then added to the if-block in
8946              gfc_duplicate_allocatable ().  */
8947           if (cmp_has_alloc_comps && !c->attr.proc_pointer && !same_type)
8948             {
8949               rank = c->as ? c->as->rank : 0;
8950               tmp = fold_convert (TREE_TYPE (dcmp), comp);
8951               gfc_add_modify (&fnblock, dcmp, tmp);
8952               add_when_allocated = structure_alloc_comps (c->ts.u.derived,
8953                                                           comp, dcmp,
8954                                                           rank, purpose,
8955                                                           caf_mode);
8956             }
8957           else
8958             add_when_allocated = NULL_TREE;
8959
8960           if (gfc_deferred_strlen (c, &tmp))
8961             {
8962               tree len, size;
8963               len = tmp;
8964               tmp = fold_build3_loc (input_location, COMPONENT_REF,
8965                                      TREE_TYPE (len),
8966                                      decl, len, NULL_TREE);
8967               len = fold_build3_loc (input_location, COMPONENT_REF,
8968                                      TREE_TYPE (len),
8969                                      dest, len, NULL_TREE);
8970               tmp = fold_build2_loc (input_location, MODIFY_EXPR,
8971                                      TREE_TYPE (len), len, tmp);
8972               gfc_add_expr_to_block (&fnblock, tmp);
8973               size = size_of_string_in_bytes (c->ts.kind, len);
8974               /* This component can not have allocatable components,
8975                  therefore add_when_allocated of duplicate_allocatable ()
8976                  is always NULL.  */
8977               tmp = duplicate_allocatable (dcmp, comp, ctype, rank,
8978                                            false, false, size, NULL_TREE);
8979               gfc_add_expr_to_block (&fnblock, tmp);
8980             }
8981           else if (c->attr.pdt_array)
8982             {
8983               tmp = duplicate_allocatable (dcmp, comp, ctype,
8984                                            c->as ? c->as->rank : 0,
8985                                            false, false, NULL_TREE, NULL_TREE);
8986               gfc_add_expr_to_block (&fnblock, tmp);
8987             }
8988           else if ((c->attr.allocatable)
8989                     && !c->attr.proc_pointer && !same_type
8990                     && (!(cmp_has_alloc_comps && c->as) || c->attr.codimension
8991                         || caf_in_coarray (caf_mode)))
8992             {
8993               rank = c->as ? c->as->rank : 0;
8994               if (c->attr.codimension)
8995                 tmp = gfc_copy_allocatable_data (dcmp, comp, ctype, rank);
8996               else if (flag_coarray == GFC_FCOARRAY_LIB
8997                        && caf_in_coarray (caf_mode))
8998                 {
8999                   tree dst_tok = c->as ? gfc_conv_descriptor_token (dcmp)
9000                                        : fold_build3_loc (input_location,
9001                                                           COMPONENT_REF,
9002                                                           pvoid_type_node, dest,
9003                                                           c->caf_token,
9004                                                           NULL_TREE);
9005                   tmp = duplicate_allocatable_coarray (dcmp, dst_tok, comp,
9006                                                        ctype, rank);
9007                 }
9008               else
9009                 tmp = gfc_duplicate_allocatable (dcmp, comp, ctype, rank,
9010                                                  add_when_allocated);
9011               gfc_add_expr_to_block (&fnblock, tmp);
9012             }
9013           else
9014             if (cmp_has_alloc_comps || is_pdt_type)
9015               gfc_add_expr_to_block (&fnblock, add_when_allocated);
9016
9017           break;
9018
9019         case ALLOCATE_PDT_COMP:
9020
9021           comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9022                                   decl, cdecl, NULL_TREE);
9023
9024           /* Set the PDT KIND and LEN fields.  */
9025           if (c->attr.pdt_kind || c->attr.pdt_len)
9026             {
9027               gfc_se tse;
9028               gfc_expr *c_expr = NULL;
9029               gfc_actual_arglist *param = pdt_param_list;
9030               gfc_init_se (&tse, NULL);
9031               for (; param; param = param->next)
9032                 if (param->name && !strcmp (c->name, param->name))
9033                   c_expr = param->expr;
9034
9035               if (!c_expr)
9036                 c_expr = c->initializer;
9037
9038               if (c_expr)
9039                 {
9040                   gfc_conv_expr_type (&tse, c_expr, TREE_TYPE (comp));
9041                   gfc_add_modify (&fnblock, comp, tse.expr);
9042                 }
9043             }
9044
9045           if (c->attr.pdt_string)
9046             {
9047               gfc_se tse;
9048               gfc_init_se (&tse, NULL);
9049               tree strlen = NULL_TREE;
9050               gfc_expr *e = gfc_copy_expr (c->ts.u.cl->length);
9051               /* Convert the parameterized string length to its value. The
9052                  string length is stored in a hidden field in the same way as
9053                  deferred string lengths.  */
9054               gfc_insert_parameter_exprs (e, pdt_param_list);
9055               if (gfc_deferred_strlen (c, &strlen) && strlen != NULL_TREE)
9056                 {
9057                   gfc_conv_expr_type (&tse, e,
9058                                       TREE_TYPE (strlen));
9059                   strlen = fold_build3_loc (input_location, COMPONENT_REF,
9060                                             TREE_TYPE (strlen),
9061                                             decl, strlen, NULL_TREE);
9062                   gfc_add_modify (&fnblock, strlen, tse.expr);
9063                   c->ts.u.cl->backend_decl = strlen;
9064                 }
9065               gfc_free_expr (e);
9066
9067               /* Scalar parameterized strings can be allocated now.  */
9068               if (!c->as)
9069                 {
9070                   tmp = fold_convert (gfc_array_index_type, strlen);
9071                   tmp = size_of_string_in_bytes (c->ts.kind, tmp);
9072                   tmp = gfc_evaluate_now (tmp, &fnblock);
9073                   tmp = gfc_call_malloc (&fnblock, TREE_TYPE (comp), tmp);
9074                   gfc_add_modify (&fnblock, comp, tmp);
9075                 }
9076             }
9077
9078           /* Allocate parameterized arrays of parameterized derived types.  */
9079           if (!(c->attr.pdt_array && c->as && c->as->type == AS_EXPLICIT)
9080               && !((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
9081                    && (c->ts.u.derived && c->ts.u.derived->attr.pdt_type)))
9082             continue;
9083
9084           if (c->ts.type == BT_CLASS)
9085             comp = gfc_class_data_get (comp);
9086
9087           if (c->attr.pdt_array)
9088             {
9089               gfc_se tse;
9090               int i;
9091               tree size = gfc_index_one_node;
9092               tree offset = gfc_index_zero_node;
9093               tree lower, upper;
9094               gfc_expr *e;
9095
9096               /* This chunk takes the expressions for 'lower' and 'upper'
9097                  in the arrayspec and substitutes in the expressions for
9098                  the parameters from 'pdt_param_list'. The descriptor
9099                  fields can then be filled from the values so obtained.  */
9100               gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)));
9101               for (i = 0; i < c->as->rank; i++)
9102                 {
9103                   gfc_init_se (&tse, NULL);
9104                   e = gfc_copy_expr (c->as->lower[i]);
9105                   gfc_insert_parameter_exprs (e, pdt_param_list);
9106                   gfc_conv_expr_type (&tse, e, gfc_array_index_type);
9107                   gfc_free_expr (e);
9108                   lower = tse.expr;
9109                   gfc_conv_descriptor_lbound_set (&fnblock, comp,
9110                                                   gfc_rank_cst[i],
9111                                                   lower);
9112                   e = gfc_copy_expr (c->as->upper[i]);
9113                   gfc_insert_parameter_exprs (e, pdt_param_list);
9114                   gfc_conv_expr_type (&tse, e, gfc_array_index_type);
9115                   gfc_free_expr (e);
9116                   upper = tse.expr;
9117                   gfc_conv_descriptor_ubound_set (&fnblock, comp,
9118                                                   gfc_rank_cst[i],
9119                                                   upper);
9120                   gfc_conv_descriptor_stride_set (&fnblock, comp,
9121                                                   gfc_rank_cst[i],
9122                                                   size);
9123                   size = gfc_evaluate_now (size, &fnblock);
9124                   offset = fold_build2_loc (input_location,
9125                                             MINUS_EXPR,
9126                                             gfc_array_index_type,
9127                                             offset, size);
9128                   offset = gfc_evaluate_now (offset, &fnblock);
9129                   tmp = fold_build2_loc (input_location, MINUS_EXPR,
9130                                          gfc_array_index_type,
9131                                          upper, lower);
9132                   tmp = fold_build2_loc (input_location, PLUS_EXPR,
9133                                          gfc_array_index_type,
9134                                          tmp, gfc_index_one_node);
9135                   size = fold_build2_loc (input_location, MULT_EXPR,
9136                                           gfc_array_index_type, size, tmp);
9137                 }
9138               gfc_conv_descriptor_offset_set (&fnblock, comp, offset);
9139               if (c->ts.type == BT_CLASS)
9140                 {
9141                   tmp = gfc_get_vptr_from_expr (comp);
9142                   if (POINTER_TYPE_P (TREE_TYPE (tmp)))
9143                     tmp = build_fold_indirect_ref_loc (input_location, tmp);
9144                   tmp = gfc_vptr_size_get (tmp);
9145                 }
9146               else
9147                 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (ctype));
9148               tmp = fold_convert (gfc_array_index_type, tmp);
9149               size = fold_build2_loc (input_location, MULT_EXPR,
9150                                       gfc_array_index_type, size, tmp);
9151               size = gfc_evaluate_now (size, &fnblock);
9152               tmp = gfc_call_malloc (&fnblock, NULL, size);
9153               gfc_conv_descriptor_data_set (&fnblock, comp, tmp);
9154               tmp = gfc_conv_descriptor_dtype (comp);
9155               gfc_add_modify (&fnblock, tmp, gfc_get_dtype (ctype));
9156
9157               if (c->initializer && c->initializer->rank)
9158                 {
9159                   gfc_init_se (&tse, NULL);
9160                   e = gfc_copy_expr (c->initializer);
9161                   gfc_insert_parameter_exprs (e, pdt_param_list);
9162                   gfc_conv_expr_descriptor (&tse, e);
9163                   gfc_add_block_to_block (&fnblock, &tse.pre);
9164                   gfc_free_expr (e);
9165                   tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
9166                   tmp = build_call_expr_loc (input_location, tmp, 3,
9167                                      gfc_conv_descriptor_data_get (comp),
9168                                      gfc_conv_descriptor_data_get (tse.expr),
9169                                      fold_convert (size_type_node, size));
9170                   gfc_add_expr_to_block (&fnblock, tmp);
9171                   gfc_add_block_to_block (&fnblock, &tse.post);
9172                 }
9173             }
9174
9175           /* Recurse in to PDT components.  */
9176           if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
9177               && c->ts.u.derived && c->ts.u.derived->attr.pdt_type
9178               && !(c->attr.pointer || c->attr.allocatable))
9179             {
9180               bool is_deferred = false;
9181               gfc_actual_arglist *tail = c->param_list;
9182
9183               for (; tail; tail = tail->next)
9184                 if (!tail->expr)
9185                   is_deferred = true;
9186
9187               tail = is_deferred ? pdt_param_list : c->param_list;
9188               tmp = gfc_allocate_pdt_comp (c->ts.u.derived, comp,
9189                                            c->as ? c->as->rank : 0,
9190                                            tail);
9191               gfc_add_expr_to_block (&fnblock, tmp);
9192             }
9193
9194           break;
9195
9196         case DEALLOCATE_PDT_COMP:
9197           /* Deallocate array or parameterized string length components
9198              of parameterized derived types.  */
9199           if (!(c->attr.pdt_array && c->as && c->as->type == AS_EXPLICIT)
9200               && !c->attr.pdt_string
9201               && !((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
9202                    && (c->ts.u.derived && c->ts.u.derived->attr.pdt_type)))
9203             continue;
9204
9205           comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9206                                   decl, cdecl, NULL_TREE);
9207           if (c->ts.type == BT_CLASS)
9208             comp = gfc_class_data_get (comp);
9209
9210           /* Recurse in to PDT components.  */
9211           if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
9212               && c->ts.u.derived && c->ts.u.derived->attr.pdt_type
9213               && (!c->attr.pointer && !c->attr.allocatable))
9214             {
9215               tmp = gfc_deallocate_pdt_comp (c->ts.u.derived, comp,
9216                                              c->as ? c->as->rank : 0);
9217               gfc_add_expr_to_block (&fnblock, tmp);
9218             }
9219
9220           if (c->attr.pdt_array)
9221             {
9222               tmp = gfc_conv_descriptor_data_get (comp);
9223               null_cond = fold_build2_loc (input_location, NE_EXPR,
9224                                            logical_type_node, tmp,
9225                                            build_int_cst (TREE_TYPE (tmp), 0));
9226               tmp = gfc_call_free (tmp);
9227               tmp = build3_v (COND_EXPR, null_cond, tmp,
9228                               build_empty_stmt (input_location));
9229               gfc_add_expr_to_block (&fnblock, tmp);
9230               gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
9231             }
9232           else if (c->attr.pdt_string)
9233             {
9234               null_cond = fold_build2_loc (input_location, NE_EXPR,
9235                                            logical_type_node, comp,
9236                                            build_int_cst (TREE_TYPE (comp), 0));
9237               tmp = gfc_call_free (comp);
9238               tmp = build3_v (COND_EXPR, null_cond, tmp,
9239                               build_empty_stmt (input_location));
9240               gfc_add_expr_to_block (&fnblock, tmp);
9241               tmp = fold_convert (TREE_TYPE (comp), null_pointer_node);
9242               gfc_add_modify (&fnblock, comp, tmp);
9243             }
9244
9245           break;
9246
9247         case CHECK_PDT_DUMMY:
9248
9249           comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9250                                   decl, cdecl, NULL_TREE);
9251           if (c->ts.type == BT_CLASS)
9252             comp = gfc_class_data_get (comp);
9253
9254           /* Recurse in to PDT components.  */
9255           if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
9256               && c->ts.u.derived && c->ts.u.derived->attr.pdt_type)
9257             {
9258               tmp = gfc_check_pdt_dummy (c->ts.u.derived, comp,
9259                                          c->as ? c->as->rank : 0,
9260                                          pdt_param_list);
9261               gfc_add_expr_to_block (&fnblock, tmp);
9262             }
9263
9264           if (!c->attr.pdt_len)
9265             continue;
9266           else
9267             {
9268               gfc_se tse;
9269               gfc_expr *c_expr = NULL;
9270               gfc_actual_arglist *param = pdt_param_list;
9271
9272               gfc_init_se (&tse, NULL);
9273               for (; param; param = param->next)
9274                 if (!strcmp (c->name, param->name)
9275                     && param->spec_type == SPEC_EXPLICIT)
9276                   c_expr = param->expr;
9277
9278               if (c_expr)
9279                 {
9280                   tree error, cond, cname;
9281                   gfc_conv_expr_type (&tse, c_expr, TREE_TYPE (comp));
9282                   cond = fold_build2_loc (input_location, NE_EXPR,
9283                                           logical_type_node,
9284                                           comp, tse.expr);
9285                   cname = gfc_build_cstring_const (c->name);
9286                   cname = gfc_build_addr_expr (pchar_type_node, cname);
9287                   error = gfc_trans_runtime_error (true, NULL,
9288                                                    "The value of the PDT LEN "
9289                                                    "parameter '%s' does not "
9290                                                    "agree with that in the "
9291                                                    "dummy declaration",
9292                                                    cname);
9293                   tmp = fold_build3_loc (input_location, COND_EXPR,
9294                                          void_type_node, cond, error,
9295                                          build_empty_stmt (input_location));
9296                   gfc_add_expr_to_block (&fnblock, tmp);
9297                 }
9298             }
9299           break;
9300
9301         default:
9302           gcc_unreachable ();
9303           break;
9304         }
9305     }
9306
9307   return gfc_finish_block (&fnblock);
9308 }
9309
9310 /* Recursively traverse an object of derived type, generating code to
9311    nullify allocatable components.  */
9312
9313 tree
9314 gfc_nullify_alloc_comp (gfc_symbol * der_type, tree decl, int rank,
9315                         int caf_mode)
9316 {
9317   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
9318                                 NULLIFY_ALLOC_COMP,
9319                               GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY | caf_mode);
9320 }
9321
9322
9323 /* Recursively traverse an object of derived type, generating code to
9324    deallocate allocatable components.  */
9325
9326 tree
9327 gfc_deallocate_alloc_comp (gfc_symbol * der_type, tree decl, int rank,
9328                            int caf_mode)
9329 {
9330   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
9331                                 DEALLOCATE_ALLOC_COMP,
9332                               GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY | caf_mode);
9333 }
9334
9335
9336 /* Recursively traverse an object of derived type, generating code to
9337    deallocate allocatable components.  But do not deallocate coarrays.
9338    To be used for intrinsic assignment, which may not change the allocation
9339    status of coarrays.  */
9340
9341 tree
9342 gfc_deallocate_alloc_comp_no_caf (gfc_symbol * der_type, tree decl, int rank)
9343 {
9344   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
9345                                 DEALLOCATE_ALLOC_COMP, 0);
9346 }
9347
9348
9349 tree
9350 gfc_reassign_alloc_comp_caf (gfc_symbol *der_type, tree decl, tree dest)
9351 {
9352   return structure_alloc_comps (der_type, decl, dest, 0, REASSIGN_CAF_COMP,
9353                                 GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY);
9354 }
9355
9356
9357 /* Recursively traverse an object of derived type, generating code to
9358    copy it and its allocatable components.  */
9359
9360 tree
9361 gfc_copy_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank,
9362                      int caf_mode)
9363 {
9364   return structure_alloc_comps (der_type, decl, dest, rank, COPY_ALLOC_COMP,
9365                                 caf_mode);
9366 }
9367
9368
9369 /* Recursively traverse an object of derived type, generating code to
9370    copy only its allocatable components.  */
9371
9372 tree
9373 gfc_copy_only_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
9374 {
9375   return structure_alloc_comps (der_type, decl, dest, rank,
9376                                 COPY_ONLY_ALLOC_COMP, 0);
9377 }
9378
9379
9380 /* Recursively traverse an object of paramterized derived type, generating
9381    code to allocate parameterized components.  */
9382
9383 tree
9384 gfc_allocate_pdt_comp (gfc_symbol * der_type, tree decl, int rank,
9385                        gfc_actual_arglist *param_list)
9386 {
9387   tree res;
9388   gfc_actual_arglist *old_param_list = pdt_param_list;
9389   pdt_param_list = param_list;
9390   res = structure_alloc_comps (der_type, decl, NULL_TREE, rank,
9391                                ALLOCATE_PDT_COMP, 0);
9392   pdt_param_list = old_param_list;
9393   return res;
9394 }
9395
9396 /* Recursively traverse an object of paramterized derived type, generating
9397    code to deallocate parameterized components.  */
9398
9399 tree
9400 gfc_deallocate_pdt_comp (gfc_symbol * der_type, tree decl, int rank)
9401 {
9402   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
9403                                 DEALLOCATE_PDT_COMP, 0);
9404 }
9405
9406
9407 /* Recursively traverse a dummy of paramterized derived type to check the
9408    values of LEN parameters.  */
9409
9410 tree
9411 gfc_check_pdt_dummy (gfc_symbol * der_type, tree decl, int rank,
9412                      gfc_actual_arglist *param_list)
9413 {
9414   tree res;
9415   gfc_actual_arglist *old_param_list = pdt_param_list;
9416   pdt_param_list = param_list;
9417   res = structure_alloc_comps (der_type, decl, NULL_TREE, rank,
9418                                CHECK_PDT_DUMMY, 0);
9419   pdt_param_list = old_param_list;
9420   return res;
9421 }
9422
9423
9424 /* Returns the value of LBOUND for an expression.  This could be broken out
9425    from gfc_conv_intrinsic_bound but this seemed to be simpler.  This is
9426    called by gfc_alloc_allocatable_for_assignment.  */
9427 static tree
9428 get_std_lbound (gfc_expr *expr, tree desc, int dim, bool assumed_size)
9429 {
9430   tree lbound;
9431   tree ubound;
9432   tree stride;
9433   tree cond, cond1, cond3, cond4;
9434   tree tmp;
9435   gfc_ref *ref;
9436
9437   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
9438     {
9439       tmp = gfc_rank_cst[dim];
9440       lbound = gfc_conv_descriptor_lbound_get (desc, tmp);
9441       ubound = gfc_conv_descriptor_ubound_get (desc, tmp);
9442       stride = gfc_conv_descriptor_stride_get (desc, tmp);
9443       cond1 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
9444                                ubound, lbound);
9445       cond3 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
9446                                stride, gfc_index_zero_node);
9447       cond3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
9448                                logical_type_node, cond3, cond1);
9449       cond4 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
9450                                stride, gfc_index_zero_node);
9451       if (assumed_size)
9452         cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
9453                                 tmp, build_int_cst (gfc_array_index_type,
9454                                                     expr->rank - 1));
9455       else
9456         cond = logical_false_node;
9457
9458       cond1 = fold_build2_loc (input_location, TRUTH_OR_EXPR,
9459                                logical_type_node, cond3, cond4);
9460       cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
9461                               logical_type_node, cond, cond1);
9462
9463       return fold_build3_loc (input_location, COND_EXPR,
9464                               gfc_array_index_type, cond,
9465                               lbound, gfc_index_one_node);
9466     }
9467
9468   if (expr->expr_type == EXPR_FUNCTION)
9469     {
9470       /* A conversion function, so use the argument.  */
9471       gcc_assert (expr->value.function.isym
9472                   && expr->value.function.isym->conversion);
9473       expr = expr->value.function.actual->expr;
9474     }
9475
9476   if (expr->expr_type == EXPR_VARIABLE)
9477     {
9478       tmp = TREE_TYPE (expr->symtree->n.sym->backend_decl);
9479       for (ref = expr->ref; ref; ref = ref->next)
9480         {
9481           if (ref->type == REF_COMPONENT
9482                 && ref->u.c.component->as
9483                 && ref->next
9484                 && ref->next->u.ar.type == AR_FULL)
9485             tmp = TREE_TYPE (ref->u.c.component->backend_decl);
9486         }
9487       return GFC_TYPE_ARRAY_LBOUND(tmp, dim);
9488     }
9489
9490   return gfc_index_one_node;
9491 }
9492
9493
9494 /* Returns true if an expression represents an lhs that can be reallocated
9495    on assignment.  */
9496
9497 bool
9498 gfc_is_reallocatable_lhs (gfc_expr *expr)
9499 {
9500   gfc_ref * ref;
9501   gfc_symbol *sym;
9502
9503   if (!expr->ref)
9504     return false;
9505
9506   sym = expr->symtree->n.sym;
9507
9508   /* An allocatable class variable with no reference.  */
9509   if (sym->ts.type == BT_CLASS
9510       && CLASS_DATA (sym)->attr.allocatable
9511       && expr->ref && expr->ref->type == REF_COMPONENT
9512       && strcmp (expr->ref->u.c.component->name, "_data") == 0
9513       && expr->ref->next == NULL)
9514     return true;
9515
9516   /* An allocatable variable.  */
9517   if (sym->attr.allocatable
9518         && expr->ref
9519         && expr->ref->type == REF_ARRAY
9520         && expr->ref->u.ar.type == AR_FULL)
9521     return true;
9522
9523   /* All that can be left are allocatable components.  */
9524   if ((sym->ts.type != BT_DERIVED
9525        && sym->ts.type != BT_CLASS)
9526         || !sym->ts.u.derived->attr.alloc_comp)
9527     return false;
9528
9529   /* Find a component ref followed by an array reference.  */
9530   for (ref = expr->ref; ref; ref = ref->next)
9531     if (ref->next
9532           && ref->type == REF_COMPONENT
9533           && ref->next->type == REF_ARRAY
9534           && !ref->next->next)
9535       break;
9536
9537   if (!ref)
9538     return false;
9539
9540   /* Return true if valid reallocatable lhs.  */
9541   if (ref->u.c.component->attr.allocatable
9542         && ref->next->u.ar.type == AR_FULL)
9543     return true;
9544
9545   return false;
9546 }
9547
9548
9549 static tree
9550 concat_str_length (gfc_expr* expr)
9551 {
9552   tree type;
9553   tree len1;
9554   tree len2;
9555   gfc_se se;
9556
9557   type = gfc_typenode_for_spec (&expr->value.op.op1->ts);
9558   len1 = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
9559   if (len1 == NULL_TREE)
9560     {
9561       if (expr->value.op.op1->expr_type == EXPR_OP)
9562         len1 = concat_str_length (expr->value.op.op1);
9563       else if (expr->value.op.op1->expr_type == EXPR_CONSTANT)
9564         len1 = build_int_cst (gfc_charlen_type_node,
9565                         expr->value.op.op1->value.character.length);
9566       else if (expr->value.op.op1->ts.u.cl->length)
9567         {
9568           gfc_init_se (&se, NULL);
9569           gfc_conv_expr (&se, expr->value.op.op1->ts.u.cl->length);
9570           len1 = se.expr;
9571         }
9572       else
9573         {
9574           /* Last resort!  */
9575           gfc_init_se (&se, NULL);
9576           se.want_pointer = 1;
9577           se.descriptor_only = 1;
9578           gfc_conv_expr (&se, expr->value.op.op1);
9579           len1 = se.string_length;
9580         }
9581     }
9582
9583   type = gfc_typenode_for_spec (&expr->value.op.op2->ts);
9584   len2 = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
9585   if (len2 == NULL_TREE)
9586     {
9587       if (expr->value.op.op2->expr_type == EXPR_OP)
9588         len2 = concat_str_length (expr->value.op.op2);
9589       else if (expr->value.op.op2->expr_type == EXPR_CONSTANT)
9590         len2 = build_int_cst (gfc_charlen_type_node,
9591                         expr->value.op.op2->value.character.length);
9592       else if (expr->value.op.op2->ts.u.cl->length)
9593         {
9594           gfc_init_se (&se, NULL);
9595           gfc_conv_expr (&se, expr->value.op.op2->ts.u.cl->length);
9596           len2 = se.expr;
9597         }
9598       else
9599         {
9600           /* Last resort!  */
9601           gfc_init_se (&se, NULL);
9602           se.want_pointer = 1;
9603           se.descriptor_only = 1;
9604           gfc_conv_expr (&se, expr->value.op.op2);
9605           len2 = se.string_length;
9606         }
9607     }
9608
9609   gcc_assert(len1 && len2);
9610   len1 = fold_convert (gfc_charlen_type_node, len1);
9611   len2 = fold_convert (gfc_charlen_type_node, len2);
9612
9613   return fold_build2_loc (input_location, PLUS_EXPR,
9614                           gfc_charlen_type_node, len1, len2);
9615 }
9616
9617
9618 /* Allocate the lhs of an assignment to an allocatable array, otherwise
9619    reallocate it.  */
9620
9621 tree
9622 gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
9623                                       gfc_expr *expr1,
9624                                       gfc_expr *expr2)
9625 {
9626   stmtblock_t realloc_block;
9627   stmtblock_t alloc_block;
9628   stmtblock_t fblock;
9629   gfc_ss *rss;
9630   gfc_ss *lss;
9631   gfc_array_info *linfo;
9632   tree realloc_expr;
9633   tree alloc_expr;
9634   tree size1;
9635   tree size2;
9636   tree array1;
9637   tree cond_null;
9638   tree cond;
9639   tree tmp;
9640   tree tmp2;
9641   tree lbound;
9642   tree ubound;
9643   tree desc;
9644   tree old_desc;
9645   tree desc2;
9646   tree offset;
9647   tree jump_label1;
9648   tree jump_label2;
9649   tree neq_size;
9650   tree lbd;
9651   int n;
9652   int dim;
9653   gfc_array_spec * as;
9654   bool coarray = (flag_coarray == GFC_FCOARRAY_LIB
9655                   && gfc_caf_attr (expr1, true).codimension);
9656   tree token;
9657   gfc_se caf_se;
9658
9659   /* x = f(...) with x allocatable.  In this case, expr1 is the rhs.
9660      Find the lhs expression in the loop chain and set expr1 and
9661      expr2 accordingly.  */
9662   if (expr1->expr_type == EXPR_FUNCTION && expr2 == NULL)
9663     {
9664       expr2 = expr1;
9665       /* Find the ss for the lhs.  */
9666       lss = loop->ss;
9667       for (; lss && lss != gfc_ss_terminator; lss = lss->loop_chain)
9668         if (lss->info->expr && lss->info->expr->expr_type == EXPR_VARIABLE)
9669           break;
9670       if (lss == gfc_ss_terminator)
9671         return NULL_TREE;
9672       expr1 = lss->info->expr;
9673     }
9674
9675   /* Bail out if this is not a valid allocate on assignment.  */
9676   if (!gfc_is_reallocatable_lhs (expr1)
9677         || (expr2 && !expr2->rank))
9678     return NULL_TREE;
9679
9680   /* Find the ss for the lhs.  */
9681   lss = loop->ss;
9682   for (; lss && lss != gfc_ss_terminator; lss = lss->loop_chain)
9683     if (lss->info->expr == expr1)
9684       break;
9685
9686   if (lss == gfc_ss_terminator)
9687     return NULL_TREE;
9688
9689   linfo = &lss->info->data.array;
9690
9691   /* Find an ss for the rhs. For operator expressions, we see the
9692      ss's for the operands. Any one of these will do.  */
9693   rss = loop->ss;
9694   for (; rss && rss != gfc_ss_terminator; rss = rss->loop_chain)
9695     if (rss->info->expr != expr1 && rss != loop->temp_ss)
9696       break;
9697
9698   if (expr2 && rss == gfc_ss_terminator)
9699     return NULL_TREE;
9700
9701   /* Ensure that the string length from the current scope is used.  */
9702   if (expr2->ts.type == BT_CHARACTER
9703       && expr2->expr_type == EXPR_FUNCTION
9704       && !expr2->value.function.isym)
9705     expr2->ts.u.cl->backend_decl = rss->info->string_length;
9706
9707   gfc_start_block (&fblock);
9708
9709   /* Since the lhs is allocatable, this must be a descriptor type.
9710      Get the data and array size.  */
9711   desc = linfo->descriptor;
9712   gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)));
9713   array1 = gfc_conv_descriptor_data_get (desc);
9714
9715   /* 7.4.1.3 "If variable is an allocated allocatable variable, it is
9716      deallocated if expr is an array of different shape or any of the
9717      corresponding length type parameter values of variable and expr
9718      differ."  This assures F95 compatibility.  */
9719   jump_label1 = gfc_build_label_decl (NULL_TREE);
9720   jump_label2 = gfc_build_label_decl (NULL_TREE);
9721
9722   /* Allocate if data is NULL.  */
9723   cond_null = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
9724                          array1, build_int_cst (TREE_TYPE (array1), 0));
9725
9726   if (expr1->ts.deferred)
9727     cond_null = gfc_evaluate_now (logical_true_node, &fblock);
9728   else
9729     cond_null= gfc_evaluate_now (cond_null, &fblock);
9730
9731   tmp = build3_v (COND_EXPR, cond_null,
9732                   build1_v (GOTO_EXPR, jump_label1),
9733                   build_empty_stmt (input_location));
9734   gfc_add_expr_to_block (&fblock, tmp);
9735
9736   /* Get arrayspec if expr is a full array.  */
9737   if (expr2 && expr2->expr_type == EXPR_FUNCTION
9738         && expr2->value.function.isym
9739         && expr2->value.function.isym->conversion)
9740     {
9741       /* For conversion functions, take the arg.  */
9742       gfc_expr *arg = expr2->value.function.actual->expr;
9743       as = gfc_get_full_arrayspec_from_expr (arg);
9744     }
9745   else if (expr2)
9746     as = gfc_get_full_arrayspec_from_expr (expr2);
9747   else
9748     as = NULL;
9749
9750   /* If the lhs shape is not the same as the rhs jump to setting the
9751      bounds and doing the reallocation.......  */
9752   for (n = 0; n < expr1->rank; n++)
9753     {
9754       /* Check the shape.  */
9755       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
9756       ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
9757       tmp = fold_build2_loc (input_location, MINUS_EXPR,
9758                              gfc_array_index_type,
9759                              loop->to[n], loop->from[n]);
9760       tmp = fold_build2_loc (input_location, PLUS_EXPR,
9761                              gfc_array_index_type,
9762                              tmp, lbound);
9763       tmp = fold_build2_loc (input_location, MINUS_EXPR,
9764                              gfc_array_index_type,
9765                              tmp, ubound);
9766       cond = fold_build2_loc (input_location, NE_EXPR,
9767                               logical_type_node,
9768                               tmp, gfc_index_zero_node);
9769       tmp = build3_v (COND_EXPR, cond,
9770                       build1_v (GOTO_EXPR, jump_label1),
9771                       build_empty_stmt (input_location));
9772       gfc_add_expr_to_block (&fblock, tmp);
9773     }
9774
9775   /* ....else jump past the (re)alloc code.  */
9776   tmp = build1_v (GOTO_EXPR, jump_label2);
9777   gfc_add_expr_to_block (&fblock, tmp);
9778
9779   /* Add the label to start automatic (re)allocation.  */
9780   tmp = build1_v (LABEL_EXPR, jump_label1);
9781   gfc_add_expr_to_block (&fblock, tmp);
9782
9783   /* If the lhs has not been allocated, its bounds will not have been
9784      initialized and so its size is set to zero.  */
9785   size1 = gfc_create_var (gfc_array_index_type, NULL);
9786   gfc_init_block (&alloc_block);
9787   gfc_add_modify (&alloc_block, size1, gfc_index_zero_node);
9788   gfc_init_block (&realloc_block);
9789   gfc_add_modify (&realloc_block, size1,
9790                   gfc_conv_descriptor_size (desc, expr1->rank));
9791   tmp = build3_v (COND_EXPR, cond_null,
9792                   gfc_finish_block (&alloc_block),
9793                   gfc_finish_block (&realloc_block));
9794   gfc_add_expr_to_block (&fblock, tmp);
9795
9796   /* Get the rhs size and fix it.  */
9797   if (expr2)
9798     desc2 = rss->info->data.array.descriptor;
9799   else
9800     desc2 = NULL_TREE;
9801
9802   size2 = gfc_index_one_node;
9803   for (n = 0; n < expr2->rank; n++)
9804     {
9805       tmp = fold_build2_loc (input_location, MINUS_EXPR,
9806                              gfc_array_index_type,
9807                              loop->to[n], loop->from[n]);
9808       tmp = fold_build2_loc (input_location, PLUS_EXPR,
9809                              gfc_array_index_type,
9810                              tmp, gfc_index_one_node);
9811       size2 = fold_build2_loc (input_location, MULT_EXPR,
9812                                gfc_array_index_type,
9813                                tmp, size2);
9814     }
9815   size2 = gfc_evaluate_now (size2, &fblock);
9816
9817   cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
9818                           size1, size2);
9819
9820   /* If the lhs is deferred length, assume that the element size
9821      changes and force a reallocation.  */
9822   if (expr1->ts.deferred)
9823     neq_size = gfc_evaluate_now (logical_true_node, &fblock);
9824   else
9825     neq_size = gfc_evaluate_now (cond, &fblock);
9826
9827   /* Deallocation of allocatable components will have to occur on
9828      reallocation.  Fix the old descriptor now.  */
9829   if ((expr1->ts.type == BT_DERIVED)
9830         && expr1->ts.u.derived->attr.alloc_comp)
9831     old_desc = gfc_evaluate_now (desc, &fblock);
9832   else
9833     old_desc = NULL_TREE;
9834
9835   /* Now modify the lhs descriptor and the associated scalarizer
9836      variables. F2003 7.4.1.3: "If variable is or becomes an
9837      unallocated allocatable variable, then it is allocated with each
9838      deferred type parameter equal to the corresponding type parameters
9839      of expr , with the shape of expr , and with each lower bound equal
9840      to the corresponding element of LBOUND(expr)."
9841      Reuse size1 to keep a dimension-by-dimension track of the
9842      stride of the new array.  */
9843   size1 = gfc_index_one_node;
9844   offset = gfc_index_zero_node;
9845
9846   for (n = 0; n < expr2->rank; n++)
9847     {
9848       tmp = fold_build2_loc (input_location, MINUS_EXPR,
9849                              gfc_array_index_type,
9850                              loop->to[n], loop->from[n]);
9851       tmp = fold_build2_loc (input_location, PLUS_EXPR,
9852                              gfc_array_index_type,
9853                              tmp, gfc_index_one_node);
9854
9855       lbound = gfc_index_one_node;
9856       ubound = tmp;
9857
9858       if (as)
9859         {
9860           lbd = get_std_lbound (expr2, desc2, n,
9861                                 as->type == AS_ASSUMED_SIZE);
9862           ubound = fold_build2_loc (input_location,
9863                                     MINUS_EXPR,
9864                                     gfc_array_index_type,
9865                                     ubound, lbound);
9866           ubound = fold_build2_loc (input_location,
9867                                     PLUS_EXPR,
9868                                     gfc_array_index_type,
9869                                     ubound, lbd);
9870           lbound = lbd;
9871         }
9872
9873       gfc_conv_descriptor_lbound_set (&fblock, desc,
9874                                       gfc_rank_cst[n],
9875                                       lbound);
9876       gfc_conv_descriptor_ubound_set (&fblock, desc,
9877                                       gfc_rank_cst[n],
9878                                       ubound);
9879       gfc_conv_descriptor_stride_set (&fblock, desc,
9880                                       gfc_rank_cst[n],
9881                                       size1);
9882       lbound = gfc_conv_descriptor_lbound_get (desc,
9883                                                gfc_rank_cst[n]);
9884       tmp2 = fold_build2_loc (input_location, MULT_EXPR,
9885                               gfc_array_index_type,
9886                               lbound, size1);
9887       offset = fold_build2_loc (input_location, MINUS_EXPR,
9888                                 gfc_array_index_type,
9889                                 offset, tmp2);
9890       size1 = fold_build2_loc (input_location, MULT_EXPR,
9891                                gfc_array_index_type,
9892                                tmp, size1);
9893     }
9894
9895   /* Set the lhs descriptor and scalarizer offsets.  For rank > 1,
9896      the array offset is saved and the info.offset is used for a
9897      running offset.  Use the saved_offset instead.  */
9898   tmp = gfc_conv_descriptor_offset (desc);
9899   gfc_add_modify (&fblock, tmp, offset);
9900   if (linfo->saved_offset
9901       && VAR_P (linfo->saved_offset))
9902     gfc_add_modify (&fblock, linfo->saved_offset, tmp);
9903
9904   /* Now set the deltas for the lhs.  */
9905   for (n = 0; n < expr1->rank; n++)
9906     {
9907       tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
9908       dim = lss->dim[n];
9909       tmp = fold_build2_loc (input_location, MINUS_EXPR,
9910                              gfc_array_index_type, tmp,
9911                              loop->from[dim]);
9912       if (linfo->delta[dim] && VAR_P (linfo->delta[dim]))
9913         gfc_add_modify (&fblock, linfo->delta[dim], tmp);
9914     }
9915
9916   /* Get the new lhs size in bytes.  */
9917   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
9918     {
9919       if (expr2->ts.deferred)
9920         {
9921           if (VAR_P (expr2->ts.u.cl->backend_decl))
9922             tmp = expr2->ts.u.cl->backend_decl;
9923           else
9924             tmp = rss->info->string_length;
9925         }
9926       else
9927         {
9928           tmp = expr2->ts.u.cl->backend_decl;
9929           if (!tmp && expr2->expr_type == EXPR_OP
9930               && expr2->value.op.op == INTRINSIC_CONCAT)
9931             {
9932               tmp = concat_str_length (expr2);
9933               expr2->ts.u.cl->backend_decl = gfc_evaluate_now (tmp, &fblock);
9934             }
9935           tmp = fold_convert (TREE_TYPE (expr1->ts.u.cl->backend_decl), tmp);
9936         }
9937
9938       if (expr1->ts.u.cl->backend_decl
9939           && VAR_P (expr1->ts.u.cl->backend_decl))
9940         gfc_add_modify (&fblock, expr1->ts.u.cl->backend_decl, tmp);
9941       else
9942         gfc_add_modify (&fblock, lss->info->string_length, tmp);
9943     }
9944   else if (expr1->ts.type == BT_CHARACTER && expr1->ts.u.cl->backend_decl)
9945     {
9946       tmp = TYPE_SIZE_UNIT (TREE_TYPE (gfc_typenode_for_spec (&expr1->ts)));
9947       tmp = fold_build2_loc (input_location, MULT_EXPR,
9948                              gfc_array_index_type, tmp,
9949                              expr1->ts.u.cl->backend_decl);
9950     }
9951   else
9952     tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr1->ts));
9953   tmp = fold_convert (gfc_array_index_type, tmp);
9954   size2 = fold_build2_loc (input_location, MULT_EXPR,
9955                            gfc_array_index_type,
9956                            tmp, size2);
9957   size2 = fold_convert (size_type_node, size2);
9958   size2 = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
9959                            size2, size_one_node);
9960   size2 = gfc_evaluate_now (size2, &fblock);
9961
9962   /* For deferred character length, the 'size' field of the dtype might
9963      have changed so set the dtype.  */
9964   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))
9965       && expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
9966     {
9967       tree type;
9968       tmp = gfc_conv_descriptor_dtype (desc);
9969       if (expr2->ts.u.cl->backend_decl)
9970         type = gfc_typenode_for_spec (&expr2->ts);
9971       else
9972         type = gfc_typenode_for_spec (&expr1->ts);
9973
9974       gfc_add_modify (&fblock, tmp,
9975                       gfc_get_dtype_rank_type (expr1->rank,type));
9976     }
9977   else if (coarray && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
9978     {
9979       gfc_add_modify (&fblock, gfc_conv_descriptor_dtype (desc),
9980                       gfc_get_dtype (TREE_TYPE (desc)));
9981     }
9982
9983   /* Realloc expression.  Note that the scalarizer uses desc.data
9984      in the array reference - (*desc.data)[<element>].  */
9985   gfc_init_block (&realloc_block);
9986   gfc_init_se (&caf_se, NULL);
9987
9988   if (coarray)
9989     {
9990       token = gfc_get_ultimate_alloc_ptr_comps_caf_token (&caf_se, expr1);
9991       if (token == NULL_TREE)
9992         {
9993           tmp = gfc_get_tree_for_caf_expr (expr1);
9994           if (POINTER_TYPE_P (TREE_TYPE (tmp)))
9995             tmp = build_fold_indirect_ref (tmp);
9996           gfc_get_caf_token_offset (&caf_se, &token, NULL, tmp, NULL_TREE,
9997                                     expr1);
9998           token = gfc_build_addr_expr (NULL_TREE, token);
9999         }
10000
10001       gfc_add_block_to_block (&realloc_block, &caf_se.pre);
10002     }
10003   if ((expr1->ts.type == BT_DERIVED)
10004         && expr1->ts.u.derived->attr.alloc_comp)
10005     {
10006       tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, old_desc,
10007                                               expr1->rank);
10008       gfc_add_expr_to_block (&realloc_block, tmp);
10009     }
10010
10011   if (!coarray)
10012     {
10013       tmp = build_call_expr_loc (input_location,
10014                                  builtin_decl_explicit (BUILT_IN_REALLOC), 2,
10015                                  fold_convert (pvoid_type_node, array1),
10016                                  size2);
10017       gfc_conv_descriptor_data_set (&realloc_block,
10018                                     desc, tmp);
10019     }
10020   else
10021     {
10022       tmp = build_call_expr_loc (input_location,
10023                                  gfor_fndecl_caf_deregister, 5, token,
10024                                  build_int_cst (integer_type_node,
10025                                                GFC_CAF_COARRAY_DEALLOCATE_ONLY),
10026                                  null_pointer_node, null_pointer_node,
10027                                  integer_zero_node);
10028       gfc_add_expr_to_block (&realloc_block, tmp);
10029       tmp = build_call_expr_loc (input_location,
10030                                  gfor_fndecl_caf_register,
10031                                  7, size2,
10032                                  build_int_cst (integer_type_node,
10033                                            GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY),
10034                                  token, gfc_build_addr_expr (NULL_TREE, desc),
10035                                  null_pointer_node, null_pointer_node,
10036                                  integer_zero_node);
10037       gfc_add_expr_to_block (&realloc_block, tmp);
10038     }
10039
10040   if ((expr1->ts.type == BT_DERIVED)
10041         && expr1->ts.u.derived->attr.alloc_comp)
10042     {
10043       tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, desc,
10044                                     expr1->rank);
10045       gfc_add_expr_to_block (&realloc_block, tmp);
10046     }
10047
10048   gfc_add_block_to_block (&realloc_block, &caf_se.post);
10049   realloc_expr = gfc_finish_block (&realloc_block);
10050
10051   /* Only reallocate if sizes are different.  */
10052   tmp = build3_v (COND_EXPR, neq_size, realloc_expr,
10053                   build_empty_stmt (input_location));
10054   realloc_expr = tmp;
10055
10056
10057   /* Malloc expression.  */
10058   gfc_init_block (&alloc_block);
10059   if (!coarray)
10060     {
10061       tmp = build_call_expr_loc (input_location,
10062                                  builtin_decl_explicit (BUILT_IN_MALLOC),
10063                                  1, size2);
10064       gfc_conv_descriptor_data_set (&alloc_block,
10065                                     desc, tmp);
10066     }
10067   else
10068     {
10069       tmp = build_call_expr_loc (input_location,
10070                                  gfor_fndecl_caf_register,
10071                                  7, size2,
10072                                  build_int_cst (integer_type_node,
10073                                                 GFC_CAF_COARRAY_ALLOC),
10074                                  token, gfc_build_addr_expr (NULL_TREE, desc),
10075                                  null_pointer_node, null_pointer_node,
10076                                  integer_zero_node);
10077       gfc_add_expr_to_block (&alloc_block, tmp);
10078     }
10079
10080
10081   /* We already set the dtype in the case of deferred character
10082      length arrays.  */
10083   if (!(GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))
10084         && ((expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10085             || coarray)))
10086     {
10087       tmp = gfc_conv_descriptor_dtype (desc);
10088       gfc_add_modify (&alloc_block, tmp, gfc_get_dtype (TREE_TYPE (desc)));
10089     }
10090
10091   if ((expr1->ts.type == BT_DERIVED)
10092         && expr1->ts.u.derived->attr.alloc_comp)
10093     {
10094       tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, desc,
10095                                     expr1->rank);
10096       gfc_add_expr_to_block (&alloc_block, tmp);
10097     }
10098   alloc_expr = gfc_finish_block (&alloc_block);
10099
10100   /* Malloc if not allocated; realloc otherwise.  */
10101   tmp = build_int_cst (TREE_TYPE (array1), 0);
10102   cond = fold_build2_loc (input_location, EQ_EXPR,
10103                           logical_type_node,
10104                           array1, tmp);
10105   tmp = build3_v (COND_EXPR, cond, alloc_expr, realloc_expr);
10106   gfc_add_expr_to_block (&fblock, tmp);
10107
10108   /* Make sure that the scalarizer data pointer is updated.  */
10109   if (linfo->data && VAR_P (linfo->data))
10110     {
10111       tmp = gfc_conv_descriptor_data_get (desc);
10112       gfc_add_modify (&fblock, linfo->data, tmp);
10113     }
10114
10115   /* Add the exit label.  */
10116   tmp = build1_v (LABEL_EXPR, jump_label2);
10117   gfc_add_expr_to_block (&fblock, tmp);
10118
10119   return gfc_finish_block (&fblock);
10120 }
10121
10122
10123 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
10124    Do likewise, recursively if necessary, with the allocatable components of
10125    derived types.  */
10126
10127 void
10128 gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block)
10129 {
10130   tree type;
10131   tree tmp;
10132   tree descriptor;
10133   stmtblock_t init;
10134   stmtblock_t cleanup;
10135   locus loc;
10136   int rank;
10137   bool sym_has_alloc_comp, has_finalizer;
10138
10139   sym_has_alloc_comp = (sym->ts.type == BT_DERIVED
10140                         || sym->ts.type == BT_CLASS)
10141                           && sym->ts.u.derived->attr.alloc_comp;
10142   has_finalizer = sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED
10143                    ? gfc_is_finalizable (sym->ts.u.derived, NULL) : false;
10144
10145   /* Make sure the frontend gets these right.  */
10146   gcc_assert (sym->attr.pointer || sym->attr.allocatable || sym_has_alloc_comp
10147               || has_finalizer);
10148
10149   gfc_save_backend_locus (&loc);
10150   gfc_set_backend_locus (&sym->declared_at);
10151   gfc_init_block (&init);
10152
10153   gcc_assert (VAR_P (sym->backend_decl)
10154               || TREE_CODE (sym->backend_decl) == PARM_DECL);
10155
10156   if (sym->ts.type == BT_CHARACTER
10157       && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
10158     {
10159       gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
10160       gfc_trans_vla_type_sizes (sym, &init);
10161     }
10162
10163   /* Dummy, use associated and result variables don't need anything special.  */
10164   if (sym->attr.dummy || sym->attr.use_assoc || sym->attr.result)
10165     {
10166       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
10167       gfc_restore_backend_locus (&loc);
10168       return;
10169     }
10170
10171   descriptor = sym->backend_decl;
10172
10173   /* Although static, derived types with default initializers and
10174      allocatable components must not be nulled wholesale; instead they
10175      are treated component by component.  */
10176   if (TREE_STATIC (descriptor) && !sym_has_alloc_comp && !has_finalizer)
10177     {
10178       /* SAVEd variables are not freed on exit.  */
10179       gfc_trans_static_array_pointer (sym);
10180
10181       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
10182       gfc_restore_backend_locus (&loc);
10183       return;
10184     }
10185
10186   /* Get the descriptor type.  */
10187   type = TREE_TYPE (sym->backend_decl);
10188
10189   if ((sym_has_alloc_comp || (has_finalizer && sym->ts.type != BT_CLASS))
10190       && !(sym->attr.pointer || sym->attr.allocatable))
10191     {
10192       if (!sym->attr.save
10193           && !(TREE_STATIC (sym->backend_decl) && sym->attr.is_main_program))
10194         {
10195           if (sym->value == NULL
10196               || !gfc_has_default_initializer (sym->ts.u.derived))
10197             {
10198               rank = sym->as ? sym->as->rank : 0;
10199               tmp = gfc_nullify_alloc_comp (sym->ts.u.derived,
10200                                             descriptor, rank);
10201               gfc_add_expr_to_block (&init, tmp);
10202             }
10203           else
10204             gfc_init_default_dt (sym, &init, false);
10205         }
10206     }
10207   else if (!GFC_DESCRIPTOR_TYPE_P (type))
10208     {
10209       /* If the backend_decl is not a descriptor, we must have a pointer
10210          to one.  */
10211       descriptor = build_fold_indirect_ref_loc (input_location,
10212                                                 sym->backend_decl);
10213       type = TREE_TYPE (descriptor);
10214     }
10215
10216   /* NULLIFY the data pointer, for non-saved allocatables.  */
10217   if (GFC_DESCRIPTOR_TYPE_P (type) && !sym->attr.save && sym->attr.allocatable)
10218     {
10219       gfc_conv_descriptor_data_set (&init, descriptor, null_pointer_node);
10220       if (flag_coarray == GFC_FCOARRAY_LIB && sym->attr.codimension)
10221         {
10222           /* Declare the variable static so its array descriptor stays present
10223              after leaving the scope.  It may still be accessed through another
10224              image.  This may happen, for example, with the caf_mpi
10225              implementation.  */
10226           TREE_STATIC (descriptor) = 1;
10227           tmp = gfc_conv_descriptor_token (descriptor);
10228           gfc_add_modify (&init, tmp, fold_convert (TREE_TYPE (tmp),
10229                                                     null_pointer_node));
10230         }
10231     }
10232
10233   gfc_restore_backend_locus (&loc);
10234   gfc_init_block (&cleanup);
10235
10236   /* Allocatable arrays need to be freed when they go out of scope.
10237      The allocatable components of pointers must not be touched.  */
10238   if (!sym->attr.allocatable && has_finalizer && sym->ts.type != BT_CLASS
10239       && !sym->attr.pointer && !sym->attr.artificial && !sym->attr.save
10240       && !sym->ns->proc_name->attr.is_main_program)
10241     {
10242       gfc_expr *e;
10243       sym->attr.referenced = 1;
10244       e = gfc_lval_expr_from_sym (sym);
10245       gfc_add_finalizer_call (&cleanup, e);
10246       gfc_free_expr (e);
10247     }
10248   else if ((!sym->attr.allocatable || !has_finalizer)
10249       && sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
10250       && !sym->attr.pointer && !sym->attr.save
10251       && !sym->ns->proc_name->attr.is_main_program)
10252     {
10253       int rank;
10254       rank = sym->as ? sym->as->rank : 0;
10255       tmp = gfc_deallocate_alloc_comp (sym->ts.u.derived, descriptor, rank);
10256       gfc_add_expr_to_block (&cleanup, tmp);
10257     }
10258
10259   if (sym->attr.allocatable && (sym->attr.dimension || sym->attr.codimension)
10260       && !sym->attr.save && !sym->attr.result
10261       && !sym->ns->proc_name->attr.is_main_program)
10262     {
10263       gfc_expr *e;
10264       e = has_finalizer ? gfc_lval_expr_from_sym (sym) : NULL;
10265       tmp = gfc_deallocate_with_status (sym->backend_decl, NULL_TREE, NULL_TREE,
10266                                         NULL_TREE, NULL_TREE, true, e,
10267                                         sym->attr.codimension
10268                                         ? GFC_CAF_COARRAY_DEREGISTER
10269                                         : GFC_CAF_COARRAY_NOCOARRAY);
10270       if (e)
10271         gfc_free_expr (e);
10272       gfc_add_expr_to_block (&cleanup, tmp);
10273     }
10274
10275   gfc_add_init_cleanup (block, gfc_finish_block (&init),
10276                         gfc_finish_block (&cleanup));
10277 }
10278
10279 /************ Expression Walking Functions ******************/
10280
10281 /* Walk a variable reference.
10282
10283    Possible extension - multiple component subscripts.
10284     x(:,:) = foo%a(:)%b(:)
10285    Transforms to
10286     forall (i=..., j=...)
10287       x(i,j) = foo%a(j)%b(i)
10288     end forall
10289    This adds a fair amount of complexity because you need to deal with more
10290    than one ref.  Maybe handle in a similar manner to vector subscripts.
10291    Maybe not worth the effort.  */
10292
10293
10294 static gfc_ss *
10295 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
10296 {
10297   gfc_ref *ref;
10298
10299   for (ref = expr->ref; ref; ref = ref->next)
10300     if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
10301       break;
10302
10303   return gfc_walk_array_ref (ss, expr, ref);
10304 }
10305
10306
10307 gfc_ss *
10308 gfc_walk_array_ref (gfc_ss * ss, gfc_expr * expr, gfc_ref * ref)
10309 {
10310   gfc_array_ref *ar;
10311   gfc_ss *newss;
10312   int n;
10313
10314   for (; ref; ref = ref->next)
10315     {
10316       if (ref->type == REF_SUBSTRING)
10317         {
10318           ss = gfc_get_scalar_ss (ss, ref->u.ss.start);
10319           ss = gfc_get_scalar_ss (ss, ref->u.ss.end);
10320         }
10321
10322       /* We're only interested in array sections from now on.  */
10323       if (ref->type != REF_ARRAY)
10324         continue;
10325
10326       ar = &ref->u.ar;
10327
10328       switch (ar->type)
10329         {
10330         case AR_ELEMENT:
10331           for (n = ar->dimen - 1; n >= 0; n--)
10332             ss = gfc_get_scalar_ss (ss, ar->start[n]);
10333           break;
10334
10335         case AR_FULL:
10336           newss = gfc_get_array_ss (ss, expr, ar->as->rank, GFC_SS_SECTION);
10337           newss->info->data.array.ref = ref;
10338
10339           /* Make sure array is the same as array(:,:), this way
10340              we don't need to special case all the time.  */
10341           ar->dimen = ar->as->rank;
10342           for (n = 0; n < ar->dimen; n++)
10343             {
10344               ar->dimen_type[n] = DIMEN_RANGE;
10345
10346               gcc_assert (ar->start[n] == NULL);
10347               gcc_assert (ar->end[n] == NULL);
10348               gcc_assert (ar->stride[n] == NULL);
10349             }
10350           ss = newss;
10351           break;
10352
10353         case AR_SECTION:
10354           newss = gfc_get_array_ss (ss, expr, 0, GFC_SS_SECTION);
10355           newss->info->data.array.ref = ref;
10356
10357           /* We add SS chains for all the subscripts in the section.  */
10358           for (n = 0; n < ar->dimen; n++)
10359             {
10360               gfc_ss *indexss;
10361
10362               switch (ar->dimen_type[n])
10363                 {
10364                 case DIMEN_ELEMENT:
10365                   /* Add SS for elemental (scalar) subscripts.  */
10366                   gcc_assert (ar->start[n]);
10367                   indexss = gfc_get_scalar_ss (gfc_ss_terminator, ar->start[n]);
10368                   indexss->loop_chain = gfc_ss_terminator;
10369                   newss->info->data.array.subscript[n] = indexss;
10370                   break;
10371
10372                 case DIMEN_RANGE:
10373                   /* We don't add anything for sections, just remember this
10374                      dimension for later.  */
10375                   newss->dim[newss->dimen] = n;
10376                   newss->dimen++;
10377                   break;
10378
10379                 case DIMEN_VECTOR:
10380                   /* Create a GFC_SS_VECTOR index in which we can store
10381                      the vector's descriptor.  */
10382                   indexss = gfc_get_array_ss (gfc_ss_terminator, ar->start[n],
10383                                               1, GFC_SS_VECTOR);
10384                   indexss->loop_chain = gfc_ss_terminator;
10385                   newss->info->data.array.subscript[n] = indexss;
10386                   newss->dim[newss->dimen] = n;
10387                   newss->dimen++;
10388                   break;
10389
10390                 default:
10391                   /* We should know what sort of section it is by now.  */
10392                   gcc_unreachable ();
10393                 }
10394             }
10395           /* We should have at least one non-elemental dimension,
10396              unless we are creating a descriptor for a (scalar) coarray.  */
10397           gcc_assert (newss->dimen > 0
10398                       || newss->info->data.array.ref->u.ar.as->corank > 0);
10399           ss = newss;
10400           break;
10401
10402         default:
10403           /* We should know what sort of section it is by now.  */
10404           gcc_unreachable ();
10405         }
10406
10407     }
10408   return ss;
10409 }
10410
10411
10412 /* Walk an expression operator. If only one operand of a binary expression is
10413    scalar, we must also add the scalar term to the SS chain.  */
10414
10415 static gfc_ss *
10416 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
10417 {
10418   gfc_ss *head;
10419   gfc_ss *head2;
10420
10421   head = gfc_walk_subexpr (ss, expr->value.op.op1);
10422   if (expr->value.op.op2 == NULL)
10423     head2 = head;
10424   else
10425     head2 = gfc_walk_subexpr (head, expr->value.op.op2);
10426
10427   /* All operands are scalar.  Pass back and let the caller deal with it.  */
10428   if (head2 == ss)
10429     return head2;
10430
10431   /* All operands require scalarization.  */
10432   if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
10433     return head2;
10434
10435   /* One of the operands needs scalarization, the other is scalar.
10436      Create a gfc_ss for the scalar expression.  */
10437   if (head == ss)
10438     {
10439       /* First operand is scalar.  We build the chain in reverse order, so
10440          add the scalar SS after the second operand.  */
10441       head = head2;
10442       while (head && head->next != ss)
10443         head = head->next;
10444       /* Check we haven't somehow broken the chain.  */
10445       gcc_assert (head);
10446       head->next = gfc_get_scalar_ss (ss, expr->value.op.op1);
10447     }
10448   else                          /* head2 == head */
10449     {
10450       gcc_assert (head2 == head);
10451       /* Second operand is scalar.  */
10452       head2 = gfc_get_scalar_ss (head2, expr->value.op.op2);
10453     }
10454
10455   return head2;
10456 }
10457
10458
10459 /* Reverse a SS chain.  */
10460
10461 gfc_ss *
10462 gfc_reverse_ss (gfc_ss * ss)
10463 {
10464   gfc_ss *next;
10465   gfc_ss *head;
10466
10467   gcc_assert (ss != NULL);
10468
10469   head = gfc_ss_terminator;
10470   while (ss != gfc_ss_terminator)
10471     {
10472       next = ss->next;
10473       /* Check we didn't somehow break the chain.  */
10474       gcc_assert (next != NULL);
10475       ss->next = head;
10476       head = ss;
10477       ss = next;
10478     }
10479
10480   return (head);
10481 }
10482
10483
10484 /* Given an expression referring to a procedure, return the symbol of its
10485    interface.  We can't get the procedure symbol directly as we have to handle
10486    the case of (deferred) type-bound procedures.  */
10487
10488 gfc_symbol *
10489 gfc_get_proc_ifc_for_expr (gfc_expr *procedure_ref)
10490 {
10491   gfc_symbol *sym;
10492   gfc_ref *ref;
10493
10494   if (procedure_ref == NULL)
10495     return NULL;
10496
10497   /* Normal procedure case.  */
10498   if (procedure_ref->expr_type == EXPR_FUNCTION
10499       && procedure_ref->value.function.esym)
10500     sym = procedure_ref->value.function.esym;
10501   else
10502     sym = procedure_ref->symtree->n.sym;
10503
10504   /* Typebound procedure case.  */
10505   for (ref = procedure_ref->ref; ref; ref = ref->next)
10506     {
10507       if (ref->type == REF_COMPONENT
10508           && ref->u.c.component->attr.proc_pointer)
10509         sym = ref->u.c.component->ts.interface;
10510       else
10511         sym = NULL;
10512     }
10513
10514   return sym;
10515 }
10516
10517
10518 /* Walk the arguments of an elemental function.
10519    PROC_EXPR is used to check whether an argument is permitted to be absent.  If
10520    it is NULL, we don't do the check and the argument is assumed to be present.
10521 */
10522
10523 gfc_ss *
10524 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
10525                                   gfc_symbol *proc_ifc, gfc_ss_type type)
10526 {
10527   gfc_formal_arglist *dummy_arg;
10528   int scalar;
10529   gfc_ss *head;
10530   gfc_ss *tail;
10531   gfc_ss *newss;
10532
10533   head = gfc_ss_terminator;
10534   tail = NULL;
10535
10536   if (proc_ifc)
10537     dummy_arg = gfc_sym_get_dummy_args (proc_ifc);
10538   else
10539     dummy_arg = NULL;
10540
10541   scalar = 1;
10542   for (; arg; arg = arg->next)
10543     {
10544       if (!arg->expr || arg->expr->expr_type == EXPR_NULL)
10545         goto loop_continue;
10546
10547       newss = gfc_walk_subexpr (head, arg->expr);
10548       if (newss == head)
10549         {
10550           /* Scalar argument.  */
10551           gcc_assert (type == GFC_SS_SCALAR || type == GFC_SS_REFERENCE);
10552           newss = gfc_get_scalar_ss (head, arg->expr);
10553           newss->info->type = type;
10554           if (dummy_arg)
10555             newss->info->data.scalar.dummy_arg = dummy_arg->sym;
10556         }
10557       else
10558         scalar = 0;
10559
10560       if (dummy_arg != NULL
10561           && dummy_arg->sym->attr.optional
10562           && arg->expr->expr_type == EXPR_VARIABLE
10563           && (gfc_expr_attr (arg->expr).optional
10564               || gfc_expr_attr (arg->expr).allocatable
10565               || gfc_expr_attr (arg->expr).pointer))
10566         newss->info->can_be_null_ref = true;
10567
10568       head = newss;
10569       if (!tail)
10570         {
10571           tail = head;
10572           while (tail->next != gfc_ss_terminator)
10573             tail = tail->next;
10574         }
10575
10576 loop_continue:
10577       if (dummy_arg != NULL)
10578         dummy_arg = dummy_arg->next;
10579     }
10580
10581   if (scalar)
10582     {
10583       /* If all the arguments are scalar we don't need the argument SS.  */
10584       gfc_free_ss_chain (head);
10585       /* Pass it back.  */
10586       return ss;
10587     }
10588
10589   /* Add it onto the existing chain.  */
10590   tail->next = ss;
10591   return head;
10592 }
10593
10594
10595 /* Walk a function call.  Scalar functions are passed back, and taken out of
10596    scalarization loops.  For elemental functions we walk their arguments.
10597    The result of functions returning arrays is stored in a temporary outside
10598    the loop, so that the function is only called once.  Hence we do not need
10599    to walk their arguments.  */
10600
10601 static gfc_ss *
10602 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
10603 {
10604   gfc_intrinsic_sym *isym;
10605   gfc_symbol *sym;
10606   gfc_component *comp = NULL;
10607
10608   isym = expr->value.function.isym;
10609
10610   /* Handle intrinsic functions separately.  */
10611   if (isym)
10612     return gfc_walk_intrinsic_function (ss, expr, isym);
10613
10614   sym = expr->value.function.esym;
10615   if (!sym)
10616     sym = expr->symtree->n.sym;
10617
10618   if (gfc_is_class_array_function (expr))
10619     return gfc_get_array_ss (ss, expr,
10620                              CLASS_DATA (expr->value.function.esym->result)->as->rank,
10621                              GFC_SS_FUNCTION);
10622
10623   /* A function that returns arrays.  */
10624   comp = gfc_get_proc_ptr_comp (expr);
10625   if ((!comp && gfc_return_by_reference (sym) && sym->result->attr.dimension)
10626       || (comp && comp->attr.dimension))
10627     return gfc_get_array_ss (ss, expr, expr->rank, GFC_SS_FUNCTION);
10628
10629   /* Walk the parameters of an elemental function.  For now we always pass
10630      by reference.  */
10631   if (sym->attr.elemental || (comp && comp->attr.elemental))
10632     {
10633       gfc_ss *old_ss = ss;
10634
10635       ss = gfc_walk_elemental_function_args (old_ss,
10636                                              expr->value.function.actual,
10637                                              gfc_get_proc_ifc_for_expr (expr),
10638                                              GFC_SS_REFERENCE);
10639       if (ss != old_ss
10640           && (comp
10641               || sym->attr.proc_pointer
10642               || sym->attr.if_source != IFSRC_DECL
10643               || sym->attr.array_outer_dependency))
10644         ss->info->array_outer_dependency = 1;
10645     }
10646
10647   /* Scalar functions are OK as these are evaluated outside the scalarization
10648      loop.  Pass back and let the caller deal with it.  */
10649   return ss;
10650 }
10651
10652
10653 /* An array temporary is constructed for array constructors.  */
10654
10655 static gfc_ss *
10656 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
10657 {
10658   return gfc_get_array_ss (ss, expr, expr->rank, GFC_SS_CONSTRUCTOR);
10659 }
10660
10661
10662 /* Walk an expression.  Add walked expressions to the head of the SS chain.
10663    A wholly scalar expression will not be added.  */
10664
10665 gfc_ss *
10666 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
10667 {
10668   gfc_ss *head;
10669
10670   switch (expr->expr_type)
10671     {
10672     case EXPR_VARIABLE:
10673       head = gfc_walk_variable_expr (ss, expr);
10674       return head;
10675
10676     case EXPR_OP:
10677       head = gfc_walk_op_expr (ss, expr);
10678       return head;
10679
10680     case EXPR_FUNCTION:
10681       head = gfc_walk_function_expr (ss, expr);
10682       return head;
10683
10684     case EXPR_CONSTANT:
10685     case EXPR_NULL:
10686     case EXPR_STRUCTURE:
10687       /* Pass back and let the caller deal with it.  */
10688       break;
10689
10690     case EXPR_ARRAY:
10691       head = gfc_walk_array_constructor (ss, expr);
10692       return head;
10693
10694     case EXPR_SUBSTRING:
10695       /* Pass back and let the caller deal with it.  */
10696       break;
10697
10698     default:
10699       gfc_internal_error ("bad expression type during walk (%d)",
10700                       expr->expr_type);
10701     }
10702   return ss;
10703 }
10704
10705
10706 /* Entry point for expression walking.
10707    A return value equal to the passed chain means this is
10708    a scalar expression.  It is up to the caller to take whatever action is
10709    necessary to translate these.  */
10710
10711 gfc_ss *
10712 gfc_walk_expr (gfc_expr * expr)
10713 {
10714   gfc_ss *res;
10715
10716   res = gfc_walk_subexpr (gfc_ss_terminator, expr);
10717   return gfc_reverse_ss (res);
10718 }