/* Primary expression subroutines
   Copyright (C) 2000-2022 Free Software Foundation, Inc.
   Contributed by Andy Vaught

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "options.h"
#include "gfortran.h"
#include "arith.h"
#include "match.h"
#include "parse.h"
#include "constructor.h"

int matching_actual_arglist = 0;

/* Matches a kind-parameter expression, which is either a named
   symbolic constant or a nonnegative integer constant.  If
   successful, sets the kind value to the correct integer.
   The argument 'is_iso_c' signals whether the kind is an ISO_C_BINDING
   symbol like e.g. 'c_int'.  */

static match
match_kind_param (int *kind, int *is_iso_c)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym;
  match m;

  *is_iso_c = 0;

  m = gfc_match_small_literal_int (kind, NULL, false);
  if (m != MATCH_NO)
    return m;

  m = gfc_match_name (name, false);
  if (m != MATCH_YES)
    return m;

  if (gfc_find_symbol (name, NULL, 1, &sym))
    return MATCH_ERROR;

  if (sym == NULL)
    return MATCH_NO;

  *is_iso_c = sym->attr.is_iso_c;

  if (sym->attr.flavor != FL_PARAMETER)
    return MATCH_NO;

  if (sym->value == NULL)
    return MATCH_NO;

  if (gfc_extract_int (sym->value, kind))
    return MATCH_NO;

  gfc_set_sym_referenced (sym);

  if (*kind < 0)
    return MATCH_NO;

  return MATCH_YES;
}


/* Get a trailing kind-specification for non-character variables.
   Returns:
     * the integer kind value or
     * -1 if an error was generated,
     * -2 if no kind was found.
   The argument 'is_iso_c' signals whether the kind is an ISO_C_BINDING
   symbol like e.g. 'c_int'.  */

static int
get_kind (int *is_iso_c)
{
  int kind;
  match m;

  *is_iso_c = 0;

  if (gfc_match_char ('_', false) != MATCH_YES)
    return -2;

  m = match_kind_param (&kind, is_iso_c);
  if (m == MATCH_NO)
    gfc_error ("Missing kind-parameter at %C");

  return (m == MATCH_YES) ? kind : -1;
}


/* Given a character and a radix, see if the character is a valid
   digit in that radix.  */

int
gfc_check_digit (char c, int radix)
{
  int r;

  switch (radix)
    {
    case 2:
      r = ('0' <= c && c <= '1');
      break;

    case 8:
      r = ('0' <= c && c <= '7');
      break;

    case 10:
      r = ('0' <= c && c <= '9');
      break;

    case 16:
      r = ISXDIGIT (c);
      break;

    default:
      gfc_internal_error ("gfc_check_digit(): bad radix");
    }

  return r;
}


/* Match the digit string part of an integer if signflag is not set,
   the signed digit string part if signflag is set.  If the buffer
   is NULL, we just count characters for the resolution pass.  Returns
   the number of characters matched, -1 for no match.  */

static int
match_digits (int signflag, int radix, char *buffer)
{
  locus old_loc;
  int length;
  char c;

  length = 0;
  c = gfc_next_ascii_char ();

  if (signflag && (c == '+' || c == '-'))
    {
      if (buffer != NULL)
	*buffer++ = c;
      gfc_gobble_whitespace ();
      c = gfc_next_ascii_char ();
      length++;
    }

  if (!gfc_check_digit (c, radix))
    return -1;

  length++;
  if (buffer != NULL)
    *buffer++ = c;

  for (;;)
    {
      old_loc = gfc_current_locus;
      c = gfc_next_ascii_char ();

      if (!gfc_check_digit (c, radix))
	break;

      if (buffer != NULL)
	*buffer++ = c;
      length++;
    }

  gfc_current_locus = old_loc;

  return length;
}

/* Convert an integer string to an expression node.  */

static gfc_expr *
convert_integer (const char *buffer, int kind, int radix, locus *where)
{
  gfc_expr *e;
  const char *t;

  e = gfc_get_constant_expr (BT_INTEGER, kind, where);
  /* A leading plus is allowed, but not by mpz_set_str.  */
  if (buffer[0] == '+')
    t = buffer + 1;
  else
    t = buffer;
  mpz_set_str (e->value.integer, t, radix);

  return e;
}


/* Convert a real string to an expression node.  */

static gfc_expr *
convert_real (const char *buffer, int kind, locus *where)
{
  gfc_expr *e;

  e = gfc_get_constant_expr (BT_REAL, kind, where);
  mpfr_set_str (e->value.real, buffer, 10, GFC_RND_MODE);

  return e;
}


/* Convert a pair of real, constant expression nodes to a single
   complex expression node.  */

static gfc_expr *
convert_complex (gfc_expr *real, gfc_expr *imag, int kind)
{
  gfc_expr *e;

  e = gfc_get_constant_expr (BT_COMPLEX, kind, &real->where);
  mpc_set_fr_fr (e->value.complex, real->value.real, imag->value.real,
		 GFC_MPC_RND_MODE);

  return e;
}


/* Match an integer (digit string and optional kind).
   A sign will be accepted if signflag is set.  */

static match
match_integer_constant (gfc_expr **result, int signflag)
{
  int length, kind, is_iso_c;
  locus old_loc;
  char *buffer;
  gfc_expr *e;

  old_loc = gfc_current_locus;
  gfc_gobble_whitespace ();

  length = match_digits (signflag, 10, NULL);
  gfc_current_locus = old_loc;
  if (length == -1)
    return MATCH_NO;

  buffer = (char *) alloca (length + 1);
  memset (buffer, '\0', length + 1);

  gfc_gobble_whitespace ();

  match_digits (signflag, 10, buffer);

  kind = get_kind (&is_iso_c);
  if (kind == -2)
    kind = gfc_default_integer_kind;
  if (kind == -1)
    return MATCH_ERROR;

  if (kind == 4 && flag_integer4_kind == 8)
    kind = 8;

  if (gfc_validate_kind (BT_INTEGER, kind, true) < 0)
    {
      gfc_error ("Integer kind %d at %C not available", kind);
      return MATCH_ERROR;
    }

  e = convert_integer (buffer, kind, 10, &gfc_current_locus);
  e->ts.is_c_interop = is_iso_c;

  if (gfc_range_check (e) != ARITH_OK)
    {
      gfc_error ("Integer too big for its kind at %C. This check can be "
		 "disabled with the option %<-fno-range-check%>");

      gfc_free_expr (e);
      return MATCH_ERROR;
    }

  *result = e;
  return MATCH_YES;
}


/* Match a Hollerith constant.  */

static match
match_hollerith_constant (gfc_expr **result)
{
  locus old_loc;
  gfc_expr *e = NULL;
  int num, pad;
  int i;

  old_loc = gfc_current_locus;
  gfc_gobble_whitespace ();

  if (match_integer_constant (&e, 0) == MATCH_YES
      && gfc_match_char ('h') == MATCH_YES)
    {
      if (!gfc_notify_std (GFC_STD_LEGACY, "Hollerith constant at %C"))
	goto cleanup;

      if (gfc_extract_int (e, &num, 1))
	goto cleanup;
      if (num == 0)
	{
	  gfc_error ("Invalid Hollerith constant: %L must contain at least "
		     "one character", &old_loc);
	  goto cleanup;
	}
      if (e->ts.kind != gfc_default_integer_kind)
	{
	  gfc_error ("Invalid Hollerith constant: Integer kind at %L "
		     "should be default", &old_loc);
	  goto cleanup;
	}
      else
	{
	  gfc_free_expr (e);
	  e = gfc_get_constant_expr (BT_HOLLERITH, gfc_default_character_kind,
				     &gfc_current_locus);

	  /* Calculate padding needed to fit default integer memory.  */
	  pad = gfc_default_integer_kind - (num % gfc_default_integer_kind);

	  e->representation.string = XCNEWVEC (char, num + pad + 1);

	  for (i = 0; i < num; i++)
	    {
	      gfc_char_t c = gfc_next_char_literal (INSTRING_WARN);
	      if (! gfc_wide_fits_in_byte (c))
		{
		  gfc_error ("Invalid Hollerith constant at %L contains a "
			     "wide character", &old_loc);
		  goto cleanup;
		}

	      e->representation.string[i] = (unsigned char) c;
	    }

	  /* Now pad with blanks and end with a null char.  */
	  for (i = 0; i < pad; i++)
	    e->representation.string[num + i] = ' ';

	  e->representation.string[num + i] = '\0';
	  e->representation.length = num + pad;
	  e->ts.u.pad = pad;

	  *result = e;
	  return MATCH_YES;
	}
    }

  gfc_free_expr (e);
  gfc_current_locus = old_loc;
  return MATCH_NO;

cleanup:
  gfc_free_expr (e);
  return MATCH_ERROR;
}


/* Match a binary, octal or hexadecimal constant that can be found in
   a DATA statement.  The standard permits b'010...', o'73...', and
   z'a1...' where b, o, and z can be capital letters.  This function
   also accepts postfixed forms of the constants: '01...'b, '73...'o,
   and 'a1...'z.  An additional extension is the use of x for z.  */

static match
match_boz_constant (gfc_expr **result)
{
  int radix, length, x_hex;
  locus old_loc, start_loc;
  char *buffer, post, delim;
  gfc_expr *e;

  start_loc = old_loc = gfc_current_locus;
  gfc_gobble_whitespace ();

  x_hex = 0;
  switch (post = gfc_next_ascii_char ())
    {
    case 'b':
      radix = 2;
      post = 0;
      break;
    case 'o':
      radix = 8;
      post = 0;
      break;
    case 'x':
      x_hex = 1;
      /* Fall through.  */
    case 'z':
      radix = 16;
      post = 0;
      break;
    case '\'':
      /* Fall through.  */
    case '\"':
      delim = post;
      post = 1;
      radix = 16;  /* Set to accept any valid digit string.  */
      break;
    default:
      goto backup;
    }

  /* No whitespace allowed here.  */

  if (post == 0)
    delim = gfc_next_ascii_char ();

  if (delim != '\'' && delim != '\"')
    goto backup;

  if (x_hex
      && gfc_invalid_boz (G_("Hexadecimal constant at %L uses "
			  "nonstandard X instead of Z"), &gfc_current_locus))
    return MATCH_ERROR;

  old_loc = gfc_current_locus;

  length = match_digits (0, radix, NULL);
  if (length == -1)
    {
      gfc_error ("Empty set of digits in BOZ constant at %C");
      return MATCH_ERROR;
    }

  if (gfc_next_ascii_char () != delim)
    {
      gfc_error ("Illegal character in BOZ constant at %C");
      return MATCH_ERROR;
    }

  if (post == 1)
    {
      switch (gfc_next_ascii_char ())
	{
	case 'b':
	  radix = 2;
	  break;
	case 'o':
	  radix = 8;
	  break;
	case 'x':
	  /* Fall through.  */
	case 'z':
	  radix = 16;
	  break;
	default:
	  goto backup;
	}

      if (gfc_invalid_boz (G_("BOZ constant at %C uses nonstandard postfix "
			   "syntax"), &gfc_current_locus))
	return MATCH_ERROR;
    }

  gfc_current_locus = old_loc;

  buffer = (char *) alloca (length + 1);
  memset (buffer, '\0', length + 1);

  match_digits (0, radix, buffer);
  gfc_next_ascii_char ();    /* Eat delimiter.  */
  if (post == 1)
    gfc_next_ascii_char ();  /* Eat postfixed b, o, z, or x.  */

  e = gfc_get_expr ();
  e->expr_type = EXPR_CONSTANT;
  e->ts.type = BT_BOZ;
  e->where = gfc_current_locus;
  e->boz.rdx = radix;
  e->boz.len = length;
  e->boz.str = XCNEWVEC (char, length + 1);
  strncpy (e->boz.str, buffer, length);

  if (!gfc_in_match_data ()
      && (!gfc_notify_std(GFC_STD_F2003, "BOZ used outside a DATA "
			  "statement at %L", &e->where)))
    return MATCH_ERROR;

  *result = e;
  return MATCH_YES;

backup:
  gfc_current_locus = start_loc;
  return MATCH_NO;
}


/* Match a real constant of some sort.  Allow a signed constant if signflag
   is nonzero.  */

