/* Routines for manipulation of expression nodes.
   Copyright (C) 2000-2025 Free Software Foundation, Inc.
   Contributed by Andy Vaught

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 "gfortran.h"
#include "arith.h"
#include "match.h"
#include "target-memory.h" /* for gfc_convert_boz */
#include "constructor.h"
#include "tree.h"


/* The following set of functions provide access to gfc_expr* of
   various types - actual all but EXPR_FUNCTION and EXPR_VARIABLE.

   There are two functions available elsewhere that provide
   slightly different flavours of variables.  Namely:
     expr.cc (gfc_get_variable_expr)
     symbol.cc (gfc_lval_expr_from_sym)
   TODO: Merge these functions, if possible.  */

/* Get a new expression node.  */

gfc_expr *
gfc_get_expr (void)
{
  gfc_expr *e;

  e = XCNEW (gfc_expr);
  gfc_clear_ts (&e->ts);
  e->shape = NULL;
  e->ref = NULL;
  e->symtree = NULL;
  return e;
}


/* Get a new expression node that is an array constructor
   of given type and kind.  */

gfc_expr *
gfc_get_array_expr (bt type, int kind, locus *where)
{
  gfc_expr *e;

  e = gfc_get_expr ();
  e->expr_type = EXPR_ARRAY;
  e->value.constructor = NULL;
  e->rank = 1;
  e->shape = NULL;

  e->ts.type = type;
  e->ts.kind = kind;
  if (where)
    e->where = *where;

  return e;
}


/* Get a new expression node that is the NULL expression.  */

gfc_expr *
gfc_get_null_expr (locus *where)
{
  gfc_expr *e;

  e = gfc_get_expr ();
  e->expr_type = EXPR_NULL;
  e->ts.type = BT_UNKNOWN;

  if (where)
    e->where = *where;

  return e;
}


/* Get a new expression node that is an operator expression node.  */

gfc_expr *
gfc_get_operator_expr (locus *where, gfc_intrinsic_op op,
                      gfc_expr *op1, gfc_expr *op2)
{
  gfc_expr *e;

  e = gfc_get_expr ();
  e->expr_type = EXPR_OP;
  e->value.op.op = op;
  e->value.op.op1 = op1;
  e->value.op.op2 = op2;

  if (where)
    e->where = *where;

  return e;
}


/* Get a new expression node that is an structure constructor
   of given type and kind.  */

gfc_expr *
gfc_get_structure_constructor_expr (bt type, int kind, locus *where)
{
  gfc_expr *e;

  e = gfc_get_expr ();
  e->expr_type = EXPR_STRUCTURE;
  e->value.constructor = NULL;

  e->ts.type = type;
  e->ts.kind = kind;
  if (where)
    e->where = *where;

  return e;
}


/* Get a new expression node that is an constant of given type and kind.  */

gfc_expr *
gfc_get_constant_expr (bt type, int kind, locus *where)
{
  gfc_expr *e;

  if (!where)
    gfc_internal_error ("gfc_get_constant_expr(): locus %<where%> cannot be "
			"NULL");

  e = gfc_get_expr ();

  e->expr_type = EXPR_CONSTANT;
  e->ts.type = type;
  e->ts.kind = kind;
  e->where = *where;

  switch (type)
    {
    case BT_INTEGER:
    case BT_UNSIGNED:
      mpz_init (e->value.integer);
      break;

    case BT_REAL:
      gfc_set_model_kind (kind);
      mpfr_init (e->value.real);
      break;

    case BT_COMPLEX:
      gfc_set_model_kind (kind);
      mpc_init2 (e->value.complex, mpfr_get_default_prec());
      break;

    default:
      break;
    }

  return e;
}


/* Get a new expression node that is an string constant.
   If no string is passed, a string of len is allocated,
   blanked and null-terminated.  */

gfc_expr *
gfc_get_character_expr (int kind, locus *where, const char *src, gfc_charlen_t len)
{
  gfc_expr *e;
  gfc_char_t *dest;

  if (!src)
    {
      dest = gfc_get_wide_string (len + 1);
      gfc_wide_memset (dest, ' ', len);
      dest[len] = '\0';
    }
  else
    dest = gfc_char_to_widechar (src);

  e = gfc_get_constant_expr (BT_CHARACTER, kind,
                            where ? where : &gfc_current_locus);
  e->value.character.string = dest;
  e->value.character.length = len;

  return e;
}


/* Get a new expression node that is an integer constant.  */

gfc_expr *
gfc_get_int_expr (int kind, locus *where, HOST_WIDE_INT value)
{
  gfc_expr *p;
  p = gfc_get_constant_expr (BT_INTEGER, kind,
			     where ? where : &gfc_current_locus);

  const wide_int w = wi::shwi (value, kind * BITS_PER_UNIT);
  wi::to_mpz (w, p->value.integer, SIGNED);

  return p;
}

/* Get a new expression node that is an unsigned constant.  */

gfc_expr *
gfc_get_unsigned_expr (int kind, locus *where, HOST_WIDE_INT value)
{
  gfc_expr *p;
  p = gfc_get_constant_expr (BT_UNSIGNED, kind,
			     where ? where : &gfc_current_locus);
  const wide_int w = wi::shwi (value, kind * BITS_PER_UNIT);
  wi::to_mpz (w, p->value.integer, UNSIGNED);

  return p;
}

/* Get a new expression node that is a logical constant.  */

gfc_expr *
gfc_get_logical_expr (int kind, locus *where, bool value)
{
  gfc_expr *p;
  p = gfc_get_constant_expr (BT_LOGICAL, kind,
			     where ? where : &gfc_current_locus);

  p->value.logical = value;

  return p;
}


gfc_expr *
gfc_get_iokind_expr (locus *where, io_kind k)
{
  gfc_expr *e;

  /* Set the types to something compatible with iokind. This is needed to
     get through gfc_free_expr later since iokind really has no Basic Type,
     BT, of its own.  */

  e = gfc_get_expr ();
  e->expr_type = EXPR_CONSTANT;
  e->ts.type = BT_LOGICAL;
  e->value.iokind = k;
  e->where = *where;

  return e;
}


/* Given an expression pointer, return a copy of the expression.  This
   subroutine is recursive.  */

gfc_expr *
gfc_copy_expr (gfc_expr *p)
{
  gfc_expr *q;
  gfc_char_t *s;
  char *c;

  if (p == NULL)
    return NULL;

  q = gfc_get_expr ();
  *q = *p;

  switch (q->expr_type)
    {
    case EXPR_SUBSTRING:
      s = gfc_get_wide_string (p->value.character.length + 1);
      q->value.character.string = s;
      memcpy (s, p->value.character.string,
	      (p->value.character.length + 1) * sizeof (gfc_char_t));
      break;

    case EXPR_CONSTANT:
      /* Copy target representation, if it exists.  */
      if (p->representation.string)
	{
	  c = XCNEWVEC (char, p->representation.length + 1);
	  q->representation.string = c;
	  memcpy (c, p->representation.string, (p->representation.length + 1));
	}

      /* Copy the values of any pointer components of p->value.  */
      switch (q->ts.type)
	{
	case BT_INTEGER:
	case BT_UNSIGNED:
	  mpz_init_set (q->value.integer, p->value.integer);
	  break;

	case BT_REAL:
	  gfc_set_model_kind (q->ts.kind);
	  mpfr_init (q->value.real);
	  mpfr_set (q->value.real, p->value.real, GFC_RND_MODE);
	  break;

	case BT_COMPLEX:
	  gfc_set_model_kind (q->ts.kind);
	  mpc_init2 (q->value.complex, mpfr_get_default_prec());
	  mpc_set (q->value.complex, p->value.complex, GFC_MPC_RND_MODE);
	  break;

	case BT_CHARACTER:
	  if (p->representation.string
	      && p->ts.kind == gfc_default_character_kind)
	    q->value.character.string
	      = gfc_char_to_widechar (q->representation.string);
	  else
	    {
	      s = gfc_get_wide_string (p->value.character.length + 1);
	      q->value.character.string = s;

	      /* This is the case for the C_NULL_CHAR named constant.  */
	      if (p->value.character.length == 0
		  && (p->ts.is_c_interop || p->ts.is_iso_c))
		{
		  *s = '\0';
		  /* Need to set the length to 1 to make sure the NUL
		     terminator is copied.  */
		  q->value.character.length = 1;
		}
	      else
		memcpy (s, p->value.character.string,
			(p->value.character.length + 1) * sizeof (gfc_char_t));
	    }
	  break;

	case BT_HOLLERITH:
	case BT_LOGICAL:
	case_bt_struct:
	case BT_CLASS:
	case BT_ASSUMED:
	  break;		/* Already done.  */

	case BT_BOZ:
	  q->boz.len = p->boz.len;
	  q->boz.rdx = p->boz.rdx;
	  q->boz.str = XCNEWVEC (char, q->boz.len + 1);
	  strncpy (q->boz.str, p->boz.str, p->boz.len);
	  break;

	case BT_PROCEDURE:
        case BT_VOID:
           /* Should never be reached.  */
	case BT_UNKNOWN:
	  gfc_internal_error ("gfc_copy_expr(): Bad expr node");
	  /* Not reached.  */
	}

      break;

    case EXPR_OP:
      switch (q->value.op.op)
	{
	case INTRINSIC_NOT:
	case INTRINSIC_PARENTHESES:
	case INTRINSIC_UPLUS:
	case INTRINSIC_UMINUS:
	  q->value.op.op1 = gfc_copy_expr (p->value.op.op1);
	  break;

	default:		/* Binary operators.  */
	  q->value.op.op1 = gfc_copy_expr (p->value.op.op1);
	  q->value.op.op2 = gfc_copy_expr (p->value.op.op2);
	  break;
	}

      break;

    case EXPR_FUNCTION:
      q->value.function.actual =
	gfc_copy_actual_arglist (p->value.function.actual);
      break;

    case EXPR_COMPCALL:
    case EXPR_PPC:
      q->value.compcall.actual =
	gfc_copy_actual_arglist (p->value.compcall.actual);
      q->value.compcall.tbp = p->value.compcall.tbp;
      break;

    case EXPR_STRUCTURE:
    case EXPR_ARRAY:
      q->value.constructor = gfc_constructor_copy (p->value.constructor);
      break;

    case EXPR_VARIABLE:
    case EXPR_NULL:
      break;

    case EXPR_UNKNOWN:
      gcc_unreachable ();
    }

  q->shape = gfc_copy_shape (p->shape, p->rank);

  q->ref = gfc_copy_ref (p->ref);

  if (p->param_list)
    q->param_list = gfc_copy_actual_arglist (p->param_list);

  return q;
}


void
gfc_clear_shape (mpz_t *shape, int rank)
{
  int i;

  for (i = 0; i < rank; i++)
    mpz_clear (shape[i]);
}


void
gfc_free_shape (mpz_t **shape, int rank)
{
  if (*shape == NULL)
    return;

  gfc_clear_shape (*shape, rank);
  free (*shape);
  *shape = NULL;
}


/* Workhorse function for gfc_free_expr() that frees everything
   beneath an expression node, but not the node itself.  This is
   useful when we want to simplify a node and replace it with
   something else or the expression node belongs to another structure.  */

static void
free_expr0 (gfc_expr *e)
{
  switch (e->expr_type)
    {
    case EXPR_CONSTANT:
      /* Free any parts of the value that need freeing.  */
      switch (e->ts.type)
	{
	case BT_INTEGER:
	case BT_UNSIGNED:
	  mpz_clear (e->value.integer);
	  break;

	case BT_REAL:
	  mpfr_clear (e->value.real);
	  break;

	case BT_CHARACTER:
	  free (e->value.character.string);
	  break;

	case BT_COMPLEX:
	  mpc_clear (e->value.complex);
	  break;

	case BT_BOZ:
	  free (e->boz.str);
	  break;

	default:
	  break;
	}

      /* Free the representation.  */
      free (e->representation.string);

      break;

    case EXPR_OP:
      if (e->value.op.op1 != NULL)
	gfc_free_expr (e->value.op.op1);
      if (e->value.op.op2 != NULL)
	gfc_free_expr (e->value.op.op2);
      break;

    case EXPR_FUNCTION:
      gfc_free_actual_arglist (e->value.function.actual);
      break;

    case EXPR_COMPCALL:
    case EXPR_PPC:
      gfc_free_actual_arglist (e->value.compcall.actual);
      break;

    case EXPR_VARIABLE:
      break;

    case EXPR_ARRAY:
    case EXPR_STRUCTURE:
      gfc_constructor_free (e->value.constructor);
      break;

    case EXPR_SUBSTRING:
      free (e->value.character.string);
      break;

    case EXPR_NULL:
      break;

    default:
      gfc_internal_error ("free_expr0(): Bad expr type");
    }

  /* Free a shape array.  */
  gfc_free_shape (&e->shape, e->rank);

  gfc_free_ref_list (e->ref);

  gfc_free_actual_arglist (e->param_list);

  memset (e, '\0', sizeof (gfc_expr));
}


/* Free an expression node and everything beneath it.  */

void
gfc_free_expr (gfc_expr *e)
{
  if (e == NULL)
    return;
  free_expr0 (e);
  free (e);
}


/* Free an argument list and everything below it.  */

void
gfc_free_actual_arglist (gfc_actual_arglist *a1)
{
  gfc_actual_arglist *a2;

  while (a1)
    {
      a2 = a1->next;
      if (a1->expr)
	gfc_free_expr (a1->expr);
      free (a1->associated_dummy);
      free (a1);
      a1 = a2;
    }
}


/* Copy an arglist structure and all of the arguments.  */

gfc_actual_arglist *
gfc_copy_actual_arglist (gfc_actual_arglist *p)
{
  gfc_actual_arglist *head, *tail, *new_arg;

  head = tail = NULL;

  for (; p; p = p->next)
    {
      new_arg = gfc_get_actual_arglist ();
      *new_arg = *p;

      if (p->associated_dummy != NULL)
	{
	  new_arg->associated_dummy = gfc_get_dummy_arg ();
	  *new_arg->associated_dummy = *p->associated_dummy;
	}

      new_arg->expr = gfc_copy_expr (p->expr);
      new_arg->next = NULL;

      if (head == NULL)
	head = new_arg;
      else
	tail->next = new_arg;

      tail = new_arg;
    }

  return head;
}


/* Free a list of reference structures.  */

void
gfc_free_ref_list (gfc_ref *p)
{
  gfc_ref *q;
  int i;

  for (; p; p = q)
    {
      q = p->next;

      switch (p->type)
	{
	case REF_ARRAY:
	  for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
	    {
	      gfc_free_expr (p->u.ar.start[i]);
	      gfc_free_expr (p->u.ar.end[i]);
	      gfc_free_expr (p->u.ar.stride[i]);
	    }

	  gfc_free_expr (p->u.ar.stat);
	  gfc_free_expr (p->u.ar.team);
	  break;

	case REF_SUBSTRING:
	  gfc_free_expr (p->u.ss.start);
	  gfc_free_expr (p->u.ss.end);
	  break;

	case REF_COMPONENT:
	case REF_INQUIRY:
	  break;
	}

      free (p);
    }
}


/* Graft the *src expression onto the *dest subexpression.  */

void
gfc_replace_expr (gfc_expr *dest, gfc_expr *src)
{
  free_expr0 (dest);
  *dest = *src;
  free (src);
}


/* Try to extract an integer constant from the passed expression node.
   Return true if some error occurred, false on success.  If REPORT_ERROR
   is non-zero, emit error, for positive REPORT_ERROR using gfc_error,
   for negative using gfc_error_now.  */

bool
gfc_extract_int (gfc_expr *expr, int *result, int report_error)
{
  gfc_ref *ref;

  /* A KIND component is a parameter too. The expression for it
     is stored in the initializer and should be consistent with
     the tests below.  */
  if (gfc_expr_attr(expr).pdt_kind)
    {
      for (ref = expr->ref; ref; ref = ref->next)
	{
	   if (ref->u.c.component->attr.pdt_kind)
	     expr = ref->u.c.component->initializer;
	}
    }

  if (expr->expr_type != EXPR_CONSTANT)
    {
      if (report_error > 0)
	gfc_error ("Constant expression required at %C");
      else if (report_error < 0)
	gfc_error_now ("Constant expression required at %C");
      return true;
    }

  if (expr->ts.type != BT_INTEGER)
    {
      if (report_error > 0)
	gfc_error ("Integer expression required at %C");
      else if (report_error < 0)
	gfc_error_now ("Integer expression required at %C");
      return true;
    }

  if ((mpz_cmp_si (expr->value.integer, INT_MAX) > 0)
      || (mpz_cmp_si (expr->value.integer, INT_MIN) < 0))
    {
      if (report_error > 0)
	gfc_error ("Integer value too large in expression at %C");
      else if (report_error < 0)
	gfc_error_now ("Integer value too large in expression at %C");
      return true;
    }

  *result = (int) mpz_get_si (expr->value.integer);

  return false;
}

/* Same as gfc_extract_int, but use a HWI.  */

bool
gfc_extract_hwi (gfc_expr *expr, HOST_WIDE_INT *result, int report_error)
{
  gfc_ref *ref;

  /* A KIND component is a parameter too. The expression for it is
     stored in the initializer and should be consistent with the tests
     below.  */
  if (gfc_expr_attr(expr).pdt_kind)
    {
      for (ref = expr->ref; ref; ref = ref->next)
	{
	  if (ref->u.c.component->attr.pdt_kind)
	    expr = ref->u.c.component->initializer;
	}
    }

  if (expr->expr_type != EXPR_CONSTANT)
    {
      if (report_error > 0)
	gfc_error ("Constant expression required at %C");
      else if (report_error < 0)
	gfc_error_now ("Constant expression required at %C");
      return true;
    }

  if (expr->ts.type != BT_INTEGER)
    {
      if (report_error > 0)
	gfc_error ("Integer expression required at %C");
      else if (report_error < 0)
	gfc_error_now ("Integer expression required at %C");
      return true;
    }

  /* Use long_long_integer_type_node to determine when to saturate.  */
  const wide_int val = wi::from_mpz (long_long_integer_type_node,
				     expr->value.integer, false);

  if (!wi::fits_shwi_p (val))
    {
      if (report_error > 0)
	gfc_error ("Integer value too large in expression at %C");
      else if (report_error < 0)
	gfc_error_now ("Integer value too large in expression at %C");
      return true;
    }

  *result = val.to_shwi ();

  return false;
}


/* Recursively copy a list of reference structures.  */

gfc_ref *
gfc_copy_ref (gfc_ref *src)
{
  gfc_array_ref *ar;
  gfc_ref *dest;

  if (src == NULL)
    return NULL;

  dest = gfc_get_ref ();
  dest->type = src->type;

  switch (src->type)
    {
    case REF_ARRAY:
      ar = gfc_copy_array_ref (&src->u.ar);
      dest->u.ar = *ar;
      free (ar);
      break;

    case REF_COMPONENT:
      dest->u.c = src->u.c;
      break;

    case REF_INQUIRY:
      dest->u.i = src->u.i;
      break;

    case REF_SUBSTRING:
      dest->u.ss = src->u.ss;
      dest->u.ss.start = gfc_copy_expr (src->u.ss.start);
      dest->u.ss.end = gfc_copy_expr (src->u.ss.end);
      break;
    }

  dest->next = gfc_copy_ref (src->next);

  return dest;
}


/* Detect whether an expression has any vector index array references.  */

bool
gfc_has_vector_index (gfc_expr *e)
{
  gfc_ref *ref;
  int i;
  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type == REF_ARRAY)
      for (i = 0; i < ref->u.ar.dimen; i++)
	if (ref->u.ar.dimen_type[i] == DIMEN_VECTOR)
	  return 1;
  return 0;
}


bool
gfc_is_ptr_fcn (gfc_expr *e)
{
  return e != NULL && e->expr_type == EXPR_FUNCTION
	      && gfc_expr_attr (e).pointer;
}


/* Copy a shape array.  */

mpz_t *
gfc_copy_shape (mpz_t *shape, int rank)
{
  mpz_t *new_shape;
  int n;

  if (shape == NULL)
    return NULL;

  new_shape = gfc_get_shape (rank);

  for (n = 0; n < rank; n++)
    mpz_init_set (new_shape[n], shape[n]);

  return new_shape;
}


/* Copy a shape array excluding dimension N, where N is an integer
   constant expression.  Dimensions are numbered in Fortran style --
   starting with ONE.

   So, if the original shape array contains R elements
      { s1 ... sN-1  sN  sN+1 ... sR-1 sR}
   the result contains R-1 elements:
      { s1 ... sN-1  sN+1    ...  sR-1}

   If anything goes wrong -- N is not a constant, its value is out
   of range -- or anything else, just returns NULL.  */

mpz_t *
gfc_copy_shape_excluding (mpz_t *shape, int rank, gfc_expr *dim)
{
  mpz_t *new_shape, *s;
  int i, n;

  if (shape == NULL
      || rank <= 1
      || dim == NULL
      || dim->expr_type != EXPR_CONSTANT
      || dim->ts.type != BT_INTEGER)
    return NULL;

  n = mpz_get_si (dim->value.integer);
  n--; /* Convert to zero based index.  */
  if (n < 0 || n >= rank)
    return NULL;

  s = new_shape = gfc_get_shape (rank - 1);

  for (i = 0; i < rank; i++)
    {
      if (i == n)
	continue;
      mpz_init_set (*s, shape[i]);
      s++;
    }

  return new_shape;
}


/* Return the maximum kind of two expressions.  In general, higher
   kind numbers mean more precision for numeric types.  */

int
gfc_kind_max (gfc_expr *e1, gfc_expr *e2)
{
  return (e1->ts.kind > e2->ts.kind) ? e1->ts.kind : e2->ts.kind;
}


/* Returns nonzero if the type is numeric, zero otherwise.  */

static bool
numeric_type (bt type)
{
  return type == BT_COMPLEX || type == BT_REAL || type == BT_INTEGER
    || type == BT_UNSIGNED;
}


/* Returns nonzero if the typespec is a numeric type, zero otherwise.  */

bool
gfc_numeric_ts (gfc_typespec *ts)
{
  return numeric_type (ts->type);
}


/* Return an expression node with an optional argument list attached.
   A variable number of gfc_expr pointers are strung together in an
   argument list with a NULL pointer terminating the list.  */

gfc_expr *
gfc_build_conversion (gfc_expr *e)
{
  gfc_expr *p;

  p = gfc_get_expr ();
  p->expr_type = EXPR_FUNCTION;
  p->symtree = NULL;
  p->value.function.actual = gfc_get_actual_arglist ();
  p->value.function.actual->expr = e;

  return p;
}


/* Given an expression node with some sort of numeric binary
   expression, insert type conversions required to make the operands
   have the same type. Conversion warnings are disabled if wconversion
   is set to 0.

   The exception is that the operands of an exponential don't have to
   have the same type.  If possible, the base is promoted to the type
   of the exponent.  For example, 1**2.3 becomes 1.0**2.3, but
   1.0**2 stays as it is.  */

void
gfc_type_convert_binary (gfc_expr *e, int wconversion)
{
  gfc_expr *op1, *op2;

  op1 = e->value.op.op1;
  op2 = e->value.op.op2;

  if (op1->ts.type == BT_UNKNOWN || op2->ts.type == BT_UNKNOWN)
    {
      gfc_clear_ts (&e->ts);
      return;
    }

  /* Kind conversions of same type.  */
  if (op1->ts.type == op2->ts.type)
    {
      if (op1->ts.kind == op2->ts.kind)
	{
	  /* No type conversions.  */
	  e->ts = op1->ts;
	  goto done;
	}

      /* Unsigned exponentiation is special, we need the type of the first
	 argument here because of modulo arithmetic.  */
      if (op1->ts.type == BT_UNSIGNED && e->value.op.op == INTRINSIC_POWER)
	{
	  e->ts = op1->ts;
	  goto done;
	}

      if (op1->ts.kind > op2->ts.kind)
	gfc_convert_type_warn (op2, &op1->ts, 2, wconversion);
      else
	gfc_convert_type_warn (op1, &op2->ts, 2, wconversion);

      e->ts = op1->ts;
      goto done;
    }

  /* Integer combined with real or complex.  */
  if (op2->ts.type == BT_INTEGER)
    {
      e->ts = op1->ts;

      /* Special case for ** operator.  */
      if (e->value.op.op == INTRINSIC_POWER)
	goto done;

      gfc_convert_type_warn (e->value.op.op2, &e->ts, 2, wconversion);
      goto done;
    }

  if (op1->ts.type == BT_INTEGER)
    {
      e->ts = op2->ts;
      gfc_convert_type_warn (e->value.op.op1, &e->ts, 2, wconversion);
      goto done;
    }

  /* Real combined with complex.  */
  e->ts.type = BT_COMPLEX;
  if (op1->ts.kind > op2->ts.kind)
    e->ts.kind = op1->ts.kind;
  else
    e->ts.kind = op2->ts.kind;
  if (op1->ts.type != BT_COMPLEX || op1->ts.kind != e->ts.kind)
    gfc_convert_type_warn (e->value.op.op1, &e->ts, 2, wconversion);
  if (op2->ts.type != BT_COMPLEX || op2->ts.kind != e->ts.kind)
    gfc_convert_type_warn (e->value.op.op2, &e->ts, 2, wconversion);

done:
  return;
}


