/* Perform type resolution on the various structures.
   Copyright (C) 2001-2020 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 && 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);
		    }
		}
	    }
	}
    }
  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;

  for (; csym; csym = csym->common_next)
    {
      /* 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 in cannot appear in COMMON at %L "
		       "[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;
	    }
	}

      /* Validate shape, except for dynamic or PDT arrays.  */
      if (cons->expr->expr_type == EXPR_ARRAY && rank == cons->expr->rank
	  && comp->as && !comp->attr.allocatable && !comp->attr.pointer
	  && !comp->attr.pdt_array)
	{
	  mpz_t len;
	  mpz_init (len);
	  for (int n = 0; n < rank; n++)
	    {
	      if (comp->as->upper[n]->expr_type != EXPR_CONSTANT
		  || comp->as->lower[n]->expr_type != EXPR_CONSTANT)
		{
		  gfc_error ("Bad array spec of component %qs referenced in "
			     "structure constructor at %L",
			     comp->name, &cons->expr->where);
		  t = false;
		  break;
		};
	      if (cons->expr->shape == NULL)
		continue;
	      mpz_set_ui (len, 1);
	      mpz_add (len, len, comp->as->upper[n]->value.integer);
	      mpz_sub (len, len, comp->as->lower[n]->value.integer);
	      if (mpz_cmp (cons->expr->shape[n], len) != 0)
		{
		  gfc_error ("The shape of component %qs in the structure "
			     "constructor at %L differs from the shape of the "
			     "declared component for dimension %d (%ld/%ld)",
			     comp->name, &cons->expr->where, n+1,
			     mpz_get_si (cons->expr->shape[n]),
			     mpz_get_si (len));
		  t = false;
		}
	    }
	  mpz_clear (len);
	}

      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))
	{
	  gfc_warning (OPT_Wpedantic,
		       "%qs at %L is an array and OPTIONAL; IF IT IS "
		       "MISSING, it cannot be the actual argument of an "
		       "ELEMENTAL procedure unless there is a non-optional "
		       "argument with the same rank (12.4.1.5)",
		       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);
	  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;

  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;

  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 ("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 ("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 = "Equality comparison for %s at %L";
		  else
		    msg = "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;
    }

  e->ts.type = BT_CHARACTER;
  e->ts.kind = gfc_default_character_kind;

  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
      && sym->assoc->target->ts.u.derived
      && CLASS_DATA (sym->assoc->target)
      && 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 = *gfc_get_array_ref();
	  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 && sym->ts.u.derived
      && CLASS_DATA (sym)
      && 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);

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

	      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.  */
  if (allocatable == 0 && pointer == 0 && !unlimited)
    {
      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)
    {
      gfc_check_vardef_context (stat, false, false, false,
				_("STAT variable"));

      if ((stat->ts.type != BT_INTEGER
	   && !(stat->ref && (stat->ref->type == REF_ARRAY
			      || stat->ref->type == REF_COMPONENT)))
	  || stat->rank > 0)
	gfc_error ("Stat-variable at %L must be a scalar INTEGER "
		   "variable", &stat->where);

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

  /* Check the errmsg variable.  */
  if (errmsg)
    {
      if (!stat)
	gfc_warning (0, "ERRMSG at %L is useless without a STAT tag",
		     &errmsg->where);

      gfc_check_vardef_context (errmsg, false, false, false,
				_("ERRMSG variable"));

      /* 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->ref
		&& (errmsg->ref->type == REF_ARRAY
		    || errmsg->ref->type == REF_COMPONENT)))
	  || 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);

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

  /* 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
	  && 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)
	{
	  if (!sym->ts.deferred)
	    {
	      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
	  && !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 && !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;
	  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
      && (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);

  /* Check ERRMSG.  */
  gfc_resolve_expr (code->expr3);
  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);
}


/* 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:
	  {
	    gfc_omp_atomic_op aop
	      = (gfc_omp_atomic_op) (b->ext.omp_atomic & GFC_OMP_ATOMIC_MASK);

	    /* Verify this before calling gfc_resolve_code, which might
	       change it.  */
	    gcc_assert (b->next && b->next->op == EXEC_ASSIGN);
	    gcc_assert (((aop != GFC_OMP_ATOMIC_CAPTURE)
			 && b->next->next == NULL)
			|| ((aop == GFC_OMP_ATOMIC_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_MASTER:
	case EXEC_OMP_ORDERED:
	case EXEC_OMP_PARALLEL:
	case EXEC_OMP_PARALLEL_DO:
	case EXEC_OMP_PARALLEL_DO_SIMD:
	case EXEC_OMP_PARALLEL_SECTIONS:
	case EXEC_OMP_PARALLEL_WORKSHARE:
	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_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_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_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.result = 0;
  tmp->n.sym->attr.flavor = FL_VARIABLE;
  tmp->n.sym->attr.dummy = 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)->expr2, 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_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 (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->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)->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_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_MASTER:
	case EXEC_OMP_ORDERED:
	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_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_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_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_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->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)
    || (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->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
	&& !(sym->ts.type == BT_DERIVED && sym->attr.intent == INTENT_OUT))
	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 && sym->attr.class_ok
		      && 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.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 (!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;
      specification_expr = true;
      gfc_resolve_array_spec (sym->result->as, false);
      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->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)))
    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)))
    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->intent == INTENT_OUT && !a->pointer))
	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
      && !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 (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);
}
