public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.
@ 2014-11-02 12:58 Markus Trippelsdorf
  2014-11-02 13:29 ` Markus Trippelsdorf
  0 siblings, 1 reply; 8+ messages in thread
From: Markus Trippelsdorf @ 2014-11-02 12:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill

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() for C++11 and up.

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

Thanks.

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

	DR 374
	PR c++/56480
	* pt.c (check_specialization_namespace): Skip permerror()
	for C++11 and up.

	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.
	* g++.dg/template/spec36.C: Likewise.
	* g++.old-deja/g++.ns/template13.C: Likewise.
	* g++.old-deja/g++.pt/explicit73.C: Likewise.
	* g++.old-deja/g++.pt/lookup10.C: Likewise.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2cf10f442f68..09a545496fa8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -785,8 +785,12 @@ 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);
+	}
       return false;
     }
 }
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..d41c5fce1297 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 "different namespace" "" { target { ! c++11 } } }
 }
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 } } }
 }  
-- 
Markus

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.
  2014-11-02 12:58 [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace Markus Trippelsdorf
@ 2014-11-02 13:29 ` Markus Trippelsdorf
  2014-11-02 14:15   ` [PATCH v2] " Markus Trippelsdorf
  0 siblings, 1 reply; 8+ messages in thread
From: Markus Trippelsdorf @ 2014-11-02 13:29 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill

On 2014.11.02 at 13:58 +0100, Markus Trippelsdorf wrote:
> diff --git a/gcc/testsuite/g++.dg/template/spec25.C b/gcc/testsuite/g++.dg/template/spec25.C
> index 385d19ada0c4..d41c5fce1297 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 "different namespace" "" { target { ! c++11 } } }
>  }

Hmm, I think this testcase should actually be rejected even with C++11.

-- 
Markus

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.
  2014-11-02 13:29 ` Markus Trippelsdorf
@ 2014-11-02 14:15   ` Markus Trippelsdorf
  2014-11-03  2:13     ` Jason Merrill
  0 siblings, 1 reply; 8+ messages in thread
From: Markus Trippelsdorf @ 2014-11-02 14:15 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill

(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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.
  2014-11-02 14:15   ` [PATCH v2] " Markus Trippelsdorf
@ 2014-11-03  2:13     ` Jason Merrill
  2014-11-03 11:27       ` [PATCH v3] " Markus Trippelsdorf
  0 siblings, 1 reply; 8+ messages in thread
From: Jason Merrill @ 2014-11-03  2:13 UTC (permalink / raw)
  To: Markus Trippelsdorf, gcc-patches

On 11/02/2014 09:15 AM, Markus Trippelsdorf wrote:
> +      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);

In most cases I think DRs should apply to C++98 as well.  In this case I 
think a pedwarn only with -pedantic in C++98 is appropriate.  Let's put 
all the logic in check_....  And add a flag to distinguish between 
instantiation and specialization.

Jason

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v3] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.
  2014-11-03  2:13     ` Jason Merrill
@ 2014-11-03 11:27       ` Markus Trippelsdorf
  2014-11-03 14:48         ` Jason Merrill
  0 siblings, 1 reply; 8+ messages in thread
From: Markus Trippelsdorf @ 2014-11-03 11:27 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

On 2014.11.02 at 21:12 -0500, Jason Merrill wrote:
> On 11/02/2014 09:15 AM, Markus Trippelsdorf wrote:
> > +      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);
> 
> In most cases I think DRs should apply to C++98 as well.  In this case I 
> think a pedwarn only with -pedantic in C++98 is appropriate.  Let's put 
> all the logic in check_....  And add a flag to distinguish between 
> instantiation and specialization.

Thanks for the suggestions. I've implemented them below.

(If someone comes up with a better name than:
check_instant_or_special_namespace I would change it)

BTW both EDG and clang reject g++.dg/template/spec17.C:

namespace io { 
  template <typename> int foo();
}
using namespace io;
template<> int foo<int>();

But I think it is a reasonable extension to accept it.

