Commit 4c581243 by Mike Stump

except.c (expand_eh_region_start_tree): Add DECL argument so we can better track…

except.c (expand_eh_region_start_tree): Add DECL argument so we can better track why the region was made for error...

	* except.c (expand_eh_region_start_tree): Add DECL argument so we
 	can better track why the region was made for error reporting.
	* except.h (expand_eh_region_start_tree): Likewise.
	* tree.h (expand_dhc_cleanup): Likewise.
	(expand_dcc_cleanup): Likewise.
	* except.c (expand_eh_region_start_for_decl): New routine.
	* except.h (expand_eh_region_start_for_decl): Likewise.
	* stmt.c (expand_decl_cleanup): Add DECL to call of
	expand_eh_region_start_tree.
	(expand_dcc_cleanup): Likewise.
	(expand_dhc_cleanup): Likewise.

	(expand_start_case): Switches introduce conditional contexts.
	(expand_start_case_dummy): Likewise.
	(expand_start_case_dummy): Likewise.
	(expand_end_case): Likewise.

From-SVN: r13990
parent 9c6cd30e
...@@ -911,7 +911,8 @@ start_dynamic_handler () ...@@ -911,7 +911,8 @@ start_dynamic_handler ()
of a using an exception region. */ of a using an exception region. */
int int
expand_eh_region_start_tree (cleanup) expand_eh_region_start_tree (decl, cleanup)
tree decl;
tree cleanup; tree cleanup;
{ {
rtx note; rtx note;
...@@ -952,52 +953,25 @@ expand_eh_region_start_tree (cleanup) ...@@ -952,52 +953,25 @@ expand_eh_region_start_tree (cleanup)
{ {
/* Arrange for returns and gotos to pop the entry we make on the /* Arrange for returns and gotos to pop the entry we make on the
dynamic cleanup stack. */ dynamic cleanup stack. */
expand_dcc_cleanup (); expand_dcc_cleanup (decl);
start_dynamic_cleanup (func, arg); start_dynamic_cleanup (func, arg);
return 1; return 1;
} }
} }
if (exceptions_via_longjmp) expand_eh_region_start_for_decl (decl);
{
/* We need a new block to record the start and end of the
dynamic handler chain. We could always do this, but we
really want to permit jumping into such a block, and we want
to avoid any errors or performance impact in the SJ EH code
for now. */
expand_start_bindings (0);
/* But we don't need or want a new temporary level. */
pop_temp_slots ();
/* Mark this block as created by expand_eh_region_start. This
is so that we can pop the block with expand_end_bindings
automatically. */
mark_block_as_eh_region ();
/* Arrange for returns and gotos to pop the entry we make on the
dynamic handler stack. */
expand_dhc_cleanup ();
}
if (exceptions_via_longjmp == 0)
note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG);
emit_label (push_eh_entry (&ehstack));
if (exceptions_via_longjmp == 0)
NOTE_BLOCK_NUMBER (note)
= CODE_LABEL_NUMBER (ehstack.top->entry->exception_handler_label);
if (exceptions_via_longjmp)
start_dynamic_handler ();
return 0; return 0;
} }
/* Start an exception handling region. All instructions emitted after /* Just like expand_eh_region_start, except if a cleanup action is
this point are considered to be part of the region until entered on the cleanup chain, the TREE_PURPOSE of the element put
expand_eh_region_end is invoked. */ on the chain is DECL. DECL should be the associated VAR_DECL, if
any, otherwise it should be NULL_TREE. */
void void
expand_eh_region_start () expand_eh_region_start_for_decl (decl)
tree decl;
{ {
rtx note; rtx note;
...@@ -1024,7 +998,7 @@ expand_eh_region_start () ...@@ -1024,7 +998,7 @@ expand_eh_region_start ()
/* Arrange for returns and gotos to pop the entry we make on the /* Arrange for returns and gotos to pop the entry we make on the
dynamic handler stack. */ dynamic handler stack. */
expand_dhc_cleanup (); expand_dhc_cleanup (decl);
} }
if (exceptions_via_longjmp == 0) if (exceptions_via_longjmp == 0)
...@@ -1037,6 +1011,16 @@ expand_eh_region_start () ...@@ -1037,6 +1011,16 @@ expand_eh_region_start ()
start_dynamic_handler (); start_dynamic_handler ();
} }
/* Start an exception handling region. All instructions emitted after
this point are considered to be part of the region until
expand_eh_region_end is invoked. */
void
expand_eh_region_start ()
{
expand_eh_region_start_for_decl (NULL_TREE);
}
/* End an exception handling region. The information about the region /* End an exception handling region. The information about the region
is found on the top of ehstack. is found on the top of ehstack.
......
...@@ -88,6 +88,13 @@ struct eh_queue { ...@@ -88,6 +88,13 @@ struct eh_queue {
extern void expand_eh_region_start PROTO((void)); extern void expand_eh_region_start PROTO((void));
/* Just like expand_eh_region_start, except if a cleanup action is
entered on the cleanup chain, the TREE_PURPOSE of the element put
on the chain is DECL. DECL should be the associated VAR_DECL, if
any, otherwise it should be NULL_TREE. */
extern void expand_eh_region_start_for_decl PROTO((tree));
/* Start an exception handling region for the given cleanup action. /* Start an exception handling region for the given cleanup action.
All instructions emitted after this point are considered to be part All instructions emitted after this point are considered to be part
of the region until expand_eh_region_end () is invoked. CLEANUP is of the region until expand_eh_region_end () is invoked. CLEANUP is
...@@ -100,7 +107,7 @@ extern void expand_eh_region_start PROTO((void)); ...@@ -100,7 +107,7 @@ extern void expand_eh_region_start PROTO((void));
generation, and optimizes it so as to not need the exception generation, and optimizes it so as to not need the exception
region. */ region. */
extern int expand_eh_region_start_tree PROTO((tree)); extern int expand_eh_region_start_tree PROTO((tree, tree));
/* End an exception handling region. The information about the region /* End an exception handling region. The information about the region
is found on the top of ehstack. is found on the top of ehstack.
......
...@@ -3950,7 +3950,7 @@ expand_decl_cleanup (decl, cleanup) ...@@ -3950,7 +3950,7 @@ expand_decl_cleanup (decl, cleanup)
/* If this was optimized so that there is no exception region for the /* If this was optimized so that there is no exception region for the
cleanup, then mark the TREE_LIST node, so that we can later tell cleanup, then mark the TREE_LIST node, so that we can later tell
if we need to call expand_eh_region_end. */ if we need to call expand_eh_region_end. */
if (expand_eh_region_start_tree (cleanup)) if (expand_eh_region_start_tree (decl, cleanup))
TREE_ADDRESSABLE (t) = 1; TREE_ADDRESSABLE (t) = 1;
if (cond_context) if (cond_context)
...@@ -3972,11 +3972,12 @@ expand_decl_cleanup (decl, cleanup) ...@@ -3972,11 +3972,12 @@ expand_decl_cleanup (decl, cleanup)
} }
/* Arrange for the top element of the dynamic cleanup chain to be /* Arrange for the top element of the dynamic cleanup chain to be
popped if we exit the current binding contour. If the current popped if we exit the current binding contour. DECL is the
contour is left via an exception, then __sjthrow will pop the top associated declaration, if any, otherwise NULL_TREE. If the
element off the dynamic cleanup chain. The code that avoids doing current contour is left via an exception, then __sjthrow will pop
the action we push into the cleanup chain in the exceptional case the top element off the dynamic cleanup chain. The code that
is contained in expand_cleanups. avoids doing the action we push into the cleanup chain in the
exceptional case is contained in expand_cleanups.
This routine is only used by expand_eh_region_start, and that is This routine is only used by expand_eh_region_start, and that is
the only way in which an exception region should be started. This the only way in which an exception region should be started. This
...@@ -3984,7 +3985,8 @@ expand_decl_cleanup (decl, cleanup) ...@@ -3984,7 +3985,8 @@ expand_decl_cleanup (decl, cleanup)
for exception handling. */ for exception handling. */
int int
expand_dcc_cleanup () expand_dcc_cleanup (decl)
tree decl;
{ {
struct nesting *thisblock = block_stack; struct nesting *thisblock = block_stack;
tree cleanup; tree cleanup;
...@@ -4003,7 +4005,7 @@ expand_dcc_cleanup () ...@@ -4003,7 +4005,7 @@ expand_dcc_cleanup ()
/* Add the cleanup in a manner similar to expand_decl_cleanup. */ /* Add the cleanup in a manner similar to expand_decl_cleanup. */
thisblock->data.block.cleanups thisblock->data.block.cleanups
= temp_tree_cons (NULL_TREE, cleanup, thisblock->data.block.cleanups); = temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
/* If this block has a cleanup, it belongs in stack_block_stack. */ /* If this block has a cleanup, it belongs in stack_block_stack. */
stack_block_stack = thisblock; stack_block_stack = thisblock;
...@@ -4011,11 +4013,12 @@ expand_dcc_cleanup () ...@@ -4011,11 +4013,12 @@ expand_dcc_cleanup ()
} }
/* Arrange for the top element of the dynamic handler chain to be /* Arrange for the top element of the dynamic handler chain to be
popped if we exit the current binding contour. If the current popped if we exit the current binding contour. DECL is the
contour is left via an exception, then __sjthrow will pop the assciated declaration, if any, otherwise NULL_TREE. If the current
top element off the dynamic handler chain. The code that avoids contour is left via an exception, then __sjthrow will pop the top
doing the action we push into the handler chain in the exceptional element off the dynamic handler chain. The code that avoids doing
case is contained in expand_cleanups. the action we push into the handler chain in the exceptional case
is contained in expand_cleanups.
This routine is only used by expand_eh_region_start, and that is This routine is only used by expand_eh_region_start, and that is
the only way in which an exception region should be started. This the only way in which an exception region should be started. This
...@@ -4023,7 +4026,8 @@ expand_dcc_cleanup () ...@@ -4023,7 +4026,8 @@ expand_dcc_cleanup ()
for exception handling. */ for exception handling. */
int int
expand_dhc_cleanup () expand_dhc_cleanup (decl)
tree decl;
{ {
struct nesting *thisblock = block_stack; struct nesting *thisblock = block_stack;
tree cleanup; tree cleanup;
...@@ -4042,7 +4046,7 @@ expand_dhc_cleanup () ...@@ -4042,7 +4046,7 @@ expand_dhc_cleanup ()
/* Add the cleanup in a manner similar to expand_decl_cleanup. */ /* Add the cleanup in a manner similar to expand_decl_cleanup. */
thisblock->data.block.cleanups thisblock->data.block.cleanups
= temp_tree_cons (NULL_TREE, cleanup, thisblock->data.block.cleanups); = temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
/* If this block has a cleanup, it belongs in stack_block_stack. */ /* If this block has a cleanup, it belongs in stack_block_stack. */
stack_block_stack = thisblock; stack_block_stack = thisblock;
...@@ -4303,6 +4307,8 @@ expand_start_case (exit_flag, expr, type, printname) ...@@ -4303,6 +4307,8 @@ expand_start_case (exit_flag, expr, type, printname)
emit_note (NULL_PTR, NOTE_INSN_DELETED); emit_note (NULL_PTR, NOTE_INSN_DELETED);
thiscase->data.case_stmt.start = get_last_insn (); thiscase->data.case_stmt.start = get_last_insn ();
start_cleanup_deferal ();
} }
...@@ -4355,6 +4361,7 @@ expand_start_case_dummy () ...@@ -4355,6 +4361,7 @@ expand_start_case_dummy ()
thiscase->data.case_stmt.num_ranges = 0; thiscase->data.case_stmt.num_ranges = 0;
case_stack = thiscase; case_stack = thiscase;
nesting_stack = thiscase; nesting_stack = thiscase;
start_cleanup_deferal ();
} }
/* End a dummy case statement. */ /* End a dummy case statement. */
...@@ -4362,6 +4369,7 @@ expand_start_case_dummy () ...@@ -4362,6 +4369,7 @@ expand_start_case_dummy ()
void void
expand_end_case_dummy () expand_end_case_dummy ()
{ {
end_cleanup_deferal ();
POPSTACK (case_stack); POPSTACK (case_stack);
} }
...@@ -5355,6 +5363,8 @@ expand_end_case (orig_index) ...@@ -5355,6 +5363,8 @@ expand_end_case (orig_index)
if (count != 0) if (count != 0)
range = fold (build (MINUS_EXPR, index_type, maxval, minval)); range = fold (build (MINUS_EXPR, index_type, maxval, minval));
end_cleanup_deferal ();
if (count == 0) if (count == 0)
{ {
expand_expr (index_expr, const0_rtx, VOIDmode, 0); expand_expr (index_expr, const0_rtx, VOIDmode, 0);
...@@ -5622,6 +5632,8 @@ expand_end_case (orig_index) ...@@ -5622,6 +5632,8 @@ expand_end_case (orig_index)
reorder_insns (before_case, get_last_insn (), reorder_insns (before_case, get_last_insn (),
thiscase->data.case_stmt.start); thiscase->data.case_stmt.start);
} }
else
end_cleanup_deferal ();
if (thiscase->exit_label) if (thiscase->exit_label)
emit_label (thiscase->exit_label); emit_label (thiscase->exit_label);
......
...@@ -1697,7 +1697,8 @@ extern void mark_block_as_not_eh_region PROTO((void)); ...@@ -1697,7 +1697,8 @@ extern void mark_block_as_not_eh_region PROTO((void));
extern int is_eh_region PROTO((void)); extern int is_eh_region PROTO((void));
extern int conditional_context PROTO((void)); extern int conditional_context PROTO((void));
extern tree last_cleanup_this_contour PROTO((void)); extern tree last_cleanup_this_contour PROTO((void));
extern int expand_dhc_cleanup PROTO((void)); extern int expand_dhc_cleanup PROTO((tree));
extern int expand_dcc_cleanup PROTO((tree));
extern void expand_start_case PROTO((int, tree, tree, extern void expand_start_case PROTO((int, tree, tree,
char *)); char *));
extern void expand_end_case PROTO((tree)); extern void expand_end_case PROTO((tree));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment