/* Check functions
   Copyright (C) 2002-2021 Free Software Foundation, Inc.
   Contributed by Andy Vaught & Katherine Holcomb

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


/* These functions check to see if an argument list is compatible with
   a particular intrinsic function or subroutine.  Presence of
   required arguments has already been established, the argument list
   has been sorted into the right order and has NULL arguments in the
   correct places for missing optional arguments.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "options.h"
#include "gfortran.h"
#include "intrinsic.h"
#include "constructor.h"
#include "target-memory.h"


/* Reset a BOZ to a zero value.  This is used to prevent run-on errors
   from resolve.c(resolve_function).  */

static void
reset_boz (gfc_expr *x)
{
  /* Clear boz info.  */
  x->boz.rdx = 0;
  x->boz.len = 0;
  free (x->boz.str);

  x->ts.type = BT_INTEGER;
  x->ts.kind = gfc_default_integer_kind;
  mpz_init (x->value.integer);
  mpz_set_ui (x->value.integer, 0);
}

/* A BOZ literal constant can appear in a limited number of contexts.
   gfc_invalid_boz() is a helper function to simplify error/warning
   generation.  gfortran accepts the nonstandard 'X' for 'Z', and gfortran
   allows the BOZ indicator to appear as a suffix.  If -fallow-invalid-boz
   is used, then issue a warning; otherwise issue an error.  */

bool
gfc_invalid_boz (const char *msg, locus *loc)
{
  if (flag_allow_invalid_boz)
    {
      gfc_warning (0, msg, loc);
      return false;
    }

  const char *hint = _(" [see %<-fno-allow-invalid-boz%>]");
  size_t len = strlen (msg) + strlen (hint) + 1;
  char *msg2 = (char *) alloca (len);
  strcpy (msg2, msg);
  strcat (msg2, hint);
  gfc_error (msg2, loc);
  return true;
}


/* Issue an error for an illegal BOZ argument.  */

static bool
illegal_boz_arg (gfc_expr *x)
{
  if (x->ts.type == BT_BOZ)
    {
      gfc_error ("BOZ literal constant at %L cannot be an actual argument "
		 "to %qs", &x->where, gfc_current_intrinsic);
      reset_boz (x);
      return true;
    }

  return false;
}

/* Some precedures take two arguments such that both cannot be BOZ.  */

static bool
boz_args_check(gfc_expr *i, gfc_expr *j)
{
  if (i->ts.type == BT_BOZ && j->ts.type == BT_BOZ)
    {
      gfc_error ("Arguments of %qs at %L and %L cannot both be BOZ "
		 "literal constants", gfc_current_intrinsic, &i->where,
		 &j->where);
      reset_boz (i);
      reset_boz (j);
      return false;

    }

  return true;
}


/* Check that a BOZ is a constant.  */

static bool
is_boz_constant (gfc_expr *a)
{
  if (a->expr_type != EXPR_CONSTANT)
    {
      gfc_error ("Invalid use of BOZ literal constant at %L", &a->where);
      return false;
    }

  return true;
}


/* Convert a octal string into a binary string.  This is used in the
   fallback conversion of an octal string to a REAL.  */

static char *
oct2bin(int nbits, char *oct)
{
  const char bits[8][5] = {
    "000", "001", "010", "011", "100", "101", "110", "111"};

  char *buf, *bufp;
  int i, j, n;

  j = nbits + 1;
  if (nbits == 64) j++;

  bufp = buf = XCNEWVEC (char, j + 1);
  memset (bufp, 0, j + 1);

  n = strlen (oct);
  for (i = 0; i < n; i++, oct++)
    {
      j = *oct - 48;
      strcpy (bufp, &bits[j][0]);
      bufp += 3;
    }

  bufp = XCNEWVEC (char, nbits + 1);
  if (nbits == 64)
    strcpy (bufp, buf + 2);
  else
    strcpy (bufp, buf + 1);

  free (buf);

  return bufp;
}


/* Convert a hexidecimal string into a binary string.  This is used in the
   fallback conversion of a hexidecimal string to a REAL.  */

static char *
hex2bin(int nbits, char *hex)
{
  const char bits[16][5] = {
    "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
    "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};

  char *buf, *bufp;
  int i, j, n;

  bufp = buf = XCNEWVEC (char, nbits + 1);
  memset (bufp, 0, nbits + 1);

  n = strlen (hex);
  for (i = 0; i < n; i++, hex++)
    {
      j = *hex;
      if (j > 47 && j < 58)
         j -= 48;
      else if (j > 64 && j < 71)
         j -= 55;
      else if (j > 96 && j < 103)
         j -= 87;
      else
         gcc_unreachable ();

      strcpy (bufp, &bits[j][0]);
      bufp += 4;
   }

   return buf;
}


/* Fallback conversion of a BOZ string to REAL.  */

static void
bin2real (gfc_expr *x, int kind)
{
  char buf[114], *sp;
  int b, i, ie, t, w;
  bool sgn;
  mpz_t em;

  i = gfc_validate_kind (BT_REAL, kind, false);
  t = gfc_real_kinds[i].digits - 1;

  /* Number of bits in the exponent.  */
  if (gfc_real_kinds[i].max_exponent == 16384)
    w = 15;
  else if (gfc_real_kinds[i].max_exponent == 1024)
    w = 11;
  else
    w = 8;

  if (x->boz.rdx == 16)
    sp = hex2bin (gfc_real_kinds[i].mode_precision, x->boz.str);
  else if (x->boz.rdx == 8)
    sp = oct2bin (gfc_real_kinds[i].mode_precision, x->boz.str);
  else
    sp = x->boz.str;

  /* Extract sign bit. */
  sgn = *sp != '0';

  /* Extract biased exponent. */
  memset (buf, 0, 114);
  strncpy (buf, ++sp, w);
  mpz_init (em);
  mpz_set_str (em, buf, 2);
  ie = mpz_get_si (em);

  mpfr_init2 (x->value.real, t + 1);
  x->ts.type = BT_REAL;
  x->ts.kind = kind;

  sp += w;		/* Set to first digit in significand. */
  b = (1 << w) - 1;
  if ((i == 0 && ie == b) || (i == 1 && ie == b)
      || ((i == 2 || i == 3) && ie == b))
    {
      bool zeros = true;
      if (i == 2) sp++;
      for (; *sp; sp++)
	{
	  if (*sp != '0')
	    {
	      zeros = false;
	      break;
	    }
	}

      if (zeros)
	mpfr_set_inf (x->value.real, 1);
      else
	mpfr_set_nan (x->value.real);
    }
  else
    {
      if (i == 2)
	strncpy (buf, sp, t + 1);
      else
	{
	  /* Significand with hidden bit. */
 	  buf[0] = '1';
	  strncpy (&buf[1], sp, t);
	}

      /* Convert to significand to integer. */
      mpz_set_str (em, buf, 2);
      ie -= ((1 << (w - 1)) - 1);	/* Unbiased exponent. */
      mpfr_set_z_2exp (x->value.real, em, ie - t, GFC_RND_MODE);
    }

   if (sgn) mpfr_neg (x->value.real, x->value.real, GFC_RND_MODE);

   mpz_clear (em);
}


/* Fortran 2018 treats a BOZ as simply a string of bits.  gfc_boz2real ()
   converts the string into a REAL of the appropriate kind.  The treatment
   of the sign bit is processor dependent.  */

bool
gfc_boz2real (gfc_expr *x, int kind)
{
  extern int gfc_max_integer_kind;
  gfc_typespec ts;
  int len;
  char *buf, *str;

  if (!is_boz_constant (x))
    return false;

  /* Determine the length of the required string.  */
  len = 8 * kind;
  if (x->boz.rdx == 16) len /= 4;
  if (x->boz.rdx == 8) len = len / 3 + 1;
  buf = (char *) alloca (len + 1);		/* +1 for NULL terminator.  */

  if (x->boz.len >= len)			/* Truncate if necessary.  */
    {
      str = x->boz.str + (x->boz.len - len);
      strcpy(buf, str);
    }
  else						/* Copy and pad. */
    {
      memset (buf, 48, len);
      str = buf + (len - x->boz.len);
      strcpy (str, x->boz.str);
    }

  /* Need to adjust leading bits in an octal string.  */
  if (x->boz.rdx == 8)
    {
      /* Clear first bit.  */
      if (kind == 4 || kind == 10 || kind == 16)
	{
	  if (buf[0] == '4')
	    buf[0] = '0';
	  else if (buf[0] == '5')
	    buf[0] = '1';
	  else if (buf[0] == '6')
	    buf[0] = '2';
	  else if (buf[0] == '7')
	    buf[0] = '3';
	}
      /* Clear first two bits.  */
      else
	{
	  if (buf[0] == '2' || buf[0] == '4' || buf[0] == '6')
	    buf[0] = '0';
	  else if (buf[0] == '3' || buf[0] == '5' || buf[0] == '7')
	    buf[0] = '1';
	}
    }

  /* Reset BOZ string to the truncated or padded version.  */
  free (x->boz.str);
  x->boz.len = len;
  x->boz.str = XCNEWVEC (char, len + 1);
  strncpy (x->boz.str, buf, len);

  /* For some targets, the largest INTEGER in terms of bits is smaller than
     the bits needed to hold the REAL.  Fortunately, the kind type parameter
     indicates the number of bytes required to an INTEGER and a REAL.  */
  if (gfc_max_integer_kind < kind)
    {
      bin2real (x, kind);
    }
  else
    {
      /* Convert to widest possible integer.  */
      gfc_boz2int (x, gfc_max_integer_kind);
      ts.type = BT_REAL;
      ts.kind = kind;
      if (!gfc_convert_boz (x, &ts))
	{
	  gfc_error ("Failure in conversion of BOZ to REAL at %L", &x->where);
	  return false;
	}
    }

  return true;
}


/* Fortran 2018 treats a BOZ as simply a string of bits.  gfc_boz2int ()
   converts the string into an INTEGER of the appropriate kind.  The
   treatment of the sign bit is processor dependent.  If the  converted
   value exceeds the range of the type, then wrap-around semantics are
   applied.  */

bool
gfc_boz2int (gfc_expr *x, int kind)
{
  int i, len;
  char *buf, *str;
  mpz_t tmp1;

  if (!is_boz_constant (x))
    return false;

  i = gfc_validate_kind (BT_INTEGER, kind, false);
  len = gfc_integer_kinds[i].bit_size;
  if (x->boz.rdx == 16) len /= 4;
  if (x->boz.rdx == 8) len = len / 3 + 1;
  buf = (char *) alloca (len + 1);		/* +1 for NULL terminator.  */

  if (x->boz.len >= len)			/* Truncate if necessary.  */
    {
      str = x->boz.str + (x->boz.len - len);
      strcpy(buf, str);
    }
  else						/* Copy and pad. */
    {
      memset (buf, 48, len);
      str = buf + (len - x->boz.len);
      strcpy (str, x->boz.str);
    }

  /* Need to adjust leading bits in an octal string.  */
  if (x->boz.rdx == 8)
    {
      /* Clear first bit.  */
      if (kind == 1 || kind == 4 || kind == 16)
	{
	  if (buf[0] == '4')
	    buf[0] = '0';
	  else if (buf[0] == '5')
	    buf[0] = '1';
	  else if (buf[0] == '6')
	    buf[0] = '2';
	  else if (buf[0] == '7')
	    buf[0] = '3';
	}
      /* Clear first two bits.  */
      else
	{
	  if (buf[0] == '2' || buf[0] == '4' || buf[0] == '6')
	    buf[0] = '0';
	  else if (buf[0] == '3' || buf[0] == '5' || buf[0] == '7')
	    buf[0] = '1';
	}
    }

  /* Convert as-if unsigned integer.  */
  mpz_init (tmp1);
  mpz_set_str (tmp1, buf, x->boz.rdx);

  /* Check for wrap-around.  */
  if (mpz_cmp (tmp1, gfc_integer_kinds[i].huge) > 0)
    {
      mpz_t tmp2;
      mpz_init (tmp2);
      mpz_add_ui (tmp2, gfc_integer_kinds[i].huge, 1);
      mpz_mod (tmp1, tmp1, tmp2);
      mpz_sub (tmp1, tmp1, tmp2);
      mpz_clear (tmp2);
    }

  /* Clear boz info.  */
  x->boz.rdx = 0;
  x->boz.len = 0;
  free (x->boz.str);

  mpz_init (x->value.integer);
  mpz_set (x->value.integer, tmp1);
  x->ts.type = BT_INTEGER;
  x->ts.kind = kind;
  mpz_clear (tmp1);

  return true;
}


/* Make sure an expression is a scalar.  */

static bool
scalar_check (gfc_expr *e, int n)
{
  if (e->rank == 0)
    return true;

  gfc_error ("%qs argument of %qs intrinsic at %L must be a scalar",
	     gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
	     &e->where);

  return false;
}


/* Check the type of an expression.  */

static bool
type_check (gfc_expr *e, int n, bt type)
{
  if (e->ts.type == type)
    return true;

  gfc_error ("%qs argument of %qs intrinsic at %L must be %s",
	     gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
	     &e->where, gfc_basic_typename (type));

  return false;
}


/* Check that the expression is a numeric type.  */

static bool
numeric_check (gfc_expr *e, int n)
{
  /* Users sometime use a subroutine designator as an actual argument to
     an intrinsic subprogram that expects an argument with a numeric type.  */
  if (e->symtree && e->symtree->n.sym->attr.subroutine)
    goto error;

  if (gfc_numeric_ts (&e->ts))
    return true;

  /* If the expression has not got a type, check if its namespace can
     offer a default type.  */
  if ((e->expr_type == EXPR_VARIABLE || e->expr_type == EXPR_FUNCTION)
	&& e->symtree->n.sym->ts.type == BT_UNKNOWN
	&& gfc_set_default_type (e->symtree->n.sym, 0, e->symtree->n.sym->ns)
	&& gfc_numeric_ts (&e->symtree->n.sym->ts))
    {
      e->ts = e->symtree->n.sym->ts;
      return true;
    }

error:

  gfc_error ("%qs argument of %qs intrinsic at %L must have a numeric type",
	     gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
	     &e->where);

  return false;
}


/* Check that an expression is integer or real.  */

static bool
int_or_real_check (gfc_expr *e, int n)
{
  if (e->ts.type != BT_INTEGER && e->ts.type != BT_REAL)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be INTEGER "
		 "or REAL", gfc_current_intrinsic_arg[n]->name,
		 gfc_current_intrinsic, &e->where);
      return false;
    }

  return true;
}

/* Check that an expression is integer or real; allow character for
   F2003 or later.  */

static bool
int_or_real_or_char_check_f2003 (gfc_expr *e, int n)
{
  if (e->ts.type != BT_INTEGER && e->ts.type != BT_REAL)
    {
      if (e->ts.type == BT_CHARACTER)
	return gfc_notify_std (GFC_STD_F2003, "Fortran 2003: Character for "
			       "%qs argument of %qs intrinsic at %L",
			       gfc_current_intrinsic_arg[n]->name,
			       gfc_current_intrinsic, &e->where);
      else
	{
	  if (gfc_option.allow_std & GFC_STD_F2003)
	    gfc_error ("%qs argument of %qs intrinsic at %L must be INTEGER "
		       "or REAL or CHARACTER",
		       gfc_current_intrinsic_arg[n]->name,
		       gfc_current_intrinsic, &e->where);
	  else
	    gfc_error ("%qs argument of %qs intrinsic at %L must be INTEGER "
		       "or REAL", gfc_current_intrinsic_arg[n]->name,
		       gfc_current_intrinsic, &e->where);
	}
      return false;
    }

  return true;
}

/* Check that an expression is an intrinsic type.  */
static bool
intrinsic_type_check (gfc_expr *e, int n)
{
  if (e->ts.type != BT_INTEGER && e->ts.type != BT_REAL
      && e->ts.type != BT_COMPLEX && e->ts.type != BT_CHARACTER
      && e->ts.type != BT_LOGICAL)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be of intrinsic type",
		 gfc_current_intrinsic_arg[n]->name,
		 gfc_current_intrinsic, &e->where);
      return false;
    }
  return true;
}

/* Check that an expression is real or complex.  */

static bool
real_or_complex_check (gfc_expr *e, int n)
{
  if (e->ts.type != BT_REAL && e->ts.type != BT_COMPLEX)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be REAL "
		 "or COMPLEX", gfc_current_intrinsic_arg[n]->name,
		 gfc_current_intrinsic, &e->where);
      return false;
    }

  return true;
}


/* Check that an expression is INTEGER or PROCEDURE.  */

static bool
int_or_proc_check (gfc_expr *e, int n)
{
  if (e->ts.type != BT_INTEGER && e->ts.type != BT_PROCEDURE)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be INTEGER "
		 "or PROCEDURE", gfc_current_intrinsic_arg[n]->name,
		 gfc_current_intrinsic, &e->where);
      return false;
    }

  return true;
}


/* Check that the expression is an optional constant integer
   and that it specifies a valid kind for that type.  */

static bool
kind_check (gfc_expr *k, int n, bt type)
{
  int kind;

  if (k == NULL)
    return true;

  if (!type_check (k, n, BT_INTEGER))
    return false;

  if (!scalar_check (k, n))
    return false;

  if (!gfc_check_init_expr (k))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be a constant",
		 gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
		 &k->where);
      return false;
    }

  if (gfc_extract_int (k, &kind)
      || gfc_validate_kind (type, kind, true) < 0)
    {
      gfc_error ("Invalid kind for %s at %L", gfc_basic_typename (type),
		 &k->where);
      return false;
    }

  return true;
}


/* Make sure the expression is a double precision real.  */

static bool
double_check (gfc_expr *d, int n)
{
  if (!type_check (d, n, BT_REAL))
    return false;

  if (d->ts.kind != gfc_default_double_kind)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be double "
		 "precision", gfc_current_intrinsic_arg[n]->name,
		 gfc_current_intrinsic, &d->where);
      return false;
    }

  return true;
}


static bool
coarray_check (gfc_expr *e, int n)
{
  if (e->ts.type == BT_CLASS && gfc_expr_attr (e).class_ok
	&& CLASS_DATA (e)->attr.codimension
	&& CLASS_DATA (e)->as->corank)
    {
      gfc_add_class_array_ref (e);
      return true;
    }

  if (!gfc_is_coarray (e))
    {
      gfc_error ("Expected coarray variable as %qs argument to the %s "
                 "intrinsic at %L", gfc_current_intrinsic_arg[n]->name,
		 gfc_current_intrinsic, &e->where);
      return false;
    }

  return true;
}


/* Make sure the expression is a logical array.  */

static bool
logical_array_check (gfc_expr *array, int n)
{
  if (array->ts.type != BT_LOGICAL || array->rank == 0)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be a logical "
		 "array", gfc_current_intrinsic_arg[n]->name,
		 gfc_current_intrinsic, &array->where);
      return false;
    }

  return true;
}


/* Make sure an expression is an array.  */

static bool
array_check (gfc_expr *e, int n)
{
  if (e->rank != 0 && e->ts.type == BT_CLASS && gfc_expr_attr (e).class_ok
	&& CLASS_DATA (e)->attr.dimension
	&& CLASS_DATA (e)->as->rank)
    {
      gfc_add_class_array_ref (e);
    }

  if (e->rank != 0 && e->ts.type != BT_PROCEDURE)
    return true;

  gfc_error ("%qs argument of %qs intrinsic at %L must be an array",
	     gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
	     &e->where);

  return false;
}


/* If expr is a constant, then check to ensure that it is greater than
   of equal to zero.  */

static bool
nonnegative_check (const char *arg, gfc_expr *expr)
{
  int i;

  if (expr->expr_type == EXPR_CONSTANT)
    {
      gfc_extract_int (expr, &i);
      if (i < 0)
	{
	  gfc_error ("%qs at %L must be nonnegative", arg, &expr->where);
	  return false;
	}
    }

  return true;
}


/* If expr is a constant, then check to ensure that it is greater than zero.  */

static bool
positive_check (int n, gfc_expr *expr)
{
  int i;

  if (expr->expr_type == EXPR_CONSTANT)
    {
      gfc_extract_int (expr, &i);
      if (i <= 0)
	{
	  gfc_error ("%qs argument of %qs intrinsic at %L must be positive",
		     gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
		     &expr->where);
	  return false;
	}
    }

  return true;
}


/* If expr2 is constant, then check that the value is less than
   (less than or equal to, if 'or_equal' is true) bit_size(expr1).  */

static bool
less_than_bitsize1 (const char *arg1, gfc_expr *expr1, const char *arg2,
		    gfc_expr *expr2, bool or_equal)
{
  int i2, i3;

  if (expr2->expr_type == EXPR_CONSTANT)
    {
      gfc_extract_int (expr2, &i2);
      i3 = gfc_validate_kind (BT_INTEGER, expr1->ts.kind, false);

      /* For ISHFT[C], check that |shift| <= bit_size(i).  */
      if (arg2 == NULL)
	{
	  if (i2 < 0)
	    i2 = -i2;

	  if (i2 > gfc_integer_kinds[i3].bit_size)
	    {
	      gfc_error ("The absolute value of SHIFT at %L must be less "
			 "than or equal to BIT_SIZE(%qs)",
			 &expr2->where, arg1);
	      return false;
	    }
	}

      if (or_equal)
	{
	  if (i2 > gfc_integer_kinds[i3].bit_size)
	    {
	      gfc_error ("%qs at %L must be less than "
			 "or equal to BIT_SIZE(%qs)",
			 arg2, &expr2->where, arg1);
	      return false;
	    }
	}
      else
	{
	  if (i2 >= gfc_integer_kinds[i3].bit_size)
	    {
	      gfc_error ("%qs at %L must be less than BIT_SIZE(%qs)",
			 arg2, &expr2->where, arg1);
	      return false;
	    }
	}
    }

  return true;
}


/* If expr is constant, then check that the value is less than or equal
   to the bit_size of the kind k.  */

static bool
less_than_bitsizekind (const char *arg, gfc_expr *expr, int k)
{
  int i, val;

  if (expr->expr_type != EXPR_CONSTANT)
    return true;

  i = gfc_validate_kind (BT_INTEGER, k, false);
  gfc_extract_int (expr, &val);

  if (val > gfc_integer_kinds[i].bit_size)
    {
      gfc_error ("%qs at %L must be less than or equal to the BIT_SIZE of "
		 "INTEGER(KIND=%d)", arg, &expr->where, k);
      return false;
    }

  return true;
}


/* If expr2 and expr3 are constants, then check that the value is less than
   or equal to bit_size(expr1).  */

static bool
less_than_bitsize2 (const char *arg1, gfc_expr *expr1, const char *arg2,
	       gfc_expr *expr2, const char *arg3, gfc_expr *expr3)
{
  int i2, i3;

  if (expr2->expr_type == EXPR_CONSTANT && expr3->expr_type == EXPR_CONSTANT)
    {
      gfc_extract_int (expr2, &i2);
      gfc_extract_int (expr3, &i3);
      i2 += i3;
      i3 = gfc_validate_kind (BT_INTEGER, expr1->ts.kind, false);
      if (i2 > gfc_integer_kinds[i3].bit_size)
	{
	  gfc_error ("%<%s + %s%> at %L must be less than or equal "
		     "to BIT_SIZE(%qs)",
		     arg2, arg3, &expr2->where, arg1);
	  return false;
	}
    }

  return true;
}

/* Make sure two expressions have the same type.  */

