ada: Fix spurious -Wstringop-overflow with link time optimization
[official-gcc.git] / gcc / fortran / trans.cc
blobe2e1b694012368f60176f8107e0f16b03e120f11
1 /* Code translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2023 Free Software Foundation, Inc.
3 Contributed by Paul Brook
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "options.h"
25 #include "tree.h"
26 #include "gfortran.h"
27 #include "gimple-expr.h" /* For create_tmp_var_raw. */
28 #include "trans.h"
29 #include "stringpool.h"
30 #include "fold-const.h"
31 #include "tree-iterator.h"
32 #include "trans-stmt.h"
33 #include "trans-array.h"
34 #include "trans-types.h"
35 #include "trans-const.h"
37 /* Naming convention for backend interface code:
39 gfc_trans_* translate gfc_code into STMT trees.
41 gfc_conv_* expression conversion
43 gfc_get_* get a backend tree representation of a decl or type */
45 static gfc_file *gfc_current_backend_file;
47 const char gfc_msg_fault[] = N_("Array reference out of bounds");
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
53 locations for 'tree'. Cf. error.cc's gfc_format_decoder. */
55 location_t
56 gfc_get_location (locus *loc)
58 return linemap_position_for_loc_and_offset (line_table, loc->lb->location,
59 loc->nextc - loc->lb->line);
62 /* Advance along TREE_CHAIN n times. */
64 tree
65 gfc_advance_chain (tree t, int n)
67 for (; n > 0; n--)
69 gcc_assert (t != NULL_TREE);
70 t = DECL_CHAIN (t);
72 return t;
75 static int num_var;
77 #define MAX_PREFIX_LEN 20
79 static tree
80 create_var_debug_raw (tree type, const char *prefix)
82 /* Space for prefix + "_" + 10-digit-number + \0. */
83 char name_buf[MAX_PREFIX_LEN + 1 + 10 + 1];
84 tree t;
85 int i;
87 if (prefix == NULL)
88 prefix = "gfc";
89 else
90 gcc_assert (strlen (prefix) <= MAX_PREFIX_LEN);
92 for (i = 0; prefix[i] != 0; i++)
93 name_buf[i] = gfc_wide_toupper (prefix[i]);
95 snprintf (name_buf + i, sizeof (name_buf) - i, "_%d", num_var++);
97 t = build_decl (input_location, VAR_DECL, get_identifier (name_buf), type);
99 /* Not setting this causes some regressions. */
100 DECL_ARTIFICIAL (t) = 1;
102 /* We want debug info for it. */
103 DECL_IGNORED_P (t) = 0;
104 /* It should not be nameless. */
105 DECL_NAMELESS (t) = 0;
107 /* Make the variable writable. */
108 TREE_READONLY (t) = 0;
110 DECL_EXTERNAL (t) = 0;
111 TREE_STATIC (t) = 0;
112 TREE_USED (t) = 1;
114 return t;
117 /* Creates a variable declaration with a given TYPE. */
119 tree
120 gfc_create_var_np (tree type, const char *prefix)
122 tree t;
124 if (flag_debug_aux_vars)
125 return create_var_debug_raw (type, prefix);
127 t = create_tmp_var_raw (type, prefix);
129 /* No warnings for anonymous variables. */
130 if (prefix == NULL)
131 suppress_warning (t);
133 return t;
137 /* Like above, but also adds it to the current scope. */
139 tree
140 gfc_create_var (tree type, const char *prefix)
142 tree tmp;
144 tmp = gfc_create_var_np (type, prefix);
146 pushdecl (tmp);
148 return tmp;
152 /* If the expression is not constant, evaluate it now. We assign the
153 result of the expression to an artificially created variable VAR, and
154 return a pointer to the VAR_DECL node for this variable. */
156 tree
157 gfc_evaluate_now_loc (location_t loc, tree expr, stmtblock_t * pblock)
159 tree var;
161 if (CONSTANT_CLASS_P (expr))
162 return expr;
164 var = gfc_create_var (TREE_TYPE (expr), NULL);
165 gfc_add_modify_loc (loc, pblock, var, expr);
167 return var;
171 tree
172 gfc_evaluate_now (tree expr, stmtblock_t * pblock)
174 return gfc_evaluate_now_loc (input_location, expr, pblock);
178 /* Returns a fresh pointer variable pointing to the same data as EXPR, adding
179 in BLOCK the initialization code that makes it point to EXPR. */
181 tree
182 gfc_evaluate_data_ref_now (tree expr, stmtblock_t *block)
184 tree t = expr;
186 STRIP_NOPS (t);
188 /* If EXPR can be used as lhs of an assignment, we have to take the address
189 of EXPR. Otherwise, reassigning the pointer would retarget it to some
190 other data without EXPR being retargetted as well. */
191 bool lvalue_p = DECL_P (t) || REFERENCE_CLASS_P (t) || INDIRECT_REF_P (t);
193 tree value;
194 if (lvalue_p)
196 value = gfc_build_addr_expr (NULL_TREE, expr);
197 value = gfc_evaluate_now (value, block);
198 return build_fold_indirect_ref_loc (input_location, value);
200 else
201 return gfc_evaluate_now (expr, block);
205 /* Like gfc_evaluate_now, but add the created variable to the
206 function scope. */
208 tree
209 gfc_evaluate_now_function_scope (tree expr, stmtblock_t * pblock)
211 tree var;
212 var = gfc_create_var_np (TREE_TYPE (expr), NULL);
213 gfc_add_decl_to_function (var);
214 gfc_add_modify (pblock, var, expr);
216 return var;
219 /* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
220 A MODIFY_EXPR is an assignment:
221 LHS <- RHS. */
223 void
224 gfc_add_modify_loc (location_t loc, stmtblock_t * pblock, tree lhs, tree rhs)
226 tree tmp;
228 tree t1, t2;
229 t1 = TREE_TYPE (rhs);
230 t2 = TREE_TYPE (lhs);
231 /* Make sure that the types of the rhs and the lhs are compatible
232 for scalar assignments. We should probably have something
233 similar for aggregates, but right now removing that check just
234 breaks everything. */
235 gcc_checking_assert (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)
236 || AGGREGATE_TYPE_P (TREE_TYPE (lhs)));
238 tmp = fold_build2_loc (loc, MODIFY_EXPR, void_type_node, lhs,
239 rhs);
240 gfc_add_expr_to_block (pblock, tmp);
244 void
245 gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs)
247 gfc_add_modify_loc (input_location, pblock, lhs, rhs);
251 /* Create a new scope/binding level and initialize a block. Care must be
252 taken when translating expressions as any temporaries will be placed in
253 the innermost scope. */
255 void
256 gfc_start_block (stmtblock_t * block)
258 /* Start a new binding level. */
259 pushlevel ();
260 block->has_scope = 1;
262 /* The block is empty. */
263 block->head = NULL_TREE;
267 /* Initialize a block without creating a new scope. */
269 void
270 gfc_init_block (stmtblock_t * block)
272 block->head = NULL_TREE;
273 block->has_scope = 0;
277 /* Sometimes we create a scope but it turns out that we don't actually
278 need it. This function merges the scope of BLOCK with its parent.
279 Only variable decls will be merged, you still need to add the code. */
281 void
282 gfc_merge_block_scope (stmtblock_t * block)
284 tree decl;
285 tree next;
287 gcc_assert (block->has_scope);
288 block->has_scope = 0;
290 /* Remember the decls in this scope. */
291 decl = getdecls ();
292 poplevel (0, 0);
294 /* Add them to the parent scope. */
295 while (decl != NULL_TREE)
297 next = DECL_CHAIN (decl);
298 DECL_CHAIN (decl) = NULL_TREE;
300 pushdecl (decl);
301 decl = next;
306 /* Finish a scope containing a block of statements. */
308 tree
309 gfc_finish_block (stmtblock_t * stmtblock)
311 tree decl;
312 tree expr;
313 tree block;
315 expr = stmtblock->head;
316 if (!expr)
317 expr = build_empty_stmt (input_location);
319 stmtblock->head = NULL_TREE;
321 if (stmtblock->has_scope)
323 decl = getdecls ();
325 if (decl)
327 block = poplevel (1, 0);
328 expr = build3_v (BIND_EXPR, decl, expr, block);
330 else
331 poplevel (0, 0);
334 return expr;
338 /* Build an ADDR_EXPR and cast the result to TYPE. If TYPE is NULL, the
339 natural type is used. */
341 tree
342 gfc_build_addr_expr (tree type, tree t)
344 tree base_type = TREE_TYPE (t);
345 tree natural_type;
347 if (type && POINTER_TYPE_P (type)
348 && TREE_CODE (base_type) == ARRAY_TYPE
349 && TYPE_MAIN_VARIANT (TREE_TYPE (type))
350 == TYPE_MAIN_VARIANT (TREE_TYPE (base_type)))
352 tree min_val = size_zero_node;
353 tree type_domain = TYPE_DOMAIN (base_type);
354 if (type_domain && TYPE_MIN_VALUE (type_domain))
355 min_val = TYPE_MIN_VALUE (type_domain);
356 t = fold (build4_loc (input_location, ARRAY_REF, TREE_TYPE (type),
357 t, min_val, NULL_TREE, NULL_TREE));
358 natural_type = type;
360 else
361 natural_type = build_pointer_type (base_type);
363 if (INDIRECT_REF_P (t))
365 if (!type)
366 type = natural_type;
367 t = TREE_OPERAND (t, 0);
368 natural_type = TREE_TYPE (t);
370 else
372 tree base = get_base_address (t);
373 if (base && DECL_P (base))
374 TREE_ADDRESSABLE (base) = 1;
375 t = fold_build1_loc (input_location, ADDR_EXPR, natural_type, t);
378 if (type && natural_type != type)
379 t = convert (type, t);
381 return t;
385 static tree
386 get_array_span (tree type, tree decl)
388 tree span;
390 /* Component references are guaranteed to have a reliable value for
391 'span'. Likewise indirect references since they emerge from the
392 conversion of a CFI descriptor or the hidden dummy descriptor. */
393 if (TREE_CODE (decl) == COMPONENT_REF
394 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
395 return gfc_conv_descriptor_span_get (decl);
396 else if (INDIRECT_REF_P (decl)
397 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
398 return gfc_conv_descriptor_span_get (decl);
400 /* Return the span for deferred character length array references. */
401 if (type && TREE_CODE (type) == ARRAY_TYPE && TYPE_STRING_FLAG (type))
403 if (TREE_CODE (decl) == PARM_DECL)
404 decl = build_fold_indirect_ref_loc (input_location, decl);
405 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
406 span = gfc_conv_descriptor_span_get (decl);
407 else
408 span = gfc_get_character_len_in_bytes (type);
409 span = (span && !integer_zerop (span))
410 ? (fold_convert (gfc_array_index_type, span)) : (NULL_TREE);
412 /* Likewise for class array or pointer array references. */
413 else if (TREE_CODE (decl) == FIELD_DECL
414 || VAR_OR_FUNCTION_DECL_P (decl)
415 || TREE_CODE (decl) == PARM_DECL)
417 if (GFC_DECL_CLASS (decl))
419 /* When a temporary is in place for the class array, then the
420 original class' declaration is stored in the saved
421 descriptor. */
422 if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
423 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
424 else
426 /* Allow for dummy arguments and other good things. */
427 if (POINTER_TYPE_P (TREE_TYPE (decl)))
428 decl = build_fold_indirect_ref_loc (input_location, decl);
430 /* Check if '_data' is an array descriptor. If it is not,
431 the array must be one of the components of the class
432 object, so return a null span. */
433 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (
434 gfc_class_data_get (decl))))
435 return NULL_TREE;
437 span = gfc_class_vtab_size_get (decl);
438 /* For unlimited polymorphic entities then _len component needs
439 to be multiplied with the size. */
440 span = gfc_resize_class_size_with_len (NULL, decl, span);
442 else if (GFC_DECL_PTR_ARRAY_P (decl))
444 if (TREE_CODE (decl) == PARM_DECL)
445 decl = build_fold_indirect_ref_loc (input_location, decl);
446 span = gfc_conv_descriptor_span_get (decl);
448 else
449 span = NULL_TREE;
451 else
452 span = NULL_TREE;
454 return span;
458 tree
459 gfc_build_spanned_array_ref (tree base, tree offset, tree span)
461 tree type;
462 tree tmp;
463 type = TREE_TYPE (TREE_TYPE (base));
464 offset = fold_build2_loc (input_location, MULT_EXPR,
465 gfc_array_index_type,
466 offset, span);
467 tmp = gfc_build_addr_expr (pvoid_type_node, base);
468 tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
469 tmp = fold_convert (build_pointer_type (type), tmp);
470 if ((TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != ARRAY_TYPE)
471 || !TYPE_STRING_FLAG (type))
472 tmp = build_fold_indirect_ref_loc (input_location, tmp);
473 return tmp;
477 /* Build an ARRAY_REF with its natural type.
478 NON_NEGATIVE_OFFSET indicates if it’s true that OFFSET can’t be negative,
479 and thus that an ARRAY_REF can safely be generated. If it’s false, we
480 have to play it safe and use pointer arithmetic. */
482 tree
483 gfc_build_array_ref (tree base, tree offset, tree decl,
484 bool non_negative_offset, tree vptr)
486 tree type = TREE_TYPE (base);
487 tree span = NULL_TREE;
489 if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0)
491 gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0);
493 return fold_convert (TYPE_MAIN_VARIANT (type), base);
496 /* Scalar coarray, there is nothing to do. */
497 if (TREE_CODE (type) != ARRAY_TYPE)
499 gcc_assert (decl == NULL_TREE);
500 gcc_assert (integer_zerop (offset));
501 return base;
504 type = TREE_TYPE (type);
506 if (DECL_P (base))
507 TREE_ADDRESSABLE (base) = 1;
509 /* Strip NON_LVALUE_EXPR nodes. */
510 STRIP_TYPE_NOPS (offset);
512 /* If decl or vptr are non-null, pointer arithmetic for the array reference
513 is likely. Generate the 'span' for the array reference. */
514 if (vptr)
516 span = gfc_vptr_size_get (vptr);
518 /* Check if this is an unlimited polymorphic object carrying a character
519 payload. In this case, the 'len' field is non-zero. */
520 if (decl && GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
521 span = gfc_resize_class_size_with_len (NULL, decl, span);
523 else if (decl)
524 span = get_array_span (type, decl);
526 /* If a non-null span has been generated reference the element with
527 pointer arithmetic. */
528 if (span != NULL_TREE)
529 return gfc_build_spanned_array_ref (base, offset, span);
530 /* Else use a straightforward array reference if possible. */
531 else if (non_negative_offset)
532 return build4_loc (input_location, ARRAY_REF, type, base, offset,
533 NULL_TREE, NULL_TREE);
534 /* Otherwise use pointer arithmetic. */
535 else
537 gcc_assert (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE);
538 tree min = NULL_TREE;
539 if (TYPE_DOMAIN (TREE_TYPE (base))
540 && !integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)))))
541 min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)));
543 tree zero_based_index
544 = min ? fold_build2_loc (input_location, MINUS_EXPR,
545 gfc_array_index_type,
546 fold_convert (gfc_array_index_type, offset),
547 fold_convert (gfc_array_index_type, min))
548 : fold_convert (gfc_array_index_type, offset);
550 tree elt_size = fold_convert (gfc_array_index_type,
551 TYPE_SIZE_UNIT (type));
553 tree offset_bytes = fold_build2_loc (input_location, MULT_EXPR,
554 gfc_array_index_type,
555 zero_based_index, elt_size);
557 tree base_addr = gfc_build_addr_expr (pvoid_type_node, base);
559 tree ptr = fold_build_pointer_plus_loc (input_location, base_addr,
560 offset_bytes);
561 return build1_loc (input_location, INDIRECT_REF, type,
562 fold_convert (build_pointer_type (type), ptr));
567 /* Generate a call to print a runtime error possibly including multiple
568 arguments and a locus. */
570 static tree
571 trans_runtime_error_vararg (tree errorfunc, locus* where, const char* msgid,
572 va_list ap)
574 stmtblock_t block;
575 tree tmp;
576 tree arg, arg2;
577 tree *argarray;
578 tree fntype;
579 char *message;
580 const char *p;
581 int line, nargs, i;
582 location_t loc;
584 /* Compute the number of extra arguments from the format string. */
585 for (p = msgid, nargs = 0; *p; p++)
586 if (*p == '%')
588 p++;
589 if (*p != '%')
590 nargs++;
593 /* The code to generate the error. */
594 gfc_start_block (&block);
596 if (where)
598 line = LOCATION_LINE (where->lb->location);
599 message = xasprintf ("At line %d of file %s", line,
600 where->lb->file->filename);
602 else
603 message = xasprintf ("In file '%s', around line %d",
604 gfc_source_file, LOCATION_LINE (input_location) + 1);
606 arg = gfc_build_addr_expr (pchar_type_node,
607 gfc_build_localized_cstring_const (message));
608 free (message);
610 message = xasprintf ("%s", _(msgid));
611 arg2 = gfc_build_addr_expr (pchar_type_node,
612 gfc_build_localized_cstring_const (message));
613 free (message);
615 /* Build the argument array. */
616 argarray = XALLOCAVEC (tree, nargs + 2);
617 argarray[0] = arg;
618 argarray[1] = arg2;
619 for (i = 0; i < nargs; i++)
620 argarray[2 + i] = va_arg (ap, tree);
622 /* Build the function call to runtime_(warning,error)_at; because of the
623 variable number of arguments, we can't use build_call_expr_loc dinput_location,
624 irectly. */
625 fntype = TREE_TYPE (errorfunc);
627 loc = where ? gfc_get_location (where) : input_location;
628 tmp = fold_build_call_array_loc (loc, TREE_TYPE (fntype),
629 fold_build1_loc (loc, ADDR_EXPR,
630 build_pointer_type (fntype),
631 errorfunc),
632 nargs + 2, argarray);
633 gfc_add_expr_to_block (&block, tmp);
635 return gfc_finish_block (&block);
639 tree
640 gfc_trans_runtime_error (bool error, locus* where, const char* msgid, ...)
642 va_list ap;
643 tree result;
645 va_start (ap, msgid);
646 result = trans_runtime_error_vararg (error
647 ? gfor_fndecl_runtime_error_at
648 : gfor_fndecl_runtime_warning_at,
649 where, msgid, ap);
650 va_end (ap);
651 return result;
655 /* Generate a runtime error if COND is true. */
657 void
658 gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
659 locus * where, const char * msgid, ...)
661 va_list ap;
662 stmtblock_t block;
663 tree body;
664 tree tmp;
665 tree tmpvar = NULL;
667 if (integer_zerop (cond))
668 return;
670 if (once)
672 tmpvar = gfc_create_var (boolean_type_node, "print_warning");
673 TREE_STATIC (tmpvar) = 1;
674 DECL_INITIAL (tmpvar) = boolean_true_node;
675 gfc_add_expr_to_block (pblock, tmpvar);
678 gfc_start_block (&block);
680 /* For error, runtime_error_at already implies PRED_NORETURN. */
681 if (!error && once)
682 gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_WARN_ONCE,
683 NOT_TAKEN));
685 /* The code to generate the error. */
686 va_start (ap, msgid);
687 gfc_add_expr_to_block (&block,
688 trans_runtime_error_vararg
689 (error ? gfor_fndecl_runtime_error_at
690 : gfor_fndecl_runtime_warning_at,
691 where, msgid, ap));
692 va_end (ap);
694 if (once)
695 gfc_add_modify (&block, tmpvar, boolean_false_node);
697 body = gfc_finish_block (&block);
699 if (integer_onep (cond))
701 gfc_add_expr_to_block (pblock, body);
703 else
705 if (once)
706 cond = fold_build2_loc (gfc_get_location (where), TRUTH_AND_EXPR,
707 boolean_type_node, tmpvar,
708 fold_convert (boolean_type_node, cond));
710 tmp = fold_build3_loc (gfc_get_location (where), COND_EXPR, void_type_node,
711 cond, body,
712 build_empty_stmt (gfc_get_location (where)));
713 gfc_add_expr_to_block (pblock, tmp);
718 static tree
719 trans_os_error_at (locus* where, const char* msgid, ...)
721 va_list ap;
722 tree result;
724 va_start (ap, msgid);
725 result = trans_runtime_error_vararg (gfor_fndecl_os_error_at,
726 where, msgid, ap);
727 va_end (ap);
728 return result;
733 /* Call malloc to allocate size bytes of memory, with special conditions:
734 + if size == 0, return a malloced area of size 1,
735 + if malloc returns NULL, issue a runtime error. */
736 tree
737 gfc_call_malloc (stmtblock_t * block, tree type, tree size)
739 tree tmp, malloc_result, null_result, res, malloc_tree;
740 stmtblock_t block2;
742 /* Create a variable to hold the result. */
743 res = gfc_create_var (prvoid_type_node, NULL);
745 /* Call malloc. */
746 gfc_start_block (&block2);
748 if (size == NULL_TREE)
749 size = build_int_cst (size_type_node, 1);
751 size = fold_convert (size_type_node, size);
752 size = fold_build2_loc (input_location, MAX_EXPR, size_type_node, size,
753 build_int_cst (size_type_node, 1));
755 malloc_tree = builtin_decl_explicit (BUILT_IN_MALLOC);
756 gfc_add_modify (&block2, res,
757 fold_convert (prvoid_type_node,
758 build_call_expr_loc (input_location,
759 malloc_tree, 1, size)));
761 /* Optionally check whether malloc was successful. */
762 if (gfc_option.rtcheck & GFC_RTCHECK_MEM)
764 null_result = fold_build2_loc (input_location, EQ_EXPR,
765 logical_type_node, res,
766 build_int_cst (pvoid_type_node, 0));
767 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
768 null_result,
769 trans_os_error_at (NULL,
770 "Error allocating %lu bytes",
771 fold_convert
772 (long_unsigned_type_node,
773 size)),
774 build_empty_stmt (input_location));
775 gfc_add_expr_to_block (&block2, tmp);
778 malloc_result = gfc_finish_block (&block2);
779 gfc_add_expr_to_block (block, malloc_result);
781 if (type != NULL)
782 res = fold_convert (type, res);
783 return res;
787 /* Allocate memory, using an optional status argument.
789 This function follows the following pseudo-code:
791 void *
792 allocate (size_t size, integer_type stat)
794 void *newmem;
796 if (stat requested)
797 stat = 0;
799 newmem = malloc (MAX (size, 1));
800 if (newmem == NULL)
802 if (stat)
803 *stat = LIBERROR_NO_MEMORY;
804 else
805 runtime_error ("Allocation would exceed memory limit");
807 return newmem;
808 } */
809 void
810 gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
811 tree size, tree status)
813 tree tmp, error_cond;
814 stmtblock_t on_error;
815 tree status_type = status ? TREE_TYPE (status) : NULL_TREE;
817 /* If successful and stat= is given, set status to 0. */
818 if (status != NULL_TREE)
819 gfc_add_expr_to_block (block,
820 fold_build2_loc (input_location, MODIFY_EXPR, status_type,
821 status, build_int_cst (status_type, 0)));
823 /* The allocation itself. */
824 size = fold_convert (size_type_node, size);
825 gfc_add_modify (block, pointer,
826 fold_convert (TREE_TYPE (pointer),
827 build_call_expr_loc (input_location,
828 builtin_decl_explicit (BUILT_IN_MALLOC), 1,
829 fold_build2_loc (input_location,
830 MAX_EXPR, size_type_node, size,
831 build_int_cst (size_type_node, 1)))));
833 /* What to do in case of error. */
834 gfc_start_block (&on_error);
835 if (status != NULL_TREE)
837 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, status,
838 build_int_cst (status_type, LIBERROR_NO_MEMORY));
839 gfc_add_expr_to_block (&on_error, tmp);
841 else
843 /* Here, os_error_at already implies PRED_NORETURN. */
844 tree lusize = fold_convert (long_unsigned_type_node, size);
845 tmp = trans_os_error_at (NULL, "Error allocating %lu bytes", lusize);
846 gfc_add_expr_to_block (&on_error, tmp);
849 error_cond = fold_build2_loc (input_location, EQ_EXPR,
850 logical_type_node, pointer,
851 build_int_cst (prvoid_type_node, 0));
852 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
853 gfc_unlikely (error_cond, PRED_FORTRAN_FAIL_ALLOC),
854 gfc_finish_block (&on_error),
855 build_empty_stmt (input_location));
857 gfc_add_expr_to_block (block, tmp);
861 /* Allocate memory, using an optional status argument.
863 This function follows the following pseudo-code:
865 void *
866 allocate (size_t size, void** token, int *stat, char* errmsg, int errlen)
868 void *newmem;
870 newmem = _caf_register (size, regtype, token, &stat, errmsg, errlen);
871 return newmem;
872 } */
873 void
874 gfc_allocate_using_caf_lib (stmtblock_t * block, tree pointer, tree size,
875 tree token, tree status, tree errmsg, tree errlen,
876 gfc_coarray_regtype alloc_type)
878 tree tmp, pstat;
880 gcc_assert (token != NULL_TREE);
882 /* The allocation itself. */
883 if (status == NULL_TREE)
884 pstat = null_pointer_node;
885 else
886 pstat = gfc_build_addr_expr (NULL_TREE, status);
888 if (errmsg == NULL_TREE)
890 gcc_assert(errlen == NULL_TREE);
891 errmsg = null_pointer_node;
892 errlen = build_int_cst (integer_type_node, 0);
895 size = fold_convert (size_type_node, size);
896 tmp = build_call_expr_loc (input_location,
897 gfor_fndecl_caf_register, 7,
898 fold_build2_loc (input_location,
899 MAX_EXPR, size_type_node, size, size_one_node),
900 build_int_cst (integer_type_node, alloc_type),
901 token, gfc_build_addr_expr (pvoid_type_node, pointer),
902 pstat, errmsg, errlen);
904 gfc_add_expr_to_block (block, tmp);
906 /* It guarantees memory consistency within the same segment */
907 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
908 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
909 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
910 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
911 ASM_VOLATILE_P (tmp) = 1;
912 gfc_add_expr_to_block (block, tmp);
916 /* Generate code for an ALLOCATE statement when the argument is an
917 allocatable variable. If the variable is currently allocated, it is an
918 error to allocate it again.
920 This function follows the following pseudo-code:
922 void *
923 allocate_allocatable (void *mem, size_t size, integer_type stat)
925 if (mem == NULL)
926 return allocate (size, stat);
927 else
929 if (stat)
930 stat = LIBERROR_ALLOCATION;
931 else
932 runtime_error ("Attempting to allocate already allocated variable");
936 expr must be set to the original expression being allocated for its locus
937 and variable name in case a runtime error has to be printed. */
938 void
939 gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size,
940 tree token, tree status, tree errmsg, tree errlen,
941 tree label_finish, gfc_expr* expr, int corank)
943 stmtblock_t alloc_block;
944 tree tmp, null_mem, alloc, error;
945 tree type = TREE_TYPE (mem);
946 symbol_attribute caf_attr;
947 bool need_assign = false, refs_comp = false;
948 gfc_coarray_regtype caf_alloc_type = GFC_CAF_COARRAY_ALLOC;
950 size = fold_convert (size_type_node, size);
951 null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
952 logical_type_node, mem,
953 build_int_cst (type, 0)),
954 PRED_FORTRAN_REALLOC);
956 /* If mem is NULL, we call gfc_allocate_using_malloc or
957 gfc_allocate_using_lib. */
958 gfc_start_block (&alloc_block);
960 if (flag_coarray == GFC_FCOARRAY_LIB)
961 caf_attr = gfc_caf_attr (expr, true, &refs_comp);
963 if (flag_coarray == GFC_FCOARRAY_LIB
964 && (corank > 0 || caf_attr.codimension))
966 tree cond, sub_caf_tree;
967 gfc_se se;
968 bool compute_special_caf_types_size = false;
970 if (expr->ts.type == BT_DERIVED
971 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
972 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
974 compute_special_caf_types_size = true;
975 caf_alloc_type = GFC_CAF_LOCK_ALLOC;
977 else if (expr->ts.type == BT_DERIVED
978 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
979 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
981 compute_special_caf_types_size = true;
982 caf_alloc_type = GFC_CAF_EVENT_ALLOC;
984 else if (!caf_attr.coarray_comp && refs_comp)
985 /* Only allocatable components in a derived type coarray can be
986 allocate only. */
987 caf_alloc_type = GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY;
989 gfc_init_se (&se, NULL);
990 sub_caf_tree = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
991 if (sub_caf_tree == NULL_TREE)
992 sub_caf_tree = token;
994 /* When mem is an array ref, then strip the .data-ref. */
995 if (TREE_CODE (mem) == COMPONENT_REF
996 && !(GFC_ARRAY_TYPE_P (TREE_TYPE (mem))))
997 tmp = TREE_OPERAND (mem, 0);
998 else
999 tmp = mem;
1001 if (!(GFC_ARRAY_TYPE_P (TREE_TYPE (tmp))
1002 && TYPE_LANG_SPECIFIC (TREE_TYPE (tmp))->corank == 0)
1003 && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
1005 symbol_attribute attr;
1007 gfc_clear_attr (&attr);
1008 tmp = gfc_conv_scalar_to_descriptor (&se, mem, attr);
1009 need_assign = true;
1011 gfc_add_block_to_block (&alloc_block, &se.pre);
1013 /* In the front end, we represent the lock variable as pointer. However,
1014 the FE only passes the pointer around and leaves the actual
1015 representation to the library. Hence, we have to convert back to the
1016 number of elements. */
1017 if (compute_special_caf_types_size)
1018 size = fold_build2_loc (input_location, TRUNC_DIV_EXPR, size_type_node,
1019 size, TYPE_SIZE_UNIT (ptr_type_node));
1021 gfc_allocate_using_caf_lib (&alloc_block, tmp, size, sub_caf_tree,
1022 status, errmsg, errlen, caf_alloc_type);
1023 if (need_assign)
1024 gfc_add_modify (&alloc_block, mem, fold_convert (TREE_TYPE (mem),
1025 gfc_conv_descriptor_data_get (tmp)));
1026 if (status != NULL_TREE)
1028 TREE_USED (label_finish) = 1;
1029 tmp = build1_v (GOTO_EXPR, label_finish);
1030 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1031 status, build_zero_cst (TREE_TYPE (status)));
1032 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1033 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
1034 tmp, build_empty_stmt (input_location));
1035 gfc_add_expr_to_block (&alloc_block, tmp);
1038 else
1039 gfc_allocate_using_malloc (&alloc_block, mem, size, status);
1041 alloc = gfc_finish_block (&alloc_block);
1043 /* If mem is not NULL, we issue a runtime error or set the
1044 status variable. */
1045 if (expr)
1047 tree varname;
1049 gcc_assert (expr->expr_type == EXPR_VARIABLE && expr->symtree);
1050 varname = gfc_build_cstring_const (expr->symtree->name);
1051 varname = gfc_build_addr_expr (pchar_type_node, varname);
1053 error = gfc_trans_runtime_error (true, &expr->where,
1054 "Attempting to allocate already"
1055 " allocated variable '%s'",
1056 varname);
1058 else
1059 error = gfc_trans_runtime_error (true, NULL,
1060 "Attempting to allocate already allocated"
1061 " variable");
1063 if (status != NULL_TREE)
1065 tree status_type = TREE_TYPE (status);
1067 error = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1068 status, build_int_cst (status_type, LIBERROR_ALLOCATION));
1071 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem,
1072 error, alloc);
1073 gfc_add_expr_to_block (block, tmp);
1077 /* Free a given variable. */
1079 tree
1080 gfc_call_free (tree var)
1082 return build_call_expr_loc (input_location,
1083 builtin_decl_explicit (BUILT_IN_FREE),
1084 1, fold_convert (pvoid_type_node, var));
1088 /* Generate the data reference to the finalization procedure pointer associated
1089 with the expression passed as argument in EXPR. */
1091 static void
1092 get_final_proc_ref (gfc_se *se, gfc_expr *expr, tree class_container)
1094 gfc_expr *final_wrapper = NULL;
1096 gcc_assert (expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS);
1098 bool using_class_container = false;
1099 if (expr->ts.type == BT_DERIVED)
1100 gfc_is_finalizable (expr->ts.u.derived, &final_wrapper);
1101 else if (class_container)
1103 using_class_container = true;
1104 se->expr = gfc_class_vtab_final_get (class_container);
1106 else
1108 final_wrapper = gfc_copy_expr (expr);
1109 gfc_add_vptr_component (final_wrapper);
1110 gfc_add_final_component (final_wrapper);
1113 if (!using_class_container)
1115 gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE);
1117 gfc_conv_expr (se, final_wrapper);
1120 if (POINTER_TYPE_P (TREE_TYPE (se->expr)))
1121 se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
1125 /* Generate the code to obtain the value of the element size of the expression
1126 passed as argument in EXPR. */
1128 static void
1129 get_elem_size (gfc_se *se, gfc_expr *expr, tree class_container)
1131 gcc_assert (expr->ts.type == BT_DERIVED || expr->ts.type == BT_CLASS);
1133 if (expr->ts.type == BT_DERIVED)
1135 se->expr = gfc_typenode_for_spec (&expr->ts);
1136 se->expr = TYPE_SIZE_UNIT (se->expr);
1137 se->expr = fold_convert (gfc_array_index_type, se->expr);
1139 else if (class_container)
1140 se->expr = gfc_class_vtab_size_get (class_container);
1141 else
1143 gfc_expr *class_size = gfc_copy_expr (expr);
1144 gfc_add_vptr_component (class_size);
1145 gfc_add_size_component (class_size);
1147 gfc_conv_expr (se, class_size);
1148 gcc_assert (se->post.head == NULL_TREE);
1153 /* Generate the data reference (array) descriptor corresponding to the
1154 expression passed as argument in VAR. */
1156 static void
1157 get_var_descr (gfc_se *se, gfc_expr *var, tree class_container)
1159 gfc_se tmp_se;
1161 gcc_assert (var);
1163 gfc_init_se (&tmp_se, NULL);
1165 if (var->ts.type == BT_DERIVED)
1167 tmp_se.want_pointer = 1;
1168 if (var->rank)
1170 tmp_se.descriptor_only = 1;
1171 gfc_conv_expr_descriptor (&tmp_se, var);
1173 else
1174 gfc_conv_expr (&tmp_se, var);
1176 else if (class_container)
1177 tmp_se.expr = gfc_class_data_get (class_container);
1178 else
1180 gfc_expr *array_expr;
1182 array_expr = gfc_copy_expr (var);
1184 tmp_se.want_pointer = 1;
1185 if (array_expr->rank)
1187 gfc_add_class_array_ref (array_expr);
1188 tmp_se.descriptor_only = 1;
1189 gfc_conv_expr_descriptor (&tmp_se, array_expr);
1191 else
1193 gfc_add_data_component (array_expr);
1194 gfc_conv_expr (&tmp_se, array_expr);
1195 gcc_assert (tmp_se.post.head == NULL_TREE);
1197 gfc_free_expr (array_expr);
1200 if (var->rank == 0)
1202 if (var->ts.type == BT_DERIVED
1203 || !gfc_is_coarray (var))
1205 /* No copy back needed, hence set attr's allocatable/pointer
1206 to zero. */
1207 symbol_attribute attr;
1208 gfc_clear_attr (&attr);
1209 tmp_se.expr = gfc_conv_scalar_to_descriptor (&tmp_se, tmp_se.expr,
1210 attr);
1212 gcc_assert (tmp_se.post.head == NULL_TREE);
1215 if (!POINTER_TYPE_P (TREE_TYPE (tmp_se.expr)))
1216 tmp_se.expr = gfc_build_addr_expr (NULL, tmp_se.expr);
1218 gfc_add_block_to_block (&se->pre, &tmp_se.pre);
1219 gfc_add_block_to_block (&se->post, &tmp_se.post);
1220 se->expr = tmp_se.expr;
1224 static void
1225 get_vptr (gfc_se *se, gfc_expr *expr, tree class_container)
1227 if (class_container)
1228 se->expr = gfc_class_vptr_get (class_container);
1229 else
1231 gfc_expr *vptr_expr = gfc_copy_expr (expr);
1232 gfc_add_vptr_component (vptr_expr);
1234 gfc_se tmp_se;
1235 gfc_init_se (&tmp_se, NULL);
1236 tmp_se.want_pointer = 1;
1237 gfc_conv_expr (&tmp_se, vptr_expr);
1238 gfc_free_expr (vptr_expr);
1240 gfc_add_block_to_block (&se->pre, &tmp_se.pre);
1241 gfc_add_block_to_block (&se->post, &tmp_se.post);
1242 se->expr = tmp_se.expr;
1247 bool
1248 gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp,
1249 bool fini_coarray)
1251 gfc_se se;
1252 stmtblock_t block2;
1253 tree final_fndecl, size, array, tmp, cond;
1254 symbol_attribute attr;
1255 gfc_expr *final_expr = NULL;
1257 if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS)
1258 return false;
1260 gfc_init_block (&block2);
1262 if (comp->ts.type == BT_DERIVED)
1264 if (comp->attr.pointer)
1265 return false;
1267 gfc_is_finalizable (comp->ts.u.derived, &final_expr);
1268 if (!final_expr)
1269 return false;
1271 gfc_init_se (&se, NULL);
1272 gfc_conv_expr (&se, final_expr);
1273 final_fndecl = se.expr;
1274 size = gfc_typenode_for_spec (&comp->ts);
1275 size = TYPE_SIZE_UNIT (size);
1276 size = fold_convert (gfc_array_index_type, size);
1278 array = decl;
1280 else /* comp->ts.type == BT_CLASS. */
1282 if (CLASS_DATA (comp)->attr.class_pointer)
1283 return false;
1285 gfc_is_finalizable (CLASS_DATA (comp)->ts.u.derived, &final_expr);
1286 final_fndecl = gfc_class_vtab_final_get (decl);
1287 size = gfc_class_vtab_size_get (decl);
1288 array = gfc_class_data_get (decl);
1291 if (comp->attr.allocatable
1292 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)->attr.allocatable))
1294 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))
1295 ? gfc_conv_descriptor_data_get (array) : array;
1296 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1297 tmp, fold_convert (TREE_TYPE (tmp),
1298 null_pointer_node));
1300 else
1301 cond = logical_true_node;
1303 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array)))
1305 gfc_clear_attr (&attr);
1306 gfc_init_se (&se, NULL);
1307 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1308 gfc_add_block_to_block (&block2, &se.pre);
1309 gcc_assert (se.post.head == NULL_TREE);
1312 if (!POINTER_TYPE_P (TREE_TYPE (array)))
1313 array = gfc_build_addr_expr (NULL, array);
1315 if (!final_expr)
1317 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1318 final_fndecl,
1319 fold_convert (TREE_TYPE (final_fndecl),
1320 null_pointer_node));
1321 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1322 logical_type_node, cond, tmp);
1325 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
1326 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
1328 tmp = build_call_expr_loc (input_location,
1329 final_fndecl, 3, array,
1330 size, fini_coarray ? boolean_true_node
1331 : boolean_false_node);
1332 gfc_add_expr_to_block (&block2, tmp);
1333 tmp = gfc_finish_block (&block2);
1335 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
1336 build_empty_stmt (input_location));
1337 gfc_add_expr_to_block (block, tmp);
1339 return true;
1343 /* Add a call to the finalizer, using the passed *expr. Returns
1344 true when a finalizer call has been inserted. */
1346 bool
1347 gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2,
1348 tree class_container)
1350 tree tmp;
1351 gfc_ref *ref;
1352 gfc_expr *expr;
1354 if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS))
1355 return false;
1357 /* Finalization of these temporaries is made by explicit calls in
1358 resolve.cc(generate_component_assignments). */
1359 if (expr2->expr_type == EXPR_VARIABLE
1360 && expr2->symtree->n.sym->name[0] == '_'
1361 && expr2->ts.type == BT_DERIVED
1362 && expr2->ts.u.derived->attr.defined_assign_comp)
1363 return false;
1365 if (expr2->ts.type == BT_DERIVED
1366 && !gfc_is_finalizable (expr2->ts.u.derived, NULL))
1367 return false;
1369 /* If we have a class array, we need go back to the class
1370 container. */
1371 expr = gfc_copy_expr (expr2);
1373 if (expr->ref && expr->ref->next && !expr->ref->next->next
1374 && expr->ref->next->type == REF_ARRAY
1375 && expr->ref->type == REF_COMPONENT
1376 && strcmp (expr->ref->u.c.component->name, "_data") == 0)
1378 gfc_free_ref_list (expr->ref);
1379 expr->ref = NULL;
1381 else
1382 for (ref = expr->ref; ref; ref = ref->next)
1383 if (ref->next && ref->next->next && !ref->next->next->next
1384 && ref->next->next->type == REF_ARRAY
1385 && ref->next->type == REF_COMPONENT
1386 && strcmp (ref->next->u.c.component->name, "_data") == 0)
1388 gfc_free_ref_list (ref->next);
1389 ref->next = NULL;
1392 if (expr->ts.type == BT_CLASS
1393 && !expr2->rank
1394 && !expr2->ref
1395 && CLASS_DATA (expr2->symtree->n.sym)->as)
1396 expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank;
1398 stmtblock_t tmp_block;
1399 gfc_start_block (&tmp_block);
1401 gfc_se final_se;
1402 gfc_init_se (&final_se, NULL);
1403 get_final_proc_ref (&final_se, expr, class_container);
1404 gfc_add_block_to_block (block, &final_se.pre);
1406 gfc_se size_se;
1407 gfc_init_se (&size_se, NULL);
1408 get_elem_size (&size_se, expr, class_container);
1409 gfc_add_block_to_block (&tmp_block, &size_se.pre);
1411 gfc_se desc_se;
1412 gfc_init_se (&desc_se, NULL);
1413 get_var_descr (&desc_se, expr, class_container);
1414 gfc_add_block_to_block (&tmp_block, &desc_se.pre);
1416 tmp = build_call_expr_loc (input_location, final_se.expr, 3,
1417 desc_se.expr, size_se.expr,
1418 boolean_false_node);
1420 gfc_add_expr_to_block (&tmp_block, tmp);
1422 gfc_add_block_to_block (&tmp_block, &desc_se.post);
1423 gfc_add_block_to_block (&tmp_block, &size_se.post);
1425 tmp = gfc_finish_block (&tmp_block);
1427 if (expr->ts.type == BT_CLASS
1428 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
1430 tree cond;
1432 tree ptr = gfc_build_addr_expr (NULL_TREE, final_se.expr);
1434 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1435 ptr, build_int_cst (TREE_TYPE (ptr), 0));
1437 /* For CLASS(*) not only sym->_vtab->_final can be NULL
1438 but already sym->_vtab itself. */
1439 if (UNLIMITED_POLY (expr))
1441 tree cond2;
1442 gfc_se vptr_se;
1444 gfc_init_se (&vptr_se, NULL);
1445 get_vptr (&vptr_se, expr, class_container);
1447 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1448 vptr_se.expr,
1449 build_int_cst (TREE_TYPE (vptr_se.expr), 0));
1450 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1451 logical_type_node, cond2, cond);
1454 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1455 cond, tmp, build_empty_stmt (input_location));
1458 gfc_add_expr_to_block (block, tmp);
1459 gfc_add_block_to_block (block, &final_se.post);
1461 return true;
1465 /* F2018 (7.5.6.3): "When an intrinsic assignment statement is executed
1466 (10.2.1.3), if the variable is not an unallocated allocatable variable,
1467 it is finalized after evaluation of expr and before the definition of
1468 the variable. If the variable is an allocated allocatable variable, or
1469 has an allocated allocatable subobject, that would be deallocated by
1470 intrinsic assignment, the finalization occurs before the deallocation */
1472 bool
1473 gfc_assignment_finalizer_call (gfc_se *lse, gfc_expr *expr1, bool init_flag)
1475 symbol_attribute lhs_attr;
1476 tree final_expr;
1477 tree ptr;
1478 tree cond;
1479 gfc_se se;
1480 gfc_symbol *sym = expr1->symtree->n.sym;
1481 gfc_ref *ref = expr1->ref;
1482 stmtblock_t final_block;
1483 gfc_init_block (&final_block);
1484 gfc_expr *finalize_expr;
1485 bool class_array_ref;
1487 /* We have to exclude vtable procedures (_copy and _final especially), uses
1488 of gfc_trans_assignment_1 in initialization and allocation before trying
1489 to build a final call. */
1490 if (!expr1->must_finalize
1491 || sym->attr.artificial
1492 || sym->ns->proc_name->attr.artificial
1493 || init_flag)
1494 return false;
1496 class_array_ref = ref && ref->type == REF_COMPONENT
1497 && !strcmp (ref->u.c.component->name, "_data")
1498 && ref->next && ref->next->type == REF_ARRAY
1499 && !ref->next->next;
1501 if (class_array_ref)
1503 finalize_expr = gfc_lval_expr_from_sym (sym);
1504 finalize_expr->must_finalize = 1;
1505 ref = NULL;
1507 else
1508 finalize_expr = gfc_copy_expr (expr1);
1510 /* F2018 7.5.6.2: Only finalizable entities are finalized. */
1511 if (!(expr1->ts.type == BT_DERIVED
1512 && gfc_is_finalizable (expr1->ts.u.derived, NULL))
1513 && expr1->ts.type != BT_CLASS)
1514 return false;
1516 if (!gfc_may_be_finalized (sym->ts))
1517 return false;
1519 gfc_init_block (&final_block);
1520 bool finalizable = gfc_add_finalizer_call (&final_block, finalize_expr);
1521 gfc_free_expr (finalize_expr);
1523 if (!finalizable)
1524 return false;
1526 lhs_attr = gfc_expr_attr (expr1);
1528 /* Check allocatable/pointer is allocated/associated. */
1529 if (lhs_attr.allocatable || lhs_attr.pointer)
1531 if (expr1->ts.type == BT_CLASS)
1533 ptr = gfc_get_class_from_gfc_expr (expr1);
1534 gcc_assert (ptr != NULL_TREE);
1535 ptr = gfc_class_data_get (ptr);
1536 if (lhs_attr.dimension)
1537 ptr = gfc_conv_descriptor_data_get (ptr);
1539 else
1541 gfc_init_se (&se, NULL);
1542 if (expr1->rank)
1544 gfc_conv_expr_descriptor (&se, expr1);
1545 ptr = gfc_conv_descriptor_data_get (se.expr);
1547 else
1549 gfc_conv_expr (&se, expr1);
1550 ptr = gfc_build_addr_expr (NULL_TREE, se.expr);
1554 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1555 ptr, build_zero_cst (TREE_TYPE (ptr)));
1556 final_expr = build3_loc (input_location, COND_EXPR, void_type_node,
1557 cond, gfc_finish_block (&final_block),
1558 build_empty_stmt (input_location));
1560 else
1561 final_expr = gfc_finish_block (&final_block);
1563 /* Check optional present. */
1564 if (sym->attr.optional)
1566 cond = gfc_conv_expr_present (sym);
1567 final_expr = build3_loc (input_location, COND_EXPR, void_type_node,
1568 cond, final_expr,
1569 build_empty_stmt (input_location));
1572 gfc_add_expr_to_block (&lse->finalblock, final_expr);
1574 return true;
1578 /* Finalize a TREE expression using the finalizer wrapper. The result is
1579 fixed in order to prevent repeated calls. */
1581 void
1582 gfc_finalize_tree_expr (gfc_se *se, gfc_symbol *derived,
1583 symbol_attribute attr, int rank)
1585 tree vptr, final_fndecl, desc, tmp, size, is_final;
1586 tree data_ptr, data_null, cond;
1587 gfc_symbol *vtab;
1588 gfc_se post_se;
1589 bool is_class = GFC_CLASS_TYPE_P (TREE_TYPE (se->expr));
1591 if (attr.pointer)
1592 return;
1594 /* Derived type function results with components that have defined
1595 assignements are handled in resolve.cc(generate_component_assignments) */
1596 if (derived && (derived->attr.is_c_interop
1597 || derived->attr.is_iso_c
1598 || derived->attr.is_bind_c
1599 || derived->attr.defined_assign_comp))
1600 return;
1602 if (is_class)
1604 if (!VAR_P (se->expr))
1606 desc = gfc_evaluate_now (se->expr, &se->pre);
1607 se->expr = desc;
1609 desc = gfc_class_data_get (se->expr);
1610 vptr = gfc_class_vptr_get (se->expr);
1612 else if (derived && gfc_is_finalizable (derived, NULL))
1614 if (derived->attr.zero_comp && !rank)
1616 /* Any attempt to assign zero length entities, causes the gimplifier
1617 all manner of problems. Instead, a variable is created to act as
1618 as the argument for the final call. */
1619 desc = gfc_create_var (TREE_TYPE (se->expr), "zero");
1621 else if (se->direct_byref)
1623 desc = gfc_evaluate_now (se->expr, &se->finalblock);
1624 if (derived->attr.alloc_comp)
1626 /* Need to copy allocated components and not finalize. */
1627 tmp = gfc_copy_alloc_comp_no_fini (derived, se->expr, desc, rank, 0);
1628 gfc_add_expr_to_block (&se->finalblock, tmp);
1631 else
1633 desc = gfc_evaluate_now (se->expr, &se->pre);
1634 se->expr = gfc_evaluate_now (desc, &se->pre);
1635 if (derived->attr.alloc_comp)
1637 /* Need to copy allocated components and not finalize. */
1638 tmp = gfc_copy_alloc_comp_no_fini (derived, se->expr, desc, rank, 0);
1639 gfc_add_expr_to_block (&se->pre, tmp);
1643 vtab = gfc_find_derived_vtab (derived);
1644 if (vtab->backend_decl == NULL_TREE)
1645 vptr = gfc_get_symbol_decl (vtab);
1646 else
1647 vptr = vtab->backend_decl;
1648 vptr = gfc_build_addr_expr (NULL, vptr);
1650 else
1651 return;
1653 size = gfc_vptr_size_get (vptr);
1654 final_fndecl = gfc_vptr_final_get (vptr);
1655 is_final = fold_build2_loc (input_location, NE_EXPR,
1656 logical_type_node,
1657 final_fndecl,
1658 fold_convert (TREE_TYPE (final_fndecl),
1659 null_pointer_node));
1661 final_fndecl = build_fold_indirect_ref_loc (input_location,
1662 final_fndecl);
1663 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
1665 if (is_class)
1666 desc = gfc_conv_scalar_to_descriptor (se, desc, attr);
1667 else
1669 gfc_init_se (&post_se, NULL);
1670 desc = gfc_conv_scalar_to_descriptor (&post_se, desc, attr);
1671 gfc_add_expr_to_block (&se->pre, gfc_finish_block (&post_se.pre));
1675 if (derived && derived->attr.zero_comp)
1677 /* All the conditions below break down for zero length derived types. */
1678 tmp = build_call_expr_loc (input_location, final_fndecl, 3,
1679 gfc_build_addr_expr (NULL, desc),
1680 size, boolean_false_node);
1681 gfc_add_expr_to_block (&se->finalblock, tmp);
1682 return;
1685 if (!VAR_P (desc))
1687 tmp = gfc_create_var (TREE_TYPE (desc), "res");
1688 if (se->direct_byref)
1689 gfc_add_modify (&se->finalblock, tmp, desc);
1690 else
1691 gfc_add_modify (&se->pre, tmp, desc);
1692 desc = tmp;
1695 data_ptr = gfc_conv_descriptor_data_get (desc);
1696 data_null = fold_convert (TREE_TYPE (data_ptr), null_pointer_node);
1697 cond = fold_build2_loc (input_location, NE_EXPR,
1698 logical_type_node, data_ptr, data_null);
1699 is_final = fold_build2_loc (input_location, TRUTH_AND_EXPR,
1700 logical_type_node, is_final, cond);
1701 tmp = build_call_expr_loc (input_location, final_fndecl, 3,
1702 gfc_build_addr_expr (NULL, desc),
1703 size, boolean_false_node);
1704 tmp = fold_build3_loc (input_location, COND_EXPR,
1705 void_type_node, is_final, tmp,
1706 build_empty_stmt (input_location));
1708 if (is_class && se->ss && se->ss->loop)
1710 gfc_add_expr_to_block (&se->loop->post, tmp);
1711 tmp = fold_build3_loc (input_location, COND_EXPR,
1712 void_type_node, cond,
1713 gfc_call_free (data_ptr),
1714 build_empty_stmt (input_location));
1715 gfc_add_expr_to_block (&se->loop->post, tmp);
1716 gfc_add_modify (&se->loop->post, data_ptr, data_null);
1718 else
1720 gfc_add_expr_to_block (&se->finalblock, tmp);
1722 /* Let the scalarizer take care of freeing of temporary arrays. */
1723 if (attr.allocatable && !(se->loop && se->loop->temp_dim))
1725 tmp = fold_build3_loc (input_location, COND_EXPR,
1726 void_type_node, cond,
1727 gfc_call_free (data_ptr),
1728 build_empty_stmt (input_location));
1729 gfc_add_expr_to_block (&se->finalblock, tmp);
1730 gfc_add_modify (&se->finalblock, data_ptr, data_null);
1736 /* User-deallocate; we emit the code directly from the front-end, and the
1737 logic is the same as the previous library function:
1739 void
1740 deallocate (void *pointer, GFC_INTEGER_4 * stat)
1742 if (!pointer)
1744 if (stat)
1745 *stat = 1;
1746 else
1747 runtime_error ("Attempt to DEALLOCATE unallocated memory.");
1749 else
1751 free (pointer);
1752 if (stat)
1753 *stat = 0;
1757 In this front-end version, status doesn't have to be GFC_INTEGER_4.
1758 Moreover, if CAN_FAIL is true, then we will not emit a runtime error,
1759 even when no status variable is passed to us (this is used for
1760 unconditional deallocation generated by the front-end at end of
1761 each procedure).
1763 If a runtime-message is possible, `expr' must point to the original
1764 expression being deallocated for its locus and variable name.
1766 For coarrays, "pointer" must be the array descriptor and not its
1767 "data" component.
1769 COARRAY_DEALLOC_MODE gives the mode unregister coarrays. Available modes are
1770 the ones of GFC_CAF_DEREGTYPE, -1 when the mode for deregistration is to be
1771 analyzed and set by this routine, and -2 to indicate that a non-coarray is to
1772 be deallocated. */
1773 tree
1774 gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
1775 tree errlen, tree label_finish,
1776 bool can_fail, gfc_expr* expr,
1777 int coarray_dealloc_mode, tree class_container,
1778 tree add_when_allocated, tree caf_token)
1780 stmtblock_t null, non_null;
1781 tree cond, tmp, error;
1782 tree status_type = NULL_TREE;
1783 tree token = NULL_TREE;
1784 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
1786 if (coarray_dealloc_mode >= GFC_CAF_COARRAY_ANALYZE)
1788 if (flag_coarray == GFC_FCOARRAY_LIB)
1790 if (caf_token)
1791 token = caf_token;
1792 else
1794 tree caf_type, caf_decl = pointer;
1795 pointer = gfc_conv_descriptor_data_get (caf_decl);
1796 caf_type = TREE_TYPE (caf_decl);
1797 STRIP_NOPS (pointer);
1798 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
1799 token = gfc_conv_descriptor_token (caf_decl);
1800 else if (DECL_LANG_SPECIFIC (caf_decl)
1801 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1802 token = GFC_DECL_TOKEN (caf_decl);
1803 else
1805 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
1806 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type)
1807 != NULL_TREE);
1808 token = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
1812 if (coarray_dealloc_mode == GFC_CAF_COARRAY_ANALYZE)
1814 bool comp_ref;
1815 if (expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
1816 && comp_ref)
1817 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
1818 // else do a deregister as set by default.
1820 else
1821 caf_dereg_type = (enum gfc_coarray_deregtype) coarray_dealloc_mode;
1823 else if (flag_coarray == GFC_FCOARRAY_SINGLE)
1824 pointer = gfc_conv_descriptor_data_get (pointer);
1826 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
1827 pointer = gfc_conv_descriptor_data_get (pointer);
1829 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
1830 build_int_cst (TREE_TYPE (pointer), 0));
1832 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1833 we emit a runtime error. */
1834 gfc_start_block (&null);
1835 if (!can_fail)
1837 tree varname;
1839 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1841 varname = gfc_build_cstring_const (expr->symtree->name);
1842 varname = gfc_build_addr_expr (pchar_type_node, varname);
1844 error = gfc_trans_runtime_error (true, &expr->where,
1845 "Attempt to DEALLOCATE unallocated '%s'",
1846 varname);
1848 else
1849 error = build_empty_stmt (input_location);
1851 if (status != NULL_TREE && !integer_zerop (status))
1853 tree cond2;
1855 status_type = TREE_TYPE (TREE_TYPE (status));
1856 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1857 status, build_int_cst (TREE_TYPE (status), 0));
1858 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1859 fold_build1_loc (input_location, INDIRECT_REF,
1860 status_type, status),
1861 build_int_cst (status_type, 1));
1862 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1863 cond2, tmp, error);
1866 gfc_add_expr_to_block (&null, error);
1868 /* When POINTER is not NULL, we free it. */
1869 gfc_start_block (&non_null);
1870 if (add_when_allocated)
1871 gfc_add_expr_to_block (&non_null, add_when_allocated);
1872 gfc_add_finalizer_call (&non_null, expr, class_container);
1873 if (coarray_dealloc_mode == GFC_CAF_COARRAY_NOCOARRAY
1874 || flag_coarray != GFC_FCOARRAY_LIB)
1876 tmp = build_call_expr_loc (input_location,
1877 builtin_decl_explicit (BUILT_IN_FREE), 1,
1878 fold_convert (pvoid_type_node, pointer));
1879 gfc_add_expr_to_block (&non_null, tmp);
1880 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
1881 0));
1883 if (status != NULL_TREE && !integer_zerop (status))
1885 /* We set STATUS to zero if it is present. */
1886 tree status_type = TREE_TYPE (TREE_TYPE (status));
1887 tree cond2;
1889 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1890 status,
1891 build_int_cst (TREE_TYPE (status), 0));
1892 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1893 fold_build1_loc (input_location, INDIRECT_REF,
1894 status_type, status),
1895 build_int_cst (status_type, 0));
1896 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1897 gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC),
1898 tmp, build_empty_stmt (input_location));
1899 gfc_add_expr_to_block (&non_null, tmp);
1902 else
1904 tree cond2, pstat = null_pointer_node;
1906 if (errmsg == NULL_TREE)
1908 gcc_assert (errlen == NULL_TREE);
1909 errmsg = null_pointer_node;
1910 errlen = build_zero_cst (integer_type_node);
1912 else
1914 gcc_assert (errlen != NULL_TREE);
1915 if (!POINTER_TYPE_P (TREE_TYPE (errmsg)))
1916 errmsg = gfc_build_addr_expr (NULL_TREE, errmsg);
1919 if (status != NULL_TREE && !integer_zerop (status))
1921 gcc_assert (status_type == integer_type_node);
1922 pstat = status;
1925 token = gfc_build_addr_expr (NULL_TREE, token);
1926 gcc_assert (caf_dereg_type > GFC_CAF_COARRAY_ANALYZE);
1927 tmp = build_call_expr_loc (input_location,
1928 gfor_fndecl_caf_deregister, 5,
1929 token, build_int_cst (integer_type_node,
1930 caf_dereg_type),
1931 pstat, errmsg, errlen);
1932 gfc_add_expr_to_block (&non_null, tmp);
1934 /* It guarantees memory consistency within the same segment */
1935 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1936 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1937 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1938 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1939 ASM_VOLATILE_P (tmp) = 1;
1940 gfc_add_expr_to_block (&non_null, tmp);
1942 if (status != NULL_TREE)
1944 tree stat = build_fold_indirect_ref_loc (input_location, status);
1945 tree nullify = fold_build2_loc (input_location, MODIFY_EXPR,
1946 void_type_node, pointer,
1947 build_int_cst (TREE_TYPE (pointer),
1948 0));
1950 TREE_USED (label_finish) = 1;
1951 tmp = build1_v (GOTO_EXPR, label_finish);
1952 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1953 stat, build_zero_cst (TREE_TYPE (stat)));
1954 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1955 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
1956 tmp, nullify);
1957 gfc_add_expr_to_block (&non_null, tmp);
1959 else
1960 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
1961 0));
1964 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
1965 gfc_finish_block (&null),
1966 gfc_finish_block (&non_null));
1970 /* Generate code for deallocation of allocatable scalars (variables or
1971 components). Before the object itself is freed, any allocatable
1972 subcomponents are being deallocated. */
1974 tree
1975 gfc_deallocate_scalar_with_status (tree pointer, tree status, tree label_finish,
1976 bool can_fail, gfc_expr* expr,
1977 gfc_typespec ts, tree class_container,
1978 bool coarray)
1980 stmtblock_t null, non_null;
1981 tree cond, tmp, error;
1982 bool finalizable, comp_ref;
1983 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
1985 if (coarray && expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
1986 && comp_ref)
1987 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
1989 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
1990 build_int_cst (TREE_TYPE (pointer), 0));
1992 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1993 we emit a runtime error. */
1994 gfc_start_block (&null);
1995 if (!can_fail)
1997 tree varname;
1999 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
2001 varname = gfc_build_cstring_const (expr->symtree->name);
2002 varname = gfc_build_addr_expr (pchar_type_node, varname);
2004 error = gfc_trans_runtime_error (true, &expr->where,
2005 "Attempt to DEALLOCATE unallocated '%s'",
2006 varname);
2008 else
2009 error = build_empty_stmt (input_location);
2011 if (status != NULL_TREE && !integer_zerop (status))
2013 tree status_type = TREE_TYPE (TREE_TYPE (status));
2014 tree cond2;
2016 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
2017 status, build_int_cst (TREE_TYPE (status), 0));
2018 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
2019 fold_build1_loc (input_location, INDIRECT_REF,
2020 status_type, status),
2021 build_int_cst (status_type, 1));
2022 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2023 cond2, tmp, error);
2025 gfc_add_expr_to_block (&null, error);
2027 /* When POINTER is not NULL, we free it. */
2028 gfc_start_block (&non_null);
2030 /* Free allocatable components. */
2031 finalizable = gfc_add_finalizer_call (&non_null, expr, class_container);
2032 if (!finalizable && ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
2034 int caf_mode = coarray
2035 ? ((caf_dereg_type == GFC_CAF_COARRAY_DEALLOCATE_ONLY
2036 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0)
2037 | GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
2038 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY)
2039 : 0;
2040 if (coarray && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
2041 tmp = gfc_conv_descriptor_data_get (pointer);
2042 else
2043 tmp = build_fold_indirect_ref_loc (input_location, pointer);
2044 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0, caf_mode);
2045 gfc_add_expr_to_block (&non_null, tmp);
2048 if (!coarray || flag_coarray == GFC_FCOARRAY_SINGLE)
2050 tmp = build_call_expr_loc (input_location,
2051 builtin_decl_explicit (BUILT_IN_FREE), 1,
2052 fold_convert (pvoid_type_node, pointer));
2053 gfc_add_expr_to_block (&non_null, tmp);
2055 if (status != NULL_TREE && !integer_zerop (status))
2057 /* We set STATUS to zero if it is present. */
2058 tree status_type = TREE_TYPE (TREE_TYPE (status));
2059 tree cond2;
2061 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
2062 status,
2063 build_int_cst (TREE_TYPE (status), 0));
2064 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
2065 fold_build1_loc (input_location, INDIRECT_REF,
2066 status_type, status),
2067 build_int_cst (status_type, 0));
2068 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2069 cond2, tmp, build_empty_stmt (input_location));
2070 gfc_add_expr_to_block (&non_null, tmp);
2073 else
2075 tree token;
2076 tree pstat = null_pointer_node;
2077 gfc_se se;
2079 gfc_init_se (&se, NULL);
2080 token = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
2081 gcc_assert (token != NULL_TREE);
2083 if (status != NULL_TREE && !integer_zerop (status))
2085 gcc_assert (TREE_TYPE (TREE_TYPE (status)) == integer_type_node);
2086 pstat = status;
2089 tmp = build_call_expr_loc (input_location,
2090 gfor_fndecl_caf_deregister, 5,
2091 token, build_int_cst (integer_type_node,
2092 caf_dereg_type),
2093 pstat, null_pointer_node, integer_zero_node);
2094 gfc_add_expr_to_block (&non_null, tmp);
2096 /* It guarantees memory consistency within the same segment. */
2097 tmp = gfc_build_string_const (strlen ("memory")+1, "memory");
2098 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
2099 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
2100 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
2101 ASM_VOLATILE_P (tmp) = 1;
2102 gfc_add_expr_to_block (&non_null, tmp);
2104 if (status != NULL_TREE)
2106 tree stat = build_fold_indirect_ref_loc (input_location, status);
2107 tree cond2;
2109 TREE_USED (label_finish) = 1;
2110 tmp = build1_v (GOTO_EXPR, label_finish);
2111 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
2112 stat, build_zero_cst (TREE_TYPE (stat)));
2113 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2114 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
2115 tmp, build_empty_stmt (input_location));
2116 gfc_add_expr_to_block (&non_null, tmp);
2120 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
2121 gfc_finish_block (&null),
2122 gfc_finish_block (&non_null));
2125 /* Reallocate MEM so it has SIZE bytes of data. This behaves like the
2126 following pseudo-code:
2128 void *
2129 internal_realloc (void *mem, size_t size)
2131 res = realloc (mem, size);
2132 if (!res && size != 0)
2133 _gfortran_os_error ("Allocation would exceed memory limit");
2135 return res;
2136 } */
2137 tree
2138 gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
2140 tree res, nonzero, null_result, tmp;
2141 tree type = TREE_TYPE (mem);
2143 /* Only evaluate the size once. */
2144 size = save_expr (fold_convert (size_type_node, size));
2146 /* Create a variable to hold the result. */
2147 res = gfc_create_var (type, NULL);
2149 /* Call realloc and check the result. */
2150 tmp = build_call_expr_loc (input_location,
2151 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
2152 fold_convert (pvoid_type_node, mem), size);
2153 gfc_add_modify (block, res, fold_convert (type, tmp));
2154 null_result = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
2155 res, build_int_cst (pvoid_type_node, 0));
2156 nonzero = fold_build2_loc (input_location, NE_EXPR, logical_type_node, size,
2157 build_int_cst (size_type_node, 0));
2158 null_result = fold_build2_loc (input_location, TRUTH_AND_EXPR, logical_type_node,
2159 null_result, nonzero);
2160 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2161 null_result,
2162 trans_os_error_at (NULL,
2163 "Error reallocating to %lu bytes",
2164 fold_convert
2165 (long_unsigned_type_node, size)),
2166 build_empty_stmt (input_location));
2167 gfc_add_expr_to_block (block, tmp);
2169 return res;
2173 /* Add an expression to another one, either at the front or the back. */
2175 static void
2176 add_expr_to_chain (tree* chain, tree expr, bool front)
2178 if (expr == NULL_TREE || IS_EMPTY_STMT (expr))
2179 return;
2181 if (*chain)
2183 if (TREE_CODE (*chain) != STATEMENT_LIST)
2185 tree tmp;
2187 tmp = *chain;
2188 *chain = NULL_TREE;
2189 append_to_statement_list (tmp, chain);
2192 if (front)
2194 tree_stmt_iterator i;
2196 i = tsi_start (*chain);
2197 tsi_link_before (&i, expr, TSI_CONTINUE_LINKING);
2199 else
2200 append_to_statement_list (expr, chain);
2202 else
2203 *chain = expr;
2207 /* Add a statement at the end of a block. */
2209 void
2210 gfc_add_expr_to_block (stmtblock_t * block, tree expr)
2212 gcc_assert (block);
2213 add_expr_to_chain (&block->head, expr, false);
2217 /* Add a statement at the beginning of a block. */
2219 void
2220 gfc_prepend_expr_to_block (stmtblock_t * block, tree expr)
2222 gcc_assert (block);
2223 add_expr_to_chain (&block->head, expr, true);
2227 /* Add a block the end of a block. */
2229 void
2230 gfc_add_block_to_block (stmtblock_t * block, stmtblock_t * append)
2232 gcc_assert (append);
2233 gcc_assert (!append->has_scope);
2235 gfc_add_expr_to_block (block, append->head);
2236 append->head = NULL_TREE;
2240 /* Save the current locus. The structure may not be complete, and should
2241 only be used with gfc_restore_backend_locus. */
2243 void
2244 gfc_save_backend_locus (locus * loc)
2246 loc->lb = XCNEW (gfc_linebuf);
2247 loc->lb->location = input_location;
2248 loc->lb->file = gfc_current_backend_file;
2252 /* Set the current locus. */
2254 void
2255 gfc_set_backend_locus (locus * loc)
2257 gfc_current_backend_file = loc->lb->file;
2258 input_location = gfc_get_location (loc);
2262 /* Restore the saved locus. Only used in conjunction with
2263 gfc_save_backend_locus, to free the memory when we are done. */
2265 void
2266 gfc_restore_backend_locus (locus * loc)
2268 /* This only restores the information captured by gfc_save_backend_locus,
2269 intentionally does not use gfc_get_location. */
2270 input_location = loc->lb->location;
2271 gfc_current_backend_file = loc->lb->file;
2272 free (loc->lb);
2276 /* Translate an executable statement. The tree cond is used by gfc_trans_do.
2277 This static function is wrapped by gfc_trans_code_cond and
2278 gfc_trans_code. */
2280 static tree
2281 trans_code (gfc_code * code, tree cond)
2283 stmtblock_t block;
2284 tree res;
2286 if (!code)
2287 return build_empty_stmt (input_location);
2289 gfc_start_block (&block);
2291 /* Translate statements one by one into GENERIC trees until we reach
2292 the end of this gfc_code branch. */
2293 for (; code; code = code->next)
2295 if (code->here != 0)
2297 res = gfc_trans_label_here (code);
2298 gfc_add_expr_to_block (&block, res);
2301 gfc_current_locus = code->loc;
2302 gfc_set_backend_locus (&code->loc);
2304 switch (code->op)
2306 case EXEC_NOP:
2307 case EXEC_END_BLOCK:
2308 case EXEC_END_NESTED_BLOCK:
2309 case EXEC_END_PROCEDURE:
2310 res = NULL_TREE;
2311 break;
2313 case EXEC_ASSIGN:
2314 res = gfc_trans_assign (code);
2315 break;
2317 case EXEC_LABEL_ASSIGN:
2318 res = gfc_trans_label_assign (code);
2319 break;
2321 case EXEC_POINTER_ASSIGN:
2322 res = gfc_trans_pointer_assign (code);
2323 break;
2325 case EXEC_INIT_ASSIGN:
2326 if (code->expr1->ts.type == BT_CLASS)
2327 res = gfc_trans_class_init_assign (code);
2328 else
2329 res = gfc_trans_init_assign (code);
2330 break;
2332 case EXEC_CONTINUE:
2333 res = NULL_TREE;
2334 break;
2336 case EXEC_CRITICAL:
2337 res = gfc_trans_critical (code);
2338 break;
2340 case EXEC_CYCLE:
2341 res = gfc_trans_cycle (code);
2342 break;
2344 case EXEC_EXIT:
2345 res = gfc_trans_exit (code);
2346 break;
2348 case EXEC_GOTO:
2349 res = gfc_trans_goto (code);
2350 break;
2352 case EXEC_ENTRY:
2353 res = gfc_trans_entry (code);
2354 break;
2356 case EXEC_PAUSE:
2357 res = gfc_trans_pause (code);
2358 break;
2360 case EXEC_STOP:
2361 case EXEC_ERROR_STOP:
2362 res = gfc_trans_stop (code, code->op == EXEC_ERROR_STOP);
2363 break;
2365 case EXEC_CALL:
2366 /* For MVBITS we've got the special exception that we need a
2367 dependency check, too. */
2369 bool is_mvbits = false;
2371 if (code->resolved_isym)
2373 res = gfc_conv_intrinsic_subroutine (code);
2374 if (res != NULL_TREE)
2375 break;
2378 if (code->resolved_isym
2379 && code->resolved_isym->id == GFC_ISYM_MVBITS)
2380 is_mvbits = true;
2382 res = gfc_trans_call (code, is_mvbits, NULL_TREE,
2383 NULL_TREE, false);
2385 break;
2387 case EXEC_CALL_PPC:
2388 res = gfc_trans_call (code, false, NULL_TREE,
2389 NULL_TREE, false);
2390 break;
2392 case EXEC_ASSIGN_CALL:
2393 res = gfc_trans_call (code, true, NULL_TREE,
2394 NULL_TREE, false);
2395 break;
2397 case EXEC_RETURN:
2398 res = gfc_trans_return (code);
2399 break;
2401 case EXEC_IF:
2402 res = gfc_trans_if (code);
2403 break;
2405 case EXEC_ARITHMETIC_IF:
2406 res = gfc_trans_arithmetic_if (code);
2407 break;
2409 case EXEC_BLOCK:
2410 res = gfc_trans_block_construct (code);
2411 break;
2413 case EXEC_DO:
2414 res = gfc_trans_do (code, cond);
2415 break;
2417 case EXEC_DO_CONCURRENT:
2418 res = gfc_trans_do_concurrent (code);
2419 break;
2421 case EXEC_DO_WHILE:
2422 res = gfc_trans_do_while (code);
2423 break;
2425 case EXEC_SELECT:
2426 res = gfc_trans_select (code);
2427 break;
2429 case EXEC_SELECT_TYPE:
2430 res = gfc_trans_select_type (code);
2431 break;
2433 case EXEC_SELECT_RANK:
2434 res = gfc_trans_select_rank (code);
2435 break;
2437 case EXEC_FLUSH:
2438 res = gfc_trans_flush (code);
2439 break;
2441 case EXEC_SYNC_ALL:
2442 case EXEC_SYNC_IMAGES:
2443 case EXEC_SYNC_MEMORY:
2444 res = gfc_trans_sync (code, code->op);
2445 break;
2447 case EXEC_LOCK:
2448 case EXEC_UNLOCK:
2449 res = gfc_trans_lock_unlock (code, code->op);
2450 break;
2452 case EXEC_EVENT_POST:
2453 case EXEC_EVENT_WAIT:
2454 res = gfc_trans_event_post_wait (code, code->op);
2455 break;
2457 case EXEC_FAIL_IMAGE:
2458 res = gfc_trans_fail_image (code);
2459 break;
2461 case EXEC_FORALL:
2462 res = gfc_trans_forall (code);
2463 break;
2465 case EXEC_FORM_TEAM:
2466 res = gfc_trans_form_team (code);
2467 break;
2469 case EXEC_CHANGE_TEAM:
2470 res = gfc_trans_change_team (code);
2471 break;
2473 case EXEC_END_TEAM:
2474 res = gfc_trans_end_team (code);
2475 break;
2477 case EXEC_SYNC_TEAM:
2478 res = gfc_trans_sync_team (code);
2479 break;
2481 case EXEC_WHERE:
2482 res = gfc_trans_where (code);
2483 break;
2485 case EXEC_ALLOCATE:
2486 res = gfc_trans_allocate (code);
2487 break;
2489 case EXEC_DEALLOCATE:
2490 res = gfc_trans_deallocate (code);
2491 break;
2493 case EXEC_OPEN:
2494 res = gfc_trans_open (code);
2495 break;
2497 case EXEC_CLOSE:
2498 res = gfc_trans_close (code);
2499 break;
2501 case EXEC_READ:
2502 res = gfc_trans_read (code);
2503 break;
2505 case EXEC_WRITE:
2506 res = gfc_trans_write (code);
2507 break;
2509 case EXEC_IOLENGTH:
2510 res = gfc_trans_iolength (code);
2511 break;
2513 case EXEC_BACKSPACE:
2514 res = gfc_trans_backspace (code);
2515 break;
2517 case EXEC_ENDFILE:
2518 res = gfc_trans_endfile (code);
2519 break;
2521 case EXEC_INQUIRE:
2522 res = gfc_trans_inquire (code);
2523 break;
2525 case EXEC_WAIT:
2526 res = gfc_trans_wait (code);
2527 break;
2529 case EXEC_REWIND:
2530 res = gfc_trans_rewind (code);
2531 break;
2533 case EXEC_TRANSFER:
2534 res = gfc_trans_transfer (code);
2535 break;
2537 case EXEC_DT_END:
2538 res = gfc_trans_dt_end (code);
2539 break;
2541 case EXEC_OMP_ALLOCATE:
2542 case EXEC_OMP_ALLOCATORS:
2543 case EXEC_OMP_ASSUME:
2544 case EXEC_OMP_ATOMIC:
2545 case EXEC_OMP_BARRIER:
2546 case EXEC_OMP_CANCEL:
2547 case EXEC_OMP_CANCELLATION_POINT:
2548 case EXEC_OMP_CRITICAL:
2549 case EXEC_OMP_DEPOBJ:
2550 case EXEC_OMP_DISTRIBUTE:
2551 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
2552 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
2553 case EXEC_OMP_DISTRIBUTE_SIMD:
2554 case EXEC_OMP_DO:
2555 case EXEC_OMP_DO_SIMD:
2556 case EXEC_OMP_LOOP:
2557 case EXEC_OMP_ERROR:
2558 case EXEC_OMP_FLUSH:
2559 case EXEC_OMP_MASKED:
2560 case EXEC_OMP_MASKED_TASKLOOP:
2561 case EXEC_OMP_MASKED_TASKLOOP_SIMD:
2562 case EXEC_OMP_MASTER:
2563 case EXEC_OMP_MASTER_TASKLOOP:
2564 case EXEC_OMP_MASTER_TASKLOOP_SIMD:
2565 case EXEC_OMP_ORDERED:
2566 case EXEC_OMP_PARALLEL:
2567 case EXEC_OMP_PARALLEL_DO:
2568 case EXEC_OMP_PARALLEL_DO_SIMD:
2569 case EXEC_OMP_PARALLEL_LOOP:
2570 case EXEC_OMP_PARALLEL_MASKED:
2571 case EXEC_OMP_PARALLEL_MASKED_TASKLOOP:
2572 case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
2573 case EXEC_OMP_PARALLEL_MASTER:
2574 case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
2575 case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
2576 case EXEC_OMP_PARALLEL_SECTIONS:
2577 case EXEC_OMP_PARALLEL_WORKSHARE:
2578 case EXEC_OMP_SCOPE:
2579 case EXEC_OMP_SECTIONS:
2580 case EXEC_OMP_SIMD:
2581 case EXEC_OMP_SINGLE:
2582 case EXEC_OMP_TARGET:
2583 case EXEC_OMP_TARGET_DATA:
2584 case EXEC_OMP_TARGET_ENTER_DATA:
2585 case EXEC_OMP_TARGET_EXIT_DATA:
2586 case EXEC_OMP_TARGET_PARALLEL:
2587 case EXEC_OMP_TARGET_PARALLEL_DO:
2588 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
2589 case EXEC_OMP_TARGET_PARALLEL_LOOP:
2590 case EXEC_OMP_TARGET_SIMD:
2591 case EXEC_OMP_TARGET_TEAMS:
2592 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
2593 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
2594 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2595 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
2596 case EXEC_OMP_TARGET_TEAMS_LOOP:
2597 case EXEC_OMP_TARGET_UPDATE:
2598 case EXEC_OMP_TASK:
2599 case EXEC_OMP_TASKGROUP:
2600 case EXEC_OMP_TASKLOOP:
2601 case EXEC_OMP_TASKLOOP_SIMD:
2602 case EXEC_OMP_TASKWAIT:
2603 case EXEC_OMP_TASKYIELD:
2604 case EXEC_OMP_TEAMS:
2605 case EXEC_OMP_TEAMS_DISTRIBUTE:
2606 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
2607 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2608 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
2609 case EXEC_OMP_TEAMS_LOOP:
2610 case EXEC_OMP_WORKSHARE:
2611 res = gfc_trans_omp_directive (code);
2612 break;
2614 case EXEC_OACC_CACHE:
2615 case EXEC_OACC_WAIT:
2616 case EXEC_OACC_UPDATE:
2617 case EXEC_OACC_LOOP:
2618 case EXEC_OACC_HOST_DATA:
2619 case EXEC_OACC_DATA:
2620 case EXEC_OACC_KERNELS:
2621 case EXEC_OACC_KERNELS_LOOP:
2622 case EXEC_OACC_PARALLEL:
2623 case EXEC_OACC_PARALLEL_LOOP:
2624 case EXEC_OACC_SERIAL:
2625 case EXEC_OACC_SERIAL_LOOP:
2626 case EXEC_OACC_ENTER_DATA:
2627 case EXEC_OACC_EXIT_DATA:
2628 case EXEC_OACC_ATOMIC:
2629 case EXEC_OACC_DECLARE:
2630 res = gfc_trans_oacc_directive (code);
2631 break;
2633 default:
2634 gfc_internal_error ("gfc_trans_code(): Bad statement code");
2637 gfc_set_backend_locus (&code->loc);
2639 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
2641 if (TREE_CODE (res) != STATEMENT_LIST)
2642 SET_EXPR_LOCATION (res, input_location);
2644 /* Add the new statement to the block. */
2645 gfc_add_expr_to_block (&block, res);
2649 /* Return the finished block. */
2650 return gfc_finish_block (&block);
2654 /* Translate an executable statement with condition, cond. The condition is
2655 used by gfc_trans_do to test for IO result conditions inside implied
2656 DO loops of READ and WRITE statements. See build_dt in trans-io.cc. */
2658 tree
2659 gfc_trans_code_cond (gfc_code * code, tree cond)
2661 return trans_code (code, cond);
2664 /* Translate an executable statement without condition. */
2666 tree
2667 gfc_trans_code (gfc_code * code)
2669 return trans_code (code, NULL_TREE);
2673 /* This function is called after a complete program unit has been parsed
2674 and resolved. */
2676 void
2677 gfc_generate_code (gfc_namespace * ns)
2679 ompws_flags = 0;
2680 if (ns->is_block_data)
2682 gfc_generate_block_data (ns);
2683 return;
2686 gfc_generate_function_code (ns);
2690 /* This function is called after a complete module has been parsed
2691 and resolved. */
2693 void
2694 gfc_generate_module_code (gfc_namespace * ns)
2696 gfc_namespace *n;
2697 struct module_htab_entry *entry;
2699 gcc_assert (ns->proc_name->backend_decl == NULL);
2700 ns->proc_name->backend_decl
2701 = build_decl (gfc_get_location (&ns->proc_name->declared_at),
2702 NAMESPACE_DECL, get_identifier (ns->proc_name->name),
2703 void_type_node);
2704 entry = gfc_find_module (ns->proc_name->name);
2705 if (entry->namespace_decl)
2706 /* Buggy sourcecode, using a module before defining it? */
2707 entry->decls->empty ();
2708 entry->namespace_decl = ns->proc_name->backend_decl;
2710 gfc_generate_module_vars (ns);
2712 /* We need to generate all module function prototypes first, to allow
2713 sibling calls. */
2714 for (n = ns->contained; n; n = n->sibling)
2716 gfc_entry_list *el;
2718 if (!n->proc_name)
2719 continue;
2721 gfc_create_function_decl (n, false);
2722 DECL_CONTEXT (n->proc_name->backend_decl) = ns->proc_name->backend_decl;
2723 gfc_module_add_decl (entry, n->proc_name->backend_decl);
2724 for (el = ns->entries; el; el = el->next)
2726 DECL_CONTEXT (el->sym->backend_decl) = ns->proc_name->backend_decl;
2727 gfc_module_add_decl (entry, el->sym->backend_decl);
2731 for (n = ns->contained; n; n = n->sibling)
2733 if (!n->proc_name)
2734 continue;
2736 gfc_generate_function_code (n);
2741 /* Initialize an init/cleanup block with existing code. */
2743 void
2744 gfc_start_wrapped_block (gfc_wrapped_block* block, tree code)
2746 gcc_assert (block);
2748 block->init = NULL_TREE;
2749 block->code = code;
2750 block->cleanup = NULL_TREE;
2754 /* Add a new pair of initializers/clean-up code. */
2756 void
2757 gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup)
2759 gcc_assert (block);
2761 /* The new pair of init/cleanup should be "wrapped around" the existing
2762 block of code, thus the initialization is added to the front and the
2763 cleanup to the back. */
2764 add_expr_to_chain (&block->init, init, true);
2765 add_expr_to_chain (&block->cleanup, cleanup, false);
2769 /* Finish up a wrapped block by building a corresponding try-finally expr. */
2771 tree
2772 gfc_finish_wrapped_block (gfc_wrapped_block* block)
2774 tree result;
2776 gcc_assert (block);
2778 /* Build the final expression. For this, just add init and body together,
2779 and put clean-up with that into a TRY_FINALLY_EXPR. */
2780 result = block->init;
2781 add_expr_to_chain (&result, block->code, false);
2782 if (block->cleanup)
2783 result = build2_loc (input_location, TRY_FINALLY_EXPR, void_type_node,
2784 result, block->cleanup);
2786 /* Clear the block. */
2787 block->init = NULL_TREE;
2788 block->code = NULL_TREE;
2789 block->cleanup = NULL_TREE;
2791 return result;
2795 /* Helper function for marking a boolean expression tree as unlikely. */
2797 tree
2798 gfc_unlikely (tree cond, enum br_predictor predictor)
2800 tree tmp;
2802 if (optimize)
2804 cond = fold_convert (long_integer_type_node, cond);
2805 tmp = build_zero_cst (long_integer_type_node);
2806 cond = build_call_expr_loc (input_location,
2807 builtin_decl_explicit (BUILT_IN_EXPECT),
2808 3, cond, tmp,
2809 build_int_cst (integer_type_node,
2810 predictor));
2812 return cond;
2816 /* Helper function for marking a boolean expression tree as likely. */
2818 tree
2819 gfc_likely (tree cond, enum br_predictor predictor)
2821 tree tmp;
2823 if (optimize)
2825 cond = fold_convert (long_integer_type_node, cond);
2826 tmp = build_one_cst (long_integer_type_node);
2827 cond = build_call_expr_loc (input_location,
2828 builtin_decl_explicit (BUILT_IN_EXPECT),
2829 3, cond, tmp,
2830 build_int_cst (integer_type_node,
2831 predictor));
2833 return cond;
2837 /* Get the string length for a deferred character length component. */
2839 bool
2840 gfc_deferred_strlen (gfc_component *c, tree *decl)
2842 char name[GFC_MAX_SYMBOL_LEN+9];
2843 gfc_component *strlen;
2844 if (!(c->ts.type == BT_CHARACTER
2845 && (c->ts.deferred || c->attr.pdt_string)))
2846 return false;
2847 sprintf (name, "_%s_length", c->name);
2848 for (strlen = c; strlen; strlen = strlen->next)
2849 if (strcmp (strlen->name, name) == 0)
2850 break;
2851 *decl = strlen ? strlen->backend_decl : NULL_TREE;
2852 return strlen != NULL;