/* Statement translation -- generate GCC trees from gfc_code.
   Copyright (C) 2002-2019 Free Software Foundation, Inc.
   Contributed by Paul Brook <paul@nowt.org>
   and Steven Bosscher <s.bosscher@student.tudelft.nl>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */


#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "options.h"
#include "tree.h"
#include "gfortran.h"
#include "trans.h"
#include "stringpool.h"
#include "fold-const.h"
#include "trans-stmt.h"
#include "trans-types.h"
#include "trans-array.h"
#include "trans-const.h"
#include "dependency.h"

typedef struct iter_info
{
  tree var;
  tree start;
  tree end;
  tree step;
  struct iter_info *next;
}
iter_info;

typedef struct forall_info
{
  iter_info *this_loop;
  tree mask;
  tree maskindex;
  int nvar;
  tree size;
  struct forall_info  *prev_nest;
  bool do_concurrent;
}
forall_info;

static void gfc_trans_where_2 (gfc_code *, tree, bool,
			       forall_info *, stmtblock_t *);

/* Translate a F95 label number to a LABEL_EXPR.  */

tree
gfc_trans_label_here (gfc_code * code)
{
  return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
}


/* Given a variable expression which has been ASSIGNed to, find the decl
   containing the auxiliary variables.  For variables in common blocks this
   is a field_decl.  */

void
gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
{
  gcc_assert (expr->symtree->n.sym->attr.assign == 1);
  gfc_conv_expr (se, expr);
  /* Deals with variable in common block. Get the field declaration.  */
  if (TREE_CODE (se->expr) == COMPONENT_REF)
    se->expr = TREE_OPERAND (se->expr, 1);
  /* Deals with dummy argument. Get the parameter declaration.  */
  else if (TREE_CODE (se->expr) == INDIRECT_REF)
    se->expr = TREE_OPERAND (se->expr, 0);
}

/* Translate a label assignment statement.  */

tree
gfc_trans_label_assign (gfc_code * code)
{
  tree label_tree;
  gfc_se se;
  tree len;
  tree addr;
  tree len_tree;
  int label_len;

  /* Start a new block.  */
  gfc_init_se (&se, NULL);
  gfc_start_block (&se.pre);
  gfc_conv_label_variable (&se, code->expr1);

  len = GFC_DECL_STRING_LEN (se.expr);
  addr = GFC_DECL_ASSIGN_ADDR (se.expr);

  label_tree = gfc_get_label_decl (code->label1);

  if (code->label1->defined == ST_LABEL_TARGET
      || code->label1->defined == ST_LABEL_DO_TARGET)
    {
      label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
      len_tree = build_int_cst (gfc_charlen_type_node, -1);
    }
  else
    {
      gfc_expr *format = code->label1->format;

      label_len = format->value.character.length;
      len_tree = build_int_cst (gfc_charlen_type_node, label_len);
      label_tree = gfc_build_wide_string_const (format->ts.kind, label_len + 1,
						format->value.character.string);
      label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
    }

  gfc_add_modify (&se.pre, len, fold_convert (TREE_TYPE (len), len_tree));
  gfc_add_modify (&se.pre, addr, label_tree);

  return gfc_finish_block (&se.pre);
}

/* Translate a GOTO statement.  */

tree
gfc_trans_goto (gfc_code * code)
{
  locus loc = code->loc;
  tree assigned_goto;
  tree target;
  tree tmp;
  gfc_se se;

  if (code->label1 != NULL)
    return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));

  /* ASSIGNED GOTO.  */
  gfc_init_se (&se, NULL);
  gfc_start_block (&se.pre);
  gfc_conv_label_variable (&se, code->expr1);
  tmp = GFC_DECL_STRING_LEN (se.expr);
  tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
			 build_int_cst (TREE_TYPE (tmp), -1));
  gfc_trans_runtime_check (true, false, tmp, &se.pre, &loc,
			   "Assigned label is not a target label");

  assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);

  /* We're going to ignore a label list.  It does not really change the
     statement's semantics (because it is just a further restriction on
     what's legal code); before, we were comparing label addresses here, but
     that's a very fragile business and may break with optimization.  So
     just ignore it.  */

  target = fold_build1_loc (input_location, GOTO_EXPR, void_type_node,
			    assigned_goto);
  gfc_add_expr_to_block (&se.pre, target);
  return gfc_finish_block (&se.pre);
}


/* Translate an ENTRY statement.  Just adds a label for this entry point.  */
tree
gfc_trans_entry (gfc_code * code)
{
  return build1_v (LABEL_EXPR, code->ext.entry->label);
}


/* Replace a gfc_ss structure by another both in the gfc_se struct
   and the gfc_loopinfo struct.  This is used in gfc_conv_elemental_dependencies
   to replace a variable ss by the corresponding temporary.  */

static void
replace_ss (gfc_se *se, gfc_ss *old_ss, gfc_ss *new_ss)
{
  gfc_ss **sess, **loopss;

  /* The old_ss is a ss for a single variable.  */
  gcc_assert (old_ss->info->type == GFC_SS_SECTION);

  for (sess = &(se->ss); *sess != gfc_ss_terminator; sess = &((*sess)->next))
    if (*sess == old_ss)
      break;
  gcc_assert (*sess != gfc_ss_terminator);

  *sess = new_ss;
  new_ss->next = old_ss->next;


  for (loopss = &(se->loop->ss); *loopss != gfc_ss_terminator;
       loopss = &((*loopss)->loop_chain))
    if (*loopss == old_ss)
      break;
  gcc_assert (*loopss != gfc_ss_terminator);

  *loopss = new_ss;
  new_ss->loop_chain = old_ss->loop_chain;
  new_ss->loop = old_ss->loop;

  gfc_free_ss (old_ss);
}


/* Check for dependencies between INTENT(IN) and INTENT(OUT) arguments of
   elemental subroutines.  Make temporaries for output arguments if any such
   dependencies are found.  Output arguments are chosen because internal_unpack
   can be used, as is, to copy the result back to the variable.  */
static void
gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
				 gfc_symbol * sym, gfc_actual_arglist * arg,
				 gfc_dep_check check_variable)
{
  gfc_actual_arglist *arg0;
  gfc_expr *e;
  gfc_formal_arglist *formal;
  gfc_se parmse;
  gfc_ss *ss;
  gfc_symbol *fsym;
  tree data;
  tree size;
  tree tmp;

  if (loopse->ss == NULL)
    return;

  ss = loopse->ss;
  arg0 = arg;
  formal = gfc_sym_get_dummy_args (sym);

  /* Loop over all the arguments testing for dependencies.  */
  for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
    {
      e = arg->expr;
      if (e == NULL)
	continue;

      /* Obtain the info structure for the current argument.  */
      for (ss = loopse->ss; ss && ss != gfc_ss_terminator; ss = ss->next)
	if (ss->info->expr == e)
	  break;

      /* If there is a dependency, create a temporary and use it
	 instead of the variable.  */
      fsym = formal ? formal->sym : NULL;
      if (e->expr_type == EXPR_VARIABLE
	    && e->rank && fsym
	    && fsym->attr.intent != INTENT_IN
	    && gfc_check_fncall_dependency (e, fsym->attr.intent,
					    sym, arg0, check_variable))
	{
	  tree initial, temptype;
	  stmtblock_t temp_post;
	  gfc_ss *tmp_ss;

	  tmp_ss = gfc_get_array_ss (gfc_ss_terminator, NULL, ss->dimen,
				     GFC_SS_SECTION);
	  gfc_mark_ss_chain_used (tmp_ss, 1);
	  tmp_ss->info->expr = ss->info->expr;
	  replace_ss (loopse, ss, tmp_ss);

	  /* Obtain the argument descriptor for unpacking.  */
	  gfc_init_se (&parmse, NULL);
	  parmse.want_pointer = 1;
	  gfc_conv_expr_descriptor (&parmse, e);
	  gfc_add_block_to_block (&se->pre, &parmse.pre);

	  /* If we've got INTENT(INOUT) or a derived type with INTENT(OUT),
	     initialize the array temporary with a copy of the values.  */
	  if (fsym->attr.intent == INTENT_INOUT
		|| (fsym->ts.type ==BT_DERIVED
		      && fsym->attr.intent == INTENT_OUT))
	    initial = parmse.expr;
	  /* For class expressions, we always initialize with the copy of
	     the values.  */
	  else if (e->ts.type == BT_CLASS)
	    initial = parmse.expr;
	  else
	    initial = NULL_TREE;

	  if (e->ts.type != BT_CLASS)
	    {
	     /* Find the type of the temporary to create; we don't use the type
		of e itself as this breaks for subcomponent-references in e
		(where the type of e is that of the final reference, but
		parmse.expr's type corresponds to the full derived-type).  */
	     /* TODO: Fix this somehow so we don't need a temporary of the whole
		array but instead only the components referenced.  */
	      temptype = TREE_TYPE (parmse.expr); /* Pointer to descriptor.  */
	      gcc_assert (TREE_CODE (temptype) == POINTER_TYPE);
	      temptype = TREE_TYPE (temptype);
	      temptype = gfc_get_element_type (temptype);
	    }

	  else
	    /* For class arrays signal that the size of the dynamic type has to
	       be obtained from the vtable, using the 'initial' expression.  */
	    temptype = NULL_TREE;

	  /* Generate the temporary.  Cleaning up the temporary should be the
	     very last thing done, so we add the code to a new block and add it
	     to se->post as last instructions.  */
	  size = gfc_create_var (gfc_array_index_type, NULL);
	  data = gfc_create_var (pvoid_type_node, NULL);
	  gfc_init_block (&temp_post);
	  tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, tmp_ss,
					     temptype, initial, false, true,
					     false, &arg->expr->where);
	  gfc_add_modify (&se->pre, size, tmp);
	  tmp = fold_convert (pvoid_type_node, tmp_ss->info->data.array.data);
	  gfc_add_modify (&se->pre, data, tmp);

	  /* Update other ss' delta.  */
	  gfc_set_delta (loopse->loop);

	  /* Copy the result back using unpack.....  */
	  if (e->ts.type != BT_CLASS)
	    tmp = build_call_expr_loc (input_location,
			gfor_fndecl_in_unpack, 2, parmse.expr, data);
	  else
	    {
	      /* ... except for class results where the copy is
		 unconditional.  */
	      tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
	      tmp = gfc_conv_descriptor_data_get (tmp);
	      tmp = build_call_expr_loc (input_location,
					 builtin_decl_explicit (BUILT_IN_MEMCPY),
					 3, tmp, data,
					 fold_convert (size_type_node, size));
	    }
	  gfc_add_expr_to_block (&se->post, tmp);

	  /* parmse.pre is already added above.  */
	  gfc_add_block_to_block (&se->post, &parmse.post);
	  gfc_add_block_to_block (&se->post, &temp_post);
	}
    }
}


/* Get the interface symbol for the procedure corresponding to the given call.
   We can't get the procedure symbol directly as we have to handle the case
   of (deferred) type-bound procedures.  */

static gfc_symbol *
get_proc_ifc_for_call (gfc_code *c)
{
  gfc_symbol *sym;

  gcc_assert (c->op == EXEC_ASSIGN_CALL || c->op == EXEC_CALL);

  sym = gfc_get_proc_ifc_for_expr (c->expr1);

  /* Fall back/last resort try.  */
  if (sym == NULL)
    sym = c->resolved_sym;

  return sym;
}


/* Translate the CALL statement.  Builds a call to an F95 subroutine.  */

tree
gfc_trans_call (gfc_code * code, bool dependency_check,
		tree mask, tree count1, bool invert)
{
  gfc_se se;
  gfc_ss * ss;
  int has_alternate_specifier;
  gfc_dep_check check_variable;
  tree index = NULL_TREE;
  tree maskexpr = NULL_TREE;
  tree tmp;

  /* A CALL starts a new block because the actual arguments may have to
     be evaluated first.  */
  gfc_init_se (&se, NULL);
  gfc_start_block (&se.pre);

  gcc_assert (code->resolved_sym);

  ss = gfc_ss_terminator;
  if (code->resolved_sym->attr.elemental)
    ss = gfc_walk_elemental_function_args (ss, code->ext.actual,
					   get_proc_ifc_for_call (code),
					   GFC_SS_REFERENCE);

  /* Is not an elemental subroutine call with array valued arguments.  */
  if (ss == gfc_ss_terminator)
    {

      /* Translate the call.  */
      has_alternate_specifier
	= gfc_conv_procedure_call (&se, code->resolved_sym, code->ext.actual,
				  code->expr1, NULL);

      /* A subroutine without side-effect, by definition, does nothing!  */
      TREE_SIDE_EFFECTS (se.expr) = 1;

      /* Chain the pieces together and return the block.  */
      if (has_alternate_specifier)
	{
	  gfc_code *select_code;
	  gfc_symbol *sym;
	  select_code = code->next;
	  gcc_assert(select_code->op == EXEC_SELECT);
	  sym = select_code->expr1->symtree->n.sym;
	  se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
	  if (sym->backend_decl == NULL)
	    sym->backend_decl = gfc_get_symbol_decl (sym);
	  gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
	}
      else
	gfc_add_expr_to_block (&se.pre, se.expr);

      gfc_add_block_to_block (&se.pre, &se.post);
    }

  else
    {
      /* An elemental subroutine call with array valued arguments has
	 to be scalarized.  */
      gfc_loopinfo loop;
      stmtblock_t body;
      stmtblock_t block;
      gfc_se loopse;
      gfc_se depse;

      /* gfc_walk_elemental_function_args renders the ss chain in the
	 reverse order to the actual argument order.  */
      ss = gfc_reverse_ss (ss);

      /* Initialize the loop.  */
      gfc_init_se (&loopse, NULL);
      gfc_init_loopinfo (&loop);
      gfc_add_ss_to_loop (&loop, ss);

      gfc_conv_ss_startstride (&loop);
      /* TODO: gfc_conv_loop_setup generates a temporary for vector
	 subscripts.  This could be prevented in the elemental case
	 as temporaries are handled separatedly
	 (below in gfc_conv_elemental_dependencies).  */
      if (code->expr1)
	gfc_conv_loop_setup (&loop, &code->expr1->where);
      else
	gfc_conv_loop_setup (&loop, &code->loc);

      gfc_mark_ss_chain_used (ss, 1);

      /* Convert the arguments, checking for dependencies.  */
      gfc_copy_loopinfo_to_se (&loopse, &loop);
      loopse.ss = ss;

      /* For operator assignment, do dependency checking.  */
      if (dependency_check)
	check_variable = ELEM_CHECK_VARIABLE;
      else
	check_variable = ELEM_DONT_CHECK_VARIABLE;

      gfc_init_se (&depse, NULL);
      gfc_conv_elemental_dependencies (&depse, &loopse, code->resolved_sym,
				       code->ext.actual, check_variable);

      gfc_add_block_to_block (&loop.pre,  &depse.pre);
      gfc_add_block_to_block (&loop.post, &depse.post);

      /* Generate the loop body.  */
      gfc_start_scalarized_body (&loop, &body);
      gfc_init_block (&block);

      if (mask && count1)
	{
	  /* Form the mask expression according to the mask.  */
	  index = count1;
	  maskexpr = gfc_build_array_ref (mask, index, NULL);
	  if (invert)
	    maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
					TREE_TYPE (maskexpr), maskexpr);
	}

      /* Add the subroutine call to the block.  */
      gfc_conv_procedure_call (&loopse, code->resolved_sym,
			       code->ext.actual, code->expr1,
			       NULL);

      if (mask && count1)
	{
	  tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
			  build_empty_stmt (input_location));
	  gfc_add_expr_to_block (&loopse.pre, tmp);
	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type,
				 count1, gfc_index_one_node);
	  gfc_add_modify (&loopse.pre, count1, tmp);
	}
      else
	gfc_add_expr_to_block (&loopse.pre, loopse.expr);

      gfc_add_block_to_block (&block, &loopse.pre);
      gfc_add_block_to_block (&block, &loopse.post);

      /* Finish up the loop block and the loop.  */
      gfc_add_expr_to_block (&body, gfc_finish_block (&block));
      gfc_trans_scalarizing_loops (&loop, &body);
      gfc_add_block_to_block (&se.pre, &loop.pre);
      gfc_add_block_to_block (&se.pre, &loop.post);
      gfc_add_block_to_block (&se.pre, &se.post);
      gfc_cleanup_loop (&loop);
    }

  return gfc_finish_block (&se.pre);
}


/* Translate the RETURN statement.  */

tree
gfc_trans_return (gfc_code * code)
{
  if (code->expr1)
    {
      gfc_se se;
      tree tmp;
      tree result;

      /* If code->expr is not NULL, this return statement must appear
	 in a subroutine and current_fake_result_decl has already
	 been generated.  */

      result = gfc_get_fake_result_decl (NULL, 0);
      if (!result)
	{
	  gfc_warning (0,
		       "An alternate return at %L without a * dummy argument",
		       &code->expr1->where);
	  return gfc_generate_return ();
	}

      /* Start a new block for this statement.  */
      gfc_init_se (&se, NULL);
      gfc_start_block (&se.pre);

      gfc_conv_expr (&se, code->expr1);

      /* Note that the actually returned expression is a simple value and
	 does not depend on any pointers or such; thus we can clean-up with
	 se.post before returning.  */
      tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (result),
			     result, fold_convert (TREE_TYPE (result),
			     se.expr));
      gfc_add_expr_to_block (&se.pre, tmp);
      gfc_add_block_to_block (&se.pre, &se.post);

      tmp = gfc_generate_return ();
      gfc_add_expr_to_block (&se.pre, tmp);
      return gfc_finish_block (&se.pre);
    }

  return gfc_generate_return ();
}


/* Translate the PAUSE statement.  We have to translate this statement
   to a runtime library call.  */

tree
gfc_trans_pause (gfc_code * code)
{
  tree gfc_int8_type_node = gfc_get_int_type (8);
  gfc_se se;
  tree tmp;

  /* Start a new block for this statement.  */
  gfc_init_se (&se, NULL);
  gfc_start_block (&se.pre);


  if (code->expr1 == NULL)
    {
      tmp = build_int_cst (size_type_node, 0);
      tmp = build_call_expr_loc (input_location,
				 gfor_fndecl_pause_string, 2,
				 build_int_cst (pchar_type_node, 0), tmp);
    }
  else if (code->expr1->ts.type == BT_INTEGER)
    {
      gfc_conv_expr (&se, code->expr1);
      tmp = build_call_expr_loc (input_location,
				 gfor_fndecl_pause_numeric, 1,
				 fold_convert (gfc_int8_type_node, se.expr));
    }
  else
    {
      gfc_conv_expr_reference (&se, code->expr1);
      tmp = build_call_expr_loc (input_location,
			     gfor_fndecl_pause_string, 2,
				 se.expr, fold_convert (size_type_node,
							se.string_length));
    }

  gfc_add_expr_to_block (&se.pre, tmp);

  gfc_add_block_to_block (&se.pre, &se.post);

  return gfc_finish_block (&se.pre);
}


/* Translate the STOP statement.  We have to translate this statement
   to a runtime library call.  */

tree
gfc_trans_stop (gfc_code *code, bool error_stop)
{
  gfc_se se;
  tree tmp;

  /* Start a new block for this statement.  */
  gfc_init_se (&se, NULL);
  gfc_start_block (&se.pre);

  if (code->expr1 == NULL)
    {
      tmp = build_int_cst (size_type_node, 0);
      tmp = build_call_expr_loc (input_location,
				 error_stop
				 ? (flag_coarray == GFC_FCOARRAY_LIB
				    ? gfor_fndecl_caf_error_stop_str
				    : gfor_fndecl_error_stop_string)
				 : (flag_coarray == GFC_FCOARRAY_LIB
				    ? gfor_fndecl_caf_stop_str
				    : gfor_fndecl_stop_string),
				 3, build_int_cst (pchar_type_node, 0), tmp,
				 boolean_false_node);
    }
  else if (code->expr1->ts.type == BT_INTEGER)
    {
      gfc_conv_expr (&se, code->expr1);
      tmp = build_call_expr_loc (input_location,
				 error_stop
				 ? (flag_coarray == GFC_FCOARRAY_LIB
				    ? gfor_fndecl_caf_error_stop
				    : gfor_fndecl_error_stop_numeric)
				 : (flag_coarray == GFC_FCOARRAY_LIB
				    ? gfor_fndecl_caf_stop_numeric
				    : gfor_fndecl_stop_numeric), 2,
				 fold_convert (integer_type_node, se.expr),
				 boolean_false_node);
    }
  else
    {
      gfc_conv_expr_reference (&se, code->expr1);
      tmp = build_call_expr_loc (input_location,
				 error_stop
				 ? (flag_coarray == GFC_FCOARRAY_LIB
				    ? gfor_fndecl_caf_error_stop_str
				    : gfor_fndecl_error_stop_string)
				 : (flag_coarray == GFC_FCOARRAY_LIB
				    ? gfor_fndecl_caf_stop_str
				    : gfor_fndecl_stop_string),
				 3, se.expr, fold_convert (size_type_node,
							   se.string_length),
				 boolean_false_node);
    }

  gfc_add_expr_to_block (&se.pre, tmp);

  gfc_add_block_to_block (&se.pre, &se.post);

  return gfc_finish_block (&se.pre);
}

/* Translate the FAIL IMAGE statement.  */

tree
gfc_trans_fail_image (gfc_code *code ATTRIBUTE_UNUSED)
{
  if (flag_coarray == GFC_FCOARRAY_LIB)
    return build_call_expr_loc (input_location,
				gfor_fndecl_caf_fail_image, 1,
				build_int_cst (pchar_type_node, 0));
  else
    {
      const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
      gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
      tree tmp = gfc_get_symbol_decl (exsym);
      return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
    }
}

/* Translate the FORM TEAM statement.  */

tree
gfc_trans_form_team (gfc_code *code)
{
  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      gfc_se se;
      gfc_se argse1, argse2;
      tree team_id, team_type, tmp;

      gfc_init_se (&se, NULL);
      gfc_init_se (&argse1, NULL);
      gfc_init_se (&argse2, NULL);
      gfc_start_block (&se.pre);

      gfc_conv_expr_val (&argse1, code->expr1);
      gfc_conv_expr_val (&argse2, code->expr2);
      team_id = fold_convert (integer_type_node, argse1.expr);
      team_type = gfc_build_addr_expr (ppvoid_type_node, argse2.expr);

      gfc_add_block_to_block (&se.pre, &argse1.pre);
      gfc_add_block_to_block (&se.pre, &argse2.pre);
      tmp = build_call_expr_loc (input_location,
				 gfor_fndecl_caf_form_team, 3,
				 team_id, team_type,
				 build_int_cst (integer_type_node, 0));
      gfc_add_expr_to_block (&se.pre, tmp);
      gfc_add_block_to_block (&se.pre, &argse1.post);
      gfc_add_block_to_block (&se.pre, &argse2.post);
      return gfc_finish_block (&se.pre);
    }
  else
    {
      const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
      gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
      tree tmp = gfc_get_symbol_decl (exsym);
      return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
    }
}

/* Translate the CHANGE TEAM statement.  */

tree
gfc_trans_change_team (gfc_code *code)
{
  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      gfc_se argse;
      tree team_type, tmp;

      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, code->expr1);
      team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);

      tmp = build_call_expr_loc (input_location,
				 gfor_fndecl_caf_change_team, 2, team_type,
				 build_int_cst (integer_type_node, 0));
      gfc_add_expr_to_block (&argse.pre, tmp);
      gfc_add_block_to_block (&argse.pre, &argse.post);
      return gfc_finish_block (&argse.pre);
    }
  else
    {
      const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
      gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
      tree tmp = gfc_get_symbol_decl (exsym);
      return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
    }
}

/* Translate the END TEAM statement.  */

tree
gfc_trans_end_team (gfc_code *code ATTRIBUTE_UNUSED)
{
  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      return build_call_expr_loc (input_location,
				  gfor_fndecl_caf_end_team, 1,
				  build_int_cst (pchar_type_node, 0));
    }
  else
    {
      const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
      gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
      tree tmp = gfc_get_symbol_decl (exsym);
      return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
    }
}

/* Translate the SYNC TEAM statement.  */

tree
gfc_trans_sync_team (gfc_code *code)
{
  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      gfc_se argse;
      tree team_type, tmp;

      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, code->expr1);
      team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr);

      tmp = build_call_expr_loc (input_location,
				 gfor_fndecl_caf_sync_team, 2,
				 team_type,
				 build_int_cst (integer_type_node, 0));
      gfc_add_expr_to_block (&argse.pre, tmp);
      gfc_add_block_to_block (&argse.pre, &argse.post);
      return gfc_finish_block (&argse.pre);
    }
  else
    {
      const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
      gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
      tree tmp = gfc_get_symbol_decl (exsym);
      return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
    }
}

