c-common.c (flag_objc_sjlj_exceptions): New.

* c-common.c (flag_objc_sjlj_exceptions): New.
	* c-common.h (flag_objc_sjlj_exceptions): Declare.
	* c-opts.c (c_common_handle_option): Set it.
	(c_common_post_options): Handle interation of different
	objective-c exception and runtime switches.
	* c-decl.c (c_eh_initialized_p): New.
	(finish_decl): Use it instead of local eh_initialized_p.
	* c-parse.in (nested_function, notype_nested_function): Record
	the result of compstmt.
	(compstmt_or_error): Likewise.
	(compstmt): Don't add_stmt the result.
	(stmt): Don't return anything.  Rewrite objc try and sync rules.
	(objc_try_stmt, objc_catch_list): Remove.
	(objc_catch_block, objc_finally_block): Remove.
	(objc_catch_prefix, objc_catch_clause, objc_opt_catch_list): New.
	(objc_try_catch_clause, objc_finally_clause): New.
	(objc_try_catch_stmt): Rewrite.
	* c-tree.h (c_eh_initialized_p): Declare.
	* c-opt (fobjc-sjlj-exceptions): New.
	* except.c (output_function_exception_table): Don't call cgraph
	on non-decls.
	* objc/objc-act.c (UTAG_EXCDATA_VAR, UTAG_CAUGHTEXC_VAR,
	UTAG_RETHROWEXC_VAR, UTAG_EVALONCE_VAR, struct val_stack,
	catch_count_stack, exc_binding_stack, if_nesting_count,
	blk_nesting_count, objc_enter_block, objc_exit_block,
	objc_declare_variable, val_stack_push, val_stack_pop,
	objc_build_try_enter_fragment, objc_build_extract_expr,
	objc_build_try_exit_fragment, objc_build_extract_fragment,
	objc_build_try_prologue, objc_build_try_epilogue,
	objc_build_catch_stmt, objc_build_catch_epilogue,
	objc_build_finally_prologue, objc_build_finally_epilogue,
	objc_build_try_catch_finally_stmt, objc_build_synchronized_prologue,
	objc_build_synchronized_epilogue): Remove.
	(objc_create_temporary_var, struct objc_try_context, cur_try_context,
	objc_eh_runtime_type, objc_init_exceptions, objc_build_exc_ptr,
	next_sjlj_build_try_exit, next_sjlj_build_enter_and_setjmp,
	next_sjlj_build_exc_extract, next_sjlj_build_catch_list,
	next_sjlj_build_try_catch_finally, objc_begin_try_stmt,
	objc_begin_catch_clause, objc_finish_catch_clause,
	objc_build_finally_clause, objc_finish_try_stmt,
	objc_build_synchronized): New.
	(objc_is_object_id, objc_is_class_id): New.
	(objc_comptypes): Use them.
	(build_next_objc_exception_stuff): Break NeXT sjlj out from
	build_objc_exception_stuff.
	(synth_module_prologue): Update to match.
	(objc_build_throw_stmt): Use cur_try_context to decide if
	we're in a @catch.
	* objc/objc-act.h: Update prototypes.
	(OCTI_EXCEPTION_BLK_STACK, objc_exception_block_stack): Remove.
testsuite/
        * objc.dg/sync-1.m: New.
        * objc.dg/try-catch-1.m: Don't force next runtime.
        * objc.dg/try-catch-3.m, objc.dg/try-catch-4.m: Likewise.
        * objc.dg/try-catch-2.m: Likewise.  Enable everywhere.  Remove
        shadowed catch clause.
        * objc.dg/try-catch-5.m: New.

From-SVN: r83332
This commit is contained in:
Richard Henderson 2004-06-17 18:20:53 -07:00 committed by Richard Henderson
parent a776161b8b
commit 093c715302
18 changed files with 803 additions and 707 deletions

View File

