/* Routines for manipulation of expression nodes.
   Copyright (C) 2000-2022 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:
      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 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:
	  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:
	  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;

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

      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]);
	    }

	  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.  */

int
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;
}


/* 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 int
numeric_type (bt type)
{
  return type == BT_COMPLEX || type == BT_REAL || type == BT_INTEGER;
}


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

int
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;
	}

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

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

  mpz_init (ptr);
  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_init_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);
	  return false;
	}

      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);
    }

  mpz_clear (ptr);

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]);
    }
  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;
}


/* 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_expr *tmp;

  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 (!inquiry)
    {
      gfc_free_expr (tmp);
      return false;
    }

  gfc_resolve_expr (tmp);

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

	  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
	    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 || tmp->expr_type != EXPR_CONSTANT)
	    goto cleanup;

	  if (!gfc_notify_std (GFC_STD_F2008, "RE part_ref at %C"))
	    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 || tmp->expr_type != EXPR_CONSTANT)
	    goto cleanup;

	  if (!gfc_notify_std (GFC_STD_F2008, "IM part_ref at %C"))
	    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;
	}
      tmp = gfc_copy_expr (*newp);
    }

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

  gfc_free_expr (tmp);
  return true;

cleanup:
  gfc_free_expr (tmp);
  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;

  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->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;

      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;
	  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 = gfc_constructor_copy (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
  };

  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_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;

  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 (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;

      /* gfc_is_formal_arg broadcasts that a formal argument list is being
	 processed in resolve.cc(resolve_formal_arglist).  This is done so
	 that host associated dummy array indices are accepted (PR23446).
	 This mechanism also does the same for the specification expressions
	 of array-valued functions.  */
      if (e->error
	    || sym->attr.in_common
	    || sym->attr.use_assoc
	    || sym->attr.dummy
	    || sym->attr.implied_index
	    || sym->attr.flavor == FL_PARAMETER
	    || is_parent_of_current_ns (sym->ns)
	    || (sym->ns->proc_name != NULL
		  && sym->ns->proc_name->attr.flavor == FL_MODULE)
	    || (gfc_is_formal_arg () && (sym->ns == gfc_current_ns)))
	{
	  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 implictly 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;
      else
	{
	  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 = lvalue->where.lb ? &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.  */
      if (gfc_array_size (lvalue, &lsize)
	  && gfc_array_size (rvalue, &rsize)
	  && mpz_cmp (rsize, lsize) < 0)
	{
	  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);
	  return false;
	}

      /* The target must be either rank one or it must be simply contiguous
	 and F2008 must be allowed.  */
      if (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;
	}
    }

  /* 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.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.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)
{
  gfc_component *c;

  gcc_assert (gfc_fl_struct (der->attr.flavor));
  for (c = der->components; c; c = c->next)
    if (gfc_bt_struct (c->ts.type))
      {
        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)))
	  return true;
	if (c->attr.pointer && c->initializer)
	  return true;
      }
    else
      {
        if (c->initializer)
	  return true;
      }

  return false;
}


/*
   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 && CLASS_DATA (comp)
    && CLASS_DATA (comp)->attr.allocatable;
}

static bool
class_pointer (gfc_component *comp)
{
  return comp->ts.type == BT_CLASS && 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)))
    {
      e->rank = var->n.sym->ts.type == BT_CLASS
		? CLASS_DATA (var->n.sym)->as->rank : var->n.sym->as->rank;
      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 (var->n.sym->ts.type == BT_CLASS
					     ? CLASS_DATA (var->n.sym)->as
					     : var->n.sym->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;
  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;
  if (lval->rank)
    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;

  if (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 (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 true;

	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)
    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)
{
  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.team;

  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.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;

  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;
}


int
gfc_get_corank (gfc_expr *e)
{
  int corank;
  gfc_ref *ref;

  if (!gfc_is_coarray (e))
    return 0;

  if (e->ts.type == BT_CLASS && e->ts.u.derived->components)
    corank = e->ts.u.derived->components->as
	     ? e->ts.u.derived->components->as->corank : 0;
  else
    corank = e->symtree->n.sym->as ? e->symtree->n.sym->as->corank : 0;

  for (ref = e->ref; ref; ref = ref->next)
    {
      if (ref->type == REF_ARRAY)
	corank = ref->u.ar.as->corank;
      gcc_assert (ref->type != REF_SUBSTRING);
    }

  return corank;
}


/* 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_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 (expr->ts.type != BT_CLASS
      && ((part_ref
	   && !part_ref->u.c.component->attr.contiguous
	   && part_ref->u.c.component->attr.pointer)
	  || (!part_ref
	      && !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 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 && sym->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 && 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_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;
	}

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