From 88a33c3406ca21d94db7ca092f3f65c898e23fda Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Wed, 2 Nov 2005 21:34:51 +0000 Subject: [PATCH] re PR c++/19253 (bad error message / ICE for invalid template parameter) PR c++/19253 * 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. PR c++/19253 * g++.dg/parse/typename8.C: Compile with -w -fpermissive. * g++.dg/parse/typename9.C: New test. * g++/dg/parse/typename10.C: Likewise. From-SVN: r106398 --- gcc/cp/ChangeLog | 7 +++ gcc/cp/parser.c | 58 +++---------------------- gcc/testsuite/ChangeLog | 7 +++ gcc/testsuite/g++.dg/parse/typename10.C | 8 ++++ gcc/testsuite/g++.dg/parse/typename8.C | 2 + gcc/testsuite/g++.dg/parse/typename9.C | 3 ++ 6 files changed, 33 insertions(+), 52 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/typename10.C create mode 100644 gcc/testsuite/g++.dg/parse/typename9.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 410c88f05303..3df790125ee9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2005-11-02 Mark Mitchell + PR c++/19253 + * 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. + PR c++/24569 * pt.c (instantiate_decl): Use cp_finish_decl, not finish_static_data_member_decl. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a065c2569acb..94ce45f5f2d3 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3961,55 +3961,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_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 || 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 - && (!TYPE_P (scope) - || !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, - typename_type, - /*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; @@ -15498,11 +15455,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser) "a template argument list"); } } - else if (!cp_lexer_next_token_is (parser->lexer, CPP_GREATER)) - error ("missing %<>%> to terminate the template argument list"); else - /* It's what we want, a '>'; consume it. */ - cp_lexer_consume_token (parser->lexer); + 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 0b9bd9276fed..aa01d33892a6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2005-11-02 Mark Mitchell + + PR c++/19253 + * g++.dg/parse/typename8.C: Compile with -w -fpermissive. + * g++.dg/parse/typename9.C: New test. + * g++/dg/parse/typename10.C: Likewise. + 2005-11-02 Andrew Pinski PR fortran/18157 diff --git a/gcc/testsuite/g++.dg/parse/typename10.C b/gcc/testsuite/g++.dg/parse/typename10.C new file mode 100644 index 000000000000..64d6ae8c207c --- /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" } +}; diff --git a/gcc/testsuite/g++.dg/parse/typename8.C b/gcc/testsuite/g++.dg/parse/typename8.C index 413e954daebe..e8e762709b4b 100644 --- a/gcc/testsuite/g++.dg/parse/typename8.C +++ b/gcc/testsuite/g++.dg/parse/typename8.C @@ -4,6 +4,8 @@ // PR 23797:ICE // Origin: Volker Reichelt +// { dg-options "-fpermissive -w" } + struct A { typedef int X; }; int i = typename A::X(); diff --git a/gcc/testsuite/g++.dg/parse/typename9.C b/gcc/testsuite/g++.dg/parse/typename9.C new file mode 100644 index 000000000000..aa72cd6c5849 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/typename9.C @@ -0,0 +1,3 @@ +struct A { typedef int X; }; + +int i = typename A::X(); // { dg-error "typename" } -- 2.43.5