This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR c++/10926, c++/11116
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 15 Dec 2003 18:41:00 -0800
- Subject: C++ PATCH: PR c++/10926, c++/11116
- Reply-to: mark at codesourcery dot com
These patches fix PR 10926 and PR 11116. The first was an
error-recovery problem; push_template_decl can return error_mark_node,
and we should propagate that. The second was a case where the new
parser was using backtracking unnecessarily; by avoiding that we
automatically get a better error message.
Tested on i686-pc-linux-gnu, applied on the mainline.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
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.
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.
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.688
diff -c -5 -p -r1.688 decl2.c
*** cp/decl2.c 15 Dec 2003 14:19:01 -0000 1.688
--- cp/decl2.c 16 Dec 2003 02:39:11 -0000
*************** grokfield (tree declarator, tree declspe
*** 880,893 ****
&& TREE_VALUE (init) == error_mark_node
&& TREE_CHAIN (init) == NULL_TREE)
init = NULL_TREE;
value = grokdeclarator (declarator, declspecs, FIELD, init != 0, &attrlist);
! if (! value || value == error_mark_node)
/* 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)
{
error ("typedef `%D' is initialized (use __typeof__ instead)", value);
--- 880,891 ----
&& TREE_VALUE (init) == error_mark_node
&& TREE_CHAIN (init) == NULL_TREE)
init = NULL_TREE;
value = grokdeclarator (declarator, declspecs, FIELD, init != 0, &attrlist);
! if (! value || error_operand_p (value))
/* friend or constructor went bad. */
return error_mark_node;
if (TREE_CODE (value) == TYPE_DECL && init)
{
error ("typedef `%D' is initialized (use __typeof__ instead)", value);
*************** grokfield (tree declarator, tree declspe
*** 979,989 ****
}
}
if (processing_template_decl
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
! value = push_template_decl (value);
if (attrlist)
cplus_decl_attributes (&value, attrlist, 0);
if (TREE_CODE (value) == VAR_DECL)
--- 977,991 ----
}
}
if (processing_template_decl
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
! {
! value = push_template_decl (value);
! if (error_operand_p (value))
! return error_mark_node;
! }
if (attrlist)
cplus_decl_attributes (&value, attrlist, 0);
if (TREE_CODE (value) == VAR_DECL)
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.132
diff -c -5 -p -r1.132 parser.c
*** cp/parser.c 15 Dec 2003 16:59:46 -0000 1.132
--- cp/parser.c 16 Dec 2003 02:39:12 -0000
*************** cp_parser_exception_declaration (cp_pars
*** 12782,12800 ****
static tree
cp_parser_throw_expression (cp_parser* parser)
{
tree expression;
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))
expression = NULL_TREE;
return build_throw (expression);
}
/* GNU Extensions */
--- 12782,12806 ----
static tree
cp_parser_throw_expression (cp_parser* parser)
{
tree expression;
+ cp_token* token;
cp_parser_require_keyword (parser, RID_THROW, "`throw'");
! 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);
}
/* GNU Extensions */
Index: testsuite/g++.dg/template/error8.C
===================================================================
RCS file: testsuite/g++.dg/template/error8.C
diff -N testsuite/g++.dg/template/error8.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/error8.C 16 Dec 2003 02:39:13 -0000
***************
*** 0 ****
--- 1,7 ----
+ // PR c++/11116
+
+ template <typename T> struct S {};
+
+ void f() {
+ throw S (); // { dg-error "template" }
+ }
Index: testsuite/g++.dg/template/error9.C
===================================================================
RCS file: testsuite/g++.dg/template/error9.C
diff -N testsuite/g++.dg/template/error9.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/error9.C 16 Dec 2003 02:40:25 -0000
***************
*** 0 ****
--- 1,7 ----
+ // PR c++/10926
+
+ struct Foo
+ {
+ template <int i>
+ ~Foo(); // { dg-error "" }
+ };