Patch tested on powerpc64-unknown-linux-gnu.

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

	DR 374
	PR c++/56480
	* pt.c (check_explicit_instantiation_namespace)
  	(check_specialization_namespace): Consolidate into 
  	check_instant_or_special_namespace.
	(check_instant_or_special_namespace): pedwarn only with
	-pedantic in C++98.
	(maybe_process_partial_specialization): Call consolidated
	function.
	(register_specialization): Likewise.
	(do_decl_instantiation): Likewise.
	(do_type_instantiation): Likewise.

	DR 374
	PR c++/56480
	* g++.dg/template/spec17.C: Add -pedantic and -pedantic-errors
	to dg-options. Don't dg-error for C++11 and up.
	* g++.dg/template/spec25.C: Likewise. Adjust regex.
	* g++.dg/template/spec36.C: Likewise.
	* g++.old-deja/g++.ns/template13.C: Likewise.
	* g++.old-deja/g++.pt/explicit73.C: Likewise.
	* g++.old-deja/g++.pt/lookup10.C: Likewise.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2cf10f442f68..0eaa6a22f39d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -755,57 +755,58 @@ end_explicit_instantiation (void)
   processing_explicit_instantiation = false;
 }
 
-/* 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
-   specialize TMPL in the current namespace.  */
+/* If specialization is true, 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 specialize TMPL in the current namespace.
+   If specialization is false, TMPL is an explicit instantiation.
+   Check that it is valid to perform this explicit instantiation in
+   the current namespace.  */
 
 static bool
-check_specialization_namespace (tree tmpl)
+check_instant_or_special_namespace (tree tmpl, bool specialization)
 {
   tree tpl_ns = decl_namespace_context (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.  */
-  if (current_scope() != DECL_CONTEXT (tmpl)
-      && !at_namespace_scope_p ())
+  if (specialization)
     {
-      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.  */
-    return true;
-  else
-    {
-      permerror (input_location, "specialization of %qD in different namespace", tmpl);
-      permerror (input_location, "  from definition of %q+#D", tmpl);
-      return false;
-    }
-}
-
-/* SPEC is an explicit instantiation.  Check that it is valid to
-   perform this explicit instantiation in the current namespace.  */
+      /* [tmpl.expl.spec]
 
-static void
-check_explicit_instantiation_namespace (tree spec)
-{
-  tree ns;
+         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.  */
+      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.  */
+        return true;
+      /* DR374: explicit specializations of templates in an enclosing
+         namespace are allowed.  */
+      else if (cxx_dialect < cxx11)
+        {
+          pedwarn (input_location, OPT_Wpedantic,
+                   "specialization of %qD in different namespace", tmpl);
+          pedwarn (input_location, OPT_Wpedantic,
+	          "  from definition of %q+#D", tmpl);
+        }
+    }
 
   /* 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);
+  if (!is_ancestor (current_namespace, tpl_ns))
+    permerror (input_location,
+               "explicit instantiation of %qD in namespace %qD "
+               "(which does not enclose namespace %qD)",
+               tmpl, current_namespace, tpl_ns);
+
+  return false;
 }
 
 /* The TYPE is being declared.  If it is a template type, that means it
@@ -859,7 +860,8 @@ maybe_process_partial_specialization (tree type)
       if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
 	  && !COMPLETE_TYPE_P (type))
 	{
-	  if (!check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type))
+	  if (!check_instant_or_special_namespace (
+		CLASSTYPE_TI_TEMPLATE (type), true)
 	      && !at_namespace_scope_p ())
 	    return error_mark_node;
 	  SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type);
@@ -1454,7 +1456,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
 		  DECL_DELETED_FN (clone)
 		    = DECL_DELETED_FN (fn);
 		}
-	      check_specialization_namespace (tmpl);
+	      check_instant_or_special_namespace (tmpl, true);
 
 	      return fn;
 	    }
@@ -1476,7 +1478,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
   /* A specialization must be declared in the same namespace as the
      template it is specializing.  */
   if (DECL_P (spec) && DECL_TEMPLATE_SPECIALIZATION (spec)
-      && !check_specialization_namespace (tmpl))
+      && !check_instant_or_special_namespace (tmpl, true))
     DECL_CONTEXT (spec) = DECL_CONTEXT (tmpl);
 
   if (slot != NULL /* !optimize_specialization_lookup_p (tmpl) */)
