[PATCH][LTO] Allow non-merged decls

Richard Guenther rguenther@suse.de
Wed Jul 29 18:00:00 GMT 2009


This is a patch to address PR40903, the failure to accept non-merged
decls for -fcommon.  I conveniently use the unused TREE_CHAIN ...

Bootstrap and regtest running, ignore the s/error_at/inform/ changes
in the patch - I'll edit them out and submit/commit them separately.

Does this look ok in principle?
(without at least some of my type merging fixes
we need to re-call lto_symtab_compatible for consistency - the
handling of function decls is very inconsistent here)

Thanks,
Richard.

2009-07-29  Richard Guenther  <rguenther@suse.de>

	PR lto/40903
	* lto-symtab.c (lto_symtab_compatible): Only warn for mismatched
	types.
	(lto_symtab_merge_decl): For decls we cannot merge chain them
	appropriately in the symtab entry.
	(lto_symtab_prevailing_decl): Return a matching entry from the
	symtab chain.

	* gcc.dg/lto/20090729_0.c: New testcase.
	* gcc.dg/lto/20090729_1.c: Likewise.

Index: gcc/lto-symtab.c
===================================================================
*** gcc/lto-symtab.c	(revision 150212)
--- gcc/lto-symtab.c	(working copy)
*************** lto_symtab_compatible (tree old_decl, tr
*** 242,257 ****
  	  gcc_assert (TREE_CODE (old_decl) == FUNCTION_DECL);
  	  error_at (DECL_SOURCE_LOCATION (new_decl),
  		    "function %qD redeclared as variable", new_decl);
! 	  error_at (DECL_SOURCE_LOCATION (old_decl),
! 		    "previously declared here");
  	  return false;
  
  	case FUNCTION_DECL:
  	  gcc_assert (TREE_CODE (old_decl) == VAR_DECL);
  	  error_at (DECL_SOURCE_LOCATION (new_decl),
  		    "variable %qD redeclared as function", new_decl);
! 	  error_at (DECL_SOURCE_LOCATION (old_decl),
! 		    "previously declared here");
  	  return false;
  
  	default:
--- 242,257 ----
  	  gcc_assert (TREE_CODE (old_decl) == FUNCTION_DECL);
  	  error_at (DECL_SOURCE_LOCATION (new_decl),
  		    "function %qD redeclared as variable", new_decl);
! 	  inform (DECL_SOURCE_LOCATION (old_decl),
! 		  "previously declared here");
  	  return false;
  
  	case FUNCTION_DECL:
  	  gcc_assert (TREE_CODE (old_decl) == VAR_DECL);
  	  error_at (DECL_SOURCE_LOCATION (new_decl),
  		    "variable %qD redeclared as function", new_decl);
! 	  inform (DECL_SOURCE_LOCATION (old_decl),
! 		  "previously declared here");
  	  return false;
  
  	default:
*************** lto_symtab_compatible (tree old_decl, tr
*** 321,331 ****
  
        if (!merged_type)
  	{
! 	  error_at (DECL_SOURCE_LOCATION (new_decl),
! 		    "type of %qD does not match original declaration",
! 		    new_decl);
! 	  error_at (DECL_SOURCE_LOCATION (old_decl),
! 		    "previously declared here");
  	  return false;
  	}
      }
--- 321,331 ----
  
        if (!merged_type)
  	{
! 	  warning_at (DECL_SOURCE_LOCATION (new_decl), 0,
! 		      "type of %qD does not match original declaration",
! 		      new_decl);
! 	  inform (DECL_SOURCE_LOCATION (old_decl),
! 		  "previously declared here");
  	  return false;
  	}
      }
*************** lto_symtab_compatible (tree old_decl, tr
*** 335,341 ****
        error_at (DECL_SOURCE_LOCATION (new_decl),
  		"signedness of %qD does not match original declaration",
  		new_decl);
!       error_at (DECL_SOURCE_LOCATION (old_decl), "previously declared here");
        return false;
      }
  
--- 335,341 ----
        error_at (DECL_SOURCE_LOCATION (new_decl),
  		"signedness of %qD does not match original declaration",
  		new_decl);
