summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/lib/Core/SymbolTable.cpp54
-rw-r--r--lld/test/core/undef-weak-coalesce.objtxt70
2 files changed, 64 insertions, 60 deletions
diff --git a/lld/lib/Core/SymbolTable.cpp b/lld/lib/Core/SymbolTable.cpp
index e7c12b8489b..c0405ddc973 100644
--- a/lld/lib/Core/SymbolTable.cpp
+++ b/lld/lib/Core/SymbolTable.cpp
@@ -172,28 +172,42 @@ void SymbolTable::addByName(const Atom & newAtom) {
}
break;
case NCR_DupUndef: {
- const UndefinedAtom* existingUndef =
- dyn_cast<UndefinedAtom>(existing);
- const UndefinedAtom* newUndef =
- dyn_cast<UndefinedAtom>(&newAtom);
- assert(existingUndef != nullptr);
- assert(newUndef != nullptr);
- if (existingUndef->canBeNull() == newUndef->canBeNull()) {
- useNew = false;
- } else {
- if (_context.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
- // FIXME: need diagonstics interface for writing warning messages
- llvm::errs() << "lld warning: undefined symbol "
- << existingUndef->name()
- << " has different weakness in "
- << existingUndef->file().path()
- << " and in "
- << newUndef->file().path();
- }
- useNew = (newUndef->canBeNull() < existingUndef->canBeNull());
- }
+ const UndefinedAtom* existingUndef = dyn_cast<UndefinedAtom>(existing);
+ const UndefinedAtom* newUndef = dyn_cast<UndefinedAtom>(&newAtom);
+ assert(existingUndef != nullptr);
+ assert(newUndef != nullptr);
+
+ bool sameCanBeNull = (existingUndef->canBeNull() == newUndef->canBeNull());
+ if (!sameCanBeNull &&
+ _context.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
+ llvm::errs() << "lld warning: undefined symbol "
+ << existingUndef->name()
+ << " has different weakness in "
+ << existingUndef->file().path()
+ << " and in " << newUndef->file().path() << "\n";
+ }
+
+ const UndefinedAtom *existingFallback = existingUndef->fallback();
+ const UndefinedAtom *newFallback = newUndef->fallback();
+ bool hasDifferentFallback =
+ (existingFallback && newFallback &&
+ existingFallback->name() != newFallback->name());
+ if (hasDifferentFallback) {
+ llvm::errs() << "lld warning: undefined symbol "
+ << existingUndef->name() << " has different fallback: "
+ << existingFallback->name() << " in "
+ << existingUndef->file().path() << " and "
+ << newFallback->name() << " in "
+ << newUndef->file().path() << "\n";
}
+
+ bool hasNewFallback = newUndef->fallback();
+ if (sameCanBeNull)
+ useNew = hasNewFallback;
+ else
+ useNew = (newUndef->canBeNull() < existingUndef->canBeNull());
break;
+ }
case NCR_DupShLib: {
const SharedLibraryAtom* curShLib =
dyn_cast<SharedLibraryAtom>(existing);
diff --git a/lld/test/core/undef-weak-coalesce.objtxt b/lld/test/core/undef-weak-coalesce.objtxt
index 595f2d65ac8..45814535060 100644
--- a/lld/test/core/undef-weak-coalesce.objtxt
+++ b/lld/test/core/undef-weak-coalesce.objtxt
@@ -1,4 +1,5 @@
-# RUN: lld -core %s | FileCheck %s
+# RUN: lld -core %s 2> %t.err | FileCheck %s
+# RUN: FileCheck -check-prefix=ERROR %s < %t.err
#
# Test that undefined symbols preserve their attributes and merge properly
@@ -8,86 +9,75 @@
undefined-atoms:
- name: regular_func
can-be-null: never
-
- name: weak_import_func
can-be-null: at-runtime
-
- name: weak_func
can-be-null: at-buildtime
-
- name: bar1
can-be-null: never
-
- name: bar2
can-be-null: at-runtime
-
- name: bar3
can-be-null: at-buildtime
-
- name: bar4
can-be-null: never
-
- name: bar5
can-be-null: at-runtime
-
- name: bar6
can-be-null: at-buildtime
-
- name: bar7
can-be-null: never
-
- name: bar8
can-be-null: at-runtime
-
+ fallback:
+ name: baz1
- name: bar9
can-be-null: at-buildtime
-
+ fallback:
+ name: baz2
---
undefined-atoms:
- name: bar1
can-be-null: never
-
- name: bar2
can-be-null: at-runtime
-
- name: bar3
can-be-null: at-buildtime
-
- name: bar4
can-be-null: at-runtime
-
- name: bar5
can-be-null: at-buildtime
-
- name: bar6
can-be-null: never
-
- name: bar7
can-be-null: at-buildtime
-
- name: bar8
can-be-null: never
-
- name: bar9
can-be-null: at-runtime
+ fallback:
+ name: baz3
...
-# CHECK: - name: regular_func
-# CHECK: - name: weak_import_func
-# CHECK: can-be-null: at-runtime
-# CHECK: - name: weak_func
-# CHECK: can-be-null: at-buildtime
-# CHECK: - name: bar1
-# CHECK: - name: bar2
-# CHECK: can-be-null: at-runtime
-# CHECK: - name: bar3
-# CHECK: can-be-null: at-buildtime
-# CHECK: - name: bar4
-# CHECK: - name: bar5
-# CHECK: can-be-null: at-runtime
-# CHECK: - name: bar7
-# CHECK: - name: bar6
-# CHECK: - name: bar8
-# CHECK: - name: bar9
-# CHECK: can-be-null: at-runtime
-# CHECK: ...
+# CHECK: - name: regular_func
+# CHECK-NEXT: - name: weak_import_func
+# CHECK-NEXT: can-be-null: at-runtime
+# CHECK-NEXT: - name: weak_func
+# CHECK-NEXT: can-be-null: at-buildtime
+# CHECK-NEXT: - name: bar1
+# CHECK-NEXT: - name: bar2
+# CHECK-NEXT: can-be-null: at-runtime
+# CHECK-NEXT: - name: bar3
+# CHECK-NEXT: can-be-null: at-buildtime
+# CHECK-NEXT: - name: bar4
+# CHECK-NEXT: - name: bar5
+# CHECK-NEXT: can-be-null: at-runtime
+# CHECK-NEXT: - name: bar7
+# CHECK-NEXT: - name: bar6
+# CHECK-NEXT: - name: bar8
+# CHECK-NEXT: - name: bar9
+# CHECK-NEXT: can-be-null: at-runtime
+# CHECK-NEXT: fallback:
+# CHECK-NEXT: name: baz3
+
+# ERROR: undefined symbol bar9 has different fallback: baz2 in and baz3 in
OpenPOWER on IntegriCloud