From 1248bd828b4742d395f6d2c545ba90ed69b2813f Mon Sep 17 00:00:00 2001 From: Volker Reichelt Date: Tue, 15 Nov 2005 19:14:21 +0000 Subject: [PATCH] re PR c++/19253 (bad error message / ICE for invalid template parameter) PR c++/19253 PR c++/22172 Backport from mainline: 2005-11-02 Mark Mitchell * parser.c (cp_parser_postfix_expression): Use cp_parser_elaborated_type_specifier to handle typename-types in functional casts. (cp_parser_enclosed_argument_list): Skip ahead to the end of the template argument list if the closing ">" is not found. Backport from mainline: 2005-11-02 Mark Mitchell PR c++/19253 * g++.dg/parse/typename10.C: New test. Backport from mainline: 2005-10-08 James A. Morrison PR c++/22172 * g++.dg/parse/crash30.C: New test. From-SVN: r107037 --- gcc/cp/ChangeLog | 13 ++++++ gcc/cp/parser.c | 53 ++++--------------------- gcc/testsuite/ChangeLog | 14 +++++++ gcc/testsuite/g++.dg/parse/crash30.C | 18 +++++++++ gcc/testsuite/g++.dg/parse/typename10.C | 8 ++++ 5 files changed, 60 insertions(+), 46 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/crash30.C create mode 100644 gcc/testsuite/g++.dg/parse/typename10.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index beab029a9bb3..27bd94771911 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2005-11-15 Volker Reichelt + + PR c++/19253 + PR c++/22172 + Backport from mainline: + 2005-11-02 Mark Mitchell + + * parser.c (cp_parser_postfix_expression): Use + cp_parser_elaborated_type_specifier to handle typename-types in + functional casts. + (cp_parser_enclosed_argument_list): Skip ahead to the end of the + template argument list if the closing ">" is not found. + 2005-11-14 Jason Merrill PR c++/24580 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 03c9f589ce5b..70218f92f5ec 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3552,52 +3552,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) case RID_TYPENAME: { - 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. 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 - identifier. */ - cp_parser_parse_tentatively (parser); - /* Try a template-id. */ - id = cp_parser_template_id (parser, template_p, - /*check_dependency_p=*/true, - /*is_declaration=*/true); - /* 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. */ - 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 - functional cast is being performed. */ - else - type = make_typename_type (parser->scope, id, - /*complain=*/1); + /* The syntax permitted here is the same permitted for an + elaborated-type-specifier. */ + type = cp_parser_elaborated_type_specifier (parser, + /*is_friend=*/false, + /*is_declaration=*/false); postfix_expression = cp_parser_functional_cast (parser, type); } break; @@ -14776,8 +14737,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser) cp_lexer_consume_token (parser->lexer); } } - else if (!cp_parser_require (parser, CPP_GREATER, "`>'")) - error ("missing `>' to terminate the template argument list"); + else + cp_parser_skip_until_found (parser, CPP_GREATER, "`>'"); /* The `>' token might be a greater-than operator again now. */ parser->greater_than_is_operator_p = saved_greater_than_is_operator_p; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b4e0a4009cc3..b41dcceda451 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2005-11-15 Volker Reichelt + + Backport from mainline: + 2005-11-02 Mark Mitchell + + PR c++/19253 + * g++.dg/parse/typename10.C: New test. + + Backport from mainline: + 2005-10-08 James A. Morrison + + PR c++/22172 + * g++.dg/parse/crash30.C: New test. + 2005-11-10 Uros Bizjak PR target/24315 diff --git a/gcc/testsuite/g++.dg/parse/crash30.C b/gcc/testsuite/g++.dg/parse/crash30.C new file mode 100644 index 000000000000..9b68535faa48 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/crash30.C @@ -0,0 +1,18 @@ +// { dg-do compile } +namespace N { template struct A { operator int() const; }; } +namespace M { template struct A {}; } +namespace P { typedef int I; } + +template void foo() +{ + +typename N::A<0>(); // { dg-bogus "expected" } +} + +template void bar() +{ + +typename M::A<0>; // { dg-error "expected" } +} + +template void baz() { + typename P::I i; // { dg-bogus "expected" } +} diff --git a/gcc/testsuite/g++.dg/parse/typename10.C b/gcc/testsuite/g++.dg/parse/typename10.C new file mode 100644 index 000000000000..759a3c9b997d --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/typename10.C @@ -0,0 +1,8 @@ +// PR c++/19253 + +namespace N { struct X; } + +template struct A +{ + A a; // { dg-error "invalid|declaration" } +}; -- 2.47.2