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