1 /* 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 17 // Test is in compiler, as it uses compiler related code. 18 #include "verifier/verifier_deps.h" 19 20 #include "art_method-inl.h" 21 #include "base/indenter.h" 22 #include "class_linker.h" 23 #include "common_compiler_driver_test.h" 24 #include "compiler_callbacks.h" 25 #include "dex/class_accessor-inl.h" 26 #include "dex/class_iterator.h" 27 #include "dex/dex_file-inl.h" 28 #include "dex/dex_file_types.h" 29 #include "dex/verification_results.h" 30 #include "dex/verified_method.h" 31 #include "driver/compiler_driver-inl.h" 32 #include "driver/compiler_options.h" 33 #include "handle_scope-inl.h" 34 #include "mirror/class_loader.h" 35 #include "runtime.h" 36 #include "scoped_thread_state_change-inl.h" 37 #include "thread.h" 38 #include "utils/atomic_dex_ref_map-inl.h" 39 #include "verifier/method_verifier-inl.h" 40 41 namespace art { 42 namespace verifier { 43 44 class VerifierDepsCompilerCallbacks : public CompilerCallbacks { 45 public: 46 VerifierDepsCompilerCallbacks() 47 : CompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp), 48 deps_(nullptr) {} 49 50 void MethodVerified(verifier::MethodVerifier* verifier ATTRIBUTE_UNUSED) override {} 51 void ClassRejected(ClassReference ref ATTRIBUTE_UNUSED) override {} 52 53 verifier::VerifierDeps* GetVerifierDeps() const override { return deps_; } 54 void SetVerifierDeps(verifier::VerifierDeps* deps) override { deps_ = deps; } 55 56 private: 57 verifier::VerifierDeps* deps_; 58 }; 59 60 class VerifierDepsTest : public CommonCompilerDriverTest { 61 public: 62 void SetUpRuntimeOptions(RuntimeOptions* options) override { 63 CommonCompilerTest::SetUpRuntimeOptions(options); 64 callbacks_.reset(new VerifierDepsCompilerCallbacks()); 65 } 66 67 ObjPtr<mirror::Class> FindClassByName(ScopedObjectAccess& soa, const std::string& name) 68 REQUIRES_SHARED(Locks::mutator_lock_) { 69 StackHandleScope<1> hs(soa.Self()); 70 Handle<mirror::ClassLoader> class_loader_handle( 71 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); 74 if (klass == nullptr) { 75 DCHECK(soa.Self()->IsExceptionPending()); 76 soa.Self()->ClearException(); 77 } 78 return klass; 79 } 80 81 void SetupCompilerDriver() { 82 compiler_options_->image_type_ = CompilerOptions::ImageType::kNone; 83 compiler_driver_->InitializeThreadPools(); 84 } 85 86 void VerifyWithCompilerDriver(verifier::VerifierDeps* verifier_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. 90 if (verifier_deps == nullptr) { 91 // Create some verifier deps by default if they are not already specified. 92 verifier_deps = new verifier::VerifierDeps(dex_files_); 93 verifier_deps_.reset(verifier_deps); 94 } 95 callbacks_->SetVerifierDeps(verifier_deps); 96 compiler_driver_->Verify(class_loader_, dex_files_, &timings, verification_results_.get()); 97 callbacks_->SetVerifierDeps(nullptr); 98 // Clear entries in the verification results to avoid hitting a DCHECK that 99 // we always succeed inserting a new entry after verifying. 100 AtomicDexRefMap<MethodReference, const VerifiedMethod*>* map = 101 &verification_results_->atomic_verified_methods_; 102 map->Visit([](const DexFileReference& ref ATTRIBUTE_UNUSED, const VerifiedMethod* method) { 103 delete method; 104 }); 105 map->ClearEntries(); 106 } 107 108 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()); 113 } 114 115 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 } 128 for (const DexFile* dex_file : dex_files_) { 129 verification_results_->AddDexFile(dex_file); 130 } 131 SetDexFilesForOatFile(dex_files_); 132 } 133 134 void LoadDexFile(ScopedObjectAccess& soa) REQUIRES_SHARED(Locks::mutator_lock_) { 135 LoadDexFile(soa, "VerifierDeps"); 136 CHECK_EQ(dex_files_.size(), 1u); 137 klass_Main_ = FindClassByName(soa, "LMain;"); 138 CHECK(klass_Main_ != nullptr); 139 } 140 141 bool VerifyMethod(const std::string& method_name) { 142 ScopedObjectAccess soa(Thread::Current()); 143 LoadDexFile(soa); 144 145 StackHandleScope<2> hs(soa.Self()); 146 Handle<mirror::ClassLoader> class_loader_handle( 147 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_))); 148 Handle<mirror::DexCache> dex_cache_handle(hs.NewHandle(klass_Main_->GetDexCache())); 149 150 const dex::ClassDef* class_def = klass_Main_->GetClassDef(); 151 ClassAccessor accessor(*primary_dex_file_, *class_def); 152 153 bool has_failures = true; 154 bool found_method = false; 155 156 for (const ClassAccessor::Method& method : accessor.GetMethods()) { 157 ArtMethod* resolved_method = 158 class_linker_->ResolveMethod<ClassLinker::ResolveMode::kNoChecks>( 159 method.GetIndex(), 160 dex_cache_handle, 161 class_loader_handle, 162 /* referrer= */ nullptr, 163 method.GetInvokeType(class_def->access_flags_)); 164 CHECK(resolved_method != nullptr); 165 if (method_name == resolved_method->GetName()) { 166 soa.Self()->SetVerifierDeps(callbacks_->GetVerifierDeps()); 167 std::unique_ptr<MethodVerifier> verifier( 168 MethodVerifier::CreateVerifier(soa.Self(), 169 primary_dex_file_, 170 dex_cache_handle, 171 class_loader_handle, 172 *class_def, 173 method.GetCodeItem(), 174 method.GetIndex(), 175 resolved_method, 176 method.GetAccessFlags(), 177 /* can_load_classes= */ true, 178 /* allow_soft_failures= */ true, 179 /* need_precise_constants= */ true, 180 /* verify to dump */ false, 181 /* allow_thread_suspension= */ true, 182 /* api_level= */ 0)); 183 verifier->Verify(); 184 soa.Self()->SetVerifierDeps(nullptr); 185 has_failures = verifier->HasFailures(); 186 found_method = true; 187 } 188 } 189 CHECK(found_method) << "Expected to find method " << method_name; 190 return !has_failures; 191 } 192 193 void VerifyDexFile(const char* multidex = nullptr) { 194 { 195 ScopedObjectAccess soa(Thread::Current()); 196 LoadDexFile(soa, "VerifierDeps", multidex); 197 } 198 SetupCompilerDriver(); 199 VerifyWithCompilerDriver(/* verifier_deps= */ nullptr); 200 } 201 202 bool TestAssignabilityRecording(const std::string& dst, 203 const std::string& src, 204 bool is_strict, 205 bool is_assignable) { 206 ScopedObjectAccess soa(Thread::Current()); 207 LoadDexFile(soa); 208 StackHandleScope<1> hs(soa.Self()); 209 Handle<mirror::Class> klass_dst = hs.NewHandle(FindClassByName(soa, dst)); 210 DCHECK(klass_dst != nullptr) << dst; 211 ObjPtr<mirror::Class> klass_src = FindClassByName(soa, src); 212 DCHECK(klass_src != nullptr) << src; 213 verifier_deps_->AddAssignability(*primary_dex_file_, 214 klass_dst.Get(), 215 klass_src, 216 is_strict, 217 is_assignable); 218 return true; 219 } 220 221 // Check that the status of classes in `class_loader_` match the 222 // expected status in `deps`. 223 void VerifyClassStatus(const verifier::VerifierDeps& deps) { 224 ScopedObjectAccess soa(Thread::Current()); 225 StackHandleScope<2> hs(soa.Self()); 226 Handle<mirror::ClassLoader> class_loader_handle( 227 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_))); 228 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr)); 229 for (const DexFile* dex_file : dex_files_) { 230 const std::vector<bool>& verified_classes = deps.GetVerifiedClasses(*dex_file); 231 ASSERT_EQ(verified_classes.size(), dex_file->NumClassDefs()); 232 for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) { 233 const dex::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)); 236 if (cls == nullptr) { 237 CHECK(soa.Self()->IsExceptionPending()); 238 soa.Self()->ClearException(); 239 } else if (&cls->GetDexFile() != dex_file) { 240 // Ignore classes from different dex files. 241 } else if (verified_classes[i]) { 242 ASSERT_EQ(cls->GetStatus(), ClassStatus::kVerified); 243 } else { 244 ASSERT_LT(cls->GetStatus(), ClassStatus::kVerified); 245 } 246 } 247 } 248 } 249 250 uint16_t GetClassDefIndex(const std::string& cls, const DexFile& dex_file) { 251 const dex::TypeId* type_id = dex_file.FindTypeId(cls.c_str()); 252 DCHECK(type_id != nullptr); 253 dex::TypeIndex type_idx = dex_file.GetIndexForTypeId(*type_id); 254 const dex::ClassDef* class_def = dex_file.FindClassDef(type_idx); 255 DCHECK(class_def != nullptr); 256 return dex_file.GetIndexForClassDef(*class_def); 257 } 258 259 bool HasUnverifiedClass(const std::string& cls) { 260 return HasUnverifiedClass(cls, *primary_dex_file_); 261 } 262 263 bool HasUnverifiedClass(const std::string& cls, const DexFile& dex_file) { 264 uint16_t class_def_idx = GetClassDefIndex(cls, dex_file); 265 return !verifier_deps_->GetVerifiedClasses(dex_file)[class_def_idx]; 266 } 267 268 bool HasRedefinedClass(const std::string& cls) { 269 uint16_t class_def_idx = GetClassDefIndex(cls, *primary_dex_file_); 270 return verifier_deps_->GetRedefinedClasses(*primary_dex_file_)[class_def_idx]; 271 } 272 273 // Iterates over all assignability records and tries to find an entry which 274 // matches the expected destination/source pair. 275 bool HasAssignable(const std::string& expected_destination, 276 const std::string& expected_source, 277 bool expected_is_assignable) { 278 for (auto& dex_dep : verifier_deps_->dex_deps_) { 279 const DexFile& dex_file = *dex_dep.first; 280 auto& storage = expected_is_assignable ? dex_dep.second->assignable_types_ 281 : dex_dep.second->unassignable_types_; 282 for (auto& entry : storage) { 283 std::string actual_destination = 284 verifier_deps_->GetStringFromId(dex_file, entry.GetDestination()); 285 std::string actual_source = verifier_deps_->GetStringFromId(dex_file, entry.GetSource()); 286 if ((expected_destination == actual_destination) && (expected_source == actual_source)) { 287 return true; 288 } 289 } 290 } 291 return false; 292 } 293 294 // Iterates over all class resolution records, finds an entry which matches 295 // the given class descriptor and tests its properties. 296 bool HasClass(const std::string& expected_klass, 297 bool expected_resolved, 298 const std::string& expected_access_flags = "") { 299 for (auto& dex_dep : verifier_deps_->dex_deps_) { 300 for (auto& entry : dex_dep.second->classes_) { 301 if (expected_resolved != entry.IsResolved()) { 302 continue; 303 } 304 305 std::string actual_klass = dex_dep.first->StringByTypeIdx(entry.GetDexTypeIndex()); 306 if (expected_klass != actual_klass) { 307 continue; 308 } 309 310 if (expected_resolved) { 311 // Test access flags. Note that PrettyJavaAccessFlags always appends 312 // a space after the modifiers. Add it to the expected access flags. 313 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags()); 314 if (expected_access_flags + " " != actual_access_flags) { 315 continue; 316 } 317 } 318 319 return true; 320 } 321 } 322 return false; 323 } 324 325 // Iterates over all field resolution records, finds an entry which matches 326 // the given field class+name+type and tests its properties. 327 bool HasField(const std::string& expected_klass, 328 const std::string& expected_name, 329 const std::string& expected_type, 330 bool expected_resolved, 331 const std::string& expected_access_flags = "", 332 const std::string& expected_decl_klass = "") { 333 for (auto& dex_dep : verifier_deps_->dex_deps_) { 334 for (auto& entry : dex_dep.second->fields_) { 335 if (expected_resolved != entry.IsResolved()) { 336 continue; 337 } 338 339 const dex::FieldId& field_id = dex_dep.first->GetFieldId(entry.GetDexFieldIndex()); 340 341 std::string actual_klass = dex_dep.first->StringByTypeIdx(field_id.class_idx_); 342 if (expected_klass != actual_klass) { 343 continue; 344 } 345 346 std::string actual_name = dex_dep.first->StringDataByIdx(field_id.name_idx_); 347 if (expected_name != actual_name) { 348 continue; 349 } 350 351 std::string actual_type = dex_dep.first->StringByTypeIdx(field_id.type_idx_); 352 if (expected_type != actual_type) { 353 continue; 354 } 355 356 if (expected_resolved) { 357 // Test access flags. Note that PrettyJavaAccessFlags always appends 358 // a space after the modifiers. Add it to the expected access flags. 359 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags()); 360 if (expected_access_flags + " " != actual_access_flags) { 361 continue; 362 } 363 364 std::string actual_decl_klass = verifier_deps_->GetStringFromId( 365 *dex_dep.first, entry.GetDeclaringClassIndex()); 366 if (expected_decl_klass != actual_decl_klass) { 367 continue; 368 } 369 } 370 371 return true; 372 } 373 } 374 return false; 375 } 376 377 // Iterates over all method resolution records, finds an entry which matches 378 // the given field kind+class+name+signature and tests its properties. 379 bool HasMethod(const std::string& expected_klass, 380 const std::string& expected_name, 381 const std::string& expected_signature, 382 bool expect_resolved, 383 const std::string& expected_access_flags = "", 384 const std::string& expected_decl_klass = "") { 385 for (auto& dex_dep : verifier_deps_->dex_deps_) { 386 for (const VerifierDeps::MethodResolution& entry : dex_dep.second->methods_) { 387 if (expect_resolved != entry.IsResolved()) { 388 continue; 389 } 390 391 const dex::MethodId& method_id = dex_dep.first->GetMethodId(entry.GetDexMethodIndex()); 392 393 std::string actual_klass = dex_dep.first->StringByTypeIdx(method_id.class_idx_); 394 if (expected_klass != actual_klass) { 395 continue; 396 } 397 398 std::string actual_name = dex_dep.first->StringDataByIdx(method_id.name_idx_); 399 if (expected_name != actual_name) { 400 continue; 401 } 402 403 std::string actual_signature = dex_dep.first->GetMethodSignature(method_id).ToString(); 404 if (expected_signature != actual_signature) { 405 continue; 406 } 407 408 if (expect_resolved) { 409 // Test access flags. Note that PrettyJavaAccessFlags always appends 410 // a space after the modifiers. Add it to the expected access flags. 411 std::string actual_access_flags = PrettyJavaAccessFlags(entry.GetAccessFlags()); 412 if (expected_access_flags + " " != actual_access_flags) { 413 continue; 414 } 415 416 std::string actual_decl_klass = verifier_deps_->GetStringFromId( 417 *dex_dep.first, entry.GetDeclaringClassIndex()); 418 if (expected_decl_klass != actual_decl_klass) { 419 continue; 420 } 421 } 422 423 return true; 424 } 425 } 426 return false; 427 } 428 429 size_t NumberOfCompiledDexFiles() { 430 return verifier_deps_->dex_deps_.size(); 431 } 432 433 bool HasBoolValue(const std::vector<bool>& vec, bool value) { 434 return std::count(vec.begin(), vec.end(), value) > 0; 435 } 436 437 bool HasEachKindOfRecord() { 438 bool has_strings = false; 439 bool has_assignability = false; 440 bool has_classes = false; 441 bool has_fields = false; 442 bool has_methods = false; 443 bool has_verified_classes = false; 444 bool has_unverified_classes = false; 445 bool has_redefined_classes = false; 446 bool has_not_redefined_classes = false; 447 448 for (auto& entry : verifier_deps_->dex_deps_) { 449 has_strings |= !entry.second->strings_.empty(); 450 has_assignability |= !entry.second->assignable_types_.empty(); 451 has_assignability |= !entry.second->unassignable_types_.empty(); 452 has_classes |= !entry.second->classes_.empty(); 453 has_fields |= !entry.second->fields_.empty(); 454 has_methods |= !entry.second->methods_.empty(); 455 has_verified_classes |= HasBoolValue(entry.second->verified_classes_, true); 456 has_unverified_classes |= HasBoolValue(entry.second->verified_classes_, false); 457 has_redefined_classes |= HasBoolValue(entry.second->redefined_classes_, true); 458 has_not_redefined_classes |= HasBoolValue(entry.second->redefined_classes_, false); 459 } 460 461 return has_strings && 462 has_assignability && 463 has_classes && 464 has_fields && 465 has_methods && 466 has_verified_classes && 467 has_unverified_classes && 468 has_redefined_classes && 469 has_not_redefined_classes; 470 } 471 472 // Load the dex file again with a new class loader, decode the VerifierDeps 473 // in `buffer`, allow the caller to modify the deps and then run validation. 474 template<typename Fn> 475 bool RunValidation(Fn fn, const std::vector<uint8_t>& buffer, std::string* error_msg) { 476 ScopedObjectAccess soa(Thread::Current()); 477 478 jobject second_loader = LoadDex("VerifierDeps"); 479 const auto& second_dex_files = GetDexFiles(second_loader); 480 481 VerifierDeps decoded_deps(second_dex_files, ArrayRef<const uint8_t>(buffer)); 482 VerifierDeps::DexFileDeps* decoded_dex_deps = 483 decoded_deps.GetDexFileDeps(*second_dex_files.front()); 484 485 // Let the test modify the dependencies. 486 fn(*decoded_dex_deps); 487 488 StackHandleScope<1> hs(soa.Self()); 489 Handle<mirror::ClassLoader> new_class_loader = 490 hs.NewHandle<mirror::ClassLoader>(soa.Decode<mirror::ClassLoader>(second_loader)); 491 492 return decoded_deps.ValidateDependencies(soa.Self(), 493 new_class_loader, 494 std::vector<const DexFile*>(), 495 error_msg); 496 } 497 498 std::unique_ptr<verifier::VerifierDeps> verifier_deps_; 499 std::vector<const DexFile*> dex_files_; 500 const DexFile* primary_dex_file_; 501 jobject class_loader_; 502 ObjPtr<mirror::Class> klass_Main_; 503 }; 504 505 TEST_F(VerifierDepsTest, StringToId) { 506 ScopedObjectAccess soa(Thread::Current()); 507 LoadDexFile(soa); 508 509 dex::StringIndex id_Main1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;"); 510 ASSERT_LT(id_Main1.index_, primary_dex_file_->NumStringIds()); 511 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main1)); 512 513 dex::StringIndex id_Main2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "LMain;"); 514 ASSERT_LT(id_Main2.index_, primary_dex_file_->NumStringIds()); 515 ASSERT_EQ("LMain;", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Main2)); 516 517 dex::StringIndex id_Lorem1 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum"); 518 ASSERT_GE(id_Lorem1.index_, primary_dex_file_->NumStringIds()); 519 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem1)); 520 521 dex::StringIndex id_Lorem2 = verifier_deps_->GetIdFromString(*primary_dex_file_, "Lorem ipsum"); 522 ASSERT_GE(id_Lorem2.index_, primary_dex_file_->NumStringIds()); 523 ASSERT_EQ("Lorem ipsum", verifier_deps_->GetStringFromId(*primary_dex_file_, id_Lorem2)); 524 525 ASSERT_EQ(id_Main1, id_Main2); 526 ASSERT_EQ(id_Lorem1, id_Lorem2); 527 ASSERT_NE(id_Main1, id_Lorem1); 528 } 529 530 TEST_F(VerifierDepsTest, Assignable_BothInBoot) { 531 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/TimeZone;", 532 /* src= */ "Ljava/util/SimpleTimeZone;", 533 /* is_strict= */ true, 534 /* is_assignable= */ true)); 535 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true)); 536 } 537 538 TEST_F(VerifierDepsTest, Assignable_DestinationInBoot1) { 539 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/net/Socket;", 540 /* src= */ "LMySSLSocket;", 541 /* is_strict= */ true, 542 /* is_assignable= */ true)); 543 ASSERT_TRUE(HasAssignable("Ljava/net/Socket;", "Ljavax/net/ssl/SSLSocket;", true)); 544 } 545 546 TEST_F(VerifierDepsTest, Assignable_DestinationInBoot2) { 547 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/TimeZone;", 548 /* src= */ "LMySimpleTimeZone;", 549 /* is_strict= */ true, 550 /* is_assignable= */ true)); 551 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true)); 552 } 553 554 TEST_F(VerifierDepsTest, Assignable_DestinationInBoot3) { 555 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/util/Collection;", 556 /* src= */ "LMyThreadSet;", 557 /* is_strict= */ true, 558 /* is_assignable= */ true)); 559 ASSERT_TRUE(HasAssignable("Ljava/util/Collection;", "Ljava/util/Set;", true)); 560 } 561 562 TEST_F(VerifierDepsTest, Assignable_BothArrays_Resolved) { 563 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[[Ljava/util/TimeZone;", 564 /* src= */ "[[Ljava/util/SimpleTimeZone;", 565 /* is_strict= */ true, 566 /* is_assignable= */ true)); 567 // If the component types of both arrays are resolved, we optimize the list of 568 // dependencies by recording a dependency on the component types. 569 ASSERT_FALSE(HasAssignable("[[Ljava/util/TimeZone;", "[[Ljava/util/SimpleTimeZone;", true)); 570 ASSERT_FALSE(HasAssignable("[Ljava/util/TimeZone;", "[Ljava/util/SimpleTimeZone;", true)); 571 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true)); 572 } 573 574 TEST_F(VerifierDepsTest, NotAssignable_BothInBoot) { 575 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;", 576 /* src= */ "Ljava/util/SimpleTimeZone;", 577 /* is_strict= */ true, 578 /* is_assignable= */ false)); 579 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false)); 580 } 581 582 TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot1) { 583 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;", 584 /* src= */ "LMySSLSocket;", 585 /* is_strict= */ true, 586 /* is_assignable= */ false)); 587 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljavax/net/ssl/SSLSocket;", false)); 588 } 589 590 TEST_F(VerifierDepsTest, NotAssignable_DestinationInBoot2) { 591 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;", 592 /* src= */ "LMySimpleTimeZone;", 593 /* is_strict= */ true, 594 /* is_assignable= */ false)); 595 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false)); 596 } 597 598 TEST_F(VerifierDepsTest, NotAssignable_BothArrays) { 599 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[Ljava/lang/Exception;", 600 /* src= */ "[Ljava/util/SimpleTimeZone;", 601 /* is_strict= */ true, 602 /* is_assignable= */ false)); 603 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/util/SimpleTimeZone;", false)); 604 } 605 606 TEST_F(VerifierDepsTest, ArgumentType_ResolvedClass) { 607 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedClass")); 608 ASSERT_TRUE(HasClass("Ljava/lang/Thread;", true, "public")); 609 } 610 611 TEST_F(VerifierDepsTest, ArgumentType_UnresolvedClass) { 612 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedClass")); 613 ASSERT_TRUE(HasClass("LUnresolvedClass;", false)); 614 } 615 616 TEST_F(VerifierDepsTest, ArgumentType_UnresolvedSuper) { 617 ASSERT_TRUE(VerifyMethod("ArgumentType_UnresolvedSuper")); 618 ASSERT_TRUE(HasClass("LMySetWithUnresolvedSuper;", false)); 619 } 620 621 TEST_F(VerifierDepsTest, ReturnType_Reference) { 622 ASSERT_TRUE(VerifyMethod("ReturnType_Reference")); 623 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true)); 624 } 625 626 TEST_F(VerifierDepsTest, ReturnType_Array) { 627 ASSERT_FALSE(VerifyMethod("ReturnType_Array")); 628 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/IllegalStateException;", false)); 629 } 630 631 TEST_F(VerifierDepsTest, InvokeArgumentType) { 632 ASSERT_TRUE(VerifyMethod("InvokeArgumentType")); 633 ASSERT_TRUE(HasClass("Ljava/text/SimpleDateFormat;", true, "public")); 634 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public")); 635 ASSERT_TRUE(HasMethod("Ljava/text/SimpleDateFormat;", 636 "setTimeZone", 637 "(Ljava/util/TimeZone;)V", 638 /* expect_resolved= */ true, 639 "public", 640 "Ljava/text/DateFormat;")); 641 ASSERT_TRUE(HasAssignable("Ljava/util/TimeZone;", "Ljava/util/SimpleTimeZone;", true)); 642 } 643 644 TEST_F(VerifierDepsTest, MergeTypes_RegisterLines) { 645 ASSERT_TRUE(VerifyMethod("MergeTypes_RegisterLines")); 646 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true)); 647 ASSERT_TRUE(HasAssignable( 648 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true)); 649 } 650 651 TEST_F(VerifierDepsTest, MergeTypes_IfInstanceOf) { 652 ASSERT_TRUE(VerifyMethod("MergeTypes_IfInstanceOf")); 653 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true)); 654 ASSERT_TRUE(HasAssignable( 655 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true)); 656 ASSERT_TRUE(HasAssignable("Ljava/net/SocketTimeoutException;", "Ljava/lang/Exception;", false)); 657 } 658 659 TEST_F(VerifierDepsTest, MergeTypes_Unresolved) { 660 ASSERT_TRUE(VerifyMethod("MergeTypes_Unresolved")); 661 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "Ljava/net/SocketTimeoutException;", true)); 662 ASSERT_TRUE(HasAssignable( 663 "Ljava/lang/Exception;", "Ljava/util/concurrent/TimeoutException;", true)); 664 } 665 666 TEST_F(VerifierDepsTest, ConstClass_Resolved) { 667 ASSERT_TRUE(VerifyMethod("ConstClass_Resolved")); 668 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public")); 669 } 670 671 TEST_F(VerifierDepsTest, ConstClass_Unresolved) { 672 ASSERT_FALSE(VerifyMethod("ConstClass_Unresolved")); 673 ASSERT_TRUE(HasClass("LUnresolvedClass;", false)); 674 } 675 676 TEST_F(VerifierDepsTest, CheckCast_Resolved) { 677 ASSERT_TRUE(VerifyMethod("CheckCast_Resolved")); 678 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public")); 679 } 680 681 TEST_F(VerifierDepsTest, CheckCast_Unresolved) { 682 ASSERT_FALSE(VerifyMethod("CheckCast_Unresolved")); 683 ASSERT_TRUE(HasClass("LUnresolvedClass;", false)); 684 } 685 686 TEST_F(VerifierDepsTest, InstanceOf_Resolved) { 687 ASSERT_TRUE(VerifyMethod("InstanceOf_Resolved")); 688 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public")); 689 } 690 691 TEST_F(VerifierDepsTest, InstanceOf_Unresolved) { 692 ASSERT_FALSE(VerifyMethod("InstanceOf_Unresolved")); 693 ASSERT_TRUE(HasClass("LUnresolvedClass;", false)); 694 } 695 696 TEST_F(VerifierDepsTest, NewInstance_Resolved) { 697 ASSERT_TRUE(VerifyMethod("NewInstance_Resolved")); 698 ASSERT_TRUE(HasClass("Ljava/lang/IllegalStateException;", true, "public")); 699 } 700 701 TEST_F(VerifierDepsTest, NewInstance_Unresolved) { 702 ASSERT_FALSE(VerifyMethod("NewInstance_Unresolved")); 703 ASSERT_TRUE(HasClass("LUnresolvedClass;", false)); 704 } 705 706 TEST_F(VerifierDepsTest, NewArray_Unresolved) { 707 ASSERT_FALSE(VerifyMethod("NewArray_Unresolved")); 708 ASSERT_TRUE(HasClass("[LUnresolvedClass;", false)); 709 } 710 711 TEST_F(VerifierDepsTest, Throw) { 712 ASSERT_TRUE(VerifyMethod("Throw")); 713 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/lang/IllegalStateException;", true)); 714 } 715 716 TEST_F(VerifierDepsTest, MoveException_Resolved) { 717 ASSERT_TRUE(VerifyMethod("MoveException_Resolved")); 718 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public")); 719 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public")); 720 ASSERT_TRUE(HasClass("Ljava/util/zip/ZipException;", true, "public")); 721 722 // Testing that all exception types are assignable to Throwable. 723 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/InterruptedIOException;", true)); 724 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true)); 725 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/util/zip/ZipException;", true)); 726 727 // Testing that the merge type is assignable to Throwable. 728 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/io/IOException;", true)); 729 730 // Merging of exception types. 731 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/io/InterruptedIOException;", true)); 732 ASSERT_TRUE(HasAssignable("Ljava/io/IOException;", "Ljava/util/zip/ZipException;", true)); 733 ASSERT_TRUE(HasAssignable( 734 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true)); 735 } 736 737 TEST_F(VerifierDepsTest, MoveException_Unresolved) { 738 ASSERT_FALSE(VerifyMethod("MoveException_Unresolved")); 739 ASSERT_TRUE(HasClass("LUnresolvedException;", false)); 740 } 741 742 TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInReferenced) { 743 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInReferenced")); 744 ASSERT_TRUE(HasClass("Ljava/lang/System;", true, "public")); 745 ASSERT_TRUE(HasField("Ljava/lang/System;", 746 "out", 747 "Ljava/io/PrintStream;", 748 true, 749 "public static", 750 "Ljava/lang/System;")); 751 } 752 753 TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass1) { 754 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass1")); 755 ASSERT_TRUE(HasClass("Ljava/util/SimpleTimeZone;", true, "public")); 756 ASSERT_TRUE(HasField( 757 "Ljava/util/SimpleTimeZone;", "LONG", "I", true, "public static", "Ljava/util/TimeZone;")); 758 } 759 760 TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInSuperclass2) { 761 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInSuperclass2")); 762 ASSERT_TRUE(HasField( 763 "LMySimpleTimeZone;", "SHORT", "I", true, "public static", "Ljava/util/TimeZone;")); 764 } 765 766 TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface1) { 767 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface1")); 768 ASSERT_TRUE(HasClass("Ljavax/xml/transform/dom/DOMResult;", true, "public")); 769 ASSERT_TRUE(HasField("Ljavax/xml/transform/dom/DOMResult;", 770 "PI_ENABLE_OUTPUT_ESCAPING", 771 "Ljava/lang/String;", 772 true, 773 "public static", 774 "Ljavax/xml/transform/Result;")); 775 } 776 777 TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface2) { 778 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface2")); 779 ASSERT_TRUE(HasField("LMyDOMResult;", 780 "PI_ENABLE_OUTPUT_ESCAPING", 781 "Ljava/lang/String;", 782 true, 783 "public static", 784 "Ljavax/xml/transform/Result;")); 785 } 786 787 TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface3) { 788 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface3")); 789 ASSERT_TRUE(HasField("LMyResult;", 790 "PI_ENABLE_OUTPUT_ESCAPING", 791 "Ljava/lang/String;", 792 true, 793 "public static", 794 "Ljavax/xml/transform/Result;")); 795 } 796 797 TEST_F(VerifierDepsTest, StaticField_Resolved_DeclaredInInterface4) { 798 ASSERT_TRUE(VerifyMethod("StaticField_Resolved_DeclaredInInterface4")); 799 ASSERT_TRUE(HasField("LMyDocument;", 800 "ELEMENT_NODE", 801 "S", 802 true, 803 "public static", 804 "Lorg/w3c/dom/Node;")); 805 } 806 807 TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInBoot) { 808 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInBoot")); 809 ASSERT_TRUE(HasClass("Ljava/util/TimeZone;", true, "public")); 810 ASSERT_TRUE(HasField("Ljava/util/TimeZone;", "x", "I", false)); 811 } 812 813 TEST_F(VerifierDepsTest, StaticField_Unresolved_ReferrerInDex) { 814 ASSERT_TRUE(VerifyMethod("StaticField_Unresolved_ReferrerInDex")); 815 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false)); 816 } 817 818 TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInReferenced) { 819 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInReferenced")); 820 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public")); 821 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;", 822 "bytesTransferred", 823 "I", 824 true, 825 "public", 826 "Ljava/io/InterruptedIOException;")); 827 ASSERT_TRUE(HasAssignable( 828 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true)); 829 } 830 831 TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass1) { 832 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass1")); 833 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public")); 834 ASSERT_TRUE(HasField("Ljava/net/SocketTimeoutException;", 835 "bytesTransferred", 836 "I", 837 true, 838 "public", 839 "Ljava/io/InterruptedIOException;")); 840 ASSERT_TRUE(HasAssignable( 841 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true)); 842 } 843 844 TEST_F(VerifierDepsTest, InstanceField_Resolved_DeclaredInSuperclass2) { 845 ASSERT_TRUE(VerifyMethod("InstanceField_Resolved_DeclaredInSuperclass2")); 846 ASSERT_TRUE(HasField("LMySocketTimeoutException;", 847 "bytesTransferred", 848 "I", 849 true, 850 "public", 851 "Ljava/io/InterruptedIOException;")); 852 ASSERT_TRUE(HasAssignable( 853 "Ljava/io/InterruptedIOException;", "Ljava/net/SocketTimeoutException;", true)); 854 } 855 856 TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInBoot) { 857 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInBoot")); 858 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public")); 859 ASSERT_TRUE(HasField("Ljava/io/InterruptedIOException;", "x", "I", false)); 860 } 861 862 TEST_F(VerifierDepsTest, InstanceField_Unresolved_ReferrerInDex) { 863 ASSERT_TRUE(VerifyMethod("InstanceField_Unresolved_ReferrerInDex")); 864 ASSERT_TRUE(HasField("LMyThreadSet;", "x", "I", false)); 865 } 866 867 TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInReferenced) { 868 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInReferenced")); 869 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public")); 870 ASSERT_TRUE(HasMethod("Ljava/net/Socket;", 871 "setSocketImplFactory", 872 "(Ljava/net/SocketImplFactory;)V", 873 /* expect_resolved= */ true, 874 "public static", 875 "Ljava/net/Socket;")); 876 } 877 878 TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass1) { 879 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass1")); 880 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public")); 881 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;", 882 "setSocketImplFactory", 883 "(Ljava/net/SocketImplFactory;)V", 884 /* expect_resolved= */ true, 885 "public static", 886 "Ljava/net/Socket;")); 887 } 888 889 TEST_F(VerifierDepsTest, InvokeStatic_Resolved_DeclaredInSuperclass2) { 890 ASSERT_TRUE(VerifyMethod("InvokeStatic_Resolved_DeclaredInSuperclass2")); 891 ASSERT_TRUE(HasMethod("LMySSLSocket;", 892 "setSocketImplFactory", 893 "(Ljava/net/SocketImplFactory;)V", 894 /* expect_resolved= */ true, 895 "public static", 896 "Ljava/net/Socket;")); 897 } 898 899 TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface1) { 900 ASSERT_TRUE(VerifyMethod("InvokeStatic_DeclaredInInterface1")); 901 ASSERT_TRUE(HasClass("Ljava/util/Map$Entry;", true, "public interface")); 902 ASSERT_TRUE(HasMethod("Ljava/util/Map$Entry;", 903 "comparingByKey", 904 "()Ljava/util/Comparator;", 905 /* expect_resolved= */ true, 906 "public static", 907 "Ljava/util/Map$Entry;")); 908 } 909 910 TEST_F(VerifierDepsTest, InvokeStatic_DeclaredInInterface2) { 911 ASSERT_FALSE(VerifyMethod("InvokeStatic_DeclaredInInterface2")); 912 ASSERT_TRUE(HasClass("Ljava/util/AbstractMap$SimpleEntry;", true, "public")); 913 ASSERT_TRUE(HasMethod("Ljava/util/AbstractMap$SimpleEntry;", 914 "comparingByKey", 915 "()Ljava/util/Comparator;", 916 /* expect_resolved= */ false)); 917 } 918 919 TEST_F(VerifierDepsTest, InvokeStatic_Unresolved1) { 920 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved1")); 921 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public")); 922 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;", 923 "x", 924 "()V", 925 /* expect_resolved= */ false)); 926 } 927 928 TEST_F(VerifierDepsTest, InvokeStatic_Unresolved2) { 929 ASSERT_FALSE(VerifyMethod("InvokeStatic_Unresolved2")); 930 ASSERT_TRUE(HasMethod("LMySSLSocket;", 931 "x", 932 "()V", 933 /* expect_resolved= */ false)); 934 } 935 936 TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInReferenced) { 937 ASSERT_TRUE(VerifyMethod("InvokeDirect_Resolved_DeclaredInReferenced")); 938 ASSERT_TRUE(HasClass("Ljava/net/Socket;", true, "public")); 939 ASSERT_TRUE(HasMethod("Ljava/net/Socket;", 940 "<init>", 941 "()V", 942 /* expect_resolved= */ true, 943 "public", 944 "Ljava/net/Socket;")); 945 } 946 947 TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass1) { 948 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass1")); 949 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public")); 950 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;", 951 "checkOldImpl", 952 "()V", 953 /* expect_resolved= */ true, 954 "private", 955 "Ljava/net/Socket;")); 956 } 957 958 TEST_F(VerifierDepsTest, InvokeDirect_Resolved_DeclaredInSuperclass2) { 959 ASSERT_FALSE(VerifyMethod("InvokeDirect_Resolved_DeclaredInSuperclass2")); 960 ASSERT_TRUE(HasMethod("LMySSLSocket;", 961 "checkOldImpl", 962 "()V", 963 /* expect_resolved= */ true, 964 "private", 965 "Ljava/net/Socket;")); 966 } 967 968 TEST_F(VerifierDepsTest, InvokeDirect_Unresolved1) { 969 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved1")); 970 ASSERT_TRUE(HasClass("Ljavax/net/ssl/SSLSocket;", true, "public")); 971 ASSERT_TRUE(HasMethod("Ljavax/net/ssl/SSLSocket;", 972 "x", 973 "()V", 974 /* expect_resolved= */ false)); 975 } 976 977 TEST_F(VerifierDepsTest, InvokeDirect_Unresolved2) { 978 ASSERT_FALSE(VerifyMethod("InvokeDirect_Unresolved2")); 979 ASSERT_TRUE(HasMethod("LMySSLSocket;", 980 "x", 981 "()V", 982 /* expect_resolved= */ false)); 983 } 984 985 TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInReferenced) { 986 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInReferenced")); 987 ASSERT_TRUE(HasClass("Ljava/lang/Throwable;", true, "public")); 988 ASSERT_TRUE(HasMethod("Ljava/lang/Throwable;", 989 "getMessage", 990 "()Ljava/lang/String;", 991 /* expect_resolved= */ true, 992 "public", 993 "Ljava/lang/Throwable;")); 994 // Type dependency on `this` argument. 995 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true)); 996 } 997 998 TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass1) { 999 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass1")); 1000 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public")); 1001 ASSERT_TRUE(HasMethod("Ljava/io/InterruptedIOException;", 1002 "getMessage", 1003 "()Ljava/lang/String;", 1004 /* expect_resolved= */ true, 1005 "public", 1006 "Ljava/lang/Throwable;")); 1007 // Type dependency on `this` argument. 1008 ASSERT_TRUE(HasAssignable("Ljava/lang/Throwable;", "Ljava/net/SocketTimeoutException;", true)); 1009 } 1010 1011 TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperclass2) { 1012 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperclass2")); 1013 ASSERT_TRUE(HasMethod("LMySocketTimeoutException;", 1014 "getMessage", 1015 "()Ljava/lang/String;", 1016 /* expect_resolved= */ true, 1017 "public", 1018 "Ljava/lang/Throwable;")); 1019 } 1020 1021 TEST_F(VerifierDepsTest, InvokeVirtual_Resolved_DeclaredInSuperinterface) { 1022 ASSERT_TRUE(VerifyMethod("InvokeVirtual_Resolved_DeclaredInSuperinterface")); 1023 ASSERT_TRUE(HasMethod("LMyThreadSet;", 1024 "size", 1025 "()I", 1026 /* expect_resolved= */ true, 1027 "public", 1028 "Ljava/util/Set;")); 1029 } 1030 1031 TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved1) { 1032 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved1")); 1033 ASSERT_TRUE(HasClass("Ljava/io/InterruptedIOException;", true, "public")); 1034 ASSERT_TRUE(HasMethod("Ljava/io/InterruptedIOException;", 1035 "x", 1036 "()V", 1037 /* expect_resolved= */ false)); 1038 } 1039 1040 TEST_F(VerifierDepsTest, InvokeVirtual_Unresolved2) { 1041 ASSERT_FALSE(VerifyMethod("InvokeVirtual_Unresolved2")); 1042 ASSERT_TRUE(HasMethod("LMySocketTimeoutException;", 1043 "x", 1044 "()V", 1045 /* expect_resolved= */ false)); 1046 } 1047 1048 TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInReferenced) { 1049 ASSERT_TRUE(VerifyMethod("InvokeInterface_Resolved_DeclaredInReferenced")); 1050 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface")); 1051 ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;", 1052 "run", 1053 "()V", 1054 /* expect_resolved= */ true, 1055 "public", 1056 "Ljava/lang/Runnable;")); 1057 } 1058 1059 TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperclass) { 1060 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperclass")); 1061 // TODO: Maybe we should not record dependency if the invoke type does not match the lookup type. 1062 ASSERT_TRUE(HasMethod("LMyThread;", 1063 "join", 1064 "()V", 1065 /* expect_resolved= */ true, 1066 "public", 1067 "Ljava/lang/Thread;")); 1068 } 1069 1070 TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface1) { 1071 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface1")); 1072 // TODO: Maybe we should not record dependency if the invoke type does not match the lookup type. 1073 ASSERT_TRUE(HasMethod("LMyThreadSet;", 1074 "run", 1075 "()V", 1076 /* expect_resolved= */ true, 1077 "public", 1078 "Ljava/lang/Thread;")); 1079 } 1080 1081 TEST_F(VerifierDepsTest, InvokeInterface_Resolved_DeclaredInSuperinterface2) { 1082 ASSERT_FALSE(VerifyMethod("InvokeInterface_Resolved_DeclaredInSuperinterface2")); 1083 ASSERT_TRUE(HasMethod("LMyThreadSet;", 1084 "isEmpty", 1085 "()Z", 1086 /* expect_resolved= */ true, 1087 "public", 1088 "Ljava/util/Set;")); 1089 } 1090 1091 TEST_F(VerifierDepsTest, InvokeInterface_Unresolved1) { 1092 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved1")); 1093 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface")); 1094 ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;", 1095 "x", 1096 "()V", 1097 /* expect_resolved= */ false)); 1098 } 1099 1100 TEST_F(VerifierDepsTest, InvokeInterface_Unresolved2) { 1101 ASSERT_FALSE(VerifyMethod("InvokeInterface_Unresolved2")); 1102 ASSERT_TRUE(HasMethod("LMyThreadSet;", "x", "()V", /* expect_resolved= */ false)); 1103 } 1104 1105 TEST_F(VerifierDepsTest, InvokeSuper_ThisAssignable) { 1106 ASSERT_TRUE(VerifyMethod("InvokeSuper_ThisAssignable")); 1107 ASSERT_TRUE(HasClass("Ljava/lang/Runnable;", true, "public interface")); 1108 ASSERT_TRUE(HasAssignable("Ljava/lang/Runnable;", "Ljava/lang/Thread;", true)); 1109 ASSERT_TRUE(HasMethod("Ljava/lang/Runnable;", 1110 "run", 1111 "()V", 1112 /* expect_resolved= */ true, 1113 "public", 1114 "Ljava/lang/Runnable;")); 1115 } 1116 1117 TEST_F(VerifierDepsTest, InvokeSuper_ThisNotAssignable) { 1118 ASSERT_FALSE(VerifyMethod("InvokeSuper_ThisNotAssignable")); 1119 ASSERT_TRUE(HasClass("Ljava/lang/Integer;", true, "public")); 1120 ASSERT_TRUE(HasAssignable("Ljava/lang/Integer;", "Ljava/lang/Thread;", false)); 1121 ASSERT_TRUE(HasMethod("Ljava/lang/Integer;", 1122 "intValue", "()I", 1123 /* expect_resolved= */ true, 1124 "public", "Ljava/lang/Integer;")); 1125 } 1126 1127 TEST_F(VerifierDepsTest, ArgumentType_ResolvedReferenceArray) { 1128 ASSERT_TRUE(VerifyMethod("ArgumentType_ResolvedReferenceArray")); 1129 ASSERT_TRUE(HasClass("[Ljava/lang/Thread;", true, "public")); 1130 } 1131 1132 TEST_F(VerifierDepsTest, NewArray_Resolved) { 1133 ASSERT_TRUE(VerifyMethod("NewArray_Resolved")); 1134 ASSERT_TRUE(HasClass("[Ljava/lang/IllegalStateException;", true, "public")); 1135 } 1136 1137 TEST_F(VerifierDepsTest, EncodeDecode) { 1138 VerifyDexFile(); 1139 1140 ASSERT_EQ(1u, NumberOfCompiledDexFiles()); 1141 ASSERT_TRUE(HasEachKindOfRecord()); 1142 1143 std::vector<uint8_t> buffer; 1144 verifier_deps_->Encode(dex_files_, &buffer); 1145 ASSERT_FALSE(buffer.empty()); 1146 1147 VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer)); 1148 ASSERT_TRUE(verifier_deps_->Equals(decoded_deps)); 1149 } 1150 1151 TEST_F(VerifierDepsTest, EncodeDecodeMulti) { 1152 VerifyDexFile("MultiDex"); 1153 1154 ASSERT_GT(NumberOfCompiledDexFiles(), 1u); 1155 std::vector<uint8_t> buffer; 1156 verifier_deps_->Encode(dex_files_, &buffer); 1157 ASSERT_FALSE(buffer.empty()); 1158 1159 // Create new DexFile, to mess with std::map order: the verifier deps used 1160 // to iterate over the map, which doesn't guarantee insertion order. We fixed 1161 // this by passing the expected order when encoding/decoding. 1162 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles("VerifierDeps"); 1163 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles("MultiDex"); 1164 std::vector<const DexFile*> dex_files; 1165 for (auto& dex_file : first_dex_files) { 1166 dex_files.push_back(dex_file.get()); 1167 } 1168 for (auto& dex_file : second_dex_files) { 1169 dex_files.push_back(dex_file.get()); 1170 } 1171 1172 // Dump the new verifier deps to ensure it can properly read the data. 1173 VerifierDeps decoded_deps(dex_files, ArrayRef<const uint8_t>(buffer)); 1174 std::ostringstream stream; 1175 VariableIndentationOutputStream os(&stream); 1176 decoded_deps.Dump(&os); 1177 } 1178 1179 TEST_F(VerifierDepsTest, UnverifiedClasses) { 1180 VerifyDexFile(); 1181 ASSERT_FALSE(HasUnverifiedClass("LMyThread;")); 1182 // Test that a class with a soft failure is recorded. 1183 ASSERT_TRUE(HasUnverifiedClass("LMain;")); 1184 // Test that a class with hard failure is recorded. 1185 ASSERT_TRUE(HasUnverifiedClass("LMyVerificationFailure;")); 1186 // Test that a class with unresolved super is recorded. 1187 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuper;")); 1188 // Test that a class with unresolved super and hard failure is recorded. 1189 ASSERT_TRUE(HasUnverifiedClass("LMyClassWithNoSuperButFailures;")); 1190 } 1191 1192 TEST_F(VerifierDepsTest, RedefinedClass) { 1193 VerifyDexFile(); 1194 // Test that a class which redefines a boot classpath class has dependencies recorded. 1195 ASSERT_TRUE(HasRedefinedClass("Ljava/net/SocketTimeoutException;")); 1196 // These come from test case InstanceField_Resolved_DeclaredInSuperclass1. 1197 ASSERT_TRUE(HasClass("Ljava/net/SocketTimeoutException;", true, "public")); 1198 ASSERT_TRUE(HasField("Ljava/net/SocketTimeoutException;", 1199 "bytesTransferred", 1200 "I", 1201 true, 1202 "public", 1203 "Ljava/io/InterruptedIOException;")); 1204 } 1205 1206 TEST_F(VerifierDepsTest, UnverifiedOrder) { 1207 ScopedObjectAccess soa(Thread::Current()); 1208 jobject loader = LoadDex("VerifierDeps"); 1209 std::vector<const DexFile*> dex_files = GetDexFiles(loader); 1210 ASSERT_GT(dex_files.size(), 0u); 1211 const DexFile* dex_file = dex_files[0]; 1212 VerifierDeps deps1(dex_files); 1213 Thread* const self = Thread::Current(); 1214 ASSERT_TRUE(self->GetVerifierDeps() == nullptr); 1215 self->SetVerifierDeps(&deps1); 1216 deps1.MaybeRecordVerificationStatus(*dex_file, 1217 dex_file->GetClassDef(0u), 1218 verifier::FailureKind::kHardFailure); 1219 deps1.MaybeRecordVerificationStatus(*dex_file, 1220 dex_file->GetClassDef(1u), 1221 verifier::FailureKind::kHardFailure); 1222 VerifierDeps deps2(dex_files); 1223 self->SetVerifierDeps(nullptr); 1224 self->SetVerifierDeps(&deps2); 1225 deps2.MaybeRecordVerificationStatus(*dex_file, 1226 dex_file->GetClassDef(1u), 1227 verifier::FailureKind::kHardFailure); 1228 deps2.MaybeRecordVerificationStatus(*dex_file, 1229 dex_file->GetClassDef(0u), 1230 verifier::FailureKind::kHardFailure); 1231 self->SetVerifierDeps(nullptr); 1232 std::vector<uint8_t> buffer1; 1233 deps1.Encode(dex_files, &buffer1); 1234 std::vector<uint8_t> buffer2; 1235 deps2.Encode(dex_files, &buffer2); 1236 EXPECT_EQ(buffer1, buffer2); 1237 } 1238 1239 TEST_F(VerifierDepsTest, VerifyDeps) { 1240 std::string error_msg; 1241 1242 VerifyDexFile(); 1243 ASSERT_EQ(1u, NumberOfCompiledDexFiles()); 1244 ASSERT_TRUE(HasEachKindOfRecord()); 1245 1246 // When validating, we create a new class loader, as 1247 // the existing `class_loader_` may contain erroneous classes, 1248 // that ClassLinker::FindClass won't return. 1249 1250 std::vector<uint8_t> buffer; 1251 verifier_deps_->Encode(dex_files_, &buffer); 1252 ASSERT_FALSE(buffer.empty()); 1253 1254 // Check that dependencies are satisfied after decoding `buffer`. 1255 ASSERT_TRUE(RunValidation([](VerifierDeps::DexFileDeps&) {}, buffer, &error_msg)) 1256 << error_msg; 1257 1258 // Mess with the dependencies to make sure we catch any change and fail to verify. 1259 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1260 deps.assignable_types_.insert(*deps.unassignable_types_.begin()); 1261 }, buffer, &error_msg)); 1262 1263 // Mess with the unassignable_types. 1264 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1265 deps.unassignable_types_.insert(*deps.assignable_types_.begin()); 1266 }, buffer, &error_msg)); 1267 1268 // Mess with classes. 1269 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1270 for (const auto& entry : deps.classes_) { 1271 if (entry.IsResolved()) { 1272 deps.classes_.insert(VerifierDeps::ClassResolution( 1273 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker)); 1274 return; 1275 } 1276 } 1277 LOG(FATAL) << "Could not find any resolved classes"; 1278 UNREACHABLE(); 1279 }, buffer, &error_msg)); 1280 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1281 for (const auto& entry : deps.classes_) { 1282 if (!entry.IsResolved()) { 1283 deps.classes_.insert(VerifierDeps::ClassResolution( 1284 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker - 1)); 1285 return; 1286 } 1287 } 1288 LOG(FATAL) << "Could not find any unresolved classes"; 1289 UNREACHABLE(); 1290 }, buffer, &error_msg)); 1291 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1292 for (const auto& entry : deps.classes_) { 1293 if (entry.IsResolved()) { 1294 deps.classes_.insert(VerifierDeps::ClassResolution( 1295 entry.GetDexTypeIndex(), entry.GetAccessFlags() - 1)); 1296 return; 1297 } 1298 } 1299 LOG(FATAL) << "Could not find any resolved classes"; 1300 UNREACHABLE(); 1301 }, buffer, &error_msg)); 1302 1303 // Mess with fields. 1304 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1305 for (const auto& entry : deps.fields_) { 1306 if (entry.IsResolved()) { 1307 deps.fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(), 1308 VerifierDeps::kUnresolvedMarker, 1309 entry.GetDeclaringClassIndex())); 1310 return; 1311 } 1312 } 1313 LOG(FATAL) << "Could not find any resolved fields"; 1314 UNREACHABLE(); 1315 }, buffer, &error_msg)); 1316 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1317 for (const auto& entry : deps.fields_) { 1318 if (!entry.IsResolved()) { 1319 constexpr dex::StringIndex kStringIndexZero(0); // We know there is a class there. 1320 deps.fields_.insert(VerifierDeps::FieldResolution(0 /* we know there is a field there */, 1321 VerifierDeps::kUnresolvedMarker - 1, 1322 kStringIndexZero)); 1323 return; 1324 } 1325 } 1326 LOG(FATAL) << "Could not find any unresolved fields"; 1327 UNREACHABLE(); 1328 }, buffer, &error_msg)); 1329 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1330 for (const auto& entry : deps.fields_) { 1331 if (entry.IsResolved()) { 1332 deps.fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(), 1333 entry.GetAccessFlags() - 1, 1334 entry.GetDeclaringClassIndex())); 1335 return; 1336 } 1337 } 1338 LOG(FATAL) << "Could not find any resolved fields"; 1339 UNREACHABLE(); 1340 }, buffer, &error_msg)); 1341 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1342 for (const auto& entry : deps.fields_) { 1343 constexpr dex::StringIndex kNewTypeIndex(0); 1344 if (entry.GetDeclaringClassIndex() != kNewTypeIndex) { 1345 deps.fields_.insert(VerifierDeps::FieldResolution(entry.GetDexFieldIndex(), 1346 entry.GetAccessFlags(), 1347 kNewTypeIndex)); 1348 return; 1349 } 1350 } 1351 LOG(FATAL) << "Could not find any suitable fields"; 1352 UNREACHABLE(); 1353 }, buffer, &error_msg)); 1354 1355 // Mess with methods. 1356 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1357 std::set<VerifierDeps::MethodResolution>* methods = &deps.methods_; 1358 for (const auto& entry : *methods) { 1359 if (entry.IsResolved()) { 1360 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(), 1361 VerifierDeps::kUnresolvedMarker, 1362 entry.GetDeclaringClassIndex())); 1363 return; 1364 } 1365 } 1366 LOG(FATAL) << "Could not find any resolved methods"; 1367 UNREACHABLE(); 1368 }, buffer, &error_msg)); 1369 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1370 std::set<VerifierDeps::MethodResolution>* methods = &deps.methods_; 1371 for (const auto& entry : *methods) { 1372 if (!entry.IsResolved()) { 1373 constexpr dex::StringIndex kStringIndexZero(0); // We know there is a class there. 1374 methods->insert(VerifierDeps::MethodResolution(0 /* we know there is a method there */, 1375 VerifierDeps::kUnresolvedMarker - 1, 1376 kStringIndexZero)); 1377 return; 1378 } 1379 } 1380 LOG(FATAL) << "Could not find any unresolved methods"; 1381 UNREACHABLE(); 1382 }, buffer, &error_msg)); 1383 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1384 std::set<VerifierDeps::MethodResolution>* methods = &deps.methods_; 1385 for (const auto& entry : *methods) { 1386 if (entry.IsResolved()) { 1387 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(), 1388 entry.GetAccessFlags() - 1, 1389 entry.GetDeclaringClassIndex())); 1390 return; 1391 } 1392 } 1393 LOG(FATAL) << "Could not find any resolved methods"; 1394 UNREACHABLE(); 1395 }, buffer, &error_msg)); 1396 ASSERT_FALSE(RunValidation([](VerifierDeps::DexFileDeps& deps) { 1397 std::set<VerifierDeps::MethodResolution>* methods = &deps.methods_; 1398 for (const auto& entry : *methods) { 1399 constexpr dex::StringIndex kNewTypeIndex(0); 1400 if (entry.IsResolved() && entry.GetDeclaringClassIndex() != kNewTypeIndex) { 1401 methods->insert(VerifierDeps::MethodResolution(entry.GetDexMethodIndex(), 1402 entry.GetAccessFlags(), 1403 kNewTypeIndex)); 1404 return; 1405 } 1406 } 1407 LOG(FATAL) << "Could not find any suitable methods"; 1408 UNREACHABLE(); 1409 }, buffer, &error_msg)); 1410 } 1411 1412 TEST_F(VerifierDepsTest, CompilerDriver) { 1413 SetupCompilerDriver(); 1414 1415 // Test both multi-dex and single-dex configuration. 1416 for (const char* multi : { "MultiDex", static_cast<const char*>(nullptr) }) { 1417 // Test that the compiler driver behaves as expected when the dependencies 1418 // verify and when they don't verify. 1419 for (bool verify_failure : { false, true }) { 1420 { 1421 ScopedObjectAccess soa(Thread::Current()); 1422 LoadDexFile(soa, "VerifierDeps", multi); 1423 } 1424 VerifyWithCompilerDriver(/* verifier_deps= */ nullptr); 1425 1426 std::vector<uint8_t> buffer; 1427 verifier_deps_->Encode(dex_files_, &buffer); 1428 1429 { 1430 ScopedObjectAccess soa(Thread::Current()); 1431 LoadDexFile(soa, "VerifierDeps", multi); 1432 } 1433 verifier::VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer)); 1434 if (verify_failure) { 1435 // Just taint the decoded VerifierDeps with one invalid entry. 1436 VerifierDeps::DexFileDeps* deps = decoded_deps.GetDexFileDeps(*primary_dex_file_); 1437 bool found = false; 1438 for (const auto& entry : deps->classes_) { 1439 if (entry.IsResolved()) { 1440 deps->classes_.insert(VerifierDeps::ClassResolution( 1441 entry.GetDexTypeIndex(), VerifierDeps::kUnresolvedMarker)); 1442 found = true; 1443 break; 1444 } 1445 } 1446 ASSERT_TRUE(found); 1447 } 1448 VerifyWithCompilerDriver(&decoded_deps); 1449 1450 if (verify_failure) { 1451 ASSERT_FALSE(verifier_deps_ == nullptr); 1452 ASSERT_FALSE(verifier_deps_->Equals(decoded_deps)); 1453 } else { 1454 VerifyClassStatus(decoded_deps); 1455 } 1456 } 1457 } 1458 } 1459 1460 TEST_F(VerifierDepsTest, MultiDexVerification) { 1461 VerifyDexFile("VerifierDepsMulti"); 1462 ASSERT_EQ(NumberOfCompiledDexFiles(), 2u); 1463 1464 ASSERT_TRUE(HasUnverifiedClass("LMySoftVerificationFailure;", *dex_files_[1])); 1465 ASSERT_TRUE(HasUnverifiedClass("LMySub1SoftVerificationFailure;", *dex_files_[0])); 1466 ASSERT_TRUE(HasUnverifiedClass("LMySub2SoftVerificationFailure;", *dex_files_[0])); 1467 1468 std::vector<uint8_t> buffer; 1469 verifier_deps_->Encode(dex_files_, &buffer); 1470 ASSERT_FALSE(buffer.empty()); 1471 } 1472 1473 TEST_F(VerifierDepsTest, NotAssignable_InterfaceWithClassInBoot) { 1474 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "Ljava/lang/Exception;", 1475 /* src= */ "LIface;", 1476 /* is_strict= */ true, 1477 /* is_assignable= */ false)); 1478 ASSERT_TRUE(HasAssignable("Ljava/lang/Exception;", "LIface;", false)); 1479 } 1480 1481 TEST_F(VerifierDepsTest, Assignable_Arrays) { 1482 ASSERT_TRUE(TestAssignabilityRecording(/* dst= */ "[LIface;", 1483 /* src= */ "[LMyClassExtendingInterface;", 1484 /* is_strict= */ false, 1485 /* is_assignable= */ true)); 1486 ASSERT_FALSE(HasAssignable( 1487 "LIface;", "LMyClassExtendingInterface;", /* expected_is_assignable= */ true)); 1488 ASSERT_FALSE(HasAssignable( 1489 "LIface;", "LMyClassExtendingInterface;", /* expected_is_assignable= */ false)); 1490 } 1491 1492 } // namespace verifier 1493 } // namespace art 1494