> On Oct 4, 2016, at 3:19 PM, Richard Smith <[email protected]> wrote: > On 4 October 2016 at 14:54, John McCall <[email protected] > <mailto:[email protected]>> wrote: > >> On Oct 4, 2016, at 2:11 PM, Richard Smith <[email protected] >> <mailto:[email protected]>> wrote: >> >> On 4 October 2016 at 13:22, John McCall <[email protected] >> <mailto:[email protected]>> wrote: >> > On Oct 4, 2016, at 4:25 AM, David Vandevoorde <[email protected] >> > <mailto:[email protected]>> wrote: >> > Shouldn't the ABI document specify how type_info entries are collated and >> > hashed with their before() and hash_code() members? >> >> Yes, that seems reasonable. It's only necessary for interoperation of >> multiple standard libraries on a platform, but that's a thing. >> >> Since the ABI only formally guarantees that the names are uniqued, I think >> the obviously correct way of implementing these is to compare name pointers >> in before() and reinterpret the name pointer as the result of hash_code(). >> That is what libc++ seems to do. I don't have a recent libstdc++ header >> around; the ancient one I do have uses that rule for before() and doesn't >> implement hash_code(), but IIRC these days libstdc++ uses a variant ABI for >> type_info anyway. >> >> libstdc++ has two modes: in one mode, it guarantees typeinfo name uniqueness >> across the program, uses the pointer for before(), and reinterprets the >> pointer as a hash for hash_code. In the other mode (where they try to merge >> types from a .so even if it was dlopen'd RTLD_LOCAL [1]), some names are >> unique and others are not; hash_code computes a hash of the name, and before >> ... well, before is broken, and doesn't produce a strict weak order. > > Is this set by environment variable or by #define? I suppose the latter > would technically work if done consistently enough in program code to paper > over the ODR problems, since the parts of the ABI library that do type_info > comparisons (for dynamic_cast and exceptions) are unlikely to use either > before() or hash_code(). > > It looks like it's a libsupc++ configure-time #define.
Ah, so basically a platform decision, then. Although I guess it's probably more plausible to swap in your own libsupc++ on Linux than it would be on Darwin. >> [1]: It would seem reasonable for the ABI document to say something about >> what happens in this case. If I understand correctly, the issue is that a >> .so that's dlopen'd RTLD_LOCAL can contain a weak definition of the >> type_info for a type that's logically part of another library, and if it's >> loaded before that other library is, the type_info name doesn't get merged >> despite there being some intent that it's the same type. > > I suppose I can't just say that that's an ELF problem. :) > > What we did for ARM64 seems like the right basic approach: the type_info > object records whether it's unique or non-unique, and non-unique RTTI just > falls back on string-based comparisons / hashes. The type_info is unique if > and only if it's for a fundamental type in the ABI library or a polymorphic > class with a key function. > > That's approximately what GCC does. IIRC, you guys use a tag bit for the > local/non-local choice, whereas GCC prepends the name with '*' for the case > where a pointer comparison is applicable. The tag bit approach seems > substantially better, since it doesn't require first fetching through the > pointer in order to tell that we didn't actually need to fetch through the > pointer :) Yep, that's why we did it that way. :) Does GCC just always emit unique RTTI with the '*' prefix, or does it rely on being configured the same way as libsupc++? > On the other hand, GCC has a trick you don't mention here: it also treats > internal-linkage types has having unique type_info. Oh, yes, we do that as well. John.
_______________________________________________ cxx-abi-dev mailing list [email protected] http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev
