diff mbox

C++ PATCH for DR 374 (specialization outside of namespace)

Message ID CADzB+2mzyqwUATq9evdTniMX_VPuQXhc=KTFFCO4Ph23+hpc3w@mail.gmail.com
State New
Headers show

Commit Message

Jason Merrill Nov. 13, 2016, 6:47 a.m. UTC
In C++11 it's OK to declare a specialization for the first time
outside of the template's namespace, so long as the specialization is
explicitly qualified.  Conversely, C++11 puts the same restrictions on
explicit instantiations, whereas C++98 didn't say anything about where
they needed to go.  So I needed to update a bunch of libstdc++ tests
which didn't conform.

To enforce this for class templates I needed to hook into the parser
at the places where we still know whether or not a
nested-name-specifier was used; for non-class templates we preserve
that information long enough for check_explicit_instantiation to find
it.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 56bc587a8c075200a19b2175aaed648b8e9d88f5
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Nov 11 07:45:01 2016 -0800

            DR 374 - specialization in outer namespace
    
            PR c++/56840
            * pt.c (check_specialization_namespace): Allow any enclosing
            namespace.
            (check_unqualified_spec_or_inst): New.
            (check_explicit_specialization): Call it.
            * parser.c (cp_parser_elaborated_type_specifier)
            (cp_parser_class_head): Call it.
diff mbox

Patch

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8183775..3e41a33 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6082,6 +6082,7 @@  extern void reset_specialization		(void);
 extern void end_specialization			(void);
 extern void begin_explicit_instantiation	(void);
 extern void end_explicit_instantiation		(void);
