OSDN Git Service

Make CONSTRUCTOR use VEC to store initializers.
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-array.c
1 /* Array translation routines
2    Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3    Contributed by Paul Brook <paul@nowt.org>
4    and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.  */
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
98 /* The contents of this structure aren't actually used, just the address.  */
99 static gfc_ss gfc_ss_terminator_var;
100 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
101
102
103 static tree
104 gfc_array_dataptr_type (tree desc)
105 {
106   return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
107 }
108
109
110 /* Build expressions to access the members of an array descriptor.
111    It's surprisingly easy to mess up here, so never access
112    an array descriptor by "brute force", always use these
113    functions.  This also avoids problems if we change the format
114    of an array descriptor.
115
116    To understand these magic numbers, look at the comments
117    before gfc_build_array_type() in trans-types.c.
118
119    The code within these defines should be the only code which knows the format
120    of an array descriptor.
121
122    Any code just needing to read obtain the bounds of an array should use
123    gfc_conv_array_* rather than the following functions as these will return
124    know constant values, and work with arrays which do not have descriptors.
125
126    Don't forget to #undef these!  */
127
128 #define DATA_FIELD 0
129 #define OFFSET_FIELD 1
130 #define DTYPE_FIELD 2
131 #define DIMENSION_FIELD 3
132
133 #define STRIDE_SUBFIELD 0
134 #define LBOUND_SUBFIELD 1
135 #define UBOUND_SUBFIELD 2
136
137 /* This provides READ-ONLY access to the data field.  The field itself
138    doesn't have the proper type.  */
139
140 tree
141 gfc_conv_descriptor_data_get (tree desc)
142 {
143   tree field, type, t;
144
145   type = TREE_TYPE (desc);
146   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
147
148   field = TYPE_FIELDS (type);
149   gcc_assert (DATA_FIELD == 0);
150
151   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
152   t = fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), t);
153
154   return t;
155 }
156
157 /* This provides WRITE access to the data field.  */
158
159 void
160 gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
161 {
162   tree field, type, t;
163
164   type = TREE_TYPE (desc);
165   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
166
167   field = TYPE_FIELDS (type);
168   gcc_assert (DATA_FIELD == 0);
169
170   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
171   gfc_add_modify_expr (block, t, fold_convert (TREE_TYPE (field), value));
172 }
173
174
175 /* This provides address access to the data field.  This should only be
176    used by array allocation, passing this on to the runtime.  */
177
178 tree
179 gfc_conv_descriptor_data_addr (tree desc)
180 {
181   tree field, type, t;
182
183   type = TREE_TYPE (desc);
184   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
185
186   field = TYPE_FIELDS (type);
187   gcc_assert (DATA_FIELD == 0);
188
189   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
190   return gfc_build_addr_expr (NULL, t);
191 }
192
193 tree
194 gfc_conv_descriptor_offset (tree desc)
195 {
196   tree type;
197   tree field;
198
199   type = TREE_TYPE (desc);
200   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
201
202   field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
203   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
204
205   return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
206 }
207
208 tree
209 gfc_conv_descriptor_dtype (tree desc)
210 {
211   tree field;
212   tree type;
213
214   type = TREE_TYPE (desc);
215   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
216
217   field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
218   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
219
220   return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
221 }
222
223 static tree
224 gfc_conv_descriptor_dimension (tree desc, tree dim)
225 {
226   tree field;
227   tree type;
228   tree tmp;
229
230   type = TREE_TYPE (desc);
231   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
232
233   field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
234   gcc_assert (field != NULL_TREE
235           && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
236           && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
237
238   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
239   tmp = gfc_build_array_ref (tmp, dim);
240   return tmp;
241 }
242
243 tree
244 gfc_conv_descriptor_stride (tree desc, tree dim)
245 {
246   tree tmp;
247   tree field;
248
249   tmp = gfc_conv_descriptor_dimension (desc, dim);
250   field = TYPE_FIELDS (TREE_TYPE (tmp));
251   field = gfc_advance_chain (field, STRIDE_SUBFIELD);
252   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
253
254   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
255   return tmp;
256 }
257
258 tree
259 gfc_conv_descriptor_lbound (tree desc, tree dim)
260 {
261   tree tmp;
262   tree field;
263
264   tmp = gfc_conv_descriptor_dimension (desc, dim);
265   field = TYPE_FIELDS (TREE_TYPE (tmp));
266   field = gfc_advance_chain (field, LBOUND_SUBFIELD);
267   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
268
269   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
270   return tmp;
271 }
272
273 tree
274 gfc_conv_descriptor_ubound (tree desc, tree dim)
275 {
276   tree tmp;
277   tree field;
278
279   tmp = gfc_conv_descriptor_dimension (desc, dim);
280   field = TYPE_FIELDS (TREE_TYPE (tmp));
281   field = gfc_advance_chain (field, UBOUND_SUBFIELD);
282   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
283
284   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
285   return tmp;
286 }
287
288
289 /* Build an null array descriptor constructor.  */
290
291 tree
292 gfc_build_null_descriptor (tree type)
293 {
294   tree field;
295   tree tmp;
296
297   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
298   gcc_assert (DATA_FIELD == 0);
299   field = TYPE_FIELDS (type);
300
301   /* Set a NULL data pointer.  */
302   tmp = build_constructor_single (type, field, null_pointer_node);
303   TREE_CONSTANT (tmp) = 1;
304   TREE_INVARIANT (tmp) = 1;
305   /* All other fields are ignored.  */
306
307   return tmp;
308 }
309
310
311 /* Cleanup those #defines.  */
312
313 #undef DATA_FIELD
314 #undef OFFSET_FIELD
315 #undef DTYPE_FIELD
316 #undef DIMENSION_FIELD
317 #undef STRIDE_SUBFIELD
318 #undef LBOUND_SUBFIELD
319 #undef UBOUND_SUBFIELD
320
321
322 /* Mark a SS chain as used.  Flags specifies in which loops the SS is used.
323    flags & 1 = Main loop body.
324    flags & 2 = temp copy loop.  */
325
326 void
327 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
328 {
329   for (; ss != gfc_ss_terminator; ss = ss->next)
330     ss->useflags = flags;
331 }
332
333 static void gfc_free_ss (gfc_ss *);
334
335
336 /* Free a gfc_ss chain.  */
337
338 static void
339 gfc_free_ss_chain (gfc_ss * ss)
340 {
341   gfc_ss *next;
342
343   while (ss != gfc_ss_terminator)
344     {
345       gcc_assert (ss != NULL);
346       next = ss->next;
347       gfc_free_ss (ss);
348       ss = next;
349     }
350 }
351
352
353 /* Free a SS.  */
354
355 static void
356 gfc_free_ss (gfc_ss * ss)
357 {
358   int n;
359
360   switch (ss->type)
361     {
362     case GFC_SS_SECTION:
363     case GFC_SS_VECTOR:
364       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
365         {
366           if (ss->data.info.subscript[n])
367             gfc_free_ss_chain (ss->data.info.subscript[n]);
368         }
369       break;
370
371     default:
372       break;
373     }
374
375   gfc_free (ss);
376 }
377
378
379 /* Free all the SS associated with a loop.  */
380
381 void
382 gfc_cleanup_loop (gfc_loopinfo * loop)
383 {
384   gfc_ss *ss;
385   gfc_ss *next;
386
387   ss = loop->ss;
388   while (ss != gfc_ss_terminator)
389     {
390       gcc_assert (ss != NULL);
391       next = ss->loop_chain;
392       gfc_free_ss (ss);
393       ss = next;
394     }
395 }
396
397
398 /* Associate a SS chain with a loop.  */
399
400 void
401 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
402 {
403   gfc_ss *ss;
404
405   if (head == gfc_ss_terminator)
406     return;
407
408   ss = head;
409   for (; ss && ss != gfc_ss_terminator; ss = ss->next)
410     {
411       if (ss->next == gfc_ss_terminator)
412         ss->loop_chain = loop->ss;
413       else
414         ss->loop_chain = ss->next;
415     }
416   gcc_assert (ss == gfc_ss_terminator);
417   loop->ss = head;
418 }
419
420
421 /* Generate an initializer for a static pointer or allocatable array.  */
422
423 void
424 gfc_trans_static_array_pointer (gfc_symbol * sym)
425 {
426   tree type;
427
428   gcc_assert (TREE_STATIC (sym->backend_decl));
429   /* Just zero the data member.  */
430   type = TREE_TYPE (sym->backend_decl);
431   DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
432 }
433
434
435 /* Generate code to allocate an array temporary, or create a variable to
436    hold the data.  If size is NULL zero the descriptor so that so that the
437    callee will allocate the array.  Also generates code to free the array
438    afterwards.  */
439
440 static void
441 gfc_trans_allocate_array_storage (gfc_loopinfo * loop, gfc_ss_info * info,
442                                   tree size, tree nelem)
443 {
444   tree tmp;
445   tree args;
446   tree desc;
447   bool onstack;
448
449   desc = info->descriptor;
450   info->offset = gfc_index_zero_node;
451   if (size == NULL_TREE)
452     {
453       /* A callee allocated array.  */
454       gfc_conv_descriptor_data_set (&loop->pre, desc, null_pointer_node);
455       onstack = FALSE;
456     }
457   else
458     {
459       /* Allocate the temporary.  */
460       onstack = gfc_can_put_var_on_stack (size);
461
462       if (onstack)
463         {
464           /* Make a temporary variable to hold the data.  */
465           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (nelem), nelem,
466                              integer_one_node);
467           tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
468                                   tmp);
469           tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
470                                   tmp);
471           tmp = gfc_create_var (tmp, "A");
472           tmp = gfc_build_addr_expr (NULL, tmp);
473           gfc_conv_descriptor_data_set (&loop->pre, desc, tmp);
474         }
475       else
476         {
477           /* Allocate memory to hold the data.  */
478           args = gfc_chainon_list (NULL_TREE, size);
479
480           if (gfc_index_integer_kind == 4)
481             tmp = gfor_fndecl_internal_malloc;
482           else if (gfc_index_integer_kind == 8)
483             tmp = gfor_fndecl_internal_malloc64;
484           else
485             gcc_unreachable ();
486           tmp = gfc_build_function_call (tmp, args);
487           tmp = gfc_evaluate_now (tmp, &loop->pre);
488           gfc_conv_descriptor_data_set (&loop->pre, desc, tmp);
489         }
490     }
491   info->data = gfc_conv_descriptor_data_get (desc);
492
493   /* The offset is zero because we create temporaries with a zero
494      lower bound.  */
495   tmp = gfc_conv_descriptor_offset (desc);
496   gfc_add_modify_expr (&loop->pre, tmp, gfc_index_zero_node);
497
498   if (!onstack)
499     {
500       /* Free the temporary.  */
501       tmp = gfc_conv_descriptor_data_get (desc);
502       tmp = fold_convert (pvoid_type_node, tmp);
503       tmp = gfc_chainon_list (NULL_TREE, tmp);
504       tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
505       gfc_add_expr_to_block (&loop->post, tmp);
506     }
507 }
508
509
510 /* Generate code to allocate and initialize the descriptor for a temporary
511    array.  This is used for both temporaries needed by the scalarizer, and
512    functions returning arrays.  Adjusts the loop variables to be zero-based,
513    and calculates the loop bounds for callee allocated arrays.
514    Also fills in the descriptor, data and offset fields of info if known.
515    Returns the size of the array, or NULL for a callee allocated array.  */
516
517 tree
518 gfc_trans_allocate_temp_array (gfc_loopinfo * loop, gfc_ss_info * info,
519                                tree eltype)
520 {
521   tree type;
522   tree desc;
523   tree tmp;
524   tree size;
525   tree nelem;
526   int n;
527   int dim;
528
529   gcc_assert (info->dimen > 0);
530   /* Set the lower bound to zero.  */
531   for (dim = 0; dim < info->dimen; dim++)
532     {
533       n = loop->order[dim];
534       if (n < loop->temp_dim)
535         gcc_assert (integer_zerop (loop->from[n]));
536       else
537         {
538           /* Callee allocated arrays may not have a known bound yet.  */
539           if (loop->to[n])
540               loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
541                                          loop->to[n], loop->from[n]);
542           loop->from[n] = gfc_index_zero_node;
543         }
544
545       info->delta[dim] = gfc_index_zero_node;
546       info->start[dim] = gfc_index_zero_node;
547       info->stride[dim] = gfc_index_one_node;
548       info->dim[dim] = dim;
549     }
550
551   /* Initialize the descriptor.  */
552   type =
553     gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1);
554   desc = gfc_create_var (type, "atmp");
555   GFC_DECL_PACKED_ARRAY (desc) = 1;
556
557   info->descriptor = desc;
558   size = gfc_index_one_node;
559
560   /* Fill in the array dtype.  */
561   tmp = gfc_conv_descriptor_dtype (desc);
562   gfc_add_modify_expr (&loop->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
563
564   /*
565      Fill in the bounds and stride.  This is a packed array, so:
566
567      size = 1;
568      for (n = 0; n < rank; n++)
569        {
570          stride[n] = size
571          delta = ubound[n] + 1 - lbound[n];
572          size = size * delta;
573        }
574      size = size * sizeof(element);
575   */
576
577   for (n = 0; n < info->dimen; n++)
578     {
579       if (loop->to[n] == NULL_TREE)
580         {
581           /* For a callee allocated array express the loop bounds in terms
582              of the descriptor fields.  */
583           tmp = build2 (MINUS_EXPR, gfc_array_index_type,
584                         gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]),
585                         gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]));
586           loop->to[n] = tmp;
587           size = NULL_TREE;
588           continue;
589         }
590         
591       /* Store the stride and bound components in the descriptor.  */
592       tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
593       gfc_add_modify_expr (&loop->pre, tmp, size);
594
595       tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
596       gfc_add_modify_expr (&loop->pre, tmp, gfc_index_zero_node);
597
598       tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
599       gfc_add_modify_expr (&loop->pre, tmp, loop->to[n]);
600
601       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
602                          loop->to[n], gfc_index_one_node);
603
604       size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
605       size = gfc_evaluate_now (size, &loop->pre);
606     }
607
608   /* Get the size of the array.  */
609   nelem = size;
610   if (size)
611     size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
612                         TYPE_SIZE_UNIT (gfc_get_element_type (type)));
613
614   gfc_trans_allocate_array_storage (loop, info, size, nelem);
615
616   if (info->dimen > loop->temp_dim)
617     loop->temp_dim = info->dimen;
618
619   return size;
620 }
621
622
623 /* Make sure offset is a variable.  */
624
625 static void
626 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
627                          tree * offsetvar)
628 {
629   /* We should have already created the offset variable.  We cannot
630      create it here because we may be in an inner scope.  */
631   gcc_assert (*offsetvar != NULL_TREE);
632   gfc_add_modify_expr (pblock, *offsetvar, *poffset);
633   *poffset = *offsetvar;
634   TREE_USED (*offsetvar) = 1;
635 }
636
637
638 /* Assign an element of an array constructor.  */
639
640 static void
641 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree pointer,
642                               tree offset, gfc_se * se, gfc_expr * expr)
643 {
644   tree tmp;
645   tree args;
646
647   gfc_conv_expr (se, expr);
648
649   /* Store the value.  */
650   tmp = gfc_build_indirect_ref (pointer);
651   tmp = gfc_build_array_ref (tmp, offset);
652   if (expr->ts.type == BT_CHARACTER)
653     {
654       gfc_conv_string_parameter (se);
655       if (POINTER_TYPE_P (TREE_TYPE (tmp)))
656         {
657           /* The temporary is an array of pointers.  */
658           se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
659           gfc_add_modify_expr (&se->pre, tmp, se->expr);
660         }
661       else
662         {
663           /* The temporary is an array of string values.  */
664           tmp = gfc_build_addr_expr (pchar_type_node, tmp);
665           /* We know the temporary and the value will be the same length,
666              so can use memcpy.  */
667           args = gfc_chainon_list (NULL_TREE, tmp);
668           args = gfc_chainon_list (args, se->expr);
669           args = gfc_chainon_list (args, se->string_length);
670           tmp = built_in_decls[BUILT_IN_MEMCPY];
671           tmp = gfc_build_function_call (tmp, args);
672           gfc_add_expr_to_block (&se->pre, tmp);
673         }
674     }
675   else
676     {
677       /* TODO: Should the frontend already have done this conversion?  */
678       se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
679       gfc_add_modify_expr (&se->pre, tmp, se->expr);
680     }
681
682   gfc_add_block_to_block (pblock, &se->pre);
683   gfc_add_block_to_block (pblock, &se->post);
684 }
685
686
687 /* Add the contents of an array to the constructor.  */
688
689 static void
690 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
691                                       tree type ATTRIBUTE_UNUSED,
692                                       tree pointer, gfc_expr * expr,
693                                       tree * poffset, tree * offsetvar)
694 {
695   gfc_se se;
696   gfc_ss *ss;
697   gfc_loopinfo loop;
698   stmtblock_t body;
699   tree tmp;
700
701   /* We need this to be a variable so we can increment it.  */
702   gfc_put_offset_into_var (pblock, poffset, offsetvar);
703
704   gfc_init_se (&se, NULL);
705
706   /* Walk the array expression.  */
707   ss = gfc_walk_expr (expr);
708   gcc_assert (ss != gfc_ss_terminator);
709
710   /* Initialize the scalarizer.  */
711   gfc_init_loopinfo (&loop);
712   gfc_add_ss_to_loop (&loop, ss);
713
714   /* Initialize the loop.  */
715   gfc_conv_ss_startstride (&loop);
716   gfc_conv_loop_setup (&loop);
717
718   /* Make the loop body.  */
719   gfc_mark_ss_chain_used (ss, 1);
720   gfc_start_scalarized_body (&loop, &body);
721   gfc_copy_loopinfo_to_se (&se, &loop);
722   se.ss = ss;
723
724   if (expr->ts.type == BT_CHARACTER)
725     gfc_todo_error ("character arrays in constructors");
726
727   gfc_trans_array_ctor_element (&body, pointer, *poffset, &se, expr);
728   gcc_assert (se.ss == gfc_ss_terminator);
729
730   /* Increment the offset.  */
731   tmp = build2 (PLUS_EXPR, gfc_array_index_type, *poffset, gfc_index_one_node);
732   gfc_add_modify_expr (&body, *poffset, tmp);
733
734   /* Finish the loop.  */
735   gfc_trans_scalarizing_loops (&loop, &body);
736   gfc_add_block_to_block (&loop.pre, &loop.post);
737   tmp = gfc_finish_block (&loop.pre);
738   gfc_add_expr_to_block (pblock, tmp);
739
740   gfc_cleanup_loop (&loop);
741 }
742
743
744 /* Assign the values to the elements of an array constructor.  */
745
746 static void
747 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
748                                    tree pointer, gfc_constructor * c,
749                                    tree * poffset, tree * offsetvar)
750 {
751   tree tmp;
752   stmtblock_t body;
753   gfc_se se;
754
755   for (; c; c = c->next)
756     {
757       /* If this is an iterator or an array, the offset must be a variable.  */
758       if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
759         gfc_put_offset_into_var (pblock, poffset, offsetvar);
760
761       gfc_start_block (&body);
762
763       if (c->expr->expr_type == EXPR_ARRAY)
764         {
765           /* Array constructors can be nested.  */
766           gfc_trans_array_constructor_value (&body, type, pointer,
767                                              c->expr->value.constructor,
768                                              poffset, offsetvar);
769         }
770       else if (c->expr->rank > 0)
771         {
772           gfc_trans_array_constructor_subarray (&body, type, pointer,
773                                                 c->expr, poffset, offsetvar);
774         }
775       else
776         {
777           /* This code really upsets the gimplifier so don't bother for now.  */
778           gfc_constructor *p;
779           HOST_WIDE_INT n;
780           HOST_WIDE_INT size;
781
782           p = c;
783           n = 0;
784           while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
785             {
786               p = p->next;
787               n++;
788             }
789           if (n < 4)
790             {
791               /* Scalar values.  */
792               gfc_init_se (&se, NULL);
793               gfc_trans_array_ctor_element (&body, pointer, *poffset, &se,
794                                             c->expr);
795
796               *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
797                                       *poffset, gfc_index_one_node);
798             }
799           else
800             {
801               /* Collect multiple scalar constants into a constructor.  */
802               tree list;
803               tree init;
804               tree bound;
805               tree tmptype;
806
807               p = c;
808               list = NULL_TREE;
809               /* Count the number of consecutive scalar constants.  */
810               while (p && !(p->iterator
811                             || p->expr->expr_type != EXPR_CONSTANT))
812                 {
813                   gfc_init_se (&se, NULL);
814                   gfc_conv_constant (&se, p->expr);
815                   if (p->expr->ts.type == BT_CHARACTER
816                       && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE
817                           (TREE_TYPE (pointer)))))
818                     {
819                       /* For constant character array constructors we build
820                          an array of pointers.  */
821                       se.expr = gfc_build_addr_expr (pchar_type_node,
822                                                       se.expr);
823                     }
824                     
825                   list = tree_cons (NULL_TREE, se.expr, list);
826                   c = p;
827                   p = p->next;
828                 }
829
830               bound = build_int_cst (NULL_TREE, n - 1);
831               /* Create an array type to hold them.  */
832               tmptype = build_range_type (gfc_array_index_type,
833                                           gfc_index_zero_node, bound);
834               tmptype = build_array_type (type, tmptype);
835
836               init = build_constructor_from_list (tmptype, nreverse (list));
837               TREE_CONSTANT (init) = 1;
838               TREE_INVARIANT (init) = 1;
839               TREE_STATIC (init) = 1;
840               /* Create a static variable to hold the data.  */
841               tmp = gfc_create_var (tmptype, "data");
842               TREE_STATIC (tmp) = 1;
843               TREE_CONSTANT (tmp) = 1;
844               TREE_INVARIANT (tmp) = 1;
845               DECL_INITIAL (tmp) = init;
846               init = tmp;
847
848               /* Use BUILTIN_MEMCPY to assign the values.  */
849               tmp = gfc_build_indirect_ref (pointer);
850               tmp = gfc_build_array_ref (tmp, *poffset);
851               tmp = gfc_build_addr_expr (NULL, tmp);
852               init = gfc_build_addr_expr (NULL, init);
853
854               size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
855               bound = build_int_cst (NULL_TREE, n * size);
856               tmp = gfc_chainon_list (NULL_TREE, tmp);
857               tmp = gfc_chainon_list (tmp, init);
858               tmp = gfc_chainon_list (tmp, bound);
859               tmp = gfc_build_function_call (built_in_decls[BUILT_IN_MEMCPY],
860                                              tmp);
861               gfc_add_expr_to_block (&body, tmp);
862
863               *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
864                                       *poffset, build_int_cst (NULL_TREE, n));
865             }
866           if (!INTEGER_CST_P (*poffset))
867             {
868               gfc_add_modify_expr (&body, *offsetvar, *poffset);
869               *poffset = *offsetvar;
870             }
871         }
872
873       /* The frontend should already have done any expansions possible
874          at compile-time.  */
875       if (!c->iterator)
876         {
877           /* Pass the code as is.  */
878           tmp = gfc_finish_block (&body);
879           gfc_add_expr_to_block (pblock, tmp);
880         }
881       else
882         {
883           /* Build the implied do-loop.  */
884           tree cond;
885           tree end;
886           tree step;
887           tree loopvar;
888           tree exit_label;
889           tree loopbody;
890
891           loopbody = gfc_finish_block (&body);
892
893           gfc_init_se (&se, NULL);
894           gfc_conv_expr (&se, c->iterator->var);
895           gfc_add_block_to_block (pblock, &se.pre);
896           loopvar = se.expr;
897
898           /* Initialize the loop.  */
899           gfc_init_se (&se, NULL);
900           gfc_conv_expr_val (&se, c->iterator->start);
901           gfc_add_block_to_block (pblock, &se.pre);
902           gfc_add_modify_expr (pblock, loopvar, se.expr);
903
904           gfc_init_se (&se, NULL);
905           gfc_conv_expr_val (&se, c->iterator->end);
906           gfc_add_block_to_block (pblock, &se.pre);
907           end = gfc_evaluate_now (se.expr, pblock);
908
909           gfc_init_se (&se, NULL);
910           gfc_conv_expr_val (&se, c->iterator->step);
911           gfc_add_block_to_block (pblock, &se.pre);
912           step = gfc_evaluate_now (se.expr, pblock);
913
914           /* Generate the loop body.  */
915           exit_label = gfc_build_label_decl (NULL_TREE);
916           gfc_start_block (&body);
917
918           /* Generate the exit condition.  Depending on the sign of
919              the step variable we have to generate the correct
920              comparison.  */
921           tmp = fold_build2 (GT_EXPR, boolean_type_node, step, 
922                              build_int_cst (TREE_TYPE (step), 0));
923           cond = fold_build3 (COND_EXPR, boolean_type_node, tmp,
924                               build2 (GT_EXPR, boolean_type_node,
925                                       loopvar, end),
926                               build2 (LT_EXPR, boolean_type_node,
927                                       loopvar, end));
928           tmp = build1_v (GOTO_EXPR, exit_label);
929           TREE_USED (exit_label) = 1;
930           tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
931           gfc_add_expr_to_block (&body, tmp);
932
933           /* The main loop body.  */
934           gfc_add_expr_to_block (&body, loopbody);
935
936           /* Increase loop variable by step.  */
937           tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
938           gfc_add_modify_expr (&body, loopvar, tmp);
939
940           /* Finish the loop.  */
941           tmp = gfc_finish_block (&body);
942           tmp = build1_v (LOOP_EXPR, tmp);
943           gfc_add_expr_to_block (pblock, tmp);
944
945           /* Add the exit label.  */
946           tmp = build1_v (LABEL_EXPR, exit_label);
947           gfc_add_expr_to_block (pblock, tmp);
948         }
949     }
950 }
951
952
953 /* Get the size of an expression.  Returns -1 if the size isn't constant.
954    Implied do loops with non-constant bounds are tricky because we must only
955    evaluate the bounds once.  */
956
957 static void
958 gfc_get_array_cons_size (mpz_t * size, gfc_constructor * c)
959 {
960   gfc_iterator *i;
961   mpz_t val;
962   mpz_t len;
963
964   mpz_set_ui (*size, 0);
965   mpz_init (len);
966   mpz_init (val);
967
968   for (; c; c = c->next)
969     {
970       if (c->expr->expr_type == EXPR_ARRAY)
971         {
972           /* A nested array constructor.  */
973           gfc_get_array_cons_size (&len, c->expr->value.constructor);
974           if (mpz_sgn (len) < 0)
975             {
976               mpz_set (*size, len);
977               mpz_clear (len);
978               mpz_clear (val);
979               return;
980             }
981         }
982       else
983         {
984           if (c->expr->rank > 0)
985             {
986               mpz_set_si (*size, -1);
987               mpz_clear (len);
988               mpz_clear (val);
989               return;
990             }
991           mpz_set_ui (len, 1);
992         }
993
994       if (c->iterator)
995         {
996           i = c->iterator;
997
998           if (i->start->expr_type != EXPR_CONSTANT
999               || i->end->expr_type != EXPR_CONSTANT
1000               || i->step->expr_type != EXPR_CONSTANT)
1001             {
1002               mpz_set_si (*size, -1);
1003               mpz_clear (len);
1004               mpz_clear (val);
1005               return;
1006             }
1007
1008           mpz_add (val, i->end->value.integer, i->start->value.integer);
1009           mpz_tdiv_q (val, val, i->step->value.integer);
1010           mpz_add_ui (val, val, 1);
1011           mpz_mul (len, len, val);
1012         }
1013       mpz_add (*size, *size, len);
1014     }
1015   mpz_clear (len);
1016   mpz_clear (val);
1017 }
1018
1019
1020 /* Figure out the string length of a variable reference expression.
1021    Used by get_array_ctor_strlen.  */
1022
1023 static void
1024 get_array_ctor_var_strlen (gfc_expr * expr, tree * len)
1025 {
1026   gfc_ref *ref;
1027   gfc_typespec *ts;
1028
1029   /* Don't bother if we already know the length is a constant.  */
1030   if (*len && INTEGER_CST_P (*len))
1031     return;
1032
1033   ts = &expr->symtree->n.sym->ts;
1034   for (ref = expr->ref; ref; ref = ref->next)
1035     {
1036       switch (ref->type)
1037         {
1038         case REF_ARRAY:
1039           /* Array references don't change the string length.  */
1040           break;
1041
1042         case COMPONENT_REF:
1043           /* Use the length of the component.  */
1044           ts = &ref->u.c.component->ts;
1045           break;
1046
1047         default:
1048           /* TODO: Substrings are tricky because we can't evaluate the
1049              expression more than once.  For now we just give up, and hope
1050              we can figure it out elsewhere.  */
1051           return;
1052         }
1053     }
1054
1055   *len = ts->cl->backend_decl;
1056 }
1057
1058
1059 /* Figure out the string length of a character array constructor.
1060    Returns TRUE if all elements are character constants.  */
1061
1062 static bool
1063 get_array_ctor_strlen (gfc_constructor * c, tree * len)
1064 {
1065   bool is_const;
1066   
1067   is_const = TRUE;
1068   for (; c; c = c->next)
1069     {
1070       switch (c->expr->expr_type)
1071         {
1072         case EXPR_CONSTANT:
1073           if (!(*len && INTEGER_CST_P (*len)))
1074             *len = build_int_cstu (gfc_charlen_type_node,
1075                                    c->expr->value.character.length);
1076           break;
1077
1078         case EXPR_ARRAY:
1079           if (!get_array_ctor_strlen (c->expr->value.constructor, len))
1080             is_const = FALSE;
1081           break;
1082
1083         case EXPR_VARIABLE:
1084           is_const = false;
1085           get_array_ctor_var_strlen (c->expr, len);
1086           break;
1087
1088         default:
1089           is_const = FALSE;
1090           /* TODO: For now we just ignore anything we don't know how to
1091              handle, and hope we can figure it out a different way.  */
1092           break;
1093         }
1094     }
1095
1096   return is_const;
1097 }
1098
1099
1100 /* Array constructors are handled by constructing a temporary, then using that
1101    within the scalarization loop.  This is not optimal, but seems by far the
1102    simplest method.  */
1103
1104 static void
1105 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
1106 {
1107   tree offset;
1108   tree offsetvar;
1109   tree desc;
1110   tree size;
1111   tree type;
1112   bool const_string;
1113
1114   ss->data.info.dimen = loop->dimen;
1115
1116   if (ss->expr->ts.type == BT_CHARACTER)
1117     {
1118       const_string = get_array_ctor_strlen (ss->expr->value.constructor,
1119                                             &ss->string_length);
1120       if (!ss->string_length)
1121         gfc_todo_error ("complex character array constructors");
1122
1123       type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1124       if (const_string)
1125         type = build_pointer_type (type);
1126     }
1127   else
1128     {
1129       const_string = TRUE;
1130       type = gfc_typenode_for_spec (&ss->expr->ts);
1131     }
1132
1133   size = gfc_trans_allocate_temp_array (loop, &ss->data.info, type);
1134
1135   desc = ss->data.info.descriptor;
1136   offset = gfc_index_zero_node;
1137   offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
1138   TREE_USED (offsetvar) = 0;
1139   gfc_trans_array_constructor_value (&loop->pre, type,
1140                                      ss->data.info.data,
1141                                      ss->expr->value.constructor, &offset,
1142                                      &offsetvar);
1143
1144   if (TREE_USED (offsetvar))
1145     pushdecl (offsetvar);
1146   else
1147     gcc_assert (INTEGER_CST_P (offset));
1148 #if 0
1149   /* Disable bound checking for now because it's probably broken.  */
1150   if (flag_bounds_check)
1151     {
1152       gcc_unreachable ();
1153     }
1154 #endif
1155 }
1156
1157
1158 /* Add the pre and post chains for all the scalar expressions in a SS chain
1159    to loop.  This is called after the loop parameters have been calculated,
1160    but before the actual scalarizing loops.  */
1161
1162 static void
1163 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
1164 {
1165   gfc_se se;
1166   int n;
1167
1168   /* TODO: This can generate bad code if there are ordering dependencies.
1169      eg. a callee allocated function and an unknown size constructor.  */
1170   gcc_assert (ss != NULL);
1171
1172   for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
1173     {
1174       gcc_assert (ss);
1175
1176       switch (ss->type)
1177         {
1178         case GFC_SS_SCALAR:
1179           /* Scalar expression.  Evaluate this now.  This includes elemental
1180              dimension indices, but not array section bounds.  */
1181           gfc_init_se (&se, NULL);
1182           gfc_conv_expr (&se, ss->expr);
1183           gfc_add_block_to_block (&loop->pre, &se.pre);
1184
1185           if (ss->expr->ts.type != BT_CHARACTER)
1186             {
1187               /* Move the evaluation of scalar expressions outside the
1188                  scalarization loop.  */
1189               if (subscript)
1190                 se.expr = convert(gfc_array_index_type, se.expr);
1191               se.expr = gfc_evaluate_now (se.expr, &loop->pre);
1192               gfc_add_block_to_block (&loop->pre, &se.post);
1193             }
1194           else
1195             gfc_add_block_to_block (&loop->post, &se.post);
1196
1197           ss->data.scalar.expr = se.expr;
1198           ss->string_length = se.string_length;
1199           break;
1200
1201         case GFC_SS_REFERENCE:
1202           /* Scalar reference.  Evaluate this now.  */
1203           gfc_init_se (&se, NULL);
1204           gfc_conv_expr_reference (&se, ss->expr);
1205           gfc_add_block_to_block (&loop->pre, &se.pre);
1206           gfc_add_block_to_block (&loop->post, &se.post);
1207
1208           ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
1209           ss->string_length = se.string_length;
1210           break;
1211
1212         case GFC_SS_SECTION:
1213         case GFC_SS_VECTOR:
1214           /* Scalarized expression.  Evaluate any scalar subscripts.  */
1215           for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1216             {
1217               /* Add the expressions for scalar subscripts.  */
1218               if (ss->data.info.subscript[n])
1219                 gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
1220             }
1221           break;
1222
1223         case GFC_SS_INTRINSIC:
1224           gfc_add_intrinsic_ss_code (loop, ss);
1225           break;
1226
1227         case GFC_SS_FUNCTION:
1228           /* Array function return value.  We call the function and save its
1229              result in a temporary for use inside the loop.  */
1230           gfc_init_se (&se, NULL);
1231           se.loop = loop;
1232           se.ss = ss;
1233           gfc_conv_expr (&se, ss->expr);
1234           gfc_add_block_to_block (&loop->pre, &se.pre);
1235           gfc_add_block_to_block (&loop->post, &se.post);
1236           break;
1237
1238         case GFC_SS_CONSTRUCTOR:
1239           gfc_trans_array_constructor (loop, ss);
1240           break;
1241
1242         case GFC_SS_TEMP:
1243         case GFC_SS_COMPONENT:
1244           /* Do nothing.  These are handled elsewhere.  */
1245           break;
1246
1247         default:
1248           gcc_unreachable ();
1249         }
1250     }
1251 }
1252
1253
1254 /* Translate expressions for the descriptor and data pointer of a SS.  */
1255 /*GCC ARRAYS*/
1256
1257 static void
1258 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
1259 {
1260   gfc_se se;
1261   tree tmp;
1262
1263   /* Get the descriptor for the array to be scalarized.  */
1264   gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
1265   gfc_init_se (&se, NULL);
1266   se.descriptor_only = 1;
1267   gfc_conv_expr_lhs (&se, ss->expr);
1268   gfc_add_block_to_block (block, &se.pre);
1269   ss->data.info.descriptor = se.expr;
1270   ss->string_length = se.string_length;
1271
1272   if (base)
1273     {
1274       /* Also the data pointer.  */
1275       tmp = gfc_conv_array_data (se.expr);
1276       /* If this is a variable or address of a variable we use it directly.
1277          Otherwise we must evaluate it now to avoid breaking dependency
1278          analysis by pulling the expressions for elemental array indices
1279          inside the loop.  */
1280       if (!(DECL_P (tmp)
1281             || (TREE_CODE (tmp) == ADDR_EXPR
1282                 && DECL_P (TREE_OPERAND (tmp, 0)))))
1283         tmp = gfc_evaluate_now (tmp, block);
1284       ss->data.info.data = tmp;
1285
1286       tmp = gfc_conv_array_offset (se.expr);
1287       ss->data.info.offset = gfc_evaluate_now (tmp, block);
1288     }
1289 }
1290
1291
1292 /* Initialize a gfc_loopinfo structure.  */
1293
1294 void
1295 gfc_init_loopinfo (gfc_loopinfo * loop)
1296 {
1297   int n;
1298
1299   memset (loop, 0, sizeof (gfc_loopinfo));
1300   gfc_init_block (&loop->pre);
1301   gfc_init_block (&loop->post);
1302
1303   /* Initially scalarize in order.  */
1304   for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1305     loop->order[n] = n;
1306
1307   loop->ss = gfc_ss_terminator;
1308 }
1309
1310
1311 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
1312    chain.  */
1313
1314 void
1315 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
1316 {
1317   se->loop = loop;
1318 }
1319
1320
1321 /* Return an expression for the data pointer of an array.  */
1322
1323 tree
1324 gfc_conv_array_data (tree descriptor)
1325 {
1326   tree type;
1327
1328   type = TREE_TYPE (descriptor);
1329   if (GFC_ARRAY_TYPE_P (type))
1330     {
1331       if (TREE_CODE (type) == POINTER_TYPE)
1332         return descriptor;
1333       else
1334         {
1335           /* Descriptorless arrays.  */
1336           return gfc_build_addr_expr (NULL, descriptor);
1337         }
1338     }
1339   else
1340     return gfc_conv_descriptor_data_get (descriptor);
1341 }
1342
1343
1344 /* Return an expression for the base offset of an array.  */
1345
1346 tree
1347 gfc_conv_array_offset (tree descriptor)
1348 {
1349   tree type;
1350
1351   type = TREE_TYPE (descriptor);
1352   if (GFC_ARRAY_TYPE_P (type))
1353     return GFC_TYPE_ARRAY_OFFSET (type);
1354   else
1355     return gfc_conv_descriptor_offset (descriptor);
1356 }
1357
1358
1359 /* Get an expression for the array stride.  */
1360
1361 tree
1362 gfc_conv_array_stride (tree descriptor, int dim)
1363 {
1364   tree tmp;
1365   tree type;
1366
1367   type = TREE_TYPE (descriptor);
1368
1369   /* For descriptorless arrays use the array size.  */
1370   tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
1371   if (tmp != NULL_TREE)
1372     return tmp;
1373
1374   tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
1375   return tmp;
1376 }
1377
1378
1379 /* Like gfc_conv_array_stride, but for the lower bound.  */
1380
1381 tree
1382 gfc_conv_array_lbound (tree descriptor, int dim)
1383 {
1384   tree tmp;
1385   tree type;
1386
1387   type = TREE_TYPE (descriptor);
1388
1389   tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
1390   if (tmp != NULL_TREE)
1391     return tmp;
1392
1393   tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
1394   return tmp;
1395 }
1396
1397
1398 /* Like gfc_conv_array_stride, but for the upper bound.  */
1399
1400 tree
1401 gfc_conv_array_ubound (tree descriptor, int dim)
1402 {
1403   tree tmp;
1404   tree type;
1405
1406   type = TREE_TYPE (descriptor);
1407
1408   tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
1409   if (tmp != NULL_TREE)
1410     return tmp;
1411
1412   /* This should only ever happen when passing an assumed shape array
1413      as an actual parameter.  The value will never be used.  */
1414   if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
1415     return gfc_index_zero_node;
1416
1417   tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
1418   return tmp;
1419 }
1420
1421
1422 /* Translate an array reference.  The descriptor should be in se->expr.
1423    Do not use this function, it wil be removed soon.  */
1424 /*GCC ARRAYS*/
1425
1426 static void
1427 gfc_conv_array_index_ref (gfc_se * se, tree pointer, tree * indices,
1428                          tree offset, int dimen)
1429 {
1430   tree array;
1431   tree tmp;
1432   tree index;
1433   int n;
1434
1435   array = gfc_build_indirect_ref (pointer);
1436
1437   index = offset;
1438   for (n = 0; n < dimen; n++)
1439     {
1440       /* index = index + stride[n]*indices[n] */
1441       tmp = gfc_conv_array_stride (se->expr, n);
1442       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indices[n], tmp);
1443
1444       index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1445     }
1446
1447   /* Result = data[index].  */
1448   tmp = gfc_build_array_ref (array, index);
1449
1450   /* Check we've used the correct number of dimensions.  */
1451   gcc_assert (TREE_CODE (TREE_TYPE (tmp)) != ARRAY_TYPE);
1452
1453   se->expr = tmp;
1454 }
1455
1456
1457 /* Generate code to perform an array index bound check.  */
1458
1459 static tree
1460 gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n)
1461 {
1462   tree cond;
1463   tree fault;
1464   tree tmp;
1465
1466   if (!flag_bounds_check)
1467     return index;
1468
1469   index = gfc_evaluate_now (index, &se->pre);
1470   /* Check lower bound.  */
1471   tmp = gfc_conv_array_lbound (descriptor, n);
1472   fault = fold_build2 (LT_EXPR, boolean_type_node, index, tmp);
1473   /* Check upper bound.  */
1474   tmp = gfc_conv_array_ubound (descriptor, n);
1475   cond = fold_build2 (GT_EXPR, boolean_type_node, index, tmp);
1476   fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1477
1478   gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1479
1480   return index;
1481 }
1482
1483
1484 /* A reference to an array vector subscript.  Uses recursion to handle nested
1485    vector subscripts.  */
1486
1487 static tree
1488 gfc_conv_vector_array_index (gfc_se * se, tree index, gfc_ss * ss)
1489 {
1490   tree descsave;
1491   tree indices[GFC_MAX_DIMENSIONS];
1492   gfc_array_ref *ar;
1493   gfc_ss_info *info;
1494   int n;
1495
1496   gcc_assert (ss && ss->type == GFC_SS_VECTOR);
1497
1498   /* Save the descriptor.  */
1499   descsave = se->expr;
1500   info = &ss->data.info;
1501   se->expr = info->descriptor;
1502
1503   ar = &info->ref->u.ar;
1504   for (n = 0; n < ar->dimen; n++)
1505     {
1506       switch (ar->dimen_type[n])
1507         {
1508         case DIMEN_ELEMENT:
1509           gcc_assert (info->subscript[n] != gfc_ss_terminator
1510                   && info->subscript[n]->type == GFC_SS_SCALAR);
1511           indices[n] = info->subscript[n]->data.scalar.expr;
1512           break;
1513
1514         case DIMEN_RANGE:
1515           indices[n] = index;
1516           break;
1517
1518         case DIMEN_VECTOR:
1519           index = gfc_conv_vector_array_index (se, index, info->subscript[n]);
1520
1521           indices[n] =
1522             gfc_trans_array_bound_check (se, info->descriptor, index, n);
1523           break;
1524
1525         default:
1526           gcc_unreachable ();
1527         }
1528     }
1529   /* Get the index from the vector.  */
1530   gfc_conv_array_index_ref (se, info->data, indices, info->offset, ar->dimen);
1531   index = se->expr;
1532   /* Put the descriptor back.  */
1533   se->expr = descsave;
1534
1535   return index;
1536 }
1537
1538
1539 /* Return the offset for an index.  Performs bound checking for elemental
1540    dimensions.  Single element references are processed separately.  */
1541
1542 static tree
1543 gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
1544                              gfc_array_ref * ar, tree stride)
1545 {
1546   tree index;
1547
1548   /* Get the index into the array for this dimension.  */
1549   if (ar)
1550     {
1551       gcc_assert (ar->type != AR_ELEMENT);
1552       if (ar->dimen_type[dim] == DIMEN_ELEMENT)
1553         {
1554           gcc_assert (i == -1);
1555           /* Elemental dimension.  */
1556           gcc_assert (info->subscript[dim]
1557                   && info->subscript[dim]->type == GFC_SS_SCALAR);
1558           /* We've already translated this value outside the loop.  */
1559           index = info->subscript[dim]->data.scalar.expr;
1560
1561           index =
1562             gfc_trans_array_bound_check (se, info->descriptor, index, dim);
1563         }
1564       else
1565         {
1566           /* Scalarized dimension.  */
1567           gcc_assert (info && se->loop);
1568
1569           /* Multiply the loop variable by the stride and delta.  */
1570           index = se->loop->loopvar[i];
1571           index = fold_build2 (MULT_EXPR, gfc_array_index_type, index,
1572                                info->stride[i]);
1573           index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index,
1574                                info->delta[i]);
1575
1576           if (ar->dimen_type[dim] == DIMEN_VECTOR)
1577             {
1578               /* Handle vector subscripts.  */
1579               index = gfc_conv_vector_array_index (se, index,
1580                                                    info->subscript[dim]);
1581               index =
1582                 gfc_trans_array_bound_check (se, info->descriptor, index,
1583                                              dim);
1584             }
1585           else
1586             gcc_assert (ar->dimen_type[dim] == DIMEN_RANGE);
1587         }
1588     }
1589   else
1590     {
1591       /* Temporary array or derived type component.  */
1592       gcc_assert (se->loop);
1593       index = se->loop->loopvar[se->loop->order[i]];
1594       if (!integer_zerop (info->delta[i]))
1595         index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1596                              index, info->delta[i]);
1597     }
1598
1599   /* Multiply by the stride.  */
1600   index = fold_build2 (MULT_EXPR, gfc_array_index_type, index, stride);
1601
1602   return index;
1603 }
1604
1605
1606 /* Build a scalarized reference to an array.  */
1607
1608 static void
1609 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
1610 {
1611   gfc_ss_info *info;
1612   tree index;
1613   tree tmp;
1614   int n;
1615
1616   info = &se->ss->data.info;
1617   if (ar)
1618     n = se->loop->order[0];
1619   else
1620     n = 0;
1621
1622   index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
1623                                        info->stride0);
1624   /* Add the offset for this dimension to the stored offset for all other
1625      dimensions.  */
1626   index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, info->offset);
1627
1628   tmp = gfc_build_indirect_ref (info->data);
1629   se->expr = gfc_build_array_ref (tmp, index);
1630 }
1631
1632
1633 /* Translate access of temporary array.  */
1634
1635 void
1636 gfc_conv_tmp_array_ref (gfc_se * se)
1637 {
1638   se->string_length = se->ss->string_length;
1639   gfc_conv_scalarized_array_ref (se, NULL);
1640 }
1641
1642
1643 /* Build an array reference.  se->expr already holds the array descriptor.
1644    This should be either a variable, indirect variable reference or component
1645    reference.  For arrays which do not have a descriptor, se->expr will be
1646    the data pointer.
1647    a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
1648
1649 void
1650 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar)
1651 {
1652   int n;
1653   tree index;
1654   tree tmp;
1655   tree stride;
1656   tree fault;
1657   gfc_se indexse;
1658
1659   /* Handle scalarized references separately.  */
1660   if (ar->type != AR_ELEMENT)
1661     {
1662       gfc_conv_scalarized_array_ref (se, ar);
1663       return;
1664     }
1665
1666   index = gfc_index_zero_node;
1667
1668   fault = gfc_index_zero_node;
1669
1670   /* Calculate the offsets from all the dimensions.  */
1671   for (n = 0; n < ar->dimen; n++)
1672     {
1673       /* Calculate the index for this dimension.  */
1674       gfc_init_se (&indexse, NULL);
1675       gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
1676       gfc_add_block_to_block (&se->pre, &indexse.pre);
1677
1678       if (flag_bounds_check)
1679         {
1680           /* Check array bounds.  */
1681           tree cond;
1682
1683           indexse.expr = gfc_evaluate_now (indexse.expr, &se->pre);
1684
1685           tmp = gfc_conv_array_lbound (se->expr, n);
1686           cond = fold_build2 (LT_EXPR, boolean_type_node, 
1687                               indexse.expr, tmp);
1688           fault =
1689             fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1690
1691           tmp = gfc_conv_array_ubound (se->expr, n);
1692           cond = fold_build2 (GT_EXPR, boolean_type_node, 
1693                               indexse.expr, tmp);
1694           fault =
1695             fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1696         }
1697
1698       /* Multiply the index by the stride.  */
1699       stride = gfc_conv_array_stride (se->expr, n);
1700       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indexse.expr,
1701                          stride);
1702
1703       /* And add it to the total.  */
1704       index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1705     }
1706
1707   if (flag_bounds_check)
1708     gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1709
1710   tmp = gfc_conv_array_offset (se->expr);
1711   if (!integer_zerop (tmp))
1712     index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1713       
1714   /* Access the calculated element.  */
1715   tmp = gfc_conv_array_data (se->expr);
1716   tmp = gfc_build_indirect_ref (tmp);
1717   se->expr = gfc_build_array_ref (tmp, index);
1718 }
1719
1720
1721 /* Generate the code to be executed immediately before entering a
1722    scalarization loop.  */
1723
1724 static void
1725 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
1726                          stmtblock_t * pblock)
1727 {
1728   tree index;
1729   tree stride;
1730   gfc_ss_info *info;
1731   gfc_ss *ss;
1732   gfc_se se;
1733   int i;
1734
1735   /* This code will be executed before entering the scalarization loop
1736      for this dimension.  */
1737   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
1738     {
1739       if ((ss->useflags & flag) == 0)
1740         continue;
1741
1742       if (ss->type != GFC_SS_SECTION
1743           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
1744           && ss->type != GFC_SS_COMPONENT)
1745         continue;
1746
1747       info = &ss->data.info;
1748
1749       if (dim >= info->dimen)
1750         continue;
1751
1752       if (dim == info->dimen - 1)
1753         {
1754           /* For the outermost loop calculate the offset due to any
1755              elemental dimensions.  It will have been initialized with the
1756              base offset of the array.  */
1757           if (info->ref)
1758             {
1759               for (i = 0; i < info->ref->u.ar.dimen; i++)
1760                 {
1761                   if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
1762                     continue;
1763
1764                   gfc_init_se (&se, NULL);
1765                   se.loop = loop;
1766                   se.expr = info->descriptor;
1767                   stride = gfc_conv_array_stride (info->descriptor, i);
1768                   index = gfc_conv_array_index_offset (&se, info, i, -1,
1769                                                        &info->ref->u.ar,
1770                                                        stride);
1771                   gfc_add_block_to_block (pblock, &se.pre);
1772
1773                   info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1774                                               info->offset, index);
1775                   info->offset = gfc_evaluate_now (info->offset, pblock);
1776                 }
1777
1778               i = loop->order[0];
1779               stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
1780             }
1781           else
1782             stride = gfc_conv_array_stride (info->descriptor, 0);
1783
1784           /* Calculate the stride of the innermost loop.  Hopefully this will
1785              allow the backend optimizers to do their stuff more effectively.
1786            */
1787           info->stride0 = gfc_evaluate_now (stride, pblock);
1788         }
1789       else
1790         {
1791           /* Add the offset for the previous loop dimension.  */
1792           gfc_array_ref *ar;
1793
1794           if (info->ref)
1795             {
1796               ar = &info->ref->u.ar;
1797               i = loop->order[dim + 1];
1798             }
1799           else
1800             {
1801               ar = NULL;
1802               i = dim + 1;
1803             }
1804
1805           gfc_init_se (&se, NULL);
1806           se.loop = loop;
1807           se.expr = info->descriptor;
1808           stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
1809           index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
1810                                                ar, stride);
1811           gfc_add_block_to_block (pblock, &se.pre);
1812           info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1813                                       info->offset, index);
1814           info->offset = gfc_evaluate_now (info->offset, pblock);
1815         }
1816
1817       /* Remember this offset for the second loop.  */
1818       if (dim == loop->temp_dim - 1)
1819         info->saved_offset = info->offset;
1820     }
1821 }
1822
1823
1824 /* Start a scalarized expression.  Creates a scope and declares loop
1825    variables.  */
1826
1827 void
1828 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
1829 {
1830   int dim;
1831   int n;
1832   int flags;
1833
1834   gcc_assert (!loop->array_parameter);
1835
1836   for (dim = loop->dimen - 1; dim >= 0; dim--)
1837     {
1838       n = loop->order[dim];
1839
1840       gfc_start_block (&loop->code[n]);
1841
1842       /* Create the loop variable.  */
1843       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
1844
1845       if (dim < loop->temp_dim)
1846         flags = 3;
1847       else
1848         flags = 1;
1849       /* Calculate values that will be constant within this loop.  */
1850       gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
1851     }
1852   gfc_start_block (pbody);
1853 }
1854
1855
1856 /* Generates the actual loop code for a scalarization loop.  */
1857
1858 static void
1859 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
1860                                stmtblock_t * pbody)
1861 {
1862   stmtblock_t block;
1863   tree cond;
1864   tree tmp;
1865   tree loopbody;
1866   tree exit_label;
1867
1868   loopbody = gfc_finish_block (pbody);
1869
1870   /* Initialize the loopvar.  */
1871   gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
1872
1873   exit_label = gfc_build_label_decl (NULL_TREE);
1874
1875   /* Generate the loop body.  */
1876   gfc_init_block (&block);
1877
1878   /* The exit condition.  */
1879   cond = build2 (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);
1880   tmp = build1_v (GOTO_EXPR, exit_label);
1881   TREE_USED (exit_label) = 1;
1882   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1883   gfc_add_expr_to_block (&block, tmp);
1884
1885   /* The main body.  */
1886   gfc_add_expr_to_block (&block, loopbody);
1887
1888   /* Increment the loopvar.  */
1889   tmp = build2 (PLUS_EXPR, gfc_array_index_type,
1890                 loop->loopvar[n], gfc_index_one_node);
1891   gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
1892
1893   /* Build the loop.  */
1894   tmp = gfc_finish_block (&block);
1895   tmp = build1_v (LOOP_EXPR, tmp);
1896   gfc_add_expr_to_block (&loop->code[n], tmp);
1897
1898   /* Add the exit label.  */
1899   tmp = build1_v (LABEL_EXPR, exit_label);
1900   gfc_add_expr_to_block (&loop->code[n], tmp);
1901 }
1902
1903
1904 /* Finishes and generates the loops for a scalarized expression.  */
1905
1906 void
1907 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
1908 {
1909   int dim;
1910   int n;
1911   gfc_ss *ss;
1912   stmtblock_t *pblock;
1913   tree tmp;
1914
1915   pblock = body;
1916   /* Generate the loops.  */
1917   for (dim = 0; dim < loop->dimen; dim++)
1918     {
1919       n = loop->order[dim];
1920       gfc_trans_scalarized_loop_end (loop, n, pblock);
1921       loop->loopvar[n] = NULL_TREE;
1922       pblock = &loop->code[n];
1923     }
1924
1925   tmp = gfc_finish_block (pblock);
1926   gfc_add_expr_to_block (&loop->pre, tmp);
1927
1928   /* Clear all the used flags.  */
1929   for (ss = loop->ss; ss; ss = ss->loop_chain)
1930     ss->useflags = 0;
1931 }
1932
1933
1934 /* Finish the main body of a scalarized expression, and start the secondary
1935    copying body.  */
1936
1937 void
1938 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
1939 {
1940   int dim;
1941   int n;
1942   stmtblock_t *pblock;
1943   gfc_ss *ss;
1944
1945   pblock = body;
1946   /* We finish as many loops as are used by the temporary.  */
1947   for (dim = 0; dim < loop->temp_dim - 1; dim++)
1948     {
1949       n = loop->order[dim];
1950       gfc_trans_scalarized_loop_end (loop, n, pblock);
1951       loop->loopvar[n] = NULL_TREE;
1952       pblock = &loop->code[n];
1953     }
1954
1955   /* We don't want to finish the outermost loop entirely.  */
1956   n = loop->order[loop->temp_dim - 1];
1957   gfc_trans_scalarized_loop_end (loop, n, pblock);
1958
1959   /* Restore the initial offsets.  */
1960   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
1961     {
1962       if ((ss->useflags & 2) == 0)
1963         continue;
1964
1965       if (ss->type != GFC_SS_SECTION
1966           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
1967           && ss->type != GFC_SS_COMPONENT)
1968         continue;
1969
1970       ss->data.info.offset = ss->data.info.saved_offset;
1971     }
1972
1973   /* Restart all the inner loops we just finished.  */
1974   for (dim = loop->temp_dim - 2; dim >= 0; dim--)
1975     {
1976       n = loop->order[dim];
1977
1978       gfc_start_block (&loop->code[n]);
1979
1980       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
1981
1982       gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
1983     }
1984
1985   /* Start a block for the secondary copying code.  */
1986   gfc_start_block (body);
1987 }
1988
1989
1990 /* Calculate the upper bound of an array section.  */
1991
1992 static tree
1993 gfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock)
1994 {
1995   int dim;
1996   gfc_ss *vecss;
1997   gfc_expr *end;
1998   tree desc;
1999   tree bound;
2000   gfc_se se;
2001
2002   gcc_assert (ss->type == GFC_SS_SECTION);
2003
2004   /* For vector array subscripts we want the size of the vector.  */
2005   dim = ss->data.info.dim[n];
2006   vecss = ss;
2007   while (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2008     {
2009       vecss = vecss->data.info.subscript[dim];
2010       gcc_assert (vecss && vecss->type == GFC_SS_VECTOR);
2011       dim = vecss->data.info.dim[0];
2012     }
2013
2014   gcc_assert (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2015   end = vecss->data.info.ref->u.ar.end[dim];
2016   desc = vecss->data.info.descriptor;
2017
2018   if (end)
2019     {
2020       /* The upper bound was specified.  */
2021       gfc_init_se (&se, NULL);
2022       gfc_conv_expr_type (&se, end, gfc_array_index_type);
2023       gfc_add_block_to_block (pblock, &se.pre);
2024       bound = se.expr;
2025     }
2026   else
2027     {
2028       /* No upper bound was specified, so use the bound of the array.  */
2029       bound = gfc_conv_array_ubound (desc, dim);
2030     }
2031
2032   return bound;
2033 }
2034
2035
2036 /* Calculate the lower bound of an array section.  */
2037
2038 static void
2039 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
2040 {
2041   gfc_expr *start;
2042   gfc_expr *stride;
2043   gfc_ss *vecss;
2044   tree desc;
2045   gfc_se se;
2046   gfc_ss_info *info;
2047   int dim;
2048
2049   info = &ss->data.info;
2050
2051   dim = info->dim[n];
2052
2053   /* For vector array subscripts we want the size of the vector.  */
2054   vecss = ss;
2055   while (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2056     {
2057       vecss = vecss->data.info.subscript[dim];
2058       gcc_assert (vecss && vecss->type == GFC_SS_VECTOR);
2059       /* Get the descriptors for the vector subscripts as well.  */
2060       if (!vecss->data.info.descriptor)
2061         gfc_conv_ss_descriptor (&loop->pre, vecss, !loop->array_parameter);
2062       dim = vecss->data.info.dim[0];
2063     }
2064
2065   gcc_assert (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2066   start = vecss->data.info.ref->u.ar.start[dim];
2067   stride = vecss->data.info.ref->u.ar.stride[dim];
2068   desc = vecss->data.info.descriptor;
2069
2070   /* Calculate the start of the range.  For vector subscripts this will
2071      be the range of the vector.  */
2072   if (start)
2073     {
2074       /* Specified section start.  */
2075       gfc_init_se (&se, NULL);
2076       gfc_conv_expr_type (&se, start, gfc_array_index_type);
2077       gfc_add_block_to_block (&loop->pre, &se.pre);
2078       info->start[n] = se.expr;
2079     }
2080   else
2081     {
2082       /* No lower bound specified so use the bound of the array.  */
2083       info->start[n] = gfc_conv_array_lbound (desc, dim);
2084     }
2085   info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);
2086
2087   /* Calculate the stride.  */
2088   if (stride == NULL)
2089     info->stride[n] = gfc_index_one_node;
2090   else
2091     {
2092       gfc_init_se (&se, NULL);
2093       gfc_conv_expr_type (&se, stride, gfc_array_index_type);
2094       gfc_add_block_to_block (&loop->pre, &se.pre);
2095       info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);
2096     }
2097 }
2098
2099
2100 /* Calculates the range start and stride for a SS chain.  Also gets the
2101    descriptor and data pointer.  The range of vector subscripts is the size
2102    of the vector.  Array bounds are also checked.  */
2103
2104 void
2105 gfc_conv_ss_startstride (gfc_loopinfo * loop)
2106 {
2107   int n;
2108   tree tmp;
2109   gfc_ss *ss;
2110   gfc_ss *vecss;
2111   tree desc;
2112
2113   loop->dimen = 0;
2114   /* Determine the rank of the loop.  */
2115   for (ss = loop->ss;
2116        ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
2117     {
2118       switch (ss->type)
2119         {
2120         case GFC_SS_SECTION:
2121         case GFC_SS_CONSTRUCTOR:
2122         case GFC_SS_FUNCTION:
2123         case GFC_SS_COMPONENT:
2124           loop->dimen = ss->data.info.dimen;
2125           break;
2126
2127         default:
2128           break;
2129         }
2130     }
2131
2132   if (loop->dimen == 0)
2133     gfc_todo_error ("Unable to determine rank of expression");
2134
2135
2136   /* Loop over all the SS in the chain.  */
2137   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2138     {
2139       if (ss->expr && ss->expr->shape && !ss->shape)
2140         ss->shape = ss->expr->shape;
2141
2142       switch (ss->type)
2143         {
2144         case GFC_SS_SECTION:
2145           /* Get the descriptor for the array.  */
2146           gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
2147
2148           for (n = 0; n < ss->data.info.dimen; n++)
2149             gfc_conv_section_startstride (loop, ss, n);
2150           break;
2151
2152         case GFC_SS_CONSTRUCTOR:
2153         case GFC_SS_FUNCTION:
2154           for (n = 0; n < ss->data.info.dimen; n++)
2155             {
2156               ss->data.info.start[n] = gfc_index_zero_node;
2157               ss->data.info.stride[n] = gfc_index_one_node;
2158             }
2159           break;
2160
2161         default:
2162           break;
2163         }
2164     }
2165
2166   /* The rest is just runtime bound checking.  */
2167   if (flag_bounds_check)
2168     {
2169       stmtblock_t block;
2170       tree fault;
2171       tree bound;
2172       tree end;
2173       tree size[GFC_MAX_DIMENSIONS];
2174       gfc_ss_info *info;
2175       int dim;
2176
2177       gfc_start_block (&block);
2178
2179       fault = integer_zero_node;
2180       for (n = 0; n < loop->dimen; n++)
2181         size[n] = NULL_TREE;
2182
2183       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2184         {
2185           if (ss->type != GFC_SS_SECTION)
2186             continue;
2187
2188           /* TODO: range checking for mapped dimensions.  */
2189           info = &ss->data.info;
2190
2191           /* This only checks scalarized dimensions, elemental dimensions are
2192              checked later.  */
2193           for (n = 0; n < loop->dimen; n++)
2194             {
2195               dim = info->dim[n];
2196               vecss = ss;
2197               while (vecss->data.info.ref->u.ar.dimen_type[dim]
2198                      == DIMEN_VECTOR)
2199                 {
2200                   vecss = vecss->data.info.subscript[dim];
2201                   gcc_assert (vecss && vecss->type == GFC_SS_VECTOR);
2202                   dim = vecss->data.info.dim[0];
2203                 }
2204               gcc_assert (vecss->data.info.ref->u.ar.dimen_type[dim]
2205                       == DIMEN_RANGE);
2206               desc = vecss->data.info.descriptor;
2207
2208               /* Check lower bound.  */
2209               bound = gfc_conv_array_lbound (desc, dim);
2210               tmp = info->start[n];
2211               tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp, bound);
2212               fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2213                                    tmp);
2214
2215               /* Check the upper bound.  */
2216               bound = gfc_conv_array_ubound (desc, dim);
2217               end = gfc_conv_section_upper_bound (ss, n, &block);
2218               tmp = fold_build2 (GT_EXPR, boolean_type_node, end, bound);
2219               fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2220                                    tmp);
2221
2222               /* Check the section sizes match.  */
2223               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2224                                  info->start[n]);
2225               tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
2226                                  info->stride[n]);
2227               /* We remember the size of the first section, and check all the
2228                  others against this.  */
2229               if (size[n])
2230                 {
2231                   tmp =
2232                     fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
2233                   fault =
2234                     build2 (TRUTH_OR_EXPR, boolean_type_node, fault, tmp);
2235                 }
2236               else
2237                 size[n] = gfc_evaluate_now (tmp, &block);
2238             }
2239         }
2240       gfc_trans_runtime_check (fault, gfc_strconst_bounds, &block);
2241
2242       tmp = gfc_finish_block (&block);
2243       gfc_add_expr_to_block (&loop->pre, tmp);
2244     }
2245 }
2246
2247
2248 /* Return true if the two SS could be aliased, i.e. both point to the same data
2249    object.  */
2250 /* TODO: resolve aliases based on frontend expressions.  */
2251
2252 static int
2253 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
2254 {
2255   gfc_ref *lref;
2256   gfc_ref *rref;
2257   gfc_symbol *lsym;
2258   gfc_symbol *rsym;
2259
2260   lsym = lss->expr->symtree->n.sym;
2261   rsym = rss->expr->symtree->n.sym;
2262   if (gfc_symbols_could_alias (lsym, rsym))
2263     return 1;
2264
2265   if (rsym->ts.type != BT_DERIVED
2266       && lsym->ts.type != BT_DERIVED)
2267     return 0;
2268
2269   /* For derived types we must check all the component types.  We can ignore
2270      array references as these will have the same base type as the previous
2271      component ref.  */
2272   for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
2273     {
2274       if (lref->type != REF_COMPONENT)
2275         continue;
2276
2277       if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
2278         return 1;
2279
2280       for (rref = rss->expr->ref; rref != rss->data.info.ref;
2281            rref = rref->next)
2282         {
2283           if (rref->type != REF_COMPONENT)
2284             continue;
2285
2286           if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
2287             return 1;
2288         }
2289     }
2290
2291   for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
2292     {
2293       if (rref->type != REF_COMPONENT)
2294         break;
2295
2296       if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
2297         return 1;
2298     }
2299
2300   return 0;
2301 }
2302
2303
2304 /* Resolve array data dependencies.  Creates a temporary if required.  */
2305 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
2306    dependency.c.  */
2307
2308 void
2309 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
2310                                gfc_ss * rss)
2311 {
2312   gfc_ss *ss;
2313   gfc_ref *lref;
2314   gfc_ref *rref;
2315   gfc_ref *aref;
2316   int nDepend = 0;
2317   int temp_dim = 0;
2318
2319   loop->temp_ss = NULL;
2320   aref = dest->data.info.ref;
2321   temp_dim = 0;
2322
2323   for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
2324     {
2325       if (ss->type != GFC_SS_SECTION)
2326         continue;
2327
2328       if (gfc_could_be_alias (dest, ss))
2329         {
2330           nDepend = 1;
2331           break;
2332         }
2333
2334       if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
2335         {
2336           lref = dest->expr->ref;
2337           rref = ss->expr->ref;
2338
2339           nDepend = gfc_dep_resolver (lref, rref);
2340 #if 0
2341           /* TODO : loop shifting.  */
2342           if (nDepend == 1)
2343             {
2344               /* Mark the dimensions for LOOP SHIFTING */
2345               for (n = 0; n < loop->dimen; n++)
2346                 {
2347                   int dim = dest->data.info.dim[n];
2348
2349                   if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2350                     depends[n] = 2;
2351                   else if (! gfc_is_same_range (&lref->u.ar,
2352                                                 &rref->u.ar, dim, 0))
2353                     depends[n] = 1;
2354                  }
2355
2356               /* Put all the dimensions with dependencies in the
2357                  innermost loops.  */
2358               dim = 0;
2359               for (n = 0; n < loop->dimen; n++)
2360                 {
2361                   gcc_assert (loop->order[n] == n);
2362                   if (depends[n])
2363                   loop->order[dim++] = n;
2364                 }
2365               temp_dim = dim;
2366               for (n = 0; n < loop->dimen; n++)
2367                 {
2368                   if (! depends[n])
2369                   loop->order[dim++] = n;
2370                 }
2371
2372               gcc_assert (dim == loop->dimen);
2373               break;
2374             }
2375 #endif
2376         }
2377     }
2378
2379   if (nDepend == 1)
2380     {
2381       loop->temp_ss = gfc_get_ss ();
2382       loop->temp_ss->type = GFC_SS_TEMP;
2383       loop->temp_ss->data.temp.type =
2384         gfc_get_element_type (TREE_TYPE (dest->data.info.descriptor));
2385       loop->temp_ss->string_length = dest->string_length;
2386       loop->temp_ss->data.temp.dimen = loop->dimen;
2387       loop->temp_ss->next = gfc_ss_terminator;
2388       gfc_add_ss_to_loop (loop, loop->temp_ss);
2389     }
2390   else
2391     loop->temp_ss = NULL;
2392 }
2393
2394
2395 /* Initialize the scalarization loop.  Creates the loop variables.  Determines
2396    the range of the loop variables.  Creates a temporary if required.
2397    Calculates how to transform from loop variables to array indices for each
2398    expression.  Also generates code for scalar expressions which have been
2399    moved outside the loop.  */
2400
2401 void
2402 gfc_conv_loop_setup (gfc_loopinfo * loop)
2403 {
2404   int n;
2405   int dim;
2406   gfc_ss_info *info;
2407   gfc_ss_info *specinfo;
2408   gfc_ss *ss;
2409   tree tmp;
2410   tree len;
2411   gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
2412   mpz_t *cshape;
2413   mpz_t i;
2414
2415   mpz_init (i);
2416   for (n = 0; n < loop->dimen; n++)
2417     {
2418       loopspec[n] = NULL;
2419       /* We use one SS term, and use that to determine the bounds of the
2420          loop for this dimension.  We try to pick the simplest term.  */
2421       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2422         {
2423           if (ss->shape)
2424             {
2425               /* The frontend has worked out the size for us.  */
2426               loopspec[n] = ss;
2427               continue;
2428             }
2429
2430           if (ss->type == GFC_SS_CONSTRUCTOR)
2431             {
2432               /* An unknown size constructor will always be rank one.
2433                  Higher rank constructors will either have known shape,
2434                  or still be wrapped in a call to reshape.  */
2435               gcc_assert (loop->dimen == 1);
2436               /* Try to figure out the size of the constructor.  */
2437               /* TODO: avoid this by making the frontend set the shape.  */
2438               gfc_get_array_cons_size (&i, ss->expr->value.constructor);
2439               /* A negative value means we failed.  */
2440               if (mpz_sgn (i) > 0)
2441                 {
2442                   mpz_sub_ui (i, i, 1);
2443                   loop->to[n] =
2444                     gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
2445                   loopspec[n] = ss;
2446                 }
2447               continue;
2448             }
2449
2450           /* TODO: Pick the best bound if we have a choice between a
2451              function and something else.  */
2452           if (ss->type == GFC_SS_FUNCTION)
2453             {
2454               loopspec[n] = ss;
2455               continue;
2456             }
2457
2458           if (ss->type != GFC_SS_SECTION)
2459             continue;
2460
2461           if (loopspec[n])
2462             specinfo = &loopspec[n]->data.info;
2463           else
2464             specinfo = NULL;
2465           info = &ss->data.info;
2466
2467           /* Criteria for choosing a loop specifier (most important first):
2468              stride of one
2469              known stride
2470              known lower bound
2471              known upper bound
2472            */
2473           if (!specinfo)
2474             loopspec[n] = ss;
2475           /* TODO: Is != constructor correct?  */
2476           else if (loopspec[n]->type != GFC_SS_CONSTRUCTOR)
2477             {
2478               if (integer_onep (info->stride[n])
2479                   && !integer_onep (specinfo->stride[n]))
2480                 loopspec[n] = ss;
2481               else if (INTEGER_CST_P (info->stride[n])
2482                        && !INTEGER_CST_P (specinfo->stride[n]))
2483                 loopspec[n] = ss;
2484               else if (INTEGER_CST_P (info->start[n])
2485                        && !INTEGER_CST_P (specinfo->start[n]))
2486                 loopspec[n] = ss;
2487               /* We don't work out the upper bound.
2488                  else if (INTEGER_CST_P (info->finish[n])
2489                  && ! INTEGER_CST_P (specinfo->finish[n]))
2490                  loopspec[n] = ss; */
2491             }
2492         }
2493
2494       if (!loopspec[n])
2495         gfc_todo_error ("Unable to find scalarization loop specifier");
2496
2497       info = &loopspec[n]->data.info;
2498
2499       /* Set the extents of this range.  */
2500       cshape = loopspec[n]->shape;
2501       if (cshape && INTEGER_CST_P (info->start[n])
2502           && INTEGER_CST_P (info->stride[n]))
2503         {
2504           loop->from[n] = info->start[n];
2505           mpz_set (i, cshape[n]);
2506           mpz_sub_ui (i, i, 1);
2507           /* To = from + (size - 1) * stride.  */
2508           tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
2509           if (!integer_onep (info->stride[n]))
2510             tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2511                                tmp, info->stride[n]);
2512           loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2513                                      loop->from[n], tmp);
2514         }
2515       else
2516         {
2517           loop->from[n] = info->start[n];
2518           switch (loopspec[n]->type)
2519             {
2520             case GFC_SS_CONSTRUCTOR:
2521               gcc_assert (info->dimen == 1);
2522               gcc_assert (loop->to[n]);
2523               break;
2524
2525             case GFC_SS_SECTION:
2526               loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
2527                                                           &loop->pre);
2528               break;
2529
2530             case GFC_SS_FUNCTION:
2531               /* The loop bound will be set when we generate the call.  */
2532               gcc_assert (loop->to[n] == NULL_TREE);
2533               break;
2534
2535             default:
2536               gcc_unreachable ();
2537             }
2538         }
2539
2540       /* Transform everything so we have a simple incrementing variable.  */
2541       if (integer_onep (info->stride[n]))
2542         info->delta[n] = gfc_index_zero_node;
2543       else
2544         {
2545           /* Set the delta for this section.  */
2546           info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
2547           /* Number of iterations is (end - start + step) / step.
2548              with start = 0, this simplifies to
2549              last = end / step;
2550              for (i = 0; i<=last; i++){...};  */
2551           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2552                              loop->to[n], loop->from[n]);
2553           tmp = fold_build2 (TRUNC_DIV_EXPR, gfc_array_index_type, 
2554                              tmp, info->stride[n]);
2555           loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
2556           /* Make the loop variable start at 0.  */
2557           loop->from[n] = gfc_index_zero_node;
2558         }
2559     }
2560
2561   /* Add all the scalar code that can be taken out of the loops.
2562      This may include calculating the loop bounds, so do it before
2563      allocating the temporary.  */
2564   gfc_add_loop_ss_code (loop, loop->ss, false);
2565
2566   /* If we want a temporary then create it.  */
2567   if (loop->temp_ss != NULL)
2568     {
2569       gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
2570       tmp = loop->temp_ss->data.temp.type;
2571       len = loop->temp_ss->string_length;
2572       n = loop->temp_ss->data.temp.dimen;
2573       memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
2574       loop->temp_ss->type = GFC_SS_SECTION;
2575       loop->temp_ss->data.info.dimen = n;
2576       gfc_trans_allocate_temp_array (loop, &loop->temp_ss->data.info, tmp);
2577     }
2578
2579   for (n = 0; n < loop->temp_dim; n++)
2580     loopspec[loop->order[n]] = NULL;
2581
2582   mpz_clear (i);
2583
2584   /* For array parameters we don't have loop variables, so don't calculate the
2585      translations.  */
2586   if (loop->array_parameter)
2587     return;
2588
2589   /* Calculate the translation from loop variables to array indices.  */
2590   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2591     {
2592       if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT)
2593         continue;
2594
2595       info = &ss->data.info;
2596
2597       for (n = 0; n < info->dimen; n++)
2598         {
2599           dim = info->dim[n];
2600
2601           /* If we are specifying the range the delta is already set.  */
2602           if (loopspec[n] != ss)
2603             {
2604               /* Calculate the offset relative to the loop variable.
2605                  First multiply by the stride.  */
2606               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2607                                  loop->from[n], info->stride[n]);
2608
2609               /* Then subtract this from our starting value.  */
2610               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2611                                  info->start[n], tmp);
2612
2613               info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
2614             }
2615         }
2616     }
2617 }
2618
2619
2620 /* Fills in an array descriptor, and returns the size of the array.  The size
2621    will be a simple_val, ie a variable or a constant.  Also calculates the
2622    offset of the base.  Returns the size of the array.
2623    {
2624     stride = 1;
2625     offset = 0;
2626     for (n = 0; n < rank; n++)
2627       {
2628         a.lbound[n] = specified_lower_bound;
2629         offset = offset + a.lbond[n] * stride;
2630         size = 1 - lbound;
2631         a.ubound[n] = specified_upper_bound;
2632         a.stride[n] = stride;
2633         size = ubound + size; //size = ubound + 1 - lbound
2634         stride = stride * size;
2635       }
2636     return (stride);
2637    }  */
2638 /*GCC ARRAYS*/
2639
2640 static tree
2641 gfc_array_init_size (tree descriptor, int rank, tree * poffset,
2642                      gfc_expr ** lower, gfc_expr ** upper,
2643                      stmtblock_t * pblock)
2644 {
2645   tree type;
2646   tree tmp;
2647   tree size;
2648   tree offset;
2649   tree stride;
2650   gfc_expr *ubound;
2651   gfc_se se;
2652   int n;
2653
2654   type = TREE_TYPE (descriptor);
2655
2656   stride = gfc_index_one_node;
2657   offset = gfc_index_zero_node;
2658
2659   /* Set the dtype.  */
2660   tmp = gfc_conv_descriptor_dtype (descriptor);
2661   gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
2662
2663   for (n = 0; n < rank; n++)
2664     {
2665       /* We have 3 possibilities for determining the size of the array:
2666          lower == NULL    => lbound = 1, ubound = upper[n]
2667          upper[n] = NULL  => lbound = 1, ubound = lower[n]
2668          upper[n] != NULL => lbound = lower[n], ubound = upper[n]  */
2669       ubound = upper[n];
2670
2671       /* Set lower bound.  */
2672       gfc_init_se (&se, NULL);
2673       if (lower == NULL)
2674         se.expr = gfc_index_one_node;
2675       else
2676         {
2677           gcc_assert (lower[n]);
2678           if (ubound)
2679             {
2680               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
2681               gfc_add_block_to_block (pblock, &se.pre);
2682             }
2683           else
2684             {
2685               se.expr = gfc_index_one_node;
2686               ubound = lower[n];
2687             }
2688         }
2689       tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
2690       gfc_add_modify_expr (pblock, tmp, se.expr);
2691
2692       /* Work out the offset for this component.  */
2693       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
2694       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
2695
2696       /* Start the calculation for the size of this dimension.  */
2697       size = build2 (MINUS_EXPR, gfc_array_index_type,
2698                      gfc_index_one_node, se.expr);
2699
2700       /* Set upper bound.  */
2701       gfc_init_se (&se, NULL);
2702       gcc_assert (ubound);
2703       gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
2704       gfc_add_block_to_block (pblock, &se.pre);
2705
2706       tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
2707       gfc_add_modify_expr (pblock, tmp, se.expr);
2708
2709       /* Store the stride.  */
2710       tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
2711       gfc_add_modify_expr (pblock, tmp, stride);
2712
2713       /* Calculate the size of this dimension.  */
2714       size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
2715
2716       /* Multiply the stride by the number of elements in this dimension.  */
2717       stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, size);
2718       stride = gfc_evaluate_now (stride, pblock);
2719     }
2720
2721   /* The stride is the number of elements in the array, so multiply by the
2722      size of an element to get the total size.  */
2723   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
2724   size = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, tmp);
2725
2726   if (poffset != NULL)
2727     {
2728       offset = gfc_evaluate_now (offset, pblock);
2729       *poffset = offset;
2730     }
2731
2732   size = gfc_evaluate_now (size, pblock);
2733   return size;
2734 }
2735
2736
2737 /* Initializes the descriptor and generates a call to _gfor_allocate.  Does
2738    the work for an ALLOCATE statement.  */
2739 /*GCC ARRAYS*/
2740
2741 void
2742 gfc_array_allocate (gfc_se * se, gfc_ref * ref, tree pstat)
2743 {
2744   tree tmp;
2745   tree pointer;
2746   tree allocate;
2747   tree offset;
2748   tree size;
2749   gfc_expr **lower;
2750   gfc_expr **upper;
2751
2752   /* Figure out the size of the array.  */
2753   switch (ref->u.ar.type)
2754     {
2755     case AR_ELEMENT:
2756       lower = NULL;
2757       upper = ref->u.ar.start;
2758       break;
2759
2760     case AR_FULL:
2761       gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
2762
2763       lower = ref->u.ar.as->lower;
2764       upper = ref->u.ar.as->upper;
2765       break;
2766
2767     case AR_SECTION:
2768       lower = ref->u.ar.start;
2769       upper = ref->u.ar.end;
2770       break;
2771
2772     default:
2773       gcc_unreachable ();
2774       break;
2775     }
2776
2777   size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
2778                               lower, upper, &se->pre);
2779
2780   /* Allocate memory to store the data.  */
2781   tmp = gfc_conv_descriptor_data_addr (se->expr);
2782   pointer = gfc_evaluate_now (tmp, &se->pre);
2783
2784   if (TYPE_PRECISION (gfc_array_index_type) == 32)
2785     allocate = gfor_fndecl_allocate;
2786   else if (TYPE_PRECISION (gfc_array_index_type) == 64)
2787     allocate = gfor_fndecl_allocate64;
2788   else
2789     gcc_unreachable ();
2790
2791   tmp = gfc_chainon_list (NULL_TREE, pointer);
2792   tmp = gfc_chainon_list (tmp, size);
2793   tmp = gfc_chainon_list (tmp, pstat);
2794   tmp = gfc_build_function_call (allocate, tmp);
2795   gfc_add_expr_to_block (&se->pre, tmp);
2796
2797   tmp = gfc_conv_descriptor_offset (se->expr);
2798   gfc_add_modify_expr (&se->pre, tmp, offset);
2799 }
2800
2801
2802 /* Deallocate an array variable.  Also used when an allocated variable goes
2803    out of scope.  */
2804 /*GCC ARRAYS*/
2805
2806 tree
2807 gfc_array_deallocate (tree descriptor, tree pstat)
2808 {
2809   tree var;
2810   tree tmp;
2811   stmtblock_t block;
2812
2813   gfc_start_block (&block);
2814   /* Get a pointer to the data.  */
2815   tmp = gfc_conv_descriptor_data_addr (descriptor);
2816   var = gfc_evaluate_now (tmp, &block);
2817
2818   /* Parameter is the address of the data component.  */
2819   tmp = gfc_chainon_list (NULL_TREE, var);
2820   tmp = gfc_chainon_list (tmp, pstat);
2821   tmp = gfc_build_function_call (gfor_fndecl_deallocate, tmp);
2822   gfc_add_expr_to_block (&block, tmp);
2823
2824   return gfc_finish_block (&block);
2825 }
2826
2827
2828 /* Create an array constructor from an initialization expression.
2829    We assume the frontend already did any expansions and conversions.  */
2830
2831 tree
2832 gfc_conv_array_initializer (tree type, gfc_expr * expr)
2833 {
2834   gfc_constructor *c;
2835   tree tmp;
2836   mpz_t maxval;
2837   gfc_se se;
2838   HOST_WIDE_INT hi;
2839   unsigned HOST_WIDE_INT lo;
2840   tree index, range;
2841   VEC(constructor_elt,gc) *v = NULL;
2842
2843   switch (expr->expr_type)
2844     {
2845     case EXPR_CONSTANT:
2846     case EXPR_STRUCTURE:
2847       /* A single scalar or derived type value.  Create an array with all
2848          elements equal to that value.  */
2849       gfc_init_se (&se, NULL);
2850       
2851       if (expr->expr_type == EXPR_CONSTANT)
2852         gfc_conv_constant (&se, expr);
2853       else
2854         gfc_conv_structure (&se, expr, 1);
2855
2856       tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2857       gcc_assert (tmp && INTEGER_CST_P (tmp));
2858       hi = TREE_INT_CST_HIGH (tmp);
2859       lo = TREE_INT_CST_LOW (tmp);
2860       lo++;
2861       if (lo == 0)
2862         hi++;
2863       /* This will probably eat buckets of memory for large arrays.  */
2864       while (hi != 0 || lo != 0)
2865         {
2866           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
2867           if (lo == 0)
2868             hi--;
2869           lo--;
2870         }
2871       break;
2872
2873     case EXPR_ARRAY:
2874       /* Create a vector of all the elements.  */
2875       for (c = expr->value.constructor; c; c = c->next)
2876         {
2877           if (c->iterator)
2878             {
2879               /* Problems occur when we get something like
2880                  integer :: a(lots) = (/(i, i=1,lots)/)  */
2881               /* TODO: Unexpanded array initializers.  */
2882               internal_error
2883                 ("Possible frontend bug: array constructor not expanded");
2884             }
2885           if (mpz_cmp_si (c->n.offset, 0) != 0)
2886             index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
2887           else
2888             index = NULL_TREE;
2889           mpz_init (maxval);
2890           if (mpz_cmp_si (c->repeat, 0) != 0)
2891             {
2892               tree tmp1, tmp2;
2893
2894               mpz_set (maxval, c->repeat);
2895               mpz_add (maxval, c->n.offset, maxval);
2896               mpz_sub_ui (maxval, maxval, 1);
2897               tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
2898               if (mpz_cmp_si (c->n.offset, 0) != 0)
2899                 {
2900                   mpz_add_ui (maxval, c->n.offset, 1);
2901                   tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
2902                 }
2903               else
2904                 tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
2905
2906               range = build2 (RANGE_EXPR, integer_type_node, tmp1, tmp2);
2907             }
2908           else
2909             range = NULL;
2910           mpz_clear (maxval);
2911
2912           gfc_init_se (&se, NULL);
2913           switch (c->expr->expr_type)
2914             {
2915             case EXPR_CONSTANT:
2916               gfc_conv_constant (&se, c->expr);
2917               if (range == NULL_TREE)
2918                 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
2919               else
2920                 {
2921                   if (index != NULL_TREE)
2922                     CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
2923                   CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
2924                 }
2925               break;
2926
2927             case EXPR_STRUCTURE:
2928               gfc_conv_structure (&se, c->expr, 1);
2929               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
2930               break;
2931
2932             default:
2933               gcc_unreachable ();
2934             }
2935         }
2936       break;
2937
2938     default:
2939       gcc_unreachable ();
2940     }
2941
2942   /* Create a constructor from the list of elements.  */
2943   tmp = build_constructor (type, v);
2944   TREE_CONSTANT (tmp) = 1;
2945   TREE_INVARIANT (tmp) = 1;
2946   return tmp;
2947 }
2948
2949
2950 /* Generate code to evaluate non-constant array bounds.  Sets *poffset and
2951    returns the size (in elements) of the array.  */
2952
2953 static tree
2954 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
2955                         stmtblock_t * pblock)
2956 {
2957   gfc_array_spec *as;
2958   tree size;
2959   tree stride;
2960   tree offset;
2961   tree ubound;
2962   tree lbound;
2963   tree tmp;
2964   gfc_se se;
2965
2966   int dim;
2967
2968   as = sym->as;
2969
2970   size = gfc_index_one_node;
2971   offset = gfc_index_zero_node;
2972   for (dim = 0; dim < as->rank; dim++)
2973     {
2974       /* Evaluate non-constant array bound expressions.  */
2975       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
2976       if (as->lower[dim] && !INTEGER_CST_P (lbound))
2977         {
2978           gfc_init_se (&se, NULL);
2979           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
2980           gfc_add_block_to_block (pblock, &se.pre);
2981           gfc_add_modify_expr (pblock, lbound, se.expr);
2982         }
2983       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
2984       if (as->upper[dim] && !INTEGER_CST_P (ubound))
2985         {
2986           gfc_init_se (&se, NULL);
2987           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
2988           gfc_add_block_to_block (pblock, &se.pre);
2989           gfc_add_modify_expr (pblock, ubound, se.expr);
2990         }
2991       /* The offset of this dimension.  offset = offset - lbound * stride.  */
2992       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
2993       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
2994
2995       /* The size of this dimension, and the stride of the next.  */
2996       if (dim + 1 < as->rank)
2997         stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
2998       else
2999         stride = NULL_TREE;
3000
3001       if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
3002         {
3003           /* Calculate stride = size * (ubound + 1 - lbound).  */
3004           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3005                              gfc_index_one_node, lbound);
3006           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
3007           tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3008           if (stride)
3009             gfc_add_modify_expr (pblock, stride, tmp);
3010           else
3011             stride = gfc_evaluate_now (tmp, pblock);
3012         }
3013
3014       size = stride;
3015     }
3016
3017   *poffset = offset;
3018   return size;
3019 }
3020
3021
3022 /* Generate code to initialize/allocate an array variable.  */
3023
3024 tree
3025 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
3026 {
3027   stmtblock_t block;
3028   tree type;
3029   tree tmp;
3030   tree fndecl;
3031   tree size;
3032   tree offset;
3033   bool onstack;
3034
3035   gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
3036
3037   /* Do nothing for USEd variables.  */
3038   if (sym->attr.use_assoc)
3039     return fnbody;
3040
3041   type = TREE_TYPE (decl);
3042   gcc_assert (GFC_ARRAY_TYPE_P (type));
3043   onstack = TREE_CODE (type) != POINTER_TYPE;
3044
3045   gfc_start_block (&block);
3046
3047   /* Evaluate character string length.  */
3048   if (sym->ts.type == BT_CHARACTER
3049       && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3050     {
3051       gfc_trans_init_string_length (sym->ts.cl, &block);
3052
3053       /* Emit a DECL_EXPR for this variable, which will cause the
3054          gimplifier to allocate storage, and all that good stuff.  */
3055       tmp = build1 (DECL_EXPR, TREE_TYPE (decl), decl);
3056       gfc_add_expr_to_block (&block, tmp);
3057     }
3058
3059   if (onstack)
3060     {
3061       gfc_add_expr_to_block (&block, fnbody);
3062       return gfc_finish_block (&block);
3063     }
3064
3065   type = TREE_TYPE (type);
3066
3067   gcc_assert (!sym->attr.use_assoc);
3068   gcc_assert (!TREE_STATIC (decl));
3069   gcc_assert (!sym->module);
3070
3071   if (sym->ts.type == BT_CHARACTER
3072       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3073     gfc_trans_init_string_length (sym->ts.cl, &block);
3074
3075   size = gfc_trans_array_bounds (type, sym, &offset, &block);
3076
3077   /* The size is the number of elements in the array, so multiply by the
3078      size of an element to get the total size.  */
3079   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3080   size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3081
3082   /* Allocate memory to hold the data.  */
3083   tmp = gfc_chainon_list (NULL_TREE, size);
3084
3085   if (gfc_index_integer_kind == 4)
3086     fndecl = gfor_fndecl_internal_malloc;
3087   else if (gfc_index_integer_kind == 8)
3088     fndecl = gfor_fndecl_internal_malloc64;
3089   else
3090     gcc_unreachable ();
3091   tmp = gfc_build_function_call (fndecl, tmp);
3092   tmp = fold (convert (TREE_TYPE (decl), tmp));
3093   gfc_add_modify_expr (&block, decl, tmp);
3094
3095   /* Set offset of the array.  */
3096   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3097     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3098
3099
3100   /* Automatic arrays should not have initializers.  */
3101   gcc_assert (!sym->value);
3102
3103   gfc_add_expr_to_block (&block, fnbody);
3104
3105   /* Free the temporary.  */
3106   tmp = convert (pvoid_type_node, decl);
3107   tmp = gfc_chainon_list (NULL_TREE, tmp);
3108   tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
3109   gfc_add_expr_to_block (&block, tmp);
3110
3111   return gfc_finish_block (&block);
3112 }
3113
3114
3115 /* Generate entry and exit code for g77 calling convention arrays.  */
3116
3117 tree
3118 gfc_trans_g77_array (gfc_symbol * sym, tree body)
3119 {
3120   tree parm;
3121   tree type;
3122   locus loc;
3123   tree offset;
3124   tree tmp;
3125   stmtblock_t block;
3126
3127   gfc_get_backend_locus (&loc);
3128   gfc_set_backend_locus (&sym->declared_at);
3129
3130   /* Descriptor type.  */
3131   parm = sym->backend_decl;
3132   type = TREE_TYPE (parm);
3133   gcc_assert (GFC_ARRAY_TYPE_P (type));
3134
3135   gfc_start_block (&block);
3136
3137   if (sym->ts.type == BT_CHARACTER
3138       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3139     gfc_trans_init_string_length (sym->ts.cl, &block);
3140
3141   /* Evaluate the bounds of the array.  */
3142   gfc_trans_array_bounds (type, sym, &offset, &block);
3143
3144   /* Set the offset.  */
3145   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3146     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3147
3148   /* Set the pointer itself if we aren't using the parameter directly.  */
3149   if (TREE_CODE (parm) != PARM_DECL)
3150     {
3151       tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
3152       gfc_add_modify_expr (&block, parm, tmp);
3153     }
3154   tmp = gfc_finish_block (&block);
3155
3156   gfc_set_backend_locus (&loc);
3157
3158   gfc_start_block (&block);
3159   /* Add the initialization code to the start of the function.  */
3160   gfc_add_expr_to_block (&block, tmp);
3161   gfc_add_expr_to_block (&block, body);
3162
3163   return gfc_finish_block (&block);
3164 }
3165
3166
3167 /* Modify the descriptor of an array parameter so that it has the
3168    correct lower bound.  Also move the upper bound accordingly.
3169    If the array is not packed, it will be copied into a temporary.
3170    For each dimension we set the new lower and upper bounds.  Then we copy the
3171    stride and calculate the offset for this dimension.  We also work out
3172    what the stride of a packed array would be, and see it the two match.
3173    If the array need repacking, we set the stride to the values we just
3174    calculated, recalculate the offset and copy the array data.
3175    Code is also added to copy the data back at the end of the function.
3176    */
3177
3178 tree
3179 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
3180 {
3181   tree size;
3182   tree type;
3183   tree offset;
3184   locus loc;
3185   stmtblock_t block;
3186   stmtblock_t cleanup;
3187   tree lbound;
3188   tree ubound;
3189   tree dubound;
3190   tree dlbound;
3191   tree dumdesc;
3192   tree tmp;
3193   tree stmt;
3194   tree stride;
3195   tree stmt_packed;
3196   tree stmt_unpacked;
3197   tree partial;
3198   gfc_se se;
3199   int n;
3200   int checkparm;
3201   int no_repack;
3202   bool optional_arg;
3203
3204   /* Do nothing for pointer and allocatable arrays.  */
3205   if (sym->attr.pointer || sym->attr.allocatable)
3206     return body;
3207
3208   if (sym->attr.dummy && gfc_is_nodesc_array (sym))
3209     return gfc_trans_g77_array (sym, body);
3210
3211   gfc_get_backend_locus (&loc);
3212   gfc_set_backend_locus (&sym->declared_at);
3213
3214   /* Descriptor type.  */
3215   type = TREE_TYPE (tmpdesc);
3216   gcc_assert (GFC_ARRAY_TYPE_P (type));
3217   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3218   dumdesc = gfc_build_indirect_ref (dumdesc);
3219   gfc_start_block (&block);
3220
3221   if (sym->ts.type == BT_CHARACTER
3222       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3223     gfc_trans_init_string_length (sym->ts.cl, &block);
3224
3225   checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
3226
3227   no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
3228                 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
3229
3230   if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
3231     {
3232       /* For non-constant shape arrays we only check if the first dimension
3233          is contiguous.  Repacking higher dimensions wouldn't gain us
3234          anything as we still don't know the array stride.  */
3235       partial = gfc_create_var (boolean_type_node, "partial");
3236       TREE_USED (partial) = 1;
3237       tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3238       tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, integer_one_node);
3239       gfc_add_modify_expr (&block, partial, tmp);
3240     }
3241   else
3242     {
3243       partial = NULL_TREE;
3244     }
3245
3246   /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
3247      here, however I think it does the right thing.  */
3248   if (no_repack)
3249     {
3250       /* Set the first stride.  */
3251       stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3252       stride = gfc_evaluate_now (stride, &block);
3253
3254       tmp = build2 (EQ_EXPR, boolean_type_node, stride, integer_zero_node);
3255       tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3256                     gfc_index_one_node, stride);
3257       stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
3258       gfc_add_modify_expr (&block, stride, tmp);
3259
3260       /* Allow the user to disable array repacking.  */
3261       stmt_unpacked = NULL_TREE;
3262     }
3263   else
3264     {
3265       gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
3266       /* A library call to repack the array if necessary.  */
3267       tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3268       tmp = gfc_chainon_list (NULL_TREE, tmp);
3269       stmt_unpacked = gfc_build_function_call (gfor_fndecl_in_pack, tmp);
3270
3271       stride = gfc_index_one_node;
3272     }
3273
3274   /* This is for the case where the array data is used directly without
3275      calling the repack function.  */
3276   if (no_repack || partial != NULL_TREE)
3277     stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
3278   else
3279     stmt_packed = NULL_TREE;
3280
3281   /* Assign the data pointer.  */
3282   if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3283     {
3284       /* Don't repack unknown shape arrays when the first stride is 1.  */
3285       tmp = build3 (COND_EXPR, TREE_TYPE (stmt_packed), partial,
3286                     stmt_packed, stmt_unpacked);
3287     }
3288   else
3289     tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
3290   gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
3291
3292   offset = gfc_index_zero_node;
3293   size = gfc_index_one_node;
3294
3295   /* Evaluate the bounds of the array.  */
3296   for (n = 0; n < sym->as->rank; n++)
3297     {
3298       if (checkparm || !sym->as->upper[n])
3299         {
3300           /* Get the bounds of the actual parameter.  */
3301           dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
3302           dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
3303         }
3304       else
3305         {
3306           dubound = NULL_TREE;
3307           dlbound = NULL_TREE;
3308         }
3309
3310       lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
3311       if (!INTEGER_CST_P (lbound))
3312         {
3313           gfc_init_se (&se, NULL);
3314           gfc_conv_expr_type (&se, sym->as->upper[n],
3315                               gfc_array_index_type);
3316           gfc_add_block_to_block (&block, &se.pre);
3317           gfc_add_modify_expr (&block, lbound, se.expr);
3318         }
3319
3320       ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
3321       /* Set the desired upper bound.  */
3322       if (sym->as->upper[n])
3323         {
3324           /* We know what we want the upper bound to be.  */
3325           if (!INTEGER_CST_P (ubound))
3326             {
3327               gfc_init_se (&se, NULL);
3328               gfc_conv_expr_type (&se, sym->as->upper[n],
3329                                   gfc_array_index_type);
3330               gfc_add_block_to_block (&block, &se.pre);
3331               gfc_add_modify_expr (&block, ubound, se.expr);
3332             }
3333
3334           /* Check the sizes match.  */
3335           if (checkparm)
3336             {
3337               /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)).  */
3338
3339               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3340                                  ubound, lbound);
3341               stride = build2 (MINUS_EXPR, gfc_array_index_type,
3342                                dubound, dlbound);
3343               tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride);
3344               gfc_trans_runtime_check (tmp, gfc_strconst_bounds, &block);
3345             }
3346         }
3347       else
3348         {
3349           /* For assumed shape arrays move the upper bound by the same amount
3350              as the lower bound.  */
3351           tmp = build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
3352           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
3353           gfc_add_modify_expr (&block, ubound, tmp);
3354         }
3355       /* The offset of this dimension.  offset = offset - lbound * stride.  */
3356       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
3357       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3358
3359       /* The size of this dimension, and the stride of the next.  */
3360       if (n + 1 < sym->as->rank)
3361         {
3362           stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
3363
3364           if (no_repack || partial != NULL_TREE)
3365             {
3366               stmt_unpacked =
3367                 gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
3368             }
3369
3370           /* Figure out the stride if not a known constant.  */
3371           if (!INTEGER_CST_P (stride))
3372             {
3373               if (no_repack)
3374                 stmt_packed = NULL_TREE;
3375               else
3376                 {
3377                   /* Calculate stride = size * (ubound + 1 - lbound).  */
3378                   tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3379                                      gfc_index_one_node, lbound);
3380                   tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3381                                      ubound, tmp);
3382                   size = fold_build2 (MULT_EXPR, gfc_array_index_type,
3383                                       size, tmp);
3384                   stmt_packed = size;
3385                 }
3386
3387               /* Assign the stride.  */
3388               if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3389                 tmp = build3 (COND_EXPR, gfc_array_index_type, partial,
3390                               stmt_unpacked, stmt_packed);
3391               else
3392                 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
3393               gfc_add_modify_expr (&block, stride, tmp);
3394             }
3395         }
3396     }
3397
3398   /* Set the offset.  */
3399   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3400     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3401
3402   stmt = gfc_finish_block (&block);
3403
3404   gfc_start_block (&block);
3405
3406   /* Only do the entry/initialization code if the arg is present.  */
3407   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3408   optional_arg = (sym->attr.optional
3409                   || (sym->ns->proc_name->attr.entry_master
3410                       && sym->attr.dummy));
3411   if (optional_arg)
3412     {
3413       tmp = gfc_conv_expr_present (sym);
3414       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3415     }
3416   gfc_add_expr_to_block (&block, stmt);
3417
3418   /* Add the main function body.  */
3419   gfc_add_expr_to_block (&block, body);
3420
3421   /* Cleanup code.  */
3422   if (!no_repack)
3423     {
3424       gfc_start_block (&cleanup);
3425       
3426       if (sym->attr.intent != INTENT_IN)
3427         {
3428           /* Copy the data back.  */
3429           tmp = gfc_chainon_list (NULL_TREE, dumdesc);
3430           tmp = gfc_chainon_list (tmp, tmpdesc);
3431           tmp = gfc_build_function_call (gfor_fndecl_in_unpack, tmp);
3432           gfc_add_expr_to_block (&cleanup, tmp);
3433         }
3434
3435       /* Free the temporary.  */
3436       tmp = gfc_chainon_list (NULL_TREE, tmpdesc);
3437       tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
3438       gfc_add_expr_to_block (&cleanup, tmp);
3439
3440       stmt = gfc_finish_block (&cleanup);
3441         
3442       /* Only do the cleanup if the array was repacked.  */
3443       tmp = gfc_build_indirect_ref (dumdesc);
3444       tmp = gfc_conv_descriptor_data_get (tmp);
3445       tmp = build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
3446       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3447
3448       if (optional_arg)
3449         {
3450           tmp = gfc_conv_expr_present (sym);
3451           stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3452         }
3453       gfc_add_expr_to_block (&block, stmt);
3454     }
3455   /* We don't need to free any memory allocated by internal_pack as it will
3456      be freed at the end of the function by pop_context.  */
3457   return gfc_finish_block (&block);
3458 }
3459
3460
3461 /* Convert an array for passing as an actual parameter.  Expressions and
3462    vector subscripts are evaluated and stored in a temporary, which is then
3463    passed.  For whole arrays the descriptor is passed.  For array sections
3464    a modified copy of the descriptor is passed, but using the original data.
3465    Also used for array pointer assignments by setting se->direct_byref.  */
3466
3467 void
3468 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
3469 {
3470   gfc_loopinfo loop;
3471   gfc_ss *secss;
3472   gfc_ss_info *info;
3473   int need_tmp;
3474   int n;
3475   tree tmp;
3476   tree desc;
3477   stmtblock_t block;
3478   tree start;
3479   tree offset;
3480   int full;
3481   gfc_ss *vss;
3482   gfc_ref *ref;
3483
3484   gcc_assert (ss != gfc_ss_terminator);
3485
3486   /* TODO: Pass constant array constructors without a temporary.  */
3487   /* Special case things we know we can pass easily.  */
3488   switch (expr->expr_type)
3489     {
3490     case EXPR_VARIABLE:
3491       /* If we have a linear array section, we can pass it directly.
3492          Otherwise we need to copy it into a temporary.  */
3493
3494       /* Find the SS for the array section.  */
3495       secss = ss;
3496       while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
3497         secss = secss->next;
3498
3499       gcc_assert (secss != gfc_ss_terminator);
3500
3501       need_tmp = 0;
3502       for (n = 0; n < secss->data.info.dimen; n++)
3503         {
3504           vss = secss->data.info.subscript[secss->data.info.dim[n]];
3505           if (vss && vss->type == GFC_SS_VECTOR)
3506             need_tmp = 1;
3507         }
3508
3509       info = &secss->data.info;
3510
3511       /* Get the descriptor for the array.  */
3512       gfc_conv_ss_descriptor (&se->pre, secss, 0);
3513       desc = info->descriptor;
3514       if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
3515         {
3516           /* Create a new descriptor if the array doesn't have one.  */
3517           full = 0;
3518         }
3519       else if (info->ref->u.ar.type == AR_FULL)
3520         full = 1;
3521       else if (se->direct_byref)
3522         full = 0;
3523       else
3524         {
3525           ref = info->ref;
3526           gcc_assert (ref->u.ar.type == AR_SECTION);
3527
3528           full = 1;
3529           for (n = 0; n < ref->u.ar.dimen; n++)
3530             {
3531               /* Detect passing the full array as a section.  This could do
3532                  even more checking, but it doesn't seem worth it.  */
3533               if (ref->u.ar.start[n]
3534                   || ref->u.ar.end[n]
3535                   || (ref->u.ar.stride[n]
3536                       && !gfc_expr_is_one (ref->u.ar.stride[n], 0)))
3537                 {
3538                   full = 0;
3539                   break;
3540                 }
3541             }
3542         }
3543
3544       /* Check for substring references.  */
3545       ref = expr->ref;
3546       if (!need_tmp && ref && expr->ts.type == BT_CHARACTER)
3547         {
3548           while (ref->next)
3549             ref = ref->next;
3550           if (ref->type == REF_SUBSTRING)
3551             {
3552               /* In general character substrings need a copy.  Character
3553                  array strides are expressed as multiples of the element
3554                  size (consistent with other array types), not in
3555                  characters.  */
3556               full = 0;
3557               need_tmp = 1;
3558             }
3559         }
3560
3561       if (full)
3562         {
3563           if (se->direct_byref)
3564             {
3565               /* Copy the descriptor for pointer assignments.  */
3566               gfc_add_modify_expr (&se->pre, se->expr, desc);
3567             }
3568           else if (se->want_pointer)
3569             {
3570               /* We pass full arrays directly.  This means that pointers and
3571                  allocatable arrays should also work.  */
3572               se->expr = gfc_build_addr_expr (NULL_TREE, desc);
3573             }
3574           else
3575             {
3576               se->expr = desc;
3577             }
3578
3579           if (expr->ts.type == BT_CHARACTER)
3580             se->string_length = gfc_get_expr_charlen (expr);
3581
3582           return;
3583         }
3584       break;
3585       
3586     case EXPR_FUNCTION:
3587       /* A transformational function return value will be a temporary
3588          array descriptor.  We still need to go through the scalarizer
3589          to create the descriptor.  Elemental functions ar handled as
3590          arbitrary expressions, i.e. copy to a temporary.  */
3591       secss = ss;
3592       /* Look for the SS for this function.  */
3593       while (secss != gfc_ss_terminator
3594              && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
3595         secss = secss->next;
3596
3597       if (se->direct_byref)
3598         {
3599           gcc_assert (secss != gfc_ss_terminator);
3600
3601           /* For pointer assignments pass the descriptor directly.  */
3602           se->ss = secss;
3603           se->expr = gfc_build_addr_expr (NULL, se->expr);
3604           gfc_conv_expr (se, expr);
3605           return;
3606         }
3607
3608       if (secss == gfc_ss_terminator)
3609         {
3610           /* Elemental function.  */
3611           need_tmp = 1;
3612           info = NULL;
3613         }
3614       else
3615         {
3616           /* Transformational function.  */
3617           info = &secss->data.info;
3618           need_tmp = 0;
3619         }
3620       break;
3621
3622     default:
3623       /* Something complicated.  Copy it into a temporary.  */
3624       need_tmp = 1;
3625       secss = NULL;
3626       info = NULL;
3627       break;
3628     }
3629
3630
3631   gfc_init_loopinfo (&loop);
3632
3633   /* Associate the SS with the loop.  */
3634   gfc_add_ss_to_loop (&loop, ss);
3635
3636   /* Tell the scalarizer not to bother creating loop variables, etc.  */
3637   if (!need_tmp)
3638     loop.array_parameter = 1;
3639   else
3640     gcc_assert (se->want_pointer && !se->direct_byref);
3641
3642   /* Setup the scalarizing loops and bounds.  */
3643   gfc_conv_ss_startstride (&loop);
3644
3645   if (need_tmp)
3646     {
3647       /* Tell the scalarizer to make a temporary.  */
3648       loop.temp_ss = gfc_get_ss ();
3649       loop.temp_ss->type = GFC_SS_TEMP;
3650       loop.temp_ss->next = gfc_ss_terminator;
3651       if (expr->ts.type == BT_CHARACTER)
3652         {
3653           gcc_assert (expr->ts.cl && expr->ts.cl->length
3654                       && expr->ts.cl->length->expr_type == EXPR_CONSTANT);
3655           loop.temp_ss->string_length = gfc_conv_mpz_to_tree
3656                         (expr->ts.cl->length->value.integer,
3657                          expr->ts.cl->length->ts.kind);
3658           expr->ts.cl->backend_decl = loop.temp_ss->string_length;
3659         }
3660         loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
3661
3662       /* ... which can hold our string, if present.  */
3663       if (expr->ts.type == BT_CHARACTER)
3664         {
3665           loop.temp_ss->string_length = TYPE_SIZE_UNIT (loop.temp_ss->data.temp.type);
3666           se->string_length = loop.temp_ss->string_length;
3667         }
3668       else
3669         loop.temp_ss->string_length = NULL;
3670       loop.temp_ss->data.temp.dimen = loop.dimen;
3671       gfc_add_ss_to_loop (&loop, loop.temp_ss);
3672     }
3673
3674   gfc_conv_loop_setup (&loop);
3675
3676   if (need_tmp)
3677     {
3678       /* Copy into a temporary and pass that.  We don't need to copy the data
3679          back because expressions and vector subscripts must be INTENT_IN.  */
3680       /* TODO: Optimize passing function return values.  */
3681       gfc_se lse;
3682       gfc_se rse;
3683
3684       /* Start the copying loops.  */
3685       gfc_mark_ss_chain_used (loop.temp_ss, 1);
3686       gfc_mark_ss_chain_used (ss, 1);
3687       gfc_start_scalarized_body (&loop, &block);
3688
3689       /* Copy each data element.  */
3690       gfc_init_se (&lse, NULL);
3691       gfc_copy_loopinfo_to_se (&lse, &loop);
3692       gfc_init_se (&rse, NULL);
3693       gfc_copy_loopinfo_to_se (&rse, &loop);
3694
3695       lse.ss = loop.temp_ss;
3696       rse.ss = ss;
3697
3698       gfc_conv_scalarized_array_ref (&lse, NULL);
3699       if (expr->ts.type == BT_CHARACTER)
3700         {
3701           gfc_conv_expr (&rse, expr);
3702           rse.expr = gfc_build_indirect_ref (rse.expr);
3703         }
3704       else
3705         gfc_conv_expr_val (&rse, expr);
3706
3707       gfc_add_block_to_block (&block, &rse.pre);
3708       gfc_add_block_to_block (&block, &lse.pre);
3709
3710       gfc_add_modify_expr (&block, lse.expr, rse.expr);
3711
3712       /* Finish the copying loops.  */
3713       gfc_trans_scalarizing_loops (&loop, &block);
3714
3715       /* Set the first stride component to zero to indicate a temporary.  */
3716       desc = loop.temp_ss->data.info.descriptor;
3717       tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[0]);
3718       gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
3719
3720       gcc_assert (is_gimple_lvalue (desc));
3721       se->expr = gfc_build_addr_expr (NULL, desc);
3722     }
3723   else if (expr->expr_type == EXPR_FUNCTION)
3724     {
3725       desc = info->descriptor;
3726
3727       if (se->want_pointer)
3728         se->expr = gfc_build_addr_expr (NULL_TREE, desc);
3729       else
3730         se->expr = desc;
3731
3732       if (expr->ts.type == BT_CHARACTER)
3733         se->string_length = expr->symtree->n.sym->ts.cl->backend_decl;
3734     }
3735   else
3736     {
3737       /* We pass sections without copying to a temporary.  Make a new
3738          descriptor and point it at the section we want.  The loop variable
3739          limits will be the limits of the section.
3740          A function may decide to repack the array to speed up access, but
3741          we're not bothered about that here.  */
3742       int dim;
3743       tree parm;
3744       tree parmtype;
3745       tree stride;
3746       tree from;
3747       tree to;
3748       tree base;
3749
3750       /* Set the string_length for a character array.  */
3751       if (expr->ts.type == BT_CHARACTER)
3752         se->string_length =  gfc_get_expr_charlen (expr);
3753
3754       desc = info->descriptor;
3755       gcc_assert (secss && secss != gfc_ss_terminator);
3756       if (se->direct_byref)
3757         {
3758           /* For pointer assignments we fill in the destination.  */
3759           parm = se->expr;
3760           parmtype = TREE_TYPE (parm);
3761         }
3762       else
3763         {
3764           /* Otherwise make a new one.  */
3765           parmtype = gfc_get_element_type (TREE_TYPE (desc));
3766           parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
3767                                                 loop.from, loop.to, 0);
3768           parm = gfc_create_var (parmtype, "parm");
3769         }
3770
3771       offset = gfc_index_zero_node;
3772       dim = 0;
3773
3774       /* The following can be somewhat confusing.  We have two
3775          descriptors, a new one and the original array.
3776          {parm, parmtype, dim} refer to the new one.
3777          {desc, type, n, secss, loop} refer to the original, which maybe
3778          a descriptorless array.
3779          The bounds of the scalarization are the bounds of the section.
3780          We don't have to worry about numeric overflows when calculating
3781          the offsets because all elements are within the array data.  */
3782
3783       /* Set the dtype.  */
3784       tmp = gfc_conv_descriptor_dtype (parm);
3785       gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
3786
3787       if (se->direct_byref)
3788         base = gfc_index_zero_node;
3789       else
3790         base = NULL_TREE;
3791
3792       for (n = 0; n < info->ref->u.ar.dimen; n++)
3793         {
3794           stride = gfc_conv_array_stride (desc, n);
3795
3796           /* Work out the offset.  */
3797           if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
3798             {
3799               gcc_assert (info->subscript[n]
3800                       && info->subscript[n]->type == GFC_SS_SCALAR);
3801               start = info->subscript[n]->data.scalar.expr;
3802             }
3803           else
3804             {
3805               /* Check we haven't somehow got out of sync.  */
3806               gcc_assert (info->dim[dim] == n);
3807
3808               /* Evaluate and remember the start of the section.  */
3809               start = info->start[dim];
3810               stride = gfc_evaluate_now (stride, &loop.pre);
3811             }
3812
3813           tmp = gfc_conv_array_lbound (desc, n);
3814           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
3815
3816           tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
3817           offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
3818
3819           if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
3820             {
3821               /* For elemental dimensions, we only need the offset.  */
3822               continue;
3823             }
3824
3825           /* Vector subscripts need copying and are handled elsewhere.  */
3826           gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
3827
3828           /* Set the new lower bound.  */
3829           from = loop.from[dim];
3830           to = loop.to[dim];
3831           if (!integer_onep (from))
3832             {
3833               /* Make sure the new section starts at 1.  */
3834               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3835                                  gfc_index_one_node, from);
3836               to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
3837               from = gfc_index_one_node;
3838             }
3839           tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
3840           gfc_add_modify_expr (&loop.pre, tmp, from);
3841
3842           /* Set the new upper bound.  */
3843           tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
3844           gfc_add_modify_expr (&loop.pre, tmp, to);
3845
3846           /* Multiply the stride by the section stride to get the
3847              total stride.  */
3848           stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
3849                                 stride, info->stride[dim]);
3850
3851           if (se->direct_byref)
3852             base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
3853                                 base, stride);
3854
3855           /* Store the new stride.  */
3856           tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
3857           gfc_add_modify_expr (&loop.pre, tmp, stride);
3858
3859           dim++;
3860         }
3861
3862       /* Point the data pointer at the first element in the section.  */
3863       tmp = gfc_conv_array_data (desc);
3864       tmp = gfc_build_indirect_ref (tmp);
3865       tmp = gfc_build_array_ref (tmp, offset);
3866       offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
3867       gfc_conv_descriptor_data_set (&loop.pre, parm, offset);
3868
3869       if (se->direct_byref)
3870         {
3871           /* Set the offset.  */
3872           tmp = gfc_conv_descriptor_offset (parm);
3873           gfc_add_modify_expr (&loop.pre, tmp, base);
3874         }
3875       else
3876         {
3877           /* Only the callee knows what the correct offset it, so just set
3878              it to zero here.  */
3879           tmp = gfc_conv_descriptor_offset (parm);
3880           gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
3881         }
3882
3883       if (!se->direct_byref)
3884         {
3885           /* Get a pointer to the new descriptor.  */
3886           if (se->want_pointer)
3887             se->expr = gfc_build_addr_expr (NULL, parm);
3888           else
3889             se->expr = parm;
3890         }
3891     }
3892
3893   gfc_add_block_to_block (&se->pre, &loop.pre);
3894   gfc_add_block_to_block (&se->post, &loop.post);
3895
3896   /* Cleanup the scalarizer.  */
3897   gfc_cleanup_loop (&loop);
3898 }
3899
3900
3901 /* Convert an array for passing as an actual parameter.  */
3902 /* TODO: Optimize passing g77 arrays.  */
3903
3904 void
3905 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
3906 {
3907   tree ptr;
3908   tree desc;
3909   tree tmp;
3910   tree stmt;
3911   gfc_symbol *sym;
3912   stmtblock_t block;
3913
3914   /* Passing address of the array if it is not pointer or assumed-shape.  */
3915   if (expr->expr_type == EXPR_VARIABLE
3916        && expr->ref->u.ar.type == AR_FULL && g77)
3917     {
3918       sym = expr->symtree->n.sym;
3919       tmp = gfc_get_symbol_decl (sym);
3920       if (sym->ts.type == BT_CHARACTER)
3921         se->string_length = sym->ts.cl->backend_decl;
3922       if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE 
3923           && !sym->attr.allocatable)
3924         {
3925           /* Some variables are declared directly, others are declared as
3926              pointers and allocated on the heap.  */
3927           if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
3928             se->expr = tmp;
3929           else
3930             se->expr = gfc_build_addr_expr (NULL, tmp);
3931           return;
3932         }
3933       if (sym->attr.allocatable)
3934         {
3935           se->expr = gfc_conv_array_data (tmp);
3936           return;
3937         }
3938     }
3939
3940   se->want_pointer = 1;
3941   gfc_conv_expr_descriptor (se, expr, ss);
3942
3943   if (g77)
3944     {
3945       desc = se->expr;
3946       /* Repack the array.  */
3947       tmp = gfc_chainon_list (NULL_TREE, desc);
3948       ptr = gfc_build_function_call (gfor_fndecl_in_pack, tmp);
3949       ptr = gfc_evaluate_now (ptr, &se->pre);
3950       se->expr = ptr;
3951
3952       gfc_start_block (&block);
3953
3954       /* Copy the data back.  */
3955       tmp = gfc_chainon_list (NULL_TREE, desc);
3956       tmp = gfc_chainon_list (tmp, ptr);
3957       tmp = gfc_build_function_call (gfor_fndecl_in_unpack, tmp);
3958       gfc_add_expr_to_block (&block, tmp);
3959
3960       /* Free the temporary.  */
3961       tmp = convert (pvoid_type_node, ptr);
3962       tmp = gfc_chainon_list (NULL_TREE, tmp);
3963       tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
3964       gfc_add_expr_to_block (&block, tmp);
3965
3966       stmt = gfc_finish_block (&block);
3967
3968       gfc_init_block (&block);
3969       /* Only if it was repacked.  This code needs to be executed before the
3970          loop cleanup code.  */
3971       tmp = gfc_build_indirect_ref (desc);
3972       tmp = gfc_conv_array_data (tmp);
3973       tmp = build2 (NE_EXPR, boolean_type_node, ptr, tmp);
3974       tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3975
3976       gfc_add_expr_to_block (&block, tmp);
3977       gfc_add_block_to_block (&block, &se->post);
3978
3979       gfc_init_block (&se->post);
3980       gfc_add_block_to_block (&se->post, &block);
3981     }
3982 }
3983
3984
3985 /* NULLIFY an allocated/pointer array on function entry, free it on exit.  */
3986
3987 tree
3988 gfc_trans_deferred_array (gfc_symbol * sym, tree body)
3989 {
3990   tree type;
3991   tree tmp;
3992   tree descriptor;
3993   tree deallocate;
3994   stmtblock_t block;
3995   stmtblock_t fnblock;
3996   locus loc;
3997
3998   /* Make sure the frontend gets these right.  */
3999   if (!(sym->attr.pointer || sym->attr.allocatable))
4000     fatal_error
4001       ("Possible frontend bug: Deferred array size without pointer or allocatable attribute.");
4002
4003   gfc_init_block (&fnblock);
4004
4005   gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL);
4006   if (sym->ts.type == BT_CHARACTER
4007       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
4008     gfc_trans_init_string_length (sym->ts.cl, &fnblock);
4009
4010   /* Parameter and use associated variables don't need anything special.  */
4011   if (sym->attr.dummy || sym->attr.use_assoc)
4012     {
4013       gfc_add_expr_to_block (&fnblock, body);
4014
4015       return gfc_finish_block (&fnblock);
4016     }
4017
4018   gfc_get_backend_locus (&loc);
4019   gfc_set_backend_locus (&sym->declared_at);
4020   descriptor = sym->backend_decl;
4021
4022   if (TREE_STATIC (descriptor))
4023     {
4024       /* SAVEd variables are not freed on exit.  */
4025       gfc_trans_static_array_pointer (sym);
4026       return body;
4027     }
4028
4029   /* Get the descriptor type.  */
4030   type = TREE_TYPE (sym->backend_decl);
4031   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
4032
4033   /* NULLIFY the data pointer.  */
4034   gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node);
4035
4036   gfc_add_expr_to_block (&fnblock, body);
4037
4038   gfc_set_backend_locus (&loc);
4039   /* Allocatable arrays need to be freed when they go out of scope.  */
4040   if (sym->attr.allocatable)
4041     {
4042       gfc_start_block (&block);
4043
4044       /* Deallocate if still allocated at the end of the procedure.  */
4045       deallocate = gfc_array_deallocate (descriptor, null_pointer_node);
4046
4047       tmp = gfc_conv_descriptor_data_get (descriptor);
4048       tmp = build2 (NE_EXPR, boolean_type_node, tmp, 
4049                     build_int_cst (TREE_TYPE (tmp), 0));
4050       tmp = build3_v (COND_EXPR, tmp, deallocate, build_empty_stmt ());
4051       gfc_add_expr_to_block (&block, tmp);
4052
4053       tmp = gfc_finish_block (&block);
4054       gfc_add_expr_to_block (&fnblock, tmp);
4055     }
4056
4057   return gfc_finish_block (&fnblock);
4058 }
4059
4060 /************ Expression Walking Functions ******************/
4061
4062 /* Walk a variable reference.
4063
4064    Possible extension - multiple component subscripts.
4065     x(:,:) = foo%a(:)%b(:)
4066    Transforms to
4067     forall (i=..., j=...)
4068       x(i,j) = foo%a(j)%b(i)
4069     end forall
4070    This adds a fair amout of complexity because you need to deal with more
4071    than one ref.  Maybe handle in a similar manner to vector subscripts.
4072    Maybe not worth the effort.  */
4073
4074
4075 static gfc_ss *
4076 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
4077 {
4078   gfc_ref *ref;
4079   gfc_array_ref *ar;
4080   gfc_ss *newss;
4081   gfc_ss *head;
4082   int n;
4083
4084   for (ref = expr->ref; ref; ref = ref->next)
4085     {
4086       /* We're only interested in array sections.  */
4087       if (ref->type != REF_ARRAY)
4088         continue;
4089
4090       ar = &ref->u.ar;
4091       switch (ar->type)
4092         {
4093         case AR_ELEMENT:
4094           /* TODO: Take elemental array references out of scalarization
4095              loop.  */
4096           break;
4097
4098         case AR_FULL:
4099           newss = gfc_get_ss ();
4100           newss->type = GFC_SS_SECTION;
4101           newss->expr = expr;
4102           newss->next = ss;
4103           newss->data.info.dimen = ar->as->rank;
4104           newss->data.info.ref = ref;
4105
4106           /* Make sure array is the same as array(:,:), this way
4107              we don't need to special case all the time.  */
4108           ar->dimen = ar->as->rank;
4109           for (n = 0; n < ar->dimen; n++)
4110             {
4111               newss->data.info.dim[n] = n;
4112               ar->dimen_type[n] = DIMEN_RANGE;
4113
4114               gcc_assert (ar->start[n] == NULL);
4115               gcc_assert (ar->end[n] == NULL);
4116               gcc_assert (ar->stride[n] == NULL);
4117             }
4118           return newss;
4119
4120         case AR_SECTION:
4121           newss = gfc_get_ss ();
4122           newss->type = GFC_SS_SECTION;
4123           newss->expr = expr;
4124           newss->next = ss;
4125           newss->data.info.dimen = 0;
4126           newss->data.info.ref = ref;
4127
4128           head = newss;
4129
4130           /* We add SS chains for all the subscripts in the section.  */
4131           for (n = 0; n < ar->dimen; n++)
4132             {
4133               gfc_ss *indexss;
4134
4135               switch (ar->dimen_type[n])
4136                 {
4137                 case DIMEN_ELEMENT:
4138                   /* Add SS for elemental (scalar) subscripts.  */
4139                   gcc_assert (ar->start[n]);
4140                   indexss = gfc_get_ss ();
4141                   indexss->type = GFC_SS_SCALAR;
4142                   indexss->expr = ar->start[n];
4143                   indexss->next = gfc_ss_terminator;
4144                   indexss->loop_chain = gfc_ss_terminator;
4145                   newss->data.info.subscript[n] = indexss;
4146                   break;
4147
4148                 case DIMEN_RANGE:
4149                   /* We don't add anything for sections, just remember this
4150                      dimension for later.  */
4151                   newss->data.info.dim[newss->data.info.dimen] = n;
4152                   newss->data.info.dimen++;
4153                   break;
4154
4155                 case DIMEN_VECTOR:
4156                   /* Get a SS for the vector.  This will not be added to the
4157                      chain directly.  */
4158                   indexss = gfc_walk_expr (ar->start[n]);
4159                   if (indexss == gfc_ss_terminator)
4160                     internal_error ("scalar vector subscript???");
4161
4162                   /* We currently only handle really simple vector
4163                      subscripts.  */
4164                   if (indexss->next != gfc_ss_terminator)
4165                     gfc_todo_error ("vector subscript expressions");
4166                   indexss->loop_chain = gfc_ss_terminator;
4167
4168                   /* Mark this as a vector subscript.  We don't add this
4169                      directly into the chain, but as a subscript of the
4170                      existing SS for this term.  */
4171                   indexss->type = GFC_SS_VECTOR;
4172                   newss->data.info.subscript[n] = indexss;
4173                   /* Also remember this dimension.  */
4174                   newss->data.info.dim[newss->data.info.dimen] = n;
4175                   newss->data.info.dimen++;
4176                   break;
4177
4178                 default:
4179                   /* We should know what sort of section it is by now.  */
4180                   gcc_unreachable ();
4181                 }
4182             }
4183           /* We should have at least one non-elemental dimension.  */
4184           gcc_assert (newss->data.info.dimen > 0);
4185           return head;
4186           break;
4187
4188         default:
4189           /* We should know what sort of section it is by now.  */
4190           gcc_unreachable ();
4191         }
4192
4193     }
4194   return ss;
4195 }
4196
4197
4198 /* Walk an expression operator. If only one operand of a binary expression is
4199    scalar, we must also add the scalar term to the SS chain.  */
4200
4201 static gfc_ss *
4202 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
4203 {
4204   gfc_ss *head;
4205   gfc_ss *head2;
4206   gfc_ss *newss;
4207
4208   head = gfc_walk_subexpr (ss, expr->value.op.op1);
4209   if (expr->value.op.op2 == NULL)
4210     head2 = head;
4211   else
4212     head2 = gfc_walk_subexpr (head, expr->value.op.op2);
4213
4214   /* All operands are scalar.  Pass back and let the caller deal with it.  */
4215   if (head2 == ss)
4216     return head2;
4217
4218   /* All operands require scalarization.  */
4219   if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
4220     return head2;
4221
4222   /* One of the operands needs scalarization, the other is scalar.
4223      Create a gfc_ss for the scalar expression.  */
4224   newss = gfc_get_ss ();
4225   newss->type = GFC_SS_SCALAR;
4226   if (head == ss)
4227     {
4228       /* First operand is scalar.  We build the chain in reverse order, so
4229          add the scarar SS after the second operand.  */
4230       head = head2;
4231       while (head && head->next != ss)
4232         head = head->next;
4233       /* Check we haven't somehow broken the chain.  */
4234       gcc_assert (head);
4235       newss->next = ss;
4236       head->next = newss;
4237       newss->expr = expr->value.op.op1;
4238     }
4239   else                          /* head2 == head */
4240     {
4241       gcc_assert (head2 == head);
4242       /* Second operand is scalar.  */
4243       newss->next = head2;
4244       head2 = newss;
4245       newss->expr = expr->value.op.op2;
4246     }
4247
4248   return head2;
4249 }
4250
4251
4252 /* Reverse a SS chain.  */
4253
4254 static gfc_ss *
4255 gfc_reverse_ss (gfc_ss * ss)
4256 {
4257   gfc_ss *next;
4258   gfc_ss *head;
4259
4260   gcc_assert (ss != NULL);
4261
4262   head = gfc_ss_terminator;
4263   while (ss != gfc_ss_terminator)
4264     {
4265       next = ss->next;
4266       /* Check we didn't somehow break the chain.  */
4267       gcc_assert (next != NULL);
4268       ss->next = head;
4269       head = ss;
4270       ss = next;
4271     }
4272
4273   return (head);
4274 }
4275
4276
4277 /* Walk the arguments of an elemental function.  */
4278
4279 gfc_ss *
4280 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_expr * expr,
4281                                   gfc_ss_type type)
4282 {
4283   gfc_actual_arglist *arg;
4284   int scalar;
4285   gfc_ss *head;
4286   gfc_ss *tail;
4287   gfc_ss *newss;
4288
4289   head = gfc_ss_terminator;
4290   tail = NULL;
4291   scalar = 1;
4292   for (arg = expr->value.function.actual; arg; arg = arg->next)
4293     {
4294       if (!arg->expr)
4295         continue;
4296
4297       newss = gfc_walk_subexpr (head, arg->expr);
4298       if (newss == head)
4299         {
4300           /* Scalar argument.  */
4301           newss = gfc_get_ss ();
4302           newss->type = type;
4303           newss->expr = arg->expr;
4304           newss->next = head;
4305         }
4306       else
4307         scalar = 0;
4308
4309       head = newss;
4310       if (!tail)
4311         {
4312           tail = head;
4313           while (tail->next != gfc_ss_terminator)
4314             tail = tail->next;
4315         }
4316     }
4317
4318   if (scalar)
4319     {
4320       /* If all the arguments are scalar we don't need the argument SS.  */
4321       gfc_free_ss_chain (head);
4322       /* Pass it back.  */
4323       return ss;
4324     }
4325
4326   /* Add it onto the existing chain.  */
4327   tail->next = ss;
4328   return head;
4329 }
4330
4331
4332 /* Walk a function call.  Scalar functions are passed back, and taken out of
4333    scalarization loops.  For elemental functions we walk their arguments.
4334    The result of functions returning arrays is stored in a temporary outside
4335    the loop, so that the function is only called once.  Hence we do not need
4336    to walk their arguments.  */
4337
4338 static gfc_ss *
4339 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
4340 {
4341   gfc_ss *newss;
4342   gfc_intrinsic_sym *isym;
4343   gfc_symbol *sym;
4344
4345   isym = expr->value.function.isym;
4346
4347   /* Handle intrinsic functions separately.  */
4348   if (isym)
4349     return gfc_walk_intrinsic_function (ss, expr, isym);
4350
4351   sym = expr->value.function.esym;
4352   if (!sym)
4353       sym = expr->symtree->n.sym;
4354
4355   /* A function that returns arrays.  */
4356   if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
4357     {
4358       newss = gfc_get_ss ();
4359       newss->type = GFC_SS_FUNCTION;
4360       newss->expr = expr;
4361       newss->next = ss;
4362       newss->data.info.dimen = expr->rank;
4363       return newss;
4364     }
4365
4366   /* Walk the parameters of an elemental function.  For now we always pass
4367      by reference.  */
4368   if (sym->attr.elemental)
4369     return gfc_walk_elemental_function_args (ss, expr, GFC_SS_REFERENCE);
4370
4371   /* Scalar functions are OK as these are evaluated outside the scalarization
4372      loop.  Pass back and let the caller deal with it.  */
4373   return ss;
4374 }
4375
4376
4377 /* An array temporary is constructed for array constructors.  */
4378
4379 static gfc_ss *
4380 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
4381 {
4382   gfc_ss *newss;
4383   int n;
4384
4385   newss = gfc_get_ss ();
4386   newss->type = GFC_SS_CONSTRUCTOR;
4387   newss->expr = expr;
4388   newss->next = ss;
4389   newss->data.info.dimen = expr->rank;
4390   for (n = 0; n < expr->rank; n++)
4391     newss->data.info.dim[n] = n;
4392
4393   return newss;
4394 }
4395
4396
4397 /* Walk an expression.  Add walked expressions to the head of the SS chain.
4398    A wholly scalar expression will not be added.  */
4399
4400 static gfc_ss *
4401 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
4402 {
4403   gfc_ss *head;
4404
4405   switch (expr->expr_type)
4406     {
4407     case EXPR_VARIABLE:
4408       head = gfc_walk_variable_expr (ss, expr);
4409       return head;
4410
4411     case EXPR_OP:
4412       head = gfc_walk_op_expr (ss, expr);
4413       return head;
4414
4415     case EXPR_FUNCTION:
4416       head = gfc_walk_function_expr (ss, expr);
4417       return head;
4418
4419     case EXPR_CONSTANT:
4420     case EXPR_NULL:
4421     case EXPR_STRUCTURE:
4422       /* Pass back and let the caller deal with it.  */
4423       break;
4424
4425     case EXPR_ARRAY:
4426       head = gfc_walk_array_constructor (ss, expr);
4427       return head;
4428
4429     case EXPR_SUBSTRING:
4430       /* Pass back and let the caller deal with it.  */
4431       break;
4432
4433     default:
4434       internal_error ("bad expression type during walk (%d)",
4435                       expr->expr_type);
4436     }
4437   return ss;
4438 }
4439
4440
4441 /* Entry point for expression walking.
4442    A return value equal to the passed chain means this is
4443    a scalar expression.  It is up to the caller to take whatever action is
4444    necessary to translate these.  */
4445
4446 gfc_ss *
4447 gfc_walk_expr (gfc_expr * expr)
4448 {
4449   gfc_ss *res;
4450
4451   res = gfc_walk_subexpr (gfc_ss_terminator, expr);
4452   return gfc_reverse_ss (res);
4453 }
4454