@@ -19406,7 +19408,7 @@ do_decl_instantiation (tree decl, tree storage)
   else
     error ("storage class %qD applied to template instantiation", storage);
 
-  check_explicit_instantiation_namespace (result);
+  check_instant_or_special_namespace (result, false);
   mark_decl_instantiated (result, extern_p);
   if (! extern_p)
     instantiate_decl (result, /*defer_ok=*/1,
@@ -19554,7 +19556,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
 	return;
     }
 
-  check_explicit_instantiation_namespace (TYPE_NAME (t));
+  check_instant_or_special_namespace (TYPE_NAME (t), false);
   mark_class_instantiated (t, extern_p);
 
   if (nomem_p)
diff --git a/gcc/testsuite/g++.dg/template/spec17.C b/gcc/testsuite/g++.dg/template/spec17.C
index 237557684238..0b2e02bf450c 100644
--- a/gcc/testsuite/g++.dg/template/spec17.C
+++ b/gcc/testsuite/g++.dg/template/spec17.C
@@ -1,11 +1,12 @@
 // PR c++/16224
+// { dg-options "-pedantic -pedantic-errors" }
 
 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..c7b51a4beca7 100644
--- a/gcc/testsuite/g++.dg/template/spec25.C
+++ b/gcc/testsuite/g++.dg/template/spec25.C
@@ -1,10 +1,11 @@
+// { dg-options "-pedantic -pedantic-errors" }
 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..277a7f6243d5 100644
--- a/gcc/testsuite/g++.dg/template/spec36.C
+++ b/gcc/testsuite/g++.dg/template/spec36.C
@@ -1,5 +1,6 @@
 /* PR c++/38089 */
 /* { dg-do compile } */
+/* { dg-options "-pedantic -pedantic-errors" } */
 
 struct basic_string
 {
@@ -8,9 +9,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..805811fd8b54 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/template13.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/template13.C
@@ -1,10 +1,11 @@
 // { dg-do compile }
+// { dg-options "-pedantic -pedantic-errors" }
 // Templates defined outside must be declared inside
 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" }
 }
 
@@ -15,7 +16,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++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..1f5e1e9d8d7b 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
@@ -1,4 +1,5 @@
 // { dg-do assemble  }
+// { dg-options "-pedantic -pedantic-errors" }
 
 // by Alexandre Oliva <oliva@dcc.unicamp.br>
 
@@ -7,9 +8,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..02b21d94cc9b 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/lookup10.C
@@ -1,4 +1,5 @@
 // { dg-do assemble  }
+// { dg-options "-pedantic -pedantic-errors" }
 
 // Copyright (C) 2000 Free Software Foundation
 // Contributed by Nathan Sidwell 3 July 2000 <nathan@codesourcery.com>
@@ -13,8 +14,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 } } }
 }  
-- 
Markus

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.
  2014-11-03 11:27       ` [PATCH v3] " Markus Trippelsdorf
@ 2014-11-03 14:48         ` Jason Merrill
  2014-11-03 18:29           ` Markus Trippelsdorf
  2014-11-04 17:10           ` [RFC PATCH v4] " Markus Trippelsdorf
  0 siblings, 2 replies; 8+ messages in thread
From: Jason Merrill @ 2014-11-03 14:48 UTC (permalink / raw)
  To: Markus Trippelsdorf; +Cc: gcc-patches

On 11/03/2014 05:27 AM, Markus Trippelsdorf wrote:
> BTW both EDG and clang reject g++.dg/template/spec17.C:
>
> namespace io {
>    template <typename> int foo();
> }
> using namespace io;
> template<> int foo<int>();
>
> But I think it is a reasonable extension to accept it.

We should reject it, too.  We can only leave out the namespace 
qualification with inline namespaces.

