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