aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/verify.c
diff options
context:
space:
mode:
authorAndrew Haley <aph@cygnus.com>1999-06-21 09:18:50 +0000
committerAndrew Haley <aph@gcc.gnu.org>1999-06-21 09:18:50 +0000
commit44d7502b7841307dda7b87b0fdb7c0761a74eba2 (patch)
tree8136a21782174edaf0486712f17e806c1fad5567 /gcc/java/verify.c
parent60d0536b1edb935829a92be6526393e7c3a31896 (diff)
downloadgcc-44d7502b7841307dda7b87b0fdb7c0761a74eba2.zip
gcc-44d7502b7841307dda7b87b0fdb7c0761a74eba2.tar.gz
gcc-44d7502b7841307dda7b87b0fdb7c0761a74eba2.tar.bz2
except.c (find_handler_in_range): The upper limit for exception ranges is exclusive, not inclusive...
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'. From-SVN: r27658
Diffstat (limited to 'gcc/java/verify.c')
-rw-r--r--gcc/java/verify.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/gcc/java/verify.c b/gcc/java/verify.c
index df3dcac..ead4ea6 100644
--- a/gcc/java/verify.c
+++ b/gcc/java/verify.c
@@ -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;