@@ -125,7 +125,7 @@ public:
125
125
// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 1)
126
126
// ------------------------------------------------------------------------- //
127
127
// This implementation of type_info assumes a unique copy of the RTTI for a
128
- // given type inside a program. This is a valid assumption when abiding to
128
+ // given type inside a program. This is a valid assumption when abiding to the
129
129
// Itanium ABI (http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-components).
130
130
// Under this assumption, we can always compare the addresses of the type names
131
131
// to implement equality-comparison of type_infos instead of having to perform
@@ -144,22 +144,29 @@ public:
144
144
// NonUniqueARMRTTIBit
145
145
// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 3)
146
146
// -------------------------------------------------------------------------- //
147
+ // This implementation is specific to ARM64 on Apple platforms.
148
+ //
147
149
// This implementation of type_info does not assume always a unique copy of
148
- // the RTTI for a given type inside a program. It packs the pointer to the
149
- // type name into a uintptr_t and reserves the high bit of that pointer (which
150
- // is assumed to be free for use under the ABI in use) to represent whether
151
- // that specific copy of the RTTI can be assumed unique inside the program.
152
- // To implement equality-comparison of type_infos, we check whether BOTH
153
- // type_infos are guaranteed unique, and if so, we simply compare the addresses
154
- // of their type names instead of doing a deep string comparison, which is
155
- // faster. If at least one of the type_infos can't guarantee uniqueness, we
156
- // have no choice but to fall back to a deep string comparison.
150
+ // the RTTI for a given type inside a program. When constructing the type_info,
151
+ // the compiler packs the pointer to the type name into a uintptr_t and reserves
152
+ // the high bit of that pointer, which is assumed to be free for use under that
153
+ // ABI. If that high bit is set, that specific copy of the RTTI can't be assumed
154
+ // to be unique within the program. If the high bit is unset, then the RTTI can
155
+ // be assumed to be unique within the program.
157
156
//
158
- // This implementation is specific to ARM64 on Apple platforms.
157
+ // When comparing type_infos, if both RTTIs can be assumed to be unique, it
158
+ // suffices to compare their addresses. If both the RTTIs can't be assumed to
159
+ // be unique, we must perform a deep string comparison of the type names.
160
+ // However, if one of the RTTIs is guaranteed unique and the other one isn't,
161
+ // then both RTTIs are necessarily not to be considered equal.
159
162
//
160
- // Note that the compiler is the one setting (or unsetting) the high bit of
161
- // the pointer when it constructs the type_info, depending on whether it can
162
- // guarantee uniqueness for that specific type_info.
163
+ // The intent of this design is to remove the need for weak symbols. Specifically,
164
+ // if a type would normally have a default-visibility RTTI emitted as a weak
165
+ // symbol, it is given hidden visibility instead and the non-unique bit is set.
166
+ // Otherwise, types declared with hidden visibility are always considered to have
167
+ // a unique RTTI: the RTTI is emitted with linkonce_odr linkage and is assumed
168
+ // to be deduplicated by the linker within the linked image. Across linked image
169
+ // boundaries, such types are thus considered different types.
163
170
164
171
// This value can be overriden in the __config_site. When it's not overriden,
165
172
// we pick a default implementation based on the platform here.
@@ -248,13 +255,15 @@ struct __type_info_implementations {
248
255
static bool __eq (__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
249
256
if (__lhs == __rhs)
250
257
return true ;
251
- if (__is_type_name_unique (__lhs, __rhs))
258
+ if (__is_type_name_unique (__lhs) || __is_type_name_unique (__rhs))
259
+ // Either both are unique and have a different address, or one of them
260
+ // is unique and the other one isn't. In both cases they are unequal.
252
261
return false ;
253
262
return __builtin_strcmp (__type_name_to_string (__lhs), __type_name_to_string (__rhs)) == 0 ;
254
263
}
255
264
_LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
256
265
static bool __lt (__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
257
- if (__is_type_name_unique (__lhs, __rhs))
266
+ if (__is_type_name_unique (__lhs) || __is_type_name_unique ( __rhs))
258
267
return __lhs < __rhs;
259
268
return __builtin_strcmp (__type_name_to_string (__lhs), __type_name_to_string (__rhs)) < 0 ;
260
269
}
@@ -269,10 +278,6 @@ struct __type_info_implementations {
269
278
static bool __is_type_name_unique (__type_name_t __lhs) _NOEXCEPT {
270
279
return !(__lhs & __non_unique_rtti_bit::value);
271
280
}
272
- _LIBCPP_INLINE_VISIBILITY
273
- static bool __is_type_name_unique (__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT {
274
- return !((__lhs & __rhs) & __non_unique_rtti_bit::value);
275
- }
276
281
};
277
282
278
283
typedef
0 commit comments