diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b48bb47d0bd..8e184bc5222 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2014-03-10 Jason Merrill + + 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 PR c++/60033 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 64583ba98bd..a3c8d7ecb3f 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 5afe0fdabc7..7e287f793e8 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 00000000000..54558b98068 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memtmpl4.C @@ -0,0 +1,10 @@ +// PR c++/53492 + +template struct A +{ + template struct B; +}; + +template <> template struct A::B { }; // { dg-error "expected 2 levels" } + +A::B b; // { dg-error "" }