[cxx-abi-dev] std::type_info::hash_code/before

John McCall rjmccall at apple.com
Tue Oct 4 21:54:18 UTC 2016


> On Oct 4, 2016, at 2:11 PM, Richard Smith <richardsmith at googlers.com> wrote:
> 
> On 4 October 2016 at 13:22, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> wrote:
> > On Oct 4, 2016, at 4:25 AM, David Vandevoorde <daveed at edg.com <mailto:daveed at edg.com>> 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().

>  [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.

John.

> 
> Darwin ARM64 uses a variant ABI that does not guarantee that names are uniqued, and so we need a different rule there to handle that; in particular, it does actually have to fall back on string comparisons and string hashes for non-unique type info.
> 
> John.
> _______________________________________________
> cxx-abi-dev mailing list
> cxx-abi-dev at codesourcery.com <mailto:cxx-abi-dev at codesourcery.com>
> http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev <http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev>
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20161004/8b154a33/attachment-0001.html>


More information about the cxx-abi-dev mailing list