1 //===----------------------- private_typeinfo.cpp -------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "private_typeinfo.h"
11 
12 // The flag _LIBCXX_DYNAMIC_FALLBACK is used to make dynamic_cast more
13 // forgiving when type_info's mistakenly have hidden visibility and thus
14 // multiple type_infos can exist for a single type.
15 //
16 // When _LIBCXX_DYNAMIC_FALLBACK is defined, and only in the case where
17 // there is a detected inconsistency in the type_info hierarchy during a
18 // dynamic_cast, then the equality operation will fall back to using strcmp
19 // on type_info names to determine type_info equality.
20 //
21 // This change happens *only* under dynamic_cast, and only when
22 // dynamic_cast is faced with the choice:  abort, or possibly give back the
23 // wrong answer.  If when the dynamic_cast is done with this fallback
24 // algorithm and an inconsistency is still detected, dynamic_cast will call
25 // abort with an appropriate message.
26 //
27 // The current implementation of _LIBCXX_DYNAMIC_FALLBACK requires a
28 // printf-like function called syslog:
29 //
30 //     void syslog(const char* format, ...);
31 //
32 // If you want this functionality but your platform doesn't have syslog,
33 // just implement it in terms of fprintf(stderr, ...).
34 //
35 // _LIBCXX_DYNAMIC_FALLBACK is currently off by default.
36 
37 #if _LIBCXX_DYNAMIC_FALLBACK
38 #include "abort_message.h"
39 #include <string.h>
40 #include <sys/syslog.h>
41 #endif
42 
43 namespace __cxxabiv1
44 {
45 
46 #pragma GCC visibility push(hidden)
47 
48 #if _LIBCXX_DYNAMIC_FALLBACK
49 
50 inline
51 bool
52 is_equal(const std::type_info* x, const std::type_info* y, bool use_strcmp)
53 {
54     if (!use_strcmp)
55         return x == y;
56     return strcmp(x->name(), y->name()) == 0;
57 }
58 
59 #else  // !_LIBCXX_DYNAMIC_FALLBACK
60 
61 inline
62 bool
63 is_equal(const std::type_info* x, const std::type_info* y, bool)
64 {
65     return x == y;
66 }
67 
68 #endif  // _LIBCXX_DYNAMIC_FALLBACK
69 
70 // __shim_type_info
71 
72 __shim_type_info::~__shim_type_info()
73 {
74 }
75 
76 void __shim_type_info::noop1() const {}
77 void __shim_type_info::noop2() const {}
78 
79 // __fundamental_type_info
80 
81 // This miraculously (compiler magic) emits the type_info's for:
82 //   1. all of the fundamental types
83 //   2. pointers to all of the fundamental types
84 //   3. pointers to all of the const fundamental types
85 __fundamental_type_info::~__fundamental_type_info()
86 {
87 }
88 
89 // __array_type_info
90 
91 __array_type_info::~__array_type_info()
92 {
93 }
94 
95 // __function_type_info
96 
97 __function_type_info::~__function_type_info()
98 {
99 }
100 
101 // __enum_type_info
102 
103 __enum_type_info::~__enum_type_info()
104 {
105 }
106 
107 // __class_type_info
108 
109 __class_type_info::~__class_type_info()
110 {
111 }
112 
113 // __si_class_type_info
114 
115 __si_class_type_info::~__si_class_type_info()
116 {
117 }
118 
119 // __vmi_class_type_info
120 
121 __vmi_class_type_info::~__vmi_class_type_info()
122 {
123 }
124 
125 // __pbase_type_info
126 
127 __pbase_type_info::~__pbase_type_info()
128 {
129 }
130 
131 // __pointer_type_info
132 
133 __pointer_type_info::~__pointer_type_info()
134 {
135 }
136 
137 // __pointer_to_member_type_info
138 
139 __pointer_to_member_type_info::~__pointer_to_member_type_info()
140 {
141 }
142 
143 // can_catch
144 
145 // A handler is a match for an exception object of type E if
146 //   1. The handler is of type cv T or cv T& and E and T are the same type
147 //      (ignoring the top-level cv-qualifiers), or
148 //   2. the handler is of type cv T or cv T& and T is an unambiguous public
149 //       base class of E, or
150 //   3. the handler is of type cv1 T* cv2 and E is a pointer type that can be
151 //      converted to the type of the handler by either or both of
152 //      A. a standard pointer conversion (4.10) not involving conversions to
153 //         pointers to private or protected or ambiguous classes
154 //      B. a qualification conversion
155 //   4. the handler is a pointer or pointer to member type and E is
156 //      std::nullptr_t.
157 
158 // adjustedPtr:
159 //
160 // catch (A& a) : adjustedPtr == &a
161 // catch (A* a) : adjustedPtr == a
162 // catch (A** a) : adjustedPtr == a
163 //
164 // catch (D2& d2) : adjustedPtr == &d2  (d2 is base class of thrown object)
165 // catch (D2* d2) : adjustedPtr == d2
166 // catch (D2*& d2) : adjustedPtr == d2
167 //
168 // catch (...) : adjustedPtr == & of the exception
169 
170 // Handles bullet 1
171 bool
172 __fundamental_type_info::can_catch(const __shim_type_info* thrown_type,
173                                    void*&) const
174 {
175     return is_equal(this, thrown_type, false);
176 }
177 
178 bool
179 __array_type_info::can_catch(const __shim_type_info*, void*&) const
180 {
181     // We can get here if someone tries to catch an array by reference.
182     //   However if someone tries to throw an array, it immediately gets
183     //   converted to a pointer, which will not convert back to an array
184     //   at the catch clause.  So this can never catch anything.
185     return false;
186 }
187 
188 bool
189 __function_type_info::can_catch(const __shim_type_info*, void*&) const
190 {
191     // We can get here if someone tries to catch a function by reference.
192     //   However if someone tries to throw a function, it immediately gets
193     //   converted to a pointer, which will not convert back to a function
194     //   at the catch clause.  So this can never catch anything.
195     return false;
196 }
197 
198 // Handles bullet 1
199 bool
200 __enum_type_info::can_catch(const __shim_type_info* thrown_type,
201                             void*&) const
202 {
203     return is_equal(this, thrown_type, false);
204 }
205 
206 #pragma clang diagnostic push
207 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
208 
209 // Handles bullets 1 and 2
210 bool
211 __class_type_info::can_catch(const __shim_type_info* thrown_type,
212                              void*& adjustedPtr) const
213 {
214     // bullet 1
215     if (is_equal(this, thrown_type, false))
216         return true;
217     const __class_type_info* thrown_class_type =
218         dynamic_cast<const __class_type_info*>(thrown_type);
219     if (thrown_class_type == 0)
220         return false;
221     // bullet 2
222     __dynamic_cast_info info = {thrown_class_type, 0, this, -1, 0};
223     info.number_of_dst_type = 1;
224     thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path);
225     if (info.path_dst_ptr_to_static_ptr == public_path)
226     {
227         adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);
228         return true;
229     }
230     return false;
231 }
232 
233 #pragma clang diagnostic pop
234 
235 void
236 __class_type_info::process_found_base_class(__dynamic_cast_info* info,
237                                                void* adjustedPtr,
238                                                int path_below) const
239 {
240     if (info->dst_ptr_leading_to_static_ptr == 0)
241     {
242         // First time here
243         info->dst_ptr_leading_to_static_ptr = adjustedPtr;
244         info->path_dst_ptr_to_static_ptr = path_below;
245         info->number_to_static_ptr = 1;
246     }
247     else if (info->dst_ptr_leading_to_static_ptr == adjustedPtr)
248     {
249         // We've been here before.  Update path to "most public"
250         if (info->path_dst_ptr_to_static_ptr == not_public_path)
251             info->path_dst_ptr_to_static_ptr = path_below;
252     }
253     else
254     {
255         // We've detected an ambiguous cast from (thrown_class_type, adjustedPtr)
256         //   to a static_type
257         info->number_to_static_ptr += 1;
258         info->path_dst_ptr_to_static_ptr = not_public_path;
259         info->search_done = true;
260     }
261 }
262 
263 void
264 __class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
265                                                void* adjustedPtr,
266                                                int path_below) const
267 {
268     if (is_equal(this, info->static_type, false))
269         process_found_base_class(info, adjustedPtr, path_below);
270 }
271 
272 void
273 __si_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
274                                                   void* adjustedPtr,
275                                                   int path_below) const
276 {
277     if (is_equal(this, info->static_type, false))
278         process_found_base_class(info, adjustedPtr, path_below);
279     else
280         __base_type->has_unambiguous_public_base(info, adjustedPtr, path_below);
281 }
282 
283 void
284 __base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
285                                                     void* adjustedPtr,
286                                                     int path_below) const
287 {
288     ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;
289     if (__offset_flags & __virtual_mask)
290     {
291         const char* vtable = *static_cast<const char*const*>(adjustedPtr);
292         offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
293     }
294     __base_type->has_unambiguous_public_base(info,
295                                              static_cast<char*>(adjustedPtr) + offset_to_base,
296                                              (__offset_flags & __public_mask) ?
297                                                  path_below :
298                                                  not_public_path);
299 }
300 
301 void
302 __vmi_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
303                                                    void* adjustedPtr,
304                                                    int path_below) const
305 {
306     if (is_equal(this, info->static_type, false))
307         process_found_base_class(info, adjustedPtr, path_below);
308     else
309     {
310         typedef const __base_class_type_info* Iter;
311         const Iter e = __base_info + __base_count;
312         Iter p = __base_info;
313         p->has_unambiguous_public_base(info, adjustedPtr, path_below);
314         if (++p < e)
315         {
316             do
317             {
318                 p->has_unambiguous_public_base(info, adjustedPtr, path_below);
319                 if (info->search_done)
320                     break;
321             } while (++p < e);
322         }
323     }
324 }
325 
326 // Handles bullets 1 and 4 for both pointers and member pointers
327 bool
328 __pbase_type_info::can_catch(const __shim_type_info* thrown_type,
329                              void*&) const
330 {
331     if (is_equal(this, thrown_type, false))
332         return true;
333     return is_equal(thrown_type, &typeid(std::nullptr_t), false);
334 }
335 
336 #pragma clang diagnostic push
337 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
338 
339 // Handles bullets 1, 3 and 4
340 bool
341 __pointer_type_info::can_catch(const __shim_type_info* thrown_type,
342                                void*& adjustedPtr) const
343 {
344     // Do the dereference adjustment
345     adjustedPtr = *static_cast<void**>(adjustedPtr);
346     // bullets 1 and 4
347     if (__pbase_type_info::can_catch(thrown_type, adjustedPtr))
348         return true;
349     // bullet 3
350     const __pointer_type_info* thrown_pointer_type =
351         dynamic_cast<const __pointer_type_info*>(thrown_type);
352     if (thrown_pointer_type == 0)
353         return false;
354     // bullet 3B
355     if (thrown_pointer_type->__flags & ~__flags)
356         return false;
357     if (is_equal(__pointee, thrown_pointer_type->__pointee, false))
358         return true;
359     // bullet 3A
360     if (is_equal(__pointee, &typeid(void), false))
361         return true;
362     const __class_type_info* catch_class_type =
363         dynamic_cast<const __class_type_info*>(__pointee);
364     if (catch_class_type == 0)
365         return false;
366     const __class_type_info* thrown_class_type =
367         dynamic_cast<const __class_type_info*>(thrown_pointer_type->__pointee);
368     if (thrown_class_type == 0)
369         return false;
370     __dynamic_cast_info info = {thrown_class_type, 0, catch_class_type, -1, 0};
371     info.number_of_dst_type = 1;
372     thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path);
373     if (info.path_dst_ptr_to_static_ptr == public_path)
374     {
375         adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);
376         return true;
377     }
378     return false;
379 }
380 
381 #pragma clang diagnostic pop
382 
383 #pragma GCC visibility pop
384 #pragma GCC visibility push(default)
385 
386 #pragma clang diagnostic push
387 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
388 
389 // __dynamic_cast
390 
391 // static_ptr: pointer to an object of type static_type; nonnull, and since the
392 //   object is polymorphic, *(void**)static_ptr is a virtual table pointer.
393 //   static_ptr is &v in the expression dynamic_cast<T>(v).
394 // static_type: static type of the object pointed to by static_ptr.
395 // dst_type: destination type of the cast (the "T" in "dynamic_cast<T>(v)").
396 // src2dst_offset: a static hint about the location of the
397 //                 source subobject with respect to the complete object;
398 //                 special negative values are:
399 //                     -1: no hint
400 //                     -2: static_type is not a public base of dst_type
401 //                     -3: static_type is a multiple public base type but never a
402 //                         virtual base type
403 //                 otherwise, the static_type type is a unique public nonvirtual
404 //                 base type of dst_type at offset src2dst_offset from the
405 //                 origin of dst_type.
406 //
407 // (dynamic_ptr, dynamic_type) are the run time type of the complete object
408 // referred to by static_ptr and a pointer to it.  These can be found from
409 // static_ptr for polymorphic types.
410 // static_type is guaranteed to be a polymorphic type.
411 //
412 // (dynamic_ptr, dynamic_type) is the root of a DAG that grows upward.  Each
413 // node of the tree represents a base class/object of its parent (or parents) below.
414 // Each node is uniquely represented by a pointer to the object, and a pointer
415 // to a type_info - its type.  Different nodes may have the same pointer and
416 // different nodes may have the same type.  But only one node has a specific
417 // (pointer-value, type) pair.  In C++ two objects of the same type can not
418 // share the same address.
419 //
420 // There are two flavors of nodes which have the type dst_type:
421 //    1.  Those that are derived from (below) (static_ptr, static_type).
422 //    2.  Those that are not derived from (below) (static_ptr, static_type).
423 //
424 // Invariants of the DAG:
425 //
426 // There is at least one path from the root (dynamic_ptr, dynamic_type) to
427 // the node (static_ptr, static_type).  This path may or may not be public.
428 // There may be more than one such path (some public some not).  Such a path may
429 // or may not go through a node having type dst_type.
430 //
431 // No node of type T appears above a node of the same type.  That means that
432 // there is only one node with dynamic_type.  And if dynamic_type == dst_type,
433 // then there is only one dst_type in the DAG.
434 //
435 // No node of type dst_type appears above a node of type static_type.  Such
436 // DAG's are possible in C++, but the compiler computes those dynamic_casts at
437 // compile time, and only calls __dynamic_cast when dst_type lies below
438 // static_type in the DAG.
439 //
440 // dst_type != static_type:  The compiler computes the dynamic_cast in this case too.
441 // dynamic_type != static_type:  The compiler computes the dynamic_cast in this case too.
442 //
443 // Returns:
444 //
445 // If there is exactly one dst_type of flavor 1, and
446 //    If there is a public path from that dst_type to (static_ptr, static_type), or
447 //    If there are 0 dst_types of flavor 2, and there is a public path from
448 //        (dynamic_ptr, dynamic_type) to (static_ptr, static_type) and a public
449 //        path from (dynamic_ptr, dynamic_type) to the one dst_type, then return
450 //        a pointer to that dst_type.
451 // Else if there are 0 dst_types of flavor 1 and exactly 1 dst_type of flavor 2, and
452 //    if there is a public path from (dynamic_ptr, dynamic_type) to
453 //    (static_ptr, static_type) and a public path from (dynamic_ptr, dynamic_type)
454 //    to the one dst_type, then return a pointer to that one dst_type.
455 // Else return nullptr.
456 //
457 // If dynamic_type == dst_type, then the above algorithm collapses to the
458 // following cheaper algorithm:
459 //
460 // If there is a public path from (dynamic_ptr, dynamic_type) to
461 //    (static_ptr, static_type), then return dynamic_ptr.
462 // Else return nullptr.
463 extern "C"
464 void*
465 __dynamic_cast(const void* static_ptr,
466                const __class_type_info* static_type,
467                const __class_type_info* dst_type,
468                std::ptrdiff_t src2dst_offset)
469 {
470     // Possible future optimization:  Take advantage of src2dst_offset
471     // Currently clang always sets src2dst_offset to -1 (no hint).
472 
473     // Get (dynamic_ptr, dynamic_type) from static_ptr
474     void** vtable = *(void***)static_ptr;
475     ptrdiff_t offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]);
476     const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived;
477     const __class_type_info* dynamic_type = static_cast<const __class_type_info*>(vtable[-1]);
478 
479     // Initialize answer to nullptr.  This will be changed from the search
480     //    results if a non-null answer is found.  Regardless, this is what will
481     //    be returned.
482     const void* dst_ptr = 0;
483     // Initialize info struct for this search.
484     __dynamic_cast_info info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
485 
486     // Find out if we can use a giant short cut in the search
487     if (is_equal(dynamic_type, dst_type, false))
488     {
489         // Using giant short cut.  Add that information to info.
490         info.number_of_dst_type = 1;
491         // Do the  search
492         dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false);
493 #if _LIBCXX_DYNAMIC_FALLBACK
494         // The following if should always be false because we should definitely
495         //   find (static_ptr, static_type), either on a public or private path
496         if (info.path_dst_ptr_to_static_ptr == unknown)
497         {
498             // We get here only if there is some kind of visibility problem
499             //   in client code.
500             syslog(LOG_ERR, "dynamic_cast error 1: Both of the following type_info's "
501                     "should have public visibility.  At least of of them is hidden. %s"
502                     ", %s.\n", static_type->name(), dynamic_type->name());
503             // Redo the search comparing type_info's using strcmp
504             info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
505             info.number_of_dst_type = 1;
506             dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true);
507         }
508 #endif  // _LIBCXX_DYNAMIC_FALLBACK
509         // Query the search.
510         if (info.path_dst_ptr_to_static_ptr == public_path)
511             dst_ptr = dynamic_ptr;
512     }
513     else
514     {
515         // Not using giant short cut.  Do the search
516         dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false);
517  #if _LIBCXX_DYNAMIC_FALLBACK
518         // The following if should always be false because we should definitely
519         //   find (static_ptr, static_type), either on a public or private path
520         if (info.path_dst_ptr_to_static_ptr == unknown &&
521             info.path_dynamic_ptr_to_static_ptr == unknown)
522         {
523             syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's "
524                             " has hidden visibility.  They should all have public visibility.  "
525                             " %s, %s, %s.\n", static_type->name(), dynamic_type->name(),
526                     dst_type->name());
527             // Redo the search comparing type_info's using strcmp
528             info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
529             dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true);
530         }
531 #endif  // _LIBCXX_DYNAMIC_FALLBACK
532         // Query the search.
533         switch (info.number_to_static_ptr)
534         {
535         case 0:
536             if (info.number_to_dst_ptr == 1 &&
537                     info.path_dynamic_ptr_to_static_ptr == public_path &&
538                     info.path_dynamic_ptr_to_dst_ptr == public_path)
539                 dst_ptr = info.dst_ptr_not_leading_to_static_ptr;
540             break;
541         case 1:
542             if (info.path_dst_ptr_to_static_ptr == public_path ||
543                    (
544                        info.number_to_dst_ptr == 0 &&
545                        info.path_dynamic_ptr_to_static_ptr == public_path &&
546                        info.path_dynamic_ptr_to_dst_ptr == public_path
547                    )
548                )
549                 dst_ptr = info.dst_ptr_leading_to_static_ptr;
550             break;
551         }
552     }
553     return const_cast<void*>(dst_ptr);
554 }
555 
556 #pragma clang diagnostic pop
557 
558 #pragma GCC visibility pop
559 #pragma GCC visibility push(hidden)
560 
561 // Call this function when you hit a static_type which is a base (above) a dst_type.
562 // Let caller know you hit a static_type.  But only start recording details if
563 // this is (static_ptr, static_type) -- the node we are casting from.
564 // If this is (static_ptr, static_type)
565 //   Record the path (public or not) from the dst_type to here.  There may be
566 //   multiple paths from the same dst_type to here, record the "most public" one.
567 //   Record the dst_ptr as pointing to (static_ptr, static_type).
568 //   If more than one (dst_ptr, dst_type) points to (static_ptr, static_type),
569 //   then mark this dyanmic_cast as ambiguous and stop the search.
570 void
571 __class_type_info::process_static_type_above_dst(__dynamic_cast_info* info,
572                                                  const void* dst_ptr,
573                                                  const void* current_ptr,
574                                                  int path_below) const
575 {
576     // Record that we found a static_type
577     info->found_any_static_type = true;
578     if (current_ptr == info->static_ptr)
579     {
580         // Record that we found (static_ptr, static_type)
581         info->found_our_static_ptr = true;
582         if (info->dst_ptr_leading_to_static_ptr == 0)
583         {
584             // First time here
585             info->dst_ptr_leading_to_static_ptr = dst_ptr;
586             info->path_dst_ptr_to_static_ptr = path_below;
587             info->number_to_static_ptr = 1;
588             // If there is only one dst_type in the entire tree and the path from
589             //    there to here is public then we are done!
590             if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path)
591                 info->search_done = true;
592         }
593         else if (info->dst_ptr_leading_to_static_ptr == dst_ptr)
594         {
595             // We've been here before.  Update path to "most public"
596             if (info->path_dst_ptr_to_static_ptr == not_public_path)
597                 info->path_dst_ptr_to_static_ptr = path_below;
598             // If there is only one dst_type in the entire tree and the path from
599             //    there to here is public then we are done!
600             if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path)
601                 info->search_done = true;
602         }
603         else
604         {
605             // We've detected an ambiguous cast from (static_ptr, static_type)
606             //   to a dst_type
607             info->number_to_static_ptr += 1;
608             info->search_done = true;
609         }
610     }
611 }
612 
613 // Call this function when you hit a static_type which is not a base (above) a dst_type.
614 // If this is (static_ptr, static_type)
615 //   Record the path (public or not) from (dynamic_ptr, dynamic_type) to here.  There may be
616 //   multiple paths from (dynamic_ptr, dynamic_type) to here, record the "most public" one.
617 void
618 __class_type_info::process_static_type_below_dst(__dynamic_cast_info* info,
619                                                  const void* current_ptr,
620                                                  int path_below) const
621 {
622     if (current_ptr == info->static_ptr)
623     {
624         // Record the most public path from (dynamic_ptr, dynamic_type) to
625         //                                  (static_ptr, static_type)
626         if (info->path_dynamic_ptr_to_static_ptr != public_path)
627             info->path_dynamic_ptr_to_static_ptr = path_below;
628     }
629 }
630 
631 // Call this function when searching below a dst_type node.  This function searches
632 // for a path to (static_ptr, static_type) and for paths to one or more dst_type nodes.
633 // If it finds a static_type node, there is no need to further search base classes
634 // above.
635 // If it finds a dst_type node it should search base classes using search_above_dst
636 // to find out if this dst_type points to (static_ptr, static_type) or not.
637 // Either way, the dst_type is recorded as one of two "flavors":  one that does
638 // or does not point to (static_ptr, static_type).
639 // If this is neither a static_type nor a dst_type node, continue searching
640 // base classes above.
641 // All the hoopla surrounding the search code is doing nothing but looking for
642 // excuses to stop the search prematurely (break out of the for-loop).  That is,
643 // the algorithm below is simply an optimization of this:
644 // void
645 // __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info,
646 //                                         const void* current_ptr,
647 //                                         int path_below) const
648 // {
649 //     typedef const __base_class_type_info* Iter;
650 //     if (this == info->static_type)
651 //         process_static_type_below_dst(info, current_ptr, path_below);
652 //     else if (this == info->dst_type)
653 //     {
654 //         // Record the most public access path that got us here
655 //         if (info->path_dynamic_ptr_to_dst_ptr != public_path)
656 //             info->path_dynamic_ptr_to_dst_ptr = path_below;
657 //         bool does_dst_type_point_to_our_static_type = false;
658 //         for (Iter p = __base_info, e= __base_info + __base_count; p < e; ++p)
659 //         {
660 //             p->search_above_dst(info, current_ptr, current_ptr, public_path);
661 //             if (info->found_our_static_ptr)
662 //                 does_dst_type_point_to_our_static_type = true;
663 //             // break out early here if you can detect it doesn't matter if you do
664 //         }
665 //         if (!does_dst_type_point_to_our_static_type)
666 //         {
667 //             // We found a dst_type that doesn't point to (static_ptr, static_type)
668 //             // So record the address of this dst_ptr and increment the
669 //             // count of the number of such dst_types found in the tree.
670 //             info->dst_ptr_not_leading_to_static_ptr = current_ptr;
671 //             info->number_to_dst_ptr += 1;
672 //         }
673 //     }
674 //     else
675 //     {
676 //         // This is not a static_type and not a dst_type.
677 //         for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p)
678 //         {
679 //             p->search_below_dst(info, current_ptr, public_path);
680 //             // break out early here if you can detect it doesn't matter if you do
681 //         }
682 //     }
683 // }
684 void
685 __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info,
686                                         const void* current_ptr,
687                                         int path_below,
688                                         bool use_strcmp) const
689 {
690     typedef const __base_class_type_info* Iter;
691     if (is_equal(this, info->static_type, use_strcmp))
692         process_static_type_below_dst(info, current_ptr, path_below);
693     else if (is_equal(this, info->dst_type, use_strcmp))
694     {
695         // We've been here before if we've recorded current_ptr in one of these
696         //   two places:
697         if (current_ptr == info->dst_ptr_leading_to_static_ptr ||
698             current_ptr == info->dst_ptr_not_leading_to_static_ptr)
699         {
700             // We've seen this node before, and therefore have already searched
701             // its base classes above.
702             //  Update path to here that is "most public".
703             if (path_below == public_path)
704                 info->path_dynamic_ptr_to_dst_ptr = public_path;
705         }
706         else  // We have haven't been here before
707         {
708             // Record the access path that got us here
709             //   If there is more than one dst_type this path doesn't matter.
710             info->path_dynamic_ptr_to_dst_ptr = path_below;
711             // Only search above here if dst_type derives from static_type, or
712             //    if it is unknown if dst_type derives from static_type.
713             if (info->is_dst_type_derived_from_static_type != no)
714             {
715                 // Set up flags to record results from all base classes
716                 bool is_dst_type_derived_from_static_type = false;
717                 bool does_dst_type_point_to_our_static_type = false;
718                 // We've found a dst_type with a potentially public path to here.
719                 // We have to assume the path is public because it may become
720                 //   public later (if we get back to here with a public path).
721                 // We can stop looking above if:
722                 //    1.  We've found a public path to (static_ptr, static_type).
723                 //    2.  We've found an ambiguous cast from (static_ptr, static_type) to a dst_type.
724                 //        This is detected at the (static_ptr, static_type).
725                 //    3.  We can prove that there is no public path to (static_ptr, static_type)
726                 //        above here.
727                 const Iter e = __base_info + __base_count;
728                 for (Iter p = __base_info; p < e; ++p)
729                 {
730                     // Zero out found flags
731                     info->found_our_static_ptr = false;
732                     info->found_any_static_type = false;
733                     p->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp);
734                     if (info->search_done)
735                         break;
736                     if (info->found_any_static_type)
737                     {
738                         is_dst_type_derived_from_static_type = true;
739                         if (info->found_our_static_ptr)
740                         {
741                             does_dst_type_point_to_our_static_type = true;
742                             // If we found what we're looking for, stop looking above.
743                             if (info->path_dst_ptr_to_static_ptr == public_path)
744                                 break;
745                             // We found a private path to (static_ptr, static_type)
746                             //   If there is no diamond then there is only one path
747                             //   to (static_ptr, static_type) and we just found it.
748                             if (!(__flags & __diamond_shaped_mask))
749                                 break;
750                         }
751                         else
752                         {
753                             // If we found a static_type that isn't the one we're looking
754                             //    for, and if there are no repeated types above here,
755                             //    then stop looking.
756                             if (!(__flags & __non_diamond_repeat_mask))
757                                 break;
758                         }
759                     }
760                 }
761                 if (!does_dst_type_point_to_our_static_type)
762                 {
763                     // We found a dst_type that doesn't point to (static_ptr, static_type)
764                     // So record the address of this dst_ptr and increment the
765                     // count of the number of such dst_types found in the tree.
766                     info->dst_ptr_not_leading_to_static_ptr = current_ptr;
767                     info->number_to_dst_ptr += 1;
768                     // If there exists another dst with a private path to
769                     //    (static_ptr, static_type), then the cast from
770                     //     (dynamic_ptr, dynamic_type) to dst_type is now ambiguous,
771                     //      so stop search.
772                     if (info->number_to_static_ptr == 1 &&
773                             info->path_dst_ptr_to_static_ptr == not_public_path)
774                         info->search_done = true;
775                 }
776                 // If we found no static_type,s then dst_type doesn't derive
777                 //   from static_type, else it does.  Record this result so that
778                 //   next time we hit a dst_type we will know not to search above
779                 //   it if it doesn't derive from static_type.
780                 if (is_dst_type_derived_from_static_type)
781                     info->is_dst_type_derived_from_static_type = yes;
782                 else
783                     info->is_dst_type_derived_from_static_type = no;
784             }
785         }
786     }
787     else
788     {
789         // This is not a static_type and not a dst_type.
790         const Iter e = __base_info + __base_count;
791         Iter p = __base_info;
792         p->search_below_dst(info, current_ptr, path_below, use_strcmp);
793         if (++p < e)
794         {
795             if ((__flags & __diamond_shaped_mask) || info->number_to_static_ptr == 1)
796             {
797                 // If there are multiple paths to a base above from here, or if
798                 //    a dst_type pointing to (static_ptr, static_type) has been found,
799                 //    then there is no way to break out of this loop early unless
800                 //    something below detects the search is done.
801                 do
802                 {
803                     if (info->search_done)
804                         break;
805                     p->search_below_dst(info, current_ptr, path_below, use_strcmp);
806                 } while (++p < e);
807             }
808             else if (__flags & __non_diamond_repeat_mask)
809             {
810                 // There are not multiple paths to any base class from here and a
811                 //   dst_type pointing to (static_ptr, static_type) has not yet been
812                 //   found.
813                 do
814                 {
815                     if (info->search_done)
816                         break;
817                     // If we just found a dst_type with a public path to (static_ptr, static_type),
818                     //    then the only reason to continue the search is to make sure
819                     //    no other dst_type points to (static_ptr, static_type).
820                     //    If !diamond, then we don't need to search here.
821                     if (info->number_to_static_ptr == 1 &&
822                               info->path_dst_ptr_to_static_ptr == public_path)
823                         break;
824                     p->search_below_dst(info, current_ptr, path_below, use_strcmp);
825                 } while (++p < e);
826             }
827             else
828             {
829                 // There are no repeated types above this node.
830                 // There are no nodes with multiple parents above this node.
831                 // no dst_type has been found to (static_ptr, static_type)
832                 do
833                 {
834                     if (info->search_done)
835                         break;
836                     // If we just found a dst_type with a public path to (static_ptr, static_type),
837                     //    then the only reason to continue the search is to make sure sure
838                     //    no other dst_type points to (static_ptr, static_type).
839                     //    If !diamond, then we don't need to search here.
840                     // if we just found a dst_type with a private path to (static_ptr, static_type),
841                     //    then we're only looking for a public path to (static_ptr, static_type)
842                     //    and to check for other dst_types.
843                     //    If !diamond & !repeat, then there is not a pointer to (static_ptr, static_type)
844                     //    and not a dst_type under here.
845                     if (info->number_to_static_ptr == 1)
846                         break;
847                     p->search_below_dst(info, current_ptr, path_below, use_strcmp);
848                 } while (++p < e);
849             }
850         }
851     }
852 }
853 
854 // This is the same algorithm as __vmi_class_type_info::search_below_dst but
855 //   simplified to the case that there is only a single base class.
856 void
857 __si_class_type_info::search_below_dst(__dynamic_cast_info* info,
858                                        const void* current_ptr,
859                                        int path_below,
860                                        bool use_strcmp) const
861 {
862     if (is_equal(this, info->static_type, use_strcmp))
863         process_static_type_below_dst(info, current_ptr, path_below);
864     else if (is_equal(this, info->dst_type, use_strcmp))
865     {
866         // We've been here before if we've recorded current_ptr in one of these
867         //   two places:
868         if (current_ptr == info->dst_ptr_leading_to_static_ptr ||
869             current_ptr == info->dst_ptr_not_leading_to_static_ptr)
870         {
871             // We've seen this node before, and therefore have already searched
872             // its base classes above.
873             //  Update path to here that is "most public".
874             if (path_below == public_path)
875                 info->path_dynamic_ptr_to_dst_ptr = public_path;
876         }
877         else  // We have haven't been here before
878         {
879             // Record the access path that got us here
880             //   If there is more than one dst_type this path doesn't matter.
881             info->path_dynamic_ptr_to_dst_ptr = path_below;
882             // Only search above here if dst_type derives from static_type, or
883             //    if it is unknown if dst_type derives from static_type.
884             if (info->is_dst_type_derived_from_static_type != no)
885             {
886                 // Set up flags to record results from all base classes
887                 bool is_dst_type_derived_from_static_type = false;
888                 bool does_dst_type_point_to_our_static_type = false;
889                 // Zero out found flags
890                 info->found_our_static_ptr = false;
891                 info->found_any_static_type = false;
892                 __base_type->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp);
893                 if (info->found_any_static_type)
894                 {
895                     is_dst_type_derived_from_static_type = true;
896                     if (info->found_our_static_ptr)
897                         does_dst_type_point_to_our_static_type = true;
898                 }
899                 if (!does_dst_type_point_to_our_static_type)
900                 {
901                     // We found a dst_type that doesn't point to (static_ptr, static_type)
902                     // So record the address of this dst_ptr and increment the
903                     // count of the number of such dst_types found in the tree.
904                     info->dst_ptr_not_leading_to_static_ptr = current_ptr;
905                     info->number_to_dst_ptr += 1;
906                     // If there exists another dst with a private path to
907                     //    (static_ptr, static_type), then the cast from
908                     //     (dynamic_ptr, dynamic_type) to dst_type is now ambiguous.
909                     if (info->number_to_static_ptr == 1 &&
910                             info->path_dst_ptr_to_static_ptr == not_public_path)
911                         info->search_done = true;
912                 }
913                 // If we found no static_type,s then dst_type doesn't derive
914                 //   from static_type, else it does.  Record this result so that
915                 //   next time we hit a dst_type we will know not to search above
916                 //   it if it doesn't derive from static_type.
917                 if (is_dst_type_derived_from_static_type)
918                     info->is_dst_type_derived_from_static_type = yes;
919                 else
920                     info->is_dst_type_derived_from_static_type = no;
921             }
922         }
923     }
924     else
925     {
926         // This is not a static_type and not a dst_type
927         __base_type->search_below_dst(info, current_ptr, path_below, use_strcmp);
928     }
929 }
930 
931 // This is the same algorithm as __vmi_class_type_info::search_below_dst but
932 //   simplified to the case that there is no base class.
933 void
934 __class_type_info::search_below_dst(__dynamic_cast_info* info,
935                                     const void* current_ptr,
936                                     int path_below,
937                                     bool use_strcmp) const
938 {
939     typedef const __base_class_type_info* Iter;
940     if (is_equal(this, info->static_type, use_strcmp))
941         process_static_type_below_dst(info, current_ptr, path_below);
942     else if (is_equal(this, info->dst_type, use_strcmp))
943     {
944         // We've been here before if we've recorded current_ptr in one of these
945         //   two places:
946         if (current_ptr == info->dst_ptr_leading_to_static_ptr ||
947             current_ptr == info->dst_ptr_not_leading_to_static_ptr)
948         {
949             // We've seen this node before, and therefore have already searched
950             // its base classes above.
951             //  Update path to here that is "most public".
952             if (path_below == public_path)
953                 info->path_dynamic_ptr_to_dst_ptr = public_path;
954         }
955         else  // We have haven't been here before
956         {
957             // Record the access path that got us here
958             //   If there is more than one dst_type this path doesn't matter.
959             info->path_dynamic_ptr_to_dst_ptr = path_below;
960             // We found a dst_type that doesn't point to (static_ptr, static_type)
961             // So record the address of this dst_ptr and increment the
962             // count of the number of such dst_types found in the tree.
963             info->dst_ptr_not_leading_to_static_ptr = current_ptr;
964             info->number_to_dst_ptr += 1;
965             // If there exists another dst with a private path to
966             //    (static_ptr, static_type), then the cast from
967             //     (dynamic_ptr, dynamic_type) to dst_type is now ambiguous.
968             if (info->number_to_static_ptr == 1 &&
969                     info->path_dst_ptr_to_static_ptr == not_public_path)
970                 info->search_done = true;
971             // We found that dst_type does not derive from static_type
972             info->is_dst_type_derived_from_static_type = no;
973         }
974     }
975 }
976 
977 // Call this function when searching above a dst_type node.  This function searches
978 // for a public path to (static_ptr, static_type).
979 // This function is guaranteed not to find a node of type dst_type.
980 // Theoretically this is a very simple function which just stops if it finds a
981 // static_type node:  All the hoopla surrounding the search code is doing
982 // nothing but looking for excuses to stop the search prematurely (break out of
983 // the for-loop).  That is, the algorithm below is simply an optimization of this:
984 // void
985 // __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info,
986 //                                         const void* dst_ptr,
987 //                                         const void* current_ptr,
988 //                                         int path_below) const
989 // {
990 //     if (this == info->static_type)
991 //         process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
992 //     else
993 //     {
994 //         typedef const __base_class_type_info* Iter;
995 //         // This is not a static_type and not a dst_type
996 //         for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p)
997 //         {
998 //             p->search_above_dst(info, dst_ptr, current_ptr, public_path);
999 //             // break out early here if you can detect it doesn't matter if you do
1000 //         }
1001 //     }
1002 // }
1003 void
1004 __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info,
1005                                         const void* dst_ptr,
1006                                         const void* current_ptr,
1007                                         int path_below,
1008                                         bool use_strcmp) const
1009 {
1010     if (is_equal(this, info->static_type, use_strcmp))
1011         process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
1012     else
1013     {
1014         typedef const __base_class_type_info* Iter;
1015         // This is not a static_type and not a dst_type
1016         // Save flags so they can be restored when returning to nodes below.
1017         bool found_our_static_ptr = info->found_our_static_ptr;
1018         bool found_any_static_type = info->found_any_static_type;
1019         // We've found a dst_type below with a path to here.  If the path
1020         //    to here is not public, there may be another path to here that
1021         //    is public.  So we have to assume that the path to here is public.
1022         //  We can stop looking above if:
1023         //    1.  We've found a public path to (static_ptr, static_type).
1024         //    2.  We've found an ambiguous cast from (static_ptr, static_type) to a dst_type.
1025         //        This is detected at the (static_ptr, static_type).
1026         //    3.  We can prove that there is no public path to (static_ptr, static_type)
1027         //        above here.
1028         const Iter e = __base_info + __base_count;
1029         Iter p = __base_info;
1030         // Zero out found flags
1031         info->found_our_static_ptr = false;
1032         info->found_any_static_type = false;
1033         p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp);
1034         if (++p < e)
1035         {
1036             do
1037             {
1038                 if (info->search_done)
1039                     break;
1040                 if (info->found_our_static_ptr)
1041                 {
1042                     // If we found what we're looking for, stop looking above.
1043                     if (info->path_dst_ptr_to_static_ptr == public_path)
1044                         break;
1045                     // We found a private path to (static_ptr, static_type)
1046                     //   If there is no diamond then there is only one path
1047                     //   to (static_ptr, static_type) from here and we just found it.
1048                     if (!(__flags & __diamond_shaped_mask))
1049                         break;
1050                 }
1051                 else if (info->found_any_static_type)
1052                 {
1053                     // If we found a static_type that isn't the one we're looking
1054                     //    for, and if there are no repeated types above here,
1055                     //    then stop looking.
1056                     if (!(__flags & __non_diamond_repeat_mask))
1057                         break;
1058                 }
1059                 // Zero out found flags
1060                 info->found_our_static_ptr = false;
1061                 info->found_any_static_type = false;
1062                 p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp);
1063             } while (++p < e);
1064         }
1065         // Restore flags
1066         info->found_our_static_ptr = found_our_static_ptr;
1067         info->found_any_static_type = found_any_static_type;
1068     }
1069 }
1070 
1071 // This is the same algorithm as __vmi_class_type_info::search_above_dst but
1072 //   simplified to the case that there is only a single base class.
1073 void
1074 __si_class_type_info::search_above_dst(__dynamic_cast_info* info,
1075                                        const void* dst_ptr,
1076                                        const void* current_ptr,
1077                                        int path_below,
1078                                        bool use_strcmp) const
1079 {
1080     if (is_equal(this, info->static_type, use_strcmp))
1081         process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
1082     else
1083         __base_type->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp);
1084 }
1085 
1086 // This is the same algorithm as __vmi_class_type_info::search_above_dst but
1087 //   simplified to the case that there is no base class.
1088 void
1089 __class_type_info::search_above_dst(__dynamic_cast_info* info,
1090                                     const void* dst_ptr,
1091                                     const void* current_ptr,
1092                                     int path_below,
1093                                     bool use_strcmp) const
1094 {
1095     if (is_equal(this, info->static_type, use_strcmp))
1096         process_static_type_above_dst(info, dst_ptr, current_ptr, path_below);
1097 }
1098 
1099 // The search functions for __base_class_type_info are simply convenience
1100 //   functions for adjusting the current_ptr and path_below as the search is
1101 //   passed up to the base class node.
1102 
1103 void
1104 __base_class_type_info::search_above_dst(__dynamic_cast_info* info,
1105                                          const void* dst_ptr,
1106                                          const void* current_ptr,
1107                                          int path_below,
1108                                          bool use_strcmp) const
1109 {
1110     ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;
1111     if (__offset_flags & __virtual_mask)
1112     {
1113         const char* vtable = *static_cast<const char*const*>(current_ptr);
1114         offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
1115     }
1116     __base_type->search_above_dst(info, dst_ptr,
1117                                   static_cast<const char*>(current_ptr) + offset_to_base,
1118                                   (__offset_flags & __public_mask) ?
1119                                       path_below :
1120                                       not_public_path,
1121                                   use_strcmp);
1122 }
1123 
1124 void
1125 __base_class_type_info::search_below_dst(__dynamic_cast_info* info,
1126                                          const void* current_ptr,
1127                                          int path_below,
1128                                          bool use_strcmp) const
1129 {
1130     ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;
1131     if (__offset_flags & __virtual_mask)
1132     {
1133         const char* vtable = *static_cast<const char*const*>(current_ptr);
1134         offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
1135     }
1136     __base_type->search_below_dst(info,
1137                                   static_cast<const char*>(current_ptr) + offset_to_base,
1138                                   (__offset_flags & __public_mask) ?
1139                                       path_below :
1140                                       not_public_path,
1141                                   use_strcmp);
1142 }
1143 
1144 #pragma GCC visibility pop
1145 
1146 }  // __cxxabiv1
1147