OSDN Git Service

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