OSDN Git Service

2006-02-19 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / fortran / resolve.c
index 1dc4db8..97f10f3 100644 (file)
@@ -1,5 +1,6 @@
 /* Perform type resolution on the various stuctures.
-   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, 
+   Inc.
    Contributed by Andy Vaught
 
 This file is part of GCC.
@@ -16,14 +17,23 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330,Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor,Boston, MA
+02110-1301, USA.  */
+
 
 #include "config.h"
+#include "system.h"
 #include "gfortran.h"
 #include "arith.h"  /* For gfc_compare_expr().  */
-#include <assert.h>
-#include <string.h>
+#include "dependency.h"
+
+/* Types used in equivalence statements.  */
+
+typedef enum seq_type
+{
+  SEQ_NONDEFAULT, SEQ_NUMERIC, SEQ_CHARACTER, SEQ_MIXED
+}
+seq_type;
 
 /* Stack to push the current if we descend into a block during
    resolution.  See resolve_branch() and resolve_code().  */
@@ -38,10 +48,24 @@ code_stack;
 static code_stack *cs_base = NULL;
 
 
-/* Nonzero if we're inside a FORALL block */
+/* Nonzero if we're inside a FORALL block */
 
 static int forall_flag;
 
+/* Nonzero if we're inside a OpenMP WORKSHARE or PARALLEL WORKSHARE block.  */
+
+static int omp_workshare_flag;
+
+/* Nonzero if we are processing a formal arglist. The corresponding function
+   resets the flag each time that it is read.  */
+static int formal_arg_flag = 0;
+
+int
+gfc_is_formal_arg (void)
+{
+  return formal_arg_flag;
+}
+
 /* 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
@@ -70,6 +94,8 @@ resolve_formal_arglist (gfc_symbol * proc)
       || (sym->as && sym->as->rank > 0))
     proc->attr.always_explicit = 1;
 
+  formal_arg_flag = 1;
+
   for (f = proc->formal; f; f = f->next)
     {
       sym = f->sym;
@@ -116,16 +142,6 @@ resolve_formal_arglist (gfc_symbol * proc)
        {
          if (!sym->attr.function || sym->result == sym)
            gfc_set_default_type (sym, 1, sym->ns);
-         else
-           {
-              /* Set the type of the RESULT, then copy.  */
-             if (sym->result->ts.type == BT_UNKNOWN)
-               gfc_set_default_type (sym->result, 1, sym->result->ns);
-
-             sym->ts = sym->result->ts;
-             if (sym->as == NULL)
-               sym->as = gfc_copy_array_spec (sym->result->as);
-           }
        }
 
       gfc_resolve_array_spec (sym->as, 0);
@@ -150,7 +166,7 @@ resolve_formal_arglist (gfc_symbol * proc)
          A procedure specification would have already set the type.  */
 
       if (sym->attr.flavor == FL_UNKNOWN)
-       gfc_add_flavor (&sym->attr, FL_VARIABLE, &sym->declared_at);
+       gfc_add_flavor (&sym->attr, FL_VARIABLE, sym->name, &sym->declared_at);
 
       if (gfc_pure (proc))
        {
@@ -216,6 +232,7 @@ resolve_formal_arglist (gfc_symbol * proc)
             }
         }
     }
+  formal_arg_flag = 0;
 }
 
 
@@ -258,37 +275,39 @@ resolve_contained_fntype (gfc_symbol * sym, gfc_namespace * ns)
           || sym->attr.flavor == FL_VARIABLE))
     return;
 
-  /* Try to find out of what type the function is.  If there was an
-     explicit RESULT clause, try to get the type from it.  If the
-     function is never defined, set it to the implicit type.  If
-     even that fails, give up.  */
+  /* Try to find out of what the return type is.  */
   if (sym->result != NULL)
     sym = sym->result;
 
   if (sym->ts.type == BT_UNKNOWN)
     {
-      /* Assume we can find an implicit type.  */
-      t = SUCCESS;
+      t = gfc_set_default_type (sym, 0, ns);
 
-      if (sym->result == NULL)
-       t = gfc_set_default_type (sym, 0, ns);
-      else
+      if (t == FAILURE && !sym->attr.untyped)
        {
-         if (sym->result->ts.type == BT_UNKNOWN)
-           t = gfc_set_default_type (sym->result, 0, NULL);
-
-         sym->ts = sym->result->ts;
+         gfc_error ("Contained function '%s' at %L has no IMPLICIT type",
+                    sym->name, &sym->declared_at); /* FIXME */
+         sym->attr.untyped = 1;
        }
+    }
 
