diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index c922b8d94d86edb77caee7fb64a04a589b9c1d52..bbcee7a9f4c595bbd28563e14d536da0c45dcbc2 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,73 @@
+2006-08-20  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/28601
+	PR fortran/28630
+	* gfortran.h : Eliminate gfc_dt_list structure and reference
+	to it in gfc_namespace.
+	* resolve.c (resolve_fl_derived): Remove the building of the
+	list of derived types for the current namespace.
+	* symbol.c (find_renamed_type): New function to find renamed
+	derived types by symbol name rather than symtree name.
+	(gfc_use_derived): Search parent namespace for identical
+	derived type and use it, even if local version is complete,
+	except in interface bodies. Ensure that renamed derived types
+	are found by call to find_renamed_type. Recurse for derived
+	type components.
+	(gfc_free_dt_list): Remove.
+	(gfc_free_namespace): Remove call to previous.
+	* trans-types.c (copy_dt_decls_ifequal): Remove.
+	(gfc_get_derived_type): Remove all the paraphenalia for
+	association of derived types, including calls to previous.
+	* match.c (gfc_match_allocate): Call gfc_use_derived to
+	associate any derived types that are being allocated.
+
+	PR fortran/20886
+	* resolve.c (resolve_actual_arglist): The passing of
+	a generic procedure name as an actual argument is an
+	error.
+
+	PR fortran/28735
+	* resolve.c (resolve_variable): Check for a symtree before
+	resolving references.
+
+	PR fortran/28762
+	* primary.c (match_variable): Return MATCH_NO if the symbol
+	is that of the program.
+
+	PR fortran/28425
+	* trans-expr.c (gfc_trans_subcomponent_assign): Translate
+	derived type component expressions other than another derived
+	type constructor.
+
+	PR fortran/28496
+	* expr.c (find_array_section): Correct errors in
+	the handling of a missing start value for the
+	index triplet in an array reference.
+
+	PR fortran/18111
+	* trans-decl.c (gfc_build_dummy_array_decl): Before resetting
+	reference to backend_decl, set it DECL_ARTIFICIAL.
+	(gfc_get_symbol_decl): Likewise for original dummy decl, when
+	a copy is made of an array.
+	(create_function_arglist): Likewise for the _entry paramter
+	in entry_masters.
+	(build_entry_thunks): Likewise for dummies in entry thunks.
+
+	PR fortran/28600
+	* trans-decl.c (gfc_get_symbol_decl): Ensure that the
+	DECL_CONTEXT of the length of a character dummy is the
+	same as that of the symbol declaration.
+
+	PR fortran/28771
+	* decl.c (add_init_expr_to_sym): Remove setting of charlen for
+	an initializer of an assumed charlen variable.
+
+	PR fortran/28660
+	* trans-decl.c (generate_expr_decls): New function.
+	(generate_dependency_declarations): New function.
+	(generate_local_decl): Call previous if not either a dummy or
+	a declaration in an entry master.
+
 2006-08-19  Erik Edelmann  <eedelman@gcc.gnu.org>
 
 	PR fortran/25217
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index fb980d63451b6e9cf1181e85a0396ff2c03027dc..79310e9dfbead117f58822230795a5323e8beb0d 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -875,12 +875,6 @@ add_init_expr_to_sym (const char *name, gfc_expr ** initp,
 	      sym->ts.cl = gfc_get_charlen ();
 	      sym->ts.cl->next = gfc_current_ns->cl_list;
 	      gfc_current_ns->cl_list = sym->ts.cl;
-
-	      if (init->expr_type == EXPR_CONSTANT)
-		sym->ts.cl->length =
-			gfc_int_expr (init->value.character.length);
-	      else if (init->expr_type == EXPR_ARRAY)
-		sym->ts.cl->length = gfc_copy_expr (init->ts.cl->length);
 	    }
 	  /* Update initializer character length according symbol.  */
 	  else if (sym->ts.cl->length->expr_type == EXPR_CONSTANT)
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 4b037983616f56769a021ead2287499bb862be16..b1f064d0720c542d893504c51492527b04979f3c 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -1014,6 +1014,7 @@ find_array_section (gfc_expr *expr, gfc_ref *ref)
   int rank;
   int d;
   long unsigned one = 1;
+  mpz_t start[GFC_MAX_DIMENSIONS];
   mpz_t end[GFC_MAX_DIMENSIONS];
   mpz_t stride[GFC_MAX_DIMENSIONS];
   mpz_t delta[GFC_MAX_DIMENSIONS];
@@ -1052,6 +1053,7 @@ find_array_section (gfc_expr *expr, gfc_ref *ref)
   for (d = 0; d < rank; d++)
     {
       mpz_init (delta[d]);
+      mpz_init (start[d]);
       mpz_init (end[d]);
       mpz_init (ctr[d]);
       mpz_init (stride[d]);
@@ -1085,15 +1087,16 @@ find_array_section (gfc_expr *expr, gfc_ref *ref)
 	mpz_set_ui (stride[d], one);
 
       /* Obtain the start value for the index.  */
-      if (begin->value.integer)
-	  mpz_set (ctr[d], begin->value.integer);
+      if (begin)
+	  mpz_set (start[d], begin->value.integer);
       else
 	{
 	  if (mpz_cmp_si (stride[d], 0) < 0)
-	    mpz_set (ctr[d], upper->value.integer);
+	    mpz_set (start[d], upper->value.integer);
 	  else
-	    mpz_set (ctr[d], lower->value.integer);
+	    mpz_set (start[d], lower->value.integer);
 	}
+      mpz_set (ctr[d], start[d]);
 
       /* Obtain the end value for the index.  */
       if (finish)
@@ -1171,7 +1174,7 @@ find_array_section (gfc_expr *expr, gfc_ref *ref)
 	  if (mpz_cmp_ui (stride[d], 0) > 0 ?
 		mpz_cmp (ctr[d], tmp_mpz) > 0 :
 		mpz_cmp (ctr[d], tmp_mpz) < 0)
-	    mpz_set (ctr[d], ref->u.ar.start[d]->value.integer);
+	    mpz_set (ctr[d], start[d]);
 	  else
 	    mpz_set_ui (stop, 0);
 	}
