> > + if (RECORD_OR_UNION_TYPE_P (t)
> > + && odr_type_p (t) && !odr_type_violation_reported_p (t))
> > + {
> > + /* Here we rely on fact that all non-ODR types was inserted into
> > + canonical type hash and thus we can safely detect conflicts between
> > + ODR types and interoperable non-ODR types. */
> > + gcc_checking_assert (type_streaming_finished
> > + && TYPE_MAIN_VARIANT (t) == t);
> > + slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash,
> > + NO_INSERT);
> > + if (slot && !TYPE_CXX_ODR_P (*(tree *)slot))
> > + {
> > + tree nonodr = *(tree *)slot;
> > + if (symtab->dump_file)
> > + {
> > + char *name = cplus_demangle_v3
> > + (IDENTIFIER_POINTER
> > + (DECL_ASSEMBLER_NAME (TYPE_NAME (t))), 0);
>
> Ugh - do we really want to demangle here? I think not. Surely
> not without -details or with -slim. Readers can c++filt this
> easily.
OK, i can dump mangled name.
Just print_generic_expr prints all instantiations of the tempalte same
way which makes it look odd that there are so many types of same name.
> > + /* Set canonical for T and all other ODR equivalent duplicates
> > + including incomplete structures. */
> > + set_type_canonical_for_odr_type (t, prevail);
> > + enable_odr_based_tbaa (t);
>
> I suppose there never will be a set of ODR types with the same
> prevailing type but some of them having a conflict with a nonodr
> type and some not?
No, we check them by structural equality while verifying ODR violations
that is more strict than gimple_canonical_types_compatible.
>
> > + if (!type_in_anonymous_namespace_p (t))
> > + hash = htab_hash_string (IDENTIFIER_POINTER
> > + (DECL_ASSEMBLER_NAME
> > + (TYPE_NAME (prevail))));
> > + else
> > + hash = TYPE_UID (TYPE_MAIN_VARIANT (t));
> > + num_canonical_type_hash_entries++;
> > + bool existed_p = canonical_type_hash_cache->put (prevail, hash);
>
> but those hash differently? I think you wanted to put t, not prevail
> here. And you want to use the TYPE_UID of prevail as well?
Actually this was intended to be prevail in both cases, but it is
harmless. The difference here is that anonymous types have
DECL_ASSEMBLED_NAME <anon>, so if we inserted them to the hash
table based on names they will all conflict.
Anonymous namespace types never have duplicated main variants, so
t==prevail here, but I will update the patch to use prevail since it is
much more obvious (I am also not sure what I was thinking of when
I typed TYPE_MAIN_VARIANT)
>
> Otherwise looks good.
>
> You can commit the C++ FE change with the adjustment in case it
> fixes the reported verification ICEs.
It only fixes ICE WRT the sanity checking that all non-ODR types
are inserted first. W/o that change the as-base type will get inserted
during streaming in and recursively we will insert ODR types early.
I am waiting for testcase WRT the other ODR ICE reported today. I think
tree.c when creating type variants wants to copy the flag: the wrong
type is va_list which is likely created by a backend bypassing the C++
hook.
I will re-test with these changes.
Honza