re PR objc/23710 (objc front-end should not "abort" after erroring out about method...
authorNicola Pero <nicola.pero@meta-innovation.com>
Tue, 21 Sep 2010 20:47:04 +0000 (20:47 +0000)
committerNicola Pero <nicola@gcc.gnu.org>
Tue, 21 Sep 2010 20:47:04 +0000 (20:47 +0000)
PR objc/23710
In gcc/:
        * c-family/c-common.h (objc_start_method_definition): Return bool
        instead of void.
        * c-family/stub-objc.c (objc_start_method_definition): Return bool
        instead of void.
        * c-parser.c (c_parser_objc_method_definition): Check the return
        value of objc_start_method_definition and if false is returned,
        parse the method definition but emit no code.
In gcc/objc/:
        * objc-act.c (objc_start_method_definition): Do not abort upon a
        'method definition not in @implementation context' error.  Return
        'false' instead.
In gcc/testsuite/:
       * objc.dg/invalid-method-1.m: New.

From-SVN: r164497

gcc/ChangeLog
gcc/c-family/c-common.h
gcc/c-family/stub-objc.c
gcc/c-parser.c
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/objc.dg/invalid-method-1.m [new file with mode: 0644]

index a8ab21e..8ae530e 100644 (file)
@@ -9,6 +9,17 @@
 
 2010-09-21  Nicola Pero  <nicola.pero@meta-innovation.com>
 
+       PR objc/23710
+       * c-family/c-common.h (objc_start_method_definition): Return bool
+       instead of void.
+       * c-family/stub-objc.c (objc_start_method_definition): Return bool
+       instead of void.
+       * c-parser.c (c_parser_objc_method_definition): Check the return
+       value of objc_start_method_definition and if false is returned,
+       parse the method definition but emit no code.
+       
+2010-09-21  Nicola Pero  <nicola.pero@meta-innovation.com>
+
        PR objc/25965
        * c-decl.c (detect_field_duplicates): If compiling Objective-C,
        call objc_get_interface_ivars ().
index ae31b7c..de72c19 100644 (file)
@@ -976,7 +976,7 @@ extern void objc_set_visibility (int);
 extern void objc_set_method_type (enum tree_code);
 extern tree objc_build_method_signature (tree, tree, tree, bool);
 extern void objc_add_method_declaration (tree);
-extern void objc_start_method_definition (tree);
+extern bool objc_start_method_definition (tree);
 extern void objc_finish_method_definition (tree);
 extern void objc_add_instance_variable (tree);
 extern tree objc_build_keyword_decl (tree, tree, tree);
index 3cb45d0..0ce1fef 100644 (file)
@@ -184,9 +184,10 @@ objc_add_method_declaration (tree ARG_UNUSED (signature))
 {
 }
 
-void
+bool
 objc_start_method_definition (tree ARG_UNUSED (signature))
 {
+  return true;
 }
 
 void
index 666f418..b1e6eb2 100644 (file)
@@ -6597,9 +6597,19 @@ c_parser_objc_method_definition (c_parser *parser)
       return;
     }
   parser->objc_pq_context = false;
-  objc_start_method_definition (decl);
-  add_stmt (c_parser_compound_statement (parser));
-  objc_finish_method_definition (current_function_decl);
+  if (objc_start_method_definition (decl))
+    {
+      add_stmt (c_parser_compound_statement (parser));
+      objc_finish_method_definition (current_function_decl);
+    }
+  else
+    {
+      /* This code is executed when we find a method definition
+        outside of an @implementation context.  Parse the method (to
+        keep going) but do not emit any code.
+      */
+      c_parser_compound_statement (parser);
+    }
 }
 
 /* Parse an objc-methodprotolist.
index 87dcec8..8d5490e 100644 (file)
@@ -1,5 +1,12 @@
 2010-09-21  Nicola Pero  <nicola.pero@meta-innovation.com>
 
+       PR objc/23710
+       * objc-act.c (objc_start_method_definition): Do not abort upon a
+       'method definition not in @implementation context' error.  Return
+       'false' instead.
+
+2010-09-21  Nicola Pero  <nicola.pero@meta-innovation.com>
+
        PR objc/25965
        * objc-act.c (objc_get_interface_ivars): New function.
        (objc_collecting_ivars): New variable.
index 5794238..55e50f4 100644 (file)
@@ -777,18 +777,30 @@ void
 objc_add_method_declaration (tree decl)
 {
   if (!objc_interface_context)
-    fatal_error ("method declaration not in @interface context");
+    {
+      /* PS: At the moment, due to how the parser works, it should be
+        impossible to get here.  But it's good to have the check in
+        case the parser changes.
+      */
+      fatal_error ("method declaration not in @interface context");
+    }
 
   objc_add_method (objc_interface_context,
                   decl,
                   objc_inherit_code == CLASS_METHOD_DECL);
 }
 
-void
+/* Return 'true' if the method definition could be started, and
+   'false' if not (because we are outside an @implementation context).
+*/
+bool
 objc_start_method_definition (tree decl)
 {
   if (!objc_implementation_context)
-    fatal_error ("method definition not in @implementation context");
+    {
+      error ("method definition not in @implementation context");
+      return false;
+    }
 
 #ifndef OBJCPLUS
   /* Indicate no valid break/continue context by setting these variables
@@ -801,6 +813,7 @@ objc_start_method_definition (tree decl)
                   decl,
                   objc_inherit_code == CLASS_METHOD_DECL);
   start_method_def (decl);
+  return true;
 }
 
 void
index a1d8eb0..101d684 100644 (file)
 
 2010-09-21  Nicola Pero  <nicola.pero@meta-innovation.com>
 
+       PR objc/23710
+       * objc.dg/invalid-method-1.m: New.
+
+2010-09-21  Nicola Pero  <nicola.pero@meta-innovation.com>
+
        Merge from 'apple/trunk' branch on FSF servers.
 
        2005-10-11  Fariborz Jahanian <fjahanian@apple.com>
diff --git a/gcc/testsuite/objc.dg/invalid-method-1.m b/gcc/testsuite/objc.dg/invalid-method-1.m
new file mode 100644 (file)
index 0000000..78eae2c
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* Test that we keep compiling if a method definition is found outside
+   of an @implementation context.
+*/
+
++ (void)C { } /* { dg-error "method definition not in @implementation context" } */
+
+/* We have another error here to test that the compiler is still going and
+   finding errors in the rest of the code.
+*/
+@compatibility_alias class1 class2; /* { dg-warning "annot find class" } */