diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e6b4f45db671f2f35013c6893a94c258196b39ad..7fc9a0707535bffe555bca0a86801981ef57b302 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,7 @@
+2007-05-22  Ollie Wild  <aaw@google.com>
+
+	* decl.c (duplicate_decls): Verify namespace names are unique.
+
 2007-05-21  Mark Mitchell  <mark@codesourcery.com>
 
 	* decl.c (cxx_maybe_build_cleanup): Handle
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index c76568a16f34379c4a83457d431a48328c32d006..02b38225a9e843743e0660b8958d14c06b027eff 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1297,30 +1297,36 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
     }
   else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
     {
-      if ((TREE_CODE (olddecl) == TYPE_DECL && DECL_ARTIFICIAL (olddecl)
-	   && TREE_CODE (newdecl) != TYPE_DECL
-	   && ! (TREE_CODE (newdecl) == TEMPLATE_DECL
-		 && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL))
-	  || (TREE_CODE (newdecl) == TYPE_DECL && DECL_ARTIFICIAL (newdecl)
-	      && TREE_CODE (olddecl) != TYPE_DECL
-	      && ! (TREE_CODE (olddecl) == TEMPLATE_DECL
-		    && (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl))
-			== TYPE_DECL))))
-	{
-	  /* We do nothing special here, because C++ does such nasty
-	     things with TYPE_DECLs.  Instead, just let the TYPE_DECL
-	     get shadowed, and know that if we need to find a TYPE_DECL
-	     for a given name, we can look in the IDENTIFIER_TYPE_VALUE
-	     slot of the identifier.  */
-	  return NULL_TREE;
+      /* C++ Standard, 3.3, clause 4:
+	 "[Note: a namespace name or a class template name must be unique
+	 in its declarative region (7.3.2, clause 14). ]"  */
+      if (TREE_CODE (olddecl) != NAMESPACE_DECL
+	  && TREE_CODE (newdecl) != NAMESPACE_DECL
+	  && (TREE_CODE (olddecl) != TEMPLATE_DECL
+	      || TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) != TYPE_DECL)
+	  && (TREE_CODE (newdecl) != TEMPLATE_DECL
+	      || TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) != TYPE_DECL))
+	{
+	  if ((TREE_CODE (olddecl) == TYPE_DECL && DECL_ARTIFICIAL (olddecl)
+	       && TREE_CODE (newdecl) != TYPE_DECL)
+	      || (TREE_CODE (newdecl) == TYPE_DECL && DECL_ARTIFICIAL (newdecl)
+		  && TREE_CODE (olddecl) != TYPE_DECL))
+	    {
+	      /* We do nothing special here, because C++ does such nasty
+		 things with TYPE_DECLs.  Instead, just let the TYPE_DECL
+		 get shadowed, and know that if we need to find a TYPE_DECL
+		 for a given name, we can look in the IDENTIFIER_TYPE_VALUE
+		 slot of the identifier.  */
+	      return NULL_TREE;
+	    }
+	    
+	    if ((TREE_CODE (newdecl) == FUNCTION_DECL
+		 && DECL_FUNCTION_TEMPLATE_P (olddecl))
+		|| (TREE_CODE (olddecl) == FUNCTION_DECL
+		    && DECL_FUNCTION_TEMPLATE_P (newdecl)))
+	      return NULL_TREE;
 	}
 
-      if ((TREE_CODE (newdecl) == FUNCTION_DECL
-	   && DECL_FUNCTION_TEMPLATE_P (olddecl))
-	  || (TREE_CODE (olddecl) == FUNCTION_DECL
-	      && DECL_FUNCTION_TEMPLATE_P (newdecl)))
-	return NULL_TREE;
-
       error ("%q#D redeclared as different kind of symbol", newdecl);
       if (TREE_CODE (olddecl) == TREE_LIST)
 	olddecl = TREE_VALUE (olddecl);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 601700c8debfca17551ca137720ac5ab59463e3a..77b6a7fa3260b64b4108ef5039ea37d229753bbe 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-05-22  Ollie Wild  <aaw@google.com>
+
+	* g++.dg/lookup/name-clash5.C: New test.
+	* g++.dg/lookup/name-clash6.C: New test.
+
 2007-05-22  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* g++.dg/other/i386-2.C: Update comments on header files tested.
diff --git a/gcc/testsuite/g++.dg/lookup/name-clash5.C b/gcc/testsuite/g++.dg/lookup/name-clash5.C
new file mode 100644
index 0000000000000000000000000000000000000000..7f220d8877f7c88925c6922a0acdba74ff292f07
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/name-clash5.C
@@ -0,0 +1,13 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do compile }
+
+// C++ Standard, 3.3, clause 4:
+// "[Note: a namespace name or a class template name must be unique in its
+// declarative region (7.3.2, clause 14). ]"
+
+namespace N
+{ // { dg-error "previous declaration" }
+}
+
+class N; // { dg-error "redeclared" }
diff --git a/gcc/testsuite/g++.dg/lookup/name-clash6.C b/gcc/testsuite/g++.dg/lookup/name-clash6.C
new file mode 100644
index 0000000000000000000000000000000000000000..63a0b15bf5eea55d687dc370e0fa8afe7fe99fc3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/name-clash6.C
@@ -0,0 +1,13 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do compile }
+
+// C++ Standard, 3.3, clause 4:
+// "[Note: a namespace name or a class template name must be unique in its
+// declarative region (7.3.2, clause 14). ]"
+
+class N; // { dg-error "previous declaration" }
+
+namespace N
+{ // { dg-error "redeclared" }
+}