tree
gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
{
  gfc_se se, argse;
  tree stat = NULL_TREE, stat2 = NULL_TREE;
  tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;

  /* Short cut: For single images without STAT= or LOCK_ACQUIRED
     return early. (ERRMSG= is always untouched for -fcoarray=single.)  */
  if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
    return NULL_TREE;

  if (code->expr2)
    {
      gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, code->expr2);
      stat = argse.expr;
    }
  else if (flag_coarray == GFC_FCOARRAY_LIB)
    stat = null_pointer_node;

  if (code->expr4)
    {
      gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, code->expr4);
      lock_acquired = argse.expr;
    }
  else if (flag_coarray == GFC_FCOARRAY_LIB)
    lock_acquired = null_pointer_node;

  gfc_start_block (&se.pre);
  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      tree tmp, token, image_index, errmsg, errmsg_len;
      tree index = build_zero_cst (gfc_array_index_type);
      tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);

      if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
	  || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
	     != INTMOD_ISO_FORTRAN_ENV
	  || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
	     != ISOFORTRAN_LOCK_TYPE)
	{
	  gfc_error ("Sorry, the lock component of derived type at %L is not "
		     "yet supported", &code->expr1->where);
	  return NULL_TREE;
	}

      gfc_get_caf_token_offset (&se, &token, NULL, caf_decl, NULL_TREE,
				code->expr1);

      if (gfc_is_coindexed (code->expr1))
	image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
      else
	image_index = integer_zero_node;

      /* For arrays, obtain the array index.  */
      if (gfc_expr_attr (code->expr1).dimension)
	{
	  tree desc, tmp, extent, lbound, ubound;
          gfc_array_ref *ar, ar2;
          int i;

	  /* TODO: Extend this, once DT components are supported.  */
	  ar = &code->expr1->ref->u.ar;
	  ar2 = *ar;
	  memset (ar, '\0', sizeof (*ar));
	  ar->as = ar2.as;
	  ar->type = AR_FULL;

	  gfc_init_se (&argse, NULL);
	  argse.descriptor_only = 1;
	  gfc_conv_expr_descriptor (&argse, code->expr1);
	  gfc_add_block_to_block (&se.pre, &argse.pre);
	  desc = argse.expr;
	  *ar = ar2;

	  extent = build_one_cst (gfc_array_index_type);
	  for (i = 0; i < ar->dimen; i++)
	    {
	      gfc_init_se (&argse, NULL);
	      gfc_conv_expr_type (&argse, ar->start[i], gfc_array_index_type);
	      gfc_add_block_to_block (&argse.pre, &argse.pre);
	      lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
				     TREE_TYPE (lbound), argse.expr, lbound);
	      tmp = fold_build2_loc (input_location, MULT_EXPR,
				     TREE_TYPE (tmp), extent, tmp);
	      index = fold_build2_loc (input_location, PLUS_EXPR,
				       TREE_TYPE (tmp), index, tmp);
	      if (i < ar->dimen - 1)
		{
		  ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
		  tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
		  extent = fold_build2_loc (input_location, MULT_EXPR,
					    TREE_TYPE (tmp), extent, tmp);
		}
	    }
	}

      /* errmsg.  */
      if (code->expr3)
	{
	  gfc_init_se (&argse, NULL);
	  argse.want_pointer = 1;
	  gfc_conv_expr (&argse, code->expr3);
	  gfc_add_block_to_block (&se.pre, &argse.pre);
	  errmsg = argse.expr;
	  errmsg_len = fold_convert (size_type_node, argse.string_length);
	}
      else
	{
	  errmsg = null_pointer_node;
	  errmsg_len = build_zero_cst (size_type_node);
	}

      if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
	{
	  stat2 = stat;
	  stat = gfc_create_var (integer_type_node, "stat");
	}

      if (lock_acquired != null_pointer_node
	  && TREE_TYPE (lock_acquired) != integer_type_node)
	{
	  lock_acquired2 = lock_acquired;
	  lock_acquired = gfc_create_var (integer_type_node, "acquired");
	}

      index = fold_convert (size_type_node, index);
      if (op == EXEC_LOCK)
	tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
                                   token, index, image_index,
				   lock_acquired != null_pointer_node
				   ? gfc_build_addr_expr (NULL, lock_acquired)
				   : lock_acquired,
				   stat != null_pointer_node
				   ? gfc_build_addr_expr (NULL, stat) : stat,
				   errmsg, errmsg_len);
      else
	tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
                                   token, index, image_index,
				   stat != null_pointer_node
				   ? gfc_build_addr_expr (NULL, stat) : stat,
				   errmsg, errmsg_len);
      gfc_add_expr_to_block (&se.pre, tmp);

      /* It guarantees memory consistency within the same segment */
      tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
      tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
			gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
			tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
      ASM_VOLATILE_P (tmp) = 1;

      gfc_add_expr_to_block (&se.pre, tmp);

      if (stat2 != NULL_TREE)
	gfc_add_modify (&se.pre, stat2,
			fold_convert (TREE_TYPE (stat2), stat));

      if (lock_acquired2 != NULL_TREE)
	gfc_add_modify (&se.pre, lock_acquired2,
			fold_convert (TREE_TYPE (lock_acquired2),
				      lock_acquired));

      return gfc_finish_block (&se.pre);
    }

  if (stat != NULL_TREE)
    gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));

  if (lock_acquired != NULL_TREE)
    gfc_add_modify (&se.pre, lock_acquired,
		    fold_convert (TREE_TYPE (lock_acquired),
				  boolean_true_node));

  return gfc_finish_block (&se.pre);
}

tree
gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op)
{
  gfc_se se, argse;
  tree stat = NULL_TREE, stat2 = NULL_TREE;
  tree until_count = NULL_TREE;

  if (code->expr2)
    {
      gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, code->expr2);
      stat = argse.expr;
    }
  else if (flag_coarray == GFC_FCOARRAY_LIB)
    stat = null_pointer_node;

  if (code->expr4)
    {
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, code->expr4);
      until_count = fold_convert (integer_type_node, argse.expr);
    }
  else
    until_count = integer_one_node;

  if (flag_coarray != GFC_FCOARRAY_LIB)
    {
      gfc_start_block (&se.pre);
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, code->expr1);

      if (op == EXEC_EVENT_POST)
	gfc_add_modify (&se.pre, argse.expr,
			fold_build2_loc (input_location, PLUS_EXPR,
				TREE_TYPE (argse.expr), argse.expr,
				build_int_cst (TREE_TYPE (argse.expr), 1)));
      else
	gfc_add_modify (&se.pre, argse.expr,
			fold_build2_loc (input_location, MINUS_EXPR,
				TREE_TYPE (argse.expr), argse.expr,
				fold_convert (TREE_TYPE (argse.expr),
					      until_count)));
      if (stat != NULL_TREE)
	gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));

      return gfc_finish_block (&se.pre);
    }

  gfc_start_block (&se.pre);
  tree tmp, token, image_index, errmsg, errmsg_len;
  tree index = build_zero_cst (gfc_array_index_type);
  tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);

  if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
      || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
	 != INTMOD_ISO_FORTRAN_ENV
      || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
	 != ISOFORTRAN_EVENT_TYPE)
    {
      gfc_error ("Sorry, the event component of derived type at %L is not "
		 "yet supported", &code->expr1->where);
      return NULL_TREE;
    }

  gfc_init_se (&argse, NULL);
  gfc_get_caf_token_offset (&argse, &token, NULL, caf_decl, NULL_TREE,
			    code->expr1);
  gfc_add_block_to_block (&se.pre, &argse.pre);

  if (gfc_is_coindexed (code->expr1))
    image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
  else
    image_index = integer_zero_node;

  /* For arrays, obtain the array index.  */
  if (gfc_expr_attr (code->expr1).dimension)
    {
      tree desc, tmp, extent, lbound, ubound;
      gfc_array_ref *ar, ar2;
      int i;

      /* TODO: Extend this, once DT components are supported.  */
      ar = &code->expr1->ref->u.ar;
      ar2 = *ar;
      memset (ar, '\0', sizeof (*ar));
      ar->as = ar2.as;
      ar->type = AR_FULL;

      gfc_init_se (&argse, NULL);
      argse.descriptor_only = 1;
      gfc_conv_expr_descriptor (&argse, code->expr1);
      gfc_add_block_to_block (&se.pre, &argse.pre);
      desc = argse.expr;
      *ar = ar2;

      extent = build_one_cst (gfc_array_index_type);
      for (i = 0; i < ar->dimen; i++)
	{
	  gfc_init_se (&argse, NULL);
	  gfc_conv_expr_type (&argse, ar->start[i], gfc_array_index_type);
	  gfc_add_block_to_block (&argse.pre, &argse.pre);
	  lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
				 TREE_TYPE (lbound), argse.expr, lbound);
	  tmp = fold_build2_loc (input_location, MULT_EXPR,
				 TREE_TYPE (tmp), extent, tmp);
	  index = fold_build2_loc (input_location, PLUS_EXPR,
				   TREE_TYPE (tmp), index, tmp);
	  if (i < ar->dimen - 1)
	    {
	      ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
	      tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
	      extent = fold_build2_loc (input_location, MULT_EXPR,
					TREE_TYPE (tmp), extent, tmp);
	    }
	}
    }

  /* errmsg.  */
  if (code->expr3)
    {
      gfc_init_se (&argse, NULL);
      argse.want_pointer = 1;
      gfc_conv_expr (&argse, code->expr3);
      gfc_add_block_to_block (&se.pre, &argse.pre);
      errmsg = argse.expr;
      errmsg_len = fold_convert (size_type_node, argse.string_length);
    }
  else
    {
      errmsg = null_pointer_node;
      errmsg_len = build_zero_cst (size_type_node);
    }

  if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
    {
      stat2 = stat;
      stat = gfc_create_var (integer_type_node, "stat");
    }

  index = fold_convert (size_type_node, index);
  if (op == EXEC_EVENT_POST)
    tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_post, 6,
			       token, index, image_index,
			       stat != null_pointer_node
			       ? gfc_build_addr_expr (NULL, stat) : stat,
			       errmsg, errmsg_len);
  else
    tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_wait, 6,
			       token, index, until_count,
			       stat != null_pointer_node
			       ? gfc_build_addr_expr (NULL, stat) : stat,
			       errmsg, errmsg_len);
  gfc_add_expr_to_block (&se.pre, tmp);

  /* It guarantees memory consistency within the same segment */
  tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
  tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
		    gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
		    tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
  ASM_VOLATILE_P (tmp) = 1;
  gfc_add_expr_to_block (&se.pre, tmp);

  if (stat2 != NULL_TREE)
    gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat));

  return gfc_finish_block (&se.pre);
}

tree
gfc_trans_sync (gfc_code *code, gfc_exec_op type)
{
  gfc_se se, argse;
  tree tmp;
  tree images = NULL_TREE, stat = NULL_TREE,
       errmsg = NULL_TREE, errmsglen = NULL_TREE;

  /* Short cut: For single images without bound checking or without STAT=,
     return early. (ERRMSG= is always untouched for -fcoarray=single.)  */
  if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
      && flag_coarray != GFC_FCOARRAY_LIB)
    return NULL_TREE;

  gfc_init_se (&se, NULL);
  gfc_start_block (&se.pre);

  if (code->expr1 && code->expr1->rank == 0)
    {
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, code->expr1);
      images = argse.expr;
    }

  if (code->expr2)
    {
      gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, code->expr2);
      stat = argse.expr;
    }
  else
    stat = null_pointer_node;

  if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
    {
      gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
      gfc_init_se (&argse, NULL);
      argse.want_pointer = 1;
      gfc_conv_expr (&argse, code->expr3);
      gfc_conv_string_parameter (&argse);
      errmsg = gfc_build_addr_expr (NULL, argse.expr);
      errmsglen = fold_convert (size_type_node, argse.string_length);
    }
  else if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      errmsg = null_pointer_node;
      errmsglen = build_int_cst (size_type_node, 0);
    }

  /* Check SYNC IMAGES(imageset) for valid image index.
     FIXME: Add a check for image-set arrays.  */
  if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
      && code->expr1->rank == 0)
    {
      tree cond;
      if (flag_coarray != GFC_FCOARRAY_LIB)
	cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
				images, build_int_cst (TREE_TYPE (images), 1));
      else
	{
	  tree cond2;
	  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
				     2, integer_zero_node,
				     build_int_cst (integer_type_node, -1));
	  cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
				  images, tmp);
	  cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
				   images,
				   build_int_cst (TREE_TYPE (images), 1));
	  cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
				  logical_type_node, cond, cond2);
	}
      gfc_trans_runtime_check (true, false, cond, &se.pre,
			       &code->expr1->where, "Invalid image number "
			       "%d in SYNC IMAGES",
			       fold_convert (integer_type_node, images));
    }

  /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the
     image control statements SYNC IMAGES and SYNC ALL.  */
  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
      tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
			gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
			tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
      ASM_VOLATILE_P (tmp) = 1;
      gfc_add_expr_to_block (&se.pre, tmp);
    }

  if (flag_coarray != GFC_FCOARRAY_LIB)
    {
      /* Set STAT to zero.  */
      if (code->expr2)
	gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
    }
  else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
    {
      /* SYNC ALL           =>   stat == null_pointer_node
	 SYNC ALL(stat=s)   =>   stat has an integer type

	 If "stat" has the wrong integer type, use a temp variable of
	 the right type and later cast the result back into "stat".  */
      if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
	{
	  if (TREE_TYPE (stat) == integer_type_node)
	    stat = gfc_build_addr_expr (NULL, stat);

	  if(type == EXEC_SYNC_MEMORY)
	    tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
				       3, stat, errmsg, errmsglen);
	  else
	    tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
				       3, stat, errmsg, errmsglen);

	  gfc_add_expr_to_block (&se.pre, tmp);
	}
      else
	{
	  tree tmp_stat = gfc_create_var (integer_type_node, "stat");

	  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
				     3, gfc_build_addr_expr (NULL, tmp_stat),
				     errmsg, errmsglen);
	  gfc_add_expr_to_block (&se.pre, tmp);

	  gfc_add_modify (&se.pre, stat,
			  fold_convert (TREE_TYPE (stat), tmp_stat));
	}
    }
  else
    {
      tree len;

      gcc_assert (type == EXEC_SYNC_IMAGES);

      if (!code->expr1)
	{
	  len = build_int_cst (integer_type_node, -1);
	  images = null_pointer_node;
	}
      else if (code->expr1->rank == 0)
	{
	  len = build_int_cst (integer_type_node, 1);
	  images = gfc_build_addr_expr (NULL_TREE, images);
	}
      else
	{
	  /* FIXME.  */
	  if (code->expr1->ts.kind != gfc_c_int_kind)
	    gfc_fatal_error ("Sorry, only support for integer kind %d "
			     "implemented for image-set at %L",
			     gfc_c_int_kind, &code->expr1->where);

	  gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
	  images = se.expr;

	  tmp = gfc_typenode_for_spec (&code->expr1->ts);
	  if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
	    tmp = gfc_get_element_type (tmp);

	  len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
				 TREE_TYPE (len), len,
				 fold_convert (TREE_TYPE (len),
					       TYPE_SIZE_UNIT (tmp)));
          len = fold_convert (integer_type_node, len);
	}

      /* SYNC IMAGES(imgs)        => stat == null_pointer_node
	 SYNC IMAGES(imgs,stat=s) => stat has an integer type

	 If "stat" has the wrong integer type, use a temp variable of
	 the right type and later cast the result back into "stat".  */
      if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
	{
	  if (TREE_TYPE (stat) == integer_type_node)
	    stat = gfc_build_addr_expr (NULL, stat);

	  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
				     5, fold_convert (integer_type_node, len),
				     images, stat, errmsg, errmsglen);
	  gfc_add_expr_to_block (&se.pre, tmp);
	}
      else
	{
	  tree tmp_stat = gfc_create_var (integer_type_node, "stat");

	  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
				     5, fold_convert (integer_type_node, len),
				     images, gfc_build_addr_expr (NULL, tmp_stat),
				     errmsg, errmsglen);
	  gfc_add_expr_to_block (&se.pre, tmp);

	  gfc_add_modify (&se.pre, stat,
			  fold_convert (TREE_TYPE (stat), tmp_stat));
	}
    }

  return gfc_finish_block (&se.pre);
}


/* Generate GENERIC for the IF construct. This function also deals with
   the simple IF statement, because the front end translates the IF
   statement into an IF construct.

   We translate:

        IF (cond) THEN
           then_clause
        ELSEIF (cond2)
           elseif_clause
        ELSE
           else_clause
        ENDIF

   into:

        pre_cond_s;
        if (cond_s)
          {
            then_clause;
          }
        else
          {
            pre_cond_s
            if (cond_s)
              {
                elseif_clause
              }
            else
              {
                else_clause;
              }
          }

   where COND_S is the simplified version of the predicate. PRE_COND_S
   are the pre side-effects produced by the translation of the
   conditional.
   We need to build the chain recursively otherwise we run into
   problems with folding incomplete statements.  */

static tree
gfc_trans_if_1 (gfc_code * code)
{
  gfc_se if_se;
  tree stmt, elsestmt;
  locus saved_loc;
  location_t loc;

  /* Check for an unconditional ELSE clause.  */
  if (!code->expr1)
    return gfc_trans_code (code->next);

  /* Initialize a statement builder for each block. Puts in NULL_TREEs.  */
  gfc_init_se (&if_se, NULL);
  gfc_start_block (&if_se.pre);

  /* Calculate the IF condition expression.  */
  if (code->expr1->where.lb)
    {
      gfc_save_backend_locus (&saved_loc);
      gfc_set_backend_locus (&code->expr1->where);
    }

  gfc_conv_expr_val (&if_se, code->expr1);

  if (code->expr1->where.lb)
    gfc_restore_backend_locus (&saved_loc);

  /* Translate the THEN clause.  */
  stmt = gfc_trans_code (code->next);

  /* Translate the ELSE clause.  */
  if (code->block)
    elsestmt = gfc_trans_if_1 (code->block);
  else
    elsestmt = build_empty_stmt (input_location);

  /* Build the condition expression and add it to the condition block.  */
  loc = code->expr1->where.lb ? code->expr1->where.lb->location : input_location;
  stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
			  elsestmt);

  gfc_add_expr_to_block (&if_se.pre, stmt);

  /* Finish off this statement.  */
  return gfc_finish_block (&if_se.pre);
}

tree
gfc_trans_if (gfc_code * code)
{
  stmtblock_t body;
  tree exit_label;

  /* Create exit label so it is available for trans'ing the body code.  */
  exit_label = gfc_build_label_decl (NULL_TREE);
  code->exit_label = exit_label;

  /* Translate the actual code in code->block.  */
  gfc_init_block (&body);
  gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));

  /* Add exit label.  */
  gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));

  return gfc_finish_block (&body);
}


/* Translate an arithmetic IF expression.

   IF (cond) label1, label2, label3 translates to

    if (cond <= 0)
      {
        if (cond < 0)
          goto label1;
        else // cond == 0
          goto label2;
      }
    else // cond > 0
      goto label3;

   An optimized version can be generated in case of equal labels.
   E.g., if label1 is equal to label2, we can translate it to

    if (cond <= 0)
      goto label1;
    else
      goto label3;
*/

tree
gfc_trans_arithmetic_if (gfc_code * code)
{
  gfc_se se;
  tree tmp;
  tree branch1;
  tree branch2;
  tree zero;

  /* Start a new block.  */
  gfc_init_se (&se, NULL);
  gfc_start_block (&se.pre);

  /* Pre-evaluate COND.  */
  gfc_conv_expr_val (&se, code->expr1);
  se.expr = gfc_evaluate_now (se.expr, &se.pre);

  /* Build something to compare with.  */
  zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);

  if (code->label1->value != code->label2->value)
    {
      /* If (cond < 0) take branch1 else take branch2.
         First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases.  */
      branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
      branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));

      if (code->label1->value != code->label3->value)
        tmp = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
			       se.expr, zero);
      else
        tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			       se.expr, zero);

      branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
				 tmp, branch1, branch2);
    }
  else
    branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));

  if (code->label1->value != code->label3->value
      && code->label2->value != code->label3->value)
    {
      /* if (cond <= 0) take branch1 else take branch2.  */
      branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
      tmp = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
			     se.expr, zero);
      branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
				 tmp, branch1, branch2);
    }

  /* Append the COND_EXPR to the evaluation of COND, and return.  */
  gfc_add_expr_to_block (&se.pre, branch1);
  return gfc_finish_block (&se.pre);
}


/* Translate a CRITICAL block.  */
tree
gfc_trans_critical (gfc_code *code)
{
  stmtblock_t block;
  tree tmp, token = NULL_TREE;

  gfc_start_block (&block);

  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      token = gfc_get_symbol_decl (code->resolved_sym);
      token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
				 token, integer_zero_node, integer_one_node,
				 null_pointer_node, null_pointer_node,
				 null_pointer_node, integer_zero_node);
      gfc_add_expr_to_block (&block, tmp);

      /* It guarantees memory consistency within the same segment */
      tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
	tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
			  gfc_build_string_const (1, ""),
			  NULL_TREE, NULL_TREE,
			  tree_cons (NULL_TREE, tmp, NULL_TREE),
			  NULL_TREE);
      ASM_VOLATILE_P (tmp) = 1;

      gfc_add_expr_to_block (&block, tmp);
    }

  tmp = gfc_trans_code (code->block->next);
  gfc_add_expr_to_block (&block, tmp);

  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
				 token, integer_zero_node, integer_one_node,
				 null_pointer_node, null_pointer_node,
				 integer_zero_node);
      gfc_add_expr_to_block (&block, tmp);

      /* It guarantees memory consistency within the same segment */
      tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
	tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
			  gfc_build_string_const (1, ""),
			  NULL_TREE, NULL_TREE,
			  tree_cons (NULL_TREE, tmp, NULL_TREE),
			  NULL_TREE);
      ASM_VOLATILE_P (tmp) = 1;

      gfc_add_expr_to_block (&block, tmp);
    }

  return gfc_finish_block (&block);
}


/* Return true, when the class has a _len component.  */

static bool
class_has_len_component (gfc_symbol *sym)
{
  gfc_component *comp = sym->ts.u.derived->components;
  while (comp)
    {
      if (strcmp (comp->name, "_len") == 0)
	return true;
      comp = comp->next;
    }
  return false;
}


/* Do proper initialization for ASSOCIATE names.  */

