]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans.c
Update copyright years.
[thirdparty/gcc.git] / gcc / fortran / trans.c
CommitLineData
6de9cd9a 1/* Code translation -- generate GCC trees from gfc_code.
99dee823 2 Copyright (C) 2002-2021 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Paul Brook
4
9fc4d79b 5This file is part of GCC.
6de9cd9a 6
9fc4d79b
TS
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
d234d788 9Software Foundation; either version 3, or (at your option) any later
9fc4d79b 10version.
6de9cd9a 11
9fc4d79b
TS
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
6de9cd9a
DN
16
17You should have received a copy of the GNU General Public License
d234d788
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
c7131fb2 24#include "options.h"
2adfab87
AM
25#include "tree.h"
26#include "gfortran.h"
45b0be94 27#include "gimple-expr.h" /* For create_tmp_var_raw. */
2adfab87 28#include "trans.h"
d8a2d370 29#include "stringpool.h"
2adfab87
AM
30#include "fold-const.h"
31#include "tree-iterator.h"
6de9cd9a
DN
32#include "trans-stmt.h"
33#include "trans-array.h"
34#include "trans-types.h"
35#include "trans-const.h"
36
37/* Naming convention for backend interface code:
38
39 gfc_trans_* translate gfc_code into STMT trees.
40
41 gfc_conv_* expression conversion
42
43 gfc_get_* get a backend tree representation of a decl or type */
44
45static gfc_file *gfc_current_backend_file;
46
7e49f965
TS
47const char gfc_msg_fault[] = N_("Array reference out of bounds");
48const char gfc_msg_wrong_return[] = N_("Incorrect function return value");
dd18a33b 49
6de9cd9a 50
9c81750c
TB
51/* Return a location_t suitable for 'tree' for a gfortran locus. The way the
52 parser works in gfortran, loc->lb->location contains only the line number
53 and LOCATION_COLUMN is 0; hence, the column has to be added when generating
54 locations for 'tree'. Cf. error.c's gfc_format_decoder. */
55
56location_t
57gfc_get_location (locus *loc)
58{
59 return linemap_position_for_loc_and_offset (line_table, loc->lb->location,
60 loc->nextc - loc->lb->line);
61}
62
6de9cd9a
DN
63/* Advance along TREE_CHAIN n times. */
64
65tree
66gfc_advance_chain (tree t, int n)
67{
68 for (; n > 0; n--)
69 {
6e45f57b 70 gcc_assert (t != NULL_TREE);
910ad8de 71 t = DECL_CHAIN (t);
6de9cd9a
DN
72 }
73 return t;
74}
75
662de36b
TK
76static int num_var;
77
78#define MAX_PREFIX_LEN 20
79
80static tree
81create_var_debug_raw (tree type, const char *prefix)
82{
83 /* Space for prefix + "_" + 10-digit-number + \0. */
84 char name_buf[MAX_PREFIX_LEN + 1 + 10 + 1];
85 tree t;
86 int i;
87
88 if (prefix == NULL)
89 prefix = "gfc";
90 else
91 gcc_assert (strlen (prefix) <= MAX_PREFIX_LEN);
92
93 for (i = 0; prefix[i] != 0; i++)
94 name_buf[i] = gfc_wide_toupper (prefix[i]);
95
96 snprintf (name_buf + i, sizeof (name_buf) - i, "_%d", num_var++);
97
98 t = build_decl (input_location, VAR_DECL, get_identifier (name_buf), type);
99
8d76c007
TK
100 /* Not setting this causes some regressions. */
101 DECL_ARTIFICIAL (t) = 1;
102
662de36b
TK
103 /* We want debug info for it. */
104 DECL_IGNORED_P (t) = 0;
105 /* It should not be nameless. */
106 DECL_NAMELESS (t) = 0;
107
108 /* Make the variable writable. */
109 TREE_READONLY (t) = 0;
110
111 DECL_EXTERNAL (t) = 0;
112 TREE_STATIC (t) = 0;
113 TREE_USED (t) = 1;
114
115 return t;
116}
117
6de9cd9a
DN
118/* Creates a variable declaration with a given TYPE. */
119
120tree
121gfc_create_var_np (tree type, const char *prefix)
122{
049e4fb0 123 tree t;
8b704316 124
662de36b
TK
125 if (flag_debug_aux_vars)
126 return create_var_debug_raw (type, prefix);
127
049e4fb0
FXC
128 t = create_tmp_var_raw (type, prefix);
129
130 /* No warnings for anonymous variables. */
131 if (prefix == NULL)
132 TREE_NO_WARNING (t) = 1;
133
134 return t;
6de9cd9a
DN
135}
136
137
138/* Like above, but also adds it to the current scope. */
139
140tree
141gfc_create_var (tree type, const char *prefix)
142{
143 tree tmp;
144
145 tmp = gfc_create_var_np (type, prefix);
146
147 pushdecl (tmp);
148
149 return tmp;
150}
151
152
df2fba9e 153/* If the expression is not constant, evaluate it now. We assign the
6de9cd9a
DN
154 result of the expression to an artificially created variable VAR, and
155 return a pointer to the VAR_DECL node for this variable. */
156
157tree
55bd9c35 158gfc_evaluate_now_loc (location_t loc, tree expr, stmtblock_t * pblock)
6de9cd9a
DN
159{
160 tree var;
161
6615c446 162 if (CONSTANT_CLASS_P (expr))
6de9cd9a
DN
163 return expr;
164
165 var = gfc_create_var (TREE_TYPE (expr), NULL);
55bd9c35 166 gfc_add_modify_loc (loc, pblock, var, expr);
6de9cd9a
DN
167
168 return var;
169}
170
171
55bd9c35
TB
172tree
173gfc_evaluate_now (tree expr, stmtblock_t * pblock)
174{
175 return gfc_evaluate_now_loc (input_location, expr, pblock);
176}
177
fb3f5eae
TK
178/* Like gfc_evaluate_now, but add the created variable to the
179 function scope. */
180
181tree
182gfc_evaluate_now_function_scope (tree expr, stmtblock_t * pblock)
183{
184 tree var;
185 var = gfc_create_var_np (TREE_TYPE (expr), NULL);
186 gfc_add_decl_to_function (var);
187 gfc_add_modify (pblock, var, expr);
188
189 return var;
190}
55bd9c35 191
8b704316 192/* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
726a989a 193 A MODIFY_EXPR is an assignment:
07beea0d 194 LHS <- RHS. */
6de9cd9a
DN
195
196void
55bd9c35 197gfc_add_modify_loc (location_t loc, stmtblock_t * pblock, tree lhs, tree rhs)
6de9cd9a
DN
198{
199 tree tmp;
200
10174ddf
MM
201 tree t1, t2;
202 t1 = TREE_TYPE (rhs);
203 t2 = TREE_TYPE (lhs);
1b31fca7 204 /* Make sure that the types of the rhs and the lhs are compatible
7ab92584
SB
205 for scalar assignments. We should probably have something
206 similar for aggregates, but right now removing that check just
207 breaks everything. */
1b31fca7 208 gcc_checking_assert (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)
c86db055 209 || AGGREGATE_TYPE_P (TREE_TYPE (lhs)));
7ab92584 210
55bd9c35 211 tmp = fold_build2_loc (loc, MODIFY_EXPR, void_type_node, lhs,
65a9ca82 212 rhs);
6de9cd9a
DN
213 gfc_add_expr_to_block (pblock, tmp);
214}
215
216
55bd9c35
TB
217void
218gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs)
219{
220 gfc_add_modify_loc (input_location, pblock, lhs, rhs);
221}
222
223
6de9cd9a 224/* Create a new scope/binding level and initialize a block. Care must be
1f2959f0 225 taken when translating expressions as any temporaries will be placed in
6de9cd9a
DN
226 the innermost scope. */
227
228void
229gfc_start_block (stmtblock_t * block)
230{
231 /* Start a new binding level. */
87a60f68 232 pushlevel ();
6de9cd9a
DN
233 block->has_scope = 1;
234
235 /* The block is empty. */
236 block->head = NULL_TREE;
237}
238
239
240/* Initialize a block without creating a new scope. */
241
242void
243gfc_init_block (stmtblock_t * block)
244{
245 block->head = NULL_TREE;
246 block->has_scope = 0;
247}
248
249
250/* Sometimes we create a scope but it turns out that we don't actually
251 need it. This function merges the scope of BLOCK with its parent.
252 Only variable decls will be merged, you still need to add the code. */
253
254void
255gfc_merge_block_scope (stmtblock_t * block)
256{
257 tree decl;
258 tree next;
259
6e45f57b 260 gcc_assert (block->has_scope);
6de9cd9a
DN
261 block->has_scope = 0;
262
263 /* Remember the decls in this scope. */
264 decl = getdecls ();
87a60f68 265 poplevel (0, 0);
6de9cd9a
DN
266
267 /* Add them to the parent scope. */
268 while (decl != NULL_TREE)
269 {
910ad8de
NF
270 next = DECL_CHAIN (decl);
271 DECL_CHAIN (decl) = NULL_TREE;
6de9cd9a
DN
272
273 pushdecl (decl);
274 decl = next;
275 }
276}
277
278
279/* Finish a scope containing a block of statements. */
280
281tree
282gfc_finish_block (stmtblock_t * stmtblock)
283{
284 tree decl;
285 tree expr;
286 tree block;
287
7c87eac6
PB
288 expr = stmtblock->head;
289 if (!expr)
c2255bc4 290 expr = build_empty_stmt (input_location);
7c87eac6 291
6de9cd9a
DN
292 stmtblock->head = NULL_TREE;
293
294 if (stmtblock->has_scope)
295 {
296 decl = getdecls ();
297
298 if (decl)
299 {
87a60f68 300 block = poplevel (1, 0);
923ab88c 301 expr = build3_v (BIND_EXPR, decl, expr, block);
6de9cd9a
DN
302 }
303 else
87a60f68 304 poplevel (0, 0);
6de9cd9a
DN
305 }
306
307 return expr;
308}
309
310
311/* Build an ADDR_EXPR and cast the result to TYPE. If TYPE is NULL, the
312 natural type is used. */
313
314tree
315gfc_build_addr_expr (tree type, tree t)
316{
317 tree base_type = TREE_TYPE (t);
318 tree natural_type;
319
320 if (type && POINTER_TYPE_P (type)
321 && TREE_CODE (base_type) == ARRAY_TYPE
322 && TYPE_MAIN_VARIANT (TREE_TYPE (type))
323 == TYPE_MAIN_VARIANT (TREE_TYPE (base_type)))
543535a3
AP
324 {
325 tree min_val = size_zero_node;
326 tree type_domain = TYPE_DOMAIN (base_type);
327 if (type_domain && TYPE_MIN_VALUE (type_domain))
328 min_val = TYPE_MIN_VALUE (type_domain);
5d44e5c8
TB
329 t = fold (build4_loc (input_location, ARRAY_REF, TREE_TYPE (type),
330 t, min_val, NULL_TREE, NULL_TREE));
543535a3
AP
331 natural_type = type;
332 }
6de9cd9a
DN
333 else
334 natural_type = build_pointer_type (base_type);
335
336 if (TREE_CODE (t) == INDIRECT_REF)
337 {
338 if (!type)
339 type = natural_type;
340 t = TREE_OPERAND (t, 0);
341 natural_type = TREE_TYPE (t);
342 }
343 else
344 {
628c189e
RG
345 tree base = get_base_address (t);
346 if (base && DECL_P (base))
347 TREE_ADDRESSABLE (base) = 1;
65a9ca82 348 t = fold_build1_loc (input_location, ADDR_EXPR, natural_type, t);
6de9cd9a
DN
349 }
350
351 if (type && natural_type != type)
352 t = convert (type, t);
353
354 return t;
355}
356
357
ff3598bc
PT
358static tree
359get_array_span (tree type, tree decl)
360{
361 tree span;
362
0a524296
PT
363 /* Component references are guaranteed to have a reliable value for
364 'span'. Likewise indirect references since they emerge from the
365 conversion of a CFI descriptor or the hidden dummy descriptor. */
366 if (TREE_CODE (decl) == COMPONENT_REF
367 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
368 return gfc_conv_descriptor_span_get (decl);
369 else if (TREE_CODE (decl) == INDIRECT_REF
370 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
371 return gfc_conv_descriptor_span_get (decl);
372
ff3598bc
PT
373 /* Return the span for deferred character length array references. */
374 if (type && TREE_CODE (type) == ARRAY_TYPE
375 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != NULL_TREE
376 && (VAR_P (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
377 || TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == INDIRECT_REF)
378 && (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == INDIRECT_REF
379 || TREE_CODE (decl) == FUNCTION_DECL
380 || DECL_CONTEXT (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
381 == DECL_CONTEXT (decl)))
382 {
7c4acac3
AV
383 span = fold_convert (gfc_array_index_type,
384 TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
385 span = fold_build2 (MULT_EXPR, gfc_array_index_type,
386 fold_convert (gfc_array_index_type,
387 TYPE_SIZE_UNIT (TREE_TYPE (type))),
388 span);
ff3598bc 389 }
ba08c70a
PT
390 else if (type && TREE_CODE (type) == ARRAY_TYPE
391 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != NULL_TREE
392 && integer_zerop (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
393 {
394 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
395 span = gfc_conv_descriptor_span_get (decl);
396 else
397 span = NULL_TREE;
398 }
ff3598bc
PT
399 /* Likewise for class array or pointer array references. */
400 else if (TREE_CODE (decl) == FIELD_DECL
401 || VAR_OR_FUNCTION_DECL_P (decl)
402 || TREE_CODE (decl) == PARM_DECL)
403 {
404 if (GFC_DECL_CLASS (decl))
405 {
406 /* When a temporary is in place for the class array, then the
407 original class' declaration is stored in the saved
408 descriptor. */
409 if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
410 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
411 else
412 {
413 /* Allow for dummy arguments and other good things. */
414 if (POINTER_TYPE_P (TREE_TYPE (decl)))
415 decl = build_fold_indirect_ref_loc (input_location, decl);
416
417 /* Check if '_data' is an array descriptor. If it is not,
418 the array must be one of the components of the class
419 object, so return a null span. */
420 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (
421 gfc_class_data_get (decl))))
422 return NULL_TREE;
423 }
424 span = gfc_class_vtab_size_get (decl);
425 }
426 else if (GFC_DECL_PTR_ARRAY_P (decl))
427 {
428 if (TREE_CODE (decl) == PARM_DECL)
429 decl = build_fold_indirect_ref_loc (input_location, decl);
430 span = gfc_conv_descriptor_span_get (decl);
431 }
432 else
433 span = NULL_TREE;
434 }
435 else
436 span = NULL_TREE;
437
438 return span;
439}
440
441
6de9cd9a
DN
442/* Build an ARRAY_REF with its natural type. */
443
444tree
f3b0bb7a 445gfc_build_array_ref (tree base, tree offset, tree decl, tree vptr)
6de9cd9a
DN
446{
447 tree type = TREE_TYPE (base);
1d6b7f39 448 tree tmp;
ff3598bc 449 tree span = NULL_TREE;
1d6b7f39 450
4409de24
TB
451 if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0)
452 {
453 gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0);
454
8a5c4899 455 return fold_convert (TYPE_MAIN_VARIANT (type), base);
4409de24
TB
456 }
457
fef89628
MM
458 /* Scalar coarray, there is nothing to do. */
459 if (TREE_CODE (type) != ARRAY_TYPE)
460 {
461 gcc_assert (decl == NULL_TREE);
462 gcc_assert (integer_zerop (offset));
463 return base;
464 }
465
6de9cd9a
DN
466 type = TREE_TYPE (type);
467
468 if (DECL_P (base))
469 TREE_ADDRESSABLE (base) = 1;
470
31120e8f
RS
471 /* Strip NON_LVALUE_EXPR nodes. */
472 STRIP_TYPE_NOPS (offset);
473
ff3598bc
PT
474 /* If decl or vptr are non-null, pointer arithmetic for the array reference
475 is likely. Generate the 'span' for the array reference. */
476 if (vptr)
fcc4891d
PT
477 {
478 span = gfc_vptr_size_get (vptr);
479
480 /* Check if this is an unlimited polymorphic object carrying a character
481 payload. In this case, the 'len' field is non-zero. */
482 if (decl && GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
ce8dcc91 483 span = gfc_resize_class_size_with_len (NULL, decl, span);
fcc4891d 484 }
ff3598bc 485 else if (decl)
0a524296 486 span = get_array_span (type, decl);
c49ea23d 487
ff3598bc
PT
488 /* If a non-null span has been generated reference the element with
489 pointer arithmetic. */
490 if (span != NULL_TREE)
491 {
65a9ca82
TB
492 offset = fold_build2_loc (input_location, MULT_EXPR,
493 gfc_array_index_type,
c49ea23d 494 offset, span);
1d6b7f39 495 tmp = gfc_build_addr_expr (pvoid_type_node, base);
5d49b6a7 496 tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
1d6b7f39 497 tmp = fold_convert (build_pointer_type (type), tmp);
f4af4019
JH
498 if ((TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != ARRAY_TYPE)
499 || !TYPE_STRING_FLAG (type))
db3927fb 500 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1d6b7f39
PT
501 return tmp;
502 }
ff3598bc 503 /* Otherwise use a straightforward array reference. */
1d6b7f39 504 else
5d44e5c8
TB
505 return build4_loc (input_location, ARRAY_REF, type, base, offset,
506 NULL_TREE, NULL_TREE);
6de9cd9a
DN
507}
508
509
f25a62a5
DK
510/* Generate a call to print a runtime error possibly including multiple
511 arguments and a locus. */
6de9cd9a 512
55bd9c35 513static tree
d74a8b05 514trans_runtime_error_vararg (tree errorfunc, locus* where, const char* msgid,
55bd9c35 515 va_list ap)
f25a62a5 516{
6de9cd9a 517 stmtblock_t block;
6de9cd9a 518 tree tmp;
f96d606f 519 tree arg, arg2;
c8fe94c7
FXC
520 tree *argarray;
521 tree fntype;
f96d606f 522 char *message;
c8fe94c7
FXC
523 const char *p;
524 int line, nargs, i;
55bd9c35 525 location_t loc;
6de9cd9a 526
c8fe94c7
FXC
527 /* Compute the number of extra arguments from the format string. */
528 for (p = msgid, nargs = 0; *p; p++)
529 if (*p == '%')
530 {
531 p++;
532 if (*p != '%')
533 nargs++;
534 }
535
6de9cd9a
DN
536 /* The code to generate the error. */
537 gfc_start_block (&block);
538
dd18a33b
FXC
539 if (where)
540 {
dd18a33b 541 line = LOCATION_LINE (where->lb->location);
1a33dc9e
UB
542 message = xasprintf ("At line %d of file %s", line,
543 where->lb->file->filename);
dd18a33b
FXC
544 }
545 else
1a33dc9e
UB
546 message = xasprintf ("In file '%s', around line %d",
547 gfc_source_file, LOCATION_LINE (input_location) + 1);
6de9cd9a 548
ee37d2f5
FXC
549 arg = gfc_build_addr_expr (pchar_type_node,
550 gfc_build_localized_cstring_const (message));
cede9502 551 free (message);
8b704316 552
1a33dc9e 553 message = xasprintf ("%s", _(msgid));
ee37d2f5
FXC
554 arg2 = gfc_build_addr_expr (pchar_type_node,
555 gfc_build_localized_cstring_const (message));
cede9502 556 free (message);
6de9cd9a 557
c8fe94c7 558 /* Build the argument array. */
1145e690 559 argarray = XALLOCAVEC (tree, nargs + 2);
c8fe94c7
FXC
560 argarray[0] = arg;
561 argarray[1] = arg2;
c8fe94c7 562 for (i = 0; i < nargs; i++)
f25a62a5 563 argarray[2 + i] = va_arg (ap, tree);
8b704316 564
0d52899f 565 /* Build the function call to runtime_(warning,error)_at; because of the
db3927fb
AH
566 variable number of arguments, we can't use build_call_expr_loc dinput_location,
567 irectly. */
d74a8b05 568 fntype = TREE_TYPE (errorfunc);
0d52899f 569
9c81750c 570 loc = where ? gfc_get_location (where) : input_location;
9b2b7279
AM
571 tmp = fold_build_call_array_loc (loc, TREE_TYPE (fntype),
572 fold_build1_loc (loc, ADDR_EXPR,
65a9ca82 573 build_pointer_type (fntype),
d74a8b05 574 errorfunc),
9b2b7279 575 nargs + 2, argarray);
6de9cd9a
DN
576 gfc_add_expr_to_block (&block, tmp);
577
f25a62a5
DK
578 return gfc_finish_block (&block);
579}
580
581
55bd9c35
TB
582tree
583gfc_trans_runtime_error (bool error, locus* where, const char* msgid, ...)
584{
585 va_list ap;
586 tree result;
587
588 va_start (ap, msgid);
d74a8b05
JB
589 result = trans_runtime_error_vararg (error
590 ? gfor_fndecl_runtime_error_at
591 : gfor_fndecl_runtime_warning_at,
592 where, msgid, ap);
55bd9c35
TB
593 va_end (ap);
594 return result;
595}
596
597
f25a62a5
DK
598/* Generate a runtime error if COND is true. */
599
600void
601gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
602 locus * where, const char * msgid, ...)
603{
604 va_list ap;
605 stmtblock_t block;
606 tree body;
607 tree tmp;
608 tree tmpvar = NULL;
609
610 if (integer_zerop (cond))
611 return;
612
613 if (once)
614 {
63ee5404 615 tmpvar = gfc_create_var (logical_type_node, "print_warning");
f25a62a5 616 TREE_STATIC (tmpvar) = 1;
63ee5404 617 DECL_INITIAL (tmpvar) = logical_true_node;
f25a62a5
DK
618 gfc_add_expr_to_block (pblock, tmpvar);
619 }
620
621 gfc_start_block (&block);
622
ed9c79e1
JJ
623 /* For error, runtime_error_at already implies PRED_NORETURN. */
624 if (!error && once)
625 gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_WARN_ONCE,
626 NOT_TAKEN));
627
f25a62a5
DK
628 /* The code to generate the error. */
629 va_start (ap, msgid);
630 gfc_add_expr_to_block (&block,
d74a8b05
JB
631 trans_runtime_error_vararg
632 (error ? gfor_fndecl_runtime_error_at
633 : gfor_fndecl_runtime_warning_at,
634 where, msgid, ap));
fc2655fb 635 va_end (ap);
f25a62a5 636
0d52899f 637 if (once)
63ee5404 638 gfc_add_modify (&block, tmpvar, logical_false_node);
0d52899f 639
6de9cd9a
DN
640 body = gfc_finish_block (&block);
641
642 if (integer_onep (cond))
643 {
644 gfc_add_expr_to_block (pblock, body);
645 }
646 else
647 {
0d52899f 648 if (once)
9c81750c 649 cond = fold_build2_loc (gfc_get_location (where), TRUTH_AND_EXPR,
65a9ca82 650 long_integer_type_node, tmpvar, cond);
0d52899f
TB
651 else
652 cond = fold_convert (long_integer_type_node, cond);
653
9c81750c 654 tmp = fold_build3_loc (gfc_get_location (where), COND_EXPR, void_type_node,
55bd9c35 655 cond, body,
9c81750c 656 build_empty_stmt (gfc_get_location (where)));
6de9cd9a
DN
657 gfc_add_expr_to_block (pblock, tmp);
658 }
659}
660
661
d74a8b05
JB
662static tree
663trans_os_error_at (locus* where, const char* msgid, ...)
664{
665 va_list ap;
666 tree result;
667
668 va_start (ap, msgid);
669 result = trans_runtime_error_vararg (gfor_fndecl_os_error_at,
670 where, msgid, ap);
671 va_end (ap);
672 return result;
673}
674
675
676
1529b8d9 677/* Call malloc to allocate size bytes of memory, with special conditions:
da17cbb7 678 + if size == 0, return a malloced area of size 1,
1529b8d9
FXC
679 + if malloc returns NULL, issue a runtime error. */
680tree
681gfc_call_malloc (stmtblock_t * block, tree type, tree size)
682{
d74a8b05 683 tree tmp, malloc_result, null_result, res, malloc_tree;
1529b8d9
FXC
684 stmtblock_t block2;
685
1529b8d9 686 /* Create a variable to hold the result. */
10174ddf 687 res = gfc_create_var (prvoid_type_node, NULL);
1529b8d9 688
22bdbb0f 689 /* Call malloc. */
1529b8d9 690 gfc_start_block (&block2);
8f0aaee5 691
107051a5 692 size = fold_convert (size_type_node, size);
65a9ca82
TB
693 size = fold_build2_loc (input_location, MAX_EXPR, size_type_node, size,
694 build_int_cst (size_type_node, 1));
8f0aaee5 695
e79983f4 696 malloc_tree = builtin_decl_explicit (BUILT_IN_MALLOC);
726a989a 697 gfc_add_modify (&block2, res,
10174ddf
MM
698 fold_convert (prvoid_type_node,
699 build_call_expr_loc (input_location,
e79983f4 700 malloc_tree, 1, size)));
22bdbb0f
TB
701
702 /* Optionally check whether malloc was successful. */
703 if (gfc_option.rtcheck & GFC_RTCHECK_MEM)
704 {
65a9ca82 705 null_result = fold_build2_loc (input_location, EQ_EXPR,
63ee5404 706 logical_type_node, res,
65a9ca82 707 build_int_cst (pvoid_type_node, 0));
65a9ca82
TB
708 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
709 null_result,
d74a8b05
JB
710 trans_os_error_at (NULL,
711 "Error allocating %lu bytes",
712 fold_convert
713 (long_unsigned_type_node,
714 size)),
715 build_empty_stmt (input_location));
22bdbb0f
TB
716 gfc_add_expr_to_block (&block2, tmp);
717 }
718
1529b8d9 719 malloc_result = gfc_finish_block (&block2);
8f0aaee5 720 gfc_add_expr_to_block (block, malloc_result);
1529b8d9
FXC
721
722 if (type != NULL)
723 res = fold_convert (type, res);
724 return res;
725}
726
22bdbb0f 727
4376b7cf 728/* Allocate memory, using an optional status argument.
8b704316 729
4376b7cf
FXC
730 This function follows the following pseudo-code:
731
732 void *
8f992d64 733 allocate (size_t size, integer_type stat)
4376b7cf
FXC
734 {
735 void *newmem;
8b704316 736
8f992d64
DC
737 if (stat requested)
738 stat = 0;
4376b7cf 739
da17cbb7
JB
740 newmem = malloc (MAX (size, 1));
741 if (newmem == NULL)
4376b7cf 742 {
da17cbb7
JB
743 if (stat)
744 *stat = LIBERROR_ALLOCATION;
745 else
bd085c20 746 runtime_error ("Allocation would exceed memory limit");
4376b7cf 747 }
4376b7cf
FXC
748 return newmem;
749 } */
4f13e17f
DC
750void
751gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
752 tree size, tree status)
4376b7cf 753{
ed9c79e1
JJ
754 tree tmp, error_cond;
755 stmtblock_t on_error;
8f992d64 756 tree status_type = status ? TREE_TYPE (status) : NULL_TREE;
4376b7cf 757
4f13e17f 758 /* If successful and stat= is given, set status to 0. */
8f992d64
DC
759 if (status != NULL_TREE)
760 gfc_add_expr_to_block (block,
761 fold_build2_loc (input_location, MODIFY_EXPR, status_type,
762 status, build_int_cst (status_type, 0)));
4376b7cf 763
4376b7cf 764 /* The allocation itself. */
107051a5 765 size = fold_convert (size_type_node, size);
4f13e17f
DC
766 gfc_add_modify (block, pointer,
767 fold_convert (TREE_TYPE (pointer),
8f992d64 768 build_call_expr_loc (input_location,
e79983f4 769 builtin_decl_explicit (BUILT_IN_MALLOC), 1,
8f992d64
DC
770 fold_build2_loc (input_location,
771 MAX_EXPR, size_type_node, size,
772 build_int_cst (size_type_node, 1)))));
773
774 /* What to do in case of error. */
ed9c79e1 775 gfc_start_block (&on_error);
8f992d64 776 if (status != NULL_TREE)
ed9c79e1 777 {
ed9c79e1
JJ
778 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, status,
779 build_int_cst (status_type, LIBERROR_ALLOCATION));
780 gfc_add_expr_to_block (&on_error, tmp);
781 }
ea6363a3 782 else
ed9c79e1 783 {
d74a8b05
JB
784 /* Here, os_error_at already implies PRED_NORETURN. */
785 tree lusize = fold_convert (long_unsigned_type_node, size);
786 tmp = trans_os_error_at (NULL, "Error allocating %lu bytes", lusize);
ed9c79e1
JJ
787 gfc_add_expr_to_block (&on_error, tmp);
788 }
4376b7cf 789
4f13e17f 790 error_cond = fold_build2_loc (input_location, EQ_EXPR,
63ee5404 791 logical_type_node, pointer,
4f13e17f 792 build_int_cst (prvoid_type_node, 0));
65a9ca82 793 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
7f7fa20f
ML
794 gfc_unlikely (error_cond, PRED_FORTRAN_FAIL_ALLOC),
795 gfc_finish_block (&on_error),
4f13e17f 796 build_empty_stmt (input_location));
4376b7cf 797
4f13e17f 798 gfc_add_expr_to_block (block, tmp);
4376b7cf
FXC
799}
800
801
8f992d64 802/* Allocate memory, using an optional status argument.
8b704316 803
8f992d64
DC
804 This function follows the following pseudo-code:
805
806 void *
979d4598 807 allocate (size_t size, void** token, int *stat, char* errmsg, int errlen)
8f992d64
DC
808 {
809 void *newmem;
979d4598
TB
810
811 newmem = _caf_register (size, regtype, token, &stat, errmsg, errlen);
8f992d64
DC
812 return newmem;
813 } */
ba85c8c3
AV
814void
815gfc_allocate_using_caf_lib (stmtblock_t * block, tree pointer, tree size,
816 tree token, tree status, tree errmsg, tree errlen,
817 gfc_coarray_regtype alloc_type)
8f992d64 818{
4f13e17f 819 tree tmp, pstat;
8f992d64 820
979d4598
TB
821 gcc_assert (token != NULL_TREE);
822
8f992d64
DC
823 /* The allocation itself. */
824 if (status == NULL_TREE)
825 pstat = null_pointer_node;
826 else
827 pstat = gfc_build_addr_expr (NULL_TREE, status);
828
829 if (errmsg == NULL_TREE)
830 {
831 gcc_assert(errlen == NULL_TREE);
832 errmsg = null_pointer_node;
833 errlen = build_int_cst (integer_type_node, 0);
834 }
835
107051a5 836 size = fold_convert (size_type_node, size);
4f13e17f 837 tmp = build_call_expr_loc (input_location,
3c9f5092 838 gfor_fndecl_caf_register, 7,
4f13e17f 839 fold_build2_loc (input_location,
ba85c8c3
AV
840 MAX_EXPR, size_type_node, size, size_one_node),
841 build_int_cst (integer_type_node, alloc_type),
3c9f5092
AV
842 token, gfc_build_addr_expr (pvoid_type_node, pointer),
843 pstat, errmsg, errlen);
8f992d64 844
4f13e17f 845 gfc_add_expr_to_block (block, tmp);
985f6c79
TB
846
847 /* It guarantees memory consistency within the same segment */
848 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
849 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
850 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
851 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
852 ASM_VOLATILE_P (tmp) = 1;
853 gfc_add_expr_to_block (block, tmp);
8f992d64
DC
854}
855
856
4376b7cf 857/* Generate code for an ALLOCATE statement when the argument is an
ea6363a3 858 allocatable variable. If the variable is currently allocated, it is an
4376b7cf 859 error to allocate it again.
8b704316 860
4376b7cf 861 This function follows the following pseudo-code:
8b704316 862
4376b7cf 863 void *
8f992d64 864 allocate_allocatable (void *mem, size_t size, integer_type stat)
4376b7cf
FXC
865 {
866 if (mem == NULL)
867 return allocate (size, stat);
868 else
869 {
870 if (stat)
8f992d64 871 stat = LIBERROR_ALLOCATION;
4376b7cf 872 else
f8dde8af 873 runtime_error ("Attempting to allocate already allocated variable");
5b130807 874 }
f25a62a5 875 }
8b704316 876
f25a62a5
DK
877 expr must be set to the original expression being allocated for its locus
878 and variable name in case a runtime error has to be printed. */
4f13e17f 879void
3c9f5092
AV
880gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size,
881 tree token, tree status, tree errmsg, tree errlen,
882 tree label_finish, gfc_expr* expr, int corank)
4376b7cf
FXC
883{
884 stmtblock_t alloc_block;
4f13e17f 885 tree tmp, null_mem, alloc, error;
4376b7cf 886 tree type = TREE_TYPE (mem);
3c9f5092 887 symbol_attribute caf_attr;
ba85c8c3
AV
888 bool need_assign = false, refs_comp = false;
889 gfc_coarray_regtype caf_alloc_type = GFC_CAF_COARRAY_ALLOC;
4376b7cf 890
107051a5 891 size = fold_convert (size_type_node, size);
9ef0b98e 892 null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
63ee5404 893 logical_type_node, mem,
ed9c79e1 894 build_int_cst (type, 0)),
7f7fa20f 895 PRED_FORTRAN_REALLOC);
4376b7cf 896
8f992d64
DC
897 /* If mem is NULL, we call gfc_allocate_using_malloc or
898 gfc_allocate_using_lib. */
4376b7cf 899 gfc_start_block (&alloc_block);
8f992d64 900
3c9f5092 901 if (flag_coarray == GFC_FCOARRAY_LIB)
ba85c8c3 902 caf_attr = gfc_caf_attr (expr, true, &refs_comp);
3c9f5092 903
f19626cf 904 if (flag_coarray == GFC_FCOARRAY_LIB
3c9f5092 905 && (corank > 0 || caf_attr.codimension))
5d81ddd0 906 {
ba85c8c3 907 tree cond, sub_caf_tree;
3c9f5092 908 gfc_se se;
ba85c8c3 909 bool compute_special_caf_types_size = false;
3c9f5092 910
ba85c8c3
AV
911 if (expr->ts.type == BT_DERIVED
912 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
913 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
914 {
915 compute_special_caf_types_size = true;
916 caf_alloc_type = GFC_CAF_LOCK_ALLOC;
917 }
918 else if (expr->ts.type == BT_DERIVED
919 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
920 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
921 {
922 compute_special_caf_types_size = true;
923 caf_alloc_type = GFC_CAF_EVENT_ALLOC;
924 }
925 else if (!caf_attr.coarray_comp && refs_comp)
926 /* Only allocatable components in a derived type coarray can be
927 allocate only. */
928 caf_alloc_type = GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY;
929
930 gfc_init_se (&se, NULL);
931 sub_caf_tree = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
3c9f5092
AV
932 if (sub_caf_tree == NULL_TREE)
933 sub_caf_tree = token;
934
935 /* When mem is an array ref, then strip the .data-ref. */
936 if (TREE_CODE (mem) == COMPONENT_REF
937 && !(GFC_ARRAY_TYPE_P (TREE_TYPE (mem))))
938 tmp = TREE_OPERAND (mem, 0);
939 else
940 tmp = mem;
941
942 if (!(GFC_ARRAY_TYPE_P (TREE_TYPE (tmp))
943 && TYPE_LANG_SPECIFIC (TREE_TYPE (tmp))->corank == 0)
944 && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
945 {
946 symbol_attribute attr;
947
948 gfc_clear_attr (&attr);
949 tmp = gfc_conv_scalar_to_descriptor (&se, mem, attr);
950 need_assign = true;
951 }
952 gfc_add_block_to_block (&alloc_block, &se.pre);
953
9f3880d1
TB
954 /* In the front end, we represent the lock variable as pointer. However,
955 the FE only passes the pointer around and leaves the actual
956 representation to the library. Hence, we have to convert back to the
957 number of elements. */
ba85c8c3 958 if (compute_special_caf_types_size)
9f3880d1
TB
959 size = fold_build2_loc (input_location, TRUNC_DIV_EXPR, size_type_node,
960 size, TYPE_SIZE_UNIT (ptr_type_node));
5d81ddd0 961
ba85c8c3
AV
962 gfc_allocate_using_caf_lib (&alloc_block, tmp, size, sub_caf_tree,
963 status, errmsg, errlen, caf_alloc_type);
3c9f5092
AV
964 if (need_assign)
965 gfc_add_modify (&alloc_block, mem, fold_convert (TREE_TYPE (mem),
966 gfc_conv_descriptor_data_get (tmp)));
5d81ddd0
TB
967 if (status != NULL_TREE)
968 {
969 TREE_USED (label_finish) = 1;
970 tmp = build1_v (GOTO_EXPR, label_finish);
63ee5404 971 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
5d81ddd0
TB
972 status, build_zero_cst (TREE_TYPE (status)));
973 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
ed9c79e1
JJ
974 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
975 tmp, build_empty_stmt (input_location));
5d81ddd0
TB
976 gfc_add_expr_to_block (&alloc_block, tmp);
977 }
978 }
8f992d64 979 else
4f13e17f 980 gfc_allocate_using_malloc (&alloc_block, mem, size, status);
ea6363a3 981
4376b7cf
FXC
982 alloc = gfc_finish_block (&alloc_block);
983
ea6363a3
DC
984 /* If mem is not NULL, we issue a runtime error or set the
985 status variable. */
f25a62a5
DK
986 if (expr)
987 {
988 tree varname;
989
990 gcc_assert (expr->expr_type == EXPR_VARIABLE && expr->symtree);
991 varname = gfc_build_cstring_const (expr->symtree->name);
992 varname = gfc_build_addr_expr (pchar_type_node, varname);
993
994 error = gfc_trans_runtime_error (true, &expr->where,
995 "Attempting to allocate already"
f8dde8af 996 " allocated variable '%s'",
f25a62a5
DK
997 varname);
998 }
999 else
1000 error = gfc_trans_runtime_error (true, NULL,
1001 "Attempting to allocate already allocated"
d8a07487 1002 " variable");
4376b7cf 1003
8f992d64 1004 if (status != NULL_TREE)
4376b7cf 1005 {
8f992d64 1006 tree status_type = TREE_TYPE (status);
4376b7cf 1007
4f13e17f
DC
1008 error = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1009 status, build_int_cst (status_type, LIBERROR_ALLOCATION));
4376b7cf
FXC
1010 }
1011
65a9ca82 1012 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem,
9ef0b98e 1013 error, alloc);
4376b7cf 1014 gfc_add_expr_to_block (block, tmp);
4376b7cf
FXC
1015}
1016
1529b8d9 1017
cd55d18e 1018/* Free a given variable. */
107051a5 1019
1529b8d9
FXC
1020tree
1021gfc_call_free (tree var)
1022{
cd55d18e 1023 return build_call_expr_loc (input_location,
e79983f4 1024 builtin_decl_explicit (BUILT_IN_FREE),
cd55d18e 1025 1, fold_convert (pvoid_type_node, var));
1529b8d9
FXC
1026}
1027
1028
ef292537
TB
1029/* Build a call to a FINAL procedure, which finalizes "var". */
1030
1031static tree
1032gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var,
1033 bool fini_coarray, gfc_expr *class_size)
1034{
1035 stmtblock_t block;
1036 gfc_se se;
1037 tree final_fndecl, array, size, tmp;
1038 symbol_attribute attr;
1039
1040 gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE);
1041 gcc_assert (var);
1042
45db6b0d 1043 gfc_start_block (&block);
ef292537
TB
1044 gfc_init_se (&se, NULL);
1045 gfc_conv_expr (&se, final_wrapper);
1046 final_fndecl = se.expr;
1047 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
1048 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
1049
1050 if (ts.type == BT_DERIVED)
1051 {
1052 tree elem_size;
1053
1054 gcc_assert (!class_size);
1055 elem_size = gfc_typenode_for_spec (&ts);
1056 elem_size = TYPE_SIZE_UNIT (elem_size);
1057 size = fold_convert (gfc_array_index_type, elem_size);
1058
1059 gfc_init_se (&se, NULL);
1060 se.want_pointer = 1;
1061 if (var->rank)
1062 {
1063 se.descriptor_only = 1;
1064 gfc_conv_expr_descriptor (&se, var);
1065 array = se.expr;
1066 }
1067 else
1068 {
1069 gfc_conv_expr (&se, var);
1070 gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
1071 array = se.expr;
1072
1073 /* No copy back needed, hence set attr's allocatable/pointer
1074 to zero. */
1075 gfc_clear_attr (&attr);
1076 gfc_init_se (&se, NULL);
1077 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1078 gcc_assert (se.post.head == NULL_TREE);
1079 }
1080 }
1081 else
1082 {
1083 gfc_expr *array_expr;
1084 gcc_assert (class_size);
1085 gfc_init_se (&se, NULL);
1086 gfc_conv_expr (&se, class_size);
2297c8ce
TB
1087 gfc_add_block_to_block (&block, &se.pre);
1088 gcc_assert (se.post.head == NULL_TREE);
ef292537
TB
1089 size = se.expr;
1090
1091 array_expr = gfc_copy_expr (var);
1092 gfc_init_se (&se, NULL);
1093 se.want_pointer = 1;
1094 if (array_expr->rank)
1095 {
1096 gfc_add_class_array_ref (array_expr);
1097 se.descriptor_only = 1;
1098 gfc_conv_expr_descriptor (&se, array_expr);
1099 array = se.expr;
1100 }
1101 else
1102 {
1103 gfc_add_data_component (array_expr);
1104 gfc_conv_expr (&se, array_expr);
2297c8ce
TB
1105 gfc_add_block_to_block (&block, &se.pre);
1106 gcc_assert (se.post.head == NULL_TREE);
ef292537 1107 array = se.expr;
ef292537
TB
1108
1109 if (!gfc_is_coarray (array_expr))
1110 {
1111 /* No copy back needed, hence set attr's allocatable/pointer
1112 to zero. */
1113 gfc_clear_attr (&attr);
1114 gfc_init_se (&se, NULL);
1115 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1116 }
1117 gcc_assert (se.post.head == NULL_TREE);
1118 }
1119 gfc_free_expr (array_expr);
1120 }
1121
1122 if (!POINTER_TYPE_P (TREE_TYPE (array)))
1123 array = gfc_build_addr_expr (NULL, array);
1124
ef292537
TB
1125 gfc_add_block_to_block (&block, &se.pre);
1126 tmp = build_call_expr_loc (input_location,
1127 final_fndecl, 3, array,
1128 size, fini_coarray ? boolean_true_node
1129 : boolean_false_node);
1130 gfc_add_block_to_block (&block, &se.post);
1131 gfc_add_expr_to_block (&block, tmp);
1132 return gfc_finish_block (&block);
1133}
1134
1135
895a0c2d
TB
1136bool
1137gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp,
1138 bool fini_coarray)
1139{
1140 gfc_se se;
1141 stmtblock_t block2;
1142 tree final_fndecl, size, array, tmp, cond;
1143 symbol_attribute attr;
1144 gfc_expr *final_expr = NULL;
1145
1146 if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS)
1147 return false;
1148
1149 gfc_init_block (&block2);
1150
1151 if (comp->ts.type == BT_DERIVED)
1152 {
1153 if (comp->attr.pointer)
1154 return false;
1155
1156 gfc_is_finalizable (comp->ts.u.derived, &final_expr);
1157 if (!final_expr)
1158 return false;
1159
1160 gfc_init_se (&se, NULL);
1161 gfc_conv_expr (&se, final_expr);
1162 final_fndecl = se.expr;
1163 size = gfc_typenode_for_spec (&comp->ts);
1164 size = TYPE_SIZE_UNIT (size);
1165 size = fold_convert (gfc_array_index_type, size);
1166
1167 array = decl;
1168 }
1169 else /* comp->ts.type == BT_CLASS. */
1170 {
1171 if (CLASS_DATA (comp)->attr.class_pointer)
1172 return false;
1173
1174 gfc_is_finalizable (CLASS_DATA (comp)->ts.u.derived, &final_expr);
34d9d749
AV
1175 final_fndecl = gfc_class_vtab_final_get (decl);
1176 size = gfc_class_vtab_size_get (decl);
895a0c2d
TB
1177 array = gfc_class_data_get (decl);
1178 }
1179
1180 if (comp->attr.allocatable
1181 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)->attr.allocatable))
1182 {
1183 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))
1184 ? gfc_conv_descriptor_data_get (array) : array;
63ee5404 1185 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
895a0c2d
TB
1186 tmp, fold_convert (TREE_TYPE (tmp),
1187 null_pointer_node));
1188 }
1189 else
63ee5404 1190 cond = logical_true_node;
895a0c2d
TB
1191
1192 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array)))
1193 {
1194 gfc_clear_attr (&attr);
1195 gfc_init_se (&se, NULL);
1196 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1197 gfc_add_block_to_block (&block2, &se.pre);
1198 gcc_assert (se.post.head == NULL_TREE);
1199 }
1200
1201 if (!POINTER_TYPE_P (TREE_TYPE (array)))
1202 array = gfc_build_addr_expr (NULL, array);
1203
1204 if (!final_expr)
1205 {
63ee5404 1206 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
895a0c2d
TB
1207 final_fndecl,
1208 fold_convert (TREE_TYPE (final_fndecl),
1209 null_pointer_node));
1210 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
63ee5404 1211 logical_type_node, cond, tmp);
895a0c2d
TB
1212 }
1213
1214 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
1215 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
1216
1217 tmp = build_call_expr_loc (input_location,
1218 final_fndecl, 3, array,
1219 size, fini_coarray ? boolean_true_node
1220 : boolean_false_node);
1221 gfc_add_expr_to_block (&block2, tmp);
1222 tmp = gfc_finish_block (&block2);
1223
1224 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
1225 build_empty_stmt (input_location));
1226 gfc_add_expr_to_block (block, tmp);
1227
1228 return true;
1229}
1230
1231
ef292537
TB
1232/* Add a call to the finalizer, using the passed *expr. Returns
1233 true when a finalizer call has been inserted. */
1234
1235bool
1236gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2)
1237{
1238 tree tmp;
1239 gfc_ref *ref;
1240 gfc_expr *expr;
1241 gfc_expr *final_expr = NULL;
1242 gfc_expr *elem_size = NULL;
1243 bool has_finalizer = false;
1244
1245 if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS))
1246 return false;
1247
1248 if (expr2->ts.type == BT_DERIVED)
1249 {
1250 gfc_is_finalizable (expr2->ts.u.derived, &final_expr);
1251 if (!final_expr)
1252 return false;
1253 }
1254
1255 /* If we have a class array, we need go back to the class
1cc0e193 1256 container. */
ef292537
TB
1257 expr = gfc_copy_expr (expr2);
1258
1259 if (expr->ref && expr->ref->next && !expr->ref->next->next
1260 && expr->ref->next->type == REF_ARRAY
1261 && expr->ref->type == REF_COMPONENT
1262 && strcmp (expr->ref->u.c.component->name, "_data") == 0)
1263 {
1264 gfc_free_ref_list (expr->ref);
1265 expr->ref = NULL;
1266 }
1267 else
1268 for (ref = expr->ref; ref; ref = ref->next)
1269 if (ref->next && ref->next->next && !ref->next->next->next
1270 && ref->next->next->type == REF_ARRAY
1271 && ref->next->type == REF_COMPONENT
1272 && strcmp (ref->next->u.c.component->name, "_data") == 0)
1273 {
1274 gfc_free_ref_list (ref->next);
1275 ref->next = NULL;
1276 }
1277
1278 if (expr->ts.type == BT_CLASS)
1279 {
1280 has_finalizer = gfc_is_finalizable (expr->ts.u.derived, NULL);
1281
1282 if (!expr2->rank && !expr2->ref && CLASS_DATA (expr2->symtree->n.sym)->as)
1283 expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank;
1284
1285 final_expr = gfc_copy_expr (expr);
1286 gfc_add_vptr_component (final_expr);
d42844f1 1287 gfc_add_final_component (final_expr);
ef292537
TB
1288
1289 elem_size = gfc_copy_expr (expr);
1290 gfc_add_vptr_component (elem_size);
d42844f1 1291 gfc_add_size_component (elem_size);
ef292537
TB
1292 }
1293
1294 gcc_assert (final_expr->expr_type == EXPR_VARIABLE);
1295
1296 tmp = gfc_build_final_call (expr->ts, final_expr, expr,
1297 false, elem_size);
1298
1299 if (expr->ts.type == BT_CLASS && !has_finalizer)
1300 {
1301 tree cond;
1302 gfc_se se;
1303
1304 gfc_init_se (&se, NULL);
1305 se.want_pointer = 1;
1306 gfc_conv_expr (&se, final_expr);
63ee5404 1307 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
ef292537
TB
1308 se.expr, build_int_cst (TREE_TYPE (se.expr), 0));
1309
1310 /* For CLASS(*) not only sym->_vtab->_final can be NULL
1311 but already sym->_vtab itself. */
1312 if (UNLIMITED_POLY (expr))
1313 {
1314 tree cond2;
1315 gfc_expr *vptr_expr;
1316
1317 vptr_expr = gfc_copy_expr (expr);
1318 gfc_add_vptr_component (vptr_expr);
1319
1320 gfc_init_se (&se, NULL);
1321 se.want_pointer = 1;
1322 gfc_conv_expr (&se, vptr_expr);
1323 gfc_free_expr (vptr_expr);
1324
63ee5404 1325 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
ef292537
TB
1326 se.expr,
1327 build_int_cst (TREE_TYPE (se.expr), 0));
1328 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
63ee5404 1329 logical_type_node, cond2, cond);
ef292537
TB
1330 }
1331
1332 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1333 cond, tmp, build_empty_stmt (input_location));
1334 }
1335
1336 gfc_add_expr_to_block (block, tmp);
1337
1338 return true;
1339}
1340
4376b7cf
FXC
1341
1342/* User-deallocate; we emit the code directly from the front-end, and the
1343 logic is the same as the previous library function:
1344
1345 void
1346 deallocate (void *pointer, GFC_INTEGER_4 * stat)
1347 {
1348 if (!pointer)
1349 {
1350 if (stat)
1351 *stat = 1;
1352 else
1353 runtime_error ("Attempt to DEALLOCATE unallocated memory.");
1354 }
1355 else
1356 {
1357 free (pointer);
1358 if (stat)
1359 *stat = 0;
1360 }
1361 }
1362
7999d7b4
TK
1363 In this front-end version, status doesn't have to be GFC_INTEGER_4.
1364 Moreover, if CAN_FAIL is true, then we will not emit a runtime error,
1365 even when no status variable is passed to us (this is used for
1366 unconditional deallocation generated by the front-end at end of
1367 each procedure).
8b704316 1368
f25a62a5 1369 If a runtime-message is possible, `expr' must point to the original
5d81ddd0
TB
1370 expression being deallocated for its locus and variable name.
1371
1372 For coarrays, "pointer" must be the array descriptor and not its
ba85c8c3
AV
1373 "data" component.
1374
1375 COARRAY_DEALLOC_MODE gives the mode unregister coarrays. Available modes are
1376 the ones of GFC_CAF_DEREGTYPE, -1 when the mode for deregistration is to be
1377 analyzed and set by this routine, and -2 to indicate that a non-coarray is to
1378 be deallocated. */
4376b7cf 1379tree
5d81ddd0
TB
1380gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
1381 tree errlen, tree label_finish,
ba85c8c3 1382 bool can_fail, gfc_expr* expr,
39da5866
AV
1383 int coarray_dealloc_mode, tree add_when_allocated,
1384 tree caf_token)
4376b7cf
FXC
1385{
1386 stmtblock_t null, non_null;
f25a62a5 1387 tree cond, tmp, error;
5d81ddd0 1388 tree status_type = NULL_TREE;
39da5866 1389 tree token = NULL_TREE;
ba85c8c3 1390 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
5d81ddd0 1391
ba85c8c3 1392 if (coarray_dealloc_mode >= GFC_CAF_COARRAY_ANALYZE)
5d81ddd0 1393 {
39da5866 1394 if (flag_coarray == GFC_FCOARRAY_LIB)
ba85c8c3 1395 {
39da5866
AV
1396 if (caf_token)
1397 token = caf_token;
1398 else
1399 {
1400 tree caf_type, caf_decl = pointer;
1401 pointer = gfc_conv_descriptor_data_get (caf_decl);
1402 caf_type = TREE_TYPE (caf_decl);
1403 STRIP_NOPS (pointer);
de91486c 1404 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
39da5866
AV
1405 token = gfc_conv_descriptor_token (caf_decl);
1406 else if (DECL_LANG_SPECIFIC (caf_decl)
1407 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1408 token = GFC_DECL_TOKEN (caf_decl);
1409 else
1410 {
1411 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
1412 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type)
1413 != NULL_TREE);
1414 token = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
1415 }
1416 }
1417
1418 if (coarray_dealloc_mode == GFC_CAF_COARRAY_ANALYZE)
1419 {
1420 bool comp_ref;
1421 if (expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
1422 && comp_ref)
1423 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
1424 // else do a deregister as set by default.
1425 }
1426 else
1427 caf_dereg_type = (enum gfc_coarray_deregtype) coarray_dealloc_mode;
ba85c8c3 1428 }
39da5866
AV
1429 else if (flag_coarray == GFC_FCOARRAY_SINGLE)
1430 pointer = gfc_conv_descriptor_data_get (pointer);
5d81ddd0 1431 }
39da5866
AV
1432 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
1433 pointer = gfc_conv_descriptor_data_get (pointer);
4376b7cf 1434
63ee5404 1435 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
65a9ca82 1436 build_int_cst (TREE_TYPE (pointer), 0));
4376b7cf
FXC
1437
1438 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1439 we emit a runtime error. */
1440 gfc_start_block (&null);
1441 if (!can_fail)
1442 {
f25a62a5
DK
1443 tree varname;
1444
1445 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1446
1447 varname = gfc_build_cstring_const (expr->symtree->name);
1448 varname = gfc_build_addr_expr (pchar_type_node, varname);
1449
1450 error = gfc_trans_runtime_error (true, &expr->where,
1451 "Attempt to DEALLOCATE unallocated '%s'",
1452 varname);
4376b7cf
FXC
1453 }
1454 else
c2255bc4 1455 error = build_empty_stmt (input_location);
4376b7cf
FXC
1456
1457 if (status != NULL_TREE && !integer_zerop (status))
1458 {
4376b7cf
FXC
1459 tree cond2;
1460
5d81ddd0 1461 status_type = TREE_TYPE (TREE_TYPE (status));
63ee5404 1462 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
65a9ca82
TB
1463 status, build_int_cst (TREE_TYPE (status), 0));
1464 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1465 fold_build1_loc (input_location, INDIRECT_REF,
1466 status_type, status),
1467 build_int_cst (status_type, 1));
1468 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1469 cond2, tmp, error);
4376b7cf
FXC
1470 }
1471
1472 gfc_add_expr_to_block (&null, error);
1473
1474 /* When POINTER is not NULL, we free it. */
1475 gfc_start_block (&non_null);
39da5866
AV
1476 if (add_when_allocated)
1477 gfc_add_expr_to_block (&non_null, add_when_allocated);
ef292537 1478 gfc_add_finalizer_call (&non_null, expr);
ba85c8c3
AV
1479 if (coarray_dealloc_mode == GFC_CAF_COARRAY_NOCOARRAY
1480 || flag_coarray != GFC_FCOARRAY_LIB)
5d81ddd0
TB
1481 {
1482 tmp = build_call_expr_loc (input_location,
1483 builtin_decl_explicit (BUILT_IN_FREE), 1,
1484 fold_convert (pvoid_type_node, pointer));
1485 gfc_add_expr_to_block (&non_null, tmp);
39da5866
AV
1486 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
1487 0));
2c807128 1488
5d81ddd0
TB
1489 if (status != NULL_TREE && !integer_zerop (status))
1490 {
1491 /* We set STATUS to zero if it is present. */
1492 tree status_type = TREE_TYPE (TREE_TYPE (status));
1493 tree cond2;
1494
63ee5404 1495 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
5d81ddd0
TB
1496 status,
1497 build_int_cst (TREE_TYPE (status), 0));
1498 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1499 fold_build1_loc (input_location, INDIRECT_REF,
1500 status_type, status),
1501 build_int_cst (status_type, 0));
1502 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
ed9c79e1
JJ
1503 gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC),
1504 tmp, build_empty_stmt (input_location));
5d81ddd0
TB
1505 gfc_add_expr_to_block (&non_null, tmp);
1506 }
1507 }
1508 else
2c807128 1509 {
39da5866 1510 tree cond2, pstat = null_pointer_node;
2c807128 1511
5d81ddd0
TB
1512 if (errmsg == NULL_TREE)
1513 {
1514 gcc_assert (errlen == NULL_TREE);
1515 errmsg = null_pointer_node;
1516 errlen = build_zero_cst (integer_type_node);
1517 }
1518 else
1519 {
1520 gcc_assert (errlen != NULL_TREE);
1521 if (!POINTER_TYPE_P (TREE_TYPE (errmsg)))
1522 errmsg = gfc_build_addr_expr (NULL_TREE, errmsg);
1523 }
1524
5d81ddd0
TB
1525 if (status != NULL_TREE && !integer_zerop (status))
1526 {
1527 gcc_assert (status_type == integer_type_node);
1528 pstat = status;
1529 }
1530
5d81ddd0 1531 token = gfc_build_addr_expr (NULL_TREE, token);
ba85c8c3 1532 gcc_assert (caf_dereg_type > GFC_CAF_COARRAY_ANALYZE);
5d81ddd0 1533 tmp = build_call_expr_loc (input_location,
ba85c8c3
AV
1534 gfor_fndecl_caf_deregister, 5,
1535 token, build_int_cst (integer_type_node,
1536 caf_dereg_type),
1537 pstat, errmsg, errlen);
2c807128 1538 gfc_add_expr_to_block (&non_null, tmp);
5d81ddd0 1539
985f6c79
TB
1540 /* It guarantees memory consistency within the same segment */
1541 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1542 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1543 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1544 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1545 ASM_VOLATILE_P (tmp) = 1;
1546 gfc_add_expr_to_block (&non_null, tmp);
1547
5d81ddd0
TB
1548 if (status != NULL_TREE)
1549 {
1550 tree stat = build_fold_indirect_ref_loc (input_location, status);
39da5866
AV
1551 tree nullify = fold_build2_loc (input_location, MODIFY_EXPR,
1552 void_type_node, pointer,
1553 build_int_cst (TREE_TYPE (pointer),
1554 0));
5d81ddd0
TB
1555
1556 TREE_USED (label_finish) = 1;
1557 tmp = build1_v (GOTO_EXPR, label_finish);
63ee5404 1558 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
5d81ddd0
TB
1559 stat, build_zero_cst (TREE_TYPE (stat)));
1560 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
7f7fa20f 1561 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
39da5866 1562 tmp, nullify);
5d81ddd0
TB
1563 gfc_add_expr_to_block (&non_null, tmp);
1564 }
39da5866
AV
1565 else
1566 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
1567 0));
2c807128
JW
1568 }
1569
1570 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
1571 gfc_finish_block (&null),
1572 gfc_finish_block (&non_null));
1573}
1574
1575
1576/* Generate code for deallocation of allocatable scalars (variables or
1577 components). Before the object itself is freed, any allocatable
1578 subcomponents are being deallocated. */
1579
1580tree
ba85c8c3
AV
1581gfc_deallocate_scalar_with_status (tree pointer, tree status, tree label_finish,
1582 bool can_fail, gfc_expr* expr,
1583 gfc_typespec ts, bool coarray)
2c807128
JW
1584{
1585 stmtblock_t null, non_null;
1586 tree cond, tmp, error;
ba85c8c3
AV
1587 bool finalizable, comp_ref;
1588 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
1589
1590 if (coarray && expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
1591 && comp_ref)
1592 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
2c807128 1593
63ee5404 1594 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
2c807128
JW
1595 build_int_cst (TREE_TYPE (pointer), 0));
1596
1597 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1598 we emit a runtime error. */
1599 gfc_start_block (&null);
1600 if (!can_fail)
1601 {
1602 tree varname;
1603
1604 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1605
1606 varname = gfc_build_cstring_const (expr->symtree->name);
1607 varname = gfc_build_addr_expr (pchar_type_node, varname);
1608
1609 error = gfc_trans_runtime_error (true, &expr->where,
1610 "Attempt to DEALLOCATE unallocated '%s'",
1611 varname);
1612 }
1613 else
1614 error = build_empty_stmt (input_location);
1615
1616 if (status != NULL_TREE && !integer_zerop (status))
1617 {
1618 tree status_type = TREE_TYPE (TREE_TYPE (status));
1619 tree cond2;
1620
63ee5404 1621 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
2c807128
JW
1622 status, build_int_cst (TREE_TYPE (status), 0));
1623 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1624 fold_build1_loc (input_location, INDIRECT_REF,
1625 status_type, status),
1626 build_int_cst (status_type, 1));
1627 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1628 cond2, tmp, error);
1629 }
2c807128
JW
1630 gfc_add_expr_to_block (&null, error);
1631
1632 /* When POINTER is not NULL, we free it. */
1633 gfc_start_block (&non_null);
8b704316 1634
2c807128 1635 /* Free allocatable components. */
ef292537
TB
1636 finalizable = gfc_add_finalizer_call (&non_null, expr);
1637 if (!finalizable && ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
2c807128 1638 {
39da5866
AV
1639 int caf_mode = coarray
1640 ? ((caf_dereg_type == GFC_CAF_COARRAY_DEALLOCATE_ONLY
1641 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0)
1642 | GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
1643 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY)
1644 : 0;
1645 if (coarray && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
ba85c8c3
AV
1646 tmp = gfc_conv_descriptor_data_get (pointer);
1647 else
1648 tmp = build_fold_indirect_ref_loc (input_location, pointer);
39da5866 1649 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0, caf_mode);
2c807128
JW
1650 gfc_add_expr_to_block (&non_null, tmp);
1651 }
8b704316 1652
de91486c 1653 if (!coarray || flag_coarray == GFC_FCOARRAY_SINGLE)
ba85c8c3
AV
1654 {
1655 tmp = build_call_expr_loc (input_location,
1656 builtin_decl_explicit (BUILT_IN_FREE), 1,
1657 fold_convert (pvoid_type_node, pointer));
1658 gfc_add_expr_to_block (&non_null, tmp);
4376b7cf 1659
ba85c8c3
AV
1660 if (status != NULL_TREE && !integer_zerop (status))
1661 {
1662 /* We set STATUS to zero if it is present. */
1663 tree status_type = TREE_TYPE (TREE_TYPE (status));
1664 tree cond2;
1665
63ee5404 1666 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
ba85c8c3
AV
1667 status,
1668 build_int_cst (TREE_TYPE (status), 0));
1669 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1670 fold_build1_loc (input_location, INDIRECT_REF,
1671 status_type, status),
1672 build_int_cst (status_type, 0));
1673 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1674 cond2, tmp, build_empty_stmt (input_location));
1675 gfc_add_expr_to_block (&non_null, tmp);
1676 }
1677 }
1678 else
4376b7cf 1679 {
ba85c8c3
AV
1680 tree token;
1681 tree pstat = null_pointer_node;
1682 gfc_se se;
4376b7cf 1683
ba85c8c3
AV
1684 gfc_init_se (&se, NULL);
1685 token = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
1686 gcc_assert (token != NULL_TREE);
1687
1688 if (status != NULL_TREE && !integer_zerop (status))
1689 {
1690 gcc_assert (TREE_TYPE (TREE_TYPE (status)) == integer_type_node);
1691 pstat = status;
1692 }
1693
1694 tmp = build_call_expr_loc (input_location,
1695 gfor_fndecl_caf_deregister, 5,
1696 token, build_int_cst (integer_type_node,
1697 caf_dereg_type),
1698 pstat, null_pointer_node, integer_zero_node);
1699 gfc_add_expr_to_block (&non_null, tmp);
1700
1701 /* It guarantees memory consistency within the same segment. */
39da5866 1702 tmp = gfc_build_string_const (strlen ("memory")+1, "memory");
ba85c8c3
AV
1703 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1704 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1705 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1706 ASM_VOLATILE_P (tmp) = 1;
4376b7cf 1707 gfc_add_expr_to_block (&non_null, tmp);
ba85c8c3
AV
1708
1709 if (status != NULL_TREE)
1710 {
1711 tree stat = build_fold_indirect_ref_loc (input_location, status);
1712 tree cond2;
1713
1714 TREE_USED (label_finish) = 1;
1715 tmp = build1_v (GOTO_EXPR, label_finish);
63ee5404 1716 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
ba85c8c3
AV
1717 stat, build_zero_cst (TREE_TYPE (stat)));
1718 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1719 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
1720 tmp, build_empty_stmt (input_location));
1721 gfc_add_expr_to_block (&non_null, tmp);
1722 }
4376b7cf
FXC
1723 }
1724
65a9ca82
TB
1725 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
1726 gfc_finish_block (&null),
1727 gfc_finish_block (&non_null));
4376b7cf
FXC
1728}
1729
4376b7cf
FXC
1730/* Reallocate MEM so it has SIZE bytes of data. This behaves like the
1731 following pseudo-code:
1732
1733void *
1734internal_realloc (void *mem, size_t size)
1735{
28762eb0
FXC
1736 res = realloc (mem, size);
1737 if (!res && size != 0)
bd085c20 1738 _gfortran_os_error ("Allocation would exceed memory limit");
4376b7cf 1739
28762eb0 1740 return res;
4376b7cf
FXC
1741} */
1742tree
1743gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
1744{
d74a8b05 1745 tree res, nonzero, null_result, tmp;
4376b7cf
FXC
1746 tree type = TREE_TYPE (mem);
1747
107051a5
FXC
1748 /* Only evaluate the size once. */
1749 size = save_expr (fold_convert (size_type_node, size));
4376b7cf
FXC
1750
1751 /* Create a variable to hold the result. */
1752 res = gfc_create_var (type, NULL);
1753
4376b7cf 1754 /* Call realloc and check the result. */
db3927fb 1755 tmp = build_call_expr_loc (input_location,
e79983f4 1756 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
4376b7cf 1757 fold_convert (pvoid_type_node, mem), size);
726a989a 1758 gfc_add_modify (block, res, fold_convert (type, tmp));
63ee5404 1759 null_result = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
65a9ca82 1760 res, build_int_cst (pvoid_type_node, 0));
63ee5404 1761 nonzero = fold_build2_loc (input_location, NE_EXPR, logical_type_node, size,
65a9ca82 1762 build_int_cst (size_type_node, 0));
63ee5404 1763 null_result = fold_build2_loc (input_location, TRUTH_AND_EXPR, logical_type_node,
65a9ca82 1764 null_result, nonzero);
65a9ca82
TB
1765 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1766 null_result,
d74a8b05
JB
1767 trans_os_error_at (NULL,
1768 "Error reallocating to %lu bytes",
1769 fold_convert
1770 (long_unsigned_type_node, size)),
65a9ca82 1771 build_empty_stmt (input_location));
4376b7cf
FXC
1772 gfc_add_expr_to_block (block, tmp);
1773
4376b7cf
FXC
1774 return res;
1775}
1776
6de9cd9a 1777
0019d498 1778/* Add an expression to another one, either at the front or the back. */
6de9cd9a 1779
0019d498
DK
1780static void
1781add_expr_to_chain (tree* chain, tree expr, bool front)
1782{
6de9cd9a
DN
1783 if (expr == NULL_TREE || IS_EMPTY_STMT (expr))
1784 return;
1785
0019d498 1786 if (*chain)
7c87eac6 1787 {
0019d498 1788 if (TREE_CODE (*chain) != STATEMENT_LIST)
7c87eac6
PB
1789 {
1790 tree tmp;
1791
0019d498
DK
1792 tmp = *chain;
1793 *chain = NULL_TREE;
1794 append_to_statement_list (tmp, chain);
7c87eac6 1795 }
0019d498
DK
1796
1797 if (front)
1798 {
1799 tree_stmt_iterator i;
1800
1801 i = tsi_start (*chain);
1802 tsi_link_before (&i, expr, TSI_CONTINUE_LINKING);
1803 }
1804 else
1805 append_to_statement_list (expr, chain);
7c87eac6 1806 }
6de9cd9a 1807 else
0019d498
DK
1808 *chain = expr;
1809}
1810
46b2c440
MM
1811
1812/* Add a statement at the end of a block. */
0019d498
DK
1813
1814void
1815gfc_add_expr_to_block (stmtblock_t * block, tree expr)
1816{
1817 gcc_assert (block);
1818 add_expr_to_chain (&block->head, expr, false);
6de9cd9a
DN
1819}
1820
1821
46b2c440
MM
1822/* Add a statement at the beginning of a block. */
1823
1824void
1825gfc_prepend_expr_to_block (stmtblock_t * block, tree expr)
1826{
1827 gcc_assert (block);
1828 add_expr_to_chain (&block->head, expr, true);
1829}
1830
1831
6de9cd9a
DN
1832/* Add a block the end of a block. */
1833
1834void
1835gfc_add_block_to_block (stmtblock_t * block, stmtblock_t * append)
1836{
6e45f57b
PB
1837 gcc_assert (append);
1838 gcc_assert (!append->has_scope);
6de9cd9a
DN
1839
1840 gfc_add_expr_to_block (block, append->head);
1841 append->head = NULL_TREE;
1842}
1843
1844
363aab21
MM
1845/* Save the current locus. The structure may not be complete, and should
1846 only be used with gfc_restore_backend_locus. */
6de9cd9a
DN
1847
1848void
363aab21 1849gfc_save_backend_locus (locus * loc)
6de9cd9a 1850{
ece3f663 1851 loc->lb = XCNEW (gfc_linebuf);
8e400578 1852 loc->lb->location = input_location;
d4fa05b9 1853 loc->lb->file = gfc_current_backend_file;
6de9cd9a
DN
1854}
1855
1856
1857/* Set the current locus. */
1858
1859void
1860gfc_set_backend_locus (locus * loc)
1861{
d4fa05b9 1862 gfc_current_backend_file = loc->lb->file;
5677444f 1863 input_location = gfc_get_location (loc);
6de9cd9a
DN
1864}
1865
1866
6bd2c800 1867/* Restore the saved locus. Only used in conjunction with
363aab21
MM
1868 gfc_save_backend_locus, to free the memory when we are done. */
1869
1870void
1871gfc_restore_backend_locus (locus * loc)
1872{
5677444f
TS
1873 /* This only restores the information captured by gfc_save_backend_locus,
1874 intentionally does not use gfc_get_location. */
1875 input_location = loc->lb->location;
1876 gfc_current_backend_file = loc->lb->file;
cede9502 1877 free (loc->lb);
363aab21
MM
1878}
1879
1880
bc51e726
JD
1881/* Translate an executable statement. The tree cond is used by gfc_trans_do.
1882 This static function is wrapped by gfc_trans_code_cond and
1883 gfc_trans_code. */
6de9cd9a 1884
bc51e726
JD
1885static tree
1886trans_code (gfc_code * code, tree cond)
6de9cd9a
DN
1887{
1888 stmtblock_t block;
1889 tree res;
1890
1891 if (!code)
c2255bc4 1892 return build_empty_stmt (input_location);
6de9cd9a
DN
1893
1894 gfc_start_block (&block);
1895
726a989a 1896 /* Translate statements one by one into GENERIC trees until we reach
6de9cd9a
DN
1897 the end of this gfc_code branch. */
1898 for (; code; code = code->next)
1899 {
6de9cd9a
DN
1900 if (code->here != 0)
1901 {
1902 res = gfc_trans_label_here (code);
1903 gfc_add_expr_to_block (&block, res);
1904 }
1905
78ab5260 1906 gfc_current_locus = code->loc;
88e09c79
JJ
1907 gfc_set_backend_locus (&code->loc);
1908
6de9cd9a
DN
1909 switch (code->op)
1910 {
1911 case EXEC_NOP:
d80c695f 1912 case EXEC_END_BLOCK:
df1a69f6 1913 case EXEC_END_NESTED_BLOCK:
5c71a5e0 1914 case EXEC_END_PROCEDURE:
6de9cd9a
DN
1915 res = NULL_TREE;
1916 break;
1917
1918 case EXEC_ASSIGN:
574284e9 1919 res = gfc_trans_assign (code);
6de9cd9a
DN
1920 break;
1921
1922 case EXEC_LABEL_ASSIGN:
1923 res = gfc_trans_label_assign (code);
1924 break;
1925
1926 case EXEC_POINTER_ASSIGN:
574284e9 1927 res = gfc_trans_pointer_assign (code);
6de9cd9a
DN
1928 break;
1929
6b591ec0 1930 case EXEC_INIT_ASSIGN:
7adac79a 1931 if (code->expr1->ts.type == BT_CLASS)
b2a5eb75 1932 res = gfc_trans_class_init_assign (code);
7adac79a
JW
1933 else
1934 res = gfc_trans_init_assign (code);
6b591ec0
PT
1935 break;
1936
6de9cd9a
DN
1937 case EXEC_CONTINUE:
1938 res = NULL_TREE;
1939 break;
1940
d0a4a61c
TB
1941 case EXEC_CRITICAL:
1942 res = gfc_trans_critical (code);
1943 break;
1944
6de9cd9a
DN
1945 case EXEC_CYCLE:
1946 res = gfc_trans_cycle (code);
1947 break;
1948
1949 case EXEC_EXIT:
1950 res = gfc_trans_exit (code);
1951 break;
1952
1953 case EXEC_GOTO:
1954 res = gfc_trans_goto (code);
1955 break;
1956
3d79abbd
PB
1957 case EXEC_ENTRY:
1958 res = gfc_trans_entry (code);
1959 break;
1960
6de9cd9a
DN
1961 case EXEC_PAUSE:
1962 res = gfc_trans_pause (code);
1963 break;
1964
1965 case EXEC_STOP:
d0a4a61c
TB
1966 case EXEC_ERROR_STOP:
1967 res = gfc_trans_stop (code, code->op == EXEC_ERROR_STOP);
6de9cd9a
DN
1968 break;
1969
1970 case EXEC_CALL:
12f681a0
DK
1971 /* For MVBITS we've got the special exception that we need a
1972 dependency check, too. */
1973 {
1974 bool is_mvbits = false;
da661a58
TB
1975
1976 if (code->resolved_isym)
1977 {
1978 res = gfc_conv_intrinsic_subroutine (code);
1979 if (res != NULL_TREE)
1980 break;
1981 }
1982
12f681a0
DK
1983 if (code->resolved_isym
1984 && code->resolved_isym->id == GFC_ISYM_MVBITS)
1985 is_mvbits = true;
da661a58
TB
1986
1987 res = gfc_trans_call (code, is_mvbits, NULL_TREE,
1988 NULL_TREE, false);
12f681a0 1989 }
476220e7
PT
1990 break;
1991
713485cc 1992 case EXEC_CALL_PPC:
eb74e79b
PT
1993 res = gfc_trans_call (code, false, NULL_TREE,
1994 NULL_TREE, false);
713485cc
JW
1995 break;
1996
476220e7 1997 case EXEC_ASSIGN_CALL:
eb74e79b
PT
1998 res = gfc_trans_call (code, true, NULL_TREE,
1999 NULL_TREE, false);
6de9cd9a
DN
2000 break;
2001
2002 case EXEC_RETURN:
2003 res = gfc_trans_return (code);
2004 break;
2005
2006 case EXEC_IF:
2007 res = gfc_trans_if (code);
2008 break;
2009
2010 case EXEC_ARITHMETIC_IF:
2011 res = gfc_trans_arithmetic_if (code);
9abe5e56
DK
2012 break;
2013
2014 case EXEC_BLOCK:
2015 res = gfc_trans_block_construct (code);
6de9cd9a
DN
2016 break;
2017
2018 case EXEC_DO:
bc51e726 2019 res = gfc_trans_do (code, cond);
6de9cd9a
DN
2020 break;
2021
8c6a85e3
TB
2022 case EXEC_DO_CONCURRENT:
2023 res = gfc_trans_do_concurrent (code);
2024 break;
2025
6de9cd9a
DN
2026 case EXEC_DO_WHILE:
2027 res = gfc_trans_do_while (code);
2028 break;
2029
2030 case EXEC_SELECT:
2031 res = gfc_trans_select (code);
2032 break;
2033
cf2b3c22 2034 case EXEC_SELECT_TYPE:
dfd6231e 2035 res = gfc_trans_select_type (code);
cf2b3c22
TB
2036 break;
2037
70570ec1
PT
2038 case EXEC_SELECT_RANK:
2039 res = gfc_trans_select_rank (code);
2040 break;
2041
6403ec5f
JB
2042 case EXEC_FLUSH:
2043 res = gfc_trans_flush (code);
2044 break;
2045
d0a4a61c
TB
2046 case EXEC_SYNC_ALL:
2047 case EXEC_SYNC_IMAGES:
2048 case EXEC_SYNC_MEMORY:
2049 res = gfc_trans_sync (code, code->op);
2050 break;
2051
fea54935
TB
2052 case EXEC_LOCK:
2053 case EXEC_UNLOCK:
2054 res = gfc_trans_lock_unlock (code, code->op);
2055 break;
2056
5df445a2
TB
2057 case EXEC_EVENT_POST:
2058 case EXEC_EVENT_WAIT:
2059 res = gfc_trans_event_post_wait (code, code->op);
2060 break;
2061
ef78bc3c
AV
2062 case EXEC_FAIL_IMAGE:
2063 res = gfc_trans_fail_image (code);
2064 break;
2065
6de9cd9a
DN
2066 case EXEC_FORALL:
2067 res = gfc_trans_forall (code);
2068 break;
2069
f8862a1b
DR
2070 case EXEC_FORM_TEAM:
2071 res = gfc_trans_form_team (code);
2072 break;
2073
2074 case EXEC_CHANGE_TEAM:
2075 res = gfc_trans_change_team (code);
2076 break;
2077
2078 case EXEC_END_TEAM:
2079 res = gfc_trans_end_team (code);
2080 break;
2081
2082 case EXEC_SYNC_TEAM:
2083 res = gfc_trans_sync_team (code);
2084 break;
2085
6de9cd9a
DN
2086 case EXEC_WHERE:
2087 res = gfc_trans_where (code);
2088 break;
2089
2090 case EXEC_ALLOCATE:
2091 res = gfc_trans_allocate (code);
2092 break;
2093
2094 case EXEC_DEALLOCATE:
2095 res = gfc_trans_deallocate (code);
2096 break;
2097
2098 case EXEC_OPEN:
2099 res = gfc_trans_open (code);
2100 break;
2101
2102 case EXEC_CLOSE:
2103 res = gfc_trans_close (code);
2104 break;
2105
2106 case EXEC_READ:
2107 res = gfc_trans_read (code);
2108 break;
2109
2110 case EXEC_WRITE:
2111 res = gfc_trans_write (code);
2112 break;
2113
2114 case EXEC_IOLENGTH:
2115 res = gfc_trans_iolength (code);
2116 break;
2117
2118 case EXEC_BACKSPACE:
2119 res = gfc_trans_backspace (code);
2120 break;
2121
2122 case EXEC_ENDFILE:
2123 res = gfc_trans_endfile (code);
2124 break;
2125
2126 case EXEC_INQUIRE:
2127 res = gfc_trans_inquire (code);
2128 break;
2129
6f0f0b2e
JD
2130 case EXEC_WAIT:
2131 res = gfc_trans_wait (code);
2132 break;
2133
6de9cd9a
DN
2134 case EXEC_REWIND:
2135 res = gfc_trans_rewind (code);
2136 break;
2137
2138 case EXEC_TRANSFER:
2139 res = gfc_trans_transfer (code);
2140 break;
2141
2142 case EXEC_DT_END:
2143 res = gfc_trans_dt_end (code);
2144 break;
2145
6c7a4dfd
JJ
2146 case EXEC_OMP_ATOMIC:
2147 case EXEC_OMP_BARRIER:
dd2fc525
JJ
2148 case EXEC_OMP_CANCEL:
2149 case EXEC_OMP_CANCELLATION_POINT:
6c7a4dfd 2150 case EXEC_OMP_CRITICAL:
f014c653
JJ
2151 case EXEC_OMP_DISTRIBUTE:
2152 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
2153 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
2154 case EXEC_OMP_DISTRIBUTE_SIMD:
6c7a4dfd 2155 case EXEC_OMP_DO:
dd2fc525 2156 case EXEC_OMP_DO_SIMD:
6c7a4dfd
JJ
2157 case EXEC_OMP_FLUSH:
2158 case EXEC_OMP_MASTER:
2159 case EXEC_OMP_ORDERED:
2160 case EXEC_OMP_PARALLEL:
2161 case EXEC_OMP_PARALLEL_DO:
dd2fc525 2162 case EXEC_OMP_PARALLEL_DO_SIMD:
6c7a4dfd
JJ
2163 case EXEC_OMP_PARALLEL_SECTIONS:
2164 case EXEC_OMP_PARALLEL_WORKSHARE:
2165 case EXEC_OMP_SECTIONS:
dd2fc525 2166 case EXEC_OMP_SIMD:
6c7a4dfd 2167 case EXEC_OMP_SINGLE:
f014c653
JJ
2168 case EXEC_OMP_TARGET:
2169 case EXEC_OMP_TARGET_DATA:
b4c3a85b
JJ
2170 case EXEC_OMP_TARGET_ENTER_DATA:
2171 case EXEC_OMP_TARGET_EXIT_DATA:
2172 case EXEC_OMP_TARGET_PARALLEL:
2173 case EXEC_OMP_TARGET_PARALLEL_DO:
2174 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
2175 case EXEC_OMP_TARGET_SIMD:
f014c653
JJ
2176 case EXEC_OMP_TARGET_TEAMS:
2177 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
2178 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
2179 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2180 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
2181 case EXEC_OMP_TARGET_UPDATE:
a68ab351 2182 case EXEC_OMP_TASK:
dd2fc525 2183 case EXEC_OMP_TASKGROUP:
b4c3a85b
JJ
2184 case EXEC_OMP_TASKLOOP:
2185 case EXEC_OMP_TASKLOOP_SIMD:
a68ab351 2186 case EXEC_OMP_TASKWAIT:
20906c66 2187 case EXEC_OMP_TASKYIELD:
f014c653
JJ
2188 case EXEC_OMP_TEAMS:
2189 case EXEC_OMP_TEAMS_DISTRIBUTE:
2190 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
2191 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2192 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
6c7a4dfd
JJ
2193 case EXEC_OMP_WORKSHARE:
2194 res = gfc_trans_omp_directive (code);
2195 break;
2196
41dbbb37
TS
2197 case EXEC_OACC_CACHE:
2198 case EXEC_OACC_WAIT:
2199 case EXEC_OACC_UPDATE:
2200 case EXEC_OACC_LOOP:
2201 case EXEC_OACC_HOST_DATA:
2202 case EXEC_OACC_DATA:
2203 case EXEC_OACC_KERNELS:
2204 case EXEC_OACC_KERNELS_LOOP:
2205 case EXEC_OACC_PARALLEL:
2206 case EXEC_OACC_PARALLEL_LOOP:
62aee289
MR
2207 case EXEC_OACC_SERIAL:
2208 case EXEC_OACC_SERIAL_LOOP:
41dbbb37
TS
2209 case EXEC_OACC_ENTER_DATA:
2210 case EXEC_OACC_EXIT_DATA:
4bf9e5a8 2211 case EXEC_OACC_ATOMIC:
dc7a8b4b 2212 case EXEC_OACC_DECLARE:
41dbbb37
TS
2213 res = gfc_trans_oacc_directive (code);
2214 break;
2215
6de9cd9a 2216 default:
17d5d49f 2217 gfc_internal_error ("gfc_trans_code(): Bad statement code");
6de9cd9a
DN
2218 }
2219
bf737879
TS
2220 gfc_set_backend_locus (&code->loc);
2221
6de9cd9a
DN
2222 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
2223 {
60f5ed26 2224 if (TREE_CODE (res) != STATEMENT_LIST)
c8cc8542 2225 SET_EXPR_LOCATION (res, input_location);
8b704316 2226
bf737879 2227 /* Add the new statement to the block. */
6de9cd9a
DN
2228 gfc_add_expr_to_block (&block, res);
2229 }
2230 }
2231
2232 /* Return the finished block. */
2233 return gfc_finish_block (&block);
2234}
2235
2236
bc51e726
JD
2237/* Translate an executable statement with condition, cond. The condition is
2238 used by gfc_trans_do to test for IO result conditions inside implied
2239 DO loops of READ and WRITE statements. See build_dt in trans-io.c. */
2240
2241tree
2242gfc_trans_code_cond (gfc_code * code, tree cond)
2243{
2244 return trans_code (code, cond);
2245}
2246
2247/* Translate an executable statement without condition. */
2248
2249tree
2250gfc_trans_code (gfc_code * code)
2251{
2252 return trans_code (code, NULL_TREE);
2253}
2254
2255
6de9cd9a
DN
2256/* This function is called after a complete program unit has been parsed
2257 and resolved. */
2258
2259void
2260gfc_generate_code (gfc_namespace * ns)
2261{
34d01e1d 2262 ompws_flags = 0;
0de4325e
TS
2263 if (ns->is_block_data)
2264 {
2265 gfc_generate_block_data (ns);
2266 return;
2267 }
2268
6de9cd9a
DN
2269 gfc_generate_function_code (ns);
2270}
2271
2272
2273/* This function is called after a complete module has been parsed
2274 and resolved. */
2275
2276void
2277gfc_generate_module_code (gfc_namespace * ns)
2278{
2279 gfc_namespace *n;
a64f5186
JJ
2280 struct module_htab_entry *entry;
2281
2282 gcc_assert (ns->proc_name->backend_decl == NULL);
2283 ns->proc_name->backend_decl
9c81750c 2284 = build_decl (gfc_get_location (&ns->proc_name->declared_at),
c2255bc4 2285 NAMESPACE_DECL, get_identifier (ns->proc_name->name),
a64f5186 2286 void_type_node);
a64f5186
JJ
2287 entry = gfc_find_module (ns->proc_name->name);
2288 if (entry->namespace_decl)
2289 /* Buggy sourcecode, using a module before defining it? */
2a22f99c 2290 entry->decls->empty ();
a64f5186 2291 entry->namespace_decl = ns->proc_name->backend_decl;
6de9cd9a
DN
2292
2293 gfc_generate_module_vars (ns);
2294
2295 /* We need to generate all module function prototypes first, to allow
2296 sibling calls. */
2297 for (n = ns->contained; n; n = n->sibling)
2298 {
a64f5186
JJ
2299 gfc_entry_list *el;
2300
6de9cd9a
DN
2301 if (!n->proc_name)
2302 continue;
2303
fb55ca75 2304 gfc_create_function_decl (n, false);
a64f5186
JJ
2305 DECL_CONTEXT (n->proc_name->backend_decl) = ns->proc_name->backend_decl;
2306 gfc_module_add_decl (entry, n->proc_name->backend_decl);
2307 for (el = ns->entries; el; el = el->next)
2308 {
a64f5186
JJ
2309 DECL_CONTEXT (el->sym->backend_decl) = ns->proc_name->backend_decl;
2310 gfc_module_add_decl (entry, el->sym->backend_decl);
2311 }
6de9cd9a
DN
2312 }
2313
2314 for (n = ns->contained; n; n = n->sibling)
2315 {
2316 if (!n->proc_name)
2317 continue;
2318
2319 gfc_generate_function_code (n);
2320 }
2321}
2322
0019d498
DK
2323
2324/* Initialize an init/cleanup block with existing code. */
2325
2326void
2327gfc_start_wrapped_block (gfc_wrapped_block* block, tree code)
2328{
2329 gcc_assert (block);
2330
2331 block->init = NULL_TREE;
2332 block->code = code;
2333 block->cleanup = NULL_TREE;
2334}
2335
2336
2337/* Add a new pair of initializers/clean-up code. */
2338
2339void
2340gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup)
2341{
2342 gcc_assert (block);
2343
2344 /* The new pair of init/cleanup should be "wrapped around" the existing
2345 block of code, thus the initialization is added to the front and the
2346 cleanup to the back. */
2347 add_expr_to_chain (&block->init, init, true);
2348 add_expr_to_chain (&block->cleanup, cleanup, false);
2349}
2350
2351
2352/* Finish up a wrapped block by building a corresponding try-finally expr. */
2353
2354tree
2355gfc_finish_wrapped_block (gfc_wrapped_block* block)
2356{
2357 tree result;
2358
2359 gcc_assert (block);
2360
2361 /* Build the final expression. For this, just add init and body together,
2362 and put clean-up with that into a TRY_FINALLY_EXPR. */
2363 result = block->init;
2364 add_expr_to_chain (&result, block->code, false);
2365 if (block->cleanup)
5d44e5c8
TB
2366 result = build2_loc (input_location, TRY_FINALLY_EXPR, void_type_node,
2367 result, block->cleanup);
8b704316 2368
0019d498
DK
2369 /* Clear the block. */
2370 block->init = NULL_TREE;
2371 block->code = NULL_TREE;
2372 block->cleanup = NULL_TREE;
2373
2374 return result;
2375}
5af07930
TB
2376
2377
2378/* Helper function for marking a boolean expression tree as unlikely. */
2379
2380tree
ed9c79e1 2381gfc_unlikely (tree cond, enum br_predictor predictor)
5af07930
TB
2382{
2383 tree tmp;
2384
ed9c79e1
JJ
2385 if (optimize)
2386 {
2387 cond = fold_convert (long_integer_type_node, cond);
2388 tmp = build_zero_cst (long_integer_type_node);
2389 cond = build_call_expr_loc (input_location,
2390 builtin_decl_explicit (BUILT_IN_EXPECT),
2391 3, cond, tmp,
2392 build_int_cst (integer_type_node,
2393 predictor));
2394 }
5af07930
TB
2395 return cond;
2396}
4f13e17f
DC
2397
2398
2399/* Helper function for marking a boolean expression tree as likely. */
2400
2401tree
ed9c79e1 2402gfc_likely (tree cond, enum br_predictor predictor)
4f13e17f
DC
2403{
2404 tree tmp;
2405
ed9c79e1
JJ
2406 if (optimize)
2407 {
2408 cond = fold_convert (long_integer_type_node, cond);
2409 tmp = build_one_cst (long_integer_type_node);
2410 cond = build_call_expr_loc (input_location,
2411 builtin_decl_explicit (BUILT_IN_EXPECT),
2412 3, cond, tmp,
2413 build_int_cst (integer_type_node,
2414 predictor));
2415 }
4f13e17f
DC
2416 return cond;
2417}
2b3dc0db
PT
2418
2419
2420/* Get the string length for a deferred character length component. */
2421
2422bool
2423gfc_deferred_strlen (gfc_component *c, tree *decl)
2424{
2425 char name[GFC_MAX_SYMBOL_LEN+9];
2426 gfc_component *strlen;
5bab4c96
PT
2427 if (!(c->ts.type == BT_CHARACTER
2428 && (c->ts.deferred || c->attr.pdt_string)))
2b3dc0db
PT
2429 return false;
2430 sprintf (name, "_%s_length", c->name);
2431 for (strlen = c; strlen; strlen = strlen->next)
2432 if (strcmp (strlen->name, name) == 0)
2433 break;
2434 *decl = strlen ? strlen->backend_decl : NULL_TREE;
2435 return strlen != NULL;
2436}