From: Manuel López-Ibáñez Date: Fri, 10 Apr 2009 12:47:58 +0000 (+0000) Subject: 2009-04-10 Manuel López-Ibáñez X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0d24670707462cb06ac0037607ef9df9e733dc44;p=platform%2Fupstream%2Fgcc.git 2009-04-10 Manuel López-Ibáñez PR c++/20118 cp/ * parser.c (cp_parser_check_template_parameters): Take a cp_declarator parameter. (cp_parser_elaborated_type_specifier): Update to cp_parser_check_template_parameters. (cp_parser_class_head): Likewise. (cp_parser_check_declarator_template_parameters): Likewise. (cp_parser_check_template_parameters): Handle first the non-error conditions. Give more accurate diagnostics if a declarator is given. testsuite/ * g++.dg/parse/pr20118.C: New. * g++.dg/template/spec16.C: Update. From-SVN: r145892 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b11e004..847b485 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2009-04-10 Manuel López-Ibáñez + + PR c++/20118 + * parser.c (cp_parser_check_template_parameters): Take a + cp_declarator parameter. + (cp_parser_elaborated_type_specifier): Update to + cp_parser_check_template_parameters. + (cp_parser_class_head): Likewise. + (cp_parser_check_declarator_template_parameters): Likewise. + (cp_parser_check_template_parameters): Handle first the non-error + conditions. Give more accurate diagnostics if a declarator is + given. + 2009-04-08 Jason Merrill PR c++/25185 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 18d62cc..68c0ef4 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1913,7 +1913,7 @@ static tree cp_parser_maybe_treat_template_as_class static bool cp_parser_check_declarator_template_parameters (cp_parser *, cp_declarator *, location_t); static bool cp_parser_check_template_parameters - (cp_parser *, unsigned, location_t); + (cp_parser *, unsigned, location_t, cp_declarator *); static tree cp_parser_simple_cast_expression (cp_parser *); static tree cp_parser_global_scope_opt @@ -11765,7 +11765,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, there were no qualifying templates. */ if (!cp_parser_check_template_parameters (parser, /*num_templates=*/0, - token->location)) + token->location, + /*declarator=*/NULL)) return error_mark_node; type = xref_tag (tag_type, identifier, ts, template_p); } @@ -15402,7 +15403,8 @@ cp_parser_class_head (cp_parser* parser, /* Make sure that the right number of template parameters were present. */ if (!cp_parser_check_template_parameters (parser, num_templates, - type_start_token->location)) + type_start_token->location, + /*declarator=*/NULL)) { /* If something went wrong, there is no point in even trying to process the class-definition. */ @@ -17311,9 +17313,9 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, additional level of template parameters. */ ++num_templates; - return cp_parser_check_template_parameters (parser, - num_templates, - declarator_location); + return cp_parser_check_template_parameters + (parser, num_templates, declarator_location, declarator); + case cdk_function: case cdk_array: @@ -17334,30 +17336,38 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, /* NUM_TEMPLATES were used in the current declaration. If that is invalid, return FALSE and issue an error messages. Otherwise, - return TRUE. */ + return TRUE. If DECLARATOR is non-NULL, then we are checking a + declarator and we can print more accurate diagnostics. */ static bool cp_parser_check_template_parameters (cp_parser* parser, unsigned num_templates, - location_t location) + location_t location, + cp_declarator *declarator) { + /* If there are the same number of template classes and parameter + lists, that's OK. */ + if (parser->num_template_parameter_lists == num_templates) + return true; + /* If there are more, but only one more, then we are referring to a + member template. That's OK too. */ + if (parser->num_template_parameter_lists == num_templates + 1) + return true; /* If there are more template classes than parameter lists, we have something like: template void S::R::f (); */ if (parser->num_template_parameter_lists < num_templates) { - error ("%Htoo few template-parameter-lists", &location); + if (declarator) + error_at (location, "specializing member %<%T::%E%> " + "requires %%> syntax", + declarator->u.id.qualifying_scope, + declarator->u.id.unqualified_name); + else + error_at (location, "too few template-parameter-lists"); return false; } - /* If there are the same number of template classes and parameter - lists, that's OK. */ - if (parser->num_template_parameter_lists == num_templates) - return true; - /* If there are more, but only one more, then we are referring to a - member template. That's OK too. */ - if (parser->num_template_parameter_lists == num_templates + 1) - return true; /* Otherwise, there are too many template parameter lists. We have something like: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fdee1fa..d83fb5e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-04-10 Manuel López-Ibáñez + + PR c++/20118 + * g++.dg/parse/pr20118.C: New. + * g++.dg/template/spec16.C: Update. + 2009-04-09 H.J. Lu PR testsuite/35621 @@ -678,7 +684,7 @@ * gfortran.dg/typebound_proc_11.f03: New test. * gfortran.dg/abstract_type_5.f03: New test. -2008-03-29 Tobias Schlüter +2008-03-29 Tobias Schlüter PR fortran/38507 * gfortran.dg/do_4.f: New. diff --git a/gcc/testsuite/g++.dg/parse/pr20118.C b/gcc/testsuite/g++.dg/parse/pr20118.C new file mode 100644 index 0000000..94e000a --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr20118.C @@ -0,0 +1,9 @@ +// { dg-do compile } +// { dg-options "-fshow-column" } +templatestruct foo { + static const int i; }; + +const int foo::i = 5; // { dg-error "11:specializing member .foo::i. requires .template<>. syntax" } + +int main() { return 0; } + diff --git a/gcc/testsuite/g++.dg/template/spec16.C b/gcc/testsuite/g++.dg/template/spec16.C index 881d7a0..c872052 100644 --- a/gcc/testsuite/g++.dg/template/spec16.C +++ b/gcc/testsuite/g++.dg/template/spec16.C @@ -7,5 +7,5 @@ struct A { template void B () ; }; -void A<0>::B<0>() { // { dg-error "parameter-lists" } +void A<0>::B<0>() { // { dg-error "specializing member 'A<0>::B<0>' requires 'template<>' syntax" } }