static void
trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
{
  gfc_expr *e;
  tree tmp;
  bool class_target;
  bool unlimited;
  tree desc;
  tree offset;
  tree dim;
  int n;
  tree charlen;
  bool need_len_assign;
  bool whole_array = true;
  gfc_ref *ref;

  gcc_assert (sym->assoc);
  e = sym->assoc->target;

  class_target = (e->expr_type == EXPR_VARIABLE)
		    && (gfc_is_class_scalar_expr (e)
			|| gfc_is_class_array_ref (e, NULL));

  unlimited = UNLIMITED_POLY (e);

  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type == REF_ARRAY
	&& ref->u.ar.type == AR_FULL
	&& ref->next)
      {
	whole_array =  false;
	break;
      }

  /* Assignments to the string length need to be generated, when
     ( sym is a char array or
       sym has a _len component)
     and the associated expression is unlimited polymorphic, which is
     not (yet) correctly in 'unlimited', because for an already associated
     BT_DERIVED the u-poly flag is not set, i.e.,
      __tmp_CHARACTER_0_1 => w => arg
       ^ generated temp      ^ from code, the w does not have the u-poly
     flag set, where UNLIMITED_POLY(e) expects it.  */
  need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
                     && e->ts.u.derived->attr.unlimited_polymorphic))
      && (sym->ts.type == BT_CHARACTER
          || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
              && class_has_len_component (sym))));
  /* Do a `pointer assignment' with updated descriptor (or assign descriptor
     to array temporary) for arrays with either unknown shape or if associating
     to a variable.  */
  if (sym->attr.dimension && !class_target
      && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
    {
      gfc_se se;
      tree desc;
      bool cst_array_ctor;

      desc = sym->backend_decl;
      cst_array_ctor = e->expr_type == EXPR_ARRAY
	      && gfc_constant_array_constructor_p (e->value.constructor)
	      && e->ts.type != BT_CHARACTER;

      /* If association is to an expression, evaluate it and create temporary.
	 Otherwise, get descriptor of target for pointer assignment.  */
      gfc_init_se (&se, NULL);

      if (sym->assoc->variable || cst_array_ctor)
	{
	  se.direct_byref = 1;
	  se.use_offset = 1;
	  se.expr = desc;
	  GFC_DECL_PTR_ARRAY_P (sym->backend_decl) = 1;
	}

      gfc_conv_expr_descriptor (&se, e);

      if (sym->ts.type == BT_CHARACTER
	  && !se.direct_byref && sym->ts.deferred
	  && !sym->attr.select_type_temporary
	  && VAR_P (sym->ts.u.cl->backend_decl)
	  && se.string_length != sym->ts.u.cl->backend_decl)
	{
	  gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
			  fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
					se.string_length));
	}

      /* If we didn't already do the pointer assignment, set associate-name
	 descriptor to the one generated for the temporary.  */
      if ((!sym->assoc->variable && !cst_array_ctor)
	  || !whole_array)
	{
	  int dim;

	  if (whole_array)
	    gfc_add_modify (&se.pre, desc, se.expr);

	  /* The generated descriptor has lower bound zero (as array
	     temporary), shift bounds so we get lower bounds of 1.  */
	  for (dim = 0; dim < e->rank; ++dim)
	    gfc_conv_shift_descriptor_lbound (&se.pre, desc,
					      dim, gfc_index_one_node);
	}

      /* If this is a subreference array pointer associate name use the
	 associate variable element size for the value of 'span'.  */
      if (sym->attr.subref_array_pointer && !se.direct_byref)
	{
	  gcc_assert (e->expr_type == EXPR_VARIABLE);
	  tmp = gfc_get_array_span (se.expr, e);

	  gfc_conv_descriptor_span_set (&se.pre, desc, tmp);
	}

      if (e->expr_type == EXPR_FUNCTION
	  && sym->ts.type == BT_DERIVED
	  && sym->ts.u.derived
	  && sym->ts.u.derived->attr.pdt_type)
	{
	  tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, se.expr,
					 sym->as->rank);
	  gfc_add_expr_to_block (&se.post, tmp);
	}

      /* Done, register stuff as init / cleanup code.  */
      gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
			    gfc_finish_block (&se.post));
    }

  /* Temporaries, arising from TYPE IS, just need the descriptor of class
     arrays to be assigned directly.  */
  else if (class_target && sym->attr.dimension
	   && (sym->ts.type == BT_DERIVED || unlimited))
    {
      gfc_se se;

      gfc_init_se (&se, NULL);
      se.descriptor_only = 1;
      /* In a select type the (temporary) associate variable shall point to
	 a standard fortran array (lower bound == 1), but conv_expr ()
	 just maps to the input array in the class object, whose lbound may
	 be arbitrary.  conv_expr_descriptor solves this by inserting a
	 temporary array descriptor.  */
      gfc_conv_expr_descriptor (&se, e);

      gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
		  || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
      gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));

      if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
	{
	  if (INDIRECT_REF_P (se.expr))
	    tmp = TREE_OPERAND (se.expr, 0);
	  else
	    tmp = se.expr;

	  gfc_add_modify (&se.pre, sym->backend_decl,
			  gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
	}
      else
	gfc_add_modify (&se.pre, sym->backend_decl, se.expr);

      if (unlimited)
	{
	  /* Recover the dtype, which has been overwritten by the
	     assignment from an unlimited polymorphic object.  */
	  tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
	  gfc_add_modify (&se.pre, tmp,
			  gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
	}

      gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
			    gfc_finish_block (&se.post));
    }

  /* Do a scalar pointer assignment; this is for scalar variable targets.  */
  else if (gfc_is_associate_pointer (sym))
    {
      gfc_se se;

      gcc_assert (!sym->attr.dimension);

      gfc_init_se (&se, NULL);

      /* Class associate-names come this way because they are
	 unconditionally associate pointers and the symbol is scalar.  */
      if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
	{
	  tree target_expr;
	  /* For a class array we need a descriptor for the selector.  */
	  gfc_conv_expr_descriptor (&se, e);
	  /* Needed to get/set the _len component below.  */
	  target_expr = se.expr;

	  /* Obtain a temporary class container for the result.  */
	  gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
	  se.expr = build_fold_indirect_ref_loc (input_location, se.expr);

	  /* Set the offset.  */
	  desc = gfc_class_data_get (se.expr);
	  offset = gfc_index_zero_node;
	  for (n = 0; n < e->rank; n++)
	    {
	      dim = gfc_rank_cst[n];
	      tmp = fold_build2_loc (input_location, MULT_EXPR,
				     gfc_array_index_type,
				     gfc_conv_descriptor_stride_get (desc, dim),
				     gfc_conv_descriptor_lbound_get (desc, dim));
	      offset = fold_build2_loc (input_location, MINUS_EXPR,
				        gfc_array_index_type,
				        offset, tmp);
	    }
	  if (need_len_assign)
	    {
	      if (e->symtree
		  && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
		  && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl)
		  && TREE_CODE (target_expr) != COMPONENT_REF)
		/* Use the original class descriptor stored in the saved
		   descriptor to get the target_expr.  */
		target_expr =
		    GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
	      else
		/* Strip the _data component from the target_expr.  */
		target_expr = TREE_OPERAND (target_expr, 0);
	      /* Add a reference to the _len comp to the target expr.  */
	      tmp = gfc_class_len_get (target_expr);
	      /* Get the component-ref for the temp structure's _len comp.  */
	      charlen = gfc_class_len_get (se.expr);
	      /* Add the assign to the beginning of the block...  */
	      gfc_add_modify (&se.pre, charlen,
			      fold_convert (TREE_TYPE (charlen), tmp));
	      /* and the oposite way at the end of the block, to hand changes
		 on the string length back.  */
	      gfc_add_modify (&se.post, tmp,
			      fold_convert (TREE_TYPE (tmp), charlen));
	      /* Length assignment done, prevent adding it again below.  */
	      need_len_assign = false;
	    }
	  gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
	}
      else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
	       && CLASS_DATA (e)->attr.dimension)
	{
	  /* This is bound to be a class array element.  */
	  gfc_conv_expr_reference (&se, e);
	  /* Get the _vptr component of the class object.  */
	  tmp = gfc_get_vptr_from_expr (se.expr);
	  /* Obtain a temporary class container for the result.  */
	  gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
	  se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
	}
      else
	{
	  /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
	     which has the string length included.  For CHARACTERS it is still
	     needed and will be done at the end of this routine.  */
	  gfc_conv_expr (&se, e);
	  need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
	}

      if (sym->ts.type == BT_CHARACTER
	  && !sym->attr.select_type_temporary
	  && VAR_P (sym->ts.u.cl->backend_decl)
	  && se.string_length != sym->ts.u.cl->backend_decl)
	{
	  gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
			  fold_convert (TREE_TYPE (sym->ts.u.cl->backend_decl),
					se.string_length));
	  if (e->expr_type == EXPR_FUNCTION)
	    {
	      tmp = gfc_call_free (sym->backend_decl);
	      gfc_add_expr_to_block (&se.post, tmp);
	    }
	}

      if (sym->ts.type == BT_CHARACTER && e->ts.type == BT_CHARACTER
	  && POINTER_TYPE_P (TREE_TYPE (se.expr)))
	{
	  /* These are pointer types already.  */
	  tmp = fold_convert (TREE_TYPE (sym->backend_decl), se.expr);
	}
      else
	{
	  tmp = TREE_TYPE (sym->backend_decl);
	  tmp = gfc_build_addr_expr (tmp, se.expr);
	}

      gfc_add_modify (&se.pre, sym->backend_decl, tmp);

      gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
			    gfc_finish_block (&se.post));
    }

  /* Do a simple assignment.  This is for scalar expressions, where we
     can simply use expression assignment.  */
  else
    {
      gfc_expr *lhs;
      tree res;
      gfc_se se;

      gfc_init_se (&se, NULL);

      /* resolve.c converts some associate names to allocatable so that
	 allocation can take place automatically in gfc_trans_assignment.
	 The frontend prevents them from being either allocated,
	 deallocated or reallocated.  */
      if (sym->attr.allocatable)
	{
	  tmp = sym->backend_decl;
	  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
	    tmp = gfc_conv_descriptor_data_get (tmp);
	  gfc_add_modify (&se.pre, tmp, fold_convert (TREE_TYPE (tmp),
						    null_pointer_node));
	}

      lhs = gfc_lval_expr_from_sym (sym);
      res = gfc_trans_assignment (lhs, e, false, true);
      gfc_add_expr_to_block (&se.pre, res);

      tmp = sym->backend_decl;
      if (e->expr_type == EXPR_FUNCTION
	  && sym->ts.type == BT_DERIVED
	  && sym->ts.u.derived
	  && sym->ts.u.derived->attr.pdt_type)
	{
	  tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived, tmp,
					 0);
	}
      else if (e->expr_type == EXPR_FUNCTION
	       && sym->ts.type == BT_CLASS
	       && CLASS_DATA (sym)->ts.u.derived
	       && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type)
	{
	  tmp = gfc_class_data_get (tmp);
	  tmp = gfc_deallocate_pdt_comp (CLASS_DATA (sym)->ts.u.derived,
					 tmp, 0);
	}
      else if (sym->attr.allocatable)
	{
	  tmp = sym->backend_decl;

	  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
	    tmp = gfc_conv_descriptor_data_get (tmp);

	  /* A simple call to free suffices here.  */
	  tmp = gfc_call_free (tmp);

	  /* Make sure that reallocation on assignment cannot occur.  */
	  sym->attr.allocatable = 0;
	}
      else
	tmp = NULL_TREE;

      res = gfc_finish_block (&se.pre);
      gfc_add_init_cleanup (block, res, tmp);
      gfc_free_expr (lhs);
    }

  /* Set the stringlength, when needed.  */
  if (need_len_assign)
    {
      gfc_se se;
      gfc_init_se (&se, NULL);
      if (e->symtree->n.sym->ts.type == BT_CHARACTER)
	{
	  /* Deferred strings are dealt with in the preceeding.  */
	  gcc_assert (!e->symtree->n.sym->ts.deferred);
	  tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
	}
      else if (e->symtree->n.sym->attr.function
	       && e->symtree->n.sym == e->symtree->n.sym->result)
	{
	  tmp = gfc_get_fake_result_decl (e->symtree->n.sym, 0);
	  tmp = gfc_class_len_get (tmp);
	}
      else
	tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
      gfc_get_symbol_decl (sym);
      charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
					: gfc_class_len_get (sym->backend_decl);
      /* Prevent adding a noop len= len.  */
      if (tmp != charlen)
	{
	  gfc_add_modify (&se.pre, charlen,
			  fold_convert (TREE_TYPE (charlen), tmp));
	  gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
				gfc_finish_block (&se.post));
	}
    }
}


/* Translate a BLOCK construct.  This is basically what we would do for a
   procedure body.  */

tree
gfc_trans_block_construct (gfc_code* code)
{
  gfc_namespace* ns;
  gfc_symbol* sym;
  gfc_wrapped_block block;
  tree exit_label;
  stmtblock_t body;
  gfc_association_list *ass;

  ns = code->ext.block.ns;
  gcc_assert (ns);
  sym = ns->proc_name;
  gcc_assert (sym);

  /* Process local variables.  */
  gcc_assert (!sym->tlink);
  sym->tlink = sym;
  gfc_process_block_locals (ns);

  /* Generate code including exit-label.  */
  gfc_init_block (&body);
  exit_label = gfc_build_label_decl (NULL_TREE);
  code->exit_label = exit_label;

  finish_oacc_declare (ns, sym, true);

  gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
  gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));

  /* Finish everything.  */
  gfc_start_wrapped_block (&block, gfc_finish_block (&body));
  gfc_trans_deferred_vars (sym, &block);
  for (ass = code->ext.block.assoc; ass; ass = ass->next)
    trans_associate_var (ass->st->n.sym, &block);

  return gfc_finish_wrapped_block (&block);
}

/* Translate the simple DO construct in a C-style manner.
   This is where the loop variable has integer type and step +-1.
   Following code will generate infinite loop in case where TO is INT_MAX
   (for +1 step) or INT_MIN (for -1 step)

   We translate a do loop from:

   DO dovar = from, to, step
      body
   END DO

   to:

   [Evaluate loop bounds and step]
    dovar = from;
    for (;;)
      {
	if (dovar > to)
	  goto end_label;
	body;
	cycle_label:
	dovar += step;
      }
    end_label:

   This helps the optimizers by avoiding the extra pre-header condition and
   we save a register as we just compare the updated IV (not a value in
   previous step).  */

static tree
gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
		     tree from, tree to, tree step, tree exit_cond)
{
  stmtblock_t body;
  tree type;
  tree cond;
  tree tmp;
  tree saved_dovar = NULL;
  tree cycle_label;
  tree exit_label;
  location_t loc;
  type = TREE_TYPE (dovar);
  bool is_step_positive = tree_int_cst_sgn (step) > 0;

  loc = code->ext.iterator->start->where.lb->location;

  /* Initialize the DO variable: dovar = from.  */
  gfc_add_modify_loc (loc, pblock, dovar,
		      fold_convert (TREE_TYPE (dovar), from));

  /* Save value for do-tinkering checking.  */
  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
    {
      saved_dovar = gfc_create_var (type, ".saved_dovar");
      gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
    }

  /* Cycle and exit statements are implemented with gotos.  */
  cycle_label = gfc_build_label_decl (NULL_TREE);
  exit_label = gfc_build_label_decl (NULL_TREE);

  /* Put the labels where they can be found later.  See gfc_trans_do().  */
  code->cycle_label = cycle_label;
  code->exit_label = exit_label;

  /* Loop body.  */
  gfc_start_block (&body);

  /* Exit the loop if there is an I/O result condition or error.  */
  if (exit_cond)
    {
      tmp = build1_v (GOTO_EXPR, exit_label);
      tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
			     exit_cond, tmp,
			     build_empty_stmt (loc));
      gfc_add_expr_to_block (&body, tmp);
    }

  /* Evaluate the loop condition.  */
  if (is_step_positive)
    cond = fold_build2_loc (loc, GT_EXPR, logical_type_node, dovar,
			    fold_convert (type, to));
  else
    cond = fold_build2_loc (loc, LT_EXPR, logical_type_node, dovar,
			    fold_convert (type, to));

  cond = gfc_evaluate_now_loc (loc, cond, &body);
  if (code->ext.iterator->unroll && cond != error_mark_node)
    cond
      = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
		build_int_cst (integer_type_node, annot_expr_unroll_kind),
		build_int_cst (integer_type_node, code->ext.iterator->unroll));

  /* The loop exit.  */
  tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
  TREE_USED (exit_label) = 1;
  tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
			 cond, tmp, build_empty_stmt (loc));
  gfc_add_expr_to_block (&body, tmp);

  /* Check whether the induction variable is equal to INT_MAX
     (respectively to INT_MIN).  */
  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
    {
      tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
	: TYPE_MIN_VALUE (type);

      tmp = fold_build2_loc (loc, EQ_EXPR, logical_type_node,
			     dovar, boundary);
      gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
			       "Loop iterates infinitely");
    }

  /* Main loop body.  */
  tmp = gfc_trans_code_cond (code->block->next, exit_cond);
  gfc_add_expr_to_block (&body, tmp);

  /* Label for cycle statements (if needed).  */
  if (TREE_USED (cycle_label))
    {
      tmp = build1_v (LABEL_EXPR, cycle_label);
      gfc_add_expr_to_block (&body, tmp);
    }

  /* Check whether someone has modified the loop variable.  */
  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
    {
      tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node,
			     dovar, saved_dovar);
      gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
			       "Loop variable has been modified");
    }

  /* Increment the loop variable.  */
  tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
  gfc_add_modify_loc (loc, &body, dovar, tmp);

  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
    gfc_add_modify_loc (loc, &body, saved_dovar, dovar);

  /* Finish the loop body.  */
  tmp = gfc_finish_block (&body);
  tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);

  gfc_add_expr_to_block (pblock, tmp);

  /* Add the exit label.  */
  tmp = build1_v (LABEL_EXPR, exit_label);
  gfc_add_expr_to_block (pblock, tmp);

  return gfc_finish_block (pblock);
}

/* Translate the DO construct.  This obviously is one of the most
   important ones to get right with any compiler, but especially
   so for Fortran.

   We special case some loop forms as described in gfc_trans_simple_do.
   For other cases we implement them with a separate loop count,
   as described in the standard.

   We translate a do loop from:

   DO dovar = from, to, step
      body
   END DO

   to:

   [evaluate loop bounds and step]
   empty = (step > 0 ? to < from : to > from);
   countm1 = (to - from) / step;
   dovar = from;
   if (empty) goto exit_label;
   for (;;)
     {
       body;
cycle_label:
       dovar += step
       countm1t = countm1;
       countm1--;
       if (countm1t == 0) goto exit_label;
     }
exit_label:

   countm1 is an unsigned integer.  It is equal to the loop count minus one,
   because the loop count itself can overflow.  */

tree
gfc_trans_do (gfc_code * code, tree exit_cond)
{
  gfc_se se;
  tree dovar;
  tree saved_dovar = NULL;
  tree from;
  tree to;
  tree step;
  tree countm1;
  tree type;
  tree utype;
  tree cond;
  tree cycle_label;
  tree exit_label;
  tree tmp;
  stmtblock_t block;
  stmtblock_t body;
  location_t loc;

  gfc_start_block (&block);

  loc = code->ext.iterator->start->where.lb->location;

  /* Evaluate all the expressions in the iterator.  */
  gfc_init_se (&se, NULL);
  gfc_conv_expr_lhs (&se, code->ext.iterator->var);
  gfc_add_block_to_block (&block, &se.pre);
  dovar = se.expr;
  type = TREE_TYPE (dovar);

  gfc_init_se (&se, NULL);
  gfc_conv_expr_val (&se, code->ext.iterator->start);
  gfc_add_block_to_block (&block, &se.pre);
  from = gfc_evaluate_now (se.expr, &block);

  gfc_init_se (&se, NULL);
  gfc_conv_expr_val (&se, code->ext.iterator->end);
  gfc_add_block_to_block (&block, &se.pre);
  to = gfc_evaluate_now (se.expr, &block);

  gfc_init_se (&se, NULL);
  gfc_conv_expr_val (&se, code->ext.iterator->step);
  gfc_add_block_to_block (&block, &se.pre);
  step = gfc_evaluate_now (se.expr, &block);

  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
    {
      tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, step,
			     build_zero_cst (type));
      gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
			       "DO step value is zero");
    }

  /* Special case simple loops.  */
  if (TREE_CODE (type) == INTEGER_TYPE
      && (integer_onep (step)
	|| tree_int_cst_equal (step, integer_minus_one_node)))
    return gfc_trans_simple_do (code, &block, dovar, from, to, step,
				exit_cond);

  if (TREE_CODE (type) == INTEGER_TYPE)
    utype = unsigned_type_for (type);
  else
    utype = unsigned_type_for (gfc_array_index_type);
  countm1 = gfc_create_var (utype, "countm1");

  /* Cycle and exit statements are implemented with gotos.  */
  cycle_label = gfc_build_label_decl (NULL_TREE);
  exit_label = gfc_build_label_decl (NULL_TREE);
  TREE_USED (exit_label) = 1;

  /* Put these labels where they can be found later.  */
  code->cycle_label = cycle_label;
  code->exit_label = exit_label;

  /* Initialize the DO variable: dovar = from.  */
  gfc_add_modify (&block, dovar, from);

  /* Save value for do-tinkering checking.  */
  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
    {
      saved_dovar = gfc_create_var (type, ".saved_dovar");
      gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
    }

  /* Initialize loop count and jump to exit label if the loop is empty.
     This code is executed before we enter the loop body. We generate:
     if (step > 0)
       {
	 countm1 = (to - from) / step;
	 if (to < from)
	   goto exit_label;
       }
     else
       {
	 countm1 = (from - to) / -step;
	 if (to > from)
	   goto exit_label;
       }
   */

  if (TREE_CODE (type) == INTEGER_TYPE)
    {
      tree pos, neg, tou, fromu, stepu, tmp2;

      /* The distance from FROM to TO cannot always be represented in a signed
         type, thus use unsigned arithmetic, also to avoid any undefined
	 overflow issues.  */
      tou = fold_convert (utype, to);
      fromu = fold_convert (utype, from);
      stepu = fold_convert (utype, step);

      /* For a positive step, when to < from, exit, otherwise compute
         countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step  */
      tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, to, from);
      tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
			      fold_build2_loc (loc, MINUS_EXPR, utype,
					       tou, fromu),
			      stepu);
      pos = build2 (COMPOUND_EXPR, void_type_node,
		    fold_build2 (MODIFY_EXPR, void_type_node,
				 countm1, tmp2),
		    build3_loc (loc, COND_EXPR, void_type_node,
				gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
				build1_loc (loc, GOTO_EXPR, void_type_node,
					    exit_label), NULL_TREE));

      /* For a negative step, when to > from, exit, otherwise compute
         countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step  */
      tmp = fold_build2_loc (loc, GT_EXPR, logical_type_node, to, from);
      tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
			      fold_build2_loc (loc, MINUS_EXPR, utype,
					       fromu, tou),
			      fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
      neg = build2 (COMPOUND_EXPR, void_type_node,
		    fold_build2 (MODIFY_EXPR, void_type_node,
				 countm1, tmp2),
		    build3_loc (loc, COND_EXPR, void_type_node,
				gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
				build1_loc (loc, GOTO_EXPR, void_type_node,
					    exit_label), NULL_TREE));

      tmp = fold_build2_loc (loc, LT_EXPR, logical_type_node, step,
			     build_int_cst (TREE_TYPE (step), 0));
      tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);

      gfc_add_expr_to_block (&block, tmp);
    }
  else
    {
      tree pos_step;

      /* TODO: We could use the same width as the real type.
	 This would probably cause more problems that it solves
	 when we implement "long double" types.  */

      tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
      tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
      tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
      gfc_add_modify (&block, countm1, tmp);

      /* We need a special check for empty loops:
	 empty = (step > 0 ? to < from : to > from);  */
      pos_step = fold_build2_loc (loc, GT_EXPR, logical_type_node, step,
				  build_zero_cst (type));
      tmp = fold_build3_loc (loc, COND_EXPR, logical_type_node, pos_step,
			     fold_build2_loc (loc, LT_EXPR,
					      logical_type_node, to, from),
			     fold_build2_loc (loc, GT_EXPR,
					      logical_type_node, to, from));
      /* If the loop is empty, go directly to the exit label.  */
      tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
			 build1_v (GOTO_EXPR, exit_label),
			 build_empty_stmt (input_location));
      gfc_add_expr_to_block (&block, tmp);
    }

  /* Loop body.  */
  gfc_start_block (&body);

  /* Main loop body.  */
  tmp = gfc_trans_code_cond (code->block->next, exit_cond);
  gfc_add_expr_to_block (&body, tmp);

  /* Label for cycle statements (if needed).  */
  if (TREE_USED (cycle_label))
    {
      tmp = build1_v (LABEL_EXPR, cycle_label);
      gfc_add_expr_to_block (&body, tmp);
    }

  /* Check whether someone has modified the loop variable.  */
  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
    {
      tmp = fold_build2_loc (loc, NE_EXPR, logical_type_node, dovar,
			     saved_dovar);
      gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
			       "Loop variable has been modified");
    }

  /* Exit the loop if there is an I/O result condition or error.  */
  if (exit_cond)
    {
      tmp = build1_v (GOTO_EXPR, exit_label);
      tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
			     exit_cond, tmp,
			     build_empty_stmt (input_location));
      gfc_add_expr_to_block (&body, tmp);
    }

  /* Increment the loop variable.  */
  tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
  gfc_add_modify_loc (loc, &body, dovar, tmp);

  if (gfc_option.rtcheck & GFC_RTCHECK_DO)
    gfc_add_modify_loc (loc, &body, saved_dovar, dovar);

  /* Initialize countm1t.  */
  tree countm1t = gfc_create_var (utype, "countm1t");
  gfc_add_modify_loc (loc, &body, countm1t, countm1);

  /* Decrement the loop count.  */
  tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
			 build_int_cst (utype, 1));
  gfc_add_modify_loc (loc, &body, countm1, tmp);

  /* End with the loop condition.  Loop until countm1t == 0.  */
  cond = fold_build2_loc (loc, EQ_EXPR, logical_type_node, countm1t,
			  build_int_cst (utype, 0));
  if (code->ext.iterator->unroll && cond != error_mark_node)
    cond
      = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
		build_int_cst (integer_type_node, annot_expr_unroll_kind),
		build_int_cst (integer_type_node, code->ext.iterator->unroll));
  tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
  tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
			 cond, tmp, build_empty_stmt (loc));
  gfc_add_expr_to_block (&body, tmp);

  /* End of loop body.  */
  tmp = gfc_finish_block (&body);

  /* The for loop itself.  */
  tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
  gfc_add_expr_to_block (&block, tmp);

  /* Add the exit label.  */
  tmp = build1_v (LABEL_EXPR, exit_label);
  gfc_add_expr_to_block (&block, tmp);

  return gfc_finish_block (&block);
}


/* Translate the DO WHILE construct.

   We translate

   DO WHILE (cond)
      body
   END DO

   to:

   for ( ; ; )
     {
       pre_cond;
       if (! cond) goto exit_label;
       body;
cycle_label:
     }
exit_label:

   Because the evaluation of the exit condition `cond' may have side
   effects, we can't do much for empty loop bodies.  The backend optimizers
   should be smart enough to eliminate any dead loops.  */

tree
gfc_trans_do_while (gfc_code * code)
{
  gfc_se cond;
  tree tmp;
  tree cycle_label;
  tree exit_label;
  stmtblock_t block;

  /* Everything we build here is part of the loop body.  */
  gfc_start_block (&block);

  /* Cycle and exit statements are implemented with gotos.  */
  cycle_label = gfc_build_label_decl (NULL_TREE);
  exit_label = gfc_build_label_decl (NULL_TREE);

  /* Put the labels where they can be found later. See gfc_trans_do().  */
  code->cycle_label = cycle_label;
  code->exit_label = exit_label;

  /* Create a GIMPLE version of the exit condition.  */
  gfc_init_se (&cond, NULL);
  gfc_conv_expr_val (&cond, code->expr1);
  gfc_add_block_to_block (&block, &cond.pre);
  cond.expr = fold_build1_loc (code->expr1->where.lb->location,
			       TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);

  /* Build "IF (! cond) GOTO exit_label".  */
  tmp = build1_v (GOTO_EXPR, exit_label);
  TREE_USED (exit_label) = 1;
  tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
			 void_type_node, cond.expr, tmp,
			 build_empty_stmt (code->expr1->where.lb->location));
  gfc_add_expr_to_block (&block, tmp);

  /* The main body of the loop.  */
  tmp = gfc_trans_code (code->block->next);
  gfc_add_expr_to_block (&block, tmp);

  /* Label for cycle statements (if needed).  */
  if (TREE_USED (cycle_label))
    {
      tmp = build1_v (LABEL_EXPR, cycle_label);
      gfc_add_expr_to_block (&block, tmp);
    }

  /* End of loop body.  */
  tmp = gfc_finish_block (&block);

  gfc_init_block (&block);
  /* Build the loop.  */
  tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
			 void_type_node, tmp);
  gfc_add_expr_to_block (&block, tmp);

  /* Add the exit label.  */
  tmp = build1_v (LABEL_EXPR, exit_label);
  gfc_add_expr_to_block (&block, tmp);

  return gfc_finish_block (&block);
}


/* Deal with the particular case of SELECT_TYPE, where the vtable
   addresses are used for the selection. Since these are not sorted,
   the selection has to be made by a series of if statements.  */

static tree
gfc_trans_select_type_cases (gfc_code * code)
{
  gfc_code *c;
  gfc_case *cp;
  tree tmp;
  tree cond;
  tree low;
  tree high;
  gfc_se se;
  gfc_se cse;
  stmtblock_t block;
  stmtblock_t body;
  bool def = false;
  gfc_expr *e;
  gfc_start_block (&block);

  /* Calculate the switch expression.  */
  gfc_init_se (&se, NULL);
  gfc_conv_expr_val (&se, code->expr1);
  gfc_add_block_to_block (&block, &se.pre);

  /* Generate an expression for the selector hash value, for
     use to resolve character cases.  */
  e = gfc_copy_expr (code->expr1->value.function.actual->expr);
  gfc_add_hash_component (e);

  TREE_USED (code->exit_label) = 0;

repeat:
  for (c = code->block; c; c = c->block)
    {
      cp = c->ext.block.case_list;

      /* Assume it's the default case.  */
      low = NULL_TREE;
      high = NULL_TREE;
      tmp = NULL_TREE;

      /* Put the default case at the end.  */
      if ((!def && !cp->low) || (def && cp->low))
	continue;

      if (cp->low && (cp->ts.type == BT_CLASS
		      || cp->ts.type == BT_DERIVED))
	{
	  gfc_init_se (&cse, NULL);
	  gfc_conv_expr_val (&cse, cp->low);
	  gfc_add_block_to_block (&block, &cse.pre);
	  low = cse.expr;
	}
      else if (cp->ts.type != BT_UNKNOWN)
	{
	  gcc_assert (cp->high);
	  gfc_init_se (&cse, NULL);
	  gfc_conv_expr_val (&cse, cp->high);
	  gfc_add_block_to_block (&block, &cse.pre);
	  high = cse.expr;
	}

      gfc_init_block (&body);

      /* Add the statements for this case.  */
      tmp = gfc_trans_code (c->next);
      gfc_add_expr_to_block (&body, tmp);

      /* Break to the end of the SELECT TYPE construct.  The default
	 case just falls through.  */
      if (!def)
	{
	  TREE_USED (code->exit_label) = 1;
	  tmp = build1_v (GOTO_EXPR, code->exit_label);
	  gfc_add_expr_to_block (&body, tmp);
	}

      tmp = gfc_finish_block (&body);

      if (low != NULL_TREE)
	{
	  /* Compare vtable pointers.  */
	  cond = fold_build2_loc (input_location, EQ_EXPR,
				  TREE_TYPE (se.expr), se.expr, low);
	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
				 cond, tmp,
				 build_empty_stmt (input_location));
	}
      else if (high != NULL_TREE)
	{
	  /* Compare hash values for character cases.  */
	  gfc_init_se (&cse, NULL);
	  gfc_conv_expr_val (&cse, e);
	  gfc_add_block_to_block (&block, &cse.pre);

	  cond = fold_build2_loc (input_location, EQ_EXPR,
				  TREE_TYPE (se.expr), high, cse.expr);
	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
				 cond, tmp,
				 build_empty_stmt (input_location));
	}

      gfc_add_expr_to_block (&block, tmp);
    }

  if (!def)
    {
      def = true;
      goto repeat;
    }

  gfc_free_expr (e);

  return gfc_finish_block (&block);
}


