[PATCH] D65213: [ELF] With --vs-diagnostics, print a separate message for each location of a duplicate symbol.

Igor Kudrin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 24 07:46:02 PDT 2019


ikudrin created this revision.
ikudrin added reviewers: ruiu, chrisjackson, grimar.
Herald added subscribers: MaskRay, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.

We extract and print the source location in the message header so that Visual Studio is able to parse it and jump there. As duplicate symbols defined in several locations, it is more convenient to have separate error messages, which allows a user to easily access all the locations.


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D65213

Files:
  ELF/Symbols.cpp
  test/ELF/vs-diagnostics-duplicate.s


Index: test/ELF/vs-diagnostics-duplicate.s
===================================================================
--- test/ELF/vs-diagnostics-duplicate.s
+++ test/ELF/vs-diagnostics-duplicate.s
@@ -8,18 +8,21 @@
 // CHECK:      duplicate.s(15): error: duplicate symbol: bar
 // CHECK-NEXT: >>> defined at duplicate.s:15
 // CHECK-NEXT: >>>{{.*}}1.o:(.text+0x{{.+}})
-// CHECK: >>> defined at duplicate2.s:20
-// CHECK: >>>{{.*}}2.o:(.text+0x{{.+}})
+// CHECK:      duplicate2.s(20): error: duplicate symbol: bar
+// CHECK-NEXT: >>> defined at duplicate2.s:20
+// CHECK-NEXT: >>>{{.*}}2.o:(.text+0x{{.+}})
 
 // Case 2. The source locations are unknown for both symbols.
 // CHECK:      {{.*}}ld.lld{{.*}}: error: duplicate symbol: foo
 // CHECK-NEXT: >>> defined at {{.*}}1.o:(.text+0x{{.+}})
+// CHECK:      {{.*}}ld.lld{{.*}}: error: duplicate symbol: foo
 // CHECK-NEXT: >>> defined at {{.*}}2.o:(.text+0x{{.+}})
 
 // Case 3. For the second definition of `baz` we know only the source file found in a STT_FILE symbol.
 // CHECK:      duplicate.s(30): error: duplicate symbol: baz
 // CHECK-NEXT: >>> defined at duplicate.s:30
 // CHECK-NEXT: >>> {{.*}}1.o:(.text+0x{{.+}})
+// CHECK:      {{.*}}ld.lld{{.*}}: error: duplicate symbol: baz
 // CHECK-NEXT: >>> defined at duplicate3.s
 // CHECK-NEXT: >>>            {{.*}}3.o:(.text+0x{{.+}})
 
Index: ELF/Symbols.cpp
===================================================================
--- ELF/Symbols.cpp
+++ ELF/Symbols.cpp
@@ -575,34 +575,38 @@
   if (config->allowMultipleDefinition)
     return;
 
+  auto makeLoc = [&](InputSectionBase *sec, uint64_t offset,
+                     InputFile *file) -> std::string {
+    if (!sec)
+      return "\n>>> defined in " + toString(file);
+    std::string loc = "\n>>> defined at ";
+    std::string src = sec->getSrcMsg(*sym, offset);
+    if (!src.empty())
+      loc += src + "\n>>>            ";
+    loc += sec->getObjMsg(offset);
+    return loc;
+  };
+
   Defined *d = cast<Defined>(sym);
-  if (!d->section || !errSec) {
-    error("duplicate symbol: " + toString(*sym) + "\n>>> defined in " +
-          toString(sym->file) + "\n>>> defined in " + toString(newFile));
-    return;
+  InputSectionBase *sec = cast_or_null<InputSectionBase>(d->section);
+  std::string msg = "duplicate symbol: " + toString(*sym);
+
+  if (errorHandler().vsDiagnostics) {
+    // Print separate error messages for each source location so that both of
+    // them can be extracted and printed in the corresponding message header.
+    error(msg + makeLoc(sec, d->value, sym->file));
+    error(msg + makeLoc(errSec, errOffset, newFile));
+  } else {
+    // Construct and print an error message in the form of:
+    //
+    //   ld.lld: error: duplicate symbol: foo
+    //   >>> defined at bar.c:30
+    //   >>>            bar.o (/home/alice/src/bar.o)
+    //   >>> defined at baz.c:563
+    //   >>>            baz.o in archive libbaz.a
+    error(msg + makeLoc(sec, d->value, sym->file) +
+          makeLoc(errSec, errOffset, newFile));
   }
-
-  // Construct and print an error message in the form of:
-  //
-  //   ld.lld: error: duplicate symbol: foo
-  //   >>> defined at bar.c:30
-  //   >>>            bar.o (/home/alice/src/bar.o)
-  //   >>> defined at baz.c:563
-  //   >>>            baz.o in archive libbaz.a
-  auto *sec1 = cast<InputSectionBase>(d->section);
-  std::string src1 = sec1->getSrcMsg(*sym, d->value);
-  std::string obj1 = sec1->getObjMsg(d->value);
-  std::string src2 = errSec->getSrcMsg(*sym, errOffset);
-  std::string obj2 = errSec->getObjMsg(errOffset);
-
-  std::string msg = "duplicate symbol: " + toString(*sym) + "\n>>> defined at ";
-  if (!src1.empty())
-    msg += src1 + "\n>>>            ";
-  msg += obj1 + "\n>>> defined at ";
-  if (!src2.empty())
-    msg += src2 + "\n>>>            ";
-  msg += obj2;
-  error(msg);
 }
 
 void Symbol::resolveCommon(const CommonSymbol &other) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D65213.211503.patch
Type: text/x-patch
Size: 3920 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190724/92ae8139/attachment.bin>


More information about the llvm-commits mailing list