/* Standard intrinsics listed under F2018:10.1.12 (6), which are excluded in
   constant expressions, except TRANSFER (c.f. item (8)), which would need
   separate treatment.  */

static bool
is_non_constant_intrinsic (gfc_expr *e)
{
  if (e->expr_type == EXPR_FUNCTION
      && e->value.function.isym)
    {
      switch (e->value.function.isym->id)
	{
	  case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
	  case GFC_ISYM_GET_TEAM:
	  case GFC_ISYM_NULL:
	  case GFC_ISYM_NUM_IMAGES:
	  case GFC_ISYM_TEAM_NUMBER:
	  case GFC_ISYM_THIS_IMAGE:
	    return true;

	default:
	  return false;
	}
    }
  return false;
}


/* Determine if an expression is constant in the sense of F08:7.1.12.
 * This function expects that the expression has already been simplified.  */

bool
gfc_is_constant_expr (gfc_expr *e)
{
  gfc_constructor *c;
  gfc_actual_arglist *arg;

  if (e == NULL)
    return true;

  switch (e->expr_type)
    {
    case EXPR_OP:
      return (gfc_is_constant_expr (e->value.op.op1)
	      && (e->value.op.op2 == NULL
		  || gfc_is_constant_expr (e->value.op.op2)));

    case EXPR_VARIABLE:
      /* The only context in which this can occur is in a parameterized
	 derived type declaration, so returning true is OK.  */
      if (e->symtree->n.sym->attr.pdt_len
	  || e->symtree->n.sym->attr.pdt_kind)
        return true;
      return false;

    case EXPR_FUNCTION:
    case EXPR_PPC:
    case EXPR_COMPCALL:
      gcc_assert (e->symtree || e->value.function.esym
		  || e->value.function.isym);

      /* Check for intrinsics excluded in constant expressions.  */
      if (e->value.function.isym && is_non_constant_intrinsic (e))
	return false;

      /* Call to intrinsic with at least one argument.  */
      if (e->value.function.isym && e->value.function.actual)
	{
	  for (arg = e->value.function.actual; arg; arg = arg->next)
	    if (!gfc_is_constant_expr (arg->expr))
	      return false;
	}

      if (e->value.function.isym
	  && (e->value.function.isym->elemental
	      || e->value.function.isym->pure
	      || e->value.function.isym->inquiry
	      || e->value.function.isym->transformational))
	return true;

      return false;

    case EXPR_CONSTANT:
    case EXPR_NULL:
      return true;

    case EXPR_SUBSTRING:
      return e->ref == NULL || (gfc_is_constant_expr (e->ref->u.ss.start)
				&& gfc_is_constant_expr (e->ref->u.ss.end));

    case EXPR_ARRAY:
    case EXPR_STRUCTURE:
      c = gfc_constructor_first (e->value.constructor);
      if ((e->expr_type == EXPR_ARRAY) && c && c->iterator)
        return gfc_constant_ac (e);

      for (; c; c = gfc_constructor_next (c))
	if (!gfc_is_constant_expr (c->expr))
	  return false;

      return true;


    default:
      gfc_internal_error ("gfc_is_constant_expr(): Unknown expression type");
      return false;
    }
}


/* Is true if the expression or symbol is a passed CFI descriptor.  */
bool
is_CFI_desc (gfc_symbol *sym, gfc_expr *e)
{
  if (sym == NULL
      && e && e->expr_type == EXPR_VARIABLE)
    sym = e->symtree->n.sym;

  if (sym && sym->attr.dummy
      && sym->ns->proc_name->attr.is_bind_c
      && (sym->attr.pointer
	  || sym->attr.allocatable
	  || (sym->attr.dimension
	      && (sym->as->type == AS_ASSUMED_SHAPE
		  || sym->as->type == AS_ASSUMED_RANK))
	  || (sym->ts.type == BT_CHARACTER
	      && (!sym->ts.u.cl || !sym->ts.u.cl->length))))
    return true;

return false;
}


/* Is true if an array reference is followed by a component or substring
   reference.  */
bool
is_subref_array (gfc_expr * e)
{
  gfc_ref * ref;
  bool seen_array;
  gfc_symbol *sym;

  if (e->expr_type != EXPR_VARIABLE)
    return false;

  sym = e->symtree->n.sym;

  if (sym->attr.subref_array_pointer)
    return true;

  seen_array = false;

  for (ref = e->ref; ref; ref = ref->next)
    {
      /* If we haven't seen the array reference and this is an intrinsic,
	 what follows cannot be a subreference array, unless there is a
	 substring reference.  */
      if (!seen_array && ref->type == REF_COMPONENT
	  && ref->next == NULL
	  && ref->u.c.component->ts.type != BT_CHARACTER
	  && ref->u.c.component->ts.type != BT_CLASS
	  && !gfc_bt_struct (ref->u.c.component->ts.type))
	return false;

      if (ref->type == REF_ARRAY
	    && ref->u.ar.type != AR_ELEMENT)
	seen_array = true;

      if (seen_array
	    && ref->type != REF_ARRAY)
	return seen_array;
    }

  if (sym->ts.type == BT_CLASS
      && sym->attr.dummy
      && CLASS_DATA (sym)->attr.dimension
      && CLASS_DATA (sym)->attr.class_pointer)
    return true;

  return false;
}


/* Try to collapse intrinsic expressions.  */

static bool
simplify_intrinsic_op (gfc_expr *p, int type)
{
  gfc_intrinsic_op op;
  gfc_expr *op1, *op2, *result;

  if (p->value.op.op == INTRINSIC_USER)
    return true;

  op1 = p->value.op.op1;
  op2 = p->value.op.op2;
  op  = p->value.op.op;

  if (!gfc_simplify_expr (op1, type))
    return false;
  if (!gfc_simplify_expr (op2, type))
    return false;

  if (!gfc_is_constant_expr (op1)
      || (op2 != NULL && !gfc_is_constant_expr (op2)))
    return true;

  /* Rip p apart.  */
  p->value.op.op1 = NULL;
  p->value.op.op2 = NULL;

  switch (op)
    {
    case INTRINSIC_PARENTHESES:
      result = gfc_parentheses (op1);
      break;

    case INTRINSIC_UPLUS:
      result = gfc_uplus (op1);
      break;

    case INTRINSIC_UMINUS:
      result = gfc_uminus (op1);
      break;

    case INTRINSIC_PLUS:
      result = gfc_add (op1, op2);
      break;

    case INTRINSIC_MINUS:
      result = gfc_subtract (op1, op2);
      break;

    case INTRINSIC_TIMES:
      result = gfc_multiply (op1, op2);
      break;

    case INTRINSIC_DIVIDE:
      result = gfc_divide (op1, op2);
      break;

    case INTRINSIC_POWER:
      result = gfc_power (op1, op2);
      break;

    case INTRINSIC_CONCAT:
      result = gfc_concat (op1, op2);
      break;

    case INTRINSIC_EQ:
    case INTRINSIC_EQ_OS:
      result = gfc_eq (op1, op2, op);
      break;

    case INTRINSIC_NE:
    case INTRINSIC_NE_OS:
      result = gfc_ne (op1, op2, op);
      break;

    case INTRINSIC_GT:
    case INTRINSIC_GT_OS:
      result = gfc_gt (op1, op2, op);
      break;

    case INTRINSIC_GE:
    case INTRINSIC_GE_OS:
      result = gfc_ge (op1, op2, op);
      break;

    case INTRINSIC_LT:
    case INTRINSIC_LT_OS:
      result = gfc_lt (op1, op2, op);
      break;

    case INTRINSIC_LE:
    case INTRINSIC_LE_OS:
      result = gfc_le (op1, op2, op);
      break;

    case INTRINSIC_NOT:
      result = gfc_not (op1);
      break;

    case INTRINSIC_AND:
      result = gfc_and (op1, op2);
      break;

    case INTRINSIC_OR:
      result = gfc_or (op1, op2);
      break;

    case INTRINSIC_EQV:
      result = gfc_eqv (op1, op2);
      break;

    case INTRINSIC_NEQV:
      result = gfc_neqv (op1, op2);
      break;

    default:
      gfc_internal_error ("simplify_intrinsic_op(): Bad operator");
    }

  if (result == NULL)
    {
      gfc_free_expr (op1);
      gfc_free_expr (op2);
      return false;
    }

  result->rank = p->rank;
  result->corank = p->corank;
  result->where = p->where;
  gfc_replace_expr (p, result);

  return true;
}


/* Subroutine to simplify constructor expressions.  Mutually recursive
   with gfc_simplify_expr().  */

static bool
simplify_constructor (gfc_constructor_base base, int type)
{
  gfc_constructor *c;
  gfc_expr *p;

  for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
    {
      if (c->iterator
	  && (!gfc_simplify_expr(c->iterator->start, type)
	      || !gfc_simplify_expr (c->iterator->end, type)
	      || !gfc_simplify_expr (c->iterator->step, type)))
	return false;

      if (c->expr && c->expr->expr_type != EXPR_CONSTANT)
	{
	  /* Try and simplify a copy.  Replace the original if successful
	     but keep going through the constructor at all costs.  Not
	     doing so can make a dog's dinner of complicated things.  */
	  p = gfc_copy_expr (c->expr);

	  if (!gfc_simplify_expr (p, type))
	    {
	      gfc_free_expr (p);
	      continue;
	    }

	  gfc_replace_expr (c->expr, p);
	}
    }

  return true;
}


/* Pull a single array element out of an array constructor.  */

static bool
find_array_element (gfc_constructor_base base, gfc_array_ref *ar,
		    gfc_constructor **rval)
{
  unsigned long nelemen;
  int i;
  mpz_t delta;
  mpz_t offset;
  mpz_t span;
  mpz_t tmp;
  gfc_constructor *cons;
  gfc_expr *e;
  bool t;

  t = true;
  e = NULL;

  mpz_init_set_ui (offset, 0);
  mpz_init (delta);
  mpz_init (tmp);
  mpz_init_set_ui (span, 1);
  for (i = 0; i < ar->dimen; i++)
    {
      if (!gfc_reduce_init_expr (ar->as->lower[i])
	  || !gfc_reduce_init_expr (ar->as->upper[i])
	  || ar->as->upper[i]->expr_type != EXPR_CONSTANT
	  || ar->as->lower[i]->expr_type != EXPR_CONSTANT)
	{
	  t = false;
	  cons = NULL;
	  goto depart;
	}

      e = ar->start[i];
      if (e->expr_type != EXPR_CONSTANT)
	{
	  cons = NULL;
	  goto depart;
	}

      /* Check the bounds.  */
      if ((ar->as->upper[i]
	   && mpz_cmp (e->value.integer,
		       ar->as->upper[i]->value.integer) > 0)
	  || (mpz_cmp (e->value.integer,
		       ar->as->lower[i]->value.integer) < 0))
	{
	  gfc_error ("Index in dimension %d is out of bounds "
		     "at %L", i + 1, &ar->c_where[i]);
	  cons = NULL;
	  t = false;
	  goto depart;
	}

      mpz_sub (delta, e->value.integer, ar->as->lower[i]->value.integer);
      mpz_mul (delta, delta, span);
      mpz_add (offset, offset, delta);

      mpz_set_ui (tmp, 1);
      mpz_add (tmp, tmp, ar->as->upper[i]->value.integer);
      mpz_sub (tmp, tmp, ar->as->lower[i]->value.integer);
      mpz_mul (span, span, tmp);
    }

  for (cons = gfc_constructor_first (base), nelemen = mpz_get_ui (offset);
       cons && nelemen > 0; cons = gfc_constructor_next (cons), nelemen--)
    {
      if (cons->iterator)
	{
	  cons = NULL;
	  goto depart;
	}
    }

depart:
  mpz_clear (delta);
  mpz_clear (offset);
  mpz_clear (span);
  mpz_clear (tmp);
  *rval = cons;
  return t;
}


/* Find a component of a structure constructor.  */

static gfc_constructor *
find_component_ref (gfc_constructor_base base, gfc_ref *ref)
{
  gfc_component *pick = ref->u.c.component;
  gfc_constructor *c = gfc_constructor_first (base);

  gfc_symbol *dt = ref->u.c.sym;
  int ext = dt->attr.extension;

  /* For extended types, check if the desired component is in one of the
   * parent types.  */
  while (ext > 0 && gfc_find_component (dt->components->ts.u.derived,
					pick->name, true, true, NULL))
    {
      dt = dt->components->ts.u.derived;
      c = gfc_constructor_first (c->expr->value.constructor);
      ext--;
    }

  gfc_component *comp = dt->components;
  while (comp != pick)
    {
      comp = comp->next;
      c = gfc_constructor_next (c);
    }

  return c;
}


/* Replace an expression with the contents of a constructor, removing
   the subobject reference in the process.  */

static void
remove_subobject_ref (gfc_expr *p, gfc_constructor *cons)
{
  gfc_expr *e;

  if (cons)
    {
      e = cons->expr;
      cons->expr = NULL;
    }
  else
    e = gfc_copy_expr (p);
  e->ref = p->ref->next;
  p->ref->next =  NULL;
  gfc_replace_expr (p, e);
}


/* Pull an array section out of an array constructor.  */

static bool
find_array_section (gfc_expr *expr, gfc_ref *ref)
{
  int idx;
  int rank;
  int d;
  int shape_i;
  int limit;
  long unsigned one = 1;
  bool incr_ctr;
  mpz_t start[GFC_MAX_DIMENSIONS];
  mpz_t end[GFC_MAX_DIMENSIONS];
  mpz_t stride[GFC_MAX_DIMENSIONS];
  mpz_t delta[GFC_MAX_DIMENSIONS];
  mpz_t ctr[GFC_MAX_DIMENSIONS];
  mpz_t delta_mpz;
  mpz_t tmp_mpz;
  mpz_t nelts;
  mpz_t ptr;
  gfc_constructor_base base;
  gfc_constructor *cons, *vecsub[GFC_MAX_DIMENSIONS];
  gfc_expr *begin;
  gfc_expr *finish;
  gfc_expr *step;
  gfc_expr *upper;
  gfc_expr *lower;
  bool t;

  t = true;

  base = expr->value.constructor;
  expr->value.constructor = NULL;

  rank = ref->u.ar.as->rank;

  if (expr->shape == NULL)
    expr->shape = gfc_get_shape (rank);

  mpz_init_set_ui (delta_mpz, one);
  mpz_init_set_ui (nelts, one);
  mpz_init (tmp_mpz);
  mpz_init (ptr);

  /* Do the initialization now, so that we can cleanup without
     keeping track of where we were.  */
  for (d = 0; d < rank; d++)
    {
      mpz_init (delta[d]);
      mpz_init (start[d]);
      mpz_init (end[d]);
      mpz_init (ctr[d]);
      mpz_init (stride[d]);
      vecsub[d] = NULL;
    }

  /* Build the counters to clock through the array reference.  */
  shape_i = 0;
  for (d = 0; d < rank; d++)
    {
      /* Make this stretch of code easier on the eye!  */
      begin = ref->u.ar.start[d];
      finish = ref->u.ar.end[d];
      step = ref->u.ar.stride[d];
      lower = ref->u.ar.as->lower[d];
      upper = ref->u.ar.as->upper[d];

      if (!lower || !upper
	  || lower->expr_type != EXPR_CONSTANT
	  || upper->expr_type != EXPR_CONSTANT
	  || lower->ts.type != BT_INTEGER
	  || upper->ts.type != BT_INTEGER)
	{
	  t = false;
	  goto cleanup;
	}

      if (ref->u.ar.dimen_type[d] == DIMEN_VECTOR)  /* Vector subscript.  */
	{
	  gfc_constructor *ci;
	  gcc_assert (begin);

	  if (begin->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (begin))
	    {
	      t = false;
	      goto cleanup;
	    }

	  gcc_assert (begin->rank == 1);
	  /* Zero-sized arrays have no shape and no elements, stop early.  */
	  if (!begin->shape)
	    {
	      mpz_set_ui (nelts, 0);
	      break;
	    }

	  vecsub[d] = gfc_constructor_first (begin->value.constructor);
	  mpz_set (ctr[d], vecsub[d]->expr->value.integer);
	  mpz_mul (nelts, nelts, begin->shape[0]);
	  mpz_set (expr->shape[shape_i++], begin->shape[0]);

	  /* Check bounds.  */
	  for (ci = vecsub[d]; ci; ci = gfc_constructor_next (ci))
	    {
	      if (mpz_cmp (ci->expr->value.integer, upper->value.integer) > 0
		  || mpz_cmp (ci->expr->value.integer,
			      lower->value.integer) < 0)
		{
		  gfc_error ("index in dimension %d is out of bounds "
			     "at %L", d + 1, &ref->u.ar.c_where[d]);
		  t = false;
		  goto cleanup;
		}
	    }
	}
      else
	{
	  if ((begin && begin->expr_type != EXPR_CONSTANT)
	      || (finish && finish->expr_type != EXPR_CONSTANT)
	      || (step && step->expr_type != EXPR_CONSTANT))
	    {
	      t = false;
	      goto cleanup;
	    }

	  /* Obtain the stride.  */
	  if (step)
	    mpz_set (stride[d], step->value.integer);
	  else
	    mpz_set_ui (stride[d], one);

	  if (mpz_cmp_ui (stride[d], 0) == 0)
	    mpz_set_ui (stride[d], one);

	  /* Obtain the start value for the index.  */
	  if (begin)
	    mpz_set (start[d], begin->value.integer);
	  else
	    mpz_set (start[d], lower->value.integer);

	  mpz_set (ctr[d], start[d]);

	  /* Obtain the end value for the index.  */
	  if (finish)
	    mpz_set (end[d], finish->value.integer);
	  else
	    mpz_set (end[d], upper->value.integer);

	  /* Separate 'if' because elements sometimes arrive with
	     non-null end.  */
	  if (ref->u.ar.dimen_type[d] == DIMEN_ELEMENT)
	    mpz_set (end [d], begin->value.integer);

	  /* Check the bounds.  */
	  if (mpz_cmp (ctr[d], upper->value.integer) > 0
	      || mpz_cmp (end[d], upper->value.integer) > 0
	      || mpz_cmp (ctr[d], lower->value.integer) < 0
	      || mpz_cmp (end[d], lower->value.integer) < 0)
	    {
	      gfc_error ("index in dimension %d is out of bounds "
			 "at %L", d + 1, &ref->u.ar.c_where[d]);
	      t = false;
	      goto cleanup;
	    }

	  /* Calculate the number of elements and the shape.  */
	  mpz_set (tmp_mpz, stride[d]);
	  mpz_add (tmp_mpz, end[d], tmp_mpz);
	  mpz_sub (tmp_mpz, tmp_mpz, ctr[d]);
	  mpz_div (tmp_mpz, tmp_mpz, stride[d]);
	  mpz_mul (nelts, nelts, tmp_mpz);

	  /* An element reference reduces the rank of the expression; don't
	     add anything to the shape array.  */
	  if (ref->u.ar.dimen_type[d] != DIMEN_ELEMENT)
	    mpz_set (expr->shape[shape_i++], tmp_mpz);
	}

      /* Calculate the 'stride' (=delta) for conversion of the
	 counter values into the index along the constructor.  */
      mpz_set (delta[d], delta_mpz);
      mpz_sub (tmp_mpz, upper->value.integer, lower->value.integer);
      mpz_add_ui (tmp_mpz, tmp_mpz, one);
      mpz_mul (delta_mpz, delta_mpz, tmp_mpz);
    }

  cons = gfc_constructor_first (base);

  /* Now clock through the array reference, calculating the index in
     the source constructor and transferring the elements to the new
     constructor.  */
  for (idx = 0; idx < (int) mpz_get_si (nelts); idx++)
    {
      mpz_set_ui (ptr, 0);

      incr_ctr = true;
      for (d = 0; d < rank; d++)
	{
	  mpz_set (tmp_mpz, ctr[d]);
	  mpz_sub (tmp_mpz, tmp_mpz, ref->u.ar.as->lower[d]->value.integer);
	  mpz_mul (tmp_mpz, tmp_mpz, delta[d]);
	  mpz_add (ptr, ptr, tmp_mpz);

	  if (!incr_ctr) continue;

	  if (ref->u.ar.dimen_type[d] == DIMEN_VECTOR) /* Vector subscript.  */
	    {
	      gcc_assert(vecsub[d]);

	      if (!gfc_constructor_next (vecsub[d]))
		vecsub[d] = gfc_constructor_first (ref->u.ar.start[d]->value.constructor);
	      else
		{
		  vecsub[d] = gfc_constructor_next (vecsub[d]);
		  incr_ctr = false;
		}
	      mpz_set (ctr[d], vecsub[d]->expr->value.integer);
	    }
	  else
	    {
	      mpz_add (ctr[d], ctr[d], stride[d]);

	      if (mpz_cmp_ui (stride[d], 0) > 0
		  ? mpz_cmp (ctr[d], end[d]) > 0
		  : mpz_cmp (ctr[d], end[d]) < 0)
		mpz_set (ctr[d], start[d]);
	      else
		incr_ctr = false;
	    }
	}

      limit = mpz_get_ui (ptr);
      if (limit >= flag_max_array_constructor)
        {
	  gfc_error ("The number of elements in the array constructor "
		     "at %L requires an increase of the allowed %d "
		     "upper limit.  See %<-fmax-array-constructor%> "
		     "option", &expr->where, flag_max_array_constructor);
	  t = false;
	  goto cleanup;
	}

      cons = gfc_constructor_lookup (base, limit);
      if (cons == NULL)
	{
	  gfc_error ("Error in array constructor referenced at %L",
		     &ref->u.ar.where);
	  t = false;
	  goto cleanup;
	}
      gfc_constructor_append_expr (&expr->value.constructor,
				   gfc_copy_expr (cons->expr), NULL);
    }

cleanup:

  mpz_clear (delta_mpz);
  mpz_clear (tmp_mpz);
  mpz_clear (nelts);
  for (d = 0; d < rank; d++)
    {
      mpz_clear (delta[d]);
      mpz_clear (start[d]);
      mpz_clear (end[d]);
      mpz_clear (ctr[d]);
      mpz_clear (stride[d]);
    }
  mpz_clear (ptr);
  gfc_constructor_free (base);
  return t;
}

/* Pull a substring out of an expression.  */

static bool
find_substring_ref (gfc_expr *p, gfc_expr **newp)
{
  gfc_charlen_t end;
  gfc_charlen_t start;
  gfc_charlen_t length;
  gfc_char_t *chr;

  if (p->ref->u.ss.start->expr_type != EXPR_CONSTANT
      || p->ref->u.ss.end->expr_type != EXPR_CONSTANT)
    return false;

  *newp = gfc_copy_expr (p);
  free ((*newp)->value.character.string);

  end = (gfc_charlen_t) mpz_get_si (p->ref->u.ss.end->value.integer);
  start = (gfc_charlen_t) mpz_get_si (p->ref->u.ss.start->value.integer);
  if (end >= start)
    length = end - start + 1;
  else
    length = 0;

  chr = (*newp)->value.character.string = gfc_get_wide_string (length + 1);
  (*newp)->value.character.length = length;
  memcpy (chr, &p->value.character.string[start - 1],
	  length * sizeof (gfc_char_t));
  chr[length] = '\0';
  return true;
}


/* Simplify inquiry references (%re/%im) of constant complex arrays.
   Used by find_inquiry_ref.  */

static gfc_expr *
simplify_complex_array_inquiry_ref (gfc_expr *p, inquiry_type inquiry)
{
  gfc_expr *e, *r, *result;
  gfc_constructor_base base;
  gfc_constructor *c;

  if ((inquiry != INQUIRY_RE && inquiry != INQUIRY_IM)
      || p->expr_type != EXPR_ARRAY
      || p->ts.type != BT_COMPLEX
      || p->rank <= 0
      || p->value.constructor == NULL
      || !gfc_is_constant_array_expr (p))
    return NULL;

  /* Simplify array sections.  */
  gfc_simplify_expr (p, 0);

  result = gfc_get_array_expr (BT_REAL, p->ts.kind, &p->where);
  result->rank = p->rank;
  result->shape = gfc_copy_shape (p->shape, p->rank);

  base = p->value.constructor;
  for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
    {
      e = c->expr;
      if (e->expr_type != EXPR_CONSTANT)
	goto fail;

      r = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
      if (inquiry == INQUIRY_RE)
	mpfr_set (r->value.real, mpc_realref (e->value.complex), GFC_RND_MODE);
      else
	mpfr_set (r->value.real, mpc_imagref (e->value.complex), GFC_RND_MODE);

      gfc_constructor_append_expr (&result->value.constructor, r, &e->where);
    }

  return result;

fail:
  gfc_free_expr (result);
  return NULL;
}


/* Pull an inquiry result out of an expression.  */

