OSDN Git Service

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