static match
match_real_constant (gfc_expr **result, int signflag)
{
  int kind, count, seen_dp, seen_digits, is_iso_c, default_exponent;
  locus old_loc, temp_loc;
  char *p, *buffer, c, exp_char;
  gfc_expr *e;
  bool negate;

  old_loc = gfc_current_locus;
  gfc_gobble_whitespace ();

  e = NULL;

  default_exponent = 0;
  count = 0;
  seen_dp = 0;
  seen_digits = 0;
  exp_char = ' ';
  negate = FALSE;

  c = gfc_next_ascii_char ();
  if (signflag && (c == '+' || c == '-'))
    {
      if (c == '-')
	negate = TRUE;

      gfc_gobble_whitespace ();
      c = gfc_next_ascii_char ();
    }

  /* Scan significand.  */
  for (;; c = gfc_next_ascii_char (), count++)
    {
      if (c == '.')
	{
	  if (seen_dp)
	    goto done;

	  /* Check to see if "." goes with a following operator like
	     ".eq.".  */
	  temp_loc = gfc_current_locus;
	  c = gfc_next_ascii_char ();

	  if (c == 'e' || c == 'd' || c == 'q')
	    {
	      c = gfc_next_ascii_char ();
	      if (c == '.')
		goto done;	/* Operator named .e. or .d.  */
	    }

	  if (ISALPHA (c))
	    goto done;		/* Distinguish 1.e9 from 1.eq.2 */

	  gfc_current_locus = temp_loc;
	  seen_dp = 1;
	  continue;
	}

      if (ISDIGIT (c))
	{
	  seen_digits = 1;
	  continue;
	}

      break;
    }

  if (!seen_digits || (c != 'e' && c != 'd' && c != 'q'))
    goto done;
  exp_char = c;


  if (c == 'q')
    {
      if (!gfc_notify_std (GFC_STD_GNU, "exponent-letter 'q' in "
			   "real-literal-constant at %C"))
	return MATCH_ERROR;
      else if (warn_real_q_constant)
	gfc_warning (OPT_Wreal_q_constant,
		     "Extension: exponent-letter %<q%> in real-literal-constant "
		     "at %C");
    }

  /* Scan exponent.  */
  c = gfc_next_ascii_char ();
  count++;

  if (c == '+' || c == '-')
    {				/* optional sign */
      c = gfc_next_ascii_char ();
      count++;
    }

  if (!ISDIGIT (c))
    {
      /* With -fdec, default exponent to 0 instead of complaining.  */
      if (flag_dec)
	default_exponent = 1;
      else
	{
	  gfc_error ("Missing exponent in real number at %C");
	  return MATCH_ERROR;
	}
    }

  while (ISDIGIT (c))
    {
      c = gfc_next_ascii_char ();
      count++;
    }

done:
  /* Check that we have a numeric constant.  */
  if (!seen_digits || (!seen_dp && exp_char == ' '))
    {
      gfc_current_locus = old_loc;
      return MATCH_NO;
    }

  /* Convert the number.  */
  gfc_current_locus = old_loc;
  gfc_gobble_whitespace ();

  buffer = (char *) alloca (count + default_exponent + 1);
  memset (buffer, '\0', count + default_exponent + 1);

  p = buffer;
  c = gfc_next_ascii_char ();
  if (c == '+' || c == '-')
    {
      gfc_gobble_whitespace ();
      c = gfc_next_ascii_char ();
    }

  /* Hack for mpfr_set_str().  */
  for (;;)
    {
      if (c == 'd' || c == 'q')
	*p = 'e';
      else
	*p = c;
      p++;
      if (--count == 0)
	break;

      c = gfc_next_ascii_char ();
    }
  if (default_exponent)
    *p++ = '0';

  kind = get_kind (&is_iso_c);
  if (kind == -1)
    goto cleanup;

  if (kind == 4)
    {
      if (flag_real4_kind == 8)
	kind = 8;
      if (flag_real4_kind == 10)
	kind = 10;
      if (flag_real4_kind == 16)
	kind = 16;
    }
  else if (kind == 8)
    {
      if (flag_real8_kind == 4)
	kind = 4;
      if (flag_real8_kind == 10)
	kind = 10;
      if (flag_real8_kind == 16)
	kind = 16;
    }

  switch (exp_char)
    {
    case 'd':
      if (kind != -2)
	{
	  gfc_error ("Real number at %C has a %<d%> exponent and an explicit "
		     "kind");
	  goto cleanup;
	}
      kind = gfc_default_double_kind;
      break;

    case 'q':
      if (kind != -2)
	{
	  gfc_error ("Real number at %C has a %<q%> exponent and an explicit "
		     "kind");
	  goto cleanup;
	}

      /* The maximum possible real kind type parameter is 16.  First, try
	 that for the kind, then fallback to trying kind=10 (Intel 80 bit)
	 extended precision.  If neither value works, just given up.  */
      kind = 16;
      if (gfc_validate_kind (BT_REAL, kind, true) < 0)
	{
	  kind = 10;
          if (gfc_validate_kind (BT_REAL, kind, true) < 0)
	    {
	      gfc_error ("Invalid exponent-letter %<q%> in "
			 "real-literal-constant at %C");
	      goto cleanup;
	    }
	}
      break;

    default:
      if (kind == -2)
	kind = gfc_default_real_kind;

      if (gfc_validate_kind (BT_REAL, kind, true) < 0)
	{
	  gfc_error ("Invalid real kind %d at %C", kind);
	  goto cleanup;
	}
    }

  e = convert_real (buffer, kind, &gfc_current_locus);
  if (negate)
    mpfr_neg (e->value.real, e->value.real, GFC_RND_MODE);
  e->ts.is_c_interop = is_iso_c;

  switch (gfc_range_check (e))
    {
    case ARITH_OK:
      break;
    case ARITH_OVERFLOW:
      gfc_error ("Real constant overflows its kind at %C");
      goto cleanup;

    case ARITH_UNDERFLOW:
      if (warn_underflow)
	gfc_warning (OPT_Wunderflow, "Real constant underflows its kind at %C");
      mpfr_set_ui (e->value.real, 0, GFC_RND_MODE);
      break;

    default:
      gfc_internal_error ("gfc_range_check() returned bad value");
    }

  /* Warn about trailing digits which suggest the user added too many
     trailing digits, which may cause the appearance of higher pecision
     than the kind kan support.

     This is done by replacing the rightmost non-zero digit with zero
     and comparing with the original value.  If these are equal, we
     assume the user supplied more digits than intended (or forgot to
     convert to the correct kind).
  */

  if (warn_conversion_extra)
    {
      mpfr_t r;
      char *c1;
      bool did_break;

      c1 = strchr (buffer, 'e');
      if (c1 == NULL)
	c1 = buffer + strlen(buffer);

      did_break = false;
      for (p = c1; p > buffer;)
	{
	  p--;
	  if (*p == '.')
	    continue;

	  if (*p != '0')
	    {
	      *p = '0';
	      did_break = true;
	      break;
	    }
	}

      if (did_break)
	{
	  mpfr_init (r);
	  mpfr_set_str (r, buffer, 10, GFC_RND_MODE);
	  if (negate)
	    mpfr_neg (r, r, GFC_RND_MODE);

	  mpfr_sub (r, r, e->value.real, GFC_RND_MODE);

	  if (mpfr_cmp_ui (r, 0) == 0)
	    gfc_warning (OPT_Wconversion_extra, "Non-significant digits "
			 "in %qs number at %C, maybe incorrect KIND",
			 gfc_typename (&e->ts));

	  mpfr_clear (r);
	}
    }

  *result = e;
  return MATCH_YES;

cleanup:
  gfc_free_expr (e);
  return MATCH_ERROR;
}


/* Match a substring reference.  */

static match
match_substring (gfc_charlen *cl, int init, gfc_ref **result, bool deferred)
{
  gfc_expr *start, *end;
  locus old_loc;
  gfc_ref *ref;
  match m;

  start = NULL;
  end = NULL;

  old_loc = gfc_current_locus;

  m = gfc_match_char ('(');
  if (m != MATCH_YES)
    return MATCH_NO;

  if (gfc_match_char (':') != MATCH_YES)
    {
      if (init)
	m = gfc_match_init_expr (&start);
      else
	m = gfc_match_expr (&start);

      if (m != MATCH_YES)
	{
	  m = MATCH_NO;
	  goto cleanup;
	}

      m = gfc_match_char (':');
      if (m != MATCH_YES)
	goto cleanup;
    }

  if (gfc_match_char (')') != MATCH_YES)
    {
      if (init)
	m = gfc_match_init_expr (&end);
      else
	m = gfc_match_expr (&end);

      if (m == MATCH_NO)
	goto syntax;
      if (m == MATCH_ERROR)
	goto cleanup;

      m = gfc_match_char (')');
      if (m == MATCH_NO)
	goto syntax;
    }

  /* Optimize away the (:) reference.  */
  if (start == NULL && end == NULL && !deferred)
    ref = NULL;
  else
    {
      ref = gfc_get_ref ();

      ref->type = REF_SUBSTRING;
      if (start == NULL)
	start = gfc_get_int_expr (gfc_charlen_int_kind, NULL, 1);
      ref->u.ss.start = start;
      if (end == NULL && cl)
	end = gfc_copy_expr (cl->length);
      ref->u.ss.end = end;
      ref->u.ss.length = cl;
    }

  *result = ref;
  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in SUBSTRING specification at %C");
  m = MATCH_ERROR;

cleanup:
  gfc_free_expr (start);
  gfc_free_expr (end);

  gfc_current_locus = old_loc;
  return m;
}


/* Reads the next character of a string constant, taking care to
   return doubled delimiters on the input as a single instance of
   the delimiter.

   Special return values for "ret" argument are:
     -1   End of the string, as determined by the delimiter
     -2   Unterminated string detected

   Backslash codes are also expanded at this time.  */

static gfc_char_t
next_string_char (gfc_char_t delimiter, int *ret)
{
  locus old_locus;
  gfc_char_t c;

  c = gfc_next_char_literal (INSTRING_WARN);
  *ret = 0;

  if (c == '\n')
    {
      *ret = -2;
      return 0;
    }

  if (flag_backslash && c == '\\')
    {
      old_locus = gfc_current_locus;

      if (gfc_match_special_char (&c) == MATCH_NO)
	gfc_current_locus = old_locus;

      if (!(gfc_option.allow_std & GFC_STD_GNU) && !inhibit_warnings)
	gfc_warning (0, "Extension: backslash character at %C");
    }

  if (c != delimiter)
    return c;

  old_locus = gfc_current_locus;
  c = gfc_next_char_literal (NONSTRING);

  if (c == delimiter)
    return c;
  gfc_current_locus = old_locus;

  *ret = -1;
  return 0;
}


/* Special case of gfc_match_name() that matches a parameter kind name
   before a string constant.  This takes case of the weird but legal
   case of:

     kind_____'string'

   where kind____ is a parameter. gfc_match_name() will happily slurp
   up all the underscores, which leads to problems.  If we return
   MATCH_YES, the parse pointer points to the final underscore, which
   is not part of the name.  We never return MATCH_ERROR-- errors in
   the name will be detected later.  */

static match
match_charkind_name (char *name)
{
  locus old_loc;
  char c, peek;
  int len;

  gfc_gobble_whitespace ();
  c = gfc_next_ascii_char ();
  if (!ISALPHA (c))
    return MATCH_NO;

  *name++ = c;
  len = 1;

  for (;;)
    {
      old_loc = gfc_current_locus;
      c = gfc_next_ascii_char ();

      if (c == '_')
	{
	  peek = gfc_peek_ascii_char ();

	  if (peek == '\'' || peek == '\"')
	    {
	      gfc_current_locus = old_loc;
	      *name = '\0';
	      return MATCH_YES;
	    }
	}

      if (!ISALNUM (c)
	  && c != '_'
	  && (c != '$' || !flag_dollar_ok))
	break;

      *name++ = c;
      if (++len > GFC_MAX_SYMBOL_LEN)
	break;
    }

  return MATCH_NO;
}


/* See if the current input matches a character constant.  Lots of
   contortions have to be done to match the kind parameter which comes
   before the actual string.  The main consideration is that we don't
   want to error out too quickly.  For example, we don't actually do
   any validation of the kinds until we have actually seen a legal
   delimiter.  Using match_kind_param() generates errors too quickly.  */

static match
match_string_constant (gfc_expr **result)
{
  char name[GFC_MAX_SYMBOL_LEN + 1], peek;
  size_t length;
  int kind,save_warn_ampersand, ret;
  locus old_locus, start_locus;
  gfc_symbol *sym;
  gfc_expr *e;
  match m;
  gfc_char_t c, delimiter, *p;

  old_locus = gfc_current_locus;

  gfc_gobble_whitespace ();

  c = gfc_next_char ();
  if (c == '\'' || c == '"')
    {
      kind = gfc_default_character_kind;
      start_locus = gfc_current_locus;
      goto got_delim;
    }

  if (gfc_wide_is_digit (c))
    {
      kind = 0;

      while (gfc_wide_is_digit (c))
	{
	  kind = kind * 10 + c - '0';
	  if (kind > 9999999)
	    goto no_match;
	  c = gfc_next_char ();
	}

    }
  else
    {
      gfc_current_locus = old_locus;

      m = match_charkind_name (name);
      if (m != MATCH_YES)
	goto no_match;

      if (gfc_find_symbol (name, NULL, 1, &sym)
	  || sym == NULL
	  || sym->attr.flavor != FL_PARAMETER)
	goto no_match;

      kind = -1;
      c = gfc_next_char ();
    }

  if (c != '_')
    goto no_match;

  c = gfc_next_char ();
  if (c != '\'' && c != '"')
    goto no_match;

  start_locus = gfc_current_locus;

  if (kind == -1)
    {
      if (gfc_extract_int (sym->value, &kind, 1))
	return MATCH_ERROR;
      gfc_set_sym_referenced (sym);
    }

  if (gfc_validate_kind (BT_CHARACTER, kind, true) < 0)
    {
      gfc_error ("Invalid kind %d for CHARACTER constant at %C", kind);
      return MATCH_ERROR;
    }

got_delim:
  /* Scan the string into a block of memory by first figuring out how
     long it is, allocating the structure, then re-reading it.  This
     isn't particularly efficient, but string constants aren't that
     common in most code.  TODO: Use obstacks?  */

  delimiter = c;
  length = 0;

  for (;;)
    {
      c = next_string_char (delimiter, &ret);
      if (ret == -1)
	break;
      if (ret == -2)
	{
	  gfc_current_locus = start_locus;
	  gfc_error ("Unterminated character constant beginning at %C");
	  return MATCH_ERROR;
	}

      length++;
    }

  /* Peek at the next character to see if it is a b, o, z, or x for the
     postfixed BOZ literal constants.  */
  peek = gfc_peek_ascii_char ();
  if (peek == 'b' || peek == 'o' || peek =='z' || peek == 'x')
    goto no_match;

  e = gfc_get_character_expr (kind, &start_locus, NULL, length);

  gfc_current_locus = start_locus;

  /* We disable the warning for the following loop as the warning has already
     been printed in the loop above.  */
  save_warn_ampersand = warn_ampersand;
  warn_ampersand = false;

  p = e->value.character.string;
  for (size_t i = 0; i < length; i++)
    {
      c = next_string_char (delimiter, &ret);

      if (!gfc_check_character_range (c, kind))
	{
	  gfc_free_expr (e);
	  gfc_error ("Character %qs in string at %C is not representable "
		     "in character kind %d", gfc_print_wide_char (c), kind);
	  return MATCH_ERROR;
	}

      *p++ = c;
    }

  *p = '\0';	/* TODO: C-style string is for development/debug purposes.  */
  warn_ampersand = save_warn_ampersand;

  next_string_char (delimiter, &ret);
  if (ret != -1)
    gfc_internal_error ("match_string_constant(): Delimiter not found");

  if (match_substring (NULL, 0, &e->ref, false) != MATCH_NO)
    e->expr_type = EXPR_SUBSTRING;

  /* Substrings with constant starting and ending points are eligible as
     designators (F2018, section 9.1).  Simplify substrings to make them usable
     e.g. in data statements.  */
  if (e->expr_type == EXPR_SUBSTRING
      && e->ref && e->ref->type == REF_SUBSTRING
      && e->ref->u.ss.start->expr_type == EXPR_CONSTANT
      && (e->ref->u.ss.end == NULL
	  || e->ref->u.ss.end->expr_type == EXPR_CONSTANT))
    {
      gfc_expr *res;
      ptrdiff_t istart, iend;
      size_t length;
      bool equal_length = false;

      /* Basic checks on substring starting and ending indices.  */
      if (!gfc_resolve_substring (e->ref, &equal_length))
	return MATCH_ERROR;

      length = e->value.character.length;
      istart = gfc_mpz_get_hwi (e->ref->u.ss.start->value.integer);
      if (e->ref->u.ss.end == NULL)
	iend = length;
      else
	iend = gfc_mpz_get_hwi (e->ref->u.ss.end->value.integer);

      if (istart <= iend)
	{
	  if (istart < 1)
	    {
	      gfc_error ("Substring start index (%ld) at %L below 1",
			 (long) istart, &e->ref->u.ss.start->where);
	      return MATCH_ERROR;
	    }
	  if (iend > (ssize_t) length)
	    {
	      gfc_error ("Substring end index (%ld) at %L exceeds string "
			 "length", (long) iend, &e->ref->u.ss.end->where);
	      return MATCH_ERROR;
	    }
	  length = iend - istart + 1;
	}
      else
	length = 0;

      res = gfc_get_constant_expr (BT_CHARACTER, e->ts.kind, &e->where);
      res->value.character.string = gfc_get_wide_string (length + 1);
      res->value.character.length = length;
      if (length > 0)
	memcpy (res->value.character.string,
		&e->value.character.string[istart - 1],
		length * sizeof (gfc_char_t));
      res->value.character.string[length] = '\0';
      e = res;
    }

  *result = e;

  return MATCH_YES;

no_match:
  gfc_current_locus = old_locus;
  return MATCH_NO;
}


