|
29 | 29 | #include "llvm/Support/PluginLoader.h"
|
30 | 30 | #include "llvm/Support/TargetSelect.h"
|
31 | 31 | #include "llvm/Support/Threading.h"
|
| 32 | +#include <atomic> |
32 | 33 |
|
33 | 34 | using namespace llvm;
|
34 | 35 | using namespace lto;
|
@@ -236,13 +237,6 @@ static int run(int argc, char **argv) {
|
236 | 237 | std::vector<std::unique_ptr<MemoryBuffer>> MBs;
|
237 | 238 |
|
238 | 239 | Config Conf;
|
239 |
| - Conf.DiagHandler = [](const DiagnosticInfo &DI) { |
240 |
| - DiagnosticPrinterRawOStream DP(errs()); |
241 |
| - DI.print(DP); |
242 |
| - errs() << '\n'; |
243 |
| - if (DI.getSeverity() == DS_Error) |
244 |
| - exit(1); |
245 |
| - }; |
246 | 240 |
|
247 | 241 | Conf.CPU = codegen::getMCPU();
|
248 | 242 | Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple());
|
@@ -314,9 +308,25 @@ static int run(int argc, char **argv) {
|
314 | 308 | else
|
315 | 309 | Backend = createInProcessThinBackend(
|
316 | 310 | llvm::heavyweight_hardware_concurrency(Threads));
|
| 311 | + // Track whether we hit an error; in particular, in the multi-threaded case, |
| 312 | + // we can't exit() early because the rest of the threads wouldn't have had a |
| 313 | + // change to be join-ed, and that would result in a "terminate called without |
| 314 | + // an active exception". Altogether, this results in nondeterministic |
| 315 | + // behavior. Instead, we don't exit in the multi-threaded case, but we make |
| 316 | + // sure to report the error and then at the end (after joining cleanly) |
| 317 | + // exit(1). |
| 318 | + std::atomic<bool> HasErrors; |
| 319 | + std::atomic_init(&HasErrors, false); |
| 320 | + Conf.DiagHandler = [&](const DiagnosticInfo &DI) { |
| 321 | + DiagnosticPrinterRawOStream DP(errs()); |
| 322 | + DI.print(DP); |
| 323 | + errs() << '\n'; |
| 324 | + if (DI.getSeverity() == DS_Error) |
| 325 | + HasErrors = true; |
| 326 | + }; |
| 327 | + |
317 | 328 | LTO Lto(std::move(Conf), std::move(Backend));
|
318 | 329 |
|
319 |
| - bool HasErrors = false; |
320 | 330 | for (std::string F : InputFilenames) {
|
321 | 331 | std::unique_ptr<MemoryBuffer> MB = check(MemoryBuffer::getFile(F), F);
|
322 | 332 | std::unique_ptr<InputFile> Input =
|
@@ -381,7 +391,7 @@ static int run(int argc, char **argv) {
|
381 | 391 | "failed to create cache");
|
382 | 392 |
|
383 | 393 | check(Lto.run(AddStream, Cache), "LTO::run failed");
|
384 |
| - return 0; |
| 394 | + return static_cast<int>(HasErrors); |
385 | 395 | }
|
386 | 396 |
|
387 | 397 | static int dumpSymtab(int argc, char **argv) {
|
|
0 commit comments