static bool
same_type_check (gfc_expr *e, int n, gfc_expr *f, int m, bool assoc = false)
{
  gfc_typespec *ets = &e->ts;
  gfc_typespec *fts = &f->ts;

  if (assoc)
    {
      /* Procedure pointer component expressions have the type of the interface
	 procedure. If they are being tested for association with a procedure
	 pointer (ie. not a component), the type of the procedure must be
	 determined.  */
      if (e->ts.type == BT_PROCEDURE && e->symtree->n.sym)
	ets = &e->symtree->n.sym->ts;
      if (f->ts.type == BT_PROCEDURE && f->symtree->n.sym)
	fts = &f->symtree->n.sym->ts;
    }

  if (gfc_compare_types (ets, fts))
    return true;

  gfc_error ("%qs argument of %qs intrinsic at %L must be the same type "
	     "and kind as %qs", gfc_current_intrinsic_arg[m]->name,
	     gfc_current_intrinsic, &f->where,
	     gfc_current_intrinsic_arg[n]->name);

  return false;
}


/* Make sure that an expression has a certain (nonzero) rank.  */

static bool
rank_check (gfc_expr *e, int n, int rank)
{
  if (e->rank == rank)
    return true;

  gfc_error ("%qs argument of %qs intrinsic at %L must be of rank %d",
	     gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
	     &e->where, rank);

  return false;
}


/* Make sure a variable expression is not an optional dummy argument.  */

static bool
nonoptional_check (gfc_expr *e, int n)
{
  if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must not be OPTIONAL",
		 gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
		 &e->where);
    }

  /* TODO: Recursive check on nonoptional variables?  */

  return true;
}


/* Check for ALLOCATABLE attribute.  */

static bool
allocatable_check (gfc_expr *e, int n)
{
  symbol_attribute attr;

  attr = gfc_variable_attr (e, NULL);
  if (!attr.allocatable
     || (attr.associate_var && !attr.select_rank_temporary))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be ALLOCATABLE",
		 gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
		 &e->where);
      return false;
    }

  return true;
}


/* Check that an expression has a particular kind.  */

static bool
kind_value_check (gfc_expr *e, int n, int k)
{
  if (e->ts.kind == k)
    return true;

  gfc_error ("%qs argument of %qs intrinsic at %L must be of kind %d",
	     gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic,
	     &e->where, k);

  return false;
}


/* Make sure an expression is a variable.  */

static bool
variable_check (gfc_expr *e, int n, bool allow_proc)
{
  if (e->expr_type == EXPR_VARIABLE
      && e->symtree->n.sym->attr.intent == INTENT_IN
      && (gfc_current_intrinsic_arg[n]->intent == INTENT_OUT
	  || gfc_current_intrinsic_arg[n]->intent == INTENT_INOUT))
    {
      gfc_ref *ref;
      bool pointer = e->symtree->n.sym->ts.type == BT_CLASS
		     && CLASS_DATA (e->symtree->n.sym)
		     ? CLASS_DATA (e->symtree->n.sym)->attr.class_pointer
		     : e->symtree->n.sym->attr.pointer;

      for (ref = e->ref; ref; ref = ref->next)
	{
	  if (pointer && ref->type == REF_COMPONENT)
	    break;
	  if (ref->type == REF_COMPONENT
	      && ((ref->u.c.component->ts.type == BT_CLASS
		   && CLASS_DATA (ref->u.c.component)->attr.class_pointer)
		  || (ref->u.c.component->ts.type != BT_CLASS
		      && ref->u.c.component->attr.pointer)))
	    break;
	}

      if (!ref)
	{
	  gfc_error ("%qs argument of %qs intrinsic at %L cannot be "
		     "INTENT(IN)", gfc_current_intrinsic_arg[n]->name,
		     gfc_current_intrinsic, &e->where);
	  return false;
	}
    }

  if (e->expr_type == EXPR_VARIABLE
      && e->symtree->n.sym->attr.flavor != FL_PARAMETER
      && (allow_proc || !e->symtree->n.sym->attr.function))
    return true;

  if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.function
      && e->symtree->n.sym == e->symtree->n.sym->result)
    {
      gfc_namespace *ns;
      for (ns = gfc_current_ns; ns; ns = ns->parent)
	if (ns->proc_name == e->symtree->n.sym)
	  return true;
    }

  /* F2018:R902: function reference having a data pointer result.  */
  if (e->expr_type == EXPR_FUNCTION
      && e->symtree->n.sym->attr.flavor == FL_PROCEDURE
      && e->symtree->n.sym->attr.function
      && e->symtree->n.sym->attr.pointer)
    return true;

  gfc_error ("%qs argument of %qs intrinsic at %L must be a variable",
	     gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic, &e->where);

  return false;
}


/* Check the common DIM parameter for correctness.  */

static bool
dim_check (gfc_expr *dim, int n, bool optional)
{
  if (dim == NULL)
    return true;

  if (!type_check (dim, n, BT_INTEGER))
    return false;

  if (!scalar_check (dim, n))
    return false;

  if (!optional && !nonoptional_check (dim, n))
    return false;

  return true;
}


/* If a coarray DIM parameter is a constant, make sure that it is greater than
   zero and less than or equal to the corank of the given array.  */

static bool
dim_corank_check (gfc_expr *dim, gfc_expr *array)
{
  int corank;

  gcc_assert (array->expr_type == EXPR_VARIABLE);

  if (dim->expr_type != EXPR_CONSTANT)
    return true;

  if (array->ts.type == BT_CLASS)
    return true;

  corank = gfc_get_corank (array);

  if (mpz_cmp_ui (dim->value.integer, 1) < 0
      || mpz_cmp_ui (dim->value.integer, corank) > 0)
    {
      gfc_error ("%<dim%> argument of %qs intrinsic at %L is not a valid "
		 "codimension index", gfc_current_intrinsic, &dim->where);

      return false;
    }

  return true;
}


/* If a DIM parameter is a constant, make sure that it is greater than
   zero and less than or equal to the rank of the given array.  If
   allow_assumed is zero then dim must be less than the rank of the array
   for assumed size arrays.  */

static bool
dim_rank_check (gfc_expr *dim, gfc_expr *array, int allow_assumed)
{
  gfc_array_ref *ar;
  int rank;

  if (dim == NULL)
    return true;

  if (dim->expr_type != EXPR_CONSTANT)
    return true;

  if (array->expr_type == EXPR_FUNCTION && array->value.function.isym
      && array->value.function.isym->id == GFC_ISYM_SPREAD)
    rank = array->rank + 1;
  else
    rank = array->rank;

  /* Assumed-rank array.  */
  if (rank == -1)
    rank = GFC_MAX_DIMENSIONS;

  if (array->expr_type == EXPR_VARIABLE)
    {
      ar = gfc_find_array_ref (array, true);
      if (!ar)
	return false;
      if (ar->as->type == AS_ASSUMED_SIZE
	  && !allow_assumed
	  && ar->type != AR_ELEMENT
	  && ar->type != AR_SECTION)
	rank--;
    }

  if (mpz_cmp_ui (dim->value.integer, 1) < 0
      || mpz_cmp_ui (dim->value.integer, rank) > 0)
    {
      gfc_error ("%<dim%> argument of %qs intrinsic at %L is not a valid "
		 "dimension index", gfc_current_intrinsic, &dim->where);

      return false;
    }

  return true;
}


/* Compare the size of a along dimension ai with the size of b along
   dimension bi, returning 0 if they are known not to be identical,
   and 1 if they are identical, or if this cannot be determined.  */

static int
identical_dimen_shape (gfc_expr *a, int ai, gfc_expr *b, int bi)
{
  mpz_t a_size, b_size;
  int ret;

  gcc_assert (a->rank > ai);
  gcc_assert (b->rank > bi);

  ret = 1;

  if (gfc_array_dimen_size (a, ai, &a_size))
    {
      if (gfc_array_dimen_size (b, bi, &b_size))
	{
	  if (mpz_cmp (a_size, b_size) != 0)
	    ret = 0;

	  mpz_clear (b_size);
	}
      mpz_clear (a_size);
    }
  return ret;
}

/*  Calculate the length of a character variable, including substrings.
    Strip away parentheses if necessary.  Return -1 if no length could
    be determined.  */

static long
gfc_var_strlen (const gfc_expr *a)
{
  gfc_ref *ra;

  while (a->expr_type == EXPR_OP && a->value.op.op == INTRINSIC_PARENTHESES)
    a = a->value.op.op1;

  for (ra = a->ref; ra != NULL && ra->type != REF_SUBSTRING; ra = ra->next)
    ;

  if (ra)
    {
      long start_a, end_a;

      if (!ra->u.ss.end)
	return -1;

      if ((!ra->u.ss.start || ra->u.ss.start->expr_type == EXPR_CONSTANT)
	  && ra->u.ss.end->expr_type == EXPR_CONSTANT)
	{
	  start_a = ra->u.ss.start ? mpz_get_si (ra->u.ss.start->value.integer)
				   : 1;
	  end_a = mpz_get_si (ra->u.ss.end->value.integer);
	  return (end_a < start_a) ? 0 : end_a - start_a + 1;
	}
      else if (ra->u.ss.start
	       && gfc_dep_compare_expr (ra->u.ss.start, ra->u.ss.end) == 0)
	return 1;
      else
	return -1;
    }

  if (a->ts.u.cl && a->ts.u.cl->length
      && a->ts.u.cl->length->expr_type == EXPR_CONSTANT)
    return mpz_get_si (a->ts.u.cl->length->value.integer);
  else if (a->expr_type == EXPR_CONSTANT
	   && (a->ts.u.cl == NULL || a->ts.u.cl->length == NULL))
    return a->value.character.length;
  else
    return -1;

}

/* Check whether two character expressions have the same length;
   returns true if they have or if the length cannot be determined,
   otherwise return false and raise a gfc_error.  */

bool
gfc_check_same_strlen (const gfc_expr *a, const gfc_expr *b, const char *name)
{
   long len_a, len_b;

   len_a = gfc_var_strlen(a);
   len_b = gfc_var_strlen(b);

   if (len_a == -1 || len_b == -1 || len_a == len_b)
     return true;
   else
     {
       gfc_error ("Unequal character lengths (%ld/%ld) in %s at %L",
		  len_a, len_b, name, &a->where);
       return false;
     }
}


/***** Check functions *****/

/* Check subroutine suitable for intrinsics taking a real argument and
   a kind argument for the result.  */

static bool
check_a_kind (gfc_expr *a, gfc_expr *kind, bt type)
{
  if (!type_check (a, 0, BT_REAL))
    return false;
  if (!kind_check (kind, 1, type))
    return false;

  return true;
}


/* Check subroutine suitable for ceiling, floor and nint.  */

bool
gfc_check_a_ikind (gfc_expr *a, gfc_expr *kind)
{
  return check_a_kind (a, kind, BT_INTEGER);
}


/* Check subroutine suitable for aint, anint.  */

bool
gfc_check_a_xkind (gfc_expr *a, gfc_expr *kind)
{
  return check_a_kind (a, kind, BT_REAL);
}


bool
gfc_check_abs (gfc_expr *a)
{
  if (!numeric_check (a, 0))
    return false;

  return true;
}


bool
gfc_check_achar (gfc_expr *a, gfc_expr *kind)
{
  if (a->ts.type == BT_BOZ)
    {
      if (gfc_invalid_boz (G_("BOZ literal constant at %L cannot appear in "
			   "ACHAR intrinsic subprogram"), &a->where))
	return false;

      if (!gfc_boz2int (a, gfc_default_integer_kind))
	return false;
    }

  if (!type_check (a, 0, BT_INTEGER))
    return false;

  if (!kind_check (kind, 1, BT_CHARACTER))
    return false;

  return true;
}


bool
gfc_check_access_func (gfc_expr *name, gfc_expr *mode)
{
  if (!type_check (name, 0, BT_CHARACTER)
      || !scalar_check (name, 0))
    return false;
  if (!kind_value_check (name, 0, gfc_default_character_kind))
    return false;

  if (!type_check (mode, 1, BT_CHARACTER)
      || !scalar_check (mode, 1))
    return false;
  if (!kind_value_check (mode, 1, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_all_any (gfc_expr *mask, gfc_expr *dim)
{
  if (!logical_array_check (mask, 0))
    return false;

  if (!dim_check (dim, 1, false))
    return false;

  if (!dim_rank_check (dim, mask, 0))
    return false;

  return true;
}


/* Limited checking for ALLOCATED intrinsic.  Additional checking
   is performed in intrinsic.c(sort_actual), because ALLOCATED
   has two mutually exclusive non-optional arguments.  */

bool
gfc_check_allocated (gfc_expr *array)
{
  /* Tests on allocated components of coarrays need to detour the check to
     argument of the _caf_get.  */
  if (flag_coarray == GFC_FCOARRAY_LIB && array->expr_type == EXPR_FUNCTION
      && array->value.function.isym
      && array->value.function.isym->id == GFC_ISYM_CAF_GET)
    {
      array = array->value.function.actual->expr;
      if (!array->ref)
	return false;
    }

  if (!variable_check (array, 0, false))
    return false;
  if (!allocatable_check (array, 0))
    return false;

  return true;
}


/* Common check function where the first argument must be real or
   integer and the second argument must be the same as the first.  */

bool
gfc_check_a_p (gfc_expr *a, gfc_expr *p)
{
  if (!int_or_real_check (a, 0))
    return false;

  if (a->ts.type != p->ts.type)
    {
      gfc_error ("%qs and %qs arguments of %qs intrinsic at %L must "
		 "have the same type", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		 &p->where);
      return false;
    }

  if (a->ts.kind != p->ts.kind)
    {
      if (!gfc_notify_std (GFC_STD_GNU, "Different type kinds at %L",
			   &p->where))
       return false;
    }

  return true;
}


bool
gfc_check_x_yd (gfc_expr *x, gfc_expr *y)
{
  if (!double_check (x, 0) || !double_check (y, 1))
    return false;

  return true;
}

bool
gfc_invalid_null_arg (gfc_expr *x)
{
  if (x->expr_type == EXPR_NULL)
    {
      gfc_error ("NULL at %L is not permitted as actual argument "
		 "to %qs intrinsic function", &x->where,
		 gfc_current_intrinsic);
      return true;
    }
  return false;
}

bool
gfc_check_associated (gfc_expr *pointer, gfc_expr *target)
{
  symbol_attribute attr1, attr2;
  int i;
  bool t;

  if (gfc_invalid_null_arg (pointer))
    return false;

  attr1 = gfc_expr_attr (pointer);

  if (!attr1.pointer && !attr1.proc_pointer)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be a POINTER",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &pointer->where);
      return false;
    }

  /* F2008, C1242.  */
  if (attr1.pointer && gfc_is_coindexed (pointer))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L shall not be "
		 "coindexed", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &pointer->where);
      return false;
    }

  /* Target argument is optional.  */
  if (target == NULL)
    return true;

  if (gfc_invalid_null_arg (target))
    return false;

  if (target->expr_type == EXPR_VARIABLE || target->expr_type == EXPR_FUNCTION)
    attr2 = gfc_expr_attr (target);
  else
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be a pointer "
		 "or target VARIABLE or FUNCTION",
		 gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		 &target->where);
      return false;
    }

  if (attr1.pointer && !attr2.pointer && !attr2.target)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be a POINTER "
		 "or a TARGET", gfc_current_intrinsic_arg[1]->name,
		 gfc_current_intrinsic, &target->where);
      return false;
    }

  /* F2008, C1242.  */
  if (attr1.pointer && gfc_is_coindexed (target))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L shall not be "
		 "coindexed", gfc_current_intrinsic_arg[1]->name,
		 gfc_current_intrinsic, &target->where);
      return false;
    }

  t = true;
  if (!same_type_check (pointer, 0, target, 1, true))
    t = false;
  /* F2018 C838 explicitly allows an assumed-rank variable as the first
     argument of intrinsic inquiry functions.  */
  if (pointer->rank != -1 && !rank_check (target, 0, pointer->rank))
    t = false;
  if (target->rank > 0)
    {
      for (i = 0; i < target->rank; i++)
	if (target->ref->u.ar.dimen_type[i] == DIMEN_VECTOR)
	  {
	    gfc_error ("Array section with a vector subscript at %L shall not "
		       "be the target of a pointer",
		       &target->where);
	    t = false;
	    break;
	  }
    }
  return t;
}


bool
gfc_check_atan_2 (gfc_expr *y, gfc_expr *x)
{
  /* gfc_notify_std would be a waste of time as the return value
     is seemingly used only for the generic resolution.  The error
     will be: Too many arguments.  */
  if ((gfc_option.allow_std & GFC_STD_F2008) == 0)
    return false;

  return gfc_check_atan2 (y, x);
}


bool
gfc_check_atan2 (gfc_expr *y, gfc_expr *x)
{
  if (!type_check (y, 0, BT_REAL))
    return false;
  if (!same_type_check (y, 0, x, 1))
    return false;

  return true;
}


static bool
gfc_check_atomic (gfc_expr *atom, int atom_no, gfc_expr *value, int val_no,
		  gfc_expr *stat, int stat_no)
{
  if (!scalar_check (atom, atom_no) || !scalar_check (value, val_no))
    return false;

  if (!(atom->ts.type == BT_INTEGER && atom->ts.kind == gfc_atomic_int_kind)
      && !(atom->ts.type == BT_LOGICAL
	   && atom->ts.kind == gfc_atomic_logical_kind))
    {
      gfc_error ("ATOM argument at %L to intrinsic function %s shall be an "
		 "integer of ATOMIC_INT_KIND or a logical of "
		 "ATOMIC_LOGICAL_KIND", &atom->where, gfc_current_intrinsic);
      return false;
    }

  if (!gfc_is_coarray (atom) && !gfc_is_coindexed (atom))
    {
      gfc_error ("ATOM argument at %L of the %s intrinsic function shall be a "
		 "coarray or coindexed", &atom->where, gfc_current_intrinsic);
      return false;
    }

  if (atom->ts.type != value->ts.type)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L shall have the same "
		 "type as %qs at %L", gfc_current_intrinsic_arg[val_no]->name,
		 gfc_current_intrinsic, &value->where,
		 gfc_current_intrinsic_arg[atom_no]->name, &atom->where);
      return false;
    }

  if (stat != NULL)
    {
      if (!type_check (stat, stat_no, BT_INTEGER))
	return false;
      if (!scalar_check (stat, stat_no))
	return false;
      if (!variable_check (stat, stat_no, false))
	return false;
      if (!kind_value_check (stat, stat_no, gfc_default_integer_kind))
	return false;

      if (!gfc_notify_std (GFC_STD_F2018, "STAT= argument to %s at %L",
			   gfc_current_intrinsic, &stat->where))
	return false;
    }

  return true;
}


bool
gfc_check_atomic_def (gfc_expr *atom, gfc_expr *value, gfc_expr *stat)
{
  if (atom->expr_type == EXPR_FUNCTION
      && atom->value.function.isym
      && atom->value.function.isym->id == GFC_ISYM_CAF_GET)
    atom = atom->value.function.actual->expr;

  if (!gfc_check_vardef_context (atom, false, false, false, NULL))
    {
      gfc_error ("ATOM argument of the %s intrinsic function at %L shall be "
		 "definable", gfc_current_intrinsic, &atom->where);
      return false;
    }

  return gfc_check_atomic (atom, 0, value, 1, stat, 2);
}


bool
gfc_check_atomic_op (gfc_expr *atom, gfc_expr *value, gfc_expr *stat)
{
  if (atom->ts.type != BT_INTEGER || atom->ts.kind != gfc_atomic_int_kind)
    {
      gfc_error ("ATOM argument at %L to intrinsic function %s shall be an "
		 "integer of ATOMIC_INT_KIND", &atom->where,
		 gfc_current_intrinsic);
      return false;
    }

  return gfc_check_atomic_def (atom, value, stat);
}


bool
gfc_check_atomic_ref (gfc_expr *value, gfc_expr *atom, gfc_expr *stat)
{
  if (atom->expr_type == EXPR_FUNCTION
      && atom->value.function.isym
      && atom->value.function.isym->id == GFC_ISYM_CAF_GET)
    atom = atom->value.function.actual->expr;

  if (!gfc_check_vardef_context (value, false, false, false, NULL))
    {
      gfc_error ("VALUE argument of the %s intrinsic function at %L shall be "
		 "definable", gfc_current_intrinsic, &value->where);
      return false;
    }

  return gfc_check_atomic (atom, 1, value, 0, stat, 2);
}


bool
gfc_check_image_status (gfc_expr *image, gfc_expr *team)
{
  /* IMAGE has to be a positive, scalar integer.  */
  if (!type_check (image, 0, BT_INTEGER) || !scalar_check (image, 0)
      || !positive_check (0, image))
    return false;

  if (team)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L not yet supported",
		 gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		 &team->where);
      return false;
    }
  return true;
}


bool
gfc_check_failed_or_stopped_images (gfc_expr *team, gfc_expr *kind)
{
  if (team)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L not yet supported",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &team->where);
      return false;
    }

  if (kind)
    {
      int k;

      if (!type_check (kind, 1, BT_INTEGER) || !scalar_check (kind, 1)
	  || !positive_check (1, kind))
	return false;

      /* Get the kind, reporting error on non-constant or overflow.  */
      gfc_current_locus = kind->where;
      if (gfc_extract_int (kind, &k, 1))
	return false;
      if (gfc_validate_kind (BT_INTEGER, k, true) == -1)
	{
	  gfc_error ("%qs argument of %qs intrinsic at %L shall specify a "
		     "valid integer kind", gfc_current_intrinsic_arg[1]->name,
		     gfc_current_intrinsic, &kind->where);
	  return false;
	}
    }
  return true;
}


bool
gfc_check_get_team (gfc_expr *level)
{
  if (level)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L not yet supported",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &level->where);
      return false;
    }
  return true;
}


bool
gfc_check_atomic_cas (gfc_expr *atom, gfc_expr *old, gfc_expr *compare,
		      gfc_expr *new_val,  gfc_expr *stat)
{
  if (atom->expr_type == EXPR_FUNCTION
      && atom->value.function.isym
      && atom->value.function.isym->id == GFC_ISYM_CAF_GET)
    atom = atom->value.function.actual->expr;

  if (!gfc_check_atomic (atom, 0, new_val, 3, stat, 4))
    return false;

  if (!scalar_check (old, 1) || !scalar_check (compare, 2))
    return false;

  if (!same_type_check (atom, 0, old, 1))
    return false;

  if (!same_type_check (atom, 0, compare, 2))
    return false;

  if (!gfc_check_vardef_context (atom, false, false, false, NULL))
    {
      gfc_error ("ATOM argument of the %s intrinsic function at %L shall be "
		 "definable", gfc_current_intrinsic, &atom->where);
      return false;
    }

  if (!gfc_check_vardef_context (old, false, false, false, NULL))
    {
      gfc_error ("OLD argument of the %s intrinsic function at %L shall be "
		 "definable", gfc_current_intrinsic, &old->where);
      return false;
    }

  return true;
}