static bool
find_inquiry_ref (gfc_expr *p, gfc_expr **newp)
{
  gfc_ref *ref;
  gfc_ref *inquiry = NULL;
  gfc_ref *inquiry_head;
  gfc_ref *ref_ss = NULL;
  gfc_expr *tmp;
  bool nofail = false;

  tmp = gfc_copy_expr (p);

  if (tmp->ref && tmp->ref->type == REF_INQUIRY)
    {
      inquiry = tmp->ref;
      tmp->ref = NULL;
    }
  else
    {
      for (ref = tmp->ref; ref; ref = ref->next)
	if (ref->next && ref->next->type == REF_INQUIRY)
	  {
	    inquiry = ref->next;
	    ref->next = NULL;
	    if (ref->type == REF_SUBSTRING)
	      ref_ss = ref;
	    break;
	  }
    }

  if (!inquiry)
    {
      gfc_free_expr (tmp);
      return false;
    }

  inquiry_head = inquiry;
  gfc_resolve_expr (tmp);

  /* Leave these to the backend since the type and kind is not confirmed until
     resolution.  */
  if (IS_INFERRED_TYPE (tmp))
    goto cleanup;

  /* In principle there can be more than one inquiry reference.  */
  for (; inquiry; inquiry = inquiry->next)
    {
      switch (inquiry->u.i)
	{
	case INQUIRY_LEN:
	  if (tmp->ts.type != BT_CHARACTER)
	    goto cleanup;

	  if (!gfc_notify_std (GFC_STD_F2003, "LEN part_ref at %C"))
	    goto cleanup;

	  /* Inquire length of substring?  */
	  if (ref_ss)
	    {
	      if (ref_ss->u.ss.start->expr_type == EXPR_CONSTANT
		  && ref_ss->u.ss.end->expr_type == EXPR_CONSTANT)
		{
		  HOST_WIDE_INT istart, iend, length;
		  istart = gfc_mpz_get_hwi (ref_ss->u.ss.start->value.integer);
		  iend = gfc_mpz_get_hwi (ref_ss->u.ss.end->value.integer);

		  if (istart <= iend)
		    length = iend - istart + 1;
		  else
		    length = 0;
		  *newp = gfc_get_int_expr (gfc_default_integer_kind,
					    NULL, length);
		  break;
		}
	      else
		goto cleanup;
	    }

	  if (tmp->ts.u.cl->length
	      && tmp->ts.u.cl->length->expr_type == EXPR_CONSTANT)
	    *newp = gfc_copy_expr (tmp->ts.u.cl->length);
	  else if (tmp->expr_type == EXPR_CONSTANT)
	    *newp = gfc_get_int_expr (gfc_default_integer_kind,
				      NULL, tmp->value.character.length);
	  else if (gfc_init_expr_flag
		   && tmp->ts.u.cl->length->symtree->n.sym->attr.pdt_len)
	    *newp = gfc_pdt_find_component_copy_initializer (tmp->symtree->n
							     .sym,
							     tmp->ts.u.cl
							     ->length->symtree
							     ->n.sym->name);
	  else
	    goto cleanup;

	  break;

	case INQUIRY_KIND:
	  if (tmp->ts.type == BT_DERIVED || tmp->ts.type == BT_CLASS)
	    goto cleanup;

	  if (!gfc_notify_std (GFC_STD_F2003, "KIND part_ref at %C"))
	    goto cleanup;

	  *newp = gfc_get_int_expr (gfc_default_integer_kind,
				    NULL, tmp->ts.kind);
	  break;

	case INQUIRY_RE:
	  if (tmp->ts.type != BT_COMPLEX)
	    goto cleanup;

	  if (!gfc_notify_std (GFC_STD_F2008, "RE part_ref at %C"))
	    goto cleanup;

	  if (tmp->expr_type == EXPR_ARRAY)
	    {
	      *newp = simplify_complex_array_inquiry_ref (tmp, INQUIRY_RE);
	      if (*newp != NULL)
		{
		  nofail = true;
		  break;
		}
	    }

	  if (tmp->expr_type != EXPR_CONSTANT)
	    goto cleanup;

	  *newp = gfc_get_constant_expr (BT_REAL, tmp->ts.kind, &tmp->where);
	  mpfr_set ((*newp)->value.real,
		    mpc_realref (tmp->value.complex), GFC_RND_MODE);
	  break;

	case INQUIRY_IM:
	  if (tmp->ts.type != BT_COMPLEX)
	    goto cleanup;

	  if (!gfc_notify_std (GFC_STD_F2008, "IM part_ref at %C"))
	    goto cleanup;

	  if (tmp->expr_type == EXPR_ARRAY)
	    {
	      *newp = simplify_complex_array_inquiry_ref (tmp, INQUIRY_IM);
	      if (*newp != NULL)
		{
		  nofail = true;
		  break;
		}
	    }

	  if (tmp->expr_type != EXPR_CONSTANT)
	    goto cleanup;

	  *newp = gfc_get_constant_expr (BT_REAL, tmp->ts.kind, &tmp->where);
	  mpfr_set ((*newp)->value.real,
		    mpc_imagref (tmp->value.complex), GFC_RND_MODE);
	  break;
	}

      if (inquiry->next)
	gfc_replace_expr (tmp, *newp);
    }

  if (!(*newp))
    goto cleanup;
  else if ((*newp)->expr_type != EXPR_CONSTANT && !nofail)
    {
      gfc_free_expr (*newp);
      goto cleanup;
    }

  gfc_free_expr (tmp);
  gfc_free_ref_list (inquiry_head);
  return true;

cleanup:
  gfc_free_expr (tmp);
  gfc_free_ref_list (inquiry_head);
  return false;
}



/* Simplify a subobject reference of a constructor.  This occurs when
   parameter variable values are substituted.  */

static bool
simplify_const_ref (gfc_expr *p)
{
  gfc_constructor *cons, *c;
  gfc_expr *newp = NULL;
  gfc_ref *last_ref;

  while (p->ref)
    {
      switch (p->ref->type)
	{
	case REF_ARRAY:
	  switch (p->ref->u.ar.type)
	    {
	    case AR_ELEMENT:
	      /* <type/kind spec>, parameter :: x(<int>) = scalar_expr
		 will generate this.  */
	      if (p->expr_type != EXPR_ARRAY)
		{
		  remove_subobject_ref (p, NULL);
		  break;
		}
	      if (!find_array_element (p->value.constructor, &p->ref->u.ar, &cons))
		return false;

	      if (!cons)
		return true;

	      remove_subobject_ref (p, cons);
	      break;

	    case AR_SECTION:
	      if (!find_array_section (p, p->ref))
		return false;
	      p->ref->u.ar.type = AR_FULL;

	    /* Fall through.  */

	    case AR_FULL:
	      if (p->ref->next != NULL
		  && (p->ts.type == BT_CHARACTER || gfc_bt_struct (p->ts.type)))
		{
		  for (c = gfc_constructor_first (p->value.constructor);
		       c; c = gfc_constructor_next (c))
		    {
		      c->expr->ref = gfc_copy_ref (p->ref->next);
		      if (!simplify_const_ref (c->expr))
			return false;
		    }

		  if (gfc_bt_struct (p->ts.type)
			&& p->ref->next
			&& (c = gfc_constructor_first (p->value.constructor)))
		    {
		      /* There may have been component references.  */
		      p->ts = c->expr->ts;
		    }

		  last_ref = p->ref;
		  for (; last_ref->next; last_ref = last_ref->next) {};

		  if (p->ts.type == BT_CHARACTER
			&& last_ref->type == REF_SUBSTRING)
		    {
		      /* If this is a CHARACTER array and we possibly took
			 a substring out of it, update the type-spec's
			 character length according to the first element
			 (as all should have the same length).  */
		      gfc_charlen_t string_len;
		      if ((c = gfc_constructor_first (p->value.constructor)))
			{
			  const gfc_expr* first = c->expr;
			  gcc_assert (first->expr_type == EXPR_CONSTANT);
			  gcc_assert (first->ts.type == BT_CHARACTER);
			  string_len = first->value.character.length;
			}
		      else
			string_len = 0;

		      if (!p->ts.u.cl)
			{
			  if (p->symtree)
			    p->ts.u.cl = gfc_new_charlen (p->symtree->n.sym->ns,
							  NULL);
			  else
			    p->ts.u.cl = gfc_new_charlen (gfc_current_ns,
							  NULL);
			}
		      else
			gfc_free_expr (p->ts.u.cl->length);

		      p->ts.u.cl->length
			= gfc_get_int_expr (gfc_charlen_int_kind,
					    NULL, string_len);
		    }
		}
	      gfc_free_ref_list (p->ref);
	      p->ref = NULL;
	      break;

	    default:
	      return true;
	    }

	  break;

	case REF_COMPONENT:
	  cons = find_component_ref (p->value.constructor, p->ref);
	  remove_subobject_ref (p, cons);
	  break;

	case REF_INQUIRY:
	  if (!find_inquiry_ref (p, &newp))
	    return false;

	  gfc_replace_expr (p, newp);
	  gfc_free_ref_list (p->ref);
	  p->ref = NULL;
	  break;

	case REF_SUBSTRING:
	  if (!find_substring_ref (p, &newp))
	    return false;

	  gfc_replace_expr (p, newp);
	  gfc_free_ref_list (p->ref);
	  p->ref = NULL;
	  break;
	}
    }

  return true;
}


/* Simplify a chain of references.  */

static bool
simplify_ref_chain (gfc_ref *ref, int type, gfc_expr **p)
{
  int n;
  gfc_expr *newp = NULL;

  for (; ref; ref = ref->next)
    {
      switch (ref->type)
	{
	case REF_ARRAY:
	  for (n = 0; n < ref->u.ar.dimen; n++)
	    {
	      if (!gfc_simplify_expr (ref->u.ar.start[n], type))
		return false;
	      if (!gfc_simplify_expr (ref->u.ar.end[n], type))
		return false;
	      if (!gfc_simplify_expr (ref->u.ar.stride[n], type))
		return false;
	    }
	  break;

	case REF_SUBSTRING:
	  if (!gfc_simplify_expr (ref->u.ss.start, type))
	    return false;
	  if (!gfc_simplify_expr (ref->u.ss.end, type))
	    return false;
	  break;

	case REF_INQUIRY:
	  if (!find_inquiry_ref (*p, &newp))
	    return false;

	  gfc_replace_expr (*p, newp);
	  gfc_free_ref_list ((*p)->ref);
	  (*p)->ref = NULL;
	  return true;

	default:
	  break;
	}
    }
  return true;
}


/* Try to substitute the value of a parameter variable.  */

static bool
simplify_parameter_variable (gfc_expr *p, int type)
{
  gfc_expr *e;
  bool t;

  /* Set rank and check array ref; as resolve_variable calls
     gfc_simplify_expr, call gfc_resolve_ref + gfc_expression_rank instead.  */
  if (!gfc_resolve_ref (p))
    {
      gfc_error_check ();
      return false;
    }
  gfc_expression_rank (p);

  /* Is this an inquiry?  */
  bool inquiry = false;
  gfc_ref* ref = p->ref;
  while (ref)
    {
      if (ref->type == REF_INQUIRY)
	break;
      ref = ref->next;
    }
  if (ref && ref->type == REF_INQUIRY)
    inquiry = ref->u.i == INQUIRY_LEN || ref->u.i == INQUIRY_KIND;

  if (gfc_is_size_zero_array (p))
    {
      if (p->expr_type == EXPR_ARRAY)
	return true;

      e = gfc_get_expr ();
      e->expr_type = EXPR_ARRAY;
      e->ts = p->ts;
      e->rank = p->rank;
      e->corank = p->corank;
      e->value.constructor = NULL;
      e->shape = gfc_copy_shape (p->shape, p->rank);
      e->where = p->where;
      /* If %kind and %len are not used then we're done, otherwise
	 drop through for simplification.  */
      if (!inquiry)
	{
	  gfc_replace_expr (p, e);
	  return true;
	}
    }
  else
    {
      e = gfc_copy_expr (p->symtree->n.sym->value);
      if (e == NULL)
	return false;

      gfc_free_shape (&e->shape, e->rank);
      e->shape = gfc_copy_shape (p->shape, p->rank);
      e->rank = p->rank;
      e->corank = p->corank;

      if (e->ts.type == BT_CHARACTER && p->ts.u.cl)
	e->ts = p->ts;
    }

  if (e->ts.type == BT_CHARACTER && e->ts.u.cl == NULL)
    e->ts.u.cl = gfc_new_charlen (gfc_current_ns, p->ts.u.cl);

  /* Do not copy subobject refs for constant.  */
  if (e->expr_type != EXPR_CONSTANT && p->ref != NULL)
    e->ref = gfc_copy_ref (p->ref);
  t = gfc_simplify_expr (e, type);
  e->where = p->where;

  /* Only use the simplification if it eliminated all subobject references.  */
  if (t && !e->ref)
    gfc_replace_expr (p, e);
  else
    gfc_free_expr (e);

  return t;
}


static bool
scalarize_intrinsic_call (gfc_expr *, bool init_flag);

/* Given an expression, simplify it by collapsing constant
   expressions.  Most simplification takes place when the expression
   tree is being constructed.  If an intrinsic function is simplified
   at some point, we get called again to collapse the result against
   other constants.

   We work by recursively simplifying expression nodes, simplifying
   intrinsic functions where possible, which can lead to further
   constant collapsing.  If an operator has constant operand(s), we
   rip the expression apart, and rebuild it, hoping that it becomes
   something simpler.

   The expression type is defined for:
     0   Basic expression parsing
     1   Simplifying array constructors -- will substitute
	 iterator values.
   Returns false on error, true otherwise.
   NOTE: Will return true even if the expression cannot be simplified.  */

bool
gfc_simplify_expr (gfc_expr *p, int type)
{
  gfc_actual_arglist *ap;
  gfc_intrinsic_sym* isym = NULL;


  if (p == NULL)
    return true;

  switch (p->expr_type)
    {
    case EXPR_CONSTANT:
      if (p->ref && p->ref->type == REF_INQUIRY)
	simplify_ref_chain (p->ref, type, &p);
      break;
    case EXPR_NULL:
      break;

    case EXPR_FUNCTION:
      // For array-bound functions, we don't need to optimize
      // the 'array' argument. In particular, if the argument
      // is a PARAMETER, simplifying might convert an EXPR_VARIABLE
      // into an EXPR_ARRAY; the latter has lbound = 1, the former
      // can have any lbound.
      ap = p->value.function.actual;
      if (p->value.function.isym &&
	  (p->value.function.isym->id == GFC_ISYM_LBOUND
	   || p->value.function.isym->id == GFC_ISYM_UBOUND
	   || p->value.function.isym->id == GFC_ISYM_LCOBOUND
	   || p->value.function.isym->id == GFC_ISYM_UCOBOUND
	   || p->value.function.isym->id == GFC_ISYM_SHAPE))
	ap = ap->next;

      for ( ; ap; ap = ap->next)
	if (!gfc_simplify_expr (ap->expr, type))
	  return false;

      if (p->value.function.isym != NULL
	  && gfc_intrinsic_func_interface (p, 1) == MATCH_ERROR)
	return false;

      if (p->symtree && (p->value.function.isym || p->ts.type == BT_UNKNOWN))
	{
	  isym = gfc_find_function (p->symtree->n.sym->name);
	  if (isym && isym->elemental)
	    scalarize_intrinsic_call (p, false);
	}

      break;

    case EXPR_SUBSTRING:
      if (!simplify_ref_chain (p->ref, type, &p))
	return false;

      if (gfc_is_constant_expr (p))
	{
	  gfc_char_t *s;
	  HOST_WIDE_INT start, end;

	  start = 0;
	  if (p->ref && p->ref->u.ss.start)
	    {
	      gfc_extract_hwi (p->ref->u.ss.start, &start);
	      start--;  /* Convert from one-based to zero-based.  */
	    }

	  end = p->value.character.length;
	  if (p->ref && p->ref->u.ss.end)
	    gfc_extract_hwi (p->ref->u.ss.end, &end);

	  if (end < start)
	    end = start;

	  s = gfc_get_wide_string (end - start + 2);
	  memcpy (s, p->value.character.string + start,
		  (end - start) * sizeof (gfc_char_t));
	  s[end - start + 1] = '\0';  /* TODO: C-style string.  */
	  free (p->value.character.string);
	  p->value.character.string = s;
	  p->value.character.length = end - start;
	  p->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
	  p->ts.u.cl->length = gfc_get_int_expr (gfc_charlen_int_kind,
						 NULL,
						 p->value.character.length);
	  gfc_free_ref_list (p->ref);
	  p->ref = NULL;
	  p->expr_type = EXPR_CONSTANT;
	}
      break;

    case EXPR_OP:
      if (!simplify_intrinsic_op (p, type))
	return false;
      break;

    case EXPR_VARIABLE:
      /* Only substitute array parameter variables if we are in an
	 initialization expression, or we want a subsection.  */
      if (p->symtree->n.sym->attr.flavor == FL_PARAMETER
	  && (gfc_init_expr_flag || p->ref
	      || (p->symtree->n.sym->value
		  && p->symtree->n.sym->value->expr_type != EXPR_ARRAY)))
	{
	  if (!simplify_parameter_variable (p, type))
	    return false;
	  if (!iter_stack)
	    break;
	}

      if (type == 1)
	{
	  gfc_simplify_iterator_var (p);
	}

      /* Simplify subcomponent references.  */
      if (!simplify_ref_chain (p->ref, type, &p))
	return false;

      break;

    case EXPR_STRUCTURE:
    case EXPR_ARRAY:
      if (!simplify_ref_chain (p->ref, type, &p))
	return false;

      /* If the following conditions hold, we found something like kind type
	 inquiry of the form a(2)%kind while simplify the ref chain.  */
      if (p->expr_type == EXPR_CONSTANT && !p->ref && !p->rank && !p->shape)
	return true;

      if (!simplify_constructor (p->value.constructor, type))
	return false;

      if (p->expr_type == EXPR_ARRAY && p->ref && p->ref->type == REF_ARRAY
	  && p->ref->u.ar.type == AR_FULL)
	  gfc_expand_constructor (p, false);

      if (!simplify_const_ref (p))
	return false;

      break;

    case EXPR_COMPCALL:
    case EXPR_PPC:
      break;

    case EXPR_UNKNOWN:
      gcc_unreachable ();
    }

  return true;
}


/* Try simplification of an expression via gfc_simplify_expr.
   When an error occurs (arithmetic or otherwise), roll back.  */

bool
gfc_try_simplify_expr (gfc_expr *e, int type)
{
  gfc_expr *n;
  bool t, saved_div0;

  if (e == NULL || e->expr_type == EXPR_CONSTANT)
    return true;

  saved_div0 = gfc_seen_div0;
  gfc_seen_div0 = false;
  n = gfc_copy_expr (e);
  t = gfc_simplify_expr (n, type) && !gfc_seen_div0;
  if (t)
    gfc_replace_expr (e, n);
  else
    gfc_free_expr (n);
  gfc_seen_div0 = saved_div0;
  return t;
}


/* Returns the type of an expression with the exception that iterator
   variables are automatically integers no matter what else they may
   be declared as.  */

static bt
et0 (gfc_expr *e)
{
  if (e->expr_type == EXPR_VARIABLE && gfc_check_iter_variable (e))
    return BT_INTEGER;

  return e->ts.type;
}


/* Scalarize an expression for an elemental intrinsic call.  */

static bool
scalarize_intrinsic_call (gfc_expr *e, bool init_flag)
{
  gfc_actual_arglist *a, *b;
  gfc_constructor_base ctor;
  gfc_constructor *args[5] = {};  /* Avoid uninitialized warnings.  */
  gfc_constructor *ci, *new_ctor;
  gfc_expr *expr, *old, *p;
  int n, i, rank[5], array_arg;

  if (e == NULL)
    return false;

  a = e->value.function.actual;
  for (; a; a = a->next)
    if (a->expr && !gfc_is_constant_expr (a->expr))
      return false;

  /* Find which, if any, arguments are arrays.  Assume that the old
     expression carries the type information and that the first arg
     that is an array expression carries all the shape information.*/
  n = array_arg = 0;
  a = e->value.function.actual;
  for (; a; a = a->next)
    {
      n++;
      if (!a->expr || a->expr->expr_type != EXPR_ARRAY)
	continue;
      array_arg = n;
      expr = gfc_copy_expr (a->expr);
      break;
    }

  if (!array_arg)
    return false;

  old = gfc_copy_expr (e);

  gfc_constructor_free (expr->value.constructor);
  expr->value.constructor = NULL;
  expr->ts = old->ts;
  expr->where = old->where;
  expr->expr_type = EXPR_ARRAY;

  /* Copy the array argument constructors into an array, with nulls
     for the scalars.  */
  n = 0;
  a = old->value.function.actual;
  for (; a; a = a->next)
    {
      /* Check that this is OK for an initialization expression.  */
      if (a->expr && init_flag && !gfc_check_init_expr (a->expr))
	goto cleanup;

      rank[n] = 0;
      if (a->expr && a->expr->rank && a->expr->expr_type == EXPR_VARIABLE)
	{
	  rank[n] = a->expr->rank;
	  ctor = a->expr->symtree->n.sym->value->value.constructor;
	  args[n] = gfc_constructor_first (ctor);
	}
      else if (a->expr && a->expr->expr_type == EXPR_ARRAY)
	{
	  if (a->expr->rank)
	    rank[n] = a->expr->rank;
	  else
	    rank[n] = 1;
	  ctor = a->expr->value.constructor;
	  args[n] = gfc_constructor_first (ctor);
	}
      else
	args[n] = NULL;

      n++;
    }

  /* Using the array argument as the master, step through the array
     calling the function for each element and advancing the array
     constructors together.  */
  for (ci = args[array_arg - 1]; ci; ci = gfc_constructor_next (ci))
    {
      new_ctor = gfc_constructor_append_expr (&expr->value.constructor,
					      gfc_copy_expr (old), NULL);

      gfc_free_actual_arglist (new_ctor->expr->value.function.actual);
      a = NULL;
      b = old->value.function.actual;
      for (i = 0; i < n; i++)
	{
	  if (a == NULL)
	    new_ctor->expr->value.function.actual
			= a = gfc_get_actual_arglist ();
	  else
	    {
	      a->next = gfc_get_actual_arglist ();
	      a = a->next;
	    }

	  if (args[i])
	    a->expr = gfc_copy_expr (args[i]->expr);
	  else
	    a->expr = gfc_copy_expr (b->expr);

	  b = b->next;
	}

      /* Simplify the function calls.  If the simplification fails, the
	 error will be flagged up down-stream or the library will deal
	 with it.  */
      p = gfc_copy_expr (new_ctor->expr);

      if (!gfc_simplify_expr (p, init_flag))
	gfc_free_expr (p);
      else
	gfc_replace_expr (new_ctor->expr, p);

      for (i = 0; i < n; i++)
	if (args[i])
	  args[i] = gfc_constructor_next (args[i]);

      for (i = 1; i < n; i++)
	if (rank[i] && ((args[i] != NULL && args[array_arg - 1] == NULL)
			|| (args[i] == NULL && args[array_arg - 1] != NULL)))
	  goto compliance;
    }

  free_expr0 (e);
  *e = *expr;
  /* Free "expr" but not the pointers it contains.  */
  free (expr);
  gfc_free_expr (old);
  return true;

compliance:
  gfc_error_now ("elemental function arguments at %C are not compliant");

cleanup:
  gfc_free_expr (expr);
  gfc_free_expr (old);
  return false;
}


static bool
check_intrinsic_op (gfc_expr *e, bool (*check_function) (gfc_expr *))
{
  gfc_expr *op1 = e->value.op.op1;
  gfc_expr *op2 = e->value.op.op2;

  if (!(*check_function)(op1))
    return false;

  switch (e->value.op.op)
    {
    case INTRINSIC_UPLUS:
    case INTRINSIC_UMINUS:
      if (!numeric_type (et0 (op1)))
	goto not_numeric;
      break;

    case INTRINSIC_EQ:
    case INTRINSIC_EQ_OS:
    case INTRINSIC_NE:
    case INTRINSIC_NE_OS:
    case INTRINSIC_GT:
    case INTRINSIC_GT_OS:
    case INTRINSIC_GE:
    case INTRINSIC_GE_OS:
    case INTRINSIC_LT:
    case INTRINSIC_LT_OS:
    case INTRINSIC_LE:
    case INTRINSIC_LE_OS:
      if (!(*check_function)(op2))
	return false;

      if (!(et0 (op1) == BT_CHARACTER && et0 (op2) == BT_CHARACTER)
	  && !(numeric_type (et0 (op1)) && numeric_type (et0 (op2))))
	{
	  gfc_error ("Numeric or CHARACTER operands are required in "
		     "expression at %L", &e->where);
	 return false;
	}
      break;

    case INTRINSIC_PLUS:
    case INTRINSIC_MINUS:
    case INTRINSIC_TIMES:
    case INTRINSIC_DIVIDE:
    case INTRINSIC_POWER:
      if (!(*check_function)(op2))
	return false;

      if (!numeric_type (et0 (op1)) || !numeric_type (et0 (op2)))
	goto not_numeric;

      break;

    case INTRINSIC_CONCAT:
      if (!(*check_function)(op2))
	return false;

      if (et0 (op1) != BT_CHARACTER || et0 (op2) != BT_CHARACTER)
	{
	  gfc_error ("Concatenation operator in expression at %L "
		     "must have two CHARACTER operands", &op1->where);
	  return false;
	}

      if (op1->ts.kind != op2->ts.kind)
	{
	  gfc_error ("Concat operator at %L must concatenate strings of the "
		     "same kind", &e->where);
	  return false;
	}

      break;

    case INTRINSIC_NOT:
      if (et0 (op1) != BT_LOGICAL)
	{
	  gfc_error (".NOT. operator in expression at %L must have a LOGICAL "
		     "operand", &op1->where);
	  return false;
	}

      break;

    case INTRINSIC_AND:
    case INTRINSIC_OR:
    case INTRINSIC_EQV:
    case INTRINSIC_NEQV:
      if (!(*check_function)(op2))
	return false;

      if (et0 (op1) != BT_LOGICAL || et0 (op2) != BT_LOGICAL)
	{
	  gfc_error ("LOGICAL operands are required in expression at %L",
		     &e->where);
	  return false;
	}

      break;

    case INTRINSIC_PARENTHESES:
      break;

    default:
      gfc_error ("Only intrinsic operators can be used in expression at %L",
		 &e->where);
      return false;
    }

  return true;

not_numeric:
  gfc_error ("Numeric operands are required in expression at %L", &e->where);

  return false;
}

