]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/53492 (ICE in retrieve_specialization, at cp/pt.c:985)
authorJason Merrill <jason@redhat.com>
Mon, 10 Mar 2014 15:44:50 +0000 (11:44 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 10 Mar 2014 15:44:50 +0000 (11:44 -0400)
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

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/template/memtmpl4.C [new file with mode: 0644]

index b48bb47d0bd0ff18d7aee7d250fae69a47ba133c..8e184bc5222e6255d17689d936842cd66a81b1e3 100644 (file)
@@ -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
index 64583ba98bdae88da19719c1bdf6451e50621567..a3c8d7ecb3f96389248a79a18185eb0d9758c303 100644 (file)
@@ -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);
index 5afe0fdabc7e511a3594dca9e2e34bc94069abe3..7e287f793e858ab816d9c02ad7ff44364d98e8ae 100644 (file)
@@ -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 (file)
index 0000000..54558b9
--- /dev/null
@@ -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 "" }