https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103240

--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to frankhb1989 from comment #7)
> (In reply to Jonathan Wakely from comment #6)
> 
> > What are the mangled type names that are unordered? (that's all you need to
> > describe, everything about flat_map and partition_point is irrelevant; just
> > tell us which names are unordered).
> 
> Here are the pair of the unordered names in the actual case:
> 
> 1.
> St5_BindIFPFN3NPL15ReductionStatusERNS0_8TermNodeERNS0_11ContextNodeEESt17ref
> erence_wrapperIS2_ESt12_PlaceholderILi1EEEE
> 2.
> St5_BindIFZN3NPL2A112_GLOBAL__N_113DoDefineOrSetILb0EE4CallIJEEENS0_15Reducti
> onStatusERNS0_8TermNodeERNS0_11ContextNodeESt10shared_ptrINS0_11EnvironmentEE
> S8_DpOT_EUlRKS7_RKSD_E_S7_SD_EE

Thanks. This second one has "*St5_BindIFZN3NPL..." in type_info::__name, so
yes, they'll be incorrectly ordered with the out-of-line definition.

t1.before(t2) will do a string comparison, but t2.before(t1) will do a pointer
comparison and depend on the string table layout.

> The unordered pair occurs iff. __GXX_TYPEINFO_EQUALITY_INLINE == 0, i.e. the
> out-of-line definition is used, and regardless to the value of
> __GXX_MERGED_TYPEINFO_NAMES (either 0 or 1).

I don't think that's true. If __GXX_MERGED_TYPEINFO_NAMES is true then the
out-of-line definition is correct. You can't just redefine that macro to 1 in
your code and expect it to affect the out-of-line definition in the library.
Even if you recompile the library with 
-D__GXX_MERGED_TYPEINFO_NAMES=1 that doesn't magically make it true. If the
platform ABI and compiler and linker really do guarantee that all typeinfo
names are unique, then address comparison works correctly.

The problem case is when both __GXX_MERGED_TYPEINFO_NAMES and
__GXX_TYPEINFO_EQUALITY_INLINE are zero.


> As above, I've later tested all 4 combinations for sure.

You can't expect that to give meaningful results though, you would need to
rebuild the entire compiler for meaningful results with redefined macros, and
even then it would fail when you use RTTI across dynamic library boundaries.

You can't just redefine those macros and expect the compiler and OS to change
how they work.

> Accidentally the
> inline definition of std::type_info::before does the right thing

I don't think it's an accident.

> (hopefully), so __GXX_TYPEINFO_EQUALITY_INLINE == 1 just works. Otherwise
> there would be no easy workaround without the modification on the standard
> headers.
> 
> Forcing address comparisons is wrong in general, but with some additional
> assumptions to rule out all potential offending features, then all type_info
> objects follow ODR in the strict sense, so this just works. When this is an
> issue, __GXX_TYPEINFO_EQUALITY_INLINE == 1 && __GXX_MERGED_TYPEINFO_NAMES ==
> 0 should be safe for all names not from unnamed namespaces. This is a real
> problem for MinGW (at least with GNU ld which does not perform ICF on
> PE/COFF AFAIK), where __GXX_TYPEINFO_EQUALITY_INLINE == 1 &&
> __GXX_MERGED_TYPEINFO_NAMES == 1 causes something like
> &typeid(shared_ptr<...>) not unique across module boundaries, and my code
> fails elsewhere due to this reason.

So stop redefining those macros then, you're lying to the compiler.

__GXX_MERGED_TYPEINFO_NAMES=1 is a lie on your target. Don't do that.

Reply via email to