/* F2003, 7.1.7 (3): In init expression, allocatable components
   must not be data-initialized.  */
static bool
check_alloc_comp_init (gfc_expr *e)
{
  gfc_component *comp;
  gfc_constructor *ctor;

  gcc_assert (e->expr_type == EXPR_STRUCTURE);
  gcc_assert (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS);

  for (comp = e->ts.u.derived->components,
       ctor = gfc_constructor_first (e->value.constructor);
       comp; comp = comp->next, ctor = gfc_constructor_next (ctor))
    {
      if (comp->attr.allocatable && ctor->expr
          && ctor->expr->expr_type != EXPR_NULL)
        {
	  gfc_error ("Invalid initialization expression for ALLOCATABLE "
		     "component %qs in structure constructor at %L",
		     comp->name, &ctor->expr->where);
	  return false;
	}
    }

  return true;
}

static match
check_init_expr_arguments (gfc_expr *e)
{
  gfc_actual_arglist *ap;

  for (ap = e->value.function.actual; ap; ap = ap->next)
    if (!gfc_check_init_expr (ap->expr))
      return MATCH_ERROR;

  return MATCH_YES;
}

static bool check_restricted (gfc_expr *);

/* F95, 7.1.6.1, Initialization expressions, (7)
   F2003, 7.1.7 Initialization expression, (8)
   F2008, 7.1.12 Constant expression, (4)  */

static match
check_inquiry (gfc_expr *e, int not_restricted)
{
  const char *name;
  const char *const *functions;

  static const char *const inquiry_func_f95[] = {
    "lbound", "shape", "size", "ubound",
    "bit_size", "len", "kind",
    "digits", "epsilon", "huge", "maxexponent", "minexponent",
    "precision", "radix", "range", "tiny",
    NULL
  };

  static const char *const inquiry_func_f2003[] = {
    "lbound", "shape", "size", "ubound",
    "bit_size", "len", "kind",
    "digits", "epsilon", "huge", "maxexponent", "minexponent",
    "precision", "radix", "range", "tiny",
    "new_line", NULL
  };

  /* std=f2008+ or -std=gnu */
  static const char *const inquiry_func_gnu[] = {
    "lbound", "shape", "size", "ubound",
    "bit_size", "len", "kind",
    "digits", "epsilon", "huge", "maxexponent", "minexponent",
    "precision", "radix", "range", "tiny",
    "new_line", "storage_size", NULL
  };

  int i = 0;
  gfc_actual_arglist *ap;
  gfc_symbol *sym;
  gfc_symbol *asym;

  if (!e->value.function.isym
      || !e->value.function.isym->inquiry)
    return MATCH_NO;

  /* An undeclared parameter will get us here (PR25018).  */
  if (e->symtree == NULL)
    return MATCH_NO;

  sym = e->symtree->n.sym;

  if (sym->from_intmod)
    {
      if (sym->from_intmod == INTMOD_ISO_FORTRAN_ENV
	  && sym->intmod_sym_id != ISOFORTRAN_COMPILER_OPTIONS
	  && sym->intmod_sym_id != ISOFORTRAN_COMPILER_VERSION)
	return MATCH_NO;

      if (sym->from_intmod == INTMOD_ISO_C_BINDING
	  && sym->intmod_sym_id != ISOCBINDING_C_SIZEOF)
	return MATCH_NO;
    }
  else
    {
      name = sym->name;

      functions = inquiry_func_gnu;
      if (gfc_option.warn_std & GFC_STD_F2003)
	functions = inquiry_func_f2003;
      if (gfc_option.warn_std & GFC_STD_F95)
	functions = inquiry_func_f95;

      for (i = 0; functions[i]; i++)
	if (strcmp (functions[i], name) == 0)
	  break;

      if (functions[i] == NULL)
	return MATCH_ERROR;
    }

  /* At this point we have an inquiry function with a variable argument.  The
     type of the variable might be undefined, but we need it now, because the
     arguments of these functions are not allowed to be undefined.  */

  for (ap = e->value.function.actual; ap; ap = ap->next)
    {
      if (!ap->expr)
	continue;

      asym = ap->expr->symtree ? ap->expr->symtree->n.sym : NULL;

      if (ap->expr->ts.type == BT_UNKNOWN)
	{
	  if (asym && asym->ts.type == BT_UNKNOWN
	      && !gfc_set_default_type (asym, 0, gfc_current_ns))
	    return MATCH_NO;

	  ap->expr->ts = asym->ts;
	}

      if (asym && asym->assoc && asym->assoc->target
	  && asym->assoc->target->expr_type == EXPR_CONSTANT)
	{
	  gfc_free_expr (ap->expr);
	  ap->expr = gfc_copy_expr (asym->assoc->target);
	}

      /* Assumed character length will not reduce to a constant expression
	 with LEN, as required by the standard.  */
      if (i == 5 && not_restricted && asym
	  && asym->ts.type == BT_CHARACTER
	  && ((asym->ts.u.cl && asym->ts.u.cl->length == NULL)
	      || asym->ts.deferred))
	{
	  gfc_error ("Assumed or deferred character length variable %qs "
		     "in constant expression at %L",
		      asym->name, &ap->expr->where);
	  return MATCH_ERROR;
	}
      else if (not_restricted && !gfc_check_init_expr (ap->expr))
	return MATCH_ERROR;

      if (not_restricted == 0
	  && ap->expr->expr_type != EXPR_VARIABLE
	  && !check_restricted (ap->expr))
	return MATCH_ERROR;

      if (not_restricted == 0
	  && ap->expr->expr_type == EXPR_VARIABLE
	  && asym->attr.dummy && asym->attr.optional)
	return MATCH_NO;
    }

  return MATCH_YES;
}


/* F95, 7.1.6.1, Initialization expressions, (5)
   F2003, 7.1.7 Initialization expression, (5)  */

static match
check_transformational (gfc_expr *e)
{
  static const char * const trans_func_f95[] = {
    "repeat", "reshape", "selected_int_kind",
    "selected_real_kind", "transfer", "trim", NULL
  };

  static const char * const trans_func_f2003[] =  {
    "all", "any", "count", "dot_product", "matmul", "null", "pack",
    "product", "repeat", "reshape", "selected_char_kind", "selected_int_kind",
    "selected_real_kind", "spread", "sum", "transfer", "transpose",
    "trim", "unpack", NULL
  };

  static const char * const trans_func_f2008[] =  {
    "all", "any", "count", "dot_product", "matmul", "null", "pack",
    "product", "repeat", "reshape", "selected_char_kind", "selected_int_kind",
    "selected_real_kind", "spread", "sum", "transfer", "transpose",
    "trim", "unpack", "findloc", NULL
  };

  static const char * const trans_func_f2023[] =  {
    "all", "any", "count", "dot_product", "matmul", "null", "pack",
    "product", "repeat", "reshape", "selected_char_kind", "selected_int_kind",
    "selected_logical_kind", "selected_real_kind", "spread", "sum", "transfer",
    "transpose", "trim", "unpack", "findloc", NULL
  };

  int i;
  const char *name;
  const char *const *functions;

  if (!e->value.function.isym
      || !e->value.function.isym->transformational)
    return MATCH_NO;

  name = e->symtree->n.sym->name;

  if (gfc_option.allow_std & GFC_STD_F2023)
    functions = trans_func_f2023;
  else if (gfc_option.allow_std & GFC_STD_F2008)
    functions = trans_func_f2008;
  else if (gfc_option.allow_std & GFC_STD_F2003)
    functions = trans_func_f2003;
  else
    functions = trans_func_f95;

  /* NULL() is dealt with below.  */
  if (strcmp ("null", name) == 0)
    return MATCH_NO;

  for (i = 0; functions[i]; i++)
    if (strcmp (functions[i], name) == 0)
       break;

  if (functions[i] == NULL)
    {
      gfc_error ("transformational intrinsic %qs at %L is not permitted "
		 "in an initialization expression", name, &e->where);
      return MATCH_ERROR;
    }

  return check_init_expr_arguments (e);
}


/* F95, 7.1.6.1, Initialization expressions, (6)
   F2003, 7.1.7 Initialization expression, (6)  */

static match
check_null (gfc_expr *e)
{
  if (strcmp ("null", e->symtree->n.sym->name) != 0)
    return MATCH_NO;

  return check_init_expr_arguments (e);
}


static match
check_elemental (gfc_expr *e)
{
  if (!e->value.function.isym
      || !e->value.function.isym->elemental)
    return MATCH_NO;

  if (e->ts.type != BT_INTEGER
      && e->ts.type != BT_CHARACTER
      && !gfc_notify_std (GFC_STD_F2003, "Evaluation of nonstandard "
			  "initialization expression at %L", &e->where))
    return MATCH_ERROR;

  return check_init_expr_arguments (e);
}


static match
check_conversion (gfc_expr *e)
{
  if (!e->value.function.isym
      || !e->value.function.isym->conversion)
    return MATCH_NO;

  return check_init_expr_arguments (e);
}


/* Verify that an expression is an initialization expression.  A side
   effect is that the expression tree is reduced to a single constant
   node if all goes well.  This would normally happen when the
   expression is constructed but function references are assumed to be
   intrinsics in the context of initialization expressions.  If
   false is returned an error message has been generated.  */

bool
gfc_check_init_expr (gfc_expr *e)
{
  match m;
  bool t;

  if (e == NULL)
    return true;

  switch (e->expr_type)
    {
    case EXPR_OP:
      t = check_intrinsic_op (e, gfc_check_init_expr);
      if (t)
	t = gfc_simplify_expr (e, 0);

      break;

    case EXPR_FUNCTION:
      t = false;

      {
	bool conversion;
	gfc_intrinsic_sym* isym = NULL;
	gfc_symbol* sym = e->symtree->n.sym;

	/* Simplify here the intrinsics from the IEEE_ARITHMETIC and
	   IEEE_EXCEPTIONS modules.  */
	int mod = sym->from_intmod;
	if (mod == INTMOD_NONE && sym->generic)
	  mod = sym->generic->sym->from_intmod;
	if (mod == INTMOD_IEEE_ARITHMETIC || mod == INTMOD_IEEE_EXCEPTIONS)
	  {
	    gfc_expr *new_expr = gfc_simplify_ieee_functions (e);
	    if (new_expr)
	      {
		gfc_replace_expr (e, new_expr);
		t = true;
		break;
	      }
	  }

	/* If a conversion function, e.g., __convert_i8_i4, was inserted
	   into an array constructor, we need to skip the error check here.
           Conversion errors are  caught below in scalarize_intrinsic_call.  */
	conversion = e->value.function.isym
		   && (e->value.function.isym->conversion == 1);

	if (!conversion && (!gfc_is_intrinsic (sym, 0, e->where)
	    || (m = gfc_intrinsic_func_interface (e, 0)) == MATCH_NO))
	  {
	    gfc_error ("Function %qs in initialization expression at %L "
		       "must be an intrinsic function",
		       e->symtree->n.sym->name, &e->where);
	    break;
	  }

	if ((m = check_conversion (e)) == MATCH_NO
	    && (m = check_inquiry (e, 1)) == MATCH_NO
	    && (m = check_null (e)) == MATCH_NO
	    && (m = check_transformational (e)) == MATCH_NO
	    && (m = check_elemental (e)) == MATCH_NO)
	  {
	    gfc_error ("Intrinsic function %qs at %L is not permitted "
		       "in an initialization expression",
		       e->symtree->n.sym->name, &e->where);
	    m = MATCH_ERROR;
	  }

	if (m == MATCH_ERROR)
	  return false;

	/* Try to scalarize an elemental intrinsic function that has an
	   array argument.  */
	isym = gfc_find_function (e->symtree->n.sym->name);
	if (isym && isym->elemental
	    && (t = scalarize_intrinsic_call (e, true)))
	  break;
      }

      if (m == MATCH_YES)
	t = gfc_simplify_expr (e, 0);

      break;

    case EXPR_VARIABLE:
      t = true;

      /* This occurs when parsing pdt templates.  */
      if (gfc_expr_attr (e).pdt_kind)
	break;

      if (gfc_check_iter_variable (e))
	break;

      if (e->symtree->n.sym->attr.flavor == FL_PARAMETER)
	{
	  /* A PARAMETER shall not be used to define itself, i.e.
		REAL, PARAMETER :: x = transfer(0, x)
	     is invalid.  */
	  if (!e->symtree->n.sym->value)
	    {
	      gfc_error ("PARAMETER %qs is used at %L before its definition "
			 "is complete", e->symtree->n.sym->name, &e->where);
	      t = false;
	    }
	  else
	    t = simplify_parameter_variable (e, 0);

	  break;
	}

      if (gfc_in_match_data ())
	break;

      t = false;

      if (e->symtree->n.sym->as)
	{
	  switch (e->symtree->n.sym->as->type)
	    {
	      case AS_ASSUMED_SIZE:
		gfc_error ("Assumed size array %qs at %L is not permitted "
			   "in an initialization expression",
			   e->symtree->n.sym->name, &e->where);
		break;

	      case AS_ASSUMED_SHAPE:
		gfc_error ("Assumed shape array %qs at %L is not permitted "
			   "in an initialization expression",
			   e->symtree->n.sym->name, &e->where);
		break;

	      case AS_DEFERRED:
		if (!e->symtree->n.sym->attr.allocatable
		    && !e->symtree->n.sym->attr.pointer
		    && e->symtree->n.sym->attr.dummy)
		  gfc_error ("Assumed-shape array %qs at %L is not permitted "
			     "in an initialization expression",
			     e->symtree->n.sym->name, &e->where);
		else
		  gfc_error ("Deferred array %qs at %L is not permitted "
			     "in an initialization expression",
			     e->symtree->n.sym->name, &e->where);
		break;

	      case AS_EXPLICIT:
		gfc_error ("Array %qs at %L is a variable, which does "
			   "not reduce to a constant expression",
			   e->symtree->n.sym->name, &e->where);
		break;

	      case AS_ASSUMED_RANK:
		gfc_error ("Assumed-rank array %qs at %L is not permitted "
			   "in an initialization expression",
			   e->symtree->n.sym->name, &e->where);
		break;

	      default:
		gcc_unreachable();
	  }
	}
      else
	gfc_error ("Parameter %qs at %L has not been declared or is "
		   "a variable, which does not reduce to a constant "
		   "expression", e->symtree->name, &e->where);

      break;

    case EXPR_CONSTANT:
    case EXPR_NULL:
      t = true;
      break;

    case EXPR_SUBSTRING:
      if (e->ref)
	{
	  t = gfc_check_init_expr (e->ref->u.ss.start);
	  if (!t)
	    break;

	  t = gfc_check_init_expr (e->ref->u.ss.end);
	  if (t)
	    t = gfc_simplify_expr (e, 0);
	}
      else
	t = false;
      break;

    case EXPR_STRUCTURE:
      t = e->ts.is_iso_c ? true : false;
      if (t)
	break;

      t = check_alloc_comp_init (e);
      if (!t)
	break;

      t = gfc_check_constructor (e, gfc_check_init_expr);
      if (!t)
	break;

      break;

    case EXPR_ARRAY:
      t = gfc_check_constructor (e, gfc_check_init_expr);
      if (!t)
	break;

      t = gfc_expand_constructor (e, true);
      if (!t)
	break;

      t = gfc_check_constructor_type (e);
      break;

    default:
      gfc_internal_error ("check_init_expr(): Unknown expression type");
    }

  return t;
}

/* Reduces a general expression to an initialization expression (a constant).
   This used to be part of gfc_match_init_expr.
   Note that this function doesn't free the given expression on false.  */

bool
gfc_reduce_init_expr (gfc_expr *expr)
{
  bool t;

  /* It is far too early to resolve a class compcall. Punt to resolution.  */
  if (expr && expr->expr_type == EXPR_COMPCALL
      && expr->symtree->n.sym->ts.type == BT_CLASS)
    return false;

  gfc_init_expr_flag = true;
  t = gfc_resolve_expr (expr);
  if (t)
    t = gfc_check_init_expr (expr);
  gfc_init_expr_flag = false;

  if (!t || !expr)
    return false;

  if (expr->expr_type == EXPR_ARRAY)
    {
      if (!gfc_check_constructor_type (expr))
	return false;
      if (!gfc_expand_constructor (expr, true))
	return false;
    }

  return true;
}


/* Match an initialization expression.  We work by first matching an
   expression, then reducing it to a constant.  */

match
gfc_match_init_expr (gfc_expr **result)
{
  gfc_expr *expr;
  match m;
  bool t;

  expr = NULL;

  gfc_init_expr_flag = true;

  m = gfc_match_expr (&expr);
  if (m != MATCH_YES)
    {
      gfc_init_expr_flag = false;
      return m;
    }

  if (expr->expr_type != EXPR_FUNCTION && gfc_derived_parameter_expr (expr))
    {
      *result = expr;
      gfc_init_expr_flag = false;
      return m;
    }

  t = gfc_reduce_init_expr (expr);
  if (!t)
    {
      gfc_free_expr (expr);
      gfc_init_expr_flag = false;
      return MATCH_ERROR;
    }

  *result = expr;
  gfc_init_expr_flag = false;

  return MATCH_YES;
}


/* Given an actual argument list, test to see that each argument is a
   restricted expression and optionally if the expression type is
   integer or character.  */

static bool
restricted_args (gfc_actual_arglist *a)
{
  for (; a; a = a->next)
    {
      if (!check_restricted (a->expr))
	return false;
    }

  return true;
}


/************* Restricted/specification expressions *************/


/* Make sure a non-intrinsic function is a specification function,
 * see F08:7.1.11.5.  */

static bool
external_spec_function (gfc_expr *e)
{
  gfc_symbol *f;

  f = e->value.function.esym;

  /* IEEE functions allowed are "a reference to a transformational function
     from the intrinsic module IEEE_ARITHMETIC or IEEE_EXCEPTIONS", and
     "inquiry function from the intrinsic modules IEEE_ARITHMETIC and
     IEEE_EXCEPTIONS".  */
  if (f->from_intmod == INTMOD_IEEE_ARITHMETIC
      || f->from_intmod == INTMOD_IEEE_EXCEPTIONS)
    {
      if (!strcmp (f->name, "ieee_selected_real_kind")
	  || !strcmp (f->name, "ieee_support_rounding")
	  || !strcmp (f->name, "ieee_support_flag")
	  || !strcmp (f->name, "ieee_support_halting")
	  || !strcmp (f->name, "ieee_support_datatype")
	  || !strcmp (f->name, "ieee_support_denormal")
	  || !strcmp (f->name, "ieee_support_subnormal")
	  || !strcmp (f->name, "ieee_support_divide")
	  || !strcmp (f->name, "ieee_support_inf")
	  || !strcmp (f->name, "ieee_support_io")
	  || !strcmp (f->name, "ieee_support_nan")
	  || !strcmp (f->name, "ieee_support_sqrt")
	  || !strcmp (f->name, "ieee_support_standard")
	  || !strcmp (f->name, "ieee_support_underflow_control"))
	goto function_allowed;
    }

  if (f->attr.proc == PROC_ST_FUNCTION)
    {
      gfc_error ("Specification function %qs at %L cannot be a statement "
		 "function", f->name, &e->where);
      return false;
    }

  if (f->attr.proc == PROC_INTERNAL)
    {
      gfc_error ("Specification function %qs at %L cannot be an internal "
		 "function", f->name, &e->where);
      return false;
    }

  if (!f->attr.pure && !f->attr.elemental)
    {
      gfc_error ("Specification function %qs at %L must be PURE", f->name,
		 &e->where);
      return false;
    }

  /* F08:7.1.11.6. */
  if (f->attr.recursive
      && !gfc_notify_std (GFC_STD_F2003,
			  "Specification function %qs "
			  "at %L cannot be RECURSIVE",  f->name, &e->where))
      return false;

function_allowed:
  return restricted_args (e->value.function.actual);
}


/* Check to see that a function reference to an intrinsic is a
   restricted expression.  */

static bool
restricted_intrinsic (gfc_expr *e)
{
  /* TODO: Check constraints on inquiry functions.  7.1.6.2 (7).  */
  if (check_inquiry (e, 0) == MATCH_YES)
    return true;

  return restricted_args (e->value.function.actual);
}


/* Check the expressions of an actual arglist.  Used by check_restricted.  */

static bool
check_arglist (gfc_actual_arglist* arg, bool (*checker) (gfc_expr*))
{
  for (; arg; arg = arg->next)
    if (!checker (arg->expr))
      return false;

  return true;
}


/* Check the subscription expressions of a reference chain with a checking
   function; used by check_restricted.  */

static bool
check_references (gfc_ref* ref, bool (*checker) (gfc_expr*))
{
  int dim;

  if (!ref)
    return true;

  switch (ref->type)
    {
    case REF_ARRAY:
      for (dim = 0; dim < ref->u.ar.dimen; ++dim)
	{
	  if (!checker (ref->u.ar.start[dim]))
	    return false;
	  if (!checker (ref->u.ar.end[dim]))
	    return false;
	  if (!checker (ref->u.ar.stride[dim]))
	    return false;
	}
      break;

    case REF_COMPONENT:
      /* Nothing needed, just proceed to next reference.  */
      break;

    case REF_SUBSTRING:
      if (!checker (ref->u.ss.start))
	return false;
      if (!checker (ref->u.ss.end))
	return false;
      break;

    default:
      gcc_unreachable ();
      break;
    }

  return check_references (ref->next, checker);
}

/*  Return true if ns is a parent of the current ns.  */

static bool
is_parent_of_current_ns (gfc_namespace *ns)
{
  gfc_namespace *p;
  for (p = gfc_current_ns->parent; p; p = p->parent)
    if (ns == p)
      return true;

  return false;
}

/* Verify that an expression is a restricted expression.  Like its
   cousin check_init_expr(), an error message is generated if we
   return false.  */

static bool
check_restricted (gfc_expr *e)
{
  gfc_symbol* sym;
  bool t;

  if (e == NULL)
    return true;

  switch (e->expr_type)
    {
    case EXPR_OP:
      t = check_intrinsic_op (e, check_restricted);
      if (t)
	t = gfc_simplify_expr (e, 0);

      break;

    case EXPR_FUNCTION:
      if (e->value.function.esym)
	{
	  t = check_arglist (e->value.function.actual, &check_restricted);
	  if (t)
	    t = external_spec_function (e);
	}
      else
	{
	  if (e->value.function.isym && e->value.function.isym->inquiry)
	    t = true;
	  else
	    t = check_arglist (e->value.function.actual, &check_restricted);

	  if (t)
	    t = restricted_intrinsic (e);
	}
      break;

    case EXPR_VARIABLE:
      sym = e->symtree->n.sym;
      t = false;

      /* If a dummy argument appears in a context that is valid for a
	 restricted expression in an elemental procedure, it will have
	 already been simplified away once we get here.  Therefore we
	 don't need to jump through hoops to distinguish valid from
	 invalid cases.  Allowed in F2008 and F2018.  */
      if (gfc_notification_std (GFC_STD_F2008)
	  && sym->attr.dummy && sym->ns == gfc_current_ns
	  && sym->ns->proc_name && sym->ns->proc_name->attr.elemental)
	{
	  gfc_error_now ("Dummy argument %qs not "
			 "allowed in expression at %L",
			 sym->name, &e->where);
	  break;
	}

      if (sym->attr.optional)
	{
	  gfc_error ("Dummy argument %qs at %L cannot be OPTIONAL",
		     sym->name, &e->where);
	  break;
	}

      if (sym->attr.intent == INTENT_OUT)
	{
	  gfc_error ("Dummy argument %qs at %L cannot be INTENT(OUT)",
		     sym->name, &e->where);
	  break;
	}

      /* Check reference chain if any.  */
      if (!check_references (e->ref, &check_restricted))
	break;

      if (e->error
	    || sym->attr.in_common
	    || sym->attr.use_assoc
	    || sym->attr.used_in_submodule
	    || sym->attr.dummy
	    || sym->attr.implied_index
	    || sym->attr.flavor == FL_PARAMETER
	    || is_parent_of_current_ns (gfc_get_spec_ns (sym)))
	{
	  t = true;
	  break;
	}

      gfc_error ("Variable %qs cannot appear in the expression at %L",
		 sym->name, &e->where);
      /* Prevent a repetition of the error.  */
      e->error = 1;
      break;

    case EXPR_NULL:
    case EXPR_CONSTANT:
      t = true;
      break;

    case EXPR_SUBSTRING:
      t = gfc_specification_expr (e->ref->u.ss.start);
      if (!t)
	break;

      t = gfc_specification_expr (e->ref->u.ss.end);
      if (t)
	t = gfc_simplify_expr (e, 0);

      break;

    case EXPR_STRUCTURE:
      t = gfc_check_constructor (e, check_restricted);
      break;

    case EXPR_ARRAY:
      t = gfc_check_constructor (e, check_restricted);
      break;

    default:
      gfc_internal_error ("check_restricted(): Unknown expression type");
    }

  return t;
}


