OSDN Git Service

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