!       inform (DECL_SOURCE_LOCATION (old_decl), "previously declared here");
        return false;
      }
  
*************** lto_symtab_compatible (tree old_decl, tr
*** 370,377 ****
  	  error_at (DECL_SOURCE_LOCATION (new_decl),
  		    "size of %qD does not match original declaration",
  		    new_decl);
! 	  error_at (DECL_SOURCE_LOCATION (old_decl),
! 		    "previously declared here");
  	  return false;
  	}
      }
--- 370,377 ----
  	  error_at (DECL_SOURCE_LOCATION (new_decl),
  		    "size of %qD does not match original declaration",
  		    new_decl);
! 	  inform (DECL_SOURCE_LOCATION (old_decl),
! 		  "previously declared here");
  	  return false;
  	}
      }
*************** lto_symtab_compatible (tree old_decl, tr
*** 383,389 ****
        error_at (DECL_SOURCE_LOCATION (new_decl),
  		"alignment of %qD does not match original declaration",
  		new_decl);
!       error_at (DECL_SOURCE_LOCATION (old_decl), "previously declared here");
        return false;
      }
  
--- 383,389 ----
        error_at (DECL_SOURCE_LOCATION (new_decl),
  		"alignment of %qD does not match original declaration",
  		new_decl);
!       inform (DECL_SOURCE_LOCATION (old_decl), "previously declared here");
        return false;
      }
  
*************** lto_symtab_compatible (tree old_decl, tr
*** 409,416 ****
  	  error_at (DECL_SOURCE_LOCATION (new_decl),
  		    "machine mode of %qD does not match original declaration",
  		    new_decl);
! 	  error_at (DECL_SOURCE_LOCATION (old_decl),
! 		    "previously declared here");
  	  return false;
  	}
      }
--- 409,416 ----
  	  error_at (DECL_SOURCE_LOCATION (new_decl),
  		    "machine mode of %qD does not match original declaration",
  		    new_decl);
! 	  inform (DECL_SOURCE_LOCATION (old_decl),
! 		  "previously declared here");
  	  return false;
  	}
      }
*************** lto_symtab_compatible (tree old_decl, tr
*** 422,428 ****
        error_at (DECL_SOURCE_LOCATION (new_decl),
  		"attributes applied to %qD are incompatible with original "
  		"declaration", new_decl);
!       error_at (DECL_SOURCE_LOCATION (old_decl), "previously declared here");
        return false;
      }
  
--- 422,428 ----
        error_at (DECL_SOURCE_LOCATION (new_decl),
  		"attributes applied to %qD are incompatible with original "
  		"declaration", new_decl);
!       inform (DECL_SOURCE_LOCATION (old_decl), "previously declared here");
        return false;
      }
  