/* Translate the SELECT CASE construct for INTEGER case expressions,
   without killing all potential optimizations.  The problem is that
   Fortran allows unbounded cases, but the back-end does not, so we
   need to intercept those before we enter the equivalent SWITCH_EXPR
   we can build.

   For example, we translate this,

   SELECT CASE (expr)
      CASE (:100,101,105:115)
	 block_1
      CASE (190:199,200:)
	 block_2
      CASE (300)
	 block_3
      CASE DEFAULT
	 block_4
   END SELECT

   to the GENERIC equivalent,

     switch (expr)
       {
	 case (minimum value for typeof(expr) ... 100:
	 case 101:
	 case 105 ... 114:
	   block1:
	   goto end_label;

	 case 200 ... (maximum value for typeof(expr):
	 case 190 ... 199:
	   block2;
	   goto end_label;

	 case 300:
	   block_3;
	   goto end_label;

	 default:
	   block_4;
	   goto end_label;
       }

     end_label:  */

static tree
gfc_trans_integer_select (gfc_code * code)
{
  gfc_code *c;
  gfc_case *cp;
  tree end_label;
  tree tmp;
  gfc_se se;
  stmtblock_t block;
  stmtblock_t body;

  gfc_start_block (&block);

  /* Calculate the switch expression.  */
  gfc_init_se (&se, NULL);
  gfc_conv_expr_val (&se, code->expr1);
  gfc_add_block_to_block (&block, &se.pre);

  end_label = gfc_build_label_decl (NULL_TREE);

  gfc_init_block (&body);

  for (c = code->block; c; c = c->block)
    {
      for (cp = c->ext.block.case_list; cp; cp = cp->next)
	{
	  tree low, high;
          tree label;

	  /* Assume it's the default case.  */
	  low = high = NULL_TREE;

	  if (cp->low)
	    {
	      low = gfc_conv_mpz_to_tree (cp->low->value.integer,
					  cp->low->ts.kind);

	      /* If there's only a lower bound, set the high bound to the
		 maximum value of the case expression.  */
	      if (!cp->high)
		high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
	    }

	  if (cp->high)
	    {
	      /* Three cases are possible here:

		 1) There is no lower bound, e.g. CASE (:N).
		 2) There is a lower bound .NE. high bound, that is
		    a case range, e.g. CASE (N:M) where M>N (we make
		    sure that M>N during type resolution).
		 3) There is a lower bound, and it has the same value
		    as the high bound, e.g. CASE (N:N).  This is our
		    internal representation of CASE(N).

		 In the first and second case, we need to set a value for
		 high.  In the third case, we don't because the GCC middle
		 end represents a single case value by just letting high be
		 a NULL_TREE.  We can't do that because we need to be able
		 to represent unbounded cases.  */

	      if (!cp->low
		  || (mpz_cmp (cp->low->value.integer,
				cp->high->value.integer) != 0))
		high = gfc_conv_mpz_to_tree (cp->high->value.integer,
					     cp->high->ts.kind);

	      /* Unbounded case.  */
	      if (!cp->low)
		low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
	    }

          /* Build a label.  */
          label = gfc_build_label_decl (NULL_TREE);

	  /* Add this case label.
             Add parameter 'label', make it match GCC backend.  */
	  tmp = build_case_label (low, high, label);
	  gfc_add_expr_to_block (&body, tmp);
	}

      /* Add the statements for this case.  */
      tmp = gfc_trans_code (c->next);
      gfc_add_expr_to_block (&body, tmp);

      /* Break to the end of the construct.  */
      tmp = build1_v (GOTO_EXPR, end_label);
      gfc_add_expr_to_block (&body, tmp);
    }

  tmp = gfc_finish_block (&body);
  tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, se.expr, tmp);
  gfc_add_expr_to_block (&block, tmp);

  tmp = build1_v (LABEL_EXPR, end_label);
  gfc_add_expr_to_block (&block, tmp);

  return gfc_finish_block (&block);
}


/* Translate the SELECT CASE construct for LOGICAL case expressions.

   There are only two cases possible here, even though the standard
   does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
   .FALSE., and DEFAULT.

   We never generate more than two blocks here.  Instead, we always
   try to eliminate the DEFAULT case.  This way, we can translate this
   kind of SELECT construct to a simple

   if {} else {};

   expression in GENERIC.  */

static tree
gfc_trans_logical_select (gfc_code * code)
{
  gfc_code *c;
  gfc_code *t, *f, *d;
  gfc_case *cp;
  gfc_se se;
  stmtblock_t block;

  /* Assume we don't have any cases at all.  */
  t = f = d = NULL;

  /* Now see which ones we actually do have.  We can have at most two
     cases in a single case list: one for .TRUE. and one for .FALSE.
     The default case is always separate.  If the cases for .TRUE. and
     .FALSE. are in the same case list, the block for that case list
     always executed, and we don't generate code a COND_EXPR.  */
  for (c = code->block; c; c = c->block)
    {
      for (cp = c->ext.block.case_list; cp; cp = cp->next)
	{
	  if (cp->low)
	    {
	      if (cp->low->value.logical == 0) /* .FALSE.  */
		f = c;
	      else /* if (cp->value.logical != 0), thus .TRUE.  */
		t = c;
	    }
	  else
	    d = c;
	}
    }

  /* Start a new block.  */
  gfc_start_block (&block);

  /* Calculate the switch expression.  We always need to do this
     because it may have side effects.  */
  gfc_init_se (&se, NULL);
  gfc_conv_expr_val (&se, code->expr1);
  gfc_add_block_to_block (&block, &se.pre);

  if (t == f && t != NULL)
    {
      /* Cases for .TRUE. and .FALSE. are in the same block.  Just
         translate the code for these cases, append it to the current
         block.  */
      gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
    }
  else
    {
      tree true_tree, false_tree, stmt;

      true_tree = build_empty_stmt (input_location);
      false_tree = build_empty_stmt (input_location);

      /* If we have a case for .TRUE. and for .FALSE., discard the default case.
          Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
          make the missing case the default case.  */
      if (t != NULL && f != NULL)
	d = NULL;
      else if (d != NULL)
        {
	  if (t == NULL)
	    t = d;
	  else
	    f = d;
	}

      /* Translate the code for each of these blocks, and append it to
         the current block.  */
      if (t != NULL)
        true_tree = gfc_trans_code (t->next);

      if (f != NULL)
	false_tree = gfc_trans_code (f->next);

      stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
			      se.expr, true_tree, false_tree);
      gfc_add_expr_to_block (&block, stmt);
    }

  return gfc_finish_block (&block);
}


/* The jump table types are stored in static variables to avoid
   constructing them from scratch every single time.  */
static GTY(()) tree select_struct[2];

/* Translate the SELECT CASE construct for CHARACTER case expressions.
   Instead of generating compares and jumps, it is far simpler to
   generate a data structure describing the cases in order and call a
   library subroutine that locates the right case.
   This is particularly true because this is the only case where we
   might have to dispose of a temporary.
   The library subroutine returns a pointer to jump to or NULL if no
   branches are to be taken.  */

static tree
gfc_trans_character_select (gfc_code *code)
{
  tree init, end_label, tmp, type, case_num, label, fndecl;
  stmtblock_t block, body;
  gfc_case *cp, *d;
  gfc_code *c;
  gfc_se se, expr1se;
  int n, k;
  vec<constructor_elt, va_gc> *inits = NULL;

  tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);

  /* The jump table types are stored in static variables to avoid
     constructing them from scratch every single time.  */
  static tree ss_string1[2], ss_string1_len[2];
  static tree ss_string2[2], ss_string2_len[2];
  static tree ss_target[2];

  cp = code->block->ext.block.case_list;
  while (cp->left != NULL)
    cp = cp->left;

  /* Generate the body */
  gfc_start_block (&block);
  gfc_init_se (&expr1se, NULL);
  gfc_conv_expr_reference (&expr1se, code->expr1);

  gfc_add_block_to_block (&block, &expr1se.pre);

  end_label = gfc_build_label_decl (NULL_TREE);

  gfc_init_block (&body);

  /* Attempt to optimize length 1 selects.  */
  if (integer_onep (expr1se.string_length))
    {
      for (d = cp; d; d = d->right)
	{
	  gfc_charlen_t i;
	  if (d->low)
	    {
	      gcc_assert (d->low->expr_type == EXPR_CONSTANT
			  && d->low->ts.type == BT_CHARACTER);
	      if (d->low->value.character.length > 1)
		{
		  for (i = 1; i < d->low->value.character.length; i++)
		    if (d->low->value.character.string[i] != ' ')
		      break;
		  if (i != d->low->value.character.length)
		    {
		      if (optimize && d->high && i == 1)
			{
			  gcc_assert (d->high->expr_type == EXPR_CONSTANT
				      && d->high->ts.type == BT_CHARACTER);
			  if (d->high->value.character.length > 1
			      && (d->low->value.character.string[0]
				  == d->high->value.character.string[0])
			      && d->high->value.character.string[1] != ' '
			      && ((d->low->value.character.string[1] < ' ')
				  == (d->high->value.character.string[1]
				      < ' ')))
			    continue;
			}
		      break;
		    }
		}
	    }
	  if (d->high)
	    {
	      gcc_assert (d->high->expr_type == EXPR_CONSTANT
			  && d->high->ts.type == BT_CHARACTER);
	      if (d->high->value.character.length > 1)
		{
		  for (i = 1; i < d->high->value.character.length; i++)
		    if (d->high->value.character.string[i] != ' ')
		      break;
		  if (i != d->high->value.character.length)
		    break;
		}
	    }
	}
      if (d == NULL)
	{
	  tree ctype = gfc_get_char_type (code->expr1->ts.kind);

	  for (c = code->block; c; c = c->block)
	    {
	      for (cp = c->ext.block.case_list; cp; cp = cp->next)
		{
		  tree low, high;
		  tree label;
		  gfc_char_t r;

		  /* Assume it's the default case.  */
		  low = high = NULL_TREE;

		  if (cp->low)
		    {
		      /* CASE ('ab') or CASE ('ab':'az') will never match
			 any length 1 character.  */
		      if (cp->low->value.character.length > 1
			  && cp->low->value.character.string[1] != ' ')
			continue;

		      if (cp->low->value.character.length > 0)
			r = cp->low->value.character.string[0];
		      else
			r = ' ';
		      low = build_int_cst (ctype, r);

		      /* If there's only a lower bound, set the high bound
			 to the maximum value of the case expression.  */
		      if (!cp->high)
			high = TYPE_MAX_VALUE (ctype);
		    }

		  if (cp->high)
		    {
		      if (!cp->low
			  || (cp->low->value.character.string[0]
			      != cp->high->value.character.string[0]))
			{
			  if (cp->high->value.character.length > 0)
			    r = cp->high->value.character.string[0];
			  else
			    r = ' ';
			  high = build_int_cst (ctype, r);
			}

		      /* Unbounded case.  */
		      if (!cp->low)
			low = TYPE_MIN_VALUE (ctype);
		    }

		  /* Build a label.  */
		  label = gfc_build_label_decl (NULL_TREE);

		  /* Add this case label.
		     Add parameter 'label', make it match GCC backend.  */
		  tmp = build_case_label (low, high, label);
		  gfc_add_expr_to_block (&body, tmp);
		}

	      /* Add the statements for this case.  */
	      tmp = gfc_trans_code (c->next);
	      gfc_add_expr_to_block (&body, tmp);

	      /* Break to the end of the construct.  */
	      tmp = build1_v (GOTO_EXPR, end_label);
	      gfc_add_expr_to_block (&body, tmp);
	    }

	  tmp = gfc_string_to_single_character (expr1se.string_length,
						expr1se.expr,
						code->expr1->ts.kind);
	  case_num = gfc_create_var (ctype, "case_num");
	  gfc_add_modify (&block, case_num, tmp);

	  gfc_add_block_to_block (&block, &expr1se.post);

	  tmp = gfc_finish_block (&body);
	  tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
				 case_num, tmp);
	  gfc_add_expr_to_block (&block, tmp);

	  tmp = build1_v (LABEL_EXPR, end_label);
	  gfc_add_expr_to_block (&block, tmp);

	  return gfc_finish_block (&block);
	}
    }

  if (code->expr1->ts.kind == 1)
    k = 0;
  else if (code->expr1->ts.kind == 4)
    k = 1;
  else
    gcc_unreachable ();

  if (select_struct[k] == NULL)
    {
      tree *chain = NULL;
      select_struct[k] = make_node (RECORD_TYPE);

      if (code->expr1->ts.kind == 1)
	TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
      else if (code->expr1->ts.kind == 4)
	TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
      else
	gcc_unreachable ();

#undef ADD_FIELD
#define ADD_FIELD(NAME, TYPE)						    \
  ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k],		    \
					  get_identifier (stringize(NAME)), \
					  TYPE,				    \
					  &chain)

      ADD_FIELD (string1, pchartype);
      ADD_FIELD (string1_len, gfc_charlen_type_node);

      ADD_FIELD (string2, pchartype);
      ADD_FIELD (string2_len, gfc_charlen_type_node);

      ADD_FIELD (target, integer_type_node);
#undef ADD_FIELD

      gfc_finish_type (select_struct[k]);
    }

  n = 0;
  for (d = cp; d; d = d->right)
    d->n = n++;

  for (c = code->block; c; c = c->block)
    {
      for (d = c->ext.block.case_list; d; d = d->next)
        {
	  label = gfc_build_label_decl (NULL_TREE);
	  tmp = build_case_label ((d->low == NULL && d->high == NULL)
				  ? NULL
				  : build_int_cst (integer_type_node, d->n),
				  NULL, label);
          gfc_add_expr_to_block (&body, tmp);
        }

      tmp = gfc_trans_code (c->next);
      gfc_add_expr_to_block (&body, tmp);

      tmp = build1_v (GOTO_EXPR, end_label);
      gfc_add_expr_to_block (&body, tmp);
    }

  /* Generate the structure describing the branches */
  for (d = cp; d; d = d->right)
    {
      vec<constructor_elt, va_gc> *node = NULL;

      gfc_init_se (&se, NULL);

      if (d->low == NULL)
        {
          CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
          CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], build_zero_cst (gfc_charlen_type_node));
        }
      else
        {
          gfc_conv_expr_reference (&se, d->low);

          CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
          CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
        }

      if (d->high == NULL)
        {
          CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
          CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], build_zero_cst (gfc_charlen_type_node));
        }
      else
        {
          gfc_init_se (&se, NULL);
          gfc_conv_expr_reference (&se, d->high);

          CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
          CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
        }

      CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
                              build_int_cst (integer_type_node, d->n));

      tmp = build_constructor (select_struct[k], node);
      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
    }

  type = build_array_type (select_struct[k],
			   build_index_type (size_int (n-1)));

  init = build_constructor (type, inits);
  TREE_CONSTANT (init) = 1;
  TREE_STATIC (init) = 1;
  /* Create a static variable to hold the jump table.  */
  tmp = gfc_create_var (type, "jumptable");
  TREE_CONSTANT (tmp) = 1;
  TREE_STATIC (tmp) = 1;
  TREE_READONLY (tmp) = 1;
  DECL_INITIAL (tmp) = init;
  init = tmp;

  /* Build the library call */
  init = gfc_build_addr_expr (pvoid_type_node, init);

  if (code->expr1->ts.kind == 1)
    fndecl = gfor_fndecl_select_string;
  else if (code->expr1->ts.kind == 4)
    fndecl = gfor_fndecl_select_string_char4;
  else
    gcc_unreachable ();

  tmp = build_call_expr_loc (input_location,
			 fndecl, 4, init,
			 build_int_cst (gfc_charlen_type_node, n),
			 expr1se.expr, expr1se.string_length);
  case_num = gfc_create_var (integer_type_node, "case_num");
  gfc_add_modify (&block, case_num, tmp);

  gfc_add_block_to_block (&block, &expr1se.post);

  tmp = gfc_finish_block (&body);
  tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE,
			 case_num, tmp);
  gfc_add_expr_to_block (&block, tmp);

  tmp = build1_v (LABEL_EXPR, end_label);
  gfc_add_expr_to_block (&block, tmp);

  return gfc_finish_block (&block);
}


/* Translate the three variants of the SELECT CASE construct.

   SELECT CASEs with INTEGER case expressions can be translated to an
   equivalent GENERIC switch statement, and for LOGICAL case
   expressions we build one or two if-else compares.

   SELECT CASEs with CHARACTER case expressions are a whole different
   story, because they don't exist in GENERIC.  So we sort them and
   do a binary search at runtime.

   Fortran has no BREAK statement, and it does not allow jumps from
   one case block to another.  That makes things a lot easier for
   the optimizers.  */

tree
gfc_trans_select (gfc_code * code)
{
  stmtblock_t block;
  tree body;
  tree exit_label;

  gcc_assert (code && code->expr1);
  gfc_init_block (&block);

  /* Build the exit label and hang it in.  */
  exit_label = gfc_build_label_decl (NULL_TREE);
  code->exit_label = exit_label;

  /* Empty SELECT constructs are legal.  */
  if (code->block == NULL)
    body = build_empty_stmt (input_location);

  /* Select the correct translation function.  */
  else
    switch (code->expr1->ts.type)
      {
      case BT_LOGICAL:
	body = gfc_trans_logical_select (code);
	break;

      case BT_INTEGER:
	body = gfc_trans_integer_select (code);
	break;

      case BT_CHARACTER:
	body = gfc_trans_character_select (code);
	break;

      default:
	gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
	/* Not reached */
      }

  /* Build everything together.  */
  gfc_add_expr_to_block (&block, body);
  gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));

  return gfc_finish_block (&block);
}

tree
gfc_trans_select_type (gfc_code * code)
{
  stmtblock_t block;
  tree body;
  tree exit_label;

  gcc_assert (code && code->expr1);
  gfc_init_block (&block);

  /* Build the exit label and hang it in.  */
  exit_label = gfc_build_label_decl (NULL_TREE);
  code->exit_label = exit_label;

  /* Empty SELECT constructs are legal.  */
  if (code->block == NULL)
    body = build_empty_stmt (input_location);
  else
    body = gfc_trans_select_type_cases (code);

  /* Build everything together.  */
  gfc_add_expr_to_block (&block, body);

  if (TREE_USED (exit_label))
    gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));

  return gfc_finish_block (&block);
}


/* Traversal function to substitute a replacement symtree if the symbol
   in the expression is the same as that passed.  f == 2 signals that
   that variable itself is not to be checked - only the references.
   This group of functions is used when the variable expression in a
   FORALL assignment has internal references.  For example:
		FORALL (i = 1:4) p(p(i)) = i
   The only recourse here is to store a copy of 'p' for the index
   expression.  */

static gfc_symtree *new_symtree;
static gfc_symtree *old_symtree;

static bool
forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
{
  if (expr->expr_type != EXPR_VARIABLE)
    return false;

  if (*f == 2)
    *f = 1;
  else if (expr->symtree->n.sym == sym)
    expr->symtree = new_symtree;

  return false;
}

static void
forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
{
  gfc_traverse_expr (e, sym, forall_replace, f);
}

static bool
forall_restore (gfc_expr *expr,
		gfc_symbol *sym ATTRIBUTE_UNUSED,
		int *f ATTRIBUTE_UNUSED)
{
  if (expr->expr_type != EXPR_VARIABLE)
    return false;

  if (expr->symtree == new_symtree)
    expr->symtree = old_symtree;

  return false;
}

static void
forall_restore_symtree (gfc_expr *e)
{
  gfc_traverse_expr (e, NULL, forall_restore, 0);
}

static void
forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
{
  gfc_se tse;
  gfc_se rse;
  gfc_expr *e;
  gfc_symbol *new_sym;
  gfc_symbol *old_sym;
  gfc_symtree *root;
  tree tmp;

  /* Build a copy of the lvalue.  */
  old_symtree = c->expr1->symtree;
  old_sym = old_symtree->n.sym;
  e = gfc_lval_expr_from_sym (old_sym);
  if (old_sym->attr.dimension)
    {
      gfc_init_se (&tse, NULL);
      gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
      gfc_add_block_to_block (pre, &tse.pre);
      gfc_add_block_to_block (post, &tse.post);
      tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);

      if (c->expr1->ref->u.ar.type != AR_SECTION)
	{
	  /* Use the variable offset for the temporary.  */
	  tmp = gfc_conv_array_offset (old_sym->backend_decl);
	  gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
	}
    }
  else
    {
      gfc_init_se (&tse, NULL);
      gfc_init_se (&rse, NULL);
      gfc_conv_expr (&rse, e);
      if (e->ts.type == BT_CHARACTER)
	{
	  tse.string_length = rse.string_length;
	  tmp = gfc_get_character_type_len (gfc_default_character_kind,
					    tse.string_length);
	  tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
					  rse.string_length);
	  gfc_add_block_to_block (pre, &tse.pre);
	  gfc_add_block_to_block (post, &tse.post);
	}
      else
	{
	  tmp = gfc_typenode_for_spec (&e->ts);
	  tse.expr = gfc_create_var (tmp, "temp");
	}

      tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
				     e->expr_type == EXPR_VARIABLE, false);
      gfc_add_expr_to_block (pre, tmp);
    }
  gfc_free_expr (e);

  /* Create a new symbol to represent the lvalue.  */
  new_sym = gfc_new_symbol (old_sym->name, NULL);
  new_sym->ts = old_sym->ts;
  new_sym->attr.referenced = 1;
  new_sym->attr.temporary = 1;
  new_sym->attr.dimension = old_sym->attr.dimension;
  new_sym->attr.flavor = old_sym->attr.flavor;

  /* Use the temporary as the backend_decl.  */
  new_sym->backend_decl = tse.expr;

  /* Create a fake symtree for it.  */
  root = NULL;
  new_symtree = gfc_new_symtree (&root, old_sym->name);
  new_symtree->n.sym = new_sym;
  gcc_assert (new_symtree == root);

  /* Go through the expression reference replacing the old_symtree
     with the new.  */
  forall_replace_symtree (c->expr1, old_sym, 2);

  /* Now we have made this temporary, we might as well use it for
  the right hand side.  */
  forall_replace_symtree (c->expr2, old_sym, 1);
}


/* Handles dependencies in forall assignments.  */
static int
check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
{
  gfc_ref *lref;
  gfc_ref *rref;
  int need_temp;
  gfc_symbol *lsym;

  lsym = c->expr1->symtree->n.sym;
  need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);

  /* Now check for dependencies within the 'variable'
     expression itself.  These are treated by making a complete
     copy of variable and changing all the references to it
     point to the copy instead.  Note that the shallow copy of
     the variable will not suffice for derived types with
     pointer components.  We therefore leave these to their
     own devices.  */
  if (lsym->ts.type == BT_DERIVED
	&& lsym->ts.u.derived->attr.pointer_comp)
    return need_temp;

  new_symtree = NULL;
  if (find_forall_index (c->expr1, lsym, 2))
    {
      forall_make_variable_temp (c, pre, post);
      need_temp = 0;
    }

  /* Substrings with dependencies are treated in the same
     way.  */
  if (c->expr1->ts.type == BT_CHARACTER
	&& c->expr1->ref
	&& c->expr2->expr_type == EXPR_VARIABLE
	&& lsym == c->expr2->symtree->n.sym)
    {
      for (lref = c->expr1->ref; lref; lref = lref->next)
	if (lref->type == REF_SUBSTRING)
	  break;
      for (rref = c->expr2->ref; rref; rref = rref->next)
	if (rref->type == REF_SUBSTRING)
	  break;

      if (rref && lref
	    && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
	{
	  forall_make_variable_temp (c, pre, post);
	  need_temp = 0;
	}
    }
  return need_temp;
}


static void
cleanup_forall_symtrees (gfc_code *c)
{
  forall_restore_symtree (c->expr1);
  forall_restore_symtree (c->expr2);
  free (new_symtree->n.sym);
  free (new_symtree);
}


/* Generate the loops for a FORALL block, specified by FORALL_TMP.  BODY
   is the contents of the FORALL block/stmt to be iterated.  MASK_FLAG
   indicates whether we should generate code to test the FORALLs mask
   array.  OUTER is the loop header to be used for initializing mask
   indices.

   The generated loop format is:
    count = (end - start + step) / step
    loopvar = start
    while (1)
      {
        if (count <=0 )
          goto end_of_loop
        <body>
        loopvar += step
        count --
      }
    end_of_loop:  */

static tree
gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
                       int mask_flag, stmtblock_t *outer)
{
  int n, nvar;
  tree tmp;
  tree cond;
  stmtblock_t block;
  tree exit_label;
  tree count;
  tree var, start, end, step;
  iter_info *iter;

  /* Initialize the mask index outside the FORALL nest.  */
  if (mask_flag && forall_tmp->mask)
    gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);

  iter = forall_tmp->this_loop;
  nvar = forall_tmp->nvar;
  for (n = 0; n < nvar; n++)
    {
      var = iter->var;
      start = iter->start;
      end = iter->end;
      step = iter->step;

      exit_label = gfc_build_label_decl (NULL_TREE);
      TREE_USED (exit_label) = 1;

      /* The loop counter.  */
      count = gfc_create_var (TREE_TYPE (var), "count");

      /* The body of the loop.  */
      gfc_init_block (&block);

      /* The exit condition.  */
      cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
			      count, build_int_cst (TREE_TYPE (count), 0));

      /* PR 83064 means that we cannot use annot_expr_parallel_kind until
       the autoparallelizer can hande this.  */
      if (forall_tmp->do_concurrent)
	cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
		       build_int_cst (integer_type_node,
				      annot_expr_ivdep_kind),
		       integer_zero_node);

      tmp = build1_v (GOTO_EXPR, exit_label);
      tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
			     cond, tmp, build_empty_stmt (input_location));
      gfc_add_expr_to_block (&block, tmp);

      /* The main loop body.  */
      gfc_add_expr_to_block (&block, body);

      /* Increment the loop variable.  */
      tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
			     step);
      gfc_add_modify (&block, var, tmp);

      /* Advance to the next mask element.  Only do this for the
	 innermost loop.  */
      if (n == 0 && mask_flag && forall_tmp->mask)
	{
	  tree maskindex = forall_tmp->maskindex;
	  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
				 maskindex, gfc_index_one_node);
	  gfc_add_modify (&block, maskindex, tmp);
	}

      /* Decrement the loop counter.  */
      tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
			     build_int_cst (TREE_TYPE (var), 1));
      gfc_add_modify (&block, count, tmp);

      body = gfc_finish_block (&block);

      /* Loop var initialization.  */
      gfc_init_block (&block);
      gfc_add_modify (&block, var, start);


      /* Initialize the loop counter.  */
      tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
			     start);
      tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
			     tmp);
      tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
			     tmp, step);
      gfc_add_modify (&block, count, tmp);

      /* The loop expression.  */
      tmp = build1_v (LOOP_EXPR, body);
      gfc_add_expr_to_block (&block, tmp);

      /* The exit label.  */
      tmp = build1_v (LABEL_EXPR, exit_label);
      gfc_add_expr_to_block (&block, tmp);

      body = gfc_finish_block (&block);
      iter = iter->next;
    }
  return body;
}


