diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/ChangeLog | 5 | ||||
| -rw-r--r-- | gcc/expr.c | 58 | ||||
| -rw-r--r-- | gcc/java/ChangeLog | 5 | ||||
| -rw-r--r-- | gcc/java/lang.c | 23 | 
4 files changed, 72 insertions, 19 deletions
| diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5bd29d35c5b..55b245a0e72 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@  2002-07-21  Richard Henderson  <rth@redhat.com> +	* expr.c (expand_expr) [TRY_FINALLY_EXPR]: Don't use +	GOTO_SUBROUTINE_EXPR when finally_block can be re-expanded. + +2002-07-21  Richard Henderson  <rth@redhat.com> +  	* unroll.c (find_splittable_givs): Do not split DEST_ADDR givs  	that are not unrolled completely. diff --git a/gcc/expr.c b/gcc/expr.c index 7b5810c617c..e70bf905b20 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8965,29 +8965,49 @@ expand_expr (exp, target, tmode, modifier)        {  	tree try_block = TREE_OPERAND (exp, 0);  	tree finally_block = TREE_OPERAND (exp, 1); -	rtx finally_label = gen_label_rtx (); -	rtx done_label = gen_label_rtx (); -	rtx return_link = gen_reg_rtx (Pmode); -	tree cleanup = build (GOTO_SUBROUTINE_EXPR, void_type_node, -			      (tree) finally_label, (tree) return_link); -	TREE_SIDE_EFFECTS (cleanup) = 1; -	/* Start a new binding layer that will keep track of all cleanup -	   actions to be performed.  */ -	expand_start_bindings (2); +        if (unsafe_for_reeval (finally_block) > 1) +	  { +	    /* In this case, wrapping FINALLY_BLOCK in an UNSAVE_EXPR +	       is not sufficient, so we cannot expand the block twice. +	       So we play games with GOTO_SUBROUTINE_EXPR to let us +	       expand the thing only once.  */ + +	    rtx finally_label = gen_label_rtx (); +	    rtx done_label = gen_label_rtx (); +	    rtx return_link = gen_reg_rtx (Pmode); +	    tree cleanup = build (GOTO_SUBROUTINE_EXPR, void_type_node, +			          (tree) finally_label, (tree) return_link); +	    TREE_SIDE_EFFECTS (cleanup) = 1; + +	    /* Start a new binding layer that will keep track of all cleanup +	       actions to be performed.  */ +	    expand_start_bindings (2); +	    target_temp_slot_level = temp_slot_level; + +	    expand_decl_cleanup (NULL_TREE, cleanup); +	    op0 = expand_expr (try_block, target, tmode, modifier); + +	    preserve_temp_slots (op0); +	    expand_end_bindings (NULL_TREE, 0, 0); +	    emit_jump (done_label); +	    emit_label (finally_label); +	    expand_expr (finally_block, const0_rtx, VOIDmode, 0); +	    emit_indirect_jump (return_link); +	    emit_label (done_label); +	  } +	else +	  { +	    expand_start_bindings (2); +	    target_temp_slot_level = temp_slot_level; -	target_temp_slot_level = temp_slot_level; +	    expand_decl_cleanup (NULL_TREE, finally_block); +	    op0 = expand_expr (try_block, target, tmode, modifier); -	expand_decl_cleanup (NULL_TREE, cleanup); -	op0 = expand_expr (try_block, target, tmode, modifier); +	    preserve_temp_slots (op0); +	    expand_end_bindings (NULL_TREE, 0, 0); +	  } -	preserve_temp_slots (op0); -	expand_end_bindings (NULL_TREE, 0, 0); -	emit_jump (done_label); -	emit_label (finally_label); -	expand_expr (finally_block, const0_rtx, VOIDmode, 0); -	emit_indirect_jump (return_link); -	emit_label (done_label);  	return op0;        } diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 601e766175f..2ccdd0585dd 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,8 @@ +2002-07-21  Richard Henderson  <rth@redhat.com> + +	* lang.c (java_unsafe_for_reeval): New. +	(LANG_HOOKS_UNSAFE_FOR_REEVAL): New. +  2002-07-21  Neil Booth  <neil@daikokuya.co.uk>  	* jcf-path.c (GET_ENV_PATH_LIST): Remove. diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 60f1a1c5931..6d7affacbc9 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -61,6 +61,7 @@ static void java_print_error_function PARAMS ((diagnostic_context *,  static int process_option_with_no PARAMS ((const char *,  					   const struct string_option *,  					   int)); +static int java_unsafe_for_reeval PARAMS ((tree));  #ifndef TARGET_OBJECT_SUFFIX  # define TARGET_OBJECT_SUFFIX ".o" @@ -238,6 +239,8 @@ struct language_function GTY(())  #define LANG_HOOKS_POST_OPTIONS java_post_options  #undef LANG_HOOKS_PARSE_FILE  #define LANG_HOOKS_PARSE_FILE java_parse_file +#undef LANG_HOOKS_UNSAFE_FOR_REEVAL +#define LANG_HOOKS_UNSAFE_FOR_REEVAL java_unsafe_for_reeval  #undef LANG_HOOKS_MARK_ADDRESSABLE  #define LANG_HOOKS_MARK_ADDRESSABLE java_mark_addressable  #undef LANG_HOOKS_EXPAND_EXPR @@ -794,4 +797,24 @@ java_post_options ()    return false;  } +/* Called from unsafe_for_reeval.  */ +static int +java_unsafe_for_reeval (t) +     tree t; +{ +  switch (TREE_CODE (t)) +    { +    case BLOCK: +      /* Our expander tries to expand the variables twice.  Boom.  */ +      if (BLOCK_EXPR_DECLS (t) != NULL) +	return 2; +      return unsafe_for_reeval (BLOCK_EXPR_BODY (t)); + +    default: +      break; +    } + +  return -1; +} +  #include "gt-java-lang.h" | 