@ -1,3 +1,56 @@
2004-06-17 Richard Henderson <rth@redhat.com>
* c-common.c (flag_objc_sjlj_exceptions): New.
* c-common.h (flag_objc_sjlj_exceptions): Declare.
* c-opts.c (c_common_handle_option): Set it.
(c_common_post_options): Handle interation of different
objective-c exception and runtime switches.
* c-decl.c (c_eh_initialized_p): New.
(finish_decl): Use it instead of local eh_initialized_p.
* c-parse.in (nested_function, notype_nested_function): Record
the result of compstmt.
(compstmt_or_error): Likewise.
(compstmt): Don't add_stmt the result.
(stmt): Don't return anything. Rewrite objc try and sync rules.
(objc_try_stmt, objc_catch_list): Remove.
(objc_catch_block, objc_finally_block): Remove.
(objc_catch_prefix, objc_catch_clause, objc_opt_catch_list): New.
(objc_try_catch_clause, objc_finally_clause): New.
(objc_try_catch_stmt): Rewrite.
* c-tree.h (c_eh_initialized_p): Declare.
* c-opt (fobjc-sjlj-exceptions): New.
* except.c (output_function_exception_table): Don't call cgraph
on non-decls.
* objc/objc-act.c (UTAG_EXCDATA_VAR, UTAG_CAUGHTEXC_VAR,
UTAG_RETHROWEXC_VAR, UTAG_EVALONCE_VAR, struct val_stack,
catch_count_stack, exc_binding_stack, if_nesting_count,
blk_nesting_count, objc_enter_block, objc_exit_block,
objc_declare_variable, val_stack_push, val_stack_pop,
objc_build_try_enter_fragment, objc_build_extract_expr,
objc_build_try_exit_fragment, objc_build_extract_fragment,
objc_build_try_prologue, objc_build_try_epilogue,
objc_build_catch_stmt, objc_build_catch_epilogue,
objc_build_finally_prologue, objc_build_finally_epilogue,
objc_build_try_catch_finally_stmt, objc_build_synchronized_prologue,
objc_build_synchronized_epilogue): Remove.
(objc_create_temporary_var, struct objc_try_context, cur_try_context,
objc_eh_runtime_type, objc_init_exceptions, objc_build_exc_ptr,
next_sjlj_build_try_exit, next_sjlj_build_enter_and_setjmp,
next_sjlj_build_exc_extract, next_sjlj_build_catch_list,
next_sjlj_build_try_catch_finally, objc_begin_try_stmt,
objc_begin_catch_clause, objc_finish_catch_clause,
objc_build_finally_clause, objc_finish_try_stmt,
objc_build_synchronized): New.
(objc_is_object_id, objc_is_class_id): New.
(objc_comptypes): Use them.
(build_next_objc_exception_stuff): Break NeXT sjlj out from
build_objc_exception_stuff.
(synth_module_prologue): Update to match.
(objc_build_throw_stmt): Use cur_try_context to decide if
we're in a @catch.
* objc/objc-act.h: Update prototypes.
(OCTI_EXCEPTION_BLK_STACK, objc_exception_block_stack): Remove.
2004-06-17 Andrew Pinski <apinski@apple.com>
* c-typeck.c (tagged_types_tu_compatible_p <case UNION_TYPE>):

View File

@ -361,6 +361,9 @@ int flag_nil_receivers = 1;
@try, etc.) in source code. */
int flag_objc_exceptions = 0;
/* Nonzero means that we generate NeXT setjmp based exceptions. */
int flag_objc_sjlj_exceptions = -1;
/* Nonzero means that code generation will be altered to support
"zero-link" execution. This currently affects ObjC only, but may
affect other languages in the future. */

View File

@ -321,6 +321,9 @@ extern int flag_nil_receivers;
@try, etc.) in source code. */
extern int flag_objc_exceptions;
/* Nonzero means that we generate NeXT setjmp based exceptions. */
extern int flag_objc_sjlj_exceptions;
/* Nonzero means that code generation will be altered to support
"zero-link" execution. This currently affects ObjC only, but may
affect other languages in the future. */

View File

