More important patches from the trunk:

* except.c (find_handler_in_range): The upper limit for exception
        ranges is exclusive, not inclusive: (start <= pc < end).
        (link_handler): find child pointer which points to outer by
        searching sibling list: previous code incorrectly assumed that
        outer->outer->first_child must point to outer.
        * verify.c (verify_jvm_instructions): FIXME added to code for
        `athrow'.
        (verify_jvm_instructions): Do not assume that the last block
        processed in a subroutine is a block which ends with a `ret'
        instruction.  With some control flows it is possible that the last
        block ends with an `athrow'.

From-SVN: r27664
This commit is contained in:
Andrew Haley 1999-06-21 12:09:20 +00:00 committed by Anthony Green
parent 4f58a86a63
commit c56167522b
3 changed files with 52 additions and 13 deletions

View File

@ -1,3 +1,17 @@
1999-06-21 Andrew Haley <aph@cygnus.com>
* except.c (find_handler_in_range): The upper limit for exception
ranges is exclusive, not inclusive: (start <= pc < end).
(link_handler): find child pointer which points to outer by
searching sibling list: previous code incorrectly assumed that
outer->outer->first_child must point to outer.
* verify.c (verify_jvm_instructions): FIXME added to code for
`athrow'.
(verify_jvm_instructions): Do not assume that the last block
processed in a subroutine is a block which ends with a `ret'
instruction. With some control flows it is possible that the last
block ends with an `athrow'.
Mon Jun 14 13:13:39 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
* parse.y (qualify_ambiguous_name): Reorganized the post

View File

@ -72,7 +72,7 @@ find_handler_in_range (pc, range, child)
{
if (pc < child->start_pc)
break;
if (pc <= child->end_pc)
if (pc < child->end_pc)
return find_handler_in_range (pc, child, child->first_child);
}
cache_range = range;
@ -129,7 +129,12 @@ link_handler (range, outer)
range->outer = outer->outer;
range->next_sibling = NULL;
range->first_child = outer;
outer->outer->first_child = range;
{
struct eh_range **pr = &(outer->outer->first_child);
while (*pr != outer)
pr = &(*pr)->next_sibling;
*pr = range;
}
outer->outer = range;
return;
}

View File

@ -999,6 +999,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
break;
case OPCODE_athrow:
// FIXME: athrow also empties the stack.
pop_type (throwable_type_node);
INVALIDATE_PC;
break;
@ -1197,21 +1198,46 @@ verify_jvm_instructions (jcf, byte_ops, length)
}
}
}
break;
case OPCODE_jsr_w:
case OPCODE_ret_w:
default:
error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
return 0;
}
/* Check if there are any more pending blocks in this subroutine.
Because we push pending blocks in a last-in-first-out order,
and because we don't push anything from our caller until we
are done with this subroutine or anything nested in it,
then we are done if the top of the pending_blocks stack is
not in a subroutine, or it is in our caller. */
if (current_subr
&& PC == INVALID_PC)
{
tree caller = LABEL_SUBR_CONTEXT (current_subr);
if (pending_blocks == NULL_TREE
|| ! LABEL_IN_SUBR (pending_blocks)
|| LABEL_SUBR_START (pending_blocks) == caller)
{
/* Since we are done with this subroutine (i.e. this is the
last ret from it), set up the (so far known) return
address as pending - with the merged type state. */
tmp = LABEL_RETURN_LABELS (current_subr);
current_subr = caller;
int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
tmp = LABEL_RETURN_LABELS (current_subr);
/* FIXME: If we exit a subroutine via a throw, we might
have returned to an earlier caller. Obviously a
"ret" can only return one level, but a throw may
return many levels.*/
current_subr = caller;
if (RETURN_MAP_ADJUSTED (ret_map))
{
/* Since we are done with this subroutine , set up
the (so far known) return address as pending -
with the merged type state. */
for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
{
tree return_label = TREE_VALUE (tmp);
@ -1241,12 +1267,6 @@ verify_jvm_instructions (jcf, byte_ops, length)
}
}
}
break;
case OPCODE_jsr_w:
case OPCODE_ret_w:
default:
error ("unknown opcode %d@pc=%d during verification", op_code, PC-1);
return 0;
}
prevpc = oldpc;