xref: /netbsd-src/external/gpl3/gcc/dist/gcc/fortran/trans-array.cc (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1 /* Array translation routines
2    Copyright (C) 2002-2022 Free Software Foundation, Inc.
3    Contributed by Paul Brook <paul@nowt.org>
4    and Steven Bosscher <s.bosscher@student.tudelft.nl>
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21 
22 /* trans-array.cc-- Various array related code, including scalarization,
23                    allocation, initialization and other support routines.  */
24 
25 /* How the scalarizer works.
26    In gfortran, array expressions use the same core routines as scalar
27    expressions.
28    First, a Scalarization State (SS) chain is built.  This is done by walking
29    the expression tree, and building a linear list of the terms in the
30    expression.  As the tree is walked, scalar subexpressions are translated.
31 
32    The scalarization parameters are stored in a gfc_loopinfo structure.
33    First the start and stride of each term is calculated by
34    gfc_conv_ss_startstride.  During this process the expressions for the array
35    descriptors and data pointers are also translated.
36 
37    If the expression is an assignment, we must then resolve any dependencies.
38    In Fortran all the rhs values of an assignment must be evaluated before
39    any assignments take place.  This can require a temporary array to store the
40    values.  We also require a temporary when we are passing array expressions
41    or vector subscripts as procedure parameters.
42 
43    Array sections are passed without copying to a temporary.  These use the
44    scalarizer to determine the shape of the section.  The flag
45    loop->array_parameter tells the scalarizer that the actual values and loop
46    variables will not be required.
47 
48    The function gfc_conv_loop_setup generates the scalarization setup code.
49    It determines the range of the scalarizing loop variables.  If a temporary
50    is required, this is created and initialized.  Code for scalar expressions
51    taken outside the loop is also generated at this time.  Next the offset and
52    scaling required to translate from loop variables to array indices for each
53    term is calculated.
54 
55    A call to gfc_start_scalarized_body marks the start of the scalarized
56    expression.  This creates a scope and declares the loop variables.  Before
57    calling this gfc_make_ss_chain_used must be used to indicate which terms
58    will be used inside this loop.
59 
60    The scalar gfc_conv_* functions are then used to build the main body of the
61    scalarization loop.  Scalarization loop variables and precalculated scalar
62    values are automatically substituted.  Note that gfc_advance_se_ss_chain
63    must be used, rather than changing the se->ss directly.
64 
65    For assignment expressions requiring a temporary two sub loops are
66    generated.  The first stores the result of the expression in the temporary,
67    the second copies it to the result.  A call to
68    gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
69    the start of the copying loop.  The temporary may be less than full rank.
70 
71    Finally gfc_trans_scalarizing_loops is called to generate the implicit do
72    loops.  The loops are added to the pre chain of the loopinfo.  The post
73    chain may still contain cleanup code.
74 
75    After the loop code has been added into its parent scope gfc_cleanup_loop
76    is called to free all the SS allocated by the scalarizer.  */
77 
78 #include "config.h"
79 #include "system.h"
80 #include "coretypes.h"
81 #include "options.h"
82 #include "tree.h"
83 #include "gfortran.h"
84 #include "gimple-expr.h"
85 #include "trans.h"
86 #include "fold-const.h"
87 #include "constructor.h"
88 #include "trans-types.h"
89 #include "trans-array.h"
90 #include "trans-const.h"
91 #include "dependency.h"
92 
93 static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor_base);
94 
95 /* The contents of this structure aren't actually used, just the address.  */
96 static gfc_ss gfc_ss_terminator_var;
97 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
98 
99 
100 static tree
gfc_array_dataptr_type(tree desc)101 gfc_array_dataptr_type (tree desc)
102 {
103   return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
104 }
105 
106 /* Build expressions to access members of the CFI descriptor.  */
107 #define CFI_FIELD_BASE_ADDR 0
108 #define CFI_FIELD_ELEM_LEN 1
109 #define CFI_FIELD_VERSION 2
110 #define CFI_FIELD_RANK 3
111 #define CFI_FIELD_ATTRIBUTE 4
112 #define CFI_FIELD_TYPE 5
113 #define CFI_FIELD_DIM 6
114 
115 #define CFI_DIM_FIELD_LOWER_BOUND 0
116 #define CFI_DIM_FIELD_EXTENT 1
117 #define CFI_DIM_FIELD_SM 2
118 
119 static tree
gfc_get_cfi_descriptor_field(tree desc,unsigned field_idx)120 gfc_get_cfi_descriptor_field (tree desc, unsigned field_idx)
121 {
122   tree type = TREE_TYPE (desc);
123   gcc_assert (TREE_CODE (type) == RECORD_TYPE
124 	      && TYPE_FIELDS (type)
125 	      && (strcmp ("base_addr",
126 			 IDENTIFIER_POINTER (DECL_NAME (TYPE_FIELDS (type))))
127 		  == 0));
128   tree field = gfc_advance_chain (TYPE_FIELDS (type), field_idx);
129   gcc_assert (field != NULL_TREE);
130 
131   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
132 			  desc, field, NULL_TREE);
133 }
134 
135 tree
gfc_get_cfi_desc_base_addr(tree desc)136 gfc_get_cfi_desc_base_addr (tree desc)
137 {
138   return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_BASE_ADDR);
139 }
140 
141 tree
gfc_get_cfi_desc_elem_len(tree desc)142 gfc_get_cfi_desc_elem_len (tree desc)
143 {
144   return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_ELEM_LEN);
145 }
146 
147 tree
gfc_get_cfi_desc_version(tree desc)148 gfc_get_cfi_desc_version (tree desc)
149 {
150   return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_VERSION);
151 }
152 
153 tree
gfc_get_cfi_desc_rank(tree desc)154 gfc_get_cfi_desc_rank (tree desc)
155 {
156   return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_RANK);
157 }
158 
159 tree
gfc_get_cfi_desc_type(tree desc)160 gfc_get_cfi_desc_type (tree desc)
161 {
162   return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_TYPE);
163 }
164 
165 tree
gfc_get_cfi_desc_attribute(tree desc)166 gfc_get_cfi_desc_attribute (tree desc)
167 {
168   return gfc_get_cfi_descriptor_field (desc, CFI_FIELD_ATTRIBUTE);
169 }
170 
171 static tree
gfc_get_cfi_dim_item(tree desc,tree idx,unsigned field_idx)172 gfc_get_cfi_dim_item (tree desc, tree idx, unsigned field_idx)
173 {
174   tree tmp = gfc_get_cfi_descriptor_field (desc, CFI_FIELD_DIM);
175   tmp = gfc_build_array_ref (tmp, idx, NULL_TREE, true);
176   tree field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), field_idx);
177   gcc_assert (field != NULL_TREE);
178   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
179 			  tmp, field, NULL_TREE);
180 }
181 
182 tree
gfc_get_cfi_dim_lbound(tree desc,tree idx)183 gfc_get_cfi_dim_lbound (tree desc, tree idx)
184 {
185   return gfc_get_cfi_dim_item (desc, idx, CFI_DIM_FIELD_LOWER_BOUND);
186 }
187 
188 tree
gfc_get_cfi_dim_extent(tree desc,tree idx)189 gfc_get_cfi_dim_extent (tree desc, tree idx)
190 {
191   return gfc_get_cfi_dim_item (desc, idx, CFI_DIM_FIELD_EXTENT);
192 }
193 
194 tree
gfc_get_cfi_dim_sm(tree desc,tree idx)195 gfc_get_cfi_dim_sm (tree desc, tree idx)
196 {
197   return gfc_get_cfi_dim_item (desc, idx, CFI_DIM_FIELD_SM);
198 }
199 
200 #undef CFI_FIELD_BASE_ADDR
201 #undef CFI_FIELD_ELEM_LEN
202 #undef CFI_FIELD_VERSION
203 #undef CFI_FIELD_RANK
204 #undef CFI_FIELD_ATTRIBUTE
205 #undef CFI_FIELD_TYPE
206 #undef CFI_FIELD_DIM
207 
208 #undef CFI_DIM_FIELD_LOWER_BOUND
209 #undef CFI_DIM_FIELD_EXTENT
210 #undef CFI_DIM_FIELD_SM
211 
212 /* Build expressions to access the members of an array descriptor.
213    It's surprisingly easy to mess up here, so never access
214    an array descriptor by "brute force", always use these
215    functions.  This also avoids problems if we change the format
216    of an array descriptor.
217 
218    To understand these magic numbers, look at the comments
219    before gfc_build_array_type() in trans-types.cc.
220 
221    The code within these defines should be the only code which knows the format
222    of an array descriptor.
223 
224    Any code just needing to read obtain the bounds of an array should use
225    gfc_conv_array_* rather than the following functions as these will return
226    know constant values, and work with arrays which do not have descriptors.
227 
228    Don't forget to #undef these!  */
229 
230 #define DATA_FIELD 0
231 #define OFFSET_FIELD 1
232 #define DTYPE_FIELD 2
233 #define SPAN_FIELD 3
234 #define DIMENSION_FIELD 4
235 #define CAF_TOKEN_FIELD 5
236 
237 #define STRIDE_SUBFIELD 0
238 #define LBOUND_SUBFIELD 1
239 #define UBOUND_SUBFIELD 2
240 
241 static tree
gfc_get_descriptor_field(tree desc,unsigned field_idx)242 gfc_get_descriptor_field (tree desc, unsigned field_idx)
243 {
244   tree type = TREE_TYPE (desc);
245   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
246 
247   tree field = gfc_advance_chain (TYPE_FIELDS (type), field_idx);
248   gcc_assert (field != NULL_TREE);
249 
250   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
251 			  desc, field, NULL_TREE);
252 }
253 
254 /* This provides READ-ONLY access to the data field.  The field itself
255    doesn't have the proper type.  */
256 
257 tree
gfc_conv_descriptor_data_get(tree desc)258 gfc_conv_descriptor_data_get (tree desc)
259 {
260   tree type = TREE_TYPE (desc);
261   if (TREE_CODE (type) == REFERENCE_TYPE)
262     gcc_unreachable ();
263 
264   tree field = gfc_get_descriptor_field (desc, DATA_FIELD);
265   return fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), field);
266 }
267 
268 /* This provides WRITE access to the data field.
269 
270    TUPLES_P is true if we are generating tuples.
271 
272    This function gets called through the following macros:
273      gfc_conv_descriptor_data_set
274      gfc_conv_descriptor_data_set.  */
275 
276 void
gfc_conv_descriptor_data_set(stmtblock_t * block,tree desc,tree value)277 gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
278 {
279   tree field = gfc_get_descriptor_field (desc, DATA_FIELD);
280   gfc_add_modify (block, field, fold_convert (TREE_TYPE (field), value));
281 }
282 
283 
284 /* This provides address access to the data field.  This should only be
285    used by array allocation, passing this on to the runtime.  */
286 
287 tree
gfc_conv_descriptor_data_addr(tree desc)288 gfc_conv_descriptor_data_addr (tree desc)
289 {
290   tree field = gfc_get_descriptor_field (desc, DATA_FIELD);
291   return gfc_build_addr_expr (NULL_TREE, field);
292 }
293 
294 static tree
gfc_conv_descriptor_offset(tree desc)295 gfc_conv_descriptor_offset (tree desc)
296 {
297   tree field = gfc_get_descriptor_field (desc, OFFSET_FIELD);
298   gcc_assert (TREE_TYPE (field) == gfc_array_index_type);
299   return field;
300 }
301 
302 tree
gfc_conv_descriptor_offset_get(tree desc)303 gfc_conv_descriptor_offset_get (tree desc)
304 {
305   return gfc_conv_descriptor_offset (desc);
306 }
307 
308 void
gfc_conv_descriptor_offset_set(stmtblock_t * block,tree desc,tree value)309 gfc_conv_descriptor_offset_set (stmtblock_t *block, tree desc,
310 				tree value)
311 {
312   tree t = gfc_conv_descriptor_offset (desc);
313   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
314 }
315 
316 
317 tree
gfc_conv_descriptor_dtype(tree desc)318 gfc_conv_descriptor_dtype (tree desc)
319 {
320   tree field = gfc_get_descriptor_field (desc, DTYPE_FIELD);
321   gcc_assert (TREE_TYPE (field) == get_dtype_type_node ());
322   return field;
323 }
324 
325 static tree
gfc_conv_descriptor_span(tree desc)326 gfc_conv_descriptor_span (tree desc)
327 {
328   tree field = gfc_get_descriptor_field (desc, SPAN_FIELD);
329   gcc_assert (TREE_TYPE (field) == gfc_array_index_type);
330   return field;
331 }
332 
333 tree
gfc_conv_descriptor_span_get(tree desc)334 gfc_conv_descriptor_span_get (tree desc)
335 {
336   return gfc_conv_descriptor_span (desc);
337 }
338 
339 void
gfc_conv_descriptor_span_set(stmtblock_t * block,tree desc,tree value)340 gfc_conv_descriptor_span_set (stmtblock_t *block, tree desc,
341 				tree value)
342 {
343   tree t = gfc_conv_descriptor_span (desc);
344   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
345 }
346 
347 
348 tree
gfc_conv_descriptor_rank(tree desc)349 gfc_conv_descriptor_rank (tree desc)
350 {
351   tree tmp;
352   tree dtype;
353 
354   dtype = gfc_conv_descriptor_dtype (desc);
355   tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), GFC_DTYPE_RANK);
356   gcc_assert (tmp != NULL_TREE
357 	      && TREE_TYPE (tmp) == signed_char_type_node);
358   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp),
359 			  dtype, tmp, NULL_TREE);
360 }
361 
362 
363 /* Return the element length from the descriptor dtype field.  */
364 
365 tree
gfc_conv_descriptor_elem_len(tree desc)366 gfc_conv_descriptor_elem_len (tree desc)
367 {
368   tree tmp;
369   tree dtype;
370 
371   dtype = gfc_conv_descriptor_dtype (desc);
372   tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)),
373 			   GFC_DTYPE_ELEM_LEN);
374   gcc_assert (tmp != NULL_TREE
375 	      && TREE_TYPE (tmp) == size_type_node);
376   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp),
377 			  dtype, tmp, NULL_TREE);
378 }
379 
380 
381 tree
gfc_conv_descriptor_attribute(tree desc)382 gfc_conv_descriptor_attribute (tree desc)
383 {
384   tree tmp;
385   tree dtype;
386 
387   dtype = gfc_conv_descriptor_dtype (desc);
388   tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)),
389 			   GFC_DTYPE_ATTRIBUTE);
390   gcc_assert (tmp!= NULL_TREE
391 	      && TREE_TYPE (tmp) == short_integer_type_node);
392   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp),
393 			  dtype, tmp, NULL_TREE);
394 }
395 
396 tree
gfc_conv_descriptor_type(tree desc)397 gfc_conv_descriptor_type (tree desc)
398 {
399   tree tmp;
400   tree dtype;
401 
402   dtype = gfc_conv_descriptor_dtype (desc);
403   tmp = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), GFC_DTYPE_TYPE);
404   gcc_assert (tmp!= NULL_TREE
405 	      && TREE_TYPE (tmp) == signed_char_type_node);
406   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp),
407 			  dtype, tmp, NULL_TREE);
408 }
409 
410 tree
gfc_get_descriptor_dimension(tree desc)411 gfc_get_descriptor_dimension (tree desc)
412 {
413   tree field = gfc_get_descriptor_field (desc, DIMENSION_FIELD);
414   gcc_assert (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
415 	      && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
416   return field;
417 }
418 
419 
420 static tree
gfc_conv_descriptor_dimension(tree desc,tree dim)421 gfc_conv_descriptor_dimension (tree desc, tree dim)
422 {
423   tree tmp;
424 
425   tmp = gfc_get_descriptor_dimension (desc);
426 
427   return gfc_build_array_ref (tmp, dim, NULL_TREE, true);
428 }
429 
430 
431 tree
gfc_conv_descriptor_token(tree desc)432 gfc_conv_descriptor_token (tree desc)
433 {
434   gcc_assert (flag_coarray == GFC_FCOARRAY_LIB);
435   tree field = gfc_get_descriptor_field (desc, CAF_TOKEN_FIELD);
436   /* Should be a restricted pointer - except in the finalization wrapper.  */
437   gcc_assert (TREE_TYPE (field) == prvoid_type_node
438 	      || TREE_TYPE (field) == pvoid_type_node);
439   return field;
440 }
441 
442 static tree
gfc_conv_descriptor_subfield(tree desc,tree dim,unsigned field_idx)443 gfc_conv_descriptor_subfield (tree desc, tree dim, unsigned field_idx)
444 {
445   tree tmp = gfc_conv_descriptor_dimension (desc, dim);
446   tree field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), field_idx);
447   gcc_assert (field != NULL_TREE);
448 
449   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
450 			  tmp, field, NULL_TREE);
451 }
452 
453 static tree
gfc_conv_descriptor_stride(tree desc,tree dim)454 gfc_conv_descriptor_stride (tree desc, tree dim)
455 {
456   tree field = gfc_conv_descriptor_subfield (desc, dim, STRIDE_SUBFIELD);
457   gcc_assert (TREE_TYPE (field) == gfc_array_index_type);
458   return field;
459 }
460 
461 tree
gfc_conv_descriptor_stride_get(tree desc,tree dim)462 gfc_conv_descriptor_stride_get (tree desc, tree dim)
463 {
464   tree type = TREE_TYPE (desc);
465   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
466   if (integer_zerop (dim)
467       && (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE
468 	  ||GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE_CONT
469 	  ||GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_RANK_CONT
470 	  ||GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT))
471     return gfc_index_one_node;
472 
473   return gfc_conv_descriptor_stride (desc, dim);
474 }
475 
476 void
gfc_conv_descriptor_stride_set(stmtblock_t * block,tree desc,tree dim,tree value)477 gfc_conv_descriptor_stride_set (stmtblock_t *block, tree desc,
478 				tree dim, tree value)
479 {
480   tree t = gfc_conv_descriptor_stride (desc, dim);
481   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
482 }
483 
484 static tree
gfc_conv_descriptor_lbound(tree desc,tree dim)485 gfc_conv_descriptor_lbound (tree desc, tree dim)
486 {
487   tree field = gfc_conv_descriptor_subfield (desc, dim, LBOUND_SUBFIELD);
488   gcc_assert (TREE_TYPE (field) == gfc_array_index_type);
489   return field;
490 }
491 
492 tree
gfc_conv_descriptor_lbound_get(tree desc,tree dim)493 gfc_conv_descriptor_lbound_get (tree desc, tree dim)
494 {
495   return gfc_conv_descriptor_lbound (desc, dim);
496 }
497 
498 void
gfc_conv_descriptor_lbound_set(stmtblock_t * block,tree desc,tree dim,tree value)499 gfc_conv_descriptor_lbound_set (stmtblock_t *block, tree desc,
500 				tree dim, tree value)
501 {
502   tree t = gfc_conv_descriptor_lbound (desc, dim);
503   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
504 }
505 
506 static tree
gfc_conv_descriptor_ubound(tree desc,tree dim)507 gfc_conv_descriptor_ubound (tree desc, tree dim)
508 {
509   tree field = gfc_conv_descriptor_subfield (desc, dim, UBOUND_SUBFIELD);
510   gcc_assert (TREE_TYPE (field) == gfc_array_index_type);
511   return field;
512 }
513 
514 tree
gfc_conv_descriptor_ubound_get(tree desc,tree dim)515 gfc_conv_descriptor_ubound_get (tree desc, tree dim)
516 {
517   return gfc_conv_descriptor_ubound (desc, dim);
518 }
519 
520 void
gfc_conv_descriptor_ubound_set(stmtblock_t * block,tree desc,tree dim,tree value)521 gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree desc,
522 				tree dim, tree value)
523 {
524   tree t = gfc_conv_descriptor_ubound (desc, dim);
525   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
526 }
527 
528 /* Build a null array descriptor constructor.  */
529 
530 tree
gfc_build_null_descriptor(tree type)531 gfc_build_null_descriptor (tree type)
532 {
533   tree field;
534   tree tmp;
535 
536   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
537   gcc_assert (DATA_FIELD == 0);
538   field = TYPE_FIELDS (type);
539 
540   /* Set a NULL data pointer.  */
541   tmp = build_constructor_single (type, field, null_pointer_node);
542   TREE_CONSTANT (tmp) = 1;
543   /* All other fields are ignored.  */
544 
545   return tmp;
546 }
547 
548 
549 /* Modify a descriptor such that the lbound of a given dimension is the value
550    specified.  This also updates ubound and offset accordingly.  */
551 
552 void
gfc_conv_shift_descriptor_lbound(stmtblock_t * block,tree desc,int dim,tree new_lbound)553 gfc_conv_shift_descriptor_lbound (stmtblock_t* block, tree desc,
554 				  int dim, tree new_lbound)
555 {
556   tree offs, ubound, lbound, stride;
557   tree diff, offs_diff;
558 
559   new_lbound = fold_convert (gfc_array_index_type, new_lbound);
560 
561   offs = gfc_conv_descriptor_offset_get (desc);
562   lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
563   ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
564   stride = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[dim]);
565 
566   /* Get difference (new - old) by which to shift stuff.  */
567   diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
568 			  new_lbound, lbound);
569 
570   /* Shift ubound and offset accordingly.  This has to be done before
571      updating the lbound, as they depend on the lbound expression!  */
572   ubound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
573 			    ubound, diff);
574   gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[dim], ubound);
575   offs_diff = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
576 			       diff, stride);
577   offs = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
578 			  offs, offs_diff);
579   gfc_conv_descriptor_offset_set (block, desc, offs);
580 
581   /* Finally set lbound to value we want.  */
582   gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[dim], new_lbound);
583 }
584 
585 
586 /* Obtain offsets for trans-types.cc(gfc_get_array_descr_info).  */
587 
588 void
gfc_get_descriptor_offsets_for_info(const_tree desc_type,tree * data_off,tree * dtype_off,tree * span_off,tree * dim_off,tree * dim_size,tree * stride_suboff,tree * lower_suboff,tree * upper_suboff)589 gfc_get_descriptor_offsets_for_info (const_tree desc_type, tree *data_off,
590 				     tree *dtype_off, tree *span_off,
591 				     tree *dim_off, tree *dim_size,
592 				     tree *stride_suboff, tree *lower_suboff,
593 				     tree *upper_suboff)
594 {
595   tree field;
596   tree type;
597 
598   type = TYPE_MAIN_VARIANT (desc_type);
599   field = gfc_advance_chain (TYPE_FIELDS (type), DATA_FIELD);
600   *data_off = byte_position (field);
601   field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
602   *dtype_off = byte_position (field);
603   field = gfc_advance_chain (TYPE_FIELDS (type), SPAN_FIELD);
604   *span_off = byte_position (field);
605   field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
606   *dim_off = byte_position (field);
607   type = TREE_TYPE (TREE_TYPE (field));
608   *dim_size = TYPE_SIZE_UNIT (type);
609   field = gfc_advance_chain (TYPE_FIELDS (type), STRIDE_SUBFIELD);
610   *stride_suboff = byte_position (field);
611   field = gfc_advance_chain (TYPE_FIELDS (type), LBOUND_SUBFIELD);
612   *lower_suboff = byte_position (field);
613   field = gfc_advance_chain (TYPE_FIELDS (type), UBOUND_SUBFIELD);
614   *upper_suboff = byte_position (field);
615 }
616 
617 
618 /* Cleanup those #defines.  */
619 
620 #undef DATA_FIELD
621 #undef OFFSET_FIELD
622 #undef DTYPE_FIELD
623 #undef SPAN_FIELD
624 #undef DIMENSION_FIELD
625 #undef CAF_TOKEN_FIELD
626 #undef STRIDE_SUBFIELD
627 #undef LBOUND_SUBFIELD
628 #undef UBOUND_SUBFIELD
629 
630 
631 /* Mark a SS chain as used.  Flags specifies in which loops the SS is used.
632    flags & 1 = Main loop body.
633    flags & 2 = temp copy loop.  */
634 
635 void
gfc_mark_ss_chain_used(gfc_ss * ss,unsigned flags)636 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
637 {
638   for (; ss != gfc_ss_terminator; ss = ss->next)
639     ss->info->useflags = flags;
640 }
641 
642 
643 /* Free a gfc_ss chain.  */
644 
645 void
gfc_free_ss_chain(gfc_ss * ss)646 gfc_free_ss_chain (gfc_ss * ss)
647 {
648   gfc_ss *next;
649 
650   while (ss != gfc_ss_terminator)
651     {
652       gcc_assert (ss != NULL);
653       next = ss->next;
654       gfc_free_ss (ss);
655       ss = next;
656     }
657 }
658 
659 
660 static void
free_ss_info(gfc_ss_info * ss_info)661 free_ss_info (gfc_ss_info *ss_info)
662 {
663   int n;
664 
665   ss_info->refcount--;
666   if (ss_info->refcount > 0)
667     return;
668 
669   gcc_assert (ss_info->refcount == 0);
670 
671   switch (ss_info->type)
672     {
673     case GFC_SS_SECTION:
674       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
675 	if (ss_info->data.array.subscript[n])
676 	  gfc_free_ss_chain (ss_info->data.array.subscript[n]);
677       break;
678 
679     default:
680       break;
681     }
682 
683   free (ss_info);
684 }
685 
686 
687 /* Free a SS.  */
688 
689 void
gfc_free_ss(gfc_ss * ss)690 gfc_free_ss (gfc_ss * ss)
691 {
692   free_ss_info (ss->info);
693   free (ss);
694 }
695 
696 
697 /* Creates and initializes an array type gfc_ss struct.  */
698 
699 gfc_ss *
gfc_get_array_ss(gfc_ss * next,gfc_expr * expr,int dimen,gfc_ss_type type)700 gfc_get_array_ss (gfc_ss *next, gfc_expr *expr, int dimen, gfc_ss_type type)
701 {
702   gfc_ss *ss;
703   gfc_ss_info *ss_info;
704   int i;
705 
706   ss_info = gfc_get_ss_info ();
707   ss_info->refcount++;
708   ss_info->type = type;
709   ss_info->expr = expr;
710 
711   ss = gfc_get_ss ();
712   ss->info = ss_info;
713   ss->next = next;
714   ss->dimen = dimen;
715   for (i = 0; i < ss->dimen; i++)
716     ss->dim[i] = i;
717 
718   return ss;
719 }
720 
721 
722 /* Creates and initializes a temporary type gfc_ss struct.  */
723 
724 gfc_ss *
gfc_get_temp_ss(tree type,tree string_length,int dimen)725 gfc_get_temp_ss (tree type, tree string_length, int dimen)
726 {
727   gfc_ss *ss;
728   gfc_ss_info *ss_info;
729   int i;
730 
731   ss_info = gfc_get_ss_info ();
732   ss_info->refcount++;
733   ss_info->type = GFC_SS_TEMP;
734   ss_info->string_length = string_length;
735   ss_info->data.temp.type = type;
736 
737   ss = gfc_get_ss ();
738   ss->info = ss_info;
739   ss->next = gfc_ss_terminator;
740   ss->dimen = dimen;
741   for (i = 0; i < ss->dimen; i++)
742     ss->dim[i] = i;
743 
744   return ss;
745 }
746 
747 
748 /* Creates and initializes a scalar type gfc_ss struct.  */
749 
750 gfc_ss *
gfc_get_scalar_ss(gfc_ss * next,gfc_expr * expr)751 gfc_get_scalar_ss (gfc_ss *next, gfc_expr *expr)
752 {
753   gfc_ss *ss;
754   gfc_ss_info *ss_info;
755 
756   ss_info = gfc_get_ss_info ();
757   ss_info->refcount++;
758   ss_info->type = GFC_SS_SCALAR;
759   ss_info->expr = expr;
760 
761   ss = gfc_get_ss ();
762   ss->info = ss_info;
763   ss->next = next;
764 
765   return ss;
766 }
767 
768 
769 /* Free all the SS associated with a loop.  */
770 
771 void
gfc_cleanup_loop(gfc_loopinfo * loop)772 gfc_cleanup_loop (gfc_loopinfo * loop)
773 {
774   gfc_loopinfo *loop_next, **ploop;
775   gfc_ss *ss;
776   gfc_ss *next;
777 
778   ss = loop->ss;
779   while (ss != gfc_ss_terminator)
780     {
781       gcc_assert (ss != NULL);
782       next = ss->loop_chain;
783       gfc_free_ss (ss);
784       ss = next;
785     }
786 
787   /* Remove reference to self in the parent loop.  */
788   if (loop->parent)
789     for (ploop = &loop->parent->nested; *ploop; ploop = &(*ploop)->next)
790       if (*ploop == loop)
791 	{
792 	  *ploop = loop->next;
793 	  break;
794 	}
795 
796   /* Free non-freed nested loops.  */
797   for (loop = loop->nested; loop; loop = loop_next)
798     {
799       loop_next = loop->next;
800       gfc_cleanup_loop (loop);
801       free (loop);
802     }
803 }
804 
805 
806 static void
set_ss_loop(gfc_ss * ss,gfc_loopinfo * loop)807 set_ss_loop (gfc_ss *ss, gfc_loopinfo *loop)
808 {
809   int n;
810 
811   for (; ss != gfc_ss_terminator; ss = ss->next)
812     {
813       ss->loop = loop;
814 
815       if (ss->info->type == GFC_SS_SCALAR
816 	  || ss->info->type == GFC_SS_REFERENCE
817 	  || ss->info->type == GFC_SS_TEMP)
818 	continue;
819 
820       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
821 	if (ss->info->data.array.subscript[n] != NULL)
822 	  set_ss_loop (ss->info->data.array.subscript[n], loop);
823     }
824 }
825 
826 
827 /* Associate a SS chain with a loop.  */
828 
829 void
gfc_add_ss_to_loop(gfc_loopinfo * loop,gfc_ss * head)830 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
831 {
832   gfc_ss *ss;
833   gfc_loopinfo *nested_loop;
834 
835   if (head == gfc_ss_terminator)
836     return;
837 
838   set_ss_loop (head, loop);
839 
840   ss = head;
841   for (; ss && ss != gfc_ss_terminator; ss = ss->next)
842     {
843       if (ss->nested_ss)
844 	{
845 	  nested_loop = ss->nested_ss->loop;
846 
847 	  /* More than one ss can belong to the same loop.  Hence, we add the
848 	     loop to the chain only if it is different from the previously
849 	     added one, to avoid duplicate nested loops.  */
850 	  if (nested_loop != loop->nested)
851 	    {
852 	      gcc_assert (nested_loop->parent == NULL);
853 	      nested_loop->parent = loop;
854 
855 	      gcc_assert (nested_loop->next == NULL);
856 	      nested_loop->next = loop->nested;
857 	      loop->nested = nested_loop;
858 	    }
859 	  else
860 	    gcc_assert (nested_loop->parent == loop);
861 	}
862 
863       if (ss->next == gfc_ss_terminator)
864 	ss->loop_chain = loop->ss;
865       else
866 	ss->loop_chain = ss->next;
867     }
868   gcc_assert (ss == gfc_ss_terminator);
869   loop->ss = head;
870 }
871 
872 
873 /* Returns true if the expression is an array pointer.  */
874 
875 static bool
is_pointer_array(tree expr)876 is_pointer_array (tree expr)
877 {
878   if (expr == NULL_TREE
879       || !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (expr))
880       || GFC_CLASS_TYPE_P (TREE_TYPE (expr)))
881     return false;
882 
883   if (TREE_CODE (expr) == VAR_DECL
884       && GFC_DECL_PTR_ARRAY_P (expr))
885     return true;
886 
887   if (TREE_CODE (expr) == PARM_DECL
888       && GFC_DECL_PTR_ARRAY_P (expr))
889     return true;
890 
891   if (TREE_CODE (expr) == INDIRECT_REF
892       && GFC_DECL_PTR_ARRAY_P (TREE_OPERAND (expr, 0)))
893     return true;
894 
895   /* The field declaration is marked as an pointer array.  */
896   if (TREE_CODE (expr) == COMPONENT_REF
897       && GFC_DECL_PTR_ARRAY_P (TREE_OPERAND (expr, 1))
898       && !GFC_CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1))))
899     return true;
900 
901   return false;
902 }
903 
904 
905 /* If the symbol or expression reference a CFI descriptor, return the
906    pointer to the converted gfc descriptor. If an array reference is
907    present as the last argument, check that it is the one applied to
908    the CFI descriptor in the expression. Note that the CFI object is
909    always the symbol in the expression!  */
910 
911 static bool
get_CFI_desc(gfc_symbol * sym,gfc_expr * expr,tree * desc,gfc_array_ref * ar)912 get_CFI_desc (gfc_symbol *sym, gfc_expr *expr,
913 	      tree *desc, gfc_array_ref *ar)
914 {
915   tree tmp;
916 
917   if (!is_CFI_desc (sym, expr))
918     return false;
919 
920   if (expr && ar)
921     {
922       if (!(expr->ref && expr->ref->type == REF_ARRAY)
923 	  || (&expr->ref->u.ar != ar))
924 	return false;
925     }
926 
927   if (sym == NULL)
928     tmp = expr->symtree->n.sym->backend_decl;
929   else
930     tmp = sym->backend_decl;
931 
932   if (tmp && DECL_LANG_SPECIFIC (tmp) && GFC_DECL_SAVED_DESCRIPTOR (tmp))
933     tmp = GFC_DECL_SAVED_DESCRIPTOR (tmp);
934 
935   *desc = tmp;
936   return true;
937 }
938 
939 
940 /* Return the span of an array.  */
941 
942 tree
gfc_get_array_span(tree desc,gfc_expr * expr)943 gfc_get_array_span (tree desc, gfc_expr *expr)
944 {
945   tree tmp;
946 
947   if (is_pointer_array (desc)
948       || (get_CFI_desc (NULL, expr, &desc, NULL)
949 	  && (POINTER_TYPE_P (TREE_TYPE (desc))
950 	      ? GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (desc)))
951 	      : GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))))
952     {
953       if (POINTER_TYPE_P (TREE_TYPE (desc)))
954 	desc = build_fold_indirect_ref_loc (input_location, desc);
955 
956       /* This will have the span field set.  */
957       tmp = gfc_conv_descriptor_span_get (desc);
958     }
959   else if (expr->ts.type == BT_ASSUMED)
960     {
961       if (DECL_LANG_SPECIFIC (desc) && GFC_DECL_SAVED_DESCRIPTOR (desc))
962 	desc = GFC_DECL_SAVED_DESCRIPTOR (desc);
963       if (POINTER_TYPE_P (TREE_TYPE (desc)))
964 	desc = build_fold_indirect_ref_loc (input_location, desc);
965       tmp = gfc_conv_descriptor_span_get (desc);
966     }
967   else if (TREE_CODE (desc) == COMPONENT_REF
968 	   && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))
969 	   && GFC_CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (desc, 0))))
970     {
971       /* The descriptor is a class _data field and so use the vtable
972 	 size for the receiving span field.  */
973       tmp = gfc_get_vptr_from_expr (desc);
974       tmp = gfc_vptr_size_get (tmp);
975     }
976   else if (expr && expr->expr_type == EXPR_VARIABLE
977 	   && expr->symtree->n.sym->ts.type == BT_CLASS
978 	   && expr->ref->type == REF_COMPONENT
979 	   && expr->ref->next->type == REF_ARRAY
980 	   && expr->ref->next->next == NULL
981 	   && CLASS_DATA (expr->symtree->n.sym)->attr.dimension)
982     {
983       /* Dummys come in sometimes with the descriptor detached from
984 	 the class field or declaration.  */
985       tmp = gfc_class_vptr_get (expr->symtree->n.sym->backend_decl);
986       tmp = gfc_vptr_size_get (tmp);
987     }
988   else
989     {
990       /* If none of the fancy stuff works, the span is the element
991 	 size of the array. Attempt to deal with unbounded character
992 	 types if possible. Otherwise, return NULL_TREE.  */
993       tmp = gfc_get_element_type (TREE_TYPE (desc));
994       if (tmp && TREE_CODE (tmp) == ARRAY_TYPE && TYPE_STRING_FLAG (tmp))
995 	{
996 	  gcc_assert (expr->ts.type == BT_CHARACTER);
997 
998 	  tmp = gfc_get_character_len_in_bytes (tmp);
999 
1000 	  if (tmp == NULL_TREE || integer_zerop (tmp))
1001 	    {
1002 	      tree bs;
1003 
1004 	      tmp = gfc_get_expr_charlen (expr);
1005 	      tmp = fold_convert (gfc_array_index_type, tmp);
1006 	      bs = build_int_cst (gfc_array_index_type, expr->ts.kind);
1007 	      tmp = fold_build2_loc (input_location, MULT_EXPR,
1008 				     gfc_array_index_type, tmp, bs);
1009 	    }
1010 
1011 	  tmp = (tmp && !integer_zerop (tmp))
1012 	    ? (fold_convert (gfc_array_index_type, tmp)) : (NULL_TREE);
1013 	}
1014       else
1015 	tmp = fold_convert (gfc_array_index_type,
1016 			    size_in_bytes (tmp));
1017     }
1018   return tmp;
1019 }
1020 
1021 
1022 /* Generate an initializer for a static pointer or allocatable array.  */
1023 
1024 void
gfc_trans_static_array_pointer(gfc_symbol * sym)1025 gfc_trans_static_array_pointer (gfc_symbol * sym)
1026 {
1027   tree type;
1028 
1029   gcc_assert (TREE_STATIC (sym->backend_decl));
1030   /* Just zero the data member.  */
1031   type = TREE_TYPE (sym->backend_decl);
1032   DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
1033 }
1034 
1035 
1036 /* If the bounds of SE's loop have not yet been set, see if they can be
1037    determined from array spec AS, which is the array spec of a called
1038    function.  MAPPING maps the callee's dummy arguments to the values
1039    that the caller is passing.  Add any initialization and finalization
1040    code to SE.  */
1041 
1042 void
gfc_set_loop_bounds_from_array_spec(gfc_interface_mapping * mapping,gfc_se * se,gfc_array_spec * as)1043 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
1044 				     gfc_se * se, gfc_array_spec * as)
1045 {
1046   int n, dim, total_dim;
1047   gfc_se tmpse;
1048   gfc_ss *ss;
1049   tree lower;
1050   tree upper;
1051   tree tmp;
1052 
1053   total_dim = 0;
1054 
1055   if (!as || as->type != AS_EXPLICIT)
1056     return;
1057 
1058   for (ss = se->ss; ss; ss = ss->parent)
1059     {
1060       total_dim += ss->loop->dimen;
1061       for (n = 0; n < ss->loop->dimen; n++)
1062 	{
1063 	  /* The bound is known, nothing to do.  */
1064 	  if (ss->loop->to[n] != NULL_TREE)
1065 	    continue;
1066 
1067 	  dim = ss->dim[n];
1068 	  gcc_assert (dim < as->rank);
1069 	  gcc_assert (ss->loop->dimen <= as->rank);
1070 
1071 	  /* Evaluate the lower bound.  */
1072 	  gfc_init_se (&tmpse, NULL);
1073 	  gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
1074 	  gfc_add_block_to_block (&se->pre, &tmpse.pre);
1075 	  gfc_add_block_to_block (&se->post, &tmpse.post);
1076 	  lower = fold_convert (gfc_array_index_type, tmpse.expr);
1077 
1078 	  /* ...and the upper bound.  */
1079 	  gfc_init_se (&tmpse, NULL);
1080 	  gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
1081 	  gfc_add_block_to_block (&se->pre, &tmpse.pre);
1082 	  gfc_add_block_to_block (&se->post, &tmpse.post);
1083 	  upper = fold_convert (gfc_array_index_type, tmpse.expr);
1084 
1085 	  /* Set the upper bound of the loop to UPPER - LOWER.  */
1086 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
1087 				 gfc_array_index_type, upper, lower);
1088 	  tmp = gfc_evaluate_now (tmp, &se->pre);
1089 	  ss->loop->to[n] = tmp;
1090 	}
1091     }
1092 
1093   gcc_assert (total_dim == as->rank);
1094 }
1095 
1096 
1097 /* Generate code to allocate an array temporary, or create a variable to
1098    hold the data.  If size is NULL, zero the descriptor so that the
1099    callee will allocate the array.  If DEALLOC is true, also generate code to
1100    free the array afterwards.
1101 
1102    If INITIAL is not NULL, it is packed using internal_pack and the result used
1103    as data instead of allocating a fresh, unitialized area of memory.
1104 
1105    Initialization code is added to PRE and finalization code to POST.
1106    DYNAMIC is true if the caller may want to extend the array later
1107    using realloc.  This prevents us from putting the array on the stack.  */
1108 
1109 static void
gfc_trans_allocate_array_storage(stmtblock_t * pre,stmtblock_t * post,gfc_array_info * info,tree size,tree nelem,tree initial,bool dynamic,bool dealloc)1110 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
1111 				  gfc_array_info * info, tree size, tree nelem,
1112 				  tree initial, bool dynamic, bool dealloc)
1113 {
1114   tree tmp;
1115   tree desc;
1116   bool onstack;
1117 
1118   desc = info->descriptor;
1119   info->offset = gfc_index_zero_node;
1120   if (size == NULL_TREE || integer_zerop (size))
1121     {
1122       /* A callee allocated array.  */
1123       gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
1124       onstack = FALSE;
1125     }
1126   else
1127     {
1128       /* Allocate the temporary.  */
1129       onstack = !dynamic && initial == NULL_TREE
1130 			 && (flag_stack_arrays
1131 			     || gfc_can_put_var_on_stack (size));
1132 
1133       if (onstack)
1134 	{
1135 	  /* Make a temporary variable to hold the data.  */
1136 	  tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (nelem),
1137 				 nelem, gfc_index_one_node);
1138 	  tmp = gfc_evaluate_now (tmp, pre);
1139 	  tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
1140 				  tmp);
1141 	  tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
1142 				  tmp);
1143 	  tmp = gfc_create_var (tmp, "A");
1144 	  /* If we're here only because of -fstack-arrays we have to
1145 	     emit a DECL_EXPR to make the gimplifier emit alloca calls.  */
1146 	  if (!gfc_can_put_var_on_stack (size))
1147 	    gfc_add_expr_to_block (pre,
1148 				   fold_build1_loc (input_location,
1149 						    DECL_EXPR, TREE_TYPE (tmp),
1150 						    tmp));
1151 	  tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1152 	  gfc_conv_descriptor_data_set (pre, desc, tmp);
1153 	}
1154       else
1155 	{
1156 	  /* Allocate memory to hold the data or call internal_pack.  */
1157 	  if (initial == NULL_TREE)
1158 	    {
1159 	      tmp = gfc_call_malloc (pre, NULL, size);
1160 	      tmp = gfc_evaluate_now (tmp, pre);
1161 	    }
1162 	  else
1163 	    {
1164 	      tree packed;
1165 	      tree source_data;
1166 	      tree was_packed;
1167 	      stmtblock_t do_copying;
1168 
1169 	      tmp = TREE_TYPE (initial); /* Pointer to descriptor.  */
1170 	      gcc_assert (TREE_CODE (tmp) == POINTER_TYPE);
1171 	      tmp = TREE_TYPE (tmp); /* The descriptor itself.  */
1172 	      tmp = gfc_get_element_type (tmp);
1173 	      packed = gfc_create_var (build_pointer_type (tmp), "data");
1174 
1175 	      tmp = build_call_expr_loc (input_location,
1176 				     gfor_fndecl_in_pack, 1, initial);
1177 	      tmp = fold_convert (TREE_TYPE (packed), tmp);
1178 	      gfc_add_modify (pre, packed, tmp);
1179 
1180 	      tmp = build_fold_indirect_ref_loc (input_location,
1181 					     initial);
1182 	      source_data = gfc_conv_descriptor_data_get (tmp);
1183 
1184 	      /* internal_pack may return source->data without any allocation
1185 		 or copying if it is already packed.  If that's the case, we
1186 		 need to allocate and copy manually.  */
1187 
1188 	      gfc_start_block (&do_copying);
1189 	      tmp = gfc_call_malloc (&do_copying, NULL, size);
1190 	      tmp = fold_convert (TREE_TYPE (packed), tmp);
1191 	      gfc_add_modify (&do_copying, packed, tmp);
1192 	      tmp = gfc_build_memcpy_call (packed, source_data, size);
1193 	      gfc_add_expr_to_block (&do_copying, tmp);
1194 
1195 	      was_packed = fold_build2_loc (input_location, EQ_EXPR,
1196 					    logical_type_node, packed,
1197 					    source_data);
1198 	      tmp = gfc_finish_block (&do_copying);
1199 	      tmp = build3_v (COND_EXPR, was_packed, tmp,
1200 			      build_empty_stmt (input_location));
1201 	      gfc_add_expr_to_block (pre, tmp);
1202 
1203 	      tmp = fold_convert (pvoid_type_node, packed);
1204 	    }
1205 
1206 	  gfc_conv_descriptor_data_set (pre, desc, tmp);
1207 	}
1208     }
1209   info->data = gfc_conv_descriptor_data_get (desc);
1210 
1211   /* The offset is zero because we create temporaries with a zero
1212      lower bound.  */
1213   gfc_conv_descriptor_offset_set (pre, desc, gfc_index_zero_node);
1214 
1215   if (dealloc && !onstack)
1216     {
1217       /* Free the temporary.  */
1218       tmp = gfc_conv_descriptor_data_get (desc);
1219       tmp = gfc_call_free (tmp);
1220       gfc_add_expr_to_block (post, tmp);
1221     }
1222 }
1223 
1224 
1225 /* Get the scalarizer array dimension corresponding to actual array dimension
1226    given by ARRAY_DIM.
1227 
1228    For example, if SS represents the array ref a(1,:,:,1), it is a
1229    bidimensional scalarizer array, and the result would be 0 for ARRAY_DIM=1,
1230    and 1 for ARRAY_DIM=2.
1231    If SS represents transpose(a(:,1,1,:)), it is again a bidimensional
1232    scalarizer array, and the result would be 1 for ARRAY_DIM=0 and 0 for
1233    ARRAY_DIM=3.
1234    If SS represents sum(a(:,:,:,1), dim=1), it is a 2+1-dimensional scalarizer
1235    array.  If called on the inner ss, the result would be respectively 0,1,2 for
1236    ARRAY_DIM=0,1,2.  If called on the outer ss, the result would be 0,1
1237    for ARRAY_DIM=1,2.  */
1238 
1239 static int
get_scalarizer_dim_for_array_dim(gfc_ss * ss,int array_dim)1240 get_scalarizer_dim_for_array_dim (gfc_ss *ss, int array_dim)
1241 {
1242   int array_ref_dim;
1243   int n;
1244 
1245   array_ref_dim = 0;
1246 
1247   for (; ss; ss = ss->parent)
1248     for (n = 0; n < ss->dimen; n++)
1249       if (ss->dim[n] < array_dim)
1250 	array_ref_dim++;
1251 
1252   return array_ref_dim;
1253 }
1254 
1255 
1256 static gfc_ss *
innermost_ss(gfc_ss * ss)1257 innermost_ss (gfc_ss *ss)
1258 {
1259   while (ss->nested_ss != NULL)
1260     ss = ss->nested_ss;
1261 
1262   return ss;
1263 }
1264 
1265 
1266 
1267 /* Get the array reference dimension corresponding to the given loop dimension.
1268    It is different from the true array dimension given by the dim array in
1269    the case of a partial array reference (i.e. a(:,:,1,:) for example)
1270    It is different from the loop dimension in the case of a transposed array.
1271    */
1272 
1273 static int
get_array_ref_dim_for_loop_dim(gfc_ss * ss,int loop_dim)1274 get_array_ref_dim_for_loop_dim (gfc_ss *ss, int loop_dim)
1275 {
1276   return get_scalarizer_dim_for_array_dim (innermost_ss (ss),
1277 					   ss->dim[loop_dim]);
1278 }
1279 
1280 
1281 /* Use the information in the ss to obtain the required information about
1282    the type and size of an array temporary, when the lhs in an assignment
1283    is a class expression.  */
1284 
1285 static tree
get_class_info_from_ss(stmtblock_t * pre,gfc_ss * ss,tree * eltype)1286 get_class_info_from_ss (stmtblock_t * pre, gfc_ss *ss, tree *eltype)
1287 {
1288   gfc_ss *lhs_ss;
1289   gfc_ss *rhs_ss;
1290   tree tmp;
1291   tree tmp2;
1292   tree vptr;
1293   tree rhs_class_expr = NULL_TREE;
1294   tree lhs_class_expr = NULL_TREE;
1295   bool unlimited_rhs = false;
1296   bool unlimited_lhs = false;
1297   bool rhs_function = false;
1298   gfc_symbol *vtab;
1299 
1300   /* The second element in the loop chain contains the source for the
1301      temporary; ie. the rhs of the assignment.  */
1302   rhs_ss = ss->loop->ss->loop_chain;
1303 
1304   if (rhs_ss != gfc_ss_terminator
1305       && rhs_ss->info
1306       && rhs_ss->info->expr
1307       && rhs_ss->info->expr->ts.type == BT_CLASS
1308       && rhs_ss->info->data.array.descriptor)
1309     {
1310       if (rhs_ss->info->expr->expr_type != EXPR_VARIABLE)
1311 	rhs_class_expr
1312 	  = gfc_get_class_from_expr (rhs_ss->info->data.array.descriptor);
1313       else
1314 	rhs_class_expr = gfc_get_class_from_gfc_expr (rhs_ss->info->expr);
1315       unlimited_rhs = UNLIMITED_POLY (rhs_ss->info->expr);
1316       if (rhs_ss->info->expr->expr_type == EXPR_FUNCTION)
1317 	rhs_function = true;
1318     }
1319 
1320   /* For an assignment the lhs is the next element in the loop chain.
1321      If we have a class rhs, this had better be a class variable
1322      expression!  */
1323   lhs_ss = rhs_ss->loop_chain;
1324   if (lhs_ss != gfc_ss_terminator
1325       && lhs_ss->info
1326       && lhs_ss->info->expr
1327       && lhs_ss->info->expr->expr_type ==EXPR_VARIABLE
1328       && lhs_ss->info->expr->ts.type == BT_CLASS)
1329     {
1330       tmp = lhs_ss->info->data.array.descriptor;
1331       unlimited_lhs = UNLIMITED_POLY (rhs_ss->info->expr);
1332     }
1333   else
1334     tmp = NULL_TREE;
1335 
1336   /* Get the lhs class expression.  */
1337   if (tmp != NULL_TREE && lhs_ss->loop_chain == gfc_ss_terminator)
1338     lhs_class_expr = gfc_get_class_from_expr (tmp);
1339   else
1340     return rhs_class_expr;
1341 
1342   gcc_assert (GFC_CLASS_TYPE_P (TREE_TYPE (lhs_class_expr)));
1343 
1344   /* Set the lhs vptr and, if necessary, the _len field.  */
1345   if (rhs_class_expr)
1346     {
1347       /* Both lhs and rhs are class expressions.  */
1348       tmp = gfc_class_vptr_get (lhs_class_expr);
1349       gfc_add_modify (pre, tmp,
1350 		      fold_convert (TREE_TYPE (tmp),
1351 				    gfc_class_vptr_get (rhs_class_expr)));
1352       if (unlimited_lhs)
1353 	{
1354 	  tmp = gfc_class_len_get (lhs_class_expr);
1355 	  if (unlimited_rhs)
1356 	    tmp2 = gfc_class_len_get (rhs_class_expr);
1357 	  else
1358 	    tmp2 = build_int_cst (TREE_TYPE (tmp), 0);
1359 	  gfc_add_modify (pre, tmp, tmp2);
1360 	}
1361 
1362       if (rhs_function)
1363 	{
1364 	  tmp = gfc_class_data_get (rhs_class_expr);
1365 	  gfc_conv_descriptor_offset_set (pre, tmp, gfc_index_zero_node);
1366 	}
1367     }
1368   else
1369    {
1370       /* lhs is class and rhs is intrinsic or derived type.  */
1371       *eltype = TREE_TYPE (rhs_ss->info->data.array.descriptor);
1372       *eltype = gfc_get_element_type (*eltype);
1373       vtab = gfc_find_vtab (&rhs_ss->info->expr->ts);
1374       vptr = vtab->backend_decl;
1375       if (vptr == NULL_TREE)
1376 	vptr = gfc_get_symbol_decl (vtab);
1377       vptr = gfc_build_addr_expr (NULL_TREE, vptr);
1378       tmp = gfc_class_vptr_get (lhs_class_expr);
1379       gfc_add_modify (pre, tmp,
1380 		      fold_convert (TREE_TYPE (tmp), vptr));
1381 
1382       if (unlimited_lhs)
1383 	{
1384 	  tmp = gfc_class_len_get (lhs_class_expr);
1385 	  if (rhs_ss->info
1386 	      && rhs_ss->info->expr
1387 	      && rhs_ss->info->expr->ts.type == BT_CHARACTER)
1388 	    tmp2 = build_int_cst (TREE_TYPE (tmp),
1389 				  rhs_ss->info->expr->ts.kind);
1390 	  else
1391 	    tmp2 = build_int_cst (TREE_TYPE (tmp), 0);
1392 	  gfc_add_modify (pre, tmp, tmp2);
1393 	}
1394     }
1395 
1396   return rhs_class_expr;
1397 }
1398 
1399 
1400 
1401 /* Generate code to create and initialize the descriptor for a temporary
1402    array.  This is used for both temporaries needed by the scalarizer, and
1403    functions returning arrays.  Adjusts the loop variables to be
1404    zero-based, and calculates the loop bounds for callee allocated arrays.
1405    Allocate the array unless it's callee allocated (we have a callee
1406    allocated array if 'callee_alloc' is true, or if loop->to[n] is
1407    NULL_TREE for any n).  Also fills in the descriptor, data and offset
1408    fields of info if known.  Returns the size of the array, or NULL for a
1409    callee allocated array.
1410 
1411    'eltype' == NULL signals that the temporary should be a class object.
1412    The 'initial' expression is used to obtain the size of the dynamic
1413    type; otherwise the allocation and initialization proceeds as for any
1414    other expression
1415 
1416    PRE, POST, INITIAL, DYNAMIC and DEALLOC are as for
1417    gfc_trans_allocate_array_storage.  */
1418 
1419 tree
gfc_trans_create_temp_array(stmtblock_t * pre,stmtblock_t * post,gfc_ss * ss,tree eltype,tree initial,bool dynamic,bool dealloc,bool callee_alloc,locus * where)1420 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss,
1421 			     tree eltype, tree initial, bool dynamic,
1422 			     bool dealloc, bool callee_alloc, locus * where)
1423 {
1424   gfc_loopinfo *loop;
1425   gfc_ss *s;
1426   gfc_array_info *info;
1427   tree from[GFC_MAX_DIMENSIONS], to[GFC_MAX_DIMENSIONS];
1428   tree type;
1429   tree desc;
1430   tree tmp;
1431   tree size;
1432   tree nelem;
1433   tree cond;
1434   tree or_expr;
1435   tree elemsize;
1436   tree class_expr = NULL_TREE;
1437   int n, dim, tmp_dim;
1438   int total_dim = 0;
1439 
1440   /* This signals a class array for which we need the size of the
1441      dynamic type.  Generate an eltype and then the class expression.  */
1442   if (eltype == NULL_TREE && initial)
1443     {
1444       gcc_assert (POINTER_TYPE_P (TREE_TYPE (initial)));
1445       class_expr = build_fold_indirect_ref_loc (input_location, initial);
1446       /* Obtain the structure (class) expression.  */
1447       class_expr = gfc_get_class_from_expr (class_expr);
1448       gcc_assert (class_expr);
1449     }
1450 
1451   /* Otherwise, some expressions, such as class functions, arising from
1452      dependency checking in assignments come here with class element type.
1453      The descriptor can be obtained from the ss->info and then converted
1454      to the class object.  */
1455   if (class_expr == NULL_TREE && GFC_CLASS_TYPE_P (eltype))
1456     class_expr = get_class_info_from_ss (pre, ss, &eltype);
1457 
1458   /* If the dynamic type is not available, use the declared type.  */
1459   if (eltype && GFC_CLASS_TYPE_P (eltype))
1460     eltype = gfc_get_element_type (TREE_TYPE (TYPE_FIELDS (eltype)));
1461 
1462   if (class_expr == NULL_TREE)
1463     elemsize = fold_convert (gfc_array_index_type,
1464 			     TYPE_SIZE_UNIT (eltype));
1465   else
1466     {
1467       /* Unlimited polymorphic entities are initialised with NULL vptr. They
1468 	 can be tested for by checking if the len field is present. If so
1469 	 test the vptr before using the vtable size.  */
1470       tmp = gfc_class_vptr_get (class_expr);
1471       tmp = fold_build2_loc (input_location, NE_EXPR,
1472 			     logical_type_node,
1473 			     tmp, build_int_cst (TREE_TYPE (tmp), 0));
1474       elemsize = fold_build3_loc (input_location, COND_EXPR,
1475 				  gfc_array_index_type,
1476 				  tmp,
1477 				  gfc_class_vtab_size_get (class_expr),
1478 				  gfc_index_zero_node);
1479       elemsize = gfc_evaluate_now (elemsize, pre);
1480       elemsize = gfc_resize_class_size_with_len (pre, class_expr, elemsize);
1481       /* Casting the data as a character of the dynamic length ensures that
1482 	 assignment of elements works when needed.  */
1483       eltype = gfc_get_character_type_len (1, elemsize);
1484     }
1485 
1486   memset (from, 0, sizeof (from));
1487   memset (to, 0, sizeof (to));
1488 
1489   info = &ss->info->data.array;
1490 
1491   gcc_assert (ss->dimen > 0);
1492   gcc_assert (ss->loop->dimen == ss->dimen);
1493 
1494   if (warn_array_temporaries && where)
1495     gfc_warning (OPT_Warray_temporaries,
1496 		 "Creating array temporary at %L", where);
1497 
1498   /* Set the lower bound to zero.  */
1499   for (s = ss; s; s = s->parent)
1500     {
1501       loop = s->loop;
1502 
1503       total_dim += loop->dimen;
1504       for (n = 0; n < loop->dimen; n++)
1505 	{
1506 	  dim = s->dim[n];
1507 
1508 	  /* Callee allocated arrays may not have a known bound yet.  */
1509 	  if (loop->to[n])
1510 	    loop->to[n] = gfc_evaluate_now (
1511 			fold_build2_loc (input_location, MINUS_EXPR,
1512 					 gfc_array_index_type,
1513 					 loop->to[n], loop->from[n]),
1514 			pre);
1515 	  loop->from[n] = gfc_index_zero_node;
1516 
1517 	  /* We have just changed the loop bounds, we must clear the
1518 	     corresponding specloop, so that delta calculation is not skipped
1519 	     later in gfc_set_delta.  */
1520 	  loop->specloop[n] = NULL;
1521 
1522 	  /* We are constructing the temporary's descriptor based on the loop
1523 	     dimensions.  As the dimensions may be accessed in arbitrary order
1524 	     (think of transpose) the size taken from the n'th loop may not map
1525 	     to the n'th dimension of the array.  We need to reconstruct loop
1526 	     infos in the right order before using it to set the descriptor
1527 	     bounds.  */
1528 	  tmp_dim = get_scalarizer_dim_for_array_dim (ss, dim);
1529 	  from[tmp_dim] = loop->from[n];
1530 	  to[tmp_dim] = loop->to[n];
1531 
1532 	  info->delta[dim] = gfc_index_zero_node;
1533 	  info->start[dim] = gfc_index_zero_node;
1534 	  info->end[dim] = gfc_index_zero_node;
1535 	  info->stride[dim] = gfc_index_one_node;
1536 	}
1537     }
1538 
1539   /* Initialize the descriptor.  */
1540   type =
1541     gfc_get_array_type_bounds (eltype, total_dim, 0, from, to, 1,
1542 			       GFC_ARRAY_UNKNOWN, true);
1543   desc = gfc_create_var (type, "atmp");
1544   GFC_DECL_PACKED_ARRAY (desc) = 1;
1545 
1546   /* Emit a DECL_EXPR for the variable sized array type in
1547      GFC_TYPE_ARRAY_DATAPTR_TYPE so the gimplification of its type
1548      sizes works correctly.  */
1549   tree arraytype = TREE_TYPE (GFC_TYPE_ARRAY_DATAPTR_TYPE (type));
1550   if (! TYPE_NAME (arraytype))
1551     TYPE_NAME (arraytype) = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
1552 					NULL_TREE, arraytype);
1553   gfc_add_expr_to_block (pre, build1 (DECL_EXPR,
1554 				      arraytype, TYPE_NAME (arraytype)));
1555 
1556   if (class_expr != NULL_TREE)
1557     {
1558       tree class_data;
1559       tree dtype;
1560 
1561       /* Create a class temporary.  */
1562       tmp = gfc_create_var (TREE_TYPE (class_expr), "ctmp");
1563       gfc_add_modify (pre, tmp, class_expr);
1564 
1565       /* Assign the new descriptor to the _data field. This allows the
1566 	 vptr _copy to be used for scalarized assignment since the class
1567 	 temporary can be found from the descriptor.  */
1568       class_data = gfc_class_data_get (tmp);
1569       tmp = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
1570 			     TREE_TYPE (desc), desc);
1571       gfc_add_modify (pre, class_data, tmp);
1572 
1573       /* Take the dtype from the class expression.  */
1574       dtype = gfc_conv_descriptor_dtype (gfc_class_data_get (class_expr));
1575       tmp = gfc_conv_descriptor_dtype (class_data);
1576       gfc_add_modify (pre, tmp, dtype);
1577 
1578       /* Point desc to the class _data field.  */
1579       desc = class_data;
1580     }
1581   else
1582     {
1583       /* Fill in the array dtype.  */
1584       tmp = gfc_conv_descriptor_dtype (desc);
1585       gfc_add_modify (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
1586     }
1587 
1588   info->descriptor = desc;
1589   size = gfc_index_one_node;
1590 
1591   /*
1592      Fill in the bounds and stride.  This is a packed array, so:
1593 
1594      size = 1;
1595      for (n = 0; n < rank; n++)
1596        {
1597 	 stride[n] = size
1598 	 delta = ubound[n] + 1 - lbound[n];
1599 	 size = size * delta;
1600        }
1601      size = size * sizeof(element);
1602   */
1603 
1604   or_expr = NULL_TREE;
1605 
1606   /* If there is at least one null loop->to[n], it is a callee allocated
1607      array.  */
1608   for (n = 0; n < total_dim; n++)
1609     if (to[n] == NULL_TREE)
1610       {
1611 	size = NULL_TREE;
1612 	break;
1613       }
1614 
1615   if (size == NULL_TREE)
1616     for (s = ss; s; s = s->parent)
1617       for (n = 0; n < s->loop->dimen; n++)
1618 	{
1619 	  dim = get_scalarizer_dim_for_array_dim (ss, s->dim[n]);
1620 
1621 	  /* For a callee allocated array express the loop bounds in terms
1622 	     of the descriptor fields.  */
1623 	  tmp = fold_build2_loc (input_location,
1624 		MINUS_EXPR, gfc_array_index_type,
1625 		gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]),
1626 		gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]));
1627 	  s->loop->to[n] = tmp;
1628 	}
1629   else
1630     {
1631       for (n = 0; n < total_dim; n++)
1632 	{
1633 	  /* Store the stride and bound components in the descriptor.  */
1634 	  gfc_conv_descriptor_stride_set (pre, desc, gfc_rank_cst[n], size);
1635 
1636 	  gfc_conv_descriptor_lbound_set (pre, desc, gfc_rank_cst[n],
1637 					  gfc_index_zero_node);
1638 
1639 	  gfc_conv_descriptor_ubound_set (pre, desc, gfc_rank_cst[n], to[n]);
1640 
1641 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
1642 				 gfc_array_index_type,
1643 				 to[n], gfc_index_one_node);
1644 
1645 	  /* Check whether the size for this dimension is negative.  */
1646 	  cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
1647 				  tmp, gfc_index_zero_node);
1648 	  cond = gfc_evaluate_now (cond, pre);
1649 
1650 	  if (n == 0)
1651 	    or_expr = cond;
1652 	  else
1653 	    or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1654 				       logical_type_node, or_expr, cond);
1655 
1656 	  size = fold_build2_loc (input_location, MULT_EXPR,
1657 				  gfc_array_index_type, size, tmp);
1658 	  size = gfc_evaluate_now (size, pre);
1659 	}
1660     }
1661 
1662   /* Get the size of the array.  */
1663   if (size && !callee_alloc)
1664     {
1665       /* If or_expr is true, then the extent in at least one
1666 	 dimension is zero and the size is set to zero.  */
1667       size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
1668 			      or_expr, gfc_index_zero_node, size);
1669 
1670       nelem = size;
1671       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
1672 			      size, elemsize);
1673     }
1674   else
1675     {
1676       nelem = size;
1677       size = NULL_TREE;
1678     }
1679 
1680   /* Set the span.  */
1681   tmp = fold_convert (gfc_array_index_type, elemsize);
1682   gfc_conv_descriptor_span_set (pre, desc, tmp);
1683 
1684   gfc_trans_allocate_array_storage (pre, post, info, size, nelem, initial,
1685 				    dynamic, dealloc);
1686 
1687   while (ss->parent)
1688     ss = ss->parent;
1689 
1690   if (ss->dimen > ss->loop->temp_dim)
1691     ss->loop->temp_dim = ss->dimen;
1692 
1693   return size;
1694 }
1695 
1696 
1697 /* Return the number of iterations in a loop that starts at START,
1698    ends at END, and has step STEP.  */
1699 
1700 static tree
gfc_get_iteration_count(tree start,tree end,tree step)1701 gfc_get_iteration_count (tree start, tree end, tree step)
1702 {
1703   tree tmp;
1704   tree type;
1705 
1706   type = TREE_TYPE (step);
1707   tmp = fold_build2_loc (input_location, MINUS_EXPR, type, end, start);
1708   tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, type, tmp, step);
1709   tmp = fold_build2_loc (input_location, PLUS_EXPR, type, tmp,
1710 			 build_int_cst (type, 1));
1711   tmp = fold_build2_loc (input_location, MAX_EXPR, type, tmp,
1712 			 build_int_cst (type, 0));
1713   return fold_convert (gfc_array_index_type, tmp);
1714 }
1715 
1716 
1717 /* Extend the data in array DESC by EXTRA elements.  */
1718 
1719 static void
gfc_grow_array(stmtblock_t * pblock,tree desc,tree extra)1720 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
1721 {
1722   tree arg0, arg1;
1723   tree tmp;
1724   tree size;
1725   tree ubound;
1726 
1727   if (integer_zerop (extra))
1728     return;
1729 
1730   ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
1731 
1732   /* Add EXTRA to the upper bound.  */
1733   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1734 			 ubound, extra);
1735   gfc_conv_descriptor_ubound_set (pblock, desc, gfc_rank_cst[0], tmp);
1736 
1737   /* Get the value of the current data pointer.  */
1738   arg0 = gfc_conv_descriptor_data_get (desc);
1739 
1740   /* Calculate the new array size.  */
1741   size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
1742   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1743 			 ubound, gfc_index_one_node);
1744   arg1 = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
1745 			  fold_convert (size_type_node, tmp),
1746 			  fold_convert (size_type_node, size));
1747 
1748   /* Call the realloc() function.  */
1749   tmp = gfc_call_realloc (pblock, arg0, arg1);
1750   gfc_conv_descriptor_data_set (pblock, desc, tmp);
1751 }
1752 
1753 
1754 /* Return true if the bounds of iterator I can only be determined
1755    at run time.  */
1756 
1757 static inline bool
gfc_iterator_has_dynamic_bounds(gfc_iterator * i)1758 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
1759 {
1760   return (i->start->expr_type != EXPR_CONSTANT
1761 	  || i->end->expr_type != EXPR_CONSTANT
1762 	  || i->step->expr_type != EXPR_CONSTANT);
1763 }
1764 
1765 
1766 /* Split the size of constructor element EXPR into the sum of two terms,
1767    one of which can be determined at compile time and one of which must
1768    be calculated at run time.  Set *SIZE to the former and return true
1769    if the latter might be nonzero.  */
1770 
1771 static bool
gfc_get_array_constructor_element_size(mpz_t * size,gfc_expr * expr)1772 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
1773 {
1774   if (expr->expr_type == EXPR_ARRAY)
1775     return gfc_get_array_constructor_size (size, expr->value.constructor);
1776   else if (expr->rank > 0)
1777     {
1778       /* Calculate everything at run time.  */
1779       mpz_set_ui (*size, 0);
1780       return true;
1781     }
1782   else
1783     {
1784       /* A single element.  */
1785       mpz_set_ui (*size, 1);
1786       return false;
1787     }
1788 }
1789 
1790 
1791 /* Like gfc_get_array_constructor_element_size, but applied to the whole
1792    of array constructor C.  */
1793 
1794 static bool
gfc_get_array_constructor_size(mpz_t * size,gfc_constructor_base base)1795 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor_base base)
1796 {
1797   gfc_constructor *c;
1798   gfc_iterator *i;
1799   mpz_t val;
1800   mpz_t len;
1801   bool dynamic;
1802 
1803   mpz_set_ui (*size, 0);
1804   mpz_init (len);
1805   mpz_init (val);
1806 
1807   dynamic = false;
1808   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
1809     {
1810       i = c->iterator;
1811       if (i && gfc_iterator_has_dynamic_bounds (i))
1812 	dynamic = true;
1813       else
1814 	{
1815 	  dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
1816 	  if (i)
1817 	    {
1818 	      /* Multiply the static part of the element size by the
1819 		 number of iterations.  */
1820 	      mpz_sub (val, i->end->value.integer, i->start->value.integer);
1821 	      mpz_fdiv_q (val, val, i->step->value.integer);
1822 	      mpz_add_ui (val, val, 1);
1823 	      if (mpz_sgn (val) > 0)
1824 		mpz_mul (len, len, val);
1825 	      else
1826 		mpz_set_ui (len, 0);
1827 	    }
1828 	  mpz_add (*size, *size, len);
1829 	}
1830     }
1831   mpz_clear (len);
1832   mpz_clear (val);
1833   return dynamic;
1834 }
1835 
1836 
1837 /* Make sure offset is a variable.  */
1838 
1839 static void
gfc_put_offset_into_var(stmtblock_t * pblock,tree * poffset,tree * offsetvar)1840 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
1841 			 tree * offsetvar)
1842 {
1843   /* We should have already created the offset variable.  We cannot
1844      create it here because we may be in an inner scope.  */
1845   gcc_assert (*offsetvar != NULL_TREE);
1846   gfc_add_modify (pblock, *offsetvar, *poffset);
1847   *poffset = *offsetvar;
1848   TREE_USED (*offsetvar) = 1;
1849 }
1850 
1851 
1852 /* Variables needed for bounds-checking.  */
1853 static bool first_len;
1854 static tree first_len_val;
1855 static bool typespec_chararray_ctor;
1856 
1857 static void
gfc_trans_array_ctor_element(stmtblock_t * pblock,tree desc,tree offset,gfc_se * se,gfc_expr * expr)1858 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
1859 			      tree offset, gfc_se * se, gfc_expr * expr)
1860 {
1861   tree tmp;
1862 
1863   gfc_conv_expr (se, expr);
1864 
1865   /* Store the value.  */
1866   tmp = build_fold_indirect_ref_loc (input_location,
1867 				 gfc_conv_descriptor_data_get (desc));
1868   tmp = gfc_build_array_ref (tmp, offset, NULL);
1869 
1870   if (expr->ts.type == BT_CHARACTER)
1871     {
1872       int i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
1873       tree esize;
1874 
1875       esize = size_in_bytes (gfc_get_element_type (TREE_TYPE (desc)));
1876       esize = fold_convert (gfc_charlen_type_node, esize);
1877       esize = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1878 			       TREE_TYPE (esize), esize,
1879 			       build_int_cst (TREE_TYPE (esize),
1880 					  gfc_character_kinds[i].bit_size / 8));
1881 
1882       gfc_conv_string_parameter (se);
1883       if (POINTER_TYPE_P (TREE_TYPE (tmp)))
1884 	{
1885 	  /* The temporary is an array of pointers.  */
1886 	  se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1887 	  gfc_add_modify (&se->pre, tmp, se->expr);
1888 	}
1889       else
1890 	{
1891 	  /* The temporary is an array of string values.  */
1892 	  tmp = gfc_build_addr_expr (gfc_get_pchar_type (expr->ts.kind), tmp);
1893 	  /* We know the temporary and the value will be the same length,
1894 	     so can use memcpy.  */
1895 	  gfc_trans_string_copy (&se->pre, esize, tmp, expr->ts.kind,
1896 				 se->string_length, se->expr, expr->ts.kind);
1897 	}
1898       if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !typespec_chararray_ctor)
1899 	{
1900 	  if (first_len)
1901 	    {
1902 	      gfc_add_modify (&se->pre, first_len_val,
1903 			      fold_convert (TREE_TYPE (first_len_val),
1904 					    se->string_length));
1905 	      first_len = false;
1906 	    }
1907 	  else
1908 	    {
1909 	      /* Verify that all constructor elements are of the same
1910 		 length.  */
1911 	      tree rhs = fold_convert (TREE_TYPE (first_len_val),
1912 				       se->string_length);
1913 	      tree cond = fold_build2_loc (input_location, NE_EXPR,
1914 					   logical_type_node, first_len_val,
1915 					   rhs);
1916 	      gfc_trans_runtime_check
1917 		(true, false, cond, &se->pre, &expr->where,
1918 		 "Different CHARACTER lengths (%ld/%ld) in array constructor",
1919 		 fold_convert (long_integer_type_node, first_len_val),
1920 		 fold_convert (long_integer_type_node, se->string_length));
1921 	    }
1922 	}
1923     }
1924   else if (GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
1925 	   && !GFC_CLASS_TYPE_P (gfc_get_element_type (TREE_TYPE (desc))))
1926     {
1927       /* Assignment of a CLASS array constructor to a derived type array.  */
1928       if (expr->expr_type == EXPR_FUNCTION)
1929 	se->expr = gfc_evaluate_now (se->expr, pblock);
1930       se->expr = gfc_class_data_get (se->expr);
1931       se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
1932       se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1933       gfc_add_modify (&se->pre, tmp, se->expr);
1934     }
1935   else
1936     {
1937       /* TODO: Should the frontend already have done this conversion?  */
1938       se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
1939       gfc_add_modify (&se->pre, tmp, se->expr);
1940     }
1941 
1942   gfc_add_block_to_block (pblock, &se->pre);
1943   gfc_add_block_to_block (pblock, &se->post);
1944 }
1945 
1946 
1947 /* Add the contents of an array to the constructor.  DYNAMIC is as for
1948    gfc_trans_array_constructor_value.  */
1949 
1950 static void
gfc_trans_array_constructor_subarray(stmtblock_t * pblock,tree type ATTRIBUTE_UNUSED,tree desc,gfc_expr * expr,tree * poffset,tree * offsetvar,bool dynamic)1951 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
1952 				      tree type ATTRIBUTE_UNUSED,
1953 				      tree desc, gfc_expr * expr,
1954 				      tree * poffset, tree * offsetvar,
1955 				      bool dynamic)
1956 {
1957   gfc_se se;
1958   gfc_ss *ss;
1959   gfc_loopinfo loop;
1960   stmtblock_t body;
1961   tree tmp;
1962   tree size;
1963   int n;
1964 
1965   /* We need this to be a variable so we can increment it.  */
1966   gfc_put_offset_into_var (pblock, poffset, offsetvar);
1967 
1968   gfc_init_se (&se, NULL);
1969 
1970   /* Walk the array expression.  */
1971   ss = gfc_walk_expr (expr);
1972   gcc_assert (ss != gfc_ss_terminator);
1973 
1974   /* Initialize the scalarizer.  */
1975   gfc_init_loopinfo (&loop);
1976   gfc_add_ss_to_loop (&loop, ss);
1977 
1978   /* Initialize the loop.  */
1979   gfc_conv_ss_startstride (&loop);
1980   gfc_conv_loop_setup (&loop, &expr->where);
1981 
1982   /* Make sure the constructed array has room for the new data.  */
1983   if (dynamic)
1984     {
1985       /* Set SIZE to the total number of elements in the subarray.  */
1986       size = gfc_index_one_node;
1987       for (n = 0; n < loop.dimen; n++)
1988 	{
1989 	  tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
1990 					 gfc_index_one_node);
1991 	  size = fold_build2_loc (input_location, MULT_EXPR,
1992 				  gfc_array_index_type, size, tmp);
1993 	}
1994 
1995       /* Grow the constructed array by SIZE elements.  */
1996       gfc_grow_array (&loop.pre, desc, size);
1997     }
1998 
1999   /* Make the loop body.  */
2000   gfc_mark_ss_chain_used (ss, 1);
2001   gfc_start_scalarized_body (&loop, &body);
2002   gfc_copy_loopinfo_to_se (&se, &loop);
2003   se.ss = ss;
2004 
2005   gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
2006   gcc_assert (se.ss == gfc_ss_terminator);
2007 
2008   /* Increment the offset.  */
2009   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
2010 			 *poffset, gfc_index_one_node);
2011   gfc_add_modify (&body, *poffset, tmp);
2012 
2013   /* Finish the loop.  */
2014   gfc_trans_scalarizing_loops (&loop, &body);
2015   gfc_add_block_to_block (&loop.pre, &loop.post);
2016   tmp = gfc_finish_block (&loop.pre);
2017   gfc_add_expr_to_block (pblock, tmp);
2018 
2019   gfc_cleanup_loop (&loop);
2020 }
2021 
2022 
2023 /* Assign the values to the elements of an array constructor.  DYNAMIC
2024    is true if descriptor DESC only contains enough data for the static
2025    size calculated by gfc_get_array_constructor_size.  When true, memory
2026    for the dynamic parts must be allocated using realloc.  */
2027 
2028 static void
gfc_trans_array_constructor_value(stmtblock_t * pblock,tree type,tree desc,gfc_constructor_base base,tree * poffset,tree * offsetvar,bool dynamic)2029 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
2030 				   tree desc, gfc_constructor_base base,
2031 				   tree * poffset, tree * offsetvar,
2032 				   bool dynamic)
2033 {
2034   tree tmp;
2035   tree start = NULL_TREE;
2036   tree end = NULL_TREE;
2037   tree step = NULL_TREE;
2038   stmtblock_t body;
2039   gfc_se se;
2040   mpz_t size;
2041   gfc_constructor *c;
2042 
2043   tree shadow_loopvar = NULL_TREE;
2044   gfc_saved_var saved_loopvar;
2045 
2046   mpz_init (size);
2047   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
2048     {
2049       /* If this is an iterator or an array, the offset must be a variable.  */
2050       if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
2051 	gfc_put_offset_into_var (pblock, poffset, offsetvar);
2052 
2053       /* Shadowing the iterator avoids changing its value and saves us from
2054 	 keeping track of it. Further, it makes sure that there's always a
2055 	 backend-decl for the symbol, even if there wasn't one before,
2056 	 e.g. in the case of an iterator that appears in a specification
2057 	 expression in an interface mapping.  */
2058       if (c->iterator)
2059 	{
2060 	  gfc_symbol *sym;
2061 	  tree type;
2062 
2063 	  /* Evaluate loop bounds before substituting the loop variable
2064 	     in case they depend on it.  Such a case is invalid, but it is
2065 	     not more expensive to do the right thing here.
2066 	     See PR 44354.  */
2067 	  gfc_init_se (&se, NULL);
2068 	  gfc_conv_expr_val (&se, c->iterator->start);
2069 	  gfc_add_block_to_block (pblock, &se.pre);
2070 	  start = gfc_evaluate_now (se.expr, pblock);
2071 
2072 	  gfc_init_se (&se, NULL);
2073 	  gfc_conv_expr_val (&se, c->iterator->end);
2074 	  gfc_add_block_to_block (pblock, &se.pre);
2075 	  end = gfc_evaluate_now (se.expr, pblock);
2076 
2077 	  gfc_init_se (&se, NULL);
2078 	  gfc_conv_expr_val (&se, c->iterator->step);
2079 	  gfc_add_block_to_block (pblock, &se.pre);
2080 	  step = gfc_evaluate_now (se.expr, pblock);
2081 
2082 	  sym = c->iterator->var->symtree->n.sym;
2083 	  type = gfc_typenode_for_spec (&sym->ts);
2084 
2085 	  shadow_loopvar = gfc_create_var (type, "shadow_loopvar");
2086 	  gfc_shadow_sym (sym, shadow_loopvar, &saved_loopvar);
2087 	}
2088 
2089       gfc_start_block (&body);
2090 
2091       if (c->expr->expr_type == EXPR_ARRAY)
2092 	{
2093 	  /* Array constructors can be nested.  */
2094 	  gfc_trans_array_constructor_value (&body, type, desc,
2095 					     c->expr->value.constructor,
2096 					     poffset, offsetvar, dynamic);
2097 	}
2098       else if (c->expr->rank > 0)
2099 	{
2100 	  gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
2101 						poffset, offsetvar, dynamic);
2102 	}
2103       else
2104 	{
2105 	  /* This code really upsets the gimplifier so don't bother for now.  */
2106 	  gfc_constructor *p;
2107 	  HOST_WIDE_INT n;
2108 	  HOST_WIDE_INT size;
2109 
2110 	  p = c;
2111 	  n = 0;
2112 	  while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
2113 	    {
2114 	      p = gfc_constructor_next (p);
2115 	      n++;
2116 	    }
2117 	  if (n < 4)
2118 	    {
2119 	      /* Scalar values.  */
2120 	      gfc_init_se (&se, NULL);
2121 	      gfc_trans_array_ctor_element (&body, desc, *poffset,
2122 					    &se, c->expr);
2123 
2124 	      *poffset = fold_build2_loc (input_location, PLUS_EXPR,
2125 					  gfc_array_index_type,
2126 					  *poffset, gfc_index_one_node);
2127 	    }
2128 	  else
2129 	    {
2130 	      /* Collect multiple scalar constants into a constructor.  */
2131 	      vec<constructor_elt, va_gc> *v = NULL;
2132 	      tree init;
2133 	      tree bound;
2134 	      tree tmptype;
2135 	      HOST_WIDE_INT idx = 0;
2136 
2137 	      p = c;
2138               /* Count the number of consecutive scalar constants.  */
2139 	      while (p && !(p->iterator
2140 			    || p->expr->expr_type != EXPR_CONSTANT))
2141 		{
2142 		  gfc_init_se (&se, NULL);
2143 		  gfc_conv_constant (&se, p->expr);
2144 
2145 		  if (c->expr->ts.type != BT_CHARACTER)
2146 		    se.expr = fold_convert (type, se.expr);
2147 		  /* For constant character array constructors we build
2148 		     an array of pointers.  */
2149 		  else if (POINTER_TYPE_P (type))
2150 		    se.expr = gfc_build_addr_expr
2151 				(gfc_get_pchar_type (p->expr->ts.kind),
2152 				 se.expr);
2153 
2154                   CONSTRUCTOR_APPEND_ELT (v,
2155                                           build_int_cst (gfc_array_index_type,
2156                                                          idx++),
2157                                           se.expr);
2158 		  c = p;
2159 		  p = gfc_constructor_next (p);
2160 		}
2161 
2162 	      bound = size_int (n - 1);
2163               /* Create an array type to hold them.  */
2164 	      tmptype = build_range_type (gfc_array_index_type,
2165 					  gfc_index_zero_node, bound);
2166 	      tmptype = build_array_type (type, tmptype);
2167 
2168 	      init = build_constructor (tmptype, v);
2169 	      TREE_CONSTANT (init) = 1;
2170 	      TREE_STATIC (init) = 1;
2171 	      /* Create a static variable to hold the data.  */
2172 	      tmp = gfc_create_var (tmptype, "data");
2173 	      TREE_STATIC (tmp) = 1;
2174 	      TREE_CONSTANT (tmp) = 1;
2175 	      TREE_READONLY (tmp) = 1;
2176 	      DECL_INITIAL (tmp) = init;
2177 	      init = tmp;
2178 
2179 	      /* Use BUILTIN_MEMCPY to assign the values.  */
2180 	      tmp = gfc_conv_descriptor_data_get (desc);
2181 	      tmp = build_fold_indirect_ref_loc (input_location,
2182 					     tmp);
2183 	      tmp = gfc_build_array_ref (tmp, *poffset, NULL);
2184 	      tmp = gfc_build_addr_expr (NULL_TREE, tmp);
2185 	      init = gfc_build_addr_expr (NULL_TREE, init);
2186 
2187 	      size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
2188 	      bound = build_int_cst (size_type_node, n * size);
2189 	      tmp = build_call_expr_loc (input_location,
2190 					 builtin_decl_explicit (BUILT_IN_MEMCPY),
2191 					 3, tmp, init, bound);
2192 	      gfc_add_expr_to_block (&body, tmp);
2193 
2194 	      *poffset = fold_build2_loc (input_location, PLUS_EXPR,
2195 				      gfc_array_index_type, *poffset,
2196 				      build_int_cst (gfc_array_index_type, n));
2197 	    }
2198 	  if (!INTEGER_CST_P (*poffset))
2199             {
2200               gfc_add_modify (&body, *offsetvar, *poffset);
2201               *poffset = *offsetvar;
2202             }
2203 	}
2204 
2205       /* The frontend should already have done any expansions
2206 	 at compile-time.  */
2207       if (!c->iterator)
2208 	{
2209 	  /* Pass the code as is.  */
2210 	  tmp = gfc_finish_block (&body);
2211 	  gfc_add_expr_to_block (pblock, tmp);
2212 	}
2213       else
2214 	{
2215 	  /* Build the implied do-loop.  */
2216 	  stmtblock_t implied_do_block;
2217 	  tree cond;
2218 	  tree exit_label;
2219 	  tree loopbody;
2220 	  tree tmp2;
2221 
2222 	  loopbody = gfc_finish_block (&body);
2223 
2224 	  /* Create a new block that holds the implied-do loop. A temporary
2225 	     loop-variable is used.  */
2226 	  gfc_start_block(&implied_do_block);
2227 
2228 	  /* Initialize the loop.  */
2229 	  gfc_add_modify (&implied_do_block, shadow_loopvar, start);
2230 
2231 	  /* If this array expands dynamically, and the number of iterations
2232 	     is not constant, we won't have allocated space for the static
2233 	     part of C->EXPR's size.  Do that now.  */
2234 	  if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
2235 	    {
2236 	      /* Get the number of iterations.  */
2237 	      tmp = gfc_get_iteration_count (shadow_loopvar, end, step);
2238 
2239 	      /* Get the static part of C->EXPR's size.  */
2240 	      gfc_get_array_constructor_element_size (&size, c->expr);
2241 	      tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
2242 
2243 	      /* Grow the array by TMP * TMP2 elements.  */
2244 	      tmp = fold_build2_loc (input_location, MULT_EXPR,
2245 				     gfc_array_index_type, tmp, tmp2);
2246 	      gfc_grow_array (&implied_do_block, desc, tmp);
2247 	    }
2248 
2249 	  /* Generate the loop body.  */
2250 	  exit_label = gfc_build_label_decl (NULL_TREE);
2251 	  gfc_start_block (&body);
2252 
2253 	  /* Generate the exit condition.  Depending on the sign of
2254 	     the step variable we have to generate the correct
2255 	     comparison.  */
2256 	  tmp = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
2257 				 step, build_int_cst (TREE_TYPE (step), 0));
2258 	  cond = fold_build3_loc (input_location, COND_EXPR,
2259 		      logical_type_node, tmp,
2260 		      fold_build2_loc (input_location, GT_EXPR,
2261 				       logical_type_node, shadow_loopvar, end),
2262 		      fold_build2_loc (input_location, LT_EXPR,
2263 				       logical_type_node, shadow_loopvar, end));
2264 	  tmp = build1_v (GOTO_EXPR, exit_label);
2265 	  TREE_USED (exit_label) = 1;
2266 	  tmp = build3_v (COND_EXPR, cond, tmp,
2267 			  build_empty_stmt (input_location));
2268 	  gfc_add_expr_to_block (&body, tmp);
2269 
2270 	  /* The main loop body.  */
2271 	  gfc_add_expr_to_block (&body, loopbody);
2272 
2273 	  /* Increase loop variable by step.  */
2274 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
2275 				 TREE_TYPE (shadow_loopvar), shadow_loopvar,
2276 				 step);
2277 	  gfc_add_modify (&body, shadow_loopvar, tmp);
2278 
2279 	  /* Finish the loop.  */
2280 	  tmp = gfc_finish_block (&body);
2281 	  tmp = build1_v (LOOP_EXPR, tmp);
2282 	  gfc_add_expr_to_block (&implied_do_block, tmp);
2283 
2284 	  /* Add the exit label.  */
2285 	  tmp = build1_v (LABEL_EXPR, exit_label);
2286 	  gfc_add_expr_to_block (&implied_do_block, tmp);
2287 
2288 	  /* Finish the implied-do loop.  */
2289 	  tmp = gfc_finish_block(&implied_do_block);
2290 	  gfc_add_expr_to_block(pblock, tmp);
2291 
2292 	  gfc_restore_sym (c->iterator->var->symtree->n.sym, &saved_loopvar);
2293 	}
2294     }
2295   mpz_clear (size);
2296 }
2297 
2298 
2299 /* The array constructor code can create a string length with an operand
2300    in the form of a temporary variable.  This variable will retain its
2301    context (current_function_decl).  If we store this length tree in a
2302    gfc_charlen structure which is shared by a variable in another
2303    context, the resulting gfc_charlen structure with a variable in a
2304    different context, we could trip the assertion in expand_expr_real_1
2305    when it sees that a variable has been created in one context and
2306    referenced in another.
2307 
2308    If this might be the case, we create a new gfc_charlen structure and
2309    link it into the current namespace.  */
2310 
2311 static void
store_backend_decl(gfc_charlen ** clp,tree len,bool force_new_cl)2312 store_backend_decl (gfc_charlen **clp, tree len, bool force_new_cl)
2313 {
2314   if (force_new_cl)
2315     {
2316       gfc_charlen *new_cl = gfc_new_charlen (gfc_current_ns, *clp);
2317       *clp = new_cl;
2318     }
2319   (*clp)->backend_decl = len;
2320 }
2321 
2322 /* A catch-all to obtain the string length for anything that is not
2323    a substring of non-constant length, a constant, array or variable.  */
2324 
2325 static void
get_array_ctor_all_strlen(stmtblock_t * block,gfc_expr * e,tree * len)2326 get_array_ctor_all_strlen (stmtblock_t *block, gfc_expr *e, tree *len)
2327 {
2328   gfc_se se;
2329 
2330   /* Don't bother if we already know the length is a constant.  */
2331   if (*len && INTEGER_CST_P (*len))
2332     return;
2333 
2334   if (!e->ref && e->ts.u.cl && e->ts.u.cl->length
2335 	&& e->ts.u.cl->length->expr_type == EXPR_CONSTANT)
2336     {
2337       /* This is easy.  */
2338       gfc_conv_const_charlen (e->ts.u.cl);
2339       *len = e->ts.u.cl->backend_decl;
2340     }
2341   else
2342     {
2343       /* Otherwise, be brutal even if inefficient.  */
2344       gfc_init_se (&se, NULL);
2345 
2346       /* No function call, in case of side effects.  */
2347       se.no_function_call = 1;
2348       if (e->rank == 0)
2349 	gfc_conv_expr (&se, e);
2350       else
2351 	gfc_conv_expr_descriptor (&se, e);
2352 
2353       /* Fix the value.  */
2354       *len = gfc_evaluate_now (se.string_length, &se.pre);
2355 
2356       gfc_add_block_to_block (block, &se.pre);
2357       gfc_add_block_to_block (block, &se.post);
2358 
2359       store_backend_decl (&e->ts.u.cl, *len, true);
2360     }
2361 }
2362 
2363 
2364 /* Figure out the string length of a variable reference expression.
2365    Used by get_array_ctor_strlen.  */
2366 
2367 static void
get_array_ctor_var_strlen(stmtblock_t * block,gfc_expr * expr,tree * len)2368 get_array_ctor_var_strlen (stmtblock_t *block, gfc_expr * expr, tree * len)
2369 {
2370   gfc_ref *ref;
2371   gfc_typespec *ts;
2372   mpz_t char_len;
2373   gfc_se se;
2374 
2375   /* Don't bother if we already know the length is a constant.  */
2376   if (*len && INTEGER_CST_P (*len))
2377     return;
2378 
2379   ts = &expr->symtree->n.sym->ts;
2380   for (ref = expr->ref; ref; ref = ref->next)
2381     {
2382       switch (ref->type)
2383 	{
2384 	case REF_ARRAY:
2385 	  /* Array references don't change the string length.  */
2386 	  if (ts->deferred)
2387 	    get_array_ctor_all_strlen (block, expr, len);
2388 	  break;
2389 
2390 	case REF_COMPONENT:
2391 	  /* Use the length of the component.  */
2392 	  ts = &ref->u.c.component->ts;
2393 	  break;
2394 
2395 	case REF_SUBSTRING:
2396 	  if (ref->u.ss.end == NULL
2397 	      || ref->u.ss.start->expr_type != EXPR_CONSTANT
2398 	      || ref->u.ss.end->expr_type != EXPR_CONSTANT)
2399 	    {
2400 	      /* Note that this might evaluate expr.  */
2401 	      get_array_ctor_all_strlen (block, expr, len);
2402 	      return;
2403 	    }
2404 	  mpz_init_set_ui (char_len, 1);
2405 	  mpz_add (char_len, char_len, ref->u.ss.end->value.integer);
2406 	  mpz_sub (char_len, char_len, ref->u.ss.start->value.integer);
2407 	  *len = gfc_conv_mpz_to_tree_type (char_len, gfc_charlen_type_node);
2408 	  mpz_clear (char_len);
2409 	  return;
2410 
2411 	case REF_INQUIRY:
2412 	  break;
2413 
2414 	default:
2415 	 gcc_unreachable ();
2416 	}
2417     }
2418 
2419   /* A last ditch attempt that is sometimes needed for deferred characters.  */
2420   if (!ts->u.cl->backend_decl)
2421     {
2422       gfc_init_se (&se, NULL);
2423       if (expr->rank)
2424 	gfc_conv_expr_descriptor (&se, expr);
2425       else
2426 	gfc_conv_expr (&se, expr);
2427       gcc_assert (se.string_length != NULL_TREE);
2428       gfc_add_block_to_block (block, &se.pre);
2429       ts->u.cl->backend_decl = se.string_length;
2430     }
2431 
2432   *len = ts->u.cl->backend_decl;
2433 }
2434 
2435 
2436 /* Figure out the string length of a character array constructor.
2437    If len is NULL, don't calculate the length; this happens for recursive calls
2438    when a sub-array-constructor is an element but not at the first position,
2439    so when we're not interested in the length.
2440    Returns TRUE if all elements are character constants.  */
2441 
2442 bool
get_array_ctor_strlen(stmtblock_t * block,gfc_constructor_base base,tree * len)2443 get_array_ctor_strlen (stmtblock_t *block, gfc_constructor_base base, tree * len)
2444 {
2445   gfc_constructor *c;
2446   bool is_const;
2447 
2448   is_const = TRUE;
2449 
2450   if (gfc_constructor_first (base) == NULL)
2451     {
2452       if (len)
2453 	*len = build_int_cstu (gfc_charlen_type_node, 0);
2454       return is_const;
2455     }
2456 
2457   /* Loop over all constructor elements to find out is_const, but in len we
2458      want to store the length of the first, not the last, element.  We can
2459      of course exit the loop as soon as is_const is found to be false.  */
2460   for (c = gfc_constructor_first (base);
2461        c && is_const; c = gfc_constructor_next (c))
2462     {
2463       switch (c->expr->expr_type)
2464 	{
2465 	case EXPR_CONSTANT:
2466 	  if (len && !(*len && INTEGER_CST_P (*len)))
2467 	    *len = build_int_cstu (gfc_charlen_type_node,
2468 				   c->expr->value.character.length);
2469 	  break;
2470 
2471 	case EXPR_ARRAY:
2472 	  if (!get_array_ctor_strlen (block, c->expr->value.constructor, len))
2473 	    is_const = false;
2474 	  break;
2475 
2476 	case EXPR_VARIABLE:
2477 	  is_const = false;
2478 	  if (len)
2479 	    get_array_ctor_var_strlen (block, c->expr, len);
2480 	  break;
2481 
2482 	default:
2483 	  is_const = false;
2484 	  if (len)
2485 	    get_array_ctor_all_strlen (block, c->expr, len);
2486 	  break;
2487 	}
2488 
2489       /* After the first iteration, we don't want the length modified.  */
2490       len = NULL;
2491     }
2492 
2493   return is_const;
2494 }
2495 
2496 /* Check whether the array constructor C consists entirely of constant
2497    elements, and if so returns the number of those elements, otherwise
2498    return zero.  Note, an empty or NULL array constructor returns zero.  */
2499 
2500 unsigned HOST_WIDE_INT
gfc_constant_array_constructor_p(gfc_constructor_base base)2501 gfc_constant_array_constructor_p (gfc_constructor_base base)
2502 {
2503   unsigned HOST_WIDE_INT nelem = 0;
2504 
2505   gfc_constructor *c = gfc_constructor_first (base);
2506   while (c)
2507     {
2508       if (c->iterator
2509 	  || c->expr->rank > 0
2510 	  || c->expr->expr_type != EXPR_CONSTANT)
2511 	return 0;
2512       c = gfc_constructor_next (c);
2513       nelem++;
2514     }
2515   return nelem;
2516 }
2517 
2518 
2519 /* Given EXPR, the constant array constructor specified by an EXPR_ARRAY,
2520    and the tree type of it's elements, TYPE, return a static constant
2521    variable that is compile-time initialized.  */
2522 
2523 tree
gfc_build_constant_array_constructor(gfc_expr * expr,tree type)2524 gfc_build_constant_array_constructor (gfc_expr * expr, tree type)
2525 {
2526   tree tmptype, init, tmp;
2527   HOST_WIDE_INT nelem;
2528   gfc_constructor *c;
2529   gfc_array_spec as;
2530   gfc_se se;
2531   int i;
2532   vec<constructor_elt, va_gc> *v = NULL;
2533 
2534   /* First traverse the constructor list, converting the constants
2535      to tree to build an initializer.  */
2536   nelem = 0;
2537   c = gfc_constructor_first (expr->value.constructor);
2538   while (c)
2539     {
2540       gfc_init_se (&se, NULL);
2541       gfc_conv_constant (&se, c->expr);
2542       if (c->expr->ts.type != BT_CHARACTER)
2543 	se.expr = fold_convert (type, se.expr);
2544       else if (POINTER_TYPE_P (type))
2545 	se.expr = gfc_build_addr_expr (gfc_get_pchar_type (c->expr->ts.kind),
2546 				       se.expr);
2547       CONSTRUCTOR_APPEND_ELT (v, build_int_cst (gfc_array_index_type, nelem),
2548                               se.expr);
2549       c = gfc_constructor_next (c);
2550       nelem++;
2551     }
2552 
2553   /* Next determine the tree type for the array.  We use the gfortran
2554      front-end's gfc_get_nodesc_array_type in order to create a suitable
2555      GFC_ARRAY_TYPE_P that may be used by the scalarizer.  */
2556 
2557   memset (&as, 0, sizeof (gfc_array_spec));
2558 
2559   as.rank = expr->rank;
2560   as.type = AS_EXPLICIT;
2561   if (!expr->shape)
2562     {
2563       as.lower[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
2564       as.upper[0] = gfc_get_int_expr (gfc_default_integer_kind,
2565 				      NULL, nelem - 1);
2566     }
2567   else
2568     for (i = 0; i < expr->rank; i++)
2569       {
2570 	int tmp = (int) mpz_get_si (expr->shape[i]);
2571         as.lower[i] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
2572         as.upper[i] = gfc_get_int_expr (gfc_default_integer_kind,
2573 					NULL, tmp - 1);
2574       }
2575 
2576   tmptype = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC, true);
2577 
2578   /* as is not needed anymore.  */
2579   for (i = 0; i < as.rank + as.corank; i++)
2580     {
2581       gfc_free_expr (as.lower[i]);
2582       gfc_free_expr (as.upper[i]);
2583     }
2584 
2585   init = build_constructor (tmptype, v);
2586 
2587   TREE_CONSTANT (init) = 1;
2588   TREE_STATIC (init) = 1;
2589 
2590   tmp = build_decl (input_location, VAR_DECL, create_tmp_var_name ("A"),
2591 		    tmptype);
2592   DECL_ARTIFICIAL (tmp) = 1;
2593   DECL_IGNORED_P (tmp) = 1;
2594   TREE_STATIC (tmp) = 1;
2595   TREE_CONSTANT (tmp) = 1;
2596   TREE_READONLY (tmp) = 1;
2597   DECL_INITIAL (tmp) = init;
2598   pushdecl (tmp);
2599 
2600   return tmp;
2601 }
2602 
2603 
2604 /* Translate a constant EXPR_ARRAY array constructor for the scalarizer.
2605    This mostly initializes the scalarizer state info structure with the
2606    appropriate values to directly use the array created by the function
2607    gfc_build_constant_array_constructor.  */
2608 
2609 static void
trans_constant_array_constructor(gfc_ss * ss,tree type)2610 trans_constant_array_constructor (gfc_ss * ss, tree type)
2611 {
2612   gfc_array_info *info;
2613   tree tmp;
2614   int i;
2615 
2616   tmp = gfc_build_constant_array_constructor (ss->info->expr, type);
2617 
2618   info = &ss->info->data.array;
2619 
2620   info->descriptor = tmp;
2621   info->data = gfc_build_addr_expr (NULL_TREE, tmp);
2622   info->offset = gfc_index_zero_node;
2623 
2624   for (i = 0; i < ss->dimen; i++)
2625     {
2626       info->delta[i] = gfc_index_zero_node;
2627       info->start[i] = gfc_index_zero_node;
2628       info->end[i] = gfc_index_zero_node;
2629       info->stride[i] = gfc_index_one_node;
2630     }
2631 }
2632 
2633 
2634 static int
get_rank(gfc_loopinfo * loop)2635 get_rank (gfc_loopinfo *loop)
2636 {
2637   int rank;
2638 
2639   rank = 0;
2640   for (; loop; loop = loop->parent)
2641     rank += loop->dimen;
2642 
2643   return rank;
2644 }
2645 
2646 
2647 /* Helper routine of gfc_trans_array_constructor to determine if the
2648    bounds of the loop specified by LOOP are constant and simple enough
2649    to use with trans_constant_array_constructor.  Returns the
2650    iteration count of the loop if suitable, and NULL_TREE otherwise.  */
2651 
2652 static tree
constant_array_constructor_loop_size(gfc_loopinfo * l)2653 constant_array_constructor_loop_size (gfc_loopinfo * l)
2654 {
2655   gfc_loopinfo *loop;
2656   tree size = gfc_index_one_node;
2657   tree tmp;
2658   int i, total_dim;
2659 
2660   total_dim = get_rank (l);
2661 
2662   for (loop = l; loop; loop = loop->parent)
2663     {
2664       for (i = 0; i < loop->dimen; i++)
2665 	{
2666 	  /* If the bounds aren't constant, return NULL_TREE.  */
2667 	  if (!INTEGER_CST_P (loop->from[i]) || !INTEGER_CST_P (loop->to[i]))
2668 	    return NULL_TREE;
2669 	  if (!integer_zerop (loop->from[i]))
2670 	    {
2671 	      /* Only allow nonzero "from" in one-dimensional arrays.  */
2672 	      if (total_dim != 1)
2673 		return NULL_TREE;
2674 	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
2675 				     gfc_array_index_type,
2676 				     loop->to[i], loop->from[i]);
2677 	    }
2678 	  else
2679 	    tmp = loop->to[i];
2680 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
2681 				 gfc_array_index_type, tmp, gfc_index_one_node);
2682 	  size = fold_build2_loc (input_location, MULT_EXPR,
2683 				  gfc_array_index_type, size, tmp);
2684 	}
2685     }
2686 
2687   return size;
2688 }
2689 
2690 
2691 static tree *
get_loop_upper_bound_for_array(gfc_ss * array,int array_dim)2692 get_loop_upper_bound_for_array (gfc_ss *array, int array_dim)
2693 {
2694   gfc_ss *ss;
2695   int n;
2696 
2697   gcc_assert (array->nested_ss == NULL);
2698 
2699   for (ss = array; ss; ss = ss->parent)
2700     for (n = 0; n < ss->loop->dimen; n++)
2701       if (array_dim == get_array_ref_dim_for_loop_dim (ss, n))
2702 	return &(ss->loop->to[n]);
2703 
2704   gcc_unreachable ();
2705 }
2706 
2707 
2708 static gfc_loopinfo *
outermost_loop(gfc_loopinfo * loop)2709 outermost_loop (gfc_loopinfo * loop)
2710 {
2711   while (loop->parent != NULL)
2712     loop = loop->parent;
2713 
2714   return loop;
2715 }
2716 
2717 
2718 /* Array constructors are handled by constructing a temporary, then using that
2719    within the scalarization loop.  This is not optimal, but seems by far the
2720    simplest method.  */
2721 
2722 static void
trans_array_constructor(gfc_ss * ss,locus * where)2723 trans_array_constructor (gfc_ss * ss, locus * where)
2724 {
2725   gfc_constructor_base c;
2726   tree offset;
2727   tree offsetvar;
2728   tree desc;
2729   tree type;
2730   tree tmp;
2731   tree *loop_ubound0;
2732   bool dynamic;
2733   bool old_first_len, old_typespec_chararray_ctor;
2734   tree old_first_len_val;
2735   gfc_loopinfo *loop, *outer_loop;
2736   gfc_ss_info *ss_info;
2737   gfc_expr *expr;
2738   gfc_ss *s;
2739   tree neg_len;
2740   char *msg;
2741 
2742   /* Save the old values for nested checking.  */
2743   old_first_len = first_len;
2744   old_first_len_val = first_len_val;
2745   old_typespec_chararray_ctor = typespec_chararray_ctor;
2746 
2747   loop = ss->loop;
2748   outer_loop = outermost_loop (loop);
2749   ss_info = ss->info;
2750   expr = ss_info->expr;
2751 
2752   /* Do bounds-checking here and in gfc_trans_array_ctor_element only if no
2753      typespec was given for the array constructor.  */
2754   typespec_chararray_ctor = (expr->ts.type == BT_CHARACTER
2755 			     && expr->ts.u.cl
2756 			     && expr->ts.u.cl->length_from_typespec);
2757 
2758   if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2759       && expr->ts.type == BT_CHARACTER && !typespec_chararray_ctor)
2760     {
2761       first_len_val = gfc_create_var (gfc_charlen_type_node, "len");
2762       first_len = true;
2763     }
2764 
2765   gcc_assert (ss->dimen == ss->loop->dimen);
2766 
2767   c = expr->value.constructor;
2768   if (expr->ts.type == BT_CHARACTER)
2769     {
2770       bool const_string;
2771       bool force_new_cl = false;
2772 
2773       /* get_array_ctor_strlen walks the elements of the constructor, if a
2774 	 typespec was given, we already know the string length and want the one
2775 	 specified there.  */
2776       if (typespec_chararray_ctor && expr->ts.u.cl->length
2777 	  && expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
2778 	{
2779 	  gfc_se length_se;
2780 
2781 	  const_string = false;
2782 	  gfc_init_se (&length_se, NULL);
2783 	  gfc_conv_expr_type (&length_se, expr->ts.u.cl->length,
2784 			      gfc_charlen_type_node);
2785 	  ss_info->string_length = length_se.expr;
2786 
2787 	  /* Check if the character length is negative.  If it is, then
2788 	     set LEN = 0.  */
2789 	  neg_len = fold_build2_loc (input_location, LT_EXPR,
2790 				     logical_type_node, ss_info->string_length,
2791 				     build_zero_cst (TREE_TYPE
2792 						     (ss_info->string_length)));
2793 	  /* Print a warning if bounds checking is enabled.  */
2794 	  if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2795 	    {
2796 	      msg = xasprintf ("Negative character length treated as LEN = 0");
2797 	      gfc_trans_runtime_check (false, true, neg_len, &length_se.pre,
2798 				       where, msg);
2799 	      free (msg);
2800 	    }
2801 
2802 	  ss_info->string_length
2803 	    = fold_build3_loc (input_location, COND_EXPR,
2804 			       gfc_charlen_type_node, neg_len,
2805 			       build_zero_cst
2806 			       (TREE_TYPE (ss_info->string_length)),
2807 			       ss_info->string_length);
2808 	  ss_info->string_length = gfc_evaluate_now (ss_info->string_length,
2809 						     &length_se.pre);
2810 	  gfc_add_block_to_block (&outer_loop->pre, &length_se.pre);
2811 	  gfc_add_block_to_block (&outer_loop->post, &length_se.post);
2812 	}
2813       else
2814 	{
2815 	  const_string = get_array_ctor_strlen (&outer_loop->pre, c,
2816 						&ss_info->string_length);
2817 	  force_new_cl = true;
2818 	}
2819 
2820       /* Complex character array constructors should have been taken care of
2821 	 and not end up here.  */
2822       gcc_assert (ss_info->string_length);
2823 
2824       store_backend_decl (&expr->ts.u.cl, ss_info->string_length, force_new_cl);
2825 
2826       type = gfc_get_character_type_len (expr->ts.kind, ss_info->string_length);
2827       if (const_string)
2828 	type = build_pointer_type (type);
2829     }
2830   else
2831     type = gfc_typenode_for_spec (expr->ts.type == BT_CLASS
2832 				  ? &CLASS_DATA (expr)->ts : &expr->ts);
2833 
2834   /* See if the constructor determines the loop bounds.  */
2835   dynamic = false;
2836 
2837   loop_ubound0 = get_loop_upper_bound_for_array (ss, 0);
2838 
2839   if (expr->shape && get_rank (loop) > 1 && *loop_ubound0 == NULL_TREE)
2840     {
2841       /* We have a multidimensional parameter.  */
2842       for (s = ss; s; s = s->parent)
2843 	{
2844 	  int n;
2845 	  for (n = 0; n < s->loop->dimen; n++)
2846 	    {
2847 	      s->loop->from[n] = gfc_index_zero_node;
2848 	      s->loop->to[n] = gfc_conv_mpz_to_tree (expr->shape[s->dim[n]],
2849 						     gfc_index_integer_kind);
2850 	      s->loop->to[n] = fold_build2_loc (input_location, MINUS_EXPR,
2851 						gfc_array_index_type,
2852 						s->loop->to[n],
2853 						gfc_index_one_node);
2854 	    }
2855 	}
2856     }
2857 
2858   if (*loop_ubound0 == NULL_TREE)
2859     {
2860       mpz_t size;
2861 
2862       /* We should have a 1-dimensional, zero-based loop.  */
2863       gcc_assert (loop->parent == NULL && loop->nested == NULL);
2864       gcc_assert (loop->dimen == 1);
2865       gcc_assert (integer_zerop (loop->from[0]));
2866 
2867       /* Split the constructor size into a static part and a dynamic part.
2868 	 Allocate the static size up-front and record whether the dynamic
2869 	 size might be nonzero.  */
2870       mpz_init (size);
2871       dynamic = gfc_get_array_constructor_size (&size, c);
2872       mpz_sub_ui (size, size, 1);
2873       loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
2874       mpz_clear (size);
2875     }
2876 
2877   /* Special case constant array constructors.  */
2878   if (!dynamic)
2879     {
2880       unsigned HOST_WIDE_INT nelem = gfc_constant_array_constructor_p (c);
2881       if (nelem > 0)
2882 	{
2883 	  tree size = constant_array_constructor_loop_size (loop);
2884 	  if (size && compare_tree_int (size, nelem) == 0)
2885 	    {
2886 	      trans_constant_array_constructor (ss, type);
2887 	      goto finish;
2888 	    }
2889 	}
2890     }
2891 
2892   gfc_trans_create_temp_array (&outer_loop->pre, &outer_loop->post, ss, type,
2893 			       NULL_TREE, dynamic, true, false, where);
2894 
2895   desc = ss_info->data.array.descriptor;
2896   offset = gfc_index_zero_node;
2897   offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
2898   suppress_warning (offsetvar);
2899   TREE_USED (offsetvar) = 0;
2900   gfc_trans_array_constructor_value (&outer_loop->pre, type, desc, c,
2901 				     &offset, &offsetvar, dynamic);
2902 
2903   /* If the array grows dynamically, the upper bound of the loop variable
2904      is determined by the array's final upper bound.  */
2905   if (dynamic)
2906     {
2907       tmp = fold_build2_loc (input_location, MINUS_EXPR,
2908 			     gfc_array_index_type,
2909 			     offsetvar, gfc_index_one_node);
2910       tmp = gfc_evaluate_now (tmp, &outer_loop->pre);
2911       gfc_conv_descriptor_ubound_set (&loop->pre, desc, gfc_rank_cst[0], tmp);
2912       if (*loop_ubound0 && VAR_P (*loop_ubound0))
2913 	gfc_add_modify (&outer_loop->pre, *loop_ubound0, tmp);
2914       else
2915 	*loop_ubound0 = tmp;
2916     }
2917 
2918   if (TREE_USED (offsetvar))
2919     pushdecl (offsetvar);
2920   else
2921     gcc_assert (INTEGER_CST_P (offset));
2922 
2923 #if 0
2924   /* Disable bound checking for now because it's probably broken.  */
2925   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2926     {
2927       gcc_unreachable ();
2928     }
2929 #endif
2930 
2931 finish:
2932   /* Restore old values of globals.  */
2933   first_len = old_first_len;
2934   first_len_val = old_first_len_val;
2935   typespec_chararray_ctor = old_typespec_chararray_ctor;
2936 }
2937 
2938 
2939 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
2940    called after evaluating all of INFO's vector dimensions.  Go through
2941    each such vector dimension and see if we can now fill in any missing
2942    loop bounds.  */
2943 
2944 static void
set_vector_loop_bounds(gfc_ss * ss)2945 set_vector_loop_bounds (gfc_ss * ss)
2946 {
2947   gfc_loopinfo *loop, *outer_loop;
2948   gfc_array_info *info;
2949   gfc_se se;
2950   tree tmp;
2951   tree desc;
2952   tree zero;
2953   int n;
2954   int dim;
2955 
2956   outer_loop = outermost_loop (ss->loop);
2957 
2958   info = &ss->info->data.array;
2959 
2960   for (; ss; ss = ss->parent)
2961     {
2962       loop = ss->loop;
2963 
2964       for (n = 0; n < loop->dimen; n++)
2965 	{
2966 	  dim = ss->dim[n];
2967 	  if (info->ref->u.ar.dimen_type[dim] != DIMEN_VECTOR
2968 	      || loop->to[n] != NULL)
2969 	    continue;
2970 
2971 	  /* Loop variable N indexes vector dimension DIM, and we don't
2972 	     yet know the upper bound of loop variable N.  Set it to the
2973 	     difference between the vector's upper and lower bounds.  */
2974 	  gcc_assert (loop->from[n] == gfc_index_zero_node);
2975 	  gcc_assert (info->subscript[dim]
2976 		      && info->subscript[dim]->info->type == GFC_SS_VECTOR);
2977 
2978 	  gfc_init_se (&se, NULL);
2979 	  desc = info->subscript[dim]->info->data.array.descriptor;
2980 	  zero = gfc_rank_cst[0];
2981 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
2982 			     gfc_array_index_type,
2983 			     gfc_conv_descriptor_ubound_get (desc, zero),
2984 			     gfc_conv_descriptor_lbound_get (desc, zero));
2985 	  tmp = gfc_evaluate_now (tmp, &outer_loop->pre);
2986 	  loop->to[n] = tmp;
2987 	}
2988     }
2989 }
2990 
2991 
2992 /* Tells whether a scalar argument to an elemental procedure is saved out
2993    of a scalarization loop as a value or as a reference.  */
2994 
2995 bool
gfc_scalar_elemental_arg_saved_as_reference(gfc_ss_info * ss_info)2996 gfc_scalar_elemental_arg_saved_as_reference (gfc_ss_info * ss_info)
2997 {
2998   if (ss_info->type != GFC_SS_REFERENCE)
2999     return false;
3000 
3001   if (ss_info->data.scalar.needs_temporary)
3002     return false;
3003 
3004   /* If the actual argument can be absent (in other words, it can
3005      be a NULL reference), don't try to evaluate it; pass instead
3006      the reference directly.  */
3007   if (ss_info->can_be_null_ref)
3008     return true;
3009 
3010   /* If the expression is of polymorphic type, it's actual size is not known,
3011      so we avoid copying it anywhere.  */
3012   if (ss_info->data.scalar.dummy_arg
3013       && gfc_dummy_arg_get_typespec (*ss_info->data.scalar.dummy_arg).type
3014 	 == BT_CLASS
3015       && ss_info->expr->ts.type == BT_CLASS)
3016     return true;
3017 
3018   /* If the expression is a data reference of aggregate type,
3019      and the data reference is not used on the left hand side,
3020      avoid a copy by saving a reference to the content.  */
3021   if (!ss_info->data.scalar.needs_temporary
3022       && (ss_info->expr->ts.type == BT_DERIVED
3023 	  || ss_info->expr->ts.type == BT_CLASS)
3024       && gfc_expr_is_variable (ss_info->expr))
3025     return true;
3026 
3027   /* Otherwise the expression is evaluated to a temporary variable before the
3028      scalarization loop.  */
3029   return false;
3030 }
3031 
3032 
3033 /* Add the pre and post chains for all the scalar expressions in a SS chain
3034    to loop.  This is called after the loop parameters have been calculated,
3035    but before the actual scalarizing loops.  */
3036 
3037 static void
gfc_add_loop_ss_code(gfc_loopinfo * loop,gfc_ss * ss,bool subscript,locus * where)3038 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript,
3039 		      locus * where)
3040 {
3041   gfc_loopinfo *nested_loop, *outer_loop;
3042   gfc_se se;
3043   gfc_ss_info *ss_info;
3044   gfc_array_info *info;
3045   gfc_expr *expr;
3046   int n;
3047 
3048   /* Don't evaluate the arguments for realloc_lhs_loop_for_fcn_call; otherwise,
3049      arguments could get evaluated multiple times.  */
3050   if (ss->is_alloc_lhs)
3051     return;
3052 
3053   outer_loop = outermost_loop (loop);
3054 
3055   /* TODO: This can generate bad code if there are ordering dependencies,
3056      e.g., a callee allocated function and an unknown size constructor.  */
3057   gcc_assert (ss != NULL);
3058 
3059   for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
3060     {
3061       gcc_assert (ss);
3062 
3063       /* Cross loop arrays are handled from within the most nested loop.  */
3064       if (ss->nested_ss != NULL)
3065 	continue;
3066 
3067       ss_info = ss->info;
3068       expr = ss_info->expr;
3069       info = &ss_info->data.array;
3070 
3071       switch (ss_info->type)
3072 	{
3073 	case GFC_SS_SCALAR:
3074 	  /* Scalar expression.  Evaluate this now.  This includes elemental
3075 	     dimension indices, but not array section bounds.  */
3076 	  gfc_init_se (&se, NULL);
3077 	  gfc_conv_expr (&se, expr);
3078 	  gfc_add_block_to_block (&outer_loop->pre, &se.pre);
3079 
3080 	  if (expr->ts.type != BT_CHARACTER
3081 	      && !gfc_is_alloc_class_scalar_function (expr))
3082 	    {
3083 	      /* Move the evaluation of scalar expressions outside the
3084 		 scalarization loop, except for WHERE assignments.  */
3085 	      if (subscript)
3086 		se.expr = convert(gfc_array_index_type, se.expr);
3087 	      if (!ss_info->where)
3088 		se.expr = gfc_evaluate_now (se.expr, &outer_loop->pre);
3089 	      gfc_add_block_to_block (&outer_loop->pre, &se.post);
3090 	    }
3091 	  else
3092 	    gfc_add_block_to_block (&outer_loop->post, &se.post);
3093 
3094 	  ss_info->data.scalar.value = se.expr;
3095 	  ss_info->string_length = se.string_length;
3096 	  break;
3097 
3098 	case GFC_SS_REFERENCE:
3099 	  /* Scalar argument to elemental procedure.  */
3100 	  gfc_init_se (&se, NULL);
3101 	  if (gfc_scalar_elemental_arg_saved_as_reference (ss_info))
3102 	    gfc_conv_expr_reference (&se, expr);
3103 	  else
3104 	    {
3105 	      /* Evaluate the argument outside the loop and pass
3106 		 a reference to the value.  */
3107 	      gfc_conv_expr (&se, expr);
3108 	    }
3109 
3110 	  /* Ensure that a pointer to the string is stored.  */
3111 	  if (expr->ts.type == BT_CHARACTER)
3112 	    gfc_conv_string_parameter (&se);
3113 
3114 	  gfc_add_block_to_block (&outer_loop->pre, &se.pre);
3115 	  gfc_add_block_to_block (&outer_loop->post, &se.post);
3116 	  if (gfc_is_class_scalar_expr (expr))
3117 	    /* This is necessary because the dynamic type will always be
3118 	       large than the declared type.  In consequence, assigning
3119 	       the value to a temporary could segfault.
3120 	       OOP-TODO: see if this is generally correct or is the value
3121 	       has to be written to an allocated temporary, whose address
3122 	       is passed via ss_info.  */
3123 	    ss_info->data.scalar.value = se.expr;
3124 	  else
3125 	    ss_info->data.scalar.value = gfc_evaluate_now (se.expr,
3126 							   &outer_loop->pre);
3127 
3128 	  ss_info->string_length = se.string_length;
3129 	  break;
3130 
3131 	case GFC_SS_SECTION:
3132 	  /* Add the expressions for scalar and vector subscripts.  */
3133 	  for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
3134 	    if (info->subscript[n])
3135 	      gfc_add_loop_ss_code (loop, info->subscript[n], true, where);
3136 
3137 	  set_vector_loop_bounds (ss);
3138 	  break;
3139 
3140 	case GFC_SS_VECTOR:
3141 	  /* Get the vector's descriptor and store it in SS.  */
3142 	  gfc_init_se (&se, NULL);
3143 	  gfc_conv_expr_descriptor (&se, expr);
3144 	  gfc_add_block_to_block (&outer_loop->pre, &se.pre);
3145 	  gfc_add_block_to_block (&outer_loop->post, &se.post);
3146 	  info->descriptor = se.expr;
3147 	  break;
3148 
3149 	case GFC_SS_INTRINSIC:
3150 	  gfc_add_intrinsic_ss_code (loop, ss);
3151 	  break;
3152 
3153 	case GFC_SS_FUNCTION:
3154 	  /* Array function return value.  We call the function and save its
3155 	     result in a temporary for use inside the loop.  */
3156 	  gfc_init_se (&se, NULL);
3157 	  se.loop = loop;
3158 	  se.ss = ss;
3159 	  if (gfc_is_class_array_function (expr))
3160 	    expr->must_finalize = 1;
3161 	  gfc_conv_expr (&se, expr);
3162 	  gfc_add_block_to_block (&outer_loop->pre, &se.pre);
3163 	  gfc_add_block_to_block (&outer_loop->post, &se.post);
3164 	  ss_info->string_length = se.string_length;
3165 	  break;
3166 
3167 	case GFC_SS_CONSTRUCTOR:
3168 	  if (expr->ts.type == BT_CHARACTER
3169 	      && ss_info->string_length == NULL
3170 	      && expr->ts.u.cl
3171 	      && expr->ts.u.cl->length
3172 	      && expr->ts.u.cl->length->expr_type == EXPR_CONSTANT)
3173 	    {
3174 	      gfc_init_se (&se, NULL);
3175 	      gfc_conv_expr_type (&se, expr->ts.u.cl->length,
3176 				  gfc_charlen_type_node);
3177 	      ss_info->string_length = se.expr;
3178 	      gfc_add_block_to_block (&outer_loop->pre, &se.pre);
3179 	      gfc_add_block_to_block (&outer_loop->post, &se.post);
3180 	    }
3181 	  trans_array_constructor (ss, where);
3182 	  break;
3183 
3184         case GFC_SS_TEMP:
3185 	case GFC_SS_COMPONENT:
3186           /* Do nothing.  These are handled elsewhere.  */
3187           break;
3188 
3189 	default:
3190 	  gcc_unreachable ();
3191 	}
3192     }
3193 
3194   if (!subscript)
3195     for (nested_loop = loop->nested; nested_loop;
3196 	 nested_loop = nested_loop->next)
3197       gfc_add_loop_ss_code (nested_loop, nested_loop->ss, subscript, where);
3198 }
3199 
3200 
3201 /* Translate expressions for the descriptor and data pointer of a SS.  */
3202 /*GCC ARRAYS*/
3203 
3204 static void
gfc_conv_ss_descriptor(stmtblock_t * block,gfc_ss * ss,int base)3205 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
3206 {
3207   gfc_se se;
3208   gfc_ss_info *ss_info;
3209   gfc_array_info *info;
3210   tree tmp;
3211 
3212   ss_info = ss->info;
3213   info = &ss_info->data.array;
3214 
3215   /* Get the descriptor for the array to be scalarized.  */
3216   gcc_assert (ss_info->expr->expr_type == EXPR_VARIABLE);
3217   gfc_init_se (&se, NULL);
3218   se.descriptor_only = 1;
3219   gfc_conv_expr_lhs (&se, ss_info->expr);
3220   gfc_add_block_to_block (block, &se.pre);
3221   info->descriptor = se.expr;
3222   ss_info->string_length = se.string_length;
3223 
3224   if (base)
3225     {
3226       if (ss_info->expr->ts.type == BT_CHARACTER && !ss_info->expr->ts.deferred
3227 	  && ss_info->expr->ts.u.cl->length == NULL)
3228 	{
3229 	  /* Emit a DECL_EXPR for the variable sized array type in
3230 	     GFC_TYPE_ARRAY_DATAPTR_TYPE so the gimplification of its type
3231 	     sizes works correctly.  */
3232 	  tree arraytype = TREE_TYPE (
3233 		GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (info->descriptor)));
3234 	  if (! TYPE_NAME (arraytype))
3235 	    TYPE_NAME (arraytype) = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
3236 						NULL_TREE, arraytype);
3237 	  gfc_add_expr_to_block (block, build1 (DECL_EXPR, arraytype,
3238 						TYPE_NAME (arraytype)));
3239 	}
3240       /* Also the data pointer.  */
3241       tmp = gfc_conv_array_data (se.expr);
3242       /* If this is a variable or address or a class array, use it directly.
3243          Otherwise we must evaluate it now to avoid breaking dependency
3244 	 analysis by pulling the expressions for elemental array indices
3245 	 inside the loop.  */
3246       if (!(DECL_P (tmp)
3247 	    || (TREE_CODE (tmp) == ADDR_EXPR
3248 		&& DECL_P (TREE_OPERAND (tmp, 0)))
3249 	    || (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
3250 		&& TREE_CODE (se.expr) == COMPONENT_REF
3251 		&& GFC_CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (se.expr, 0))))))
3252 	tmp = gfc_evaluate_now (tmp, block);
3253       info->data = tmp;
3254 
3255       tmp = gfc_conv_array_offset (se.expr);
3256       info->offset = gfc_evaluate_now (tmp, block);
3257 
3258       /* Make absolutely sure that the saved_offset is indeed saved
3259 	 so that the variable is still accessible after the loops
3260 	 are translated.  */
3261       info->saved_offset = info->offset;
3262     }
3263 }
3264 
3265 
3266 /* Initialize a gfc_loopinfo structure.  */
3267 
3268 void
gfc_init_loopinfo(gfc_loopinfo * loop)3269 gfc_init_loopinfo (gfc_loopinfo * loop)
3270 {
3271   int n;
3272 
3273   memset (loop, 0, sizeof (gfc_loopinfo));
3274   gfc_init_block (&loop->pre);
3275   gfc_init_block (&loop->post);
3276 
3277   /* Initially scalarize in order and default to no loop reversal.  */
3278   for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
3279     {
3280       loop->order[n] = n;
3281       loop->reverse[n] = GFC_INHIBIT_REVERSE;
3282     }
3283 
3284   loop->ss = gfc_ss_terminator;
3285 }
3286 
3287 
3288 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
3289    chain.  */
3290 
3291 void
gfc_copy_loopinfo_to_se(gfc_se * se,gfc_loopinfo * loop)3292 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
3293 {
3294   se->loop = loop;
3295 }
3296 
3297 
3298 /* Return an expression for the data pointer of an array.  */
3299 
3300 tree
gfc_conv_array_data(tree descriptor)3301 gfc_conv_array_data (tree descriptor)
3302 {
3303   tree type;
3304 
3305   type = TREE_TYPE (descriptor);
3306   if (GFC_ARRAY_TYPE_P (type))
3307     {
3308       if (TREE_CODE (type) == POINTER_TYPE)
3309         return descriptor;
3310       else
3311         {
3312           /* Descriptorless arrays.  */
3313 	  return gfc_build_addr_expr (NULL_TREE, descriptor);
3314         }
3315     }
3316   else
3317     return gfc_conv_descriptor_data_get (descriptor);
3318 }
3319 
3320 
3321 /* Return an expression for the base offset of an array.  */
3322 
3323 tree
gfc_conv_array_offset(tree descriptor)3324 gfc_conv_array_offset (tree descriptor)
3325 {
3326   tree type;
3327 
3328   type = TREE_TYPE (descriptor);
3329   if (GFC_ARRAY_TYPE_P (type))
3330     return GFC_TYPE_ARRAY_OFFSET (type);
3331   else
3332     return gfc_conv_descriptor_offset_get (descriptor);
3333 }
3334 
3335 
3336 /* Get an expression for the array stride.  */
3337 
3338 tree
gfc_conv_array_stride(tree descriptor,int dim)3339 gfc_conv_array_stride (tree descriptor, int dim)
3340 {
3341   tree tmp;
3342   tree type;
3343 
3344   type = TREE_TYPE (descriptor);
3345 
3346   /* For descriptorless arrays use the array size.  */
3347   tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
3348   if (tmp != NULL_TREE)
3349     return tmp;
3350 
3351   tmp = gfc_conv_descriptor_stride_get (descriptor, gfc_rank_cst[dim]);
3352   return tmp;
3353 }
3354 
3355 
3356 /* Like gfc_conv_array_stride, but for the lower bound.  */
3357 
3358 tree
gfc_conv_array_lbound(tree descriptor,int dim)3359 gfc_conv_array_lbound (tree descriptor, int dim)
3360 {
3361   tree tmp;
3362   tree type;
3363 
3364   type = TREE_TYPE (descriptor);
3365 
3366   tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
3367   if (tmp != NULL_TREE)
3368     return tmp;
3369 
3370   tmp = gfc_conv_descriptor_lbound_get (descriptor, gfc_rank_cst[dim]);
3371   return tmp;
3372 }
3373 
3374 
3375 /* Like gfc_conv_array_stride, but for the upper bound.  */
3376 
3377 tree
gfc_conv_array_ubound(tree descriptor,int dim)3378 gfc_conv_array_ubound (tree descriptor, int dim)
3379 {
3380   tree tmp;
3381   tree type;
3382 
3383   type = TREE_TYPE (descriptor);
3384 
3385   tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
3386   if (tmp != NULL_TREE)
3387     return tmp;
3388 
3389   /* This should only ever happen when passing an assumed shape array
3390      as an actual parameter.  The value will never be used.  */
3391   if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
3392     return gfc_index_zero_node;
3393 
3394   tmp = gfc_conv_descriptor_ubound_get (descriptor, gfc_rank_cst[dim]);
3395   return tmp;
3396 }
3397 
3398 
3399 /* Generate code to perform an array index bound check.  */
3400 
3401 static tree
trans_array_bound_check(gfc_se * se,gfc_ss * ss,tree index,int n,locus * where,bool check_upper)3402 trans_array_bound_check (gfc_se * se, gfc_ss *ss, tree index, int n,
3403 			 locus * where, bool check_upper)
3404 {
3405   tree fault;
3406   tree tmp_lo, tmp_up;
3407   tree descriptor;
3408   char *msg;
3409   const char * name = NULL;
3410 
3411   if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
3412     return index;
3413 
3414   descriptor = ss->info->data.array.descriptor;
3415 
3416   index = gfc_evaluate_now (index, &se->pre);
3417 
3418   /* We find a name for the error message.  */
3419   name = ss->info->expr->symtree->n.sym->name;
3420   gcc_assert (name != NULL);
3421 
3422   if (VAR_P (descriptor))
3423     name = IDENTIFIER_POINTER (DECL_NAME (descriptor));
3424 
3425   /* If upper bound is present, include both bounds in the error message.  */
3426   if (check_upper)
3427     {
3428       tmp_lo = gfc_conv_array_lbound (descriptor, n);
3429       tmp_up = gfc_conv_array_ubound (descriptor, n);
3430 
3431       if (name)
3432 	msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
3433 			 "outside of expected range (%%ld:%%ld)", n+1, name);
3434       else
3435 	msg = xasprintf ("Index '%%ld' of dimension %d "
3436 			 "outside of expected range (%%ld:%%ld)", n+1);
3437 
3438       fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
3439 			       index, tmp_lo);
3440       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
3441 			       fold_convert (long_integer_type_node, index),
3442 			       fold_convert (long_integer_type_node, tmp_lo),
3443 			       fold_convert (long_integer_type_node, tmp_up));
3444       fault = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
3445 			       index, tmp_up);
3446       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
3447 			       fold_convert (long_integer_type_node, index),
3448 			       fold_convert (long_integer_type_node, tmp_lo),
3449 			       fold_convert (long_integer_type_node, tmp_up));
3450       free (msg);
3451     }
3452   else
3453     {
3454       tmp_lo = gfc_conv_array_lbound (descriptor, n);
3455 
3456       if (name)
3457 	msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
3458 			 "below lower bound of %%ld", n+1, name);
3459       else
3460 	msg = xasprintf ("Index '%%ld' of dimension %d "
3461 			 "below lower bound of %%ld", n+1);
3462 
3463       fault = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
3464 			       index, tmp_lo);
3465       gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
3466 			       fold_convert (long_integer_type_node, index),
3467 			       fold_convert (long_integer_type_node, tmp_lo));
3468       free (msg);
3469     }
3470 
3471   return index;
3472 }
3473 
3474 
3475 /* Return the offset for an index.  Performs bound checking for elemental
3476    dimensions.  Single element references are processed separately.
3477    DIM is the array dimension, I is the loop dimension.  */
3478 
3479 static tree
conv_array_index_offset(gfc_se * se,gfc_ss * ss,int dim,int i,gfc_array_ref * ar,tree stride)3480 conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i,
3481 			 gfc_array_ref * ar, tree stride)
3482 {
3483   gfc_array_info *info;
3484   tree index;
3485   tree desc;
3486   tree data;
3487 
3488   info = &ss->info->data.array;
3489 
3490   /* Get the index into the array for this dimension.  */
3491   if (ar)
3492     {
3493       gcc_assert (ar->type != AR_ELEMENT);
3494       switch (ar->dimen_type[dim])
3495 	{
3496 	case DIMEN_THIS_IMAGE:
3497 	  gcc_unreachable ();
3498 	  break;
3499 	case DIMEN_ELEMENT:
3500 	  /* Elemental dimension.  */
3501 	  gcc_assert (info->subscript[dim]
3502 		      && info->subscript[dim]->info->type == GFC_SS_SCALAR);
3503 	  /* We've already translated this value outside the loop.  */
3504 	  index = info->subscript[dim]->info->data.scalar.value;
3505 
3506 	  index = trans_array_bound_check (se, ss, index, dim, &ar->where,
3507 					   ar->as->type != AS_ASSUMED_SIZE
3508 					   || dim < ar->dimen - 1);
3509 	  break;
3510 
3511 	case DIMEN_VECTOR:
3512 	  gcc_assert (info && se->loop);
3513 	  gcc_assert (info->subscript[dim]
3514 		      && info->subscript[dim]->info->type == GFC_SS_VECTOR);
3515 	  desc = info->subscript[dim]->info->data.array.descriptor;
3516 
3517 	  /* Get a zero-based index into the vector.  */
3518 	  index = fold_build2_loc (input_location, MINUS_EXPR,
3519 				   gfc_array_index_type,
3520 				   se->loop->loopvar[i], se->loop->from[i]);
3521 
3522 	  /* Multiply the index by the stride.  */
3523 	  index = fold_build2_loc (input_location, MULT_EXPR,
3524 				   gfc_array_index_type,
3525 				   index, gfc_conv_array_stride (desc, 0));
3526 
3527 	  /* Read the vector to get an index into info->descriptor.  */
3528 	  data = build_fold_indirect_ref_loc (input_location,
3529 					  gfc_conv_array_data (desc));
3530 	  index = gfc_build_array_ref (data, index, NULL);
3531 	  index = gfc_evaluate_now (index, &se->pre);
3532 	  index = fold_convert (gfc_array_index_type, index);
3533 
3534 	  /* Do any bounds checking on the final info->descriptor index.  */
3535 	  index = trans_array_bound_check (se, ss, index, dim, &ar->where,
3536 					   ar->as->type != AS_ASSUMED_SIZE
3537 					   || dim < ar->dimen - 1);
3538 	  break;
3539 
3540 	case DIMEN_RANGE:
3541 	  /* Scalarized dimension.  */
3542 	  gcc_assert (info && se->loop);
3543 
3544 	  /* Multiply the loop variable by the stride and delta.  */
3545 	  index = se->loop->loopvar[i];
3546 	  if (!integer_onep (info->stride[dim]))
3547 	    index = fold_build2_loc (input_location, MULT_EXPR,
3548 				     gfc_array_index_type, index,
3549 				     info->stride[dim]);
3550 	  if (!integer_zerop (info->delta[dim]))
3551 	    index = fold_build2_loc (input_location, PLUS_EXPR,
3552 				     gfc_array_index_type, index,
3553 				     info->delta[dim]);
3554 	  break;
3555 
3556 	default:
3557 	  gcc_unreachable ();
3558 	}
3559     }
3560   else
3561     {
3562       /* Temporary array or derived type component.  */
3563       gcc_assert (se->loop);
3564       index = se->loop->loopvar[se->loop->order[i]];
3565 
3566       /* Pointer functions can have stride[0] different from unity.
3567 	 Use the stride returned by the function call and stored in
3568 	 the descriptor for the temporary.  */
3569       if (se->ss && se->ss->info->type == GFC_SS_FUNCTION
3570 	  && se->ss->info->expr
3571 	  && se->ss->info->expr->symtree
3572 	  && se->ss->info->expr->symtree->n.sym->result
3573 	  && se->ss->info->expr->symtree->n.sym->result->attr.pointer)
3574 	stride = gfc_conv_descriptor_stride_get (info->descriptor,
3575 						 gfc_rank_cst[dim]);
3576 
3577       if (info->delta[dim] && !integer_zerop (info->delta[dim]))
3578 	index = fold_build2_loc (input_location, PLUS_EXPR,
3579 				 gfc_array_index_type, index, info->delta[dim]);
3580     }
3581 
3582   /* Multiply by the stride.  */
3583   if (stride != NULL && !integer_onep (stride))
3584     index = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3585 			     index, stride);
3586 
3587   return index;
3588 }
3589 
3590 
3591 /* Build a scalarized array reference using the vptr 'size'.  */
3592 
3593 static bool
build_class_array_ref(gfc_se * se,tree base,tree index)3594 build_class_array_ref (gfc_se *se, tree base, tree index)
3595 {
3596   tree size;
3597   tree decl = NULL_TREE;
3598   tree tmp;
3599   gfc_expr *expr = se->ss->info->expr;
3600   gfc_expr *class_expr;
3601   gfc_typespec *ts;
3602   gfc_symbol *sym;
3603 
3604   tmp = !VAR_P (base) ? gfc_get_class_from_expr (base) : NULL_TREE;
3605 
3606   if (tmp != NULL_TREE)
3607     decl = tmp;
3608   else
3609     {
3610       /* The base expression does not contain a class component, either
3611 	 because it is a temporary array or array descriptor.  Class
3612 	 array functions are correctly resolved above.  */
3613       if (!expr
3614 	  || (expr->ts.type != BT_CLASS
3615 	      && !gfc_is_class_array_ref (expr, NULL)))
3616 	return false;
3617 
3618       /* Obtain the expression for the class entity or component that is
3619 	 followed by an array reference, which is not an element, so that
3620 	 the span of the array can be obtained.  */
3621       class_expr = gfc_find_and_cut_at_last_class_ref (expr, false, &ts);
3622 
3623       if (!ts)
3624 	return false;
3625 
3626       sym = (!class_expr && expr) ? expr->symtree->n.sym : NULL;
3627       if (sym && sym->attr.function
3628 	  && sym == sym->result
3629 	  && sym->backend_decl == current_function_decl)
3630 	/* The temporary is the data field of the class data component
3631 	   of the current function.  */
3632 	decl = gfc_get_fake_result_decl (sym, 0);
3633       else if (sym)
3634 	{
3635 	  if (decl == NULL_TREE)
3636 	    decl = expr->symtree->n.sym->backend_decl;
3637 	  /* For class arrays the tree containing the class is stored in
3638 	     GFC_DECL_SAVED_DESCRIPTOR of the sym's backend_decl.
3639 	     For all others it's sym's backend_decl directly.  */
3640 	  if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
3641 	    decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
3642 	}
3643       else
3644 	decl = gfc_get_class_from_gfc_expr (class_expr);
3645 
3646       if (POINTER_TYPE_P (TREE_TYPE (decl)))
3647 	decl = build_fold_indirect_ref_loc (input_location, decl);
3648 
3649       if (!GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
3650 	return false;
3651     }
3652 
3653   se->class_vptr = gfc_evaluate_now (gfc_class_vptr_get (decl), &se->pre);
3654 
3655   size = gfc_class_vtab_size_get (decl);
3656   /* For unlimited polymorphic entities then _len component needs to be
3657      multiplied with the size.  */
3658   size = gfc_resize_class_size_with_len (&se->pre, decl, size);
3659   size = fold_convert (TREE_TYPE (index), size);
3660 
3661   /* Return the element in the se expression.  */
3662   se->expr = gfc_build_spanned_array_ref (base, index, size);
3663   return true;
3664 }
3665 
3666 
3667 /* Indicates that the tree EXPR is a reference to an array that can’t
3668    have any negative stride.  */
3669 
3670 static bool
non_negative_strides_array_p(tree expr)3671 non_negative_strides_array_p (tree expr)
3672 {
3673   if (expr == NULL_TREE)
3674     return false;
3675 
3676   tree type = TREE_TYPE (expr);
3677   if (POINTER_TYPE_P (type))
3678     type = TREE_TYPE (type);
3679 
3680   if (TYPE_LANG_SPECIFIC (type))
3681     {
3682       gfc_array_kind array_kind = GFC_TYPE_ARRAY_AKIND (type);
3683 
3684       if (array_kind == GFC_ARRAY_ALLOCATABLE
3685 	  || array_kind == GFC_ARRAY_ASSUMED_SHAPE_CONT)
3686 	return true;
3687     }
3688 
3689   /* An array with descriptor can have negative strides.
3690      We try to be conservative and return false by default here
3691      if we don’t recognize a contiguous array instead of
3692      returning false if we can identify a non-contiguous one.  */
3693   if (!GFC_ARRAY_TYPE_P (type))
3694     return false;
3695 
3696   /* If the array was originally a dummy with a descriptor, strides can be
3697      negative.  */
3698   if (DECL_P (expr)
3699       && DECL_LANG_SPECIFIC (expr)
3700       && GFC_DECL_SAVED_DESCRIPTOR (expr)
3701       && GFC_DECL_SAVED_DESCRIPTOR (expr) != expr)
3702     return non_negative_strides_array_p (GFC_DECL_SAVED_DESCRIPTOR (expr));
3703 
3704   return true;
3705 }
3706 
3707 
3708 /* Build a scalarized reference to an array.  */
3709 
3710 static void
gfc_conv_scalarized_array_ref(gfc_se * se,gfc_array_ref * ar,bool tmp_array=false)3711 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar,
3712 			       bool tmp_array = false)
3713 {
3714   gfc_array_info *info;
3715   tree decl = NULL_TREE;
3716   tree index;
3717   tree base;
3718   gfc_ss *ss;
3719   gfc_expr *expr;
3720   int n;
3721 
3722   ss = se->ss;
3723   expr = ss->info->expr;
3724   info = &ss->info->data.array;
3725   if (ar)
3726     n = se->loop->order[0];
3727   else
3728     n = 0;
3729 
3730   index = conv_array_index_offset (se, ss, ss->dim[n], n, ar, info->stride0);
3731   /* Add the offset for this dimension to the stored offset for all other
3732      dimensions.  */
3733   if (info->offset && !integer_zerop (info->offset))
3734     index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3735 			     index, info->offset);
3736 
3737   base = build_fold_indirect_ref_loc (input_location, info->data);
3738 
3739   /* Use the vptr 'size' field to access the element of a class array.  */
3740   if (build_class_array_ref (se, base, index))
3741     return;
3742 
3743   if (get_CFI_desc (NULL, expr, &decl, ar))
3744     decl = build_fold_indirect_ref_loc (input_location, decl);
3745 
3746   /* A pointer array component can be detected from its field decl. Fix
3747      the descriptor, mark the resulting variable decl and pass it to
3748      gfc_build_array_ref.  */
3749   if (is_pointer_array (info->descriptor)
3750       || (expr && expr->ts.deferred && info->descriptor
3751 	  && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (info->descriptor))))
3752     {
3753       if (TREE_CODE (info->descriptor) == COMPONENT_REF)
3754 	decl = info->descriptor;
3755       else if (TREE_CODE (info->descriptor) == INDIRECT_REF)
3756 	decl = TREE_OPERAND (info->descriptor, 0);
3757 
3758       if (decl == NULL_TREE)
3759 	decl = info->descriptor;
3760     }
3761 
3762   bool non_negative_stride = tmp_array
3763 			     || non_negative_strides_array_p (info->descriptor);
3764   se->expr = gfc_build_array_ref (base, index, decl,
3765 				  non_negative_stride);
3766 }
3767 
3768 
3769 /* Translate access of temporary array.  */
3770 
3771 void
gfc_conv_tmp_array_ref(gfc_se * se)3772 gfc_conv_tmp_array_ref (gfc_se * se)
3773 {
3774   se->string_length = se->ss->info->string_length;
3775   gfc_conv_scalarized_array_ref (se, NULL, true);
3776   gfc_advance_se_ss_chain (se);
3777 }
3778 
3779 /* Add T to the offset pair *OFFSET, *CST_OFFSET.  */
3780 
3781 static void
add_to_offset(tree * cst_offset,tree * offset,tree t)3782 add_to_offset (tree *cst_offset, tree *offset, tree t)
3783 {
3784   if (TREE_CODE (t) == INTEGER_CST)
3785     *cst_offset = int_const_binop (PLUS_EXPR, *cst_offset, t);
3786   else
3787     {
3788       if (!integer_zerop (*offset))
3789 	*offset = fold_build2_loc (input_location, PLUS_EXPR,
3790 				   gfc_array_index_type, *offset, t);
3791       else
3792 	*offset = t;
3793     }
3794 }
3795 
3796 
3797 static tree
build_array_ref(tree desc,tree offset,tree decl,tree vptr)3798 build_array_ref (tree desc, tree offset, tree decl, tree vptr)
3799 {
3800   tree tmp;
3801   tree type;
3802   tree cdesc;
3803 
3804   /* For class arrays the class declaration is stored in the saved
3805      descriptor.  */
3806   if (INDIRECT_REF_P (desc)
3807       && DECL_LANG_SPECIFIC (TREE_OPERAND (desc, 0))
3808       && GFC_DECL_SAVED_DESCRIPTOR (TREE_OPERAND (desc, 0)))
3809     cdesc = gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (
3810 				  TREE_OPERAND (desc, 0)));
3811   else
3812     cdesc = desc;
3813 
3814   /* Class container types do not always have the GFC_CLASS_TYPE_P
3815      but the canonical type does.  */
3816   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (cdesc))
3817       && TREE_CODE (cdesc) == COMPONENT_REF)
3818     {
3819       type = TREE_TYPE (TREE_OPERAND (cdesc, 0));
3820       if (TYPE_CANONICAL (type)
3821 	  && GFC_CLASS_TYPE_P (TYPE_CANONICAL (type)))
3822 	vptr = gfc_class_vptr_get (TREE_OPERAND (cdesc, 0));
3823     }
3824 
3825   tmp = gfc_conv_array_data (desc);
3826   tmp = build_fold_indirect_ref_loc (input_location, tmp);
3827   tmp = gfc_build_array_ref (tmp, offset, decl,
3828 			     non_negative_strides_array_p (desc),
3829 			     vptr);
3830   return tmp;
3831 }
3832 
3833 
3834 /* Build an array reference.  se->expr already holds the array descriptor.
3835    This should be either a variable, indirect variable reference or component
3836    reference.  For arrays which do not have a descriptor, se->expr will be
3837    the data pointer.
3838    a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
3839 
3840 void
gfc_conv_array_ref(gfc_se * se,gfc_array_ref * ar,gfc_expr * expr,locus * where)3841 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr,
3842 		    locus * where)
3843 {
3844   int n;
3845   tree offset, cst_offset;
3846   tree tmp;
3847   tree stride;
3848   tree decl = NULL_TREE;
3849   gfc_se indexse;
3850   gfc_se tmpse;
3851   gfc_symbol * sym = expr->symtree->n.sym;
3852   char *var_name = NULL;
3853 
3854   if (ar->dimen == 0)
3855     {
3856       gcc_assert (ar->codimen || sym->attr.select_rank_temporary
3857 		  || (ar->as && ar->as->corank));
3858 
3859       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr)))
3860 	se->expr = build_fold_indirect_ref (gfc_conv_array_data (se->expr));
3861       else
3862 	{
3863 	  if (GFC_ARRAY_TYPE_P (TREE_TYPE (se->expr))
3864 	      && TREE_CODE (TREE_TYPE (se->expr)) == POINTER_TYPE)
3865 	    se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
3866 
3867 	  /* Use the actual tree type and not the wrapped coarray.  */
3868 	  if (!se->want_pointer)
3869 	    se->expr = fold_convert (TYPE_MAIN_VARIANT (TREE_TYPE (se->expr)),
3870 				     se->expr);
3871 	}
3872 
3873       return;
3874     }
3875 
3876   /* Handle scalarized references separately.  */
3877   if (ar->type != AR_ELEMENT)
3878     {
3879       gfc_conv_scalarized_array_ref (se, ar);
3880       gfc_advance_se_ss_chain (se);
3881       return;
3882     }
3883 
3884   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3885     {
3886       size_t len;
3887       gfc_ref *ref;
3888 
3889       len = strlen (sym->name) + 1;
3890       for (ref = expr->ref; ref; ref = ref->next)
3891 	{
3892 	  if (ref->type == REF_ARRAY && &ref->u.ar == ar)
3893 	    break;
3894 	  if (ref->type == REF_COMPONENT)
3895 	    len += 2 + strlen (ref->u.c.component->name);
3896 	}
3897 
3898       var_name = XALLOCAVEC (char, len);
3899       strcpy (var_name, sym->name);
3900 
3901       for (ref = expr->ref; ref; ref = ref->next)
3902 	{
3903 	  if (ref->type == REF_ARRAY && &ref->u.ar == ar)
3904 	    break;
3905 	  if (ref->type == REF_COMPONENT)
3906 	    {
3907 	      strcat (var_name, "%%");
3908 	      strcat (var_name, ref->u.c.component->name);
3909 	    }
3910 	}
3911     }
3912 
3913   decl = se->expr;
3914   if (UNLIMITED_POLY(sym)
3915       && IS_CLASS_ARRAY (sym)
3916       && sym->attr.dummy
3917       && ar->as->type != AS_DEFERRED)
3918     decl = sym->backend_decl;
3919 
3920   cst_offset = offset = gfc_index_zero_node;
3921   add_to_offset (&cst_offset, &offset, gfc_conv_array_offset (decl));
3922 
3923   /* Calculate the offsets from all the dimensions.  Make sure to associate
3924      the final offset so that we form a chain of loop invariant summands.  */
3925   for (n = ar->dimen - 1; n >= 0; n--)
3926     {
3927       /* Calculate the index for this dimension.  */
3928       gfc_init_se (&indexse, se);
3929       gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
3930       gfc_add_block_to_block (&se->pre, &indexse.pre);
3931 
3932       if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && ! expr->no_bounds_check)
3933 	{
3934 	  /* Check array bounds.  */
3935 	  tree cond;
3936 	  char *msg;
3937 
3938 	  /* Evaluate the indexse.expr only once.  */
3939 	  indexse.expr = save_expr (indexse.expr);
3940 
3941 	  /* Lower bound.  */
3942 	  tmp = gfc_conv_array_lbound (decl, n);
3943 	  if (sym->attr.temporary)
3944 	    {
3945 	      gfc_init_se (&tmpse, se);
3946 	      gfc_conv_expr_type (&tmpse, ar->as->lower[n],
3947 				  gfc_array_index_type);
3948 	      gfc_add_block_to_block (&se->pre, &tmpse.pre);
3949 	      tmp = tmpse.expr;
3950 	    }
3951 
3952 	  cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
3953 				  indexse.expr, tmp);
3954 	  msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
3955 			   "below lower bound of %%ld", n+1, var_name);
3956 	  gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
3957 				   fold_convert (long_integer_type_node,
3958 						 indexse.expr),
3959 				   fold_convert (long_integer_type_node, tmp));
3960 	  free (msg);
3961 
3962 	  /* Upper bound, but not for the last dimension of assumed-size
3963 	     arrays.  */
3964 	  if (n < ar->dimen - 1 || ar->as->type != AS_ASSUMED_SIZE)
3965 	    {
3966 	      tmp = gfc_conv_array_ubound (decl, n);
3967 	      if (sym->attr.temporary)
3968 		{
3969 		  gfc_init_se (&tmpse, se);
3970 		  gfc_conv_expr_type (&tmpse, ar->as->upper[n],
3971 				      gfc_array_index_type);
3972 		  gfc_add_block_to_block (&se->pre, &tmpse.pre);
3973 		  tmp = tmpse.expr;
3974 		}
3975 
3976 	      cond = fold_build2_loc (input_location, GT_EXPR,
3977 				      logical_type_node, indexse.expr, tmp);
3978 	      msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
3979 			       "above upper bound of %%ld", n+1, var_name);
3980 	      gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
3981 				   fold_convert (long_integer_type_node,
3982 						 indexse.expr),
3983 				   fold_convert (long_integer_type_node, tmp));
3984 	      free (msg);
3985 	    }
3986 	}
3987 
3988       /* Multiply the index by the stride.  */
3989       stride = gfc_conv_array_stride (decl, n);
3990       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3991 			     indexse.expr, stride);
3992 
3993       /* And add it to the total.  */
3994       add_to_offset (&cst_offset, &offset, tmp);
3995     }
3996 
3997   if (!integer_zerop (cst_offset))
3998     offset = fold_build2_loc (input_location, PLUS_EXPR,
3999 			      gfc_array_index_type, offset, cst_offset);
4000 
4001   /* A pointer array component can be detected from its field decl. Fix
4002      the descriptor, mark the resulting variable decl and pass it to
4003      build_array_ref.  */
4004   decl = NULL_TREE;
4005   if (get_CFI_desc (sym, expr, &decl, ar))
4006     decl = build_fold_indirect_ref_loc (input_location, decl);
4007   if (!expr->ts.deferred && !sym->attr.codimension
4008       && is_pointer_array (se->expr))
4009     {
4010       if (TREE_CODE (se->expr) == COMPONENT_REF)
4011 	decl = se->expr;
4012       else if (TREE_CODE (se->expr) == INDIRECT_REF)
4013 	decl = TREE_OPERAND (se->expr, 0);
4014       else
4015 	decl = se->expr;
4016     }
4017   else if (expr->ts.deferred
4018 	   || (sym->ts.type == BT_CHARACTER
4019 	       && sym->attr.select_type_temporary))
4020     {
4021       if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr)))
4022 	{
4023 	  decl = se->expr;
4024 	  if (TREE_CODE (decl) == INDIRECT_REF)
4025 	    decl = TREE_OPERAND (decl, 0);
4026 	}
4027       else
4028 	decl = sym->backend_decl;
4029     }
4030   else if (sym->ts.type == BT_CLASS)
4031     {
4032       if (UNLIMITED_POLY (sym))
4033 	{
4034 	  gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (expr);
4035 	  gfc_init_se (&tmpse, NULL);
4036 	  gfc_conv_expr (&tmpse, class_expr);
4037 	  if (!se->class_vptr)
4038 	    se->class_vptr = gfc_class_vptr_get (tmpse.expr);
4039 	  gfc_free_expr (class_expr);
4040 	  decl = tmpse.expr;
4041 	}
4042       else
4043 	decl = NULL_TREE;
4044     }
4045 
4046   se->expr = build_array_ref (se->expr, offset, decl, se->class_vptr);
4047 }
4048 
4049 
4050 /* Add the offset corresponding to array's ARRAY_DIM dimension and loop's
4051    LOOP_DIM dimension (if any) to array's offset.  */
4052 
4053 static void
add_array_offset(stmtblock_t * pblock,gfc_loopinfo * loop,gfc_ss * ss,gfc_array_ref * ar,int array_dim,int loop_dim)4054 add_array_offset (stmtblock_t *pblock, gfc_loopinfo *loop, gfc_ss *ss,
4055 		  gfc_array_ref *ar, int array_dim, int loop_dim)
4056 {
4057   gfc_se se;
4058   gfc_array_info *info;
4059   tree stride, index;
4060 
4061   info = &ss->info->data.array;
4062 
4063   gfc_init_se (&se, NULL);
4064   se.loop = loop;
4065   se.expr = info->descriptor;
4066   stride = gfc_conv_array_stride (info->descriptor, array_dim);
4067   index = conv_array_index_offset (&se, ss, array_dim, loop_dim, ar, stride);
4068   gfc_add_block_to_block (pblock, &se.pre);
4069 
4070   info->offset = fold_build2_loc (input_location, PLUS_EXPR,
4071 				  gfc_array_index_type,
4072 				  info->offset, index);
4073   info->offset = gfc_evaluate_now (info->offset, pblock);
4074 }
4075 
4076 
4077 /* Generate the code to be executed immediately before entering a
4078    scalarization loop.  */
4079 
4080 static void
gfc_trans_preloop_setup(gfc_loopinfo * loop,int dim,int flag,stmtblock_t * pblock)4081 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
4082 			 stmtblock_t * pblock)
4083 {
4084   tree stride;
4085   gfc_ss_info *ss_info;
4086   gfc_array_info *info;
4087   gfc_ss_type ss_type;
4088   gfc_ss *ss, *pss;
4089   gfc_loopinfo *ploop;
4090   gfc_array_ref *ar;
4091   int i;
4092 
4093   /* This code will be executed before entering the scalarization loop
4094      for this dimension.  */
4095   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4096     {
4097       ss_info = ss->info;
4098 
4099       if ((ss_info->useflags & flag) == 0)
4100 	continue;
4101 
4102       ss_type = ss_info->type;
4103       if (ss_type != GFC_SS_SECTION
4104 	  && ss_type != GFC_SS_FUNCTION
4105 	  && ss_type != GFC_SS_CONSTRUCTOR
4106 	  && ss_type != GFC_SS_COMPONENT)
4107 	continue;
4108 
4109       info = &ss_info->data.array;
4110 
4111       gcc_assert (dim < ss->dimen);
4112       gcc_assert (ss->dimen == loop->dimen);
4113 
4114       if (info->ref)
4115 	ar = &info->ref->u.ar;
4116       else
4117 	ar = NULL;
4118 
4119       if (dim == loop->dimen - 1 && loop->parent != NULL)
4120 	{
4121 	  /* If we are in the outermost dimension of this loop, the previous
4122 	     dimension shall be in the parent loop.  */
4123 	  gcc_assert (ss->parent != NULL);
4124 
4125 	  pss = ss->parent;
4126 	  ploop = loop->parent;
4127 
4128 	  /* ss and ss->parent are about the same array.  */
4129 	  gcc_assert (ss_info == pss->info);
4130 	}
4131       else
4132 	{
4133 	  ploop = loop;
4134 	  pss = ss;
4135 	}
4136 
4137       if (dim == loop->dimen - 1)
4138 	i = 0;
4139       else
4140 	i = dim + 1;
4141 
4142       /* For the time being, there is no loop reordering.  */
4143       gcc_assert (i == ploop->order[i]);
4144       i = ploop->order[i];
4145 
4146       if (dim == loop->dimen - 1 && loop->parent == NULL)
4147 	{
4148 	  stride = gfc_conv_array_stride (info->descriptor,
4149 					  innermost_ss (ss)->dim[i]);
4150 
4151 	  /* Calculate the stride of the innermost loop.  Hopefully this will
4152 	     allow the backend optimizers to do their stuff more effectively.
4153 	   */
4154 	  info->stride0 = gfc_evaluate_now (stride, pblock);
4155 
4156 	  /* For the outermost loop calculate the offset due to any
4157 	     elemental dimensions.  It will have been initialized with the
4158 	     base offset of the array.  */
4159 	  if (info->ref)
4160 	    {
4161 	      for (i = 0; i < ar->dimen; i++)
4162 		{
4163 		  if (ar->dimen_type[i] != DIMEN_ELEMENT)
4164 		    continue;
4165 
4166 		  add_array_offset (pblock, loop, ss, ar, i, /* unused */ -1);
4167 		}
4168 	    }
4169 	}
4170       else
4171 	/* Add the offset for the previous loop dimension.  */
4172 	add_array_offset (pblock, ploop, ss, ar, pss->dim[i], i);
4173 
4174       /* Remember this offset for the second loop.  */
4175       if (dim == loop->temp_dim - 1 && loop->parent == NULL)
4176         info->saved_offset = info->offset;
4177     }
4178 }
4179 
4180 
4181 /* Start a scalarized expression.  Creates a scope and declares loop
4182    variables.  */
4183 
4184 void
gfc_start_scalarized_body(gfc_loopinfo * loop,stmtblock_t * pbody)4185 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
4186 {
4187   int dim;
4188   int n;
4189   int flags;
4190 
4191   gcc_assert (!loop->array_parameter);
4192 
4193   for (dim = loop->dimen - 1; dim >= 0; dim--)
4194     {
4195       n = loop->order[dim];
4196 
4197       gfc_start_block (&loop->code[n]);
4198 
4199       /* Create the loop variable.  */
4200       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
4201 
4202       if (dim < loop->temp_dim)
4203 	flags = 3;
4204       else
4205 	flags = 1;
4206       /* Calculate values that will be constant within this loop.  */
4207       gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
4208     }
4209   gfc_start_block (pbody);
4210 }
4211 
4212 
4213 /* Generates the actual loop code for a scalarization loop.  */
4214 
4215 static void
gfc_trans_scalarized_loop_end(gfc_loopinfo * loop,int n,stmtblock_t * pbody)4216 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
4217 			       stmtblock_t * pbody)
4218 {
4219   stmtblock_t block;
4220   tree cond;
4221   tree tmp;
4222   tree loopbody;
4223   tree exit_label;
4224   tree stmt;
4225   tree init;
4226   tree incr;
4227 
4228   if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS
4229 		      | OMPWS_SCALARIZER_BODY))
4230       == (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)
4231       && n == loop->dimen - 1)
4232     {
4233       /* We create an OMP_FOR construct for the outermost scalarized loop.  */
4234       init = make_tree_vec (1);
4235       cond = make_tree_vec (1);
4236       incr = make_tree_vec (1);
4237 
4238       /* Cycle statement is implemented with a goto.  Exit statement must not
4239 	 be present for this loop.  */
4240       exit_label = gfc_build_label_decl (NULL_TREE);
4241       TREE_USED (exit_label) = 1;
4242 
4243       /* Label for cycle statements (if needed).  */
4244       tmp = build1_v (LABEL_EXPR, exit_label);
4245       gfc_add_expr_to_block (pbody, tmp);
4246 
4247       stmt = make_node (OMP_FOR);
4248 
4249       TREE_TYPE (stmt) = void_type_node;
4250       OMP_FOR_BODY (stmt) = loopbody = gfc_finish_block (pbody);
4251 
4252       OMP_FOR_CLAUSES (stmt) = build_omp_clause (input_location,
4253 						 OMP_CLAUSE_SCHEDULE);
4254       OMP_CLAUSE_SCHEDULE_KIND (OMP_FOR_CLAUSES (stmt))
4255 	= OMP_CLAUSE_SCHEDULE_STATIC;
4256       if (ompws_flags & OMPWS_NOWAIT)
4257 	OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (stmt))
4258 	  = build_omp_clause (input_location, OMP_CLAUSE_NOWAIT);
4259 
4260       /* Initialize the loopvar.  */
4261       TREE_VEC_ELT (init, 0) = build2_v (MODIFY_EXPR, loop->loopvar[n],
4262 					 loop->from[n]);
4263       OMP_FOR_INIT (stmt) = init;
4264       /* The exit condition.  */
4265       TREE_VEC_ELT (cond, 0) = build2_loc (input_location, LE_EXPR,
4266 					   logical_type_node,
4267 					   loop->loopvar[n], loop->to[n]);
4268       SET_EXPR_LOCATION (TREE_VEC_ELT (cond, 0), input_location);
4269       OMP_FOR_COND (stmt) = cond;
4270       /* Increment the loopvar.  */
4271       tmp = build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4272 			loop->loopvar[n], gfc_index_one_node);
4273       TREE_VEC_ELT (incr, 0) = fold_build2_loc (input_location, MODIFY_EXPR,
4274 	  void_type_node, loop->loopvar[n], tmp);
4275       OMP_FOR_INCR (stmt) = incr;
4276 
4277       ompws_flags &= ~OMPWS_CURR_SINGLEUNIT;
4278       gfc_add_expr_to_block (&loop->code[n], stmt);
4279     }
4280   else
4281     {
4282       bool reverse_loop = (loop->reverse[n] == GFC_REVERSE_SET)
4283 			     && (loop->temp_ss == NULL);
4284 
4285       loopbody = gfc_finish_block (pbody);
4286 
4287       if (reverse_loop)
4288 	std::swap (loop->from[n], loop->to[n]);
4289 
4290       /* Initialize the loopvar.  */
4291       if (loop->loopvar[n] != loop->from[n])
4292 	gfc_add_modify (&loop->code[n], loop->loopvar[n], loop->from[n]);
4293 
4294       exit_label = gfc_build_label_decl (NULL_TREE);
4295 
4296       /* Generate the loop body.  */
4297       gfc_init_block (&block);
4298 
4299       /* The exit condition.  */
4300       cond = fold_build2_loc (input_location, reverse_loop ? LT_EXPR : GT_EXPR,
4301 			  logical_type_node, loop->loopvar[n], loop->to[n]);
4302       tmp = build1_v (GOTO_EXPR, exit_label);
4303       TREE_USED (exit_label) = 1;
4304       tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
4305       gfc_add_expr_to_block (&block, tmp);
4306 
4307       /* The main body.  */
4308       gfc_add_expr_to_block (&block, loopbody);
4309 
4310       /* Increment the loopvar.  */
4311       tmp = fold_build2_loc (input_location,
4312 			     reverse_loop ? MINUS_EXPR : PLUS_EXPR,
4313 			     gfc_array_index_type, loop->loopvar[n],
4314 			     gfc_index_one_node);
4315 
4316       gfc_add_modify (&block, loop->loopvar[n], tmp);
4317 
4318       /* Build the loop.  */
4319       tmp = gfc_finish_block (&block);
4320       tmp = build1_v (LOOP_EXPR, tmp);
4321       gfc_add_expr_to_block (&loop->code[n], tmp);
4322 
4323       /* Add the exit label.  */
4324       tmp = build1_v (LABEL_EXPR, exit_label);
4325       gfc_add_expr_to_block (&loop->code[n], tmp);
4326     }
4327 
4328 }
4329 
4330 
4331 /* Finishes and generates the loops for a scalarized expression.  */
4332 
4333 void
gfc_trans_scalarizing_loops(gfc_loopinfo * loop,stmtblock_t * body)4334 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
4335 {
4336   int dim;
4337   int n;
4338   gfc_ss *ss;
4339   stmtblock_t *pblock;
4340   tree tmp;
4341 
4342   pblock = body;
4343   /* Generate the loops.  */
4344   for (dim = 0; dim < loop->dimen; dim++)
4345     {
4346       n = loop->order[dim];
4347       gfc_trans_scalarized_loop_end (loop, n, pblock);
4348       loop->loopvar[n] = NULL_TREE;
4349       pblock = &loop->code[n];
4350     }
4351 
4352   tmp = gfc_finish_block (pblock);
4353   gfc_add_expr_to_block (&loop->pre, tmp);
4354 
4355   /* Clear all the used flags.  */
4356   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4357     if (ss->parent == NULL)
4358       ss->info->useflags = 0;
4359 }
4360 
4361 
4362 /* Finish the main body of a scalarized expression, and start the secondary
4363    copying body.  */
4364 
4365 void
gfc_trans_scalarized_loop_boundary(gfc_loopinfo * loop,stmtblock_t * body)4366 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
4367 {
4368   int dim;
4369   int n;
4370   stmtblock_t *pblock;
4371   gfc_ss *ss;
4372 
4373   pblock = body;
4374   /* We finish as many loops as are used by the temporary.  */
4375   for (dim = 0; dim < loop->temp_dim - 1; dim++)
4376     {
4377       n = loop->order[dim];
4378       gfc_trans_scalarized_loop_end (loop, n, pblock);
4379       loop->loopvar[n] = NULL_TREE;
4380       pblock = &loop->code[n];
4381     }
4382 
4383   /* We don't want to finish the outermost loop entirely.  */
4384   n = loop->order[loop->temp_dim - 1];
4385   gfc_trans_scalarized_loop_end (loop, n, pblock);
4386 
4387   /* Restore the initial offsets.  */
4388   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4389     {
4390       gfc_ss_type ss_type;
4391       gfc_ss_info *ss_info;
4392 
4393       ss_info = ss->info;
4394 
4395       if ((ss_info->useflags & 2) == 0)
4396 	continue;
4397 
4398       ss_type = ss_info->type;
4399       if (ss_type != GFC_SS_SECTION
4400 	  && ss_type != GFC_SS_FUNCTION
4401 	  && ss_type != GFC_SS_CONSTRUCTOR
4402 	  && ss_type != GFC_SS_COMPONENT)
4403 	continue;
4404 
4405       ss_info->data.array.offset = ss_info->data.array.saved_offset;
4406     }
4407 
4408   /* Restart all the inner loops we just finished.  */
4409   for (dim = loop->temp_dim - 2; dim >= 0; dim--)
4410     {
4411       n = loop->order[dim];
4412 
4413       gfc_start_block (&loop->code[n]);
4414 
4415       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
4416 
4417       gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
4418     }
4419 
4420   /* Start a block for the secondary copying code.  */
4421   gfc_start_block (body);
4422 }
4423 
4424 
4425 /* Precalculate (either lower or upper) bound of an array section.
4426      BLOCK: Block in which the (pre)calculation code will go.
4427      BOUNDS[DIM]: Where the bound value will be stored once evaluated.
4428      VALUES[DIM]: Specified bound (NULL <=> unspecified).
4429      DESC: Array descriptor from which the bound will be picked if unspecified
4430        (either lower or upper bound according to LBOUND).  */
4431 
4432 static void
evaluate_bound(stmtblock_t * block,tree * bounds,gfc_expr ** values,tree desc,int dim,bool lbound,bool deferred)4433 evaluate_bound (stmtblock_t *block, tree *bounds, gfc_expr ** values,
4434 		tree desc, int dim, bool lbound, bool deferred)
4435 {
4436   gfc_se se;
4437   gfc_expr * input_val = values[dim];
4438   tree *output = &bounds[dim];
4439 
4440 
4441   if (input_val)
4442     {
4443       /* Specified section bound.  */
4444       gfc_init_se (&se, NULL);
4445       gfc_conv_expr_type (&se, input_val, gfc_array_index_type);
4446       gfc_add_block_to_block (block, &se.pre);
4447       *output = se.expr;
4448     }
4449   else if (deferred && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
4450     {
4451       /* The gfc_conv_array_lbound () routine returns a constant zero for
4452 	 deferred length arrays, which in the scalarizer wreaks havoc, when
4453 	 copying to a (newly allocated) one-based array.
4454 	 Keep returning the actual result in sync for both bounds.  */
4455       *output = lbound ? gfc_conv_descriptor_lbound_get (desc,
4456 							 gfc_rank_cst[dim]):
4457 			 gfc_conv_descriptor_ubound_get (desc,
4458 							 gfc_rank_cst[dim]);
4459     }
4460   else
4461     {
4462       /* No specific bound specified so use the bound of the array.  */
4463       *output = lbound ? gfc_conv_array_lbound (desc, dim) :
4464 			 gfc_conv_array_ubound (desc, dim);
4465     }
4466   *output = gfc_evaluate_now (*output, block);
4467 }
4468 
4469 
4470 /* Calculate the lower bound of an array section.  */
4471 
4472 static void
gfc_conv_section_startstride(stmtblock_t * block,gfc_ss * ss,int dim)4473 gfc_conv_section_startstride (stmtblock_t * block, gfc_ss * ss, int dim)
4474 {
4475   gfc_expr *stride = NULL;
4476   tree desc;
4477   gfc_se se;
4478   gfc_array_info *info;
4479   gfc_array_ref *ar;
4480 
4481   gcc_assert (ss->info->type == GFC_SS_SECTION);
4482 
4483   info = &ss->info->data.array;
4484   ar = &info->ref->u.ar;
4485 
4486   if (ar->dimen_type[dim] == DIMEN_VECTOR)
4487     {
4488       /* We use a zero-based index to access the vector.  */
4489       info->start[dim] = gfc_index_zero_node;
4490       info->end[dim] = NULL;
4491       info->stride[dim] = gfc_index_one_node;
4492       return;
4493     }
4494 
4495   gcc_assert (ar->dimen_type[dim] == DIMEN_RANGE
4496 	      || ar->dimen_type[dim] == DIMEN_THIS_IMAGE);
4497   desc = info->descriptor;
4498   stride = ar->stride[dim];
4499 
4500 
4501   /* Calculate the start of the range.  For vector subscripts this will
4502      be the range of the vector.  */
4503   evaluate_bound (block, info->start, ar->start, desc, dim, true,
4504 		  ar->as->type == AS_DEFERRED);
4505 
4506   /* Similarly calculate the end.  Although this is not used in the
4507      scalarizer, it is needed when checking bounds and where the end
4508      is an expression with side-effects.  */
4509   evaluate_bound (block, info->end, ar->end, desc, dim, false,
4510 		  ar->as->type == AS_DEFERRED);
4511 
4512 
4513   /* Calculate the stride.  */
4514   if (stride == NULL)
4515     info->stride[dim] = gfc_index_one_node;
4516   else
4517     {
4518       gfc_init_se (&se, NULL);
4519       gfc_conv_expr_type (&se, stride, gfc_array_index_type);
4520       gfc_add_block_to_block (block, &se.pre);
4521       info->stride[dim] = gfc_evaluate_now (se.expr, block);
4522     }
4523 }
4524 
4525 
4526 /* Calculates the range start and stride for a SS chain.  Also gets the
4527    descriptor and data pointer.  The range of vector subscripts is the size
4528    of the vector.  Array bounds are also checked.  */
4529 
4530 void
gfc_conv_ss_startstride(gfc_loopinfo * loop)4531 gfc_conv_ss_startstride (gfc_loopinfo * loop)
4532 {
4533   int n;
4534   tree tmp;
4535   gfc_ss *ss;
4536   tree desc;
4537 
4538   gfc_loopinfo * const outer_loop = outermost_loop (loop);
4539 
4540   loop->dimen = 0;
4541   /* Determine the rank of the loop.  */
4542   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4543     {
4544       switch (ss->info->type)
4545 	{
4546 	case GFC_SS_SECTION:
4547 	case GFC_SS_CONSTRUCTOR:
4548 	case GFC_SS_FUNCTION:
4549 	case GFC_SS_COMPONENT:
4550 	  loop->dimen = ss->dimen;
4551 	  goto done;
4552 
4553 	/* As usual, lbound and ubound are exceptions!.  */
4554 	case GFC_SS_INTRINSIC:
4555 	  switch (ss->info->expr->value.function.isym->id)
4556 	    {
4557 	    case GFC_ISYM_LBOUND:
4558 	    case GFC_ISYM_UBOUND:
4559 	    case GFC_ISYM_LCOBOUND:
4560 	    case GFC_ISYM_UCOBOUND:
4561 	    case GFC_ISYM_SHAPE:
4562 	    case GFC_ISYM_THIS_IMAGE:
4563 	      loop->dimen = ss->dimen;
4564 	      goto done;
4565 
4566 	    default:
4567 	      break;
4568 	    }
4569 
4570 	default:
4571 	  break;
4572 	}
4573     }
4574 
4575   /* We should have determined the rank of the expression by now.  If
4576      not, that's bad news.  */
4577   gcc_unreachable ();
4578 
4579 done:
4580   /* Loop over all the SS in the chain.  */
4581   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4582     {
4583       gfc_ss_info *ss_info;
4584       gfc_array_info *info;
4585       gfc_expr *expr;
4586 
4587       ss_info = ss->info;
4588       expr = ss_info->expr;
4589       info = &ss_info->data.array;
4590 
4591       if (expr && expr->shape && !info->shape)
4592 	info->shape = expr->shape;
4593 
4594       switch (ss_info->type)
4595 	{
4596 	case GFC_SS_SECTION:
4597 	  /* Get the descriptor for the array.  If it is a cross loops array,
4598 	     we got the descriptor already in the outermost loop.  */
4599 	  if (ss->parent == NULL)
4600 	    gfc_conv_ss_descriptor (&outer_loop->pre, ss,
4601 				    !loop->array_parameter);
4602 
4603 	  for (n = 0; n < ss->dimen; n++)
4604 	    gfc_conv_section_startstride (&outer_loop->pre, ss, ss->dim[n]);
4605 	  break;
4606 
4607 	case GFC_SS_INTRINSIC:
4608 	  switch (expr->value.function.isym->id)
4609 	    {
4610 	    /* Fall through to supply start and stride.  */
4611 	    case GFC_ISYM_LBOUND:
4612 	    case GFC_ISYM_UBOUND:
4613 	      /* This is the variant without DIM=...  */
4614 	      gcc_assert (expr->value.function.actual->next->expr == NULL);
4615 	      /* Fall through.  */
4616 
4617 	    case GFC_ISYM_SHAPE:
4618 	      {
4619 		gfc_expr *arg;
4620 
4621 		arg = expr->value.function.actual->expr;
4622 		if (arg->rank == -1)
4623 		  {
4624 		    gfc_se se;
4625 		    tree rank, tmp;
4626 
4627 		    /* The rank (hence the return value's shape) is unknown,
4628 		       we have to retrieve it.  */
4629 		    gfc_init_se (&se, NULL);
4630 		    se.descriptor_only = 1;
4631 		    gfc_conv_expr (&se, arg);
4632 		    /* This is a bare variable, so there is no preliminary
4633 		       or cleanup code.  */
4634 		    gcc_assert (se.pre.head == NULL_TREE
4635 				&& se.post.head == NULL_TREE);
4636 		    rank = gfc_conv_descriptor_rank (se.expr);
4637 		    tmp = fold_build2_loc (input_location, MINUS_EXPR,
4638 					   gfc_array_index_type,
4639 					   fold_convert (gfc_array_index_type,
4640 							 rank),
4641 					   gfc_index_one_node);
4642 		    info->end[0] = gfc_evaluate_now (tmp, &outer_loop->pre);
4643 		    info->start[0] = gfc_index_zero_node;
4644 		    info->stride[0] = gfc_index_one_node;
4645 		    continue;
4646 		  }
4647 		  /* Otherwise fall through GFC_SS_FUNCTION.  */
4648 		  gcc_fallthrough ();
4649 	      }
4650 	    case GFC_ISYM_LCOBOUND:
4651 	    case GFC_ISYM_UCOBOUND:
4652 	    case GFC_ISYM_THIS_IMAGE:
4653 	      break;
4654 
4655 	    default:
4656 	      continue;
4657 	    }
4658 
4659 	  /* FALLTHRU */
4660 	case GFC_SS_CONSTRUCTOR:
4661 	case GFC_SS_FUNCTION:
4662 	  for (n = 0; n < ss->dimen; n++)
4663 	    {
4664 	      int dim = ss->dim[n];
4665 
4666 	      info->start[dim]  = gfc_index_zero_node;
4667 	      info->end[dim]    = gfc_index_zero_node;
4668 	      info->stride[dim] = gfc_index_one_node;
4669 	    }
4670 	  break;
4671 
4672 	default:
4673 	  break;
4674 	}
4675     }
4676 
4677   /* The rest is just runtime bounds checking.  */
4678   if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
4679     {
4680       stmtblock_t block;
4681       tree lbound, ubound;
4682       tree end;
4683       tree size[GFC_MAX_DIMENSIONS];
4684       tree stride_pos, stride_neg, non_zerosized, tmp2, tmp3;
4685       gfc_array_info *info;
4686       char *msg;
4687       int dim;
4688 
4689       gfc_start_block (&block);
4690 
4691       for (n = 0; n < loop->dimen; n++)
4692 	size[n] = NULL_TREE;
4693 
4694       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
4695 	{
4696 	  stmtblock_t inner;
4697 	  gfc_ss_info *ss_info;
4698 	  gfc_expr *expr;
4699 	  locus *expr_loc;
4700 	  const char *expr_name;
4701 
4702 	  ss_info = ss->info;
4703 	  if (ss_info->type != GFC_SS_SECTION)
4704 	    continue;
4705 
4706 	  /* Catch allocatable lhs in f2003.  */
4707 	  if (flag_realloc_lhs && ss->no_bounds_check)
4708 	    continue;
4709 
4710 	  expr = ss_info->expr;
4711 	  expr_loc = &expr->where;
4712 	  expr_name = expr->symtree->name;
4713 
4714 	  gfc_start_block (&inner);
4715 
4716 	  /* TODO: range checking for mapped dimensions.  */
4717 	  info = &ss_info->data.array;
4718 
4719 	  /* This code only checks ranges.  Elemental and vector
4720 	     dimensions are checked later.  */
4721 	  for (n = 0; n < loop->dimen; n++)
4722 	    {
4723 	      bool check_upper;
4724 
4725 	      dim = ss->dim[n];
4726 	      if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
4727 		continue;
4728 
4729 	      if (dim == info->ref->u.ar.dimen - 1
4730 		  && info->ref->u.ar.as->type == AS_ASSUMED_SIZE)
4731 		check_upper = false;
4732 	      else
4733 		check_upper = true;
4734 
4735 	      /* Zero stride is not allowed.  */
4736 	      tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
4737 				     info->stride[dim], gfc_index_zero_node);
4738 	      msg = xasprintf ("Zero stride is not allowed, for dimension %d "
4739 			       "of array '%s'", dim + 1, expr_name);
4740 	      gfc_trans_runtime_check (true, false, tmp, &inner,
4741 				       expr_loc, msg);
4742 	      free (msg);
4743 
4744 	      desc = info->descriptor;
4745 
4746 	      /* This is the run-time equivalent of resolve.cc's
4747 		 check_dimension().  The logical is more readable there
4748 		 than it is here, with all the trees.  */
4749 	      lbound = gfc_conv_array_lbound (desc, dim);
4750 	      end = info->end[dim];
4751 	      if (check_upper)
4752 		ubound = gfc_conv_array_ubound (desc, dim);
4753 	      else
4754 		ubound = NULL;
4755 
4756 	      /* non_zerosized is true when the selected range is not
4757 		 empty.  */
4758 	      stride_pos = fold_build2_loc (input_location, GT_EXPR,
4759 					logical_type_node, info->stride[dim],
4760 					gfc_index_zero_node);
4761 	      tmp = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
4762 				     info->start[dim], end);
4763 	      stride_pos = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4764 					    logical_type_node, stride_pos, tmp);
4765 
4766 	      stride_neg = fold_build2_loc (input_location, LT_EXPR,
4767 				     logical_type_node,
4768 				     info->stride[dim], gfc_index_zero_node);
4769 	      tmp = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
4770 				     info->start[dim], end);
4771 	      stride_neg = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4772 					    logical_type_node,
4773 					    stride_neg, tmp);
4774 	      non_zerosized = fold_build2_loc (input_location, TRUTH_OR_EXPR,
4775 					       logical_type_node,
4776 					       stride_pos, stride_neg);
4777 
4778 	      /* Check the start of the range against the lower and upper
4779 		 bounds of the array, if the range is not empty.
4780 	         If upper bound is present, include both bounds in the
4781 		 error message.  */
4782 	      if (check_upper)
4783 		{
4784 		  tmp = fold_build2_loc (input_location, LT_EXPR,
4785 					 logical_type_node,
4786 					 info->start[dim], lbound);
4787 		  tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4788 					 logical_type_node,
4789 					 non_zerosized, tmp);
4790 		  tmp2 = fold_build2_loc (input_location, GT_EXPR,
4791 					  logical_type_node,
4792 					  info->start[dim], ubound);
4793 		  tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4794 					  logical_type_node,
4795 					  non_zerosized, tmp2);
4796 		  msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
4797 				   "outside of expected range (%%ld:%%ld)",
4798 				   dim + 1, expr_name);
4799 		  gfc_trans_runtime_check (true, false, tmp, &inner,
4800 					   expr_loc, msg,
4801 		     fold_convert (long_integer_type_node, info->start[dim]),
4802 		     fold_convert (long_integer_type_node, lbound),
4803 		     fold_convert (long_integer_type_node, ubound));
4804 		  gfc_trans_runtime_check (true, false, tmp2, &inner,
4805 					   expr_loc, msg,
4806 		     fold_convert (long_integer_type_node, info->start[dim]),
4807 		     fold_convert (long_integer_type_node, lbound),
4808 		     fold_convert (long_integer_type_node, ubound));
4809 		  free (msg);
4810 		}
4811 	      else
4812 		{
4813 		  tmp = fold_build2_loc (input_location, LT_EXPR,
4814 					 logical_type_node,
4815 					 info->start[dim], lbound);
4816 		  tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4817 					 logical_type_node, non_zerosized, tmp);
4818 		  msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
4819 				   "below lower bound of %%ld",
4820 				   dim + 1, expr_name);
4821 		  gfc_trans_runtime_check (true, false, tmp, &inner,
4822 					   expr_loc, msg,
4823 		     fold_convert (long_integer_type_node, info->start[dim]),
4824 		     fold_convert (long_integer_type_node, lbound));
4825 		  free (msg);
4826 		}
4827 
4828 	      /* Compute the last element of the range, which is not
4829 		 necessarily "end" (think 0:5:3, which doesn't contain 5)
4830 		 and check it against both lower and upper bounds.  */
4831 
4832 	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
4833 				     gfc_array_index_type, end,
4834 				     info->start[dim]);
4835 	      tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
4836 				     gfc_array_index_type, tmp,
4837 				     info->stride[dim]);
4838 	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
4839 				     gfc_array_index_type, end, tmp);
4840 	      tmp2 = fold_build2_loc (input_location, LT_EXPR,
4841 				      logical_type_node, tmp, lbound);
4842 	      tmp2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4843 				      logical_type_node, non_zerosized, tmp2);
4844 	      if (check_upper)
4845 		{
4846 		  tmp3 = fold_build2_loc (input_location, GT_EXPR,
4847 					  logical_type_node, tmp, ubound);
4848 		  tmp3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4849 					  logical_type_node, non_zerosized, tmp3);
4850 		  msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
4851 				   "outside of expected range (%%ld:%%ld)",
4852 				   dim + 1, expr_name);
4853 		  gfc_trans_runtime_check (true, false, tmp2, &inner,
4854 					   expr_loc, msg,
4855 		     fold_convert (long_integer_type_node, tmp),
4856 		     fold_convert (long_integer_type_node, ubound),
4857 		     fold_convert (long_integer_type_node, lbound));
4858 		  gfc_trans_runtime_check (true, false, tmp3, &inner,
4859 					   expr_loc, msg,
4860 		     fold_convert (long_integer_type_node, tmp),
4861 		     fold_convert (long_integer_type_node, ubound),
4862 		     fold_convert (long_integer_type_node, lbound));
4863 		  free (msg);
4864 		}
4865 	      else
4866 		{
4867 		  msg = xasprintf ("Index '%%ld' of dimension %d of array '%s' "
4868 				   "below lower bound of %%ld",
4869 				   dim + 1, expr_name);
4870 		  gfc_trans_runtime_check (true, false, tmp2, &inner,
4871 					   expr_loc, msg,
4872 		     fold_convert (long_integer_type_node, tmp),
4873 		     fold_convert (long_integer_type_node, lbound));
4874 		  free (msg);
4875 		}
4876 
4877 	      /* Check the section sizes match.  */
4878 	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
4879 				     gfc_array_index_type, end,
4880 				     info->start[dim]);
4881 	      tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR,
4882 				     gfc_array_index_type, tmp,
4883 				     info->stride[dim]);
4884 	      tmp = fold_build2_loc (input_location, PLUS_EXPR,
4885 				     gfc_array_index_type,
4886 				     gfc_index_one_node, tmp);
4887 	      tmp = fold_build2_loc (input_location, MAX_EXPR,
4888 				     gfc_array_index_type, tmp,
4889 				     build_int_cst (gfc_array_index_type, 0));
4890 	      /* We remember the size of the first section, and check all the
4891 		 others against this.  */
4892 	      if (size[n])
4893 		{
4894 		  tmp3 = fold_build2_loc (input_location, NE_EXPR,
4895 					  logical_type_node, tmp, size[n]);
4896 		  msg = xasprintf ("Array bound mismatch for dimension %d "
4897 				   "of array '%s' (%%ld/%%ld)",
4898 				   dim + 1, expr_name);
4899 
4900 		  gfc_trans_runtime_check (true, false, tmp3, &inner,
4901 					   expr_loc, msg,
4902 			fold_convert (long_integer_type_node, tmp),
4903 			fold_convert (long_integer_type_node, size[n]));
4904 
4905 		  free (msg);
4906 		}
4907 	      else
4908 		size[n] = gfc_evaluate_now (tmp, &inner);
4909 	    }
4910 
4911 	  tmp = gfc_finish_block (&inner);
4912 
4913 	  /* For optional arguments, only check bounds if the argument is
4914 	     present.  */
4915 	  if ((expr->symtree->n.sym->attr.optional
4916 	       || expr->symtree->n.sym->attr.not_always_present)
4917 	      && expr->symtree->n.sym->attr.dummy)
4918 	    tmp = build3_v (COND_EXPR,
4919 			    gfc_conv_expr_present (expr->symtree->n.sym),
4920 			    tmp, build_empty_stmt (input_location));
4921 
4922 	  gfc_add_expr_to_block (&block, tmp);
4923 
4924 	}
4925 
4926       tmp = gfc_finish_block (&block);
4927       gfc_add_expr_to_block (&outer_loop->pre, tmp);
4928     }
4929 
4930   for (loop = loop->nested; loop; loop = loop->next)
4931     gfc_conv_ss_startstride (loop);
4932 }
4933 
4934 /* Return true if both symbols could refer to the same data object.  Does
4935    not take account of aliasing due to equivalence statements.  */
4936 
4937 static int
symbols_could_alias(gfc_symbol * lsym,gfc_symbol * rsym,bool lsym_pointer,bool lsym_target,bool rsym_pointer,bool rsym_target)4938 symbols_could_alias (gfc_symbol *lsym, gfc_symbol *rsym, bool lsym_pointer,
4939 		     bool lsym_target, bool rsym_pointer, bool rsym_target)
4940 {
4941   /* Aliasing isn't possible if the symbols have different base types.  */
4942   if (gfc_compare_types (&lsym->ts, &rsym->ts) == 0)
4943     return 0;
4944 
4945   /* Pointers can point to other pointers and target objects.  */
4946 
4947   if ((lsym_pointer && (rsym_pointer || rsym_target))
4948       || (rsym_pointer && (lsym_pointer || lsym_target)))
4949     return 1;
4950 
4951   /* Special case: Argument association, cf. F90 12.4.1.6, F2003 12.4.1.7
4952      and F2008 12.5.2.13 items 3b and 4b. The pointer case (a) is already
4953      checked above.  */
4954   if (lsym_target && rsym_target
4955       && ((lsym->attr.dummy && !lsym->attr.contiguous
4956 	   && (!lsym->attr.dimension || lsym->as->type == AS_ASSUMED_SHAPE))
4957 	  || (rsym->attr.dummy && !rsym->attr.contiguous
4958 	      && (!rsym->attr.dimension
4959 		  || rsym->as->type == AS_ASSUMED_SHAPE))))
4960     return 1;
4961 
4962   return 0;
4963 }
4964 
4965 
4966 /* Return true if the two SS could be aliased, i.e. both point to the same data
4967    object.  */
4968 /* TODO: resolve aliases based on frontend expressions.  */
4969 
4970 static int
gfc_could_be_alias(gfc_ss * lss,gfc_ss * rss)4971 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
4972 {
4973   gfc_ref *lref;
4974   gfc_ref *rref;
4975   gfc_expr *lexpr, *rexpr;
4976   gfc_symbol *lsym;
4977   gfc_symbol *rsym;
4978   bool lsym_pointer, lsym_target, rsym_pointer, rsym_target;
4979 
4980   lexpr = lss->info->expr;
4981   rexpr = rss->info->expr;
4982 
4983   lsym = lexpr->symtree->n.sym;
4984   rsym = rexpr->symtree->n.sym;
4985 
4986   lsym_pointer = lsym->attr.pointer;
4987   lsym_target = lsym->attr.target;
4988   rsym_pointer = rsym->attr.pointer;
4989   rsym_target = rsym->attr.target;
4990 
4991   if (symbols_could_alias (lsym, rsym, lsym_pointer, lsym_target,
4992 			   rsym_pointer, rsym_target))
4993     return 1;
4994 
4995   if (rsym->ts.type != BT_DERIVED && rsym->ts.type != BT_CLASS
4996       && lsym->ts.type != BT_DERIVED && lsym->ts.type != BT_CLASS)
4997     return 0;
4998 
4999   /* For derived types we must check all the component types.  We can ignore
5000      array references as these will have the same base type as the previous
5001      component ref.  */
5002   for (lref = lexpr->ref; lref != lss->info->data.array.ref; lref = lref->next)
5003     {
5004       if (lref->type != REF_COMPONENT)
5005 	continue;
5006 
5007       lsym_pointer = lsym_pointer || lref->u.c.sym->attr.pointer;
5008       lsym_target  = lsym_target  || lref->u.c.sym->attr.target;
5009 
5010       if (symbols_could_alias (lref->u.c.sym, rsym, lsym_pointer, lsym_target,
5011 			       rsym_pointer, rsym_target))
5012 	return 1;
5013 
5014       if ((lsym_pointer && (rsym_pointer || rsym_target))
5015 	  || (rsym_pointer && (lsym_pointer || lsym_target)))
5016 	{
5017 	  if (gfc_compare_types (&lref->u.c.component->ts,
5018 				 &rsym->ts))
5019 	    return 1;
5020 	}
5021 
5022       for (rref = rexpr->ref; rref != rss->info->data.array.ref;
5023 	   rref = rref->next)
5024 	{
5025 	  if (rref->type != REF_COMPONENT)
5026 	    continue;
5027 
5028 	  rsym_pointer = rsym_pointer || rref->u.c.sym->attr.pointer;
5029 	  rsym_target  = lsym_target  || rref->u.c.sym->attr.target;
5030 
5031 	  if (symbols_could_alias (lref->u.c.sym, rref->u.c.sym,
5032 				   lsym_pointer, lsym_target,
5033 				   rsym_pointer, rsym_target))
5034 	    return 1;
5035 
5036 	  if ((lsym_pointer && (rsym_pointer || rsym_target))
5037 	      || (rsym_pointer && (lsym_pointer || lsym_target)))
5038 	    {
5039 	      if (gfc_compare_types (&lref->u.c.component->ts,
5040 				     &rref->u.c.sym->ts))
5041 		return 1;
5042 	      if (gfc_compare_types (&lref->u.c.sym->ts,
5043 				     &rref->u.c.component->ts))
5044 		return 1;
5045 	      if (gfc_compare_types (&lref->u.c.component->ts,
5046 				     &rref->u.c.component->ts))
5047 		return 1;
5048 	    }
5049 	}
5050     }
5051 
5052   lsym_pointer = lsym->attr.pointer;
5053   lsym_target = lsym->attr.target;
5054 
5055   for (rref = rexpr->ref; rref != rss->info->data.array.ref; rref = rref->next)
5056     {
5057       if (rref->type != REF_COMPONENT)
5058 	break;
5059 
5060       rsym_pointer = rsym_pointer || rref->u.c.sym->attr.pointer;
5061       rsym_target  = lsym_target  || rref->u.c.sym->attr.target;
5062 
5063       if (symbols_could_alias (rref->u.c.sym, lsym,
5064 			       lsym_pointer, lsym_target,
5065 			       rsym_pointer, rsym_target))
5066 	return 1;
5067 
5068       if ((lsym_pointer && (rsym_pointer || rsym_target))
5069 	  || (rsym_pointer && (lsym_pointer || lsym_target)))
5070 	{
5071 	  if (gfc_compare_types (&lsym->ts, &rref->u.c.component->ts))
5072 	    return 1;
5073 	}
5074     }
5075 
5076   return 0;
5077 }
5078 
5079 
5080 /* Resolve array data dependencies.  Creates a temporary if required.  */
5081 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
5082    dependency.cc.  */
5083 
5084 void
gfc_conv_resolve_dependencies(gfc_loopinfo * loop,gfc_ss * dest,gfc_ss * rss)5085 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
5086 			       gfc_ss * rss)
5087 {
5088   gfc_ss *ss;
5089   gfc_ref *lref;
5090   gfc_ref *rref;
5091   gfc_ss_info *ss_info;
5092   gfc_expr *dest_expr;
5093   gfc_expr *ss_expr;
5094   int nDepend = 0;
5095   int i, j;
5096 
5097   loop->temp_ss = NULL;
5098   dest_expr = dest->info->expr;
5099 
5100   for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
5101     {
5102       ss_info = ss->info;
5103       ss_expr = ss_info->expr;
5104 
5105       if (ss_info->array_outer_dependency)
5106 	{
5107 	  nDepend = 1;
5108 	  break;
5109 	}
5110 
5111       if (ss_info->type != GFC_SS_SECTION)
5112 	{
5113 	  if (flag_realloc_lhs
5114 	      && dest_expr != ss_expr
5115 	      && gfc_is_reallocatable_lhs (dest_expr)
5116 	      && ss_expr->rank)
5117 	    nDepend = gfc_check_dependency (dest_expr, ss_expr, true);
5118 
5119 	  /* Check for cases like   c(:)(1:2) = c(2)(2:3)  */
5120 	  if (!nDepend && dest_expr->rank > 0
5121 	      && dest_expr->ts.type == BT_CHARACTER
5122 	      && ss_expr->expr_type == EXPR_VARIABLE)
5123 
5124 	    nDepend = gfc_check_dependency (dest_expr, ss_expr, false);
5125 
5126 	  if (ss_info->type == GFC_SS_REFERENCE
5127 	      && gfc_check_dependency (dest_expr, ss_expr, false))
5128 	    ss_info->data.scalar.needs_temporary = 1;
5129 
5130 	  if (nDepend)
5131 	    break;
5132 	  else
5133 	    continue;
5134 	}
5135 
5136       if (dest_expr->symtree->n.sym != ss_expr->symtree->n.sym)
5137 	{
5138 	  if (gfc_could_be_alias (dest, ss)
5139 	      || gfc_are_equivalenced_arrays (dest_expr, ss_expr))
5140 	    {
5141 	      nDepend = 1;
5142 	      break;
5143 	    }
5144 	}
5145       else
5146 	{
5147 	  lref = dest_expr->ref;
5148 	  rref = ss_expr->ref;
5149 
5150 	  nDepend = gfc_dep_resolver (lref, rref, &loop->reverse[0]);
5151 
5152 	  if (nDepend == 1)
5153 	    break;
5154 
5155 	  for (i = 0; i < dest->dimen; i++)
5156 	    for (j = 0; j < ss->dimen; j++)
5157 	      if (i != j
5158 		  && dest->dim[i] == ss->dim[j])
5159 		{
5160 		  /* If we don't access array elements in the same order,
5161 		     there is a dependency.  */
5162 		  nDepend = 1;
5163 		  goto temporary;
5164 		}
5165 #if 0
5166 	  /* TODO : loop shifting.  */
5167 	  if (nDepend == 1)
5168 	    {
5169 	      /* Mark the dimensions for LOOP SHIFTING */
5170 	      for (n = 0; n < loop->dimen; n++)
5171 	        {
5172 	          int dim = dest->data.info.dim[n];
5173 
5174 		  if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
5175 		    depends[n] = 2;
5176 		  else if (! gfc_is_same_range (&lref->u.ar,
5177 						&rref->u.ar, dim, 0))
5178 		    depends[n] = 1;
5179 	         }
5180 
5181 	      /* Put all the dimensions with dependencies in the
5182 		 innermost loops.  */
5183 	      dim = 0;
5184 	      for (n = 0; n < loop->dimen; n++)
5185 		{
5186 		  gcc_assert (loop->order[n] == n);
5187 		  if (depends[n])
5188 		  loop->order[dim++] = n;
5189 		}
5190 	      for (n = 0; n < loop->dimen; n++)
5191 	        {
5192 		  if (! depends[n])
5193 		  loop->order[dim++] = n;
5194 		}
5195 
5196 	      gcc_assert (dim == loop->dimen);
5197 	      break;
5198 	    }
5199 #endif
5200 	}
5201     }
5202 
5203 temporary:
5204 
5205   if (nDepend == 1)
5206     {
5207       tree base_type = gfc_typenode_for_spec (&dest_expr->ts);
5208       if (GFC_ARRAY_TYPE_P (base_type)
5209 	  || GFC_DESCRIPTOR_TYPE_P (base_type))
5210 	base_type = gfc_get_element_type (base_type);
5211       loop->temp_ss = gfc_get_temp_ss (base_type, dest->info->string_length,
5212 				       loop->dimen);
5213       gfc_add_ss_to_loop (loop, loop->temp_ss);
5214     }
5215   else
5216     loop->temp_ss = NULL;
5217 }
5218 
5219 
5220 /* Browse through each array's information from the scalarizer and set the loop
5221    bounds according to the "best" one (per dimension), i.e. the one which
5222    provides the most information (constant bounds, shape, etc.).  */
5223 
5224 static void
set_loop_bounds(gfc_loopinfo * loop)5225 set_loop_bounds (gfc_loopinfo *loop)
5226 {
5227   int n, dim, spec_dim;
5228   gfc_array_info *info;
5229   gfc_array_info *specinfo;
5230   gfc_ss *ss;
5231   tree tmp;
5232   gfc_ss **loopspec;
5233   bool dynamic[GFC_MAX_DIMENSIONS];
5234   mpz_t *cshape;
5235   mpz_t i;
5236   bool nonoptional_arr;
5237 
5238   gfc_loopinfo * const outer_loop = outermost_loop (loop);
5239 
5240   loopspec = loop->specloop;
5241 
5242   mpz_init (i);
5243   for (n = 0; n < loop->dimen; n++)
5244     {
5245       loopspec[n] = NULL;
5246       dynamic[n] = false;
5247 
5248       /* If there are both optional and nonoptional array arguments, scalarize
5249 	 over the nonoptional; otherwise, it does not matter as then all
5250 	 (optional) arrays have to be present per F2008, 125.2.12p3(6).  */
5251 
5252       nonoptional_arr = false;
5253 
5254       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
5255 	if (ss->info->type != GFC_SS_SCALAR && ss->info->type != GFC_SS_TEMP
5256 	    && ss->info->type != GFC_SS_REFERENCE && !ss->info->can_be_null_ref)
5257 	  {
5258 	    nonoptional_arr = true;
5259 	    break;
5260 	  }
5261 
5262       /* We use one SS term, and use that to determine the bounds of the
5263 	 loop for this dimension.  We try to pick the simplest term.  */
5264       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
5265 	{
5266 	  gfc_ss_type ss_type;
5267 
5268 	  ss_type = ss->info->type;
5269 	  if (ss_type == GFC_SS_SCALAR
5270 	      || ss_type == GFC_SS_TEMP
5271 	      || ss_type == GFC_SS_REFERENCE
5272 	      || (ss->info->can_be_null_ref && nonoptional_arr))
5273 	    continue;
5274 
5275 	  info = &ss->info->data.array;
5276 	  dim = ss->dim[n];
5277 
5278 	  if (loopspec[n] != NULL)
5279 	    {
5280 	      specinfo = &loopspec[n]->info->data.array;
5281 	      spec_dim = loopspec[n]->dim[n];
5282 	    }
5283 	  else
5284 	    {
5285 	      /* Silence uninitialized warnings.  */
5286 	      specinfo = NULL;
5287 	      spec_dim = 0;
5288 	    }
5289 
5290 	  if (info->shape)
5291 	    {
5292 	      /* The frontend has worked out the size for us.  */
5293 	      if (!loopspec[n]
5294 		  || !specinfo->shape
5295 		  || !integer_zerop (specinfo->start[spec_dim]))
5296 		/* Prefer zero-based descriptors if possible.  */
5297 		loopspec[n] = ss;
5298 	      continue;
5299 	    }
5300 
5301 	  if (ss_type == GFC_SS_CONSTRUCTOR)
5302 	    {
5303 	      gfc_constructor_base base;
5304 	      /* An unknown size constructor will always be rank one.
5305 		 Higher rank constructors will either have known shape,
5306 		 or still be wrapped in a call to reshape.  */
5307 	      gcc_assert (loop->dimen == 1);
5308 
5309 	      /* Always prefer to use the constructor bounds if the size
5310 		 can be determined at compile time.  Prefer not to otherwise,
5311 		 since the general case involves realloc, and it's better to
5312 		 avoid that overhead if possible.  */
5313 	      base = ss->info->expr->value.constructor;
5314 	      dynamic[n] = gfc_get_array_constructor_size (&i, base);
5315 	      if (!dynamic[n] || !loopspec[n])
5316 		loopspec[n] = ss;
5317 	      continue;
5318 	    }
5319 
5320 	  /* Avoid using an allocatable lhs in an assignment, since
5321 	     there might be a reallocation coming.  */
5322 	  if (loopspec[n] && ss->is_alloc_lhs)
5323 	    continue;
5324 
5325 	  if (!loopspec[n])
5326 	    loopspec[n] = ss;
5327 	  /* Criteria for choosing a loop specifier (most important first):
5328 	     doesn't need realloc
5329 	     stride of one
5330 	     known stride
5331 	     known lower bound
5332 	     known upper bound
5333 	   */
5334 	  else if (loopspec[n]->info->type == GFC_SS_CONSTRUCTOR && dynamic[n])
5335 	    loopspec[n] = ss;
5336 	  else if (integer_onep (info->stride[dim])
5337 		   && !integer_onep (specinfo->stride[spec_dim]))
5338 	    loopspec[n] = ss;
5339 	  else if (INTEGER_CST_P (info->stride[dim])
5340 		   && !INTEGER_CST_P (specinfo->stride[spec_dim]))
5341 	    loopspec[n] = ss;
5342 	  else if (INTEGER_CST_P (info->start[dim])
5343 		   && !INTEGER_CST_P (specinfo->start[spec_dim])
5344 		   && integer_onep (info->stride[dim])
5345 		      == integer_onep (specinfo->stride[spec_dim])
5346 		   && INTEGER_CST_P (info->stride[dim])
5347 		      == INTEGER_CST_P (specinfo->stride[spec_dim]))
5348 	    loopspec[n] = ss;
5349 	  /* We don't work out the upper bound.
5350 	     else if (INTEGER_CST_P (info->finish[n])
5351 	     && ! INTEGER_CST_P (specinfo->finish[n]))
5352 	     loopspec[n] = ss; */
5353 	}
5354 
5355       /* We should have found the scalarization loop specifier.  If not,
5356 	 that's bad news.  */
5357       gcc_assert (loopspec[n]);
5358 
5359       info = &loopspec[n]->info->data.array;
5360       dim = loopspec[n]->dim[n];
5361 
5362       /* Set the extents of this range.  */
5363       cshape = info->shape;
5364       if (cshape && INTEGER_CST_P (info->start[dim])
5365 	  && INTEGER_CST_P (info->stride[dim]))
5366 	{
5367 	  loop->from[n] = info->start[dim];
5368 	  mpz_set (i, cshape[get_array_ref_dim_for_loop_dim (loopspec[n], n)]);
5369 	  mpz_sub_ui (i, i, 1);
5370 	  /* To = from + (size - 1) * stride.  */
5371 	  tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
5372 	  if (!integer_onep (info->stride[dim]))
5373 	    tmp = fold_build2_loc (input_location, MULT_EXPR,
5374 				   gfc_array_index_type, tmp,
5375 				   info->stride[dim]);
5376 	  loop->to[n] = fold_build2_loc (input_location, PLUS_EXPR,
5377 					 gfc_array_index_type,
5378 					 loop->from[n], tmp);
5379 	}
5380       else
5381 	{
5382 	  loop->from[n] = info->start[dim];
5383 	  switch (loopspec[n]->info->type)
5384 	    {
5385 	    case GFC_SS_CONSTRUCTOR:
5386 	      /* The upper bound is calculated when we expand the
5387 		 constructor.  */
5388 	      gcc_assert (loop->to[n] == NULL_TREE);
5389 	      break;
5390 
5391 	    case GFC_SS_SECTION:
5392 	      /* Use the end expression if it exists and is not constant,
5393 		 so that it is only evaluated once.  */
5394 	      loop->to[n] = info->end[dim];
5395 	      break;
5396 
5397 	    case GFC_SS_FUNCTION:
5398 	      /* The loop bound will be set when we generate the call.  */
5399 	      gcc_assert (loop->to[n] == NULL_TREE);
5400 	      break;
5401 
5402 	    case GFC_SS_INTRINSIC:
5403 	      {
5404 		gfc_expr *expr = loopspec[n]->info->expr;
5405 
5406 		/* The {l,u}bound of an assumed rank.  */
5407 		if (expr->value.function.isym->id == GFC_ISYM_SHAPE)
5408 		  gcc_assert (expr->value.function.actual->expr->rank == -1);
5409 		else
5410 		  gcc_assert ((expr->value.function.isym->id == GFC_ISYM_LBOUND
5411 			       || expr->value.function.isym->id == GFC_ISYM_UBOUND)
5412 			      && expr->value.function.actual->next->expr == NULL
5413 			      && expr->value.function.actual->expr->rank == -1);
5414 
5415 		loop->to[n] = info->end[dim];
5416 		break;
5417 	      }
5418 
5419 	    case GFC_SS_COMPONENT:
5420 	      {
5421 		if (info->end[dim] != NULL_TREE)
5422 		  {
5423 		    loop->to[n] = info->end[dim];
5424 		    break;
5425 		  }
5426 		else
5427 		  gcc_unreachable ();
5428 	      }
5429 
5430 	    default:
5431 	      gcc_unreachable ();
5432 	    }
5433 	}
5434 
5435       /* Transform everything so we have a simple incrementing variable.  */
5436       if (integer_onep (info->stride[dim]))
5437 	info->delta[dim] = gfc_index_zero_node;
5438       else
5439 	{
5440 	  /* Set the delta for this section.  */
5441 	  info->delta[dim] = gfc_evaluate_now (loop->from[n], &outer_loop->pre);
5442 	  /* Number of iterations is (end - start + step) / step.
5443 	     with start = 0, this simplifies to
5444 	     last = end / step;
5445 	     for (i = 0; i<=last; i++){...};  */
5446 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
5447 				 gfc_array_index_type, loop->to[n],
5448 				 loop->from[n]);
5449 	  tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR,
5450 				 gfc_array_index_type, tmp, info->stride[dim]);
5451 	  tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
5452 				 tmp, build_int_cst (gfc_array_index_type, -1));
5453 	  loop->to[n] = gfc_evaluate_now (tmp, &outer_loop->pre);
5454 	  /* Make the loop variable start at 0.  */
5455 	  loop->from[n] = gfc_index_zero_node;
5456 	}
5457     }
5458   mpz_clear (i);
5459 
5460   for (loop = loop->nested; loop; loop = loop->next)
5461     set_loop_bounds (loop);
5462 }
5463 
5464 
5465 /* Initialize the scalarization loop.  Creates the loop variables.  Determines
5466    the range of the loop variables.  Creates a temporary if required.
5467    Also generates code for scalar expressions which have been
5468    moved outside the loop.  */
5469 
5470 void
gfc_conv_loop_setup(gfc_loopinfo * loop,locus * where)5471 gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
5472 {
5473   gfc_ss *tmp_ss;
5474   tree tmp;
5475 
5476   set_loop_bounds (loop);
5477 
5478   /* Add all the scalar code that can be taken out of the loops.
5479      This may include calculating the loop bounds, so do it before
5480      allocating the temporary.  */
5481   gfc_add_loop_ss_code (loop, loop->ss, false, where);
5482 
5483   tmp_ss = loop->temp_ss;
5484   /* If we want a temporary then create it.  */
5485   if (tmp_ss != NULL)
5486     {
5487       gfc_ss_info *tmp_ss_info;
5488 
5489       tmp_ss_info = tmp_ss->info;
5490       gcc_assert (tmp_ss_info->type == GFC_SS_TEMP);
5491       gcc_assert (loop->parent == NULL);
5492 
5493       /* Make absolutely sure that this is a complete type.  */
5494       if (tmp_ss_info->string_length)
5495 	tmp_ss_info->data.temp.type
5496 		= gfc_get_character_type_len_for_eltype
5497 			(TREE_TYPE (tmp_ss_info->data.temp.type),
5498 			 tmp_ss_info->string_length);
5499 
5500       tmp = tmp_ss_info->data.temp.type;
5501       memset (&tmp_ss_info->data.array, 0, sizeof (gfc_array_info));
5502       tmp_ss_info->type = GFC_SS_SECTION;
5503 
5504       gcc_assert (tmp_ss->dimen != 0);
5505 
5506       gfc_trans_create_temp_array (&loop->pre, &loop->post, tmp_ss, tmp,
5507 				   NULL_TREE, false, true, false, where);
5508     }
5509 
5510   /* For array parameters we don't have loop variables, so don't calculate the
5511      translations.  */
5512   if (!loop->array_parameter)
5513     gfc_set_delta (loop);
5514 }
5515 
5516 
5517 /* Calculates how to transform from loop variables to array indices for each
5518    array: once loop bounds are chosen, sets the difference (DELTA field) between
5519    loop bounds and array reference bounds, for each array info.  */
5520 
5521 void
gfc_set_delta(gfc_loopinfo * loop)5522 gfc_set_delta (gfc_loopinfo *loop)
5523 {
5524   gfc_ss *ss, **loopspec;
5525   gfc_array_info *info;
5526   tree tmp;
5527   int n, dim;
5528 
5529   gfc_loopinfo * const outer_loop = outermost_loop (loop);
5530 
5531   loopspec = loop->specloop;
5532 
5533   /* Calculate the translation from loop variables to array indices.  */
5534   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
5535     {
5536       gfc_ss_type ss_type;
5537 
5538       ss_type = ss->info->type;
5539       if (ss_type != GFC_SS_SECTION
5540 	  && ss_type != GFC_SS_COMPONENT
5541 	  && ss_type != GFC_SS_CONSTRUCTOR)
5542 	continue;
5543 
5544       info = &ss->info->data.array;
5545 
5546       for (n = 0; n < ss->dimen; n++)
5547 	{
5548 	  /* If we are specifying the range the delta is already set.  */
5549 	  if (loopspec[n] != ss)
5550 	    {
5551 	      dim = ss->dim[n];
5552 
5553 	      /* Calculate the offset relative to the loop variable.
5554 		 First multiply by the stride.  */
5555 	      tmp = loop->from[n];
5556 	      if (!integer_onep (info->stride[dim]))
5557 		tmp = fold_build2_loc (input_location, MULT_EXPR,
5558 				       gfc_array_index_type,
5559 				       tmp, info->stride[dim]);
5560 
5561 	      /* Then subtract this from our starting value.  */
5562 	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
5563 				     gfc_array_index_type,
5564 				     info->start[dim], tmp);
5565 
5566 	      info->delta[dim] = gfc_evaluate_now (tmp, &outer_loop->pre);
5567 	    }
5568 	}
5569     }
5570 
5571   for (loop = loop->nested; loop; loop = loop->next)
5572     gfc_set_delta (loop);
5573 }
5574 
5575 
5576 /* Calculate the size of a given array dimension from the bounds.  This
5577    is simply (ubound - lbound + 1) if this expression is positive
5578    or 0 if it is negative (pick either one if it is zero).  Optionally
5579    (if or_expr is present) OR the (expression != 0) condition to it.  */
5580 
5581 tree
gfc_conv_array_extent_dim(tree lbound,tree ubound,tree * or_expr)5582 gfc_conv_array_extent_dim (tree lbound, tree ubound, tree* or_expr)
5583 {
5584   tree res;
5585   tree cond;
5586 
5587   /* Calculate (ubound - lbound + 1).  */
5588   res = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5589 			 ubound, lbound);
5590   res = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, res,
5591 			 gfc_index_one_node);
5592 
5593   /* Check whether the size for this dimension is negative.  */
5594   cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, res,
5595 			  gfc_index_zero_node);
5596   res = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
5597 			 gfc_index_zero_node, res);
5598 
5599   /* Build OR expression.  */
5600   if (or_expr)
5601     *or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
5602 				logical_type_node, *or_expr, cond);
5603 
5604   return res;
5605 }
5606 
5607 
5608 /* For an array descriptor, get the total number of elements.  This is just
5609    the product of the extents along from_dim to to_dim.  */
5610 
5611 static tree
gfc_conv_descriptor_size_1(tree desc,int from_dim,int to_dim)5612 gfc_conv_descriptor_size_1 (tree desc, int from_dim, int to_dim)
5613 {
5614   tree res;
5615   int dim;
5616 
5617   res = gfc_index_one_node;
5618 
5619   for (dim = from_dim; dim < to_dim; ++dim)
5620     {
5621       tree lbound;
5622       tree ubound;
5623       tree extent;
5624 
5625       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
5626       ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
5627 
5628       extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
5629       res = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5630 			     res, extent);
5631     }
5632 
5633   return res;
5634 }
5635 
5636 
5637 /* Full size of an array.  */
5638 
5639 tree
gfc_conv_descriptor_size(tree desc,int rank)5640 gfc_conv_descriptor_size (tree desc, int rank)
5641 {
5642   return gfc_conv_descriptor_size_1 (desc, 0, rank);
5643 }
5644 
5645 
5646 /* Size of a coarray for all dimensions but the last.  */
5647 
5648 tree
gfc_conv_descriptor_cosize(tree desc,int rank,int corank)5649 gfc_conv_descriptor_cosize (tree desc, int rank, int corank)
5650 {
5651   return gfc_conv_descriptor_size_1 (desc, rank, rank + corank - 1);
5652 }
5653 
5654 
5655 /* Fills in an array descriptor, and returns the size of the array.
5656    The size will be a simple_val, ie a variable or a constant.  Also
5657    calculates the offset of the base.  The pointer argument overflow,
5658    which should be of integer type, will increase in value if overflow
5659    occurs during the size calculation.  Returns the size of the array.
5660    {
5661     stride = 1;
5662     offset = 0;
5663     for (n = 0; n < rank; n++)
5664       {
5665 	a.lbound[n] = specified_lower_bound;
5666 	offset = offset + a.lbond[n] * stride;
5667 	size = 1 - lbound;
5668 	a.ubound[n] = specified_upper_bound;
5669 	a.stride[n] = stride;
5670 	size = size >= 0 ? ubound + size : 0; //size = ubound + 1 - lbound
5671 	overflow += size == 0 ? 0: (MAX/size < stride ? 1: 0);
5672 	stride = stride * size;
5673       }
5674     for (n = rank; n < rank+corank; n++)
5675       (Set lcobound/ucobound as above.)
5676     element_size = sizeof (array element);
5677     if (!rank)
5678       return element_size
5679     stride = (size_t) stride;
5680     overflow += element_size == 0 ? 0: (MAX/element_size < stride ? 1: 0);
5681     stride = stride * element_size;
5682     return (stride);
5683    }  */
5684 /*GCC ARRAYS*/
5685 
5686 static tree
gfc_array_init_size(tree descriptor,int rank,int corank,tree * poffset,gfc_expr ** lower,gfc_expr ** upper,stmtblock_t * pblock,stmtblock_t * descriptor_block,tree * overflow,tree expr3_elem_size,tree * nelems,gfc_expr * expr3,tree expr3_desc,bool e3_has_nodescriptor,gfc_expr * expr,tree * element_size)5687 gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
5688 		     gfc_expr ** lower, gfc_expr ** upper, stmtblock_t * pblock,
5689 		     stmtblock_t * descriptor_block, tree * overflow,
5690 		     tree expr3_elem_size, tree *nelems, gfc_expr *expr3,
5691 		     tree expr3_desc, bool e3_has_nodescriptor, gfc_expr *expr,
5692 		     tree *element_size)
5693 {
5694   tree type;
5695   tree tmp;
5696   tree size;
5697   tree offset;
5698   tree stride;
5699   tree or_expr;
5700   tree thencase;
5701   tree elsecase;
5702   tree cond;
5703   tree var;
5704   stmtblock_t thenblock;
5705   stmtblock_t elseblock;
5706   gfc_expr *ubound;
5707   gfc_se se;
5708   int n;
5709 
5710   type = TREE_TYPE (descriptor);
5711 
5712   stride = gfc_index_one_node;
5713   offset = gfc_index_zero_node;
5714 
5715   /* Set the dtype before the alloc, because registration of coarrays needs
5716      it initialized.  */
5717   if (expr->ts.type == BT_CHARACTER
5718       && expr->ts.deferred
5719       && VAR_P (expr->ts.u.cl->backend_decl))
5720     {
5721       type = gfc_typenode_for_spec (&expr->ts);
5722       tmp = gfc_conv_descriptor_dtype (descriptor);
5723       gfc_add_modify (pblock, tmp, gfc_get_dtype_rank_type (rank, type));
5724     }
5725   else if (expr->ts.type == BT_CHARACTER
5726 	   && expr->ts.deferred
5727 	   && TREE_CODE (descriptor) == COMPONENT_REF)
5728     {
5729       /* Deferred character components have their string length tucked away
5730 	 in a hidden field of the derived type. Obtain that and use it to
5731 	 set the dtype. The charlen backend decl is zero because the field
5732 	 type is zero length.  */
5733       gfc_ref *ref;
5734       tmp = NULL_TREE;
5735       for (ref = expr->ref; ref; ref = ref->next)
5736 	if (ref->type == REF_COMPONENT
5737 	    && gfc_deferred_strlen (ref->u.c.component, &tmp))
5738 	  break;
5739       gcc_assert (tmp != NULL_TREE);
5740       tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp),
5741 			     TREE_OPERAND (descriptor, 0), tmp, NULL_TREE);
5742       tmp = fold_convert (gfc_charlen_type_node, tmp);
5743       type = gfc_get_character_type_len (expr->ts.kind, tmp);
5744       tmp = gfc_conv_descriptor_dtype (descriptor);
5745       gfc_add_modify (pblock, tmp, gfc_get_dtype_rank_type (rank, type));
5746     }
5747   else
5748     {
5749       tmp = gfc_conv_descriptor_dtype (descriptor);
5750       gfc_add_modify (pblock, tmp, gfc_get_dtype (type));
5751     }
5752 
5753   or_expr = logical_false_node;
5754 
5755   for (n = 0; n < rank; n++)
5756     {
5757       tree conv_lbound;
5758       tree conv_ubound;
5759 
5760       /* We have 3 possibilities for determining the size of the array:
5761 	 lower == NULL    => lbound = 1, ubound = upper[n]
5762 	 upper[n] = NULL  => lbound = 1, ubound = lower[n]
5763 	 upper[n] != NULL => lbound = lower[n], ubound = upper[n]  */
5764       ubound = upper[n];
5765 
5766       /* Set lower bound.  */
5767       gfc_init_se (&se, NULL);
5768       if (expr3_desc != NULL_TREE)
5769 	{
5770 	  if (e3_has_nodescriptor)
5771 	    /* The lbound of nondescriptor arrays like array constructors,
5772 	       nonallocatable/nonpointer function results/variables,
5773 	       start at zero, but when allocating it, the standard expects
5774 	       the array to start at one.  */
5775 	    se.expr = gfc_index_one_node;
5776 	  else
5777 	    se.expr = gfc_conv_descriptor_lbound_get (expr3_desc,
5778 						      gfc_rank_cst[n]);
5779 	}
5780       else if (lower == NULL)
5781 	se.expr = gfc_index_one_node;
5782       else
5783 	{
5784 	  gcc_assert (lower[n]);
5785 	  if (ubound)
5786 	    {
5787 	      gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
5788 	      gfc_add_block_to_block (pblock, &se.pre);
5789 	    }
5790 	  else
5791 	    {
5792 	      se.expr = gfc_index_one_node;
5793 	      ubound = lower[n];
5794 	    }
5795 	}
5796       gfc_conv_descriptor_lbound_set (descriptor_block, descriptor,
5797 				      gfc_rank_cst[n], se.expr);
5798       conv_lbound = se.expr;
5799 
5800       /* Work out the offset for this component.  */
5801       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5802 			     se.expr, stride);
5803       offset = fold_build2_loc (input_location, MINUS_EXPR,
5804 				gfc_array_index_type, offset, tmp);
5805 
5806       /* Set upper bound.  */
5807       gfc_init_se (&se, NULL);
5808       if (expr3_desc != NULL_TREE)
5809 	{
5810 	  if (e3_has_nodescriptor)
5811 	    {
5812 	      /* The lbound of nondescriptor arrays like array constructors,
5813 		 nonallocatable/nonpointer function results/variables,
5814 		 start at zero, but when allocating it, the standard expects
5815 		 the array to start at one.  Therefore fix the upper bound to be
5816 		 (desc.ubound - desc.lbound) + 1.  */
5817 	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
5818 				     gfc_array_index_type,
5819 				     gfc_conv_descriptor_ubound_get (
5820 				       expr3_desc, gfc_rank_cst[n]),
5821 				     gfc_conv_descriptor_lbound_get (
5822 				       expr3_desc, gfc_rank_cst[n]));
5823 	      tmp = fold_build2_loc (input_location, PLUS_EXPR,
5824 				     gfc_array_index_type, tmp,
5825 				     gfc_index_one_node);
5826 	      se.expr = gfc_evaluate_now (tmp, pblock);
5827 	    }
5828 	  else
5829 	    se.expr = gfc_conv_descriptor_ubound_get (expr3_desc,
5830 						      gfc_rank_cst[n]);
5831 	}
5832       else
5833 	{
5834 	  gcc_assert (ubound);
5835 	  gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
5836 	  gfc_add_block_to_block (pblock, &se.pre);
5837 	  if (ubound->expr_type == EXPR_FUNCTION)
5838 	    se.expr = gfc_evaluate_now (se.expr, pblock);
5839 	}
5840       gfc_conv_descriptor_ubound_set (descriptor_block, descriptor,
5841 				      gfc_rank_cst[n], se.expr);
5842       conv_ubound = se.expr;
5843 
5844       /* Store the stride.  */
5845       gfc_conv_descriptor_stride_set (descriptor_block, descriptor,
5846 				      gfc_rank_cst[n], stride);
5847 
5848       /* Calculate size and check whether extent is negative.  */
5849       size = gfc_conv_array_extent_dim (conv_lbound, conv_ubound, &or_expr);
5850       size = gfc_evaluate_now (size, pblock);
5851 
5852       /* Check whether multiplying the stride by the number of
5853 	 elements in this dimension would overflow. We must also check
5854 	 whether the current dimension has zero size in order to avoid
5855 	 division by zero.
5856       */
5857       tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
5858 			     gfc_array_index_type,
5859 			     fold_convert (gfc_array_index_type,
5860 					   TYPE_MAX_VALUE (gfc_array_index_type)),
5861 					   size);
5862       cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR,
5863 					    logical_type_node, tmp, stride),
5864 			   PRED_FORTRAN_OVERFLOW);
5865       tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
5866 			     integer_one_node, integer_zero_node);
5867       cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR,
5868 					    logical_type_node, size,
5869 					    gfc_index_zero_node),
5870 			   PRED_FORTRAN_SIZE_ZERO);
5871       tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
5872 			     integer_zero_node, tmp);
5873       tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
5874 			     *overflow, tmp);
5875       *overflow = gfc_evaluate_now (tmp, pblock);
5876 
5877       /* Multiply the stride by the number of elements in this dimension.  */
5878       stride = fold_build2_loc (input_location, MULT_EXPR,
5879 				gfc_array_index_type, stride, size);
5880       stride = gfc_evaluate_now (stride, pblock);
5881     }
5882 
5883   for (n = rank; n < rank + corank; n++)
5884     {
5885       ubound = upper[n];
5886 
5887       /* Set lower bound.  */
5888       gfc_init_se (&se, NULL);
5889       if (lower == NULL || lower[n] == NULL)
5890 	{
5891 	  gcc_assert (n == rank + corank - 1);
5892 	  se.expr = gfc_index_one_node;
5893 	}
5894       else
5895 	{
5896 	  if (ubound || n == rank + corank - 1)
5897 	    {
5898 	      gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
5899 	      gfc_add_block_to_block (pblock, &se.pre);
5900 	    }
5901 	  else
5902 	    {
5903 	      se.expr = gfc_index_one_node;
5904 	      ubound = lower[n];
5905 	    }
5906 	}
5907       gfc_conv_descriptor_lbound_set (descriptor_block, descriptor,
5908 				      gfc_rank_cst[n], se.expr);
5909 
5910       if (n < rank + corank - 1)
5911 	{
5912 	  gfc_init_se (&se, NULL);
5913 	  gcc_assert (ubound);
5914 	  gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
5915 	  gfc_add_block_to_block (pblock, &se.pre);
5916 	  gfc_conv_descriptor_ubound_set (descriptor_block, descriptor,
5917 					  gfc_rank_cst[n], se.expr);
5918 	}
5919     }
5920 
5921   /* The stride is the number of elements in the array, so multiply by the
5922      size of an element to get the total size.  Obviously, if there is a
5923      SOURCE expression (expr3) we must use its element size.  */
5924   if (expr3_elem_size != NULL_TREE)
5925     tmp = expr3_elem_size;
5926   else if (expr3 != NULL)
5927     {
5928       if (expr3->ts.type == BT_CLASS)
5929 	{
5930 	  gfc_se se_sz;
5931 	  gfc_expr *sz = gfc_copy_expr (expr3);
5932 	  gfc_add_vptr_component (sz);
5933 	  gfc_add_size_component (sz);
5934 	  gfc_init_se (&se_sz, NULL);
5935 	  gfc_conv_expr (&se_sz, sz);
5936 	  gfc_free_expr (sz);
5937 	  tmp = se_sz.expr;
5938 	}
5939       else
5940 	{
5941 	  tmp = gfc_typenode_for_spec (&expr3->ts);
5942 	  tmp = TYPE_SIZE_UNIT (tmp);
5943 	}
5944     }
5945   else
5946     tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
5947 
5948   /* Convert to size_t.  */
5949   *element_size = fold_convert (size_type_node, tmp);
5950 
5951   if (rank == 0)
5952     return *element_size;
5953 
5954   *nelems = gfc_evaluate_now (stride, pblock);
5955   stride = fold_convert (size_type_node, stride);
5956 
5957   /* First check for overflow. Since an array of type character can
5958      have zero element_size, we must check for that before
5959      dividing.  */
5960   tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
5961 			 size_type_node,
5962 			 TYPE_MAX_VALUE (size_type_node), *element_size);
5963   cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR,
5964 					logical_type_node, tmp, stride),
5965 		       PRED_FORTRAN_OVERFLOW);
5966   tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
5967 			 integer_one_node, integer_zero_node);
5968   cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR,
5969 					logical_type_node, *element_size,
5970 					build_int_cst (size_type_node, 0)),
5971 		       PRED_FORTRAN_SIZE_ZERO);
5972   tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
5973 			 integer_zero_node, tmp);
5974   tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
5975 			 *overflow, tmp);
5976   *overflow = gfc_evaluate_now (tmp, pblock);
5977 
5978   size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
5979 			  stride, *element_size);
5980 
5981   if (poffset != NULL)
5982     {
5983       offset = gfc_evaluate_now (offset, pblock);
5984       *poffset = offset;
5985     }
5986 
5987   if (integer_zerop (or_expr))
5988     return size;
5989   if (integer_onep (or_expr))
5990     return build_int_cst (size_type_node, 0);
5991 
5992   var = gfc_create_var (TREE_TYPE (size), "size");
5993   gfc_start_block (&thenblock);
5994   gfc_add_modify (&thenblock, var, build_int_cst (size_type_node, 0));
5995   thencase = gfc_finish_block (&thenblock);
5996 
5997   gfc_start_block (&elseblock);
5998   gfc_add_modify (&elseblock, var, size);
5999   elsecase = gfc_finish_block (&elseblock);
6000 
6001   tmp = gfc_evaluate_now (or_expr, pblock);
6002   tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
6003   gfc_add_expr_to_block (pblock, tmp);
6004 
6005   return var;
6006 }
6007 
6008 
6009 /* Retrieve the last ref from the chain.  This routine is specific to
6010    gfc_array_allocate ()'s needs.  */
6011 
6012 bool
retrieve_last_ref(gfc_ref ** ref_in,gfc_ref ** prev_ref_in)6013 retrieve_last_ref (gfc_ref **ref_in, gfc_ref **prev_ref_in)
6014 {
6015   gfc_ref *ref, *prev_ref;
6016 
6017   ref = *ref_in;
6018   /* Prevent warnings for uninitialized variables.  */
6019   prev_ref = *prev_ref_in;
6020   while (ref && ref->next != NULL)
6021     {
6022       gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT
6023 		  || (ref->u.ar.dimen == 0 && ref->u.ar.codimen > 0));
6024       prev_ref = ref;
6025       ref = ref->next;
6026     }
6027 
6028   if (ref == NULL || ref->type != REF_ARRAY)
6029     return false;
6030 
6031   *ref_in = ref;
6032   *prev_ref_in = prev_ref;
6033   return true;
6034 }
6035 
6036 /* Initializes the descriptor and generates a call to _gfor_allocate.  Does
6037    the work for an ALLOCATE statement.  */
6038 /*GCC ARRAYS*/
6039 
6040 bool
gfc_array_allocate(gfc_se * se,gfc_expr * expr,tree status,tree errmsg,tree errlen,tree label_finish,tree expr3_elem_size,tree * nelems,gfc_expr * expr3,tree e3_arr_desc,bool e3_has_nodescriptor)6041 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
6042 		    tree errlen, tree label_finish, tree expr3_elem_size,
6043 		    tree *nelems, gfc_expr *expr3, tree e3_arr_desc,
6044 		    bool e3_has_nodescriptor)
6045 {
6046   tree tmp;
6047   tree pointer;
6048   tree offset = NULL_TREE;
6049   tree token = NULL_TREE;
6050   tree size;
6051   tree msg;
6052   tree error = NULL_TREE;
6053   tree overflow; /* Boolean storing whether size calculation overflows.  */
6054   tree var_overflow = NULL_TREE;
6055   tree cond;
6056   tree set_descriptor;
6057   tree not_prev_allocated = NULL_TREE;
6058   tree element_size = NULL_TREE;
6059   stmtblock_t set_descriptor_block;
6060   stmtblock_t elseblock;
6061   gfc_expr **lower;
6062   gfc_expr **upper;
6063   gfc_ref *ref, *prev_ref = NULL, *coref;
6064   bool allocatable, coarray, dimension, alloc_w_e3_arr_spec = false,
6065       non_ulimate_coarray_ptr_comp;
6066 
6067   ref = expr->ref;
6068 
6069   /* Find the last reference in the chain.  */
6070   if (!retrieve_last_ref (&ref, &prev_ref))
6071     return false;
6072 
6073   /* Take the allocatable and coarray properties solely from the expr-ref's
6074      attributes and not from source=-expression.  */
6075   if (!prev_ref)
6076     {
6077       allocatable = expr->symtree->n.sym->attr.allocatable;
6078       dimension = expr->symtree->n.sym->attr.dimension;
6079       non_ulimate_coarray_ptr_comp = false;
6080     }
6081   else
6082     {
6083       allocatable = prev_ref->u.c.component->attr.allocatable;
6084       /* Pointer components in coarrayed derived types must be treated
6085 	 specially in that they are registered without a check if the are
6086 	 already associated.  This does not hold for ultimate coarray
6087 	 pointers.  */
6088       non_ulimate_coarray_ptr_comp = (prev_ref->u.c.component->attr.pointer
6089 	      && !prev_ref->u.c.component->attr.codimension);
6090       dimension = prev_ref->u.c.component->attr.dimension;
6091     }
6092 
6093   /* For allocatable/pointer arrays in derived types, one of the refs has to be
6094      a coarray.  In this case it does not matter whether we are on this_image
6095      or not.  */
6096   coarray = false;
6097   for (coref = expr->ref; coref; coref = coref->next)
6098     if (coref->type == REF_ARRAY && coref->u.ar.codimen > 0)
6099       {
6100 	coarray = true;
6101 	break;
6102       }
6103 
6104   if (!dimension)
6105     gcc_assert (coarray);
6106 
6107   if (ref->u.ar.type == AR_FULL && expr3 != NULL)
6108     {
6109       gfc_ref *old_ref = ref;
6110       /* F08:C633: Array shape from expr3.  */
6111       ref = expr3->ref;
6112 
6113       /* Find the last reference in the chain.  */
6114       if (!retrieve_last_ref (&ref, &prev_ref))
6115 	{
6116 	  if (expr3->expr_type == EXPR_FUNCTION
6117 	      && gfc_expr_attr (expr3).dimension)
6118 	    ref = old_ref;
6119 	  else
6120 	    return false;
6121 	}
6122       alloc_w_e3_arr_spec = true;
6123     }
6124 
6125   /* Figure out the size of the array.  */
6126   switch (ref->u.ar.type)
6127     {
6128     case AR_ELEMENT:
6129       if (!coarray)
6130 	{
6131 	  lower = NULL;
6132 	  upper = ref->u.ar.start;
6133 	  break;
6134 	}
6135       /* Fall through.  */
6136 
6137     case AR_SECTION:
6138       lower = ref->u.ar.start;
6139       upper = ref->u.ar.end;
6140       break;
6141 
6142     case AR_FULL:
6143       gcc_assert (ref->u.ar.as->type == AS_EXPLICIT
6144 		  || alloc_w_e3_arr_spec);
6145 
6146       lower = ref->u.ar.as->lower;
6147       upper = ref->u.ar.as->upper;
6148       break;
6149 
6150     default:
6151       gcc_unreachable ();
6152       break;
6153     }
6154 
6155   overflow = integer_zero_node;
6156 
6157   if (expr->ts.type == BT_CHARACTER
6158       && TREE_CODE (se->string_length) == COMPONENT_REF
6159       && expr->ts.u.cl->backend_decl != se->string_length
6160       && VAR_P (expr->ts.u.cl->backend_decl))
6161     gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
6162 		    fold_convert (TREE_TYPE (expr->ts.u.cl->backend_decl),
6163 				  se->string_length));
6164 
6165   gfc_init_block (&set_descriptor_block);
6166   /* Take the corank only from the actual ref and not from the coref.  The
6167      later will mislead the generation of the array dimensions for allocatable/
6168      pointer components in derived types.  */
6169   size = gfc_array_init_size (se->expr, alloc_w_e3_arr_spec ? expr->rank
6170 							   : ref->u.ar.as->rank,
6171 			      coarray ? ref->u.ar.as->corank : 0,
6172 			      &offset, lower, upper,
6173 			      &se->pre, &set_descriptor_block, &overflow,
6174 			      expr3_elem_size, nelems, expr3, e3_arr_desc,
6175 			      e3_has_nodescriptor, expr, &element_size);
6176 
6177   if (dimension)
6178     {
6179       var_overflow = gfc_create_var (integer_type_node, "overflow");
6180       gfc_add_modify (&se->pre, var_overflow, overflow);
6181 
6182       if (status == NULL_TREE)
6183 	{
6184 	  /* Generate the block of code handling overflow.  */
6185 	  msg = gfc_build_addr_expr (pchar_type_node,
6186 		    gfc_build_localized_cstring_const
6187   			("Integer overflow when calculating the amount of "
6188   			 "memory to allocate"));
6189 	  error = build_call_expr_loc (input_location,
6190 				       gfor_fndecl_runtime_error, 1, msg);
6191 	}
6192       else
6193 	{
6194 	  tree status_type = TREE_TYPE (status);
6195 	  stmtblock_t set_status_block;
6196 
6197 	  gfc_start_block (&set_status_block);
6198 	  gfc_add_modify (&set_status_block, status,
6199 			  build_int_cst (status_type, LIBERROR_ALLOCATION));
6200 	  error = gfc_finish_block (&set_status_block);
6201 	}
6202     }
6203 
6204   /* Allocate memory to store the data.  */
6205   if (POINTER_TYPE_P (TREE_TYPE (se->expr)))
6206     se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
6207 
6208   if (coarray && flag_coarray == GFC_FCOARRAY_LIB)
6209     {
6210       pointer = non_ulimate_coarray_ptr_comp ? se->expr
6211 				      : gfc_conv_descriptor_data_get (se->expr);
6212       token = gfc_conv_descriptor_token (se->expr);
6213       token = gfc_build_addr_expr (NULL_TREE, token);
6214     }
6215   else
6216     pointer = gfc_conv_descriptor_data_get (se->expr);
6217   STRIP_NOPS (pointer);
6218 
6219   if (allocatable)
6220     {
6221       not_prev_allocated = gfc_create_var (logical_type_node,
6222 					   "not_prev_allocated");
6223       tmp = fold_build2_loc (input_location, EQ_EXPR,
6224 			     logical_type_node, pointer,
6225 			     build_int_cst (TREE_TYPE (pointer), 0));
6226 
6227       gfc_add_modify (&se->pre, not_prev_allocated, tmp);
6228     }
6229 
6230   gfc_start_block (&elseblock);
6231 
6232   /* The allocatable variant takes the old pointer as first argument.  */
6233   if (allocatable)
6234     gfc_allocate_allocatable (&elseblock, pointer, size, token,
6235 			      status, errmsg, errlen, label_finish, expr,
6236 			      coref != NULL ? coref->u.ar.as->corank : 0);
6237   else if (non_ulimate_coarray_ptr_comp && token)
6238     /* The token is set only for GFC_FCOARRAY_LIB mode.  */
6239     gfc_allocate_using_caf_lib (&elseblock, pointer, size, token, status,
6240 				errmsg, errlen,
6241 				GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY);
6242   else
6243     gfc_allocate_using_malloc (&elseblock, pointer, size, status);
6244 
6245   if (dimension)
6246     {
6247       cond = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
6248 			   logical_type_node, var_overflow, integer_zero_node),
6249 			   PRED_FORTRAN_OVERFLOW);
6250       tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
6251 			     error, gfc_finish_block (&elseblock));
6252     }
6253   else
6254     tmp = gfc_finish_block (&elseblock);
6255 
6256   gfc_add_expr_to_block (&se->pre, tmp);
6257 
6258   /* Update the array descriptor with the offset and the span.  */
6259   if (dimension)
6260     {
6261       gfc_conv_descriptor_offset_set (&set_descriptor_block, se->expr, offset);
6262       tmp = fold_convert (gfc_array_index_type, element_size);
6263       gfc_conv_descriptor_span_set (&set_descriptor_block, se->expr, tmp);
6264     }
6265 
6266   set_descriptor = gfc_finish_block (&set_descriptor_block);
6267   if (status != NULL_TREE)
6268     {
6269       cond = fold_build2_loc (input_location, EQ_EXPR,
6270 			  logical_type_node, status,
6271 			  build_int_cst (TREE_TYPE (status), 0));
6272 
6273       if (not_prev_allocated != NULL_TREE)
6274 	cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
6275 				logical_type_node, cond, not_prev_allocated);
6276 
6277       gfc_add_expr_to_block (&se->pre,
6278 		 fold_build3_loc (input_location, COND_EXPR, void_type_node,
6279 				  cond,
6280 				  set_descriptor,
6281 				  build_empty_stmt (input_location)));
6282     }
6283   else
6284       gfc_add_expr_to_block (&se->pre, set_descriptor);
6285 
6286   return true;
6287 }
6288 
6289 
6290 /* Create an array constructor from an initialization expression.
6291    We assume the frontend already did any expansions and conversions.  */
6292 
6293 tree
gfc_conv_array_initializer(tree type,gfc_expr * expr)6294 gfc_conv_array_initializer (tree type, gfc_expr * expr)
6295 {
6296   gfc_constructor *c;
6297   tree tmp;
6298   gfc_se se;
6299   tree index, range;
6300   vec<constructor_elt, va_gc> *v = NULL;
6301 
6302   if (expr->expr_type == EXPR_VARIABLE
6303       && expr->symtree->n.sym->attr.flavor == FL_PARAMETER
6304       && expr->symtree->n.sym->value)
6305     expr = expr->symtree->n.sym->value;
6306 
6307   switch (expr->expr_type)
6308     {
6309     case EXPR_CONSTANT:
6310     case EXPR_STRUCTURE:
6311       /* A single scalar or derived type value.  Create an array with all
6312          elements equal to that value.  */
6313       gfc_init_se (&se, NULL);
6314 
6315       if (expr->expr_type == EXPR_CONSTANT)
6316 	gfc_conv_constant (&se, expr);
6317       else
6318 	gfc_conv_structure (&se, expr, 1);
6319 
6320       if (tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
6321 			   TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
6322 	break;
6323       else if (tree_int_cst_equal (TYPE_MIN_VALUE (TYPE_DOMAIN (type)),
6324 				   TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
6325 	range = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
6326       else
6327 	range = build2 (RANGE_EXPR, gfc_array_index_type,
6328 			TYPE_MIN_VALUE (TYPE_DOMAIN (type)),
6329 			TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
6330       CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
6331       break;
6332 
6333     case EXPR_ARRAY:
6334       /* Create a vector of all the elements.  */
6335       for (c = gfc_constructor_first (expr->value.constructor);
6336 	   c && c->expr; c = gfc_constructor_next (c))
6337         {
6338           if (c->iterator)
6339             {
6340               /* Problems occur when we get something like
6341                  integer :: a(lots) = (/(i, i=1, lots)/)  */
6342               gfc_fatal_error ("The number of elements in the array "
6343 			       "constructor at %L requires an increase of "
6344 			       "the allowed %d upper limit. See "
6345 			       "%<-fmax-array-constructor%> option",
6346 			       &expr->where, flag_max_array_constructor);
6347 	      return NULL_TREE;
6348 	    }
6349           if (mpz_cmp_si (c->offset, 0) != 0)
6350             index = gfc_conv_mpz_to_tree (c->offset, gfc_index_integer_kind);
6351           else
6352             index = NULL_TREE;
6353 
6354 	  if (mpz_cmp_si (c->repeat, 1) > 0)
6355 	    {
6356 	      tree tmp1, tmp2;
6357 	      mpz_t maxval;
6358 
6359 	      mpz_init (maxval);
6360 	      mpz_add (maxval, c->offset, c->repeat);
6361 	      mpz_sub_ui (maxval, maxval, 1);
6362 	      tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
6363 	      if (mpz_cmp_si (c->offset, 0) != 0)
6364 		{
6365 		  mpz_add_ui (maxval, c->offset, 1);
6366 		  tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
6367 		}
6368 	      else
6369 		tmp1 = gfc_conv_mpz_to_tree (c->offset, gfc_index_integer_kind);
6370 
6371 	      range = fold_build2 (RANGE_EXPR, gfc_array_index_type, tmp1, tmp2);
6372 	      mpz_clear (maxval);
6373 	    }
6374 	  else
6375 	    range = NULL;
6376 
6377           gfc_init_se (&se, NULL);
6378 	  switch (c->expr->expr_type)
6379 	    {
6380 	    case EXPR_CONSTANT:
6381 	      gfc_conv_constant (&se, c->expr);
6382 
6383 	      /* See gfortran.dg/charlen_15.f90 for instance.  */
6384 	      if (TREE_CODE (se.expr) == STRING_CST
6385 		  && TREE_CODE (type) == ARRAY_TYPE)
6386 		{
6387 		  tree atype = type;
6388 		  while (TREE_CODE (TREE_TYPE (atype)) == ARRAY_TYPE)
6389 		    atype = TREE_TYPE (atype);
6390 		  gcc_checking_assert (TREE_CODE (TREE_TYPE (atype))
6391 				       == INTEGER_TYPE);
6392 		  gcc_checking_assert (TREE_TYPE (TREE_TYPE (se.expr))
6393 				       == TREE_TYPE (atype));
6394 		  if (tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (se.expr)))
6395 		      > tree_to_uhwi (TYPE_SIZE_UNIT (atype)))
6396 		    {
6397 		      unsigned HOST_WIDE_INT size
6398 			= tree_to_uhwi (TYPE_SIZE_UNIT (atype));
6399 		      const char *p = TREE_STRING_POINTER (se.expr);
6400 
6401 		      se.expr = build_string (size, p);
6402 		    }
6403 		  TREE_TYPE (se.expr) = atype;
6404 		}
6405 	      break;
6406 
6407 	    case EXPR_STRUCTURE:
6408               gfc_conv_structure (&se, c->expr, 1);
6409 	      break;
6410 
6411 	    default:
6412 	      /* Catch those occasional beasts that do not simplify
6413 		 for one reason or another, assuming that if they are
6414 		 standard defying the frontend will catch them.  */
6415 	      gfc_conv_expr (&se, c->expr);
6416 	      break;
6417 	    }
6418 
6419 	  if (range == NULL_TREE)
6420 	    CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
6421 	  else
6422 	    {
6423 	      if (index != NULL_TREE)
6424 		CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
6425 	      CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
6426 	    }
6427         }
6428       break;
6429 
6430     case EXPR_NULL:
6431       return gfc_build_null_descriptor (type);
6432 
6433     default:
6434       gcc_unreachable ();
6435     }
6436 
6437   /* Create a constructor from the list of elements.  */
6438   tmp = build_constructor (type, v);
6439   TREE_CONSTANT (tmp) = 1;
6440   return tmp;
6441 }
6442 
6443 
6444 /* Generate code to evaluate non-constant coarray cobounds.  */
6445 
6446 void
gfc_trans_array_cobounds(tree type,stmtblock_t * pblock,const gfc_symbol * sym)6447 gfc_trans_array_cobounds (tree type, stmtblock_t * pblock,
6448 			  const gfc_symbol *sym)
6449 {
6450   int dim;
6451   tree ubound;
6452   tree lbound;
6453   gfc_se se;
6454   gfc_array_spec *as;
6455 
6456   as = IS_CLASS_ARRAY (sym) ? CLASS_DATA (sym)->as : sym->as;
6457 
6458   for (dim = as->rank; dim < as->rank + as->corank; dim++)
6459     {
6460       /* Evaluate non-constant array bound expressions.  */
6461       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
6462       if (as->lower[dim] && !INTEGER_CST_P (lbound))
6463         {
6464           gfc_init_se (&se, NULL);
6465           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
6466           gfc_add_block_to_block (pblock, &se.pre);
6467           gfc_add_modify (pblock, lbound, se.expr);
6468         }
6469       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
6470       if (as->upper[dim] && !INTEGER_CST_P (ubound))
6471         {
6472           gfc_init_se (&se, NULL);
6473           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
6474           gfc_add_block_to_block (pblock, &se.pre);
6475           gfc_add_modify (pblock, ubound, se.expr);
6476         }
6477     }
6478 }
6479 
6480 
6481 /* Generate code to evaluate non-constant array bounds.  Sets *poffset and
6482    returns the size (in elements) of the array.  */
6483 
6484 tree
gfc_trans_array_bounds(tree type,gfc_symbol * sym,tree * poffset,stmtblock_t * pblock)6485 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
6486                         stmtblock_t * pblock)
6487 {
6488   gfc_array_spec *as;
6489   tree size;
6490   tree stride;
6491   tree offset;
6492   tree ubound;
6493   tree lbound;
6494   tree tmp;
6495   gfc_se se;
6496 
6497   int dim;
6498 
6499   as = IS_CLASS_ARRAY (sym) ? CLASS_DATA (sym)->as : sym->as;
6500 
6501   size = gfc_index_one_node;
6502   offset = gfc_index_zero_node;
6503   for (dim = 0; dim < as->rank; dim++)
6504     {
6505       /* Evaluate non-constant array bound expressions.  */
6506       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
6507       if (as->lower[dim] && !INTEGER_CST_P (lbound))
6508         {
6509           gfc_init_se (&se, NULL);
6510           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
6511           gfc_add_block_to_block (pblock, &se.pre);
6512           gfc_add_modify (pblock, lbound, se.expr);
6513         }
6514       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
6515       if (as->upper[dim] && !INTEGER_CST_P (ubound))
6516         {
6517           gfc_init_se (&se, NULL);
6518           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
6519           gfc_add_block_to_block (pblock, &se.pre);
6520           gfc_add_modify (pblock, ubound, se.expr);
6521         }
6522       /* The offset of this dimension.  offset = offset - lbound * stride.  */
6523       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6524 			     lbound, size);
6525       offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
6526 				offset, tmp);
6527 
6528       /* The size of this dimension, and the stride of the next.  */
6529       if (dim + 1 < as->rank)
6530         stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
6531       else
6532 	stride = GFC_TYPE_ARRAY_SIZE (type);
6533 
6534       if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
6535         {
6536           /* Calculate stride = size * (ubound + 1 - lbound).  */
6537           tmp = fold_build2_loc (input_location, MINUS_EXPR,
6538 				 gfc_array_index_type,
6539 				 gfc_index_one_node, lbound);
6540           tmp = fold_build2_loc (input_location, PLUS_EXPR,
6541 				 gfc_array_index_type, ubound, tmp);
6542           tmp = fold_build2_loc (input_location, MULT_EXPR,
6543 				 gfc_array_index_type, size, tmp);
6544           if (stride)
6545             gfc_add_modify (pblock, stride, tmp);
6546           else
6547             stride = gfc_evaluate_now (tmp, pblock);
6548 
6549 	  /* Make sure that negative size arrays are translated
6550 	     to being zero size.  */
6551 	  tmp = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
6552 				 stride, gfc_index_zero_node);
6553 	  tmp = fold_build3_loc (input_location, COND_EXPR,
6554 				 gfc_array_index_type, tmp,
6555 				 stride, gfc_index_zero_node);
6556 	  gfc_add_modify (pblock, stride, tmp);
6557         }
6558 
6559       size = stride;
6560     }
6561 
6562   gfc_trans_array_cobounds (type, pblock, sym);
6563   gfc_trans_vla_type_sizes (sym, pblock);
6564 
6565   *poffset = offset;
6566   return size;
6567 }
6568 
6569 
6570 /* Generate code to initialize/allocate an array variable.  */
6571 
6572 void
gfc_trans_auto_array_allocation(tree decl,gfc_symbol * sym,gfc_wrapped_block * block)6573 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
6574 				 gfc_wrapped_block * block)
6575 {
6576   stmtblock_t init;
6577   tree type;
6578   tree tmp = NULL_TREE;
6579   tree size;
6580   tree offset;
6581   tree space;
6582   tree inittree;
6583   bool onstack;
6584 
6585   gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
6586 
6587   /* Do nothing for USEd variables.  */
6588   if (sym->attr.use_assoc)
6589     return;
6590 
6591   type = TREE_TYPE (decl);
6592   gcc_assert (GFC_ARRAY_TYPE_P (type));
6593   onstack = TREE_CODE (type) != POINTER_TYPE;
6594 
6595   gfc_init_block (&init);
6596 
6597   /* Evaluate character string length.  */
6598   if (sym->ts.type == BT_CHARACTER
6599       && onstack && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
6600     {
6601       gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
6602 
6603       gfc_trans_vla_type_sizes (sym, &init);
6604 
6605       /* Emit a DECL_EXPR for this variable, which will cause the
6606 	 gimplifier to allocate storage, and all that good stuff.  */
6607       tmp = fold_build1_loc (input_location, DECL_EXPR, TREE_TYPE (decl), decl);
6608       gfc_add_expr_to_block (&init, tmp);
6609     }
6610 
6611   if (onstack)
6612     {
6613       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
6614       return;
6615     }
6616 
6617   type = TREE_TYPE (type);
6618 
6619   gcc_assert (!sym->attr.use_assoc);
6620   gcc_assert (!sym->module);
6621 
6622   if (sym->ts.type == BT_CHARACTER
6623       && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
6624     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
6625 
6626   size = gfc_trans_array_bounds (type, sym, &offset, &init);
6627 
6628   /* Don't actually allocate space for Cray Pointees.  */
6629   if (sym->attr.cray_pointee)
6630     {
6631       if (VAR_P (GFC_TYPE_ARRAY_OFFSET (type)))
6632 	gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
6633 
6634       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
6635       return;
6636     }
6637 
6638   if (flag_stack_arrays)
6639     {
6640       gcc_assert (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE);
6641       space = build_decl (gfc_get_location (&sym->declared_at),
6642 			  VAR_DECL, create_tmp_var_name ("A"),
6643 			  TREE_TYPE (TREE_TYPE (decl)));
6644       gfc_trans_vla_type_sizes (sym, &init);
6645     }
6646   else
6647     {
6648       /* The size is the number of elements in the array, so multiply by the
6649 	 size of an element to get the total size.  */
6650       tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
6651       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6652 			      size, fold_convert (gfc_array_index_type, tmp));
6653 
6654       /* Allocate memory to hold the data.  */
6655       tmp = gfc_call_malloc (&init, TREE_TYPE (decl), size);
6656       gfc_add_modify (&init, decl, tmp);
6657 
6658       /* Free the temporary.  */
6659       tmp = gfc_call_free (decl);
6660       space = NULL_TREE;
6661     }
6662 
6663   /* Set offset of the array.  */
6664   if (VAR_P (GFC_TYPE_ARRAY_OFFSET (type)))
6665     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
6666 
6667   /* Automatic arrays should not have initializers.  */
6668   gcc_assert (!sym->value);
6669 
6670   inittree = gfc_finish_block (&init);
6671 
6672   if (space)
6673     {
6674       tree addr;
6675       pushdecl (space);
6676 
6677       /* Don't create new scope, emit the DECL_EXPR in exactly the scope
6678          where also space is located.  */
6679       gfc_init_block (&init);
6680       tmp = fold_build1_loc (input_location, DECL_EXPR,
6681 			     TREE_TYPE (space), space);
6682       gfc_add_expr_to_block (&init, tmp);
6683       addr = fold_build1_loc (gfc_get_location (&sym->declared_at),
6684 			      ADDR_EXPR, TREE_TYPE (decl), space);
6685       gfc_add_modify (&init, decl, addr);
6686       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
6687       tmp = NULL_TREE;
6688     }
6689   gfc_add_init_cleanup (block, inittree, tmp);
6690 }
6691 
6692 
6693 /* Generate entry and exit code for g77 calling convention arrays.  */
6694 
6695 void
gfc_trans_g77_array(gfc_symbol * sym,gfc_wrapped_block * block)6696 gfc_trans_g77_array (gfc_symbol * sym, gfc_wrapped_block * block)
6697 {
6698   tree parm;
6699   tree type;
6700   locus loc;
6701   tree offset;
6702   tree tmp;
6703   tree stmt;
6704   stmtblock_t init;
6705 
6706   gfc_save_backend_locus (&loc);
6707   gfc_set_backend_locus (&sym->declared_at);
6708 
6709   /* Descriptor type.  */
6710   parm = sym->backend_decl;
6711   type = TREE_TYPE (parm);
6712   gcc_assert (GFC_ARRAY_TYPE_P (type));
6713 
6714   gfc_start_block (&init);
6715 
6716   if (sym->ts.type == BT_CHARACTER
6717       && VAR_P (sym->ts.u.cl->backend_decl))
6718     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
6719 
6720   /* Evaluate the bounds of the array.  */
6721   gfc_trans_array_bounds (type, sym, &offset, &init);
6722 
6723   /* Set the offset.  */
6724   if (VAR_P (GFC_TYPE_ARRAY_OFFSET (type)))
6725     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
6726 
6727   /* Set the pointer itself if we aren't using the parameter directly.  */
6728   if (TREE_CODE (parm) != PARM_DECL)
6729     {
6730       tmp = GFC_DECL_SAVED_DESCRIPTOR (parm);
6731       if (sym->ts.type == BT_CLASS)
6732 	{
6733 	  tmp = build_fold_indirect_ref_loc (input_location, tmp);
6734 	  tmp = gfc_class_data_get (tmp);
6735 	  tmp = gfc_conv_descriptor_data_get (tmp);
6736 	}
6737       tmp = convert (TREE_TYPE (parm), tmp);
6738       gfc_add_modify (&init, parm, tmp);
6739     }
6740   stmt = gfc_finish_block (&init);
6741 
6742   gfc_restore_backend_locus (&loc);
6743 
6744   /* Add the initialization code to the start of the function.  */
6745 
6746   if ((sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.optional)
6747       || sym->attr.optional
6748       || sym->attr.not_always_present)
6749     {
6750       tree nullify;
6751       if (TREE_CODE (parm) != PARM_DECL)
6752 	nullify = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6753 				   parm, null_pointer_node);
6754       else
6755 	nullify = build_empty_stmt (input_location);
6756       tmp = gfc_conv_expr_present (sym, true);
6757       stmt = build3_v (COND_EXPR, tmp, stmt, nullify);
6758     }
6759 
6760   gfc_add_init_cleanup (block, stmt, NULL_TREE);
6761 }
6762 
6763 
6764 /* Modify the descriptor of an array parameter so that it has the
6765    correct lower bound.  Also move the upper bound accordingly.
6766    If the array is not packed, it will be copied into a temporary.
6767    For each dimension we set the new lower and upper bounds.  Then we copy the
6768    stride and calculate the offset for this dimension.  We also work out
6769    what the stride of a packed array would be, and see it the two match.
6770    If the array need repacking, we set the stride to the values we just
6771    calculated, recalculate the offset and copy the array data.
6772    Code is also added to copy the data back at the end of the function.
6773    */
6774 
6775 void
gfc_trans_dummy_array_bias(gfc_symbol * sym,tree tmpdesc,gfc_wrapped_block * block)6776 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc,
6777 			    gfc_wrapped_block * block)
6778 {
6779   tree size;
6780   tree type;
6781   tree offset;
6782   locus loc;
6783   stmtblock_t init;
6784   tree stmtInit, stmtCleanup;
6785   tree lbound;
6786   tree ubound;
6787   tree dubound;
6788   tree dlbound;
6789   tree dumdesc;
6790   tree tmp;
6791   tree stride, stride2;
6792   tree stmt_packed;
6793   tree stmt_unpacked;
6794   tree partial;
6795   gfc_se se;
6796   int n;
6797   int checkparm;
6798   int no_repack;
6799   bool optional_arg;
6800   gfc_array_spec *as;
6801   bool is_classarray = IS_CLASS_ARRAY (sym);
6802 
6803   /* Do nothing for pointer and allocatable arrays.  */
6804   if ((sym->ts.type != BT_CLASS && sym->attr.pointer)
6805       || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.class_pointer)
6806       || sym->attr.allocatable
6807       || (is_classarray && CLASS_DATA (sym)->attr.allocatable))
6808     return;
6809 
6810   if (!is_classarray && sym->attr.dummy && gfc_is_nodesc_array (sym))
6811     {
6812       gfc_trans_g77_array (sym, block);
6813       return;
6814     }
6815 
6816   loc.nextc = NULL;
6817   gfc_save_backend_locus (&loc);
6818   /* loc.nextc is not set by save_backend_locus but the location routines
6819      depend on it.  */
6820   if (loc.nextc == NULL)
6821     loc.nextc = loc.lb->line;
6822   gfc_set_backend_locus (&sym->declared_at);
6823 
6824   /* Descriptor type.  */
6825   type = TREE_TYPE (tmpdesc);
6826   gcc_assert (GFC_ARRAY_TYPE_P (type));
6827   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
6828   if (is_classarray)
6829     /* For a class array the dummy array descriptor is in the _class
6830        component.  */
6831     dumdesc = gfc_class_data_get (dumdesc);
6832   else
6833     dumdesc = build_fold_indirect_ref_loc (input_location, dumdesc);
6834   as = IS_CLASS_ARRAY (sym) ? CLASS_DATA (sym)->as : sym->as;
6835   gfc_start_block (&init);
6836 
6837   if (sym->ts.type == BT_CHARACTER
6838       && VAR_P (sym->ts.u.cl->backend_decl))
6839     gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
6840 
6841   /* TODO: Fix the exclusion of class arrays from extent checking.  */
6842   checkparm = (as->type == AS_EXPLICIT && !is_classarray
6843 	       && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS));
6844 
6845   no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
6846 		|| GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
6847 
6848   if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
6849     {
6850       /* For non-constant shape arrays we only check if the first dimension
6851 	 is contiguous.  Repacking higher dimensions wouldn't gain us
6852 	 anything as we still don't know the array stride.  */
6853       partial = gfc_create_var (logical_type_node, "partial");
6854       TREE_USED (partial) = 1;
6855       tmp = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
6856       tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, tmp,
6857 			     gfc_index_one_node);
6858       gfc_add_modify (&init, partial, tmp);
6859     }
6860   else
6861     partial = NULL_TREE;
6862 
6863   /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
6864      here, however I think it does the right thing.  */
6865   if (no_repack)
6866     {
6867       /* Set the first stride.  */
6868       stride = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
6869       stride = gfc_evaluate_now (stride, &init);
6870 
6871       tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
6872 			     stride, gfc_index_zero_node);
6873       tmp = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
6874 			     tmp, gfc_index_one_node, stride);
6875       stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
6876       gfc_add_modify (&init, stride, tmp);
6877 
6878       /* Allow the user to disable array repacking.  */
6879       stmt_unpacked = NULL_TREE;
6880     }
6881   else
6882     {
6883       gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
6884       /* A library call to repack the array if necessary.  */
6885       tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
6886       stmt_unpacked = build_call_expr_loc (input_location,
6887 				       gfor_fndecl_in_pack, 1, tmp);
6888 
6889       stride = gfc_index_one_node;
6890 
6891       if (warn_array_temporaries)
6892 	gfc_warning (OPT_Warray_temporaries,
6893 		     "Creating array temporary at %L", &loc);
6894     }
6895 
6896   /* This is for the case where the array data is used directly without
6897      calling the repack function.  */
6898   if (no_repack || partial != NULL_TREE)
6899     stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
6900   else
6901     stmt_packed = NULL_TREE;
6902 
6903   /* Assign the data pointer.  */
6904   if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
6905     {
6906       /* Don't repack unknown shape arrays when the first stride is 1.  */
6907       tmp = fold_build3_loc (input_location, COND_EXPR, TREE_TYPE (stmt_packed),
6908 			     partial, stmt_packed, stmt_unpacked);
6909     }
6910   else
6911     tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
6912   gfc_add_modify (&init, tmpdesc, fold_convert (type, tmp));
6913 
6914   offset = gfc_index_zero_node;
6915   size = gfc_index_one_node;
6916 
6917   /* Evaluate the bounds of the array.  */
6918   for (n = 0; n < as->rank; n++)
6919     {
6920       if (checkparm || !as->upper[n])
6921 	{
6922 	  /* Get the bounds of the actual parameter.  */
6923 	  dubound = gfc_conv_descriptor_ubound_get (dumdesc, gfc_rank_cst[n]);
6924 	  dlbound = gfc_conv_descriptor_lbound_get (dumdesc, gfc_rank_cst[n]);
6925 	}
6926       else
6927 	{
6928 	  dubound = NULL_TREE;
6929 	  dlbound = NULL_TREE;
6930 	}
6931 
6932       lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
6933       if (!INTEGER_CST_P (lbound))
6934 	{
6935 	  gfc_init_se (&se, NULL);
6936 	  gfc_conv_expr_type (&se, as->lower[n],
6937 			      gfc_array_index_type);
6938 	  gfc_add_block_to_block (&init, &se.pre);
6939 	  gfc_add_modify (&init, lbound, se.expr);
6940 	}
6941 
6942       ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
6943       /* Set the desired upper bound.  */
6944       if (as->upper[n])
6945 	{
6946 	  /* We know what we want the upper bound to be.  */
6947 	  if (!INTEGER_CST_P (ubound))
6948 	    {
6949 	      gfc_init_se (&se, NULL);
6950 	      gfc_conv_expr_type (&se, as->upper[n],
6951 				  gfc_array_index_type);
6952 	      gfc_add_block_to_block (&init, &se.pre);
6953 	      gfc_add_modify (&init, ubound, se.expr);
6954 	    }
6955 
6956 	  /* Check the sizes match.  */
6957 	  if (checkparm)
6958 	    {
6959 	      /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)).  */
6960 	      char * msg;
6961 	      tree temp;
6962 
6963 	      temp = fold_build2_loc (input_location, MINUS_EXPR,
6964 				      gfc_array_index_type, ubound, lbound);
6965 	      temp = fold_build2_loc (input_location, PLUS_EXPR,
6966 				      gfc_array_index_type,
6967 				      gfc_index_one_node, temp);
6968 	      stride2 = fold_build2_loc (input_location, MINUS_EXPR,
6969 					 gfc_array_index_type, dubound,
6970 					 dlbound);
6971 	      stride2 = fold_build2_loc (input_location, PLUS_EXPR,
6972 					 gfc_array_index_type,
6973 					 gfc_index_one_node, stride2);
6974 	      tmp = fold_build2_loc (input_location, NE_EXPR,
6975 				     gfc_array_index_type, temp, stride2);
6976 	      msg = xasprintf ("Dimension %d of array '%s' has extent "
6977 			       "%%ld instead of %%ld", n+1, sym->name);
6978 
6979 	      gfc_trans_runtime_check (true, false, tmp, &init, &loc, msg,
6980 			fold_convert (long_integer_type_node, temp),
6981 			fold_convert (long_integer_type_node, stride2));
6982 
6983 	      free (msg);
6984 	    }
6985 	}
6986       else
6987 	{
6988 	  /* For assumed shape arrays move the upper bound by the same amount
6989 	     as the lower bound.  */
6990 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
6991 				 gfc_array_index_type, dubound, dlbound);
6992 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
6993 				 gfc_array_index_type, tmp, lbound);
6994 	  gfc_add_modify (&init, ubound, tmp);
6995 	}
6996       /* The offset of this dimension.  offset = offset - lbound * stride.  */
6997       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
6998 			     lbound, stride);
6999       offset = fold_build2_loc (input_location, MINUS_EXPR,
7000 				gfc_array_index_type, offset, tmp);
7001 
7002       /* The size of this dimension, and the stride of the next.  */
7003       if (n + 1 < as->rank)
7004 	{
7005 	  stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
7006 
7007 	  if (no_repack || partial != NULL_TREE)
7008 	    stmt_unpacked =
7009 	      gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[n+1]);
7010 
7011 	  /* Figure out the stride if not a known constant.  */
7012 	  if (!INTEGER_CST_P (stride))
7013 	    {
7014 	      if (no_repack)
7015 		stmt_packed = NULL_TREE;
7016 	      else
7017 		{
7018 		  /* Calculate stride = size * (ubound + 1 - lbound).  */
7019 		  tmp = fold_build2_loc (input_location, MINUS_EXPR,
7020 					 gfc_array_index_type,
7021 					 gfc_index_one_node, lbound);
7022 		  tmp = fold_build2_loc (input_location, PLUS_EXPR,
7023 					 gfc_array_index_type, ubound, tmp);
7024 		  size = fold_build2_loc (input_location, MULT_EXPR,
7025 					  gfc_array_index_type, size, tmp);
7026 		  stmt_packed = size;
7027 		}
7028 
7029 	      /* Assign the stride.  */
7030 	      if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
7031 		tmp = fold_build3_loc (input_location, COND_EXPR,
7032 				       gfc_array_index_type, partial,
7033 				       stmt_unpacked, stmt_packed);
7034 	      else
7035 		tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
7036 	      gfc_add_modify (&init, stride, tmp);
7037 	    }
7038 	}
7039       else
7040 	{
7041 	  stride = GFC_TYPE_ARRAY_SIZE (type);
7042 
7043 	  if (stride && !INTEGER_CST_P (stride))
7044 	    {
7045 	      /* Calculate size = stride * (ubound + 1 - lbound).  */
7046 	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
7047 				     gfc_array_index_type,
7048 				     gfc_index_one_node, lbound);
7049 	      tmp = fold_build2_loc (input_location, PLUS_EXPR,
7050 				     gfc_array_index_type,
7051 				     ubound, tmp);
7052 	      tmp = fold_build2_loc (input_location, MULT_EXPR,
7053 				     gfc_array_index_type,
7054 				     GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
7055 	      gfc_add_modify (&init, stride, tmp);
7056 	    }
7057 	}
7058     }
7059 
7060   gfc_trans_array_cobounds (type, &init, sym);
7061 
7062   /* Set the offset.  */
7063   if (VAR_P (GFC_TYPE_ARRAY_OFFSET (type)))
7064     gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
7065 
7066   gfc_trans_vla_type_sizes (sym, &init);
7067 
7068   stmtInit = gfc_finish_block (&init);
7069 
7070   /* Only do the entry/initialization code if the arg is present.  */
7071   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
7072   optional_arg = (sym->attr.optional
7073 		  || (sym->ns->proc_name->attr.entry_master
7074 		      && sym->attr.dummy));
7075   if (optional_arg)
7076     {
7077       tree zero_init = fold_convert (TREE_TYPE (tmpdesc), null_pointer_node);
7078       zero_init = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
7079 				   tmpdesc, zero_init);
7080       tmp = gfc_conv_expr_present (sym, true);
7081       stmtInit = build3_v (COND_EXPR, tmp, stmtInit, zero_init);
7082     }
7083 
7084   /* Cleanup code.  */
7085   if (no_repack)
7086     stmtCleanup = NULL_TREE;
7087   else
7088     {
7089       stmtblock_t cleanup;
7090       gfc_start_block (&cleanup);
7091 
7092       if (sym->attr.intent != INTENT_IN)
7093 	{
7094 	  /* Copy the data back.  */
7095 	  tmp = build_call_expr_loc (input_location,
7096 				 gfor_fndecl_in_unpack, 2, dumdesc, tmpdesc);
7097 	  gfc_add_expr_to_block (&cleanup, tmp);
7098 	}
7099 
7100       /* Free the temporary.  */
7101       tmp = gfc_call_free (tmpdesc);
7102       gfc_add_expr_to_block (&cleanup, tmp);
7103 
7104       stmtCleanup = gfc_finish_block (&cleanup);
7105 
7106       /* Only do the cleanup if the array was repacked.  */
7107       if (is_classarray)
7108 	/* For a class array the dummy array descriptor is in the _class
7109 	   component.  */
7110 	tmp = gfc_class_data_get (dumdesc);
7111       else
7112 	tmp = build_fold_indirect_ref_loc (input_location, dumdesc);
7113       tmp = gfc_conv_descriptor_data_get (tmp);
7114       tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
7115 			     tmp, tmpdesc);
7116       stmtCleanup = build3_v (COND_EXPR, tmp, stmtCleanup,
7117 			      build_empty_stmt (input_location));
7118 
7119       if (optional_arg)
7120 	{
7121 	  tmp = gfc_conv_expr_present (sym);
7122 	  stmtCleanup = build3_v (COND_EXPR, tmp, stmtCleanup,
7123 				  build_empty_stmt (input_location));
7124 	}
7125     }
7126 
7127   /* We don't need to free any memory allocated by internal_pack as it will
7128      be freed at the end of the function by pop_context.  */
7129   gfc_add_init_cleanup (block, stmtInit, stmtCleanup);
7130 
7131   gfc_restore_backend_locus (&loc);
7132 }
7133 
7134 
7135 /* Calculate the overall offset, including subreferences.  */
7136 void
gfc_get_dataptr_offset(stmtblock_t * block,tree parm,tree desc,tree offset,bool subref,gfc_expr * expr)7137 gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
7138 			bool subref, gfc_expr *expr)
7139 {
7140   tree tmp;
7141   tree field;
7142   tree stride;
7143   tree index;
7144   gfc_ref *ref;
7145   gfc_se start;
7146   int n;
7147 
7148   /* If offset is NULL and this is not a subreferenced array, there is
7149      nothing to do.  */
7150   if (offset == NULL_TREE)
7151     {
7152       if (subref)
7153 	offset = gfc_index_zero_node;
7154       else
7155 	return;
7156     }
7157 
7158   tmp = build_array_ref (desc, offset, NULL, NULL);
7159 
7160   /* Offset the data pointer for pointer assignments from arrays with
7161      subreferences; e.g. my_integer => my_type(:)%integer_component.  */
7162   if (subref)
7163     {
7164       /* Go past the array reference.  */
7165       for (ref = expr->ref; ref; ref = ref->next)
7166 	if (ref->type == REF_ARRAY &&
7167 	      ref->u.ar.type != AR_ELEMENT)
7168 	  {
7169 	    ref = ref->next;
7170 	    break;
7171 	  }
7172 
7173       /* Calculate the offset for each subsequent subreference.  */
7174       for (; ref; ref = ref->next)
7175 	{
7176 	  switch (ref->type)
7177 	    {
7178 	    case REF_COMPONENT:
7179 	      field = ref->u.c.component->backend_decl;
7180 	      gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
7181 	      tmp = fold_build3_loc (input_location, COMPONENT_REF,
7182 				     TREE_TYPE (field),
7183 				     tmp, field, NULL_TREE);
7184 	      break;
7185 
7186 	    case REF_SUBSTRING:
7187 	      gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
7188 	      gfc_init_se (&start, NULL);
7189 	      gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
7190 	      gfc_add_block_to_block (block, &start.pre);
7191 	      tmp = gfc_build_array_ref (tmp, start.expr, NULL);
7192 	      break;
7193 
7194 	    case REF_ARRAY:
7195 	      gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE
7196 			    && ref->u.ar.type == AR_ELEMENT);
7197 
7198 	      /* TODO - Add bounds checking.  */
7199 	      stride = gfc_index_one_node;
7200 	      index = gfc_index_zero_node;
7201 	      for (n = 0; n < ref->u.ar.dimen; n++)
7202 		{
7203 		  tree itmp;
7204 		  tree jtmp;
7205 
7206 		  /* Update the index.  */
7207 		  gfc_init_se (&start, NULL);
7208 		  gfc_conv_expr_type (&start, ref->u.ar.start[n], gfc_array_index_type);
7209 		  itmp = gfc_evaluate_now (start.expr, block);
7210 		  gfc_init_se (&start, NULL);
7211 		  gfc_conv_expr_type (&start, ref->u.ar.as->lower[n], gfc_array_index_type);
7212 		  jtmp = gfc_evaluate_now (start.expr, block);
7213 		  itmp = fold_build2_loc (input_location, MINUS_EXPR,
7214 					  gfc_array_index_type, itmp, jtmp);
7215 		  itmp = fold_build2_loc (input_location, MULT_EXPR,
7216 					  gfc_array_index_type, itmp, stride);
7217 		  index = fold_build2_loc (input_location, PLUS_EXPR,
7218 					  gfc_array_index_type, itmp, index);
7219 		  index = gfc_evaluate_now (index, block);
7220 
7221 		  /* Update the stride.  */
7222 		  gfc_init_se (&start, NULL);
7223 		  gfc_conv_expr_type (&start, ref->u.ar.as->upper[n], gfc_array_index_type);
7224 		  itmp =  fold_build2_loc (input_location, MINUS_EXPR,
7225 					   gfc_array_index_type, start.expr,
7226 					   jtmp);
7227 		  itmp =  fold_build2_loc (input_location, PLUS_EXPR,
7228 					   gfc_array_index_type,
7229 					   gfc_index_one_node, itmp);
7230 		  stride =  fold_build2_loc (input_location, MULT_EXPR,
7231 					     gfc_array_index_type, stride, itmp);
7232 		  stride = gfc_evaluate_now (stride, block);
7233 		}
7234 
7235 	      /* Apply the index to obtain the array element.  */
7236 	      tmp = gfc_build_array_ref (tmp, index, NULL);
7237 	      break;
7238 
7239 	    case REF_INQUIRY:
7240 	      switch (ref->u.i)
7241 		{
7242 		case INQUIRY_RE:
7243 		  tmp = fold_build1_loc (input_location, REALPART_EXPR,
7244 					 TREE_TYPE (TREE_TYPE (tmp)), tmp);
7245 		  break;
7246 
7247 		case INQUIRY_IM:
7248 		  tmp = fold_build1_loc (input_location, IMAGPART_EXPR,
7249 					 TREE_TYPE (TREE_TYPE (tmp)), tmp);
7250 		  break;
7251 
7252 		default:
7253 		  break;
7254 		}
7255 	      break;
7256 
7257 	    default:
7258 	      gcc_unreachable ();
7259 	      break;
7260 	    }
7261 	}
7262     }
7263 
7264   /* Set the target data pointer.  */
7265   offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
7266   gfc_conv_descriptor_data_set (block, parm, offset);
7267 }
7268 
7269 
7270 /* gfc_conv_expr_descriptor needs the string length an expression
7271    so that the size of the temporary can be obtained.  This is done
7272    by adding up the string lengths of all the elements in the
7273    expression.  Function with non-constant expressions have their
7274    string lengths mapped onto the actual arguments using the
7275    interface mapping machinery in trans-expr.cc.  */
7276 static void
get_array_charlen(gfc_expr * expr,gfc_se * se)7277 get_array_charlen (gfc_expr *expr, gfc_se *se)
7278 {
7279   gfc_interface_mapping mapping;
7280   gfc_formal_arglist *formal;
7281   gfc_actual_arglist *arg;
7282   gfc_se tse;
7283   gfc_expr *e;
7284 
7285   if (expr->ts.u.cl->length
7286 	&& gfc_is_constant_expr (expr->ts.u.cl->length))
7287     {
7288       if (!expr->ts.u.cl->backend_decl)
7289 	gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
7290       return;
7291     }
7292 
7293   switch (expr->expr_type)
7294     {
7295     case EXPR_ARRAY:
7296 
7297       /* This is somewhat brutal. The expression for the first
7298 	 element of the array is evaluated and assigned to a
7299 	 new string length for the original expression.  */
7300       e = gfc_constructor_first (expr->value.constructor)->expr;
7301 
7302       gfc_init_se (&tse, NULL);
7303 
7304       /* Avoid evaluating trailing array references since all we need is
7305 	 the string length.  */
7306       if (e->rank)
7307 	tse.descriptor_only = 1;
7308       if (e->rank && e->expr_type != EXPR_VARIABLE)
7309 	gfc_conv_expr_descriptor (&tse, e);
7310       else
7311 	gfc_conv_expr (&tse, e);
7312 
7313       gfc_add_block_to_block (&se->pre, &tse.pre);
7314       gfc_add_block_to_block (&se->post, &tse.post);
7315 
7316       if (!expr->ts.u.cl->backend_decl || !VAR_P (expr->ts.u.cl->backend_decl))
7317 	{
7318 	  expr->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
7319 	  expr->ts.u.cl->backend_decl =
7320 			gfc_create_var (gfc_charlen_type_node, "sln");
7321 	}
7322 
7323       gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
7324 		      tse.string_length);
7325 
7326       /* Make sure that deferred length components point to the hidden
7327 	 string_length component.  */
7328       if (TREE_CODE (tse.expr) == COMPONENT_REF
7329 	  && TREE_CODE (tse.string_length) == COMPONENT_REF
7330 	  && TREE_OPERAND (tse.expr, 0) == TREE_OPERAND (tse.string_length, 0))
7331 	e->ts.u.cl->backend_decl = expr->ts.u.cl->backend_decl;
7332 
7333       return;
7334 
7335     case EXPR_OP:
7336       get_array_charlen (expr->value.op.op1, se);
7337 
7338       /* For parentheses the expression ts.u.cl should be identical.  */
7339       if (expr->value.op.op == INTRINSIC_PARENTHESES)
7340 	{
7341 	  if (expr->value.op.op1->ts.u.cl != expr->ts.u.cl)
7342 	    expr->ts.u.cl->backend_decl
7343 			= expr->value.op.op1->ts.u.cl->backend_decl;
7344 	  return;
7345 	}
7346 
7347       expr->ts.u.cl->backend_decl =
7348 		gfc_create_var (gfc_charlen_type_node, "sln");
7349 
7350       if (expr->value.op.op2)
7351 	{
7352 	  get_array_charlen (expr->value.op.op2, se);
7353 
7354 	  gcc_assert (expr->value.op.op == INTRINSIC_CONCAT);
7355 
7356 	  /* Add the string lengths and assign them to the expression
7357 	     string length backend declaration.  */
7358 	  gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
7359 			  fold_build2_loc (input_location, PLUS_EXPR,
7360 				gfc_charlen_type_node,
7361 				expr->value.op.op1->ts.u.cl->backend_decl,
7362 				expr->value.op.op2->ts.u.cl->backend_decl));
7363 	}
7364       else
7365 	gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl,
7366 			expr->value.op.op1->ts.u.cl->backend_decl);
7367       break;
7368 
7369     case EXPR_FUNCTION:
7370       if (expr->value.function.esym == NULL
7371 	    || expr->ts.u.cl->length->expr_type == EXPR_CONSTANT)
7372 	{
7373 	  gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
7374 	  break;
7375 	}
7376 
7377       /* Map expressions involving the dummy arguments onto the actual
7378 	 argument expressions.  */
7379       gfc_init_interface_mapping (&mapping);
7380       formal = gfc_sym_get_dummy_args (expr->symtree->n.sym);
7381       arg = expr->value.function.actual;
7382 
7383       /* Set se = NULL in the calls to the interface mapping, to suppress any
7384 	 backend stuff.  */
7385       for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
7386 	{
7387 	  if (!arg->expr)
7388 	    continue;
7389 	  if (formal->sym)
7390 	  gfc_add_interface_mapping (&mapping, formal->sym, NULL, arg->expr);
7391 	}
7392 
7393       gfc_init_se (&tse, NULL);
7394 
7395       /* Build the expression for the character length and convert it.  */
7396       gfc_apply_interface_mapping (&mapping, &tse, expr->ts.u.cl->length);
7397 
7398       gfc_add_block_to_block (&se->pre, &tse.pre);
7399       gfc_add_block_to_block (&se->post, &tse.post);
7400       tse.expr = fold_convert (gfc_charlen_type_node, tse.expr);
7401       tse.expr = fold_build2_loc (input_location, MAX_EXPR,
7402 				  TREE_TYPE (tse.expr), tse.expr,
7403 				  build_zero_cst (TREE_TYPE (tse.expr)));
7404       expr->ts.u.cl->backend_decl = tse.expr;
7405       gfc_free_interface_mapping (&mapping);
7406       break;
7407 
7408     default:
7409       gfc_conv_string_length (expr->ts.u.cl, expr, &se->pre);
7410       break;
7411     }
7412 }
7413 
7414 
7415 /* Helper function to check dimensions.  */
7416 static bool
transposed_dims(gfc_ss * ss)7417 transposed_dims (gfc_ss *ss)
7418 {
7419   int n;
7420 
7421   for (n = 0; n < ss->dimen; n++)
7422     if (ss->dim[n] != n)
7423       return true;
7424   return false;
7425 }
7426 
7427 
7428 /* Convert the last ref of a scalar coarray from an AR_ELEMENT to an
7429    AR_FULL, suitable for the scalarizer.  */
7430 
7431 static gfc_ss *
walk_coarray(gfc_expr * e)7432 walk_coarray (gfc_expr *e)
7433 {
7434   gfc_ss *ss;
7435 
7436   gcc_assert (gfc_get_corank (e) > 0);
7437 
7438   ss = gfc_walk_expr (e);
7439 
7440   /* Fix scalar coarray.  */
7441   if (ss == gfc_ss_terminator)
7442     {
7443       gfc_ref *ref;
7444 
7445       ref = e->ref;
7446       while (ref)
7447 	{
7448 	  if (ref->type == REF_ARRAY
7449 	      && ref->u.ar.codimen > 0)
7450 	    break;
7451 
7452 	  ref = ref->next;
7453 	}
7454 
7455       gcc_assert (ref != NULL);
7456       if (ref->u.ar.type == AR_ELEMENT)
7457 	ref->u.ar.type = AR_SECTION;
7458       ss = gfc_reverse_ss (gfc_walk_array_ref (ss, e, ref));
7459     }
7460 
7461   return ss;
7462 }
7463 
7464 
7465 /* Convert an array for passing as an actual argument.  Expressions and
7466    vector subscripts are evaluated and stored in a temporary, which is then
7467    passed.  For whole arrays the descriptor is passed.  For array sections
7468    a modified copy of the descriptor is passed, but using the original data.
7469 
7470    This function is also used for array pointer assignments, and there
7471    are three cases:
7472 
7473      - se->want_pointer && !se->direct_byref
7474 	 EXPR is an actual argument.  On exit, se->expr contains a
7475 	 pointer to the array descriptor.
7476 
7477      - !se->want_pointer && !se->direct_byref
7478 	 EXPR is an actual argument to an intrinsic function or the
7479 	 left-hand side of a pointer assignment.  On exit, se->expr
7480 	 contains the descriptor for EXPR.
7481 
7482      - !se->want_pointer && se->direct_byref
7483 	 EXPR is the right-hand side of a pointer assignment and
7484 	 se->expr is the descriptor for the previously-evaluated
7485 	 left-hand side.  The function creates an assignment from
7486 	 EXPR to se->expr.
7487 
7488 
7489    The se->force_tmp flag disables the non-copying descriptor optimization
7490    that is used for transpose. It may be used in cases where there is an
7491    alias between the transpose argument and another argument in the same
7492    function call.  */
7493 
7494 void
gfc_conv_expr_descriptor(gfc_se * se,gfc_expr * expr)7495 gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
7496 {
7497   gfc_ss *ss;
7498   gfc_ss_type ss_type;
7499   gfc_ss_info *ss_info;
7500   gfc_loopinfo loop;
7501   gfc_array_info *info;
7502   int need_tmp;
7503   int n;
7504   tree tmp;
7505   tree desc;
7506   stmtblock_t block;
7507   tree start;
7508   int full;
7509   bool subref_array_target = false;
7510   bool deferred_array_component = false;
7511   gfc_expr *arg, *ss_expr;
7512 
7513   if (se->want_coarray)
7514     ss = walk_coarray (expr);
7515   else
7516     ss = gfc_walk_expr (expr);
7517 
7518   gcc_assert (ss != NULL);
7519   gcc_assert (ss != gfc_ss_terminator);
7520 
7521   ss_info = ss->info;
7522   ss_type = ss_info->type;
7523   ss_expr = ss_info->expr;
7524 
7525   /* Special case: TRANSPOSE which needs no temporary.  */
7526   while (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym
7527 	 && (arg = gfc_get_noncopying_intrinsic_argument (expr)) != NULL)
7528     {
7529       /* This is a call to transpose which has already been handled by the
7530 	 scalarizer, so that we just need to get its argument's descriptor.  */
7531       gcc_assert (expr->value.function.isym->id == GFC_ISYM_TRANSPOSE);
7532       expr = expr->value.function.actual->expr;
7533     }
7534 
7535   if (!se->direct_byref)
7536     se->unlimited_polymorphic = UNLIMITED_POLY (expr);
7537 
7538   /* Special case things we know we can pass easily.  */
7539   switch (expr->expr_type)
7540     {
7541     case EXPR_VARIABLE:
7542       /* If we have a linear array section, we can pass it directly.
7543 	 Otherwise we need to copy it into a temporary.  */
7544 
7545       gcc_assert (ss_type == GFC_SS_SECTION);
7546       gcc_assert (ss_expr == expr);
7547       info = &ss_info->data.array;
7548 
7549       /* Get the descriptor for the array.  */
7550       gfc_conv_ss_descriptor (&se->pre, ss, 0);
7551       desc = info->descriptor;
7552 
7553       /* The charlen backend decl for deferred character components cannot
7554 	 be used because it is fixed at zero.  Instead, the hidden string
7555 	 length component is used.  */
7556       if (expr->ts.type == BT_CHARACTER
7557 	  && expr->ts.deferred
7558 	  && TREE_CODE (desc) == COMPONENT_REF)
7559 	deferred_array_component = true;
7560 
7561       subref_array_target = (is_subref_array (expr)
7562 			     && (se->direct_byref
7563 				 || expr->ts.type == BT_CHARACTER));
7564       need_tmp = (gfc_ref_needs_temporary_p (expr->ref)
7565 		  && !subref_array_target);
7566 
7567       if (se->force_tmp)
7568 	need_tmp = 1;
7569       else if (se->force_no_tmp)
7570 	need_tmp = 0;
7571 
7572       if (need_tmp)
7573 	full = 0;
7574       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
7575 	{
7576 	  /* Create a new descriptor if the array doesn't have one.  */
7577 	  full = 0;
7578 	}
7579       else if (info->ref->u.ar.type == AR_FULL || se->descriptor_only)
7580 	full = 1;
7581       else if (se->direct_byref)
7582 	full = 0;
7583       else if (info->ref->u.ar.dimen == 0 && !info->ref->next)
7584 	full = 1;
7585       else if (info->ref->u.ar.type == AR_SECTION && se->want_pointer)
7586 	full = 0;
7587       else
7588 	full = gfc_full_array_ref_p (info->ref, NULL);
7589 
7590       if (full && !transposed_dims (ss))
7591 	{
7592 	  if (se->direct_byref && !se->byref_noassign)
7593 	    {
7594 	      /* Copy the descriptor for pointer assignments.  */
7595 	      gfc_add_modify (&se->pre, se->expr, desc);
7596 
7597 	      /* Add any offsets from subreferences.  */
7598 	      gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE,
7599 				      subref_array_target, expr);
7600 
7601 	      /* ....and set the span field.  */
7602 	      tmp = gfc_conv_descriptor_span_get (desc);
7603 	      gfc_conv_descriptor_span_set (&se->pre, se->expr, tmp);
7604 	    }
7605 	  else if (se->want_pointer)
7606 	    {
7607 	      /* We pass full arrays directly.  This means that pointers and
7608 		 allocatable arrays should also work.  */
7609 	      se->expr = gfc_build_addr_expr (NULL_TREE, desc);
7610 	    }
7611 	  else
7612 	    {
7613 	      se->expr = desc;
7614 	    }
7615 
7616 	  if (expr->ts.type == BT_CHARACTER && !deferred_array_component)
7617 	    se->string_length = gfc_get_expr_charlen (expr);
7618 	  /* The ss_info string length is returned set to the value of the
7619 	     hidden string length component.  */
7620 	  else if (deferred_array_component)
7621 	    se->string_length = ss_info->string_length;
7622 
7623 	  gfc_free_ss_chain (ss);
7624 	  return;
7625 	}
7626       break;
7627 
7628     case EXPR_FUNCTION:
7629       /* A transformational function return value will be a temporary
7630 	 array descriptor.  We still need to go through the scalarizer
7631 	 to create the descriptor.  Elemental functions are handled as
7632 	 arbitrary expressions, i.e. copy to a temporary.  */
7633 
7634       if (se->direct_byref)
7635 	{
7636 	  gcc_assert (ss_type == GFC_SS_FUNCTION && ss_expr == expr);
7637 
7638 	  /* For pointer assignments pass the descriptor directly.  */
7639 	  if (se->ss == NULL)
7640 	    se->ss = ss;
7641 	  else
7642 	    gcc_assert (se->ss == ss);
7643 
7644 	  if (!is_pointer_array (se->expr))
7645 	    {
7646 	      tmp = gfc_get_element_type (TREE_TYPE (se->expr));
7647 	      tmp = fold_convert (gfc_array_index_type,
7648 				  size_in_bytes (tmp));
7649 	      gfc_conv_descriptor_span_set (&se->pre, se->expr, tmp);
7650 	    }
7651 
7652 	  se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
7653 	  gfc_conv_expr (se, expr);
7654 
7655 	  gfc_free_ss_chain (ss);
7656 	  return;
7657 	}
7658 
7659       if (ss_expr != expr || ss_type != GFC_SS_FUNCTION)
7660 	{
7661 	  if (ss_expr != expr)
7662 	    /* Elemental function.  */
7663 	    gcc_assert ((expr->value.function.esym != NULL
7664 			 && expr->value.function.esym->attr.elemental)
7665 			|| (expr->value.function.isym != NULL
7666 			    && expr->value.function.isym->elemental)
7667 			|| (gfc_expr_attr (expr).proc_pointer
7668 			    && gfc_expr_attr (expr).elemental)
7669 			|| gfc_inline_intrinsic_function_p (expr));
7670 
7671 	  need_tmp = 1;
7672 	  if (expr->ts.type == BT_CHARACTER
7673 		&& expr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
7674 	    get_array_charlen (expr, se);
7675 
7676 	  info = NULL;
7677 	}
7678       else
7679 	{
7680 	  /* Transformational function.  */
7681 	  info = &ss_info->data.array;
7682 	  need_tmp = 0;
7683 	}
7684       break;
7685 
7686     case EXPR_ARRAY:
7687       /* Constant array constructors don't need a temporary.  */
7688       if (ss_type == GFC_SS_CONSTRUCTOR
7689 	  && expr->ts.type != BT_CHARACTER
7690 	  && gfc_constant_array_constructor_p (expr->value.constructor))
7691 	{
7692 	  need_tmp = 0;
7693 	  info = &ss_info->data.array;
7694 	}
7695       else
7696 	{
7697 	  need_tmp = 1;
7698 	  info = NULL;
7699 	}
7700       break;
7701 
7702     default:
7703       /* Something complicated.  Copy it into a temporary.  */
7704       need_tmp = 1;
7705       info = NULL;
7706       break;
7707     }
7708 
7709   /* If we are creating a temporary, we don't need to bother about aliases
7710      anymore.  */
7711   if (need_tmp)
7712     se->force_tmp = 0;
7713 
7714   gfc_init_loopinfo (&loop);
7715 
7716   /* Associate the SS with the loop.  */
7717   gfc_add_ss_to_loop (&loop, ss);
7718 
7719   /* Tell the scalarizer not to bother creating loop variables, etc.  */
7720   if (!need_tmp)
7721     loop.array_parameter = 1;
7722   else
7723     /* The right-hand side of a pointer assignment mustn't use a temporary.  */
7724     gcc_assert (!se->direct_byref);
7725 
7726   /* Do we need bounds checking or not?  */
7727   ss->no_bounds_check = expr->no_bounds_check;
7728 
7729   /* Setup the scalarizing loops and bounds.  */
7730   gfc_conv_ss_startstride (&loop);
7731 
7732   if (need_tmp)
7733     {
7734       if (expr->ts.type == BT_CHARACTER
7735 	  && (!expr->ts.u.cl->backend_decl || expr->expr_type == EXPR_ARRAY))
7736 	get_array_charlen (expr, se);
7737 
7738       /* Tell the scalarizer to make a temporary.  */
7739       loop.temp_ss = gfc_get_temp_ss (gfc_typenode_for_spec (&expr->ts),
7740 				      ((expr->ts.type == BT_CHARACTER)
7741 				       ? expr->ts.u.cl->backend_decl
7742 				       : NULL),
7743 				      loop.dimen);
7744 
7745       se->string_length = loop.temp_ss->info->string_length;
7746       gcc_assert (loop.temp_ss->dimen == loop.dimen);
7747       gfc_add_ss_to_loop (&loop, loop.temp_ss);
7748     }
7749 
7750   gfc_conv_loop_setup (&loop, & expr->where);
7751 
7752   if (need_tmp)
7753     {
7754       /* Copy into a temporary and pass that.  We don't need to copy the data
7755          back because expressions and vector subscripts must be INTENT_IN.  */
7756       /* TODO: Optimize passing function return values.  */
7757       gfc_se lse;
7758       gfc_se rse;
7759       bool deep_copy;
7760 
7761       /* Start the copying loops.  */
7762       gfc_mark_ss_chain_used (loop.temp_ss, 1);
7763       gfc_mark_ss_chain_used (ss, 1);
7764       gfc_start_scalarized_body (&loop, &block);
7765 
7766       /* Copy each data element.  */
7767       gfc_init_se (&lse, NULL);
7768       gfc_copy_loopinfo_to_se (&lse, &loop);
7769       gfc_init_se (&rse, NULL);
7770       gfc_copy_loopinfo_to_se (&rse, &loop);
7771 
7772       lse.ss = loop.temp_ss;
7773       rse.ss = ss;
7774 
7775       gfc_conv_tmp_array_ref (&lse);
7776       if (expr->ts.type == BT_CHARACTER)
7777 	{
7778 	  gfc_conv_expr (&rse, expr);
7779 	  if (POINTER_TYPE_P (TREE_TYPE (rse.expr)))
7780 	    rse.expr = build_fold_indirect_ref_loc (input_location,
7781 						rse.expr);
7782 	}
7783       else
7784         gfc_conv_expr_val (&rse, expr);
7785 
7786       gfc_add_block_to_block (&block, &rse.pre);
7787       gfc_add_block_to_block (&block, &lse.pre);
7788 
7789       lse.string_length = rse.string_length;
7790 
7791       deep_copy = !se->data_not_needed
7792 		  && (expr->expr_type == EXPR_VARIABLE
7793 		      || expr->expr_type == EXPR_ARRAY);
7794       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts,
7795 				     deep_copy, false);
7796       gfc_add_expr_to_block (&block, tmp);
7797 
7798       /* Finish the copying loops.  */
7799       gfc_trans_scalarizing_loops (&loop, &block);
7800 
7801       desc = loop.temp_ss->info->data.array.descriptor;
7802     }
7803   else if (expr->expr_type == EXPR_FUNCTION && !transposed_dims (ss))
7804     {
7805       desc = info->descriptor;
7806       se->string_length = ss_info->string_length;
7807     }
7808   else
7809     {
7810       /* We pass sections without copying to a temporary.  Make a new
7811 	 descriptor and point it at the section we want.  The loop variable
7812 	 limits will be the limits of the section.
7813 	 A function may decide to repack the array to speed up access, but
7814 	 we're not bothered about that here.  */
7815       int dim, ndim, codim;
7816       tree parm;
7817       tree parmtype;
7818       tree dtype;
7819       tree stride;
7820       tree from;
7821       tree to;
7822       tree base;
7823       tree offset;
7824 
7825       ndim = info->ref ? info->ref->u.ar.dimen : ss->dimen;
7826 
7827       if (se->want_coarray)
7828 	{
7829 	  gfc_array_ref *ar = &info->ref->u.ar;
7830 
7831 	  codim = gfc_get_corank (expr);
7832 	  for (n = 0; n < codim - 1; n++)
7833 	    {
7834 	      /* Make sure we are not lost somehow.  */
7835 	      gcc_assert (ar->dimen_type[n + ndim] == DIMEN_THIS_IMAGE);
7836 
7837 	      /* Make sure the call to gfc_conv_section_startstride won't
7838 		 generate unnecessary code to calculate stride.  */
7839 	      gcc_assert (ar->stride[n + ndim] == NULL);
7840 
7841 	      gfc_conv_section_startstride (&loop.pre, ss, n + ndim);
7842 	      loop.from[n + loop.dimen] = info->start[n + ndim];
7843 	      loop.to[n + loop.dimen]   = info->end[n + ndim];
7844 	    }
7845 
7846 	  gcc_assert (n == codim - 1);
7847 	  evaluate_bound (&loop.pre, info->start, ar->start,
7848 			  info->descriptor, n + ndim, true,
7849 			  ar->as->type == AS_DEFERRED);
7850 	  loop.from[n + loop.dimen] = info->start[n + ndim];
7851 	}
7852       else
7853 	codim = 0;
7854 
7855       /* Set the string_length for a character array.  */
7856       if (expr->ts.type == BT_CHARACTER)
7857 	{
7858 	  if (deferred_array_component)
7859 	    se->string_length = ss_info->string_length;
7860 	  else
7861 	    se->string_length =  gfc_get_expr_charlen (expr);
7862 
7863 	  if (VAR_P (se->string_length)
7864 	      && expr->ts.u.cl->backend_decl == se->string_length)
7865 	    tmp = ss_info->string_length;
7866 	  else
7867 	    tmp = se->string_length;
7868 
7869 	  if (expr->ts.deferred && VAR_P (expr->ts.u.cl->backend_decl))
7870 	    gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl, tmp);
7871 	  else
7872 	    expr->ts.u.cl->backend_decl = tmp;
7873 	}
7874 
7875       /* If we have an array section, are assigning  or passing an array
7876 	 section argument make sure that the lower bound is 1.  References
7877 	 to the full array should otherwise keep the original bounds.  */
7878       if (!info->ref || info->ref->u.ar.type != AR_FULL)
7879 	for (dim = 0; dim < loop.dimen; dim++)
7880 	  if (!integer_onep (loop.from[dim]))
7881 	    {
7882 	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
7883 				     gfc_array_index_type, gfc_index_one_node,
7884 				     loop.from[dim]);
7885 	      loop.to[dim] = fold_build2_loc (input_location, PLUS_EXPR,
7886 					      gfc_array_index_type,
7887 					      loop.to[dim], tmp);
7888 	      loop.from[dim] = gfc_index_one_node;
7889 	    }
7890 
7891       desc = info->descriptor;
7892       if (se->direct_byref && !se->byref_noassign)
7893 	{
7894 	  /* For pointer assignments we fill in the destination.  */
7895 	  parm = se->expr;
7896 	  parmtype = TREE_TYPE (parm);
7897 	}
7898       else
7899 	{
7900 	  /* Otherwise make a new one.  */
7901 	  if (expr->ts.type == BT_CHARACTER)
7902 	    parmtype = gfc_typenode_for_spec (&expr->ts);
7903 	  else
7904 	    parmtype = gfc_get_element_type (TREE_TYPE (desc));
7905 
7906 	  parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, codim,
7907 						loop.from, loop.to, 0,
7908 						GFC_ARRAY_UNKNOWN, false);
7909 	  parm = gfc_create_var (parmtype, "parm");
7910 
7911 	  /* When expression is a class object, then add the class' handle to
7912 	     the parm_decl.  */
7913 	  if (expr->ts.type == BT_CLASS && expr->expr_type == EXPR_VARIABLE)
7914 	    {
7915 	      gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (expr);
7916 	      gfc_se classse;
7917 
7918 	      /* class_expr can be NULL, when no _class ref is in expr.
7919 		 We must not fix this here with a gfc_fix_class_ref ().  */
7920 	      if (class_expr)
7921 		{
7922 		  gfc_init_se (&classse, NULL);
7923 		  gfc_conv_expr (&classse, class_expr);
7924 		  gfc_free_expr (class_expr);
7925 
7926 		  gcc_assert (classse.pre.head == NULL_TREE
7927 			      && classse.post.head == NULL_TREE);
7928 		  gfc_allocate_lang_decl (parm);
7929 		  GFC_DECL_SAVED_DESCRIPTOR (parm) = classse.expr;
7930 		}
7931 	    }
7932 	}
7933 
7934       /* Set the span field.  */
7935       tmp = gfc_get_array_span (desc, expr);
7936       if (tmp)
7937 	gfc_conv_descriptor_span_set (&loop.pre, parm, tmp);
7938 
7939       /* The following can be somewhat confusing.  We have two
7940          descriptors, a new one and the original array.
7941          {parm, parmtype, dim} refer to the new one.
7942          {desc, type, n, loop} refer to the original, which maybe
7943          a descriptorless array.
7944          The bounds of the scalarization are the bounds of the section.
7945          We don't have to worry about numeric overflows when calculating
7946          the offsets because all elements are within the array data.  */
7947 
7948       /* Set the dtype.  */
7949       tmp = gfc_conv_descriptor_dtype (parm);
7950       if (se->unlimited_polymorphic)
7951 	dtype = gfc_get_dtype (TREE_TYPE (desc), &loop.dimen);
7952       else if (expr->ts.type == BT_ASSUMED)
7953 	{
7954 	  tree tmp2 = desc;
7955 	  if (DECL_LANG_SPECIFIC (tmp2) && GFC_DECL_SAVED_DESCRIPTOR (tmp2))
7956 	    tmp2 = GFC_DECL_SAVED_DESCRIPTOR (tmp2);
7957 	  if (POINTER_TYPE_P (TREE_TYPE (tmp2)))
7958 	    tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
7959 	  dtype = gfc_conv_descriptor_dtype (tmp2);
7960 	}
7961       else
7962 	dtype = gfc_get_dtype (parmtype);
7963       gfc_add_modify (&loop.pre, tmp, dtype);
7964 
7965       /* The 1st element in the section.  */
7966       base = gfc_index_zero_node;
7967 
7968       /* The offset from the 1st element in the section.  */
7969       offset = gfc_index_zero_node;
7970 
7971       for (n = 0; n < ndim; n++)
7972 	{
7973 	  stride = gfc_conv_array_stride (desc, n);
7974 
7975 	  /* Work out the 1st element in the section.  */
7976 	  if (info->ref
7977 	      && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
7978 	    {
7979 	      gcc_assert (info->subscript[n]
7980 			  && info->subscript[n]->info->type == GFC_SS_SCALAR);
7981 	      start = info->subscript[n]->info->data.scalar.value;
7982 	    }
7983 	  else
7984 	    {
7985 	      /* Evaluate and remember the start of the section.  */
7986 	      start = info->start[n];
7987 	      stride = gfc_evaluate_now (stride, &loop.pre);
7988 	    }
7989 
7990 	  tmp = gfc_conv_array_lbound (desc, n);
7991 	  tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp),
7992 				 start, tmp);
7993 	  tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
7994 				 tmp, stride);
7995 	  base = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
7996 				    base, tmp);
7997 
7998 	  if (info->ref
7999 	      && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
8000 	    {
8001 	      /* For elemental dimensions, we only need the 1st
8002 		 element in the section.  */
8003 	      continue;
8004 	    }
8005 
8006 	  /* Vector subscripts need copying and are handled elsewhere.  */
8007 	  if (info->ref)
8008 	    gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
8009 
8010 	  /* look for the corresponding scalarizer dimension: dim.  */
8011 	  for (dim = 0; dim < ndim; dim++)
8012 	    if (ss->dim[dim] == n)
8013 	      break;
8014 
8015 	  /* loop exited early: the DIM being looked for has been found.  */
8016 	  gcc_assert (dim < ndim);
8017 
8018 	  /* Set the new lower bound.  */
8019 	  from = loop.from[dim];
8020 	  to = loop.to[dim];
8021 
8022 	  gfc_conv_descriptor_lbound_set (&loop.pre, parm,
8023 					  gfc_rank_cst[dim], from);
8024 
8025 	  /* Set the new upper bound.  */
8026 	  gfc_conv_descriptor_ubound_set (&loop.pre, parm,
8027 					  gfc_rank_cst[dim], to);
8028 
8029 	  /* Multiply the stride by the section stride to get the
8030 	     total stride.  */
8031 	  stride = fold_build2_loc (input_location, MULT_EXPR,
8032 				    gfc_array_index_type,
8033 				    stride, info->stride[n]);
8034 
8035 	  tmp = fold_build2_loc (input_location, MULT_EXPR,
8036 				 TREE_TYPE (offset), stride, from);
8037 	  offset = fold_build2_loc (input_location, MINUS_EXPR,
8038 				   TREE_TYPE (offset), offset, tmp);
8039 
8040 	  /* Store the new stride.  */
8041 	  gfc_conv_descriptor_stride_set (&loop.pre, parm,
8042 					  gfc_rank_cst[dim], stride);
8043 	}
8044 
8045       for (n = loop.dimen; n < loop.dimen + codim; n++)
8046 	{
8047 	  from = loop.from[n];
8048 	  to = loop.to[n];
8049 	  gfc_conv_descriptor_lbound_set (&loop.pre, parm,
8050 					  gfc_rank_cst[n], from);
8051 	  if (n < loop.dimen + codim - 1)
8052 	    gfc_conv_descriptor_ubound_set (&loop.pre, parm,
8053 					    gfc_rank_cst[n], to);
8054 	}
8055 
8056       if (se->data_not_needed)
8057 	gfc_conv_descriptor_data_set (&loop.pre, parm,
8058 				      gfc_index_zero_node);
8059       else
8060 	/* Point the data pointer at the 1st element in the section.  */
8061 	gfc_get_dataptr_offset (&loop.pre, parm, desc, base,
8062 				subref_array_target, expr);
8063 
8064       gfc_conv_descriptor_offset_set (&loop.pre, parm, offset);
8065 
8066       desc = parm;
8067     }
8068 
8069   /* For class arrays add the class tree into the saved descriptor to
8070      enable getting of _vptr and the like.  */
8071   if (expr->expr_type == EXPR_VARIABLE && VAR_P (desc)
8072       && IS_CLASS_ARRAY (expr->symtree->n.sym))
8073     {
8074       gfc_allocate_lang_decl (desc);
8075       GFC_DECL_SAVED_DESCRIPTOR (desc) =
8076 	  DECL_LANG_SPECIFIC (expr->symtree->n.sym->backend_decl) ?
8077 	    GFC_DECL_SAVED_DESCRIPTOR (expr->symtree->n.sym->backend_decl)
8078 	  : expr->symtree->n.sym->backend_decl;
8079     }
8080   else if (expr->expr_type == EXPR_ARRAY && VAR_P (desc)
8081 	   && IS_CLASS_ARRAY (expr))
8082     {
8083       tree vtype;
8084       gfc_allocate_lang_decl (desc);
8085       tmp = gfc_create_var (expr->ts.u.derived->backend_decl, "class");
8086       GFC_DECL_SAVED_DESCRIPTOR (desc) = tmp;
8087       vtype = gfc_class_vptr_get (tmp);
8088       gfc_add_modify (&se->pre, vtype,
8089 		      gfc_build_addr_expr (TREE_TYPE (vtype),
8090 				      gfc_find_vtab (&expr->ts)->backend_decl));
8091     }
8092   if (!se->direct_byref || se->byref_noassign)
8093     {
8094       /* Get a pointer to the new descriptor.  */
8095       if (se->want_pointer)
8096 	se->expr = gfc_build_addr_expr (NULL_TREE, desc);
8097       else
8098 	se->expr = desc;
8099     }
8100 
8101   gfc_add_block_to_block (&se->pre, &loop.pre);
8102   gfc_add_block_to_block (&se->post, &loop.post);
8103 
8104   /* Cleanup the scalarizer.  */
8105   gfc_cleanup_loop (&loop);
8106 }
8107 
8108 
8109 /* Calculate the array size (number of elements); if dim != NULL_TREE,
8110    return size for that dim (dim=0..rank-1; only for GFC_DESCRIPTOR_TYPE_P).  */
8111 tree
gfc_tree_array_size(stmtblock_t * block,tree desc,gfc_expr * expr,tree dim)8112 gfc_tree_array_size (stmtblock_t *block, tree desc, gfc_expr *expr, tree dim)
8113 {
8114   if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
8115     {
8116       gcc_assert (dim == NULL_TREE);
8117       return GFC_TYPE_ARRAY_SIZE (TREE_TYPE (desc));
8118     }
8119   tree size, tmp, rank = NULL_TREE, cond = NULL_TREE;
8120   symbol_attribute attr = gfc_expr_attr (expr);
8121   gfc_array_spec *as = gfc_get_full_arrayspec_from_expr (expr);
8122   gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)));
8123   if ((!attr.pointer && !attr.allocatable && as && as->type == AS_ASSUMED_RANK)
8124        || !dim)
8125     {
8126       if (expr->rank < 0)
8127 	rank = fold_convert (signed_char_type_node,
8128 			     gfc_conv_descriptor_rank (desc));
8129       else
8130 	rank = build_int_cst (signed_char_type_node, expr->rank);
8131     }
8132 
8133   if (dim || expr->rank == 1)
8134     {
8135       if (!dim)
8136 	dim = gfc_index_zero_node;
8137       tree ubound = gfc_conv_descriptor_ubound_get (desc, dim);
8138       tree lbound = gfc_conv_descriptor_lbound_get (desc, dim);
8139 
8140       size = fold_build2_loc (input_location, MINUS_EXPR,
8141 			      gfc_array_index_type, ubound, lbound);
8142       size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
8143 			      size, gfc_index_one_node);
8144       /* if (!allocatable && !pointer && assumed rank)
8145 	   size = (idx == rank && ubound[rank-1] == -1 ? -1 : size;
8146 	 else
8147 	   size = max (0, size);  */
8148       size = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
8149 			      size, gfc_index_zero_node);
8150       if (!attr.pointer && !attr.allocatable
8151 	  && as && as->type == AS_ASSUMED_RANK)
8152 	{
8153 	  tmp = fold_build2_loc (input_location, MINUS_EXPR, signed_char_type_node,
8154 				 rank, build_int_cst (signed_char_type_node, 1));
8155 	  cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
8156 				  fold_convert (signed_char_type_node, dim),
8157 				  tmp);
8158 	  tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
8159 				 gfc_conv_descriptor_ubound_get (desc, dim),
8160 				 build_int_cst (gfc_array_index_type, -1));
8161 	  cond = fold_build2_loc (input_location, TRUTH_AND_EXPR, boolean_type_node,
8162 				  cond, tmp);
8163 	  tmp = build_int_cst (gfc_array_index_type, -1);
8164 	  size = build3_loc (input_location, COND_EXPR, gfc_array_index_type,
8165 			     cond, tmp, size);
8166 	}
8167       return size;
8168     }
8169 
8170   /* size = 1. */
8171   size = gfc_create_var (gfc_array_index_type, "size");
8172   gfc_add_modify (block, size, build_int_cst (TREE_TYPE (size), 1));
8173   tree extent = gfc_create_var (gfc_array_index_type, "extent");
8174 
8175   stmtblock_t cond_block, loop_body;
8176   gfc_init_block (&cond_block);
8177   gfc_init_block (&loop_body);
8178 
8179   /* Loop: for (i = 0; i < rank; ++i).  */
8180   tree idx = gfc_create_var (signed_char_type_node, "idx");
8181   /* Loop body.  */
8182   /* #if (assumed-rank + !allocatable && !pointer)
8183        if (idx == rank - 1 && dim[idx].ubound == -1)
8184 	 extent = -1;
8185        else
8186      #endif
8187 	 extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1
8188 	 if (extent < 0)
8189 	   extent = 0
8190       size *= extent.  */
8191   cond = NULL_TREE;
8192   if (!attr.pointer && !attr.allocatable && as && as->type == AS_ASSUMED_RANK)
8193     {
8194       tmp = fold_build2_loc (input_location, MINUS_EXPR, signed_char_type_node,
8195 			     rank, build_int_cst (signed_char_type_node, 1));
8196       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
8197 				  idx, tmp);
8198       tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
8199 			     gfc_conv_descriptor_ubound_get (desc, idx),
8200 			     build_int_cst (gfc_array_index_type, -1));
8201       cond = fold_build2_loc (input_location, TRUTH_AND_EXPR, boolean_type_node,
8202 			      cond, tmp);
8203     }
8204   tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8205 			 gfc_conv_descriptor_ubound_get (desc, idx),
8206 			 gfc_conv_descriptor_lbound_get (desc, idx));
8207   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
8208 			 tmp, gfc_index_one_node);
8209   gfc_add_modify (&cond_block, extent, tmp);
8210   tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
8211 			 extent, gfc_index_zero_node);
8212   tmp = build3_v (COND_EXPR, tmp,
8213 		  fold_build2_loc (input_location, MODIFY_EXPR,
8214 				   gfc_array_index_type,
8215 				   extent, gfc_index_zero_node),
8216 		  build_empty_stmt (input_location));
8217   gfc_add_expr_to_block (&cond_block, tmp);
8218   tmp = gfc_finish_block (&cond_block);
8219   if (cond)
8220     tmp = build3_v (COND_EXPR, cond,
8221 		    fold_build2_loc (input_location, MODIFY_EXPR,
8222 				     gfc_array_index_type, extent,
8223 				     build_int_cst (gfc_array_index_type, -1)),
8224 		    tmp);
8225    gfc_add_expr_to_block (&loop_body, tmp);
8226    /* size *= extent.  */
8227    gfc_add_modify (&loop_body, size,
8228 		   fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
8229 				    size, extent));
8230   /* Generate loop. */
8231   gfc_simple_for_loop (block, idx, build_int_cst (TREE_TYPE (idx), 0), rank, LT_EXPR,
8232 		       build_int_cst (TREE_TYPE (idx), 1),
8233 		       gfc_finish_block (&loop_body));
8234   return size;
8235 }
8236 
8237 /* Helper function for gfc_conv_array_parameter if array size needs to be
8238    computed.  */
8239 
8240 static void
array_parameter_size(stmtblock_t * block,tree desc,gfc_expr * expr,tree * size)8241 array_parameter_size (stmtblock_t *block, tree desc, gfc_expr *expr, tree *size)
8242 {
8243   tree elem;
8244   *size = gfc_tree_array_size (block, desc, expr, NULL);
8245   elem = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
8246   *size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
8247 			   *size, fold_convert (gfc_array_index_type, elem));
8248 }
8249 
8250 /* Helper function - return true if the argument is a pointer.  */
8251 
8252 static bool
is_pointer(gfc_expr * e)8253 is_pointer (gfc_expr *e)
8254 {
8255   gfc_symbol *sym;
8256 
8257   if (e->expr_type != EXPR_VARIABLE ||  e->symtree == NULL)
8258     return false;
8259 
8260   sym = e->symtree->n.sym;
8261   if (sym == NULL)
8262     return false;
8263 
8264   return sym->attr.pointer || sym->attr.proc_pointer;
8265 }
8266 
8267 /* Convert an array for passing as an actual parameter.  */
8268 
8269 void
gfc_conv_array_parameter(gfc_se * se,gfc_expr * expr,bool g77,const gfc_symbol * fsym,const char * proc_name,tree * size)8270 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, bool g77,
8271 			  const gfc_symbol *fsym, const char *proc_name,
8272 			  tree *size)
8273 {
8274   tree ptr;
8275   tree desc;
8276   tree tmp = NULL_TREE;
8277   tree stmt;
8278   tree parent = DECL_CONTEXT (current_function_decl);
8279   bool full_array_var;
8280   bool this_array_result;
8281   bool contiguous;
8282   bool no_pack;
8283   bool array_constructor;
8284   bool good_allocatable;
8285   bool ultimate_ptr_comp;
8286   bool ultimate_alloc_comp;
8287   gfc_symbol *sym;
8288   stmtblock_t block;
8289   gfc_ref *ref;
8290 
8291   ultimate_ptr_comp = false;
8292   ultimate_alloc_comp = false;
8293 
8294   for (ref = expr->ref; ref; ref = ref->next)
8295     {
8296       if (ref->next == NULL)
8297         break;
8298 
8299       if (ref->type == REF_COMPONENT)
8300 	{
8301 	  ultimate_ptr_comp = ref->u.c.component->attr.pointer;
8302 	  ultimate_alloc_comp = ref->u.c.component->attr.allocatable;
8303 	}
8304     }
8305 
8306   full_array_var = false;
8307   contiguous = false;
8308 
8309   if (expr->expr_type == EXPR_VARIABLE && ref && !ultimate_ptr_comp)
8310     full_array_var = gfc_full_array_ref_p (ref, &contiguous);
8311 
8312   sym = full_array_var ? expr->symtree->n.sym : NULL;
8313 
8314   /* The symbol should have an array specification.  */
8315   gcc_assert (!sym || sym->as || ref->u.ar.as);
8316 
8317   if (expr->expr_type == EXPR_ARRAY && expr->ts.type == BT_CHARACTER)
8318     {
8319       get_array_ctor_strlen (&se->pre, expr->value.constructor, &tmp);
8320       expr->ts.u.cl->backend_decl = tmp;
8321       se->string_length = tmp;
8322     }
8323 
8324   /* Is this the result of the enclosing procedure?  */
8325   this_array_result = (full_array_var && sym->attr.flavor == FL_PROCEDURE);
8326   if (this_array_result
8327 	&& (sym->backend_decl != current_function_decl)
8328 	&& (sym->backend_decl != parent))
8329     this_array_result = false;
8330 
8331   /* Passing address of the array if it is not pointer or assumed-shape.  */
8332   if (full_array_var && g77 && !this_array_result
8333       && sym->ts.type != BT_DERIVED && sym->ts.type != BT_CLASS)
8334     {
8335       tmp = gfc_get_symbol_decl (sym);
8336 
8337       if (sym->ts.type == BT_CHARACTER)
8338 	se->string_length = sym->ts.u.cl->backend_decl;
8339 
8340       if (!sym->attr.pointer
8341 	  && sym->as
8342 	  && sym->as->type != AS_ASSUMED_SHAPE
8343 	  && sym->as->type != AS_DEFERRED
8344 	  && sym->as->type != AS_ASSUMED_RANK
8345 	  && !sym->attr.allocatable)
8346         {
8347 	  /* Some variables are declared directly, others are declared as
8348 	     pointers and allocated on the heap.  */
8349           if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
8350             se->expr = tmp;
8351           else
8352 	    se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
8353 	  if (size)
8354 	    array_parameter_size (&se->pre, tmp, expr, size);
8355 	  return;
8356         }
8357 
8358       if (sym->attr.allocatable)
8359         {
8360 	  if (sym->attr.dummy || sym->attr.result)
8361 	    {
8362 	      gfc_conv_expr_descriptor (se, expr);
8363 	      tmp = se->expr;
8364 	    }
8365 	  if (size)
8366 	    array_parameter_size (&se->pre, tmp, expr, size);
8367 	  se->expr = gfc_conv_array_data (tmp);
8368           return;
8369         }
8370     }
8371 
8372   /* A convenient reduction in scope.  */
8373   contiguous = g77 && !this_array_result && contiguous;
8374 
8375   /* There is no need to pack and unpack the array, if it is contiguous
8376      and not a deferred- or assumed-shape array, or if it is simply
8377      contiguous.  */
8378   no_pack = ((sym && sym->as
8379 		  && !sym->attr.pointer
8380 		  && sym->as->type != AS_DEFERRED
8381 		  && sym->as->type != AS_ASSUMED_RANK
8382 		  && sym->as->type != AS_ASSUMED_SHAPE)
8383 		      ||
8384 	     (ref && ref->u.ar.as
8385 		  && ref->u.ar.as->type != AS_DEFERRED
8386 		  && ref->u.ar.as->type != AS_ASSUMED_RANK
8387 		  && ref->u.ar.as->type != AS_ASSUMED_SHAPE)
8388 		      ||
8389 	     gfc_is_simply_contiguous (expr, false, true));
8390 
8391   no_pack = contiguous && no_pack;
8392 
8393   /* If we have an EXPR_OP or a function returning an explicit-shaped
8394      or allocatable array, an array temporary will be generated which
8395      does not need to be packed / unpacked if passed to an
8396      explicit-shape dummy array.  */
8397 
8398   if (g77)
8399     {
8400       if (expr->expr_type == EXPR_OP)
8401 	no_pack = 1;
8402       else if (expr->expr_type == EXPR_FUNCTION && expr->value.function.esym)
8403 	{
8404 	  gfc_symbol *result = expr->value.function.esym->result;
8405 	  if (result->attr.dimension
8406 	      && (result->as->type == AS_EXPLICIT
8407 		  || result->attr.allocatable
8408 		  || result->attr.contiguous))
8409 	    no_pack = 1;
8410 	}
8411     }
8412 
8413   /* Array constructors are always contiguous and do not need packing.  */
8414   array_constructor = g77 && !this_array_result && expr->expr_type == EXPR_ARRAY;
8415 
8416   /* Same is true of contiguous sections from allocatable variables.  */
8417   good_allocatable = contiguous
8418 		       && expr->symtree
8419 		       && expr->symtree->n.sym->attr.allocatable;
8420 
8421   /* Or ultimate allocatable components.  */
8422   ultimate_alloc_comp = contiguous && ultimate_alloc_comp;
8423 
8424   if (no_pack || array_constructor || good_allocatable || ultimate_alloc_comp)
8425     {
8426       gfc_conv_expr_descriptor (se, expr);
8427       /* Deallocate the allocatable components of structures that are
8428 	 not variable.  */
8429       if ((expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS)
8430 	   && expr->ts.u.derived->attr.alloc_comp
8431 	   && expr->expr_type != EXPR_VARIABLE)
8432 	{
8433 	  tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, se->expr, expr->rank);
8434 
8435 	  /* The components shall be deallocated before their containing entity.  */
8436 	  gfc_prepend_expr_to_block (&se->post, tmp);
8437 	}
8438       if (expr->ts.type == BT_CHARACTER && expr->expr_type != EXPR_FUNCTION)
8439 	se->string_length = expr->ts.u.cl->backend_decl;
8440       if (size)
8441 	array_parameter_size (&se->pre, se->expr, expr, size);
8442       se->expr = gfc_conv_array_data (se->expr);
8443       return;
8444     }
8445 
8446   if (this_array_result)
8447     {
8448       /* Result of the enclosing function.  */
8449       gfc_conv_expr_descriptor (se, expr);
8450       if (size)
8451 	array_parameter_size (&se->pre, se->expr, expr, size);
8452       se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
8453 
8454       if (g77 && TREE_TYPE (TREE_TYPE (se->expr)) != NULL_TREE
8455 	      && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
8456 	se->expr = gfc_conv_array_data (build_fold_indirect_ref_loc (input_location,
8457 								 se->expr));
8458 
8459       return;
8460     }
8461   else
8462     {
8463       /* Every other type of array.  */
8464       se->want_pointer = 1;
8465       gfc_conv_expr_descriptor (se, expr);
8466 
8467       if (size)
8468 	array_parameter_size (&se->pre,
8469 			      build_fold_indirect_ref_loc (input_location,
8470 							    se->expr),
8471 			      expr, size);
8472     }
8473 
8474   /* Deallocate the allocatable components of structures that are
8475      not variable, for descriptorless arguments.
8476      Arguments with a descriptor are handled in gfc_conv_procedure_call.  */
8477   if (g77 && (expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS)
8478 	  && expr->ts.u.derived->attr.alloc_comp
8479 	  && expr->expr_type != EXPR_VARIABLE)
8480     {
8481       tmp = build_fold_indirect_ref_loc (input_location, se->expr);
8482       tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp, expr->rank);
8483 
8484       /* The components shall be deallocated before their containing entity.  */
8485       gfc_prepend_expr_to_block (&se->post, tmp);
8486     }
8487 
8488   if (g77 || (fsym && fsym->attr.contiguous
8489 	      && !gfc_is_simply_contiguous (expr, false, true)))
8490     {
8491       tree origptr = NULL_TREE;
8492 
8493       desc = se->expr;
8494 
8495       /* For contiguous arrays, save the original value of the descriptor.  */
8496       if (!g77)
8497 	{
8498 	  origptr = gfc_create_var (pvoid_type_node, "origptr");
8499 	  tmp = build_fold_indirect_ref_loc (input_location, desc);
8500 	  tmp = gfc_conv_array_data (tmp);
8501 	  tmp = fold_build2_loc (input_location, MODIFY_EXPR,
8502 				 TREE_TYPE (origptr), origptr,
8503 				 fold_convert (TREE_TYPE (origptr), tmp));
8504 	  gfc_add_expr_to_block (&se->pre, tmp);
8505 	}
8506 
8507       /* Repack the array.  */
8508       if (warn_array_temporaries)
8509 	{
8510 	  if (fsym)
8511 	    gfc_warning (OPT_Warray_temporaries,
8512 			 "Creating array temporary at %L for argument %qs",
8513 			 &expr->where, fsym->name);
8514 	  else
8515 	    gfc_warning (OPT_Warray_temporaries,
8516 			 "Creating array temporary at %L", &expr->where);
8517 	}
8518 
8519       /* When optmizing, we can use gfc_conv_subref_array_arg for
8520 	 making the packing and unpacking operation visible to the
8521 	 optimizers.  */
8522 
8523       if (g77 && flag_inline_arg_packing && expr->expr_type == EXPR_VARIABLE
8524 	  && !is_pointer (expr) && ! gfc_has_dimen_vector_ref (expr)
8525 	  && !(expr->symtree->n.sym->as
8526 	       && expr->symtree->n.sym->as->type == AS_ASSUMED_RANK)
8527 	  && (fsym == NULL || fsym->ts.type != BT_ASSUMED))
8528 	{
8529 	  gfc_conv_subref_array_arg (se, expr, g77,
8530 				     fsym ? fsym->attr.intent : INTENT_INOUT,
8531 				     false, fsym, proc_name, sym, true);
8532 	  return;
8533 	}
8534 
8535       ptr = build_call_expr_loc (input_location,
8536 			     gfor_fndecl_in_pack, 1, desc);
8537 
8538       if (fsym && fsym->attr.optional && sym && sym->attr.optional)
8539 	{
8540 	  tmp = gfc_conv_expr_present (sym);
8541 	  ptr = build3_loc (input_location, COND_EXPR, TREE_TYPE (se->expr),
8542 			tmp, fold_convert (TREE_TYPE (se->expr), ptr),
8543 			fold_convert (TREE_TYPE (se->expr), null_pointer_node));
8544 	}
8545 
8546       ptr = gfc_evaluate_now (ptr, &se->pre);
8547 
8548       /* Use the packed data for the actual argument, except for contiguous arrays,
8549 	 where the descriptor's data component is set.  */
8550       if (g77)
8551 	se->expr = ptr;
8552       else
8553 	{
8554 	  tmp = build_fold_indirect_ref_loc (input_location, desc);
8555 
8556 	  gfc_ss * ss = gfc_walk_expr (expr);
8557 	  if (!transposed_dims (ss))
8558 	    gfc_conv_descriptor_data_set (&se->pre, tmp, ptr);
8559 	  else
8560 	    {
8561 	      tree old_field, new_field;
8562 
8563 	      /* The original descriptor has transposed dims so we can't reuse
8564 		 it directly; we have to create a new one.  */
8565 	      tree old_desc = tmp;
8566 	      tree new_desc = gfc_create_var (TREE_TYPE (old_desc), "arg_desc");
8567 
8568 	      old_field = gfc_conv_descriptor_dtype (old_desc);
8569 	      new_field = gfc_conv_descriptor_dtype (new_desc);
8570 	      gfc_add_modify (&se->pre, new_field, old_field);
8571 
8572 	      old_field = gfc_conv_descriptor_offset (old_desc);
8573 	      new_field = gfc_conv_descriptor_offset (new_desc);
8574 	      gfc_add_modify (&se->pre, new_field, old_field);
8575 
8576 	      for (int i = 0; i < expr->rank; i++)
8577 		{
8578 		  old_field = gfc_conv_descriptor_dimension (old_desc,
8579 			gfc_rank_cst[get_array_ref_dim_for_loop_dim (ss, i)]);
8580 		  new_field = gfc_conv_descriptor_dimension (new_desc,
8581 			gfc_rank_cst[i]);
8582 		  gfc_add_modify (&se->pre, new_field, old_field);
8583 		}
8584 
8585 	      if (flag_coarray == GFC_FCOARRAY_LIB
8586 		  && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (old_desc))
8587 		  && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (old_desc))
8588 		     == GFC_ARRAY_ALLOCATABLE)
8589 		{
8590 		  old_field = gfc_conv_descriptor_token (old_desc);
8591 		  new_field = gfc_conv_descriptor_token (new_desc);
8592 		  gfc_add_modify (&se->pre, new_field, old_field);
8593 		}
8594 
8595 	      gfc_conv_descriptor_data_set (&se->pre, new_desc, ptr);
8596 	      se->expr = gfc_build_addr_expr (NULL_TREE, new_desc);
8597 	    }
8598 	  gfc_free_ss (ss);
8599 	}
8600 
8601       if (gfc_option.rtcheck & GFC_RTCHECK_ARRAY_TEMPS)
8602 	{
8603 	  char * msg;
8604 
8605 	  if (fsym && proc_name)
8606 	    msg = xasprintf ("An array temporary was created for argument "
8607 			     "'%s' of procedure '%s'", fsym->name, proc_name);
8608 	  else
8609 	    msg = xasprintf ("An array temporary was created");
8610 
8611 	  tmp = build_fold_indirect_ref_loc (input_location,
8612 					 desc);
8613 	  tmp = gfc_conv_array_data (tmp);
8614 	  tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
8615 				 fold_convert (TREE_TYPE (tmp), ptr), tmp);
8616 
8617 	  if (fsym && fsym->attr.optional && sym && sym->attr.optional)
8618 	    tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
8619 				   logical_type_node,
8620 				   gfc_conv_expr_present (sym), tmp);
8621 
8622 	  gfc_trans_runtime_check (false, true, tmp, &se->pre,
8623 				   &expr->where, msg);
8624 	  free (msg);
8625 	}
8626 
8627       gfc_start_block (&block);
8628 
8629       /* Copy the data back.  */
8630       if (fsym == NULL || fsym->attr.intent != INTENT_IN)
8631 	{
8632 	  tmp = build_call_expr_loc (input_location,
8633 				 gfor_fndecl_in_unpack, 2, desc, ptr);
8634 	  gfc_add_expr_to_block (&block, tmp);
8635 	}
8636 
8637       /* Free the temporary.  */
8638       tmp = gfc_call_free (ptr);
8639       gfc_add_expr_to_block (&block, tmp);
8640 
8641       stmt = gfc_finish_block (&block);
8642 
8643       gfc_init_block (&block);
8644       /* Only if it was repacked.  This code needs to be executed before the
8645          loop cleanup code.  */
8646       tmp = build_fold_indirect_ref_loc (input_location,
8647 				     desc);
8648       tmp = gfc_conv_array_data (tmp);
8649       tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
8650 			     fold_convert (TREE_TYPE (tmp), ptr), tmp);
8651 
8652       if (fsym && fsym->attr.optional && sym && sym->attr.optional)
8653 	tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
8654 			       logical_type_node,
8655 			       gfc_conv_expr_present (sym), tmp);
8656 
8657       tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
8658 
8659       gfc_add_expr_to_block (&block, tmp);
8660       gfc_add_block_to_block (&block, &se->post);
8661 
8662       gfc_init_block (&se->post);
8663 
8664       /* Reset the descriptor pointer.  */
8665       if (!g77)
8666         {
8667           tmp = build_fold_indirect_ref_loc (input_location, desc);
8668           gfc_conv_descriptor_data_set (&se->post, tmp, origptr);
8669         }
8670 
8671       gfc_add_block_to_block (&se->post, &block);
8672     }
8673 }
8674 
8675 
8676 /* This helper function calculates the size in words of a full array.  */
8677 
8678 tree
gfc_full_array_size(stmtblock_t * block,tree decl,int rank)8679 gfc_full_array_size (stmtblock_t *block, tree decl, int rank)
8680 {
8681   tree idx;
8682   tree nelems;
8683   tree tmp;
8684   idx = gfc_rank_cst[rank - 1];
8685   nelems = gfc_conv_descriptor_ubound_get (decl, idx);
8686   tmp = gfc_conv_descriptor_lbound_get (decl, idx);
8687   tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
8688 			 nelems, tmp);
8689   tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
8690 			 tmp, gfc_index_one_node);
8691   tmp = gfc_evaluate_now (tmp, block);
8692 
8693   nelems = gfc_conv_descriptor_stride_get (decl, idx);
8694   tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
8695 			 nelems, tmp);
8696   return gfc_evaluate_now (tmp, block);
8697 }
8698 
8699 
8700 /* Allocate dest to the same size as src, and copy src -> dest.
8701    If no_malloc is set, only the copy is done.  */
8702 
8703 static tree
duplicate_allocatable(tree dest,tree src,tree type,int rank,bool no_malloc,bool no_memcpy,tree str_sz,tree add_when_allocated)8704 duplicate_allocatable (tree dest, tree src, tree type, int rank,
8705 		       bool no_malloc, bool no_memcpy, tree str_sz,
8706 		       tree add_when_allocated)
8707 {
8708   tree tmp;
8709   tree size;
8710   tree nelems;
8711   tree null_cond;
8712   tree null_data;
8713   stmtblock_t block;
8714 
8715   /* If the source is null, set the destination to null.  Then,
8716      allocate memory to the destination.  */
8717   gfc_init_block (&block);
8718 
8719   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest)))
8720     {
8721       gfc_add_modify (&block, dest, fold_convert (type, null_pointer_node));
8722       null_data = gfc_finish_block (&block);
8723 
8724       gfc_init_block (&block);
8725       if (str_sz != NULL_TREE)
8726 	size = str_sz;
8727       else
8728 	size = TYPE_SIZE_UNIT (TREE_TYPE (type));
8729 
8730       if (!no_malloc)
8731 	{
8732 	  tmp = gfc_call_malloc (&block, type, size);
8733 	  gfc_add_modify (&block, dest, fold_convert (type, tmp));
8734 	}
8735 
8736       if (!no_memcpy)
8737 	{
8738 	  tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
8739 	  tmp = build_call_expr_loc (input_location, tmp, 3, dest, src,
8740 				     fold_convert (size_type_node, size));
8741 	  gfc_add_expr_to_block (&block, tmp);
8742 	}
8743     }
8744   else
8745     {
8746       gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8747       null_data = gfc_finish_block (&block);
8748 
8749       gfc_init_block (&block);
8750       if (rank)
8751 	nelems = gfc_full_array_size (&block, src, rank);
8752       else
8753 	nelems = gfc_index_one_node;
8754 
8755       if (str_sz != NULL_TREE)
8756 	tmp = fold_convert (gfc_array_index_type, str_sz);
8757       else
8758 	tmp = fold_convert (gfc_array_index_type,
8759 			    TYPE_SIZE_UNIT (gfc_get_element_type (type)));
8760       size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
8761 			      nelems, tmp);
8762       if (!no_malloc)
8763 	{
8764 	  tmp = TREE_TYPE (gfc_conv_descriptor_data_get (src));
8765 	  tmp = gfc_call_malloc (&block, tmp, size);
8766 	  gfc_conv_descriptor_data_set (&block, dest, tmp);
8767 	}
8768 
8769       /* We know the temporary and the value will be the same length,
8770 	 so can use memcpy.  */
8771       if (!no_memcpy)
8772 	{
8773 	  tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
8774 	  tmp = build_call_expr_loc (input_location, tmp, 3,
8775 				     gfc_conv_descriptor_data_get (dest),
8776 				     gfc_conv_descriptor_data_get (src),
8777 				     fold_convert (size_type_node, size));
8778 	  gfc_add_expr_to_block (&block, tmp);
8779 	}
8780     }
8781 
8782   gfc_add_expr_to_block (&block, add_when_allocated);
8783   tmp = gfc_finish_block (&block);
8784 
8785   /* Null the destination if the source is null; otherwise do
8786      the allocate and copy.  */
8787   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (src)))
8788     null_cond = src;
8789   else
8790     null_cond = gfc_conv_descriptor_data_get (src);
8791 
8792   null_cond = convert (pvoid_type_node, null_cond);
8793   null_cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
8794 			       null_cond, null_pointer_node);
8795   return build3_v (COND_EXPR, null_cond, tmp, null_data);
8796 }
8797 
8798 
8799 /* Allocate dest to the same size as src, and copy data src -> dest.  */
8800 
8801 tree
gfc_duplicate_allocatable(tree dest,tree src,tree type,int rank,tree add_when_allocated)8802 gfc_duplicate_allocatable (tree dest, tree src, tree type, int rank,
8803 			   tree add_when_allocated)
8804 {
8805   return duplicate_allocatable (dest, src, type, rank, false, false,
8806 				NULL_TREE, add_when_allocated);
8807 }
8808 
8809 
8810 /* Copy data src -> dest.  */
8811 
8812 tree
gfc_copy_allocatable_data(tree dest,tree src,tree type,int rank)8813 gfc_copy_allocatable_data (tree dest, tree src, tree type, int rank)
8814 {
8815   return duplicate_allocatable (dest, src, type, rank, true, false,
8816 				NULL_TREE, NULL_TREE);
8817 }
8818 
8819 /* Allocate dest to the same size as src, but don't copy anything.  */
8820 
8821 tree
gfc_duplicate_allocatable_nocopy(tree dest,tree src,tree type,int rank)8822 gfc_duplicate_allocatable_nocopy (tree dest, tree src, tree type, int rank)
8823 {
8824   return duplicate_allocatable (dest, src, type, rank, false, true,
8825 				NULL_TREE, NULL_TREE);
8826 }
8827 
8828 
8829 static tree
duplicate_allocatable_coarray(tree dest,tree dest_tok,tree src,tree type,int rank)8830 duplicate_allocatable_coarray (tree dest, tree dest_tok, tree src,
8831 			       tree type, int rank)
8832 {
8833   tree tmp;
8834   tree size;
8835   tree nelems;
8836   tree null_cond;
8837   tree null_data;
8838   stmtblock_t block, globalblock;
8839 
8840   /* If the source is null, set the destination to null.  Then,
8841      allocate memory to the destination.  */
8842   gfc_init_block (&block);
8843   gfc_init_block (&globalblock);
8844 
8845   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest)))
8846     {
8847       gfc_se se;
8848       symbol_attribute attr;
8849       tree dummy_desc;
8850 
8851       gfc_init_se (&se, NULL);
8852       gfc_clear_attr (&attr);
8853       attr.allocatable = 1;
8854       dummy_desc = gfc_conv_scalar_to_descriptor (&se, dest, attr);
8855       gfc_add_block_to_block (&globalblock, &se.pre);
8856       size = TYPE_SIZE_UNIT (TREE_TYPE (type));
8857 
8858       gfc_add_modify (&block, dest, fold_convert (type, null_pointer_node));
8859       gfc_allocate_using_caf_lib (&block, dummy_desc, size,
8860 				  gfc_build_addr_expr (NULL_TREE, dest_tok),
8861 				  NULL_TREE, NULL_TREE, NULL_TREE,
8862 				  GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY);
8863       null_data = gfc_finish_block (&block);
8864 
8865       gfc_init_block (&block);
8866 
8867       gfc_allocate_using_caf_lib (&block, dummy_desc,
8868 				  fold_convert (size_type_node, size),
8869 				  gfc_build_addr_expr (NULL_TREE, dest_tok),
8870 				  NULL_TREE, NULL_TREE, NULL_TREE,
8871 				  GFC_CAF_COARRAY_ALLOC);
8872 
8873       tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
8874       tmp = build_call_expr_loc (input_location, tmp, 3, dest, src,
8875 				 fold_convert (size_type_node, size));
8876       gfc_add_expr_to_block (&block, tmp);
8877     }
8878   else
8879     {
8880       /* Set the rank or unitialized memory access may be reported.  */
8881       tmp = gfc_conv_descriptor_rank (dest);
8882       gfc_add_modify (&globalblock, tmp, build_int_cst (TREE_TYPE (tmp), rank));
8883 
8884       if (rank)
8885 	nelems = gfc_full_array_size (&block, src, rank);
8886       else
8887 	nelems = integer_one_node;
8888 
8889       tmp = fold_convert (size_type_node,
8890 			  TYPE_SIZE_UNIT (gfc_get_element_type (type)));
8891       size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
8892 			      fold_convert (size_type_node, nelems), tmp);
8893 
8894       gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
8895       gfc_allocate_using_caf_lib (&block, dest, fold_convert (size_type_node,
8896 							      size),
8897 				  gfc_build_addr_expr (NULL_TREE, dest_tok),
8898 				  NULL_TREE, NULL_TREE, NULL_TREE,
8899 				  GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY);
8900       null_data = gfc_finish_block (&block);
8901 
8902       gfc_init_block (&block);
8903       gfc_allocate_using_caf_lib (&block, dest,
8904 				  fold_convert (size_type_node, size),
8905 				  gfc_build_addr_expr (NULL_TREE, dest_tok),
8906 				  NULL_TREE, NULL_TREE, NULL_TREE,
8907 				  GFC_CAF_COARRAY_ALLOC);
8908 
8909       tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
8910       tmp = build_call_expr_loc (input_location, tmp, 3,
8911 				 gfc_conv_descriptor_data_get (dest),
8912 				 gfc_conv_descriptor_data_get (src),
8913 				 fold_convert (size_type_node, size));
8914       gfc_add_expr_to_block (&block, tmp);
8915     }
8916 
8917   tmp = gfc_finish_block (&block);
8918 
8919   /* Null the destination if the source is null; otherwise do
8920      the register and copy.  */
8921   if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (src)))
8922     null_cond = src;
8923   else
8924     null_cond = gfc_conv_descriptor_data_get (src);
8925 
8926   null_cond = convert (pvoid_type_node, null_cond);
8927   null_cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
8928 			       null_cond, null_pointer_node);
8929   gfc_add_expr_to_block (&globalblock, build3_v (COND_EXPR, null_cond, tmp,
8930 						 null_data));
8931   return gfc_finish_block (&globalblock);
8932 }
8933 
8934 
8935 /* Helper function to abstract whether coarray processing is enabled.  */
8936 
8937 static bool
caf_enabled(int caf_mode)8938 caf_enabled (int caf_mode)
8939 {
8940   return (caf_mode & GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY)
8941       == GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY;
8942 }
8943 
8944 
8945 /* Helper function to abstract whether coarray processing is enabled
8946    and we are in a derived type coarray.  */
8947 
8948 static bool
caf_in_coarray(int caf_mode)8949 caf_in_coarray (int caf_mode)
8950 {
8951   static const int pat = GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
8952 			 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY;
8953   return (caf_mode & pat) == pat;
8954 }
8955 
8956 
8957 /* Helper function to abstract whether coarray is to deallocate only.  */
8958 
8959 bool
gfc_caf_is_dealloc_only(int caf_mode)8960 gfc_caf_is_dealloc_only (int caf_mode)
8961 {
8962   return (caf_mode & GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY)
8963       == GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY;
8964 }
8965 
8966 
8967 /* Recursively traverse an object of derived type, generating code to
8968    deallocate, nullify or copy allocatable components.  This is the work horse
8969    function for the functions named in this enum.  */
8970 
8971 enum {DEALLOCATE_ALLOC_COMP = 1, NULLIFY_ALLOC_COMP,
8972       COPY_ALLOC_COMP, COPY_ONLY_ALLOC_COMP, REASSIGN_CAF_COMP,
8973       ALLOCATE_PDT_COMP, DEALLOCATE_PDT_COMP, CHECK_PDT_DUMMY,
8974       BCAST_ALLOC_COMP};
8975 
8976 static gfc_actual_arglist *pdt_param_list;
8977 
8978 static tree
structure_alloc_comps(gfc_symbol * der_type,tree decl,tree dest,int rank,int purpose,int caf_mode,gfc_co_subroutines_args * args)8979 structure_alloc_comps (gfc_symbol * der_type, tree decl,
8980 		       tree dest, int rank, int purpose, int caf_mode,
8981 		       gfc_co_subroutines_args *args)
8982 {
8983   gfc_component *c;
8984   gfc_loopinfo loop;
8985   stmtblock_t fnblock;
8986   stmtblock_t loopbody;
8987   stmtblock_t tmpblock;
8988   tree decl_type;
8989   tree tmp;
8990   tree comp;
8991   tree dcmp;
8992   tree nelems;
8993   tree index;
8994   tree var;
8995   tree cdecl;
8996   tree ctype;
8997   tree vref, dref;
8998   tree null_cond = NULL_TREE;
8999   tree add_when_allocated;
9000   tree dealloc_fndecl;
9001   tree caf_token;
9002   gfc_symbol *vtab;
9003   int caf_dereg_mode;
9004   symbol_attribute *attr;
9005   bool deallocate_called;
9006 
9007   gfc_init_block (&fnblock);
9008 
9009   decl_type = TREE_TYPE (decl);
9010 
9011   if ((POINTER_TYPE_P (decl_type))
9012 	|| (TREE_CODE (decl_type) == REFERENCE_TYPE && rank == 0))
9013     {
9014       decl = build_fold_indirect_ref_loc (input_location, decl);
9015       /* Deref dest in sync with decl, but only when it is not NULL.  */
9016       if (dest)
9017 	dest = build_fold_indirect_ref_loc (input_location, dest);
9018 
9019       /* Update the decl_type because it got dereferenced.  */
9020       decl_type = TREE_TYPE (decl);
9021     }
9022 
9023   /* If this is an array of derived types with allocatable components
9024      build a loop and recursively call this function.  */
9025   if (TREE_CODE (decl_type) == ARRAY_TYPE
9026       || (GFC_DESCRIPTOR_TYPE_P (decl_type) && rank != 0))
9027     {
9028       tmp = gfc_conv_array_data (decl);
9029       var = build_fold_indirect_ref_loc (input_location, tmp);
9030 
9031       /* Get the number of elements - 1 and set the counter.  */
9032       if (GFC_DESCRIPTOR_TYPE_P (decl_type))
9033 	{
9034 	  /* Use the descriptor for an allocatable array.  Since this
9035 	     is a full array reference, we only need the descriptor
9036 	     information from dimension = rank.  */
9037 	  tmp = gfc_full_array_size (&fnblock, decl, rank);
9038 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
9039 				 gfc_array_index_type, tmp,
9040 				 gfc_index_one_node);
9041 
9042 	  null_cond = gfc_conv_descriptor_data_get (decl);
9043 	  null_cond = fold_build2_loc (input_location, NE_EXPR,
9044 				       logical_type_node, null_cond,
9045 				       build_int_cst (TREE_TYPE (null_cond), 0));
9046 	}
9047       else
9048 	{
9049 	  /*  Otherwise use the TYPE_DOMAIN information.  */
9050 	  tmp = array_type_nelts (decl_type);
9051 	  tmp = fold_convert (gfc_array_index_type, tmp);
9052 	}
9053 
9054       /* Remember that this is, in fact, the no. of elements - 1.  */
9055       nelems = gfc_evaluate_now (tmp, &fnblock);
9056       index = gfc_create_var (gfc_array_index_type, "S");
9057 
9058       /* Build the body of the loop.  */
9059       gfc_init_block (&loopbody);
9060 
9061       vref = gfc_build_array_ref (var, index, NULL);
9062 
9063       if (purpose == COPY_ALLOC_COMP || purpose == COPY_ONLY_ALLOC_COMP)
9064 	{
9065 	  tmp = build_fold_indirect_ref_loc (input_location,
9066 					     gfc_conv_array_data (dest));
9067 	  dref = gfc_build_array_ref (tmp, index, NULL);
9068 	  tmp = structure_alloc_comps (der_type, vref, dref, rank,
9069 				       COPY_ALLOC_COMP, caf_mode, args);
9070 	}
9071       else
9072 	tmp = structure_alloc_comps (der_type, vref, NULL_TREE, rank, purpose,
9073 				     caf_mode, args);
9074 
9075       gfc_add_expr_to_block (&loopbody, tmp);
9076 
9077       /* Build the loop and return.  */
9078       gfc_init_loopinfo (&loop);
9079       loop.dimen = 1;
9080       loop.from[0] = gfc_index_zero_node;
9081       loop.loopvar[0] = index;
9082       loop.to[0] = nelems;
9083       gfc_trans_scalarizing_loops (&loop, &loopbody);
9084       gfc_add_block_to_block (&fnblock, &loop.pre);
9085 
9086       tmp = gfc_finish_block (&fnblock);
9087       /* When copying allocateable components, the above implements the
9088 	 deep copy.  Nevertheless is a deep copy only allowed, when the current
9089 	 component is allocated, for which code will be generated in
9090 	 gfc_duplicate_allocatable (), where the deep copy code is just added
9091 	 into the if's body, by adding tmp (the deep copy code) as last
9092 	 argument to gfc_duplicate_allocatable ().  */
9093       if (purpose == COPY_ALLOC_COMP
9094 	  && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (dest)))
9095 	tmp = gfc_duplicate_allocatable (dest, decl, decl_type, rank,
9096 					 tmp);
9097       else if (null_cond != NULL_TREE)
9098 	tmp = build3_v (COND_EXPR, null_cond, tmp,
9099 			build_empty_stmt (input_location));
9100 
9101       return tmp;
9102     }
9103 
9104   if (purpose == DEALLOCATE_ALLOC_COMP && der_type->attr.pdt_type)
9105     {
9106       tmp = structure_alloc_comps (der_type, decl, NULL_TREE, rank,
9107 				   DEALLOCATE_PDT_COMP, 0, args);
9108       gfc_add_expr_to_block (&fnblock, tmp);
9109     }
9110   else if (purpose == ALLOCATE_PDT_COMP && der_type->attr.alloc_comp)
9111     {
9112       tmp = structure_alloc_comps (der_type, decl, NULL_TREE, rank,
9113 				   NULLIFY_ALLOC_COMP, 0, args);
9114       gfc_add_expr_to_block (&fnblock, tmp);
9115     }
9116 
9117   /* Otherwise, act on the components or recursively call self to
9118      act on a chain of components.  */
9119   for (c = der_type->components; c; c = c->next)
9120     {
9121       bool cmp_has_alloc_comps = (c->ts.type == BT_DERIVED
9122 				  || c->ts.type == BT_CLASS)
9123 				    && c->ts.u.derived->attr.alloc_comp;
9124       bool same_type = (c->ts.type == BT_DERIVED && der_type == c->ts.u.derived)
9125 	|| (c->ts.type == BT_CLASS && der_type == CLASS_DATA (c)->ts.u.derived);
9126 
9127       bool is_pdt_type = c->ts.type == BT_DERIVED
9128 			 && c->ts.u.derived->attr.pdt_type;
9129 
9130       cdecl = c->backend_decl;
9131       ctype = TREE_TYPE (cdecl);
9132 
9133       switch (purpose)
9134 	{
9135 
9136 	case BCAST_ALLOC_COMP:
9137 
9138 	  tree ubound;
9139 	  tree cdesc;
9140 	  stmtblock_t derived_type_block;
9141 
9142 	  gfc_init_block (&tmpblock);
9143 
9144 	  comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9145 				  decl, cdecl, NULL_TREE);
9146 
9147 	  /* Shortcut to get the attributes of the component.  */
9148 	  if (c->ts.type == BT_CLASS)
9149 	    {
9150 	      attr = &CLASS_DATA (c)->attr;
9151 	      if (attr->class_pointer)
9152 		continue;
9153 	    }
9154 	  else
9155 	    {
9156 	      attr = &c->attr;
9157 	      if (attr->pointer)
9158 		continue;
9159 	    }
9160 
9161 	  /* Do not broadcast a caf_token.  These are local to the image.  */
9162 	  if (attr->caf_token)
9163 	    continue;
9164 
9165 	  add_when_allocated = NULL_TREE;
9166 	  if (cmp_has_alloc_comps
9167 	      && !c->attr.pointer && !c->attr.proc_pointer)
9168 	    {
9169 	      if (c->ts.type == BT_CLASS)
9170 		{
9171 		  rank = CLASS_DATA (c)->as ? CLASS_DATA (c)->as->rank : 0;
9172 		  add_when_allocated
9173 		      = structure_alloc_comps (CLASS_DATA (c)->ts.u.derived,
9174 					       comp, NULL_TREE, rank, purpose,
9175 					       caf_mode, args);
9176 		}
9177 	      else
9178 		{
9179 		  rank = c->as ? c->as->rank : 0;
9180 		  add_when_allocated = structure_alloc_comps (c->ts.u.derived,
9181 							      comp, NULL_TREE,
9182 							      rank, purpose,
9183 							      caf_mode, args);
9184 		}
9185 	    }
9186 
9187 	  gfc_init_block (&derived_type_block);
9188 	  if (add_when_allocated)
9189 	    gfc_add_expr_to_block (&derived_type_block, add_when_allocated);
9190 	  tmp = gfc_finish_block (&derived_type_block);
9191 	  gfc_add_expr_to_block (&tmpblock, tmp);
9192 
9193 	  /* Convert the component into a rank 1 descriptor type.  */
9194 	  if (attr->dimension)
9195 	    {
9196 	      tmp = gfc_get_element_type (TREE_TYPE (comp));
9197 	      if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)))
9198 		ubound = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (comp));
9199 	      else
9200 		ubound = gfc_full_array_size (&tmpblock, comp,
9201 					      c->ts.type == BT_CLASS
9202 					      ? CLASS_DATA (c)->as->rank
9203 					      : c->as->rank);
9204 	    }
9205 	  else
9206 	    {
9207 	      tmp = TREE_TYPE (comp);
9208 	      ubound = build_int_cst (gfc_array_index_type, 1);
9209 	    }
9210 
9211 	  /* Treat strings like arrays.  Or the other way around, do not
9212 	   * generate an additional array layer for scalar components.  */
9213 	  if (attr->dimension || c->ts.type == BT_CHARACTER)
9214 	    {
9215 	      cdesc = gfc_get_array_type_bounds (tmp, 1, 0, &gfc_index_one_node,
9216 						 &ubound, 1,
9217 						 GFC_ARRAY_ALLOCATABLE, false);
9218 
9219 	      cdesc = gfc_create_var (cdesc, "cdesc");
9220 	      DECL_ARTIFICIAL (cdesc) = 1;
9221 
9222 	      gfc_add_modify (&tmpblock, gfc_conv_descriptor_dtype (cdesc),
9223 			      gfc_get_dtype_rank_type (1, tmp));
9224 	      gfc_conv_descriptor_lbound_set (&tmpblock, cdesc,
9225 					      gfc_index_zero_node,
9226 					      gfc_index_one_node);
9227 	      gfc_conv_descriptor_stride_set (&tmpblock, cdesc,
9228 					      gfc_index_zero_node,
9229 					      gfc_index_one_node);
9230 	      gfc_conv_descriptor_ubound_set (&tmpblock, cdesc,
9231 					      gfc_index_zero_node, ubound);
9232 	    }
9233 	  else
9234 	    /* Prevent warning.  */
9235 	    cdesc = NULL_TREE;
9236 
9237 	  if (attr->dimension)
9238 	    {
9239 	      if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)))
9240 		comp = gfc_conv_descriptor_data_get (comp);
9241 	      else
9242 		comp = gfc_build_addr_expr (NULL_TREE, comp);
9243 	    }
9244 	  else
9245 	    {
9246 	      gfc_se se;
9247 
9248 	      gfc_init_se (&se, NULL);
9249 
9250 	      comp = gfc_conv_scalar_to_descriptor (&se, comp,
9251 						     c->ts.type == BT_CLASS
9252 						     ? CLASS_DATA (c)->attr
9253 						     : c->attr);
9254 	      if (c->ts.type == BT_CHARACTER)
9255 		comp = gfc_build_addr_expr (NULL_TREE, comp);
9256 	      gfc_add_block_to_block (&tmpblock, &se.pre);
9257 	    }
9258 
9259 	  if (attr->dimension || c->ts.type == BT_CHARACTER)
9260 	    gfc_conv_descriptor_data_set (&tmpblock, cdesc, comp);
9261 	  else
9262 	    cdesc = comp;
9263 
9264 	  tree fndecl;
9265 
9266 	  fndecl = build_call_expr_loc (input_location,
9267 					gfor_fndecl_co_broadcast, 5,
9268 					gfc_build_addr_expr (pvoid_type_node,cdesc),
9269 					args->image_index,
9270 					null_pointer_node, null_pointer_node,
9271 					null_pointer_node);
9272 
9273 	  gfc_add_expr_to_block (&tmpblock, fndecl);
9274 	  gfc_add_block_to_block (&fnblock, &tmpblock);
9275 
9276 	  break;
9277 
9278 	case DEALLOCATE_ALLOC_COMP:
9279 
9280 	  gfc_init_block (&tmpblock);
9281 
9282 	  comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9283 				  decl, cdecl, NULL_TREE);
9284 
9285 	  /* Shortcut to get the attributes of the component.  */
9286 	  if (c->ts.type == BT_CLASS)
9287 	    {
9288 	      attr = &CLASS_DATA (c)->attr;
9289 	      if (attr->class_pointer)
9290 		continue;
9291 	    }
9292 	  else
9293 	    {
9294 	      attr = &c->attr;
9295 	      if (attr->pointer)
9296 		continue;
9297 	    }
9298 
9299 	  if ((c->ts.type == BT_DERIVED && !c->attr.pointer)
9300 	     || (c->ts.type == BT_CLASS && !CLASS_DATA (c)->attr.class_pointer))
9301 	    /* Call the finalizer, which will free the memory and nullify the
9302 	       pointer of an array.  */
9303 	    deallocate_called = gfc_add_comp_finalizer_call (&tmpblock, comp, c,
9304 							 caf_enabled (caf_mode))
9305 		&& attr->dimension;
9306 	  else
9307 	    deallocate_called = false;
9308 
9309 	  /* Add the _class ref for classes.  */
9310 	  if (c->ts.type == BT_CLASS && attr->allocatable)
9311 	    comp = gfc_class_data_get (comp);
9312 
9313 	  add_when_allocated = NULL_TREE;
9314 	  if (cmp_has_alloc_comps
9315 	      && !c->attr.pointer && !c->attr.proc_pointer
9316 	      && !same_type
9317 	      && !deallocate_called)
9318 	    {
9319 	      /* Add checked deallocation of the components.  This code is
9320 		 obviously added because the finalizer is not trusted to free
9321 		 all memory.  */
9322 	      if (c->ts.type == BT_CLASS)
9323 		{
9324 		  rank = CLASS_DATA (c)->as ? CLASS_DATA (c)->as->rank : 0;
9325 		  add_when_allocated
9326 		      = structure_alloc_comps (CLASS_DATA (c)->ts.u.derived,
9327 					       comp, NULL_TREE, rank, purpose,
9328 					       caf_mode, args);
9329 		}
9330 	      else
9331 		{
9332 		  rank = c->as ? c->as->rank : 0;
9333 		  add_when_allocated = structure_alloc_comps (c->ts.u.derived,
9334 							      comp, NULL_TREE,
9335 							      rank, purpose,
9336 							      caf_mode, args);
9337 		}
9338 	    }
9339 
9340 	  if (attr->allocatable && !same_type
9341 	      && (!attr->codimension || caf_enabled (caf_mode)))
9342 	    {
9343 	      /* Handle all types of components besides components of the
9344 		 same_type as the current one, because those would create an
9345 		 endless loop.  */
9346 	      caf_dereg_mode
9347 		  = (caf_in_coarray (caf_mode) || attr->codimension)
9348 		  ? (gfc_caf_is_dealloc_only (caf_mode)
9349 		     ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
9350 		     : GFC_CAF_COARRAY_DEREGISTER)
9351 		  : GFC_CAF_COARRAY_NOCOARRAY;
9352 
9353 	      caf_token = NULL_TREE;
9354 	      /* Coarray components are handled directly by
9355 		 deallocate_with_status.  */
9356 	      if (!attr->codimension
9357 		  && caf_dereg_mode != GFC_CAF_COARRAY_NOCOARRAY)
9358 		{
9359 		  if (c->caf_token)
9360 		    caf_token = fold_build3_loc (input_location, COMPONENT_REF,
9361 						 TREE_TYPE (c->caf_token),
9362 						 decl, c->caf_token, NULL_TREE);
9363 		  else if (attr->dimension && !attr->proc_pointer)
9364 		    caf_token = gfc_conv_descriptor_token (comp);
9365 		}
9366 	      if (attr->dimension && !attr->codimension && !attr->proc_pointer)
9367 		/* When this is an array but not in conjunction with a coarray
9368 		   then add the data-ref.  For coarray'ed arrays the data-ref
9369 		   is added by deallocate_with_status.  */
9370 		comp = gfc_conv_descriptor_data_get (comp);
9371 
9372 	      tmp = gfc_deallocate_with_status (comp, NULL_TREE, NULL_TREE,
9373 						NULL_TREE, NULL_TREE, true,
9374 						NULL, caf_dereg_mode,
9375 						add_when_allocated, caf_token);
9376 
9377 	      gfc_add_expr_to_block (&tmpblock, tmp);
9378 	    }
9379 	  else if (attr->allocatable && !attr->codimension
9380 		   && !deallocate_called)
9381 	    {
9382 	      /* Case of recursive allocatable derived types.  */
9383 	      tree is_allocated;
9384 	      tree ubound;
9385 	      tree cdesc;
9386 	      stmtblock_t dealloc_block;
9387 
9388 	      gfc_init_block (&dealloc_block);
9389 	      if (add_when_allocated)
9390 		gfc_add_expr_to_block (&dealloc_block, add_when_allocated);
9391 
9392 	      /* Convert the component into a rank 1 descriptor type.  */
9393 	      if (attr->dimension)
9394 		{
9395 		  tmp = gfc_get_element_type (TREE_TYPE (comp));
9396 		  ubound = gfc_full_array_size (&dealloc_block, comp,
9397 						c->ts.type == BT_CLASS
9398 						? CLASS_DATA (c)->as->rank
9399 						: c->as->rank);
9400 		}
9401 	      else
9402 		{
9403 		  tmp = TREE_TYPE (comp);
9404 		  ubound = build_int_cst (gfc_array_index_type, 1);
9405 		}
9406 
9407 	      cdesc = gfc_get_array_type_bounds (tmp, 1, 0, &gfc_index_one_node,
9408 						 &ubound, 1,
9409 						 GFC_ARRAY_ALLOCATABLE, false);
9410 
9411 	      cdesc = gfc_create_var (cdesc, "cdesc");
9412 	      DECL_ARTIFICIAL (cdesc) = 1;
9413 
9414 	      gfc_add_modify (&dealloc_block, gfc_conv_descriptor_dtype (cdesc),
9415 			      gfc_get_dtype_rank_type (1, tmp));
9416 	      gfc_conv_descriptor_lbound_set (&dealloc_block, cdesc,
9417 					      gfc_index_zero_node,
9418 					      gfc_index_one_node);
9419 	      gfc_conv_descriptor_stride_set (&dealloc_block, cdesc,
9420 					      gfc_index_zero_node,
9421 					      gfc_index_one_node);
9422 	      gfc_conv_descriptor_ubound_set (&dealloc_block, cdesc,
9423 					      gfc_index_zero_node, ubound);
9424 
9425 	      if (attr->dimension)
9426 		comp = gfc_conv_descriptor_data_get (comp);
9427 
9428 	      gfc_conv_descriptor_data_set (&dealloc_block, cdesc, comp);
9429 
9430 	      /* Now call the deallocator.  */
9431 	      vtab = gfc_find_vtab (&c->ts);
9432 	      if (vtab->backend_decl == NULL)
9433 		gfc_get_symbol_decl (vtab);
9434 	      tmp = gfc_build_addr_expr (NULL_TREE, vtab->backend_decl);
9435 	      dealloc_fndecl = gfc_vptr_deallocate_get (tmp);
9436 	      dealloc_fndecl = build_fold_indirect_ref_loc (input_location,
9437 							    dealloc_fndecl);
9438 	      tmp = build_int_cst (TREE_TYPE (comp), 0);
9439 	      is_allocated = fold_build2_loc (input_location, NE_EXPR,
9440 					      logical_type_node, tmp,
9441 					      comp);
9442 	      cdesc = gfc_build_addr_expr (NULL_TREE, cdesc);
9443 
9444 	      tmp = build_call_expr_loc (input_location,
9445 					 dealloc_fndecl, 1,
9446 					 cdesc);
9447 	      gfc_add_expr_to_block (&dealloc_block, tmp);
9448 
9449 	      tmp = gfc_finish_block (&dealloc_block);
9450 
9451 	      tmp = fold_build3_loc (input_location, COND_EXPR,
9452 				     void_type_node, is_allocated, tmp,
9453 				     build_empty_stmt (input_location));
9454 
9455 	      gfc_add_expr_to_block (&tmpblock, tmp);
9456 	    }
9457 	  else if (add_when_allocated)
9458 	    gfc_add_expr_to_block (&tmpblock, add_when_allocated);
9459 
9460 	  if (c->ts.type == BT_CLASS && attr->allocatable
9461 	      && (!attr->codimension || !caf_enabled (caf_mode)))
9462 	    {
9463 	      /* Finally, reset the vptr to the declared type vtable and, if
9464 		 necessary reset the _len field.
9465 
9466 		 First recover the reference to the component and obtain
9467 		 the vptr.  */
9468 	      comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9469 				      decl, cdecl, NULL_TREE);
9470 	      tmp = gfc_class_vptr_get (comp);
9471 
9472 	      if (UNLIMITED_POLY (c))
9473 		{
9474 		  /* Both vptr and _len field should be nulled.  */
9475 		  gfc_add_modify (&tmpblock, tmp,
9476 				  build_int_cst (TREE_TYPE (tmp), 0));
9477 		  tmp = gfc_class_len_get (comp);
9478 		  gfc_add_modify (&tmpblock, tmp,
9479 				  build_int_cst (TREE_TYPE (tmp), 0));
9480 		}
9481 	      else
9482 		{
9483 		  /* Build the vtable address and set the vptr with it.  */
9484 		  tree vtab;
9485 		  gfc_symbol *vtable;
9486 		  vtable = gfc_find_derived_vtab (c->ts.u.derived);
9487 		  vtab = vtable->backend_decl;
9488 		  if (vtab == NULL_TREE)
9489 		    vtab = gfc_get_symbol_decl (vtable);
9490 		  vtab = gfc_build_addr_expr (NULL, vtab);
9491 		  vtab = fold_convert (TREE_TYPE (tmp), vtab);
9492 		  gfc_add_modify (&tmpblock, tmp, vtab);
9493 		}
9494 	    }
9495 
9496 	  /* Now add the deallocation of this component.  */
9497 	  gfc_add_block_to_block (&fnblock, &tmpblock);
9498 	  break;
9499 
9500 	case NULLIFY_ALLOC_COMP:
9501 	  /* Nullify
9502 	     - allocatable components (regular or in class)
9503 	     - components that have allocatable components
9504 	     - pointer components when in a coarray.
9505 	     Skip everything else especially proc_pointers, which may come
9506 	     coupled with the regular pointer attribute.  */
9507 	  if (c->attr.proc_pointer
9508 	      || !(c->attr.allocatable || (c->ts.type == BT_CLASS
9509 					   && CLASS_DATA (c)->attr.allocatable)
9510 		   || (cmp_has_alloc_comps
9511 		       && ((c->ts.type == BT_DERIVED && !c->attr.pointer)
9512 			   || (c->ts.type == BT_CLASS
9513 			       && !CLASS_DATA (c)->attr.class_pointer)))
9514 		   || (caf_in_coarray (caf_mode) && c->attr.pointer)))
9515 	    continue;
9516 
9517 	  /* Process class components first, because they always have the
9518 	     pointer-attribute set which would be caught wrong else.  */
9519 	  if (c->ts.type == BT_CLASS
9520 	      && (CLASS_DATA (c)->attr.allocatable
9521 		  || CLASS_DATA (c)->attr.class_pointer))
9522 	    {
9523 	      tree vptr_decl;
9524 
9525 	      /* Allocatable CLASS components.  */
9526 	      comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9527 				      decl, cdecl, NULL_TREE);
9528 
9529 	      vptr_decl = gfc_class_vptr_get (comp);
9530 
9531 	      comp = gfc_class_data_get (comp);
9532 	      if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)))
9533 		gfc_conv_descriptor_data_set (&fnblock, comp,
9534 					      null_pointer_node);
9535 	      else
9536 		{
9537 		  tmp = fold_build2_loc (input_location, MODIFY_EXPR,
9538 					 void_type_node, comp,
9539 					 build_int_cst (TREE_TYPE (comp), 0));
9540 		  gfc_add_expr_to_block (&fnblock, tmp);
9541 		}
9542 
9543 	      /* The dynamic type of a disassociated pointer or unallocated
9544 		 allocatable variable is its declared type. An unlimited
9545 		 polymorphic entity has no declared type.  */
9546 	      if (!UNLIMITED_POLY (c))
9547 		{
9548 		  vtab = gfc_find_derived_vtab (c->ts.u.derived);
9549 		  if (!vtab->backend_decl)
9550 		     gfc_get_symbol_decl (vtab);
9551 		  tmp = gfc_build_addr_expr (NULL_TREE, vtab->backend_decl);
9552 		}
9553 	      else
9554 		tmp = build_int_cst (TREE_TYPE (vptr_decl), 0);
9555 
9556 	      tmp = fold_build2_loc (input_location, MODIFY_EXPR,
9557 					 void_type_node, vptr_decl, tmp);
9558 	      gfc_add_expr_to_block (&fnblock, tmp);
9559 
9560 	      cmp_has_alloc_comps = false;
9561 	    }
9562 	  /* Coarrays need the component to be nulled before the api-call
9563 	     is made.  */
9564 	  else if (c->attr.pointer || c->attr.allocatable)
9565 	    {
9566 	      comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9567 				      decl, cdecl, NULL_TREE);
9568 	      if (c->attr.dimension || c->attr.codimension)
9569 		gfc_conv_descriptor_data_set (&fnblock, comp,
9570 					      null_pointer_node);
9571 	      else
9572 		gfc_add_modify (&fnblock, comp,
9573 				build_int_cst (TREE_TYPE (comp), 0));
9574 	      if (gfc_deferred_strlen (c, &comp))
9575 		{
9576 		  comp = fold_build3_loc (input_location, COMPONENT_REF,
9577 					  TREE_TYPE (comp),
9578 					  decl, comp, NULL_TREE);
9579 		  tmp = fold_build2_loc (input_location, MODIFY_EXPR,
9580 					 TREE_TYPE (comp), comp,
9581 					 build_int_cst (TREE_TYPE (comp), 0));
9582 		  gfc_add_expr_to_block (&fnblock, tmp);
9583 		}
9584 	      cmp_has_alloc_comps = false;
9585 	    }
9586 
9587 	  if (flag_coarray == GFC_FCOARRAY_LIB && caf_in_coarray (caf_mode))
9588 	    {
9589 	      /* Register a component of a derived type coarray with the
9590 		 coarray library.  Do not register ultimate component
9591 		 coarrays here.  They are treated like regular coarrays and
9592 		 are either allocated on all images or on none.  */
9593 	      tree token;
9594 
9595 	      comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9596 				      decl, cdecl, NULL_TREE);
9597 	      if (c->attr.dimension)
9598 		{
9599 		  /* Set the dtype, because caf_register needs it.  */
9600 		  gfc_add_modify (&fnblock, gfc_conv_descriptor_dtype (comp),
9601 				  gfc_get_dtype (TREE_TYPE (comp)));
9602 		  tmp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9603 					 decl, cdecl, NULL_TREE);
9604 		  token = gfc_conv_descriptor_token (tmp);
9605 		}
9606 	      else
9607 		{
9608 		  gfc_se se;
9609 
9610 		  gfc_init_se (&se, NULL);
9611 		  token = fold_build3_loc (input_location, COMPONENT_REF,
9612 					   pvoid_type_node, decl, c->caf_token,
9613 					   NULL_TREE);
9614 		  comp = gfc_conv_scalar_to_descriptor (&se, comp,
9615 							c->ts.type == BT_CLASS
9616 							? CLASS_DATA (c)->attr
9617 							: c->attr);
9618 		  gfc_add_block_to_block (&fnblock, &se.pre);
9619 		}
9620 
9621 	      gfc_allocate_using_caf_lib (&fnblock, comp, size_zero_node,
9622 					  gfc_build_addr_expr (NULL_TREE,
9623 							       token),
9624 					  NULL_TREE, NULL_TREE, NULL_TREE,
9625 					  GFC_CAF_COARRAY_ALLOC_REGISTER_ONLY);
9626 	    }
9627 
9628 	  if (cmp_has_alloc_comps)
9629 	    {
9630 	      comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9631 				      decl, cdecl, NULL_TREE);
9632 	      rank = c->as ? c->as->rank : 0;
9633 	      tmp = structure_alloc_comps (c->ts.u.derived, comp, NULL_TREE,
9634 					   rank, purpose, caf_mode, args);
9635 	      gfc_add_expr_to_block (&fnblock, tmp);
9636 	    }
9637 	  break;
9638 
9639 	case REASSIGN_CAF_COMP:
9640 	  if (caf_enabled (caf_mode)
9641 	      && (c->attr.codimension
9642 		  || (c->ts.type == BT_CLASS
9643 		      && (CLASS_DATA (c)->attr.coarray_comp
9644 			  || caf_in_coarray (caf_mode)))
9645 		  || (c->ts.type == BT_DERIVED
9646 		      && (c->ts.u.derived->attr.coarray_comp
9647 			  || caf_in_coarray (caf_mode))))
9648 	      && !same_type)
9649 	    {
9650 	      comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9651 				      decl, cdecl, NULL_TREE);
9652 	      dcmp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9653 				      dest, cdecl, NULL_TREE);
9654 
9655 	      if (c->attr.codimension)
9656 		{
9657 		  if (c->ts.type == BT_CLASS)
9658 		    {
9659 		      comp = gfc_class_data_get (comp);
9660 		      dcmp = gfc_class_data_get (dcmp);
9661 		    }
9662 		  gfc_conv_descriptor_data_set (&fnblock, dcmp,
9663 					   gfc_conv_descriptor_data_get (comp));
9664 		}
9665 	      else
9666 		{
9667 		  tmp = structure_alloc_comps (c->ts.u.derived, comp, dcmp,
9668 					       rank, purpose, caf_mode
9669 					       | GFC_STRUCTURE_CAF_MODE_IN_COARRAY,
9670 					       args);
9671 		  gfc_add_expr_to_block (&fnblock, tmp);
9672 		}
9673 	    }
9674 	  break;
9675 
9676 	case COPY_ALLOC_COMP:
9677 	  if (c->attr.pointer || c->attr.proc_pointer)
9678 	    continue;
9679 
9680 	  /* We need source and destination components.  */
9681 	  comp = fold_build3_loc (input_location, COMPONENT_REF, ctype, decl,
9682 				  cdecl, NULL_TREE);
9683 	  dcmp = fold_build3_loc (input_location, COMPONENT_REF, ctype, dest,
9684 				  cdecl, NULL_TREE);
9685 	  dcmp = fold_convert (TREE_TYPE (comp), dcmp);
9686 
9687 	  if (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.allocatable)
9688 	    {
9689 	      tree ftn_tree;
9690 	      tree size;
9691 	      tree dst_data;
9692 	      tree src_data;
9693 	      tree null_data;
9694 
9695 	      dst_data = gfc_class_data_get (dcmp);
9696 	      src_data = gfc_class_data_get (comp);
9697 	      size = fold_convert (size_type_node,
9698 				   gfc_class_vtab_size_get (comp));
9699 
9700 	      if (CLASS_DATA (c)->attr.dimension)
9701 		{
9702 		  nelems = gfc_conv_descriptor_size (src_data,
9703 						     CLASS_DATA (c)->as->rank);
9704 		  size = fold_build2_loc (input_location, MULT_EXPR,
9705 					  size_type_node, size,
9706 					  fold_convert (size_type_node,
9707 							nelems));
9708 		}
9709 	      else
9710 		nelems = build_int_cst (size_type_node, 1);
9711 
9712 	      if (CLASS_DATA (c)->attr.dimension
9713 		  || CLASS_DATA (c)->attr.codimension)
9714 		{
9715 		  src_data = gfc_conv_descriptor_data_get (src_data);
9716 		  dst_data = gfc_conv_descriptor_data_get (dst_data);
9717 		}
9718 
9719 	      gfc_init_block (&tmpblock);
9720 
9721 	      gfc_add_modify (&tmpblock, gfc_class_vptr_get (dcmp),
9722 			      gfc_class_vptr_get (comp));
9723 
9724 	      /* Copy the unlimited '_len' field. If it is greater than zero
9725 		 (ie. a character(_len)), multiply it by size and use this
9726 		 for the malloc call.  */
9727 	      if (UNLIMITED_POLY (c))
9728 		{
9729 		  gfc_add_modify (&tmpblock, gfc_class_len_get (dcmp),
9730 				  gfc_class_len_get (comp));
9731 		  size = gfc_resize_class_size_with_len (&tmpblock, comp, size);
9732 		}
9733 
9734 	      /* Coarray component have to have the same allocation status and
9735 		 shape/type-parameter/effective-type on the LHS and RHS of an
9736 		 intrinsic assignment. Hence, we did not deallocated them - and
9737 		 do not allocate them here.  */
9738 	      if (!CLASS_DATA (c)->attr.codimension)
9739 		{
9740 		  ftn_tree = builtin_decl_explicit (BUILT_IN_MALLOC);
9741 		  tmp = build_call_expr_loc (input_location, ftn_tree, 1, size);
9742 		  gfc_add_modify (&tmpblock, dst_data,
9743 				  fold_convert (TREE_TYPE (dst_data), tmp));
9744 		}
9745 
9746 	      tmp = gfc_copy_class_to_class (comp, dcmp, nelems,
9747 					     UNLIMITED_POLY (c));
9748 	      gfc_add_expr_to_block (&tmpblock, tmp);
9749 	      tmp = gfc_finish_block (&tmpblock);
9750 
9751 	      gfc_init_block (&tmpblock);
9752 	      gfc_add_modify (&tmpblock, dst_data,
9753 			      fold_convert (TREE_TYPE (dst_data),
9754 					    null_pointer_node));
9755 	      null_data = gfc_finish_block (&tmpblock);
9756 
9757 	      null_cond = fold_build2_loc (input_location, NE_EXPR,
9758 					   logical_type_node, src_data,
9759 				           null_pointer_node);
9760 
9761 	      gfc_add_expr_to_block (&fnblock, build3_v (COND_EXPR, null_cond,
9762 							 tmp, null_data));
9763 	      continue;
9764 	    }
9765 
9766 	  /* To implement guarded deep copy, i.e., deep copy only allocatable
9767 	     components that are really allocated, the deep copy code has to
9768 	     be generated first and then added to the if-block in
9769 	     gfc_duplicate_allocatable ().  */
9770 	  if (cmp_has_alloc_comps && !c->attr.proc_pointer && !same_type)
9771 	    {
9772 	      rank = c->as ? c->as->rank : 0;
9773 	      tmp = fold_convert (TREE_TYPE (dcmp), comp);
9774 	      gfc_add_modify (&fnblock, dcmp, tmp);
9775 	      add_when_allocated = structure_alloc_comps (c->ts.u.derived,
9776 							  comp, dcmp,
9777 							  rank, purpose,
9778 							  caf_mode, args);
9779 	    }
9780 	  else
9781 	    add_when_allocated = NULL_TREE;
9782 
9783 	  if (gfc_deferred_strlen (c, &tmp))
9784 	    {
9785 	      tree len, size;
9786 	      len = tmp;
9787 	      tmp = fold_build3_loc (input_location, COMPONENT_REF,
9788 				     TREE_TYPE (len),
9789 				     decl, len, NULL_TREE);
9790 	      len = fold_build3_loc (input_location, COMPONENT_REF,
9791 				     TREE_TYPE (len),
9792 				     dest, len, NULL_TREE);
9793 	      tmp = fold_build2_loc (input_location, MODIFY_EXPR,
9794 				     TREE_TYPE (len), len, tmp);
9795 	      gfc_add_expr_to_block (&fnblock, tmp);
9796 	      size = size_of_string_in_bytes (c->ts.kind, len);
9797 	      /* This component cannot have allocatable components,
9798 		 therefore add_when_allocated of duplicate_allocatable ()
9799 		 is always NULL.  */
9800 	      tmp = duplicate_allocatable (dcmp, comp, ctype, rank,
9801 					   false, false, size, NULL_TREE);
9802 	      gfc_add_expr_to_block (&fnblock, tmp);
9803 	    }
9804 	  else if (c->attr.pdt_array)
9805 	    {
9806 	      tmp = duplicate_allocatable (dcmp, comp, ctype,
9807 					   c->as ? c->as->rank : 0,
9808 					   false, false, NULL_TREE, NULL_TREE);
9809 	      gfc_add_expr_to_block (&fnblock, tmp);
9810 	    }
9811 	  else if ((c->attr.allocatable)
9812 		    && !c->attr.proc_pointer && !same_type
9813 		    && (!(cmp_has_alloc_comps && c->as) || c->attr.codimension
9814 			|| caf_in_coarray (caf_mode)))
9815 	    {
9816 	      rank = c->as ? c->as->rank : 0;
9817 	      if (c->attr.codimension)
9818 		tmp = gfc_copy_allocatable_data (dcmp, comp, ctype, rank);
9819 	      else if (flag_coarray == GFC_FCOARRAY_LIB
9820 		       && caf_in_coarray (caf_mode))
9821 		{
9822 		  tree dst_tok;
9823 		  if (c->as)
9824 		    dst_tok = gfc_conv_descriptor_token (dcmp);
9825 		  else
9826 		    {
9827 		      /* For a scalar allocatable component the caf_token is
9828 			 the next component.  */
9829 		      if (!c->caf_token)
9830 			  c->caf_token = c->next->backend_decl;
9831 		      dst_tok = fold_build3_loc (input_location,
9832 						 COMPONENT_REF,
9833 						 pvoid_type_node, dest,
9834 						 c->caf_token,
9835 						 NULL_TREE);
9836 		    }
9837 		  tmp = duplicate_allocatable_coarray (dcmp, dst_tok, comp,
9838 						       ctype, rank);
9839 		}
9840 	      else
9841 		tmp = gfc_duplicate_allocatable (dcmp, comp, ctype, rank,
9842 						 add_when_allocated);
9843 	      gfc_add_expr_to_block (&fnblock, tmp);
9844 	    }
9845 	  else
9846 	    if (cmp_has_alloc_comps || is_pdt_type)
9847 	      gfc_add_expr_to_block (&fnblock, add_when_allocated);
9848 
9849 	  break;
9850 
9851 	case ALLOCATE_PDT_COMP:
9852 
9853 	  comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
9854 				  decl, cdecl, NULL_TREE);
9855 
9856 	  /* Set the PDT KIND and LEN fields.  */
9857 	  if (c->attr.pdt_kind || c->attr.pdt_len)
9858 	    {
9859 	      gfc_se tse;
9860 	      gfc_expr *c_expr = NULL;
9861 	      gfc_actual_arglist *param = pdt_param_list;
9862 	      gfc_init_se (&tse, NULL);
9863 	      for (; param; param = param->next)
9864 		if (param->name && !strcmp (c->name, param->name))
9865 		  c_expr = param->expr;
9866 
9867 	      if (!c_expr)
9868 		c_expr = c->initializer;
9869 
9870 	      if (c_expr)
9871 		{
9872 		  gfc_conv_expr_type (&tse, c_expr, TREE_TYPE (comp));
9873 		  gfc_add_modify (&fnblock, comp, tse.expr);
9874 		}
9875 	    }
9876 
9877 	  if (c->attr.pdt_string)
9878 	    {
9879 	      gfc_se tse;
9880 	      gfc_init_se (&tse, NULL);
9881 	      tree strlen = NULL_TREE;
9882 	      gfc_expr *e = gfc_copy_expr (c->ts.u.cl->length);
9883 	      /* Convert the parameterized string length to its value. The
9884 		 string length is stored in a hidden field in the same way as
9885 		 deferred string lengths.  */
9886 	      gfc_insert_parameter_exprs (e, pdt_param_list);
9887 	      if (gfc_deferred_strlen (c, &strlen) && strlen != NULL_TREE)
9888 		{
9889 		  gfc_conv_expr_type (&tse, e,
9890 				      TREE_TYPE (strlen));
9891 		  strlen = fold_build3_loc (input_location, COMPONENT_REF,
9892 					    TREE_TYPE (strlen),
9893 					    decl, strlen, NULL_TREE);
9894 		  gfc_add_modify (&fnblock, strlen, tse.expr);
9895 		  c->ts.u.cl->backend_decl = strlen;
9896 		}
9897 	      gfc_free_expr (e);
9898 
9899 	      /* Scalar parameterized strings can be allocated now.  */
9900 	      if (!c->as)
9901 		{
9902 		  tmp = fold_convert (gfc_array_index_type, strlen);
9903 		  tmp = size_of_string_in_bytes (c->ts.kind, tmp);
9904 		  tmp = gfc_evaluate_now (tmp, &fnblock);
9905 		  tmp = gfc_call_malloc (&fnblock, TREE_TYPE (comp), tmp);
9906 		  gfc_add_modify (&fnblock, comp, tmp);
9907 		}
9908 	    }
9909 
9910 	  /* Allocate parameterized arrays of parameterized derived types.  */
9911 	  if (!(c->attr.pdt_array && c->as && c->as->type == AS_EXPLICIT)
9912 	      && !((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
9913 		   && (c->ts.u.derived && c->ts.u.derived->attr.pdt_type)))
9914 	    continue;
9915 
9916 	  if (c->ts.type == BT_CLASS)
9917 	    comp = gfc_class_data_get (comp);
9918 
9919 	  if (c->attr.pdt_array)
9920 	    {
9921 	      gfc_se tse;
9922 	      int i;
9923 	      tree size = gfc_index_one_node;
9924 	      tree offset = gfc_index_zero_node;
9925 	      tree lower, upper;
9926 	      gfc_expr *e;
9927 
9928 	      /* This chunk takes the expressions for 'lower' and 'upper'
9929 		 in the arrayspec and substitutes in the expressions for
9930 		 the parameters from 'pdt_param_list'. The descriptor
9931 		 fields can then be filled from the values so obtained.  */
9932 	      gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)));
9933 	      for (i = 0; i < c->as->rank; i++)
9934 		{
9935 		  gfc_init_se (&tse, NULL);
9936 		  e = gfc_copy_expr (c->as->lower[i]);
9937 		  gfc_insert_parameter_exprs (e, pdt_param_list);
9938 		  gfc_conv_expr_type (&tse, e, gfc_array_index_type);
9939 		  gfc_free_expr (e);
9940 		  lower = tse.expr;
9941 		  gfc_conv_descriptor_lbound_set (&fnblock, comp,
9942 						  gfc_rank_cst[i],
9943 						  lower);
9944 		  e = gfc_copy_expr (c->as->upper[i]);
9945 		  gfc_insert_parameter_exprs (e, pdt_param_list);
9946 		  gfc_conv_expr_type (&tse, e, gfc_array_index_type);
9947 		  gfc_free_expr (e);
9948 		  upper = tse.expr;
9949 		  gfc_conv_descriptor_ubound_set (&fnblock, comp,
9950 						  gfc_rank_cst[i],
9951 						  upper);
9952 		  gfc_conv_descriptor_stride_set (&fnblock, comp,
9953 						  gfc_rank_cst[i],
9954 						  size);
9955 		  size = gfc_evaluate_now (size, &fnblock);
9956 		  offset = fold_build2_loc (input_location,
9957 					    MINUS_EXPR,
9958 					    gfc_array_index_type,
9959 					    offset, size);
9960 		  offset = gfc_evaluate_now (offset, &fnblock);
9961 		  tmp = fold_build2_loc (input_location, MINUS_EXPR,
9962 					 gfc_array_index_type,
9963 					 upper, lower);
9964 		  tmp = fold_build2_loc (input_location, PLUS_EXPR,
9965 					 gfc_array_index_type,
9966 					 tmp, gfc_index_one_node);
9967 		  size = fold_build2_loc (input_location, MULT_EXPR,
9968 					  gfc_array_index_type, size, tmp);
9969 		}
9970 	      gfc_conv_descriptor_offset_set (&fnblock, comp, offset);
9971 	      if (c->ts.type == BT_CLASS)
9972 		{
9973 		  tmp = gfc_get_vptr_from_expr (comp);
9974 		  if (POINTER_TYPE_P (TREE_TYPE (tmp)))
9975 		    tmp = build_fold_indirect_ref_loc (input_location, tmp);
9976 		  tmp = gfc_vptr_size_get (tmp);
9977 		}
9978 	      else
9979 		tmp = TYPE_SIZE_UNIT (gfc_get_element_type (ctype));
9980 	      tmp = fold_convert (gfc_array_index_type, tmp);
9981 	      size = fold_build2_loc (input_location, MULT_EXPR,
9982 				      gfc_array_index_type, size, tmp);
9983 	      size = gfc_evaluate_now (size, &fnblock);
9984 	      tmp = gfc_call_malloc (&fnblock, NULL, size);
9985 	      gfc_conv_descriptor_data_set (&fnblock, comp, tmp);
9986 	      tmp = gfc_conv_descriptor_dtype (comp);
9987 	      gfc_add_modify (&fnblock, tmp, gfc_get_dtype (ctype));
9988 
9989 	      if (c->initializer && c->initializer->rank)
9990 		{
9991 		  gfc_init_se (&tse, NULL);
9992 		  e = gfc_copy_expr (c->initializer);
9993 		  gfc_insert_parameter_exprs (e, pdt_param_list);
9994 		  gfc_conv_expr_descriptor (&tse, e);
9995 		  gfc_add_block_to_block (&fnblock, &tse.pre);
9996 		  gfc_free_expr (e);
9997 		  tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
9998 		  tmp = build_call_expr_loc (input_location, tmp, 3,
9999 				     gfc_conv_descriptor_data_get (comp),
10000 				     gfc_conv_descriptor_data_get (tse.expr),
10001 				     fold_convert (size_type_node, size));
10002 		  gfc_add_expr_to_block (&fnblock, tmp);
10003 		  gfc_add_block_to_block (&fnblock, &tse.post);
10004 		}
10005 	    }
10006 
10007 	  /* Recurse in to PDT components.  */
10008 	  if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
10009 	      && c->ts.u.derived && c->ts.u.derived->attr.pdt_type
10010 	      && !(c->attr.pointer || c->attr.allocatable))
10011 	    {
10012 	      bool is_deferred = false;
10013 	      gfc_actual_arglist *tail = c->param_list;
10014 
10015 	      for (; tail; tail = tail->next)
10016 		if (!tail->expr)
10017 		  is_deferred = true;
10018 
10019 	      tail = is_deferred ? pdt_param_list : c->param_list;
10020 	      tmp = gfc_allocate_pdt_comp (c->ts.u.derived, comp,
10021 					   c->as ? c->as->rank : 0,
10022 					   tail);
10023 	      gfc_add_expr_to_block (&fnblock, tmp);
10024 	    }
10025 
10026 	  break;
10027 
10028 	case DEALLOCATE_PDT_COMP:
10029 	  /* Deallocate array or parameterized string length components
10030 	     of parameterized derived types.  */
10031 	  if (!(c->attr.pdt_array && c->as && c->as->type == AS_EXPLICIT)
10032 	      && !c->attr.pdt_string
10033 	      && !((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
10034 		   && (c->ts.u.derived && c->ts.u.derived->attr.pdt_type)))
10035 	    continue;
10036 
10037 	  comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
10038 				  decl, cdecl, NULL_TREE);
10039 	  if (c->ts.type == BT_CLASS)
10040 	    comp = gfc_class_data_get (comp);
10041 
10042 	  /* Recurse in to PDT components.  */
10043 	  if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
10044 	      && c->ts.u.derived && c->ts.u.derived->attr.pdt_type
10045 	      && (!c->attr.pointer && !c->attr.allocatable))
10046 	    {
10047 	      tmp = gfc_deallocate_pdt_comp (c->ts.u.derived, comp,
10048 					     c->as ? c->as->rank : 0);
10049 	      gfc_add_expr_to_block (&fnblock, tmp);
10050 	    }
10051 
10052 	  if (c->attr.pdt_array)
10053 	    {
10054 	      tmp = gfc_conv_descriptor_data_get (comp);
10055 	      null_cond = fold_build2_loc (input_location, NE_EXPR,
10056 					   logical_type_node, tmp,
10057 					   build_int_cst (TREE_TYPE (tmp), 0));
10058 	      tmp = gfc_call_free (tmp);
10059 	      tmp = build3_v (COND_EXPR, null_cond, tmp,
10060 			      build_empty_stmt (input_location));
10061 	      gfc_add_expr_to_block (&fnblock, tmp);
10062 	      gfc_conv_descriptor_data_set (&fnblock, comp, null_pointer_node);
10063 	    }
10064 	  else if (c->attr.pdt_string)
10065 	    {
10066 	      null_cond = fold_build2_loc (input_location, NE_EXPR,
10067 					   logical_type_node, comp,
10068 					   build_int_cst (TREE_TYPE (comp), 0));
10069 	      tmp = gfc_call_free (comp);
10070 	      tmp = build3_v (COND_EXPR, null_cond, tmp,
10071 			      build_empty_stmt (input_location));
10072 	      gfc_add_expr_to_block (&fnblock, tmp);
10073 	      tmp = fold_convert (TREE_TYPE (comp), null_pointer_node);
10074 	      gfc_add_modify (&fnblock, comp, tmp);
10075 	    }
10076 
10077 	  break;
10078 
10079 	case CHECK_PDT_DUMMY:
10080 
10081 	  comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
10082 				  decl, cdecl, NULL_TREE);
10083 	  if (c->ts.type == BT_CLASS)
10084 	    comp = gfc_class_data_get (comp);
10085 
10086 	  /* Recurse in to PDT components.  */
10087 	  if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
10088 	      && c->ts.u.derived && c->ts.u.derived->attr.pdt_type)
10089 	    {
10090 	      tmp = gfc_check_pdt_dummy (c->ts.u.derived, comp,
10091 					 c->as ? c->as->rank : 0,
10092 					 pdt_param_list);
10093 	      gfc_add_expr_to_block (&fnblock, tmp);
10094 	    }
10095 
10096 	  if (!c->attr.pdt_len)
10097 	    continue;
10098 	  else
10099 	    {
10100 	      gfc_se tse;
10101 	      gfc_expr *c_expr = NULL;
10102 	      gfc_actual_arglist *param = pdt_param_list;
10103 
10104 	      gfc_init_se (&tse, NULL);
10105 	      for (; param; param = param->next)
10106 		if (!strcmp (c->name, param->name)
10107 		    && param->spec_type == SPEC_EXPLICIT)
10108 		  c_expr = param->expr;
10109 
10110 	      if (c_expr)
10111 		{
10112 		  tree error, cond, cname;
10113 		  gfc_conv_expr_type (&tse, c_expr, TREE_TYPE (comp));
10114 		  cond = fold_build2_loc (input_location, NE_EXPR,
10115 					  logical_type_node,
10116 					  comp, tse.expr);
10117 		  cname = gfc_build_cstring_const (c->name);
10118 		  cname = gfc_build_addr_expr (pchar_type_node, cname);
10119 		  error = gfc_trans_runtime_error (true, NULL,
10120 						   "The value of the PDT LEN "
10121 						   "parameter '%s' does not "
10122 						   "agree with that in the "
10123 						   "dummy declaration",
10124 						   cname);
10125 		  tmp = fold_build3_loc (input_location, COND_EXPR,
10126 					 void_type_node, cond, error,
10127 					 build_empty_stmt (input_location));
10128 		  gfc_add_expr_to_block (&fnblock, tmp);
10129 		}
10130 	    }
10131 	  break;
10132 
10133 	default:
10134 	  gcc_unreachable ();
10135 	  break;
10136 	}
10137     }
10138 
10139   return gfc_finish_block (&fnblock);
10140 }
10141 
10142 /* Recursively traverse an object of derived type, generating code to
10143    nullify allocatable components.  */
10144 
10145 tree
gfc_nullify_alloc_comp(gfc_symbol * der_type,tree decl,int rank,int caf_mode)10146 gfc_nullify_alloc_comp (gfc_symbol * der_type, tree decl, int rank,
10147 			int caf_mode)
10148 {
10149   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
10150 				NULLIFY_ALLOC_COMP,
10151 				GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY | caf_mode, NULL);
10152 }
10153 
10154 
10155 /* Recursively traverse an object of derived type, generating code to
10156    deallocate allocatable components.  */
10157 
10158 tree
gfc_deallocate_alloc_comp(gfc_symbol * der_type,tree decl,int rank,int caf_mode)10159 gfc_deallocate_alloc_comp (gfc_symbol * der_type, tree decl, int rank,
10160 			   int caf_mode)
10161 {
10162   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
10163 				DEALLOCATE_ALLOC_COMP,
10164 				GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY | caf_mode, NULL);
10165 }
10166 
10167 tree
gfc_bcast_alloc_comp(gfc_symbol * derived,gfc_expr * expr,int rank,tree image_index,tree stat,tree errmsg,tree errmsg_len)10168 gfc_bcast_alloc_comp (gfc_symbol *derived, gfc_expr *expr, int rank,
10169 		      tree image_index, tree stat, tree errmsg,
10170 		      tree errmsg_len)
10171 {
10172   tree tmp, array;
10173   gfc_se argse;
10174   stmtblock_t block, post_block;
10175   gfc_co_subroutines_args args;
10176 
10177   args.image_index = image_index;
10178   args.stat = stat;
10179   args.errmsg = errmsg;
10180   args.errmsg_len = errmsg_len;
10181 
10182   if (rank == 0)
10183     {
10184       gfc_start_block (&block);
10185       gfc_init_block (&post_block);
10186       gfc_init_se (&argse, NULL);
10187       gfc_conv_expr (&argse, expr);
10188       gfc_add_block_to_block (&block, &argse.pre);
10189       gfc_add_block_to_block (&post_block, &argse.post);
10190       array = argse.expr;
10191     }
10192   else
10193     {
10194       gfc_init_se (&argse, NULL);
10195       argse.want_pointer = 1;
10196       gfc_conv_expr_descriptor (&argse, expr);
10197       array = argse.expr;
10198     }
10199 
10200   tmp = structure_alloc_comps (derived, array, NULL_TREE, rank,
10201 			       BCAST_ALLOC_COMP,
10202   			       GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY, &args);
10203   return tmp;
10204 }
10205 
10206 /* Recursively traverse an object of derived type, generating code to
10207    deallocate allocatable components.  But do not deallocate coarrays.
10208    To be used for intrinsic assignment, which may not change the allocation
10209    status of coarrays.  */
10210 
10211 tree
gfc_deallocate_alloc_comp_no_caf(gfc_symbol * der_type,tree decl,int rank)10212 gfc_deallocate_alloc_comp_no_caf (gfc_symbol * der_type, tree decl, int rank)
10213 {
10214   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
10215 				DEALLOCATE_ALLOC_COMP, 0, NULL);
10216 }
10217 
10218 
10219 tree
gfc_reassign_alloc_comp_caf(gfc_symbol * der_type,tree decl,tree dest)10220 gfc_reassign_alloc_comp_caf (gfc_symbol *der_type, tree decl, tree dest)
10221 {
10222   return structure_alloc_comps (der_type, decl, dest, 0, REASSIGN_CAF_COMP,
10223 				GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY, NULL);
10224 }
10225 
10226 
10227 /* Recursively traverse an object of derived type, generating code to
10228    copy it and its allocatable components.  */
10229 
10230 tree
gfc_copy_alloc_comp(gfc_symbol * der_type,tree decl,tree dest,int rank,int caf_mode)10231 gfc_copy_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank,
10232 		     int caf_mode)
10233 {
10234   return structure_alloc_comps (der_type, decl, dest, rank, COPY_ALLOC_COMP,
10235 				caf_mode, NULL);
10236 }
10237 
10238 
10239 /* Recursively traverse an object of derived type, generating code to
10240    copy only its allocatable components.  */
10241 
10242 tree
gfc_copy_only_alloc_comp(gfc_symbol * der_type,tree decl,tree dest,int rank)10243 gfc_copy_only_alloc_comp (gfc_symbol * der_type, tree decl, tree dest, int rank)
10244 {
10245   return structure_alloc_comps (der_type, decl, dest, rank,
10246 				COPY_ONLY_ALLOC_COMP, 0, NULL);
10247 }
10248 
10249 
10250 /* Recursively traverse an object of parameterized derived type, generating
10251    code to allocate parameterized components.  */
10252 
10253 tree
gfc_allocate_pdt_comp(gfc_symbol * der_type,tree decl,int rank,gfc_actual_arglist * param_list)10254 gfc_allocate_pdt_comp (gfc_symbol * der_type, tree decl, int rank,
10255 		       gfc_actual_arglist *param_list)
10256 {
10257   tree res;
10258   gfc_actual_arglist *old_param_list = pdt_param_list;
10259   pdt_param_list = param_list;
10260   res = structure_alloc_comps (der_type, decl, NULL_TREE, rank,
10261 			       ALLOCATE_PDT_COMP, 0, NULL);
10262   pdt_param_list = old_param_list;
10263   return res;
10264 }
10265 
10266 /* Recursively traverse an object of parameterized derived type, generating
10267    code to deallocate parameterized components.  */
10268 
10269 tree
gfc_deallocate_pdt_comp(gfc_symbol * der_type,tree decl,int rank)10270 gfc_deallocate_pdt_comp (gfc_symbol * der_type, tree decl, int rank)
10271 {
10272   return structure_alloc_comps (der_type, decl, NULL_TREE, rank,
10273 				DEALLOCATE_PDT_COMP, 0, NULL);
10274 }
10275 
10276 
10277 /* Recursively traverse a dummy of parameterized derived type to check the
10278    values of LEN parameters.  */
10279 
10280 tree
gfc_check_pdt_dummy(gfc_symbol * der_type,tree decl,int rank,gfc_actual_arglist * param_list)10281 gfc_check_pdt_dummy (gfc_symbol * der_type, tree decl, int rank,
10282 		     gfc_actual_arglist *param_list)
10283 {
10284   tree res;
10285   gfc_actual_arglist *old_param_list = pdt_param_list;
10286   pdt_param_list = param_list;
10287   res = structure_alloc_comps (der_type, decl, NULL_TREE, rank,
10288 			       CHECK_PDT_DUMMY, 0, NULL);
10289   pdt_param_list = old_param_list;
10290   return res;
10291 }
10292 
10293 
10294 /* Returns the value of LBOUND for an expression.  This could be broken out
10295    from gfc_conv_intrinsic_bound but this seemed to be simpler.  This is
10296    called by gfc_alloc_allocatable_for_assignment.  */
10297 static tree
get_std_lbound(gfc_expr * expr,tree desc,int dim,bool assumed_size)10298 get_std_lbound (gfc_expr *expr, tree desc, int dim, bool assumed_size)
10299 {
10300   tree lbound;
10301   tree ubound;
10302   tree stride;
10303   tree cond, cond1, cond3, cond4;
10304   tree tmp;
10305   gfc_ref *ref;
10306 
10307   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
10308     {
10309       tmp = gfc_rank_cst[dim];
10310       lbound = gfc_conv_descriptor_lbound_get (desc, tmp);
10311       ubound = gfc_conv_descriptor_ubound_get (desc, tmp);
10312       stride = gfc_conv_descriptor_stride_get (desc, tmp);
10313       cond1 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
10314 			       ubound, lbound);
10315       cond3 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
10316 			       stride, gfc_index_zero_node);
10317       cond3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
10318 			       logical_type_node, cond3, cond1);
10319       cond4 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
10320 			       stride, gfc_index_zero_node);
10321       if (assumed_size)
10322 	cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10323 				tmp, build_int_cst (gfc_array_index_type,
10324 						    expr->rank - 1));
10325       else
10326 	cond = logical_false_node;
10327 
10328       cond1 = fold_build2_loc (input_location, TRUTH_OR_EXPR,
10329 			       logical_type_node, cond3, cond4);
10330       cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
10331 			      logical_type_node, cond, cond1);
10332 
10333       return fold_build3_loc (input_location, COND_EXPR,
10334 			      gfc_array_index_type, cond,
10335 			      lbound, gfc_index_one_node);
10336     }
10337 
10338   if (expr->expr_type == EXPR_FUNCTION)
10339     {
10340       /* A conversion function, so use the argument.  */
10341       gcc_assert (expr->value.function.isym
10342 		  && expr->value.function.isym->conversion);
10343       expr = expr->value.function.actual->expr;
10344     }
10345 
10346   if (expr->expr_type == EXPR_VARIABLE)
10347     {
10348       tmp = TREE_TYPE (expr->symtree->n.sym->backend_decl);
10349       for (ref = expr->ref; ref; ref = ref->next)
10350 	{
10351 	  if (ref->type == REF_COMPONENT
10352 		&& ref->u.c.component->as
10353 		&& ref->next
10354 		&& ref->next->u.ar.type == AR_FULL)
10355 	    tmp = TREE_TYPE (ref->u.c.component->backend_decl);
10356 	}
10357       return GFC_TYPE_ARRAY_LBOUND(tmp, dim);
10358     }
10359 
10360   return gfc_index_one_node;
10361 }
10362 
10363 
10364 /* Returns true if an expression represents an lhs that can be reallocated
10365    on assignment.  */
10366 
10367 bool
gfc_is_reallocatable_lhs(gfc_expr * expr)10368 gfc_is_reallocatable_lhs (gfc_expr *expr)
10369 {
10370   gfc_ref * ref;
10371   gfc_symbol *sym;
10372 
10373   if (!expr->ref)
10374     return false;
10375 
10376   sym = expr->symtree->n.sym;
10377 
10378   if (sym->attr.associate_var && !expr->ref)
10379     return false;
10380 
10381   /* An allocatable class variable with no reference.  */
10382   if (sym->ts.type == BT_CLASS
10383       && (!sym->attr.associate_var || sym->attr.select_rank_temporary)
10384       && CLASS_DATA (sym)->attr.allocatable
10385       && expr->ref
10386       && ((expr->ref->type == REF_ARRAY && expr->ref->u.ar.type == AR_FULL
10387 	   && expr->ref->next == NULL)
10388 	  || (expr->ref->type == REF_COMPONENT
10389 	      && strcmp (expr->ref->u.c.component->name, "_data") == 0
10390 	      && (expr->ref->next == NULL
10391 		  || (expr->ref->next->type == REF_ARRAY
10392 		      && expr->ref->next->u.ar.type == AR_FULL
10393 		      && expr->ref->next->next == NULL)))))
10394     return true;
10395 
10396   /* An allocatable variable.  */
10397   if (sym->attr.allocatable
10398       && (!sym->attr.associate_var || sym->attr.select_rank_temporary)
10399       && expr->ref
10400       && expr->ref->type == REF_ARRAY
10401       && expr->ref->u.ar.type == AR_FULL)
10402     return true;
10403 
10404   /* All that can be left are allocatable components.  */
10405   if ((sym->ts.type != BT_DERIVED
10406        && sym->ts.type != BT_CLASS)
10407 	|| !sym->ts.u.derived->attr.alloc_comp)
10408     return false;
10409 
10410   /* Find a component ref followed by an array reference.  */
10411   for (ref = expr->ref; ref; ref = ref->next)
10412     if (ref->next
10413 	  && ref->type == REF_COMPONENT
10414 	  && ref->next->type == REF_ARRAY
10415 	  && !ref->next->next)
10416       break;
10417 
10418   if (!ref)
10419     return false;
10420 
10421   /* Return true if valid reallocatable lhs.  */
10422   if (ref->u.c.component->attr.allocatable
10423 	&& ref->next->u.ar.type == AR_FULL)
10424     return true;
10425 
10426   return false;
10427 }
10428 
10429 
10430 static tree
concat_str_length(gfc_expr * expr)10431 concat_str_length (gfc_expr* expr)
10432 {
10433   tree type;
10434   tree len1;
10435   tree len2;
10436   gfc_se se;
10437 
10438   type = gfc_typenode_for_spec (&expr->value.op.op1->ts);
10439   len1 = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
10440   if (len1 == NULL_TREE)
10441     {
10442       if (expr->value.op.op1->expr_type == EXPR_OP)
10443 	len1 = concat_str_length (expr->value.op.op1);
10444       else if (expr->value.op.op1->expr_type == EXPR_CONSTANT)
10445 	len1 = build_int_cst (gfc_charlen_type_node,
10446 			expr->value.op.op1->value.character.length);
10447       else if (expr->value.op.op1->ts.u.cl->length)
10448 	{
10449 	  gfc_init_se (&se, NULL);
10450 	  gfc_conv_expr (&se, expr->value.op.op1->ts.u.cl->length);
10451 	  len1 = se.expr;
10452 	}
10453       else
10454 	{
10455 	  /* Last resort!  */
10456 	  gfc_init_se (&se, NULL);
10457 	  se.want_pointer = 1;
10458 	  se.descriptor_only = 1;
10459 	  gfc_conv_expr (&se, expr->value.op.op1);
10460 	  len1 = se.string_length;
10461 	}
10462     }
10463 
10464   type = gfc_typenode_for_spec (&expr->value.op.op2->ts);
10465   len2 = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
10466   if (len2 == NULL_TREE)
10467     {
10468       if (expr->value.op.op2->expr_type == EXPR_OP)
10469 	len2 = concat_str_length (expr->value.op.op2);
10470       else if (expr->value.op.op2->expr_type == EXPR_CONSTANT)
10471 	len2 = build_int_cst (gfc_charlen_type_node,
10472 			expr->value.op.op2->value.character.length);
10473       else if (expr->value.op.op2->ts.u.cl->length)
10474 	{
10475 	  gfc_init_se (&se, NULL);
10476 	  gfc_conv_expr (&se, expr->value.op.op2->ts.u.cl->length);
10477 	  len2 = se.expr;
10478 	}
10479       else
10480 	{
10481 	  /* Last resort!  */
10482 	  gfc_init_se (&se, NULL);
10483 	  se.want_pointer = 1;
10484 	  se.descriptor_only = 1;
10485 	  gfc_conv_expr (&se, expr->value.op.op2);
10486 	  len2 = se.string_length;
10487 	}
10488     }
10489 
10490   gcc_assert(len1 && len2);
10491   len1 = fold_convert (gfc_charlen_type_node, len1);
10492   len2 = fold_convert (gfc_charlen_type_node, len2);
10493 
10494   return fold_build2_loc (input_location, PLUS_EXPR,
10495 			  gfc_charlen_type_node, len1, len2);
10496 }
10497 
10498 
10499 /* Allocate the lhs of an assignment to an allocatable array, otherwise
10500    reallocate it.  */
10501 
10502 tree
gfc_alloc_allocatable_for_assignment(gfc_loopinfo * loop,gfc_expr * expr1,gfc_expr * expr2)10503 gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
10504 				      gfc_expr *expr1,
10505 				      gfc_expr *expr2)
10506 {
10507   stmtblock_t realloc_block;
10508   stmtblock_t alloc_block;
10509   stmtblock_t fblock;
10510   gfc_ss *rss;
10511   gfc_ss *lss;
10512   gfc_array_info *linfo;
10513   tree realloc_expr;
10514   tree alloc_expr;
10515   tree size1;
10516   tree size2;
10517   tree elemsize1;
10518   tree elemsize2;
10519   tree array1;
10520   tree cond_null;
10521   tree cond;
10522   tree tmp;
10523   tree tmp2;
10524   tree lbound;
10525   tree ubound;
10526   tree desc;
10527   tree old_desc;
10528   tree desc2;
10529   tree offset;
10530   tree jump_label1;
10531   tree jump_label2;
10532   tree neq_size;
10533   tree lbd;
10534   tree class_expr2 = NULL_TREE;
10535   int n;
10536   int dim;
10537   gfc_array_spec * as;
10538   bool coarray = (flag_coarray == GFC_FCOARRAY_LIB
10539 		  && gfc_caf_attr (expr1, true).codimension);
10540   tree token;
10541   gfc_se caf_se;
10542 
10543   /* x = f(...) with x allocatable.  In this case, expr1 is the rhs.
10544      Find the lhs expression in the loop chain and set expr1 and
10545      expr2 accordingly.  */
10546   if (expr1->expr_type == EXPR_FUNCTION && expr2 == NULL)
10547     {
10548       expr2 = expr1;
10549       /* Find the ss for the lhs.  */
10550       lss = loop->ss;
10551       for (; lss && lss != gfc_ss_terminator; lss = lss->loop_chain)
10552 	if (lss->info->expr && lss->info->expr->expr_type == EXPR_VARIABLE)
10553 	  break;
10554       if (lss == gfc_ss_terminator)
10555 	return NULL_TREE;
10556       expr1 = lss->info->expr;
10557     }
10558 
10559   /* Bail out if this is not a valid allocate on assignment.  */
10560   if (!gfc_is_reallocatable_lhs (expr1)
10561 	|| (expr2 && !expr2->rank))
10562     return NULL_TREE;
10563 
10564   /* Find the ss for the lhs.  */
10565   lss = loop->ss;
10566   for (; lss && lss != gfc_ss_terminator; lss = lss->loop_chain)
10567     if (lss->info->expr == expr1)
10568       break;
10569 
10570   if (lss == gfc_ss_terminator)
10571     return NULL_TREE;
10572 
10573   linfo = &lss->info->data.array;
10574 
10575   /* Find an ss for the rhs. For operator expressions, we see the
10576      ss's for the operands. Any one of these will do.  */
10577   rss = loop->ss;
10578   for (; rss && rss != gfc_ss_terminator; rss = rss->loop_chain)
10579     if (rss->info->expr != expr1 && rss != loop->temp_ss)
10580       break;
10581 
10582   if (expr2 && rss == gfc_ss_terminator)
10583     return NULL_TREE;
10584 
10585   /* Ensure that the string length from the current scope is used.  */
10586   if (expr2->ts.type == BT_CHARACTER
10587       && expr2->expr_type == EXPR_FUNCTION
10588       && !expr2->value.function.isym)
10589     expr2->ts.u.cl->backend_decl = rss->info->string_length;
10590 
10591   gfc_start_block (&fblock);
10592 
10593   /* Since the lhs is allocatable, this must be a descriptor type.
10594      Get the data and array size.  */
10595   desc = linfo->descriptor;
10596   gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)));
10597   array1 = gfc_conv_descriptor_data_get (desc);
10598 
10599   if (expr2)
10600     desc2 = rss->info->data.array.descriptor;
10601   else
10602     desc2 = NULL_TREE;
10603 
10604   /* Get the old lhs element size for deferred character and class expr1.  */
10605   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10606     {
10607       if (expr1->ts.u.cl->backend_decl
10608 	  && VAR_P (expr1->ts.u.cl->backend_decl))
10609 	elemsize1 = expr1->ts.u.cl->backend_decl;
10610       else
10611 	elemsize1 = lss->info->string_length;
10612     }
10613   else if (expr1->ts.type == BT_CLASS)
10614     {
10615       /* Unfortunately, the lhs vptr is set too early in many cases.
10616 	 Play it safe by using the descriptor element length.  */
10617       tmp = gfc_conv_descriptor_elem_len (desc);
10618       elemsize1 = fold_convert (gfc_array_index_type, tmp);
10619     }
10620   else
10621     elemsize1 = NULL_TREE;
10622   if (elemsize1 != NULL_TREE)
10623     elemsize1 = gfc_evaluate_now (elemsize1, &fblock);
10624 
10625   /* Get the new lhs size in bytes.  */
10626   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10627     {
10628       if (expr2->ts.deferred)
10629 	{
10630 	  if (expr2->ts.u.cl->backend_decl
10631 	      && VAR_P (expr2->ts.u.cl->backend_decl))
10632 	    tmp = expr2->ts.u.cl->backend_decl;
10633 	  else
10634 	    tmp = rss->info->string_length;
10635 	}
10636       else
10637 	{
10638 	  tmp = expr2->ts.u.cl->backend_decl;
10639 	  if (!tmp && expr2->expr_type == EXPR_OP
10640 	      && expr2->value.op.op == INTRINSIC_CONCAT)
10641 	    {
10642 	      tmp = concat_str_length (expr2);
10643 	      expr2->ts.u.cl->backend_decl = gfc_evaluate_now (tmp, &fblock);
10644 	    }
10645 	  else if (!tmp && expr2->ts.u.cl->length)
10646 	    {
10647 	      gfc_se tmpse;
10648 	      gfc_init_se (&tmpse, NULL);
10649 	      gfc_conv_expr_type (&tmpse, expr2->ts.u.cl->length,
10650 				  gfc_charlen_type_node);
10651 	      tmp = tmpse.expr;
10652 	      expr2->ts.u.cl->backend_decl = gfc_evaluate_now (tmp, &fblock);
10653 	    }
10654 	  tmp = fold_convert (TREE_TYPE (expr1->ts.u.cl->backend_decl), tmp);
10655 	}
10656 
10657       if (expr1->ts.u.cl->backend_decl
10658 	  && VAR_P (expr1->ts.u.cl->backend_decl))
10659 	gfc_add_modify (&fblock, expr1->ts.u.cl->backend_decl, tmp);
10660       else
10661 	gfc_add_modify (&fblock, lss->info->string_length, tmp);
10662 
10663       if (expr1->ts.kind > 1)
10664 	tmp = fold_build2_loc (input_location, MULT_EXPR,
10665 			       TREE_TYPE (tmp),
10666 			       tmp, build_int_cst (TREE_TYPE (tmp),
10667 						   expr1->ts.kind));
10668     }
10669   else if (expr1->ts.type == BT_CHARACTER && expr1->ts.u.cl->backend_decl)
10670     {
10671       tmp = TYPE_SIZE_UNIT (TREE_TYPE (gfc_typenode_for_spec (&expr1->ts)));
10672       tmp = fold_build2_loc (input_location, MULT_EXPR,
10673 			     gfc_array_index_type, tmp,
10674 			     expr1->ts.u.cl->backend_decl);
10675     }
10676   else if (UNLIMITED_POLY (expr1) && expr2->ts.type != BT_CLASS)
10677     tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr2->ts));
10678   else if (expr1->ts.type == BT_CLASS && expr2->ts.type == BT_CLASS)
10679     {
10680       tmp = expr2->rank ? gfc_get_class_from_expr (desc2) : NULL_TREE;
10681       if (tmp == NULL_TREE && expr2->expr_type == EXPR_VARIABLE)
10682 	tmp = class_expr2 = gfc_get_class_from_gfc_expr (expr2);
10683 
10684       if (tmp != NULL_TREE)
10685 	tmp = gfc_class_vtab_size_get (tmp);
10686       else
10687 	tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&CLASS_DATA (expr2)->ts));
10688     }
10689   else
10690     tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr2->ts));
10691   elemsize2 = fold_convert (gfc_array_index_type, tmp);
10692   elemsize2 = gfc_evaluate_now (elemsize2, &fblock);
10693 
10694   /* 7.4.1.3 "If variable is an allocated allocatable variable, it is
10695      deallocated if expr is an array of different shape or any of the
10696      corresponding length type parameter values of variable and expr
10697      differ."  This assures F95 compatibility.  */
10698   jump_label1 = gfc_build_label_decl (NULL_TREE);
10699   jump_label2 = gfc_build_label_decl (NULL_TREE);
10700 
10701   /* Allocate if data is NULL.  */
10702   cond_null = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
10703 			 array1, build_int_cst (TREE_TYPE (array1), 0));
10704 
10705   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10706     {
10707       tmp = fold_build2_loc (input_location, NE_EXPR,
10708 			     logical_type_node,
10709 			     lss->info->string_length,
10710 			     rss->info->string_length);
10711       cond_null = fold_build2_loc (input_location, TRUTH_OR_EXPR,
10712 				   logical_type_node, tmp, cond_null);
10713       cond_null= gfc_evaluate_now (cond_null, &fblock);
10714     }
10715   else
10716     cond_null= gfc_evaluate_now (cond_null, &fblock);
10717 
10718   tmp = build3_v (COND_EXPR, cond_null,
10719 		  build1_v (GOTO_EXPR, jump_label1),
10720 		  build_empty_stmt (input_location));
10721   gfc_add_expr_to_block (&fblock, tmp);
10722 
10723   /* Get arrayspec if expr is a full array.  */
10724   if (expr2 && expr2->expr_type == EXPR_FUNCTION
10725 	&& expr2->value.function.isym
10726 	&& expr2->value.function.isym->conversion)
10727     {
10728       /* For conversion functions, take the arg.  */
10729       gfc_expr *arg = expr2->value.function.actual->expr;
10730       as = gfc_get_full_arrayspec_from_expr (arg);
10731     }
10732   else if (expr2)
10733     as = gfc_get_full_arrayspec_from_expr (expr2);
10734   else
10735     as = NULL;
10736 
10737   /* If the lhs shape is not the same as the rhs jump to setting the
10738      bounds and doing the reallocation.......  */
10739   for (n = 0; n < expr1->rank; n++)
10740     {
10741       /* Check the shape.  */
10742       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10743       ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
10744       tmp = fold_build2_loc (input_location, MINUS_EXPR,
10745 			     gfc_array_index_type,
10746 			     loop->to[n], loop->from[n]);
10747       tmp = fold_build2_loc (input_location, PLUS_EXPR,
10748 			     gfc_array_index_type,
10749 			     tmp, lbound);
10750       tmp = fold_build2_loc (input_location, MINUS_EXPR,
10751 			     gfc_array_index_type,
10752 			     tmp, ubound);
10753       cond = fold_build2_loc (input_location, NE_EXPR,
10754 			      logical_type_node,
10755 			      tmp, gfc_index_zero_node);
10756       tmp = build3_v (COND_EXPR, cond,
10757 		      build1_v (GOTO_EXPR, jump_label1),
10758 		      build_empty_stmt (input_location));
10759       gfc_add_expr_to_block (&fblock, tmp);
10760     }
10761 
10762   /* ...else if the element lengths are not the same also go to
10763      setting the bounds and doing the reallocation.... */
10764   if (elemsize1 != NULL_TREE)
10765     {
10766       cond = fold_build2_loc (input_location, NE_EXPR,
10767 			      logical_type_node,
10768 			      elemsize1, elemsize2);
10769       tmp = build3_v (COND_EXPR, cond,
10770 		      build1_v (GOTO_EXPR, jump_label1),
10771 		      build_empty_stmt (input_location));
10772       gfc_add_expr_to_block (&fblock, tmp);
10773     }
10774 
10775   /* ....else jump past the (re)alloc code.  */
10776   tmp = build1_v (GOTO_EXPR, jump_label2);
10777   gfc_add_expr_to_block (&fblock, tmp);
10778 
10779   /* Add the label to start automatic (re)allocation.  */
10780   tmp = build1_v (LABEL_EXPR, jump_label1);
10781   gfc_add_expr_to_block (&fblock, tmp);
10782 
10783   /* If the lhs has not been allocated, its bounds will not have been
10784      initialized and so its size is set to zero.  */
10785   size1 = gfc_create_var (gfc_array_index_type, NULL);
10786   gfc_init_block (&alloc_block);
10787   gfc_add_modify (&alloc_block, size1, gfc_index_zero_node);
10788   gfc_init_block (&realloc_block);
10789   gfc_add_modify (&realloc_block, size1,
10790 		  gfc_conv_descriptor_size (desc, expr1->rank));
10791   tmp = build3_v (COND_EXPR, cond_null,
10792 		  gfc_finish_block (&alloc_block),
10793 		  gfc_finish_block (&realloc_block));
10794   gfc_add_expr_to_block (&fblock, tmp);
10795 
10796   /* Get the rhs size and fix it.  */
10797   size2 = gfc_index_one_node;
10798   for (n = 0; n < expr2->rank; n++)
10799     {
10800       tmp = fold_build2_loc (input_location, MINUS_EXPR,
10801 			     gfc_array_index_type,
10802 			     loop->to[n], loop->from[n]);
10803       tmp = fold_build2_loc (input_location, PLUS_EXPR,
10804 			     gfc_array_index_type,
10805 			     tmp, gfc_index_one_node);
10806       size2 = fold_build2_loc (input_location, MULT_EXPR,
10807 			       gfc_array_index_type,
10808 			       tmp, size2);
10809     }
10810   size2 = gfc_evaluate_now (size2, &fblock);
10811 
10812   cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
10813 			  size1, size2);
10814 
10815   /* If the lhs is deferred length, assume that the element size
10816      changes and force a reallocation.  */
10817   if (expr1->ts.deferred)
10818     neq_size = gfc_evaluate_now (logical_true_node, &fblock);
10819   else
10820     neq_size = gfc_evaluate_now (cond, &fblock);
10821 
10822   /* Deallocation of allocatable components will have to occur on
10823      reallocation.  Fix the old descriptor now.  */
10824   if ((expr1->ts.type == BT_DERIVED)
10825 	&& expr1->ts.u.derived->attr.alloc_comp)
10826     old_desc = gfc_evaluate_now (desc, &fblock);
10827   else
10828     old_desc = NULL_TREE;
10829 
10830   /* Now modify the lhs descriptor and the associated scalarizer
10831      variables. F2003 7.4.1.3: "If variable is or becomes an
10832      unallocated allocatable variable, then it is allocated with each
10833      deferred type parameter equal to the corresponding type parameters
10834      of expr , with the shape of expr , and with each lower bound equal
10835      to the corresponding element of LBOUND(expr)."
10836      Reuse size1 to keep a dimension-by-dimension track of the
10837      stride of the new array.  */
10838   size1 = gfc_index_one_node;
10839   offset = gfc_index_zero_node;
10840 
10841   for (n = 0; n < expr2->rank; n++)
10842     {
10843       tmp = fold_build2_loc (input_location, MINUS_EXPR,
10844 			     gfc_array_index_type,
10845 			     loop->to[n], loop->from[n]);
10846       tmp = fold_build2_loc (input_location, PLUS_EXPR,
10847 			     gfc_array_index_type,
10848 			     tmp, gfc_index_one_node);
10849 
10850       lbound = gfc_index_one_node;
10851       ubound = tmp;
10852 
10853       if (as)
10854 	{
10855 	  lbd = get_std_lbound (expr2, desc2, n,
10856 				as->type == AS_ASSUMED_SIZE);
10857 	  ubound = fold_build2_loc (input_location,
10858 				    MINUS_EXPR,
10859 				    gfc_array_index_type,
10860 				    ubound, lbound);
10861 	  ubound = fold_build2_loc (input_location,
10862 				    PLUS_EXPR,
10863 				    gfc_array_index_type,
10864 				    ubound, lbd);
10865 	  lbound = lbd;
10866 	}
10867 
10868       gfc_conv_descriptor_lbound_set (&fblock, desc,
10869 				      gfc_rank_cst[n],
10870 				      lbound);
10871       gfc_conv_descriptor_ubound_set (&fblock, desc,
10872 				      gfc_rank_cst[n],
10873 				      ubound);
10874       gfc_conv_descriptor_stride_set (&fblock, desc,
10875 				      gfc_rank_cst[n],
10876 				      size1);
10877       lbound = gfc_conv_descriptor_lbound_get (desc,
10878 					       gfc_rank_cst[n]);
10879       tmp2 = fold_build2_loc (input_location, MULT_EXPR,
10880 			      gfc_array_index_type,
10881 			      lbound, size1);
10882       offset = fold_build2_loc (input_location, MINUS_EXPR,
10883 				gfc_array_index_type,
10884 				offset, tmp2);
10885       size1 = fold_build2_loc (input_location, MULT_EXPR,
10886 			       gfc_array_index_type,
10887 			       tmp, size1);
10888     }
10889 
10890   /* Set the lhs descriptor and scalarizer offsets.  For rank > 1,
10891      the array offset is saved and the info.offset is used for a
10892      running offset.  Use the saved_offset instead.  */
10893   tmp = gfc_conv_descriptor_offset (desc);
10894   gfc_add_modify (&fblock, tmp, offset);
10895   if (linfo->saved_offset
10896       && VAR_P (linfo->saved_offset))
10897     gfc_add_modify (&fblock, linfo->saved_offset, tmp);
10898 
10899   /* Now set the deltas for the lhs.  */
10900   for (n = 0; n < expr1->rank; n++)
10901     {
10902       tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]);
10903       dim = lss->dim[n];
10904       tmp = fold_build2_loc (input_location, MINUS_EXPR,
10905 			     gfc_array_index_type, tmp,
10906 			     loop->from[dim]);
10907       if (linfo->delta[dim] && VAR_P (linfo->delta[dim]))
10908 	gfc_add_modify (&fblock, linfo->delta[dim], tmp);
10909     }
10910 
10911   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
10912     gfc_conv_descriptor_span_set (&fblock, desc, elemsize2);
10913 
10914   size2 = fold_build2_loc (input_location, MULT_EXPR,
10915 			   gfc_array_index_type,
10916 			   elemsize2, size2);
10917   size2 = fold_convert (size_type_node, size2);
10918   size2 = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
10919 			   size2, size_one_node);
10920   size2 = gfc_evaluate_now (size2, &fblock);
10921 
10922   /* For deferred character length, the 'size' field of the dtype might
10923      have changed so set the dtype.  */
10924   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))
10925       && expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
10926     {
10927       tree type;
10928       tmp = gfc_conv_descriptor_dtype (desc);
10929       if (expr2->ts.u.cl->backend_decl)
10930 	type = gfc_typenode_for_spec (&expr2->ts);
10931       else
10932 	type = gfc_typenode_for_spec (&expr1->ts);
10933 
10934       gfc_add_modify (&fblock, tmp,
10935 		      gfc_get_dtype_rank_type (expr1->rank,type));
10936     }
10937   else if (expr1->ts.type == BT_CLASS)
10938     {
10939       tree type;
10940       tmp = gfc_conv_descriptor_dtype (desc);
10941 
10942       if (expr2->ts.type != BT_CLASS)
10943 	type = gfc_typenode_for_spec (&expr2->ts);
10944       else
10945 	type = gfc_get_character_type_len (1, elemsize2);
10946 
10947       gfc_add_modify (&fblock, tmp,
10948 		      gfc_get_dtype_rank_type (expr2->rank,type));
10949       /* Set the _len field as well...  */
10950       if (UNLIMITED_POLY (expr1))
10951 	{
10952 	  tmp = gfc_class_len_get (TREE_OPERAND (desc, 0));
10953 	  if (expr2->ts.type == BT_CHARACTER)
10954 	    gfc_add_modify (&fblock, tmp,
10955 			    fold_convert (TREE_TYPE (tmp),
10956 					  TYPE_SIZE_UNIT (type)));
10957 	  else
10958 	    gfc_add_modify (&fblock, tmp,
10959 			    build_int_cst (TREE_TYPE (tmp), 0));
10960 	}
10961       /* ...and the vptr.  */
10962       tmp = gfc_class_vptr_get (TREE_OPERAND (desc, 0));
10963       if (expr2->ts.type == BT_CLASS && !VAR_P (desc2)
10964 	  && TREE_CODE (desc2) == COMPONENT_REF)
10965 	{
10966 	  tmp2 = gfc_get_class_from_expr (desc2);
10967 	  tmp2 = gfc_class_vptr_get (tmp2);
10968 	}
10969       else if (expr2->ts.type == BT_CLASS && class_expr2 != NULL_TREE)
10970 	tmp2 = gfc_class_vptr_get (class_expr2);
10971       else
10972 	{
10973 	  tmp2 = gfc_get_symbol_decl (gfc_find_vtab (&expr2->ts));
10974 	  tmp2 = gfc_build_addr_expr (TREE_TYPE (tmp), tmp2);
10975 	}
10976 
10977       gfc_add_modify (&fblock, tmp, fold_convert (TREE_TYPE (tmp), tmp2));
10978     }
10979   else if (coarray && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
10980     {
10981       gfc_add_modify (&fblock, gfc_conv_descriptor_dtype (desc),
10982 		      gfc_get_dtype (TREE_TYPE (desc)));
10983     }
10984 
10985   /* Realloc expression.  Note that the scalarizer uses desc.data
10986      in the array reference - (*desc.data)[<element>].  */
10987   gfc_init_block (&realloc_block);
10988   gfc_init_se (&caf_se, NULL);
10989 
10990   if (coarray)
10991     {
10992       token = gfc_get_ultimate_alloc_ptr_comps_caf_token (&caf_se, expr1);
10993       if (token == NULL_TREE)
10994 	{
10995 	  tmp = gfc_get_tree_for_caf_expr (expr1);
10996 	  if (POINTER_TYPE_P (TREE_TYPE (tmp)))
10997 	    tmp = build_fold_indirect_ref (tmp);
10998 	  gfc_get_caf_token_offset (&caf_se, &token, NULL, tmp, NULL_TREE,
10999 				    expr1);
11000 	  token = gfc_build_addr_expr (NULL_TREE, token);
11001 	}
11002 
11003       gfc_add_block_to_block (&realloc_block, &caf_se.pre);
11004     }
11005   if ((expr1->ts.type == BT_DERIVED)
11006 	&& expr1->ts.u.derived->attr.alloc_comp)
11007     {
11008       tmp = gfc_deallocate_alloc_comp_no_caf (expr1->ts.u.derived, old_desc,
11009 					      expr1->rank);
11010       gfc_add_expr_to_block (&realloc_block, tmp);
11011     }
11012 
11013   if (!coarray)
11014     {
11015       tmp = build_call_expr_loc (input_location,
11016 				 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
11017 				 fold_convert (pvoid_type_node, array1),
11018 				 size2);
11019       gfc_conv_descriptor_data_set (&realloc_block,
11020 				    desc, tmp);
11021     }
11022   else
11023     {
11024       tmp = build_call_expr_loc (input_location,
11025 				 gfor_fndecl_caf_deregister, 5, token,
11026 				 build_int_cst (integer_type_node,
11027 					       GFC_CAF_COARRAY_DEALLOCATE_ONLY),
11028 				 null_pointer_node, null_pointer_node,
11029 				 integer_zero_node);
11030       gfc_add_expr_to_block (&realloc_block, tmp);
11031       tmp = build_call_expr_loc (input_location,
11032 				 gfor_fndecl_caf_register,
11033 				 7, size2,
11034 				 build_int_cst (integer_type_node,
11035 					   GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY),
11036 				 token, gfc_build_addr_expr (NULL_TREE, desc),
11037 				 null_pointer_node, null_pointer_node,
11038 				 integer_zero_node);
11039       gfc_add_expr_to_block (&realloc_block, tmp);
11040     }
11041 
11042   if ((expr1->ts.type == BT_DERIVED)
11043 	&& expr1->ts.u.derived->attr.alloc_comp)
11044     {
11045       tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, desc,
11046 				    expr1->rank);
11047       gfc_add_expr_to_block (&realloc_block, tmp);
11048     }
11049 
11050   gfc_add_block_to_block (&realloc_block, &caf_se.post);
11051   realloc_expr = gfc_finish_block (&realloc_block);
11052 
11053   /* Reallocate if sizes or dynamic types are different.  */
11054   if (elemsize1)
11055     {
11056       tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
11057 			     elemsize1, elemsize2);
11058       tmp = gfc_evaluate_now (tmp, &fblock);
11059       neq_size = fold_build2_loc (input_location, TRUTH_OR_EXPR,
11060 				  logical_type_node, neq_size, tmp);
11061     }
11062   tmp = build3_v (COND_EXPR, neq_size, realloc_expr,
11063 		  build_empty_stmt (input_location));
11064 
11065   realloc_expr = tmp;
11066 
11067   /* Malloc expression.  */
11068   gfc_init_block (&alloc_block);
11069   if (!coarray)
11070     {
11071       tmp = build_call_expr_loc (input_location,
11072 				 builtin_decl_explicit (BUILT_IN_MALLOC),
11073 				 1, size2);
11074       gfc_conv_descriptor_data_set (&alloc_block,
11075 				    desc, tmp);
11076     }
11077   else
11078     {
11079       tmp = build_call_expr_loc (input_location,
11080 				 gfor_fndecl_caf_register,
11081 				 7, size2,
11082 				 build_int_cst (integer_type_node,
11083 						GFC_CAF_COARRAY_ALLOC),
11084 				 token, gfc_build_addr_expr (NULL_TREE, desc),
11085 				 null_pointer_node, null_pointer_node,
11086 				 integer_zero_node);
11087       gfc_add_expr_to_block (&alloc_block, tmp);
11088     }
11089 
11090 
11091   /* We already set the dtype in the case of deferred character
11092      length arrays and class lvalues.  */
11093   if (!(GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))
11094 	&& ((expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
11095 	    || coarray))
11096       && expr1->ts.type != BT_CLASS)
11097     {
11098       tmp = gfc_conv_descriptor_dtype (desc);
11099       gfc_add_modify (&alloc_block, tmp, gfc_get_dtype (TREE_TYPE (desc)));
11100     }
11101 
11102   if ((expr1->ts.type == BT_DERIVED)
11103 	&& expr1->ts.u.derived->attr.alloc_comp)
11104     {
11105       tmp = gfc_nullify_alloc_comp (expr1->ts.u.derived, desc,
11106 				    expr1->rank);
11107       gfc_add_expr_to_block (&alloc_block, tmp);
11108     }
11109   alloc_expr = gfc_finish_block (&alloc_block);
11110 
11111   /* Malloc if not allocated; realloc otherwise.  */
11112   tmp = build3_v (COND_EXPR, cond_null, alloc_expr, realloc_expr);
11113   gfc_add_expr_to_block (&fblock, tmp);
11114 
11115   /* Make sure that the scalarizer data pointer is updated.  */
11116   if (linfo->data && VAR_P (linfo->data))
11117     {
11118       tmp = gfc_conv_descriptor_data_get (desc);
11119       gfc_add_modify (&fblock, linfo->data, tmp);
11120     }
11121 
11122   /* Add the label for same shape lhs and rhs.  */
11123   tmp = build1_v (LABEL_EXPR, jump_label2);
11124   gfc_add_expr_to_block (&fblock, tmp);
11125 
11126   return gfc_finish_block (&fblock);
11127 }
11128 
11129 
11130 /* Initialize class descriptor's TKR infomation.  */
11131 
11132 void
gfc_trans_class_array(gfc_symbol * sym,gfc_wrapped_block * block)11133 gfc_trans_class_array (gfc_symbol * sym, gfc_wrapped_block * block)
11134 {
11135   tree type, etype;
11136   tree tmp;
11137   tree descriptor;
11138   stmtblock_t init;
11139   locus loc;
11140   int rank;
11141 
11142   /* Make sure the frontend gets these right.  */
11143   gcc_assert (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
11144 	      && (CLASS_DATA (sym)->attr.class_pointer
11145 		  || CLASS_DATA (sym)->attr.allocatable));
11146 
11147   gcc_assert (VAR_P (sym->backend_decl)
11148 	      || TREE_CODE (sym->backend_decl) == PARM_DECL);
11149 
11150   if (sym->attr.dummy)
11151     return;
11152 
11153   descriptor = gfc_class_data_get (sym->backend_decl);
11154   type = TREE_TYPE (descriptor);
11155 
11156   if (type == NULL || !GFC_DESCRIPTOR_TYPE_P (type))
11157     return;
11158 
11159   gfc_save_backend_locus (&loc);
11160   gfc_set_backend_locus (&sym->declared_at);
11161   gfc_init_block (&init);
11162 
11163   rank = CLASS_DATA (sym)->as ? (CLASS_DATA (sym)->as->rank) : (0);
11164   gcc_assert (rank>=0);
11165   tmp = gfc_conv_descriptor_dtype (descriptor);
11166   etype = gfc_get_element_type (type);
11167   tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (tmp), tmp,
11168 			 gfc_get_dtype_rank_type (rank, etype));
11169   gfc_add_expr_to_block (&init, tmp);
11170 
11171   gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
11172   gfc_restore_backend_locus (&loc);
11173 }
11174 
11175 
11176 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.
11177    Do likewise, recursively if necessary, with the allocatable components of
11178    derived types.  This function is also called for assumed-rank arrays, which
11179    are always dummy arguments.  */
11180 
11181 void
gfc_trans_deferred_array(gfc_symbol * sym,gfc_wrapped_block * block)11182 gfc_trans_deferred_array (gfc_symbol * sym, gfc_wrapped_block * block)
11183 {
11184   tree type;
11185   tree tmp;
11186   tree descriptor;
11187   stmtblock_t init;
11188   stmtblock_t cleanup;
11189   locus loc;
11190   int rank;
11191   bool sym_has_alloc_comp, has_finalizer;
11192 
11193   sym_has_alloc_comp = (sym->ts.type == BT_DERIVED
11194 			|| sym->ts.type == BT_CLASS)
11195 			  && sym->ts.u.derived->attr.alloc_comp;
11196   has_finalizer = sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED
11197 		   ? gfc_is_finalizable (sym->ts.u.derived, NULL) : false;
11198 
11199   /* Make sure the frontend gets these right.  */
11200   gcc_assert (sym->attr.pointer || sym->attr.allocatable || sym_has_alloc_comp
11201 	      || has_finalizer
11202 	      || (sym->as->type == AS_ASSUMED_RANK && sym->attr.dummy));
11203 
11204   gfc_save_backend_locus (&loc);
11205   gfc_set_backend_locus (&sym->declared_at);
11206   gfc_init_block (&init);
11207 
11208   gcc_assert (VAR_P (sym->backend_decl)
11209 	      || TREE_CODE (sym->backend_decl) == PARM_DECL);
11210 
11211   if (sym->ts.type == BT_CHARACTER
11212       && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
11213     {
11214       gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
11215       gfc_trans_vla_type_sizes (sym, &init);
11216     }
11217 
11218   /* Dummy, use associated and result variables don't need anything special.  */
11219   if (sym->attr.dummy || sym->attr.use_assoc || sym->attr.result)
11220     {
11221       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
11222       gfc_restore_backend_locus (&loc);
11223       return;
11224     }
11225 
11226   descriptor = sym->backend_decl;
11227 
11228   /* Although static, derived types with default initializers and
11229      allocatable components must not be nulled wholesale; instead they
11230      are treated component by component.  */
11231   if (TREE_STATIC (descriptor) && !sym_has_alloc_comp && !has_finalizer)
11232     {
11233       /* SAVEd variables are not freed on exit.  */
11234       gfc_trans_static_array_pointer (sym);
11235 
11236       gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
11237       gfc_restore_backend_locus (&loc);
11238       return;
11239     }
11240 
11241   /* Get the descriptor type.  */
11242   type = TREE_TYPE (sym->backend_decl);
11243 
11244   if ((sym_has_alloc_comp || (has_finalizer && sym->ts.type != BT_CLASS))
11245       && !(sym->attr.pointer || sym->attr.allocatable))
11246     {
11247       if (!sym->attr.save
11248 	  && !(TREE_STATIC (sym->backend_decl) && sym->attr.is_main_program))
11249 	{
11250 	  if (sym->value == NULL
11251 	      || !gfc_has_default_initializer (sym->ts.u.derived))
11252 	    {
11253 	      rank = sym->as ? sym->as->rank : 0;
11254 	      tmp = gfc_nullify_alloc_comp (sym->ts.u.derived,
11255 					    descriptor, rank);
11256 	      gfc_add_expr_to_block (&init, tmp);
11257 	    }
11258 	  else
11259 	    gfc_init_default_dt (sym, &init, false);
11260 	}
11261     }
11262   else if (!GFC_DESCRIPTOR_TYPE_P (type))
11263     {
11264       /* If the backend_decl is not a descriptor, we must have a pointer
11265 	 to one.  */
11266       descriptor = build_fold_indirect_ref_loc (input_location,
11267 						sym->backend_decl);
11268       type = TREE_TYPE (descriptor);
11269     }
11270 
11271   /* NULLIFY the data pointer, for non-saved allocatables.  */
11272   if (GFC_DESCRIPTOR_TYPE_P (type) && !sym->attr.save && sym->attr.allocatable)
11273     {
11274       gfc_conv_descriptor_data_set (&init, descriptor, null_pointer_node);
11275       if (flag_coarray == GFC_FCOARRAY_LIB && sym->attr.codimension)
11276 	{
11277 	  /* Declare the variable static so its array descriptor stays present
11278 	     after leaving the scope.  It may still be accessed through another
11279 	     image.  This may happen, for example, with the caf_mpi
11280 	     implementation.  */
11281 	  TREE_STATIC (descriptor) = 1;
11282 	  tmp = gfc_conv_descriptor_token (descriptor);
11283 	  gfc_add_modify (&init, tmp, fold_convert (TREE_TYPE (tmp),
11284 						    null_pointer_node));
11285 	}
11286     }
11287 
11288   /* Set initial TKR for pointers and allocatables */
11289   if (GFC_DESCRIPTOR_TYPE_P (type)
11290       && (sym->attr.pointer || sym->attr.allocatable))
11291     {
11292       tree etype;
11293 
11294       gcc_assert (sym->as && sym->as->rank>=0);
11295       tmp = gfc_conv_descriptor_dtype (descriptor);
11296       etype = gfc_get_element_type (type);
11297       tmp = fold_build2_loc (input_location, MODIFY_EXPR,
11298   			     TREE_TYPE (tmp), tmp,
11299   			     gfc_get_dtype_rank_type (sym->as->rank, etype));
11300       gfc_add_expr_to_block (&init, tmp);
11301     }
11302   gfc_restore_backend_locus (&loc);
11303   gfc_init_block (&cleanup);
11304 
11305   /* Allocatable arrays need to be freed when they go out of scope.
11306      The allocatable components of pointers must not be touched.  */
11307   if (!sym->attr.allocatable && has_finalizer && sym->ts.type != BT_CLASS
11308       && !sym->attr.pointer && !sym->attr.artificial && !sym->attr.save
11309       && !sym->ns->proc_name->attr.is_main_program)
11310     {
11311       gfc_expr *e;
11312       sym->attr.referenced = 1;
11313       e = gfc_lval_expr_from_sym (sym);
11314       gfc_add_finalizer_call (&cleanup, e);
11315       gfc_free_expr (e);
11316     }
11317   else if ((!sym->attr.allocatable || !has_finalizer)
11318       && sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
11319       && !sym->attr.pointer && !sym->attr.save
11320       && !sym->ns->proc_name->attr.is_main_program)
11321     {
11322       int rank;
11323       rank = sym->as ? sym->as->rank : 0;
11324       tmp = gfc_deallocate_alloc_comp (sym->ts.u.derived, descriptor, rank);
11325       gfc_add_expr_to_block (&cleanup, tmp);
11326     }
11327 
11328   if (sym->attr.allocatable && (sym->attr.dimension || sym->attr.codimension)
11329       && !sym->attr.save && !sym->attr.result
11330       && !sym->ns->proc_name->attr.is_main_program)
11331     {
11332       gfc_expr *e;
11333       e = has_finalizer ? gfc_lval_expr_from_sym (sym) : NULL;
11334       tmp = gfc_deallocate_with_status (sym->backend_decl, NULL_TREE, NULL_TREE,
11335 					NULL_TREE, NULL_TREE, true, e,
11336 					sym->attr.codimension
11337 					? GFC_CAF_COARRAY_DEREGISTER
11338 					: GFC_CAF_COARRAY_NOCOARRAY);
11339       if (e)
11340 	gfc_free_expr (e);
11341       gfc_add_expr_to_block (&cleanup, tmp);
11342     }
11343 
11344   gfc_add_init_cleanup (block, gfc_finish_block (&init),
11345 			gfc_finish_block (&cleanup));
11346 }
11347 
11348 /************ Expression Walking Functions ******************/
11349 
11350 /* Walk a variable reference.
11351 
11352    Possible extension - multiple component subscripts.
11353     x(:,:) = foo%a(:)%b(:)
11354    Transforms to
11355     forall (i=..., j=...)
11356       x(i,j) = foo%a(j)%b(i)
11357     end forall
11358    This adds a fair amount of complexity because you need to deal with more
11359    than one ref.  Maybe handle in a similar manner to vector subscripts.
11360    Maybe not worth the effort.  */
11361 
11362 
11363 static gfc_ss *
gfc_walk_variable_expr(gfc_ss * ss,gfc_expr * expr)11364 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
11365 {
11366   gfc_ref *ref;
11367 
11368   gfc_fix_class_refs (expr);
11369 
11370   for (ref = expr->ref; ref; ref = ref->next)
11371     if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
11372       break;
11373 
11374   return gfc_walk_array_ref (ss, expr, ref);
11375 }
11376 
11377 
11378 gfc_ss *
gfc_walk_array_ref(gfc_ss * ss,gfc_expr * expr,gfc_ref * ref)11379 gfc_walk_array_ref (gfc_ss * ss, gfc_expr * expr, gfc_ref * ref)
11380 {
11381   gfc_array_ref *ar;
11382   gfc_ss *newss;
11383   int n;
11384 
11385   for (; ref; ref = ref->next)
11386     {
11387       if (ref->type == REF_SUBSTRING)
11388 	{
11389 	  ss = gfc_get_scalar_ss (ss, ref->u.ss.start);
11390 	  if (ref->u.ss.end)
11391 	    ss = gfc_get_scalar_ss (ss, ref->u.ss.end);
11392 	}
11393 
11394       /* We're only interested in array sections from now on.  */
11395       if (ref->type != REF_ARRAY)
11396 	continue;
11397 
11398       ar = &ref->u.ar;
11399 
11400       switch (ar->type)
11401 	{
11402 	case AR_ELEMENT:
11403 	  for (n = ar->dimen - 1; n >= 0; n--)
11404 	    ss = gfc_get_scalar_ss (ss, ar->start[n]);
11405 	  break;
11406 
11407 	case AR_FULL:
11408 	  newss = gfc_get_array_ss (ss, expr, ar->as->rank, GFC_SS_SECTION);
11409 	  newss->info->data.array.ref = ref;
11410 
11411 	  /* Make sure array is the same as array(:,:), this way
11412 	     we don't need to special case all the time.  */
11413 	  ar->dimen = ar->as->rank;
11414 	  for (n = 0; n < ar->dimen; n++)
11415 	    {
11416 	      ar->dimen_type[n] = DIMEN_RANGE;
11417 
11418 	      gcc_assert (ar->start[n] == NULL);
11419 	      gcc_assert (ar->end[n] == NULL);
11420 	      gcc_assert (ar->stride[n] == NULL);
11421 	    }
11422 	  ss = newss;
11423 	  break;
11424 
11425 	case AR_SECTION:
11426 	  newss = gfc_get_array_ss (ss, expr, 0, GFC_SS_SECTION);
11427 	  newss->info->data.array.ref = ref;
11428 
11429 	  /* We add SS chains for all the subscripts in the section.  */
11430 	  for (n = 0; n < ar->dimen; n++)
11431 	    {
11432 	      gfc_ss *indexss;
11433 
11434 	      switch (ar->dimen_type[n])
11435 		{
11436 		case DIMEN_ELEMENT:
11437 		  /* Add SS for elemental (scalar) subscripts.  */
11438 		  gcc_assert (ar->start[n]);
11439 		  indexss = gfc_get_scalar_ss (gfc_ss_terminator, ar->start[n]);
11440 		  indexss->loop_chain = gfc_ss_terminator;
11441 		  newss->info->data.array.subscript[n] = indexss;
11442 		  break;
11443 
11444 		case DIMEN_RANGE:
11445                   /* We don't add anything for sections, just remember this
11446                      dimension for later.  */
11447 		  newss->dim[newss->dimen] = n;
11448 		  newss->dimen++;
11449 		  break;
11450 
11451 		case DIMEN_VECTOR:
11452 		  /* Create a GFC_SS_VECTOR index in which we can store
11453 		     the vector's descriptor.  */
11454 		  indexss = gfc_get_array_ss (gfc_ss_terminator, ar->start[n],
11455 					      1, GFC_SS_VECTOR);
11456 		  indexss->loop_chain = gfc_ss_terminator;
11457 		  newss->info->data.array.subscript[n] = indexss;
11458 		  newss->dim[newss->dimen] = n;
11459 		  newss->dimen++;
11460 		  break;
11461 
11462 		default:
11463 		  /* We should know what sort of section it is by now.  */
11464 		  gcc_unreachable ();
11465 		}
11466 	    }
11467 	  /* We should have at least one non-elemental dimension,
11468 	     unless we are creating a descriptor for a (scalar) coarray.  */
11469 	  gcc_assert (newss->dimen > 0
11470 		      || newss->info->data.array.ref->u.ar.as->corank > 0);
11471 	  ss = newss;
11472 	  break;
11473 
11474 	default:
11475 	  /* We should know what sort of section it is by now.  */
11476 	  gcc_unreachable ();
11477 	}
11478 
11479     }
11480   return ss;
11481 }
11482 
11483 
11484 /* Walk an expression operator. If only one operand of a binary expression is
11485    scalar, we must also add the scalar term to the SS chain.  */
11486 
11487 static gfc_ss *
gfc_walk_op_expr(gfc_ss * ss,gfc_expr * expr)11488 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
11489 {
11490   gfc_ss *head;
11491   gfc_ss *head2;
11492 
11493   head = gfc_walk_subexpr (ss, expr->value.op.op1);
11494   if (expr->value.op.op2 == NULL)
11495     head2 = head;
11496   else
11497     head2 = gfc_walk_subexpr (head, expr->value.op.op2);
11498 
11499   /* All operands are scalar.  Pass back and let the caller deal with it.  */
11500   if (head2 == ss)
11501     return head2;
11502 
11503   /* All operands require scalarization.  */
11504   if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
11505     return head2;
11506 
11507   /* One of the operands needs scalarization, the other is scalar.
11508      Create a gfc_ss for the scalar expression.  */
11509   if (head == ss)
11510     {
11511       /* First operand is scalar.  We build the chain in reverse order, so
11512          add the scalar SS after the second operand.  */
11513       head = head2;
11514       while (head && head->next != ss)
11515 	head = head->next;
11516       /* Check we haven't somehow broken the chain.  */
11517       gcc_assert (head);
11518       head->next = gfc_get_scalar_ss (ss, expr->value.op.op1);
11519     }
11520   else				/* head2 == head */
11521     {
11522       gcc_assert (head2 == head);
11523       /* Second operand is scalar.  */
11524       head2 = gfc_get_scalar_ss (head2, expr->value.op.op2);
11525     }
11526 
11527   return head2;
11528 }
11529 
11530 
11531 /* Reverse a SS chain.  */
11532 
11533 gfc_ss *
gfc_reverse_ss(gfc_ss * ss)11534 gfc_reverse_ss (gfc_ss * ss)
11535 {
11536   gfc_ss *next;
11537   gfc_ss *head;
11538 
11539   gcc_assert (ss != NULL);
11540 
11541   head = gfc_ss_terminator;
11542   while (ss != gfc_ss_terminator)
11543     {
11544       next = ss->next;
11545       /* Check we didn't somehow break the chain.  */
11546       gcc_assert (next != NULL);
11547       ss->next = head;
11548       head = ss;
11549       ss = next;
11550     }
11551 
11552   return (head);
11553 }
11554 
11555 
11556 /* Given an expression referring to a procedure, return the symbol of its
11557    interface.  We can't get the procedure symbol directly as we have to handle
11558    the case of (deferred) type-bound procedures.  */
11559 
11560 gfc_symbol *
gfc_get_proc_ifc_for_expr(gfc_expr * procedure_ref)11561 gfc_get_proc_ifc_for_expr (gfc_expr *procedure_ref)
11562 {
11563   gfc_symbol *sym;
11564   gfc_ref *ref;
11565 
11566   if (procedure_ref == NULL)
11567     return NULL;
11568 
11569   /* Normal procedure case.  */
11570   if (procedure_ref->expr_type == EXPR_FUNCTION
11571       && procedure_ref->value.function.esym)
11572     sym = procedure_ref->value.function.esym;
11573   else
11574     sym = procedure_ref->symtree->n.sym;
11575 
11576   /* Typebound procedure case.  */
11577   for (ref = procedure_ref->ref; ref; ref = ref->next)
11578     {
11579       if (ref->type == REF_COMPONENT
11580 	  && ref->u.c.component->attr.proc_pointer)
11581 	sym = ref->u.c.component->ts.interface;
11582       else
11583 	sym = NULL;
11584     }
11585 
11586   return sym;
11587 }
11588 
11589 
11590 /* Given an expression referring to an intrinsic function call,
11591    return the intrinsic symbol.  */
11592 
11593 gfc_intrinsic_sym *
gfc_get_intrinsic_for_expr(gfc_expr * call)11594 gfc_get_intrinsic_for_expr (gfc_expr *call)
11595 {
11596   if (call == NULL)
11597     return NULL;
11598 
11599   /* Normal procedure case.  */
11600   if (call->expr_type == EXPR_FUNCTION)
11601     return call->value.function.isym;
11602   else
11603     return NULL;
11604 }
11605 
11606 
11607 /* Indicates whether an argument to an intrinsic function should be used in
11608    scalarization.  It is usually the case, except for some intrinsics
11609    requiring the value to be constant, and using the value at compile time only.
11610    As the value is not used at runtime in those cases, we don’t produce code
11611    for it, and it should not be visible to the scalarizer.
11612    FUNCTION is the intrinsic function being called, ACTUAL_ARG is the actual
11613    argument being examined in that call, and ARG_NUM the index number
11614    of ACTUAL_ARG in the list of arguments.
11615    The intrinsic procedure’s dummy argument associated with ACTUAL_ARG is
11616    identified using the name in ACTUAL_ARG if it is present (that is: if it’s
11617    a keyword argument), otherwise using ARG_NUM.  */
11618 
11619 static bool
arg_evaluated_for_scalarization(gfc_intrinsic_sym * function,gfc_dummy_arg * dummy_arg)11620 arg_evaluated_for_scalarization (gfc_intrinsic_sym *function,
11621 				 gfc_dummy_arg *dummy_arg)
11622 {
11623   if (function != NULL && dummy_arg != NULL)
11624     {
11625       switch (function->id)
11626 	{
11627 	  case GFC_ISYM_INDEX:
11628 	  case GFC_ISYM_LEN_TRIM:
11629 	  case GFC_ISYM_MASKL:
11630 	  case GFC_ISYM_MASKR:
11631 	  case GFC_ISYM_SCAN:
11632 	  case GFC_ISYM_VERIFY:
11633 	    if (strcmp ("kind", gfc_dummy_arg_get_name (*dummy_arg)) == 0)
11634 	      return false;
11635 	  /* Fallthrough.  */
11636 
11637 	  default:
11638 	    break;
11639 	}
11640     }
11641 
11642   return true;
11643 }
11644 
11645 
11646 /* Walk the arguments of an elemental function.
11647    PROC_EXPR is used to check whether an argument is permitted to be absent.  If
11648    it is NULL, we don't do the check and the argument is assumed to be present.
11649 */
11650 
11651 gfc_ss *
gfc_walk_elemental_function_args(gfc_ss * ss,gfc_actual_arglist * arg,gfc_intrinsic_sym * intrinsic_sym,gfc_ss_type type)11652 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
11653 				  gfc_intrinsic_sym *intrinsic_sym,
11654 				  gfc_ss_type type)
11655 {
11656   int scalar;
11657   gfc_ss *head;
11658   gfc_ss *tail;
11659   gfc_ss *newss;
11660 
11661   head = gfc_ss_terminator;
11662   tail = NULL;
11663 
11664   scalar = 1;
11665   for (; arg; arg = arg->next)
11666     {
11667       gfc_dummy_arg * const dummy_arg = arg->associated_dummy;
11668       if (!arg->expr
11669 	  || arg->expr->expr_type == EXPR_NULL
11670 	  || !arg_evaluated_for_scalarization (intrinsic_sym, dummy_arg))
11671 	continue;
11672 
11673       newss = gfc_walk_subexpr (head, arg->expr);
11674       if (newss == head)
11675 	{
11676 	  /* Scalar argument.  */
11677 	  gcc_assert (type == GFC_SS_SCALAR || type == GFC_SS_REFERENCE);
11678 	  newss = gfc_get_scalar_ss (head, arg->expr);
11679 	  newss->info->type = type;
11680 	  if (dummy_arg)
11681 	    newss->info->data.scalar.dummy_arg = dummy_arg;
11682 	}
11683       else
11684 	scalar = 0;
11685 
11686       if (dummy_arg != NULL
11687 	  && gfc_dummy_arg_is_optional (*dummy_arg)
11688 	  && arg->expr->expr_type == EXPR_VARIABLE
11689 	  && (gfc_expr_attr (arg->expr).optional
11690 	      || gfc_expr_attr (arg->expr).allocatable
11691 	      || gfc_expr_attr (arg->expr).pointer))
11692 	newss->info->can_be_null_ref = true;
11693 
11694       head = newss;
11695       if (!tail)
11696         {
11697           tail = head;
11698           while (tail->next != gfc_ss_terminator)
11699             tail = tail->next;
11700         }
11701     }
11702 
11703   if (scalar)
11704     {
11705       /* If all the arguments are scalar we don't need the argument SS.  */
11706       gfc_free_ss_chain (head);
11707       /* Pass it back.  */
11708       return ss;
11709     }
11710 
11711   /* Add it onto the existing chain.  */
11712   tail->next = ss;
11713   return head;
11714 }
11715 
11716 
11717 /* Walk a function call.  Scalar functions are passed back, and taken out of
11718    scalarization loops.  For elemental functions we walk their arguments.
11719    The result of functions returning arrays is stored in a temporary outside
11720    the loop, so that the function is only called once.  Hence we do not need
11721    to walk their arguments.  */
11722 
11723 static gfc_ss *
gfc_walk_function_expr(gfc_ss * ss,gfc_expr * expr)11724 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
11725 {
11726   gfc_intrinsic_sym *isym;
11727   gfc_symbol *sym;
11728   gfc_component *comp = NULL;
11729 
11730   isym = expr->value.function.isym;
11731 
11732   /* Handle intrinsic functions separately.  */
11733   if (isym)
11734     return gfc_walk_intrinsic_function (ss, expr, isym);
11735 
11736   sym = expr->value.function.esym;
11737   if (!sym)
11738     sym = expr->symtree->n.sym;
11739 
11740   if (gfc_is_class_array_function (expr))
11741     return gfc_get_array_ss (ss, expr,
11742 			     CLASS_DATA (expr->value.function.esym->result)->as->rank,
11743 			     GFC_SS_FUNCTION);
11744 
11745   /* A function that returns arrays.  */
11746   comp = gfc_get_proc_ptr_comp (expr);
11747   if ((!comp && gfc_return_by_reference (sym) && sym->result->attr.dimension)
11748       || (comp && comp->attr.dimension))
11749     return gfc_get_array_ss (ss, expr, expr->rank, GFC_SS_FUNCTION);
11750 
11751   /* Walk the parameters of an elemental function.  For now we always pass
11752      by reference.  */
11753   if (sym->attr.elemental || (comp && comp->attr.elemental))
11754     {
11755       gfc_ss *old_ss = ss;
11756 
11757       ss = gfc_walk_elemental_function_args (old_ss,
11758 					     expr->value.function.actual,
11759 					     gfc_get_intrinsic_for_expr (expr),
11760 					     GFC_SS_REFERENCE);
11761       if (ss != old_ss
11762 	  && (comp
11763 	      || sym->attr.proc_pointer
11764 	      || sym->attr.if_source != IFSRC_DECL
11765 	      || sym->attr.array_outer_dependency))
11766 	ss->info->array_outer_dependency = 1;
11767     }
11768 
11769   /* Scalar functions are OK as these are evaluated outside the scalarization
11770      loop.  Pass back and let the caller deal with it.  */
11771   return ss;
11772 }
11773 
11774 
11775 /* An array temporary is constructed for array constructors.  */
11776 
11777 static gfc_ss *
gfc_walk_array_constructor(gfc_ss * ss,gfc_expr * expr)11778 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
11779 {
11780   return gfc_get_array_ss (ss, expr, expr->rank, GFC_SS_CONSTRUCTOR);
11781 }
11782 
11783 
11784 /* Walk an expression.  Add walked expressions to the head of the SS chain.
11785    A wholly scalar expression will not be added.  */
11786 
11787 gfc_ss *
gfc_walk_subexpr(gfc_ss * ss,gfc_expr * expr)11788 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
11789 {
11790   gfc_ss *head;
11791 
11792   switch (expr->expr_type)
11793     {
11794     case EXPR_VARIABLE:
11795       head = gfc_walk_variable_expr (ss, expr);
11796       return head;
11797 
11798     case EXPR_OP:
11799       head = gfc_walk_op_expr (ss, expr);
11800       return head;
11801 
11802     case EXPR_FUNCTION:
11803       head = gfc_walk_function_expr (ss, expr);
11804       return head;
11805 
11806     case EXPR_CONSTANT:
11807     case EXPR_NULL:
11808     case EXPR_STRUCTURE:
11809       /* Pass back and let the caller deal with it.  */
11810       break;
11811 
11812     case EXPR_ARRAY:
11813       head = gfc_walk_array_constructor (ss, expr);
11814       return head;
11815 
11816     case EXPR_SUBSTRING:
11817       /* Pass back and let the caller deal with it.  */
11818       break;
11819 
11820     default:
11821       gfc_internal_error ("bad expression type during walk (%d)",
11822 		      expr->expr_type);
11823     }
11824   return ss;
11825 }
11826 
11827 
11828 /* Entry point for expression walking.
11829    A return value equal to the passed chain means this is
11830    a scalar expression.  It is up to the caller to take whatever action is
11831    necessary to translate these.  */
11832 
11833 gfc_ss *
gfc_walk_expr(gfc_expr * expr)11834 gfc_walk_expr (gfc_expr * expr)
11835 {
11836   gfc_ss *res;
11837 
11838   res = gfc_walk_subexpr (gfc_ss_terminator, expr);
11839   return gfc_reverse_ss (res);
11840 }
11841