[lld] r295507 - [COFF] support /ERRORLIMIT option
Bob Haarman via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 17 14:46:06 PST 2017
Author: inglorion
Date: Fri Feb 17 16:46:06 2017
New Revision: 295507
URL: http://llvm.org/viewvc/llvm-project?rev=295507&view=rev
Log:
[COFF] support /ERRORLIMIT option
Summary: This adds support for reporting multiple errors in a single invocation of lld-link. The limit defaults to 20 and can be changed with the /ERRORLIMIT command line parameter, or set to unlimited by passing a value of 0.
Reviewers: pcc, ruiu
Reviewed By: ruiu
Differential Revision: https://reviews.llvm.org/D29691
Added:
lld/trunk/test/COFF/error-limit.test
Modified:
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/Error.cpp
lld/trunk/COFF/Options.td
lld/trunk/COFF/SymbolTable.cpp
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=295507&r1=295506&r2=295507&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Fri Feb 17 16:46:06 2017
@@ -63,7 +63,7 @@ bool link(ArrayRef<const char *> Args, r
(ErrorOS == &llvm::errs() && Process::StandardErrHasColors());
Driver = make<LinkerDriver>();
Driver->link(Args);
- return true;
+ return !ErrorCount;
}
// Drop directory components and replace extension with ".exe" or ".dll".
@@ -126,9 +126,10 @@ void LinkerDriver::addBuffer(std::unique
if (Magic == file_magic::bitcode)
return Symtab.addFile(make<BitcodeFile>(MBRef));
if (Magic == file_magic::coff_cl_gl_object)
- fatal(MBRef.getBufferIdentifier() + ": is not a native COFF file. "
+ error(MBRef.getBufferIdentifier() + ": is not a native COFF file. "
"Recompile without /GL");
- Symtab.addFile(make<ObjectFile>(MBRef));
+ else
+ Symtab.addFile(make<ObjectFile>(MBRef));
}
void LinkerDriver::enqueuePath(StringRef Path) {
@@ -138,8 +139,9 @@ void LinkerDriver::enqueuePath(StringRef
enqueueTask([=]() {
auto MBOrErr = Future->get();
if (MBOrErr.second)
- fatal(MBOrErr.second, "could not open " + PathStr);
- Driver->addBuffer(std::move(MBOrErr.first));
+ error("could not open " + PathStr + ": " + MBOrErr.second.message());
+ else
+ Driver->addBuffer(std::move(MBOrErr.first));
});
if (Config->OutputFile == "")
@@ -155,12 +157,14 @@ void LinkerDriver::addArchiveBuffer(Memo
}
InputFile *Obj;
- if (Magic == file_magic::coff_object)
+ if (Magic == file_magic::coff_object) {
Obj = make<ObjectFile>(MB);
- else if (Magic == file_magic::bitcode)
+ } else if (Magic == file_magic::bitcode) {
Obj = make<BitcodeFile>(MB);
- else
- fatal("unknown file type: " + MB.getBufferIdentifier());
+ } else {
+ error("unknown file type: " + MB.getBufferIdentifier());
+ return;
+ }
Obj->ParentName = ParentName;
Symtab.addFile(Obj);
@@ -238,7 +242,7 @@ void LinkerDriver::parseDirectives(Strin
case OPT_throwingnew:
break;
default:
- fatal(Arg->getSpelling() + " is not allowed in .drectve");
+ error(Arg->getSpelling() + " is not allowed in .drectve");
}
}
}
@@ -456,6 +460,15 @@ void LinkerDriver::link(ArrayRef<const c
// Parse command line options.
opt::InputArgList Args = Parser.parseLINK(ArgsArr.slice(1));
+ // Handle /errorlimit early, because error() depends on it.
+ if (auto *Arg = Args.getLastArg(OPT_errorlimit)) {
+ int N = 20;
+ StringRef S = Arg->getValue();
+ if (S.getAsInteger(10, N))
+ error(Arg->getSpelling() + " number expected, but got " + S);
+ Config->ErrorLimit = N;
+ }
+
// Handle /help
if (Args.hasArg(OPT_help)) {
printHelp(ArgsArr[0]);
@@ -514,8 +527,9 @@ void LinkerDriver::link(ArrayRef<const c
// Handle /noentry
if (Args.hasArg(OPT_noentry)) {
if (!Args.hasArg(OPT_dll))
- fatal("/noentry must be specified with /dll");
- Config->NoEntry = true;
+ error("/noentry must be specified with /dll");
+ else
+ Config->NoEntry = true;
}
// Handle /dll
@@ -526,10 +540,12 @@ void LinkerDriver::link(ArrayRef<const c
// Handle /fixed
if (Args.hasArg(OPT_fixed)) {
- if (Args.hasArg(OPT_dynamicbase))
- fatal("/fixed must not be specified with /dynamicbase");
- Config->Relocatable = false;
- Config->DynamicBase = false;
+ if (Args.hasArg(OPT_dynamicbase)) {
+ error("/fixed must not be specified with /dynamicbase");
+ } else {
+ Config->Relocatable = false;
+ Config->DynamicBase = false;
+ }
}
// Handle /machine
@@ -601,24 +617,24 @@ void LinkerDriver::link(ArrayRef<const c
StringRef OptLevel = StringRef(S).substr(7);
if (OptLevel.getAsInteger(10, Config->LTOOptLevel) ||
Config->LTOOptLevel > 3)
- fatal("/opt:lldlto: invalid optimization level: " + OptLevel);
+ error("/opt:lldlto: invalid optimization level: " + OptLevel);
continue;
}
if (StringRef(S).startswith("lldltojobs=")) {
StringRef Jobs = StringRef(S).substr(11);
if (Jobs.getAsInteger(10, Config->LTOJobs) || Config->LTOJobs == 0)
- fatal("/opt:lldltojobs: invalid job count: " + Jobs);
+ error("/opt:lldltojobs: invalid job count: " + Jobs);
continue;
}
if (StringRef(S).startswith("lldltopartitions=")) {
StringRef N = StringRef(S).substr(17);
if (N.getAsInteger(10, Config->LTOPartitions) ||
Config->LTOPartitions == 0)
- fatal("/opt:lldltopartitions: invalid partition count: " + N);
+ error("/opt:lldltopartitions: invalid partition count: " + N);
continue;
}
if (S != "ref" && S != "lbr" && S != "nolbr")
- fatal("/opt: unknown option: " + S);
+ error("/opt: unknown option: " + S);
}
}
@@ -686,6 +702,9 @@ void LinkerDriver::link(ArrayRef<const c
if (Optional<StringRef> Path = findLib(Arg->getValue()))
enqueuePath(*Path);
+ if (ErrorCount)
+ return;
+
// Windows specific -- Create a resource file containing a manifest file.
if (Config->Manifest == Configuration::Embed)
addBuffer(createManifestRes());
@@ -730,11 +749,13 @@ void LinkerDriver::link(ArrayRef<const c
// Windows specific -- If entry point name is not given, we need to
// infer that from user-defined entry name.
StringRef S = findDefaultEntry();
- if (S.empty())
- fatal("entry point must be defined");
- Config->Entry = addUndefined(S);
- if (Config->Verbose)
- outs() << "Entry name inferred: " << S << "\n";
+ if (S.empty()) {
+ error("entry point must be defined");
+ } else {
+ Config->Entry = addUndefined(S);
+ if (Config->Verbose)
+ outs() << "Entry name inferred: " << S << "\n";
+ }
}
// Handle /export
@@ -819,6 +840,9 @@ void LinkerDriver::link(ArrayRef<const c
addUndefined(mangle("_load_config_used"));
} while (run());
+ if (ErrorCount)
+ return;
+
// If /msvclto is given, we use the MSVC linker to link LTO output files.
// This is useful because MSVC link.exe can generate complete PDBs.
if (Args.hasArg(OPT_msvclto)) {
@@ -844,10 +868,13 @@ void LinkerDriver::link(ArrayRef<const c
}
// Handle /safeseh.
- if (Args.hasArg(OPT_safeseh))
+ if (Args.hasArg(OPT_safeseh)) {
for (ObjectFile *File : Symtab.ObjectFiles)
if (!File->SEHCompat)
- fatal("/safeseh: " + File->getName() + " is not compatible with SEH");
+ error("/safeseh: " + File->getName() + " is not compatible with SEH");
+ if (ErrorCount)
+ return;
+ }
// Windows specific -- when we are creating a .dll file, we also
// need to create a .lib file.
Modified: lld/trunk/COFF/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Error.cpp?rev=295507&r1=295506&r2=295507&view=diff
==============================================================================
--- lld/trunk/COFF/Error.cpp (original)
+++ lld/trunk/COFF/Error.cpp Fri Feb 17 16:46:06 2017
@@ -59,12 +59,13 @@ void error(const Twine &Msg) {
std::lock_guard<std::mutex> Lock(Mu);
if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) {
+ errs() << "error " << ErrorCount << " of " << Config->ErrorLimit << "\n";
print("error: ", raw_ostream::RED);
*ErrorOS << Msg << "\n";
} else if (ErrorCount == Config->ErrorLimit) {
print("error: ", raw_ostream::RED);
*ErrorOS << "too many errors emitted, stopping now"
- << " (use -error-limit=0 to see all errors)\n";
+ << " (use /ERRORLIMIT:0 to see all errors)\n";
exitLld(1);
}
Modified: lld/trunk/COFF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Options.td?rev=295507&r1=295506&r2=295507&view=diff
==============================================================================
--- lld/trunk/COFF/Options.td (original)
+++ lld/trunk/COFF/Options.td Fri Feb 17 16:46:06 2017
@@ -21,6 +21,8 @@ def base : P<"base", "Base address of
def defaultlib : P<"defaultlib", "Add the library to the list of input files">;
def delayload : P<"delayload", "Delay loaded DLL name">;
def entry : P<"entry", "Name of entry point symbol">;
+def errorlimit : P<"errorlimit",
+ "Maximum number of errors to emit before stopping (0 = no limit)">;
def export : P<"export", "Export a function">;
// No help text because /failifmismatch is not intended to be used by the user.
def failifmismatch : P<"failifmismatch", "">;
Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=295507&r1=295506&r2=295507&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Fri Feb 17 16:46:06 2017
@@ -193,7 +193,7 @@ void SymbolTable::addLazy(ArchiveFile *F
}
void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {
- fatal("duplicate symbol: " + toString(*Existing->body()) + " in " +
+ error("duplicate symbol: " + toString(*Existing->body()) + " in " +
toString(Existing->body()->getFile()) + " and in " +
(NewFile ? toString(NewFile) : "(internal)"));
}
Added: lld/trunk/test/COFF/error-limit.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/error-limit.test?rev=295507&view=auto
==============================================================================
--- lld/trunk/test/COFF/error-limit.test (added)
+++ lld/trunk/test/COFF/error-limit.test Fri Feb 17 16:46:06 2017
@@ -0,0 +1,33 @@
+RUN: not lld-link 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 \
+RUN: 21 22 2>&1 | FileCheck -check-prefix=DEFAULT %s
+
+DEFAULT: could not open 01
+DEFAULT: could not open 20
+DEFAULT-NEXT: too many errors emitted, stopping now (use /ERRORLIMIT:0 to see all errors)
+DEFAULT-NOT: could not open 21
+
+RUN: not lld-link /ERRORLIMIT:5 01 02 03 04 05 06 07 08 09 10 2>&1 \
+RUN: | FileCheck -check-prefix=LIMIT5 %s
+
+LIMIT5: could not open 01
+LIMIT5: could not open 05
+LIMIT5-NEXT: too many errors emitted, stopping now (use /ERRORLIMIT:0 to see all errors)
+LIMIT5-NOT: could not open 06
+
+RUN: not lld-link /ERRORLIMIT:0 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 \
+RUN: 16 17 18 19 20 21 22 2>&1 | FileCheck -check-prefix=UNLIMITED %s
+
+UNLIMITED: could not open 01
+UNLIMITED: could not open 20
+UNLIMITED: could not open 21
+UNLIMITED: could not open 22
+UNLIMITED-NOT: too many errors emitted, stopping now (use /ERRORLIMIT:0 to see all errors)
+
+RUN: not lld-link /ERRORLIMIT:XYZ 01 02 03 04 05 06 07 08 09 10 11 12 13 14 \
+RUN: 15 16 17 18 19 20 21 22 2>&1 | FileCheck -check-prefix=WRONG %s
+
+WRONG: /ERRORLIMIT: number expected, but got XYZ
+WRONG: could not open 01
+WRONG: could not open 19
+WRONG-NEXT: too many errors emitted, stopping now (use /ERRORLIMIT:0 to see all errors)
+WRONG-NOT: could not open 20
More information about the llvm-commits
mailing list