/* Match a .true. or .false.  Returns 1 if a .true. was found,
   0 if a .false. was found, and -1 otherwise.  */
static int
match_logical_constant_string (void)
{
  locus orig_loc = gfc_current_locus;

  gfc_gobble_whitespace ();
  if (gfc_next_ascii_char () == '.')
    {
      char ch = gfc_next_ascii_char ();
      if (ch == 'f')
	{
	  if (gfc_next_ascii_char () == 'a'
	      && gfc_next_ascii_char () == 'l'
	      && gfc_next_ascii_char () == 's'
	      && gfc_next_ascii_char () == 'e'
	      && gfc_next_ascii_char () == '.')
	    /* Matched ".false.".  */
	    return 0;
	}
      else if (ch == 't')
	{
	  if (gfc_next_ascii_char () == 'r'
	      && gfc_next_ascii_char () == 'u'
	      && gfc_next_ascii_char () == 'e'
	      && gfc_next_ascii_char () == '.')
	    /* Matched ".true.".  */
	    return 1;
	}
    }
  gfc_current_locus = orig_loc;
  return -1;
}

/* Match a .true. or .false.  */

static match
match_logical_constant (gfc_expr **result)
{
  gfc_expr *e;
  int i, kind, is_iso_c;

  i = match_logical_constant_string ();
  if (i == -1)
    return MATCH_NO;

  kind = get_kind (&is_iso_c);
  if (kind == -1)
    return MATCH_ERROR;
  if (kind == -2)
    kind = gfc_default_logical_kind;

  if (gfc_validate_kind (BT_LOGICAL, kind, true) < 0)
    {
      gfc_error ("Bad kind for logical constant at %C");
      return MATCH_ERROR;
    }

  e = gfc_get_logical_expr (kind, &gfc_current_locus, i);
  e->ts.is_c_interop = is_iso_c;

  *result = e;
  return MATCH_YES;
}


/* Match a real or imaginary part of a complex constant that is a
   symbolic constant.  */

static match
match_sym_complex_part (gfc_expr **result)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym;
  gfc_expr *e;
  match m;

  m = gfc_match_name (name);
  if (m != MATCH_YES)
    return m;

  if (gfc_find_symbol (name, NULL, 1, &sym) || sym == NULL)
    return MATCH_NO;

  if (sym->attr.flavor != FL_PARAMETER)
    {
      /* Give the matcher for implied do-loops a chance to run.  This yields
	 a much saner error message for "write(*,*) (i, i=1, 6" where the
	 right parenthesis is missing.  */
      char c;
      gfc_gobble_whitespace ();
      c = gfc_peek_ascii_char ();
      if (c == '=' || c == ',')
	{
	  m = MATCH_NO;
	}
      else
	{
	  gfc_error ("Expected PARAMETER symbol in complex constant at %C");
	  m = MATCH_ERROR;
	}
      return m;
    }

  if (!sym->value)
    goto error;

  if (!gfc_numeric_ts (&sym->value->ts))
    {
      gfc_error ("Numeric PARAMETER required in complex constant at %C");
      return MATCH_ERROR;
    }

  if (sym->value->rank != 0)
    {
      gfc_error ("Scalar PARAMETER required in complex constant at %C");
      return MATCH_ERROR;
    }

  if (!gfc_notify_std (GFC_STD_F2003, "PARAMETER symbol in "
		       "complex constant at %C"))
    return MATCH_ERROR;

  switch (sym->value->ts.type)
    {
    case BT_REAL:
      e = gfc_copy_expr (sym->value);
      break;

    case BT_COMPLEX:
      e = gfc_complex2real (sym->value, sym->value->ts.kind);
      if (e == NULL)
	goto error;
      break;

    case BT_INTEGER:
      e = gfc_int2real (sym->value, gfc_default_real_kind);
      if (e == NULL)
	goto error;
      break;

    default:
      gfc_internal_error ("gfc_match_sym_complex_part(): Bad type");
    }

  *result = e;		/* e is a scalar, real, constant expression.  */
  return MATCH_YES;

error:
  gfc_error ("Error converting PARAMETER constant in complex constant at %C");
  return MATCH_ERROR;
}


/* Match a real or imaginary part of a complex number.  */

static match
match_complex_part (gfc_expr **result)
{
  match m;

  m = match_sym_complex_part (result);
  if (m != MATCH_NO)
    return m;

  m = match_real_constant (result, 1);
  if (m != MATCH_NO)
    return m;

  return match_integer_constant (result, 1);
}


/* Try to match a complex constant.  */

static match
match_complex_constant (gfc_expr **result)
{
  gfc_expr *e, *real, *imag;
  gfc_error_buffer old_error;
  gfc_typespec target;
  locus old_loc;
  int kind;
  match m;

  old_loc = gfc_current_locus;
  real = imag = e = NULL;

  m = gfc_match_char ('(');
  if (m != MATCH_YES)
    return m;

  gfc_push_error (&old_error);

  m = match_complex_part (&real);
  if (m == MATCH_NO)
    {
      gfc_free_error (&old_error);
      goto cleanup;
    }

  if (gfc_match_char (',') == MATCH_NO)
    {
      /* It is possible that gfc_int2real issued a warning when
	 converting an integer to real.  Throw this away here.  */

      gfc_clear_warning ();
      gfc_pop_error (&old_error);
      m = MATCH_NO;
      goto cleanup;
    }

  /* If m is error, then something was wrong with the real part and we
     assume we have a complex constant because we've seen the ','.  An
     ambiguous case here is the start of an iterator list of some
     sort. These sort of lists are matched prior to coming here.  */

  if (m == MATCH_ERROR)
    {
      gfc_free_error (&old_error);
      goto cleanup;
    }
  gfc_pop_error (&old_error);

  m = match_complex_part (&imag);
  if (m == MATCH_NO)
    goto syntax;
  if (m == MATCH_ERROR)
    goto cleanup;

  m = gfc_match_char (')');
  if (m == MATCH_NO)
    {
      /* Give the matcher for implied do-loops a chance to run.  This
	 yields a much saner error message for (/ (i, 4=i, 6) /).  */
      if (gfc_peek_ascii_char () == '=')
	{
	  m = MATCH_ERROR;
	  goto cleanup;
	}
      else
    goto syntax;
    }

  if (m == MATCH_ERROR)
    goto cleanup;

  /* Decide on the kind of this complex number.  */
  if (real->ts.type == BT_REAL)
    {
      if (imag->ts.type == BT_REAL)
	kind = gfc_kind_max (real, imag);
      else
	kind = real->ts.kind;
    }
  else
    {
      if (imag->ts.type == BT_REAL)
	kind = imag->ts.kind;
      else
	kind = gfc_default_real_kind;
    }
  gfc_clear_ts (&target);
  target.type = BT_REAL;
  target.kind = kind;

  if (real->ts.type != BT_REAL || kind != real->ts.kind)
    gfc_convert_type (real, &target, 2);
  if (imag->ts.type != BT_REAL || kind != imag->ts.kind)
    gfc_convert_type (imag, &target, 2);

  e = convert_complex (real, imag, kind);
  e->where = gfc_current_locus;

  gfc_free_expr (real);
  gfc_free_expr (imag);

  *result = e;
  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in COMPLEX constant at %C");
  m = MATCH_ERROR;

cleanup:
  gfc_free_expr (e);
  gfc_free_expr (real);
  gfc_free_expr (imag);
  gfc_current_locus = old_loc;

  return m;
}


/* Match constants in any of several forms.  Returns nonzero for a
   match, zero for no match.  */

match
gfc_match_literal_constant (gfc_expr **result, int signflag)
{
  match m;

  m = match_complex_constant (result);
  if (m != MATCH_NO)
    return m;

  m = match_string_constant (result);
  if (m != MATCH_NO)
    return m;

  m = match_boz_constant (result);
  if (m != MATCH_NO)
    return m;

  m = match_real_constant (result, signflag);
  if (m != MATCH_NO)
    return m;

  m = match_hollerith_constant (result);
  if (m != MATCH_NO)
    return m;

  m = match_integer_constant (result, signflag);
  if (m != MATCH_NO)
    return m;

  m = match_logical_constant (result);
  if (m != MATCH_NO)
    return m;

  return MATCH_NO;
}


/* This checks if a symbol is the return value of an encompassing function.
   Function nesting can be maximally two levels deep, but we may have
   additional local namespaces like BLOCK etc.  */

bool
gfc_is_function_return_value (gfc_symbol *sym, gfc_namespace *ns)
{
  if (!sym->attr.function || (sym->result != sym))
    return false;
  while (ns)
    {
      if (ns->proc_name == sym)
	return true;
      ns = ns->parent;
    }
  return false;
}


/* Match a single actual argument value.  An actual argument is
   usually an expression, but can also be a procedure name.  If the
   argument is a single name, it is not always possible to tell
   whether the name is a dummy procedure or not.  We treat these cases
   by creating an argument that looks like a dummy procedure and
   fixing things later during resolution.  */

static match
match_actual_arg (gfc_expr **result)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symtree *symtree;
  locus where, w;
  gfc_expr *e;
  char c;

  gfc_gobble_whitespace ();
  where = gfc_current_locus;

  switch (gfc_match_name (name))
    {
    case MATCH_ERROR:
      return MATCH_ERROR;

    case MATCH_NO:
      break;

    case MATCH_YES:
      w = gfc_current_locus;
      gfc_gobble_whitespace ();
      c = gfc_next_ascii_char ();
      gfc_current_locus = w;

      if (c != ',' && c != ')')
	break;

      if (gfc_find_sym_tree (name, NULL, 1, &symtree))
	break;
      /* Handle error elsewhere.  */

      /* Eliminate a couple of common cases where we know we don't
	 have a function argument.  */
      if (symtree == NULL)
	{
	  gfc_get_sym_tree (name, NULL, &symtree, false);
	  gfc_set_sym_referenced (symtree->n.sym);
	}
      else
	{
	  gfc_symbol *sym;

	  sym = symtree->n.sym;
	  gfc_set_sym_referenced (sym);
	  if (sym->attr.flavor == FL_NAMELIST)
	    {
	      gfc_error ("Namelist %qs cannot be an argument at %L",
	      sym->name, &where);
	      break;
	    }
	  if (sym->attr.flavor != FL_PROCEDURE
	      && sym->attr.flavor != FL_UNKNOWN)
	    break;

	  if (sym->attr.in_common && !sym->attr.proc_pointer)
	    {
	      if (!gfc_add_flavor (&sym->attr, FL_VARIABLE,
				   sym->name, &sym->declared_at))
		return MATCH_ERROR;
	      break;
	    }

	  /* If the symbol is a function with itself as the result and
	     is being defined, then we have a variable.  */
	  if (sym->attr.function && sym->result == sym)
	    {
	      if (gfc_is_function_return_value (sym, gfc_current_ns))
		break;

	      if (sym->attr.entry
		  && (sym->ns == gfc_current_ns
		      || sym->ns == gfc_current_ns->parent))
		{
		  gfc_entry_list *el = NULL;

		  for (el = sym->ns->entries; el; el = el->next)
		    if (sym == el->sym)
		      break;

		  if (el)
		    break;
		}
	    }
	}

      e = gfc_get_expr ();	/* Leave it unknown for now */
      e->symtree = symtree;
      e->expr_type = EXPR_VARIABLE;
      e->ts.type = BT_PROCEDURE;
      e->where = where;

      *result = e;
      return MATCH_YES;
    }

  gfc_current_locus = where;
  return gfc_match_expr (result);
}


/* Match a keyword argument or type parameter spec list..  */

static match
match_keyword_arg (gfc_actual_arglist *actual, gfc_actual_arglist *base, bool pdt)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_actual_arglist *a;
  locus name_locus;
  match m;

  name_locus = gfc_current_locus;
  m = gfc_match_name (name);

  if (m != MATCH_YES)
    goto cleanup;
  if (gfc_match_char ('=') != MATCH_YES)
    {
      m = MATCH_NO;
      goto cleanup;
    }

  if (pdt)
    {
      if (gfc_match_char ('*') == MATCH_YES)
	{
	  actual->spec_type = SPEC_ASSUMED;
	  goto add_name;
	}
      else if (gfc_match_char (':') == MATCH_YES)
	{
	  actual->spec_type = SPEC_DEFERRED;
	  goto add_name;
	}
      else
	actual->spec_type = SPEC_EXPLICIT;
    }

  m = match_actual_arg (&actual->expr);
  if (m != MATCH_YES)
    goto cleanup;

  /* Make sure this name has not appeared yet.  */
add_name:
  if (name[0] != '\0')
    {
      for (a = base; a; a = a->next)
	if (a->name != NULL && strcmp (a->name, name) == 0)
	  {
	    gfc_error ("Keyword %qs at %C has already appeared in the "
		       "current argument list", name);
	    return MATCH_ERROR;
	  }
    }

  actual->name = gfc_get_string ("%s", name);
  return MATCH_YES;

cleanup:
  gfc_current_locus = name_locus;
  return m;
}


/* Match an argument list function, such as %VAL.  */