-      if (t == FAILURE)
-       gfc_error ("Contained function '%s' at %L has no IMPLICIT type",
-                   sym->name, &sym->declared_at); /* FIXME */
+  /*Fortran 95 Draft Standard, page 51, Section 5.1.1.5, on the Character type,
+    lists the only ways a character length value of * can be used: dummy arguments
+    of procedures, named constants, and function results in external functions.
+    Internal function results are not on that list; ergo, not permitted.  */
+
+  if (sym->ts.type == BT_CHARACTER)
+    {
+      gfc_charlen *cl = sym->ts.cl;
+      if (!cl || !cl->length)
+       gfc_error ("Character-valued internal function '%s' 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.   */
+   introduce duplicates.  */
 
 static void
 merge_argument_lists (gfc_symbol *proc, gfc_formal_arglist *new_args)
@@ -344,8 +363,8 @@ resolve_entries (gfc_namespace * ns)
   if (ns->proc_name->attr.entry_master)
     return;
 
-  /* If this isn't a procedure something as gone horribly wrong.   */
-  assert (ns->proc_name->attr.flavor == FL_PROCEDURE);
+  /* 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;
@@ -369,21 +388,126 @@ resolve_entries (gfc_namespace * ns)
 
   /* Create a new symbol for the master function.  */
   /* Give the internal function a unique name (within this file).
-     Also include teh function name so the user has some hope of figuring
-     out whats going on.  */
+     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);
-  name[GFC_MAX_SYMBOL_LEN] = '\0';
   gfc_get_ha_symbol (name, &proc);
-  assert (proc != NULL);
+  gcc_assert (proc != NULL);
 
-  gfc_add_procedure (&proc->attr, PROC_INTERNAL, NULL);
+  gfc_add_procedure (&proc->attr, PROC_INTERNAL, proc->name, NULL);
   if (ns->proc_name->attr.subroutine)
-    gfc_add_subroutine (&proc->attr, NULL);
+    gfc_add_subroutine (&proc->attr, proc->name, NULL);
   else
     {
-      gfc_add_function (&proc->attr, NULL);
-      gfc_internal_error ("TODO: Functions with alternate entry points");
+      gfc_symbol *sym;
+      gfc_typespec *ts, *fts;
+
+      gfc_add_function (&proc->attr, proc->name, NULL);
+      proc->result = proc;
+      fts = &ns->entries->sym->result->ts;
+      if (fts->type == BT_UNKNOWN)
+       fts = gfc_get_default_type (ns->entries->sym->result, NULL);
+      for (el = ns->entries->next; el; el = el->next)
+       {
+         ts = &el->sym->result->ts;
+         if (ts->type == BT_UNKNOWN)
+           ts = gfc_get_default_type (el->sym->result, 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;
+       }
+
+      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 can't be an array in FUNCTION %s at %L",
+                  sym->name, ns->entries->sym->name, &sym->declared_at);
+               else
+                 gfc_error
+                   ("ENTRY result %s can't 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 can't be a POINTER in FUNCTION %s at %L",
+                  sym->name, ns->entries->sym->name, &sym->declared_at);
+               else
+                 gfc_error
+                   ("ENTRY result %s can't 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, 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 can't 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 can't 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;
@@ -392,10 +516,10 @@ resolve_entries (gfc_namespace * ns)
   for (el = ns->entries; el; el = el->next)
     merge_argument_lists (proc, el->sym->formal);
 
-  /* And use it for the function body.  */
+  /* Use the master function for the function body.  */
   ns->proc_name = proc;
 
-  /* FInalize the new symbols.  */
+  /* Finalize the new symbols.  */
   gfc_commit_symbols ();
 
   /* Restore the original namespace.  */
@@ -418,6 +542,8 @@ resolve_contained_functions (gfc_namespace * ns)
   gfc_namespace *child;
   gfc_entry_list *el;
 
+  resolve_entries (ns);
+
   resolve_formal_arglists (ns);
 
   for (child = ns->contained; child; child = child->sibling)
@@ -434,7 +560,7 @@ resolve_contained_functions (gfc_namespace * ns)
 
 
 /* Resolve all of the elements of a structure constructor and make sure that
-   the types are correct. */
+   the types are correct.  */
 
 static try
 resolve_structure_cons (gfc_expr * expr)
@@ -469,9 +595,18 @@ resolve_structure_cons (gfc_expr * expr)
 
       /* If we don't have the right type, try to convert it.  */
 
-      if (!gfc_compare_types (&cons->expr->ts, &comp->ts)
-         && gfc_convert_type (cons->expr, &comp->ts, 1) == FAILURE)
-       t = FAILURE;
+      if (!gfc_compare_types (&cons->expr->ts, &comp->ts))
+       {
+         t = FAILURE;
+         if (comp->pointer && cons->expr->ts.type != BT_UNKNOWN)
+           gfc_error ("The element in the derived type constructor at %L, "
+                      "for pointer component '%s', is %s but should be %s",
+                      &cons->expr->where, comp->name,
+                      gfc_basic_typename (cons->expr->ts.type),
+                      gfc_basic_typename (comp->ts.type));
+         else
+           t = gfc_convert_type (cons->expr, &comp->ts, 1);
+       }
     }
 
   return t;
@@ -494,7 +629,7 @@ was_declared (gfc_symbol * sym)
   if (!a.implicit_type && sym->ts.type != BT_UNKNOWN)
     return 1;
 
-  if (a.allocatable || a.dimension || a.external || a.intrinsic
+  if (a.allocatable || a.dimension || a.dummy || a.external || a.intrinsic
       || a.optional || a.pointer || a.save || a.target
       || a.access != ACCESS_UNKNOWN || a.intent != INTENT_UNKNOWN)
     return 1;
@@ -567,6 +702,69 @@ procedure_kind (gfc_symbol * sym)
   return PTYPE_UNKNOWN;
 }
 
+/* Check references to assumed size arrays.  The flag need_full_assumed_size
+   is non-zero when matching actual arguments.  */
+
+static int need_full_assumed_size = 0;
+
+static bool
+check_assumed_size_reference (gfc_symbol * sym, gfc_expr * e)
+{
+  gfc_ref * ref;
+  int dim;
+  int last = 1;
+
+  if (need_full_assumed_size
+       || !(sym->as && sym->as->type == AS_ASSUMED_SIZE))
+      return false;
+
+  for (ref = e->ref; ref; ref = ref->next)
+    if (ref->type == REF_ARRAY)
+      for (dim = 0; dim < ref->u.ar.as->rank; dim++)
+       last = (ref->u.ar.end[dim] == NULL) && (ref->u.ar.type == DIMEN_ELEMENT);
+
+  if (last)
+    {
+      gfc_error ("The upper bound in the last dimension must "
+                "appear in the reference to the assumed size "
+                "array '%s' 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;
+}
+
 
 /* Resolve an actual argument list.  Most of the time, this is just
    resolving the expressions in the list.
@@ -617,6 +815,26 @@ resolve_actual_arglist (gfc_actual_arglist * arg)
          || sym->attr.external)
        {
 
+         if (sym->attr.proc == PROC_ST_FUNCTION)
+           {
+             gfc_error ("Statement function '%s' 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)
+           {
+             gfc_error ("Internal procedure '%s' is not allowed as an "
+                        "actual argument at %L", sym->name, &e->where);
+           }
+
+         if (sym->attr.elemental && !sym->attr.intrinsic)
+           {
+             gfc_error ("ELEMENTAL non-INTRINSIC procedure '%s' is not "
+                        "allowed as an actual argument at %L", sym->name,
+                        &e->where);
+           }
+
          /* If the symbol is the function that names the current (or
             parent) scope, then we really have a variable reference.  */
 
@@ -670,6 +888,54 @@ resolve_actual_arglist (gfc_actual_arglist * arg)
 }
 
 
+/* Go through each actual argument in ACTUAL and see if it can be
+   implemented as an inlined, non-copying intrinsic.  FNSYM is the
+   function being called, or NULL if not known.  */
+
+static void
+find_noncopying_intrinsics (gfc_symbol * fnsym, gfc_actual_arglist * actual)
+{
+  gfc_actual_arglist *ap;
+  gfc_expr *expr;
+
+  for (ap = actual; ap; ap = ap->next)
+    if (ap->expr
+       && (expr = gfc_get_noncopying_intrinsic_argument (ap->expr))
+       && !gfc_check_fncall_dependency (expr, INTENT_IN, fnsym, actual))
+      ap->expr->inline_noncopying_intrinsic = 1;
+}
+
+/* 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.  */
+
+static void
+resolve_global_procedure (gfc_symbol *sym, locus *where, int sub)
+{
+  gfc_gsymbol * gsym;
+  unsigned int type;
+
+  type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;
+
+  gsym = gfc_get_gsymbol (sym->name);
+
+  if ((gsym->type != GSYM_UNKNOWN && gsym->type != type))
+    global_used (gsym, where);
+
+  if (gsym->type == GSYM_UNKNOWN)
+    {
+      gsym->type = type;
+      gsym->where = *where;
+    }
+
+  gsym->used = 1;
+}
+
 /************* Function resolution *************/
 
 /* Resolve a function call known to be generic.
@@ -885,7 +1151,7 @@ set_type:
 
       if (ts->type == BT_UNKNOWN)
        {
-         gfc_error ("Function '%s' at %L has no implicit type",
+         gfc_error ("Function '%s' at %L has no IMPLICIT type",
                     sym->name, &expr->where);
          return FAILURE;
        }
@@ -897,12 +1163,12 @@ set_type:
 }
 
 
-/* Figure out if if a function reference is pure or not.  Also sets the name
-   of the function for a potential error message.  Returns nonzero if the
+/* 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_function (gfc_expr * e, char **name)
+pure_function (gfc_expr * e, const char **name)
 {
   int pure;
 
@@ -937,25 +1203,70 @@ static try
 resolve_function (gfc_expr * expr)
 {
   gfc_actual_arglist *arg;
-  char *name;
+  gfc_symbol * sym;
+  const char *name;
   try t;
+  int temp;
+
+  sym = NULL;
+  if (expr->symtree)
+    sym = expr->symtree->n.sym;
+
+  /* If the procedure is not internal, a statement function or a module
+     procedure,it must be external and should be checked for usage.  */
+  if (sym && !sym->attr.dummy && !sym->attr.contained
+       && sym->attr.proc != PROC_ST_FUNCTION
+       && !sym->attr.use_assoc)
+    resolve_global_procedure (sym, &expr->where, 0);
+
+  /* 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 (resolve_actual_arglist (expr->value.function.actual) == FAILURE)
     return FAILURE;
 
+  /* Resume assumed_size checking. */
+  need_full_assumed_size--;
+
+  if (sym && sym->ts.type == BT_CHARACTER
+         && sym->ts.cl && sym->ts.cl->length == NULL)
+    {
+      if (sym->attr.if_source == IFSRC_IFBODY)
+       {
+         /* This follows from a slightly odd requirement at 5.1.1.5 in the
+            standard that allows assumed character length functions to be
+            declared in interfaces but not used.  Picking up the symbol here,
+            rather than resolve_symbol, accomplishes that.  */
+         gfc_error ("Function '%s' can be declared in an interface to "
+                    "return CHARACTER(*) but cannot be used at %L",
+                    sym->name, &expr->where);
+         return FAILURE;
+       }
+
+      /* Internal procedures are taken care of in resolve_contained_fntype.  */
+      if (!sym->attr.dummy && !sym->attr.contained)
+       {
+         gfc_error ("Function '%s' is declared CHARACTER(*) and cannot "
+                    "be used at %L since it is not a dummy argument",
+                    sym->name, &expr->where);
+         return FAILURE;
+       }
+    }
+
 /* See if function is already resolved.  */
 
   if (expr->value.function.name != NULL)
     {
       if (expr->ts.type == BT_UNKNOWN)
-       expr->ts = expr->symtree->n.sym->ts;
+       expr->ts = sym->ts;
       t = SUCCESS;
     }
   else
     {
       /* Apply the rules of section 14.1.2.  */
 
-      switch (procedure_kind (expr->symtree->n.sym))
+      switch (procedure_kind (sym))
        {
        case PTYPE_GENERIC:
          t = resolve_generic_f (expr);
@@ -980,15 +1291,16 @@ resolve_function (gfc_expr * expr)
   if (expr->expr_type != EXPR_FUNCTION)
     return t;
 
+  temp = need_full_assumed_size;
+  need_full_assumed_size = 0;
+
   if (expr->value.function.actual != NULL
       && ((expr->value.function.esym != NULL
           && expr->value.function.esym->attr.elemental)
          || (expr->value.function.isym != NULL
              && expr->value.function.isym->elemental)))
     {
-
       /* The rank of an elemental is the rank of its array argument(s).  */
-
       for (arg = expr->value.function.actual; arg; arg = arg->next)
        {
          if (arg->expr != NULL && arg->expr->rank > 0)
@@ -997,8 +1309,56 @@ resolve_function (gfc_expr * expr)
              break;
            }
        }
+
+      /* Being elemental, the last upper bound of an assumed size array
+        argument must be present.  */
+      for (arg = expr->value.function.actual; arg; arg = arg->next)
+       {
+         if (arg->expr != NULL
+               && arg->expr->rank > 0
+               && resolve_assumed_size_actual (arg->expr))
+           return FAILURE;
+       }
+    }
+  if (omp_workshare_flag
+      && expr->value.function.esym
+      && ! gfc_elemental (expr->value.function.esym))
+    {
+      gfc_error ("User defined non-ELEMENTAL function '%s' at %L not allowed"
+                " in WORKSHARE construct", expr->value.function.esym->name,
+                &expr->where);
+      t = FAILURE;
+    }
+
+  else if (expr->value.function.actual != NULL
+            && expr->value.function.isym != NULL
+            && expr->value.function.isym->generic_id != GFC_ISYM_LBOUND
+            && expr->value.function.isym->generic_id != GFC_ISYM_LOC
+            && expr->value.function.isym->generic_id != GFC_ISYM_PRESENT)
+    {
+      /* Array instrinsics must also have the last upper bound of an
+        asumed size array argument.  UBOUND and SIZE have to be
+        excluded from the check if the second argument is anything
+        than a constant.  */
+      int inquiry;
+      inquiry = expr->value.function.isym->generic_id == GFC_ISYM_UBOUND
+                 || expr->value.function.isym->generic_id == GFC_ISYM_SIZE;
+           
+      for (arg = expr->value.function.actual; arg; arg = arg->next)
+       {
+         if (inquiry && arg->next != NULL && arg->next->expr
+               && arg->next->expr->expr_type != EXPR_CONSTANT)
+           break;
+         
+         if (arg->expr != NULL
+               && arg->expr->rank > 0
+               && resolve_assumed_size_actual (arg->expr))
+           return FAILURE;
+       }
     }
 
+  need_full_assumed_size = temp;
+
   if (!pure_function (expr, &name))
     {
       if (forall_flag)
@@ -1016,6 +1376,19 @@ resolve_function (gfc_expr * expr)
        }
     }
 
+  /* 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.cl->length);
+    }
+
+  if (t == SUCCESS)
+    find_noncopying_intrinsics (expr->value.function.esym,
+                               expr->value.function.actual);
   return t;
 }
 
@@ -1235,33 +1608,104 @@ resolve_call (gfc_code * c)
 {
   try t;
 
+  if (c->symtree && c->symtree->n.sym
+       && c->symtree->n.sym->ts.type != BT_UNKNOWN)
+    {
+      gfc_error ("'%s' at %L has a type, which is not consistent with "
+                "the CALL at %L", c->symtree->n.sym->name,
+                &c->symtree->n.sym->declared_at, &c->loc);
+      return FAILURE;
+    }
+
+  /* If the procedure is not internal or module, it must be external and
+     should be checked for usage.  */
+  if (c->symtree && c->symtree->n.sym
+       && !c->symtree->n.sym->attr.dummy
+       && !c->symtree->n.sym->attr.contained
+       && !c->symtree->n.sym->attr.use_assoc)
+    resolve_global_procedure (c->symtree->n.sym, &c->loc, 1);
+
+  /* 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 (resolve_actual_arglist (c->ext.actual) == FAILURE)
     return FAILURE;
 
-  if (c->resolved_sym != NULL)
-    return SUCCESS;
+  /* Resume assumed_size checking. */
+  need_full_assumed_size--;
 
-  switch (procedure_kind (c->symtree->n.sym))
-    {
-    case PTYPE_GENERIC:
-      t = resolve_generic_s (c);
-      break;
 
-    case PTYPE_SPECIFIC:
-      t = resolve_specific_s (c);
-      break;
+  t = SUCCESS;
+  if (c->resolved_sym == NULL)
+    switch (procedure_kind (c->symtree->n.sym))
+      {
+      case PTYPE_GENERIC:
+       t = resolve_generic_s (c);
+       break;
 
-    case PTYPE_UNKNOWN:
-      t = resolve_unknown_s (c);
-      break;
+      case PTYPE_SPECIFIC:
+       t = resolve_specific_s (c);
+       break;
 
-    default:
-      gfc_internal_error ("resolve_subroutine(): bad function type");
+      case PTYPE_UNKNOWN:
+       t = resolve_unknown_s (c);
+       break;
+
+      default:
+       gfc_internal_error ("resolve_subroutine(): bad function type");
+      }
+
+  if (c->ext.actual != NULL
+      && c->symtree->n.sym->attr.elemental)
+    {
+      gfc_actual_arglist * a;
+      /* Being elemental, the last upper bound of an assumed size array
+        argument must be present.  */
+      for (a = c->ext.actual; a; a = a->next)
+       {
+         if (a->expr != NULL
+               && a->expr->rank > 0
+               && resolve_assumed_size_actual (a->expr))
+           return FAILURE;
+       }
     }
 
+  if (t == SUCCESS)
+    find_noncopying_intrinsics (c->resolved_sym, c->ext.actual);
   return t;
 }
 
+/* Compare the shapes of two arrays that have non-NULL shapes.  If both
+   op1->shape and op2->shape are non-NULL return SUCCESS if their shapes
+   match.  If both op1->shape and op2->shape are non-NULL return FAILURE
+   if their shapes do not match.  If either op1->shape or op2->shape is
+   NULL, return SUCCESS.  */
+
+static try
+compare_shapes (gfc_expr * op1, gfc_expr * op2)
+{
+  try t;
+  int i;
+
+  t = SUCCESS;
+                 
+  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 = FAILURE;
+            break;
+          }
+       }
+    }
+
+  return t;
+}
 
 /* Resolve an operator expression node.  This can involve replacing the
    operation with a user defined function call.  */
@@ -1275,10 +1719,10 @@ resolve_operator (gfc_expr * e)
 
   /* Resolve all subnodes-- give them types.  */
 
-  switch (e->operator)
+  switch (e->value.op.operator)
     {
     default:
-      if (gfc_resolve_expr (e->op2) == FAILURE)
+      if (gfc_resolve_expr (e->value.op.op2) == FAILURE)
        return FAILURE;
 
     /* Fall through...  */
@@ -1286,17 +1730,18 @@ resolve_operator (gfc_expr * e)
     case INTRINSIC_NOT:
     case INTRINSIC_UPLUS:
     case INTRINSIC_UMINUS:
-      if (gfc_resolve_expr (e->op1) == FAILURE)
+    case INTRINSIC_PARENTHESES:
+      if (gfc_resolve_expr (e->value.op.op1) == FAILURE)
        return FAILURE;
       break;
     }
 
   /* Typecheck the new node.  */
 
-  op1 = e->op1;
-  op2 = e->op2;
+  op1 = e->value.op.op1;
+  op2 = e->value.op.op2;
 
-  switch (e->operator)
+  switch (e->value.op.operator)
     {
     case INTRINSIC_UPLUS:
     case INTRINSIC_UMINUS:
@@ -1308,8 +1753,8 @@ resolve_operator (gfc_expr * e)
          break;
        }
 
-      sprintf (msg, "Operand of unary numeric operator '%s' at %%L is %s",
-              gfc_op2string (e->operator), gfc_typename (&e->ts));
+      sprintf (msg, _("Operand of unary numeric operator '%s' at %%L is %s"),
+              gfc_op2string (e->value.op.operator), gfc_typename (&e->ts));
       goto bad_op;
 
     case INTRINSIC_PLUS:
@@ -1324,8 +1769,8 @@ resolve_operator (gfc_expr * e)
        }
 
       sprintf (msg,
-              "Operands of binary numeric operator '%s' at %%L are %s/%s",
-              gfc_op2string (e->operator), gfc_typename (&op1->ts),
+              _("Operands of binary numeric operator '%s' at %%L are %s/%s"),
+              gfc_op2string (e->value.op.operator), gfc_typename (&op1->ts),
               gfc_typename (&op2->ts));
       goto bad_op;
 
@@ -1338,7 +1783,7 @@ resolve_operator (gfc_expr * e)
        }
 
       sprintf (msg,
-              "Operands of string concatenation operator at %%L are %s/%s",
+              _("Operands of string concatenation operator at %%L are %s/%s"),
               gfc_typename (&op1->ts), gfc_typename (&op2->ts));
       goto bad_op;
 
@@ -1357,8 +1802,8 @@ resolve_operator (gfc_expr * e)
          break;
        }
 
