/* Statement translation -- generate GCC trees from gfc_code.
   Copyright (C) 2002-2020 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 ? gfc_get_location (&code->expr1->where)
			      : 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)
    {
      tree zero_size = build_zero_cst (size_type_node);
      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, zero_size, integer_one_node,
				 null_pointer_node, null_pointer_node,
				 null_pointer_node, zero_size);
      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)
    {
      tree zero_size = build_zero_cst (size_type_node);
      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
				 token, zero_size, integer_one_node,
				 null_pointer_node, null_pointer_node,
				 zero_size);
      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;
}


static void
copy_descriptor (stmtblock_t *block, tree dst, tree src, int rank)
{
  int n;
  tree dim;
  tree tmp;
  tree tmp2;
  tree size;
  tree offset;

  offset = gfc_index_zero_node;

  /* Use memcpy to copy the descriptor. The size is the minimum of
     the sizes of 'src' and 'dst'. This avoids a non-trivial conversion.  */
  tmp = TYPE_SIZE_UNIT (TREE_TYPE (src));
  tmp2 = TYPE_SIZE_UNIT (TREE_TYPE (dst));
  size = fold_build2_loc (input_location, MIN_EXPR,
			  TREE_TYPE (tmp), tmp, tmp2);
  tmp = builtin_decl_explicit (BUILT_IN_MEMCPY);
  tmp = build_call_expr_loc (input_location, tmp, 3,
			     gfc_build_addr_expr (NULL_TREE, dst),
			     gfc_build_addr_expr (NULL_TREE, src),
			     fold_convert (size_type_node, size));
  gfc_add_expr_to_block (block, tmp);

  /* Set the offset correctly.  */
  for (n = 0; n < rank; n++)
    {
      dim = gfc_rank_cst[n];
      tmp = gfc_conv_descriptor_lbound_get (src, dim);
      tmp2 = gfc_conv_descriptor_stride_get (src, dim);
      tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
			     tmp, tmp2);
      offset = fold_build2_loc (input_location, MINUS_EXPR,
			TREE_TYPE (offset), offset, tmp);
      offset = gfc_evaluate_now (offset, block);
    }

  gfc_conv_descriptor_offset_set (block, dst, offset);
}


