diff options
-rw-r--r-- | runtime/verifier/method_verifier.cc | 33 | ||||
-rw-r--r-- | test/800-smali/expected.txt | 1 | ||||
-rw-r--r-- | test/800-smali/smali/b_20224106.smali | 16 | ||||
-rw-r--r-- | test/800-smali/src/Main.java | 2 |
4 files changed, 41 insertions, 11 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 6c58d55..f1097d1 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -2406,8 +2406,10 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { case Instruction::INVOKE_DIRECT: case Instruction::INVOKE_DIRECT_RANGE: { bool is_range = (inst->Opcode() == Instruction::INVOKE_DIRECT_RANGE); - mirror::ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_DIRECT, - is_range, false); + mirror::ArtMethod* called_method = VerifyInvocationArgs(inst, + METHOD_DIRECT, + is_range, + false); const char* return_type_descriptor; bool is_constructor; const RegType* return_type = nullptr; @@ -2489,9 +2491,9 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { case Instruction::INVOKE_STATIC_RANGE: { bool is_range = (inst->Opcode() == Instruction::INVOKE_STATIC_RANGE); mirror::ArtMethod* called_method = VerifyInvocationArgs(inst, - METHOD_STATIC, - is_range, - false); + METHOD_STATIC, + is_range, + false); const char* descriptor; if (called_method == nullptr) { uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); @@ -2514,9 +2516,9 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { case Instruction::INVOKE_INTERFACE_RANGE: { bool is_range = (inst->Opcode() == Instruction::INVOKE_INTERFACE_RANGE); mirror::ArtMethod* abs_method = VerifyInvocationArgs(inst, - METHOD_INTERFACE, - is_range, - false); + METHOD_INTERFACE, + is_range, + false); if (abs_method != nullptr) { mirror::Class* called_interface = abs_method->GetDeclaringClass(); if (!called_interface->IsInterface() && !called_interface->IsObjectClass()) { @@ -2886,7 +2888,16 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { if (have_pending_hard_failure_) { if (Runtime::Current()->IsAotCompiler()) { /* When AOT compiling, check that the last failure is a hard failure */ - CHECK_EQ(failures_[failures_.size() - 1], VERIFY_ERROR_BAD_CLASS_HARD); + if (failures_[failures_.size() - 1] != VERIFY_ERROR_BAD_CLASS_HARD) { + LOG(ERROR) << "Pending failures:"; + for (auto& error : failures_) { + LOG(ERROR) << error; + } + for (auto& error_msg : failure_messages_) { + LOG(ERROR) << error_msg->str(); + } + LOG(FATAL) << "Pending hard failure, but last failure not hard."; + } } /* immediate failure, reject class */ info_messages_ << "Rejecting opcode " << inst->DumpString(dex_file_); @@ -3384,13 +3395,13 @@ mirror::ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator(T* it, const if (!src_type.IsIntegralTypes()) { Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register v" << get_reg << " has type " << src_type << " but expected " << reg_type; - return res_method; + return nullptr; } } else if (!work_line_->VerifyRegisterType(this, get_reg, reg_type)) { // Continue on soft failures. We need to find possible hard failures to avoid problems in the // compiler. if (have_pending_hard_failure_) { - return res_method; + return nullptr; } } sig_registers += reg_type.IsLongOrDoubleTypes() ? 2 : 1; diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt index 5922257..a6b216b 100644 --- a/test/800-smali/expected.txt +++ b/test/800-smali/expected.txt @@ -15,4 +15,5 @@ b/18800943 (2) MoveExc MoveExceptionOnEntry EmptySparseSwitch +b/20224106 Done! diff --git a/test/800-smali/smali/b_20224106.smali b/test/800-smali/smali/b_20224106.smali new file mode 100644 index 0000000..78009db --- /dev/null +++ b/test/800-smali/smali/b_20224106.smali @@ -0,0 +1,16 @@ +.class public LB20224106; + +# Test that a hard + soft verifier failure in invoke-interface does not lead to +# an order abort (the last failure must be hard). + +.super Ljava/lang/Object; + +.method public static run(LB20224106;Ljava/lang/Object;)V + .registers 4 + # Two failure points here: + # 1) There is a parameter type mismatch. The formal type is integral (int), but the actual + # type is reference. + # 2) The receiver is not an interface or Object + invoke-interface {v2, v3}, Ljava/net/DatagramSocket;->checkPort(I)V + return-void +.end method diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java index 3e0b1f9..3e88364 100644 --- a/test/800-smali/src/Main.java +++ b/test/800-smali/src/Main.java @@ -79,6 +79,8 @@ public class Main { "moveExceptionOnEntry", new Object[]{0}, new VerifyError(), null)); testCases.add(new TestCase("EmptySparseSwitch", "EmptySparseSwitch", "run", null, null, null)); + testCases.add(new TestCase("b/20224106", "B20224106", "run", null, new VerifyError(), + 0)); } public void runTests() { |