static match
match_arg_list_function (gfc_actual_arglist *result)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  locus old_locus;
  match m;

  old_locus = gfc_current_locus;

  if (gfc_match_char ('%') != MATCH_YES)
    {
      m = MATCH_NO;
      goto cleanup;
    }

  m = gfc_match ("%n (", name);
  if (m != MATCH_YES)
    goto cleanup;

  if (name[0] != '\0')
    {
      switch (name[0])
	{
	case 'l':
	  if (startswith (name, "loc"))
	    {
	      result->name = "%LOC";
	      break;
	    }
	  /* FALLTHRU */
	case 'r':
	  if (startswith (name, "ref"))
	    {
	      result->name = "%REF";
	      break;
	    }
	  /* FALLTHRU */
	case 'v':
	  if (startswith (name, "val"))
	    {
	      result->name = "%VAL";
	      break;
	    }
	  /* FALLTHRU */
	default:
	  m = MATCH_ERROR;
	  goto cleanup;
	}
    }

  if (!gfc_notify_std (GFC_STD_GNU, "argument list function at %C"))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  m = match_actual_arg (&result->expr);
  if (m != MATCH_YES)
    goto cleanup;

  if (gfc_match_char (')') != MATCH_YES)
    {
      m = MATCH_NO;
      goto cleanup;
    }

  return MATCH_YES;

cleanup:
  gfc_current_locus = old_locus;
  return m;
}


/* Matches an actual argument list of a function or subroutine, from
   the opening parenthesis to the closing parenthesis.  The argument
   list is assumed to allow keyword arguments because we don't know if
   the symbol associated with the procedure has an implicit interface
   or not.  We make sure keywords are unique. If sub_flag is set,
   we're matching the argument list of a subroutine.

   NOTE: An alternative use for this function is to match type parameter
   spec lists, which are so similar to actual argument lists that the
   machinery can be reused. This use is flagged by the optional argument
   'pdt'.  */

match
gfc_match_actual_arglist (int sub_flag, gfc_actual_arglist **argp, bool pdt)
{
  gfc_actual_arglist *head, *tail;
  int seen_keyword;
  gfc_st_label *label;
  locus old_loc;
  match m;

  *argp = tail = NULL;
  old_loc = gfc_current_locus;

  seen_keyword = 0;

  if (gfc_match_char ('(') == MATCH_NO)
    return (sub_flag) ? MATCH_YES : MATCH_NO;

  if (gfc_match_char (')') == MATCH_YES)
    return MATCH_YES;

  head = NULL;

  matching_actual_arglist++;

  for (;;)
    {
      if (head == NULL)
	head = tail = gfc_get_actual_arglist ();
      else
	{
	  tail->next = gfc_get_actual_arglist ();
	  tail = tail->next;
	}

      if (sub_flag && !pdt && gfc_match_char ('*') == MATCH_YES)
	{
	  m = gfc_match_st_label (&label);
	  if (m == MATCH_NO)
	    gfc_error ("Expected alternate return label at %C");
	  if (m != MATCH_YES)
	    goto cleanup;

	  if (!gfc_notify_std (GFC_STD_F95_OBS, "Alternate-return argument "
			       "at %C"))
	    goto cleanup;

	  tail->label = label;
	  goto next;
	}

      if (pdt && !seen_keyword)
	{
	  if (gfc_match_char (':') == MATCH_YES)
	    {
	      tail->spec_type = SPEC_DEFERRED;
	      goto next;
	    }
	  else if (gfc_match_char ('*') == MATCH_YES)
	    {
	      tail->spec_type = SPEC_ASSUMED;
	      goto next;
	    }
	  else
	    tail->spec_type = SPEC_EXPLICIT;

	  m = match_keyword_arg (tail, head, pdt);
	  if (m == MATCH_YES)
	    {
	      seen_keyword = 1;
	      goto next;
	    }
	  if (m == MATCH_ERROR)
	    goto cleanup;
	}

      /* After the first keyword argument is seen, the following
	 arguments must also have keywords.  */
      if (seen_keyword)
	{
	  m = match_keyword_arg (tail, head, pdt);

	  if (m == MATCH_ERROR)
	    goto cleanup;
	  if (m == MATCH_NO)
	    {
	      gfc_error ("Missing keyword name in actual argument list at %C");
	      goto cleanup;
	    }

	}
      else
	{
	  /* Try an argument list function, like %VAL.  */
	  m = match_arg_list_function (tail);
	  if (m == MATCH_ERROR)
	    goto cleanup;

	  /* See if we have the first keyword argument.  */
	  if (m == MATCH_NO)
	    {
	      m = match_keyword_arg (tail, head, false);
	      if (m == MATCH_YES)
		seen_keyword = 1;
	      if (m == MATCH_ERROR)
		goto cleanup;
	    }

	  if (m == MATCH_NO)
	    {
	      /* Try for a non-keyword argument.  */
	      m = match_actual_arg (&tail->expr);
	      if (m == MATCH_ERROR)
		goto cleanup;
	      if (m == MATCH_NO)
		goto syntax;
	    }
	}


    next:
      if (gfc_match_char (')') == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  *argp = head;
  matching_actual_arglist--;
  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in argument list at %C");

cleanup:
  gfc_free_actual_arglist (head);
  gfc_current_locus = old_loc;
  matching_actual_arglist--;
  return MATCH_ERROR;
}


/* Used by gfc_match_varspec() to extend the reference list by one
   element.  */

static gfc_ref *
extend_ref (gfc_expr *primary, gfc_ref *tail)
{
  if (primary->ref == NULL)
    primary->ref = tail = gfc_get_ref ();
  else
    {
      if (tail == NULL)
	gfc_internal_error ("extend_ref(): Bad tail");
      tail->next = gfc_get_ref ();
      tail = tail->next;
    }

  return tail;
}


/* Used by gfc_match_varspec() to match an inquiry reference.  */

static bool
is_inquiry_ref (const char *name, gfc_ref **ref)
{
  inquiry_type type;

  if (name == NULL)
    return false;

  if (ref) *ref = NULL;

  if (strcmp (name, "re") == 0)
    type = INQUIRY_RE;
  else if (strcmp (name, "im") == 0)
    type = INQUIRY_IM;
  else if (strcmp (name, "kind") == 0)
    type = INQUIRY_KIND;
  else if (strcmp (name, "len") == 0)
    type = INQUIRY_LEN;
  else
    return false;

  if (ref)
    {
      *ref = gfc_get_ref ();
      (*ref)->type = REF_INQUIRY;
      (*ref)->u.i = type;
    }

  return true;
}


/* Match any additional specifications associated with the current
   variable like member references or substrings.  If equiv_flag is
   set we only match stuff that is allowed inside an EQUIVALENCE
   statement.  sub_flag tells whether we expect a type-bound procedure found
   to be a subroutine as part of CALL or a FUNCTION. For procedure pointer
   components, 'ppc_arg' determines whether the PPC may be called (with an
   argument list), or whether it may just be referred to as a pointer.  */

match
gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
		   bool ppc_arg)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_ref *substring, *tail, *tmp;
  gfc_component *component = NULL;
  gfc_component *previous = NULL;
  gfc_symbol *sym = primary->symtree->n.sym;
  gfc_expr *tgt_expr = NULL;
  match m;
  bool unknown;
  bool inquiry;
  bool intrinsic;
  locus old_loc;
  char sep;

  tail = NULL;

  gfc_gobble_whitespace ();

  if (gfc_peek_ascii_char () == '[')
    {
      if ((sym->ts.type != BT_CLASS && sym->attr.dimension)
	  || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
	      && CLASS_DATA (sym)->attr.dimension))
	{
	  gfc_error ("Array section designator, e.g. '(:)', is required "
		     "besides the coarray designator '[...]' at %C");
	  return MATCH_ERROR;
	}
      if ((sym->ts.type != BT_CLASS && !sym->attr.codimension)
	  || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
	      && !CLASS_DATA (sym)->attr.codimension))
	{
	  gfc_error ("Coarray designator at %C but %qs is not a coarray",
		     sym->name);
	  return MATCH_ERROR;
	}
    }

  if (sym->assoc && sym->assoc->target)
    tgt_expr = sym->assoc->target;

  /* For associate names, we may not yet know whether they are arrays or not.
     If the selector expression is unambiguously an array; eg. a full array
     or an array section, then the associate name must be an array and we can
     fix it now. Otherwise, if parentheses follow and it is not a character
     type, we have to assume that it actually is one for now.  The final
     decision will be made at resolution, of course.  */
  if (sym->assoc
      && gfc_peek_ascii_char () == '('
      && sym->ts.type != BT_CLASS
      && !sym->attr.dimension)
    {
      gfc_ref *ref = NULL;

      if (!sym->assoc->dangling && tgt_expr)
	{
	   if (tgt_expr->expr_type == EXPR_VARIABLE)
	     gfc_resolve_expr (tgt_expr);

	   ref = tgt_expr->ref;
	   for (; ref; ref = ref->next)
	      if (ref->type == REF_ARRAY
		  && (ref->u.ar.type == AR_FULL
		      || ref->u.ar.type == AR_SECTION))
		break;
	}

      if (ref || (!(sym->assoc->dangling || sym->ts.type == BT_CHARACTER)
		  && sym->assoc->st
		  && sym->assoc->st->n.sym
		  && sym->assoc->st->n.sym->attr.dimension == 0))
	{
	  sym->attr.dimension = 1;
	  if (sym->as == NULL
	      && sym->assoc->st
	      && sym->assoc->st->n.sym
	      && sym->assoc->st->n.sym->as)
	    sym->as = gfc_copy_array_spec (sym->assoc->st->n.sym->as);
	}
    }
  else if (sym->ts.type == BT_CLASS
	   && tgt_expr
	   && tgt_expr->expr_type == EXPR_VARIABLE
	   && sym->ts.u.derived != tgt_expr->ts.u.derived)
    {
      gfc_resolve_expr (tgt_expr);
      if (tgt_expr->rank)
	sym->ts.u.derived = tgt_expr->ts.u.derived;
    }

  if ((equiv_flag && gfc_peek_ascii_char () == '(')
      || gfc_peek_ascii_char () == '[' || sym->attr.codimension
      || (sym->attr.dimension && sym->ts.type != BT_CLASS
	  && !sym->attr.proc_pointer && !gfc_is_proc_ptr_comp (primary)
	  && !(gfc_matching_procptr_assignment
	       && sym->attr.flavor == FL_PROCEDURE))
      || (sym->ts.type == BT_CLASS && sym->attr.class_ok
	  && sym->ts.u.derived && CLASS_DATA (sym)
	  && (CLASS_DATA (sym)->attr.dimension
	      || CLASS_DATA (sym)->attr.codimension)))
    {
      gfc_array_spec *as;

      tail = extend_ref (primary, tail);
      tail->type = REF_ARRAY;

      /* In EQUIVALENCE, we don't know yet whether we are seeing
	 an array, character variable or array of character
	 variables.  We'll leave the decision till resolve time.  */

      if (equiv_flag)
	as = NULL;
      else if (sym->ts.type == BT_CLASS && CLASS_DATA (sym))
	as = CLASS_DATA (sym)->as;
      else
	as = sym->as;

      m = gfc_match_array_ref (&tail->u.ar, as, equiv_flag,
			       as ? as->corank : 0);
      if (m != MATCH_YES)
	return m;

      gfc_gobble_whitespace ();
      if (equiv_flag && gfc_peek_ascii_char () == '(')
	{
	  tail = extend_ref (primary, tail);
	  tail->type = REF_ARRAY;

	  m = gfc_match_array_ref (&tail->u.ar, NULL, equiv_flag, 0);
	  if (m != MATCH_YES)
	    return m;
	}
    }

  primary->ts = sym->ts;

  if (equiv_flag)
    return MATCH_YES;

  /* With DEC extensions, member separator may be '.' or '%'.  */
  sep = gfc_peek_ascii_char ();
  m = gfc_match_member_sep (sym);
  if (m == MATCH_ERROR)
    return MATCH_ERROR;

  inquiry = false;
  if (m == MATCH_YES && sep == '%'
      && primary->ts.type != BT_CLASS
      && primary->ts.type != BT_DERIVED)
    {
      match mm;
      old_loc = gfc_current_locus;
      mm = gfc_match_name (name);
      if (mm == MATCH_YES && is_inquiry_ref (name, &tmp))
	inquiry = true;
      gfc_current_locus = old_loc;
    }

  if (sym->ts.type == BT_UNKNOWN && m == MATCH_YES
      && gfc_get_default_type (sym->name, sym->ns)->type == BT_DERIVED)
    gfc_set_default_type (sym, 0, sym->ns);

  /* See if there is a usable typespec in the "no IMPLICIT type" error.  */
  if (sym->ts.type == BT_UNKNOWN && m == MATCH_YES)
    {
      bool permissible;

      /* These target expressions can be resolved at any time.  */
      permissible = tgt_expr && tgt_expr->symtree && tgt_expr->symtree->n.sym
		    && (tgt_expr->symtree->n.sym->attr.use_assoc
			|| tgt_expr->symtree->n.sym->attr.host_assoc
			|| tgt_expr->symtree->n.sym->attr.if_source
								== IFSRC_DECL);
      permissible = permissible
		    || (tgt_expr && tgt_expr->expr_type == EXPR_OP);

      if (permissible)
	{
	  gfc_resolve_expr (tgt_expr);
	  sym->ts = tgt_expr->ts;
	}

      if (sym->ts.type == BT_UNKNOWN)
	{
	  gfc_error ("Symbol %qs at %C has no IMPLICIT type", sym->name);
	  return MATCH_ERROR;
	}
    }
  else if ((sym->ts.type != BT_DERIVED && sym->ts.type != BT_CLASS)
           && m == MATCH_YES && !inquiry)
    {
      gfc_error ("Unexpected %<%c%> for nonderived-type variable %qs at %C",
		 sep, sym->name);
      return MATCH_ERROR;
    }

  if ((sym->ts.type != BT_DERIVED && sym->ts.type != BT_CLASS && !inquiry)
      || m != MATCH_YES)
    goto check_substring;

  if (!inquiry)
    sym = sym->ts.u.derived;
  else
    sym = NULL;

  for (;;)
    {
      bool t;
      gfc_symtree *tbp;

      m = gfc_match_name (name);
      if (m == MATCH_NO)
	gfc_error ("Expected structure component name at %C");
      if (m != MATCH_YES)
	return MATCH_ERROR;

      intrinsic = false;
      if (primary->ts.type != BT_CLASS && primary->ts.type != BT_DERIVED)
	{
	  inquiry = is_inquiry_ref (name, &tmp);
	  if (inquiry)
	    sym = NULL;

	  if (sep == '%')
	    {
	      if (tmp)
		{
		  switch (tmp->u.i)
		    {
		    case INQUIRY_RE:
		    case INQUIRY_IM:
		      if (!gfc_notify_std (GFC_STD_F2008,
					   "RE or IM part_ref at %C"))
			return MATCH_ERROR;
		      break;

		    case INQUIRY_KIND:
		      if (!gfc_notify_std (GFC_STD_F2003,
					   "KIND part_ref at %C"))
			return MATCH_ERROR;
		      break;

		    case INQUIRY_LEN:
		      if (!gfc_notify_std (GFC_STD_F2003, "LEN part_ref at %C"))
			return MATCH_ERROR;
		      break;
		    }

		  if ((tmp->u.i == INQUIRY_RE || tmp->u.i == INQUIRY_IM)
		      && primary->ts.type != BT_COMPLEX)
		    {
			gfc_error ("The RE or IM part_ref at %C must be "
				   "applied to a COMPLEX expression");
			return MATCH_ERROR;
		    }
		  else if (tmp->u.i == INQUIRY_LEN
			   && primary->ts.type != BT_CHARACTER)
		    {
			gfc_error ("The LEN part_ref at %C must be applied "
				   "to a CHARACTER expression");
			return MATCH_ERROR;
		    }
		}
	      if (primary->ts.type != BT_UNKNOWN)
		intrinsic = true;
	    }
	}
      else
	inquiry = false;

      if (sym && sym->f2k_derived)
	tbp = gfc_find_typebound_proc (sym, &t, name, false, &gfc_current_locus);
      else
	tbp = NULL;

      if (tbp)
	{
	  gfc_symbol* tbp_sym;

	  if (!t)
	    return MATCH_ERROR;

	  gcc_assert (!tail || !tail->next);

	  if (!(primary->expr_type == EXPR_VARIABLE
		|| (primary->expr_type == EXPR_STRUCTURE
		    && primary->symtree && primary->symtree->n.sym
		    && primary->symtree->n.sym->attr.flavor)))
	    return MATCH_ERROR;

	  if (tbp->n.tb->is_generic)
	    tbp_sym = NULL;
	  else
	    tbp_sym = tbp->n.tb->u.specific->n.sym;

	  primary->expr_type = EXPR_COMPCALL;
	  primary->value.compcall.tbp = tbp->n.tb;
	  primary->value.compcall.name = tbp->name;
	  primary->value.compcall.ignore_pass = 0;
	  primary->value.compcall.assign = 0;
	  primary->value.compcall.base_object = NULL;
	  gcc_assert (primary->symtree->n.sym->attr.referenced);
	  if (tbp_sym)
	    primary->ts = tbp_sym->ts;
	  else
	    gfc_clear_ts (&primary->ts);

	  m = gfc_match_actual_arglist (tbp->n.tb->subroutine,
					&primary->value.compcall.actual);
	  if (m == MATCH_ERROR)
	    return MATCH_ERROR;
	  if (m == MATCH_NO)
	    {
	      if (sub_flag)
		primary->value.compcall.actual = NULL;
	      else
		{
		  gfc_error ("Expected argument list at %C");
		  return MATCH_ERROR;
		}
	    }

	  break;
	}

      previous = component;

      if (!inquiry && !intrinsic)
	component = gfc_find_component (sym, name, false, false, &tmp);
      else
	component = NULL;

      if (intrinsic && !inquiry)
	{
	  if (previous)
	    gfc_error ("%qs at %C is not an inquiry reference to an intrinsic "
			"type component %qs", name, previous->name);
	  else
	    gfc_error ("%qs at %C is not an inquiry reference to an intrinsic "
			"type component", name);
	  return MATCH_ERROR;
	}
      else if (component == NULL && !inquiry)
	return MATCH_ERROR;

      /* Extend the reference chain determined by gfc_find_component or
	 is_inquiry_ref.  */
      if (primary->ref == NULL)
	primary->ref = tmp;
      else
	{
	  /* Set by the for loop below for the last component ref.  */
	  gcc_assert (tail != NULL);
	  tail->next = tmp;
	}

      /* The reference chain may be longer than one hop for union
	 subcomponents; find the new tail.  */
      for (tail = tmp; tail->next; tail = tail->next)
	;

      if (tmp && tmp->type == REF_INQUIRY)
	{
	  if (!primary->where.lb || !primary->where.nextc)
	    primary->where = gfc_current_locus;
	  gfc_simplify_expr (primary, 0);

	  if (primary->expr_type == EXPR_CONSTANT)
	    goto check_done;

	  switch (tmp->u.i)
	    {
	    case INQUIRY_RE:
	    case INQUIRY_IM:
	      if (!gfc_notify_std (GFC_STD_F2008, "RE or IM part_ref at %C"))
		return MATCH_ERROR;

	      if (primary->ts.type != BT_COMPLEX)
		{
		  gfc_error ("The RE or IM part_ref at %C must be "
			     "applied to a COMPLEX expression");
		  return MATCH_ERROR;
		}
	      primary->ts.type = BT_REAL;
	      break;

	    case INQUIRY_LEN:
	      if (!gfc_notify_std (GFC_STD_F2003, "LEN part_ref at %C"))
		return MATCH_ERROR;

	      if (primary->ts.type != BT_CHARACTER)
		{
		  gfc_error ("The LEN part_ref at %C must be applied "
			     "to a CHARACTER expression");
		  return MATCH_ERROR;
		}
	      primary->ts.u.cl = NULL;
	      primary->ts.type = BT_INTEGER;
	      primary->ts.kind = gfc_default_integer_kind;
	      break;

	    case INQUIRY_KIND:
	      if (!gfc_notify_std (GFC_STD_F2003, "KIND part_ref at %C"))
		return MATCH_ERROR;

	      if (primary->ts.type == BT_CLASS
		  || primary->ts.type == BT_DERIVED)
		{
		  gfc_error ("The KIND part_ref at %C must be applied "
			     "to an expression of intrinsic type");
		  return MATCH_ERROR;
		}
	      primary->ts.type = BT_INTEGER;
	      primary->ts.kind = gfc_default_integer_kind;
	      break;

	    default:
	      gcc_unreachable ();
	    }

	  goto check_done;
	}

      primary->ts = component->ts;

      if (component->attr.proc_pointer && ppc_arg)
	{
	  /* Procedure pointer component call: Look for argument list.  */
	  m = gfc_match_actual_arglist (sub_flag,
					&primary->value.compcall.actual);
	  if (m == MATCH_ERROR)
	    return MATCH_ERROR;

	  if (m == MATCH_NO && !gfc_matching_ptr_assignment
	      && !gfc_matching_procptr_assignment && !matching_actual_arglist)
	    {
	      gfc_error ("Procedure pointer component %qs requires an "
			 "argument list at %C", component->name);
	      return MATCH_ERROR;
	    }

	  if (m == MATCH_YES)
	    primary->expr_type = EXPR_PPC;

          break;
	}

      if (component->as != NULL && !component->attr.proc_pointer)
	{
	  tail = extend_ref (primary, tail);
	  tail->type = REF_ARRAY;

	  m = gfc_match_array_ref (&tail->u.ar, component->as, equiv_flag,
			  component->as->corank);
	  if (m != MATCH_YES)
	    return m;
	}
      else if (component->ts.type == BT_CLASS && component->attr.class_ok
	       && CLASS_DATA (component)->as && !component->attr.proc_pointer)
	{
	  tail = extend_ref (primary, tail);
	  tail->type = REF_ARRAY;

	  m = gfc_match_array_ref (&tail->u.ar, CLASS_DATA (component)->as,
				   equiv_flag,
				   CLASS_DATA (component)->as->corank);
	  if (m != MATCH_YES)
	    return m;
	}

check_done:
      /* In principle, we could have eg. expr%re%kind so we must allow for
	 this possibility.  */
      if (gfc_match_char ('%') == MATCH_YES)
	{
	  if (component && (component->ts.type == BT_DERIVED
			    || component->ts.type == BT_CLASS))
	    sym = component->ts.u.derived;
	  continue;
	}
      else if (inquiry)
	break;

      if ((component->ts.type != BT_DERIVED && component->ts.type != BT_CLASS)
  	  || gfc_match_member_sep (component->ts.u.derived) != MATCH_YES)
	break;

      if (component->ts.type == BT_DERIVED || component->ts.type == BT_CLASS)
	sym = component->ts.u.derived;
    }