/* Generate the body and loops according to MASK_FLAG.  If MASK_FLAG
   is nonzero, the body is controlled by all masks in the forall nest.
   Otherwise, the innermost loop is not controlled by it's mask.  This
   is used for initializing that mask.  */

static tree
gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
                              int mask_flag)
{
  tree tmp;
  stmtblock_t header;
  forall_info *forall_tmp;
  tree mask, maskindex;

  gfc_start_block (&header);

  forall_tmp = nested_forall_info;
  while (forall_tmp != NULL)
    {
      /* Generate body with masks' control.  */
      if (mask_flag)
        {
          mask = forall_tmp->mask;
          maskindex = forall_tmp->maskindex;

          /* If a mask was specified make the assignment conditional.  */
          if (mask)
            {
              tmp = gfc_build_array_ref (mask, maskindex, NULL);
              body = build3_v (COND_EXPR, tmp, body,
			       build_empty_stmt (input_location));
            }
        }
      body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
      forall_tmp = forall_tmp->prev_nest;
      mask_flag = 1;
    }

  gfc_add_expr_to_block (&header, body);
  return gfc_finish_block (&header);
}


/* Allocate data for holding a temporary array.  Returns either a local
   temporary array or a pointer variable.  */

static tree
gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
                 tree elem_type)
{
  tree tmpvar;
  tree type;
  tree tmp;

  if (INTEGER_CST_P (size))
    tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			   size, gfc_index_one_node);
  else
    tmp = NULL_TREE;

  type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
  type = build_array_type (elem_type, type);
  if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
    {
      tmpvar = gfc_create_var (type, "temp");
      *pdata = NULL_TREE;
    }
  else
    {
      tmpvar = gfc_create_var (build_pointer_type (type), "temp");
      *pdata = convert (pvoid_type_node, tmpvar);

      tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
      gfc_add_modify (pblock, tmpvar, tmp);
    }
  return tmpvar;
}


/* Generate codes to copy the temporary to the actual lhs.  */

static tree
generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
			       tree count1,
			       gfc_ss *lss, gfc_ss *rss,
			       tree wheremask, bool invert)
{
  stmtblock_t block, body1;
  gfc_loopinfo loop;
  gfc_se lse;
  gfc_se rse;
  tree tmp;
  tree wheremaskexpr;

  (void) rss; /* TODO: unused.  */

  gfc_start_block (&block);

  gfc_init_se (&rse, NULL);
  gfc_init_se (&lse, NULL);

  if (lss == gfc_ss_terminator)
    {
      gfc_init_block (&body1);
      gfc_conv_expr (&lse, expr);
      rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
    }
  else
    {
      /* Initialize the loop.  */
      gfc_init_loopinfo (&loop);

      /* We may need LSS to determine the shape of the expression.  */
      gfc_add_ss_to_loop (&loop, lss);

      gfc_conv_ss_startstride (&loop);
      gfc_conv_loop_setup (&loop, &expr->where);

      gfc_mark_ss_chain_used (lss, 1);
      /* Start the loop body.  */
      gfc_start_scalarized_body (&loop, &body1);

      /* Translate the expression.  */
      gfc_copy_loopinfo_to_se (&lse, &loop);
      lse.ss = lss;
      gfc_conv_expr (&lse, expr);

      /* Form the expression of the temporary.  */
      rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
    }

  /* Use the scalar assignment.  */
  rse.string_length = lse.string_length;
  tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts,
				 expr->expr_type == EXPR_VARIABLE, false);

  /* Form the mask expression according to the mask tree list.  */
  if (wheremask)
    {
      wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
      if (invert)
	wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
					 TREE_TYPE (wheremaskexpr),
					 wheremaskexpr);
      tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
			     wheremaskexpr, tmp,
			     build_empty_stmt (input_location));
    }

  gfc_add_expr_to_block (&body1, tmp);

  tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
			 count1, gfc_index_one_node);
  gfc_add_modify (&body1, count1, tmp);

  if (lss == gfc_ss_terminator)
      gfc_add_block_to_block (&block, &body1);
  else
    {
      /* Increment count3.  */
      if (count3)
	{
	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type,
				 count3, gfc_index_one_node);
	  gfc_add_modify (&body1, count3, tmp);
	}

      /* Generate the copying loops.  */
      gfc_trans_scalarizing_loops (&loop, &body1);

      gfc_add_block_to_block (&block, &loop.pre);
      gfc_add_block_to_block (&block, &loop.post);

      gfc_cleanup_loop (&loop);
      /* TODO: Reuse lss and rss when copying temp->lhs.  Need to be careful
	 as tree nodes in SS may not be valid in different scope.  */
    }

  tmp = gfc_finish_block (&block);
  return tmp;
}


/* Generate codes to copy rhs to the temporary. TMP1 is the address of
   temporary, LSS and RSS are formed in function compute_inner_temp_size(),
   and should not be freed.  WHEREMASK is the conditional execution mask
   whose sense may be inverted by INVERT.  */

static tree
generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
			       tree count1, gfc_ss *lss, gfc_ss *rss,
			       tree wheremask, bool invert)
{
  stmtblock_t block, body1;
  gfc_loopinfo loop;
  gfc_se lse;
  gfc_se rse;
  tree tmp;
  tree wheremaskexpr;

  gfc_start_block (&block);

  gfc_init_se (&rse, NULL);
  gfc_init_se (&lse, NULL);

  if (lss == gfc_ss_terminator)
    {
      gfc_init_block (&body1);
      gfc_conv_expr (&rse, expr2);
      lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
    }
  else
    {
      /* Initialize the loop.  */
      gfc_init_loopinfo (&loop);

      /* We may need LSS to determine the shape of the expression.  */
      gfc_add_ss_to_loop (&loop, lss);
      gfc_add_ss_to_loop (&loop, rss);

      gfc_conv_ss_startstride (&loop);
      gfc_conv_loop_setup (&loop, &expr2->where);

      gfc_mark_ss_chain_used (rss, 1);
      /* Start the loop body.  */
      gfc_start_scalarized_body (&loop, &body1);

      /* Translate the expression.  */
      gfc_copy_loopinfo_to_se (&rse, &loop);
      rse.ss = rss;
      gfc_conv_expr (&rse, expr2);

      /* Form the expression of the temporary.  */
      lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
    }

  /* Use the scalar assignment.  */
  lse.string_length = rse.string_length;
  tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
				 expr2->expr_type == EXPR_VARIABLE, false);

  /* Form the mask expression according to the mask tree list.  */
  if (wheremask)
    {
      wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
      if (invert)
	wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
					 TREE_TYPE (wheremaskexpr),
					 wheremaskexpr);
      tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
			     wheremaskexpr, tmp,
			     build_empty_stmt (input_location));
    }

  gfc_add_expr_to_block (&body1, tmp);

  if (lss == gfc_ss_terminator)
    {
      gfc_add_block_to_block (&block, &body1);

      /* Increment count1.  */
      tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
			     count1, gfc_index_one_node);
      gfc_add_modify (&block, count1, tmp);
    }
  else
    {
      /* Increment count1.  */
      tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			     count1, gfc_index_one_node);
      gfc_add_modify (&body1, count1, tmp);

      /* Increment count3.  */
      if (count3)
	{
	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type,
				 count3, gfc_index_one_node);
	  gfc_add_modify (&body1, count3, tmp);
	}

      /* Generate the copying loops.  */
      gfc_trans_scalarizing_loops (&loop, &body1);

      gfc_add_block_to_block (&block, &loop.pre);
      gfc_add_block_to_block (&block, &loop.post);

      gfc_cleanup_loop (&loop);
      /* TODO: Reuse lss and rss when copying temp->lhs.  Need to be careful
	 as tree nodes in SS may not be valid in different scope.  */
    }

  tmp = gfc_finish_block (&block);
  return tmp;
}


/* Calculate the size of temporary needed in the assignment inside forall.
   LSS and RSS are filled in this function.  */

static tree
compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
			 stmtblock_t * pblock,
                         gfc_ss **lss, gfc_ss **rss)
{
  gfc_loopinfo loop;
  tree size;
  int i;
  int save_flag;
  tree tmp;

  *lss = gfc_walk_expr (expr1);
  *rss = NULL;

  size = gfc_index_one_node;
  if (*lss != gfc_ss_terminator)
    {
      gfc_init_loopinfo (&loop);

      /* Walk the RHS of the expression.  */
      *rss = gfc_walk_expr (expr2);
      if (*rss == gfc_ss_terminator)
	/* The rhs is scalar.  Add a ss for the expression.  */
	*rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);

      /* Associate the SS with the loop.  */
      gfc_add_ss_to_loop (&loop, *lss);
      /* We don't actually need to add the rhs at this point, but it might
         make guessing the loop bounds a bit easier.  */
      gfc_add_ss_to_loop (&loop, *rss);

      /* We only want the shape of the expression, not rest of the junk
         generated by the scalarizer.  */
      loop.array_parameter = 1;

      /* Calculate the bounds of the scalarization.  */
      save_flag = gfc_option.rtcheck;
      gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
      gfc_conv_ss_startstride (&loop);
      gfc_option.rtcheck = save_flag;
      gfc_conv_loop_setup (&loop, &expr2->where);

      /* Figure out how many elements we need.  */
      for (i = 0; i < loop.dimen; i++)
        {
	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
				 gfc_array_index_type,
				 gfc_index_one_node, loop.from[i]);
          tmp = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type, tmp, loop.to[i]);
          size = fold_build2_loc (input_location, MULT_EXPR,
				  gfc_array_index_type, size, tmp);
        }
      gfc_add_block_to_block (pblock, &loop.pre);
      size = gfc_evaluate_now (size, pblock);
      gfc_add_block_to_block (pblock, &loop.post);

      /* TODO: write a function that cleans up a loopinfo without freeing
         the SS chains.  Currently a NOP.  */
    }

  return size;
}


/* Calculate the overall iterator number of the nested forall construct.
   This routine actually calculates the number of times the body of the
   nested forall specified by NESTED_FORALL_INFO is executed and multiplies
   that by the expression INNER_SIZE.  The BLOCK argument specifies the
   block in which to calculate the result, and the optional INNER_SIZE_BODY
   argument contains any statements that need to executed (inside the loop)
   to initialize or calculate INNER_SIZE.  */

static tree
compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
			     stmtblock_t *inner_size_body, stmtblock_t *block)
{
  forall_info *forall_tmp = nested_forall_info;
  tree tmp, number;
  stmtblock_t body;

  /* We can eliminate the innermost unconditional loops with constant
     array bounds.  */
  if (INTEGER_CST_P (inner_size))
    {
      while (forall_tmp
	     && !forall_tmp->mask
	     && INTEGER_CST_P (forall_tmp->size))
	{
	  inner_size = fold_build2_loc (input_location, MULT_EXPR,
					gfc_array_index_type,
					inner_size, forall_tmp->size);
	  forall_tmp = forall_tmp->prev_nest;
	}

      /* If there are no loops left, we have our constant result.  */
      if (!forall_tmp)
	return inner_size;
    }

  /* Otherwise, create a temporary variable to compute the result.  */
  number = gfc_create_var (gfc_array_index_type, "num");
  gfc_add_modify (block, number, gfc_index_zero_node);

  gfc_start_block (&body);
  if (inner_size_body)
    gfc_add_block_to_block (&body, inner_size_body);
  if (forall_tmp)
    tmp = fold_build2_loc (input_location, PLUS_EXPR,
			   gfc_array_index_type, number, inner_size);
  else
    tmp = inner_size;
  gfc_add_modify (&body, number, tmp);
  tmp = gfc_finish_block (&body);

  /* Generate loops.  */
  if (forall_tmp != NULL)
    tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);

  gfc_add_expr_to_block (block, tmp);

  return number;
}


/* Allocate temporary for forall construct.  SIZE is the size of temporary
   needed.  PTEMP1 is returned for space free.  */

static tree
allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
				 tree * ptemp1)
{
  tree bytesize;
  tree unit;
  tree tmp;

  unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
  if (!integer_onep (unit))
    bytesize = fold_build2_loc (input_location, MULT_EXPR,
				gfc_array_index_type, size, unit);
  else
    bytesize = size;

  *ptemp1 = NULL;
  tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);

  if (*ptemp1)
    tmp = build_fold_indirect_ref_loc (input_location, tmp);
  return tmp;
}


/* Allocate temporary for forall construct according to the information in
   nested_forall_info.  INNER_SIZE is the size of temporary needed in the
   assignment inside forall.  PTEMP1 is returned for space free.  */

static tree
allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
			       tree inner_size, stmtblock_t * inner_size_body,
			       stmtblock_t * block, tree * ptemp1)
{
  tree size;

  /* Calculate the total size of temporary needed in forall construct.  */
  size = compute_overall_iter_number (nested_forall_info, inner_size,
				      inner_size_body, block);

  return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
}


/* Handle assignments inside forall which need temporary.

    forall (i=start:end:stride; maskexpr)
      e<i> = f<i>
    end forall
   (where e,f<i> are arbitrary expressions possibly involving i
    and there is a dependency between e<i> and f<i>)
   Translates to:
    masktmp(:) = maskexpr(:)

    maskindex = 0;
    count1 = 0;
    num = 0;
    for (i = start; i <= end; i += stride)
      num += SIZE (f<i>)
    count1 = 0;
    ALLOCATE (tmp(num))
    for (i = start; i <= end; i += stride)
      {
	if (masktmp[maskindex++])
	  tmp[count1++] = f<i>
      }
    maskindex = 0;
    count1 = 0;
    for (i = start; i <= end; i += stride)
      {
	if (masktmp[maskindex++])
	  e<i> = tmp[count1++]
      }
    DEALLOCATE (tmp)
  */
static void
gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
			    tree wheremask, bool invert,
                            forall_info * nested_forall_info,
                            stmtblock_t * block)
{
  tree type;
  tree inner_size;
  gfc_ss *lss, *rss;
  tree count, count1;
  tree tmp, tmp1;
  tree ptemp1;
  stmtblock_t inner_size_body;

  /* Create vars. count1 is the current iterator number of the nested
     forall.  */
  count1 = gfc_create_var (gfc_array_index_type, "count1");

  /* Count is the wheremask index.  */
  if (wheremask)
    {
      count = gfc_create_var (gfc_array_index_type, "count");
      gfc_add_modify (block, count, gfc_index_zero_node);
    }
  else
    count = NULL;

  /* Initialize count1.  */
  gfc_add_modify (block, count1, gfc_index_zero_node);

  /* Calculate the size of temporary needed in the assignment. Return loop, lss
     and rss which are used in function generate_loop_for_rhs_to_temp().  */
  /* The type of LHS. Used in function allocate_temp_for_forall_nest */
  if (expr1->ts.type == BT_CHARACTER)
    {
      type = NULL;
      if (expr1->ref && expr1->ref->type == REF_SUBSTRING)
	{
	  gfc_se ssse;
	  gfc_init_se (&ssse, NULL);
	  gfc_conv_expr (&ssse, expr1);
	  type = gfc_get_character_type_len (gfc_default_character_kind,
					     ssse.string_length);
	}
      else
	{
	  if (!expr1->ts.u.cl->backend_decl)
	    {
	      gfc_se tse;
	      gcc_assert (expr1->ts.u.cl->length);
	      gfc_init_se (&tse, NULL);
	      gfc_conv_expr (&tse, expr1->ts.u.cl->length);
	      expr1->ts.u.cl->backend_decl = tse.expr;
	    }
	  type = gfc_get_character_type_len (gfc_default_character_kind,
					     expr1->ts.u.cl->backend_decl);
	}
    }
  else
    type = gfc_typenode_for_spec (&expr1->ts);

  gfc_init_block (&inner_size_body);
  inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
					&lss, &rss);

  /* Allocate temporary for nested forall construct according to the
     information in nested_forall_info and inner_size.  */
  tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
					&inner_size_body, block, &ptemp1);

  /* Generate codes to copy rhs to the temporary .  */
  tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
				       wheremask, invert);

  /* Generate body and loops according to the information in
     nested_forall_info.  */
  tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
  gfc_add_expr_to_block (block, tmp);

  /* Reset count1.  */
  gfc_add_modify (block, count1, gfc_index_zero_node);

  /* Reset count.  */
  if (wheremask)
    gfc_add_modify (block, count, gfc_index_zero_node);

  /* TODO: Second call to compute_inner_temp_size to initialize lss and
     rss;  there must be a better way.  */
  inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
					&lss, &rss);

  /* Generate codes to copy the temporary to lhs.  */
  tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
				       lss, rss,
				       wheremask, invert);

  /* Generate body and loops according to the information in
     nested_forall_info.  */
  tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
  gfc_add_expr_to_block (block, tmp);

  if (ptemp1)
    {
      /* Free the temporary.  */
      tmp = gfc_call_free (ptemp1);
      gfc_add_expr_to_block (block, tmp);
    }
}


/* Translate pointer assignment inside FORALL which need temporary.  */

static void
gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
                                    forall_info * nested_forall_info,
                                    stmtblock_t * block)
{
  tree type;
  tree inner_size;
  gfc_ss *lss, *rss;
  gfc_se lse;
  gfc_se rse;
  gfc_array_info *info;
  gfc_loopinfo loop;
  tree desc;
  tree parm;
  tree parmtype;
  stmtblock_t body;
  tree count;
  tree tmp, tmp1, ptemp1;

  count = gfc_create_var (gfc_array_index_type, "count");
  gfc_add_modify (block, count, gfc_index_zero_node);

  inner_size = gfc_index_one_node;
  lss = gfc_walk_expr (expr1);
  rss = gfc_walk_expr (expr2);
  if (lss == gfc_ss_terminator)
    {
      type = gfc_typenode_for_spec (&expr1->ts);
      type = build_pointer_type (type);

      /* Allocate temporary for nested forall construct according to the
         information in nested_forall_info and inner_size.  */
      tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
					    inner_size, NULL, block, &ptemp1);
      gfc_start_block (&body);
      gfc_init_se (&lse, NULL);
      lse.expr = gfc_build_array_ref (tmp1, count, NULL);
      gfc_init_se (&rse, NULL);
      rse.want_pointer = 1;
      gfc_conv_expr (&rse, expr2);
      gfc_add_block_to_block (&body, &rse.pre);
      gfc_add_modify (&body, lse.expr,
			   fold_convert (TREE_TYPE (lse.expr), rse.expr));
      gfc_add_block_to_block (&body, &rse.post);

      /* Increment count.  */
      tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			     count, gfc_index_one_node);
      gfc_add_modify (&body, count, tmp);

      tmp = gfc_finish_block (&body);

      /* Generate body and loops according to the information in
         nested_forall_info.  */
      tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
      gfc_add_expr_to_block (block, tmp);

      /* Reset count.  */
      gfc_add_modify (block, count, gfc_index_zero_node);

      gfc_start_block (&body);
      gfc_init_se (&lse, NULL);
      gfc_init_se (&rse, NULL);
      rse.expr = gfc_build_array_ref (tmp1, count, NULL);
      lse.want_pointer = 1;
      gfc_conv_expr (&lse, expr1);
      gfc_add_block_to_block (&body, &lse.pre);
      gfc_add_modify (&body, lse.expr, rse.expr);
      gfc_add_block_to_block (&body, &lse.post);
      /* Increment count.  */
      tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			     count, gfc_index_one_node);
      gfc_add_modify (&body, count, tmp);
      tmp = gfc_finish_block (&body);

      /* Generate body and loops according to the information in
         nested_forall_info.  */
      tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
      gfc_add_expr_to_block (block, tmp);
    }
  else
    {
      gfc_init_loopinfo (&loop);

      /* Associate the SS with the loop.  */
      gfc_add_ss_to_loop (&loop, rss);

      /* Setup the scalarizing loops and bounds.  */
      gfc_conv_ss_startstride (&loop);

      gfc_conv_loop_setup (&loop, &expr2->where);

      info = &rss->info->data.array;
      desc = info->descriptor;

      /* Make a new descriptor.  */
      parmtype = gfc_get_element_type (TREE_TYPE (desc));
      parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
                                            loop.from, loop.to, 1,
					    GFC_ARRAY_UNKNOWN, true);

      /* Allocate temporary for nested forall construct.  */
      tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
					    inner_size, NULL, block, &ptemp1);
      gfc_start_block (&body);
      gfc_init_se (&lse, NULL);
      lse.expr = gfc_build_array_ref (tmp1, count, NULL);
      lse.direct_byref = 1;
      gfc_conv_expr_descriptor (&lse, expr2);

      gfc_add_block_to_block (&body, &lse.pre);
      gfc_add_block_to_block (&body, &lse.post);

      /* Increment count.  */
      tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			     count, gfc_index_one_node);
      gfc_add_modify (&body, count, tmp);

      tmp = gfc_finish_block (&body);

      /* Generate body and loops according to the information in
         nested_forall_info.  */
      tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
      gfc_add_expr_to_block (block, tmp);

      /* Reset count.  */
      gfc_add_modify (block, count, gfc_index_zero_node);

      parm = gfc_build_array_ref (tmp1, count, NULL);
      gfc_init_se (&lse, NULL);
      gfc_conv_expr_descriptor (&lse, expr1);
      gfc_add_modify (&lse.pre, lse.expr, parm);
      gfc_start_block (&body);
      gfc_add_block_to_block (&body, &lse.pre);
      gfc_add_block_to_block (&body, &lse.post);

      /* Increment count.  */
      tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			     count, gfc_index_one_node);
      gfc_add_modify (&body, count, tmp);

      tmp = gfc_finish_block (&body);

      tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
      gfc_add_expr_to_block (block, tmp);
    }
  /* Free the temporary.  */
  if (ptemp1)
    {
      tmp = gfc_call_free (ptemp1);
      gfc_add_expr_to_block (block, tmp);
    }
}


/* FORALL and WHERE statements are really nasty, especially when you nest
   them. All the rhs of a forall assignment must be evaluated before the
   actual assignments are performed. Presumably this also applies to all the
   assignments in an inner where statement.  */

/* Generate code for a FORALL statement.  Any temporaries are allocated as a
   linear array, relying on the fact that we process in the same order in all
   loops.

    forall (i=start:end:stride; maskexpr)
      e<i> = f<i>
      g<i> = h<i>
    end forall
   (where e,f,g,h<i> are arbitrary expressions possibly involving i)
   Translates to:
    count = ((end + 1 - start) / stride)
    masktmp(:) = maskexpr(:)

    maskindex = 0;
    for (i = start; i <= end; i += stride)
      {
        if (masktmp[maskindex++])
          e<i> = f<i>
      }
    maskindex = 0;
    for (i = start; i <= end; i += stride)
      {
        if (masktmp[maskindex++])
          g<i> = h<i>
      }

    Note that this code only works when there are no dependencies.
    Forall loop with array assignments and data dependencies are a real pain,
    because the size of the temporary cannot always be determined before the
    loop is executed.  This problem is compounded by the presence of nested
    FORALL constructs.
 */

