This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.


(Fixed g++.dg/template/spec25.C issue. Sorry for the churn.)

DR374: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374
allows explicit specialization of templates in the enclosing namespace.
Because this idiom is currently already accepted with -fpermissive, the
fix is easy: Just skip the calls to permerror().

Tested on powerpc64-unknown-linux-gnu.
OK for trunk?

Thanks again.

2014-11-02  Markus Trippelsdorf  <markus@trippelsdorf.de>

	DR 374
	PR c++/56480
	* pt.c (check_explicit_instantiation_namespace): Move above.
	* pt.c (check_specialization_namespace): Skip permerror()
	for C++11 and up. Make sure instantiation is valid in current
	namespace.

	DR 374
	PR c++/56480
	* g++.dg/template/spec17.C: Don't dg-error for C++11 and up.
	* g++.dg/template/spec25.C: Likewise. Adjust regex.
	* g++.dg/template/spec36.C: Don't dg-error for C++11 and up.
	* g++.old-deja/g++.ns/template13.C: Likewise.
	* g++.old-deja/g++.pt/explicit73.C: Likewise.
	* g++.old-deja/g++.pt/lookup10.C: Likewise.
---
 gcc/cp/pt.c                                    | 45 +++++++++++++++-----------
 gcc/testsuite/g++.dg/template/spec17.C         |  4 +--
 gcc/testsuite/g++.dg/template/spec25.C         |  4 +--
 gcc/testsuite/g++.dg/template/spec36.C         |  4 +--
 gcc/testsuite/g++.old-deja/g++.ns/template13.C |  6 ++--
 gcc/testsuite/g++.old-deja/g++.pt/explicit73.C |  4 +--
 gcc/testsuite/g++.old-deja/g++.pt/lookup10.C   |  4 +--
 7 files changed, 39 insertions(+), 32 deletions(-)

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2cf10f442f68..8672202f91e2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -755,6 +755,23 @@ end_explicit_instantiation (void)
   processing_explicit_instantiation = false;
 }
 
+/* SPEC is an explicit instantiation.  Check that it is valid to
+   perform this explicit instantiation in the current namespace.  */
+
+static void
+check_explicit_instantiation_namespace (tree spec)
+{
+  tree ns;
+
+  /* DR 275: An explicit instantiation shall appear in an enclosing
+     namespace of its template.  */
+  ns = decl_namespace_context (spec);
+  if (!is_ancestor (current_namespace, ns))
+    permerror (input_location, "explicit instantiation of %qD in namespace %qD "
+	       "(which does not enclose namespace %qD)",
+	       spec, current_namespace, ns);
+}
+
 /* An explicit specialization or partial specialization of TMPL is being
    declared.  Check that the namespace in which the specialization is
    occurring is permissible.  Returns false iff it is invalid to
@@ -785,29 +802,19 @@ check_specialization_namespace (tree tmpl)
     return true;
   else
     {
-      permerror (input_location, "specialization of %qD in different namespace", tmpl);
-      permerror (input_location, "  from definition of %q+#D", tmpl);
+      if (cxx_dialect < cxx11)
+	{
+	  permerror (input_location, "specialization of %qD in different "
+		     "namespace", tmpl);
+	  permerror (input_location, "  from definition of %q+#D", tmpl);
+	}
+      else
+	check_explicit_instantiation_namespace (tmpl);
+
       return false;
     }
 }
 
-/* SPEC is an explicit instantiation.  Check that it is valid to
-   perform this explicit instantiation in the current namespace.  */
-
-static void
-check_explicit_instantiation_namespace (tree spec)
-{
-  tree ns;
-
-  /* DR 275: An explicit instantiation shall appear in an enclosing
-     namespace of its template.  */
-  ns = decl_namespace_context (spec);
-  if (!is_ancestor (current_namespace, ns))
-    permerror (input_location, "explicit instantiation of %qD in namespace %qD "
-	       "(which does not enclose namespace %qD)",
-	       spec, current_namespace, ns);
-}
-
 /* The TYPE is being declared.  If it is a template type, that means it
    is a partial specialization.  Do appropriate error-checking.  */
 
diff --git a/gcc/testsuite/g++.dg/template/spec17.C b/gcc/testsuite/g++.dg/template/spec17.C
index 237557684238..70e5be28e05a 100644
--- a/gcc/testsuite/g++.dg/template/spec17.C
+++ b/gcc/testsuite/g++.dg/template/spec17.C
@@ -1,11 +1,11 @@
 // PR c++/16224
 
 namespace io { 
-  template <typename> int foo(); // { dg-error "" }
+  template <typename> int foo(); // { dg-error "" "" { target { ! c++11 } } }
 } 
  
 using namespace io; 
  
-template<> int foo<int>(); // { dg-error "" }
+template<> int foo<int>(); // { dg-error "" "" { target { ! c++11 } } }
  
 int a = foo<int>(); 
diff --git a/gcc/testsuite/g++.dg/template/spec25.C b/gcc/testsuite/g++.dg/template/spec25.C
index 385d19ada0c4..c3836261f6af 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() {}			// { dg-error "definition" "" { target { ! c++11 } } }
   };
 }
 
 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 7e8dc5241d9f..d9c57824b7e5 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-error "from definition" "" { target { ! c++11 } } } */
   };
 }
 template <>
-basic_string MyNS::MyClass::test() /* { dg-error "specialization of" } */
+basic_string MyNS::MyClass::test() /* { dg-error "specialization of" "" { target { ! c++11 } } } */
 { 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 a9559c7153b6..21ad61847b73 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/template13.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/template13.C
@@ -4,18 +4,18 @@ namespace bar
 {
   // trick it to provide some prior declaration
   template<class T>
-  void foo(); // { dg-error "definition" }
+  void foo(); // { dg-error "definition" "" { target { ! c++11 } } }
   template<class T>class X; // { dg-message "note: previous declaration" }
 }
 
 template <typename T>
 T const
-bar::foo(T const &a)     // { dg-error "" "" { xfail *-*-* } } not declared in bar - 
+bar::foo(T const &a)    // { dg-error "" "" { xfail *-*-* } } not declared in bar -
 {
   return a;
 }
 
-template<> void bar::foo<int>()     // { dg-error "different namespace" }
+template<> void bar::foo<int>()     // { dg-error "different namespace" "" { target { ! c++11 } } }
 {
 }
 
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
index 1d83e3468289..bcf4fe7f21a5 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
@@ -7,9 +7,9 @@
 // the template
 
 namespace N {
-  template <class T> class foo;	// { dg-error "" } referenced below
+  template <class T> class foo;	// { dg-error "" "" { target { ! c++11 } } } referenced below
 }
 
 using namespace N;
 
-template <> class foo<void>; // { dg-error "" } invalid specialization
+template <> class foo<void>; // { dg-error "" "" { target { ! c++11 } } } invalid specialization
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C b/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C
index 1c04250fc3c0..0ed5dbe42c89 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 *) {} // { dg-error "definition" "" { target { ! c++11 } } }
   }
 
-  template<> void Core::Foo<> (Render_Real::Type *) {} // { dg-error "" }
+  template<> void Core::Foo<> (Render_Real::Type *) {} // { dg-error "" "" { target { ! c++11 } } }
 }  
-- 
2.1.3

-- 
Markus


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]