@@ -1205,6 +1208,7 @@ cleanup:
   for (d = 0; d < rank; d++)
     {
       mpz_clear (delta[d]);
+      mpz_clear (start[d]);
       mpz_clear (end[d]);
       mpz_clear (ctr[d]);
       mpz_clear (stride[d]);
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 01bcf976e54686275cc805184bc19af17ae729f9..14e2ce6bdb0c97d7f6453f3026090bc03a543a0e 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -927,17 +927,6 @@ typedef struct gfc_symtree
 }
 gfc_symtree;
 
-/* A linked list of derived types in the namespace.  */
-typedef struct gfc_dt_list
-{
-  struct gfc_symbol *derived;
-  struct gfc_dt_list *next;
-}
-gfc_dt_list;
-
-#define gfc_get_dt_list() gfc_getmem(sizeof(gfc_dt_list))
-
-
 /* A namespace describes the contents of procedure, module or
    interface block.  */
 /* ??? Anything else use these?  */
@@ -1000,9 +989,6 @@ typedef struct gfc_namespace
   /* A list of all alternate entry points to this procedure (or NULL).  */
   gfc_entry_list *entries;
 
-  /* A list of all derived types in this procedure (or NULL).  */
-  gfc_dt_list *derived_types;
-
   /* Set to 1 if namespace is a BLOCK DATA program unit.  */
   int is_block_data;
 }
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 77594cbf5672fa6209bd63013c964ee4b43a3408..e6a7689b0189b786dc404cbcc20856f206ede9f1 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -1798,6 +1798,9 @@ gfc_match_allocate (void)
 	  goto cleanup;
 	}
 
+      if (tail->expr->ts.type == BT_DERIVED)
+	tail->expr->ts.derived = gfc_use_derived (tail->expr->ts.derived);
+
       if (gfc_match_char (',') != MATCH_YES)
 	break;
 
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index ad569fcf6b643f69b78bf9758bec6be2e80c91c1..c0ed3643a40d0f5947a544ab02878ea66474e6eb 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -2295,6 +2295,10 @@ match_variable (gfc_expr ** result, int equiv_flag, int host_flag)
     case FL_VARIABLE:
       break;
 
+    case FL_PROGRAM:
+      return MATCH_NO;
+      break;
+
     case FL_UNKNOWN:
       if (gfc_add_flavor (&sym->attr, FL_VARIABLE,
 			  sym->name, NULL) == FAILURE)
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 5c9786b74100c03c85fe4d6be78f7545970da0f0..3924dc69aa91add6be9dce29517ebd59563e37cd 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -858,6 +858,13 @@ resolve_actual_arglist (gfc_actual_arglist * arg)
 			 &e->where);
 	    }
 
+	  if (sym->attr.generic)
+	    {
+	      gfc_error ("GENERIC 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.  */
 
@@ -2883,10 +2890,10 @@ resolve_variable (gfc_expr * e)
 
   t = SUCCESS;
 
-  if (e->ref && resolve_ref (e) == FAILURE)
+  if (e->symtree == NULL)
     return FAILURE;
 
-  if (e->symtree == NULL)
+  if (e->ref && resolve_ref (e) == FAILURE)
     return FAILURE;
 
   sym = e->symtree->n.sym;
@@ -5360,7 +5367,6 @@ 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)
@@ -5423,12 +5429,6 @@ resolve_fl_derived (gfc_symbol *sym)
 	}
     }
     
-  /* 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;
 }
 
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 63e45ecb5fe7ae58fcf7800ff941afd6836305c2..801e85acec0ec4941ea48f42a2472ef2cc2c90f0 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -1364,6 +1364,33 @@ gfc_add_component (gfc_symbol * sym, const char *name, gfc_component ** componen
 }
 
 
+/* Recursive search for a renamed derived type.  */
+
+static gfc_symbol *
+find_renamed_type (gfc_symbol * der, gfc_symtree * st)
+{
+  gfc_symbol *sym = NULL;
+
+  if (st == NULL)
+    return NULL;
+
+  sym = find_renamed_type (der, st->left);
+  if (sym != NULL)
+    return sym;
+
+  sym = find_renamed_type (der, st->right);
+  if (sym != NULL)
+    return sym;
+
+  if (strcmp (der->name, st->n.sym->name) == 0
+	&& st->n.sym->attr.use_assoc
+	&& st->n.sym->attr.flavor == FL_DERIVED
+	&& gfc_compare_derived_types (der, st->n.sym))
+    sym = st->n.sym;
+
+  return sym;
+}
+
 /* Recursive function to switch derived types of all symbol in a
    namespace.  */
 