+extern void check_unqualified_spec_or_inst	(tree, location_t);
 extern tree check_explicit_specialization	(tree, tree, int, int);
 extern int num_template_headers_for_class	(tree);
 extern void check_template_variable		(tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 185c98b..6101504 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7868,8 +7868,7 @@  check_class_member_definition_namespace (tree decl)
      diagnostics.  */
   if (processing_specialization)
     return;
-  /* There are no restrictions on the placement of
-     explicit instantiations.  */
+  /* We check this in check_explicit_instantiation_namespace.  */
   if (processing_explicit_instantiation)
     return;
   /* [class.mfct]
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index e574c27..8db6cfd 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3558,7 +3558,7 @@  set_decl_namespace (tree decl, tree scope, bool friendp)
   /* Since decl is a function, old should contain a function decl.  */
   if (!is_overloaded_fn (old))
     goto complain;
-  /* A template can be explicitly specialized in any namespace.  */
+  /* We handle these in check_explicit_instantiation_namespace.  */
   if (processing_explicit_instantiation)
     return;
   if (processing_template_decl || processing_specialization)
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7b95dba..b3b69b3 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -17004,24 +17004,28 @@  cp_parser_elaborated_type_specifier (cp_parser* parser,
   globalscope =  cp_parser_global_scope_opt (parser,
 					     /*current_scope_valid_p=*/false);
   /* Look for the nested-name-specifier.  */
+  tree nested_name_specifier;
   if (tag_type == typename_type && !globalscope)
     {
-      if (!cp_parser_nested_name_specifier (parser,
+      nested_name_specifier
+	= cp_parser_nested_name_specifier (parser,
 					   /*typename_keyword_p=*/true,
 					   /*check_dependency_p=*/true,
 					   /*type_p=*/true,
-					    is_declaration))
+					   is_declaration);
+      if (!nested_name_specifier)
 	return error_mark_node;
     }
   else
     /* Even though `typename' is not present, the proposed resolution
        to Core Issue 180 says that in `class A<T>::B', `B' should be
        considered a type-name, even if `A<T>' is dependent.  */
-    cp_parser_nested_name_specifier_opt (parser,
-					 /*typename_keyword_p=*/true,
-					 /*check_dependency_p=*/true,
-					 /*type_p=*/true,
-					 is_declaration);
+    nested_name_specifier
+      = cp_parser_nested_name_specifier_opt (parser,
+					     /*typename_keyword_p=*/true,
+					     /*check_dependency_p=*/true,
+					     /*type_p=*/true,
+					     is_declaration);
  /* For everything but enumeration types, consider a template-id.
     For an enumeration type, consider only a plain identifier.  */
   if (tag_type != enum_type)
@@ -17069,8 +17073,18 @@  cp_parser_elaborated_type_specifier (cp_parser* parser,
       else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
         ; 
       else if (TREE_CODE (decl) == TYPE_DECL)
-        type = check_elaborated_type_specifier (tag_type, decl,
-						/*allow_template_p=*/true);
+	{
+	  type = check_elaborated_type_specifier (tag_type, decl,
+						  /*allow_template_p=*/true);
+
+	  /* If the next token is a semicolon, this must be a specialization,
+	     instantiation, or friend declaration.  Check the scope while we
+	     still know whether or not we had a nested-name-specifier.  */
+	  if (type != error_mark_node
+	      && !nested_name_specifier && !is_friend
+	      && cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+	    check_unqualified_spec_or_inst (type, token->location);
+	}
       else if (decl == error_mark_node)
 	type = error_mark_node; 
     }
@@ -22336,6 +22350,11 @@  cp_parser_class_head (cp_parser* parser,
 	{
 	  type = TREE_TYPE (id);
 	  type = maybe_process_partial_specialization (type);
+
+	  /* Check the scope while we still know whether or not we had a
+	     nested-name-specifier.  */
+	  if (type != error_mark_node)
+	    check_unqualified_spec_or_inst (type, type_start_token->location);
 	}
       if (nested_name_specifier)
 	pushed_scope = push_scope (nested_name_specifier);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d4855d5..d9499d9 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -772,28 +772,29 @@  check_specialization_namespace (tree tmpl)
 
   /* [tmpl.expl.spec]
 
-     An explicit specialization shall be declared in the namespace of
-     which the template is a member, or, for member templates, in the
-     namespace of which the enclosing class or enclosing class
-     template is a member.  An explicit specialization of a member
-     function, member class or static data member of a class template
-     shall be declared in the namespace of which the class template is
-     a member.  */
+     An explicit specialization shall be declared in a namespace enclosing the
+     specialized template. An explicit specialization whose declarator-id is
+     not qualified shall be declared in the nearest enclosing namespace of the
+     template, or, if the namespace is inline (7.3.1), any namespace from its
+     enclosing namespace set.  */
   if (current_scope() != DECL_CONTEXT (tmpl)
       && !at_namespace_scope_p ())
     {
       error ("specialization of %qD must appear at namespace scope", tmpl);
       return false;
     }
-  if (is_associated_namespace (current_namespace, tpl_ns))
-    /* Same or super-using namespace.  */
+
+  if (cxx_dialect < cxx11
+      ? is_associated_namespace (current_namespace, tpl_ns)
+      : is_ancestor (current_namespace, tpl_ns))
+    /* Same or enclosing namespace.  */
     return true;
   else
     {
       permerror (input_location,
 		 "specialization of %qD in different namespace", tmpl);
-      permerror (DECL_SOURCE_LOCATION (tmpl),
-		 "  from definition of %q#D", tmpl);
+      inform (DECL_SOURCE_LOCATION (tmpl),
+	      "  from definition of %q#D", tmpl);
       return false;
     }
 }
@@ -2586,6 +2587,36 @@  check_template_variable (tree decl)
     }
 }
 
+/* An explicit specialization whose declarator-id or class-head-name is not
+   qualified shall be declared in the nearest enclosing namespace of the
+   template, or, if the namespace is inline (7.3.1), any namespace from its
+   enclosing namespace set.
+
+   If the name declared in the explicit instantiation is an unqualified name,
+   the explicit instantiation shall appear in the namespace where its template
+   is declared or, if that namespace is inline (7.3.1), any namespace from its
+   enclosing namespace set.  */
+
+void
+check_unqualified_spec_or_inst (tree t, location_t loc)
+{
+  tree tmpl = most_general_template (t);
+  if (DECL_NAMESPACE_SCOPE_P (tmpl)
+      && !is_associated_namespace (current_namespace,
+				   CP_DECL_CONTEXT (tmpl)))
+    {
+      if (processing_specialization)
+	permerror (loc, "explicit specialization of %qD outside its "
+		   "namespace must use a nested-name-specifier", tmpl);
+      else if (processing_explicit_instantiation
+	       && cxx_dialect >= cxx11)
+	/* This was allowed in C++98, so only pedwarn.  */
+	pedwarn (loc, OPT_Wpedantic, "explicit instantiation of %qD "
+		 "outside its namespace must use a nested-name-"
+		 "specifier", tmpl);
+    }
+}
+
 /* Check to see if the function just declared, as indicated in
    DECLARATOR, and in DECL, is a specialization of a function
    template.  We may also discover that the declaration is an explicit
@@ -2949,15 +2980,8 @@  check_explicit_specialization (tree declarator,
 	return error_mark_node;
       else
 	{
-	  if (!ctype && !was_template_id
-	      && (specialization || member_specialization
-		  || explicit_instantiation)
-	      && !is_associated_namespace (CP_DECL_CONTEXT (decl),
-					   CP_DECL_CONTEXT (tmpl)))
-	    error ("%qD is not declared in %qD",
-		   tmpl, current_namespace);
-	  else if (TREE_CODE (decl) == FUNCTION_DECL
-		   && DECL_HIDDEN_FRIEND_P (tmpl))
+	  if (TREE_CODE (decl) == FUNCTION_DECL
+	      && DECL_HIDDEN_FRIEND_P (tmpl))
 	    {
 	      if (pedwarn (DECL_SOURCE_LOCATION (decl), 0,
 			   "friend declaration %qD is not visible to "
@@ -2965,6 +2989,9 @@  check_explicit_specialization (tree declarator,
 		inform (DECL_SOURCE_LOCATION (tmpl),
 			"friend declaration here");
 	    }
+	  else if (!ctype && !is_friend
+		   && CP_DECL_CONTEXT (decl) == current_namespace)
+	    check_unqualified_spec_or_inst (tmpl, DECL_SOURCE_LOCATION (decl));
 
 	  tree gen_tmpl = most_general_template (tmpl);
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit-inst1.C b/gcc/testsuite/g++.dg/cpp0x/explicit-inst1.C
new file mode 100644
index 0000000..a6455d8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/explicit-inst1.C
@@ -0,0 +1,13 @@ 
+// In C++11 explicit instantiation without a nested-name-specifier must be in
+// the same namespace.
+
+namespace N {
+  template <class T> class foo {};
+  template <class T> class bar {};
+}
+
+using N::bar;
+template class bar<int>;	// { dg-error "" "" { target c++11 } }
+
+using namespace N;
+template class foo<int>;	// { dg-error "" "" { target c++11 } }
diff --git a/gcc/testsuite/g++.dg/template/spec17.C b/gcc/testsuite/g++.dg/template/spec17.C
index 2375576..91c5d56 100644
--- a/gcc/testsuite/g++.dg/template/spec17.C
+++ b/gcc/testsuite/g++.dg/template/spec17.C
@@ -1,7 +1,7 @@ 
 // PR c++/16224
 
 namespace io { 
-  template <typename> int foo(); // { dg-error "" }
+  template <typename> int foo();
 } 
  
 using namespace io; 
diff --git a/gcc/testsuite/g++.dg/template/spec25.C b/gcc/testsuite/g++.dg/template/spec25.C
index 385d19a..d6f0f08 100644
--- a/gcc/testsuite/g++.dg/template/spec25.C
+++ b/gcc/testsuite/g++.dg/template/spec25.C
@@ -1,10 +1,10 @@ 
 namespace N {
   template <typename T>
   struct S {
-    void f() {}			// { dg-error "definition" }
+    void f() {}
   };
 }
 
 namespace K {
-  template <> void N::S<char>::f() {} // { dg-error "different namespace" }
+  template <> void N::S<char>::f() {} // { dg-error "namespace" }
 }
diff --git a/gcc/testsuite/g++.dg/template/spec36.C b/gcc/testsuite/g++.dg/template/spec36.C
index 7e8dc52..5807fc5 100644
--- a/gcc/testsuite/g++.dg/template/spec36.C
+++ b/gcc/testsuite/g++.dg/template/spec36.C
@@ -8,9 +8,9 @@  struct basic_string
 namespace MyNS {
   class MyClass {
     template <typename T>
-    T test() { } /* { dg-error "from definition" } */
+    T test() { } /* { dg-message "from definition" "" { target c++98_only } } */
   };
 }
 template <>
