From 26c895e7dc411d217603e6b2f944b9750c4404d2 Mon Sep 17 00:00:00 2001 From: Kriang Lerdsuwanakij Date: Sat, 19 Mar 2005 11:54:49 +0000 Subject: [PATCH] re PR c++/20333 (ICE on invalid code, typename outside of a template) PR c++/20333 * parser.c (cp_parser_postfix_expression) : Check the return value of cp_parser_nested_name_specifier. * g++.dg/template/crash36.C: New test. From-SVN: r96720 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/parser.c | 22 +++++++++++++++------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/template/crash36.C | 9 +++++++++ 4 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/crash36.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9bcdbb6bff3..aade257bcb6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2005-03-19 Kriang Lerdsuwanakij + + PR c++/20333 + * parser.c (cp_parser_postfix_expression) : + Check the return value of cp_parser_nested_name_specifier. + 2005-03-18 Paolo Carlini PR c++/20463 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 2724f5a29db..6df7bad1d81 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3861,18 +3861,22 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p) bool template_p = false; tree id; tree type; + tree scope; /* Consume the `typename' token. */ cp_lexer_consume_token (parser->lexer); /* Look for the optional `::' operator. */ cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false); - /* Look for the nested-name-specifier. */ - cp_parser_nested_name_specifier (parser, - /*typename_keyword_p=*/true, - /*check_dependency_p=*/true, - /*type_p=*/true, - /*is_declaration=*/true); + /* Look for the nested-name-specifier. In case of error here, + consume the trailing id to avoid subsequent error messages + for usual cases. */ + scope = cp_parser_nested_name_specifier (parser, + /*typename_keyword_p=*/true, + /*check_dependency_p=*/true, + /*type_p=*/true, + /*is_declaration=*/true); + /* Look for the optional `template' keyword. */ template_p = cp_parser_optional_template_keyword (parser); /* We don't know whether we're looking at a template-id or an @@ -3885,9 +3889,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p) /* If that didn't work, try an identifier. */ if (!cp_parser_parse_definitely (parser)) id = cp_parser_identifier (parser); + + /* Don't process id if nested name specifier is invalid. */ + if (scope == error_mark_node) + return error_mark_node; /* If we look up a template-id in a non-dependent qualifying scope, there's no need to create a dependent type. */ - if (TREE_CODE (id) == TYPE_DECL + else if (TREE_CODE (id) == TYPE_DECL && !dependent_type_p (parser->scope)) type = TREE_TYPE (id); /* Create a TYPENAME_TYPE to represent the type to which the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 861304d12d0..d223ddb3eb3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-03-19 Kriang Lerdsuwanakij + + PR c++/20333 + * g++.dg/template/crash36.C: New test. + 2005-03-18 Paolo Carlini PR c++/20463 diff --git a/gcc/testsuite/g++.dg/template/crash36.C b/gcc/testsuite/g++.dg/template/crash36.C new file mode 100644 index 00000000000..2f0ef921a67 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash36.C @@ -0,0 +1,9 @@ +// { dg-do compile } + +// Origin: Ivan Godard +// Andrew Pinski + +// PR c++/20333: ICE parsing typename without nested-name-specifier + +template struct f {}; +f f2[2] = {typename f()}; // { dg-error "" }