static tree
gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
{
  stmtblock_t pre;
  stmtblock_t post;
  stmtblock_t block;
  stmtblock_t body;
  tree *var;
  tree *start;
  tree *end;
  tree *step;
  gfc_expr **varexpr;
  tree tmp;
  tree assign;
  tree size;
  tree maskindex;
  tree mask;
  tree pmask;
  tree cycle_label = NULL_TREE;
  int n;
  int nvar;
  int need_temp;
  gfc_forall_iterator *fa;
  gfc_se se;
  gfc_code *c;
  gfc_saved_var *saved_vars;
  iter_info *this_forall;
  forall_info *info;
  bool need_mask;

  /* Do nothing if the mask is false.  */
  if (code->expr1
      && code->expr1->expr_type == EXPR_CONSTANT
      && !code->expr1->value.logical)
    return build_empty_stmt (input_location);

  n = 0;
  /* Count the FORALL index number.  */
  for (fa = code->ext.forall_iterator; fa; fa = fa->next)
    n++;
  nvar = n;

  /* Allocate the space for var, start, end, step, varexpr.  */
  var = XCNEWVEC (tree, nvar);
  start = XCNEWVEC (tree, nvar);
  end = XCNEWVEC (tree, nvar);
  step = XCNEWVEC (tree, nvar);
  varexpr = XCNEWVEC (gfc_expr *, nvar);
  saved_vars = XCNEWVEC (gfc_saved_var, nvar);

  /* Allocate the space for info.  */
  info = XCNEW (forall_info);

  gfc_start_block (&pre);
  gfc_init_block (&post);
  gfc_init_block (&block);

  n = 0;
  for (fa = code->ext.forall_iterator; fa; fa = fa->next)
    {
      gfc_symbol *sym = fa->var->symtree->n.sym;

      /* Allocate space for this_forall.  */
      this_forall = XCNEW (iter_info);

      /* Create a temporary variable for the FORALL index.  */
      tmp = gfc_typenode_for_spec (&sym->ts);
      var[n] = gfc_create_var (tmp, sym->name);
      gfc_shadow_sym (sym, var[n], &saved_vars[n]);

      /* Record it in this_forall.  */
      this_forall->var = var[n];

      /* Replace the index symbol's backend_decl with the temporary decl.  */
      sym->backend_decl = var[n];

      /* Work out the start, end and stride for the loop.  */
      gfc_init_se (&se, NULL);
      gfc_conv_expr_val (&se, fa->start);
      /* Record it in this_forall.  */
      this_forall->start = se.expr;
      gfc_add_block_to_block (&block, &se.pre);
      start[n] = se.expr;

      gfc_init_se (&se, NULL);
      gfc_conv_expr_val (&se, fa->end);
      /* Record it in this_forall.  */
      this_forall->end = se.expr;
      gfc_make_safe_expr (&se);
      gfc_add_block_to_block (&block, &se.pre);
      end[n] = se.expr;

      gfc_init_se (&se, NULL);
      gfc_conv_expr_val (&se, fa->stride);
      /* Record it in this_forall.  */
      this_forall->step = se.expr;
      gfc_make_safe_expr (&se);
      gfc_add_block_to_block (&block, &se.pre);
      step[n] = se.expr;

      /* Set the NEXT field of this_forall to NULL.  */
      this_forall->next = NULL;
      /* Link this_forall to the info construct.  */
      if (info->this_loop)
        {
          iter_info *iter_tmp = info->this_loop;
          while (iter_tmp->next != NULL)
            iter_tmp = iter_tmp->next;
          iter_tmp->next = this_forall;
        }
      else
        info->this_loop = this_forall;

      n++;
    }
  nvar = n;

  /* Calculate the size needed for the current forall level.  */
  size = gfc_index_one_node;
  for (n = 0; n < nvar; n++)
    {
      /* size = (end + step - start) / step.  */
      tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
			     step[n], start[n]);
      tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
			     end[n], tmp);
      tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
			     tmp, step[n]);
      tmp = convert (gfc_array_index_type, tmp);

      size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
			      size, tmp);
    }

  /* Record the nvar and size of current forall level.  */
  info->nvar = nvar;
  info->size = size;

  if (code->expr1)
    {
      /* If the mask is .true., consider the FORALL unconditional.  */
      if (code->expr1->expr_type == EXPR_CONSTANT
	  && code->expr1->value.logical)
	need_mask = false;
      else
	need_mask = true;
    }
  else
    need_mask = false;

  /* First we need to allocate the mask.  */
  if (need_mask)
    {
      /* As the mask array can be very big, prefer compact boolean types.  */
      tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
      mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
					    size, NULL, &block, &pmask);
      maskindex = gfc_create_var_np (gfc_array_index_type, "mi");

      /* Record them in the info structure.  */
      info->maskindex = maskindex;
      info->mask = mask;
    }
  else
    {
      /* No mask was specified.  */
      maskindex = NULL_TREE;
      mask = pmask = NULL_TREE;
    }

  /* Link the current forall level to nested_forall_info.  */
  info->prev_nest = nested_forall_info;
  nested_forall_info = info;

  /* Copy the mask into a temporary variable if required.
     For now we assume a mask temporary is needed.  */
  if (need_mask)
    {
      /* As the mask array can be very big, prefer compact boolean types.  */
      tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);

      gfc_add_modify (&block, maskindex, gfc_index_zero_node);

      /* Start of mask assignment loop body.  */
      gfc_start_block (&body);

      /* Evaluate the mask expression.  */
      gfc_init_se (&se, NULL);
      gfc_conv_expr_val (&se, code->expr1);
      gfc_add_block_to_block (&body, &se.pre);

      /* Store the mask.  */
      se.expr = convert (mask_type, se.expr);

      tmp = gfc_build_array_ref (mask, maskindex, NULL);
      gfc_add_modify (&body, tmp, se.expr);

      /* Advance to the next mask element.  */
      tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			     maskindex, gfc_index_one_node);
      gfc_add_modify (&body, maskindex, tmp);

      /* Generate the loops.  */
      tmp = gfc_finish_block (&body);
      tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
      gfc_add_expr_to_block (&block, tmp);
    }

  if (code->op == EXEC_DO_CONCURRENT)
    {
      gfc_init_block (&body);
      cycle_label = gfc_build_label_decl (NULL_TREE);
      code->cycle_label = cycle_label;
      tmp = gfc_trans_code (code->block->next);
      gfc_add_expr_to_block (&body, tmp);

      if (TREE_USED (cycle_label))
	{
	  tmp = build1_v (LABEL_EXPR, cycle_label);
	  gfc_add_expr_to_block (&body, tmp);
	}

      tmp = gfc_finish_block (&body);
      nested_forall_info->do_concurrent = true;
      tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
      gfc_add_expr_to_block (&block, tmp);
      goto done;
    }

  c = code->block->next;

  /* TODO: loop merging in FORALL statements.  */
  /* Now that we've got a copy of the mask, generate the assignment loops.  */
  while (c)
    {
      switch (c->op)
	{
	case EXEC_ASSIGN:
          /* A scalar or array assignment.  DO the simple check for
	     lhs to rhs dependencies.  These make a temporary for the
	     rhs and form a second forall block to copy to variable.  */
	  need_temp = check_forall_dependencies(c, &pre, &post);

          /* Temporaries due to array assignment data dependencies introduce
             no end of problems.  */
	  if (need_temp || flag_test_forall_temp)
	    gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
                                        nested_forall_info, &block);
          else
            {
              /* Use the normal assignment copying routines.  */
              assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);

              /* Generate body and loops.  */
              tmp = gfc_trans_nested_forall_loop (nested_forall_info,
						  assign, 1);
              gfc_add_expr_to_block (&block, tmp);
            }

	  /* Cleanup any temporary symtrees that have been made to deal
	     with dependencies.  */
	  if (new_symtree)
	    cleanup_forall_symtrees (c);

	  break;

        case EXEC_WHERE:
	  /* Translate WHERE or WHERE construct nested in FORALL.  */
	  gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
	  break;

        /* Pointer assignment inside FORALL.  */
	case EXEC_POINTER_ASSIGN:
          need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
	  /* Avoid cases where a temporary would never be needed and where
	     the temp code is guaranteed to fail.  */
	  if (need_temp
	      || (flag_test_forall_temp
		  && c->expr2->expr_type != EXPR_CONSTANT
		  && c->expr2->expr_type != EXPR_NULL))
            gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
                                                nested_forall_info, &block);
          else
            {
              /* Use the normal assignment copying routines.  */
              assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);

              /* Generate body and loops.  */
              tmp = gfc_trans_nested_forall_loop (nested_forall_info,
						  assign, 1);
              gfc_add_expr_to_block (&block, tmp);
            }
          break;

	case EXEC_FORALL:
	  tmp = gfc_trans_forall_1 (c, nested_forall_info);
          gfc_add_expr_to_block (&block, tmp);
          break;

	/* Explicit subroutine calls are prevented by the frontend but interface
	   assignments can legitimately produce them.  */
	case EXEC_ASSIGN_CALL:
	  assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
          tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
          gfc_add_expr_to_block (&block, tmp);
          break;

	default:
	  gcc_unreachable ();
	}

      c = c->next;
    }

done:
  /* Restore the original index variables.  */
  for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
    gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);

  /* Free the space for var, start, end, step, varexpr.  */
  free (var);
  free (start);
  free (end);
  free (step);
  free (varexpr);
  free (saved_vars);

  for (this_forall = info->this_loop; this_forall;)
    {
      iter_info *next = this_forall->next;
      free (this_forall);
      this_forall = next;
    }

  /* Free the space for this forall_info.  */
  free (info);

  if (pmask)
    {
      /* Free the temporary for the mask.  */
      tmp = gfc_call_free (pmask);
      gfc_add_expr_to_block (&block, tmp);
    }
  if (maskindex)
    pushdecl (maskindex);

  gfc_add_block_to_block (&pre, &block);
  gfc_add_block_to_block (&pre, &post);

  return gfc_finish_block (&pre);
}


/* Translate the FORALL statement or construct.  */

tree gfc_trans_forall (gfc_code * code)
{
  return gfc_trans_forall_1 (code, NULL);
}


/* Translate the DO CONCURRENT construct.  */

tree gfc_trans_do_concurrent (gfc_code * code)
{
  return gfc_trans_forall_1 (code, NULL);
}


/* Evaluate the WHERE mask expression, copy its value to a temporary.
   If the WHERE construct is nested in FORALL, compute the overall temporary
   needed by the WHERE mask expression multiplied by the iterator number of
   the nested forall.
   ME is the WHERE mask expression.
   MASK is the current execution mask upon input, whose sense may or may
   not be inverted as specified by the INVERT argument.
   CMASK is the updated execution mask on output, or NULL if not required.
   PMASK is the pending execution mask on output, or NULL if not required.
   BLOCK is the block in which to place the condition evaluation loops.  */

static void
gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
                         tree mask, bool invert, tree cmask, tree pmask,
                         tree mask_type, stmtblock_t * block)
{
  tree tmp, tmp1;
  gfc_ss *lss, *rss;
  gfc_loopinfo loop;
  stmtblock_t body, body1;
  tree count, cond, mtmp;
  gfc_se lse, rse;

  gfc_init_loopinfo (&loop);

  lss = gfc_walk_expr (me);
  rss = gfc_walk_expr (me);

  /* Variable to index the temporary.  */
  count = gfc_create_var (gfc_array_index_type, "count");
  /* Initialize count.  */
  gfc_add_modify (block, count, gfc_index_zero_node);

  gfc_start_block (&body);

  gfc_init_se (&rse, NULL);
  gfc_init_se (&lse, NULL);

  if (lss == gfc_ss_terminator)
    {
      gfc_init_block (&body1);
    }
  else
    {
      /* Initialize the loop.  */
      gfc_init_loopinfo (&loop);

      /* We may need LSS to determine the shape of the expression.  */
      gfc_add_ss_to_loop (&loop, lss);
      gfc_add_ss_to_loop (&loop, rss);

      gfc_conv_ss_startstride (&loop);
      gfc_conv_loop_setup (&loop, &me->where);

      gfc_mark_ss_chain_used (rss, 1);
      /* Start the loop body.  */
      gfc_start_scalarized_body (&loop, &body1);

      /* Translate the expression.  */
      gfc_copy_loopinfo_to_se (&rse, &loop);
      rse.ss = rss;
      gfc_conv_expr (&rse, me);
    }

  /* Variable to evaluate mask condition.  */
  cond = gfc_create_var (mask_type, "cond");
  if (mask && (cmask || pmask))
    mtmp = gfc_create_var (mask_type, "mask");
  else mtmp = NULL_TREE;

  gfc_add_block_to_block (&body1, &lse.pre);
  gfc_add_block_to_block (&body1, &rse.pre);

  gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));

  if (mask && (cmask || pmask))
    {
      tmp = gfc_build_array_ref (mask, count, NULL);
      if (invert)
	tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
      gfc_add_modify (&body1, mtmp, tmp);
    }

  if (cmask)
    {
      tmp1 = gfc_build_array_ref (cmask, count, NULL);
      tmp = cond;
      if (mask)
	tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
			       mtmp, tmp);
      gfc_add_modify (&body1, tmp1, tmp);
    }

  if (pmask)
    {
      tmp1 = gfc_build_array_ref (pmask, count, NULL);
      tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
      if (mask)
	tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
			       tmp);
      gfc_add_modify (&body1, tmp1, tmp);
    }

  gfc_add_block_to_block (&body1, &lse.post);
  gfc_add_block_to_block (&body1, &rse.post);

  if (lss == gfc_ss_terminator)
    {
      gfc_add_block_to_block (&body, &body1);
    }
  else
    {
      /* Increment count.  */
      tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			      count, gfc_index_one_node);
      gfc_add_modify (&body1, count, tmp1);

      /* Generate the copying loops.  */
      gfc_trans_scalarizing_loops (&loop, &body1);

      gfc_add_block_to_block (&body, &loop.pre);
      gfc_add_block_to_block (&body, &loop.post);

      gfc_cleanup_loop (&loop);
      /* TODO: Reuse lss and rss when copying temp->lhs.  Need to be careful
         as tree nodes in SS may not be valid in different scope.  */
    }

  tmp1 = gfc_finish_block (&body);
  /* If the WHERE construct is inside FORALL, fill the full temporary.  */
  if (nested_forall_info != NULL)
    tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);

  gfc_add_expr_to_block (block, tmp1);
}


/* Translate an assignment statement in a WHERE statement or construct
   statement. The MASK expression is used to control which elements
   of EXPR1 shall be assigned.  The sense of MASK is specified by
   INVERT.  */

static tree
gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
			tree mask, bool invert,
                        tree count1, tree count2,
			gfc_code *cnext)
{
  gfc_se lse;
  gfc_se rse;
  gfc_ss *lss;
  gfc_ss *lss_section;
  gfc_ss *rss;

  gfc_loopinfo loop;
  tree tmp;
  stmtblock_t block;
  stmtblock_t body;
  tree index, maskexpr;

  /* A defined assignment.  */
  if (cnext && cnext->resolved_sym)
    return gfc_trans_call (cnext, true, mask, count1, invert);

#if 0
  /* TODO: handle this special case.
     Special case a single function returning an array.  */
  if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
    {
      tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
      if (tmp)
        return tmp;
    }
#endif

 /* Assignment of the form lhs = rhs.  */
  gfc_start_block (&block);

  gfc_init_se (&lse, NULL);
  gfc_init_se (&rse, NULL);

  /* Walk the lhs.  */
  lss = gfc_walk_expr (expr1);
  rss = NULL;

  /* In each where-assign-stmt, the mask-expr and the variable being
     defined shall be arrays of the same shape.  */
  gcc_assert (lss != gfc_ss_terminator);

  /* The assignment needs scalarization.  */
  lss_section = lss;

  /* Find a non-scalar SS from the lhs.  */
  while (lss_section != gfc_ss_terminator
	 && lss_section->info->type != GFC_SS_SECTION)
    lss_section = lss_section->next;

  gcc_assert (lss_section != gfc_ss_terminator);

  /* Initialize the scalarizer.  */
  gfc_init_loopinfo (&loop);

  /* Walk the rhs.  */
  rss = gfc_walk_expr (expr2);
  if (rss == gfc_ss_terminator)
    {
      /* The rhs is scalar.  Add a ss for the expression.  */
      rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
      rss->info->where = 1;
    }

  /* Associate the SS with the loop.  */
  gfc_add_ss_to_loop (&loop, lss);
  gfc_add_ss_to_loop (&loop, rss);

  /* Calculate the bounds of the scalarization.  */
  gfc_conv_ss_startstride (&loop);

  /* Resolve any data dependencies in the statement.  */
  gfc_conv_resolve_dependencies (&loop, lss_section, rss);

  /* Setup the scalarizing loops.  */
  gfc_conv_loop_setup (&loop, &expr2->where);

  /* Setup the gfc_se structures.  */
  gfc_copy_loopinfo_to_se (&lse, &loop);
  gfc_copy_loopinfo_to_se (&rse, &loop);

  rse.ss = rss;
  gfc_mark_ss_chain_used (rss, 1);
  if (loop.temp_ss == NULL)
    {
      lse.ss = lss;
      gfc_mark_ss_chain_used (lss, 1);
    }
  else
    {
      lse.ss = loop.temp_ss;
      gfc_mark_ss_chain_used (lss, 3);
      gfc_mark_ss_chain_used (loop.temp_ss, 3);
    }

  /* Start the scalarized loop body.  */
  gfc_start_scalarized_body (&loop, &body);

  /* Translate the expression.  */
  gfc_conv_expr (&rse, expr2);
  if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
    gfc_conv_tmp_array_ref (&lse);
  else
    gfc_conv_expr (&lse, expr1);

  /* Form the mask expression according to the mask.  */
  index = count1;
  maskexpr = gfc_build_array_ref (mask, index, NULL);
  if (invert)
    maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
				TREE_TYPE (maskexpr), maskexpr);

  /* Use the scalar assignment as is.  */
  tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
				 false, loop.temp_ss == NULL);

  tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));

  gfc_add_expr_to_block (&body, tmp);

  if (lss == gfc_ss_terminator)
    {
      /* Increment count1.  */
      tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			     count1, gfc_index_one_node);
      gfc_add_modify (&body, count1, tmp);

      /* Use the scalar assignment as is.  */
      gfc_add_block_to_block (&block, &body);
    }
  else
    {
      gcc_assert (lse.ss == gfc_ss_terminator
		  && rse.ss == gfc_ss_terminator);

      if (loop.temp_ss != NULL)
        {
          /* Increment count1 before finish the main body of a scalarized
             expression.  */
          tmp = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type, count1, gfc_index_one_node);
          gfc_add_modify (&body, count1, tmp);
          gfc_trans_scalarized_loop_boundary (&loop, &body);

          /* We need to copy the temporary to the actual lhs.  */
          gfc_init_se (&lse, NULL);
          gfc_init_se (&rse, NULL);
          gfc_copy_loopinfo_to_se (&lse, &loop);
          gfc_copy_loopinfo_to_se (&rse, &loop);

          rse.ss = loop.temp_ss;
          lse.ss = lss;

          gfc_conv_tmp_array_ref (&rse);
          gfc_conv_expr (&lse, expr1);

          gcc_assert (lse.ss == gfc_ss_terminator
		      && rse.ss == gfc_ss_terminator);

          /* Form the mask expression according to the mask tree list.  */
          index = count2;
          maskexpr = gfc_build_array_ref (mask, index, NULL);
	  if (invert)
	    maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
					TREE_TYPE (maskexpr), maskexpr);

          /* Use the scalar assignment as is.  */
          tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
          tmp = build3_v (COND_EXPR, maskexpr, tmp,
			  build_empty_stmt (input_location));
          gfc_add_expr_to_block (&body, tmp);

          /* Increment count2.  */
          tmp = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type, count2,
				 gfc_index_one_node);
          gfc_add_modify (&body, count2, tmp);
        }
      else
        {
          /* Increment count1.  */
          tmp = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type, count1,
				 gfc_index_one_node);
          gfc_add_modify (&body, count1, tmp);
        }

      /* Generate the copying loops.  */
      gfc_trans_scalarizing_loops (&loop, &body);

      /* Wrap the whole thing up.  */
      gfc_add_block_to_block (&block, &loop.pre);
      gfc_add_block_to_block (&block, &loop.post);
      gfc_cleanup_loop (&loop);
    }

  return gfc_finish_block (&block);
}


/* Translate the WHERE construct or statement.
   This function can be called iteratively to translate the nested WHERE
   construct or statement.
   MASK is the control mask.  */

static void
gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
		   forall_info * nested_forall_info, stmtblock_t * block)
{
  stmtblock_t inner_size_body;
  tree inner_size, size;
  gfc_ss *lss, *rss;
  tree mask_type;
  gfc_expr *expr1;
  gfc_expr *expr2;
  gfc_code *cblock;
  gfc_code *cnext;
  tree tmp;
  tree cond;
  tree count1, count2;
  bool need_cmask;
  bool need_pmask;
  int need_temp;
  tree pcmask = NULL_TREE;
  tree ppmask = NULL_TREE;
  tree cmask = NULL_TREE;
  tree pmask = NULL_TREE;
  gfc_actual_arglist *arg;

  /* the WHERE statement or the WHERE construct statement.  */
  cblock = code->block;

  /* As the mask array can be very big, prefer compact boolean types.  */
  mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);

  /* Determine which temporary masks are needed.  */
  if (!cblock->block)
    {
      /* One clause: No ELSEWHEREs.  */
      need_cmask = (cblock->next != 0);
      need_pmask = false;
    }
  else if (cblock->block->block)
    {
      /* Three or more clauses: Conditional ELSEWHEREs.  */
      need_cmask = true;
      need_pmask = true;
    }
  else if (cblock->next)
    {
      /* Two clauses, the first non-empty.  */
      need_cmask = true;
      need_pmask = (mask != NULL_TREE
		    && cblock->block->next != 0);
    }
  else if (!cblock->block->next)
    {
      /* Two clauses, both empty.  */
      need_cmask = false;
      need_pmask = false;
    }
  /* Two clauses, the first empty, the second non-empty.  */
  else if (mask)
    {
      need_cmask = (cblock->block->expr1 != 0);
      need_pmask = true;
    }
  else
    {
      need_cmask = true;
      need_pmask = false;
    }

  if (need_cmask || need_pmask)
    {
      /* Calculate the size of temporary needed by the mask-expr.  */
      gfc_init_block (&inner_size_body);
      inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
					    &inner_size_body, &lss, &rss);

      gfc_free_ss_chain (lss);
      gfc_free_ss_chain (rss);

      /* Calculate the total size of temporary needed.  */
      size = compute_overall_iter_number (nested_forall_info, inner_size,
					  &inner_size_body, block);

      /* Check whether the size is negative.  */
      cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, size,
			      gfc_index_zero_node);
      size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
			      cond, gfc_index_zero_node, size);
      size = gfc_evaluate_now (size, block);

      /* Allocate temporary for WHERE mask if needed.  */
      if (need_cmask)
	cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
						 &pcmask);

      /* Allocate temporary for !mask if needed.  */
      if (need_pmask)
	pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
						 &ppmask);
    }

  while (cblock)
    {
      /* Each time around this loop, the where clause is conditional
	 on the value of mask and invert, which are updated at the
	 bottom of the loop.  */

      /* Has mask-expr.  */
      if (cblock->expr1)
        {
          /* Ensure that the WHERE mask will be evaluated exactly once.
	     If there are no statements in this WHERE/ELSEWHERE clause,
	     then we don't need to update the control mask (cmask).
	     If this is the last clause of the WHERE construct, then
	     we don't need to update the pending control mask (pmask).  */
	  if (mask)
	    gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
				     mask, invert,
				     cblock->next  ? cmask : NULL_TREE,
				     cblock->block ? pmask : NULL_TREE,
				     mask_type, block);
	  else
	    gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
				     NULL_TREE, false,
				     (cblock->next || cblock->block)
				     ? cmask : NULL_TREE,
				     NULL_TREE, mask_type, block);

	  invert = false;
        }
      /* It's a final elsewhere-stmt. No mask-expr is present.  */
      else
        cmask = mask;

      /* The body of this where clause are controlled by cmask with
	 sense specified by invert.  */

      /* Get the assignment statement of a WHERE statement, or the first
         statement in where-body-construct of a WHERE construct.  */
      cnext = cblock->next;
      while (cnext)
        {
          switch (cnext->op)
            {
            /* WHERE assignment statement.  */
	    case EXEC_ASSIGN_CALL:

	      arg = cnext->ext.actual;
	      expr1 = expr2 = NULL;
	      for (; arg; arg = arg->next)
		{
		  if (!arg->expr)
		    continue;
		  if (expr1 == NULL)
		    expr1 = arg->expr;
		  else
		    expr2 = arg->expr;
		}
	      goto evaluate;

            case EXEC_ASSIGN:
              expr1 = cnext->expr1;
              expr2 = cnext->expr2;
    evaluate:
              if (nested_forall_info != NULL)
                {
                  need_temp = gfc_check_dependency (expr1, expr2, 0);
		  if ((need_temp || flag_test_forall_temp)
		    && cnext->op != EXEC_ASSIGN_CALL)
                    gfc_trans_assign_need_temp (expr1, expr2,
						cmask, invert,
                                                nested_forall_info, block);
                  else
                    {
                      /* Variables to control maskexpr.  */
                      count1 = gfc_create_var (gfc_array_index_type, "count1");
                      count2 = gfc_create_var (gfc_array_index_type, "count2");
                      gfc_add_modify (block, count1, gfc_index_zero_node);
                      gfc_add_modify (block, count2, gfc_index_zero_node);

                      tmp = gfc_trans_where_assign (expr1, expr2,
						    cmask, invert,
						    count1, count2,
						    cnext);

                      tmp = gfc_trans_nested_forall_loop (nested_forall_info,
                                                          tmp, 1);
                      gfc_add_expr_to_block (block, tmp);
                    }
                }
              else
                {
                  /* Variables to control maskexpr.  */
                  count1 = gfc_create_var (gfc_array_index_type, "count1");
                  count2 = gfc_create_var (gfc_array_index_type, "count2");
                  gfc_add_modify (block, count1, gfc_index_zero_node);
                  gfc_add_modify (block, count2, gfc_index_zero_node);

                  tmp = gfc_trans_where_assign (expr1, expr2,
						cmask, invert,
						count1, count2,
						cnext);
                  gfc_add_expr_to_block (block, tmp);

                }
              break;

            /* WHERE or WHERE construct is part of a where-body-construct.  */
            case EXEC_WHERE:
	      gfc_trans_where_2 (cnext, cmask, invert,
				 nested_forall_info, block);
	      break;

            default:
              gcc_unreachable ();
            }

         /* The next statement within the same where-body-construct.  */
         cnext = cnext->next;
       }
    /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt.  */
    cblock = cblock->block;
    if (mask == NULL_TREE)
      {
        /* If we're the initial WHERE, we can simply invert the sense
	   of the current mask to obtain the "mask" for the remaining
	   ELSEWHEREs.  */
	invert = true;
	mask = cmask;
      }
    else
      {
	/* Otherwise, for nested WHERE's we need to use the pending mask.  */
        invert = false;
        mask = pmask;
      }
  }

  /* If we allocated a pending mask array, deallocate it now.  */
  if (ppmask)
    {
      tmp = gfc_call_free (ppmask);
      gfc_add_expr_to_block (block, tmp);
    }

  /* If we allocated a current mask array, deallocate it now.  */
  if (pcmask)
    {
      tmp = gfc_call_free (pcmask);
      gfc_add_expr_to_block (block, tmp);
    }
}

/* Translate a simple WHERE construct or statement without dependencies.
   CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
   is the mask condition, and EBLOCK if non-NULL is the "else" clause.
   Currently both CBLOCK and EBLOCK are restricted to single assignments.  */

static tree
gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
{
  stmtblock_t block, body;
  gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
  tree tmp, cexpr, tstmt, estmt;
  gfc_ss *css, *tdss, *tsss;
  gfc_se cse, tdse, tsse, edse, esse;
  gfc_loopinfo loop;
  gfc_ss *edss = 0;
  gfc_ss *esss = 0;
  bool maybe_workshare = false;

  /* Allow the scalarizer to workshare simple where loops.  */
  if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
      == OMPWS_WORKSHARE_FLAG)
    {
      maybe_workshare = true;
      ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
    }

  cond = cblock->expr1;
  tdst = cblock->next->expr1;
  tsrc = cblock->next->expr2;
  edst = eblock ? eblock->next->expr1 : NULL;
  esrc = eblock ? eblock->next->expr2 : NULL;

  gfc_start_block (&block);
  gfc_init_loopinfo (&loop);

  /* Handle the condition.  */
  gfc_init_se (&cse, NULL);
  css = gfc_walk_expr (cond);
  gfc_add_ss_to_loop (&loop, css);

  /* Handle the then-clause.  */
  gfc_init_se (&tdse, NULL);
  gfc_init_se (&tsse, NULL);
  tdss = gfc_walk_expr (tdst);
  tsss = gfc_walk_expr (tsrc);
  if (tsss == gfc_ss_terminator)
    {
      tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
      tsss->info->where = 1;
    }
  gfc_add_ss_to_loop (&loop, tdss);
  gfc_add_ss_to_loop (&loop, tsss);

  if (eblock)
    {
      /* Handle the else clause.  */
      gfc_init_se (&edse, NULL);
      gfc_init_se (&esse, NULL);
      edss = gfc_walk_expr (edst);
      esss = gfc_walk_expr (esrc);
      if (esss == gfc_ss_terminator)
	{
	  esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
	  esss->info->where = 1;
	}
      gfc_add_ss_to_loop (&loop, edss);
      gfc_add_ss_to_loop (&loop, esss);
    }

  gfc_conv_ss_startstride (&loop);
  gfc_conv_loop_setup (&loop, &tdst->where);

  gfc_mark_ss_chain_used (css, 1);
  gfc_mark_ss_chain_used (tdss, 1);
  gfc_mark_ss_chain_used (tsss, 1);
  if (eblock)
    {
      gfc_mark_ss_chain_used (edss, 1);
      gfc_mark_ss_chain_used (esss, 1);
    }

  gfc_start_scalarized_body (&loop, &body);

  gfc_copy_loopinfo_to_se (&cse, &loop);
  gfc_copy_loopinfo_to_se (&tdse, &loop);
  gfc_copy_loopinfo_to_se (&tsse, &loop);
  cse.ss = css;
  tdse.ss = tdss;
  tsse.ss = tsss;
  if (eblock)
    {
      gfc_copy_loopinfo_to_se (&edse, &loop);
      gfc_copy_loopinfo_to_se (&esse, &loop);
      edse.ss = edss;
      esse.ss = esss;
    }

  gfc_conv_expr (&cse, cond);
  gfc_add_block_to_block (&body, &cse.pre);
  cexpr = cse.expr;

  gfc_conv_expr (&tsse, tsrc);
  if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
    gfc_conv_tmp_array_ref (&tdse);
  else
    gfc_conv_expr (&tdse, tdst);

  if (eblock)
    {
      gfc_conv_expr (&esse, esrc);
      if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
	gfc_conv_tmp_array_ref (&edse);
      else
	gfc_conv_expr (&edse, edst);
    }

  tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
  estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
					    false, true)
		 : build_empty_stmt (input_location);
  tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
  gfc_add_expr_to_block (&body, tmp);
  gfc_add_block_to_block (&body, &cse.post);

  if (maybe_workshare)
    ompws_flags &= ~OMPWS_SCALARIZER_BODY;
  gfc_trans_scalarizing_loops (&loop, &body);
  gfc_add_block_to_block (&block, &loop.pre);
  gfc_add_block_to_block (&block, &loop.post);
  gfc_cleanup_loop (&loop);

  return gfc_finish_block (&block);
}