-basic_string MyNS::MyClass::test() /* { dg-error "specialization of" } */
+basic_string MyNS::MyClass::test() /* { dg-error "specialization of" "" { target c++98_only } }*/
 { return 1; }
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/template13.C b/gcc/testsuite/g++.old-deja/g++.ns/template13.C
index a9559c71..e8e5304 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/template13.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/template13.C
@@ -4,7 +4,7 @@  namespace bar
 {
   // trick it to provide some prior declaration
   template<class T>
-  void foo(); // { dg-error "definition" }
+  void foo();
   template<class T>class X; // { dg-message "note: previous declaration" }
 }
 
@@ -15,7 +15,7 @@  bar::foo(T const &a)     // { dg-error "" "" { xfail *-*-* } } not declared in b
   return a;
 }
 
-template<> void bar::foo<int>()     // { dg-error "different namespace" }
+template<> void bar::foo<int>()     // { dg-error "different namespace" "" { target c++98_only } }
 {
 }
 
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
index 1d83e34..f8ceaf7 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
@@ -7,7 +7,7 @@ 
 // the template
 
 namespace N {
-  template <class T> class foo;	// { dg-error "" } referenced below
+  template <class T> class foo;
 }
 
 using namespace N;
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C b/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C
index 1c04250..9d2add8 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C
@@ -13,8 +13,8 @@  namespace Outer {
   namespace Core = Core_Real;
 
   namespace Core_Real {
-    template<class T> void Foo (T *) {} // { dg-error "definition" }
+    template<class T> void Foo (T *) {}
   }
 
-  template<> void Core::Foo<> (Render_Real::Type *) {} // { dg-error "" }
+  template<> void Core::Foo<> (Render_Real::Type *) {} // { dg-error "" "" { target c++98_only } }
 }  
