[PATCH] D69650: [ELF] Suggest an arbitrary C++ overload as an alternative spelling

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 30 17:04:41 PDT 2019


MaskRay created this revision.
MaskRay added reviewers: dblaikie, grimar, peter.smith, ruiu, thakis.
Herald added subscribers: llvm-commits, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.

The definition may be mangled while an undefined reference is not.
This may come up when the reference is from a C file or the definition
misses an extern "C".

Suggest an arbitrary <source-name> that matches the undefined reference,
if such a definition exists.

  ld.lld: error: undefined symbol: foo
  >>> referenced by a.o:(.text+0x1)
  >>> did you mean: one of the C++ overloads such as foo(int)
  >>> defined in: a1.o


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D69650

Files:
  lld/ELF/Relocations.cpp
  lld/test/ELF/undef-suggest-extern-cxx.s


Index: lld/test/ELF/undef-suggest-extern-cxx.s
===================================================================
--- /dev/null
+++ lld/test/ELF/undef-suggest-extern-cxx.s
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+
+## The definition is mangled while the reference is not, suggest an arbitrary
+## C++ overload.
+# RUN: echo '.globl _Z3fooi; _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 that we can suggest a local definition.
+# RUN: echo '_Z3fooi: call foo' | llvm-mc -filetype=obj -triple=x86_64 - -o %t2.o
+# RUN: not ld.lld %t2.o -o /dev/null 2>&1 | FileCheck %s
+
+# CHECK:      error: undefined symbol: foo
+# CHECK-NEXT: >>> referenced by {{.*}}
+# CHECK-NEXT: >>> did you mean: one of the C++ overloads such as foo(int)
+
+## Don't suggest nested names whose base name is "foo", e.g. F::foo().
+# RUN: echo '.globl _ZN1F3fooEv; _ZN1F3fooEv:' | llvm-mc -filetype=obj -triple=x86_64 - -o %t3.o
+# RUN: not ld.lld %t.o %t3.o -o /dev/null 2>&1 | FileCheck /dev/null --implicit-check-not='did you mean'
+
+call foo
Index: lld/ELF/Relocations.cpp
===================================================================
--- lld/ELF/Relocations.cpp
+++ lld/ELF/Relocations.cpp
@@ -697,6 +697,15 @@
 
 static std::vector<UndefinedDiag> undefs;
 
+// Check whether the definition name def is a mangled source-name that matches
+// the reference name ref, i.e. def is in the form of _Z <length> <ref>
+// <ignored>.
+static bool canSuggestExternCXX(StringRef ref, StringRef def) {
+  unsigned len;
+  return def.consume_front("_Z") && !def.consumeInteger(10, len) &&
+         len == ref.size() && def.take_front(len) == ref;
+}
+
 // 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.
@@ -774,6 +783,19 @@
           return s;
         }
       }
+  } else {
+    const Symbol *s = nullptr;
+    for (auto &it : map)
+      if (canSuggestExternCXX(name, it.first))
+        s = it.second;
+    symtab->forEachSymbol([&](Symbol *sym) {
+      if (canSuggestExternCXX(name, sym->getName()))
+        s = sym;
+    });
+    if (s) {
+      hint = "one of the C++ overloads such as ";
+      return s;
+    }
   }
 
   return nullptr;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69650.227203.patch
Type: text/x-patch
Size: 2387 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191031/f68afc31/attachment.bin>


More information about the llvm-commits mailing list