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 <mar...@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