blob: 5c6b815ad53c79d6b391e9644927c68eb2ba0e24 [file] [log] [blame]
David Brazdilca3c8c32016-09-06 14:04:48 +01001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Nicolas Geoffray08025182016-10-25 17:20:18 +010017// Test is in compiler, as it uses compiler related code.
18#include "verifier/verifier_deps.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010019
Andreas Gampec6ea7d02017-02-01 16:46:28 -080020#include "art_method-inl.h"
David Sehr9c4a0152018-04-05 12:23:54 -070021#include "base/indenter.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010022#include "class_linker.h"
Andreas Gamped9911ee2017-03-27 13:27:24 -070023#include "common_compiler_test.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010024#include "compiler_callbacks.h"
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -070025#include "dex/class_accessor-inl.h"
26#include "dex/class_iterator.h"
David Sehr9e734c72018-01-04 17:56:19 -080027#include "dex/dex_file-inl.h"
28#include "dex/dex_file_types.h"
Andreas Gamped9911ee2017-03-27 13:27:24 -070029#include "dex/verification_results.h"
30#include "dex/verified_method.h"
Andreas Gamped482e732017-04-24 17:59:09 -070031#include "driver/compiler_driver-inl.h"
Andreas Gamped9911ee2017-03-27 13:27:24 -070032#include "driver/compiler_options.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010033#include "handle_scope-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010034#include "mirror/class_loader.h"
35#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070036#include "scoped_thread_state_change-inl.h"
Andreas Gampe6d7abbd2017-04-24 13:19:09 -070037#include "thread.h"
Mathieu Chartier93764b82017-07-17 14:51:53 -070038#include "utils/atomic_dex_ref_map-inl.h"
Andreas Gampe6d7abbd2017-04-24 13:19:09 -070039#include "verifier/method_verifier-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010040
41namespace art {
42namespace verifier {
43
44class VerifierDepsCompilerCallbacks : public CompilerCallbacks {
45 public:
Igor Murashkin2ffb7032017-11-08 13:35:21 -080046 VerifierDepsCompilerCallbacks()
David Brazdilca3c8c32016-09-06 14:04:48 +010047 : CompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp),
48 deps_(nullptr) {}
49
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010050 void MethodVerified(verifier::MethodVerifier* verifier ATTRIBUTE_UNUSED) override {}
51 void ClassRejected(ClassReference ref ATTRIBUTE_UNUSED) override {}
David Brazdilca3c8c32016-09-06 14:04:48 +010052
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010053 verifier::VerifierDeps* GetVerifierDeps() const override { return deps_; }
Andreas Gampefa6a1b02018-09-07 08:11:55 -070054 void SetVerifierDeps(verifier::VerifierDeps* deps) override { deps_ = deps; }
David Brazdilca3c8c32016-09-06 14:04:48 +010055
56 private:
57 verifier::VerifierDeps* deps_;
58};
59
Nicolas Geoffray08025182016-10-25 17:20:18 +010060class VerifierDepsTest : public CommonCompilerTest {
David Brazdilca3c8c32016-09-06 14:04:48 +010061 public:
Andreas Gampefa6a1b02018-09-07 08:11:55 -070062 void SetUpRuntimeOptions(RuntimeOptions* options) override {
Nicolas Geoffray08025182016-10-25 17:20:18 +010063 CommonCompilerTest::SetUpRuntimeOptions(options);
David Brazdilca3c8c32016-09-06 14:04:48 +010064 callbacks_.reset(new VerifierDepsCompilerCallbacks());
65 }
66
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010067 ObjPtr<mirror::Class> FindClassByName(ScopedObjectAccess& soa, const std::string& name)
David Brazdilca3c8c32016-09-06 14:04:48 +010068 REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010069 StackHandleScope<1> hs(soa.Self());
David Brazdilca3c8c32016-09-06 14:04:48 +010070 Handle<mirror::ClassLoader> class_loader_handle(
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010071 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
72 ObjPtr<mirror::Class> klass =
73 class_linker_->FindClass(soa.Self(), name.c_str(), class_loader_handle);
David Brazdil6f82fbd2016-09-14 11:55:26 +010074 if (klass == nullptr) {
Vladimir Markoa8bba7d2018-05-30 15:18:48 +010075 DCHECK(soa.Self()->IsExceptionPending());
76 soa.Self()->ClearException();
David Brazdil6f82fbd2016-09-14 11:55:26 +010077 }
78 return klass;
79 }
80
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000081 void SetupCompilerDriver() {
Vladimir Marko9c4b9702018-11-14 15:09:02 +000082 compiler_options_->image_type_ = CompilerOptions::ImageType::kNone;
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000083 compiler_driver_->InitializeThreadPools();
84 }
85
Andreas Gampe3db70682018-12-26 15:12:03 -080086 void VerifyWithCompilerDriver(verifier::VerifierDeps* verifier_deps) {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000087 TimingLogger timings("Verify", false, false);
88 // The compiler driver handles the verifier deps in the callbacks, so
89 // remove what this class did for unit testing.
Andreas Gampe3db70682018-12-26 15:12:03 -080090 if (verifier_deps == nullptr) {
Mathieu Chartier72041a02017-07-14 18:23:25 -070091 // Create some verifier deps by default if they are not already specified.
Andreas Gampe3db70682018-12-26 15:12:03 -080092 verifier_deps = new verifier::VerifierDeps(dex_files_);
93 verifier_deps_.reset(verifier_deps);
Mathieu Chartier72041a02017-07-14 18:23:25 -070094 }
Andreas Gampe3db70682018-12-26 15:12:03 -080095 callbacks_->SetVerifierDeps(verifier_deps);
Vladimir Marko2afaff72018-11-30 17:01:50 +000096 compiler_driver_->Verify(class_loader_, dex_files_, &timings, verification_results_.get());
Nicolas Geoffrayb0bbe8e2016-11-19 10:42:37 +000097 callbacks_->SetVerifierDeps(nullptr);
Nicolas Geoffray1d0ae3f2016-12-06 13:40:16 +000098 // Clear entries in the verification results to avoid hitting a DCHECK that
99 // we always succeed inserting a new entry after verifying.
Mathieu Chartierfc8b4222017-09-17 13:44:24 -0700100 AtomicDexRefMap<MethodReference, const VerifiedMethod*>* map =
Vladimir Marko2afaff72018-11-30 17:01:50 +0000101 &verification_results_->atomic_verified_methods_;
Mathieu Chartier93764b82017-07-17 14:51:53 -0700102 map->Visit([](const DexFileReference& ref ATTRIBUTE_UNUSED, const VerifiedMethod* method) {
Nicolas Geoffray1d0ae3f2016-12-06 13:40:16 +0000103 delete method;
104 });
105 map->ClearEntries();
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000106 }
107
David Brazdil6f82fbd2016-09-14 11:55:26 +0100108 void SetVerifierDeps(const std::vector<const DexFile*>& dex_files) {
109 verifier_deps_.reset(new verifier::VerifierDeps(dex_files));
110 VerifierDepsCompilerCallbacks* callbacks =
111 reinterpret_cast<VerifierDepsCompilerCallbacks*>(callbacks_.get());
112 callbacks->SetVerifierDeps(verifier_deps_.get());
David Brazdilca3c8c32016-09-06 14:04:48 +0100113 }
114
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100115 void LoadDexFile(ScopedObjectAccess& soa, const char* name1, const char* name2 = nullptr)
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100116 REQUIRES_SHARED(Locks::mutator_lock_) {
117 class_loader_ = (name2 == nullptr) ? LoadDex(name1) : LoadMultiDex(name1, name2);
118 dex_files_ = GetDexFiles(class_loader_);
119 primary_dex_file_ = dex_files_.front();
120
121 SetVerifierDeps(dex_files_);
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100122 StackHandleScope<1> hs(soa.Self());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100123 Handle<mirror::ClassLoader> loader =
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100124 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_));
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100125 for (const DexFile* dex_file : dex_files_) {
126 class_linker_->RegisterDexFile(*dex_file, loader.Get());
127 }
Nicolas Geoffray1d0ae3f2016-12-06 13:40:16 +0000128 for (const DexFile* dex_file : dex_files_) {
Vladimir Marko2afaff72018-11-30 17:01:50 +0000129 verification_results_->AddDexFile(dex_file);
Nicolas Geoffray1d0ae3f2016-12-06 13:40:16 +0000130 }
Vladimir Marko213ee2d2018-06-22 11:56:34 +0100131 SetDexFilesForOatFile(dex_files_);
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100132 }
133
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100134 void LoadDexFile(ScopedObjectAccess& soa) REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100135 LoadDexFile(soa, "VerifierDeps");
136 CHECK_EQ(dex_files_.size(), 1u);
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100137 klass_Main_ = FindClassByName(soa, "LMain;");
David Brazdilca3c8c32016-09-06 14:04:48 +0100138 CHECK(klass_Main_ != nullptr);
David Brazdilca3c8c32016-09-06 14:04:48 +0100139 }
140
141 bool VerifyMethod(const std::string& method_name) {
142 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100143 LoadDexFile(soa);
David Brazdilca3c8c32016-09-06 14:04:48 +0100144
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100145 StackHandleScope<2> hs(soa.Self());
David Brazdilca3c8c32016-09-06 14:04:48 +0100146 Handle<mirror::ClassLoader> class_loader_handle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700147 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
David Brazdilca3c8c32016-09-06 14:04:48 +0100148 Handle<mirror::DexCache> dex_cache_handle(hs.NewHandle(klass_Main_->GetDexCache()));
149
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800150 const dex::ClassDef* class_def = klass_Main_->GetClassDef();
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700151 ClassAccessor accessor(*primary_dex_file_, *class_def);
David Brazdilca3c8c32016-09-06 14:04:48 +0100152
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700153 bool has_failures = true;
154 bool found_method = false;
David Brazdilca3c8c32016-09-06 14:04:48 +0100155
Mathieu Chartier0d896bd2018-05-25 00:20:27 -0700156 for (const ClassAccessor::Method& method : accessor.GetMethods()) {
Vladimir Markoba118822017-06-12 15:41:56 +0100157 ArtMethod* resolved_method =
158 class_linker_->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700159 method.GetIndex(),
Vladimir Markoba118822017-06-12 15:41:56 +0100160 dex_cache_handle,
161 class_loader_handle,
Andreas Gampe3db70682018-12-26 15:12:03 -0800162 /* referrer= */ nullptr,
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700163 method.GetInvokeType(class_def->access_flags_));
David Brazdilca3c8c32016-09-06 14:04:48 +0100164 CHECK(resolved_method != nullptr);
165 if (method_name == resolved_method->GetName()) {
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700166 soa.Self()->SetVerifierDeps(callbacks_->GetVerifierDeps());
167 MethodVerifier verifier(soa.Self(),
168 primary_dex_file_,
169 dex_cache_handle,
170 class_loader_handle,
171 *class_def,
172 method.GetCodeItem(),
173 method.GetIndex(),
174 resolved_method,
175 method.GetAccessFlags(),
Andreas Gampe3db70682018-12-26 15:12:03 -0800176 /* can_load_classes= */ true,
177 /* allow_soft_failures= */ true,
178 /* need_precise_constants= */ true,
179 /* verify to dump */ false,
180 /* allow_thread_suspension= */ true,
181 /* api_level= */ 0);
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700182 verifier.Verify();
183 soa.Self()->SetVerifierDeps(nullptr);
184 has_failures = verifier.HasFailures();
185 found_method = true;
David Brazdilca3c8c32016-09-06 14:04:48 +0100186 }
Mathieu Chartier0d896bd2018-05-25 00:20:27 -0700187 }
Mathieu Chartierc8c8d5f2018-05-22 11:56:14 -0700188 CHECK(found_method) << "Expected to find method " << method_name;
189 return !has_failures;
David Brazdilca3c8c32016-09-06 14:04:48 +0100190 }
191
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100192 void VerifyDexFile(const char* multidex = nullptr) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100193 {
194 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100195 LoadDexFile(soa, "VerifierDeps", multidex);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100196 }
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000197 SetupCompilerDriver();
Andreas Gampe3db70682018-12-26 15:12:03 -0800198 VerifyWithCompilerDriver(/* verifier_deps= */ nullptr);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100199 }
200
David Brazdilca3c8c32016-09-06 14:04:48 +0100201 bool TestAssignabilityRecording(const std::string& dst,
202 const std::string& src,
203 bool is_strict,
204 bool is_assignable) {
205 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100206 LoadDexFile(soa);
207 StackHandleScope<1> hs(soa.Self());
208 Handle<mirror::Class> klass_dst = hs.NewHandle(FindClassByName(soa, dst));
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100209 DCHECK(klass_dst != nullptr) << dst;
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100210 ObjPtr<mirror::Class> klass_src = FindClassByName(soa, src);
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100211 DCHECK(klass_src != nullptr) << src;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100212 verifier_deps_->AddAssignability(*primary_dex_file_,
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100213 klass_dst.Get(),
David Brazdil6f82fbd2016-09-14 11:55:26 +0100214 klass_src,
David Brazdilca3c8c32016-09-06 14:04:48 +0100215 is_strict,
216 is_assignable);
217 return true;
218 }
219
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000220 // Check that the status of classes in `class_loader_` match the
221 // expected status in `deps`.
222 void VerifyClassStatus(const verifier::VerifierDeps& deps) {
223 ScopedObjectAccess soa(Thread::Current());
224 StackHandleScope<2> hs(soa.Self());
225 Handle<mirror::ClassLoader> class_loader_handle(
226 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
227 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
228 for (const DexFile* dex_file : dex_files_) {
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700229 const std::set<dex::TypeIndex>& unverified_classes = deps.GetUnverifiedClasses(*dex_file);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000230 for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800231 const dex::ClassDef& class_def = dex_file->GetClassDef(i);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000232 const char* descriptor = dex_file->GetClassDescriptor(class_def);
233 cls.Assign(class_linker_->FindClass(soa.Self(), descriptor, class_loader_handle));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800234 if (cls == nullptr) {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000235 CHECK(soa.Self()->IsExceptionPending());
236 soa.Self()->ClearException();
Andreas Gampebb30d5d2018-04-23 09:59:25 -0700237 } else if (&cls->GetDexFile() != dex_file) {
238 // Ignore classes from different dex files.
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700239 } else if (unverified_classes.find(class_def.class_idx_) == unverified_classes.end()) {
Vladimir Marko2c64a832018-01-04 11:31:56 +0000240 ASSERT_EQ(cls->GetStatus(), ClassStatus::kVerified);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000241 } else {
Vladimir Marko2c64a832018-01-04 11:31:56 +0000242 ASSERT_LT(cls->GetStatus(), ClassStatus::kVerified);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000243 }
244 }
245 }
246 }
247
Nicolas Geoffray08025182016-10-25 17:20:18 +0100248 bool HasUnverifiedClass(const std::string& cls) {
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +0000249 return HasUnverifiedClass(cls, *primary_dex_file_);
250 }
251
252 bool HasUnverifiedClass(const std::string& cls, const DexFile& dex_file) {
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800253 const dex::TypeId* type_id = dex_file.FindTypeId(cls.c_str());
Nicolas Geoffray08025182016-10-25 17:20:18 +0100254 DCHECK(type_id != nullptr);
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +0000255 dex::TypeIndex index = dex_file.GetIndexForTypeId(*type_id);
Nicolas Geoffray08025182016-10-25 17:20:18 +0100256 for (const auto& dex_dep : verifier_deps_->dex_deps_) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800257 for (dex::TypeIndex entry : dex_dep.second->unverified_classes_) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100258 if (index == entry) {
259 return true;
260 }
261 }
262 }
263 return false;
264 }
265
David Brazdilca3c8c32016-09-06 14:04:48 +0100266 // Iterates over all assignability records and tries to find an entry which
267 // matches the expected destination/source pair.
268 bool HasAssignable(const std::string& expected_destination,
269 const std::string& expected_source,
270 bool expected_is_assignable) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100271 for (auto& dex_dep : verifier_deps_->dex_deps_) {
272 const DexFile& dex_file = *dex_dep.first;
273 auto& storage = expected_is_assignable ? dex_dep.second->assignable_types_
274 : dex_dep.second->unassignable_types_;
275 for (auto& entry : storage) {
276 std::string actual_destination =
277 verifier_deps_->GetStringFromId(dex_file, entry.GetDestination());
278 std::string actual_source = verifier_deps_->GetStringFromId(dex_file, entry.GetSource());
279 if ((expected_destination == actual_destination) && (expected_source == actual_source)) {
280 return true;
281 }
282 }
283 }
284 return false;
285 }
286
287 // Iterates over all class resolution records, finds an entry which matches
288 // the given class descriptor and tests its properties.
289 bool HasClass(const std::string& expected_klass,
290 bool expected_resolved,
291 const std::string& expected_access_flags = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100292 for (auto& dex_dep : verifier_deps_->dex_deps_) {
293 for (auto& entry : dex_dep.second->classes_) {
294 if (expected_resolved != entry.IsResolved()) {
295 continue;
296 }
297
298 std::string actual_klass = dex_dep.first->StringByTypeIdx(entry.GetDexTypeIndex());
299 if (expected_klass != actual_klass) {
300 continue;
301 }
302
303 if (expected_resolved) {
304 // Test access flags. Note that PrettyJavaAccessFlags always appends
305 // a space after the modifiers. Add it to the expected access flags.
306 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
307 if (expected_access_flags + " " != actual_access_flags) {
308 continue;
309 }
310 }
311
312 return true;
313 }
314 }
315 return false;
316 }
317
318 // Iterates over all field resolution records, finds an entry which matches
319 // the given field class+name+type and tests its properties.
320 bool HasField(const std::string& expected_klass,
321 const std::string& expected_name,
322 const std::string& expected_type,
323 bool expected_resolved,
324 const std::string& expected_access_flags = "",
325 const std::string& expected_decl_klass = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100326 for (auto& dex_dep : verifier_deps_->dex_deps_) {
327 for (auto& entry : dex_dep.second->fields_) {
328 if (expected_resolved != entry.IsResolved()) {
329 continue;
330 }
331
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800332 const dex::FieldId& field_id = dex_dep.first->GetFieldId(entry.GetDexFieldIndex());
David Brazdilca3c8c32016-09-06 14:04:48 +0100333
334 std::string actual_klass = dex_dep.first->StringByTypeIdx(field_id.class_idx_);
335 if (expected_klass != actual_klass) {
336 continue;
337 }
338
339 std::string actual_name = dex_dep.first->StringDataByIdx(field_id.name_idx_);
340 if (expected_name != actual_name) {
341 continue;
342 }
343
344 std::string actual_type = dex_dep.first->StringByTypeIdx(field_id.type_idx_);
345 if (expected_type != actual_type) {
346 continue;
347 }
348
349 if (expected_resolved) {
350 // Test access flags. Note that PrettyJavaAccessFlags always appends
351 // a space after the modifiers. Add it to the expected access flags.
352 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
353 if (expected_access_flags + " " != actual_access_flags) {
354 continue;
355 }
356
357 std::string actual_decl_klass = verifier_deps_->GetStringFromId(
358 *dex_dep.first, entry.GetDeclaringClassIndex());
359 if (expected_decl_klass != actual_decl_klass) {
360 continue;
361 }
362 }
363
364 return true;
365 }
366 }
367 return false;
368 }
369
370 // Iterates over all method resolution records, finds an entry which matches
371 // the given field kind+class+name+signature and tests its properties.
Vladimir Markoba118822017-06-12 15:41:56 +0100372 bool HasMethod(const std::string& expected_klass,
David Brazdilca3c8c32016-09-06 14:04:48 +0100373 const std::string& expected_name,
374 const std::string& expected_signature,
Andreas Gampe3db70682018-12-26 15:12:03 -0800375 bool expect_resolved,
David Brazdilca3c8c32016-09-06 14:04:48 +0100376 const std::string& expected_access_flags = "",
377 const std::string& expected_decl_klass = "") {
David Brazdilca3c8c32016-09-06 14:04:48 +0100378 for (auto& dex_dep : verifier_deps_->dex_deps_) {
Vladimir Markoba118822017-06-12 15:41:56 +0100379 for (const VerifierDeps::MethodResolution& entry : dex_dep.second->methods_) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800380 if (expect_resolved != entry.IsResolved()) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100381 continue;
382 }
383
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800384 const dex::MethodId& method_id = dex_dep.first->GetMethodId(entry.GetDexMethodIndex());
David Brazdilca3c8c32016-09-06 14:04:48 +0100385
386 std::string actual_klass = dex_dep.first->StringByTypeIdx(method_id.class_idx_);
387 if (expected_klass != actual_klass) {
388 continue;
389 }
390
391 std::string actual_name = dex_dep.first->StringDataByIdx(method_id.name_idx_);
392 if (expected_name != actual_name) {
393 continue;
394 }
395
396 std::string actual_signature = dex_dep.first->GetMethodSignature(method_id).ToString();
397 if (expected_signature != actual_signature) {
398 continue;
399 }
400
Andreas Gampe3db70682018-12-26 15:12:03 -0800401 if (expect_resolved) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100402 // Test access flags. Note that PrettyJavaAccessFlags always appends
403 // a space after the modifiers. Add it to the expected access flags.
404 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags());
405 if (expected_access_flags + " " != actual_access_flags) {
406 continue;
407 }
408
409 std::string actual_decl_klass = verifier_deps_->GetStringFromId(
410 *dex_dep.first, entry.GetDeclaringClassIndex());
411 if (expected_decl_klass != actual_decl_klass) {
412 continue;
413 }
414 }
415
416 return true;
417 }
418 }
419 return false;
420 }
421
David Brazdil6f82fbd2016-09-14 11:55:26 +0100422 size_t NumberOfCompiledDexFiles() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100423 return verifier_deps_->dex_deps_.size();
424 }
425
Andreas Gampe654698d2018-09-20 13:34:35 -0700426 bool HasEachKindOfRecord() {
David Brazdil6f82fbd2016-09-14 11:55:26 +0100427 bool has_strings = false;
428 bool has_assignability = false;
429 bool has_classes = false;
430 bool has_fields = false;
431 bool has_methods = false;
Nicolas Geoffray08025182016-10-25 17:20:18 +0100432 bool has_unverified_classes = false;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100433
434 for (auto& entry : verifier_deps_->dex_deps_) {
435 has_strings |= !entry.second->strings_.empty();
436 has_assignability |= !entry.second->assignable_types_.empty();
437 has_assignability |= !entry.second->unassignable_types_.empty();
438 has_classes |= !entry.second->classes_.empty();
439 has_fields |= !entry.second->fields_.empty();
Vladimir Markoba118822017-06-12 15:41:56 +0100440 has_methods |= !entry.second->methods_.empty();
Nicolas Geoffray08025182016-10-25 17:20:18 +0100441 has_unverified_classes |= !entry.second->unverified_classes_.empty();
David Brazdil6f82fbd2016-09-14 11:55:26 +0100442 }
443
Nicolas Geoffray08025182016-10-25 17:20:18 +0100444 return has_strings &&
445 has_assignability &&
446 has_classes &&
447 has_fields &&
448 has_methods &&
449 has_unverified_classes;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100450 }
451
David Brazdil8fd67222019-02-05 18:13:44 +0000452 // Load the dex file again with a new class loader, decode the VerifierDeps
453 // in `buffer`, allow the caller to modify the deps and then run validation.
454 template<typename Fn>
455 bool RunValidation(Fn fn, const std::vector<uint8_t>& buffer, std::string* error_msg) {
456 ScopedObjectAccess soa(Thread::Current());
457
458 jobject second_loader = LoadDex("VerifierDeps");
459 const auto& second_dex_files = GetDexFiles(second_loader);
460
461 VerifierDeps decoded_deps(second_dex_files, ArrayRef<const uint8_t>(buffer));
462 VerifierDeps::DexFileDeps* decoded_dex_deps =
463 decoded_deps.GetDexFileDeps(*second_dex_files.front());
464
465 // Let the test modify the dependencies.
466 fn(*decoded_dex_deps);
467
468 StackHandleScope<1> hs(soa.Self());
469 Handle<mirror::ClassLoader> new_class_loader =
470 hs.NewHandle<mirror::ClassLoader>(soa.Decode<mirror::ClassLoader>(second_loader));
471 return decoded_deps.ValidateDependencies(new_class_loader, soa.Self(), error_msg);
472 }
473
David Brazdilca3c8c32016-09-06 14:04:48 +0100474 std::unique_ptr<verifier::VerifierDeps> verifier_deps_;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100475 std::vector<const DexFile*> dex_files_;
476 const DexFile* primary_dex_file_;
David Brazdilca3c8c32016-09-06 14:04:48 +0100477 jobject class_loader_;
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100478 ObjPtr<mirror::Class> klass_Main_;
David Brazdilca3c8c32016-09-06 14:04:48 +0100479};
480
481TEST_F(VerifierDepsTest, StringToId) {
482 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100483 LoadDexFile(soa);
David Brazdilca3c8c32016-09-06 14:04:48 +0100484
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800485 dex::StringIndex id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
486 ASSERT_LT(id_Main1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100487 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100488
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800489 dex::StringIndex id_Main2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
490 ASSERT_LT(id_Main2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100491 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100492
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800493 dex::StringIndex id_Lorem1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
494 ASSERT_GE(id_Lorem1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100495 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100496
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800497 dex::StringIndex id_Lorem2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
498 ASSERT_GE(id_Lorem2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100499 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100500
501 ASSERT_EQ(id_Main1, id_Main2);
502 ASSERT_EQ(id_Lorem1, id_Lorem2);
503 ASSERT_NE(id_Main1, id_Lorem1);
504}
505
506TEST_F(VerifierDepsTest, Assignable_BothInBoot) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800507 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/TimeZone;",
508 /* src= */ "Ljava/util/SimpleTimeZone;",
509 /* is_strict= */ true,
510 /* is_assignable= */ true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100511 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
512}
513
514TEST_F(VerifierDepsTest, Assignable_DestinationInBoot1) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800515 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/net/Socket;",
516 /* src= */ "LMySSLSocket;",
517 /* is_strict= */ true,
518 /* is_assignable= */ true));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000519 ASSERT_TRUE(HasAssignable("Ljava/net/Socket;", "Ljavax/net/ssl/SSLSocket;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100520}
521
522TEST_F(VerifierDepsTest, Assignable_DestinationInBoot2) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800523 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/TimeZone;",
524 /* src= */ "LMySimpleTimeZone;",
525 /* is_strict= */ true,
526 /* is_assignable= */ true));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000527 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100528}
529
530TEST_F(VerifierDepsTest, Assignable_DestinationInBoot3) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800531 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/Collection;",
532 /* src= */ "LMyThreadSet;",
533 /* is_strict= */ true,
534 /* is_assignable= */ true));
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +0000535 ASSERT_TRUE(HasAssignable("Ljava/util/Collection;", "Ljava/util/Set;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100536}
537
538TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800539 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[[Ljava/util/TimeZone;",
540 /* src= */ "[[Ljava/util/SimpleTimeZone;",
541 /* is_strict= */ true,
542 /* is_assignable= */ true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100543 // If the component types of both arrays are resolved, we optimize the list of
544 // dependencies by recording a dependency on the component types.
545 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;", true));
546 ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;", true));
547 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
548}
549
David Brazdilca3c8c32016-09-06 14:04:48 +0100550TEST_F(VerifierDepsTest, NotAssignable_BothInBoot) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800551 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;",
552 /* src= */ "Ljava/util/SimpleTimeZone;",
553 /* is_strict= */ true,
554 /* is_assignable= */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100555 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
556}
557
558TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot1) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800559 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;",
560 /* src= */ "LMySSLSocket;",
561 /* is_strict= */ true,
562 /* is_assignable= */ false));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000563 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljavax/net/ssl/SSLSocket;", false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100564}
565
566TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot2) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800567 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;",
568 /* src= */ "LMySimpleTimeZone;",
569 /* is_strict= */ true,
570 /* is_assignable= */ false));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000571 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100572}
573
574TEST_F(VerifierDepsTest, NotAssignable_BothArrays) {
Andreas Gampe3db70682018-12-26 15:12:03 -0800575 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[Ljava/lang/Exception;",
576 /* src= */ "[Ljava/util/SimpleTimeZone;",
577 /* is_strict= */ true,
578 /* is_assignable= */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100579 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
580}
581
582TEST_F(VerifierDepsTest, ArgumentType_ResolvedClass) {
583 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedClass"));
584 ASSERT_TRUE(HasClass("Ljava/lang/Thread;", true, "public"));
585}
586
David Brazdilca3c8c32016-09-06 14:04:48 +0100587TEST_F(VerifierDepsTest, ArgumentType_UnresolvedClass) {
588 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedClass"));
589 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
590}
591
592TEST_F(VerifierDepsTest, ArgumentType_UnresolvedSuper) {
593 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedSuper"));
594 ASSERT_TRUE(HasClass("LMySetWithUnresolvedSuper;", false));
595}
596
597TEST_F(VerifierDepsTest, ReturnType_Reference) {
598 ASSERT_TRUE(VerifyMethod("ReturnType_Reference"));
599 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
600}
601
602TEST_F(VerifierDepsTest, ReturnType_Array) {
603 ASSERT_FALSE(VerifyMethod("ReturnType_Array"));
604 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/IllegalStateException;", false));
605}
606
607TEST_F(VerifierDepsTest, InvokeArgumentType) {
608 ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
609 ASSERT_TRUE(HasClass("Ljava/text/SimpleDateFormat;", true, "public"));
610 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100611 ASSERT_TRUE(HasMethod("Ljava/text/SimpleDateFormat;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100612 "setTimeZone",
613 "(Ljava/util/TimeZone;)V",
Andreas Gampe3db70682018-12-26 15:12:03 -0800614 /* expect_resolved= */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100615 "public",
616 "Ljava/text/DateFormat;"));
617 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
618}
619
620TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) {
621 ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines"));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000622 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100623 ASSERT_TRUE(HasAssignable(
624 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
625}
626
627TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) {
628 ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf"));
629 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
630 ASSERT_TRUE(HasAssignable(
631 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
632 ASSERT_TRUE(HasAssignable("Ljava/net/SocketTimeoutException;", "Ljava/lang/Exception;", false));
633}
634
635TEST_F(VerifierDepsTest, MergeTypes_Unresolved) {
636 ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved"));
637 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
638 ASSERT_TRUE(HasAssignable(
639 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
640}
641
642TEST_F(VerifierDepsTest, ConstClass_Resolved) {
643 ASSERT_TRUE(VerifyMethod("ConstClass_Resolved"));
644 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
645}
646
647TEST_F(VerifierDepsTest, ConstClass_Unresolved) {
Andreas Gampe629be512017-08-25 17:09:32 -0700648 ASSERT_FALSE(VerifyMethod("ConstClass_Unresolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100649 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
650}
651
652TEST_F(VerifierDepsTest, CheckCast_Resolved) {
653 ASSERT_TRUE(VerifyMethod("CheckCast_Resolved"));
654 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
655}
656
657TEST_F(VerifierDepsTest, CheckCast_Unresolved) {
Andreas Gampe629be512017-08-25 17:09:32 -0700658 ASSERT_FALSE(VerifyMethod("CheckCast_Unresolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100659 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
660}
661
662TEST_F(VerifierDepsTest, InstanceOf_Resolved) {
663 ASSERT_TRUE(VerifyMethod("InstanceOf_Resolved"));
664 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
665}
666
667TEST_F(VerifierDepsTest, InstanceOf_Unresolved) {
Andreas Gampe629be512017-08-25 17:09:32 -0700668 ASSERT_FALSE(VerifyMethod("InstanceOf_Unresolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100669 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
670}
671
672TEST_F(VerifierDepsTest, NewInstance_Resolved) {
673 ASSERT_TRUE(VerifyMethod("NewInstance_Resolved"));
674 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
675}
676
677TEST_F(VerifierDepsTest, NewInstance_Unresolved) {
Andreas Gampe629be512017-08-25 17:09:32 -0700678 ASSERT_FALSE(VerifyMethod("NewInstance_Unresolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100679 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
680}
681
David Brazdilca3c8c32016-09-06 14:04:48 +0100682TEST_F(VerifierDepsTest, NewArray_Unresolved) {
Andreas Gampe629be512017-08-25 17:09:32 -0700683 ASSERT_FALSE(VerifyMethod("NewArray_Unresolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100684 ASSERT_TRUE(HasClass("[LUnresolvedClass;", false));
685}
686
687TEST_F(VerifierDepsTest, Throw) {
688 ASSERT_TRUE(VerifyMethod("Throw"));
689 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
690}
691
692TEST_F(VerifierDepsTest, MoveException_Resolved) {
693 ASSERT_TRUE(VerifyMethod("MoveException_Resolved"));
694 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
695 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
696 ASSERT_TRUE(HasClass("Ljava/util/zip/ZipException;", true, "public"));
697
698 // Testing that all exception types are assignable to Throwable.
699 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;", true));
700 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
701 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;", true));
702
703 // Testing that the merge type is assignable to Throwable.
704 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;", true));
705
706 // Merging of exception types.
707 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;", true));
708 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;", true));
709 ASSERT_TRUE(HasAssignable(
710 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
711}
712
713TEST_F(VerifierDepsTest, MoveException_Unresolved) {
714 ASSERT_FALSE(VerifyMethod("MoveException_Unresolved"));
715 ASSERT_TRUE(HasClass("LUnresolvedException;", false));
716}
717
718TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInReferenced) {
719 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInReferenced"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000720 ASSERT_TRUE(HasClass("Ljava/lang/System;", true, "public"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100721 ASSERT_TRUE(HasField("Ljava/lang/System;",
722 "out",
723 "Ljava/io/PrintStream;",
724 true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000725 "public static",
David Brazdilca3c8c32016-09-06 14:04:48 +0100726 "Ljava/lang/System;"));
727}
728
729TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass1) {
730 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass1"));
731 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
732 ASSERT_TRUE(HasField(
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000733 "Ljava/util/SimpleTimeZone;", "LONG", "I", true, "public static", "Ljava/util/TimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100734}
735
736TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass2) {
737 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass2"));
738 ASSERT_TRUE(HasField(
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000739 "LMySimpleTimeZone;", "SHORT", "I", true, "public static", "Ljava/util/TimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100740}
741
742TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface1) {
743 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface1"));
744 ASSERT_TRUE(HasClass("Ljavax/xml/transform/dom/DOMResult;", true, "public"));
745 ASSERT_TRUE(HasField("Ljavax/xml/transform/dom/DOMResult;",
746 "PI_ENABLE_OUTPUT_ESCAPING",
747 "Ljava/lang/String;",
748 true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000749 "public static",
David Brazdilca3c8c32016-09-06 14:04:48 +0100750 "Ljavax/xml/transform/Result;"));
751}
752
753TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface2) {
754 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface2"));
755 ASSERT_TRUE(HasField("LMyDOMResult;",
756 "PI_ENABLE_OUTPUT_ESCAPING",
757 "Ljava/lang/String;",
758 true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000759 "public static",
David Brazdilca3c8c32016-09-06 14:04:48 +0100760 "Ljavax/xml/transform/Result;"));
761}
762
763TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface3) {
764 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface3"));
765 ASSERT_TRUE(HasField("LMyResult;",
766 "PI_ENABLE_OUTPUT_ESCAPING",
767 "Ljava/lang/String;",
768 true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000769 "public static",
David Brazdilca3c8c32016-09-06 14:04:48 +0100770 "Ljavax/xml/transform/Result;"));
771}
772
773TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface4) {
774 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface4"));
775 ASSERT_TRUE(HasField("LMyDocument;",
776 "ELEMENT_NODE",
777 "S",
778 true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000779 "public static",
David Brazdilca3c8c32016-09-06 14:04:48 +0100780 "Lorg/w3c/dom/Node;"));
781}
782
783TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInBoot) {
784 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInBoot"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000785 ASSERT_TRUE(HasClass("Ljava/util/TimeZone;", true, "public"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100786 ASSERT_TRUE(HasField("Ljava/util/TimeZone;", "x", "I", false));
787}
788
789TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInDex) {
790 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInDex"));
791 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
792}
793
794TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) {
795 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced"));
796 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
797 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;",
798 "bytesTransferred",
799 "I",
800 true,
801 "public",
802 "Ljava/io/InterruptedIOException;"));
803 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000804 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100805}
806
807TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) {
808 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1"));
809 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
810 ASSERT_TRUE(HasField("Ljava/net/SocketTimeoutException;",
811 "bytesTransferred",
812 "I",
813 true,
814 "public",
815 "Ljava/io/InterruptedIOException;"));
816 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000817 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100818}
819
820TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) {
821 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2"));
822 ASSERT_TRUE(HasField("LMySocketTimeoutException;",
823 "bytesTransferred",
824 "I",
825 true,
826 "public",
827 "Ljava/io/InterruptedIOException;"));
828 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000829 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100830}
831
832TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInBoot) {
833 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInBoot"));
834 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
835 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;", "x", "I", false));
836}
837
838TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInDex) {
839 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInDex"));
840 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
841}
842
843TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInReferenced) {
844 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInReferenced"));
845 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100846 ASSERT_TRUE(HasMethod("Ljava/net/Socket;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100847 "setSocketImplFactory",
848 "(Ljava/net/SocketImplFactory;)V",
Andreas Gampe3db70682018-12-26 15:12:03 -0800849 /* expect_resolved= */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100850 "public static",
851 "Ljava/net/Socket;"));
852}
853
854TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass1) {
855 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000856 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100857 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100858 "setSocketImplFactory",
859 "(Ljava/net/SocketImplFactory;)V",
Andreas Gampe3db70682018-12-26 15:12:03 -0800860 /* expect_resolved= */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100861 "public static",
862 "Ljava/net/Socket;"));
863}
864
865TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass2) {
866 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass2"));
Vladimir Markoba118822017-06-12 15:41:56 +0100867 ASSERT_TRUE(HasMethod("LMySSLSocket;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100868 "setSocketImplFactory",
869 "(Ljava/net/SocketImplFactory;)V",
Andreas Gampe3db70682018-12-26 15:12:03 -0800870 /* expect_resolved= */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100871 "public static",
872 "Ljava/net/Socket;"));
873}
874
875TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface1) {
876 ASSERT_TRUE(VerifyMethod("InvokeStatic_DeclaredInInterface1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000877 ASSERT_TRUE(HasClass("Ljava/util/Map$Entry;", true, "public interface"));
Vladimir Markoba118822017-06-12 15:41:56 +0100878 ASSERT_TRUE(HasMethod("Ljava/util/Map$Entry;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100879 "comparingByKey",
880 "()Ljava/util/Comparator;",
Andreas Gampe3db70682018-12-26 15:12:03 -0800881 /* expect_resolved= */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100882 "public static",
883 "Ljava/util/Map$Entry;"));
884}
885
886TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface2) {
887 ASSERT_FALSE(VerifyMethod("InvokeStatic_DeclaredInInterface2"));
888 ASSERT_TRUE(HasClass("Ljava/util/AbstractMap$SimpleEntry;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100889 ASSERT_TRUE(HasMethod("Ljava/util/AbstractMap$SimpleEntry;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100890 "comparingByKey",
891 "()Ljava/util/Comparator;",
Andreas Gampe3db70682018-12-26 15:12:03 -0800892 /* expect_resolved= */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100893}
894
895TEST_F(VerifierDepsTest, InvokeStatic_Unresolved1) {
896 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000897 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100898 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
899 "x",
900 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -0800901 /* expect_resolved= */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100902}
903
904TEST_F(VerifierDepsTest, InvokeStatic_Unresolved2) {
905 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved2"));
Vladimir Markoba118822017-06-12 15:41:56 +0100906 ASSERT_TRUE(HasMethod("LMySSLSocket;",
907 "x",
908 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -0800909 /* expect_resolved= */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100910}
911
912TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInReferenced) {
913 ASSERT_TRUE(VerifyMethod("InvokeDirect_Resolved_DeclaredInReferenced"));
914 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100915 ASSERT_TRUE(HasMethod("Ljava/net/Socket;",
916 "<init>",
917 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -0800918 /* expect_resolved= */ true,
Vladimir Markoba118822017-06-12 15:41:56 +0100919 "public",
920 "Ljava/net/Socket;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100921}
922
923TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass1) {
924 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000925 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100926 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100927 "checkOldImpl",
928 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -0800929 /* expect_resolved= */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100930 "private",
931 "Ljava/net/Socket;"));
932}
933
934TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass2) {
935 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass2"));
Vladimir Markoba118822017-06-12 15:41:56 +0100936 ASSERT_TRUE(HasMethod("LMySSLSocket;",
937 "checkOldImpl",
938 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -0800939 /* expect_resolved= */ true,
Vladimir Markoba118822017-06-12 15:41:56 +0100940 "private",
941 "Ljava/net/Socket;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100942}
943
944TEST_F(VerifierDepsTest, InvokeDirect_Unresolved1) {
945 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000946 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100947 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
948 "x",
949 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -0800950 /* expect_resolved= */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100951}
952
953TEST_F(VerifierDepsTest, InvokeDirect_Unresolved2) {
954 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved2"));
Vladimir Markoba118822017-06-12 15:41:56 +0100955 ASSERT_TRUE(HasMethod("LMySSLSocket;",
956 "x",
957 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -0800958 /* expect_resolved= */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100959}
960
961TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
962 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
963 ASSERT_TRUE(HasClass("Ljava/lang/Throwable;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100964 ASSERT_TRUE(HasMethod("Ljava/lang/Throwable;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100965 "getMessage",
966 "()Ljava/lang/String;",
Andreas Gampe3db70682018-12-26 15:12:03 -0800967 /* expect_resolved= */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100968 "public",
969 "Ljava/lang/Throwable;"));
970 // Type dependency on `this` argument.
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000971 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100972}
973
974TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
975 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
976 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100977 ASSERT_TRUE(HasMethod("Ljava/io/InterruptedIOException;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100978 "getMessage",
979 "()Ljava/lang/String;",
Andreas Gampe3db70682018-12-26 15:12:03 -0800980 /* expect_resolved= */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100981 "public",
982 "Ljava/lang/Throwable;"));
983 // Type dependency on `this` argument.
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000984 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100985}
986
987TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass2) {
988 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass2"));
Vladimir Markoba118822017-06-12 15:41:56 +0100989 ASSERT_TRUE(HasMethod("LMySocketTimeoutException;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100990 "getMessage",
991 "()Ljava/lang/String;",
Andreas Gampe3db70682018-12-26 15:12:03 -0800992 /* expect_resolved= */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100993 "public",
994 "Ljava/lang/Throwable;"));
995}
996
997TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperinterface) {
998 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperinterface"));
Vladimir Markoba118822017-06-12 15:41:56 +0100999 ASSERT_TRUE(HasMethod("LMyThreadSet;",
David Brazdilca3c8c32016-09-06 14:04:48 +01001000 "size",
1001 "()I",
Andreas Gampe3db70682018-12-26 15:12:03 -08001002 /* expect_resolved= */ true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001003 "public",
David Brazdilca3c8c32016-09-06 14:04:48 +01001004 "Ljava/util/Set;"));
1005}
1006
1007TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved1) {
1008 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved1"));
1009 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +01001010 ASSERT_TRUE(HasMethod("Ljava/io/InterruptedIOException;",
1011 "x",
1012 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -08001013 /* expect_resolved= */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +01001014}
1015
1016TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved2) {
1017 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved2"));
Vladimir Markoba118822017-06-12 15:41:56 +01001018 ASSERT_TRUE(HasMethod("LMySocketTimeoutException;",
1019 "x",
1020 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -08001021 /* expect_resolved= */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +01001022}
1023
1024TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInReferenced) {
1025 ASSERT_TRUE(VerifyMethod("InvokeInterface_Resolved_DeclaredInReferenced"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001026 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface"));
Vladimir Markoba118822017-06-12 15:41:56 +01001027 ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;",
David Brazdilca3c8c32016-09-06 14:04:48 +01001028 "run",
1029 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -08001030 /* expect_resolved= */ true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001031 "public",
David Brazdilca3c8c32016-09-06 14:04:48 +01001032 "Ljava/lang/Runnable;"));
1033}
1034
1035TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperclass) {
1036 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperclass"));
Vladimir Markoba118822017-06-12 15:41:56 +01001037 // TODO: Maybe we should not record dependency if the invoke type does not match the lookup type.
1038 ASSERT_TRUE(HasMethod("LMyThread;",
1039 "join",
1040 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -08001041 /* expect_resolved= */ true,
Vladimir Markoba118822017-06-12 15:41:56 +01001042 "public",
1043 "Ljava/lang/Thread;"));
David Brazdilca3c8c32016-09-06 14:04:48 +01001044}
1045
1046TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface1) {
1047 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface1"));
Vladimir Markoba118822017-06-12 15:41:56 +01001048 // TODO: Maybe we should not record dependency if the invoke type does not match the lookup type.
1049 ASSERT_TRUE(HasMethod("LMyThreadSet;",
David Brazdilca3c8c32016-09-06 14:04:48 +01001050 "run",
1051 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -08001052 /* expect_resolved= */ true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001053 "public",
Vladimir Markoba118822017-06-12 15:41:56 +01001054 "Ljava/lang/Thread;"));
David Brazdilca3c8c32016-09-06 14:04:48 +01001055}
1056
1057TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface2) {
1058 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface2"));
Vladimir Markoba118822017-06-12 15:41:56 +01001059 ASSERT_TRUE(HasMethod("LMyThreadSet;",
David Brazdilca3c8c32016-09-06 14:04:48 +01001060 "isEmpty",
1061 "()Z",
Andreas Gampe3db70682018-12-26 15:12:03 -08001062 /* expect_resolved= */ true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001063 "public",
David Brazdilca3c8c32016-09-06 14:04:48 +01001064 "Ljava/util/Set;"));
1065}
1066
1067TEST_F(VerifierDepsTest, InvokeInterface_Unresolved1) {
1068 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001069 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface"));
Vladimir Markoba118822017-06-12 15:41:56 +01001070 ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;",
1071 "x",
1072 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -08001073 /* expect_resolved= */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +01001074}
1075
1076TEST_F(VerifierDepsTest, InvokeInterface_Unresolved2) {
1077 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved2"));
Andreas Gampe3db70682018-12-26 15:12:03 -08001078 ASSERT_TRUE(HasMethod("LMyThreadSet;", "x", "()V", /* expect_resolved= */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +01001079}
1080
1081TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
1082 ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001083 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface"));
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +00001084 ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "Ljava/lang/Thread;", true));
Vladimir Markoba118822017-06-12 15:41:56 +01001085 ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;",
David Brazdilca3c8c32016-09-06 14:04:48 +01001086 "run",
1087 "()V",
Andreas Gampe3db70682018-12-26 15:12:03 -08001088 /* expect_resolved= */ true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001089 "public",
David Brazdilca3c8c32016-09-06 14:04:48 +01001090 "Ljava/lang/Runnable;"));
1091}
1092
1093TEST_F(VerifierDepsTest, InvokeSuper_ThisNotAssignable) {
1094 ASSERT_FALSE(VerifyMethod("InvokeSuper_ThisNotAssignable"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001095 ASSERT_TRUE(HasClass("Ljava/lang/Integer;", true, "public"));
Nicolas Geoffray119e8462016-12-21 10:29:43 +00001096 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/Thread;", false));
Vladimir Markoba118822017-06-12 15:41:56 +01001097 ASSERT_TRUE(HasMethod("Ljava/lang/Integer;",
1098 "intValue", "()I",
Andreas Gampe3db70682018-12-26 15:12:03 -08001099 /* expect_resolved= */ true,
Vladimir Markoba118822017-06-12 15:41:56 +01001100 "public", "Ljava/lang/Integer;"));
David Brazdilca3c8c32016-09-06 14:04:48 +01001101}
1102
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +00001103TEST_F(VerifierDepsTest, ArgumentType_ResolvedReferenceArray) {
1104 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedReferenceArray"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001105 ASSERT_TRUE(HasClass("[Ljava/lang/Thread;", true, "public"));
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +00001106}
1107
1108TEST_F(VerifierDepsTest, NewArray_Resolved) {
1109 ASSERT_TRUE(VerifyMethod("NewArray_Resolved"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001110 ASSERT_TRUE(HasClass("[Ljava/lang/IllegalStateException;", true, "public"));
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +00001111}
1112
David Brazdil6f82fbd2016-09-14 11:55:26 +01001113TEST_F(VerifierDepsTest, EncodeDecode) {
1114 VerifyDexFile();
1115
1116 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1117 ASSERT_TRUE(HasEachKindOfRecord());
1118
1119 std::vector<uint8_t> buffer;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001120 verifier_deps_->Encode(dex_files_, &buffer);
David Brazdil6f82fbd2016-09-14 11:55:26 +01001121 ASSERT_FALSE(buffer.empty());
1122
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001123 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
David Brazdil6f82fbd2016-09-14 11:55:26 +01001124 ASSERT_TRUE(verifier_deps_->Equals(decoded_deps));
1125}
1126
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001127TEST_F(VerifierDepsTest, EncodeDecodeMulti) {
1128 VerifyDexFile("MultiDex");
1129
1130 ASSERT_GT(NumberOfCompiledDexFiles(), 1u);
1131 std::vector<uint8_t> buffer;
1132 verifier_deps_->Encode(dex_files_, &buffer);
1133 ASSERT_FALSE(buffer.empty());
1134
1135 // Create new DexFile, to mess with std::map order: the verifier deps used
1136 // to iterate over the map, which doesn't guarantee insertion order. We fixed
1137 // this by passing the expected order when encoding/decoding.
1138 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles("VerifierDeps");
1139 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles("MultiDex");
1140 std::vector<const DexFile*> dex_files;
1141 for (auto& dex_file : first_dex_files) {
1142 dex_files.push_back(dex_file.get());
1143 }
1144 for (auto& dex_file : second_dex_files) {
1145 dex_files.push_back(dex_file.get());
1146 }
1147
1148 // Dump the new verifier deps to ensure it can properly read the data.
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001149 VerifierDeps decoded_deps(dex_files, ArrayRef<const uint8_t>(buffer));
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001150 std::ostringstream stream;
1151 VariableIndentationOutputStream os(&stream);
1152 decoded_deps.Dump(&os);
1153}
1154
Nicolas Geoffray08025182016-10-25 17:20:18 +01001155TEST_F(VerifierDepsTest, UnverifiedClasses) {
1156 VerifyDexFile();
1157 ASSERT_FALSE(HasUnverifiedClass("LMyThread;"));
1158 // Test that a class with a soft failure is recorded.
1159 ASSERT_TRUE(HasUnverifiedClass("LMain;"));
1160 // Test that a class with hard failure is recorded.
1161 ASSERT_TRUE(HasUnverifiedClass("LMyVerificationFailure;"));
1162 // Test that a class with unresolved super is recorded.
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +00001163 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuper;"));
Nicolas Geoffray08025182016-10-25 17:20:18 +01001164 // Test that a class with unresolved super and hard failure is recorded.
1165 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;"));
1166}
1167
Mathieu Chartierbf755fe2017-08-01 13:42:56 -07001168TEST_F(VerifierDepsTest, UnverifiedOrder) {
1169 ScopedObjectAccess soa(Thread::Current());
1170 jobject loader = LoadDex("VerifierDeps");
1171 std::vector<const DexFile*> dex_files = GetDexFiles(loader);
1172 ASSERT_GT(dex_files.size(), 0u);
1173 const DexFile* dex_file = dex_files[0];
1174 VerifierDeps deps1(dex_files);
1175 Thread* const self = Thread::Current();
1176 ASSERT_TRUE(self->GetVerifierDeps() == nullptr);
1177 self->SetVerifierDeps(&deps1);
1178 deps1.MaybeRecordVerificationStatus(*dex_file,
1179 dex::TypeIndex(0),
1180 verifier::FailureKind::kHardFailure);
1181 deps1.MaybeRecordVerificationStatus(*dex_file,
1182 dex::TypeIndex(1),
1183 verifier::FailureKind::kHardFailure);
1184 VerifierDeps deps2(dex_files);
1185 self->SetVerifierDeps(nullptr);
1186 self->SetVerifierDeps(&deps2);
1187 deps2.MaybeRecordVerificationStatus(*dex_file,
1188 dex::TypeIndex(1),
1189 verifier::FailureKind::kHardFailure);
1190 deps2.MaybeRecordVerificationStatus(*dex_file,
1191 dex::TypeIndex(0),
1192 verifier::FailureKind::kHardFailure);
1193 self->SetVerifierDeps(nullptr);
1194 std::vector<uint8_t> buffer1;
1195 deps1.Encode(dex_files, &buffer1);
1196 std::vector<uint8_t> buffer2;
1197 deps2.Encode(dex_files, &buffer2);
1198 EXPECT_EQ(buffer1, buffer2);
1199}
1200
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001201TEST_F(VerifierDepsTest, VerifyDeps) {
David Brazdil8fd67222019-02-05 18:13:44 +00001202 std::string error_msg;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001203
David Brazdil8fd67222019-02-05 18:13:44 +00001204 VerifyDexFile();
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001205 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1206 ASSERT_TRUE(HasEachKindOfRecord());
1207
1208 // When validating, we create a new class loader, as
1209 // the existing `class_loader_` may contain erroneous classes,
1210 // that ClassLinker::FindClass won't return.
1211
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001212 std::vector<uint8_t> buffer;
1213 verifier_deps_->Encode(dex_files_, &buffer);
1214 ASSERT_FALSE(buffer.empty());
1215
David Brazdil8fd67222019-02-05 18:13:44 +00001216 // Check that dependencies are satisfied after decoding `buffer`.
1217 ASSERT_TRUE(RunValidation([](VerifierDeps::DexFileDeps&) {}, buffer, &error_msg))
1218 << error_msg;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001219
David Brazdil8fd67222019-02-05 18:13:44 +00001220 // Mess with the dependencies to make sure we catch any change and fail to verify.
1221 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1222 deps.assignable_types_.insert(*deps.unassignable_types_.begin());
1223 }, buffer, &error_msg));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001224
David Brazdil8fd67222019-02-05 18:13:44 +00001225 // Mess with the unassignable_types.
1226 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1227 deps.unassignable_types_.insert(*deps.assignable_types_.begin());
1228 }, buffer, &error_msg));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001229
David Brazdil8fd67222019-02-05 18:13:44 +00001230 // Mess with classes.
1231 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1232 for (const auto& entry : deps.classes_) {
1233 if (entry.IsResolved()) {
1234 deps.classes_.insert(VerifierDeps::ClassResolution(
1235 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker));
1236 return;
1237 }
1238 }
1239 LOG(FATAL) << "Could not find any resolved classes";
1240 UNREACHABLE();
1241 }, buffer, &error_msg));
1242 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1243 for (const auto& entry : deps.classes_) {
1244 if (!entry.IsResolved()) {
1245 deps.classes_.insert(VerifierDeps::ClassResolution(
1246 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker - 1));
1247 return;
1248 }
1249 }
1250 LOG(FATAL) << "Could not find any unresolved classes";
1251 UNREACHABLE();
1252 }, buffer, &error_msg));
1253 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1254 for (const auto& entry : deps.classes_) {
1255 if (entry.IsResolved()) {
1256 deps.classes_.insert(VerifierDeps::ClassResolution(
1257 entry.GetDexTypeIndex(), entry.GetAccessFlags() - 1));
1258 return;
1259 }
1260 }
1261 LOG(FATAL) << "Could not find any resolved classes";
1262 UNREACHABLE();
1263 }, buffer, &error_msg));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001264
David Brazdil8fd67222019-02-05 18:13:44 +00001265 // Mess with fields.
1266 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1267 for (const auto& entry : deps.fields_) {
1268 if (entry.IsResolved()) {
1269 deps.fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1270 VerifierDeps::kUnresolvedMarker,
1271 entry.GetDeclaringClassIndex()));
1272 return;
1273 }
1274 }
1275 LOG(FATAL) << "Could not find any resolved fields";
1276 UNREACHABLE();
1277 }, buffer, &error_msg));
1278 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1279 for (const auto& entry : deps.fields_) {
1280 if (!entry.IsResolved()) {
1281 constexpr dex::StringIndex kStringIndexZero(0); // We know there is a class there.
1282 deps.fields_.insert(VerifierDeps::FieldResolution(0 /* we know there is a field there */,
1283 VerifierDeps::kUnresolvedMarker - 1,
1284 kStringIndexZero));
1285 return;
1286 }
1287 }
1288 LOG(FATAL) << "Could not find any unresolved fields";
1289 UNREACHABLE();
1290 }, buffer, &error_msg));
1291 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1292 for (const auto& entry : deps.fields_) {
1293 if (entry.IsResolved()) {
1294 deps.fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1295 entry.GetAccessFlags() - 1,
1296 entry.GetDeclaringClassIndex()));
1297 return;
1298 }
1299 }
1300 LOG(FATAL) << "Could not find any resolved fields";
1301 UNREACHABLE();
1302 }, buffer, &error_msg));
1303 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1304 for (const auto& entry : deps.fields_) {
1305 constexpr dex::StringIndex kNewTypeIndex(0);
1306 if (entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1307 deps.fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1308 entry.GetAccessFlags(),
1309 kNewTypeIndex));
1310 return;
1311 }
1312 }
1313 LOG(FATAL) << "Could not find any suitable fields";
1314 UNREACHABLE();
1315 }, buffer, &error_msg));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001316
David Brazdil8fd67222019-02-05 18:13:44 +00001317 // Mess with methods.
1318 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1319 std::set<VerifierDeps::MethodResolution>* methods = &deps.methods_;
1320 for (const auto& entry : *methods) {
1321 if (entry.IsResolved()) {
1322 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1323 VerifierDeps::kUnresolvedMarker,
1324 entry.GetDeclaringClassIndex()));
1325 return;
1326 }
1327 }
1328 LOG(FATAL) << "Could not find any resolved methods";
1329 UNREACHABLE();
1330 }, buffer, &error_msg));
1331 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1332 std::set<VerifierDeps::MethodResolution>* methods = &deps.methods_;
1333 for (const auto& entry : *methods) {
1334 if (!entry.IsResolved()) {
1335 constexpr dex::StringIndex kStringIndexZero(0); // We know there is a class there.
1336 methods->insert(VerifierDeps::MethodResolution(0 /* we know there is a method there */,
1337 VerifierDeps::kUnresolvedMarker - 1,
1338 kStringIndexZero));
1339 return;
1340 }
1341 }
1342 LOG(FATAL) << "Could not find any unresolved methods";
1343 UNREACHABLE();
1344 }, buffer, &error_msg));
1345 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1346 std::set<VerifierDeps::MethodResolution>* methods = &deps.methods_;
1347 for (const auto& entry : *methods) {
1348 if (entry.IsResolved()) {
1349 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1350 entry.GetAccessFlags() - 1,
1351 entry.GetDeclaringClassIndex()));
1352 return;
1353 }
1354 }
1355 LOG(FATAL) << "Could not find any resolved methods";
1356 UNREACHABLE();
1357 }, buffer, &error_msg));
1358 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) {
1359 std::set<VerifierDeps::MethodResolution>* methods = &deps.methods_;
1360 for (const auto& entry : *methods) {
1361 constexpr dex::StringIndex kNewTypeIndex(0);
1362 if (entry.IsResolved() && entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1363 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1364 entry.GetAccessFlags(),
1365 kNewTypeIndex));
1366 return;
1367 }
1368 }
1369 LOG(FATAL) << "Could not find any suitable methods";
1370 UNREACHABLE();
1371 }, buffer, &error_msg));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001372}
1373
1374TEST_F(VerifierDepsTest, CompilerDriver) {
1375 SetupCompilerDriver();
1376
1377 // Test both multi-dex and single-dex configuration.
1378 for (const char* multi : { "MultiDex", static_cast<const char*>(nullptr) }) {
1379 // Test that the compiler driver behaves as expected when the dependencies
1380 // verify and when they don't verify.
1381 for (bool verify_failure : { false, true }) {
1382 {
1383 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +01001384 LoadDexFile(soa, "VerifierDeps", multi);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001385 }
Andreas Gampe3db70682018-12-26 15:12:03 -08001386 VerifyWithCompilerDriver(/* verifier_deps= */ nullptr);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001387
1388 std::vector<uint8_t> buffer;
1389 verifier_deps_->Encode(dex_files_, &buffer);
1390
1391 {
1392 ScopedObjectAccess soa(Thread::Current());
Vladimir Markoa8bba7d2018-05-30 15:18:48 +01001393 LoadDexFile(soa, "VerifierDeps", multi);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001394 }
1395 verifier::VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1396 if (verify_failure) {
1397 // Just taint the decoded VerifierDeps with one invalid entry.
1398 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1399 bool found = false;
1400 for (const auto& entry : deps->classes_) {
1401 if (entry.IsResolved()) {
1402 deps->classes_.insert(VerifierDeps::ClassResolution(
1403 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker));
1404 found = true;
1405 break;
1406 }
1407 }
1408 ASSERT_TRUE(found);
1409 }
1410 VerifyWithCompilerDriver(&decoded_deps);
1411
1412 if (verify_failure) {
1413 ASSERT_FALSE(verifier_deps_ == nullptr);
1414 ASSERT_FALSE(verifier_deps_->Equals(decoded_deps));
1415 } else {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001416 VerifyClassStatus(decoded_deps);
1417 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001418 }
1419 }
1420}
1421
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +00001422TEST_F(VerifierDepsTest, MultiDexVerification) {
1423 VerifyDexFile("VerifierDepsMulti");
1424 ASSERT_EQ(NumberOfCompiledDexFiles(), 2u);
1425
1426 ASSERT_TRUE(HasUnverifiedClass("LMySoftVerificationFailure;", *dex_files_[1]));
1427 ASSERT_TRUE(HasUnverifiedClass("LMySub1SoftVerificationFailure;", *dex_files_[0]));
1428 ASSERT_TRUE(HasUnverifiedClass("LMySub2SoftVerificationFailure;", *dex_files_[0]));
1429
1430 std::vector<uint8_t> buffer;
1431 verifier_deps_->Encode(dex_files_, &buffer);
1432 ASSERT_FALSE(buffer.empty());
1433}
1434
Nicolas Geoffrayfc38e912017-03-16 16:51:59 +00001435TEST_F(VerifierDepsTest, NotAssignable_InterfaceWithClassInBoot) {
Andreas Gampe3db70682018-12-26 15:12:03 -08001436 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;",
1437 /* src= */ "LIface;",
1438 /* is_strict= */ true,
1439 /* is_assignable= */ false));
Nicolas Geoffrayfc38e912017-03-16 16:51:59 +00001440 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LIface;", false));
1441}
1442
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +01001443TEST_F(VerifierDepsTest, Assignable_Arrays) {
Andreas Gampe3db70682018-12-26 15:12:03 -08001444 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[LIface;",
1445 /* src= */ "[LMyClassExtendingInterface;",
1446 /* is_strict= */ false,
1447 /* is_assignable= */ true));
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +01001448 ASSERT_FALSE(HasAssignable(
Andreas Gampe3db70682018-12-26 15:12:03 -08001449 "LIface;", "LMyClassExtendingInterface;", /* expected_is_assignable= */ true));
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +01001450 ASSERT_FALSE(HasAssignable(
Andreas Gampe3db70682018-12-26 15:12:03 -08001451 "LIface;", "LMyClassExtendingInterface;", /* expected_is_assignable= */ false));
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +01001452}
1453
David Brazdilca3c8c32016-09-06 14:04:48 +01001454} // namespace verifier
1455} // namespace art