Daily bump.
[official-gcc.git] / gcc / fortran / trans.c
blobeb5682a7cda31fa1b3714e1eee484365ad5cb6f1
1 /* Code translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2021 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");
48 const char gfc_msg_wrong_return[] = N_("Incorrect function return value");
51 /* Return a location_t suitable for 'tree' for a gfortran locus. The way the
52 parser works in gfortran, loc->lb->location contains only the line number
53 and LOCATION_COLUMN is 0; hence, the column has to be added when generating
54 locations for 'tree'. Cf. error.c's gfc_format_decoder. */
56 location_t
57 gfc_get_location (locus *loc)
59 return linemap_position_for_loc_and_offset (line_table, loc->lb->location,
60 loc->nextc - loc->lb->line);
63 /* Advance along TREE_CHAIN n times. */
65 tree
66 gfc_advance_chain (tree t, int n)
68 for (; n > 0; n--)
70 gcc_assert (t != NULL_TREE);
71 t = DECL_CHAIN (t);
73 return t;
76 static int num_var;
78 #define MAX_PREFIX_LEN 20
80 static tree
81 create_var_debug_raw (tree type, const char *prefix)
83 /* Space for prefix + "_" + 10-digit-number + \0. */
84 char name_buf[MAX_PREFIX_LEN + 1 + 10 + 1];
85 tree t;
86 int i;
88 if (prefix == NULL)
89 prefix = "gfc";
90 else
91 gcc_assert (strlen (prefix) <= MAX_PREFIX_LEN);
93 for (i = 0; prefix[i] != 0; i++)
94 name_buf[i] = gfc_wide_toupper (prefix[i]);
96 snprintf (name_buf + i, sizeof (name_buf) - i, "_%d", num_var++);
98 t = build_decl (input_location, VAR_DECL, get_identifier (name_buf), type);
100 /* Not setting this causes some regressions. */
101 DECL_ARTIFICIAL (t) = 1;
103 /* We want debug info for it. */
104 DECL_IGNORED_P (t) = 0;
105 /* It should not be nameless. */
106 DECL_NAMELESS (t) = 0;
108 /* Make the variable writable. */
109 TREE_READONLY (t) = 0;
111 DECL_EXTERNAL (t) = 0;
112 TREE_STATIC (t) = 0;
113 TREE_USED (t) = 1;
115 return t;
118 /* Creates a variable declaration with a given TYPE. */
120 tree
121 gfc_create_var_np (tree type, const char *prefix)
123 tree t;
125 if (flag_debug_aux_vars)
126 return create_var_debug_raw (type, prefix);
128 t = create_tmp_var_raw (type, prefix);
130 /* No warnings for anonymous variables. */
131 if (prefix == NULL)
132 suppress_warning (t);
134 return t;
138 /* Like above, but also adds it to the current scope. */
140 tree
141 gfc_create_var (tree type, const char *prefix)
143 tree tmp;
145 tmp = gfc_create_var_np (type, prefix);
147 pushdecl (tmp);
149 return tmp;
153 /* If the expression is not constant, evaluate it now. We assign the
154 result of the expression to an artificially created variable VAR, and
155 return a pointer to the VAR_DECL node for this variable. */
157 tree
158 gfc_evaluate_now_loc (location_t loc, tree expr, stmtblock_t * pblock)
160 tree var;
162 if (CONSTANT_CLASS_P (expr))
163 return expr;
165 var = gfc_create_var (TREE_TYPE (expr), NULL);
166 gfc_add_modify_loc (loc, pblock, var, expr);
168 return var;
172 tree
173 gfc_evaluate_now (tree expr, stmtblock_t * pblock)
175 return gfc_evaluate_now_loc (input_location, expr, pblock);
178 /* Like gfc_evaluate_now, but add the created variable to the
179 function scope. */
181 tree
182 gfc_evaluate_now_function_scope (tree expr, stmtblock_t * pblock)
184 tree var;
185 var = gfc_create_var_np (TREE_TYPE (expr), NULL);
186 gfc_add_decl_to_function (var);
187 gfc_add_modify (pblock, var, expr);
189 return var;
192 /* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
193 A MODIFY_EXPR is an assignment:
194 LHS <- RHS. */
196 void
197 gfc_add_modify_loc (location_t loc, stmtblock_t * pblock, tree lhs, tree rhs)
199 tree tmp;
201 tree t1, t2;
202 t1 = TREE_TYPE (rhs);
203 t2 = TREE_TYPE (lhs);
204 /* Make sure that the types of the rhs and the lhs are compatible
205 for scalar assignments. We should probably have something
206 similar for aggregates, but right now removing that check just
207 breaks everything. */
208 gcc_checking_assert (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)
209 || AGGREGATE_TYPE_P (TREE_TYPE (lhs)));
211 tmp = fold_build2_loc (loc, MODIFY_EXPR, void_type_node, lhs,
212 rhs);
213 gfc_add_expr_to_block (pblock, tmp);
217 void
218 gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs)
220 gfc_add_modify_loc (input_location, pblock, lhs, rhs);
224 /* Create a new scope/binding level and initialize a block. Care must be
225 taken when translating expressions as any temporaries will be placed in
226 the innermost scope. */
228 void
229 gfc_start_block (stmtblock_t * block)
231 /* Start a new binding level. */
232 pushlevel ();
233 block->has_scope = 1;
235 /* The block is empty. */
236 block->head = NULL_TREE;
240 /* Initialize a block without creating a new scope. */
242 void
243 gfc_init_block (stmtblock_t * block)
245 block->head = NULL_TREE;
246 block->has_scope = 0;
250 /* Sometimes we create a scope but it turns out that we don't actually
251 need it. This function merges the scope of BLOCK with its parent.
252 Only variable decls will be merged, you still need to add the code. */
254 void
255 gfc_merge_block_scope (stmtblock_t * block)
257 tree decl;
258 tree next;
260 gcc_assert (block->has_scope);
261 block->has_scope = 0;
263 /* Remember the decls in this scope. */
264 decl = getdecls ();
265 poplevel (0, 0);
267 /* Add them to the parent scope. */
268 while (decl != NULL_TREE)
270 next = DECL_CHAIN (decl);
271 DECL_CHAIN (decl) = NULL_TREE;
273 pushdecl (decl);
274 decl = next;
279 /* Finish a scope containing a block of statements. */
281 tree
282 gfc_finish_block (stmtblock_t * stmtblock)
284 tree decl;
285 tree expr;
286 tree block;
288 expr = stmtblock->head;
289 if (!expr)
290 expr = build_empty_stmt (input_location);
292 stmtblock->head = NULL_TREE;
294 if (stmtblock->has_scope)
296 decl = getdecls ();
298 if (decl)
300 block = poplevel (1, 0);
301 expr = build3_v (BIND_EXPR, decl, expr, block);
303 else
304 poplevel (0, 0);
307 return expr;
311 /* Build an ADDR_EXPR and cast the result to TYPE. If TYPE is NULL, the
312 natural type is used. */
314 tree
315 gfc_build_addr_expr (tree type, tree t)
317 tree base_type = TREE_TYPE (t);
318 tree natural_type;
320 if (type && POINTER_TYPE_P (type)
321 && TREE_CODE (base_type) == ARRAY_TYPE
322 && TYPE_MAIN_VARIANT (TREE_TYPE (type))
323 == TYPE_MAIN_VARIANT (TREE_TYPE (base_type)))
325 tree min_val = size_zero_node;
326 tree type_domain = TYPE_DOMAIN (base_type);
327 if (type_domain && TYPE_MIN_VALUE (type_domain))
328 min_val = TYPE_MIN_VALUE (type_domain);
329 t = fold (build4_loc (input_location, ARRAY_REF, TREE_TYPE (type),
330 t, min_val, NULL_TREE, NULL_TREE));
331 natural_type = type;
333 else
334 natural_type = build_pointer_type (base_type);
336 if (TREE_CODE (t) == INDIRECT_REF)
338 if (!type)
339 type = natural_type;
340 t = TREE_OPERAND (t, 0);
341 natural_type = TREE_TYPE (t);
343 else
345 tree base = get_base_address (t);
346 if (base && DECL_P (base))
347 TREE_ADDRESSABLE (base) = 1;
348 t = fold_build1_loc (input_location, ADDR_EXPR, natural_type, t);
351 if (type && natural_type != type)
352 t = convert (type, t);
354 return t;
358 static tree
359 get_array_span (tree type, tree decl)
361 tree span;
363 /* Component references are guaranteed to have a reliable value for
364 'span'. Likewise indirect references since they emerge from the
365 conversion of a CFI descriptor or the hidden dummy descriptor. */
366 if (TREE_CODE (decl) == COMPONENT_REF
367 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
368 return gfc_conv_descriptor_span_get (decl);
369 else if (TREE_CODE (decl) == INDIRECT_REF
370 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
371 return gfc_conv_descriptor_span_get (decl);
373 /* Return the span for deferred character length array references. */
374 if (type && TREE_CODE (type) == ARRAY_TYPE && TYPE_STRING_FLAG (type))
376 if (TREE_CODE (decl) == PARM_DECL)
377 decl = build_fold_indirect_ref_loc (input_location, decl);
378 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
379 span = gfc_conv_descriptor_span_get (decl);
380 else
381 span = gfc_get_character_len_in_bytes (type);
382 span = (span && !integer_zerop (span))
383 ? (fold_convert (gfc_array_index_type, span)) : (NULL_TREE);
385 /* Likewise for class array or pointer array references. */
386 else if (TREE_CODE (decl) == FIELD_DECL
387 || VAR_OR_FUNCTION_DECL_P (decl)
388 || TREE_CODE (decl) == PARM_DECL)
390 if (GFC_DECL_CLASS (decl))
392 /* When a temporary is in place for the class array, then the
393 original class' declaration is stored in the saved
394 descriptor. */
395 if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
396 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
397 else
399 /* Allow for dummy arguments and other good things. */
400 if (POINTER_TYPE_P (TREE_TYPE (decl)))
401 decl = build_fold_indirect_ref_loc (input_location, decl);
403 /* Check if '_data' is an array descriptor. If it is not,
404 the array must be one of the components of the class
405 object, so return a null span. */
406 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (
407 gfc_class_data_get (decl))))
408 return NULL_TREE;
410 span = gfc_class_vtab_size_get (decl);
411 /* For unlimited polymorphic entities then _len component needs
412 to be multiplied with the size. */
413 span = gfc_resize_class_size_with_len (NULL, decl, span);
415 else if (GFC_DECL_PTR_ARRAY_P (decl))
417 if (TREE_CODE (decl) == PARM_DECL)
418 decl = build_fold_indirect_ref_loc (input_location, decl);
419 span = gfc_conv_descriptor_span_get (decl);
421 else
422 span = NULL_TREE;
424 else
425 span = NULL_TREE;
427 return span;
431 tree
432 gfc_build_spanned_array_ref (tree base, tree offset, tree span)
434 tree type;
435 tree tmp;
436 type = TREE_TYPE (TREE_TYPE (base));
437 offset = fold_build2_loc (input_location, MULT_EXPR,
438 gfc_array_index_type,
439 offset, span);
440 tmp = gfc_build_addr_expr (pvoid_type_node, base);
441 tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
442 tmp = fold_convert (build_pointer_type (type), tmp);
443 if ((TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != ARRAY_TYPE)
444 || !TYPE_STRING_FLAG (type))
445 tmp = build_fold_indirect_ref_loc (input_location, tmp);
446 return tmp;
450 /* Build an ARRAY_REF with its natural type. */
452 tree
453 gfc_build_array_ref (tree base, tree offset, tree decl, tree vptr)
455 tree type = TREE_TYPE (base);
456 tree span = NULL_TREE;
458 if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0)
460 gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0);
462 return fold_convert (TYPE_MAIN_VARIANT (type), base);
465 /* Scalar coarray, there is nothing to do. */
466 if (TREE_CODE (type) != ARRAY_TYPE)
468 gcc_assert (decl == NULL_TREE);
469 gcc_assert (integer_zerop (offset));
470 return base;
473 type = TREE_TYPE (type);
475 if (DECL_P (base))
476 TREE_ADDRESSABLE (base) = 1;
478 /* Strip NON_LVALUE_EXPR nodes. */
479 STRIP_TYPE_NOPS (offset);
481 /* If decl or vptr are non-null, pointer arithmetic for the array reference
482 is likely. Generate the 'span' for the array reference. */
483 if (vptr)
485 span = gfc_vptr_size_get (vptr);
487 /* Check if this is an unlimited polymorphic object carrying a character
488 payload. In this case, the 'len' field is non-zero. */
489 if (decl && GFC_CLASS_TYPE_P (TREE_TYPE (decl)))
490 span = gfc_resize_class_size_with_len (NULL, decl, span);
492 else if (decl)
493 span = get_array_span (type, decl);
495 /* If a non-null span has been generated reference the element with
496 pointer arithmetic. */
497 if (span != NULL_TREE)
498 return gfc_build_spanned_array_ref (base, offset, span);
499 /* Otherwise use a straightforward array reference. */
500 else
501 return build4_loc (input_location, ARRAY_REF, type, base, offset,
502 NULL_TREE, NULL_TREE);
506 /* Generate a call to print a runtime error possibly including multiple
507 arguments and a locus. */
509 static tree
510 trans_runtime_error_vararg (tree errorfunc, locus* where, const char* msgid,
511 va_list ap)
513 stmtblock_t block;
514 tree tmp;
515 tree arg, arg2;
516 tree *argarray;
517 tree fntype;
518 char *message;
519 const char *p;
520 int line, nargs, i;
521 location_t loc;
523 /* Compute the number of extra arguments from the format string. */
524 for (p = msgid, nargs = 0; *p; p++)
525 if (*p == '%')
527 p++;
528 if (*p != '%')
529 nargs++;
532 /* The code to generate the error. */
533 gfc_start_block (&block);
535 if (where)
537 line = LOCATION_LINE (where->lb->location);
538 message = xasprintf ("At line %d of file %s", line,
539 where->lb->file->filename);
541 else
542 message = xasprintf ("In file '%s', around line %d",
543 gfc_source_file, LOCATION_LINE (input_location) + 1);
545 arg = gfc_build_addr_expr (pchar_type_node,
546 gfc_build_localized_cstring_const (message));
547 free (message);
549 message = xasprintf ("%s", _(msgid));
550 arg2 = gfc_build_addr_expr (pchar_type_node,
551 gfc_build_localized_cstring_const (message));
552 free (message);
554 /* Build the argument array. */
555 argarray = XALLOCAVEC (tree, nargs + 2);
556 argarray[0] = arg;
557 argarray[1] = arg2;
558 for (i = 0; i < nargs; i++)
559 argarray[2 + i] = va_arg (ap, tree);
561 /* Build the function call to runtime_(warning,error)_at; because of the
562 variable number of arguments, we can't use build_call_expr_loc dinput_location,
563 irectly. */
564 fntype = TREE_TYPE (errorfunc);
566 loc = where ? gfc_get_location (where) : input_location;
567 tmp = fold_build_call_array_loc (loc, TREE_TYPE (fntype),
568 fold_build1_loc (loc, ADDR_EXPR,
569 build_pointer_type (fntype),
570 errorfunc),
571 nargs + 2, argarray);
572 gfc_add_expr_to_block (&block, tmp);
574 return gfc_finish_block (&block);
578 tree
579 gfc_trans_runtime_error (bool error, locus* where, const char* msgid, ...)
581 va_list ap;
582 tree result;
584 va_start (ap, msgid);
585 result = trans_runtime_error_vararg (error
586 ? gfor_fndecl_runtime_error_at
587 : gfor_fndecl_runtime_warning_at,
588 where, msgid, ap);
589 va_end (ap);
590 return result;
594 /* Generate a runtime error if COND is true. */
596 void
597 gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
598 locus * where, const char * msgid, ...)
600 va_list ap;
601 stmtblock_t block;
602 tree body;
603 tree tmp;
604 tree tmpvar = NULL;
606 if (integer_zerop (cond))
607 return;
609 if (once)
611 tmpvar = gfc_create_var (logical_type_node, "print_warning");
612 TREE_STATIC (tmpvar) = 1;
613 DECL_INITIAL (tmpvar) = logical_true_node;
614 gfc_add_expr_to_block (pblock, tmpvar);
617 gfc_start_block (&block);
619 /* For error, runtime_error_at already implies PRED_NORETURN. */
620 if (!error && once)
621 gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_WARN_ONCE,
622 NOT_TAKEN));
624 /* The code to generate the error. */
625 va_start (ap, msgid);
626 gfc_add_expr_to_block (&block,
627 trans_runtime_error_vararg
628 (error ? gfor_fndecl_runtime_error_at
629 : gfor_fndecl_runtime_warning_at,
630 where, msgid, ap));
631 va_end (ap);
633 if (once)
634 gfc_add_modify (&block, tmpvar, logical_false_node);
636 body = gfc_finish_block (&block);
638 if (integer_onep (cond))
640 gfc_add_expr_to_block (pblock, body);
642 else
644 if (once)
645 cond = fold_build2_loc (gfc_get_location (where), TRUTH_AND_EXPR,
646 long_integer_type_node, tmpvar, cond);
647 else
648 cond = fold_convert (long_integer_type_node, cond);
650 tmp = fold_build3_loc (gfc_get_location (where), COND_EXPR, void_type_node,
651 cond, body,
652 build_empty_stmt (gfc_get_location (where)));
653 gfc_add_expr_to_block (pblock, tmp);
658 static tree
659 trans_os_error_at (locus* where, const char* msgid, ...)
661 va_list ap;
662 tree result;
664 va_start (ap, msgid);
665 result = trans_runtime_error_vararg (gfor_fndecl_os_error_at,
666 where, msgid, ap);
667 va_end (ap);
668 return result;
673 /* Call malloc to allocate size bytes of memory, with special conditions:
674 + if size == 0, return a malloced area of size 1,
675 + if malloc returns NULL, issue a runtime error. */
676 tree
677 gfc_call_malloc (stmtblock_t * block, tree type, tree size)
679 tree tmp, malloc_result, null_result, res, malloc_tree;
680 stmtblock_t block2;
682 /* Create a variable to hold the result. */
683 res = gfc_create_var (prvoid_type_node, NULL);
685 /* Call malloc. */
686 gfc_start_block (&block2);
688 if (size == NULL_TREE)
689 size = build_int_cst (size_type_node, 1);
691 size = fold_convert (size_type_node, size);
692 size = fold_build2_loc (input_location, MAX_EXPR, size_type_node, size,
693 build_int_cst (size_type_node, 1));
695 malloc_tree = builtin_decl_explicit (BUILT_IN_MALLOC);
696 gfc_add_modify (&block2, res,
697 fold_convert (prvoid_type_node,
698 build_call_expr_loc (input_location,
699 malloc_tree, 1, size)));
701 /* Optionally check whether malloc was successful. */
702 if (gfc_option.rtcheck & GFC_RTCHECK_MEM)
704 null_result = fold_build2_loc (input_location, EQ_EXPR,
705 logical_type_node, res,
706 build_int_cst (pvoid_type_node, 0));
707 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
708 null_result,
709 trans_os_error_at (NULL,
710 "Error allocating %lu bytes",
711 fold_convert
712 (long_unsigned_type_node,
713 size)),
714 build_empty_stmt (input_location));
715 gfc_add_expr_to_block (&block2, tmp);
718 malloc_result = gfc_finish_block (&block2);
719 gfc_add_expr_to_block (block, malloc_result);
721 if (type != NULL)
722 res = fold_convert (type, res);
723 return res;
727 /* Allocate memory, using an optional status argument.
729 This function follows the following pseudo-code:
731 void *
732 allocate (size_t size, integer_type stat)
734 void *newmem;
736 if (stat requested)
737 stat = 0;
739 newmem = malloc (MAX (size, 1));
740 if (newmem == NULL)
742 if (stat)
743 *stat = LIBERROR_ALLOCATION;
744 else
745 runtime_error ("Allocation would exceed memory limit");
747 return newmem;
748 } */
749 void
750 gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
751 tree size, tree status)
753 tree tmp, error_cond;
754 stmtblock_t on_error;
755 tree status_type = status ? TREE_TYPE (status) : NULL_TREE;
757 /* If successful and stat= is given, set status to 0. */
758 if (status != NULL_TREE)
759 gfc_add_expr_to_block (block,
760 fold_build2_loc (input_location, MODIFY_EXPR, status_type,
761 status, build_int_cst (status_type, 0)));
763 /* The allocation itself. */
764 size = fold_convert (size_type_node, size);
765 gfc_add_modify (block, pointer,
766 fold_convert (TREE_TYPE (pointer),
767 build_call_expr_loc (input_location,
768 builtin_decl_explicit (BUILT_IN_MALLOC), 1,
769 fold_build2_loc (input_location,
770 MAX_EXPR, size_type_node, size,
771 build_int_cst (size_type_node, 1)))));
773 /* What to do in case of error. */
774 gfc_start_block (&on_error);
775 if (status != NULL_TREE)
777 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, status,
778 build_int_cst (status_type, LIBERROR_ALLOCATION));
779 gfc_add_expr_to_block (&on_error, tmp);
781 else
783 /* Here, os_error_at already implies PRED_NORETURN. */
784 tree lusize = fold_convert (long_unsigned_type_node, size);
785 tmp = trans_os_error_at (NULL, "Error allocating %lu bytes", lusize);
786 gfc_add_expr_to_block (&on_error, tmp);
789 error_cond = fold_build2_loc (input_location, EQ_EXPR,
790 logical_type_node, pointer,
791 build_int_cst (prvoid_type_node, 0));
792 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
793 gfc_unlikely (error_cond, PRED_FORTRAN_FAIL_ALLOC),
794 gfc_finish_block (&on_error),
795 build_empty_stmt (input_location));
797 gfc_add_expr_to_block (block, tmp);
801 /* Allocate memory, using an optional status argument.
803 This function follows the following pseudo-code:
805 void *
806 allocate (size_t size, void** token, int *stat, char* errmsg, int errlen)
808 void *newmem;
810 newmem = _caf_register (size, regtype, token, &stat, errmsg, errlen);
811 return newmem;
812 } */
813 void
814 gfc_allocate_using_caf_lib (stmtblock_t * block, tree pointer, tree size,
815 tree token, tree status, tree errmsg, tree errlen,
816 gfc_coarray_regtype alloc_type)
818 tree tmp, pstat;
820 gcc_assert (token != NULL_TREE);
822 /* The allocation itself. */
823 if (status == NULL_TREE)
824 pstat = null_pointer_node;
825 else
826 pstat = gfc_build_addr_expr (NULL_TREE, status);
828 if (errmsg == NULL_TREE)
830 gcc_assert(errlen == NULL_TREE);
831 errmsg = null_pointer_node;
832 errlen = build_int_cst (integer_type_node, 0);
835 size = fold_convert (size_type_node, size);
836 tmp = build_call_expr_loc (input_location,
837 gfor_fndecl_caf_register, 7,
838 fold_build2_loc (input_location,
839 MAX_EXPR, size_type_node, size, size_one_node),
840 build_int_cst (integer_type_node, alloc_type),
841 token, gfc_build_addr_expr (pvoid_type_node, pointer),
842 pstat, errmsg, errlen);
844 gfc_add_expr_to_block (block, tmp);
846 /* It guarantees memory consistency within the same segment */
847 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
848 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
849 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
850 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
851 ASM_VOLATILE_P (tmp) = 1;
852 gfc_add_expr_to_block (block, tmp);
856 /* Generate code for an ALLOCATE statement when the argument is an
857 allocatable variable. If the variable is currently allocated, it is an
858 error to allocate it again.
860 This function follows the following pseudo-code:
862 void *
863 allocate_allocatable (void *mem, size_t size, integer_type stat)
865 if (mem == NULL)
866 return allocate (size, stat);
867 else
869 if (stat)
870 stat = LIBERROR_ALLOCATION;
871 else
872 runtime_error ("Attempting to allocate already allocated variable");
876 expr must be set to the original expression being allocated for its locus
877 and variable name in case a runtime error has to be printed. */
878 void
879 gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size,
880 tree token, tree status, tree errmsg, tree errlen,
881 tree label_finish, gfc_expr* expr, int corank)
883 stmtblock_t alloc_block;
884 tree tmp, null_mem, alloc, error;
885 tree type = TREE_TYPE (mem);
886 symbol_attribute caf_attr;
887 bool need_assign = false, refs_comp = false;
888 gfc_coarray_regtype caf_alloc_type = GFC_CAF_COARRAY_ALLOC;
890 size = fold_convert (size_type_node, size);
891 null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
892 logical_type_node, mem,
893 build_int_cst (type, 0)),
894 PRED_FORTRAN_REALLOC);
896 /* If mem is NULL, we call gfc_allocate_using_malloc or
897 gfc_allocate_using_lib. */
898 gfc_start_block (&alloc_block);
900 if (flag_coarray == GFC_FCOARRAY_LIB)
901 caf_attr = gfc_caf_attr (expr, true, &refs_comp);
903 if (flag_coarray == GFC_FCOARRAY_LIB
904 && (corank > 0 || caf_attr.codimension))
906 tree cond, sub_caf_tree;
907 gfc_se se;
908 bool compute_special_caf_types_size = false;
910 if (expr->ts.type == BT_DERIVED
911 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
912 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
914 compute_special_caf_types_size = true;
915 caf_alloc_type = GFC_CAF_LOCK_ALLOC;
917 else if (expr->ts.type == BT_DERIVED
918 && expr->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
919 && expr->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
921 compute_special_caf_types_size = true;
922 caf_alloc_type = GFC_CAF_EVENT_ALLOC;
924 else if (!caf_attr.coarray_comp && refs_comp)
925 /* Only allocatable components in a derived type coarray can be
926 allocate only. */
927 caf_alloc_type = GFC_CAF_COARRAY_ALLOC_ALLOCATE_ONLY;
929 gfc_init_se (&se, NULL);
930 sub_caf_tree = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
931 if (sub_caf_tree == NULL_TREE)
932 sub_caf_tree = token;
934 /* When mem is an array ref, then strip the .data-ref. */
935 if (TREE_CODE (mem) == COMPONENT_REF
936 && !(GFC_ARRAY_TYPE_P (TREE_TYPE (mem))))
937 tmp = TREE_OPERAND (mem, 0);
938 else
939 tmp = mem;
941 if (!(GFC_ARRAY_TYPE_P (TREE_TYPE (tmp))
942 && TYPE_LANG_SPECIFIC (TREE_TYPE (tmp))->corank == 0)
943 && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
945 symbol_attribute attr;
947 gfc_clear_attr (&attr);
948 tmp = gfc_conv_scalar_to_descriptor (&se, mem, attr);
949 need_assign = true;
951 gfc_add_block_to_block (&alloc_block, &se.pre);
953 /* In the front end, we represent the lock variable as pointer. However,
954 the FE only passes the pointer around and leaves the actual
955 representation to the library. Hence, we have to convert back to the
956 number of elements. */
957 if (compute_special_caf_types_size)
958 size = fold_build2_loc (input_location, TRUNC_DIV_EXPR, size_type_node,
959 size, TYPE_SIZE_UNIT (ptr_type_node));
961 gfc_allocate_using_caf_lib (&alloc_block, tmp, size, sub_caf_tree,
962 status, errmsg, errlen, caf_alloc_type);
963 if (need_assign)
964 gfc_add_modify (&alloc_block, mem, fold_convert (TREE_TYPE (mem),
965 gfc_conv_descriptor_data_get (tmp)));
966 if (status != NULL_TREE)
968 TREE_USED (label_finish) = 1;
969 tmp = build1_v (GOTO_EXPR, label_finish);
970 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
971 status, build_zero_cst (TREE_TYPE (status)));
972 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
973 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
974 tmp, build_empty_stmt (input_location));
975 gfc_add_expr_to_block (&alloc_block, tmp);
978 else
979 gfc_allocate_using_malloc (&alloc_block, mem, size, status);
981 alloc = gfc_finish_block (&alloc_block);
983 /* If mem is not NULL, we issue a runtime error or set the
984 status variable. */
985 if (expr)
987 tree varname;
989 gcc_assert (expr->expr_type == EXPR_VARIABLE && expr->symtree);
990 varname = gfc_build_cstring_const (expr->symtree->name);
991 varname = gfc_build_addr_expr (pchar_type_node, varname);
993 error = gfc_trans_runtime_error (true, &expr->where,
994 "Attempting to allocate already"
995 " allocated variable '%s'",
996 varname);
998 else
999 error = gfc_trans_runtime_error (true, NULL,
1000 "Attempting to allocate already allocated"
1001 " variable");
1003 if (status != NULL_TREE)
1005 tree status_type = TREE_TYPE (status);
1007 error = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1008 status, build_int_cst (status_type, LIBERROR_ALLOCATION));
1011 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem,
1012 error, alloc);
1013 gfc_add_expr_to_block (block, tmp);
1017 /* Free a given variable. */
1019 tree
1020 gfc_call_free (tree var)
1022 return build_call_expr_loc (input_location,
1023 builtin_decl_explicit (BUILT_IN_FREE),
1024 1, fold_convert (pvoid_type_node, var));
1028 /* Build a call to a FINAL procedure, which finalizes "var". */
1030 static tree
1031 gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var,
1032 bool fini_coarray, gfc_expr *class_size)
1034 stmtblock_t block;
1035 gfc_se se;
1036 tree final_fndecl, array, size, tmp;
1037 symbol_attribute attr;
1039 gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE);
1040 gcc_assert (var);
1042 gfc_start_block (&block);
1043 gfc_init_se (&se, NULL);
1044 gfc_conv_expr (&se, final_wrapper);
1045 final_fndecl = se.expr;
1046 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
1047 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
1049 if (ts.type == BT_DERIVED)
1051 tree elem_size;
1053 gcc_assert (!class_size);
1054 elem_size = gfc_typenode_for_spec (&ts);
1055 elem_size = TYPE_SIZE_UNIT (elem_size);
1056 size = fold_convert (gfc_array_index_type, elem_size);
1058 gfc_init_se (&se, NULL);
1059 se.want_pointer = 1;
1060 if (var->rank)
1062 se.descriptor_only = 1;
1063 gfc_conv_expr_descriptor (&se, var);
1064 array = se.expr;
1066 else
1068 gfc_conv_expr (&se, var);
1069 gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
1070 array = se.expr;
1072 /* No copy back needed, hence set attr's allocatable/pointer
1073 to zero. */
1074 gfc_clear_attr (&attr);
1075 gfc_init_se (&se, NULL);
1076 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1077 gcc_assert (se.post.head == NULL_TREE);
1080 else
1082 gfc_expr *array_expr;
1083 gcc_assert (class_size);
1084 gfc_init_se (&se, NULL);
1085 gfc_conv_expr (&se, class_size);
1086 gfc_add_block_to_block (&block, &se.pre);
1087 gcc_assert (se.post.head == NULL_TREE);
1088 size = se.expr;
1090 array_expr = gfc_copy_expr (var);
1091 gfc_init_se (&se, NULL);
1092 se.want_pointer = 1;
1093 if (array_expr->rank)
1095 gfc_add_class_array_ref (array_expr);
1096 se.descriptor_only = 1;
1097 gfc_conv_expr_descriptor (&se, array_expr);
1098 array = se.expr;
1100 else
1102 gfc_add_data_component (array_expr);
1103 gfc_conv_expr (&se, array_expr);
1104 gfc_add_block_to_block (&block, &se.pre);
1105 gcc_assert (se.post.head == NULL_TREE);
1106 array = se.expr;
1108 if (!gfc_is_coarray (array_expr))
1110 /* No copy back needed, hence set attr's allocatable/pointer
1111 to zero. */
1112 gfc_clear_attr (&attr);
1113 gfc_init_se (&se, NULL);
1114 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1116 gcc_assert (se.post.head == NULL_TREE);
1118 gfc_free_expr (array_expr);
1121 if (!POINTER_TYPE_P (TREE_TYPE (array)))
1122 array = gfc_build_addr_expr (NULL, array);
1124 gfc_add_block_to_block (&block, &se.pre);
1125 tmp = build_call_expr_loc (input_location,
1126 final_fndecl, 3, array,
1127 size, fini_coarray ? boolean_true_node
1128 : boolean_false_node);
1129 gfc_add_block_to_block (&block, &se.post);
1130 gfc_add_expr_to_block (&block, tmp);
1131 return gfc_finish_block (&block);
1135 bool
1136 gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp,
1137 bool fini_coarray)
1139 gfc_se se;
1140 stmtblock_t block2;
1141 tree final_fndecl, size, array, tmp, cond;
1142 symbol_attribute attr;
1143 gfc_expr *final_expr = NULL;
1145 if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS)
1146 return false;
1148 gfc_init_block (&block2);
1150 if (comp->ts.type == BT_DERIVED)
1152 if (comp->attr.pointer)
1153 return false;
1155 gfc_is_finalizable (comp->ts.u.derived, &final_expr);
1156 if (!final_expr)
1157 return false;
1159 gfc_init_se (&se, NULL);
1160 gfc_conv_expr (&se, final_expr);
1161 final_fndecl = se.expr;
1162 size = gfc_typenode_for_spec (&comp->ts);
1163 size = TYPE_SIZE_UNIT (size);
1164 size = fold_convert (gfc_array_index_type, size);
1166 array = decl;
1168 else /* comp->ts.type == BT_CLASS. */
1170 if (CLASS_DATA (comp)->attr.class_pointer)
1171 return false;
1173 gfc_is_finalizable (CLASS_DATA (comp)->ts.u.derived, &final_expr);
1174 final_fndecl = gfc_class_vtab_final_get (decl);
1175 size = gfc_class_vtab_size_get (decl);
1176 array = gfc_class_data_get (decl);
1179 if (comp->attr.allocatable
1180 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)->attr.allocatable))
1182 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))
1183 ? gfc_conv_descriptor_data_get (array) : array;
1184 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1185 tmp, fold_convert (TREE_TYPE (tmp),
1186 null_pointer_node));
1188 else
1189 cond = logical_true_node;
1191 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array)))
1193 gfc_clear_attr (&attr);
1194 gfc_init_se (&se, NULL);
1195 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1196 gfc_add_block_to_block (&block2, &se.pre);
1197 gcc_assert (se.post.head == NULL_TREE);
1200 if (!POINTER_TYPE_P (TREE_TYPE (array)))
1201 array = gfc_build_addr_expr (NULL, array);
1203 if (!final_expr)
1205 tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1206 final_fndecl,
1207 fold_convert (TREE_TYPE (final_fndecl),
1208 null_pointer_node));
1209 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1210 logical_type_node, cond, tmp);
1213 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
1214 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
1216 tmp = build_call_expr_loc (input_location,
1217 final_fndecl, 3, array,
1218 size, fini_coarray ? boolean_true_node
1219 : boolean_false_node);
1220 gfc_add_expr_to_block (&block2, tmp);
1221 tmp = gfc_finish_block (&block2);
1223 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
1224 build_empty_stmt (input_location));
1225 gfc_add_expr_to_block (block, tmp);
1227 return true;
1231 /* Add a call to the finalizer, using the passed *expr. Returns
1232 true when a finalizer call has been inserted. */
1234 bool
1235 gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2)
1237 tree tmp;
1238 gfc_ref *ref;
1239 gfc_expr *expr;
1240 gfc_expr *final_expr = NULL;
1241 gfc_expr *elem_size = NULL;
1242 bool has_finalizer = false;
1244 if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS))
1245 return false;
1247 if (expr2->ts.type == BT_DERIVED)
1249 gfc_is_finalizable (expr2->ts.u.derived, &final_expr);
1250 if (!final_expr)
1251 return false;
1254 /* If we have a class array, we need go back to the class
1255 container. */
1256 expr = gfc_copy_expr (expr2);
1258 if (expr->ref && expr->ref->next && !expr->ref->next->next
1259 && expr->ref->next->type == REF_ARRAY
1260 && expr->ref->type == REF_COMPONENT
1261 && strcmp (expr->ref->u.c.component->name, "_data") == 0)
1263 gfc_free_ref_list (expr->ref);
1264 expr->ref = NULL;
1266 else
1267 for (ref = expr->ref; ref; ref = ref->next)
1268 if (ref->next && ref->next->next && !ref->next->next->next
1269 && ref->next->next->type == REF_ARRAY
1270 && ref->next->type == REF_COMPONENT
1271 && strcmp (ref->next->u.c.component->name, "_data") == 0)
1273 gfc_free_ref_list (ref->next);
1274 ref->next = NULL;
1277 if (expr->ts.type == BT_CLASS)
1279 has_finalizer = gfc_is_finalizable (expr->ts.u.derived, NULL);
1281 if (!expr2->rank && !expr2->ref && CLASS_DATA (expr2->symtree->n.sym)->as)
1282 expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank;
1284 final_expr = gfc_copy_expr (expr);
1285 gfc_add_vptr_component (final_expr);
1286 gfc_add_final_component (final_expr);
1288 elem_size = gfc_copy_expr (expr);
1289 gfc_add_vptr_component (elem_size);
1290 gfc_add_size_component (elem_size);
1293 gcc_assert (final_expr->expr_type == EXPR_VARIABLE);
1295 tmp = gfc_build_final_call (expr->ts, final_expr, expr,
1296 false, elem_size);
1298 if (expr->ts.type == BT_CLASS && !has_finalizer)
1300 tree cond;
1301 gfc_se se;
1303 gfc_init_se (&se, NULL);
1304 se.want_pointer = 1;
1305 gfc_conv_expr (&se, final_expr);
1306 cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1307 se.expr, build_int_cst (TREE_TYPE (se.expr), 0));
1309 /* For CLASS(*) not only sym->_vtab->_final can be NULL
1310 but already sym->_vtab itself. */
1311 if (UNLIMITED_POLY (expr))
1313 tree cond2;
1314 gfc_expr *vptr_expr;
1316 vptr_expr = gfc_copy_expr (expr);
1317 gfc_add_vptr_component (vptr_expr);
1319 gfc_init_se (&se, NULL);
1320 se.want_pointer = 1;
1321 gfc_conv_expr (&se, vptr_expr);
1322 gfc_free_expr (vptr_expr);
1324 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1325 se.expr,
1326 build_int_cst (TREE_TYPE (se.expr), 0));
1327 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1328 logical_type_node, cond2, cond);
1331 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1332 cond, tmp, build_empty_stmt (input_location));
1335 gfc_add_expr_to_block (block, tmp);
1337 return true;
1341 /* User-deallocate; we emit the code directly from the front-end, and the
1342 logic is the same as the previous library function:
1344 void
1345 deallocate (void *pointer, GFC_INTEGER_4 * stat)
1347 if (!pointer)
1349 if (stat)
1350 *stat = 1;
1351 else
1352 runtime_error ("Attempt to DEALLOCATE unallocated memory.");
1354 else
1356 free (pointer);
1357 if (stat)
1358 *stat = 0;
1362 In this front-end version, status doesn't have to be GFC_INTEGER_4.
1363 Moreover, if CAN_FAIL is true, then we will not emit a runtime error,
1364 even when no status variable is passed to us (this is used for
1365 unconditional deallocation generated by the front-end at end of
1366 each procedure).
1368 If a runtime-message is possible, `expr' must point to the original
1369 expression being deallocated for its locus and variable name.
1371 For coarrays, "pointer" must be the array descriptor and not its
1372 "data" component.
1374 COARRAY_DEALLOC_MODE gives the mode unregister coarrays. Available modes are
1375 the ones of GFC_CAF_DEREGTYPE, -1 when the mode for deregistration is to be
1376 analyzed and set by this routine, and -2 to indicate that a non-coarray is to
1377 be deallocated. */
1378 tree
1379 gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
1380 tree errlen, tree label_finish,
1381 bool can_fail, gfc_expr* expr,
1382 int coarray_dealloc_mode, tree add_when_allocated,
1383 tree caf_token)
1385 stmtblock_t null, non_null;
1386 tree cond, tmp, error;
1387 tree status_type = NULL_TREE;
1388 tree token = NULL_TREE;
1389 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
1391 if (coarray_dealloc_mode >= GFC_CAF_COARRAY_ANALYZE)
1393 if (flag_coarray == GFC_FCOARRAY_LIB)
1395 if (caf_token)
1396 token = caf_token;
1397 else
1399 tree caf_type, caf_decl = pointer;
1400 pointer = gfc_conv_descriptor_data_get (caf_decl);
1401 caf_type = TREE_TYPE (caf_decl);
1402 STRIP_NOPS (pointer);
1403 if (GFC_DESCRIPTOR_TYPE_P (caf_type))
1404 token = gfc_conv_descriptor_token (caf_decl);
1405 else if (DECL_LANG_SPECIFIC (caf_decl)
1406 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1407 token = GFC_DECL_TOKEN (caf_decl);
1408 else
1410 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
1411 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type)
1412 != NULL_TREE);
1413 token = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
1417 if (coarray_dealloc_mode == GFC_CAF_COARRAY_ANALYZE)
1419 bool comp_ref;
1420 if (expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
1421 && comp_ref)
1422 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
1423 // else do a deregister as set by default.
1425 else
1426 caf_dereg_type = (enum gfc_coarray_deregtype) coarray_dealloc_mode;
1428 else if (flag_coarray == GFC_FCOARRAY_SINGLE)
1429 pointer = gfc_conv_descriptor_data_get (pointer);
1431 else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
1432 pointer = gfc_conv_descriptor_data_get (pointer);
1434 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
1435 build_int_cst (TREE_TYPE (pointer), 0));
1437 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1438 we emit a runtime error. */
1439 gfc_start_block (&null);
1440 if (!can_fail)
1442 tree varname;
1444 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1446 varname = gfc_build_cstring_const (expr->symtree->name);
1447 varname = gfc_build_addr_expr (pchar_type_node, varname);
1449 error = gfc_trans_runtime_error (true, &expr->where,
1450 "Attempt to DEALLOCATE unallocated '%s'",
1451 varname);
1453 else
1454 error = build_empty_stmt (input_location);
1456 if (status != NULL_TREE && !integer_zerop (status))
1458 tree cond2;
1460 status_type = TREE_TYPE (TREE_TYPE (status));
1461 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1462 status, build_int_cst (TREE_TYPE (status), 0));
1463 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1464 fold_build1_loc (input_location, INDIRECT_REF,
1465 status_type, status),
1466 build_int_cst (status_type, 1));
1467 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1468 cond2, tmp, error);
1471 gfc_add_expr_to_block (&null, error);
1473 /* When POINTER is not NULL, we free it. */
1474 gfc_start_block (&non_null);
1475 if (add_when_allocated)
1476 gfc_add_expr_to_block (&non_null, add_when_allocated);
1477 gfc_add_finalizer_call (&non_null, expr);
1478 if (coarray_dealloc_mode == GFC_CAF_COARRAY_NOCOARRAY
1479 || flag_coarray != GFC_FCOARRAY_LIB)
1481 tmp = build_call_expr_loc (input_location,
1482 builtin_decl_explicit (BUILT_IN_FREE), 1,
1483 fold_convert (pvoid_type_node, pointer));
1484 gfc_add_expr_to_block (&non_null, tmp);
1485 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
1486 0));
1488 if (status != NULL_TREE && !integer_zerop (status))
1490 /* We set STATUS to zero if it is present. */
1491 tree status_type = TREE_TYPE (TREE_TYPE (status));
1492 tree cond2;
1494 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1495 status,
1496 build_int_cst (TREE_TYPE (status), 0));
1497 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1498 fold_build1_loc (input_location, INDIRECT_REF,
1499 status_type, status),
1500 build_int_cst (status_type, 0));
1501 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1502 gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC),
1503 tmp, build_empty_stmt (input_location));
1504 gfc_add_expr_to_block (&non_null, tmp);
1507 else
1509 tree cond2, pstat = null_pointer_node;
1511 if (errmsg == NULL_TREE)
1513 gcc_assert (errlen == NULL_TREE);
1514 errmsg = null_pointer_node;
1515 errlen = build_zero_cst (integer_type_node);
1517 else
1519 gcc_assert (errlen != NULL_TREE);
1520 if (!POINTER_TYPE_P (TREE_TYPE (errmsg)))
1521 errmsg = gfc_build_addr_expr (NULL_TREE, errmsg);
1524 if (status != NULL_TREE && !integer_zerop (status))
1526 gcc_assert (status_type == integer_type_node);
1527 pstat = status;
1530 token = gfc_build_addr_expr (NULL_TREE, token);
1531 gcc_assert (caf_dereg_type > GFC_CAF_COARRAY_ANALYZE);
1532 tmp = build_call_expr_loc (input_location,
1533 gfor_fndecl_caf_deregister, 5,
1534 token, build_int_cst (integer_type_node,
1535 caf_dereg_type),
1536 pstat, errmsg, errlen);
1537 gfc_add_expr_to_block (&non_null, tmp);
1539 /* It guarantees memory consistency within the same segment */
1540 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1541 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1542 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1543 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1544 ASM_VOLATILE_P (tmp) = 1;
1545 gfc_add_expr_to_block (&non_null, tmp);
1547 if (status != NULL_TREE)
1549 tree stat = build_fold_indirect_ref_loc (input_location, status);
1550 tree nullify = fold_build2_loc (input_location, MODIFY_EXPR,
1551 void_type_node, pointer,
1552 build_int_cst (TREE_TYPE (pointer),
1553 0));
1555 TREE_USED (label_finish) = 1;
1556 tmp = build1_v (GOTO_EXPR, label_finish);
1557 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1558 stat, build_zero_cst (TREE_TYPE (stat)));
1559 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1560 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
1561 tmp, nullify);
1562 gfc_add_expr_to_block (&non_null, tmp);
1564 else
1565 gfc_add_modify (&non_null, pointer, build_int_cst (TREE_TYPE (pointer),
1566 0));
1569 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
1570 gfc_finish_block (&null),
1571 gfc_finish_block (&non_null));
1575 /* Generate code for deallocation of allocatable scalars (variables or
1576 components). Before the object itself is freed, any allocatable
1577 subcomponents are being deallocated. */
1579 tree
1580 gfc_deallocate_scalar_with_status (tree pointer, tree status, tree label_finish,
1581 bool can_fail, gfc_expr* expr,
1582 gfc_typespec ts, bool coarray)
1584 stmtblock_t null, non_null;
1585 tree cond, tmp, error;
1586 bool finalizable, comp_ref;
1587 gfc_coarray_deregtype caf_dereg_type = GFC_CAF_COARRAY_DEREGISTER;
1589 if (coarray && expr && !gfc_caf_attr (expr, false, &comp_ref).coarray_comp
1590 && comp_ref)
1591 caf_dereg_type = GFC_CAF_COARRAY_DEALLOCATE_ONLY;
1593 cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pointer,
1594 build_int_cst (TREE_TYPE (pointer), 0));
1596 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1597 we emit a runtime error. */
1598 gfc_start_block (&null);
1599 if (!can_fail)
1601 tree varname;
1603 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1605 varname = gfc_build_cstring_const (expr->symtree->name);
1606 varname = gfc_build_addr_expr (pchar_type_node, varname);
1608 error = gfc_trans_runtime_error (true, &expr->where,
1609 "Attempt to DEALLOCATE unallocated '%s'",
1610 varname);
1612 else
1613 error = build_empty_stmt (input_location);
1615 if (status != NULL_TREE && !integer_zerop (status))
1617 tree status_type = TREE_TYPE (TREE_TYPE (status));
1618 tree cond2;
1620 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1621 status, build_int_cst (TREE_TYPE (status), 0));
1622 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1623 fold_build1_loc (input_location, INDIRECT_REF,
1624 status_type, status),
1625 build_int_cst (status_type, 1));
1626 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1627 cond2, tmp, error);
1629 gfc_add_expr_to_block (&null, error);
1631 /* When POINTER is not NULL, we free it. */
1632 gfc_start_block (&non_null);
1634 /* Free allocatable components. */
1635 finalizable = gfc_add_finalizer_call (&non_null, expr);
1636 if (!finalizable && ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
1638 int caf_mode = coarray
1639 ? ((caf_dereg_type == GFC_CAF_COARRAY_DEALLOCATE_ONLY
1640 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0)
1641 | GFC_STRUCTURE_CAF_MODE_ENABLE_COARRAY
1642 | GFC_STRUCTURE_CAF_MODE_IN_COARRAY)
1643 : 0;
1644 if (coarray && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)))
1645 tmp = gfc_conv_descriptor_data_get (pointer);
1646 else
1647 tmp = build_fold_indirect_ref_loc (input_location, pointer);
1648 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0, caf_mode);
1649 gfc_add_expr_to_block (&non_null, tmp);
1652 if (!coarray || flag_coarray == GFC_FCOARRAY_SINGLE)
1654 tmp = build_call_expr_loc (input_location,
1655 builtin_decl_explicit (BUILT_IN_FREE), 1,
1656 fold_convert (pvoid_type_node, pointer));
1657 gfc_add_expr_to_block (&non_null, tmp);
1659 if (status != NULL_TREE && !integer_zerop (status))
1661 /* We set STATUS to zero if it is present. */
1662 tree status_type = TREE_TYPE (TREE_TYPE (status));
1663 tree cond2;
1665 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1666 status,
1667 build_int_cst (TREE_TYPE (status), 0));
1668 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1669 fold_build1_loc (input_location, INDIRECT_REF,
1670 status_type, status),
1671 build_int_cst (status_type, 0));
1672 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1673 cond2, tmp, build_empty_stmt (input_location));
1674 gfc_add_expr_to_block (&non_null, tmp);
1677 else
1679 tree token;
1680 tree pstat = null_pointer_node;
1681 gfc_se se;
1683 gfc_init_se (&se, NULL);
1684 token = gfc_get_ultimate_alloc_ptr_comps_caf_token (&se, expr);
1685 gcc_assert (token != NULL_TREE);
1687 if (status != NULL_TREE && !integer_zerop (status))
1689 gcc_assert (TREE_TYPE (TREE_TYPE (status)) == integer_type_node);
1690 pstat = status;
1693 tmp = build_call_expr_loc (input_location,
1694 gfor_fndecl_caf_deregister, 5,
1695 token, build_int_cst (integer_type_node,
1696 caf_dereg_type),
1697 pstat, null_pointer_node, integer_zero_node);
1698 gfc_add_expr_to_block (&non_null, tmp);
1700 /* It guarantees memory consistency within the same segment. */
1701 tmp = gfc_build_string_const (strlen ("memory")+1, "memory");
1702 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1703 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1704 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1705 ASM_VOLATILE_P (tmp) = 1;
1706 gfc_add_expr_to_block (&non_null, tmp);
1708 if (status != NULL_TREE)
1710 tree stat = build_fold_indirect_ref_loc (input_location, status);
1711 tree cond2;
1713 TREE_USED (label_finish) = 1;
1714 tmp = build1_v (GOTO_EXPR, label_finish);
1715 cond2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
1716 stat, build_zero_cst (TREE_TYPE (stat)));
1717 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1718 gfc_unlikely (cond2, PRED_FORTRAN_REALLOC),
1719 tmp, build_empty_stmt (input_location));
1720 gfc_add_expr_to_block (&non_null, tmp);
1724 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
1725 gfc_finish_block (&null),
1726 gfc_finish_block (&non_null));
1729 /* Reallocate MEM so it has SIZE bytes of data. This behaves like the
1730 following pseudo-code:
1732 void *
1733 internal_realloc (void *mem, size_t size)
1735 res = realloc (mem, size);
1736 if (!res && size != 0)
1737 _gfortran_os_error ("Allocation would exceed memory limit");
1739 return res;
1740 } */
1741 tree
1742 gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
1744 tree res, nonzero, null_result, tmp;
1745 tree type = TREE_TYPE (mem);
1747 /* Only evaluate the size once. */
1748 size = save_expr (fold_convert (size_type_node, size));
1750 /* Create a variable to hold the result. */
1751 res = gfc_create_var (type, NULL);
1753 /* Call realloc and check the result. */
1754 tmp = build_call_expr_loc (input_location,
1755 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
1756 fold_convert (pvoid_type_node, mem), size);
1757 gfc_add_modify (block, res, fold_convert (type, tmp));
1758 null_result = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
1759 res, build_int_cst (pvoid_type_node, 0));
1760 nonzero = fold_build2_loc (input_location, NE_EXPR, logical_type_node, size,
1761 build_int_cst (size_type_node, 0));
1762 null_result = fold_build2_loc (input_location, TRUTH_AND_EXPR, logical_type_node,
1763 null_result, nonzero);
1764 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1765 null_result,
1766 trans_os_error_at (NULL,
1767 "Error reallocating to %lu bytes",
1768 fold_convert
1769 (long_unsigned_type_node, size)),
1770 build_empty_stmt (input_location));
1771 gfc_add_expr_to_block (block, tmp);
1773 return res;
1777 /* Add an expression to another one, either at the front or the back. */
1779 static void
1780 add_expr_to_chain (tree* chain, tree expr, bool front)
1782 if (expr == NULL_TREE || IS_EMPTY_STMT (expr))
1783 return;
1785 if (*chain)
1787 if (TREE_CODE (*chain) != STATEMENT_LIST)
1789 tree tmp;
1791 tmp = *chain;
1792 *chain = NULL_TREE;
1793 append_to_statement_list (tmp, chain);
1796 if (front)
1798 tree_stmt_iterator i;
1800 i = tsi_start (*chain);
1801 tsi_link_before (&i, expr, TSI_CONTINUE_LINKING);
1803 else
1804 append_to_statement_list (expr, chain);
1806 else
1807 *chain = expr;
1811 /* Add a statement at the end of a block. */
1813 void
1814 gfc_add_expr_to_block (stmtblock_t * block, tree expr)
1816 gcc_assert (block);
1817 add_expr_to_chain (&block->head, expr, false);
1821 /* Add a statement at the beginning of a block. */
1823 void
1824 gfc_prepend_expr_to_block (stmtblock_t * block, tree expr)
1826 gcc_assert (block);
1827 add_expr_to_chain (&block->head, expr, true);
1831 /* Add a block the end of a block. */
1833 void
1834 gfc_add_block_to_block (stmtblock_t * block, stmtblock_t * append)
1836 gcc_assert (append);
1837 gcc_assert (!append->has_scope);
1839 gfc_add_expr_to_block (block, append->head);
1840 append->head = NULL_TREE;
1844 /* Save the current locus. The structure may not be complete, and should
1845 only be used with gfc_restore_backend_locus. */
1847 void
1848 gfc_save_backend_locus (locus * loc)
1850 loc->lb = XCNEW (gfc_linebuf);
1851 loc->lb->location = input_location;
1852 loc->lb->file = gfc_current_backend_file;
1856 /* Set the current locus. */
1858 void
1859 gfc_set_backend_locus (locus * loc)
1861 gfc_current_backend_file = loc->lb->file;
1862 input_location = gfc_get_location (loc);
1866 /* Restore the saved locus. Only used in conjunction with
1867 gfc_save_backend_locus, to free the memory when we are done. */
1869 void
1870 gfc_restore_backend_locus (locus * loc)
1872 /* This only restores the information captured by gfc_save_backend_locus,
1873 intentionally does not use gfc_get_location. */
1874 input_location = loc->lb->location;
1875 gfc_current_backend_file = loc->lb->file;
1876 free (loc->lb);
1880 /* Translate an executable statement. The tree cond is used by gfc_trans_do.
1881 This static function is wrapped by gfc_trans_code_cond and
1882 gfc_trans_code. */
1884 static tree
1885 trans_code (gfc_code * code, tree cond)
1887 stmtblock_t block;
1888 tree res;
1890 if (!code)
1891 return build_empty_stmt (input_location);
1893 gfc_start_block (&block);
1895 /* Translate statements one by one into GENERIC trees until we reach
1896 the end of this gfc_code branch. */
1897 for (; code; code = code->next)
1899 if (code->here != 0)
1901 res = gfc_trans_label_here (code);
1902 gfc_add_expr_to_block (&block, res);
1905 gfc_current_locus = code->loc;
1906 gfc_set_backend_locus (&code->loc);
1908 switch (code->op)
1910 case EXEC_NOP:
1911 case EXEC_END_BLOCK:
1912 case EXEC_END_NESTED_BLOCK:
1913 case EXEC_END_PROCEDURE:
1914 res = NULL_TREE;
1915 break;
1917 case EXEC_ASSIGN:
1918 res = gfc_trans_assign (code);
1919 break;
1921 case EXEC_LABEL_ASSIGN:
1922 res = gfc_trans_label_assign (code);
1923 break;
1925 case EXEC_POINTER_ASSIGN:
1926 res = gfc_trans_pointer_assign (code);
1927 break;
1929 case EXEC_INIT_ASSIGN:
1930 if (code->expr1->ts.type == BT_CLASS)
1931 res = gfc_trans_class_init_assign (code);
1932 else
1933 res = gfc_trans_init_assign (code);
1934 break;
1936 case EXEC_CONTINUE:
1937 res = NULL_TREE;
1938 break;
1940 case EXEC_CRITICAL:
1941 res = gfc_trans_critical (code);
1942 break;
1944 case EXEC_CYCLE:
1945 res = gfc_trans_cycle (code);
1946 break;
1948 case EXEC_EXIT:
1949 res = gfc_trans_exit (code);
1950 break;
1952 case EXEC_GOTO:
1953 res = gfc_trans_goto (code);
1954 break;
1956 case EXEC_ENTRY:
1957 res = gfc_trans_entry (code);
1958 break;
1960 case EXEC_PAUSE:
1961 res = gfc_trans_pause (code);
1962 break;
1964 case EXEC_STOP:
1965 case EXEC_ERROR_STOP:
1966 res = gfc_trans_stop (code, code->op == EXEC_ERROR_STOP);
1967 break;
1969 case EXEC_CALL:
1970 /* For MVBITS we've got the special exception that we need a
1971 dependency check, too. */
1973 bool is_mvbits = false;
1975 if (code->resolved_isym)
1977 res = gfc_conv_intrinsic_subroutine (code);
1978 if (res != NULL_TREE)
1979 break;
1982 if (code->resolved_isym
1983 && code->resolved_isym->id == GFC_ISYM_MVBITS)
1984 is_mvbits = true;
1986 res = gfc_trans_call (code, is_mvbits, NULL_TREE,
1987 NULL_TREE, false);
1989 break;
1991 case EXEC_CALL_PPC:
1992 res = gfc_trans_call (code, false, NULL_TREE,
1993 NULL_TREE, false);
1994 break;
1996 case EXEC_ASSIGN_CALL:
1997 res = gfc_trans_call (code, true, NULL_TREE,
1998 NULL_TREE, false);
1999 break;
2001 case EXEC_RETURN:
2002 res = gfc_trans_return (code);
2003 break;
2005 case EXEC_IF:
2006 res = gfc_trans_if (code);
2007 break;
2009 case EXEC_ARITHMETIC_IF:
2010 res = gfc_trans_arithmetic_if (code);
2011 break;
2013 case EXEC_BLOCK:
2014 res = gfc_trans_block_construct (code);
2015 break;
2017 case EXEC_DO:
2018 res = gfc_trans_do (code, cond);
2019 break;
2021 case EXEC_DO_CONCURRENT:
2022 res = gfc_trans_do_concurrent (code);
2023 break;
2025 case EXEC_DO_WHILE:
2026 res = gfc_trans_do_while (code);
2027 break;
2029 case EXEC_SELECT:
2030 res = gfc_trans_select (code);
2031 break;
2033 case EXEC_SELECT_TYPE:
2034 res = gfc_trans_select_type (code);
2035 break;
2037 case EXEC_SELECT_RANK:
2038 res = gfc_trans_select_rank (code);
2039 break;
2041 case EXEC_FLUSH:
2042 res = gfc_trans_flush (code);
2043 break;
2045 case EXEC_SYNC_ALL:
2046 case EXEC_SYNC_IMAGES:
2047 case EXEC_SYNC_MEMORY:
2048 res = gfc_trans_sync (code, code->op);
2049 break;
2051 case EXEC_LOCK:
2052 case EXEC_UNLOCK:
2053 res = gfc_trans_lock_unlock (code, code->op);
2054 break;
2056 case EXEC_EVENT_POST:
2057 case EXEC_EVENT_WAIT:
2058 res = gfc_trans_event_post_wait (code, code->op);
2059 break;
2061 case EXEC_FAIL_IMAGE:
2062 res = gfc_trans_fail_image (code);
2063 break;
2065 case EXEC_FORALL:
2066 res = gfc_trans_forall (code);
2067 break;
2069 case EXEC_FORM_TEAM:
2070 res = gfc_trans_form_team (code);
2071 break;
2073 case EXEC_CHANGE_TEAM:
2074 res = gfc_trans_change_team (code);
2075 break;
2077 case EXEC_END_TEAM:
2078 res = gfc_trans_end_team (code);
2079 break;
2081 case EXEC_SYNC_TEAM:
2082 res = gfc_trans_sync_team (code);
2083 break;
2085 case EXEC_WHERE:
2086 res = gfc_trans_where (code);
2087 break;
2089 case EXEC_ALLOCATE:
2090 res = gfc_trans_allocate (code);
2091 break;
2093 case EXEC_DEALLOCATE:
2094 res = gfc_trans_deallocate (code);
2095 break;
2097 case EXEC_OPEN:
2098 res = gfc_trans_open (code);
2099 break;
2101 case EXEC_CLOSE:
2102 res = gfc_trans_close (code);
2103 break;
2105 case EXEC_READ:
2106 res = gfc_trans_read (code);
2107 break;
2109 case EXEC_WRITE:
2110 res = gfc_trans_write (code);
2111 break;
2113 case EXEC_IOLENGTH:
2114 res = gfc_trans_iolength (code);
2115 break;
2117 case EXEC_BACKSPACE:
2118 res = gfc_trans_backspace (code);
2119 break;
2121 case EXEC_ENDFILE:
2122 res = gfc_trans_endfile (code);
2123 break;
2125 case EXEC_INQUIRE:
2126 res = gfc_trans_inquire (code);
2127 break;
2129 case EXEC_WAIT:
2130 res = gfc_trans_wait (code);
2131 break;
2133 case EXEC_REWIND:
2134 res = gfc_trans_rewind (code);
2135 break;
2137 case EXEC_TRANSFER:
2138 res = gfc_trans_transfer (code);
2139 break;
2141 case EXEC_DT_END:
2142 res = gfc_trans_dt_end (code);
2143 break;
2145 case EXEC_OMP_ATOMIC:
2146 case EXEC_OMP_BARRIER:
2147 case EXEC_OMP_CANCEL:
2148 case EXEC_OMP_CANCELLATION_POINT:
2149 case EXEC_OMP_CRITICAL:
2150 case EXEC_OMP_DEPOBJ:
2151 case EXEC_OMP_DISTRIBUTE:
2152 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
2153 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
2154 case EXEC_OMP_DISTRIBUTE_SIMD:
2155 case EXEC_OMP_DO:
2156 case EXEC_OMP_DO_SIMD:
2157 case EXEC_OMP_LOOP:
2158 case EXEC_OMP_ERROR:
2159 case EXEC_OMP_FLUSH:
2160 case EXEC_OMP_MASKED:
2161 case EXEC_OMP_MASKED_TASKLOOP:
2162 case EXEC_OMP_MASKED_TASKLOOP_SIMD:
2163 case EXEC_OMP_MASTER:
2164 case EXEC_OMP_MASTER_TASKLOOP:
2165 case EXEC_OMP_MASTER_TASKLOOP_SIMD:
2166 case EXEC_OMP_ORDERED:
2167 case EXEC_OMP_PARALLEL:
2168 case EXEC_OMP_PARALLEL_DO:
2169 case EXEC_OMP_PARALLEL_DO_SIMD:
2170 case EXEC_OMP_PARALLEL_LOOP:
2171 case EXEC_OMP_PARALLEL_MASKED:
2172 case EXEC_OMP_PARALLEL_MASKED_TASKLOOP:
2173 case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
2174 case EXEC_OMP_PARALLEL_MASTER:
2175 case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
2176 case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
2177 case EXEC_OMP_PARALLEL_SECTIONS:
2178 case EXEC_OMP_PARALLEL_WORKSHARE:
2179 case EXEC_OMP_SCOPE:
2180 case EXEC_OMP_SECTIONS:
2181 case EXEC_OMP_SIMD:
2182 case EXEC_OMP_SINGLE:
2183 case EXEC_OMP_TARGET:
2184 case EXEC_OMP_TARGET_DATA:
2185 case EXEC_OMP_TARGET_ENTER_DATA:
2186 case EXEC_OMP_TARGET_EXIT_DATA:
2187 case EXEC_OMP_TARGET_PARALLEL:
2188 case EXEC_OMP_TARGET_PARALLEL_DO:
2189 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
2190 case EXEC_OMP_TARGET_PARALLEL_LOOP:
2191 case EXEC_OMP_TARGET_SIMD:
2192 case EXEC_OMP_TARGET_TEAMS:
2193 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
2194 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
2195 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2196 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
2197 case EXEC_OMP_TARGET_TEAMS_LOOP:
2198 case EXEC_OMP_TARGET_UPDATE:
2199 case EXEC_OMP_TASK:
2200 case EXEC_OMP_TASKGROUP:
2201 case EXEC_OMP_TASKLOOP:
2202 case EXEC_OMP_TASKLOOP_SIMD:
2203 case EXEC_OMP_TASKWAIT:
2204 case EXEC_OMP_TASKYIELD:
2205 case EXEC_OMP_TEAMS:
2206 case EXEC_OMP_TEAMS_DISTRIBUTE:
2207 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
2208 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2209 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
2210 case EXEC_OMP_TEAMS_LOOP:
2211 case EXEC_OMP_WORKSHARE:
2212 res = gfc_trans_omp_directive (code);
2213 break;
2215 case EXEC_OACC_CACHE:
2216 case EXEC_OACC_WAIT:
2217 case EXEC_OACC_UPDATE:
2218 case EXEC_OACC_LOOP:
2219 case EXEC_OACC_HOST_DATA:
2220 case EXEC_OACC_DATA:
2221 case EXEC_OACC_KERNELS:
2222 case EXEC_OACC_KERNELS_LOOP:
2223 case EXEC_OACC_PARALLEL:
2224 case EXEC_OACC_PARALLEL_LOOP:
2225 case EXEC_OACC_SERIAL:
2226 case EXEC_OACC_SERIAL_LOOP:
2227 case EXEC_OACC_ENTER_DATA:
2228 case EXEC_OACC_EXIT_DATA:
2229 case EXEC_OACC_ATOMIC:
2230 case EXEC_OACC_DECLARE:
2231 res = gfc_trans_oacc_directive (code);
2232 break;
2234 default:
2235 gfc_internal_error ("gfc_trans_code(): Bad statement code");
2238 gfc_set_backend_locus (&code->loc);
2240 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
2242 if (TREE_CODE (res) != STATEMENT_LIST)
2243 SET_EXPR_LOCATION (res, input_location);
2245 /* Add the new statement to the block. */
2246 gfc_add_expr_to_block (&block, res);
2250 /* Return the finished block. */
2251 return gfc_finish_block (&block);
2255 /* Translate an executable statement with condition, cond. The condition is
2256 used by gfc_trans_do to test for IO result conditions inside implied
2257 DO loops of READ and WRITE statements. See build_dt in trans-io.c. */
2259 tree
2260 gfc_trans_code_cond (gfc_code * code, tree cond)
2262 return trans_code (code, cond);
2265 /* Translate an executable statement without condition. */
2267 tree
2268 gfc_trans_code (gfc_code * code)
2270 return trans_code (code, NULL_TREE);
2274 /* This function is called after a complete program unit has been parsed
2275 and resolved. */
2277 void
2278 gfc_generate_code (gfc_namespace * ns)
2280 ompws_flags = 0;
2281 if (ns->is_block_data)
2283 gfc_generate_block_data (ns);
2284 return;
2287 gfc_generate_function_code (ns);
2291 /* This function is called after a complete module has been parsed
2292 and resolved. */
2294 void
2295 gfc_generate_module_code (gfc_namespace * ns)
2297 gfc_namespace *n;
2298 struct module_htab_entry *entry;
2300 gcc_assert (ns->proc_name->backend_decl == NULL);
2301 ns->proc_name->backend_decl
2302 = build_decl (gfc_get_location (&ns->proc_name->declared_at),
2303 NAMESPACE_DECL, get_identifier (ns->proc_name->name),
2304 void_type_node);
2305 entry = gfc_find_module (ns->proc_name->name);
2306 if (entry->namespace_decl)
2307 /* Buggy sourcecode, using a module before defining it? */
2308 entry->decls->empty ();
2309 entry->namespace_decl = ns->proc_name->backend_decl;
2311 gfc_generate_module_vars (ns);
2313 /* We need to generate all module function prototypes first, to allow
2314 sibling calls. */
2315 for (n = ns->contained; n; n = n->sibling)
2317 gfc_entry_list *el;
2319 if (!n->proc_name)
2320 continue;
2322 gfc_create_function_decl (n, false);
2323 DECL_CONTEXT (n->proc_name->backend_decl) = ns->proc_name->backend_decl;
2324 gfc_module_add_decl (entry, n->proc_name->backend_decl);
2325 for (el = ns->entries; el; el = el->next)
2327 DECL_CONTEXT (el->sym->backend_decl) = ns->proc_name->backend_decl;
2328 gfc_module_add_decl (entry, el->sym->backend_decl);
2332 for (n = ns->contained; n; n = n->sibling)
2334 if (!n->proc_name)
2335 continue;
2337 gfc_generate_function_code (n);
2342 /* Initialize an init/cleanup block with existing code. */
2344 void
2345 gfc_start_wrapped_block (gfc_wrapped_block* block, tree code)
2347 gcc_assert (block);
2349 block->init = NULL_TREE;
2350 block->code = code;
2351 block->cleanup = NULL_TREE;
2355 /* Add a new pair of initializers/clean-up code. */
2357 void
2358 gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup)
2360 gcc_assert (block);
2362 /* The new pair of init/cleanup should be "wrapped around" the existing
2363 block of code, thus the initialization is added to the front and the
2364 cleanup to the back. */
2365 add_expr_to_chain (&block->init, init, true);
2366 add_expr_to_chain (&block->cleanup, cleanup, false);
2370 /* Finish up a wrapped block by building a corresponding try-finally expr. */
2372 tree
2373 gfc_finish_wrapped_block (gfc_wrapped_block* block)
2375 tree result;
2377 gcc_assert (block);
2379 /* Build the final expression. For this, just add init and body together,
2380 and put clean-up with that into a TRY_FINALLY_EXPR. */
2381 result = block->init;
2382 add_expr_to_chain (&result, block->code, false);
2383 if (block->cleanup)
2384 result = build2_loc (input_location, TRY_FINALLY_EXPR, void_type_node,
2385 result, block->cleanup);
2387 /* Clear the block. */
2388 block->init = NULL_TREE;
2389 block->code = NULL_TREE;
2390 block->cleanup = NULL_TREE;
2392 return result;
2396 /* Helper function for marking a boolean expression tree as unlikely. */
2398 tree
2399 gfc_unlikely (tree cond, enum br_predictor predictor)
2401 tree tmp;
2403 if (optimize)
2405 cond = fold_convert (long_integer_type_node, cond);
2406 tmp = build_zero_cst (long_integer_type_node);
2407 cond = build_call_expr_loc (input_location,
2408 builtin_decl_explicit (BUILT_IN_EXPECT),
2409 3, cond, tmp,
2410 build_int_cst (integer_type_node,
2411 predictor));
2413 return cond;
2417 /* Helper function for marking a boolean expression tree as likely. */
2419 tree
2420 gfc_likely (tree cond, enum br_predictor predictor)
2422 tree tmp;
2424 if (optimize)
2426 cond = fold_convert (long_integer_type_node, cond);
2427 tmp = build_one_cst (long_integer_type_node);
2428 cond = build_call_expr_loc (input_location,
2429 builtin_decl_explicit (BUILT_IN_EXPECT),
2430 3, cond, tmp,
2431 build_int_cst (integer_type_node,
2432 predictor));
2434 return cond;
2438 /* Get the string length for a deferred character length component. */
2440 bool
2441 gfc_deferred_strlen (gfc_component *c, tree *decl)
2443 char name[GFC_MAX_SYMBOL_LEN+9];
2444 gfc_component *strlen;
2445 if (!(c->ts.type == BT_CHARACTER
2446 && (c->ts.deferred || c->attr.pdt_string)))
2447 return false;
2448 sprintf (name, "_%s_length", c->name);
2449 for (strlen = c; strlen; strlen = strlen->next)
2450 if (strcmp (strlen->name, name) == 0)
2451 break;
2452 *decl = strlen ? strlen->backend_decl : NULL_TREE;
2453 return strlen != NULL;