bool
gfc_check_event_query (gfc_expr *event, gfc_expr *count, gfc_expr *stat)
{
  if (event->ts.type != BT_DERIVED
      || event->ts.u.derived->from_intmod != INTMOD_ISO_FORTRAN_ENV
      || event->ts.u.derived->intmod_sym_id != ISOFORTRAN_EVENT_TYPE)
    {
      gfc_error ("EVENT argument at %L to the intrinsic EVENT_QUERY "
		 "shall be of type EVENT_TYPE", &event->where);
      return false;
    }

  if (!scalar_check (event, 0))
    return false;

  if (!gfc_check_vardef_context (count, false, false, false, NULL))
    {
      gfc_error ("COUNT argument of the EVENT_QUERY intrinsic function at %L "
		 "shall be definable", &count->where);
      return false;
    }

  if (!type_check (count, 1, BT_INTEGER))
    return false;

  int i = gfc_validate_kind (BT_INTEGER, count->ts.kind, false);
  int j = gfc_validate_kind (BT_INTEGER, gfc_default_integer_kind, false);

  if (gfc_integer_kinds[i].range < gfc_integer_kinds[j].range)
    {
      gfc_error ("COUNT argument of the EVENT_QUERY intrinsic function at %L "
		 "shall have at least the range of the default integer",
		 &count->where);
      return false;
    }

  if (stat != NULL)
    {
      if (!type_check (stat, 2, BT_INTEGER))
	return false;
      if (!scalar_check (stat, 2))
	return false;
      if (!variable_check (stat, 2, false))
	return false;

      if (!gfc_notify_std (GFC_STD_F2018, "STAT= argument to %s at %L",
			   gfc_current_intrinsic, &stat->where))
	return false;
    }

  return true;
}


bool
gfc_check_atomic_fetch_op (gfc_expr *atom, gfc_expr *value, gfc_expr *old,
			   gfc_expr *stat)
{
  if (atom->expr_type == EXPR_FUNCTION
      && atom->value.function.isym
      && atom->value.function.isym->id == GFC_ISYM_CAF_GET)
    atom = atom->value.function.actual->expr;

  if (atom->ts.type != BT_INTEGER || atom->ts.kind != gfc_atomic_int_kind)
    {
      gfc_error ("ATOM argument at %L to intrinsic function %s shall be an "
		 "integer of ATOMIC_INT_KIND", &atom->where,
		 gfc_current_intrinsic);
      return false;
    }

  if (!gfc_check_atomic (atom, 0, value, 1, stat, 3))
    return false;

  if (!scalar_check (old, 2))
    return false;

  if (!same_type_check (atom, 0, old, 2))
    return false;

  if (!gfc_check_vardef_context (atom, false, false, false, NULL))
    {
      gfc_error ("ATOM argument of the %s intrinsic function at %L shall be "
		 "definable", gfc_current_intrinsic, &atom->where);
      return false;
    }

  if (!gfc_check_vardef_context (old, false, false, false, NULL))
    {
      gfc_error ("OLD argument of the %s intrinsic function at %L shall be "
		 "definable", gfc_current_intrinsic, &old->where);
      return false;
    }

  return true;
}


/* BESJN and BESYN functions.  */

bool
gfc_check_besn (gfc_expr *n, gfc_expr *x)
{
  if (!type_check (n, 0, BT_INTEGER))
    return false;
  if (n->expr_type == EXPR_CONSTANT)
    {
      int i;
      gfc_extract_int (n, &i);
      if (i < 0 && !gfc_notify_std (GFC_STD_GNU, "Negative argument "
				    "N at %L", &n->where))
	return false;
    }

  if (!type_check (x, 1, BT_REAL))
    return false;

  return true;
}


/* Transformational version of the Bessel JN and YN functions.  */

bool
gfc_check_bessel_n2 (gfc_expr *n1, gfc_expr *n2, gfc_expr *x)
{
  if (!type_check (n1, 0, BT_INTEGER))
    return false;
  if (!scalar_check (n1, 0))
    return false;
  if (!nonnegative_check ("N1", n1))
    return false;

  if (!type_check (n2, 1, BT_INTEGER))
    return false;
  if (!scalar_check (n2, 1))
    return false;
  if (!nonnegative_check ("N2", n2))
    return false;

  if (!type_check (x, 2, BT_REAL))
    return false;
  if (!scalar_check (x, 2))
    return false;

  return true;
}


bool
gfc_check_bge_bgt_ble_blt (gfc_expr *i, gfc_expr *j)
{
  extern int gfc_max_integer_kind;

  /* If i and j are both BOZ, convert to widest INTEGER.  */
  if (i->ts.type == BT_BOZ && j->ts.type == BT_BOZ)
    {
      if (!gfc_boz2int (i, gfc_max_integer_kind))
	return false;
      if (!gfc_boz2int (j, gfc_max_integer_kind))
	return false;
    }

  /* If i is BOZ and j is integer, convert i to type of j.  */
  if (i->ts.type == BT_BOZ && j->ts.type == BT_INTEGER
      && !gfc_boz2int (i, j->ts.kind))
    return false;

  /* If j is BOZ and i is integer, convert j to type of i.  */
  if (j->ts.type == BT_BOZ && i->ts.type == BT_INTEGER
      && !gfc_boz2int (j, i->ts.kind))
    return false;

  if (!type_check (i, 0, BT_INTEGER))
    return false;

  if (!type_check (j, 1, BT_INTEGER))
    return false;

  return true;
}


bool
gfc_check_bitfcn (gfc_expr *i, gfc_expr *pos)
{
  if (!type_check (i, 0, BT_INTEGER))
    return false;

  if (!type_check (pos, 1, BT_INTEGER))
    return false;

  if (!nonnegative_check ("pos", pos))
    return false;

  if (!less_than_bitsize1 ("i", i, "pos", pos, false))
    return false;

  return true;
}


bool
gfc_check_char (gfc_expr *i, gfc_expr *kind)
{
  if (i->ts.type == BT_BOZ)
    {
      if (gfc_invalid_boz (G_("BOZ literal constant at %L cannot appear in "
			   "CHAR intrinsic subprogram"), &i->where))
	return false;

      if (!gfc_boz2int (i, gfc_default_integer_kind))
	return false;
    }

  if (!type_check (i, 0, BT_INTEGER))
    return false;

  if (!kind_check (kind, 1, BT_CHARACTER))
    return false;

  return true;
}


bool
gfc_check_chdir (gfc_expr *dir)
{
  if (!type_check (dir, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (dir, 0, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_chdir_sub (gfc_expr *dir, gfc_expr *status)
{
  if (!type_check (dir, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (dir, 0, gfc_default_character_kind))
    return false;

  if (status == NULL)
    return true;

  if (!type_check (status, 1, BT_INTEGER))
    return false;
  if (!scalar_check (status, 1))
    return false;

  return true;
}


bool
gfc_check_chmod (gfc_expr *name, gfc_expr *mode)
{
  if (!type_check (name, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (name, 0, gfc_default_character_kind))
    return false;

  if (!type_check (mode, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (mode, 1, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_chmod_sub (gfc_expr *name, gfc_expr *mode, gfc_expr *status)
{
  if (!type_check (name, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (name, 0, gfc_default_character_kind))
    return false;

  if (!type_check (mode, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (mode, 1, gfc_default_character_kind))
    return false;

  if (status == NULL)
    return true;

  if (!type_check (status, 2, BT_INTEGER))
    return false;

  if (!scalar_check (status, 2))
    return false;

  return true;
}


bool
gfc_check_cmplx (gfc_expr *x, gfc_expr *y, gfc_expr *kind)
{
  int k;

  /* Check kind first, because it may be needed in conversion of a BOZ.  */
  if (kind)
    {
      if (!kind_check (kind, 2, BT_COMPLEX))
	return false;
      gfc_extract_int (kind, &k);
    }
  else
    k = gfc_default_complex_kind;

  if (x->ts.type == BT_BOZ && !gfc_boz2real (x, k))
    return false;

  if (!numeric_check (x, 0))
    return false;

  if (y != NULL)
    {
      if (y->ts.type == BT_BOZ && !gfc_boz2real (y, k))
	return false;

      if (!numeric_check (y, 1))
	return false;

      if (x->ts.type == BT_COMPLEX)
	{
	  gfc_error ("%qs argument of %qs intrinsic at %L must not be "
		     "present if %<x%> is COMPLEX",
		     gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		     &y->where);
	  return false;
	}

      if (y->ts.type == BT_COMPLEX)
	{
	  gfc_error ("%qs argument of %qs intrinsic at %L must have a type "
		     "of either REAL or INTEGER",
		     gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		     &y->where);
	  return false;
	}
    }

  if (!kind && warn_conversion
      && x->ts.type == BT_REAL && x->ts.kind > gfc_default_real_kind)
    gfc_warning_now (OPT_Wconversion, "Conversion from %s to default-kind "
		     "COMPLEX(%d) at %L might lose precision, consider using "
		     "the KIND argument", gfc_typename (&x->ts),
		     gfc_default_real_kind, &x->where);
  else if (y && !kind && warn_conversion
	   && y->ts.type == BT_REAL && y->ts.kind > gfc_default_real_kind)
    gfc_warning_now (OPT_Wconversion, "Conversion from %s to default-kind "
		     "COMPLEX(%d) at %L might lose precision, consider using "
		     "the KIND argument", gfc_typename (&y->ts),
		     gfc_default_real_kind, &y->where);
  return true;
}


static bool
check_co_collective (gfc_expr *a, gfc_expr *image_idx, gfc_expr *stat,
		    gfc_expr *errmsg, bool co_reduce)
{
  if (!variable_check (a, 0, false))
    return false;

  if (!gfc_check_vardef_context (a, false, false, false, "argument 'A' with "
				 "INTENT(INOUT)"))
    return false;

  /* Fortran 2008, 12.5.2.4, paragraph 18.  */
  if (gfc_has_vector_subscript (a))
    {
      gfc_error ("Argument %<A%> with INTENT(INOUT) at %L of the intrinsic "
		 "subroutine %s shall not have a vector subscript",
		 &a->where, gfc_current_intrinsic);
      return false;
    }

  if (gfc_is_coindexed (a))
    {
      gfc_error ("The A argument at %L to the intrinsic %s shall not be "
		 "coindexed", &a->where, gfc_current_intrinsic);
      return false;
    }

  if (image_idx != NULL)
    {
      if (!type_check (image_idx, co_reduce ? 2 : 1, BT_INTEGER))
	return false;
      if (!scalar_check (image_idx, co_reduce ? 2 : 1))
	return false;
    }

  if (stat != NULL)
    {
      if (!type_check (stat, co_reduce ? 3 : 2, BT_INTEGER))
	return false;
      if (!scalar_check (stat, co_reduce ? 3 : 2))
	return false;
      if (!variable_check (stat, co_reduce ? 3 : 2, false))
	return false;
      if (stat->ts.kind != 4)
	{
	  gfc_error ("The stat= argument at %L must be a kind=4 integer "
		     "variable", &stat->where);
	  return false;
	}
    }

  if (errmsg != NULL)
    {
      if (!type_check (errmsg, co_reduce ? 4 : 3, BT_CHARACTER))
	return false;
      if (!scalar_check (errmsg, co_reduce ? 4 : 3))
	return false;
      if (!variable_check (errmsg, co_reduce ? 4 : 3, false))
	return false;
      if (errmsg->ts.kind != 1)
	{
	  gfc_error ("The errmsg= argument at %L must be a default-kind "
		     "character variable", &errmsg->where);
	  return false;
	}
    }

  if (flag_coarray == GFC_FCOARRAY_NONE)
    {
      gfc_fatal_error ("Coarrays disabled at %L, use %<-fcoarray=%> to enable",
		       &a->where);
      return false;
    }

  return true;
}


bool
gfc_check_co_broadcast (gfc_expr *a, gfc_expr *source_image, gfc_expr *stat,
			gfc_expr *errmsg)
{
  if (a->ts.type == BT_CLASS || gfc_expr_attr (a).alloc_comp)
    {
      gfc_error ("Support for the A argument at %L which is polymorphic A "
		 "argument or has allocatable components is not yet "
		 "implemented", &a->where);
      return false;
    }
  return check_co_collective (a, source_image, stat, errmsg, false);
}


bool
gfc_check_co_reduce (gfc_expr *a, gfc_expr *op, gfc_expr *result_image,
		     gfc_expr *stat, gfc_expr *errmsg)
{
  symbol_attribute attr;
  gfc_formal_arglist *formal;
  gfc_symbol *sym;

  if (a->ts.type == BT_CLASS)
    {
      gfc_error ("The A argument at %L of CO_REDUCE shall not be polymorphic",
		 &a->where);
      return false;
    }

  if (gfc_expr_attr (a).alloc_comp)
    {
      gfc_error ("Support for the A argument at %L with allocatable components"
                 " is not yet implemented", &a->where);
      return false;
    }

  if (!check_co_collective (a, result_image, stat, errmsg, true))
    return false;

  if (!gfc_resolve_expr (op))
    return false;

  attr = gfc_expr_attr (op);
  if (!attr.pure || !attr.function)
    {
      gfc_error ("OPERATOR argument at %L must be a PURE function",
		 &op->where);
      return false;
    }

  if (attr.intrinsic)
    {
      /* None of the intrinsics fulfills the criteria of taking two arguments,
	 returning the same type and kind as the arguments and being permitted
	 as actual argument.  */
      gfc_error ("Intrinsic function %s at %L is not permitted for CO_REDUCE",
		 op->symtree->n.sym->name, &op->where);
      return false;
    }

  if (gfc_is_proc_ptr_comp (op))
    {
      gfc_component *comp = gfc_get_proc_ptr_comp (op);
      sym = comp->ts.interface;
    }
  else
    sym = op->symtree->n.sym;

  formal = sym->formal;

  if (!formal || !formal->next || formal->next->next)
    {
      gfc_error ("The function passed as OPERATOR at %L shall have two "
		 "arguments", &op->where);
      return false;
    }

  if (sym->result->ts.type == BT_UNKNOWN)
    gfc_set_default_type (sym->result, 0, NULL);

  if (!gfc_compare_types (&a->ts, &sym->result->ts))
    {
      gfc_error ("The A argument at %L has type %s but the function passed as "
		 "OPERATOR at %L returns %s",
		 &a->where, gfc_typename (a), &op->where,
		 gfc_typename (&sym->result->ts));
      return false;
    }
  if (!gfc_compare_types (&a->ts, &formal->sym->ts)
      || !gfc_compare_types (&a->ts, &formal->next->sym->ts))
    {
      gfc_error ("The function passed as OPERATOR at %L has arguments of type "
		 "%s and %s but shall have type %s", &op->where,
		 gfc_typename (&formal->sym->ts),
		 gfc_typename (&formal->next->sym->ts), gfc_typename (a));
      return false;
    }
  if (op->rank || attr.allocatable || attr.pointer || formal->sym->as
      || formal->next->sym->as || formal->sym->attr.allocatable
      || formal->next->sym->attr.allocatable || formal->sym->attr.pointer
      || formal->next->sym->attr.pointer)
    {
      gfc_error ("The function passed as OPERATOR at %L shall have scalar "
		 "nonallocatable nonpointer arguments and return a "
		 "nonallocatable nonpointer scalar", &op->where);
      return false;
    }

  if (formal->sym->attr.value != formal->next->sym->attr.value)
    {
      gfc_error ("The function passed as OPERATOR at %L shall have the VALUE "
		 "attribute either for none or both arguments", &op->where);
      return false;
    }

  if (formal->sym->attr.target != formal->next->sym->attr.target)
    {
      gfc_error ("The function passed as OPERATOR at %L shall have the TARGET "
		 "attribute either for none or both arguments", &op->where);
      return false;
    }

  if (formal->sym->attr.asynchronous != formal->next->sym->attr.asynchronous)
    {
      gfc_error ("The function passed as OPERATOR at %L shall have the "
		 "ASYNCHRONOUS attribute either for none or both arguments",
		 &op->where);
      return false;
    }

  if (formal->sym->attr.optional || formal->next->sym->attr.optional)
    {
      gfc_error ("The function passed as OPERATOR at %L shall not have the "
		 "OPTIONAL attribute for either of the arguments", &op->where);
      return false;
    }

  if (a->ts.type == BT_CHARACTER)
    {
      gfc_charlen *cl;
      unsigned long actual_size, formal_size1, formal_size2, result_size;

      cl = a->ts.u.cl;
      actual_size = cl && cl->length && cl->length->expr_type == EXPR_CONSTANT
		     ? mpz_get_ui (cl->length->value.integer) : 0;

      cl = formal->sym->ts.u.cl;
      formal_size1 = cl && cl->length && cl->length->expr_type == EXPR_CONSTANT
		     ? mpz_get_ui (cl->length->value.integer) : 0;

      cl = formal->next->sym->ts.u.cl;
      formal_size2 = cl && cl->length && cl->length->expr_type == EXPR_CONSTANT
		     ? mpz_get_ui (cl->length->value.integer) : 0;

      cl = sym->ts.u.cl;
      result_size = cl && cl->length && cl->length->expr_type == EXPR_CONSTANT
		    ? mpz_get_ui (cl->length->value.integer) : 0;

      if (actual_size
	  && ((formal_size1 && actual_size != formal_size1)
	       || (formal_size2 && actual_size != formal_size2)))
	{
	  gfc_error ("The character length of the A argument at %L and of the "
		     "arguments of the OPERATOR at %L shall be the same",
		     &a->where, &op->where);
	  return false;
	}
      if (actual_size && result_size && actual_size != result_size)
	{
	  gfc_error ("The character length of the A argument at %L and of the "
		     "function result of the OPERATOR at %L shall be the same",
		     &a->where, &op->where);
	  return false;
	}
    }

  return true;
}


bool
gfc_check_co_minmax (gfc_expr *a, gfc_expr *result_image, gfc_expr *stat,
		     gfc_expr *errmsg)
{
  if (a->ts.type != BT_INTEGER && a->ts.type != BT_REAL
      && a->ts.type != BT_CHARACTER)
    {
       gfc_error ("%qs argument of %qs intrinsic at %L shall be of type "
		  "integer, real or character",
		  gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		  &a->where);
       return false;
    }
  return check_co_collective (a, result_image, stat, errmsg, false);
}


bool
gfc_check_co_sum (gfc_expr *a, gfc_expr *result_image, gfc_expr *stat,
		  gfc_expr *errmsg)
{
  if (!numeric_check (a, 0))
    return false;
  return check_co_collective (a, result_image, stat, errmsg, false);
}


bool
gfc_check_complex (gfc_expr *x, gfc_expr *y)
{
  if (!boz_args_check (x, y))
    return false;

  if (x->ts.type == BT_BOZ)
    {
      if (gfc_invalid_boz (G_("BOZ constant at %L cannot appear in the COMPLEX"
			   " intrinsic subprogram"), &x->where))
	{
	  reset_boz (x);
	  return false;
        }
      if (y->ts.type == BT_INTEGER && !gfc_boz2int (x, y->ts.kind))
	return false;
      if (y->ts.type == BT_REAL && !gfc_boz2real (x, y->ts.kind))
    	return false;
    }

  if (y->ts.type == BT_BOZ)
    {
      if (gfc_invalid_boz (G_("BOZ constant at %L cannot appear in the COMPLEX"
			   " intrinsic subprogram"), &y->where))
	{
	  reset_boz (y);
	  return false;
	}
      if (x->ts.type == BT_INTEGER && !gfc_boz2int (y, x->ts.kind))
	return false;
      if (x->ts.type == BT_REAL && !gfc_boz2real (y, x->ts.kind))
	return false;
    }

  if (!int_or_real_check (x, 0))
    return false;
  if (!scalar_check (x, 0))
    return false;

  if (!int_or_real_check (y, 1))
    return false;
  if (!scalar_check (y, 1))
    return false;

  return true;
}


bool
gfc_check_count (gfc_expr *mask, gfc_expr *dim, gfc_expr *kind)
{
  if (!logical_array_check (mask, 0))
    return false;
  if (!dim_check (dim, 1, false))
    return false;
  if (!dim_rank_check (dim, mask, 0))
    return false;
  if (!kind_check (kind, 2, BT_INTEGER))
    return false;
  if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
			       "with KIND argument at %L",
			       gfc_current_intrinsic, &kind->where))
    return false;

  return true;
}


bool
gfc_check_cshift (gfc_expr *array, gfc_expr *shift, gfc_expr *dim)
{
  if (!array_check (array, 0))
    return false;

  if (!type_check (shift, 1, BT_INTEGER))
    return false;

  if (!dim_check (dim, 2, true))
    return false;

  if (!dim_rank_check (dim, array, false))
    return false;

  if (array->rank == 1 || shift->rank == 0)
    {
      if (!scalar_check (shift, 1))
	return false;
    }
  else if (shift->rank == array->rank - 1)
    {
      int d;
      if (!dim)
	d = 1;
      else if (dim->expr_type == EXPR_CONSTANT)
	gfc_extract_int (dim, &d);
      else
	d = -1;

      if (d > 0)
	{
	  int i, j;
	  for (i = 0, j = 0; i < array->rank; i++)
	    if (i != d - 1)
	      {
		if (!identical_dimen_shape (array, i, shift, j))
		  {
		    gfc_error ("%qs argument of %qs intrinsic at %L has "
			       "invalid shape in dimension %d (%ld/%ld)",
			       gfc_current_intrinsic_arg[1]->name,
			       gfc_current_intrinsic, &shift->where, i + 1,
			       mpz_get_si (array->shape[i]),
			       mpz_get_si (shift->shape[j]));
		    return false;
		  }

		j += 1;
	      }
	}
    }
  else
    {
      gfc_error ("%qs argument of intrinsic %qs at %L of must have rank "
		 "%d or be a scalar", gfc_current_intrinsic_arg[1]->name,
		 gfc_current_intrinsic, &shift->where, array->rank - 1);
      return false;
    }

  return true;
}


bool
gfc_check_ctime (gfc_expr *time)
{
  if (!scalar_check (time, 0))
    return false;

  if (!type_check (time, 0, BT_INTEGER))
    return false;

  return true;
}


bool gfc_check_datan2 (gfc_expr *y, gfc_expr *x)
{
  if (!double_check (y, 0) || !double_check (x, 1))
    return false;

  return true;
}

bool
gfc_check_dcmplx (gfc_expr *x, gfc_expr *y)
{
  if (x->ts.type == BT_BOZ && !gfc_boz2real (x, gfc_default_double_kind))
    return false;

  if (!numeric_check (x, 0))
    return false;

  if (y != NULL)
    {
      if (y->ts.type == BT_BOZ && !gfc_boz2real (y, gfc_default_double_kind))
	return false;

      if (!numeric_check (y, 1))
	return false;

      if (x->ts.type == BT_COMPLEX)
	{
	  gfc_error ("%qs argument of %qs intrinsic at %L must not be "
		     "present if %<x%> is COMPLEX",
		     gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		     &y->where);
	  return false;
	}

      if (y->ts.type == BT_COMPLEX)
	{
	  gfc_error ("%qs argument of %qs intrinsic at %L must have a type "
		     "of either REAL or INTEGER",
		     gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		     &y->where);
	  return false;
	}
    }

  return true;
}


bool
gfc_check_dble (gfc_expr *x)
{
  if (x->ts.type == BT_BOZ && !gfc_boz2real (x, gfc_default_double_kind))
    return false;

  if (!numeric_check (x, 0))
    return false;

  return true;
}


bool
gfc_check_digits (gfc_expr *x)
{
  if (!int_or_real_check (x, 0))
    return false;

  return true;
}


bool
gfc_check_dot_product (gfc_expr *vector_a, gfc_expr *vector_b)
{
  switch (vector_a->ts.type)
    {
    case BT_LOGICAL:
      if (!type_check (vector_b, 1, BT_LOGICAL))
	return false;
      break;

    case BT_INTEGER:
    case BT_REAL:
    case BT_COMPLEX:
      if (!numeric_check (vector_b, 1))
	return false;
      break;

    default:
      gfc_error ("%qs argument of %qs intrinsic at %L must be numeric "
		 "or LOGICAL", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &vector_a->where);
      return false;
    }

  if (!rank_check (vector_a, 0, 1))
    return false;

  if (!rank_check (vector_b, 1, 1))
    return false;

  if (! identical_dimen_shape (vector_a, 0, vector_b, 0))
    {
      gfc_error ("Different shape for arguments %qs and %qs at %L for "
		 "intrinsic %<dot_product%>",
		 gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic_arg[1]->name, &vector_a->where);
      return false;
    }

  return true;
}


bool
gfc_check_dprod (gfc_expr *x, gfc_expr *y)
{
  if (!type_check (x, 0, BT_REAL)
      || !type_check (y, 1, BT_REAL))
    return false;

  if (x->ts.kind != gfc_default_real_kind)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be default "
		 "real", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &x->where);
      return false;
    }

  if (y->ts.kind != gfc_default_real_kind)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be default "
		 "real", gfc_current_intrinsic_arg[1]->name,
		 gfc_current_intrinsic, &y->where);
      return false;
    }

  return true;
}

bool
gfc_check_dshift (gfc_expr *i, gfc_expr *j, gfc_expr *shift)
{
  /* i and j cannot both be BOZ literal constants.  */
  if (!boz_args_check (i, j))
    return false;

  /* If i is BOZ and j is integer, convert i to type of j.  If j is not
     an integer, clear the BOZ; otherwise, check that i is an integer.  */
  if (i->ts.type == BT_BOZ)
    {
      if (j->ts.type != BT_INTEGER)
        reset_boz (i);
      else if (!gfc_boz2int (i, j->ts.kind))
	return false;
    }
  else if (!type_check (i, 0, BT_INTEGER))
    {
      if (j->ts.type == BT_BOZ)
	reset_boz (j);
      return false;
    }

  /* If j is BOZ and i is integer, convert j to type of i.  If i is not
     an integer, clear the BOZ; otherwise, check that i is an integer.  */
  if (j->ts.type == BT_BOZ)
    {
      if (i->ts.type != BT_INTEGER)
        reset_boz (j);
      else if (!gfc_boz2int (j, i->ts.kind))
	return false;
    }
  else if (!type_check (j, 1, BT_INTEGER))
    return false;

  if (!same_type_check (i, 0, j, 1))
    return false;

  if (!type_check (shift, 2, BT_INTEGER))
    return false;

  if (!nonnegative_check ("SHIFT", shift))
    return false;

  if (!less_than_bitsize1 ("I", i, "SHIFT", shift, true))
    return false;

  return true;
}


bool
gfc_check_eoshift (gfc_expr *array, gfc_expr *shift, gfc_expr *boundary,
		   gfc_expr *dim)
{
  int d;

  if (!array_check (array, 0))
    return false;

  if (!type_check (shift, 1, BT_INTEGER))
    return false;

  if (!dim_check (dim, 3, true))
    return false;

  if (!dim_rank_check (dim, array, false))
    return false;

  if (!dim)
    d = 1;
  else if (dim->expr_type == EXPR_CONSTANT)
    gfc_extract_int (dim, &d);
  else
    d = -1;

  if (array->rank == 1 || shift->rank == 0)
    {
      if (!scalar_check (shift, 1))
	return false;
    }
  else if (shift->rank == array->rank - 1)
    {
      if (d > 0)
	{
	  int i, j;
	  for (i = 0, j = 0; i < array->rank; i++)
	    if (i != d - 1)
	      {
		if (!identical_dimen_shape (array, i, shift, j))
		  {
		    gfc_error ("%qs argument of %qs intrinsic at %L has "
			       "invalid shape in dimension %d (%ld/%ld)",
			       gfc_current_intrinsic_arg[1]->name,
			       gfc_current_intrinsic, &shift->where, i + 1,
			       mpz_get_si (array->shape[i]),
			       mpz_get_si (shift->shape[j]));
		    return false;
		  }

		j += 1;
	      }
	}
    }
  else
    {
      gfc_error ("%qs argument of intrinsic %qs at %L of must have rank "
		 "%d or be a scalar", gfc_current_intrinsic_arg[1]->name,
		 gfc_current_intrinsic, &shift->where, array->rank - 1);
      return false;
    }

  if (boundary != NULL)
    {
      if (!same_type_check (array, 0, boundary, 2))
	return false;

      /* Reject unequal string lengths and emit a better error message than
       gfc_check_same_strlen would.  */
      if (array->ts.type == BT_CHARACTER)
	{
	  ssize_t len_a, len_b;

	  len_a = gfc_var_strlen (array);
	  len_b = gfc_var_strlen (boundary);
	  if (len_a != -1 && len_b != -1 && len_a != len_b)
	    {
	      gfc_error ("%qs must be of same type and kind as %qs at %L in %qs",
			 gfc_current_intrinsic_arg[2]->name,
			 gfc_current_intrinsic_arg[0]->name,
			 &boundary->where, gfc_current_intrinsic);
	      return false;
	    }
	}

      if (array->rank == 1 || boundary->rank == 0)
	{
	  if (!scalar_check (boundary, 2))
	    return false;
	}
      else if (boundary->rank == array->rank - 1)
	{
	  if (d > 0)
	    {
	      int i,j;
	      for (i = 0, j = 0; i < array->rank; i++)
		{
		  if (i != d - 1)
		    {
		      if (!identical_dimen_shape (array, i, boundary, j))
			{
			  gfc_error ("%qs argument of %qs intrinsic at %L has "
				     "invalid shape in dimension %d (%ld/%ld)",
				     gfc_current_intrinsic_arg[2]->name,
				     gfc_current_intrinsic, &shift->where, i+1,
				     mpz_get_si (array->shape[i]),
				     mpz_get_si (boundary->shape[j]));
			  return false;
			}
		      j += 1;
		    }
		}
	    }
	}
      else
	{
	  gfc_error ("%qs argument of intrinsic %qs at %L of must have "
		     "rank %d or be a scalar",
		     gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		     &shift->where, array->rank - 1);
	  return false;
	}
    }
  else
    {
      switch (array->ts.type)
	{
	case BT_INTEGER:
	case BT_LOGICAL:
	case BT_REAL:
	case BT_COMPLEX:
	case BT_CHARACTER:
	  break;

	default:
	  gfc_error ("Missing %qs argument to %qs intrinsic at %L for %qs "
		     "of type %qs", gfc_current_intrinsic_arg[2]->name,
		     gfc_current_intrinsic, &array->where,
		     gfc_current_intrinsic_arg[0]->name,
		     gfc_typename (array));
	  return false;
	}
    }

  return true;
}


bool
gfc_check_float (gfc_expr *a)
{
  if (a->ts.type == BT_BOZ)
    {
      if (gfc_invalid_boz (G_("BOZ literal constant at %L cannot appear in the"
			   " FLOAT intrinsic subprogram"), &a->where))
	{
	  reset_boz (a);
	  return false;
	}
      if (!gfc_boz2int (a, gfc_default_integer_kind))
	return false;
    }

  if (!type_check (a, 0, BT_INTEGER))
    return false;

  if ((a->ts.kind != gfc_default_integer_kind)
      && !gfc_notify_std (GFC_STD_GNU, "non-default INTEGER "
			  "kind argument to %s intrinsic at %L",
			  gfc_current_intrinsic, &a->where))
    return false;

  return true;
}

/* A single complex argument.  */

bool
gfc_check_fn_c (gfc_expr *a)
{
  if (!type_check (a, 0, BT_COMPLEX))
    return false;

  return true;
}


/* A single real argument.  */

bool
gfc_check_fn_r (gfc_expr *a)
{
  if (!type_check (a, 0, BT_REAL))
    return false;

  return true;
}

/* A single double argument.  */

bool
gfc_check_fn_d (gfc_expr *a)
{
  if (!double_check (a, 0))
    return false;

  return true;
}

/* A single real or complex argument.  */

bool
gfc_check_fn_rc (gfc_expr *a)
{
  if (!real_or_complex_check (a, 0))
    return false;

  return true;
}


bool
gfc_check_fn_rc2008 (gfc_expr *a)
{
  if (!real_or_complex_check (a, 0))
    return false;

  if (a->ts.type == BT_COMPLEX
      && !gfc_notify_std (GFC_STD_F2008, "COMPLEX argument %qs "
			  "of %qs intrinsic at %L",
			  gfc_current_intrinsic_arg[0]->name,
			  gfc_current_intrinsic, &a->where))
    return false;

  return true;
}


bool
gfc_check_fnum (gfc_expr *unit)
{
  if (!type_check (unit, 0, BT_INTEGER))
    return false;

  if (!scalar_check (unit, 0))
    return false;

  return true;
}


bool
gfc_check_huge (gfc_expr *x)
{
  if (!int_or_real_check (x, 0))
    return false;

  return true;
}


bool
gfc_check_hypot (gfc_expr *x, gfc_expr *y)
{
  if (!type_check (x, 0, BT_REAL))
    return false;
  if (!same_type_check (x, 0, y, 1))
    return false;

  return true;
}


/* Check that the single argument is an integer.  */

bool
gfc_check_i (gfc_expr *i)
{
  if (!type_check (i, 0, BT_INTEGER))
    return false;

  return true;
}


bool
gfc_check_iand_ieor_ior (gfc_expr *i, gfc_expr *j)
{
  /* i and j cannot both be BOZ literal constants.  */
  if (!boz_args_check (i, j))
    return false;

  /* If i is BOZ and j is integer, convert i to type of j.  */
  if (i->ts.type == BT_BOZ && j->ts.type == BT_INTEGER
      && !gfc_boz2int (i, j->ts.kind))
    return false;

  /* If j is BOZ and i is integer, convert j to type of i.  */
  if (j->ts.type == BT_BOZ && i->ts.type == BT_INTEGER
      && !gfc_boz2int (j, i->ts.kind))
    return false;

  if (!type_check (i, 0, BT_INTEGER))
    return false;

  if (!type_check (j, 1, BT_INTEGER))
    return false;

  if (i->ts.kind != j->ts.kind)
    {
      gfc_error ("Arguments of %qs have different kind type parameters "
		 "at %L", gfc_current_intrinsic, &i->where);
	return false;
    }

  return true;
}


bool
gfc_check_ibits (gfc_expr *i, gfc_expr *pos, gfc_expr *len)
{
  if (!type_check (i, 0, BT_INTEGER))
    return false;

  if (!type_check (pos, 1, BT_INTEGER))
    return false;

  if (!type_check (len, 2, BT_INTEGER))
    return false;

  if (!nonnegative_check ("pos", pos))
    return false;

  if (!nonnegative_check ("len", len))
    return false;

  if (!less_than_bitsize2 ("i", i, "pos", pos, "len", len))
    return false;

  return true;
}


bool
gfc_check_ichar_iachar (gfc_expr *c, gfc_expr *kind)
{
  int i;

  if (!type_check (c, 0, BT_CHARACTER))
    return false;

  if (!kind_check (kind, 1, BT_INTEGER))
    return false;

  if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
			       "with KIND argument at %L",
			       gfc_current_intrinsic, &kind->where))
    return false;

  if (c->expr_type == EXPR_VARIABLE || c->expr_type == EXPR_SUBSTRING)
    {
      gfc_expr *start;
      gfc_expr *end;
      gfc_ref *ref;

      /* Substring references don't have the charlength set.  */
      ref = c->ref;
      while (ref && ref->type != REF_SUBSTRING)
	ref = ref->next;

      gcc_assert (ref == NULL || ref->type == REF_SUBSTRING);

      if (!ref)
	{
	  /* Check that the argument is length one.  Non-constant lengths
	     can't be checked here, so assume they are ok.  */
	  if (c->ts.u.cl && c->ts.u.cl->length)
	    {
	      /* If we already have a length for this expression then use it.  */
	      if (c->ts.u.cl->length->expr_type != EXPR_CONSTANT)
		return true;
	      i = mpz_get_si (c->ts.u.cl->length->value.integer);
	    }
	  else
	    return true;
	}
      else
	{
	  start = ref->u.ss.start;
	  end = ref->u.ss.end;

	  gcc_assert (start);
	  if (end == NULL || end->expr_type != EXPR_CONSTANT
	      || start->expr_type != EXPR_CONSTANT)
	    return true;

	  i = mpz_get_si (end->value.integer) + 1
	    - mpz_get_si (start->value.integer);
	}
    }
  else
    return true;

  if (i != 1)
    {
      gfc_error ("Argument of %s at %L must be of length one",
		 gfc_current_intrinsic, &c->where);
      return false;
    }

  return true;
}


bool
gfc_check_idnint (gfc_expr *a)
{
  if (!double_check (a, 0))
    return false;

  return true;
}


bool
gfc_check_index (gfc_expr *string, gfc_expr *substring, gfc_expr *back,
		 gfc_expr *kind)
{
  if (!type_check (string, 0, BT_CHARACTER)
      || !type_check (substring, 1, BT_CHARACTER))
    return false;

  if (back != NULL && !type_check (back, 2, BT_LOGICAL))
    return false;

  if (!kind_check (kind, 3, BT_INTEGER))
    return false;
  if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
			       "with KIND argument at %L",
			       gfc_current_intrinsic, &kind->where))
    return false;

  if (string->ts.kind != substring->ts.kind)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be the same "
		 "kind as %qs", gfc_current_intrinsic_arg[1]->name,
		 gfc_current_intrinsic, &substring->where,
		 gfc_current_intrinsic_arg[0]->name);
      return false;
    }

  return true;
}