/* As the WHERE or WHERE construct statement can be nested, we call
   gfc_trans_where_2 to do the translation, and pass the initial
   NULL values for both the control mask and the pending control mask.  */

tree
gfc_trans_where (gfc_code * code)
{
  stmtblock_t block;
  gfc_code *cblock;
  gfc_code *eblock;

  cblock = code->block;
  if (cblock->next
      && cblock->next->op == EXEC_ASSIGN
      && !cblock->next->next)
    {
      eblock = cblock->block;
      if (!eblock)
	{
          /* A simple "WHERE (cond) x = y" statement or block is
	     dependence free if cond is not dependent upon writing x,
	     and the source y is unaffected by the destination x.  */
	  if (!gfc_check_dependency (cblock->next->expr1,
				     cblock->expr1, 0)
	      && !gfc_check_dependency (cblock->next->expr1,
					cblock->next->expr2, 0))
	    return gfc_trans_where_3 (cblock, NULL);
	}
      else if (!eblock->expr1
	       && !eblock->block
	       && eblock->next
	       && eblock->next->op == EXEC_ASSIGN
	       && !eblock->next->next)
	{
          /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
	     block is dependence free if cond is not dependent on writes
	     to x1 and x2, y1 is not dependent on writes to x2, and y2
	     is not dependent on writes to x1, and both y's are not
	     dependent upon their own x's.  In addition to this, the
	     final two dependency checks below exclude all but the same
	     array reference if the where and elswhere destinations
	     are the same.  In short, this is VERY conservative and this
	     is needed because the two loops, required by the standard
	     are coalesced in gfc_trans_where_3.  */
	  if (!gfc_check_dependency (cblock->next->expr1,
				    cblock->expr1, 0)
	      && !gfc_check_dependency (eblock->next->expr1,
				       cblock->expr1, 0)
	      && !gfc_check_dependency (cblock->next->expr1,
				       eblock->next->expr2, 1)
	      && !gfc_check_dependency (eblock->next->expr1,
				       cblock->next->expr2, 1)
	      && !gfc_check_dependency (cblock->next->expr1,
				       cblock->next->expr2, 1)
	      && !gfc_check_dependency (eblock->next->expr1,
				       eblock->next->expr2, 1)
	      && !gfc_check_dependency (cblock->next->expr1,
				       eblock->next->expr1, 0)
	      && !gfc_check_dependency (eblock->next->expr1,
				       cblock->next->expr1, 0))
	    return gfc_trans_where_3 (cblock, eblock);
	}
    }

  gfc_start_block (&block);

  gfc_trans_where_2 (code, NULL, false, NULL, &block);

  return gfc_finish_block (&block);
}


/* CYCLE a DO loop. The label decl has already been created by
   gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
   node at the head of the loop. We must mark the label as used.  */

tree
gfc_trans_cycle (gfc_code * code)
{
  tree cycle_label;

  cycle_label = code->ext.which_construct->cycle_label;
  gcc_assert (cycle_label);

  TREE_USED (cycle_label) = 1;
  return build1_v (GOTO_EXPR, cycle_label);
}


/* EXIT a DO loop. Similar to CYCLE, but now the label is in
   TREE_VALUE (backend_decl) of the gfc_code node at the head of the
   loop.  */

tree
gfc_trans_exit (gfc_code * code)
{
  tree exit_label;

  exit_label = code->ext.which_construct->exit_label;
  gcc_assert (exit_label);

  TREE_USED (exit_label) = 1;
  return build1_v (GOTO_EXPR, exit_label);
}


/* Get the initializer expression for the code and expr of an allocate.
   When no initializer is needed return NULL.  */

static gfc_expr *
allocate_get_initializer (gfc_code * code, gfc_expr * expr)
{
  if (!gfc_bt_struct (expr->ts.type) && expr->ts.type != BT_CLASS)
    return NULL;

  /* An explicit type was given in allocate ( T:: object).  */
  if (code->ext.alloc.ts.type == BT_DERIVED
      && (code->ext.alloc.ts.u.derived->attr.alloc_comp
	  || gfc_has_default_initializer (code->ext.alloc.ts.u.derived)))
    return gfc_default_initializer (&code->ext.alloc.ts);

  if (gfc_bt_struct (expr->ts.type)
      && (expr->ts.u.derived->attr.alloc_comp
	  || gfc_has_default_initializer (expr->ts.u.derived)))
    return gfc_default_initializer (&expr->ts);

  if (expr->ts.type == BT_CLASS
      && (CLASS_DATA (expr)->ts.u.derived->attr.alloc_comp
	  || gfc_has_default_initializer (CLASS_DATA (expr)->ts.u.derived)))
    return gfc_default_initializer (&CLASS_DATA (expr)->ts);

  return NULL;
}

/* Translate the ALLOCATE statement.  */

tree
gfc_trans_allocate (gfc_code * code)
{
  gfc_alloc *al;
  gfc_expr *expr, *e3rhs = NULL, *init_expr;
  gfc_se se, se_sz;
  tree tmp;
  tree parm;
  tree stat;
  tree errmsg;
  tree errlen;
  tree label_errmsg;
  tree label_finish;
  tree memsz;
  tree al_vptr, al_len;
  /* If an expr3 is present, then store the tree for accessing its
     _vptr, and _len components in the variables, respectively.  The
     element size, i.e. _vptr%size, is stored in expr3_esize.  Any of
     the trees may be the NULL_TREE indicating that this is not
     available for expr3's type.  */
  tree expr3, expr3_vptr, expr3_len, expr3_esize;
  /* Classify what expr3 stores.  */
  enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
  stmtblock_t block;
  stmtblock_t post;
  stmtblock_t final_block;
  tree nelems;
  bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray;
  bool needs_caf_sync, caf_refs_comp;
  bool e3_has_nodescriptor = false;
  gfc_symtree *newsym = NULL;
  symbol_attribute caf_attr;
  gfc_actual_arglist *param_list;

  if (!code->ext.alloc.list)
    return NULL_TREE;

  stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
  expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
  label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
  e3_is = E3_UNSET;
  is_coarray = needs_caf_sync = false;

  gfc_init_block (&block);
  gfc_init_block (&post);
  gfc_init_block (&final_block);

  /* STAT= (and maybe ERRMSG=) is present.  */
  if (code->expr1)
    {
      /* STAT=.  */
      tree gfc_int4_type_node = gfc_get_int_type (4);
      stat = gfc_create_var (gfc_int4_type_node, "stat");

      /* ERRMSG= only makes sense with STAT=.  */
      if (code->expr2)
	{
	  gfc_init_se (&se, NULL);
	  se.want_pointer = 1;
	  gfc_conv_expr_lhs (&se, code->expr2);
	  errmsg = se.expr;
	  errlen = se.string_length;
	}
      else
	{
	  errmsg = null_pointer_node;
	  errlen = build_int_cst (gfc_charlen_type_node, 0);
	}

      /* GOTO destinations.  */
      label_errmsg = gfc_build_label_decl (NULL_TREE);
      label_finish = gfc_build_label_decl (NULL_TREE);
      TREE_USED (label_finish) = 0;
    }

  /* When an expr3 is present evaluate it only once.  The standards prevent a
     dependency of expr3 on the objects in the allocate list.  An expr3 can
     be pre-evaluated in all cases.  One just has to make sure, to use the
     correct way, i.e., to get the descriptor or to get a reference
     expression.  */
  if (code->expr3)
    {
      bool vtab_needed = false, temp_var_needed = false,
	  temp_obj_created = false;

      is_coarray = gfc_is_coarray (code->expr3);

      if (code->expr3->expr_type == EXPR_FUNCTION && !code->expr3->mold
	  && (gfc_is_class_array_function (code->expr3)
	      || gfc_is_alloc_class_scalar_function (code->expr3)))
	code->expr3->must_finalize = 1;

      /* Figure whether we need the vtab from expr3.  */
      for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
	   al = al->next)
	vtab_needed = (al->expr->ts.type == BT_CLASS);

      gfc_init_se (&se, NULL);
      /* When expr3 is a variable, i.e., a very simple expression,
	     then convert it once here.  */
      if (code->expr3->expr_type == EXPR_VARIABLE
	  || code->expr3->expr_type == EXPR_ARRAY
	  || code->expr3->expr_type == EXPR_CONSTANT)
	{
	  if (!code->expr3->mold
	      || code->expr3->ts.type == BT_CHARACTER
	      || vtab_needed
	      || code->ext.alloc.arr_spec_from_expr3)
	    {
	      /* Convert expr3 to a tree.  For all "simple" expression just
		 get the descriptor or the reference, respectively, depending
		 on the rank of the expr.  */
	      if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
		gfc_conv_expr_descriptor (&se, code->expr3);
	      else
		{
		  gfc_conv_expr_reference (&se, code->expr3);

		  /* gfc_conv_expr_reference wraps POINTER_PLUS_EXPR in a
		     NOP_EXPR, which prevents gfortran from getting the vptr
		     from the source=-expression.  Remove the NOP_EXPR and go
		     with the POINTER_PLUS_EXPR in this case.  */
		  if (code->expr3->ts.type == BT_CLASS
		      && TREE_CODE (se.expr) == NOP_EXPR
		      && (TREE_CODE (TREE_OPERAND (se.expr, 0))
							    == POINTER_PLUS_EXPR
			  || is_coarray))
		    se.expr = TREE_OPERAND (se.expr, 0);
		}
	      /* Create a temp variable only for component refs to prevent
		 having to go through the full deref-chain each time and to
		 simplfy computation of array properties.  */
	      temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
	    }
	}
      else
	{
	  /* In all other cases evaluate the expr3.  */
	  symbol_attribute attr;
	  /* Get the descriptor for all arrays, that are not allocatable or
	     pointer, because the latter are descriptors already.
	     The exception are function calls returning a class object:
	     The descriptor is stored in their results _data component, which
	     is easier to access, when first a temporary variable for the
	     result is created and the descriptor retrieved from there.  */
	  attr = gfc_expr_attr (code->expr3);
	  if (code->expr3->rank != 0
	      && ((!attr.allocatable && !attr.pointer)
		  || (code->expr3->expr_type == EXPR_FUNCTION
		      && (code->expr3->ts.type != BT_CLASS
			  || (code->expr3->value.function.isym
			      && code->expr3->value.function.isym
							 ->transformational)))))
	    gfc_conv_expr_descriptor (&se, code->expr3);
	  else
	    gfc_conv_expr_reference (&se, code->expr3);
	  if (code->expr3->ts.type == BT_CLASS)
	    gfc_conv_class_to_class (&se, code->expr3,
				     code->expr3->ts,
				     false, true,
				     false, false);
	  temp_obj_created = temp_var_needed = !VAR_P (se.expr);
	}
      gfc_add_block_to_block (&block, &se.pre);
      if (code->expr3->must_finalize)
	gfc_add_block_to_block (&final_block, &se.post);
      else
	gfc_add_block_to_block (&post, &se.post);

      /* Special case when string in expr3 is zero.  */
      if (code->expr3->ts.type == BT_CHARACTER
	  && integer_zerop (se.string_length))
	{
	  gfc_init_se (&se, NULL);
	  temp_var_needed = false;
	  expr3_len = build_zero_cst (gfc_charlen_type_node);
	  e3_is = E3_MOLD;
	}
      /* Prevent aliasing, i.e., se.expr may be already a
	     variable declaration.  */
      else if (se.expr != NULL_TREE && temp_var_needed)
	{
	  tree var, desc;
	  tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) || is_coarray ?
		se.expr
	      : build_fold_indirect_ref_loc (input_location, se.expr);

	  /* Get the array descriptor and prepare it to be assigned to the
	     temporary variable var.  For classes the array descriptor is
	     in the _data component and the object goes into the
	     GFC_DECL_SAVED_DESCRIPTOR.  */
	  if (code->expr3->ts.type == BT_CLASS
	      && code->expr3->rank != 0)
	    {
	      /* When an array_ref was in expr3, then the descriptor is the
		 first operand.  */
	      if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
		{
		  desc = TREE_OPERAND (tmp, 0);
		}
	      else
		{
		  desc = tmp;
		  tmp = gfc_class_data_get (tmp);
		}
	      if (code->ext.alloc.arr_spec_from_expr3)
		e3_is = E3_DESC;
	    }
	  else
	    desc = !is_coarray ? se.expr
			       : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
	  /* We need a regular (non-UID) symbol here, therefore give a
	     prefix.  */
	  var = gfc_create_var (TREE_TYPE (tmp), "source");
	  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
	    {
	      gfc_allocate_lang_decl (var);
	      GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
	    }
	  gfc_add_modify_loc (input_location, &block, var, tmp);

	  expr3 = var;
	  if (se.string_length)
	    /* Evaluate it assuming that it also is complicated like expr3.  */
	    expr3_len = gfc_evaluate_now (se.string_length, &block);
	}
      else
	{
	  expr3 = se.expr;
	  expr3_len = se.string_length;
	}

      /* Deallocate any allocatable components in expressions that use a
	 temporary object, i.e. are not a simple alias of to an EXPR_VARIABLE.
	 E.g. temporaries of a function call need freeing of their components
	 here.  */
      if ((code->expr3->ts.type == BT_DERIVED
	   || code->expr3->ts.type == BT_CLASS)
	  && (code->expr3->expr_type != EXPR_VARIABLE || temp_obj_created)
	  && code->expr3->ts.u.derived->attr.alloc_comp
	  && !code->expr3->must_finalize)
	{
	  tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
					   expr3, code->expr3->rank);
	  gfc_prepend_expr_to_block (&post, tmp);
	}

      /* Store what the expr3 is to be used for.  */
      if (e3_is == E3_UNSET)
	e3_is = expr3 != NULL_TREE ?
	      (code->ext.alloc.arr_spec_from_expr3 ?
		 E3_DESC
	       : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
	    : E3_UNSET;

      /* Figure how to get the _vtab entry.  This also obtains the tree
	 expression for accessing the _len component, because only
	 unlimited polymorphic objects, which are a subcategory of class
	 types, have a _len component.  */
      if (code->expr3->ts.type == BT_CLASS)
	{
	  gfc_expr *rhs;
	  tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
		build_fold_indirect_ref (expr3): expr3;
	  /* Polymorphic SOURCE: VPTR must be determined at run time.
	     expr3 may be a temporary array declaration, therefore check for
	     GFC_CLASS_TYPE_P before trying to get the _vptr component.  */
	  if (tmp != NULL_TREE
	      && (e3_is == E3_DESC
		  || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
		      && (VAR_P (tmp) || !code->expr3->ref))
		  || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
	    tmp = gfc_class_vptr_get (expr3);
	  else
	    {
	      rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
	      gfc_add_vptr_component (rhs);
	      gfc_init_se (&se, NULL);
	      se.want_pointer = 1;
	      gfc_conv_expr (&se, rhs);
	      tmp = se.expr;
	      gfc_free_expr (rhs);
	    }
	  /* Set the element size.  */
	  expr3_esize = gfc_vptr_size_get (tmp);
	  if (vtab_needed)
	    expr3_vptr = tmp;
	  /* Initialize the ref to the _len component.  */
	  if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
	    {
	      /* Same like for retrieving the _vptr.  */
	      if (expr3 != NULL_TREE && !code->expr3->ref)
		expr3_len = gfc_class_len_get (expr3);
	      else
		{
		  rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
		  gfc_add_len_component (rhs);
		  gfc_init_se (&se, NULL);
		  gfc_conv_expr (&se, rhs);
		  expr3_len = se.expr;
		  gfc_free_expr (rhs);
		}
	    }
	}
      else
	{
	  /* When the object to allocate is polymorphic type, then it
	     needs its vtab set correctly, so deduce the required _vtab
	     and _len from the source expression.  */
	  if (vtab_needed)
	    {
	      /* VPTR is fixed at compile time.  */
	      gfc_symbol *vtab;

	      vtab = gfc_find_vtab (&code->expr3->ts);
	      gcc_assert (vtab);
	      expr3_vptr = gfc_get_symbol_decl (vtab);
	      expr3_vptr = gfc_build_addr_expr (NULL_TREE,
						expr3_vptr);
	    }
	  /* _len component needs to be set, when ts is a character
	     array.  */
	  if (expr3_len == NULL_TREE
	      && code->expr3->ts.type == BT_CHARACTER)
	    {
	      if (code->expr3->ts.u.cl
		  && code->expr3->ts.u.cl->length)
		{
		  gfc_init_se (&se, NULL);
		  gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
		  gfc_add_block_to_block (&block, &se.pre);
		  expr3_len = gfc_evaluate_now (se.expr, &block);
		}
	      gcc_assert (expr3_len);
	    }
	  /* For character arrays only the kind's size is needed, because
	     the array mem_size is _len * (elem_size = kind_size).
	     For all other get the element size in the normal way.  */
	  if (code->expr3->ts.type == BT_CHARACTER)
	    expr3_esize = TYPE_SIZE_UNIT (
		  gfc_get_char_type (code->expr3->ts.kind));
	  else
	    expr3_esize = TYPE_SIZE_UNIT (
		  gfc_typenode_for_spec (&code->expr3->ts));
	}
      gcc_assert (expr3_esize);
      expr3_esize = fold_convert (sizetype, expr3_esize);
      if (e3_is == E3_MOLD)
	/* The expr3 is no longer valid after this point.  */
	expr3 = NULL_TREE;
    }
  else if (code->ext.alloc.ts.type != BT_UNKNOWN)
    {
      /* Compute the explicit typespec given only once for all objects
	 to allocate.  */
      if (code->ext.alloc.ts.type != BT_CHARACTER)
	expr3_esize = TYPE_SIZE_UNIT (
	      gfc_typenode_for_spec (&code->ext.alloc.ts));
      else if (code->ext.alloc.ts.u.cl->length != NULL)
	{
	  gfc_expr *sz;
	  sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
	  gfc_init_se (&se_sz, NULL);
	  gfc_conv_expr (&se_sz, sz);
	  gfc_free_expr (sz);
	  tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
	  tmp = TYPE_SIZE_UNIT (tmp);
	  tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
	  gfc_add_block_to_block (&block, &se_sz.pre);
	  expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
					 TREE_TYPE (se_sz.expr),
					 tmp, se_sz.expr);
	  expr3_esize = gfc_evaluate_now (expr3_esize, &block);
	}
      else
	expr3_esize = NULL_TREE;
    }

  /* The routine gfc_trans_assignment () already implements all
     techniques needed.  Unfortunately we may have a temporary
     variable for the source= expression here.  When that is the
     case convert this variable into a temporary gfc_expr of type
     EXPR_VARIABLE and used it as rhs for the assignment.  The
     advantage is, that we get scalarizer support for free,
     don't have to take care about scalar to array treatment and
     will benefit of every enhancements gfc_trans_assignment ()
     gets.
     No need to check whether e3_is is E3_UNSET, because that is
     done by expr3 != NULL_TREE.
     Exclude variables since the following block does not handle
     array sections.  In any case, there is no harm in sending
     variables to gfc_trans_assignment because there is no
     evaluation of variables.  */
  if (code->expr3)
    {
      if (code->expr3->expr_type != EXPR_VARIABLE
	  && e3_is != E3_MOLD && expr3 != NULL_TREE
	  && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
	{
	  /* Build a temporary symtree and symbol.  Do not add it to the current
	     namespace to prevent accidently modifying a colliding
	     symbol's as.  */
	  newsym = XCNEW (gfc_symtree);
	  /* The name of the symtree should be unique, because gfc_create_var ()
	     took care about generating the identifier.  */
	  newsym->name
	    = gfc_get_string ("%s", IDENTIFIER_POINTER (DECL_NAME (expr3)));
	  newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
	  /* The backend_decl is known.  It is expr3, which is inserted
	     here.  */
	  newsym->n.sym->backend_decl = expr3;
	  e3rhs = gfc_get_expr ();
	  e3rhs->rank = code->expr3->rank;
	  e3rhs->symtree = newsym;
	  /* Mark the symbol referenced or gfc_trans_assignment will bug.  */
	  newsym->n.sym->attr.referenced = 1;
	  e3rhs->expr_type = EXPR_VARIABLE;
	  e3rhs->where = code->expr3->where;
	  /* Set the symbols type, upto it was BT_UNKNOWN.  */
	  if (IS_CLASS_ARRAY (code->expr3)
	      && code->expr3->expr_type == EXPR_FUNCTION
	      && code->expr3->value.function.isym
	      && code->expr3->value.function.isym->transformational)
	    {
	      e3rhs->ts = CLASS_DATA (code->expr3)->ts;
	    }
	  else if (code->expr3->ts.type == BT_CLASS
		   && !GFC_CLASS_TYPE_P (TREE_TYPE (expr3)))
	    e3rhs->ts = CLASS_DATA (code->expr3)->ts;
	  else
	    e3rhs->ts = code->expr3->ts;
	  newsym->n.sym->ts = e3rhs->ts;
	  /* Check whether the expr3 is array valued.  */
	  if (e3rhs->rank)
	    {
	      gfc_array_spec *arr;
	      arr = gfc_get_array_spec ();
	      arr->rank = e3rhs->rank;
	      arr->type = AS_DEFERRED;
	      /* Set the dimension and pointer attribute for arrays
	     to be on the safe side.  */
	      newsym->n.sym->attr.dimension = 1;
	      newsym->n.sym->attr.pointer = 1;
	      newsym->n.sym->as = arr;
	      if (IS_CLASS_ARRAY (code->expr3)
		  && code->expr3->expr_type == EXPR_FUNCTION
		  && code->expr3->value.function.isym
		  && code->expr3->value.function.isym->transformational)
		{
		  gfc_array_spec *tarr;
		  tarr = gfc_get_array_spec ();
		  *tarr = *arr;
		  e3rhs->ts.u.derived->as = tarr;
		}
	      gfc_add_full_array_ref (e3rhs, arr);
	    }
	  else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
	    newsym->n.sym->attr.pointer = 1;
	  /* The string length is known, too.  Set it for char arrays.  */
	  if (e3rhs->ts.type == BT_CHARACTER)
	    newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
	  gfc_commit_symbol (newsym->n.sym);
	}
      else
	e3rhs = gfc_copy_expr (code->expr3);

      // We need to propagate the bounds of the expr3 for source=/mold=;
      // however, for nondescriptor arrays, we use internally a lower bound
      // of zero instead of one, which needs to be corrected for the allocate obj
      if (e3_is == E3_DESC)
	{
	  symbol_attribute attr = gfc_expr_attr (code->expr3);
	  if (code->expr3->expr_type == EXPR_ARRAY ||
	      (!attr.allocatable && !attr.pointer))
	    e3_has_nodescriptor = true;
	}
    }

  /* Loop over all objects to allocate.  */
  for (al = code->ext.alloc.list; al != NULL; al = al->next)
    {
      expr = gfc_copy_expr (al->expr);
      /* UNLIMITED_POLY () needs the _data component to be set, when
	 expr is a unlimited polymorphic object.  But the _data component
	 has not been set yet, so check the derived type's attr for the
	 unlimited polymorphic flag to be safe.  */
      upoly_expr = UNLIMITED_POLY (expr)
		    || (expr->ts.type == BT_DERIVED
			&& expr->ts.u.derived->attr.unlimited_polymorphic);
      gfc_init_se (&se, NULL);

      /* For class types prepare the expressions to ref the _vptr
	 and the _len component.  The latter for unlimited polymorphic
	 types only.  */
      if (expr->ts.type == BT_CLASS)
	{
	  gfc_expr *expr_ref_vptr, *expr_ref_len;
	  gfc_add_data_component (expr);
	  /* Prep the vptr handle.  */
	  expr_ref_vptr = gfc_copy_expr (al->expr);
	  gfc_add_vptr_component (expr_ref_vptr);
	  se.want_pointer = 1;
	  gfc_conv_expr (&se, expr_ref_vptr);
	  al_vptr = se.expr;
	  se.want_pointer = 0;
	  gfc_free_expr (expr_ref_vptr);
	  /* Allocated unlimited polymorphic objects always have a _len
	     component.  */
	  if (upoly_expr)
	    {
	      expr_ref_len = gfc_copy_expr (al->expr);
	      gfc_add_len_component (expr_ref_len);
	      gfc_conv_expr (&se, expr_ref_len);
	      al_len = se.expr;
	      gfc_free_expr (expr_ref_len);
	    }
	  else
	    /* In a loop ensure that all loop variable dependent variables
	       are initialized at the same spot in all execution paths.  */
	    al_len = NULL_TREE;
	}
      else
	al_vptr = al_len = NULL_TREE;

      se.want_pointer = 1;
      se.descriptor_only = 1;

      gfc_conv_expr (&se, expr);
      if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
	/* se.string_length now stores the .string_length variable of expr
	   needed to allocate character(len=:) arrays.  */
	al_len = se.string_length;

      al_len_needs_set = al_len != NULL_TREE;
      /* When allocating an array one cannot use much of the
	 pre-evaluated expr3 expressions, because for most of them the
	 scalarizer is needed which is not available in the pre-evaluation
	 step.  Therefore gfc_array_allocate () is responsible (and able)
	 to handle the complete array allocation.  Only the element size
	 needs to be provided, which is done most of the time by the
	 pre-evaluation step.  */
      nelems = NULL_TREE;
      if (expr3_len && (code->expr3->ts.type == BT_CHARACTER
			|| code->expr3->ts.type == BT_CLASS))
	{
	  /* When al is an array, then the element size for each element
	     in the array is needed, which is the product of the len and
	     esize for char arrays.  For unlimited polymorphics len can be
	     zero, therefore take the maximum of len and one.  */
	  tmp = fold_build2_loc (input_location, MAX_EXPR,
				 TREE_TYPE (expr3_len),
				 expr3_len, fold_convert (TREE_TYPE (expr3_len),
							  integer_one_node));
	  tmp = fold_build2_loc (input_location, MULT_EXPR,
				 TREE_TYPE (expr3_esize), expr3_esize,
				 fold_convert (TREE_TYPE (expr3_esize), tmp));
	}
      else
	tmp = expr3_esize;

      if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
			       label_finish, tmp, &nelems,
			       e3rhs ? e3rhs : code->expr3,
			       e3_is == E3_DESC ? expr3 : NULL_TREE,
			       e3_has_nodescriptor))
	{
	  /* A scalar or derived type.  First compute the size to
	     allocate.

	     expr3_len is set when expr3 is an unlimited polymorphic
	     object or a deferred length string.  */
	  if (expr3_len != NULL_TREE)
	    {
	      tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
	      tmp = fold_build2_loc (input_location, MULT_EXPR,
				     TREE_TYPE (expr3_esize),
				      expr3_esize, tmp);
	      if (code->expr3->ts.type != BT_CLASS)
		/* expr3 is a deferred length string, i.e., we are
		   done.  */
		memsz = tmp;
	      else
		{
		  /* For unlimited polymorphic enties build
			  (len > 0) ? element_size * len : element_size
		     to compute the number of bytes to allocate.
		     This allows the allocation of unlimited polymorphic
		     objects from an expr3 that is also unlimited
		     polymorphic and stores a _len dependent object,
		     e.g., a string.  */
		  memsz = fold_build2_loc (input_location, GT_EXPR,
					   logical_type_node, expr3_len,
					   build_zero_cst
					   (TREE_TYPE (expr3_len)));
		  memsz = fold_build3_loc (input_location, COND_EXPR,
					 TREE_TYPE (expr3_esize),
					 memsz, tmp, expr3_esize);
		}
	    }
	  else if (expr3_esize != NULL_TREE)
	    /* Any other object in expr3 just needs element size in
	       bytes.  */
	    memsz = expr3_esize;
	  else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
		   || (upoly_expr
		       && code->ext.alloc.ts.type == BT_CHARACTER))
	    {
	      /* Allocating deferred length char arrays need the length
		 to allocate in the alloc_type_spec.  But also unlimited
		 polymorphic objects may be allocated as char arrays.
		 Both are handled here.  */
	      gfc_init_se (&se_sz, NULL);
	      gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
	      gfc_add_block_to_block (&se.pre, &se_sz.pre);
	      se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
	      gfc_add_block_to_block (&se.pre, &se_sz.post);
	      expr3_len = se_sz.expr;
	      tmp_expr3_len_flag = true;
	      tmp = TYPE_SIZE_UNIT (
		    gfc_get_char_type (code->ext.alloc.ts.kind));
	      memsz = fold_build2_loc (input_location, MULT_EXPR,
				       TREE_TYPE (tmp),
				       fold_convert (TREE_TYPE (tmp),
						     expr3_len),
				       tmp);
	    }
	  else if (expr->ts.type == BT_CHARACTER)
	    {
	      /* Compute the number of bytes needed to allocate a fixed
		 length char array.  */
	      gcc_assert (se.string_length != NULL_TREE);
	      tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
	      memsz = fold_build2_loc (input_location, MULT_EXPR,
				       TREE_TYPE (tmp), tmp,
				       fold_convert (TREE_TYPE (tmp),
						     se.string_length));
	    }
	  else if (code->ext.alloc.ts.type != BT_UNKNOWN)
	    /* Handle all types, where the alloc_type_spec is set.  */
	    memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
	  else
	    /* Handle size computation of the type declared to alloc.  */
	    memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));

	  /* Store the caf-attributes for latter use.  */
	  if (flag_coarray == GFC_FCOARRAY_LIB
	      && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
		 .codimension)
	    {
	      /* Scalar allocatable components in coarray'ed derived types make
		 it here and are treated now.  */
	      tree caf_decl, token;
	      gfc_se caf_se;

	      is_coarray = true;
	      /* Set flag, to add synchronize after the allocate.  */
	      needs_caf_sync = needs_caf_sync
		  || caf_attr.coarray_comp || !caf_refs_comp;

	      gfc_init_se (&caf_se, NULL);

	      caf_decl = gfc_get_tree_for_caf_expr (expr);
	      gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl,
					NULL_TREE, NULL);
	      gfc_add_block_to_block (&se.pre, &caf_se.pre);
	      gfc_allocate_allocatable (&se.pre, se.expr, memsz,
					gfc_build_addr_expr (NULL_TREE, token),
					NULL_TREE, NULL_TREE, NULL_TREE,
					label_finish, expr, 1);
	    }
	  /* Allocate - for non-pointers with re-alloc checking.  */
	  else if (gfc_expr_attr (expr).allocatable)
	    gfc_allocate_allocatable (&se.pre, se.expr, memsz,
				      NULL_TREE, stat, errmsg, errlen,
				      label_finish, expr, 0);
	  else
	    gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
	}
      else
	{
	  /* Allocating coarrays needs a sync after the allocate executed.
	     Set the flag to add the sync after all objects are allocated.  */
	  if (flag_coarray == GFC_FCOARRAY_LIB
	      && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
		 .codimension)
	    {
	      is_coarray = true;
	      needs_caf_sync = needs_caf_sync
		  || caf_attr.coarray_comp || !caf_refs_comp;
	    }

	  if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
	      && expr3_len != NULL_TREE)
	    {
	      /* Arrays need to have a _len set before the array
		 descriptor is filled.  */
	      gfc_add_modify (&block, al_len,
			      fold_convert (TREE_TYPE (al_len), expr3_len));
	      /* Prevent setting the length twice.  */
	      al_len_needs_set = false;
	    }
	  else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
	      && code->ext.alloc.ts.u.cl->length)
	    {
	      /* Cover the cases where a string length is explicitly
		 specified by a type spec for deferred length character
		 arrays or unlimited polymorphic objects without a
		 source= or mold= expression.  */
	      gfc_init_se (&se_sz, NULL);
	      gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
	      gfc_add_block_to_block (&block, &se_sz.pre);
	      gfc_add_modify (&block, al_len,
			      fold_convert (TREE_TYPE (al_len),
					    se_sz.expr));
	      al_len_needs_set = false;
	    }
	}

      gfc_add_block_to_block (&block, &se.pre);

      /* Error checking -- Note: ERRMSG only makes sense with STAT.  */
      if (code->expr1)
	{
	  tmp = build1_v (GOTO_EXPR, label_errmsg);
	  parm = fold_build2_loc (input_location, NE_EXPR,
				  logical_type_node, stat,
				  build_int_cst (TREE_TYPE (stat), 0));
	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
				 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
				 tmp, build_empty_stmt (input_location));
	  gfc_add_expr_to_block (&block, tmp);
	}

      /* Set the vptr only when no source= is set.  When source= is set, then
	 the trans_assignment below will set the vptr.  */
      if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold))
	{
	  if (expr3_vptr != NULL_TREE)
	    /* The vtab is already known, so just assign it.  */
	    gfc_add_modify (&block, al_vptr,
			    fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
	  else
	    {
	      /* VPTR is fixed at compile time.  */
	      gfc_symbol *vtab;
	      gfc_typespec *ts;

	      if (code->expr3)
		/* Although expr3 is pre-evaluated above, it may happen,
		   that for arrays or in mold= cases the pre-evaluation
		   was not successful.  In these rare cases take the vtab
		   from the typespec of expr3 here.  */
		ts = &code->expr3->ts;
	      else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
		/* The alloc_type_spec gives the type to allocate or the
		   al is unlimited polymorphic, which enforces the use of
		   an alloc_type_spec that is not necessarily a BT_DERIVED.  */
		ts = &code->ext.alloc.ts;
	      else
		/* Prepare for setting the vtab as declared.  */
		ts = &expr->ts;

	      vtab = gfc_find_vtab (ts);
	      gcc_assert (vtab);
	      tmp = gfc_build_addr_expr (NULL_TREE,
					 gfc_get_symbol_decl (vtab));
	      gfc_add_modify (&block, al_vptr,
			      fold_convert (TREE_TYPE (al_vptr), tmp));
	    }
	}

      /* Add assignment for string length.  */
      if (al_len != NULL_TREE && al_len_needs_set)
	{
	  if (expr3_len != NULL_TREE)
	    {
	      gfc_add_modify (&block, al_len,
			      fold_convert (TREE_TYPE (al_len),
					    expr3_len));
	      /* When tmp_expr3_len_flag is set, then expr3_len is
		 abused to carry the length information from the
		 alloc_type.  Clear it to prevent setting incorrect len
		 information in future loop iterations.  */
	      if (tmp_expr3_len_flag)
		/* No need to reset tmp_expr3_len_flag, because the
		   presence of an expr3 cannot change within in the
		   loop.  */
		expr3_len = NULL_TREE;
	    }
	  else if (code->ext.alloc.ts.type == BT_CHARACTER
	      && code->ext.alloc.ts.u.cl->length)
	    {
	      /* Cover the cases where a string length is explicitly
		 specified by a type spec for deferred length character
		 arrays or unlimited polymorphic objects without a
		 source= or mold= expression.  */
	      if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
		{
		  gfc_init_se (&se_sz, NULL);
		  gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
		  gfc_add_block_to_block (&block, &se_sz.pre);
		  gfc_add_modify (&block, al_len,
				  fold_convert (TREE_TYPE (al_len),
						se_sz.expr));
		}
	      else
		gfc_add_modify (&block, al_len,
				fold_convert (TREE_TYPE (al_len),
					      expr3_esize));
	    }
	  else
	    /* No length information needed, because type to allocate
	       has no length.  Set _len to 0.  */
	    gfc_add_modify (&block, al_len,
			    fold_convert (TREE_TYPE (al_len),
					  integer_zero_node));
	}

      init_expr = NULL;
      if (code->expr3 && !code->expr3->mold && e3_is != E3_MOLD)
	{
	  /* Initialization via SOURCE block (or static default initializer).
	     Switch off automatic reallocation since we have just done the
	     ALLOCATE.  */
	  int realloc_lhs = flag_realloc_lhs;
	  gfc_expr *init_expr = gfc_expr_to_initialize (expr);
	  gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
	  flag_realloc_lhs = 0;
	  tmp = gfc_trans_assignment (init_expr, rhs, false, false, true,
				      false);
	  flag_realloc_lhs = realloc_lhs;
	  /* Free the expression allocated for init_expr.  */
	  gfc_free_expr (init_expr);
	  if (rhs != e3rhs)
	    gfc_free_expr (rhs);
	  gfc_add_expr_to_block (&block, tmp);
	}
      /* Set KIND and LEN PDT components and allocate those that are
         parameterized.  */
      else if (expr->ts.type == BT_DERIVED
	       && expr->ts.u.derived->attr.pdt_type)
	{
	  if (code->expr3 && code->expr3->param_list)
	    param_list = code->expr3->param_list;
	  else if (expr->param_list)
	    param_list = expr->param_list;
	  else
	    param_list = expr->symtree->n.sym->param_list;
	  tmp = gfc_allocate_pdt_comp (expr->ts.u.derived, se.expr,
				       expr->rank, param_list);
	  gfc_add_expr_to_block (&block, tmp);
	}
      /* Ditto for CLASS expressions.  */
      else if (expr->ts.type == BT_CLASS
	       && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type)
	{
	  if (code->expr3 && code->expr3->param_list)
	    param_list = code->expr3->param_list;
	  else if (expr->param_list)
	    param_list = expr->param_list;
	  else
	    param_list = expr->symtree->n.sym->param_list;
	  tmp = gfc_allocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
				       se.expr, expr->rank, param_list);
	  gfc_add_expr_to_block (&block, tmp);
	}
      else if (code->expr3 && code->expr3->mold
	       && code->expr3->ts.type == BT_CLASS)
	{
	  /* Use class_init_assign to initialize expr.  */
	  gfc_code *ini;
	  ini = gfc_get_code (EXEC_INIT_ASSIGN);
	  ini->expr1 = gfc_find_and_cut_at_last_class_ref (expr, true);
	  tmp = gfc_trans_class_init_assign (ini);
	  gfc_free_statements (ini);
	  gfc_add_expr_to_block (&block, tmp);
	}
      else if ((init_expr = allocate_get_initializer (code, expr)))
	{
	  /* Use class_init_assign to initialize expr.  */
	  gfc_code *ini;
	  int realloc_lhs = flag_realloc_lhs;
	  ini = gfc_get_code (EXEC_INIT_ASSIGN);
	  ini->expr1 = gfc_expr_to_initialize (expr);
	  ini->expr2 = init_expr;
	  flag_realloc_lhs = 0;
	  tmp= gfc_trans_init_assign (ini);
	  flag_realloc_lhs = realloc_lhs;
	  gfc_free_statements (ini);
	  /* Init_expr is freeed by above free_statements, just need to null
	     it here.  */
	  init_expr = NULL;
	  gfc_add_expr_to_block (&block, tmp);
	}

      /* Nullify all pointers in derived type coarrays.  This registers a
	 token for them which allows their allocation.  */
      if (is_coarray)
	{
	  gfc_symbol *type = NULL;
	  symbol_attribute caf_attr;
	  int rank = 0;
	  if (code->ext.alloc.ts.type == BT_DERIVED
	      && code->ext.alloc.ts.u.derived->attr.pointer_comp)
	    {
	      type = code->ext.alloc.ts.u.derived;
	      rank = type->attr.dimension ? type->as->rank : 0;
	      gfc_clear_attr (&caf_attr);
	    }
	  else if (expr->ts.type == BT_DERIVED
		   && expr->ts.u.derived->attr.pointer_comp)
	    {
	      type = expr->ts.u.derived;
	      rank = expr->rank;
	      caf_attr = gfc_caf_attr (expr, true);
	    }

	  /* Initialize the tokens of pointer components in derived type
	     coarrays.  */
	  if (type)
	    {
	      tmp = (caf_attr.codimension && !caf_attr.dimension)
		  ? gfc_conv_descriptor_data_get (se.expr) : se.expr;
	      tmp = gfc_nullify_alloc_comp (type, tmp, rank,
					    GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
	      gfc_add_expr_to_block (&block, tmp);
	    }
	}

      gfc_free_expr (expr);
    } // for-loop

  if (e3rhs)
    {
      if (newsym)
	{
	  gfc_free_symbol (newsym->n.sym);
	  XDELETE (newsym);
	}
      gfc_free_expr (e3rhs);
    }
  /* STAT.  */
  if (code->expr1)
    {
      tmp = build1_v (LABEL_EXPR, label_errmsg);
      gfc_add_expr_to_block (&block, tmp);
    }

  /* ERRMSG - only useful if STAT is present.  */
  if (code->expr1 && code->expr2)
    {
      const char *msg = "Attempt to allocate an allocated object";
      tree slen, dlen, errmsg_str;
      stmtblock_t errmsg_block;

      gfc_init_block (&errmsg_block);

      errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
      gfc_add_modify (&errmsg_block, errmsg_str,
		gfc_build_addr_expr (pchar_type_node,
			gfc_build_localized_cstring_const (msg)));

      slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
      dlen = gfc_get_expr_charlen (code->expr2);
      slen = fold_build2_loc (input_location, MIN_EXPR,
			      TREE_TYPE (slen), dlen, slen);

      gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
			     code->expr2->ts.kind,
			     slen, errmsg_str,
			     gfc_default_character_kind);
      dlen = gfc_finish_block (&errmsg_block);

      tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			     stat, build_int_cst (TREE_TYPE (stat), 0));

      tmp = build3_v (COND_EXPR, tmp,
		      dlen, build_empty_stmt (input_location));

      gfc_add_expr_to_block (&block, tmp);
    }

  /* STAT block.  */
  if (code->expr1)
    {
      if (TREE_USED (label_finish))
	{
	  tmp = build1_v (LABEL_EXPR, label_finish);
	  gfc_add_expr_to_block (&block, tmp);
	}

      gfc_init_se (&se, NULL);
      gfc_conv_expr_lhs (&se, code->expr1);
      tmp = convert (TREE_TYPE (se.expr), stat);
      gfc_add_modify (&block, se.expr, tmp);
    }

  if (needs_caf_sync)
    {
      /* Add a sync all after the allocation has been executed.  */
      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
				 3, null_pointer_node, null_pointer_node,
				 integer_zero_node);
      gfc_add_expr_to_block (&post, tmp);
    }

  gfc_add_block_to_block (&block, &se.post);
  gfc_add_block_to_block (&block, &post);
  if (code->expr3 && code->expr3->must_finalize)
    gfc_add_block_to_block (&block, &final_block);

  return gfc_finish_block (&block);
}