> +// { dg-options "-pedantic -pedantic-errors" }

You shouldn't need these dg-options lines; if a testcase has no 
dg-options line, -pedantic-errors is the default.

Jason

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.
  2014-11-03 14:48         ` Jason Merrill
@ 2014-11-03 18:29           ` Markus Trippelsdorf
  2014-11-04 17:10           ` [RFC PATCH v4] " Markus Trippelsdorf
  1 sibling, 0 replies; 8+ messages in thread
From: Markus Trippelsdorf @ 2014-11-03 18:29 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

On 2014.11.03 at 08:47 -0600, Jason Merrill wrote:
> On 11/03/2014 05:27 AM, Markus Trippelsdorf wrote:
> > BTW both EDG and clang reject g++.dg/template/spec17.C:
> >
> > namespace io {
> >    template <typename> int foo();
> > }
> > using namespace io;
> > template<> int foo<int>();
> >
> > But I think it is a reasonable extension to accept it.
> 
> We should reject it, too.  We can only leave out the namespace 
> qualification with inline namespaces.

Where would be the best place to check for this issue?

> > +// { dg-options "-pedantic -pedantic-errors" }
> 
> You shouldn't need these dg-options lines; if a testcase has no 
> dg-options line, -pedantic-errors is the default.

OK. Fixed.

-- 
Markus

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [RFC PATCH v4] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.
  2014-11-03 14:48         ` Jason Merrill
  2014-11-03 18:29           ` Markus Trippelsdorf
@ 2014-11-04 17:10           ` Markus Trippelsdorf
  1 sibling, 0 replies; 8+ messages in thread
From: Markus Trippelsdorf @ 2014-11-04 17:10 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

On 2014.11.03 at 08:47 -0600, Jason Merrill wrote:
> On 11/03/2014 05:27 AM, Markus Trippelsdorf wrote:
> > BTW both EDG and clang reject g++.dg/template/spec17.C:
> >
> > namespace io {
> >    template <typename> int foo();
> > }
> > using namespace io;
> > template<> int foo<int>();
> >
> > But I think it is a reasonable extension to accept it.
> 
> We should reject it, too.  We can only leave out the namespace 
> qualification with inline namespaces.
> 
> > +// { dg-options "-pedantic -pedantic-errors" }
> 
> You shouldn't need these dg-options lines; if a testcase has no 
> dg-options line, -pedantic-errors is the default.

The following patch passes testing and fixes both issues.
Please let me know if you're OK with the general direction, before I
write a full Changelog.

Thanks.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 320c39f636a2..ddfa5ebfd968 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7855,7 +7855,8 @@ grokfndecl (tree ctype,
   decl = check_explicit_specialization (orig_declarator, decl,
 					template_count,
 					2 * funcdef_flag +
-					4 * (friendp != 0));
+					4 * (friendp != 0) +
+					8 * (in_namespace != 0));
   if (decl == error_mark_node)
     return NULL_TREE;
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2cf10f442f68..5cc320ed2fcf 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -755,57 +755,58 @@ end_explicit_instantiation (void)
   processing_explicit_instantiation = false;
 }
 
-/* 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
-   specialize TMPL in the current namespace.  */
+/* If specialization is true, 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 specialize TMPL in the current namespace.
+   If specialization is false, tmpl is an explicit instantiation.
+   Check that it is valid to perform this explicit instantiation in
+   the current namespace.  */
 
 static bool
