aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-03-10 11:44:50 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-03-10 11:44:50 -0400
commit4d3f2fa687ec4c8cf6aa668f4c2eab4f298c3f8e (patch)
tree88eab3ba0706e5f72df74b8eab5b4eb752e653fb
parent31dad8091a44abef7ac099835ea2a241f1dc4057 (diff)
downloadgcc-4d3f2fa687ec4c8cf6aa668f4c2eab4f298c3f8e.zip
gcc-4d3f2fa687ec4c8cf6aa668f4c2eab4f298c3f8e.tar.gz
gcc-4d3f2fa687ec4c8cf6aa668f4c2eab4f298c3f8e.tar.bz2
re PR c++/53492 (ICE in retrieve_specialization, at cp/pt.c:985)
PR c++/53492 * parser.c (cp_parser_class_head): Also check PRIMARY_TEMPLATE_P when deciding whether to call push_template_decl for a member class. * pt.c (push_template_decl_real): Return after wrong levels error. From-SVN: r208455
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/parser.c8
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/testsuite/g++.dg/template/memtmpl4.C10
4 files changed, 26 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b48bb47d..8e184bc 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2014-03-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/53492
+ * parser.c (cp_parser_class_head): Also check PRIMARY_TEMPLATE_P
+ when deciding whether to call push_template_decl for a member class.
+ * pt.c (push_template_decl_real): Return after wrong levels error.
+
2014-03-08 Adam Butcher <adam@jessamine.co.uk>
PR c++/60033
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 64583ba..a3c8d7e 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -19888,7 +19888,13 @@ cp_parser_class_head (cp_parser* parser,
pushed_scope = push_scope (nested_name_specifier);
/* Get the canonical version of this type. */
type = TYPE_MAIN_DECL (TREE_TYPE (type));
- if (PROCESSING_REAL_TEMPLATE_DECL_P ()
+ /* Call push_template_decl if it seems like we should be defining a
+ template either from the template headers or the type we're
+ defining, so that we diagnose both extra and missing headers. */
+ if ((PROCESSING_REAL_TEMPLATE_DECL_P ()
+ || (CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (type))
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE
+ (TREE_TYPE (type)))))
&& !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (type)))
{
type = push_template_decl (type);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5afe0fd..7e287f7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4908,6 +4908,8 @@ push_template_decl_real (tree decl, bool is_friend)
{
error ("expected %d levels of template parms for %q#D, got %d",
i, decl, TMPL_ARGS_DEPTH (args));
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ return error_mark_node;
}
else
for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms))
diff --git a/gcc/testsuite/g++.dg/template/memtmpl4.C b/gcc/testsuite/g++.dg/template/memtmpl4.C
new file mode 100644
index 0000000..54558b9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/memtmpl4.C
@@ -0,0 +1,10 @@
+// PR c++/53492
+
+template<typename T> struct A
+{
+ template<typename U> struct B;
+};
+
+template <> template<class T> struct A<T>::B { }; // { dg-error "expected 2 levels" }
+
+A<int>::B<int> b; // { dg-error "" }