check_substring:
  unknown = false;
  if (primary->ts.type == BT_UNKNOWN && !gfc_fl_struct (sym->attr.flavor))
    {
      if (gfc_get_default_type (sym->name, sym->ns)->type == BT_CHARACTER)
       {
	 gfc_set_default_type (sym, 0, sym->ns);
	 primary->ts = sym->ts;
	 unknown = true;
       }
    }

  if (primary->ts.type == BT_CHARACTER)
    {
      bool def = primary->ts.deferred == 1;
      switch (match_substring (primary->ts.u.cl, equiv_flag, &substring, def))
	{
	case MATCH_YES:
	  if (tail == NULL)
	    primary->ref = substring;
	  else
	    tail->next = substring;

	  if (primary->expr_type == EXPR_CONSTANT)
	    primary->expr_type = EXPR_SUBSTRING;

	  if (substring)
	    primary->ts.u.cl = NULL;

	  break;

	case MATCH_NO:
	  if (unknown)
	    {
	      gfc_clear_ts (&primary->ts);
	      gfc_clear_ts (&sym->ts);
	    }
	  break;

	case MATCH_ERROR:
	  return MATCH_ERROR;
	}
    }

  /* F08:C611.  */
  if (primary->ts.type == BT_DERIVED && primary->ref
      && primary->ts.u.derived && primary->ts.u.derived->attr.abstract)
    {
      gfc_error ("Nonpolymorphic reference to abstract type at %C");
      return MATCH_ERROR;
    }

  /* F08:C727.  */
  if (primary->expr_type == EXPR_PPC && gfc_is_coindexed (primary))
    {
      gfc_error ("Coindexed procedure-pointer component at %C");
      return MATCH_ERROR;
    }

  return MATCH_YES;
}


/* Given an expression that is a variable, figure out what the
   ultimate variable's type and attribute is, traversing the reference
   structures if necessary.

   This subroutine is trickier than it looks.  We start at the base
   symbol and store the attribute.  Component references load a
   completely new attribute.

   A couple of rules come into play.  Subobjects of targets are always
   targets themselves.  If we see a component that goes through a
   pointer, then the expression must also be a target, since the
   pointer is associated with something (if it isn't core will soon be
   dumped).  If we see a full part or section of an array, the
   expression is also an array.

   We can have at most one full array reference.  */

symbol_attribute
gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
{
  int dimension, codimension, pointer, allocatable, target, optional;
  symbol_attribute attr;
  gfc_ref *ref;
  gfc_symbol *sym;
  gfc_component *comp;
  bool has_inquiry_part;

  if (expr->expr_type != EXPR_VARIABLE && expr->expr_type != EXPR_FUNCTION)
    gfc_internal_error ("gfc_variable_attr(): Expression isn't a variable");

  sym = expr->symtree->n.sym;
  attr = sym->attr;

  optional = attr.optional;
  if (sym->ts.type == BT_CLASS && sym->attr.class_ok && sym->ts.u.derived)
    {
      dimension = CLASS_DATA (sym)->attr.dimension;
      codimension = CLASS_DATA (sym)->attr.codimension;
      pointer = CLASS_DATA (sym)->attr.class_pointer;
      allocatable = CLASS_DATA (sym)->attr.allocatable;
      optional |= CLASS_DATA (sym)->attr.optional;
    }
  else
    {
      dimension = attr.dimension;
      codimension = attr.codimension;
      pointer = attr.pointer;
      allocatable = attr.allocatable;
    }

  target = attr.target;
  if (pointer || attr.proc_pointer)
    target = 1;

  if (ts != NULL && expr->ts.type == BT_UNKNOWN)
    *ts = sym->ts;

  has_inquiry_part = false;
  for (ref = expr->ref; ref; ref = ref->next)
    if (ref->type == REF_INQUIRY)
      {
	has_inquiry_part = true;
	optional = false;
	break;
      }

  for (ref = expr->ref; ref; ref = ref->next)
    switch (ref->type)
      {
      case REF_ARRAY:

	switch (ref->u.ar.type)
	  {
	  case AR_FULL:
	    dimension = 1;
	    break;

	  case AR_SECTION:
	    allocatable = pointer = 0;
	    dimension = 1;
	    optional = false;
	    break;

	  case AR_ELEMENT:
	    /* Handle coarrays.  */
	    if (ref->u.ar.dimen > 0)
	      allocatable = pointer = optional = false;
	    break;

	  case AR_UNKNOWN:
	    /* For standard conforming code, AR_UNKNOWN should not happen.
	       For nonconforming code, gfortran can end up here.  Treat it
	       as a no-op.  */
	    break;
	  }

	break;

      case REF_COMPONENT:
	optional = false;
	comp = ref->u.c.component;
	attr = comp->attr;
	if (ts != NULL && !has_inquiry_part)
	  {
	    *ts = comp->ts;
	    /* Don't set the string length if a substring reference
	       follows.  */
	    if (ts->type == BT_CHARACTER
		&& ref->next && ref->next->type == REF_SUBSTRING)
		ts->u.cl = NULL;
	  }

	if (comp->ts.type == BT_CLASS)
	  {
	    codimension = CLASS_DATA (comp)->attr.codimension;
	    pointer = CLASS_DATA (comp)->attr.class_pointer;
	    allocatable = CLASS_DATA (comp)->attr.allocatable;
	  }
	else
	  {
	    codimension = comp->attr.codimension;
	    if (expr->ts.type == BT_CLASS && strcmp (comp->name, "_data") == 0)
	      pointer = comp->attr.class_pointer;
	    else
	      pointer = comp->attr.pointer;
	    allocatable = comp->attr.allocatable;
	  }
	if (pointer || attr.proc_pointer)
	  target = 1;

	break;

      case REF_INQUIRY:
      case REF_SUBSTRING:
	allocatable = pointer = optional = false;
	break;
      }

  attr.dimension = dimension;
  attr.codimension = codimension;
  attr.pointer = pointer;
  attr.allocatable = allocatable;
  attr.target = target;
  attr.save = sym->attr.save;
  attr.optional = optional;

  return attr;
}