diff --git a/libstdc++-v3/testsuite/30_threads/future/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/future/requirements/explicit_instantiation.cc
index 1632523..87d423f 100644
--- a/libstdc++-v3/testsuite/30_threads/future/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/30_threads/future/requirements/explicit_instantiation.cc
@@ -25,9 +25,8 @@ 
 #include <testsuite_tr1.h>
 
 using namespace __gnu_test;
-using std::future;
-template class future<int>;
-template class future<int&>;
-template class future<void>;
-template class future<ClassType>;
-template class future<ClassType&>;
+template class std::future<int>;
+template class std::future<int&>;
+template class std::future<void>;
+template class std::future<ClassType>;
+template class std::future<ClassType&>;
diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/requirements/explicit_instantiation.cc
index db90ff2..e3b61e4 100644
--- a/libstdc++-v3/testsuite/30_threads/packaged_task/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/30_threads/packaged_task/requirements/explicit_instantiation.cc
@@ -25,9 +25,8 @@ 
 #include <testsuite_tr1.h>
 
 using namespace __gnu_test;
-using std::packaged_task;
-template class packaged_task<int()>;
-template class packaged_task<int&()>;
-template class packaged_task<void()>;
-template class packaged_task<ClassType(int)>;
-template class packaged_task<AbstractClass&(int)>;
+template class std::packaged_task<int()>;
+template class std::packaged_task<int&()>;
+template class std::packaged_task<void()>;
+template class std::packaged_task<ClassType(int)>;
+template class std::packaged_task<AbstractClass&(int)>;
diff --git a/libstdc++-v3/testsuite/30_threads/promise/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/promise/requirements/explicit_instantiation.cc
index 9691ab0..4a220a9 100644
--- a/libstdc++-v3/testsuite/30_threads/promise/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/30_threads/promise/requirements/explicit_instantiation.cc
@@ -25,9 +25,8 @@ 
 #include <testsuite_tr1.h>
 
 using namespace __gnu_test;
