2016-01-15 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / fortran / trans.c
blobe71430baeb88c93f3915255607a03ef7d3fda1cf
1 /* Code translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2016 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 /* Advance along TREE_CHAIN n times. */
53 tree
54 gfc_advance_chain (tree t, int n)
56 for (; n > 0; n--)
58 gcc_assert (t != NULL_TREE);
59 t = DECL_CHAIN (t);
61 return t;
65 /* Strip off a legitimate source ending from the input
66 string NAME of length LEN. */
68 static inline void
69 remove_suffix (char *name, int len)
71 int i;
73 for (i = 2; i < 8 && len > i; i++)
75 if (name[len - i] == '.')
77 name[len - i] = '\0';
78 break;
84 /* Creates a variable declaration with a given TYPE. */
86 tree
87 gfc_create_var_np (tree type, const char *prefix)
89 tree t;
91 t = create_tmp_var_raw (type, prefix);
93 /* No warnings for anonymous variables. */
94 if (prefix == NULL)
95 TREE_NO_WARNING (t) = 1;
97 return t;
101 /* Like above, but also adds it to the current scope. */
103 tree
104 gfc_create_var (tree type, const char *prefix)
106 tree tmp;
108 tmp = gfc_create_var_np (type, prefix);
110 pushdecl (tmp);
112 return tmp;
116 /* If the expression is not constant, evaluate it now. We assign the
117 result of the expression to an artificially created variable VAR, and
118 return a pointer to the VAR_DECL node for this variable. */
120 tree
121 gfc_evaluate_now_loc (location_t loc, tree expr, stmtblock_t * pblock)
123 tree var;
125 if (CONSTANT_CLASS_P (expr))
126 return expr;
128 var = gfc_create_var (TREE_TYPE (expr), NULL);
129 gfc_add_modify_loc (loc, pblock, var, expr);
131 return var;
135 tree
136 gfc_evaluate_now (tree expr, stmtblock_t * pblock)
138 return gfc_evaluate_now_loc (input_location, expr, pblock);
142 /* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
143 A MODIFY_EXPR is an assignment:
144 LHS <- RHS. */
146 void
147 gfc_add_modify_loc (location_t loc, stmtblock_t * pblock, tree lhs, tree rhs)
149 tree tmp;
151 tree t1, t2;
152 t1 = TREE_TYPE (rhs);
153 t2 = TREE_TYPE (lhs);
154 /* Make sure that the types of the rhs and the lhs are the same
155 for scalar assignments. We should probably have something
156 similar for aggregates, but right now removing that check just
157 breaks everything. */
158 gcc_checking_assert (t1 == t2
159 || AGGREGATE_TYPE_P (TREE_TYPE (lhs)));
161 tmp = fold_build2_loc (loc, MODIFY_EXPR, void_type_node, lhs,
162 rhs);
163 gfc_add_expr_to_block (pblock, tmp);
167 void
168 gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs)
170 gfc_add_modify_loc (input_location, pblock, lhs, rhs);
174 /* Create a new scope/binding level and initialize a block. Care must be
175 taken when translating expressions as any temporaries will be placed in
176 the innermost scope. */
178 void
179 gfc_start_block (stmtblock_t * block)
181 /* Start a new binding level. */
182 pushlevel ();
183 block->has_scope = 1;
185 /* The block is empty. */
186 block->head = NULL_TREE;
190 /* Initialize a block without creating a new scope. */
192 void
193 gfc_init_block (stmtblock_t * block)
195 block->head = NULL_TREE;
196 block->has_scope = 0;
200 /* Sometimes we create a scope but it turns out that we don't actually
201 need it. This function merges the scope of BLOCK with its parent.
202 Only variable decls will be merged, you still need to add the code. */
204 void
205 gfc_merge_block_scope (stmtblock_t * block)
207 tree decl;
208 tree next;
210 gcc_assert (block->has_scope);
211 block->has_scope = 0;
213 /* Remember the decls in this scope. */
214 decl = getdecls ();
215 poplevel (0, 0);
217 /* Add them to the parent scope. */
218 while (decl != NULL_TREE)
220 next = DECL_CHAIN (decl);
221 DECL_CHAIN (decl) = NULL_TREE;
223 pushdecl (decl);
224 decl = next;
229 /* Finish a scope containing a block of statements. */
231 tree
232 gfc_finish_block (stmtblock_t * stmtblock)
234 tree decl;
235 tree expr;
236 tree block;
238 expr = stmtblock->head;
239 if (!expr)
240 expr = build_empty_stmt (input_location);
242 stmtblock->head = NULL_TREE;
244 if (stmtblock->has_scope)
246 decl = getdecls ();
248 if (decl)
250 block = poplevel (1, 0);
251 expr = build3_v (BIND_EXPR, decl, expr, block);
253 else
254 poplevel (0, 0);
257 return expr;
261 /* Build an ADDR_EXPR and cast the result to TYPE. If TYPE is NULL, the
262 natural type is used. */
264 tree
265 gfc_build_addr_expr (tree type, tree t)
267 tree base_type = TREE_TYPE (t);
268 tree natural_type;
270 if (type && POINTER_TYPE_P (type)
271 && TREE_CODE (base_type) == ARRAY_TYPE
272 && TYPE_MAIN_VARIANT (TREE_TYPE (type))
273 == TYPE_MAIN_VARIANT (TREE_TYPE (base_type)))
275 tree min_val = size_zero_node;
276 tree type_domain = TYPE_DOMAIN (base_type);
277 if (type_domain && TYPE_MIN_VALUE (type_domain))
278 min_val = TYPE_MIN_VALUE (type_domain);
279 t = fold (build4_loc (input_location, ARRAY_REF, TREE_TYPE (type),
280 t, min_val, NULL_TREE, NULL_TREE));
281 natural_type = type;
283 else
284 natural_type = build_pointer_type (base_type);
286 if (TREE_CODE (t) == INDIRECT_REF)
288 if (!type)
289 type = natural_type;
290 t = TREE_OPERAND (t, 0);
291 natural_type = TREE_TYPE (t);
293 else
295 tree base = get_base_address (t);
296 if (base && DECL_P (base))
297 TREE_ADDRESSABLE (base) = 1;
298 t = fold_build1_loc (input_location, ADDR_EXPR, natural_type, t);
301 if (type && natural_type != type)
302 t = convert (type, t);
304 return t;
308 /* Build an ARRAY_REF with its natural type. */
310 tree
311 gfc_build_array_ref (tree base, tree offset, tree decl, tree vptr)
313 tree type = TREE_TYPE (base);
314 tree tmp;
315 tree span;
317 if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0)
319 gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0);
321 return fold_convert (TYPE_MAIN_VARIANT (type), base);
324 /* Scalar coarray, there is nothing to do. */
325 if (TREE_CODE (type) != ARRAY_TYPE)
327 gcc_assert (decl == NULL_TREE);
328 gcc_assert (integer_zerop (offset));
329 return base;
332 type = TREE_TYPE (type);
334 /* Use pointer arithmetic for deferred character length array
335 references. */
336 if (type && TREE_CODE (type) == ARRAY_TYPE
337 && TYPE_MAXVAL (TYPE_DOMAIN (type)) != NULL_TREE
338 && (TREE_CODE (TYPE_MAXVAL (TYPE_DOMAIN (type))) == VAR_DECL
339 || TREE_CODE (TYPE_MAXVAL (TYPE_DOMAIN (type))) == INDIRECT_REF)
340 && decl
341 && (TREE_CODE (TYPE_MAXVAL (TYPE_DOMAIN (type))) == INDIRECT_REF
342 || TREE_CODE (decl) == FUNCTION_DECL
343 || DECL_CONTEXT (TYPE_MAXVAL (TYPE_DOMAIN (type)))
344 == DECL_CONTEXT (decl)))
345 span = TYPE_MAXVAL (TYPE_DOMAIN (type));
346 else
347 span = NULL_TREE;
349 if (DECL_P (base))
350 TREE_ADDRESSABLE (base) = 1;
352 /* Strip NON_LVALUE_EXPR nodes. */
353 STRIP_TYPE_NOPS (offset);
355 /* If the array reference is to a pointer, whose target contains a
356 subreference, use the span that is stored with the backend decl
357 and reference the element with pointer arithmetic. */
358 if ((decl && (TREE_CODE (decl) == FIELD_DECL
359 || TREE_CODE (decl) == VAR_DECL
360 || TREE_CODE (decl) == PARM_DECL
361 || TREE_CODE (decl) == FUNCTION_DECL)
362 && ((GFC_DECL_SUBREF_ARRAY_P (decl)
363 && !integer_zerop (GFC_DECL_SPAN (decl)))
364 || GFC_DECL_CLASS (decl)
365 || span != NULL_TREE))
366 || vptr != NULL_TREE)
368 if (decl)
370 if (GFC_DECL_CLASS (decl))
372 /* When a temporary is in place for the class array, then the
373 original class' declaration is stored in the saved
374 descriptor. */
375 if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl))
376 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
377 else
379 /* Allow for dummy arguments and other good things. */
380 if (POINTER_TYPE_P (TREE_TYPE (decl)))
381 decl = build_fold_indirect_ref_loc (input_location, decl);
383 /* Check if '_data' is an array descriptor. If it is not,
384 the array must be one of the components of the class
385 object, so return a normal array reference. */
386 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (
387 gfc_class_data_get (decl))))
388 return build4_loc (input_location, ARRAY_REF, type, base,
389 offset, NULL_TREE, NULL_TREE);
392 span = gfc_class_vtab_size_get (decl);
394 else if (GFC_DECL_SUBREF_ARRAY_P (decl))
395 span = GFC_DECL_SPAN (decl);
396 else if (span)
397 span = fold_convert (gfc_array_index_type, span);
398 else
399 gcc_unreachable ();
401 else if (vptr)
402 span = gfc_vptr_size_get (vptr);
403 else
404 gcc_unreachable ();
406 offset = fold_build2_loc (input_location, MULT_EXPR,
407 gfc_array_index_type,
408 offset, span);
409 tmp = gfc_build_addr_expr (pvoid_type_node, base);
410 tmp = fold_build_pointer_plus_loc (input_location, tmp, offset);
411 tmp = fold_convert (build_pointer_type (type), tmp);
412 if (!TYPE_STRING_FLAG (type))
413 tmp = build_fold_indirect_ref_loc (input_location, tmp);
414 return tmp;
416 else
417 /* Otherwise use a straightforward array reference. */
418 return build4_loc (input_location, ARRAY_REF, type, base, offset,
419 NULL_TREE, NULL_TREE);
423 /* Generate a call to print a runtime error possibly including multiple
424 arguments and a locus. */
426 static tree
427 trans_runtime_error_vararg (bool error, locus* where, const char* msgid,
428 va_list ap)
430 stmtblock_t block;
431 tree tmp;
432 tree arg, arg2;
433 tree *argarray;
434 tree fntype;
435 char *message;
436 const char *p;
437 int line, nargs, i;
438 location_t loc;
440 /* Compute the number of extra arguments from the format string. */
441 for (p = msgid, nargs = 0; *p; p++)
442 if (*p == '%')
444 p++;
445 if (*p != '%')
446 nargs++;
449 /* The code to generate the error. */
450 gfc_start_block (&block);
452 if (where)
454 line = LOCATION_LINE (where->lb->location);
455 message = xasprintf ("At line %d of file %s", line,
456 where->lb->file->filename);
458 else
459 message = xasprintf ("In file '%s', around line %d",
460 gfc_source_file, LOCATION_LINE (input_location) + 1);
462 arg = gfc_build_addr_expr (pchar_type_node,
463 gfc_build_localized_cstring_const (message));
464 free (message);
466 message = xasprintf ("%s", _(msgid));
467 arg2 = gfc_build_addr_expr (pchar_type_node,
468 gfc_build_localized_cstring_const (message));
469 free (message);
471 /* Build the argument array. */
472 argarray = XALLOCAVEC (tree, nargs + 2);
473 argarray[0] = arg;
474 argarray[1] = arg2;
475 for (i = 0; i < nargs; i++)
476 argarray[2 + i] = va_arg (ap, tree);
478 /* Build the function call to runtime_(warning,error)_at; because of the
479 variable number of arguments, we can't use build_call_expr_loc dinput_location,
480 irectly. */
481 if (error)
482 fntype = TREE_TYPE (gfor_fndecl_runtime_error_at);
483 else
484 fntype = TREE_TYPE (gfor_fndecl_runtime_warning_at);
486 loc = where ? where->lb->location : input_location;
487 tmp = fold_build_call_array_loc (loc, TREE_TYPE (fntype),
488 fold_build1_loc (loc, ADDR_EXPR,
489 build_pointer_type (fntype),
490 error
491 ? gfor_fndecl_runtime_error_at
492 : gfor_fndecl_runtime_warning_at),
493 nargs + 2, argarray);
494 gfc_add_expr_to_block (&block, tmp);
496 return gfc_finish_block (&block);
500 tree
501 gfc_trans_runtime_error (bool error, locus* where, const char* msgid, ...)
503 va_list ap;
504 tree result;
506 va_start (ap, msgid);
507 result = trans_runtime_error_vararg (error, where, msgid, ap);
508 va_end (ap);
509 return result;
513 /* Generate a runtime error if COND is true. */
515 void
516 gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
517 locus * where, const char * msgid, ...)
519 va_list ap;
520 stmtblock_t block;
521 tree body;
522 tree tmp;
523 tree tmpvar = NULL;
525 if (integer_zerop (cond))
526 return;
528 if (once)
530 tmpvar = gfc_create_var (boolean_type_node, "print_warning");
531 TREE_STATIC (tmpvar) = 1;
532 DECL_INITIAL (tmpvar) = boolean_true_node;
533 gfc_add_expr_to_block (pblock, tmpvar);
536 gfc_start_block (&block);
538 /* For error, runtime_error_at already implies PRED_NORETURN. */
539 if (!error && once)
540 gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_WARN_ONCE,
541 NOT_TAKEN));
543 /* The code to generate the error. */
544 va_start (ap, msgid);
545 gfc_add_expr_to_block (&block,
546 trans_runtime_error_vararg (error, where,
547 msgid, ap));
548 va_end (ap);
550 if (once)
551 gfc_add_modify (&block, tmpvar, boolean_false_node);
553 body = gfc_finish_block (&block);
555 if (integer_onep (cond))
557 gfc_add_expr_to_block (pblock, body);
559 else
561 if (once)
562 cond = fold_build2_loc (where->lb->location, TRUTH_AND_EXPR,
563 long_integer_type_node, tmpvar, cond);
564 else
565 cond = fold_convert (long_integer_type_node, cond);
567 tmp = fold_build3_loc (where->lb->location, COND_EXPR, void_type_node,
568 cond, body,
569 build_empty_stmt (where->lb->location));
570 gfc_add_expr_to_block (pblock, tmp);
575 /* Call malloc to allocate size bytes of memory, with special conditions:
576 + if size == 0, return a malloced area of size 1,
577 + if malloc returns NULL, issue a runtime error. */
578 tree
579 gfc_call_malloc (stmtblock_t * block, tree type, tree size)
581 tree tmp, msg, malloc_result, null_result, res, malloc_tree;
582 stmtblock_t block2;
584 /* Create a variable to hold the result. */
585 res = gfc_create_var (prvoid_type_node, NULL);
587 /* Call malloc. */
588 gfc_start_block (&block2);
590 size = fold_convert (size_type_node, size);
591 size = fold_build2_loc (input_location, MAX_EXPR, size_type_node, size,
592 build_int_cst (size_type_node, 1));
594 malloc_tree = builtin_decl_explicit (BUILT_IN_MALLOC);
595 gfc_add_modify (&block2, res,
596 fold_convert (prvoid_type_node,
597 build_call_expr_loc (input_location,
598 malloc_tree, 1, size)));
600 /* Optionally check whether malloc was successful. */
601 if (gfc_option.rtcheck & GFC_RTCHECK_MEM)
603 null_result = fold_build2_loc (input_location, EQ_EXPR,
604 boolean_type_node, res,
605 build_int_cst (pvoid_type_node, 0));
606 msg = gfc_build_addr_expr (pchar_type_node,
607 gfc_build_localized_cstring_const ("Memory allocation failed"));
608 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
609 null_result,
610 build_call_expr_loc (input_location,
611 gfor_fndecl_os_error, 1, msg),
612 build_empty_stmt (input_location));
613 gfc_add_expr_to_block (&block2, tmp);
616 malloc_result = gfc_finish_block (&block2);
617 gfc_add_expr_to_block (block, malloc_result);
619 if (type != NULL)
620 res = fold_convert (type, res);
621 return res;
625 /* Allocate memory, using an optional status argument.
627 This function follows the following pseudo-code:
629 void *
630 allocate (size_t size, integer_type stat)
632 void *newmem;
634 if (stat requested)
635 stat = 0;
637 newmem = malloc (MAX (size, 1));
638 if (newmem == NULL)
640 if (stat)
641 *stat = LIBERROR_ALLOCATION;
642 else
643 runtime_error ("Allocation would exceed memory limit");
645 return newmem;
646 } */
647 void
648 gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
649 tree size, tree status)
651 tree tmp, error_cond;
652 stmtblock_t on_error;
653 tree status_type = status ? TREE_TYPE (status) : NULL_TREE;
655 /* If successful and stat= is given, set status to 0. */
656 if (status != NULL_TREE)
657 gfc_add_expr_to_block (block,
658 fold_build2_loc (input_location, MODIFY_EXPR, status_type,
659 status, build_int_cst (status_type, 0)));
661 /* The allocation itself. */
662 size = fold_convert (size_type_node, size);
663 gfc_add_modify (block, pointer,
664 fold_convert (TREE_TYPE (pointer),
665 build_call_expr_loc (input_location,
666 builtin_decl_explicit (BUILT_IN_MALLOC), 1,
667 fold_build2_loc (input_location,
668 MAX_EXPR, size_type_node, size,
669 build_int_cst (size_type_node, 1)))));
671 /* What to do in case of error. */
672 gfc_start_block (&on_error);
673 if (status != NULL_TREE)
675 gfc_add_expr_to_block (&on_error,
676 build_predict_expr (PRED_FORTRAN_FAIL_ALLOC,
677 NOT_TAKEN));
678 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type, status,
679 build_int_cst (status_type, LIBERROR_ALLOCATION));
680 gfc_add_expr_to_block (&on_error, tmp);
682 else
684 /* Here, os_error already implies PRED_NORETURN. */
685 tmp = build_call_expr_loc (input_location, gfor_fndecl_os_error, 1,
686 gfc_build_addr_expr (pchar_type_node,
687 gfc_build_localized_cstring_const
688 ("Allocation would exceed memory limit")));
689 gfc_add_expr_to_block (&on_error, tmp);
692 error_cond = fold_build2_loc (input_location, EQ_EXPR,
693 boolean_type_node, pointer,
694 build_int_cst (prvoid_type_node, 0));
695 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
696 error_cond, gfc_finish_block (&on_error),
697 build_empty_stmt (input_location));
699 gfc_add_expr_to_block (block, tmp);
703 /* Allocate memory, using an optional status argument.
705 This function follows the following pseudo-code:
707 void *
708 allocate (size_t size, void** token, int *stat, char* errmsg, int errlen)
710 void *newmem;
712 newmem = _caf_register (size, regtype, token, &stat, errmsg, errlen);
713 return newmem;
714 } */
715 static void
716 gfc_allocate_using_lib (stmtblock_t * block, tree pointer, tree size,
717 tree token, tree status, tree errmsg, tree errlen,
718 bool lock_var, bool event_var)
720 tree tmp, pstat;
722 gcc_assert (token != NULL_TREE);
724 /* The allocation itself. */
725 if (status == NULL_TREE)
726 pstat = null_pointer_node;
727 else
728 pstat = gfc_build_addr_expr (NULL_TREE, status);
730 if (errmsg == NULL_TREE)
732 gcc_assert(errlen == NULL_TREE);
733 errmsg = null_pointer_node;
734 errlen = build_int_cst (integer_type_node, 0);
737 size = fold_convert (size_type_node, size);
738 tmp = build_call_expr_loc (input_location,
739 gfor_fndecl_caf_register, 6,
740 fold_build2_loc (input_location,
741 MAX_EXPR, size_type_node, size,
742 build_int_cst (size_type_node, 1)),
743 build_int_cst (integer_type_node,
744 lock_var ? GFC_CAF_LOCK_ALLOC
745 : event_var ? GFC_CAF_EVENT_ALLOC
746 : GFC_CAF_COARRAY_ALLOC),
747 token, pstat, errmsg, errlen);
749 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
750 TREE_TYPE (pointer), pointer,
751 fold_convert ( TREE_TYPE (pointer), tmp));
752 gfc_add_expr_to_block (block, tmp);
754 /* It guarantees memory consistency within the same segment */
755 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
756 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
757 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
758 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
759 ASM_VOLATILE_P (tmp) = 1;
760 gfc_add_expr_to_block (block, tmp);
764 /* Generate code for an ALLOCATE statement when the argument is an
765 allocatable variable. If the variable is currently allocated, it is an
766 error to allocate it again.
768 This function follows the following pseudo-code:
770 void *
771 allocate_allocatable (void *mem, size_t size, integer_type stat)
773 if (mem == NULL)
774 return allocate (size, stat);
775 else
777 if (stat)
778 stat = LIBERROR_ALLOCATION;
779 else
780 runtime_error ("Attempting to allocate already allocated variable");
784 expr must be set to the original expression being allocated for its locus
785 and variable name in case a runtime error has to be printed. */
786 void
787 gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size, tree token,
788 tree status, tree errmsg, tree errlen, tree label_finish,
789 gfc_expr* expr)
791 stmtblock_t alloc_block;
792 tree tmp, null_mem, alloc, error;
793 tree type = TREE_TYPE (mem);
795 size = fold_convert (size_type_node, size);
796 null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
797 boolean_type_node, mem,
798 build_int_cst (type, 0)),
799 PRED_FORTRAN_FAIL_ALLOC);
801 /* If mem is NULL, we call gfc_allocate_using_malloc or
802 gfc_allocate_using_lib. */
803 gfc_start_block (&alloc_block);
805 if (flag_coarray == GFC_FCOARRAY_LIB
806 && gfc_expr_attr (expr).codimension)
808 tree cond;
809 bool lock_var = expr->ts.type == BT_DERIVED
810 && expr->ts.u.derived->from_intmod
811 == INTMOD_ISO_FORTRAN_ENV
812 && expr->ts.u.derived->intmod_sym_id
813 == ISOFORTRAN_LOCK_TYPE;
814 bool event_var = expr->ts.type == BT_DERIVED
815 && expr->ts.u.derived->from_intmod
816 == INTMOD_ISO_FORTRAN_ENV
817 && expr->ts.u.derived->intmod_sym_id
818 == ISOFORTRAN_EVENT_TYPE;
819 /* In the front end, we represent the lock variable as pointer. However,
820 the FE only passes the pointer around and leaves the actual
821 representation to the library. Hence, we have to convert back to the
822 number of elements. */
823 if (lock_var)
824 size = fold_build2_loc (input_location, TRUNC_DIV_EXPR, size_type_node,
825 size, TYPE_SIZE_UNIT (ptr_type_node));
827 gfc_allocate_using_lib (&alloc_block, mem, size, token, status,
828 errmsg, errlen, lock_var, event_var);
830 if (status != NULL_TREE)
832 TREE_USED (label_finish) = 1;
833 tmp = build1_v (GOTO_EXPR, label_finish);
834 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
835 status, build_zero_cst (TREE_TYPE (status)));
836 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
837 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
838 tmp, build_empty_stmt (input_location));
839 gfc_add_expr_to_block (&alloc_block, tmp);
842 else
843 gfc_allocate_using_malloc (&alloc_block, mem, size, status);
845 alloc = gfc_finish_block (&alloc_block);
847 /* If mem is not NULL, we issue a runtime error or set the
848 status variable. */
849 if (expr)
851 tree varname;
853 gcc_assert (expr->expr_type == EXPR_VARIABLE && expr->symtree);
854 varname = gfc_build_cstring_const (expr->symtree->name);
855 varname = gfc_build_addr_expr (pchar_type_node, varname);
857 error = gfc_trans_runtime_error (true, &expr->where,
858 "Attempting to allocate already"
859 " allocated variable '%s'",
860 varname);
862 else
863 error = gfc_trans_runtime_error (true, NULL,
864 "Attempting to allocate already allocated"
865 " variable");
867 if (status != NULL_TREE)
869 tree status_type = TREE_TYPE (status);
871 error = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
872 status, build_int_cst (status_type, LIBERROR_ALLOCATION));
875 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem,
876 error, alloc);
877 gfc_add_expr_to_block (block, tmp);
881 /* Free a given variable. */
883 tree
884 gfc_call_free (tree var)
886 return build_call_expr_loc (input_location,
887 builtin_decl_explicit (BUILT_IN_FREE),
888 1, fold_convert (pvoid_type_node, var));
892 /* Build a call to a FINAL procedure, which finalizes "var". */
894 static tree
895 gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var,
896 bool fini_coarray, gfc_expr *class_size)
898 stmtblock_t block;
899 gfc_se se;
900 tree final_fndecl, array, size, tmp;
901 symbol_attribute attr;
903 gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE);
904 gcc_assert (var);
906 gfc_start_block (&block);
907 gfc_init_se (&se, NULL);
908 gfc_conv_expr (&se, final_wrapper);
909 final_fndecl = se.expr;
910 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
911 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
913 if (ts.type == BT_DERIVED)
915 tree elem_size;
917 gcc_assert (!class_size);
918 elem_size = gfc_typenode_for_spec (&ts);
919 elem_size = TYPE_SIZE_UNIT (elem_size);
920 size = fold_convert (gfc_array_index_type, elem_size);
922 gfc_init_se (&se, NULL);
923 se.want_pointer = 1;
924 if (var->rank)
926 se.descriptor_only = 1;
927 gfc_conv_expr_descriptor (&se, var);
928 array = se.expr;
930 else
932 gfc_conv_expr (&se, var);
933 gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
934 array = se.expr;
936 /* No copy back needed, hence set attr's allocatable/pointer
937 to zero. */
938 gfc_clear_attr (&attr);
939 gfc_init_se (&se, NULL);
940 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
941 gcc_assert (se.post.head == NULL_TREE);
944 else
946 gfc_expr *array_expr;
947 gcc_assert (class_size);
948 gfc_init_se (&se, NULL);
949 gfc_conv_expr (&se, class_size);
950 gfc_add_block_to_block (&block, &se.pre);
951 gcc_assert (se.post.head == NULL_TREE);
952 size = se.expr;
954 array_expr = gfc_copy_expr (var);
955 gfc_init_se (&se, NULL);
956 se.want_pointer = 1;
957 if (array_expr->rank)
959 gfc_add_class_array_ref (array_expr);
960 se.descriptor_only = 1;
961 gfc_conv_expr_descriptor (&se, array_expr);
962 array = se.expr;
964 else
966 gfc_add_data_component (array_expr);
967 gfc_conv_expr (&se, array_expr);
968 gfc_add_block_to_block (&block, &se.pre);
969 gcc_assert (se.post.head == NULL_TREE);
970 array = se.expr;
971 if (TREE_CODE (array) == ADDR_EXPR
972 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (array, 0))))
973 tmp = TREE_OPERAND (array, 0);
975 if (!gfc_is_coarray (array_expr))
977 /* No copy back needed, hence set attr's allocatable/pointer
978 to zero. */
979 gfc_clear_attr (&attr);
980 gfc_init_se (&se, NULL);
981 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
983 gcc_assert (se.post.head == NULL_TREE);
985 gfc_free_expr (array_expr);
988 if (!POINTER_TYPE_P (TREE_TYPE (array)))
989 array = gfc_build_addr_expr (NULL, array);
991 gfc_add_block_to_block (&block, &se.pre);
992 tmp = build_call_expr_loc (input_location,
993 final_fndecl, 3, array,
994 size, fini_coarray ? boolean_true_node
995 : boolean_false_node);
996 gfc_add_block_to_block (&block, &se.post);
997 gfc_add_expr_to_block (&block, tmp);
998 return gfc_finish_block (&block);
1002 bool
1003 gfc_add_comp_finalizer_call (stmtblock_t *block, tree decl, gfc_component *comp,
1004 bool fini_coarray)
1006 gfc_se se;
1007 stmtblock_t block2;
1008 tree final_fndecl, size, array, tmp, cond;
1009 symbol_attribute attr;
1010 gfc_expr *final_expr = NULL;
1012 if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS)
1013 return false;
1015 gfc_init_block (&block2);
1017 if (comp->ts.type == BT_DERIVED)
1019 if (comp->attr.pointer)
1020 return false;
1022 gfc_is_finalizable (comp->ts.u.derived, &final_expr);
1023 if (!final_expr)
1024 return false;
1026 gfc_init_se (&se, NULL);
1027 gfc_conv_expr (&se, final_expr);
1028 final_fndecl = se.expr;
1029 size = gfc_typenode_for_spec (&comp->ts);
1030 size = TYPE_SIZE_UNIT (size);
1031 size = fold_convert (gfc_array_index_type, size);
1033 array = decl;
1035 else /* comp->ts.type == BT_CLASS. */
1037 if (CLASS_DATA (comp)->attr.class_pointer)
1038 return false;
1040 gfc_is_finalizable (CLASS_DATA (comp)->ts.u.derived, &final_expr);
1041 final_fndecl = gfc_class_vtab_final_get (decl);
1042 size = gfc_class_vtab_size_get (decl);
1043 array = gfc_class_data_get (decl);
1046 if (comp->attr.allocatable
1047 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)->attr.allocatable))
1049 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))
1050 ? gfc_conv_descriptor_data_get (array) : array;
1051 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1052 tmp, fold_convert (TREE_TYPE (tmp),
1053 null_pointer_node));
1055 else
1056 cond = boolean_true_node;
1058 if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array)))
1060 gfc_clear_attr (&attr);
1061 gfc_init_se (&se, NULL);
1062 array = gfc_conv_scalar_to_descriptor (&se, array, attr);
1063 gfc_add_block_to_block (&block2, &se.pre);
1064 gcc_assert (se.post.head == NULL_TREE);
1067 if (!POINTER_TYPE_P (TREE_TYPE (array)))
1068 array = gfc_build_addr_expr (NULL, array);
1070 if (!final_expr)
1072 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1073 final_fndecl,
1074 fold_convert (TREE_TYPE (final_fndecl),
1075 null_pointer_node));
1076 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1077 boolean_type_node, cond, tmp);
1080 if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
1081 final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
1083 tmp = build_call_expr_loc (input_location,
1084 final_fndecl, 3, array,
1085 size, fini_coarray ? boolean_true_node
1086 : boolean_false_node);
1087 gfc_add_expr_to_block (&block2, tmp);
1088 tmp = gfc_finish_block (&block2);
1090 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
1091 build_empty_stmt (input_location));
1092 gfc_add_expr_to_block (block, tmp);
1094 return true;
1098 /* Add a call to the finalizer, using the passed *expr. Returns
1099 true when a finalizer call has been inserted. */
1101 bool
1102 gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2)
1104 tree tmp;
1105 gfc_ref *ref;
1106 gfc_expr *expr;
1107 gfc_expr *final_expr = NULL;
1108 gfc_expr *elem_size = NULL;
1109 bool has_finalizer = false;
1111 if (!expr2 || (expr2->ts.type != BT_DERIVED && expr2->ts.type != BT_CLASS))
1112 return false;
1114 if (expr2->ts.type == BT_DERIVED)
1116 gfc_is_finalizable (expr2->ts.u.derived, &final_expr);
1117 if (!final_expr)
1118 return false;
1121 /* If we have a class array, we need go back to the class
1122 container. */
1123 expr = gfc_copy_expr (expr2);
1125 if (expr->ref && expr->ref->next && !expr->ref->next->next
1126 && expr->ref->next->type == REF_ARRAY
1127 && expr->ref->type == REF_COMPONENT
1128 && strcmp (expr->ref->u.c.component->name, "_data") == 0)
1130 gfc_free_ref_list (expr->ref);
1131 expr->ref = NULL;
1133 else
1134 for (ref = expr->ref; ref; ref = ref->next)
1135 if (ref->next && ref->next->next && !ref->next->next->next
1136 && ref->next->next->type == REF_ARRAY
1137 && ref->next->type == REF_COMPONENT
1138 && strcmp (ref->next->u.c.component->name, "_data") == 0)
1140 gfc_free_ref_list (ref->next);
1141 ref->next = NULL;
1144 if (expr->ts.type == BT_CLASS)
1146 has_finalizer = gfc_is_finalizable (expr->ts.u.derived, NULL);
1148 if (!expr2->rank && !expr2->ref && CLASS_DATA (expr2->symtree->n.sym)->as)
1149 expr->rank = CLASS_DATA (expr2->symtree->n.sym)->as->rank;
1151 final_expr = gfc_copy_expr (expr);
1152 gfc_add_vptr_component (final_expr);
1153 gfc_add_component_ref (final_expr, "_final");
1155 elem_size = gfc_copy_expr (expr);
1156 gfc_add_vptr_component (elem_size);
1157 gfc_add_component_ref (elem_size, "_size");
1160 gcc_assert (final_expr->expr_type == EXPR_VARIABLE);
1162 tmp = gfc_build_final_call (expr->ts, final_expr, expr,
1163 false, elem_size);
1165 if (expr->ts.type == BT_CLASS && !has_finalizer)
1167 tree cond;
1168 gfc_se se;
1170 gfc_init_se (&se, NULL);
1171 se.want_pointer = 1;
1172 gfc_conv_expr (&se, final_expr);
1173 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1174 se.expr, build_int_cst (TREE_TYPE (se.expr), 0));
1176 /* For CLASS(*) not only sym->_vtab->_final can be NULL
1177 but already sym->_vtab itself. */
1178 if (UNLIMITED_POLY (expr))
1180 tree cond2;
1181 gfc_expr *vptr_expr;
1183 vptr_expr = gfc_copy_expr (expr);
1184 gfc_add_vptr_component (vptr_expr);
1186 gfc_init_se (&se, NULL);
1187 se.want_pointer = 1;
1188 gfc_conv_expr (&se, vptr_expr);
1189 gfc_free_expr (vptr_expr);
1191 cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1192 se.expr,
1193 build_int_cst (TREE_TYPE (se.expr), 0));
1194 cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
1195 boolean_type_node, cond2, cond);
1198 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1199 cond, tmp, build_empty_stmt (input_location));
1202 gfc_add_expr_to_block (block, tmp);
1204 return true;
1208 /* User-deallocate; we emit the code directly from the front-end, and the
1209 logic is the same as the previous library function:
1211 void
1212 deallocate (void *pointer, GFC_INTEGER_4 * stat)
1214 if (!pointer)
1216 if (stat)
1217 *stat = 1;
1218 else
1219 runtime_error ("Attempt to DEALLOCATE unallocated memory.");
1221 else
1223 free (pointer);
1224 if (stat)
1225 *stat = 0;
1229 In this front-end version, status doesn't have to be GFC_INTEGER_4.
1230 Moreover, if CAN_FAIL is true, then we will not emit a runtime error,
1231 even when no status variable is passed to us (this is used for
1232 unconditional deallocation generated by the front-end at end of
1233 each procedure).
1235 If a runtime-message is possible, `expr' must point to the original
1236 expression being deallocated for its locus and variable name.
1238 For coarrays, "pointer" must be the array descriptor and not its
1239 "data" component. */
1240 tree
1241 gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
1242 tree errlen, tree label_finish,
1243 bool can_fail, gfc_expr* expr, bool coarray)
1245 stmtblock_t null, non_null;
1246 tree cond, tmp, error;
1247 tree status_type = NULL_TREE;
1248 tree caf_decl = NULL_TREE;
1250 if (coarray)
1252 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (pointer)));
1253 caf_decl = pointer;
1254 pointer = gfc_conv_descriptor_data_get (caf_decl);
1255 STRIP_NOPS (pointer);
1258 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, pointer,
1259 build_int_cst (TREE_TYPE (pointer), 0));
1261 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1262 we emit a runtime error. */
1263 gfc_start_block (&null);
1264 if (!can_fail)
1266 tree varname;
1268 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1270 varname = gfc_build_cstring_const (expr->symtree->name);
1271 varname = gfc_build_addr_expr (pchar_type_node, varname);
1273 error = gfc_trans_runtime_error (true, &expr->where,
1274 "Attempt to DEALLOCATE unallocated '%s'",
1275 varname);
1277 else
1278 error = build_empty_stmt (input_location);
1280 if (status != NULL_TREE && !integer_zerop (status))
1282 tree cond2;
1284 status_type = TREE_TYPE (TREE_TYPE (status));
1285 cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1286 status, build_int_cst (TREE_TYPE (status), 0));
1287 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1288 fold_build1_loc (input_location, INDIRECT_REF,
1289 status_type, status),
1290 build_int_cst (status_type, 1));
1291 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1292 cond2, tmp, error);
1295 gfc_add_expr_to_block (&null, error);
1297 /* When POINTER is not NULL, we free it. */
1298 gfc_start_block (&non_null);
1299 gfc_add_finalizer_call (&non_null, expr);
1300 if (!coarray || flag_coarray != GFC_FCOARRAY_LIB)
1302 tmp = build_call_expr_loc (input_location,
1303 builtin_decl_explicit (BUILT_IN_FREE), 1,
1304 fold_convert (pvoid_type_node, pointer));
1305 gfc_add_expr_to_block (&non_null, tmp);
1307 if (status != NULL_TREE && !integer_zerop (status))
1309 /* We set STATUS to zero if it is present. */
1310 tree status_type = TREE_TYPE (TREE_TYPE (status));
1311 tree cond2;
1313 cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1314 status,
1315 build_int_cst (TREE_TYPE (status), 0));
1316 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1317 fold_build1_loc (input_location, INDIRECT_REF,
1318 status_type, status),
1319 build_int_cst (status_type, 0));
1320 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1321 gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC),
1322 tmp, build_empty_stmt (input_location));
1323 gfc_add_expr_to_block (&non_null, tmp);
1326 else
1328 tree caf_type, token, cond2;
1329 tree pstat = null_pointer_node;
1331 if (errmsg == NULL_TREE)
1333 gcc_assert (errlen == NULL_TREE);
1334 errmsg = null_pointer_node;
1335 errlen = build_zero_cst (integer_type_node);
1337 else
1339 gcc_assert (errlen != NULL_TREE);
1340 if (!POINTER_TYPE_P (TREE_TYPE (errmsg)))
1341 errmsg = gfc_build_addr_expr (NULL_TREE, errmsg);
1344 caf_type = TREE_TYPE (caf_decl);
1346 if (status != NULL_TREE && !integer_zerop (status))
1348 gcc_assert (status_type == integer_type_node);
1349 pstat = status;
1352 if (GFC_DESCRIPTOR_TYPE_P (caf_type)
1353 && GFC_TYPE_ARRAY_AKIND (caf_type) == GFC_ARRAY_ALLOCATABLE)
1354 token = gfc_conv_descriptor_token (caf_decl);
1355 else if (DECL_LANG_SPECIFIC (caf_decl)
1356 && GFC_DECL_TOKEN (caf_decl) != NULL_TREE)
1357 token = GFC_DECL_TOKEN (caf_decl);
1358 else
1360 gcc_assert (GFC_ARRAY_TYPE_P (caf_type)
1361 && GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) != NULL_TREE);
1362 token = GFC_TYPE_ARRAY_CAF_TOKEN (caf_type);
1365 token = gfc_build_addr_expr (NULL_TREE, token);
1366 tmp = build_call_expr_loc (input_location,
1367 gfor_fndecl_caf_deregister, 4,
1368 token, pstat, errmsg, errlen);
1369 gfc_add_expr_to_block (&non_null, tmp);
1371 /* It guarantees memory consistency within the same segment */
1372 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1373 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1374 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1375 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1376 ASM_VOLATILE_P (tmp) = 1;
1377 gfc_add_expr_to_block (&non_null, tmp);
1379 if (status != NULL_TREE)
1381 tree stat = build_fold_indirect_ref_loc (input_location, status);
1383 TREE_USED (label_finish) = 1;
1384 tmp = build1_v (GOTO_EXPR, label_finish);
1385 cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1386 stat, build_zero_cst (TREE_TYPE (stat)));
1387 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1388 gfc_unlikely (cond2, PRED_FORTRAN_FAIL_ALLOC),
1389 tmp, build_empty_stmt (input_location));
1390 gfc_add_expr_to_block (&non_null, tmp);
1394 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
1395 gfc_finish_block (&null),
1396 gfc_finish_block (&non_null));
1400 /* Generate code for deallocation of allocatable scalars (variables or
1401 components). Before the object itself is freed, any allocatable
1402 subcomponents are being deallocated. */
1404 tree
1405 gfc_deallocate_scalar_with_status (tree pointer, tree status, bool can_fail,
1406 gfc_expr* expr, gfc_typespec ts)
1408 stmtblock_t null, non_null;
1409 tree cond, tmp, error;
1410 bool finalizable;
1412 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, pointer,
1413 build_int_cst (TREE_TYPE (pointer), 0));
1415 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
1416 we emit a runtime error. */
1417 gfc_start_block (&null);
1418 if (!can_fail)
1420 tree varname;
1422 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
1424 varname = gfc_build_cstring_const (expr->symtree->name);
1425 varname = gfc_build_addr_expr (pchar_type_node, varname);
1427 error = gfc_trans_runtime_error (true, &expr->where,
1428 "Attempt to DEALLOCATE unallocated '%s'",
1429 varname);
1431 else
1432 error = build_empty_stmt (input_location);
1434 if (status != NULL_TREE && !integer_zerop (status))
1436 tree status_type = TREE_TYPE (TREE_TYPE (status));
1437 tree cond2;
1439 cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1440 status, build_int_cst (TREE_TYPE (status), 0));
1441 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1442 fold_build1_loc (input_location, INDIRECT_REF,
1443 status_type, status),
1444 build_int_cst (status_type, 1));
1445 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1446 cond2, tmp, error);
1449 gfc_add_expr_to_block (&null, error);
1451 /* When POINTER is not NULL, we free it. */
1452 gfc_start_block (&non_null);
1454 /* Free allocatable components. */
1455 finalizable = gfc_add_finalizer_call (&non_null, expr);
1456 if (!finalizable && ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
1458 tmp = build_fold_indirect_ref_loc (input_location, pointer);
1459 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
1460 gfc_add_expr_to_block (&non_null, tmp);
1463 tmp = build_call_expr_loc (input_location,
1464 builtin_decl_explicit (BUILT_IN_FREE), 1,
1465 fold_convert (pvoid_type_node, pointer));
1466 gfc_add_expr_to_block (&non_null, tmp);
1468 if (status != NULL_TREE && !integer_zerop (status))
1470 /* We set STATUS to zero if it is present. */
1471 tree status_type = TREE_TYPE (TREE_TYPE (status));
1472 tree cond2;
1474 cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1475 status, build_int_cst (TREE_TYPE (status), 0));
1476 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1477 fold_build1_loc (input_location, INDIRECT_REF,
1478 status_type, status),
1479 build_int_cst (status_type, 0));
1480 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
1481 tmp, build_empty_stmt (input_location));
1482 gfc_add_expr_to_block (&non_null, tmp);
1485 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
1486 gfc_finish_block (&null),
1487 gfc_finish_block (&non_null));
1491 /* Reallocate MEM so it has SIZE bytes of data. This behaves like the
1492 following pseudo-code:
1494 void *
1495 internal_realloc (void *mem, size_t size)
1497 res = realloc (mem, size);
1498 if (!res && size != 0)
1499 _gfortran_os_error ("Allocation would exceed memory limit");
1501 return res;
1502 } */
1503 tree
1504 gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
1506 tree msg, res, nonzero, null_result, tmp;
1507 tree type = TREE_TYPE (mem);
1509 /* Only evaluate the size once. */
1510 size = save_expr (fold_convert (size_type_node, size));
1512 /* Create a variable to hold the result. */
1513 res = gfc_create_var (type, NULL);
1515 /* Call realloc and check the result. */
1516 tmp = build_call_expr_loc (input_location,
1517 builtin_decl_explicit (BUILT_IN_REALLOC), 2,
1518 fold_convert (pvoid_type_node, mem), size);
1519 gfc_add_modify (block, res, fold_convert (type, tmp));
1520 null_result = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1521 res, build_int_cst (pvoid_type_node, 0));
1522 nonzero = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, size,
1523 build_int_cst (size_type_node, 0));
1524 null_result = fold_build2_loc (input_location, TRUTH_AND_EXPR, boolean_type_node,
1525 null_result, nonzero);
1526 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const
1527 ("Allocation would exceed memory limit"));
1528 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1529 null_result,
1530 build_call_expr_loc (input_location,
1531 gfor_fndecl_os_error, 1, msg),
1532 build_empty_stmt (input_location));
1533 gfc_add_expr_to_block (block, tmp);
1535 return res;
1539 /* Add an expression to another one, either at the front or the back. */
1541 static void
1542 add_expr_to_chain (tree* chain, tree expr, bool front)
1544 if (expr == NULL_TREE || IS_EMPTY_STMT (expr))
1545 return;
1547 if (*chain)
1549 if (TREE_CODE (*chain) != STATEMENT_LIST)
1551 tree tmp;
1553 tmp = *chain;
1554 *chain = NULL_TREE;
1555 append_to_statement_list (tmp, chain);
1558 if (front)
1560 tree_stmt_iterator i;
1562 i = tsi_start (*chain);
1563 tsi_link_before (&i, expr, TSI_CONTINUE_LINKING);
1565 else
1566 append_to_statement_list (expr, chain);
1568 else
1569 *chain = expr;
1573 /* Add a statement at the end of a block. */
1575 void
1576 gfc_add_expr_to_block (stmtblock_t * block, tree expr)
1578 gcc_assert (block);
1579 add_expr_to_chain (&block->head, expr, false);
1583 /* Add a statement at the beginning of a block. */
1585 void
1586 gfc_prepend_expr_to_block (stmtblock_t * block, tree expr)
1588 gcc_assert (block);
1589 add_expr_to_chain (&block->head, expr, true);
1593 /* Add a block the end of a block. */
1595 void
1596 gfc_add_block_to_block (stmtblock_t * block, stmtblock_t * append)
1598 gcc_assert (append);
1599 gcc_assert (!append->has_scope);
1601 gfc_add_expr_to_block (block, append->head);
1602 append->head = NULL_TREE;
1606 /* Save the current locus. The structure may not be complete, and should
1607 only be used with gfc_restore_backend_locus. */
1609 void
1610 gfc_save_backend_locus (locus * loc)
1612 loc->lb = XCNEW (gfc_linebuf);
1613 loc->lb->location = input_location;
1614 loc->lb->file = gfc_current_backend_file;
1618 /* Set the current locus. */
1620 void
1621 gfc_set_backend_locus (locus * loc)
1623 gfc_current_backend_file = loc->lb->file;
1624 input_location = loc->lb->location;
1628 /* Restore the saved locus. Only used in conjunction with
1629 gfc_save_backend_locus, to free the memory when we are done. */
1631 void
1632 gfc_restore_backend_locus (locus * loc)
1634 gfc_set_backend_locus (loc);
1635 free (loc->lb);
1639 /* Translate an executable statement. The tree cond is used by gfc_trans_do.
1640 This static function is wrapped by gfc_trans_code_cond and
1641 gfc_trans_code. */
1643 static tree
1644 trans_code (gfc_code * code, tree cond)
1646 stmtblock_t block;
1647 tree res;
1649 if (!code)
1650 return build_empty_stmt (input_location);
1652 gfc_start_block (&block);
1654 /* Translate statements one by one into GENERIC trees until we reach
1655 the end of this gfc_code branch. */
1656 for (; code; code = code->next)
1658 if (code->here != 0)
1660 res = gfc_trans_label_here (code);
1661 gfc_add_expr_to_block (&block, res);
1664 gfc_current_locus = code->loc;
1665 gfc_set_backend_locus (&code->loc);
1667 switch (code->op)
1669 case EXEC_NOP:
1670 case EXEC_END_BLOCK:
1671 case EXEC_END_NESTED_BLOCK:
1672 case EXEC_END_PROCEDURE:
1673 res = NULL_TREE;
1674 break;
1676 case EXEC_ASSIGN:
1677 if (code->expr1->ts.type == BT_CLASS)
1678 res = gfc_trans_class_assign (code->expr1, code->expr2, code->op);
1679 else
1680 res = gfc_trans_assign (code);
1681 break;
1683 case EXEC_LABEL_ASSIGN:
1684 res = gfc_trans_label_assign (code);
1685 break;
1687 case EXEC_POINTER_ASSIGN:
1688 if (code->expr1->ts.type == BT_CLASS)
1689 res = gfc_trans_class_assign (code->expr1, code->expr2, code->op);
1690 else if (UNLIMITED_POLY (code->expr2)
1691 && code->expr1->ts.type == BT_DERIVED
1692 && (code->expr1->ts.u.derived->attr.sequence
1693 || code->expr1->ts.u.derived->attr.is_bind_c))
1694 /* F2003: C717 */
1695 res = gfc_trans_class_assign (code->expr1, code->expr2, code->op);
1696 else
1697 res = gfc_trans_pointer_assign (code);
1698 break;
1700 case EXEC_INIT_ASSIGN:
1701 if (code->expr1->ts.type == BT_CLASS)
1702 res = gfc_trans_class_init_assign (code);
1703 else
1704 res = gfc_trans_init_assign (code);
1705 break;
1707 case EXEC_CONTINUE:
1708 res = NULL_TREE;
1709 break;
1711 case EXEC_CRITICAL:
1712 res = gfc_trans_critical (code);
1713 break;
1715 case EXEC_CYCLE:
1716 res = gfc_trans_cycle (code);
1717 break;
1719 case EXEC_EXIT:
1720 res = gfc_trans_exit (code);
1721 break;
1723 case EXEC_GOTO:
1724 res = gfc_trans_goto (code);
1725 break;
1727 case EXEC_ENTRY:
1728 res = gfc_trans_entry (code);
1729 break;
1731 case EXEC_PAUSE:
1732 res = gfc_trans_pause (code);
1733 break;
1735 case EXEC_STOP:
1736 case EXEC_ERROR_STOP:
1737 res = gfc_trans_stop (code, code->op == EXEC_ERROR_STOP);
1738 break;
1740 case EXEC_CALL:
1741 /* For MVBITS we've got the special exception that we need a
1742 dependency check, too. */
1744 bool is_mvbits = false;
1746 if (code->resolved_isym)
1748 res = gfc_conv_intrinsic_subroutine (code);
1749 if (res != NULL_TREE)
1750 break;
1753 if (code->resolved_isym
1754 && code->resolved_isym->id == GFC_ISYM_MVBITS)
1755 is_mvbits = true;
1757 res = gfc_trans_call (code, is_mvbits, NULL_TREE,
1758 NULL_TREE, false);
1760 break;
1762 case EXEC_CALL_PPC:
1763 res = gfc_trans_call (code, false, NULL_TREE,
1764 NULL_TREE, false);
1765 break;
1767 case EXEC_ASSIGN_CALL:
1768 res = gfc_trans_call (code, true, NULL_TREE,
1769 NULL_TREE, false);
1770 break;
1772 case EXEC_RETURN:
1773 res = gfc_trans_return (code);
1774 break;
1776 case EXEC_IF:
1777 res = gfc_trans_if (code);
1778 break;
1780 case EXEC_ARITHMETIC_IF:
1781 res = gfc_trans_arithmetic_if (code);
1782 break;
1784 case EXEC_BLOCK:
1785 res = gfc_trans_block_construct (code);
1786 break;
1788 case EXEC_DO:
1789 res = gfc_trans_do (code, cond);
1790 break;
1792 case EXEC_DO_CONCURRENT:
1793 res = gfc_trans_do_concurrent (code);
1794 break;
1796 case EXEC_DO_WHILE:
1797 res = gfc_trans_do_while (code);
1798 break;
1800 case EXEC_SELECT:
1801 res = gfc_trans_select (code);
1802 break;
1804 case EXEC_SELECT_TYPE:
1805 /* Do nothing. SELECT TYPE statements should be transformed into
1806 an ordinary SELECT CASE at resolution stage.
1807 TODO: Add an error message here once this is done. */
1808 res = NULL_TREE;
1809 break;
1811 case EXEC_FLUSH:
1812 res = gfc_trans_flush (code);
1813 break;
1815 case EXEC_SYNC_ALL:
1816 case EXEC_SYNC_IMAGES:
1817 case EXEC_SYNC_MEMORY:
1818 res = gfc_trans_sync (code, code->op);
1819 break;
1821 case EXEC_LOCK:
1822 case EXEC_UNLOCK:
1823 res = gfc_trans_lock_unlock (code, code->op);
1824 break;
1826 case EXEC_EVENT_POST:
1827 case EXEC_EVENT_WAIT:
1828 res = gfc_trans_event_post_wait (code, code->op);
1829 break;
1831 case EXEC_FORALL:
1832 res = gfc_trans_forall (code);
1833 break;
1835 case EXEC_WHERE:
1836 res = gfc_trans_where (code);
1837 break;
1839 case EXEC_ALLOCATE:
1840 res = gfc_trans_allocate (code);
1841 break;
1843 case EXEC_DEALLOCATE:
1844 res = gfc_trans_deallocate (code);
1845 break;
1847 case EXEC_OPEN:
1848 res = gfc_trans_open (code);
1849 break;
1851 case EXEC_CLOSE:
1852 res = gfc_trans_close (code);
1853 break;
1855 case EXEC_READ:
1856 res = gfc_trans_read (code);
1857 break;
1859 case EXEC_WRITE:
1860 res = gfc_trans_write (code);
1861 break;
1863 case EXEC_IOLENGTH:
1864 res = gfc_trans_iolength (code);
1865 break;
1867 case EXEC_BACKSPACE:
1868 res = gfc_trans_backspace (code);
1869 break;
1871 case EXEC_ENDFILE:
1872 res = gfc_trans_endfile (code);
1873 break;
1875 case EXEC_INQUIRE:
1876 res = gfc_trans_inquire (code);
1877 break;
1879 case EXEC_WAIT:
1880 res = gfc_trans_wait (code);
1881 break;
1883 case EXEC_REWIND:
1884 res = gfc_trans_rewind (code);
1885 break;
1887 case EXEC_TRANSFER:
1888 res = gfc_trans_transfer (code);
1889 break;
1891 case EXEC_DT_END:
1892 res = gfc_trans_dt_end (code);
1893 break;
1895 case EXEC_OMP_ATOMIC:
1896 case EXEC_OMP_BARRIER:
1897 case EXEC_OMP_CANCEL:
1898 case EXEC_OMP_CANCELLATION_POINT:
1899 case EXEC_OMP_CRITICAL:
1900 case EXEC_OMP_DISTRIBUTE:
1901 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
1902 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
1903 case EXEC_OMP_DISTRIBUTE_SIMD:
1904 case EXEC_OMP_DO:
1905 case EXEC_OMP_DO_SIMD:
1906 case EXEC_OMP_FLUSH:
1907 case EXEC_OMP_MASTER:
1908 case EXEC_OMP_ORDERED:
1909 case EXEC_OMP_PARALLEL:
1910 case EXEC_OMP_PARALLEL_DO:
1911 case EXEC_OMP_PARALLEL_DO_SIMD:
1912 case EXEC_OMP_PARALLEL_SECTIONS:
1913 case EXEC_OMP_PARALLEL_WORKSHARE:
1914 case EXEC_OMP_SECTIONS:
1915 case EXEC_OMP_SIMD:
1916 case EXEC_OMP_SINGLE:
1917 case EXEC_OMP_TARGET:
1918 case EXEC_OMP_TARGET_DATA:
1919 case EXEC_OMP_TARGET_TEAMS:
1920 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
1921 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
1922 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
1923 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
1924 case EXEC_OMP_TARGET_UPDATE:
1925 case EXEC_OMP_TASK:
1926 case EXEC_OMP_TASKGROUP:
1927 case EXEC_OMP_TASKWAIT:
1928 case EXEC_OMP_TASKYIELD:
1929 case EXEC_OMP_TEAMS:
1930 case EXEC_OMP_TEAMS_DISTRIBUTE:
1931 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
1932 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
1933 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
1934 case EXEC_OMP_WORKSHARE:
1935 res = gfc_trans_omp_directive (code);
1936 break;
1938 case EXEC_OACC_CACHE:
1939 case EXEC_OACC_WAIT:
1940 case EXEC_OACC_UPDATE:
1941 case EXEC_OACC_LOOP:
1942 case EXEC_OACC_HOST_DATA:
1943 case EXEC_OACC_DATA:
1944 case EXEC_OACC_KERNELS:
1945 case EXEC_OACC_KERNELS_LOOP:
1946 case EXEC_OACC_PARALLEL:
1947 case EXEC_OACC_PARALLEL_LOOP:
1948 case EXEC_OACC_ENTER_DATA:
1949 case EXEC_OACC_EXIT_DATA:
1950 case EXEC_OACC_ATOMIC:
1951 case EXEC_OACC_DECLARE:
1952 res = gfc_trans_oacc_directive (code);
1953 break;
1955 default:
1956 gfc_internal_error ("gfc_trans_code(): Bad statement code");
1959 gfc_set_backend_locus (&code->loc);
1961 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
1963 if (TREE_CODE (res) != STATEMENT_LIST)
1964 SET_EXPR_LOCATION (res, input_location);
1966 /* Add the new statement to the block. */
1967 gfc_add_expr_to_block (&block, res);
1971 /* Return the finished block. */
1972 return gfc_finish_block (&block);
1976 /* Translate an executable statement with condition, cond. The condition is
1977 used by gfc_trans_do to test for IO result conditions inside implied
1978 DO loops of READ and WRITE statements. See build_dt in trans-io.c. */
1980 tree
1981 gfc_trans_code_cond (gfc_code * code, tree cond)
1983 return trans_code (code, cond);
1986 /* Translate an executable statement without condition. */
1988 tree
1989 gfc_trans_code (gfc_code * code)
1991 return trans_code (code, NULL_TREE);
1995 /* This function is called after a complete program unit has been parsed
1996 and resolved. */
1998 void
1999 gfc_generate_code (gfc_namespace * ns)
2001 ompws_flags = 0;
2002 if (ns->is_block_data)
2004 gfc_generate_block_data (ns);
2005 return;
2008 gfc_generate_function_code (ns);
2012 /* This function is called after a complete module has been parsed
2013 and resolved. */
2015 void
2016 gfc_generate_module_code (gfc_namespace * ns)
2018 gfc_namespace *n;
2019 struct module_htab_entry *entry;
2021 gcc_assert (ns->proc_name->backend_decl == NULL);
2022 ns->proc_name->backend_decl
2023 = build_decl (ns->proc_name->declared_at.lb->location,
2024 NAMESPACE_DECL, get_identifier (ns->proc_name->name),
2025 void_type_node);
2026 entry = gfc_find_module (ns->proc_name->name);
2027 if (entry->namespace_decl)
2028 /* Buggy sourcecode, using a module before defining it? */
2029 entry->decls->empty ();
2030 entry->namespace_decl = ns->proc_name->backend_decl;
2032 gfc_generate_module_vars (ns);
2034 /* We need to generate all module function prototypes first, to allow
2035 sibling calls. */
2036 for (n = ns->contained; n; n = n->sibling)
2038 gfc_entry_list *el;
2040 if (!n->proc_name)
2041 continue;
2043 gfc_create_function_decl (n, false);
2044 DECL_CONTEXT (n->proc_name->backend_decl) = ns->proc_name->backend_decl;
2045 gfc_module_add_decl (entry, n->proc_name->backend_decl);
2046 for (el = ns->entries; el; el = el->next)
2048 DECL_CONTEXT (el->sym->backend_decl) = ns->proc_name->backend_decl;
2049 gfc_module_add_decl (entry, el->sym->backend_decl);
2053 for (n = ns->contained; n; n = n->sibling)
2055 if (!n->proc_name)
2056 continue;
2058 gfc_generate_function_code (n);
2063 /* Initialize an init/cleanup block with existing code. */
2065 void
2066 gfc_start_wrapped_block (gfc_wrapped_block* block, tree code)
2068 gcc_assert (block);
2070 block->init = NULL_TREE;
2071 block->code = code;
2072 block->cleanup = NULL_TREE;
2076 /* Add a new pair of initializers/clean-up code. */
2078 void
2079 gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup)
2081 gcc_assert (block);
2083 /* The new pair of init/cleanup should be "wrapped around" the existing
2084 block of code, thus the initialization is added to the front and the
2085 cleanup to the back. */
2086 add_expr_to_chain (&block->init, init, true);
2087 add_expr_to_chain (&block->cleanup, cleanup, false);
2091 /* Finish up a wrapped block by building a corresponding try-finally expr. */
2093 tree
2094 gfc_finish_wrapped_block (gfc_wrapped_block* block)
2096 tree result;
2098 gcc_assert (block);
2100 /* Build the final expression. For this, just add init and body together,
2101 and put clean-up with that into a TRY_FINALLY_EXPR. */
2102 result = block->init;
2103 add_expr_to_chain (&result, block->code, false);
2104 if (block->cleanup)
2105 result = build2_loc (input_location, TRY_FINALLY_EXPR, void_type_node,
2106 result, block->cleanup);
2108 /* Clear the block. */
2109 block->init = NULL_TREE;
2110 block->code = NULL_TREE;
2111 block->cleanup = NULL_TREE;
2113 return result;
2117 /* Helper function for marking a boolean expression tree as unlikely. */
2119 tree
2120 gfc_unlikely (tree cond, enum br_predictor predictor)
2122 tree tmp;
2124 if (optimize)
2126 cond = fold_convert (long_integer_type_node, cond);
2127 tmp = build_zero_cst (long_integer_type_node);
2128 cond = build_call_expr_loc (input_location,
2129 builtin_decl_explicit (BUILT_IN_EXPECT),
2130 3, cond, tmp,
2131 build_int_cst (integer_type_node,
2132 predictor));
2134 cond = fold_convert (boolean_type_node, cond);
2135 return cond;
2139 /* Helper function for marking a boolean expression tree as likely. */
2141 tree
2142 gfc_likely (tree cond, enum br_predictor predictor)
2144 tree tmp;
2146 if (optimize)
2148 cond = fold_convert (long_integer_type_node, cond);
2149 tmp = build_one_cst (long_integer_type_node);
2150 cond = build_call_expr_loc (input_location,
2151 builtin_decl_explicit (BUILT_IN_EXPECT),
2152 3, cond, tmp,
2153 build_int_cst (integer_type_node,
2154 predictor));
2156 cond = fold_convert (boolean_type_node, cond);
2157 return cond;
2161 /* Get the string length for a deferred character length component. */
2163 bool
2164 gfc_deferred_strlen (gfc_component *c, tree *decl)
2166 char name[GFC_MAX_SYMBOL_LEN+9];
2167 gfc_component *strlen;
2168 if (!(c->ts.type == BT_CHARACTER && c->ts.deferred))
2169 return false;
2170 sprintf (name, "_%s_length", c->name);
2171 for (strlen = c; strlen; strlen = strlen->next)
2172 if (strcmp (strlen->name, name) == 0)
2173 break;
2174 *decl = strlen ? strlen->backend_decl : NULL_TREE;
2175 return strlen != NULL;