]>
Commit | Line | Data |
---|---|---|
fbd26352 | 1 | // Copyright (C) 1994-2019 Free Software Foundation, Inc. |
f779f82c | 2 | // |
3 | // This file is part of GCC. | |
4 | // | |
5 | // GCC is free software; you can redistribute it and/or modify | |
6 | // it under the terms of the GNU General Public License as published by | |
6bc9506f | 7 | // the Free Software Foundation; either version 3, or (at your option) |
f779f82c | 8 | // any later version. |
9 | ||
10 | // GCC is distributed in the hope that it will be useful, | |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | // GNU General Public License for more details. | |
14 | ||
6bc9506f | 15 | // Under Section 7 of GPL version 3, you are granted additional |
16 | // permissions described in the GCC Runtime Library Exception, version | |
17 | // 3.1, as published by the Free Software Foundation. | |
f779f82c | 18 | |
6bc9506f | 19 | // You should have received a copy of the GNU General Public License and |
20 | // a copy of the GCC Runtime Library Exception along with this program; | |
21 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
22 | // <http://www.gnu.org/licenses/>. | |
f779f82c | 23 | |
24 | #include "tinfo.h" | |
25 | ||
26 | namespace __cxxabiv1 { | |
27 | ||
28 | __pbase_type_info:: | |
29 | ~__pbase_type_info () | |
30 | {} | |
31 | ||
32 | bool __pbase_type_info:: | |
33 | __do_catch (const type_info *thr_type, | |
34 | void **thr_obj, | |
35 | unsigned outer) const | |
36 | { | |
37 | if (*this == *thr_type) | |
38 | return true; // same type | |
6261db62 | 39 | |
0fcfaa33 | 40 | #if __cpp_rtti |
1913be16 | 41 | if (*thr_type == typeid (nullptr)) |
42 | { | |
43 | // A catch handler for any pointer type matches nullptr_t. | |
44 | if (typeid (*this) == typeid(__pointer_type_info)) | |
45 | { | |
46 | *thr_obj = nullptr; | |
47 | return true; | |
48 | } | |
49 | else if (typeid (*this) == typeid(__pointer_to_member_type_info)) | |
50 | { | |
51 | if (__pointee->__is_function_p ()) | |
52 | { | |
8669e753 | 53 | using pmf_type = void (__pbase_type_info::*)(); |
54 | static const pmf_type pmf = nullptr; | |
55 | *thr_obj = const_cast<pmf_type*>(&pmf); | |
56 | return true; | |
1913be16 | 57 | } |
58 | else | |
59 | { | |
8669e753 | 60 | using pm_type = int __pbase_type_info::*; |
61 | static const pm_type pm = nullptr; | |
62 | *thr_obj = const_cast<pm_type*>(&pm); | |
1913be16 | 63 | return true; |
64 | } | |
65 | } | |
66 | } | |
67 | ||
f779f82c | 68 | if (typeid (*this) != typeid (*thr_type)) |
69 | return false; // not both same kind of pointers | |
6261db62 | 70 | #endif |
f779f82c | 71 | |
72 | if (!(outer & 1)) | |
73 | // We're not the same and our outer pointers are not all const qualified | |
74 | // Therefore there must at least be a qualification conversion involved | |
75 | // But for that to be valid, our outer pointers must be const qualified. | |
76 | return false; | |
77 | ||
78 | const __pbase_type_info *thrown_type = | |
79 | static_cast <const __pbase_type_info *> (thr_type); | |
6d02e6b2 | 80 | |
81 | unsigned tflags = thrown_type->__flags; | |
82 | ||
2e9e9363 | 83 | const unsigned fqual_mask = __transaction_safe_mask|__noexcept_mask; |
84 | unsigned throw_fqual = (tflags & fqual_mask); | |
85 | unsigned catch_fqual = (__flags & fqual_mask); | |
86 | if (throw_fqual & ~catch_fqual) | |
87 | /* Catch can perform a function pointer conversion. */ | |
88 | tflags &= catch_fqual; | |
89 | if (catch_fqual & ~throw_fqual) | |
6d02e6b2 | 90 | /* But not the reverse. */ |
91 | return false; | |
f779f82c | 92 | |
6d02e6b2 | 93 | if (tflags & ~__flags) |
f779f82c | 94 | // We're less qualified. |
95 | return false; | |
96 | ||
97 | if (!(__flags & __const_mask)) | |
98 | outer &= ~1; | |
99 | ||
100 | return __pointer_catch (thrown_type, thr_obj, outer); | |
101 | } | |
102 | ||
103 | } |