diff mbox

Fix false negatives of ODR type checking on non-aggregates

Message ID 20150425022328.GB51820@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka April 25, 2015, 2:23 a.m. UTC
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.
diff mbox

Patch

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};