bool
gfc_check_int (gfc_expr *x, gfc_expr *kind)
{
  /* BOZ is dealt within simplify_int*.  */
  if (x->ts.type == BT_BOZ)
    return true;

  if (!numeric_check (x, 0))
    return false;

  if (!kind_check (kind, 1, BT_INTEGER))
    return false;

  return true;
}


bool
gfc_check_intconv (gfc_expr *x)
{
  if (strcmp (gfc_current_intrinsic, "short") == 0
      || strcmp (gfc_current_intrinsic, "long") == 0)
    {
      gfc_error ("%qs intrinsic subprogram at %L has been deprecated.  "
		 "Use INT intrinsic subprogram.", gfc_current_intrinsic,
		 &x->where);
      return false;
    }

  /* BOZ is dealt within simplify_int*.  */
  if (x->ts.type == BT_BOZ)
    return true;

  if (!numeric_check (x, 0))
    return false;

  return true;
}

bool
gfc_check_ishft (gfc_expr *i, gfc_expr *shift)
{
  if (!type_check (i, 0, BT_INTEGER)
      || !type_check (shift, 1, BT_INTEGER))
    return false;

  if (!less_than_bitsize1 ("I", i, NULL, shift, true))
    return false;

  return true;
}


bool
gfc_check_ishftc (gfc_expr *i, gfc_expr *shift, gfc_expr *size)
{
  if (!type_check (i, 0, BT_INTEGER)
      || !type_check (shift, 1, BT_INTEGER))
    return false;

  if (size != NULL)
    {
      int i2, i3;

      if (!type_check (size, 2, BT_INTEGER))
	return false;

      if (!less_than_bitsize1 ("I", i, "SIZE", size, true))
	return false;

      if (size->expr_type == EXPR_CONSTANT)
	{
	  gfc_extract_int (size, &i3);
	  if (i3 <= 0)
	    {
	      gfc_error ("SIZE at %L must be positive", &size->where);
	      return false;
	    }

	  if (shift->expr_type == EXPR_CONSTANT)
	    {
	      gfc_extract_int (shift, &i2);
	      if (i2 < 0)
		i2 = -i2;

	      if (i2 > i3)
		{
		  gfc_error ("The absolute value of SHIFT at %L must be less "
			     "than or equal to SIZE at %L", &shift->where,
			     &size->where);
		  return false;
		}
	     }
	}
    }
  else if (!less_than_bitsize1 ("I", i, NULL, shift, true))
    return false;

  return true;
}


bool
gfc_check_kill (gfc_expr *pid, gfc_expr *sig)
{
  if (!type_check (pid, 0, BT_INTEGER))
    return false;

  if (!scalar_check (pid, 0))
    return false;

  if (!type_check (sig, 1, BT_INTEGER))
    return false;

  if (!scalar_check (sig, 1))
    return false;

  return true;
}


bool
gfc_check_kill_sub (gfc_expr *pid, gfc_expr *sig, gfc_expr *status)
{
  if (!type_check (pid, 0, BT_INTEGER))
    return false;

  if (!scalar_check (pid, 0))
    return false;

  if (!type_check (sig, 1, BT_INTEGER))
    return false;

  if (!scalar_check (sig, 1))
    return false;

  if (status)
    {
      if (!type_check (status, 2, BT_INTEGER))
	return false;

      if (!scalar_check (status, 2))
	return false;

      if (status->expr_type != EXPR_VARIABLE)
	{
	  gfc_error ("STATUS at %L shall be an INTENT(OUT) variable",
		     &status->where);
	  return false;
	}

      if (status->expr_type == EXPR_VARIABLE
	  && status->symtree && status->symtree->n.sym
	  && status->symtree->n.sym->attr.intent == INTENT_IN)
	{
	  gfc_error ("%qs at %L shall be an INTENT(OUT) variable",
		     status->symtree->name, &status->where);
	  return false;
	}
    }

  return true;
}


bool
gfc_check_kind (gfc_expr *x)
{
  if (gfc_invalid_null_arg (x))
    return false;

  if (gfc_bt_struct (x->ts.type) || x->ts.type == BT_CLASS)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be of "
		 "intrinsic type", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &x->where);
      return false;
    }
  if (x->ts.type == BT_PROCEDURE)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be a data entity",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &x->where);
      return false;
    }

  return true;
}


bool
gfc_check_lbound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
{
  if (!array_check (array, 0))
    return false;

  if (!dim_check (dim, 1, false))
    return false;

  if (!dim_rank_check (dim, array, 1))
    return false;

  if (!kind_check (kind, 2, BT_INTEGER))
    return false;
  if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
			       "with KIND argument at %L",
			       gfc_current_intrinsic, &kind->where))
    return false;

  return true;
}


bool
gfc_check_lcobound (gfc_expr *coarray, gfc_expr *dim, gfc_expr *kind)
{
  if (flag_coarray == GFC_FCOARRAY_NONE)
    {
      gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
      return false;
    }

  if (!coarray_check (coarray, 0))
    return false;

  if (dim != NULL)
    {
      if (!dim_check (dim, 1, false))
        return false;

      if (!dim_corank_check (dim, coarray))
        return false;
    }

  if (!kind_check (kind, 2, BT_INTEGER))
    return false;

  return true;
}


bool
gfc_check_len_lentrim (gfc_expr *s, gfc_expr *kind)
{
  if (!type_check (s, 0, BT_CHARACTER))
    return false;

  if (gfc_invalid_null_arg (s))
    return false;

  if (!kind_check (kind, 1, BT_INTEGER))
    return false;
  if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
			       "with KIND argument at %L",
			       gfc_current_intrinsic, &kind->where))
    return false;

  return true;
}


