Patchwork ObjC/ObjC++: fixes for parsing of @throw

login
register
mail settings
Submitter Nicola Pero
Date Dec. 1, 2010, 1:01 a.m.
Message ID <1291165285.037120602@192.168.2.229>
Download mbox | patch
Permalink /patch/73691/
State New
Headers show

Comments

Nicola Pero - Dec. 1, 2010, 1:01 a.m.
This small patch fixes a couple of small bugs in the Objective-C++ parser.

I reviewed the parsing of @throw in Objective-C and Objective-C++ and looked
at testcases from other compilers.  It all looks good in our compiler with the 
exception of a couple of very minor issues that this patch fixes.

The main one is that upon finding

 @throw;

outside of a @catch block, the Objective-C++ compiler would not recovery properly
from the error, and would cause spurious errors on the next statement.  I fixed that.

The second one is that the Objective-C compiler allowed

 @throw object1, object2;

while the Objective-C++ didn't.  I allowed it for the Objective-C++ compiler as well
(clang allows it both for ObjC and ObjC++).

A testcase for ObjC and one for ObjC++ are included.

Ok to commit ?

Thanks
Mike Stump - Dec. 1, 2010, 10:24 p.m.
On Nov 30, 2010, at 5:01 PM, Nicola Pero wrote:
> I reviewed the parsing of @throw in Objective-C and Objective-C++ and looked
> at testcases from other compilers.  It all looks good in our compiler with the 
> exception of a couple of very minor issues that this patch fixes.

> Ok to commit ?

Ok.

Patch

Index: gcc/objc/objc-act.c
===================================================================
--- gcc/objc/objc-act.c (revision 167318)
+++ gcc/objc/objc-act.c (working copy)
@@ -5520,7 +5520,7 @@  objc_build_throw_stmt (location_t loc, tree throw_
           || cur_try_context->current_catch == NULL)
        {
          error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
-         return NULL_TREE;
+         return error_mark_node;
        }
 
       /* Otherwise the object is still sitting in the EXC_PTR_EXPR
Index: gcc/objc/ChangeLog
===================================================================
--- gcc/objc/ChangeLog  (revision 167318)
+++ gcc/objc/ChangeLog  (working copy)
@@ -1,3 +1,8 @@ 
+2010-12-01  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc-act.c (objc_build_throw_stmt): Return error_mark_node and
+       not NULL_TREE when a @throw is used outside of a @catch block.
+
 2010-11-30  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * objc-act.c (objc_build_volatilized_type): Removed.
Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog     (revision 167318)
+++ gcc/testsuite/ChangeLog     (working copy)
@@ -1,3 +1,8 @@ 
+2010-12-01  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc.dg/exceptions-6.m: New.
+       * obj-c++.dg/exceptions-6.mm: New.      
+       
 2010-11-30  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * gcc.target/powerpc/ppc-fma-7.c: New file, test that (a*b)+c and
Index: gcc/testsuite/objc.dg/exceptions-6.m
===================================================================
--- gcc/testsuite/objc.dg/exceptions-6.m        (revision 0)
+++ gcc/testsuite/objc.dg/exceptions-6.m        (revision 0)
@@ -0,0 +1,29 @@ 
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010.  */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* Test warnings when parsing syntax errors in @throw.  */
+
+#include <objc/objc.h>
+
+void test (id object)
+{
+  @throw object;   /* Ok */
+  @throw;          /* { dg-error ".@throw. .rethrow. used outside of a @catch block" } */
+  @throw (object); /* Ok.  */
+  @throw (id)0
+}                  /* { dg-error "expected" } */
+
+void test2 (id object)
+{
+  @throw object);  /* { dg-error "expected" } */
+  @throw (...);    /* { dg-error "expected" } */
+  @throw ();       /* { dg-error "expected" } */
+  @throw           
+}                  /* { dg-error "expected" } */
+
+void test3 (id object1, id object2)
+{
+  /* This is apparently valid.  */
+  @throw object1, object2; /* Ok.  */
+}
Index: gcc/testsuite/obj-c++.dg/exceptions-6.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/exceptions-6.mm    (revision 0)
+++ gcc/testsuite/obj-c++.dg/exceptions-6.mm    (revision 0)
@@ -0,0 +1,29 @@ 
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010.  */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile } */
+
+/* Test warnings when parsing syntax errors in @throw.  */
+
+#include <objc/objc.h>
+
+void test (id object)
+{
+  @throw object;   /* Ok */
+  @throw;          /* { dg-error ".@throw. .rethrow. used outside of a @catch block" } */
+  @throw (object); /* Ok.  */
+  @throw (id)0
+}                  /* { dg-error "expected" } */
+
+void test2 (id object)
+{
+  @throw object);  /* { dg-error "expected" } */
+  @throw (...);    /* { dg-error "expected" } */
+  @throw ();       /* { dg-error "expected" } */
+  @throw           
+}                  /* { dg-error "expected" } */
+
+void test3 (id object1, id object2)
+{
+  /* This is apparently valid.  */
+  @throw object1, object2; /* Ok.  */
+}
Index: gcc/cp/ChangeLog
===================================================================
--- gcc/cp/ChangeLog    (revision 167318)
+++ gcc/cp/ChangeLog    (working copy)
@@ -1,3 +1,9 @@ 
+2010-12-01  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * parser.c (cp_parser_objc_throw_statement): Use
+       cp_parser_expression, not cp_parser_assignment_expression, to
+       parse the argument of a @throw.
+
 2010-11-30  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * decl.c (finish_function): Call objc_finish_function when
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c     (revision 167318)
+++ gcc/cp/parser.c     (working copy)
@@ -22705,7 +22705,8 @@  cp_parser_objc_try_catch_finally_statement (cp_par
    Returns NULL_TREE.  */
 
 static tree
-cp_parser_objc_synchronized_statement (cp_parser *parser) {
+cp_parser_objc_synchronized_statement (cp_parser *parser)
+{
   location_t location;
   tree lock, stmt;
 
@@ -22732,14 +22733,15 @@  static tree
    Returns a constructed '@throw' statement.  */
 
 static tree
-cp_parser_objc_throw_statement (cp_parser *parser) {
+cp_parser_objc_throw_statement (cp_parser *parser)
+{
   tree expr = NULL_TREE;
   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
   cp_parser_require_keyword (parser, RID_AT_THROW, RT_AT_THROW);
 
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
-    expr = cp_parser_assignment_expression (parser, false, NULL);
+    expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
 
   cp_parser_consume_semicolon_at_end_of_statement (parser);
 
@@ -22749,7 +22751,8 @@  static tree
 /* Parse an Objective-C statement.  */
 
 static tree
-cp_parser_objc_statement (cp_parser * parser) {
+cp_parser_objc_statement (cp_parser * parser)
+{
   /* Try to figure out what kind of declaration is present.  */
   cp_token *kwd = cp_lexer_peek_token (parser->lexer);