/* 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;
  gfc_symbol *sym2;

  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)))
      && !sym->attr.select_rank_temporary);

  /* 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. Select rank temporaries need somewhat different treatment
     to other associate names and case temporaries. This because the selector
     is assumed rank and so the offset in particular has to be changed. Also,
     the case temporaries carry both allocatable and target attributes if
     present in the selector. This means that an allocatation or change of
     association can occur and so has to be dealt with.  */
  if (sym->attr.select_rank_temporary)
    {
      gfc_se se;
      tree class_decl = NULL_TREE;
      int rank = 0;
      bool class_ptr;

      sym2 = e->symtree->n.sym;
      gfc_init_se (&se, NULL);
      if (e->ts.type == BT_CLASS)
	{
	  /* Go straight to the class data.  */
	  if (sym2->attr.dummy)
	    {
	      class_decl = DECL_LANG_SPECIFIC (sym2->backend_decl) ?
			   GFC_DECL_SAVED_DESCRIPTOR (sym2->backend_decl) :
			   sym2->backend_decl;
	      if (POINTER_TYPE_P (TREE_TYPE (class_decl)))
		class_decl = build_fold_indirect_ref_loc (input_location,
							  class_decl);
	      gcc_assert (GFC_CLASS_TYPE_P (TREE_TYPE (class_decl)));
	      se.expr = gfc_class_data_get (class_decl);
	    }
	  else
	    {
	      class_decl = sym2->backend_decl;
	      gfc_conv_expr_descriptor (&se, e);
	      if (POINTER_TYPE_P (TREE_TYPE (se.expr)))
		se.expr = build_fold_indirect_ref_loc (input_location,
						       se.expr);
	    }

	  if (CLASS_DATA (sym)->as && CLASS_DATA (sym)->as->rank > 0)
	    rank = CLASS_DATA (sym)->as->rank;
	}
      else
	{
	  gfc_conv_expr_descriptor (&se, e);
	  if (sym->as && sym->as->rank > 0)
	    rank = sym->as->rank;
	}

      desc = sym->backend_decl;

      /* The SELECT TYPE mechanisms turn class temporaries into pointers, which
	 point to the selector. */
      class_ptr = class_decl != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (desc));
      if (class_ptr)
	{
	  tmp = gfc_create_var (TREE_TYPE (TREE_TYPE (desc)), "class");
	  tmp = gfc_build_addr_expr (NULL, tmp);
	  gfc_add_modify (&se.pre, desc, tmp);

	  tmp = gfc_class_vptr_get (class_decl);
	  gfc_add_modify (&se.pre, gfc_class_vptr_get (desc), tmp);
	  if (UNLIMITED_POLY (sym))
	    gfc_add_modify (&se.pre, gfc_class_len_get (desc),
			    gfc_class_len_get (class_decl));

	  desc = gfc_class_data_get (desc);
	}

      /* SELECT RANK temporaries can carry the allocatable and pointer
	 attributes so the selector descriptor must be copied in and
	 copied out.  */
      if (rank > 0)
	copy_descriptor (&se.pre, desc, se.expr, rank);
      else
	{
	  tmp = gfc_conv_descriptor_data_get (se.expr);
	  gfc_add_modify (&se.pre, desc,
			  fold_convert (TREE_TYPE (desc), tmp));
	}

      /* Deal with associate_name => selector. Class associate names are
	 treated in the same way as in SELECT TYPE.  */
      sym2 = sym->assoc->target->symtree->n.sym;
      if (sym2->assoc && sym->assoc->target && sym2->ts.type != BT_CLASS)
	{
	  sym2 = sym2->assoc->target->symtree->n.sym;
	  se.expr = sym2->backend_decl;

	  if (POINTER_TYPE_P (TREE_TYPE (se.expr)))
	    se.expr = build_fold_indirect_ref_loc (input_location,
						   se.expr);
	}

      /* There could have been reallocation.  Copy descriptor back to the
	 selector and update the offset.  */
      if (sym->attr.allocatable || sym->attr.pointer
	  || (sym->ts.type == BT_CLASS
	      && (CLASS_DATA (sym)->attr.allocatable
		  || CLASS_DATA (sym)->attr.pointer)))
	{
	  if (rank > 0)
	    copy_descriptor (&se.post, se.expr, desc, rank);
	  else
	    gfc_conv_descriptor_data_set (&se.post, se.expr, desc);

	  /* The dynamic type could have changed too.  */
	  if (sym->ts.type == BT_CLASS)
	    {
	      tmp = sym->backend_decl;
	      if (class_ptr)
		tmp = build_fold_indirect_ref_loc (input_location, tmp);
	      gfc_add_modify (&se.post, gfc_class_vptr_get (class_decl),
			      gfc_class_vptr_get (tmp));
	      if (UNLIMITED_POLY (sym))
		gfc_add_modify (&se.post, gfc_class_len_get (class_decl),
				gfc_class_len_get (tmp));
	    }
	}

      tmp = gfc_finish_block (&se.post);

      gfc_add_init_cleanup (block, gfc_finish_block (&se.pre), tmp);
    }
  /* Now all the other kinds of associate variable.  */
  else 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
	{
	  tree ctree = gfc_get_class_from_expr (se.expr);
	  tmp = TREE_TYPE (sym->backend_decl);

	  /* Coarray scalar component expressions can emerge from
	     the front end as array elements of the _data field.  */
	  if (sym->ts.type == BT_CLASS
	      && e->ts.type == BT_CLASS && e->rank == 0
	      && !GFC_CLASS_TYPE_P (TREE_TYPE (se.expr)) && ctree)
	    {
	      tree stmp;
	      tree dtmp;

	      se.expr = ctree;
	      dtmp = TREE_TYPE (TREE_TYPE (sym->backend_decl));
	      ctree = gfc_create_var (dtmp, "class");

	      stmp = gfc_class_data_get (se.expr);
	      gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (stmp)));

	      /* Set the fields of the target class variable.  */
	      stmp = gfc_conv_descriptor_data_get (stmp);
	      dtmp = gfc_class_data_get (ctree);
	      stmp = fold_convert (TREE_TYPE (dtmp), stmp);
	      gfc_add_modify (&se.pre, dtmp, stmp);
	      stmp = gfc_class_vptr_get (se.expr);
	      dtmp = gfc_class_vptr_get (ctree);
	      stmp = fold_convert (TREE_TYPE (dtmp), stmp);
	      gfc_add_modify (&se.pre, dtmp, stmp);
	      if (UNLIMITED_POLY (sym))
		{
		  stmp = gfc_class_len_get (se.expr);
		  dtmp = gfc_class_len_get (ctree);
		  stmp = fold_convert (TREE_TYPE (dtmp), stmp);
		  gfc_add_modify (&se.pre, dtmp, stmp);
		}
	      se.expr = ctree;
	    }
	  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 = gfc_get_location (&code->ext.iterator->start->where);

  /* 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));

  if (code->ext.iterator->ivdep && cond != error_mark_node)
    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
		   build_int_cst (integer_type_node, annot_expr_ivdep_kind),
		   integer_zero_node);
  if (code->ext.iterator->vector && cond != error_mark_node)
    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
		   build_int_cst (integer_type_node, annot_expr_vector_kind),
		   integer_zero_node);
  if (code->ext.iterator->novector && cond != error_mark_node)
    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
		   build_int_cst (integer_type_node, annot_expr_no_vector_kind),
		   integer_zero_node);

  /* 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 = gfc_get_location (&code->ext.iterator->start->where);

  /* 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));

  if (code->ext.iterator->ivdep && cond != error_mark_node)
    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
		   build_int_cst (integer_type_node, annot_expr_ivdep_kind),
		   integer_zero_node);
  if (code->ext.iterator->vector && cond != error_mark_node)
    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
		   build_int_cst (integer_type_node, annot_expr_vector_kind),
		   integer_zero_node);
  if (code->ext.iterator->novector && cond != error_mark_node)
    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
		   build_int_cst (integer_type_node, annot_expr_no_vector_kind),
		   integer_zero_node);

  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 (gfc_get_location (&code->expr1->where),
			       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 (gfc_get_location (&code->expr1->where), COND_EXPR,
			 void_type_node, cond.expr, tmp,
			 build_empty_stmt (gfc_get_location (
					     &code->expr1->where)));
  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 (gfc_get_location (&code->expr1->where), 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);
}


static tree
gfc_trans_select_rank_cases (gfc_code * code)
{
  gfc_code *c;
  gfc_case *cp;
  tree tmp;
  tree cond;
  tree low;
  tree sexpr;
  tree rank;
  tree rank_minus_one;
  tree minus_one;
  gfc_se se;
  gfc_se cse;
  stmtblock_t block;
  stmtblock_t body;
  bool def = false;

  gfc_start_block (&block);

  /* Calculate the switch expression.  */
  gfc_init_se (&se, NULL);
  gfc_conv_expr_descriptor (&se, code->expr1);
  rank = gfc_conv_descriptor_rank (se.expr);
  rank = gfc_evaluate_now (rank, &block);
  minus_one = build_int_cst (TREE_TYPE (rank), -1);
  tmp = fold_build2_loc (input_location, MINUS_EXPR,
			 gfc_array_index_type,
			 fold_convert (gfc_array_index_type, rank),
			 build_int_cst (gfc_array_index_type, 1));
  rank_minus_one = gfc_evaluate_now (tmp, &block);
  tmp = gfc_conv_descriptor_ubound_get (se.expr, rank_minus_one);
  cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			  tmp, build_int_cst (TREE_TYPE (tmp), -1));
  tmp = fold_build3_loc (input_location, COND_EXPR,
			 TREE_TYPE (rank), cond,
			 rank, minus_one);
  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
			  rank, build_int_cst (TREE_TYPE (rank), 0));
  sexpr = fold_build3_loc (input_location, COND_EXPR,
			   TREE_TYPE (rank), cond,
			   rank, tmp);
  sexpr = gfc_evaluate_now (sexpr, &block);
  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;
      tmp = NULL_TREE;

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

      if (cp->low)
	{
	  gfc_init_se (&cse, NULL);
	  gfc_conv_expr_val (&cse, cp->low);
	  gfc_add_block_to_block (&block, &cse.pre);
	  low = 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 RANK 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)
	{
	  cond = fold_build2_loc (input_location, EQ_EXPR,
				  TREE_TYPE (sexpr), sexpr,
				  fold_convert (TREE_TYPE (sexpr), low));
	  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;
    }

  return gfc_finish_block (&block);
}


tree
gfc_trans_select_rank (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_rank_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.  */
      tree zero_size = build_zero_cst (size_type_node);
      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
				 3, null_pointer_node, null_pointer_node,
				 zero_size);
      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"