-check_specialization_namespace (tree tmpl)
+check_instant_or_special_namespace (tree tmpl, bool specialization)
 {
   tree tpl_ns = decl_namespace_context (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.  */
-  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.  */
-    return true;
-  else
+  if (specialization)
     {
-      permerror (input_location, "specialization of %qD in different namespace", tmpl);
-      permerror (input_location, "  from definition of %q+#D", tmpl);
-      return false;
-    }
-}
+      /* [tmpl.expl.spec]
 
-/* 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;
+	 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.  */
+      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.  */
+	return true;
+      /* DR374: explicit specializations of templates in an enclosing
+	 namespace are allowed.  */
+      else if (cxx_dialect < cxx11)
+	{
+	  pedwarn (input_location, OPT_Wpedantic,
+		   "specialization of %qD in different namespace", tmpl);
+	  pedwarn (input_location, OPT_Wpedantic, "  from definition of %q+#D",
+		   tmpl);
+	}
+    }
 
   /* 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 "
+  if (!is_ancestor (current_namespace, tpl_ns))
+    permerror (input_location,
+	       "explicit instantiation of %qD in namespace %qD "
 	       "(which does not enclose namespace %qD)",
-	       spec, current_namespace, ns);
+	       tmpl, current_namespace, tpl_ns);
+
+  return false;
 }
 
 /* The TYPE is being declared.  If it is a template type, that means it
@@ -859,7 +860,8 @@ maybe_process_partial_specialization (tree type)
       if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
 	  && !COMPLETE_TYPE_P (type))
 	{
-	  if (!check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type))
+	  if (!check_instant_or_special_namespace (
+		CLASSTYPE_TI_TEMPLATE (type), true)
 	      && !at_namespace_scope_p ())
 	    return error_mark_node;
 	  SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type);
@@ -1338,14 +1340,22 @@ is_specialization_of_friend (tree decl, tree friend_decl)
    is actually just a friend declaration.  Returns SPEC, or an
    equivalent prior declaration, if available.
 
+   FLAGS is a bitmask consisting of the following flags:
+
+   2: The function has a definition.
+   4: The function is a friend.
+   8: The function has explicit namespace qualification.
+
    We also store instantiations of field packs in the hash table, even
    though they are not themselves templates, to make lookup easier.  */
 
 static tree
 register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
-			 hashval_t hash)
+			 hashval_t hash, int flags)
 {
   tree fn;
+  int have_def = flags & 2;
+  int in_namespace = flags & 8;
   spec_entry **slot = NULL;
   spec_entry elt;
 
@@ -1454,7 +1464,15 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
 		  DECL_DELETED_FN (clone)
 		    = DECL_DELETED_FN (fn);
 		}
-	      check_specialization_namespace (tmpl);
+
+
+	      if (!is_associated_namespace (current_namespace,
+					    decl_namespace_context (tmpl))
+		  && !have_def && !in_namespace)
+		error ("no function template matches function "
+		       "template specialization");
+
+	      check_instant_or_special_namespace (tmpl, true);
 
 	      return fn;
 	    }
@@ -1476,7 +1494,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
   /* A specialization must be declared in the same namespace as the
      template it is specializing.  */
   if (DECL_P (spec) && DECL_TEMPLATE_SPECIALIZATION (spec)
-      && !check_specialization_namespace (tmpl))
+      && !check_instant_or_special_namespace (tmpl, true))
     DECL_CONTEXT (spec) = DECL_CONTEXT (tmpl);
 
   if (slot != NULL /* !optimize_specialization_lookup_p (tmpl) */)
@@ -2347,6 +2365,7 @@ check_template_variable (tree decl)
 
    2: The function has a definition.
    4: The function is a friend.
+   8: The function has explicit namespace qualification.
 
    The TEMPLATE_COUNT is the number of references to qualifying
    template classes that appeared in the name of the function.  For
@@ -2741,7 +2760,7 @@ check_explicit_specialization (tree declarator,
 		    DECL_CONTEXT (parm) = result;
 		}
 	      return register_specialization (tmpl, gen_tmpl, targs,
-					      is_friend, 0);
+					      is_friend, 0, 0);
 	    }
 
 	  /* Set up the DECL_TEMPLATE_INFO for DECL.  */
