aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-12-16 02:46:31 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-12-16 02:46:31 +0000
commit89f1a6eccc670a5d41d7aa2e8bdbe5793d662eda (patch)
tree666879933d74c747ef939964a372c4a7812082cf
parent040fc928031ee65c0eeed2ed20e024179d02d9cf (diff)
downloadgcc-89f1a6eccc670a5d41d7aa2e8bdbe5793d662eda.zip
gcc-89f1a6eccc670a5d41d7aa2e8bdbe5793d662eda.tar.gz
gcc-89f1a6eccc670a5d41d7aa2e8bdbe5793d662eda.tar.bz2
re PR c++/10926 (ICE in build_delete when trying to declare template destructor)
PR c++/10926 * decl2.c (grokfield): Robustify. PR c++/11116 * parser.c (cp_parser_throw_expression): Determine whether or not an assignment-expression is present by doing one-token lookahead. PR c++/10926 * g++.dg/template/error9.C: New test. PR c++/11116 * g++.dg/template/error8.C: New test. From-SVN: r74664
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl2.c10
-rw-r--r--gcc/cp/parser.c18
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/template/error8.C7
-rw-r--r--gcc/testsuite/g++.dg/template/error9.C7
6 files changed, 47 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d00f67c..2c4b052 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,12 @@
2003-12-15 Mark Mitchell <mark@codesourcery.com>
+ PR c++/10926
+ * decl2.c (grokfield): Robustify.
+
+ PR c++/11116
+ * parser.c (cp_parser_throw_expression): Determine whether or not
+ an assignment-expression is present by doing one-token lookahead.
+
PR c++/13269
* parser.c (cp_parser_function_definition_after_declarator): Stop
scanning tokens when reaching EOF.
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 14814b5..b9034a1 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -882,10 +882,8 @@ grokfield (tree declarator, tree declspecs, tree init, tree asmspec_tree,
init = NULL_TREE;
value = grokdeclarator (declarator, declspecs, FIELD, init != 0, &attrlist);
- if (! value || value == error_mark_node)
+ if (! value || error_operand_p (value))
/* friend or constructor went bad. */
- return value;
- if (TREE_TYPE (value) == error_mark_node)
return error_mark_node;
if (TREE_CODE (value) == TYPE_DECL && init)
@@ -981,7 +979,11 @@ grokfield (tree declarator, tree declspecs, tree init, tree asmspec_tree,
if (processing_template_decl
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
- value = push_template_decl (value);
+ {
+ value = push_template_decl (value);
+ if (error_operand_p (value))
+ return error_mark_node;
+ }
if (attrlist)
cplus_decl_attributes (&value, attrlist, 0);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index fd25aa2..14923b1 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -12784,15 +12784,21 @@ static tree
cp_parser_throw_expression (cp_parser* parser)
{
tree expression;
+ cp_token* token;
cp_parser_require_keyword (parser, RID_THROW, "`throw'");
- /* We can't be sure if there is an assignment-expression or not. */
- cp_parser_parse_tentatively (parser);
- /* Try it. */
- expression = cp_parser_assignment_expression (parser);
- /* If it didn't work, this is just a rethrow. */
- if (!cp_parser_parse_definitely (parser))
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Figure out whether or not there is an assignment-expression
+ following the "throw" keyword. */
+ if (token->type == CPP_COMMA
+ || token->type == CPP_SEMICOLON
+ || token->type == CPP_CLOSE_PAREN
+ || token->type == CPP_CLOSE_SQUARE
+ || token->type == CPP_CLOSE_BRACE
+ || token->type == CPP_COLON)
expression = NULL_TREE;
+ else
+ expression = cp_parser_assignment_expression (parser);
return build_throw (expression);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 96c0ee8..b3e3e1a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2003-12-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10926
+ * g++.dg/template/error9.C: New test.
+
+ PR c++/11116
+ * g++.dg/template/error8.C: New test.
+
2003-12-15 Roger Sayle <roger@eyesopen.com>
PR middle-end/13400
diff --git a/gcc/testsuite/g++.dg/template/error8.C b/gcc/testsuite/g++.dg/template/error8.C
new file mode 100644
index 0000000..30872a2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/error8.C
@@ -0,0 +1,7 @@
+// PR c++/11116
+
+template <typename T> struct S {};
+
+void f() {
+ throw S (); // { dg-error "template" }
+}
diff --git a/gcc/testsuite/g++.dg/template/error9.C b/gcc/testsuite/g++.dg/template/error9.C
new file mode 100644
index 0000000..60f550a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/error9.C
@@ -0,0 +1,7 @@
+// PR c++/10926
+
+struct Foo
+{
+ template <int i>
+ ~Foo(); // { dg-error "" }
+};