bool
gfc_check_lge_lgt_lle_llt (gfc_expr *a, gfc_expr *b)
{
  if (!type_check (a, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (a, 0, gfc_default_character_kind))
    return false;

  if (!type_check (b, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (b, 1, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_link (gfc_expr *path1, gfc_expr *path2)
{
  if (!type_check (path1, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (path1, 0, gfc_default_character_kind))
    return false;

  if (!type_check (path2, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (path2, 1, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_link_sub (gfc_expr *path1, gfc_expr *path2, gfc_expr *status)
{
  if (!type_check (path1, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (path1, 0, gfc_default_character_kind))
    return false;

  if (!type_check (path2, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (path2, 0, gfc_default_character_kind))
    return false;

  if (status == NULL)
    return true;

  if (!type_check (status, 2, BT_INTEGER))
    return false;

  if (!scalar_check (status, 2))
    return false;

  return true;
}


bool
gfc_check_loc (gfc_expr *expr)
{
  return variable_check (expr, 0, true);
}


bool
gfc_check_symlnk (gfc_expr *path1, gfc_expr *path2)
{
  if (!type_check (path1, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (path1, 0, gfc_default_character_kind))
    return false;

  if (!type_check (path2, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (path2, 1, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_symlnk_sub (gfc_expr *path1, gfc_expr *path2, gfc_expr *status)
{
  if (!type_check (path1, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (path1, 0, gfc_default_character_kind))
    return false;

  if (!type_check (path2, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (path2, 1, gfc_default_character_kind))
    return false;

  if (status == NULL)
    return true;

  if (!type_check (status, 2, BT_INTEGER))
    return false;

  if (!scalar_check (status, 2))
    return false;

  return true;
}


bool
gfc_check_logical (gfc_expr *a, gfc_expr *kind)
{
  if (!type_check (a, 0, BT_LOGICAL))
    return false;
  if (!kind_check (kind, 1, BT_LOGICAL))
    return false;

  return true;
}


/* Min/max family.  */

static bool
min_max_args (gfc_actual_arglist *args)
{
  gfc_actual_arglist *arg;
  int i, j, nargs, *nlabels, nlabelless;
  bool a1 = false, a2 = false;

  if (args == NULL || args->next == NULL)
    {
      gfc_error ("Intrinsic %qs at %L must have at least two arguments",
		 gfc_current_intrinsic, gfc_current_intrinsic_where);
      return false;
    }

  if (!args->name)
    a1 = true;

  if (!args->next->name)
    a2 = true;

  nargs = 0;
  for (arg = args; arg; arg = arg->next)
    if (arg->name)
      nargs++;

  if (nargs == 0)
    return true;

  /* Note: Having a keywordless argument after an "arg=" is checked before.  */
  nlabelless = 0;
  nlabels = XALLOCAVEC (int, nargs);
  for (arg = args, i = 0; arg; arg = arg->next, i++)
    if (arg->name)
      {
	int n;
	char *endp;

	if (arg->name[0] != 'a' || arg->name[1] < '1' || arg->name[1] > '9')
	  goto unknown;
	n = strtol (&arg->name[1], &endp, 10);
	if (endp[0] != '\0')
	  goto unknown;
	if (n <= 0)
	  goto unknown;
	if (n <= nlabelless)
	  goto duplicate;
	nlabels[i] = n;
	if (n == 1)
	  a1 = true;
	if (n == 2)
	  a2 = true;
      }
    else
      nlabelless++;

  if (!a1 || !a2)
    {
      gfc_error ("Missing %qs argument to the %s intrinsic at %L",
	         !a1 ? "a1" : "a2", gfc_current_intrinsic,
		 gfc_current_intrinsic_where);
      return false;
    }

  /* Check for duplicates.  */
  for (i = 0; i < nargs; i++)
    for (j = i + 1; j < nargs; j++)
      if (nlabels[i] == nlabels[j])
	goto duplicate;

  return true;

duplicate:
  gfc_error ("Duplicate argument %qs at %L to intrinsic %s", arg->name,
	     &arg->expr->where, gfc_current_intrinsic);
  return false;

unknown:
  gfc_error ("Unknown argument %qs at %L to intrinsic %s", arg->name,
	     &arg->expr->where, gfc_current_intrinsic);
  return false;
}


static bool
check_rest (bt type, int kind, gfc_actual_arglist *arglist)
{
  gfc_actual_arglist *arg, *tmp;
  gfc_expr *x;
  int m, n;

  if (!min_max_args (arglist))
    return false;

  for (arg = arglist, n=1; arg; arg = arg->next, n++)
    {
      x = arg->expr;
      if (x->ts.type != type || x->ts.kind != kind)
	{
	  if (x->ts.type == type)
	    {
	      if (x->ts.type == BT_CHARACTER)
		{
		  gfc_error ("Different character kinds at %L", &x->where);
		  return false;
		}
	      if (!gfc_notify_std (GFC_STD_GNU, "Different type "
				   "kinds at %L", &x->where))
		return false;
	    }
	  else
	    {
	      gfc_error ("%<a%d%> argument of %qs intrinsic at %L must be "
			 "%s(%d)", n, gfc_current_intrinsic, &x->where,
			 gfc_basic_typename (type), kind);
	      return false;
	    }
	}

      for (tmp = arglist, m=1; tmp != arg; tmp = tmp->next, m++)
	if (!gfc_check_conformance (tmp->expr, x,
				    _("arguments 'a%d' and 'a%d' for "
				    "intrinsic '%s'"), m, n,
				    gfc_current_intrinsic))
	    return false;
    }

  return true;
}


bool
gfc_check_min_max (gfc_actual_arglist *arg)
{
  gfc_expr *x;

  if (!min_max_args (arg))
    return false;

  x = arg->expr;

  if (x->ts.type == BT_CHARACTER)
    {
      if (!gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
			   "with CHARACTER argument at %L",
			   gfc_current_intrinsic, &x->where))
	return false;
    }
  else if (x->ts.type != BT_INTEGER && x->ts.type != BT_REAL)
    {
      gfc_error ("%<a1%> argument of %qs intrinsic at %L must be INTEGER, "
		 "REAL or CHARACTER", gfc_current_intrinsic, &x->where);
      return false;
    }

  return check_rest (x->ts.type, x->ts.kind, arg);
}


bool
gfc_check_min_max_integer (gfc_actual_arglist *arg)
{
  return check_rest (BT_INTEGER, gfc_default_integer_kind, arg);
}


bool
gfc_check_min_max_real (gfc_actual_arglist *arg)
{
  return check_rest (BT_REAL, gfc_default_real_kind, arg);
}


bool
gfc_check_min_max_double (gfc_actual_arglist *arg)
{
  return check_rest (BT_REAL, gfc_default_double_kind, arg);
}


/* End of min/max family.  */

bool
gfc_check_malloc (gfc_expr *size)
{
  if (!type_check (size, 0, BT_INTEGER))
    return false;

  if (!scalar_check (size, 0))
    return false;

  return true;
}


bool
gfc_check_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b)
{
  if ((matrix_a->ts.type != BT_LOGICAL) && !gfc_numeric_ts (&matrix_a->ts))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be numeric "
		 "or LOGICAL", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &matrix_a->where);
      return false;
    }

  if ((matrix_b->ts.type != BT_LOGICAL) && !gfc_numeric_ts (&matrix_b->ts))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be numeric "
		 "or LOGICAL", gfc_current_intrinsic_arg[1]->name,
		 gfc_current_intrinsic, &matrix_b->where);
      return false;
    }

  if ((matrix_a->ts.type == BT_LOGICAL && gfc_numeric_ts (&matrix_b->ts))
      || (gfc_numeric_ts (&matrix_a->ts) && matrix_b->ts.type == BT_LOGICAL))
    {
      gfc_error ("Argument types of %qs intrinsic at %L must match (%s/%s)",
		 gfc_current_intrinsic, &matrix_a->where,
		 gfc_typename(&matrix_a->ts), gfc_typename(&matrix_b->ts));
       return false;
    }

  switch (matrix_a->rank)
    {
    case 1:
      if (!rank_check (matrix_b, 1, 2))
	return false;
      /* Check for case matrix_a has shape(m), matrix_b has shape (m, k).  */
      if (!identical_dimen_shape (matrix_a, 0, matrix_b, 0))
	{
	  gfc_error ("Different shape on dimension 1 for arguments %qs "
		     "and %qs at %L for intrinsic matmul",
		     gfc_current_intrinsic_arg[0]->name,
		     gfc_current_intrinsic_arg[1]->name, &matrix_a->where);
	  return false;
	}
      break;

    case 2:
      if (matrix_b->rank != 2)
	{
	  if (!rank_check (matrix_b, 1, 1))
	    return false;
	}
      /* matrix_b has rank 1 or 2 here. Common check for the cases
	 - matrix_a has shape (n,m) and matrix_b has shape (m, k)
	 - matrix_a has shape (n,m) and matrix_b has shape (m).  */
      if (!identical_dimen_shape (matrix_a, 1, matrix_b, 0))
	{
	  gfc_error ("Different shape on dimension 2 for argument %qs and "
		     "dimension 1 for argument %qs at %L for intrinsic "
		     "matmul", gfc_current_intrinsic_arg[0]->name,
		     gfc_current_intrinsic_arg[1]->name, &matrix_a->where);
	  return false;
	}
      break;

    default:
      gfc_error ("%qs argument of %qs intrinsic at %L must be of rank "
		 "1 or 2", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &matrix_a->where);
      return false;
    }

  return true;
}


/* Whoever came up with this interface was probably on something.
   The possibilities for the occupation of the second and third
   parameters are:

	 Arg #2     Arg #3
	 NULL       NULL
	 DIM	NULL
	 MASK       NULL
	 NULL       MASK	     minloc(array, mask=m)
	 DIM	MASK

   I.e. in the case of minloc(array,mask), mask will be in the second
   position of the argument list and we'll have to fix that up.  Also,
   add the BACK argument if that isn't present.  */

bool
gfc_check_minloc_maxloc (gfc_actual_arglist *ap)
{
  gfc_expr *a, *m, *d, *k, *b;

  a = ap->expr;
  if (!int_or_real_or_char_check_f2003 (a, 0) || !array_check (a, 0))
    return false;

  d = ap->next->expr;
  m = ap->next->next->expr;
  k = ap->next->next->next->expr;
  b = ap->next->next->next->next->expr;

  if (b)
    {
      if (!type_check (b, 4, BT_LOGICAL) || !scalar_check (b,4))
	return false;
    }
  else
    {
      b = gfc_get_logical_expr (gfc_logical_4_kind, NULL, 0);
      ap->next->next->next->next->expr = b;
    }

  if (m == NULL && d != NULL && d->ts.type == BT_LOGICAL
      && ap->next->name == NULL)
    {
      m = d;
      d = NULL;
      ap->next->expr = NULL;
      ap->next->next->expr = m;
    }

  if (!dim_check (d, 1, false))
    return false;

  if (!dim_rank_check (d, a, 0))
    return false;

  if (m != NULL && !type_check (m, 2, BT_LOGICAL))
    return false;

  if (m != NULL
      && !gfc_check_conformance (a, m,
				 _("arguments '%s' and '%s' for intrinsic %s"),
				 gfc_current_intrinsic_arg[0]->name,
				 gfc_current_intrinsic_arg[2]->name,
				 gfc_current_intrinsic))
    return false;

  if (!kind_check (k, 1, BT_INTEGER))
    return false;

  return true;
}

/* Check function for findloc.  Mostly like gfc_check_minloc_maxloc
   above, with the additional "value" argument.  */

bool
gfc_check_findloc (gfc_actual_arglist *ap)
{
  gfc_expr *a, *v, *m, *d, *k, *b;
  bool a1, v1;

  a = ap->expr;
  if (!intrinsic_type_check (a, 0) || !array_check (a, 0))
    return false;

  v = ap->next->expr;
  if (!intrinsic_type_check (v, 1) || !scalar_check (v,1))
    return false;

  /* Check if the type are both logical.  */
  a1 = a->ts.type == BT_LOGICAL;
  v1 = v->ts.type == BT_LOGICAL;
  if ((a1 && !v1) || (!a1 && v1))
    goto incompat;

  /* Check if the type are both character.  */
  a1 = a->ts.type == BT_CHARACTER;
  v1 = v->ts.type == BT_CHARACTER;
  if ((a1 && !v1) || (!a1 && v1))
    goto incompat;

  /* Check the kind of the characters argument match.  */
  if (a1 && v1 && a->ts.kind != v->ts.kind)
    goto incompat;

  d = ap->next->next->expr;
  m = ap->next->next->next->expr;
  k = ap->next->next->next->next->expr;
  b = ap->next->next->next->next->next->expr;

  if (b)
    {
      if (!type_check (b, 5, BT_LOGICAL) || !scalar_check (b,4))
	return false;
    }
  else
    {
      b = gfc_get_logical_expr (gfc_logical_4_kind, NULL, 0);
      ap->next->next->next->next->next->expr = b;
    }

  if (m == NULL && d != NULL && d->ts.type == BT_LOGICAL
      && ap->next->name == NULL)
    {
      m = d;
      d = NULL;
      ap->next->next->expr = NULL;
      ap->next->next->next->expr = m;
    }

  if (!dim_check (d, 2, false))
    return false;

  if (!dim_rank_check (d, a, 0))
    return false;

  if (m != NULL && !type_check (m, 3, BT_LOGICAL))
    return false;

  if (m != NULL
      && !gfc_check_conformance (a, m,
				 _("arguments '%s' and '%s' for intrinsic %s"),
				 gfc_current_intrinsic_arg[0]->name,
				 gfc_current_intrinsic_arg[3]->name,
				 gfc_current_intrinsic))
    return false;

  if (!kind_check (k, 1, BT_INTEGER))
    return false;

  return true;

incompat:
  gfc_error ("Argument %qs of %qs intrinsic at %L must be in type "
	     "conformance to argument %qs at %L",
	     gfc_current_intrinsic_arg[0]->name,
	     gfc_current_intrinsic, &a->where,
	     gfc_current_intrinsic_arg[1]->name, &v->where);
  return false;
}


/* Similar to minloc/maxloc, the argument list might need to be
   reordered for the MINVAL, MAXVAL, PRODUCT, and SUM intrinsics.  The
   difference is that MINLOC/MAXLOC take an additional KIND argument.
   The possibilities are:

	 Arg #2     Arg #3
	 NULL       NULL
	 DIM	NULL
	 MASK       NULL
	 NULL       MASK	     minval(array, mask=m)
	 DIM	MASK

   I.e. in the case of minval(array,mask), mask will be in the second
   position of the argument list and we'll have to fix that up.  */

static bool
check_reduction (gfc_actual_arglist *ap)
{
  gfc_expr *a, *m, *d;

  a = ap->expr;
  d = ap->next->expr;
  m = ap->next->next->expr;

  if (m == NULL && d != NULL && d->ts.type == BT_LOGICAL
      && ap->next->name == NULL)
    {
      m = d;
      d = NULL;
      ap->next->expr = NULL;
      ap->next->next->expr = m;
    }

  if (!dim_check (d, 1, false))
    return false;

  if (!dim_rank_check (d, a, 0))
    return false;

  if (m != NULL && !type_check (m, 2, BT_LOGICAL))
    return false;

  if (m != NULL
      && !gfc_check_conformance (a, m,
				 _("arguments '%s' and '%s' for intrinsic %s"),
				 gfc_current_intrinsic_arg[0]->name,
				 gfc_current_intrinsic_arg[2]->name,
				 gfc_current_intrinsic))
    return false;

  return true;
}


bool
gfc_check_minval_maxval (gfc_actual_arglist *ap)
{
  if (!int_or_real_or_char_check_f2003 (ap->expr, 0)
      || !array_check (ap->expr, 0))
    return false;

  return check_reduction (ap);
}


bool
gfc_check_product_sum (gfc_actual_arglist *ap)
{
  if (!numeric_check (ap->expr, 0)
      || !array_check (ap->expr, 0))
    return false;

  return check_reduction (ap);
}


/* For IANY, IALL and IPARITY.  */

bool
gfc_check_mask (gfc_expr *i, gfc_expr *kind)
{
  int k;

  if (!type_check (i, 0, BT_INTEGER))
    return false;

  if (!nonnegative_check ("I", i))
    return false;

  if (!kind_check (kind, 1, BT_INTEGER))
    return false;

  if (kind)
    gfc_extract_int (kind, &k);
  else
    k = gfc_default_integer_kind;

  if (!less_than_bitsizekind ("I", i, k))
    return false;

  return true;
}


bool
gfc_check_transf_bit_intrins (gfc_actual_arglist *ap)
{
  if (ap->expr->ts.type != BT_INTEGER)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be INTEGER",
                 gfc_current_intrinsic_arg[0]->name,
                 gfc_current_intrinsic, &ap->expr->where);
      return false;
    }

  if (!array_check (ap->expr, 0))
    return false;

  return check_reduction (ap);
}


bool
gfc_check_merge (gfc_expr *tsource, gfc_expr *fsource, gfc_expr *mask)
{
  if (gfc_invalid_null_arg (tsource))
    return false;

  if (gfc_invalid_null_arg (fsource))
    return false;

  if (!same_type_check (tsource, 0, fsource, 1))
    return false;

  if (!type_check (mask, 2, BT_LOGICAL))
    return false;

  if (tsource->ts.type == BT_CHARACTER)
    return gfc_check_same_strlen (tsource, fsource, "MERGE intrinsic");

  return true;
}


bool
gfc_check_merge_bits (gfc_expr *i, gfc_expr *j, gfc_expr *mask)
{
  /* i and j cannot both be BOZ literal constants.  */
  if (!boz_args_check (i, j))
    return false;

  /* If i is BOZ and j is integer, convert i to type of j.  */
  if (i->ts.type == BT_BOZ && j->ts.type == BT_INTEGER
      && !gfc_boz2int (i, j->ts.kind))
    return false;

  /* If j is BOZ and i is integer, convert j to type of i.  */
  if (j->ts.type == BT_BOZ && i->ts.type == BT_INTEGER
      && !gfc_boz2int (j, i->ts.kind))
    return false;

  if (!type_check (i, 0, BT_INTEGER))
    return false;

  if (!type_check (j, 1, BT_INTEGER))
    return false;

  if (!same_type_check (i, 0, j, 1))
    return false;

  if (mask->ts.type == BT_BOZ && !gfc_boz2int(mask, i->ts.kind))
    return false;

  if (!type_check (mask, 2, BT_INTEGER))
    return false;

  if (!same_type_check (i, 0, mask, 2))
    return false;

  return true;
}


bool
gfc_check_move_alloc (gfc_expr *from, gfc_expr *to)
{
  if (!variable_check (from, 0, false))
    return false;
  if (!allocatable_check (from, 0))
    return false;
  if (gfc_is_coindexed (from))
    {
      gfc_error ("The FROM argument to MOVE_ALLOC at %L shall not be "
		 "coindexed", &from->where);
      return false;
    }

  if (!variable_check (to, 1, false))
    return false;
  if (!allocatable_check (to, 1))
    return false;
  if (gfc_is_coindexed (to))
    {
      gfc_error ("The TO argument to MOVE_ALLOC at %L shall not be "
		 "coindexed", &to->where);
      return false;
    }

  if (from->ts.type == BT_CLASS && to->ts.type == BT_DERIVED)
    {
      gfc_error ("The TO arguments in MOVE_ALLOC at %L must be "
		 "polymorphic if FROM is polymorphic",
		 &to->where);
      return false;
    }

  if (!same_type_check (to, 1, from, 0))
    return false;

  if (to->rank != from->rank)
    {
      gfc_error ("The FROM and TO arguments of the MOVE_ALLOC intrinsic at %L "
		 "must have the same rank %d/%d", &to->where,  from->rank,
		 to->rank);
      return false;
    }

  /* IR F08/0040; cf. 12-006A.  */
  if (gfc_get_corank (to) != gfc_get_corank (from))
    {
      gfc_error ("The FROM and TO arguments of the MOVE_ALLOC intrinsic at %L "
		 "must have the same corank %d/%d", &to->where,
		 gfc_get_corank (from), gfc_get_corank (to));
      return false;
    }

  /*  This is based losely on F2003 12.4.1.7. It is intended to prevent
      the likes of to = sym->cmp1->cmp2 and from = sym->cmp1, where cmp1
      and cmp2 are allocatable.  After the allocation is transferred,
      the 'to' chain is broken by the nullification of the 'from'. A bit
      of reflection reveals that this can only occur for derived types
      with recursive allocatable components.  */
  if (to->expr_type == EXPR_VARIABLE && from->expr_type == EXPR_VARIABLE
      && !strcmp (to->symtree->n.sym->name, from->symtree->n.sym->name))
    {
      gfc_ref *to_ref, *from_ref;
      to_ref = to->ref;
      from_ref = from->ref;
      bool aliasing = true;

      for (; from_ref && to_ref;
	   from_ref = from_ref->next, to_ref = to_ref->next)
	{
	  if (to_ref->type != from->ref->type)
	    aliasing = false;
	  else if (to_ref->type == REF_ARRAY
		   && to_ref->u.ar.type != AR_FULL
		   && from_ref->u.ar.type != AR_FULL)
	    /* Play safe; assume sections and elements are different.  */
	    aliasing = false;
	  else if (to_ref->type == REF_COMPONENT
		   && to_ref->u.c.component != from_ref->u.c.component)
	    aliasing = false;

	  if (!aliasing)
	    break;
	}

      if (aliasing)
	{
	  gfc_error ("The FROM and TO arguments at %L violate aliasing "
		     "restrictions (F2003 12.4.1.7)", &to->where);
	  return false;
	}
    }

  /* CLASS arguments: Make sure the vtab of from is present.  */
  if (to->ts.type == BT_CLASS && !UNLIMITED_POLY (from))
    gfc_find_vtab (&from->ts);

  return true;
}


bool
gfc_check_nearest (gfc_expr *x, gfc_expr *s)
{
  if (!type_check (x, 0, BT_REAL))
    return false;

  if (!type_check (s, 1, BT_REAL))
    return false;

  if (s->expr_type == EXPR_CONSTANT)
    {
      if (mpfr_sgn (s->value.real) == 0)
	{
	  gfc_error ("Argument %<S%> of NEAREST at %L shall not be zero",
		     &s->where);
	  return false;
	}
    }

  return true;
}


bool
gfc_check_new_line (gfc_expr *a)
{
  if (!type_check (a, 0, BT_CHARACTER))
    return false;

  return true;
}


bool
gfc_check_norm2 (gfc_expr *array, gfc_expr *dim)
{
  if (!type_check (array, 0, BT_REAL))
    return false;

  if (!array_check (array, 0))
    return false;

  if (!dim_rank_check (dim, array, false))
    return false;

  return true;
}

bool
gfc_check_null (gfc_expr *mold)
{
  symbol_attribute attr;

  if (mold == NULL)
    return true;

  if (!variable_check (mold, 0, true))
    return false;

  attr = gfc_variable_attr (mold, NULL);

  if (!attr.pointer && !attr.proc_pointer && !attr.allocatable)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be a POINTER, "
		 "ALLOCATABLE or procedure pointer",
		 gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &mold->where);
      return false;
    }

  if (attr.allocatable
      && !gfc_notify_std (GFC_STD_F2003, "NULL intrinsic with "
			  "allocatable MOLD at %L", &mold->where))
    return false;

  /* F2008, C1242.  */
  if (gfc_is_coindexed (mold))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L shall not be "
		 "coindexed", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &mold->where);
      return false;
    }

  return true;
}


bool
gfc_check_pack (gfc_expr *array, gfc_expr *mask, gfc_expr *vector)
{
  if (!array_check (array, 0))
    return false;

  if (!type_check (mask, 1, BT_LOGICAL))
    return false;

  if (!gfc_check_conformance (array, mask,
			      _("arguments '%s' and '%s' for intrinsic '%s'"),
			      gfc_current_intrinsic_arg[0]->name,
			      gfc_current_intrinsic_arg[1]->name,
			      gfc_current_intrinsic))
    return false;

  if (vector != NULL)
    {
      mpz_t array_size, vector_size;
      bool have_array_size, have_vector_size;

      if (!same_type_check (array, 0, vector, 2))
	return false;

      if (!rank_check (vector, 2, 1))
	return false;

      /* VECTOR requires at least as many elements as MASK
         has .TRUE. values.  */
      have_array_size = gfc_array_size(array, &array_size);
      have_vector_size = gfc_array_size(vector, &vector_size);

      if (have_vector_size
	  && (mask->expr_type == EXPR_ARRAY
	      || (mask->expr_type == EXPR_CONSTANT
		  && have_array_size)))
	{
	  int mask_true_values = 0;

	  if (mask->expr_type == EXPR_ARRAY)
	    {
	      gfc_constructor *mask_ctor;
	      mask_ctor = gfc_constructor_first (mask->value.constructor);
	      while (mask_ctor)
		{
		  if (mask_ctor->expr->expr_type != EXPR_CONSTANT)
		    {
		      mask_true_values = 0;
		      break;
		    }

		  if (mask_ctor->expr->value.logical)
		    mask_true_values++;

		  mask_ctor = gfc_constructor_next (mask_ctor);
		}
	    }
	  else if (mask->expr_type == EXPR_CONSTANT && mask->value.logical)
	    mask_true_values = mpz_get_si (array_size);

	  if (mpz_get_si (vector_size) < mask_true_values)
	    {
	      gfc_error ("%qs argument of %qs intrinsic at %L must "
			 "provide at least as many elements as there "
			 "are .TRUE. values in %qs (%ld/%d)",
			 gfc_current_intrinsic_arg[2]->name,
			 gfc_current_intrinsic, &vector->where,
			 gfc_current_intrinsic_arg[1]->name,
			 mpz_get_si (vector_size), mask_true_values);
	      return false;
	    }
	}

      if (have_array_size)
	mpz_clear (array_size);
      if (have_vector_size)
	mpz_clear (vector_size);
    }

  return true;
}


bool
gfc_check_parity (gfc_expr *mask, gfc_expr *dim)
{
  if (!type_check (mask, 0, BT_LOGICAL))
    return false;

  if (!array_check (mask, 0))
    return false;

  if (!dim_rank_check (dim, mask, false))
    return false;

  return true;
}


bool
gfc_check_precision (gfc_expr *x)
{
  if (!real_or_complex_check (x, 0))
    return false;

  return true;
}


bool
gfc_check_present (gfc_expr *a)
{
  gfc_symbol *sym;

  if (!variable_check (a, 0, true))
    return false;

  sym = a->symtree->n.sym;
  if (!sym->attr.dummy)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be of a "
		 "dummy variable", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &a->where);
      return false;
    }

  /* For CLASS, the optional attribute might be set at either location. */
  if ((sym->ts.type != BT_CLASS || !CLASS_DATA (sym)->attr.optional)
      && !sym->attr.optional)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be of "
		 "an OPTIONAL dummy variable",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &a->where);
      return false;
    }

  /* 13.14.82  PRESENT(A)
     ......
     Argument.  A shall be the name of an optional dummy argument that is
     accessible in the subprogram in which the PRESENT function reference
     appears...  */

  if (a->ref != NULL
      && !(a->ref->next == NULL && a->ref->type == REF_ARRAY
	   && (a->ref->u.ar.type == AR_FULL
	       || (a->ref->u.ar.type == AR_ELEMENT
		   && a->ref->u.ar.as->rank == 0))))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must not be a "
		 "subobject of %qs", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &a->where, sym->name);
      return false;
    }

  return true;
}


bool
gfc_check_radix (gfc_expr *x)
{
  if (!int_or_real_check (x, 0))
    return false;

  return true;
}


bool
gfc_check_range (gfc_expr *x)
{
  if (!numeric_check (x, 0))
    return false;

  return true;
}


bool
gfc_check_rank (gfc_expr *a)
{
  /* Any data object is allowed; a "data object" is a "constant (4.1.3),
     variable (6), or subobject of a constant (2.4.3.2.3)" (F2008, 1.3.45).  */

  bool is_variable = true;

  /* Functions returning pointers are regarded as variable, cf. F2008, R602.  */
  if (a->expr_type == EXPR_FUNCTION)
    is_variable = a->value.function.esym
		  ? a->value.function.esym->result->attr.pointer
		  : a->symtree->n.sym->result->attr.pointer;

  if (a->expr_type == EXPR_OP
      || a->expr_type == EXPR_NULL
      || a->expr_type == EXPR_COMPCALL
      || a->expr_type == EXPR_PPC
      || a->ts.type == BT_PROCEDURE
      || !is_variable)
    {
      gfc_error ("The argument of the RANK intrinsic at %L must be a data "
		 "object", &a->where);
      return false;
    }

  return true;
}


bool
gfc_check_real (gfc_expr *a, gfc_expr *kind)
{
  if (!kind_check (kind, 1, BT_REAL))
    return false;

  /* BOZ is dealt with in gfc_simplify_real.  */
  if (a->ts.type == BT_BOZ)
    return true;

  if (!numeric_check (a, 0))
    return false;

  return true;
}


bool
gfc_check_rename (gfc_expr *path1, gfc_expr *path2)
{
  if (!type_check (path1, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (path1, 0, gfc_default_character_kind))
    return false;

  if (!type_check (path2, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (path2, 1, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_rename_sub (gfc_expr *path1, gfc_expr *path2, gfc_expr *status)
{
  if (!type_check (path1, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (path1, 0, gfc_default_character_kind))
    return false;

  if (!type_check (path2, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (path2, 1, gfc_default_character_kind))
    return false;

  if (status == NULL)
    return true;

  if (!type_check (status, 2, BT_INTEGER))
    return false;

  if (!scalar_check (status, 2))
    return false;

  return true;
}


bool
gfc_check_repeat (gfc_expr *x, gfc_expr *y)
{
  if (!type_check (x, 0, BT_CHARACTER))
    return false;

  if (!scalar_check (x, 0))
    return false;

  if (!type_check (y, 0, BT_INTEGER))
    return false;

  if (!scalar_check (y, 1))
    return false;

  return true;
}


bool
gfc_check_reshape (gfc_expr *source, gfc_expr *shape,
		   gfc_expr *pad, gfc_expr *order)
{
  mpz_t size;
  mpz_t nelems;
  int shape_size;

  if (!array_check (source, 0))
    return false;

  if (!rank_check (shape, 1, 1))
    return false;

  if (!type_check (shape, 1, BT_INTEGER))
    return false;

  if (!gfc_array_size (shape, &size))
    {
      gfc_error ("%<shape%> argument of %<reshape%> intrinsic at %L must be an "
		 "array of constant size", &shape->where);
      return false;
    }

  shape_size = mpz_get_ui (size);
  mpz_clear (size);

  if (shape_size <= 0)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L is empty",
		 gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		 &shape->where);
      return false;
    }
  else if (shape_size > GFC_MAX_DIMENSIONS)
    {
      gfc_error ("%<shape%> argument of %<reshape%> intrinsic at %L has more "
		 "than %d elements", &shape->where, GFC_MAX_DIMENSIONS);
      return false;
    }
  else if (shape->expr_type == EXPR_ARRAY && gfc_is_constant_expr (shape))
    {
      gfc_expr *e;
      int i, extent;
      for (i = 0; i < shape_size; ++i)
	{
	  e = gfc_constructor_lookup_expr (shape->value.constructor, i);
	  if (e->expr_type != EXPR_CONSTANT)
	    continue;

	  gfc_extract_int (e, &extent);
	  if (extent < 0)
	    {
	      gfc_error ("%qs argument of %qs intrinsic at %L has "
			 "negative element (%d)",
			 gfc_current_intrinsic_arg[1]->name,
			 gfc_current_intrinsic, &e->where, extent);
	      return false;
	    }
	}
    }
  else if (shape->expr_type == EXPR_VARIABLE && shape->ref
	   && shape->ref->u.ar.type == AR_FULL && shape->ref->u.ar.dimen == 1
	   && shape->ref->u.ar.as
	   && shape->ref->u.ar.as->lower[0]->expr_type == EXPR_CONSTANT
	   && shape->ref->u.ar.as->lower[0]->ts.type == BT_INTEGER
	   && shape->ref->u.ar.as->upper[0]->expr_type == EXPR_CONSTANT
	   && shape->ref->u.ar.as->upper[0]->ts.type == BT_INTEGER
	   && shape->symtree->n.sym->attr.flavor == FL_PARAMETER
	   && shape->symtree->n.sym->value)
    {
      int i, extent;
      gfc_expr *e, *v;

      v = shape->symtree->n.sym->value;

      for (i = 0; i < shape_size; i++)
	{
	  e = gfc_constructor_lookup_expr (v->value.constructor, i);
	  if (e == NULL)
	     break;

	  gfc_extract_int (e, &extent);

	  if (extent < 0)
	    {
	      gfc_error ("Element %d of actual argument of RESHAPE at %L "
			 "cannot be negative", i + 1, &shape->where);
	      return false;
	    }
	}
    }

  if (pad != NULL)
    {
      if (!same_type_check (source, 0, pad, 2))
	return false;

      if (!array_check (pad, 2))
	return false;
    }

  if (order != NULL)
    {
      if (!array_check (order, 3))
	return false;

      if (!type_check (order, 3, BT_INTEGER))
	return false;

      if (order->expr_type == EXPR_ARRAY && gfc_is_constant_expr (order))
	{
	  int i, order_size, dim, perm[GFC_MAX_DIMENSIONS];
	  gfc_expr *e;

	  for (i = 0; i < GFC_MAX_DIMENSIONS; ++i)
	    perm[i] = 0;

	  gfc_array_size (order, &size);
	  order_size = mpz_get_ui (size);
	  mpz_clear (size);

	  if (order_size != shape_size)
	    {
	      gfc_error ("%qs argument of %qs intrinsic at %L "
			 "has wrong number of elements (%d/%d)",
			 gfc_current_intrinsic_arg[3]->name,
			 gfc_current_intrinsic, &order->where,
			 order_size, shape_size);
	      return false;
	    }

	  for (i = 1; i <= order_size; ++i)
	    {
	      e = gfc_constructor_lookup_expr (order->value.constructor, i-1);
	      if (e->expr_type != EXPR_CONSTANT)
		continue;

	      gfc_extract_int (e, &dim);

	      if (dim < 1 || dim > order_size)
		{
		  gfc_error ("%qs argument of %qs intrinsic at %L "
			     "has out-of-range dimension (%d)",
			     gfc_current_intrinsic_arg[3]->name,
			     gfc_current_intrinsic, &e->where, dim);
		  return false;
		}

	      if (perm[dim-1] != 0)
		{
		  gfc_error ("%qs argument of %qs intrinsic at %L has "
			     "invalid permutation of dimensions (dimension "
			     "%qd duplicated)",
			     gfc_current_intrinsic_arg[3]->name,
			     gfc_current_intrinsic, &e->where, dim);
		  return false;
		}

	      perm[dim-1] = 1;
	    }
	}
    }

  if (pad == NULL && shape->expr_type == EXPR_ARRAY
      && gfc_is_constant_expr (shape)
      && !(source->expr_type == EXPR_VARIABLE && source->symtree->n.sym->as
	   && source->symtree->n.sym->as->type == AS_ASSUMED_SIZE))
    {
      /* Check the match in size between source and destination.  */
      if (gfc_array_size (source, &nelems))
	{
	  gfc_constructor *c;
	  bool test;


	  mpz_init_set_ui (size, 1);
	  for (c = gfc_constructor_first (shape->value.constructor);
	       c; c = gfc_constructor_next (c))
	    mpz_mul (size, size, c->expr->value.integer);

	  test = mpz_cmp (nelems, size) < 0 && mpz_cmp_ui (size, 0) > 0;
	  mpz_clear (nelems);
	  mpz_clear (size);

	  if (test)
	    {
	      gfc_error ("Without padding, there are not enough elements "
			 "in the intrinsic RESHAPE source at %L to match "
			 "the shape", &source->where);
	      return false;
	    }
	}
    }

  return true;
}


bool
gfc_check_same_type_as (gfc_expr *a, gfc_expr *b)
{
  if (a->ts.type != BT_DERIVED && a->ts.type != BT_CLASS)
    {
        gfc_error ("%qs argument of %qs intrinsic at %L "
		   "cannot be of type %s",
		   gfc_current_intrinsic_arg[0]->name,
		   gfc_current_intrinsic,
		   &a->where, gfc_typename (a));
        return false;
    }

  if (!(gfc_type_is_extensible (a->ts.u.derived) || UNLIMITED_POLY (a)))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L "
		 "must be of an extensible type",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &a->where);
      return false;
    }

  if (b->ts.type != BT_DERIVED && b->ts.type != BT_CLASS)
    {
        gfc_error ("%qs argument of %qs intrinsic at %L "
		   "cannot be of type %s",
		   gfc_current_intrinsic_arg[0]->name,
		   gfc_current_intrinsic,
		   &b->where, gfc_typename (b));
      return false;
    }

  if (!(gfc_type_is_extensible (b->ts.u.derived) || UNLIMITED_POLY (b)))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L "
		 "must be of an extensible type",
		 gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		 &b->where);
      return false;
    }

  return true;
}


bool
gfc_check_scale (gfc_expr *x, gfc_expr *i)
{
  if (!type_check (x, 0, BT_REAL))
    return false;

  if (!type_check (i, 1, BT_INTEGER))
    return false;

  return true;
}


bool
gfc_check_scan (gfc_expr *x, gfc_expr *y, gfc_expr *z, gfc_expr *kind)
{
  if (!type_check (x, 0, BT_CHARACTER))
    return false;

  if (!type_check (y, 1, BT_CHARACTER))
    return false;

  if (z != NULL && !type_check (z, 2, BT_LOGICAL))
    return false;

  if (!kind_check (kind, 3, BT_INTEGER))
    return false;
  if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
			       "with KIND argument at %L",
			       gfc_current_intrinsic, &kind->where))
    return false;

  if (!same_type_check (x, 0, y, 1))
    return false;

  return true;
}