-      sprintf (msg, "Operands of logical operator '%s' at %%L are %s/%s",
-              gfc_op2string (e->operator), gfc_typename (&op1->ts),
+      sprintf (msg, _("Operands of logical operator '%s' at %%L are %s/%s"),
+              gfc_op2string (e->value.op.operator), gfc_typename (&op1->ts),
               gfc_typename (&op2->ts));
 
       goto bad_op;
@@ -1371,7 +1816,7 @@ resolve_operator (gfc_expr * e)
          break;
        }
 
-      sprintf (msg, "Operand of .NOT. operator at %%L is %s",
+      sprintf (msg, _("Operand of .NOT. operator at %%L is %s"),
               gfc_typename (&op1->ts));
       goto bad_op;
 
@@ -1381,7 +1826,7 @@ resolve_operator (gfc_expr * e)
     case INTRINSIC_LE:
       if (op1->ts.type == BT_COMPLEX || op2->ts.type == BT_COMPLEX)
        {
-         strcpy (msg, "COMPLEX quantities cannot be compared at %L");
+         strcpy (msg, _("COMPLEX quantities cannot be compared at %L"));
          goto bad_op;
        }
 
@@ -1392,7 +1837,7 @@ resolve_operator (gfc_expr * e)
       if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER)
        {
          e->ts.type = BT_LOGICAL;
-         e->ts.kind = gfc_default_logical_kind ();
+         e->ts.kind = gfc_default_logical_kind;
          break;
        }
 
@@ -1401,27 +1846,37 @@ resolve_operator (gfc_expr * e)
          gfc_type_convert_binary (e);
 
          e->ts.type = BT_LOGICAL;
-         e->ts.kind = gfc_default_logical_kind ();
+         e->ts.kind = gfc_default_logical_kind;
          break;
        }
 
-      sprintf (msg, "Operands of comparison operator '%s' at %%L are %s/%s",
-              gfc_op2string (e->operator), gfc_typename (&op1->ts),
-              gfc_typename (&op2->ts));
+      if (op1->ts.type == BT_LOGICAL && op2->ts.type == BT_LOGICAL)
+       sprintf (msg,
+                _("Logicals at %%L must be compared with %s instead of %s"),
+                e->value.op.operator == INTRINSIC_EQ ? ".EQV." : ".NEQV.",
+                gfc_op2string (e->value.op.operator));
+      else
+       sprintf (msg,
+                _("Operands of comparison operator '%s' at %%L are %s/%s"),
+                gfc_op2string (e->value.op.operator), gfc_typename (&op1->ts),
+                gfc_typename (&op2->ts));
 
       goto bad_op;
 
     case INTRINSIC_USER:
       if (op2 == NULL)
-       sprintf (msg, "Operand of user operator '%s' at %%L is %s",
-                e->uop->ns->proc_name->name, gfc_typename (&op1->ts));
+       sprintf (msg, _("Operand of user operator '%s' at %%L is %s"),
+                e->value.op.uop->name, gfc_typename (&op1->ts));
       else
-       sprintf (msg, "Operands of user operator '%s' at %%L are %s/%s",
-                e->uop->ns->proc_name->name, gfc_typename (&op1->ts),
+       sprintf (msg, _("Operands of user operator '%s' at %%L are %s/%s"),
+                e->value.op.uop->name, gfc_typename (&op1->ts),
                 gfc_typename (&op2->ts));
 
       goto bad_op;
 
+    case INTRINSIC_PARENTHESES:
+      break;
+
     default:
       gfc_internal_error ("resolve_operator(): Bad intrinsic");
     }
@@ -1430,7 +1885,7 @@ resolve_operator (gfc_expr * e)
 
   t = SUCCESS;
 
-  switch (e->operator)
+  switch (e->value.op.operator)
     {
     case INTRINSIC_PLUS:
     case INTRINSIC_MINUS:
@@ -1473,10 +1928,14 @@ resolve_operator (gfc_expr * e)
          if (op1->rank == op2->rank)
            {
              e->rank = op1->rank;
-
              if (e->shape == NULL)
+               {
+                 t = compare_shapes(op1, op2);
+                 if (t == FAILURE)
+                   e->shape = NULL;
+                 else
                e->shape = gfc_copy_shape (op1->shape, op1->rank);
-
+               }
            }
          else
            {
@@ -1494,6 +1953,7 @@ resolve_operator (gfc_expr * e)
     case INTRINSIC_NOT:
     case INTRINSIC_UPLUS:
     case INTRINSIC_UMINUS:
+    case INTRINSIC_PARENTHESES:
       e->rank = op1->rank;
 
       if (e->shape == NULL)
@@ -1512,10 +1972,12 @@ resolve_operator (gfc_expr * e)
   return t;
 
 bad_op:
+
   if (gfc_extend_expr (e) == SUCCESS)
     return SUCCESS;
 
   gfc_error (msg, &e->where);
+
   return FAILURE;
 }
 
@@ -1582,7 +2044,7 @@ check_dimension (int i, gfc_array_ref * ar, gfc_array_spec * as)
 {
 
 /* Given start, end and stride values, calculate the minimum and
-   maximum referenced indexes. */
+   maximum referenced indexes.  */
 
   switch (ar->type)
     {
@@ -1610,7 +2072,7 @@ check_dimension (int i, gfc_array_ref * ar, gfc_array_spec * as)
        goto bound;
 
       /* TODO: Possibly, we could warn about end[i] being out-of-bound although
-         it is legal (see 6.2.2.3.1). */
+         it is legal (see 6.2.2.3.1).  */
 
       break;
 
@@ -1678,20 +2140,28 @@ gfc_resolve_index (gfc_expr * index, int check_scalar)
   if (gfc_resolve_expr (index) == FAILURE)
     return FAILURE;
 
-  if (index->ts.type != BT_INTEGER)
+  if (check_scalar && index->rank != 0)
     {
-      gfc_error ("Array index at %L must be of INTEGER type", &index->where);
+      gfc_error ("Array index at %L must be scalar", &index->where);
       return FAILURE;
     }
 
-  if (check_scalar && index->rank != 0)
+  if (index->ts.type != BT_INTEGER && index->ts.type != BT_REAL)
     {
-      gfc_error ("Array index at %L must be scalar", &index->where);
+      gfc_error ("Array index at %L must be of INTEGER type",
+                &index->where);
       return FAILURE;
     }
 
-  if (index->ts.kind != gfc_index_integer_kind)
+  if (index->ts.type == BT_REAL)
+    if (gfc_notify_std (GFC_STD_GNU, "Extension: REAL array index at %L",
+                       &index->where) == FAILURE)
+      return FAILURE;
+
+  if (index->ts.kind != gfc_index_integer_kind
+      || index->ts.type != BT_INTEGER)
     {
+      gfc_clear_ts (&ts);
       ts.type = BT_INTEGER;
       ts.kind = gfc_index_integer_kind;
 
@@ -1701,6 +2171,40 @@ gfc_resolve_index (gfc_expr * index, int check_scalar)
   return SUCCESS;
 }
 
+/* Resolve a dim argument to an intrinsic function.  */
+
+try
+gfc_resolve_dim_arg (gfc_expr *dim)
+{
+  if (dim == NULL)
+    return SUCCESS;
+
+  if (gfc_resolve_expr (dim) == FAILURE)
+    return FAILURE;
+
+  if (dim->rank != 0)
+    {
+      gfc_error ("Argument dim at %L must be scalar", &dim->where);
+      return FAILURE;
+  
+    }
+  if (dim->ts.type != BT_INTEGER)
+    {
+      gfc_error ("Argument dim at %L must be of INTEGER type", &dim->where);
+      return FAILURE;
+    }
+  if (dim->ts.kind != gfc_index_integer_kind)
+    {
+      gfc_typespec ts;
+
+      ts.type = BT_INTEGER;
+      ts.kind = gfc_index_integer_kind;
+
+      gfc_convert_type_warn (dim, &ts, 2, 0);
+    }
+
+  return SUCCESS;
+}
 
 /* Given an expression that contains array references, update those array
    references to point to the right array specifications.  While this is
@@ -1720,7 +2224,6 @@ find_array_spec (gfc_expr * e)
   gfc_ref *ref;
 
   as = e->symtree->n.sym->as;
-  c = e->symtree->n.sym->components;
 
   for (ref = e->ref; ref; ref = ref->next)
     switch (ref->type)
@@ -1734,7 +2237,7 @@ find_array_spec (gfc_expr * e)
        break;
 
       case REF_COMPONENT:
-       for (; c; c = c->next)
+       for (c = e->symtree->n.sym->ts.derived->components; c; c = c->next)
          if (c == ref->u.c.component)
            break;
 
@@ -1748,7 +2251,6 @@ find_array_spec (gfc_expr * e)
            as = c->as;
          }
 
-       c = c->ts.derived->components;
        break;
 
       case REF_SUBSTRING:
@@ -1810,7 +2312,7 @@ resolve_array_ref (gfc_array_ref * ar)
          }
     }
 
-  if (compare_spec_to_ref (ar) == FAILURE)
+  if (!ar->as->cray_pointee && compare_spec_to_ref (ar) == FAILURE)
     return FAILURE;
 
   return SUCCESS;
@@ -1983,7 +2485,7 @@ resolve_ref (gfc_expr * expr)
 
 
 /* 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. */
+   Leaves the shape array NULL if it is not possible to determine the shape.  */
 
 static void
 expression_shape (gfc_expr * e)
@@ -2023,7 +2525,7 @@ expression_rank (gfc_expr * e)
     {
       if (e->expr_type == EXPR_ARRAY)
        goto done;
-      /* Constructors can have a rank different from one via RESHAPE().   */
+      /* Constructors can have a rank different from one via RESHAPE().  */
 
       if (e->symtree == NULL)
        {
@@ -2081,6 +2583,9 @@ resolve_variable (gfc_expr * e)
   if (e->ref && resolve_ref (e) == FAILURE)
     return FAILURE;
 
+  if (e->symtree == NULL)
+    return FAILURE;
+
   sym = e->symtree->n.sym;
   if (sym->attr.flavor == FL_PROCEDURE && !sym->attr.function)
     {
@@ -2098,6 +2603,9 @@ resolve_variable (gfc_expr * e)
       e->ts = sym->ts;
     }
 
+  if (check_assumed_size_reference (sym, e))
+    return FAILURE;
+
   return SUCCESS;
 }
 
@@ -2174,73 +2682,104 @@ gfc_resolve_expr (gfc_expr * e)
 }
 
 
-/* Resolve the expressions in an iterator structure and require that they all
-   be of integer type.  */
+/* Resolve an expression from an iterator.  They must be scalar and have
+   INTEGER or (optionally) REAL type.  */
 
-try
-gfc_resolve_iterator (gfc_iterator * iter)
+static try
+gfc_resolve_iterator_expr (gfc_expr * expr, bool real_ok,
+                          const char * name_msgid)
 {
-
-  if (gfc_resolve_expr (iter->var) == FAILURE)
+  if (gfc_resolve_expr (expr) == FAILURE)
     return FAILURE;
 
-  if (iter->var->ts.type != BT_INTEGER || iter->var->rank != 0)
+  if (expr->rank != 0)
     {
-      gfc_error ("Loop variable at %L must be a scalar INTEGER",
-                &iter->var->where);
+      gfc_error ("%s at %L must be a scalar", _(name_msgid), &expr->where);
       return FAILURE;
     }
 
-  if (gfc_pure (NULL) && gfc_impure_variable (iter->var->symtree->n.sym))
+  if (!(expr->ts.type == BT_INTEGER
+       || (expr->ts.type == BT_REAL && real_ok)))
     {
-      gfc_error ("Cannot assign to loop variable in PURE procedure at %L",
-                &iter->var->where);
+      if (real_ok)
+       gfc_error ("%s at %L must be INTEGER or REAL", _(name_msgid),
+                  &expr->where);
+      else
+       gfc_error ("%s at %L must be INTEGER", _(name_msgid), &expr->where);
       return FAILURE;
     }
+  return SUCCESS;
+}
 
-  if (gfc_resolve_expr (iter->start) == FAILURE)
+
+/* Resolve the expressions in an iterator structure.  If REAL_OK is
+   false allow only INTEGER type iterators, otherwise allow REAL types.  */
+
+try
+gfc_resolve_iterator (gfc_iterator * iter, bool real_ok)
+{
+
+  if (iter->var->ts.type == BT_REAL)
+    gfc_notify_std (GFC_STD_F95_DEL,
+                   "Obsolete: REAL DO loop iterator at %L",
+                   &iter->var->where);
+
+  if (gfc_resolve_iterator_expr (iter->var, real_ok, "Loop variable")
+      == FAILURE)
     return FAILURE;
 
-  if (iter->start->ts.type != BT_INTEGER || iter->start->rank != 0)
+  if (gfc_pure (NULL) && gfc_impure_variable (iter->var->symtree->n.sym))
     {
-      gfc_error ("Start expression in DO loop at %L must be a scalar INTEGER",
-                &iter->start->where);
+      gfc_error ("Cannot assign to loop variable in PURE procedure at %L",
+                &iter->var->where);
       return FAILURE;
     }
 
-  if (gfc_resolve_expr (iter->end) == FAILURE)
+  if (gfc_resolve_iterator_expr (iter->start, real_ok,
+                                "Start expression in DO loop") == FAILURE)
     return FAILURE;
 
-  if (iter->end->ts.type != BT_INTEGER || iter->end->rank != 0)
-    {
-      gfc_error ("End expression in DO loop at %L must be a scalar INTEGER",
-                &iter->end->where);
-      return FAILURE;
-    }
+  if (gfc_resolve_iterator_expr (iter->end, real_ok,
+                                "End expression in DO loop") == FAILURE)
+    return FAILURE;
 
-  if (gfc_resolve_expr (iter->step) == FAILURE)
+  if (gfc_resolve_iterator_expr (iter->step, real_ok,
+                                "Step expression in DO loop") == FAILURE)
     return FAILURE;
 
-  if (iter->step->ts.type != BT_INTEGER || iter->step->rank != 0)
+  if (iter->step->expr_type == EXPR_CONSTANT)
     {
-      gfc_error ("Step expression in DO loop at %L must be a scalar INTEGER",
-                &iter->step->where);
-      return FAILURE;
+      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 FAILURE;
+       }
     }
 
-  if (iter->step->expr_type == EXPR_CONSTANT
-      && mpz_cmp_ui (iter->step->value.integer, 0) == 0)
-    {
-      gfc_error ("Step expression in DO loop at %L cannot be zero",
-                &iter->step->where);
-      return FAILURE;
-    }
+  /* 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, 2);
+
+  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, 2);
+
+  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, 2);
 
   return SUCCESS;
 }
 
 
-/* Resolve a list of FORALL iterators.  */
+/* 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.  */
 
 static void
 resolve_forall_iterators (gfc_forall_iterator * iter)
@@ -2249,28 +2788,35 @@ resolve_forall_iterators (gfc_forall_iterator * iter)
   while (iter)
     {
       if (gfc_resolve_expr (iter->var) == SUCCESS
-         && iter->var->ts.type != BT_INTEGER)
-       gfc_error ("FORALL Iteration variable at %L must be INTEGER",
+         && (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) == SUCCESS
-         && iter->start->ts.type != BT_INTEGER)
-       gfc_error ("FORALL start expression at %L must be INTEGER",
+         && (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, 2);
 
       if (gfc_resolve_expr (iter->end) == SUCCESS
-         && iter->end->ts.type != BT_INTEGER)
-       gfc_error ("FORALL end expression at %L must be INTEGER",
+         && (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, 2);
 
-      if (gfc_resolve_expr (iter->stride) == SUCCESS
-         && iter->stride->ts.type != BT_INTEGER)
-       gfc_error ("FORALL Stride expression at %L must be INTEGER",
-                  &iter->stride->where);
+      if (gfc_resolve_expr (iter->stride) == SUCCESS)
+       {
+         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, 2);
 
@@ -2301,6 +2847,29 @@ derived_pointer (gfc_symbol * sym)
 }
 
 
+/* 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->component_access == ACCESS_PRIVATE)
+    return 1;
+
+  for (c = sym->components; c; c = c->next)
+    {
+        if (c->ts.type == BT_DERIVED && derived_inaccessible (c->ts.derived))
+          return 1;
+    }
+
+  return 0;
+}
+
+
 /* Resolve the argument of a deallocate expression.  The expression must be
    a pointer or a full array.  */
 
@@ -2351,17 +2920,49 @@ resolve_deallocate_expr (gfc_expr * e)
 }
 
 
+/* 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).  */
+
+static gfc_expr *
+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)
+      {
+        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;
+
+        result->rank = ref->u.ar.dimen; 
+        break;
+      }
+
+  return result;
+}
+
+
 /* 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 try
-resolve_allocate_expr (gfc_expr * e)
+resolve_allocate_expr (gfc_expr * e, gfc_code * code)
 {
   int i, pointer, allocatable, dimension;
   symbol_attribute attr;
   gfc_ref *ref, *ref2;
   gfc_array_ref *ar;
+  gfc_code *init_st;
+  gfc_expr *init_e;
 
   if (gfc_resolve_expr (e) == FAILURE)
     return FAILURE;
@@ -2416,6 +3017,19 @@ resolve_allocate_expr (gfc_expr * e)
       return FAILURE;
     }
 
+  /* Add default initializer for those derived types that need them.  */
+  if (e->ts.type == BT_DERIVED && (init_e = gfc_default_initializer (&e->ts)))
+    {
+        init_st = gfc_get_code ();
+        init_st->loc = code->loc;
+        init_st->op = EXEC_ASSIGN;
+        init_st->expr = expr_to_initialize (e);
+        init_st->expr2 = init_e;
+
+        init_st->next = code->next;
+        code->next = init_st;
+    }
+
   if (pointer && dimension == 0)
     return SUCCESS;
 
@@ -2465,89 +3079,52 @@ resolve_allocate_expr (gfc_expr * e)
 
 /* 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.  */
+   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 void * _op1, const void * _op2)
+compare_cases (const gfc_case * op1, const gfc_case * op2)
 {
-  const gfc_case *op1, *op2;
-
-  op1 = (const gfc_case *) _op1;
-  op2 = (const gfc_case *) _op2;
+  int retval;
 
-  if (op1->low == NULL) /* op1 = (:N) */
+  if (op1->low == NULL) /* op1 = (:L)  */
     {
-      if (op2->low == NULL) /* op2 = (:M), so overlap.  */
-        return 0;
-
-      else if (op2->high == NULL) /* op2 = (M:) */
-        {
-         if (gfc_compare_expr (op1->high, op2->low) < 0)
-           return -1;  /* N < M */
-         else
-           return 0;
-       }
-
-      else /* op2 = (L:M) */
-        {
-         if (gfc_compare_expr (op1->high, op2->low) < 0)
-           return -1; /* N < L */
-         else
-           return 0;
-       }
+      /* op2 = (:N), so overlap.  */
+      retval = 0;
+      /* op2 = (M:) or (M:N),  L < M  */
+      if (op2->low != NULL
+         && gfc_compare_expr (op1->high, op2->low) < 0)
+       retval = -1;
     }
-
-  else if (op1->high == NULL) /* op1 = (N:) */
+  else if (op1->high == NULL) /* op1 = (K:)  */
     {
-      if (op2->low == NULL) /* op2 = (:M)  */
-        {
-         if (gfc_compare_expr (op1->low, op2->high) > 0)
-           return 1; /* N > M */
-         else
-           return 0;
-       }
-
-      else if (op2->high == NULL) /* op2 = (M:), so overlap.  */
-        return 0;
-
-      else /* op2 = (L:M) */
-        {
-         if (gfc_compare_expr (op1->low, op2->high) > 0)
-           return 1; /* N > M */
-         else
-           return 0;
-       }
+      /* op2 = (M:), so overlap.  */
+      retval = 0;
+      /* op2 = (:N) or (M:N), K > N  */
+      if (op2->high != NULL
+         && gfc_compare_expr (op1->low, op2->high) > 0)
+       retval = 1;
     }
-
-  else /* op1 = (N:P) */
+  else /* op1 = (K:L)  */
     {
-      if (op2->low == NULL) /* op2 = (:M)  */
-        {
-         if (gfc_compare_expr (op1->low, op2->high) > 0)
-           return 1; /* N > M */
-         else
-           return 0;
-       }
-
-      else if (op2->high == NULL) /* op2 = (M:)  */
-        {
-         if (gfc_compare_expr (op1->high, op2->low) < 0)
-           return -1; /* P < M */
-         else
-           return 0;
-       }
-
-      else /* op2 = (L:M) */
+      if (op2->low == NULL)       /* op2 = (:N), K > N  */
+       retval = (gfc_compare_expr (op1->low, op2->high) > 0) ? 1 : 0;
+      else if (op2->high == NULL) /* op2 = (M:), L < M  */
+       retval = (gfc_compare_expr (op1->high, op2->low) < 0) ? -1 : 0;
+      else                        /* op2 = (M:N)  */
         {
+         retval =  0;
+          /* L < M  */
          if (gfc_compare_expr (op1->high, op2->low) < 0)
-           return -1; /* P < L */
-
-         if (gfc_compare_expr (op1->low, op2->high) > 0)
-           return 1; /* N > M */
-
-         return 0;
+           retval =  -1;
+          /* K > N  */
+         else if (gfc_compare_expr (op1->low, op2->high) > 0)
+           retval =  1;
        }
     }
+
+  return retval;
 }
 
 
@@ -2588,7 +3165,7 @@ check_case_overlap (gfc_case * list)
          /* Count this merge.  */
          nmerges++;
 
-         /* Cut the list in two pieces by steppin INSIZE places
+         /* Cut the list in two pieces by stepping INSIZE places
              forward in the list, starting from P.  */
          psize = 0;
          q = p;
@@ -2685,32 +3262,38 @@ check_case_overlap (gfc_case * list)
 }
 
 
