except.c (expand_fixup_region_end): New fn.

* except.c (expand_fixup_region_end): New fn.
	(expand_fixup_region_start): Likewise.
	(expand_eh_region_start_tree): Store cleanup into finalization here.
	* stmt.c (expand_cleanups): Use them to protect fixups.

From-SVN: r16929
This commit is contained in:
Jason Merrill 1997-12-03 20:04:31 +00:00 committed by Jason Merrill
parent aa36c0813a
commit 9762d48da5
3 changed files with 66 additions and 0 deletions

View file

@ -1,3 +1,10 @@
Wed Dec 3 12:01:56 1997 Jason Merrill <jason@yorick.cygnus.com>
* except.c (expand_fixup_region_end): New fn.
(expand_fixup_region_start): Likewise.
(expand_eh_region_start_tree): Store cleanup into finalization here.
* stmt.c (expand_cleanups): Use them to protect fixups.
Wed Dec 3 11:41:13 1997 Gavin Koch <gavin@cygnus.com>
* mips/mips.md (muldi3_r4000): Broaden the output template

View file

@ -1013,6 +1013,7 @@ expand_eh_region_start_tree (decl, cleanup)
}
expand_eh_region_start_for_decl (decl);
ehstack.top->entry->finalization = cleanup;
return 0;
}
@ -1138,6 +1139,57 @@ expand_eh_region_end (handler)
}
}
/* End the EH region for a goto fixup. We only need them in the region-based
EH scheme. */
void
expand_fixup_region_start ()
{
if (! doing_eh (0) || exceptions_via_longjmp)
return;
expand_eh_region_start ();
}
/* End the EH region for a goto fixup. CLEANUP is the cleanup we just
expanded; to avoid running it twice if it throws, we look through the
ehqueue for a matching region and rethrow from its outer_context. */
void
expand_fixup_region_end (cleanup)
tree cleanup;
{
tree t;
struct eh_node *node;
int yes;
if (! doing_eh (0) || exceptions_via_longjmp)
return;
for (node = ehstack.top; node && node->entry->finalization != cleanup; )
node = node->chain;
if (node == 0)
for (node = ehqueue.head; node && node->entry->finalization != cleanup; )
node = node->chain;
if (node == 0)
abort ();
yes = suspend_momentary ();
t = build (RTL_EXPR, void_type_node, NULL_RTX, const0_rtx);
TREE_SIDE_EFFECTS (t) = 1;
do_pending_stack_adjust ();
start_sequence_for_rtl_expr (t);
expand_internal_throw (node->entry->outer_context);
do_pending_stack_adjust ();
RTL_EXPR_SEQUENCE (t) = get_insns ();
end_sequence ();
resume_momentary (yes);
expand_eh_region_end (t);
}
/* If we are using the setjmp/longjmp EH codegen method, we emit a
call to __sjthrow.

View file

@ -4229,7 +4229,14 @@ expand_cleanups (list, dont_do, in_fixup, reachable)
the target. Though the cleanups are expanded multiple
times, the control paths are non-overlapping so the
cleanups will not be executed twice. */
/* We may need to protect fixups with rethrow regions. */
int protect = (in_fixup && ! TREE_ADDRESSABLE (tail));
if (protect)
expand_fixup_region_start ();
expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
if (protect)
expand_fixup_region_end (TREE_VALUE (tail));
free_temp_slots ();
}
}