[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