/* Return the attribute from a general expression.  */

symbol_attribute
gfc_expr_attr (gfc_expr *e)
{
  symbol_attribute attr;

  switch (e->expr_type)
    {
    case EXPR_VARIABLE:
      attr = gfc_variable_attr (e, NULL);
      break;

    case EXPR_FUNCTION:
      gfc_clear_attr (&attr);

      if (e->value.function.esym && e->value.function.esym->result)
	{
	  gfc_symbol *sym = e->value.function.esym->result;
	  attr = sym->attr;
	  if (sym->ts.type == BT_CLASS)
	    {
	      attr.dimension = CLASS_DATA (sym)->attr.dimension;
	      attr.pointer = CLASS_DATA (sym)->attr.class_pointer;
	      attr.allocatable = CLASS_DATA (sym)->attr.allocatable;
	    }
	}
      else if (e->value.function.isym
	       && e->value.function.isym->transformational
	       && e->ts.type == BT_CLASS)
	attr = CLASS_DATA (e)->attr;
      else if (e->symtree)
	attr = gfc_variable_attr (e, NULL);

      /* TODO: NULL() returns pointers.  May have to take care of this
	 here.  */

      break;

    default:
      gfc_clear_attr (&attr);
      break;
    }

  return attr;
}


/* Given an expression, figure out what the ultimate expression
   attribute is.  This routine is similar to gfc_variable_attr with
   parts of gfc_expr_attr, but focuses more on the needs of
   coarrays.  For coarrays a codimension attribute is kind of
   "infectious" being propagated once set and never cleared.
   The coarray_comp is only set, when the expression refs a coarray
   component.  REFS_COMP is set when present to true only, when this EXPR
   refs a (non-_data) component.  To check whether EXPR refs an allocatable
   component in a derived type coarray *refs_comp needs to be set and
   coarray_comp has to false.  */

static symbol_attribute
caf_variable_attr (gfc_expr *expr, bool in_allocate, bool *refs_comp)
{
  int dimension, codimension, pointer, allocatable, target, coarray_comp;
  symbol_attribute attr;
  gfc_ref *ref;
  gfc_symbol *sym;
  gfc_component *comp;

  if (expr->expr_type != EXPR_VARIABLE && expr->expr_type != EXPR_FUNCTION)
    gfc_internal_error ("gfc_caf_attr(): Expression isn't a variable");

  sym = expr->symtree->n.sym;
  gfc_clear_attr (&attr);

  if (refs_comp)
    *refs_comp = false;

  if (sym->ts.type == BT_CLASS && sym->attr.class_ok)
    {
      dimension = CLASS_DATA (sym)->attr.dimension;
      codimension = CLASS_DATA (sym)->attr.codimension;
      pointer = CLASS_DATA (sym)->attr.class_pointer;
      allocatable = CLASS_DATA (sym)->attr.allocatable;
      attr.alloc_comp = CLASS_DATA (sym)->ts.u.derived->attr.alloc_comp;
      attr.pointer_comp = CLASS_DATA (sym)->ts.u.derived->attr.pointer_comp;
    }
  else
    {
      dimension = sym->attr.dimension;
      codimension = sym->attr.codimension;
      pointer = sym->attr.pointer;
      allocatable = sym->attr.allocatable;
      attr.alloc_comp = sym->ts.type == BT_DERIVED
	  ? sym->ts.u.derived->attr.alloc_comp : 0;
      attr.pointer_comp = sym->ts.type == BT_DERIVED
	  ? sym->ts.u.derived->attr.pointer_comp : 0;
    }

  target = coarray_comp = 0;
  if (pointer || attr.proc_pointer)
    target = 1;

  for (ref = expr->ref; ref; ref = ref->next)
    switch (ref->type)
      {
      case REF_ARRAY:

	switch (ref->u.ar.type)
	  {
	  case AR_FULL:
	  case AR_SECTION:
	    dimension = 1;
	    break;

	  case AR_ELEMENT:
	    /* Handle coarrays.  */
	    if (ref->u.ar.dimen > 0 && !in_allocate)
	      allocatable = pointer = 0;
	    break;

	  case AR_UNKNOWN:
	    /* If any of start, end or stride is not integer, there will
	       already have been an error issued.  */
	    int errors;
	    gfc_get_errors (NULL, &errors);
	    if (errors == 0)
	      gfc_internal_error ("gfc_caf_attr(): Bad array reference");
	  }

	break;

      case REF_COMPONENT:
	comp = ref->u.c.component;

	if (comp->ts.type == BT_CLASS)
	  {
	    /* Set coarray_comp only, when this component introduces the
	       coarray.  */
	    coarray_comp = !codimension && CLASS_DATA (comp)->attr.codimension;
	    codimension |= CLASS_DATA (comp)->attr.codimension;
	    pointer = CLASS_DATA (comp)->attr.class_pointer;
	    allocatable = CLASS_DATA (comp)->attr.allocatable;
	  }
	else
	  {
	    /* Set coarray_comp only, when this component introduces the
	       coarray.  */
	    coarray_comp = !codimension && comp->attr.codimension;
	    codimension |= comp->attr.codimension;
	    pointer = comp->attr.pointer;
	    allocatable = comp->attr.allocatable;
	  }

	if (refs_comp && strcmp (comp->name, "_data") != 0
	    && (ref->next == NULL
		|| (ref->next->type == REF_ARRAY && ref->next->next == NULL)))
	  *refs_comp = true;

	if (pointer || attr.proc_pointer)
	  target = 1;

	break;

      case REF_SUBSTRING:
      case REF_INQUIRY:
	allocatable = pointer = 0;
	break;
      }

  attr.dimension = dimension;
  attr.codimension = codimension;
  attr.pointer = pointer;
  attr.allocatable = allocatable;
  attr.target = target;
  attr.save = sym->attr.save;
  attr.coarray_comp = coarray_comp;

  return attr;
}


symbol_attribute
gfc_caf_attr (gfc_expr *e, bool in_allocate, bool *refs_comp)
{
  symbol_attribute attr;

  switch (e->expr_type)
    {
    case EXPR_VARIABLE:
      attr = caf_variable_attr (e, in_allocate, refs_comp);
      break;

    case EXPR_FUNCTION:
      gfc_clear_attr (&attr);

      if (e->value.function.esym && e->value.function.esym->result)
	{
	  gfc_symbol *sym = e->value.function.esym->result;
	  attr = sym->attr;
	  if (sym->ts.type == BT_CLASS)
	    {
	      attr.dimension = CLASS_DATA (sym)->attr.dimension;
	      attr.pointer = CLASS_DATA (sym)->attr.class_pointer;
	      attr.allocatable = CLASS_DATA (sym)->attr.allocatable;
	      attr.alloc_comp = CLASS_DATA (sym)->ts.u.derived->attr.alloc_comp;
	      attr.pointer_comp = CLASS_DATA (sym)->ts.u.derived
		  ->attr.pointer_comp;
	    }
	}
      else if (e->symtree)
	attr = caf_variable_attr (e, in_allocate, refs_comp);
      else
	gfc_clear_attr (&attr);
      break;

    default:
      gfc_clear_attr (&attr);
      break;
    }

  return attr;
}


/* Match a structure constructor.  The initial symbol has already been
   seen.  */

typedef struct gfc_structure_ctor_component
{
  char* name;
  gfc_expr* val;
  locus where;
  struct gfc_structure_ctor_component* next;
}
gfc_structure_ctor_component;

#define gfc_get_structure_ctor_component() XCNEW (gfc_structure_ctor_component)

static void
gfc_free_structure_ctor_component (gfc_structure_ctor_component *comp)
{
  free (comp->name);
  gfc_free_expr (comp->val);
  free (comp);
}


/* Translate the component list into the actual constructor by sorting it in
   the order required; this also checks along the way that each and every
   component actually has an initializer and handles default initializers
   for components without explicit value given.  */
static bool
build_actual_constructor (gfc_structure_ctor_component **comp_head,
			  gfc_constructor_base *ctor_head, gfc_symbol *sym)
{
  gfc_structure_ctor_component *comp_iter;
  gfc_component *comp;

  for (comp = sym->components; comp; comp = comp->next)
    {
      gfc_structure_ctor_component **next_ptr;
      gfc_expr *value = NULL;

      /* Try to find the initializer for the current component by name.  */
      next_ptr = comp_head;
      for (comp_iter = *comp_head; comp_iter; comp_iter = comp_iter->next)
	{
	  if (!strcmp (comp_iter->name, comp->name))
	    break;
	  next_ptr = &comp_iter->next;
	}

      /* If an extension, try building the parent derived type by building
	 a value expression for the parent derived type and calling self.  */
      if (!comp_iter && comp == sym->components && sym->attr.extension)
	{
	  value = gfc_get_structure_constructor_expr (comp->ts.type,
						      comp->ts.kind,
						      &gfc_current_locus);
	  value->ts = comp->ts;

	  if (!build_actual_constructor (comp_head,
					 &value->value.constructor,
					 comp->ts.u.derived))
	    {
	      gfc_free_expr (value);
	      return false;
	    }

	  gfc_constructor_append_expr (ctor_head, value, NULL);
	  continue;
	}

      /* If it was not found, apply NULL expression to set the component as
	 unallocated. Then try the default initializer if there's any;
	 otherwise, it's an error unless this is a deferred parameter.  */
      if (!comp_iter)
	{
	  /* F2018 7.5.10: If an allocatable component has no corresponding
	     component-data-source, then that component has an allocation
	     status of unallocated....  */
	  if (comp->attr.allocatable
	      || (comp->ts.type == BT_CLASS
		  && CLASS_DATA (comp)->attr.allocatable))
	    {
	      if (!gfc_notify_std (GFC_STD_F2008, "No initializer for "
				   "allocatable component %qs given in the "
				   "structure constructor at %C", comp->name))
		return false;
	      value = gfc_get_null_expr (&gfc_current_locus);
	    }
	  /* ....(Preceeding sentence) If a component with default
	     initialization has no corresponding component-data-source, then
	     the default initialization is applied to that component.  */
	  else if (comp->initializer)
	    {
	      if (!gfc_notify_std (GFC_STD_F2003, "Structure constructor "
				   "with missing optional arguments at %C"))
		return false;
	      value = gfc_copy_expr (comp->initializer);
	    }
	  /* Do not trap components such as the string length for deferred
	     length character components.  */
	  else if (!comp->attr.artificial)
	    {
	      gfc_error ("No initializer for component %qs given in the"
			 " structure constructor at %C", comp->name);
	      return false;
	    }
	}
      else
	value = comp_iter->val;

      /* Add the value to the constructor chain built.  */
      gfc_constructor_append_expr (ctor_head, value, NULL);

      /* Remove the entry from the component list.  We don't want the expression
	 value to be free'd, so set it to NULL.  */
      if (comp_iter)
	{
	  *next_ptr = comp_iter->next;
	  comp_iter->val = NULL;
	  gfc_free_structure_ctor_component (comp_iter);
	}
    }
  return true;
}


