OSDN Git Service

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