From 92067896c6583d59171dbee9c720a316d63be177 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Tue, 23 Jun 2015 17:45:21 +0100 Subject: [PATCH] Hard-fail get-/put-object to a non-reference field. Bug: 21886894 (cherry picked from commit 414000ec4d728b5c85f8c6dee4f867fecde59b01) Change-Id: Iafc32f0e45d26f3aaa2d521b98353e7cede16c6f --- runtime/verifier/method_verifier.cc | 26 ++++++++++++++++++-------- test/800-smali/expected.txt | 1 + test/800-smali/smali/b_21886894.smali | 15 +++++++++++++++ test/800-smali/src/Main.java | 2 ++ 4 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 test/800-smali/smali/b_21886894.smali diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index bcad9b6f7..89f51158d 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 f2765e114..ca4ca3534 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 000000000..f1ac3e9ff --- /dev/null +++ b/test/800-smali/smali/b_21886894.smali @@ -0,0 +1,15 @@ +.class public LB21886894; +.super Ljava/lang/Object; + +.method public constructor ()V + .registers 2 + invoke-direct {p0}, Ljava/lang/Object;->()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 2faee8f57..8c9fda118 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() { -- 2.11.0