< prev index next >

src/hotspot/share/classfile/verifier.cpp

Print this page
rev 55090 : secret-sfac

*** 1677,1687 **** "Method expects a return value"); return; } // Make sure "this" has been initialized if current method is an // <init>. ! if (_method->name() == vmSymbols::object_initializer_name() && current_frame.flag_this_uninit()) { verify_error(ErrorContext::bad_code(bci), "Constructor must call super() or this() " "before return"); return; --- 1677,1687 ---- "Method expects a return value"); return; } // Make sure "this" has been initialized if current method is an // <init>. ! if (_method->is_object_constructor() && current_frame.flag_this_uninit()) { verify_error(ErrorContext::bad_code(bci), "Constructor must call super() or this() " "before return"); return;
*** 1713,1729 **** case Bytecodes::_invokevirtual : case Bytecodes::_invokespecial : case Bytecodes::_invokestatic : verify_invoke_instructions( &bcs, code_length, &current_frame, (bci >= ex_min && bci < ex_max), ! &this_uninit, return_type, cp, &stackmap_table, CHECK_VERIFY(this)); no_control_flow = false; break; case Bytecodes::_invokeinterface : case Bytecodes::_invokedynamic : verify_invoke_instructions( &bcs, code_length, &current_frame, (bci >= ex_min && bci < ex_max), ! &this_uninit, return_type, cp, &stackmap_table, CHECK_VERIFY(this)); no_control_flow = false; break; case Bytecodes::_new : { index = bcs.get_index_u2(); verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this)); --- 1713,1729 ---- case Bytecodes::_invokevirtual : case Bytecodes::_invokespecial : case Bytecodes::_invokestatic : verify_invoke_instructions( &bcs, code_length, &current_frame, (bci >= ex_min && bci < ex_max), ! &this_uninit, cp, &stackmap_table, CHECK_VERIFY(this)); no_control_flow = false; break; case Bytecodes::_invokeinterface : case Bytecodes::_invokedynamic : verify_invoke_instructions( &bcs, code_length, &current_frame, (bci >= ex_min && bci < ex_max), ! &this_uninit, cp, &stackmap_table, CHECK_VERIFY(this)); no_control_flow = false; break; case Bytecodes::_new : { index = bcs.get_index_u2(); verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));
*** 2817,2827 **** return false; } void ClassVerifier::verify_invoke_instructions( RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame, ! bool in_try_block, bool *this_uninit, VerificationType return_type, const constantPoolHandle& cp, StackMapTable* stackmap_table, TRAPS) { // Make sure the constant pool item is the right type u2 index = bcs->get_index_u2(); Bytecodes::Code opcode = bcs->raw_code(); unsigned int types = 0; --- 2817,2827 ---- return false; } void ClassVerifier::verify_invoke_instructions( RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame, ! bool in_try_block, bool *this_uninit, const constantPoolHandle& cp, StackMapTable* stackmap_table, TRAPS) { // Make sure the constant pool item is the right type u2 index = bcs->get_index_u2(); Bytecodes::Code opcode = bcs->raw_code(); unsigned int types = 0;
*** 2915,2926 **** return; } } if (method_name->char_at(0) == '<') { ! // Make sure <init> can only be invoked by invokespecial ! if (opcode != Bytecodes::_invokespecial || method_name != vmSymbols::object_initializer_name()) { verify_error(ErrorContext::bad_code(bci), "Illegal call to internal method"); return; } --- 2915,2928 ---- return; } } if (method_name->char_at(0) == '<') { ! // Make sure <init> can only be invoked by invokespecial or invokestatic. ! // The allowed invocation mode of <init> depends on its signature. ! if ((opcode != Bytecodes::_invokespecial && ! opcode != Bytecodes::_invokestatic) || method_name != vmSymbols::object_initializer_name()) { verify_error(ErrorContext::bad_code(bci), "Illegal call to internal method"); return; }
*** 2970,2979 **** --- 2972,2982 ---- // Check objectref on operand stack if (opcode != Bytecodes::_invokestatic && opcode != Bytecodes::_invokedynamic) { if (method_name == vmSymbols::object_initializer_name()) { // <init> method + // (use of <init> as a static factory is handled under invokestatic) verify_invoke_init(bcs, index, ref_class_type, current_frame, code_length, in_try_block, this_uninit, cp, stackmap_table, CHECK_VERIFY(this)); if (was_recursively_verified()) return; } else { // other methods
*** 3040,3053 **** } } // Push the result type. int sig_verif_types_len = sig_verif_types->length(); if (sig_verif_types_len > nargs) { // There's a return type ! if (method_name == vmSymbols::object_initializer_name()) { ! // <init> method must have a void return type ! /* Unreachable? Class file parser verifies that methods with '<' have ! * void return */ verify_error(ErrorContext::bad_code(bci), "Return type must be void in <init> method"); return; } --- 3043,3055 ---- } } // Push the result type. int sig_verif_types_len = sig_verif_types->length(); if (sig_verif_types_len > nargs) { // There's a return type ! if (method_name == vmSymbols::object_initializer_name() && ! opcode != Bytecodes::_invokestatic) { ! // an <init> method must have a void return type, unless it's a static factory verify_error(ErrorContext::bad_code(bci), "Return type must be void in <init> method"); return; }
*** 3056,3065 **** --- 3058,3075 ---- for (int i = nargs; i < sig_verif_types_len; i++) { assert(i == nargs || sig_verif_types->at(i).is_long2() || sig_verif_types->at(i).is_double2(), "Unexpected return verificationType"); current_frame->push_stack(sig_verif_types->at(i), CHECK_VERIFY(this)); } + } else { + // an <init> method may not have a void return type, if it's a static factory + if (method_name == vmSymbols::object_initializer_name() && + opcode != Bytecodes::_invokespecial) { + verify_error(ErrorContext::bad_code(bci), + "Return type must be non-void in <init> static factory method"); + return; + } } } VerificationType ClassVerifier::get_newarray_type( u2 index, u2 bci, TRAPS) {
< prev index next >