/* Translate a DEALLOCATE statement.  */

tree
gfc_trans_deallocate (gfc_code *code)
{
  gfc_se se;
  gfc_alloc *al;
  tree apstat, pstat, stat, errmsg, errlen, tmp;
  tree label_finish, label_errmsg;
  stmtblock_t block;

  pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
  label_finish = label_errmsg = NULL_TREE;

  gfc_start_block (&block);

  /* Count the number of failed deallocations.  If deallocate() was
     called with STAT= , then set STAT to the count.  If deallocate
     was called with ERRMSG, then set ERRMG to a string.  */
  if (code->expr1)
    {
      tree gfc_int4_type_node = gfc_get_int_type (4);

      stat = gfc_create_var (gfc_int4_type_node, "stat");
      pstat = gfc_build_addr_expr (NULL_TREE, stat);

      /* GOTO destinations.  */
      label_errmsg = gfc_build_label_decl (NULL_TREE);
      label_finish = gfc_build_label_decl (NULL_TREE);
      TREE_USED (label_finish) = 0;
    }

  /* Set ERRMSG - only needed if STAT is available.  */
  if (code->expr1 && code->expr2)
    {
      gfc_init_se (&se, NULL);
      se.want_pointer = 1;
      gfc_conv_expr_lhs (&se, code->expr2);
      errmsg = se.expr;
      errlen = se.string_length;
    }

  for (al = code->ext.alloc.list; al != NULL; al = al->next)
    {
      gfc_expr *expr = gfc_copy_expr (al->expr);
      bool is_coarray = false, is_coarray_array = false;
      int caf_mode = 0;

      gcc_assert (expr->expr_type == EXPR_VARIABLE);

      if (expr->ts.type == BT_CLASS)
	gfc_add_data_component (expr);

      gfc_init_se (&se, NULL);
      gfc_start_block (&se.pre);

      se.want_pointer = 1;
      se.descriptor_only = 1;
      gfc_conv_expr (&se, expr);

      /* Deallocate PDT components that are parameterized.  */
      tmp = NULL;
      if (expr->ts.type == BT_DERIVED
	  && expr->ts.u.derived->attr.pdt_type
	  && expr->symtree->n.sym->param_list)
	tmp = gfc_deallocate_pdt_comp (expr->ts.u.derived, se.expr, expr->rank);
      else if (expr->ts.type == BT_CLASS
	       && CLASS_DATA (expr)->ts.u.derived->attr.pdt_type
	       && expr->symtree->n.sym->param_list)
	tmp = gfc_deallocate_pdt_comp (CLASS_DATA (expr)->ts.u.derived,
				       se.expr, expr->rank);

      if (tmp)
	gfc_add_expr_to_block (&block, tmp);

      if (flag_coarray == GFC_FCOARRAY_LIB
	  || flag_coarray == GFC_FCOARRAY_SINGLE)
	{
	  bool comp_ref;
	  symbol_attribute caf_attr = gfc_caf_attr (expr, false, &comp_ref);
	  if (caf_attr.codimension)
	    {
	      is_coarray = true;
	      is_coarray_array = caf_attr.dimension || !comp_ref
		  || caf_attr.coarray_comp;

	      if (flag_coarray == GFC_FCOARRAY_LIB)
		/* When the expression to deallocate is referencing a
		   component, then only deallocate it, but do not
		   deregister.  */
		caf_mode = GFC_STRUCTURE_CAF_MODE_IN_COARRAY
		    | (comp_ref && !caf_attr.coarray_comp
		       ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0);
	    }
	}

      if (expr->rank || is_coarray_array)
	{
	  gfc_ref *ref;

	  if (gfc_bt_struct (expr->ts.type)
	      && expr->ts.u.derived->attr.alloc_comp
	      && !gfc_is_finalizable (expr->ts.u.derived, NULL))
	    {
	      gfc_ref *last = NULL;

	      for (ref = expr->ref; ref; ref = ref->next)
		if (ref->type == REF_COMPONENT)
		  last = ref;

	      /* Do not deallocate the components of a derived type
		 ultimate pointer component.  */
	      if (!(last && last->u.c.component->attr.pointer)
		    && !(!last && expr->symtree->n.sym->attr.pointer))
		{
		  if (is_coarray && expr->rank == 0
		      && (!last || !last->u.c.component->attr.dimension)
		      && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
		    {
		      /* Add the ref to the data member only, when this is not
			 a regular array or deallocate_alloc_comp will try to
			 add another one.  */
		      tmp = gfc_conv_descriptor_data_get (se.expr);
		    }
		  else
		    tmp = se.expr;
		  tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp,
						   expr->rank, caf_mode);
		  gfc_add_expr_to_block (&se.pre, tmp);
		}
	    }

	  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
	    {
	      gfc_coarray_deregtype caf_dtype;

	      if (is_coarray)
		caf_dtype = gfc_caf_is_dealloc_only (caf_mode)
		    ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
		    : GFC_CAF_COARRAY_DEREGISTER;
	      else
		caf_dtype = GFC_CAF_COARRAY_NOCOARRAY;
	      tmp = gfc_deallocate_with_status (se.expr, pstat, errmsg, errlen,
						label_finish, false, expr,
						caf_dtype);
	      gfc_add_expr_to_block (&se.pre, tmp);
	    }
	  else if (TREE_CODE (se.expr) == COMPONENT_REF
		   && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
		   && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
			== RECORD_TYPE)
	    {
	      /* class.c(finalize_component) generates these, when a
		 finalizable entity has a non-allocatable derived type array
		 component, which has allocatable components. Obtain the
		 derived type of the array and deallocate the allocatable
		 components. */
	      for (ref = expr->ref; ref; ref = ref->next)
		{
		  if (ref->u.c.component->attr.dimension
		      && ref->u.c.component->ts.type == BT_DERIVED)
		    break;
		}

	      if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
		  && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
					  NULL))
		{
		  tmp = gfc_deallocate_alloc_comp
				(ref->u.c.component->ts.u.derived,
				 se.expr, expr->rank);
		  gfc_add_expr_to_block (&se.pre, tmp);
		}
	    }

	  if (al->expr->ts.type == BT_CLASS)
	    {
	      gfc_reset_vptr (&se.pre, al->expr);
	      if (UNLIMITED_POLY (al->expr)
		  || (al->expr->ts.type == BT_DERIVED
		      && al->expr->ts.u.derived->attr.unlimited_polymorphic))
		/* Clear _len, too.  */
		gfc_reset_len (&se.pre, al->expr);
	    }
	}
      else
	{
	  tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, label_finish,
						   false, al->expr,
						   al->expr->ts, is_coarray);
	  gfc_add_expr_to_block (&se.pre, tmp);

	  /* Set to zero after deallocation.  */
	  tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
				 se.expr,
				 build_int_cst (TREE_TYPE (se.expr), 0));
	  gfc_add_expr_to_block (&se.pre, tmp);

	  if (al->expr->ts.type == BT_CLASS)
	    {
	      gfc_reset_vptr (&se.pre, al->expr);
	      if (UNLIMITED_POLY (al->expr)
		  || (al->expr->ts.type == BT_DERIVED
		      && al->expr->ts.u.derived->attr.unlimited_polymorphic))
		/* Clear _len, too.  */
		gfc_reset_len (&se.pre, al->expr);
	    }
	}

      if (code->expr1)
	{
          tree cond;

	  cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
				  build_int_cst (TREE_TYPE (stat), 0));
	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
				 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
				 build1_v (GOTO_EXPR, label_errmsg),
				 build_empty_stmt (input_location));
	  gfc_add_expr_to_block (&se.pre, tmp);
	}

      tmp = gfc_finish_block (&se.pre);
      gfc_add_expr_to_block (&block, tmp);
      gfc_free_expr (expr);
    }

  if (code->expr1)
    {
      tmp = build1_v (LABEL_EXPR, label_errmsg);
      gfc_add_expr_to_block (&block, tmp);
    }

  /* Set ERRMSG - only needed if STAT is available.  */
  if (code->expr1 && code->expr2)
    {
      const char *msg = "Attempt to deallocate an unallocated object";
      stmtblock_t errmsg_block;
      tree errmsg_str, slen, dlen, cond;

      gfc_init_block (&errmsg_block);

      errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
      gfc_add_modify (&errmsg_block, errmsg_str,
		gfc_build_addr_expr (pchar_type_node,
                        gfc_build_localized_cstring_const (msg)));
      slen = build_int_cst (gfc_charlen_type_node, strlen (msg));
      dlen = gfc_get_expr_charlen (code->expr2);

      gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
			     slen, errmsg_str, gfc_default_character_kind);
      tmp = gfc_finish_block (&errmsg_block);

      cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, stat,
			     build_int_cst (TREE_TYPE (stat), 0));
      tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
			     gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
			     build_empty_stmt (input_location));

      gfc_add_expr_to_block (&block, tmp);
    }

  if (code->expr1 && TREE_USED (label_finish))
    {
      tmp = build1_v (LABEL_EXPR, label_finish);
      gfc_add_expr_to_block (&block, tmp);
    }

  /* Set STAT.  */
  if (code->expr1)
    {
      gfc_init_se (&se, NULL);
      gfc_conv_expr_lhs (&se, code->expr1);
      tmp = convert (TREE_TYPE (se.expr), stat);
      gfc_add_modify (&block, se.expr, tmp);
    }

  return gfc_finish_block (&block);
}

#include "gt-fortran-trans-stmt.h"