-using std::promise;
-template class promise<int>;
-template class promise<int&>;
-template class promise<void>;
-template class promise<ClassType>;
-template class promise<ClassType&>;
+template class std::promise<int>;
+template class std::promise<int&>;
+template class std::promise<void>;
+template class std::promise<ClassType>;
+template class std::promise<ClassType&>;
diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/shared_future/requirements/explicit_instantiation.cc
index a992b88..715b7fe 100644
--- a/libstdc++-v3/testsuite/30_threads/shared_future/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/30_threads/shared_future/requirements/explicit_instantiation.cc
@@ -25,9 +25,8 @@ 
 #include <testsuite_tr1.h>
 
 using namespace __gnu_test;
-using std::shared_future;
-template class shared_future<int>;
-template class shared_future<int&>;
-template class shared_future<void>;
-template class shared_future<ClassType>;
-template class shared_future<ClassType&>;
+template class std::shared_future<int>;
+template class std::shared_future<int&>;
+template class std::shared_future<void>;
+template class std::shared_future<ClassType>;
+template class std::shared_future<ClassType&>;
diff --git a/libstdc++-v3/testsuite/ext/numeric_traits/numeric_traits.cc b/libstdc++-v3/testsuite/ext/numeric_traits/numeric_traits.cc
index 6198743..6653625 100644
--- a/libstdc++-v3/testsuite/ext/numeric_traits/numeric_traits.cc
+++ b/libstdc++-v3/testsuite/ext/numeric_traits/numeric_traits.cc
@@ -21,7 +21,6 @@ 
 
 #include <ext/numeric_traits.h>
 
-using __gnu_cxx::__numeric_traits;
-template struct __numeric_traits<short>;
-template struct __numeric_traits<unsigned short>;
-template struct __numeric_traits<double>;
+template struct __gnu_cxx::__numeric_traits<short>;
+template struct __gnu_cxx::__numeric_traits<unsigned short>;
+template struct __gnu_cxx::__numeric_traits<double>;
diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/enable_shared_from_this/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/enable_shared_from_this/requirements/explicit_instantiation/1.cc
index a7b967f..18d94df 100644
--- a/libstdc++-v3/testsuite/tr1/2_general_utilities/enable_shared_from_this/requirements/explicit_instantiation/1.cc
+++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/enable_shared_from_this/requirements/explicit_instantiation/1.cc
@@ -23,8 +23,7 @@ 
 // { dg-do compile }
 
 using namespace __gnu_test;
-using std::tr1::enable_shared_from_this;
-template class enable_shared_from_this<int>;
-template class enable_shared_from_this<void>;
-template class enable_shared_from_this<ClassType>;
-template class enable_shared_from_this<IncompleteClass>;
+template class std::tr1::enable_shared_from_this<int>;
+template class std::tr1::enable_shared_from_this<void>;
+template class std::tr1::enable_shared_from_this<ClassType>;
+template class std::tr1::enable_shared_from_this<IncompleteClass>;
diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/1.cc
index 794deaf..918822d 100644
--- a/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/1.cc
+++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/1.cc
@@ -23,8 +23,7 @@ 
 // { dg-do compile }
 
 using namespace __gnu_test;
-using std::tr1::shared_ptr;
-template class shared_ptr<int>;
-template class shared_ptr<void>;
-template class shared_ptr<ClassType>;
-template class shared_ptr<IncompleteClass>;
+template class std::tr1::shared_ptr<int>;
+template class std::tr1::shared_ptr<void>;
+template class std::tr1::shared_ptr<ClassType>;
+template class std::tr1::shared_ptr<IncompleteClass>;
diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/2.cc
index 93587b2..870e888 100644
--- a/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/requirements/explicit_instantiation/2.cc
@@ -26,8 +26,7 @@ 
 // library this checks the templates can be instantiated for non-default
 // lock policy, for a single-threaded lib this is redundant but harmless.
 using namespace __gnu_test;