@@ -2821,7 +2840,7 @@ check_explicit_specialization (tree declarator,
 
 	  /* Register this specialization so that we can find it
 	     again.  */
-	  decl = register_specialization (decl, gen_tmpl, targs, is_friend, 0);
+	  decl = register_specialization (decl, gen_tmpl, targs, is_friend, 0, flags);
 
 	  /* A 'structor should already have clones.  */
 	  gcc_assert (decl == error_mark_node
@@ -4930,7 +4949,7 @@ push_template_decl_real (tree decl, bool is_friend)
 	  register_specialization (new_tmpl,
 				   most_general_template (tmpl),
 				   args,
-				   is_friend, 0);
+				   is_friend, 0, 0);
 	  return decl;
 	}
 
@@ -8661,7 +8680,7 @@ tsubst_friend_function (tree decl, tree args)
 						       DECL_TI_ARGS (spec));
 
 		      register_specialization
-			(spec, new_template, DECL_TI_ARGS (spec), true, 0);
+			(spec, new_template, DECL_TI_ARGS (spec), true, 0, 0);
 
 		    }
 		  DECL_TEMPLATE_INSTANTIATIONS (old_decl) = NULL_TREE;
@@ -10587,7 +10606,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 	  /* Record this non-type partial instantiation.  */
 	  register_specialization (r, t,
 				   DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)),
-				   false, hash);
+				   false, hash, 0);
       }
       break;
 
@@ -10795,7 +10814,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 	    SET_DECL_IMPLICIT_INSTANTIATION (r);
 
 	    tree new_r
-	      = register_specialization (r, gen_tmpl, argvec, false, hash);
+	      = register_specialization (r, gen_tmpl, argvec, false, hash, 0);
 	    if (new_r != r)
 	      /* We instantiated this while substituting into
 		 the type earlier (template/friend54.C).  */
@@ -11067,7 +11086,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 	    SET_ARGUMENT_PACK_ARGS (pack, vec);
 	    SET_ARGUMENT_PACK_ARGS (tpack, expanded_types);
 	    TREE_TYPE (pack) = tpack;
-	    register_specialization (pack, t, args, false, 0);
+	    register_specialization (pack, t, args, false, 0, 0);
 	  }
       }
       break;
@@ -11293,7 +11312,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 	       processing here.  */
 	    DECL_EXTERNAL (r) = 1;
 
-	    register_specialization (r, gen_tmpl, argvec, false, hash);
+	    register_specialization (r, gen_tmpl, argvec, false, hash, 0);
 	    DECL_TEMPLATE_INFO (r) = build_template_info (tmpl, argvec);
 	    SET_DECL_IMPLICIT_INSTANTIATION (r);
 	  }
@@ -19406,7 +19425,7 @@ do_decl_instantiation (tree decl, tree storage)
   else
     error ("storage class %qD applied to template instantiation", storage);
 
-  check_explicit_instantiation_namespace (result);
+  check_instant_or_special_namespace (result, false);
   mark_decl_instantiated (result, extern_p);
   if (! extern_p)
     instantiate_decl (result, /*defer_ok=*/1,
@@ -19554,7 +19573,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
 	return;
     }
 
-  check_explicit_instantiation_namespace (TYPE_NAME (t));
+  check_instant_or_special_namespace (TYPE_NAME (t), false);
   mark_class_instantiated (t, extern_p);
 
   if (nomem_p)
diff --git a/gcc/testsuite/g++.dg/template/spec17.C b/gcc/testsuite/g++.dg/template/spec17.C
index 237557684238..849178920012 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(); // { dg-error "" "" { target { ! c++11 } } }
 } 
  
 using namespace io; 
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..0c99e74dc466 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(); // { dg-error "definition" "" { target { ! c++11 } } }
   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++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 } } }
 }  

-- 
Markus

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-11-04 17:10 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-02 12:58 [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace Markus Trippelsdorf
2014-11-02 13:29 ` Markus Trippelsdorf
2014-11-02 14:15   ` [PATCH v2] " Markus Trippelsdorf
2014-11-03  2:13     ` Jason Merrill
2014-11-03 11:27       ` [PATCH v3] " Markus Trippelsdorf
2014-11-03 14:48         ` Jason Merrill
2014-11-03 18:29           ` Markus Trippelsdorf
2014-11-04 17:10           ` [RFC PATCH v4] " Markus Trippelsdorf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).