OSDN Git Service

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