2009-04-10 Manuel López-Ibáñez <manu@gcc.gnu.org>

	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
parent 62298c61
2009-04-10 Manuel López-Ibáñez <manu@gcc.gnu.org>
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 <jason@redhat.com> 2009-04-08 Jason Merrill <jason@redhat.com>
PR c++/25185 PR c++/25185
......
...@@ -1913,7 +1913,7 @@ static tree cp_parser_maybe_treat_template_as_class ...@@ -1913,7 +1913,7 @@ static tree cp_parser_maybe_treat_template_as_class
static bool cp_parser_check_declarator_template_parameters static bool cp_parser_check_declarator_template_parameters
(cp_parser *, cp_declarator *, location_t); (cp_parser *, cp_declarator *, location_t);
static bool cp_parser_check_template_parameters 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 static tree cp_parser_simple_cast_expression
(cp_parser *); (cp_parser *);
static tree cp_parser_global_scope_opt static tree cp_parser_global_scope_opt
...@@ -11765,7 +11765,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, ...@@ -11765,7 +11765,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
there were no qualifying templates. */ there were no qualifying templates. */
if (!cp_parser_check_template_parameters (parser, if (!cp_parser_check_template_parameters (parser,
/*num_templates=*/0, /*num_templates=*/0,
token->location)) token->location,
/*declarator=*/NULL))
return error_mark_node; return error_mark_node;
type = xref_tag (tag_type, identifier, ts, template_p); type = xref_tag (tag_type, identifier, ts, template_p);
} }
...@@ -15402,7 +15403,8 @@ cp_parser_class_head (cp_parser* parser, ...@@ -15402,7 +15403,8 @@ cp_parser_class_head (cp_parser* parser,
/* Make sure that the right number of template parameters were /* Make sure that the right number of template parameters were
present. */ present. */
if (!cp_parser_check_template_parameters (parser, num_templates, 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 /* If something went wrong, there is no point in even trying to
process the class-definition. */ process the class-definition. */
...@@ -17311,9 +17313,9 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, ...@@ -17311,9 +17313,9 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
additional level of template parameters. */ additional level of template parameters. */
++num_templates; ++num_templates;
return cp_parser_check_template_parameters (parser, return cp_parser_check_template_parameters
num_templates, (parser, num_templates, declarator_location, declarator);
declarator_location);
case cdk_function: case cdk_function:
case cdk_array: case cdk_array:
...@@ -17334,30 +17336,38 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, ...@@ -17334,30 +17336,38 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
/* NUM_TEMPLATES were used in the current declaration. If that is /* NUM_TEMPLATES were used in the current declaration. If that is
invalid, return FALSE and issue an error messages. Otherwise, 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 static bool
cp_parser_check_template_parameters (cp_parser* parser, cp_parser_check_template_parameters (cp_parser* parser,
unsigned num_templates, 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 /* If there are more template classes than parameter lists, we have
something like: something like:
template <class T> void S<T>::R<T>::f (); */ template <class T> void S<T>::R<T>::f (); */
if (parser->num_template_parameter_lists < num_templates) 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 %<template<>%> syntax",
declarator->u.id.qualifying_scope,
declarator->u.id.unqualified_name);
else
error_at (location, "too few template-parameter-lists");
return false; 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 /* Otherwise, there are too many template parameter lists. We have
something like: something like:
......
2009-04-10 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c++/20118
* g++.dg/parse/pr20118.C: New.
* g++.dg/template/spec16.C: Update.
2009-04-09 H.J. Lu <hongjiu.lu@intel.com> 2009-04-09 H.J. Lu <hongjiu.lu@intel.com>
PR testsuite/35621 PR testsuite/35621
...@@ -678,7 +684,7 @@ ...@@ -678,7 +684,7 @@
* gfortran.dg/typebound_proc_11.f03: New test. * gfortran.dg/typebound_proc_11.f03: New test.
* gfortran.dg/abstract_type_5.f03: New test. * gfortran.dg/abstract_type_5.f03: New test.
2008-03-29 Tobias Schlter <tobi@gcc.gnu.org> 2008-03-29 Tobias Schlüter <tobi@gcc.gnu.org>
PR fortran/38507 PR fortran/38507
* gfortran.dg/do_4.f: New. * gfortran.dg/do_4.f: New.
......
// { dg-do compile }
// { dg-options "-fshow-column" }
template<typename t>struct foo {
static const int i; };
const int foo<bool>::i = 5; // { dg-error "11:specializing member .foo<bool>::i. requires .template<>. syntax" }
int main() { return 0; }
...@@ -7,5 +7,5 @@ struct A { ...@@ -7,5 +7,5 @@ struct A {
template<int M> void B () ; template<int M> 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" }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment