diff options
-rw-r--r-- | runtime/verifier/method_verifier.cc | 26 | ||||
-rw-r--r-- | test/800-smali/expected.txt | 1 | ||||
-rw-r--r-- | test/800-smali/smali/b_21886894.smali | 15 | ||||
-rw-r--r-- | test/800-smali/src/Main.java | 2 |
4 files changed, 36 insertions, 8 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index bcad9b6..89f5115 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -4006,10 +4006,15 @@ void MethodVerifier::VerifyISFieldAccess(const Instruction* inst, const RegType& VerifyPrimitivePut(*field_type, insn_type, vregA); } else { if (!insn_type.IsAssignableFrom(*field_type)) { - Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << PrettyField(field) - << " to be compatible with type '" << insn_type - << "' but found type '" << *field_type - << "' in put-object"; + // If the field type is not a reference, this is a global failure rather than + // a class change failure as the instructions and the descriptors for the type + // should have been consistent within the same file at compile time. + VerifyError error = field_type->IsReferenceTypes() ? VERIFY_ERROR_BAD_CLASS_SOFT + : VERIFY_ERROR_BAD_CLASS_HARD; + Fail(error) << "expected field " << PrettyField(field) + << " to be compatible with type '" << insn_type + << "' but found type '" << *field_type + << "' in put-object"; return; } work_line_->VerifyRegisterType(this, vregA, *field_type); @@ -4033,10 +4038,15 @@ void MethodVerifier::VerifyISFieldAccess(const Instruction* inst, const RegType& } } else { if (!insn_type.IsAssignableFrom(*field_type)) { - Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << PrettyField(field) - << " to be compatible with type '" << insn_type - << "' but found type '" << *field_type - << "' in get-object"; + // If the field type is not a reference, this is a global failure rather than + // a class change failure as the instructions and the descriptors for the type + // should have been consistent within the same file at compile time. + VerifyError error = field_type->IsReferenceTypes() ? VERIFY_ERROR_BAD_CLASS_SOFT + : VERIFY_ERROR_BAD_CLASS_HARD; + Fail(error) << "expected field " << PrettyField(field) + << " to be compatible with type '" << insn_type + << "' but found type '" << *field_type + << "' in get-object"; work_line_->SetRegisterType(this, vregA, reg_types_.Conflict()); return; } diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt index f2765e1..ca4ca35 100644 --- a/test/800-smali/expected.txt +++ b/test/800-smali/expected.txt @@ -20,4 +20,5 @@ b/21873167 b/21614284 b/21902684 b/21863767 +b/21886894 Done! diff --git a/test/800-smali/smali/b_21886894.smali b/test/800-smali/smali/b_21886894.smali new file mode 100644 index 0000000..f1ac3e9 --- /dev/null +++ b/test/800-smali/smali/b_21886894.smali @@ -0,0 +1,15 @@ +.class public LB21886894; +.super Ljava/lang/Object; + +.method public constructor <init>()V + .registers 2 + invoke-direct {p0}, Ljava/lang/Object;-><init>()V + return-void +.end method + +.method public test()V + .registers 2 + const v0, 0 + iput-object v0, p0, Lsome/unresolved/Type;->a:I + return-void +.end method diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java index 2faee8f..8c9fda1 100644 --- a/test/800-smali/src/Main.java +++ b/test/800-smali/src/Main.java @@ -87,6 +87,8 @@ public class Main { testCases.add(new TestCase("b/21902684", "B21902684", "test", null, null, null)); testCases.add(new TestCase("b/21863767", "B21863767", "run", null, null, null)); + testCases.add(new TestCase("b/21886894", "B21886894", "test", null, new VerifyError(), + null)); } public void runTests() { |