OSDN Git Service

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