diff options
author | Jan Hubicka <hubicka@gcc.gnu.org> | 2017-06-15 18:42:10 +0000 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2017-06-15 18:42:10 +0000 |
commit | d1eed638ed170a22a3feb9515b82b125fd203727 (patch) | |
tree | a753e9e9d5423fbd3ccff9f0c5190c796dd8e3c2 /gcc/lto/lto-symtab.c | |
parent | 55dabf65f039c3a5635f01dccb9e4de767f89323 (diff) |
re PR lto/69866 (lto1: internal compiler error: in add_symbol_to_partition_1, at lto/lto-partition.c:158)
PR lto/69866
* lto-symtab.c (lto_symtab_merge_symbols): Drop useless definitions
that resolved externally.
* gcc.dg/lto/pr69866_0.c: New test.
* gcc.dg/lto/pr69866_1.c: Likewise.
From-SVN: r249224
Diffstat (limited to 'gcc/lto/lto-symtab.c')
-rw-r--r-- | gcc/lto/lto-symtab.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c index 9fd94861c6d..019677eaf95 100644 --- a/gcc/lto/lto-symtab.c +++ b/gcc/lto/lto-symtab.c @@ -952,6 +952,42 @@ lto_symtab_merge_symbols (void) if (tgt) node->resolve_alias (tgt, true); } + /* If the symbol was preempted outside IR, see if we want to get rid + of the definition. */ + if (node->analyzed + && !DECL_EXTERNAL (node->decl) + && (node->resolution == LDPR_PREEMPTED_REG + || node->resolution == LDPR_RESOLVED_IR + || node->resolution == LDPR_RESOLVED_EXEC + || node->resolution == LDPR_RESOLVED_DYN)) + { + DECL_EXTERNAL (node->decl) = 1; + /* If alias to local symbol was preempted by external definition, + we know it is not pointing to the local symbol. Remove it. */ + if (node->alias + && !node->weakref + && !node->transparent_alias + && node->get_alias_target ()->binds_to_current_def_p ()) + { + node->alias = false; + node->remove_all_references (); + node->definition = false; + node->analyzed = false; + node->cpp_implicit_alias = false; + } + else if (!node->alias + && node->definition + && node->get_availability () <= AVAIL_INTERPOSABLE) + { + if ((cnode = dyn_cast <cgraph_node *> (node)) != NULL) + cnode->reset (); + else + { + node->analyzed = node->definition = false; + node->remove_all_references (); + } + } + } if (!(cnode = dyn_cast <cgraph_node *> (node)) || !cnode->clone_of |