@@ -1408,20 +1435,68 @@ gfc_use_derived (gfc_symbol * sym)
   gfc_symbol *s;
   gfc_typespec *t;
   gfc_symtree *st;
+  gfc_component *c;
   int i;
 
-  if (sym->components != NULL)
-    return sym;               /* Already defined.  */
-
   if (sym->ns->parent == NULL)
-    goto bad;
+    {
+      /* Already defined in highest possible namespace.  */
+      if (sym->components != NULL)
+	return sym;
+
+      /*  There is no scope for finding a definition elsewhere.  */
+      else
+	goto bad;
+    }
+  else
+    {
+      /* This type can only be locally associated.  */
+      if (!(sym->attr.use_assoc || sym->attr.sequence))
+	return sym;
+
+      /* Derived types must be defined within an interface.  */
+      if (gfc_current_ns->proc_name->attr.if_source == IFSRC_IFBODY)
+	return sym;
+    }
 
+  /* Look in parent namespace for a derived type of the same name.  */
   if (gfc_find_symbol (sym->name, sym->ns->parent, 1, &s))
     {
       gfc_error ("Symbol '%s' at %C is ambiguous", sym->name);
       return NULL;
     }
 
+  if (s == NULL || s->attr.flavor != FL_DERIVED)
+    {
+      /* Check to see if type has been renamed in parent namespace.
+	 Leave cleanup of local symbols until the end of the
+	 compilation because doing it here is complicated by
+	 multiple association with the same type.  */
+      s = find_renamed_type (sym, sym->ns->parent->sym_root);
+      if (s != NULL)
+	{
+	  switch_types (sym->ns->sym_root, sym, s);
+	  return s;
+	}
+
+      /* The local definition is all that there is.  */
+      if (sym->components != NULL)
+	{
+	  /* Non-pointer derived type components have already been checked
+	     but pointer types need to be correctly associated.  */
+	  for (c = sym->components; c; c = c->next)
+	    if (c->ts.type == BT_DERIVED && c->pointer)
+	      c->ts.derived = gfc_use_derived (c->ts.derived);
+
+	  return sym;
+	}
+    }
+
+  /* Although the parent namespace has a derived type of the same name, it is
+     not an identical derived type and so cannot be used.  */
+  if (s != NULL && sym->components != NULL && !gfc_compare_derived_types (s, sym))
+    return sym;
+
   if (s == NULL || s->attr.flavor != FL_DERIVED)
     goto bad;
 
@@ -2440,21 +2515,6 @@ free_sym_tree (gfc_symtree * sym_tree)
 }
 
 
-/* Free a derived type list.  */
-
-static void
-gfc_free_dt_list (gfc_dt_list * dt)
-{
-  gfc_dt_list *n;
-
-  for (; dt; dt = n)
-    {
-      n = dt->next;
-      gfc_free (dt);
-    }
-}
-
-
 /* Free the gfc_equiv_info's.  */
 
 static void
@@ -2517,8 +2577,6 @@ gfc_free_namespace (gfc_namespace * ns)
   gfc_free_equiv (ns->equiv);
   gfc_free_equiv_lists (ns->equiv_lists);
 
-  gfc_free_dt_list (ns->derived_types);
-
   for (i = GFC_INTRINSIC_BEGIN; i != GFC_INTRINSIC_END; i++)
     gfc_free_interface (ns->operator[i]);
 
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 7398e16423763ac945ea31ec6b79eec522b95a48..855c98216c56c537a3275ef83a6d07caf8800f73 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -728,6 +728,7 @@ gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy)
       /* We now have an expression for the element size, so create a fully
 	 qualified type.  Reset sym->backend decl or this will just return the
 	 old type.  */
+      DECL_ARTIFICIAL (sym->backend_decl) = 1;
       sym->backend_decl = NULL_TREE;
       type = gfc_sym_type (sym);
       packed = 2;
@@ -884,7 +885,15 @@ gfc_get_symbol_decl (gfc_symbol * sym)
 	  if (TREE_CODE (length) == VAR_DECL
 	      && DECL_CONTEXT (length) == NULL_TREE)
 	    {
-	      gfc_add_decl_to_function (length);
+	      /* Add the string length to the same context as the symbol.  */
+	      if (DECL_CONTEXT (sym->backend_decl) == current_function_decl)
+	        gfc_add_decl_to_function (length);
+	      else
+		gfc_add_decl_to_parent_function (length);
+
+	      gcc_assert (DECL_CONTEXT (sym->backend_decl) ==
+			    DECL_CONTEXT (length));
+
 	      gfc_defer_symbol_init (sym);
 	    }
 	}
@@ -892,8 +901,11 @@ gfc_get_symbol_decl (gfc_symbol * sym)
       /* Use a copy of the descriptor for dummy arrays.  */
       if (sym->attr.dimension && !TREE_USED (sym->backend_decl))
         {
-          sym->backend_decl =
-            gfc_build_dummy_array_decl (sym, sym->backend_decl);
+	  decl = gfc_build_dummy_array_decl (sym, sym->backend_decl);
+	  /* Prevent the dummy from being detected as unused if it is copied.  */
+	  if (sym->backend_decl != NULL && decl != sym->backend_decl)
+	    DECL_ARTIFICIAL (sym->backend_decl) = 1;
+	  sym->backend_decl = decl;
 	}
 
       TREE_USED (sym->backend_decl) = 1;