@ -71,11 +71,14 @@ enum decl_context
/* Nonzero if we have seen an invalid cross reference
to a struct, union, or enum, but not yet printed the message. */
tree pending_invalid_xref;
/* File and line to appear in the eventual error message. */
location_t pending_invalid_xref_location;
/* True means we've initialized exception handling. */
bool c_eh_initialized_p;
/* While defining an enum type, this is 1 plus the last enumerator
constant value. Note that will do not have to save this or `enum_overflow'
around nested function definition since such a definition could only
@ -2982,8 +2985,6 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
tree attr = lookup_attribute ("cleanup", DECL_ATTRIBUTES (decl));
if (attr)
{
static bool eh_initialized_p;
tree cleanup_id = TREE_VALUE (TREE_VALUE (attr));
tree cleanup_decl = lookup_name (cleanup_id);
tree cleanup;
@ -2998,9 +2999,9 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
TREE_USED (cleanup_decl) = 1;
/* Initialize EH, if we've been told to do so. */
if (flag_exceptions && !eh_initialized_p)
if (flag_exceptions && !c_eh_initialized_p)
{
eh_initialized_p = true;
c_eh_initialized_p = true;
eh_personality_libfunc
= init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "__gcc_personality_sj0"

View File

@ -863,6 +863,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
flag_objc_exceptions = value;
break;
case OPT_fobjc_sjlj_exceptions:
flag_objc_sjlj_exceptions = value;
break;
case OPT_foperator_names:
cpp_opts->operator_names = value;
break;
@ -1109,6 +1113,12 @@ c_common_post_options (const char **pfilename)
flag_inline_functions = 0;
}
/* Default to ObjC sjlj exception handling if NeXT runtime. */
if (flag_objc_sjlj_exceptions < 0)
flag_objc_sjlj_exceptions = flag_next_runtime;
if (flag_objc_exceptions && !flag_objc_sjlj_exceptions)
flag_exceptions = 1;
/* -Wextra implies -Wsign-compare, but not if explicitly
overridden. */
if (warn_sign_compare == -1)

View File

