diff options
author | Volker Reichelt <reichelt@igpm.rwth-aachen.de> | 2006-09-08 22:56:44 +0000 |
---|---|---|
committer | Volker Reichelt <reichelt@gcc.gnu.org> | 2006-09-08 22:56:44 +0000 |
commit | a7b9d08c3563ec731b3213c279a25e66be384d0b (patch) | |
tree | 7f8c829898d90a21a450edc8b19bfc0094314329 | |
parent | 38371be9886507f8bf82fe2fb0a56803efd4ea79 (diff) | |
download | gcc-a7b9d08c3563ec731b3213c279a25e66be384d0b.zip gcc-a7b9d08c3563ec731b3213c279a25e66be384d0b.tar.gz gcc-a7b9d08c3563ec731b3213c279a25e66be384d0b.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/parser.c | 61 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/def-tmpl-arg1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/template20.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/operator8.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/crash65.C | 4 |
7 files changed, 62 insertions, 36 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a914e2a..6e20eb1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 41726f3..af4f312 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2ec550f..eb350af 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/g++.dg/parse/def-tmpl-arg1.C b/gcc/testsuite/g++.dg/parse/def-tmpl-arg1.C index fd85b97..6c3659f 100644 --- a/gcc/testsuite/g++.dg/parse/def-tmpl-arg1.C +++ b/gcc/testsuite/g++.dg/parse/def-tmpl-arg1.C @@ -6,4 +6,4 @@ template <typename X, typename Y = B<X> > struct A // { dg-error "" } { A(); A(const A&); -}; // { dg-error "" } +}; diff --git a/gcc/testsuite/g++.dg/parse/template20.C b/gcc/testsuite/g++.dg/parse/template20.C new file mode 100644 index 0000000..2705f46 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/template20.C @@ -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 "" } diff --git a/gcc/testsuite/g++.dg/template/operator8.C b/gcc/testsuite/g++.dg/template/operator8.C index a7f9856..29d17b8 100644 --- a/gcc/testsuite/g++.dg/template/operator8.C +++ b/gcc/testsuite/g++.dg/template/operator8.C @@ -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" } -}; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash65.C b/gcc/testsuite/g++.old-deja/g++.pt/crash65.C index 98fbec6..a7df70c 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/crash65.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash65.C @@ -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" } |