summaryrefslogtreecommitdiff
path: root/runtime/verifier/method_verifier.cc
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2016-04-12 15:50:55 -0700
committer Alex Light <allight@google.com> 2016-04-13 21:12:42 +0000
commitb55f1ac873f9541f391625c13fe9129fbd38e74c (patch)
tree996e696a06437f93c6f87e773e76d9e3c6a4fe8a /runtime/verifier/method_verifier.cc
parent336dd6a0989dafb356be5f689028d983b0931335 (diff)
Allow private methods in interfaces.
Private methods may be generated in interfaces during compilation of some default methods. Change the verifier to allow these methods. Bug: 27999840 Change-Id: Ib8120a8f6cb036021334d9af0ed78ae372974ecb
Diffstat (limited to 'runtime/verifier/method_verifier.cc')
-rw-r--r--runtime/verifier/method_verifier.cc18
1 files changed, 14 insertions, 4 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 83da6b7b4e..d5319fdb0c 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -790,9 +790,16 @@ bool MethodVerifier::Verify() {
} else if (method_access_flags_ & kAccFinal) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have final methods";
return false;
- } else if (!(method_access_flags_ & kAccPublic)) {
- Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have non-public members";
- return false;
+ } else {
+ uint32_t access_flag_options = kAccPublic;
+ if (dex_file_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
+ access_flag_options |= kAccPrivate;
+ }
+ if (!(method_access_flags_ & access_flag_options)) {
+ Fail(VERIFY_ERROR_BAD_CLASS_HARD)
+ << "interfaces may not have protected or package-private members";
+ return false;
+ }
}
}
}
@@ -3794,9 +3801,12 @@ ArtMethod* MethodVerifier::ResolveMethodAndCheckAccess(
// Note: this check must be after the initializer check, as those are required to fail a class,
// while this check implies an IncompatibleClassChangeError.
if (klass->IsInterface()) {
- // methods called on interfaces should be invoke-interface, invoke-super, or invoke-static.
+ // methods called on interfaces should be invoke-interface, invoke-super, invoke-direct (if
+ // dex file version is 37 or greater), or invoke-static.
if (method_type != METHOD_INTERFACE &&
method_type != METHOD_STATIC &&
+ ((dex_file_->GetVersion() < DexFile::kDefaultMethodsVersion) ||
+ method_type != METHOD_DIRECT) &&
method_type != METHOD_SUPER) {
Fail(VERIFY_ERROR_CLASS_CHANGE)
<< "non-interface method " << PrettyMethod(dex_method_idx, *dex_file_)