OSDN Git Service

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