-/* 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/kind.  Return FAILURE if anything
-   is wrong.  */
+/* 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 FAILURE if anything is wrong.  */
 
 static try
 validate_case_label_expr (gfc_expr * e, gfc_expr * case_expr)
 {
-  gfc_typespec case_ts = case_expr->ts;
-
   if (e == NULL) return SUCCESS;
 
-  if (e->ts.type != case_ts.type)
+  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_ts.type));
+                &e->where, gfc_basic_typename (case_expr->ts.type));
       return FAILURE;
     }
 
-  if (e->ts.kind != case_ts.kind)
+  /* 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 kind %d",
-                &e->where, case_ts.kind);
+                &e->where, case_expr->ts.kind);
       return FAILURE;
     }
 
+  /* Convert the case value kind to that of case expression kind, if needed.
+     FIXME:  Should a warning be issued?  */
+  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",
@@ -2736,7 +3319,7 @@ validate_case_label_expr (gfc_expr * e, gfc_expr * case_expr)
    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. Furtunately we can fairly
+   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
@@ -2793,6 +3376,40 @@ resolve_select (gfc_code * code)
       return;
     }
 
+  /* 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.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) > 0)
+               continue;
+
+             /* FIXME: Should a warning be issued?  */
+             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;
@@ -2962,6 +3579,62 @@ resolve_select (gfc_code * code)
 }
 
 
+/* 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_typespec *ts;
+  gfc_symbol *sym;
+  gfc_ref *ref;
+  gfc_expr *exp;
+
+  exp = code->expr;
+
+  if (exp->expr_type != EXPR_VARIABLE)
+    return;
+
+  sym = exp->symtree->n.sym;
+  ts = &sym->ts;
+
+  /* Go to actual component transferred.  */
+  for (ref = code->expr->ref; ref; ref = ref->next)
+    if (ref->type == REF_COMPONENT)
+      ts = &ref->u.c.component->ts;
+
+  if (ts->type == BT_DERIVED)
+    {
+      /* Check that transferred derived type doesn't contain POINTER
+        components.  */
+      if (derived_pointer (ts->derived))
+       {
+         gfc_error ("Data transfer element at %L cannot have "
+                    "POINTER components", &code->loc);
+         return;
+       }
+
+      if (derived_inaccessible (ts->derived))
+       {
+         gfc_error ("Data transfer element at %L cannot have "
+                    "PRIVATE components",&code->loc);
+         return;
+       }
+    }
+
+  if (sym->as != NULL && sym->as->type == AS_ASSUMED_SIZE
+      && 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 ***********/
 
 /* Given a branch to a label and a namespace, if the branch is conforming.
@@ -3027,9 +3700,12 @@ resolve_branch (gfc_st_label * label, gfc_code * code)
 
   if (found == NULL)
     {
-      /* still nothing, so illegal.  */
-      gfc_error_now ("Label at %L is not in the same block as the "
-                    "GOTO statement at %L", &lp->where, &code->loc);
+      /* The label is not in an enclosing block, so illegal.  This was
+        allowed in Fortran 66, so we allow it as extension.  We also 
+        forego further checks if we run into this.  */
+      gfc_notify_std (GFC_STD_LEGACY,
+                     "Label at %L is not in the same block as the "
+                     "GOTO statement at %L", &lp->where, &code->loc);
       return;
     }
 
