summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/verifier/method_verifier.cc33
-rw-r--r--test/800-smali/expected.txt1
-rw-r--r--test/800-smali/smali/b_20224106.smali16
-rw-r--r--test/800-smali/src/Main.java2
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() {