-using std::tr1::__shared_ptr;
 using std::tr1::_S_single;
-template class __shared_ptr<int, _S_single>;
-template class __shared_ptr<ClassType, _S_single>;
-template class __shared_ptr<IncompleteClass, _S_single>;
+template class std::tr1::__shared_ptr<int, _S_single>;
+template class std::tr1::__shared_ptr<ClassType, _S_single>;
+template class std::tr1::__shared_ptr<IncompleteClass, _S_single>;
diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/1.cc
index d64517c..0680ead 100644
--- a/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/1.cc
+++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/1.cc
@@ -23,8 +23,7 @@ 
 // { dg-do compile }
 
 using namespace __gnu_test;
-using std::tr1::weak_ptr;
-template class weak_ptr<int>;
-template class weak_ptr<void>;
-template class weak_ptr<ClassType>;
-template class weak_ptr<IncompleteClass>;
+template class std::tr1::weak_ptr<int>;
+template class std::tr1::weak_ptr<void>;
+template class std::tr1::weak_ptr<ClassType>;
+template class std::tr1::weak_ptr<IncompleteClass>;
diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/2.cc
index 672e637..31617c9 100644
--- a/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/weak_ptr/requirements/explicit_instantiation/2.cc
@@ -26,9 +26,8 @@ 
 // library this checks the templates can be instantiated for non-default
 // lock policy, for a single-threaded lib this is redundant but harmless.
 using namespace __gnu_test;
-using std::tr1::__weak_ptr;
 using std::tr1::_S_single;
-template class __weak_ptr<int, _S_single>;
-template class __weak_ptr<void, _S_single>;
-template class __weak_ptr<ClassType, _S_single>;
-template class __weak_ptr<IncompleteClass, _S_single>;
+template class std::tr1::__weak_ptr<int, _S_single>;
+template class std::tr1::__weak_ptr<void, _S_single>;
+template class std::tr1::__weak_ptr<ClassType, _S_single>;
+template class std::tr1::__weak_ptr<IncompleteClass, _S_single>;
diff --git a/libstdc++-v3/testsuite/tr1/6_containers/hash/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr1/6_containers/hash/requirements/explicit_instantiation.cc
index aba574d..5f017c7 100644
--- a/libstdc++-v3/testsuite/tr1/6_containers/hash/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/tr1/6_containers/hash/requirements/explicit_instantiation.cc
@@ -24,27 +24,25 @@ 
 #include <string>
 #include <tr1/functional>
 
-using namespace std::tr1;
-
 // Verify that we can instantiate hash for every required type.
-template class hash<bool>;
-template class hash<char>;
-template class hash<signed char>;
-template class hash<unsigned char>;
-template class hash<short>;
-template class hash<int>;
-template class hash<long>;
-template class hash<unsigned short>;
-template class hash<unsigned int>;
-template class hash<unsigned long>;
-template class hash<float>;
-template class hash<double>;
-template class hash<long double>;
-template class hash<void*>;
-template class hash<std::string>;
+template class std::tr1::hash<bool>;
+template class std::tr1::hash<char>;
+template class std::tr1::hash<signed char>;
+template class std::tr1::hash<unsigned char>;
+template class std::tr1::hash<short>;
+template class std::tr1::hash<int>;
+template class std::tr1::hash<long>;
+template class std::tr1::hash<unsigned short>;
+template class std::tr1::hash<unsigned int>;
+template class std::tr1::hash<unsigned long>;
+template class std::tr1::hash<float>;
+template class std::tr1::hash<double>;
+template class std::tr1::hash<long double>;
+template class std::tr1::hash<void*>;
+template class std::tr1::hash<std::string>;
 
 #ifdef _GLIBCXX_USE_WCHAR_T