bool
gfc_check_secnds (gfc_expr *r)
{
  if (!type_check (r, 0, BT_REAL))
    return false;

  if (!kind_value_check (r, 0, 4))
    return false;

  if (!scalar_check (r, 0))
    return false;

  return true;
}


bool
gfc_check_selected_char_kind (gfc_expr *name)
{
  if (!type_check (name, 0, BT_CHARACTER))
    return false;

  if (!kind_value_check (name, 0, gfc_default_character_kind))
    return false;

  if (!scalar_check (name, 0))
    return false;

  return true;
}


bool
gfc_check_selected_int_kind (gfc_expr *r)
{
  if (!type_check (r, 0, BT_INTEGER))
    return false;

  if (!scalar_check (r, 0))
    return false;

  return true;
}


bool
gfc_check_selected_real_kind (gfc_expr *p, gfc_expr *r, gfc_expr *radix)
{
  if (p == NULL && r == NULL
      && !gfc_notify_std (GFC_STD_F2008, "SELECTED_REAL_KIND with"
			  " neither %<P%> nor %<R%> argument at %L",
			  gfc_current_intrinsic_where))
    return false;

  if (p)
    {
      if (!type_check (p, 0, BT_INTEGER))
	return false;

      if (!scalar_check (p, 0))
	return false;
    }

  if (r)
    {
      if (!type_check (r, 1, BT_INTEGER))
	return false;

      if (!scalar_check (r, 1))
	return false;
    }

  if (radix)
    {
      if (!type_check (radix, 1, BT_INTEGER))
	return false;

      if (!scalar_check (radix, 1))
	return false;

      if (!gfc_notify_std (GFC_STD_F2008, "%qs intrinsic with "
			   "RADIX argument at %L", gfc_current_intrinsic,
			   &radix->where))
	return false;
    }

  return true;
}


bool
gfc_check_set_exponent (gfc_expr *x, gfc_expr *i)
{
  if (!type_check (x, 0, BT_REAL))
    return false;

  if (!type_check (i, 1, BT_INTEGER))
    return false;

  return true;
}


bool
gfc_check_shape (gfc_expr *source, gfc_expr *kind)
{
  gfc_array_ref *ar;

  if (gfc_invalid_null_arg (source))
    return false;

  if (!kind_check (kind, 1, BT_INTEGER))
    return false;
  if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
			       "with KIND argument at %L",
			       gfc_current_intrinsic, &kind->where))
    return false;

  if (source->rank == 0 || source->expr_type != EXPR_VARIABLE)
    return true;

  ar = gfc_find_array_ref (source);

  if (ar->as && ar->as->type == AS_ASSUMED_SIZE && ar->type == AR_FULL)
    {
      gfc_error ("%<source%> argument of %<shape%> intrinsic at %L must not be "
		 "an assumed size array", &source->where);
      return false;
    }

  return true;
}


bool
gfc_check_shift (gfc_expr *i, gfc_expr *shift)
{
  if (!type_check (i, 0, BT_INTEGER))
    return false;

  if (!type_check (shift, 0, BT_INTEGER))
    return false;

  if (!nonnegative_check ("SHIFT", shift))
    return false;

  if (!less_than_bitsize1 ("I", i, "SHIFT", shift, true))
    return false;

  return true;
}


bool
gfc_check_sign (gfc_expr *a, gfc_expr *b)
{
  if (!int_or_real_check (a, 0))
    return false;

  if (!same_type_check (a, 0, b, 1))
    return false;

  return true;
}


bool
gfc_check_size (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
{
  if (!array_check (array, 0))
    return false;

  if (!dim_check (dim, 1, true))
    return false;

  if (!dim_rank_check (dim, array, 0))
    return false;

  if (!kind_check (kind, 2, BT_INTEGER))
    return false;
  if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
			       "with KIND argument at %L",
			       gfc_current_intrinsic, &kind->where))
    return false;


  return true;
}


bool
gfc_check_sizeof (gfc_expr *arg)
{
  if (gfc_invalid_null_arg (arg))
    return false;

  if (arg->ts.type == BT_PROCEDURE)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L shall not be a procedure",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &arg->where);
      return false;
    }

  /* TYPE(*) is acceptable if and only if it uses an array descriptor.  */
  if (arg->ts.type == BT_ASSUMED
      && (arg->symtree->n.sym->as == NULL
	  || (arg->symtree->n.sym->as->type != AS_ASSUMED_SHAPE
	      && arg->symtree->n.sym->as->type != AS_DEFERRED
	      && arg->symtree->n.sym->as->type != AS_ASSUMED_RANK)))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L shall not be TYPE(*)",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &arg->where);
      return false;
    }

  if (arg->rank && arg->expr_type == EXPR_VARIABLE
      && arg->symtree->n.sym->as != NULL
      && arg->symtree->n.sym->as->type == AS_ASSUMED_SIZE && arg->ref
      && arg->ref->type == REF_ARRAY && arg->ref->u.ar.type == AR_FULL)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L shall not be an "
		 "assumed-size array", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &arg->where);
      return false;
    }

  return true;
}


/* Check whether an expression is interoperable.  When returning false,
   msg is set to a string telling why the expression is not interoperable,
   otherwise, it is set to NULL.  The msg string can be used in diagnostics.
   If c_loc is true, character with len > 1 are allowed (cf. Fortran
   2003corr5); additionally, assumed-shape/assumed-rank/deferred-shape
   arrays are permitted. And if c_f_ptr is true, deferred-shape arrays
   are permitted.  */

static bool
is_c_interoperable (gfc_expr *expr, const char **msg, bool c_loc, bool c_f_ptr)
{
  *msg = NULL;

  if (expr->ts.type == BT_CLASS)
    {
      *msg = "Expression is polymorphic";
      return false;
    }

  if (expr->ts.type == BT_DERIVED && !expr->ts.u.derived->attr.is_bind_c
      && !expr->ts.u.derived->ts.is_iso_c)
    {
      *msg = "Expression is a noninteroperable derived type";
      return false;
    }

  if (expr->ts.type == BT_PROCEDURE)
    {
      *msg = "Procedure unexpected as argument";
      return false;
    }

  if (gfc_notification_std (GFC_STD_GNU) && expr->ts.type == BT_LOGICAL)
    {
      int i;
      for (i = 0; gfc_logical_kinds[i].kind; i++)
        if (gfc_logical_kinds[i].kind == expr->ts.kind)
          return true;
      *msg = "Extension to use a non-C_Bool-kind LOGICAL";
      return false;
    }

  if (gfc_notification_std (GFC_STD_GNU) && expr->ts.type == BT_CHARACTER
      && expr->ts.kind != 1)
    {
      *msg = "Extension to use a non-C_CHAR-kind CHARACTER";
      return false;
    }

  if (expr->ts.type == BT_CHARACTER) {
    if (expr->ts.deferred)
      {
	/* TS 29113 allows deferred-length strings as dummy arguments,
	   but it is not an interoperable type.  */
	*msg = "Expression shall not be a deferred-length string";
	return false;
      }

    if (expr->ts.u.cl && expr->ts.u.cl->length
	&& !gfc_simplify_expr (expr->ts.u.cl->length, 0))
      gfc_internal_error ("is_c_interoperable(): gfc_simplify_expr failed");

    if (!c_loc && expr->ts.u.cl
	&& (!expr->ts.u.cl->length
	    || expr->ts.u.cl->length->expr_type != EXPR_CONSTANT
	    || mpz_cmp_si (expr->ts.u.cl->length->value.integer, 1) != 0))
      {
	*msg = "Type shall have a character length of 1";
	return false;
      }
    }

  /* Note: The following checks are about interoperatable variables, Fortran
     15.3.5/15.3.6.  In intrinsics like C_LOC or in procedure interface, more
     is allowed, e.g. assumed-shape arrays with TS 29113.  */

  if (gfc_is_coarray (expr))
    {
      *msg = "Coarrays are not interoperable";
      return false;
    }

  if (!c_loc && expr->rank > 0 && expr->expr_type != EXPR_ARRAY)
    {
      gfc_array_ref *ar = gfc_find_array_ref (expr);
      if (ar->type != AR_FULL)
	{
	  *msg = "Only whole-arrays are interoperable";
	  return false;
	}
      if (!c_f_ptr && ar->as->type != AS_EXPLICIT
	  && ar->as->type != AS_ASSUMED_SIZE)
	{
	  *msg = "Only explicit-size and assumed-size arrays are interoperable";
	  return false;
	}
    }

  return true;
}


bool
gfc_check_c_sizeof (gfc_expr *arg)
{
  const char *msg;

  if (!is_c_interoperable (arg, &msg, false, false))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be an "
		 "interoperable data entity: %s",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &arg->where, msg);
      return false;
    }

  if (arg->ts.type == BT_ASSUMED)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L shall not be "
		 "TYPE(*)",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &arg->where);
      return false;
    }

  if (arg->rank && arg->expr_type == EXPR_VARIABLE
      && arg->symtree->n.sym->as != NULL
      && arg->symtree->n.sym->as->type == AS_ASSUMED_SIZE && arg->ref
      && arg->ref->type == REF_ARRAY && arg->ref->u.ar.type == AR_FULL)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L shall not be an "
		 "assumed-size array", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &arg->where);
      return false;
    }

  return true;
}


bool
gfc_check_c_associated (gfc_expr *c_ptr_1, gfc_expr *c_ptr_2)
{
  if (c_ptr_1->ts.type != BT_DERIVED
      || c_ptr_1->ts.u.derived->from_intmod != INTMOD_ISO_C_BINDING
      || (c_ptr_1->ts.u.derived->intmod_sym_id != ISOCBINDING_PTR
	  && c_ptr_1->ts.u.derived->intmod_sym_id != ISOCBINDING_FUNPTR))
    {
      gfc_error ("Argument C_PTR_1 at %L to C_ASSOCIATED shall have the "
		 "type TYPE(C_PTR) or TYPE(C_FUNPTR)", &c_ptr_1->where);
      return false;
    }

  if (!scalar_check (c_ptr_1, 0))
    return false;

  if (c_ptr_2
      && (c_ptr_2->ts.type != BT_DERIVED
	  || c_ptr_2->ts.u.derived->from_intmod != INTMOD_ISO_C_BINDING
	  || (c_ptr_1->ts.u.derived->intmod_sym_id
	      != c_ptr_2->ts.u.derived->intmod_sym_id)))
    {
      gfc_error ("Argument C_PTR_2 at %L to C_ASSOCIATED shall have the "
		 "same type as C_PTR_1: %s instead of %s", &c_ptr_1->where,
		 gfc_typename (&c_ptr_1->ts),
		 gfc_typename (&c_ptr_2->ts));
      return false;
    }

  if (c_ptr_2 && !scalar_check (c_ptr_2, 1))
    return false;

  return true;
}


bool
gfc_check_c_f_pointer (gfc_expr *cptr, gfc_expr *fptr, gfc_expr *shape)
{
  symbol_attribute attr;
  const char *msg;

  if (cptr->ts.type != BT_DERIVED
      || cptr->ts.u.derived->from_intmod != INTMOD_ISO_C_BINDING
      || cptr->ts.u.derived->intmod_sym_id != ISOCBINDING_PTR)
    {
      gfc_error ("Argument CPTR at %L to C_F_POINTER shall have the "
		 "type TYPE(C_PTR)", &cptr->where);
      return false;
    }

  if (!scalar_check (cptr, 0))
    return false;

  attr = gfc_expr_attr (fptr);

  if (!attr.pointer)
    {
      gfc_error ("Argument FPTR at %L to C_F_POINTER must be a pointer",
		 &fptr->where);
      return false;
    }

  if (fptr->ts.type == BT_CLASS)
    {
      gfc_error ("FPTR argument at %L to C_F_POINTER shall not be polymorphic",
		 &fptr->where);
      return false;
    }

  if (gfc_is_coindexed (fptr))
    {
      gfc_error ("Argument FPTR at %L to C_F_POINTER shall not be "
		 "coindexed", &fptr->where);
      return false;
    }

  if (fptr->rank == 0 && shape)
    {
      gfc_error ("Unexpected SHAPE argument at %L to C_F_POINTER with scalar "
		 "FPTR", &fptr->where);
      return false;
    }
  else if (fptr->rank && !shape)
    {
      gfc_error ("Expected SHAPE argument to C_F_POINTER with array "
		 "FPTR at %L", &fptr->where);
      return false;
    }

  if (shape && !rank_check (shape, 2, 1))
    return false;

  if (shape && !type_check (shape, 2, BT_INTEGER))
    return false;

  if (shape)
    {
      mpz_t size;
      if (gfc_array_size (shape, &size))
	{
	  if (mpz_cmp_ui (size, fptr->rank) != 0)
	    {
	      mpz_clear (size);
	      gfc_error ("SHAPE argument at %L to C_F_POINTER must have the same "
			"size as the RANK of FPTR", &shape->where);
	      return false;
	    }
	  mpz_clear (size);
	}
    }

  if (fptr->ts.type == BT_CLASS)
    {
      gfc_error ("Polymorphic FPTR at %L to C_F_POINTER", &fptr->where);
      return false;
    }

  if (fptr->rank > 0 && !is_c_interoperable (fptr, &msg, false, true))
    return gfc_notify_std (GFC_STD_F2018, "Noninteroperable array FPTR "
			   "at %L to C_F_POINTER: %s", &fptr->where, msg);

  return true;
}


