master
   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
  60template <typename T>
  61static 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
  68static inline
  69bool
  70is_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
  80static 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
  90namespace __cxxabiv1
  91{
  92
  93namespace {
  94
  95struct 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.
 102void 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`.
 136const 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.
 214const 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
 267const 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
 335void __shim_type_info::noop1() const {}
 336void __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
 434bool
 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
 441bool
 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
 451bool
 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
 462bool
 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
 475bool
 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
 519void
 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
 545void
 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
 554void
 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
 565void
 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
 599void
 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
 625bool
 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.
 649bool
 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
 733bool __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
 768bool __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
 809bool __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
 909extern "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.
 969void
 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.
1016void
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// }
1083void
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.
1256void
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.
1333void
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// }
1402void
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.
1476void
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.
1491void
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
1506void
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
1527void
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