OSDN Git Service

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