/* Check to see that an expression is a specification expression.  If
   we return false, an error has been generated.  */

bool
gfc_specification_expr (gfc_expr *e)
{
  gfc_component *comp;

  if (e == NULL)
    return true;

  if (e->ts.type != BT_INTEGER)
    {
      gfc_error ("Expression at %L must be of INTEGER type, found %s",
		 &e->where, gfc_basic_typename (e->ts.type));
      return false;
    }

  comp = gfc_get_proc_ptr_comp (e);
  if (e->expr_type == EXPR_FUNCTION
      && !e->value.function.isym
      && !e->value.function.esym
      && !gfc_pure (e->symtree->n.sym)
      && (!comp || !comp->attr.pure))
    {
      gfc_error ("Function %qs at %L must be PURE",
		 e->symtree->n.sym->name, &e->where);
      /* Prevent repeat error messages.  */
      e->symtree->n.sym->attr.pure = 1;
      return false;
    }

  if (e->rank != 0)
    {
      gfc_error ("Expression at %L must be scalar", &e->where);
      return false;
    }

  if (!gfc_simplify_expr (e, 0))
    return false;

  return check_restricted (e);
}


/************** Expression conformance checks.  *************/

/* Given two expressions, make sure that the arrays are conformable.  */

bool
gfc_check_conformance (gfc_expr *op1, gfc_expr *op2, const char *optype_msgid, ...)
{
  int op1_flag, op2_flag, d;
  mpz_t op1_size, op2_size;
  bool t;

  va_list argp;
  char buffer[240];

  if (op1->rank == 0 || op2->rank == 0)
    return true;

  va_start (argp, optype_msgid);
  d = vsnprintf (buffer, sizeof (buffer), optype_msgid, argp);
  va_end (argp);
  if (d < 1 || d >= (int) sizeof (buffer)) /* Reject truncation.  */
    gfc_internal_error ("optype_msgid overflow: %d", d);

  if (op1->rank != op2->rank)
    {
      gfc_error ("Incompatible ranks in %s (%d and %d) at %L", _(buffer),
		 op1->rank, op2->rank, &op1->where);
      return false;
    }

  t = true;

  for (d = 0; d < op1->rank; d++)
    {
      op1_flag = gfc_array_dimen_size(op1, d, &op1_size);
      op2_flag = gfc_array_dimen_size(op2, d, &op2_size);

      if (op1_flag && op2_flag && mpz_cmp (op1_size, op2_size) != 0)
	{
	  gfc_error ("Different shape for %s at %L on dimension %d "
		     "(%d and %d)", _(buffer), &op1->where, d + 1,
		     (int) mpz_get_si (op1_size),
		     (int) mpz_get_si (op2_size));

	  t = false;
	}

      if (op1_flag)
	mpz_clear (op1_size);
      if (op2_flag)
	mpz_clear (op2_size);

      if (!t)
	return false;
    }

  return true;
}


/* Given an assignable expression and an arbitrary expression, make
   sure that the assignment can take place.  Only add a call to the intrinsic
   conversion routines, when allow_convert is set.  When this assign is a
   coarray call, then the convert is done by the coarray routine implicitly and
   adding the intrinsic conversion would do harm in most cases.  */

bool
gfc_check_assign (gfc_expr *lvalue, gfc_expr *rvalue, int conform,
		  bool allow_convert)
{
  gfc_symbol *sym;
  gfc_ref *ref;
  int has_pointer;

  sym = lvalue->symtree->n.sym;

  /* See if this is the component or subcomponent of a pointer and guard
     against assignment to LEN or KIND part-refs.  */
  has_pointer = sym->attr.pointer;
  for (ref = lvalue->ref; ref; ref = ref->next)
    {
      if (!has_pointer && ref->type == REF_COMPONENT
	  && ref->u.c.component->attr.pointer)
        has_pointer = 1;
      else if (ref->type == REF_INQUIRY
	       && (ref->u.i == INQUIRY_LEN || ref->u.i == INQUIRY_KIND))
	{
	  gfc_error ("Assignment to a LEN or KIND part_ref at %L is not "
		     "allowed", &lvalue->where);
	  return false;
	}
    }

  /* 12.5.2.2, Note 12.26: The result variable is very similar to any other
     variable local to a function subprogram.  Its existence begins when
     execution of the function is initiated and ends when execution of the
     function is terminated...
     Therefore, the left hand side is no longer a variable, when it is:  */
  if (sym->attr.flavor == FL_PROCEDURE && sym->attr.proc != PROC_ST_FUNCTION
      && !sym->attr.external)
    {
      bool bad_proc;
      bad_proc = false;

      /* (i) Use associated;  */
      if (sym->attr.use_assoc)
	bad_proc = true;

      /* (ii) The assignment is in the main program; or  */
      if (gfc_current_ns->proc_name
	  && gfc_current_ns->proc_name->attr.is_main_program)
	bad_proc = true;

      /* (iii) A module or internal procedure...  */
      if (gfc_current_ns->proc_name
	  && (gfc_current_ns->proc_name->attr.proc == PROC_INTERNAL
	      || gfc_current_ns->proc_name->attr.proc == PROC_MODULE)
	  && gfc_current_ns->parent
	  && (!(gfc_current_ns->parent->proc_name->attr.function
		|| gfc_current_ns->parent->proc_name->attr.subroutine)
	      || gfc_current_ns->parent->proc_name->attr.is_main_program))
	{
	  /* ... that is not a function...  */
	  if (gfc_current_ns->proc_name
	      && !gfc_current_ns->proc_name->attr.function)
	    bad_proc = true;

	  /* ... or is not an entry and has a different name.  */
	  if (!sym->attr.entry && sym->name != gfc_current_ns->proc_name->name)
	    bad_proc = true;
	}

      /* (iv) Host associated and not the function symbol or the
	      parent result.  This picks up sibling references, which
	      cannot be entries.  */
      if (!sym->attr.entry
	    && sym->ns == gfc_current_ns->parent
	    && sym != gfc_current_ns->proc_name
	    && sym != gfc_current_ns->parent->proc_name->result)
	bad_proc = true;

      if (bad_proc)
	{
	  gfc_error ("%qs at %L is not a VALUE", sym->name, &lvalue->where);
	  return false;
	}
    }
  else
    {
      /* Reject assigning to an external symbol.  For initializers, this
	 was already done before, in resolve_fl_procedure.  */
      if (sym->attr.flavor == FL_PROCEDURE && sym->attr.external
	  && sym->attr.proc != PROC_MODULE && !rvalue->error)
	{
	  gfc_error ("Illegal assignment to external procedure at %L",
		     &lvalue->where);
	  return false;
	}
    }

  if (rvalue->rank != 0 && lvalue->rank != rvalue->rank)
    {
      gfc_error ("Incompatible ranks %d and %d in assignment at %L",
		 lvalue->rank, rvalue->rank, &lvalue->where);
      return false;
    }

  if (lvalue->ts.type == BT_UNKNOWN)
    {
      gfc_error ("Variable type is UNKNOWN in assignment at %L",
		 &lvalue->where);
      return false;
    }

  if (rvalue->expr_type == EXPR_NULL)
    {
      if (has_pointer && (ref == NULL || ref->next == NULL)
	  && lvalue->symtree->n.sym->attr.data)
        return true;
      /* Prevent the following error message for caf-single mode, because there
	 are no teams in single mode and the simplify returns a null then.  */
      else if (!(flag_coarray == GFC_FCOARRAY_SINGLE
		 && rvalue->ts.type == BT_DERIVED
		 && rvalue->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
		 && rvalue->ts.u.derived->intmod_sym_id
		      == ISOFORTRAN_TEAM_TYPE))
	{
	  gfc_error ("NULL appears on right-hand side in assignment at %L",
		     &rvalue->where);
	  return false;
	}
    }

  /* This is possibly a typo: x = f() instead of x => f().  */
  if (warn_surprising
      && rvalue->expr_type == EXPR_FUNCTION && gfc_expr_attr (rvalue).pointer)
    gfc_warning (OPT_Wsurprising,
		 "POINTER-valued function appears on right-hand side of "
		 "assignment at %L", &rvalue->where);

  /* Check size of array assignments.  */
  if (lvalue->rank != 0 && rvalue->rank != 0
      && !gfc_check_conformance (lvalue, rvalue, _("array assignment")))
    return false;

  /* Handle the case of a BOZ literal on the RHS.  */
  if (rvalue->ts.type == BT_BOZ)
    {
      if (lvalue->symtree->n.sym->attr.data)
	{
	  if (lvalue->ts.type == BT_INTEGER
	      && gfc_boz2int (rvalue, lvalue->ts.kind))
	    return true;

	  if (lvalue->ts.type == BT_REAL
	      && gfc_boz2real (rvalue, lvalue->ts.kind))
	    {
	      if (gfc_invalid_boz ("BOZ literal constant near %L cannot "
				   "be assigned to a REAL variable",
				   &rvalue->where))
		return false;
	      return true;
	    }
	}

      if (!lvalue->symtree->n.sym->attr.data
	  && gfc_invalid_boz ("BOZ literal constant at %L is neither a "
			      "data-stmt-constant nor an actual argument to "
			      "INT, REAL, DBLE, or CMPLX intrinsic function",
			      &rvalue->where))
	return false;

      if (lvalue->ts.type == BT_INTEGER
	  && gfc_boz2int (rvalue, lvalue->ts.kind))
	return true;

      if (lvalue->ts.type == BT_REAL
	  && gfc_boz2real (rvalue, lvalue->ts.kind))
	return true;

      gfc_error ("BOZ literal constant near %L cannot be assigned to a "
		 "%qs variable", &rvalue->where, gfc_typename (lvalue));
      return false;
    }

  if (gfc_expr_attr (lvalue).pdt_kind || gfc_expr_attr (lvalue).pdt_len)
    {
      gfc_error ("The assignment to a KIND or LEN component of a "
		 "parameterized type at %L is not allowed",
		 &lvalue->where);
      return false;
    }

  if (gfc_compare_types (&lvalue->ts, &rvalue->ts))
    return true;

  /* Only DATA Statements come here.  */
  if (!conform)
    {
      locus *where;

      /* Numeric can be converted to any other numeric. And Hollerith can be
	 converted to any other type.  */
      if ((gfc_numeric_ts (&lvalue->ts) && gfc_numeric_ts (&rvalue->ts))
	  || rvalue->ts.type == BT_HOLLERITH)
	return true;

      if (flag_dec_char_conversions && (gfc_numeric_ts (&lvalue->ts)
	  || lvalue->ts.type == BT_LOGICAL)
	  && rvalue->ts.type == BT_CHARACTER
	  && rvalue->ts.kind == gfc_default_character_kind)
	return true;

      if (lvalue->ts.type == BT_LOGICAL && rvalue->ts.type == BT_LOGICAL)
	return true;

      where = (GFC_LOCUS_IS_SET (lvalue->where)
	       ? &lvalue->where : &rvalue->where);
      gfc_error ("Incompatible types in DATA statement at %L; attempted "
		 "conversion of %s to %s", where,
		 gfc_typename (rvalue), gfc_typename (lvalue));

      return false;
    }

  /* Assignment is the only case where character variables of different
     kind values can be converted into one another.  */
  if (lvalue->ts.type == BT_CHARACTER && rvalue->ts.type == BT_CHARACTER)
    {
      if (lvalue->ts.kind != rvalue->ts.kind && allow_convert)
	return gfc_convert_chartype (rvalue, &lvalue->ts);
      else
	return true;
    }

  if (!allow_convert)
    return true;

  return gfc_convert_type (rvalue, &lvalue->ts, 1);
}


/* Check that a pointer assignment is OK.  We first check lvalue, and
   we only check rvalue if it's not an assignment to NULL() or a
   NULLIFY statement.  */

