summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Ganea <alexandre.ganea@ubisoft.com>2019-03-06 20:18:38 +0000
committerAlexandre Ganea <alexandre.ganea@ubisoft.com>2019-03-06 20:18:38 +0000
commitd8ec81059eb1e3737f98b45027750b210e5c96b5 (patch)
tree7d11d0d26709e3a58aa01039f094045e8574ca7d
parent05efe0fdc472e1f57e36b7f42476946c59c7128b (diff)
downloadbcm5719-llvm-d8ec81059eb1e3737f98b45027750b210e5c96b5.tar.gz
bcm5719-llvm-d8ec81059eb1e3737f98b45027750b210e5c96b5.zip
[LLD][COFF] More detailed information for /failifmismatch
When mismatched #pragma detect_mismatch declarations occur, now print the conflicting OBJs. lld-link: error: /failifmismatch: mismatch detected for 'TEST': >>> test.obj has value 1 >>> test2.obj has value 2 Fixes PR38579 Differential Revision: https://reviews.llvm.org/D58910 llvm-svn: 355543
-rw-r--r--lld/COFF/Config.h2
-rw-r--r--lld/COFF/Driver.cpp12
-rw-r--r--lld/COFF/Driver.h4
-rw-r--r--lld/COFF/DriverUtils.cpp14
-rw-r--r--lld/COFF/SymbolTable.cpp7
-rw-r--r--lld/test/COFF/Inputs/failmismatch1.ll22
-rw-r--r--lld/test/COFF/Inputs/failmismatch2.ll28
-rw-r--r--lld/test/COFF/failifmismatch.test35
8 files changed, 98 insertions, 26 deletions
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index fefec40d3da..f46be3b0404 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -164,7 +164,7 @@ struct Configuration {
std::map<std::string, int> AlignComm;
// Used for /failifmismatch.
- std::map<StringRef, StringRef> MustMatch;
+ std::map<StringRef, std::pair<StringRef, std::string>> MustMatch;
// Used for /alternatename.
std::map<StringRef, StringRef> AlternateNames;
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 564f6c16d5e..0d161ecc537 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -264,7 +264,13 @@ static bool isDecorated(StringRef Sym) {
// Parses .drectve section contents and returns a list of files
// specified by /defaultlib.
-void LinkerDriver::parseDirectives(StringRef S) {
+void LinkerDriver::parseDirectives(InputFile *File) {
+ StringRef S = File->getDirectives();
+ if (S.empty())
+ return;
+
+ log("Directives: " + toString(File) + ": " + S);
+
ArgParser Parser;
// .drectve is always tokenized using Windows shell rules.
// /EXPORT: option can appear too many times, processing in fastpath.
@@ -307,7 +313,7 @@ void LinkerDriver::parseDirectives(StringRef S) {
Config->Entry = addUndefined(mangle(Arg->getValue()));
break;
case OPT_failifmismatch:
- checkFailIfMismatch(Arg->getValue());
+ checkFailIfMismatch(Arg->getValue(), toString(File));
break;
case OPT_incl:
addUndefined(Arg->getValue());
@@ -1271,7 +1277,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// Handle /failifmismatch
for (auto *Arg : Args.filtered(OPT_failifmismatch))
- checkFailIfMismatch(Arg->getValue());
+ checkFailIfMismatch(Arg->getValue(), "cmd-line");
// Handle /merge
for (auto *Arg : Args.filtered(OPT_merge))
diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h
index 51a21db0d15..1b3ca485d95 100644
--- a/lld/COFF/Driver.h
+++ b/lld/COFF/Driver.h
@@ -69,7 +69,7 @@ public:
void link(llvm::ArrayRef<const char *> Args);
// Used by the resolver to parse .drectve section contents.
- void parseDirectives(StringRef S);
+ void parseDirectives(InputFile *File);
// Used by ArchiveFile to enqueue members.
void enqueueArchiveMember(const Archive::Child &C, StringRef SymName,
@@ -180,7 +180,7 @@ void assignExportOrdinals();
// if value matches previous values for the key.
// This feature used in the directive section to reject
// incompatible objects.
-void checkFailIfMismatch(StringRef Arg);
+void checkFailIfMismatch(StringRef Arg, StringRef Source);
// Convert Windows resource files (.res files) to a .obj file.
MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> MBs);
diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index b790c1b3b78..6f3cf85de5d 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -698,16 +698,18 @@ void assignExportOrdinals() {
// Parses a string in the form of "key=value" and check
// if value matches previous values for the same key.
-void checkFailIfMismatch(StringRef Arg) {
+void checkFailIfMismatch(StringRef Arg, StringRef Source) {
StringRef K, V;
std::tie(K, V) = Arg.split('=');
if (K.empty() || V.empty())
fatal("/failifmismatch: invalid argument: " + Arg);
- StringRef Existing = Config->MustMatch[K];
- if (!Existing.empty() && V != Existing)
- fatal("/failifmismatch: mismatch detected: " + Existing + " and " + V +
- " for key " + K);
- Config->MustMatch[K] = V;
+ std::pair<StringRef, StringRef> Existing = Config->MustMatch[K];
+ if (!Existing.first.empty() && V != Existing.first) {
+ fatal("/failifmismatch: mismatch detected for '" + K + "':\n>>> " +
+ Existing.second + " has value " + Existing.first + "\n>>> " +
+ Source + " has value " + V);
+ }
+ Config->MustMatch[K] = {V, Source};
}
// Convert Windows resource files (.res files) to a .obj file.
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index 18289292cb6..ae84898f24e 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -50,12 +50,7 @@ void SymbolTable::addFile(InputFile *File) {
ImportFile::Instances.push_back(F);
}
- StringRef S = File->getDirectives();
- if (S.empty())
- return;
-
- log("Directives: " + toString(File) + ": " + S);
- Driver->parseDirectives(S);
+ Driver->parseDirectives(File);
}
static void errorOrWarn(const Twine &S) {
diff --git a/lld/test/COFF/Inputs/failmismatch1.ll b/lld/test/COFF/Inputs/failmismatch1.ll
new file mode 100644
index 00000000000..0fb1fa975a9
--- /dev/null
+++ b/lld/test/COFF/Inputs/failmismatch1.ll
@@ -0,0 +1,22 @@
+; ModuleID = 'test.cpp'
+source_filename = "test.cpp"
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc19.16.27027"
+
+; Function Attrs: noinline nounwind optnone sspstrong uwtable
+define dso_local i32 @"?f@@YAHXZ"() #0 {
+ ret i32 0
+}
+
+attributes #0 = { noinline nounwind optnone sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.linker.options = !{!0, !1, !2}
+!llvm.module.flags = !{!3, !4}
+!llvm.ident = !{!5}
+
+!0 = !{!"/DEFAULTLIB:libcmt.lib"}
+!1 = !{!"/DEFAULTLIB:oldnames.lib"}
+!2 = !{!"/FAILIFMISMATCH:\22TEST=1\22"}
+!3 = !{i32 1, !"wchar_size", i32 2}
+!4 = !{i32 7, !"PIC Level", i32 2}
+!5 = !{!"clang version 7.0.1 (tags/RELEASE_701/final)"}
diff --git a/lld/test/COFF/Inputs/failmismatch2.ll b/lld/test/COFF/Inputs/failmismatch2.ll
new file mode 100644
index 00000000000..62cb5b6bdfb
--- /dev/null
+++ b/lld/test/COFF/Inputs/failmismatch2.ll
@@ -0,0 +1,28 @@
+; ModuleID = 'test2.cpp'
+source_filename = "test2.cpp"
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc19.16.27027"
+
+; Function Attrs: noinline norecurse nounwind optnone sspstrong uwtable
+define dso_local i32 @main() #0 {
+ %1 = alloca i32, align 4
+ store i32 0, i32* %1, align 4
+ %2 = call i32 @"?f@@YAHXZ"()
+ ret i32 %2
+}
+
+declare dso_local i32 @"?f@@YAHXZ"() #1
+
+attributes #0 = { noinline norecurse nounwind optnone sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.linker.options = !{!0, !1, !2}
+!llvm.module.flags = !{!3, !4}
+!llvm.ident = !{!5}
+
+!0 = !{!"/DEFAULTLIB:libcmt.lib"}
+!1 = !{!"/DEFAULTLIB:oldnames.lib"}
+!2 = !{!"/FAILIFMISMATCH:\22TEST=2\22"}
+!3 = !{i32 1, !"wchar_size", i32 2}
+!4 = !{i32 7, !"PIC Level", i32 2}
+!5 = !{!"clang version 7.0.1 (tags/RELEASE_701/final)"}
diff --git a/lld/test/COFF/failifmismatch.test b/lld/test/COFF/failifmismatch.test
index 021d91b644c..10634ffe7ca 100644
--- a/lld/test/COFF/failifmismatch.test
+++ b/lld/test/COFF/failifmismatch.test
@@ -1,11 +1,30 @@
-# RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
-# RUN: %p/Inputs/ret42.obj
+RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
+RUN: %p/Inputs/ret42.obj
-# RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
-# RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k2=v1
+RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
+RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k2=v1
-# RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
-# RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v1
+RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
+RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v1
-# RUN: not lld-link /entry:main /subsystem:console /out:%t.exe \
-# RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v2
+RUN: not lld-link /entry:main /subsystem:console /out:%t.exe \
+RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v2 2>&1 | FileCheck %s
+
+RUN: llc < %p/Inputs/failmismatch1.ll -filetype obj -o %t1.obj
+RUN: llc < %p/Inputs/failmismatch2.ll -filetype obj -o %t2.obj
+RUN: not lld-link %t1.obj %t2.obj 2>&1 | FileCheck %s -check-prefix OBJ
+
+RUN: llvm-lib %t1.obj /out:%t.lib
+RUN: not lld-link %t.lib %t2.obj 2>&1 | FileCheck %s -check-prefix LIB
+
+CHECK: lld-link: error: /failifmismatch: mismatch detected for 'k1':
+CHECK-NEXT: >>> cmd-line has value v1
+CHECK-NEXT: >>> cmd-line has value v2
+
+OBJ: lld-link: error: /failifmismatch: mismatch detected for 'TEST':
+OBJ-NEXT: >>> {{.*}}failifmismatch.test.tmp1.obj has value 1
+OBJ-NEXT: >>> {{.*}}failifmismatch.test.tmp2.obj has value 2
+
+LIB: lld-link: error: /failifmismatch: mismatch detected for 'TEST':
+LIB-NEXT: >>> {{.*}}failifmismatch.test.tmp2.obj has value 2
+LIB-NEXT: >>> failifmismatch.test.tmp.lib(failifmismatch.test.tmp1.obj) has value 1
OpenPOWER on IntegriCloud