Workaround for b/160292234.
Resolve the type if not found before invoking CheckInvokeClassMismatch.
Test: test.py
Bug: 160292234
Bug: 73760543
Change-Id: Ia8ae4c2fff19af758b5bb7586a13b76972f50711
Merged-In: Ia8ae4c2fff19af758b5bb7586a13b76972f50711
(cherry picked from commit 28d0a1dd26bad8a0542d167d148a7f4c9fe66c21)
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 2732de5..b3aecde 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -368,10 +368,26 @@
type);
} else if (kResolveMode == ResolveMode::kCheckICCEAndIAE) {
referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_);
+ const dex::MethodId& method_id = referrer->GetDexFile()->GetMethodId(method_idx);
+ ObjPtr<mirror::Class> cls =
+ LookupResolvedType(method_id.class_idx_,
+ referrer->GetDexCache(),
+ referrer->GetClassLoader());
+ if (cls == nullptr) {
+ // The verifier breaks the invariant that a resolved method must have its
+ // class in the class table, so resolve the type in case we haven't found it.
+ // b/73760543
+ StackHandleScope<2> hs(Thread::Current());
+ Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(referrer->GetDexCache()));
+ Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(referrer->GetClassLoader()));
+ cls = ResolveType(method_id.class_idx_, h_dex_cache, h_class_loader);
+ if (hs.Self()->IsExceptionPending()) {
+ return nullptr;
+ }
+ }
// Check if the invoke type matches the class type.
- ObjPtr<mirror::DexCache> dex_cache = referrer->GetDexCache();
- ObjPtr<mirror::ClassLoader> class_loader = referrer->GetClassLoader();
- if (CheckInvokeClassMismatch</* kThrow= */ true>(dex_cache, type, method_idx, class_loader)) {
+ if (CheckInvokeClassMismatch</* kThrow= */ true>(
+ referrer->GetDexCache(), type, [cls]() { return cls; })) {
DCHECK(Thread::Current()->IsExceptionPending());
return nullptr;
}
@@ -379,7 +395,7 @@
ObjPtr<mirror::Class> referring_class = referrer->GetDeclaringClass();
if (!referring_class->CheckResolvedMethodAccess(resolved_method->GetDeclaringClass(),
resolved_method,
- dex_cache,
+ referrer->GetDexCache(),
method_idx,
type)) {
DCHECK(Thread::Current()->IsExceptionPending());