[PATCH] D69592: [ELF] Suggest extern "C" when an undefined reference is mangled while the definition is not
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 8 09:49:28 PST 2019
This revision was automatically updated to reflect the committed changes.
Closed by commit rG70e62a4fa6c2: [ELF] Suggest extern "C" when an undefined reference is mangled while theā¦ (authored by MaskRay).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D69592/new/
https://reviews.llvm.org/D69592
Files:
lld/ELF/CMakeLists.txt
lld/ELF/Relocations.cpp
lld/test/ELF/undef-suggest-extern-c.s
Index: lld/test/ELF/undef-suggest-extern-c.s
===================================================================
--- /dev/null
+++ lld/test/ELF/undef-suggest-extern-c.s
@@ -0,0 +1,19 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+
+## The reference is mangled while the definition is not, suggest a missing
+## extern "C".
+# RUN: echo 'call _Z3fooi' | llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o
+# RUN: not ld.lld %t.o %t1.o -o /dev/null 2>&1 | FileCheck %s
+
+# CHECK: error: undefined symbol: foo(int)
+# CHECK-NEXT: >>> referenced by {{.*}}
+# CHECK-NEXT: >>> did you mean: extern "C" foo
+
+## Don't suggest for nested names like F::foo() and foo::foo().
+# RUN: echo 'call _ZN1F3fooEv; call _ZN3fooC1Ev' | llvm-mc -filetype=obj -triple=x86_64 - -o %t2.o
+# RUN: not ld.lld %t.o %t2.o -o /dev/null 2>&1 | FileCheck /dev/null --implicit-check-not='did you mean'
+
+.globl _start, foo
+_start:
+foo:
Index: lld/ELF/Relocations.cpp
===================================================================
--- lld/ELF/Relocations.cpp
+++ lld/ELF/Relocations.cpp
@@ -53,6 +53,7 @@
#include "lld/Common/Memory.h"
#include "lld/Common/Strings.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -699,7 +700,8 @@
// 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.
-static const Symbol *getAlternativeSpelling(const Undefined &sym) {
+static const Symbol *getAlternativeSpelling(const Undefined &sym,
+ std::string &pre_hint) {
// Build a map of local defined symbols.
DenseMap<StringRef, const Symbol *> map;
if (sym.file && !isa<SharedFile>(sym.file)) {
@@ -759,6 +761,21 @@
return s;
}
+ // The reference may be a mangled name while the definition is not. Suggest a
+ // missing extern "C".
+ if (name.startswith("_Z")) {
+ llvm::ItaniumPartialDemangler d;
+ if (!d.partialDemangle(name.str().c_str()))
+ if (char *buf = d.getFunctionName(nullptr, nullptr)) {
+ const Symbol *s = suggest(buf);
+ free(buf);
+ if (s) {
+ pre_hint = ": extern \"C\" ";
+ return s;
+ }
+ }
+ }
+
return nullptr;
}
@@ -804,13 +821,15 @@
msg += ("\n>>> referenced " + Twine(undef.locs.size() - i) + " more times")
.str();
- if (correctSpelling)
+ if (correctSpelling) {
+ std::string pre_hint = ": ";
if (const Symbol *corrected =
- getAlternativeSpelling(cast<Undefined>(sym))) {
- msg += "\n>>> did you mean: " + toString(*corrected);
+ getAlternativeSpelling(cast<Undefined>(sym), pre_hint)) {
+ msg += "\n>>> did you mean" + pre_hint + toString(*corrected);
if (corrected->file)
msg += "\n>>> defined in: " + toString(corrected->file);
}
+ }
if (sym.getName().startswith("_ZTV"))
msg += "\nthe vtable symbol may be undefined because the class is missing "
Index: lld/ELF/CMakeLists.txt
===================================================================
--- lld/ELF/CMakeLists.txt
+++ lld/ELF/CMakeLists.txt
@@ -52,6 +52,7 @@
BitWriter
Core
DebugInfoDWARF
+ Demangle
LTO
MC
Object
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69592.228479.patch
Type: text/x-patch
Size: 3394 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191108/9aafc3f0/attachment.bin>
More information about the llvm-commits
mailing list