This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR c++/10926, c++/11116


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 "" }
+ };


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]