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