bool
gfc_convert_to_structure_constructor (gfc_expr *e, gfc_symbol *sym, gfc_expr **cexpr,
				      gfc_actual_arglist **arglist,
				      bool parent)
{
  gfc_actual_arglist *actual;
  gfc_structure_ctor_component *comp_tail, *comp_head, *comp_iter;
  gfc_constructor_base ctor_head = NULL;
  gfc_component *comp; /* Is set NULL when named component is first seen */
  const char* last_name = NULL;
  locus old_locus;
  gfc_expr *expr;

  expr = parent ? *cexpr : e;
  old_locus = gfc_current_locus;
  if (parent)
    ; /* gfc_current_locus = *arglist->expr ? ->where;*/
  else
    gfc_current_locus = expr->where;

  comp_tail = comp_head = NULL;

  if (!parent && sym->attr.abstract)
    {
      gfc_error ("Cannot construct ABSTRACT type %qs at %L",
		 sym->name, &expr->where);
      goto cleanup;
    }

  comp = sym->components;
  actual = parent ? *arglist : expr->value.function.actual;
  for ( ; actual; )
    {
      gfc_component *this_comp = NULL;

      if (!comp_head)
	comp_tail = comp_head = gfc_get_structure_ctor_component ();
      else
	{
	  comp_tail->next = gfc_get_structure_ctor_component ();
	  comp_tail = comp_tail->next;
       	}
      if (actual->name)
	{
	  if (!gfc_notify_std (GFC_STD_F2003, "Structure"
			       " constructor with named arguments at %C"))
	    goto cleanup;

	  comp_tail->name = xstrdup (actual->name);
	  last_name = comp_tail->name;
	  comp = NULL;
	}
      else
	{
	  /* Components without name are not allowed after the first named
	     component initializer!  */
	  if (!comp || comp->attr.artificial)
	    {
	      if (last_name)
		gfc_error ("Component initializer without name after component"
			   " named %s at %L", last_name,
			   actual->expr ? &actual->expr->where
					: &gfc_current_locus);
	      else
		gfc_error ("Too many components in structure constructor at "
			   "%L", actual->expr ? &actual->expr->where
					      : &gfc_current_locus);
	      goto cleanup;
	    }

	  comp_tail->name = xstrdup (comp->name);
	}

      /* Find the current component in the structure definition and check
	     its access is not private.  */
      if (comp)
	this_comp = gfc_find_component (sym, comp->name, false, false, NULL);
      else
	{
	  this_comp = gfc_find_component (sym, (const char *)comp_tail->name,
					  false, false, NULL);
	  comp = NULL; /* Reset needed!  */
	}

      /* Here we can check if a component name is given which does not
	 correspond to any component of the defined structure.  */
      if (!this_comp)
	goto cleanup;

      /* For a constant string constructor, make sure the length is
	 correct; truncate of fill with blanks if needed.  */
      if (this_comp->ts.type == BT_CHARACTER && !this_comp->attr.allocatable
	  && this_comp->ts.u.cl && this_comp->ts.u.cl->length
	  && this_comp->ts.u.cl->length->expr_type == EXPR_CONSTANT
	  && actual->expr->ts.type == BT_CHARACTER
	  && actual->expr->expr_type == EXPR_CONSTANT)
	{
	  ptrdiff_t c, e1;
	  c = gfc_mpz_get_hwi (this_comp->ts.u.cl->length->value.integer);
	  e1 = actual->expr->value.character.length;

	  if (c != e1)
	    {
	      ptrdiff_t i, to;
	      gfc_char_t *dest;
	      dest = gfc_get_wide_string (c + 1);

	      to = e1 < c ? e1 : c;
	      for (i = 0; i < to; i++)
		dest[i] = actual->expr->value.character.string[i];

	      for (i = e1; i < c; i++)
		dest[i] = ' ';

	      dest[c] = '\0';
	      free (actual->expr->value.character.string);

	      actual->expr->value.character.length = c;
	      actual->expr->value.character.string = dest;

	      if (warn_line_truncation && c < e1)
		gfc_warning_now (OPT_Wcharacter_truncation,
				 "CHARACTER expression will be truncated "
				 "in constructor (%ld/%ld) at %L", (long int) c,
				 (long int) e1, &actual->expr->where);
	    }
	}

      comp_tail->val = actual->expr;
      if (actual->expr != NULL)
	comp_tail->where = actual->expr->where;
      actual->expr = NULL;

      /* Check if this component is already given a value.  */
      for (comp_iter = comp_head; comp_iter != comp_tail;
	   comp_iter = comp_iter->next)
	{
	  gcc_assert (comp_iter);
	  if (!strcmp (comp_iter->name, comp_tail->name))
	    {
	      gfc_error ("Component %qs is initialized twice in the structure"
			 " constructor at %L", comp_tail->name,
			 comp_tail->val ? &comp_tail->where
					: &gfc_current_locus);
	      goto cleanup;
	    }
	}

      /* F2008, R457/C725, for PURE C1283.  */
      if (this_comp->attr.pointer && comp_tail->val
	  && gfc_is_coindexed (comp_tail->val))
     	{
	  gfc_error ("Coindexed expression to pointer component %qs in "
		     "structure constructor at %L", comp_tail->name,
		     &comp_tail->where);
	  goto cleanup;
	}

          /* If not explicitly a parent constructor, gather up the components
             and build one.  */
          if (comp && comp == sym->components
                && sym->attr.extension
		&& comp_tail->val
                && (!gfc_bt_struct (comp_tail->val->ts.type)
                      ||
                    comp_tail->val->ts.u.derived != this_comp->ts.u.derived))
            {
              bool m;
	      gfc_actual_arglist *arg_null = NULL;

	      actual->expr = comp_tail->val;
	      comp_tail->val = NULL;

              m = gfc_convert_to_structure_constructor (NULL,
					comp->ts.u.derived, &comp_tail->val,
					comp->ts.u.derived->attr.zero_comp
					  ? &arg_null : &actual, true);
              if (!m)
                goto cleanup;

	      if (comp->ts.u.derived->attr.zero_comp)
		{
		  comp = comp->next;
		  continue;
		}
            }

      if (comp)
	comp = comp->next;
      if (parent && !comp)
	break;

      if (actual)
	actual = actual->next;
    }

  if (!build_actual_constructor (&comp_head, &ctor_head, sym))
    goto cleanup;

  /* No component should be left, as this should have caused an error in the
     loop constructing the component-list (name that does not correspond to any
     component in the structure definition).  */
  if (comp_head && sym->attr.extension)
    {
      for (comp_iter = comp_head; comp_iter; comp_iter = comp_iter->next)
	{
	  gfc_error ("component %qs at %L has already been set by a "
		     "parent derived type constructor", comp_iter->name,
		     &comp_iter->where);
	}
      goto cleanup;
    }
  else
    gcc_assert (!comp_head);

  if (parent)
    {
      expr = gfc_get_structure_constructor_expr (BT_DERIVED, 0, &gfc_current_locus);
      expr->ts.u.derived = sym;
      expr->value.constructor = ctor_head;
      *cexpr = expr;
    }
  else
    {
      expr->ts.u.derived = sym;
      expr->ts.kind = 0;
      expr->ts.type = BT_DERIVED;
      expr->value.constructor = ctor_head;
      expr->expr_type = EXPR_STRUCTURE;
    }

  gfc_current_locus = old_locus;
  if (parent)
    *arglist = actual;
  return true;

  cleanup:
  gfc_current_locus = old_locus;

  for (comp_iter = comp_head; comp_iter; )
    {
      gfc_structure_ctor_component *next = comp_iter->next;
      gfc_free_structure_ctor_component (comp_iter);
      comp_iter = next;
    }
  gfc_constructor_free (ctor_head);

  return false;
}


match
gfc_match_structure_constructor (gfc_symbol *sym, gfc_expr **result)
{
  match m;
  gfc_expr *e;
  gfc_symtree *symtree;
  bool t = true;

  gfc_get_ha_sym_tree (sym->name, &symtree);

  e = gfc_get_expr ();
  e->symtree = symtree;
  e->expr_type = EXPR_FUNCTION;
  e->where = gfc_current_locus;

  gcc_assert (gfc_fl_struct (sym->attr.flavor)
	      && symtree->n.sym->attr.flavor == FL_PROCEDURE);
  e->value.function.esym = sym;
  e->symtree->n.sym->attr.generic = 1;

  m = gfc_match_actual_arglist (0, &e->value.function.actual);
  if (m != MATCH_YES)
    {
      gfc_free_expr (e);
      return m;
    }

  if (!gfc_convert_to_structure_constructor (e, sym, NULL, NULL, false))
    {
      gfc_free_expr (e);
      return MATCH_ERROR;
    }

  /* If a structure constructor is in a DATA statement, then each entity
     in the structure constructor must be a constant.  Try to reduce the
     expression here.  */
  if (gfc_in_match_data ())
    t = gfc_reduce_init_expr (e);

  if (t)
    {
      *result = e;
      return MATCH_YES;
    }
  else
    {
      gfc_free_expr (e);
      return MATCH_ERROR;
    }
}


/* If the symbol is an implicit do loop index and implicitly typed,
   it should not be host associated.  Provide a symtree from the
   current namespace.  */
static match
check_for_implicit_index (gfc_symtree **st, gfc_symbol **sym)
{
  if ((*sym)->attr.flavor == FL_VARIABLE
      && (*sym)->ns != gfc_current_ns
      && (*sym)->attr.implied_index
      && (*sym)->attr.implicit_type
      && !(*sym)->attr.use_assoc)
    {
      int i;
      i = gfc_get_sym_tree ((*sym)->name, NULL, st, false);
      if (i)
	return MATCH_ERROR;
      *sym = (*st)->n.sym;
    }
  return MATCH_YES;
}


/* Procedure pointer as function result: Replace the function symbol by the
   auto-generated hidden result variable named "ppr@".  */

static bool
replace_hidden_procptr_result (gfc_symbol **sym, gfc_symtree **st)
{
  /* Check for procedure pointer result variable.  */
  if ((*sym)->attr.function && !(*sym)->attr.external
      && (*sym)->result && (*sym)->result != *sym
      && (*sym)->result->attr.proc_pointer
      && (*sym) == gfc_current_ns->proc_name
      && (*sym) == (*sym)->result->ns->proc_name
      && strcmp ("ppr@", (*sym)->result->name) == 0)
    {
      /* Automatic replacement with "hidden" result variable.  */
      (*sym)->result->attr.referenced = (*sym)->attr.referenced;
      *sym = (*sym)->result;
      *st = gfc_find_symtree ((*sym)->ns->sym_root, (*sym)->name);
      return true;
    }
  return false;
}


/* Matches a variable name followed by anything that might follow it--
   array reference, argument list of a function, etc.  */