@ -251,7 +251,6 @@ do { \
%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING
%type <ttype> superclass
%type <itype> objc_try_catch_stmt objc_finally_block
@@end_ifobjc
%{
@ -1515,7 +1514,7 @@ designator:
;
nested_function:
declarator
declarator
{ if (pedantic)
pedwarn ("ISO C forbids nested functions");
@ -1527,25 +1526,25 @@ nested_function:
YYERROR1;
}
}
old_style_parm_decls save_location
old_style_parm_decls save_location
{ tree decl = current_function_decl;
DECL_SOURCE_LOCATION (decl) = $4;
store_parm_decls (); }
/* This used to use compstmt_or_error.
That caused a bug with input `f(g) int g {}',
where the use of YYERROR1 above caused an error
which then was handled by compstmt_or_error.
There followed a repeated execution of that same rule,
which called YYERROR1 again, and so on. */
compstmt
/* This used to use compstmt_or_error. That caused a bug with
input `f(g) int g {}', where the use of YYERROR1 above caused
an error which then was handled by compstmt_or_error. There
followed a repeated execution of that same rule, which called
YYERROR1 again, and so on. */
compstmt
{ tree decl = current_function_decl;
add_stmt ($6);
finish_function ();
pop_function_context ();
add_decl_stmt (decl); }
;
notype_nested_function:
notype_declarator
notype_declarator
{ if (pedantic)
pedwarn ("ISO C forbids nested functions");
@ -1557,18 +1556,18 @@ notype_nested_function:
YYERROR1;
}
}
old_style_parm_decls save_location
old_style_parm_decls save_location
{ tree decl = current_function_decl;
DECL_SOURCE_LOCATION (decl) = $4;
store_parm_decls (); }
/* This used to use compstmt_or_error.
That caused a bug with input `f(g) int g {}',
where the use of YYERROR1 above caused an error
which then was handled by compstmt_or_error.
There followed a repeated execution of that same rule,
which called YYERROR1 again, and so on. */
compstmt
/* This used to use compstmt_or_error. That caused a bug with
input `f(g) int g {}', where the use of YYERROR1 above caused
an error which then was handled by compstmt_or_error. There
followed a repeated execution of that same rule, which called
YYERROR1 again, and so on. */
compstmt
{ tree decl = current_function_decl;
add_stmt ($6);
finish_function ();
pop_function_context ();
add_decl_stmt (decl); }
@ -2029,7 +2028,7 @@ label_decl:
It causes syntax errors to ignore to the next openbrace. */
compstmt_or_error:
compstmt
{}
{ add_stmt ($1); }
| error compstmt
;
@ -2060,8 +2059,7 @@ compstmt_primary_start:
;
compstmt: compstmt_start compstmt_nostart
{ add_stmt (c_end_compound_stmt ($1, true));
$$ = NULL_TREE; }
{ $$ = c_end_compound_stmt ($1, true); }
;
if_prefix:
@ -2226,37 +2224,27 @@ xexpr:
/* Parse a single real statement, not including any labels. */
stmt:
compstmt
{ stmt_count++; $$ = $1; }
{ stmt_count++; add_stmt ($1); }
| expr ';'
{ stmt_count++;
$$ = c_expand_expr_stmt ($1); }
{ stmt_count++; c_expand_expr_stmt ($1); }
| c99_block_start select_or_iter_stmt
{ add_stmt (c_end_compound_stmt ($1, flag_isoc99));
$$ = NULL_TREE; }
{ add_stmt (c_end_compound_stmt ($1, flag_isoc99)); }
| BREAK ';'
{ stmt_count++;
if (!(c_in_iteration_stmt || c_in_case_stmt))
{
error ("break statement not within loop or switch");
$$ = NULL_TREE;
}
error ("break statement not within loop or switch");
else
$$ = add_stmt (build_break_stmt ()); }
add_stmt (build_break_stmt ()); }
| CONTINUE ';'
{ stmt_count++;
if (!c_in_iteration_stmt)
{
error ("continue statement not within a loop");
$$ = NULL_TREE;
}
error ("continue statement not within a loop");
else
$$ = add_stmt (build_continue_stmt ()); }
add_stmt (build_continue_stmt ()); }
| RETURN ';'
{ stmt_count++;
$$ = c_expand_return (NULL_TREE); }
{ stmt_count++; c_expand_return (NULL_TREE); }
| RETURN expr ';'
{ stmt_count++;
$$ = c_expand_return ($2); }
{ stmt_count++; c_expand_return ($2); }
| asm_stmt
| GOTO identifier ';'
{ tree decl;
@ -2265,71 +2253,61 @@ stmt:
if (decl != 0)
{
TREE_USED (decl) = 1;
$$ = add_stmt (build_stmt (GOTO_EXPR, decl));
add_stmt (build_stmt (GOTO_EXPR, decl));
}
else
$$ = NULL_TREE;
}
| GOTO '*' expr ';'
{ if (pedantic)
pedwarn ("ISO C forbids `goto *expr;'");
stmt_count++;
$3 = convert (ptr_type_node, $3);
$$ = add_stmt (build_stmt (GOTO_EXPR, $3)); }
add_stmt (build_stmt (GOTO_EXPR, $3)); }
| ';'
{ $$ = NULL_TREE; }
{ }
@@ifobjc
| AT_THROW expr ';'
{ stmt_count++;
$$ = objc_build_throw_stmt ($2);
}
{ stmt_count++; objc_build_throw_stmt ($2); }
| AT_THROW ';'
{ stmt_count++;
$$ = objc_build_throw_stmt (NULL_TREE);
}
{ stmt_count++; objc_build_throw_stmt (NULL_TREE); }
| objc_try_catch_stmt
{ objc_build_finally_prologue (); }
objc_finally_block
{ $$ = objc_build_try_catch_finally_stmt ($1, $3); }
| AT_SYNCHRONIZED '(' expr ')'
{ objc_build_synchronized_prologue ($3); }
compstmt
{ $$ = objc_build_synchronized_epilogue (); }
{ }
| AT_SYNCHRONIZED '(' expr ')' save_location compstmt
{ stmt_count++; objc_build_synchronized ($5, $3, $6); }
;
objc_catch_prefix:
AT_CATCH '(' parm ')'
{ objc_begin_catch_clause ($3); }
;
objc_catch_clause:
objc_catch_prefix '{' compstmt_nostart
{ objc_finish_catch_clause (); }
| objc_catch_prefix '{' error '}'
{ objc_finish_catch_clause (); }
;
objc_opt_catch_list:
/* empty */
| objc_opt_catch_list objc_catch_clause
;
objc_try_catch_clause:
AT_TRY save_location compstmt
{ stmt_count++; objc_begin_try_stmt ($2, $3); }
objc_opt_catch_list
;
objc_finally_clause:
AT_FINALLY save_location compstmt
{ objc_build_finally_clause ($2, $3); }
;
objc_try_catch_stmt:
objc_try_stmt
{ objc_build_try_epilogue (1); }
objc_catch_list
{ objc_build_catch_epilogue (); $$ = 1; }
| objc_try_stmt
{ objc_build_try_epilogue (0); $$ = 0; }
;
objc_try_stmt:
AT_TRY
{ objc_build_try_prologue (); }
compstmt
;
objc_catch_list:
objc_catch_list objc_catch_block
| objc_catch_block
;
objc_catch_block:
AT_CATCH '(' parm ')'
{ objc_build_catch_stmt ($3); }
compstmt
{ stmt_count++; }
;
objc_finally_block:
AT_FINALLY compstmt
{ $$ = 1; }
| /* NULL */
{ $$ = 0; }
objc_try_catch_clause
{ objc_finish_try_stmt (); }
| objc_try_catch_clause objc_finally_clause
{ objc_finish_try_stmt (); }
@@end_ifobjc
;

