summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/class_linker.cc3
-rw-r--r--runtime/entrypoints/entrypoint_utils-inl.h26
-rw-r--r--test/Android.run-test.mk1
3 files changed, 27 insertions, 3 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index c80f91a7b8..e4f492b221 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4104,9 +4104,10 @@ ArtMethod* ClassLinker::FindMethodForProxy(mirror::Class* proxy_class, ArtMethod
void ClassLinker::CreateProxyConstructor(Handle<mirror::Class> klass, ArtMethod* out) {
// Create constructor for Proxy that must initialize the method.
- CHECK_EQ(GetClassRoot(kJavaLangReflectProxy)->NumDirectMethods(), 19u);
+ CHECK_EQ(GetClassRoot(kJavaLangReflectProxy)->NumDirectMethods(), 18u);
ArtMethod* proxy_constructor = GetClassRoot(kJavaLangReflectProxy)->GetDirectMethodUnchecked(
2, image_pointer_size_);
+ DCHECK_EQ(std::string(proxy_constructor->GetName()), "<init>");
// Ensure constructor is in dex cache so that we can use the dex cache to look up the overridden
// constructor method.
GetClassRoot(kJavaLangReflectProxy)->GetDexCache()->SetResolvedMethod(
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 0663b7ef78..51611753c8 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -316,7 +316,31 @@ inline ArtField* FindFieldFromCode(uint32_t field_idx, ArtMethod* referrer,
default: is_primitive = true; is_set = true; is_static = true; break;
}
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- ArtField* resolved_field = class_linker->ResolveField(field_idx, referrer, is_static);
+
+ ArtField* resolved_field;
+ if (access_check) {
+ // Slow path: According to JLS 13.4.8, a linkage error may occur if a compile-time
+ // qualifying type of a field and the resolved run-time qualifying type of a field differed
+ // in their static-ness.
+ //
+ // In particular, don't assume the dex instruction already correctly knows if the
+ // real field is static or not. The resolution must not be aware of this.
+ ArtMethod* method = referrer->GetInterfaceMethodIfProxy(sizeof(void*));
+
+ StackHandleScope<2> hs(self);
+ Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(method->GetDexCache()));
+ Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(method->GetClassLoader()));
+
+ resolved_field = class_linker->ResolveFieldJLS(*method->GetDexFile(),
+ field_idx,
+ h_dex_cache,
+ h_class_loader);
+ } else {
+ // Fast path: Verifier already would've called ResolveFieldJLS and we wouldn't
+ // be executing here if there was a static/non-static mismatch.
+ resolved_field = class_linker->ResolveField(field_idx, referrer, is_static);
+ }
+
if (UNLIKELY(resolved_field == nullptr)) {
DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
return nullptr; // Failure.
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index e48694c4a5..870b51468a 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -302,7 +302,6 @@ TEST_ART_BROKEN_NO_RELOCATE_TESTS :=
# Temporarily disable some broken tests when forcing access checks in interpreter b/22414682
TEST_ART_BROKEN_INTERPRETER_ACCESS_CHECK_TESTS := \
- 073-mismatched-field \
135-MirandaDispatch \
137-cfi \
412-new-array \