OSDN Git Service

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