1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "private_typeinfo.h" 10 11 // The flag _LIBCXXABI_FORGIVING_DYNAMIC_CAST is used to make dynamic_cast 12 // more forgiving when type_info's mistakenly have hidden visibility and 13 // thus multiple type_infos can exist for a single type. 14 // 15 // When _LIBCXXABI_FORGIVING_DYNAMIC_CAST is defined, and only in the case where 16 // there is a detected inconsistency in the type_info hierarchy during a 17 // dynamic_cast, then the equality operation will fall back to using strcmp 18 // on type_info names to determine type_info equality. 19 // 20 // This change happens *only* under dynamic_cast, and only when 21 // dynamic_cast is faced with the choice: abort, or possibly give back the 22 // wrong answer. If when the dynamic_cast is done with this fallback 23 // algorithm and an inconsistency is still detected, dynamic_cast will call 24 // abort with an appropriate message. 25 // 26 // The current implementation of _LIBCXXABI_FORGIVING_DYNAMIC_CAST requires a 27 // printf-like function called syslog: 28 // 29 // void syslog(int facility_priority, const char* format, ...); 30 // 31 // If you want this functionality but your platform doesn't have syslog, 32 // just implement it in terms of fprintf(stderr, ...). 33 // 34 // _LIBCXXABI_FORGIVING_DYNAMIC_CAST is currently off by default. 35 36 // On Windows, typeids are different between DLLs and EXEs, so comparing 37 // type_info* will work for typeids from the same compiled file but fail 38 // for typeids from a DLL and an executable. Among other things, exceptions 39 // are not caught by handlers since can_catch() returns false. 40 // 41 // Defining _LIBCXXABI_FORGIVING_DYNAMIC_CAST does not help since can_catch() calls 42 // is_equal() with use_strcmp=false so the string names are not compared. 43 44 #include <cassert> 45 #include <cstddef> 46 #include <cstdint> 47 #include <string.h> 48 49 #include "abort_message.h" 50 51 #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST 52 #include <sys/syslog.h> 53 #include <atomic> 54 #endif 55 56 #if __has_feature(ptrauth_calls) 57 #include <ptrauth.h> 58 #endif 59 60 template <typename T> 61 static inline T* strip_vtable(T* vtable) { 62 #if __has_feature(ptrauth_calls) 63 vtable = ptrauth_strip(vtable, ptrauth_key_cxx_vtable_pointer); 64 #endif 65 return vtable; 66 } 67 68 static inline 69 bool 70 is_equal(const std::type_info* x, const std::type_info* y, bool use_strcmp) 71 { 72 // Use std::type_info's default comparison unless we've explicitly asked 73 // for strcmp. 74 if (!use_strcmp) 75 return *x == *y; 76 // Still allow pointer equality to short circut. 77 return x == y || strcmp(x->name(), y->name()) == 0; 78 } 79 80 static inline ptrdiff_t update_offset_to_base(const char* vtable, 81 ptrdiff_t offset_to_base) { 82 #if __has_feature(cxx_abi_relative_vtable) 83 // VTable components are 32 bits in the relative vtables ABI. 84 return *reinterpret_cast<const int32_t*>(vtable + offset_to_base); 85 #else 86 return *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); 87 #endif 88 } 89 90 namespace __cxxabiv1 91 { 92 93 namespace { 94 95 struct derived_object_info { 96 const void* dynamic_ptr; 97 const __class_type_info* dynamic_type; 98 std::ptrdiff_t offset_to_derived; 99 }; 100 101 /// A helper function that gets (dynamic_ptr, dynamic_type, offset_to_derived) from static_ptr. 102 void dyn_cast_get_derived_info(derived_object_info* info, const void* static_ptr) 103 { 104 #if __has_feature(cxx_abi_relative_vtable) 105 // The vtable address will point to the first virtual function, which is 8 106 // bytes after the start of the vtable (4 for the offset from top + 4 for 107 // the typeinfo component). 108 const int32_t* vtable = 109 *reinterpret_cast<const int32_t* const*>(static_ptr); 110 info->offset_to_derived = static_cast<std::ptrdiff_t>(vtable[-2]); 111 info->dynamic_ptr = static_cast<const char*>(static_ptr) + info->offset_to_derived; 112 113 // The typeinfo component is now a relative offset to a proxy. 114 int32_t offset_to_ti_proxy = vtable[-1]; 115 const uint8_t* ptr_to_ti_proxy = 116 reinterpret_cast<const uint8_t*>(vtable) + offset_to_ti_proxy; 117 info->dynamic_type = *(reinterpret_cast<const __class_type_info* const*>(ptr_to_ti_proxy)); 118 #else 119 void** vtable = strip_vtable(*static_cast<void** const*>(static_ptr)); 120 info->offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]); 121 info->dynamic_ptr = static_cast<const char*>(static_ptr) + info->offset_to_derived; 122 info->dynamic_type = static_cast<const __class_type_info*>(vtable[-1]); 123 #endif 124 } 125 126 /// A helper function for __dynamic_cast that casts a base sub-object pointer 127 /// to the object's dynamic type. 128 /// 129 /// This function returns the casting result directly. No further processing 130 /// required. 131 /// 132 /// Specifically, this function can only be called if the following pre- 133 /// condition holds: 134 /// * The dynamic type of the object pointed to by `static_ptr` is exactly 135 /// the same as `dst_type`. 136 const void* dyn_cast_to_derived(const void* static_ptr, 137 const void* dynamic_ptr, 138 const __class_type_info* static_type, 139 const __class_type_info* dst_type, 140 std::ptrdiff_t offset_to_derived, 141 std::ptrdiff_t src2dst_offset) 142 { 143 // We're downcasting from src_type to the complete object's dynamic type. 144 // This is a really hot path that can be further optimized with the 145 // `src2dst_offset` hint. 146 // In such a case, dynamic_ptr already gives the casting result if the 147 // casting ever succeeds. All we have to do now is to check static_ptr 148 // points to a public base sub-object of dynamic_ptr. 149 150 if (src2dst_offset >= 0) 151 { 152 // The static type is a unique public non-virtual base type of 153 // dst_type at offset `src2dst_offset` from the origin of dst. 154 // Note that there might be other non-public static_type bases. The 155 // hint only guarantees that the public base is non-virtual and 156 // unique. So we have to check whether static_ptr points to that 157 // unique public base sub-object. 158 if (offset_to_derived != -src2dst_offset) 159 return nullptr; 160 return dynamic_ptr; 161 } 162 163 if (src2dst_offset == -2) 164 { 165 // static_type is not a public base of dst_type. 166 return nullptr; 167 } 168 169 // If src2dst_offset == -3, then: 170 // src_type is a multiple public base type but never a virtual 171 // base type. We can't conclude that static_ptr points to those 172 // public base sub-objects because there might be other non- 173 // public static_type bases. The search is inevitable. 174 175 // Fallback to the slow path to check that static_type is a public 176 // base type of dynamic_type. 177 // Using giant short cut. Add that information to info. 178 __dynamic_cast_info info = {dst_type, static_ptr, static_type, src2dst_offset, 0, 0, 0, 0, 0, 0, 0, 0, 179 1, // number_of_dst_type 180 false, false, false, true, nullptr}; 181 // Do the search 182 dst_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false); 183 #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST 184 // The following if should always be false because we should 185 // definitely find (static_ptr, static_type), either on a public 186 // or private path 187 if (info.path_dst_ptr_to_static_ptr == unknown) 188 { 189 // We get here only if there is some kind of visibility problem 190 // in client code. 191 static_assert(std::atomic<size_t>::is_always_lock_free, ""); 192 static std::atomic<size_t> error_count(0); 193 size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed); 194 if ((error_count_snapshot & (error_count_snapshot-1)) == 0) 195 syslog(LOG_ERR, "dynamic_cast error 1: Both of the following type_info's " 196 "should have public visibility. At least one of them is hidden. %s" 197 ", %s.\n", static_type->name(), dst_type->name()); 198 // Redo the search comparing type_info's using strcmp 199 info = {dst_type, static_ptr, static_type, src2dst_offset, 0, 0, 0, 0, 0, 0, 200 0, 0, 0, false, false, false, true, nullptr}; 201 info.number_of_dst_type = 1; 202 dst_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true); 203 } 204 #endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST 205 // Query the search. 206 if (info.path_dst_ptr_to_static_ptr != public_path) 207 return nullptr; 208 209 return dynamic_ptr; 210 } 211 212 /// A helper function for __dynamic_cast that tries to perform a downcast 213 /// before giving up and falling back to the slow path. 214 const void* dyn_cast_try_downcast(const void* static_ptr, 215 const void* dynamic_ptr, 216 const __class_type_info* dst_type, 217 const __class_type_info* dynamic_type, 218 std::ptrdiff_t src2dst_offset) 219 { 220 if (src2dst_offset < 0) 221 { 222 // We can only optimize the case if the static type is a unique public 223 // base of dst_type. Give up. 224 return nullptr; 225 } 226 227 // Pretend there is a dst_type object that leads to static_ptr. Later we 228 // will check whether this imagined dst_type object exists. If it exists 229 // then it will be the casting result. 230 const void* dst_ptr_to_static = reinterpret_cast<const char*>(static_ptr) - src2dst_offset; 231 232 if (reinterpret_cast<std::intptr_t>(dst_ptr_to_static) < reinterpret_cast<std::intptr_t>(dynamic_ptr)) 233 { 234 // The imagined dst_type object does not exist. Bail-out quickly. 235 return nullptr; 236 } 237 238 // Try to search a path from dynamic_type to dst_type. 239 __dynamic_cast_info dynamic_to_dst_info = {dynamic_type, 240 dst_ptr_to_static, 241 dst_type, 242 src2dst_offset, 243 0, 244 0, 245 0, 246 0, 247 0, 248 0, 249 0, 250 0, 251 1, // number_of_dst_type 252 false, 253 false, 254 false, 255 true, 256 nullptr}; 257 dynamic_type->search_above_dst(&dynamic_to_dst_info, dynamic_ptr, dynamic_ptr, public_path, false); 258 if (dynamic_to_dst_info.path_dst_ptr_to_static_ptr != unknown) { 259 // We have found at least one path from dynamic_ptr to dst_ptr. The 260 // downcast can succeed. 261 return dst_ptr_to_static; 262 } 263 264 return nullptr; 265 } 266 267 const void* dyn_cast_slow(const void* static_ptr, 268 const void* dynamic_ptr, 269 const __class_type_info* static_type, 270 const __class_type_info* dst_type, 271 const __class_type_info* dynamic_type, 272 std::ptrdiff_t src2dst_offset) 273 { 274 // Not using giant short cut. Do the search 275 276 // Initialize info struct for this search. 277 __dynamic_cast_info info = {dst_type, static_ptr, static_type, src2dst_offset, 0, 0, 0, 0, 0, 0, 278 0, 0, 0, false, false, false, true, nullptr}; 279 280 dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false); 281 #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST 282 // The following if should always be false because we should 283 // definitely find (static_ptr, static_type), either on a public 284 // or private path 285 if (info.path_dst_ptr_to_static_ptr == unknown && 286 info.path_dynamic_ptr_to_static_ptr == unknown) 287 { 288 static_assert(std::atomic<size_t>::is_always_lock_free, ""); 289 static std::atomic<size_t> error_count(0); 290 size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed); 291 if ((error_count_snapshot & (error_count_snapshot-1)) == 0) 292 syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's " 293 "has hidden visibility or is defined in more than one translation " 294 "unit. They should all have public visibility. " 295 "%s, %s, %s.\n", static_type->name(), dynamic_type->name(), 296 dst_type->name()); 297 // Redo the search comparing type_info's using strcmp 298 info = {dst_type, static_ptr, static_type, src2dst_offset, 0, 0, 0, 0, 0, 0, 299 0, 0, 0, false, false, false, true, nullptr}; 300 dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true); 301 } 302 #endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST 303 // Query the search. 304 switch (info.number_to_static_ptr) 305 { 306 case 0: 307 if (info.number_to_dst_ptr == 1 && 308 info.path_dynamic_ptr_to_static_ptr == public_path && 309 info.path_dynamic_ptr_to_dst_ptr == public_path) 310 return info.dst_ptr_not_leading_to_static_ptr; 311 break; 312 case 1: 313 if (info.path_dst_ptr_to_static_ptr == public_path || 314 ( 315 info.number_to_dst_ptr == 0 && 316 info.path_dynamic_ptr_to_static_ptr == public_path && 317 info.path_dynamic_ptr_to_dst_ptr == public_path 318 ) 319 ) 320 return info.dst_ptr_leading_to_static_ptr; 321 break; 322 } 323 324 return nullptr; 325 } 326 327 } // namespace 328 329 // __shim_type_info 330 331 __shim_type_info::~__shim_type_info() 332 { 333 } 334 335 void __shim_type_info::noop1() const {} 336 void __shim_type_info::noop2() const {} 337 338 // __fundamental_type_info 339 340 // This miraculously (compiler magic) emits the type_info's for: 341 // 1. all of the fundamental types 342 // 2. pointers to all of the fundamental types 343 // 3. pointers to all of the const fundamental types 344 __fundamental_type_info::~__fundamental_type_info() 345 { 346 } 347 348 // __array_type_info 349 350 __array_type_info::~__array_type_info() 351 { 352 } 353 354 // __function_type_info 355 356 __function_type_info::~__function_type_info() 357 { 358 } 359 360 // __enum_type_info 361 362 __enum_type_info::~__enum_type_info() 363 { 364 } 365 366 // __class_type_info 367 368 __class_type_info::~__class_type_info() 369 { 370 } 371 372 // __si_class_type_info 373 374 __si_class_type_info::~__si_class_type_info() 375 { 376 } 377 378 // __vmi_class_type_info 379 380 __vmi_class_type_info::~__vmi_class_type_info() 381 { 382 } 383 384 // __pbase_type_info 385 386 __pbase_type_info::~__pbase_type_info() 387 { 388 } 389 390 // __pointer_type_info 391 392 __pointer_type_info::~__pointer_type_info() 393 { 394 } 395 396 // __pointer_to_member_type_info 397 398 __pointer_to_member_type_info::~__pointer_to_member_type_info() 399 { 400 } 401 402 // can_catch 403 404 // A handler is a match for an exception object of type E if 405 // 1. The handler is of type cv T or cv T& and E and T are the same type 406 // (ignoring the top-level cv-qualifiers), or 407 // 2. the handler is of type cv T or cv T& and T is an unambiguous public 408 // base class of E, or 409 // 3. the handler is of type cv1 T* cv2 and E is a pointer type that can be 410 // converted to the type of the handler by either or both of 411 // A. a standard pointer conversion (4.10) not involving conversions to 412 // pointers to private or protected or ambiguous classes 413 // B. a qualification conversion 414 // 4. the handler is a pointer or pointer to member type and E is 415 // std::nullptr_t. 416 417 // adjustedPtr: 418 // 419 // catch (A& a) : adjustedPtr == &a 420 // catch (A* a) : adjustedPtr == a 421 // catch (A** a) : adjustedPtr == a 422 // 423 // catch (D2& d2) : adjustedPtr == &d2 (d2 is base class of thrown object) 424 // catch (D2* d2) : adjustedPtr == d2 425 // catch (D2*& d2) : adjustedPtr == d2 426 // 427 // catch (...) : adjustedPtr == & of the exception 428 // 429 // If the thrown type is nullptr_t and the caught type is a pointer to 430 // member type, adjustedPtr points to a statically-allocated null pointer 431 // representation of that type. 432 433 // Handles bullet 1 434 bool 435 __fundamental_type_info::can_catch(const __shim_type_info* thrown_type, 436 void*&) const 437 { 438 return is_equal(this, thrown_type, false); 439 } 440 441 bool 442 __array_type_info::can_catch(const __shim_type_info*, void*&) const 443 { 444 // We can get here if someone tries to catch an array by reference. 445 // However if someone tries to throw an array, it immediately gets 446 // converted to a pointer, which will not convert back to an array 447 // at the catch clause. So this can never catch anything. 448 return false; 449 } 450 451 bool 452 __function_type_info::can_catch(const __shim_type_info*, void*&) const 453 { 454 // We can get here if someone tries to catch a function by reference. 455 // However if someone tries to throw a function, it immediately gets 456 // converted to a pointer, which will not convert back to a function 457 // at the catch clause. So this can never catch anything. 458 return false; 459 } 460 461 // Handles bullet 1 462 bool 463 __enum_type_info::can_catch(const __shim_type_info* thrown_type, 464 void*&) const 465 { 466 return is_equal(this, thrown_type, false); 467 } 468 469 #ifdef __clang__ 470 #pragma clang diagnostic push 471 #pragma clang diagnostic ignored "-Wmissing-field-initializers" 472 #endif 473 474 // Handles bullets 1 and 2 475 bool 476 __class_type_info::can_catch(const __shim_type_info* thrown_type, 477 void*& adjustedPtr) const 478 { 479 // bullet 1 480 if (is_equal(this, thrown_type, false)) 481 return true; 482 const __class_type_info* thrown_class_type = 483 dynamic_cast<const __class_type_info*>(thrown_type); 484 if (thrown_class_type == 0) 485 return false; 486 // bullet 2 487 _LIBCXXABI_ASSERT(adjustedPtr, "catching a class without an object?"); 488 __dynamic_cast_info info = {thrown_class_type, 0, this, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true, nullptr}; 489 info.number_of_dst_type = 1; 490 thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path); 491 if (info.path_dst_ptr_to_static_ptr == public_path) 492 { 493 adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr); 494 return true; 495 } 496 return false; 497 } 498 499 #ifdef __clang__ 500 #pragma clang diagnostic pop 501 #endif 502 503 // When we have an object to inspect - we just pass the pointer to the sub- 504 // object that matched the static_type we just checked. If that is different 505 // from any previously recorded pointer to that object type, then we have 506 // an ambiguous case. 507 508 // When we have no object to inspect, we need to account for virtual bases 509 // explicitly. 510 // info->vbase_cookie is a pointer to the name of the innermost virtual base 511 // type, or nullptr if there is no virtual base on the path so far. 512 // adjustedPtr points to the subobject we just found. 513 // If vbase_cookie != any previously recorded (including the case of nullptr 514 // representing an already-found static sub-object) then we have an ambiguous 515 // case. Assuming that the vbase_cookie values agree; if then we have a 516 // different offset (adjustedPtr) from any previously recorded, this indicates 517 // an ambiguous case within the virtual base. 518 519 void 520 __class_type_info::process_found_base_class(__dynamic_cast_info* info, 521 void* adjustedPtr, 522 int path_below) const 523 { 524 if (info->number_to_static_ptr == 0) { 525 // First time we found this base 526 info->dst_ptr_leading_to_static_ptr = adjustedPtr; 527 info->path_dst_ptr_to_static_ptr = path_below; 528 // stash the virtual base cookie. 529 info->dst_ptr_not_leading_to_static_ptr = info->vbase_cookie; 530 info->number_to_static_ptr = 1; 531 } else if (info->dst_ptr_not_leading_to_static_ptr == info->vbase_cookie && 532 info->dst_ptr_leading_to_static_ptr == adjustedPtr) { 533 // We've been here before. Update path to "most public" 534 if (info->path_dst_ptr_to_static_ptr == not_public_path) 535 info->path_dst_ptr_to_static_ptr = path_below; 536 } else { 537 // We've detected an ambiguous cast from (thrown_class_type, adjustedPtr) 538 // to a static_type. 539 info->number_to_static_ptr += 1; 540 info->path_dst_ptr_to_static_ptr = not_public_path; 541 info->search_done = true; 542 } 543 } 544 545 void 546 __class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 547 void* adjustedPtr, 548 int path_below) const 549 { 550 if (is_equal(this, info->static_type, false)) 551 process_found_base_class(info, adjustedPtr, path_below); 552 } 553 554 void 555 __si_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 556 void* adjustedPtr, 557 int path_below) const 558 { 559 if (is_equal(this, info->static_type, false)) 560 process_found_base_class(info, adjustedPtr, path_below); 561 else 562 __base_type->has_unambiguous_public_base(info, adjustedPtr, path_below); 563 } 564 565 void 566 __base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 567 void* adjustedPtr, 568 int path_below) const 569 { 570 bool is_virtual = __offset_flags & __virtual_mask; 571 ptrdiff_t offset_to_base = 0; 572 if (info->have_object) { 573 /* We have an object to inspect, we can look through its vtables to 574 find the layout. */ 575 offset_to_base = __offset_flags >> __offset_shift; 576 if (is_virtual) { 577 const char* vtable = strip_vtable(*static_cast<const char* const*>(adjustedPtr)); 578 offset_to_base = update_offset_to_base(vtable, offset_to_base); 579 } 580 } else if (!is_virtual) { 581 /* We have no object; however, for non-virtual bases, (since we do not 582 need to inspect any content) we can pretend to have an object based 583 at '0'. */ 584 offset_to_base = __offset_flags >> __offset_shift; 585 } else { 586 /* No object to inspect, and the next base is virtual. 587 We cannot indirect through the vtable to find the actual object offset. 588 So, update vbase_cookie to the new innermost virtual base using the 589 pointer to the typeinfo name as a key. */ 590 info->vbase_cookie = static_cast<const void*>(__base_type->name()); 591 // .. and reset the pointer. 592 adjustedPtr = nullptr; 593 } 594 __base_type->has_unambiguous_public_base( 595 info, reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(adjustedPtr) + offset_to_base), 596 (__offset_flags & __public_mask) ? path_below : not_public_path); 597 } 598 599 void 600 __vmi_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, 601 void* adjustedPtr, 602 int path_below) const 603 { 604 if (is_equal(this, info->static_type, false)) 605 process_found_base_class(info, adjustedPtr, path_below); 606 else 607 { 608 typedef const __base_class_type_info* Iter; 609 const Iter e = __base_info + __base_count; 610 Iter p = __base_info; 611 p->has_unambiguous_public_base(info, adjustedPtr, path_below); 612 if (++p < e) 613 { 614 do 615 { 616 p->has_unambiguous_public_base(info, adjustedPtr, path_below); 617 if (info->search_done) 618 break; 619 } while (++p < e); 620 } 621 } 622 } 623 624 // Handles bullet 1 for both pointers and member pointers 625 bool 626 __pbase_type_info::can_catch(const __shim_type_info* thrown_type, 627 void*&) const 628 { 629 bool use_strcmp = this->__flags & (__incomplete_class_mask | 630 __incomplete_mask); 631 if (!use_strcmp) { 632 const __pbase_type_info* thrown_pbase = dynamic_cast<const __pbase_type_info*>( 633 thrown_type); 634 if (!thrown_pbase) return false; 635 use_strcmp = thrown_pbase->__flags & (__incomplete_class_mask | 636 __incomplete_mask); 637 } 638 return is_equal(this, thrown_type, use_strcmp); 639 } 640 641 #ifdef __clang__ 642 #pragma clang diagnostic push 643 #pragma clang diagnostic ignored "-Wmissing-field-initializers" 644 #endif 645 646 // Handles bullets 1, 3 and 4 647 // NOTE: It might not be safe to adjust the pointer if it is not not a pointer 648 // type. Only adjust the pointer after we know it is safe to do so. 649 bool 650 __pointer_type_info::can_catch(const __shim_type_info* thrown_type, 651 void*& adjustedPtr) const 652 { 653 // bullet 4 654 if (is_equal(thrown_type, &typeid(std::nullptr_t), false)) { 655 adjustedPtr = nullptr; 656 return true; 657 } 658 659 // bullet 1 660 if (__pbase_type_info::can_catch(thrown_type, adjustedPtr)) { 661 if (adjustedPtr != NULL) 662 adjustedPtr = *static_cast<void**>(adjustedPtr); 663 return true; 664 } 665 // bullet 3 666 const __pointer_type_info* thrown_pointer_type = 667 dynamic_cast<const __pointer_type_info*>(thrown_type); 668 if (thrown_pointer_type == 0) 669 return false; 670 // Do the dereference adjustment 671 if (adjustedPtr != NULL) 672 adjustedPtr = *static_cast<void**>(adjustedPtr); 673 // bullet 3B and 3C 674 if (thrown_pointer_type->__flags & ~__flags & __no_remove_flags_mask) 675 return false; 676 if (__flags & ~thrown_pointer_type->__flags & __no_add_flags_mask) 677 return false; 678 if (is_equal(__pointee, thrown_pointer_type->__pointee, false)) 679 return true; 680 // bullet 3A 681 if (is_equal(__pointee, &typeid(void), false)) { 682 // pointers to functions cannot be converted to void*. 683 // pointers to member functions are not handled here. 684 const __function_type_info* thrown_function = 685 dynamic_cast<const __function_type_info*>(thrown_pointer_type->__pointee); 686 return (thrown_function == nullptr); 687 } 688 // Handle pointer to pointer 689 const __pointer_type_info* nested_pointer_type = 690 dynamic_cast<const __pointer_type_info*>(__pointee); 691 if (nested_pointer_type) { 692 if (~__flags & __const_mask) return false; 693 return nested_pointer_type->can_catch_nested(thrown_pointer_type->__pointee); 694 } 695 696 // Handle pointer to pointer to member 697 const __pointer_to_member_type_info* member_ptr_type = 698 dynamic_cast<const __pointer_to_member_type_info*>(__pointee); 699 if (member_ptr_type) { 700 if (~__flags & __const_mask) return false; 701 return member_ptr_type->can_catch_nested(thrown_pointer_type->__pointee); 702 } 703 704 // Handle pointer to class type 705 const __class_type_info* catch_class_type = 706 dynamic_cast<const __class_type_info*>(__pointee); 707 if (catch_class_type == 0) 708 return false; 709 const __class_type_info* thrown_class_type = 710 dynamic_cast<const __class_type_info*>(thrown_pointer_type->__pointee); 711 if (thrown_class_type == 0) 712 return false; 713 bool have_object = adjustedPtr != nullptr; 714 __dynamic_cast_info info = {thrown_class_type, 0, catch_class_type, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 715 have_object, nullptr}; 716 info.number_of_dst_type = 1; 717 thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path); 718 if (info.path_dst_ptr_to_static_ptr == public_path) 719 { 720 // In the case of a thrown null pointer, we have no object but we might 721 // well have computed the offset to where a public sub-object would be. 722 // However, we do not want to return that offset to the user; we still 723 // want them to catch a null ptr. 724 if (have_object) 725 adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr); 726 else 727 adjustedPtr = nullptr; 728 return true; 729 } 730 return false; 731 } 732 733 bool __pointer_type_info::can_catch_nested( 734 const __shim_type_info* thrown_type) const 735 { 736 const __pointer_type_info* thrown_pointer_type = 737 dynamic_cast<const __pointer_type_info*>(thrown_type); 738 if (thrown_pointer_type == 0) 739 return false; 740 // bullet 3B 741 if (thrown_pointer_type->__flags & ~__flags) 742 return false; 743 if (is_equal(__pointee, thrown_pointer_type->__pointee, false)) 744 return true; 745 // If the pointed to types differ then the catch type must be const 746 // qualified. 747 if (~__flags & __const_mask) 748 return false; 749 750 // Handle pointer to pointer 751 const __pointer_type_info* nested_pointer_type = 752 dynamic_cast<const __pointer_type_info*>(__pointee); 753 if (nested_pointer_type) { 754 return nested_pointer_type->can_catch_nested( 755 thrown_pointer_type->__pointee); 756 } 757 758 // Handle pointer to pointer to member 759 const __pointer_to_member_type_info* member_ptr_type = 760 dynamic_cast<const __pointer_to_member_type_info*>(__pointee); 761 if (member_ptr_type) { 762 return member_ptr_type->can_catch_nested(thrown_pointer_type->__pointee); 763 } 764 765 return false; 766 } 767 768 bool __pointer_to_member_type_info::can_catch( 769 const __shim_type_info* thrown_type, void*& adjustedPtr) const { 770 // bullet 4 771 if (is_equal(thrown_type, &typeid(std::nullptr_t), false)) { 772 // We assume that the pointer to member representation is the same for 773 // all pointers to data members and for all pointers to member functions. 774 struct X {}; 775 if (dynamic_cast<const __function_type_info*>(__pointee)) { 776 static int (X::*const null_ptr_rep)() = nullptr; 777 adjustedPtr = const_cast<int (X::**)()>(&null_ptr_rep); 778 } else { 779 static int X::*const null_ptr_rep = nullptr; 780 adjustedPtr = const_cast<int X::**>(&null_ptr_rep); 781 } 782 return true; 783 } 784 785 // bullet 1 786 if (__pbase_type_info::can_catch(thrown_type, adjustedPtr)) 787 return true; 788 789 const __pointer_to_member_type_info* thrown_pointer_type = 790 dynamic_cast<const __pointer_to_member_type_info*>(thrown_type); 791 if (thrown_pointer_type == 0) 792 return false; 793 if (thrown_pointer_type->__flags & ~__flags & __no_remove_flags_mask) 794 return false; 795 if (__flags & ~thrown_pointer_type->__flags & __no_add_flags_mask) 796 return false; 797 if (!is_equal(__pointee, thrown_pointer_type->__pointee, false)) 798 return false; 799 if (is_equal(__context, thrown_pointer_type->__context, false)) 800 return true; 801 802 // [except.handle] does not allow the pointer-to-member conversions mentioned 803 // in [mem.conv] to take place. For this reason we don't check Derived->Base 804 // for Derived->Base conversions. 805 806 return false; 807 } 808 809 bool __pointer_to_member_type_info::can_catch_nested( 810 const __shim_type_info* thrown_type) const 811 { 812 const __pointer_to_member_type_info* thrown_member_ptr_type = 813 dynamic_cast<const __pointer_to_member_type_info*>(thrown_type); 814 if (thrown_member_ptr_type == 0) 815 return false; 816 if (~__flags & thrown_member_ptr_type->__flags) 817 return false; 818 if (!is_equal(__pointee, thrown_member_ptr_type->__pointee, false)) 819 return false; 820 if (!is_equal(__context, thrown_member_ptr_type->__context, false)) 821 return false; 822 return true; 823 } 824 825 #ifdef __clang__ 826 #pragma clang diagnostic pop 827 #endif 828 829 #ifdef __clang__ 830 #pragma clang diagnostic push 831 #pragma clang diagnostic ignored "-Wmissing-field-initializers" 832 #endif 833 834 // __dynamic_cast 835 836 // static_ptr: pointer to an object of type static_type; nonnull, and since the 837 // object is polymorphic, *(void**)static_ptr is a virtual table pointer. 838 // static_ptr is &v in the expression dynamic_cast<T>(v). 839 // static_type: static type of the object pointed to by static_ptr. 840 // dst_type: destination type of the cast (the "T" in "dynamic_cast<T>(v)"). 841 // src2dst_offset: a static hint about the location of the 842 // source subobject with respect to the complete object; 843 // special negative values are: 844 // -1: no hint 845 // -2: static_type is not a public base of dst_type 846 // -3: static_type is a multiple public base type but never a 847 // virtual base type 848 // otherwise, the static_type type is a unique public nonvirtual 849 // base type of dst_type at offset src2dst_offset from the 850 // origin of dst_type. 851 // 852 // (dynamic_ptr, dynamic_type) are the run time type of the complete object 853 // referred to by static_ptr and a pointer to it. These can be found from 854 // static_ptr for polymorphic types. 855 // static_type is guaranteed to be a polymorphic type. 856 // 857 // (dynamic_ptr, dynamic_type) is the root of a DAG that grows upward. Each 858 // node of the tree represents a base class/object of its parent (or parents) below. 859 // Each node is uniquely represented by a pointer to the object, and a pointer 860 // to a type_info - its type. Different nodes may have the same pointer and 861 // different nodes may have the same type. But only one node has a specific 862 // (pointer-value, type) pair. In C++ two objects of the same type can not 863 // share the same address. 864 // 865 // There are two flavors of nodes which have the type dst_type: 866 // 1. Those that are derived from (below) (static_ptr, static_type). 867 // 2. Those that are not derived from (below) (static_ptr, static_type). 868 // 869 // Invariants of the DAG: 870 // 871 // There is at least one path from the root (dynamic_ptr, dynamic_type) to 872 // the node (static_ptr, static_type). This path may or may not be public. 873 // There may be more than one such path (some public some not). Such a path may 874 // or may not go through a node having type dst_type. 875 // 876 // No node of type T appears above a node of the same type. That means that 877 // there is only one node with dynamic_type. And if dynamic_type == dst_type, 878 // then there is only one dst_type in the DAG. 879 // 880 // No node of type dst_type appears above a node of type static_type. Such 881 // DAG's are possible in C++, but the compiler computes those dynamic_casts at 882 // compile time, and only calls __dynamic_cast when dst_type lies below 883 // static_type in the DAG. 884 // 885 // dst_type != static_type: The compiler computes the dynamic_cast in this case too. 886 // dynamic_type != static_type: The compiler computes the dynamic_cast in this case too. 887 // 888 // Returns: 889 // 890 // If there is exactly one dst_type of flavor 1, and 891 // If there is a public path from that dst_type to (static_ptr, static_type), or 892 // If there are 0 dst_types of flavor 2, and there is a public path from 893 // (dynamic_ptr, dynamic_type) to (static_ptr, static_type) and a public 894 // path from (dynamic_ptr, dynamic_type) to the one dst_type, then return 895 // a pointer to that dst_type. 896 // Else if there are 0 dst_types of flavor 1 and exactly 1 dst_type of flavor 2, and 897 // if there is a public path from (dynamic_ptr, dynamic_type) to 898 // (static_ptr, static_type) and a public path from (dynamic_ptr, dynamic_type) 899 // to the one dst_type, then return a pointer to that one dst_type. 900 // Else return nullptr. 901 // 902 // If dynamic_type == dst_type, then the above algorithm collapses to the 903 // following cheaper algorithm: 904 // 905 // If there is a public path from (dynamic_ptr, dynamic_type) to 906 // (static_ptr, static_type), then return dynamic_ptr. 907 // Else return nullptr. 908 909 extern "C" _LIBCXXABI_FUNC_VIS void * 910 __dynamic_cast(const void *static_ptr, const __class_type_info *static_type, 911 const __class_type_info *dst_type, 912 std::ptrdiff_t src2dst_offset) { 913 // Get (dynamic_ptr, dynamic_type) from static_ptr 914 derived_object_info derived_info; 915 dyn_cast_get_derived_info(&derived_info, static_ptr); 916 917 // Initialize answer to nullptr. This will be changed from the search 918 // results if a non-null answer is found. Regardless, this is what will 919 // be returned. 920 const void* dst_ptr = 0; 921 922 // Find out if we can use a giant short cut in the search 923 if (is_equal(derived_info.dynamic_type, dst_type, false)) 924 { 925 dst_ptr = dyn_cast_to_derived(static_ptr, 926 derived_info.dynamic_ptr, 927 static_type, 928 dst_type, 929 derived_info.offset_to_derived, 930 src2dst_offset); 931 } 932 else 933 { 934 // Optimize toward downcasting: let's first try to do a downcast before 935 // falling back to the slow path. 936 dst_ptr = dyn_cast_try_downcast(static_ptr, 937 derived_info.dynamic_ptr, 938 dst_type, 939 derived_info.dynamic_type, 940 src2dst_offset); 941 942 if (!dst_ptr) 943 { 944 dst_ptr = dyn_cast_slow(static_ptr, 945 derived_info.dynamic_ptr, 946 static_type, 947 dst_type, 948 derived_info.dynamic_type, 949 src2dst_offset); 950 } 951 } 952 953 return const_cast<void*>(dst_ptr); 954 } 955 956 #ifdef __clang__ 957 #pragma clang diagnostic pop 958 #endif 959 960 // Call this function when you hit a static_type which is a base (above) a dst_type. 961 // Let caller know you hit a static_type. But only start recording details if 962 // this is (static_ptr, static_type) -- the node we are casting from. 963 // If this is (static_ptr, static_type) 964 // Record the path (public or not) from the dst_type to here. There may be 965 // multiple paths from the same dst_type to here, record the "most public" one. 966 // Record the dst_ptr as pointing to (static_ptr, static_type). 967 // If more than one (dst_ptr, dst_type) points to (static_ptr, static_type), 968 // then mark this dyanmic_cast as ambiguous and stop the search. 969 void 970 __class_type_info::process_static_type_above_dst(__dynamic_cast_info* info, 971 const void* dst_ptr, 972 const void* current_ptr, 973 int path_below) const 974 { 975 // Record that we found a static_type 976 info->found_any_static_type = true; 977 if (current_ptr == info->static_ptr) 978 { 979 // Record that we found (static_ptr, static_type) 980 info->found_our_static_ptr = true; 981 if (info->dst_ptr_leading_to_static_ptr == 0) 982 { 983 // First time here 984 info->dst_ptr_leading_to_static_ptr = dst_ptr; 985 info->path_dst_ptr_to_static_ptr = path_below; 986 info->number_to_static_ptr = 1; 987 // If there is only one dst_type in the entire tree and the path from 988 // there to here is public then we are done! 989 if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path) 990 info->search_done = true; 991 } 992 else if (info->dst_ptr_leading_to_static_ptr == dst_ptr) 993 { 994 // We've been here before. Update path to "most public" 995 if (info->path_dst_ptr_to_static_ptr == not_public_path) 996 info->path_dst_ptr_to_static_ptr = path_below; 997 // If there is only one dst_type in the entire tree and the path from 998 // there to here is public then we are done! 999 if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path) 1000 info->search_done = true; 1001 } 1002 else 1003 { 1004 // We've detected an ambiguous cast from (static_ptr, static_type) 1005 // to a dst_type 1006 info->number_to_static_ptr += 1; 1007 info->search_done = true; 1008 } 1009 } 1010 } 1011 1012 // Call this function when you hit a static_type which is not a base (above) a dst_type. 1013 // If this is (static_ptr, static_type) 1014 // Record the path (public or not) from (dynamic_ptr, dynamic_type) to here. There may be 1015 // multiple paths from (dynamic_ptr, dynamic_type) to here, record the "most public" one. 1016 void 1017 __class_type_info::process_static_type_below_dst(__dynamic_cast_info* info, 1018 const void* current_ptr, 1019 int path_below) const 1020 { 1021 if (current_ptr == info->static_ptr) 1022 { 1023 // Record the most public path from (dynamic_ptr, dynamic_type) to 1024 // (static_ptr, static_type) 1025 if (info->path_dynamic_ptr_to_static_ptr != public_path) 1026 info->path_dynamic_ptr_to_static_ptr = path_below; 1027 } 1028 } 1029 1030 // Call this function when searching below a dst_type node. This function searches 1031 // for a path to (static_ptr, static_type) and for paths to one or more dst_type nodes. 1032 // If it finds a static_type node, there is no need to further search base classes 1033 // above. 1034 // If it finds a dst_type node it should search base classes using search_above_dst 1035 // to find out if this dst_type points to (static_ptr, static_type) or not. 1036 // Either way, the dst_type is recorded as one of two "flavors": one that does 1037 // or does not point to (static_ptr, static_type). 1038 // If this is neither a static_type nor a dst_type node, continue searching 1039 // base classes above. 1040 // All the hoopla surrounding the search code is doing nothing but looking for 1041 // excuses to stop the search prematurely (break out of the for-loop). That is, 1042 // the algorithm below is simply an optimization of this: 1043 // void 1044 // __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, 1045 // const void* current_ptr, 1046 // int path_below) const 1047 // { 1048 // typedef const __base_class_type_info* Iter; 1049 // if (this == info->static_type) 1050 // process_static_type_below_dst(info, current_ptr, path_below); 1051 // else if (this == info->dst_type) 1052 // { 1053 // // Record the most public access path that got us here 1054 // if (info->path_dynamic_ptr_to_dst_ptr != public_path) 1055 // info->path_dynamic_ptr_to_dst_ptr = path_below; 1056 // bool does_dst_type_point_to_our_static_type = false; 1057 // for (Iter p = __base_info, e= __base_info + __base_count; p < e; ++p) 1058 // { 1059 // p->search_above_dst(info, current_ptr, current_ptr, public_path); 1060 // if (info->found_our_static_ptr) 1061 // does_dst_type_point_to_our_static_type = true; 1062 // // break out early here if you can detect it doesn't matter if you do 1063 // } 1064 // if (!does_dst_type_point_to_our_static_type) 1065 // { 1066 // // We found a dst_type that doesn't point to (static_ptr, static_type) 1067 // // So record the address of this dst_ptr and increment the 1068 // // count of the number of such dst_types found in the tree. 1069 // info->dst_ptr_not_leading_to_static_ptr = current_ptr; 1070 // info->number_to_dst_ptr += 1; 1071 // } 1072 // } 1073 // else 1074 // { 1075 // // This is not a static_type and not a dst_type. 1076 // for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p) 1077 // { 1078 // p->search_below_dst(info, current_ptr, public_path); 1079 // // break out early here if you can detect it doesn't matter if you do 1080 // } 1081 // } 1082 // } 1083 void 1084 __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, 1085 const void* current_ptr, 1086 int path_below, 1087 bool use_strcmp) const 1088 { 1089 typedef const __base_class_type_info* Iter; 1090 if (is_equal(this, info->static_type, use_strcmp)) 1091 process_static_type_below_dst(info, current_ptr, path_below); 1092 else if (is_equal(this, info->dst_type, use_strcmp)) 1093 { 1094 // We've been here before if we've recorded current_ptr in one of these 1095 // two places: 1096 if (current_ptr == info->dst_ptr_leading_to_static_ptr || 1097 current_ptr == info->dst_ptr_not_leading_to_static_ptr) 1098 { 1099 // We've seen this node before, and therefore have already searched 1100 // its base classes above. 1101 // Update path to here that is "most public". 1102 if (path_below == public_path) 1103 info->path_dynamic_ptr_to_dst_ptr = public_path; 1104 } 1105 else // We have haven't been here before 1106 { 1107 // Record the access path that got us here 1108 // If there is more than one dst_type this path doesn't matter. 1109 info->path_dynamic_ptr_to_dst_ptr = path_below; 1110 bool does_dst_type_point_to_our_static_type = false; 1111 // Only search above here if dst_type derives from static_type, or 1112 // if it is unknown if dst_type derives from static_type. 1113 if (info->is_dst_type_derived_from_static_type != no) 1114 { 1115 // Set up flags to record results from all base classes 1116 bool is_dst_type_derived_from_static_type = false; 1117 1118 // We've found a dst_type with a potentially public path to here. 1119 // We have to assume the path is public because it may become 1120 // public later (if we get back to here with a public path). 1121 // We can stop looking above if: 1122 // 1. We've found a public path to (static_ptr, static_type). 1123 // 2. We've found an ambiguous cast from (static_ptr, static_type) to a dst_type. 1124 // This is detected at the (static_ptr, static_type). 1125 // 3. We can prove that there is no public path to (static_ptr, static_type) 1126 // above here. 1127 const Iter e = __base_info + __base_count; 1128 for (Iter p = __base_info; p < e; ++p) 1129 { 1130 // Zero out found flags 1131 info->found_our_static_ptr = false; 1132 info->found_any_static_type = false; 1133 p->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp); 1134 if (info->search_done) 1135 break; 1136 if (info->found_any_static_type) 1137 { 1138 is_dst_type_derived_from_static_type = true; 1139 if (info->found_our_static_ptr) 1140 { 1141 does_dst_type_point_to_our_static_type = true; 1142 // If we found what we're looking for, stop looking above. 1143 if (info->path_dst_ptr_to_static_ptr == public_path) 1144 break; 1145 // We found a private path to (static_ptr, static_type) 1146 // If there is no diamond then there is only one path 1147 // to (static_ptr, static_type) and we just found it. 1148 if (!(__flags & __diamond_shaped_mask)) 1149 break; 1150 } 1151 else 1152 { 1153 // If we found a static_type that isn't the one we're looking 1154 // for, and if there are no repeated types above here, 1155 // then stop looking. 1156 if (!(__flags & __non_diamond_repeat_mask)) 1157 break; 1158 } 1159 } 1160 } 1161 // If we found no static_type,s then dst_type doesn't derive 1162 // from static_type, else it does. Record this result so that 1163 // next time we hit a dst_type we will know not to search above 1164 // it if it doesn't derive from static_type. 1165 if (is_dst_type_derived_from_static_type) 1166 info->is_dst_type_derived_from_static_type = yes; 1167 else 1168 info->is_dst_type_derived_from_static_type = no; 1169 } 1170 if (!does_dst_type_point_to_our_static_type) 1171 { 1172 // We found a dst_type that doesn't point to (static_ptr, static_type) 1173 // So record the address of this dst_ptr and increment the 1174 // count of the number of such dst_types found in the tree. 1175 info->dst_ptr_not_leading_to_static_ptr = current_ptr; 1176 info->number_to_dst_ptr += 1; 1177 // If there exists another dst with a private path to 1178 // (static_ptr, static_type), then the cast from 1179 // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous, 1180 // so stop search. 1181 if (info->number_to_static_ptr == 1 && 1182 info->path_dst_ptr_to_static_ptr == not_public_path) 1183 info->search_done = true; 1184 } 1185 } 1186 } 1187 else 1188 { 1189 // This is not a static_type and not a dst_type. 1190 const Iter e = __base_info + __base_count; 1191 Iter p = __base_info; 1192 p->search_below_dst(info, current_ptr, path_below, use_strcmp); 1193 if (++p < e) 1194 { 1195 if ((__flags & __diamond_shaped_mask) || info->number_to_static_ptr == 1) 1196 { 1197 // If there are multiple paths to a base above from here, or if 1198 // a dst_type pointing to (static_ptr, static_type) has been found, 1199 // then there is no way to break out of this loop early unless 1200 // something below detects the search is done. 1201 do 1202 { 1203 if (info->search_done) 1204 break; 1205 p->search_below_dst(info, current_ptr, path_below, use_strcmp); 1206 } while (++p < e); 1207 } 1208 else if (__flags & __non_diamond_repeat_mask) 1209 { 1210 // There are not multiple paths to any base class from here and a 1211 // dst_type pointing to (static_ptr, static_type) has not yet been 1212 // found. 1213 do 1214 { 1215 if (info->search_done) 1216 break; 1217 // If we just found a dst_type with a public path to (static_ptr, static_type), 1218 // then the only reason to continue the search is to make sure 1219 // no other dst_type points to (static_ptr, static_type). 1220 // If !diamond, then we don't need to search here. 1221 if (info->number_to_static_ptr == 1 && 1222 info->path_dst_ptr_to_static_ptr == public_path) 1223 break; 1224 p->search_below_dst(info, current_ptr, path_below, use_strcmp); 1225 } while (++p < e); 1226 } 1227 else 1228 { 1229 // There are no repeated types above this node. 1230 // There are no nodes with multiple parents above this node. 1231 // no dst_type has been found to (static_ptr, static_type) 1232 do 1233 { 1234 if (info->search_done) 1235 break; 1236 // If we just found a dst_type with a public path to (static_ptr, static_type), 1237 // then the only reason to continue the search is to make sure 1238 // no other dst_type points to (static_ptr, static_type). 1239 // If !diamond, then we don't need to search here. 1240 // if we just found a dst_type with a private path to (static_ptr, static_type), 1241 // then we're only looking for a public path to (static_ptr, static_type) 1242 // and to check for other dst_types. 1243 // If !diamond & !repeat, then there is not a pointer to (static_ptr, static_type) 1244 // and not a dst_type under here. 1245 if (info->number_to_static_ptr == 1) 1246 break; 1247 p->search_below_dst(info, current_ptr, path_below, use_strcmp); 1248 } while (++p < e); 1249 } 1250 } 1251 } 1252 } 1253 1254 // This is the same algorithm as __vmi_class_type_info::search_below_dst but 1255 // simplified to the case that there is only a single base class. 1256 void 1257 __si_class_type_info::search_below_dst(__dynamic_cast_info* info, 1258 const void* current_ptr, 1259 int path_below, 1260 bool use_strcmp) const 1261 { 1262 if (is_equal(this, info->static_type, use_strcmp)) 1263 process_static_type_below_dst(info, current_ptr, path_below); 1264 else if (is_equal(this, info->dst_type, use_strcmp)) 1265 { 1266 // We've been here before if we've recorded current_ptr in one of these 1267 // two places: 1268 if (current_ptr == info->dst_ptr_leading_to_static_ptr || 1269 current_ptr == info->dst_ptr_not_leading_to_static_ptr) 1270 { 1271 // We've seen this node before, and therefore have already searched 1272 // its base classes above. 1273 // Update path to here that is "most public". 1274 if (path_below == public_path) 1275 info->path_dynamic_ptr_to_dst_ptr = public_path; 1276 } 1277 else // We have haven't been here before 1278 { 1279 // Record the access path that got us here 1280 // If there is more than one dst_type this path doesn't matter. 1281 info->path_dynamic_ptr_to_dst_ptr = path_below; 1282 bool does_dst_type_point_to_our_static_type = false; 1283 // Only search above here if dst_type derives from static_type, or 1284 // if it is unknown if dst_type derives from static_type. 1285 if (info->is_dst_type_derived_from_static_type != no) 1286 { 1287 // Set up flags to record results from all base classes 1288 bool is_dst_type_derived_from_static_type = false; 1289 // Zero out found flags 1290 info->found_our_static_ptr = false; 1291 info->found_any_static_type = false; 1292 __base_type->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp); 1293 if (info->found_any_static_type) 1294 { 1295 is_dst_type_derived_from_static_type = true; 1296 if (info->found_our_static_ptr) 1297 does_dst_type_point_to_our_static_type = true; 1298 } 1299 // If we found no static_type,s then dst_type doesn't derive 1300 // from static_type, else it does. Record this result so that 1301 // next time we hit a dst_type we will know not to search above 1302 // it if it doesn't derive from static_type. 1303 if (is_dst_type_derived_from_static_type) 1304 info->is_dst_type_derived_from_static_type = yes; 1305 else 1306 info->is_dst_type_derived_from_static_type = no; 1307 } 1308 if (!does_dst_type_point_to_our_static_type) 1309 { 1310 // We found a dst_type that doesn't point to (static_ptr, static_type) 1311 // So record the address of this dst_ptr and increment the 1312 // count of the number of such dst_types found in the tree. 1313 info->dst_ptr_not_leading_to_static_ptr = current_ptr; 1314 info->number_to_dst_ptr += 1; 1315 // If there exists another dst with a private path to 1316 // (static_ptr, static_type), then the cast from 1317 // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous. 1318 if (info->number_to_static_ptr == 1 && 1319 info->path_dst_ptr_to_static_ptr == not_public_path) 1320 info->search_done = true; 1321 } 1322 } 1323 } 1324 else 1325 { 1326 // This is not a static_type and not a dst_type 1327 __base_type->search_below_dst(info, current_ptr, path_below, use_strcmp); 1328 } 1329 } 1330 1331 // This is the same algorithm as __vmi_class_type_info::search_below_dst but 1332 // simplified to the case that there is no base class. 1333 void 1334 __class_type_info::search_below_dst(__dynamic_cast_info* info, 1335 const void* current_ptr, 1336 int path_below, 1337 bool use_strcmp) const 1338 { 1339 if (is_equal(this, info->static_type, use_strcmp)) 1340 process_static_type_below_dst(info, current_ptr, path_below); 1341 else if (is_equal(this, info->dst_type, use_strcmp)) 1342 { 1343 // We've been here before if we've recorded current_ptr in one of these 1344 // two places: 1345 if (current_ptr == info->dst_ptr_leading_to_static_ptr || 1346 current_ptr == info->dst_ptr_not_leading_to_static_ptr) 1347 { 1348 // We've seen this node before, and therefore have already searched 1349 // its base classes above. 1350 // Update path to here that is "most public". 1351 if (path_below == public_path) 1352 info->path_dynamic_ptr_to_dst_ptr = public_path; 1353 } 1354 else // We have haven't been here before 1355 { 1356 // Record the access path that got us here 1357 // If there is more than one dst_type this path doesn't matter. 1358 info->path_dynamic_ptr_to_dst_ptr = path_below; 1359 // We found a dst_type that doesn't point to (static_ptr, static_type) 1360 // So record the address of this dst_ptr and increment the 1361 // count of the number of such dst_types found in the tree. 1362 info->dst_ptr_not_leading_to_static_ptr = current_ptr; 1363 info->number_to_dst_ptr += 1; 1364 // If there exists another dst with a private path to 1365 // (static_ptr, static_type), then the cast from 1366 // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous. 1367 if (info->number_to_static_ptr == 1 && 1368 info->path_dst_ptr_to_static_ptr == not_public_path) 1369 info->search_done = true; 1370 // We found that dst_type does not derive from static_type 1371 info->is_dst_type_derived_from_static_type = no; 1372 } 1373 } 1374 } 1375 1376 // Call this function when searching above a dst_type node. This function searches 1377 // for a public path to (static_ptr, static_type). 1378 // This function is guaranteed not to find a node of type dst_type. 1379 // Theoretically this is a very simple function which just stops if it finds a 1380 // static_type node: All the hoopla surrounding the search code is doing 1381 // nothing but looking for excuses to stop the search prematurely (break out of 1382 // the for-loop). That is, the algorithm below is simply an optimization of this: 1383 // void 1384 // __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, 1385 // const void* dst_ptr, 1386 // const void* current_ptr, 1387 // int path_below) const 1388 // { 1389 // if (this == info->static_type) 1390 // process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 1391 // else 1392 // { 1393 // typedef const __base_class_type_info* Iter; 1394 // // This is not a static_type and not a dst_type 1395 // for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p) 1396 // { 1397 // p->search_above_dst(info, dst_ptr, current_ptr, public_path); 1398 // // break out early here if you can detect it doesn't matter if you do 1399 // } 1400 // } 1401 // } 1402 void 1403 __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, 1404 const void* dst_ptr, 1405 const void* current_ptr, 1406 int path_below, 1407 bool use_strcmp) const 1408 { 1409 if (is_equal(this, info->static_type, use_strcmp)) 1410 process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 1411 else 1412 { 1413 typedef const __base_class_type_info* Iter; 1414 // This is not a static_type and not a dst_type 1415 // Save flags so they can be restored when returning to nodes below. 1416 bool found_our_static_ptr = info->found_our_static_ptr; 1417 bool found_any_static_type = info->found_any_static_type; 1418 // We've found a dst_type below with a path to here. If the path 1419 // to here is not public, there may be another path to here that 1420 // is public. So we have to assume that the path to here is public. 1421 // We can stop looking above if: 1422 // 1. We've found a public path to (static_ptr, static_type). 1423 // 2. We've found an ambiguous cast from (static_ptr, static_type) to a dst_type. 1424 // This is detected at the (static_ptr, static_type). 1425 // 3. We can prove that there is no public path to (static_ptr, static_type) 1426 // above here. 1427 const Iter e = __base_info + __base_count; 1428 Iter p = __base_info; 1429 // Zero out found flags 1430 info->found_our_static_ptr = false; 1431 info->found_any_static_type = false; 1432 p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); 1433 found_our_static_ptr |= info->found_our_static_ptr; 1434 found_any_static_type |= info->found_any_static_type; 1435 if (++p < e) 1436 { 1437 do 1438 { 1439 if (info->search_done) 1440 break; 1441 if (info->found_our_static_ptr) 1442 { 1443 // If we found what we're looking for, stop looking above. 1444 if (info->path_dst_ptr_to_static_ptr == public_path) 1445 break; 1446 // We found a private path to (static_ptr, static_type) 1447 // If there is no diamond then there is only one path 1448 // to (static_ptr, static_type) from here and we just found it. 1449 if (!(__flags & __diamond_shaped_mask)) 1450 break; 1451 } 1452 else if (info->found_any_static_type) 1453 { 1454 // If we found a static_type that isn't the one we're looking 1455 // for, and if there are no repeated types above here, 1456 // then stop looking. 1457 if (!(__flags & __non_diamond_repeat_mask)) 1458 break; 1459 } 1460 // Zero out found flags 1461 info->found_our_static_ptr = false; 1462 info->found_any_static_type = false; 1463 p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); 1464 found_our_static_ptr |= info->found_our_static_ptr; 1465 found_any_static_type |= info->found_any_static_type; 1466 } while (++p < e); 1467 } 1468 // Restore flags 1469 info->found_our_static_ptr = found_our_static_ptr; 1470 info->found_any_static_type = found_any_static_type; 1471 } 1472 } 1473 1474 // This is the same algorithm as __vmi_class_type_info::search_above_dst but 1475 // simplified to the case that there is only a single base class. 1476 void 1477 __si_class_type_info::search_above_dst(__dynamic_cast_info* info, 1478 const void* dst_ptr, 1479 const void* current_ptr, 1480 int path_below, 1481 bool use_strcmp) const 1482 { 1483 if (is_equal(this, info->static_type, use_strcmp)) 1484 process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 1485 else 1486 __base_type->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); 1487 } 1488 1489 // This is the same algorithm as __vmi_class_type_info::search_above_dst but 1490 // simplified to the case that there is no base class. 1491 void 1492 __class_type_info::search_above_dst(__dynamic_cast_info* info, 1493 const void* dst_ptr, 1494 const void* current_ptr, 1495 int path_below, 1496 bool use_strcmp) const 1497 { 1498 if (is_equal(this, info->static_type, use_strcmp)) 1499 process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); 1500 } 1501 1502 // The search functions for __base_class_type_info are simply convenience 1503 // functions for adjusting the current_ptr and path_below as the search is 1504 // passed up to the base class node. 1505 1506 void 1507 __base_class_type_info::search_above_dst(__dynamic_cast_info* info, 1508 const void* dst_ptr, 1509 const void* current_ptr, 1510 int path_below, 1511 bool use_strcmp) const 1512 { 1513 ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; 1514 if (__offset_flags & __virtual_mask) 1515 { 1516 const char* vtable = strip_vtable(*static_cast<const char* const*>(current_ptr)); 1517 offset_to_base = update_offset_to_base(vtable, offset_to_base); 1518 } 1519 __base_type->search_above_dst(info, dst_ptr, 1520 static_cast<const char*>(current_ptr) + offset_to_base, 1521 (__offset_flags & __public_mask) ? 1522 path_below : 1523 not_public_path, 1524 use_strcmp); 1525 } 1526 1527 void 1528 __base_class_type_info::search_below_dst(__dynamic_cast_info* info, 1529 const void* current_ptr, 1530 int path_below, 1531 bool use_strcmp) const 1532 { 1533 ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; 1534 if (__offset_flags & __virtual_mask) 1535 { 1536 const char* vtable = strip_vtable(*static_cast<const char* const*>(current_ptr)); 1537 offset_to_base = update_offset_to_base(vtable, offset_to_base); 1538 } 1539 __base_type->search_below_dst(info, 1540 static_cast<const char*>(current_ptr) + offset_to_base, 1541 (__offset_flags & __public_mask) ? 1542 path_below : 1543 not_public_path, 1544 use_strcmp); 1545 } 1546 1547 } // __cxxabiv1 1548