match
gfc_match_rvalue (gfc_expr **result)
{
  gfc_actual_arglist *actual_arglist;
  char name[GFC_MAX_SYMBOL_LEN + 1], argname[GFC_MAX_SYMBOL_LEN + 1];
  gfc_state_data *st;
  gfc_symbol *sym;
  gfc_symtree *symtree;
  locus where, old_loc;
  gfc_expr *e;
  match m, m2;
  int i;
  gfc_typespec *ts;
  bool implicit_char;
  gfc_ref *ref;

  m = gfc_match ("%%loc");
  if (m == MATCH_YES)
    {
      if (!gfc_notify_std (GFC_STD_LEGACY, "%%LOC() as an rvalue at %C"))
        return MATCH_ERROR;
      strncpy (name, "loc", 4);
    }

  else
    {
      m = gfc_match_name (name);
      if (m != MATCH_YES)
        return m;
    }

  /* Check if the symbol exists.  */
  if (gfc_find_sym_tree (name, NULL, 1, &symtree))
    return MATCH_ERROR;

  /* If the symbol doesn't exist, create it unless the name matches a FL_STRUCT
     type. For derived types we create a generic symbol which links to the
     derived type symbol; STRUCTUREs are simpler and must not conflict with
     variables.  */
  if (!symtree)
    if (gfc_find_sym_tree (gfc_dt_upper_string (name), NULL, 1, &symtree))
      return MATCH_ERROR;
  if (!symtree || symtree->n.sym->attr.flavor != FL_STRUCT)
    {
      if (gfc_find_state (COMP_INTERFACE)
          && !gfc_current_ns->has_import_set)
        i = gfc_get_sym_tree (name, NULL, &symtree, false);
      else
        i = gfc_get_ha_sym_tree (name, &symtree);
      if (i)
        return MATCH_ERROR;
    }


  sym = symtree->n.sym;
  e = NULL;
  where = gfc_current_locus;

  replace_hidden_procptr_result (&sym, &symtree);

  /* If this is an implicit do loop index and implicitly typed,
     it should not be host associated.  */
  m = check_for_implicit_index (&symtree, &sym);
  if (m != MATCH_YES)
    return m;

  gfc_set_sym_referenced (sym);
  sym->attr.implied_index = 0;

  if (sym->attr.function && sym->result == sym)
    {
      /* See if this is a directly recursive function call.  */
      gfc_gobble_whitespace ();
      if (sym->attr.recursive
	  && gfc_peek_ascii_char () == '('
	  && gfc_current_ns->proc_name == sym
	  && !sym->attr.dimension)
	{
	  gfc_error ("%qs at %C is the name of a recursive function "
		     "and so refers to the result variable. Use an "
		     "explicit RESULT variable for direct recursion "
		     "(12.5.2.1)", sym->name);
	  return MATCH_ERROR;
	}

      if (gfc_is_function_return_value (sym, gfc_current_ns))
	goto variable;

      if (sym->attr.entry
	  && (sym->ns == gfc_current_ns
	      || sym->ns == gfc_current_ns->parent))
	{
	  gfc_entry_list *el = NULL;

	  for (el = sym->ns->entries; el; el = el->next)
	    if (sym == el->sym)
	      goto variable;
	}
    }

  if (gfc_matching_procptr_assignment)
    {
      /* It can be a procedure or a derived-type procedure or a not-yet-known
	 type.  */
      if (sym->attr.flavor != FL_UNKNOWN
	  && sym->attr.flavor != FL_PROCEDURE
	  && sym->attr.flavor != FL_PARAMETER
	  && sym->attr.flavor != FL_VARIABLE)
	{
	  gfc_error ("Symbol at %C is not appropriate for an expression");
	  return MATCH_ERROR;
	}
      goto procptr0;
    }

  if (sym->attr.function || sym->attr.external || sym->attr.intrinsic)
    goto function0;

  if (sym->attr.generic)
    goto generic_function;

  switch (sym->attr.flavor)
    {
    case FL_VARIABLE:
    variable:
      e = gfc_get_expr ();

      e->expr_type = EXPR_VARIABLE;
      e->symtree = symtree;

      m = gfc_match_varspec (e, 0, false, true);
      break;

    case FL_PARAMETER:
      /* A statement of the form "REAL, parameter :: a(0:10) = 1" will
	 end up here.  Unfortunately, sym->value->expr_type is set to
	 EXPR_CONSTANT, and so the if () branch would be followed without
	 the !sym->as check.  */
      if (sym->value && sym->value->expr_type != EXPR_ARRAY && !sym->as)
	e = gfc_copy_expr (sym->value);
      else
	{
	  e = gfc_get_expr ();
	  e->expr_type = EXPR_VARIABLE;
	}

      e->symtree = symtree;
      m = gfc_match_varspec (e, 0, false, true);

      if (sym->ts.is_c_interop || sym->ts.is_iso_c)
	break;

      /* Variable array references to derived type parameters cause
	 all sorts of headaches in simplification. Treating such
	 expressions as variable works just fine for all array
	 references.  */
      if (sym->value && sym->ts.type == BT_DERIVED && e->ref)
	{
	  for (ref = e->ref; ref; ref = ref->next)
	    if (ref->type == REF_ARRAY)
	      break;

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

	  ref = e->ref;
	  e->ref = NULL;
	  gfc_free_expr (e);
	  e = gfc_get_expr ();
	  e->expr_type = EXPR_VARIABLE;
	  e->symtree = symtree;
	  e->ref = ref;
	}

      break;

    case FL_STRUCT:
    case FL_DERIVED:
      sym = gfc_use_derived (sym);
      if (sym == NULL)
	m = MATCH_ERROR;
      else
	goto generic_function;
      break;

    /* If we're here, then the name is known to be the name of a
       procedure, yet it is not sure to be the name of a function.  */
    case FL_PROCEDURE:

    /* Procedure Pointer Assignments.  */
    procptr0:
      if (gfc_matching_procptr_assignment)
	{
	  gfc_gobble_whitespace ();
	  if (!sym->attr.dimension && gfc_peek_ascii_char () == '(')
	    /* Parse functions returning a procptr.  */
	    goto function0;

	  e = gfc_get_expr ();
	  e->expr_type = EXPR_VARIABLE;
	  e->symtree = symtree;
	  m = gfc_match_varspec (e, 0, false, true);
	  if (!e->ref && sym->attr.flavor == FL_UNKNOWN
	      && sym->ts.type == BT_UNKNOWN
	      && !gfc_add_flavor (&sym->attr, FL_PROCEDURE, sym->name, NULL))
	    {
	      m = MATCH_ERROR;
	      break;
	    }
	  break;
	}

      if (sym->attr.subroutine)
	{
	  gfc_error ("Unexpected use of subroutine name %qs at %C",
		     sym->name);
	  m = MATCH_ERROR;
	  break;
	}

      /* At this point, the name has to be a non-statement function.
	 If the name is the same as the current function being
	 compiled, then we have a variable reference (to the function
	 result) if the name is non-recursive.  */

      st = gfc_enclosing_unit (NULL);

      if (st != NULL
	  && st->state == COMP_FUNCTION
	  && st->sym == sym
	  && !sym->attr.recursive)
	{
	  e = gfc_get_expr ();
	  e->symtree = symtree;
	  e->expr_type = EXPR_VARIABLE;

	  m = gfc_match_varspec (e, 0, false, true);
	  break;
	}

    /* Match a function reference.  */
    function0:
      m = gfc_match_actual_arglist (0, &actual_arglist);
      if (m == MATCH_NO)
	{
	  if (sym->attr.proc == PROC_ST_FUNCTION)
	    gfc_error ("Statement function %qs requires argument list at %C",
		       sym->name);
	  else
	    gfc_error ("Function %qs requires an argument list at %C",
		       sym->name);

	  m = MATCH_ERROR;
	  break;
	}

      if (m != MATCH_YES)
	{
	  m = MATCH_ERROR;
	  break;
	}

      gfc_get_ha_sym_tree (name, &symtree);	/* Can't fail */
      sym = symtree->n.sym;

      replace_hidden_procptr_result (&sym, &symtree);

      e = gfc_get_expr ();
      e->symtree = symtree;
      e->expr_type = EXPR_FUNCTION;
      e->value.function.actual = actual_arglist;
      e->where = gfc_current_locus;

      if (sym->ts.type == BT_CLASS && sym->attr.class_ok
	  && CLASS_DATA (sym)->as)
	e->rank = CLASS_DATA (sym)->as->rank;
      else if (sym->as != NULL)
	e->rank = sym->as->rank;

      if (!sym->attr.function
	  && !gfc_add_function (&sym->attr, sym->name, NULL))
	{
	  m = MATCH_ERROR;
	  break;
	}

      /* Check here for the existence of at least one argument for the
         iso_c_binding functions C_LOC, C_FUNLOC, and C_ASSOCIATED.  The
         argument(s) given will be checked in gfc_iso_c_func_interface,
         during resolution of the function call.  */
      if (sym->attr.is_iso_c == 1
	  && (sym->from_intmod == INTMOD_ISO_C_BINDING
	      && (sym->intmod_sym_id == ISOCBINDING_LOC
		  || sym->intmod_sym_id == ISOCBINDING_FUNLOC
		  || sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)))
        {
          /* make sure we were given a param */
          if (actual_arglist == NULL)
            {
              gfc_error ("Missing argument to %qs at %C", sym->name);
              m = MATCH_ERROR;
              break;
            }
        }

      if (sym->result == NULL)
	sym->result = sym;

      gfc_gobble_whitespace ();
      /* F08:C612.  */
      if (gfc_peek_ascii_char() == '%')
	{
	  gfc_error ("The leftmost part-ref in a data-ref cannot be a "
		     "function reference at %C");
	  m = MATCH_ERROR;
	  break;
	}

      m = MATCH_YES;
      break;

    case FL_UNKNOWN:

      /* Special case for derived type variables that get their types
	 via an IMPLICIT statement.  This can't wait for the
	 resolution phase.  */

      old_loc = gfc_current_locus;
      if (gfc_match_member_sep (sym) == MATCH_YES
	  && sym->ts.type == BT_UNKNOWN
	  && gfc_get_default_type (sym->name, sym->ns)->type == BT_DERIVED)
	gfc_set_default_type (sym, 0, sym->ns);
      gfc_current_locus = old_loc;

      /* If the symbol has a (co)dimension attribute, the expression is a
	 variable.  */

      if (sym->attr.dimension || sym->attr.codimension)
	{
	  if (!gfc_add_flavor (&sym->attr, FL_VARIABLE, sym->name, NULL))
	    {
	      m = MATCH_ERROR;
	      break;
	    }

	  e = gfc_get_expr ();
	  e->symtree = symtree;
	  e->expr_type = EXPR_VARIABLE;
	  m = gfc_match_varspec (e, 0, false, true);
	  break;
	}

      if (sym->ts.type == BT_CLASS && sym->attr.class_ok
	  && (CLASS_DATA (sym)->attr.dimension
	      || CLASS_DATA (sym)->attr.codimension))
	{
	  if (!gfc_add_flavor (&sym->attr, FL_VARIABLE, sym->name, NULL))
	    {
	      m = MATCH_ERROR;
	      break;
	    }

	  e = gfc_get_expr ();
	  e->symtree = symtree;
	  e->expr_type = EXPR_VARIABLE;
	  m = gfc_match_varspec (e, 0, false, true);
	  break;
	}

      /* Name is not an array, so we peek to see if a '(' implies a
	 function call or a substring reference.  Otherwise the
	 variable is just a scalar.  */

      gfc_gobble_whitespace ();
      if (gfc_peek_ascii_char () != '(')
	{
	  /* Assume a scalar variable */
	  e = gfc_get_expr ();
	  e->symtree = symtree;
	  e->expr_type = EXPR_VARIABLE;

	  if (!gfc_add_flavor (&sym->attr, FL_VARIABLE, sym->name, NULL))
	    {
	      m = MATCH_ERROR;
	      break;
	    }

	  /*FIXME:??? gfc_match_varspec does set this for us: */
	  e->ts = sym->ts;
	  m = gfc_match_varspec (e, 0, false, true);
	  break;
	}

      /* See if this is a function reference with a keyword argument
	 as first argument. We do this because otherwise a spurious
	 symbol would end up in the symbol table.  */

      old_loc = gfc_current_locus;
      m2 = gfc_match (" ( %n =", argname);
      gfc_current_locus = old_loc;

      e = gfc_get_expr ();
      e->symtree = symtree;

      if (m2 != MATCH_YES)
	{
	  /* Try to figure out whether we're dealing with a character type.
	     We're peeking ahead here, because we don't want to call
	     match_substring if we're dealing with an implicitly typed
	     non-character variable.  */
	  implicit_char = false;
	  if (sym->ts.type == BT_UNKNOWN)
	    {
	      ts = gfc_get_default_type (sym->name, NULL);
	      if (ts->type == BT_CHARACTER)
		implicit_char = true;
	    }

	  /* See if this could possibly be a substring reference of a name
	     that we're not sure is a variable yet.  */

	  if ((implicit_char || sym->ts.type == BT_CHARACTER)
	      && match_substring (sym->ts.u.cl, 0, &e->ref, false) == MATCH_YES)
	    {

	      e->expr_type = EXPR_VARIABLE;

	      if (sym->attr.flavor != FL_VARIABLE
		  && !gfc_add_flavor (&sym->attr, FL_VARIABLE,
				      sym->name, NULL))
		{
		  m = MATCH_ERROR;
		  break;
		}

	      if (sym->ts.type == BT_UNKNOWN
		  && !gfc_set_default_type (sym, 1, NULL))
		{
		  m = MATCH_ERROR;
		  break;
		}

	      e->ts = sym->ts;
	      if (e->ref)
		e->ts.u.cl = NULL;
	      m = MATCH_YES;
	      break;
	    }
	}

      /* Give up, assume we have a function.  */

      gfc_get_sym_tree (name, NULL, &symtree, false);	/* Can't fail */
      sym = symtree->n.sym;
      e->expr_type = EXPR_FUNCTION;

      if (!sym->attr.function
	  && !gfc_add_function (&sym->attr, sym->name, NULL))
	{
	  m = MATCH_ERROR;
	  break;
	}

      sym->result = sym;

      m = gfc_match_actual_arglist (0, &e->value.function.actual);
      if (m == MATCH_NO)
	gfc_error ("Missing argument list in function %qs at %C", sym->name);

      if (m != MATCH_YES)
	{
	  m = MATCH_ERROR;
	  break;
	}

      /* If our new function returns a character, array or structure
	 type, it might have subsequent references.  */

      m = gfc_match_varspec (e, 0, false, true);
      if (m == MATCH_NO)
	m = MATCH_YES;

      break;

    generic_function:
      /* Look for symbol first; if not found, look for STRUCTURE type symbol
         specially. Creates a generic symbol for derived types.  */
      gfc_find_sym_tree (name, NULL, 1, &symtree);
      if (!symtree)
        gfc_find_sym_tree (gfc_dt_upper_string (name), NULL, 1, &symtree);
      if (!symtree || symtree->n.sym->attr.flavor != FL_STRUCT)
        gfc_get_sym_tree (name, NULL, &symtree, false); /* Can't fail */

      e = gfc_get_expr ();
      e->symtree = symtree;
      e->expr_type = EXPR_FUNCTION;

      if (gfc_fl_struct (sym->attr.flavor))
	{
	  e->value.function.esym = sym;
	  e->symtree->n.sym->attr.generic = 1;
	}

      m = gfc_match_actual_arglist (0, &e->value.function.actual);
      break;

    case FL_NAMELIST:
      m = MATCH_ERROR;
      break;

    default:
      gfc_error ("Symbol at %C is not appropriate for an expression");
      return MATCH_ERROR;
    }

  if (m == MATCH_YES)
    {
      e->where = where;
      *result = e;
    }
  else
    gfc_free_expr (e);

  return m;
}


/* Match a variable, i.e. something that can be assigned to.  This
   starts as a symbol, can be a structure component or an array
   reference.  It can be a function if the function doesn't have a
   separate RESULT variable.  If the symbol has not been previously
   seen, we assume it is a variable.

   This function is called by two interface functions:
   gfc_match_variable, which has host_flag = 1, and
   gfc_match_equiv_variable, with host_flag = 0, to restrict the
   match of the symbol to the local scope.  */

static match
match_variable (gfc_expr **result, int equiv_flag, int host_flag)
{
  gfc_symbol *sym, *dt_sym;
  gfc_symtree *st;
  gfc_expr *expr;
  locus where, old_loc;
  match m;

  /* Since nothing has any business being an lvalue in a module
     specification block, an interface block or a contains section,
     we force the changed_symbols mechanism to work by setting
     host_flag to 0. This prevents valid symbols that have the name
     of keywords, such as 'end', being turned into variables by
     failed matching to assignments for, e.g., END INTERFACE.  */
  if (gfc_current_state () == COMP_MODULE
      || gfc_current_state () == COMP_SUBMODULE
      || gfc_current_state () == COMP_INTERFACE
      || gfc_current_state () == COMP_CONTAINS)
    host_flag = 0;

  where = gfc_current_locus;
  m = gfc_match_sym_tree (&st, host_flag);
  if (m != MATCH_YES)
    return m;

  sym = st->n.sym;

  /* If this is an implicit do loop index and implicitly typed,
     it should not be host associated.  */
  m = check_for_implicit_index (&st, &sym);
  if (m != MATCH_YES)
    return m;

  sym->attr.implied_index = 0;

  gfc_set_sym_referenced (sym);

  /* STRUCTUREs may share names with variables, but derived types may not.  */
  if (sym->attr.flavor == FL_PROCEDURE && sym->generic
      && (dt_sym = gfc_find_dt_in_generic (sym)))
    {
      if (dt_sym->attr.flavor == FL_DERIVED)
        gfc_error ("Derived type %qs cannot be used as a variable at %C",
                   sym->name);
      return MATCH_ERROR;
    }

  switch (sym->attr.flavor)
    {
    case FL_VARIABLE:
      /* Everything is alright.  */
      break;

    case FL_UNKNOWN:
      {
	sym_flavor flavor = FL_UNKNOWN;

	gfc_gobble_whitespace ();

	if (sym->attr.external || sym->attr.procedure
	    || sym->attr.function || sym->attr.subroutine)
	  flavor = FL_PROCEDURE;

	/* If it is not a procedure, is not typed and is host associated,
	   we cannot give it a flavor yet.  */
	else if (sym->ns == gfc_current_ns->parent
		   && sym->ts.type == BT_UNKNOWN)
	  break;

	/* These are definitive indicators that this is a variable.  */
	else if (gfc_peek_ascii_char () != '(' || sym->ts.type != BT_UNKNOWN
		 || sym->attr.pointer || sym->as != NULL)
	  flavor = FL_VARIABLE;

	if (flavor != FL_UNKNOWN
	    && !gfc_add_flavor (&sym->attr, flavor, sym->name, NULL))
	  return MATCH_ERROR;
      }
      break;

    case FL_PARAMETER:
      if (equiv_flag)
	{
	  gfc_error ("Named constant at %C in an EQUIVALENCE");
	  return MATCH_ERROR;
	}
      /* Otherwise this is checked for and an error given in the
	 variable definition context checks.  */
      break;

    case FL_PROCEDURE:
      /* Check for a nonrecursive function result variable.  */
      if (sym->attr.function
	  && !sym->attr.external
	  && sym->result == sym
	  && (gfc_is_function_return_value (sym, gfc_current_ns)
	      || (sym->attr.entry
		  && sym->ns == gfc_current_ns)
	      || (sym->attr.entry
		  && sym->ns == gfc_current_ns->parent)))
	{
	  /* If a function result is a derived type, then the derived
	     type may still have to be resolved.  */

	  if (sym->ts.type == BT_DERIVED
	      && gfc_use_derived (sym->ts.u.derived) == NULL)
	    return MATCH_ERROR;
	  break;
	}

      if (sym->attr.proc_pointer
	  || replace_hidden_procptr_result (&sym, &st))
	break;

      /* Fall through to error */
      gcc_fallthrough ();

    default:
      gfc_error ("%qs at %C is not a variable", sym->name);
      return MATCH_ERROR;
    }

  /* Special case for derived type variables that get their types
     via an IMPLICIT statement.  This can't wait for the
     resolution phase.  */

    {
      gfc_namespace * implicit_ns;

      if (gfc_current_ns->proc_name == sym)
	implicit_ns = gfc_current_ns;
      else
	implicit_ns = sym->ns;

      old_loc = gfc_current_locus;
      if (gfc_match_member_sep (sym) == MATCH_YES
	  && sym->ts.type == BT_UNKNOWN
	  && gfc_get_default_type (sym->name, implicit_ns)->type == BT_DERIVED)
	gfc_set_default_type (sym, 0, implicit_ns);
      gfc_current_locus = old_loc;
    }

  expr = gfc_get_expr ();

  expr->expr_type = EXPR_VARIABLE;
  expr->symtree = st;
  expr->ts = sym->ts;
  expr->where = where;

  /* Now see if we have to do more.  */
  m = gfc_match_varspec (expr, equiv_flag, false, false);
  if (m != MATCH_YES)
    {
      gfc_free_expr (expr);
      return m;
    }

  *result = expr;
  return MATCH_YES;
}


match
gfc_match_variable (gfc_expr **result, int equiv_flag)
{
  return match_variable (result, equiv_flag, 1);
}


match
gfc_match_equiv_variable (gfc_expr **result)
{
  return match_variable (result, 1, 0);
}

