2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-03-25 10:40:56 +08:00

re PR c++/28858 (Algorithm to find the end of a template parameter list is flawed)

PR c++/28858
	* parser.c (cp_parser_skip_until_found): Rename to
	cp_parser_skip_to_end_of_template_parameter_list.  Remove last two
	parameters.  Track levels of '< ... >'.  Stop at '{', '}', or ';'.
	Reorganize.  Adjust comment.
	(cp_parser_template_declaration_after_export): Adjust call.
	(cp_parser_enclosed_template_argument_list): Likewise.

	* g++.dg/parse/template20.C: New test.
	* g++.dg/template/operator8.C: Remove obsolete part.
	* g++.dg/parse/def-tmpl-arg1.C: Adjust error-markers.
	* g++.old-deja/g++.pt/crash65.C: Likewise.

From-SVN: r116788
This commit is contained in:
Volker Reichelt 2006-09-08 22:56:44 +00:00 committed by Volker Reichelt
parent 38371be988
commit a7b9d08c35
7 changed files with 62 additions and 36 deletions
gcc
cp
testsuite
ChangeLog
g++.dg
g++.old-deja/g++.pt

@ -1,3 +1,13 @@
2006-09-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/28858
* parser.c (cp_parser_skip_until_found): Rename to
cp_parser_skip_to_end_of_template_parameter_list. Remove last two
parameters. Track levels of '< ... >'. Stop at '{', '}', or ';'.
Reorganize. Adjust comment.
(cp_parser_template_declaration_after_export): Adjust call.
(cp_parser_enclosed_template_argument_list): Likewise.
2006-09-07 Andrew Pinski <pinskia@physics.uc.edu>
PR C++/28906

@ -1819,8 +1819,8 @@ static void cp_parser_skip_to_end_of_block_or_statement
(cp_parser *);
static void cp_parser_skip_to_closing_brace
(cp_parser *);
static void cp_parser_skip_until_found
(cp_parser *, enum cpp_ttype, const char *);
static void cp_parser_skip_to_end_of_template_parameter_list
(cp_parser *);
static void cp_parser_skip_to_pragma_eol
(cp_parser*, cp_token *);
static bool cp_parser_error_occurred
@ -15495,7 +15495,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
checks = get_deferred_access_checks ();
/* Look for the `>'. */
cp_parser_skip_until_found (parser, CPP_GREATER, "`>'");
cp_parser_skip_to_end_of_template_parameter_list (parser);
/* We just processed one more parameter list. */
++parser->num_template_parameter_lists;
/* If the next token is `template', there are more template
@ -15838,7 +15838,7 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
}
}
else
cp_parser_skip_until_found (parser, CPP_GREATER, "`>'");
cp_parser_skip_to_end_of_template_parameter_list (parser);
/* The `>' token might be a greater-than operator again now. */
parser->greater_than_is_operator_p
= saved_greater_than_is_operator_p;
@ -16266,54 +16266,61 @@ cp_parser_require (cp_parser* parser,
}
}
/* Like cp_parser_require, except that tokens will be skipped until
the desired token is found. An error message is still produced if
the next token is not as expected. */
/* An error message is produced if the next token is not '>'.
All further tokens are skipped until the desired token is
found or '{', '}', ';' or an unbalanced ')' or ']'. */
static void
cp_parser_skip_until_found (cp_parser* parser,
enum cpp_ttype type,
const char* token_desc)
cp_parser_skip_to_end_of_template_parameter_list (cp_parser* parser)
{
cp_token *token;
/* Current level of '< ... >'. */
unsigned level = 0;
/* Ignore '<' and '>' nested inside '( ... )' or '[ ... ]'. */
unsigned nesting_depth = 0;
if (cp_parser_require (parser, type, token_desc))
/* Are we ready, yet? If not, issue error message. */
if (cp_parser_require (parser, CPP_GREATER, "%<>%>"))
return;
/* Skip tokens until the desired token is found. */
while (true)
{
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
/* If we've reached the token we want, consume it and stop. */
if (token->type == type && !nesting_depth)
switch (cp_lexer_peek_token (parser->lexer)->type)
{
cp_lexer_consume_token (parser->lexer);
return;
}
case CPP_LESS:
if (!nesting_depth)
++level;
break;
switch (token->type)
{
case CPP_EOF:
case CPP_PRAGMA_EOL:
/* If we've run out of tokens, stop. */
return;
case CPP_GREATER:
if (!nesting_depth && level-- == 0)
{
/* We've reached the token we want, consume it and stop. */
cp_lexer_consume_token (parser->lexer);
return;
}
break;
case CPP_OPEN_BRACE:
case CPP_OPEN_PAREN:
case CPP_OPEN_SQUARE:
++nesting_depth;
break;
case CPP_CLOSE_BRACE:
case CPP_CLOSE_PAREN:
case CPP_CLOSE_SQUARE:
if (nesting_depth-- == 0)
return;
break;
case CPP_EOF:
case CPP_PRAGMA_EOL:
case CPP_SEMICOLON:
case CPP_OPEN_BRACE:
case CPP_CLOSE_BRACE:
/* The '>' was probably forgotten, don't look further. */
return;
default:
break;
}

@ -1,3 +1,11 @@
2006-09-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/28858
* g++.dg/parse/template20.C: New test.
* g++.dg/template/operator8.C: Remove obsolete part.
* g++.dg/parse/def-tmpl-arg1.C: Adjust error-markers.
* g++.old-deja/g++.pt/crash65.C: Likewise.
2006-09-07 Andrew Pinski <pinskia@physics.uc.edu>
PR C++/28906

@ -6,4 +6,4 @@ template <typename X, typename Y = B<X> > struct A // { dg-error "" }
{
A();
A(const A&);
}; // { dg-error "" }
};

@ -0,0 +1,7 @@
// PR c++/28858
// { dg-do compile }
template<int N struct A; // { dg-error "before" }
bool i = 1 > 0; // { dg-bogus "" }
int j = i; // { dg-bogus "" }

@ -4,9 +4,3 @@ struct A
{
template<operator+> void foo() {} // { dg-error "identifier|non-function|template arguments" }
};
struct B
{
template<operator> void foo() {} // { dg-error "identifier|non-function|'void'" }
template<int> void bar() {} // { dg-error "template arguments" }
};

@ -8,5 +8,5 @@
template<class T =
struct W {}; // { dg-error "" } inside template parms
> struct S{};
struct W {}; // { dg-error "inside template parameter list|before" }
> struct S{}; // { dg-error "before" }