blob: 76448d819c2654b6c7096b7f726f0929f2e46cee [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 Brazdilca3c8c32016-09-06 14:04:48 +010021#include "class_linker.h"
Andreas Gamped9911ee2017-03-27 13:27:24 -070022#include "common_compiler_test.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010023#include "compiler_callbacks.h"
David Sehr9e734c72018-01-04 17:56:19 -080024#include "dex/dex_file-inl.h"
25#include "dex/dex_file_types.h"
Andreas Gamped9911ee2017-03-27 13:27:24 -070026#include "dex/verification_results.h"
27#include "dex/verified_method.h"
Andreas Gamped482e732017-04-24 17:59:09 -070028#include "driver/compiler_driver-inl.h"
Andreas Gamped9911ee2017-03-27 13:27:24 -070029#include "driver/compiler_options.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010030#include "handle_scope-inl.h"
Andreas Gampe6d7abbd2017-04-24 13:19:09 -070031#include "indenter.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010032#include "mirror/class_loader.h"
33#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070034#include "scoped_thread_state_change-inl.h"
Andreas Gampe6d7abbd2017-04-24 13:19:09 -070035#include "thread.h"
Mathieu Chartier93764b82017-07-17 14:51:53 -070036#include "utils/atomic_dex_ref_map-inl.h"
Andreas Gampe6d7abbd2017-04-24 13:19:09 -070037#include "verifier/method_verifier-inl.h"
David Brazdilca3c8c32016-09-06 14:04:48 +010038
39namespace art {
40namespace verifier {
41
42class VerifierDepsCompilerCallbacks : public CompilerCallbacks {
43 public:
Igor Murashkin2ffb7032017-11-08 13:35:21 -080044 VerifierDepsCompilerCallbacks()
David Brazdilca3c8c32016-09-06 14:04:48 +010045 : CompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp),
46 deps_(nullptr) {}
47
48 void MethodVerified(verifier::MethodVerifier* verifier ATTRIBUTE_UNUSED) OVERRIDE {}
49 void ClassRejected(ClassReference ref ATTRIBUTE_UNUSED) OVERRIDE {}
50 bool IsRelocationPossible() OVERRIDE { return false; }
51
52 verifier::VerifierDeps* GetVerifierDeps() const OVERRIDE { return deps_; }
53 void SetVerifierDeps(verifier::VerifierDeps* deps) { deps_ = deps; }
54
55 private:
56 verifier::VerifierDeps* deps_;
57};
58
Nicolas Geoffray08025182016-10-25 17:20:18 +010059class VerifierDepsTest : public CommonCompilerTest {
David Brazdilca3c8c32016-09-06 14:04:48 +010060 public:
61 void SetUpRuntimeOptions(RuntimeOptions* options) {
Nicolas Geoffray08025182016-10-25 17:20:18 +010062 CommonCompilerTest::SetUpRuntimeOptions(options);
David Brazdilca3c8c32016-09-06 14:04:48 +010063 callbacks_.reset(new VerifierDepsCompilerCallbacks());
64 }
65
66 mirror::Class* FindClassByName(const std::string& name, ScopedObjectAccess* soa)
67 REQUIRES_SHARED(Locks::mutator_lock_) {
68 StackHandleScope<1> hs(Thread::Current());
69 Handle<mirror::ClassLoader> class_loader_handle(
Mathieu Chartier0795f232016-09-27 18:43:30 -070070 hs.NewHandle(soa->Decode<mirror::ClassLoader>(class_loader_)));
David Brazdil6f82fbd2016-09-14 11:55:26 +010071 mirror::Class* klass = class_linker_->FindClass(Thread::Current(),
72 name.c_str(),
73 class_loader_handle);
74 if (klass == nullptr) {
75 DCHECK(Thread::Current()->IsExceptionPending());
76 Thread::Current()->ClearException();
77 }
78 return klass;
79 }
80
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +000081 void SetupCompilerDriver() {
82 compiler_options_->boot_image_ = false;
83 compiler_driver_->InitializeThreadPools();
84 }
85
86 void VerifyWithCompilerDriver(verifier::VerifierDeps* deps) {
87 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.
Mathieu Chartier72041a02017-07-14 18:23:25 -070090 if (deps == nullptr) {
91 // Create some verifier deps by default if they are not already specified.
92 deps = new verifier::VerifierDeps(dex_files_);
93 verifier_deps_.reset(deps);
94 }
Nicolas Geoffrayb0bbe8e2016-11-19 10:42:37 +000095 callbacks_->SetVerifierDeps(deps);
96 compiler_driver_->Verify(class_loader_, dex_files_, &timings);
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 =
Nicolas Geoffray1d0ae3f2016-12-06 13:40:16 +0000101 &compiler_driver_->GetVerificationResults()->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
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100115 void LoadDexFile(ScopedObjectAccess* soa, const char* name1, const char* name2 = nullptr)
116 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_);
122 StackHandleScope<1> hs(soa->Self());
123 Handle<mirror::ClassLoader> loader =
124 hs.NewHandle(soa->Decode<mirror::ClassLoader>(class_loader_));
125 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_) {
129 compiler_driver_->GetVerificationResults()->AddDexFile(dex_file);
130 }
Mathieu Chartier72041a02017-07-14 18:23:25 -0700131 compiler_driver_->SetDexFilesForOatFile(dex_files_);
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100132 }
133
David Brazdilca3c8c32016-09-06 14:04: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);
David Brazdilca3c8c32016-09-06 14:04:48 +0100137 klass_Main_ = FindClassByName("LMain;", soa);
138 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());
143 LoadDexFile(&soa);
144
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
150 const DexFile::ClassDef* class_def = klass_Main_->GetClassDef();
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100151 const uint8_t* class_data = primary_dex_file_->GetClassData(*class_def);
David Brazdilca3c8c32016-09-06 14:04:48 +0100152 CHECK(class_data != nullptr);
153
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100154 ClassDataItemIterator it(*primary_dex_file_, class_data);
Mathieu Chartiere17cf242017-06-19 11:05:51 -0700155 it.SkipAllFields();
David Brazdilca3c8c32016-09-06 14:04:48 +0100156
157 ArtMethod* method = nullptr;
158 while (it.HasNextDirectMethod()) {
Vladimir Markoba118822017-06-12 15:41:56 +0100159 ArtMethod* resolved_method =
160 class_linker_->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>(
Vladimir Markoba118822017-06-12 15:41:56 +0100161 it.GetMemberIndex(),
162 dex_cache_handle,
163 class_loader_handle,
Vladimir Marko89011192017-12-11 13:45:05 +0000164 /* referrer */ nullptr,
Vladimir Markoba118822017-06-12 15:41:56 +0100165 it.GetMethodInvokeType(*class_def));
David Brazdilca3c8c32016-09-06 14:04:48 +0100166 CHECK(resolved_method != nullptr);
167 if (method_name == resolved_method->GetName()) {
168 method = resolved_method;
169 break;
170 }
171 it.Next();
172 }
173 CHECK(method != nullptr);
174
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000175 Thread::Current()->SetVerifierDeps(callbacks_->GetVerifierDeps());
David Brazdilca3c8c32016-09-06 14:04:48 +0100176 MethodVerifier verifier(Thread::Current(),
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100177 primary_dex_file_,
David Brazdilca3c8c32016-09-06 14:04:48 +0100178 dex_cache_handle,
179 class_loader_handle,
180 *class_def,
181 it.GetMethodCodeItem(),
182 it.GetMemberIndex(),
183 method,
184 it.GetMethodAccessFlags(),
185 true /* can_load_classes */,
186 true /* allow_soft_failures */,
187 true /* need_precise_constants */,
188 false /* verify to dump */,
189 true /* allow_thread_suspension */);
190 verifier.Verify();
Nicolas Geoffray340dafa2016-11-18 16:03:10 +0000191 Thread::Current()->SetVerifierDeps(nullptr);
David Brazdilca3c8c32016-09-06 14:04:48 +0100192 return !verifier.HasFailures();
193 }
194
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100195 void VerifyDexFile(const char* multidex = nullptr) {
Nicolas Geoffray08025182016-10-25 17:20:18 +0100196 {
197 ScopedObjectAccess soa(Thread::Current());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100198 LoadDexFile(&soa, "VerifierDeps", multidex);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100199 }
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000200 SetupCompilerDriver();
201 VerifyWithCompilerDriver(/* verifier_deps */ nullptr);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100202 }
203
David Brazdilca3c8c32016-09-06 14:04:48 +0100204 bool TestAssignabilityRecording(const std::string& dst,
205 const std::string& src,
206 bool is_strict,
207 bool is_assignable) {
208 ScopedObjectAccess soa(Thread::Current());
209 LoadDexFile(&soa);
David Brazdil6f82fbd2016-09-14 11:55:26 +0100210 mirror::Class* klass_dst = FindClassByName(dst, &soa);
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100211 DCHECK(klass_dst != nullptr) << dst;
David Brazdil6f82fbd2016-09-14 11:55:26 +0100212 mirror::Class* klass_src = FindClassByName(src, &soa);
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +0100213 DCHECK(klass_src != nullptr) << src;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100214 verifier_deps_->AddAssignability(*primary_dex_file_,
David Brazdil6f82fbd2016-09-14 11:55:26 +0100215 klass_dst,
216 klass_src,
David Brazdilca3c8c32016-09-06 14:04:48 +0100217 is_strict,
218 is_assignable);
219 return true;
220 }
221
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000222 // Check that the status of classes in `class_loader_` match the
223 // expected status in `deps`.
224 void VerifyClassStatus(const verifier::VerifierDeps& deps) {
225 ScopedObjectAccess soa(Thread::Current());
226 StackHandleScope<2> hs(soa.Self());
227 Handle<mirror::ClassLoader> class_loader_handle(
228 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_)));
229 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
230 for (const DexFile* dex_file : dex_files_) {
Mathieu Chartierbf755fe2017-08-01 13:42:56 -0700231 const std::set<dex::TypeIndex>& unverified_classes = deps.GetUnverifiedClasses(*dex_file);
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000232 for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
233 const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
234 const char* descriptor = dex_file->GetClassDescriptor(class_def);
235 cls.Assign(class_linker_->FindClass(soa.Self(), descriptor, class_loader_handle));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800236 if (cls == nullptr) {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +0000237 CHECK(soa.Self()->IsExceptionPending());
238 soa.Self()->ClearException();
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) {
253 const DexFile::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
332 const DexFile::FieldId& field_id = dex_dep.first->GetFieldId(entry.GetDexFieldIndex());
333
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,
375 bool expected_resolved,
376 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_) {
David Brazdilca3c8c32016-09-06 14:04:48 +0100380 if (expected_resolved != entry.IsResolved()) {
381 continue;
382 }
383
384 const DexFile::MethodId& method_id = dex_dep.first->GetMethodId(entry.GetDexMethodIndex());
385
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
401 if (expected_resolved) {
402 // 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
426 size_t 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 Brazdilca3c8c32016-09-06 14:04:48 +0100452 std::unique_ptr<verifier::VerifierDeps> verifier_deps_;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100453 std::vector<const DexFile*> dex_files_;
454 const DexFile* primary_dex_file_;
David Brazdilca3c8c32016-09-06 14:04:48 +0100455 jobject class_loader_;
456 mirror::Class* klass_Main_;
457};
458
459TEST_F(VerifierDepsTest, StringToId) {
460 ScopedObjectAccess soa(Thread::Current());
461 LoadDexFile(&soa);
462
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800463 dex::StringIndex id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
464 ASSERT_LT(id_Main1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100465 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100466
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800467 dex::StringIndex id_Main2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;");
468 ASSERT_LT(id_Main2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100469 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100470
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800471 dex::StringIndex id_Lorem1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
472 ASSERT_GE(id_Lorem1.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100473 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem1));
David Brazdilca3c8c32016-09-06 14:04:48 +0100474
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800475 dex::StringIndex id_Lorem2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum");
476 ASSERT_GE(id_Lorem2.index_, primary_dex_file_->NumStringIds());
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100477 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem2));
David Brazdilca3c8c32016-09-06 14:04:48 +0100478
479 ASSERT_EQ(id_Main1, id_Main2);
480 ASSERT_EQ(id_Lorem1, id_Lorem2);
481 ASSERT_NE(id_Main1, id_Lorem1);
482}
483
484TEST_F(VerifierDepsTest, Assignable_BothInBoot) {
485 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
486 /* src */ "Ljava/util/SimpleTimeZone;",
487 /* is_strict */ true,
488 /* is_assignable */ true));
489 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
490}
491
492TEST_F(VerifierDepsTest, Assignable_DestinationInBoot1) {
493 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/net/Socket;",
494 /* src */ "LMySSLSocket;",
495 /* is_strict */ true,
496 /* is_assignable */ true));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000497 ASSERT_TRUE(HasAssignable("Ljava/net/Socket;", "Ljavax/net/ssl/SSLSocket;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100498}
499
500TEST_F(VerifierDepsTest, Assignable_DestinationInBoot2) {
501 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/TimeZone;",
502 /* src */ "LMySimpleTimeZone;",
503 /* is_strict */ true,
504 /* is_assignable */ true));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000505 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100506}
507
508TEST_F(VerifierDepsTest, Assignable_DestinationInBoot3) {
509 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/util/Collection;",
510 /* src */ "LMyThreadSet;",
511 /* is_strict */ true,
512 /* is_assignable */ true));
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +0000513 ASSERT_TRUE(HasAssignable("Ljava/util/Collection;", "Ljava/util/Set;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100514}
515
516TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) {
517 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[[Ljava/util/TimeZone;",
518 /* src */ "[[Ljava/util/SimpleTimeZone;",
519 /* is_strict */ true,
520 /* is_assignable */ true));
521 // If the component types of both arrays are resolved, we optimize the list of
522 // dependencies by recording a dependency on the component types.
523 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;", true));
524 ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;", true));
525 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
526}
527
David Brazdilca3c8c32016-09-06 14:04:48 +0100528TEST_F(VerifierDepsTest, NotAssignable_BothInBoot) {
529 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
530 /* src */ "Ljava/util/SimpleTimeZone;",
531 /* is_strict */ true,
532 /* is_assignable */ false));
533 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
534}
535
536TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot1) {
537 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
538 /* src */ "LMySSLSocket;",
539 /* is_strict */ true,
540 /* is_assignable */ false));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000541 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljavax/net/ssl/SSLSocket;", false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100542}
543
544TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot2) {
545 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
546 /* src */ "LMySimpleTimeZone;",
547 /* is_strict */ true,
548 /* is_assignable */ false));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000549 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100550}
551
552TEST_F(VerifierDepsTest, NotAssignable_BothArrays) {
553 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[Ljava/lang/Exception;",
554 /* src */ "[Ljava/util/SimpleTimeZone;",
555 /* is_strict */ true,
556 /* is_assignable */ false));
557 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false));
558}
559
560TEST_F(VerifierDepsTest, ArgumentType_ResolvedClass) {
561 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedClass"));
562 ASSERT_TRUE(HasClass("Ljava/lang/Thread;", true, "public"));
563}
564
David Brazdilca3c8c32016-09-06 14:04:48 +0100565TEST_F(VerifierDepsTest, ArgumentType_UnresolvedClass) {
566 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedClass"));
567 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
568}
569
570TEST_F(VerifierDepsTest, ArgumentType_UnresolvedSuper) {
571 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedSuper"));
572 ASSERT_TRUE(HasClass("LMySetWithUnresolvedSuper;", false));
573}
574
575TEST_F(VerifierDepsTest, ReturnType_Reference) {
576 ASSERT_TRUE(VerifyMethod("ReturnType_Reference"));
577 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
578}
579
580TEST_F(VerifierDepsTest, ReturnType_Array) {
581 ASSERT_FALSE(VerifyMethod("ReturnType_Array"));
582 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/IllegalStateException;", false));
583}
584
585TEST_F(VerifierDepsTest, InvokeArgumentType) {
586 ASSERT_TRUE(VerifyMethod("InvokeArgumentType"));
587 ASSERT_TRUE(HasClass("Ljava/text/SimpleDateFormat;", true, "public"));
588 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100589 ASSERT_TRUE(HasMethod("Ljava/text/SimpleDateFormat;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100590 "setTimeZone",
591 "(Ljava/util/TimeZone;)V",
Vladimir Markoba118822017-06-12 15:41:56 +0100592 /* expect_resolved */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100593 "public",
594 "Ljava/text/DateFormat;"));
595 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true));
596}
597
598TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) {
599 ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines"));
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000600 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100601 ASSERT_TRUE(HasAssignable(
602 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
603}
604
605TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) {
606 ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf"));
607 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
608 ASSERT_TRUE(HasAssignable(
609 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
610 ASSERT_TRUE(HasAssignable("Ljava/net/SocketTimeoutException;", "Ljava/lang/Exception;", false));
611}
612
613TEST_F(VerifierDepsTest, MergeTypes_Unresolved) {
614 ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved"));
615 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true));
616 ASSERT_TRUE(HasAssignable(
617 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true));
618}
619
620TEST_F(VerifierDepsTest, ConstClass_Resolved) {
621 ASSERT_TRUE(VerifyMethod("ConstClass_Resolved"));
622 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
623}
624
625TEST_F(VerifierDepsTest, ConstClass_Unresolved) {
Andreas Gampe629be512017-08-25 17:09:32 -0700626 ASSERT_FALSE(VerifyMethod("ConstClass_Unresolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100627 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
628}
629
630TEST_F(VerifierDepsTest, CheckCast_Resolved) {
631 ASSERT_TRUE(VerifyMethod("CheckCast_Resolved"));
632 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
633}
634
635TEST_F(VerifierDepsTest, CheckCast_Unresolved) {
Andreas Gampe629be512017-08-25 17:09:32 -0700636 ASSERT_FALSE(VerifyMethod("CheckCast_Unresolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100637 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
638}
639
640TEST_F(VerifierDepsTest, InstanceOf_Resolved) {
641 ASSERT_TRUE(VerifyMethod("InstanceOf_Resolved"));
642 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
643}
644
645TEST_F(VerifierDepsTest, InstanceOf_Unresolved) {
Andreas Gampe629be512017-08-25 17:09:32 -0700646 ASSERT_FALSE(VerifyMethod("InstanceOf_Unresolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100647 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
648}
649
650TEST_F(VerifierDepsTest, NewInstance_Resolved) {
651 ASSERT_TRUE(VerifyMethod("NewInstance_Resolved"));
652 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public"));
653}
654
655TEST_F(VerifierDepsTest, NewInstance_Unresolved) {
Andreas Gampe629be512017-08-25 17:09:32 -0700656 ASSERT_FALSE(VerifyMethod("NewInstance_Unresolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100657 ASSERT_TRUE(HasClass("LUnresolvedClass;", false));
658}
659
David Brazdilca3c8c32016-09-06 14:04:48 +0100660TEST_F(VerifierDepsTest, NewArray_Unresolved) {
Andreas Gampe629be512017-08-25 17:09:32 -0700661 ASSERT_FALSE(VerifyMethod("NewArray_Unresolved"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100662 ASSERT_TRUE(HasClass("[LUnresolvedClass;", false));
663}
664
665TEST_F(VerifierDepsTest, Throw) {
666 ASSERT_TRUE(VerifyMethod("Throw"));
667 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true));
668}
669
670TEST_F(VerifierDepsTest, MoveException_Resolved) {
671 ASSERT_TRUE(VerifyMethod("MoveException_Resolved"));
672 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
673 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
674 ASSERT_TRUE(HasClass("Ljava/util/zip/ZipException;", true, "public"));
675
676 // Testing that all exception types are assignable to Throwable.
677 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;", true));
678 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
679 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;", true));
680
681 // Testing that the merge type is assignable to Throwable.
682 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;", true));
683
684 // Merging of exception types.
685 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;", true));
686 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;", true));
687 ASSERT_TRUE(HasAssignable(
688 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
689}
690
691TEST_F(VerifierDepsTest, MoveException_Unresolved) {
692 ASSERT_FALSE(VerifyMethod("MoveException_Unresolved"));
693 ASSERT_TRUE(HasClass("LUnresolvedException;", false));
694}
695
696TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInReferenced) {
697 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInReferenced"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000698 ASSERT_TRUE(HasClass("Ljava/lang/System;", true, "public"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100699 ASSERT_TRUE(HasField("Ljava/lang/System;",
700 "out",
701 "Ljava/io/PrintStream;",
702 true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000703 "public static",
David Brazdilca3c8c32016-09-06 14:04:48 +0100704 "Ljava/lang/System;"));
705}
706
707TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass1) {
708 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass1"));
709 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public"));
710 ASSERT_TRUE(HasField(
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000711 "Ljava/util/SimpleTimeZone;", "LONG", "I", true, "public static", "Ljava/util/TimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100712}
713
714TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass2) {
715 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass2"));
716 ASSERT_TRUE(HasField(
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000717 "LMySimpleTimeZone;", "SHORT", "I", true, "public static", "Ljava/util/TimeZone;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100718}
719
720TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface1) {
721 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface1"));
722 ASSERT_TRUE(HasClass("Ljavax/xml/transform/dom/DOMResult;", true, "public"));
723 ASSERT_TRUE(HasField("Ljavax/xml/transform/dom/DOMResult;",
724 "PI_ENABLE_OUTPUT_ESCAPING",
725 "Ljava/lang/String;",
726 true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000727 "public static",
David Brazdilca3c8c32016-09-06 14:04:48 +0100728 "Ljavax/xml/transform/Result;"));
729}
730
731TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface2) {
732 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface2"));
733 ASSERT_TRUE(HasField("LMyDOMResult;",
734 "PI_ENABLE_OUTPUT_ESCAPING",
735 "Ljava/lang/String;",
736 true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000737 "public static",
David Brazdilca3c8c32016-09-06 14:04:48 +0100738 "Ljavax/xml/transform/Result;"));
739}
740
741TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface3) {
742 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface3"));
743 ASSERT_TRUE(HasField("LMyResult;",
744 "PI_ENABLE_OUTPUT_ESCAPING",
745 "Ljava/lang/String;",
746 true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000747 "public static",
David Brazdilca3c8c32016-09-06 14:04:48 +0100748 "Ljavax/xml/transform/Result;"));
749}
750
751TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface4) {
752 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface4"));
753 ASSERT_TRUE(HasField("LMyDocument;",
754 "ELEMENT_NODE",
755 "S",
756 true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000757 "public static",
David Brazdilca3c8c32016-09-06 14:04:48 +0100758 "Lorg/w3c/dom/Node;"));
759}
760
761TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInBoot) {
762 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInBoot"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000763 ASSERT_TRUE(HasClass("Ljava/util/TimeZone;", true, "public"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100764 ASSERT_TRUE(HasField("Ljava/util/TimeZone;", "x", "I", false));
765}
766
767TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInDex) {
768 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInDex"));
769 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
770}
771
772TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) {
773 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced"));
774 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
775 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;",
776 "bytesTransferred",
777 "I",
778 true,
779 "public",
780 "Ljava/io/InterruptedIOException;"));
781 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000782 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100783}
784
785TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) {
786 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1"));
787 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public"));
788 ASSERT_TRUE(HasField("Ljava/net/SocketTimeoutException;",
789 "bytesTransferred",
790 "I",
791 true,
792 "public",
793 "Ljava/io/InterruptedIOException;"));
794 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000795 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100796}
797
798TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) {
799 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2"));
800 ASSERT_TRUE(HasField("LMySocketTimeoutException;",
801 "bytesTransferred",
802 "I",
803 true,
804 "public",
805 "Ljava/io/InterruptedIOException;"));
806 ASSERT_TRUE(HasAssignable(
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000807 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100808}
809
810TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInBoot) {
811 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInBoot"));
812 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
813 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;", "x", "I", false));
814}
815
816TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInDex) {
817 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInDex"));
818 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false));
819}
820
821TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInReferenced) {
822 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInReferenced"));
823 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100824 ASSERT_TRUE(HasMethod("Ljava/net/Socket;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100825 "setSocketImplFactory",
826 "(Ljava/net/SocketImplFactory;)V",
Vladimir Markoba118822017-06-12 15:41:56 +0100827 /* expect_resolved */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100828 "public static",
829 "Ljava/net/Socket;"));
830}
831
832TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass1) {
833 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000834 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100835 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100836 "setSocketImplFactory",
837 "(Ljava/net/SocketImplFactory;)V",
Vladimir Markoba118822017-06-12 15:41:56 +0100838 /* expect_resolved */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100839 "public static",
840 "Ljava/net/Socket;"));
841}
842
843TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass2) {
844 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass2"));
Vladimir Markoba118822017-06-12 15:41:56 +0100845 ASSERT_TRUE(HasMethod("LMySSLSocket;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100846 "setSocketImplFactory",
847 "(Ljava/net/SocketImplFactory;)V",
Vladimir Markoba118822017-06-12 15:41:56 +0100848 /* expect_resolved */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100849 "public static",
850 "Ljava/net/Socket;"));
851}
852
853TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface1) {
854 ASSERT_TRUE(VerifyMethod("InvokeStatic_DeclaredInInterface1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000855 ASSERT_TRUE(HasClass("Ljava/util/Map$Entry;", true, "public interface"));
Vladimir Markoba118822017-06-12 15:41:56 +0100856 ASSERT_TRUE(HasMethod("Ljava/util/Map$Entry;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100857 "comparingByKey",
858 "()Ljava/util/Comparator;",
Vladimir Markoba118822017-06-12 15:41:56 +0100859 /* expect_resolved */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100860 "public static",
861 "Ljava/util/Map$Entry;"));
862}
863
864TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface2) {
865 ASSERT_FALSE(VerifyMethod("InvokeStatic_DeclaredInInterface2"));
866 ASSERT_TRUE(HasClass("Ljava/util/AbstractMap$SimpleEntry;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100867 ASSERT_TRUE(HasMethod("Ljava/util/AbstractMap$SimpleEntry;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100868 "comparingByKey",
869 "()Ljava/util/Comparator;",
Vladimir Markoba118822017-06-12 15:41:56 +0100870 /* expect_resolved */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100871}
872
873TEST_F(VerifierDepsTest, InvokeStatic_Unresolved1) {
874 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000875 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100876 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
877 "x",
878 "()V",
879 /* expect_resolved */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100880}
881
882TEST_F(VerifierDepsTest, InvokeStatic_Unresolved2) {
883 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved2"));
Vladimir Markoba118822017-06-12 15:41:56 +0100884 ASSERT_TRUE(HasMethod("LMySSLSocket;",
885 "x",
886 "()V",
887 /* expect_resolved */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100888}
889
890TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInReferenced) {
891 ASSERT_TRUE(VerifyMethod("InvokeDirect_Resolved_DeclaredInReferenced"));
892 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100893 ASSERT_TRUE(HasMethod("Ljava/net/Socket;",
894 "<init>",
895 "()V",
896 /* expect_resolved */ true,
897 "public",
898 "Ljava/net/Socket;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100899}
900
901TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass1) {
902 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000903 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100904 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100905 "checkOldImpl",
906 "()V",
Vladimir Markoba118822017-06-12 15:41:56 +0100907 /* expect_resolved */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100908 "private",
909 "Ljava/net/Socket;"));
910}
911
912TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass2) {
913 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass2"));
Vladimir Markoba118822017-06-12 15:41:56 +0100914 ASSERT_TRUE(HasMethod("LMySSLSocket;",
915 "checkOldImpl",
916 "()V",
917 /* expect_resolved */ true,
918 "private",
919 "Ljava/net/Socket;"));
David Brazdilca3c8c32016-09-06 14:04:48 +0100920}
921
922TEST_F(VerifierDepsTest, InvokeDirect_Unresolved1) {
923 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000924 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100925 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;",
926 "x",
927 "()V",
928 /* expect_resolved */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100929}
930
931TEST_F(VerifierDepsTest, InvokeDirect_Unresolved2) {
932 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved2"));
Vladimir Markoba118822017-06-12 15:41:56 +0100933 ASSERT_TRUE(HasMethod("LMySSLSocket;",
934 "x",
935 "()V",
936 /* expect_resolved */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100937}
938
939TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) {
940 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced"));
941 ASSERT_TRUE(HasClass("Ljava/lang/Throwable;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100942 ASSERT_TRUE(HasMethod("Ljava/lang/Throwable;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100943 "getMessage",
944 "()Ljava/lang/String;",
Vladimir Markoba118822017-06-12 15:41:56 +0100945 /* expect_resolved */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100946 "public",
947 "Ljava/lang/Throwable;"));
948 // Type dependency on `this` argument.
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000949 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100950}
951
952TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) {
953 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1"));
954 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100955 ASSERT_TRUE(HasMethod("Ljava/io/InterruptedIOException;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100956 "getMessage",
957 "()Ljava/lang/String;",
Vladimir Markoba118822017-06-12 15:41:56 +0100958 /* expect_resolved */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100959 "public",
960 "Ljava/lang/Throwable;"));
961 // Type dependency on `this` argument.
Nicolas Geoffray119e8462016-12-21 10:29:43 +0000962 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true));
David Brazdilca3c8c32016-09-06 14:04:48 +0100963}
964
965TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass2) {
966 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass2"));
Vladimir Markoba118822017-06-12 15:41:56 +0100967 ASSERT_TRUE(HasMethod("LMySocketTimeoutException;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100968 "getMessage",
969 "()Ljava/lang/String;",
Vladimir Markoba118822017-06-12 15:41:56 +0100970 /* expect_resolved */ true,
David Brazdilca3c8c32016-09-06 14:04:48 +0100971 "public",
972 "Ljava/lang/Throwable;"));
973}
974
975TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperinterface) {
976 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperinterface"));
Vladimir Markoba118822017-06-12 15:41:56 +0100977 ASSERT_TRUE(HasMethod("LMyThreadSet;",
David Brazdilca3c8c32016-09-06 14:04:48 +0100978 "size",
979 "()I",
Vladimir Markoba118822017-06-12 15:41:56 +0100980 /* expect_resolved */ true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +0000981 "public",
David Brazdilca3c8c32016-09-06 14:04:48 +0100982 "Ljava/util/Set;"));
983}
984
985TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved1) {
986 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved1"));
987 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public"));
Vladimir Markoba118822017-06-12 15:41:56 +0100988 ASSERT_TRUE(HasMethod("Ljava/io/InterruptedIOException;",
989 "x",
990 "()V",
991 /* expect_resolved */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +0100992}
993
994TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved2) {
995 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved2"));
Vladimir Markoba118822017-06-12 15:41:56 +0100996 ASSERT_TRUE(HasMethod("LMySocketTimeoutException;",
997 "x",
998 "()V",
999 /* expect_resolved */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +01001000}
1001
1002TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInReferenced) {
1003 ASSERT_TRUE(VerifyMethod("InvokeInterface_Resolved_DeclaredInReferenced"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001004 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface"));
Vladimir Markoba118822017-06-12 15:41:56 +01001005 ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;",
David Brazdilca3c8c32016-09-06 14:04:48 +01001006 "run",
1007 "()V",
Vladimir Markoba118822017-06-12 15:41:56 +01001008 /* expect_resolved */ true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001009 "public",
David Brazdilca3c8c32016-09-06 14:04:48 +01001010 "Ljava/lang/Runnable;"));
1011}
1012
1013TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperclass) {
1014 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperclass"));
Vladimir Markoba118822017-06-12 15:41:56 +01001015 // TODO: Maybe we should not record dependency if the invoke type does not match the lookup type.
1016 ASSERT_TRUE(HasMethod("LMyThread;",
1017 "join",
1018 "()V",
1019 /* expect_resolved */ true,
1020 "public",
1021 "Ljava/lang/Thread;"));
David Brazdilca3c8c32016-09-06 14:04:48 +01001022}
1023
1024TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface1) {
1025 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface1"));
Vladimir Markoba118822017-06-12 15:41:56 +01001026 // TODO: Maybe we should not record dependency if the invoke type does not match the lookup type.
1027 ASSERT_TRUE(HasMethod("LMyThreadSet;",
David Brazdilca3c8c32016-09-06 14:04:48 +01001028 "run",
1029 "()V",
Vladimir Markoba118822017-06-12 15:41:56 +01001030 /* expect_resolved */ true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001031 "public",
Vladimir Markoba118822017-06-12 15:41:56 +01001032 "Ljava/lang/Thread;"));
David Brazdilca3c8c32016-09-06 14:04:48 +01001033}
1034
1035TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface2) {
1036 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface2"));
Vladimir Markoba118822017-06-12 15:41:56 +01001037 ASSERT_TRUE(HasMethod("LMyThreadSet;",
David Brazdilca3c8c32016-09-06 14:04:48 +01001038 "isEmpty",
1039 "()Z",
Vladimir Markoba118822017-06-12 15:41:56 +01001040 /* expect_resolved */ true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001041 "public",
David Brazdilca3c8c32016-09-06 14:04:48 +01001042 "Ljava/util/Set;"));
1043}
1044
1045TEST_F(VerifierDepsTest, InvokeInterface_Unresolved1) {
1046 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved1"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001047 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface"));
Vladimir Markoba118822017-06-12 15:41:56 +01001048 ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;",
1049 "x",
1050 "()V",
1051 /* expect_resolved */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +01001052}
1053
1054TEST_F(VerifierDepsTest, InvokeInterface_Unresolved2) {
1055 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved2"));
Vladimir Markoba118822017-06-12 15:41:56 +01001056 ASSERT_TRUE(HasMethod("LMyThreadSet;", "x", "()V", /* expect_resolved */ false));
David Brazdilca3c8c32016-09-06 14:04:48 +01001057}
1058
1059TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) {
1060 ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001061 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface"));
Nicolas Geoffray0e2fe0f2016-12-21 16:54:52 +00001062 ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "Ljava/lang/Thread;", true));
Vladimir Markoba118822017-06-12 15:41:56 +01001063 ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;",
David Brazdilca3c8c32016-09-06 14:04:48 +01001064 "run",
1065 "()V",
Vladimir Markoba118822017-06-12 15:41:56 +01001066 /* expect_resolved */ true,
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001067 "public",
David Brazdilca3c8c32016-09-06 14:04:48 +01001068 "Ljava/lang/Runnable;"));
1069}
1070
1071TEST_F(VerifierDepsTest, InvokeSuper_ThisNotAssignable) {
1072 ASSERT_FALSE(VerifyMethod("InvokeSuper_ThisNotAssignable"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001073 ASSERT_TRUE(HasClass("Ljava/lang/Integer;", true, "public"));
Nicolas Geoffray119e8462016-12-21 10:29:43 +00001074 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/Thread;", false));
Vladimir Markoba118822017-06-12 15:41:56 +01001075 ASSERT_TRUE(HasMethod("Ljava/lang/Integer;",
1076 "intValue", "()I",
1077 /* expect_resolved */ true,
1078 "public", "Ljava/lang/Integer;"));
David Brazdilca3c8c32016-09-06 14:04:48 +01001079}
1080
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +00001081TEST_F(VerifierDepsTest, ArgumentType_ResolvedReferenceArray) {
1082 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedReferenceArray"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001083 ASSERT_TRUE(HasClass("[Ljava/lang/Thread;", true, "public"));
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +00001084}
1085
1086TEST_F(VerifierDepsTest, NewArray_Resolved) {
1087 ASSERT_TRUE(VerifyMethod("NewArray_Resolved"));
Nicolas Geoffray6e54f782017-03-08 15:27:09 +00001088 ASSERT_TRUE(HasClass("[Ljava/lang/IllegalStateException;", true, "public"));
Nicolas Geoffray0f1cb172017-01-05 15:23:19 +00001089}
1090
David Brazdil6f82fbd2016-09-14 11:55:26 +01001091TEST_F(VerifierDepsTest, EncodeDecode) {
1092 VerifyDexFile();
1093
1094 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1095 ASSERT_TRUE(HasEachKindOfRecord());
1096
1097 std::vector<uint8_t> buffer;
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001098 verifier_deps_->Encode(dex_files_, &buffer);
David Brazdil6f82fbd2016-09-14 11:55:26 +01001099 ASSERT_FALSE(buffer.empty());
1100
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001101 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
David Brazdil6f82fbd2016-09-14 11:55:26 +01001102 ASSERT_TRUE(verifier_deps_->Equals(decoded_deps));
1103}
1104
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001105TEST_F(VerifierDepsTest, EncodeDecodeMulti) {
1106 VerifyDexFile("MultiDex");
1107
1108 ASSERT_GT(NumberOfCompiledDexFiles(), 1u);
1109 std::vector<uint8_t> buffer;
1110 verifier_deps_->Encode(dex_files_, &buffer);
1111 ASSERT_FALSE(buffer.empty());
1112
1113 // Create new DexFile, to mess with std::map order: the verifier deps used
1114 // to iterate over the map, which doesn't guarantee insertion order. We fixed
1115 // this by passing the expected order when encoding/decoding.
1116 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles("VerifierDeps");
1117 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles("MultiDex");
1118 std::vector<const DexFile*> dex_files;
1119 for (auto& dex_file : first_dex_files) {
1120 dex_files.push_back(dex_file.get());
1121 }
1122 for (auto& dex_file : second_dex_files) {
1123 dex_files.push_back(dex_file.get());
1124 }
1125
1126 // Dump the new verifier deps to ensure it can properly read the data.
Nicolas Geoffraye70dd562016-10-30 21:03:35 +00001127 VerifierDeps decoded_deps(dex_files, ArrayRef<const uint8_t>(buffer));
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +01001128 std::ostringstream stream;
1129 VariableIndentationOutputStream os(&stream);
1130 decoded_deps.Dump(&os);
1131}
1132
Nicolas Geoffray08025182016-10-25 17:20:18 +01001133TEST_F(VerifierDepsTest, UnverifiedClasses) {
1134 VerifyDexFile();
1135 ASSERT_FALSE(HasUnverifiedClass("LMyThread;"));
1136 // Test that a class with a soft failure is recorded.
1137 ASSERT_TRUE(HasUnverifiedClass("LMain;"));
1138 // Test that a class with hard failure is recorded.
1139 ASSERT_TRUE(HasUnverifiedClass("LMyVerificationFailure;"));
1140 // Test that a class with unresolved super is recorded.
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +00001141 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuper;"));
Nicolas Geoffray08025182016-10-25 17:20:18 +01001142 // Test that a class with unresolved super and hard failure is recorded.
1143 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;"));
1144}
1145
Mathieu Chartierbf755fe2017-08-01 13:42:56 -07001146TEST_F(VerifierDepsTest, UnverifiedOrder) {
1147 ScopedObjectAccess soa(Thread::Current());
1148 jobject loader = LoadDex("VerifierDeps");
1149 std::vector<const DexFile*> dex_files = GetDexFiles(loader);
1150 ASSERT_GT(dex_files.size(), 0u);
1151 const DexFile* dex_file = dex_files[0];
1152 VerifierDeps deps1(dex_files);
1153 Thread* const self = Thread::Current();
1154 ASSERT_TRUE(self->GetVerifierDeps() == nullptr);
1155 self->SetVerifierDeps(&deps1);
1156 deps1.MaybeRecordVerificationStatus(*dex_file,
1157 dex::TypeIndex(0),
1158 verifier::FailureKind::kHardFailure);
1159 deps1.MaybeRecordVerificationStatus(*dex_file,
1160 dex::TypeIndex(1),
1161 verifier::FailureKind::kHardFailure);
1162 VerifierDeps deps2(dex_files);
1163 self->SetVerifierDeps(nullptr);
1164 self->SetVerifierDeps(&deps2);
1165 deps2.MaybeRecordVerificationStatus(*dex_file,
1166 dex::TypeIndex(1),
1167 verifier::FailureKind::kHardFailure);
1168 deps2.MaybeRecordVerificationStatus(*dex_file,
1169 dex::TypeIndex(0),
1170 verifier::FailureKind::kHardFailure);
1171 self->SetVerifierDeps(nullptr);
1172 std::vector<uint8_t> buffer1;
1173 deps1.Encode(dex_files, &buffer1);
1174 std::vector<uint8_t> buffer2;
1175 deps2.Encode(dex_files, &buffer2);
1176 EXPECT_EQ(buffer1, buffer2);
1177}
1178
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001179TEST_F(VerifierDepsTest, VerifyDeps) {
1180 VerifyDexFile();
1181
1182 ASSERT_EQ(1u, NumberOfCompiledDexFiles());
1183 ASSERT_TRUE(HasEachKindOfRecord());
1184
1185 // When validating, we create a new class loader, as
1186 // the existing `class_loader_` may contain erroneous classes,
1187 // that ClassLinker::FindClass won't return.
1188
1189 ScopedObjectAccess soa(Thread::Current());
1190 StackHandleScope<1> hs(soa.Self());
1191 MutableHandle<mirror::ClassLoader> new_class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
1192 {
1193 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001194 ASSERT_TRUE(verifier_deps_->ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001195 }
1196
1197 std::vector<uint8_t> buffer;
1198 verifier_deps_->Encode(dex_files_, &buffer);
1199 ASSERT_FALSE(buffer.empty());
1200
1201 {
1202 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1203 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001204 ASSERT_TRUE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001205 }
1206
1207 // Fiddle with the dependencies to make sure we catch any change and fail to verify.
1208
1209 {
1210 // Mess up with the assignable_types.
1211 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1212 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1213 deps->assignable_types_.insert(*deps->unassignable_types_.begin());
1214 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001215 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001216 }
1217
1218 {
1219 // Mess up with the unassignable_types.
1220 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1221 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1222 deps->unassignable_types_.insert(*deps->assignable_types_.begin());
1223 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001224 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001225 }
1226
1227 // Mess up with classes.
1228 {
1229 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1230 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1231 bool found = false;
1232 for (const auto& entry : deps->classes_) {
1233 if (entry.IsResolved()) {
1234 deps->classes_.insert(VerifierDeps::ClassResolution(
1235 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker));
1236 found = true;
1237 break;
1238 }
1239 }
1240 ASSERT_TRUE(found);
1241 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001242 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001243 }
1244
1245 {
1246 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1247 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1248 bool found = false;
1249 for (const auto& entry : deps->classes_) {
1250 if (!entry.IsResolved()) {
1251 deps->classes_.insert(VerifierDeps::ClassResolution(
1252 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker - 1));
1253 found = true;
1254 break;
1255 }
1256 }
1257 ASSERT_TRUE(found);
1258 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001259 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001260 }
1261
1262 {
1263 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1264 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1265 bool found = false;
1266 for (const auto& entry : deps->classes_) {
1267 if (entry.IsResolved()) {
1268 deps->classes_.insert(VerifierDeps::ClassResolution(
1269 entry.GetDexTypeIndex(), entry.GetAccessFlags() - 1));
1270 found = true;
1271 break;
1272 }
1273 }
1274 ASSERT_TRUE(found);
1275 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001276 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001277 }
1278
1279 // Mess up with fields.
1280 {
1281 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1282 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1283 bool found = false;
1284 for (const auto& entry : deps->fields_) {
1285 if (entry.IsResolved()) {
1286 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1287 VerifierDeps::kUnresolvedMarker,
1288 entry.GetDeclaringClassIndex()));
1289 found = true;
1290 break;
1291 }
1292 }
1293 ASSERT_TRUE(found);
1294 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001295 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001296 }
1297
1298 {
1299 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1300 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1301 bool found = false;
1302 for (const auto& entry : deps->fields_) {
1303 if (!entry.IsResolved()) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001304 constexpr dex::StringIndex kStringIndexZero(0); // We know there is a class there.
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001305 deps->fields_.insert(VerifierDeps::FieldResolution(0 /* we know there is a field there */,
1306 VerifierDeps::kUnresolvedMarker - 1,
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001307 kStringIndexZero));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001308 found = true;
1309 break;
1310 }
1311 }
1312 ASSERT_TRUE(found);
1313 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001314 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001315 }
1316
1317 {
1318 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1319 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1320 bool found = false;
1321 for (const auto& entry : deps->fields_) {
1322 if (entry.IsResolved()) {
1323 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1324 entry.GetAccessFlags() - 1,
1325 entry.GetDeclaringClassIndex()));
1326 found = true;
1327 break;
1328 }
1329 }
1330 ASSERT_TRUE(found);
1331 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001332 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001333 }
1334
1335 {
1336 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1337 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1338 bool found = false;
1339 for (const auto& entry : deps->fields_) {
Andreas Gampe8a0128a2016-11-28 07:38:35 -08001340 constexpr dex::StringIndex kNewTypeIndex(0);
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001341 if (entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1342 deps->fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(),
1343 entry.GetAccessFlags(),
1344 kNewTypeIndex));
1345 found = true;
1346 break;
1347 }
1348 }
1349 ASSERT_TRUE(found);
1350 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001351 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001352 }
1353
1354 // Mess up with methods.
Vladimir Markoba118822017-06-12 15:41:56 +01001355 {
1356 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1357 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1358 bool found = false;
1359 std::set<VerifierDeps::MethodResolution>* methods = &deps->methods_;
1360 for (const auto& entry : *methods) {
1361 if (entry.IsResolved()) {
1362 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1363 VerifierDeps::kUnresolvedMarker,
1364 entry.GetDeclaringClassIndex()));
1365 found = true;
1366 break;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001367 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001368 }
Vladimir Markoba118822017-06-12 15:41:56 +01001369 ASSERT_TRUE(found);
1370 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1371 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
1372 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001373
Vladimir Markoba118822017-06-12 15:41:56 +01001374 {
1375 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1376 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1377 bool found = false;
1378 std::set<VerifierDeps::MethodResolution>* methods = &deps->methods_;
1379 for (const auto& entry : *methods) {
1380 if (!entry.IsResolved()) {
1381 constexpr dex::StringIndex kStringIndexZero(0); // We know there is a class there.
1382 methods->insert(VerifierDeps::MethodResolution(0 /* we know there is a method there */,
1383 VerifierDeps::kUnresolvedMarker - 1,
1384 kStringIndexZero));
1385 found = true;
1386 break;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001387 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001388 }
Vladimir Markoba118822017-06-12 15:41:56 +01001389 ASSERT_TRUE(found);
1390 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1391 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
1392 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001393
Vladimir Markoba118822017-06-12 15:41:56 +01001394 {
1395 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1396 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1397 bool found = false;
1398 std::set<VerifierDeps::MethodResolution>* methods = &deps->methods_;
1399 for (const auto& entry : *methods) {
1400 if (entry.IsResolved()) {
1401 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1402 entry.GetAccessFlags() - 1,
1403 entry.GetDeclaringClassIndex()));
1404 found = true;
1405 break;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001406 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001407 }
Vladimir Markoba118822017-06-12 15:41:56 +01001408 ASSERT_TRUE(found);
1409 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1410 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
1411 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001412
Vladimir Markoba118822017-06-12 15:41:56 +01001413 {
1414 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1415 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1416 bool found = false;
1417 std::set<VerifierDeps::MethodResolution>* methods = &deps->methods_;
1418 for (const auto& entry : *methods) {
1419 constexpr dex::StringIndex kNewTypeIndex(0);
1420 if (entry.IsResolved() && entry.GetDeclaringClassIndex() != kNewTypeIndex) {
1421 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(),
1422 entry.GetAccessFlags(),
1423 kNewTypeIndex));
1424 found = true;
1425 break;
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001426 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001427 }
Vladimir Markoba118822017-06-12 15:41:56 +01001428 ASSERT_TRUE(found);
1429 new_class_loader.Assign(soa.Decode<mirror::ClassLoader>(LoadDex("VerifierDeps")));
1430 ASSERT_FALSE(decoded_deps.ValidateDependencies(new_class_loader, soa.Self()));
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001431 }
1432}
1433
1434TEST_F(VerifierDepsTest, CompilerDriver) {
1435 SetupCompilerDriver();
1436
1437 // Test both multi-dex and single-dex configuration.
1438 for (const char* multi : { "MultiDex", static_cast<const char*>(nullptr) }) {
1439 // Test that the compiler driver behaves as expected when the dependencies
1440 // verify and when they don't verify.
1441 for (bool verify_failure : { false, true }) {
1442 {
1443 ScopedObjectAccess soa(Thread::Current());
1444 LoadDexFile(&soa, "VerifierDeps", multi);
1445 }
1446 VerifyWithCompilerDriver(/* verifier_deps */ nullptr);
1447
1448 std::vector<uint8_t> buffer;
1449 verifier_deps_->Encode(dex_files_, &buffer);
1450
1451 {
1452 ScopedObjectAccess soa(Thread::Current());
1453 LoadDexFile(&soa, "VerifierDeps", multi);
1454 }
1455 verifier::VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
1456 if (verify_failure) {
1457 // Just taint the decoded VerifierDeps with one invalid entry.
1458 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_);
1459 bool found = false;
1460 for (const auto& entry : deps->classes_) {
1461 if (entry.IsResolved()) {
1462 deps->classes_.insert(VerifierDeps::ClassResolution(
1463 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker));
1464 found = true;
1465 break;
1466 }
1467 }
1468 ASSERT_TRUE(found);
1469 }
1470 VerifyWithCompilerDriver(&decoded_deps);
1471
1472 if (verify_failure) {
1473 ASSERT_FALSE(verifier_deps_ == nullptr);
1474 ASSERT_FALSE(verifier_deps_->Equals(decoded_deps));
1475 } else {
Nicolas Geoffray6bb7f1b2016-11-03 10:52:49 +00001476 VerifyClassStatus(decoded_deps);
1477 }
Nicolas Geoffray8904b6f2016-10-28 19:50:34 +01001478 }
1479 }
1480}
1481
Nicolas Geoffray7cc3ae52017-03-07 14:33:37 +00001482TEST_F(VerifierDepsTest, MultiDexVerification) {
1483 VerifyDexFile("VerifierDepsMulti");
1484 ASSERT_EQ(NumberOfCompiledDexFiles(), 2u);
1485
1486 ASSERT_TRUE(HasUnverifiedClass("LMySoftVerificationFailure;", *dex_files_[1]));
1487 ASSERT_TRUE(HasUnverifiedClass("LMySub1SoftVerificationFailure;", *dex_files_[0]));
1488 ASSERT_TRUE(HasUnverifiedClass("LMySub2SoftVerificationFailure;", *dex_files_[0]));
1489
1490 std::vector<uint8_t> buffer;
1491 verifier_deps_->Encode(dex_files_, &buffer);
1492 ASSERT_FALSE(buffer.empty());
1493}
1494
Nicolas Geoffrayfc38e912017-03-16 16:51:59 +00001495TEST_F(VerifierDepsTest, NotAssignable_InterfaceWithClassInBoot) {
1496 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "Ljava/lang/Exception;",
1497 /* src */ "LIface;",
1498 /* is_strict */ true,
1499 /* is_assignable */ false));
1500 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LIface;", false));
1501}
1502
Nicolas Geoffraybdb540d2017-04-19 13:50:34 +01001503TEST_F(VerifierDepsTest, Assignable_Arrays) {
1504 ASSERT_TRUE(TestAssignabilityRecording(/* dst */ "[LIface;",
1505 /* src */ "[LMyClassExtendingInterface;",
1506 /* is_strict */ false,
1507 /* is_assignable */ true));
1508 ASSERT_FALSE(HasAssignable(
1509 "LIface;", "LMyClassExtendingInterface;", /* expected_is_assignable */ true));
1510 ASSERT_FALSE(HasAssignable(
1511 "LIface;", "LMyClassExtendingInterface;", /* expected_is_assignable */ false));
1512}
1513
David Brazdilca3c8c32016-09-06 14:04:48 +01001514} // namespace verifier
1515} // namespace art