View File

@ -298,6 +298,9 @@ extern int system_header_p;
extern bool c_override_global_bindings_to_false;
/* True means we've initialized exception handling. */
extern bool c_eh_initialized_p;
/* In c-decl.c */
extern void c_finish_incomplete_decl (tree);
extern void *get_current_scope (void);

View File

@ -584,6 +584,10 @@ fobjc-exceptions
ObjC ObjC++
Enable Objective-C exception and synchronization syntax
fobjc-sjlj-exceptions
ObjC ObjC++
Enable Objective-C setjmp exception handling runtime
foperator-names
C++ ObjC++
Recognize C++ kewords like \"compl\" and \"xor\"

View File

@ -4085,9 +4085,12 @@ output_function_exception_table (void)
if (TREE_CODE (type) == ADDR_EXPR)
{
type = TREE_OPERAND (type, 0);
node = cgraph_varpool_node (type);
if (node)
cgraph_varpool_mark_needed_node (node);
if (TREE_CODE (type) == VAR_DECL)
{
node = cgraph_varpool_node (type);
if (node)
cgraph_varpool_mark_needed_node (node);
}
}
else if (TREE_CODE (type) != INTEGER_CST)
abort ();

File diff suppressed because it is too large Load Diff

View File

@ -39,16 +39,13 @@ void finish_method_def (void);
tree start_protocol (enum tree_code, tree, tree);
void finish_protocol (tree);
tree objc_build_throw_stmt (tree);
tree objc_build_try_catch_finally_stmt (int, int);
void objc_build_synchronized_prologue (tree);
tree objc_build_synchronized_epilogue (void);
tree objc_build_try_prologue (void);
void objc_build_try_epilogue (int);
void objc_build_catch_stmt (tree);
void objc_build_catch_epilogue (void);
tree objc_build_finally_prologue (void);
tree objc_build_finally_epilogue (void);
void objc_build_throw_stmt (tree);
void objc_begin_try_stmt (location_t, tree);
void objc_begin_catch_clause (tree);
void objc_finish_catch_clause (void);
void objc_build_finally_clause (location_t, tree);
void objc_finish_try_stmt (void);
void objc_build_synchronized (location_t, tree, tree);
tree is_ivar (tree, tree);
int is_private (tree);
@ -282,7 +279,6 @@ enum objc_tree_index
OCTI_LOCAL_EXCEPTION_DECL,
OCTI_RETHROW_EXCEPTION_DECL,
OCTI_EVAL_ONCE_DECL,
OCTI_EXCEPTION_BLK_STACK,
OCTI_CATCH_TYPE,
OCTI_MAX
@ -402,8 +398,6 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX];
#define objc_caught_exception objc_global_trees[OCTI_LOCAL_EXCEPTION_DECL]
#define objc_rethrow_exception objc_global_trees[OCTI_RETHROW_EXCEPTION_DECL]
#define objc_eval_once objc_global_trees[OCTI_EVAL_ONCE_DECL]
#define objc_exception_block_stack \
objc_global_trees[OCTI_EXCEPTION_BLK_STACK]
#define objc_catch_type objc_global_trees[OCTI_CATCH_TYPE]
#define objc_method_template objc_global_trees[OCTI_METH_TEMPL]