@@ -3169,7 +3845,7 @@ gfc_find_forall_index (gfc_expr *expr, gfc_symbol *symbol)
   switch (expr->expr_type)
     {
     case EXPR_VARIABLE:
-      assert (expr->symtree->n.sym);
+      gcc_assert (expr->symtree->n.sym);
 
       /* A scalar assignment  */
       if (!expr->ref)
@@ -3241,7 +3917,7 @@ gfc_find_forall_index (gfc_expr *expr, gfc_symbol *symbol)
       if (expr->ref)
         {
           tmp = expr->ref;
-          assert(expr->ref->type == REF_SUBSTRING);
+          gcc_assert (expr->ref->type == REF_SUBSTRING);
           if (gfc_find_forall_index (tmp->u.ss.start, symbol) == SUCCESS)
             return SUCCESS;
           if (gfc_find_forall_index (tmp->u.ss.end, symbol) == SUCCESS)
@@ -3255,23 +3931,27 @@ gfc_find_forall_index (gfc_expr *expr, gfc_symbol *symbol)
       gfc_error ("Unsupported statement while finding forall index in "
                  "expression");
       break;
-    default:
+
+    case EXPR_OP:
+      /* Find the FORALL index in the first operand.  */
+      if (expr->value.op.op1)
+       {
+         if (gfc_find_forall_index (expr->value.op.op1, symbol) == SUCCESS)
+           return SUCCESS;
+       }
+
+      /* Find the FORALL index in the second operand.  */
+      if (expr->value.op.op2)
+       {
+         if (gfc_find_forall_index (expr->value.op.op2, symbol) == SUCCESS)
+           return SUCCESS;
+       }
       break;
-    }
 
-  /* Find the FORALL index in the first operand.  */
-  if (expr->op1)
-    {
-      if (gfc_find_forall_index (expr->op1, symbol) == SUCCESS)
-        return SUCCESS;
+    default:
+      break;
     }
 
-  /* Find the FORALL index in the second operand.  */
-  if (expr->op2)
-    {
-      if (gfc_find_forall_index (expr->op2, symbol) == SUCCESS)
-        return SUCCESS;
-    }
   return FAILURE;
 }
 
@@ -3292,7 +3972,7 @@ gfc_resolve_assign_in_forall (gfc_code *code, int nvar, gfc_expr **var_expr)
       forall_index = var_expr[n]->symtree->n.sym;
 
       /* Check whether the assignment target is one of the FORALL index
-         variable. */
+         variable.  */
       if ((code->expr->expr_type == EXPR_VARIABLE)
           && (code->expr->symtree->n.sym == forall_index))
         gfc_error ("Assignment to a FORALL index variable at %L",
@@ -3371,7 +4051,7 @@ gfc_resolve_forall_body (gfc_code *code, int nvar, gfc_expr **var_expr)
           gfc_resolve_assign_in_forall (c, nvar, var_expr);
           break;
 
-        /* Because the resolve_blocks() will handle the nested FORALL,
+        /* Because the gfc_resolve_blocks() will handle the nested FORALL,
            there is no need to handle it here.  */
         case EXEC_FORALL:
           break;
@@ -3390,8 +4070,6 @@ gfc_resolve_forall_body (gfc_code *code, int nvar, gfc_expr **var_expr)
 /* Given a FORALL construct, first resolve the FORALL iterator, then call
    gfc_resolve_forall_body to resolve the FORALL body.  */
 
-static void resolve_blocks (gfc_code *, gfc_namespace *);
-
 static void
 gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
 {
@@ -3407,7 +4085,7 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
   if (forall_save == 0)
     {
       /* Count the total number of FORALL index in the nested FORALL
-         construct in order to allocate the VAR_EXPR with proper size.   */
+         construct in order to allocate the VAR_EXPR with proper size.  */
       next = code;
       while ((next != NULL) && (next->op == EXEC_FORALL))
         {
@@ -3416,7 +4094,7 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
           next = next->block->next;
         }
 
-      /* allocate VAR_EXPR with NUMBER_OF_FORALL_INDEX elements.   */
+      /* Allocate VAR_EXPR with NUMBER_OF_FORALL_INDEX elements.  */
       var_expr = (gfc_expr **) gfc_getmem (total_var * sizeof (gfc_expr *));
     }
 
@@ -3457,7 +4135,7 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
   gfc_resolve_forall_body (code, nvar, var_expr);
 
   /* May call gfc_resolve_forall to resolve the inner FORALL loop.  */
-  resolve_blocks (code->block, ns);
+  gfc_resolve_blocks (code->block, ns);
 
   /* Free VAR_EXPR after the whole FORALL construct resolved.  */
   for (i = 0; i < total_var; i++)
@@ -3474,8 +4152,8 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
 
 static void resolve_code (gfc_code *, gfc_namespace *);
 
-static void
-resolve_blocks (gfc_code * b, gfc_namespace * ns)
+void
+gfc_resolve_blocks (gfc_code * b, gfc_namespace * ns)
 {
   try t;
 
@@ -3513,6 +4191,23 @@ resolve_blocks (gfc_code * b, gfc_namespace * ns)
        case EXEC_FORALL:
        case EXEC_DO:
        case EXEC_DO_WHILE:
+       case EXEC_READ:
+       case EXEC_WRITE:
+       case EXEC_IOLENGTH:
+         break;
+
+       case EXEC_OMP_ATOMIC:
+       case EXEC_OMP_CRITICAL:
+       case EXEC_OMP_DO:
+       case EXEC_OMP_MASTER:
+       case EXEC_OMP_ORDERED:
+       case EXEC_OMP_PARALLEL:
+       case EXEC_OMP_PARALLEL_DO:
+       case EXEC_OMP_PARALLEL_SECTIONS:
+       case EXEC_OMP_PARALLEL_WORKSHARE:
+       case EXEC_OMP_SECTIONS:
+       case EXEC_OMP_SINGLE:
+       case EXEC_OMP_WORKSHARE:
          break;
 
        default:
@@ -3530,7 +4225,7 @@ resolve_blocks (gfc_code * b, gfc_namespace * ns)
 static void
 resolve_code (gfc_code * code, gfc_namespace * ns)
 {
-  int forall_save = 0;
+  int omp_workshare_save;
   code_stack frame;
   gfc_alloc *a;
   try t;
@@ -3545,15 +4240,44 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
 
       if (code->op == EXEC_FORALL)
        {
-         forall_save = forall_flag;
+         int forall_save = forall_flag;
+
          forall_flag = 1;
-          gfc_resolve_forall (code, ns, forall_save);
-        }
-      else
-        resolve_blocks (code->block, ns);
+         gfc_resolve_forall (code, ns, forall_save);
+         forall_flag = forall_save;
+       }
+      else if (code->block)
+       {
+         omp_workshare_save = -1;
+         switch (code->op)
+           {
+           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_PARALLEL:
+           case EXEC_OMP_PARALLEL_DO:
+           case EXEC_OMP_PARALLEL_SECTIONS:
+             omp_workshare_save = omp_workshare_flag;
+             omp_workshare_flag = 0;
+             gfc_resolve_omp_parallel_blocks (code, ns);
+             break;
+           case EXEC_OMP_DO:
+             gfc_resolve_omp_do_blocks (code, ns);
+             break;
+           case EXEC_OMP_WORKSHARE:
+             omp_workshare_save = omp_workshare_flag;
+             omp_workshare_flag = 1;
+             /* FALLTHROUGH */
+           default:
+             gfc_resolve_blocks (code->block, ns);
+             break;
+           }
 
-      if (code->op == EXEC_FORALL)
-       forall_flag = forall_save;
+         if (omp_workshare_save != -1)
+           omp_workshare_flag = omp_workshare_save;
+       }
 
       t = gfc_resolve_expr (code->expr);
       if (gfc_resolve_expr (code->expr2) == FAILURE)
@@ -3568,7 +4292,6 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
        case EXEC_EXIT:
        case EXEC_CONTINUE:
        case EXEC_DT_END:
-       case EXEC_TRANSFER:
        case EXEC_ENTRY:
          break;
 
@@ -3577,10 +4300,17 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
          break;
 
        case EXEC_GOTO:
-          if (code->expr != NULL && code->expr->ts.type != BT_INTEGER)
-            gfc_error ("ASSIGNED GOTO statement at %L requires an INTEGER "
+          if (code->expr != NULL)
+           {
+             if (code->expr->ts.type != BT_INTEGER)
+               gfc_error ("ASSIGNED GOTO statement at %L requires an INTEGER "
                        "variable", &code->expr->where);
-          else
+             else if (code->expr->symtree->n.sym->attr.assign != 1)
+               gfc_error ("Variable '%s' has not been assigned a target label "
+                       "at %L", code->expr->symtree->n.sym->name,
+                       &code->expr->where);
+           }
+         else
             resolve_branch (code->label, code);
          break;
 
@@ -3595,7 +4325,16 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
            break;
 
          if (gfc_extend_assign (code, ns) == SUCCESS)
-           goto call;
+           {
+             if (gfc_pure (NULL) && !gfc_pure (code->symtree->n.sym))
+               {
+                 gfc_error ("Subroutine '%s' called instead of assignment at "
+                            "%L must be PURE", code->symtree->n.sym->name,
+                            &code->loc);
+                 break;
+               }
+             goto call;
+           }
 
          if (gfc_pure (NULL))
            {
@@ -3625,9 +4364,14 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
           if (code->label->defined == ST_LABEL_UNKNOWN)
             gfc_error ("Label %d referenced at %L is never defined",
                        code->label->value, &code->label->where);
-          if (t == SUCCESS && code->expr->ts.type != BT_INTEGER)
-           gfc_error ("ASSIGN statement at %L requires an INTEGER "
-                      "variable", &code->expr->where);
+          if (t == SUCCESS
+             && (code->expr->expr_type != EXPR_VARIABLE
+                 || code->expr->symtree->n.sym->ts.type != BT_INTEGER
+                 || code->expr->symtree->n.sym->ts.kind 
+                       != gfc_default_integer_kind
+                 || code->expr->symtree->n.sym->as != NULL))
+           gfc_error ("ASSIGN statement at %L requires a scalar "
+                      "default INTEGER variable", &code->expr->where);
          break;
 
        case EXEC_POINTER_ASSIGN:
@@ -3670,7 +4414,11 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
 
        case EXEC_DO:
          if (code->ext.iterator != NULL)
-           gfc_resolve_iterator (code->ext.iterator);
+           {
+             gfc_iterator *iter = code->ext.iterator;
+             if (gfc_resolve_iterator (iter, true) != FAILURE)
+               gfc_resolve_do_iterator (code, iter->var->symtree->n.sym);
+           }
          break;
 
        case EXEC_DO_WHILE:
@@ -3690,7 +4438,7 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
                       "of type INTEGER", &code->expr->where);
 
          for (a = code->ext.alloc_list; a; a = a->next)
-           resolve_allocate_expr (a->expr);
+           resolve_allocate_expr (a->expr, code);
 
          break;
 
@@ -3723,6 +4471,7 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
        case EXEC_BACKSPACE:
        case EXEC_ENDFILE:
        case EXEC_REWIND:
+       case EXEC_FLUSH:
          if (gfc_resolve_filepos (code->ext.filepos) == FAILURE)
            break;
 
@@ -3737,7 +4486,7 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
          break;
 
        case EXEC_IOLENGTH:
-         assert(code->ext.inquire != NULL);
+         gcc_assert (code->ext.inquire != NULL);
          if (gfc_resolve_inquire (code->ext.inquire) == FAILURE)
            break;
 
@@ -3754,6 +4503,10 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
          resolve_branch (code->ext.dt->eor, code);
          break;
 
+       case EXEC_TRANSFER:
+         resolve_transfer (code);
+         break;
+
        case EXEC_FORALL:
          resolve_forall_iterators (code->ext.forall_iterator);
 
@@ -3763,6 +4516,29 @@ resolve_code (gfc_code * code, gfc_namespace * ns)
               &code->expr->where);
          break;
 
+       case EXEC_OMP_ATOMIC:
+       case EXEC_OMP_BARRIER:
+       case EXEC_OMP_CRITICAL:
+       case EXEC_OMP_FLUSH:
+       case EXEC_OMP_DO:
+       case EXEC_OMP_MASTER:
+       case EXEC_OMP_ORDERED:
+       case EXEC_OMP_SECTIONS:
+       case EXEC_OMP_SINGLE:
+       case EXEC_OMP_WORKSHARE:
+         gfc_resolve_omp_directive (code, ns);
+         break;
+
+       case EXEC_OMP_PARALLEL:
+       case EXEC_OMP_PARALLEL_DO:
+       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 ("resolve_code(): Bad statement code");
        }
@@ -3789,128 +4565,249 @@ resolve_values (gfc_symbol * sym)
 }
 
 
-/* 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.  */
+/* Resolve an index expression.  */
 
-static void
-resolve_symbol (gfc_symbol * sym)
+static try
+resolve_index_expr (gfc_expr * e)
 {
-  /* Zero if we are checking a formal namespace.  */
-  static int formal_ns_flag = 1;
-  int formal_ns_save, check_constant, mp_flag;
-  int i;
-  const char *whynot;
 
+  if (gfc_resolve_expr (e) == FAILURE)
+    return FAILURE;
+
+  if (gfc_simplify_expr (e, 0) == FAILURE)
+    return FAILURE;
 
-  if (sym->attr.flavor == FL_UNKNOWN)
+  if (gfc_specification_expr (e) == FAILURE)
+    return FAILURE;
+
+  return SUCCESS;
+}
+
+/* Resolve a charlen structure.  */
+
+static try
+resolve_charlen (gfc_charlen *cl)
+{
+  if (cl->resolved)
+    return SUCCESS;
+
+  cl->resolved = 1;
+
+  if (resolve_index_expr (cl->length) == FAILURE)
+    return FAILURE;
+
+  return SUCCESS;
+}
+
+
+/* Test for non-constant shape arrays. */
+
+static bool
+is_non_constant_shape_array (gfc_symbol *sym)
+{
+  gfc_expr *e;
+  int i;
+
+  if (sym->as != NULL)
     {
-      if (sym->attr.external == 0 && sym->attr.intrinsic == 0)
-       sym->attr.flavor = FL_VARIABLE;
-      else
+      /* 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; i++)
        {
-         sym->attr.flavor = FL_PROCEDURE;
-         if (sym->attr.dimension)
-           sym->attr.function = 1;
+         e = sym->as->lower[i];
+         if (e && (resolve_index_expr (e) == FAILURE
+               || !gfc_is_constant_expr (e)))
+           return true;
+
+         e = sym->as->upper[i];
+         if (e && (resolve_index_expr (e) == FAILURE
+               || !gfc_is_constant_expr (e)))
+           return true;
        }
     }
+  return false;
+}
 
-  /* 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);
+/* Resolution of common features of flavors variable and procedure. */
 
-  /* Assign default type to symbols that need one and don't have one.  */
-  if (sym->ts.type == BT_UNKNOWN)
+static try
+resolve_fl_var_and_proc (gfc_symbol *sym, int mp_flag)
+{
+  /* Constraints on deferred shape variable.  */
+  if (sym->as == NULL || sym->as->type != AS_DEFERRED)
     {
-      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.function)
+      if (sym->attr.allocatable)
        {
-         if (!mp_flag)
-           gfc_set_default_type (sym, 0, NULL);
+         if (sym->attr.dimension)
+           gfc_error ("Allocatable array '%s' at %L must have "
+                      "a deferred shape", sym->name, &sym->declared_at);
          else
-           {
-              /* Result may be in another namespace.  */
-             resolve_symbol (sym->result);
-
-             sym->ts = sym->result->ts;
-             sym->as = gfc_copy_array_spec (sym->result->as);
-           }
+           gfc_error ("Scalar object '%s' at %L may not be ALLOCATABLE",
+                      sym->name, &sym->declared_at);
+           return FAILURE;
        }
-    }
 
-  /* Assumed size arrays and assumed shape arrays must be dummy
-     arguments.  */ 
+      if (sym->attr.pointer && sym->attr.dimension)
+       {
+         gfc_error ("Array pointer '%s' at %L must have a deferred shape",
+                    sym->name, &sym->declared_at);
+         return FAILURE;
+       }
 
-  if (sym->as != NULL
-      && (sym->as->type == AS_ASSUMED_SIZE
-         || sym->as->type == AS_ASSUMED_SHAPE)
-      && sym->attr.dummy == 0)
+    }
+  else
     {
-      gfc_error ("Assumed %s array at %L must be a dummy argument",
-                sym->as->type == AS_ASSUMED_SIZE ? "size" : "shape",
-                 &sym->declared_at);
-      return;
+      if (!mp_flag && !sym->attr.allocatable
+            && !sym->attr.pointer && !sym->attr.dummy)
+       {
+         gfc_error ("Array '%s' at %L cannot have a deferred shape",
+                    sym->name, &sym->declared_at);
+         return FAILURE;
+        }
     }
+  return SUCCESS;
+}
 
-  /* A parameter array's shape needs to be constant.  */
+/* Resolve symbols with flavor variable.  */
 
-  if (sym->attr.flavor == FL_PARAMETER && sym->as != NULL 
-      && !gfc_is_compile_time_shape (sym->as))
-    {
-      gfc_error ("Parameter array '%s' at %L cannot be automatic "
-                "or assumed shape", sym->name, &sym->declared_at);
-         return;
-    }
+static try
+resolve_fl_variable (gfc_symbol *sym, int mp_flag)
+{
+  int flag;
+  int i;
+  gfc_expr *e;
+  gfc_expr *constructor_expr;
 
-  /* Make sure that character string variables with assumed length are
-     dummy arguments.  */
+  if (resolve_fl_var_and_proc (sym, mp_flag) == FAILURE)
+    return FAILURE;
 
-  if (sym->attr.flavor == FL_VARIABLE && !sym->attr.result
-      && sym->ts.type == BT_CHARACTER
-      && sym->ts.cl->length == NULL && sym->attr.dummy == 0)
+  /* The shape of a main program or module array needs to be constant.  */
+  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))
     {
-      gfc_error ("Entity with assumed character length at %L must be a "
-                "dummy argument or a PARAMETER", &sym->declared_at);
-      return;
+       gfc_error ("The module or main program array '%s' at %L must "
+                    "have constant shape", sym->name, &sym->declared_at);
+         return FAILURE;
     }
 
