re PR c++/10926 (ICE in build_delete when trying to declare template destructor)
authorMark Mitchell <mark@codesourcery.com>
Tue, 16 Dec 2003 02:46:31 +0000 (02:46 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 16 Dec 2003 02:46:31 +0000 (02:46 +0000)
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

gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/error8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/error9.C [new file with mode: 0644]

index d00f67cc5ec183f4b01d90eea42e88d96c4cdf31..2c4b0526f4955ff13026dc64fea24c4f1989245f 100644 (file)
@@ -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.
index 14814b532dd561e5540655e0382661e4a83ac0eb..b9034a1f1c0ba97c9d053a6bae0a54090c0034cb 100644 (file)
@@ -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);
index fd25aa2a7a942f7fd5363c62f55197f79f11978f..14923b17ce4e72e6f45ff4a44945da1994d6bc63 100644 (file)
@@ -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);
 }
index 96c0ee8a93ecc3f1fbea7c46a80be2e9b212bcbe..b3e3e1aa845d7dd19bfde89ab60d91f3512af876 100644 (file)
@@ -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 (file)
index 0000000..30872a2
--- /dev/null
@@ -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 (file)
index 0000000..60f550a
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/10926
+
+struct Foo
+{
+    template <int i>
+    ~Foo(); // { dg-error "" }
+};