https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86490
--- Comment #14 from zenith432 at users dot sourceforge.net --- (In reply to H.J. Lu from comment #13) > > But the symbol in question won't be USED by lto1 at all. Ok. I didn't completely check the logic for resolutions in ld.bfd so didn't understand that it *knows* the symbol won't be used. If ld knows a symbol in the IR won't be used and wants to trick lto1 into discarding the symbol - it can do so by setting the resolution to LDPR_PREEMPTED_REG. lto1 has no way of verifying whether the symbol is defined outside the IR or not - so will simply respond to this resolution by discarding the symbol. There is an example of this in gold in Pluginobj::get_symbol_resolution_info > if (static_cast<size_t>(nsyms) > this->symbols_.size()) > { > // We never decided to include this object. We mark all symbols as > // preempted. > gold_assert(this->symbols_.size() == 0); > for (int i = 0; i < nsyms; i++) > syms[i].resolution = LDPR_PREEMPTED_REG; > return version > 2 ? LDPS_NO_SYMS : LDPS_OK; > } I did not completely follow the gold code as to why it may decide not to include the object, but if gold decides not to include the object after it's been claimed - this is how it gets all its symbols to be discarded by lto1. Note that there are cases of multiple defs in the IR of an unused symbol where the linker still has to stop with an error. For example - if the duplicate def is a regular kind (non-common, non-weak) and the obj files all appear on the command-line (not archive) - this is a duplicate symbol error even if the symbol is unreferenced. The linker can either print the error itself - or leave multiple prevailing defs for lto1 to print the error :)