-  /* Make sure a parameter that has been implicitly typed still
-     matches the implicit type, since PARAMETER statements can precede
-     IMPLICIT statements.  */
+  if (sym->ts.type == BT_CHARACTER)
+    {
+      /* Make sure that character string variables with assumed length are
+        dummy arguments.  */
+      e = sym->ts.cl->length;
+      if (e == NULL && !sym->attr.dummy && !sym->attr.result)
+       {
+         gfc_error ("Entity with assumed character length at %L must be a "
+                    "dummy argument or a PARAMETER", &sym->declared_at);
+         return FAILURE;
+       }
 
-  if (sym->attr.flavor == FL_PARAMETER
-      && sym->attr.implicit_type
-      && !gfc_compare_types (&sym->ts, gfc_get_default_type (sym, sym->ns)))
-    gfc_error ("Implicitly typed PARAMETER '%s' at %L doesn't match a "
-              "later IMPLICIT type", sym->name, &sym->declared_at);
+      if (!gfc_is_constant_expr (e)
+           && !(e->expr_type == EXPR_VARIABLE
+           && e->symtree->n.sym->attr.flavor == FL_PARAMETER)
+           && sym->ns->proc_name
+           && (sym->ns->proc_name->attr.flavor == FL_MODULE
+                 || sym->ns->proc_name->attr.is_main_program)
+           && !sym->attr.use_assoc)
+       {
+         gfc_error ("'%s' at %L must have constant character length "
+                    "in this context", sym->name, &sym->declared_at);
+         return FAILURE;
+       }
+    }
 
-  /* 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.  */
+  /* Can the symbol have an initializer?  */
+  flag = 0;
+  if (sym->attr.allocatable || sym->attr.external || sym->attr.dummy
+       || sym->attr.intrinsic || sym->attr.result)
+    flag = 1;
+  else if (sym->attr.dimension && !sym->attr.pointer)
+    {
+      /* Don't allow initialization of automatic arrays.  */
+      for (i = 0; i < sym->as->rank; i++)
+       {
+         if (sym->as->lower[i] == NULL
+               || sym->as->lower[i]->expr_type != EXPR_CONSTANT
+               || sym->as->upper[i] == NULL
+               || sym->as->upper[i]->expr_type != EXPR_CONSTANT)
+           {
+             flag = 1;
+             break;
+           }
+       }
+  }
 
-  if (sym->attr.flavor == FL_PARAMETER
-      && 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);
+  /* Reject illegal initializers.  */
+  if (sym->value && flag)
+    {
+      if (sym->attr.allocatable)
+       gfc_error ("Allocatable '%s' at %L cannot have an initializer",
+                  sym->name, &sym->declared_at);
+      else if (sym->attr.external)
+       gfc_error ("External '%s' at %L cannot have an initializer",
+                  sym->name, &sym->declared_at);
+      else if (sym->attr.dummy)
+       gfc_error ("Dummy '%s' at %L cannot have an initializer",
+                  sym->name, &sym->declared_at);
+      else if (sym->attr.intrinsic)
+       gfc_error ("Intrinsic '%s' at %L cannot have an initializer",
+                  sym->name, &sym->declared_at);
+      else if (sym->attr.result)
+       gfc_error ("Function result '%s' at %L cannot have an initializer",
+                  sym->name, &sym->declared_at);
+      else
+       gfc_error ("Automatic array '%s' at %L cannot have an initializer",
+                  sym->name, &sym->declared_at);
+      return FAILURE;
+    }
 
-  /* Make sure symbols with known intent or optional are really dummy
-     variable.  Because of ENTRY statement, this has to be deferred
-     until resolution time.  */
+  /* 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."  */
 
-  if (! sym->attr.dummy
-      && (sym->attr.optional
-         || sym->attr.intent != INTENT_UNKNOWN))
+  constructor_expr = NULL;
+  if (sym->ts.type == BT_DERIVED && !(sym->value || flag))
+       constructor_expr = gfc_default_initializer (&sym->ts);
+
+  if (sym->ns->proc_name
+       && sym->ns->proc_name->attr.flavor == FL_MODULE
+       && constructor_expr
+       && !sym->ns->save_all && !sym->attr.save
+       && !sym->attr.pointer && !sym->attr.allocatable)
     {
-      gfc_error ("Symbol at %L is not a DUMMY variable", &sym->declared_at);
-      return;
+      gfc_error("Object '%s' at %L must have the SAVE attribute %s",
+               sym->name, &sym->declared_at,
+               "for default initialization of a component");
+      return FAILURE;
     }
 
+  /* Assign default initializer.  */
+  if (sym->ts.type == BT_DERIVED && !(sym->value || flag)
+       && !sym->attr.pointer)
+    sym->value = gfc_default_initializer (&sym->ts);
+
+  return SUCCESS;
+}
+
+
+/* Resolve a procedure.  */
+
+static try
+resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
+{
+  gfc_formal_arglist *arg;
+
+  if (sym->attr.function
+       && resolve_fl_var_and_proc (sym, mp_flag) == FAILURE)
+    return FAILURE;
+
   if (sym->attr.proc == PROC_ST_FUNCTION)
     {
       if (sym->ts.type == BT_CHARACTER)
@@ -3920,92 +4817,427 @@ resolve_symbol (gfc_symbol * sym)
             {
               gfc_error ("Character-valued statement function '%s' at %L must "
                          "have constant length", sym->name, &sym->declared_at);
-              return;
+              return FAILURE;
             }
         }
     }
 
-  /* Constraints on deferred shape variable.  */
-  if (sym->attr.flavor == FL_VARIABLE
-      || (sym->attr.flavor == FL_PROCEDURE
-         && sym->attr.function))
+  /* Ensure that derived type formal arguments of a public procedure
+     are not of a private type.  */
+  if (gfc_check_access(sym->attr.access, sym->ns->default_access))
     {
-      if (sym->as == NULL || sym->as->type != AS_DEFERRED)
+      for (arg = sym->formal; arg; arg = arg->next)
        {
-         if (sym->attr.allocatable)
+         if (arg->sym
+               && arg->sym->ts.type == BT_DERIVED
+               && !arg->sym->ts.derived->attr.use_assoc
+               && !gfc_check_access(arg->sym->ts.derived->attr.access,
+                       arg->sym->ts.derived->ns->default_access))
            {
-             if (sym->attr.dimension)
-               gfc_error ("Allocatable array at %L must have a deferred shape",
-                          &sym->declared_at);
-             else
-               gfc_error ("Object at %L may not be ALLOCATABLE",
-                          &sym->declared_at);
-             return;
+             gfc_error_now ("'%s' is of a PRIVATE type and cannot be "
+                            "a dummy argument of '%s', which is "
+                            "PUBLIC at %L", arg->sym->name, sym->name,
+                            &sym->declared_at);
+             /* Stop this message from recurring.  */
+             arg->sym->ts.derived->attr.access = ACCESS_PUBLIC;
+             return FAILURE;
            }
+       }
+    }
+
+  /* An external symbol may not have an intializer because it is taken to be
+     a procedure.  */
+  if (sym->attr.external && sym->value)
+    {
+      gfc_error ("External object '%s' at %L may not have an initializer",
+                sym->name, &sym->declared_at);
+      return FAILURE;
+    }
 
