mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-24 11:24:05 +08:00
verify.cc (state::enter_subroutine): New method.
* verify.cc (state::enter_subroutine): New method. (handle_jsr_insn): Use it. (state::merge): When processing a `ret', correctly use subroutine's state to determine which local variables have changed. (push_exception_jump): Don't let stack overflow. From-SVN: r49388
This commit is contained in:
parent
6f48900c2b
commit
de0ed7b6c5
@ -1,3 +1,12 @@
|
||||
2002-01-31 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* verify.cc (state::enter_subroutine): New method.
|
||||
(handle_jsr_insn): Use it.
|
||||
(state::merge): When processing a `ret', correctly use
|
||||
subroutine's state to determine which local variables have
|
||||
changed.
|
||||
(push_exception_jump): Don't let stack overflow.
|
||||
|
||||
2002-01-31 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* gnu/gcj/convert/Convert.java: Only include one copyright year in
|
||||
|
@ -891,6 +891,18 @@ private:
|
||||
// FIXME: subroutine handling?
|
||||
}
|
||||
|
||||
// Modify this state to reflect entry into a subroutine.
|
||||
void enter_subroutine (int npc, int max_locals)
|
||||
{
|
||||
subroutine = npc;
|
||||
// Mark all items as unchanged. Each subroutine needs to keep
|
||||
// track of its `changed' state independently. In the case of
|
||||
// nested subroutines, this information will be merged back into
|
||||
// parent by the `ret'.
|
||||
for (int i = 0; i < max_locals; ++i)
|
||||
local_changed[i] = false;
|
||||
}
|
||||
|
||||
// Merge STATE_OLD into this state. Destructively modifies this
|
||||
// state. Returns true if the new state was in fact changed.
|
||||
// Will throw an exception if the states are not mergeable.
|
||||
@ -936,7 +948,12 @@ private:
|
||||
// Merge local variables.
|
||||
for (int i = 0; i < max_locals; ++i)
|
||||
{
|
||||
if (! ret_semantics || local_changed[i])
|
||||
// If we're not processing a `ret', then we merge every
|
||||
// local variable. If we are processing a `ret', then we
|
||||
// only merge locals which changed in the subroutine. When
|
||||
// processing a `ret', STATE_OLD is the state at the point
|
||||
// of the `ret', and THIS is the state just after the `jsr'.
|
||||
if (! ret_semantics || state_old->local_changed[i])
|
||||
{
|
||||
if (locals[i].merge (state_old->locals[i], true, verifier))
|
||||
{
|
||||
@ -1264,6 +1281,8 @@ private:
|
||||
this, true);
|
||||
state s (current_state, current_method->max_stack,
|
||||
current_method->max_locals);
|
||||
if (current_method->max_stack < 1)
|
||||
verify_fail ("stack overflow at exception handler");
|
||||
s.set_exception (t, current_method->max_stack);
|
||||
push_jump_merge (pc, &s);
|
||||
}
|
||||
@ -1401,18 +1420,19 @@ private:
|
||||
current_state->check_no_uninitialized_objects (current_method->max_locals, this);
|
||||
check_nonrecursive_call (current_state->subroutine, npc);
|
||||
|
||||
// Temporarily modify the current state so that it looks like we are
|
||||
// in the subroutine.
|
||||
// Create a new state and modify it as appropriate for entry into
|
||||
// a subroutine. We're writing this in a weird way because,
|
||||
// unfortunately, push_type only works on the current state.
|
||||
push_type (return_address_type);
|
||||
int save = current_state->subroutine;
|
||||
current_state->subroutine = npc;
|
||||
|
||||
// Merge into the subroutine.
|
||||
push_jump_merge (npc, current_state);
|
||||
|
||||
// Undo our modifications.
|
||||
current_state->subroutine = save;
|
||||
// Clean up the weirdness.
|
||||
pop_type (return_address_type);
|
||||
|
||||
// On entry to the subroutine, the subroutine number must be set
|
||||
// and the locals must be marked as cleared. We do this after
|
||||
// merging state so that we don't erroneously "notice" a variable
|
||||
// change merely on entry.
|
||||
states[npc]->enter_subroutine (npc, current_method->max_locals);
|
||||
}
|
||||
|
||||
jclass construct_primitive_array_type (type_val prim)
|
||||
|
Loading…
Reference in New Issue
Block a user