View File

@ -1,3 +1,12 @@
2004-06-17 Richard Henderson <rth@redhat.com>
* objc.dg/sync-1.m: New.
* objc.dg/try-catch-1.m: Don't force next runtime.
* objc.dg/try-catch-3.m, objc.dg/try-catch-4.m: Likewise.
* objc.dg/try-catch-2.m: Likewise. Enable everywhere. Remove
shadowed catch clause.
* objc.dg/try-catch-5.m: New.
2004-06-17 Zack Weinberg <zack@codesourcery.com>
Bug 14610

View File

@ -0,0 +1,12 @@
/* Make sure that @synchronized parses. */
/* { dg-options "-fnext-runtime -fobjc-exceptions" } */
/* { dg-do compile } */
#include <objc/Object.h>
void foo(id sem)
{
@synchronized (sem) {
return;
}
}

View File

@ -1,8 +1,6 @@
/* Test if the compiler accepts @throw / @try..@catch..@finally
syntax. This will only be usable on MacOS X 10.3 and later,
but may be compiled on all targets. */
/* Test if the compiler accepts @throw / @try..@catch..@finally syntax. */
/* Developed by Ziemowit Laski <zlaski@apple.com>. */
/* { dg-options "-fnext-runtime -fobjc-exceptions" } */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do compile } */
#include <objc/Object.h>

View File

@ -2,11 +2,9 @@
all uncaught exceptions. */
/* Developed by Ziemowit Laski <zlaski@apple.com>. */
/* { dg-options "-fobjc-exceptions -lobjc" } */
/* { dg-do run { target *-*-darwin* } } */
/* { dg-options "-fobjc-exceptions" } */
/* { dg-do run } */
#include <objc/objc.h>
#include <objc/objc-runtime.h>
#include <objc/Object.h>
#include <stdio.h>
@ -72,10 +70,6 @@ void test (Object* sendPort)
CHECK_IF(!sendPort);
CHECK_IF(!cleanupPorts);
}
@catch(Object *obj) { /* { dg-warning "Exception already handled by preceding .\\@catch\\(id\\)." } */
printf ("Exception caught by incorrect handler!\n");
CHECK_IF(0);
}
}
int main (void) {

View File

@ -3,7 +3,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
/* { dg-options "-fnext-runtime -fobjc-exceptions" } */
/* { dg-options "-fobjc-exceptions" } */
#include <objc/Object.h>

View File

@ -3,7 +3,7 @@
/* Author: Ziemowit Laski <zlaski@apple.com> */
/* { dg-do compile } */
/* { dg-options "-Wall -fnext-runtime -fobjc-exceptions" } */
/* { dg-options "-Wall -fobjc-exceptions" } */
@interface Exception
@end

View File

@ -0,0 +1,27 @@
/* Check that the compiler does correctly complain about
exceptions being caught by previous @catch blocks. */
/* Force the use of NeXT runtime to see that we don't ICE after
generating the warning message. */
/* { dg-do compile } */
/* { dg-options "-Wall -fnext-runtime -fobjc-exceptions" } */
@interface Exception
@end
@interface FooException : Exception
@end
extern void foo();
void test()
{
@try {
foo();
}
@catch (Exception* e) { /* { dg-warning "earlier handler" } */
}
@catch (FooException* fe) { /* { dg-warning "will be caught" } */
}
}