Index: cp/decl.c =================================================================== --- cp/decl.c (revision 196497) +++ cp/decl.c (working copy) @@ -11712,9 +11712,6 @@ check_elaborated_type_specifier (enum tag_types ta { tree type; - if (decl == error_mark_node) - return error_mark_node; - /* In the case of: struct S { struct S *p; }; Index: cp/parser.c =================================================================== --- cp/parser.c (revision 196497) +++ cp/parser.c (working copy) @@ -14248,12 +14248,14 @@ cp_parser_elaborated_type_specifier (cp_parser* pa typename_type, /*complain=*/tf_error); /* If the `typename' keyword is in effect and DECL is not a type - decl. Then type is non existant. */ + decl, then type is non existent. */ else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL) - type = NULL_TREE; - else - type = check_elaborated_type_specifier (tag_type, decl, + ; + else if (TREE_CODE (decl) == TYPE_DECL) + type = check_elaborated_type_specifier (tag_type, decl, /*allow_template_p=*/true); + else if (decl == error_mark_node) + type = error_mark_node; } if (!type) Index: testsuite/g++.dg/template/crash115.C =================================================================== --- testsuite/g++.dg/template/crash115.C (revision 0) +++ testsuite/g++.dg/template/crash115.C (working copy) @@ -0,0 +1,3 @@ +// PR c++/56534 + +template < struct template rebind < > // { dg-error "expected" }