*************** lto_symtab_merge_decl (tree new_decl,
*** 542,547 ****
--- 542,549 ----
  
    gcc_assert (TREE_PUBLIC (new_decl));
  
+   gcc_assert (TREE_CHAIN (new_decl) == NULL_TREE);
+ 
    /* Check that declarations reaching this function do not have
       properties inconsistent with having external linkage.  If any of
       these asertions fail, then the object file reader has failed to
*************** lto_symtab_merge_decl (tree new_decl,
*** 568,583 ****
        return;
      }
  
    /* The linker may ask us to combine two incompatible symbols. */
    if (!lto_symtab_compatible (old_decl, new_decl))
!     return;
  
    /* Merge decl state in both directions, we may still end up using
       the new decl.  */
    TREE_ADDRESSABLE (old_decl) |= TREE_ADDRESSABLE (new_decl);
    TREE_ADDRESSABLE (new_decl) |= TREE_ADDRESSABLE (old_decl);
  
-   old_resolution = lto_symtab_get_resolution (old_decl);
    gcc_assert (resolution != LDPR_UNKNOWN
  	      && resolution != LDPR_UNDEF
  	      && old_resolution != LDPR_UNKNOWN
--- 570,604 ----
        return;
      }
  
+   /* Give ODR violation errors.  */
+   old_resolution = lto_symtab_get_resolution (old_decl);
+   if (resolution == LDPR_PREVAILING_DEF
+       || resolution == LDPR_PREVAILING_DEF_IRONLY)
+     {
+       if ((old_resolution == LDPR_PREVAILING_DEF
+ 	   || old_resolution == LDPR_PREVAILING_DEF_IRONLY)
+ 	  && (old_resolution != resolution || flag_no_common))
+ 	{
+ 	  error_at (DECL_SOURCE_LOCATION (new_decl),
+ 		    "%qD has already been defined", new_decl);
+ 	  inform (DECL_SOURCE_LOCATION (old_decl),
+ 		  "previously defined here");
+ 	  return;
+ 	}
+     }
+ 
    /* The linker may ask us to combine two incompatible symbols. */
    if (!lto_symtab_compatible (old_decl, new_decl))
!     {
!       TREE_CHAIN (old_decl) = new_decl;
!       return;
!     }
  
    /* Merge decl state in both directions, we may still end up using
       the new decl.  */
    TREE_ADDRESSABLE (old_decl) |= TREE_ADDRESSABLE (new_decl);
    TREE_ADDRESSABLE (new_decl) |= TREE_ADDRESSABLE (old_decl);
  
    gcc_assert (resolution != LDPR_UNKNOWN
  	      && resolution != LDPR_UNDEF
  	      && old_resolution != LDPR_UNKNOWN
*************** lto_symtab_merge_decl (tree new_decl,
*** 586,601 ****
    if (resolution == LDPR_PREVAILING_DEF
        || resolution == LDPR_PREVAILING_DEF_IRONLY)
      {
-       if ((old_resolution == LDPR_PREVAILING_DEF
- 	   || old_resolution == LDPR_PREVAILING_DEF_IRONLY)
- 	  && (old_resolution != resolution || flag_no_common))
- 	{
- 	  error_at (DECL_SOURCE_LOCATION (new_decl),
- 		    "%qD has already been defined", new_decl);
- 	  error_at (DECL_SOURCE_LOCATION (old_decl),
- 		    "previously defined here");
- 	  return;
- 	}
        gcc_assert (old_resolution == LDPR_PREEMPTED_IR
  		  || old_resolution ==  LDPR_RESOLVED_IR
  		  || (old_resolution == resolution && !flag_no_common));
--- 607,612 ----
*************** lto_symtab_prevailing_decl (tree decl)
*** 659,667 ****
    /* Ensure DECL_ASSEMBLER_NAME will not set assembler name.  */
    gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
  
    ret = lto_symtab_get_identifier_decl (DECL_ASSEMBLER_NAME (decl));
  
!   return ret;
  }
  
  /* Return the hash table entry of DECL. */
--- 670,688 ----
    /* Ensure DECL_ASSEMBLER_NAME will not set assembler name.  */
    gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
  
+   /* Walk through the list of candidates and return the one we merged to.  */
    ret = lto_symtab_get_identifier_decl (DECL_ASSEMBLER_NAME (decl));
+   while (ret)
+     {
+       /* ???  This should just be useless_type_conversion_p on the types.
+          For now we emit redundant warnings a lot ...  */
+       if (lto_symtab_compatible (decl, ret))
+ 	return ret;
+ 
+       ret = TREE_CHAIN (ret);
+     }
  
!   gcc_unreachable ();
  }
  
  /* Return the hash table entry of DECL. */
Index: gcc/testsuite/gcc.dg/lto/20090729_0.c
===================================================================
*** gcc/testsuite/gcc.dg/lto/20090729_0.c	(revision 0)
--- gcc/testsuite/gcc.dg/lto/20090729_0.c	(revision 0)
***************
*** 0 ****
--- 1,4 ----
+ /* { dg-lto-options "-w" } */
+ 
+ double i;
+ 
Index: gcc/testsuite/gcc.dg/lto/20090729_1.c
===================================================================
*** gcc/testsuite/gcc.dg/lto/20090729_1.c	(revision 0)
--- gcc/testsuite/gcc.dg/lto/20090729_1.c	(revision 0)
***************
*** 0 ****
--- 1,3 ----
+ int i;
+ int main () { return i; }
+ 



More information about the Gcc-patches mailing list