bool
gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue,
			  bool suppress_type_test, bool is_init_expr)
{
  symbol_attribute attr, lhs_attr;
  gfc_ref *ref;
  bool is_pure, is_implicit_pure, rank_remap;
  int proc_pointer;
  bool same_rank;

  if (!lvalue->symtree)
    return false;

  lhs_attr = gfc_expr_attr (lvalue);
  if (lvalue->ts.type == BT_UNKNOWN && !lhs_attr.proc_pointer)
    {
      gfc_error ("Pointer assignment target is not a POINTER at %L",
		 &lvalue->where);
      return false;
    }

  if (lhs_attr.flavor == FL_PROCEDURE && lhs_attr.use_assoc
      && !lhs_attr.proc_pointer)
    {
      gfc_error ("%qs in the pointer assignment at %L cannot be an "
		 "l-value since it is a procedure",
		 lvalue->symtree->n.sym->name, &lvalue->where);
      return false;
    }

  proc_pointer = lvalue->symtree->n.sym->attr.proc_pointer;

  rank_remap = false;
  same_rank = lvalue->rank == rvalue->rank;
  for (ref = lvalue->ref; ref; ref = ref->next)
    {
      if (ref->type == REF_COMPONENT)
	proc_pointer = ref->u.c.component->attr.proc_pointer;

      if (ref->type == REF_ARRAY && ref->next == NULL)
	{
	  int dim;

	  if (ref->u.ar.type == AR_FULL)
	    break;

	  if (ref->u.ar.type != AR_SECTION)
	    {
	      gfc_error ("Expected bounds specification for %qs at %L",
			 lvalue->symtree->n.sym->name, &lvalue->where);
	      return false;
	    }

	  if (!gfc_notify_std (GFC_STD_F2003, "Bounds specification "
			       "for %qs in pointer assignment at %L",
			       lvalue->symtree->n.sym->name, &lvalue->where))
	    return false;

	  /* Fortran standard (e.g. F2018, 10.2.2 Pointer assignment):
	   *
	   * (C1017) If bounds-spec-list is specified, the number of
	   * bounds-specs shall equal the rank of data-pointer-object.
	   *
	   * If bounds-spec-list appears, it specifies the lower bounds.
	   *
	   * (C1018) If bounds-remapping-list is specified, the number of
	   * bounds-remappings shall equal the rank of data-pointer-object.
	   *
	   * If bounds-remapping-list appears, it specifies the upper and
	   * lower bounds of each dimension of the pointer; the pointer target
	   * shall be simply contiguous or of rank one.
	   *
	   * (C1019) If bounds-remapping-list is not specified, the ranks of
	   * data-pointer-object and data-target shall be the same.
	   *
	   * Thus when bounds are given, all lbounds are necessary and either
	   * all or none of the upper bounds; no strides are allowed.  If the
	   * upper bounds are present, we may do rank remapping.  */
	  for (dim = 0; dim < ref->u.ar.dimen; ++dim)
	    {
	      if (ref->u.ar.stride[dim])
		{
		  gfc_error ("Stride must not be present at %L",
			     &lvalue->where);
		  return false;
		}
	      if (!same_rank && (!ref->u.ar.start[dim] ||!ref->u.ar.end[dim]))
		{
		  gfc_error ("Rank remapping requires a "
			     "list of %<lower-bound : upper-bound%> "
			     "specifications at %L", &lvalue->where);
		  return false;
		}
	      if (!ref->u.ar.start[dim]
		  || ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
		{
		  gfc_error ("Expected list of %<lower-bound :%> or "
			     "list of %<lower-bound : upper-bound%> "
			     "specifications at %L", &lvalue->where);
		  return false;
		}

	      if (dim == 0)
		rank_remap = (ref->u.ar.end[dim] != NULL);
	      else
		{
		  if ((rank_remap && !ref->u.ar.end[dim]))
		    {
		      gfc_error ("Rank remapping requires a "
				 "list of %<lower-bound : upper-bound%> "
				 "specifications at %L", &lvalue->where);
		      return false;
		    }
		  if (!rank_remap && ref->u.ar.end[dim])
		    {
		      gfc_error ("Expected list of %<lower-bound :%> or "
				 "list of %<lower-bound : upper-bound%> "
				 "specifications at %L", &lvalue->where);
		      return false;
		    }
		}
	    }
	}
    }

  is_pure = gfc_pure (NULL);
  is_implicit_pure = gfc_implicit_pure (NULL);

  /* If rvalue is a NULL() or NULLIFY, we're done. Otherwise the type,
     kind, etc for lvalue and rvalue must match, and rvalue must be a
     pure variable if we're in a pure function.  */
  if (rvalue->expr_type == EXPR_NULL && rvalue->ts.type == BT_UNKNOWN)
    return true;

  /* F2008, C723 (pointer) and C726 (proc-pointer); for PURE also C1283.  */
  if (lvalue->expr_type == EXPR_VARIABLE
      && gfc_is_coindexed (lvalue))
    {
      gfc_ref *ref;
      for (ref = lvalue->ref; ref; ref = ref->next)
	if (ref->type == REF_ARRAY && ref->u.ar.codimen)
	  {
	    gfc_error ("Pointer object at %L shall not have a coindex",
		       &lvalue->where);
	    return false;
	  }
    }

  /* Checks on rvalue for procedure pointer assignments.  */
  if (proc_pointer)
    {
      char err[200];
      gfc_symbol *s1,*s2;
      gfc_component *comp1, *comp2;
      const char *name;

      attr = gfc_expr_attr (rvalue);
      if (!((rvalue->expr_type == EXPR_NULL)
	    || (rvalue->expr_type == EXPR_FUNCTION && attr.proc_pointer)
	    || (rvalue->expr_type == EXPR_VARIABLE && attr.proc_pointer)
	    || (rvalue->expr_type == EXPR_VARIABLE
		&& attr.flavor == FL_PROCEDURE)))
	{
	  gfc_error ("Invalid procedure pointer assignment at %L",
		     &rvalue->where);
	  return false;
	}

      if (rvalue->expr_type == EXPR_VARIABLE && !attr.proc_pointer)
	{
      	  /* Check for intrinsics.  */
	  gfc_symbol *sym = rvalue->symtree->n.sym;
	  if (!sym->attr.intrinsic
	      && (gfc_is_intrinsic (sym, 0, sym->declared_at)
		  || gfc_is_intrinsic (sym, 1, sym->declared_at)))
	    {
	      sym->attr.intrinsic = 1;
	      gfc_resolve_intrinsic (sym, &rvalue->where);
	      attr = gfc_expr_attr (rvalue);
	    }
	  /* Check for result of embracing function.  */
	  if (sym->attr.function && sym->result == sym)
	    {
	      gfc_namespace *ns;

	      for (ns = gfc_current_ns; ns; ns = ns->parent)
		if (sym == ns->proc_name)
		  {
		    gfc_error ("Function result %qs is invalid as proc-target "
			       "in procedure pointer assignment at %L",
			       sym->name, &rvalue->where);
		    return false;
		  }
	    }
	}
      if (attr.abstract)
	{
	  gfc_error ("Abstract interface %qs is invalid "
		     "in procedure pointer assignment at %L",
		     rvalue->symtree->name, &rvalue->where);
	  return false;
	}
      /* Check for F08:C729.  */
      if (attr.flavor == FL_PROCEDURE)
	{
	  if (attr.proc == PROC_ST_FUNCTION)
	    {
	      gfc_error ("Statement function %qs is invalid "
			 "in procedure pointer assignment at %L",
			 rvalue->symtree->name, &rvalue->where);
	      return false;
	    }
	  if (attr.proc == PROC_INTERNAL &&
	      !gfc_notify_std(GFC_STD_F2008, "Internal procedure %qs "
			      "is invalid in procedure pointer assignment "
			      "at %L", rvalue->symtree->name, &rvalue->where))
	    return false;
	  if (attr.intrinsic && gfc_intrinsic_actual_ok (rvalue->symtree->name,
							 attr.subroutine) == 0)
	    {
	      gfc_error ("Intrinsic %qs at %L is invalid in procedure pointer "
			 "assignment", rvalue->symtree->name, &rvalue->where);
	      return false;
	    }
	}
      /* Check for F08:C730.  */
      if (attr.elemental && !attr.intrinsic)
	{
	  gfc_error ("Nonintrinsic elemental procedure %qs is invalid "
		     "in procedure pointer assignment at %L",
		     rvalue->symtree->name, &rvalue->where);
	  return false;
	}

      /* Ensure that the calling convention is the same. As other attributes
	 such as DLLEXPORT may differ, one explicitly only tests for the
	 calling conventions.  */
      if (rvalue->expr_type == EXPR_VARIABLE
	  && lvalue->symtree->n.sym->attr.ext_attr
	       != rvalue->symtree->n.sym->attr.ext_attr)
	{
	  symbol_attribute calls;

	  calls.ext_attr = 0;
	  gfc_add_ext_attribute (&calls, EXT_ATTR_CDECL, NULL);
	  gfc_add_ext_attribute (&calls, EXT_ATTR_STDCALL, NULL);
	  gfc_add_ext_attribute (&calls, EXT_ATTR_FASTCALL, NULL);

	  if ((calls.ext_attr & lvalue->symtree->n.sym->attr.ext_attr)
	      != (calls.ext_attr & rvalue->symtree->n.sym->attr.ext_attr))
	    {
	      gfc_error ("Mismatch in the procedure pointer assignment "
			 "at %L: mismatch in the calling convention",
			 &rvalue->where);
	  return false;
	    }
	}

      comp1 = gfc_get_proc_ptr_comp (lvalue);
      if (comp1)
	s1 = comp1->ts.interface;
      else
	{
	  s1 = lvalue->symtree->n.sym;
	  if (s1->ts.interface)
	    s1 = s1->ts.interface;
	}

      comp2 = gfc_get_proc_ptr_comp (rvalue);
      if (comp2)
	{
	  if (rvalue->expr_type == EXPR_FUNCTION)
	    {
	      s2 = comp2->ts.interface->result;
	      name = s2->name;
	    }
	  else
	    {
	      s2 = comp2->ts.interface;
	      name = comp2->name;
	    }
	}
      else if (rvalue->expr_type == EXPR_FUNCTION)
	{
	  if (rvalue->value.function.esym)
	    s2 = rvalue->value.function.esym->result;
	  else
	    s2 = rvalue->symtree->n.sym->result;

	  name = s2->name;
	}
      else
	{
	  s2 = rvalue->symtree->n.sym;
	  name = s2->name;
	}

      if (s2 && s2->attr.proc_pointer && s2->ts.interface)
	s2 = s2->ts.interface;

      /* Special check for the case of absent interface on the lvalue.
       * All other interface checks are done below. */
      if (!s1 && comp1 && comp1->attr.subroutine && s2 && s2->attr.function)
	{
	  gfc_error ("Interface mismatch in procedure pointer assignment "
		     "at %L: %qs is not a subroutine", &rvalue->where, name);
	  return false;
	}

      /* F08:7.2.2.4 (4)  */
      if (s2 && gfc_explicit_interface_required (s2, err, sizeof(err)))
	{
	  if (comp1 && !s1)
	    {
	      gfc_error ("Explicit interface required for component %qs at %L: %s",
			 comp1->name, &lvalue->where, err);
	      return false;
	    }
	  else if (s1->attr.if_source == IFSRC_UNKNOWN)
	    {
	      gfc_error ("Explicit interface required for %qs at %L: %s",
			 s1->name, &lvalue->where, err);
	      return false;
	    }
	}
      if (s1 && gfc_explicit_interface_required (s1, err, sizeof(err)))
	{
	  if (comp2 && !s2)
	    {
	      gfc_error ("Explicit interface required for component %qs at %L: %s",
			 comp2->name, &rvalue->where, err);
	      return false;
	    }
	  else if (s2->attr.if_source == IFSRC_UNKNOWN)
	    {
	      gfc_error ("Explicit interface required for %qs at %L: %s",
			 s2->name, &rvalue->where, err);
	      return false;
	    }
	}

      if (s1 == s2 || !s1 || !s2)
	return true;

      if (!gfc_compare_interfaces (s1, s2, name, 0, 1,
				   err, sizeof(err), NULL, NULL))
	{
	  gfc_error ("Interface mismatch in procedure pointer assignment "
		     "at %L: %s", &rvalue->where, err);
	  return false;
	}

      /* Check F2008Cor2, C729.  */
      if (!s2->attr.intrinsic && s2->attr.if_source == IFSRC_UNKNOWN
	  && !s2->attr.external && !s2->attr.subroutine && !s2->attr.function)
	{
	  gfc_error ("Procedure pointer target %qs at %L must be either an "
		     "intrinsic, host or use associated, referenced or have "
		     "the EXTERNAL attribute", s2->name, &rvalue->where);
	  return false;
	}

      return true;
    }
  else
    {
      /* A non-proc pointer cannot point to a constant.  */
      if (rvalue->expr_type == EXPR_CONSTANT)
	{
	  gfc_error_now ("Pointer assignment target cannot be a constant at %L",
			 &rvalue->where);
	  return false;
	}
    }

  if (!gfc_compare_types (&lvalue->ts, &rvalue->ts))
    {
      /* Check for F03:C717.  */
      if (UNLIMITED_POLY (rvalue)
	  && !(UNLIMITED_POLY (lvalue)
	       || (lvalue->ts.type == BT_DERIVED
		   && (lvalue->ts.u.derived->attr.is_bind_c
		       || lvalue->ts.u.derived->attr.sequence))))
	gfc_error ("Data-pointer-object at %L must be unlimited "
		   "polymorphic, or of a type with the BIND or SEQUENCE "
		   "attribute, to be compatible with an unlimited "
		   "polymorphic target", &lvalue->where);
      else if (!suppress_type_test)
	gfc_error ("Different types in pointer assignment at %L; "
		   "attempted assignment of %s to %s", &lvalue->where,
		   gfc_typename (rvalue), gfc_typename (lvalue));
      return false;
    }

  if (lvalue->ts.type != BT_CLASS && lvalue->ts.kind != rvalue->ts.kind)
    {
      gfc_error ("Different kind type parameters in pointer "
		 "assignment at %L", &lvalue->where);
      return false;
    }

  if (lvalue->rank != rvalue->rank && !rank_remap)
    {
      gfc_error ("Different ranks in pointer assignment at %L", &lvalue->where);
      return false;
    }

  /* Make sure the vtab is present.  */
  if (lvalue->ts.type == BT_CLASS && !UNLIMITED_POLY (rvalue))
    gfc_find_vtab (&rvalue->ts);

  /* Check rank remapping.  */
  if (rank_remap)
    {
      mpz_t lsize, rsize;

      /* If this can be determined, check that the target must be at least as
	 large as the pointer assigned to it is.  */
      bool got_lsize = gfc_array_size (lvalue, &lsize);
      bool got_rsize = got_lsize && gfc_array_size (rvalue, &rsize);
      bool too_small = got_rsize && mpz_cmp (rsize, lsize) < 0;

      if (too_small)
	{
	  gfc_error ("Rank remapping target is smaller than size of the"
		     " pointer (%ld < %ld) at %L",
		     mpz_get_si (rsize), mpz_get_si (lsize),
		     &lvalue->where);
	  mpz_clear (lsize);
	  mpz_clear (rsize);
	  return false;
	}
      if (got_lsize)
	mpz_clear (lsize);
      if (got_rsize)
	mpz_clear (rsize);

      /* An assumed rank target is an experimental F202y feature.  */
      if (rvalue->rank == -1 && !(gfc_option.allow_std & GFC_STD_F202Y))
	{
	  gfc_error ("The assumed rank target at %L is an experimental F202y "
		     "feature. Use option -std=f202y to enable",
		     &rvalue->where);
	  return false;
	}

      /* The target must be either rank one or it must be simply contiguous
	 and F2008 must be allowed.  */
      if (rvalue->rank != 1 && rvalue->rank != -1)
	{
	  if (!gfc_is_simply_contiguous (rvalue, true, false))
	    {
	      gfc_error ("Rank remapping target must be rank 1 or"
			 " simply contiguous at %L", &rvalue->where);
	      return false;
	    }
	  if (!gfc_notify_std (GFC_STD_F2008, "Rank remapping target is not "
			       "rank 1 at %L", &rvalue->where))
	    return false;
	}
    }
  else if (rvalue->rank == -1)
    {
      gfc_error ("The data-target at %L is an assumed rank object and so the "
		 "data-pointer-object %s must have a bounds remapping list "
		 "(list of lbound:ubound for each dimension)",
		  &rvalue->where, lvalue->symtree->name);
      return false;
    }

  if (rvalue->rank == -1 && !gfc_is_simply_contiguous (rvalue, true, false))
    {
      gfc_error ("The assumed rank data-target at %L must be contiguous",
		 &rvalue->where);
      return false;
    }

  /* Now punt if we are dealing with a NULLIFY(X) or X = NULL(X).  */
  if (rvalue->expr_type == EXPR_NULL)
    return true;

  if (rvalue->expr_type == EXPR_VARIABLE && is_subref_array (rvalue))
    lvalue->symtree->n.sym->attr.subref_array_pointer = 1;

  attr = gfc_expr_attr (rvalue);

  if (rvalue->expr_type == EXPR_FUNCTION && !attr.pointer)
    {
      /* F2008, C725.  For PURE also C1283.  Sometimes rvalue is a function call
	 to caf_get.  Map this to the same error message as below when it is
	 still a variable expression.  */
      if (rvalue->value.function.isym
	  && rvalue->value.function.isym->id == GFC_ISYM_CAF_GET)
	/* The test above might need to be extend when F08, Note 5.4 has to be
	   interpreted in the way that target and pointer with the same coindex
	   are allowed.  */
	gfc_error ("Data target at %L shall not have a coindex",
		   &rvalue->where);
      else
	gfc_error ("Target expression in pointer assignment "
		   "at %L must deliver a pointer result",
		   &rvalue->where);
      return false;
    }

  if (is_init_expr)
    {
      gfc_symbol *sym;
      bool target;
      gfc_ref *ref;

      if (gfc_is_size_zero_array (rvalue))
	{
	  gfc_error ("Zero-sized array detected at %L where an entity with "
		     "the TARGET attribute is expected", &rvalue->where);
	  return false;
	}
      else if (!rvalue->symtree)
	{
	  gfc_error ("Pointer assignment target in initialization expression "
		     "does not have the TARGET attribute at %L",
		     &rvalue->where);
	  return false;
	}

      sym = rvalue->symtree->n.sym;

      if (sym->ts.type == BT_CLASS && sym->attr.class_ok)
	target = CLASS_DATA (sym)->attr.target;
      else
	target = sym->attr.target;

      if (!target && !proc_pointer)
	{
	  gfc_error ("Pointer assignment target in initialization expression "
		     "does not have the TARGET attribute at %L",
		     &rvalue->where);
	  return false;
	}

      for (ref = rvalue->ref; ref; ref = ref->next)
	{
	  switch (ref->type)
	    {
	    case REF_ARRAY:
	      for (int n = 0; n < ref->u.ar.dimen; n++)
		if (!gfc_is_constant_expr (ref->u.ar.start[n])
		    || !gfc_is_constant_expr (ref->u.ar.end[n])
		    || !gfc_is_constant_expr (ref->u.ar.stride[n]))
		  {
		    gfc_error ("Every subscript of target specification "
			       "at %L must be a constant expression",
			       &ref->u.ar.where);
		    return false;
		  }
	      break;

	    case REF_SUBSTRING:
	      if (!gfc_is_constant_expr (ref->u.ss.start)
		  || !gfc_is_constant_expr (ref->u.ss.end))
		{
		  gfc_error ("Substring starting and ending points of target "
			     "specification at %L must be constant expressions",
			     &ref->u.ss.start->where);
		  return false;
		}
	      break;

	    default:
	      break;
	    }
	}
    }
  else
    {
      if (!attr.target && !attr.pointer)
	{
	  gfc_error ("Pointer assignment target is neither TARGET "
		     "nor POINTER at %L", &rvalue->where);
	  return false;
	}
    }

  if (lvalue->ts.type == BT_CHARACTER)
    {
      bool t = gfc_check_same_strlen (lvalue, rvalue, "pointer assignment");
      if (!t)
	return false;
    }

  if (is_pure && gfc_impure_variable (rvalue->symtree->n.sym))
    {
      gfc_error ("Bad target in pointer assignment in PURE "
		 "procedure at %L", &rvalue->where);
    }

  if (is_implicit_pure && gfc_impure_variable (rvalue->symtree->n.sym))
    gfc_unset_implicit_pure (gfc_current_ns->proc_name);

  if (gfc_has_vector_index (rvalue))
    {
      gfc_error ("Pointer assignment with vector subscript "
		 "on rhs at %L", &rvalue->where);
      return false;
    }

  if (attr.is_protected && attr.use_assoc
      && !(attr.pointer || attr.proc_pointer))
    {
      gfc_error ("Pointer assignment target has PROTECTED "
		 "attribute at %L", &rvalue->where);
      return false;
    }

  /* F2008, C725. For PURE also C1283.  */
  if (rvalue->expr_type == EXPR_VARIABLE
      && gfc_is_coindexed (rvalue))
    {
      gfc_ref *ref;
      for (ref = rvalue->ref; ref; ref = ref->next)
	if (ref->type == REF_ARRAY && ref->u.ar.codimen)
	  {
	    gfc_error ("Data target at %L shall not have a coindex",
		       &rvalue->where);
	    return false;
	  }
    }

  /* Warn for assignments of contiguous pointers to targets which is not
     contiguous.  Be lenient in the definition of what counts as
     contiguous.  */

  if (lhs_attr.contiguous
      && lhs_attr.dimension > 0)
    {
      if (gfc_is_not_contiguous (rvalue))
	{
	  gfc_error ("Assignment to contiguous pointer from "
		     "non-contiguous target at %L", &rvalue->where);
	  return false;
	}
      if (!gfc_is_simply_contiguous (rvalue, false, true))
	gfc_warning (OPT_Wextra, "Assignment to contiguous pointer from "
				 "non-contiguous target at %L", &rvalue->where);
    }

  /* Warn if it is the LHS pointer may lives longer than the RHS target.  */
  if (warn_target_lifetime
      && rvalue->expr_type == EXPR_VARIABLE
      && !rvalue->symtree->n.sym->attr.save
      && !rvalue->symtree->n.sym->attr.pointer && !attr.pointer
      && !rvalue->symtree->n.sym->attr.host_assoc
      && !rvalue->symtree->n.sym->attr.in_common
      && !rvalue->symtree->n.sym->attr.use_assoc
      && !rvalue->symtree->n.sym->attr.dummy)
    {
      bool warn;
      gfc_namespace *ns;

      warn = lvalue->symtree->n.sym->attr.dummy
	     || lvalue->symtree->n.sym->attr.result
	     || lvalue->symtree->n.sym->attr.function
	     || (lvalue->symtree->n.sym->attr.host_assoc
		 && lvalue->symtree->n.sym->ns
		    != rvalue->symtree->n.sym->ns)
	     || lvalue->symtree->n.sym->attr.use_assoc
	     || lvalue->symtree->n.sym->attr.in_common;

      if (rvalue->symtree->n.sym->ns->proc_name
	  && rvalue->symtree->n.sym->ns->proc_name->attr.flavor != FL_PROCEDURE
	  && rvalue->symtree->n.sym->ns->proc_name->attr.flavor != FL_PROGRAM)
       for (ns = rvalue->symtree->n.sym->ns;
	    ns && ns->proc_name && ns->proc_name->attr.flavor != FL_PROCEDURE;
	    ns = ns->parent)
	if (ns->parent == lvalue->symtree->n.sym->ns)
	  {
	    warn = true;
	    break;
	  }

      if (warn)
	gfc_warning (OPT_Wtarget_lifetime,
		     "Pointer at %L in pointer assignment might outlive the "
		     "pointer target", &lvalue->where);
    }

  return true;
}


/* Relative of gfc_check_assign() except that the lvalue is a single
   symbol.  Used for initialization assignments.  */

bool
gfc_check_assign_symbol (gfc_symbol *sym, gfc_component *comp, gfc_expr *rvalue)
{
  gfc_expr lvalue;
  bool r;
  bool pointer, proc_pointer;

  memset (&lvalue, '\0', sizeof (gfc_expr));

  lvalue.expr_type = EXPR_VARIABLE;
  lvalue.ts = sym->ts;
  if (sym->as)
    {
      lvalue.rank = sym->as->rank;
      lvalue.corank = sym->as->corank;
    }
  lvalue.symtree = XCNEW (gfc_symtree);
  lvalue.symtree->n.sym = sym;
  lvalue.where = sym->declared_at;

  if (comp)
    {
      lvalue.ref = gfc_get_ref ();
      lvalue.ref->type = REF_COMPONENT;
      lvalue.ref->u.c.component = comp;
      lvalue.ref->u.c.sym = sym;
      lvalue.ts = comp->ts;
      lvalue.rank = comp->as ? comp->as->rank : 0;
      lvalue.corank = comp->as ? comp->as->corank : 0;
      lvalue.where = comp->loc;
      pointer = comp->ts.type == BT_CLASS &&  CLASS_DATA (comp)
		? CLASS_DATA (comp)->attr.class_pointer : comp->attr.pointer;
      proc_pointer = comp->attr.proc_pointer;
    }
  else
    {
      pointer = sym->ts.type == BT_CLASS &&  CLASS_DATA (sym)
		? CLASS_DATA (sym)->attr.class_pointer : sym->attr.pointer;
      proc_pointer = sym->attr.proc_pointer;
    }

  if (pointer || proc_pointer)
    r = gfc_check_pointer_assign (&lvalue, rvalue, false, true);
  else
    {
      /* If a conversion function, e.g., __convert_i8_i4, was inserted
	 into an array constructor, we should check if it can be reduced
	 as an initialization expression.  */
      if (rvalue->expr_type == EXPR_FUNCTION
	  && rvalue->value.function.isym
	  && (rvalue->value.function.isym->conversion == 1))
	gfc_check_init_expr (rvalue);

      r = gfc_check_assign (&lvalue, rvalue, 1);
    }

  free (lvalue.symtree);
  free (lvalue.ref);

  if (!r)
    return r;

  if (pointer && rvalue->expr_type != EXPR_NULL && !proc_pointer)
    {
      /* F08:C461. Additional checks for pointer initialization.  */
      symbol_attribute attr;
      attr = gfc_expr_attr (rvalue);
      if (attr.allocatable)
	{
	  gfc_error ("Pointer initialization target at %L "
	             "must not be ALLOCATABLE", &rvalue->where);
	  return false;
	}
      if (!attr.target || attr.pointer)
	{
	  gfc_error ("Pointer initialization target at %L "
		     "must have the TARGET attribute", &rvalue->where);
	  return false;
	}

      if (!attr.save && rvalue->expr_type == EXPR_VARIABLE
	  && rvalue->symtree->n.sym->ns->proc_name
	  && rvalue->symtree->n.sym->ns->proc_name->attr.is_main_program)
	{
	  rvalue->symtree->n.sym->ns->proc_name->attr.save = SAVE_IMPLICIT;
	  attr.save = SAVE_IMPLICIT;
	}

      if (!attr.save)
	{
	  gfc_error ("Pointer initialization target at %L "
		     "must have the SAVE attribute", &rvalue->where);
	  return false;
	}
    }

  if (proc_pointer && rvalue->expr_type != EXPR_NULL)
    {
      /* F08:C1220. Additional checks for procedure pointer initialization.  */
      symbol_attribute attr = gfc_expr_attr (rvalue);
      if (attr.proc_pointer)
	{
	  gfc_error ("Procedure pointer initialization target at %L "
		     "may not be a procedure pointer", &rvalue->where);
	  return false;
	}
      if (attr.proc == PROC_INTERNAL)
	{
	  gfc_error ("Internal procedure %qs is invalid in "
		     "procedure pointer initialization at %L",
		     rvalue->symtree->name, &rvalue->where);
	  return false;
	}
      if (attr.dummy)
	{
	  gfc_error ("Dummy procedure %qs is invalid in "
		     "procedure pointer initialization at %L",
		     rvalue->symtree->name, &rvalue->where);
	  return false;
	}
    }

  return true;
}

/* Build an initializer for a local integer, real, complex, logical, or
   character variable, based on the command line flags finit-local-zero,
   finit-integer=, finit-real=, finit-logical=, and finit-character=.
   With force, an initializer is ALWAYS generated.  */

static gfc_expr *
gfc_build_init_expr (gfc_typespec *ts, locus *where, bool force)
{
  gfc_expr *init_expr;

  /* Try to build an initializer expression.  */
  init_expr = gfc_get_constant_expr (ts->type, ts->kind, where);

  /* If we want to force generation, make sure we default to zero.  */
  gfc_init_local_real init_real = flag_init_real;
  int init_logical = gfc_option.flag_init_logical;
  if (force)
    {
      if (init_real == GFC_INIT_REAL_OFF)
	init_real = GFC_INIT_REAL_ZERO;
      if (init_logical == GFC_INIT_LOGICAL_OFF)
	init_logical = GFC_INIT_LOGICAL_FALSE;
    }

  /* We will only initialize integers, reals, complex, logicals, and
     characters, and only if the corresponding command-line flags
     were set.  Otherwise, we free init_expr and return null.  */
  switch (ts->type)
    {
    case BT_INTEGER:
      if (force || gfc_option.flag_init_integer != GFC_INIT_INTEGER_OFF)
        mpz_set_si (init_expr->value.integer,
                         gfc_option.flag_init_integer_value);
      else
        {
          gfc_free_expr (init_expr);
          init_expr = NULL;
        }
      break;

    case BT_REAL:
      switch (init_real)
        {
        case GFC_INIT_REAL_SNAN:
          init_expr->is_snan = 1;
          /* Fall through.  */
        case GFC_INIT_REAL_NAN:
          mpfr_set_nan (init_expr->value.real);
          break;

        case GFC_INIT_REAL_INF:
          mpfr_set_inf (init_expr->value.real, 1);
          break;

        case GFC_INIT_REAL_NEG_INF:
          mpfr_set_inf (init_expr->value.real, -1);
          break;

        case GFC_INIT_REAL_ZERO:
          mpfr_set_ui (init_expr->value.real, 0.0, GFC_RND_MODE);
          break;

        default:
          gfc_free_expr (init_expr);
          init_expr = NULL;
          break;
        }
      break;

    case BT_COMPLEX:
      switch (init_real)
        {
        case GFC_INIT_REAL_SNAN:
          init_expr->is_snan = 1;
          /* Fall through.  */
        case GFC_INIT_REAL_NAN:
          mpfr_set_nan (mpc_realref (init_expr->value.complex));
          mpfr_set_nan (mpc_imagref (init_expr->value.complex));
          break;

        case GFC_INIT_REAL_INF:
          mpfr_set_inf (mpc_realref (init_expr->value.complex), 1);
          mpfr_set_inf (mpc_imagref (init_expr->value.complex), 1);
          break;

        case GFC_INIT_REAL_NEG_INF:
          mpfr_set_inf (mpc_realref (init_expr->value.complex), -1);
          mpfr_set_inf (mpc_imagref (init_expr->value.complex), -1);
          break;

        case GFC_INIT_REAL_ZERO:
          mpc_set_ui (init_expr->value.complex, 0, GFC_MPC_RND_MODE);
          break;

        default:
          gfc_free_expr (init_expr);
          init_expr = NULL;
          break;
        }
      break;

    case BT_LOGICAL:
      if (init_logical == GFC_INIT_LOGICAL_FALSE)
        init_expr->value.logical = 0;
      else if (init_logical == GFC_INIT_LOGICAL_TRUE)
        init_expr->value.logical = 1;
      else
        {
          gfc_free_expr (init_expr);
          init_expr = NULL;
        }
      break;

    case BT_CHARACTER:
      /* For characters, the length must be constant in order to
         create a default initializer.  */
      if ((force || gfc_option.flag_init_character == GFC_INIT_CHARACTER_ON)
          && ts->u.cl->length
          && ts->u.cl->length->expr_type == EXPR_CONSTANT)
        {
          HOST_WIDE_INT char_len = gfc_mpz_get_hwi (ts->u.cl->length->value.integer);
          init_expr->value.character.length = char_len;
          init_expr->value.character.string = gfc_get_wide_string (char_len+1);
          for (size_t i = 0; i < (size_t) char_len; i++)
            init_expr->value.character.string[i]
              = (unsigned char) gfc_option.flag_init_character_value;
        }
      else
        {
          gfc_free_expr (init_expr);
          init_expr = NULL;
        }
      if (!init_expr
	  && (force || gfc_option.flag_init_character == GFC_INIT_CHARACTER_ON)
          && ts->u.cl->length && flag_max_stack_var_size != 0)
        {
          gfc_actual_arglist *arg;
          init_expr = gfc_get_expr ();
          init_expr->where = *where;
          init_expr->ts = *ts;
          init_expr->expr_type = EXPR_FUNCTION;
          init_expr->value.function.isym =
                gfc_intrinsic_function_by_id (GFC_ISYM_REPEAT);
          init_expr->value.function.name = "repeat";
          arg = gfc_get_actual_arglist ();
          arg->expr = gfc_get_character_expr (ts->kind, where, NULL, 1);
          arg->expr->value.character.string[0] =
            gfc_option.flag_init_character_value;
          arg->next = gfc_get_actual_arglist ();
          arg->next->expr = gfc_copy_expr (ts->u.cl->length);
          init_expr->value.function.actual = arg;
        }
      break;

    default:
     gfc_free_expr (init_expr);
     init_expr = NULL;
    }

  return init_expr;
}

/* Invoke gfc_build_init_expr to create an initializer expression, but do not
 * require that an expression be built.  */

gfc_expr *
gfc_build_default_init_expr (gfc_typespec *ts, locus *where)
{
  return gfc_build_init_expr (ts, where, false);
}

/* Apply an initialization expression to a typespec. Can be used for symbols or
   components. Similar to add_init_expr_to_sym in decl.cc; could probably be
   combined with some effort.  */

void
gfc_apply_init (gfc_typespec *ts, symbol_attribute *attr, gfc_expr *init)
{
  if (ts->type == BT_CHARACTER && !attr->pointer && init
      && ts->u.cl
      && ts->u.cl->length
      && ts->u.cl->length->expr_type == EXPR_CONSTANT
      && ts->u.cl->length->ts.type == BT_INTEGER)
    {
      HOST_WIDE_INT len = gfc_mpz_get_hwi (ts->u.cl->length->value.integer);

      if (init->expr_type == EXPR_CONSTANT)
        gfc_set_constant_character_len (len, init, -1);
      else if (init
	       && init->ts.type == BT_CHARACTER
               && init->ts.u.cl && init->ts.u.cl->length
               && mpz_cmp (ts->u.cl->length->value.integer,
                           init->ts.u.cl->length->value.integer))
        {
          gfc_constructor *ctor;
          ctor = gfc_constructor_first (init->value.constructor);

          if (ctor)
            {
              bool has_ts = (init->ts.u.cl
                             && init->ts.u.cl->length_from_typespec);

              /* Remember the length of the first element for checking
                 that all elements *in the constructor* have the same
                 length.  This need not be the length of the LHS!  */
              gcc_assert (ctor->expr->expr_type == EXPR_CONSTANT);
              gcc_assert (ctor->expr->ts.type == BT_CHARACTER);
              gfc_charlen_t first_len = ctor->expr->value.character.length;

              for ( ; ctor; ctor = gfc_constructor_next (ctor))
                if (ctor->expr->expr_type == EXPR_CONSTANT)
                {
                  gfc_set_constant_character_len (len, ctor->expr,
                                                  has_ts ? -1 : first_len);
		  if (!ctor->expr->ts.u.cl)
		    ctor->expr->ts.u.cl
		      = gfc_new_charlen (gfc_current_ns, ts->u.cl);
		  else
                    ctor->expr->ts.u.cl->length
		      = gfc_copy_expr (ts->u.cl->length);
                }
            }
        }
    }
}


/* Check whether an expression is a structure constructor and whether it has
   other values than NULL.  */

static bool
is_non_empty_structure_constructor (gfc_expr * e)
{
  if (e->expr_type != EXPR_STRUCTURE)
    return false;

  gfc_constructor *cons = gfc_constructor_first (e->value.constructor);
  while (cons)
    {
      if (!cons->expr || cons->expr->expr_type != EXPR_NULL)
	return true;
      cons = gfc_constructor_next (cons);
    }
  return false;
}


/* Check for default initializer; sym->value is not enough
   as it is also set for EXPR_NULL of allocatables.  */

bool
gfc_has_default_initializer (gfc_symbol *der)
{
  static hash_set<gfc_symbol *> seen_derived_types;
  gfc_component *c;
  /* The rewrite to a result variable and breaks is only needed, because
     there is no scope_guard in C++ yet.  */
  bool result = false;

  gcc_assert (gfc_fl_struct (der->attr.flavor));
  seen_derived_types.add (der);
  for (c = der->components; c; c = c->next)
    if (gfc_bt_struct (c->ts.type)
	&& !seen_derived_types.contains (c->ts.u.derived))
      {
	if (!c->attr.pointer && !c->attr.proc_pointer
	    && !(c->attr.allocatable && der == c->ts.u.derived)
	    && ((c->initializer
		 && is_non_empty_structure_constructor (c->initializer))
		|| gfc_has_default_initializer (c->ts.u.derived)))
	  {
	    result = true;
	    break;
	  }
	if (c->attr.pointer && c->initializer)
	  {
	    result = true;
	    break;
	  }
      }
    else
      {
	if (c->initializer)
	  {
	    result = true;
	    break;
	  }
      }

  seen_derived_types.remove (der);
  return result;
}


/*
   Generate an initializer expression which initializes the entirety of a union.
   A normal structure constructor is insufficient without undue effort, because
   components of maps may be oddly aligned/overlapped. (For example if a
   character is initialized from one map overtop a real from the other, only one
   byte of the real is actually initialized.)  Unfortunately we don't know the
   size of the union right now, so we can't generate a proper initializer, but
   we use a NULL expr as a placeholder and do the right thing later in
   gfc_trans_subcomponent_assign.
 */
static gfc_expr *
generate_union_initializer (gfc_component *un)
{
  if (un == NULL || un->ts.type != BT_UNION)
    return NULL;

  gfc_expr *placeholder = gfc_get_null_expr (&un->loc);
  placeholder->ts = un->ts;
  return placeholder;
}


/* Get the user-specified initializer for a union, if any. This means the user
   has said to initialize component(s) of a map.  For simplicity's sake we
   only allow the user to initialize the first map.  We don't have to worry
   about overlapping initializers as they are released early in resolution (see
   resolve_fl_struct).   */

static gfc_expr *
get_union_initializer (gfc_symbol *union_type, gfc_component **map_p)
{
  gfc_component *map;
  gfc_expr *init=NULL;

  if (!union_type || union_type->attr.flavor != FL_UNION)
    return NULL;

  for (map = union_type->components; map; map = map->next)
    {
      if (gfc_has_default_initializer (map->ts.u.derived))
        {
          init = gfc_default_initializer (&map->ts);
          if (map_p)
            *map_p = map;
          break;
        }
    }

  if (map_p && !init)
    *map_p = NULL;

  return init;
}

static bool
class_allocatable (gfc_component *comp)
{
  return comp->ts.type == BT_CLASS && comp->attr.class_ok && CLASS_DATA (comp)
    && CLASS_DATA (comp)->attr.allocatable;
}

static bool
class_pointer (gfc_component *comp)
{
  return comp->ts.type == BT_CLASS && comp->attr.class_ok && CLASS_DATA (comp)
    && CLASS_DATA (comp)->attr.pointer;
}

static bool
comp_allocatable (gfc_component *comp)
{
  return comp->attr.allocatable || class_allocatable (comp);
}

static bool
comp_pointer (gfc_component *comp)
{
  return comp->attr.pointer
    || comp->attr.proc_pointer
    || comp->attr.class_pointer
    || class_pointer (comp);
}

/* Fetch or generate an initializer for the given component.
   Only generate an initializer if generate is true.  */

static gfc_expr *
component_initializer (gfc_component *c, bool generate)
{
  gfc_expr *init = NULL;

  /* Allocatable components always get EXPR_NULL.
     Pointer components are only initialized when generating, and only if they
     do not already have an initializer.  */
  if (comp_allocatable (c) || (generate && comp_pointer (c) && !c->initializer))
    {
      init = gfc_get_null_expr (&c->loc);
      init->ts = c->ts;
      return init;
    }

  /* See if we can find the initializer immediately.  */
  if (c->initializer || !generate)
    return c->initializer;

  /* Recursively handle derived type components.  */
  else if (c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
    init = gfc_generate_initializer (&c->ts, true);

  else if (c->ts.type == BT_UNION && c->ts.u.derived->components)
    {
      gfc_component *map = NULL;
      gfc_constructor *ctor;
      gfc_expr *user_init;

      /* If we don't have a user initializer and we aren't generating one, this
         union has no initializer.  */
      user_init = get_union_initializer (c->ts.u.derived, &map);
      if (!user_init && !generate)
        return NULL;

      /* Otherwise use a structure constructor.  */
      init = gfc_get_structure_constructor_expr (c->ts.type, c->ts.kind,
                                                 &c->loc);
      init->ts = c->ts;

      /* If we are to generate an initializer for the union, add a constructor
         which initializes the whole union first.  */
      if (generate)
        {
          ctor = gfc_constructor_get ();
          ctor->expr = generate_union_initializer (c);
          gfc_constructor_append (&init->value.constructor, ctor);
        }

      /* If we found an initializer in one of our maps, apply it.  Note this
         is applied _after_ the entire-union initializer above if any.  */
      if (user_init)
        {
          ctor = gfc_constructor_get ();
          ctor->expr = user_init;
          ctor->n.component = map;
          gfc_constructor_append (&init->value.constructor, ctor);
        }
    }

  /* Treat simple components like locals.  */
  else
    {
      /* We MUST give an initializer, so force generation.  */
      init = gfc_build_init_expr (&c->ts, &c->loc, true);
      gfc_apply_init (&c->ts, &c->attr, init);
    }

  return init;
}


/* Get an expression for a default initializer of a derived type.  */

gfc_expr *
gfc_default_initializer (gfc_typespec *ts)
{
  return gfc_generate_initializer (ts, false);
}

/* Generate an initializer expression for an iso_c_binding type
   such as c_[fun]ptr. The appropriate initializer is c_null_[fun]ptr.  */

static gfc_expr *
generate_isocbinding_initializer (gfc_symbol *derived)
{
  /* The initializers have already been built into the c_null_[fun]ptr symbols
     from gen_special_c_interop_ptr.  */
  gfc_symtree *npsym = NULL;
  if (0 == strcmp (derived->name, "c_ptr"))
    gfc_find_sym_tree ("c_null_ptr", gfc_current_ns, true, &npsym);
  else if (0 == strcmp (derived->name, "c_funptr"))
    gfc_find_sym_tree ("c_null_funptr", gfc_current_ns, true, &npsym);
  else
    gfc_internal_error ("generate_isocbinding_initializer(): bad iso_c_binding"
			" type, expected %<c_ptr%> or %<c_funptr%>");
  if (npsym)
    {
      gfc_expr *init = gfc_copy_expr (npsym->n.sym->value);
      init->symtree = npsym;
      init->ts.is_iso_c = true;
      return init;
    }

  return NULL;
}

/* Get or generate an expression for a default initializer of a derived type.
   If -finit-derived is specified, generate default initialization expressions
   for components that lack them when generate is set.  */

gfc_expr *
gfc_generate_initializer (gfc_typespec *ts, bool generate)
{
  gfc_expr *init, *tmp;
  gfc_component *comp;

  generate = flag_init_derived && generate;

  if (ts->u.derived->ts.is_iso_c && generate)
    return generate_isocbinding_initializer (ts->u.derived);

  /* See if we have a default initializer in this, but not in nested
     types (otherwise we could use gfc_has_default_initializer()).
     We don't need to check if we are going to generate them.  */
  comp = ts->u.derived->components;
  if (!generate)
    {
      for (; comp; comp = comp->next)
	if (comp->initializer || comp_allocatable (comp))
          break;
    }

  if (!comp)
    return NULL;

  init = gfc_get_structure_constructor_expr (ts->type, ts->kind,
					     &ts->u.derived->declared_at);
  init->ts = *ts;

  for (comp = ts->u.derived->components; comp; comp = comp->next)
    {
      gfc_constructor *ctor = gfc_constructor_get();

      /* Fetch or generate an initializer for the component.  */
      tmp = component_initializer (comp, generate);
      if (tmp)
	{
	  /* Save the component ref for STRUCTUREs and UNIONs.  */
	  if (ts->u.derived->attr.flavor == FL_STRUCT
	      || ts->u.derived->attr.flavor == FL_UNION)
	    ctor->n.component = comp;

          /* If the initializer was not generated, we need a copy.  */
          ctor->expr = comp->initializer ? gfc_copy_expr (tmp) : tmp;
	  if ((comp->ts.type != tmp->ts.type || comp->ts.kind != tmp->ts.kind)
	      && !comp->attr.pointer && !comp->attr.proc_pointer)
	    {
	      bool val;
	      val = gfc_convert_type_warn (ctor->expr, &comp->ts, 1, false);
	      if (val == false)
		return NULL;
	    }
	}

      gfc_constructor_append (&init->value.constructor, ctor);
    }

  return init;
}


/* Given a symbol, create an expression node with that symbol as a
   variable. If the symbol is array valued, setup a reference of the
   whole array.  */

gfc_expr *
gfc_get_variable_expr (gfc_symtree *var)
{
  gfc_expr *e;

  e = gfc_get_expr ();
  e->expr_type = EXPR_VARIABLE;
  e->symtree = var;
  e->ts = var->n.sym->ts;

  if (var->n.sym->attr.flavor != FL_PROCEDURE
      && ((var->n.sym->as != NULL && var->n.sym->ts.type != BT_CLASS)
	   || (var->n.sym->ts.type == BT_CLASS && var->n.sym->ts.u.derived
	       && CLASS_DATA (var->n.sym)
	       && CLASS_DATA (var->n.sym)->as)))
    {
      gfc_array_spec *as = var->n.sym->ts.type == BT_CLASS
			     ? CLASS_DATA (var->n.sym)->as
			     : var->n.sym->as;
      e->rank = as->rank;
      e->corank = as->corank;
      e->ref = gfc_get_ref ();
      e->ref->type = REF_ARRAY;
      e->ref->u.ar.type = AR_FULL;
      e->ref->u.ar.as = gfc_copy_array_spec (as);
    }

  return e;
}


/* Adds a full array reference to an expression, as needed.  */

void
gfc_add_full_array_ref (gfc_expr *e, gfc_array_spec *as)
{
  gfc_ref *ref;
  for (ref = e->ref; ref; ref = ref->next)
    if (!ref->next)
      break;
  if (ref)
    {
      ref->next = gfc_get_ref ();
      ref = ref->next;
    }
  else
    {
      e->ref = gfc_get_ref ();
      ref = e->ref;
    }
  ref->type = REF_ARRAY;
  ref->u.ar.type = AR_FULL;
  ref->u.ar.dimen = e->rank;
  /* Do not set the corank here, or resolve will not be able to set correct
     dimen-types for the coarray.  */
  ref->u.ar.where = e->where;
  ref->u.ar.as = as;
}


gfc_expr *
gfc_lval_expr_from_sym (gfc_symbol *sym)
{
  gfc_expr *lval;
  gfc_array_spec *as;
  lval = gfc_get_expr ();
  lval->expr_type = EXPR_VARIABLE;
  lval->where = sym->declared_at;
  lval->ts = sym->ts;
  lval->symtree = gfc_find_symtree (sym->ns->sym_root, sym->name);

  /* It will always be a full array.  */
  as = IS_CLASS_ARRAY (sym) ? CLASS_DATA (sym)->as : sym->as;
  lval->rank = as ? as->rank : 0;
  lval->corank = as ? as->corank : 0;
  if (lval->rank || lval->corank)
    gfc_add_full_array_ref (lval, as);
  return lval;
}


/* Returns the array_spec of a full array expression.  A NULL is
   returned otherwise.  */
gfc_array_spec *
gfc_get_full_arrayspec_from_expr (gfc_expr *expr)
{
  gfc_array_spec *as;
  gfc_ref *ref;

  if (expr->rank == 0)
    return NULL;

  /* Follow any component references.  */
  if (expr->expr_type == EXPR_VARIABLE
      || expr->expr_type == EXPR_CONSTANT)
    {
      if (expr->symtree)
	as = expr->symtree->n.sym->as;
      else
	as = NULL;

      for (ref = expr->ref; ref; ref = ref->next)
	{
	  switch (ref->type)
	    {
	    case REF_COMPONENT:
	      as = ref->u.c.component->as;
	      continue;

	    case REF_SUBSTRING:
	    case REF_INQUIRY:
	      continue;

	    case REF_ARRAY:
	      {
		switch (ref->u.ar.type)
		  {
		  case AR_ELEMENT:
		  case AR_SECTION:
		  case AR_UNKNOWN:
		    as = NULL;
		    continue;

		  case AR_FULL:
		    break;
		  }
		break;
	      }
	    }
	}
    }
  else
    as = NULL;

  return as;
}


/* General expression traversal function.  */

bool
gfc_traverse_expr (gfc_expr *expr, gfc_symbol *sym,
		   bool (*func)(gfc_expr *, gfc_symbol *, int*),
		   int f)
{
  gfc_array_ref ar;
  gfc_ref *ref;
  gfc_actual_arglist *args;
  gfc_constructor *c;
  int i;

  if (!expr)
    return false;

  if ((*func) (expr, sym, &f))
    return true;

  /* Descend into length type parameter of character expressions only for
     non-negative f.  */
  if (f >= 0
      && expr->ts.type == BT_CHARACTER
      && expr->ts.u.cl
      && expr->ts.u.cl->length
      && expr->ts.u.cl->length->expr_type != EXPR_CONSTANT
      && gfc_traverse_expr (expr->ts.u.cl->length, sym, func, f))
    return true;

  switch (expr->expr_type)
    {
    case EXPR_PPC:
    case EXPR_COMPCALL:
    case EXPR_FUNCTION:
      for (args = expr->value.function.actual; args; args = args->next)
	{
	  if (gfc_traverse_expr (args->expr, sym, func, f))
	    return true;
	}
      break;

    case EXPR_VARIABLE:
    case EXPR_CONSTANT:
    case EXPR_NULL:
    case EXPR_SUBSTRING:
      break;

    case EXPR_STRUCTURE:
    case EXPR_ARRAY:
      for (c = gfc_constructor_first (expr->value.constructor);
	   c; c = gfc_constructor_next (c))
	{
	  if (gfc_traverse_expr (c->expr, sym, func, f))
	    return true;
	  if (c->iterator)
	    {
	      if (gfc_traverse_expr (c->iterator->var, sym, func, f))
		return true;
	      if (gfc_traverse_expr (c->iterator->start, sym, func, f))
		return true;
	      if (gfc_traverse_expr (c->iterator->end, sym, func, f))
		return true;
	      if (gfc_traverse_expr (c->iterator->step, sym, func, f))
		return true;
	    }
	}
      break;

    case EXPR_OP:
      if (gfc_traverse_expr (expr->value.op.op1, sym, func, f))
	return true;
      if (gfc_traverse_expr (expr->value.op.op2, sym, func, f))
	return true;
      break;

    default:
      gcc_unreachable ();
      break;
    }

  ref = expr->ref;
  while (ref != NULL)
    {
      switch (ref->type)
	{
	case  REF_ARRAY:
	  ar = ref->u.ar;
	  for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
	    {
	      if (gfc_traverse_expr (ar.start[i], sym, func, f))
		return true;
	      if (gfc_traverse_expr (ar.end[i], sym, func, f))
		return true;
	      if (gfc_traverse_expr (ar.stride[i], sym, func, f))
		return true;
	    }
	  break;

	case REF_SUBSTRING:
	  if (gfc_traverse_expr (ref->u.ss.start, sym, func, f))
	    return true;
	  if (gfc_traverse_expr (ref->u.ss.end, sym, func, f))
	    return true;
	  break;

	case REF_COMPONENT:
	  if (f >= 0
	      && ref->u.c.component->ts.type == BT_CHARACTER
	      && ref->u.c.component->ts.u.cl
	      && ref->u.c.component->ts.u.cl->length
	      && ref->u.c.component->ts.u.cl->length->expr_type
	      != EXPR_CONSTANT
	      && gfc_traverse_expr (ref->u.c.component->ts.u.cl->length,
				    sym, func, f))
	    return true;

	  if (ref->u.c.component->as)
	    for (i = 0; i < ref->u.c.component->as->rank
			    + ref->u.c.component->as->corank; i++)
	      {
		if (gfc_traverse_expr (ref->u.c.component->as->lower[i],
				       sym, func, f))
		  return true;
		if (gfc_traverse_expr (ref->u.c.component->as->upper[i],
				       sym, func, f))
		  return true;
	      }
	  break;

	case REF_INQUIRY:
	  return false;

	default:
	  gcc_unreachable ();
	}
      ref = ref->next;
    }
  return false;
}

/* Traverse expr, marking all EXPR_VARIABLE symbols referenced.  */

static bool
expr_set_symbols_referenced (gfc_expr *expr,
			     gfc_symbol *sym ATTRIBUTE_UNUSED,
			     int *f ATTRIBUTE_UNUSED)
{
  if (expr->expr_type != EXPR_VARIABLE)
    return false;
  gfc_set_sym_referenced (expr->symtree->n.sym);
  return false;
}

void
gfc_expr_set_symbols_referenced (gfc_expr *expr)
{
  gfc_traverse_expr (expr, NULL, expr_set_symbols_referenced, 0);
}


/* Determine if an expression is a procedure pointer component and return
   the component in that case.  Otherwise return NULL.  */

gfc_component *
gfc_get_proc_ptr_comp (gfc_expr *expr)
{
  gfc_ref *ref;

  if (!expr || !expr->ref)
    return NULL;

  ref = expr->ref;
  while (ref->next)
    ref = ref->next;

  if (ref->type == REF_COMPONENT
      && ref->u.c.component->attr.proc_pointer)
    return ref->u.c.component;

  return NULL;
}


/* Determine if an expression is a procedure pointer component.  */

bool
gfc_is_proc_ptr_comp (gfc_expr *expr)
{
  return (gfc_get_proc_ptr_comp (expr) != NULL);
}


/* Determine if an expression is a function with an allocatable class scalar
   result.  */
bool
gfc_is_alloc_class_scalar_function (gfc_expr *expr)
{
  if (expr->expr_type == EXPR_FUNCTION
      && ((expr->value.function.esym
	   && expr->value.function.esym->result
	   && expr->value.function.esym->result->ts.type == BT_CLASS
	   && !CLASS_DATA (expr->value.function.esym->result)->attr.dimension
	   && CLASS_DATA (expr->value.function.esym->result)->attr.allocatable)
	  || (expr->ts.type == BT_CLASS
	      && CLASS_DATA (expr)->attr.allocatable
	      && !CLASS_DATA (expr)->attr.dimension)))
    return true;

  return false;
}


/* Determine if an expression is a function with an allocatable class array
   result.  */
bool
gfc_is_class_array_function (gfc_expr *expr)
{
  if (expr->expr_type == EXPR_FUNCTION
      && expr->value.function.esym
      && expr->value.function.esym->result
      && expr->value.function.esym->result->ts.type == BT_CLASS
      && CLASS_DATA (expr->value.function.esym->result)->attr.dimension
      && (CLASS_DATA (expr->value.function.esym->result)->attr.allocatable
	  || CLASS_DATA (expr->value.function.esym->result)->attr.pointer))
    return true;

  return false;
}


/* Walk an expression tree and check each variable encountered for being typed.
   If strict is not set, a top-level variable is tolerated untyped in -std=gnu
   mode as is a basic arithmetic expression using those; this is for things in
   legacy-code like:

     INTEGER :: arr(n), n
     INTEGER :: arr(n + 1), n

   The namespace is needed for IMPLICIT typing.  */

static gfc_namespace* check_typed_ns;

static bool
expr_check_typed_help (gfc_expr* e, gfc_symbol* sym ATTRIBUTE_UNUSED,
                       int* f ATTRIBUTE_UNUSED)
{
  bool t;

  if (e->expr_type != EXPR_VARIABLE)
    return false;

  gcc_assert (e->symtree);
  t = gfc_check_symbol_typed (e->symtree->n.sym, check_typed_ns,
                              true, e->where);

  return (!t);
}

bool
gfc_expr_check_typed (gfc_expr* e, gfc_namespace* ns, bool strict)
{
  bool error_found;

  /* If this is a top-level variable or EXPR_OP, do the check with strict given
     to us.  */
  if (!strict)
    {
      if (e->expr_type == EXPR_VARIABLE && !e->ref)
	return gfc_check_symbol_typed (e->symtree->n.sym, ns, strict, e->where);

      if (e->expr_type == EXPR_OP)
	{
	  bool t = true;

	  gcc_assert (e->value.op.op1);
	  t = gfc_expr_check_typed (e->value.op.op1, ns, strict);

	  if (t && e->value.op.op2)
	    t = gfc_expr_check_typed (e->value.op.op2, ns, strict);

	  return t;
	}
    }

  /* Otherwise, walk the expression and do it strictly.  */
  check_typed_ns = ns;
  error_found = gfc_traverse_expr (e, NULL, &expr_check_typed_help, 0);

  return error_found ? false : true;
}


/* This function returns true if it contains any references to PDT KIND
   or LEN parameters.  */

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

  gcc_assert (e->symtree);
  if (e->symtree->n.sym->attr.pdt_kind
      || e->symtree->n.sym->attr.pdt_len)
    return true;

  return false;
}


bool
gfc_derived_parameter_expr (gfc_expr *e)
{
  return gfc_traverse_expr (e, NULL, &derived_parameter_expr, 0);
}


/* This function returns the overall type of a type parameter spec list.
   If all the specs are explicit, SPEC_EXPLICIT is returned. If any of the
   parameters are assumed/deferred then SPEC_ASSUMED/DEFERRED is returned
   unless derived is not NULL.  In this latter case, all the LEN parameters
   must be either assumed or deferred for the return argument to be set to
   anything other than SPEC_EXPLICIT.  */

gfc_param_spec_type
gfc_spec_list_type (gfc_actual_arglist *param_list, gfc_symbol *derived)
{
  gfc_param_spec_type res = SPEC_EXPLICIT;
  gfc_component *c;
  bool seen_assumed = false;
  bool seen_deferred = false;

  if (derived == NULL)
    {
      for (; param_list; param_list = param_list->next)
	if (param_list->spec_type == SPEC_ASSUMED
	    || param_list->spec_type == SPEC_DEFERRED)
	  return param_list->spec_type;
    }
  else
    {
      for (; param_list; param_list = param_list->next)
	{
	  c = gfc_find_component (derived, param_list->name,
				  true, true, NULL);
	  gcc_assert (c != NULL);
	  if (c->attr.pdt_kind)
	    continue;
	  else if (param_list->spec_type == SPEC_EXPLICIT)
	    return SPEC_EXPLICIT;
	  seen_assumed = param_list->spec_type == SPEC_ASSUMED;
	  seen_deferred = param_list->spec_type == SPEC_DEFERRED;
	  if (seen_assumed && seen_deferred)
	    return SPEC_EXPLICIT;
	}
      res = seen_assumed ? SPEC_ASSUMED : SPEC_DEFERRED;
    }
  return res;
}


bool
gfc_ref_this_image (gfc_ref *ref)
{
  int n;

  gcc_assert (ref->type == REF_ARRAY && ref->u.ar.codimen > 0);

  for (n = ref->u.ar.dimen; n < ref->u.ar.dimen + ref->u.ar.codimen; n++)
    if (ref->u.ar.dimen_type[n] != DIMEN_THIS_IMAGE)
      return false;

  return true;
}

gfc_expr *
gfc_find_team_co (gfc_expr *e, enum gfc_array_ref_team_type req_team_type)
{
  gfc_ref *ref;

  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0
	&& ref->u.ar.team_type == req_team_type)
      return ref->u.ar.team;

  if (e->expr_type == EXPR_FUNCTION && e->value.function.actual->expr)
    for (ref = e->value.function.actual->expr->ref; ref;
	 ref = ref->next)
      if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0
	  && ref->u.ar.team_type == req_team_type)
	return ref->u.ar.team;

  return NULL;
}

