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:
parent
38371be988
commit
a7b9d08c35
gcc
cp
testsuite
@ -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 "" }
|
||||
};
|
||||
|
7
gcc/testsuite/g++.dg/parse/template20.C
Normal file
7
gcc/testsuite/g++.dg/parse/template20.C
Normal file
@ -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" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user