-template class hash<wchar_t>;
-template class hash<std::wstring>;
+template class std::tr1::hash<wchar_t>;
+template class std::tr1::hash<std::wstring>;
 #endif
 
diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/requirements/explicit_instantiation.cc
index f659817..60ac8a5 100644
--- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_map/requirements/explicit_instantiation.cc
@@ -30,13 +30,13 @@  using std::allocator;
 using std::pair;
 using std::equal_to;
 
-template class unordered_map<string, float>;
-template class unordered_map<string, int,
+template class std::tr1::unordered_map<string, float>;
+template class std::tr1::unordered_map<string, int,
 			     hash<string>, equal_to<string>,
 			     allocator<pair<const string, int> > >;
-template class unordered_map<string, float,
+template class std::tr1::unordered_map<string, float,
 			     hash<string>, equal_to<string>,
 			     allocator<char> >;
-template class __unordered_map<string, int,
+template class std::tr1::__unordered_map<string, int,
 			       hash<string>, equal_to<string>,
 			       allocator<pair<const string, int> >, true>;
diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/requirements/explicit_instantiation.cc
index 5b72ae9..e92da82 100644
--- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multimap/requirements/explicit_instantiation.cc
@@ -30,13 +30,13 @@  using std::equal_to;
 using std::allocator;
 using std::pair;
 
-template class unordered_multimap<string, float>;
-template class unordered_multimap<string, int,
+template class std::tr1::unordered_multimap<string, float>;
+template class std::tr1::unordered_multimap<string, int,
 				  hash<string>, equal_to<string>,
 				  allocator<pair<const string, int> > >;
-template class unordered_multimap<string, float,
+template class std::tr1::unordered_multimap<string, float,
 				  hash<string>, equal_to<string>,
 				  allocator<char> >;
-template class __unordered_multimap<string, int,
+template class std::tr1::__unordered_multimap<string, int,
 				    hash<string>, equal_to<string>,
 				    allocator<pair<const string, int> >, true>;
diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/requirements/explicit_instantiation.cc
index a160526..662184b 100644
--- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_multiset/requirements/explicit_instantiation.cc
@@ -27,10 +27,10 @@  using namespace std::tr1;
 using std::equal_to;
 using std::allocator;
 
-template class unordered_multiset<int>;
-template class unordered_multiset<float, hash<float>, equal_to<float>,
+template class std::tr1::unordered_multiset<int>;
+template class std::tr1::unordered_multiset<float, hash<float>, equal_to<float>,
 				  allocator<float> >;
-template class unordered_multiset<int, hash<int>, equal_to<int>,
+template class std::tr1::unordered_multiset<int, hash<int>, equal_to<int>,
 				  allocator<char> >;
-template class __unordered_multiset<float, hash<float>, equal_to<float>,
+template class std::tr1::__unordered_multiset<float, hash<float>, equal_to<float>,
 				    allocator<float>, true>;
diff --git a/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/requirements/explicit_instantiation.cc
index 15679e1..5d4d83d 100644
--- a/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/tr1/6_containers/unordered_set/requirements/explicit_instantiation.cc
@@ -27,10 +27,10 @@  using namespace std::tr1;
 using std::equal_to;
 using std::allocator;
 
-template class unordered_set<int>;
-template class unordered_set<float, hash<float>, equal_to<float>,
-			     allocator<float> >;
-template class unordered_set<int, hash<int>, equal_to<int>,
-			     allocator<char> >;
-template class __unordered_set<float, hash<float>, equal_to<float>,
-			       allocator<float>, true>;
+template class std::tr1::unordered_set<int>;
+template class std::tr1::unordered_set<float, hash<float>, equal_to<float>,
+				       allocator<float> >;
+template class std::tr1::unordered_set<int, hash<int>, equal_to<int>,
+				       allocator<char> >;
+template class std::tr1::__unordered_set<float, hash<float>, equal_to<float>,
+					 allocator<float>, true>;