-         if (sym->attr.pointer && sym->attr.dimension)
+  /* 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.cl && sym->ts.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 '%s' at %L cannot be "
+                      "array-valued", sym->name, &sym->declared_at);
+
+         if (sym->attr.pointer)
+           gfc_error ("CHARACTER(*) function '%s' at %L cannot be "
+                      "pointer-valued", sym->name, &sym->declared_at);
+
+         if (sym->attr.pure)
+           gfc_error ("CHARACTER(*) function '%s' at %L cannot be "
+                      "pure", sym->name, &sym->declared_at);
+
+         if (sym->attr.recursive)
+           gfc_error ("CHARACTER(*) function '%s' at %L cannot be "
+                      "recursive", sym->name, &sym->declared_at);
+
+         return FAILURE;
+       }
+
+      /* Appendix B.2 of the standard.  Contained functions give an
+        error anyway.  Fixed-form is likely to be F77/legacy.  */
+      if (!sym->attr.contained && gfc_current_form != FORM_FIXED)
+       gfc_notify_std (GFC_STD_F95_OBS, "CHARACTER(*) function "
+                       "'%s' at %L is obsolescent in fortran 95",
+                       sym->name, &sym->declared_at);
+    }
+  return SUCCESS;
+}
+
+
+/* Resolve the components of a derived type.  */
+
+static try
+resolve_fl_derived (gfc_symbol *sym)
+{
+  gfc_component *c;
+  gfc_dt_list * dt_list;
+  int i;
+
+  for (c = sym->components; c != NULL; c = c->next)
+    {
+      if (c->ts.type == BT_CHARACTER)
+       {
+        if (c->ts.cl->length == NULL
+            || (resolve_charlen (c->ts.cl) == FAILURE)
+            || !gfc_is_constant_expr (c->ts.cl->length))
+          {
+            gfc_error ("Character length of component '%s' needs to "
+                       "be a constant specification expression at %L.",
+                       c->name,
+                       c->ts.cl->length ? &c->ts.cl->length->where : &c->loc);
+            return FAILURE;
+          }
+       }
+
+      if (c->ts.type == BT_DERIVED
+           && sym->component_access != ACCESS_PRIVATE
+           && gfc_check_access(sym->attr.access, sym->ns->default_access)
+           && !c->ts.derived->attr.use_assoc
+           && !gfc_check_access(c->ts.derived->attr.access,
+                                c->ts.derived->ns->default_access))
+       {
+         gfc_error ("The component '%s' is a PRIVATE type and cannot be "
+                    "a component of '%s', which is PUBLIC at %L",
+                     c->name, sym->name, &sym->declared_at);
+         return FAILURE;
+       }
+
+      if (c->pointer || c->as == NULL)
+       continue;
+
+      for (i = 0; i < c->as->rank; i++)
+       {
+         if (c->as->lower[i] == NULL
+               || !gfc_is_constant_expr (c->as->lower[i])
+               || (resolve_index_expr (c->as->lower[i]) == FAILURE)
+               || c->as->upper[i] == NULL
+               || (resolve_index_expr (c->as->upper[i]) == FAILURE)
+               || !gfc_is_constant_expr (c->as->upper[i]))
            {
-             gfc_error ("Pointer to array at %L must have a deferred shape",
-                        &sym->declared_at);
-             return;
+             gfc_error ("Component '%s' of '%s' at %L must have "
+                        "constant array bounds.",
+                        c->name, sym->name, &c->loc);
+             return FAILURE;
            }
-
        }
-      else
+    }
+    
+  /* Add derived type to the derived type list.  */
+  dt_list = gfc_get_dt_list ();
+  dt_list->next = sym->ns->derived_types;
+  dt_list->derived = sym;
+  sym->ns->derived_types = dt_list;
+
+  return SUCCESS;
+}
+
+
+static try
+resolve_fl_namelist (gfc_symbol *sym)
+{
+  gfc_namelist *nl;
+  gfc_symbol *nlsym;
+
+  /* Reject PRIVATE objects in a PUBLIC namelist.  */
+  if (gfc_check_access(sym->attr.access, sym->ns->default_access))
+    {
+      for (nl = sym->namelist; nl; nl = nl->next)
        {
-         if (!mp_flag && !sym->attr.allocatable
-             && !sym->attr.pointer && !sym->attr.dummy)
+         if (!nl->sym->attr.use_assoc
+               && !(sym->ns->parent == nl->sym->ns)
+                      && !gfc_check_access(nl->sym->attr.access,
+                                           nl->sym->ns->default_access))
            {
-             gfc_error ("Array at %L cannot have a deferred shape",
+             gfc_error ("PRIVATE symbol '%s' cannot be member of "
+                        "PUBLIC namelist at %L", nl->sym->name,
                         &sym->declared_at);
-             return;
+             return FAILURE;
            }
        }
     }
 
-  if (sym->attr.flavor == FL_VARIABLE)
+    /* Reject namelist arrays that are not constant shape.  */
+    for (nl = sym->namelist; nl; nl = nl->next)
+      {
+       if (is_non_constant_shape_array (nl->sym))
+         {
+           gfc_error ("The array '%s' must have constant shape to be "
+                      "a NAMELIST object at %L", nl->sym->name,
+                      &sym->declared_at);
+           return FAILURE;
+         }
+    }
+
+  /* 14.1.2 A module or internal procedure represent local entities
+     of the same type as a namelist member and so are not allowed.
+     Note that this is sometimes caught by check_conflict so the
+     same message has been used.  */
+  for (nl = sym->namelist; nl; nl = nl->next)
     {
-      /* Can the sybol have an initializer?  */
-      whynot = NULL;
-      if (sym->attr.allocatable)
-       whynot = "Allocatable";
-      else if (sym->attr.external)
-       whynot = "External";
-      else if (sym->attr.dummy)
-       whynot = "Dummy";
-      else if (sym->attr.intrinsic)
-       whynot = "Intrinsic";
-      else if (sym->attr.result)
-       whynot = "Function Result";
-      else if (sym->attr.dimension && !sym->attr.pointer)
+      nlsym = NULL;
+       if (sym->ns->parent && nl->sym && nl->sym->name)
+         gfc_find_symbol (nl->sym->name, sym->ns->parent, 0, &nlsym);
+       if (nlsym && nlsym->attr.flavor == FL_PROCEDURE)
+         {
+           gfc_error ("PROCEDURE attribute conflicts with NAMELIST "
+                      "attribute in '%s' at %L", nlsym->name,
+                      &sym->declared_at);
+           return FAILURE;
+         }
+    }
+
+  return SUCCESS;
+}
+
+
+static try
+resolve_fl_parameter (gfc_symbol *sym)
+{
+  /* A parameter array's shape needs to be constant.  */
+  if (sym->as != NULL && !gfc_is_compile_time_shape (sym->as))
+    {
+      gfc_error ("Parameter array '%s' at %L cannot be automatic "
+                "or assumed shape", sym->name, &sym->declared_at);
+      return FAILURE;
+    }
+
+  /* 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, sym->ns)))
+    {
+      gfc_error ("Implicitly typed PARAMETER '%s' at %L doesn't match a "
+                "later IMPLICIT type", sym->name, &sym->declared_at);
+      return FAILURE;
+    }
+
+  /* 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 FAILURE;
+    }
+  return SUCCESS;
+}
+
+
+/* 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)
+{
+  /* Zero if we are checking a formal namespace.  */
+  static int formal_ns_flag = 1;
+  int formal_ns_save, check_constant, mp_flag;
+  gfc_symtree *symtree;
+  gfc_symtree *this_symtree;
+  gfc_namespace *ns;
+  gfc_component *c;
+
+  if (sym->attr.flavor == FL_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)
        {
-         /* Don't allow initialization of automatic arrays.  */
-         for (i = 0; i < sym->as->rank; i++)
+         symtree = gfc_find_symtree (ns->sym_root, sym->name);
+         if (symtree && symtree->n.sym->generic)
            {
-             if (sym->as->lower[i] == NULL
-                 || sym->as->lower[i]->expr_type != EXPR_CONSTANT
-                 || sym->as->upper[i] == NULL
-                 || sym->as->upper[i]->expr_type != EXPR_CONSTANT)
-               {
-                 whynot = "Automatic array";
-                 break;
-               }
+             this_symtree = gfc_find_symtree (gfc_current_ns->sym_root,
+                                              sym->name);
+             sym->refs--;
+             if (!sym->refs)
+               gfc_free_symbol (sym);
+             symtree->n.sym->refs++;
+             this_symtree->n.sym = symtree->n.sym;
+             return;
            }
        }
 
-      /* Reject illegal initializers.  */
-      if (sym->value && whynot)
+      /* Otherwise give it a flavor according to such attributes as
+        it has.  */
+      if (sym->attr.external == 0 && sym->attr.intrinsic == 0)
+       sym->attr.flavor = FL_VARIABLE;
+      else
        {
-         gfc_error ("%s '%s' at %L cannot have an initializer",
-                    whynot, sym->name, &sym->declared_at);
-         return;
+         sym->attr.flavor = FL_PROCEDURE;
+         if (sym->attr.dimension)
+           sym->attr.function = 1;
        }
+    }
+
+  if (sym->attr.flavor == FL_DERIVED && resolve_fl_derived (sym) == FAILURE)
+    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);
+
+  /* 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);
 
-      /* Assign default initializer.  */
-      if (sym->ts.type == BT_DERIVED && !(sym->value || whynot))
-       sym->value = gfc_default_initializer (&sym->ts);
+      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)
+           gfc_set_default_type (sym, sym->attr.external, NULL);
+         else
+           {
+              /* Result may be in another namespace.  */
+             resolve_symbol (sym->result);
+
+             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;
+           }
+       }
     }
 
