diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a8ab21e2eb9..8ae530e9949 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -7,6 +7,17 @@ static. (TTARGET_ASM_OUTPUT_ADDR_CONST_EXTRA): Define. +2010-09-21 Nicola Pero + + 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 PR objc/25965 diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index ae31b7cf55f..de72c192edf 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -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); diff --git a/gcc/c-family/stub-objc.c b/gcc/c-family/stub-objc.c index 3cb45d0734a..0ce1feffb41 100644 --- a/gcc/c-family/stub-objc.c +++ b/gcc/c-family/stub-objc.c @@ -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 diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 666f4188f98..b1e6eb2ee08 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -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. diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 87dcec853bf..8d5490e5282 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,10 @@ +2010-09-21 Nicola Pero + + 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 PR objc/25965 diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 57942380934..55e50f411f8 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a1d8eb03cd0..101d68470e2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -9,6 +9,11 @@ arguments checks. Update temporary counts. * gfortran.dg/transpose_optimization_1.f90: New. +2010-09-21 Nicola Pero + + PR objc/23710 + * objc.dg/invalid-method-1.m: New. + 2010-09-21 Nicola Pero Merge from 'apple/trunk' branch on FSF servers. diff --git a/gcc/testsuite/objc.dg/invalid-method-1.m b/gcc/testsuite/objc.dg/invalid-method-1.m new file mode 100644 index 00000000000..78eae2c5815 --- /dev/null +++ b/gcc/testsuite/objc.dg/invalid-method-1.m @@ -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" } */