bool
gfc_check_c_f_procpointer (gfc_expr *cptr, gfc_expr *fptr)
{
  symbol_attribute attr;

  if (cptr->ts.type != BT_DERIVED
      || cptr->ts.u.derived->from_intmod != INTMOD_ISO_C_BINDING
      || cptr->ts.u.derived->intmod_sym_id != ISOCBINDING_FUNPTR)
    {
      gfc_error ("Argument CPTR at %L to C_F_PROCPOINTER shall have the "
		 "type TYPE(C_FUNPTR)", &cptr->where);
      return false;
    }

  if (!scalar_check (cptr, 0))
    return false;

  attr = gfc_expr_attr (fptr);

  if (!attr.proc_pointer)
    {
      gfc_error ("Argument FPTR at %L to C_F_PROCPOINTER shall be a procedure "
		 "pointer", &fptr->where);
      return false;
    }

  if (gfc_is_coindexed (fptr))
    {
      gfc_error ("Argument FPTR at %L to C_F_PROCPOINTER shall not be "
		 "coindexed", &fptr->where);
      return false;
    }

  if (!attr.is_bind_c)
    return gfc_notify_std (GFC_STD_F2018, "Noninteroperable procedure "
			   "pointer at %L to C_F_PROCPOINTER", &fptr->where);

  return true;
}


bool
gfc_check_c_funloc (gfc_expr *x)
{
  symbol_attribute attr;

  if (gfc_is_coindexed (x))
    {
      gfc_error ("Argument X at %L to C_FUNLOC shall not be "
		 "coindexed", &x->where);
      return false;
    }

  attr = gfc_expr_attr (x);

  if (attr.function && !attr.proc_pointer && x->expr_type == EXPR_VARIABLE
      && x->symtree->n.sym == x->symtree->n.sym->result)
    for (gfc_namespace *ns = gfc_current_ns; ns; ns = ns->parent)
      if (x->symtree->n.sym == ns->proc_name)
	{
	  gfc_error ("Function result %qs at %L is invalid as X argument "
		     "to C_FUNLOC", x->symtree->n.sym->name, &x->where);
	  return false;
	}

  if (attr.flavor != FL_PROCEDURE)
    {
      gfc_error ("Argument X at %L to C_FUNLOC shall be a procedure "
		 "or a procedure pointer", &x->where);
      return false;
    }

  if (!attr.is_bind_c)
    return gfc_notify_std (GFC_STD_F2018, "Noninteroperable procedure "
			   "at %L to C_FUNLOC", &x->where);
  return true;
}


bool
gfc_check_c_loc (gfc_expr *x)
{
  symbol_attribute attr;
  const char *msg;

  if (gfc_is_coindexed (x))
    {
      gfc_error ("Argument X at %L to C_LOC shall not be coindexed", &x->where);
      return false;
    }

  if (x->ts.type == BT_CLASS)
    {
      gfc_error ("X argument at %L to C_LOC shall not be polymorphic",
		 &x->where);
      return false;
    }

  attr = gfc_expr_attr (x);

  if (!attr.pointer
      && (x->expr_type != EXPR_VARIABLE || !attr.target
	  || attr.flavor == FL_PARAMETER))
    {
      gfc_error ("Argument X at %L to C_LOC shall have either "
		 "the POINTER or the TARGET attribute", &x->where);
      return false;
    }

  if (x->ts.type == BT_CHARACTER
      && gfc_var_strlen (x) == 0)
    {
      gfc_error ("Argument X at %L to C_LOC shall be not be a zero-sized "
		 "string", &x->where);
      return false;
    }

  if (!is_c_interoperable (x, &msg, true, false))
    {
      if (x->ts.type == BT_CLASS)
	{
	  gfc_error ("Argument at %L to C_LOC shall not be polymorphic",
		     &x->where);
	  return false;
	}

      if (x->rank
	  && !gfc_notify_std (GFC_STD_F2018,
			      "Noninteroperable array at %L as"
			      " argument to C_LOC: %s", &x->where, msg))
	  return false;
    }
  else if (x->rank > 0 && gfc_notification_std (GFC_STD_F2008))
    {
      gfc_array_ref *ar = gfc_find_array_ref (x);

      if (ar->as->type != AS_EXPLICIT && ar->as->type != AS_ASSUMED_SIZE
	  && !attr.allocatable
	  && !gfc_notify_std (GFC_STD_F2008,
			      "Array of interoperable type at %L "
			      "to C_LOC which is nonallocatable and neither "
			      "assumed size nor explicit size", &x->where))
	return false;
      else if (ar->type != AR_FULL
	       && !gfc_notify_std (GFC_STD_F2008, "Array section at %L "
				   "to C_LOC", &x->where))
	return false;
    }

  return true;
}


bool
gfc_check_sleep_sub (gfc_expr *seconds)
{
  if (!type_check (seconds, 0, BT_INTEGER))
    return false;

  if (!scalar_check (seconds, 0))
    return false;

  return true;
}

bool
gfc_check_sngl (gfc_expr *a)
{
  if (!type_check (a, 0, BT_REAL))
    return false;

  if ((a->ts.kind != gfc_default_double_kind)
      && !gfc_notify_std (GFC_STD_GNU, "non double precision "
			  "REAL argument to %s intrinsic at %L",
			  gfc_current_intrinsic, &a->where))
    return false;

  return true;
}

bool
gfc_check_spread (gfc_expr *source, gfc_expr *dim, gfc_expr *ncopies)
{
  if (gfc_invalid_null_arg (source))
    return false;

  if (source->rank >= GFC_MAX_DIMENSIONS)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be less "
		 "than rank %d", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &source->where, GFC_MAX_DIMENSIONS);

      return false;
    }

  if (dim == NULL)
    return false;

  if (!dim_check (dim, 1, false))
    return false;

  /* dim_rank_check() does not apply here.  */
  if (dim
      && dim->expr_type == EXPR_CONSTANT
      && (mpz_cmp_ui (dim->value.integer, 1) < 0
	  || mpz_cmp_ui (dim->value.integer, source->rank + 1) > 0))
    {
      gfc_error ("%qs argument of %qs intrinsic at %L is not a valid "
		 "dimension index", gfc_current_intrinsic_arg[1]->name,
		 gfc_current_intrinsic, &dim->where);
      return false;
    }

  if (!type_check (ncopies, 2, BT_INTEGER))
    return false;

  if (!scalar_check (ncopies, 2))
    return false;

  return true;
}


/* Functions for checking FGETC, FPUTC, FGET and FPUT (subroutines and
   functions).  */

bool
arg_strlen_is_zero (gfc_expr *c, int n)
{
  if (gfc_var_strlen (c) == 0)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must have "
		 "length at least 1", gfc_current_intrinsic_arg[n]->name,
		 gfc_current_intrinsic, &c->where);
      return true;
    }
  return false;
}

bool
gfc_check_fgetputc_sub (gfc_expr *unit, gfc_expr *c, gfc_expr *status)
{
  if (!type_check (unit, 0, BT_INTEGER))
    return false;

  if (!scalar_check (unit, 0))
    return false;

  if (!type_check (c, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (c, 1, gfc_default_character_kind))
    return false;
  if (strcmp (gfc_current_intrinsic, "fgetc") == 0
      && !variable_check (c, 1, false))
    return false;
  if (arg_strlen_is_zero (c, 1))
    return false;

  if (status == NULL)
    return true;

  if (!type_check (status, 2, BT_INTEGER)
      || !kind_value_check (status, 2, gfc_default_integer_kind)
      || !scalar_check (status, 2)
      || !variable_check (status, 2, false))
    return false;

  return true;
}


bool
gfc_check_fgetputc (gfc_expr *unit, gfc_expr *c)
{
  return gfc_check_fgetputc_sub (unit, c, NULL);
}


bool
gfc_check_fgetput_sub (gfc_expr *c, gfc_expr *status)
{
  if (!type_check (c, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (c, 0, gfc_default_character_kind))
    return false;
  if (strcmp (gfc_current_intrinsic, "fget") == 0
      && !variable_check (c, 0, false))
    return false;
  if (arg_strlen_is_zero (c, 0))
    return false;

  if (status == NULL)
    return true;

  if (!type_check (status, 1, BT_INTEGER)
      || !kind_value_check (status, 1, gfc_default_integer_kind)
      || !scalar_check (status, 1)
      || !variable_check (status, 1, false))
    return false;

  return true;
}


bool
gfc_check_fgetput (gfc_expr *c)
{
  return gfc_check_fgetput_sub (c, NULL);
}


bool
gfc_check_fseek_sub (gfc_expr *unit, gfc_expr *offset, gfc_expr *whence, gfc_expr *status)
{
  if (!type_check (unit, 0, BT_INTEGER))
    return false;

  if (!scalar_check (unit, 0))
    return false;

  if (!type_check (offset, 1, BT_INTEGER))
    return false;

  if (!scalar_check (offset, 1))
    return false;

  if (!type_check (whence, 2, BT_INTEGER))
    return false;

  if (!scalar_check (whence, 2))
    return false;

  if (status == NULL)
    return true;

  if (!type_check (status, 3, BT_INTEGER))
    return false;

  if (!kind_value_check (status, 3, 4))
    return false;

  if (!scalar_check (status, 3))
    return false;

  return true;
}



bool
gfc_check_fstat (gfc_expr *unit, gfc_expr *array)
{
  if (!type_check (unit, 0, BT_INTEGER))
    return false;

  if (!scalar_check (unit, 0))
    return false;

  if (!type_check (array, 1, BT_INTEGER)
      || !kind_value_check (unit, 0, gfc_default_integer_kind))
    return false;

  if (!array_check (array, 1))
    return false;

  return true;
}


bool
gfc_check_fstat_sub (gfc_expr *unit, gfc_expr *array, gfc_expr *status)
{
  if (!type_check (unit, 0, BT_INTEGER))
    return false;

  if (!scalar_check (unit, 0))
    return false;

  if (!type_check (array, 1, BT_INTEGER)
      || !kind_value_check (array, 1, gfc_default_integer_kind))
    return false;

  if (!array_check (array, 1))
    return false;

  if (status == NULL)
    return true;

  if (!type_check (status, 2, BT_INTEGER)
      || !kind_value_check (status, 2, gfc_default_integer_kind))
    return false;

  if (!scalar_check (status, 2))
    return false;

  return true;
}


bool
gfc_check_ftell (gfc_expr *unit)
{
  if (!type_check (unit, 0, BT_INTEGER))
    return false;

  if (!scalar_check (unit, 0))
    return false;

  return true;
}


bool
gfc_check_ftell_sub (gfc_expr *unit, gfc_expr *offset)
{
  if (!type_check (unit, 0, BT_INTEGER))
    return false;

  if (!scalar_check (unit, 0))
    return false;

  if (!type_check (offset, 1, BT_INTEGER))
    return false;

  if (!scalar_check (offset, 1))
    return false;

  return true;
}


bool
gfc_check_stat (gfc_expr *name, gfc_expr *array)
{
  if (!type_check (name, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (name, 0, gfc_default_character_kind))
    return false;

  if (!type_check (array, 1, BT_INTEGER)
      || !kind_value_check (array, 1, gfc_default_integer_kind))
    return false;

  if (!array_check (array, 1))
    return false;

  return true;
}


bool
gfc_check_stat_sub (gfc_expr *name, gfc_expr *array, gfc_expr *status)
{
  if (!type_check (name, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (name, 0, gfc_default_character_kind))
    return false;

  if (!type_check (array, 1, BT_INTEGER)
      || !kind_value_check (array, 1, gfc_default_integer_kind))
    return false;

  if (!array_check (array, 1))
    return false;

  if (status == NULL)
    return true;

  if (!type_check (status, 2, BT_INTEGER)
      || !kind_value_check (array, 1, gfc_default_integer_kind))
    return false;

  if (!scalar_check (status, 2))
    return false;

  return true;
}


bool
gfc_check_image_index (gfc_expr *coarray, gfc_expr *sub)
{
  mpz_t nelems;

  if (flag_coarray == GFC_FCOARRAY_NONE)
    {
      gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
      return false;
    }

  if (!coarray_check (coarray, 0))
    return false;

  if (sub->rank != 1)
    {
      gfc_error ("%s argument to IMAGE_INDEX must be a rank one array at %L",
                gfc_current_intrinsic_arg[1]->name, &sub->where);
      return false;
    }

  if (gfc_array_size (sub, &nelems))
    {
      int corank = gfc_get_corank (coarray);

      if (mpz_cmp_ui (nelems, corank) != 0)
	{
	  gfc_error ("The number of array elements of the SUB argument to "
		     "IMAGE_INDEX at %L shall be %d (corank) not %d",
		     &sub->where, corank, (int) mpz_get_si (nelems));
	  mpz_clear (nelems);
	  return false;
	}
      mpz_clear (nelems);
    }

  return true;
}


bool
gfc_check_num_images (gfc_expr *distance, gfc_expr *failed)
{
  if (flag_coarray == GFC_FCOARRAY_NONE)
    {
      gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
      return false;
    }

  if (distance)
    {
      if (!type_check (distance, 0, BT_INTEGER))
	return false;

      if (!nonnegative_check ("DISTANCE", distance))
	return false;

      if (!scalar_check (distance, 0))
	return false;

      if (!gfc_notify_std (GFC_STD_F2018, "DISTANCE= argument to "
			   "NUM_IMAGES at %L", &distance->where))
	return false;
    }

   if (failed)
    {
      if (!type_check (failed, 1, BT_LOGICAL))
	return false;

      if (!scalar_check (failed, 1))
	return false;

      if (!gfc_notify_std (GFC_STD_F2018, "FAILED= argument to "
			   "NUM_IMAGES at %L", &failed->where))
	return false;
    }

  return true;
}


bool
gfc_check_team_number (gfc_expr *team)
{
  if (flag_coarray == GFC_FCOARRAY_NONE)
    {
      gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
      return false;
    }

  if (team)
    {
      if (team->ts.type != BT_DERIVED
	  || team->ts.u.derived->from_intmod != INTMOD_ISO_FORTRAN_ENV
	  || team->ts.u.derived->intmod_sym_id != ISOFORTRAN_TEAM_TYPE)
	 {
	   gfc_error ("TEAM argument at %L to the intrinsic TEAM_NUMBER "
	   	      "shall be of type TEAM_TYPE", &team->where);
	   return false;
	 }
    }
  else
    return true;

  return true;
}


bool
gfc_check_this_image (gfc_expr *coarray, gfc_expr *dim, gfc_expr *distance)
{
  if (flag_coarray == GFC_FCOARRAY_NONE)
    {
      gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
      return false;
    }

  if (coarray == NULL && dim == NULL && distance == NULL)
    return true;

  if (dim != NULL && coarray == NULL)
    {
      gfc_error ("DIM argument without COARRAY argument not allowed for "
		 "THIS_IMAGE intrinsic at %L", &dim->where);
      return false;
    }

  if (distance && (coarray || dim))
    {
      gfc_error ("The DISTANCE argument may not be specified together with the "
		 "COARRAY or DIM argument in intrinsic at %L",
		 &distance->where);
      return false;
    }

  /* Assume that we have "this_image (distance)".  */
  if (coarray && !gfc_is_coarray (coarray) && coarray->ts.type == BT_INTEGER)
    {
      if (dim)
	{
	  gfc_error ("Unexpected DIM argument with noncoarray argument at %L",
		     &coarray->where);
	  return false;
	}
      distance = coarray;
    }

  if (distance)
    {
      if (!type_check (distance, 2, BT_INTEGER))
	return false;

      if (!nonnegative_check ("DISTANCE", distance))
	return false;

      if (!scalar_check (distance, 2))
	return false;

      if (!gfc_notify_std (GFC_STD_F2018, "DISTANCE= argument to "
			   "THIS_IMAGE at %L", &distance->where))
	return false;

      return true;
    }

  if (!coarray_check (coarray, 0))
    return false;

  if (dim != NULL)
    {
      if (!dim_check (dim, 1, false))
       return false;

      if (!dim_corank_check (dim, coarray))
       return false;
    }

  return true;
}

/* Calculate the sizes for transfer, used by gfc_check_transfer and also
   by gfc_simplify_transfer.  Return false if we cannot do so.  */

bool
gfc_calculate_transfer_sizes (gfc_expr *source, gfc_expr *mold, gfc_expr *size,
			      size_t *source_size, size_t *result_size,
			      size_t *result_length_p)
{
  size_t result_elt_size;

  if (source->expr_type == EXPR_FUNCTION)
    return false;

  if (size && size->expr_type != EXPR_CONSTANT)
    return false;

  /* Calculate the size of the source.  */
  if (!gfc_target_expr_size (source, source_size))
    return false;

  /* Determine the size of the element.  */
  if (!gfc_element_size (mold, &result_elt_size))
    return false;

  /* If the storage size of SOURCE is greater than zero and MOLD is an array,
   * a scalar with the type and type parameters of MOLD shall not have a
   * storage size equal to zero.
   * If MOLD is a scalar and SIZE is absent, the result is a scalar.
   * If MOLD is an array and SIZE is absent, the result is an array and of
   * rank one. Its size is as small as possible such that its physical
   * representation is not shorter than that of SOURCE.
   * If SIZE is present, the result is an array of rank one and size SIZE.
   */
  if (result_elt_size == 0 && *source_size > 0 && !size
      && mold->expr_type == EXPR_ARRAY)
    {
      gfc_error ("%<MOLD%> argument of %<TRANSFER%> intrinsic at %L is an "
		 "array and shall not have storage size 0 when %<SOURCE%> "
		 "argument has size greater than 0", &mold->where);
      return false;
    }

  if (result_elt_size == 0 && *source_size == 0 && !size)
    {
      *result_size = 0;
      if (result_length_p)
	*result_length_p = 0;
      return true;
    }

  if ((result_elt_size > 0 && (mold->expr_type == EXPR_ARRAY || mold->rank))
      || size)
    {
      int result_length;

      if (size)
	result_length = (size_t)mpz_get_ui (size->value.integer);
      else
	{
	  result_length = *source_size / result_elt_size;
	  if (result_length * result_elt_size < *source_size)
	    result_length += 1;
	}

      *result_size = result_length * result_elt_size;
      if (result_length_p)
	*result_length_p = result_length;
    }
  else
    *result_size = result_elt_size;

  return true;
}


bool
gfc_check_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
{
  size_t source_size;
  size_t result_size;

  if (gfc_invalid_null_arg (source))
    return false;

  /* SOURCE shall be a scalar or array of any type.  */
  if (source->ts.type == BT_PROCEDURE
      && source->symtree->n.sym->attr.subroutine == 1)
    {
      gfc_error ("%<SOURCE%> argument of %<TRANSFER%> intrinsic at %L "
                 "must not be a %s", &source->where,
		 gfc_basic_typename (source->ts.type));
      return false;
    }

  if (source->ts.type == BT_BOZ && illegal_boz_arg (source))
    return false;

  if (mold->ts.type == BT_BOZ && illegal_boz_arg (mold))
    return false;

  if (gfc_invalid_null_arg (mold))
    return false;

  /* MOLD shall be a scalar or array of any type.  */
  if (mold->ts.type == BT_PROCEDURE
      && mold->symtree->n.sym->attr.subroutine == 1)
    {
      gfc_error ("%<MOLD%> argument of %<TRANSFER%> intrinsic at %L "
                 "must not be a %s", &mold->where,
		 gfc_basic_typename (mold->ts.type));
      return false;
    }

  if (mold->ts.type == BT_HOLLERITH)
    {
      gfc_error ("%<MOLD%> argument of %<TRANSFER%> intrinsic at %L must not be"
                 " %s", &mold->where, gfc_basic_typename (BT_HOLLERITH));
      return false;
    }

  /* SIZE (optional) shall be an integer scalar.  The corresponding actual
     argument shall not be an optional dummy argument.  */
  if (size != NULL)
    {
      if (!type_check (size, 2, BT_INTEGER))
	{
	  if (size->ts.type == BT_BOZ)
	    reset_boz (size);
	  return false;
	}

      if (!scalar_check (size, 2))
	return false;

      if (!nonoptional_check (size, 2))
	return false;
    }

  if (!warn_surprising)
    return true;

  /* If we can't calculate the sizes, we cannot check any more.
     Return true for that case.  */

  if (!gfc_calculate_transfer_sizes (source, mold, size, &source_size,
				     &result_size, NULL))
    return true;

  if (source_size < result_size)
    gfc_warning (OPT_Wsurprising,
		 "Intrinsic TRANSFER at %L has partly undefined result: "
		 "source size %ld < result size %ld", &source->where,
		 (long) source_size, (long) result_size);

  return true;
}


bool
gfc_check_transpose (gfc_expr *matrix)
{
  if (!rank_check (matrix, 0, 2))
    return false;

  return true;
}


bool
gfc_check_ubound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
{
  if (!array_check (array, 0))
    return false;

  if (!dim_check (dim, 1, false))
    return false;

  if (!dim_rank_check (dim, array, 0))
    return false;

  if (!kind_check (kind, 2, BT_INTEGER))
    return false;
  if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
			       "with KIND argument at %L",
			       gfc_current_intrinsic, &kind->where))
    return false;

  return true;
}


bool
gfc_check_ucobound (gfc_expr *coarray, gfc_expr *dim, gfc_expr *kind)
{
  if (flag_coarray == GFC_FCOARRAY_NONE)
    {
      gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
      return false;
    }

  if (!coarray_check (coarray, 0))
    return false;

  if (dim != NULL)
    {
      if (!dim_check (dim, 1, false))
        return false;

      if (!dim_corank_check (dim, coarray))
        return false;
    }

  if (!kind_check (kind, 2, BT_INTEGER))
    return false;

  return true;
}


bool
gfc_check_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
{
  mpz_t vector_size;

  if (!rank_check (vector, 0, 1))
    return false;

  if (!array_check (mask, 1))
    return false;

  if (!type_check (mask, 1, BT_LOGICAL))
    return false;

  if (!same_type_check (vector, 0, field, 2))
    return false;

  if (mask->expr_type == EXPR_ARRAY
      && gfc_array_size (vector, &vector_size))
    {
      int mask_true_count = 0;
      gfc_constructor *mask_ctor;
      mask_ctor = gfc_constructor_first (mask->value.constructor);
      while (mask_ctor)
	{
	  if (mask_ctor->expr->expr_type != EXPR_CONSTANT)
	    {
	      mask_true_count = 0;
	      break;
	    }

	  if (mask_ctor->expr->value.logical)
	    mask_true_count++;

	  mask_ctor = gfc_constructor_next (mask_ctor);
	}

      if (mpz_get_si (vector_size) < mask_true_count)
	{
	  gfc_error ("%qs argument of %qs intrinsic at %L must "
		     "provide at least as many elements as there "
		     "are .TRUE. values in %qs (%ld/%d)",
		     gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		     &vector->where, gfc_current_intrinsic_arg[1]->name,
		     mpz_get_si (vector_size), mask_true_count);
	  return false;
	}

      mpz_clear (vector_size);
    }

  if (mask->rank != field->rank && field->rank != 0)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must have "
		 "the same rank as %qs or be a scalar",
		 gfc_current_intrinsic_arg[2]->name, gfc_current_intrinsic,
		 &field->where, gfc_current_intrinsic_arg[1]->name);
      return false;
    }

  if (mask->rank == field->rank)
    {
      int i;
      for (i = 0; i < field->rank; i++)
	if (! identical_dimen_shape (mask, i, field, i))
	{
	  gfc_error ("%qs and %qs arguments of %qs intrinsic at %L "
		     "must have identical shape.",
		     gfc_current_intrinsic_arg[2]->name,
		     gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		     &field->where);
	}
    }

  return true;
}


