From 0e37e3f07660892f3666527aedcb58c6b7cb5d37 Mon Sep 17 00:00:00 2001
From: aaw <aaw@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 22 May 2007 20:36:49 +0000
Subject: [PATCH] 	* decl.c (duplicate_decls): Verify namespace names are
 unique.

	* g++.dg/lookup/name-clash5.C: New test.
	* g++.dg/lookup/name-clash6.C: New test.



git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124960 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/cp/ChangeLog                          |  4 ++
 gcc/cp/decl.c                             | 50 +++++++++++++----------
 gcc/testsuite/ChangeLog                   |  5 +++
 gcc/testsuite/g++.dg/lookup/name-clash5.C | 13 ++++++
 gcc/testsuite/g++.dg/lookup/name-clash6.C | 13 ++++++
 5 files changed, 63 insertions(+), 22 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/lookup/name-clash5.C
 create mode 100644 gcc/testsuite/g++.dg/lookup/name-clash6.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e6b4f45db671..7fc9a0707535 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 c76568a16f34..02b38225a9e8 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 601700c8debf..77b6a7fa3260 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 000000000000..7f220d8877f7
--- /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 000000000000..63a0b15bf5ee
--- /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" }
+}
-- 
GitLab