diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -714,12 +714,19 @@ // Suggest an alternative spelling of an "undefined symbol" diagnostic. Returns // the suggested symbol, which is either in the symbol table, or in the same // file of sym. +template static const Symbol *getAlternativeSpelling(const Undefined &sym, std::string &pre_hint, std::string &post_hint) { - // Build a map of local defined symbols. DenseMap map; - if (sym.file && !isa(sym.file)) { + if (auto *file = dyn_cast_or_null>(sym.file)) { + // If sym is a symbol defined in a discarded section, maybeReportDiscarded() + // will give an error. Don't suggest an alternative spelling. + if (file && sym.discardedSecIdx != 0 && + file->getSections()[sym.discardedSecIdx] == &InputSection::discarded) + return nullptr; + + // Build a map of local defined symbols. for (const Symbol *s : sym.file->getSymbols()) if (s->isLocal() && s->isDefined()) map.try_emplace(s->getName(), s); @@ -865,8 +872,8 @@ if (correctSpelling) { std::string pre_hint = ": ", post_hint; - if (const Symbol *corrected = - getAlternativeSpelling(cast(sym), pre_hint, post_hint)) { + if (const Symbol *corrected = getAlternativeSpelling( + cast(sym), pre_hint, post_hint)) { msg += "\n>>> did you mean" + pre_hint + toString(*corrected) + post_hint; if (corrected->file) msg += "\n>>> defined in: " + toString(corrected->file); diff --git a/lld/test/ELF/undef-not-suggest.s b/lld/test/ELF/undef-not-suggest.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/undef-not-suggest.s @@ -0,0 +1,25 @@ +# REQUIRES: riscv +## Check we don't suggest alternative spelling for relocations to symbols +## defined in discarded sections. + +# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o +# RUN: not ld.lld %t.o %t.o -o /dev/null 2>&1 | FileCheck %s + +# CHECK-NOT: did you mean: + +.section .text.foo,"axG",%progbits,foo,comdat +foo: + +.section .rodata +## Relocation which references .text.foo . +## Check we don't suggest .data, which has an empty name. +.quad .text.foo + +## Relocation which references foo (this is not represented a section symbol on +## RISC-V). Check we don't suggest for. +.quad foo + +## .data is referenced, so there is a section symbol for .data +.section .data +.quad .data +for: