diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index fe5d0c709c233b274d996a5eb3b7b43d676b527c..aa508e3ffe2227c57bb59adf7b38dcec53038562 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
 2006-07-15  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
+	PR c++/28249
+	* parser.c (cp_parser_check_decl_spec): New function.
+	(cp_parser_decl_specifier_seq): Factor out check for repeated
+	decl-specifiers into cp_parser_check_decl_spec. Use it.
+	(cp_parser_type_specifier_seq) Use it.
+
 	PR c++/28294
 	* semantics.c (finish_offsetof): Use TREE_OPERAND for COMPONENT_REFs
 	only.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 63a6b88ea416cc1d13b035e8c73897e55e6d028c..81000bf47acb2a7d2e55475ac6b23d8ce1b0ece4 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1950,6 +1950,49 @@ cp_parser_simulate_error (cp_parser* parser)
   return false;
 }
 
+/* Check for repeated decl-specifiers.  */
+
+static void
+cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs)
+{
+  cp_decl_spec ds;
+
+  for (ds = ds_first; ds != ds_last; ++ds)
+    {
+      unsigned count = decl_specs->specs[(int)ds];
+      if (count < 2)
+	continue;
+      /* The "long" specifier is a special case because of "long long".  */
+      if (ds == ds_long)
+	{
+	  if (count > 2)
+	    error ("%<long long long%> is too long for GCC");
+	  else if (pedantic && !in_system_header && warn_long_long)
+	    pedwarn ("ISO C++ does not support %<long long%>");
+	}
+      else if (count > 1)
+	{
+	  static const char *const decl_spec_names[] = {
+	    "signed",
+	    "unsigned",
+	    "short",
+	    "long",
+	    "const",
+	    "volatile",
+	    "restrict",
+	    "inline",
+	    "virtual",
+	    "explicit",
+	    "friend",
+	    "typedef",
+	    "__complex",
+	    "__thread"
+	  };
+	  error ("duplicate %qs", decl_spec_names[(int)ds]);
+	}
+    }
+}
+
 /* This function is called when a type is defined.  If type
    definitions are forbidden at this point, an error message is
    issued.  */
@@ -7376,7 +7419,6 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
 			      int* declares_class_or_enum)
 {
   bool constructor_possible_p = !parser->in_declarator_p;
-  cp_decl_spec ds;
 
   /* Clear DECL_SPECS.  */
   clear_decl_specs (decl_specs);
@@ -7559,41 +7601,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
       flags |= CP_PARSER_FLAGS_OPTIONAL;
     }
 
-  /* Check for repeated decl-specifiers.  */
-  for (ds = ds_first; ds != ds_last; ++ds)
-    {
-      unsigned count = decl_specs->specs[(int)ds];
-      if (count < 2)
-	continue;
-      /* The "long" specifier is a special case because of "long long".  */
-      if (ds == ds_long)
-	{
-	  if (count > 2)
-	    error ("%<long long long%> is too long for GCC");
-	  else if (pedantic && !in_system_header && warn_long_long)
-	    pedwarn ("ISO C++ does not support %<long long%>");
-	}
-      else if (count > 1)
-	{
-	  static const char *const decl_spec_names[] = {
-	    "signed",
-	    "unsigned",
-	    "short",
-	    "long",
-	    "const",
-	    "volatile",
-	    "restrict",
-	    "inline",
-	    "virtual",
-	    "explicit",
-	    "friend",
-	    "typedef",
-	    "__complex",
-	    "__thread"
-	  };
-	  error ("duplicate %qs", decl_spec_names[(int)ds]);
-	}
-    }
+  cp_parser_check_decl_spec (decl_specs);
 
   /* Don't allow a friend specifier with a class definition.  */
   if (decl_specs->specs[(int) ds_friend] != 0
@@ -12030,6 +12038,8 @@ cp_parser_type_specifier_seq (cp_parser* parser,
       if (is_condition && !is_cv_qualifier)
 	flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
     }
+
+  cp_parser_check_decl_spec (type_specifier_seq);
 }
 
 /* Parse a parameter-declaration-clause.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6a2a4b5c9ba55fa47c1df4f62f86736c03daff4c..c145b16318bdb0020b0bda3b876b073b329cd539 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
 2006-07-15  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
+	PR c++/28249
+	* g++.dg/parse/catch1.C: New test.
+
 	PR c++/28294
 	* g++.dg/ext/offsetof1.C: Add test with function pointer arithmetic.
 
diff --git a/gcc/testsuite/g++.dg/parse/catch1.C b/gcc/testsuite/g++.dg/parse/catch1.C
new file mode 100644
index 0000000000000000000000000000000000000000..877402231ea9b6989255550edb6d04ce0b47ef16
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/catch1.C
@@ -0,0 +1,8 @@
+// PR c++/28249
+// { dg-do compile }
+
+void foo()
+{
+  try {}
+  catch (long long long) {}  // { dg-error "long long long" }
+}