Hi, this patch makes us to diagnoze correctly ODR violations such as: $ cat tt.C enum test {val1}; enum test a; $ cat tt2.C enum test {val1, val2}; enum test b; $ ./xgcc -B ./ -O2 -flto tt.C tt2.C tt.C:1:6: warning: type 'test' violates one definition rule [-Wodr] enum test {val1}; ^ tt2.C:1:6: note: an enum with mismatching number of values is defined in another translation unit enum test {val1, val2}; ^
OR $ cat t.C char a; $ ./xgcc -B ./ -O2 t.C -o t1.o -fno-signed-char -c -flto $ ./xgcc -B ./ -O2 t.C -o t2.o -fsigned-char -c -flto $ ./xgcc -B ./ -O2 t1.o t2.o -flto -fno-signed-char -flto <built-in>: warning: type �char� violates one definition rule [-Wodr] <built-in>: note: a type with different signedness is defined in another translation unit t.C:1:6: warning: type of �a� does not match original declaration char a; ^ t.C:1:6: note: previously declared here char a; ^ The char signedness differences happen in Firefox. Previously we would miss this because tree.c saves mangled name only for aggregates. This was useful optimization at a time we used the mangled name only for type inhertiance graph construction. I measured its effect at a time Richard suggested it and the difference was sub 1% on memory use/LTO file sizes that is hopefully acceptable. (most named types are class types, enums are quite rare and integer types adds just constant number of new manglings). One case we still do not handle well in all cases is mismatch in bulitin types, such as -fsigned-char -fno-signed-char and/or -malign-double. This is caused by preloading these types and I guess it comes from bigger problem that those types gets merged despite their differences. Bootstrapped/regtested x86_64-linux, will commit it later today. Honza * tree.c (need_assembler_name_p): Compute mangled name for non-builtin types. * ipa-devirt.c (odr_subtypes_equivalent_p): Non-aggregate types may match unnamed to named. Index: tree.c =================================================================== --- tree.c (revision 222391) +++ tree.c (working copy) @@ -5138,7 +5138,17 @@ need_assembler_name_p (tree decl) && DECL_NAME (decl) && decl == TYPE_NAME (TREE_TYPE (decl)) && !is_lang_specific (TREE_TYPE (decl)) - && AGGREGATE_TYPE_P (TREE_TYPE (decl)) + /* Save some work. Names of builtin types are always derived from + properties of its main variant. A special case are integer types + where mangling do make differences between char/signed char/unsigned + char etc. Storing name for these makes e.g. + -fno-signed-char/-fsigned-char mismatches to be handled well. + + See cp/mangle.c:write_builtin_type for details. */ + && (TREE_CODE (TREE_TYPE (decl)) != VOID_TYPE + && TREE_CODE (TREE_TYPE (decl)) != BOOLEAN_TYPE + && TREE_CODE (TREE_TYPE (decl)) != REAL_TYPE + && TREE_CODE (TREE_TYPE (decl)) != FIXED_POINT_TYPE) && !TYPE_ARTIFICIAL (TREE_TYPE (decl)) && !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE) && !type_in_anonymous_namespace_p (TREE_TYPE (decl))) Index: ipa-devirt.c =================================================================== --- ipa-devirt.c (revision 222391) +++ ipa-devirt.c (working copy) @@ -675,7 +675,8 @@ odr_subtypes_equivalent_p (tree t1, tree have to be compared structurally. */ if (TREE_CODE (t1) != TREE_CODE (t2)) return false; - if ((TYPE_NAME (t1) == NULL_TREE) != (TYPE_NAME (t2) == NULL_TREE)) + if (AGGREGATE_TYPE_P (t1) + && (TYPE_NAME (t1) == NULL_TREE) != (TYPE_NAME (t2) == NULL_TREE)) return false; type_pair pair={t1,t2};