gfc_expr *
gfc_find_stat_co (gfc_expr *e)
{
  gfc_ref *ref;

  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
      return ref->u.ar.stat;

  if (e->value.function.actual->expr)
    for (ref = e->value.function.actual->expr->ref; ref;
	 ref = ref->next)
      if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
	return ref->u.ar.stat;

  return NULL;
}

bool
gfc_is_coindexed (gfc_expr *e)
{
  gfc_ref *ref;

  if (e->expr_type == EXPR_FUNCTION && e->value.function.isym
      && e->value.function.isym->id == GFC_ISYM_CAF_GET)
    e = e->value.function.actual->expr;

  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
      return !gfc_ref_this_image (ref);

  return false;
}


/* Coarrays are variables with a corank but not being coindexed. However, also
   the following is a coarray: A subobject of a coarray is a coarray if it does
   not have any cosubscripts, vector subscripts, allocatable component
   selection, or pointer component selection. (F2008, 2.4.7)  */

bool
gfc_is_coarray (gfc_expr *e)
{
  gfc_ref *ref;
  gfc_symbol *sym;
  gfc_component *comp;
  bool coindexed;
  bool coarray;
  int i;

  if (e->expr_type != EXPR_VARIABLE)
    return false;

  coindexed = false;
  sym = e->symtree->n.sym;

  if (sym->ts.type == BT_CLASS && sym->attr.class_ok)
    coarray = CLASS_DATA (sym)->attr.codimension;
  else
    coarray = sym->attr.codimension;

  for (ref = e->ref; ref; ref = ref->next)
    switch (ref->type)
    {
      case REF_COMPONENT:
	comp = ref->u.c.component;
	if (comp->ts.type == BT_CLASS && comp->attr.class_ok
	    && (CLASS_DATA (comp)->attr.class_pointer
		|| CLASS_DATA (comp)->attr.allocatable))
	  {
	    coindexed = false;
	    coarray = CLASS_DATA (comp)->attr.codimension;
	  }
        else if (comp->attr.pointer || comp->attr.allocatable)
	  {
	    coindexed = false;
	    coarray = comp->attr.codimension;
	  }
        break;

     case REF_ARRAY:
	if (!coarray)
	  break;

	if (ref->u.ar.codimen > 0 && !gfc_ref_this_image (ref))
	  {
	    coindexed = true;
	    break;
	  }

	for (i = 0; i < ref->u.ar.dimen; i++)
	  if (ref->u.ar.dimen_type[i] == DIMEN_VECTOR)
	    {
	      coarray = false;
	      break;
	    }
	break;

     case REF_SUBSTRING:
     case REF_INQUIRY:
	break;
    }

  return coarray && !coindexed;
}


