OSDN Git Service

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