ART: Fix hidden hard fail in instance field verification
Move the reference type check for the given object upfront so that
it isn't hidden by other soft-fail cases.
Bug: 122501785
Test: m test-art-host
Test: art/test/testrunner/testrunner.py -b --host -t 800
Change-Id: I715a859665a9550bc23defa63ba6fbecd13d7531
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 32cd47a..79b3178 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -4692,6 +4692,12 @@
template <bool kVerifierDebug>
ArtField* MethodVerifier<kVerifierDebug>::GetInstanceField(const RegType& obj_type, int field_idx) {
+ if (!obj_type.IsZeroOrNull() && !obj_type.IsReferenceTypes()) {
+ // Trying to read a field from something that isn't a reference.
+ Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has "
+ << "non-reference type " << obj_type;
+ return nullptr;
+ }
const dex::FieldId& field_id = dex_file_->GetFieldId(field_idx);
// Check access to class.
const RegType& klass_type = ResolveClass<CheckAccess::kYes>(field_id.class_idx_);
@@ -4725,11 +4731,6 @@
} else if (obj_type.IsZeroOrNull()) {
// Cannot infer and check type, however, access will cause null pointer exception.
// Fall through into a few last soft failure checks below.
- } else if (!obj_type.IsReferenceTypes()) {
- // Trying to read a field from something that isn't a reference.
- Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has "
- << "non-reference type " << obj_type;
- return nullptr;
} else {
std::string temp;
ObjPtr<mirror::Class> klass = field->GetDeclaringClass();
diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt
index 291de72..63859fe 100644
--- a/test/800-smali/expected.txt
+++ b/test/800-smali/expected.txt
@@ -74,4 +74,5 @@
b/31313170
ConstClassAliasing
b/121191566
+b/122501785
Done!
diff --git a/test/800-smali/smali/b_122501785.smali b/test/800-smali/smali/b_122501785.smali
new file mode 100644
index 0000000..240aad9
--- /dev/null
+++ b/test/800-smali/smali/b_122501785.smali
@@ -0,0 +1,14 @@
+.class public LB122501785;
+
+# Test that a hard + soft verifier failure in instance field access
+# correctly triggers the hard fail to protect the compiler.
+
+.super Ljava/lang/Object;
+
+.method public static run(LB122501785;Ljava/lang/Object;)V
+ .registers 4
+ const/4 v0, 0
+ const/4 v1, 1
+ iput-boolean v0, v1, Ldoes/not/Exist;->field:Z
+ return-void
+.end method
diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java
index d7979e1..d10fdf1 100644
--- a/test/800-smali/src/Main.java
+++ b/test/800-smali/src/Main.java
@@ -195,6 +195,8 @@
null, true));
testCases.add(new TestCase("b/121191566", "B121191566", "run", new Object[] { "a" }, null,
true, false));
+ testCases.add(new TestCase("b/122501785", "B122501785", "run", null, new VerifyError(),
+ 0));
}
public void runTests() {