/* Primary expression subroutines
   Copyright (C) 2000-2021 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);
  if (m != MATCH_NO)
    return m;

  m = gfc_match_name (name);
  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 ('_') != 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 == ' ')
    {
      gfc_gobble_whitespace ();
      c = gfc_next_char ();
    }

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

  gfc_gobble_whitespace ();

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

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

	  case AR_ELEMENT:
	    /* Handle coarrays.  */
	    if (ref->u.ar.dimen > 0)
	      allocatable = pointer = 0;
	    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:
	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;
	    pointer = comp->attr.pointer;
	    allocatable = comp->attr.allocatable;
	  }
	if (pointer || attr.proc_pointer)
	  target = 1;

	break;

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

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

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

  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 ())
    gfc_reduce_init_expr (e);

  *result = e;
  return MATCH_YES;
}


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

