This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH v2] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.
- From: Markus Trippelsdorf <markus at trippelsdorf dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jason Merrill <jason at redhat dot com>
- Date: Sun, 2 Nov 2014 15:15:50 +0100
- Subject: [PATCH v2] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.
- Authentication-results: sourceware.org; auth=none
- References: <20141102125814 dot GB31234 at x4> <20141102132914 dot GC31234 at x4>
(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