[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