aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-12-11 13:16:50 -0500
committerJason Merrill <jason@gcc.gnu.org>2012-12-11 13:16:50 -0500
commitdf266ea5fe3a76bc03108764befb939cc69b2f90 (patch)
tree71a6dc59ed886455276ee5e3753a8735a3efe6b3 /gcc
parentbefd067c5ab038183979ee93a7010b5dcc9f1e2e (diff)
downloadgcc-df266ea5fe3a76bc03108764befb939cc69b2f90.zip
gcc-df266ea5fe3a76bc03108764befb939cc69b2f90.tar.gz
gcc-df266ea5fe3a76bc03108764befb939cc69b2f90.tar.bz2
re PR c++/54416 (ICE (segv) in codegen)
PR c++/54416 * pt.c (maybe_process_partial_specialization): Don't accept definition of a specialization without the appropriate header. From-SVN: r194408
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/pt.c8
-rw-r--r--gcc/testsuite/g++.dg/template/crash105.C5
-rw-r--r--gcc/testsuite/g++.dg/template/error48.C15
4 files changed, 30 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 02c0bfe..2c3efe8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2012-12-11 Jason Merrill <jason@redhat.com>
+ PR c++/54416
+ * pt.c (maybe_process_partial_specialization): Don't accept
+ definition of a specialization without the appropriate header.
+
* pt.c (maybe_process_partial_specialization): Handle aliases first.
2012-12-11 Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f30a1e1..91450d8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -850,7 +850,13 @@ maybe_process_partial_specialization (tree type)
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
error ("specialization of %qT after instantiation", type);
-
+ else if (errorcount && !processing_specialization
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (type)
+ && !uses_template_parms (CLASSTYPE_TI_ARGS (type)))
+ /* Trying to define a specialization either without a template<> header
+ or in an inappropriate place. We've already given an error, so just
+ bail now so we don't actually define the specialization. */
+ return error_mark_node;
}
else if (CLASS_TYPE_P (type)
&& !CLASSTYPE_USE_TEMPLATE (type)
diff --git a/gcc/testsuite/g++.dg/template/crash105.C b/gcc/testsuite/g++.dg/template/crash105.C
index 649bf8b..8cfff6a 100644
--- a/gcc/testsuite/g++.dg/template/crash105.C
+++ b/gcc/testsuite/g++.dg/template/crash105.C
@@ -10,5 +10,8 @@ template < typename > struct S < int >
void
f ()
{
- S < int >::f (); // { dg-error "cannot call" }
+ S < int >::f ();
}
+
+// Don't be picky about error-recovery.
+// { dg-prune-output "." }
diff --git a/gcc/testsuite/g++.dg/template/error48.C b/gcc/testsuite/g++.dg/template/error48.C
new file mode 100644
index 0000000..483f7b5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/error48.C
@@ -0,0 +1,15 @@
+// PR c++/54416
+
+template < typename T > struct foo;
+template <> struct foo < int >;
+template < typename T > struct bar
+{
+ template <> struct foo < int > // { dg-error "non-namespace scope" }
+ {
+ void baz ();
+ };
+};
+void foo < int >::baz () { }
+
+// Don't be picky about error-recovery.
+// { dg-prune-output "." }