aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Reichelt <reichelt@igpm.rwth-aachen.de>2006-09-08 22:56:44 +0000
committerVolker Reichelt <reichelt@gcc.gnu.org>2006-09-08 22:56:44 +0000
commita7b9d08c3563ec731b3213c279a25e66be384d0b (patch)
tree7f8c829898d90a21a450edc8b19bfc0094314329
parent38371be9886507f8bf82fe2fb0a56803efd4ea79 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/cp/parser.c61
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/parse/def-tmpl-arg1.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/template20.C7
-rw-r--r--gcc/testsuite/g++.dg/template/operator8.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash65.C4
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" }