bool
gfc_check_verify (gfc_expr *x, gfc_expr *y, gfc_expr *z, gfc_expr *kind)
{
  if (!type_check (x, 0, BT_CHARACTER))
    return false;

  if (!same_type_check (x, 0, y, 1))
    return false;

  if (z != NULL && !type_check (z, 2, BT_LOGICAL))
    return false;

  if (!kind_check (kind, 3, BT_INTEGER))
    return false;
  if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
			       "with KIND argument at %L",
			       gfc_current_intrinsic, &kind->where))
    return false;

  return true;
}


bool
gfc_check_trim (gfc_expr *x)
{
  if (!type_check (x, 0, BT_CHARACTER))
    return false;

  if (gfc_invalid_null_arg (x))
    return false;

  if (!scalar_check (x, 0))
    return false;

   return true;
}


bool
gfc_check_ttynam (gfc_expr *unit)
{
  if (!scalar_check (unit, 0))
    return false;

  if (!type_check (unit, 0, BT_INTEGER))
    return false;

  return true;
}


/************* Check functions for intrinsic subroutines *************/

bool
gfc_check_cpu_time (gfc_expr *time)
{
  if (!scalar_check (time, 0))
    return false;

  if (!type_check (time, 0, BT_REAL))
    return false;

  if (!variable_check (time, 0, false))
    return false;

  return true;
}


bool
gfc_check_date_and_time (gfc_expr *date, gfc_expr *time,
			 gfc_expr *zone, gfc_expr *values)
{
  if (date != NULL)
    {
      if (!type_check (date, 0, BT_CHARACTER))
	return false;
      if (!kind_value_check (date, 0, gfc_default_character_kind))
	return false;
      if (!scalar_check (date, 0))
	return false;
      if (!variable_check (date, 0, false))
	return false;
    }

  if (time != NULL)
    {
      if (!type_check (time, 1, BT_CHARACTER))
	return false;
      if (!kind_value_check (time, 1, gfc_default_character_kind))
	return false;
      if (!scalar_check (time, 1))
	return false;
      if (!variable_check (time, 1, false))
	return false;
    }

  if (zone != NULL)
    {
      if (!type_check (zone, 2, BT_CHARACTER))
	return false;
      if (!kind_value_check (zone, 2, gfc_default_character_kind))
	return false;
      if (!scalar_check (zone, 2))
	return false;
      if (!variable_check (zone, 2, false))
	return false;
    }

  if (values != NULL)
    {
      if (!type_check (values, 3, BT_INTEGER))
	return false;
      if (!array_check (values, 3))
	return false;
      if (!rank_check (values, 3, 1))
	return false;
      if (!variable_check (values, 3, false))
	return false;
    }

  return true;
}


bool
gfc_check_mvbits (gfc_expr *from, gfc_expr *frompos, gfc_expr *len,
		  gfc_expr *to, gfc_expr *topos)
{
  if (!type_check (from, 0, BT_INTEGER))
    return false;

  if (!type_check (frompos, 1, BT_INTEGER))
    return false;

  if (!type_check (len, 2, BT_INTEGER))
    return false;

  if (!same_type_check (from, 0, to, 3))
    return false;

  if (!variable_check (to, 3, false))
    return false;

  if (!type_check (topos, 4, BT_INTEGER))
    return false;

  if (!nonnegative_check ("frompos", frompos))
    return false;

  if (!nonnegative_check ("topos", topos))
    return false;

  if (!nonnegative_check ("len", len))
    return false;

  if (!less_than_bitsize2 ("from", from, "frompos", frompos, "len", len))
    return false;

  if (!less_than_bitsize2 ("to", to, "topos", topos, "len", len))
    return false;

  return true;
}


/* Check the arguments for RANDOM_INIT.  */

bool
gfc_check_random_init (gfc_expr *repeatable, gfc_expr *image_distinct)
{
  if (!type_check (repeatable, 0, BT_LOGICAL))
    return false;

  if (!scalar_check (repeatable, 0))
    return false;

  if (!type_check (image_distinct, 1, BT_LOGICAL))
    return false;

  if (!scalar_check (image_distinct, 1))
    return false;

  return true;
}


bool
gfc_check_random_number (gfc_expr *harvest)
{
  if (!type_check (harvest, 0, BT_REAL))
    return false;

  if (!variable_check (harvest, 0, false))
    return false;

  return true;
}


bool
gfc_check_random_seed (gfc_expr *size, gfc_expr *put, gfc_expr *get)
{
  unsigned int nargs = 0, seed_size;
  locus *where = NULL;
  mpz_t put_size, get_size;

  /* Keep the number of bytes in sync with master_state in
     libgfortran/intrinsics/random.c.  */
  seed_size = 32 / gfc_default_integer_kind;

  if (size != NULL)
    {
      if (size->expr_type != EXPR_VARIABLE
	  || !size->symtree->n.sym->attr.optional)
	nargs++;

      if (!scalar_check (size, 0))
	return false;

      if (!type_check (size, 0, BT_INTEGER))
	return false;

      if (!variable_check (size, 0, false))
	return false;

      if (!kind_value_check (size, 0, gfc_default_integer_kind))
	return false;
    }

  if (put != NULL)
    {
      if (put->expr_type != EXPR_VARIABLE
	  || !put->symtree->n.sym->attr.optional)
	{
	  nargs++;
	  where = &put->where;
	}

      if (!array_check (put, 1))
	return false;

      if (!rank_check (put, 1, 1))
	return false;

      if (!type_check (put, 1, BT_INTEGER))
	return false;

      if (!kind_value_check (put, 1, gfc_default_integer_kind))
	return false;

      if (gfc_array_size (put, &put_size)
	  && mpz_get_ui (put_size) < seed_size)
	gfc_error ("Size of %qs argument of %qs intrinsic at %L "
		   "too small (%i/%i)",
		   gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		   &put->where, (int) mpz_get_ui (put_size), seed_size);
    }

  if (get != NULL)
    {
      if (get->expr_type != EXPR_VARIABLE
	  || !get->symtree->n.sym->attr.optional)
	{
	  nargs++;
	  where = &get->where;
	}

      if (!array_check (get, 2))
	return false;

      if (!rank_check (get, 2, 1))
	return false;

      if (!type_check (get, 2, BT_INTEGER))
	return false;

      if (!variable_check (get, 2, false))
	return false;

      if (!kind_value_check (get, 2, gfc_default_integer_kind))
	return false;

       if (gfc_array_size (get, &get_size)
	   && mpz_get_ui (get_size) < seed_size)
	gfc_error ("Size of %qs argument of %qs intrinsic at %L "
		   "too small (%i/%i)",
		   gfc_current_intrinsic_arg[2]->name, gfc_current_intrinsic,
		   &get->where, (int) mpz_get_ui (get_size), seed_size);
    }

  /* RANDOM_SEED may not have more than one non-optional argument.  */
  if (nargs > 1)
    gfc_error ("Too many arguments to %s at %L", gfc_current_intrinsic, where);

  return true;
}

bool
gfc_check_fe_runtime_error (gfc_actual_arglist *a)
{
  gfc_expr *e;
  size_t len, i;
  int num_percent, nargs;

  e = a->expr;
  if (e->expr_type != EXPR_CONSTANT)
    return true;

  len = e->value.character.length;
  if (e->value.character.string[len-1] != '\0')
    gfc_internal_error ("fe_runtime_error string must be null terminated");

  num_percent = 0;
  for (i=0; i<len-1; i++)
    if (e->value.character.string[i] == '%')
      num_percent ++;

  nargs = 0;
  for (; a; a = a->next)
    nargs ++;

  if (nargs -1 != num_percent)
    gfc_internal_error ("fe_runtime_error: Wrong number of arguments (%d instead of %d)",
			nargs, num_percent++);

  return true;
}

bool
gfc_check_second_sub (gfc_expr *time)
{
  if (!scalar_check (time, 0))
    return false;

  if (!type_check (time, 0, BT_REAL))
    return false;

  if (!kind_value_check (time, 0, 4))
    return false;

  return true;
}


/* COUNT and COUNT_MAX of SYSTEM_CLOCK are scalar, default-kind integer
   variables in Fortran 95.  In Fortran 2003 and later, they can be of any
   kind, and COUNT_RATE can be of type real.  Note, count, count_rate, and
   count_max are all optional arguments */

bool
gfc_check_system_clock (gfc_expr *count, gfc_expr *count_rate,
			gfc_expr *count_max)
{
  if (count != NULL)
    {
      if (!scalar_check (count, 0))
	return false;

      if (!type_check (count, 0, BT_INTEGER))
	return false;

      if (count->ts.kind != gfc_default_integer_kind
	  && !gfc_notify_std (GFC_STD_F2003, "COUNT argument to "
			      "SYSTEM_CLOCK at %L has non-default kind",
			      &count->where))
	return false;

      if (!variable_check (count, 0, false))
	return false;
    }

  if (count_rate != NULL)
    {
      if (!scalar_check (count_rate, 1))
	return false;

      if (!variable_check (count_rate, 1, false))
	return false;

      if (count_rate->ts.type == BT_REAL)
	{
	  if (!gfc_notify_std (GFC_STD_F2003, "Real COUNT_RATE argument to "
			       "SYSTEM_CLOCK at %L", &count_rate->where))
	    return false;
	}
      else
	{
	  if (!type_check (count_rate, 1, BT_INTEGER))
	    return false;

	  if (count_rate->ts.kind != gfc_default_integer_kind
	      && !gfc_notify_std (GFC_STD_F2003, "COUNT_RATE argument to "
				  "SYSTEM_CLOCK at %L has non-default kind",
				  &count_rate->where))
	    return false;
	}

    }

  if (count_max != NULL)
    {
      if (!scalar_check (count_max, 2))
	return false;

      if (!type_check (count_max, 2, BT_INTEGER))
	return false;

      if (count_max->ts.kind != gfc_default_integer_kind
	  && !gfc_notify_std (GFC_STD_F2003, "COUNT_MAX argument to "
			      "SYSTEM_CLOCK at %L has non-default kind",
			      &count_max->where))
	return false;

      if (!variable_check (count_max, 2, false))
	return false;
    }

  return true;
}


bool
gfc_check_irand (gfc_expr *x)
{
  if (x == NULL)
    return true;

  if (!scalar_check (x, 0))
    return false;

  if (!type_check (x, 0, BT_INTEGER))
    return false;

  if (!kind_value_check (x, 0, 4))
    return false;

  return true;
}


bool
gfc_check_alarm_sub (gfc_expr *seconds, gfc_expr *handler, gfc_expr *status)
{
  if (!scalar_check (seconds, 0))
    return false;
  if (!type_check (seconds, 0, BT_INTEGER))
    return false;

  if (!int_or_proc_check (handler, 1))
    return false;
  if (handler->ts.type == BT_INTEGER && !scalar_check (handler, 1))
    return false;

  if (status == NULL)
    return true;

  if (!scalar_check (status, 2))
    return false;
  if (!type_check (status, 2, BT_INTEGER))
    return false;
  if (!kind_value_check (status, 2, gfc_default_integer_kind))
    return false;

  return true;
}


bool
gfc_check_rand (gfc_expr *x)
{
  if (x == NULL)
    return true;

  if (!scalar_check (x, 0))
    return false;

  if (!type_check (x, 0, BT_INTEGER))
    return false;

  if (!kind_value_check (x, 0, 4))
    return false;

  return true;
}


bool
gfc_check_srand (gfc_expr *x)
{
  if (!scalar_check (x, 0))
    return false;

  if (!type_check (x, 0, BT_INTEGER))
    return false;

  if (!kind_value_check (x, 0, 4))
    return false;

  return true;
}


bool
gfc_check_ctime_sub (gfc_expr *time, gfc_expr *result)
{
  if (!scalar_check (time, 0))
    return false;
  if (!type_check (time, 0, BT_INTEGER))
    return false;

  if (!type_check (result, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (result, 1, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_dtime_etime (gfc_expr *x)
{
  if (!array_check (x, 0))
    return false;

  if (!rank_check (x, 0, 1))
    return false;

  if (!variable_check (x, 0, false))
    return false;

  if (!type_check (x, 0, BT_REAL))
    return false;

  if (!kind_value_check (x, 0, 4))
    return false;

  return true;
}


bool
gfc_check_dtime_etime_sub (gfc_expr *values, gfc_expr *time)
{
  if (!array_check (values, 0))
    return false;

  if (!rank_check (values, 0, 1))
    return false;

  if (!variable_check (values, 0, false))
    return false;

  if (!type_check (values, 0, BT_REAL))
    return false;

  if (!kind_value_check (values, 0, 4))
    return false;

  if (!scalar_check (time, 1))
    return false;

  if (!type_check (time, 1, BT_REAL))
    return false;

  if (!kind_value_check (time, 1, 4))
    return false;

  return true;
}


bool
gfc_check_fdate_sub (gfc_expr *date)
{
  if (!type_check (date, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (date, 0, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_gerror (gfc_expr *msg)
{
  if (!type_check (msg, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (msg, 0, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_getcwd_sub (gfc_expr *cwd, gfc_expr *status)
{
  if (!type_check (cwd, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (cwd, 0, gfc_default_character_kind))
    return false;

  if (status == NULL)
    return true;

  if (!scalar_check (status, 1))
    return false;

  if (!type_check (status, 1, BT_INTEGER))
    return false;

  return true;
}


bool
gfc_check_getarg (gfc_expr *pos, gfc_expr *value)
{
  if (!type_check (pos, 0, BT_INTEGER))
    return false;

  if (pos->ts.kind > gfc_default_integer_kind)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be of a kind "
		 "not wider than the default kind (%d)",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &pos->where, gfc_default_integer_kind);
      return false;
    }

  if (!type_check (value, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (value, 1, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_getlog (gfc_expr *msg)
{
  if (!type_check (msg, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (msg, 0, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_exit (gfc_expr *status)
{
  if (status == NULL)
    return true;

  if (!type_check (status, 0, BT_INTEGER))
    return false;

  if (!scalar_check (status, 0))
    return false;

  return true;
}


bool
gfc_check_flush (gfc_expr *unit)
{
  if (unit == NULL)
    return true;

  if (!type_check (unit, 0, BT_INTEGER))
    return false;

  if (!scalar_check (unit, 0))
    return false;

  return true;
}


bool
gfc_check_free (gfc_expr *i)
{
  if (!type_check (i, 0, BT_INTEGER))
    return false;

  if (!scalar_check (i, 0))
    return false;

  return true;
}


bool
gfc_check_hostnm (gfc_expr *name)
{
  if (!type_check (name, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (name, 0, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_hostnm_sub (gfc_expr *name, gfc_expr *status)
{
  if (!type_check (name, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (name, 0, gfc_default_character_kind))
    return false;

  if (status == NULL)
    return true;

  if (!scalar_check (status, 1))
    return false;

  if (!type_check (status, 1, BT_INTEGER))
    return false;

  return true;
}


bool
gfc_check_itime_idate (gfc_expr *values)
{
  if (!array_check (values, 0))
    return false;

  if (!rank_check (values, 0, 1))
    return false;

  if (!variable_check (values, 0, false))
    return false;

  if (!type_check (values, 0, BT_INTEGER))
    return false;

  if (!kind_value_check (values, 0, gfc_default_integer_kind))
    return false;

  return true;
}


bool
gfc_check_ltime_gmtime (gfc_expr *time, gfc_expr *values)
{
  if (!type_check (time, 0, BT_INTEGER))
    return false;

  if (!kind_value_check (time, 0, gfc_default_integer_kind))
    return false;

  if (!scalar_check (time, 0))
    return false;

  if (!array_check (values, 1))
    return false;

  if (!rank_check (values, 1, 1))
    return false;

  if (!variable_check (values, 1, false))
    return false;

  if (!type_check (values, 1, BT_INTEGER))
    return false;

  if (!kind_value_check (values, 1, gfc_default_integer_kind))
    return false;

  return true;
}


bool
gfc_check_ttynam_sub (gfc_expr *unit, gfc_expr *name)
{
  if (!scalar_check (unit, 0))
    return false;

  if (!type_check (unit, 0, BT_INTEGER))
    return false;

  if (!type_check (name, 1, BT_CHARACTER))
    return false;
  if (!kind_value_check (name, 1, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_is_contiguous (gfc_expr *array)
{
  if (array->expr_type == EXPR_NULL)
    {
      gfc_error ("Actual argument at %L of %qs intrinsic shall be an "
		 "associated pointer", &array->where, gfc_current_intrinsic);
      return false;
    }

  if (!array_check (array, 0))
    return false;

  return true;
}


bool
gfc_check_isatty (gfc_expr *unit)
{
  if (unit == NULL)
    return false;

  if (!type_check (unit, 0, BT_INTEGER))
    return false;

  if (!scalar_check (unit, 0))
    return false;

  return true;
}


bool
gfc_check_isnan (gfc_expr *x)
{
  if (!type_check (x, 0, BT_REAL))
    return false;

  return true;
}


bool
gfc_check_perror (gfc_expr *string)
{
  if (!type_check (string, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (string, 0, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_umask (gfc_expr *mask)
{
  if (!type_check (mask, 0, BT_INTEGER))
    return false;

  if (!scalar_check (mask, 0))
    return false;

  return true;
}


bool
gfc_check_umask_sub (gfc_expr *mask, gfc_expr *old)
{
  if (!type_check (mask, 0, BT_INTEGER))
    return false;

  if (!scalar_check (mask, 0))
    return false;

  if (old == NULL)
    return true;

  if (!scalar_check (old, 1))
    return false;

  if (!type_check (old, 1, BT_INTEGER))
    return false;

  return true;
}


bool
gfc_check_unlink (gfc_expr *name)
{
  if (!type_check (name, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (name, 0, gfc_default_character_kind))
    return false;

  return true;
}


bool
gfc_check_unlink_sub (gfc_expr *name, gfc_expr *status)
{
  if (!type_check (name, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (name, 0, gfc_default_character_kind))
    return false;

  if (status == NULL)
    return true;

  if (!scalar_check (status, 1))
    return false;

  if (!type_check (status, 1, BT_INTEGER))
    return false;

  return true;
}


bool
gfc_check_signal (gfc_expr *number, gfc_expr *handler)
{
  if (!scalar_check (number, 0))
    return false;
  if (!type_check (number, 0, BT_INTEGER))
    return false;

  if (!int_or_proc_check (handler, 1))
    return false;
  if (handler->ts.type == BT_INTEGER && !scalar_check (handler, 1))
    return false;

  return true;
}


bool
gfc_check_signal_sub (gfc_expr *number, gfc_expr *handler, gfc_expr *status)
{
  if (!scalar_check (number, 0))
    return false;
  if (!type_check (number, 0, BT_INTEGER))
    return false;

  if (!int_or_proc_check (handler, 1))
    return false;
  if (handler->ts.type == BT_INTEGER && !scalar_check (handler, 1))
    return false;

  if (status == NULL)
    return true;

  if (!type_check (status, 2, BT_INTEGER))
    return false;
  if (!scalar_check (status, 2))
    return false;

  return true;
}


bool
gfc_check_system_sub (gfc_expr *cmd, gfc_expr *status)
{
  if (!type_check (cmd, 0, BT_CHARACTER))
    return false;
  if (!kind_value_check (cmd, 0, gfc_default_character_kind))
    return false;

  if (!scalar_check (status, 1))
    return false;

  if (!type_check (status, 1, BT_INTEGER))
    return false;

  if (!kind_value_check (status, 1, gfc_default_integer_kind))
    return false;

  return true;
}


/* This is used for the GNU intrinsics AND, OR and XOR.  */
bool
gfc_check_and (gfc_expr *i, gfc_expr *j)
{
  if (i->ts.type != BT_INTEGER
      && i->ts.type != BT_LOGICAL
      && i->ts.type != BT_BOZ)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be INTEGER, "
                 "LOGICAL, or a BOZ literal constant",
		 gfc_current_intrinsic_arg[0]->name,
                 gfc_current_intrinsic, &i->where);
      return false;
    }

  if (j->ts.type != BT_INTEGER
      && j->ts.type != BT_LOGICAL
      && j->ts.type != BT_BOZ)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be INTEGER, "
                 "LOGICAL, or a BOZ literal constant",
		 gfc_current_intrinsic_arg[1]->name,
                 gfc_current_intrinsic, &j->where);
      return false;
    }

  /* i and j cannot both be BOZ literal constants.  */
  if (!boz_args_check (i, j))
    return false;

  /* If i is BOZ and j is integer, convert i to type of j.  */
  if (i->ts.type == BT_BOZ)
    {
      if (j->ts.type != BT_INTEGER)
	{
	  gfc_error ("%qs argument of %qs intrinsic at %L must be INTEGER",
		     gfc_current_intrinsic_arg[1]->name,
		     gfc_current_intrinsic, &j->where);
	  reset_boz (i);
	  return false;
	}
      if (!gfc_boz2int (i, j->ts.kind))
	return false;
    }

  /* If j is BOZ and i is integer, convert j to type of i.  */
  if (j->ts.type == BT_BOZ)
    {
      if (i->ts.type != BT_INTEGER)
	{
	  gfc_error ("%qs argument of %qs intrinsic at %L must be INTEGER",
		     gfc_current_intrinsic_arg[0]->name,
		     gfc_current_intrinsic, &j->where);
	  reset_boz (j);
	  return false;
	}
      if (!gfc_boz2int (j, i->ts.kind))
	return false;
    }

  if (!same_type_check (i, 0, j, 1, false))
    return false;

  if (!scalar_check (i, 0))
    return false;

  if (!scalar_check (j, 1))
    return false;

  return true;
}


bool
gfc_check_storage_size (gfc_expr *a, gfc_expr *kind)
{

  if (a->expr_type == EXPR_NULL)
    {
      gfc_error ("Intrinsic function NULL at %L cannot be an actual "
		 "argument to STORAGE_SIZE, because it returns a "
		 "disassociated pointer", &a->where);
      return false;
    }

  if (a->ts.type == BT_ASSUMED)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L shall not be TYPE(*)",
		 gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
		 &a->where);
      return false;
    }

  if (a->ts.type == BT_PROCEDURE)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L shall not be a "
		 "procedure", gfc_current_intrinsic_arg[0]->name,
		 gfc_current_intrinsic, &a->where);
      return false;
    }

  if (a->ts.type == BT_BOZ && illegal_boz_arg (a))
    return false;

  if (kind == NULL)
    return true;

  if (!type_check (kind, 1, BT_INTEGER))
    return false;

  if (!scalar_check (kind, 1))
    return false;

  if (kind->expr_type != EXPR_CONSTANT)
    {
      gfc_error ("%qs argument of %qs intrinsic at %L must be a constant",
		 gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
		 &kind->where);
      return false;
    }

  return true;
}
