diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c768b4f2fe387c94a9c92a58a2bb93c2f5327506..723f67a30c9ede4c1210b8e81eda6a8731126386 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2003-04-23  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/9847
+	* cp-tree.h (duplicate_tag_error): Remove.
+	* class.c (duplicate_tag_error): Remove.
+	* semantics.c (begin_class_definition): Return immediately for a
+	duplicate class definition.
+
+	PR c++/10451
+	* decl.c (grokdeclarator): Correct logic for "mutable" errors.
+
 2003-04-22  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/10446
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 382519e75286797d9906ddae822d1c3b979d24ce..405e571a63f972802c4d0242a5c7ee1678991010 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1924,78 +1924,6 @@ finish_struct_methods (tree t)
 	   method_name_cmp);
 }
 
-/* Emit error when a duplicate definition of a type is seen.  Patch up.  */
-
-void
-duplicate_tag_error (tree t)
-{
-  error ("redefinition of `%#T'", t);
-  cp_error_at ("previous definition of `%#T'", t);
-
-  /* Pretend we haven't defined this type.  */
-
-  /* All of the component_decl's were TREE_CHAINed together in the parser.
-     finish_struct_methods walks these chains and assembles all methods with
-     the same base name into DECL_CHAINs. Now we don't need the parser chains
-     anymore, so we unravel them.  */
-
-  /* This used to be in finish_struct, but it turns out that the
-     TREE_CHAIN is used by dbxout_type_methods and perhaps some other
-     things...  */
-  if (CLASSTYPE_METHOD_VEC (t)) 
-    {
-      tree method_vec = CLASSTYPE_METHOD_VEC (t);
-      int i, len  = TREE_VEC_LENGTH (method_vec);
-      for (i = 0; i < len; i++)
-	{
-	  tree unchain = TREE_VEC_ELT (method_vec, i);
-	  while (unchain != NULL_TREE) 
-	    {
-	      TREE_CHAIN (OVL_CURRENT (unchain)) = NULL_TREE;
-	      unchain = OVL_NEXT (unchain);
-	    }
-	}
-    }
-
-  if (TYPE_LANG_SPECIFIC (t))
-    {
-      tree binfo = TYPE_BINFO (t);
-      int interface_only = CLASSTYPE_INTERFACE_ONLY (t);
-      int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t);
-      tree template_info = CLASSTYPE_TEMPLATE_INFO (t);
-      int use_template = CLASSTYPE_USE_TEMPLATE (t);
-
-      memset ((char *) TYPE_LANG_SPECIFIC (t), 0, sizeof (struct lang_type));
-      BINFO_BASETYPES(binfo) = NULL_TREE;
-
-      TYPE_LANG_SPECIFIC (t)->u.h.is_lang_type_class = 1;
-      TYPE_BINFO (t) = binfo;
-      CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
-      SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
-      TYPE_REDEFINED (t) = 1;
-      CLASSTYPE_TEMPLATE_INFO (t) = template_info;
-      CLASSTYPE_USE_TEMPLATE (t) = use_template;
-      CLASSTYPE_DECL_LIST (t) = NULL_TREE;
-    }
-  TYPE_SIZE (t) = NULL_TREE;
-  TYPE_MODE (t) = VOIDmode;
-  TYPE_FIELDS (t) = NULL_TREE;
-  TYPE_METHODS (t) = NULL_TREE;
-  TYPE_VFIELD (t) = NULL_TREE;
-  TYPE_CONTEXT (t) = NULL_TREE;
-  
-  /* Clear TYPE_LANG_FLAGS -- those in TYPE_LANG_SPECIFIC are cleared above.  */
-  TYPE_LANG_FLAG_0 (t) = 0;
-  TYPE_LANG_FLAG_1 (t) = 0;
-  TYPE_LANG_FLAG_2 (t) = 0;
-  TYPE_LANG_FLAG_3 (t) = 0;
-  TYPE_LANG_FLAG_4 (t) = 0;
-  TYPE_LANG_FLAG_5 (t) = 0;
-  TYPE_LANG_FLAG_6 (t) = 0;
-  /* But not this one.  */
-  SET_IS_AGGR_TYPE (t, 1);
-}
-
 /* Make BINFO's vtable have N entries, including RTTI entries,
    vbase and vcall offsets, etc.  Set its type and call the backend
    to lay it out.  */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index cbee534b4da882660d19b8e5a63cf71512e57672..24913624c2e37de7d4d066bdab8bda25c1e758d0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3540,7 +3540,6 @@ extern void resort_type_method_vec
 extern void add_method				(tree, tree, int);
 extern int currently_open_class			(tree);
 extern tree currently_open_derived_class	(tree);
-extern void duplicate_tag_error			(tree);
 extern tree finish_struct			(tree, tree);
 extern void finish_struct_1			(tree);
 extern int resolves_to_fixed_type_p		(tree, int *);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 84e267ee9f60975d6d975231fcdc5d5fbb623ed1..181dd6fc4a6f5c2218d3732bfa34170b9e10e163 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -11044,7 +11044,7 @@ grokdeclarator (tree declarator,
 
   if (RIDBIT_SETP (RID_MUTABLE, specbits))
     {
-      if (current_class_name == NULL_TREE || decl_context == PARM || friendp)
+      if (decl_context != FIELD || friendp)
         {
 	  error ("non-member `%s' cannot be declared `mutable'", name);
           RIDBIT_RESET (RID_MUTABLE, specbits);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 7c7af3e839913b44e56fa43de13091db8786dc45..cdb24f6e91017696af0ea08b0c5f9f89e53d1a92 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1797,7 +1797,11 @@ begin_class_definition (t)
   /* If this type was already complete, and we see another definition,
      that's an error.  */
   if (COMPLETE_TYPE_P (t))
-    duplicate_tag_error (t);
+    {
+      error ("redefinition of `%#T'", t);
+      cp_error_at ("previous definition of `%#T'", t);
+      return error_mark_node;
+    }
 
   /* Update the location of the decl.  */
   DECL_SOURCE_FILE (TYPE_NAME (t)) = input_filename;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 154e129e0ae19cbf18c5898545d909e7094c9459..2fc733dedcb1b4aec062bc57a643a4a326d19e01 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2003-04-23  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/10451
+	* g++.dg/parse/crash4.C: New test.
+	
+	PR c++/9847
+	* g++.dg/parse/crash5.C: New test.
+
 2003-04-22  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/10446
diff --git a/gcc/testsuite/g++.dg/parse/crash4.C b/gcc/testsuite/g++.dg/parse/crash4.C
new file mode 100644
index 0000000000000000000000000000000000000000..a24f0dd003c1e5296c74004dffecbe2560c765e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash4.C
@@ -0,0 +1,12 @@
+struct Bar
+ {
+     typedef int type;
+ };
+ 
+ struct Foo
+ {
+     void func(void)
+     {
+       mutable Bar::type x; // { dg-error "" }
+     }
+ };
diff --git a/gcc/testsuite/g++.dg/parse/crash5.C b/gcc/testsuite/g++.dg/parse/crash5.C
new file mode 100644
index 0000000000000000000000000000000000000000..3a4185b7e6c1c5e82d6d023f5f910820473df739
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash5.C
@@ -0,0 +1,13 @@
+// { dg-options "-w" }
+
+class QString { // { dg-error "" }
+  QString (const QString & a); // { dg-error "" }
+};
+
+class QString { }; // { dg-error "" }
+
+const QString q () {
+  QString z; // { dg-error "" }
+  int x;
+  return x ? QString () : QString (); // { dg-error "" }
+}