+  /* Assumed size arrays and assumed shape arrays must be dummy
+     arguments.  */ 
+
+  if (sym->as != NULL
+      && (sym->as->type == AS_ASSUMED_SIZE
+         || sym->as->type == AS_ASSUMED_SHAPE)
+      && sym->attr.dummy == 0)
+    {
+      if (sym->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;
+    }
+
+  /* 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 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->ts.derived->components == NULL)
+    {
+      gfc_error ("The derived type '%s' at %L is of type '%s', "
+                "which has not been defined.", sym->name,
+                 &sym->declared_at, sym->ts.derived->name);
+      sym->ts.type = BT_UNKNOWN;
+      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.derived->components; c; c = c->next)
+       {
+         if (c->initializer)
+           {
+             gfc_error ("The INTENT(OUT) dummy argument '%s' at %L is "
+                        "ASSUMED SIZE and so cannot have a default initializer",
+                        sym->name, &sym->declared_at);
+             return;
+           }
+       }
+    }
+
+  switch (sym->attr.flavor)
+    {
+    case FL_VARIABLE:
+      if (resolve_fl_variable (sym, mp_flag) == FAILURE)
+       return;
+      break;
+
+    case FL_PROCEDURE:
+      if (resolve_fl_procedure (sym, mp_flag) == FAILURE)
+       return;
+      break;
+
+    case FL_NAMELIST:
+      if (resolve_fl_namelist (sym) == FAILURE)
+       return;
+      break;
+
+    case FL_PARAMETER:
+      if (resolve_fl_parameter (sym) == FAILURE)
+       return;
+
+      break;
+
+    default:
+
+      break;
+    }
 
   /* Make sure that intrinsic exist */
   if (sym->attr.intrinsic
@@ -4014,7 +5246,7 @@ resolve_symbol (gfc_symbol * sym)
     gfc_error("Intrinsic at %L does not exist", &sym->declared_at);
 
   /* Resolve array specifier. Check as well some constraints
-     on COMMON blocks. */
+     on COMMON blocks.  */
 
   check_constant = sym->attr.in_common && !sym->attr.pointer;
   gfc_resolve_array_spec (sym->as, check_constant);
@@ -4028,6 +5260,14 @@ resolve_symbol (gfc_symbol * sym)
       gfc_resolve (sym->formal_ns);
       formal_ns_flag = formal_ns_save;
     }
+
+  /* Check threadprivate restrictions.  */
+  if (sym->attr.threadprivate && !sym->attr.save
+      && (!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);
 }
 
 
@@ -4037,7 +5277,7 @@ resolve_symbol (gfc_symbol * sym)
 static struct
 {
   gfc_data_value *vnode;
-  int left;
+  unsigned int left;
 }
 values;
 
@@ -4047,7 +5287,6 @@ values;
 static try
 next_data_value (void)
 {
-
   while (values.left == 0)
     {
       if (values.vnode->next == NULL)
@@ -4057,7 +5296,6 @@ next_data_value (void)
       values.left = values.vnode->repeat;
     }
 
-  values.left--;
   return SUCCESS;
 }
 
@@ -4085,8 +5323,18 @@ check_data_variable (gfc_data_variable * var, locus * where)
   if (e->expr_type != EXPR_VARIABLE)
     gfc_internal_error ("check_data_variable(): Bad expression");
 
+  if (e->symtree->n.sym->ns->is_block_data
+       && !e->symtree->n.sym->attr.in_common)
+    {
+      gfc_error ("BLOCK DATA element '%s' at %L must be in COMMON",
+                e->symtree->n.sym->name, &e->symtree->n.sym->declared_at);
+    }
+
   if (e->rank == 0)
-    mpz_init_set_ui (size, 1);
+    {
+      mpz_init_set_ui (size, 1);
+      ref = NULL;
+    }
   else
     {
       ref = e->ref;
@@ -4100,9 +5348,9 @@ check_data_variable (gfc_data_variable * var, locus * where)
            continue;
          break;
        }
-      assert (ref);
+      gcc_assert (ref);
 
-      /* Set marks asscording to the reference pattern.  */
+      /* Set marks according to the reference pattern.  */
       switch (ref->u.ar.type)
        {
        case AR_FULL:
@@ -4117,7 +5365,7 @@ check_data_variable (gfc_data_variable * var, locus * where)
          break;
 
        default:
-         abort();
+         gcc_unreachable ();
        }
 
       if (gfc_array_size (e, &size) == FAILURE)
@@ -4145,19 +5393,54 @@ check_data_variable (gfc_data_variable * var, locus * where)
       if (t == FAILURE)
        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.  */
+      /* ??? Only done for full arrays for now, since array sections
+        seem tricky.  */
+      if (mark == AR_FULL && ref && ref->next == NULL
+         && values.left > 1 && mpz_cmp_ui (size, 1) > 0)
+       {
+         mpz_t range;
+
+         if (mpz_cmp_ui (size, values.left) >= 0)
+           {
+             mpz_init_set_ui (range, values.left);
+             mpz_sub_ui (size, size, values.left);
+             values.left = 0;
+           }
+         else
+           {
+             mpz_init_set (range, size);
+             values.left -= mpz_get_ui (size);
+             mpz_set_ui (size, 0);
+           }
+
+         gfc_assign_data_value_range (var->expr, values.vnode->expr,
+                                      offset, range);
+
+         mpz_add (offset, offset, range);
+         mpz_clear (range);
+       }
+
       /* Assign initial value to symbol.  */
-      gfc_assign_data_value (var->expr, values.vnode->expr, offset);
+      else
+       {
+         values.left -= 1;
+         mpz_sub_ui (size, size, 1);
 
-      if (mark == AR_FULL)
-        mpz_add_ui (offset, offset, 1);
+         gfc_assign_data_value (var->expr, values.vnode->expr, offset);
 
-      /* 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_FULL)
+           mpz_add_ui (offset, offset, 1);
 
-      mpz_sub_ui (size, size, 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++)
@@ -4253,7 +5536,6 @@ traverse_data_var (gfc_data_variable * var, locus * where)
 static try
 resolve_data_variables (gfc_data_variable * d)
 {
-
   for (; d; d = d->next)
     {
       if (d->list == NULL)
@@ -4263,7 +5545,7 @@ resolve_data_variables (gfc_data_variable * d)
        }
       else
        {
-         if (gfc_resolve_iterator (&d->iter) == FAILURE)
+         if (gfc_resolve_iterator (&d->iter, false) == FAILURE)
            return FAILURE;
 
          if (d->iter.start->expr_type != EXPR_CONSTANT
@@ -4287,7 +5569,6 @@ resolve_data_variables (gfc_data_variable * d)
 static void
 resolve_data (gfc_data * d)
 {
-
   if (resolve_data_variables (d->var) == FAILURE)
     return;
 
@@ -4312,7 +5593,6 @@ resolve_data (gfc_data * d)
 int
 gfc_impure_variable (gfc_symbol * sym)
 {
-
   if (sym->attr.use_assoc || sym->attr.in_common)
     return 1;
 
@@ -4364,38 +5644,92 @@ gfc_elemental (gfc_symbol * sym)
 /* Warn about unused labels.  */
 
 static void
-warn_unused_label (gfc_namespace * ns)
+warn_unused_label (gfc_st_label * label)
 {
-  gfc_st_label *l;
-
-  l = ns->st_labels;
-  if (l == NULL)
+  if (label == NULL)
     return;
 
-  while (l->next)
-    l = l->next;
+  warn_unused_label (label->left);
 
-  for (; l; l = l->prev)
-    {
-      if (l->defined == ST_LABEL_UNKNOWN)
-       continue;
+  if (label->defined == ST_LABEL_UNKNOWN)
+    return;
 
-      switch (l->referenced)
-       {
-       case ST_LABEL_UNKNOWN:
-         gfc_warning ("Label %d at %L defined but not used", l->value,
-                      &l->where);
-         break;
+  switch (label->referenced)
+    {
+    case ST_LABEL_UNKNOWN:
+      gfc_warning ("Label %d at %L defined but not used", label->value,
+                  &label->where);
+      break;
 
-       case ST_LABEL_BAD_TARGET:
-         gfc_warning ("Label %d at %L defined but cannot be used", l->value,
-                      &l->where);
-         break;
+    case ST_LABEL_BAD_TARGET:
+      gfc_warning ("Label %d at %L defined but cannot be used",
+                  label->value, &label->where);
+      break;
 
-       default:
-         break;
-       }
+    default:
+      break;
     }
+
+  warn_unused_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.derived->components == NULL)
+       return SEQ_NONDEFAULT;
+
+      result = sequence_type (ts.derived->components->ts);
+      for (c = ts.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;
+  }
 }
 
 
@@ -4428,7 +5762,14 @@ resolve_equivalence_derived (gfc_symbol *derived, gfc_symbol *sym, gfc_expr *e)
          in the structure.  */
       if (c->pointer)
         {
-          gfc_error ("Derived type variable '%s' at %L has pointer componet(s) "
+          gfc_error ("Derived type variable '%s' at %L with pointer component(s) "
+                     "cannot be an EQUIVALENCE object", sym->name, &e->where);
+          return FAILURE;
+        }
+
+      if (c->initializer)
+        {
+          gfc_error ("Derived type variable '%s' at %L with default initializer "
                      "cannot be an EQUIVALENCE object", sym->name, &e->where);
           return FAILURE;
         }
@@ -4438,62 +5779,134 @@ resolve_equivalence_derived (gfc_symbol *derived, gfc_symbol *sym, gfc_expr *e)
 
 
 /* Resolve equivalence object. 
-   An EQUIVALENCE object shall not be a dummy argument, a pointer, an
-   allocatable array, an object of nonsequence derived type, an object of
+   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.  */
+   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.
+   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 *derived;
+  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;
+  const char *value_name;
+  const char *msg;
 
-  for (; eq; eq = eq->eq)
+  value_name = NULL;
+  last_ts = &eq->expr->symtree->n.sym->ts;
+
+  first_sym = eq->expr->symtree->n.sym;
+
+  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_int_expr (1);
+                 ref->u.ss.start = start;
+                 if (end == NULL && e->ts.cl)
+                   end = gfc_copy_expr (e->ts.cl->length);
+                 ref->u.ss.end = end;
+                 ref->u.ss.length = e->ts.cl;
+                 e->ts.cl = NULL;
+               }
+             ref = ref->next;
+             gfc_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) == FAILURE)
         continue;
 
       sym = e->symtree->n.sym;
-     
-      /* Shall not be a dummy argument.  */
-      if (sym->attr.dummy)
-        {
-          gfc_error ("Dummy argument '%s' at %L cannot be an EQUIVALENCE "
-                     "object", sym->name, &e->where);
-          continue;
-        }
 
-      /* Shall not be an allocatable array.  */
-      if (sym->attr.allocatable)
-        {
-          gfc_error ("Allocatable array '%s' at %L cannot be an EQUIVALENCE "
-                     "object", sym->name, &e->where);
-          continue;
-        }
+      /* An equivalence statement cannot have more than one initialized
+        object.  */
+      if (sym->value)
+       {
+         if (value_name != NULL)
+           {
+             gfc_error ("Initialized objects '%s' and '%s'  cannot both "
+                        "be in the EQUIVALENCE statement at %L",
+                        value_name, sym->name, &e->where);
+             continue;
+           }
+         else
+           value_name = sym->name;
+       }
 
-      /* Shall not be a pointer.  */
-      if (sym->attr.pointer)
-        {
-          gfc_error ("Pointer '%s' at %L cannot be an EQUIVALENCE object",
-                     sym->name, &e->where);
-          continue;
-        }
-      
-      /* Shall not be a function name, ...  */
-      if (sym->attr.function || sym->attr.result || sym->attr.entry
-          || sym->attr.subroutine)
+      /* 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)
         {
-          gfc_error ("Entity '%s' at %L cannot be an EQUIVALENCE object",
-                     sym->name, &e->where);
-          continue;
+          gfc_error ("Common block member '%s' at %L cannot be an EQUIVALENCE "
+                    "object in the pure procedure '%s'",
+                    sym->name, &e->where, sym->ns->proc_name->name);
+          break;
         }
-
       /* Shall not be a named constant.  */      
       if (e->expr_type == EXPR_CONSTANT)
         {
@@ -4506,6 +5919,69 @@ resolve_equivalence (gfc_equiv *eq)
       if (derived && resolve_equivalence_derived (derived, sym, e) == FAILURE)
         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) == FAILURE)
+          ||  (eq_type == SEQ_MIXED
+              && gfc_notify_std (GFC_STD_GNU, msg,sym->name,
+                                 &e->where) == FAILURE))
+       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) == FAILURE)
+          ||  (eq_type == SEQ_NONDEFAULT
+              && gfc_notify_std (GFC_STD_GNU, msg, sym->name,
+                                 &e->where) == FAILURE))
+       continue;
+
+      msg ="Non-CHARACTER object '%s' 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) == FAILURE)
+               continue;
+
+      msg ="Non-NUMERIC object '%s' 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) == FAILURE)
+               continue;
+
+  identical_types:
+      last_ts =&sym->ts;
+      last_where = &e->where;
+
       if (!e->ref)
         continue;
 
@@ -4518,46 +5994,106 @@ resolve_equivalence (gfc_equiv *eq)
           continue;
         }
 
-      /* Shall not be a structure component.  */
       r = e->ref;
       while (r)
         {
-          if (r->type == REF_COMPONENT)
-            {
-              gfc_error ("Structure component '%s' at %L cannot be an "
-                         "EQUIVALENCE object",
-                         r->u.c.component->name, &e->where);
-              break;
-            }
-          r = r->next;
-        }
+         /* Shall not be a structure component.  */
+         if (r->type == REF_COMPONENT)
+           {
+             gfc_error ("Structure component '%s' 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;
+       }
     }    
 }      
-      
-      
-/* 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)
+
+/* Resolve function and ENTRY types, issue diagnostics if needed. */
+
+static void
+resolve_fntype (gfc_namespace * ns)
 {
-  gfc_namespace *old_ns, *n;
+  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) == FAILURE
+      && !sym->attr.untyped)
+    {
+      gfc_error ("Function '%s' at %L has no IMPLICIT type",
+                sym->name, &sym->declared_at);
+      sym->attr.untyped = 1;
+    }
+
+  if (sym->ts.type == BT_DERIVED && !sym->ts.derived->attr.use_assoc
+      && !gfc_check_access (sym->ts.derived->attr.access,
+                            sym->ts.derived->ns->default_access)
+      && gfc_check_access (sym->attr.access, sym->ns->default_access))
+    {
+      gfc_error ("PUBLIC function '%s' at %L cannot be of PRIVATE type '%s'",
+                 sym->name, &sym->declared_at, sym->ts.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) == FAILURE
+           && !el->sym->attr.untyped)
+         {
+           gfc_error ("ENTRY '%s' at %L has no IMPLICIT type",
+                      el->sym->name, &el->sym->declared_at);
+           el->sym->attr.untyped = 1;
+         }
+      }
+}
+
+
+/* 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 resolve_code.  */
+
+static void
+resolve_types (gfc_namespace * ns)
+{
+  gfc_namespace *n;
   gfc_charlen *cl;
   gfc_data *d;
   gfc_equiv *eq;
 
-  old_ns = gfc_current_ns;
   gfc_current_ns = ns;
 
-  resolve_entries (ns);
-
-  resolve_contained_functions (ns);
-
   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))
@@ -4565,22 +6101,14 @@ gfc_resolve (gfc_namespace * ns)
                   "also be PURE", n->proc_name->name,
                   &n->proc_name->declared_at);
 
-      gfc_resolve (n);
+      resolve_types (n);
     }
 
   forall_flag = 0;
   gfc_check_interfaces (ns);
 
   for (cl = ns->cl_list; cl; cl = cl->next)
-    {
-      if (cl->length == NULL || gfc_resolve_expr (cl->length) == FAILURE)
-       continue;
-
-      if (cl->length->ts.type != BT_INTEGER)
-       gfc_error
-         ("Character length specification at %L must be of type INTEGER",
-          &cl->length->where);
-    }
+    resolve_charlen (cl);
 
   gfc_traverse_ns (ns, resolve_values);
 
@@ -4597,13 +6125,44 @@ gfc_resolve (gfc_namespace * ns)
   for (eq = ns->equiv; eq; eq = eq->next)
     resolve_equivalence (eq);
 
+  /* Warn about unused labels.  */
+  if (gfc_option.warn_unused_labels)
+    warn_unused_label (ns->st_labels);
+}
+
+
+/* Call resolve_code recursively.  */
+
+static void
+resolve_codes (gfc_namespace * ns)
+{
+  gfc_namespace *n;
+
+  for (n = ns->contained; n; n = n->sibling)
+    resolve_codes (n);
+
+  gfc_current_ns = ns;
   cs_base = NULL;
   resolve_code (ns->code, ns);
+}
 
-  /* Warn about unused labels.  */
-  if (gfc_option.warn_unused_labels)
-    warn_unused_label (ns);
+
+/* 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;
+
+  old_ns = gfc_current_ns;
+
+  resolve_contained_functions (ns);
+  resolve_types (ns);
+  resolve_codes (ns);
 
   gfc_current_ns = old_ns;
 }
-