@@ -1284,6 +1296,7 @@ create_function_arglist (gfc_symbol * sym)
       DECL_ARG_TYPE (parm) = type;
       TREE_READONLY (parm) = 1;
       gfc_finish_decl (parm, NULL_TREE);
+      DECL_ARTIFICIAL (parm) = 1;
 
       arglist = chainon (arglist, parm);
       typelist = TREE_CHAIN (typelist);
@@ -1603,6 +1616,7 @@ build_entry_thunks (gfc_namespace * ns)
 	  if (thunk_formal)
 	    {
 	      /* Pass the argument.  */
+	      DECL_ARTIFICIAL (thunk_formal->sym->backend_decl) = 1;
 	      args = tree_cons (NULL_TREE, thunk_formal->sym->backend_decl,
 				args);
 	      if (formal->sym->ts.type == BT_CHARACTER)
@@ -2743,6 +2757,112 @@ gfc_generate_contained_functions (gfc_namespace * parent)
 }
 
 
+/* Drill down through expressions for the array specification bounds and
+   character length calling generate_local_decl for all those variables
+   that have not already been declared.  */
+
+static void
+generate_local_decl (gfc_symbol *);
+
+static void
+generate_expr_decls (gfc_symbol *sym, gfc_expr *e)
+{
+  gfc_actual_arglist *arg;
+  gfc_ref *ref;
+  int i;
+
+  if (e == NULL)
+    return;
+
+  switch (e->expr_type)
+    {
+    case EXPR_FUNCTION:
+      for (arg = e->value.function.actual; arg; arg = arg->next)
+	generate_expr_decls (sym, arg->expr);
+      break;
+
+    /* If the variable is not the same as the dependent, 'sym', and
+       it is not marked as being declared and it is in the same
+       namespace as 'sym', add it to the local declarations.  */
+    case EXPR_VARIABLE:
+      if (sym == e->symtree->n.sym
+	    || e->symtree->n.sym->mark
+	    || e->symtree->n.sym->ns != sym->ns)
+	return;
+
+      generate_local_decl (e->symtree->n.sym);
+      break;
+
+    case EXPR_OP:
+      generate_expr_decls (sym, e->value.op.op1);
+      generate_expr_decls (sym, e->value.op.op2);
+      break;
+
+    default:
+      break;
+    }
+
+  if (e->ref)
+    {
+      for (ref = e->ref; ref; ref = ref->next)
+	{
+	  switch (ref->type)
+	    {
+	    case REF_ARRAY:
+	      for (i = 0; i < ref->u.ar.dimen; i++)
+		{
+		  generate_expr_decls (sym, ref->u.ar.start[i]);
+		  generate_expr_decls (sym, ref->u.ar.end[i]);
+		  generate_expr_decls (sym, ref->u.ar.stride[i]);
+		}
+	      break;
+
+	    case REF_SUBSTRING:
+	      generate_expr_decls (sym, ref->u.ss.start);
+	      generate_expr_decls (sym, ref->u.ss.end);
+	      break;
+
+	    case REF_COMPONENT:
+	      if (ref->u.c.component->ts.type == BT_CHARACTER
+		    && ref->u.c.component->ts.cl->length->expr_type
+						!= EXPR_CONSTANT)
+		generate_expr_decls (sym, ref->u.c.component->ts.cl->length);
+
+	      if (ref->u.c.component->as)
+	        for (i = 0; i < ref->u.c.component->as->rank; i++)
+		  {
+		    generate_expr_decls (sym, ref->u.c.component->as->lower[i]);
+		    generate_expr_decls (sym, ref->u.c.component->as->upper[i]);
+		  }
+	      break;
+	    }
+	}
+    }
+}
+
+
+/* Check for dependencies in the character length and array spec. */
+
+static void
+generate_dependency_declarations (gfc_symbol *sym)
+{
+  int i;
+
+  if (sym->ts.type == BT_CHARACTER
+	&& sym->ts.cl->length->expr_type != EXPR_CONSTANT)
+    generate_expr_decls (sym, sym->ts.cl->length);
+
+  if (sym->as && sym->as->rank)
+    {
+      for (i = 0; i < sym->as->rank; i++)
+	{
+          generate_expr_decls (sym, sym->as->lower[i]);
+          generate_expr_decls (sym, sym->as->upper[i]);
+	}
+    }
+}
+
+
 /* Generate decls for all local variables.  We do this to ensure correct
    handling of expressions which only appear in the specification of
    other functions.  */
