OSDN Git Service

2007-11-18 Paul Thomas <pault@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-array.c
1 /* Array translation routines
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3    Free Software Foundation, Inc.
4    Contributed by Paul Brook <paul@nowt.org>
5    and Steven Bosscher <s.bosscher@student.tudelft.nl>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 /* trans-array.c-- Various array related code, including scalarization,
24                    allocation, initialization and other support routines.  */
25
26 /* How the scalarizer works.
27    In gfortran, array expressions use the same core routines as scalar
28    expressions.
29    First, a Scalarization State (SS) chain is built.  This is done by walking
30    the expression tree, and building a linear list of the terms in the
31    expression.  As the tree is walked, scalar subexpressions are translated.
32
33    The scalarization parameters are stored in a gfc_loopinfo structure.
34    First the start and stride of each term is calculated by
35    gfc_conv_ss_startstride.  During this process the expressions for the array
36    descriptors and data pointers are also translated.
37
38    If the expression is an assignment, we must then resolve any dependencies.
39    In fortran all the rhs values of an assignment must be evaluated before
40    any assignments take place.  This can require a temporary array to store the
41    values.  We also require a temporary when we are passing array expressions
42    or vector subecripts as procedure parameters.
43
44    Array sections are passed without copying to a temporary.  These use the
45    scalarizer to determine the shape of the section.  The flag
46    loop->array_parameter tells the scalarizer that the actual values and loop
47    variables will not be required.
48
49    The function gfc_conv_loop_setup generates the scalarization setup code.
50    It determines the range of the scalarizing loop variables.  If a temporary
51    is required, this is created and initialized.  Code for scalar expressions
52    taken outside the loop is also generated at this time.  Next the offset and
53    scaling required to translate from loop variables to array indices for each
54    term is calculated.
55
56    A call to gfc_start_scalarized_body marks the start of the scalarized
57    expression.  This creates a scope and declares the loop variables.  Before
58    calling this gfc_make_ss_chain_used must be used to indicate which terms
59    will be used inside this loop.
60
61    The scalar gfc_conv_* functions are then used to build the main body of the
62    scalarization loop.  Scalarization loop variables and precalculated scalar
63    values are automatically substituted.  Note that gfc_advance_se_ss_chain
64    must be used, rather than changing the se->ss directly.
65
66    For assignment expressions requiring a temporary two sub loops are
67    generated.  The first stores the result of the expression in the temporary,
68    the second copies it to the result.  A call to
69    gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
70    the start of the copying loop.  The temporary may be less than full rank.
71
72    Finally gfc_trans_scalarizing_loops is called to generate the implicit do
73    loops.  The loops are added to the pre chain of the loopinfo.  The post
74    chain may still contain cleanup code.
75
76    After the loop code has been added into its parent scope gfc_cleanup_loop
77    is called to free all the SS allocated by the scalarizer.  */
78
79 #include "config.h"
80 #include "system.h"
81 #include "coretypes.h"
82 #include "tree.h"
83 #include "tree-gimple.h"
84 #include "ggc.h"
85 #include "toplev.h"
86 #include "real.h"
87 #include "flags.h"
88 #include "gfortran.h"
89 #include "trans.h"
90 #include "trans-stmt.h"
91 #include "trans-types.h"
92 #include "trans-array.h"
93 #include "trans-const.h"
94 #include "dependency.h"
95
96 static gfc_ss *gfc_walk_subexpr (gfc_ss *, gfc_expr *);
97 static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor *);
98
99 /* The contents of this structure aren't actually used, just the address.  */
100 static gfc_ss gfc_ss_terminator_var;
101 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
102
103
104 static tree
105 gfc_array_dataptr_type (tree desc)
106 {
107   return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
108 }
109
110
111 /* Build expressions to access the members of an array descriptor.
112    It's surprisingly easy to mess up here, so never access
113    an array descriptor by "brute force", always use these
114    functions.  This also avoids problems if we change the format
115    of an array descriptor.
116
117    To understand these magic numbers, look at the comments
118    before gfc_build_array_type() in trans-types.c.
119
120    The code within these defines should be the only code which knows the format
121    of an array descriptor.
122
123    Any code just needing to read obtain the bounds of an array should use
124    gfc_conv_array_* rather than the following functions as these will return
125    know constant values, and work with arrays which do not have descriptors.
126
127    Don't forget to #undef these!  */
128
129 #define DATA_FIELD 0
130 #define OFFSET_FIELD 1
131 #define DTYPE_FIELD 2
132 #define DIMENSION_FIELD 3
133
134 #define STRIDE_SUBFIELD 0
135 #define LBOUND_SUBFIELD 1
136 #define UBOUND_SUBFIELD 2
137
138 /* This provides READ-ONLY access to the data field.  The field itself
139    doesn't have the proper type.  */
140
141 tree
142 gfc_conv_descriptor_data_get (tree desc)
143 {
144   tree field, type, t;
145
146   type = TREE_TYPE (desc);
147   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
148
149   field = TYPE_FIELDS (type);
150   gcc_assert (DATA_FIELD == 0);
151
152   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
153   t = fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), t);
154
155   return t;
156 }
157
158 /* This provides WRITE access to the data field.
159
160    TUPLES_P is true if we are generating tuples.
161    
162    This function gets called through the following macros:
163      gfc_conv_descriptor_data_set
164      gfc_conv_descriptor_data_set_tuples.  */
165
166 void
167 gfc_conv_descriptor_data_set_internal (stmtblock_t *block,
168                                        tree desc, tree value,
169                                        bool tuples_p)
170 {
171   tree field, type, t;
172
173   type = TREE_TYPE (desc);
174   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
175
176   field = TYPE_FIELDS (type);
177   gcc_assert (DATA_FIELD == 0);
178
179   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
180   gfc_add_modify (block, t, fold_convert (TREE_TYPE (field), value), tuples_p);
181 }
182
183
184 /* This provides address access to the data field.  This should only be
185    used by array allocation, passing this on to the runtime.  */
186
187 tree
188 gfc_conv_descriptor_data_addr (tree desc)
189 {
190   tree field, type, t;
191
192   type = TREE_TYPE (desc);
193   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
194
195   field = TYPE_FIELDS (type);
196   gcc_assert (DATA_FIELD == 0);
197
198   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
199   return build_fold_addr_expr (t);
200 }
201
202 tree
203 gfc_conv_descriptor_offset (tree desc)
204 {
205   tree type;
206   tree field;
207
208   type = TREE_TYPE (desc);
209   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
210
211   field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
212   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
213
214   return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
215 }
216
217 tree
218 gfc_conv_descriptor_dtype (tree desc)
219 {
220   tree field;
221   tree type;
222
223   type = TREE_TYPE (desc);
224   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
225
226   field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
227   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
228
229   return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
230 }
231
232 static tree
233 gfc_conv_descriptor_dimension (tree desc, tree dim)
234 {
235   tree field;
236   tree type;
237   tree tmp;
238
239   type = TREE_TYPE (desc);
240   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
241
242   field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
243   gcc_assert (field != NULL_TREE
244           && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
245           && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
246
247   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
248   tmp = gfc_build_array_ref (tmp, dim, NULL);
249   return tmp;
250 }
251
252 tree
253 gfc_conv_descriptor_stride (tree desc, tree dim)
254 {
255   tree tmp;
256   tree field;
257
258   tmp = gfc_conv_descriptor_dimension (desc, dim);
259   field = TYPE_FIELDS (TREE_TYPE (tmp));
260   field = gfc_advance_chain (field, STRIDE_SUBFIELD);
261   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
262
263   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
264   return tmp;
265 }
266
267 tree
268 gfc_conv_descriptor_lbound (tree desc, tree dim)
269 {
270   tree tmp;
271   tree field;
272
273   tmp = gfc_conv_descriptor_dimension (desc, dim);
274   field = TYPE_FIELDS (TREE_TYPE (tmp));
275   field = gfc_advance_chain (field, LBOUND_SUBFIELD);
276   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
277
278   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
279   return tmp;
280 }
281
282 tree
283 gfc_conv_descriptor_ubound (tree desc, tree dim)
284 {
285   tree tmp;
286   tree field;
287
288   tmp = gfc_conv_descriptor_dimension (desc, dim);
289   field = TYPE_FIELDS (TREE_TYPE (tmp));
290   field = gfc_advance_chain (field, UBOUND_SUBFIELD);
291   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
292
293   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
294   return tmp;
295 }
296
297
298 /* Build a null array descriptor constructor.  */
299
300 tree
301 gfc_build_null_descriptor (tree type)
302 {
303   tree field;
304   tree tmp;
305
306   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
307   gcc_assert (DATA_FIELD == 0);
308   field = TYPE_FIELDS (type);
309
310   /* Set a NULL data pointer.  */
311   tmp = build_constructor_single (type, field, null_pointer_node);
312   TREE_CONSTANT (tmp) = 1;
313   TREE_INVARIANT (tmp) = 1;
314   /* All other fields are ignored.  */
315
316   return tmp;
317 }
318
319
320 /* Cleanup those #defines.  */
321
322 #undef DATA_FIELD
323 #undef OFFSET_FIELD
324 #undef DTYPE_FIELD
325 #undef DIMENSION_FIELD
326 #undef STRIDE_SUBFIELD
327 #undef LBOUND_SUBFIELD
328 #undef UBOUND_SUBFIELD
329
330
331 /* Mark a SS chain as used.  Flags specifies in which loops the SS is used.
332    flags & 1 = Main loop body.
333    flags & 2 = temp copy loop.  */
334
335 void
336 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
337 {
338   for (; ss != gfc_ss_terminator; ss = ss->next)
339     ss->useflags = flags;
340 }
341
342 static void gfc_free_ss (gfc_ss *);
343
344
345 /* Free a gfc_ss chain.  */
346
347 static void
348 gfc_free_ss_chain (gfc_ss * ss)
349 {
350   gfc_ss *next;
351
352   while (ss != gfc_ss_terminator)
353     {
354       gcc_assert (ss != NULL);
355       next = ss->next;
356       gfc_free_ss (ss);
357       ss = next;
358     }
359 }
360
361
362 /* Free a SS.  */
363
364 static void
365 gfc_free_ss (gfc_ss * ss)
366 {
367   int n;
368
369   switch (ss->type)
370     {
371     case GFC_SS_SECTION:
372       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
373         {
374           if (ss->data.info.subscript[n])
375             gfc_free_ss_chain (ss->data.info.subscript[n]);
376         }
377       break;
378
379     default:
380       break;
381     }
382
383   gfc_free (ss);
384 }
385
386
387 /* Free all the SS associated with a loop.  */
388
389 void
390 gfc_cleanup_loop (gfc_loopinfo * loop)
391 {
392   gfc_ss *ss;
393   gfc_ss *next;
394
395   ss = loop->ss;
396   while (ss != gfc_ss_terminator)
397     {
398       gcc_assert (ss != NULL);
399       next = ss->loop_chain;
400       gfc_free_ss (ss);
401       ss = next;
402     }
403 }
404
405
406 /* Associate a SS chain with a loop.  */
407
408 void
409 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
410 {
411   gfc_ss *ss;
412
413   if (head == gfc_ss_terminator)
414     return;
415
416   ss = head;
417   for (; ss && ss != gfc_ss_terminator; ss = ss->next)
418     {
419       if (ss->next == gfc_ss_terminator)
420         ss->loop_chain = loop->ss;
421       else
422         ss->loop_chain = ss->next;
423     }
424   gcc_assert (ss == gfc_ss_terminator);
425   loop->ss = head;
426 }
427
428
429 /* Generate an initializer for a static pointer or allocatable array.  */
430
431 void
432 gfc_trans_static_array_pointer (gfc_symbol * sym)
433 {
434   tree type;
435
436   gcc_assert (TREE_STATIC (sym->backend_decl));
437   /* Just zero the data member.  */
438   type = TREE_TYPE (sym->backend_decl);
439   DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
440 }
441
442
443 /* If the bounds of SE's loop have not yet been set, see if they can be
444    determined from array spec AS, which is the array spec of a called
445    function.  MAPPING maps the callee's dummy arguments to the values
446    that the caller is passing.  Add any initialization and finalization
447    code to SE.  */
448
449 void
450 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
451                                      gfc_se * se, gfc_array_spec * as)
452 {
453   int n, dim;
454   gfc_se tmpse;
455   tree lower;
456   tree upper;
457   tree tmp;
458
459   if (as && as->type == AS_EXPLICIT)
460     for (dim = 0; dim < se->loop->dimen; dim++)
461       {
462         n = se->loop->order[dim];
463         if (se->loop->to[n] == NULL_TREE)
464           {
465             /* Evaluate the lower bound.  */
466             gfc_init_se (&tmpse, NULL);
467             gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
468             gfc_add_block_to_block (&se->pre, &tmpse.pre);
469             gfc_add_block_to_block (&se->post, &tmpse.post);
470             lower = tmpse.expr;
471
472             /* ...and the upper bound.  */
473             gfc_init_se (&tmpse, NULL);
474             gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
475             gfc_add_block_to_block (&se->pre, &tmpse.pre);
476             gfc_add_block_to_block (&se->post, &tmpse.post);
477             upper = tmpse.expr;
478
479             /* Set the upper bound of the loop to UPPER - LOWER.  */
480             tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, upper, lower);
481             tmp = gfc_evaluate_now (tmp, &se->pre);
482             se->loop->to[n] = tmp;
483           }
484       }
485 }
486
487
488 /* Generate code to allocate an array temporary, or create a variable to
489    hold the data.  If size is NULL, zero the descriptor so that the
490    callee will allocate the array.  If DEALLOC is true, also generate code to
491    free the array afterwards.
492
493    Initialization code is added to PRE and finalization code to POST.
494    DYNAMIC is true if the caller may want to extend the array later
495    using realloc.  This prevents us from putting the array on the stack.  */
496
497 static void
498 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
499                                   gfc_ss_info * info, tree size, tree nelem,
500                                   bool dynamic, bool dealloc)
501 {
502   tree tmp;
503   tree desc;
504   bool onstack;
505
506   desc = info->descriptor;
507   info->offset = gfc_index_zero_node;
508   if (size == NULL_TREE || integer_zerop (size))
509     {
510       /* A callee allocated array.  */
511       gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
512       onstack = FALSE;
513     }
514   else
515     {
516       /* Allocate the temporary.  */
517       onstack = !dynamic && gfc_can_put_var_on_stack (size);
518
519       if (onstack)
520         {
521           /* Make a temporary variable to hold the data.  */
522           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (nelem), nelem,
523                              gfc_index_one_node);
524           tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
525                                   tmp);
526           tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
527                                   tmp);
528           tmp = gfc_create_var (tmp, "A");
529           tmp = build_fold_addr_expr (tmp);
530           gfc_conv_descriptor_data_set (pre, desc, tmp);
531         }
532       else
533         {
534           /* Allocate memory to hold the data.  */
535           tmp = gfc_call_malloc (pre, NULL, size);
536           tmp = gfc_evaluate_now (tmp, pre);
537           gfc_conv_descriptor_data_set (pre, desc, tmp);
538         }
539     }
540   info->data = gfc_conv_descriptor_data_get (desc);
541
542   /* The offset is zero because we create temporaries with a zero
543      lower bound.  */
544   tmp = gfc_conv_descriptor_offset (desc);
545   gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
546
547   if (dealloc && !onstack)
548     {
549       /* Free the temporary.  */
550       tmp = gfc_conv_descriptor_data_get (desc);
551       tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
552       gfc_add_expr_to_block (post, tmp);
553     }
554 }
555
556
557 /* Generate code to create and initialize the descriptor for a temporary
558    array.  This is used for both temporaries needed by the scalarizer, and
559    functions returning arrays.  Adjusts the loop variables to be
560    zero-based, and calculates the loop bounds for callee allocated arrays.
561    Allocate the array unless it's callee allocated (we have a callee
562    allocated array if 'callee_alloc' is true, or if loop->to[n] is
563    NULL_TREE for any n).  Also fills in the descriptor, data and offset
564    fields of info if known.  Returns the size of the array, or NULL for a
565    callee allocated array.
566
567    PRE, POST, DYNAMIC and DEALLOC are as for gfc_trans_allocate_array_storage.
568  */
569
570 tree
571 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
572                              gfc_loopinfo * loop, gfc_ss_info * info,
573                              tree eltype, bool dynamic, bool dealloc,
574                              bool callee_alloc)
575 {
576   tree type;
577   tree desc;
578   tree tmp;
579   tree size;
580   tree nelem;
581   tree cond;
582   tree or_expr;
583   int n;
584   int dim;
585
586   gcc_assert (info->dimen > 0);
587   /* Set the lower bound to zero.  */
588   for (dim = 0; dim < info->dimen; dim++)
589     {
590       n = loop->order[dim];
591       if (n < loop->temp_dim)
592         gcc_assert (integer_zerop (loop->from[n]));
593       else
594         {
595           /* Callee allocated arrays may not have a known bound yet.  */
596           if (loop->to[n])
597               loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
598                                          loop->to[n], loop->from[n]);
599           loop->from[n] = gfc_index_zero_node;
600         }
601
602       info->delta[dim] = gfc_index_zero_node;
603       info->start[dim] = gfc_index_zero_node;
604       info->end[dim] = gfc_index_zero_node;
605       info->stride[dim] = gfc_index_one_node;
606       info->dim[dim] = dim;
607     }
608
609   /* Initialize the descriptor.  */
610   type =
611     gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1);
612   desc = gfc_create_var (type, "atmp");
613   GFC_DECL_PACKED_ARRAY (desc) = 1;
614
615   info->descriptor = desc;
616   size = gfc_index_one_node;
617
618   /* Fill in the array dtype.  */
619   tmp = gfc_conv_descriptor_dtype (desc);
620   gfc_add_modify_expr (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
621
622   /*
623      Fill in the bounds and stride.  This is a packed array, so:
624
625      size = 1;
626      for (n = 0; n < rank; n++)
627        {
628          stride[n] = size
629          delta = ubound[n] + 1 - lbound[n];
630          size = size * delta;
631        }
632      size = size * sizeof(element);
633   */
634
635   or_expr = NULL_TREE;
636
637   for (n = 0; n < info->dimen; n++)
638     {
639       if (loop->to[n] == NULL_TREE)
640         {
641           /* For a callee allocated array express the loop bounds in terms
642              of the descriptor fields.  */
643           tmp = build2 (MINUS_EXPR, gfc_array_index_type,
644                         gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]),
645                         gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]));
646           loop->to[n] = tmp;
647           size = NULL_TREE;
648           continue;
649         }
650         
651       /* Store the stride and bound components in the descriptor.  */
652       tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
653       gfc_add_modify_expr (pre, tmp, size);
654
655       tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
656       gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
657
658       tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
659       gfc_add_modify_expr (pre, tmp, loop->to[n]);
660
661       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
662                          loop->to[n], gfc_index_one_node);
663
664       /* Check whether the size for this dimension is negative.  */
665       cond = fold_build2 (LE_EXPR, boolean_type_node, tmp,
666                           gfc_index_zero_node);
667       cond = gfc_evaluate_now (cond, pre);
668
669       if (n == 0)
670         or_expr = cond;
671       else
672         or_expr = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, or_expr, cond);
673
674       size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
675       size = gfc_evaluate_now (size, pre);
676     }
677
678   /* Get the size of the array.  */
679
680   if (size && !callee_alloc)
681     {
682       /* If or_expr is true, then the extent in at least one
683          dimension is zero and the size is set to zero.  */
684       size = fold_build3 (COND_EXPR, gfc_array_index_type,
685                           or_expr, gfc_index_zero_node, size);
686
687       nelem = size;
688       size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
689                 fold_convert (gfc_array_index_type,
690                               TYPE_SIZE_UNIT (gfc_get_element_type (type))));
691     }
692   else
693     {
694       nelem = size;
695       size = NULL_TREE;
696     }
697
698   gfc_trans_allocate_array_storage (pre, post, info, size, nelem, dynamic,
699                                     dealloc);
700
701   if (info->dimen > loop->temp_dim)
702     loop->temp_dim = info->dimen;
703
704   return size;
705 }
706
707
708 /* Generate code to transpose array EXPR by creating a new descriptor
709    in which the dimension specifications have been reversed.  */
710
711 void
712 gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr)
713 {
714   tree dest, src, dest_index, src_index;
715   gfc_loopinfo *loop;
716   gfc_ss_info *dest_info, *src_info;
717   gfc_ss *dest_ss, *src_ss;
718   gfc_se src_se;
719   int n;
720
721   loop = se->loop;
722
723   src_ss = gfc_walk_expr (expr);
724   dest_ss = se->ss;
725
726   src_info = &src_ss->data.info;
727   dest_info = &dest_ss->data.info;
728   gcc_assert (dest_info->dimen == 2);
729   gcc_assert (src_info->dimen == 2);
730
731   /* Get a descriptor for EXPR.  */
732   gfc_init_se (&src_se, NULL);
733   gfc_conv_expr_descriptor (&src_se, expr, src_ss);
734   gfc_add_block_to_block (&se->pre, &src_se.pre);
735   gfc_add_block_to_block (&se->post, &src_se.post);
736   src = src_se.expr;
737
738   /* Allocate a new descriptor for the return value.  */
739   dest = gfc_create_var (TREE_TYPE (src), "atmp");
740   dest_info->descriptor = dest;
741   se->expr = dest;
742
743   /* Copy across the dtype field.  */
744   gfc_add_modify_expr (&se->pre,
745                        gfc_conv_descriptor_dtype (dest),
746                        gfc_conv_descriptor_dtype (src));
747
748   /* Copy the dimension information, renumbering dimension 1 to 0 and
749      0 to 1.  */
750   for (n = 0; n < 2; n++)
751     {
752       dest_info->delta[n] = gfc_index_zero_node;
753       dest_info->start[n] = gfc_index_zero_node;
754       dest_info->end[n] = gfc_index_zero_node;
755       dest_info->stride[n] = gfc_index_one_node;
756       dest_info->dim[n] = n;
757
758       dest_index = gfc_rank_cst[n];
759       src_index = gfc_rank_cst[1 - n];
760
761       gfc_add_modify_expr (&se->pre,
762                            gfc_conv_descriptor_stride (dest, dest_index),
763                            gfc_conv_descriptor_stride (src, src_index));
764
765       gfc_add_modify_expr (&se->pre,
766                            gfc_conv_descriptor_lbound (dest, dest_index),
767                            gfc_conv_descriptor_lbound (src, src_index));
768
769       gfc_add_modify_expr (&se->pre,
770                            gfc_conv_descriptor_ubound (dest, dest_index),
771                            gfc_conv_descriptor_ubound (src, src_index));
772
773       if (!loop->to[n])
774         {
775           gcc_assert (integer_zerop (loop->from[n]));
776           loop->to[n] = build2 (MINUS_EXPR, gfc_array_index_type,
777                                 gfc_conv_descriptor_ubound (dest, dest_index),
778                                 gfc_conv_descriptor_lbound (dest, dest_index));
779         }
780     }
781
782   /* Copy the data pointer.  */
783   dest_info->data = gfc_conv_descriptor_data_get (src);
784   gfc_conv_descriptor_data_set (&se->pre, dest, dest_info->data);
785
786   /* Copy the offset.  This is not changed by transposition; the top-left
787      element is still at the same offset as before, except where the loop
788      starts at zero.  */
789   if (!integer_zerop (loop->from[0]))
790     dest_info->offset = gfc_conv_descriptor_offset (src);
791   else
792     dest_info->offset = gfc_index_zero_node;
793
794   gfc_add_modify_expr (&se->pre,
795                        gfc_conv_descriptor_offset (dest),
796                        dest_info->offset);
797           
798   if (dest_info->dimen > loop->temp_dim)
799     loop->temp_dim = dest_info->dimen;
800 }
801
802
803 /* Return the number of iterations in a loop that starts at START,
804    ends at END, and has step STEP.  */
805
806 static tree
807 gfc_get_iteration_count (tree start, tree end, tree step)
808 {
809   tree tmp;
810   tree type;
811
812   type = TREE_TYPE (step);
813   tmp = fold_build2 (MINUS_EXPR, type, end, start);
814   tmp = fold_build2 (FLOOR_DIV_EXPR, type, tmp, step);
815   tmp = fold_build2 (PLUS_EXPR, type, tmp, build_int_cst (type, 1));
816   tmp = fold_build2 (MAX_EXPR, type, tmp, build_int_cst (type, 0));
817   return fold_convert (gfc_array_index_type, tmp);
818 }
819
820
821 /* Extend the data in array DESC by EXTRA elements.  */
822
823 static void
824 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
825 {
826   tree arg0, arg1;
827   tree tmp;
828   tree size;
829   tree ubound;
830
831   if (integer_zerop (extra))
832     return;
833
834   ubound = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
835
836   /* Add EXTRA to the upper bound.  */
837   tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, extra);
838   gfc_add_modify_expr (pblock, ubound, tmp);
839
840   /* Get the value of the current data pointer.  */
841   arg0 = gfc_conv_descriptor_data_get (desc);
842
843   /* Calculate the new array size.  */
844   size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
845   tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, gfc_index_one_node);
846   arg1 = build2 (MULT_EXPR, size_type_node, fold_convert (size_type_node, tmp),
847                  fold_convert (size_type_node, size));
848
849   /* Call the realloc() function.  */
850   tmp = gfc_call_realloc (pblock, arg0, arg1);
851   gfc_conv_descriptor_data_set (pblock, desc, tmp);
852 }
853
854
855 /* Return true if the bounds of iterator I can only be determined
856    at run time.  */
857
858 static inline bool
859 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
860 {
861   return (i->start->expr_type != EXPR_CONSTANT
862           || i->end->expr_type != EXPR_CONSTANT
863           || i->step->expr_type != EXPR_CONSTANT);
864 }
865
866
867 /* Split the size of constructor element EXPR into the sum of two terms,
868    one of which can be determined at compile time and one of which must
869    be calculated at run time.  Set *SIZE to the former and return true
870    if the latter might be nonzero.  */
871
872 static bool
873 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
874 {
875   if (expr->expr_type == EXPR_ARRAY)
876     return gfc_get_array_constructor_size (size, expr->value.constructor);
877   else if (expr->rank > 0)
878     {
879       /* Calculate everything at run time.  */
880       mpz_set_ui (*size, 0);
881       return true;
882     }
883   else
884     {
885       /* A single element.  */
886       mpz_set_ui (*size, 1);
887       return false;
888     }
889 }
890
891
892 /* Like gfc_get_array_constructor_element_size, but applied to the whole
893    of array constructor C.  */
894
895 static bool
896 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor * c)
897 {
898   gfc_iterator *i;
899   mpz_t val;
900   mpz_t len;
901   bool dynamic;
902
903   mpz_set_ui (*size, 0);
904   mpz_init (len);
905   mpz_init (val);
906
907   dynamic = false;
908   for (; c; c = c->next)
909     {
910       i = c->iterator;
911       if (i && gfc_iterator_has_dynamic_bounds (i))
912         dynamic = true;
913       else
914         {
915           dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
916           if (i)
917             {
918               /* Multiply the static part of the element size by the
919                  number of iterations.  */
920               mpz_sub (val, i->end->value.integer, i->start->value.integer);
921               mpz_fdiv_q (val, val, i->step->value.integer);
922               mpz_add_ui (val, val, 1);
923               if (mpz_sgn (val) > 0)
924                 mpz_mul (len, len, val);
925               else
926                 mpz_set_ui (len, 0);
927             }
928           mpz_add (*size, *size, len);
929         }
930     }
931   mpz_clear (len);
932   mpz_clear (val);
933   return dynamic;
934 }
935
936
937 /* Make sure offset is a variable.  */
938
939 static void
940 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
941                          tree * offsetvar)
942 {
943   /* We should have already created the offset variable.  We cannot
944      create it here because we may be in an inner scope.  */
945   gcc_assert (*offsetvar != NULL_TREE);
946   gfc_add_modify_expr (pblock, *offsetvar, *poffset);
947   *poffset = *offsetvar;
948   TREE_USED (*offsetvar) = 1;
949 }
950
951
952 /* Assign an element of an array constructor.  */
953
954 static void
955 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
956                               tree offset, gfc_se * se, gfc_expr * expr)
957 {
958   tree tmp;
959
960   gfc_conv_expr (se, expr);
961
962   /* Store the value.  */
963   tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (desc));
964   tmp = gfc_build_array_ref (tmp, offset, NULL);
965   if (expr->ts.type == BT_CHARACTER)
966     {
967       gfc_conv_string_parameter (se);
968       if (POINTER_TYPE_P (TREE_TYPE (tmp)))
969         {
970           /* The temporary is an array of pointers.  */
971           se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
972           gfc_add_modify_expr (&se->pre, tmp, se->expr);
973         }
974       else
975         {
976           /* The temporary is an array of string values.  */
977           tmp = gfc_build_addr_expr (pchar_type_node, tmp);
978           /* We know the temporary and the value will be the same length,
979              so can use memcpy.  */
980           tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
981                                  tmp, se->expr, se->string_length);
982           gfc_add_expr_to_block (&se->pre, tmp);
983         }
984     }
985   else
986     {
987       /* TODO: Should the frontend already have done this conversion?  */
988       se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
989       gfc_add_modify_expr (&se->pre, tmp, se->expr);
990     }
991
992   gfc_add_block_to_block (pblock, &se->pre);
993   gfc_add_block_to_block (pblock, &se->post);
994 }
995
996
997 /* Add the contents of an array to the constructor.  DYNAMIC is as for
998    gfc_trans_array_constructor_value.  */
999
1000 static void
1001 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
1002                                       tree type ATTRIBUTE_UNUSED,
1003                                       tree desc, gfc_expr * expr,
1004                                       tree * poffset, tree * offsetvar,
1005                                       bool dynamic)
1006 {
1007   gfc_se se;
1008   gfc_ss *ss;
1009   gfc_loopinfo loop;
1010   stmtblock_t body;
1011   tree tmp;
1012   tree size;
1013   int n;
1014
1015   /* We need this to be a variable so we can increment it.  */
1016   gfc_put_offset_into_var (pblock, poffset, offsetvar);
1017
1018   gfc_init_se (&se, NULL);
1019
1020   /* Walk the array expression.  */
1021   ss = gfc_walk_expr (expr);
1022   gcc_assert (ss != gfc_ss_terminator);
1023
1024   /* Initialize the scalarizer.  */
1025   gfc_init_loopinfo (&loop);
1026   gfc_add_ss_to_loop (&loop, ss);
1027
1028   /* Initialize the loop.  */
1029   gfc_conv_ss_startstride (&loop);
1030   gfc_conv_loop_setup (&loop);
1031
1032   /* Make sure the constructed array has room for the new data.  */
1033   if (dynamic)
1034     {
1035       /* Set SIZE to the total number of elements in the subarray.  */
1036       size = gfc_index_one_node;
1037       for (n = 0; n < loop.dimen; n++)
1038         {
1039           tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
1040                                          gfc_index_one_node);
1041           size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
1042         }
1043
1044       /* Grow the constructed array by SIZE elements.  */
1045       gfc_grow_array (&loop.pre, desc, size);
1046     }
1047
1048   /* Make the loop body.  */
1049   gfc_mark_ss_chain_used (ss, 1);
1050   gfc_start_scalarized_body (&loop, &body);
1051   gfc_copy_loopinfo_to_se (&se, &loop);
1052   se.ss = ss;
1053
1054   gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
1055   gcc_assert (se.ss == gfc_ss_terminator);
1056
1057   /* Increment the offset.  */
1058   tmp = build2 (PLUS_EXPR, gfc_array_index_type, *poffset, gfc_index_one_node);
1059   gfc_add_modify_expr (&body, *poffset, tmp);
1060
1061   /* Finish the loop.  */
1062   gfc_trans_scalarizing_loops (&loop, &body);
1063   gfc_add_block_to_block (&loop.pre, &loop.post);
1064   tmp = gfc_finish_block (&loop.pre);
1065   gfc_add_expr_to_block (pblock, tmp);
1066
1067   gfc_cleanup_loop (&loop);
1068 }
1069
1070
1071 /* Assign the values to the elements of an array constructor.  DYNAMIC
1072    is true if descriptor DESC only contains enough data for the static
1073    size calculated by gfc_get_array_constructor_size.  When true, memory
1074    for the dynamic parts must be allocated using realloc.  */
1075
1076 static void
1077 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
1078                                    tree desc, gfc_constructor * c,
1079                                    tree * poffset, tree * offsetvar,
1080                                    bool dynamic)
1081 {
1082   tree tmp;
1083   stmtblock_t body;
1084   gfc_se se;
1085   mpz_t size;
1086
1087   mpz_init (size);
1088   for (; c; c = c->next)
1089     {
1090       /* If this is an iterator or an array, the offset must be a variable.  */
1091       if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
1092         gfc_put_offset_into_var (pblock, poffset, offsetvar);
1093
1094       gfc_start_block (&body);
1095
1096       if (c->expr->expr_type == EXPR_ARRAY)
1097         {
1098           /* Array constructors can be nested.  */
1099           gfc_trans_array_constructor_value (&body, type, desc,
1100                                              c->expr->value.constructor,
1101                                              poffset, offsetvar, dynamic);
1102         }
1103       else if (c->expr->rank > 0)
1104         {
1105           gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
1106                                                 poffset, offsetvar, dynamic);
1107         }
1108       else
1109         {
1110           /* This code really upsets the gimplifier so don't bother for now.  */
1111           gfc_constructor *p;
1112           HOST_WIDE_INT n;
1113           HOST_WIDE_INT size;
1114
1115           p = c;
1116           n = 0;
1117           while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1118             {
1119               p = p->next;
1120               n++;
1121             }
1122           if (n < 4)
1123             {
1124               /* Scalar values.  */
1125               gfc_init_se (&se, NULL);
1126               gfc_trans_array_ctor_element (&body, desc, *poffset,
1127                                             &se, c->expr);
1128
1129               *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1130                                       *poffset, gfc_index_one_node);
1131             }
1132           else
1133             {
1134               /* Collect multiple scalar constants into a constructor.  */
1135               tree list;
1136               tree init;
1137               tree bound;
1138               tree tmptype;
1139
1140               p = c;
1141               list = NULL_TREE;
1142               /* Count the number of consecutive scalar constants.  */
1143               while (p && !(p->iterator
1144                             || p->expr->expr_type != EXPR_CONSTANT))
1145                 {
1146                   gfc_init_se (&se, NULL);
1147                   gfc_conv_constant (&se, p->expr);
1148                   if (p->expr->ts.type == BT_CHARACTER
1149                       && POINTER_TYPE_P (type))
1150                     {
1151                       /* For constant character array constructors we build
1152                          an array of pointers.  */
1153                       se.expr = gfc_build_addr_expr (pchar_type_node,
1154                                                      se.expr);
1155                     }
1156                     
1157                   list = tree_cons (NULL_TREE, se.expr, list);
1158                   c = p;
1159                   p = p->next;
1160                 }
1161
1162               bound = build_int_cst (NULL_TREE, n - 1);
1163               /* Create an array type to hold them.  */
1164               tmptype = build_range_type (gfc_array_index_type,
1165                                           gfc_index_zero_node, bound);
1166               tmptype = build_array_type (type, tmptype);
1167
1168               init = build_constructor_from_list (tmptype, nreverse (list));
1169               TREE_CONSTANT (init) = 1;
1170               TREE_INVARIANT (init) = 1;
1171               TREE_STATIC (init) = 1;
1172               /* Create a static variable to hold the data.  */
1173               tmp = gfc_create_var (tmptype, "data");
1174               TREE_STATIC (tmp) = 1;
1175               TREE_CONSTANT (tmp) = 1;
1176               TREE_INVARIANT (tmp) = 1;
1177               TREE_READONLY (tmp) = 1;
1178               DECL_INITIAL (tmp) = init;
1179               init = tmp;
1180
1181               /* Use BUILTIN_MEMCPY to assign the values.  */
1182               tmp = gfc_conv_descriptor_data_get (desc);
1183               tmp = build_fold_indirect_ref (tmp);
1184               tmp = gfc_build_array_ref (tmp, *poffset, NULL);
1185               tmp = build_fold_addr_expr (tmp);
1186               init = build_fold_addr_expr (init);
1187
1188               size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1189               bound = build_int_cst (NULL_TREE, n * size);
1190               tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
1191                                      tmp, init, bound);
1192               gfc_add_expr_to_block (&body, tmp);
1193
1194               *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1195                                       *poffset,
1196                                       build_int_cst (gfc_array_index_type, n));
1197             }
1198           if (!INTEGER_CST_P (*poffset))
1199             {
1200               gfc_add_modify_expr (&body, *offsetvar, *poffset);
1201               *poffset = *offsetvar;
1202             }
1203         }
1204
1205       /* The frontend should already have done any expansions possible
1206          at compile-time.  */
1207       if (!c->iterator)
1208         {
1209           /* Pass the code as is.  */
1210           tmp = gfc_finish_block (&body);
1211           gfc_add_expr_to_block (pblock, tmp);
1212         }
1213       else
1214         {
1215           /* Build the implied do-loop.  */
1216           tree cond;
1217           tree end;
1218           tree step;
1219           tree loopvar;
1220           tree exit_label;
1221           tree loopbody;
1222           tree tmp2;
1223           tree tmp_loopvar;
1224
1225           loopbody = gfc_finish_block (&body);
1226
1227           gfc_init_se (&se, NULL);
1228           gfc_conv_expr (&se, c->iterator->var);
1229           gfc_add_block_to_block (pblock, &se.pre);
1230           loopvar = se.expr;
1231
1232           /* Make a temporary, store the current value in that
1233              and return it, once the loop is done.  */
1234           tmp_loopvar = gfc_create_var (TREE_TYPE (loopvar), "loopvar");
1235           gfc_add_modify_expr (pblock, tmp_loopvar, loopvar);
1236
1237           /* Initialize the loop.  */
1238           gfc_init_se (&se, NULL);
1239           gfc_conv_expr_val (&se, c->iterator->start);
1240           gfc_add_block_to_block (pblock, &se.pre);
1241           gfc_add_modify_expr (pblock, loopvar, se.expr);
1242
1243           gfc_init_se (&se, NULL);
1244           gfc_conv_expr_val (&se, c->iterator->end);
1245           gfc_add_block_to_block (pblock, &se.pre);
1246           end = gfc_evaluate_now (se.expr, pblock);
1247
1248           gfc_init_se (&se, NULL);
1249           gfc_conv_expr_val (&se, c->iterator->step);
1250           gfc_add_block_to_block (pblock, &se.pre);
1251           step = gfc_evaluate_now (se.expr, pblock);
1252
1253           /* If this array expands dynamically, and the number of iterations
1254              is not constant, we won't have allocated space for the static
1255              part of C->EXPR's size.  Do that now.  */
1256           if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1257             {
1258               /* Get the number of iterations.  */
1259               tmp = gfc_get_iteration_count (loopvar, end, step);
1260
1261               /* Get the static part of C->EXPR's size.  */
1262               gfc_get_array_constructor_element_size (&size, c->expr);
1263               tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1264
1265               /* Grow the array by TMP * TMP2 elements.  */
1266               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, tmp2);
1267               gfc_grow_array (pblock, desc, tmp);
1268             }
1269
1270           /* Generate the loop body.  */
1271           exit_label = gfc_build_label_decl (NULL_TREE);
1272           gfc_start_block (&body);
1273
1274           /* Generate the exit condition.  Depending on the sign of
1275              the step variable we have to generate the correct
1276              comparison.  */
1277           tmp = fold_build2 (GT_EXPR, boolean_type_node, step, 
1278                              build_int_cst (TREE_TYPE (step), 0));
1279           cond = fold_build3 (COND_EXPR, boolean_type_node, tmp,
1280                               build2 (GT_EXPR, boolean_type_node,
1281                                       loopvar, end),
1282                               build2 (LT_EXPR, boolean_type_node,
1283                                       loopvar, end));
1284           tmp = build1_v (GOTO_EXPR, exit_label);
1285           TREE_USED (exit_label) = 1;
1286           tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1287           gfc_add_expr_to_block (&body, tmp);
1288
1289           /* The main loop body.  */
1290           gfc_add_expr_to_block (&body, loopbody);
1291
1292           /* Increase loop variable by step.  */
1293           tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
1294           gfc_add_modify_expr (&body, loopvar, tmp);
1295
1296           /* Finish the loop.  */
1297           tmp = gfc_finish_block (&body);
1298           tmp = build1_v (LOOP_EXPR, tmp);
1299           gfc_add_expr_to_block (pblock, tmp);
1300
1301           /* Add the exit label.  */
1302           tmp = build1_v (LABEL_EXPR, exit_label);
1303           gfc_add_expr_to_block (pblock, tmp);
1304
1305           /* Restore the original value of the loop counter.  */
1306           gfc_add_modify_expr (pblock, loopvar, tmp_loopvar);
1307         }
1308     }
1309   mpz_clear (size);
1310 }
1311
1312
1313 /* Figure out the string length of a variable reference expression.
1314    Used by get_array_ctor_strlen.  */
1315
1316 static void
1317 get_array_ctor_var_strlen (gfc_expr * expr, tree * len)
1318 {
1319   gfc_ref *ref;
1320   gfc_typespec *ts;
1321   mpz_t char_len;
1322
1323   /* Don't bother if we already know the length is a constant.  */
1324   if (*len && INTEGER_CST_P (*len))
1325     return;
1326
1327   ts = &expr->symtree->n.sym->ts;
1328   for (ref = expr->ref; ref; ref = ref->next)
1329     {
1330       switch (ref->type)
1331         {
1332         case REF_ARRAY:
1333           /* Array references don't change the string length.  */
1334           break;
1335
1336         case REF_COMPONENT:
1337           /* Use the length of the component.  */
1338           ts = &ref->u.c.component->ts;
1339           break;
1340
1341         case REF_SUBSTRING:
1342           if (ref->u.ss.start->expr_type != EXPR_CONSTANT
1343               || ref->u.ss.end->expr_type != EXPR_CONSTANT)
1344             break;
1345           mpz_init_set_ui (char_len, 1);
1346           mpz_add (char_len, char_len, ref->u.ss.end->value.integer);
1347           mpz_sub (char_len, char_len, ref->u.ss.start->value.integer);
1348           *len = gfc_conv_mpz_to_tree (char_len,
1349                                        gfc_default_character_kind);
1350           *len = convert (gfc_charlen_type_node, *len);
1351           mpz_clear (char_len);
1352           return;
1353
1354         default:
1355           /* TODO: Substrings are tricky because we can't evaluate the
1356              expression more than once.  For now we just give up, and hope
1357              we can figure it out elsewhere.  */
1358           return;
1359         }
1360     }
1361
1362   *len = ts->cl->backend_decl;
1363 }
1364
1365
1366 /* A catch-all to obtain the string length for anything that is not a
1367    constant, array or variable.  */
1368 static void
1369 get_array_ctor_all_strlen (stmtblock_t *block, gfc_expr *e, tree *len)
1370 {
1371   gfc_se se;
1372   gfc_ss *ss;
1373
1374   /* Don't bother if we already know the length is a constant.  */
1375   if (*len && INTEGER_CST_P (*len))
1376     return;
1377
1378   if (!e->ref && e->ts.cl && e->ts.cl->length
1379         && e->ts.cl->length->expr_type == EXPR_CONSTANT)
1380     {
1381       /* This is easy.  */
1382       gfc_conv_const_charlen (e->ts.cl);
1383       *len = e->ts.cl->backend_decl;
1384     }
1385   else
1386     {
1387       /* Otherwise, be brutal even if inefficient.  */
1388       ss = gfc_walk_expr (e);
1389       gfc_init_se (&se, NULL);
1390
1391       /* No function call, in case of side effects.  */
1392       se.no_function_call = 1;
1393       if (ss == gfc_ss_terminator)
1394         gfc_conv_expr (&se, e);
1395       else
1396         gfc_conv_expr_descriptor (&se, e, ss);
1397
1398       /* Fix the value.  */
1399       *len = gfc_evaluate_now (se.string_length, &se.pre);
1400
1401       gfc_add_block_to_block (block, &se.pre);
1402       gfc_add_block_to_block (block, &se.post);
1403
1404       e->ts.cl->backend_decl = *len;
1405     }
1406 }
1407
1408
1409 /* Figure out the string length of a character array constructor.
1410    Returns TRUE if all elements are character constants.  */
1411
1412 bool
1413 get_array_ctor_strlen (stmtblock_t *block, gfc_constructor * c, tree * len)
1414 {
1415   bool is_const;
1416   tree first_len = NULL_TREE;
1417   
1418   is_const = TRUE;
1419
1420   if (c == NULL)
1421     {
1422       *len = build_int_cstu (gfc_charlen_type_node, 0);
1423       return is_const;
1424     }
1425
1426   for (; c; c = c->next)
1427     {
1428       switch (c->expr->expr_type)
1429         {
1430         case EXPR_CONSTANT:
1431           if (!(*len && INTEGER_CST_P (*len)))
1432             *len = build_int_cstu (gfc_charlen_type_node,
1433                                    c->expr->value.character.length);
1434           break;
1435
1436         case EXPR_ARRAY:
1437           if (!get_array_ctor_strlen (block, c->expr->value.constructor, len))
1438             is_const = false;
1439           break;
1440
1441         case EXPR_VARIABLE:
1442           is_const = false;
1443           get_array_ctor_var_strlen (c->expr, len);
1444           break;
1445
1446         default:
1447           is_const = false;
1448           get_array_ctor_all_strlen (block, c->expr, len);
1449           break;
1450         }
1451       if (flag_bounds_check)
1452         {
1453           if (!first_len)
1454             first_len = *len;
1455           else
1456             {
1457               /* Verify that all constructor elements are of the same
1458                  length.  */
1459               tree cond = fold_build2 (NE_EXPR, boolean_type_node,
1460                                        first_len, *len);
1461               gfc_trans_runtime_check
1462                 (cond, block, &c->expr->where,
1463                  "Different CHARACTER lengths (%ld/%ld) in array constructor",
1464                  fold_convert (long_integer_type_node, first_len),
1465                  fold_convert (long_integer_type_node, *len));
1466             }
1467         }
1468     }
1469
1470   return is_const;
1471 }
1472
1473 /* Check whether the array constructor C consists entirely of constant
1474    elements, and if so returns the number of those elements, otherwise
1475    return zero.  Note, an empty or NULL array constructor returns zero.  */
1476
1477 unsigned HOST_WIDE_INT
1478 gfc_constant_array_constructor_p (gfc_constructor * c)
1479 {
1480   unsigned HOST_WIDE_INT nelem = 0;
1481
1482   while (c)
1483     {
1484       if (c->iterator
1485           || c->expr->rank > 0
1486           || c->expr->expr_type != EXPR_CONSTANT)
1487         return 0;
1488       c = c->next;
1489       nelem++;
1490     }
1491   return nelem;
1492 }
1493
1494
1495 /* Given EXPR, the constant array constructor specified by an EXPR_ARRAY,
1496    and the tree type of it's elements, TYPE, return a static constant
1497    variable that is compile-time initialized.  */
1498
1499 tree
1500 gfc_build_constant_array_constructor (gfc_expr * expr, tree type)
1501 {
1502   tree tmptype, list, init, tmp;
1503   HOST_WIDE_INT nelem;
1504   gfc_constructor *c;
1505   gfc_array_spec as;
1506   gfc_se se;
1507   int i;
1508
1509   /* First traverse the constructor list, converting the constants
1510      to tree to build an initializer.  */
1511   nelem = 0;
1512   list = NULL_TREE;
1513   c = expr->value.constructor;
1514   while (c)
1515     {
1516       gfc_init_se (&se, NULL);
1517       gfc_conv_constant (&se, c->expr);
1518       if (c->expr->ts.type == BT_CHARACTER
1519           && POINTER_TYPE_P (type))
1520         se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
1521       list = tree_cons (NULL_TREE, se.expr, list);
1522       c = c->next;
1523       nelem++;
1524     }
1525
1526   /* Next determine the tree type for the array.  We use the gfortran
1527      front-end's gfc_get_nodesc_array_type in order to create a suitable
1528      GFC_ARRAY_TYPE_P that may be used by the scalarizer.  */
1529
1530   memset (&as, 0, sizeof (gfc_array_spec));
1531
1532   as.rank = expr->rank;
1533   as.type = AS_EXPLICIT;
1534   if (!expr->shape)
1535     {
1536       as.lower[0] = gfc_int_expr (0);
1537       as.upper[0] = gfc_int_expr (nelem - 1);
1538     }
1539   else
1540     for (i = 0; i < expr->rank; i++)
1541       {
1542         int tmp = (int) mpz_get_si (expr->shape[i]);
1543         as.lower[i] = gfc_int_expr (0);
1544         as.upper[i] = gfc_int_expr (tmp - 1);
1545       }
1546
1547   tmptype = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC);
1548
1549   init = build_constructor_from_list (tmptype, nreverse (list));
1550
1551   TREE_CONSTANT (init) = 1;
1552   TREE_INVARIANT (init) = 1;
1553   TREE_STATIC (init) = 1;
1554
1555   tmp = gfc_create_var (tmptype, "A");
1556   TREE_STATIC (tmp) = 1;
1557   TREE_CONSTANT (tmp) = 1;
1558   TREE_INVARIANT (tmp) = 1;
1559   TREE_READONLY (tmp) = 1;
1560   DECL_INITIAL (tmp) = init;
1561
1562   return tmp;
1563 }
1564
1565
1566 /* Translate a constant EXPR_ARRAY array constructor for the scalarizer.
1567    This mostly initializes the scalarizer state info structure with the
1568    appropriate values to directly use the array created by the function
1569    gfc_build_constant_array_constructor.  */
1570
1571 static void
1572 gfc_trans_constant_array_constructor (gfc_loopinfo * loop,
1573                                       gfc_ss * ss, tree type)
1574 {
1575   gfc_ss_info *info;
1576   tree tmp;
1577   int i;
1578
1579   tmp = gfc_build_constant_array_constructor (ss->expr, type);
1580
1581   info = &ss->data.info;
1582
1583   info->descriptor = tmp;
1584   info->data = build_fold_addr_expr (tmp);
1585   info->offset = fold_build1 (NEGATE_EXPR, gfc_array_index_type,
1586                               loop->from[0]);
1587
1588   for (i = 0; i < info->dimen; i++)
1589     {
1590       info->delta[i] = gfc_index_zero_node;
1591       info->start[i] = gfc_index_zero_node;
1592       info->end[i] = gfc_index_zero_node;
1593       info->stride[i] = gfc_index_one_node;
1594       info->dim[i] = i;
1595     }
1596
1597   if (info->dimen > loop->temp_dim)
1598     loop->temp_dim = info->dimen;
1599 }
1600
1601 /* Helper routine of gfc_trans_array_constructor to determine if the
1602    bounds of the loop specified by LOOP are constant and simple enough
1603    to use with gfc_trans_constant_array_constructor.  Returns the
1604    the iteration count of the loop if suitable, and NULL_TREE otherwise.  */
1605
1606 static tree
1607 constant_array_constructor_loop_size (gfc_loopinfo * loop)
1608 {
1609   tree size = gfc_index_one_node;
1610   tree tmp;
1611   int i;
1612
1613   for (i = 0; i < loop->dimen; i++)
1614     {
1615       /* If the bounds aren't constant, return NULL_TREE.  */
1616       if (!INTEGER_CST_P (loop->from[i]) || !INTEGER_CST_P (loop->to[i]))
1617         return NULL_TREE;
1618       if (!integer_zerop (loop->from[i]))
1619         {
1620           /* Only allow nonzero "from" in one-dimensional arrays.  */
1621           if (loop->dimen != 1)
1622             return NULL_TREE;
1623           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1624                              loop->to[i], loop->from[i]);
1625         }
1626       else
1627         tmp = loop->to[i];
1628       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1629                          tmp, gfc_index_one_node);
1630       size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
1631     }
1632
1633   return size;
1634 }
1635
1636
1637 /* Array constructors are handled by constructing a temporary, then using that
1638    within the scalarization loop.  This is not optimal, but seems by far the
1639    simplest method.  */
1640
1641 static void
1642 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
1643 {
1644   gfc_constructor *c;
1645   tree offset;
1646   tree offsetvar;
1647   tree desc;
1648   tree type;
1649   bool dynamic;
1650
1651   ss->data.info.dimen = loop->dimen;
1652
1653   c = ss->expr->value.constructor;
1654   if (ss->expr->ts.type == BT_CHARACTER)
1655     {
1656       bool const_string = get_array_ctor_strlen (&loop->pre, c, &ss->string_length);
1657
1658       /* Complex character array constructors should have been taken care of
1659          and not end up here.  */
1660       gcc_assert (ss->string_length);
1661
1662       ss->expr->ts.cl->backend_decl = ss->string_length;
1663
1664       type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1665       if (const_string)
1666         type = build_pointer_type (type);
1667     }
1668   else
1669     type = gfc_typenode_for_spec (&ss->expr->ts);
1670
1671   /* See if the constructor determines the loop bounds.  */
1672   dynamic = false;
1673
1674   if (ss->expr->shape && loop->dimen > 1 && loop->to[0] == NULL_TREE)
1675     {
1676       /* We have a multidimensional parameter.  */
1677       int n;
1678       for (n = 0; n < ss->expr->rank; n++)
1679       {
1680         loop->from[n] = gfc_index_zero_node;
1681         loop->to[n] = gfc_conv_mpz_to_tree (ss->expr->shape [n],
1682                                             gfc_index_integer_kind);
1683         loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1684                                    loop->to[n], gfc_index_one_node);
1685       }
1686     }
1687
1688   if (loop->to[0] == NULL_TREE)
1689     {
1690       mpz_t size;
1691
1692       /* We should have a 1-dimensional, zero-based loop.  */
1693       gcc_assert (loop->dimen == 1);
1694       gcc_assert (integer_zerop (loop->from[0]));
1695
1696       /* Split the constructor size into a static part and a dynamic part.
1697          Allocate the static size up-front and record whether the dynamic
1698          size might be nonzero.  */
1699       mpz_init (size);
1700       dynamic = gfc_get_array_constructor_size (&size, c);
1701       mpz_sub_ui (size, size, 1);
1702       loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1703       mpz_clear (size);
1704     }
1705
1706   /* Special case constant array constructors.  */
1707   if (!dynamic)
1708     {
1709       unsigned HOST_WIDE_INT nelem = gfc_constant_array_constructor_p (c);
1710       if (nelem > 0)
1711         {
1712           tree size = constant_array_constructor_loop_size (loop);
1713           if (size && compare_tree_int (size, nelem) == 0)
1714             {
1715               gfc_trans_constant_array_constructor (loop, ss, type);
1716               return;
1717             }
1718         }
1719     }
1720
1721   gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, &ss->data.info,
1722                                type, dynamic, true, false);
1723
1724   desc = ss->data.info.descriptor;
1725   offset = gfc_index_zero_node;
1726   offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
1727   TREE_NO_WARNING (offsetvar) = 1;
1728   TREE_USED (offsetvar) = 0;
1729   gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
1730                                      &offset, &offsetvar, dynamic);
1731
1732   /* If the array grows dynamically, the upper bound of the loop variable
1733      is determined by the array's final upper bound.  */
1734   if (dynamic)
1735     loop->to[0] = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
1736
1737   if (TREE_USED (offsetvar))
1738     pushdecl (offsetvar);
1739   else
1740     gcc_assert (INTEGER_CST_P (offset));
1741 #if 0
1742   /* Disable bound checking for now because it's probably broken.  */
1743   if (flag_bounds_check)
1744     {
1745       gcc_unreachable ();
1746     }
1747 #endif
1748 }
1749
1750
1751 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
1752    called after evaluating all of INFO's vector dimensions.  Go through
1753    each such vector dimension and see if we can now fill in any missing
1754    loop bounds.  */
1755
1756 static void
1757 gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info)
1758 {
1759   gfc_se se;
1760   tree tmp;
1761   tree desc;
1762   tree zero;
1763   int n;
1764   int dim;
1765
1766   for (n = 0; n < loop->dimen; n++)
1767     {
1768       dim = info->dim[n];
1769       if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR
1770           && loop->to[n] == NULL)
1771         {
1772           /* Loop variable N indexes vector dimension DIM, and we don't
1773              yet know the upper bound of loop variable N.  Set it to the
1774              difference between the vector's upper and lower bounds.  */
1775           gcc_assert (loop->from[n] == gfc_index_zero_node);
1776           gcc_assert (info->subscript[dim]
1777                       && info->subscript[dim]->type == GFC_SS_VECTOR);
1778
1779           gfc_init_se (&se, NULL);
1780           desc = info->subscript[dim]->data.info.descriptor;
1781           zero = gfc_rank_cst[0];
1782           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1783                              gfc_conv_descriptor_ubound (desc, zero),
1784                              gfc_conv_descriptor_lbound (desc, zero));
1785           tmp = gfc_evaluate_now (tmp, &loop->pre);
1786           loop->to[n] = tmp;
1787         }
1788     }
1789 }
1790
1791
1792 /* Add the pre and post chains for all the scalar expressions in a SS chain
1793    to loop.  This is called after the loop parameters have been calculated,
1794    but before the actual scalarizing loops.  */
1795
1796 static void
1797 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
1798 {
1799   gfc_se se;
1800   int n;
1801
1802   /* TODO: This can generate bad code if there are ordering dependencies.
1803      eg. a callee allocated function and an unknown size constructor.  */
1804   gcc_assert (ss != NULL);
1805
1806   for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
1807     {
1808       gcc_assert (ss);
1809
1810       switch (ss->type)
1811         {
1812         case GFC_SS_SCALAR:
1813           /* Scalar expression.  Evaluate this now.  This includes elemental
1814              dimension indices, but not array section bounds.  */
1815           gfc_init_se (&se, NULL);
1816           gfc_conv_expr (&se, ss->expr);
1817           gfc_add_block_to_block (&loop->pre, &se.pre);
1818
1819           if (ss->expr->ts.type != BT_CHARACTER)
1820             {
1821               /* Move the evaluation of scalar expressions outside the
1822                  scalarization loop.  */
1823               if (subscript)
1824                 se.expr = convert(gfc_array_index_type, se.expr);
1825               se.expr = gfc_evaluate_now (se.expr, &loop->pre);
1826               gfc_add_block_to_block (&loop->pre, &se.post);
1827             }
1828           else
1829             gfc_add_block_to_block (&loop->post, &se.post);
1830
1831           ss->data.scalar.expr = se.expr;
1832           ss->string_length = se.string_length;
1833           break;
1834
1835         case GFC_SS_REFERENCE:
1836           /* Scalar reference.  Evaluate this now.  */
1837           gfc_init_se (&se, NULL);
1838           gfc_conv_expr_reference (&se, ss->expr);
1839           gfc_add_block_to_block (&loop->pre, &se.pre);
1840           gfc_add_block_to_block (&loop->post, &se.post);
1841
1842           ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
1843           ss->string_length = se.string_length;
1844           break;
1845
1846         case GFC_SS_SECTION:
1847           /* Add the expressions for scalar and vector subscripts.  */
1848           for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1849             if (ss->data.info.subscript[n])
1850               gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
1851
1852           gfc_set_vector_loop_bounds (loop, &ss->data.info);
1853           break;
1854
1855         case GFC_SS_VECTOR:
1856           /* Get the vector's descriptor and store it in SS.  */
1857           gfc_init_se (&se, NULL);
1858           gfc_conv_expr_descriptor (&se, ss->expr, gfc_walk_expr (ss->expr));
1859           gfc_add_block_to_block (&loop->pre, &se.pre);
1860           gfc_add_block_to_block (&loop->post, &se.post);
1861           ss->data.info.descriptor = se.expr;
1862           break;
1863
1864         case GFC_SS_INTRINSIC:
1865           gfc_add_intrinsic_ss_code (loop, ss);
1866           break;
1867
1868         case GFC_SS_FUNCTION:
1869           /* Array function return value.  We call the function and save its
1870              result in a temporary for use inside the loop.  */
1871           gfc_init_se (&se, NULL);
1872           se.loop = loop;
1873           se.ss = ss;
1874           gfc_conv_expr (&se, ss->expr);
1875           gfc_add_block_to_block (&loop->pre, &se.pre);
1876           gfc_add_block_to_block (&loop->post, &se.post);
1877           ss->string_length = se.string_length;
1878           break;
1879
1880         case GFC_SS_CONSTRUCTOR:
1881           gfc_trans_array_constructor (loop, ss);
1882           break;
1883
1884         case GFC_SS_TEMP:
1885         case GFC_SS_COMPONENT:
1886           /* Do nothing.  These are handled elsewhere.  */
1887           break;
1888
1889         default:
1890           gcc_unreachable ();
1891         }
1892     }
1893 }
1894
1895
1896 /* Translate expressions for the descriptor and data pointer of a SS.  */
1897 /*GCC ARRAYS*/
1898
1899 static void
1900 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
1901 {
1902   gfc_se se;
1903   tree tmp;
1904
1905   /* Get the descriptor for the array to be scalarized.  */
1906   gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
1907   gfc_init_se (&se, NULL);
1908   se.descriptor_only = 1;
1909   gfc_conv_expr_lhs (&se, ss->expr);
1910   gfc_add_block_to_block (block, &se.pre);
1911   ss->data.info.descriptor = se.expr;
1912   ss->string_length = se.string_length;
1913
1914   if (base)
1915     {
1916       /* Also the data pointer.  */
1917       tmp = gfc_conv_array_data (se.expr);
1918       /* If this is a variable or address of a variable we use it directly.
1919          Otherwise we must evaluate it now to avoid breaking dependency
1920          analysis by pulling the expressions for elemental array indices
1921          inside the loop.  */
1922       if (!(DECL_P (tmp)
1923             || (TREE_CODE (tmp) == ADDR_EXPR
1924                 && DECL_P (TREE_OPERAND (tmp, 0)))))
1925         tmp = gfc_evaluate_now (tmp, block);
1926       ss->data.info.data = tmp;
1927
1928       tmp = gfc_conv_array_offset (se.expr);
1929       ss->data.info.offset = gfc_evaluate_now (tmp, block);
1930     }
1931 }
1932
1933
1934 /* Initialize a gfc_loopinfo structure.  */
1935
1936 void
1937 gfc_init_loopinfo (gfc_loopinfo * loop)
1938 {
1939   int n;
1940
1941   memset (loop, 0, sizeof (gfc_loopinfo));
1942   gfc_init_block (&loop->pre);
1943   gfc_init_block (&loop->post);
1944
1945   /* Initially scalarize in order.  */
1946   for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1947     loop->order[n] = n;
1948
1949   loop->ss = gfc_ss_terminator;
1950 }
1951
1952
1953 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
1954    chain.  */
1955
1956 void
1957 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
1958 {
1959   se->loop = loop;
1960 }
1961
1962
1963 /* Return an expression for the data pointer of an array.  */
1964
1965 tree
1966 gfc_conv_array_data (tree descriptor)
1967 {
1968   tree type;
1969
1970   type = TREE_TYPE (descriptor);
1971   if (GFC_ARRAY_TYPE_P (type))
1972     {
1973       if (TREE_CODE (type) == POINTER_TYPE)
1974         return descriptor;
1975       else
1976         {
1977           /* Descriptorless arrays.  */
1978           return build_fold_addr_expr (descriptor);
1979         }
1980     }
1981   else
1982     return gfc_conv_descriptor_data_get (descriptor);
1983 }
1984
1985
1986 /* Return an expression for the base offset of an array.  */
1987
1988 tree
1989 gfc_conv_array_offset (tree descriptor)
1990 {
1991   tree type;
1992
1993   type = TREE_TYPE (descriptor);
1994   if (GFC_ARRAY_TYPE_P (type))
1995     return GFC_TYPE_ARRAY_OFFSET (type);
1996   else
1997     return gfc_conv_descriptor_offset (descriptor);
1998 }
1999
2000
2001 /* Get an expression for the array stride.  */
2002
2003 tree
2004 gfc_conv_array_stride (tree descriptor, int dim)
2005 {
2006   tree tmp;
2007   tree type;
2008
2009   type = TREE_TYPE (descriptor);
2010
2011   /* For descriptorless arrays use the array size.  */
2012   tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
2013   if (tmp != NULL_TREE)
2014     return tmp;
2015
2016   tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
2017   return tmp;
2018 }
2019
2020
2021 /* Like gfc_conv_array_stride, but for the lower bound.  */
2022
2023 tree
2024 gfc_conv_array_lbound (tree descriptor, int dim)
2025 {
2026   tree tmp;
2027   tree type;
2028
2029   type = TREE_TYPE (descriptor);
2030
2031   tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
2032   if (tmp != NULL_TREE)
2033     return tmp;
2034
2035   tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
2036   return tmp;
2037 }
2038
2039
2040 /* Like gfc_conv_array_stride, but for the upper bound.  */
2041
2042 tree
2043 gfc_conv_array_ubound (tree descriptor, int dim)
2044 {
2045   tree tmp;
2046   tree type;
2047
2048   type = TREE_TYPE (descriptor);
2049
2050   tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
2051   if (tmp != NULL_TREE)
2052     return tmp;
2053
2054   /* This should only ever happen when passing an assumed shape array
2055      as an actual parameter.  The value will never be used.  */
2056   if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
2057     return gfc_index_zero_node;
2058
2059   tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
2060   return tmp;
2061 }
2062
2063
2064 /* Generate code to perform an array index bound check.  */
2065
2066 static tree
2067 gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n,
2068                              locus * where, bool check_upper)
2069 {
2070   tree fault;
2071   tree tmp;
2072   char *msg;
2073   const char * name = NULL;
2074
2075   if (!flag_bounds_check)
2076     return index;
2077
2078   index = gfc_evaluate_now (index, &se->pre);
2079
2080   /* We find a name for the error message.  */
2081   if (se->ss)
2082     name = se->ss->expr->symtree->name;
2083
2084   if (!name && se->loop && se->loop->ss && se->loop->ss->expr
2085       && se->loop->ss->expr->symtree)
2086     name = se->loop->ss->expr->symtree->name;
2087
2088   if (!name && se->loop && se->loop->ss && se->loop->ss->loop_chain
2089       && se->loop->ss->loop_chain->expr
2090       && se->loop->ss->loop_chain->expr->symtree)
2091     name = se->loop->ss->loop_chain->expr->symtree->name;
2092
2093   if (!name && se->loop && se->loop->ss && se->loop->ss->loop_chain
2094       && se->loop->ss->loop_chain->expr->symtree)
2095     name = se->loop->ss->loop_chain->expr->symtree->name;
2096
2097   if (!name && se->loop && se->loop->ss && se->loop->ss->expr)
2098     {
2099       if (se->loop->ss->expr->expr_type == EXPR_FUNCTION
2100           && se->loop->ss->expr->value.function.name)
2101         name = se->loop->ss->expr->value.function.name;
2102       else
2103         if (se->loop->ss->type == GFC_SS_CONSTRUCTOR
2104             || se->loop->ss->type == GFC_SS_SCALAR)
2105           name = "unnamed constant";
2106     }
2107
2108   /* Check lower bound.  */
2109   tmp = gfc_conv_array_lbound (descriptor, n);
2110   fault = fold_build2 (LT_EXPR, boolean_type_node, index, tmp);
2111   if (name)
2112     asprintf (&msg, "%s for array '%s', lower bound of dimension %d exceeded"
2113               "(%%ld < %%ld)", gfc_msg_fault, name, n+1);
2114   else
2115     asprintf (&msg, "%s, lower bound of dimension %d exceeded (%%ld < %%ld)",
2116               gfc_msg_fault, n+1);
2117   gfc_trans_runtime_check (fault, &se->pre, where, msg,
2118                            fold_convert (long_integer_type_node, index),
2119                            fold_convert (long_integer_type_node, tmp));
2120   gfc_free (msg);
2121
2122   /* Check upper bound.  */
2123   if (check_upper)
2124     {
2125       tmp = gfc_conv_array_ubound (descriptor, n);
2126       fault = fold_build2 (GT_EXPR, boolean_type_node, index, tmp);
2127       if (name)
2128         asprintf (&msg, "%s for array '%s', upper bound of dimension %d "
2129                         " exceeded (%%ld > %%ld)", gfc_msg_fault, name, n+1);
2130       else
2131         asprintf (&msg, "%s, upper bound of dimension %d exceeded (%%ld > %%ld)",
2132                   gfc_msg_fault, n+1);
2133       gfc_trans_runtime_check (fault, &se->pre, where, msg,
2134                                fold_convert (long_integer_type_node, index),
2135                                fold_convert (long_integer_type_node, tmp));
2136       gfc_free (msg);
2137     }
2138
2139   return index;
2140 }
2141
2142
2143 /* Return the offset for an index.  Performs bound checking for elemental
2144    dimensions.  Single element references are processed separately.  */
2145
2146 static tree
2147 gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
2148                              gfc_array_ref * ar, tree stride)
2149 {
2150   tree index;
2151   tree desc;
2152   tree data;
2153
2154   /* Get the index into the array for this dimension.  */
2155   if (ar)
2156     {
2157       gcc_assert (ar->type != AR_ELEMENT);
2158       switch (ar->dimen_type[dim])
2159         {
2160         case DIMEN_ELEMENT:
2161           gcc_assert (i == -1);
2162           /* Elemental dimension.  */
2163           gcc_assert (info->subscript[dim]
2164                       && info->subscript[dim]->type == GFC_SS_SCALAR);
2165           /* We've already translated this value outside the loop.  */
2166           index = info->subscript[dim]->data.scalar.expr;
2167
2168           index = gfc_trans_array_bound_check (se, info->descriptor,
2169                         index, dim, &ar->where,
2170                         (ar->as->type != AS_ASSUMED_SIZE
2171                          && !ar->as->cp_was_assumed) || dim < ar->dimen - 1);
2172           break;
2173
2174         case DIMEN_VECTOR:
2175           gcc_assert (info && se->loop);
2176           gcc_assert (info->subscript[dim]
2177                       && info->subscript[dim]->type == GFC_SS_VECTOR);
2178           desc = info->subscript[dim]->data.info.descriptor;
2179
2180           /* Get a zero-based index into the vector.  */
2181           index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2182                                se->loop->loopvar[i], se->loop->from[i]);
2183
2184           /* Multiply the index by the stride.  */
2185           index = fold_build2 (MULT_EXPR, gfc_array_index_type,
2186                                index, gfc_conv_array_stride (desc, 0));
2187
2188           /* Read the vector to get an index into info->descriptor.  */
2189           data = build_fold_indirect_ref (gfc_conv_array_data (desc));
2190           index = gfc_build_array_ref (data, index, NULL);
2191           index = gfc_evaluate_now (index, &se->pre);
2192
2193           /* Do any bounds checking on the final info->descriptor index.  */
2194           index = gfc_trans_array_bound_check (se, info->descriptor,
2195                         index, dim, &ar->where,
2196                         (ar->as->type != AS_ASSUMED_SIZE
2197                          && !ar->as->cp_was_assumed) || dim < ar->dimen - 1);
2198           break;
2199
2200         case DIMEN_RANGE:
2201           /* Scalarized dimension.  */
2202           gcc_assert (info && se->loop);
2203
2204           /* Multiply the loop variable by the stride and delta.  */
2205           index = se->loop->loopvar[i];
2206           if (!integer_onep (info->stride[i]))
2207             index = fold_build2 (MULT_EXPR, gfc_array_index_type, index,
2208                                  info->stride[i]);
2209           if (!integer_zerop (info->delta[i]))
2210             index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index,
2211                                  info->delta[i]);
2212           break;
2213
2214         default:
2215           gcc_unreachable ();
2216         }
2217     }
2218   else
2219     {
2220       /* Temporary array or derived type component.  */
2221       gcc_assert (se->loop);
2222       index = se->loop->loopvar[se->loop->order[i]];
2223       if (!integer_zerop (info->delta[i]))
2224         index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2225                              index, info->delta[i]);
2226     }
2227
2228   /* Multiply by the stride.  */
2229   if (!integer_onep (stride))
2230     index = fold_build2 (MULT_EXPR, gfc_array_index_type, index, stride);
2231
2232   return index;
2233 }
2234
2235
2236 /* Build a scalarized reference to an array.  */
2237
2238 static void
2239 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
2240 {
2241   gfc_ss_info *info;
2242   tree decl = NULL_TREE;
2243   tree index;
2244   tree tmp;
2245   int n;
2246
2247   info = &se->ss->data.info;
2248   if (ar)
2249     n = se->loop->order[0];
2250   else
2251     n = 0;
2252
2253   index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
2254                                        info->stride0);
2255   /* Add the offset for this dimension to the stored offset for all other
2256      dimensions.  */
2257   if (!integer_zerop (info->offset))
2258     index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, info->offset);
2259
2260   if (se->ss->expr && is_subref_array (se->ss->expr))
2261     decl = se->ss->expr->symtree->n.sym->backend_decl;
2262
2263   tmp = build_fold_indirect_ref (info->data);
2264   se->expr = gfc_build_array_ref (tmp, index, decl);
2265 }
2266
2267
2268 /* Translate access of temporary array.  */
2269
2270 void
2271 gfc_conv_tmp_array_ref (gfc_se * se)
2272 {
2273   se->string_length = se->ss->string_length;
2274   gfc_conv_scalarized_array_ref (se, NULL);
2275 }
2276
2277
2278 /* Build an array reference.  se->expr already holds the array descriptor.
2279    This should be either a variable, indirect variable reference or component
2280    reference.  For arrays which do not have a descriptor, se->expr will be
2281    the data pointer.
2282    a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
2283
2284 void
2285 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
2286                     locus * where)
2287 {
2288   int n;
2289   tree index;
2290   tree tmp;
2291   tree stride;
2292   gfc_se indexse;
2293
2294   /* Handle scalarized references separately.  */
2295   if (ar->type != AR_ELEMENT)
2296     {
2297       gfc_conv_scalarized_array_ref (se, ar);
2298       gfc_advance_se_ss_chain (se);
2299       return;
2300     }
2301
2302   index = gfc_index_zero_node;
2303
2304   /* Calculate the offsets from all the dimensions.  */
2305   for (n = 0; n < ar->dimen; n++)
2306     {
2307       /* Calculate the index for this dimension.  */
2308       gfc_init_se (&indexse, se);
2309       gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
2310       gfc_add_block_to_block (&se->pre, &indexse.pre);
2311
2312       if (flag_bounds_check)
2313         {
2314           /* Check array bounds.  */
2315           tree cond;
2316           char *msg;
2317
2318           /* Evaluate the indexse.expr only once.  */
2319           indexse.expr = save_expr (indexse.expr);
2320
2321           /* Lower bound.  */
2322           tmp = gfc_conv_array_lbound (se->expr, n);
2323           cond = fold_build2 (LT_EXPR, boolean_type_node, 
2324                               indexse.expr, tmp);
2325           asprintf (&msg, "%s for array '%s', "
2326                     "lower bound of dimension %d exceeded (%%ld < %%ld)",
2327                     gfc_msg_fault, sym->name, n+1);
2328           gfc_trans_runtime_check (cond, &se->pre, where, msg,
2329                                    fold_convert (long_integer_type_node,
2330                                                  indexse.expr),
2331                                    fold_convert (long_integer_type_node, tmp));
2332           gfc_free (msg);
2333
2334           /* Upper bound, but not for the last dimension of assumed-size
2335              arrays.  */
2336           if (n < ar->dimen - 1
2337               || (ar->as->type != AS_ASSUMED_SIZE && !ar->as->cp_was_assumed))
2338             {
2339               tmp = gfc_conv_array_ubound (se->expr, n);
2340               cond = fold_build2 (GT_EXPR, boolean_type_node, 
2341                                   indexse.expr, tmp);
2342               asprintf (&msg, "%s for array '%s', "
2343                         "upper bound of dimension %d exceeded (%%ld > %%ld)",
2344                         gfc_msg_fault, sym->name, n+1);
2345               gfc_trans_runtime_check (cond, &se->pre, where, msg,
2346                                    fold_convert (long_integer_type_node,
2347                                                  indexse.expr),
2348                                    fold_convert (long_integer_type_node, tmp));
2349               gfc_free (msg);
2350             }
2351         }
2352
2353       /* Multiply the index by the stride.  */
2354       stride = gfc_conv_array_stride (se->expr, n);
2355       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indexse.expr,
2356                          stride);
2357
2358       /* And add it to the total.  */
2359       index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
2360     }
2361
2362   tmp = gfc_conv_array_offset (se->expr);
2363   if (!integer_zerop (tmp))
2364     index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
2365
2366   /* Access the calculated element.  */
2367   tmp = gfc_conv_array_data (se->expr);
2368   tmp = build_fold_indirect_ref (tmp);
2369   se->expr = gfc_build_array_ref (tmp, index, sym->backend_decl);
2370 }
2371
2372
2373 /* Generate the code to be executed immediately before entering a
2374    scalarization loop.  */
2375
2376 static void
2377 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
2378                          stmtblock_t * pblock)
2379 {
2380   tree index;
2381   tree stride;
2382   gfc_ss_info *info;
2383   gfc_ss *ss;
2384   gfc_se se;
2385   int i;
2386
2387   /* This code will be executed before entering the scalarization loop
2388      for this dimension.  */
2389   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2390     {
2391       if ((ss->useflags & flag) == 0)
2392         continue;
2393
2394       if (ss->type != GFC_SS_SECTION
2395           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2396           && ss->type != GFC_SS_COMPONENT)
2397         continue;
2398
2399       info = &ss->data.info;
2400
2401       if (dim >= info->dimen)
2402         continue;
2403
2404       if (dim == info->dimen - 1)
2405         {
2406           /* For the outermost loop calculate the offset due to any
2407              elemental dimensions.  It will have been initialized with the
2408              base offset of the array.  */
2409           if (info->ref)
2410             {
2411               for (i = 0; i < info->ref->u.ar.dimen; i++)
2412                 {
2413                   if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
2414                     continue;
2415
2416                   gfc_init_se (&se, NULL);
2417                   se.loop = loop;
2418                   se.expr = info->descriptor;
2419                   stride = gfc_conv_array_stride (info->descriptor, i);
2420                   index = gfc_conv_array_index_offset (&se, info, i, -1,
2421                                                        &info->ref->u.ar,
2422                                                        stride);
2423                   gfc_add_block_to_block (pblock, &se.pre);
2424
2425                   info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2426                                               info->offset, index);
2427                   info->offset = gfc_evaluate_now (info->offset, pblock);
2428                 }
2429
2430               i = loop->order[0];
2431               stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2432             }
2433           else
2434             stride = gfc_conv_array_stride (info->descriptor, 0);
2435
2436           /* Calculate the stride of the innermost loop.  Hopefully this will
2437              allow the backend optimizers to do their stuff more effectively.
2438            */
2439           info->stride0 = gfc_evaluate_now (stride, pblock);
2440         }
2441       else
2442         {
2443           /* Add the offset for the previous loop dimension.  */
2444           gfc_array_ref *ar;
2445
2446           if (info->ref)
2447             {
2448               ar = &info->ref->u.ar;
2449               i = loop->order[dim + 1];
2450             }
2451           else
2452             {
2453               ar = NULL;
2454               i = dim + 1;
2455             }
2456
2457           gfc_init_se (&se, NULL);
2458           se.loop = loop;
2459           se.expr = info->descriptor;
2460           stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2461           index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
2462                                                ar, stride);
2463           gfc_add_block_to_block (pblock, &se.pre);
2464           info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2465                                       info->offset, index);
2466           info->offset = gfc_evaluate_now (info->offset, pblock);
2467         }
2468
2469       /* Remember this offset for the second loop.  */
2470       if (dim == loop->temp_dim - 1)
2471         info->saved_offset = info->offset;
2472     }
2473 }
2474
2475
2476 /* Start a scalarized expression.  Creates a scope and declares loop
2477    variables.  */
2478
2479 void
2480 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
2481 {
2482   int dim;
2483   int n;
2484   int flags;
2485
2486   gcc_assert (!loop->array_parameter);
2487
2488   for (dim = loop->dimen - 1; dim >= 0; dim--)
2489     {
2490       n = loop->order[dim];
2491
2492       gfc_start_block (&loop->code[n]);
2493
2494       /* Create the loop variable.  */
2495       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
2496
2497       if (dim < loop->temp_dim)
2498         flags = 3;
2499       else
2500         flags = 1;
2501       /* Calculate values that will be constant within this loop.  */
2502       gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
2503     }
2504   gfc_start_block (pbody);
2505 }
2506
2507
2508 /* Generates the actual loop code for a scalarization loop.  */
2509
2510 static void
2511 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
2512                                stmtblock_t * pbody)
2513 {
2514   stmtblock_t block;
2515   tree cond;
2516   tree tmp;
2517   tree loopbody;
2518   tree exit_label;
2519
2520   loopbody = gfc_finish_block (pbody);
2521
2522   /* Initialize the loopvar.  */
2523   gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
2524
2525   exit_label = gfc_build_label_decl (NULL_TREE);
2526
2527   /* Generate the loop body.  */
2528   gfc_init_block (&block);
2529
2530   /* The exit condition.  */
2531   cond = build2 (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);
2532   tmp = build1_v (GOTO_EXPR, exit_label);
2533   TREE_USED (exit_label) = 1;
2534   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2535   gfc_add_expr_to_block (&block, tmp);
2536
2537   /* The main body.  */
2538   gfc_add_expr_to_block (&block, loopbody);
2539
2540   /* Increment the loopvar.  */
2541   tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2542                 loop->loopvar[n], gfc_index_one_node);
2543   gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
2544
2545   /* Build the loop.  */
2546   tmp = gfc_finish_block (&block);
2547   tmp = build1_v (LOOP_EXPR, tmp);
2548   gfc_add_expr_to_block (&loop->code[n], tmp);
2549
2550   /* Add the exit label.  */
2551   tmp = build1_v (LABEL_EXPR, exit_label);
2552   gfc_add_expr_to_block (&loop->code[n], tmp);
2553 }
2554
2555
2556 /* Finishes and generates the loops for a scalarized expression.  */
2557
2558 void
2559 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
2560 {
2561   int dim;
2562   int n;
2563   gfc_ss *ss;
2564   stmtblock_t *pblock;
2565   tree tmp;
2566
2567   pblock = body;
2568   /* Generate the loops.  */
2569   for (dim = 0; dim < loop->dimen; dim++)
2570     {
2571       n = loop->order[dim];
2572       gfc_trans_scalarized_loop_end (loop, n, pblock);
2573       loop->loopvar[n] = NULL_TREE;
2574       pblock = &loop->code[n];
2575     }
2576
2577   tmp = gfc_finish_block (pblock);
2578   gfc_add_expr_to_block (&loop->pre, tmp);
2579
2580   /* Clear all the used flags.  */
2581   for (ss = loop->ss; ss; ss = ss->loop_chain)
2582     ss->useflags = 0;
2583 }
2584
2585
2586 /* Finish the main body of a scalarized expression, and start the secondary
2587    copying body.  */
2588
2589 void
2590 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
2591 {
2592   int dim;
2593   int n;
2594   stmtblock_t *pblock;
2595   gfc_ss *ss;
2596
2597   pblock = body;
2598   /* We finish as many loops as are used by the temporary.  */
2599   for (dim = 0; dim < loop->temp_dim - 1; dim++)
2600     {
2601       n = loop->order[dim];
2602       gfc_trans_scalarized_loop_end (loop, n, pblock);
2603       loop->loopvar[n] = NULL_TREE;
2604       pblock = &loop->code[n];
2605     }
2606
2607   /* We don't want to finish the outermost loop entirely.  */
2608   n = loop->order[loop->temp_dim - 1];
2609   gfc_trans_scalarized_loop_end (loop, n, pblock);
2610
2611   /* Restore the initial offsets.  */
2612   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2613     {
2614       if ((ss->useflags & 2) == 0)
2615         continue;
2616
2617       if (ss->type != GFC_SS_SECTION
2618           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2619           && ss->type != GFC_SS_COMPONENT)
2620         continue;
2621
2622       ss->data.info.offset = ss->data.info.saved_offset;
2623     }
2624
2625   /* Restart all the inner loops we just finished.  */
2626   for (dim = loop->temp_dim - 2; dim >= 0; dim--)
2627     {
2628       n = loop->order[dim];
2629
2630       gfc_start_block (&loop->code[n]);
2631
2632       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
2633
2634       gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
2635     }
2636
2637   /* Start a block for the secondary copying code.  */
2638   gfc_start_block (body);
2639 }
2640
2641
2642 /* Calculate the upper bound of an array section.  */
2643
2644 static tree
2645 gfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock)
2646 {
2647   int dim;
2648   gfc_expr *end;
2649   tree desc;
2650   tree bound;
2651   gfc_se se;
2652   gfc_ss_info *info;
2653
2654   gcc_assert (ss->type == GFC_SS_SECTION);
2655
2656   info = &ss->data.info;
2657   dim = info->dim[n];
2658
2659   if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2660     /* We'll calculate the upper bound once we have access to the
2661        vector's descriptor.  */
2662     return NULL;
2663
2664   gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2665   desc = info->descriptor;
2666   end = info->ref->u.ar.end[dim];
2667
2668   if (end)
2669     {
2670       /* The upper bound was specified.  */
2671       gfc_init_se (&se, NULL);
2672       gfc_conv_expr_type (&se, end, gfc_array_index_type);
2673       gfc_add_block_to_block (pblock, &se.pre);
2674       bound = se.expr;
2675     }
2676   else
2677     {
2678       /* No upper bound was specified, so use the bound of the array.  */
2679       bound = gfc_conv_array_ubound (desc, dim);
2680     }
2681
2682   return bound;
2683 }
2684
2685
2686 /* Calculate the lower bound of an array section.  */
2687
2688 static void
2689 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
2690 {
2691   gfc_expr *start;
2692   gfc_expr *end;
2693   gfc_expr *stride;
2694   tree desc;
2695   gfc_se se;
2696   gfc_ss_info *info;
2697   int dim;
2698
2699   gcc_assert (ss->type == GFC_SS_SECTION);
2700
2701   info = &ss->data.info;
2702   dim = info->dim[n];
2703
2704   if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2705     {
2706       /* We use a zero-based index to access the vector.  */
2707       info->start[n] = gfc_index_zero_node;
2708       info->end[n] = gfc_index_zero_node;
2709       info->stride[n] = gfc_index_one_node;
2710       return;
2711     }
2712
2713   gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2714   desc = info->descriptor;
2715   start = info->ref->u.ar.start[dim];
2716   end = info->ref->u.ar.end[dim];
2717   stride = info->ref->u.ar.stride[dim];
2718
2719   /* Calculate the start of the range.  For vector subscripts this will
2720      be the range of the vector.  */
2721   if (start)
2722     {
2723       /* Specified section start.  */
2724       gfc_init_se (&se, NULL);
2725       gfc_conv_expr_type (&se, start, gfc_array_index_type);
2726       gfc_add_block_to_block (&loop->pre, &se.pre);
2727       info->start[n] = se.expr;
2728     }
2729   else
2730     {
2731       /* No lower bound specified so use the bound of the array.  */
2732       info->start[n] = gfc_conv_array_lbound (desc, dim);
2733     }
2734   info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);
2735
2736   /* Similarly calculate the end.  Although this is not used in the
2737      scalarizer, it is needed when checking bounds and where the end
2738      is an expression with side-effects.  */
2739   if (end)
2740     {
2741       /* Specified section start.  */
2742       gfc_init_se (&se, NULL);
2743       gfc_conv_expr_type (&se, end, gfc_array_index_type);
2744       gfc_add_block_to_block (&loop->pre, &se.pre);
2745       info->end[n] = se.expr;
2746     }
2747   else
2748     {
2749       /* No upper bound specified so use the bound of the array.  */
2750       info->end[n] = gfc_conv_array_ubound (desc, dim);
2751     }
2752   info->end[n] = gfc_evaluate_now (info->end[n], &loop->pre);
2753
2754   /* Calculate the stride.  */
2755   if (stride == NULL)
2756     info->stride[n] = gfc_index_one_node;
2757   else
2758     {
2759       gfc_init_se (&se, NULL);
2760       gfc_conv_expr_type (&se, stride, gfc_array_index_type);
2761       gfc_add_block_to_block (&loop->pre, &se.pre);
2762       info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);
2763     }
2764 }
2765
2766
2767 /* Calculates the range start and stride for a SS chain.  Also gets the
2768    descriptor and data pointer.  The range of vector subscripts is the size
2769    of the vector.  Array bounds are also checked.  */
2770
2771 void
2772 gfc_conv_ss_startstride (gfc_loopinfo * loop)
2773 {
2774   int n;
2775   tree tmp;
2776   gfc_ss *ss;
2777   tree desc;
2778
2779   loop->dimen = 0;
2780   /* Determine the rank of the loop.  */
2781   for (ss = loop->ss;
2782        ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
2783     {
2784       switch (ss->type)
2785         {
2786         case GFC_SS_SECTION:
2787         case GFC_SS_CONSTRUCTOR:
2788         case GFC_SS_FUNCTION:
2789         case GFC_SS_COMPONENT:
2790           loop->dimen = ss->data.info.dimen;
2791           break;
2792
2793         /* As usual, lbound and ubound are exceptions!.  */
2794         case GFC_SS_INTRINSIC:
2795           switch (ss->expr->value.function.isym->id)
2796             {
2797             case GFC_ISYM_LBOUND:
2798             case GFC_ISYM_UBOUND:
2799               loop->dimen = ss->data.info.dimen;
2800
2801             default:
2802               break;
2803             }
2804
2805         default:
2806           break;
2807         }
2808     }
2809
2810   /* We should have determined the rank of the expression by now.  If
2811      not, that's bad news.  */
2812   gcc_assert (loop->dimen != 0);
2813
2814   /* Loop over all the SS in the chain.  */
2815   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2816     {
2817       if (ss->expr && ss->expr->shape && !ss->shape)
2818         ss->shape = ss->expr->shape;
2819
2820       switch (ss->type)
2821         {
2822         case GFC_SS_SECTION:
2823           /* Get the descriptor for the array.  */
2824           gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
2825
2826           for (n = 0; n < ss->data.info.dimen; n++)
2827             gfc_conv_section_startstride (loop, ss, n);
2828           break;
2829
2830         case GFC_SS_INTRINSIC:
2831           switch (ss->expr->value.function.isym->id)
2832             {
2833             /* Fall through to supply start and stride.  */
2834             case GFC_ISYM_LBOUND:
2835             case GFC_ISYM_UBOUND:
2836               break;
2837             default:
2838               continue;
2839             }
2840
2841         case GFC_SS_CONSTRUCTOR:
2842         case GFC_SS_FUNCTION:
2843           for (n = 0; n < ss->data.info.dimen; n++)
2844             {
2845               ss->data.info.start[n] = gfc_index_zero_node;
2846               ss->data.info.end[n] = gfc_index_zero_node;
2847               ss->data.info.stride[n] = gfc_index_one_node;
2848             }
2849           break;
2850
2851         default:
2852           break;
2853         }
2854     }
2855
2856   /* The rest is just runtime bound checking.  */
2857   if (flag_bounds_check)
2858     {
2859       stmtblock_t block;
2860       tree lbound, ubound;
2861       tree end;
2862       tree size[GFC_MAX_DIMENSIONS];
2863       tree stride_pos, stride_neg, non_zerosized, tmp2;
2864       gfc_ss_info *info;
2865       char *msg;
2866       int dim;
2867
2868       gfc_start_block (&block);
2869
2870       for (n = 0; n < loop->dimen; n++)
2871         size[n] = NULL_TREE;
2872
2873       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2874         {
2875           if (ss->type != GFC_SS_SECTION)
2876             continue;
2877
2878           /* TODO: range checking for mapped dimensions.  */
2879           info = &ss->data.info;
2880
2881           /* This code only checks ranges.  Elemental and vector
2882              dimensions are checked later.  */
2883           for (n = 0; n < loop->dimen; n++)
2884             {
2885               bool check_upper;
2886
2887               dim = info->dim[n];
2888               if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
2889                 continue;
2890
2891               if (dim == info->ref->u.ar.dimen - 1
2892                   && (info->ref->u.ar.as->type == AS_ASSUMED_SIZE
2893                       || info->ref->u.ar.as->cp_was_assumed))
2894                 check_upper = false;
2895               else
2896                 check_upper = true;
2897
2898               /* Zero stride is not allowed.  */
2899               tmp = fold_build2 (EQ_EXPR, boolean_type_node, info->stride[n],
2900                                  gfc_index_zero_node);
2901               asprintf (&msg, "Zero stride is not allowed, for dimension %d "
2902                         "of array '%s'", info->dim[n]+1,
2903                         ss->expr->symtree->name);
2904               gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg);
2905               gfc_free (msg);
2906
2907               desc = ss->data.info.descriptor;
2908
2909               /* This is the run-time equivalent of resolve.c's
2910                  check_dimension().  The logical is more readable there
2911                  than it is here, with all the trees.  */
2912               lbound = gfc_conv_array_lbound (desc, dim);
2913               end = info->end[n];
2914               if (check_upper)
2915                 ubound = gfc_conv_array_ubound (desc, dim);
2916               else
2917                 ubound = NULL;
2918
2919               /* non_zerosized is true when the selected range is not
2920                  empty.  */
2921               stride_pos = fold_build2 (GT_EXPR, boolean_type_node,
2922                                         info->stride[n], gfc_index_zero_node);
2923               tmp = fold_build2 (LE_EXPR, boolean_type_node, info->start[n],
2924                                  end);
2925               stride_pos = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2926                                         stride_pos, tmp);
2927
2928               stride_neg = fold_build2 (LT_EXPR, boolean_type_node,
2929                                         info->stride[n], gfc_index_zero_node);
2930               tmp = fold_build2 (GE_EXPR, boolean_type_node, info->start[n],
2931                                  end);
2932               stride_neg = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2933                                         stride_neg, tmp);
2934               non_zerosized = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
2935                                            stride_pos, stride_neg);
2936
2937               /* Check the start of the range against the lower and upper
2938                  bounds of the array, if the range is not empty.  */
2939               tmp = fold_build2 (LT_EXPR, boolean_type_node, info->start[n],
2940                                  lbound);
2941               tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2942                                  non_zerosized, tmp);
2943               asprintf (&msg, "%s, lower bound of dimension %d of array '%s'"
2944                         " exceeded (%%ld < %%ld)", gfc_msg_fault,
2945                         info->dim[n]+1, ss->expr->symtree->name);
2946               gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg,
2947                                        fold_convert (long_integer_type_node,
2948                                                      info->start[n]),
2949                                        fold_convert (long_integer_type_node,
2950                                                      lbound));
2951               gfc_free (msg);
2952
2953               if (check_upper)
2954                 {
2955                   tmp = fold_build2 (GT_EXPR, boolean_type_node,
2956                                      info->start[n], ubound);
2957                   tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2958                                      non_zerosized, tmp);
2959                   asprintf (&msg, "%s, upper bound of dimension %d of array "
2960                             "'%s' exceeded (%%ld > %%ld)", gfc_msg_fault,
2961                             info->dim[n]+1, ss->expr->symtree->name);
2962                   gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg,
2963                         fold_convert (long_integer_type_node, info->start[n]),
2964                         fold_convert (long_integer_type_node, ubound));
2965                   gfc_free (msg);
2966                 }
2967
2968               /* Compute the last element of the range, which is not
2969                  necessarily "end" (think 0:5:3, which doesn't contain 5)
2970                  and check it against both lower and upper bounds.  */
2971               tmp2 = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2972                                   info->start[n]);
2973               tmp2 = fold_build2 (TRUNC_MOD_EXPR, gfc_array_index_type, tmp2,
2974                                   info->stride[n]);
2975               tmp2 = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2976                                   tmp2);
2977
2978               tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp2, lbound);
2979               tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2980                                  non_zerosized, tmp);
2981               asprintf (&msg, "%s, lower bound of dimension %d of array '%s'"
2982                         " exceeded (%%ld < %%ld)", gfc_msg_fault,
2983                         info->dim[n]+1, ss->expr->symtree->name);
2984               gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg,
2985                                        fold_convert (long_integer_type_node,
2986                                                      tmp2),
2987                                        fold_convert (long_integer_type_node,
2988                                                      lbound));
2989               gfc_free (msg);
2990
2991               if (check_upper)
2992                 {
2993                   tmp = fold_build2 (GT_EXPR, boolean_type_node, tmp2, ubound);
2994                   tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2995                                      non_zerosized, tmp);
2996                   asprintf (&msg, "%s, upper bound of dimension %d of array "
2997                             "'%s' exceeded (%%ld > %%ld)", gfc_msg_fault,
2998                             info->dim[n]+1, ss->expr->symtree->name);
2999                   gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg,
3000                         fold_convert (long_integer_type_node, tmp2),
3001                         fold_convert (long_integer_type_node, ubound));
3002                   gfc_free (msg);
3003                 }
3004
3005               /* Check the section sizes match.  */
3006               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
3007                                  info->start[n]);
3008               tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
3009                                  info->stride[n]);
3010               /* We remember the size of the first section, and check all the
3011                  others against this.  */
3012               if (size[n])
3013                 {
3014                   tree tmp3;
3015
3016                   tmp3 = fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
3017
3018                   /* For optional arguments, only check bounds if the
3019                      argument is present.  */
3020                   if (ss->expr->symtree->n.sym->attr.optional
3021                       || ss->expr->symtree->n.sym->attr.not_always_present)
3022                     {
3023                       tree cond;
3024
3025                       cond = gfc_conv_expr_present (ss->expr->symtree->n.sym);
3026                       tmp3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3027                                           cond, tmp3);
3028                     }
3029
3030                   asprintf (&msg, "%s, size mismatch for dimension %d "
3031                             "of array '%s' (%%ld/%%ld)", gfc_msg_bounds,
3032                             info->dim[n]+1, ss->expr->symtree->name);
3033                   gfc_trans_runtime_check (tmp3, &block, &ss->expr->where, msg,
3034                         fold_convert (long_integer_type_node, tmp),
3035                         fold_convert (long_integer_type_node, size[n]));
3036                   gfc_free (msg);
3037                 }
3038               else
3039                 size[n] = gfc_evaluate_now (tmp, &block);
3040             }
3041         }
3042
3043       tmp = gfc_finish_block (&block);
3044       gfc_add_expr_to_block (&loop->pre, tmp);
3045     }
3046 }
3047
3048
3049 /* Return true if the two SS could be aliased, i.e. both point to the same data
3050    object.  */
3051 /* TODO: resolve aliases based on frontend expressions.  */
3052
3053 static int
3054 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
3055 {
3056   gfc_ref *lref;
3057   gfc_ref *rref;
3058   gfc_symbol *lsym;
3059   gfc_symbol *rsym;
3060
3061   lsym = lss->expr->symtree->n.sym;
3062   rsym = rss->expr->symtree->n.sym;
3063   if (gfc_symbols_could_alias (lsym, rsym))
3064     return 1;
3065
3066   if (rsym->ts.type != BT_DERIVED
3067       && lsym->ts.type != BT_DERIVED)
3068     return 0;
3069
3070   /* For derived types we must check all the component types.  We can ignore
3071      array references as these will have the same base type as the previous
3072      component ref.  */
3073   for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
3074     {
3075       if (lref->type != REF_COMPONENT)
3076         continue;
3077
3078       if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
3079         return 1;
3080
3081       for (rref = rss->expr->ref; rref != rss->data.info.ref;
3082            rref = rref->next)
3083         {
3084           if (rref->type != REF_COMPONENT)
3085             continue;
3086
3087           if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
3088             return 1;
3089         }
3090     }
3091
3092   for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
3093     {
3094       if (rref->type != REF_COMPONENT)
3095         break;
3096
3097       if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
3098         return 1;
3099     }
3100
3101   return 0;
3102 }
3103
3104
3105 /* Resolve array data dependencies.  Creates a temporary if required.  */
3106 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
3107    dependency.c.  */
3108
3109 void
3110 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
3111                                gfc_ss * rss)
3112 {
3113   gfc_ss *ss;
3114   gfc_ref *lref;
3115   gfc_ref *rref;
3116   gfc_ref *aref;
3117   int nDepend = 0;
3118   int temp_dim = 0;
3119
3120   loop->temp_ss = NULL;
3121   aref = dest->data.info.ref;
3122   temp_dim = 0;
3123
3124   for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
3125     {
3126       if (ss->type != GFC_SS_SECTION)
3127         continue;
3128
3129       if (gfc_could_be_alias (dest, ss)
3130             || gfc_are_equivalenced_arrays (dest->expr, ss->expr))
3131         {
3132           nDepend = 1;
3133           break;
3134         }
3135
3136       if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
3137         {
3138           lref = dest->expr->ref;
3139           rref = ss->expr->ref;
3140
3141           nDepend = gfc_dep_resolver (lref, rref);
3142           if (nDepend == 1)
3143             break;
3144 #if 0
3145           /* TODO : loop shifting.  */
3146           if (nDepend == 1)
3147             {
3148               /* Mark the dimensions for LOOP SHIFTING */
3149               for (n = 0; n < loop->dimen; n++)
3150                 {
3151                   int dim = dest->data.info.dim[n];
3152
3153                   if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
3154                     depends[n] = 2;
3155                   else if (! gfc_is_same_range (&lref->u.ar,
3156                                                 &rref->u.ar, dim, 0))
3157                     depends[n] = 1;
3158                  }
3159
3160               /* Put all the dimensions with dependencies in the
3161                  innermost loops.  */
3162               dim = 0;
3163               for (n = 0; n < loop->dimen; n++)
3164                 {
3165                   gcc_assert (loop->order[n] == n);
3166                   if (depends[n])
3167                   loop->order[dim++] = n;
3168                 }
3169               temp_dim = dim;
3170               for (n = 0; n < loop->dimen; n++)
3171                 {
3172                   if (! depends[n])
3173                   loop->order[dim++] = n;
3174                 }
3175
3176               gcc_assert (dim == loop->dimen);
3177               break;
3178             }
3179 #endif
3180         }
3181     }
3182
3183   if (nDepend == 1)
3184     {
3185       tree base_type = gfc_typenode_for_spec (&dest->expr->ts);
3186       if (GFC_ARRAY_TYPE_P (base_type)
3187           || GFC_DESCRIPTOR_TYPE_P (base_type))
3188         base_type = gfc_get_element_type (base_type);
3189       loop->temp_ss = gfc_get_ss ();
3190       loop->temp_ss->type = GFC_SS_TEMP;
3191       loop->temp_ss->data.temp.type = base_type;
3192       loop->temp_ss->string_length = dest->string_length;
3193       loop->temp_ss->data.temp.dimen = loop->dimen;
3194       loop->temp_ss->next = gfc_ss_terminator;
3195       gfc_add_ss_to_loop (loop, loop->temp_ss);
3196     }
3197   else
3198     loop->temp_ss = NULL;
3199 }
3200
3201
3202 /* Initialize the scalarization loop.  Creates the loop variables.  Determines
3203    the range of the loop variables.  Creates a temporary if required.
3204    Calculates how to transform from loop variables to array indices for each
3205    expression.  Also generates code for scalar expressions which have been
3206    moved outside the loop.  */
3207
3208 void
3209 gfc_conv_loop_setup (gfc_loopinfo * loop)
3210 {
3211   int n;
3212   int dim;
3213   gfc_ss_info *info;
3214   gfc_ss_info *specinfo;
3215   gfc_ss *ss;
3216   tree tmp;
3217   tree len;
3218   gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
3219   bool dynamic[GFC_MAX_DIMENSIONS];
3220   gfc_constructor *c;
3221   mpz_t *cshape;
3222   mpz_t i;
3223
3224   mpz_init (i);
3225   for (n = 0; n < loop->dimen; n++)
3226     {
3227       loopspec[n] = NULL;
3228       dynamic[n] = false;
3229       /* We use one SS term, and use that to determine the bounds of the
3230          loop for this dimension.  We try to pick the simplest term.  */
3231       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3232         {
3233           if (ss->shape)
3234             {
3235               /* The frontend has worked out the size for us.  */
3236               loopspec[n] = ss;
3237               continue;
3238             }
3239
3240           if (ss->type == GFC_SS_CONSTRUCTOR)
3241             {
3242               /* An unknown size constructor will always be rank one.
3243                  Higher rank constructors will either have known shape,
3244                  or still be wrapped in a call to reshape.  */
3245               gcc_assert (loop->dimen == 1);
3246
3247               /* Always prefer to use the constructor bounds if the size
3248                  can be determined at compile time.  Prefer not to otherwise,
3249                  since the general case involves realloc, and it's better to
3250                  avoid that overhead if possible.  */
3251               c = ss->expr->value.constructor;
3252               dynamic[n] = gfc_get_array_constructor_size (&i, c);
3253               if (!dynamic[n] || !loopspec[n])
3254                 loopspec[n] = ss;
3255               continue;
3256             }
3257
3258           /* TODO: Pick the best bound if we have a choice between a
3259              function and something else.  */
3260           if (ss->type == GFC_SS_FUNCTION)
3261             {
3262               loopspec[n] = ss;
3263               continue;
3264             }
3265
3266           if (ss->type != GFC_SS_SECTION)
3267             continue;
3268
3269           if (loopspec[n])
3270             specinfo = &loopspec[n]->data.info;
3271           else
3272             specinfo = NULL;
3273           info = &ss->data.info;
3274
3275           if (!specinfo)
3276             loopspec[n] = ss;
3277           /* Criteria for choosing a loop specifier (most important first):
3278              doesn't need realloc
3279              stride of one
3280              known stride
3281              known lower bound
3282              known upper bound
3283            */
3284           else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
3285             loopspec[n] = ss;
3286           else if (integer_onep (info->stride[n])
3287                    && !integer_onep (specinfo->stride[n]))
3288             loopspec[n] = ss;
3289           else if (INTEGER_CST_P (info->stride[n])
3290                    && !INTEGER_CST_P (specinfo->stride[n]))
3291             loopspec[n] = ss;
3292           else if (INTEGER_CST_P (info->start[n])
3293                    && !INTEGER_CST_P (specinfo->start[n]))
3294             loopspec[n] = ss;
3295           /* We don't work out the upper bound.
3296              else if (INTEGER_CST_P (info->finish[n])
3297              && ! INTEGER_CST_P (specinfo->finish[n]))
3298              loopspec[n] = ss; */
3299         }
3300
3301       /* We should have found the scalarization loop specifier.  If not,
3302          that's bad news.  */
3303       gcc_assert (loopspec[n]);
3304
3305       info = &loopspec[n]->data.info;
3306
3307       /* Set the extents of this range.  */
3308       cshape = loopspec[n]->shape;
3309       if (cshape && INTEGER_CST_P (info->start[n])
3310           && INTEGER_CST_P (info->stride[n]))
3311         {
3312           loop->from[n] = info->start[n];
3313           mpz_set (i, cshape[n]);
3314           mpz_sub_ui (i, i, 1);
3315           /* To = from + (size - 1) * stride.  */
3316           tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
3317           if (!integer_onep (info->stride[n]))
3318             tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3319                                tmp, info->stride[n]);
3320           loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3321                                      loop->from[n], tmp);
3322         }
3323       else
3324         {
3325           loop->from[n] = info->start[n];
3326           switch (loopspec[n]->type)
3327             {
3328             case GFC_SS_CONSTRUCTOR:
3329               /* The upper bound is calculated when we expand the
3330                  constructor.  */
3331               gcc_assert (loop->to[n] == NULL_TREE);
3332               break;
3333
3334             case GFC_SS_SECTION:
3335               loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
3336                                                           &loop->pre);
3337               break;
3338
3339             case GFC_SS_FUNCTION:
3340               /* The loop bound will be set when we generate the call.  */
3341               gcc_assert (loop->to[n] == NULL_TREE);
3342               break;
3343
3344             default:
3345               gcc_unreachable ();
3346             }
3347         }
3348
3349       /* Transform everything so we have a simple incrementing variable.  */
3350       if (integer_onep (info->stride[n]))
3351         info->delta[n] = gfc_index_zero_node;
3352       else
3353         {
3354           /* Set the delta for this section.  */
3355           info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
3356           /* Number of iterations is (end - start + step) / step.
3357              with start = 0, this simplifies to
3358              last = end / step;
3359              for (i = 0; i<=last; i++){...};  */
3360           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3361                              loop->to[n], loop->from[n]);
3362           tmp = fold_build2 (TRUNC_DIV_EXPR, gfc_array_index_type, 
3363                              tmp, info->stride[n]);
3364           loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
3365           /* Make the loop variable start at 0.  */
3366           loop->from[n] = gfc_index_zero_node;
3367         }
3368     }
3369
3370   /* Add all the scalar code that can be taken out of the loops.
3371      This may include calculating the loop bounds, so do it before
3372      allocating the temporary.  */
3373   gfc_add_loop_ss_code (loop, loop->ss, false);
3374
3375   /* If we want a temporary then create it.  */
3376   if (loop->temp_ss != NULL)
3377     {
3378       gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
3379
3380       /* Make absolutely sure that this is a complete type.  */
3381       if (loop->temp_ss->string_length)
3382         loop->temp_ss->data.temp.type
3383                 = gfc_get_character_type_len (gfc_default_character_kind,
3384                                               loop->temp_ss->string_length);
3385
3386       tmp = loop->temp_ss->data.temp.type;
3387       len = loop->temp_ss->string_length;
3388       n = loop->temp_ss->data.temp.dimen;
3389       memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
3390       loop->temp_ss->type = GFC_SS_SECTION;
3391       loop->temp_ss->data.info.dimen = n;
3392       gfc_trans_create_temp_array (&loop->pre, &loop->post, loop,
3393                                    &loop->temp_ss->data.info, tmp, false, true,
3394                                    false);
3395     }
3396
3397   for (n = 0; n < loop->temp_dim; n++)
3398     loopspec[loop->order[n]] = NULL;
3399
3400   mpz_clear (i);
3401
3402   /* For array parameters we don't have loop variables, so don't calculate the
3403      translations.  */
3404   if (loop->array_parameter)
3405     return;
3406
3407   /* Calculate the translation from loop variables to array indices.  */
3408   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
3409     {
3410       if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT)
3411         continue;
3412
3413       info = &ss->data.info;
3414
3415       for (n = 0; n < info->dimen; n++)
3416         {
3417           dim = info->dim[n];
3418
3419           /* If we are specifying the range the delta is already set.  */
3420           if (loopspec[n] != ss)
3421             {
3422               /* Calculate the offset relative to the loop variable.
3423                  First multiply by the stride.  */
3424               tmp = loop->from[n];
3425               if (!integer_onep (info->stride[n]))
3426                 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3427                                    tmp, info->stride[n]);
3428
3429               /* Then subtract this from our starting value.  */
3430               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3431                                  info->start[n], tmp);
3432
3433               info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
3434             }
3435         }
3436     }
3437 }
3438
3439
3440 /* Fills in an array descriptor, and returns the size of the array.  The size
3441    will be a simple_val, ie a variable or a constant.  Also calculates the
3442    offset of the base.  Returns the size of the array.
3443    {
3444     stride = 1;
3445     offset = 0;
3446     for (n = 0; n < rank; n++)
3447       {
3448         a.lbound[n] = specified_lower_bound;
3449         offset = offset + a.lbond[n] * stride;
3450         size = 1 - lbound;
3451         a.ubound[n] = specified_upper_bound;
3452         a.stride[n] = stride;
3453         size = ubound + size; //size = ubound + 1 - lbound
3454         stride = stride * size;
3455       }
3456     return (stride);
3457    }  */
3458 /*GCC ARRAYS*/
3459
3460 static tree
3461 gfc_array_init_size (tree descriptor, int rank, tree * poffset,
3462                      gfc_expr ** lower, gfc_expr ** upper,
3463                      stmtblock_t * pblock)
3464 {
3465   tree type;
3466   tree tmp;
3467   tree size;
3468   tree offset;
3469   tree stride;
3470   tree cond;
3471   tree or_expr;
3472   tree thencase;
3473   tree elsecase;
3474   tree var;
3475   stmtblock_t thenblock;
3476   stmtblock_t elseblock;
3477   gfc_expr *ubound;
3478   gfc_se se;
3479   int n;
3480
3481   type = TREE_TYPE (descriptor);
3482
3483   stride = gfc_index_one_node;
3484   offset = gfc_index_zero_node;
3485
3486   /* Set the dtype.  */
3487   tmp = gfc_conv_descriptor_dtype (descriptor);
3488   gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
3489
3490   or_expr = NULL_TREE;
3491
3492   for (n = 0; n < rank; n++)
3493     {
3494       /* We have 3 possibilities for determining the size of the array:
3495          lower == NULL    => lbound = 1, ubound = upper[n]
3496          upper[n] = NULL  => lbound = 1, ubound = lower[n]
3497          upper[n] != NULL => lbound = lower[n], ubound = upper[n]  */
3498       ubound = upper[n];
3499
3500       /* Set lower bound.  */
3501       gfc_init_se (&se, NULL);
3502       if (lower == NULL)
3503         se.expr = gfc_index_one_node;
3504       else
3505         {
3506           gcc_assert (lower[n]);
3507           if (ubound)
3508             {
3509               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
3510               gfc_add_block_to_block (pblock, &se.pre);
3511             }
3512           else
3513             {
3514               se.expr = gfc_index_one_node;
3515               ubound = lower[n];
3516             }
3517         }
3518       tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
3519       gfc_add_modify_expr (pblock, tmp, se.expr);
3520
3521       /* Work out the offset for this component.  */
3522       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
3523       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3524
3525       /* Start the calculation for the size of this dimension.  */
3526       size = build2 (MINUS_EXPR, gfc_array_index_type,
3527                      gfc_index_one_node, se.expr);
3528
3529       /* Set upper bound.  */
3530       gfc_init_se (&se, NULL);
3531       gcc_assert (ubound);
3532       gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
3533       gfc_add_block_to_block (pblock, &se.pre);
3534
3535       tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
3536       gfc_add_modify_expr (pblock, tmp, se.expr);
3537
3538       /* Store the stride.  */
3539       tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
3540       gfc_add_modify_expr (pblock, tmp, stride);
3541
3542       /* Calculate the size of this dimension.  */
3543       size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
3544
3545       /* Check whether the size for this dimension is negative.  */
3546       cond = fold_build2 (LE_EXPR, boolean_type_node, size,
3547                           gfc_index_zero_node);
3548       if (n == 0)
3549         or_expr = cond;
3550       else
3551         or_expr = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, or_expr, cond);
3552
3553       /* Multiply the stride by the number of elements in this dimension.  */
3554       stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, size);
3555       stride = gfc_evaluate_now (stride, pblock);
3556     }
3557
3558   /* The stride is the number of elements in the array, so multiply by the
3559      size of an element to get the total size.  */
3560   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3561   size = fold_build2 (MULT_EXPR, gfc_array_index_type, stride,
3562                       fold_convert (gfc_array_index_type, tmp));
3563
3564   if (poffset != NULL)
3565     {
3566       offset = gfc_evaluate_now (offset, pblock);
3567       *poffset = offset;
3568     }
3569
3570   if (integer_zerop (or_expr))
3571     return size;
3572   if (integer_onep (or_expr))
3573     return gfc_index_zero_node;
3574
3575   var = gfc_create_var (TREE_TYPE (size), "size");
3576   gfc_start_block (&thenblock);
3577   gfc_add_modify_expr (&thenblock, var, gfc_index_zero_node);
3578   thencase = gfc_finish_block (&thenblock);
3579
3580   gfc_start_block (&elseblock);
3581   gfc_add_modify_expr (&elseblock, var, size);
3582   elsecase = gfc_finish_block (&elseblock);
3583
3584   tmp = gfc_evaluate_now (or_expr, pblock);
3585   tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
3586   gfc_add_expr_to_block (pblock, tmp);
3587
3588   return var;
3589 }
3590
3591
3592 /* Initializes the descriptor and generates a call to _gfor_allocate.  Does
3593    the work for an ALLOCATE statement.  */
3594 /*GCC ARRAYS*/
3595
3596 bool
3597 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat)
3598 {
3599   tree tmp;
3600   tree pointer;
3601   tree offset;
3602   tree size;
3603   gfc_expr **lower;
3604   gfc_expr **upper;
3605   gfc_ref *ref, *prev_ref = NULL;
3606   bool allocatable_array;
3607
3608   ref = expr->ref;
3609
3610   /* Find the last reference in the chain.  */
3611   while (ref && ref->next != NULL)
3612     {
3613       gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
3614       prev_ref = ref;
3615       ref = ref->next;
3616     }
3617
3618   if (ref == NULL || ref->type != REF_ARRAY)
3619     return false;
3620
3621   if (!prev_ref)
3622     allocatable_array = expr->symtree->n.sym->attr.allocatable;
3623   else
3624     allocatable_array = prev_ref->u.c.component->allocatable;
3625
3626   /* Figure out the size of the array.  */
3627   switch (ref->u.ar.type)
3628     {
3629     case AR_ELEMENT:
3630       lower = NULL;
3631       upper = ref->u.ar.start;
3632       break;
3633
3634     case AR_FULL:
3635       gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
3636
3637       lower = ref->u.ar.as->lower;
3638       upper = ref->u.ar.as->upper;
3639       break;
3640
3641     case AR_SECTION:
3642       lower = ref->u.ar.start;
3643       upper = ref->u.ar.end;
3644       break;
3645
3646     default:
3647       gcc_unreachable ();
3648       break;
3649     }
3650
3651   size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
3652                               lower, upper, &se->pre);
3653
3654   /* Allocate memory to store the data.  */
3655   pointer = gfc_conv_descriptor_data_get (se->expr);
3656   STRIP_NOPS (pointer);
3657
3658   /* The allocate_array variants take the old pointer as first argument.  */
3659   if (allocatable_array)
3660     tmp = gfc_allocate_array_with_status (&se->pre, pointer, size, pstat);
3661   else
3662     tmp = gfc_allocate_with_status (&se->pre, size, pstat);
3663   tmp = build2 (MODIFY_EXPR, void_type_node, pointer, tmp);
3664   gfc_add_expr_to_block (&se->pre, tmp);
3665
3666   tmp = gfc_conv_descriptor_offset (se->expr);
3667   gfc_add_modify_expr (&se->pre, tmp, offset);
3668
3669   if (expr->ts.type == BT_DERIVED
3670         && expr->ts.derived->attr.alloc_comp)
3671     {
3672       tmp = gfc_nullify_alloc_comp (expr->ts.derived, se->expr,
3673                                     ref->u.ar.as->rank);
3674       gfc_add_expr_to_block (&se->pre, tmp);
3675     }
3676
3677   return true;
3678 }
3679
3680
3681 /* Deallocate an array variable.  Also used when an allocated variable goes
3682    out of scope.  */
3683 /*GCC ARRAYS*/
3684
3685 tree
3686 gfc_array_deallocate (tree descriptor, tree pstat)
3687 {
3688   tree var;
3689   tree tmp;
3690   stmtblock_t block;
3691
3692   gfc_start_block (&block);
3693   /* Get a pointer to the data.  */
3694   var = gfc_conv_descriptor_data_get (descriptor);
3695   STRIP_NOPS (var);
3696
3697   /* Parameter is the address of the data component.  */
3698   tmp = gfc_deallocate_with_status (var, pstat, false);
3699   gfc_add_expr_to_block (&block, tmp);
3700
3701   /* Zero the data pointer.  */
3702   tmp = build2 (MODIFY_EXPR, void_type_node,
3703                 var, build_int_cst (TREE_TYPE (var), 0));
3704   gfc_add_expr_to_block (&block, tmp);
3705
3706   return gfc_finish_block (&block);
3707 }
3708
3709
3710 /* Create an array constructor from an initialization expression.
3711    We assume the frontend already did any expansions and conversions.  */
3712
3713 tree
3714 gfc_conv_array_initializer (tree type, gfc_expr * expr)
3715 {
3716   gfc_constructor *c;
3717   tree tmp;
3718   mpz_t maxval;
3719   gfc_se se;
3720   HOST_WIDE_INT hi;
3721   unsigned HOST_WIDE_INT lo;
3722   tree index, range;
3723   VEC(constructor_elt,gc) *v = NULL;
3724
3725   switch (expr->expr_type)
3726     {
3727     case EXPR_CONSTANT:
3728     case EXPR_STRUCTURE:
3729       /* A single scalar or derived type value.  Create an array with all
3730          elements equal to that value.  */
3731       gfc_init_se (&se, NULL);
3732       
3733       if (expr->expr_type == EXPR_CONSTANT)
3734         gfc_conv_constant (&se, expr);
3735       else
3736         gfc_conv_structure (&se, expr, 1);
3737
3738       tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3739       gcc_assert (tmp && INTEGER_CST_P (tmp));
3740       hi = TREE_INT_CST_HIGH (tmp);
3741       lo = TREE_INT_CST_LOW (tmp);
3742       lo++;
3743       if (lo == 0)
3744         hi++;
3745       /* This will probably eat buckets of memory for large arrays.  */
3746       while (hi != 0 || lo != 0)
3747         {
3748           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
3749           if (lo == 0)
3750             hi--;
3751           lo--;
3752         }
3753       break;
3754
3755     case EXPR_ARRAY:
3756       /* Create a vector of all the elements.  */
3757       for (c = expr->value.constructor; c; c = c->next)
3758         {
3759           if (c->iterator)
3760             {
3761               /* Problems occur when we get something like
3762                  integer :: a(lots) = (/(i, i=1,lots)/)  */
3763               /* TODO: Unexpanded array initializers.  */
3764               internal_error
3765                 ("Possible frontend bug: array constructor not expanded");
3766             }
3767           if (mpz_cmp_si (c->n.offset, 0) != 0)
3768             index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3769           else
3770             index = NULL_TREE;
3771           mpz_init (maxval);
3772           if (mpz_cmp_si (c->repeat, 0) != 0)
3773             {
3774               tree tmp1, tmp2;
3775
3776               mpz_set (maxval, c->repeat);
3777               mpz_add (maxval, c->n.offset, maxval);
3778               mpz_sub_ui (maxval, maxval, 1);
3779               tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3780               if (mpz_cmp_si (c->n.offset, 0) != 0)
3781                 {
3782                   mpz_add_ui (maxval, c->n.offset, 1);
3783                   tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3784                 }
3785               else
3786                 tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3787
3788               range = build2 (RANGE_EXPR, integer_type_node, tmp1, tmp2);
3789             }
3790           else
3791             range = NULL;
3792           mpz_clear (maxval);
3793
3794           gfc_init_se (&se, NULL);
3795           switch (c->expr->expr_type)
3796             {
3797             case EXPR_CONSTANT:
3798               gfc_conv_constant (&se, c->expr);
3799               if (range == NULL_TREE)
3800                 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3801               else
3802                 {
3803                   if (index != NULL_TREE)
3804                     CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3805                   CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
3806                 }
3807               break;
3808
3809             case EXPR_STRUCTURE:
3810               gfc_conv_structure (&se, c->expr, 1);
3811               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3812               break;
3813
3814             default:
3815               gcc_unreachable ();
3816             }
3817         }
3818       break;
3819
3820     case EXPR_NULL:
3821       return gfc_build_null_descriptor (type);
3822
3823     default:
3824       gcc_unreachable ();
3825     }
3826
3827   /* Create a constructor from the list of elements.  */
3828   tmp = build_constructor (type, v);
3829   TREE_CONSTANT (tmp) = 1;
3830   TREE_INVARIANT (tmp) = 1;
3831   return tmp;
3832 }
3833
3834
3835 /* Generate code to evaluate non-constant array bounds.  Sets *poffset and
3836    returns the size (in elements) of the array.  */
3837
3838 static tree
3839 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
3840                         stmtblock_t * pblock)
3841 {
3842   gfc_array_spec *as;
3843   tree size;
3844   tree stride;
3845   tree offset;
3846   tree ubound;
3847   tree lbound;
3848   tree tmp;
3849   gfc_se se;
3850
3851   int dim;
3852
3853   as = sym->as;
3854
3855   size = gfc_index_one_node;
3856   offset = gfc_index_zero_node;
3857   for (dim = 0; dim < as->rank; dim++)
3858     {
3859       /* Evaluate non-constant array bound expressions.  */
3860       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
3861       if (as->lower[dim] && !INTEGER_CST_P (lbound))
3862         {
3863           gfc_init_se (&se, NULL);
3864           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
3865           gfc_add_block_to_block (pblock, &se.pre);
3866           gfc_add_modify_expr (pblock, lbound, se.expr);
3867         }
3868       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
3869       if (as->upper[dim] && !INTEGER_CST_P (ubound))
3870         {
3871           gfc_init_se (&se, NULL);
3872           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
3873           gfc_add_block_to_block (pblock, &se.pre);
3874           gfc_add_modify_expr (pblock, ubound, se.expr);
3875         }
3876       /* The offset of this dimension.  offset = offset - lbound * stride.  */
3877       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
3878       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3879
3880       /* The size of this dimension, and the stride of the next.  */
3881       if (dim + 1 < as->rank)
3882         stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
3883       else
3884         stride = GFC_TYPE_ARRAY_SIZE (type);
3885
3886       if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
3887         {
3888           /* Calculate stride = size * (ubound + 1 - lbound).  */
3889           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3890                              gfc_index_one_node, lbound);
3891           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
3892           tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3893           if (stride)
3894             gfc_add_modify_expr (pblock, stride, tmp);
3895           else
3896             stride = gfc_evaluate_now (tmp, pblock);
3897
3898           /* Make sure that negative size arrays are translated
3899              to being zero size.  */
3900           tmp = build2 (GE_EXPR, boolean_type_node,
3901                         stride, gfc_index_zero_node);
3902           tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3903                         stride, gfc_index_zero_node);
3904           gfc_add_modify_expr (pblock, stride, tmp);
3905         }
3906
3907       size = stride;
3908     }
3909
3910   gfc_trans_vla_type_sizes (sym, pblock);
3911
3912   *poffset = offset;
3913   return size;
3914 }
3915
3916
3917 /* Generate code to initialize/allocate an array variable.  */
3918
3919 tree
3920 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
3921 {
3922   stmtblock_t block;
3923   tree type;
3924   tree tmp;
3925   tree size;
3926   tree offset;
3927   bool onstack;
3928
3929   gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
3930
3931   /* Do nothing for USEd variables.  */
3932   if (sym->attr.use_assoc)
3933     return fnbody;
3934
3935   type = TREE_TYPE (decl);
3936   gcc_assert (GFC_ARRAY_TYPE_P (type));
3937   onstack = TREE_CODE (type) != POINTER_TYPE;
3938
3939   gfc_start_block (&block);
3940
3941   /* Evaluate character string length.  */
3942   if (sym->ts.type == BT_CHARACTER
3943       && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3944     {
3945       gfc_conv_string_length (sym->ts.cl, &block);
3946
3947       gfc_trans_vla_type_sizes (sym, &block);
3948
3949       /* Emit a DECL_EXPR for this variable, which will cause the
3950          gimplifier to allocate storage, and all that good stuff.  */
3951       tmp = build1 (DECL_EXPR, TREE_TYPE (decl), decl);
3952       gfc_add_expr_to_block (&block, tmp);
3953     }
3954
3955   if (onstack)
3956     {
3957       gfc_add_expr_to_block (&block, fnbody);
3958       return gfc_finish_block (&block);
3959     }
3960
3961   type = TREE_TYPE (type);
3962
3963   gcc_assert (!sym->attr.use_assoc);
3964   gcc_assert (!TREE_STATIC (decl));
3965   gcc_assert (!sym->module);
3966
3967   if (sym->ts.type == BT_CHARACTER
3968       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3969     gfc_conv_string_length (sym->ts.cl, &block);
3970
3971   size = gfc_trans_array_bounds (type, sym, &offset, &block);
3972
3973   /* Don't actually allocate space for Cray Pointees.  */
3974   if (sym->attr.cray_pointee)
3975     {
3976       if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3977         gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3978       gfc_add_expr_to_block (&block, fnbody);
3979       return gfc_finish_block (&block);
3980     }
3981
3982   /* The size is the number of elements in the array, so multiply by the
3983      size of an element to get the total size.  */
3984   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3985   size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
3986                       fold_convert (gfc_array_index_type, tmp));
3987
3988   /* Allocate memory to hold the data.  */
3989   tmp = gfc_call_malloc (&block, TREE_TYPE (decl), size);
3990   gfc_add_modify_expr (&block, decl, tmp);
3991
3992   /* Set offset of the array.  */
3993   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3994     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3995
3996
3997   /* Automatic arrays should not have initializers.  */
3998   gcc_assert (!sym->value);
3999
4000   gfc_add_expr_to_block (&block, fnbody);
4001
4002   /* Free the temporary.  */
4003   tmp = gfc_call_free (convert (pvoid_type_node, decl));
4004   gfc_add_expr_to_block (&block, tmp);
4005
4006   return gfc_finish_block (&block);
4007 }
4008
4009
4010 /* Generate entry and exit code for g77 calling convention arrays.  */
4011
4012 tree
4013 gfc_trans_g77_array (gfc_symbol * sym, tree body)
4014 {
4015   tree parm;
4016   tree type;
4017   locus loc;
4018   tree offset;
4019   tree tmp;
4020   tree stmt;  
4021   stmtblock_t block;
4022
4023   gfc_get_backend_locus (&loc);
4024   gfc_set_backend_locus (&sym->declared_at);
4025
4026   /* Descriptor type.  */
4027   parm = sym->backend_decl;
4028   type = TREE_TYPE (parm);
4029   gcc_assert (GFC_ARRAY_TYPE_P (type));
4030
4031   gfc_start_block (&block);
4032
4033   if (sym->ts.type == BT_CHARACTER
4034       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
4035     gfc_conv_string_length (sym->ts.cl, &block);
4036
4037   /* Evaluate the bounds of the array.  */
4038   gfc_trans_array_bounds (type, sym, &offset, &block);
4039
4040   /* Set the offset.  */
4041   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4042     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
4043
4044   /* Set the pointer itself if we aren't using the parameter directly.  */
4045   if (TREE_CODE (parm) != PARM_DECL)
4046     {
4047       tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
4048       gfc_add_modify_expr (&block, parm, tmp);
4049     }
4050   stmt = gfc_finish_block (&block);
4051
4052   gfc_set_backend_locus (&loc);
4053
4054   gfc_start_block (&block);
4055
4056   /* Add the initialization code to the start of the function.  */
4057
4058   if (sym->attr.optional || sym->attr.not_always_present)
4059     {
4060       tmp = gfc_conv_expr_present (sym);
4061       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4062     }
4063   
4064   gfc_add_expr_to_block (&block, stmt);
4065   gfc_add_expr_to_block (&block, body);
4066
4067   return gfc_finish_block (&block);
4068 }
4069
4070
4071 /* Modify the descriptor of an array parameter so that it has the
4072    correct lower bound.  Also move the upper bound accordingly.
4073    If the array is not packed, it will be copied into a temporary.
4074    For each dimension we set the new lower and upper bounds.  Then we copy the
4075    stride and calculate the offset for this dimension.  We also work out
4076    what the stride of a packed array would be, and see it the two match.
4077    If the array need repacking, we set the stride to the values we just
4078    calculated, recalculate the offset and copy the array data.
4079    Code is also added to copy the data back at the end of the function.
4080    */
4081
4082 tree
4083 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
4084 {
4085   tree size;
4086   tree type;
4087   tree offset;
4088   locus loc;
4089   stmtblock_t block;
4090   stmtblock_t cleanup;
4091   tree lbound;
4092   tree ubound;
4093   tree dubound;
4094   tree dlbound;
4095   tree dumdesc;
4096   tree tmp;
4097   tree stmt;
4098   tree stride, stride2;
4099   tree stmt_packed;
4100   tree stmt_unpacked;
4101   tree partial;
4102   gfc_se se;
4103   int n;
4104   int checkparm;
4105   int no_repack;
4106   bool optional_arg;
4107
4108   /* Do nothing for pointer and allocatable arrays.  */
4109   if (sym->attr.pointer || sym->attr.allocatable)
4110     return body;
4111
4112   if (sym->attr.dummy && gfc_is_nodesc_array (sym))
4113     return gfc_trans_g77_array (sym, body);
4114
4115   gfc_get_backend_locus (&loc);
4116   gfc_set_backend_locus (&sym->declared_at);
4117
4118   /* Descriptor type.  */
4119   type = TREE_TYPE (tmpdesc);
4120   gcc_assert (GFC_ARRAY_TYPE_P (type));
4121   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4122   dumdesc = build_fold_indirect_ref (dumdesc);
4123   gfc_start_block (&block);
4124
4125   if (sym->ts.type == BT_CHARACTER
4126       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
4127     gfc_conv_string_length (sym->ts.cl, &block);
4128
4129   checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
4130
4131   no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
4132                 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
4133
4134   if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
4135     {
4136       /* For non-constant shape arrays we only check if the first dimension
4137          is contiguous.  Repacking higher dimensions wouldn't gain us
4138          anything as we still don't know the array stride.  */
4139       partial = gfc_create_var (boolean_type_node, "partial");
4140       TREE_USED (partial) = 1;
4141       tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
4142       tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, gfc_index_one_node);
4143       gfc_add_modify_expr (&block, partial, tmp);
4144     }
4145   else
4146     {
4147       partial = NULL_TREE;
4148     }
4149
4150   /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
4151      here, however I think it does the right thing.  */
4152   if (no_repack)
4153     {
4154       /* Set the first stride.  */
4155       stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
4156       stride = gfc_evaluate_now (stride, &block);
4157
4158       tmp = build2 (EQ_EXPR, boolean_type_node, stride, gfc_index_zero_node);
4159       tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
4160                     gfc_index_one_node, stride);
4161       stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
4162       gfc_add_modify_expr (&block, stride, tmp);
4163
4164       /* Allow the user to disable array repacking.  */
4165       stmt_unpacked = NULL_TREE;
4166     }
4167   else
4168     {
4169       gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
4170       /* A library call to repack the array if necessary.  */
4171       tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4172       stmt_unpacked = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
4173
4174       stride = gfc_index_one_node;
4175     }
4176
4177   /* This is for the case where the array data is used directly without
4178      calling the repack function.  */
4179   if (no_repack || partial != NULL_TREE)
4180     stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
4181   else
4182     stmt_packed = NULL_TREE;
4183
4184   /* Assign the data pointer.  */
4185   if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4186     {
4187       /* Don't repack unknown shape arrays when the first stride is 1.  */
4188       tmp = build3 (COND_EXPR, TREE_TYPE (stmt_packed), partial,
4189                     stmt_packed, stmt_unpacked);
4190     }
4191   else
4192     tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
4193   gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
4194
4195   offset = gfc_index_zero_node;
4196   size = gfc_index_one_node;
4197
4198   /* Evaluate the bounds of the array.  */
4199   for (n = 0; n < sym->as->rank; n++)
4200     {
4201       if (checkparm || !sym->as->upper[n])
4202         {
4203           /* Get the bounds of the actual parameter.  */
4204           dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
4205           dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
4206         }
4207       else
4208         {
4209           dubound = NULL_TREE;
4210           dlbound = NULL_TREE;
4211         }
4212
4213       lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
4214       if (!INTEGER_CST_P (lbound))
4215         {
4216           gfc_init_se (&se, NULL);
4217           gfc_conv_expr_type (&se, sym->as->lower[n],
4218                               gfc_array_index_type);
4219           gfc_add_block_to_block (&block, &se.pre);
4220           gfc_add_modify_expr (&block, lbound, se.expr);
4221         }
4222
4223       ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
4224       /* Set the desired upper bound.  */
4225       if (sym->as->upper[n])
4226         {
4227           /* We know what we want the upper bound to be.  */
4228           if (!INTEGER_CST_P (ubound))
4229             {
4230               gfc_init_se (&se, NULL);
4231               gfc_conv_expr_type (&se, sym->as->upper[n],
4232                                   gfc_array_index_type);
4233               gfc_add_block_to_block (&block, &se.pre);
4234               gfc_add_modify_expr (&block, ubound, se.expr);
4235             }
4236
4237           /* Check the sizes match.  */
4238           if (checkparm)
4239             {
4240               /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)).  */
4241               char * msg;
4242
4243               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4244                                  ubound, lbound);
4245               stride2 = build2 (MINUS_EXPR, gfc_array_index_type,
4246                                dubound, dlbound);
4247               tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride2);
4248               asprintf (&msg, "%s for dimension %d of array '%s'",
4249                         gfc_msg_bounds, n+1, sym->name);
4250               gfc_trans_runtime_check (tmp, &block, &loc, msg);
4251               gfc_free (msg);
4252             }
4253         }
4254       else
4255         {
4256           /* For assumed shape arrays move the upper bound by the same amount
4257              as the lower bound.  */
4258           tmp = build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
4259           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
4260           gfc_add_modify_expr (&block, ubound, tmp);
4261         }
4262       /* The offset of this dimension.  offset = offset - lbound * stride.  */
4263       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
4264       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
4265
4266       /* The size of this dimension, and the stride of the next.  */
4267       if (n + 1 < sym->as->rank)
4268         {
4269           stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
4270
4271           if (no_repack || partial != NULL_TREE)
4272             {
4273               stmt_unpacked =
4274                 gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
4275             }
4276
4277           /* Figure out the stride if not a known constant.  */
4278           if (!INTEGER_CST_P (stride))
4279             {
4280               if (no_repack)
4281                 stmt_packed = NULL_TREE;
4282               else
4283                 {
4284                   /* Calculate stride = size * (ubound + 1 - lbound).  */
4285                   tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4286                                      gfc_index_one_node, lbound);
4287                   tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4288                                      ubound, tmp);
4289                   size = fold_build2 (MULT_EXPR, gfc_array_index_type,
4290                                       size, tmp);
4291                   stmt_packed = size;
4292                 }
4293
4294               /* Assign the stride.  */
4295               if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
4296                 tmp = build3 (COND_EXPR, gfc_array_index_type, partial,
4297                               stmt_unpacked, stmt_packed);
4298               else
4299                 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
4300               gfc_add_modify_expr (&block, stride, tmp);
4301             }
4302         }
4303       else
4304         {
4305           stride = GFC_TYPE_ARRAY_SIZE (type);
4306
4307           if (stride && !INTEGER_CST_P (stride))
4308             {
4309               /* Calculate size = stride * (ubound + 1 - lbound).  */
4310               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4311                                  gfc_index_one_node, lbound);
4312               tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4313                                  ubound, tmp);
4314               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4315                                  GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
4316               gfc_add_modify_expr (&block, stride, tmp);
4317             }
4318         }
4319     }
4320
4321   /* Set the offset.  */
4322   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
4323     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
4324
4325   gfc_trans_vla_type_sizes (sym, &block);
4326
4327   stmt = gfc_finish_block (&block);
4328
4329   gfc_start_block (&block);
4330
4331   /* Only do the entry/initialization code if the arg is present.  */
4332   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
4333   optional_arg = (sym->attr.optional
4334                   || (sym->ns->proc_name->attr.entry_master
4335                       && sym->attr.dummy));
4336   if (optional_arg)
4337     {
4338       tmp = gfc_conv_expr_present (sym);
4339       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4340     }
4341   gfc_add_expr_to_block (&block, stmt);
4342
4343   /* Add the main function body.  */
4344   gfc_add_expr_to_block (&block, body);
4345
4346   /* Cleanup code.  */
4347   if (!no_repack)
4348     {
4349       gfc_start_block (&cleanup);
4350       
4351       if (sym->attr.intent != INTENT_IN)
4352         {
4353           /* Copy the data back.  */
4354           tmp = build_call_expr (gfor_fndecl_in_unpack, 2, dumdesc, tmpdesc);
4355           gfc_add_expr_to_block (&cleanup, tmp);
4356         }
4357
4358       /* Free the temporary.  */
4359       tmp = gfc_call_free (tmpdesc);
4360       gfc_add_expr_to_block (&cleanup, tmp);
4361
4362       stmt = gfc_finish_block (&cleanup);
4363         
4364       /* Only do the cleanup if the array was repacked.  */
4365       tmp = build_fold_indirect_ref (dumdesc);
4366       tmp = gfc_conv_descriptor_data_get (tmp);
4367       tmp = build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
4368       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4369
4370       if (optional_arg)
4371         {
4372           tmp = gfc_conv_expr_present (sym);
4373           stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4374         }
4375       gfc_add_expr_to_block (&block, stmt);
4376     }
4377   /* We don't need to free any memory allocated by internal_pack as it will
4378      be freed at the end of the function by pop_context.  */
4379   return gfc_finish_block (&block);
4380 }
4381
4382
4383 /* Calculate the overall offset, including subreferences.  */
4384 static void
4385 gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
4386                         bool subref, gfc_expr *expr)
4387 {
4388   tree tmp;
4389   tree field;
4390   tree stride;
4391   tree index;
4392   gfc_ref *ref;
4393   gfc_se start;
4394   int n;
4395
4396   /* If offset is NULL and this is not a subreferenced array, there is
4397      nothing to do.  */
4398   if (offset == NULL_TREE)
4399     {
4400       if (subref)
4401         offset = gfc_index_zero_node;
4402       else
4403         return;
4404     }
4405
4406   tmp = gfc_conv_array_data (desc);
4407   tmp = build_fold_indirect_ref (tmp);
4408   tmp = gfc_build_array_ref (tmp, offset, NULL);
4409
4410   /* Offset the data pointer for pointer assignments from arrays with
4411      subreferences; eg. my_integer => my_type(:)%integer_component.  */
4412   if (subref)
4413     {
4414       /* Go past the array reference.  */
4415       for (ref = expr->ref; ref; ref = ref->next)
4416         if (ref->type == REF_ARRAY &&
4417               ref->u.ar.type != AR_ELEMENT)
4418           {
4419             ref = ref->next;
4420             break;
4421           }
4422
4423       /* Calculate the offset for each subsequent subreference.  */
4424       for (; ref; ref = ref->next)
4425         {
4426           switch (ref->type)
4427             {
4428             case REF_COMPONENT:
4429               field = ref->u.c.component->backend_decl;
4430               gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
4431               tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
4432               break;
4433
4434             case REF_SUBSTRING:
4435               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
4436               gfc_init_se (&start, NULL);
4437               gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
4438               gfc_add_block_to_block (block, &start.pre);
4439               tmp = gfc_build_array_ref (tmp, start.expr, NULL);
4440               break;
4441
4442             case REF_ARRAY:
4443               gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE
4444                             && ref->u.ar.type == AR_ELEMENT);
4445
4446               /* TODO - Add bounds checking.  */
4447               stride = gfc_index_one_node;
4448               index = gfc_index_zero_node;
4449               for (n = 0; n < ref->u.ar.dimen; n++)
4450                 {
4451                   tree itmp;
4452                   tree jtmp;
4453
4454                   /* Update the index.  */
4455                   gfc_init_se (&start, NULL);
4456                   gfc_conv_expr_type (&start, ref->u.ar.start[n], gfc_array_index_type);
4457                   itmp = gfc_evaluate_now (start.expr, block);
4458                   gfc_init_se (&start, NULL);
4459                   gfc_conv_expr_type (&start, ref->u.ar.as->lower[n], gfc_array_index_type);
4460                   jtmp = gfc_evaluate_now (start.expr, block);
4461                   itmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, itmp, jtmp);
4462                   itmp = fold_build2 (MULT_EXPR, gfc_array_index_type, itmp, stride);
4463                   index = fold_build2 (PLUS_EXPR, gfc_array_index_type, itmp, index);
4464                   index = gfc_evaluate_now (index, block);
4465
4466                   /* Update the stride.  */
4467                   gfc_init_se (&start, NULL);
4468                   gfc_conv_expr_type (&start, ref->u.ar.as->upper[n], gfc_array_index_type);
4469                   itmp =  fold_build2 (MINUS_EXPR, gfc_array_index_type, start.expr, jtmp);
4470                   itmp =  fold_build2 (PLUS_EXPR, gfc_array_index_type,
4471                                        gfc_index_one_node, itmp);
4472                   stride =  fold_build2 (MULT_EXPR, gfc_array_index_type, stride, itmp);
4473                   stride = gfc_evaluate_now (stride, block);
4474                 }
4475
4476               /* Apply the index to obtain the array element.  */
4477               tmp = gfc_build_array_ref (tmp, index, NULL);
4478               break;
4479
4480             default:
4481               gcc_unreachable ();
4482               break;
4483             }
4484         }
4485     }
4486
4487   /* Set the target data pointer.  */
4488   offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
4489   gfc_conv_descriptor_data_set (block, parm, offset);
4490 }
4491
4492
4493 /* Convert an array for passing as an actual argument.  Expressions and
4494    vector subscripts are evaluated and stored in a temporary, which is then
4495    passed.  For whole arrays the descriptor is passed.  For array sections
4496    a modified copy of the descriptor is passed, but using the original data.
4497
4498    This function is also used for array pointer assignments, and there
4499    are three cases:
4500
4501      - se->want_pointer && !se->direct_byref
4502          EXPR is an actual argument.  On exit, se->expr contains a
4503          pointer to the array descriptor.
4504
4505      - !se->want_pointer && !se->direct_byref
4506          EXPR is an actual argument to an intrinsic function or the
4507          left-hand side of a pointer assignment.  On exit, se->expr
4508          contains the descriptor for EXPR.
4509
4510      - !se->want_pointer && se->direct_byref
4511          EXPR is the right-hand side of a pointer assignment and
4512          se->expr is the descriptor for the previously-evaluated
4513          left-hand side.  The function creates an assignment from
4514          EXPR to se->expr.  */
4515
4516 void
4517 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
4518 {
4519   gfc_loopinfo loop;
4520   gfc_ss *secss;
4521   gfc_ss_info *info;
4522   int need_tmp;
4523   int n;
4524   tree tmp;
4525   tree desc;
4526   stmtblock_t block;
4527   tree start;
4528   tree offset;
4529   int full;
4530   bool subref_array_target = false;
4531
4532   gcc_assert (ss != gfc_ss_terminator);
4533
4534   /* Special case things we know we can pass easily.  */
4535   switch (expr->expr_type)
4536     {
4537     case EXPR_VARIABLE:
4538       /* If we have a linear array section, we can pass it directly.
4539          Otherwise we need to copy it into a temporary.  */
4540
4541       /* Find the SS for the array section.  */
4542       secss = ss;
4543       while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
4544         secss = secss->next;
4545
4546       gcc_assert (secss != gfc_ss_terminator);
4547       info = &secss->data.info;
4548
4549       /* Get the descriptor for the array.  */
4550       gfc_conv_ss_descriptor (&se->pre, secss, 0);
4551       desc = info->descriptor;
4552
4553       subref_array_target = se->direct_byref && is_subref_array (expr);
4554       need_tmp = gfc_ref_needs_temporary_p (expr->ref)
4555                         && !subref_array_target;
4556
4557       if (need_tmp)
4558         full = 0;
4559       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4560         {
4561           /* Create a new descriptor if the array doesn't have one.  */
4562           full = 0;
4563         }
4564       else if (info->ref->u.ar.type == AR_FULL)
4565         full = 1;
4566       else if (se->direct_byref)
4567         full = 0;
4568       else
4569         full = gfc_full_array_ref_p (info->ref);
4570
4571       if (full)
4572         {
4573           if (se->direct_byref)
4574             {
4575               /* Copy the descriptor for pointer assignments.  */
4576               gfc_add_modify_expr (&se->pre, se->expr, desc);
4577
4578               /* Add any offsets from subreferences.  */
4579               gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE,
4580                                       subref_array_target, expr);
4581             }
4582           else if (se->want_pointer)
4583             {
4584               /* We pass full arrays directly.  This means that pointers and
4585                  allocatable arrays should also work.  */
4586               se->expr = build_fold_addr_expr (desc);
4587             }
4588           else
4589             {
4590               se->expr = desc;
4591             }
4592
4593           if (expr->ts.type == BT_CHARACTER)
4594             se->string_length = gfc_get_expr_charlen (expr);
4595
4596           return;
4597         }
4598       break;
4599       
4600     case EXPR_FUNCTION:
4601       /* A transformational function return value will be a temporary
4602          array descriptor.  We still need to go through the scalarizer
4603          to create the descriptor.  Elemental functions ar handled as
4604          arbitrary expressions, i.e. copy to a temporary.  */
4605       secss = ss;
4606       /* Look for the SS for this function.  */
4607       while (secss != gfc_ss_terminator
4608              && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
4609         secss = secss->next;
4610
4611       if (se->direct_byref)
4612         {
4613           gcc_assert (secss != gfc_ss_terminator);
4614
4615           /* For pointer assignments pass the descriptor directly.  */
4616           se->ss = secss;
4617           se->expr = build_fold_addr_expr (se->expr);
4618           gfc_conv_expr (se, expr);
4619           return;
4620         }
4621
4622       if (secss == gfc_ss_terminator)
4623         {
4624           /* Elemental function.  */
4625           need_tmp = 1;
4626           info = NULL;
4627         }
4628       else
4629         {
4630           /* Transformational function.  */
4631           info = &secss->data.info;
4632           need_tmp = 0;
4633         }
4634       break;
4635
4636     case EXPR_ARRAY:
4637       /* Constant array constructors don't need a temporary.  */
4638       if (ss->type == GFC_SS_CONSTRUCTOR
4639           && expr->ts.type != BT_CHARACTER
4640           && gfc_constant_array_constructor_p (expr->value.constructor))
4641         {
4642           need_tmp = 0;
4643           info = &ss->data.info;
4644           secss = ss;
4645         }
4646       else
4647         {
4648           need_tmp = 1;
4649           secss = NULL;
4650           info = NULL;
4651         }
4652       break;
4653
4654     default:
4655       /* Something complicated.  Copy it into a temporary.  */
4656       need_tmp = 1;
4657       secss = NULL;
4658       info = NULL;
4659       break;
4660     }
4661
4662
4663   gfc_init_loopinfo (&loop);
4664
4665   /* Associate the SS with the loop.  */
4666   gfc_add_ss_to_loop (&loop, ss);
4667
4668   /* Tell the scalarizer not to bother creating loop variables, etc.  */
4669   if (!need_tmp)
4670     loop.array_parameter = 1;
4671   else
4672     /* The right-hand side of a pointer assignment mustn't use a temporary.  */
4673     gcc_assert (!se->direct_byref);
4674
4675   /* Setup the scalarizing loops and bounds.  */
4676   gfc_conv_ss_startstride (&loop);
4677
4678   if (need_tmp)
4679     {
4680       /* Tell the scalarizer to make a temporary.  */
4681       loop.temp_ss = gfc_get_ss ();
4682       loop.temp_ss->type = GFC_SS_TEMP;
4683       loop.temp_ss->next = gfc_ss_terminator;
4684
4685       if (expr->ts.type == BT_CHARACTER && !expr->ts.cl->backend_decl)
4686         gfc_conv_string_length (expr->ts.cl, &se->pre);
4687
4688       loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
4689
4690       if (expr->ts.type == BT_CHARACTER)
4691         loop.temp_ss->string_length = expr->ts.cl->backend_decl;
4692       else
4693         loop.temp_ss->string_length = NULL;
4694
4695       se->string_length = loop.temp_ss->string_length;
4696       loop.temp_ss->data.temp.dimen = loop.dimen;
4697       gfc_add_ss_to_loop (&loop, loop.temp_ss);
4698     }
4699
4700   gfc_conv_loop_setup (&loop);
4701
4702   if (need_tmp)
4703     {
4704       /* Copy into a temporary and pass that.  We don't need to copy the data
4705          back because expressions and vector subscripts must be INTENT_IN.  */
4706       /* TODO: Optimize passing function return values.  */
4707       gfc_se lse;
4708       gfc_se rse;
4709
4710       /* Start the copying loops.  */
4711       gfc_mark_ss_chain_used (loop.temp_ss, 1);
4712       gfc_mark_ss_chain_used (ss, 1);
4713       gfc_start_scalarized_body (&loop, &block);
4714
4715       /* Copy each data element.  */
4716       gfc_init_se (&lse, NULL);
4717       gfc_copy_loopinfo_to_se (&lse, &loop);
4718       gfc_init_se (&rse, NULL);
4719       gfc_copy_loopinfo_to_se (&rse, &loop);
4720
4721       lse.ss = loop.temp_ss;
4722       rse.ss = ss;
4723
4724       gfc_conv_scalarized_array_ref (&lse, NULL);
4725       if (expr->ts.type == BT_CHARACTER)
4726         {
4727           gfc_conv_expr (&rse, expr);
4728           if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
4729             rse.expr = build_fold_indirect_ref (rse.expr);
4730         }
4731       else
4732         gfc_conv_expr_val (&rse, expr);
4733
4734       gfc_add_block_to_block (&block, &rse.pre);
4735       gfc_add_block_to_block (&block, &lse.pre);
4736
4737       lse.string_length = rse.string_length;
4738       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true,
4739                                      expr->expr_type == EXPR_VARIABLE);
4740       gfc_add_expr_to_block (&block, tmp);
4741
4742       /* Finish the copying loops.  */
4743       gfc_trans_scalarizing_loops (&loop, &block);
4744
4745       desc = loop.temp_ss->data.info.descriptor;
4746
4747       gcc_assert (is_gimple_lvalue (desc));
4748     }
4749   else if (expr->expr_type == EXPR_FUNCTION)
4750     {
4751       desc = info->descriptor;
4752       se->string_length = ss->string_length;
4753     }
4754   else
4755     {
4756       /* We pass sections without copying to a temporary.  Make a new
4757          descriptor and point it at the section we want.  The loop variable
4758          limits will be the limits of the section.
4759          A function may decide to repack the array to speed up access, but
4760          we're not bothered about that here.  */
4761       int dim, ndim;
4762       tree parm;
4763       tree parmtype;
4764       tree stride;
4765       tree from;
4766       tree to;
4767       tree base;
4768
4769       /* Set the string_length for a character array.  */
4770       if (expr->ts.type == BT_CHARACTER)
4771         se->string_length =  gfc_get_expr_charlen (expr);
4772
4773       desc = info->descriptor;
4774       gcc_assert (secss && secss != gfc_ss_terminator);
4775       if (se->direct_byref)
4776         {
4777           /* For pointer assignments we fill in the destination.  */
4778           parm = se->expr;
4779           parmtype = TREE_TYPE (parm);
4780         }
4781       else
4782         {
4783           /* Otherwise make a new one.  */
4784           parmtype = gfc_get_element_type (TREE_TYPE (desc));
4785           parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
4786                                                 loop.from, loop.to, 0);
4787           parm = gfc_create_var (parmtype, "parm");
4788         }
4789
4790       offset = gfc_index_zero_node;
4791       dim = 0;
4792
4793       /* The following can be somewhat confusing.  We have two
4794          descriptors, a new one and the original array.
4795          {parm, parmtype, dim} refer to the new one.
4796          {desc, type, n, secss, loop} refer to the original, which maybe
4797          a descriptorless array.
4798          The bounds of the scalarization are the bounds of the section.
4799          We don't have to worry about numeric overflows when calculating
4800          the offsets because all elements are within the array data.  */
4801
4802       /* Set the dtype.  */
4803       tmp = gfc_conv_descriptor_dtype (parm);
4804       gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
4805
4806       /* Set offset for assignments to pointer only to zero if it is not
4807          the full array.  */
4808       if (se->direct_byref
4809           && info->ref && info->ref->u.ar.type != AR_FULL)
4810         base = gfc_index_zero_node;
4811       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4812         base = gfc_evaluate_now (gfc_conv_array_offset (desc), &loop.pre);
4813       else
4814         base = NULL_TREE;
4815
4816       ndim = info->ref ? info->ref->u.ar.dimen : info->dimen;
4817       for (n = 0; n < ndim; n++)
4818         {
4819           stride = gfc_conv_array_stride (desc, n);
4820
4821           /* Work out the offset.  */
4822           if (info->ref
4823               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4824             {
4825               gcc_assert (info->subscript[n]
4826                       && info->subscript[n]->type == GFC_SS_SCALAR);
4827               start = info->subscript[n]->data.scalar.expr;
4828             }
4829           else
4830             {
4831               /* Check we haven't somehow got out of sync.  */
4832               gcc_assert (info->dim[dim] == n);
4833
4834               /* Evaluate and remember the start of the section.  */
4835               start = info->start[dim];
4836               stride = gfc_evaluate_now (stride, &loop.pre);
4837             }
4838
4839           tmp = gfc_conv_array_lbound (desc, n);
4840           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
4841
4842           tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
4843           offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
4844
4845           if (info->ref
4846               && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4847             {
4848               /* For elemental dimensions, we only need the offset.  */
4849               continue;
4850             }
4851
4852           /* Vector subscripts need copying and are handled elsewhere.  */
4853           if (info->ref)
4854             gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
4855
4856           /* Set the new lower bound.  */
4857           from = loop.from[dim];
4858           to = loop.to[dim];
4859
4860           /* If we have an array section or are assigning make sure that
4861              the lower bound is 1.  References to the full
4862              array should otherwise keep the original bounds.  */
4863           if ((!info->ref
4864                   || info->ref->u.ar.type != AR_FULL)
4865               && !integer_onep (from))
4866             {
4867               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4868                                  gfc_index_one_node, from);
4869               to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
4870               from = gfc_index_one_node;
4871             }
4872           tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
4873           gfc_add_modify_expr (&loop.pre, tmp, from);
4874
4875           /* Set the new upper bound.  */
4876           tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
4877           gfc_add_modify_expr (&loop.pre, tmp, to);
4878
4879           /* Multiply the stride by the section stride to get the
4880              total stride.  */
4881           stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
4882                                 stride, info->stride[dim]);
4883
4884           if (se->direct_byref && info->ref && info->ref->u.ar.type != AR_FULL)
4885             {
4886               base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4887                                   base, stride);
4888             }
4889           else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4890             {
4891               tmp = gfc_conv_array_lbound (desc, n);
4892               tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4893                                  tmp, loop.from[dim]);
4894               tmp = fold_build2 (MULT_EXPR, TREE_TYPE (base),
4895                                  tmp, gfc_conv_array_stride (desc, n));
4896               base = fold_build2 (PLUS_EXPR, TREE_TYPE (base),
4897                                   tmp, base);
4898             }
4899
4900           /* Store the new stride.  */
4901           tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
4902           gfc_add_modify_expr (&loop.pre, tmp, stride);
4903
4904           dim++;
4905         }
4906
4907       if (se->data_not_needed)
4908         gfc_conv_descriptor_data_set (&loop.pre, parm, gfc_index_zero_node);
4909       else
4910         /* Point the data pointer at the first element in the section.  */
4911         gfc_get_dataptr_offset (&loop.pre, parm, desc, offset,
4912                                 subref_array_target, expr);
4913
4914       if ((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
4915           && !se->data_not_needed)
4916         {
4917           /* Set the offset.  */
4918           tmp = gfc_conv_descriptor_offset (parm);
4919           gfc_add_modify_expr (&loop.pre, tmp, base);
4920         }
4921       else
4922         {
4923           /* Only the callee knows what the correct offset it, so just set
4924              it to zero here.  */
4925           tmp = gfc_conv_descriptor_offset (parm);
4926           gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
4927         }
4928       desc = parm;
4929     }
4930
4931   if (!se->direct_byref)
4932     {
4933       /* Get a pointer to the new descriptor.  */
4934       if (se->want_pointer)
4935         se->expr = build_fold_addr_expr (desc);
4936       else
4937         se->expr = desc;
4938     }
4939
4940   gfc_add_block_to_block (&se->pre, &loop.pre);
4941   gfc_add_block_to_block (&se->post, &loop.post);
4942
4943   /* Cleanup the scalarizer.  */
4944   gfc_cleanup_loop (&loop);
4945 }
4946
4947
4948 /* Convert an array for passing as an actual parameter.  */
4949 /* TODO: Optimize passing g77 arrays.  */
4950
4951 void
4952 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
4953 {
4954   tree ptr;
4955   tree desc;
4956   tree tmp = NULL_TREE;
4957   tree stmt;
4958   tree parent = DECL_CONTEXT (current_function_decl);
4959   bool full_array_var, this_array_result;
4960   gfc_symbol *sym;
4961   stmtblock_t block;
4962
4963   full_array_var = (expr->expr_type == EXPR_VARIABLE
4964                       && expr->ref->u.ar.type == AR_FULL);
4965   sym = full_array_var ? expr->symtree->n.sym : NULL;
4966
4967   if (expr->expr_type == EXPR_ARRAY && expr->ts.type == BT_CHARACTER)
4968     {
4969       get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp);
4970       expr->ts.cl->backend_decl = tmp;
4971       se->string_length = gfc_evaluate_now (tmp, &se->pre);
4972     }
4973
4974   /* Is this the result of the enclosing procedure?  */
4975   this_array_result = (full_array_var && sym->attr.flavor == FL_PROCEDURE);
4976   if (this_array_result
4977         && (sym->backend_decl != current_function_decl)
4978         && (sym->backend_decl != parent))
4979     this_array_result = false;
4980
4981   /* Passing address of the array if it is not pointer or assumed-shape.  */
4982   if (full_array_var && g77 && !this_array_result)
4983     {
4984       tmp = gfc_get_symbol_decl (sym);
4985
4986       if (sym->ts.type == BT_CHARACTER)
4987         se->string_length = sym->ts.cl->backend_decl;
4988       if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE 
4989           && !sym->attr.allocatable)
4990         {
4991           /* Some variables are declared directly, others are declared as
4992              pointers and allocated on the heap.  */
4993           if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
4994             se->expr = tmp;
4995           else
4996             se->expr = build_fold_addr_expr (tmp);
4997           return;
4998         }
4999       if (sym->attr.allocatable)
5000         {
5001           if (sym->attr.dummy || sym->attr.result)
5002             {
5003               gfc_conv_expr_descriptor (se, expr, ss);
5004               se->expr = gfc_conv_array_data (se->expr);
5005             }
5006           else
5007             se->expr = gfc_conv_array_data (tmp);
5008           return;
5009         }
5010     }
5011
5012   if (this_array_result)
5013     {
5014       /* Result of the enclosing function.  */
5015       gfc_conv_expr_descriptor (se, expr, ss);
5016       se->expr = build_fold_addr_expr (se->expr);
5017
5018       if (g77 && TREE_TYPE (TREE_TYPE (se->expr)) != NULL_TREE
5019               && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
5020         se->expr = gfc_conv_array_data (build_fold_indirect_ref (se->expr));
5021
5022       return;
5023     }
5024   else
5025     {
5026       /* Every other type of array.  */
5027       se->want_pointer = 1;
5028       gfc_conv_expr_descriptor (se, expr, ss);
5029     }
5030
5031
5032   /* Deallocate the allocatable components of structures that are
5033      not variable.  */
5034   if (expr->ts.type == BT_DERIVED
5035         && expr->ts.derived->attr.alloc_comp
5036         && expr->expr_type != EXPR_VARIABLE)
5037     {
5038       tmp = build_fold_indirect_ref (se->expr);
5039       tmp = gfc_deallocate_alloc_comp (expr->ts.derived, tmp, expr->rank);
5040       gfc_add_expr_to_block (&se->post, tmp);
5041     }
5042
5043   if (g77)
5044     {
5045       desc = se->expr;
5046       /* Repack the array.  */
5047       ptr = build_call_expr (gfor_fndecl_in_pack, 1, desc);
5048       ptr = gfc_evaluate_now (ptr, &se->pre);
5049       se->expr = ptr;
5050
5051       gfc_start_block (&block);
5052
5053       /* Copy the data back.  */
5054       tmp = build_call_expr (gfor_fndecl_in_unpack, 2, desc, ptr);
5055       gfc_add_expr_to_block (&block, tmp);
5056
5057       /* Free the temporary.  */
5058       tmp = gfc_call_free (convert (pvoid_type_node, ptr));
5059       gfc_add_expr_to_block (&block, tmp);
5060
5061       stmt = gfc_finish_block (&block);
5062
5063       gfc_init_block (&block);
5064       /* Only if it was repacked.  This code needs to be executed before the
5065          loop cleanup code.  */
5066       tmp = build_fold_indirect_ref (desc);
5067       tmp = gfc_conv_array_data (tmp);
5068       tmp = build2 (NE_EXPR, boolean_type_node,
5069                     fold_convert (TREE_TYPE (tmp), ptr), tmp);
5070       tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
5071
5072       gfc_add_expr_to_block (&block, tmp);
5073       gfc_add_block_to_block (&block, &se->post);
5074
5075       gfc_init_block (&se->post);
5076       gfc_add_block_to_block (&se->post, &block);
5077     }
5078 }
5079
5080
5081 /* Generate code to deallocate an array, if it is allocated.  */
5082
5083 tree
5084 gfc_trans_dealloc_allocated (tree descriptor)
5085
5086   tree tmp;
5087   tree var;
5088   stmtblock_t block;
5089
5090   gfc_start_block (&block);
5091
5092   var = gfc_conv_descriptor_data_get (descriptor);
5093   STRIP_NOPS (var);
5094
5095   /* Call array_deallocate with an int * present in the second argument.
5096      Although it is ignored here, it's presence ensures that arrays that
5097      are already deallocated are ignored.  */
5098   tmp = gfc_deallocate_with_status (var, NULL_TREE, true);
5099   gfc_add_expr_to_block (&block, tmp);
5100
5101   /* Zero the data pointer.  */
5102   tmp = build2 (MODIFY_EXPR, void_type_node,
5103                 var, build_int_cst (TREE_TYPE (var), 0));
5104   gfc_add_expr_to_block (&block, tmp);
5105
5106   return gfc_finish_block (&block);
5107 }
5108
5109
5110 /* This helper function calculates the size in words of a full array.  */
5111
5112 static tree
5113 get_full_array_size (stmtblock_t *block, tree decl, int rank)
5114 {
5115   tree idx;
5116   tree nelems;
5117   tree tmp;
5118   idx = gfc_rank_cst[rank - 1];
5119   nelems = gfc_conv_descriptor_ubound (decl, idx);
5120   tmp = gfc_conv_descriptor_lbound (decl, idx);
5121   tmp = build2 (MINUS_EXPR, gfc_array_index_type, nelems, tmp);
5122   tmp = build2 (PLUS_EXPR, gfc_array_index_type,
5123                 tmp, gfc_index_one_node);
5124   tmp = gfc_evaluate_now (tmp, block);
5125
5126   nelems = gfc_conv_descriptor_stride (decl, idx);
5127   tmp = build2 (MULT_EXPR, gfc_array_index_type, nelems, tmp);
5128   return gfc_evaluate_now (tmp, block);
5129 }
5130
5131
5132 /* Allocate dest to the same size as src, and copy src -> dest.  */
5133
5134 tree
5135 gfc_duplicate_allocatable(tree dest, tree src, tree type, int rank)
5136 {
5137   tree tmp;
5138   tree size;
5139   tree nelems;
5140   tree null_cond;
5141   tree null_data;
5142   stmtblock_t block;
5143
5144   /* If the source is null, set the destination to null.  */
5145   gfc_init_block (&block);
5146   gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
5147   null_data = gfc_finish_block (&block);
5148
5149   gfc_init_block (&block);
5150
5151   nelems = get_full_array_size (&block, src, rank);
5152   size = fold_build2 (MULT_EXPR, gfc_array_index_type, nelems,
5153                       fold_convert (gfc_array_index_type,
5154                                     TYPE_SIZE_UNIT (gfc_get_element_type (type))));
5155
5156   /* Allocate memory to the destination.  */
5157   tmp = gfc_call_malloc (&block, TREE_TYPE (gfc_conv_descriptor_data_get (src)),
5158                          size);
5159   gfc_conv_descriptor_data_set (&block, dest, tmp);
5160
5161   /* We know the temporary and the value will be the same length,
5162      so can use memcpy.  */
5163   tmp = built_in_decls[BUILT_IN_MEMCPY];
5164   tmp = build_call_expr (tmp, 3, gfc_conv_descriptor_data_get (dest),
5165                          gfc_conv_descriptor_data_get (src), size);
5166   gfc_add_expr_to_block (&block, tmp);
5167   tmp = gfc_finish_block (&block);
5168
5169   /* Null the destination if the source is null; otherwise do
5170      the allocate and copy.  */
5171   null_cond = gfc_conv_descriptor_data_get (src);
5172   null_cond = convert (pvoid_type_node, null_cond);
5173   null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
5174                       null_pointer_node);
5175   return build3_v (COND_EXPR, null_cond, tmp, null_data);
5176 }
5177
5178
5179 /* Recursively traverse an object of derived type, generating code to
5180    deallocate, nullify or copy allocatable components.  This is the work horse
5181    function for the functions named in this enum.  */
5182
5183 enum {DEALLOCATE_ALLOC_COMP = 1, NULLIFY_ALLOC_COMP, COPY_ALLOC_COMP};
5184
5185 static tree
5186 structure_alloc_comps (gfc_symbol * der_type, tree decl,
5187                        tree dest, int rank, int purpose)
5188 {
5189   gfc_component *c;
5190   gfc_loopinfo loop;
5191   stmtblock_t fnblock;
5192   stmtblock_t loopbody;
5193   tree tmp;
5194   tree comp;
5195   tree dcmp;
5196   tree nelems;
5197   tree index;
5198   tree var;
5199   tree cdecl;
5200   tree ctype;
5201   tree vref, dref;
5202   tree null_cond = NULL_TREE;
5203
5204   gfc_init_block (&fnblock);
5205
5206   if (POINTER_TYPE_P (TREE_TYPE (decl)))
5207     decl = build_fold_indirect_ref (decl);
5208
5209   /* If this an array of derived types with allocatable components
5210      build a loop and recursively call this function.  */
5211   if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
5212         || GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
5213     {
5214       tmp = gfc_conv_array_data (decl);
5215       var = build_fold_indirect_ref (tmp);
5216         
5217       /* Get the number of elements - 1 and set the counter.  */
5218       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
5219         {
5220           /* Use the descriptor for an allocatable array.  Since this
5221              is a full array reference, we only need the descriptor
5222              information from dimension = rank.  */
5223           tmp = get_full_array_size (&fnblock, decl, rank);
5224           tmp = build2 (MINUS_EXPR, gfc_array_index_type,
5225                         tmp, gfc_index_one_node);
5226
5227           null_cond = gfc_conv_descriptor_data_get (decl);
5228           null_cond = build2 (NE_EXPR, boolean_type_node, null_cond,
5229                               build_int_cst (TREE_TYPE (null_cond), 0));
5230         }
5231       else
5232         {
5233           /*  Otherwise use the TYPE_DOMAIN information.  */
5234           tmp =  array_type_nelts (TREE_TYPE (decl));
5235           tmp = fold_convert (gfc_array_index_type, tmp);
5236         }
5237
5238       /* Remember that this is, in fact, the no. of elements - 1.  */
5239       nelems = gfc_evaluate_now (tmp, &fnblock);
5240       index = gfc_create_var (gfc_array_index_type, "S");
5241
5242       /* Build the body of the loop.  */
5243       gfc_init_block (&loopbody);
5244
5245       vref = gfc_build_array_ref (var, index, NULL);
5246
5247       if (purpose == COPY_ALLOC_COMP)
5248         {
5249           tmp = gfc_duplicate_allocatable (dest, decl, TREE_TYPE(decl), rank);
5250           gfc_add_expr_to_block (&fnblock, tmp);
5251
5252           tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (dest));
5253           dref = gfc_build_array_ref (tmp, index, NULL);
5254           tmp = structure_alloc_comps (der_type, vref, dref, rank, purpose);
5255         }
5256       else
5257         tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose);
5258
5259       gfc_add_expr_to_block (&loopbody, tmp);
5260
5261       /* Build the loop and return.  */
5262       gfc_init_loopinfo (&loop);
5263       loop.dimen = 1;
5264       loop.from[0] = gfc_index_zero_node;
5265       loop.loopvar[0] = index;
5266       loop.to[0] = nelems;
5267       gfc_trans_scalarizing_loops (&loop, &loopbody);
5268       gfc_add_block_to_block (&fnblock, &loop.pre);
5269
5270       tmp = gfc_finish_block (&fnblock);
5271       if (null_cond != NULL_TREE)
5272         tmp = build3_v (COND_EXPR, null_cond, tmp, build_empty_stmt ());
5273
5274       return tmp;
5275     }
5276
5277   /* Otherwise, act on the components or recursively call self to
5278      act on a chain of components.  */
5279   for (c = der_type->components; c; c = c->next)
5280     {
5281       bool cmp_has_alloc_comps = (c->ts.type == BT_DERIVED)
5282                                     && c->ts.derived->attr.alloc_comp;
5283       cdecl = c->backend_decl;
5284       ctype = TREE_TYPE (cdecl);
5285
5286       switch (purpose)
5287         {
5288         case DEALLOCATE_ALLOC_COMP:
5289           /* Do not deallocate the components of ultimate pointer
5290              components.  */
5291           if (cmp_has_alloc_comps && !c->pointer)
5292             {
5293               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5294               rank = c->as ? c->as->rank : 0;
5295               tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
5296                                            rank, purpose);
5297               gfc_add_expr_to_block (&fnblock, tmp);
5298             }
5299
5300           if (c->allocatable)
5301             {
5302               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5303               tmp = gfc_trans_dealloc_allocated (comp);
5304               gfc_add_expr_to_block (&fnblock, tmp);
5305             }
5306           break;
5307
5308         case NULLIFY_ALLOC_COMP:
5309           if (c->pointer)
5310             continue;
5311           else if (c->allocatable)
5312             {
5313               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5314               gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
5315             }
5316           else if (cmp_has_alloc_comps)
5317             {
5318               comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5319               rank = c->as ? c->as->rank : 0;
5320               tmp = structure_alloc_comps (c->ts.derived, comp, NULL_TREE,
5321                                            rank, purpose);
5322               gfc_add_expr_to_block (&fnblock, tmp);
5323             }
5324           break;
5325
5326         case COPY_ALLOC_COMP:
5327           if (c->pointer)
5328             continue;
5329
5330           /* We need source and destination components.  */
5331           comp = build3 (COMPONENT_REF, ctype, decl, cdecl, NULL_TREE);
5332           dcmp = build3 (COMPONENT_REF, ctype, dest, cdecl, NULL_TREE);
5333           dcmp = fold_convert (TREE_TYPE (comp), dcmp);
5334
5335           if (c->allocatable && !cmp_has_alloc_comps)
5336             {
5337               tmp = gfc_duplicate_allocatable(dcmp, comp, ctype, c->as->rank);
5338               gfc_add_expr_to_block (&fnblock, tmp);
5339             }
5340
5341           if (cmp_has_alloc_comps)
5342             {
5343               rank = c->as ? c->as->rank : 0;
5344               tmp = fold_convert (TREE_TYPE (dcmp), comp);
5345               gfc_add_modify_expr (&fnblock, dcmp, tmp);
5346               tmp = structure_alloc_comps (c->ts.derived, comp, dcmp,
5347                                            rank, purpose);
5348               gfc_add_expr_to_block (&fnblock, tmp);
5349             }
5350           break;
5351
5352         default:
5353           gcc_unreachable ();
5354           break;
5355         }
5356     }
5357
5358   return gfc_finish_block (&fnblock);
5359 }
5360
5361 /* Recursively traverse an object of derived type, generating code to
5362    nullify allocatable components.  */
5363
5364 tree
5365 gfc_nullify_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5366 {
5367   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5368                                 NULLIFY_ALLOC_COMP);
5369 }
5370
5371
5372 /* Recursively traverse an object of derived type, generating code to
5373    deallocate allocatable components.  */
5374
5375 tree
5376 gfc_deallocate_alloc_comp (gfc_symbol * der_type, tree decl, int rank)
5377 {
5378   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
5379                                 DEALLOCATE_ALLOC_COMP);
5380 }
5381
5382
5383 /* Recursively traverse an object of derived type, generating code to
5384    copy its allocatable components.  */
5385
5386 tree
5387 gfc_copy_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
5388 {
5389   return structure_alloc_comps (der_type, decl, dest, rank, COPY_ALLOC_COMP);
5390 }
5391
5392
5393 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
5394    Do likewise, recursively if necessary, with the allocatable components of
5395    derived types.  */
5396
5397 tree
5398 gfc_trans_deferred_array (gfc_symbol * sym, tree body)
5399 {
5400   tree type;
5401   tree tmp;
5402   tree descriptor;
5403   stmtblock_t fnblock;
5404   locus loc;
5405   int rank;
5406   bool sym_has_alloc_comp;
5407
5408   sym_has_alloc_comp = (sym->ts.type == BT_DERIVED)
5409                           && sym->ts.derived->attr.alloc_comp;
5410
5411   /* Make sure the frontend gets these right.  */
5412   if (!(sym->attr.pointer || sym->attr.allocatable || sym_has_alloc_comp))
5413     fatal_error ("Possible frontend bug: Deferred array size without pointer, "
5414                  "allocatable attribute or derived type without allocatable "
5415                  "components.");
5416
5417   gfc_init_block (&fnblock);
5418
5419   gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
5420                 || TREE_CODE (sym->backend_decl) == PARM_DECL);
5421
5422   if (sym->ts.type == BT_CHARACTER
5423       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
5424     {
5425       gfc_conv_string_length (sym->ts.cl, &fnblock);
5426       gfc_trans_vla_type_sizes (sym, &fnblock);
5427     }
5428
5429   /* Dummy and use associated variables don't need anything special.  */
5430   if (sym->attr.dummy || sym->attr.use_assoc)
5431     {
5432       gfc_add_expr_to_block (&fnblock, body);
5433
5434       return gfc_finish_block (&fnblock);
5435     }
5436
5437   gfc_get_backend_locus (&loc);
5438   gfc_set_backend_locus (&sym->declared_at);
5439   descriptor = sym->backend_decl;
5440
5441   /* Although static, derived types with default initializers and
5442      allocatable components must not be nulled wholesale; instead they
5443      are treated component by component.  */
5444   if (TREE_STATIC (descriptor) && !sym_has_alloc_comp)
5445     {
5446       /* SAVEd variables are not freed on exit.  */
5447       gfc_trans_static_array_pointer (sym);
5448       return body;
5449     }
5450
5451   /* Get the descriptor type.  */
5452   type = TREE_TYPE (sym->backend_decl);
5453     
5454   if (sym_has_alloc_comp && !(sym->attr.pointer || sym->attr.allocatable))
5455     {
5456       if (!sym->attr.save)
5457         {
5458           rank = sym->as ? sym->as->rank : 0;
5459           tmp = gfc_nullify_alloc_comp (sym->ts.derived, descriptor, rank);
5460           gfc_add_expr_to_block (&fnblock, tmp);
5461         }
5462     }
5463   else if (!GFC_DESCRIPTOR_TYPE_P (type))
5464     {
5465       /* If the backend_decl is not a descriptor, we must have a pointer
5466          to one.  */
5467       descriptor = build_fold_indirect_ref (sym->backend_decl);
5468       type = TREE_TYPE (descriptor);
5469     }
5470   
5471   /* NULLIFY the data pointer.  */
5472   if (GFC_DESCRIPTOR_TYPE_P (type))
5473     gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node);
5474
5475   gfc_add_expr_to_block (&fnblock, body);
5476
5477   gfc_set_backend_locus (&loc);
5478
5479   /* Allocatable arrays need to be freed when they go out of scope.
5480      The allocatable components of pointers must not be touched.  */
5481   if (sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
5482       && !sym->attr.pointer && !sym->attr.save)
5483     {
5484       int rank;
5485       rank = sym->as ? sym->as->rank : 0;
5486       tmp = gfc_deallocate_alloc_comp (sym->ts.derived, descriptor, rank);
5487       gfc_add_expr_to_block (&fnblock, tmp);
5488     }
5489
5490   if (sym->attr.allocatable)
5491     {
5492       tmp = gfc_trans_dealloc_allocated (sym->backend_decl);
5493       gfc_add_expr_to_block (&fnblock, tmp);
5494     }
5495
5496   return gfc_finish_block (&fnblock);
5497 }
5498
5499 /************ Expression Walking Functions ******************/
5500
5501 /* Walk a variable reference.
5502
5503    Possible extension - multiple component subscripts.
5504     x(:,:) = foo%a(:)%b(:)
5505    Transforms to
5506     forall (i=..., j=...)
5507       x(i,j) = foo%a(j)%b(i)
5508     end forall
5509    This adds a fair amount of complexity because you need to deal with more
5510    than one ref.  Maybe handle in a similar manner to vector subscripts.
5511    Maybe not worth the effort.  */
5512
5513
5514 static gfc_ss *
5515 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
5516 {
5517   gfc_ref *ref;
5518   gfc_array_ref *ar;
5519   gfc_ss *newss;
5520   gfc_ss *head;
5521   int n;
5522
5523   for (ref = expr->ref; ref; ref = ref->next)
5524     if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
5525       break;
5526
5527   for (; ref; ref = ref->next)
5528     {
5529       if (ref->type == REF_SUBSTRING)
5530         {
5531           newss = gfc_get_ss ();
5532           newss->type = GFC_SS_SCALAR;
5533           newss->expr = ref->u.ss.start;
5534           newss->next = ss;
5535           ss = newss;
5536
5537           newss = gfc_get_ss ();
5538           newss->type = GFC_SS_SCALAR;
5539           newss->expr = ref->u.ss.end;
5540           newss->next = ss;
5541           ss = newss;
5542         }
5543
5544       /* We're only interested in array sections from now on.  */
5545       if (ref->type != REF_ARRAY)
5546         continue;
5547
5548       ar = &ref->u.ar;
5549       switch (ar->type)
5550         {
5551         case AR_ELEMENT:
5552           for (n = 0; n < ar->dimen; n++)
5553             {
5554               newss = gfc_get_ss ();
5555               newss->type = GFC_SS_SCALAR;
5556               newss->expr = ar->start[n];
5557               newss->next = ss;
5558               ss = newss;
5559             }
5560           break;
5561
5562         case AR_FULL:
5563           newss = gfc_get_ss ();
5564           newss->type = GFC_SS_SECTION;
5565           newss->expr = expr;
5566           newss->next = ss;
5567           newss->data.info.dimen = ar->as->rank;
5568           newss->data.info.ref = ref;
5569
5570           /* Make sure array is the same as array(:,:), this way
5571              we don't need to special case all the time.  */
5572           ar->dimen = ar->as->rank;
5573           for (n = 0; n < ar->dimen; n++)
5574             {
5575               newss->data.info.dim[n] = n;
5576               ar->dimen_type[n] = DIMEN_RANGE;
5577
5578               gcc_assert (ar->start[n] == NULL);
5579               gcc_assert (ar->end[n] == NULL);
5580               gcc_assert (ar->stride[n] == NULL);
5581             }
5582           ss = newss;
5583           break;
5584
5585         case AR_SECTION:
5586           newss = gfc_get_ss ();
5587           newss->type = GFC_SS_SECTION;
5588           newss->expr = expr;
5589           newss->next = ss;
5590           newss->data.info.dimen = 0;
5591           newss->data.info.ref = ref;
5592
5593           head = newss;
5594
5595           /* We add SS chains for all the subscripts in the section.  */
5596           for (n = 0; n < ar->dimen; n++)
5597             {
5598               gfc_ss *indexss;
5599
5600               switch (ar->dimen_type[n])
5601                 {
5602                 case DIMEN_ELEMENT:
5603                   /* Add SS for elemental (scalar) subscripts.  */
5604                   gcc_assert (ar->start[n]);
5605                   indexss = gfc_get_ss ();
5606                   indexss->type = GFC_SS_SCALAR;
5607                   indexss->expr = ar->start[n];
5608                   indexss->next = gfc_ss_terminator;
5609                   indexss->loop_chain = gfc_ss_terminator;
5610                   newss->data.info.subscript[n] = indexss;
5611                   break;
5612
5613                 case DIMEN_RANGE:
5614                   /* We don't add anything for sections, just remember this
5615                      dimension for later.  */
5616                   newss->data.info.dim[newss->data.info.dimen] = n;
5617                   newss->data.info.dimen++;
5618                   break;
5619
5620                 case DIMEN_VECTOR:
5621                   /* Create a GFC_SS_VECTOR index in which we can store
5622                      the vector's descriptor.  */
5623                   indexss = gfc_get_ss ();
5624                   indexss->type = GFC_SS_VECTOR;
5625                   indexss->expr = ar->start[n];
5626                   indexss->next = gfc_ss_terminator;
5627                   indexss->loop_chain = gfc_ss_terminator;
5628                   newss->data.info.subscript[n] = indexss;
5629                   newss->data.info.dim[newss->data.info.dimen] = n;
5630                   newss->data.info.dimen++;
5631                   break;
5632
5633                 default:
5634                   /* We should know what sort of section it is by now.  */
5635                   gcc_unreachable ();
5636                 }
5637             }
5638           /* We should have at least one non-elemental dimension.  */
5639           gcc_assert (newss->data.info.dimen > 0);
5640           ss = newss;
5641           break;
5642
5643         default:
5644           /* We should know what sort of section it is by now.  */
5645           gcc_unreachable ();
5646         }
5647
5648     }
5649   return ss;
5650 }
5651
5652
5653 /* Walk an expression operator. If only one operand of a binary expression is
5654    scalar, we must also add the scalar term to the SS chain.  */
5655
5656 static gfc_ss *
5657 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
5658 {
5659   gfc_ss *head;
5660   gfc_ss *head2;
5661   gfc_ss *newss;
5662
5663   head = gfc_walk_subexpr (ss, expr->value.op.op1);
5664   if (expr->value.op.op2 == NULL)
5665     head2 = head;
5666   else
5667     head2 = gfc_walk_subexpr (head, expr->value.op.op2);
5668
5669   /* All operands are scalar.  Pass back and let the caller deal with it.  */
5670   if (head2 == ss)
5671     return head2;
5672
5673   /* All operands require scalarization.  */
5674   if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
5675     return head2;
5676
5677   /* One of the operands needs scalarization, the other is scalar.
5678      Create a gfc_ss for the scalar expression.  */
5679   newss = gfc_get_ss ();
5680   newss->type = GFC_SS_SCALAR;
5681   if (head == ss)
5682     {
5683       /* First operand is scalar.  We build the chain in reverse order, so
5684          add the scarar SS after the second operand.  */
5685       head = head2;
5686       while (head && head->next != ss)
5687         head = head->next;
5688       /* Check we haven't somehow broken the chain.  */
5689       gcc_assert (head);
5690       newss->next = ss;
5691       head->next = newss;
5692       newss->expr = expr->value.op.op1;
5693     }
5694   else                          /* head2 == head */
5695     {
5696       gcc_assert (head2 == head);
5697       /* Second operand is scalar.  */
5698       newss->next = head2;
5699       head2 = newss;
5700       newss->expr = expr->value.op.op2;
5701     }
5702
5703   return head2;
5704 }
5705
5706
5707 /* Reverse a SS chain.  */
5708
5709 gfc_ss *
5710 gfc_reverse_ss (gfc_ss * ss)
5711 {
5712   gfc_ss *next;
5713   gfc_ss *head;
5714
5715   gcc_assert (ss != NULL);
5716
5717   head = gfc_ss_terminator;
5718   while (ss != gfc_ss_terminator)
5719     {
5720       next = ss->next;
5721       /* Check we didn't somehow break the chain.  */
5722       gcc_assert (next != NULL);
5723       ss->next = head;
5724       head = ss;
5725       ss = next;
5726     }
5727
5728   return (head);
5729 }
5730
5731
5732 /* Walk the arguments of an elemental function.  */
5733
5734 gfc_ss *
5735 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
5736                                   gfc_ss_type type)
5737 {
5738   int scalar;
5739   gfc_ss *head;
5740   gfc_ss *tail;
5741   gfc_ss *newss;
5742
5743   head = gfc_ss_terminator;
5744   tail = NULL;
5745   scalar = 1;
5746   for (; arg; arg = arg->next)
5747     {
5748       if (!arg->expr)
5749         continue;
5750
5751       newss = gfc_walk_subexpr (head, arg->expr);
5752       if (newss == head)
5753         {
5754           /* Scalar argument.  */
5755           newss = gfc_get_ss ();
5756           newss->type = type;
5757           newss->expr = arg->expr;
5758           newss->next = head;
5759         }
5760       else
5761         scalar = 0;
5762
5763       head = newss;
5764       if (!tail)
5765         {
5766           tail = head;
5767           while (tail->next != gfc_ss_terminator)
5768             tail = tail->next;
5769         }
5770     }
5771
5772   if (scalar)
5773     {
5774       /* If all the arguments are scalar we don't need the argument SS.  */
5775       gfc_free_ss_chain (head);
5776       /* Pass it back.  */
5777       return ss;
5778     }
5779
5780   /* Add it onto the existing chain.  */
5781   tail->next = ss;
5782   return head;
5783 }
5784
5785
5786 /* Walk a function call.  Scalar functions are passed back, and taken out of
5787    scalarization loops.  For elemental functions we walk their arguments.
5788    The result of functions returning arrays is stored in a temporary outside
5789    the loop, so that the function is only called once.  Hence we do not need
5790    to walk their arguments.  */
5791
5792 static gfc_ss *
5793 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
5794 {
5795   gfc_ss *newss;
5796   gfc_intrinsic_sym *isym;
5797   gfc_symbol *sym;
5798
5799   isym = expr->value.function.isym;
5800
5801   /* Handle intrinsic functions separately.  */
5802   if (isym)
5803     return gfc_walk_intrinsic_function (ss, expr, isym);
5804
5805   sym = expr->value.function.esym;
5806   if (!sym)
5807       sym = expr->symtree->n.sym;
5808
5809   /* A function that returns arrays.  */
5810   if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
5811     {
5812       newss = gfc_get_ss ();
5813       newss->type = GFC_SS_FUNCTION;
5814       newss->expr = expr;
5815       newss->next = ss;
5816       newss->data.info.dimen = expr->rank;
5817       return newss;
5818     }
5819
5820   /* Walk the parameters of an elemental function.  For now we always pass
5821      by reference.  */
5822   if (sym->attr.elemental)
5823     return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
5824                                              GFC_SS_REFERENCE);
5825
5826   /* Scalar functions are OK as these are evaluated outside the scalarization
5827      loop.  Pass back and let the caller deal with it.  */
5828   return ss;
5829 }
5830
5831
5832 /* An array temporary is constructed for array constructors.  */
5833
5834 static gfc_ss *
5835 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
5836 {
5837   gfc_ss *newss;
5838   int n;
5839
5840   newss = gfc_get_ss ();
5841   newss->type = GFC_SS_CONSTRUCTOR;
5842   newss->expr = expr;
5843   newss->next = ss;
5844   newss->data.info.dimen = expr->rank;
5845   for (n = 0; n < expr->rank; n++)
5846     newss->data.info.dim[n] = n;
5847
5848   return newss;
5849 }
5850
5851
5852 /* Walk an expression.  Add walked expressions to the head of the SS chain.
5853    A wholly scalar expression will not be added.  */
5854
5855 static gfc_ss *
5856 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
5857 {
5858   gfc_ss *head;
5859
5860   switch (expr->expr_type)
5861     {
5862     case EXPR_VARIABLE:
5863       head = gfc_walk_variable_expr (ss, expr);
5864       return head;
5865
5866     case EXPR_OP:
5867       head = gfc_walk_op_expr (ss, expr);
5868       return head;
5869
5870     case EXPR_FUNCTION:
5871       head = gfc_walk_function_expr (ss, expr);
5872       return head;
5873
5874     case EXPR_CONSTANT:
5875     case EXPR_NULL:
5876     case EXPR_STRUCTURE:
5877       /* Pass back and let the caller deal with it.  */
5878       break;
5879
5880     case EXPR_ARRAY:
5881       head = gfc_walk_array_constructor (ss, expr);
5882       return head;
5883
5884     case EXPR_SUBSTRING:
5885       /* Pass back and let the caller deal with it.  */
5886       break;
5887
5888     default:
5889       internal_error ("bad expression type during walk (%d)",
5890                       expr->expr_type);
5891     }
5892   return ss;
5893 }
5894
5895
5896 /* Entry point for expression walking.
5897    A return value equal to the passed chain means this is
5898    a scalar expression.  It is up to the caller to take whatever action is
5899    necessary to translate these.  */
5900
5901 gfc_ss *
5902 gfc_walk_expr (gfc_expr * expr)
5903 {
5904   gfc_ss *res;
5905
5906   res = gfc_walk_subexpr (gfc_ss_terminator, expr);
5907   return gfc_reverse_ss (res);
5908 }