/* Check whether the expression has an ultimate allocatable component.
   Being itself allocatable does not count.  */
bool
gfc_has_ultimate_allocatable (gfc_expr *e)
{
  gfc_ref *ref, *last = NULL;

  if (e->expr_type != EXPR_VARIABLE)
    return false;

  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type == REF_COMPONENT)
      last = ref;

  if (last && last->u.c.component->ts.type == BT_CLASS)
    return CLASS_DATA (last->u.c.component)->attr.alloc_comp;
  else if (last && last->u.c.component->ts.type == BT_DERIVED)
    return last->u.c.component->ts.u.derived->attr.alloc_comp;
  else if (last)
    return false;

  if (e->ts.type == BT_CLASS)
    return CLASS_DATA (e)->attr.alloc_comp;
  else if (e->ts.type == BT_DERIVED)
    return e->ts.u.derived->attr.alloc_comp;
  else
    return false;
}


/* Check whether the expression has an pointer component.
   Being itself a pointer does not count.  */
bool
gfc_has_ultimate_pointer (gfc_expr *e)
{
  gfc_ref *ref, *last = NULL;

  if (e->expr_type != EXPR_VARIABLE)
    return false;

  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type == REF_COMPONENT)
      last = ref;

  if (last && last->u.c.component->ts.type == BT_CLASS)
    return CLASS_DATA (last->u.c.component)->attr.pointer_comp;
  else if (last && last->u.c.component->ts.type == BT_DERIVED)
    return last->u.c.component->ts.u.derived->attr.pointer_comp;
  else if (last)
    return false;

  if (e->ts.type == BT_CLASS)
    return CLASS_DATA (e)->attr.pointer_comp;
  else if (e->ts.type == BT_DERIVED)
    return e->ts.u.derived->attr.pointer_comp;
  else
    return false;
}


/* Check whether an expression is "simply contiguous", cf. F2008, 6.5.4.
   Note: A scalar is not regarded as "simply contiguous" by the standard.
   if bool is not strict, some further checks are done - for instance,
   a "(::1)" is accepted.  */

bool
gfc_is_simply_contiguous (gfc_expr *expr, bool strict, bool permit_element)
{
  bool colon;
  int i;
  gfc_array_ref *ar = NULL;
  gfc_ref *ref, *part_ref = NULL;
  gfc_symbol *sym;

  if (expr->expr_type == EXPR_ARRAY)
    return true;

  if (expr->expr_type == EXPR_NULL)
    {
      /* F2018:16.9.144  NULL ([MOLD]):
	 "If MOLD is present, the characteristics are the same as MOLD."
	 "If MOLD is absent, the characteristics of the result are
	 determined by the entity with which the reference is associated."
	 F2018:15.3.2.2 characteristics attributes include CONTIGUOUS.  */
      if (expr->ts.type == BT_UNKNOWN)
	return true;
      else
	return (gfc_variable_attr (expr, NULL).contiguous
		|| gfc_variable_attr (expr, NULL).allocatable);
    }

  if (expr->expr_type == EXPR_FUNCTION)
    {
      if (expr->value.function.isym)
	/* TRANSPOSE is the only intrinsic that may return a
	   non-contiguous array.  It's treated as a special case in
	   gfc_conv_expr_descriptor too.  */
	return (expr->value.function.isym->id != GFC_ISYM_TRANSPOSE);
      else if (expr->value.function.esym)
	/* Only a pointer to an array without the contiguous attribute
	   can be non-contiguous as a result value.  */
	return (expr->value.function.esym->result->attr.contiguous
		|| !expr->value.function.esym->result->attr.pointer);
      else
	{
	  /* Type-bound procedures.  */
	  gfc_symbol *s = expr->symtree->n.sym;
	  if (s->ts.type != BT_CLASS && s->ts.type != BT_DERIVED)
	    return false;

	  gfc_ref *rc = NULL;
	  for (gfc_ref *r = expr->ref; r; r = r->next)
	    if (r->type == REF_COMPONENT)
	      rc = r;

	  if (rc == NULL || rc->u.c.component == NULL
	      || rc->u.c.component->ts.interface == NULL)
	    return false;

	  return rc->u.c.component->ts.interface->attr.contiguous;
	}
    }
  else if (expr->expr_type != EXPR_VARIABLE)
    return false;

  if (!permit_element && expr->rank == 0)
    return false;

  for (ref = expr->ref; ref; ref = ref->next)
    {
      if (ar)
	return false; /* Array shall be last part-ref.  */

      if (ref->type == REF_COMPONENT)
	part_ref  = ref;
      else if (ref->type == REF_SUBSTRING)
	return false;
      else if (ref->type == REF_INQUIRY)
	return false;
      else if (ref->u.ar.type != AR_ELEMENT)
	ar = &ref->u.ar;
    }

  sym = expr->symtree->n.sym;
  if ((part_ref
       && part_ref->u.c.component
       && !part_ref->u.c.component->attr.contiguous
       && IS_POINTER (part_ref->u.c.component))
      || (!part_ref
	  && expr->ts.type != BT_CLASS
	  && !sym->attr.contiguous
	  && (sym->attr.pointer
	      || (sym->as && sym->as->type == AS_ASSUMED_RANK)
	      || (sym->as && sym->as->type == AS_ASSUMED_SHAPE))))
    return false;

  if (!ar || ar->type == AR_FULL)
    return true;

  gcc_assert (ar->type == AR_SECTION);

  /* Check for simply contiguous array */
  colon = true;
  for (i = 0; i < ar->dimen; i++)
    {
      if (ar->dimen_type[i] == DIMEN_VECTOR)
	return false;

      if (ar->dimen_type[i] == DIMEN_ELEMENT)
	{
	  colon = false;
	  continue;
	}

      gcc_assert (ar->dimen_type[i] == DIMEN_RANGE);


      /* If the previous section was not contiguous, that's an error,
	 unless we have effective only one element and checking is not
	 strict.  */
      if (!colon && (strict || !ar->start[i] || !ar->end[i]
		     || ar->start[i]->expr_type != EXPR_CONSTANT
		     || ar->end[i]->expr_type != EXPR_CONSTANT
		     || mpz_cmp (ar->start[i]->value.integer,
				 ar->end[i]->value.integer) != 0))
	return false;

      /* Following the standard, "(::1)" or - if known at compile time -
	 "(lbound:ubound)" are not simply contiguous; if strict
	 is false, they are regarded as simply contiguous.  */
      if (ar->stride[i] && (strict || ar->stride[i]->expr_type != EXPR_CONSTANT
			    || ar->stride[i]->ts.type != BT_INTEGER
			    || mpz_cmp_si (ar->stride[i]->value.integer, 1) != 0))
	return false;

      if (ar->start[i]
	  && (strict || ar->start[i]->expr_type != EXPR_CONSTANT
	      || !ar->as->lower[i]
	      || ar->as->lower[i]->expr_type != EXPR_CONSTANT
	      || mpz_cmp (ar->start[i]->value.integer,
			  ar->as->lower[i]->value.integer) != 0))
	colon = false;

      if (ar->end[i]
	  && (strict || ar->end[i]->expr_type != EXPR_CONSTANT
	      || !ar->as->upper[i]
	      || ar->as->upper[i]->expr_type != EXPR_CONSTANT
	      || mpz_cmp (ar->end[i]->value.integer,
			  ar->as->upper[i]->value.integer) != 0))
	colon = false;
    }

  return true;
}

/* Return true if the expression is guaranteed to be non-contiguous,
   false if we cannot prove anything.  It is probably best to call
   this after gfc_is_simply_contiguous.  If neither of them returns
   true, we cannot say (at compile-time).  */

bool
gfc_is_not_contiguous (gfc_expr *array)
{
  int i;
  gfc_array_ref *ar = NULL;
  gfc_ref *ref;
  bool previous_incomplete;

  for (ref = array->ref; ref; ref = ref->next)
    {
      /* Array-ref shall be last ref.  */

      if (ar && ar->type != AR_ELEMENT)
	return true;

      if (ref->type == REF_ARRAY)
	ar = &ref->u.ar;
    }

  if (ar == NULL || ar->type != AR_SECTION)
    return false;

  previous_incomplete = false;

  /* Check if we can prove that the array is not contiguous.  */

  for (i = 0; i < ar->dimen; i++)
    {
      mpz_t arr_size, ref_size;

      if (gfc_ref_dimen_size (ar, i, &ref_size, NULL))
	{
	  if (gfc_dep_difference (ar->as->upper[i], ar->as->lower[i], &arr_size))
	    {
	      /* a(2:4,2:) is known to be non-contiguous, but
		 a(2:4,i:i) can be contiguous.  */
	      mpz_add_ui (arr_size, arr_size, 1L);
	      if (previous_incomplete && mpz_cmp_si (ref_size, 1) != 0)
		{
		  mpz_clear (arr_size);
		  mpz_clear (ref_size);
		  return true;
		}
	      else if (mpz_cmp (arr_size, ref_size) != 0)
		previous_incomplete = true;

	      mpz_clear (arr_size);
	    }

	  /* Check for a(::2), i.e. where the stride is not unity.
	     This is only done if there is more than one element in
	     the reference along this dimension.  */

	  if (mpz_cmp_ui (ref_size, 1) > 0 && ar->type == AR_SECTION
	      && ar->dimen_type[i] == DIMEN_RANGE
	      && ar->stride[i] && ar->stride[i]->expr_type == EXPR_CONSTANT
	      && mpz_cmp_si (ar->stride[i]->value.integer, 1) != 0)
	    {
	      mpz_clear (ref_size);
	      return true;
	    }

	  mpz_clear (ref_size);
	}
    }
  /* We didn't find anything definitive.  */
  return false;
}

/* Build call to an intrinsic procedure.  The number of arguments has to be
   passed (rather than ending the list with a NULL value) because we may
   want to add arguments but with a NULL-expression.  */

gfc_expr*
gfc_build_intrinsic_call (gfc_namespace *ns, gfc_isym_id id, const char* name,
			  locus where, unsigned numarg, ...)
{
  gfc_expr* result;
  gfc_actual_arglist* atail;
  gfc_intrinsic_sym* isym;
  va_list ap;
  unsigned i;
  const char *mangled_name = gfc_get_string (GFC_PREFIX ("%s"), name);

  isym = gfc_intrinsic_function_by_id (id);
  gcc_assert (isym);

  result = gfc_get_expr ();
  result->expr_type = EXPR_FUNCTION;
  result->ts = isym->ts;
  result->where = where;
  result->value.function.name = mangled_name;
  result->value.function.isym = isym;

  gfc_get_sym_tree (mangled_name, ns, &result->symtree, false);
  gfc_commit_symbol (result->symtree->n.sym);
  gcc_assert (result->symtree
	      && (result->symtree->n.sym->attr.flavor == FL_PROCEDURE
		  || result->symtree->n.sym->attr.flavor == FL_UNKNOWN));
  result->symtree->n.sym->intmod_sym_id = id;
  result->symtree->n.sym->attr.flavor = FL_PROCEDURE;
  result->symtree->n.sym->attr.intrinsic = 1;
  result->symtree->n.sym->attr.artificial = 1;

  va_start (ap, numarg);
  atail = NULL;
  for (i = 0; i < numarg; ++i)
    {
      if (atail)
	{
	  atail->next = gfc_get_actual_arglist ();
	  atail = atail->next;
	}
      else
	atail = result->value.function.actual = gfc_get_actual_arglist ();

      atail->expr = va_arg (ap, gfc_expr*);
    }
  va_end (ap);

  return result;
}


/* Check if a symbol referenced in a submodule is declared in the ancestor
   module and not accessed by use-association, and that the submodule is a
   descendant.  */

static bool
sym_is_from_ancestor (gfc_symbol *sym)
{
  const char dot[2] = ".";
  /* Symbols take the form module.submodule_ or module.name_. */
  char ancestor_module[2 * GFC_MAX_SYMBOL_LEN + 2];
  char *ancestor;

  if (sym == NULL
      || sym->attr.use_assoc
      || !sym->attr.used_in_submodule
      || !sym->module
      || !sym->ns->proc_name
      || !sym->ns->proc_name->name)
    return false;

  memset (ancestor_module, '\0', sizeof (ancestor_module));
  strcpy (ancestor_module, sym->ns->proc_name->name);
  ancestor = strtok (ancestor_module, dot);
  return strcmp (ancestor, sym->module) == 0;
}


/* Check if an expression may appear in a variable definition context
   (F2008, 16.6.7) or pointer association context (F2008, 16.6.8).
   This is called from the various places when resolving
   the pieces that make up such a context.
   If own_scope is true (applies to, e.g., ac-implied-do/data-implied-do
   variables), some checks are not performed.

   Optionally, a possible error message can be suppressed if context is NULL
   and just the return status (true / false) be requested.  */

bool
gfc_check_vardef_context (gfc_expr* e, bool pointer, bool alloc_obj,
			  bool own_scope, const char* context)
{
  gfc_symbol* sym = NULL;
  bool is_pointer;
  bool check_intentin;
  bool ptr_component;
  symbol_attribute attr;
  gfc_ref* ref;
  int i;

  if (e->expr_type == EXPR_VARIABLE)
    {
      gcc_assert (e->symtree);
      sym = e->symtree->n.sym;
    }
  else if (e->expr_type == EXPR_FUNCTION)
    {
      gcc_assert (e->symtree);
      sym = e->value.function.esym ? e->value.function.esym : e->symtree->n.sym;
    }

  attr = gfc_expr_attr (e);
  if (!pointer && e->expr_type == EXPR_FUNCTION && attr.pointer)
    {
      if (!(gfc_option.allow_std & GFC_STD_F2008))
	{
	  if (context)
	    gfc_error ("Fortran 2008: Pointer functions in variable definition"
		       " context (%s) at %L", context, &e->where);
	  return false;
	}
    }
  else if (e->expr_type != EXPR_VARIABLE)
    {
      if (context)
	gfc_error ("Non-variable expression in variable definition context (%s)"
		   " at %L", context, &e->where);
      return false;
    }

  if (!pointer && sym->attr.flavor == FL_PARAMETER)
    {
      if (context)
	gfc_error ("Named constant %qs in variable definition context (%s)"
		   " at %L", sym->name, context, &e->where);
      return false;
    }
  if (!pointer && sym->attr.flavor != FL_VARIABLE
      && !(sym->attr.flavor == FL_PROCEDURE && sym == sym->result)
      && !(sym->attr.flavor == FL_PROCEDURE && sym->attr.proc_pointer)
      && !(sym->attr.flavor == FL_PROCEDURE
	   && sym->attr.function && attr.pointer))
    {
      if (context)
	gfc_error ("%qs in variable definition context (%s) at %L is not"
		   " a variable", sym->name, context, &e->where);
      return false;
    }

  /* Find out whether the expr is a pointer; this also means following
     component references to the last one.  */
  is_pointer = (attr.pointer || attr.proc_pointer);
  if (pointer && !is_pointer)
    {
      if (context)
	gfc_error ("Non-POINTER in pointer association context (%s)"
		   " at %L", context, &e->where);
      return false;
    }

  if (e->ts.type == BT_DERIVED
      && e->ts.u.derived == NULL)
    {
      if (context)
	gfc_error ("Type inaccessible in variable definition context (%s) "
		   "at %L", context, &e->where);
      return false;
    }

  /* F2008, C1303.  */
  if (!alloc_obj
      && (attr.lock_comp
	  || (e->ts.type == BT_DERIVED
	      && e->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
	      && e->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)))
    {
      if (context)
	gfc_error ("LOCK_TYPE in variable definition context (%s) at %L",
		   context, &e->where);
      return false;
    }

  /* TS18508, C702/C203.  */
  if (!alloc_obj
      && (attr.lock_comp
	  || (e->ts.type == BT_DERIVED
	      && e->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
	      && e->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)))
    {
      if (context)
	gfc_error ("LOCK_EVENT in variable definition context (%s) at %L",
		   context, &e->where);
      return false;
    }

  /* INTENT(IN) dummy argument.  Check this, unless the object itself is the
     component of sub-component of a pointer; we need to distinguish
     assignment to a pointer component from pointer-assignment to a pointer
     component.  Note that (normal) assignment to procedure pointers is not
     possible.  */
  check_intentin = !own_scope;
  ptr_component = (sym->ts.type == BT_CLASS && sym->ts.u.derived
		   && CLASS_DATA (sym))
		  ? CLASS_DATA (sym)->attr.class_pointer : sym->attr.pointer;
  for (ref = e->ref; ref && check_intentin; ref = ref->next)
    {
      if (ptr_component && ref->type == REF_COMPONENT)
	check_intentin = false;
      if (ref->type == REF_COMPONENT)
	{
	  gfc_component *comp = ref->u.c.component;
	  ptr_component = (comp->ts.type == BT_CLASS && comp->attr.class_ok)
			? CLASS_DATA (comp)->attr.class_pointer
			: comp->attr.pointer;
	  if (ptr_component && !pointer)
	    check_intentin = false;
	}
      if (ref->type == REF_INQUIRY
	  && (ref->u.i == INQUIRY_KIND || ref->u.i == INQUIRY_LEN))
	{
	  if (context)
	    gfc_error ("%qs parameter inquiry for %qs in "
		       "variable definition context (%s) at %L",
		       ref->u.i == INQUIRY_KIND ? "KIND" : "LEN",
		       sym->name, context, &e->where);
	  return false;
	}
    }

  if (check_intentin
      && (sym->attr.intent == INTENT_IN
	  || (sym->attr.select_type_temporary && sym->assoc
	      && sym->assoc->target && sym->assoc->target->symtree
	      && sym->assoc->target->symtree->n.sym->attr.intent == INTENT_IN)))
    {
      if (pointer && is_pointer)
	{
	  if (context)
	    gfc_error ("Dummy argument %qs with INTENT(IN) in pointer"
		       " association context (%s) at %L",
		       sym->name, context, &e->where);
	  return false;
	}
      if (!pointer && !is_pointer && !sym->attr.pointer)
	{
	  const char *name = sym->attr.select_type_temporary
			   ? sym->assoc->target->symtree->name : sym->name;
	  if (context)
	    gfc_error ("Dummy argument %qs with INTENT(IN) in variable"
		       " definition context (%s) at %L",
		       name, context, &e->where);
	  return false;
	}
    }

  /* PROTECTED and use-associated.  */
  if (sym->attr.is_protected
      && (sym->attr.use_assoc
	  || (sym->attr.used_in_submodule && !sym_is_from_ancestor (sym)))
      && check_intentin)
    {
      if (pointer && is_pointer)
	{
	  if (context)
	    gfc_error ("Variable %qs is PROTECTED and cannot appear in a "
		       "pointer association context (%s) at %L",
		       sym->name, context, &e->where);
	  return false;
	}
      if (!pointer && !is_pointer)
	{
	  if (context)
	    gfc_error ("Variable %qs is PROTECTED and cannot appear in a "
		       "variable definition context (%s) at %L",
		       sym->name, context, &e->where);
	  return false;
	}
    }

  /* Variable not assignable from a PURE procedure but appears in
     variable definition context.  */
  own_scope = own_scope
	      || (sym->attr.result && sym->ns->proc_name
		  && sym == sym->ns->proc_name->result);
  if (!pointer && !own_scope && gfc_pure (NULL) && gfc_impure_variable (sym))
    {
      if (context)
	gfc_error ("Variable %qs cannot appear in a variable definition"
		   " context (%s) at %L in PURE procedure",
		   sym->name, context, &e->where);
      return false;
    }

  if (!pointer && context && gfc_implicit_pure (NULL)
      && gfc_impure_variable (sym))
    {
      gfc_namespace *ns;
      gfc_symbol *sym;

      for (ns = gfc_current_ns; ns; ns = ns->parent)
	{
	  sym = ns->proc_name;
	  if (sym == NULL)
	    break;
	  if (sym->attr.flavor == FL_PROCEDURE)
	    {
	      sym->attr.implicit_pure = 0;
	      break;
	    }
	}
    }
  /* Check variable definition context for associate-names.  */
  if (!pointer && sym->assoc && !sym->attr.select_rank_temporary)
    {
      const char* name;
      gfc_association_list* assoc;

      gcc_assert (sym->assoc->target);

      /* If this is a SELECT TYPE temporary (the association is used internally
	 for SELECT TYPE), silently go over to the target.  */
      if (sym->attr.select_type_temporary)
	{
	  gfc_expr* t = sym->assoc->target;

	  gcc_assert (t->expr_type == EXPR_VARIABLE);
	  name = t->symtree->name;

	  if (t->symtree->n.sym->assoc)
	    assoc = t->symtree->n.sym->assoc;
	  else
	    assoc = sym->assoc;
	}
      else
	{
	  name = sym->name;
	  assoc = sym->assoc;
	}
      gcc_assert (name && assoc);

      /* Is association to a valid variable?  */
      if (!assoc->variable)
	{
	  if (context)
	    {
	      if (assoc->target->expr_type == EXPR_VARIABLE
		  && gfc_has_vector_index (assoc->target))
		gfc_error ("%qs at %L associated to vector-indexed target"
			   " cannot be used in a variable definition"
			   " context (%s)",
			   name, &e->where, context);
	      else
		gfc_error ("%qs at %L associated to expression"
			   " cannot be used in a variable definition"
			   " context (%s)",
			   name, &e->where, context);
	    }
	  return false;
	}
      else if (context && gfc_is_ptr_fcn (assoc->target))
	{
	  if (!gfc_notify_std (GFC_STD_F2018, "%qs at %L associated to "
			       "pointer function target being used in a "
			       "variable definition context (%s)", name,
			       &e->where, context))
	    return false;
	  else if (gfc_has_vector_index (e))
	    {
	      gfc_error ("%qs at %L associated to vector-indexed target"
			 " cannot be used in a variable definition"
			 " context (%s)",
			 name, &e->where, context);
	      return false;
	    }
	}

      /* Target must be allowed to appear in a variable definition context.  */
      if (!gfc_check_vardef_context (assoc->target, pointer, false, false, NULL))
	{
	  if (context)
	    gfc_error ("Associate-name %qs cannot appear in a variable"
		       " definition context (%s) at %L because its target"
		       " at %L cannot, either",
		       name, context, &e->where,
		       &assoc->target->where);
	  return false;
	}
    }

  /* Check for same value in vector expression subscript.  */

  if (e->rank > 0)
    for (ref = e->ref; ref != NULL; ref = ref->next)
      if (ref->type == REF_ARRAY && ref->u.ar.type == AR_SECTION)
	for (i = 0; i < GFC_MAX_DIMENSIONS
	       && ref->u.ar.dimen_type[i] != 0; i++)
	  if (ref->u.ar.dimen_type[i] == DIMEN_VECTOR)
	    {
	      gfc_expr *arr = ref->u.ar.start[i];
	      if (arr->expr_type == EXPR_ARRAY)
		{
		  gfc_constructor *c, *n;
		  gfc_expr *ec, *en;

		  for (c = gfc_constructor_first (arr->value.constructor);
		       c != NULL; c = gfc_constructor_next (c))
		    {
		      if (c == NULL || c->iterator != NULL)
			continue;

		      ec = c->expr;

		      for (n = gfc_constructor_next (c); n != NULL;
			   n = gfc_constructor_next (n))
			{
			  if (n->iterator != NULL)
			    continue;

			  en = n->expr;
			  if (gfc_dep_compare_expr (ec, en) == 0)
			    {
			      if (context)
				gfc_error_now ("Elements with the same value "
					       "at %L and %L in vector "
					       "subscript in a variable "
					       "definition context (%s)",
					       &(ec->where), &(en->where),
					       context);
			      return false;
			    }
			}
		    }
		}
	    }

  return true;
}

gfc_expr*
gfc_pdt_find_component_copy_initializer (gfc_symbol *sym, const char *name)
{
  /* The actual length of a pdt is in its components.  In the
     initializer of the current ref is only the default value.
     Therefore traverse the chain of components and pick the correct
     one's initializer expressions.  */
  for (gfc_component *comp = sym->ts.u.derived->components; comp != NULL;
       comp = comp->next)
    {
      if (!strcmp (comp->name, name))
	return gfc_copy_expr (comp->initializer);
    }
  return NULL;
}
