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