mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 22:30:13 +00:00
[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
This commit is contained in:
parent
05efe0fdc4
commit
d8ec81059e
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
22
lld/test/COFF/Inputs/failmismatch1.ll
Normal file
22
lld/test/COFF/Inputs/failmismatch1.ll
Normal file
@ -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)"}
|
28
lld/test/COFF/Inputs/failmismatch2.ll
Normal file
28
lld/test/COFF/Inputs/failmismatch2.ll
Normal file
@ -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)"}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user