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