OSDN Git Service

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