8035119: Fix exceptions to bytecode verification

Prevent ctor calls to super() and this() from avoidable code (try blocks, if stmts, etc.)

Reviewed-by: coleenp, acorn, mschoene
This commit is contained in:
Harold Seigel 2014-07-14 12:45:14 +04:00
parent afbd45bb8c
commit 13d9244b49
3 changed files with 45 additions and 1 deletions

View file

@ -633,6 +633,9 @@ void ClassVerifier::verify_method(methodHandle m, TRAPS) {
bool no_control_flow = false; // Set to true when there is no direct control
// flow from current instruction to the next
// instruction in sequence
set_furthest_jump(0);
Bytecodes::Code opcode;
while (!bcs.is_last_bytecode()) {
// Check for recursive re-verification before each bytecode.
@ -2248,6 +2251,29 @@ void ClassVerifier::verify_invoke_init(
"Bad <init> method call");
return;
}
// Make sure that this call is not jumped over.
if (bci < furthest_jump()) {
verify_error(ErrorContext::bad_code(bci),
"Bad <init> method call from inside of a branch");
return;
}
// Make sure that this call is not done from within a TRY block because
// that can result in returning an incomplete object. Simply checking
// (bci >= start_pc) also ensures that this call is not done after a TRY
// block. That is also illegal because this call must be the first Java
// statement in the constructor.
ExceptionTable exhandlers(_method());
int exlength = exhandlers.length();
for(int i = 0; i < exlength; i++) {
if (bci >= exhandlers.start_pc(i)) {
verify_error(ErrorContext::bad_code(bci),
"Bad <init> method call from after the start of a try block");
return;
}
}
current_frame->initialize_object(type, current_type());
*this_uninit = true;
} else if (type.is_uninitialized()) {