/* Check functions
   Copyright (C) 2002-2022 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.cc(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_check_vardef_context (e, false, true, false, NULL))
    {
      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.cc(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 && target->ref)
    {
      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 ("OPERATION 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 OPERATION 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 "
		 "OPERATION 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 OPERATION 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 OPERATION 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 OPERATION 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 OPERATION 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 OPERATION 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 OPERATION 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 OPERATION 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 OPERATION 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 removed.  "
		 "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_check (dim, 1, false))
    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_check (dim, 1, false))
    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;
  bool shape_is_const;

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

  gfc_simplify_expr (shape, 0);
  shape_is_const = gfc_is_constant_expr (shape);

  if (shape->expr_type == EXPR_ARRAY && shape_is_const)
    {
      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, &shape->where, extent);
	      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 && shape_is_const
      && !(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;

  if (source->ref == NULL)
    return false;

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

  if (illegal_boz_arg (arg))
    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->expr_type == EXPR_NULL)
    {
      *msg = "NULL() is not interoperable";
      return false;
    }

  if (expr->ts.type == BT_BOZ)
    {
      *msg = "BOZ literal constant";
      return false;
    }

  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 (sub->ts.type != BT_INTEGER)
    {
      gfc_error ("Type of %s argument of IMAGE_INDEX at %L shall be INTEGER",
		 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
      && (mold->expr_type == EXPR_ARRAY || mold->rank))
    {
      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;
}
