]> gcc.gnu.org Git - gcc.git/blame - gcc/fortran/trans.cc
Fortran: Fix bugs and missing features in finalization [PR37336]
[gcc.git] / gcc / fortran / trans.cc
CommitLineData
6de9cd9a 1/* Code translation -- generate GCC trees from gfc_code.
83ffe9cd 2 Copyright (C) 2002-2023 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
7964ab6c
MM
449/* Build an ARRAY_REF with its natural type.
450 NON_NEGATIVE_OFFSET indicates if it’s true that OFFSET can’t be negative,
451 and thus that an ARRAY_REF can safely be generated. If it’s false, we
452 have to play it safe and use pointer arithmetic. */
6de9cd9a
DN
453
454tree
7964ab6c
MM
455gfc_build_array_ref (tree base, tree offset, tree decl,
456 bool non_negative_offset, tree vptr)
6de9cd9a
DN
457{
458 tree type = TREE_TYPE (base);
ff3598bc 459 tree span = NULL_TREE;
1d6b7f39 460
4409de24
TB
461 if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0)
462 {
463 gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0);
464
8a5c4899 465 return fold_convert (TYPE_MAIN_VARIANT (type), base);
4409de24
TB
466 }
467
fef89628
MM
468 /* Scalar coarray, there is nothing to do. */
469 if (TREE_CODE (type) != ARRAY_TYPE)
470 {
471 gcc_assert (decl == NULL_TREE);
472 gcc_assert (integer_zerop (offset));
473 return base;
474 }
475
6de9cd9a
DN
476 type = TREE_TYPE (type);
477
478 if (DECL_P (base))
479 TREE_ADDRESSABLE (base) = 1;
480
31120e8f
RS
481 /* Strip NON_LVALUE_EXPR nodes. */
482 STRIP_TYPE_NOPS (offset);
483
ff3598bc
PT
484 /* If decl or vptr are non-null, pointer arithmetic for the array reference
485 is likely. Generate the 'span' for the array reference. */
486 if (vptr)
fcc4891d
PT
487 {
488 span = gfc_vptr_size_get (vptr);
489
490 /* Check if this is an unlimited polymorphic object carrying a character
491 payload. In this case, the 'len' field is non-zero. */
492 if (decl && GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
ce8dcc91 493 span = gfc_resize_class_size_with_len (NULL, decl, span);
fcc4891d 494 }
ff3598bc 495 else if (decl)
0a524296 496 span = get_array_span (type, decl);
c49ea23d 497
ff3598bc
PT
498 /* If a non-null span has been generated reference the element with
499 pointer arithmetic. */
500 if (span != NULL_TREE)
9a0e09f3 501 return gfc_build_spanned_array_ref (base, offset, span);
7964ab6c
MM
502 /* Else use a straightforward array reference if possible. */
503 else if (non_negative_offset)
5d44e5c8
TB
504 return build4_loc (input_location, ARRAY_REF, type, base, offset,
505 NULL_TREE, NULL_TREE);
7964ab6c
MM
506 /* Otherwise use pointer arithmetic. */
507 else
508 {
509 gcc_assert (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE);
510 tree min = NULL_TREE;
511 if (TYPE_DOMAIN (TREE_TYPE (base))
512 && !integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)))))
513 min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)));
514
515 tree zero_based_index
516 = min ? fold_build2_loc (input_location, MINUS_EXPR,
517 gfc_array_index_type,
518 fold_convert (gfc_array_index_type, offset),
519 fold_convert (gfc_array_index_type, min))
520 : fold_convert (gfc_array_index_type, offset);
521
522 tree elt_size = fold_convert (gfc_array_index_type,
523 TYPE_SIZE_UNIT (type));
524
525 tree offset_bytes = fold_build2_loc (input_location, MULT_EXPR,
526 gfc_array_index_type,
527 zero_based_index, elt_size);
528
529 tree base_addr = gfc_build_addr_expr (pvoid_type_node, base);
530
531 tree ptr = fold_build_pointer_plus_loc (input_location, base_addr,
532 offset_bytes);
533 return build1_loc (input_location, INDIRECT_REF, type,
534 fold_convert (build_pointer_type (type), ptr));
535 }
6de9cd9a
DN
536}
537
538
f25a62a5
DK
539/* Generate a call to print a runtime error possibly including multiple
540 arguments and a locus. */
6de9cd9a 541
55bd9c35 542static tree
d74a8b05 543trans_runtime_error_vararg (tree errorfunc, locus* where, const char* msgid,
55bd9c35 544 va_list ap)
f25a62a5 545{
6de9cd9a 546 stmtblock_t block;
6de9cd9a 547 tree tmp;
f96d606f 548 tree arg, arg2;
c8fe94c7
FXC
549 tree *argarray;
550 tree fntype;
f96d606f 551 char *message;
c8fe94c7
FXC
552 const char *p;
553 int line, nargs, i;
55bd9c35 554 location_t loc;
6de9cd9a 555
c8fe94c7
FXC
556 /* Compute the number of extra arguments from the format string. */
557 for (p = msgid, nargs = 0; *p; p++)
558 if (*p == '%')
559 {
560 p++;
561 if (*p != '%')
562 nargs++;
563 }
564
6de9cd9a
DN
565 /* The code to generate the error. */
566 gfc_start_block (&block);
567
dd18a33b
FXC
568 if (where)
569 {
dd18a33b 570 line = LOCATION_LINE (where->lb->location);
1a33dc9e
UB
571 message = xasprintf ("At line %d of file %s", line,
572 where->lb->file->filename);
dd18a33b
FXC
573 }
574 else
1a33dc9e
UB
575 message = xasprintf ("In file '%s', around line %d",
576 gfc_source_file, LOCATION_LINE (input_location) + 1);
6de9cd9a 577
ee37d2f5
FXC
578 arg = gfc_build_addr_expr (pchar_type_node,
579 gfc_build_localized_cstring_const (message));
cede9502 580 free (message);
8b704316 581
1a33dc9e 582 message = xasprintf ("%s", _(msgid));
ee37d2f5
FXC
583 arg2 = gfc_build_addr_expr (pchar_type_node,
584 gfc_build_localized_cstring_const (message));
cede9502 585 free (message);
6de9cd9a 586
c8fe94c7 587 /* Build the argument array. */
1145e690 588 argarray = XALLOCAVEC (tree, nargs + 2);
c8fe94c7
FXC
589 argarray[0] = arg;
590 argarray[1] = arg2;
c8fe94c7 591 for (i = 0; i < nargs; i++)
f25a62a5 592 argarray[2 + i] = va_arg (ap, tree);
8b704316 593
0d52899f 594 /* Build the function call to runtime_(warning,error)_at; because of the
db3927fb
AH
595 variable number of arguments, we can't use build_call_expr_loc dinput_location,
596 irectly. */
d74a8b05 597 fntype = TREE_TYPE (errorfunc);
0d52899f 598
9c81750c 599 loc = where ? gfc_get_location (where) : input_location;
9b2b7279
AM
600 tmp = fold_build_call_array_loc (loc, TREE_TYPE (fntype),
601 fold_build1_loc (loc, ADDR_EXPR,
65a9ca82 602 build_pointer_type (fntype),
d74a8b05 603 errorfunc),
9b2b7279 604 nargs + 2, argarray);
6de9cd9a
DN
605 gfc_add_expr_to_block (&block, tmp);
606
f25a62a5
DK
607 return gfc_finish_block (&block);
608}
609
610
55bd9c35
TB
611tree
612gfc_trans_runtime_error (bool error, locus* where, const char* msgid, ...)
613{
614 va_list ap;
615 tree result;
616
617 va_start (ap, msgid);
d74a8b05
JB
618 result = trans_runtime_error_vararg (error
619 ? gfor_fndecl_runtime_error_at
620 : gfor_fndecl_runtime_warning_at,
621 where, msgid, ap);
55bd9c35
TB
622 va_end (ap);
623 return result;
624}
625
626
f25a62a5
DK
627/* Generate a runtime error if COND is true. */
628
629void
630gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
631 locus * where, const char * msgid, ...)
632{
633 va_list ap;
634 stmtblock_t block;
635 tree body;
636 tree tmp;
637 tree tmpvar = NULL;
638
639 if (integer_zerop (cond))
640 return;
641
642 if (once)
643 {
64f96237 644 tmpvar = gfc_create_var (boolean_type_node, "print_warning");
f25a62a5 645 TREE_STATIC (tmpvar) = 1;
64f96237 646 DECL_INITIAL (tmpvar) = boolean_true_node;
f25a62a5
DK
647 gfc_add_expr_to_block (pblock, tmpvar);
648 }
649
650 gfc_start_block (&block);
651
ed9c79e1
JJ
652 /* For error, runtime_error_at already implies PRED_NORETURN. */
653 if (!error && once)
654 gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_WARN_ONCE,
655 NOT_TAKEN));
656
f25a62a5
DK
657 /* The code to generate the error. */
658 va_start (ap, msgid);
659 gfc_add_expr_to_block (&block,
d74a8b05
JB
660 trans_runtime_error_vararg
661 (error ? gfor_fndecl_runtime_error_at
662 : gfor_fndecl_runtime_warning_at,
663 where, msgid, ap));
fc2655fb 664 va_end (ap);
f25a62a5 665
0d52899f 666 if (once)
64f96237 667 gfc_add_modify (&block, tmpvar, boolean_false_node);
0d52899f 668
6de9cd9a
DN
669 body = gfc_finish_block (&block);
670
671 if (integer_onep (cond))
672 {
673 gfc_add_expr_to_block (pblock, body);
674 }
675 else
676 {
0d52899f 677 if (once)
9c81750c 678 cond = fold_build2_loc (gfc_get_location (where), TRUTH_AND_EXPR,
64f96237
TB
679 boolean_type_node, tmpvar,
680 fold_convert (boolean_type_node, cond));
0d52899f 681
9c81750c 682 tmp = fold_build3_loc (gfc_get_location (where), COND_EXPR, void_type_node,
55bd9c35 683 cond, body,
9c81750c 684 build_empty_stmt (gfc_get_location (where)));
6de9cd9a
DN
685 gfc_add_expr_to_block (pblock, tmp);
686 }
687}
688
689
d74a8b05
JB
690static tree
691trans_os_error_at (locus* where, const char* msgid, ...)
692{
693 va_list ap;
694 tree result;
695
696 va_start (ap, msgid);
697 result = trans_runtime_error_vararg (gfor_fndecl_os_error_at,
698 where, msgid, ap);
699 va_end (ap);
700 return result;
701}
702
703
704
1529b8d9 705/* Call malloc to allocate size bytes of memory, with special conditions:
da17cbb7 706 + if size == 0, return a malloced area of size 1,
1529b8d9
FXC
707 + if malloc returns NULL, issue a runtime error. */
708tree
709gfc_call_malloc (stmtblock_t * block, tree type, tree size)
710{
d74a8b05 711 tree tmp, malloc_result, null_result, res, malloc_tree;
1529b8d9
FXC
712 stmtblock_t block2;
713
1529b8d9 714 /* Create a variable to hold the result. */
10174ddf 715 res = gfc_create_var (prvoid_type_node, NULL);
1529b8d9 716
22bdbb0f 717 /* Call malloc. */
1529b8d9 718 gfc_start_block (&block2);
8f0aaee5 719
33a7a932
HA
720 if (size == NULL_TREE)
721 size = build_int_cst (size_type_node, 1);
722
107051a5 723 size = fold_convert (size_type_node, size);
65a9ca82
TB
724 size = fold_build2_loc (input_location, MAX_EXPR, size_type_node, size,
725 build_int_cst (size_type_node, 1));
8f0aaee5 726
e79983f4 727 malloc_tree = builtin_decl_explicit (BUILT_IN_MALLOC);
726a989a 728 gfc_add_modify (&block2, res,
10174ddf
MM
729 fold_convert (prvoid_type_node,
730 build_call_expr_loc (input_location,
e79983f4 731 malloc_tree, 1, size)));
22bdbb0f
TB
732
733 /* Optionally check whether malloc was successful. */
734 if (gfc_option.rtcheck & GFC_RTCHECK_MEM)
735 {
65a9ca82 736 null_result = fold_build2_loc (input_location, EQ_EXPR,
63ee5404 737 logical_type_node, res,
65a9ca82 738 build_int_cst (pvoid_type_node, 0));
65a9ca82
TB
739 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
740 null_result,
d74a8b05
JB
741 trans_os_error_at (NULL,
742 "Error allocating %lu bytes",
743 fold_convert
744 (long_unsigned_type_node,
745 size)),
746 build_empty_stmt (input_location));
22bdbb0f
TB
747 gfc_add_expr_to_block (&block2, tmp);
748 }
749
1529b8d9 750 malloc_result = gfc_finish_block (&block2);
8f0aaee5 751 gfc_add_expr_to_block (block, malloc_result);
1529b8d9
FXC
752
753 if (type != NULL)
754 res = fold_convert (type, res);
755 return res;
756}
757
22bdbb0f 758
4376b7cf 759/* Allocate memory, using an optional status argument.
8b704316 760
4376b7cf
FXC
761 This function follows the following pseudo-code:
762
763 void *
8f992d64 764 allocate (size_t size, integer_type stat)
4376b7cf
FXC
765 {
766 void *newmem;
8b704316 767
8f992d64
DC
768 if (stat requested)
769 stat = 0;
4376b7cf 770
da17cbb7
JB
771 newmem = malloc (MAX (size, 1));
772 if (newmem == NULL)
4376b7cf 773 {
da17cbb7 774 if (stat)
871dbb61 775 *stat = LIBERROR_NO_MEMORY;
da17cbb7 776 else
bd085c20 777 runtime_error ("Allocation would exceed memory limit");
4376b7cf 778 }
4376b7cf
FXC
779 return newmem;
780 } */
4f13e17f
DC
781void
782gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
783 tree size, tree status)
4376b7cf 784{
ed9c79e1
JJ
785 tree tmp, error_cond;
786 stmtblock_t on_error;
8f992d64 787 tree status_type = status ? TREE_TYPE (status) : NULL_TREE;
4376b7cf 788
4f13e17f 789 /* If successful and stat= is given, set status to 0. */
8f992d64
DC
790 if (status != NULL_TREE)
791 gfc_add_expr_to_block (block,
792 fold_build2_loc (input_location, MODIFY_EXPR, status_type,
793 status, build_int_cst (status_type, 0)));
4376b7cf 794
4376b7cf 795 /* The allocation itself. */
107051a5 796 size = fold_convert (size_type_node, size);
4f13e17f
DC
797 gfc_add_modify (block, pointer,
798 fold_convert (TREE_TYPE (pointer),
8f992d64 799 build_call_expr_loc (input_location,
e79983f4 800 builtin_decl_explicit (BUILT_IN_MALLOC), 1,
8f992d64
DC
801 fold_build2_loc (input_location,
802 MAX_EXPR, size_type_node, size,
803 build_int_cst (size_type_node, 1)))));
804
805 /* What to do in case of error. */
ed9c79e1 806 gfc_start_block (&on_error);
8f992d64 807 if (status != NULL_TREE)
ed9c79e1 808 {
ed9c79e1 809 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, status,
871dbb61 810 build_int_cst (status_type, LIBERROR_NO_MEMORY));
ed9c79e1
JJ
811 gfc_add_expr_to_block (&on_error, tmp);
812 }
ea6363a3 813 else
ed9c79e1 814 {
d74a8b05
JB
815 /* Here, os_error_at already implies PRED_NORETURN. */
816 tree lusize = fold_convert (long_unsigned_type_node, size);
817 tmp = trans_os_error_at (NULL, "Error allocating %lu bytes", lusize);
ed9c79e1
JJ
818 gfc_add_expr_to_block (&on_error, tmp);
819 }
4376b7cf 820
4f13e17f 821 error_cond = fold_build2_loc (input_location, EQ_EXPR,
63ee5404 822 logical_type_node, pointer,
4f13e17f 823 build_int_cst (prvoid_type_node, 0));
65a9ca82 824 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
7f7fa20f
ML
825 gfc_unlikely (error_cond, PRED_FORTRAN_FAIL_ALLOC),
826 gfc_finish_block (&on_error),
4f13e17f 827 build_empty_stmt (input_location));
4376b7cf 828
4f13e17f 829 gfc_add_expr_to_block (block, tmp);
4376b7cf
FXC
830}
831
832
8f992d64 833/* Allocate memory, using an optional status argument.
8b704316 834
8f992d64
DC
835 This function follows the following pseudo-code:
836
837 void *
979d4598 838 allocate (size_t size, void** token, int *stat, char* errmsg, int errlen)
8f992d64
DC
839 {
840 void *newmem;
979d4598
TB
841
842 newmem = _caf_register (size, regtype, token, &stat, errmsg, errlen);
8f992d64
DC
843 return newmem;
844 } */
ba85c8c3
AV
845void
846gfc_allocate_using_caf_lib (stmtblock_t * block, tree pointer, tree size,
847 tree token, tree status, tree errmsg, tree errlen,
848 gfc_coarray_regtype alloc_type)
8f992d64 849{
4f13e17f 850 tree tmp, pstat;
8f992d64 851
979d4598
TB
852 gcc_assert (token != NULL_TREE);
853
8f992d64
DC
854 /* The allocation itself. */
855 if (status == NULL_TREE)
856 pstat = null_pointer_node;
857 else
858 pstat = gfc_build_addr_expr (NULL_TREE, status);
859
860 if (errmsg == NULL_TREE)
861 {
862 gcc_assert(errlen == NULL_TREE);
863 errmsg = null_pointer_node;
864 errlen = build_int_cst (integer_type_node, 0);
865 }
866
107051a5 867 size = fold_convert (size_type_node, size);
4f13e17f 868 tmp = build_call_expr_loc (input_location,
3c9f5092 869 gfor_fndecl_caf_register, 7,
4f13e17f 870 fold_build2_loc (input_location,
ba85c8c3
AV
871 MAX_EXPR, size_type_node, size, size_one_node),
872 build_int_cst (integer_type_node, alloc_type),
3c9f5092
AV
873 token, gfc_build_addr_expr (pvoid_type_node, pointer),
874 pstat, errmsg, errlen);
8f992d64 875
4f13e17f 876 gfc_add_expr_to_block (block, tmp);
985f6c79
TB
877
878 /* It guarantees memory consistency within the same segment */
879 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
880 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
881 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
882 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
883 ASM_VOLATILE_P (tmp) = 1;
884 gfc_add_expr_to_block (block, tmp);
8f992d64
DC
885}
886
887
4376b7cf 888/* Generate code for an ALLOCATE statement when the argument is an
ea6363a3 889 allocatable variable. If the variable is currently allocated, it is an
4376b7cf 890 error to allocate it again.
8b704316 891
4376b7cf 892 This function follows the following pseudo-code:
8b704316 893
4376b7cf 894 void *
8f992d64 895 allocate_allocatable (void *mem, size_t size, integer_type stat)
4376b7cf
FXC
896 {
897 if (mem == NULL)
898 return allocate (size, stat);
899 else
900 {
901 if (stat)
8f992d64 902 stat = LIBERROR_ALLOCATION;
4376b7cf 903 else
f8dde8af 904 runtime_error ("Attempting to allocate already allocated variable");
5b130807 905 }
f25a62a5 906 }
8b704316 907
f25a62a5
DK
908 expr must be set to the original expression being allocated for its locus
909 and variable name in case a runtime error has to be printed. */
4f13e17f 910void
3c9f5092
AV
911gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size,
912 tree token, tree status, tree errmsg, tree errlen,
913 tree label_finish, gfc_expr* expr, int corank)
4376b7cf
FXC
914{
915 stmtblock_t alloc_block;
4f13e17f 916 tree tmp, null_mem, alloc, error;
4376b7cf 917 tree type = TREE_TYPE (mem);
3c9f5092 918 symbol_attribute caf_attr;
ba85c8c3
AV
919 bool need_assign = false, refs_comp = false;
920 gfc_coarray_regtype caf_alloc_type = GFC_CAF_COARRAY_ALLOC;
4376b7cf 921
107051a5 922 size = fold_convert (size_type_node, size);
9ef0b98e 923 null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
63ee5404 924 logical_type_node, mem,
ed9c79e1 925 build_int_cst (type, 0)),
7f7fa20f 926 PRED_FORTRAN_REALLOC);
4376b7cf 927
8f992d64
DC
928 /* If mem is NULL, we call gfc_allocate_using_malloc or
929 gfc_allocate_using_lib. */
4376b7cf 930 gfc_start_block (&alloc_block);
8f992d64 931
3c9f5092 932 if (flag_coarray == GFC_FCOARRAY_LIB)
ba85c8c3 933 caf_attr = gfc_caf_attr (expr, true, &refs_comp);
3c9f5092 934
f19626cf 935 if (flag_coarray == GFC_FCOARRAY_LIB
3c9f5092 936 && (corank > 0 || caf_attr.codimension))
5d81ddd0 937 {
ba85c8c3 938 tree cond, sub_caf_tree;
3c9f5092 939 gfc_se se;
ba85c8c3 940 bool compute_special_caf_types_size = false;
3c9f5092 941
ba85c8c3
AV
942 if (expr->ts.type == BT_DERIVED
943 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
944 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
945 {
946 compute_special_caf_types_size = true;
947 caf_alloc_type = GFC_CAF_LOCK_ALLOC;
948 }
949 else if (expr->ts.type == BT_DERIVED
950 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
951 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
952 {
953 compute_special_caf_types_size = true;
954 caf_alloc_type = GFC_CAF_EVENT_ALLOC;
955 }
956 else if (!caf_attr.coarray_comp && refs_comp)
957 /* Only allocatable components in a derived type coarray can be
958 allocate only. */
959 caf_alloc_type = GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY;
960
961 gfc_init_se (&se, NULL);
962 sub_caf_tree = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
3c9f5092
AV
963 if (sub_caf_tree == NULL_TREE)
964 sub_caf_tree = token;
965
966 /* When mem is an array ref, then strip the .data-ref. */
967 if (TREE_CODE (mem) == COMPONENT_REF
968 && !(GFC_ARRAY_TYPE_P (TREE_TYPE (mem))))
969 tmp = TREE_OPERAND (mem, 0);
970 else
971 tmp = mem;
972
973 if (!(GFC_ARRAY_TYPE_P (TREE_TYPE (tmp))
974 && TYPE_LANG_SPECIFIC (TREE_TYPE (tmp))->corank == 0)
975 && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
976 {
977 symbol_attribute attr;
978
979 gfc_clear_attr (&attr);
980 tmp = gfc_conv_scalar_to_descriptor (&se, mem, attr);
981 need_assign = true;
982 }
983 gfc_add_block_to_block (&alloc_block, &se.pre);
984
9f3880d1
TB
985 /* In the front end, we represent the lock variable as pointer. However,
986 the FE only passes the pointer around and leaves the actual
987 representation to the library. Hence, we have to convert back to the
988 number of elements. */
ba85c8c3 989 if (compute_special_caf_types_size)
9f3880d1
TB
990 size = fold_build2_loc (input_location, TRUNC_DIV_EXPR, size_type_node,
991 size, TYPE_SIZE_UNIT (ptr_type_node));
5d81ddd0 992
ba85c8c3
AV
993 gfc_allocate_using_caf_lib (&alloc_block, tmp, size, sub_caf_tree,
994 status, errmsg, errlen, caf_alloc_type);
3c9f5092
AV
995 if (need_assign)
996 gfc_add_modify (&alloc_block, mem, fold_convert (TREE_TYPE (mem),
997 gfc_conv_descriptor_data_get (tmp)));
5d81ddd0
TB
998 if (status != NULL_TREE)
999 {
1000 TREE_USED (label_finish) = 1;
1001 tmp = build1_v (GOTO_EXPR, label_finish);
63ee5404 1002 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
5d81ddd0
TB
1003 status, build_zero_cst (TREE_TYPE (status)));
1004 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
ed9c79e1
JJ
1005 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
1006 tmp, build_empty_stmt (input_location));
5d81ddd0
TB
1007 gfc_add_expr_to_block (&alloc_block, tmp);
1008 }
1009 }
8f992d64 1010 else
4f13e17f 1011 gfc_allocate_using_malloc (&alloc_block, mem, size, status);
ea6363a3 1012
4376b7cf
FXC
1013 alloc = gfc_finish_block (&alloc_block);
1014
ea6363a3
DC
1015 /* If mem is not NULL, we issue a runtime error or set the
1016 status variable. */
f25a62a5
DK
1017 if (expr)
1018 {
1019 tree varname;
1020
1021 gcc_assert (expr->expr_type == EXPR_VARIABLE && expr->symtree);
1022 varname = gfc_build_cstring_const (expr->symtree->name);
1023 varname = gfc_build_addr_expr (pchar_type_node, varname);
1024
1025 error = gfc_trans_runtime_error (true, &expr->where,
1026 "Attempting to allocate already"
f8dde8af 1027 " allocated variable '%s'",
f25a62a5
DK
1028 varname);
1029 }
1030 else
1031 error = gfc_trans_runtime_error (true, NULL,
1032 "Attempting to allocate already allocated"
d8a07487 1033 " variable");
4376b7cf 1034
8f992d64 1035 if (status != NULL_TREE)
4376b7cf 1036 {
8f992d64 1037 tree status_type = TREE_TYPE (status);
4376b7cf 1038
4f13e17f
DC
1039 error = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1040 status, build_int_cst (status_type, LIBERROR_ALLOCATION));
4376b7cf
FXC
1041 }
1042
65a9ca82 1043 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem,
9ef0b98e 1044 error, alloc);
4376b7cf 1045 gfc_add_expr_to_block (block, tmp);
4376b7cf
FXC
1046}
1047
1529b8d9 1048
cd55d18e 1049/* Free a given variable. */
107051a5 1050
1529b8d9
FXC
1051tree
1052gfc_call_free (tree var)
1053{
cd55d18e 1054 return build_call_expr_loc (input_location,
e79983f4 1055 builtin_decl_explicit (BUILT_IN_FREE),
cd55d18e 1056 1, fold_convert (pvoid_type_node, var));
1529b8d9
FXC
1057}
1058
1059
ef292537
TB
1060/* Build a call to a FINAL procedure, which finalizes "var". */
1061
1062static tree
1063gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var,
1064 bool fini_coarray, gfc_expr *class_size)
1065{
1066 stmtblock_t block;
1067 gfc_se se;
1068 tree final_fndecl, array, size, tmp;
1069 symbol_attribute attr;
1070
1071 gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE);
1072 gcc_assert (var);
1073
45db6b0d 1074 gfc_start_block (&block);
ef292537
TB
1075 gfc_init_se (&se, NULL);
1076 gfc_conv_expr (&se, final_wrapper);
1077 final_fndecl = se.expr;
1078 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
1079 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
1080
1081 if (ts.type == BT_DERIVED)
1082 {
1083 tree elem_size;
1084
1085 gcc_assert (!class_size);
1086 elem_size = gfc_typenode_for_spec (&ts);
1087 elem_size = TYPE_SIZE_UNIT (elem_size);
1088 size = fold_convert (gfc_array_index_type, elem_size);
1089
1090 gfc_init_se (&se, NULL);
1091 se.want_pointer = 1;
1092 if (var->rank)
1093 {
1094 se.descriptor_only = 1;
1095 gfc_conv_expr_descriptor (&se, var);
1096 array = se.expr;
1097 }
1098 else
1099 {
1100 gfc_conv_expr (&se, var);
d7caf313 1101// gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
ef292537
TB
1102 array = se.expr;
1103
1104 /* No copy back needed, hence set attr's allocatable/pointer
1105 to zero. */
1106 gfc_clear_attr (&attr);
1107 gfc_init_se (&se, NULL);
1108 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1109 gcc_assert (se.post.head == NULL_TREE);
1110 }
1111 }
1112 else
1113 {
1114 gfc_expr *array_expr;
1115 gcc_assert (class_size);
1116 gfc_init_se (&se, NULL);
1117 gfc_conv_expr (&se, class_size);
2297c8ce
TB
1118 gfc_add_block_to_block (&block, &se.pre);
1119 gcc_assert (se.post.head == NULL_TREE);
ef292537
TB
1120 size = se.expr;
1121
1122 array_expr = gfc_copy_expr (var);
1123 gfc_init_se (&se, NULL);
1124 se.want_pointer = 1;
1125 if (array_expr->rank)
1126 {
1127 gfc_add_class_array_ref (array_expr);
1128 se.descriptor_only = 1;
1129 gfc_conv_expr_descriptor (&se, array_expr);
1130 array = se.expr;
1131 }
1132 else
1133 {
1134 gfc_add_data_component (array_expr);
1135 gfc_conv_expr (&se, array_expr);
2297c8ce
TB
1136 gfc_add_block_to_block (&block, &se.pre);
1137 gcc_assert (se.post.head == NULL_TREE);
ef292537 1138 array = se.expr;
ef292537
TB
1139
1140 if (!gfc_is_coarray (array_expr))
1141 {
1142 /* No copy back needed, hence set attr's allocatable/pointer
1143 to zero. */
1144 gfc_clear_attr (&attr);
1145 gfc_init_se (&se, NULL);
1146 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1147 }
1148 gcc_assert (se.post.head == NULL_TREE);
1149 }
1150 gfc_free_expr (array_expr);
1151 }
1152
1153 if (!POINTER_TYPE_P (TREE_TYPE (array)))
1154 array = gfc_build_addr_expr (NULL, array);
1155
ef292537
TB
1156 gfc_add_block_to_block (&block, &se.pre);
1157 tmp = build_call_expr_loc (input_location,
1158 final_fndecl, 3, array,
1159 size, fini_coarray ? boolean_true_node
1160 : boolean_false_node);
1161 gfc_add_block_to_block (&block, &se.post);
1162 gfc_add_expr_to_block (&block, tmp);
1163 return gfc_finish_block (&block);
1164}
1165
1166
895a0c2d
TB
1167bool
1168gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp,
1169 bool fini_coarray)
1170{
1171 gfc_se se;
1172 stmtblock_t block2;
1173 tree final_fndecl, size, array, tmp, cond;
1174 symbol_attribute attr;
1175 gfc_expr *final_expr = NULL;
1176
1177 if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS)
1178 return false;
1179
1180 gfc_init_block (&block2);
1181
1182 if (comp->ts.type == BT_DERIVED)
1183 {
1184 if (comp->attr.pointer)
1185 return false;
1186
1187 gfc_is_finalizable (comp->ts.u.derived, &final_expr);
1188 if (!final_expr)
1189 return false;
1190
1191 gfc_init_se (&se, NULL);
1192 gfc_conv_expr (&se, final_expr);
1193 final_fndecl = se.expr;
1194 size = gfc_typenode_for_spec (&comp->ts);
1195 size = TYPE_SIZE_UNIT (size);
1196 size = fold_convert (gfc_array_index_type, size);
1197
1198 array = decl;
1199 }
1200 else /* comp->ts.type == BT_CLASS. */
1201 {
1202 if (CLASS_DATA (comp)->attr.class_pointer)
1203 return false;
1204
1205 gfc_is_finalizable (CLASS_DATA (comp)->ts.u.derived, &final_expr);
34d9d749
AV
1206 final_fndecl = gfc_class_vtab_final_get (decl);
1207 size = gfc_class_vtab_size_get (decl);
895a0c2d
TB
1208 array = gfc_class_data_get (decl);
1209 }
1210
1211 if (comp->attr.allocatable
1212 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)->attr.allocatable))
1213 {
1214 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))
1215 ? gfc_conv_descriptor_data_get (array) : array;
63ee5404 1216 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
895a0c2d
TB
1217 tmp, fold_convert (TREE_TYPE (tmp),
1218 null_pointer_node));
1219 }
1220 else
63ee5404 1221 cond = logical_true_node;
895a0c2d
TB
1222
1223 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array)))
1224 {
1225 gfc_clear_attr (&attr);
1226 gfc_init_se (&se, NULL);
1227 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1228 gfc_add_block_to_block (&block2, &se.pre);
1229 gcc_assert (se.post.head == NULL_TREE);
1230 }
1231
1232 if (!POINTER_TYPE_P (TREE_TYPE (array)))
1233 array = gfc_build_addr_expr (NULL, array);
1234
1235 if (!final_expr)
1236 {
63ee5404 1237 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
895a0c2d
TB
1238 final_fndecl,
1239 fold_convert (TREE_TYPE (final_fndecl),
1240 null_pointer_node));
1241 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
63ee5404 1242 logical_type_node, cond, tmp);
895a0c2d
TB
1243 }
1244
1245 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
1246 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
1247
1248 tmp = build_call_expr_loc (input_location,
1249 final_fndecl, 3, array,
1250 size, fini_coarray ? boolean_true_node
1251 : boolean_false_node);
1252 gfc_add_expr_to_block (&block2, tmp);
1253 tmp = gfc_finish_block (&block2);
1254
1255 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
1256 build_empty_stmt (input_location));
1257 gfc_add_expr_to_block (block, tmp);
1258
1259 return true;
1260}
1261
1262
ef292537
TB
1263/* Add a call to the finalizer, using the passed *expr. Returns
1264 true when a finalizer call has been inserted. */
1265
1266bool
1267gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2)
1268{
1269 tree tmp;
1270 gfc_ref *ref;
1271 gfc_expr *expr;
1272 gfc_expr *final_expr = NULL;
1273 gfc_expr *elem_size = NULL;
1274 bool has_finalizer = false;
1275
1276 if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS))
1277 return false;
1278
d7caf313
PT
1279 /* Finalization of these temporaries is made by explicit calls in
1280 resolve.cc(generate_component_assignments). */
1281 if (expr2->expr_type == EXPR_VARIABLE
1282 && expr2->symtree->n.sym->name[0] == '_'
1283 && expr2->ts.type == BT_DERIVED
1284 && expr2->ts.u.derived->attr.defined_assign_comp)
1285 return false;
1286
ef292537
TB
1287 if (expr2->ts.type == BT_DERIVED)
1288 {
1289 gfc_is_finalizable (expr2->ts.u.derived, &final_expr);
1290 if (!final_expr)
1291 return false;
1292 }
1293
1294 /* If we have a class array, we need go back to the class
1cc0e193 1295 container. */
ef292537
TB
1296 expr = gfc_copy_expr (expr2);
1297
1298 if (expr->ref && expr->ref->next && !expr->ref->next->next
1299 && expr->ref->next->type == REF_ARRAY
1300 && expr->ref->type == REF_COMPONENT
1301 && strcmp (expr->ref->u.c.component->name, "_data") == 0)
1302 {
1303 gfc_free_ref_list (expr->ref);
1304 expr->ref = NULL;
1305 }
1306 else
1307 for (ref = expr->ref; ref; ref = ref->next)
1308 if (ref->next && ref->next->next && !ref->next->next->next
1309 && ref->next->next->type == REF_ARRAY
1310 && ref->next->type == REF_COMPONENT
1311 && strcmp (ref->next->u.c.component->name, "_data") == 0)
1312 {
1313 gfc_free_ref_list (ref->next);
1314 ref->next = NULL;
1315 }
1316
1317 if (expr->ts.type == BT_CLASS)
1318 {
1319 has_finalizer = gfc_is_finalizable (expr->ts.u.derived, NULL);
1320
1321 if (!expr2->rank && !expr2->ref && CLASS_DATA (expr2->symtree->n.sym)->as)
1322 expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank;
1323
1324 final_expr = gfc_copy_expr (expr);
1325 gfc_add_vptr_component (final_expr);
d42844f1 1326 gfc_add_final_component (final_expr);
ef292537
TB
1327
1328 elem_size = gfc_copy_expr (expr);
1329 gfc_add_vptr_component (elem_size);
d42844f1 1330 gfc_add_size_component (elem_size);
ef292537
TB
1331 }
1332
1333 gcc_assert (final_expr->expr_type == EXPR_VARIABLE);
1334
1335 tmp = gfc_build_final_call (expr->ts, final_expr, expr,
1336 false, elem_size);
1337
1338 if (expr->ts.type == BT_CLASS && !has_finalizer)
1339 {
1340 tree cond;
1341 gfc_se se;
1342
1343 gfc_init_se (&se, NULL);
1344 se.want_pointer = 1;
1345 gfc_conv_expr (&se, final_expr);
63ee5404 1346 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
ef292537
TB
1347 se.expr, build_int_cst (TREE_TYPE (se.expr), 0));
1348
1349 /* For CLASS(*) not only sym->_vtab->_final can be NULL
1350 but already sym->_vtab itself. */
1351 if (UNLIMITED_POLY (expr))
1352 {
1353 tree cond2;
1354 gfc_expr *vptr_expr;
1355
1356 vptr_expr = gfc_copy_expr (expr);
1357 gfc_add_vptr_component (vptr_expr);
1358
1359 gfc_init_se (&se, NULL);
1360 se.want_pointer = 1;
1361 gfc_conv_expr (&se, vptr_expr);
1362 gfc_free_expr (vptr_expr);
1363
63ee5404 1364 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
ef292537
TB
1365 se.expr,
1366 build_int_cst (TREE_TYPE (se.expr), 0));
1367 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
63ee5404 1368 logical_type_node, cond2, cond);
ef292537
TB
1369 }
1370
1371 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1372 cond, tmp, build_empty_stmt (input_location));
1373 }
1374
1375 gfc_add_expr_to_block (block, tmp);
1376
1377 return true;
1378}
1379
4376b7cf 1380
d7caf313
PT
1381 /* F2018 (7.5.6.3): "When an intrinsic assignment statement is executed
1382 (10.2.1.3), if the variable is not an unallocated allocatable variable,
1383 it is finalized after evaluation of expr and before the definition of
1384 the variable. If the variable is an allocated allocatable variable, or
1385 has an allocated allocatable subobject, that would be deallocated by
1386 intrinsic assignment, the finalization occurs before the deallocation */
1387
1388bool
1389gfc_assignment_finalizer_call (gfc_se *lse, gfc_expr *expr1, bool init_flag)
1390{
1391 symbol_attribute lhs_attr;
1392 tree final_expr;
1393 tree ptr;
1394 tree cond;
1395 gfc_se se;
1396 gfc_symbol *sym = expr1->symtree->n.sym;
1397 gfc_ref *ref = expr1->ref;
1398 stmtblock_t final_block;
1399 gfc_init_block (&final_block);
1400 gfc_expr *finalize_expr;
1401 bool class_array_ref;
1402
1403 /* We have to exclude vtable procedures (_copy and _final especially), uses
1404 of gfc_trans_assignment_1 in initialization and allocation before trying
1405 to build a final call. */
1406 if (!expr1->must_finalize
1407 || sym->attr.artificial
1408 || sym->ns->proc_name->attr.artificial
1409 || init_flag)
1410 return false;
1411
1412 class_array_ref = ref && ref->type == REF_COMPONENT
1413 && !strcmp (ref->u.c.component->name, "_data")
1414 && ref->next && ref->next->type == REF_ARRAY
1415 && !ref->next->next;
1416
1417 if (class_array_ref)
1418 {
1419 finalize_expr = gfc_lval_expr_from_sym (sym);
1420 finalize_expr->must_finalize = 1;
1421 ref = NULL;
1422 }
1423 else
1424 finalize_expr = gfc_copy_expr (expr1);
1425
1426 /* F2018 7.5.6.2: Only finalizable entities are finalized. */
1427 if (!(expr1->ts.type == BT_DERIVED
1428 && gfc_is_finalizable (expr1->ts.u.derived, NULL))
1429 && expr1->ts.type != BT_CLASS)
1430 return false;
1431
1432 if (!gfc_may_be_finalized (sym->ts))
1433 return false;
1434
1435 gfc_init_block (&final_block);
1436 bool finalizable = gfc_add_finalizer_call (&final_block, finalize_expr);
1437 gfc_free_expr (finalize_expr);
1438
1439 if (!finalizable)
1440 return false;
1441
1442 lhs_attr = gfc_expr_attr (expr1);
1443
1444 /* Check allocatable/pointer is allocated/associated. */
1445 if (lhs_attr.allocatable || lhs_attr.pointer)
1446 {
1447 if (expr1->ts.type == BT_CLASS)
1448 {
1449 ptr = gfc_get_class_from_gfc_expr (expr1);
1450 gcc_assert (ptr != NULL_TREE);
1451 ptr = gfc_class_data_get (ptr);
1452 if (lhs_attr.dimension)
1453 ptr = gfc_conv_descriptor_data_get (ptr);
1454 }
1455 else
1456 {
1457 gfc_init_se (&se, NULL);
1458 if (expr1->rank)
1459 {
1460 gfc_conv_expr_descriptor (&se, expr1);
1461 ptr = gfc_conv_descriptor_data_get (se.expr);
1462 }
1463 else
1464 {
1465 gfc_conv_expr (&se, expr1);
1466 ptr = gfc_build_addr_expr (NULL_TREE, se.expr);
1467 }
1468 }
1469
1470 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1471 ptr, build_zero_cst (TREE_TYPE (ptr)));
1472 final_expr = build3_loc (input_location, COND_EXPR, void_type_node,
1473 cond, gfc_finish_block (&final_block),
1474 build_empty_stmt (input_location));
1475 }
1476 else
1477 final_expr = gfc_finish_block (&final_block);
1478
1479 /* Check optional present. */
1480 if (sym->attr.optional)
1481 {
1482 cond = gfc_conv_expr_present (sym);
1483 final_expr = build3_loc (input_location, COND_EXPR, void_type_node,
1484 cond, final_expr,
1485 build_empty_stmt (input_location));
1486 }
1487
1488 gfc_add_expr_to_block (&lse->finalblock, final_expr);
1489
1490 return true;
1491}
1492
1493
1494/* Finalize a TREE expression using the finalizer wrapper. The result is
1495 fixed in order to prevent repeated calls. */
1496
1497void
1498gfc_finalize_tree_expr (gfc_se *se, gfc_symbol *derived,
1499 symbol_attribute attr, int rank)
1500{
1501 tree vptr, final_fndecl, desc, tmp, size, is_final;
1502 tree data_ptr, data_null, cond;
1503 gfc_symbol *vtab;
1504 gfc_se post_se;
1505 bool is_class = GFC_CLASS_TYPE_P (TREE_TYPE (se->expr));
1506
1507 if (attr.pointer)
1508 return;
1509
1510 /* Derived type function results with components that have defined
1511 assignements are handled in resolve.cc(generate_component_assignments) */
1512 if (derived && (derived->attr.is_c_interop
1513 || derived->attr.is_iso_c
1514 || derived->attr.is_bind_c
1515 || derived->attr.defined_assign_comp))
1516 return;
1517
1518 if (is_class)
1519 {
1520 if (!VAR_P (se->expr))
1521 {
1522 desc = gfc_evaluate_now (se->expr, &se->pre);
1523 se->expr = desc;
1524 }
1525 desc = gfc_class_data_get (se->expr);
1526 vptr = gfc_class_vptr_get (se->expr);
1527 }
1528 else if (derived && gfc_is_finalizable (derived, NULL))
1529 {
1530 if (derived->attr.zero_comp && !rank)
1531 {
1532 /* Any attempt to assign zero length entities, causes the gimplifier
1533 all manner of problems. Instead, a variable is created to act as
1534 as the argument for the final call. */
1535 desc = gfc_create_var (TREE_TYPE (se->expr), "zero");
1536 }
1537 else if (se->direct_byref)
1538 {
1539 desc = gfc_evaluate_now (se->expr, &se->finalblock);
1540 if (derived->attr.alloc_comp)
1541 {
1542 /* Need to copy allocated components and not finalize. */
1543 tmp = gfc_copy_alloc_comp_no_fini (derived, se->expr, desc, rank, 0);
1544 gfc_add_expr_to_block (&se->finalblock, tmp);
1545 }
1546 }
1547 else
1548 {
1549 desc = gfc_evaluate_now (se->expr, &se->pre);
1550 se->expr = gfc_evaluate_now (desc, &se->pre);
1551 if (derived->attr.alloc_comp)
1552 {
1553 /* Need to copy allocated components and not finalize. */
1554 tmp = gfc_copy_alloc_comp_no_fini (derived, se->expr, desc, rank, 0);
1555 gfc_add_expr_to_block (&se->pre, tmp);
1556 }
1557 }
1558
1559 vtab = gfc_find_derived_vtab (derived);
1560 if (vtab->backend_decl == NULL_TREE)
1561 vptr = gfc_get_symbol_decl (vtab);
1562 else
1563 vptr = vtab->backend_decl;
1564 vptr = gfc_build_addr_expr (NULL, vptr);
1565 }
1566 else
1567 return;
1568
1569 size = gfc_vptr_size_get (vptr);
1570 final_fndecl = gfc_vptr_final_get (vptr);
1571 is_final = fold_build2_loc (input_location, NE_EXPR,
1572 logical_type_node,
1573 final_fndecl,
1574 fold_convert (TREE_TYPE (final_fndecl),
1575 null_pointer_node));
1576
1577 final_fndecl = build_fold_indirect_ref_loc (input_location,
1578 final_fndecl);
1579 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
1580 {
1581 if (is_class)
1582 desc = gfc_conv_scalar_to_descriptor (se, desc, attr);
1583 else
1584 {
1585 gfc_init_se (&post_se, NULL);
1586 desc = gfc_conv_scalar_to_descriptor (&post_se, desc, attr);
1587 gfc_add_expr_to_block (&se->pre, gfc_finish_block (&post_se.pre));
1588 }
1589 }
1590
1591 if (derived && derived->attr.zero_comp)
1592 {
1593 /* All the conditions below break down for zero length derived types. */
1594 tmp = build_call_expr_loc (input_location, final_fndecl, 3,
1595 gfc_build_addr_expr (NULL, desc),
1596 size, boolean_false_node);
1597 gfc_add_expr_to_block (&se->finalblock, tmp);
1598 return;
1599 }
1600
1601 if (!VAR_P (desc))
1602 {
1603 tmp = gfc_create_var (TREE_TYPE (desc), "res");
1604 if (se->direct_byref)
1605 gfc_add_modify (&se->finalblock, tmp, desc);
1606 else
1607 gfc_add_modify (&se->pre, tmp, desc);
1608 desc = tmp;
1609 }
1610
1611 data_ptr = gfc_conv_descriptor_data_get (desc);
1612 data_null = fold_convert (TREE_TYPE (data_ptr), null_pointer_node);
1613 cond = fold_build2_loc (input_location, NE_EXPR,
1614 logical_type_node, data_ptr, data_null);
1615 is_final = fold_build2_loc (input_location, TRUTH_AND_EXPR,
1616 logical_type_node, is_final, cond);
1617 tmp = build_call_expr_loc (input_location, final_fndecl, 3,
1618 gfc_build_addr_expr (NULL, desc),
1619 size, boolean_false_node);
1620 tmp = fold_build3_loc (input_location, COND_EXPR,
1621 void_type_node, is_final, tmp,
1622 build_empty_stmt (input_location));
1623
1624 if (is_class && se->ss && se->ss->loop)
1625 {
1626 gfc_add_expr_to_block (&se->loop->post, tmp);
1627 tmp = fold_build3_loc (input_location, COND_EXPR,
1628 void_type_node, cond,
1629 gfc_call_free (data_ptr),
1630 build_empty_stmt (input_location));
1631 gfc_add_expr_to_block (&se->loop->post, tmp);
1632 gfc_add_modify (&se->loop->post, data_ptr, data_null);
1633 }
1634 else
1635 {
1636 gfc_add_expr_to_block (&se->finalblock, tmp);
1637
1638 /* Let the scalarizer take care of freeing of temporary arrays. */
1639 if (attr.allocatable && !(se->loop && se->loop->temp_dim))
1640 {
1641 tmp = fold_build3_loc (input_location, COND_EXPR,
1642 void_type_node, cond,
1643 gfc_call_free (data_ptr),
1644 build_empty_stmt (input_location));
1645 gfc_add_expr_to_block (&se->finalblock, tmp);
1646 gfc_add_modify (&se->finalblock, data_ptr, data_null);
1647 }
1648 }
1649}
1650
1651
4376b7cf
FXC
1652/* User-deallocate; we emit the code directly from the front-end, and the
1653 logic is the same as the previous library function:
1654
1655 void
1656 deallocate (void *pointer, GFC_INTEGER_4 * stat)
1657 {
1658 if (!pointer)
1659 {
1660 if (stat)
1661 *stat = 1;
1662 else
1663 runtime_error ("Attempt to DEALLOCATE unallocated memory.");
1664 }
1665 else
1666 {
1667 free (pointer);
1668 if (stat)
1669 *stat = 0;
1670 }
1671 }
1672
7999d7b4
TK
1673 In this front-end version, status doesn't have to be GFC_INTEGER_4.
1674 Moreover, if CAN_FAIL is true, then we will not emit a runtime error,
1675 even when no status variable is passed to us (this is used for
1676 unconditional deallocation generated by the front-end at end of
1677 each procedure).
8b704316 1678
f25a62a5 1679 If a runtime-message is possible, `expr' must point to the original
5d81ddd0
TB
1680 expression being deallocated for its locus and variable name.
1681
1682 For coarrays, "pointer" must be the array descriptor and not its
ba85c8c3
AV
1683 "data" component.
1684
1685 COARRAY_DEALLOC_MODE gives the mode unregister coarrays. Available modes are
1686 the ones of GFC_CAF_DEREGTYPE, -1 when the mode for deregistration is to be
1687 analyzed and set by this routine, and -2 to indicate that a non-coarray is to
1688 be deallocated. */
4376b7cf 1689tree
5d81ddd0
TB
1690gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
1691 tree errlen, tree label_finish,
ba85c8c3 1692 bool can_fail, gfc_expr* expr,
39da5866
AV
1693 int coarray_dealloc_mode, tree add_when_allocated,
1694 tree caf_token)
4376b7cf
FXC
1695{
1696 stmtblock_t null, non_null;
f25a62a5 1697 tree cond, tmp, error;
5d81ddd0 1698 tree status_type = NULL_TREE;
39da5866 1699 tree token = NULL_TREE;
ba85c8c3 1700 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
5d81ddd0 1701
ba85c8c3 1702 if (coarray_dealloc_mode >= GFC_CAF_COARRAY_ANALYZE)
5d81ddd0 1703 {
39da5866 1704 if (flag_coarray == GFC_FCOARRAY_LIB)
ba85c8c3 1705 {
39da5866
AV
1706 if (caf_token)
1707 token = caf_token;
1708 else
1709 {
1710 tree caf_type, caf_decl = pointer;
1711 pointer = gfc_conv_descriptor_data_get (caf_decl);
1712 caf_type = TREE_TYPE (caf_decl);
1713 STRIP_NOPS (pointer);
de91486c 1714 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
39da5866
AV
1715 token = gfc_conv_descriptor_token (caf_decl);
1716 else if (DECL_LANG_SPECIFIC (caf_decl)
1717 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1718 token = GFC_DECL_TOKEN (caf_decl);
1719 else
1720 {
1721 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
1722 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type)
1723 != NULL_TREE);
1724 token = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
1725 }
1726 }
1727
1728 if (coarray_dealloc_mode == GFC_CAF_COARRAY_ANALYZE)
1729 {
1730 bool comp_ref;
1731 if (expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
1732 && comp_ref)
1733 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
1734 // else do a deregister as set by default.
1735 }
1736 else
1737 caf_dereg_type = (enum gfc_coarray_deregtype) coarray_dealloc_mode;
ba85c8c3 1738 }
39da5866
AV
1739 else if (flag_coarray == GFC_FCOARRAY_SINGLE)
1740 pointer = gfc_conv_descriptor_data_get (pointer);
5d81ddd0 1741 }
39da5866
AV
1742 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
1743 pointer = gfc_conv_descriptor_data_get (pointer);
4376b7cf 1744
63ee5404 1745 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
65a9ca82 1746 build_int_cst (TREE_TYPE (pointer), 0));
4376b7cf
FXC
1747
1748 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1749 we emit a runtime error. */
1750 gfc_start_block (&null);
1751 if (!can_fail)
1752 {
f25a62a5
DK
1753 tree varname;
1754
1755 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1756
1757 varname = gfc_build_cstring_const (expr->symtree->name);
1758 varname = gfc_build_addr_expr (pchar_type_node, varname);
1759
1760 error = gfc_trans_runtime_error (true, &expr->where,
1761 "Attempt to DEALLOCATE unallocated '%s'",
1762 varname);
4376b7cf
FXC
1763 }
1764 else
c2255bc4 1765 error = build_empty_stmt (input_location);
4376b7cf
FXC
1766
1767 if (status != NULL_TREE && !integer_zerop (status))
1768 {
4376b7cf
FXC
1769 tree cond2;
1770
5d81ddd0 1771 status_type = TREE_TYPE (TREE_TYPE (status));
63ee5404 1772 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
65a9ca82
TB
1773 status, build_int_cst (TREE_TYPE (status), 0));
1774 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1775 fold_build1_loc (input_location, INDIRECT_REF,
1776 status_type, status),
1777 build_int_cst (status_type, 1));
1778 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1779 cond2, tmp, error);
4376b7cf
FXC
1780 }
1781
1782 gfc_add_expr_to_block (&null, error);
1783
1784 /* When POINTER is not NULL, we free it. */
1785 gfc_start_block (&non_null);
39da5866
AV
1786 if (add_when_allocated)
1787 gfc_add_expr_to_block (&non_null, add_when_allocated);
ef292537 1788 gfc_add_finalizer_call (&non_null, expr);
ba85c8c3
AV
1789 if (coarray_dealloc_mode == GFC_CAF_COARRAY_NOCOARRAY
1790 || flag_coarray != GFC_FCOARRAY_LIB)
5d81ddd0
TB
1791 {
1792 tmp = build_call_expr_loc (input_location,
1793 builtin_decl_explicit (BUILT_IN_FREE), 1,
1794 fold_convert (pvoid_type_node, pointer));
1795 gfc_add_expr_to_block (&non_null, tmp);
39da5866
AV
1796 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
1797 0));
2c807128 1798
5d81ddd0
TB
1799 if (status != NULL_TREE && !integer_zerop (status))
1800 {
1801 /* We set STATUS to zero if it is present. */
1802 tree status_type = TREE_TYPE (TREE_TYPE (status));
1803 tree cond2;
1804
63ee5404 1805 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
5d81ddd0
TB
1806 status,
1807 build_int_cst (TREE_TYPE (status), 0));
1808 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1809 fold_build1_loc (input_location, INDIRECT_REF,
1810 status_type, status),
1811 build_int_cst (status_type, 0));
1812 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
ed9c79e1
JJ
1813 gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC),
1814 tmp, build_empty_stmt (input_location));
5d81ddd0
TB
1815 gfc_add_expr_to_block (&non_null, tmp);
1816 }
1817 }
1818 else
2c807128 1819 {
39da5866 1820 tree cond2, pstat = null_pointer_node;
2c807128 1821
5d81ddd0
TB
1822 if (errmsg == NULL_TREE)
1823 {
1824 gcc_assert (errlen == NULL_TREE);
1825 errmsg = null_pointer_node;
1826 errlen = build_zero_cst (integer_type_node);
1827 }
1828 else
1829 {
1830 gcc_assert (errlen != NULL_TREE);
1831 if (!POINTER_TYPE_P (TREE_TYPE (errmsg)))
1832 errmsg = gfc_build_addr_expr (NULL_TREE, errmsg);
1833 }
1834
5d81ddd0
TB
1835 if (status != NULL_TREE && !integer_zerop (status))
1836 {
1837 gcc_assert (status_type == integer_type_node);
1838 pstat = status;
1839 }
1840
5d81ddd0 1841 token = gfc_build_addr_expr (NULL_TREE, token);
ba85c8c3 1842 gcc_assert (caf_dereg_type > GFC_CAF_COARRAY_ANALYZE);
5d81ddd0 1843 tmp = build_call_expr_loc (input_location,
ba85c8c3
AV
1844 gfor_fndecl_caf_deregister, 5,
1845 token, build_int_cst (integer_type_node,
1846 caf_dereg_type),
1847 pstat, errmsg, errlen);
2c807128 1848 gfc_add_expr_to_block (&non_null, tmp);
5d81ddd0 1849
985f6c79
TB
1850 /* It guarantees memory consistency within the same segment */
1851 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1852 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1853 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1854 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1855 ASM_VOLATILE_P (tmp) = 1;
1856 gfc_add_expr_to_block (&non_null, tmp);
1857
5d81ddd0
TB
1858 if (status != NULL_TREE)
1859 {
1860 tree stat = build_fold_indirect_ref_loc (input_location, status);
39da5866
AV
1861 tree nullify = fold_build2_loc (input_location, MODIFY_EXPR,
1862 void_type_node, pointer,
1863 build_int_cst (TREE_TYPE (pointer),
1864 0));
5d81ddd0
TB
1865
1866 TREE_USED (label_finish) = 1;
1867 tmp = build1_v (GOTO_EXPR, label_finish);
63ee5404 1868 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
5d81ddd0
TB
1869 stat, build_zero_cst (TREE_TYPE (stat)));
1870 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
7f7fa20f 1871 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
39da5866 1872 tmp, nullify);
5d81ddd0
TB
1873 gfc_add_expr_to_block (&non_null, tmp);
1874 }
39da5866
AV
1875 else
1876 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
1877 0));
2c807128
JW
1878 }
1879
1880 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
1881 gfc_finish_block (&null),
1882 gfc_finish_block (&non_null));
1883}
1884
1885
1886/* Generate code for deallocation of allocatable scalars (variables or
1887 components). Before the object itself is freed, any allocatable
1888 subcomponents are being deallocated. */
1889
1890tree
ba85c8c3
AV
1891gfc_deallocate_scalar_with_status (tree pointer, tree status, tree label_finish,
1892 bool can_fail, gfc_expr* expr,
1893 gfc_typespec ts, bool coarray)
2c807128
JW
1894{
1895 stmtblock_t null, non_null;
1896 tree cond, tmp, error;
ba85c8c3
AV
1897 bool finalizable, comp_ref;
1898 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
1899
1900 if (coarray && expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
1901 && comp_ref)
1902 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
2c807128 1903
63ee5404 1904 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
2c807128
JW
1905 build_int_cst (TREE_TYPE (pointer), 0));
1906
1907 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1908 we emit a runtime error. */
1909 gfc_start_block (&null);
1910 if (!can_fail)
1911 {
1912 tree varname;
1913
1914 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1915
1916 varname = gfc_build_cstring_const (expr->symtree->name);
1917 varname = gfc_build_addr_expr (pchar_type_node, varname);
1918
1919 error = gfc_trans_runtime_error (true, &expr->where,
1920 "Attempt to DEALLOCATE unallocated '%s'",
1921 varname);
1922 }
1923 else
1924 error = build_empty_stmt (input_location);
1925
1926 if (status != NULL_TREE && !integer_zerop (status))
1927 {
1928 tree status_type = TREE_TYPE (TREE_TYPE (status));
1929 tree cond2;
1930
63ee5404 1931 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
2c807128
JW
1932 status, build_int_cst (TREE_TYPE (status), 0));
1933 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1934 fold_build1_loc (input_location, INDIRECT_REF,
1935 status_type, status),
1936 build_int_cst (status_type, 1));
1937 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1938 cond2, tmp, error);
1939 }
2c807128
JW
1940 gfc_add_expr_to_block (&null, error);
1941
1942 /* When POINTER is not NULL, we free it. */
1943 gfc_start_block (&non_null);
8b704316 1944
2c807128 1945 /* Free allocatable components. */
ef292537
TB
1946 finalizable = gfc_add_finalizer_call (&non_null, expr);
1947 if (!finalizable && ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
2c807128 1948 {
39da5866
AV
1949 int caf_mode = coarray
1950 ? ((caf_dereg_type == GFC_CAF_COARRAY_DEALLOCATE_ONLY
1951 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0)
1952 | GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
1953 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY)
1954 : 0;
1955 if (coarray && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
ba85c8c3
AV
1956 tmp = gfc_conv_descriptor_data_get (pointer);
1957 else
1958 tmp = build_fold_indirect_ref_loc (input_location, pointer);
39da5866 1959 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0, caf_mode);
2c807128
JW
1960 gfc_add_expr_to_block (&non_null, tmp);
1961 }
8b704316 1962
de91486c 1963 if (!coarray || flag_coarray == GFC_FCOARRAY_SINGLE)
ba85c8c3
AV
1964 {
1965 tmp = build_call_expr_loc (input_location,
1966 builtin_decl_explicit (BUILT_IN_FREE), 1,
1967 fold_convert (pvoid_type_node, pointer));
1968 gfc_add_expr_to_block (&non_null, tmp);
4376b7cf 1969
ba85c8c3
AV
1970 if (status != NULL_TREE && !integer_zerop (status))
1971 {
1972 /* We set STATUS to zero if it is present. */
1973 tree status_type = TREE_TYPE (TREE_TYPE (status));
1974 tree cond2;
1975
63ee5404 1976 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
ba85c8c3
AV
1977 status,
1978 build_int_cst (TREE_TYPE (status), 0));
1979 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1980 fold_build1_loc (input_location, INDIRECT_REF,
1981 status_type, status),
1982 build_int_cst (status_type, 0));
1983 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1984 cond2, tmp, build_empty_stmt (input_location));
1985 gfc_add_expr_to_block (&non_null, tmp);
1986 }
1987 }
1988 else
4376b7cf 1989 {
ba85c8c3
AV
1990 tree token;
1991 tree pstat = null_pointer_node;
1992 gfc_se se;
4376b7cf 1993
ba85c8c3
AV
1994 gfc_init_se (&se, NULL);
1995 token = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
1996 gcc_assert (token != NULL_TREE);
1997
1998 if (status != NULL_TREE && !integer_zerop (status))
1999 {
2000 gcc_assert (TREE_TYPE (TREE_TYPE (status)) == integer_type_node);
2001 pstat = status;
2002 }
2003
2004 tmp = build_call_expr_loc (input_location,
2005 gfor_fndecl_caf_deregister, 5,
2006 token, build_int_cst (integer_type_node,
2007 caf_dereg_type),
2008 pstat, null_pointer_node, integer_zero_node);
2009 gfc_add_expr_to_block (&non_null, tmp);
2010
2011 /* It guarantees memory consistency within the same segment. */
39da5866 2012 tmp = gfc_build_string_const (strlen ("memory")+1, "memory");
ba85c8c3
AV
2013 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
2014 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
2015 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
2016 ASM_VOLATILE_P (tmp) = 1;
4376b7cf 2017 gfc_add_expr_to_block (&non_null, tmp);
ba85c8c3
AV
2018
2019 if (status != NULL_TREE)
2020 {
2021 tree stat = build_fold_indirect_ref_loc (input_location, status);
2022 tree cond2;
2023
2024 TREE_USED (label_finish) = 1;
2025 tmp = build1_v (GOTO_EXPR, label_finish);
63ee5404 2026 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
ba85c8c3
AV
2027 stat, build_zero_cst (TREE_TYPE (stat)));
2028 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2029 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
2030 tmp, build_empty_stmt (input_location));
2031 gfc_add_expr_to_block (&non_null, tmp);
2032 }
4376b7cf
FXC
2033 }
2034
65a9ca82
TB
2035 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
2036 gfc_finish_block (&null),
2037 gfc_finish_block (&non_null));
4376b7cf
FXC
2038}
2039
4376b7cf
FXC
2040/* Reallocate MEM so it has SIZE bytes of data. This behaves like the
2041 following pseudo-code:
2042
2043void *
2044internal_realloc (void *mem, size_t size)
2045{
28762eb0
FXC
2046 res = realloc (mem, size);
2047 if (!res && size != 0)
bd085c20 2048 _gfortran_os_error ("Allocation would exceed memory limit");
4376b7cf 2049
28762eb0 2050 return res;
4376b7cf
FXC
2051} */
2052tree
2053gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
2054{
d74a8b05 2055 tree res, nonzero, null_result, tmp;
4376b7cf
FXC
2056 tree type = TREE_TYPE (mem);
2057
107051a5
FXC
2058 /* Only evaluate the size once. */
2059 size = save_expr (fold_convert (size_type_node, size));
4376b7cf
FXC
2060
2061 /* Create a variable to hold the result. */
2062 res = gfc_create_var (type, NULL);
2063
4376b7cf 2064 /* Call realloc and check the result. */
db3927fb 2065 tmp = build_call_expr_loc (input_location,
e79983f4 2066 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
4376b7cf 2067 fold_convert (pvoid_type_node, mem), size);
726a989a 2068 gfc_add_modify (block, res, fold_convert (type, tmp));
63ee5404 2069 null_result = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
65a9ca82 2070 res, build_int_cst (pvoid_type_node, 0));
63ee5404 2071 nonzero = fold_build2_loc (input_location, NE_EXPR, logical_type_node, size,
65a9ca82 2072 build_int_cst (size_type_node, 0));
63ee5404 2073 null_result = fold_build2_loc (input_location, TRUTH_AND_EXPR, logical_type_node,
65a9ca82 2074 null_result, nonzero);
65a9ca82
TB
2075 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2076 null_result,
d74a8b05
JB
2077 trans_os_error_at (NULL,
2078 "Error reallocating to %lu bytes",
2079 fold_convert
2080 (long_unsigned_type_node, size)),
65a9ca82 2081 build_empty_stmt (input_location));
4376b7cf
FXC
2082 gfc_add_expr_to_block (block, tmp);
2083
4376b7cf
FXC
2084 return res;
2085}
2086
6de9cd9a 2087
0019d498 2088/* Add an expression to another one, either at the front or the back. */
6de9cd9a 2089
0019d498
DK
2090static void
2091add_expr_to_chain (tree* chain, tree expr, bool front)
2092{
6de9cd9a
DN
2093 if (expr == NULL_TREE || IS_EMPTY_STMT (expr))
2094 return;
2095
0019d498 2096 if (*chain)
7c87eac6 2097 {
0019d498 2098 if (TREE_CODE (*chain) != STATEMENT_LIST)
7c87eac6
PB
2099 {
2100 tree tmp;
2101
0019d498
DK
2102 tmp = *chain;
2103 *chain = NULL_TREE;
2104 append_to_statement_list (tmp, chain);
7c87eac6 2105 }
0019d498
DK
2106
2107 if (front)
2108 {
2109 tree_stmt_iterator i;
2110
2111 i = tsi_start (*chain);
2112 tsi_link_before (&i, expr, TSI_CONTINUE_LINKING);
2113 }
2114 else
2115 append_to_statement_list (expr, chain);
7c87eac6 2116 }
6de9cd9a 2117 else
0019d498
DK
2118 *chain = expr;
2119}
2120
46b2c440
MM
2121
2122/* Add a statement at the end of a block. */
0019d498
DK
2123
2124void
2125gfc_add_expr_to_block (stmtblock_t * block, tree expr)
2126{
2127 gcc_assert (block);
2128 add_expr_to_chain (&block->head, expr, false);
6de9cd9a
DN
2129}
2130
2131
46b2c440
MM
2132/* Add a statement at the beginning of a block. */
2133
2134void
2135gfc_prepend_expr_to_block (stmtblock_t * block, tree expr)
2136{
2137 gcc_assert (block);
2138 add_expr_to_chain (&block->head, expr, true);
2139}
2140
2141
6de9cd9a
DN
2142/* Add a block the end of a block. */
2143
2144void
2145gfc_add_block_to_block (stmtblock_t * block, stmtblock_t * append)
2146{
6e45f57b
PB
2147 gcc_assert (append);
2148 gcc_assert (!append->has_scope);
6de9cd9a
DN
2149
2150 gfc_add_expr_to_block (block, append->head);
2151 append->head = NULL_TREE;
2152}
2153
2154
363aab21
MM
2155/* Save the current locus. The structure may not be complete, and should
2156 only be used with gfc_restore_backend_locus. */
6de9cd9a
DN
2157
2158void
363aab21 2159gfc_save_backend_locus (locus * loc)
6de9cd9a 2160{
ece3f663 2161 loc->lb = XCNEW (gfc_linebuf);
8e400578 2162 loc->lb->location = input_location;
d4fa05b9 2163 loc->lb->file = gfc_current_backend_file;
6de9cd9a
DN
2164}
2165
2166
2167/* Set the current locus. */
2168
2169void
2170gfc_set_backend_locus (locus * loc)
2171{
d4fa05b9 2172 gfc_current_backend_file = loc->lb->file;
5677444f 2173 input_location = gfc_get_location (loc);
6de9cd9a
DN
2174}
2175
2176
6bd2c800 2177/* Restore the saved locus. Only used in conjunction with
363aab21
MM
2178 gfc_save_backend_locus, to free the memory when we are done. */
2179
2180void
2181gfc_restore_backend_locus (locus * loc)
2182{
5677444f
TS
2183 /* This only restores the information captured by gfc_save_backend_locus,
2184 intentionally does not use gfc_get_location. */
2185 input_location = loc->lb->location;
2186 gfc_current_backend_file = loc->lb->file;
cede9502 2187 free (loc->lb);
363aab21
MM
2188}
2189
2190
bc51e726
JD
2191/* Translate an executable statement. The tree cond is used by gfc_trans_do.
2192 This static function is wrapped by gfc_trans_code_cond and
2193 gfc_trans_code. */
6de9cd9a 2194
bc51e726
JD
2195static tree
2196trans_code (gfc_code * code, tree cond)
6de9cd9a
DN
2197{
2198 stmtblock_t block;
2199 tree res;
2200
2201 if (!code)
c2255bc4 2202 return build_empty_stmt (input_location);
6de9cd9a
DN
2203
2204 gfc_start_block (&block);
2205
726a989a 2206 /* Translate statements one by one into GENERIC trees until we reach
6de9cd9a
DN
2207 the end of this gfc_code branch. */
2208 for (; code; code = code->next)
2209 {
6de9cd9a
DN
2210 if (code->here != 0)
2211 {
2212 res = gfc_trans_label_here (code);
2213 gfc_add_expr_to_block (&block, res);
2214 }
2215
78ab5260 2216 gfc_current_locus = code->loc;
88e09c79
JJ
2217 gfc_set_backend_locus (&code->loc);
2218
6de9cd9a
DN
2219 switch (code->op)
2220 {
2221 case EXEC_NOP:
d80c695f 2222 case EXEC_END_BLOCK:
df1a69f6 2223 case EXEC_END_NESTED_BLOCK:
5c71a5e0 2224 case EXEC_END_PROCEDURE:
6de9cd9a
DN
2225 res = NULL_TREE;
2226 break;
2227
2228 case EXEC_ASSIGN:
574284e9 2229 res = gfc_trans_assign (code);
6de9cd9a
DN
2230 break;
2231
2232 case EXEC_LABEL_ASSIGN:
2233 res = gfc_trans_label_assign (code);
2234 break;
2235
2236 case EXEC_POINTER_ASSIGN:
574284e9 2237 res = gfc_trans_pointer_assign (code);
6de9cd9a
DN
2238 break;
2239
6b591ec0 2240 case EXEC_INIT_ASSIGN:
7adac79a 2241 if (code->expr1->ts.type == BT_CLASS)
b2a5eb75 2242 res = gfc_trans_class_init_assign (code);
7adac79a
JW
2243 else
2244 res = gfc_trans_init_assign (code);
6b591ec0
PT
2245 break;
2246
6de9cd9a
DN
2247 case EXEC_CONTINUE:
2248 res = NULL_TREE;
2249 break;
2250
d0a4a61c
TB
2251 case EXEC_CRITICAL:
2252 res = gfc_trans_critical (code);
2253 break;
2254
6de9cd9a
DN
2255 case EXEC_CYCLE:
2256 res = gfc_trans_cycle (code);
2257 break;
2258
2259 case EXEC_EXIT:
2260 res = gfc_trans_exit (code);
2261 break;
2262
2263 case EXEC_GOTO:
2264 res = gfc_trans_goto (code);
2265 break;
2266
3d79abbd
PB
2267 case EXEC_ENTRY:
2268 res = gfc_trans_entry (code);
2269 break;
2270
6de9cd9a
DN
2271 case EXEC_PAUSE:
2272 res = gfc_trans_pause (code);
2273 break;
2274
2275 case EXEC_STOP:
d0a4a61c
TB
2276 case EXEC_ERROR_STOP:
2277 res = gfc_trans_stop (code, code->op == EXEC_ERROR_STOP);
6de9cd9a
DN
2278 break;
2279
2280 case EXEC_CALL:
12f681a0
DK
2281 /* For MVBITS we've got the special exception that we need a
2282 dependency check, too. */
2283 {
2284 bool is_mvbits = false;
da661a58
TB
2285
2286 if (code->resolved_isym)
2287 {
2288 res = gfc_conv_intrinsic_subroutine (code);
2289 if (res != NULL_TREE)
2290 break;
2291 }
2292
12f681a0
DK
2293 if (code->resolved_isym
2294 && code->resolved_isym->id == GFC_ISYM_MVBITS)
2295 is_mvbits = true;
da661a58
TB
2296
2297 res = gfc_trans_call (code, is_mvbits, NULL_TREE,
2298 NULL_TREE, false);
12f681a0 2299 }
476220e7
PT
2300 break;
2301
713485cc 2302 case EXEC_CALL_PPC:
eb74e79b
PT
2303 res = gfc_trans_call (code, false, NULL_TREE,
2304 NULL_TREE, false);
713485cc
JW
2305 break;
2306
476220e7 2307 case EXEC_ASSIGN_CALL:
eb74e79b
PT
2308 res = gfc_trans_call (code, true, NULL_TREE,
2309 NULL_TREE, false);
6de9cd9a
DN
2310 break;
2311
2312 case EXEC_RETURN:
2313 res = gfc_trans_return (code);
2314 break;
2315
2316 case EXEC_IF:
2317 res = gfc_trans_if (code);
2318 break;
2319
2320 case EXEC_ARITHMETIC_IF:
2321 res = gfc_trans_arithmetic_if (code);
9abe5e56
DK
2322 break;
2323
2324 case EXEC_BLOCK:
2325 res = gfc_trans_block_construct (code);
6de9cd9a
DN
2326 break;
2327
2328 case EXEC_DO:
bc51e726 2329 res = gfc_trans_do (code, cond);
6de9cd9a
DN
2330 break;
2331
8c6a85e3
TB
2332 case EXEC_DO_CONCURRENT:
2333 res = gfc_trans_do_concurrent (code);
2334 break;
2335
6de9cd9a
DN
2336 case EXEC_DO_WHILE:
2337 res = gfc_trans_do_while (code);
2338 break;
2339
2340 case EXEC_SELECT:
2341 res = gfc_trans_select (code);
2342 break;
2343
cf2b3c22 2344 case EXEC_SELECT_TYPE:
dfd6231e 2345 res = gfc_trans_select_type (code);
cf2b3c22
TB
2346 break;
2347
70570ec1
PT
2348 case EXEC_SELECT_RANK:
2349 res = gfc_trans_select_rank (code);
2350 break;
2351
6403ec5f
JB
2352 case EXEC_FLUSH:
2353 res = gfc_trans_flush (code);
2354 break;
2355
d0a4a61c
TB
2356 case EXEC_SYNC_ALL:
2357 case EXEC_SYNC_IMAGES:
2358 case EXEC_SYNC_MEMORY:
2359 res = gfc_trans_sync (code, code->op);
2360 break;
2361
fea54935
TB
2362 case EXEC_LOCK:
2363 case EXEC_UNLOCK:
2364 res = gfc_trans_lock_unlock (code, code->op);
2365 break;
2366
5df445a2
TB
2367 case EXEC_EVENT_POST:
2368 case EXEC_EVENT_WAIT:
2369 res = gfc_trans_event_post_wait (code, code->op);
2370 break;
2371
ef78bc3c
AV
2372 case EXEC_FAIL_IMAGE:
2373 res = gfc_trans_fail_image (code);
2374 break;
2375
6de9cd9a
DN
2376 case EXEC_FORALL:
2377 res = gfc_trans_forall (code);
2378 break;
2379
f8862a1b
DR
2380 case EXEC_FORM_TEAM:
2381 res = gfc_trans_form_team (code);
2382 break;
2383
2384 case EXEC_CHANGE_TEAM:
2385 res = gfc_trans_change_team (code);
2386 break;
2387
2388 case EXEC_END_TEAM:
2389 res = gfc_trans_end_team (code);
2390 break;
2391
2392 case EXEC_SYNC_TEAM:
2393 res = gfc_trans_sync_team (code);
2394 break;
2395
6de9cd9a
DN
2396 case EXEC_WHERE:
2397 res = gfc_trans_where (code);
2398 break;
2399
2400 case EXEC_ALLOCATE:
2401 res = gfc_trans_allocate (code);
2402 break;
2403
2404 case EXEC_DEALLOCATE:
2405 res = gfc_trans_deallocate (code);
2406 break;
2407
2408 case EXEC_OPEN:
2409 res = gfc_trans_open (code);
2410 break;
2411
2412 case EXEC_CLOSE:
2413 res = gfc_trans_close (code);
2414 break;
2415
2416 case EXEC_READ:
2417 res = gfc_trans_read (code);
2418 break;
2419
2420 case EXEC_WRITE:
2421 res = gfc_trans_write (code);
2422 break;
2423
2424 case EXEC_IOLENGTH:
2425 res = gfc_trans_iolength (code);
2426 break;
2427
2428 case EXEC_BACKSPACE:
2429 res = gfc_trans_backspace (code);
2430 break;
2431
2432 case EXEC_ENDFILE:
2433 res = gfc_trans_endfile (code);
2434 break;
2435
2436 case EXEC_INQUIRE:
2437 res = gfc_trans_inquire (code);
2438 break;
2439
6f0f0b2e
JD
2440 case EXEC_WAIT:
2441 res = gfc_trans_wait (code);
2442 break;
2443
6de9cd9a
DN
2444 case EXEC_REWIND:
2445 res = gfc_trans_rewind (code);
2446 break;
2447
2448 case EXEC_TRANSFER:
2449 res = gfc_trans_transfer (code);
2450 break;
2451
2452 case EXEC_DT_END:
2453 res = gfc_trans_dt_end (code);
2454 break;
2455
e2a22843 2456 case EXEC_OMP_ASSUME:
6c7a4dfd
JJ
2457 case EXEC_OMP_ATOMIC:
2458 case EXEC_OMP_BARRIER:
dd2fc525
JJ
2459 case EXEC_OMP_CANCEL:
2460 case EXEC_OMP_CANCELLATION_POINT:
6c7a4dfd 2461 case EXEC_OMP_CRITICAL:
a61c4964 2462 case EXEC_OMP_DEPOBJ:
f014c653
JJ
2463 case EXEC_OMP_DISTRIBUTE:
2464 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
2465 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
2466 case EXEC_OMP_DISTRIBUTE_SIMD:
6c7a4dfd 2467 case EXEC_OMP_DO:
dd2fc525 2468 case EXEC_OMP_DO_SIMD:
178191e1 2469 case EXEC_OMP_LOOP:
77167196 2470 case EXEC_OMP_ERROR:
6c7a4dfd 2471 case EXEC_OMP_FLUSH:
53d5b59c
TB
2472 case EXEC_OMP_MASKED:
2473 case EXEC_OMP_MASKED_TASKLOOP:
2474 case EXEC_OMP_MASKED_TASKLOOP_SIMD:
6c7a4dfd 2475 case EXEC_OMP_MASTER:
f6bf436d
TB
2476 case EXEC_OMP_MASTER_TASKLOOP:
2477 case EXEC_OMP_MASTER_TASKLOOP_SIMD:
6c7a4dfd
JJ
2478 case EXEC_OMP_ORDERED:
2479 case EXEC_OMP_PARALLEL:
2480 case EXEC_OMP_PARALLEL_DO:
dd2fc525 2481 case EXEC_OMP_PARALLEL_DO_SIMD:
178191e1 2482 case EXEC_OMP_PARALLEL_LOOP:
53d5b59c
TB
2483 case EXEC_OMP_PARALLEL_MASKED:
2484 case EXEC_OMP_PARALLEL_MASKED_TASKLOOP:
2485 case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
0e3702f8 2486 case EXEC_OMP_PARALLEL_MASTER:
f6bf436d
TB
2487 case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
2488 case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
6c7a4dfd
JJ
2489 case EXEC_OMP_PARALLEL_SECTIONS:
2490 case EXEC_OMP_PARALLEL_WORKSHARE:
f8d535f3 2491 case EXEC_OMP_SCOPE:
6c7a4dfd 2492 case EXEC_OMP_SECTIONS:
dd2fc525 2493 case EXEC_OMP_SIMD:
6c7a4dfd 2494 case EXEC_OMP_SINGLE:
f014c653
JJ
2495 case EXEC_OMP_TARGET:
2496 case EXEC_OMP_TARGET_DATA:
b4c3a85b
JJ
2497 case EXEC_OMP_TARGET_ENTER_DATA:
2498 case EXEC_OMP_TARGET_EXIT_DATA:
2499 case EXEC_OMP_TARGET_PARALLEL:
2500 case EXEC_OMP_TARGET_PARALLEL_DO:
2501 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
178191e1 2502 case EXEC_OMP_TARGET_PARALLEL_LOOP:
b4c3a85b 2503 case EXEC_OMP_TARGET_SIMD:
f014c653
JJ
2504 case EXEC_OMP_TARGET_TEAMS:
2505 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
2506 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
2507 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2508 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
178191e1 2509 case EXEC_OMP_TARGET_TEAMS_LOOP:
f014c653 2510 case EXEC_OMP_TARGET_UPDATE:
a68ab351 2511 case EXEC_OMP_TASK:
dd2fc525 2512 case EXEC_OMP_TASKGROUP:
b4c3a85b
JJ
2513 case EXEC_OMP_TASKLOOP:
2514 case EXEC_OMP_TASKLOOP_SIMD:
a68ab351 2515 case EXEC_OMP_TASKWAIT:
20906c66 2516 case EXEC_OMP_TASKYIELD:
f014c653
JJ
2517 case EXEC_OMP_TEAMS:
2518 case EXEC_OMP_TEAMS_DISTRIBUTE:
2519 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
2520 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2521 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
178191e1 2522 case EXEC_OMP_TEAMS_LOOP:
6c7a4dfd
JJ
2523 case EXEC_OMP_WORKSHARE:
2524 res = gfc_trans_omp_directive (code);
2525 break;
2526
41dbbb37
TS
2527 case EXEC_OACC_CACHE:
2528 case EXEC_OACC_WAIT:
2529 case EXEC_OACC_UPDATE:
2530 case EXEC_OACC_LOOP:
2531 case EXEC_OACC_HOST_DATA:
2532 case EXEC_OACC_DATA:
2533 case EXEC_OACC_KERNELS:
2534 case EXEC_OACC_KERNELS_LOOP:
2535 case EXEC_OACC_PARALLEL:
2536 case EXEC_OACC_PARALLEL_LOOP:
62aee289
MR
2537 case EXEC_OACC_SERIAL:
2538 case EXEC_OACC_SERIAL_LOOP:
41dbbb37
TS
2539 case EXEC_OACC_ENTER_DATA:
2540 case EXEC_OACC_EXIT_DATA:
4bf9e5a8 2541 case EXEC_OACC_ATOMIC:
dc7a8b4b 2542 case EXEC_OACC_DECLARE:
41dbbb37
TS
2543 res = gfc_trans_oacc_directive (code);
2544 break;
2545
6de9cd9a 2546 default:
17d5d49f 2547 gfc_internal_error ("gfc_trans_code(): Bad statement code");
6de9cd9a
DN
2548 }
2549
bf737879
TS
2550 gfc_set_backend_locus (&code->loc);
2551
6de9cd9a
DN
2552 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
2553 {
60f5ed26 2554 if (TREE_CODE (res) != STATEMENT_LIST)
c8cc8542 2555 SET_EXPR_LOCATION (res, input_location);
8b704316 2556
bf737879 2557 /* Add the new statement to the block. */
6de9cd9a
DN
2558 gfc_add_expr_to_block (&block, res);
2559 }
2560 }
2561
2562 /* Return the finished block. */
2563 return gfc_finish_block (&block);
2564}
2565
2566
bc51e726
JD
2567/* Translate an executable statement with condition, cond. The condition is
2568 used by gfc_trans_do to test for IO result conditions inside implied
e53b6e56 2569 DO loops of READ and WRITE statements. See build_dt in trans-io.cc. */
bc51e726
JD
2570
2571tree
2572gfc_trans_code_cond (gfc_code * code, tree cond)
2573{
2574 return trans_code (code, cond);
2575}
2576
2577/* Translate an executable statement without condition. */
2578
2579tree
2580gfc_trans_code (gfc_code * code)
2581{
2582 return trans_code (code, NULL_TREE);
2583}
2584
2585
6de9cd9a
DN
2586/* This function is called after a complete program unit has been parsed
2587 and resolved. */
2588
2589void
2590gfc_generate_code (gfc_namespace * ns)
2591{
34d01e1d 2592 ompws_flags = 0;
0de4325e
TS
2593 if (ns->is_block_data)
2594 {
2595 gfc_generate_block_data (ns);
2596 return;
2597 }
2598
6de9cd9a
DN
2599 gfc_generate_function_code (ns);
2600}
2601
2602
2603/* This function is called after a complete module has been parsed
2604 and resolved. */
2605
2606void
2607gfc_generate_module_code (gfc_namespace * ns)
2608{
2609 gfc_namespace *n;
a64f5186
JJ
2610 struct module_htab_entry *entry;
2611
2612 gcc_assert (ns->proc_name->backend_decl == NULL);
2613 ns->proc_name->backend_decl
9c81750c 2614 = build_decl (gfc_get_location (&ns->proc_name->declared_at),
c2255bc4 2615 NAMESPACE_DECL, get_identifier (ns->proc_name->name),
a64f5186 2616 void_type_node);
a64f5186
JJ
2617 entry = gfc_find_module (ns->proc_name->name);
2618 if (entry->namespace_decl)
2619 /* Buggy sourcecode, using a module before defining it? */
2a22f99c 2620 entry->decls->empty ();
a64f5186 2621 entry->namespace_decl = ns->proc_name->backend_decl;
6de9cd9a
DN
2622
2623 gfc_generate_module_vars (ns);
2624
2625 /* We need to generate all module function prototypes first, to allow
2626 sibling calls. */
2627 for (n = ns->contained; n; n = n->sibling)
2628 {
a64f5186
JJ
2629 gfc_entry_list *el;
2630
6de9cd9a
DN
2631 if (!n->proc_name)
2632 continue;
2633
fb55ca75 2634 gfc_create_function_decl (n, false);
a64f5186
JJ
2635 DECL_CONTEXT (n->proc_name->backend_decl) = ns->proc_name->backend_decl;
2636 gfc_module_add_decl (entry, n->proc_name->backend_decl);
2637 for (el = ns->entries; el; el = el->next)
2638 {
a64f5186
JJ
2639 DECL_CONTEXT (el->sym->backend_decl) = ns->proc_name->backend_decl;
2640 gfc_module_add_decl (entry, el->sym->backend_decl);
2641 }
6de9cd9a
DN
2642 }
2643
2644 for (n = ns->contained; n; n = n->sibling)
2645 {
2646 if (!n->proc_name)
2647 continue;
2648
2649 gfc_generate_function_code (n);
2650 }
2651}
2652
0019d498
DK
2653
2654/* Initialize an init/cleanup block with existing code. */
2655
2656void
2657gfc_start_wrapped_block (gfc_wrapped_block* block, tree code)
2658{
2659 gcc_assert (block);
2660
2661 block->init = NULL_TREE;
2662 block->code = code;
2663 block->cleanup = NULL_TREE;
2664}
2665
2666
2667/* Add a new pair of initializers/clean-up code. */
2668
2669void
2670gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup)
2671{
2672 gcc_assert (block);
2673
2674 /* The new pair of init/cleanup should be "wrapped around" the existing
2675 block of code, thus the initialization is added to the front and the
2676 cleanup to the back. */
2677 add_expr_to_chain (&block->init, init, true);
2678 add_expr_to_chain (&block->cleanup, cleanup, false);
2679}
2680
2681
2682/* Finish up a wrapped block by building a corresponding try-finally expr. */
2683
2684tree
2685gfc_finish_wrapped_block (gfc_wrapped_block* block)
2686{
2687 tree result;
2688
2689 gcc_assert (block);
2690
2691 /* Build the final expression. For this, just add init and body together,
2692 and put clean-up with that into a TRY_FINALLY_EXPR. */
2693 result = block->init;
2694 add_expr_to_chain (&result, block->code, false);
2695 if (block->cleanup)
5d44e5c8
TB
2696 result = build2_loc (input_location, TRY_FINALLY_EXPR, void_type_node,
2697 result, block->cleanup);
8b704316 2698
0019d498
DK
2699 /* Clear the block. */
2700 block->init = NULL_TREE;
2701 block->code = NULL_TREE;
2702 block->cleanup = NULL_TREE;
2703
2704 return result;
2705}
5af07930
TB
2706
2707
2708/* Helper function for marking a boolean expression tree as unlikely. */
2709
2710tree
ed9c79e1 2711gfc_unlikely (tree cond, enum br_predictor predictor)
5af07930
TB
2712{
2713 tree tmp;
2714
ed9c79e1
JJ
2715 if (optimize)
2716 {
2717 cond = fold_convert (long_integer_type_node, cond);
2718 tmp = build_zero_cst (long_integer_type_node);
2719 cond = build_call_expr_loc (input_location,
2720 builtin_decl_explicit (BUILT_IN_EXPECT),
2721 3, cond, tmp,
2722 build_int_cst (integer_type_node,
2723 predictor));
2724 }
5af07930
TB
2725 return cond;
2726}
4f13e17f
DC
2727
2728
2729/* Helper function for marking a boolean expression tree as likely. */
2730
2731tree
ed9c79e1 2732gfc_likely (tree cond, enum br_predictor predictor)
4f13e17f
DC
2733{
2734 tree tmp;
2735
ed9c79e1
JJ
2736 if (optimize)
2737 {
2738 cond = fold_convert (long_integer_type_node, cond);
2739 tmp = build_one_cst (long_integer_type_node);
2740 cond = build_call_expr_loc (input_location,
2741 builtin_decl_explicit (BUILT_IN_EXPECT),
2742 3, cond, tmp,
2743 build_int_cst (integer_type_node,
2744 predictor));
2745 }
4f13e17f
DC
2746 return cond;
2747}
2b3dc0db
PT
2748
2749
2750/* Get the string length for a deferred character length component. */
2751
2752bool
2753gfc_deferred_strlen (gfc_component *c, tree *decl)
2754{
2755 char name[GFC_MAX_SYMBOL_LEN+9];
2756 gfc_component *strlen;
5bab4c96
PT
2757 if (!(c->ts.type == BT_CHARACTER
2758 && (c->ts.deferred || c->attr.pdt_string)))
2b3dc0db
PT
2759 return false;
2760 sprintf (name, "_%s_length", c->name);
2761 for (strlen = c; strlen; strlen = strlen->next)
2762 if (strcmp (strlen->name, name) == 0)
2763 break;
2764 *decl = strlen ? strlen->backend_decl : NULL_TREE;
2765 return strlen != NULL;
2766}
This page took 6.92678 seconds and 5 git commands to generate.