/* Perform type resolution on the various structures.
   Copyright (C) 2001-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 "bitmap.h"
#include "gfortran.h"
#include "arith.h"  /* For gfc_compare_expr().  */
#include "dependency.h"
#include "data.h"
#include "target-memory.h" /* for gfc_simplify_transfer */
#include "constructor.h"

/* Types used in equivalence statements.  */

enum seq_type
{
  SEQ_NONDEFAULT, SEQ_NUMERIC, SEQ_CHARACTER, SEQ_MIXED
};

/* Stack to keep track of the nesting of blocks as we move through the
   code.  See resolve_branch() and gfc_resolve_code().  */

typedef struct code_stack
{
  struct gfc_code *head, *current;
  struct code_stack *prev;

  /* This bitmap keeps track of the targets valid for a branch from
     inside this block except for END {IF|SELECT}s of enclosing
     blocks.  */
  bitmap reachable_labels;
}
code_stack;

static code_stack *cs_base = NULL;


/* Nonzero if we're inside a FORALL or DO CONCURRENT block.  */

static int forall_flag;
int gfc_do_concurrent_flag;

/* True when we are resolving an expression that is an actual argument to
   a procedure.  */
static bool actual_arg = false;
/* True when we are resolving an expression that is the first actual argument
   to a procedure.  */
static bool first_actual_arg = false;


/* Nonzero if we're inside a OpenMP WORKSHARE or PARALLEL WORKSHARE block.  */

static int omp_workshare_flag;

/* True if we are processing a formal arglist. The corresponding function
   resets the flag each time that it is read.  */
static bool formal_arg_flag = false;

/* True if we are resolving a specification expression.  */
static bool specification_expr = false;

/* The id of the last entry seen.  */
static int current_entry_id;

/* We use bitmaps to determine if a branch target is valid.  */
static bitmap_obstack labels_obstack;

/* True when simplifying a EXPR_VARIABLE argument to an inquiry function.  */
static bool inquiry_argument = false;


bool
gfc_is_formal_arg (void)
{
  return formal_arg_flag;
}

/* Is the symbol host associated?  */
static bool
is_sym_host_assoc (gfc_symbol *sym, gfc_namespace *ns)
{
  for (ns = ns->parent; ns; ns = ns->parent)
    {
      if (sym->ns == ns)
	return true;
    }

  return false;
}

/* Ensure a typespec used is valid; for instance, TYPE(t) is invalid if t is
   an ABSTRACT derived-type.  If where is not NULL, an error message with that
   locus is printed, optionally using name.  */

static bool
resolve_typespec_used (gfc_typespec* ts, locus* where, const char* name)
{
  if (ts->type == BT_DERIVED && ts->u.derived->attr.abstract)
    {
      if (where)
	{
	  if (name)
	    gfc_error ("%qs at %L is of the ABSTRACT type %qs",
		       name, where, ts->u.derived->name);
	  else
	    gfc_error ("ABSTRACT type %qs used at %L",
		       ts->u.derived->name, where);
	}

      return false;
    }

  return true;
}


static bool
check_proc_interface (gfc_symbol *ifc, locus *where)
{
  /* Several checks for F08:C1216.  */
  if (ifc->attr.procedure)
    {
      gfc_error ("Interface %qs at %L is declared "
		 "in a later PROCEDURE statement", ifc->name, where);
      return false;
    }
  if (ifc->generic)
    {
      /* For generic interfaces, check if there is
	 a specific procedure with the same name.  */
      gfc_interface *gen = ifc->generic;
      while (gen && strcmp (gen->sym->name, ifc->name) != 0)
	gen = gen->next;
      if (!gen)
	{
	  gfc_error ("Interface %qs at %L may not be generic",
		     ifc->name, where);
	  return false;
	}
    }
  if (ifc->attr.proc == PROC_ST_FUNCTION)
    {
      gfc_error ("Interface %qs at %L may not be a statement function",
		 ifc->name, where);
      return false;
    }
  if (gfc_is_intrinsic (ifc, 0, ifc->declared_at)
      || gfc_is_intrinsic (ifc, 1, ifc->declared_at))
    ifc->attr.intrinsic = 1;
  if (ifc->attr.intrinsic && !gfc_intrinsic_actual_ok (ifc->name, 0))
    {
      gfc_error ("Intrinsic procedure %qs not allowed in "
		 "PROCEDURE statement at %L", ifc->name, where);
      return false;
    }
  if (!ifc->attr.if_source && !ifc->attr.intrinsic && ifc->name[0] != '\0')
    {
      gfc_error ("Interface %qs at %L must be explicit", ifc->name, where);
      return false;
    }
  return true;
}


static void resolve_symbol (gfc_symbol *sym);


/* Resolve the interface for a PROCEDURE declaration or procedure pointer.  */

static bool
resolve_procedure_interface (gfc_symbol *sym)
{
  gfc_symbol *ifc = sym->ts.interface;

  if (!ifc)
    return true;

  if (ifc == sym)
    {
      gfc_error ("PROCEDURE %qs at %L may not be used as its own interface",
		 sym->name, &sym->declared_at);
      return false;
    }
  if (!check_proc_interface (ifc, &sym->declared_at))
    return false;

  if (ifc->attr.if_source || ifc->attr.intrinsic)
    {
      /* Resolve interface and copy attributes.  */
      resolve_symbol (ifc);
      if (ifc->attr.intrinsic)
	gfc_resolve_intrinsic (ifc, &ifc->declared_at);

      if (ifc->result)
	{
	  sym->ts = ifc->result->ts;
	  sym->attr.allocatable = ifc->result->attr.allocatable;
	  sym->attr.pointer = ifc->result->attr.pointer;
	  sym->attr.dimension = ifc->result->attr.dimension;
	  sym->attr.class_ok = ifc->result->attr.class_ok;
	  sym->as = gfc_copy_array_spec (ifc->result->as);
	  sym->result = sym;
	}
      else
	{
	  sym->ts = ifc->ts;
	  sym->attr.allocatable = ifc->attr.allocatable;
	  sym->attr.pointer = ifc->attr.pointer;
	  sym->attr.dimension = ifc->attr.dimension;
	  sym->attr.class_ok = ifc->attr.class_ok;
	  sym->as = gfc_copy_array_spec (ifc->as);
	}
      sym->ts.interface = ifc;
      sym->attr.function = ifc->attr.function;
      sym->attr.subroutine = ifc->attr.subroutine;

      sym->attr.pure = ifc->attr.pure;
      sym->attr.elemental = ifc->attr.elemental;
      sym->attr.contiguous = ifc->attr.contiguous;
      sym->attr.recursive = ifc->attr.recursive;
      sym->attr.always_explicit = ifc->attr.always_explicit;
      sym->attr.ext_attr |= ifc->attr.ext_attr;
      sym->attr.is_bind_c = ifc->attr.is_bind_c;
      /* Copy char length.  */
      if (ifc->ts.type == BT_CHARACTER && ifc->ts.u.cl)
	{
	  sym->ts.u.cl = gfc_new_charlen (sym->ns, ifc->ts.u.cl);
	  if (sym->ts.u.cl->length && !sym->ts.u.cl->resolved
	      && !gfc_resolve_expr (sym->ts.u.cl->length))
	    return false;
	}
    }

  return true;
}


/* Resolve types of formal argument lists.  These have to be done early so that
   the formal argument lists of module procedures can be copied to the
   containing module before the individual procedures are resolved
   individually.  We also resolve argument lists of procedures in interface
   blocks because they are self-contained scoping units.

   Since a dummy argument cannot be a non-dummy procedure, the only
   resort left for untyped names are the IMPLICIT types.  */

void
gfc_resolve_formal_arglist (gfc_symbol *proc)
{
  gfc_formal_arglist *f;
  gfc_symbol *sym;
  bool saved_specification_expr;
  int i;

  if (proc->result != NULL)
    sym = proc->result;
  else
    sym = proc;

  if (gfc_elemental (proc)
      || sym->attr.pointer || sym->attr.allocatable
      || (sym->as && sym->as->rank != 0))
    {
      proc->attr.always_explicit = 1;
      sym->attr.always_explicit = 1;
    }

  formal_arg_flag = true;

  for (f = proc->formal; f; f = f->next)
    {
      gfc_array_spec *as;

      sym = f->sym;

      if (sym == NULL)
	{
	  /* Alternate return placeholder.  */
	  if (gfc_elemental (proc))
	    gfc_error ("Alternate return specifier in elemental subroutine "
		       "%qs at %L is not allowed", proc->name,
		       &proc->declared_at);
	  if (proc->attr.function)
	    gfc_error ("Alternate return specifier in function "
		       "%qs at %L is not allowed", proc->name,
		       &proc->declared_at);
	  continue;
	}
      else if (sym->attr.procedure && sym->attr.if_source != IFSRC_DECL
	       && !resolve_procedure_interface (sym))
	return;

      if (strcmp (proc->name, sym->name) == 0)
        {
          gfc_error ("Self-referential argument "
                     "%qs at %L is not allowed", sym->name,
                     &proc->declared_at);
          return;
        }

      if (sym->attr.if_source != IFSRC_UNKNOWN)
	gfc_resolve_formal_arglist (sym);

      if (sym->attr.subroutine || sym->attr.external)
	{
	  if (sym->attr.flavor == FL_UNKNOWN)
	    gfc_add_flavor (&sym->attr, FL_PROCEDURE, sym->name, &sym->declared_at);
	}
      else
	{
	  if (sym->ts.type == BT_UNKNOWN && !proc->attr.intrinsic
	      && (!sym->attr.function || sym->result == sym))
	    gfc_set_default_type (sym, 1, sym->ns);
	}

      as = sym->ts.type == BT_CLASS && sym->attr.class_ok
	   ? CLASS_DATA (sym)->as : sym->as;

      saved_specification_expr = specification_expr;
      specification_expr = true;
      gfc_resolve_array_spec (as, 0);
      specification_expr = saved_specification_expr;

      /* We can't tell if an array with dimension (:) is assumed or deferred
	 shape until we know if it has the pointer or allocatable attributes.
      */
      if (as && as->rank > 0 && as->type == AS_DEFERRED
	  && ((sym->ts.type != BT_CLASS
	       && !(sym->attr.pointer || sym->attr.allocatable))
              || (sym->ts.type == BT_CLASS
		  && !(CLASS_DATA (sym)->attr.class_pointer
		       || CLASS_DATA (sym)->attr.allocatable)))
	  && sym->attr.flavor != FL_PROCEDURE)
	{
	  as->type = AS_ASSUMED_SHAPE;
	  for (i = 0; i < as->rank; i++)
	    as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
	}

      if ((as && as->rank > 0 && as->type == AS_ASSUMED_SHAPE)
	  || (as && as->type == AS_ASSUMED_RANK)
	  || sym->attr.pointer || sym->attr.allocatable || sym->attr.target
	  || (sym->ts.type == BT_CLASS && sym->attr.class_ok
	      && (CLASS_DATA (sym)->attr.class_pointer
		  || CLASS_DATA (sym)->attr.allocatable
		  || CLASS_DATA (sym)->attr.target))
	  || sym->attr.optional)
	{
	  proc->attr.always_explicit = 1;
	  if (proc->result)
	    proc->result->attr.always_explicit = 1;
	}

      /* If the flavor is unknown at this point, it has to be a variable.
	 A procedure specification would have already set the type.  */

      if (sym->attr.flavor == FL_UNKNOWN)
	gfc_add_flavor (&sym->attr, FL_VARIABLE, sym->name, &sym->declared_at);

      if (gfc_pure (proc))
	{
	  if (sym->attr.flavor == FL_PROCEDURE)
	    {
	      /* F08:C1279.  */
	      if (!gfc_pure (sym))
		{
		  gfc_error ("Dummy procedure %qs of PURE procedure at %L must "
			    "also be PURE", sym->name, &sym->declared_at);
		  continue;
		}
	    }
	  else if (!sym->attr.pointer)
	    {
	      if (proc->attr.function && sym->attr.intent != INTENT_IN)
		{
		  if (sym->attr.value)
		    gfc_notify_std (GFC_STD_F2008, "Argument %qs"
				    " of pure function %qs at %L with VALUE "
				    "attribute but without INTENT(IN)",
				    sym->name, proc->name, &sym->declared_at);
		  else
		    gfc_error ("Argument %qs of pure function %qs at %L must "
			       "be INTENT(IN) or VALUE", sym->name, proc->name,
			       &sym->declared_at);
		}

	      if (proc->attr.subroutine && sym->attr.intent == INTENT_UNKNOWN)
		{
		  if (sym->attr.value)
		    gfc_notify_std (GFC_STD_F2008, "Argument %qs"
				    " of pure subroutine %qs at %L with VALUE "
				    "attribute but without INTENT", sym->name,
				    proc->name, &sym->declared_at);
		  else
		    gfc_error ("Argument %qs of pure subroutine %qs at %L "
			       "must have its INTENT specified or have the "
			       "VALUE attribute", sym->name, proc->name,
			       &sym->declared_at);
		}
	    }

	  /* F08:C1278a.  */
	  if (sym->ts.type == BT_CLASS && sym->attr.intent == INTENT_OUT)
	    {
	      gfc_error ("INTENT(OUT) argument %qs of pure procedure %qs at %L"
			 " may not be polymorphic", sym->name, proc->name,
			 &sym->declared_at);
	      continue;
	    }
	}

      if (proc->attr.implicit_pure)
	{
	  if (sym->attr.flavor == FL_PROCEDURE)
	    {
	      if (!gfc_pure (sym))
		proc->attr.implicit_pure = 0;
	    }
	  else if (!sym->attr.pointer)
	    {
	      if (proc->attr.function && sym->attr.intent != INTENT_IN
		  && !sym->value)
		proc->attr.implicit_pure = 0;

	      if (proc->attr.subroutine && sym->attr.intent == INTENT_UNKNOWN
		  && !sym->value)
		proc->attr.implicit_pure = 0;
	    }
	}

      if (gfc_elemental (proc))
	{
	  /* F08:C1289.  */
	  if (sym->attr.codimension
	      || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
		  && CLASS_DATA (sym)->attr.codimension))
	    {
	      gfc_error ("Coarray dummy argument %qs at %L to elemental "
			 "procedure", sym->name, &sym->declared_at);
	      continue;
	    }

	  if (sym->as || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
			  && CLASS_DATA (sym)->as))
	    {
	      gfc_error ("Argument %qs of elemental procedure at %L must "
			 "be scalar", sym->name, &sym->declared_at);
	      continue;
	    }

	  if (sym->attr.allocatable
	      || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
		  && CLASS_DATA (sym)->attr.allocatable))
	    {
	      gfc_error ("Argument %qs of elemental procedure at %L cannot "
			 "have the ALLOCATABLE attribute", sym->name,
			 &sym->declared_at);
	      continue;
	    }

	  if (sym->attr.pointer
	      || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
		  && CLASS_DATA (sym)->attr.class_pointer))
	    {
	      gfc_error ("Argument %qs of elemental procedure at %L cannot "
			 "have the POINTER attribute", sym->name,
			 &sym->declared_at);
	      continue;
	    }

	  if (sym->attr.flavor == FL_PROCEDURE)
	    {
	      gfc_error ("Dummy procedure %qs not allowed in elemental "
			 "procedure %qs at %L", sym->name, proc->name,
			 &sym->declared_at);
	      continue;
	    }

	  /* Fortran 2008 Corrigendum 1, C1290a.  */
	  if (sym->attr.intent == INTENT_UNKNOWN && !sym->attr.value)
	    {
	      gfc_error ("Argument %qs of elemental procedure %qs at %L must "
			 "have its INTENT specified or have the VALUE "
			 "attribute", sym->name, proc->name,
			 &sym->declared_at);
	      continue;
	    }
	}

      /* Each dummy shall be specified to be scalar.  */
      if (proc->attr.proc == PROC_ST_FUNCTION)
	{
	  if (sym->as != NULL)
	    {
	      /* F03:C1263 (R1238) The function-name and each dummy-arg-name
		 shall be specified, explicitly or implicitly, to be scalar.  */
	      gfc_error ("Argument '%s' of statement function '%s' at %L "
			 "must be scalar", sym->name, proc->name,
			 &proc->declared_at);
	      continue;
	    }

	  if (sym->ts.type == BT_CHARACTER)
	    {
	      gfc_charlen *cl = sym->ts.u.cl;
	      if (!cl || !cl->length || cl->length->expr_type != EXPR_CONSTANT)
		{
		  gfc_error ("Character-valued argument %qs of statement "
			     "function at %L must have constant length",
			     sym->name, &sym->declared_at);
		  continue;
		}
	    }
	}
    }
  formal_arg_flag = false;
}


/* Work function called when searching for symbols that have argument lists
   associated with them.  */

static void
find_arglists (gfc_symbol *sym)
{
  if (sym->attr.if_source == IFSRC_UNKNOWN || sym->ns != gfc_current_ns
      || gfc_fl_struct (sym->attr.flavor) || sym->attr.intrinsic)
    return;

  gfc_resolve_formal_arglist (sym);
}


/* Given a namespace, resolve all formal argument lists within the namespace.
 */

static void
resolve_formal_arglists (gfc_namespace *ns)
{
  if (ns == NULL)
    return;

  gfc_traverse_ns (ns, find_arglists);
}


static void
resolve_contained_fntype (gfc_symbol *sym, gfc_namespace *ns)
{
  bool t;

  if (sym && sym->attr.flavor == FL_PROCEDURE
      && sym->ns->parent
      && sym->ns->parent->proc_name
      && sym->ns->parent->proc_name->attr.flavor == FL_PROCEDURE
      && !strcmp (sym->name, sym->ns->parent->proc_name->name))
    gfc_error ("Contained procedure %qs at %L has the same name as its "
	       "encompassing procedure", sym->name, &sym->declared_at);

  /* If this namespace is not a function or an entry master function,
     ignore it.  */
  if (! sym || !(sym->attr.function || sym->attr.flavor == FL_VARIABLE)
      || sym->attr.entry_master)
    return;

  if (!sym->result)
    return;

  /* Try to find out of what the return type is.  */
  if (sym->result->ts.type == BT_UNKNOWN && sym->result->ts.interface == NULL)
    {
      t = gfc_set_default_type (sym->result, 0, ns);

      if (!t && !sym->result->attr.untyped)
	{
	  if (sym->result == sym)
	    gfc_error ("Contained function %qs at %L has no IMPLICIT type",
		       sym->name, &sym->declared_at);
	  else if (!sym->result->attr.proc_pointer)
	    gfc_error ("Result %qs of contained function %qs at %L has "
		       "no IMPLICIT type", sym->result->name, sym->name,
		       &sym->result->declared_at);
	  sym->result->attr.untyped = 1;
	}
    }

  /* Fortran 2008 Draft Standard, page 535, C418, on type-param-value
     type, lists the only ways a character length value of * can be used:
     dummy arguments of procedures, named constants, function results and
     in allocate statements if the allocate_object is an assumed length dummy
     in external functions.  Internal function results and results of module
     procedures are not on this list, ergo, not permitted.  */

  if (sym->result->ts.type == BT_CHARACTER)
    {
      gfc_charlen *cl = sym->result->ts.u.cl;
      if ((!cl || !cl->length) && !sym->result->ts.deferred)
	{
	  /* See if this is a module-procedure and adapt error message
	     accordingly.  */
	  bool module_proc;
	  gcc_assert (ns->parent && ns->parent->proc_name);
	  module_proc = (ns->parent->proc_name->attr.flavor == FL_MODULE);

	  gfc_error (module_proc
		     ? G_("Character-valued module procedure %qs at %L"
			  " must not be assumed length")
		     : G_("Character-valued internal function %qs at %L"
			  " must not be assumed length"),
		     sym->name, &sym->declared_at);
	}
    }
}


/* Add NEW_ARGS to the formal argument list of PROC, taking care not to
   introduce duplicates.  */

static void
merge_argument_lists (gfc_symbol *proc, gfc_formal_arglist *new_args)
{
  gfc_formal_arglist *f, *new_arglist;
  gfc_symbol *new_sym;

  for (; new_args != NULL; new_args = new_args->next)
    {
      new_sym = new_args->sym;
      /* See if this arg is already in the formal argument list.  */
      for (f = proc->formal; f; f = f->next)
	{
	  if (new_sym == f->sym)
	    break;
	}

      if (f)
	continue;

      /* Add a new argument.  Argument order is not important.  */
      new_arglist = gfc_get_formal_arglist ();
      new_arglist->sym = new_sym;
      new_arglist->next = proc->formal;
      proc->formal  = new_arglist;
    }
}


/* Flag the arguments that are not present in all entries.  */

static void
check_argument_lists (gfc_symbol *proc, gfc_formal_arglist *new_args)
{
  gfc_formal_arglist *f, *head;
  head = new_args;

  for (f = proc->formal; f; f = f->next)
    {
      if (f->sym == NULL)
	continue;

      for (new_args = head; new_args; new_args = new_args->next)
	{
	  if (new_args->sym == f->sym)
	    break;
	}

      if (new_args)
	continue;

      f->sym->attr.not_always_present = 1;
    }
}


/* Resolve alternate entry points.  If a symbol has multiple entry points we
   create a new master symbol for the main routine, and turn the existing
   symbol into an entry point.  */

static void
resolve_entries (gfc_namespace *ns)
{
  gfc_namespace *old_ns;
  gfc_code *c;
  gfc_symbol *proc;
  gfc_entry_list *el;
  char name[GFC_MAX_SYMBOL_LEN + 1];
  static int master_count = 0;

  if (ns->proc_name == NULL)
    return;

  /* No need to do anything if this procedure doesn't have alternate entry
     points.  */
  if (!ns->entries)
    return;

  /* We may already have resolved alternate entry points.  */
  if (ns->proc_name->attr.entry_master)
    return;

  /* If this isn't a procedure something has gone horribly wrong.  */
  gcc_assert (ns->proc_name->attr.flavor == FL_PROCEDURE);

  /* Remember the current namespace.  */
  old_ns = gfc_current_ns;

  gfc_current_ns = ns;

  /* Add the main entry point to the list of entry points.  */
  el = gfc_get_entry_list ();
  el->sym = ns->proc_name;
  el->id = 0;
  el->next = ns->entries;
  ns->entries = el;
  ns->proc_name->attr.entry = 1;

  /* If it is a module function, it needs to be in the right namespace
     so that gfc_get_fake_result_decl can gather up the results. The
     need for this arose in get_proc_name, where these beasts were
     left in their own namespace, to keep prior references linked to
     the entry declaration.*/
  if (ns->proc_name->attr.function
      && ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE)
    el->sym->ns = ns;

  /* Do the same for entries where the master is not a module
     procedure.  These are retained in the module namespace because
     of the module procedure declaration.  */
  for (el = el->next; el; el = el->next)
    if (el->sym->ns->proc_name->attr.flavor == FL_MODULE
	  && el->sym->attr.mod_proc)
      el->sym->ns = ns;
  el = ns->entries;

  /* Add an entry statement for it.  */
  c = gfc_get_code (EXEC_ENTRY);
  c->ext.entry = el;
  c->next = ns->code;
  ns->code = c;

  /* Create a new symbol for the master function.  */
  /* Give the internal function a unique name (within this file).
     Also include the function name so the user has some hope of figuring
     out what is going on.  */
  snprintf (name, GFC_MAX_SYMBOL_LEN, "master.%d.%s",
	    master_count++, ns->proc_name->name);
  gfc_get_ha_symbol (name, &proc);
  gcc_assert (proc != NULL);

  gfc_add_procedure (&proc->attr, PROC_INTERNAL, proc->name, NULL);
  if (ns->proc_name->attr.subroutine)
    gfc_add_subroutine (&proc->attr, proc->name, NULL);
  else
    {
      gfc_symbol *sym;
      gfc_typespec *ts, *fts;
      gfc_array_spec *as, *fas;
      gfc_add_function (&proc->attr, proc->name, NULL);
      proc->result = proc;
      fas = ns->entries->sym->as;
      fas = fas ? fas : ns->entries->sym->result->as;
      fts = &ns->entries->sym->result->ts;
      if (fts->type == BT_UNKNOWN)
	fts = gfc_get_default_type (ns->entries->sym->result->name, NULL);
      for (el = ns->entries->next; el; el = el->next)
	{
	  ts = &el->sym->result->ts;
	  as = el->sym->as;
	  as = as ? as : el->sym->result->as;
	  if (ts->type == BT_UNKNOWN)
	    ts = gfc_get_default_type (el->sym->result->name, NULL);

	  if (! gfc_compare_types (ts, fts)
	      || (el->sym->result->attr.dimension
		  != ns->entries->sym->result->attr.dimension)
	      || (el->sym->result->attr.pointer
		  != ns->entries->sym->result->attr.pointer))
	    break;
	  else if (as && fas && ns->entries->sym->result != el->sym->result
		      && gfc_compare_array_spec (as, fas) == 0)
	    gfc_error ("Function %s at %L has entries with mismatched "
		       "array specifications", ns->entries->sym->name,
		       &ns->entries->sym->declared_at);
	  /* The characteristics need to match and thus both need to have
	     the same string length, i.e. both len=*, or both len=4.
	     Having both len=<variable> is also possible, but difficult to
	     check at compile time.  */
	  else if (ts->type == BT_CHARACTER
		   && (el->sym->result->attr.allocatable
		       != ns->entries->sym->result->attr.allocatable))
	    {
	      gfc_error ("Function %s at %L has entry %s with mismatched "
			 "characteristics", ns->entries->sym->name,
			 &ns->entries->sym->declared_at, el->sym->name);
	      goto cleanup;
	    }
	  else if (ts->type == BT_CHARACTER && ts->u.cl && fts->u.cl
		   && (((ts->u.cl->length && !fts->u.cl->length)
			||(!ts->u.cl->length && fts->u.cl->length))
		       || (ts->u.cl->length
			   && ts->u.cl->length->expr_type
			      != fts->u.cl->length->expr_type)
		       || (ts->u.cl->length
			   && ts->u.cl->length->expr_type == EXPR_CONSTANT
		           && mpz_cmp (ts->u.cl->length->value.integer,
				       fts->u.cl->length->value.integer) != 0)))
	    gfc_notify_std (GFC_STD_GNU, "Function %s at %L with "
			    "entries returning variables of different "
			    "string lengths", ns->entries->sym->name,
			    &ns->entries->sym->declared_at);
	}

      if (el == NULL)
	{
	  sym = ns->entries->sym->result;
	  /* All result types the same.  */
	  proc->ts = *fts;
	  if (sym->attr.dimension)
	    gfc_set_array_spec (proc, gfc_copy_array_spec (sym->as), NULL);
	  if (sym->attr.pointer)
	    gfc_add_pointer (&proc->attr, NULL);
	}
      else
	{
	  /* Otherwise the result will be passed through a union by
	     reference.  */
	  proc->attr.mixed_entry_master = 1;
	  for (el = ns->entries; el; el = el->next)
	    {
	      sym = el->sym->result;
	      if (sym->attr.dimension)
		{
		  if (el == ns->entries)
		    gfc_error ("FUNCTION result %s cannot be an array in "
			       "FUNCTION %s at %L", sym->name,
			       ns->entries->sym->name, &sym->declared_at);
		  else
		    gfc_error ("ENTRY result %s cannot be an array in "
			       "FUNCTION %s at %L", sym->name,
			       ns->entries->sym->name, &sym->declared_at);
		}
	      else if (sym->attr.pointer)
		{
		  if (el == ns->entries)
		    gfc_error ("FUNCTION result %s cannot be a POINTER in "
			       "FUNCTION %s at %L", sym->name,
			       ns->entries->sym->name, &sym->declared_at);
		  else
		    gfc_error ("ENTRY result %s cannot be a POINTER in "
			       "FUNCTION %s at %L", sym->name,
			       ns->entries->sym->name, &sym->declared_at);
		}
	      else
		{
		  ts = &sym->ts;
		  if (ts->type == BT_UNKNOWN)
		    ts = gfc_get_default_type (sym->name, NULL);
		  switch (ts->type)
		    {
		    case BT_INTEGER:
		      if (ts->kind == gfc_default_integer_kind)
			sym = NULL;
		      break;
		    case BT_REAL:
		      if (ts->kind == gfc_default_real_kind
			  || ts->kind == gfc_default_double_kind)
			sym = NULL;
		      break;
		    case BT_COMPLEX:
		      if (ts->kind == gfc_default_complex_kind)
			sym = NULL;
		      break;
		    case BT_LOGICAL:
		      if (ts->kind == gfc_default_logical_kind)
			sym = NULL;
		      break;
		    case BT_UNKNOWN:
		      /* We will issue error elsewhere.  */
		      sym = NULL;
		      break;
		    default:
		      break;
		    }
		  if (sym)
		    {
		      if (el == ns->entries)
			gfc_error ("FUNCTION result %s cannot be of type %s "
				   "in FUNCTION %s at %L", sym->name,
				   gfc_typename (ts), ns->entries->sym->name,
				   &sym->declared_at);
		      else
			gfc_error ("ENTRY result %s cannot be of type %s "
				   "in FUNCTION %s at %L", sym->name,
				   gfc_typename (ts), ns->entries->sym->name,
				   &sym->declared_at);
		    }
		}
	    }
	}
    }

cleanup:
  proc->attr.access = ACCESS_PRIVATE;
  proc->attr.entry_master = 1;

  /* Merge all the entry point arguments.  */
  for (el = ns->entries; el; el = el->next)
    merge_argument_lists (proc, el->sym->formal);

  /* Check the master formal arguments for any that are not
     present in all entry points.  */
  for (el = ns->entries; el; el = el->next)
    check_argument_lists (proc, el->sym->formal);

  /* Use the master function for the function body.  */
  ns->proc_name = proc;

  /* Finalize the new symbols.  */
  gfc_commit_symbols ();

  /* Restore the original namespace.  */
  gfc_current_ns = old_ns;
}


/* Resolve common variables.  */
static void
resolve_common_vars (gfc_common_head *common_block, bool named_common)
{
  gfc_symbol *csym = common_block->head;
  gfc_gsymbol *gsym;

  for (; csym; csym = csym->common_next)
    {
      gsym = gfc_find_gsymbol (gfc_gsym_root, csym->name);
      if (gsym && (gsym->type == GSYM_MODULE || gsym->type == GSYM_PROGRAM))
	gfc_error_now ("Global entity %qs at %L cannot appear in a "
			"COMMON block at %L", gsym->name,
			&gsym->where, &csym->common_block->where);

      /* gfc_add_in_common may have been called before, but the reported errors
	 have been ignored to continue parsing.
	 We do the checks again here.  */
      if (!csym->attr.use_assoc)
	{
	  gfc_add_in_common (&csym->attr, csym->name, &common_block->where);
	  gfc_notify_std (GFC_STD_F2018_OBS, "COMMON block at %L",
			  &common_block->where);
	}

      if (csym->value || csym->attr.data)
	{
	  if (!csym->ns->is_block_data)
	    gfc_notify_std (GFC_STD_GNU, "Variable %qs at %L is in COMMON "
			    "but only in BLOCK DATA initialization is "
			    "allowed", csym->name, &csym->declared_at);
	  else if (!named_common)
	    gfc_notify_std (GFC_STD_GNU, "Initialized variable %qs at %L is "
			    "in a blank COMMON but initialization is only "
			    "allowed in named common blocks", csym->name,
			    &csym->declared_at);
	}

      if (UNLIMITED_POLY (csym))
	gfc_error_now ("%qs at %L cannot appear in COMMON "
		       "[F2008:C5100]", csym->name, &csym->declared_at);

      if (csym->ts.type != BT_DERIVED)
	continue;

      if (!(csym->ts.u.derived->attr.sequence
	    || csym->ts.u.derived->attr.is_bind_c))
	gfc_error_now ("Derived type variable %qs in COMMON at %L "
		       "has neither the SEQUENCE nor the BIND(C) "
		       "attribute", csym->name, &csym->declared_at);
      if (csym->ts.u.derived->attr.alloc_comp)
	gfc_error_now ("Derived type variable %qs in COMMON at %L "
		       "has an ultimate component that is "
		       "allocatable", csym->name, &csym->declared_at);
      if (gfc_has_default_initializer (csym->ts.u.derived))
	gfc_error_now ("Derived type variable %qs in COMMON at %L "
		       "may not have default initializer", csym->name,
		       &csym->declared_at);

      if (csym->attr.flavor == FL_UNKNOWN && !csym->attr.proc_pointer)
	gfc_add_flavor (&csym->attr, FL_VARIABLE, csym->name, &csym->declared_at);
    }
}

/* Resolve common blocks.  */
static void
resolve_common_blocks (gfc_symtree *common_root)
{
  gfc_symbol *sym;
  gfc_gsymbol * gsym;

  if (common_root == NULL)
    return;

  if (common_root->left)
    resolve_common_blocks (common_root->left);
  if (common_root->right)
    resolve_common_blocks (common_root->right);

  resolve_common_vars (common_root->n.common, true);

  /* The common name is a global name - in Fortran 2003 also if it has a
     C binding name, since Fortran 2008 only the C binding name is a global
     identifier.  */
  if (!common_root->n.common->binding_label
      || gfc_notification_std (GFC_STD_F2008))
    {
      gsym = gfc_find_gsymbol (gfc_gsym_root,
			       common_root->n.common->name);

      if (gsym && gfc_notification_std (GFC_STD_F2008)
	  && gsym->type == GSYM_COMMON
	  && ((common_root->n.common->binding_label
	       && (!gsym->binding_label
		   || strcmp (common_root->n.common->binding_label,
			      gsym->binding_label) != 0))
	      || (!common_root->n.common->binding_label
		  && gsym->binding_label)))
	{
	  gfc_error ("In Fortran 2003 COMMON %qs block at %L is a global "
		     "identifier and must thus have the same binding name "
		     "as the same-named COMMON block at %L: %s vs %s",
		     common_root->n.common->name, &common_root->n.common->where,
		     &gsym->where,
		     common_root->n.common->binding_label
		     ? common_root->n.common->binding_label : "(blank)",
		     gsym->binding_label ? gsym->binding_label : "(blank)");
	  return;
	}

      if (gsym && gsym->type != GSYM_COMMON
	  && !common_root->n.common->binding_label)
	{
	  gfc_error ("COMMON block %qs at %L uses the same global identifier "
		     "as entity at %L",
		     common_root->n.common->name, &common_root->n.common->where,
		     &gsym->where);
	  return;
	}
      if (gsym && gsym->type != GSYM_COMMON)
	{
	  gfc_error ("Fortran 2008: COMMON block %qs with binding label at "
		     "%L sharing the identifier with global non-COMMON-block "
		     "entity at %L", common_root->n.common->name,
		     &common_root->n.common->where, &gsym->where);
	  return;
	}
      if (!gsym)
	{
	  gsym = gfc_get_gsymbol (common_root->n.common->name, false);
	  gsym->type = GSYM_COMMON;
	  gsym->where = common_root->n.common->where;
	  gsym->defined = 1;
	}
      gsym->used = 1;
    }

  if (common_root->n.common->binding_label)
    {
      gsym = gfc_find_gsymbol (gfc_gsym_root,
			       common_root->n.common->binding_label);
      if (gsym && gsym->type != GSYM_COMMON)
	{
	  gfc_error ("COMMON block at %L with binding label %qs uses the same "
		     "global identifier as entity at %L",
		     &common_root->n.common->where,
		     common_root->n.common->binding_label, &gsym->where);
	  return;
	}
      if (!gsym)
	{
	  gsym = gfc_get_gsymbol (common_root->n.common->binding_label, true);
	  gsym->type = GSYM_COMMON;
	  gsym->where = common_root->n.common->where;
	  gsym->defined = 1;
	}
      gsym->used = 1;
    }

  gfc_find_symbol (common_root->name, gfc_current_ns, 0, &sym);
  if (sym == NULL)
    return;

  if (sym->attr.flavor == FL_PARAMETER)
    gfc_error ("COMMON block %qs at %L is used as PARAMETER at %L",
	       sym->name, &common_root->n.common->where, &sym->declared_at);

  if (sym->attr.external)
    gfc_error ("COMMON block %qs at %L cannot have the EXTERNAL attribute",
	       sym->name, &common_root->n.common->where);

  if (sym->attr.intrinsic)
    gfc_error ("COMMON block %qs at %L is also an intrinsic procedure",
	       sym->name, &common_root->n.common->where);
  else if (sym->attr.result
	   || gfc_is_function_return_value (sym, gfc_current_ns))
    gfc_notify_std (GFC_STD_F2003, "COMMON block %qs at %L "
		    "that is also a function result", sym->name,
		    &common_root->n.common->where);
  else if (sym->attr.flavor == FL_PROCEDURE && sym->attr.proc != PROC_INTERNAL
	   && sym->attr.proc != PROC_ST_FUNCTION)
    gfc_notify_std (GFC_STD_F2003, "COMMON block %qs at %L "
		    "that is also a global procedure", sym->name,
		    &common_root->n.common->where);
}


/* Resolve contained function types.  Because contained functions can call one
   another, they have to be worked out before any of the contained procedures
   can be resolved.

   The good news is that if a function doesn't already have a type, the only
   way it can get one is through an IMPLICIT type or a RESULT variable, because
   by definition contained functions are contained namespace they're contained
   in, not in a sibling or parent namespace.  */

static void
resolve_contained_functions (gfc_namespace *ns)
{
  gfc_namespace *child;
  gfc_entry_list *el;

  resolve_formal_arglists (ns);

  for (child = ns->contained; child; child = child->sibling)
    {
      /* Resolve alternate entry points first.  */
      resolve_entries (child);

      /* Then check function return types.  */
      resolve_contained_fntype (child->proc_name, child);
      for (el = child->entries; el; el = el->next)
	resolve_contained_fntype (el->sym, child);
    }
}



/* A Parameterized Derived Type constructor must contain values for
   the PDT KIND parameters or they must have a default initializer.
   Go through the constructor picking out the KIND expressions,
   storing them in 'param_list' and then call gfc_get_pdt_instance
   to obtain the PDT instance.  */

static gfc_actual_arglist *param_list, *param_tail, *param;

static bool
get_pdt_spec_expr (gfc_component *c, gfc_expr *expr)
{
  param = gfc_get_actual_arglist ();
  if (!param_list)
    param_list = param_tail = param;
  else
    {
      param_tail->next = param;
      param_tail = param_tail->next;
    }

  param_tail->name = c->name;
  if (expr)
    param_tail->expr = gfc_copy_expr (expr);
  else if (c->initializer)
    param_tail->expr = gfc_copy_expr (c->initializer);
  else
    {
      param_tail->spec_type = SPEC_ASSUMED;
      if (c->attr.pdt_kind)
	{
	  gfc_error ("The KIND parameter %qs in the PDT constructor "
		     "at %C has no value", param->name);
	  return false;
	}
    }

  return true;
}

static bool
get_pdt_constructor (gfc_expr *expr, gfc_constructor **constr,
		     gfc_symbol *derived)
{
  gfc_constructor *cons = NULL;
  gfc_component *comp;
  bool t = true;

  if (expr && expr->expr_type == EXPR_STRUCTURE)
    cons = gfc_constructor_first (expr->value.constructor);
  else if (constr)
    cons = *constr;
  gcc_assert (cons);

  comp = derived->components;

  for (; comp && cons; comp = comp->next, cons = gfc_constructor_next (cons))
    {
      if (cons->expr
	  && cons->expr->expr_type == EXPR_STRUCTURE
	  && comp->ts.type == BT_DERIVED)
	{
	  t = get_pdt_constructor (cons->expr, NULL, comp->ts.u.derived);
	  if (!t)
	    return t;
	}
      else if (comp->ts.type == BT_DERIVED)
	{
	  t = get_pdt_constructor (NULL, &cons, comp->ts.u.derived);
	  if (!t)
	    return t;
	}
     else if ((comp->attr.pdt_kind || comp->attr.pdt_len)
	       && derived->attr.pdt_template)
	{
	  t = get_pdt_spec_expr (comp, cons->expr);
	  if (!t)
	    return t;
	}
    }
  return t;
}


static bool resolve_fl_derived0 (gfc_symbol *sym);
static bool resolve_fl_struct (gfc_symbol *sym);


/* Resolve all of the elements of a structure constructor and make sure that
   the types are correct. The 'init' flag indicates that the given
   constructor is an initializer.  */

static bool
resolve_structure_cons (gfc_expr *expr, int init)
{
  gfc_constructor *cons;
  gfc_component *comp;
  bool t;
  symbol_attribute a;

  t = true;

  if (expr->ts.type == BT_DERIVED || expr->ts.type == BT_UNION)
    {
      if (expr->ts.u.derived->attr.flavor == FL_DERIVED)
        resolve_fl_derived0 (expr->ts.u.derived);
      else
        resolve_fl_struct (expr->ts.u.derived);

      /* If this is a Parameterized Derived Type template, find the
	 instance corresponding to the PDT kind parameters.  */
      if (expr->ts.u.derived->attr.pdt_template)
	{
	  param_list = NULL;
	  t = get_pdt_constructor (expr, NULL, expr->ts.u.derived);
	  if (!t)
	    return t;
	  gfc_get_pdt_instance (param_list, &expr->ts.u.derived, NULL);

	  expr->param_list = gfc_copy_actual_arglist (param_list);

	  if (param_list)
	    gfc_free_actual_arglist (param_list);

	  if (!expr->ts.u.derived->attr.pdt_type)
	    return false;
	}
    }

  cons = gfc_constructor_first (expr->value.constructor);

  /* A constructor may have references if it is the result of substituting a
     parameter variable.  In this case we just pull out the component we
     want.  */
  if (expr->ref)
    comp = expr->ref->u.c.sym->components;
  else
    comp = expr->ts.u.derived->components;

  for (; comp && cons; comp = comp->next, cons = gfc_constructor_next (cons))
    {
      int rank;

      if (!cons->expr)
	continue;

      /* Unions use an EXPR_NULL contrived expression to tell the translation
         phase to generate an initializer of the appropriate length.
         Ignore it here.  */
      if (cons->expr->ts.type == BT_UNION && cons->expr->expr_type == EXPR_NULL)
        continue;

      if (!gfc_resolve_expr (cons->expr))
	{
	  t = false;
	  continue;
	}

      rank = comp->as ? comp->as->rank : 0;
      if (comp->ts.type == BT_CLASS
	  && !comp->ts.u.derived->attr.unlimited_polymorphic
	  && CLASS_DATA (comp)->as)
 	rank = CLASS_DATA (comp)->as->rank;

      if (cons->expr->expr_type != EXPR_NULL && rank != cons->expr->rank
	  && (comp->attr.allocatable || cons->expr->rank))
	{
	  gfc_error ("The rank of the element in the structure "
		     "constructor at %L does not match that of the "
		     "component (%d/%d)", &cons->expr->where,
		     cons->expr->rank, rank);
	  t = false;
	}

      /* If we don't have the right type, try to convert it.  */

      if (!comp->attr.proc_pointer &&
	  !gfc_compare_types (&cons->expr->ts, &comp->ts))
	{
	  if (strcmp (comp->name, "_extends") == 0)
	    {
	      /* Can afford to be brutal with the _extends initializer.
		 The derived type can get lost because it is PRIVATE
		 but it is not usage constrained by the standard.  */
	      cons->expr->ts = comp->ts;
	    }
	  else if (comp->attr.pointer && cons->expr->ts.type != BT_UNKNOWN)
	    {
	      gfc_error ("The element in the structure constructor at %L, "
			 "for pointer component %qs, is %s but should be %s",
			 &cons->expr->where, comp->name,
			 gfc_basic_typename (cons->expr->ts.type),
			 gfc_basic_typename (comp->ts.type));
	      t = false;
	    }
	  else
	    {
	      bool t2 = gfc_convert_type (cons->expr, &comp->ts, 1);
	      if (t)
		t = t2;
	    }
	}

      /* For strings, the length of the constructor should be the same as
	 the one of the structure, ensure this if the lengths are known at
 	 compile time and when we are dealing with PARAMETER or structure
	 constructors.  */
      if (cons->expr->ts.type == BT_CHARACTER && comp->ts.u.cl
	  && comp->ts.u.cl->length
	  && comp->ts.u.cl->length->expr_type == EXPR_CONSTANT
	  && cons->expr->ts.u.cl && cons->expr->ts.u.cl->length
	  && cons->expr->ts.u.cl->length->expr_type == EXPR_CONSTANT
	  && cons->expr->rank != 0
	  && mpz_cmp (cons->expr->ts.u.cl->length->value.integer,
		      comp->ts.u.cl->length->value.integer) != 0)
	{
	  if (cons->expr->expr_type == EXPR_VARIABLE
	      && cons->expr->symtree->n.sym->attr.flavor == FL_PARAMETER)
	    {
	      /* Wrap the parameter in an array constructor (EXPR_ARRAY)
		 to make use of the gfc_resolve_character_array_constructor
		 machinery.  The expression is later simplified away to
		 an array of string literals.  */
	      gfc_expr *para = cons->expr;
	      cons->expr = gfc_get_expr ();
	      cons->expr->ts = para->ts;
	      cons->expr->where = para->where;
	      cons->expr->expr_type = EXPR_ARRAY;
	      cons->expr->rank = para->rank;
	      cons->expr->shape = gfc_copy_shape (para->shape, para->rank);
	      gfc_constructor_append_expr (&cons->expr->value.constructor,
					   para, &cons->expr->where);
	    }

	  if (cons->expr->expr_type == EXPR_ARRAY)
	    {
	      /* Rely on the cleanup of the namespace to deal correctly with
		 the old charlen.  (There was a block here that attempted to
		 remove the charlen but broke the chain in so doing.)  */
	      cons->expr->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
	      cons->expr->ts.u.cl->length_from_typespec = true;
	      cons->expr->ts.u.cl->length = gfc_copy_expr (comp->ts.u.cl->length);
	      gfc_resolve_character_array_constructor (cons->expr);
	    }
	}

      if (cons->expr->expr_type == EXPR_NULL
	  && !(comp->attr.pointer || comp->attr.allocatable
	       || comp->attr.proc_pointer || comp->ts.f90_type == BT_VOID
	       || (comp->ts.type == BT_CLASS
		   && (CLASS_DATA (comp)->attr.class_pointer
		       || CLASS_DATA (comp)->attr.allocatable))))
	{
	  t = false;
	  gfc_error ("The NULL in the structure constructor at %L is "
		     "being applied to component %qs, which is neither "
		     "a POINTER nor ALLOCATABLE", &cons->expr->where,
		     comp->name);
	}

      if (comp->attr.proc_pointer && comp->ts.interface)
	{
	  /* Check procedure pointer interface.  */
	  gfc_symbol *s2 = NULL;
	  gfc_component *c2;
	  const char *name;
	  char err[200];

	  c2 = gfc_get_proc_ptr_comp (cons->expr);
	  if (c2)
	    {
	      s2 = c2->ts.interface;
	      name = c2->name;
	    }
	  else if (cons->expr->expr_type == EXPR_FUNCTION)
	    {
	      s2 = cons->expr->symtree->n.sym->result;
	      name = cons->expr->symtree->n.sym->result->name;
	    }
	  else if (cons->expr->expr_type != EXPR_NULL)
	    {
	      s2 = cons->expr->symtree->n.sym;
	      name = cons->expr->symtree->n.sym->name;
	    }

	  if (s2 && !gfc_compare_interfaces (comp->ts.interface, s2, name, 0, 1,
					     err, sizeof (err), NULL, NULL))
	    {
	      gfc_error_opt (0, "Interface mismatch for procedure-pointer "
			     "component %qs in structure constructor at %L:"
			     " %s", comp->name, &cons->expr->where, err);
	      return false;
	    }
	}

      if (!comp->attr.pointer || comp->attr.proc_pointer
	  || cons->expr->expr_type == EXPR_NULL)
	continue;

      a = gfc_expr_attr (cons->expr);

      if (!a.pointer && !a.target)
	{
	  t = false;
	  gfc_error ("The element in the structure constructor at %L, "
		     "for pointer component %qs should be a POINTER or "
		     "a TARGET", &cons->expr->where, comp->name);
	}

      if (init)
	{
	  /* F08:C461. Additional checks for pointer initialization.  */
	  if (a.allocatable)
	    {
	      t = false;
	      gfc_error ("Pointer initialization target at %L "
			 "must not be ALLOCATABLE", &cons->expr->where);
	    }
	  if (!a.save)
	    {
	      t = false;
	      gfc_error ("Pointer initialization target at %L "
			 "must have the SAVE attribute", &cons->expr->where);
	    }
	}

      /* F2003, C1272 (3).  */
      bool impure = cons->expr->expr_type == EXPR_VARIABLE
		    && (gfc_impure_variable (cons->expr->symtree->n.sym)
			|| gfc_is_coindexed (cons->expr));
      if (impure && gfc_pure (NULL))
	{
	  t = false;
	  gfc_error ("Invalid expression in the structure constructor for "
		     "pointer component %qs at %L in PURE procedure",
		     comp->name, &cons->expr->where);
	}

      if (impure)
	gfc_unset_implicit_pure (NULL);
    }

  return t;
}


/****************** Expression name resolution ******************/

/* Returns 0 if a symbol was not declared with a type or
   attribute declaration statement, nonzero otherwise.  */

static int
was_declared (gfc_symbol *sym)
{
  symbol_attribute a;

  a = sym->attr;

  if (!a.implicit_type && sym->ts.type != BT_UNKNOWN)
    return 1;

  if (a.allocatable || a.dimension || a.dummy || a.external || a.intrinsic
      || a.optional || a.pointer || a.save || a.target || a.volatile_
      || a.value || a.access != ACCESS_UNKNOWN || a.intent != INTENT_UNKNOWN
      || a.asynchronous || a.codimension)
    return 1;

  return 0;
}


/* Determine if a symbol is generic or not.  */

static int
generic_sym (gfc_symbol *sym)
{
  gfc_symbol *s;

  if (sym->attr.generic ||
      (sym->attr.intrinsic && gfc_generic_intrinsic (sym->name)))
    return 1;

  if (was_declared (sym) || sym->ns->parent == NULL)
    return 0;

  gfc_find_symbol (sym->name, sym->ns->parent, 1, &s);

  if (s != NULL)
    {
      if (s == sym)
	return 0;
      else
	return generic_sym (s);
    }

  return 0;
}


/* Determine if a symbol is specific or not.  */

static int
specific_sym (gfc_symbol *sym)
{
  gfc_symbol *s;

  if (sym->attr.if_source == IFSRC_IFBODY
      || sym->attr.proc == PROC_MODULE
      || sym->attr.proc == PROC_INTERNAL
      || sym->attr.proc == PROC_ST_FUNCTION
      || (sym->attr.intrinsic && gfc_specific_intrinsic (sym->name))
      || sym->attr.external)
    return 1;

  if (was_declared (sym) || sym->ns->parent == NULL)
    return 0;

  gfc_find_symbol (sym->name, sym->ns->parent, 1, &s);

  return (s == NULL) ? 0 : specific_sym (s);
}


/* Figure out if the procedure is specific, generic or unknown.  */

enum proc_type
{ PTYPE_GENERIC = 1, PTYPE_SPECIFIC, PTYPE_UNKNOWN };

static proc_type
procedure_kind (gfc_symbol *sym)
{
  if (generic_sym (sym))
    return PTYPE_GENERIC;

  if (specific_sym (sym))
    return PTYPE_SPECIFIC;

  return PTYPE_UNKNOWN;
}

/* Check references to assumed size arrays.  The flag need_full_assumed_size
   is nonzero when matching actual arguments.  */

static int need_full_assumed_size = 0;

static bool
check_assumed_size_reference (gfc_symbol *sym, gfc_expr *e)
{
  if (need_full_assumed_size || !(sym->as && sym->as->type == AS_ASSUMED_SIZE))
      return false;

  /* FIXME: The comparison "e->ref->u.ar.type == AR_FULL" is wrong.
     What should it be?  */
  if (e->ref && (e->ref->u.ar.end[e->ref->u.ar.as->rank - 1] == NULL)
	  && (e->ref->u.ar.as->type == AS_ASSUMED_SIZE)
	       && (e->ref->u.ar.type == AR_FULL))
    {
      gfc_error ("The upper bound in the last dimension must "
		 "appear in the reference to the assumed size "
		 "array %qs at %L", sym->name, &e->where);
      return true;
    }
  return false;
}


/* Look for bad assumed size array references in argument expressions
  of elemental and array valued intrinsic procedures.  Since this is
  called from procedure resolution functions, it only recurses at
  operators.  */

static bool
resolve_assumed_size_actual (gfc_expr *e)
{
  if (e == NULL)
   return false;

  switch (e->expr_type)
    {
    case EXPR_VARIABLE:
      if (e->symtree && check_assumed_size_reference (e->symtree->n.sym, e))
	return true;
      break;

    case EXPR_OP:
      if (resolve_assumed_size_actual (e->value.op.op1)
	  || resolve_assumed_size_actual (e->value.op.op2))
	return true;
      break;

    default:
      break;
    }
  return false;
}


/* Check a generic procedure, passed as an actual argument, to see if
   there is a matching specific name.  If none, it is an error, and if
   more than one, the reference is ambiguous.  */
static int
count_specific_procs (gfc_expr *e)
{
  int n;
  gfc_interface *p;
  gfc_symbol *sym;

  n = 0;
  sym = e->symtree->n.sym;

  for (p = sym->generic; p; p = p->next)
    if (strcmp (sym->name, p->sym->name) == 0)
      {
	e->symtree = gfc_find_symtree (p->sym->ns->sym_root,
				       sym->name);
	n++;
      }

  if (n > 1)
    gfc_error ("%qs at %L is ambiguous", e->symtree->n.sym->name,
	       &e->where);

  if (n == 0)
    gfc_error ("GENERIC procedure %qs is not allowed as an actual "
	       "argument at %L", sym->name, &e->where);

  return n;
}


/* See if a call to sym could possibly be a not allowed RECURSION because of
   a missing RECURSIVE declaration.  This means that either sym is the current
   context itself, or sym is the parent of a contained procedure calling its
   non-RECURSIVE containing procedure.
   This also works if sym is an ENTRY.  */

static bool
is_illegal_recursion (gfc_symbol* sym, gfc_namespace* context)
{
  gfc_symbol* proc_sym;
  gfc_symbol* context_proc;
  gfc_namespace* real_context;

  if (sym->attr.flavor == FL_PROGRAM
      || gfc_fl_struct (sym->attr.flavor))
    return false;

  /* If we've got an ENTRY, find real procedure.  */
  if (sym->attr.entry && sym->ns->entries)
    proc_sym = sym->ns->entries->sym;
  else
    proc_sym = sym;

  /* If sym is RECURSIVE, all is well of course.  */
  if (proc_sym->attr.recursive || flag_recursive)
    return false;

  /* Find the context procedure's "real" symbol if it has entries.
     We look for a procedure symbol, so recurse on the parents if we don't
     find one (like in case of a BLOCK construct).  */
  for (real_context = context; ; real_context = real_context->parent)
    {
      /* We should find something, eventually!  */
      gcc_assert (real_context);

      context_proc = (real_context->entries ? real_context->entries->sym
					    : real_context->proc_name);

      /* In some special cases, there may not be a proc_name, like for this
	 invalid code:
	 real(bad_kind()) function foo () ...
	 when checking the call to bad_kind ().
	 In these cases, we simply return here and assume that the
	 call is ok.  */
      if (!context_proc)
	return false;

      if (context_proc->attr.flavor != FL_LABEL)
	break;
    }

  /* A call from sym's body to itself is recursion, of course.  */
  if (context_proc == proc_sym)
    return true;

  /* The same is true if context is a contained procedure and sym the
     containing one.  */
  if (context_proc->attr.contained)
    {
      gfc_symbol* parent_proc;

      gcc_assert (context->parent);
      parent_proc = (context->parent->entries ? context->parent->entries->sym
					      : context->parent->proc_name);

      if (parent_proc == proc_sym)
	return true;
    }

  return false;
}


/* Resolve an intrinsic procedure: Set its function/subroutine attribute,
   its typespec and formal argument list.  */

bool
gfc_resolve_intrinsic (gfc_symbol *sym, locus *loc)
{
  gfc_intrinsic_sym* isym = NULL;
  const char* symstd;

  if (sym->resolve_symbol_called >= 2)
    return true;

  sym->resolve_symbol_called = 2;

  /* Already resolved.  */
  if (sym->from_intmod && sym->ts.type != BT_UNKNOWN)
    return true;

  /* We already know this one is an intrinsic, so we don't call
     gfc_is_intrinsic for full checking but rather use gfc_find_function and
     gfc_find_subroutine directly to check whether it is a function or
     subroutine.  */

  if (sym->intmod_sym_id && sym->attr.subroutine)
    {
      gfc_isym_id id = gfc_isym_id_by_intmod_sym (sym);
      isym = gfc_intrinsic_subroutine_by_id (id);
    }
  else if (sym->intmod_sym_id)
    {
      gfc_isym_id id = gfc_isym_id_by_intmod_sym (sym);
      isym = gfc_intrinsic_function_by_id (id);
    }
  else if (!sym->attr.subroutine)
    isym = gfc_find_function (sym->name);

  if (isym && !sym->attr.subroutine)
    {
      if (sym->ts.type != BT_UNKNOWN && warn_surprising
	  && !sym->attr.implicit_type)
	gfc_warning (OPT_Wsurprising,
		     "Type specified for intrinsic function %qs at %L is"
		      " ignored", sym->name, &sym->declared_at);

      if (!sym->attr.function &&
	  !gfc_add_function(&sym->attr, sym->name, loc))
	return false;

      sym->ts = isym->ts;
    }
  else if (isym || (isym = gfc_find_subroutine (sym->name)))
    {
      if (sym->ts.type != BT_UNKNOWN && !sym->attr.implicit_type)
	{
	  gfc_error ("Intrinsic subroutine %qs at %L shall not have a type"
		      " specifier", sym->name, &sym->declared_at);
	  return false;
	}

      if (!sym->attr.subroutine &&
	  !gfc_add_subroutine(&sym->attr, sym->name, loc))
	return false;
    }
  else
    {
      gfc_error ("%qs declared INTRINSIC at %L does not exist", sym->name,
		 &sym->declared_at);
      return false;
    }

  gfc_copy_formal_args_intr (sym, isym, NULL);

  sym->attr.pure = isym->pure;
  sym->attr.elemental = isym->elemental;

  /* Check it is actually available in the standard settings.  */
  if (!gfc_check_intrinsic_standard (isym, &symstd, false, sym->declared_at))
    {
      gfc_error ("The intrinsic %qs declared INTRINSIC at %L is not "
		 "available in the current standard settings but %s. Use "
		 "an appropriate %<-std=*%> option or enable "
		 "%<-fall-intrinsics%> in order to use it.",
		 sym->name, &sym->declared_at, symstd);
      return false;
    }

  return true;
}


/* Resolve a procedure expression, like passing it to a called procedure or as
   RHS for a procedure pointer assignment.  */

static bool
resolve_procedure_expression (gfc_expr* expr)
{
  gfc_symbol* sym;

  if (expr->expr_type != EXPR_VARIABLE)
    return true;
  gcc_assert (expr->symtree);

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

  if (sym->attr.intrinsic)
    gfc_resolve_intrinsic (sym, &expr->where);

  if (sym->attr.flavor != FL_PROCEDURE
      || (sym->attr.function && sym->result == sym))
    return true;

  /* A non-RECURSIVE procedure that is used as procedure expression within its
     own body is in danger of being called recursively.  */
  if (is_illegal_recursion (sym, gfc_current_ns))
    gfc_warning (0, "Non-RECURSIVE procedure %qs at %L is possibly calling"
		 " itself recursively.  Declare it RECURSIVE or use"
		 " %<-frecursive%>", sym->name, &expr->where);

  return true;
}


/* Check that name is not a derived type.  */

static bool
is_dt_name (const char *name)
{
  gfc_symbol *dt_list, *dt_first;

  dt_list = dt_first = gfc_derived_types;
  for (; dt_list; dt_list = dt_list->dt_next)
    {
      if (strcmp(dt_list->name, name) == 0)
	return true;
      if (dt_first == dt_list->dt_next)
	break;
    }
  return false;
}


/* Resolve an actual argument list.  Most of the time, this is just
   resolving the expressions in the list.
   The exception is that we sometimes have to decide whether arguments
   that look like procedure arguments are really simple variable
   references.  */

static bool
resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype,
			bool no_formal_args)
{
  gfc_symbol *sym;
  gfc_symtree *parent_st;
  gfc_expr *e;
  gfc_component *comp;
  int save_need_full_assumed_size;
  bool return_value = false;
  bool actual_arg_sav = actual_arg, first_actual_arg_sav = first_actual_arg;

  actual_arg = true;
  first_actual_arg = true;

  for (; arg; arg = arg->next)
    {
      e = arg->expr;
      if (e == NULL)
	{
	  /* Check the label is a valid branching target.  */
	  if (arg->label)
	    {
	      if (arg->label->defined == ST_LABEL_UNKNOWN)
		{
		  gfc_error ("Label %d referenced at %L is never defined",
			     arg->label->value, &arg->label->where);
		  goto cleanup;
		}
	    }
	  first_actual_arg = false;
	  continue;
	}

      if (e->expr_type == EXPR_VARIABLE
	    && e->symtree->n.sym->attr.generic
	    && no_formal_args
	    && count_specific_procs (e) != 1)
	goto cleanup;

      if (e->ts.type != BT_PROCEDURE)
	{
	  save_need_full_assumed_size = need_full_assumed_size;
	  if (e->expr_type != EXPR_VARIABLE)
	    need_full_assumed_size = 0;
	  if (!gfc_resolve_expr (e))
	    goto cleanup;
	  need_full_assumed_size = save_need_full_assumed_size;
	  goto argument_list;
	}

      /* See if the expression node should really be a variable reference.  */

      sym = e->symtree->n.sym;

      if (sym->attr.flavor == FL_PROCEDURE && is_dt_name (sym->name))
	{
	  gfc_error ("Derived type %qs is used as an actual "
		     "argument at %L", sym->name, &e->where);
	  goto cleanup;
	}

      if (sym->attr.flavor == FL_PROCEDURE
	  || sym->attr.intrinsic
	  || sym->attr.external)
	{
	  int actual_ok;

	  /* If a procedure is not already determined to be something else
	     check if it is intrinsic.  */
	  if (gfc_is_intrinsic (sym, sym->attr.subroutine, e->where))
	    sym->attr.intrinsic = 1;

	  if (sym->attr.proc == PROC_ST_FUNCTION)
	    {
	      gfc_error ("Statement function %qs at %L is not allowed as an "
			 "actual argument", sym->name, &e->where);
	    }

	  actual_ok = gfc_intrinsic_actual_ok (sym->name,
					       sym->attr.subroutine);
	  if (sym->attr.intrinsic && actual_ok == 0)
	    {
	      gfc_error ("Intrinsic %qs at %L is not allowed as an "
			 "actual argument", sym->name, &e->where);
	    }

	  if (sym->attr.contained && !sym->attr.use_assoc
	      && sym->ns->proc_name->attr.flavor != FL_MODULE)
	    {
	      if (!gfc_notify_std (GFC_STD_F2008, "Internal procedure %qs is"
				   " used as actual argument at %L",
				   sym->name, &e->where))
		goto cleanup;
	    }

	  if (sym->attr.elemental && !sym->attr.intrinsic)
	    {
	      gfc_error ("ELEMENTAL non-INTRINSIC procedure %qs is not "
			 "allowed as an actual argument at %L", sym->name,
			 &e->where);
	    }

	  /* Check if a generic interface has a specific procedure
	    with the same name before emitting an error.  */
	  if (sym->attr.generic && count_specific_procs (e) != 1)
	    goto cleanup;

	  /* Just in case a specific was found for the expression.  */
	  sym = e->symtree->n.sym;

	  /* If the symbol is the function that names the current (or
	     parent) scope, then we really have a variable reference.  */

	  if (gfc_is_function_return_value (sym, sym->ns))
	    goto got_variable;

	  /* If all else fails, see if we have a specific intrinsic.  */
	  if (sym->ts.type == BT_UNKNOWN && sym->attr.intrinsic)
	    {
	      gfc_intrinsic_sym *isym;

	      isym = gfc_find_function (sym->name);
	      if (isym == NULL || !isym->specific)
		{
		  gfc_error ("Unable to find a specific INTRINSIC procedure "
			     "for the reference %qs at %L", sym->name,
			     &e->where);
		  goto cleanup;
		}
	      sym->ts = isym->ts;
	      sym->attr.intrinsic = 1;
	      sym->attr.function = 1;
	    }

	  if (!gfc_resolve_expr (e))
	    goto cleanup;
	  goto argument_list;
	}

      /* See if the name is a module procedure in a parent unit.  */

      if (was_declared (sym) || sym->ns->parent == NULL)
	goto got_variable;

      if (gfc_find_sym_tree (sym->name, sym->ns->parent, 1, &parent_st))
	{
	  gfc_error ("Symbol %qs at %L is ambiguous", sym->name, &e->where);
	  goto cleanup;
	}

      if (parent_st == NULL)
	goto got_variable;

      sym = parent_st->n.sym;
      e->symtree = parent_st;		/* Point to the right thing.  */

      if (sym->attr.flavor == FL_PROCEDURE
	  || sym->attr.intrinsic
	  || sym->attr.external)
	{
	  if (!gfc_resolve_expr (e))
	    goto cleanup;
	  goto argument_list;
	}

    got_variable:
      e->expr_type = EXPR_VARIABLE;
      e->ts = sym->ts;
      if ((sym->as != NULL && sym->ts.type != BT_CLASS)
	  || (sym->ts.type == BT_CLASS && sym->attr.class_ok
	      && CLASS_DATA (sym)->as))
	{
	  e->rank = sym->ts.type == BT_CLASS
		    ? CLASS_DATA (sym)->as->rank : sym->as->rank;
	  e->ref = gfc_get_ref ();
	  e->ref->type = REF_ARRAY;
	  e->ref->u.ar.type = AR_FULL;
	  e->ref->u.ar.as = sym->ts.type == BT_CLASS
			    ? CLASS_DATA (sym)->as : sym->as;
	}

      /* Expressions are assigned a default ts.type of BT_PROCEDURE in
	 primary.c (match_actual_arg). If above code determines that it
	 is a  variable instead, it needs to be resolved as it was not
	 done at the beginning of this function.  */
      save_need_full_assumed_size = need_full_assumed_size;
      if (e->expr_type != EXPR_VARIABLE)
	need_full_assumed_size = 0;
      if (!gfc_resolve_expr (e))
	goto cleanup;
      need_full_assumed_size = save_need_full_assumed_size;

    argument_list:
      /* Check argument list functions %VAL, %LOC and %REF.  There is
	 nothing to do for %REF.  */
      if (arg->name && arg->name[0] == '%')
	{
	  if (strcmp ("%VAL", arg->name) == 0)
	    {
	      if (e->ts.type == BT_CHARACTER || e->ts.type == BT_DERIVED)
		{
		  gfc_error ("By-value argument at %L is not of numeric "
			     "type", &e->where);
		  goto cleanup;
		}

	      if (e->rank)
		{
		  gfc_error ("By-value argument at %L cannot be an array or "
			     "an array section", &e->where);
		  goto cleanup;
		}

	      /* Intrinsics are still PROC_UNKNOWN here.  However,
		 since same file external procedures are not resolvable
		 in gfortran, it is a good deal easier to leave them to
		 intrinsic.c.  */
	      if (ptype != PROC_UNKNOWN
		  && ptype != PROC_DUMMY
		  && ptype != PROC_EXTERNAL
		  && ptype != PROC_MODULE)
		{
		  gfc_error ("By-value argument at %L is not allowed "
			     "in this context", &e->where);
		  goto cleanup;
		}
	    }

	  /* Statement functions have already been excluded above.  */
	  else if (strcmp ("%LOC", arg->name) == 0
		   && e->ts.type == BT_PROCEDURE)
	    {
	      if (e->symtree->n.sym->attr.proc == PROC_INTERNAL)
		{
		  gfc_error ("Passing internal procedure at %L by location "
			     "not allowed", &e->where);
		  goto cleanup;
		}
	    }
	}

      comp = gfc_get_proc_ptr_comp(e);
      if (e->expr_type == EXPR_VARIABLE
	  && comp && comp->attr.elemental)
	{
	    gfc_error ("ELEMENTAL procedure pointer component %qs is not "
		       "allowed as an actual argument at %L", comp->name,
		       &e->where);
	}

      /* Fortran 2008, C1237.  */
      if (e->expr_type == EXPR_VARIABLE && gfc_is_coindexed (e)
	  && gfc_has_ultimate_pointer (e))
	{
	  gfc_error ("Coindexed actual argument at %L with ultimate pointer "
		     "component", &e->where);
	  goto cleanup;
	}

      first_actual_arg = false;
    }

  return_value = true;

cleanup:
  actual_arg = actual_arg_sav;
  first_actual_arg = first_actual_arg_sav;

  return return_value;
}


/* Do the checks of the actual argument list that are specific to elemental
   procedures.  If called with c == NULL, we have a function, otherwise if
   expr == NULL, we have a subroutine.  */

static bool
resolve_elemental_actual (gfc_expr *expr, gfc_code *c)
{
  gfc_actual_arglist *arg0;
  gfc_actual_arglist *arg;
  gfc_symbol *esym = NULL;
  gfc_intrinsic_sym *isym = NULL;
  gfc_expr *e = NULL;
  gfc_intrinsic_arg *iformal = NULL;
  gfc_formal_arglist *eformal = NULL;
  bool formal_optional = false;
  bool set_by_optional = false;
  int i;
  int rank = 0;

  /* Is this an elemental procedure?  */
  if (expr && expr->value.function.actual != NULL)
    {
      if (expr->value.function.esym != NULL
	  && expr->value.function.esym->attr.elemental)
	{
	  arg0 = expr->value.function.actual;
	  esym = expr->value.function.esym;
	}
      else if (expr->value.function.isym != NULL
	       && expr->value.function.isym->elemental)
	{
	  arg0 = expr->value.function.actual;
	  isym = expr->value.function.isym;
	}
      else
	return true;
    }
  else if (c && c->ext.actual != NULL)
    {
      arg0 = c->ext.actual;

      if (c->resolved_sym)
	esym = c->resolved_sym;
      else
	esym = c->symtree->n.sym;
      gcc_assert (esym);

      if (!esym->attr.elemental)
	return true;
    }
  else
    return true;

  /* The rank of an elemental is the rank of its array argument(s).  */
  for (arg = arg0; arg; arg = arg->next)
    {
      if (arg->expr != NULL && arg->expr->rank != 0)
	{
	  rank = arg->expr->rank;
	  if (arg->expr->expr_type == EXPR_VARIABLE
	      && arg->expr->symtree->n.sym->attr.optional)
	    set_by_optional = true;

	  /* Function specific; set the result rank and shape.  */
	  if (expr)
	    {
	      expr->rank = rank;
	      if (!expr->shape && arg->expr->shape)
		{
		  expr->shape = gfc_get_shape (rank);
		  for (i = 0; i < rank; i++)
		    mpz_init_set (expr->shape[i], arg->expr->shape[i]);
		}
	    }
	  break;
	}
    }

  /* If it is an array, it shall not be supplied as an actual argument
     to an elemental procedure unless an array of the same rank is supplied
     as an actual argument corresponding to a nonoptional dummy argument of
     that elemental procedure(12.4.1.5).  */
  formal_optional = false;
  if (isym)
    iformal = isym->formal;
  else
    eformal = esym->formal;

  for (arg = arg0; arg; arg = arg->next)
    {
      if (eformal)
	{
	  if (eformal->sym && eformal->sym->attr.optional)
	    formal_optional = true;
	  eformal = eformal->next;
	}
      else if (isym && iformal)
	{
	  if (iformal->optional)
	    formal_optional = true;
	  iformal = iformal->next;
	}
      else if (isym)
	formal_optional = true;

      if (pedantic && arg->expr != NULL
	  && arg->expr->expr_type == EXPR_VARIABLE
	  && arg->expr->symtree->n.sym->attr.optional
	  && formal_optional
	  && arg->expr->rank
	  && (set_by_optional || arg->expr->rank != rank)
	  && !(isym && isym->id == GFC_ISYM_CONVERSION))
	{
	  bool t = false;
	  gfc_actual_arglist *a;

	  /* Scan the argument list for a non-optional argument with the
	     same rank as arg.  */
	  for (a = arg0; a; a = a->next)
	    if (a != arg
		&& a->expr->rank == arg->expr->rank
		&& !a->expr->symtree->n.sym->attr.optional)
	      {
		t = true;
		break;
	      }

	  if (!t)
	    gfc_warning (OPT_Wpedantic,
			 "%qs at %L is an array and OPTIONAL; If it is not "
			 "present, then it cannot be the actual argument of "
			 "an ELEMENTAL procedure unless there is a non-optional"
			 " argument with the same rank "
			 "(Fortran 2018, 15.5.2.12)",
			 arg->expr->symtree->n.sym->name, &arg->expr->where);
	}
    }

  for (arg = arg0; arg; arg = arg->next)
    {
      if (arg->expr == NULL || arg->expr->rank == 0)
	continue;

      /* Being elemental, the last upper bound of an assumed size array
	 argument must be present.  */
      if (resolve_assumed_size_actual (arg->expr))
	return false;

      /* Elemental procedure's array actual arguments must conform.  */
      if (e != NULL)
	{
	  if (!gfc_check_conformance (arg->expr, e, _("elemental procedure")))
	    return false;
	}
      else
	e = arg->expr;
    }

  /* INTENT(OUT) is only allowed for subroutines; if any actual argument
     is an array, the intent inout/out variable needs to be also an array.  */
  if (rank > 0 && esym && expr == NULL)
    for (eformal = esym->formal, arg = arg0; arg && eformal;
	 arg = arg->next, eformal = eformal->next)
      if ((eformal->sym->attr.intent == INTENT_OUT
	   || eformal->sym->attr.intent == INTENT_INOUT)
	  && arg->expr && arg->expr->rank == 0)
	{
	  gfc_error ("Actual argument at %L for INTENT(%s) dummy %qs of "
		     "ELEMENTAL subroutine %qs is a scalar, but another "
		     "actual argument is an array", &arg->expr->where,
		     (eformal->sym->attr.intent == INTENT_OUT) ? "OUT"
		     : "INOUT", eformal->sym->name, esym->name);
	  return false;
	}
  return true;
}


/* This function does the checking of references to global procedures
   as defined in sections 18.1 and 14.1, respectively, of the Fortran
   77 and 95 standards.  It checks for a gsymbol for the name, making
   one if it does not already exist.  If it already exists, then the
   reference being resolved must correspond to the type of gsymbol.
   Otherwise, the new symbol is equipped with the attributes of the
   reference.  The corresponding code that is called in creating
   global entities is parse.c.

   In addition, for all but -std=legacy, the gsymbols are used to
   check the interfaces of external procedures from the same file.
   The namespace of the gsymbol is resolved and then, once this is
   done the interface is checked.  */


static bool
not_in_recursive (gfc_symbol *sym, gfc_namespace *gsym_ns)
{
  if (!gsym_ns->proc_name->attr.recursive)
    return true;

  if (sym->ns == gsym_ns)
    return false;

  if (sym->ns->parent && sym->ns->parent == gsym_ns)
    return false;

  return true;
}

static bool
not_entry_self_reference  (gfc_symbol *sym, gfc_namespace *gsym_ns)
{
  if (gsym_ns->entries)
    {
      gfc_entry_list *entry = gsym_ns->entries;

      for (; entry; entry = entry->next)
	{
	  if (strcmp (sym->name, entry->sym->name) == 0)
	    {
	      if (strcmp (gsym_ns->proc_name->name,
			  sym->ns->proc_name->name) == 0)
		return false;

	      if (sym->ns->parent
		  && strcmp (gsym_ns->proc_name->name,
			     sym->ns->parent->proc_name->name) == 0)
		return false;
	    }
	}
    }
  return true;
}


/* Check for the requirement of an explicit interface. F08:12.4.2.2.  */

bool
gfc_explicit_interface_required (gfc_symbol *sym, char *errmsg, int err_len)
{
  gfc_formal_arglist *arg = gfc_sym_get_dummy_args (sym);

  for ( ; arg; arg = arg->next)
    {
      if (!arg->sym)
	continue;

      if (arg->sym->attr.allocatable)  /* (2a)  */
	{
	  strncpy (errmsg, _("allocatable argument"), err_len);
	  return true;
	}
      else if (arg->sym->attr.asynchronous)
	{
	  strncpy (errmsg, _("asynchronous argument"), err_len);
	  return true;
	}
      else if (arg->sym->attr.optional)
	{
	  strncpy (errmsg, _("optional argument"), err_len);
	  return true;
	}
      else if (arg->sym->attr.pointer)
	{
	  strncpy (errmsg, _("pointer argument"), err_len);
	  return true;
	}
      else if (arg->sym->attr.target)
	{
	  strncpy (errmsg, _("target argument"), err_len);
	  return true;
	}
      else if (arg->sym->attr.value)
	{
	  strncpy (errmsg, _("value argument"), err_len);
	  return true;
	}
      else if (arg->sym->attr.volatile_)
	{
	  strncpy (errmsg, _("volatile argument"), err_len);
	  return true;
	}
      else if (arg->sym->as && arg->sym->as->type == AS_ASSUMED_SHAPE)  /* (2b)  */
	{
	  strncpy (errmsg, _("assumed-shape argument"), err_len);
	  return true;
	}
      else if (arg->sym->as && arg->sym->as->type == AS_ASSUMED_RANK)  /* TS 29113, 6.2.  */
	{
	  strncpy (errmsg, _("assumed-rank argument"), err_len);
	  return true;
	}
      else if (arg->sym->attr.codimension)  /* (2c)  */
	{
	  strncpy (errmsg, _("coarray argument"), err_len);
	  return true;
	}
      else if (false)  /* (2d) TODO: parametrized derived type  */
	{
	  strncpy (errmsg, _("parametrized derived type argument"), err_len);
	  return true;
	}
      else if (arg->sym->ts.type == BT_CLASS)  /* (2e)  */
	{
	  strncpy (errmsg, _("polymorphic argument"), err_len);
	  return true;
	}
      else if (arg->sym->attr.ext_attr & (1 << EXT_ATTR_NO_ARG_CHECK))
	{
	  strncpy (errmsg, _("NO_ARG_CHECK attribute"), err_len);
	  return true;
	}
      else if (arg->sym->ts.type == BT_ASSUMED)
	{
	  /* As assumed-type is unlimited polymorphic (cf. above).
	     See also TS 29113, Note 6.1.  */
	  strncpy (errmsg, _("assumed-type argument"), err_len);
	  return true;
	}
    }

  if (sym->attr.function)
    {
      gfc_symbol *res = sym->result ? sym->result : sym;

      if (res->attr.dimension)  /* (3a)  */
	{
	  strncpy (errmsg, _("array result"), err_len);
	  return true;
	}
      else if (res->attr.pointer || res->attr.allocatable)  /* (3b)  */
	{
	  strncpy (errmsg, _("pointer or allocatable result"), err_len);
	  return true;
	}
      else if (res->ts.type == BT_CHARACTER && res->ts.u.cl
	       && res->ts.u.cl->length
	       && res->ts.u.cl->length->expr_type != EXPR_CONSTANT)  /* (3c)  */
	{
	  strncpy (errmsg, _("result with non-constant character length"), err_len);
	  return true;
	}
    }

  if (sym->attr.elemental && !sym->attr.intrinsic)  /* (4)  */
    {
      strncpy (errmsg, _("elemental procedure"), err_len);
      return true;
    }
  else if (sym->attr.is_bind_c)  /* (5)  */
    {
      strncpy (errmsg, _("bind(c) procedure"), err_len);
      return true;
    }

  return false;
}


static void
resolve_global_procedure (gfc_symbol *sym, locus *where, int sub)
{
  gfc_gsymbol * gsym;
  gfc_namespace *ns;
  enum gfc_symbol_type type;
  char reason[200];

  type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;

  gsym = gfc_get_gsymbol (sym->binding_label ? sym->binding_label : sym->name,
			  sym->binding_label != NULL);

  if ((gsym->type != GSYM_UNKNOWN && gsym->type != type))
    gfc_global_used (gsym, where);

  if ((sym->attr.if_source == IFSRC_UNKNOWN
       || sym->attr.if_source == IFSRC_IFBODY)
      && gsym->type != GSYM_UNKNOWN
      && !gsym->binding_label
      && gsym->ns
      && gsym->ns->proc_name
      && not_in_recursive (sym, gsym->ns)
      && not_entry_self_reference (sym, gsym->ns))
    {
      gfc_symbol *def_sym;
      def_sym = gsym->ns->proc_name;

      if (gsym->ns->resolved != -1)
	{

	  /* Resolve the gsymbol namespace if needed.  */
	  if (!gsym->ns->resolved)
	    {
	      gfc_symbol *old_dt_list;

	      /* Stash away derived types so that the backend_decls
		 do not get mixed up.  */
	      old_dt_list = gfc_derived_types;
	      gfc_derived_types = NULL;

	      gfc_resolve (gsym->ns);

	      /* Store the new derived types with the global namespace.  */
	      if (gfc_derived_types)
		gsym->ns->derived_types = gfc_derived_types;

	      /* Restore the derived types of this namespace.  */
	      gfc_derived_types = old_dt_list;
	    }

	  /* Make sure that translation for the gsymbol occurs before
	     the procedure currently being resolved.  */
	  ns = gfc_global_ns_list;
	  for (; ns && ns != gsym->ns; ns = ns->sibling)
	    {
	      if (ns->sibling == gsym->ns)
		{
		  ns->sibling = gsym->ns->sibling;
		  gsym->ns->sibling = gfc_global_ns_list;
		  gfc_global_ns_list = gsym->ns;
		  break;
		}
	    }

	  /* This can happen if a binding name has been specified.  */
	  if (gsym->binding_label && gsym->sym_name != def_sym->name)
	    gfc_find_symbol (gsym->sym_name, gsym->ns, 0, &def_sym);

	  if (def_sym->attr.entry_master || def_sym->attr.entry)
	    {
	      gfc_entry_list *entry;
	      for (entry = gsym->ns->entries; entry; entry = entry->next)
		if (strcmp (entry->sym->name, sym->name) == 0)
		  {
		    def_sym = entry->sym;
		    break;
		  }
	    }
	}

      if (sym->attr.function && !gfc_compare_types (&sym->ts, &def_sym->ts))
	{
	  gfc_error ("Return type mismatch of function %qs at %L (%s/%s)",
		     sym->name, &sym->declared_at, gfc_typename (&sym->ts),
		     gfc_typename (&def_sym->ts));
	  goto done;
	}

      if (sym->attr.if_source == IFSRC_UNKNOWN
	  && gfc_explicit_interface_required (def_sym, reason, sizeof(reason)))
	{
	  gfc_error ("Explicit interface required for %qs at %L: %s",
		     sym->name, &sym->declared_at, reason);
	  goto done;
	}

      bool bad_result_characteristics;
      if (!gfc_compare_interfaces (sym, def_sym, sym->name, 0, 1,
				   reason, sizeof(reason), NULL, NULL,
				   &bad_result_characteristics))
	{
	  /* Turn erros into warnings with -std=gnu and -std=legacy,
	     unless a function returns a wrong type, which can lead
	     to all kinds of ICEs and wrong code.  */

	  if (!pedantic && (gfc_option.allow_std & GFC_STD_GNU)
	      && !bad_result_characteristics)
	    gfc_errors_to_warnings (true);

	  gfc_error ("Interface mismatch in global procedure %qs at %L: %s",
		     sym->name, &sym->declared_at, reason);
	  sym->error = 1;
	  gfc_errors_to_warnings (false);
	  goto done;
	}
    }

done:

  if (gsym->type == GSYM_UNKNOWN)
    {
      gsym->type = type;
      gsym->where = *where;
    }

  gsym->used = 1;
}


/************* Function resolution *************/

/* Resolve a function call known to be generic.
   Section 14.1.2.4.1.  */

static match
resolve_generic_f0 (gfc_expr *expr, gfc_symbol *sym)
{
  gfc_symbol *s;

  if (sym->attr.generic)
    {
      s = gfc_search_interface (sym->generic, 0, &expr->value.function.actual);
      if (s != NULL)
	{
	  expr->value.function.name = s->name;
	  expr->value.function.esym = s;

	  if (s->ts.type != BT_UNKNOWN)
	    expr->ts = s->ts;
	  else if (s->result != NULL && s->result->ts.type != BT_UNKNOWN)
	    expr->ts = s->result->ts;

	  if (s->as != NULL)
	    expr->rank = s->as->rank;
	  else if (s->result != NULL && s->result->as != NULL)
	    expr->rank = s->result->as->rank;

	  gfc_set_sym_referenced (expr->value.function.esym);

	  return MATCH_YES;
	}

      /* TODO: Need to search for elemental references in generic
	 interface.  */
    }

  if (sym->attr.intrinsic)
    return gfc_intrinsic_func_interface (expr, 0);

  return MATCH_NO;
}


static bool
resolve_generic_f (gfc_expr *expr)
{
  gfc_symbol *sym;
  match m;
  gfc_interface *intr = NULL;

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

  for (;;)
    {
      m = resolve_generic_f0 (expr, sym);
      if (m == MATCH_YES)
	return true;
      else if (m == MATCH_ERROR)
	return false;

generic:
      if (!intr)
	for (intr = sym->generic; intr; intr = intr->next)
	  if (gfc_fl_struct (intr->sym->attr.flavor))
	    break;

      if (sym->ns->parent == NULL)
	break;
      gfc_find_symbol (sym->name, sym->ns->parent, 1, &sym);

      if (sym == NULL)
	break;
      if (!generic_sym (sym))
	goto generic;
    }

  /* Last ditch attempt.  See if the reference is to an intrinsic
     that possesses a matching interface.  14.1.2.4  */
  if (sym  && !intr && !gfc_is_intrinsic (sym, 0, expr->where))
    {
      if (gfc_init_expr_flag)
	gfc_error ("Function %qs in initialization expression at %L "
		   "must be an intrinsic function",
		   expr->symtree->n.sym->name, &expr->where);
      else
	gfc_error ("There is no specific function for the generic %qs "
		   "at %L", expr->symtree->n.sym->name, &expr->where);
      return false;
    }

  if (intr)
    {
      if (!gfc_convert_to_structure_constructor (expr, intr->sym, NULL,
						 NULL, false))
	return false;
      if (!gfc_use_derived (expr->ts.u.derived))
	return false;
      return resolve_structure_cons (expr, 0);
    }

  m = gfc_intrinsic_func_interface (expr, 0);
  if (m == MATCH_YES)
    return true;

  if (m == MATCH_NO)
    gfc_error ("Generic function %qs at %L is not consistent with a "
	       "specific intrinsic interface", expr->symtree->n.sym->name,
	       &expr->where);

  return false;
}


/* Resolve a function call known to be specific.  */

static match
resolve_specific_f0 (gfc_symbol *sym, gfc_expr *expr)
{
  match m;

  if (sym->attr.external || sym->attr.if_source == IFSRC_IFBODY)
    {
      if (sym->attr.dummy)
	{
	  sym->attr.proc = PROC_DUMMY;
	  goto found;
	}

      sym->attr.proc = PROC_EXTERNAL;
      goto found;
    }

  if (sym->attr.proc == PROC_MODULE
      || sym->attr.proc == PROC_ST_FUNCTION
      || sym->attr.proc == PROC_INTERNAL)
    goto found;

  if (sym->attr.intrinsic)
    {
      m = gfc_intrinsic_func_interface (expr, 1);
      if (m == MATCH_YES)
	return MATCH_YES;
      if (m == MATCH_NO)
	gfc_error ("Function %qs at %L is INTRINSIC but is not compatible "
		   "with an intrinsic", sym->name, &expr->where);

      return MATCH_ERROR;
    }

  return MATCH_NO;

found:
  gfc_procedure_use (sym, &expr->value.function.actual, &expr->where);

  if (sym->result)
    expr->ts = sym->result->ts;
  else
    expr->ts = sym->ts;
  expr->value.function.name = sym->name;
  expr->value.function.esym = sym;
  /* Prevent crash when sym->ts.u.derived->components is not set due to previous
     error(s).  */
  if (sym->ts.type == BT_CLASS && !CLASS_DATA (sym))
    return MATCH_ERROR;
  if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as)
    expr->rank = CLASS_DATA (sym)->as->rank;
  else if (sym->as != NULL)
    expr->rank = sym->as->rank;

  return MATCH_YES;
}


static bool
resolve_specific_f (gfc_expr *expr)
{
  gfc_symbol *sym;
  match m;

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

  for (;;)
    {
      m = resolve_specific_f0 (sym, expr);
      if (m == MATCH_YES)
	return true;
      if (m == MATCH_ERROR)
	return false;

      if (sym->ns->parent == NULL)
	break;

      gfc_find_symbol (sym->name, sym->ns->parent, 1, &sym);

      if (sym == NULL)
	break;
    }

  gfc_error ("Unable to resolve the specific function %qs at %L",
	     expr->symtree->n.sym->name, &expr->where);

  return true;
}

/* Recursively append candidate SYM to CANDIDATES.  Store the number of
   candidates in CANDIDATES_LEN.  */

static void
lookup_function_fuzzy_find_candidates (gfc_symtree *sym,
				       char **&candidates,
				       size_t &candidates_len)
{
  gfc_symtree *p;

  if (sym == NULL)
    return;
  if ((sym->n.sym->ts.type != BT_UNKNOWN || sym->n.sym->attr.external)
      && sym->n.sym->attr.flavor == FL_PROCEDURE)
    vec_push (candidates, candidates_len, sym->name);

  p = sym->left;
  if (p)
    lookup_function_fuzzy_find_candidates (p, candidates, candidates_len);

  p = sym->right;
  if (p)
    lookup_function_fuzzy_find_candidates (p, candidates, candidates_len);
}


/* Lookup function FN fuzzily, taking names in SYMROOT into account.  */

const char*
gfc_lookup_function_fuzzy (const char *fn, gfc_symtree *symroot)
{
  char **candidates = NULL;
  size_t candidates_len = 0;
  lookup_function_fuzzy_find_candidates (symroot, candidates, candidates_len);
  return gfc_closest_fuzzy_match (fn, candidates);
}


/* Resolve a procedure call not known to be generic nor specific.  */

static bool
resolve_unknown_f (gfc_expr *expr)
{
  gfc_symbol *sym;
  gfc_typespec *ts;

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

  if (sym->attr.dummy)
    {
      sym->attr.proc = PROC_DUMMY;
      expr->value.function.name = sym->name;
      goto set_type;
    }

  /* See if we have an intrinsic function reference.  */

  if (gfc_is_intrinsic (sym, 0, expr->where))
    {
      if (gfc_intrinsic_func_interface (expr, 1) == MATCH_YES)
	return true;
      return false;
    }

  /* The reference is to an external name.  */

  sym->attr.proc = PROC_EXTERNAL;
  expr->value.function.name = sym->name;
  expr->value.function.esym = expr->symtree->n.sym;

  if (sym->as != NULL)
    expr->rank = sym->as->rank;

  /* Type of the expression is either the type of the symbol or the
     default type of the symbol.  */

set_type:
  gfc_procedure_use (sym, &expr->value.function.actual, &expr->where);

  if (sym->ts.type != BT_UNKNOWN)
    expr->ts = sym->ts;
  else
    {
      ts = gfc_get_default_type (sym->name, sym->ns);

      if (ts->type == BT_UNKNOWN)
	{
	  const char *guessed
	    = gfc_lookup_function_fuzzy (sym->name, sym->ns->sym_root);
	  if (guessed)
	    gfc_error ("Function %qs at %L has no IMPLICIT type"
		       "; did you mean %qs?",
		       sym->name, &expr->where, guessed);
	  else
	    gfc_error ("Function %qs at %L has no IMPLICIT type",
		       sym->name, &expr->where);
	  return false;
	}
      else
	expr->ts = *ts;
    }

  return true;
}


/* Return true, if the symbol is an external procedure.  */
static bool
is_external_proc (gfc_symbol *sym)
{
  if (!sym->attr.dummy && !sym->attr.contained
	&& !gfc_is_intrinsic (sym, sym->attr.subroutine, sym->declared_at)
	&& sym->attr.proc != PROC_ST_FUNCTION
	&& !sym->attr.proc_pointer
	&& !sym->attr.use_assoc
	&& sym->name)
    return true;

  return false;
}


/* Figure out if a function reference is pure or not.  Also set the name
   of the function for a potential error message.  Return nonzero if the
   function is PURE, zero if not.  */
static int
pure_stmt_function (gfc_expr *, gfc_symbol *);

int
gfc_pure_function (gfc_expr *e, const char **name)
{
  int pure;
  gfc_component *comp;

  *name = NULL;

  if (e->symtree != NULL
        && e->symtree->n.sym != NULL
        && e->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
    return pure_stmt_function (e, e->symtree->n.sym);

  comp = gfc_get_proc_ptr_comp (e);
  if (comp)
    {
      pure = gfc_pure (comp->ts.interface);
      *name = comp->name;
    }
  else if (e->value.function.esym)
    {
      pure = gfc_pure (e->value.function.esym);
      *name = e->value.function.esym->name;
    }
  else if (e->value.function.isym)
    {
      pure = e->value.function.isym->pure
	     || e->value.function.isym->elemental;
      *name = e->value.function.isym->name;
    }
  else
    {
      /* Implicit functions are not pure.  */
      pure = 0;
      *name = e->value.function.name;
    }

  return pure;
}


/* Check if the expression is a reference to an implicitly pure function.  */

int
gfc_implicit_pure_function (gfc_expr *e)
{
  gfc_component *comp = gfc_get_proc_ptr_comp (e);
  if (comp)
    return gfc_implicit_pure (comp->ts.interface);
  else if (e->value.function.esym)
    return gfc_implicit_pure (e->value.function.esym);
  else
    return 0;
}


static bool
impure_stmt_fcn (gfc_expr *e, gfc_symbol *sym,
		 int *f ATTRIBUTE_UNUSED)
{
  const char *name;

  /* Don't bother recursing into other statement functions
     since they will be checked individually for purity.  */
  if (e->expr_type != EXPR_FUNCTION
	|| !e->symtree
	|| e->symtree->n.sym == sym
	|| e->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
    return false;

  return gfc_pure_function (e, &name) ? false : true;
}


static int
pure_stmt_function (gfc_expr *e, gfc_symbol *sym)
{
  return gfc_traverse_expr (e, sym, impure_stmt_fcn, 0) ? 0 : 1;
}


/* Check if an impure function is allowed in the current context. */

static bool check_pure_function (gfc_expr *e)
{
  const char *name = NULL;
  if (!gfc_pure_function (e, &name) && name)
    {
      if (forall_flag)
	{
	  gfc_error ("Reference to impure function %qs at %L inside a "
		     "FORALL %s", name, &e->where,
		     forall_flag == 2 ? "mask" : "block");
	  return false;
	}
      else if (gfc_do_concurrent_flag)
	{
	  gfc_error ("Reference to impure function %qs at %L inside a "
		     "DO CONCURRENT %s", name, &e->where,
		     gfc_do_concurrent_flag == 2 ? "mask" : "block");
	  return false;
	}
      else if (gfc_pure (NULL))
	{
	  gfc_error ("Reference to impure function %qs at %L "
		     "within a PURE procedure", name, &e->where);
	  return false;
	}
      if (!gfc_implicit_pure_function (e))
	gfc_unset_implicit_pure (NULL);
    }
  return true;
}


/* Update current procedure's array_outer_dependency flag, considering
   a call to procedure SYM.  */

static void
update_current_proc_array_outer_dependency (gfc_symbol *sym)
{
  /* Check to see if this is a sibling function that has not yet
     been resolved.  */
  gfc_namespace *sibling = gfc_current_ns->sibling;
  for (; sibling; sibling = sibling->sibling)
    {
      if (sibling->proc_name == sym)
	{
	  gfc_resolve (sibling);
	  break;
	}
    }

  /* If SYM has references to outer arrays, so has the procedure calling
     SYM.  If SYM is a procedure pointer, we can assume the worst.  */
  if ((sym->attr.array_outer_dependency || sym->attr.proc_pointer)
      && gfc_current_ns->proc_name)
    gfc_current_ns->proc_name->attr.array_outer_dependency = 1;
}


/* Resolve a function call, which means resolving the arguments, then figuring
   out which entity the name refers to.  */

static bool
resolve_function (gfc_expr *expr)
{
  gfc_actual_arglist *arg;
  gfc_symbol *sym;
  bool t;
  int temp;
  procedure_type p = PROC_INTRINSIC;
  bool no_formal_args;

  sym = NULL;
  if (expr->symtree)
    sym = expr->symtree->n.sym;

  /* If this is a procedure pointer component, it has already been resolved.  */
  if (gfc_is_proc_ptr_comp (expr))
    return true;

  /* Avoid re-resolving the arguments of caf_get, which can lead to inserting
     another caf_get.  */
  if (sym && sym->attr.intrinsic
      && (sym->intmod_sym_id == GFC_ISYM_CAF_GET
	  || sym->intmod_sym_id == GFC_ISYM_CAF_SEND))
    return true;

  if (expr->ref)
    {
      gfc_error ("Unexpected junk after %qs at %L", expr->symtree->n.sym->name,
		 &expr->where);
      return false;
    }

  if (sym && sym->attr.intrinsic
      && !gfc_resolve_intrinsic (sym, &expr->where))
    return false;

  if (sym && (sym->attr.flavor == FL_VARIABLE || sym->attr.subroutine))
    {
      gfc_error ("%qs at %L is not a function", sym->name, &expr->where);
      return false;
    }

  /* If this is a deferred TBP with an abstract interface (which may
     of course be referenced), expr->value.function.esym will be set.  */
  if (sym && sym->attr.abstract && !expr->value.function.esym)
    {
      gfc_error ("ABSTRACT INTERFACE %qs must not be referenced at %L",
		 sym->name, &expr->where);
      return false;
    }

  /* If this is a deferred TBP with an abstract interface, its result
     cannot be an assumed length character (F2003: C418).  */
  if (sym && sym->attr.abstract && sym->attr.function
      && sym->result->ts.u.cl
      && sym->result->ts.u.cl->length == NULL
      && !sym->result->ts.deferred)
    {
      gfc_error ("ABSTRACT INTERFACE %qs at %L must not have an assumed "
		 "character length result (F2008: C418)", sym->name,
		 &sym->declared_at);
      return false;
    }

  /* Switch off assumed size checking and do this again for certain kinds
     of procedure, once the procedure itself is resolved.  */
  need_full_assumed_size++;

  if (expr->symtree && expr->symtree->n.sym)
    p = expr->symtree->n.sym->attr.proc;

  if (expr->value.function.isym && expr->value.function.isym->inquiry)
    inquiry_argument = true;
  no_formal_args = sym && is_external_proc (sym)
  		       && gfc_sym_get_dummy_args (sym) == NULL;

  if (!resolve_actual_arglist (expr->value.function.actual,
			       p, no_formal_args))
    {
      inquiry_argument = false;
      return false;
    }

  inquiry_argument = false;

  /* Resume assumed_size checking.  */
  need_full_assumed_size--;

  /* If the procedure is external, check for usage.  */
  if (sym && is_external_proc (sym))
    resolve_global_procedure (sym, &expr->where, 0);

  if (sym && sym->ts.type == BT_CHARACTER
      && sym->ts.u.cl
      && sym->ts.u.cl->length == NULL
      && !sym->attr.dummy
      && !sym->ts.deferred
      && expr->value.function.esym == NULL
      && !sym->attr.contained)
    {
      /* Internal procedures are taken care of in resolve_contained_fntype.  */
      gfc_error ("Function %qs is declared CHARACTER(*) and cannot "
		 "be used at %L since it is not a dummy argument",
		 sym->name, &expr->where);
      return false;
    }

  /* See if function is already resolved.  */

  if (expr->value.function.name != NULL
      || expr->value.function.isym != NULL)
    {
      if (expr->ts.type == BT_UNKNOWN)
	expr->ts = sym->ts;
      t = true;
    }
  else
    {
      /* Apply the rules of section 14.1.2.  */

      switch (procedure_kind (sym))
	{
	case PTYPE_GENERIC:
	  t = resolve_generic_f (expr);
	  break;

	case PTYPE_SPECIFIC:
	  t = resolve_specific_f (expr);
	  break;

	case PTYPE_UNKNOWN:
	  t = resolve_unknown_f (expr);
	  break;

	default:
	  gfc_internal_error ("resolve_function(): bad function type");
	}
    }

  /* If the expression is still a function (it might have simplified),
     then we check to see if we are calling an elemental function.  */

  if (expr->expr_type != EXPR_FUNCTION)
    return t;

  /* Walk the argument list looking for invalid BOZ.  */
  for (arg = expr->value.function.actual; arg; arg = arg->next)
    if (arg->expr && arg->expr->ts.type == BT_BOZ)
      {
	gfc_error ("A BOZ literal constant at %L cannot appear as an "
		   "actual argument in a function reference",
		   &arg->expr->where);
	return false;
      }

  temp = need_full_assumed_size;
  need_full_assumed_size = 0;

  if (!resolve_elemental_actual (expr, NULL))
    return false;

  if (omp_workshare_flag
      && expr->value.function.esym
      && ! gfc_elemental (expr->value.function.esym))
    {
      gfc_error ("User defined non-ELEMENTAL function %qs at %L not allowed "
		 "in WORKSHARE construct", expr->value.function.esym->name,
		 &expr->where);
      t = false;
    }

#define GENERIC_ID expr->value.function.isym->id
  else if (expr->value.function.actual != NULL
	   && expr->value.function.isym != NULL
	   && GENERIC_ID != GFC_ISYM_LBOUND
	   && GENERIC_ID != GFC_ISYM_LCOBOUND
	   && GENERIC_ID != GFC_ISYM_UCOBOUND
	   && GENERIC_ID != GFC_ISYM_LEN
	   && GENERIC_ID != GFC_ISYM_LOC
	   && GENERIC_ID != GFC_ISYM_C_LOC
	   && GENERIC_ID != GFC_ISYM_PRESENT)
    {
      /* Array intrinsics must also have the last upper bound of an
	 assumed size array argument.  UBOUND and SIZE have to be
	 excluded from the check if the second argument is anything
	 than a constant.  */

      for (arg = expr->value.function.actual; arg; arg = arg->next)
	{
	  if ((GENERIC_ID == GFC_ISYM_UBOUND || GENERIC_ID == GFC_ISYM_SIZE)
	      && arg == expr->value.function.actual
	      && arg->next != NULL && arg->next->expr)
	    {
	      if (arg->next->expr->expr_type != EXPR_CONSTANT)
		break;

	      if (arg->next->name && strcmp (arg->next->name, "kind") == 0)
		break;

	      if ((int)mpz_get_si (arg->next->expr->value.integer)
			< arg->expr->rank)
		break;
	    }

	  if (arg->expr != NULL
	      && arg->expr->rank > 0
	      && resolve_assumed_size_actual (arg->expr))
	    return false;
	}
    }
#undef GENERIC_ID

  need_full_assumed_size = temp;

  if (!check_pure_function(expr))
    t = false;

  /* Functions without the RECURSIVE attribution are not allowed to
   * call themselves.  */
  if (expr->value.function.esym && !expr->value.function.esym->attr.recursive)
    {
      gfc_symbol *esym;
      esym = expr->value.function.esym;

      if (is_illegal_recursion (esym, gfc_current_ns))
      {
	if (esym->attr.entry && esym->ns->entries)
	  gfc_error ("ENTRY %qs at %L cannot be called recursively, as"
		     " function %qs is not RECURSIVE",
		     esym->name, &expr->where, esym->ns->entries->sym->name);
	else
	  gfc_error ("Function %qs at %L cannot be called recursively, as it"
		     " is not RECURSIVE", esym->name, &expr->where);

	t = false;
      }
    }

  /* Character lengths of use associated functions may contains references to
     symbols not referenced from the current program unit otherwise.  Make sure
     those symbols are marked as referenced.  */

  if (expr->ts.type == BT_CHARACTER && expr->value.function.esym
      && expr->value.function.esym->attr.use_assoc)
    {
      gfc_expr_set_symbols_referenced (expr->ts.u.cl->length);
    }

  /* Make sure that the expression has a typespec that works.  */
  if (expr->ts.type == BT_UNKNOWN)
    {
      if (expr->symtree->n.sym->result
	    && expr->symtree->n.sym->result->ts.type != BT_UNKNOWN
	    && !expr->symtree->n.sym->result->attr.proc_pointer)
	expr->ts = expr->symtree->n.sym->result->ts;
    }

  if (!expr->ref && !expr->value.function.isym)
    {
      if (expr->value.function.esym)
	update_current_proc_array_outer_dependency (expr->value.function.esym);
      else
	update_current_proc_array_outer_dependency (sym);
    }
  else if (expr->ref)
    /* typebound procedure: Assume the worst.  */
    gfc_current_ns->proc_name->attr.array_outer_dependency = 1;

  if (expr->value.function.esym
      && expr->value.function.esym->attr.ext_attr & (1 << EXT_ATTR_DEPRECATED))
    gfc_warning (OPT_Wdeprecated_declarations,
		 "Using function %qs at %L is deprecated",
		 sym->name, &expr->where);
  return t;
}


/************* Subroutine resolution *************/

static bool
pure_subroutine (gfc_symbol *sym, const char *name, locus *loc)
{
  if (gfc_pure (sym))
    return true;

  if (forall_flag)
    {
      gfc_error ("Subroutine call to %qs in FORALL block at %L is not PURE",
		 name, loc);
      return false;
    }
  else if (gfc_do_concurrent_flag)
    {
      gfc_error ("Subroutine call to %qs in DO CONCURRENT block at %L is not "
		 "PURE", name, loc);
      return false;
    }
  else if (gfc_pure (NULL))
    {
      gfc_error ("Subroutine call to %qs at %L is not PURE", name, loc);
      return false;
    }

  gfc_unset_implicit_pure (NULL);
  return true;
}


static match
resolve_generic_s0 (gfc_code *c, gfc_symbol *sym)
{
  gfc_symbol *s;

  if (sym->attr.generic)
    {
      s = gfc_search_interface (sym->generic, 1, &c->ext.actual);
      if (s != NULL)
	{
	  c->resolved_sym = s;
	  if (!pure_subroutine (s, s->name, &c->loc))
	    return MATCH_ERROR;
	  return MATCH_YES;
	}

      /* TODO: Need to search for elemental references in generic interface.  */
    }

  if (sym->attr.intrinsic)
    return gfc_intrinsic_sub_interface (c, 0);

  return MATCH_NO;
}


static bool
resolve_generic_s (gfc_code *c)
{
  gfc_symbol *sym;
  match m;

  sym = c->symtree->n.sym;

  for (;;)
    {
      m = resolve_generic_s0 (c, sym);
      if (m == MATCH_YES)
	return true;
      else if (m == MATCH_ERROR)
	return false;

generic:
      if (sym->ns->parent == NULL)
	break;
      gfc_find_symbol (sym->name, sym->ns->parent, 1, &sym);

      if (sym == NULL)
	break;
      if (!generic_sym (sym))
	goto generic;
    }

  /* Last ditch attempt.  See if the reference is to an intrinsic
     that possesses a matching interface.  14.1.2.4  */
  sym = c->symtree->n.sym;

  if (!gfc_is_intrinsic (sym, 1, c->loc))
    {
      gfc_error ("There is no specific subroutine for the generic %qs at %L",
		 sym->name, &c->loc);
      return false;
    }

  m = gfc_intrinsic_sub_interface (c, 0);
  if (m == MATCH_YES)
    return true;
  if (m == MATCH_NO)
    gfc_error ("Generic subroutine %qs at %L is not consistent with an "
	       "intrinsic subroutine interface", sym->name, &c->loc);

  return false;
}


/* Resolve a subroutine call known to be specific.  */

static match
resolve_specific_s0 (gfc_code *c, gfc_symbol *sym)
{
  match m;

  if (sym->attr.external || sym->attr.if_source == IFSRC_IFBODY)
    {
      if (sym->attr.dummy)
	{
	  sym->attr.proc = PROC_DUMMY;
	  goto found;
	}

      sym->attr.proc = PROC_EXTERNAL;
      goto found;
    }

  if (sym->attr.proc == PROC_MODULE || sym->attr.proc == PROC_INTERNAL)
    goto found;

  if (sym->attr.intrinsic)
    {
      m = gfc_intrinsic_sub_interface (c, 1);
      if (m == MATCH_YES)
	return MATCH_YES;
      if (m == MATCH_NO)
	gfc_error ("Subroutine %qs at %L is INTRINSIC but is not compatible "
		   "with an intrinsic", sym->name, &c->loc);

      return MATCH_ERROR;
    }

  return MATCH_NO;

found:
  gfc_procedure_use (sym, &c->ext.actual, &c->loc);

  c->resolved_sym = sym;
  if (!pure_subroutine (sym, sym->name, &c->loc))
    return MATCH_ERROR;

  return MATCH_YES;
}


static bool
resolve_specific_s (gfc_code *c)
{
  gfc_symbol *sym;
  match m;

  sym = c->symtree->n.sym;

  for (;;)
    {
      m = resolve_specific_s0 (c, sym);
      if (m == MATCH_YES)
	return true;
      if (m == MATCH_ERROR)
	return false;

      if (sym->ns->parent == NULL)
	break;

      gfc_find_symbol (sym->name, sym->ns->parent, 1, &sym);

      if (sym == NULL)
	break;
    }

  sym = c->symtree->n.sym;
  gfc_error ("Unable to resolve the specific subroutine %qs at %L",
	     sym->name, &c->loc);

  return false;
}


/* Resolve a subroutine call not known to be generic nor specific.  */

static bool
resolve_unknown_s (gfc_code *c)
{
  gfc_symbol *sym;

  sym = c->symtree->n.sym;

  if (sym->attr.dummy)
    {
      sym->attr.proc = PROC_DUMMY;
      goto found;
    }

  /* See if we have an intrinsic function reference.  */

  if (gfc_is_intrinsic (sym, 1, c->loc))
    {
      if (gfc_intrinsic_sub_interface (c, 1) == MATCH_YES)
	return true;
      return false;
    }

  /* The reference is to an external name.  */

found:
  gfc_procedure_use (sym, &c->ext.actual, &c->loc);

  c->resolved_sym = sym;

  return pure_subroutine (sym, sym->name, &c->loc);
}


/* Resolve a subroutine call.  Although it was tempting to use the same code
   for functions, subroutines and functions are stored differently and this
   makes things awkward.  */

static bool
resolve_call (gfc_code *c)
{
  bool t;
  procedure_type ptype = PROC_INTRINSIC;
  gfc_symbol *csym, *sym;
  bool no_formal_args;

  csym = c->symtree ? c->symtree->n.sym : NULL;

  if (csym && csym->ts.type != BT_UNKNOWN)
    {
      gfc_error ("%qs at %L has a type, which is not consistent with "
		 "the CALL at %L", csym->name, &csym->declared_at, &c->loc);
      return false;
    }

  if (csym && gfc_current_ns->parent && csym->ns != gfc_current_ns)
    {
      gfc_symtree *st;
      gfc_find_sym_tree (c->symtree->name, gfc_current_ns, 1, &st);
      sym = st ? st->n.sym : NULL;
      if (sym && csym != sym
	      && sym->ns == gfc_current_ns
	      && sym->attr.flavor == FL_PROCEDURE
	      && sym->attr.contained)
	{
	  sym->refs++;
	  if (csym->attr.generic)
	    c->symtree->n.sym = sym;
	  else
	    c->symtree = st;
	  csym = c->symtree->n.sym;
	}
    }

  /* If this ia a deferred TBP, c->expr1 will be set.  */
  if (!c->expr1 && csym)
    {
      if (csym->attr.abstract)
	{
	  gfc_error ("ABSTRACT INTERFACE %qs must not be referenced at %L",
		    csym->name, &c->loc);
	  return false;
	}

      /* Subroutines without the RECURSIVE attribution are not allowed to
	 call themselves.  */
      if (is_illegal_recursion (csym, gfc_current_ns))
	{
	  if (csym->attr.entry && csym->ns->entries)
	    gfc_error ("ENTRY %qs at %L cannot be called recursively, "
		       "as subroutine %qs is not RECURSIVE",
		       csym->name, &c->loc, csym->ns->entries->sym->name);
	  else
	    gfc_error ("SUBROUTINE %qs at %L cannot be called recursively, "
		       "as it is not RECURSIVE", csym->name, &c->loc);

	  t = false;
	}
    }

  /* Switch off assumed size checking and do this again for certain kinds
     of procedure, once the procedure itself is resolved.  */
  need_full_assumed_size++;

  if (csym)
    ptype = csym->attr.proc;

  no_formal_args = csym && is_external_proc (csym)
			&& gfc_sym_get_dummy_args (csym) == NULL;
  if (!resolve_actual_arglist (c->ext.actual, ptype, no_formal_args))
    return false;

  /* Resume assumed_size checking.  */
  need_full_assumed_size--;

  /* If external, check for usage.  */
  if (csym && is_external_proc (csym))
    resolve_global_procedure (csym, &c->loc, 1);

  t = true;
  if (c->resolved_sym == NULL)
    {
      c->resolved_isym = NULL;
      switch (procedure_kind (csym))
	{
	case PTYPE_GENERIC:
	  t = resolve_generic_s (c);
	  break;

	case PTYPE_SPECIFIC:
	  t = resolve_specific_s (c);
	  break;

	case PTYPE_UNKNOWN:
	  t = resolve_unknown_s (c);
	  break;

	default:
	  gfc_internal_error ("resolve_subroutine(): bad function type");
	}
    }

  /* Some checks of elemental subroutine actual arguments.  */
  if (!resolve_elemental_actual (NULL, c))
    return false;

  if (!c->expr1)
    update_current_proc_array_outer_dependency (csym);
  else
    /* Typebound procedure: Assume the worst.  */
    gfc_current_ns->proc_name->attr.array_outer_dependency = 1;

  if (c->resolved_sym
      && c->resolved_sym->attr.ext_attr & (1 << EXT_ATTR_DEPRECATED))
    gfc_warning (OPT_Wdeprecated_declarations,
		 "Using subroutine %qs at %L is deprecated",
		 c->resolved_sym->name, &c->loc);

  return t;
}


/* Compare the shapes of two arrays that have non-NULL shapes.  If both
   op1->shape and op2->shape are non-NULL return true if their shapes
   match.  If both op1->shape and op2->shape are non-NULL return false
   if their shapes do not match.  If either op1->shape or op2->shape is
   NULL, return true.  */

static bool
compare_shapes (gfc_expr *op1, gfc_expr *op2)
{
  bool t;
  int i;

  t = true;

  if (op1->shape != NULL && op2->shape != NULL)
    {
      for (i = 0; i < op1->rank; i++)
	{
	  if (mpz_cmp (op1->shape[i], op2->shape[i]) != 0)
	   {
	     gfc_error ("Shapes for operands at %L and %L are not conformable",
			&op1->where, &op2->where);
	     t = false;
	     break;
	   }
	}
    }

  return t;
}

/* Convert a logical operator to the corresponding bitwise intrinsic call.
   For example A .AND. B becomes IAND(A, B).  */
static gfc_expr *
logical_to_bitwise (gfc_expr *e)
{
  gfc_expr *tmp, *op1, *op2;
  gfc_isym_id isym;
  gfc_actual_arglist *args = NULL;

  gcc_assert (e->expr_type == EXPR_OP);

  isym = GFC_ISYM_NONE;
  op1 = e->value.op.op1;
  op2 = e->value.op.op2;

  switch (e->value.op.op)
    {
    case INTRINSIC_NOT:
      isym = GFC_ISYM_NOT;
      break;
    case INTRINSIC_AND:
      isym = GFC_ISYM_IAND;
      break;
    case INTRINSIC_OR:
      isym = GFC_ISYM_IOR;
      break;
    case INTRINSIC_NEQV:
      isym = GFC_ISYM_IEOR;
      break;
    case INTRINSIC_EQV:
      /* "Bitwise eqv" is just the complement of NEQV === IEOR.
	 Change the old expression to NEQV, which will get replaced by IEOR,
	 and wrap it in NOT.  */
      tmp = gfc_copy_expr (e);
      tmp->value.op.op = INTRINSIC_NEQV;
      tmp = logical_to_bitwise (tmp);
      isym = GFC_ISYM_NOT;
      op1 = tmp;
      op2 = NULL;
      break;
    default:
      gfc_internal_error ("logical_to_bitwise(): Bad intrinsic");
    }

  /* Inherit the original operation's operands as arguments.  */
  args = gfc_get_actual_arglist ();
  args->expr = op1;
  if (op2)
    {
      args->next = gfc_get_actual_arglist ();
      args->next->expr = op2;
    }

  /* Convert the expression to a function call.  */
  e->expr_type = EXPR_FUNCTION;
  e->value.function.actual = args;
  e->value.function.isym = gfc_intrinsic_function_by_id (isym);
  e->value.function.name = e->value.function.isym->name;
  e->value.function.esym = NULL;

  /* Make up a pre-resolved function call symtree if we need to.  */
  if (!e->symtree || !e->symtree->n.sym)
    {
      gfc_symbol *sym;
      gfc_get_ha_sym_tree (e->value.function.isym->name, &e->symtree);
      sym = e->symtree->n.sym;
      sym->result = sym;
      sym->attr.flavor = FL_PROCEDURE;
      sym->attr.function = 1;
      sym->attr.elemental = 1;
      sym->attr.pure = 1;
      sym->attr.referenced = 1;
      gfc_intrinsic_symbol (sym);
      gfc_commit_symbol (sym);
    }

  args->name = e->value.function.isym->formal->name;
  if (e->value.function.isym->formal->next)
    args->next->name = e->value.function.isym->formal->next->name;

  return e;
}

/* Recursively append candidate UOP to CANDIDATES.  Store the number of
   candidates in CANDIDATES_LEN.  */
static void
lookup_uop_fuzzy_find_candidates (gfc_symtree *uop,
				  char **&candidates,
				  size_t &candidates_len)
{
  gfc_symtree *p;

  if (uop == NULL)
    return;

  /* Not sure how to properly filter here.  Use all for a start.
     n.uop.op is NULL for empty interface operators (is that legal?) disregard
     these as i suppose they don't make terribly sense.  */

  if (uop->n.uop->op != NULL)
    vec_push (candidates, candidates_len, uop->name);

  p = uop->left;
  if (p)
    lookup_uop_fuzzy_find_candidates (p, candidates, candidates_len);

  p = uop->right;
  if (p)
    lookup_uop_fuzzy_find_candidates (p, candidates, candidates_len);
}

/* Lookup user-operator OP fuzzily, taking names in UOP into account.  */

static const char*
lookup_uop_fuzzy (const char *op, gfc_symtree *uop)
{
  char **candidates = NULL;
  size_t candidates_len = 0;
  lookup_uop_fuzzy_find_candidates (uop, candidates, candidates_len);
  return gfc_closest_fuzzy_match (op, candidates);
}


/* Callback finding an impure function as an operand to an .and. or
   .or.  expression.  Remember the last function warned about to
   avoid double warnings when recursing.  */

static int
impure_function_callback (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
			  void *data)
{
  gfc_expr *f = *e;
  const char *name;
  static gfc_expr *last = NULL;
  bool *found = (bool *) data;

  if (f->expr_type == EXPR_FUNCTION)
    {
      *found = 1;
      if (f != last && !gfc_pure_function (f, &name)
	  && !gfc_implicit_pure_function (f))
	{
	  if (name)
	    gfc_warning (OPT_Wfunction_elimination,
			 "Impure function %qs at %L might not be evaluated",
			 name, &f->where);
	  else
	    gfc_warning (OPT_Wfunction_elimination,
			 "Impure function at %L might not be evaluated",
			 &f->where);
	}
      last = f;
    }

  return 0;
}

/* Return true if TYPE is character based, false otherwise.  */

static int
is_character_based (bt type)
{
  return type == BT_CHARACTER || type == BT_HOLLERITH;
}


/* If expression is a hollerith, convert it to character and issue a warning
   for the conversion.  */

static void
convert_hollerith_to_character (gfc_expr *e)
{
  if (e->ts.type == BT_HOLLERITH)
    {
      gfc_typespec t;
      gfc_clear_ts (&t);
      t.type = BT_CHARACTER;
      t.kind = e->ts.kind;
      gfc_convert_type_warn (e, &t, 2, 1);
    }
}

/* Convert to numeric and issue a warning for the conversion.  */

static void
convert_to_numeric (gfc_expr *a, gfc_expr *b)
{
  gfc_typespec t;
  gfc_clear_ts (&t);
  t.type = b->ts.type;
  t.kind = b->ts.kind;
  gfc_convert_type_warn (a, &t, 2, 1);
}

/* Resolve an operator expression node.  This can involve replacing the
   operation with a user defined function call.  */

static bool
resolve_operator (gfc_expr *e)
{
  gfc_expr *op1, *op2;
  /* One error uses 3 names; additional space for wording (also via gettext). */
  char msg[3*GFC_MAX_SYMBOL_LEN + 1 + 50];
  bool dual_locus_error;
  bool t = true;

  /* Resolve all subnodes-- give them types.  */

  switch (e->value.op.op)
    {
    default:
      if (!gfc_resolve_expr (e->value.op.op2))
	return false;

    /* Fall through.  */

    case INTRINSIC_NOT:
    case INTRINSIC_UPLUS:
    case INTRINSIC_UMINUS:
    case INTRINSIC_PARENTHESES:
      if (!gfc_resolve_expr (e->value.op.op1))
	return false;
      if (e->value.op.op1
	  && e->value.op.op1->ts.type == BT_BOZ && !e->value.op.op2)
	{
	  gfc_error ("BOZ literal constant at %L cannot be an operand of "
		     "unary operator %qs", &e->value.op.op1->where,
		     gfc_op2string (e->value.op.op));
	  return false;
	}
      break;
    }

  /* Typecheck the new node.  */

  op1 = e->value.op.op1;
  op2 = e->value.op.op2;
  if (op1 == NULL && op2 == NULL)
    return false;

  dual_locus_error = false;

  /* op1 and op2 cannot both be BOZ.  */
  if (op1 && op1->ts.type == BT_BOZ
      && op2 && op2->ts.type == BT_BOZ)
    {
      gfc_error ("Operands at %L and %L cannot appear as operands of "
		 "binary operator %qs", &op1->where, &op2->where,
		 gfc_op2string (e->value.op.op));
      return false;
    }

  if ((op1 && op1->expr_type == EXPR_NULL)
      || (op2 && op2->expr_type == EXPR_NULL))
    {
      snprintf (msg, sizeof (msg),
		_("Invalid context for NULL() pointer at %%L"));
      goto bad_op;
    }

  switch (e->value.op.op)
    {
    case INTRINSIC_UPLUS:
    case INTRINSIC_UMINUS:
      if (op1->ts.type == BT_INTEGER
	  || op1->ts.type == BT_REAL
	  || op1->ts.type == BT_COMPLEX)
	{
	  e->ts = op1->ts;
	  break;
	}

      snprintf (msg, sizeof (msg),
		_("Operand of unary numeric operator %%<%s%%> at %%L is %s"),
		gfc_op2string (e->value.op.op), gfc_typename (e));
      goto bad_op;

    case INTRINSIC_PLUS:
    case INTRINSIC_MINUS:
    case INTRINSIC_TIMES:
    case INTRINSIC_DIVIDE:
    case INTRINSIC_POWER:
      if (gfc_numeric_ts (&op1->ts) && gfc_numeric_ts (&op2->ts))
	{
	  gfc_type_convert_binary (e, 1);
	  break;
	}

      if (op1->ts.type == BT_DERIVED || op2->ts.type == BT_DERIVED)
	snprintf (msg, sizeof (msg),
		  _("Unexpected derived-type entities in binary intrinsic "
		  "numeric operator %%<%s%%> at %%L"),
	       gfc_op2string (e->value.op.op));
      else
	snprintf (msg, sizeof(msg),
		  _("Operands of binary numeric operator %%<%s%%> at %%L are %s/%s"),
		  gfc_op2string (e->value.op.op), gfc_typename (op1),
	       gfc_typename (op2));
      goto bad_op;

    case INTRINSIC_CONCAT:
      if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
	  && op1->ts.kind == op2->ts.kind)
	{
	  e->ts.type = BT_CHARACTER;
	  e->ts.kind = op1->ts.kind;
	  break;
	}

      snprintf (msg, sizeof (msg),
		_("Operands of string concatenation operator at %%L are %s/%s"),
		gfc_typename (op1), gfc_typename (op2));
      goto bad_op;

    case INTRINSIC_AND:
    case INTRINSIC_OR:
    case INTRINSIC_EQV:
    case INTRINSIC_NEQV:
      if (op1->ts.type == BT_LOGICAL && op2->ts.type == BT_LOGICAL)
	{
	  e->ts.type = BT_LOGICAL;
	  e->ts.kind = gfc_kind_max (op1, op2);
	  if (op1->ts.kind < e->ts.kind)
	    gfc_convert_type (op1, &e->ts, 2);
	  else if (op2->ts.kind < e->ts.kind)
	    gfc_convert_type (op2, &e->ts, 2);

	  if (flag_frontend_optimize &&
	    (e->value.op.op == INTRINSIC_AND || e->value.op.op == INTRINSIC_OR))
	    {
	      /* Warn about short-circuiting
	         with impure function as second operand.  */
	      bool op2_f = false;
	      gfc_expr_walker (&op2, impure_function_callback, &op2_f);
	    }
	  break;
	}

      /* Logical ops on integers become bitwise ops with -fdec.  */
      else if (flag_dec
	       && (op1->ts.type == BT_INTEGER || op2->ts.type == BT_INTEGER))
	{
	  e->ts.type = BT_INTEGER;
	  e->ts.kind = gfc_kind_max (op1, op2);
	  if (op1->ts.type != e->ts.type || op1->ts.kind != e->ts.kind)
	    gfc_convert_type (op1, &e->ts, 1);
	  if (op2->ts.type != e->ts.type || op2->ts.kind != e->ts.kind)
	    gfc_convert_type (op2, &e->ts, 1);
	  e = logical_to_bitwise (e);
	  goto simplify_op;
	}

      snprintf (msg, sizeof (msg),
		_("Operands of logical operator %%<%s%%> at %%L are %s/%s"),
		gfc_op2string (e->value.op.op), gfc_typename (op1),
		gfc_typename (op2));

      goto bad_op;

    case INTRINSIC_NOT:
      /* Logical ops on integers become bitwise ops with -fdec.  */
      if (flag_dec && op1->ts.type == BT_INTEGER)
	{
	  e->ts.type = BT_INTEGER;
	  e->ts.kind = op1->ts.kind;
	  e = logical_to_bitwise (e);
	  goto simplify_op;
	}

      if (op1->ts.type == BT_LOGICAL)
	{
	  e->ts.type = BT_LOGICAL;
	  e->ts.kind = op1->ts.kind;
	  break;
	}

      snprintf (msg, sizeof (msg), _("Operand of .not. operator at %%L is %s"),
		gfc_typename (op1));
      goto bad_op;

    case INTRINSIC_GT:
    case INTRINSIC_GT_OS:
    case INTRINSIC_GE:
    case INTRINSIC_GE_OS:
    case INTRINSIC_LT:
    case INTRINSIC_LT_OS:
    case INTRINSIC_LE:
    case INTRINSIC_LE_OS:
      if (op1->ts.type == BT_COMPLEX || op2->ts.type == BT_COMPLEX)
	{
	  strcpy (msg, _("COMPLEX quantities cannot be compared at %L"));
	  goto bad_op;
	}

      /* Fall through.  */

    case INTRINSIC_EQ:
    case INTRINSIC_EQ_OS:
    case INTRINSIC_NE:
    case INTRINSIC_NE_OS:

      if (flag_dec
	  && is_character_based (op1->ts.type)
	  && is_character_based (op2->ts.type))
	{
	  convert_hollerith_to_character (op1);
	  convert_hollerith_to_character (op2);
	}

      if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
	  && op1->ts.kind == op2->ts.kind)
	{
	  e->ts.type = BT_LOGICAL;
	  e->ts.kind = gfc_default_logical_kind;
	  break;
	}

      /* If op1 is BOZ, then op2 is not!.  Try to convert to type of op2.  */
      if (op1->ts.type == BT_BOZ)
	{
	  if (gfc_invalid_boz (G_("BOZ literal constant near %L cannot appear "
			       "as an operand of a relational operator"),
			       &op1->where))
	    return false;

	  if (op2->ts.type == BT_INTEGER && !gfc_boz2int (op1, op2->ts.kind))
	    return false;

	  if (op2->ts.type == BT_REAL && !gfc_boz2real (op1, op2->ts.kind))
	    return false;
	}

      /* If op2 is BOZ, then op1 is not!.  Try to convert to type of op2. */
      if (op2->ts.type == BT_BOZ)
	{
	  if (gfc_invalid_boz (G_("BOZ literal constant near %L cannot appear"
			       " as an operand of a relational operator"),
				&op2->where))
	    return false;

	  if (op1->ts.type == BT_INTEGER && !gfc_boz2int (op2, op1->ts.kind))
	    return false;

	  if (op1->ts.type == BT_REAL && !gfc_boz2real (op2, op1->ts.kind))
	    return false;
	}
      if (flag_dec
	  && op1->ts.type == BT_HOLLERITH && gfc_numeric_ts (&op2->ts))
	convert_to_numeric (op1, op2);

      if (flag_dec
	  && gfc_numeric_ts (&op1->ts) && op2->ts.type == BT_HOLLERITH)
	convert_to_numeric (op2, op1);

      if (gfc_numeric_ts (&op1->ts) && gfc_numeric_ts (&op2->ts))
	{
	  gfc_type_convert_binary (e, 1);

	  e->ts.type = BT_LOGICAL;
	  e->ts.kind = gfc_default_logical_kind;

	  if (warn_compare_reals)
	    {
	      gfc_intrinsic_op op = e->value.op.op;

	      /* Type conversion has made sure that the types of op1 and op2
		 agree, so it is only necessary to check the first one.   */
	      if ((op1->ts.type == BT_REAL || op1->ts.type == BT_COMPLEX)
		  && (op == INTRINSIC_EQ || op == INTRINSIC_EQ_OS
		      || op == INTRINSIC_NE || op == INTRINSIC_NE_OS))
		{
		  const char *msg;

		  if (op == INTRINSIC_EQ || op == INTRINSIC_EQ_OS)
		    msg = G_("Equality comparison for %s at %L");
		  else
		    msg = G_("Inequality comparison for %s at %L");

		  gfc_warning (OPT_Wcompare_reals, msg,
			       gfc_typename (op1), &op1->where);
		}
	    }

	  break;
	}

      if (op1->ts.type == BT_LOGICAL && op2->ts.type == BT_LOGICAL)
	snprintf (msg, sizeof (msg),
		  _("Logicals at %%L must be compared with %s instead of %s"),
		  (e->value.op.op == INTRINSIC_EQ
		   || e->value.op.op == INTRINSIC_EQ_OS)
		  ? ".eqv." : ".neqv.", gfc_op2string (e->value.op.op));
      else
	snprintf (msg, sizeof (msg),
		  _("Operands of comparison operator %%<%s%%> at %%L are %s/%s"),
		  gfc_op2string (e->value.op.op), gfc_typename (op1),
		  gfc_typename (op2));

      goto bad_op;

    case INTRINSIC_USER:
      if (e->value.op.uop->op == NULL)
	{
	  const char *name = e->value.op.uop->name;
	  const char *guessed;
	  guessed = lookup_uop_fuzzy (name, e->value.op.uop->ns->uop_root);
	  if (guessed)
	    snprintf (msg, sizeof (msg),
		      _("Unknown operator %%<%s%%> at %%L; did you mean '%s'?"),
		      name, guessed);
	  else
	    snprintf (msg, sizeof (msg), _("Unknown operator %%<%s%%> at %%L"),
		      name);
	}
      else if (op2 == NULL)
	snprintf (msg, sizeof (msg),
		  _("Operand of user operator %%<%s%%> at %%L is %s"),
		  e->value.op.uop->name, gfc_typename (op1));
      else
	{
	  snprintf (msg, sizeof (msg),
		    _("Operands of user operator %%<%s%%> at %%L are %s/%s"),
		    e->value.op.uop->name, gfc_typename (op1),
		    gfc_typename (op2));
	  e->value.op.uop->op->sym->attr.referenced = 1;
	}

      goto bad_op;

    case INTRINSIC_PARENTHESES:
      e->ts = op1->ts;
      if (e->ts.type == BT_CHARACTER)
	e->ts.u.cl = op1->ts.u.cl;
      break;

    default:
      gfc_internal_error ("resolve_operator(): Bad intrinsic");
    }

  /* Deal with arrayness of an operand through an operator.  */

  switch (e->value.op.op)
    {
    case INTRINSIC_PLUS:
    case INTRINSIC_MINUS:
    case INTRINSIC_TIMES:
    case INTRINSIC_DIVIDE:
    case INTRINSIC_POWER:
    case INTRINSIC_CONCAT:
    case INTRINSIC_AND:
    case INTRINSIC_OR:
    case INTRINSIC_EQV:
    case INTRINSIC_NEQV:
    case INTRINSIC_EQ:
    case INTRINSIC_EQ_OS:
    case INTRINSIC_NE:
    case INTRINSIC_NE_OS:
    case INTRINSIC_GT:
    case INTRINSIC_GT_OS:
    case INTRINSIC_GE:
    case INTRINSIC_GE_OS:
    case INTRINSIC_LT:
    case INTRINSIC_LT_OS:
    case INTRINSIC_LE:
    case INTRINSIC_LE_OS:

      if (op1->rank == 0 && op2->rank == 0)
	e->rank = 0;

      if (op1->rank == 0 && op2->rank != 0)
	{
	  e->rank = op2->rank;

	  if (e->shape == NULL)
	    e->shape = gfc_copy_shape (op2->shape, op2->rank);
	}

      if (op1->rank != 0 && op2->rank == 0)
	{
	  e->rank = op1->rank;

	  if (e->shape == NULL)
	    e->shape = gfc_copy_shape (op1->shape, op1->rank);
	}

      if (op1->rank != 0 && op2->rank != 0)
	{
	  if (op1->rank == op2->rank)
	    {
	      e->rank = op1->rank;
	      if (e->shape == NULL)
		{
		  t = compare_shapes (op1, op2);
		  if (!t)
		    e->shape = NULL;
		  else
		    e->shape = gfc_copy_shape (op1->shape, op1->rank);
		}
	    }
	  else
	    {
	      /* Allow higher level expressions to work.  */
	      e->rank = 0;

	      /* Try user-defined operators, and otherwise throw an error.  */
	      dual_locus_error = true;
	      snprintf (msg, sizeof (msg),
			_("Inconsistent ranks for operator at %%L and %%L"));
	      goto bad_op;
	    }
	}

      break;

    case INTRINSIC_PARENTHESES:
    case INTRINSIC_NOT:
    case INTRINSIC_UPLUS:
    case INTRINSIC_UMINUS:
      /* Simply copy arrayness attribute */
      e->rank = op1->rank;

      if (e->shape == NULL)
	e->shape = gfc_copy_shape (op1->shape, op1->rank);

      break;

    default:
      break;
    }

simplify_op:

  /* Attempt to simplify the expression.  */
  if (t)
    {
      t = gfc_simplify_expr (e, 0);
      /* Some calls do not succeed in simplification and return false
	 even though there is no error; e.g. variable references to
	 PARAMETER arrays.  */
      if (!gfc_is_constant_expr (e))
	t = true;
    }
  return t;

bad_op:

  {
    match m = gfc_extend_expr (e);
    if (m == MATCH_YES)
      return true;
    if (m == MATCH_ERROR)
      return false;
  }

  if (dual_locus_error)
    gfc_error (msg, &op1->where, &op2->where);
  else
    gfc_error (msg, &e->where);

  return false;
}


/************** Array resolution subroutines **************/

enum compare_result
{ CMP_LT, CMP_EQ, CMP_GT, CMP_UNKNOWN };

/* Compare two integer expressions.  */

static compare_result
compare_bound (gfc_expr *a, gfc_expr *b)
{
  int i;

  if (a == NULL || a->expr_type != EXPR_CONSTANT
      || b == NULL || b->expr_type != EXPR_CONSTANT)
    return CMP_UNKNOWN;

  /* If either of the types isn't INTEGER, we must have
     raised an error earlier.  */

  if (a->ts.type != BT_INTEGER || b->ts.type != BT_INTEGER)
    return CMP_UNKNOWN;

  i = mpz_cmp (a->value.integer, b->value.integer);

  if (i < 0)
    return CMP_LT;
  if (i > 0)
    return CMP_GT;
  return CMP_EQ;
}


/* Compare an integer expression with an integer.  */

static compare_result
compare_bound_int (gfc_expr *a, int b)
{
  int i;

  if (a == NULL || a->expr_type != EXPR_CONSTANT)
    return CMP_UNKNOWN;

  if (a->ts.type != BT_INTEGER)
    gfc_internal_error ("compare_bound_int(): Bad expression");

  i = mpz_cmp_si (a->value.integer, b);

  if (i < 0)
    return CMP_LT;
  if (i > 0)
    return CMP_GT;
  return CMP_EQ;
}


/* Compare an integer expression with a mpz_t.  */

static compare_result
compare_bound_mpz_t (gfc_expr *a, mpz_t b)
{
  int i;

  if (a == NULL || a->expr_type != EXPR_CONSTANT)
    return CMP_UNKNOWN;

  if (a->ts.type != BT_INTEGER)
    gfc_internal_error ("compare_bound_int(): Bad expression");

  i = mpz_cmp (a->value.integer, b);

  if (i < 0)
    return CMP_LT;
  if (i > 0)
    return CMP_GT;
  return CMP_EQ;
}


/* Compute the last value of a sequence given by a triplet.
   Return 0 if it wasn't able to compute the last value, or if the
   sequence if empty, and 1 otherwise.  */

static int
compute_last_value_for_triplet (gfc_expr *start, gfc_expr *end,
				gfc_expr *stride, mpz_t last)
{
  mpz_t rem;

  if (start == NULL || start->expr_type != EXPR_CONSTANT
      || end == NULL || end->expr_type != EXPR_CONSTANT
      || (stride != NULL && stride->expr_type != EXPR_CONSTANT))
    return 0;

  if (start->ts.type != BT_INTEGER || end->ts.type != BT_INTEGER
      || (stride != NULL && stride->ts.type != BT_INTEGER))
    return 0;

  if (stride == NULL || compare_bound_int (stride, 1) == CMP_EQ)
    {
      if (compare_bound (start, end) == CMP_GT)
	return 0;
      mpz_set (last, end->value.integer);
      return 1;
    }

  if (compare_bound_int (stride, 0) == CMP_GT)
    {
      /* Stride is positive */
      if (mpz_cmp (start->value.integer, end->value.integer) > 0)
	return 0;
    }
  else
    {
      /* Stride is negative */
      if (mpz_cmp (start->value.integer, end->value.integer) < 0)
	return 0;
    }

  mpz_init (rem);
  mpz_sub (rem, end->value.integer, start->value.integer);
  mpz_tdiv_r (rem, rem, stride->value.integer);
  mpz_sub (last, end->value.integer, rem);
  mpz_clear (rem);

  return 1;
}


/* Compare a single dimension of an array reference to the array
   specification.  */

static bool
check_dimension (int i, gfc_array_ref *ar, gfc_array_spec *as)
{
  mpz_t last_value;

  if (ar->dimen_type[i] == DIMEN_STAR)
    {
      gcc_assert (ar->stride[i] == NULL);
      /* This implies [*] as [*:] and [*:3] are not possible.  */
      if (ar->start[i] == NULL)
	{
	  gcc_assert (ar->end[i] == NULL);
	  return true;
	}
    }

/* Given start, end and stride values, calculate the minimum and
   maximum referenced indexes.  */

  switch (ar->dimen_type[i])
    {
    case DIMEN_VECTOR:
    case DIMEN_THIS_IMAGE:
      break;

    case DIMEN_STAR:
    case DIMEN_ELEMENT:
      if (compare_bound (ar->start[i], as->lower[i]) == CMP_LT)
	{
	  if (i < as->rank)
	    gfc_warning (0, "Array reference at %L is out of bounds "
			 "(%ld < %ld) in dimension %d", &ar->c_where[i],
			 mpz_get_si (ar->start[i]->value.integer),
			 mpz_get_si (as->lower[i]->value.integer), i+1);
	  else
	    gfc_warning (0, "Array reference at %L is out of bounds "
			 "(%ld < %ld) in codimension %d", &ar->c_where[i],
			 mpz_get_si (ar->start[i]->value.integer),
			 mpz_get_si (as->lower[i]->value.integer),
			 i + 1 - as->rank);
	  return true;
	}
      if (compare_bound (ar->start[i], as->upper[i]) == CMP_GT)
	{
	  if (i < as->rank)
	    gfc_warning (0, "Array reference at %L is out of bounds "
			 "(%ld > %ld) in dimension %d", &ar->c_where[i],
			 mpz_get_si (ar->start[i]->value.integer),
			 mpz_get_si (as->upper[i]->value.integer), i+1);
	  else
	    gfc_warning (0, "Array reference at %L is out of bounds "
			 "(%ld > %ld) in codimension %d", &ar->c_where[i],
			 mpz_get_si (ar->start[i]->value.integer),
			 mpz_get_si (as->upper[i]->value.integer),
			 i + 1 - as->rank);
	  return true;
	}

      break;

    case DIMEN_RANGE:
      {
#define AR_START (ar->start[i] ? ar->start[i] : as->lower[i])
#define AR_END (ar->end[i] ? ar->end[i] : as->upper[i])

	compare_result comp_start_end = compare_bound (AR_START, AR_END);

	/* Check for zero stride, which is not allowed.  */
	if (compare_bound_int (ar->stride[i], 0) == CMP_EQ)
	  {
	    gfc_error ("Illegal stride of zero at %L", &ar->c_where[i]);
	    return false;
	  }

	/* if start == len || (stride > 0 && start < len)
			   || (stride < 0 && start > len),
	   then the array section contains at least one element.  In this
	   case, there is an out-of-bounds access if
	   (start < lower || start > upper).  */
	if (compare_bound (AR_START, AR_END) == CMP_EQ
	    || ((compare_bound_int (ar->stride[i], 0) == CMP_GT
		 || ar->stride[i] == NULL) && comp_start_end == CMP_LT)
	    || (compare_bound_int (ar->stride[i], 0) == CMP_LT
	        && comp_start_end == CMP_GT))
	  {
	    if (compare_bound (AR_START, as->lower[i]) == CMP_LT)
	      {
		gfc_warning (0, "Lower array reference at %L is out of bounds "
		       "(%ld < %ld) in dimension %d", &ar->c_where[i],
		       mpz_get_si (AR_START->value.integer),
		       mpz_get_si (as->lower[i]->value.integer), i+1);
		return true;
	      }
	    if (compare_bound (AR_START, as->upper[i]) == CMP_GT)
	      {
		gfc_warning (0, "Lower array reference at %L is out of bounds "
		       "(%ld > %ld) in dimension %d", &ar->c_where[i],
		       mpz_get_si (AR_START->value.integer),
		       mpz_get_si (as->upper[i]->value.integer), i+1);
		return true;
	      }
	  }

	/* If we can compute the highest index of the array section,
	   then it also has to be between lower and upper.  */
	mpz_init (last_value);
	if (compute_last_value_for_triplet (AR_START, AR_END, ar->stride[i],
					    last_value))
	  {
	    if (compare_bound_mpz_t (as->lower[i], last_value) == CMP_GT)
	      {
		gfc_warning (0, "Upper array reference at %L is out of bounds "
		       "(%ld < %ld) in dimension %d", &ar->c_where[i],
		       mpz_get_si (last_value),
		       mpz_get_si (as->lower[i]->value.integer), i+1);
	        mpz_clear (last_value);
		return true;
	      }
	    if (compare_bound_mpz_t (as->upper[i], last_value) == CMP_LT)
	      {
		gfc_warning (0, "Upper array reference at %L is out of bounds "
		       "(%ld > %ld) in dimension %d", &ar->c_where[i],
		       mpz_get_si (last_value),
		       mpz_get_si (as->upper[i]->value.integer), i+1);
	        mpz_clear (last_value);
		return true;
	      }
	  }
	mpz_clear (last_value);

#undef AR_START
#undef AR_END
      }
      break;

    default:
      gfc_internal_error ("check_dimension(): Bad array reference");
    }

  return true;
}


/* Compare an array reference with an array specification.  */

static bool
compare_spec_to_ref (gfc_array_ref *ar)
{
  gfc_array_spec *as;
  int i;

  as = ar->as;
  i = as->rank - 1;
  /* TODO: Full array sections are only allowed as actual parameters.  */
  if (as->type == AS_ASSUMED_SIZE
      && (/*ar->type == AR_FULL
	  ||*/ (ar->type == AR_SECTION
	      && ar->dimen_type[i] == DIMEN_RANGE && ar->end[i] == NULL)))
    {
      gfc_error ("Rightmost upper bound of assumed size array section "
		 "not specified at %L", &ar->where);
      return false;
    }

  if (ar->type == AR_FULL)
    return true;

  if (as->rank != ar->dimen)
    {
      gfc_error ("Rank mismatch in array reference at %L (%d/%d)",
		 &ar->where, ar->dimen, as->rank);
      return false;
    }

  /* ar->codimen == 0 is a local array.  */
  if (as->corank != ar->codimen && ar->codimen != 0)
    {
      gfc_error ("Coindex rank mismatch in array reference at %L (%d/%d)",
		 &ar->where, ar->codimen, as->corank);
      return false;
    }

  for (i = 0; i < as->rank; i++)
    if (!check_dimension (i, ar, as))
      return false;

  /* Local access has no coarray spec.  */
  if (ar->codimen != 0)
    for (i = as->rank; i < as->rank + as->corank; i++)
      {
	if (ar->dimen_type[i] != DIMEN_ELEMENT && !ar->in_allocate
	    && ar->dimen_type[i] != DIMEN_THIS_IMAGE)
	  {
	    gfc_error ("Coindex of codimension %d must be a scalar at %L",
		       i + 1 - as->rank, &ar->where);
	    return false;
	  }
	if (!check_dimension (i, ar, as))
	  return false;
      }

  return true;
}


/* Resolve one part of an array index.  */

static bool
gfc_resolve_index_1 (gfc_expr *index, int check_scalar,
		     int force_index_integer_kind)
{
  gfc_typespec ts;

  if (index == NULL)
    return true;

  if (!gfc_resolve_expr (index))
    return false;

  if (check_scalar && index->rank != 0)
    {
      gfc_error ("Array index at %L must be scalar", &index->where);
      return false;
    }

  if (index->ts.type != BT_INTEGER && index->ts.type != BT_REAL)
    {
      gfc_error ("Array index at %L must be of INTEGER type, found %s",
		 &index->where, gfc_basic_typename (index->ts.type));
      return false;
    }

  if (index->ts.type == BT_REAL)
    if (!gfc_notify_std (GFC_STD_LEGACY, "REAL array index at %L",
			 &index->where))
      return false;

  if ((index->ts.kind != gfc_index_integer_kind
       && force_index_integer_kind)
      || index->ts.type != BT_INTEGER)
    {
      gfc_clear_ts (&ts);
      ts.type = BT_INTEGER;
      ts.kind = gfc_index_integer_kind;

      gfc_convert_type_warn (index, &ts, 2, 0);
    }

  return true;
}

/* Resolve one part of an array index.  */

bool
gfc_resolve_index (gfc_expr *index, int check_scalar)
{
  return gfc_resolve_index_1 (index, check_scalar, 1);
}

/* Resolve a dim argument to an intrinsic function.  */

bool
gfc_resolve_dim_arg (gfc_expr *dim)
{
  if (dim == NULL)
    return true;

  if (!gfc_resolve_expr (dim))
    return false;

  if (dim->rank != 0)
    {
      gfc_error ("Argument dim at %L must be scalar", &dim->where);
      return false;

    }

  if (dim->ts.type != BT_INTEGER)
    {
      gfc_error ("Argument dim at %L must be of INTEGER type", &dim->where);
      return false;
    }

  if (dim->ts.kind != gfc_index_integer_kind)
    {
      gfc_typespec ts;

      gfc_clear_ts (&ts);
      ts.type = BT_INTEGER;
      ts.kind = gfc_index_integer_kind;

      gfc_convert_type_warn (dim, &ts, 2, 0);
    }

  return true;
}

/* Given an expression that contains array references, update those array
   references to point to the right array specifications.  While this is
   filled in during matching, this information is difficult to save and load
   in a module, so we take care of it here.

   The idea here is that the original array reference comes from the
   base symbol.  We traverse the list of reference structures, setting
   the stored reference to references.  Component references can
   provide an additional array specification.  */
static void
resolve_assoc_var (gfc_symbol* sym, bool resolve_target);

static void
find_array_spec (gfc_expr *e)
{
  gfc_array_spec *as;
  gfc_component *c;
  gfc_ref *ref;
  bool class_as = false;

  if (e->symtree->n.sym->assoc)
    {
      if (e->symtree->n.sym->assoc->target)
	gfc_resolve_expr (e->symtree->n.sym->assoc->target);
      resolve_assoc_var (e->symtree->n.sym, false);
    }

  if (e->symtree->n.sym->ts.type == BT_CLASS)
    {
      as = CLASS_DATA (e->symtree->n.sym)->as;
      class_as = true;
    }
  else
    as = e->symtree->n.sym->as;

  for (ref = e->ref; ref; ref = ref->next)
    switch (ref->type)
      {
      case REF_ARRAY:
	if (as == NULL)
	  gfc_internal_error ("find_array_spec(): Missing spec");

	ref->u.ar.as = as;
	as = NULL;
	break;

      case REF_COMPONENT:
	c = ref->u.c.component;
	if (c->attr.dimension)
	  {
	    if (as != NULL && !(class_as && as == c->as))
	      gfc_internal_error ("find_array_spec(): unused as(1)");
	    as = c->as;
	  }

	break;

      case REF_SUBSTRING:
      case REF_INQUIRY:
	break;
      }

  if (as != NULL)
    gfc_internal_error ("find_array_spec(): unused as(2)");
}


/* Resolve an array reference.  */

static bool
resolve_array_ref (gfc_array_ref *ar)
{
  int i, check_scalar;
  gfc_expr *e;

  for (i = 0; i < ar->dimen + ar->codimen; i++)
    {
      check_scalar = ar->dimen_type[i] == DIMEN_RANGE;

      /* Do not force gfc_index_integer_kind for the start.  We can
         do fine with any integer kind.  This avoids temporary arrays
	 created for indexing with a vector.  */
      if (!gfc_resolve_index_1 (ar->start[i], check_scalar, 0))
	return false;
      if (!gfc_resolve_index (ar->end[i], check_scalar))
	return false;
      if (!gfc_resolve_index (ar->stride[i], check_scalar))
	return false;

      e = ar->start[i];

      if (ar->dimen_type[i] == DIMEN_UNKNOWN)
	switch (e->rank)
	  {
	  case 0:
	    ar->dimen_type[i] = DIMEN_ELEMENT;
	    break;

	  case 1:
	    ar->dimen_type[i] = DIMEN_VECTOR;
	    if (e->expr_type == EXPR_VARIABLE
		&& e->symtree->n.sym->ts.type == BT_DERIVED)
	      ar->start[i] = gfc_get_parentheses (e);
	    break;

	  default:
	    gfc_error ("Array index at %L is an array of rank %d",
		       &ar->c_where[i], e->rank);
	    return false;
	  }

      /* Fill in the upper bound, which may be lower than the
	 specified one for something like a(2:10:5), which is
	 identical to a(2:7:5).  Only relevant for strides not equal
	 to one.  Don't try a division by zero.  */
      if (ar->dimen_type[i] == DIMEN_RANGE
	  && ar->stride[i] != NULL && ar->stride[i]->expr_type == EXPR_CONSTANT
	  && mpz_cmp_si (ar->stride[i]->value.integer, 1L) != 0
	  && mpz_cmp_si (ar->stride[i]->value.integer, 0L) != 0)
	{
	  mpz_t size, end;

	  if (gfc_ref_dimen_size (ar, i, &size, &end))
	    {
	      if (ar->end[i] == NULL)
		{
		  ar->end[i] =
		    gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
					   &ar->where);
		  mpz_set (ar->end[i]->value.integer, end);
		}
	      else if (ar->end[i]->ts.type == BT_INTEGER
		       && ar->end[i]->expr_type == EXPR_CONSTANT)
		{
		  mpz_set (ar->end[i]->value.integer, end);
		}
	      else
		gcc_unreachable ();

	      mpz_clear (size);
	      mpz_clear (end);
	    }
	}
    }

  if (ar->type == AR_FULL)
    {
      if (ar->as->rank == 0)
	ar->type = AR_ELEMENT;

      /* Make sure array is the same as array(:,:), this way
	 we don't need to special case all the time.  */
      ar->dimen = ar->as->rank;
      for (i = 0; i < ar->dimen; i++)
	{
	  ar->dimen_type[i] = DIMEN_RANGE;

	  gcc_assert (ar->start[i] == NULL);
	  gcc_assert (ar->end[i] == NULL);
	  gcc_assert (ar->stride[i] == NULL);
	}
    }

  /* If the reference type is unknown, figure out what kind it is.  */

  if (ar->type == AR_UNKNOWN)
    {
      ar->type = AR_ELEMENT;
      for (i = 0; i < ar->dimen; i++)
	if (ar->dimen_type[i] == DIMEN_RANGE
	    || ar->dimen_type[i] == DIMEN_VECTOR)
	  {
	    ar->type = AR_SECTION;
	    break;
	  }
    }

  if (!ar->as->cray_pointee && !compare_spec_to_ref (ar))
    return false;

  if (ar->as->corank && ar->codimen == 0)
    {
      int n;
      ar->codimen = ar->as->corank;
      for (n = ar->dimen; n < ar->dimen + ar->codimen; n++)
	ar->dimen_type[n] = DIMEN_THIS_IMAGE;
    }

  return true;
}


bool
gfc_resolve_substring (gfc_ref *ref, bool *equal_length)
{
  int k = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);

  if (ref->u.ss.start != NULL)
    {
      if (!gfc_resolve_expr (ref->u.ss.start))
	return false;

      if (ref->u.ss.start->ts.type != BT_INTEGER)
	{
	  gfc_error ("Substring start index at %L must be of type INTEGER",
		     &ref->u.ss.start->where);
	  return false;
	}

      if (ref->u.ss.start->rank != 0)
	{
	  gfc_error ("Substring start index at %L must be scalar",
		     &ref->u.ss.start->where);
	  return false;
	}

      if (compare_bound_int (ref->u.ss.start, 1) == CMP_LT
	  && (compare_bound (ref->u.ss.end, ref->u.ss.start) == CMP_EQ
	      || compare_bound (ref->u.ss.end, ref->u.ss.start) == CMP_GT))
	{
	  gfc_error ("Substring start index at %L is less than one",
		     &ref->u.ss.start->where);
	  return false;
	}
    }

  if (ref->u.ss.end != NULL)
    {
      if (!gfc_resolve_expr (ref->u.ss.end))
	return false;

      if (ref->u.ss.end->ts.type != BT_INTEGER)
	{
	  gfc_error ("Substring end index at %L must be of type INTEGER",
		     &ref->u.ss.end->where);
	  return false;
	}

      if (ref->u.ss.end->rank != 0)
	{
	  gfc_error ("Substring end index at %L must be scalar",
		     &ref->u.ss.end->where);
	  return false;
	}

      if (ref->u.ss.length != NULL
	  && compare_bound (ref->u.ss.end, ref->u.ss.length->length) == CMP_GT
	  && (compare_bound (ref->u.ss.end, ref->u.ss.start) == CMP_EQ
	      || compare_bound (ref->u.ss.end, ref->u.ss.start) == CMP_GT))
	{
	  gfc_error ("Substring end index at %L exceeds the string length",
		     &ref->u.ss.start->where);
	  return false;
	}

      if (compare_bound_mpz_t (ref->u.ss.end,
			       gfc_integer_kinds[k].huge) == CMP_GT
	  && (compare_bound (ref->u.ss.end, ref->u.ss.start) == CMP_EQ
	      || compare_bound (ref->u.ss.end, ref->u.ss.start) == CMP_GT))
	{
	  gfc_error ("Substring end index at %L is too large",
		     &ref->u.ss.end->where);
	  return false;
	}
      /*  If the substring has the same length as the original
	  variable, the reference itself can be deleted.  */

      if (ref->u.ss.length != NULL
	  && compare_bound (ref->u.ss.end, ref->u.ss.length->length) == CMP_EQ
	  && compare_bound_int (ref->u.ss.start, 1) == CMP_EQ)
	*equal_length = true;
    }

  return true;
}


/* This function supplies missing substring charlens.  */

void
gfc_resolve_substring_charlen (gfc_expr *e)
{
  gfc_ref *char_ref;
  gfc_expr *start, *end;
  gfc_typespec *ts = NULL;
  mpz_t diff;

  for (char_ref = e->ref; char_ref; char_ref = char_ref->next)
    {
      if (char_ref->type == REF_SUBSTRING || char_ref->type == REF_INQUIRY)
	break;
      if (char_ref->type == REF_COMPONENT)
	ts = &char_ref->u.c.component->ts;
    }

  if (!char_ref || char_ref->type == REF_INQUIRY)
    return;

  gcc_assert (char_ref->next == NULL);

  if (e->ts.u.cl)
    {
      if (e->ts.u.cl->length)
	gfc_free_expr (e->ts.u.cl->length);
      else if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.dummy)
	return;
    }

  if (!e->ts.u.cl)
    e->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);

  if (char_ref->u.ss.start)
    start = gfc_copy_expr (char_ref->u.ss.start);
  else
    start = gfc_get_int_expr (gfc_charlen_int_kind, NULL, 1);

  if (char_ref->u.ss.end)
    end = gfc_copy_expr (char_ref->u.ss.end);
  else if (e->expr_type == EXPR_VARIABLE)
    {
      if (!ts)
	ts = &e->symtree->n.sym->ts;
      end = gfc_copy_expr (ts->u.cl->length);
    }
  else
    end = NULL;

  if (!start || !end)
    {
      gfc_free_expr (start);
      gfc_free_expr (end);
      return;
    }

  /* Length = (end - start + 1).
     Check first whether it has a constant length.  */
  if (gfc_dep_difference (end, start, &diff))
    {
      gfc_expr *len = gfc_get_constant_expr (BT_INTEGER, gfc_charlen_int_kind,
					     &e->where);

      mpz_add_ui (len->value.integer, diff, 1);
      mpz_clear (diff);
      e->ts.u.cl->length = len;
      /* The check for length < 0 is handled below */
    }
  else
    {
      e->ts.u.cl->length = gfc_subtract (end, start);
      e->ts.u.cl->length = gfc_add (e->ts.u.cl->length,
				    gfc_get_int_expr (gfc_charlen_int_kind,
						      NULL, 1));
    }

  /* F2008, 6.4.1:  Both the starting point and the ending point shall
     be within the range 1, 2, ..., n unless the starting point exceeds
     the ending point, in which case the substring has length zero.  */

  if (mpz_cmp_si (e->ts.u.cl->length->value.integer, 0) < 0)
    mpz_set_si (e->ts.u.cl->length->value.integer, 0);

  e->ts.u.cl->length->ts.type = BT_INTEGER;
  e->ts.u.cl->length->ts.kind = gfc_charlen_int_kind;

  /* Make sure that the length is simplified.  */
  gfc_simplify_expr (e->ts.u.cl->length, 1);
  gfc_resolve_expr (e->ts.u.cl->length);
}


/* Resolve subtype references.  */

bool
gfc_resolve_ref (gfc_expr *expr)
{
  int current_part_dimension, n_components, seen_part_dimension, dim;
  gfc_ref *ref, **prev, *array_ref;
  bool equal_length;

  for (ref = expr->ref; ref; ref = ref->next)
    if (ref->type == REF_ARRAY && ref->u.ar.as == NULL)
      {
	find_array_spec (expr);
	break;
      }

  for (prev = &expr->ref; *prev != NULL;
       prev = *prev == NULL ? prev : &(*prev)->next)
    switch ((*prev)->type)
      {
      case REF_ARRAY:
	if (!resolve_array_ref (&(*prev)->u.ar))
	  return false;
	break;

      case REF_COMPONENT:
      case REF_INQUIRY:
	break;

      case REF_SUBSTRING:
	equal_length = false;
	if (!gfc_resolve_substring (*prev, &equal_length))
	  return false;

	if (expr->expr_type != EXPR_SUBSTRING && equal_length)
	  {
	    /* Remove the reference and move the charlen, if any.  */
	    ref = *prev;
	    *prev = ref->next;
	    ref->next = NULL;
	    expr->ts.u.cl = ref->u.ss.length;
	    ref->u.ss.length = NULL;
	    gfc_free_ref_list (ref);
	  }
	break;
      }

  /* Check constraints on part references.  */

  current_part_dimension = 0;
  seen_part_dimension = 0;
  n_components = 0;
  array_ref = NULL;

  for (ref = expr->ref; ref; ref = ref->next)
    {
      switch (ref->type)
	{
	case REF_ARRAY:
	  array_ref = ref;
	  switch (ref->u.ar.type)
	    {
	    case AR_FULL:
	      /* Coarray scalar.  */
	      if (ref->u.ar.as->rank == 0)
		{
		  current_part_dimension = 0;
		  break;
		}
	      /* Fall through.  */
	    case AR_SECTION:
	      current_part_dimension = 1;
	      break;

	    case AR_ELEMENT:
	      array_ref = NULL;
	      current_part_dimension = 0;
	      break;

	    case AR_UNKNOWN:
	      gfc_internal_error ("resolve_ref(): Bad array reference");
	    }

	  break;

	case REF_COMPONENT:
	  if (current_part_dimension || seen_part_dimension)
	    {
	      /* F03:C614.  */
	      if (ref->u.c.component->attr.pointer
		  || ref->u.c.component->attr.proc_pointer
		  || (ref->u.c.component->ts.type == BT_CLASS
			&& CLASS_DATA (ref->u.c.component)->attr.pointer))
		{
		  gfc_error ("Component to the right of a part reference "
			     "with nonzero rank must not have the POINTER "
			     "attribute at %L", &expr->where);
		  return false;
		}
	      else if (ref->u.c.component->attr.allocatable
			|| (ref->u.c.component->ts.type == BT_CLASS
			    && CLASS_DATA (ref->u.c.component)->attr.allocatable))

		{
		  gfc_error ("Component to the right of a part reference "
			     "with nonzero rank must not have the ALLOCATABLE "
			     "attribute at %L", &expr->where);
		  return false;
		}
	    }

	  n_components++;
	  break;

	case REF_SUBSTRING:
	  break;

	case REF_INQUIRY:
	  /* Implement requirement in note 9.7 of F2018 that the result of the
	     LEN inquiry be a scalar.  */
	  if (ref->u.i == INQUIRY_LEN && array_ref && expr->ts.deferred)
	    {
	      array_ref->u.ar.type = AR_ELEMENT;
	      expr->rank = 0;
	      /* INQUIRY_LEN is not evaluated from the rest of the expr
		 but directly from the string length. This means that setting
		 the array indices to one does not matter but might trigger
		 a runtime bounds error. Suppress the check.  */
	      expr->no_bounds_check = 1;
	      for (dim = 0; dim < array_ref->u.ar.dimen; dim++)
		{
		  array_ref->u.ar.dimen_type[dim] = DIMEN_ELEMENT;
		  if (array_ref->u.ar.start[dim])
		    gfc_free_expr (array_ref->u.ar.start[dim]);
		  array_ref->u.ar.start[dim]
			= gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
		  if (array_ref->u.ar.end[dim])
		    gfc_free_expr (array_ref->u.ar.end[dim]);
		  if (array_ref->u.ar.stride[dim])
		    gfc_free_expr (array_ref->u.ar.stride[dim]);
		}
	    }
	  break;
	}

      if (((ref->type == REF_COMPONENT && n_components > 1)
	   || ref->next == NULL)
	  && current_part_dimension
	  && seen_part_dimension)
	{
	  gfc_error ("Two or more part references with nonzero rank must "
		     "not be specified at %L", &expr->where);
	  return false;
	}

      if (ref->type == REF_COMPONENT)
	{
	  if (current_part_dimension)
	    seen_part_dimension = 1;

	  /* reset to make sure */
	  current_part_dimension = 0;
	}
    }

  return true;
}


/* Given an expression, determine its shape.  This is easier than it sounds.
   Leaves the shape array NULL if it is not possible to determine the shape.  */

static void
expression_shape (gfc_expr *e)
{
  mpz_t array[GFC_MAX_DIMENSIONS];
  int i;

  if (e->rank <= 0 || e->shape != NULL)
    return;

  for (i = 0; i < e->rank; i++)
    if (!gfc_array_dimen_size (e, i, &array[i]))
      goto fail;

  e->shape = gfc_get_shape (e->rank);

  memcpy (e->shape, array, e->rank * sizeof (mpz_t));

  return;

fail:
  for (i--; i >= 0; i--)
    mpz_clear (array[i]);
}


/* Given a variable expression node, compute the rank of the expression by
   examining the base symbol and any reference structures it may have.  */

void
gfc_expression_rank (gfc_expr *e)
{
  gfc_ref *ref;
  int i, rank;

  /* Just to make sure, because EXPR_COMPCALL's also have an e->ref and that
     could lead to serious confusion...  */
  gcc_assert (e->expr_type != EXPR_COMPCALL);

  if (e->ref == NULL)
    {
      if (e->expr_type == EXPR_ARRAY)
	goto done;
      /* Constructors can have a rank different from one via RESHAPE().  */

      e->rank = ((e->symtree == NULL || e->symtree->n.sym->as == NULL)
		 ? 0 : e->symtree->n.sym->as->rank);
      goto done;
    }

  rank = 0;

  for (ref = e->ref; ref; ref = ref->next)
    {
      if (ref->type == REF_COMPONENT && ref->u.c.component->attr.proc_pointer
	  && ref->u.c.component->attr.function && !ref->next)
	rank = ref->u.c.component->as ? ref->u.c.component->as->rank : 0;

      if (ref->type != REF_ARRAY)
	continue;

      if (ref->u.ar.type == AR_FULL)
	{
	  rank = ref->u.ar.as->rank;
	  break;
	}

      if (ref->u.ar.type == AR_SECTION)
	{
	  /* Figure out the rank of the section.  */
	  if (rank != 0)
	    gfc_internal_error ("gfc_expression_rank(): Two array specs");

	  for (i = 0; i < ref->u.ar.dimen; i++)
	    if (ref->u.ar.dimen_type[i] == DIMEN_RANGE
		|| ref->u.ar.dimen_type[i] == DIMEN_VECTOR)
	      rank++;

	  break;
	}
    }

  e->rank = rank;

done:
  expression_shape (e);
}


static void
add_caf_get_intrinsic (gfc_expr *e)
{
  gfc_expr *wrapper, *tmp_expr;
  gfc_ref *ref;
  int n;

  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
      break;
  if (ref == NULL)
    return;

  for (n = ref->u.ar.dimen; n < ref->u.ar.dimen + ref->u.ar.codimen; n++)
    if (ref->u.ar.dimen_type[n] != DIMEN_ELEMENT)
      return;

  tmp_expr = XCNEW (gfc_expr);
  *tmp_expr = *e;
  wrapper = gfc_build_intrinsic_call (gfc_current_ns, GFC_ISYM_CAF_GET,
				      "caf_get", tmp_expr->where, 1, tmp_expr);
  wrapper->ts = e->ts;
  wrapper->rank = e->rank;
  if (e->rank)
    wrapper->shape = gfc_copy_shape (e->shape, e->rank);
  *e = *wrapper;
  free (wrapper);
}


static void
remove_caf_get_intrinsic (gfc_expr *e)
{
  gcc_assert (e->expr_type == EXPR_FUNCTION && e->value.function.isym
	      && e->value.function.isym->id == GFC_ISYM_CAF_GET);
  gfc_expr *e2 = e->value.function.actual->expr;
  e->value.function.actual->expr = NULL;
  gfc_free_actual_arglist (e->value.function.actual);
  gfc_free_shape (&e->shape, e->rank);
  *e = *e2;
  free (e2);
}


/* Resolve a variable expression.  */

static bool
resolve_variable (gfc_expr *e)
{
  gfc_symbol *sym;
  bool t;

  t = true;

  if (e->symtree == NULL)
    return false;
  sym = e->symtree->n.sym;

  /* Use same check as for TYPE(*) below; this check has to be before TYPE(*)
     as ts.type is set to BT_ASSUMED in resolve_symbol.  */
  if (sym->attr.ext_attr & (1 << EXT_ATTR_NO_ARG_CHECK))
    {
      if (!actual_arg || inquiry_argument)
	{
	  gfc_error ("Variable %s at %L with NO_ARG_CHECK attribute may only "
		     "be used as actual argument", sym->name, &e->where);
	  return false;
	}
    }
  /* TS 29113, 407b.  */
  else if (e->ts.type == BT_ASSUMED)
    {
      if (!actual_arg)
	{
	  gfc_error ("Assumed-type variable %s at %L may only be used "
		     "as actual argument", sym->name, &e->where);
	  return false;
	}
      else if (inquiry_argument && !first_actual_arg)
	{
	  /* FIXME: It doesn't work reliably as inquiry_argument is not set
	     for all inquiry functions in resolve_function; the reason is
	     that the function-name resolution happens too late in that
	     function.  */
	  gfc_error ("Assumed-type variable %s at %L as actual argument to "
		     "an inquiry function shall be the first argument",
		     sym->name, &e->where);
	  return false;
	}
    }
  /* TS 29113, C535b.  */
  else if (((sym->ts.type == BT_CLASS && sym->attr.class_ok
	     && sym->ts.u.derived && CLASS_DATA (sym)
	     && CLASS_DATA (sym)->as
	     && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
	    || (sym->ts.type != BT_CLASS && sym->as
	        && sym->as->type == AS_ASSUMED_RANK))
	   && !sym->attr.select_rank_temporary)
    {
      if (!actual_arg
	  && !(cs_base && cs_base->current
	       && cs_base->current->op == EXEC_SELECT_RANK))
	{
	  gfc_error ("Assumed-rank variable %s at %L may only be used as "
		     "actual argument", sym->name, &e->where);
	  return false;
	}
      else if (inquiry_argument && !first_actual_arg)
	{
	  /* FIXME: It doesn't work reliably as inquiry_argument is not set
	     for all inquiry functions in resolve_function; the reason is
	     that the function-name resolution happens too late in that
	     function.  */
	  gfc_error ("Assumed-rank variable %s at %L as actual argument "
		     "to an inquiry function shall be the first argument",
		     sym->name, &e->where);
	  return false;
	}
    }

  if ((sym->attr.ext_attr & (1 << EXT_ATTR_NO_ARG_CHECK)) && e->ref
      && !(e->ref->type == REF_ARRAY && e->ref->u.ar.type == AR_FULL
	   && e->ref->next == NULL))
    {
      gfc_error ("Variable %s at %L with NO_ARG_CHECK attribute shall not have "
		 "a subobject reference", sym->name, &e->ref->u.ar.where);
      return false;
    }
  /* TS 29113, 407b.  */
  else if (e->ts.type == BT_ASSUMED && e->ref
	   && !(e->ref->type == REF_ARRAY && e->ref->u.ar.type == AR_FULL
		&& e->ref->next == NULL))
    {
      gfc_error ("Assumed-type variable %s at %L shall not have a subobject "
		 "reference", sym->name, &e->ref->u.ar.where);
      return false;
    }

  /* TS 29113, C535b.  */
  if (((sym->ts.type == BT_CLASS && sym->attr.class_ok
	&& sym->ts.u.derived && CLASS_DATA (sym)
	&& CLASS_DATA (sym)->as
	&& CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK)
       || (sym->ts.type != BT_CLASS && sym->as
	   && sym->as->type == AS_ASSUMED_RANK))
      && e->ref
      && !(e->ref->type == REF_ARRAY && e->ref->u.ar.type == AR_FULL
	   && e->ref->next == NULL))
    {
      gfc_error ("Assumed-rank variable %s at %L shall not have a subobject "
		 "reference", sym->name, &e->ref->u.ar.where);
      return false;
    }

  /* For variables that are used in an associate (target => object) where
     the object's basetype is array valued while the target is scalar,
     the ts' type of the component refs is still array valued, which
     can't be translated that way.  */
  if (sym->assoc && e->rank == 0 && e->ref && sym->ts.type == BT_CLASS
      && sym->assoc->target && sym->assoc->target->ts.type == BT_CLASS
      && CLASS_DATA (sym->assoc->target)->as)
    {
      gfc_ref *ref = e->ref;
      while (ref)
	{
	  switch (ref->type)
	    {
	    case REF_COMPONENT:
	      ref->u.c.sym = sym->ts.u.derived;
	      /* Stop the loop.  */
	      ref = NULL;
	      break;
	    default:
	      ref = ref->next;
	      break;
	    }
	}
    }

  /* If this is an associate-name, it may be parsed with an array reference
     in error even though the target is scalar.  Fail directly in this case.
     TODO Understand why class scalar expressions must be excluded.  */
  if (sym->assoc && !(sym->ts.type == BT_CLASS && e->rank == 0))
    {
      if (sym->ts.type == BT_CLASS)
	gfc_fix_class_refs (e);
      if (!sym->attr.dimension && e->ref && e->ref->type == REF_ARRAY)
	return false;
      else if (sym->attr.dimension && (!e->ref || e->ref->type != REF_ARRAY))
	{
	  /* This can happen because the parser did not detect that the
	     associate name is an array and the expression had no array
	     part_ref.  */
	  gfc_ref *ref = gfc_get_ref ();
	  ref->type = REF_ARRAY;
	  ref->u.ar.type = AR_FULL;
	  if (sym->as)
	    {
	      ref->u.ar.as = sym->as;
	      ref->u.ar.dimen = sym->as->rank;
	    }
	  ref->next = e->ref;
	  e->ref = ref;

	}
    }

  if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.generic)
    sym->ts.u.derived = gfc_find_dt_in_generic (sym->ts.u.derived);

  /* On the other hand, the parser may not have known this is an array;
     in this case, we have to add a FULL reference.  */
  if (sym->assoc && sym->attr.dimension && !e->ref)
    {
      e->ref = gfc_get_ref ();
      e->ref->type = REF_ARRAY;
      e->ref->u.ar.type = AR_FULL;
      e->ref->u.ar.dimen = 0;
    }

  /* Like above, but for class types, where the checking whether an array
     ref is present is more complicated.  Furthermore make sure not to add
     the full array ref to _vptr or _len refs.  */
  if (sym->assoc && sym->ts.type == BT_CLASS
      && CLASS_DATA (sym)->attr.dimension
      && (e->ts.type != BT_DERIVED || !e->ts.u.derived->attr.vtype))
    {
      gfc_ref *ref, *newref;

      newref = gfc_get_ref ();
      newref->type = REF_ARRAY;
      newref->u.ar.type = AR_FULL;
      newref->u.ar.dimen = 0;
      /* Because this is an associate var and the first ref either is a ref to
	 the _data component or not, no traversal of the ref chain is
	 needed.  The array ref needs to be inserted after the _data ref,
	 or when that is not present, which may happend for polymorphic
	 types, then at the first position.  */
      ref = e->ref;
      if (!ref)
	e->ref = newref;
      else if (ref->type == REF_COMPONENT
	       && strcmp ("_data", ref->u.c.component->name) == 0)
	{
	  if (!ref->next || ref->next->type != REF_ARRAY)
	    {
	      newref->next = ref->next;
	      ref->next = newref;
	    }
	  else
	    /* Array ref present already.  */
	    gfc_free_ref_list (newref);
	}
      else if (ref->type == REF_ARRAY)
	/* Array ref present already.  */
	gfc_free_ref_list (newref);
      else
	{
	  newref->next = ref;
	  e->ref = newref;
	}
    }

  if (e->ref && !gfc_resolve_ref (e))
    return false;

  if (sym->attr.flavor == FL_PROCEDURE
      && (!sym->attr.function
	  || (sym->attr.function && sym->result
	      && sym->result->attr.proc_pointer
	      && !sym->result->attr.function)))
    {
      e->ts.type = BT_PROCEDURE;
      goto resolve_procedure;
    }

  if (sym->ts.type != BT_UNKNOWN)
    gfc_variable_attr (e, &e->ts);
  else if (sym->attr.flavor == FL_PROCEDURE
	   && sym->attr.function && sym->result
	   && sym->result->ts.type != BT_UNKNOWN
	   && sym->result->attr.proc_pointer)
    e->ts = sym->result->ts;
  else
    {
      /* Must be a simple variable reference.  */
      if (!gfc_set_default_type (sym, 1, sym->ns))
	return false;
      e->ts = sym->ts;
    }

  if (check_assumed_size_reference (sym, e))
    return false;

  /* Deal with forward references to entries during gfc_resolve_code, to
     satisfy, at least partially, 12.5.2.5.  */
  if (gfc_current_ns->entries
      && current_entry_id == sym->entry_id
      && cs_base
      && cs_base->current
      && cs_base->current->op != EXEC_ENTRY)
    {
      gfc_entry_list *entry;
      gfc_formal_arglist *formal;
      int n;
      bool seen, saved_specification_expr;

      /* If the symbol is a dummy...  */
      if (sym->attr.dummy && sym->ns == gfc_current_ns)
	{
	  entry = gfc_current_ns->entries;
	  seen = false;

	  /* ...test if the symbol is a parameter of previous entries.  */
	  for (; entry && entry->id <= current_entry_id; entry = entry->next)
	    for (formal = entry->sym->formal; formal; formal = formal->next)
	      {
		if (formal->sym && sym->name == formal->sym->name)
		  {
		    seen = true;
		    break;
		  }
	      }

	  /*  If it has not been seen as a dummy, this is an error.  */
	  if (!seen)
	    {
	      if (specification_expr)
		gfc_error ("Variable %qs, used in a specification expression"
			   ", is referenced at %L before the ENTRY statement "
			   "in which it is a parameter",
			   sym->name, &cs_base->current->loc);
	      else
		gfc_error ("Variable %qs is used at %L before the ENTRY "
			   "statement in which it is a parameter",
			   sym->name, &cs_base->current->loc);
	      t = false;
	    }
	}

      /* Now do the same check on the specification expressions.  */
      saved_specification_expr = specification_expr;
      specification_expr = true;
      if (sym->ts.type == BT_CHARACTER
	  && !gfc_resolve_expr (sym->ts.u.cl->length))
	t = false;

      if (sym->as)
	for (n = 0; n < sym->as->rank; n++)
	  {
	     if (!gfc_resolve_expr (sym->as->lower[n]))
	       t = false;
	     if (!gfc_resolve_expr (sym->as->upper[n]))
	       t = false;
	  }
      specification_expr = saved_specification_expr;

      if (t)
	/* Update the symbol's entry level.  */
	sym->entry_id = current_entry_id + 1;
    }

  /* If a symbol has been host_associated mark it.  This is used latter,
     to identify if aliasing is possible via host association.  */
  if (sym->attr.flavor == FL_VARIABLE
	&& gfc_current_ns->parent
	&& (gfc_current_ns->parent == sym->ns
	      || (gfc_current_ns->parent->parent
		    && gfc_current_ns->parent->parent == sym->ns)))
    sym->attr.host_assoc = 1;

  if (gfc_current_ns->proc_name
      && sym->attr.dimension
      && (sym->ns != gfc_current_ns
	  || sym->attr.use_assoc
	  || sym->attr.in_common))
    gfc_current_ns->proc_name->attr.array_outer_dependency = 1;

resolve_procedure:
  if (t && !resolve_procedure_expression (e))
    t = false;

  /* F2008, C617 and C1229.  */
  if (!inquiry_argument && (e->ts.type == BT_CLASS || e->ts.type == BT_DERIVED)
      && gfc_is_coindexed (e))
    {
      gfc_ref *ref, *ref2 = NULL;

      for (ref = e->ref; ref; ref = ref->next)
	{
	  if (ref->type == REF_COMPONENT)
	    ref2 = ref;
	  if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
	    break;
	}

      for ( ; ref; ref = ref->next)
	if (ref->type == REF_COMPONENT)
	  break;

      /* Expression itself is not coindexed object.  */
      if (ref && e->ts.type == BT_CLASS)
	{
	  gfc_error ("Polymorphic subobject of coindexed object at %L",
		     &e->where);
	  t = false;
	}

      /* Expression itself is coindexed object.  */
      if (ref == NULL)
	{
	  gfc_component *c;
	  c = ref2 ? ref2->u.c.component : e->symtree->n.sym->components;
	  for ( ; c; c = c->next)
	    if (c->attr.allocatable && c->ts.type == BT_CLASS)
	      {
		gfc_error ("Coindexed object with polymorphic allocatable "
			 "subcomponent at %L", &e->where);
		t = false;
		break;
	      }
	}
    }

  if (t)
    gfc_expression_rank (e);

  if (t && flag_coarray == GFC_FCOARRAY_LIB && gfc_is_coindexed (e))
    add_caf_get_intrinsic (e);

  if (sym->attr.ext_attr & (1 << EXT_ATTR_DEPRECATED) && sym != sym->result)
    gfc_warning (OPT_Wdeprecated_declarations,
		 "Using variable %qs at %L is deprecated",
		 sym->name, &e->where);
  /* Simplify cases where access to a parameter array results in a
     single constant.  Suppress errors since those will have been
     issued before, as warnings.  */
  if (e->rank == 0 && sym->as && sym->attr.flavor == FL_PARAMETER)
    {
      gfc_push_suppress_errors ();
      gfc_simplify_expr (e, 1);
      gfc_pop_suppress_errors ();
    }

  return t;
}


/* Checks to see that the correct symbol has been host associated.
   The only situation where this arises is that in which a twice
   contained function is parsed after the host association is made.
   Therefore, on detecting this, change the symbol in the expression
   and convert the array reference into an actual arglist if the old
   symbol is a variable.  */
static bool
check_host_association (gfc_expr *e)
{
  gfc_symbol *sym, *old_sym;
  gfc_symtree *st;
  int n;
  gfc_ref *ref;
  gfc_actual_arglist *arg, *tail = NULL;
  bool retval = e->expr_type == EXPR_FUNCTION;

  /*  If the expression is the result of substitution in
      interface.c(gfc_extend_expr) because there is no way in
      which the host association can be wrong.  */
  if (e->symtree == NULL
	|| e->symtree->n.sym == NULL
	|| e->user_operator)
    return retval;

  old_sym = e->symtree->n.sym;

  if (gfc_current_ns->parent
	&& old_sym->ns != gfc_current_ns)
    {
      /* Use the 'USE' name so that renamed module symbols are
	 correctly handled.  */
      gfc_find_symbol (e->symtree->name, gfc_current_ns, 1, &sym);

      if (sym && old_sym != sym
	      && sym->ts.type == old_sym->ts.type
	      && sym->attr.flavor == FL_PROCEDURE
	      && sym->attr.contained)
	{
	  /* Clear the shape, since it might not be valid.  */
	  gfc_free_shape (&e->shape, e->rank);

	  /* Give the expression the right symtree!  */
	  gfc_find_sym_tree (e->symtree->name, NULL, 1, &st);
	  gcc_assert (st != NULL);

	  if (old_sym->attr.flavor == FL_PROCEDURE
		|| e->expr_type == EXPR_FUNCTION)
  	    {
	      /* Original was function so point to the new symbol, since
		 the actual argument list is already attached to the
		 expression.  */
	      e->value.function.esym = NULL;
	      e->symtree = st;
	    }
	  else
	    {
	      /* Original was variable so convert array references into
		 an actual arglist. This does not need any checking now
		 since resolve_function will take care of it.  */
	      e->value.function.actual = NULL;
	      e->expr_type = EXPR_FUNCTION;
	      e->symtree = st;

	      /* Ambiguity will not arise if the array reference is not
		 the last reference.  */
	      for (ref = e->ref; ref; ref = ref->next)
		if (ref->type == REF_ARRAY && ref->next == NULL)
		  break;

	      if ((ref == NULL || ref->type != REF_ARRAY)
		  && sym->attr.proc == PROC_INTERNAL)
		{
		  gfc_error ("%qs at %L is host associated at %L into "
			     "a contained procedure with an internal "
			     "procedure of the same name", sym->name,
			      &old_sym->declared_at, &e->where);
		  return false;
		}

	      gcc_assert (ref->type == REF_ARRAY);

	      /* Grab the start expressions from the array ref and
		 copy them into actual arguments.  */
	      for (n = 0; n < ref->u.ar.dimen; n++)
		{
		  arg = gfc_get_actual_arglist ();
		  arg->expr = gfc_copy_expr (ref->u.ar.start[n]);
		  if (e->value.function.actual == NULL)
		    tail = e->value.function.actual = arg;
	          else
		    {
		      tail->next = arg;
		      tail = arg;
		    }
		}

	      /* Dump the reference list and set the rank.  */
	      gfc_free_ref_list (e->ref);
	      e->ref = NULL;
	      e->rank = sym->as ? sym->as->rank : 0;
	    }

	  gfc_resolve_expr (e);
	  sym->refs++;
	}
    }
  /* This might have changed!  */
  return e->expr_type == EXPR_FUNCTION;
}


static void
gfc_resolve_character_operator (gfc_expr *e)
{
  gfc_expr *op1 = e->value.op.op1;
  gfc_expr *op2 = e->value.op.op2;
  gfc_expr *e1 = NULL;
  gfc_expr *e2 = NULL;

  gcc_assert (e->value.op.op == INTRINSIC_CONCAT);

  if (op1->ts.u.cl && op1->ts.u.cl->length)
    e1 = gfc_copy_expr (op1->ts.u.cl->length);
  else if (op1->expr_type == EXPR_CONSTANT)
    e1 = gfc_get_int_expr (gfc_charlen_int_kind, NULL,
			   op1->value.character.length);

  if (op2->ts.u.cl && op2->ts.u.cl->length)
    e2 = gfc_copy_expr (op2->ts.u.cl->length);
  else if (op2->expr_type == EXPR_CONSTANT)
    e2 = gfc_get_int_expr (gfc_charlen_int_kind, NULL,
			   op2->value.character.length);

  e->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);

  if (!e1 || !e2)
    {
      gfc_free_expr (e1);
      gfc_free_expr (e2);

      return;
    }

  e->ts.u.cl->length = gfc_add (e1, e2);
  e->ts.u.cl->length->ts.type = BT_INTEGER;
  e->ts.u.cl->length->ts.kind = gfc_charlen_int_kind;
  gfc_simplify_expr (e->ts.u.cl->length, 0);
  gfc_resolve_expr (e->ts.u.cl->length);

  return;
}


/*  Ensure that an character expression has a charlen and, if possible, a
    length expression.  */

static void
fixup_charlen (gfc_expr *e)
{
  /* The cases fall through so that changes in expression type and the need
     for multiple fixes are picked up.  In all circumstances, a charlen should
     be available for the middle end to hang a backend_decl on.  */
  switch (e->expr_type)
    {
    case EXPR_OP:
      gfc_resolve_character_operator (e);
      /* FALLTHRU */

    case EXPR_ARRAY:
      if (e->expr_type == EXPR_ARRAY)
	gfc_resolve_character_array_constructor (e);
      /* FALLTHRU */

    case EXPR_SUBSTRING:
      if (!e->ts.u.cl && e->ref)
	gfc_resolve_substring_charlen (e);
      /* FALLTHRU */

    default:
      if (!e->ts.u.cl)
	e->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);

      break;
    }
}


/* Update an actual argument to include the passed-object for type-bound
   procedures at the right position.  */

static gfc_actual_arglist*
update_arglist_pass (gfc_actual_arglist* lst, gfc_expr* po, unsigned argpos,
		     const char *name)
{
  gcc_assert (argpos > 0);

  if (argpos == 1)
    {
      gfc_actual_arglist* result;

      result = gfc_get_actual_arglist ();
      result->expr = po;
      result->next = lst;
      if (name)
        result->name = name;

      return result;
    }

  if (lst)
    lst->next = update_arglist_pass (lst->next, po, argpos - 1, name);
  else
    lst = update_arglist_pass (NULL, po, argpos - 1, name);
  return lst;
}


/* Extract the passed-object from an EXPR_COMPCALL (a copy of it).  */

static gfc_expr*
extract_compcall_passed_object (gfc_expr* e)
{
  gfc_expr* po;

  if (e->expr_type == EXPR_UNKNOWN)
    {
      gfc_error ("Error in typebound call at %L",
		 &e->where);
      return NULL;
    }

  gcc_assert (e->expr_type == EXPR_COMPCALL);

  if (e->value.compcall.base_object)
    po = gfc_copy_expr (e->value.compcall.base_object);
  else
    {
      po = gfc_get_expr ();
      po->expr_type = EXPR_VARIABLE;
      po->symtree = e->symtree;
      po->ref = gfc_copy_ref (e->ref);
      po->where = e->where;
    }

  if (!gfc_resolve_expr (po))
    return NULL;

  return po;
}


/* Update the arglist of an EXPR_COMPCALL expression to include the
   passed-object.  */

static bool
update_compcall_arglist (gfc_expr* e)
{
  gfc_expr* po;
  gfc_typebound_proc* tbp;

  tbp = e->value.compcall.tbp;

  if (tbp->error)
    return false;

  po = extract_compcall_passed_object (e);
  if (!po)
    return false;

  if (tbp->nopass || e->value.compcall.ignore_pass)
    {
      gfc_free_expr (po);
      return true;
    }

  if (tbp->pass_arg_num <= 0)
    return false;

  e->value.compcall.actual = update_arglist_pass (e->value.compcall.actual, po,
						  tbp->pass_arg_num,
						  tbp->pass_arg);

  return true;
}


/* Extract the passed object from a PPC call (a copy of it).  */

static gfc_expr*
extract_ppc_passed_object (gfc_expr *e)
{
  gfc_expr *po;
  gfc_ref **ref;

  po = gfc_get_expr ();
  po->expr_type = EXPR_VARIABLE;
  po->symtree = e->symtree;
  po->ref = gfc_copy_ref (e->ref);
  po->where = e->where;

  /* Remove PPC reference.  */
  ref = &po->ref;
  while ((*ref)->next)
    ref = &(*ref)->next;
  gfc_free_ref_list (*ref);
  *ref = NULL;

  if (!gfc_resolve_expr (po))
    return NULL;

  return po;
}


/* Update the actual arglist of a procedure pointer component to include the
   passed-object.  */

static bool
update_ppc_arglist (gfc_expr* e)
{
  gfc_expr* po;
  gfc_component *ppc;
  gfc_typebound_proc* tb;

  ppc = gfc_get_proc_ptr_comp (e);
  if (!ppc)
    return false;

  tb = ppc->tb;

  if (tb->error)
    return false;
  else if (tb->nopass)
    return true;

  po = extract_ppc_passed_object (e);
  if (!po)
    return false;

  /* F08:R739.  */
  if (po->rank != 0)
    {
      gfc_error ("Passed-object at %L must be scalar", &e->where);
      return false;
    }

  /* F08:C611.  */
  if (po->ts.type == BT_DERIVED && po->ts.u.derived->attr.abstract)
    {
      gfc_error ("Base object for procedure-pointer component call at %L is of"
		 " ABSTRACT type %qs", &e->where, po->ts.u.derived->name);
      return false;
    }

  gcc_assert (tb->pass_arg_num > 0);
  e->value.compcall.actual = update_arglist_pass (e->value.compcall.actual, po,
						  tb->pass_arg_num,
						  tb->pass_arg);

  return true;
}


/* Check that the object a TBP is called on is valid, i.e. it must not be
   of ABSTRACT type (as in subobject%abstract_parent%tbp()).  */

static bool
check_typebound_baseobject (gfc_expr* e)
{
  gfc_expr* base;
  bool return_value = false;

  base = extract_compcall_passed_object (e);
  if (!base)
    return false;

  if (base->ts.type != BT_DERIVED && base->ts.type != BT_CLASS)
    {
      gfc_error ("Error in typebound call at %L", &e->where);
      goto cleanup;
    }

  if (base->ts.type == BT_CLASS && !gfc_expr_attr (base).class_ok)
    return false;

  /* F08:C611.  */
  if (base->ts.type == BT_DERIVED && base->ts.u.derived->attr.abstract)
    {
      gfc_error ("Base object for type-bound procedure call at %L is of"
		 " ABSTRACT type %qs", &e->where, base->ts.u.derived->name);
      goto cleanup;
    }

  /* F08:C1230. If the procedure called is NOPASS,
     the base object must be scalar.  */
  if (e->value.compcall.tbp->nopass && base->rank != 0)
    {
      gfc_error ("Base object for NOPASS type-bound procedure call at %L must"
		 " be scalar", &e->where);
      goto cleanup;
    }

  return_value = true;

cleanup:
  gfc_free_expr (base);
  return return_value;
}


/* Resolve a call to a type-bound procedure, either function or subroutine,
   statically from the data in an EXPR_COMPCALL expression.  The adapted
   arglist and the target-procedure symtree are returned.  */

static bool
resolve_typebound_static (gfc_expr* e, gfc_symtree** target,
			  gfc_actual_arglist** actual)
{
  gcc_assert (e->expr_type == EXPR_COMPCALL);
  gcc_assert (!e->value.compcall.tbp->is_generic);

  /* Update the actual arglist for PASS.  */
  if (!update_compcall_arglist (e))
    return false;

  *actual = e->value.compcall.actual;
  *target = e->value.compcall.tbp->u.specific;

  gfc_free_ref_list (e->ref);
  e->ref = NULL;
  e->value.compcall.actual = NULL;

  /* If we find a deferred typebound procedure, check for derived types
     that an overriding typebound procedure has not been missed.  */
  if (e->value.compcall.name
      && !e->value.compcall.tbp->non_overridable
      && e->value.compcall.base_object
      && e->value.compcall.base_object->ts.type == BT_DERIVED)
    {
      gfc_symtree *st;
      gfc_symbol *derived;

      /* Use the derived type of the base_object.  */
      derived = e->value.compcall.base_object->ts.u.derived;
      st = NULL;

      /* If necessary, go through the inheritance chain.  */
      while (!st && derived)
	{
	  /* Look for the typebound procedure 'name'.  */
	  if (derived->f2k_derived && derived->f2k_derived->tb_sym_root)
	    st = gfc_find_symtree (derived->f2k_derived->tb_sym_root,
				   e->value.compcall.name);
	  if (!st)
	    derived = gfc_get_derived_super_type (derived);
	}

      /* Now find the specific name in the derived type namespace.  */
      if (st && st->n.tb && st->n.tb->u.specific)
	gfc_find_sym_tree (st->n.tb->u.specific->name,
			   derived->ns, 1, &st);
      if (st)
	*target = st;
    }
  return true;
}


/* Get the ultimate declared type from an expression.  In addition,
   return the last class/derived type reference and the copy of the
   reference list.  If check_types is set true, derived types are
   identified as well as class references.  */
static gfc_symbol*
get_declared_from_expr (gfc_ref **class_ref, gfc_ref **new_ref,
			gfc_expr *e, bool check_types)
{
  gfc_symbol *declared;
  gfc_ref *ref;

  declared = NULL;
  if (class_ref)
    *class_ref = NULL;
  if (new_ref)
    *new_ref = gfc_copy_ref (e->ref);

  for (ref = e->ref; ref; ref = ref->next)
    {
      if (ref->type != REF_COMPONENT)
	continue;

      if ((ref->u.c.component->ts.type == BT_CLASS
	     || (check_types && gfc_bt_struct (ref->u.c.component->ts.type)))
	  && ref->u.c.component->attr.flavor != FL_PROCEDURE)
	{
	  declared = ref->u.c.component->ts.u.derived;
	  if (class_ref)
	    *class_ref = ref;
	}
    }

  if (declared == NULL)
    declared = e->symtree->n.sym->ts.u.derived;

  return declared;
}


/* Given an EXPR_COMPCALL calling a GENERIC typebound procedure, figure out
   which of the specific bindings (if any) matches the arglist and transform
   the expression into a call of that binding.  */

static bool
resolve_typebound_generic_call (gfc_expr* e, const char **name)
{
  gfc_typebound_proc* genproc;
  const char* genname;
  gfc_symtree *st;
  gfc_symbol *derived;

  gcc_assert (e->expr_type == EXPR_COMPCALL);
  genname = e->value.compcall.name;
  genproc = e->value.compcall.tbp;

  if (!genproc->is_generic)
    return true;

  /* Try the bindings on this type and in the inheritance hierarchy.  */
  for (; genproc; genproc = genproc->overridden)
    {
      gfc_tbp_generic* g;

      gcc_assert (genproc->is_generic);
      for (g = genproc->u.generic; g; g = g->next)
	{
	  gfc_symbol* target;
	  gfc_actual_arglist* args;
	  bool matches;

	  gcc_assert (g->specific);

	  if (g->specific->error)
	    continue;

	  target = g->specific->u.specific->n.sym;

	  /* Get the right arglist by handling PASS/NOPASS.  */
	  args = gfc_copy_actual_arglist (e->value.compcall.actual);
	  if (!g->specific->nopass)
	    {
	      gfc_expr* po;
	      po = extract_compcall_passed_object (e);
	      if (!po)
		{
		  gfc_free_actual_arglist (args);
		  return false;
		}

	      gcc_assert (g->specific->pass_arg_num > 0);
	      gcc_assert (!g->specific->error);
	      args = update_arglist_pass (args, po, g->specific->pass_arg_num,
					  g->specific->pass_arg);
	    }
	  resolve_actual_arglist (args, target->attr.proc,
				  is_external_proc (target)
				  && gfc_sym_get_dummy_args (target) == NULL);

	  /* Check if this arglist matches the formal.  */
	  matches = gfc_arglist_matches_symbol (&args, target);

	  /* Clean up and break out of the loop if we've found it.  */
	  gfc_free_actual_arglist (args);
	  if (matches)
	    {
	      e->value.compcall.tbp = g->specific;
	      genname = g->specific_st->name;
	      /* Pass along the name for CLASS methods, where the vtab
		 procedure pointer component has to be referenced.  */
	      if (name)
		*name = genname;
	      goto success;
	    }
	}
    }

  /* Nothing matching found!  */
  gfc_error ("Found no matching specific binding for the call to the GENERIC"
	     " %qs at %L", genname, &e->where);
  return false;

success:
  /* Make sure that we have the right specific instance for the name.  */
  derived = get_declared_from_expr (NULL, NULL, e, true);

  st = gfc_find_typebound_proc (derived, NULL, genname, true, &e->where);
  if (st)
    e->value.compcall.tbp = st->n.tb;

  return true;
}


/* Resolve a call to a type-bound subroutine.  */

static bool
resolve_typebound_call (gfc_code* c, const char **name, bool *overridable)
{
  gfc_actual_arglist* newactual;
  gfc_symtree* target;

  /* Check that's really a SUBROUTINE.  */
  if (!c->expr1->value.compcall.tbp->subroutine)
    {
      if (!c->expr1->value.compcall.tbp->is_generic
	  && c->expr1->value.compcall.tbp->u.specific
	  && c->expr1->value.compcall.tbp->u.specific->n.sym
	  && c->expr1->value.compcall.tbp->u.specific->n.sym->attr.subroutine)
	c->expr1->value.compcall.tbp->subroutine = 1;
      else
	{
	  gfc_error ("%qs at %L should be a SUBROUTINE",
		     c->expr1->value.compcall.name, &c->loc);
	  return false;
	}
    }

  if (!check_typebound_baseobject (c->expr1))
    return false;

  /* Pass along the name for CLASS methods, where the vtab
     procedure pointer component has to be referenced.  */
  if (name)
    *name = c->expr1->value.compcall.name;

  if (!resolve_typebound_generic_call (c->expr1, name))
    return false;

  /* Pass along the NON_OVERRIDABLE attribute of the specific TBP. */
  if (overridable)
    *overridable = !c->expr1->value.compcall.tbp->non_overridable;

  /* Transform into an ordinary EXEC_CALL for now.  */

  if (!resolve_typebound_static (c->expr1, &target, &newactual))
    return false;

  c->ext.actual = newactual;
  c->symtree = target;
  c->op = (c->expr1->value.compcall.assign ? EXEC_ASSIGN_CALL : EXEC_CALL);

  gcc_assert (!c->expr1->ref && !c->expr1->value.compcall.actual);

  gfc_free_expr (c->expr1);
  c->expr1 = gfc_get_expr ();
  c->expr1->expr_type = EXPR_FUNCTION;
  c->expr1->symtree = target;
  c->expr1->where = c->loc;

  return resolve_call (c);
}


/* Resolve a component-call expression.  */
static bool
resolve_compcall (gfc_expr* e, const char **name)
{
  gfc_actual_arglist* newactual;
  gfc_symtree* target;

  /* Check that's really a FUNCTION.  */
  if (!e->value.compcall.tbp->function)
    {
      gfc_error ("%qs at %L should be a FUNCTION",
		 e->value.compcall.name, &e->where);
      return false;
    }


  /* These must not be assign-calls!  */
  gcc_assert (!e->value.compcall.assign);

  if (!check_typebound_baseobject (e))
    return false;

  /* Pass along the name for CLASS methods, where the vtab
     procedure pointer component has to be referenced.  */
  if (name)
    *name = e->value.compcall.name;

  if (!resolve_typebound_generic_call (e, name))
    return false;
  gcc_assert (!e->value.compcall.tbp->is_generic);

  /* Take the rank from the function's symbol.  */
  if (e->value.compcall.tbp->u.specific->n.sym->as)
    e->rank = e->value.compcall.tbp->u.specific->n.sym->as->rank;

  /* For now, we simply transform it into an EXPR_FUNCTION call with the same
     arglist to the TBP's binding target.  */

  if (!resolve_typebound_static (e, &target, &newactual))
    return false;

  e->value.function.actual = newactual;
  e->value.function.name = NULL;
  e->value.function.esym = target->n.sym;
  e->value.function.isym = NULL;
  e->symtree = target;
  e->ts = target->n.sym->ts;
  e->expr_type = EXPR_FUNCTION;

  /* Resolution is not necessary if this is a class subroutine; this
     function only has to identify the specific proc. Resolution of
     the call will be done next in resolve_typebound_call.  */
  return gfc_resolve_expr (e);
}


static bool resolve_fl_derived (gfc_symbol *sym);


/* Resolve a typebound function, or 'method'. First separate all
   the non-CLASS references by calling resolve_compcall directly.  */

static bool
resolve_typebound_function (gfc_expr* e)
{
  gfc_symbol *declared;
  gfc_component *c;
  gfc_ref *new_ref;
  gfc_ref *class_ref;
  gfc_symtree *st;
  const char *name;
  gfc_typespec ts;
  gfc_expr *expr;
  bool overridable;

  st = e->symtree;

  /* Deal with typebound operators for CLASS objects.  */
  expr = e->value.compcall.base_object;
  overridable = !e->value.compcall.tbp->non_overridable;
  if (expr && expr->ts.type == BT_CLASS && e->value.compcall.name)
    {
      /* Since the typebound operators are generic, we have to ensure
	 that any delays in resolution are corrected and that the vtab
	 is present.  */
      ts = expr->ts;
      declared = ts.u.derived;
      c = gfc_find_component (declared, "_vptr", true, true, NULL);
      if (c->ts.u.derived == NULL)
	c->ts.u.derived = gfc_find_derived_vtab (declared);

      if (!resolve_compcall (e, &name))
	return false;

      /* Use the generic name if it is there.  */
      name = name ? name : e->value.function.esym->name;
      e->symtree = expr->symtree;
      e->ref = gfc_copy_ref (expr->ref);
      get_declared_from_expr (&class_ref, NULL, e, false);

      /* Trim away the extraneous references that emerge from nested
	 use of interface.c (extend_expr).  */
      if (class_ref && class_ref->next)
	{
	  gfc_free_ref_list (class_ref->next);
	  class_ref->next = NULL;
	}
      else if (e->ref && !class_ref && expr->ts.type != BT_CLASS)
	{
	  gfc_free_ref_list (e->ref);
	  e->ref = NULL;
	}

      gfc_add_vptr_component (e);
      gfc_add_component_ref (e, name);
      e->value.function.esym = NULL;
      if (expr->expr_type != EXPR_VARIABLE)
	e->base_expr = expr;
      return true;
    }

  if (st == NULL)
    return resolve_compcall (e, NULL);

  if (!gfc_resolve_ref (e))
    return false;

  /* Get the CLASS declared type.  */
  declared = get_declared_from_expr (&class_ref, &new_ref, e, true);

  if (!resolve_fl_derived (declared))
    return false;

  /* Weed out cases of the ultimate component being a derived type.  */
  if ((class_ref && gfc_bt_struct (class_ref->u.c.component->ts.type))
	 || (!class_ref && st->n.sym->ts.type != BT_CLASS))
    {
      gfc_free_ref_list (new_ref);
      return resolve_compcall (e, NULL);
    }

  c = gfc_find_component (declared, "_data", true, true, NULL);

  /* Treat the call as if it is a typebound procedure, in order to roll
     out the correct name for the specific function.  */
  if (!resolve_compcall (e, &name))
    {
      gfc_free_ref_list (new_ref);
      return false;
    }
  ts = e->ts;

  if (overridable)
    {
      /* Convert the expression to a procedure pointer component call.  */
      e->value.function.esym = NULL;
      e->symtree = st;

      if (new_ref)
	e->ref = new_ref;

      /* '_vptr' points to the vtab, which contains the procedure pointers.  */
      gfc_add_vptr_component (e);
      gfc_add_component_ref (e, name);

      /* Recover the typespec for the expression.  This is really only
	necessary for generic procedures, where the additional call
	to gfc_add_component_ref seems to throw the collection of the
	correct typespec.  */
      e->ts = ts;
    }
  else if (new_ref)
    gfc_free_ref_list (new_ref);

  return true;
}

/* Resolve a typebound subroutine, or 'method'. First separate all
   the non-CLASS references by calling resolve_typebound_call
   directly.  */

static bool
resolve_typebound_subroutine (gfc_code *code)
{
  gfc_symbol *declared;
  gfc_component *c;
  gfc_ref *new_ref;
  gfc_ref *class_ref;
  gfc_symtree *st;
  const char *name;
  gfc_typespec ts;
  gfc_expr *expr;
  bool overridable;

  st = code->expr1->symtree;

  /* Deal with typebound operators for CLASS objects.  */
  expr = code->expr1->value.compcall.base_object;
  overridable = !code->expr1->value.compcall.tbp->non_overridable;
  if (expr && expr->ts.type == BT_CLASS && code->expr1->value.compcall.name)
    {
      /* If the base_object is not a variable, the corresponding actual
	 argument expression must be stored in e->base_expression so
	 that the corresponding tree temporary can be used as the base
	 object in gfc_conv_procedure_call.  */
      if (expr->expr_type != EXPR_VARIABLE)
	{
	  gfc_actual_arglist *args;

	  args= code->expr1->value.function.actual;
	  for (; args; args = args->next)
	    if (expr == args->expr)
	      expr = args->expr;
	}

      /* Since the typebound operators are generic, we have to ensure
	 that any delays in resolution are corrected and that the vtab
	 is present.  */
      declared = expr->ts.u.derived;
      c = gfc_find_component (declared, "_vptr", true, true, NULL);
      if (c->ts.u.derived == NULL)
	c->ts.u.derived = gfc_find_derived_vtab (declared);

      if (!resolve_typebound_call (code, &name, NULL))
	return false;

      /* Use the generic name if it is there.  */
      name = name ? name : code->expr1->value.function.esym->name;
      code->expr1->symtree = expr->symtree;
      code->expr1->ref = gfc_copy_ref (expr->ref);

      /* Trim away the extraneous references that emerge from nested
	 use of interface.c (extend_expr).  */
      get_declared_from_expr (&class_ref, NULL, code->expr1, false);
      if (class_ref && class_ref->next)
	{
	  gfc_free_ref_list (class_ref->next);
	  class_ref->next = NULL;
	}
      else if (code->expr1->ref && !class_ref)
	{
	  gfc_free_ref_list (code->expr1->ref);
	  code->expr1->ref = NULL;
	}

      /* Now use the procedure in the vtable.  */
      gfc_add_vptr_component (code->expr1);
      gfc_add_component_ref (code->expr1, name);
      code->expr1->value.function.esym = NULL;
      if (expr->expr_type != EXPR_VARIABLE)
	code->expr1->base_expr = expr;
      return true;
    }

  if (st == NULL)
    return resolve_typebound_call (code, NULL, NULL);

  if (!gfc_resolve_ref (code->expr1))
    return false;

  /* Get the CLASS declared type.  */
  get_declared_from_expr (&class_ref, &new_ref, code->expr1, true);

  /* Weed out cases of the ultimate component being a derived type.  */
  if ((class_ref && gfc_bt_struct (class_ref->u.c.component->ts.type))
	 || (!class_ref && st->n.sym->ts.type != BT_CLASS))
    {
      gfc_free_ref_list (new_ref);
      return resolve_typebound_call (code, NULL, NULL);
    }

  if (!resolve_typebound_call (code, &name, &overridable))
    {
      gfc_free_ref_list (new_ref);
      return false;
    }
  ts = code->expr1->ts;

  if (overridable)
    {
      /* Convert the expression to a procedure pointer component call.  */
      code->expr1->value.function.esym = NULL;
      code->expr1->symtree = st;

      if (new_ref)
	code->expr1->ref = new_ref;

      /* '_vptr' points to the vtab, which contains the procedure pointers.  */
      gfc_add_vptr_component (code->expr1);
      gfc_add_component_ref (code->expr1, name);

      /* Recover the typespec for the expression.  This is really only
	necessary for generic procedures, where the additional call
	to gfc_add_component_ref seems to throw the collection of the
	correct typespec.  */
      code->expr1->ts = ts;
    }
  else if (new_ref)
    gfc_free_ref_list (new_ref);

  return true;
}


/* Resolve a CALL to a Procedure Pointer Component (Subroutine).  */

static bool
resolve_ppc_call (gfc_code* c)
{
  gfc_component *comp;

  comp = gfc_get_proc_ptr_comp (c->expr1);
  gcc_assert (comp != NULL);

  c->resolved_sym = c->expr1->symtree->n.sym;
  c->expr1->expr_type = EXPR_VARIABLE;

  if (!comp->attr.subroutine)
    gfc_add_subroutine (&comp->attr, comp->name, &c->expr1->where);

  if (!gfc_resolve_ref (c->expr1))
    return false;

  if (!update_ppc_arglist (c->expr1))
    return false;

  c->ext.actual = c->expr1->value.compcall.actual;

  if (!resolve_actual_arglist (c->ext.actual, comp->attr.proc,
			       !(comp->ts.interface
				 && comp->ts.interface->formal)))
    return false;

  if (!pure_subroutine (comp->ts.interface, comp->name, &c->expr1->where))
    return false;

  gfc_ppc_use (comp, &c->expr1->value.compcall.actual, &c->expr1->where);

  return true;
}


/* Resolve a Function Call to a Procedure Pointer Component (Function).  */

static bool
resolve_expr_ppc (gfc_expr* e)
{
  gfc_component *comp;

  comp = gfc_get_proc_ptr_comp (e);
  gcc_assert (comp != NULL);

  /* Convert to EXPR_FUNCTION.  */
  e->expr_type = EXPR_FUNCTION;
  e->value.function.isym = NULL;
  e->value.function.actual = e->value.compcall.actual;
  e->ts = comp->ts;
  if (comp->as != NULL)
    e->rank = comp->as->rank;

  if (!comp->attr.function)
    gfc_add_function (&comp->attr, comp->name, &e->where);

  if (!gfc_resolve_ref (e))
    return false;

  if (!resolve_actual_arglist (e->value.function.actual, comp->attr.proc,
			       !(comp->ts.interface
				 && comp->ts.interface->formal)))
    return false;

  if (!update_ppc_arglist (e))
    return false;

  if (!check_pure_function(e))
    return false;

  gfc_ppc_use (comp, &e->value.compcall.actual, &e->where);

  return true;
}


static bool
gfc_is_expandable_expr (gfc_expr *e)
{
  gfc_constructor *con;

  if (e->expr_type == EXPR_ARRAY)
    {
      /* Traverse the constructor looking for variables that are flavor
	 parameter.  Parameters must be expanded since they are fully used at
	 compile time.  */
      con = gfc_constructor_first (e->value.constructor);
      for (; con; con = gfc_constructor_next (con))
	{
	  if (con->expr->expr_type == EXPR_VARIABLE
	      && con->expr->symtree
	      && (con->expr->symtree->n.sym->attr.flavor == FL_PARAMETER
	      || con->expr->symtree->n.sym->attr.flavor == FL_VARIABLE))
	    return true;
	  if (con->expr->expr_type == EXPR_ARRAY
	      && gfc_is_expandable_expr (con->expr))
	    return true;
	}
    }

  return false;
}


/* Sometimes variables in specification expressions of the result
   of module procedures in submodules wind up not being the 'real'
   dummy.  Find this, if possible, in the namespace of the first
   formal argument.  */

static void
fixup_unique_dummy (gfc_expr *e)
{
  gfc_symtree *st = NULL;
  gfc_symbol *s = NULL;

  if (e->symtree->n.sym->ns->proc_name
      && e->symtree->n.sym->ns->proc_name->formal)
    s = e->symtree->n.sym->ns->proc_name->formal->sym;

  if (s != NULL)
    st = gfc_find_symtree (s->ns->sym_root, e->symtree->n.sym->name);

  if (st != NULL
      && st->n.sym != NULL
      && st->n.sym->attr.dummy)
    e->symtree = st;
}

/* Resolve an expression.  That is, make sure that types of operands agree
   with their operators, intrinsic operators are converted to function calls
   for overloaded types and unresolved function references are resolved.  */

bool
gfc_resolve_expr (gfc_expr *e)
{
  bool t;
  bool inquiry_save, actual_arg_save, first_actual_arg_save;

  if (e == NULL || e->do_not_resolve_again)
    return true;

  /* inquiry_argument only applies to variables.  */
  inquiry_save = inquiry_argument;
  actual_arg_save = actual_arg;
  first_actual_arg_save = first_actual_arg;

  if (e->expr_type != EXPR_VARIABLE)
    {
      inquiry_argument = false;
      actual_arg = false;
      first_actual_arg = false;
    }
  else if (e->symtree != NULL
	   && *e->symtree->name == '@'
	   && e->symtree->n.sym->attr.dummy)
    {
      /* Deal with submodule specification expressions that are not
	 found to be referenced in module.c(read_cleanup).  */
      fixup_unique_dummy (e);
    }

  switch (e->expr_type)
    {
    case EXPR_OP:
      t = resolve_operator (e);
      break;

    case EXPR_FUNCTION:
    case EXPR_VARIABLE:

      if (check_host_association (e))
	t = resolve_function (e);
      else
	t = resolve_variable (e);

      if (e->ts.type == BT_CHARACTER && e->ts.u.cl == NULL && e->ref
	  && e->ref->type != REF_SUBSTRING)
	gfc_resolve_substring_charlen (e);

      break;

    case EXPR_COMPCALL:
      t = resolve_typebound_function (e);
      break;

    case EXPR_SUBSTRING:
      t = gfc_resolve_ref (e);
      break;

    case EXPR_CONSTANT:
    case EXPR_NULL:
      t = true;
      break;

    case EXPR_PPC:
      t = resolve_expr_ppc (e);
      break;

    case EXPR_ARRAY:
      t = false;
      if (!gfc_resolve_ref (e))
	break;

      t = gfc_resolve_array_constructor (e);
      /* Also try to expand a constructor.  */
      if (t)
	{
	  gfc_expression_rank (e);
	  if (gfc_is_constant_expr (e) || gfc_is_expandable_expr (e))
	    gfc_expand_constructor (e, false);
	}

      /* This provides the opportunity for the length of constructors with
	 character valued function elements to propagate the string length
	 to the expression.  */
      if (t && e->ts.type == BT_CHARACTER)
        {
	  /* For efficiency, we call gfc_expand_constructor for BT_CHARACTER
	     here rather then add a duplicate test for it above.  */
	  gfc_expand_constructor (e, false);
	  t = gfc_resolve_character_array_constructor (e);
	}

      break;

    case EXPR_STRUCTURE:
      t = gfc_resolve_ref (e);
      if (!t)
	break;

      t = resolve_structure_cons (e, 0);
      if (!t)
	break;

      t = gfc_simplify_expr (e, 0);
      break;

    default:
      gfc_internal_error ("gfc_resolve_expr(): Bad expression type");
    }

  if (e->ts.type == BT_CHARACTER && t && !e->ts.u.cl)
    fixup_charlen (e);

  inquiry_argument = inquiry_save;
  actual_arg = actual_arg_save;
  first_actual_arg = first_actual_arg_save;

  /* For some reason, resolving these expressions a second time mangles
     the typespec of the expression itself.  */
  if (t && e->expr_type == EXPR_VARIABLE
      && e->symtree->n.sym->attr.select_rank_temporary
      && UNLIMITED_POLY (e->symtree->n.sym))
    e->do_not_resolve_again = 1;

  return t;
}


/* Resolve an expression from an iterator.  They must be scalar and have
   INTEGER or (optionally) REAL type.  */

static bool
gfc_resolve_iterator_expr (gfc_expr *expr, bool real_ok,
			   const char *name_msgid)
{
  if (!gfc_resolve_expr (expr))
    return false;

  if (expr->rank != 0)
    {
      gfc_error ("%s at %L must be a scalar", _(name_msgid), &expr->where);
      return false;
    }

  if (expr->ts.type != BT_INTEGER)
    {
      if (expr->ts.type == BT_REAL)
	{
	  if (real_ok)
	    return gfc_notify_std (GFC_STD_F95_DEL,
				   "%s at %L must be integer",
				   _(name_msgid), &expr->where);
	  else
	    {
	      gfc_error ("%s at %L must be INTEGER", _(name_msgid),
			 &expr->where);
	      return false;
	    }
	}
      else
	{
	  gfc_error ("%s at %L must be INTEGER", _(name_msgid), &expr->where);
	  return false;
	}
    }
  return true;
}


/* Resolve the expressions in an iterator structure.  If REAL_OK is
   false allow only INTEGER type iterators, otherwise allow REAL types.
   Set own_scope to true for ac-implied-do and data-implied-do as those
   have a separate scope such that, e.g., a INTENT(IN) doesn't apply.  */

bool
gfc_resolve_iterator (gfc_iterator *iter, bool real_ok, bool own_scope)
{
  if (!gfc_resolve_iterator_expr (iter->var, real_ok, "Loop variable"))
    return false;

  if (!gfc_check_vardef_context (iter->var, false, false, own_scope,
				 _("iterator variable")))
    return false;

  if (!gfc_resolve_iterator_expr (iter->start, real_ok,
				  "Start expression in DO loop"))
    return false;

  if (!gfc_resolve_iterator_expr (iter->end, real_ok,
				  "End expression in DO loop"))
    return false;

  if (!gfc_resolve_iterator_expr (iter->step, real_ok,
				  "Step expression in DO loop"))
    return false;

  /* Convert start, end, and step to the same type as var.  */
  if (iter->start->ts.kind != iter->var->ts.kind
      || iter->start->ts.type != iter->var->ts.type)
    gfc_convert_type (iter->start, &iter->var->ts, 1);

  if (iter->end->ts.kind != iter->var->ts.kind
      || iter->end->ts.type != iter->var->ts.type)
    gfc_convert_type (iter->end, &iter->var->ts, 1);

  if (iter->step->ts.kind != iter->var->ts.kind
      || iter->step->ts.type != iter->var->ts.type)
    gfc_convert_type (iter->step, &iter->var->ts, 1);

  if (iter->step->expr_type == EXPR_CONSTANT)
    {
      if ((iter->step->ts.type == BT_INTEGER
	   && mpz_cmp_ui (iter->step->value.integer, 0) == 0)
	  || (iter->step->ts.type == BT_REAL
	      && mpfr_sgn (iter->step->value.real) == 0))
	{
	  gfc_error ("Step expression in DO loop at %L cannot be zero",
		     &iter->step->where);
	  return false;
	}
    }

  if (iter->start->expr_type == EXPR_CONSTANT
      && iter->end->expr_type == EXPR_CONSTANT
      && iter->step->expr_type == EXPR_CONSTANT)
    {
      int sgn, cmp;
      if (iter->start->ts.type == BT_INTEGER)
	{
	  sgn = mpz_cmp_ui (iter->step->value.integer, 0);
	  cmp = mpz_cmp (iter->end->value.integer, iter->start->value.integer);
	}
      else
	{
	  sgn = mpfr_sgn (iter->step->value.real);
	  cmp = mpfr_cmp (iter->end->value.real, iter->start->value.real);
	}
      if (warn_zerotrip && ((sgn > 0 && cmp < 0) || (sgn < 0 && cmp > 0)))
	gfc_warning (OPT_Wzerotrip,
		     "DO loop at %L will be executed zero times",
		     &iter->step->where);
    }

  if (iter->end->expr_type == EXPR_CONSTANT
      && iter->end->ts.type == BT_INTEGER
      && iter->step->expr_type == EXPR_CONSTANT
      && iter->step->ts.type == BT_INTEGER
      && (mpz_cmp_si (iter->step->value.integer, -1L) == 0
	  || mpz_cmp_si (iter->step->value.integer, 1L) == 0))
    {
      bool is_step_positive = mpz_cmp_ui (iter->step->value.integer, 1) == 0;
      int k = gfc_validate_kind (BT_INTEGER, iter->end->ts.kind, false);

      if (is_step_positive
	  && mpz_cmp (iter->end->value.integer, gfc_integer_kinds[k].huge) == 0)
	gfc_warning (OPT_Wundefined_do_loop,
		     "DO loop at %L is undefined as it overflows",
		     &iter->step->where);
      else if (!is_step_positive
	       && mpz_cmp (iter->end->value.integer,
			   gfc_integer_kinds[k].min_int) == 0)
	gfc_warning (OPT_Wundefined_do_loop,
		     "DO loop at %L is undefined as it underflows",
		     &iter->step->where);
    }

  return true;
}


/* Traversal function for find_forall_index.  f == 2 signals that
   that variable itself is not to be checked - only the references.  */

static bool
forall_index (gfc_expr *expr, gfc_symbol *sym, int *f)
{
  if (expr->expr_type != EXPR_VARIABLE)
    return false;

  /* A scalar assignment  */
  if (!expr->ref || *f == 1)
    {
      if (expr->symtree->n.sym == sym)
	return true;
      else
	return false;
    }

  if (*f == 2)
    *f = 1;
  return false;
}


/* Check whether the FORALL index appears in the expression or not.
   Returns true if SYM is found in EXPR.  */

bool
find_forall_index (gfc_expr *expr, gfc_symbol *sym, int f)
{
  if (gfc_traverse_expr (expr, sym, forall_index, f))
    return true;
  else
    return false;
}


/* Resolve a list of FORALL iterators.  The FORALL index-name is constrained
   to be a scalar INTEGER variable.  The subscripts and stride are scalar
   INTEGERs, and if stride is a constant it must be nonzero.
   Furthermore "A subscript or stride in a forall-triplet-spec shall
   not contain a reference to any index-name in the
   forall-triplet-spec-list in which it appears." (7.5.4.1)  */

static void
resolve_forall_iterators (gfc_forall_iterator *it)
{
  gfc_forall_iterator *iter, *iter2;

  for (iter = it; iter; iter = iter->next)
    {
      if (gfc_resolve_expr (iter->var)
	  && (iter->var->ts.type != BT_INTEGER || iter->var->rank != 0))
	gfc_error ("FORALL index-name at %L must be a scalar INTEGER",
		   &iter->var->where);

      if (gfc_resolve_expr (iter->start)
	  && (iter->start->ts.type != BT_INTEGER || iter->start->rank != 0))
	gfc_error ("FORALL start expression at %L must be a scalar INTEGER",
		   &iter->start->where);
      if (iter->var->ts.kind != iter->start->ts.kind)
	gfc_convert_type (iter->start, &iter->var->ts, 1);

      if (gfc_resolve_expr (iter->end)
	  && (iter->end->ts.type != BT_INTEGER || iter->end->rank != 0))
	gfc_error ("FORALL end expression at %L must be a scalar INTEGER",
		   &iter->end->where);
      if (iter->var->ts.kind != iter->end->ts.kind)
	gfc_convert_type (iter->end, &iter->var->ts, 1);

      if (gfc_resolve_expr (iter->stride))
	{
	  if (iter->stride->ts.type != BT_INTEGER || iter->stride->rank != 0)
	    gfc_error ("FORALL stride expression at %L must be a scalar %s",
		       &iter->stride->where, "INTEGER");

	  if (iter->stride->expr_type == EXPR_CONSTANT
	      && mpz_cmp_ui (iter->stride->value.integer, 0) == 0)
	    gfc_error ("FORALL stride expression at %L cannot be zero",
		       &iter->stride->where);
	}
      if (iter->var->ts.kind != iter->stride->ts.kind)
	gfc_convert_type (iter->stride, &iter->var->ts, 1);
    }

  for (iter = it; iter; iter = iter->next)
    for (iter2 = iter; iter2; iter2 = iter2->next)
      {
	if (find_forall_index (iter2->start, iter->var->symtree->n.sym, 0)
	    || find_forall_index (iter2->end, iter->var->symtree->n.sym, 0)
	    || find_forall_index (iter2->stride, iter->var->symtree->n.sym, 0))
	  gfc_error ("FORALL index %qs may not appear in triplet "
		     "specification at %L", iter->var->symtree->name,
		     &iter2->start->where);
      }
}


/* Given a pointer to a symbol that is a derived type, see if it's
   inaccessible, i.e. if it's defined in another module and the components are
   PRIVATE.  The search is recursive if necessary.  Returns zero if no
   inaccessible components are found, nonzero otherwise.  */

static int
derived_inaccessible (gfc_symbol *sym)
{
  gfc_component *c;

  if (sym->attr.use_assoc && sym->attr.private_comp)
    return 1;

  for (c = sym->components; c; c = c->next)
    {
	/* Prevent an infinite loop through this function.  */
	if (c->ts.type == BT_DERIVED && c->attr.pointer
	    && sym == c->ts.u.derived)
	  continue;

	if (c->ts.type == BT_DERIVED && derived_inaccessible (c->ts.u.derived))
	  return 1;
    }

  return 0;
}


/* Resolve the argument of a deallocate expression.  The expression must be
   a pointer or a full array.  */

static bool
resolve_deallocate_expr (gfc_expr *e)
{
  symbol_attribute attr;
  int allocatable, pointer;
  gfc_ref *ref;
  gfc_symbol *sym;
  gfc_component *c;
  bool unlimited;

  if (!gfc_resolve_expr (e))
    return false;

  if (e->expr_type != EXPR_VARIABLE)
    goto bad;

  sym = e->symtree->n.sym;
  unlimited = UNLIMITED_POLY(sym);

  if (sym->ts.type == BT_CLASS)
    {
      allocatable = CLASS_DATA (sym)->attr.allocatable;
      pointer = CLASS_DATA (sym)->attr.class_pointer;
    }
  else
    {
      allocatable = sym->attr.allocatable;
      pointer = sym->attr.pointer;
    }
  for (ref = e->ref; ref; ref = ref->next)
    {
      switch (ref->type)
	{
	case REF_ARRAY:
	  if (ref->u.ar.type != AR_FULL
	      && !(ref->u.ar.type == AR_ELEMENT && ref->u.ar.as->rank == 0
	           && ref->u.ar.codimen && gfc_ref_this_image (ref)))
	    allocatable = 0;
	  break;

	case REF_COMPONENT:
	  c = ref->u.c.component;
	  if (c->ts.type == BT_CLASS)
	    {
	      allocatable = CLASS_DATA (c)->attr.allocatable;
	      pointer = CLASS_DATA (c)->attr.class_pointer;
	    }
	  else
	    {
	      allocatable = c->attr.allocatable;
	      pointer = c->attr.pointer;
	    }
	  break;

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

  attr = gfc_expr_attr (e);

  if (allocatable == 0 && attr.pointer == 0 && !unlimited)
    {
    bad:
      gfc_error ("Allocate-object at %L must be ALLOCATABLE or a POINTER",
		 &e->where);
      return false;
    }

  /* F2008, C644.  */
  if (gfc_is_coindexed (e))
    {
      gfc_error ("Coindexed allocatable object at %L", &e->where);
      return false;
    }

  if (pointer
      && !gfc_check_vardef_context (e, true, true, false,
				    _("DEALLOCATE object")))
    return false;
  if (!gfc_check_vardef_context (e, false, true, false,
				 _("DEALLOCATE object")))
    return false;

  return true;
}


/* Returns true if the expression e contains a reference to the symbol sym.  */
static bool
sym_in_expr (gfc_expr *e, gfc_symbol *sym, int *f ATTRIBUTE_UNUSED)
{
  if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym == sym)
    return true;

  return false;
}

bool
gfc_find_sym_in_expr (gfc_symbol *sym, gfc_expr *e)
{
  return gfc_traverse_expr (e, sym, sym_in_expr, 0);
}


/* Given the expression node e for an allocatable/pointer of derived type to be
   allocated, get the expression node to be initialized afterwards (needed for
   derived types with default initializers, and derived types with allocatable
   components that need nullification.)  */

gfc_expr *
gfc_expr_to_initialize (gfc_expr *e)
{
  gfc_expr *result;
  gfc_ref *ref;
  int i;

  result = gfc_copy_expr (e);

  /* Change the last array reference from AR_ELEMENT to AR_FULL.  */
  for (ref = result->ref; ref; ref = ref->next)
    if (ref->type == REF_ARRAY && ref->next == NULL)
      {
	if (ref->u.ar.dimen == 0
	    && ref->u.ar.as && ref->u.ar.as->corank)
	  return result;

	ref->u.ar.type = AR_FULL;

	for (i = 0; i < ref->u.ar.dimen; i++)
	  ref->u.ar.start[i] = ref->u.ar.end[i] = ref->u.ar.stride[i] = NULL;

	break;
      }

  gfc_free_shape (&result->shape, result->rank);

  /* Recalculate rank, shape, etc.  */
  gfc_resolve_expr (result);
  return result;
}


/* If the last ref of an expression is an array ref, return a copy of the
   expression with that one removed.  Otherwise, a copy of the original
   expression.  This is used for allocate-expressions and pointer assignment
   LHS, where there may be an array specification that needs to be stripped
   off when using gfc_check_vardef_context.  */

static gfc_expr*
remove_last_array_ref (gfc_expr* e)
{
  gfc_expr* e2;
  gfc_ref** r;

  e2 = gfc_copy_expr (e);
  for (r = &e2->ref; *r; r = &(*r)->next)
    if ((*r)->type == REF_ARRAY && !(*r)->next)
      {
	gfc_free_ref_list (*r);
	*r = NULL;
	break;
      }

  return e2;
}


/* Used in resolve_allocate_expr to check that a allocation-object and
   a source-expr are conformable.  This does not catch all possible
   cases; in particular a runtime checking is needed.  */

static bool
conformable_arrays (gfc_expr *e1, gfc_expr *e2)
{
  gfc_ref *tail;
  for (tail = e2->ref; tail && tail->next; tail = tail->next);

  /* First compare rank.  */
  if ((tail && (!tail->u.ar.as || e1->rank != tail->u.ar.as->rank))
      || (!tail && e1->rank != e2->rank))
    {
      gfc_error ("Source-expr at %L must be scalar or have the "
		 "same rank as the allocate-object at %L",
		 &e1->where, &e2->where);
      return false;
    }

  if (e1->shape)
    {
      int i;
      mpz_t s;

      mpz_init (s);

      for (i = 0; i < e1->rank; i++)
	{
	  if (tail->u.ar.start[i] == NULL)
	    break;

	  if (tail->u.ar.end[i])
	    {
	      mpz_set (s, tail->u.ar.end[i]->value.integer);
	      mpz_sub (s, s, tail->u.ar.start[i]->value.integer);
	      mpz_add_ui (s, s, 1);
	    }
	  else
	    {
	      mpz_set (s, tail->u.ar.start[i]->value.integer);
	    }

	  if (mpz_cmp (e1->shape[i], s) != 0)
	    {
	      gfc_error ("Source-expr at %L and allocate-object at %L must "
			 "have the same shape", &e1->where, &e2->where);
	      mpz_clear (s);
   	      return false;
	    }
	}

      mpz_clear (s);
    }

  return true;
}


/* Resolve the expression in an ALLOCATE statement, doing the additional
   checks to see whether the expression is OK or not.  The expression must
   have a trailing array reference that gives the size of the array.  */

static bool
resolve_allocate_expr (gfc_expr *e, gfc_code *code, bool *array_alloc_wo_spec)
{
  int i, pointer, allocatable, dimension, is_abstract;
  int codimension;
  bool coindexed;
  bool unlimited;
  symbol_attribute attr;
  gfc_ref *ref, *ref2;
  gfc_expr *e2;
  gfc_array_ref *ar;
  gfc_symbol *sym = NULL;
  gfc_alloc *a;
  gfc_component *c;
  bool t;

  /* Mark the utmost array component as being in allocate to allow DIMEN_STAR
     checking of coarrays.  */
  for (ref = e->ref; ref; ref = ref->next)
    if (ref->next == NULL)
      break;

  if (ref && ref->type == REF_ARRAY)
    ref->u.ar.in_allocate = true;

  if (!gfc_resolve_expr (e))
    goto failure;

  /* Make sure the expression is allocatable or a pointer.  If it is
     pointer, the next-to-last reference must be a pointer.  */

  ref2 = NULL;
  if (e->symtree)
    sym = e->symtree->n.sym;

  /* Check whether ultimate component is abstract and CLASS.  */
  is_abstract = 0;

  /* Is the allocate-object unlimited polymorphic?  */
  unlimited = UNLIMITED_POLY(e);

  if (e->expr_type != EXPR_VARIABLE)
    {
      allocatable = 0;
      attr = gfc_expr_attr (e);
      pointer = attr.pointer;
      dimension = attr.dimension;
      codimension = attr.codimension;
    }
  else
    {
      if (sym->ts.type == BT_CLASS && CLASS_DATA (sym))
	{
	  allocatable = CLASS_DATA (sym)->attr.allocatable;
	  pointer = CLASS_DATA (sym)->attr.class_pointer;
	  dimension = CLASS_DATA (sym)->attr.dimension;
	  codimension = CLASS_DATA (sym)->attr.codimension;
	  is_abstract = CLASS_DATA (sym)->attr.abstract;
	}
      else
	{
	  allocatable = sym->attr.allocatable;
	  pointer = sym->attr.pointer;
	  dimension = sym->attr.dimension;
	  codimension = sym->attr.codimension;
	}

      coindexed = false;

      for (ref = e->ref; ref; ref2 = ref, ref = ref->next)
	{
	  switch (ref->type)
	    {
 	      case REF_ARRAY:
                if (ref->u.ar.codimen > 0)
		  {
		    int n;
		    for (n = ref->u.ar.dimen;
			 n < ref->u.ar.dimen + ref->u.ar.codimen; n++)
		      if (ref->u.ar.dimen_type[n] != DIMEN_THIS_IMAGE)
			{
			  coindexed = true;
			  break;
			}
		   }

		if (ref->next != NULL)
		  pointer = 0;
		break;

	      case REF_COMPONENT:
		/* F2008, C644.  */
		if (coindexed)
		  {
		    gfc_error ("Coindexed allocatable object at %L",
			       &e->where);
		    goto failure;
		  }

		c = ref->u.c.component;
		if (c->ts.type == BT_CLASS)
		  {
		    allocatable = CLASS_DATA (c)->attr.allocatable;
		    pointer = CLASS_DATA (c)->attr.class_pointer;
		    dimension = CLASS_DATA (c)->attr.dimension;
		    codimension = CLASS_DATA (c)->attr.codimension;
		    is_abstract = CLASS_DATA (c)->attr.abstract;
		  }
		else
		  {
		    allocatable = c->attr.allocatable;
		    pointer = c->attr.pointer;
		    dimension = c->attr.dimension;
		    codimension = c->attr.codimension;
		    is_abstract = c->attr.abstract;
		  }
		break;

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

  /* Check for F08:C628 (F2018:C932).  Each allocate-object shall be a data
     pointer or an allocatable variable.  */
  if (allocatable == 0 && pointer == 0)
    {
      gfc_error ("Allocate-object at %L must be ALLOCATABLE or a POINTER",
		 &e->where);
      goto failure;
    }

  /* Some checks for the SOURCE tag.  */
  if (code->expr3)
    {
      /* Check F03:C631.  */
      if (!gfc_type_compatible (&e->ts, &code->expr3->ts))
	{
	  gfc_error ("Type of entity at %L is type incompatible with "
		     "source-expr at %L", &e->where, &code->expr3->where);
	  goto failure;
	}

      /* Check F03:C632 and restriction following Note 6.18.  */
      if (code->expr3->rank > 0 && !conformable_arrays (code->expr3, e))
	goto failure;

      /* Check F03:C633.  */
      if (code->expr3->ts.kind != e->ts.kind && !unlimited)
	{
	  gfc_error ("The allocate-object at %L and the source-expr at %L "
		     "shall have the same kind type parameter",
		     &e->where, &code->expr3->where);
	  goto failure;
	}

      /* Check F2008, C642.  */
      if (code->expr3->ts.type == BT_DERIVED
	  && ((codimension && gfc_expr_attr (code->expr3).lock_comp)
	      || (code->expr3->ts.u.derived->from_intmod
		     == INTMOD_ISO_FORTRAN_ENV
		  && code->expr3->ts.u.derived->intmod_sym_id
		     == ISOFORTRAN_LOCK_TYPE)))
	{
	  gfc_error ("The source-expr at %L shall neither be of type "
		     "LOCK_TYPE nor have a LOCK_TYPE component if "
		      "allocate-object at %L is a coarray",
		      &code->expr3->where, &e->where);
	  goto failure;
	}

      /* Check TS18508, C702/C703.  */
      if (code->expr3->ts.type == BT_DERIVED
	  && ((codimension && gfc_expr_attr (code->expr3).event_comp)
	      || (code->expr3->ts.u.derived->from_intmod
		     == INTMOD_ISO_FORTRAN_ENV
		  && code->expr3->ts.u.derived->intmod_sym_id
		     == ISOFORTRAN_EVENT_TYPE)))
	{
	  gfc_error ("The source-expr at %L shall neither be of type "
		     "EVENT_TYPE nor have a EVENT_TYPE component if "
		      "allocate-object at %L is a coarray",
		      &code->expr3->where, &e->where);
	  goto failure;
	}
    }

  /* Check F08:C629.  */
  if (is_abstract && code->ext.alloc.ts.type == BT_UNKNOWN
      && !code->expr3)
    {
      gcc_assert (e->ts.type == BT_CLASS);
      gfc_error ("Allocating %s of ABSTRACT base type at %L requires a "
		 "type-spec or source-expr", sym->name, &e->where);
      goto failure;
    }

  /* Check F08:C632.  */
  if (code->ext.alloc.ts.type == BT_CHARACTER && !e->ts.deferred
      && !UNLIMITED_POLY (e))
    {
      int cmp;

      if (!e->ts.u.cl->length)
	goto failure;

      cmp = gfc_dep_compare_expr (e->ts.u.cl->length,
				  code->ext.alloc.ts.u.cl->length);
      if (cmp == 1 || cmp == -1 || cmp == -3)
	{
	  gfc_error ("Allocating %s at %L with type-spec requires the same "
		     "character-length parameter as in the declaration",
		     sym->name, &e->where);
	  goto failure;
	}
    }

  /* In the variable definition context checks, gfc_expr_attr is used
     on the expression.  This is fooled by the array specification
     present in e, thus we have to eliminate that one temporarily.  */
  e2 = remove_last_array_ref (e);
  t = true;
  if (t && pointer)
    t = gfc_check_vardef_context (e2, true, true, false,
				  _("ALLOCATE object"));
  if (t)
    t = gfc_check_vardef_context (e2, false, true, false,
				  _("ALLOCATE object"));
  gfc_free_expr (e2);
  if (!t)
    goto failure;

  if (e->ts.type == BT_CLASS && CLASS_DATA (e)->attr.dimension
	&& !code->expr3 && code->ext.alloc.ts.type == BT_DERIVED)
    {
      /* For class arrays, the initialization with SOURCE is done
	 using _copy and trans_call. It is convenient to exploit that
	 when the allocated type is different from the declared type but
	 no SOURCE exists by setting expr3.  */
      code->expr3 = gfc_default_initializer (&code->ext.alloc.ts);
    }
  else if (flag_coarray != GFC_FCOARRAY_LIB && e->ts.type == BT_DERIVED
	   && e->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
	   && e->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
    {
      /* We have to zero initialize the integer variable.  */
      code->expr3 = gfc_get_int_expr (gfc_default_integer_kind, &e->where, 0);
    }

  if (e->ts.type == BT_CLASS && !unlimited && !UNLIMITED_POLY (code->expr3))
    {
      /* Make sure the vtab symbol is present when
	 the module variables are generated.  */
      gfc_typespec ts = e->ts;
      if (code->expr3)
	ts = code->expr3->ts;
      else if (code->ext.alloc.ts.type == BT_DERIVED)
	ts = code->ext.alloc.ts;

      /* Finding the vtab also publishes the type's symbol.  Therefore this
	 statement is necessary.  */
      gfc_find_derived_vtab (ts.u.derived);
    }
  else if (unlimited && !UNLIMITED_POLY (code->expr3))
    {
      /* Again, make sure the vtab symbol is present when
	 the module variables are generated.  */
      gfc_typespec *ts = NULL;
      if (code->expr3)
	ts = &code->expr3->ts;
      else
	ts = &code->ext.alloc.ts;

      gcc_assert (ts);

      /* Finding the vtab also publishes the type's symbol.  Therefore this
	 statement is necessary.  */
      gfc_find_vtab (ts);
    }

  if (dimension == 0 && codimension == 0)
    goto success;

  /* Make sure the last reference node is an array specification.  */

  if (!ref2 || ref2->type != REF_ARRAY || ref2->u.ar.type == AR_FULL
      || (dimension && ref2->u.ar.dimen == 0))
    {
      /* F08:C633.  */
      if (code->expr3)
	{
	  if (!gfc_notify_std (GFC_STD_F2008, "Array specification required "
			       "in ALLOCATE statement at %L", &e->where))
	    goto failure;
	  if (code->expr3->rank != 0)
	    *array_alloc_wo_spec = true;
	  else
	    {
	      gfc_error ("Array specification or array-valued SOURCE= "
			 "expression required in ALLOCATE statement at %L",
			 &e->where);
	      goto failure;
	    }
	}
      else
	{
	  gfc_error ("Array specification required in ALLOCATE statement "
		     "at %L", &e->where);
	  goto failure;
	}
    }

  /* Make sure that the array section reference makes sense in the
     context of an ALLOCATE specification.  */

  ar = &ref2->u.ar;

  if (codimension)
    for (i = ar->dimen; i < ar->dimen + ar->codimen; i++)
      {
	switch (ar->dimen_type[i])
	  {
	  case DIMEN_THIS_IMAGE:
	    gfc_error ("Coarray specification required in ALLOCATE statement "
		       "at %L", &e->where);
	    goto failure;

	  case  DIMEN_RANGE:
	    if (ar->start[i] == 0 || ar->end[i] == 0)
	      {
		/* If ar->stride[i] is NULL, we issued a previous error.  */
		if (ar->stride[i] == NULL)
		  gfc_error ("Bad array specification in ALLOCATE statement "
			     "at %L", &e->where);
		goto failure;
	      }
	    else if (gfc_dep_compare_expr (ar->start[i], ar->end[i]) == 1)
	      {
		gfc_error ("Upper cobound is less than lower cobound at %L",
			   &ar->start[i]->where);
		goto failure;
	      }
	    break;

	  case DIMEN_ELEMENT:
	    if (ar->start[i]->expr_type == EXPR_CONSTANT)
	      {
		gcc_assert (ar->start[i]->ts.type == BT_INTEGER);
		if (mpz_cmp_si (ar->start[i]->value.integer, 1) < 0)
		  {
		    gfc_error ("Upper cobound is less than lower cobound "
			       "of 1 at %L", &ar->start[i]->where);
		    goto failure;
		  }
	      }
	    break;

	  case DIMEN_STAR:
	    break;

	  default:
	    gfc_error ("Bad array specification in ALLOCATE statement at %L",
		       &e->where);
	    goto failure;

	  }
      }
  for (i = 0; i < ar->dimen; i++)
    {
      if (ar->type == AR_ELEMENT || ar->type == AR_FULL)
	goto check_symbols;

      switch (ar->dimen_type[i])
	{
	case DIMEN_ELEMENT:
	  break;

	case DIMEN_RANGE:
	  if (ar->start[i] != NULL
	      && ar->end[i] != NULL
	      && ar->stride[i] == NULL)
	    break;

	  /* Fall through.  */

	case DIMEN_UNKNOWN:
	case DIMEN_VECTOR:
	case DIMEN_STAR:
	case DIMEN_THIS_IMAGE:
	  gfc_error ("Bad array specification in ALLOCATE statement at %L",
		     &e->where);
	  goto failure;
	}

check_symbols:
      for (a = code->ext.alloc.list; a; a = a->next)
	{
	  sym = a->expr->symtree->n.sym;

	  /* TODO - check derived type components.  */
	  if (gfc_bt_struct (sym->ts.type) || sym->ts.type == BT_CLASS)
	    continue;

	  if ((ar->start[i] != NULL
	       && gfc_find_sym_in_expr (sym, ar->start[i]))
	      || (ar->end[i] != NULL
		  && gfc_find_sym_in_expr (sym, ar->end[i])))
	    {
	      gfc_error ("%qs must not appear in the array specification at "
			 "%L in the same ALLOCATE statement where it is "
			 "itself allocated", sym->name, &ar->where);
	      goto failure;
	    }
	}
    }

  for (i = ar->dimen; i < ar->codimen + ar->dimen; i++)
    {
      if (ar->dimen_type[i] == DIMEN_ELEMENT
	  || ar->dimen_type[i] == DIMEN_RANGE)
	{
	  if (i == (ar->dimen + ar->codimen - 1))
	    {
	      gfc_error ("Expected '*' in coindex specification in ALLOCATE "
			 "statement at %L", &e->where);
	      goto failure;
	    }
	  continue;
	}

      if (ar->dimen_type[i] == DIMEN_STAR && i == (ar->dimen + ar->codimen - 1)
	  && ar->stride[i] == NULL)
	break;

      gfc_error ("Bad coarray specification in ALLOCATE statement at %L",
		 &e->where);
      goto failure;
    }

success:
  return true;

failure:
  return false;
}


static void
resolve_allocate_deallocate (gfc_code *code, const char *fcn)
{
  gfc_expr *stat, *errmsg, *pe, *qe;
  gfc_alloc *a, *p, *q;

  stat = code->expr1;
  errmsg = code->expr2;

  /* Check the stat variable.  */
  if (stat)
    {
      if (!gfc_check_vardef_context (stat, false, false, false,
				     _("STAT variable")))
	  goto done_stat;

      if (stat->ts.type != BT_INTEGER
	  || stat->rank > 0)
	gfc_error ("Stat-variable at %L must be a scalar INTEGER "
		   "variable", &stat->where);

      if (stat->expr_type == EXPR_CONSTANT || stat->symtree == NULL)
	goto done_stat;

      /* F2018:9.7.4: The stat-variable shall not be allocated or deallocated
       * within the ALLOCATE or DEALLOCATE statement in which it appears ...
       */
      for (p = code->ext.alloc.list; p; p = p->next)
	if (p->expr->symtree->n.sym->name == stat->symtree->n.sym->name)
	  {
	    gfc_ref *ref1, *ref2;
	    bool found = true;

	    for (ref1 = p->expr->ref, ref2 = stat->ref; ref1 && ref2;
		 ref1 = ref1->next, ref2 = ref2->next)
	      {
		if (ref1->type != REF_COMPONENT || ref2->type != REF_COMPONENT)
		  continue;
		if (ref1->u.c.component->name != ref2->u.c.component->name)
		  {
		    found = false;
		    break;
		  }
	      }

	    if (found)
	      {
		gfc_error ("Stat-variable at %L shall not be %sd within "
			   "the same %s statement", &stat->where, fcn, fcn);
		break;
	      }
	  }
    }

done_stat:

  /* Check the errmsg variable.  */
  if (errmsg)
    {
      if (!stat)
	gfc_warning (0, "ERRMSG at %L is useless without a STAT tag",
		     &errmsg->where);

      if (!gfc_check_vardef_context (errmsg, false, false, false,
				     _("ERRMSG variable")))
	  goto done_errmsg;

      /* F18:R928  alloc-opt             is ERRMSG = errmsg-variable
	 F18:R930  errmsg-variable       is scalar-default-char-variable
	 F18:R906  default-char-variable is variable
	 F18:C906  default-char-variable shall be default character.  */
      if (errmsg->ts.type != BT_CHARACTER
	  || errmsg->rank > 0
	  || errmsg->ts.kind != gfc_default_character_kind)
	gfc_error ("ERRMSG variable at %L shall be a scalar default CHARACTER "
		   "variable", &errmsg->where);

      if (errmsg->expr_type == EXPR_CONSTANT || errmsg->symtree == NULL)
	goto done_errmsg;

      /* F2018:9.7.5: The errmsg-variable shall not be allocated or deallocated
       * within the ALLOCATE or DEALLOCATE statement in which it appears ...
       */
      for (p = code->ext.alloc.list; p; p = p->next)
	if (p->expr->symtree->n.sym->name == errmsg->symtree->n.sym->name)
	  {
	    gfc_ref *ref1, *ref2;
	    bool found = true;

	    for (ref1 = p->expr->ref, ref2 = errmsg->ref; ref1 && ref2;
		 ref1 = ref1->next, ref2 = ref2->next)
	      {
		if (ref1->type != REF_COMPONENT || ref2->type != REF_COMPONENT)
		  continue;
		if (ref1->u.c.component->name != ref2->u.c.component->name)
		  {
		    found = false;
		    break;
		  }
	      }

	    if (found)
	      {
		gfc_error ("Errmsg-variable at %L shall not be %sd within "
			   "the same %s statement", &errmsg->where, fcn, fcn);
		break;
	      }
	  }
    }

done_errmsg:

  /* Check that an allocate-object appears only once in the statement.  */

  for (p = code->ext.alloc.list; p; p = p->next)
    {
      pe = p->expr;
      for (q = p->next; q; q = q->next)
	{
	  qe = q->expr;
	  if (pe->symtree->n.sym->name == qe->symtree->n.sym->name)
	    {
	      /* This is a potential collision.  */
	      gfc_ref *pr = pe->ref;
	      gfc_ref *qr = qe->ref;

	      /* Follow the references  until
		 a) They start to differ, in which case there is no error;
		 you can deallocate a%b and a%c in a single statement
		 b) Both of them stop, which is an error
		 c) One of them stops, which is also an error.  */
	      while (1)
		{
		  if (pr == NULL && qr == NULL)
		    {
		      gfc_error ("Allocate-object at %L also appears at %L",
				 &pe->where, &qe->where);
		      break;
		    }
		  else if (pr != NULL && qr == NULL)
		    {
		      gfc_error ("Allocate-object at %L is subobject of"
				 " object at %L", &pe->where, &qe->where);
		      break;
		    }
		  else if (pr == NULL && qr != NULL)
		    {
		      gfc_error ("Allocate-object at %L is subobject of"
				 " object at %L", &qe->where, &pe->where);
		      break;
		    }
		  /* Here, pr != NULL && qr != NULL  */
		  gcc_assert(pr->type == qr->type);
		  if (pr->type == REF_ARRAY)
		    {
		      /* Handle cases like allocate(v(3)%x(3), v(2)%x(3)),
			 which are legal.  */
		      gcc_assert (qr->type == REF_ARRAY);

		      if (pr->next && qr->next)
			{
			  int i;
			  gfc_array_ref *par = &(pr->u.ar);
			  gfc_array_ref *qar = &(qr->u.ar);

			  for (i=0; i<par->dimen; i++)
			    {
			      if ((par->start[i] != NULL
				   || qar->start[i] != NULL)
				  && gfc_dep_compare_expr (par->start[i],
							   qar->start[i]) != 0)
				goto break_label;
			    }
			}
		    }
		  else
		    {
		      if (pr->u.c.component->name != qr->u.c.component->name)
			break;
		    }

		  pr = pr->next;
		  qr = qr->next;
		}
	    break_label:
	      ;
	    }
	}
    }

  if (strcmp (fcn, "ALLOCATE") == 0)
    {
      bool arr_alloc_wo_spec = false;

      /* Resolving the expr3 in the loop over all objects to allocate would
	 execute loop invariant code for each loop item.  Therefore do it just
	 once here.  */
      if (code->expr3 && code->expr3->mold
	  && code->expr3->ts.type == BT_DERIVED)
	{
	  /* Default initialization via MOLD (non-polymorphic).  */
	  gfc_expr *rhs = gfc_default_initializer (&code->expr3->ts);
	  if (rhs != NULL)
	    {
	      gfc_resolve_expr (rhs);
	      gfc_free_expr (code->expr3);
	      code->expr3 = rhs;
	    }
	}
      for (a = code->ext.alloc.list; a; a = a->next)
	resolve_allocate_expr (a->expr, code, &arr_alloc_wo_spec);

      if (arr_alloc_wo_spec && code->expr3)
	{
	  /* Mark the allocate to have to take the array specification
	     from the expr3.  */
	  code->ext.alloc.arr_spec_from_expr3 = 1;
	}
    }
  else
    {
      for (a = code->ext.alloc.list; a; a = a->next)
	resolve_deallocate_expr (a->expr);
    }
}


/************ SELECT CASE resolution subroutines ************/

/* Callback function for our mergesort variant.  Determines interval
   overlaps for CASEs. Return <0 if op1 < op2, 0 for overlap, >0 for
   op1 > op2.  Assumes we're not dealing with the default case.
   We have op1 = (:L), (K:L) or (K:) and op2 = (:N), (M:N) or (M:).
   There are nine situations to check.  */

static int
compare_cases (const gfc_case *op1, const gfc_case *op2)
{
  int retval;

  if (op1->low == NULL) /* op1 = (:L)  */
    {
      /* op2 = (:N), so overlap.  */
      retval = 0;
      /* op2 = (M:) or (M:N),  L < M  */
      if (op2->low != NULL
	  && gfc_compare_expr (op1->high, op2->low, INTRINSIC_LT) < 0)
	retval = -1;
    }
  else if (op1->high == NULL) /* op1 = (K:)  */
    {
      /* op2 = (M:), so overlap.  */
      retval = 0;
      /* op2 = (:N) or (M:N), K > N  */
      if (op2->high != NULL
	  && gfc_compare_expr (op1->low, op2->high, INTRINSIC_GT) > 0)
	retval = 1;
    }
  else /* op1 = (K:L)  */
    {
      if (op2->low == NULL)       /* op2 = (:N), K > N  */
	retval = (gfc_compare_expr (op1->low, op2->high, INTRINSIC_GT) > 0)
		 ? 1 : 0;
      else if (op2->high == NULL) /* op2 = (M:), L < M  */
	retval = (gfc_compare_expr (op1->high, op2->low, INTRINSIC_LT) < 0)
		 ? -1 : 0;
      else			/* op2 = (M:N)  */
	{
	  retval =  0;
	  /* L < M  */
	  if (gfc_compare_expr (op1->high, op2->low, INTRINSIC_LT) < 0)
	    retval =  -1;
	  /* K > N  */
	  else if (gfc_compare_expr (op1->low, op2->high, INTRINSIC_GT) > 0)
	    retval =  1;
	}
    }

  return retval;
}


/* Merge-sort a double linked case list, detecting overlap in the
   process.  LIST is the head of the double linked case list before it
   is sorted.  Returns the head of the sorted list if we don't see any
   overlap, or NULL otherwise.  */

static gfc_case *
check_case_overlap (gfc_case *list)
{
  gfc_case *p, *q, *e, *tail;
  int insize, nmerges, psize, qsize, cmp, overlap_seen;

  /* If the passed list was empty, return immediately.  */
  if (!list)
    return NULL;

  overlap_seen = 0;
  insize = 1;

  /* Loop unconditionally.  The only exit from this loop is a return
     statement, when we've finished sorting the case list.  */
  for (;;)
    {
      p = list;
      list = NULL;
      tail = NULL;

      /* Count the number of merges we do in this pass.  */
      nmerges = 0;

      /* Loop while there exists a merge to be done.  */
      while (p)
	{
	  int i;

	  /* Count this merge.  */
	  nmerges++;

	  /* Cut the list in two pieces by stepping INSIZE places
	     forward in the list, starting from P.  */
	  psize = 0;
	  q = p;
	  for (i = 0; i < insize; i++)
	    {
	      psize++;
	      q = q->right;
	      if (!q)
		break;
	    }
	  qsize = insize;

	  /* Now we have two lists.  Merge them!  */
	  while (psize > 0 || (qsize > 0 && q != NULL))
	    {
	      /* See from which the next case to merge comes from.  */
	      if (psize == 0)
		{
		  /* P is empty so the next case must come from Q.  */
		  e = q;
		  q = q->right;
		  qsize--;
		}
	      else if (qsize == 0 || q == NULL)
		{
		  /* Q is empty.  */
		  e = p;
		  p = p->right;
		  psize--;
		}
	      else
		{
		  cmp = compare_cases (p, q);
		  if (cmp < 0)
		    {
		      /* The whole case range for P is less than the
			 one for Q.  */
		      e = p;
		      p = p->right;
		      psize--;
		    }
		  else if (cmp > 0)
		    {
		      /* The whole case range for Q is greater than
			 the case range for P.  */
		      e = q;
		      q = q->right;
		      qsize--;
		    }
		  else
		    {
		      /* The cases overlap, or they are the same
			 element in the list.  Either way, we must
			 issue an error and get the next case from P.  */
		      /* FIXME: Sort P and Q by line number.  */
		      gfc_error ("CASE label at %L overlaps with CASE "
				 "label at %L", &p->where, &q->where);
		      overlap_seen = 1;
		      e = p;
		      p = p->right;
		      psize--;
		    }
		}

		/* Add the next element to the merged list.  */
	      if (tail)
		tail->right = e;
	      else
		list = e;
	      e->left = tail;
	      tail = e;
	    }

	  /* P has now stepped INSIZE places along, and so has Q.  So
	     they're the same.  */
	  p = q;
	}
      tail->right = NULL;

      /* If we have done only one merge or none at all, we've
	 finished sorting the cases.  */
      if (nmerges <= 1)
	{
	  if (!overlap_seen)
	    return list;
	  else
	    return NULL;
	}

      /* Otherwise repeat, merging lists twice the size.  */
      insize *= 2;
    }
}


/* Check to see if an expression is suitable for use in a CASE statement.
   Makes sure that all case expressions are scalar constants of the same
   type.  Return false if anything is wrong.  */

static bool
validate_case_label_expr (gfc_expr *e, gfc_expr *case_expr)
{
  if (e == NULL) return true;

  if (e->ts.type != case_expr->ts.type)
    {
      gfc_error ("Expression in CASE statement at %L must be of type %s",
		 &e->where, gfc_basic_typename (case_expr->ts.type));
      return false;
    }

  /* C805 (R808) For a given case-construct, each case-value shall be of
     the same type as case-expr.  For character type, length differences
     are allowed, but the kind type parameters shall be the same.  */

  if (case_expr->ts.type == BT_CHARACTER && e->ts.kind != case_expr->ts.kind)
    {
      gfc_error ("Expression in CASE statement at %L must be of kind %d",
		 &e->where, case_expr->ts.kind);
      return false;
    }

  /* Convert the case value kind to that of case expression kind,
     if needed */

  if (e->ts.kind != case_expr->ts.kind)
    gfc_convert_type_warn (e, &case_expr->ts, 2, 0);

  if (e->rank != 0)
    {
      gfc_error ("Expression in CASE statement at %L must be scalar",
		 &e->where);
      return false;
    }

  return true;
}


/* Given a completely parsed select statement, we:

     - Validate all expressions and code within the SELECT.
     - Make sure that the selection expression is not of the wrong type.
     - Make sure that no case ranges overlap.
     - Eliminate unreachable cases and unreachable code resulting from
       removing case labels.

   The standard does allow unreachable cases, e.g. CASE (5:3).  But
   they are a hassle for code generation, and to prevent that, we just
   cut them out here.  This is not necessary for overlapping cases
   because they are illegal and we never even try to generate code.

   We have the additional caveat that a SELECT construct could have
   been a computed GOTO in the source code. Fortunately we can fairly
   easily work around that here: The case_expr for a "real" SELECT CASE
   is in code->expr1, but for a computed GOTO it is in code->expr2. All
   we have to do is make sure that the case_expr is a scalar integer
   expression.  */

static void
resolve_select (gfc_code *code, bool select_type)
{
  gfc_code *body;
  gfc_expr *case_expr;
  gfc_case *cp, *default_case, *tail, *head;
  int seen_unreachable;
  int seen_logical;
  int ncases;
  bt type;
  bool t;

  if (code->expr1 == NULL)
    {
      /* This was actually a computed GOTO statement.  */
      case_expr = code->expr2;
      if (case_expr->ts.type != BT_INTEGER|| case_expr->rank != 0)
	gfc_error ("Selection expression in computed GOTO statement "
		   "at %L must be a scalar integer expression",
		   &case_expr->where);

      /* Further checking is not necessary because this SELECT was built
	 by the compiler, so it should always be OK.  Just move the
	 case_expr from expr2 to expr so that we can handle computed
	 GOTOs as normal SELECTs from here on.  */
      code->expr1 = code->expr2;
      code->expr2 = NULL;
      return;
    }

  case_expr = code->expr1;
  type = case_expr->ts.type;

  /* F08:C830.  */
  if (type != BT_LOGICAL && type != BT_INTEGER && type != BT_CHARACTER)
    {
      gfc_error ("Argument of SELECT statement at %L cannot be %s",
		 &case_expr->where, gfc_typename (case_expr));

      /* Punt. Going on here just produce more garbage error messages.  */
      return;
    }

  /* F08:R842.  */
  if (!select_type && case_expr->rank != 0)
    {
      gfc_error ("Argument of SELECT statement at %L must be a scalar "
		 "expression", &case_expr->where);

      /* Punt.  */
      return;
    }

  /* Raise a warning if an INTEGER case value exceeds the range of
     the case-expr. Later, all expressions will be promoted to the
     largest kind of all case-labels.  */

  if (type == BT_INTEGER)
    for (body = code->block; body; body = body->block)
      for (cp = body->ext.block.case_list; cp; cp = cp->next)
	{
	  if (cp->low
	      && gfc_check_integer_range (cp->low->value.integer,
					  case_expr->ts.kind) != ARITH_OK)
	    gfc_warning (0, "Expression in CASE statement at %L is "
			 "not in the range of %s", &cp->low->where,
			 gfc_typename (case_expr));

	  if (cp->high
	      && cp->low != cp->high
	      && gfc_check_integer_range (cp->high->value.integer,
					  case_expr->ts.kind) != ARITH_OK)
	    gfc_warning (0, "Expression in CASE statement at %L is "
			 "not in the range of %s", &cp->high->where,
			 gfc_typename (case_expr));
	}

  /* PR 19168 has a long discussion concerning a mismatch of the kinds
     of the SELECT CASE expression and its CASE values.  Walk the lists
     of case values, and if we find a mismatch, promote case_expr to
     the appropriate kind.  */

  if (type == BT_LOGICAL || type == BT_INTEGER)
    {
      for (body = code->block; body; body = body->block)
	{
	  /* Walk the case label list.  */
	  for (cp = body->ext.block.case_list; cp; cp = cp->next)
	    {
	      /* Intercept the DEFAULT case.  It does not have a kind.  */
	      if (cp->low == NULL && cp->high == NULL)
		continue;

	      /* Unreachable case ranges are discarded, so ignore.  */
	      if (cp->low != NULL && cp->high != NULL
		  && cp->low != cp->high
		  && gfc_compare_expr (cp->low, cp->high, INTRINSIC_GT) > 0)
		continue;

	      if (cp->low != NULL
		  && case_expr->ts.kind != gfc_kind_max(case_expr, cp->low))
		gfc_convert_type_warn (case_expr, &cp->low->ts, 2, 0);

	      if (cp->high != NULL
		  && case_expr->ts.kind != gfc_kind_max(case_expr, cp->high))
		gfc_convert_type_warn (case_expr, &cp->high->ts, 2, 0);
	    }
	 }
    }

  /* Assume there is no DEFAULT case.  */
  default_case = NULL;
  head = tail = NULL;
  ncases = 0;
  seen_logical = 0;

  for (body = code->block; body; body = body->block)
    {
      /* Assume the CASE list is OK, and all CASE labels can be matched.  */
      t = true;
      seen_unreachable = 0;

      /* Walk the case label list, making sure that all case labels
	 are legal.  */
      for (cp = body->ext.block.case_list; cp; cp = cp->next)
	{
	  /* Count the number of cases in the whole construct.  */
	  ncases++;

	  /* Intercept the DEFAULT case.  */
	  if (cp->low == NULL && cp->high == NULL)
	    {
	      if (default_case != NULL)
		{
		  gfc_error ("The DEFAULT CASE at %L cannot be followed "
			     "by a second DEFAULT CASE at %L",
			     &default_case->where, &cp->where);
		  t = false;
		  break;
		}
	      else
		{
		  default_case = cp;
		  continue;
		}
	    }

	  /* Deal with single value cases and case ranges.  Errors are
	     issued from the validation function.  */
	  if (!validate_case_label_expr (cp->low, case_expr)
	      || !validate_case_label_expr (cp->high, case_expr))
	    {
	      t = false;
	      break;
	    }

	  if (type == BT_LOGICAL
	      && ((cp->low == NULL || cp->high == NULL)
		  || cp->low != cp->high))
	    {
	      gfc_error ("Logical range in CASE statement at %L is not "
			 "allowed", &cp->low->where);
	      t = false;
	      break;
	    }

	  if (type == BT_LOGICAL && cp->low->expr_type == EXPR_CONSTANT)
	    {
	      int value;
	      value = cp->low->value.logical == 0 ? 2 : 1;
	      if (value & seen_logical)
		{
		  gfc_error ("Constant logical value in CASE statement "
			     "is repeated at %L",
			     &cp->low->where);
		  t = false;
		  break;
		}
	      seen_logical |= value;
	    }

	  if (cp->low != NULL && cp->high != NULL
	      && cp->low != cp->high
	      && gfc_compare_expr (cp->low, cp->high, INTRINSIC_GT) > 0)
	    {
	      if (warn_surprising)
		gfc_warning (OPT_Wsurprising,
			     "Range specification at %L can never be matched",
			     &cp->where);

	      cp->unreachable = 1;
	      seen_unreachable = 1;
	    }
	  else
	    {
	      /* If the case range can be matched, it can also overlap with
		 other cases.  To make sure it does not, we put it in a
		 double linked list here.  We sort that with a merge sort
		 later on to detect any overlapping cases.  */
	      if (!head)
		{
		  head = tail = cp;
		  head->right = head->left = NULL;
		}
	      else
		{
		  tail->right = cp;
		  tail->right->left = tail;
		  tail = tail->right;
		  tail->right = NULL;
		}
	    }
	}

      /* It there was a failure in the previous case label, give up
	 for this case label list.  Continue with the next block.  */
      if (!t)
	continue;

      /* See if any case labels that are unreachable have been seen.
	 If so, we eliminate them.  This is a bit of a kludge because
	 the case lists for a single case statement (label) is a
	 single forward linked lists.  */
      if (seen_unreachable)
      {
	/* Advance until the first case in the list is reachable.  */
	while (body->ext.block.case_list != NULL
	       && body->ext.block.case_list->unreachable)
	  {
	    gfc_case *n = body->ext.block.case_list;
	    body->ext.block.case_list = body->ext.block.case_list->next;
	    n->next = NULL;
	    gfc_free_case_list (n);
	  }

	/* Strip all other unreachable cases.  */
	if (body->ext.block.case_list)
	  {
	    for (cp = body->ext.block.case_list; cp && cp->next; cp = cp->next)
	      {
		if (cp->next->unreachable)
		  {
		    gfc_case *n = cp->next;
		    cp->next = cp->next->next;
		    n->next = NULL;
		    gfc_free_case_list (n);
		  }
	      }
	  }
      }
    }

  /* See if there were overlapping cases.  If the check returns NULL,
     there was overlap.  In that case we don't do anything.  If head
     is non-NULL, we prepend the DEFAULT case.  The sorted list can
     then used during code generation for SELECT CASE constructs with
     a case expression of a CHARACTER type.  */
  if (head)
    {
      head = check_case_overlap (head);

      /* Prepend the default_case if it is there.  */
      if (head != NULL && default_case)
	{
	  default_case->left = NULL;
	  default_case->right = head;
	  head->left = default_case;
	}
    }

  /* Eliminate dead blocks that may be the result if we've seen
     unreachable case labels for a block.  */
  for (body = code; body && body->block; body = body->block)
    {
      if (body->block->ext.block.case_list == NULL)
	{
	  /* Cut the unreachable block from the code chain.  */
	  gfc_code *c = body->block;
	  body->block = c->block;

	  /* Kill the dead block, but not the blocks below it.  */
	  c->block = NULL;
	  gfc_free_statements (c);
	}
    }

  /* More than two cases is legal but insane for logical selects.
     Issue a warning for it.  */
  if (warn_surprising && type == BT_LOGICAL && ncases > 2)
    gfc_warning (OPT_Wsurprising,
		 "Logical SELECT CASE block at %L has more that two cases",
		 &code->loc);
}


/* Check if a derived type is extensible.  */

bool
gfc_type_is_extensible (gfc_symbol *sym)
{
  return !(sym->attr.is_bind_c || sym->attr.sequence
	   || (sym->attr.is_class
	       && sym->components->ts.u.derived->attr.unlimited_polymorphic));
}


static void
resolve_types (gfc_namespace *ns);

/* Resolve an associate-name:  Resolve target and ensure the type-spec is
   correct as well as possibly the array-spec.  */

static void
resolve_assoc_var (gfc_symbol* sym, bool resolve_target)
{
  gfc_expr* target;

  gcc_assert (sym->assoc);
  gcc_assert (sym->attr.flavor == FL_VARIABLE);

  /* If this is for SELECT TYPE, the target may not yet be set.  In that
     case, return.  Resolution will be called later manually again when
     this is done.  */
  target = sym->assoc->target;
  if (!target)
    return;
  gcc_assert (!sym->assoc->dangling);

  if (resolve_target && !gfc_resolve_expr (target))
    return;

  /* For variable targets, we get some attributes from the target.  */
  if (target->expr_type == EXPR_VARIABLE)
    {
      gfc_symbol *tsym, *dsym;

      gcc_assert (target->symtree);
      tsym = target->symtree->n.sym;

      if (gfc_expr_attr (target).proc_pointer)
	{
	  gfc_error ("Associating entity %qs at %L is a procedure pointer",
		     tsym->name, &target->where);
	  return;
	}

      if (tsym->attr.flavor == FL_PROCEDURE && tsym->generic
	  && (dsym = gfc_find_dt_in_generic (tsym)) != NULL
	  && dsym->attr.flavor == FL_DERIVED)
	{
	  gfc_error ("Derived type %qs cannot be used as a variable at %L",
		     tsym->name, &target->where);
	  return;
	}

      if (tsym->attr.flavor == FL_PROCEDURE)
	{
	  bool is_error = true;
	  if (tsym->attr.function && tsym->result == tsym)
	    for (gfc_namespace *ns = sym->ns; ns; ns = ns->parent)
	      if (tsym == ns->proc_name)
		{
		  is_error = false;
		  break;
		}
	  if (is_error)
	    {
	      gfc_error ("Associating entity %qs at %L is a procedure name",
			 tsym->name, &target->where);
	      return;
	    }
	}

      sym->attr.asynchronous = tsym->attr.asynchronous;
      sym->attr.volatile_ = tsym->attr.volatile_;

      sym->attr.target = tsym->attr.target
			 || gfc_expr_attr (target).pointer;
      if (is_subref_array (target))
	sym->attr.subref_array_pointer = 1;
    }
  else if (target->ts.type == BT_PROCEDURE)
    {
      gfc_error ("Associating selector-expression at %L yields a procedure",
		 &target->where);
      return;
    }

  if (target->expr_type == EXPR_NULL)
    {
      gfc_error ("Selector at %L cannot be NULL()", &target->where);
      return;
    }
  else if (target->ts.type == BT_UNKNOWN)
    {
      gfc_error ("Selector at %L has no type", &target->where);
      return;
    }

  /* Get type if this was not already set.  Note that it can be
     some other type than the target in case this is a SELECT TYPE
     selector!  So we must not update when the type is already there.  */
  if (sym->ts.type == BT_UNKNOWN)
    sym->ts = target->ts;

  gcc_assert (sym->ts.type != BT_UNKNOWN);

  /* See if this is a valid association-to-variable.  */
  sym->assoc->variable = (target->expr_type == EXPR_VARIABLE
			  && !gfc_has_vector_subscript (target));

  /* Finally resolve if this is an array or not.  */
  if (sym->attr.dimension && target->rank == 0)
    {
      /* primary.c makes the assumption that a reference to an associate
	 name followed by a left parenthesis is an array reference.  */
      if (sym->ts.type != BT_CHARACTER)
	gfc_error ("Associate-name %qs at %L is used as array",
		   sym->name, &sym->declared_at);
      sym->attr.dimension = 0;
      return;
    }


  /* We cannot deal with class selectors that need temporaries.  */
  if (target->ts.type == BT_CLASS
	&& gfc_ref_needs_temporary_p (target->ref))
    {
      gfc_error ("CLASS selector at %L needs a temporary which is not "
		 "yet implemented", &target->where);
      return;
    }

  if (target->ts.type == BT_CLASS)
    gfc_fix_class_refs (target);

  if (target->rank != 0 && !sym->attr.select_rank_temporary)
    {
      gfc_array_spec *as;
      /* The rank may be incorrectly guessed at parsing, therefore make sure
	 it is corrected now.  */
      if (sym->ts.type != BT_CLASS && (!sym->as || sym->assoc->rankguessed))
	{
	  if (!sym->as)
	    sym->as = gfc_get_array_spec ();
	  as = sym->as;
	  as->rank = target->rank;
	  as->type = AS_DEFERRED;
	  as->corank = gfc_get_corank (target);
	  sym->attr.dimension = 1;
	  if (as->corank != 0)
	    sym->attr.codimension = 1;
	}
      else if (sym->ts.type == BT_CLASS
	       && CLASS_DATA (sym)
	       && (!CLASS_DATA (sym)->as || sym->assoc->rankguessed))
	{
	  if (!CLASS_DATA (sym)->as)
	    CLASS_DATA (sym)->as = gfc_get_array_spec ();
	  as = CLASS_DATA (sym)->as;
	  as->rank = target->rank;
	  as->type = AS_DEFERRED;
	  as->corank = gfc_get_corank (target);
	  CLASS_DATA (sym)->attr.dimension = 1;
	  if (as->corank != 0)
	    CLASS_DATA (sym)->attr.codimension = 1;
	}
    }
  else if (!sym->attr.select_rank_temporary)
    {
      /* target's rank is 0, but the type of the sym is still array valued,
	 which has to be corrected.  */
      if (sym->ts.type == BT_CLASS && sym->ts.u.derived
	  && CLASS_DATA (sym) && CLASS_DATA (sym)->as)
	{
	  gfc_array_spec *as;
	  symbol_attribute attr;
	  /* The associated variable's type is still the array type
	     correct this now.  */
	  gfc_typespec *ts = &target->ts;
	  gfc_ref *ref;
	  gfc_component *c;
	  for (ref = target->ref; ref != NULL; ref = ref->next)
	    {
	      switch (ref->type)
		{
		case REF_COMPONENT:
		  ts = &ref->u.c.component->ts;
		  break;
		case REF_ARRAY:
		  if (ts->type == BT_CLASS)
		    ts = &ts->u.derived->components->ts;
		  break;
		default:
		  break;
		}
	    }
	  /* Create a scalar instance of the current class type.  Because the
	     rank of a class array goes into its name, the type has to be
	     rebuild.  The alternative of (re-)setting just the attributes
	     and as in the current type, destroys the type also in other
	     places.  */
	  as = NULL;
	  sym->ts = *ts;
	  sym->ts.type = BT_CLASS;
	  attr = CLASS_DATA (sym) ? CLASS_DATA (sym)->attr : sym->attr;
	  attr.class_ok = 0;
	  attr.associate_var = 1;
	  attr.dimension = attr.codimension = 0;
	  attr.class_pointer = 1;
	  if (!gfc_build_class_symbol (&sym->ts, &attr, &as))
	    gcc_unreachable ();
	  /* Make sure the _vptr is set.  */
	  c = gfc_find_component (sym->ts.u.derived, "_vptr", true, true, NULL);
	  if (c->ts.u.derived == NULL)
	    c->ts.u.derived = gfc_find_derived_vtab (sym->ts.u.derived);
	  CLASS_DATA (sym)->attr.pointer = 1;
	  CLASS_DATA (sym)->attr.class_pointer = 1;
	  gfc_set_sym_referenced (sym->ts.u.derived);
	  gfc_commit_symbol (sym->ts.u.derived);
	  /* _vptr now has the _vtab in it, change it to the _vtype.  */
	  if (c->ts.u.derived->attr.vtab)
	    c->ts.u.derived = c->ts.u.derived->ts.u.derived;
	  c->ts.u.derived->ns->types_resolved = 0;
	  resolve_types (c->ts.u.derived->ns);
	}
    }

  /* Mark this as an associate variable.  */
  sym->attr.associate_var = 1;

  /* Fix up the type-spec for CHARACTER types.  */
  if (sym->ts.type == BT_CHARACTER && !sym->attr.select_type_temporary)
    {
      if (!sym->ts.u.cl)
	sym->ts.u.cl = target->ts.u.cl;

      if (sym->ts.deferred && target->expr_type == EXPR_VARIABLE
	  && target->symtree->n.sym->attr.dummy
	  && sym->ts.u.cl == target->ts.u.cl)
	{
	  sym->ts.u.cl = gfc_new_charlen (sym->ns, NULL);
	  sym->ts.deferred = 1;
	}

      if (!sym->ts.u.cl->length
	  && !sym->ts.deferred
	  && target->expr_type == EXPR_CONSTANT)
	{
	  sym->ts.u.cl->length =
		gfc_get_int_expr (gfc_charlen_int_kind, NULL,
				  target->value.character.length);
	}
      else if ((!sym->ts.u.cl->length
		|| sym->ts.u.cl->length->expr_type != EXPR_CONSTANT)
		&& target->expr_type != EXPR_VARIABLE)
	{
	  sym->ts.u.cl = gfc_new_charlen (sym->ns, NULL);
	  sym->ts.deferred = 1;

	  /* This is reset in trans-stmt.c after the assignment
	     of the target expression to the associate name.  */
	  sym->attr.allocatable = 1;
	}
    }

  /* If the target is a good class object, so is the associate variable.  */
  if (sym->ts.type == BT_CLASS && gfc_expr_attr (target).class_ok)
    sym->attr.class_ok = 1;
}


/* Ensure that SELECT TYPE expressions have the correct rank and a full
   array reference, where necessary.  The symbols are artificial and so
   the dimension attribute and arrayspec can also be set.  In addition,
   sometimes the expr1 arrives as BT_DERIVED, when the symbol is BT_CLASS.
   This is corrected here as well.*/

static void
fixup_array_ref (gfc_expr **expr1, gfc_expr *expr2,
		 int rank, gfc_ref *ref)
{
  gfc_ref *nref = (*expr1)->ref;
  gfc_symbol *sym1 = (*expr1)->symtree->n.sym;
  gfc_symbol *sym2 = expr2 ? expr2->symtree->n.sym : NULL;
  (*expr1)->rank = rank;
  if (sym1->ts.type == BT_CLASS)
    {
      if ((*expr1)->ts.type != BT_CLASS)
	(*expr1)->ts = sym1->ts;

      CLASS_DATA (sym1)->attr.dimension = 1;
      if (CLASS_DATA (sym1)->as == NULL && sym2)
	CLASS_DATA (sym1)->as
		= gfc_copy_array_spec (CLASS_DATA (sym2)->as);
    }
  else
    {
      sym1->attr.dimension = 1;
      if (sym1->as == NULL && sym2)
	sym1->as = gfc_copy_array_spec (sym2->as);
    }

  for (; nref; nref = nref->next)
    if (nref->next == NULL)
      break;

  if (ref && nref && nref->type != REF_ARRAY)
    nref->next = gfc_copy_ref (ref);
  else if (ref && !nref)
    (*expr1)->ref = gfc_copy_ref (ref);
}


static gfc_expr *
build_loc_call (gfc_expr *sym_expr)
{
  gfc_expr *loc_call;
  loc_call = gfc_get_expr ();
  loc_call->expr_type = EXPR_FUNCTION;
  gfc_get_sym_tree ("_loc", gfc_current_ns, &loc_call->symtree, false);
  loc_call->symtree->n.sym->attr.flavor = FL_PROCEDURE;
  loc_call->symtree->n.sym->attr.intrinsic = 1;
  loc_call->symtree->n.sym->result = loc_call->symtree->n.sym;
  gfc_commit_symbol (loc_call->symtree->n.sym);
  loc_call->ts.type = BT_INTEGER;
  loc_call->ts.kind = gfc_index_integer_kind;
  loc_call->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_LOC);
  loc_call->value.function.actual = gfc_get_actual_arglist ();
  loc_call->value.function.actual->expr = sym_expr;
  loc_call->where = sym_expr->where;
  return loc_call;
}

/* Resolve a SELECT TYPE statement.  */

static void
resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
{
  gfc_symbol *selector_type;
  gfc_code *body, *new_st, *if_st, *tail;
  gfc_code *class_is = NULL, *default_case = NULL;
  gfc_case *c;
  gfc_symtree *st;
  char name[GFC_MAX_SYMBOL_LEN + 12 + 1];
  gfc_namespace *ns;
  int error = 0;
  int rank = 0;
  gfc_ref* ref = NULL;
  gfc_expr *selector_expr = NULL;

  ns = code->ext.block.ns;
  gfc_resolve (ns);

  /* Check for F03:C813.  */
  if (code->expr1->ts.type != BT_CLASS
      && !(code->expr2 && code->expr2->ts.type == BT_CLASS))
    {
      gfc_error ("Selector shall be polymorphic in SELECT TYPE statement "
		 "at %L", &code->loc);
      return;
    }

  if (!code->expr1->symtree->n.sym->attr.class_ok)
    return;

  if (code->expr2)
    {
      gfc_ref *ref2 = NULL;
      for (ref = code->expr2->ref; ref != NULL; ref = ref->next)
	 if (ref->type == REF_COMPONENT
	     && ref->u.c.component->ts.type == BT_CLASS)
	   ref2 = ref;

      if (ref2)
	{
	  if (code->expr1->symtree->n.sym->attr.untyped)
	    code->expr1->symtree->n.sym->ts = ref2->u.c.component->ts;
	  selector_type = CLASS_DATA (ref2->u.c.component)->ts.u.derived;
	}
      else
	{
	  if (code->expr1->symtree->n.sym->attr.untyped)
	    code->expr1->symtree->n.sym->ts = code->expr2->ts;
	  selector_type = CLASS_DATA (code->expr2)
	    ? CLASS_DATA (code->expr2)->ts.u.derived : code->expr2->ts.u.derived;
	}

      if (code->expr2->rank
	  && code->expr1->ts.type == BT_CLASS
	  && CLASS_DATA (code->expr1)->as)
	CLASS_DATA (code->expr1)->as->rank = code->expr2->rank;

      /* F2008: C803 The selector expression must not be coindexed.  */
      if (gfc_is_coindexed (code->expr2))
	{
	  gfc_error ("Selector at %L must not be coindexed",
		     &code->expr2->where);
	  return;
	}

    }
  else
    {
      selector_type = CLASS_DATA (code->expr1)->ts.u.derived;

      if (gfc_is_coindexed (code->expr1))
	{
	  gfc_error ("Selector at %L must not be coindexed",
		     &code->expr1->where);
	  return;
	}
    }

  /* Loop over TYPE IS / CLASS IS cases.  */
  for (body = code->block; body; body = body->block)
    {
      c = body->ext.block.case_list;

      if (!error)
	{
	  /* Check for repeated cases.  */
	  for (tail = code->block; tail; tail = tail->block)
	    {
	      gfc_case *d = tail->ext.block.case_list;
	      if (tail == body)
		break;

	      if (c->ts.type == d->ts.type
		  && ((c->ts.type == BT_DERIVED
		       && c->ts.u.derived && d->ts.u.derived
		       && !strcmp (c->ts.u.derived->name,
				   d->ts.u.derived->name))
		      || c->ts.type == BT_UNKNOWN
		      || (!(c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
			  && c->ts.kind == d->ts.kind)))
		{
		  gfc_error ("TYPE IS at %L overlaps with TYPE IS at %L",
			     &c->where, &d->where);
		  return;
		}
	    }
	}

      /* Check F03:C815.  */
      if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
	  && !selector_type->attr.unlimited_polymorphic
	  && !gfc_type_is_extensible (c->ts.u.derived))
	{
	  gfc_error ("Derived type %qs at %L must be extensible",
		     c->ts.u.derived->name, &c->where);
	  error++;
	  continue;
	}

      /* Check F03:C816.  */
      if (c->ts.type != BT_UNKNOWN && !selector_type->attr.unlimited_polymorphic
	  && ((c->ts.type != BT_DERIVED && c->ts.type != BT_CLASS)
	      || !gfc_type_is_extension_of (selector_type, c->ts.u.derived)))
	{
	  if (c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
	    gfc_error ("Derived type %qs at %L must be an extension of %qs",
		       c->ts.u.derived->name, &c->where, selector_type->name);
	  else
	    gfc_error ("Unexpected intrinsic type %qs at %L",
		       gfc_basic_typename (c->ts.type), &c->where);
	  error++;
	  continue;
	}

      /* Check F03:C814.  */
      if (c->ts.type == BT_CHARACTER
	  && (c->ts.u.cl->length != NULL || c->ts.deferred))
	{
	  gfc_error ("The type-spec at %L shall specify that each length "
		     "type parameter is assumed", &c->where);
	  error++;
	  continue;
	}

      /* Intercept the DEFAULT case.  */
      if (c->ts.type == BT_UNKNOWN)
	{
	  /* Check F03:C818.  */
	  if (default_case)
	    {
	      gfc_error ("The DEFAULT CASE at %L cannot be followed "
			 "by a second DEFAULT CASE at %L",
			 &default_case->ext.block.case_list->where, &c->where);
	      error++;
	      continue;
	    }

	  default_case = body;
	}
    }

  if (error > 0)
    return;

  /* Transform SELECT TYPE statement to BLOCK and associate selector to
     target if present.  If there are any EXIT statements referring to the
     SELECT TYPE construct, this is no problem because the gfc_code
     reference stays the same and EXIT is equally possible from the BLOCK
     it is changed to.  */
  code->op = EXEC_BLOCK;
  if (code->expr2)
    {
      gfc_association_list* assoc;

      assoc = gfc_get_association_list ();
      assoc->st = code->expr1->symtree;
      assoc->target = gfc_copy_expr (code->expr2);
      assoc->target->where = code->expr2->where;
      /* assoc->variable will be set by resolve_assoc_var.  */

      code->ext.block.assoc = assoc;
      code->expr1->symtree->n.sym->assoc = assoc;

      resolve_assoc_var (code->expr1->symtree->n.sym, false);
    }
  else
    code->ext.block.assoc = NULL;

  /* Ensure that the selector rank and arrayspec are available to
     correct expressions in which they might be missing.  */
  if (code->expr2 && code->expr2->rank)
    {
      rank = code->expr2->rank;
      for (ref = code->expr2->ref; ref; ref = ref->next)
	if (ref->next == NULL)
	  break;
      if (ref && ref->type == REF_ARRAY)
	ref = gfc_copy_ref (ref);

      /* Fixup expr1 if necessary.  */
      if (rank)
	fixup_array_ref (&code->expr1, code->expr2, rank, ref);
    }
  else if (code->expr1->rank)
    {
      rank = code->expr1->rank;
      for (ref = code->expr1->ref; ref; ref = ref->next)
	if (ref->next == NULL)
	  break;
      if (ref && ref->type == REF_ARRAY)
	ref = gfc_copy_ref (ref);
    }

  /* Add EXEC_SELECT to switch on type.  */
  new_st = gfc_get_code (code->op);
  new_st->expr1 = code->expr1;
  new_st->expr2 = code->expr2;
  new_st->block = code->block;
  code->expr1 = code->expr2 =  NULL;
  code->block = NULL;
  if (!ns->code)
    ns->code = new_st;
  else
    ns->code->next = new_st;
  code = new_st;
  code->op = EXEC_SELECT_TYPE;

  /* Use the intrinsic LOC function to generate an integer expression
     for the vtable of the selector.  Note that the rank of the selector
     expression has to be set to zero.  */
  gfc_add_vptr_component (code->expr1);
  code->expr1->rank = 0;
  code->expr1 = build_loc_call (code->expr1);
  selector_expr = code->expr1->value.function.actual->expr;

  /* Loop over TYPE IS / CLASS IS cases.  */
  for (body = code->block; body; body = body->block)
    {
      gfc_symbol *vtab;
      gfc_expr *e;
      c = body->ext.block.case_list;

      /* Generate an index integer expression for address of the
	 TYPE/CLASS vtable and store it in c->low.  The hash expression
	 is stored in c->high and is used to resolve intrinsic cases.  */
      if (c->ts.type != BT_UNKNOWN)
	{
	  if (c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
	    {
	      vtab = gfc_find_derived_vtab (c->ts.u.derived);
	      gcc_assert (vtab);
	      c->high = gfc_get_int_expr (gfc_integer_4_kind, NULL,
					  c->ts.u.derived->hash_value);
	    }
	  else
	    {
	      vtab = gfc_find_vtab (&c->ts);
	      gcc_assert (vtab && CLASS_DATA (vtab)->initializer);
	      e = CLASS_DATA (vtab)->initializer;
	      c->high = gfc_copy_expr (e);
	      if (c->high->ts.kind != gfc_integer_4_kind)
		{
		  gfc_typespec ts;
		  ts.kind = gfc_integer_4_kind;
		  ts.type = BT_INTEGER;
		  gfc_convert_type_warn (c->high, &ts, 2, 0);
		}
	    }

	  e = gfc_lval_expr_from_sym (vtab);
	  c->low = build_loc_call (e);
	}
      else
	continue;

      /* Associate temporary to selector.  This should only be done
	 when this case is actually true, so build a new ASSOCIATE
	 that does precisely this here (instead of using the
	 'global' one).  */

      if (c->ts.type == BT_CLASS)
	sprintf (name, "__tmp_class_%s", c->ts.u.derived->name);
      else if (c->ts.type == BT_DERIVED)
	sprintf (name, "__tmp_type_%s", c->ts.u.derived->name);
      else if (c->ts.type == BT_CHARACTER)
	{
	  HOST_WIDE_INT charlen = 0;
	  if (c->ts.u.cl && c->ts.u.cl->length
	      && c->ts.u.cl->length->expr_type == EXPR_CONSTANT)
	    charlen = gfc_mpz_get_hwi (c->ts.u.cl->length->value.integer);
	  snprintf (name, sizeof (name),
		    "__tmp_%s_" HOST_WIDE_INT_PRINT_DEC "_%d",
		    gfc_basic_typename (c->ts.type), charlen, c->ts.kind);
	}
      else
	sprintf (name, "__tmp_%s_%d", gfc_basic_typename (c->ts.type),
	         c->ts.kind);

      st = gfc_find_symtree (ns->sym_root, name);
      gcc_assert (st->n.sym->assoc);
      st->n.sym->assoc->target = gfc_get_variable_expr (selector_expr->symtree);
      st->n.sym->assoc->target->where = selector_expr->where;
      if (c->ts.type != BT_CLASS && c->ts.type != BT_UNKNOWN)
	{
	  gfc_add_data_component (st->n.sym->assoc->target);
	  /* Fixup the target expression if necessary.  */
	  if (rank)
	    fixup_array_ref (&st->n.sym->assoc->target, NULL, rank, ref);
	}

      new_st = gfc_get_code (EXEC_BLOCK);
      new_st->ext.block.ns = gfc_build_block_ns (ns);
      new_st->ext.block.ns->code = body->next;
      body->next = new_st;

      /* Chain in the new list only if it is marked as dangling.  Otherwise
	 there is a CASE label overlap and this is already used.  Just ignore,
	 the error is diagnosed elsewhere.  */
      if (st->n.sym->assoc->dangling)
	{
	  new_st->ext.block.assoc = st->n.sym->assoc;
	  st->n.sym->assoc->dangling = 0;
	}

      resolve_assoc_var (st->n.sym, false);
    }

  /* Take out CLASS IS cases for separate treatment.  */
  body = code;
  while (body && body->block)
    {
      if (body->block->ext.block.case_list->ts.type == BT_CLASS)
	{
	  /* Add to class_is list.  */
	  if (class_is == NULL)
	    {
	      class_is = body->block;
	      tail = class_is;
	    }
	  else
	    {
	      for (tail = class_is; tail->block; tail = tail->block) ;
	      tail->block = body->block;
	      tail = tail->block;
	    }
	  /* Remove from EXEC_SELECT list.  */
	  body->block = body->block->block;
	  tail->block = NULL;
	}
      else
	body = body->block;
    }

  if (class_is)
    {
      gfc_symbol *vtab;

      if (!default_case)
	{
	  /* Add a default case to hold the CLASS IS cases.  */
	  for (tail = code; tail->block; tail = tail->block) ;
	  tail->block = gfc_get_code (EXEC_SELECT_TYPE);
	  tail = tail->block;
	  tail->ext.block.case_list = gfc_get_case ();
	  tail->ext.block.case_list->ts.type = BT_UNKNOWN;
	  tail->next = NULL;
	  default_case = tail;
	}

      /* More than one CLASS IS block?  */
      if (class_is->block)
	{
	  gfc_code **c1,*c2;
	  bool swapped;
	  /* Sort CLASS IS blocks by extension level.  */
	  do
	    {
	      swapped = false;
	      for (c1 = &class_is; (*c1) && (*c1)->block; c1 = &((*c1)->block))
		{
		  c2 = (*c1)->block;
		  /* F03:C817 (check for doubles).  */
		  if ((*c1)->ext.block.case_list->ts.u.derived->hash_value
		      == c2->ext.block.case_list->ts.u.derived->hash_value)
		    {
		      gfc_error ("Double CLASS IS block in SELECT TYPE "
				 "statement at %L",
				 &c2->ext.block.case_list->where);
		      return;
		    }
		  if ((*c1)->ext.block.case_list->ts.u.derived->attr.extension
		      < c2->ext.block.case_list->ts.u.derived->attr.extension)
		    {
		      /* Swap.  */
		      (*c1)->block = c2->block;
		      c2->block = *c1;
		      *c1 = c2;
		      swapped = true;
		    }
		}
	    }
	  while (swapped);
	}

      /* Generate IF chain.  */
      if_st = gfc_get_code (EXEC_IF);
      new_st = if_st;
      for (body = class_is; body; body = body->block)
	{
	  new_st->block = gfc_get_code (EXEC_IF);
	  new_st = new_st->block;
	  /* Set up IF condition: Call _gfortran_is_extension_of.  */
	  new_st->expr1 = gfc_get_expr ();
	  new_st->expr1->expr_type = EXPR_FUNCTION;
	  new_st->expr1->ts.type = BT_LOGICAL;
	  new_st->expr1->ts.kind = 4;
	  new_st->expr1->value.function.name = gfc_get_string (PREFIX ("is_extension_of"));
	  new_st->expr1->value.function.isym = XCNEW (gfc_intrinsic_sym);
	  new_st->expr1->value.function.isym->id = GFC_ISYM_EXTENDS_TYPE_OF;
	  /* Set up arguments.  */
	  new_st->expr1->value.function.actual = gfc_get_actual_arglist ();
	  new_st->expr1->value.function.actual->expr = gfc_get_variable_expr (selector_expr->symtree);
	  new_st->expr1->value.function.actual->expr->where = code->loc;
	  new_st->expr1->where = code->loc;
	  gfc_add_vptr_component (new_st->expr1->value.function.actual->expr);
	  vtab = gfc_find_derived_vtab (body->ext.block.case_list->ts.u.derived);
	  st = gfc_find_symtree (vtab->ns->sym_root, vtab->name);
	  new_st->expr1->value.function.actual->next = gfc_get_actual_arglist ();
	  new_st->expr1->value.function.actual->next->expr = gfc_get_variable_expr (st);
	  new_st->expr1->value.function.actual->next->expr->where = code->loc;
	  /* Set up types in formal arg list.  */
	  new_st->expr1->value.function.isym->formal = XCNEW (gfc_intrinsic_arg);
	  new_st->expr1->value.function.isym->formal->ts = new_st->expr1->value.function.actual->expr->ts;
	  new_st->expr1->value.function.isym->formal->next = XCNEW (gfc_intrinsic_arg);
	  new_st->expr1->value.function.isym->formal->next->ts = new_st->expr1->value.function.actual->next->expr->ts;

	  new_st->next = body->next;
	}
	if (default_case->next)
	  {
	    new_st->block = gfc_get_code (EXEC_IF);
	    new_st = new_st->block;
	    new_st->next = default_case->next;
	  }

	/* Replace CLASS DEFAULT code by the IF chain.  */
	default_case->next = if_st;
    }

  /* Resolve the internal code.  This cannot be done earlier because
     it requires that the sym->assoc of selectors is set already.  */
  gfc_current_ns = ns;
  gfc_resolve_blocks (code->block, gfc_current_ns);
  gfc_current_ns = old_ns;

  if (ref)
    free (ref);
}


/* Resolve a SELECT RANK statement.  */

static void
resolve_select_rank (gfc_code *code, gfc_namespace *old_ns)
{
  gfc_namespace *ns;
  gfc_code *body, *new_st, *tail;
  gfc_case *c;
  char tname[GFC_MAX_SYMBOL_LEN + 7];
  char name[2 * GFC_MAX_SYMBOL_LEN];
  gfc_symtree *st;
  gfc_expr *selector_expr = NULL;
  int case_value;
  HOST_WIDE_INT charlen = 0;

  ns = code->ext.block.ns;
  gfc_resolve (ns);

  code->op = EXEC_BLOCK;
  if (code->expr2)
    {
      gfc_association_list* assoc;

      assoc = gfc_get_association_list ();
      assoc->st = code->expr1->symtree;
      assoc->target = gfc_copy_expr (code->expr2);
      assoc->target->where = code->expr2->where;
      /* assoc->variable will be set by resolve_assoc_var.  */

      code->ext.block.assoc = assoc;
      code->expr1->symtree->n.sym->assoc = assoc;

      resolve_assoc_var (code->expr1->symtree->n.sym, false);
    }
  else
    code->ext.block.assoc = NULL;

  /* Loop over RANK cases. Note that returning on the errors causes a
     cascade of further errors because the case blocks do not compile
     correctly.  */
  for (body = code->block; body; body = body->block)
    {
      c = body->ext.block.case_list;
      if (c->low)
	case_value = (int) mpz_get_si (c->low->value.integer);
      else
	case_value = -2;

      /* Check for repeated cases.  */
      for (tail = code->block; tail; tail = tail->block)
	{
	  gfc_case *d = tail->ext.block.case_list;
	  int case_value2;

	  if (tail == body)
	    break;

	  /* Check F2018: C1153.  */
	  if (!c->low && !d->low)
	    gfc_error ("RANK DEFAULT at %L is repeated at %L",
		       &c->where, &d->where);

	  if (!c->low || !d->low)
	    continue;

	  /* Check F2018: C1153.  */
	  case_value2 = (int) mpz_get_si (d->low->value.integer);
	  if ((case_value == case_value2) && case_value == -1)
	    gfc_error ("RANK (*) at %L is repeated at %L",
		       &c->where, &d->where);
	  else if (case_value == case_value2)
	    gfc_error ("RANK (%i) at %L is repeated at %L",
		       case_value, &c->where, &d->where);
	}

      if (!c->low)
        continue;

      /* Check F2018: C1155.  */
      if (case_value == -1 && (gfc_expr_attr (code->expr1).allocatable
			       || gfc_expr_attr (code->expr1).pointer))
	gfc_error ("RANK (*) at %L cannot be used with the pointer or "
		   "allocatable selector at %L", &c->where, &code->expr1->where);

      if (case_value == -1 && (gfc_expr_attr (code->expr1).allocatable
			       || gfc_expr_attr (code->expr1).pointer))
	gfc_error ("RANK (*) at %L cannot be used with the pointer or "
		   "allocatable selector at %L", &c->where, &code->expr1->where);
    }

  /* Add EXEC_SELECT to switch on rank.  */
  new_st = gfc_get_code (code->op);
  new_st->expr1 = code->expr1;
  new_st->expr2 = code->expr2;
  new_st->block = code->block;
  code->expr1 = code->expr2 =  NULL;
  code->block = NULL;
  if (!ns->code)
    ns->code = new_st;
  else
    ns->code->next = new_st;
  code = new_st;
  code->op = EXEC_SELECT_RANK;

  selector_expr = code->expr1;

  /* Loop over SELECT RANK cases.  */
  for (body = code->block; body; body = body->block)
    {
      c = body->ext.block.case_list;
      int case_value;

      /* Pass on the default case.  */
      if (c->low == NULL)
	continue;

      /* Associate temporary to selector.  This should only be done
	 when this case is actually true, so build a new ASSOCIATE
	 that does precisely this here (instead of using the
	 'global' one).  */
      if (c->ts.type == BT_CHARACTER && c->ts.u.cl && c->ts.u.cl->length
	  && c->ts.u.cl->length->expr_type == EXPR_CONSTANT)
	charlen = gfc_mpz_get_hwi (c->ts.u.cl->length->value.integer);

      if (c->ts.type == BT_CLASS)
	sprintf (tname, "class_%s", c->ts.u.derived->name);
      else if (c->ts.type == BT_DERIVED)
	sprintf (tname, "type_%s", c->ts.u.derived->name);
      else if (c->ts.type != BT_CHARACTER)
	sprintf (tname, "%s_%d", gfc_basic_typename (c->ts.type), c->ts.kind);
      else
	sprintf (tname, "%s_" HOST_WIDE_INT_PRINT_DEC "_%d",
		 gfc_basic_typename (c->ts.type), charlen, c->ts.kind);

      case_value = (int) mpz_get_si (c->low->value.integer);
      if (case_value >= 0)
	sprintf (name, "__tmp_%s_rank_%d", tname, case_value);
      else
	sprintf (name, "__tmp_%s_rank_m%d", tname, -case_value);

      st = gfc_find_symtree (ns->sym_root, name);
      gcc_assert (st->n.sym->assoc);

      st->n.sym->assoc->target = gfc_get_variable_expr (selector_expr->symtree);
      st->n.sym->assoc->target->where = selector_expr->where;

      new_st = gfc_get_code (EXEC_BLOCK);
      new_st->ext.block.ns = gfc_build_block_ns (ns);
      new_st->ext.block.ns->code = body->next;
      body->next = new_st;

      /* Chain in the new list only if it is marked as dangling.  Otherwise
	 there is a CASE label overlap and this is already used.  Just ignore,
	 the error is diagnosed elsewhere.  */
      if (st->n.sym->assoc->dangling)
	{
	  new_st->ext.block.assoc = st->n.sym->assoc;
	  st->n.sym->assoc->dangling = 0;
	}

      resolve_assoc_var (st->n.sym, false);
    }

  gfc_current_ns = ns;
  gfc_resolve_blocks (code->block, gfc_current_ns);
  gfc_current_ns = old_ns;
}


/* Resolve a transfer statement. This is making sure that:
   -- a derived type being transferred has only non-pointer components
   -- a derived type being transferred doesn't have private components, unless
      it's being transferred from the module where the type was defined
   -- we're not trying to transfer a whole assumed size array.  */

static void
resolve_transfer (gfc_code *code)
{
  gfc_symbol *sym, *derived;
  gfc_ref *ref;
  gfc_expr *exp;
  bool write = false;
  bool formatted = false;
  gfc_dt *dt = code->ext.dt;
  gfc_symbol *dtio_sub = NULL;

  exp = code->expr1;

  while (exp != NULL && exp->expr_type == EXPR_OP
	 && exp->value.op.op == INTRINSIC_PARENTHESES)
    exp = exp->value.op.op1;

  if (exp && exp->expr_type == EXPR_NULL
      && code->ext.dt)
    {
      gfc_error ("Invalid context for NULL () intrinsic at %L",
		 &exp->where);
      return;
    }

  if (exp == NULL || (exp->expr_type != EXPR_VARIABLE
		      && exp->expr_type != EXPR_FUNCTION
		      && exp->expr_type != EXPR_STRUCTURE))
    return;

  /* If we are reading, the variable will be changed.  Note that
     code->ext.dt may be NULL if the TRANSFER is related to
     an INQUIRE statement -- but in this case, we are not reading, either.  */
  if (dt && dt->dt_io_kind->value.iokind == M_READ
      && !gfc_check_vardef_context (exp, false, false, false,
				    _("item in READ")))
    return;

  const gfc_typespec *ts = exp->expr_type == EXPR_STRUCTURE
			|| exp->expr_type == EXPR_FUNCTION
			 ? &exp->ts : &exp->symtree->n.sym->ts;

  /* Go to actual component transferred.  */
  for (ref = exp->ref; ref; ref = ref->next)
    if (ref->type == REF_COMPONENT)
      ts = &ref->u.c.component->ts;

  if (dt && dt->dt_io_kind->value.iokind != M_INQUIRE
      && (ts->type == BT_DERIVED || ts->type == BT_CLASS))
    {
      derived = ts->u.derived;

      /* Determine when to use the formatted DTIO procedure.  */
      if (dt && (dt->format_expr || dt->format_label))
	formatted = true;

      write = dt->dt_io_kind->value.iokind == M_WRITE
	      || dt->dt_io_kind->value.iokind == M_PRINT;
      dtio_sub = gfc_find_specific_dtio_proc (derived, write, formatted);

      if (dtio_sub != NULL && exp->expr_type == EXPR_VARIABLE)
	{
	  dt->udtio = exp;
	  sym = exp->symtree->n.sym->ns->proc_name;
	  /* Check to see if this is a nested DTIO call, with the
	     dummy as the io-list object.  */
	  if (sym && sym == dtio_sub && sym->formal
	      && sym->formal->sym == exp->symtree->n.sym
	      && exp->ref == NULL)
	    {
	      if (!sym->attr.recursive)
		{
		  gfc_error ("DTIO %s procedure at %L must be recursive",
			     sym->name, &sym->declared_at);
		  return;
		}
	    }
	}
    }

  if (ts->type == BT_CLASS && dtio_sub == NULL)
    {
      gfc_error ("Data transfer element at %L cannot be polymorphic unless "
                "it is processed by a defined input/output procedure",
                &code->loc);
      return;
    }

  if (ts->type == BT_DERIVED)
    {
      /* Check that transferred derived type doesn't contain POINTER
	 components unless it is processed by a defined input/output
	 procedure".  */
      if (ts->u.derived->attr.pointer_comp && dtio_sub == NULL)
	{
	  gfc_error ("Data transfer element at %L cannot have POINTER "
		     "components unless it is processed by a defined "
		     "input/output procedure", &code->loc);
	  return;
	}

      /* F08:C935.  */
      if (ts->u.derived->attr.proc_pointer_comp)
	{
	  gfc_error ("Data transfer element at %L cannot have "
		     "procedure pointer components", &code->loc);
	  return;
	}

      if (ts->u.derived->attr.alloc_comp && dtio_sub == NULL)
	{
	  gfc_error ("Data transfer element at %L cannot have ALLOCATABLE "
		     "components unless it is processed by a defined "
		     "input/output procedure", &code->loc);
	  return;
	}

      /* C_PTR and C_FUNPTR have private components which means they cannot
         be printed.  However, if -std=gnu and not -pedantic, allow
         the component to be printed to help debugging.  */
      if (ts->u.derived->ts.f90_type == BT_VOID)
	{
	  if (!gfc_notify_std (GFC_STD_GNU, "Data transfer element at %L "
			       "cannot have PRIVATE components", &code->loc))
	    return;
	}
      else if (derived_inaccessible (ts->u.derived) && dtio_sub == NULL)
	{
	  gfc_error ("Data transfer element at %L cannot have "
		     "PRIVATE components unless it is processed by "
		     "a defined input/output procedure", &code->loc);
	  return;
	}
    }

  if (exp->expr_type == EXPR_STRUCTURE)
    return;

  sym = exp->symtree->n.sym;

  if (sym->as != NULL && sym->as->type == AS_ASSUMED_SIZE && exp->ref
      && exp->ref->type == REF_ARRAY && exp->ref->u.ar.type == AR_FULL)
    {
      gfc_error ("Data transfer element at %L cannot be a full reference to "
		 "an assumed-size array", &code->loc);
      return;
    }
}


/*********** Toplevel code resolution subroutines ***********/

/* Find the set of labels that are reachable from this block.  We also
   record the last statement in each block.  */

static void
find_reachable_labels (gfc_code *block)
{
  gfc_code *c;

  if (!block)
    return;

  cs_base->reachable_labels = bitmap_alloc (&labels_obstack);

  /* Collect labels in this block.  We don't keep those corresponding
     to END {IF|SELECT}, these are checked in resolve_branch by going
     up through the code_stack.  */
  for (c = block; c; c = c->next)
    {
      if (c->here && c->op != EXEC_END_NESTED_BLOCK)
	bitmap_set_bit (cs_base->reachable_labels, c->here->value);
    }

  /* Merge with labels from parent block.  */
  if (cs_base->prev)
    {
      gcc_assert (cs_base->prev->reachable_labels);
      bitmap_ior_into (cs_base->reachable_labels,
		       cs_base->prev->reachable_labels);
    }
}


static void
resolve_lock_unlock_event (gfc_code *code)
{
  if (code->expr1->expr_type == EXPR_FUNCTION
      && code->expr1->value.function.isym
      && code->expr1->value.function.isym->id == GFC_ISYM_CAF_GET)
    remove_caf_get_intrinsic (code->expr1);

  if ((code->op == EXEC_LOCK || code->op == EXEC_UNLOCK)
      && (code->expr1->ts.type != BT_DERIVED
	  || code->expr1->expr_type != EXPR_VARIABLE
	  || code->expr1->ts.u.derived->from_intmod != INTMOD_ISO_FORTRAN_ENV
	  || code->expr1->ts.u.derived->intmod_sym_id != ISOFORTRAN_LOCK_TYPE
	  || code->expr1->rank != 0
	  || (!gfc_is_coarray (code->expr1) &&
	      !gfc_is_coindexed (code->expr1))))
    gfc_error ("Lock variable at %L must be a scalar of type LOCK_TYPE",
	       &code->expr1->where);
  else if ((code->op == EXEC_EVENT_POST || code->op == EXEC_EVENT_WAIT)
	   && (code->expr1->ts.type != BT_DERIVED
	       || code->expr1->expr_type != EXPR_VARIABLE
	       || code->expr1->ts.u.derived->from_intmod
		  != INTMOD_ISO_FORTRAN_ENV
	       || code->expr1->ts.u.derived->intmod_sym_id
		  != ISOFORTRAN_EVENT_TYPE
	       || code->expr1->rank != 0))
    gfc_error ("Event variable at %L must be a scalar of type EVENT_TYPE",
	       &code->expr1->where);
  else if (code->op == EXEC_EVENT_POST && !gfc_is_coarray (code->expr1)
	   && !gfc_is_coindexed (code->expr1))
    gfc_error ("Event variable argument at %L must be a coarray or coindexed",
	       &code->expr1->where);
  else if (code->op == EXEC_EVENT_WAIT && !gfc_is_coarray (code->expr1))
    gfc_error ("Event variable argument at %L must be a coarray but not "
	       "coindexed", &code->expr1->where);

  /* Check STAT.  */
  if (code->expr2
      && (code->expr2->ts.type != BT_INTEGER || code->expr2->rank != 0
	  || code->expr2->expr_type != EXPR_VARIABLE))
    gfc_error ("STAT= argument at %L must be a scalar INTEGER variable",
	       &code->expr2->where);

  if (code->expr2
      && !gfc_check_vardef_context (code->expr2, false, false, false,
				    _("STAT variable")))
    return;

  /* Check ERRMSG.  */
  if (code->expr3
      && (code->expr3->ts.type != BT_CHARACTER || code->expr3->rank != 0
	  || code->expr3->expr_type != EXPR_VARIABLE))
    gfc_error ("ERRMSG= argument at %L must be a scalar CHARACTER variable",
	       &code->expr3->where);

  if (code->expr3
      && !gfc_check_vardef_context (code->expr3, false, false, false,
				    _("ERRMSG variable")))
    return;

  /* Check for LOCK the ACQUIRED_LOCK.  */
  if (code->op != EXEC_EVENT_WAIT && code->expr4
      && (code->expr4->ts.type != BT_LOGICAL || code->expr4->rank != 0
	  || code->expr4->expr_type != EXPR_VARIABLE))
    gfc_error ("ACQUIRED_LOCK= argument at %L must be a scalar LOGICAL "
	       "variable", &code->expr4->where);

  if (code->op != EXEC_EVENT_WAIT && code->expr4
      && !gfc_check_vardef_context (code->expr4, false, false, false,
				    _("ACQUIRED_LOCK variable")))
    return;

  /* Check for EVENT WAIT the UNTIL_COUNT.  */
  if (code->op == EXEC_EVENT_WAIT && code->expr4)
    {
      if (!gfc_resolve_expr (code->expr4) || code->expr4->ts.type != BT_INTEGER
	  || code->expr4->rank != 0)
	gfc_error ("UNTIL_COUNT= argument at %L must be a scalar INTEGER "
		   "expression", &code->expr4->where);
    }
}


static void
resolve_critical (gfc_code *code)
{
  gfc_symtree *symtree;
  gfc_symbol *lock_type;
  char name[GFC_MAX_SYMBOL_LEN];
  static int serial = 0;

  if (flag_coarray != GFC_FCOARRAY_LIB)
    return;

  symtree = gfc_find_symtree (gfc_current_ns->sym_root,
			      GFC_PREFIX ("lock_type"));
  if (symtree)
    lock_type = symtree->n.sym;
  else
    {
      if (gfc_get_sym_tree (GFC_PREFIX ("lock_type"), gfc_current_ns, &symtree,
			    false) != 0)
	gcc_unreachable ();
      lock_type = symtree->n.sym;
      lock_type->attr.flavor = FL_DERIVED;
      lock_type->attr.zero_comp = 1;
      lock_type->from_intmod = INTMOD_ISO_FORTRAN_ENV;
      lock_type->intmod_sym_id = ISOFORTRAN_LOCK_TYPE;
    }

  sprintf(name, GFC_PREFIX ("lock_var") "%d",serial++);
  if (gfc_get_sym_tree (name, gfc_current_ns, &symtree, false) != 0)
    gcc_unreachable ();

  code->resolved_sym = symtree->n.sym;
  symtree->n.sym->attr.flavor = FL_VARIABLE;
  symtree->n.sym->attr.referenced = 1;
  symtree->n.sym->attr.artificial = 1;
  symtree->n.sym->attr.codimension = 1;
  symtree->n.sym->ts.type = BT_DERIVED;
  symtree->n.sym->ts.u.derived = lock_type;
  symtree->n.sym->as = gfc_get_array_spec ();
  symtree->n.sym->as->corank = 1;
  symtree->n.sym->as->type = AS_EXPLICIT;
  symtree->n.sym->as->cotype = AS_EXPLICIT;
  symtree->n.sym->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind,
						   NULL, 1);
  gfc_commit_symbols();
}


static void
resolve_sync (gfc_code *code)
{
  /* Check imageset. The * case matches expr1 == NULL.  */
  if (code->expr1)
    {
      if (code->expr1->ts.type != BT_INTEGER || code->expr1->rank > 1)
	gfc_error ("Imageset argument at %L must be a scalar or rank-1 "
		   "INTEGER expression", &code->expr1->where);
      if (code->expr1->expr_type == EXPR_CONSTANT && code->expr1->rank == 0
	  && mpz_cmp_si (code->expr1->value.integer, 1) < 0)
	gfc_error ("Imageset argument at %L must between 1 and num_images()",
		   &code->expr1->where);
      else if (code->expr1->expr_type == EXPR_ARRAY
	       && gfc_simplify_expr (code->expr1, 0))
	{
	   gfc_constructor *cons;
	   cons = gfc_constructor_first (code->expr1->value.constructor);
	   for (; cons; cons = gfc_constructor_next (cons))
	     if (cons->expr->expr_type == EXPR_CONSTANT
		 &&  mpz_cmp_si (cons->expr->value.integer, 1) < 0)
	       gfc_error ("Imageset argument at %L must between 1 and "
			  "num_images()", &cons->expr->where);
	}
    }

  /* Check STAT.  */
  gfc_resolve_expr (code->expr2);
  if (code->expr2)
    {
      if (code->expr2->ts.type != BT_INTEGER || code->expr2->rank != 0)
	gfc_error ("STAT= argument at %L must be a scalar INTEGER variable",
		   &code->expr2->where);
      else
	gfc_check_vardef_context (code->expr2, false, false, false,
				  _("STAT variable"));
    }

  /* Check ERRMSG.  */
  gfc_resolve_expr (code->expr3);
  if (code->expr3)
    {
      if (code->expr3->ts.type != BT_CHARACTER || code->expr3->rank != 0)
	gfc_error ("ERRMSG= argument at %L must be a scalar CHARACTER variable",
		   &code->expr3->where);
      else
	gfc_check_vardef_context (code->expr3, false, false, false,
				  _("ERRMSG variable"));
    }
}


/* Given a branch to a label, see if the branch is conforming.
   The code node describes where the branch is located.  */

static void
resolve_branch (gfc_st_label *label, gfc_code *code)
{
  code_stack *stack;

  if (label == NULL)
    return;

  /* Step one: is this a valid branching target?  */

  if (label->defined == ST_LABEL_UNKNOWN)
    {
      gfc_error ("Label %d referenced at %L is never defined", label->value,
		 &code->loc);
      return;
    }

  if (label->defined != ST_LABEL_TARGET && label->defined != ST_LABEL_DO_TARGET)
    {
      gfc_error ("Statement at %L is not a valid branch target statement "
		 "for the branch statement at %L", &label->where, &code->loc);
      return;
    }

  /* Step two: make sure this branch is not a branch to itself ;-)  */

  if (code->here == label)
    {
      gfc_warning (0,
		   "Branch at %L may result in an infinite loop", &code->loc);
      return;
    }

  /* Step three:  See if the label is in the same block as the
     branching statement.  The hard work has been done by setting up
     the bitmap reachable_labels.  */

  if (bitmap_bit_p (cs_base->reachable_labels, label->value))
    {
      /* Check now whether there is a CRITICAL construct; if so, check
	 whether the label is still visible outside of the CRITICAL block,
	 which is invalid.  */
      for (stack = cs_base; stack; stack = stack->prev)
	{
	  if (stack->current->op == EXEC_CRITICAL
	      && bitmap_bit_p (stack->reachable_labels, label->value))
	    gfc_error ("GOTO statement at %L leaves CRITICAL construct for "
		      "label at %L", &code->loc, &label->where);
	  else if (stack->current->op == EXEC_DO_CONCURRENT
		   && bitmap_bit_p (stack->reachable_labels, label->value))
	    gfc_error ("GOTO statement at %L leaves DO CONCURRENT construct "
		      "for label at %L", &code->loc, &label->where);
	}

      return;
    }

  /* Step four:  If we haven't found the label in the bitmap, it may
    still be the label of the END of the enclosing block, in which
    case we find it by going up the code_stack.  */

  for (stack = cs_base; stack; stack = stack->prev)
    {
      if (stack->current->next && stack->current->next->here == label)
	break;
      if (stack->current->op == EXEC_CRITICAL)
	{
	  /* Note: A label at END CRITICAL does not leave the CRITICAL
	     construct as END CRITICAL is still part of it.  */
	  gfc_error ("GOTO statement at %L leaves CRITICAL construct for label"
		      " at %L", &code->loc, &label->where);
	  return;
	}
      else if (stack->current->op == EXEC_DO_CONCURRENT)
	{
	  gfc_error ("GOTO statement at %L leaves DO CONCURRENT construct for "
		     "label at %L", &code->loc, &label->where);
	  return;
	}
    }

  if (stack)
    {
      gcc_assert (stack->current->next->op == EXEC_END_NESTED_BLOCK);
      return;
    }

  /* The label is not in an enclosing block, so illegal.  This was
     allowed in Fortran 66, so we allow it as extension.  No
     further checks are necessary in this case.  */
  gfc_notify_std (GFC_STD_LEGACY, "Label at %L is not in the same block "
		  "as the GOTO statement at %L", &label->where,
		  &code->loc);
  return;
}


/* Check whether EXPR1 has the same shape as EXPR2.  */

static bool
resolve_where_shape (gfc_expr *expr1, gfc_expr *expr2)
{
  mpz_t shape[GFC_MAX_DIMENSIONS];
  mpz_t shape2[GFC_MAX_DIMENSIONS];
  bool result = false;
  int i;

  /* Compare the rank.  */
  if (expr1->rank != expr2->rank)
    return result;

  /* Compare the size of each dimension.  */
  for (i=0; i<expr1->rank; i++)
    {
      if (!gfc_array_dimen_size (expr1, i, &shape[i]))
	goto ignore;

      if (!gfc_array_dimen_size (expr2, i, &shape2[i]))
	goto ignore;

      if (mpz_cmp (shape[i], shape2[i]))
	goto over;
    }

  /* When either of the two expression is an assumed size array, we
     ignore the comparison of dimension sizes.  */
ignore:
  result = true;

over:
  gfc_clear_shape (shape, i);
  gfc_clear_shape (shape2, i);
  return result;
}


/* Check whether a WHERE assignment target or a WHERE mask expression
   has the same shape as the outmost WHERE mask expression.  */

static void
resolve_where (gfc_code *code, gfc_expr *mask)
{
  gfc_code *cblock;
  gfc_code *cnext;
  gfc_expr *e = NULL;

  cblock = code->block;

  /* Store the first WHERE mask-expr of the WHERE statement or construct.
     In case of nested WHERE, only the outmost one is stored.  */
  if (mask == NULL) /* outmost WHERE */
    e = cblock->expr1;
  else /* inner WHERE */
    e = mask;

  while (cblock)
    {
      if (cblock->expr1)
	{
	  /* Check if the mask-expr has a consistent shape with the
	     outmost WHERE mask-expr.  */
	  if (!resolve_where_shape (cblock->expr1, e))
	    gfc_error ("WHERE mask at %L has inconsistent shape",
		       &cblock->expr1->where);
	 }

      /* the assignment statement of a WHERE statement, or the first
	 statement in where-body-construct of a WHERE construct */
      cnext = cblock->next;
      while (cnext)
	{
	  switch (cnext->op)
	    {
	    /* WHERE assignment statement */
	    case EXEC_ASSIGN:

	      /* Check shape consistent for WHERE assignment target.  */
	      if (e && !resolve_where_shape (cnext->expr1, e))
	       gfc_error ("WHERE assignment target at %L has "
			  "inconsistent shape", &cnext->expr1->where);
	      break;


	    case EXEC_ASSIGN_CALL:
	      resolve_call (cnext);
	      if (!cnext->resolved_sym->attr.elemental)
		gfc_error("Non-ELEMENTAL user-defined assignment in WHERE at %L",
			  &cnext->ext.actual->expr->where);
	      break;

	    /* WHERE or WHERE construct is part of a where-body-construct */
	    case EXEC_WHERE:
	      resolve_where (cnext, e);
	      break;

	    default:
	      gfc_error ("Unsupported statement inside WHERE at %L",
			 &cnext->loc);
	    }
	 /* the next statement within the same where-body-construct */
	 cnext = cnext->next;
       }
    /* the next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt */
    cblock = cblock->block;
  }
}


/* Resolve assignment in FORALL construct.
   NVAR is the number of FORALL index variables, and VAR_EXPR records the
   FORALL index variables.  */

static void
gfc_resolve_assign_in_forall (gfc_code *code, int nvar, gfc_expr **var_expr)
{
  int n;

  for (n = 0; n < nvar; n++)
    {
      gfc_symbol *forall_index;

      forall_index = var_expr[n]->symtree->n.sym;

      /* Check whether the assignment target is one of the FORALL index
	 variable.  */
      if ((code->expr1->expr_type == EXPR_VARIABLE)
	  && (code->expr1->symtree->n.sym == forall_index))
	gfc_error ("Assignment to a FORALL index variable at %L",
		   &code->expr1->where);
      else
	{
	  /* If one of the FORALL index variables doesn't appear in the
	     assignment variable, then there could be a many-to-one
	     assignment.  Emit a warning rather than an error because the
	     mask could be resolving this problem.  */
	  if (!find_forall_index (code->expr1, forall_index, 0))
	    gfc_warning (0, "The FORALL with index %qs is not used on the "
			 "left side of the assignment at %L and so might "
			 "cause multiple assignment to this object",
			 var_expr[n]->symtree->name, &code->expr1->where);
	}
    }
}


/* Resolve WHERE statement in FORALL construct.  */

static void
gfc_resolve_where_code_in_forall (gfc_code *code, int nvar,
				  gfc_expr **var_expr)
{
  gfc_code *cblock;
  gfc_code *cnext;

  cblock = code->block;
  while (cblock)
    {
      /* the assignment statement of a WHERE statement, or the first
	 statement in where-body-construct of a WHERE construct */
      cnext = cblock->next;
      while (cnext)
	{
	  switch (cnext->op)
	    {
	    /* WHERE assignment statement */
	    case EXEC_ASSIGN:
	      gfc_resolve_assign_in_forall (cnext, nvar, var_expr);
	      break;

	    /* WHERE operator assignment statement */
	    case EXEC_ASSIGN_CALL:
	      resolve_call (cnext);
	      if (!cnext->resolved_sym->attr.elemental)
		gfc_error("Non-ELEMENTAL user-defined assignment in WHERE at %L",
			  &cnext->ext.actual->expr->where);
	      break;

	    /* WHERE or WHERE construct is part of a where-body-construct */
	    case EXEC_WHERE:
	      gfc_resolve_where_code_in_forall (cnext, nvar, var_expr);
	      break;

	    default:
	      gfc_error ("Unsupported statement inside WHERE at %L",
			 &cnext->loc);
	    }
	  /* the next statement within the same where-body-construct */
	  cnext = cnext->next;
	}
      /* the next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt */
      cblock = cblock->block;
    }
}


/* Traverse the FORALL body to check whether the following errors exist:
   1. For assignment, check if a many-to-one assignment happens.
   2. For WHERE statement, check the WHERE body to see if there is any
      many-to-one assignment.  */

static void
gfc_resolve_forall_body (gfc_code *code, int nvar, gfc_expr **var_expr)
{
  gfc_code *c;

  c = code->block->next;
  while (c)
    {
      switch (c->op)
	{
	case EXEC_ASSIGN:
	case EXEC_POINTER_ASSIGN:
	  gfc_resolve_assign_in_forall (c, nvar, var_expr);
	  break;

	case EXEC_ASSIGN_CALL:
	  resolve_call (c);
	  break;

	/* Because the gfc_resolve_blocks() will handle the nested FORALL,
	   there is no need to handle it here.  */
	case EXEC_FORALL:
	  break;
	case EXEC_WHERE:
	  gfc_resolve_where_code_in_forall(c, nvar, var_expr);
	  break;
	default:
	  break;
	}
      /* The next statement in the FORALL body.  */
      c = c->next;
    }
}


/* Counts the number of iterators needed inside a forall construct, including
   nested forall constructs. This is used to allocate the needed memory
   in gfc_resolve_forall.  */

static int
gfc_count_forall_iterators (gfc_code *code)
{
  int max_iters, sub_iters, current_iters;
  gfc_forall_iterator *fa;

  gcc_assert(code->op == EXEC_FORALL);
  max_iters = 0;
  current_iters = 0;

  for (fa = code->ext.forall_iterator; fa; fa = fa->next)
    current_iters ++;

  code = code->block->next;

  while (code)
    {
      if (code->op == EXEC_FORALL)
        {
          sub_iters = gfc_count_forall_iterators (code);
          if (sub_iters > max_iters)
            max_iters = sub_iters;
        }
      code = code->next;
    }

  return current_iters + max_iters;
}


/* Given a FORALL construct, first resolve the FORALL iterator, then call
   gfc_resolve_forall_body to resolve the FORALL body.  */

static void
gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
{
  static gfc_expr **var_expr;
  static int total_var = 0;
  static int nvar = 0;
  int i, old_nvar, tmp;
  gfc_forall_iterator *fa;

  old_nvar = nvar;

  if (!gfc_notify_std (GFC_STD_F2018_OBS, "FORALL construct at %L", &code->loc))
    return;

  /* Start to resolve a FORALL construct   */
  if (forall_save == 0)
    {
      /* Count the total number of FORALL indices in the nested FORALL
         construct in order to allocate the VAR_EXPR with proper size.  */
      total_var = gfc_count_forall_iterators (code);

      /* Allocate VAR_EXPR with NUMBER_OF_FORALL_INDEX elements.  */
      var_expr = XCNEWVEC (gfc_expr *, total_var);
    }

  /* The information about FORALL iterator, including FORALL indices start, end
     and stride.  An outer FORALL indice cannot appear in start, end or stride.  */
  for (fa = code->ext.forall_iterator; fa; fa = fa->next)
    {
      /* Fortran 20008: C738 (R753).  */
      if (fa->var->ref && fa->var->ref->type == REF_ARRAY)
	{
	  gfc_error ("FORALL index-name at %L must be a scalar variable "
		     "of type integer", &fa->var->where);
	  continue;
	}

      /* Check if any outer FORALL index name is the same as the current
	 one.  */
      for (i = 0; i < nvar; i++)
	{
	  if (fa->var->symtree->n.sym == var_expr[i]->symtree->n.sym)
	    gfc_error ("An outer FORALL construct already has an index "
			"with this name %L", &fa->var->where);
	}

      /* Record the current FORALL index.  */
      var_expr[nvar] = gfc_copy_expr (fa->var);

      nvar++;

      /* No memory leak.  */
      gcc_assert (nvar <= total_var);
    }

  /* Resolve the FORALL body.  */
  gfc_resolve_forall_body (code, nvar, var_expr);

  /* May call gfc_resolve_forall to resolve the inner FORALL loop.  */
  gfc_resolve_blocks (code->block, ns);

  tmp = nvar;
  nvar = old_nvar;
  /* Free only the VAR_EXPRs allocated in this frame.  */
  for (i = nvar; i < tmp; i++)
     gfc_free_expr (var_expr[i]);

  if (nvar == 0)
    {
      /* We are in the outermost FORALL construct.  */
      gcc_assert (forall_save == 0);

      /* VAR_EXPR is not needed any more.  */
      free (var_expr);
      total_var = 0;
    }
}


/* Resolve a BLOCK construct statement.  */

static void
resolve_block_construct (gfc_code* code)
{
  /* Resolve the BLOCK's namespace.  */
  gfc_resolve (code->ext.block.ns);

  /* For an ASSOCIATE block, the associations (and their targets) are already
     resolved during resolve_symbol.  */
}


/* Resolve lists of blocks found in IF, SELECT CASE, WHERE, FORALL, GOTO and
   DO code nodes.  */

void
gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
{
  bool t;

  for (; b; b = b->block)
    {
      t = gfc_resolve_expr (b->expr1);
      if (!gfc_resolve_expr (b->expr2))
	t = false;

      switch (b->op)
	{
	case EXEC_IF:
	  if (t && b->expr1 != NULL
	      && (b->expr1->ts.type != BT_LOGICAL || b->expr1->rank != 0))
	    gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
		       &b->expr1->where);
	  break;

	case EXEC_WHERE:
	  if (t
	      && b->expr1 != NULL
	      && (b->expr1->ts.type != BT_LOGICAL || b->expr1->rank == 0))
	    gfc_error ("WHERE/ELSEWHERE clause at %L requires a LOGICAL array",
		       &b->expr1->where);
	  break;

	case EXEC_GOTO:
	  resolve_branch (b->label1, b);
	  break;

	case EXEC_BLOCK:
	  resolve_block_construct (b);
	  break;

	case EXEC_SELECT:
	case EXEC_SELECT_TYPE:
	case EXEC_SELECT_RANK:
	case EXEC_FORALL:
	case EXEC_DO:
	case EXEC_DO_WHILE:
	case EXEC_DO_CONCURRENT:
	case EXEC_CRITICAL:
	case EXEC_READ:
	case EXEC_WRITE:
	case EXEC_IOLENGTH:
	case EXEC_WAIT:
	  break;

	case EXEC_OMP_ATOMIC:
	case EXEC_OACC_ATOMIC:
	  {
	    /* Verify this before calling gfc_resolve_code, which might
	       change it.  */
	    gcc_assert (b->next && b->next->op == EXEC_ASSIGN);
	    gcc_assert ((!b->ext.omp_clauses->capture
			 && b->next->next == NULL)
			|| (b->ext.omp_clauses->capture
			    && b->next->next != NULL
			    && b->next->next->op == EXEC_ASSIGN
			    && b->next->next->next == NULL));
	  }
	  break;

	case EXEC_OACC_PARALLEL_LOOP:
	case EXEC_OACC_PARALLEL:
	case EXEC_OACC_KERNELS_LOOP:
	case EXEC_OACC_KERNELS:
	case EXEC_OACC_SERIAL_LOOP:
	case EXEC_OACC_SERIAL:
	case EXEC_OACC_DATA:
	case EXEC_OACC_HOST_DATA:
	case EXEC_OACC_LOOP:
	case EXEC_OACC_UPDATE:
	case EXEC_OACC_WAIT:
	case EXEC_OACC_CACHE:
	case EXEC_OACC_ENTER_DATA:
	case EXEC_OACC_EXIT_DATA:
	case EXEC_OACC_ROUTINE:
	case EXEC_OMP_CRITICAL:
	case EXEC_OMP_DISTRIBUTE:
	case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
	case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
	case EXEC_OMP_DISTRIBUTE_SIMD:
	case EXEC_OMP_DO:
	case EXEC_OMP_DO_SIMD:
	case EXEC_OMP_ERROR:
	case EXEC_OMP_LOOP:
	case EXEC_OMP_MASKED:
	case EXEC_OMP_MASKED_TASKLOOP:
	case EXEC_OMP_MASKED_TASKLOOP_SIMD:
	case EXEC_OMP_MASTER:
	case EXEC_OMP_MASTER_TASKLOOP:
	case EXEC_OMP_MASTER_TASKLOOP_SIMD:
	case EXEC_OMP_ORDERED:
	case EXEC_OMP_PARALLEL:
	case EXEC_OMP_PARALLEL_DO:
	case EXEC_OMP_PARALLEL_DO_SIMD:
	case EXEC_OMP_PARALLEL_LOOP:
	case EXEC_OMP_PARALLEL_MASKED:
	case EXEC_OMP_PARALLEL_MASKED_TASKLOOP:
	case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
	case EXEC_OMP_PARALLEL_MASTER:
	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
	case EXEC_OMP_PARALLEL_SECTIONS:
	case EXEC_OMP_PARALLEL_WORKSHARE:
	case EXEC_OMP_SECTIONS:
	case EXEC_OMP_SIMD:
	case EXEC_OMP_SCOPE:
	case EXEC_OMP_SINGLE:
	case EXEC_OMP_TARGET:
	case EXEC_OMP_TARGET_DATA:
	case EXEC_OMP_TARGET_ENTER_DATA:
	case EXEC_OMP_TARGET_EXIT_DATA:
	case EXEC_OMP_TARGET_PARALLEL:
	case EXEC_OMP_TARGET_PARALLEL_DO:
	case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
	case EXEC_OMP_TARGET_PARALLEL_LOOP:
	case EXEC_OMP_TARGET_SIMD:
	case EXEC_OMP_TARGET_TEAMS:
	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
	case EXEC_OMP_TARGET_TEAMS_LOOP:
	case EXEC_OMP_TARGET_UPDATE:
	case EXEC_OMP_TASK:
	case EXEC_OMP_TASKGROUP:
	case EXEC_OMP_TASKLOOP:
	case EXEC_OMP_TASKLOOP_SIMD:
	case EXEC_OMP_TASKWAIT:
	case EXEC_OMP_TASKYIELD:
	case EXEC_OMP_TEAMS:
	case EXEC_OMP_TEAMS_DISTRIBUTE:
	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
	case EXEC_OMP_TEAMS_LOOP:
	case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
	case EXEC_OMP_WORKSHARE:
	  break;

	default:
	  gfc_internal_error ("gfc_resolve_blocks(): Bad block type");
	}

      gfc_resolve_code (b->next, ns);
    }
}


/* Does everything to resolve an ordinary assignment.  Returns true
   if this is an interface assignment.  */
static bool
resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns)
{
  bool rval = false;
  gfc_expr *lhs;
  gfc_expr *rhs;
  int n;
  gfc_ref *ref;
  symbol_attribute attr;

  if (gfc_extend_assign (code, ns))
    {
      gfc_expr** rhsptr;

      if (code->op == EXEC_ASSIGN_CALL)
	{
	  lhs = code->ext.actual->expr;
	  rhsptr = &code->ext.actual->next->expr;
	}
      else
	{
	  gfc_actual_arglist* args;
	  gfc_typebound_proc* tbp;

	  gcc_assert (code->op == EXEC_COMPCALL);

	  args = code->expr1->value.compcall.actual;
	  lhs = args->expr;
	  rhsptr = &args->next->expr;

	  tbp = code->expr1->value.compcall.tbp;
	  gcc_assert (!tbp->is_generic);
	}

      /* Make a temporary rhs when there is a default initializer
	 and rhs is the same symbol as the lhs.  */
      if ((*rhsptr)->expr_type == EXPR_VARIABLE
	    && (*rhsptr)->symtree->n.sym->ts.type == BT_DERIVED
	    && gfc_has_default_initializer ((*rhsptr)->symtree->n.sym->ts.u.derived)
	    && (lhs->symtree->n.sym == (*rhsptr)->symtree->n.sym))
	*rhsptr = gfc_get_parentheses (*rhsptr);

      return true;
    }

  lhs = code->expr1;
  rhs = code->expr2;

  if ((gfc_numeric_ts (&lhs->ts) || lhs->ts.type == BT_LOGICAL)
      && rhs->ts.type == BT_CHARACTER
      && (rhs->expr_type != EXPR_CONSTANT || !flag_dec_char_conversions))
    {
      /* Use of -fdec-char-conversions allows assignment of character data
	 to non-character variables.  This not permited for nonconstant
	 strings.  */
      gfc_error ("Cannot convert %s to %s at %L", gfc_typename (rhs),
		 gfc_typename (lhs), &rhs->where);
      return false;
    }

  /* Handle the case of a BOZ literal on the RHS.  */
  if (rhs->ts.type == BT_BOZ)
    {
      if (gfc_invalid_boz ("BOZ literal constant at %L is neither a DATA "
			   "statement value nor an actual argument of "
			   "INT/REAL/DBLE/CMPLX intrinsic subprogram",
			   &rhs->where))
	return false;

      switch (lhs->ts.type)
	{
	case BT_INTEGER:
	  if (!gfc_boz2int (rhs, lhs->ts.kind))
	    return false;
	  break;
	case BT_REAL:
	  if (!gfc_boz2real (rhs, lhs->ts.kind))
	    return false;
	  break;
	default:
	  gfc_error ("Invalid use of BOZ literal constant at %L", &rhs->where);
	  return false;
	}
    }

  if (lhs->ts.type == BT_CHARACTER && warn_character_truncation)
    {
      HOST_WIDE_INT llen = 0, rlen = 0;
      if (lhs->ts.u.cl != NULL
	    && lhs->ts.u.cl->length != NULL
	    && lhs->ts.u.cl->length->expr_type == EXPR_CONSTANT)
	llen = gfc_mpz_get_hwi (lhs->ts.u.cl->length->value.integer);

      if (rhs->expr_type == EXPR_CONSTANT)
 	rlen = rhs->value.character.length;

      else if (rhs->ts.u.cl != NULL
		 && rhs->ts.u.cl->length != NULL
		 && rhs->ts.u.cl->length->expr_type == EXPR_CONSTANT)
	rlen = gfc_mpz_get_hwi (rhs->ts.u.cl->length->value.integer);

      if (rlen && llen && rlen > llen)
	gfc_warning_now (OPT_Wcharacter_truncation,
			 "CHARACTER expression will be truncated "
			 "in assignment (%ld/%ld) at %L",
			 (long) llen, (long) rlen, &code->loc);
    }

  /* Ensure that a vector index expression for the lvalue is evaluated
     to a temporary if the lvalue symbol is referenced in it.  */
  if (lhs->rank)
    {
      for (ref = lhs->ref; ref; ref= ref->next)
	if (ref->type == REF_ARRAY)
	  {
	    for (n = 0; n < ref->u.ar.dimen; n++)
	      if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR
		  && gfc_find_sym_in_expr (lhs->symtree->n.sym,
					   ref->u.ar.start[n]))
		ref->u.ar.start[n]
			= gfc_get_parentheses (ref->u.ar.start[n]);
	  }
    }

  if (gfc_pure (NULL))
    {
      if (lhs->ts.type == BT_DERIVED
	    && lhs->expr_type == EXPR_VARIABLE
	    && lhs->ts.u.derived->attr.pointer_comp
	    && rhs->expr_type == EXPR_VARIABLE
	    && (gfc_impure_variable (rhs->symtree->n.sym)
		|| gfc_is_coindexed (rhs)))
	{
	  /* F2008, C1283.  */
	  if (gfc_is_coindexed (rhs))
	    gfc_error ("Coindexed expression at %L is assigned to "
			"a derived type variable with a POINTER "
			"component in a PURE procedure",
			&rhs->where);
	  else
	  /* F2008, C1283 (4).  */
	    gfc_error ("In a pure subprogram an INTENT(IN) dummy argument "
			"shall not be used as the expr at %L of an intrinsic "
			"assignment statement in which the variable is of a "
			"derived type if the derived type has a pointer "
			"component at any level of component selection.",
			&rhs->where);
	  return rval;
	}

      /* Fortran 2008, C1283.  */
      if (gfc_is_coindexed (lhs))
	{
	  gfc_error ("Assignment to coindexed variable at %L in a PURE "
		     "procedure", &rhs->where);
	  return rval;
	}
    }

  if (gfc_implicit_pure (NULL))
    {
      if (lhs->expr_type == EXPR_VARIABLE
	    && lhs->symtree->n.sym != gfc_current_ns->proc_name
	    && lhs->symtree->n.sym->ns != gfc_current_ns)
	gfc_unset_implicit_pure (NULL);

      if (lhs->ts.type == BT_DERIVED
	    && lhs->expr_type == EXPR_VARIABLE
	    && lhs->ts.u.derived->attr.pointer_comp
	    && rhs->expr_type == EXPR_VARIABLE
	    && (gfc_impure_variable (rhs->symtree->n.sym)
		|| gfc_is_coindexed (rhs)))
	gfc_unset_implicit_pure (NULL);

      /* Fortran 2008, C1283.  */
      if (gfc_is_coindexed (lhs))
	gfc_unset_implicit_pure (NULL);
    }

  /* F2008, 7.2.1.2.  */
  attr = gfc_expr_attr (lhs);
  if (lhs->ts.type == BT_CLASS && attr.allocatable)
    {
      if (attr.codimension)
	{
	  gfc_error ("Assignment to polymorphic coarray at %L is not "
		     "permitted", &lhs->where);
	  return false;
	}
      if (!gfc_notify_std (GFC_STD_F2008, "Assignment to an allocatable "
			   "polymorphic variable at %L", &lhs->where))
	return false;
      if (!flag_realloc_lhs)
	{
	  gfc_error ("Assignment to an allocatable polymorphic variable at %L "
		     "requires %<-frealloc-lhs%>", &lhs->where);
	  return false;
	}
    }
  else if (lhs->ts.type == BT_CLASS)
    {
      gfc_error ("Nonallocatable variable must not be polymorphic in intrinsic "
		 "assignment at %L - check that there is a matching specific "
		 "subroutine for '=' operator", &lhs->where);
      return false;
    }

  bool lhs_coindexed = gfc_is_coindexed (lhs);

  /* F2008, Section 7.2.1.2.  */
  if (lhs_coindexed && gfc_has_ultimate_allocatable (lhs))
    {
      gfc_error ("Coindexed variable must not have an allocatable ultimate "
		 "component in assignment at %L", &lhs->where);
      return false;
    }

  /* Assign the 'data' of a class object to a derived type.  */
  if (lhs->ts.type == BT_DERIVED
      && rhs->ts.type == BT_CLASS
      && rhs->expr_type != EXPR_ARRAY)
    gfc_add_data_component (rhs);

  /* Make sure there is a vtable and, in particular, a _copy for the
     rhs type.  */
  if (lhs->ts.type == BT_CLASS && rhs->ts.type != BT_CLASS)
    gfc_find_vtab (&rhs->ts);

  bool caf_convert_to_send = flag_coarray == GFC_FCOARRAY_LIB
      && (lhs_coindexed
	  || (code->expr2->expr_type == EXPR_FUNCTION
	      && code->expr2->value.function.isym
	      && code->expr2->value.function.isym->id == GFC_ISYM_CAF_GET
	      && (code->expr1->rank == 0 || code->expr2->rank != 0)
	      && !gfc_expr_attr (rhs).allocatable
	      && !gfc_has_vector_subscript (rhs)));

  gfc_check_assign (lhs, rhs, 1, !caf_convert_to_send);

  /* Insert a GFC_ISYM_CAF_SEND intrinsic, when the LHS is a coindexed variable.
     Additionally, insert this code when the RHS is a CAF as we then use the
     GFC_ISYM_CAF_SEND intrinsic just to avoid a temporary; but do not do so if
     the LHS is (re)allocatable or has a vector subscript.  If the LHS is a
     noncoindexed array and the RHS is a coindexed scalar, use the normal code
     path.  */
  if (caf_convert_to_send)
    {
      if (code->expr2->expr_type == EXPR_FUNCTION
	  && code->expr2->value.function.isym
	  && code->expr2->value.function.isym->id == GFC_ISYM_CAF_GET)
	remove_caf_get_intrinsic (code->expr2);
      code->op = EXEC_CALL;
      gfc_get_sym_tree (GFC_PREFIX ("caf_send"), ns, &code->symtree, true);
      code->resolved_sym = code->symtree->n.sym;
      code->resolved_sym->attr.flavor = FL_PROCEDURE;
      code->resolved_sym->attr.intrinsic = 1;
      code->resolved_sym->attr.subroutine = 1;
      code->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SEND);
      gfc_commit_symbol (code->resolved_sym);
      code->ext.actual = gfc_get_actual_arglist ();
      code->ext.actual->expr = lhs;
      code->ext.actual->next = gfc_get_actual_arglist ();
      code->ext.actual->next->expr = rhs;
      code->expr1 = NULL;
      code->expr2 = NULL;
    }

  return false;
}


/* Add a component reference onto an expression.  */

static void
add_comp_ref (gfc_expr *e, gfc_component *c)
{
  gfc_ref **ref;
  ref = &(e->ref);
  while (*ref)
    ref = &((*ref)->next);
  *ref = gfc_get_ref ();
  (*ref)->type = REF_COMPONENT;
  (*ref)->u.c.sym = e->ts.u.derived;
  (*ref)->u.c.component = c;
  e->ts = c->ts;

  /* Add a full array ref, as necessary.  */
  if (c->as)
    {
      gfc_add_full_array_ref (e, c->as);
      e->rank = c->as->rank;
    }
}


/* Build an assignment.  Keep the argument 'op' for future use, so that
   pointer assignments can be made.  */

static gfc_code *
build_assignment (gfc_exec_op op, gfc_expr *expr1, gfc_expr *expr2,
		  gfc_component *comp1, gfc_component *comp2, locus loc)
{
  gfc_code *this_code;

  this_code = gfc_get_code (op);
  this_code->next = NULL;
  this_code->expr1 = gfc_copy_expr (expr1);
  this_code->expr2 = gfc_copy_expr (expr2);
  this_code->loc = loc;
  if (comp1 && comp2)
    {
      add_comp_ref (this_code->expr1, comp1);
      add_comp_ref (this_code->expr2, comp2);
    }

  return this_code;
}


/* Makes a temporary variable expression based on the characteristics of
   a given variable expression.  */

static gfc_expr*
get_temp_from_expr (gfc_expr *e, gfc_namespace *ns)
{
  static int serial = 0;
  char name[GFC_MAX_SYMBOL_LEN];
  gfc_symtree *tmp;
  gfc_array_spec *as;
  gfc_array_ref *aref;
  gfc_ref *ref;

  sprintf (name, GFC_PREFIX("DA%d"), serial++);
  gfc_get_sym_tree (name, ns, &tmp, false);
  gfc_add_type (tmp->n.sym, &e->ts, NULL);

  if (e->expr_type == EXPR_CONSTANT && e->ts.type == BT_CHARACTER)
    tmp->n.sym->ts.u.cl->length = gfc_get_int_expr (gfc_charlen_int_kind,
						    NULL,
						    e->value.character.length);

  as = NULL;
  ref = NULL;
  aref = NULL;

  /* Obtain the arrayspec for the temporary.  */
   if (e->rank && e->expr_type != EXPR_ARRAY
       && e->expr_type != EXPR_FUNCTION
       && e->expr_type != EXPR_OP)
    {
      aref = gfc_find_array_ref (e);
      if (e->expr_type == EXPR_VARIABLE
	  && e->symtree->n.sym->as == aref->as)
	as = aref->as;
      else
	{
	  for (ref = e->ref; ref; ref = ref->next)
	    if (ref->type == REF_COMPONENT
		&& ref->u.c.component->as == aref->as)
	      {
		as = aref->as;
		break;
	      }
	}
    }

  /* Add the attributes and the arrayspec to the temporary.  */
  tmp->n.sym->attr = gfc_expr_attr (e);
  tmp->n.sym->attr.function = 0;
  tmp->n.sym->attr.proc_pointer = 0;
  tmp->n.sym->attr.result = 0;
  tmp->n.sym->attr.flavor = FL_VARIABLE;
  tmp->n.sym->attr.dummy = 0;
  tmp->n.sym->attr.use_assoc = 0;
  tmp->n.sym->attr.intent = INTENT_UNKNOWN;

  if (as)
    {
      tmp->n.sym->as = gfc_copy_array_spec (as);
      if (!ref)
	ref = e->ref;
      if (as->type == AS_DEFERRED)
	tmp->n.sym->attr.allocatable = 1;
    }
  else if (e->rank && (e->expr_type == EXPR_ARRAY
		       || e->expr_type == EXPR_FUNCTION
		       || e->expr_type == EXPR_OP))
    {
      tmp->n.sym->as = gfc_get_array_spec ();
      tmp->n.sym->as->type = AS_DEFERRED;
      tmp->n.sym->as->rank = e->rank;
      tmp->n.sym->attr.allocatable = 1;
      tmp->n.sym->attr.dimension = 1;
    }
  else
    tmp->n.sym->attr.dimension = 0;

  gfc_set_sym_referenced (tmp->n.sym);
  gfc_commit_symbol (tmp->n.sym);
  e = gfc_lval_expr_from_sym (tmp->n.sym);

  /* Should the lhs be a section, use its array ref for the
     temporary expression.  */
  if (aref && aref->type != AR_FULL)
    {
      gfc_free_ref_list (e->ref);
      e->ref = gfc_copy_ref (ref);
    }
  return e;
}


/* Add one line of code to the code chain, making sure that 'head' and
   'tail' are appropriately updated.  */

static void
add_code_to_chain (gfc_code **this_code, gfc_code **head, gfc_code **tail)
{
  gcc_assert (this_code);
  if (*head == NULL)
    *head = *tail = *this_code;
  else
    *tail = gfc_append_code (*tail, *this_code);
  *this_code = NULL;
}


/* Counts the potential number of part array references that would
   result from resolution of typebound defined assignments.  */

static int
nonscalar_typebound_assign (gfc_symbol *derived, int depth)
{
  gfc_component *c;
  int c_depth = 0, t_depth;

  for (c= derived->components; c; c = c->next)
    {
      if ((!gfc_bt_struct (c->ts.type)
	    || c->attr.pointer
	    || c->attr.allocatable
	    || c->attr.proc_pointer_comp
	    || c->attr.class_pointer
	    || c->attr.proc_pointer)
	  && !c->attr.defined_assign_comp)
	continue;

      if (c->as && c_depth == 0)
	c_depth = 1;

      if (c->ts.u.derived->attr.defined_assign_comp)
	t_depth = nonscalar_typebound_assign (c->ts.u.derived,
					      c->as ? 1 : 0);
      else
	t_depth = 0;

      c_depth = t_depth > c_depth ? t_depth : c_depth;
    }
  return depth + c_depth;
}


/* Implement 7.2.1.3 of the F08 standard:
   "An intrinsic assignment where the variable is of derived type is
   performed as if each component of the variable were assigned from the
   corresponding component of expr using pointer assignment (7.2.2) for
   each pointer component, defined assignment for each nonpointer
   nonallocatable component of a type that has a type-bound defined
   assignment consistent with the component, intrinsic assignment for
   each other nonpointer nonallocatable component, ..."

   The pointer assignments are taken care of by the intrinsic
   assignment of the structure itself.  This function recursively adds
   defined assignments where required.  The recursion is accomplished
   by calling gfc_resolve_code.

   When the lhs in a defined assignment has intent INOUT, we need a
   temporary for the lhs.  In pseudo-code:

   ! Only call function lhs once.
      if (lhs is not a constant or an variable)
	  temp_x = expr2
          expr2 => temp_x
   ! Do the intrinsic assignment
      expr1 = expr2
   ! Now do the defined assignments
      do over components with typebound defined assignment [%cmp]
	#if one component's assignment procedure is INOUT
	  t1 = expr1
	  #if expr2 non-variable
	    temp_x = expr2
	    expr2 => temp_x
	  # endif
	  expr1 = expr2
	  # for each cmp
	    t1%cmp {defined=} expr2%cmp
	    expr1%cmp = t1%cmp
	#else
	  expr1 = expr2

	# for each cmp
	  expr1%cmp {defined=} expr2%cmp
	#endif
   */

/* The temporary assignments have to be put on top of the additional
   code to avoid the result being changed by the intrinsic assignment.
   */
static int component_assignment_level = 0;
static gfc_code *tmp_head = NULL, *tmp_tail = NULL;

static void
generate_component_assignments (gfc_code **code, gfc_namespace *ns)
{
  gfc_component *comp1, *comp2;
  gfc_code *this_code = NULL, *head = NULL, *tail = NULL;
  gfc_expr *t1;
  int error_count, depth;

  gfc_get_errors (NULL, &error_count);

  /* Filter out continuing processing after an error.  */
  if (error_count
      || (*code)->expr1->ts.type != BT_DERIVED
      || (*code)->expr2->ts.type != BT_DERIVED)
    return;

  /* TODO: Handle more than one part array reference in assignments.  */
  depth = nonscalar_typebound_assign ((*code)->expr1->ts.u.derived,
				      (*code)->expr1->rank ? 1 : 0);
  if (depth > 1)
    {
      gfc_warning (0, "TODO: type-bound defined assignment(s) at %L not "
		   "done because multiple part array references would "
		   "occur in intermediate expressions.", &(*code)->loc);
      return;
    }

  component_assignment_level++;

  /* Create a temporary so that functions get called only once.  */
  if ((*code)->expr2->expr_type != EXPR_VARIABLE
      && (*code)->expr2->expr_type != EXPR_CONSTANT)
    {
      gfc_expr *tmp_expr;

      /* Assign the rhs to the temporary.  */
      tmp_expr = get_temp_from_expr ((*code)->expr1, ns);
      this_code = build_assignment (EXEC_ASSIGN,
				    tmp_expr, (*code)->expr2,
				    NULL, NULL, (*code)->loc);
      /* Add the code and substitute the rhs expression.  */
      add_code_to_chain (&this_code, &tmp_head, &tmp_tail);
      gfc_free_expr ((*code)->expr2);
      (*code)->expr2 = tmp_expr;
    }

  /* Do the intrinsic assignment.  This is not needed if the lhs is one
     of the temporaries generated here, since the intrinsic assignment
     to the final result already does this.  */
  if ((*code)->expr1->symtree->n.sym->name[2] != '@')
    {
      this_code = build_assignment (EXEC_ASSIGN,
				    (*code)->expr1, (*code)->expr2,
				    NULL, NULL, (*code)->loc);
      add_code_to_chain (&this_code, &head, &tail);
    }

  comp1 = (*code)->expr1->ts.u.derived->components;
  comp2 = (*code)->expr2->ts.u.derived->components;

  t1 = NULL;
  for (; comp1; comp1 = comp1->next, comp2 = comp2->next)
    {
      bool inout = false;

      /* The intrinsic assignment does the right thing for pointers
	 of all kinds and allocatable components.  */
      if (!gfc_bt_struct (comp1->ts.type)
	  || comp1->attr.pointer
	  || comp1->attr.allocatable
	  || comp1->attr.proc_pointer_comp
	  || comp1->attr.class_pointer
	  || comp1->attr.proc_pointer)
	continue;

      /* Make an assigment for this component.  */
      this_code = build_assignment (EXEC_ASSIGN,
				    (*code)->expr1, (*code)->expr2,
				    comp1, comp2, (*code)->loc);

      /* Convert the assignment if there is a defined assignment for
	 this type.  Otherwise, using the call from gfc_resolve_code,
	 recurse into its components.  */
      gfc_resolve_code (this_code, ns);

      if (this_code->op == EXEC_ASSIGN_CALL)
	{
	  gfc_formal_arglist *dummy_args;
	  gfc_symbol *rsym;
	  /* Check that there is a typebound defined assignment.  If not,
	     then this must be a module defined assignment.  We cannot
	     use the defined_assign_comp attribute here because it must
	     be this derived type that has the defined assignment and not
	     a parent type.  */
	  if (!(comp1->ts.u.derived->f2k_derived
		&& comp1->ts.u.derived->f2k_derived
					->tb_op[INTRINSIC_ASSIGN]))
	    {
	      gfc_free_statements (this_code);
	      this_code = NULL;
	      continue;
	    }

	  /* If the first argument of the subroutine has intent INOUT
	     a temporary must be generated and used instead.  */
	  rsym = this_code->resolved_sym;
	  dummy_args = gfc_sym_get_dummy_args (rsym);
	  if (dummy_args
	      && dummy_args->sym->attr.intent == INTENT_INOUT)
	    {
	      gfc_code *temp_code;
	      inout = true;

	      /* Build the temporary required for the assignment and put
		 it at the head of the generated code.  */
	      if (!t1)
		{
		  t1 = get_temp_from_expr ((*code)->expr1, ns);
		  temp_code = build_assignment (EXEC_ASSIGN,
						t1, (*code)->expr1,
				NULL, NULL, (*code)->loc);

		  /* For allocatable LHS, check whether it is allocated.  Note
		     that allocatable components with defined assignment are
		     not yet support.  See PR 57696.  */
		  if ((*code)->expr1->symtree->n.sym->attr.allocatable)
		    {
		      gfc_code *block;
		      gfc_expr *e =
			gfc_lval_expr_from_sym ((*code)->expr1->symtree->n.sym);
		      block = gfc_get_code (EXEC_IF);
		      block->block = gfc_get_code (EXEC_IF);
		      block->block->expr1
			  = gfc_build_intrinsic_call (ns,
				    GFC_ISYM_ALLOCATED, "allocated",
				    (*code)->loc, 1, e);
		      block->block->next = temp_code;
		      temp_code = block;
		    }
		  add_code_to_chain (&temp_code, &tmp_head, &tmp_tail);
		}

	      /* Replace the first actual arg with the component of the
		 temporary.  */
	      gfc_free_expr (this_code->ext.actual->expr);
	      this_code->ext.actual->expr = gfc_copy_expr (t1);
	      add_comp_ref (this_code->ext.actual->expr, comp1);

	      /* If the LHS variable is allocatable and wasn't allocated and
                 the temporary is allocatable, pointer assign the address of
                 the freshly allocated LHS to the temporary.  */
	      if ((*code)->expr1->symtree->n.sym->attr.allocatable
		  && gfc_expr_attr ((*code)->expr1).allocatable)
		{
		  gfc_code *block;
		  gfc_expr *cond;

		  cond = gfc_get_expr ();
		  cond->ts.type = BT_LOGICAL;
		  cond->ts.kind = gfc_default_logical_kind;
		  cond->expr_type = EXPR_OP;
		  cond->where = (*code)->loc;
		  cond->value.op.op = INTRINSIC_NOT;
		  cond->value.op.op1 = gfc_build_intrinsic_call (ns,
					  GFC_ISYM_ALLOCATED, "allocated",
					  (*code)->loc, 1, gfc_copy_expr (t1));
		  block = gfc_get_code (EXEC_IF);
		  block->block = gfc_get_code (EXEC_IF);
		  block->block->expr1 = cond;
		  block->block->next = build_assignment (EXEC_POINTER_ASSIGN,
					t1, (*code)->expr1,
					NULL, NULL, (*code)->loc);
		  add_code_to_chain (&block, &head, &tail);
		}
	    }
	}
      else if (this_code->op == EXEC_ASSIGN && !this_code->next)
	{
	  /* Don't add intrinsic assignments since they are already
	     effected by the intrinsic assignment of the structure.  */
	  gfc_free_statements (this_code);
	  this_code = NULL;
	  continue;
	}

      add_code_to_chain (&this_code, &head, &tail);

      if (t1 && inout)
	{
	  /* Transfer the value to the final result.  */
	  this_code = build_assignment (EXEC_ASSIGN,
					(*code)->expr1, t1,
					comp1, comp2, (*code)->loc);
	  add_code_to_chain (&this_code, &head, &tail);
	}
    }

  /* Put the temporary assignments at the top of the generated code.  */
  if (tmp_head && component_assignment_level == 1)
    {
      gfc_append_code (tmp_head, head);
      head = tmp_head;
      tmp_head = tmp_tail = NULL;
    }

  // If we did a pointer assignment - thus, we need to ensure that the LHS is
  // not accidentally deallocated. Hence, nullify t1.
  if (t1 && (*code)->expr1->symtree->n.sym->attr.allocatable
      && gfc_expr_attr ((*code)->expr1).allocatable)
    {
      gfc_code *block;
      gfc_expr *cond;
      gfc_expr *e;

      e = gfc_lval_expr_from_sym ((*code)->expr1->symtree->n.sym);
      cond = gfc_build_intrinsic_call (ns, GFC_ISYM_ASSOCIATED, "associated",
				       (*code)->loc, 2, gfc_copy_expr (t1), e);
      block = gfc_get_code (EXEC_IF);
      block->block = gfc_get_code (EXEC_IF);
      block->block->expr1 = cond;
      block->block->next = build_assignment (EXEC_POINTER_ASSIGN,
					t1, gfc_get_null_expr (&(*code)->loc),
					NULL, NULL, (*code)->loc);
      gfc_append_code (tail, block);
      tail = block;
    }

  /* Now attach the remaining code chain to the input code.  Step on
     to the end of the new code since resolution is complete.  */
  gcc_assert ((*code)->op == EXEC_ASSIGN);
  tail->next = (*code)->next;
  /* Overwrite 'code' because this would place the intrinsic assignment
     before the temporary for the lhs is created.  */
  gfc_free_expr ((*code)->expr1);
  gfc_free_expr ((*code)->expr2);
  **code = *head;
  if (head != tail)
    free (head);
  *code = tail;

  component_assignment_level--;
}


/* F2008: Pointer function assignments are of the form:
	ptr_fcn (args) = expr
   This function breaks these assignments into two statements:
	temporary_pointer => ptr_fcn(args)
	temporary_pointer = expr  */

static bool
resolve_ptr_fcn_assign (gfc_code **code, gfc_namespace *ns)
{
  gfc_expr *tmp_ptr_expr;
  gfc_code *this_code;
  gfc_component *comp;
  gfc_symbol *s;

  if ((*code)->expr1->expr_type != EXPR_FUNCTION)
    return false;

  /* Even if standard does not support this feature, continue to build
     the two statements to avoid upsetting frontend_passes.c.  */
  gfc_notify_std (GFC_STD_F2008, "Pointer procedure assignment at "
		  "%L", &(*code)->loc);

  comp = gfc_get_proc_ptr_comp ((*code)->expr1);

  if (comp)
    s = comp->ts.interface;
  else
    s = (*code)->expr1->symtree->n.sym;

  if (s == NULL || !s->result->attr.pointer)
    {
      gfc_error ("The function result on the lhs of the assignment at "
		 "%L must have the pointer attribute.",
		 &(*code)->expr1->where);
      (*code)->op = EXEC_NOP;
      return false;
    }

  tmp_ptr_expr = get_temp_from_expr ((*code)->expr1, ns);

  /* get_temp_from_expression is set up for ordinary assignments. To that
     end, where array bounds are not known, arrays are made allocatable.
     Change the temporary to a pointer here.  */
  tmp_ptr_expr->symtree->n.sym->attr.pointer = 1;
  tmp_ptr_expr->symtree->n.sym->attr.allocatable = 0;
  tmp_ptr_expr->where = (*code)->loc;

  this_code = build_assignment (EXEC_ASSIGN,
				tmp_ptr_expr, (*code)->expr2,
				NULL, NULL, (*code)->loc);
  this_code->next = (*code)->next;
  (*code)->next = this_code;
  (*code)->op = EXEC_POINTER_ASSIGN;
  (*code)->expr2 = (*code)->expr1;
  (*code)->expr1 = tmp_ptr_expr;

  return true;
}


/* Deferred character length assignments from an operator expression
   require a temporary because the character length of the lhs can
   change in the course of the assignment.  */

static bool
deferred_op_assign (gfc_code **code, gfc_namespace *ns)
{
  gfc_expr *tmp_expr;
  gfc_code *this_code;

  if (!((*code)->expr1->ts.type == BT_CHARACTER
	 && (*code)->expr1->ts.deferred && (*code)->expr1->rank
	 && (*code)->expr2->expr_type == EXPR_OP))
    return false;

  if (!gfc_check_dependency ((*code)->expr1, (*code)->expr2, 1))
    return false;

  if (gfc_expr_attr ((*code)->expr1).pointer)
    return false;

  tmp_expr = get_temp_from_expr ((*code)->expr1, ns);
  tmp_expr->where = (*code)->loc;

  /* A new charlen is required to ensure that the variable string
     length is different to that of the original lhs.  */
  tmp_expr->ts.u.cl = gfc_get_charlen();
  tmp_expr->symtree->n.sym->ts.u.cl = tmp_expr->ts.u.cl;
  tmp_expr->ts.u.cl->next = (*code)->expr2->ts.u.cl->next;
  (*code)->expr2->ts.u.cl->next = tmp_expr->ts.u.cl;

  tmp_expr->symtree->n.sym->ts.deferred = 1;

  this_code = build_assignment (EXEC_ASSIGN,
				(*code)->expr1,
				gfc_copy_expr (tmp_expr),
				NULL, NULL, (*code)->loc);

  (*code)->expr1 = tmp_expr;

  this_code->next = (*code)->next;
  (*code)->next = this_code;

  return true;
}


/* Given a block of code, recursively resolve everything pointed to by this
   code block.  */

void
gfc_resolve_code (gfc_code *code, gfc_namespace *ns)
{
  int omp_workshare_save;
  int forall_save, do_concurrent_save;
  code_stack frame;
  bool t;

  frame.prev = cs_base;
  frame.head = code;
  cs_base = &frame;

  find_reachable_labels (code);

  for (; code; code = code->next)
    {
      frame.current = code;
      forall_save = forall_flag;
      do_concurrent_save = gfc_do_concurrent_flag;

      if (code->op == EXEC_FORALL)
	{
	  forall_flag = 1;
	  gfc_resolve_forall (code, ns, forall_save);
	  forall_flag = 2;
	}
      else if (code->block)
	{
	  omp_workshare_save = -1;
	  switch (code->op)
	    {
	    case EXEC_OACC_PARALLEL_LOOP:
	    case EXEC_OACC_PARALLEL:
	    case EXEC_OACC_KERNELS_LOOP:
	    case EXEC_OACC_KERNELS:
	    case EXEC_OACC_SERIAL_LOOP:
	    case EXEC_OACC_SERIAL:
	    case EXEC_OACC_DATA:
	    case EXEC_OACC_HOST_DATA:
	    case EXEC_OACC_LOOP:
	      gfc_resolve_oacc_blocks (code, ns);
	      break;
	    case EXEC_OMP_PARALLEL_WORKSHARE:
	      omp_workshare_save = omp_workshare_flag;
	      omp_workshare_flag = 1;
	      gfc_resolve_omp_parallel_blocks (code, ns);
	      break;
	    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
	    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
	    case EXEC_OMP_PARALLEL:
	    case EXEC_OMP_PARALLEL_DO:
	    case EXEC_OMP_PARALLEL_DO_SIMD:
	    case EXEC_OMP_PARALLEL_MASKED:
	    case EXEC_OMP_PARALLEL_MASKED_TASKLOOP:
	    case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
	    case EXEC_OMP_PARALLEL_MASTER:
	    case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
	    case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
	    case EXEC_OMP_PARALLEL_SECTIONS:
	    case EXEC_OMP_TARGET_PARALLEL:
	    case EXEC_OMP_TARGET_PARALLEL_DO:
	    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
	    case EXEC_OMP_TARGET_TEAMS:
	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
	    case EXEC_OMP_TASK:
	    case EXEC_OMP_TASKLOOP:
	    case EXEC_OMP_TASKLOOP_SIMD:
	    case EXEC_OMP_TEAMS:
	    case EXEC_OMP_TEAMS_DISTRIBUTE:
	    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
	    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
	    case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
	      omp_workshare_save = omp_workshare_flag;
	      omp_workshare_flag = 0;
	      gfc_resolve_omp_parallel_blocks (code, ns);
	      break;
	    case EXEC_OMP_DISTRIBUTE:
	    case EXEC_OMP_DISTRIBUTE_SIMD:
	    case EXEC_OMP_DO:
	    case EXEC_OMP_DO_SIMD:
	    case EXEC_OMP_SIMD:
	    case EXEC_OMP_TARGET_SIMD:
	      gfc_resolve_omp_do_blocks (code, ns);
	      break;
	    case EXEC_SELECT_TYPE:
	    case EXEC_SELECT_RANK:
	      /* Blocks are handled in resolve_select_type/rank because we
		 have to transform the SELECT TYPE into ASSOCIATE first.  */
	      break;
            case EXEC_DO_CONCURRENT:
	      gfc_do_concurrent_flag = 1;
	      gfc_resolve_blocks (code->block, ns);
	      gfc_do_concurrent_flag = 2;
	      break;
	    case EXEC_OMP_WORKSHARE:
	      omp_workshare_save = omp_workshare_flag;
	      omp_workshare_flag = 1;
	      /* FALL THROUGH */
	    default:
	      gfc_resolve_blocks (code->block, ns);
	      break;
	    }

	  if (omp_workshare_save != -1)
	    omp_workshare_flag = omp_workshare_save;
	}
start:
      t = true;
      if (code->op != EXEC_COMPCALL && code->op != EXEC_CALL_PPC)
	t = gfc_resolve_expr (code->expr1);
      forall_flag = forall_save;
      gfc_do_concurrent_flag = do_concurrent_save;

      if (!gfc_resolve_expr (code->expr2))
	t = false;

      if (code->op == EXEC_ALLOCATE
	  && !gfc_resolve_expr (code->expr3))
	t = false;

      switch (code->op)
	{
	case EXEC_NOP:
	case EXEC_END_BLOCK:
	case EXEC_END_NESTED_BLOCK:
	case EXEC_CYCLE:
	case EXEC_PAUSE:
	case EXEC_STOP:
	case EXEC_ERROR_STOP:
	case EXEC_EXIT:
	case EXEC_CONTINUE:
	case EXEC_DT_END:
	case EXEC_ASSIGN_CALL:
	  break;

	case EXEC_CRITICAL:
	  resolve_critical (code);
	  break;

	case EXEC_SYNC_ALL:
	case EXEC_SYNC_IMAGES:
	case EXEC_SYNC_MEMORY:
	  resolve_sync (code);
	  break;

	case EXEC_LOCK:
	case EXEC_UNLOCK:
	case EXEC_EVENT_POST:
	case EXEC_EVENT_WAIT:
	  resolve_lock_unlock_event (code);
	  break;

	case EXEC_FAIL_IMAGE:
	case EXEC_FORM_TEAM:
	case EXEC_CHANGE_TEAM:
	case EXEC_END_TEAM:
	case EXEC_SYNC_TEAM:
	  break;

	case EXEC_ENTRY:
	  /* Keep track of which entry we are up to.  */
	  current_entry_id = code->ext.entry->id;
	  break;

	case EXEC_WHERE:
	  resolve_where (code, NULL);
	  break;

	case EXEC_GOTO:
	  if (code->expr1 != NULL)
	    {
	      if (code->expr1->expr_type != EXPR_VARIABLE
		  || code->expr1->ts.type != BT_INTEGER
		  || (code->expr1->ref
		      && code->expr1->ref->type == REF_ARRAY)
		  || code->expr1->symtree == NULL
		  || (code->expr1->symtree->n.sym
		      && (code->expr1->symtree->n.sym->attr.flavor
			  == FL_PARAMETER)))
		gfc_error ("ASSIGNED GOTO statement at %L requires a "
			   "scalar INTEGER variable", &code->expr1->where);
	      else if (code->expr1->symtree->n.sym
		       && code->expr1->symtree->n.sym->attr.assign != 1)
		gfc_error ("Variable %qs has not been assigned a target "
			   "label at %L", code->expr1->symtree->n.sym->name,
			   &code->expr1->where);
	    }
	  else
	    resolve_branch (code->label1, code);
	  break;

	case EXEC_RETURN:
	  if (code->expr1 != NULL
		&& (code->expr1->ts.type != BT_INTEGER || code->expr1->rank))
	    gfc_error ("Alternate RETURN statement at %L requires a SCALAR-"
		       "INTEGER return specifier", &code->expr1->where);
	  break;

	case EXEC_INIT_ASSIGN:
	case EXEC_END_PROCEDURE:
	  break;

	case EXEC_ASSIGN:
	  if (!t)
	    break;

	  if (code->expr1->ts.type == BT_CLASS)
	   gfc_find_vtab (&code->expr2->ts);

	  /* Remove a GFC_ISYM_CAF_GET inserted for a coindexed variable on
	     the LHS.  */
	  if (code->expr1->expr_type == EXPR_FUNCTION
	      && code->expr1->value.function.isym
	      && code->expr1->value.function.isym->id == GFC_ISYM_CAF_GET)
	    remove_caf_get_intrinsic (code->expr1);

	  /* If this is a pointer function in an lvalue variable context,
	     the new code will have to be resolved afresh. This is also the
	     case with an error, where the code is transformed into NOP to
	     prevent ICEs downstream.  */
	  if (resolve_ptr_fcn_assign (&code, ns)
	      || code->op == EXEC_NOP)
	    goto start;

	  if (!gfc_check_vardef_context (code->expr1, false, false, false,
					 _("assignment")))
	    break;

	  if (resolve_ordinary_assign (code, ns))
	    {
	      if (omp_workshare_flag)
		{
		  gfc_error ("Expected intrinsic assignment in OMP WORKSHARE "
			     "at %L", &code->loc);
		  break;
		}
	      if (code->op == EXEC_COMPCALL)
		goto compcall;
	      else
		goto call;
	    }

	  /* Check for dependencies in deferred character length array
	     assignments and generate a temporary, if necessary.  */
	  if (code->op == EXEC_ASSIGN && deferred_op_assign (&code, ns))
	    break;

	  /* F03 7.4.1.3 for non-allocatable, non-pointer components.  */
	  if (code->op != EXEC_CALL && code->expr1->ts.type == BT_DERIVED
	      && code->expr1->ts.u.derived
	      && code->expr1->ts.u.derived->attr.defined_assign_comp)
	    generate_component_assignments (&code, ns);

	  break;

	case EXEC_LABEL_ASSIGN:
	  if (code->label1->defined == ST_LABEL_UNKNOWN)
	    gfc_error ("Label %d referenced at %L is never defined",
		       code->label1->value, &code->label1->where);
	  if (t
	      && (code->expr1->expr_type != EXPR_VARIABLE
		  || code->expr1->symtree->n.sym->ts.type != BT_INTEGER
		  || code->expr1->symtree->n.sym->ts.kind
		     != gfc_default_integer_kind
		  || code->expr1->symtree->n.sym->attr.flavor == FL_PARAMETER
		  || code->expr1->symtree->n.sym->as != NULL))
	    gfc_error ("ASSIGN statement at %L requires a scalar "
		       "default INTEGER variable", &code->expr1->where);
	  break;

	case EXEC_POINTER_ASSIGN:
	  {
	    gfc_expr* e;

	    if (!t)
	      break;

	    /* This is both a variable definition and pointer assignment
	       context, so check both of them.  For rank remapping, a final
	       array ref may be present on the LHS and fool gfc_expr_attr
	       used in gfc_check_vardef_context.  Remove it.  */
	    e = remove_last_array_ref (code->expr1);
	    t = gfc_check_vardef_context (e, true, false, false,
					  _("pointer assignment"));
	    if (t)
	      t = gfc_check_vardef_context (e, false, false, false,
					    _("pointer assignment"));
	    gfc_free_expr (e);

	    t = gfc_check_pointer_assign (code->expr1, code->expr2, !t) && t;

	    if (!t)
	      break;

	    /* Assigning a class object always is a regular assign.  */
	    if (code->expr2->ts.type == BT_CLASS
		&& code->expr1->ts.type == BT_CLASS
		&& CLASS_DATA (code->expr2)
		&& !CLASS_DATA (code->expr2)->attr.dimension
		&& !(gfc_expr_attr (code->expr1).proc_pointer
		     && code->expr2->expr_type == EXPR_VARIABLE
		     && code->expr2->symtree->n.sym->attr.flavor
			== FL_PROCEDURE))
	      code->op = EXEC_ASSIGN;
	    break;
	  }

	case EXEC_ARITHMETIC_IF:
	  {
	    gfc_expr *e = code->expr1;

	    gfc_resolve_expr (e);
	    if (e->expr_type == EXPR_NULL)
	      gfc_error ("Invalid NULL at %L", &e->where);

	    if (t && (e->rank > 0
		      || !(e->ts.type == BT_REAL || e->ts.type == BT_INTEGER)))
	      gfc_error ("Arithmetic IF statement at %L requires a scalar "
			 "REAL or INTEGER expression", &e->where);

	    resolve_branch (code->label1, code);
	    resolve_branch (code->label2, code);
	    resolve_branch (code->label3, code);
	  }
	  break;

	case EXEC_IF:
	  if (t && code->expr1 != NULL
	      && (code->expr1->ts.type != BT_LOGICAL
		  || code->expr1->rank != 0))
	    gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
		       &code->expr1->where);
	  break;

	case EXEC_CALL:
	call:
	  resolve_call (code);
	  break;

	case EXEC_COMPCALL:
	compcall:
	  resolve_typebound_subroutine (code);
	  break;

	case EXEC_CALL_PPC:
	  resolve_ppc_call (code);
	  break;

	case EXEC_SELECT:
	  /* Select is complicated. Also, a SELECT construct could be
	     a transformed computed GOTO.  */
	  resolve_select (code, false);
	  break;

	case EXEC_SELECT_TYPE:
	  resolve_select_type (code, ns);
	  break;

	case EXEC_SELECT_RANK:
	  resolve_select_rank (code, ns);
	  break;

	case EXEC_BLOCK:
	  resolve_block_construct (code);
	  break;

	case EXEC_DO:
	  if (code->ext.iterator != NULL)
	    {
	      gfc_iterator *iter = code->ext.iterator;
	      if (gfc_resolve_iterator (iter, true, false))
		gfc_resolve_do_iterator (code, iter->var->symtree->n.sym,
					 true);
	    }
	  break;

	case EXEC_DO_WHILE:
	  if (code->expr1 == NULL)
	    gfc_internal_error ("gfc_resolve_code(): No expression on "
				"DO WHILE");
	  if (t
	      && (code->expr1->rank != 0
		  || code->expr1->ts.type != BT_LOGICAL))
	    gfc_error ("Exit condition of DO WHILE loop at %L must be "
		       "a scalar LOGICAL expression", &code->expr1->where);
	  break;

	case EXEC_ALLOCATE:
	  if (t)
	    resolve_allocate_deallocate (code, "ALLOCATE");

	  break;

	case EXEC_DEALLOCATE:
	  if (t)
	    resolve_allocate_deallocate (code, "DEALLOCATE");

	  break;

	case EXEC_OPEN:
	  if (!gfc_resolve_open (code->ext.open, &code->loc))
	    break;

	  resolve_branch (code->ext.open->err, code);
	  break;

	case EXEC_CLOSE:
	  if (!gfc_resolve_close (code->ext.close, &code->loc))
	    break;

	  resolve_branch (code->ext.close->err, code);
	  break;

	case EXEC_BACKSPACE:
	case EXEC_ENDFILE:
	case EXEC_REWIND:
	case EXEC_FLUSH:
	  if (!gfc_resolve_filepos (code->ext.filepos, &code->loc))
	    break;

	  resolve_branch (code->ext.filepos->err, code);
	  break;

	case EXEC_INQUIRE:
	  if (!gfc_resolve_inquire (code->ext.inquire))
	      break;

	  resolve_branch (code->ext.inquire->err, code);
	  break;

	case EXEC_IOLENGTH:
	  gcc_assert (code->ext.inquire != NULL);
	  if (!gfc_resolve_inquire (code->ext.inquire))
	    break;

	  resolve_branch (code->ext.inquire->err, code);
	  break;

	case EXEC_WAIT:
	  if (!gfc_resolve_wait (code->ext.wait))
	    break;

	  resolve_branch (code->ext.wait->err, code);
	  resolve_branch (code->ext.wait->end, code);
	  resolve_branch (code->ext.wait->eor, code);
	  break;

	case EXEC_READ:
	case EXEC_WRITE:
	  if (!gfc_resolve_dt (code, code->ext.dt, &code->loc))
	    break;

	  resolve_branch (code->ext.dt->err, code);
	  resolve_branch (code->ext.dt->end, code);
	  resolve_branch (code->ext.dt->eor, code);
	  break;

	case EXEC_TRANSFER:
	  resolve_transfer (code);
	  break;

	case EXEC_DO_CONCURRENT:
	case EXEC_FORALL:
	  resolve_forall_iterators (code->ext.forall_iterator);

	  if (code->expr1 != NULL
	      && (code->expr1->ts.type != BT_LOGICAL || code->expr1->rank))
	    gfc_error ("FORALL mask clause at %L requires a scalar LOGICAL "
		       "expression", &code->expr1->where);
	  break;

	case EXEC_OACC_PARALLEL_LOOP:
	case EXEC_OACC_PARALLEL:
	case EXEC_OACC_KERNELS_LOOP:
	case EXEC_OACC_KERNELS:
	case EXEC_OACC_SERIAL_LOOP:
	case EXEC_OACC_SERIAL:
	case EXEC_OACC_DATA:
	case EXEC_OACC_HOST_DATA:
	case EXEC_OACC_LOOP:
	case EXEC_OACC_UPDATE:
	case EXEC_OACC_WAIT:
	case EXEC_OACC_CACHE:
	case EXEC_OACC_ENTER_DATA:
	case EXEC_OACC_EXIT_DATA:
	case EXEC_OACC_ATOMIC:
	case EXEC_OACC_DECLARE:
	  gfc_resolve_oacc_directive (code, ns);
	  break;

	case EXEC_OMP_ATOMIC:
	case EXEC_OMP_BARRIER:
	case EXEC_OMP_CANCEL:
	case EXEC_OMP_CANCELLATION_POINT:
	case EXEC_OMP_CRITICAL:
	case EXEC_OMP_FLUSH:
	case EXEC_OMP_DEPOBJ:
	case EXEC_OMP_DISTRIBUTE:
	case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
	case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
	case EXEC_OMP_DISTRIBUTE_SIMD:
	case EXEC_OMP_DO:
	case EXEC_OMP_DO_SIMD:
	case EXEC_OMP_ERROR:
	case EXEC_OMP_LOOP:
	case EXEC_OMP_MASTER:
	case EXEC_OMP_MASTER_TASKLOOP:
	case EXEC_OMP_MASTER_TASKLOOP_SIMD:
	case EXEC_OMP_MASKED:
	case EXEC_OMP_MASKED_TASKLOOP:
	case EXEC_OMP_MASKED_TASKLOOP_SIMD:
	case EXEC_OMP_ORDERED:
	case EXEC_OMP_SCAN:
	case EXEC_OMP_SCOPE:
	case EXEC_OMP_SECTIONS:
	case EXEC_OMP_SIMD:
	case EXEC_OMP_SINGLE:
	case EXEC_OMP_TARGET:
	case EXEC_OMP_TARGET_DATA:
	case EXEC_OMP_TARGET_ENTER_DATA:
	case EXEC_OMP_TARGET_EXIT_DATA:
	case EXEC_OMP_TARGET_PARALLEL:
	case EXEC_OMP_TARGET_PARALLEL_DO:
	case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
	case EXEC_OMP_TARGET_PARALLEL_LOOP:
	case EXEC_OMP_TARGET_SIMD:
	case EXEC_OMP_TARGET_TEAMS:
	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
	case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
	case EXEC_OMP_TARGET_TEAMS_LOOP:
	case EXEC_OMP_TARGET_UPDATE:
	case EXEC_OMP_TASK:
	case EXEC_OMP_TASKGROUP:
	case EXEC_OMP_TASKLOOP:
	case EXEC_OMP_TASKLOOP_SIMD:
	case EXEC_OMP_TASKWAIT:
	case EXEC_OMP_TASKYIELD:
	case EXEC_OMP_TEAMS:
	case EXEC_OMP_TEAMS_DISTRIBUTE:
	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
	case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
	case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
	case EXEC_OMP_TEAMS_LOOP:
	case EXEC_OMP_WORKSHARE:
	  gfc_resolve_omp_directive (code, ns);
	  break;

	case EXEC_OMP_PARALLEL:
	case EXEC_OMP_PARALLEL_DO:
	case EXEC_OMP_PARALLEL_DO_SIMD:
	case EXEC_OMP_PARALLEL_LOOP:
	case EXEC_OMP_PARALLEL_MASKED:
	case EXEC_OMP_PARALLEL_MASKED_TASKLOOP:
	case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
	case EXEC_OMP_PARALLEL_MASTER:
	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
	case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
	case EXEC_OMP_PARALLEL_SECTIONS:
	case EXEC_OMP_PARALLEL_WORKSHARE:
	  omp_workshare_save = omp_workshare_flag;
	  omp_workshare_flag = 0;
	  gfc_resolve_omp_directive (code, ns);
	  omp_workshare_flag = omp_workshare_save;
	  break;

	default:
	  gfc_internal_error ("gfc_resolve_code(): Bad statement code");
	}
    }

  cs_base = frame.prev;
}


/* Resolve initial values and make sure they are compatible with
   the variable.  */

static void
resolve_values (gfc_symbol *sym)
{
  bool t;

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

  if (sym->attr.ext_attr & (1 << EXT_ATTR_DEPRECATED) && sym->attr.referenced)
    gfc_warning (OPT_Wdeprecated_declarations,
		 "Using parameter %qs declared at %L is deprecated",
		 sym->name, &sym->declared_at);

  if (sym->value->expr_type == EXPR_STRUCTURE)
    t= resolve_structure_cons (sym->value, 1);
  else
    t = gfc_resolve_expr (sym->value);

  if (!t)
    return;

  gfc_check_assign_symbol (sym, NULL, sym->value);
}


/* Verify any BIND(C) derived types in the namespace so we can report errors
   for them once, rather than for each variable declared of that type.  */

static void
resolve_bind_c_derived_types (gfc_symbol *derived_sym)
{
  if (derived_sym != NULL && derived_sym->attr.flavor == FL_DERIVED
      && derived_sym->attr.is_bind_c == 1)
    verify_bind_c_derived_type (derived_sym);

  return;
}


/* Check the interfaces of DTIO procedures associated with derived
   type 'sym'.  These procedures can either have typebound bindings or
   can appear in DTIO generic interfaces.  */

static void
gfc_verify_DTIO_procedures (gfc_symbol *sym)
{
  if (!sym || sym->attr.flavor != FL_DERIVED)
    return;

  gfc_check_dtio_interfaces (sym);

  return;
}

/* Verify that any binding labels used in a given namespace do not collide
   with the names or binding labels of any global symbols.  Multiple INTERFACE
   for the same procedure are permitted.  */

static void
gfc_verify_binding_labels (gfc_symbol *sym)
{
  gfc_gsymbol *gsym;
  const char *module;

  if (!sym || !sym->attr.is_bind_c || sym->attr.is_iso_c
      || sym->attr.flavor == FL_DERIVED || !sym->binding_label)
    return;

  gsym = gfc_find_case_gsymbol (gfc_gsym_root, sym->binding_label);

  if (sym->module)
    module = sym->module;
  else if (sym->ns && sym->ns->proc_name
	   && sym->ns->proc_name->attr.flavor == FL_MODULE)
    module = sym->ns->proc_name->name;
  else if (sym->ns && sym->ns->parent
	   && sym->ns && sym->ns->parent->proc_name
	   && sym->ns->parent->proc_name->attr.flavor == FL_MODULE)
    module = sym->ns->parent->proc_name->name;
  else
    module = NULL;

  if (!gsym
      || (!gsym->defined
	  && (gsym->type == GSYM_FUNCTION || gsym->type == GSYM_SUBROUTINE)))
    {
      if (!gsym)
	gsym = gfc_get_gsymbol (sym->binding_label, true);
      gsym->where = sym->declared_at;
      gsym->sym_name = sym->name;
      gsym->binding_label = sym->binding_label;
      gsym->ns = sym->ns;
      gsym->mod_name = module;
      if (sym->attr.function)
        gsym->type = GSYM_FUNCTION;
      else if (sym->attr.subroutine)
	gsym->type = GSYM_SUBROUTINE;
      /* Mark as variable/procedure as defined, unless its an INTERFACE.  */
      gsym->defined = sym->attr.if_source != IFSRC_IFBODY;
      return;
    }

  if (sym->attr.flavor == FL_VARIABLE && gsym->type != GSYM_UNKNOWN)
    {
      gfc_error ("Variable %qs with binding label %qs at %L uses the same global "
		 "identifier as entity at %L", sym->name,
		 sym->binding_label, &sym->declared_at, &gsym->where);
      /* Clear the binding label to prevent checking multiple times.  */
      sym->binding_label = NULL;
      return;
    }

  if (sym->attr.flavor == FL_VARIABLE && module
      && (strcmp (module, gsym->mod_name) != 0
	  || strcmp (sym->name, gsym->sym_name) != 0))
    {
      /* This can only happen if the variable is defined in a module - if it
	 isn't the same module, reject it.  */
      gfc_error ("Variable %qs from module %qs with binding label %qs at %L "
		 "uses the same global identifier as entity at %L from module %qs",
		 sym->name, module, sym->binding_label,
		 &sym->declared_at, &gsym->where, gsym->mod_name);
      sym->binding_label = NULL;
      return;
    }

  if ((sym->attr.function || sym->attr.subroutine)
      && ((gsym->type != GSYM_SUBROUTINE && gsym->type != GSYM_FUNCTION)
	   || (gsym->defined && sym->attr.if_source != IFSRC_IFBODY))
      && (sym != gsym->ns->proc_name && sym->attr.entry == 0)
      && (module != gsym->mod_name
	  || strcmp (gsym->sym_name, sym->name) != 0
	  || (module && strcmp (module, gsym->mod_name) != 0)))
    {
      /* Print an error if the procedure is defined multiple times; we have to
	 exclude references to the same procedure via module association or
	 multiple checks for the same procedure.  */
      gfc_error ("Procedure %qs with binding label %qs at %L uses the same "
		 "global identifier as entity at %L", sym->name,
		 sym->binding_label, &sym->declared_at, &gsym->where);
      sym->binding_label = NULL;
    }
}


/* Resolve an index expression.  */

static bool
resolve_index_expr (gfc_expr *e)
{
  if (!gfc_resolve_expr (e))
    return false;

  if (!gfc_simplify_expr (e, 0))
    return false;

  if (!gfc_specification_expr (e))
    return false;

  return true;
}


/* Resolve a charlen structure.  */

static bool
resolve_charlen (gfc_charlen *cl)
{
  int k;
  bool saved_specification_expr;

  if (cl->resolved)
    return true;

  cl->resolved = 1;
  saved_specification_expr = specification_expr;
  specification_expr = true;

  if (cl->length_from_typespec)
    {
      if (!gfc_resolve_expr (cl->length))
	{
	  specification_expr = saved_specification_expr;
	  return false;
	}

      if (!gfc_simplify_expr (cl->length, 0))
	{
	  specification_expr = saved_specification_expr;
	  return false;
	}

      /* cl->length has been resolved.  It should have an integer type.  */
      if (cl->length
	  && (cl->length->ts.type != BT_INTEGER || cl->length->rank != 0))
	{
	  gfc_error ("Scalar INTEGER expression expected at %L",
		     &cl->length->where);
	  return false;
	}
    }
  else
    {
      if (!resolve_index_expr (cl->length))
	{
	  specification_expr = saved_specification_expr;
	  return false;
	}
    }

  /* F2008, 4.4.3.2:  If the character length parameter value evaluates to
     a negative value, the length of character entities declared is zero.  */
  if (cl->length && cl->length->expr_type == EXPR_CONSTANT
      && mpz_sgn (cl->length->value.integer) < 0)
    gfc_replace_expr (cl->length,
		      gfc_get_int_expr (gfc_charlen_int_kind, NULL, 0));

  /* Check that the character length is not too large.  */
  k = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
  if (cl->length && cl->length->expr_type == EXPR_CONSTANT
      && cl->length->ts.type == BT_INTEGER
      && mpz_cmp (cl->length->value.integer, gfc_integer_kinds[k].huge) > 0)
    {
      gfc_error ("String length at %L is too large", &cl->length->where);
      specification_expr = saved_specification_expr;
      return false;
    }

  specification_expr = saved_specification_expr;
  return true;
}


/* Test for non-constant shape arrays.  */

static bool
is_non_constant_shape_array (gfc_symbol *sym)
{
  gfc_expr *e;
  int i;
  bool not_constant;

  not_constant = false;
  if (sym->as != NULL)
    {
      /* Unfortunately, !gfc_is_compile_time_shape hits a legal case that
	 has not been simplified; parameter array references.  Do the
	 simplification now.  */
      for (i = 0; i < sym->as->rank + sym->as->corank; i++)
	{
	  if (i == GFC_MAX_DIMENSIONS)
	    break;

	  e = sym->as->lower[i];
	  if (e && (!resolve_index_expr(e)
		    || !gfc_is_constant_expr (e)))
	    not_constant = true;
	  e = sym->as->upper[i];
	  if (e && (!resolve_index_expr(e)
		    || !gfc_is_constant_expr (e)))
	    not_constant = true;
	}
    }
  return not_constant;
}

/* Given a symbol and an initialization expression, add code to initialize
   the symbol to the function entry.  */
static void
build_init_assign (gfc_symbol *sym, gfc_expr *init)
{
  gfc_expr *lval;
  gfc_code *init_st;
  gfc_namespace *ns = sym->ns;

  /* Search for the function namespace if this is a contained
     function without an explicit result.  */
  if (sym->attr.function && sym == sym->result
      && sym->name != sym->ns->proc_name->name)
    {
      ns = ns->contained;
      for (;ns; ns = ns->sibling)
	if (strcmp (ns->proc_name->name, sym->name) == 0)
	  break;
    }

  if (ns == NULL)
    {
      gfc_free_expr (init);
      return;
    }

  /* Build an l-value expression for the result.  */
  lval = gfc_lval_expr_from_sym (sym);

  /* Add the code at scope entry.  */
  init_st = gfc_get_code (EXEC_INIT_ASSIGN);
  init_st->next = ns->code;
  ns->code = init_st;

  /* Assign the default initializer to the l-value.  */
  init_st->loc = sym->declared_at;
  init_st->expr1 = lval;
  init_st->expr2 = init;
}


/* Whether or not we can generate a default initializer for a symbol.  */

static bool
can_generate_init (gfc_symbol *sym)
{
  symbol_attribute *a;
  if (!sym)
    return false;
  a = &sym->attr;

  /* These symbols should never have a default initialization.  */
  return !(
       a->allocatable
    || a->external
    || a->pointer
    || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
        && (CLASS_DATA (sym)->attr.class_pointer
            || CLASS_DATA (sym)->attr.proc_pointer))
    || a->in_equivalence
    || a->in_common
    || a->data
    || sym->module
    || a->cray_pointee
    || a->cray_pointer
    || sym->assoc
    || (!a->referenced && !a->result)
    || (a->dummy && (a->intent != INTENT_OUT
		     || sym->ns->proc_name->attr.if_source == IFSRC_IFBODY))
    || (a->function && sym != sym->result)
  );
}


/* Assign the default initializer to a derived type variable or result.  */

static void
apply_default_init (gfc_symbol *sym)
{
  gfc_expr *init = NULL;

  if (sym->attr.flavor != FL_VARIABLE && !sym->attr.function)
    return;

  if (sym->ts.type == BT_DERIVED && sym->ts.u.derived)
    init = gfc_generate_initializer (&sym->ts, can_generate_init (sym));

  if (init == NULL && sym->ts.type != BT_CLASS)
    return;

  build_init_assign (sym, init);
  sym->attr.referenced = 1;
}


/* Build an initializer for a local. Returns null if the symbol should not have
   a default initialization.  */

static gfc_expr *
build_default_init_expr (gfc_symbol *sym)
{
  /* These symbols should never have a default initialization.  */
  if (sym->attr.allocatable
      || sym->attr.external
      || sym->attr.dummy
      || sym->attr.pointer
      || sym->attr.in_equivalence
      || sym->attr.in_common
      || sym->attr.data
      || sym->module
      || sym->attr.cray_pointee
      || sym->attr.cray_pointer
      || sym->assoc)
    return NULL;

  /* Get the appropriate init expression.  */
  return gfc_build_default_init_expr (&sym->ts, &sym->declared_at);
}

/* Add an initialization expression to a local variable.  */
static void
apply_default_init_local (gfc_symbol *sym)
{
  gfc_expr *init = NULL;

  /* The symbol should be a variable or a function return value.  */
  if ((sym->attr.flavor != FL_VARIABLE && !sym->attr.function)
      || (sym->attr.function && sym->result != sym))
    return;

  /* Try to build the initializer expression.  If we can't initialize
     this symbol, then init will be NULL.  */
  init = build_default_init_expr (sym);
  if (init == NULL)
    return;

  /* For saved variables, we don't want to add an initializer at function
     entry, so we just add a static initializer. Note that automatic variables
     are stack allocated even with -fno-automatic; we have also to exclude
     result variable, which are also nonstatic.  */
  if (!sym->attr.automatic
      && (sym->attr.save || sym->ns->save_all
	  || (flag_max_stack_var_size == 0 && !sym->attr.result
	      && (sym->ns->proc_name && !sym->ns->proc_name->attr.recursive)
	      && (!sym->attr.dimension || !is_non_constant_shape_array (sym)))))
    {
      /* Don't clobber an existing initializer!  */
      gcc_assert (sym->value == NULL);
      sym->value = init;
      return;
    }

  build_init_assign (sym, init);
}


/* Resolution of common features of flavors variable and procedure.  */

static bool
resolve_fl_var_and_proc (gfc_symbol *sym, int mp_flag)
{
  gfc_array_spec *as;

  if (sym->ts.type == BT_CLASS && sym->attr.class_ok
      && sym->ts.u.derived && CLASS_DATA (sym))
    as = CLASS_DATA (sym)->as;
  else
    as = sym->as;

  /* Constraints on deferred shape variable.  */
  if (as == NULL || as->type != AS_DEFERRED)
    {
      bool pointer, allocatable, dimension;

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

      if (allocatable)
	{
	  if (dimension && as->type != AS_ASSUMED_RANK)
	    {
	      gfc_error ("Allocatable array %qs at %L must have a deferred "
			 "shape or assumed rank", sym->name, &sym->declared_at);
	      return false;
	    }
	  else if (!gfc_notify_std (GFC_STD_F2003, "Scalar object "
				    "%qs at %L may not be ALLOCATABLE",
				    sym->name, &sym->declared_at))
	    return false;
	}

      if (pointer && dimension && as->type != AS_ASSUMED_RANK)
	{
	  gfc_error ("Array pointer %qs at %L must have a deferred shape or "
		     "assumed rank", sym->name, &sym->declared_at);
	  sym->error = 1;
	  return false;
	}
    }
  else
    {
      if (!mp_flag && !sym->attr.allocatable && !sym->attr.pointer
	  && sym->ts.type != BT_CLASS && !sym->assoc)
	{
	  gfc_error ("Array %qs at %L cannot have a deferred shape",
		     sym->name, &sym->declared_at);
	  return false;
	 }
    }

  /* Constraints on polymorphic variables.  */
  if (sym->ts.type == BT_CLASS && !(sym->result && sym->result != sym))
    {
      /* F03:C502.  */
      if (sym->attr.class_ok
	  && sym->ts.u.derived
	  && !sym->attr.select_type_temporary
	  && !UNLIMITED_POLY (sym)
	  && !gfc_type_is_extensible (CLASS_DATA (sym)->ts.u.derived))
	{
	  gfc_error ("Type %qs of CLASS variable %qs at %L is not extensible",
		     CLASS_DATA (sym)->ts.u.derived->name, sym->name,
		     &sym->declared_at);
	  return false;
	}

      /* F03:C509.  */
      /* Assume that use associated symbols were checked in the module ns.
	 Class-variables that are associate-names are also something special
	 and excepted from the test.  */
      if (!sym->attr.class_ok && !sym->attr.use_assoc && !sym->assoc)
	{
	  gfc_error ("CLASS variable %qs at %L must be dummy, allocatable "
		     "or pointer", sym->name, &sym->declared_at);
	  return false;
	}
    }

  return true;
}


/* Additional checks for symbols with flavor variable and derived
   type.  To be called from resolve_fl_variable.  */

static bool
resolve_fl_variable_derived (gfc_symbol *sym, int no_init_flag)
{
  gcc_assert (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS);

  /* Check to see if a derived type is blocked from being host
     associated by the presence of another class I symbol in the same
     namespace.  14.6.1.3 of the standard and the discussion on
     comp.lang.fortran.  */
  if (sym->ts.u.derived
      && sym->ns != sym->ts.u.derived->ns
      && !sym->ts.u.derived->attr.use_assoc
      && sym->ns->proc_name->attr.if_source != IFSRC_IFBODY)
    {
      gfc_symbol *s;
      gfc_find_symbol (sym->ts.u.derived->name, sym->ns, 0, &s);
      if (s && s->attr.generic)
	s = gfc_find_dt_in_generic (s);
      if (s && !gfc_fl_struct (s->attr.flavor))
	{
	  gfc_error ("The type %qs cannot be host associated at %L "
		     "because it is blocked by an incompatible object "
		     "of the same name declared at %L",
		     sym->ts.u.derived->name, &sym->declared_at,
		     &s->declared_at);
	  return false;
	}
    }

  /* 4th constraint in section 11.3: "If an object of a type for which
     component-initialization is specified (R429) appears in the
     specification-part of a module and does not have the ALLOCATABLE
     or POINTER attribute, the object shall have the SAVE attribute."

     The check for initializers is performed with
     gfc_has_default_initializer because gfc_default_initializer generates
     a hidden default for allocatable components.  */
  if (!(sym->value || no_init_flag) && sym->ns->proc_name
      && sym->ns->proc_name->attr.flavor == FL_MODULE
      && !(sym->ns->save_all && !sym->attr.automatic) && !sym->attr.save
      && !sym->attr.pointer && !sym->attr.allocatable
      && gfc_has_default_initializer (sym->ts.u.derived)
      && !gfc_notify_std (GFC_STD_F2008, "Implied SAVE for module variable "
			  "%qs at %L, needed due to the default "
			  "initialization", sym->name, &sym->declared_at))
    return false;

  /* Assign default initializer.  */
  if (!(sym->value || sym->attr.pointer || sym->attr.allocatable)
      && (!no_init_flag
	  || (sym->attr.intent == INTENT_OUT
	      && sym->ns->proc_name->attr.if_source != IFSRC_IFBODY)))
    sym->value = gfc_generate_initializer (&sym->ts, can_generate_init (sym));

  return true;
}


/* F2008, C402 (R401):  A colon shall not be used as a type-param-value
   except in the declaration of an entity or component that has the POINTER
   or ALLOCATABLE attribute.  */

static bool
deferred_requirements (gfc_symbol *sym)
{
  if (sym->ts.deferred
      && !(sym->attr.pointer
	   || sym->attr.allocatable
	   || sym->attr.associate_var
	   || sym->attr.omp_udr_artificial_var))
    {
      /* If a function has a result variable, only check the variable.  */
      if (sym->result && sym->name != sym->result->name)
	return true;

      gfc_error ("Entity %qs at %L has a deferred type parameter and "
		 "requires either the POINTER or ALLOCATABLE attribute",
		 sym->name, &sym->declared_at);
      return false;
    }
  return true;
}


/* Resolve symbols with flavor variable.  */

static bool
resolve_fl_variable (gfc_symbol *sym, int mp_flag)
{
  const char *auto_save_msg = "Automatic object %qs at %L cannot have the "
			      "SAVE attribute";

  if (!resolve_fl_var_and_proc (sym, mp_flag))
    return false;

  /* Set this flag to check that variables are parameters of all entries.
     This check is effected by the call to gfc_resolve_expr through
     is_non_constant_shape_array.  */
  bool saved_specification_expr = specification_expr;
  specification_expr = true;

  if (sym->ns->proc_name
      && (sym->ns->proc_name->attr.flavor == FL_MODULE
	  || sym->ns->proc_name->attr.is_main_program)
      && !sym->attr.use_assoc
      && !sym->attr.allocatable
      && !sym->attr.pointer
      && is_non_constant_shape_array (sym))
    {
      /* F08:C541. The shape of an array defined in a main program or module
       * needs to be constant.  */
      gfc_error ("The module or main program array %qs at %L must "
		 "have constant shape", sym->name, &sym->declared_at);
      specification_expr = saved_specification_expr;
      return false;
    }

  /* Constraints on deferred type parameter.  */
  if (!deferred_requirements (sym))
    return false;

  if (sym->ts.type == BT_CHARACTER && !sym->attr.associate_var)
    {
      /* Make sure that character string variables with assumed length are
	 dummy arguments.  */
      gfc_expr *e = NULL;

      if (sym->ts.u.cl)
	e = sym->ts.u.cl->length;
      else
	return false;

      if (e == NULL && !sym->attr.dummy && !sym->attr.result
	  && !sym->ts.deferred && !sym->attr.select_type_temporary
	  && !sym->attr.omp_udr_artificial_var)
	{
	  gfc_error ("Entity with assumed character length at %L must be a "
		     "dummy argument or a PARAMETER", &sym->declared_at);
	  specification_expr = saved_specification_expr;
	  return false;
	}

      if (e && sym->attr.save == SAVE_EXPLICIT && !gfc_is_constant_expr (e))
	{
	  gfc_error (auto_save_msg, sym->name, &sym->declared_at);
	  specification_expr = saved_specification_expr;
	  return false;
	}

      if (!gfc_is_constant_expr (e)
	  && !(e->expr_type == EXPR_VARIABLE
	       && e->symtree->n.sym->attr.flavor == FL_PARAMETER))
	{
	  if (!sym->attr.use_assoc && sym->ns->proc_name
	      && (sym->ns->proc_name->attr.flavor == FL_MODULE
		  || sym->ns->proc_name->attr.is_main_program))
	    {
	      gfc_error ("%qs at %L must have constant character length "
			"in this context", sym->name, &sym->declared_at);
	      specification_expr = saved_specification_expr;
	      return false;
	    }
	  if (sym->attr.in_common)
	    {
	      gfc_error ("COMMON variable %qs at %L must have constant "
			 "character length", sym->name, &sym->declared_at);
	      specification_expr = saved_specification_expr;
	      return false;
	    }
	}
    }

  if (sym->value == NULL && sym->attr.referenced)
    apply_default_init_local (sym); /* Try to apply a default initialization.  */

  /* Determine if the symbol may not have an initializer.  */
  int no_init_flag = 0, automatic_flag = 0;
  if (sym->attr.allocatable || sym->attr.external || sym->attr.dummy
      || sym->attr.intrinsic || sym->attr.result)
    no_init_flag = 1;
  else if ((sym->attr.dimension || sym->attr.codimension) && !sym->attr.pointer
	   && is_non_constant_shape_array (sym))
    {
      no_init_flag = automatic_flag = 1;

      /* Also, they must not have the SAVE attribute.
	 SAVE_IMPLICIT is checked below.  */
      if (sym->as && sym->attr.codimension)
	{
	  int corank = sym->as->corank;
	  sym->as->corank = 0;
	  no_init_flag = automatic_flag = is_non_constant_shape_array (sym);
	  sym->as->corank = corank;
	}
      if (automatic_flag && sym->attr.save == SAVE_EXPLICIT)
	{
	  gfc_error (auto_save_msg, sym->name, &sym->declared_at);
	  specification_expr = saved_specification_expr;
	  return false;
	}
    }

  /* Ensure that any initializer is simplified.  */
  if (sym->value)
    gfc_simplify_expr (sym->value, 1);

  /* Reject illegal initializers.  */
  if (!sym->mark && sym->value)
    {
      if (sym->attr.allocatable || (sym->ts.type == BT_CLASS
				    && CLASS_DATA (sym)->attr.allocatable))
	gfc_error ("Allocatable %qs at %L cannot have an initializer",
		   sym->name, &sym->declared_at);
      else if (sym->attr.external)
	gfc_error ("External %qs at %L cannot have an initializer",
		   sym->name, &sym->declared_at);
      else if (sym->attr.dummy)
	gfc_error ("Dummy %qs at %L cannot have an initializer",
		   sym->name, &sym->declared_at);
      else if (sym->attr.intrinsic)
	gfc_error ("Intrinsic %qs at %L cannot have an initializer",
		   sym->name, &sym->declared_at);
      else if (sym->attr.result)
	gfc_error ("Function result %qs at %L cannot have an initializer",
		   sym->name, &sym->declared_at);
      else if (automatic_flag)
	gfc_error ("Automatic array %qs at %L cannot have an initializer",
		   sym->name, &sym->declared_at);
      else
	goto no_init_error;
      specification_expr = saved_specification_expr;
      return false;
    }

no_init_error:
  if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
    {
      bool res = resolve_fl_variable_derived (sym, no_init_flag);
      specification_expr = saved_specification_expr;
      return res;
    }

  specification_expr = saved_specification_expr;
  return true;
}


/* Compare the dummy characteristics of a module procedure interface
   declaration with the corresponding declaration in a submodule.  */
static gfc_formal_arglist *new_formal;
static char errmsg[200];

static void
compare_fsyms (gfc_symbol *sym)
{
  gfc_symbol *fsym;

  if (sym == NULL || new_formal == NULL)
    return;

  fsym = new_formal->sym;

  if (sym == fsym)
    return;

  if (strcmp (sym->name, fsym->name) == 0)
    {
      if (!gfc_check_dummy_characteristics (fsym, sym, true, errmsg, 200))
	gfc_error ("%s at %L", errmsg, &fsym->declared_at);
    }
}


/* Resolve a procedure.  */

static bool
resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
{
  gfc_formal_arglist *arg;
  bool allocatable_or_pointer;

  if (sym->attr.function
      && !resolve_fl_var_and_proc (sym, mp_flag))
    return false;

  /* Constraints on deferred type parameter.  */
  if (!deferred_requirements (sym))
    return false;

  if (sym->ts.type == BT_CHARACTER)
    {
      gfc_charlen *cl = sym->ts.u.cl;

      if (cl && cl->length && gfc_is_constant_expr (cl->length)
	     && !resolve_charlen (cl))
	return false;

      if ((!cl || !cl->length || cl->length->expr_type != EXPR_CONSTANT)
	  && sym->attr.proc == PROC_ST_FUNCTION)
	{
	  gfc_error ("Character-valued statement function %qs at %L must "
		     "have constant length", sym->name, &sym->declared_at);
	  return false;
	}
    }

  /* Ensure that derived type for are not of a private type.  Internal
     module procedures are excluded by 2.2.3.3 - i.e., they are not
     externally accessible and can access all the objects accessible in
     the host.  */
  if (!(sym->ns->parent && sym->ns->parent->proc_name
	&& sym->ns->parent->proc_name->attr.flavor == FL_MODULE)
      && gfc_check_symbol_access (sym))
    {
      gfc_interface *iface;

      for (arg = gfc_sym_get_dummy_args (sym); arg; arg = arg->next)
	{
	  if (arg->sym
	      && arg->sym->ts.type == BT_DERIVED
	      && arg->sym->ts.u.derived
	      && !arg->sym->ts.u.derived->attr.use_assoc
	      && !gfc_check_symbol_access (arg->sym->ts.u.derived)
	      && !gfc_notify_std (GFC_STD_F2003, "%qs is of a PRIVATE type "
				  "and cannot be a dummy argument"
				  " of %qs, which is PUBLIC at %L",
				  arg->sym->name, sym->name,
				  &sym->declared_at))
	    {
	      /* Stop this message from recurring.  */
	      arg->sym->ts.u.derived->attr.access = ACCESS_PUBLIC;
	      return false;
	    }
	}

      /* PUBLIC interfaces may expose PRIVATE procedures that take types
	 PRIVATE to the containing module.  */
      for (iface = sym->generic; iface; iface = iface->next)
	{
	  for (arg = gfc_sym_get_dummy_args (iface->sym); arg; arg = arg->next)
	    {
	      if (arg->sym
		  && arg->sym->ts.type == BT_DERIVED
		  && !arg->sym->ts.u.derived->attr.use_assoc
		  && !gfc_check_symbol_access (arg->sym->ts.u.derived)
		  && !gfc_notify_std (GFC_STD_F2003, "Procedure %qs in "
				      "PUBLIC interface %qs at %L "
				      "takes dummy arguments of %qs which "
				      "is PRIVATE", iface->sym->name,
				      sym->name, &iface->sym->declared_at,
				      gfc_typename(&arg->sym->ts)))
		{
		  /* Stop this message from recurring.  */
		  arg->sym->ts.u.derived->attr.access = ACCESS_PUBLIC;
		  return false;
		}
	     }
	}
    }

  if (sym->attr.function && sym->value && sym->attr.proc != PROC_ST_FUNCTION
      && !sym->attr.proc_pointer)
    {
      gfc_error ("Function %qs at %L cannot have an initializer",
		 sym->name, &sym->declared_at);

      /* Make sure no second error is issued for this.  */
      sym->value->error = 1;
      return false;
    }

  /* An external symbol may not have an initializer because it is taken to be
     a procedure. Exception: Procedure Pointers.  */
  if (sym->attr.external && sym->value && !sym->attr.proc_pointer)
    {
      gfc_error ("External object %qs at %L may not have an initializer",
		 sym->name, &sym->declared_at);
      return false;
    }

  /* An elemental function is required to return a scalar 12.7.1  */
  if (sym->attr.elemental && sym->attr.function
      && (sym->as || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as)))
    {
      gfc_error ("ELEMENTAL function %qs at %L must have a scalar "
		 "result", sym->name, &sym->declared_at);
      /* Reset so that the error only occurs once.  */
      sym->attr.elemental = 0;
      return false;
    }

  if (sym->attr.proc == PROC_ST_FUNCTION
      && (sym->attr.allocatable || sym->attr.pointer))
    {
      gfc_error ("Statement function %qs at %L may not have pointer or "
		 "allocatable attribute", sym->name, &sym->declared_at);
      return false;
    }

  /* 5.1.1.5 of the Standard: A function name declared with an asterisk
     char-len-param shall not be array-valued, pointer-valued, recursive
     or pure.  ....snip... A character value of * may only be used in the
     following ways: (i) Dummy arg of procedure - dummy associates with
     actual length; (ii) To declare a named constant; or (iii) External
     function - but length must be declared in calling scoping unit.  */
  if (sym->attr.function
      && sym->ts.type == BT_CHARACTER && !sym->ts.deferred
      && sym->ts.u.cl && sym->ts.u.cl->length == NULL)
    {
      if ((sym->as && sym->as->rank) || (sym->attr.pointer)
	  || (sym->attr.recursive) || (sym->attr.pure))
	{
	  if (sym->as && sym->as->rank)
	    gfc_error ("CHARACTER(*) function %qs at %L cannot be "
		       "array-valued", sym->name, &sym->declared_at);

	  if (sym->attr.pointer)
	    gfc_error ("CHARACTER(*) function %qs at %L cannot be "
		       "pointer-valued", sym->name, &sym->declared_at);

	  if (sym->attr.pure)
	    gfc_error ("CHARACTER(*) function %qs at %L cannot be "
		       "pure", sym->name, &sym->declared_at);

	  if (sym->attr.recursive)
	    gfc_error ("CHARACTER(*) function %qs at %L cannot be "
		       "recursive", sym->name, &sym->declared_at);

	  return false;
	}

      /* Appendix B.2 of the standard.  Contained functions give an
	 error anyway.  Deferred character length is an F2003 feature.
	 Don't warn on intrinsic conversion functions, which start
	 with two underscores.  */
      if (!sym->attr.contained && !sym->ts.deferred
	  && (sym->name[0] != '_' || sym->name[1] != '_'))
	gfc_notify_std (GFC_STD_F95_OBS,
			"CHARACTER(*) function %qs at %L",
			sym->name, &sym->declared_at);
    }

  /* F2008, C1218.  */
  if (sym->attr.elemental)
    {
      if (sym->attr.proc_pointer)
	{
	  const char* name = (sym->attr.result ? sym->ns->proc_name->name
					       : sym->name);
	  gfc_error ("Procedure pointer %qs at %L shall not be elemental",
		     name, &sym->declared_at);
	  return false;
	}
      if (sym->attr.dummy)
	{
	  gfc_error ("Dummy procedure %qs at %L shall not be elemental",
		     sym->name, &sym->declared_at);
	  return false;
	}
    }

  /* F2018, C15100: "The result of an elemental function shall be scalar,
     and shall not have the POINTER or ALLOCATABLE attribute."  The scalar
     pointer is tested and caught elsewhere.  */
  if (sym->result)
    allocatable_or_pointer = sym->result->ts.type == BT_CLASS
			     && CLASS_DATA (sym->result) ?
			     (CLASS_DATA (sym->result)->attr.allocatable
			      || CLASS_DATA (sym->result)->attr.pointer) :
			     (sym->result->attr.allocatable
			      || sym->result->attr.pointer);

  if (sym->attr.elemental && sym->result
      && allocatable_or_pointer)
    {
      gfc_error ("Function result variable %qs at %L of elemental "
		 "function %qs shall not have an ALLOCATABLE or POINTER "
		 "attribute", sym->result->name,
		 &sym->result->declared_at, sym->name);
      return false;
    }

  if (sym->attr.is_bind_c && sym->attr.is_c_interop != 1)
    {
      gfc_formal_arglist *curr_arg;
      int has_non_interop_arg = 0;

      if (!verify_bind_c_sym (sym, &(sym->ts), sym->attr.in_common,
			      sym->common_block))
        {
          /* Clear these to prevent looking at them again if there was an
             error.  */
          sym->attr.is_bind_c = 0;
          sym->attr.is_c_interop = 0;
          sym->ts.is_c_interop = 0;
        }
      else
        {
          /* So far, no errors have been found.  */
          sym->attr.is_c_interop = 1;
          sym->ts.is_c_interop = 1;
        }

      curr_arg = gfc_sym_get_dummy_args (sym);
      while (curr_arg != NULL)
        {
          /* Skip implicitly typed dummy args here.  */
	  if (curr_arg->sym && curr_arg->sym->attr.implicit_type == 0)
	    if (!gfc_verify_c_interop_param (curr_arg->sym))
	      /* If something is found to fail, record the fact so we
		 can mark the symbol for the procedure as not being
		 BIND(C) to try and prevent multiple errors being
		 reported.  */
	      has_non_interop_arg = 1;

          curr_arg = curr_arg->next;
        }

      /* See if any of the arguments were not interoperable and if so, clear
	 the procedure symbol to prevent duplicate error messages.  */
      if (has_non_interop_arg != 0)
	{
	  sym->attr.is_c_interop = 0;
	  sym->ts.is_c_interop = 0;
	  sym->attr.is_bind_c = 0;
	}
    }

  if (!sym->attr.proc_pointer)
    {
      if (sym->attr.save == SAVE_EXPLICIT)
	{
	  gfc_error ("PROCEDURE attribute conflicts with SAVE attribute "
		     "in %qs at %L", sym->name, &sym->declared_at);
	  return false;
	}
      if (sym->attr.intent)
	{
	  gfc_error ("PROCEDURE attribute conflicts with INTENT attribute "
		     "in %qs at %L", sym->name, &sym->declared_at);
	  return false;
	}
      if (sym->attr.subroutine && sym->attr.result)
	{
	  gfc_error ("PROCEDURE attribute conflicts with RESULT attribute "
		     "in %qs at %L", sym->ns->proc_name->name, &sym->declared_at);
	  return false;
	}
      if (sym->attr.external && sym->attr.function && !sym->attr.module_procedure
	  && ((sym->attr.if_source == IFSRC_DECL && !sym->attr.procedure)
	      || sym->attr.contained))
	{
	  gfc_error ("EXTERNAL attribute conflicts with FUNCTION attribute "
		     "in %qs at %L", sym->name, &sym->declared_at);
	  return false;
	}
      if (strcmp ("ppr@", sym->name) == 0)
	{
	  gfc_error ("Procedure pointer result %qs at %L "
		     "is missing the pointer attribute",
		     sym->ns->proc_name->name, &sym->declared_at);
	  return false;
	}
    }

  /* Assume that a procedure whose body is not known has references
     to external arrays.  */
  if (sym->attr.if_source != IFSRC_DECL)
    sym->attr.array_outer_dependency = 1;

  /* Compare the characteristics of a module procedure with the
     interface declaration. Ideally this would be done with
     gfc_compare_interfaces but, at present, the formal interface
     cannot be copied to the ts.interface.  */
  if (sym->attr.module_procedure
      && sym->attr.if_source == IFSRC_DECL)
    {
      gfc_symbol *iface;
      char name[2*GFC_MAX_SYMBOL_LEN + 1];
      char *module_name;
      char *submodule_name;
      strcpy (name, sym->ns->proc_name->name);
      module_name = strtok (name, ".");
      submodule_name = strtok (NULL, ".");

      iface = sym->tlink;
      sym->tlink = NULL;

      /* Make sure that the result uses the correct charlen for deferred
	 length results.  */
      if (iface && sym->result
	  && iface->ts.type == BT_CHARACTER
	  && iface->ts.deferred)
	sym->result->ts.u.cl = iface->ts.u.cl;

      if (iface == NULL)
	goto check_formal;

      /* Check the procedure characteristics.  */
      if (sym->attr.elemental != iface->attr.elemental)
	{
	  gfc_error ("Mismatch in ELEMENTAL attribute between MODULE "
		     "PROCEDURE at %L and its interface in %s",
		     &sym->declared_at, module_name);
	  return false;
	}

      if (sym->attr.pure != iface->attr.pure)
	{
	  gfc_error ("Mismatch in PURE attribute between MODULE "
		     "PROCEDURE at %L and its interface in %s",
		     &sym->declared_at, module_name);
	  return false;
	}

      if (sym->attr.recursive != iface->attr.recursive)
	{
	  gfc_error ("Mismatch in RECURSIVE attribute between MODULE "
		     "PROCEDURE at %L and its interface in %s",
		     &sym->declared_at, module_name);
	  return false;
	}

      /* Check the result characteristics.  */
      if (!gfc_check_result_characteristics (sym, iface, errmsg, 200))
	{
	  gfc_error ("%s between the MODULE PROCEDURE declaration "
		     "in MODULE %qs and the declaration at %L in "
		     "(SUB)MODULE %qs",
		     errmsg, module_name, &sym->declared_at,
		     submodule_name ? submodule_name : module_name);
	  return false;
	}

check_formal:
      /* Check the characteristics of the formal arguments.  */
      if (sym->formal && sym->formal_ns)
	{
	  for (arg = sym->formal; arg && arg->sym; arg = arg->next)
	    {
	      new_formal = arg;
	      gfc_traverse_ns (sym->formal_ns, compare_fsyms);
	    }
	}
    }
  return true;
}


/* Resolve a list of finalizer procedures.  That is, after they have hopefully
   been defined and we now know their defined arguments, check that they fulfill
   the requirements of the standard for procedures used as finalizers.  */

static bool
gfc_resolve_finalizers (gfc_symbol* derived, bool *finalizable)
{
  gfc_finalizer* list;
  gfc_finalizer** prev_link; /* For removing wrong entries from the list.  */
  bool result = true;
  bool seen_scalar = false;
  gfc_symbol *vtab;
  gfc_component *c;
  gfc_symbol *parent = gfc_get_derived_super_type (derived);

  if (parent)
    gfc_resolve_finalizers (parent, finalizable);

  /* Ensure that derived-type components have a their finalizers resolved.  */
  bool has_final = derived->f2k_derived && derived->f2k_derived->finalizers;
  for (c = derived->components; c; c = c->next)
    if (c->ts.type == BT_DERIVED
	&& !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable)
      {
	bool has_final2 = false;
	if (!gfc_resolve_finalizers (c->ts.u.derived, &has_final2))
	  return false;  /* Error.  */
	has_final = has_final || has_final2;
      }
  /* Return early if not finalizable.  */
  if (!has_final)
    {
      if (finalizable)
	*finalizable = false;
      return true;
    }

  /* Walk over the list of finalizer-procedures, check them, and if any one
     does not fit in with the standard's definition, print an error and remove
     it from the list.  */
  prev_link = &derived->f2k_derived->finalizers;
  for (list = derived->f2k_derived->finalizers; list; list = *prev_link)
    {
      gfc_formal_arglist *dummy_args;
      gfc_symbol* arg;
      gfc_finalizer* i;
      int my_rank;

      /* Skip this finalizer if we already resolved it.  */
      if (list->proc_tree)
	{
	  if (list->proc_tree->n.sym->formal->sym->as == NULL
	      || list->proc_tree->n.sym->formal->sym->as->rank == 0)
	    seen_scalar = true;
	  prev_link = &(list->next);
	  continue;
	}

      /* Check this exists and is a SUBROUTINE.  */
      if (!list->proc_sym->attr.subroutine)
	{
	  gfc_error ("FINAL procedure %qs at %L is not a SUBROUTINE",
		     list->proc_sym->name, &list->where);
	  goto error;
	}

      /* We should have exactly one argument.  */
      dummy_args = gfc_sym_get_dummy_args (list->proc_sym);
      if (!dummy_args || dummy_args->next)
	{
	  gfc_error ("FINAL procedure at %L must have exactly one argument",
		     &list->where);
	  goto error;
	}
      arg = dummy_args->sym;

      /* This argument must be of our type.  */
      if (arg->ts.type != BT_DERIVED || arg->ts.u.derived != derived)
	{
	  gfc_error ("Argument of FINAL procedure at %L must be of type %qs",
		     &arg->declared_at, derived->name);
	  goto error;
	}

      /* It must neither be a pointer nor allocatable nor optional.  */
      if (arg->attr.pointer)
	{
	  gfc_error ("Argument of FINAL procedure at %L must not be a POINTER",
		     &arg->declared_at);
	  goto error;
	}
      if (arg->attr.allocatable)
	{
	  gfc_error ("Argument of FINAL procedure at %L must not be"
		     " ALLOCATABLE", &arg->declared_at);
	  goto error;
	}
      if (arg->attr.optional)
	{
	  gfc_error ("Argument of FINAL procedure at %L must not be OPTIONAL",
		     &arg->declared_at);
	  goto error;
	}

      /* It must not be INTENT(OUT).  */
      if (arg->attr.intent == INTENT_OUT)
	{
	  gfc_error ("Argument of FINAL procedure at %L must not be"
		     " INTENT(OUT)", &arg->declared_at);
	  goto error;
	}

      /* Warn if the procedure is non-scalar and not assumed shape.  */
      if (warn_surprising && arg->as && arg->as->rank != 0
	  && arg->as->type != AS_ASSUMED_SHAPE)
	gfc_warning (OPT_Wsurprising,
		     "Non-scalar FINAL procedure at %L should have assumed"
		     " shape argument", &arg->declared_at);

      /* Check that it does not match in kind and rank with a FINAL procedure
	 defined earlier.  To really loop over the *earlier* declarations,
	 we need to walk the tail of the list as new ones were pushed at the
	 front.  */
      /* TODO: Handle kind parameters once they are implemented.  */
      my_rank = (arg->as ? arg->as->rank : 0);
      for (i = list->next; i; i = i->next)
	{
	  gfc_formal_arglist *dummy_args;

	  /* Argument list might be empty; that is an error signalled earlier,
	     but we nevertheless continued resolving.  */
	  dummy_args = gfc_sym_get_dummy_args (i->proc_sym);
	  if (dummy_args)
	    {
	      gfc_symbol* i_arg = dummy_args->sym;
	      const int i_rank = (i_arg->as ? i_arg->as->rank : 0);
	      if (i_rank == my_rank)
		{
		  gfc_error ("FINAL procedure %qs declared at %L has the same"
			     " rank (%d) as %qs",
			     list->proc_sym->name, &list->where, my_rank,
			     i->proc_sym->name);
		  goto error;
		}
	    }
	}

	/* Is this the/a scalar finalizer procedure?  */
	if (my_rank == 0)
	  seen_scalar = true;

	/* Find the symtree for this procedure.  */
	gcc_assert (!list->proc_tree);
	list->proc_tree = gfc_find_sym_in_symtree (list->proc_sym);

	prev_link = &list->next;
	continue;

	/* Remove wrong nodes immediately from the list so we don't risk any
	   troubles in the future when they might fail later expectations.  */
error:
	i = list;
	*prev_link = list->next;
	gfc_free_finalizer (i);
	result = false;
    }

  if (result == false)
    return false;

  /* Warn if we haven't seen a scalar finalizer procedure (but we know there
     were nodes in the list, must have been for arrays.  It is surely a good
     idea to have a scalar version there if there's something to finalize.  */
  if (warn_surprising && derived->f2k_derived->finalizers && !seen_scalar)
    gfc_warning (OPT_Wsurprising,
		 "Only array FINAL procedures declared for derived type %qs"
		 " defined at %L, suggest also scalar one",
		 derived->name, &derived->declared_at);

  vtab = gfc_find_derived_vtab (derived);
  c = vtab->ts.u.derived->components->next->next->next->next->next;
  gfc_set_sym_referenced (c->initializer->symtree->n.sym);

  if (finalizable)
    *finalizable = true;

  return true;
}


/* Check if two GENERIC targets are ambiguous and emit an error is they are.  */

static bool
check_generic_tbp_ambiguity (gfc_tbp_generic* t1, gfc_tbp_generic* t2,
			     const char* generic_name, locus where)
{
  gfc_symbol *sym1, *sym2;
  const char *pass1, *pass2;
  gfc_formal_arglist *dummy_args;

  gcc_assert (t1->specific && t2->specific);
  gcc_assert (!t1->specific->is_generic);
  gcc_assert (!t2->specific->is_generic);
  gcc_assert (t1->is_operator == t2->is_operator);

  sym1 = t1->specific->u.specific->n.sym;
  sym2 = t2->specific->u.specific->n.sym;

  if (sym1 == sym2)
    return true;

  /* Both must be SUBROUTINEs or both must be FUNCTIONs.  */
  if (sym1->attr.subroutine != sym2->attr.subroutine
      || sym1->attr.function != sym2->attr.function)
    {
      gfc_error ("%qs and %qs cannot be mixed FUNCTION/SUBROUTINE for"
		 " GENERIC %qs at %L",
		 sym1->name, sym2->name, generic_name, &where);
      return false;
    }

  /* Determine PASS arguments.  */
  if (t1->specific->nopass)
    pass1 = NULL;
  else if (t1->specific->pass_arg)
    pass1 = t1->specific->pass_arg;
  else
    {
      dummy_args = gfc_sym_get_dummy_args (t1->specific->u.specific->n.sym);
      if (dummy_args)
	pass1 = dummy_args->sym->name;
      else
	pass1 = NULL;
    }
  if (t2->specific->nopass)
    pass2 = NULL;
  else if (t2->specific->pass_arg)
    pass2 = t2->specific->pass_arg;
  else
    {
      dummy_args = gfc_sym_get_dummy_args (t2->specific->u.specific->n.sym);
      if (dummy_args)
	pass2 = dummy_args->sym->name;
      else
	pass2 = NULL;
    }

  /* Compare the interfaces.  */
  if (gfc_compare_interfaces (sym1, sym2, sym2->name, !t1->is_operator, 0,
			      NULL, 0, pass1, pass2))
    {
      gfc_error ("%qs and %qs for GENERIC %qs at %L are ambiguous",
		 sym1->name, sym2->name, generic_name, &where);
      return false;
    }

  return true;
}


/* Worker function for resolving a generic procedure binding; this is used to
   resolve GENERIC as well as user and intrinsic OPERATOR typebound procedures.

   The difference between those cases is finding possible inherited bindings
   that are overridden, as one has to look for them in tb_sym_root,
   tb_uop_root or tb_op, respectively.  Thus the caller must already find
   the super-type and set p->overridden correctly.  */

static bool
resolve_tb_generic_targets (gfc_symbol* super_type,
			    gfc_typebound_proc* p, const char* name)
{
  gfc_tbp_generic* target;
  gfc_symtree* first_target;
  gfc_symtree* inherited;

  gcc_assert (p && p->is_generic);

  /* Try to find the specific bindings for the symtrees in our target-list.  */
  gcc_assert (p->u.generic);
  for (target = p->u.generic; target; target = target->next)
    if (!target->specific)
      {
	gfc_typebound_proc* overridden_tbp;
	gfc_tbp_generic* g;
	const char* target_name;

	target_name = target->specific_st->name;

	/* Defined for this type directly.  */
	if (target->specific_st->n.tb && !target->specific_st->n.tb->error)
	  {
	    target->specific = target->specific_st->n.tb;
	    goto specific_found;
	  }

	/* Look for an inherited specific binding.  */
	if (super_type)
	  {
	    inherited = gfc_find_typebound_proc (super_type, NULL, target_name,
						 true, NULL);

	    if (inherited)
	      {
		gcc_assert (inherited->n.tb);
		target->specific = inherited->n.tb;
		goto specific_found;
	      }
	  }

	gfc_error ("Undefined specific binding %qs as target of GENERIC %qs"
		   " at %L", target_name, name, &p->where);
	return false;

	/* Once we've found the specific binding, check it is not ambiguous with
	   other specifics already found or inherited for the same GENERIC.  */
specific_found:
	gcc_assert (target->specific);

	/* This must really be a specific binding!  */
	if (target->specific->is_generic)
	  {
	    gfc_error ("GENERIC %qs at %L must target a specific binding,"
		       " %qs is GENERIC, too", name, &p->where, target_name);
	    return false;
	  }

	/* Check those already resolved on this type directly.  */
	for (g = p->u.generic; g; g = g->next)
	  if (g != target && g->specific
	      && !check_generic_tbp_ambiguity (target, g, name, p->where))
	    return false;

	/* Check for ambiguity with inherited specific targets.  */
	for (overridden_tbp = p->overridden; overridden_tbp;
	     overridden_tbp = overridden_tbp->overridden)
	  if (overridden_tbp->is_generic)
	    {
	      for (g = overridden_tbp->u.generic; g; g = g->next)
		{
		  gcc_assert (g->specific);
		  if (!check_generic_tbp_ambiguity (target, g, name, p->where))
		    return false;
		}
	    }
      }

  /* If we attempt to "overwrite" a specific binding, this is an error.  */
  if (p->overridden && !p->overridden->is_generic)
    {
      gfc_error ("GENERIC %qs at %L cannot overwrite specific binding with"
		 " the same name", name, &p->where);
      return false;
    }

  /* Take the SUBROUTINE/FUNCTION attributes of the first specific target, as
     all must have the same attributes here.  */
  first_target = p->u.generic->specific->u.specific;
  gcc_assert (first_target);
  p->subroutine = first_target->n.sym->attr.subroutine;
  p->function = first_target->n.sym->attr.function;

  return true;
}


/* Resolve a GENERIC procedure binding for a derived type.  */

static bool
resolve_typebound_generic (gfc_symbol* derived, gfc_symtree* st)
{
  gfc_symbol* super_type;

  /* Find the overridden binding if any.  */
  st->n.tb->overridden = NULL;
  super_type = gfc_get_derived_super_type (derived);
  if (super_type)
    {
      gfc_symtree* overridden;
      overridden = gfc_find_typebound_proc (super_type, NULL, st->name,
					    true, NULL);

      if (overridden && overridden->n.tb)
	st->n.tb->overridden = overridden->n.tb;
    }

  /* Resolve using worker function.  */
  return resolve_tb_generic_targets (super_type, st->n.tb, st->name);
}


/* Retrieve the target-procedure of an operator binding and do some checks in
   common for intrinsic and user-defined type-bound operators.  */

static gfc_symbol*
get_checked_tb_operator_target (gfc_tbp_generic* target, locus where)
{
  gfc_symbol* target_proc;

  gcc_assert (target->specific && !target->specific->is_generic);
  target_proc = target->specific->u.specific->n.sym;
  gcc_assert (target_proc);

  /* F08:C468. All operator bindings must have a passed-object dummy argument.  */
  if (target->specific->nopass)
    {
      gfc_error ("Type-bound operator at %L cannot be NOPASS", &where);
      return NULL;
    }

  return target_proc;
}


/* Resolve a type-bound intrinsic operator.  */

static bool
resolve_typebound_intrinsic_op (gfc_symbol* derived, gfc_intrinsic_op op,
				gfc_typebound_proc* p)
{
  gfc_symbol* super_type;
  gfc_tbp_generic* target;

  /* If there's already an error here, do nothing (but don't fail again).  */
  if (p->error)
    return true;

  /* Operators should always be GENERIC bindings.  */
  gcc_assert (p->is_generic);

  /* Look for an overridden binding.  */
  super_type = gfc_get_derived_super_type (derived);
  if (super_type && super_type->f2k_derived)
    p->overridden = gfc_find_typebound_intrinsic_op (super_type, NULL,
						     op, true, NULL);
  else
    p->overridden = NULL;

  /* Resolve general GENERIC properties using worker function.  */
  if (!resolve_tb_generic_targets (super_type, p, gfc_op2string(op)))
    goto error;

  /* Check the targets to be procedures of correct interface.  */
  for (target = p->u.generic; target; target = target->next)
    {
      gfc_symbol* target_proc;

      target_proc = get_checked_tb_operator_target (target, p->where);
      if (!target_proc)
	goto error;

      if (!gfc_check_operator_interface (target_proc, op, p->where))
	goto error;

      /* Add target to non-typebound operator list.  */
      if (!target->specific->deferred && !derived->attr.use_assoc
	  && p->access != ACCESS_PRIVATE && derived->ns == gfc_current_ns)
	{
	  gfc_interface *head, *intr;

	  /* Preempt 'gfc_check_new_interface' for submodules, where the
	     mechanism for handling module procedures winds up resolving
	     operator interfaces twice and would otherwise cause an error.  */
	  for (intr = derived->ns->op[op]; intr; intr = intr->next)
	    if (intr->sym == target_proc
		&& target_proc->attr.used_in_submodule)
	      return true;

	  if (!gfc_check_new_interface (derived->ns->op[op],
					target_proc, p->where))
	    return false;
	  head = derived->ns->op[op];
	  intr = gfc_get_interface ();
	  intr->sym = target_proc;
	  intr->where = p->where;
	  intr->next = head;
	  derived->ns->op[op] = intr;
	}
    }

  return true;

error:
  p->error = 1;
  return false;
}


/* Resolve a type-bound user operator (tree-walker callback).  */

static gfc_symbol* resolve_bindings_derived;
static bool resolve_bindings_result;

static bool check_uop_procedure (gfc_symbol* sym, locus where);

static void
resolve_typebound_user_op (gfc_symtree* stree)
{
  gfc_symbol* super_type;
  gfc_tbp_generic* target;

  gcc_assert (stree && stree->n.tb);

  if (stree->n.tb->error)
    return;

  /* Operators should always be GENERIC bindings.  */
  gcc_assert (stree->n.tb->is_generic);

  /* Find overridden procedure, if any.  */
  super_type = gfc_get_derived_super_type (resolve_bindings_derived);
  if (super_type && super_type->f2k_derived)
    {
      gfc_symtree* overridden;
      overridden = gfc_find_typebound_user_op (super_type, NULL,
					       stree->name, true, NULL);

      if (overridden && overridden->n.tb)
	stree->n.tb->overridden = overridden->n.tb;
    }
  else
    stree->n.tb->overridden = NULL;

  /* Resolve basically using worker function.  */
  if (!resolve_tb_generic_targets (super_type, stree->n.tb, stree->name))
    goto error;

  /* Check the targets to be functions of correct interface.  */
  for (target = stree->n.tb->u.generic; target; target = target->next)
    {
      gfc_symbol* target_proc;

      target_proc = get_checked_tb_operator_target (target, stree->n.tb->where);
      if (!target_proc)
	goto error;

      if (!check_uop_procedure (target_proc, stree->n.tb->where))
	goto error;
    }

  return;

error:
  resolve_bindings_result = false;
  stree->n.tb->error = 1;
}


/* Resolve the type-bound procedures for a derived type.  */

static void
resolve_typebound_procedure (gfc_symtree* stree)
{
  gfc_symbol* proc;
  locus where;
  gfc_symbol* me_arg;
  gfc_symbol* super_type;
  gfc_component* comp;

  gcc_assert (stree);

  /* Undefined specific symbol from GENERIC target definition.  */
  if (!stree->n.tb)
    return;

  if (stree->n.tb->error)
    return;

  /* If this is a GENERIC binding, use that routine.  */
  if (stree->n.tb->is_generic)
    {
      if (!resolve_typebound_generic (resolve_bindings_derived, stree))
	goto error;
      return;
    }

  /* Get the target-procedure to check it.  */
  gcc_assert (!stree->n.tb->is_generic);
  gcc_assert (stree->n.tb->u.specific);
  proc = stree->n.tb->u.specific->n.sym;
  where = stree->n.tb->where;

  /* Default access should already be resolved from the parser.  */
  gcc_assert (stree->n.tb->access != ACCESS_UNKNOWN);

  if (stree->n.tb->deferred)
    {
      if (!check_proc_interface (proc, &where))
	goto error;
    }
  else
    {
      /* If proc has not been resolved at this point, proc->name may
	 actually be a USE associated entity. See PR fortran/89647. */
      if (!proc->resolve_symbol_called
	  && proc->attr.function == 0 && proc->attr.subroutine == 0)
	{
	  gfc_symbol *tmp;
	  gfc_find_symbol (proc->name, gfc_current_ns->parent, 1, &tmp);
	  if (tmp && tmp->attr.use_assoc)
	    {
	      proc->module = tmp->module;
	      proc->attr.proc = tmp->attr.proc;
	      proc->attr.function = tmp->attr.function;
	      proc->attr.subroutine = tmp->attr.subroutine;
	      proc->attr.use_assoc = tmp->attr.use_assoc;
	      proc->ts = tmp->ts;
	      proc->result = tmp->result;
	    }
	}

      /* Check for F08:C465.  */
      if ((!proc->attr.subroutine && !proc->attr.function)
	  || (proc->attr.proc != PROC_MODULE
	      && proc->attr.if_source != IFSRC_IFBODY
	      && !proc->attr.module_procedure)
	  || proc->attr.abstract)
	{
	  gfc_error ("%qs must be a module procedure or an external "
		     "procedure with an explicit interface at %L",
		     proc->name, &where);
	  goto error;
	}
    }

  stree->n.tb->subroutine = proc->attr.subroutine;
  stree->n.tb->function = proc->attr.function;

  /* Find the super-type of the current derived type.  We could do this once and
     store in a global if speed is needed, but as long as not I believe this is
     more readable and clearer.  */
  super_type = gfc_get_derived_super_type (resolve_bindings_derived);

  /* If PASS, resolve and check arguments if not already resolved / loaded
     from a .mod file.  */
  if (!stree->n.tb->nopass && stree->n.tb->pass_arg_num == 0)
    {
      gfc_formal_arglist *dummy_args;

      dummy_args = gfc_sym_get_dummy_args (proc);
      if (stree->n.tb->pass_arg)
	{
	  gfc_formal_arglist *i;

	  /* If an explicit passing argument name is given, walk the arg-list
	     and look for it.  */

	  me_arg = NULL;
	  stree->n.tb->pass_arg_num = 1;
	  for (i = dummy_args; i; i = i->next)
	    {
	      if (!strcmp (i->sym->name, stree->n.tb->pass_arg))
		{
		  me_arg = i->sym;
		  break;
		}
	      ++stree->n.tb->pass_arg_num;
	    }

	  if (!me_arg)
	    {
	      gfc_error ("Procedure %qs with PASS(%s) at %L has no"
			 " argument %qs",
			 proc->name, stree->n.tb->pass_arg, &where,
			 stree->n.tb->pass_arg);
	      goto error;
	    }
	}
      else
	{
	  /* Otherwise, take the first one; there should in fact be at least
	     one.  */
	  stree->n.tb->pass_arg_num = 1;
	  if (!dummy_args)
	    {
	      gfc_error ("Procedure %qs with PASS at %L must have at"
			 " least one argument", proc->name, &where);
	      goto error;
	    }
	  me_arg = dummy_args->sym;
	}

      /* Now check that the argument-type matches and the passed-object
	 dummy argument is generally fine.  */

      gcc_assert (me_arg);

      if (me_arg->ts.type != BT_CLASS)
	{
	  gfc_error ("Non-polymorphic passed-object dummy argument of %qs"
		     " at %L", proc->name, &where);
	  goto error;
	}

      if (CLASS_DATA (me_arg)->ts.u.derived
	  != resolve_bindings_derived)
	{
	  gfc_error ("Argument %qs of %qs with PASS(%s) at %L must be of"
		     " the derived-type %qs", me_arg->name, proc->name,
		     me_arg->name, &where, resolve_bindings_derived->name);
	  goto error;
	}

      gcc_assert (me_arg->ts.type == BT_CLASS);
      if (CLASS_DATA (me_arg)->as && CLASS_DATA (me_arg)->as->rank != 0)
	{
	  gfc_error ("Passed-object dummy argument of %qs at %L must be"
		     " scalar", proc->name, &where);
	  goto error;
	}
      if (CLASS_DATA (me_arg)->attr.allocatable)
	{
	  gfc_error ("Passed-object dummy argument of %qs at %L must not"
		     " be ALLOCATABLE", proc->name, &where);
	  goto error;
	}
      if (CLASS_DATA (me_arg)->attr.class_pointer)
	{
	  gfc_error ("Passed-object dummy argument of %qs at %L must not"
		     " be POINTER", proc->name, &where);
	  goto error;
	}
    }

  /* If we are extending some type, check that we don't override a procedure
     flagged NON_OVERRIDABLE.  */
  stree->n.tb->overridden = NULL;
  if (super_type)
    {
      gfc_symtree* overridden;
      overridden = gfc_find_typebound_proc (super_type, NULL,
					    stree->name, true, NULL);

      if (overridden)
	{
	  if (overridden->n.tb)
	    stree->n.tb->overridden = overridden->n.tb;

	  if (!gfc_check_typebound_override (stree, overridden))
	    goto error;
	}
    }

  /* See if there's a name collision with a component directly in this type.  */
  for (comp = resolve_bindings_derived->components; comp; comp = comp->next)
    if (!strcmp (comp->name, stree->name))
      {
	gfc_error ("Procedure %qs at %L has the same name as a component of"
		   " %qs",
		   stree->name, &where, resolve_bindings_derived->name);
	goto error;
      }

  /* Try to find a name collision with an inherited component.  */
  if (super_type && gfc_find_component (super_type, stree->name, true, true,
                                        NULL))
    {
      gfc_error ("Procedure %qs at %L has the same name as an inherited"
		 " component of %qs",
		 stree->name, &where, resolve_bindings_derived->name);
      goto error;
    }

  stree->n.tb->error = 0;
  return;

error:
  resolve_bindings_result = false;
  stree->n.tb->error = 1;
}


static bool
resolve_typebound_procedures (gfc_symbol* derived)
{
  int op;
  gfc_symbol* super_type;

  if (!derived->f2k_derived || !derived->f2k_derived->tb_sym_root)
    return true;

  super_type = gfc_get_derived_super_type (derived);
  if (super_type)
    resolve_symbol (super_type);

  resolve_bindings_derived = derived;
  resolve_bindings_result = true;

  if (derived->f2k_derived->tb_sym_root)
    gfc_traverse_symtree (derived->f2k_derived->tb_sym_root,
			  &resolve_typebound_procedure);

  if (derived->f2k_derived->tb_uop_root)
    gfc_traverse_symtree (derived->f2k_derived->tb_uop_root,
			  &resolve_typebound_user_op);

  for (op = 0; op != GFC_INTRINSIC_OPS; ++op)
    {
      gfc_typebound_proc* p = derived->f2k_derived->tb_op[op];
      if (p && !resolve_typebound_intrinsic_op (derived,
						(gfc_intrinsic_op)op, p))
	resolve_bindings_result = false;
    }

  return resolve_bindings_result;
}


/* Add a derived type to the dt_list.  The dt_list is used in trans-types.c
   to give all identical derived types the same backend_decl.  */
static void
add_dt_to_dt_list (gfc_symbol *derived)
{
  if (!derived->dt_next)
    {
      if (gfc_derived_types)
	{
	  derived->dt_next = gfc_derived_types->dt_next;
	  gfc_derived_types->dt_next = derived;
	}
      else
	{
	  derived->dt_next = derived;
	}
      gfc_derived_types = derived;
    }
}


/* Ensure that a derived-type is really not abstract, meaning that every
   inherited DEFERRED binding is overridden by a non-DEFERRED one.  */

static bool
ensure_not_abstract_walker (gfc_symbol* sub, gfc_symtree* st)
{
  if (!st)
    return true;

  if (!ensure_not_abstract_walker (sub, st->left))
    return false;
  if (!ensure_not_abstract_walker (sub, st->right))
    return false;

  if (st->n.tb && st->n.tb->deferred)
    {
      gfc_symtree* overriding;
      overriding = gfc_find_typebound_proc (sub, NULL, st->name, true, NULL);
      if (!overriding)
	return false;
      gcc_assert (overriding->n.tb);
      if (overriding->n.tb->deferred)
	{
	  gfc_error ("Derived-type %qs declared at %L must be ABSTRACT because"
		     " %qs is DEFERRED and not overridden",
		     sub->name, &sub->declared_at, st->name);
	  return false;
	}
    }

  return true;
}

static bool
ensure_not_abstract (gfc_symbol* sub, gfc_symbol* ancestor)
{
  /* The algorithm used here is to recursively travel up the ancestry of sub
     and for each ancestor-type, check all bindings.  If any of them is
     DEFERRED, look it up starting from sub and see if the found (overriding)
     binding is not DEFERRED.
     This is not the most efficient way to do this, but it should be ok and is
     clearer than something sophisticated.  */

  gcc_assert (ancestor && !sub->attr.abstract);

  if (!ancestor->attr.abstract)
    return true;

  /* Walk bindings of this ancestor.  */
  if (ancestor->f2k_derived)
    {
      bool t;
      t = ensure_not_abstract_walker (sub, ancestor->f2k_derived->tb_sym_root);
      if (!t)
	return false;
    }

  /* Find next ancestor type and recurse on it.  */
  ancestor = gfc_get_derived_super_type (ancestor);
  if (ancestor)
    return ensure_not_abstract (sub, ancestor);

  return true;
}


/* This check for typebound defined assignments is done recursively
   since the order in which derived types are resolved is not always in
   order of the declarations.  */

static void
check_defined_assignments (gfc_symbol *derived)
{
  gfc_component *c;

  for (c = derived->components; c; c = c->next)
    {
      if (!gfc_bt_struct (c->ts.type)
	  || c->attr.pointer
	  || c->attr.allocatable
	  || c->attr.proc_pointer_comp
	  || c->attr.class_pointer
	  || c->attr.proc_pointer)
	continue;

      if (c->ts.u.derived->attr.defined_assign_comp
	  || (c->ts.u.derived->f2k_derived
	     && c->ts.u.derived->f2k_derived->tb_op[INTRINSIC_ASSIGN]))
	{
	  derived->attr.defined_assign_comp = 1;
	  return;
	}

      check_defined_assignments (c->ts.u.derived);
      if (c->ts.u.derived->attr.defined_assign_comp)
	{
	  derived->attr.defined_assign_comp = 1;
	  return;
	}
    }
}


/* Resolve a single component of a derived type or structure.  */

static bool
resolve_component (gfc_component *c, gfc_symbol *sym)
{
  gfc_symbol *super_type;
  symbol_attribute *attr;

  if (c->attr.artificial)
    return true;

  /* Do not allow vtype components to be resolved in nameless namespaces
     such as block data because the procedure pointers will cause ICEs
     and vtables are not needed in these contexts.  */
  if (sym->attr.vtype && sym->attr.use_assoc
      && sym->ns->proc_name == NULL)
    return true;

  /* F2008, C442.  */
  if ((!sym->attr.is_class || c != sym->components)
      && c->attr.codimension
      && (!c->attr.allocatable || (c->as && c->as->type != AS_DEFERRED)))
    {
      gfc_error ("Coarray component %qs at %L must be allocatable with "
                 "deferred shape", c->name, &c->loc);
      return false;
    }

  /* F2008, C443.  */
  if (c->attr.codimension && c->ts.type == BT_DERIVED
      && c->ts.u.derived->ts.is_iso_c)
    {
      gfc_error ("Component %qs at %L of TYPE(C_PTR) or TYPE(C_FUNPTR) "
                 "shall not be a coarray", c->name, &c->loc);
      return false;
    }

  /* F2008, C444.  */
  if (gfc_bt_struct (c->ts.type) && c->ts.u.derived->attr.coarray_comp
      && (c->attr.codimension || c->attr.pointer || c->attr.dimension
          || c->attr.allocatable))
    {
      gfc_error ("Component %qs at %L with coarray component "
                 "shall be a nonpointer, nonallocatable scalar",
                 c->name, &c->loc);
      return false;
    }

  /* F2008, C448.  */
  if (c->ts.type == BT_CLASS)
    {
      if (c->attr.class_ok && CLASS_DATA (c))
	{
	  attr = &(CLASS_DATA (c)->attr);

	  /* Fix up contiguous attribute.  */
	  if (c->attr.contiguous)
	    attr->contiguous = 1;
	}
      else
	attr = NULL;
    }
  else
    attr = &c->attr;

  if (attr && attr->contiguous && (!attr->dimension || !attr->pointer))
    {
      gfc_error ("Component %qs at %L has the CONTIGUOUS attribute but "
                 "is not an array pointer", c->name, &c->loc);
      return false;
    }

  /* F2003, 15.2.1 - length has to be one.  */
  if (sym->attr.is_bind_c && c->ts.type == BT_CHARACTER
      && (c->ts.u.cl == NULL || c->ts.u.cl->length == NULL
	  || !gfc_is_constant_expr (c->ts.u.cl->length)
	  || mpz_cmp_si (c->ts.u.cl->length->value.integer, 1) != 0))
    {
      gfc_error ("Component %qs of BIND(C) type at %L must have length one",
		 c->name, &c->loc);
      return false;
    }

  if (c->attr.proc_pointer && c->ts.interface)
    {
      gfc_symbol *ifc = c->ts.interface;

      if (!sym->attr.vtype && !check_proc_interface (ifc, &c->loc))
        {
          c->tb->error = 1;
          return false;
        }

      if (ifc->attr.if_source || ifc->attr.intrinsic)
        {
          /* Resolve interface and copy attributes.  */
          if (ifc->formal && !ifc->formal_ns)
            resolve_symbol (ifc);
          if (ifc->attr.intrinsic)
            gfc_resolve_intrinsic (ifc, &ifc->declared_at);

          if (ifc->result)
            {
              c->ts = ifc->result->ts;
              c->attr.allocatable = ifc->result->attr.allocatable;
              c->attr.pointer = ifc->result->attr.pointer;
              c->attr.dimension = ifc->result->attr.dimension;
              c->as = gfc_copy_array_spec (ifc->result->as);
              c->attr.class_ok = ifc->result->attr.class_ok;
            }
          else
            {
              c->ts = ifc->ts;
              c->attr.allocatable = ifc->attr.allocatable;
              c->attr.pointer = ifc->attr.pointer;
              c->attr.dimension = ifc->attr.dimension;
              c->as = gfc_copy_array_spec (ifc->as);
              c->attr.class_ok = ifc->attr.class_ok;
            }
          c->ts.interface = ifc;
          c->attr.function = ifc->attr.function;
          c->attr.subroutine = ifc->attr.subroutine;

          c->attr.pure = ifc->attr.pure;
          c->attr.elemental = ifc->attr.elemental;
          c->attr.recursive = ifc->attr.recursive;
          c->attr.always_explicit = ifc->attr.always_explicit;
          c->attr.ext_attr |= ifc->attr.ext_attr;
          /* Copy char length.  */
          if (ifc->ts.type == BT_CHARACTER && ifc->ts.u.cl)
            {
              gfc_charlen *cl = gfc_new_charlen (sym->ns, ifc->ts.u.cl);
              if (cl->length && !cl->resolved
                  && !gfc_resolve_expr (cl->length))
                {
                  c->tb->error = 1;
                  return false;
                }
              c->ts.u.cl = cl;
            }
        }
    }
  else if (c->attr.proc_pointer && c->ts.type == BT_UNKNOWN)
    {
      /* Since PPCs are not implicitly typed, a PPC without an explicit
         interface must be a subroutine.  */
      gfc_add_subroutine (&c->attr, c->name, &c->loc);
    }

  /* Procedure pointer components: Check PASS arg.  */
  if (c->attr.proc_pointer && !c->tb->nopass && c->tb->pass_arg_num == 0
      && !sym->attr.vtype)
    {
      gfc_symbol* me_arg;

      if (c->tb->pass_arg)
        {
          gfc_formal_arglist* i;

          /* If an explicit passing argument name is given, walk the arg-list
            and look for it.  */

          me_arg = NULL;
          c->tb->pass_arg_num = 1;
          for (i = c->ts.interface->formal; i; i = i->next)
            {
              if (!strcmp (i->sym->name, c->tb->pass_arg))
                {
                  me_arg = i->sym;
                  break;
                }
              c->tb->pass_arg_num++;
            }

          if (!me_arg)
            {
              gfc_error ("Procedure pointer component %qs with PASS(%s) "
                         "at %L has no argument %qs", c->name,
                         c->tb->pass_arg, &c->loc, c->tb->pass_arg);
              c->tb->error = 1;
              return false;
            }
        }
      else
        {
          /* Otherwise, take the first one; there should in fact be at least
            one.  */
          c->tb->pass_arg_num = 1;
          if (!c->ts.interface->formal)
            {
              gfc_error ("Procedure pointer component %qs with PASS at %L "
                         "must have at least one argument",
                         c->name, &c->loc);
              c->tb->error = 1;
              return false;
            }
          me_arg = c->ts.interface->formal->sym;
        }

      /* Now check that the argument-type matches.  */
      gcc_assert (me_arg);
      if ((me_arg->ts.type != BT_DERIVED && me_arg->ts.type != BT_CLASS)
          || (me_arg->ts.type == BT_DERIVED && me_arg->ts.u.derived != sym)
          || (me_arg->ts.type == BT_CLASS
              && CLASS_DATA (me_arg)->ts.u.derived != sym))
        {
          gfc_error ("Argument %qs of %qs with PASS(%s) at %L must be of"
                     " the derived type %qs", me_arg->name, c->name,
                     me_arg->name, &c->loc, sym->name);
          c->tb->error = 1;
          return false;
        }

      /* Check for F03:C453.  */
      if (CLASS_DATA (me_arg)->attr.dimension)
        {
          gfc_error ("Argument %qs of %qs with PASS(%s) at %L "
                     "must be scalar", me_arg->name, c->name, me_arg->name,
                     &c->loc);
          c->tb->error = 1;
          return false;
        }

      if (CLASS_DATA (me_arg)->attr.class_pointer)
        {
          gfc_error ("Argument %qs of %qs with PASS(%s) at %L "
                     "may not have the POINTER attribute", me_arg->name,
                     c->name, me_arg->name, &c->loc);
          c->tb->error = 1;
          return false;
        }

      if (CLASS_DATA (me_arg)->attr.allocatable)
        {
          gfc_error ("Argument %qs of %qs with PASS(%s) at %L "
                     "may not be ALLOCATABLE", me_arg->name, c->name,
                     me_arg->name, &c->loc);
          c->tb->error = 1;
          return false;
        }

      if (gfc_type_is_extensible (sym) && me_arg->ts.type != BT_CLASS)
        {
          gfc_error ("Non-polymorphic passed-object dummy argument of %qs"
                     " at %L", c->name, &c->loc);
          return false;
        }

    }

  /* Check type-spec if this is not the parent-type component.  */
  if (((sym->attr.is_class
        && (!sym->components->ts.u.derived->attr.extension
            || c != sym->components->ts.u.derived->components))
       || (!sym->attr.is_class
           && (!sym->attr.extension || c != sym->components)))
      && !sym->attr.vtype
      && !resolve_typespec_used (&c->ts, &c->loc, c->name))
    return false;

  super_type = gfc_get_derived_super_type (sym);

  /* If this type is an extension, set the accessibility of the parent
     component.  */
  if (super_type
      && ((sym->attr.is_class
           && c == sym->components->ts.u.derived->components)
          || (!sym->attr.is_class && c == sym->components))
      && strcmp (super_type->name, c->name) == 0)
    c->attr.access = super_type->attr.access;

  /* If this type is an extension, see if this component has the same name
     as an inherited type-bound procedure.  */
  if (super_type && !sym->attr.is_class
      && gfc_find_typebound_proc (super_type, NULL, c->name, true, NULL))
    {
      gfc_error ("Component %qs of %qs at %L has the same name as an"
                 " inherited type-bound procedure",
                 c->name, sym->name, &c->loc);
      return false;
    }

  if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
        && !c->ts.deferred)
    {
     if (c->ts.u.cl->length == NULL
         || (!resolve_charlen(c->ts.u.cl))
         || !gfc_is_constant_expr (c->ts.u.cl->length))
       {
         gfc_error ("Character length of component %qs needs to "
                    "be a constant specification expression at %L",
                    c->name,
                    c->ts.u.cl->length ? &c->ts.u.cl->length->where : &c->loc);
         return false;
       }
    }

  if (c->ts.type == BT_CHARACTER && c->ts.deferred
      && !c->attr.pointer && !c->attr.allocatable)
    {
      gfc_error ("Character component %qs of %qs at %L with deferred "
                 "length must be a POINTER or ALLOCATABLE",
                 c->name, sym->name, &c->loc);
      return false;
    }

  /* Add the hidden deferred length field.  */
  if (c->ts.type == BT_CHARACTER
      && (c->ts.deferred || c->attr.pdt_string)
      && !c->attr.function
      && !sym->attr.is_class)
    {
      char name[GFC_MAX_SYMBOL_LEN+9];
      gfc_component *strlen;
      sprintf (name, "_%s_length", c->name);
      strlen = gfc_find_component (sym, name, true, true, NULL);
      if (strlen == NULL)
        {
          if (!gfc_add_component (sym, name, &strlen))
            return false;
          strlen->ts.type = BT_INTEGER;
          strlen->ts.kind = gfc_charlen_int_kind;
          strlen->attr.access = ACCESS_PRIVATE;
          strlen->attr.artificial = 1;
        }
    }

  if (c->ts.type == BT_DERIVED
      && sym->component_access != ACCESS_PRIVATE
      && gfc_check_symbol_access (sym)
      && !is_sym_host_assoc (c->ts.u.derived, sym->ns)
      && !c->ts.u.derived->attr.use_assoc
      && !gfc_check_symbol_access (c->ts.u.derived)
      && !gfc_notify_std (GFC_STD_F2003, "the component %qs is a "
                          "PRIVATE type and cannot be a component of "
                          "%qs, which is PUBLIC at %L", c->name,
                          sym->name, &sym->declared_at))
    return false;

  if ((sym->attr.sequence || sym->attr.is_bind_c) && c->ts.type == BT_CLASS)
    {
      gfc_error ("Polymorphic component %s at %L in SEQUENCE or BIND(C) "
                 "type %s", c->name, &c->loc, sym->name);
      return false;
    }

  if (sym->attr.sequence)
    {
      if (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.sequence == 0)
        {
          gfc_error ("Component %s of SEQUENCE type declared at %L does "
                     "not have the SEQUENCE attribute",
                     c->ts.u.derived->name, &sym->declared_at);
          return false;
        }
    }

  if (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.generic)
    c->ts.u.derived = gfc_find_dt_in_generic (c->ts.u.derived);
  else if (c->ts.type == BT_CLASS && c->attr.class_ok
           && CLASS_DATA (c)->ts.u.derived->attr.generic)
    CLASS_DATA (c)->ts.u.derived
                    = gfc_find_dt_in_generic (CLASS_DATA (c)->ts.u.derived);

  /* If an allocatable component derived type is of the same type as
     the enclosing derived type, we need a vtable generating so that
     the __deallocate procedure is created.  */
  if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
       && c->ts.u.derived == sym && c->attr.allocatable == 1)
    gfc_find_vtab (&c->ts);

  /* Ensure that all the derived type components are put on the
     derived type list; even in formal namespaces, where derived type
     pointer components might not have been declared.  */
  if (c->ts.type == BT_DERIVED
        && c->ts.u.derived
        && c->ts.u.derived->components
        && c->attr.pointer
        && sym != c->ts.u.derived)
    add_dt_to_dt_list (c->ts.u.derived);

  if (c->as && c->as->type != AS_DEFERRED
      && (c->attr.pointer || c->attr.allocatable))
    return false;

  if (!gfc_resolve_array_spec (c->as,
                               !(c->attr.pointer || c->attr.proc_pointer
                                 || c->attr.allocatable)))
    return false;

  if (c->initializer && !sym->attr.vtype
      && !c->attr.pdt_kind && !c->attr.pdt_len
      && !gfc_check_assign_symbol (sym, c, c->initializer))
    return false;

  return true;
}


/* Be nice about the locus for a structure expression - show the locus of the
   first non-null sub-expression if we can.  */

static locus *
cons_where (gfc_expr *struct_expr)
{
  gfc_constructor *cons;

  gcc_assert (struct_expr && struct_expr->expr_type == EXPR_STRUCTURE);

  cons = gfc_constructor_first (struct_expr->value.constructor);
  for (; cons; cons = gfc_constructor_next (cons))
    {
      if (cons->expr && cons->expr->expr_type != EXPR_NULL)
        return &cons->expr->where;
    }

  return &struct_expr->where;
}

/* Resolve the components of a structure type. Much less work than derived
   types.  */

static bool
resolve_fl_struct (gfc_symbol *sym)
{
  gfc_component *c;
  gfc_expr *init = NULL;
  bool success;

  /* Make sure UNIONs do not have overlapping initializers.  */
  if (sym->attr.flavor == FL_UNION)
    {
      for (c = sym->components; c; c = c->next)
        {
          if (init && c->initializer)
            {
              gfc_error ("Conflicting initializers in union at %L and %L",
                         cons_where (init), cons_where (c->initializer));
              gfc_free_expr (c->initializer);
              c->initializer = NULL;
            }
          if (init == NULL)
            init = c->initializer;
        }
    }

  success = true;
  for (c = sym->components; c; c = c->next)
    if (!resolve_component (c, sym))
      success = false;

  if (!success)
    return false;

  if (sym->components)
    add_dt_to_dt_list (sym);

  return true;
}


/* Resolve the components of a derived type. This does not have to wait until
   resolution stage, but can be done as soon as the dt declaration has been
   parsed.  */

static bool
resolve_fl_derived0 (gfc_symbol *sym)
{
  gfc_symbol* super_type;
  gfc_component *c;
  gfc_formal_arglist *f;
  bool success;

  if (sym->attr.unlimited_polymorphic)
    return true;

  super_type = gfc_get_derived_super_type (sym);

  /* F2008, C432.  */
  if (super_type && sym->attr.coarray_comp && !super_type->attr.coarray_comp)
    {
      gfc_error ("As extending type %qs at %L has a coarray component, "
		 "parent type %qs shall also have one", sym->name,
		 &sym->declared_at, super_type->name);
      return false;
    }

  /* Ensure the extended type gets resolved before we do.  */
  if (super_type && !resolve_fl_derived0 (super_type))
    return false;

  /* An ABSTRACT type must be extensible.  */
  if (sym->attr.abstract && !gfc_type_is_extensible (sym))
    {
      gfc_error ("Non-extensible derived-type %qs at %L must not be ABSTRACT",
		 sym->name, &sym->declared_at);
      return false;
    }

  c = (sym->attr.is_class) ? sym->components->ts.u.derived->components
			   : sym->components;

  success = true;
  for ( ; c != NULL; c = c->next)
    if (!resolve_component (c, sym))
      success = false;

  if (!success)
    return false;

  /* Now add the caf token field, where needed.  */
  if (flag_coarray != GFC_FCOARRAY_NONE
      && !sym->attr.is_class && !sym->attr.vtype)
    {
      for (c = sym->components; c; c = c->next)
	if (!c->attr.dimension && !c->attr.codimension
	    && (c->attr.allocatable || c->attr.pointer))
	  {
	    char name[GFC_MAX_SYMBOL_LEN+9];
	    gfc_component *token;
	    sprintf (name, "_caf_%s", c->name);
	    token = gfc_find_component (sym, name, true, true, NULL);
	    if (token == NULL)
	      {
		if (!gfc_add_component (sym, name, &token))
		  return false;
		token->ts.type = BT_VOID;
		token->ts.kind = gfc_default_integer_kind;
		token->attr.access = ACCESS_PRIVATE;
		token->attr.artificial = 1;
		token->attr.caf_token = 1;
	      }
	  }
    }

  check_defined_assignments (sym);

  if (!sym->attr.defined_assign_comp && super_type)
    sym->attr.defined_assign_comp
			= super_type->attr.defined_assign_comp;

  /* If this is a non-ABSTRACT type extending an ABSTRACT one, ensure that
     all DEFERRED bindings are overridden.  */
  if (super_type && super_type->attr.abstract && !sym->attr.abstract
      && !sym->attr.is_class
      && !ensure_not_abstract (sym, super_type))
    return false;

  /* Check that there is a component for every PDT parameter.  */
  if (sym->attr.pdt_template)
    {
      for (f = sym->formal; f; f = f->next)
	{
	  if (!f->sym)
	    continue;
	  c = gfc_find_component (sym, f->sym->name, true, true, NULL);
	  if (c == NULL)
	    {
	      gfc_error ("Parameterized type %qs does not have a component "
			 "corresponding to parameter %qs at %L", sym->name,
			 f->sym->name, &sym->declared_at);
	      break;
	    }
	}
    }

  /* Add derived type to the derived type list.  */
  add_dt_to_dt_list (sym);

  return true;
}


/* The following procedure does the full resolution of a derived type,
   including resolution of all type-bound procedures (if present). In contrast
   to 'resolve_fl_derived0' this can only be done after the module has been
   parsed completely.  */

static bool
resolve_fl_derived (gfc_symbol *sym)
{
  gfc_symbol *gen_dt = NULL;

  if (sym->attr.unlimited_polymorphic)
    return true;

  if (!sym->attr.is_class)
    gfc_find_symbol (sym->name, sym->ns, 0, &gen_dt);
  if (gen_dt && gen_dt->generic && gen_dt->generic->next
      && (!gen_dt->generic->sym->attr.use_assoc
	  || gen_dt->generic->sym->module != gen_dt->generic->next->sym->module)
      && !gfc_notify_std (GFC_STD_F2003, "Generic name %qs of function "
			  "%qs at %L being the same name as derived "
			  "type at %L", sym->name,
			  gen_dt->generic->sym == sym
			  ? gen_dt->generic->next->sym->name
			  : gen_dt->generic->sym->name,
			  gen_dt->generic->sym == sym
			  ? &gen_dt->generic->next->sym->declared_at
			  : &gen_dt->generic->sym->declared_at,
			  &sym->declared_at))
    return false;

  if (sym->components == NULL && !sym->attr.zero_comp && !sym->attr.use_assoc)
    {
      gfc_error ("Derived type %qs at %L has not been declared",
		  sym->name, &sym->declared_at);
      return false;
    }

  /* Resolve the finalizer procedures.  */
  if (!gfc_resolve_finalizers (sym, NULL))
    return false;

  if (sym->attr.is_class && sym->ts.u.derived == NULL)
    {
      /* Fix up incomplete CLASS symbols.  */
      gfc_component *data = gfc_find_component (sym, "_data", true, true, NULL);
      gfc_component *vptr = gfc_find_component (sym, "_vptr", true, true, NULL);

      /* Nothing more to do for unlimited polymorphic entities.  */
      if (data->ts.u.derived->attr.unlimited_polymorphic)
	return true;
      else if (vptr->ts.u.derived == NULL)
	{
	  gfc_symbol *vtab = gfc_find_derived_vtab (data->ts.u.derived);
	  gcc_assert (vtab);
	  vptr->ts.u.derived = vtab->ts.u.derived;
	  if (!resolve_fl_derived0 (vptr->ts.u.derived))
	    return false;
	}
    }

  if (!resolve_fl_derived0 (sym))
    return false;

  /* Resolve the type-bound procedures.  */
  if (!resolve_typebound_procedures (sym))
    return false;

  /* Generate module vtables subject to their accessibility and their not
     being vtables or pdt templates. If this is not done class declarations
     in external procedures wind up with their own version and so SELECT TYPE
     fails because the vptrs do not have the same address.  */
  if (gfc_option.allow_std & GFC_STD_F2003
      && sym->ns->proc_name
      && sym->ns->proc_name->attr.flavor == FL_MODULE
      && sym->attr.access != ACCESS_PRIVATE
      && !(sym->attr.use_assoc || sym->attr.vtype || sym->attr.pdt_template))
    {
      gfc_symbol *vtab = gfc_find_derived_vtab (sym);
      gfc_set_sym_referenced (vtab);
    }

  return true;
}


static bool
resolve_fl_namelist (gfc_symbol *sym)
{
  gfc_namelist *nl;
  gfc_symbol *nlsym;

  for (nl = sym->namelist; nl; nl = nl->next)
    {
      /* Check again, the check in match only works if NAMELIST comes
	 after the decl.  */
      if (nl->sym->as && nl->sym->as->type == AS_ASSUMED_SIZE)
     	{
	  gfc_error ("Assumed size array %qs in namelist %qs at %L is not "
		     "allowed", nl->sym->name, sym->name, &sym->declared_at);
	  return false;
	}

      if (nl->sym->as && nl->sym->as->type == AS_ASSUMED_SHAPE
	  && !gfc_notify_std (GFC_STD_F2003, "NAMELIST array object %qs "
			      "with assumed shape in namelist %qs at %L",
			      nl->sym->name, sym->name, &sym->declared_at))
	return false;

      if (is_non_constant_shape_array (nl->sym)
	  && !gfc_notify_std (GFC_STD_F2003, "NAMELIST array object %qs "
			      "with nonconstant shape in namelist %qs at %L",
			      nl->sym->name, sym->name, &sym->declared_at))
	return false;

      if (nl->sym->ts.type == BT_CHARACTER
	  && (nl->sym->ts.u.cl->length == NULL
	      || !gfc_is_constant_expr (nl->sym->ts.u.cl->length))
	  && !gfc_notify_std (GFC_STD_F2003, "NAMELIST object %qs with "
			      "nonconstant character length in "
			      "namelist %qs at %L", nl->sym->name,
			      sym->name, &sym->declared_at))
	return false;

    }

  /* Reject PRIVATE objects in a PUBLIC namelist.  */
  if (gfc_check_symbol_access (sym))
    {
      for (nl = sym->namelist; nl; nl = nl->next)
	{
	  if (!nl->sym->attr.use_assoc
	      && !is_sym_host_assoc (nl->sym, sym->ns)
	      && !gfc_check_symbol_access (nl->sym))
	    {
	      gfc_error ("NAMELIST object %qs was declared PRIVATE and "
			 "cannot be member of PUBLIC namelist %qs at %L",
			 nl->sym->name, sym->name, &sym->declared_at);
	      return false;
	    }

	  if (nl->sym->ts.type == BT_DERIVED
	     && (nl->sym->ts.u.derived->attr.alloc_comp
		 || nl->sym->ts.u.derived->attr.pointer_comp))
	   {
	     if (!gfc_notify_std (GFC_STD_F2003, "NAMELIST object %qs in "
				  "namelist %qs at %L with ALLOCATABLE "
				  "or POINTER components", nl->sym->name,
				  sym->name, &sym->declared_at))
	       return false;
	     return true;
	   }

	  /* Types with private components that came here by USE-association.  */
	  if (nl->sym->ts.type == BT_DERIVED
	      && derived_inaccessible (nl->sym->ts.u.derived))
	    {
	      gfc_error ("NAMELIST object %qs has use-associated PRIVATE "
			 "components and cannot be member of namelist %qs at %L",
			 nl->sym->name, sym->name, &sym->declared_at);
	      return false;
	    }

	  /* Types with private components that are defined in the same module.  */
	  if (nl->sym->ts.type == BT_DERIVED
	      && !is_sym_host_assoc (nl->sym->ts.u.derived, sym->ns)
	      && nl->sym->ts.u.derived->attr.private_comp)
	    {
	      gfc_error ("NAMELIST object %qs has PRIVATE components and "
			 "cannot be a member of PUBLIC namelist %qs at %L",
			 nl->sym->name, sym->name, &sym->declared_at);
	      return false;
	    }
	}
    }


  /* 14.1.2 A module or internal procedure represent local entities
     of the same type as a namelist member and so are not allowed.  */
  for (nl = sym->namelist; nl; nl = nl->next)
    {
      if (nl->sym->ts.kind != 0 && nl->sym->attr.flavor == FL_VARIABLE)
	continue;

      if (nl->sym->attr.function && nl->sym == nl->sym->result)
	if ((nl->sym == sym->ns->proc_name)
	       ||
	    (sym->ns->parent && nl->sym == sym->ns->parent->proc_name))
	  continue;

      nlsym = NULL;
      if (nl->sym->name)
	gfc_find_symbol (nl->sym->name, sym->ns, 1, &nlsym);
      if (nlsym && nlsym->attr.flavor == FL_PROCEDURE)
	{
	  gfc_error ("PROCEDURE attribute conflicts with NAMELIST "
		     "attribute in %qs at %L", nlsym->name,
		     &sym->declared_at);
	  return false;
	}
    }

  return true;
}


static bool
resolve_fl_parameter (gfc_symbol *sym)
{
  /* A parameter array's shape needs to be constant.  */
  if (sym->as != NULL
      && (sym->as->type == AS_DEFERRED
          || is_non_constant_shape_array (sym)))
    {
      gfc_error ("Parameter array %qs at %L cannot be automatic "
		 "or of deferred shape", sym->name, &sym->declared_at);
      return false;
    }

  /* Constraints on deferred type parameter.  */
  if (!deferred_requirements (sym))
    return false;

  /* Make sure a parameter that has been implicitly typed still
     matches the implicit type, since PARAMETER statements can precede
     IMPLICIT statements.  */
  if (sym->attr.implicit_type
      && !gfc_compare_types (&sym->ts, gfc_get_default_type (sym->name,
							     sym->ns)))
    {
      gfc_error ("Implicitly typed PARAMETER %qs at %L doesn't match a "
		 "later IMPLICIT type", sym->name, &sym->declared_at);
      return false;
    }

  /* Make sure the types of derived parameters are consistent.  This
     type checking is deferred until resolution because the type may
     refer to a derived type from the host.  */
  if (sym->ts.type == BT_DERIVED
      && !gfc_compare_types (&sym->ts, &sym->value->ts))
    {
      gfc_error ("Incompatible derived type in PARAMETER at %L",
		 &sym->value->where);
      return false;
    }

  /* F03:C509,C514.  */
  if (sym->ts.type == BT_CLASS)
    {
      gfc_error ("CLASS variable %qs at %L cannot have the PARAMETER attribute",
		 sym->name, &sym->declared_at);
      return false;
    }

  return true;
}


/* Called by resolve_symbol to check PDTs.  */

static void
resolve_pdt (gfc_symbol* sym)
{
  gfc_symbol *derived = NULL;
  gfc_actual_arglist *param;
  gfc_component *c;
  bool const_len_exprs = true;
  bool assumed_len_exprs = false;
  symbol_attribute *attr;

  if (sym->ts.type == BT_DERIVED)
    {
      derived = sym->ts.u.derived;
      attr = &(sym->attr);
    }
  else if (sym->ts.type == BT_CLASS)
    {
      derived = CLASS_DATA (sym)->ts.u.derived;
      attr = &(CLASS_DATA (sym)->attr);
    }
  else
    gcc_unreachable ();

  gcc_assert (derived->attr.pdt_type);

  for (param = sym->param_list; param; param = param->next)
    {
      c = gfc_find_component (derived, param->name, false, true, NULL);
      gcc_assert (c);
      if (c->attr.pdt_kind)
	continue;

      if (param->expr && !gfc_is_constant_expr (param->expr)
	  && c->attr.pdt_len)
	const_len_exprs = false;
      else if (param->spec_type == SPEC_ASSUMED)
	assumed_len_exprs = true;

      if (param->spec_type == SPEC_DEFERRED
	  && !attr->allocatable && !attr->pointer)
	gfc_error ("The object %qs at %L has a deferred LEN "
		   "parameter %qs and is neither allocatable "
		   "nor a pointer", sym->name, &sym->declared_at,
		   param->name);

    }

  if (!const_len_exprs
      && (sym->ns->proc_name->attr.is_main_program
	  || sym->ns->proc_name->attr.flavor == FL_MODULE
	  || sym->attr.save != SAVE_NONE))
    gfc_error ("The AUTOMATIC object %qs at %L must not have the "
	       "SAVE attribute or be a variable declared in the "
	       "main program, a module or a submodule(F08/C513)",
	       sym->name, &sym->declared_at);

  if (assumed_len_exprs && !(sym->attr.dummy
      || sym->attr.select_type_temporary || sym->attr.associate_var))
    gfc_error ("The object %qs at %L with ASSUMED type parameters "
	       "must be a dummy or a SELECT TYPE selector(F08/4.2)",
	       sym->name, &sym->declared_at);
}


/* Do anything necessary to resolve a symbol.  Right now, we just
   assume that an otherwise unknown symbol is a variable.  This sort
   of thing commonly happens for symbols in module.  */

static void
resolve_symbol (gfc_symbol *sym)
{
  int check_constant, mp_flag;
  gfc_symtree *symtree;
  gfc_symtree *this_symtree;
  gfc_namespace *ns;
  gfc_component *c;
  symbol_attribute class_attr;
  gfc_array_spec *as;
  bool saved_specification_expr;

  if (sym->resolve_symbol_called >= 1)
    return;
  sym->resolve_symbol_called = 1;

  /* No symbol will ever have union type; only components can be unions.
     Union type declaration symbols have type BT_UNKNOWN but flavor FL_UNION
     (just like derived type declaration symbols have flavor FL_DERIVED). */
  gcc_assert (sym->ts.type != BT_UNION);

  /* Coarrayed polymorphic objects with allocatable or pointer components are
     yet unsupported for -fcoarray=lib.  */
  if (flag_coarray == GFC_FCOARRAY_LIB && sym->ts.type == BT_CLASS
      && sym->ts.u.derived && CLASS_DATA (sym)
      && CLASS_DATA (sym)->attr.codimension
      && CLASS_DATA (sym)->ts.u.derived
      && (CLASS_DATA (sym)->ts.u.derived->attr.alloc_comp
	  || CLASS_DATA (sym)->ts.u.derived->attr.pointer_comp))
    {
      gfc_error ("Sorry, allocatable/pointer components in polymorphic (CLASS) "
		 "type coarrays at %L are unsupported", &sym->declared_at);
      return;
    }

  if (sym->attr.artificial)
    return;

  if (sym->attr.unlimited_polymorphic)
    return;

  if (sym->attr.flavor == FL_UNKNOWN
      || (sym->attr.flavor == FL_PROCEDURE && !sym->attr.intrinsic
	  && !sym->attr.generic && !sym->attr.external
	  && sym->attr.if_source == IFSRC_UNKNOWN
	  && sym->ts.type == BT_UNKNOWN))
    {

    /* If we find that a flavorless symbol is an interface in one of the
       parent namespaces, find its symtree in this namespace, free the
       symbol and set the symtree to point to the interface symbol.  */
      for (ns = gfc_current_ns->parent; ns; ns = ns->parent)
	{
	  symtree = gfc_find_symtree (ns->sym_root, sym->name);
	  if (symtree && (symtree->n.sym->generic ||
			  (symtree->n.sym->attr.flavor == FL_PROCEDURE
			   && sym->ns->construct_entities)))
	    {
	      this_symtree = gfc_find_symtree (gfc_current_ns->sym_root,
					       sym->name);
	      if (this_symtree->n.sym == sym)
		{
		  symtree->n.sym->refs++;
		  gfc_release_symbol (sym);
		  this_symtree->n.sym = symtree->n.sym;
		  return;
		}
	    }
	}

      /* Otherwise give it a flavor according to such attributes as
	 it has.  */
      if (sym->attr.flavor == FL_UNKNOWN && sym->attr.external == 0
	  && sym->attr.intrinsic == 0)
	sym->attr.flavor = FL_VARIABLE;
      else if (sym->attr.flavor == FL_UNKNOWN)
	{
	  sym->attr.flavor = FL_PROCEDURE;
	  if (sym->attr.dimension)
	    sym->attr.function = 1;
	}
    }

  if (sym->attr.external && sym->ts.type != BT_UNKNOWN && !sym->attr.function)
    gfc_add_function (&sym->attr, sym->name, &sym->declared_at);

  if (sym->attr.procedure && sym->attr.if_source != IFSRC_DECL
      && !resolve_procedure_interface (sym))
    return;

  if (sym->attr.is_protected && !sym->attr.proc_pointer
      && (sym->attr.procedure || sym->attr.external))
    {
      if (sym->attr.external)
	gfc_error ("PROTECTED attribute conflicts with EXTERNAL attribute "
	           "at %L", &sym->declared_at);
      else
	gfc_error ("PROCEDURE attribute conflicts with PROTECTED attribute "
	           "at %L", &sym->declared_at);

      return;
    }

  if (sym->attr.flavor == FL_DERIVED && !resolve_fl_derived (sym))
    return;

  else if ((sym->attr.flavor == FL_STRUCT || sym->attr.flavor == FL_UNION)
           && !resolve_fl_struct (sym))
    return;

  /* Symbols that are module procedures with results (functions) have
     the types and array specification copied for type checking in
     procedures that call them, as well as for saving to a module
     file.  These symbols can't stand the scrutiny that their results
     can.  */
  mp_flag = (sym->result != NULL && sym->result != sym);

  /* Make sure that the intrinsic is consistent with its internal
     representation. This needs to be done before assigning a default
     type to avoid spurious warnings.  */
  if (sym->attr.flavor != FL_MODULE && sym->attr.intrinsic
      && !gfc_resolve_intrinsic (sym, &sym->declared_at))
    return;

  /* Resolve associate names.  */
  if (sym->assoc)
    resolve_assoc_var (sym, true);

  /* Assign default type to symbols that need one and don't have one.  */
  if (sym->ts.type == BT_UNKNOWN)
    {
      if (sym->attr.flavor == FL_VARIABLE || sym->attr.flavor == FL_PARAMETER)
	{
	  gfc_set_default_type (sym, 1, NULL);
	}

      if (sym->attr.flavor == FL_PROCEDURE && sym->attr.external
	  && !sym->attr.function && !sym->attr.subroutine
	  && gfc_get_default_type (sym->name, sym->ns)->type == BT_UNKNOWN)
	gfc_add_subroutine (&sym->attr, sym->name, &sym->declared_at);

      if (sym->attr.flavor == FL_PROCEDURE && sym->attr.function)
	{
	  /* The specific case of an external procedure should emit an error
	     in the case that there is no implicit type.  */
	  if (!mp_flag)
	    {
	      if (!sym->attr.mixed_entry_master)
		gfc_set_default_type (sym, sym->attr.external, NULL);
	    }
	  else
	    {
	      /* Result may be in another namespace.  */
	      resolve_symbol (sym->result);

	      if (!sym->result->attr.proc_pointer)
		{
		  sym->ts = sym->result->ts;
		  sym->as = gfc_copy_array_spec (sym->result->as);
		  sym->attr.dimension = sym->result->attr.dimension;
		  sym->attr.pointer = sym->result->attr.pointer;
		  sym->attr.allocatable = sym->result->attr.allocatable;
		  sym->attr.contiguous = sym->result->attr.contiguous;
		}
	    }
	}
    }
  else if (mp_flag && sym->attr.flavor == FL_PROCEDURE && sym->attr.function)
    {
      bool saved_specification_expr = specification_expr;
      bool saved_formal_arg_flag = formal_arg_flag;

      specification_expr = true;
      formal_arg_flag = true;
      gfc_resolve_array_spec (sym->result->as, false);
      formal_arg_flag = saved_formal_arg_flag;
      specification_expr = saved_specification_expr;
    }

  if (sym->ts.type == BT_CLASS && sym->attr.class_ok && sym->ts.u.derived)
    {
      as = CLASS_DATA (sym)->as;
      class_attr = CLASS_DATA (sym)->attr;
      class_attr.pointer = class_attr.class_pointer;
    }
  else
    {
      class_attr = sym->attr;
      as = sym->as;
    }

  /* F2008, C530.  */
  if (sym->attr.contiguous
      && (!class_attr.dimension
	  || (as->type != AS_ASSUMED_SHAPE && as->type != AS_ASSUMED_RANK
	      && !class_attr.pointer)))
    {
      gfc_error ("%qs at %L has the CONTIGUOUS attribute but is not an "
		 "array pointer or an assumed-shape or assumed-rank array",
		 sym->name, &sym->declared_at);
      return;
    }

  /* Assumed size arrays and assumed shape arrays must be dummy
     arguments.  Array-spec's of implied-shape should have been resolved to
     AS_EXPLICIT already.  */

  if (as)
    {
      /* If AS_IMPLIED_SHAPE makes it to here, it must be a bad
	 specification expression.  */
      if (as->type == AS_IMPLIED_SHAPE)
	{
	  int i;
	  for (i=0; i<as->rank; i++)
	    {
	      if (as->lower[i] != NULL && as->upper[i] == NULL)
		{
		  gfc_error ("Bad specification for assumed size array at %L",
			     &as->lower[i]->where);
		  return;
		}
	    }
	  gcc_unreachable();
	}

      if (((as->type == AS_ASSUMED_SIZE && !as->cp_was_assumed)
	   || as->type == AS_ASSUMED_SHAPE)
	  && !sym->attr.dummy && !sym->attr.select_type_temporary)
	{
	  if (as->type == AS_ASSUMED_SIZE)
	    gfc_error ("Assumed size array at %L must be a dummy argument",
		       &sym->declared_at);
	  else
	    gfc_error ("Assumed shape array at %L must be a dummy argument",
		       &sym->declared_at);
	  return;
	}
      /* TS 29113, C535a.  */
      if (as->type == AS_ASSUMED_RANK && !sym->attr.dummy
	  && !sym->attr.select_type_temporary
	  && !(cs_base && cs_base->current
	       && cs_base->current->op == EXEC_SELECT_RANK))
	{
	  gfc_error ("Assumed-rank array at %L must be a dummy argument",
		     &sym->declared_at);
	  return;
	}
      if (as->type == AS_ASSUMED_RANK
	  && (sym->attr.codimension || sym->attr.value))
	{
	  gfc_error ("Assumed-rank array at %L may not have the VALUE or "
		     "CODIMENSION attribute", &sym->declared_at);
	  return;
	}
    }

  /* Make sure symbols with known intent or optional are really dummy
     variable.  Because of ENTRY statement, this has to be deferred
     until resolution time.  */

  if (!sym->attr.dummy
      && (sym->attr.optional || sym->attr.intent != INTENT_UNKNOWN))
    {
      gfc_error ("Symbol at %L is not a DUMMY variable", &sym->declared_at);
      return;
    }

  if (sym->attr.value && !sym->attr.dummy)
    {
      gfc_error ("%qs at %L cannot have the VALUE attribute because "
		 "it is not a dummy argument", sym->name, &sym->declared_at);
      return;
    }

  if (sym->attr.value && sym->ts.type == BT_CHARACTER)
    {
      gfc_charlen *cl = sym->ts.u.cl;
      if (!cl || !cl->length || cl->length->expr_type != EXPR_CONSTANT)
	{
	  gfc_error ("Character dummy variable %qs at %L with VALUE "
		     "attribute must have constant length",
		     sym->name, &sym->declared_at);
	  return;
	}

      if (sym->ts.is_c_interop
	  && mpz_cmp_si (cl->length->value.integer, 1) != 0)
	{
	  gfc_error ("C interoperable character dummy variable %qs at %L "
		     "with VALUE attribute must have length one",
		     sym->name, &sym->declared_at);
	  return;
	}
    }

  if (sym->ts.type == BT_DERIVED && !sym->attr.is_iso_c
      && sym->ts.u.derived->attr.generic)
    {
      sym->ts.u.derived = gfc_find_dt_in_generic (sym->ts.u.derived);
      if (!sym->ts.u.derived)
	{
	  gfc_error ("The derived type %qs at %L is of type %qs, "
		     "which has not been defined", sym->name,
		     &sym->declared_at, sym->ts.u.derived->name);
	  sym->ts.type = BT_UNKNOWN;
	  return;
	}
    }

    /* Use the same constraints as TYPE(*), except for the type check
       and that only scalars and assumed-size arrays are permitted.  */
    if (sym->attr.ext_attr & (1 << EXT_ATTR_NO_ARG_CHECK))
      {
	if (!sym->attr.dummy)
	  {
	    gfc_error ("Variable %s at %L with NO_ARG_CHECK attribute shall be "
		       "a dummy argument", sym->name, &sym->declared_at);
	    return;
	  }

	if (sym->ts.type != BT_ASSUMED && sym->ts.type != BT_INTEGER
	    && sym->ts.type != BT_REAL && sym->ts.type != BT_LOGICAL
	    && sym->ts.type != BT_COMPLEX)
	  {
	    gfc_error ("Variable %s at %L with NO_ARG_CHECK attribute shall be "
		       "of type TYPE(*) or of an numeric intrinsic type",
		       sym->name, &sym->declared_at);
	    return;
	  }

      if (sym->attr.allocatable || sym->attr.codimension
	  || sym->attr.pointer || sym->attr.value)
	{
	  gfc_error ("Variable %s at %L with NO_ARG_CHECK attribute may not "
		     "have the ALLOCATABLE, CODIMENSION, POINTER or VALUE "
		     "attribute", sym->name, &sym->declared_at);
	  return;
	}

      if (sym->attr.intent == INTENT_OUT)
	{
	  gfc_error ("Variable %s at %L with NO_ARG_CHECK attribute may not "
		     "have the INTENT(OUT) attribute",
		     sym->name, &sym->declared_at);
	  return;
	}
      if (sym->attr.dimension && sym->as->type != AS_ASSUMED_SIZE)
	{
	  gfc_error ("Variable %s at %L with NO_ARG_CHECK attribute shall "
		     "either be a scalar or an assumed-size array",
		     sym->name, &sym->declared_at);
	  return;
	}

      /* Set the type to TYPE(*) and add a dimension(*) to ensure
	 NO_ARG_CHECK is correctly handled in trans*.c, e.g. with
	 packing.  */
      sym->ts.type = BT_ASSUMED;
      sym->as = gfc_get_array_spec ();
      sym->as->type = AS_ASSUMED_SIZE;
      sym->as->rank = 1;
      sym->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
    }
  else if (sym->ts.type == BT_ASSUMED)
    {
      /* TS 29113, C407a.  */
      if (!sym->attr.dummy)
	{
	  gfc_error ("Assumed type of variable %s at %L is only permitted "
		     "for dummy variables", sym->name, &sym->declared_at);
	  return;
	}
      if (sym->attr.allocatable || sym->attr.codimension
	  || sym->attr.pointer || sym->attr.value)
    	{
	  gfc_error ("Assumed-type variable %s at %L may not have the "
		     "ALLOCATABLE, CODIMENSION, POINTER or VALUE attribute",
		     sym->name, &sym->declared_at);
	  return;
	}
      if (sym->attr.intent == INTENT_OUT)
    	{
	  gfc_error ("Assumed-type variable %s at %L may not have the "
		     "INTENT(OUT) attribute",
		     sym->name, &sym->declared_at);
	  return;
	}
      if (sym->attr.dimension && sym->as->type == AS_EXPLICIT)
	{
	  gfc_error ("Assumed-type variable %s at %L shall not be an "
		     "explicit-shape array", sym->name, &sym->declared_at);
	  return;
	}
    }

  /* If the symbol is marked as bind(c), that it is declared at module level
     scope and verify its type and kind.  Do not do the latter for symbols
     that are implicitly typed because that is handled in
     gfc_set_default_type.  Handle dummy arguments and procedure definitions
     separately.  Also, anything that is use associated is not handled here
     but instead is handled in the module it is declared in.  Finally, derived
     type definitions are allowed to be BIND(C) since that only implies that
     they're interoperable, and they are checked fully for interoperability
     when a variable is declared of that type.  */
  if (sym->attr.is_bind_c && sym->attr.use_assoc == 0
      && sym->attr.dummy == 0 && sym->attr.flavor != FL_PROCEDURE
      && sym->attr.flavor != FL_DERIVED)
    {
      bool t = true;

      /* First, make sure the variable is declared at the
	 module-level scope (J3/04-007, Section 15.3).	*/
      if (sym->ns->proc_name->attr.flavor != FL_MODULE &&
          sym->attr.in_common == 0)
	{
	  gfc_error ("Variable %qs at %L cannot be BIND(C) because it "
		     "is neither a COMMON block nor declared at the "
		     "module level scope", sym->name, &(sym->declared_at));
	  t = false;
	}
      else if (sym->ts.type == BT_CHARACTER
	       && (sym->ts.u.cl == NULL || sym->ts.u.cl->length == NULL
		   || !gfc_is_constant_expr (sym->ts.u.cl->length)
		   || mpz_cmp_si (sym->ts.u.cl->length->value.integer, 1) != 0))
	{
	  gfc_error ("BIND(C) Variable %qs at %L must have length one",
		     sym->name, &sym->declared_at);
	  t = false;
	}
      else if (sym->common_head != NULL && sym->attr.implicit_type == 0)
        {
          t = verify_com_block_vars_c_interop (sym->common_head);
        }
      else if (sym->attr.implicit_type == 0)
	{
	  /* If type() declaration, we need to verify that the components
	     of the given type are all C interoperable, etc.  */
	  if (sym->ts.type == BT_DERIVED &&
              sym->ts.u.derived->attr.is_c_interop != 1)
            {
              /* Make sure the user marked the derived type as BIND(C).  If
                 not, call the verify routine.  This could print an error
                 for the derived type more than once if multiple variables
                 of that type are declared.  */
              if (sym->ts.u.derived->attr.is_bind_c != 1)
                verify_bind_c_derived_type (sym->ts.u.derived);
              t = false;
            }

	  /* Verify the variable itself as C interoperable if it
             is BIND(C).  It is not possible for this to succeed if
             the verify_bind_c_derived_type failed, so don't have to handle
             any error returned by verify_bind_c_derived_type.  */
          t = verify_bind_c_sym (sym, &(sym->ts), sym->attr.in_common,
                                 sym->common_block);
	}

      if (!t)
        {
          /* clear the is_bind_c flag to prevent reporting errors more than
             once if something failed.  */
          sym->attr.is_bind_c = 0;
          return;
        }
    }

  /* If a derived type symbol has reached this point, without its
     type being declared, we have an error.  Notice that most
     conditions that produce undefined derived types have already
     been dealt with.  However, the likes of:
     implicit type(t) (t) ..... call foo (t) will get us here if
     the type is not declared in the scope of the implicit
     statement. Change the type to BT_UNKNOWN, both because it is so
     and to prevent an ICE.  */
  if (sym->ts.type == BT_DERIVED && !sym->attr.is_iso_c
      && sym->ts.u.derived->components == NULL
      && !sym->ts.u.derived->attr.zero_comp)
    {
      gfc_error ("The derived type %qs at %L is of type %qs, "
		 "which has not been defined", sym->name,
		  &sym->declared_at, sym->ts.u.derived->name);
      sym->ts.type = BT_UNKNOWN;
      return;
    }

  /* Make sure that the derived type has been resolved and that the
     derived type is visible in the symbol's namespace, if it is a
     module function and is not PRIVATE.  */
  if (sym->ts.type == BT_DERIVED
	&& sym->ts.u.derived->attr.use_assoc
	&& sym->ns->proc_name
	&& sym->ns->proc_name->attr.flavor == FL_MODULE
        && !resolve_fl_derived (sym->ts.u.derived))
    return;

  /* Unless the derived-type declaration is use associated, Fortran 95
     does not allow public entries of private derived types.
     See 4.4.1 (F95) and 4.5.1.1 (F2003); and related interpretation
     161 in 95-006r3.  */
  if (sym->ts.type == BT_DERIVED
      && sym->ns->proc_name && sym->ns->proc_name->attr.flavor == FL_MODULE
      && !sym->ts.u.derived->attr.use_assoc
      && gfc_check_symbol_access (sym)
      && !gfc_check_symbol_access (sym->ts.u.derived)
      && !gfc_notify_std (GFC_STD_F2003, "PUBLIC %s %qs at %L of PRIVATE "
			  "derived type %qs",
			  (sym->attr.flavor == FL_PARAMETER)
			  ? "parameter" : "variable",
			  sym->name, &sym->declared_at,
			  sym->ts.u.derived->name))
    return;

  /* F2008, C1302.  */
  if (sym->ts.type == BT_DERIVED
      && ((sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
	   && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
	  || sym->ts.u.derived->attr.lock_comp)
      && !sym->attr.codimension && !sym->ts.u.derived->attr.coarray_comp)
    {
      gfc_error ("Variable %s at %L of type LOCK_TYPE or with subcomponent of "
		 "type LOCK_TYPE must be a coarray", sym->name,
		 &sym->declared_at);
      return;
    }

  /* TS18508, C702/C703.  */
  if (sym->ts.type == BT_DERIVED
      && ((sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
	   && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
	  || sym->ts.u.derived->attr.event_comp)
      && !sym->attr.codimension && !sym->ts.u.derived->attr.coarray_comp)
    {
      gfc_error ("Variable %s at %L of type EVENT_TYPE or with subcomponent of "
		 "type EVENT_TYPE must be a coarray", sym->name,
		 &sym->declared_at);
      return;
    }

  /* An assumed-size array with INTENT(OUT) shall not be of a type for which
     default initialization is defined (5.1.2.4.4).  */
  if (sym->ts.type == BT_DERIVED
      && sym->attr.dummy
      && sym->attr.intent == INTENT_OUT
      && sym->as
      && sym->as->type == AS_ASSUMED_SIZE)
    {
      for (c = sym->ts.u.derived->components; c; c = c->next)
	{
	  if (c->initializer)
	    {
	      gfc_error ("The INTENT(OUT) dummy argument %qs at %L is "
			 "ASSUMED SIZE and so cannot have a default initializer",
			 sym->name, &sym->declared_at);
	      return;
	    }
	}
    }

  /* F2008, C542.  */
  if (sym->ts.type == BT_DERIVED && sym->attr.dummy
      && sym->attr.intent == INTENT_OUT && sym->attr.lock_comp)
    {
      gfc_error ("Dummy argument %qs at %L of LOCK_TYPE shall not be "
		 "INTENT(OUT)", sym->name, &sym->declared_at);
      return;
    }

  /* TS18508.  */
  if (sym->ts.type == BT_DERIVED && sym->attr.dummy
      && sym->attr.intent == INTENT_OUT && sym->attr.event_comp)
    {
      gfc_error ("Dummy argument %qs at %L of EVENT_TYPE shall not be "
		 "INTENT(OUT)", sym->name, &sym->declared_at);
      return;
    }

  /* F2008, C525.  */
  if ((((sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.coarray_comp)
	 || (sym->ts.type == BT_CLASS && sym->attr.class_ok
	     && sym->ts.u.derived && CLASS_DATA (sym)
	     && CLASS_DATA (sym)->attr.coarray_comp))
       || class_attr.codimension)
      && (sym->attr.result || sym->result == sym))
    {
      gfc_error ("Function result %qs at %L shall not be a coarray or have "
	         "a coarray component", sym->name, &sym->declared_at);
      return;
    }

  /* F2008, C524.  */
  if (sym->attr.codimension && sym->ts.type == BT_DERIVED
      && sym->ts.u.derived->ts.is_iso_c)
    {
      gfc_error ("Variable %qs at %L of TYPE(C_PTR) or TYPE(C_FUNPTR) "
		 "shall not be a coarray", sym->name, &sym->declared_at);
      return;
    }

  /* F2008, C525.  */
  if (((sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.coarray_comp)
	|| (sym->ts.type == BT_CLASS && sym->attr.class_ok
	    && sym->ts.u.derived && CLASS_DATA (sym)
	    && CLASS_DATA (sym)->attr.coarray_comp))
      && (class_attr.codimension || class_attr.pointer || class_attr.dimension
	  || class_attr.allocatable))
    {
      gfc_error ("Variable %qs at %L with coarray component shall be a "
		 "nonpointer, nonallocatable scalar, which is not a coarray",
		 sym->name, &sym->declared_at);
      return;
    }

  /* F2008, C526.  The function-result case was handled above.  */
  if (class_attr.codimension
      && !(class_attr.allocatable || sym->attr.dummy || sym->attr.save
	   || sym->attr.select_type_temporary
	   || sym->attr.associate_var
	   || (sym->ns->save_all && !sym->attr.automatic)
	   || sym->ns->proc_name->attr.flavor == FL_MODULE
	   || sym->ns->proc_name->attr.is_main_program
	   || sym->attr.function || sym->attr.result || sym->attr.use_assoc))
    {
      gfc_error ("Variable %qs at %L is a coarray and is not ALLOCATABLE, SAVE "
		 "nor a dummy argument", sym->name, &sym->declared_at);
      return;
    }
  /* F2008, C528.  */
  else if (class_attr.codimension && !sym->attr.select_type_temporary
	   && !class_attr.allocatable && as && as->cotype == AS_DEFERRED)
    {
      gfc_error ("Coarray variable %qs at %L shall not have codimensions with "
		 "deferred shape", sym->name, &sym->declared_at);
      return;
    }
  else if (class_attr.codimension && class_attr.allocatable && as
	   && (as->cotype != AS_DEFERRED || as->type != AS_DEFERRED))
    {
      gfc_error ("Allocatable coarray variable %qs at %L must have "
		 "deferred shape", sym->name, &sym->declared_at);
      return;
    }

  /* F2008, C541.  */
  if ((((sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.coarray_comp)
	|| (sym->ts.type == BT_CLASS && sym->attr.class_ok
	    && sym->ts.u.derived && CLASS_DATA (sym)
	    && CLASS_DATA (sym)->attr.coarray_comp))
       || (class_attr.codimension && class_attr.allocatable))
      && sym->attr.dummy && sym->attr.intent == INTENT_OUT)
    {
      gfc_error ("Variable %qs at %L is INTENT(OUT) and can thus not be an "
		 "allocatable coarray or have coarray components",
		 sym->name, &sym->declared_at);
      return;
    }

  if (class_attr.codimension && sym->attr.dummy
      && sym->ns->proc_name && sym->ns->proc_name->attr.is_bind_c)
    {
      gfc_error ("Coarray dummy variable %qs at %L not allowed in BIND(C) "
		 "procedure %qs", sym->name, &sym->declared_at,
		 sym->ns->proc_name->name);
      return;
    }

  if (sym->ts.type == BT_LOGICAL
      && ((sym->attr.function && sym->attr.is_bind_c && sym->result == sym)
	  || ((sym->attr.dummy || sym->attr.result) && sym->ns->proc_name
	      && sym->ns->proc_name->attr.is_bind_c)))
    {
      int i;
      for (i = 0; gfc_logical_kinds[i].kind; i++)
        if (gfc_logical_kinds[i].kind == sym->ts.kind)
          break;
      if (!gfc_logical_kinds[i].c_bool && sym->attr.dummy
	  && !gfc_notify_std (GFC_STD_GNU, "LOGICAL dummy argument %qs at "
			      "%L with non-C_Bool kind in BIND(C) procedure "
			      "%qs", sym->name, &sym->declared_at,
			      sym->ns->proc_name->name))
	return;
      else if (!gfc_logical_kinds[i].c_bool
	       && !gfc_notify_std (GFC_STD_GNU, "LOGICAL result variable "
				   "%qs at %L with non-C_Bool kind in "
				   "BIND(C) procedure %qs", sym->name,
				   &sym->declared_at,
				   sym->attr.function ? sym->name
				   : sym->ns->proc_name->name))
	return;
    }

  switch (sym->attr.flavor)
    {
    case FL_VARIABLE:
      if (!resolve_fl_variable (sym, mp_flag))
	return;
      break;

    case FL_PROCEDURE:
      if (sym->formal && !sym->formal_ns)
	{
	  /* Check that none of the arguments are a namelist.  */
	  gfc_formal_arglist *formal = sym->formal;

	  for (; formal; formal = formal->next)
	    if (formal->sym && formal->sym->attr.flavor == FL_NAMELIST)
	      {
		gfc_error ("Namelist %qs cannot be an argument to "
			   "subroutine or function at %L",
			   formal->sym->name, &sym->declared_at);
		return;
	      }
	}

      if (!resolve_fl_procedure (sym, mp_flag))
	return;
      break;

    case FL_NAMELIST:
      if (!resolve_fl_namelist (sym))
	return;
      break;

    case FL_PARAMETER:
      if (!resolve_fl_parameter (sym))
	return;
      break;

    default:
      break;
    }

  /* Resolve array specifier. Check as well some constraints
     on COMMON blocks.  */

  check_constant = sym->attr.in_common && !sym->attr.pointer;

  /* Set the formal_arg_flag so that check_conflict will not throw
     an error for host associated variables in the specification
     expression for an array_valued function.  */
  if ((sym->attr.function || sym->attr.result) && sym->as)
    formal_arg_flag = true;

  saved_specification_expr = specification_expr;
  specification_expr = true;
  gfc_resolve_array_spec (sym->as, check_constant);
  specification_expr = saved_specification_expr;

  formal_arg_flag = false;

  /* Resolve formal namespaces.  */
  if (sym->formal_ns && sym->formal_ns != gfc_current_ns
      && !sym->attr.contained && !sym->attr.intrinsic)
    gfc_resolve (sym->formal_ns);

  /* Make sure the formal namespace is present.  */
  if (sym->formal && !sym->formal_ns)
    {
      gfc_formal_arglist *formal = sym->formal;
      while (formal && !formal->sym)
	formal = formal->next;

      if (formal)
	{
	  sym->formal_ns = formal->sym->ns;
	  if (sym->formal_ns && sym->ns != formal->sym->ns)
	    sym->formal_ns->refs++;
	}
    }

  /* Check threadprivate restrictions.  */
  if (sym->attr.threadprivate
      && !(sym->attr.save || sym->attr.data || sym->attr.in_common)
      && !(sym->ns->save_all && !sym->attr.automatic)
      && sym->module == NULL
      && (sym->ns->proc_name == NULL
	  || (sym->ns->proc_name->attr.flavor != FL_MODULE
	      && !sym->ns->proc_name->attr.is_main_program)))
    gfc_error ("Threadprivate at %L isn't SAVEd", &sym->declared_at);

  /* Check omp declare target restrictions.  */
  if (sym->attr.omp_declare_target
      && sym->attr.flavor == FL_VARIABLE
      && !sym->attr.save
      && !(sym->ns->save_all && !sym->attr.automatic)
      && (!sym->attr.in_common
	  && sym->module == NULL
	  && (sym->ns->proc_name == NULL
	      || (sym->ns->proc_name->attr.flavor != FL_MODULE
		  && !sym->ns->proc_name->attr.is_main_program))))
    gfc_error ("!$OMP DECLARE TARGET variable %qs at %L isn't SAVEd",
	       sym->name, &sym->declared_at);

  /* If we have come this far we can apply default-initializers, as
     described in 14.7.5, to those variables that have not already
     been assigned one.  */
  if (sym->ts.type == BT_DERIVED
      && !sym->value
      && !sym->attr.allocatable
      && !sym->attr.alloc_comp)
    {
      symbol_attribute *a = &sym->attr;

      if ((!a->save && !a->dummy && !a->pointer
	   && !a->in_common && !a->use_assoc
	   && a->referenced
	   && !((a->function || a->result)
		&& (!a->dimension
		    || sym->ts.u.derived->attr.alloc_comp
		    || sym->ts.u.derived->attr.pointer_comp))
	   && !(a->function && sym != sym->result))
	  || (a->dummy && !a->pointer && a->intent == INTENT_OUT
	      && sym->ns->proc_name->attr.if_source != IFSRC_IFBODY))
	apply_default_init (sym);
      else if (a->function && sym->result && a->access != ACCESS_PRIVATE
	       && (sym->ts.u.derived->attr.alloc_comp
		   || sym->ts.u.derived->attr.pointer_comp))
	/* Mark the result symbol to be referenced, when it has allocatable
	   components.  */
	sym->result->attr.referenced = 1;
    }

  if (sym->ts.type == BT_CLASS && sym->ns == gfc_current_ns
      && sym->attr.dummy && sym->attr.intent == INTENT_OUT
      && sym->ns->proc_name->attr.if_source != IFSRC_IFBODY
      && !CLASS_DATA (sym)->attr.class_pointer
      && !CLASS_DATA (sym)->attr.allocatable)
    apply_default_init (sym);

  /* If this symbol has a type-spec, check it.  */
  if (sym->attr.flavor == FL_VARIABLE || sym->attr.flavor == FL_PARAMETER
      || (sym->attr.flavor == FL_PROCEDURE && sym->attr.function))
    if (!resolve_typespec_used (&sym->ts, &sym->declared_at, sym->name))
      return;

  if (sym->param_list)
    resolve_pdt (sym);
}


/************* Resolve DATA statements *************/

static struct
{
  gfc_data_value *vnode;
  mpz_t left;
}
values;


/* Advance the values structure to point to the next value in the data list.  */

static bool
next_data_value (void)
{
  while (mpz_cmp_ui (values.left, 0) == 0)
    {

      if (values.vnode->next == NULL)
	return false;

      values.vnode = values.vnode->next;
      mpz_set (values.left, values.vnode->repeat);
    }

  return true;
}


static bool
check_data_variable (gfc_data_variable *var, locus *where)
{
  gfc_expr *e;
  mpz_t size;
  mpz_t offset;
  bool t;
  ar_type mark = AR_UNKNOWN;
  int i;
  mpz_t section_index[GFC_MAX_DIMENSIONS];
  gfc_ref *ref;
  gfc_array_ref *ar;
  gfc_symbol *sym;
  int has_pointer;

  if (!gfc_resolve_expr (var->expr))
    return false;

  ar = NULL;
  mpz_init_set_si (offset, 0);
  e = var->expr;

  if (e->expr_type == EXPR_FUNCTION && e->value.function.isym
      && e->value.function.isym->id == GFC_ISYM_CAF_GET)
    e = e->value.function.actual->expr;

  if (e->expr_type != EXPR_VARIABLE)
    {
      gfc_error ("Expecting definable entity near %L", where);
      return false;
    }

  sym = e->symtree->n.sym;

  if (sym->ns->is_block_data && !sym->attr.in_common)
    {
      gfc_error ("BLOCK DATA element %qs at %L must be in COMMON",
		 sym->name, &sym->declared_at);
      return false;
    }

  if (e->ref == NULL && sym->as)
    {
      gfc_error ("DATA array %qs at %L must be specified in a previous"
		 " declaration", sym->name, where);
      return false;
    }

  if (gfc_is_coindexed (e))
    {
      gfc_error ("DATA element %qs at %L cannot have a coindex", sym->name,
		 where);
      return false;
    }

  has_pointer = sym->attr.pointer;

  for (ref = e->ref; ref; ref = ref->next)
    {
      if (ref->type == REF_COMPONENT && ref->u.c.component->attr.pointer)
	has_pointer = 1;

      if (has_pointer)
	{
	  if (ref->type == REF_ARRAY && ref->u.ar.type != AR_FULL)
	    {
	      gfc_error ("DATA element %qs at %L is a pointer and so must "
			 "be a full array", sym->name, where);
	      return false;
	    }

	  if (values.vnode->expr->expr_type == EXPR_CONSTANT)
	    {
	      gfc_error ("DATA object near %L has the pointer attribute "
			 "and the corresponding DATA value is not a valid "
			 "initial-data-target", where);
	      return false;
	    }
	}

      if (ref->type == REF_COMPONENT && ref->u.c.component->attr.allocatable)
	{
	  gfc_error ("DATA element %qs at %L cannot have the ALLOCATABLE "
		     "attribute", ref->u.c.component->name, &e->where);
	  return false;
	}
    }

  if (e->rank == 0 || has_pointer)
    {
      mpz_init_set_ui (size, 1);
      ref = NULL;
    }
  else
    {
      ref = e->ref;

      /* Find the array section reference.  */
      for (ref = e->ref; ref; ref = ref->next)
	{
	  if (ref->type != REF_ARRAY)
	    continue;
	  if (ref->u.ar.type == AR_ELEMENT)
	    continue;
	  break;
	}
      gcc_assert (ref);

      /* Set marks according to the reference pattern.  */
      switch (ref->u.ar.type)
	{
	case AR_FULL:
	  mark = AR_FULL;
	  break;

	case AR_SECTION:
	  ar = &ref->u.ar;
	  /* Get the start position of array section.  */
	  gfc_get_section_index (ar, section_index, &offset);
	  mark = AR_SECTION;
	  break;

	default:
	  gcc_unreachable ();
	}

      if (!gfc_array_size (e, &size))
	{
	  gfc_error ("Nonconstant array section at %L in DATA statement",
		     where);
	  mpz_clear (offset);
	  return false;
	}
    }

  t = true;

  while (mpz_cmp_ui (size, 0) > 0)
    {
      if (!next_data_value ())
	{
	  gfc_error ("DATA statement at %L has more variables than values",
		     where);
	  t = false;
	  break;
	}

      t = gfc_check_assign (var->expr, values.vnode->expr, 0);
      if (!t)
	break;

      /* If we have more than one element left in the repeat count,
	 and we have more than one element left in the target variable,
	 then create a range assignment.  */
      /* FIXME: Only done for full arrays for now, since array sections
	 seem tricky.  */
      if (mark == AR_FULL && ref && ref->next == NULL
	  && mpz_cmp_ui (values.left, 1) > 0 && mpz_cmp_ui (size, 1) > 0)
	{
	  mpz_t range;

	  if (mpz_cmp (size, values.left) >= 0)
	    {
	      mpz_init_set (range, values.left);
	      mpz_sub (size, size, values.left);
	      mpz_set_ui (values.left, 0);
	    }
	  else
	    {
	      mpz_init_set (range, size);
	      mpz_sub (values.left, values.left, size);
	      mpz_set_ui (size, 0);
	    }

	  t = gfc_assign_data_value (var->expr, values.vnode->expr,
				     offset, &range);

	  mpz_add (offset, offset, range);
	  mpz_clear (range);

	  if (!t)
	    break;
	}

      /* Assign initial value to symbol.  */
      else
	{
	  mpz_sub_ui (values.left, values.left, 1);
	  mpz_sub_ui (size, size, 1);

	  t = gfc_assign_data_value (var->expr, values.vnode->expr,
				     offset, NULL);
	  if (!t)
	    break;

	  if (mark == AR_FULL)
	    mpz_add_ui (offset, offset, 1);

	  /* Modify the array section indexes and recalculate the offset
	     for next element.  */
	  else if (mark == AR_SECTION)
	    gfc_advance_section (section_index, ar, &offset);
	}
    }

  if (mark == AR_SECTION)
    {
      for (i = 0; i < ar->dimen; i++)
	mpz_clear (section_index[i]);
    }

  mpz_clear (size);
  mpz_clear (offset);

  return t;
}


static bool traverse_data_var (gfc_data_variable *, locus *);

/* Iterate over a list of elements in a DATA statement.  */

static bool
traverse_data_list (gfc_data_variable *var, locus *where)
{
  mpz_t trip;
  iterator_stack frame;
  gfc_expr *e, *start, *end, *step;
  bool retval = true;

  mpz_init (frame.value);
  mpz_init (trip);

  start = gfc_copy_expr (var->iter.start);
  end = gfc_copy_expr (var->iter.end);
  step = gfc_copy_expr (var->iter.step);

  if (!gfc_simplify_expr (start, 1)
      || start->expr_type != EXPR_CONSTANT)
    {
      gfc_error ("start of implied-do loop at %L could not be "
		 "simplified to a constant value", &start->where);
      retval = false;
      goto cleanup;
    }
  if (!gfc_simplify_expr (end, 1)
      || end->expr_type != EXPR_CONSTANT)
    {
      gfc_error ("end of implied-do loop at %L could not be "
		 "simplified to a constant value", &end->where);
      retval = false;
      goto cleanup;
    }
  if (!gfc_simplify_expr (step, 1)
      || step->expr_type != EXPR_CONSTANT)
    {
      gfc_error ("step of implied-do loop at %L could not be "
		 "simplified to a constant value", &step->where);
      retval = false;
      goto cleanup;
    }
  if (mpz_cmp_si (step->value.integer, 0) == 0)
    {
      gfc_error ("step of implied-do loop at %L shall not be zero",
		 &step->where);
      retval = false;
      goto cleanup;
    }

  mpz_set (trip, end->value.integer);
  mpz_sub (trip, trip, start->value.integer);
  mpz_add (trip, trip, step->value.integer);

  mpz_div (trip, trip, step->value.integer);

  mpz_set (frame.value, start->value.integer);

  frame.prev = iter_stack;
  frame.variable = var->iter.var->symtree;
  iter_stack = &frame;

  while (mpz_cmp_ui (trip, 0) > 0)
    {
      if (!traverse_data_var (var->list, where))
	{
	  retval = false;
	  goto cleanup;
	}

      e = gfc_copy_expr (var->expr);
      if (!gfc_simplify_expr (e, 1))
	{
	  gfc_free_expr (e);
	  retval = false;
	  goto cleanup;
	}

      mpz_add (frame.value, frame.value, step->value.integer);

      mpz_sub_ui (trip, trip, 1);
    }

cleanup:
  mpz_clear (frame.value);
  mpz_clear (trip);

  gfc_free_expr (start);
  gfc_free_expr (end);
  gfc_free_expr (step);

  iter_stack = frame.prev;
  return retval;
}


/* Type resolve variables in the variable list of a DATA statement.  */

static bool
traverse_data_var (gfc_data_variable *var, locus *where)
{
  bool t;

  for (; var; var = var->next)
    {
      if (var->expr == NULL)
	t = traverse_data_list (var, where);
      else
	t = check_data_variable (var, where);

      if (!t)
	return false;
    }

  return true;
}


/* Resolve the expressions and iterators associated with a data statement.
   This is separate from the assignment checking because data lists should
   only be resolved once.  */

static bool
resolve_data_variables (gfc_data_variable *d)
{
  for (; d; d = d->next)
    {
      if (d->list == NULL)
	{
	  if (!gfc_resolve_expr (d->expr))
	    return false;
	}
      else
	{
	  if (!gfc_resolve_iterator (&d->iter, false, true))
	    return false;

	  if (!resolve_data_variables (d->list))
	    return false;
	}
    }

  return true;
}


/* Resolve a single DATA statement.  We implement this by storing a pointer to
   the value list into static variables, and then recursively traversing the
   variables list, expanding iterators and such.  */

static void
resolve_data (gfc_data *d)
{

  if (!resolve_data_variables (d->var))
    return;

  values.vnode = d->value;
  if (d->value == NULL)
    mpz_set_ui (values.left, 0);
  else
    mpz_set (values.left, d->value->repeat);

  if (!traverse_data_var (d->var, &d->where))
    return;

  /* At this point, we better not have any values left.  */

  if (next_data_value ())
    gfc_error ("DATA statement at %L has more values than variables",
	       &d->where);
}


/* 12.6 Constraint: In a pure subprogram any variable which is in common or
   accessed by host or use association, is a dummy argument to a pure function,
   is a dummy argument with INTENT (IN) to a pure subroutine, or an object that
   is storage associated with any such variable, shall not be used in the
   following contexts: (clients of this function).  */

/* Determines if a variable is not 'pure', i.e., not assignable within a pure
   procedure.  Returns zero if assignment is OK, nonzero if there is a
   problem.  */
int
gfc_impure_variable (gfc_symbol *sym)
{
  gfc_symbol *proc;
  gfc_namespace *ns;

  if (sym->attr.use_assoc || sym->attr.in_common)
    return 1;

  /* Check if the symbol's ns is inside the pure procedure.  */
  for (ns = gfc_current_ns; ns; ns = ns->parent)
    {
      if (ns == sym->ns)
	break;
      if (ns->proc_name->attr.flavor == FL_PROCEDURE && !sym->attr.function)
	return 1;
    }

  proc = sym->ns->proc_name;
  if (sym->attr.dummy
      && !sym->attr.value
      && ((proc->attr.subroutine && sym->attr.intent == INTENT_IN)
	  || proc->attr.function))
    return 1;

  /* TODO: Sort out what can be storage associated, if anything, and include
     it here.  In principle equivalences should be scanned but it does not
     seem to be possible to storage associate an impure variable this way.  */
  return 0;
}


/* Test whether a symbol is pure or not.  For a NULL pointer, checks if the
   current namespace is inside a pure procedure.  */

int
gfc_pure (gfc_symbol *sym)
{
  symbol_attribute attr;
  gfc_namespace *ns;

  if (sym == NULL)
    {
      /* Check if the current namespace or one of its parents
	belongs to a pure procedure.  */
      for (ns = gfc_current_ns; ns; ns = ns->parent)
	{
	  sym = ns->proc_name;
	  if (sym == NULL)
	    return 0;
	  attr = sym->attr;
	  if (attr.flavor == FL_PROCEDURE && attr.pure)
	    return 1;
	}
      return 0;
    }

  attr = sym->attr;

  return attr.flavor == FL_PROCEDURE && attr.pure;
}


/* Test whether a symbol is implicitly pure or not.  For a NULL pointer,
   checks if the current namespace is implicitly pure.  Note that this
   function returns false for a PURE procedure.  */

int
gfc_implicit_pure (gfc_symbol *sym)
{
  gfc_namespace *ns;

  if (sym == NULL)
    {
      /* Check if the current procedure is implicit_pure.  Walk up
	 the procedure list until we find a procedure.  */
      for (ns = gfc_current_ns; ns; ns = ns->parent)
	{
	  sym = ns->proc_name;
	  if (sym == NULL)
	    return 0;

	  if (sym->attr.flavor == FL_PROCEDURE)
	    break;
	}
    }

  return sym->attr.flavor == FL_PROCEDURE && sym->attr.implicit_pure
    && !sym->attr.pure;
}


void
gfc_unset_implicit_pure (gfc_symbol *sym)
{
  gfc_namespace *ns;

  if (sym == NULL)
    {
      /* Check if the current procedure is implicit_pure.  Walk up
	 the procedure list until we find a procedure.  */
      for (ns = gfc_current_ns; ns; ns = ns->parent)
	{
	  sym = ns->proc_name;
	  if (sym == NULL)
	    return;

	  if (sym->attr.flavor == FL_PROCEDURE)
	    break;
	}
    }

  if (sym->attr.flavor == FL_PROCEDURE)
    sym->attr.implicit_pure = 0;
  else
    sym->attr.pure = 0;
}


/* Test whether the current procedure is elemental or not.  */

int
gfc_elemental (gfc_symbol *sym)
{
  symbol_attribute attr;

  if (sym == NULL)
    sym = gfc_current_ns->proc_name;
  if (sym == NULL)
    return 0;
  attr = sym->attr;

  return attr.flavor == FL_PROCEDURE && attr.elemental;
}


/* Warn about unused labels.  */

static void
warn_unused_fortran_label (gfc_st_label *label)
{
  if (label == NULL)
    return;

  warn_unused_fortran_label (label->left);

  if (label->defined == ST_LABEL_UNKNOWN)
    return;

  switch (label->referenced)
    {
    case ST_LABEL_UNKNOWN:
      gfc_warning (OPT_Wunused_label, "Label %d at %L defined but not used",
		   label->value, &label->where);
      break;

    case ST_LABEL_BAD_TARGET:
      gfc_warning (OPT_Wunused_label,
		   "Label %d at %L defined but cannot be used",
		   label->value, &label->where);
      break;

    default:
      break;
    }

  warn_unused_fortran_label (label->right);
}


/* Returns the sequence type of a symbol or sequence.  */

static seq_type
sequence_type (gfc_typespec ts)
{
  seq_type result;
  gfc_component *c;

  switch (ts.type)
  {
    case BT_DERIVED:

      if (ts.u.derived->components == NULL)
	return SEQ_NONDEFAULT;

      result = sequence_type (ts.u.derived->components->ts);
      for (c = ts.u.derived->components->next; c; c = c->next)
	if (sequence_type (c->ts) != result)
	  return SEQ_MIXED;

      return result;

    case BT_CHARACTER:
      if (ts.kind != gfc_default_character_kind)
	  return SEQ_NONDEFAULT;

      return SEQ_CHARACTER;

    case BT_INTEGER:
      if (ts.kind != gfc_default_integer_kind)
	  return SEQ_NONDEFAULT;

      return SEQ_NUMERIC;

    case BT_REAL:
      if (!(ts.kind == gfc_default_real_kind
	    || ts.kind == gfc_default_double_kind))
	  return SEQ_NONDEFAULT;

      return SEQ_NUMERIC;

    case BT_COMPLEX:
      if (ts.kind != gfc_default_complex_kind)
	  return SEQ_NONDEFAULT;

      return SEQ_NUMERIC;

    case BT_LOGICAL:
      if (ts.kind != gfc_default_logical_kind)
	  return SEQ_NONDEFAULT;

      return SEQ_NUMERIC;

    default:
      return SEQ_NONDEFAULT;
  }
}


/* Resolve derived type EQUIVALENCE object.  */

static bool
resolve_equivalence_derived (gfc_symbol *derived, gfc_symbol *sym, gfc_expr *e)
{
  gfc_component *c = derived->components;

  if (!derived)
    return true;

  /* Shall not be an object of nonsequence derived type.  */
  if (!derived->attr.sequence)
    {
      gfc_error ("Derived type variable %qs at %L must have SEQUENCE "
		 "attribute to be an EQUIVALENCE object", sym->name,
		 &e->where);
      return false;
    }

  /* Shall not have allocatable components.  */
  if (derived->attr.alloc_comp)
    {
      gfc_error ("Derived type variable %qs at %L cannot have ALLOCATABLE "
		 "components to be an EQUIVALENCE object",sym->name,
		 &e->where);
      return false;
    }

  if (sym->attr.in_common && gfc_has_default_initializer (sym->ts.u.derived))
    {
      gfc_error ("Derived type variable %qs at %L with default "
		 "initialization cannot be in EQUIVALENCE with a variable "
		 "in COMMON", sym->name, &e->where);
      return false;
    }

  for (; c ; c = c->next)
    {
      if (gfc_bt_struct (c->ts.type)
	  && (!resolve_equivalence_derived(c->ts.u.derived, sym, e)))
	return false;

      /* Shall not be an object of sequence derived type containing a pointer
	 in the structure.  */
      if (c->attr.pointer)
	{
	  gfc_error ("Derived type variable %qs at %L with pointer "
		     "component(s) cannot be an EQUIVALENCE object",
		     sym->name, &e->where);
	  return false;
	}
    }
  return true;
}


/* Resolve equivalence object.
   An EQUIVALENCE object shall not be a dummy argument, a pointer, a target,
   an allocatable array, an object of nonsequence derived type, an object of
   sequence derived type containing a pointer at any level of component
   selection, an automatic object, a function name, an entry name, a result
   name, a named constant, a structure component, or a subobject of any of
   the preceding objects.  A substring shall not have length zero.  A
   derived type shall not have components with default initialization nor
   shall two objects of an equivalence group be initialized.
   Either all or none of the objects shall have an protected attribute.
   The simple constraints are done in symbol.c(check_conflict) and the rest
   are implemented here.  */

static void
resolve_equivalence (gfc_equiv *eq)
{
  gfc_symbol *sym;
  gfc_symbol *first_sym;
  gfc_expr *e;
  gfc_ref *r;
  locus *last_where = NULL;
  seq_type eq_type, last_eq_type;
  gfc_typespec *last_ts;
  int object, cnt_protected;
  const char *msg;

  last_ts = &eq->expr->symtree->n.sym->ts;

  first_sym = eq->expr->symtree->n.sym;

  cnt_protected = 0;

  for (object = 1; eq; eq = eq->eq, object++)
    {
      e = eq->expr;

      e->ts = e->symtree->n.sym->ts;
      /* match_varspec might not know yet if it is seeing
	 array reference or substring reference, as it doesn't
	 know the types.  */
      if (e->ref && e->ref->type == REF_ARRAY)
	{
	  gfc_ref *ref = e->ref;
	  sym = e->symtree->n.sym;

	  if (sym->attr.dimension)
	    {
	      ref->u.ar.as = sym->as;
	      ref = ref->next;
	    }

	  /* For substrings, convert REF_ARRAY into REF_SUBSTRING.  */
	  if (e->ts.type == BT_CHARACTER
	      && ref
	      && ref->type == REF_ARRAY
	      && ref->u.ar.dimen == 1
	      && ref->u.ar.dimen_type[0] == DIMEN_RANGE
	      && ref->u.ar.stride[0] == NULL)
	    {
	      gfc_expr *start = ref->u.ar.start[0];
	      gfc_expr *end = ref->u.ar.end[0];
	      void *mem = NULL;

	      /* Optimize away the (:) reference.  */
	      if (start == NULL && end == NULL)
		{
		  if (e->ref == ref)
		    e->ref = ref->next;
		  else
		    e->ref->next = ref->next;
		  mem = ref;
		}
	      else
		{
		  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 && e->ts.u.cl)
		    end = gfc_copy_expr (e->ts.u.cl->length);
		  ref->u.ss.end = end;
		  ref->u.ss.length = e->ts.u.cl;
		  e->ts.u.cl = NULL;
		}
	      ref = ref->next;
	      free (mem);
	    }

	  /* Any further ref is an error.  */
	  if (ref)
	    {
	      gcc_assert (ref->type == REF_ARRAY);
	      gfc_error ("Syntax error in EQUIVALENCE statement at %L",
			 &ref->u.ar.where);
	      continue;
	    }
	}

      if (!gfc_resolve_expr (e))
	continue;

      sym = e->symtree->n.sym;

      if (sym->attr.is_protected)
	cnt_protected++;
      if (cnt_protected > 0 && cnt_protected != object)
       	{
	      gfc_error ("Either all or none of the objects in the "
			 "EQUIVALENCE set at %L shall have the "
			 "PROTECTED attribute",
			 &e->where);
	      break;
	}

      /* Shall not equivalence common block variables in a PURE procedure.  */
      if (sym->ns->proc_name
	  && sym->ns->proc_name->attr.pure
	  && sym->attr.in_common)
	{
	  /* Need to check for symbols that may have entered the pure
	     procedure via a USE statement.  */
	  bool saw_sym = false;
	  if (sym->ns->use_stmts)
	    {
	      gfc_use_rename *r;
	      for (r = sym->ns->use_stmts->rename; r; r = r->next)
		if (strcmp(r->use_name, sym->name) == 0) saw_sym = true;
	    }
	  else
	    saw_sym = true;

	  if (saw_sym)
	    gfc_error ("COMMON block member %qs at %L cannot be an "
		       "EQUIVALENCE object in the pure procedure %qs",
		       sym->name, &e->where, sym->ns->proc_name->name);
	  break;
	}

      /* Shall not be a named constant.  */
      if (e->expr_type == EXPR_CONSTANT)
	{
	  gfc_error ("Named constant %qs at %L cannot be an EQUIVALENCE "
		     "object", sym->name, &e->where);
	  continue;
	}

      if (e->ts.type == BT_DERIVED
	  && !resolve_equivalence_derived (e->ts.u.derived, sym, e))
	continue;

      /* Check that the types correspond correctly:
	 Note 5.28:
	 A numeric sequence structure may be equivalenced to another sequence
	 structure, an object of default integer type, default real type, double
	 precision real type, default logical type such that components of the
	 structure ultimately only become associated to objects of the same
	 kind. A character sequence structure may be equivalenced to an object
	 of default character kind or another character sequence structure.
	 Other objects may be equivalenced only to objects of the same type and
	 kind parameters.  */

      /* Identical types are unconditionally OK.  */
      if (object == 1 || gfc_compare_types (last_ts, &sym->ts))
	goto identical_types;

      last_eq_type = sequence_type (*last_ts);
      eq_type = sequence_type (sym->ts);

      /* Since the pair of objects is not of the same type, mixed or
	 non-default sequences can be rejected.  */

      msg = "Sequence %s with mixed components in EQUIVALENCE "
	    "statement at %L with different type objects";
      if ((object ==2
	   && last_eq_type == SEQ_MIXED
	   && !gfc_notify_std (GFC_STD_GNU, msg, first_sym->name, last_where))
	  || (eq_type == SEQ_MIXED
	      && !gfc_notify_std (GFC_STD_GNU, msg, sym->name, &e->where)))
	continue;

      msg = "Non-default type object or sequence %s in EQUIVALENCE "
	    "statement at %L with objects of different type";
      if ((object ==2
	   && last_eq_type == SEQ_NONDEFAULT
	   && !gfc_notify_std (GFC_STD_GNU, msg, first_sym->name, last_where))
	  || (eq_type == SEQ_NONDEFAULT
	      && !gfc_notify_std (GFC_STD_GNU, msg, sym->name, &e->where)))
	continue;

      msg ="Non-CHARACTER object %qs in default CHARACTER "
	   "EQUIVALENCE statement at %L";
      if (last_eq_type == SEQ_CHARACTER
	  && eq_type != SEQ_CHARACTER
	  && !gfc_notify_std (GFC_STD_GNU, msg, sym->name, &e->where))
		continue;

      msg ="Non-NUMERIC object %qs in default NUMERIC "
	   "EQUIVALENCE statement at %L";
      if (last_eq_type == SEQ_NUMERIC
	  && eq_type != SEQ_NUMERIC
	  && !gfc_notify_std (GFC_STD_GNU, msg, sym->name, &e->where))
		continue;

identical_types:

      last_ts =&sym->ts;
      last_where = &e->where;

      if (!e->ref)
	continue;

      /* Shall not be an automatic array.  */
      if (e->ref->type == REF_ARRAY && is_non_constant_shape_array (sym))
	{
	  gfc_error ("Array %qs at %L with non-constant bounds cannot be "
		     "an EQUIVALENCE object", sym->name, &e->where);
	  continue;
	}

      r = e->ref;
      while (r)
	{
	  /* Shall not be a structure component.  */
	  if (r->type == REF_COMPONENT)
	    {
	      gfc_error ("Structure component %qs at %L cannot be an "
			 "EQUIVALENCE object",
			 r->u.c.component->name, &e->where);
	      break;
	    }

	  /* A substring shall not have length zero.  */
	  if (r->type == REF_SUBSTRING)
	    {
	      if (compare_bound (r->u.ss.start, r->u.ss.end) == CMP_GT)
		{
		  gfc_error ("Substring at %L has length zero",
			     &r->u.ss.start->where);
		  break;
		}
	    }
	  r = r->next;
	}
    }
}


/* Function called by resolve_fntype to flag other symbols used in the
   length type parameter specification of function results.  */

static bool
flag_fn_result_spec (gfc_expr *expr,
                     gfc_symbol *sym,
                     int *f ATTRIBUTE_UNUSED)
{
  gfc_namespace *ns;
  gfc_symbol *s;

  if (expr->expr_type == EXPR_VARIABLE)
    {
      s = expr->symtree->n.sym;
      for (ns = s->ns; ns; ns = ns->parent)
	if (!ns->parent)
	  break;

      if (sym == s)
	{
	  gfc_error ("Self reference in character length expression "
		     "for %qs at %L", sym->name, &expr->where);
	  return true;
	}

      if (!s->fn_result_spec
	  && s->attr.flavor == FL_PARAMETER)
	{
	  /* Function contained in a module.... */
	  if (ns->proc_name && ns->proc_name->attr.flavor == FL_MODULE)
	    {
	      gfc_symtree *st;
	      s->fn_result_spec = 1;
	      /* Make sure that this symbol is translated as a module
		 variable.  */
	      st = gfc_get_unique_symtree (ns);
	      st->n.sym = s;
	      s->refs++;
	    }
	  /* ... which is use associated and called.  */
	  else if (s->attr.use_assoc || s->attr.used_in_submodule
			||
		  /* External function matched with an interface.  */
		  (s->ns->proc_name
		   && ((s->ns == ns
			 && s->ns->proc_name->attr.if_source == IFSRC_DECL)
		       || s->ns->proc_name->attr.if_source == IFSRC_IFBODY)
		   && s->ns->proc_name->attr.function))
	    s->fn_result_spec = 1;
	}
    }
  return false;
}


/* Resolve function and ENTRY types, issue diagnostics if needed.  */

static void
resolve_fntype (gfc_namespace *ns)
{
  gfc_entry_list *el;
  gfc_symbol *sym;

  if (ns->proc_name == NULL || !ns->proc_name->attr.function)
    return;

  /* If there are any entries, ns->proc_name is the entry master
     synthetic symbol and ns->entries->sym actual FUNCTION symbol.  */
  if (ns->entries)
    sym = ns->entries->sym;
  else
    sym = ns->proc_name;
  if (sym->result == sym
      && sym->ts.type == BT_UNKNOWN
      && !gfc_set_default_type (sym, 0, NULL)
      && !sym->attr.untyped)
    {
      gfc_error ("Function %qs at %L has no IMPLICIT type",
		 sym->name, &sym->declared_at);
      sym->attr.untyped = 1;
    }

  if (sym->ts.type == BT_DERIVED && !sym->ts.u.derived->attr.use_assoc
      && !sym->attr.contained
      && !gfc_check_symbol_access (sym->ts.u.derived)
      && gfc_check_symbol_access (sym))
    {
      gfc_notify_std (GFC_STD_F2003, "PUBLIC function %qs at "
		      "%L of PRIVATE type %qs", sym->name,
		      &sym->declared_at, sym->ts.u.derived->name);
    }

    if (ns->entries)
    for (el = ns->entries->next; el; el = el->next)
      {
	if (el->sym->result == el->sym
	    && el->sym->ts.type == BT_UNKNOWN
	    && !gfc_set_default_type (el->sym, 0, NULL)
	    && !el->sym->attr.untyped)
	  {
	    gfc_error ("ENTRY %qs at %L has no IMPLICIT type",
		       el->sym->name, &el->sym->declared_at);
	    el->sym->attr.untyped = 1;
	  }
      }

  if (sym->ts.type == BT_CHARACTER)
    gfc_traverse_expr (sym->ts.u.cl->length, sym, flag_fn_result_spec, 0);
}


/* 12.3.2.1.1 Defined operators.  */

static bool
check_uop_procedure (gfc_symbol *sym, locus where)
{
  gfc_formal_arglist *formal;

  if (!sym->attr.function)
    {
      gfc_error ("User operator procedure %qs at %L must be a FUNCTION",
		 sym->name, &where);
      return false;
    }

  if (sym->ts.type == BT_CHARACTER
      && !((sym->ts.u.cl && sym->ts.u.cl->length) || sym->ts.deferred)
      && !(sym->result && ((sym->result->ts.u.cl
	   && sym->result->ts.u.cl->length) || sym->result->ts.deferred)))
    {
      gfc_error ("User operator procedure %qs at %L cannot be assumed "
		 "character length", sym->name, &where);
      return false;
    }

  formal = gfc_sym_get_dummy_args (sym);
  if (!formal || !formal->sym)
    {
      gfc_error ("User operator procedure %qs at %L must have at least "
		 "one argument", sym->name, &where);
      return false;
    }

  if (formal->sym->attr.intent != INTENT_IN)
    {
      gfc_error ("First argument of operator interface at %L must be "
		 "INTENT(IN)", &where);
      return false;
    }

  if (formal->sym->attr.optional)
    {
      gfc_error ("First argument of operator interface at %L cannot be "
		 "optional", &where);
      return false;
    }

  formal = formal->next;
  if (!formal || !formal->sym)
    return true;

  if (formal->sym->attr.intent != INTENT_IN)
    {
      gfc_error ("Second argument of operator interface at %L must be "
		 "INTENT(IN)", &where);
      return false;
    }

  if (formal->sym->attr.optional)
    {
      gfc_error ("Second argument of operator interface at %L cannot be "
		 "optional", &where);
      return false;
    }

  if (formal->next)
    {
      gfc_error ("Operator interface at %L must have, at most, two "
		 "arguments", &where);
      return false;
    }

  return true;
}

static void
gfc_resolve_uops (gfc_symtree *symtree)
{
  gfc_interface *itr;

  if (symtree == NULL)
    return;

  gfc_resolve_uops (symtree->left);
  gfc_resolve_uops (symtree->right);

  for (itr = symtree->n.uop->op; itr; itr = itr->next)
    check_uop_procedure (itr->sym, itr->sym->declared_at);
}


/* Examine all of the expressions associated with a program unit,
   assign types to all intermediate expressions, make sure that all
   assignments are to compatible types and figure out which names
   refer to which functions or subroutines.  It doesn't check code
   block, which is handled by gfc_resolve_code.  */

static void
resolve_types (gfc_namespace *ns)
{
  gfc_namespace *n;
  gfc_charlen *cl;
  gfc_data *d;
  gfc_equiv *eq;
  gfc_namespace* old_ns = gfc_current_ns;
  bool recursive = ns->proc_name && ns->proc_name->attr.recursive;

  if (ns->types_resolved)
    return;

  /* Check that all IMPLICIT types are ok.  */
  if (!ns->seen_implicit_none)
    {
      unsigned letter;
      for (letter = 0; letter != GFC_LETTERS; ++letter)
	if (ns->set_flag[letter]
	    && !resolve_typespec_used (&ns->default_type[letter],
				       &ns->implicit_loc[letter], NULL))
	  return;
    }

  gfc_current_ns = ns;

  resolve_entries (ns);

  resolve_common_vars (&ns->blank_common, false);
  resolve_common_blocks (ns->common_root);

  resolve_contained_functions (ns);

  if (ns->proc_name && ns->proc_name->attr.flavor == FL_PROCEDURE
      && ns->proc_name->attr.if_source == IFSRC_IFBODY)
    gfc_resolve_formal_arglist (ns->proc_name);

  gfc_traverse_ns (ns, resolve_bind_c_derived_types);

  for (cl = ns->cl_list; cl; cl = cl->next)
    resolve_charlen (cl);

  gfc_traverse_ns (ns, resolve_symbol);

  resolve_fntype (ns);

  for (n = ns->contained; n; n = n->sibling)
    {
      if (gfc_pure (ns->proc_name) && !gfc_pure (n->proc_name))
	gfc_error ("Contained procedure %qs at %L of a PURE procedure must "
		   "also be PURE", n->proc_name->name,
		   &n->proc_name->declared_at);

      resolve_types (n);
    }

  forall_flag = 0;
  gfc_do_concurrent_flag = 0;
  gfc_check_interfaces (ns);

  gfc_traverse_ns (ns, resolve_values);

  if (ns->save_all || (!flag_automatic && !recursive))
    gfc_save_all (ns);

  iter_stack = NULL;
  for (d = ns->data; d; d = d->next)
    resolve_data (d);

  iter_stack = NULL;
  gfc_traverse_ns (ns, gfc_formalize_init_value);

  gfc_traverse_ns (ns, gfc_verify_binding_labels);

  for (eq = ns->equiv; eq; eq = eq->next)
    resolve_equivalence (eq);

  /* Warn about unused labels.  */
  if (warn_unused_label)
    warn_unused_fortran_label (ns->st_labels);

  gfc_resolve_uops (ns->uop_root);

  gfc_traverse_ns (ns, gfc_verify_DTIO_procedures);

  gfc_resolve_omp_declare_simd (ns);

  gfc_resolve_omp_udrs (ns->omp_udr_root);

  ns->types_resolved = 1;

  gfc_current_ns = old_ns;
}


/* Call gfc_resolve_code recursively.  */

static void
resolve_codes (gfc_namespace *ns)
{
  gfc_namespace *n;
  bitmap_obstack old_obstack;

  if (ns->resolved == 1)
    return;

  for (n = ns->contained; n; n = n->sibling)
    resolve_codes (n);

  gfc_current_ns = ns;

  /* Don't clear 'cs_base' if this is the namespace of a BLOCK construct.  */
  if (!(ns->proc_name && ns->proc_name->attr.flavor == FL_LABEL))
    cs_base = NULL;

  /* Set to an out of range value.  */
  current_entry_id = -1;

  old_obstack = labels_obstack;
  bitmap_obstack_initialize (&labels_obstack);

  gfc_resolve_oacc_declare (ns);
  gfc_resolve_oacc_routines (ns);
  gfc_resolve_omp_local_vars (ns);
  gfc_resolve_code (ns->code, ns);

  bitmap_obstack_release (&labels_obstack);
  labels_obstack = old_obstack;
}


/* This function is called after a complete program unit has been compiled.
   Its purpose is to examine all of the expressions associated with a program
   unit, assign types to all intermediate expressions, make sure that all
   assignments are to compatible types and figure out which names refer to
   which functions or subroutines.  */

void
gfc_resolve (gfc_namespace *ns)
{
  gfc_namespace *old_ns;
  code_stack *old_cs_base;
  struct gfc_omp_saved_state old_omp_state;

  if (ns->resolved)
    return;

  ns->resolved = -1;
  old_ns = gfc_current_ns;
  old_cs_base = cs_base;

  /* As gfc_resolve can be called during resolution of an OpenMP construct
     body, we should clear any state associated to it, so that say NS's
     DO loops are not interpreted as OpenMP loops.  */
  if (!ns->construct_entities)
    gfc_omp_save_and_clear_state (&old_omp_state);

  resolve_types (ns);
  component_assignment_level = 0;
  resolve_codes (ns);

  gfc_current_ns = old_ns;
  cs_base = old_cs_base;
  ns->resolved = 1;

  gfc_run_passes (ns);

  if (!ns->construct_entities)
    gfc_omp_restore_state (&old_omp_state);
}
