diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e5940ffe6148d6d6cc6b7cb8656b1c4456110c7b..ec4684ddef209e1d9cba01771c441380bdd0d5b2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
 2003-04-22  Mark Mitchell  <mark@codesourcery.com>
 
+	PR c++/10428
+	* decl.c (check_elaborated_type_specifier): New function, split
+	out from ...
+	(xref_tag): ... here.  Use the new function in more places.
+
 	* rtti.c (throw_bad_typeid): Use build_cxx_call.
 
 2003-04-21  Mark Mitchell  <mark@codesourcery.com>
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a14389f12565443f875894d4f8651a3566aae1d6..84e267ee9f60975d6d975231fcdc5d5fbb623ed1 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -12525,6 +12525,38 @@ tag_name (enum tag_types code)
     }
 }
 
+/* Name lookup in an elaborated-type-specifier (after the keyword
+   indicated by TAG_CODE) has found TYPE.  If the
+   elaborated-type-specifier is invalid, issue a diagnostic and return
+   error_mark_node; otherwise, return TYPE itself.  */
+
+static tree
+check_elaborated_type_specifier (enum tag_types tag_code,
+				 tree type)
+{
+  tree t;
+
+  t = follow_tag_typedef (type);
+
+  /* [dcl.type.elab] If the identifier resolves to a typedef-name or a
+     template type-parameter, the elaborated-type-specifier is
+     ill-formed.  */
+  if (!t)
+    {
+      error ("using typedef-name `%D' after `%s'",
+	     TYPE_NAME (type), tag_name (tag_code));
+      t = error_mark_node;
+    }
+  else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+    {
+      error ("using template type parameter `%T' after `%s'",
+	     type, tag_name (tag_code));
+      t = error_mark_node;
+    }
+
+  return t;
+}
+
 /* Get the struct, enum or union (CODE says which) with tag NAME.
    Define the tag as a forward-reference if it is not defined.
 
@@ -12611,20 +12643,9 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
     {
       if (t)
 	{
-	  ref = follow_tag_typedef (t);
-
-	  /* [dcl.type.elab] If the identifier resolves to a
-	     typedef-name or a template type-parameter, the
-	     elaborated-type-specifier is ill-formed.  */
-	  if (!ref)
-	    {
-	      pedwarn ("using typedef-name `%D' after `%s'",
-		       TYPE_NAME (t), tag_name (tag_code));
-	      ref = t;
-	    }
-	  else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
-	    error ("using template type parameter `%T' after `%s'",
-		   t, tag_name (tag_code));
+	  ref = check_elaborated_type_specifier (tag_code, t);
+	  if (ref == error_mark_node)
+	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 	}
       else
 	ref = lookup_tag (code, name, b, 0);
@@ -12643,9 +12664,15 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
 	       template, so we want this type.  */
 	    ref = DECL_TEMPLATE_RESULT (ref);
 
-	  if (ref && TREE_CODE (ref) == TYPE_DECL
-	      && TREE_CODE (TREE_TYPE (ref)) == code)
-	    ref = TREE_TYPE (ref);
+	  if (ref && TREE_CODE (ref) == TYPE_DECL)
+	    {
+	      ref = check_elaborated_type_specifier (tag_code, 
+						     TREE_TYPE (ref));
+	      if (ref == error_mark_node)
+		POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+	      if (ref && TREE_CODE (ref) != code)
+		ref = NULL_TREE;
+	    }
 	  else
 	    ref = NULL_TREE;
 	}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3face0f955d9250d367d265f4cc296ef9b03f136..35bbeb964068e86906a01dc7e90a16f0f58cc6be 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2003-04-22  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/10428
+	* g++.dg/parse/elab1.C: New test.
 
 2003-04-22  Devang Patel  <dpatel@apple.com>
 
diff --git a/gcc/testsuite/g++.dg/parse/elab1.C b/gcc/testsuite/g++.dg/parse/elab1.C
new file mode 100644
index 0000000000000000000000000000000000000000..2997eef62557cd77788f45c9478f2faa25b745ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/elab1.C
@@ -0,0 +1,9 @@
+namespace Name {
+
+    typedef void *(*Function)( void *, int );
+
+    struct Foo {
+      struct Function xyz[5]; // { dg-error "" }
+    };
+
+}