Mercurial > hg > truffle
diff src/share/vm/classfile/verifier.cpp @ 20204:d22136881b85
Merge
author | robm |
---|---|
date | Thu, 17 Jul 2014 18:03:26 +0100 |
parents | ce8f6bb717c9 d6fcbd1e1075 |
children | d14a18794c90 |
line wrap: on
line diff
--- a/src/share/vm/classfile/verifier.cpp Wed Jul 16 16:45:17 2014 -0700 +++ b/src/share/vm/classfile/verifier.cpp Thu Jul 17 18:03:26 2014 +0100 @@ -633,6 +633,9 @@ 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 @@ "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()) { @@ -2283,18 +2309,20 @@ ref_class_type.name(), CHECK_VERIFY(this)); Method* m = InstanceKlass::cast(ref_klass)->uncached_lookup_method( vmSymbols::object_initializer_name(), - cp->signature_ref_at(bcs->get_index_u2()), - Klass::normal); - instanceKlassHandle mh(THREAD, m->method_holder()); - if (m->is_protected() && !mh->is_same_class_package(_klass())) { - bool assignable = current_type().is_assignable_from( - objectref_type, this, CHECK_VERIFY(this)); - if (!assignable) { - verify_error(ErrorContext::bad_type(bci, - TypeOrigin::cp(new_class_index, objectref_type), - TypeOrigin::implicit(current_type())), - "Bad access to protected <init> method"); - return; + cp->signature_ref_at(bcs->get_index_u2()), Klass::normal); + // Do nothing if method is not found. Let resolution detect the error. + if (m != NULL) { + instanceKlassHandle mh(THREAD, m->method_holder()); + if (m->is_protected() && !mh->is_same_class_package(_klass())) { + bool assignable = current_type().is_assignable_from( + objectref_type, this, CHECK_VERIFY(this)); + if (!assignable) { + verify_error(ErrorContext::bad_type(bci, + TypeOrigin::cp(new_class_index, objectref_type), + TypeOrigin::implicit(current_type())), + "Bad access to protected <init> method"); + return; + } } } }