@@ -2752,6 +2872,14 @@ generate_local_decl (gfc_symbol * sym)
 {
   if (sym->attr.flavor == FL_VARIABLE)
     {
+      /* Check for dependencies in the array specification and string
+	length, adding the necessary declarations to the function.  We
+	mark the symbol now, as well as in traverse_ns, to prevent
+	getting stuck in a circular dependency.  */
+      sym->mark = 1;
+      if (!sym->attr.dummy && !sym->ns->proc_name->attr.entry_master)
+        generate_dependency_declarations (sym);
+
       if (sym->attr.referenced)
         gfc_get_symbol_decl (sym);
       else if (sym->attr.dummy && warn_unused_parameter)
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 4225b6930c3481fdc865a5425ecb39ec61c7e989..b1bd2170638729e5ff44101dd9f6c54431fa267b 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -2669,9 +2669,19 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
     }
   else if (expr->ts.type == BT_DERIVED)
     {
-      /* Nested derived type.  */
-      tmp = gfc_trans_structure_assign (dest, expr);
-      gfc_add_expr_to_block (&block, tmp);
+      if (expr->expr_type != EXPR_STRUCTURE)
+	{
+	  gfc_init_se (&se, NULL);
+	  gfc_conv_expr (&se, expr);
+	  gfc_add_modify_expr (&block, dest,
+			       fold_convert (TREE_TYPE (dest), se.expr));
+	}
+      else
+	{
+	  /* Nested constructors.  */
+	  tmp = gfc_trans_structure_assign (dest, expr);
+	  gfc_add_expr_to_block (&block, tmp);
+	}
     }
   else
     {
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index ca93adbf968e8fd11c4c7efdc53fd5d0edf4eb69..3eb1f2cc06d11a3016eef8d64cd6dbb8e5c05870 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -1411,59 +1411,15 @@ gfc_add_field_to_struct (tree *fieldlist, tree context,
 }
 
 
-/* Copy the backend_decl and component backend_decls if
-   the two derived type symbols are "equal", as described
-   in 4.4.2 and resolved by gfc_compare_derived_types.  */
-
-static int
-copy_dt_decls_ifequal (gfc_symbol *from, gfc_symbol *to)
-{
-  gfc_component *to_cm;
-  gfc_component *from_cm;
-
-  if (from->backend_decl == NULL
-	|| !gfc_compare_derived_types (from, to))
-    return 0;
-
-  to->backend_decl = from->backend_decl;
-
-  to_cm = to->components;
-  from_cm = from->components;
-
-  /* Copy the component declarations.  If a component is itself
-     a derived type, we need a copy of its component declarations.
-     This is done by recursing into gfc_get_derived_type and
-     ensures that the component's component declarations have
-     been built.  If it is a character, we need the character 
-     length, as well.  */
-  for (; to_cm; to_cm = to_cm->next, from_cm = from_cm->next)
-    {
-      to_cm->backend_decl = from_cm->backend_decl;
-      if (from_cm->ts.type == BT_DERIVED)
-	gfc_get_derived_type (to_cm->ts.derived);
-
-      else if (from_cm->ts.type == BT_CHARACTER)
-	to_cm->ts.cl->backend_decl = from_cm->ts.cl->backend_decl;
-    }
-
-  return 1;
-}
-
-
-/* Build a tree node for a derived type.  If there are equal
-   derived types, with different local names, these are built
-   at the same time.  If an equal derived type has been built
-   in a parent namespace, this is used.  */
+/* Build a tree node for a derived type.  */
 
 static tree
 gfc_get_derived_type (gfc_symbol * derived)
 {
   tree typenode, field, field_type, fieldlist;
   gfc_component *c;
-  gfc_dt_list *dt;
-  gfc_namespace * ns;
 
-  gcc_assert (derived && derived->attr.flavor == FL_DERIVED);
+  gcc_assert (derived);
 
   /* derived->backend_decl != 0 means we saw it before, but its
      components' backend_decl may have not been built.  */
@@ -1477,29 +1433,6 @@ gfc_get_derived_type (gfc_symbol * derived)
     }
   else
     {
-      /* In a module, if an equal derived type is already available in the
-	 specification block, use its backend declaration and those of its
-	 components, rather than building anew so that potential dummy and
-	 actual arguments use the same TREE_TYPE.  Non-module structures,
-	 need to be built, if found, because the order of visits to the 
-	 namespaces is different.  */
-
-      for (ns = derived->ns->parent; ns; ns = ns->parent)
-	{
-	  for (dt = ns->derived_types; dt; dt = dt->next)
-	    {
-	      if (derived->module == NULL
-		    && dt->derived->backend_decl == NULL
-		    && gfc_compare_derived_types (dt->derived, derived))
-		gfc_get_derived_type (dt->derived);
-
-	      if (copy_dt_decls_ifequal (dt->derived, derived))
-		break;
-	    }
-	  if (derived->backend_decl)
-	    goto other_equal_dts;
-	}
-
       /* We see this derived type first time, so build the type node.  */
       typenode = make_node (RECORD_TYPE);
       TYPE_NAME (typenode) = get_identifier (derived->name);
@@ -1578,12 +1511,6 @@ gfc_get_derived_type (gfc_symbol * derived)
 
   derived->backend_decl = typenode;
 
-other_equal_dts:
-  /* Add this backend_decl to all the other, equal derived types and
-     their components in this namespace.  */
-  for (dt = derived->ns->derived_types; dt; dt = dt->next)
-    copy_dt_decls_ifequal (derived, dt->derived);
-
   return derived->backend_decl;
 }
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6f8ae4dd29bf866861ae1d6000ce0025fabbd24f..ad646c5613cae457a6182c8a2bbf5d5fd839688d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,38 @@
+2006-08-20  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/28630
+	* gfortran.dg/used_types_2.f90: New test.
+
+	PR fortran/28601
+	* gfortran.dg/used_types_3.f90: New test.
+
+	PR fortran/20886
+	* gfortran.dg/generic_actual_arg.f90: New test.
+
+	PR fortran/28735
+	* gfortran.dg/module_private_array_refs_1.f90: New test.
+
+	PR fortran/28762
+	* gfortran.dg/program_name_1.f90: New test.
+
+	PR fortran/28425
+	* gfortran.dg/derived_constructor_comps_1.f90: New test.
+
+	PR fortran/28496
+	* gfortran.dg/array_initializer_2.f90: New test.
+
+	PR fortran/18111
+	* gfortran.dg/unused_artificial_dummies_1.f90: New test. 
+
+	PR fortran/28600
+	* gfortran.dg/assumed_charlen_function_4.f90: New test.
+
+	PR fortran/28771
+	* gfortran.dg/assumed_charlen_in_main.f90: New test.
+
+	PR fortran/28660
+	* gfortran.dg/dependent_decls_1.f90: New test.
+
 2006-08-19  Erik Edelmann  <eedelman@gcc.gnu.org>
 
 	PR fortran/25217
diff --git a/gcc/testsuite/gfortran.dg/array_initializer_2.f90 b/gcc/testsuite/gfortran.dg/array_initializer_2.f90
new file mode 100644
index 0000000000000000000000000000000000000000..a1a5bdf024a361c14974ec644b5c74bde121ca44
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_initializer_2.f90
@@ -0,0 +1,17 @@
+! { dg-do run }
+! Tests the fix for PR28496 in which initializer array constructors with
+! a missing initial array index would cause an ICE.
+!
+! Contributed by Paul Thomas  <pault@gcc.gnu.org>
+! Based on original test case from Samir Nordin  <snordin_ng@yahoo.fr> 
+!
+  integer, dimension(3), parameter :: a=(/1,2,3/)
+  integer, dimension(3), parameter :: b=(/a(:)/)
+  integer, dimension(3,3), parameter :: c=reshape ((/(i, i = 1,9)/),(/3,3/))
+  integer, dimension(2,3), parameter :: d=reshape ((/c(:2:-1,:)/),(/2,3/))
+  integer, dimension(3,3), parameter :: e=reshape ((/a(:),a(:)+3,a(:)+6/),(/3,3/))
+  integer, dimension(2,3), parameter :: f=reshape ((/c(2:1:-1,:)/),(/2,3/))
+  if (any (b .ne. (/1,2,3/))) call abort ()
+  if (any (reshape(d,(/6/)) .ne. (/3, 2, 6, 5, 9, 8/))) call abort () 
+  if (any (reshape(f,(/6/)) .ne. (/2, 1, 5, 4, 8, 7/))) call abort () 
+end
diff --git a/gcc/testsuite/gfortran.dg/assumed_charlen_function_4.f90 b/gcc/testsuite/gfortran.dg/assumed_charlen_function_4.f90
new file mode 100644
index 0000000000000000000000000000000000000000..9c96ba4d69fa705a9395fb3abcd76ffd64fb5124
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/assumed_charlen_function_4.f90
@@ -0,0 +1,17 @@
+! { dg-do compile }
+! Tests the fix for PR28600 in which the declaration for the
+! character length n, would be given the DECL_CONTEXT of 'gee'
+! thus causing an ICE.
+!
+! Contributed by Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
+!
+subroutine bar(s, n)
+ integer n
+ character s*(n)
+ character*3, dimension(:), pointer :: m
+ s = ""
+contains
+ subroutine gee
+    m(1) = s(1:3)
+ end subroutine gee
+end subroutine bar
diff --git a/gcc/testsuite/gfortran.dg/assumed_charlen_in_main.f90 b/gcc/testsuite/gfortran.dg/assumed_charlen_in_main.f90
new file mode 100644
index 0000000000000000000000000000000000000000..a29bdb9d5d023036f909c4b80312be288709a405
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/assumed_charlen_in_main.f90
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! Tests the fix for PR28771 in which an assumed character length variable with an initializer could
+! survive in the main program without causing an error.
+!
+! Contributed by Martin Reinecke  <martin@mpa-garching.mpg.de>
+!
+program test
+  character(len=*), parameter :: foo = 'test'     ! Parameters must work.
+  character(len=4) :: bar = foo
+  character(len=*) :: foobar = 'This should fail' ! {  dg-error "must be a dummy" }
+  print *, bar
+end
+
diff --git a/gcc/testsuite/gfortran.dg/dependent_decls_1.f90 b/gcc/testsuite/gfortran.dg/dependent_decls_1.f90
new file mode 100644
index 0000000000000000000000000000000000000000..675c4a0d00d6ef45bec36657c87b350d1dfa9b7f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dependent_decls_1.f90
@@ -0,0 +1,39 @@
+! { dg-do run }
+! Tests the fix for pr28660 in which the order of dependent declarations
+! would get scrambled in the compiled code.
+!
+! Contributed by Erik Edelmann  <erik.edelmann@iki.fi>
+!
+program bar
+    implicit none
+    real :: x(10)
+    call foo1 (x)
+    call foo2 (x)
+    call foo3 (x)
+contains
+    subroutine foo1 (xmin)
+        real, intent(inout) :: xmin(:)
+        real :: x(size(xmin)+1)           ! The declaration for r would be added
+        real :: r(size(x)-2)              ! to the function before that of x
+        xmin = r
+        if (size(r) .ne. 9) call abort ()
+        if (size(x) .ne. 11) call abort ()
+    end subroutine foo1
+    subroutine foo2 (xmin)                ! This version was OK because of the
+        real, intent(inout) :: xmin(:)    ! renaming of r which pushed it up
+        real :: x(size(xmin)+3)           ! the symtree.
+        real :: zr(size(x)-6)
+        xmin = zr
+        if (size(zr) .ne. 7) call abort ()
+        if (size(x) .ne. 13) call abort ()
+    end subroutine foo2
+    subroutine foo3 (xmin)
+        real, intent(inout) :: xmin(:)
+        character(size(x)+2) :: y         ! host associated x
+        character(len(y)+3) :: z          ! This did not work for any combination
+        real :: r(len(z)-10)              ! of names.
+        xmin = r
+        if (size(r) .ne. 5) call abort ()
+        if (len(z) .ne. 15) call abort ()
+    end subroutine foo3
+end program bar
diff --git a/gcc/testsuite/gfortran.dg/derived_constructor_comps_1.f90 b/gcc/testsuite/gfortran.dg/derived_constructor_comps_1.f90
new file mode 100644
index 0000000000000000000000000000000000000000..1c02a31c7a319855d0d8317b8b8f78dbef73a7c0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/derived_constructor_comps_1.f90
@@ -0,0 +1,56 @@
+! { dg-do run }
+!
+! Tests fix for PR28425 in which anything other than a constructor would
+! not work for derived type components in a structure constructor.
+!
+! Original version sent by Vivek Rao on 18 Jan 06
+! Modified by Steve Kargl to remove IO
+!
+module foo_mod
+
+  implicit none
+
+  type :: date_m
+     integer :: month
+  end type date_m
+
+  type :: file_info
+     type(date_m) :: date
+  end type file_info
+
+end module foo_mod
+
+program prog
+
+  use foo_mod
+
+  implicit none
+  type(date_m)  :: dat
+  type(file_info) :: xx
+
+  type(date_m), parameter :: christmas = date_m (12)
+
+  dat = date_m(1)
+
+  xx = file_info(date_m(-1))  ! This always worked - a constructor
+  if (xx%date%month /= -1) call abort
+
+  xx = file_info(dat)         ! This was the original PR - a variable
+  if (xx%date%month /= 1) call abort
+
+  xx = file_info(foo(2))      ! ...functions were also broken
+  if (xx%date%month /= 2) call abort
+
+  xx = file_info(christmas)   ! ...and parameters
+  if (xx%date%month /= 12) call abort
+
+
+contains
+
+  function foo (i) result (ans)
+     integer :: i
+     type(date_m) :: ans
+     ans = date_m(i)
+  end function foo
+
+end program prog
diff --git a/gcc/testsuite/gfortran.dg/generic_actual_arg.f90 b/gcc/testsuite/gfortran.dg/generic_actual_arg.f90
new file mode 100644
index 0000000000000000000000000000000000000000..93a6588592fa8770edef60806f1f8982b83fffe0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/generic_actual_arg.f90
@@ -0,0 +1,25 @@
+! { dg-do compile }
+! Tests fix for PR20886 in which the passing of a generic procedure as
+! an actual argument was not detected.
+!
+! Contributed by Joost VandeVondele  <jv244@cam.ac.uk> 
+!
+MODULE TEST
+INTERFACE CALCULATION
+  MODULE PROCEDURE C1,C2
+END INTERFACE
+CONTAINS
+SUBROUTINE C1(r)
+ INTEGER :: r
+END SUBROUTINE
+SUBROUTINE C2(r)
+ REAL :: r
+END SUBROUTINE
+END MODULE TEST
+    
+USE TEST
+CALL F(CALCULATION) ! { dg-error "GENERIC non-INTRINSIC procedure" } 
+END
+
+SUBROUTINE F()
+END SUBROUTINE
\ No newline at end of file
diff --git a/gcc/testsuite/gfortran.dg/module_private_array_refs_1.f90 b/gcc/testsuite/gfortran.dg/module_private_array_refs_1.f90
new file mode 100644
index 0000000000000000000000000000000000000000..2b239747b63a1d461e8f68038a5b32706c8fe4c4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/module_private_array_refs_1.f90
@@ -0,0 +1,51 @@
+! { dg-do compile }
+! This tests the fix for PR28735 in which an ICE would be triggered in resolve_ref
+! because the references to 'a' and 'b' in the dummy arguments of mysub have
+! no symtrees in module bar, being private there.
+!
+! Contributed by  Andrew Sampson  <adsspamtrap01@yahoo.com>
+!
+!-- foo.F -----------------------------------------------
+module foo
+  implicit none
+  public
+  integer, allocatable :: a(:), b(:)
+end module foo
+
+!-- bar.F ---------------------------------------------
+module bar
+  use foo
+  implicit none
+  private                !  This triggered the ICE
+  public :: mysub        !  since a and b are not public
+
+contains
+
+  subroutine mysub(n, parray1)
+    integer, intent(in) :: n
+    real, dimension(a(n):b(n)) :: parray1
+    if ((n == 1) .and. size(parray1, 1) /= 10) call abort ()
+    if ((n == 2) .and. size(parray1, 1) /= 42) call abort ()
+  end subroutine mysub
+end module bar
+
+!-- sub.F -------------------------------------------------------
+subroutine sub()
+
+  use foo
+  use bar
+  real :: z(100)
+  allocate (a(2), b(2))
+  a = (/1, 6/)
+  b = (/10, 47/)
+  call mysub (1, z)
+  call mysub (2, z)
+
+  return
+end
+
+!-- MAIN ------------------------------------------------------
+  use bar
+  call sub ()
+end
+
diff --git a/gcc/testsuite/gfortran.dg/program_name_1.f90 b/gcc/testsuite/gfortran.dg/program_name_1.f90
new file mode 100644
index 0000000000000000000000000000000000000000..6d6c79bb06d9e87489ceefafd616376792af514b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/program_name_1.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! Tests the fix for PR28762 in which the program name would cause
+! the compiler to test the write statement as a variable thereby generating
+! an "Expecting VARIABLE" error.
+!
+! Contributed by David Ham  <David@ham.dropbear.id.au>
+!
+program write
+  integer :: debuglevel = 1
+  if (0 < debuglevel) write (*,*) "Hello World"
+end program write
diff --git a/gcc/testsuite/gfortran.dg/unused_artificial_dummies_1.f90 b/gcc/testsuite/gfortran.dg/unused_artificial_dummies_1.f90
new file mode 100644
index 0000000000000000000000000000000000000000..68ceee7af331844b3d0bd5af96fdaae08d056861
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/unused_artificial_dummies_1.f90
@@ -0,0 +1,49 @@
+! { dg-do compile }
+! { dg-options "-Wunused-variable -Wunused-parameter" }
+! This tests the fix for PR18111 in which some artificial declarations
+! were being listed as unused parameters:
+! (i) Array dummies, where a copy is made;
+! (ii) The dummies of "entry thunks" (ie. the articial procedures that
+! represent ENTRYs and call the "entry_master" function; and
+! (iii) The __entry parameter of the entry_master function, which
+! indentifies the calling entry thunk.
+! All of these have DECL_ARTIFICIAL (tree) set.
+!
+! Contributed by Paul Thomas  <pault@gcc.gnu.org>
+!
+module foo
+  implicit none
+contains
+
+!This is the original problem
+
+  subroutine bar(arg1, arg2, arg3, arg4, arg5)
+    character(len=80), intent(in) :: arg1
+    character(len=80), dimension(:), intent(in) :: arg2
+    integer, dimension(arg4), intent(in) :: arg3
+    integer, intent(in) :: arg4
+    character(len=arg4), intent(in) :: arg5
+    print *, arg1, arg2, arg3, arg4, arg5
+  end subroutine bar
+
+! This ICED with the first version of the fix because gfc_build_dummy_array_decl
+! sometimes NULLS sym->backend_decl; taken from aliasing_dummy_1.f90
+
+  subroutine foo1 (slist, i)
+    character(*), dimension(*) :: slist
+    integer i
+    write (slist(i), '(2hi=,i3)') i
+  end subroutine foo1
+
+! This tests the additions to the fix that prevent the dummies of entry thunks
+! and entry_master __entry parameters from being listed as unused.
+
+  function f1 (a)
+    integer, dimension (2, 2) :: a, b, f1, e1
+    f1 (:, :) = 15 + a
+    return
+  entry e1 (b)
+    e1 (:, :) = 42 + b
+  end function
+
+end module foo
diff --git a/gcc/testsuite/gfortran.dg/used_types_2.f90 b/gcc/testsuite/gfortran.dg/used_types_2.f90
new file mode 100644
index 0000000000000000000000000000000000000000..167323c0cb14658a6234a83e429dca0020a8d813
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/used_types_2.f90
@@ -0,0 +1,33 @@
+! { dg-do compile }
+! Tests the fix for PR28630, in which a contained,
+! derived type function caused an ICE if its definition
+! was both host and use associated.
+!
+! Contributed by Mark Hesselink <mhesseli@alumni.caltech.edu>
+!
+MODULE types
+   TYPE :: t
+      INTEGER :: i
+   END TYPE
+END MODULE types
+
+MODULE foo
+   USE types
+CONTAINS
+   FUNCTION bar (x) RESULT(r)
+      USE types
+      REAL, INTENT(IN) :: x
+      TYPE(t) :: r
+      r = t(0)
+   END FUNCTION bar
+END MODULE
+
+
+LOGICAL FUNCTION foobar (x)
+   USE foo
+   REAL, INTENT(IN) :: x
+   TYPE(t) :: c
+   foobar = .FALSE.
+   c = bar (x)
+END FUNCTION foobar
+
diff --git a/gcc/testsuite/gfortran.dg/used_types_3.f90 b/gcc/testsuite/gfortran.dg/used_types_3.f90
new file mode 100644
index 0000000000000000000000000000000000000000..8273ee420ea20d477c936e3b90e537b6f4d8eb3c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/used_types_3.f90
@@ -0,0 +1,57 @@
+! { dg-do compile }
+! Test the fix for PR28601 in which line 55 would produce an ICE
+! because the rhs and lhs derived times were not identically
+! associated and so could not be cast.
+!
+! Contributed by Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
+!
+module modA
+implicit none
+save
+private
+
+type, public :: typA
+integer :: i
+end type typA
+
+type, public :: atom
+type(typA), pointer :: ofTypA(:,:)
+end type atom
+end module modA
+
+!!! re-name and re-export typA as typB:
+module modB
+use modA, only: typB => typA
+implicit none
+save
+private
+
+public typB
+end module modB
+
+!!! mixed used of typA and typeB:
+module modC
+use modB
+implicit none
+save
+private
+contains
+
+subroutine buggy(a)
+use modA, only: atom
+! use modB, only: typB
+! use modA, only: typA
+implicit none
+type(atom),intent(inout) :: a
+target :: a
+! *** end of interface ***
+
+type(typB), pointer :: ofTypB(:,:)
+! type(typA), pointer :: ofTypB(:,:)
+integer :: i,j,k
+
+ofTypB => a%ofTypA
+
+a%ofTypA(i,j) = ofTypB(k,j)
+end subroutine buggy
+end module modC