diff options
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 5 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.cc | 6 | ||||
-rw-r--r-- | runtime/verifier/verifier_compiler_binding.h | 1 |
3 files changed, 9 insertions, 3 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index cd03e054b5..76ee456b55 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -957,6 +957,11 @@ static ArtMethod* ResolveMethod(uint16_t method_idx, resolved_method, class_linker->GetImagePointerSize()); } else { uint16_t vtable_index = resolved_method->GetMethodIndex(); + if (vtable_index >= static_cast<uint32_t>( + compiling_class->GetSuperClass()->GetVTableLength())) { + // No super method. The runtime will throw a NoSuchMethodError. + return nullptr; + } actual_method = compiling_class->GetSuperClass()->GetVTableEntry( vtable_index, class_linker->GetImagePointerSize()); } diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 1ea2c8c22e..4bebbcc24a 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -5169,15 +5169,14 @@ MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self, } // Return whether the runtime knows how to execute a method without needing to -// re-verify it at runtime (and therefore save on first use of the class). We -// currently only support it for access checks, where the runtime will mark the -// methods as needing access checks and have the interpreter execute with them. +// re-verify it at runtime (and therefore save on first use of the class). // The AOT/JIT compiled code is not affected. static inline bool CanRuntimeHandleVerificationFailure(uint32_t encountered_failure_types) { constexpr uint32_t unresolved_mask = verifier::VerifyError::VERIFY_ERROR_CLASS_CHANGE | verifier::VerifyError::VERIFY_ERROR_ACCESS_CLASS | verifier::VerifyError::VERIFY_ERROR_ACCESS_FIELD | + verifier::VerifyError::VERIFY_ERROR_NO_METHOD | verifier::VerifyError::VERIFY_ERROR_ACCESS_METHOD; return (encountered_failure_types & (~unresolved_mask)) == 0; } @@ -5542,6 +5541,7 @@ std::ostream& MethodVerifier::Fail(VerifyError error, bool pending_exc) { if (IsAotMode() || !can_load_classes_) { if (error != VERIFY_ERROR_ACCESS_CLASS && error != VERIFY_ERROR_ACCESS_FIELD && + error != VERIFY_ERROR_NO_METHOD && error != VERIFY_ERROR_ACCESS_METHOD) { // If we're optimistically running verification at compile time, turn NO_xxx, // class change and instantiation errors into soft verification errors so that we diff --git a/runtime/verifier/verifier_compiler_binding.h b/runtime/verifier/verifier_compiler_binding.h index d39f98ddde..a92a063fe6 100644 --- a/runtime/verifier/verifier_compiler_binding.h +++ b/runtime/verifier/verifier_compiler_binding.h @@ -29,6 +29,7 @@ ALWAYS_INLINE static inline bool CanCompilerHandleVerificationFailure(uint32_t encountered_failure_types) { constexpr uint32_t unresolved_mask = verifier::VerifyError::VERIFY_ERROR_NO_CLASS | verifier::VerifyError::VERIFY_ERROR_CLASS_CHANGE + | verifier::VerifyError::VERIFY_ERROR_NO_METHOD | verifier::VerifyError::VERIFY_ERROR_ACCESS_CLASS | verifier::VerifyError::VERIFY_ERROR_ACCESS_FIELD | verifier::VerifyError::VERIFY_ERROR_ACCESS_METHOD; |