> 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

Reply via email to