mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-14 15:16:07 +03:00
Don't output files on LLVM errors. (#4425)
Fix issue where an LLVM error or warning during IR passes (e.g. --fwarn-stack-size) does not abort outputting files. The object file would be added to the cache, and subsequent repeated LDC execution would fetch the object file from the cache, effectively swallowing the error.
This commit is contained in:
parent
29bf2d302c
commit
3e2156fa68
3 changed files with 62 additions and 12 deletions
|
@ -377,15 +377,24 @@ void CodeGenerator::writeMLIRModule(mlir::OwningModuleRef *module,
|
|||
const auto llpath = replaceExtensionWith(mlir_ext, filename);
|
||||
Logger::println("Writting MLIR to %s\n", llpath.c_str());
|
||||
std::error_code errinfo;
|
||||
llvm::raw_fd_ostream aos(llpath, errinfo, llvm::sys::fs::OF_None);
|
||||
llvm::ToolOutputFile aos(llpath, errinfo, llvm::sys::fs::OF_None);
|
||||
|
||||
if (aos.has_error()) {
|
||||
if (aos.os().has_error()) {
|
||||
error(Loc(), "Cannot write MLIR file '%s': %s", llpath.c_str(),
|
||||
errinfo.message().c_str());
|
||||
fatal();
|
||||
}
|
||||
|
||||
// module->print(aos);
|
||||
|
||||
// Terminate upon errors during the LLVM passes.
|
||||
if (global.errors || global.warnings) {
|
||||
Logger::println(
|
||||
"Aborting because of errors/warnings during bitcode LLVM passes");
|
||||
fatal();
|
||||
}
|
||||
|
||||
aos.keep();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "llvm/Support/FormattedStream.h"
|
||||
#include "llvm/Support/Program.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/ToolOutputFile.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
|
@ -93,7 +94,7 @@ void codegenModule(llvm::TargetMachine &Target, llvm::Module &m,
|
|||
}
|
||||
|
||||
std::error_code errinfo;
|
||||
llvm::raw_fd_ostream out(filename, errinfo, llvm::sys::fs::OF_None);
|
||||
llvm::ToolOutputFile out(filename, errinfo, llvm::sys::fs::OF_None);
|
||||
if (errinfo) {
|
||||
error(Loc(), "cannot write file '%s': %s", filename,
|
||||
errinfo.message().c_str());
|
||||
|
@ -119,7 +120,7 @@ void codegenModule(llvm::TargetMachine &Target, llvm::Module &m,
|
|||
|
||||
if (Target.addPassesToEmitFile(
|
||||
Passes,
|
||||
out, // Output file
|
||||
out.os(), // Output file
|
||||
nullptr, // DWO output file
|
||||
// Always generate assembly for ptx as it is an assembly format
|
||||
// The PTX backend fails if we pass anything else.
|
||||
|
@ -129,6 +130,14 @@ void codegenModule(llvm::TargetMachine &Target, llvm::Module &m,
|
|||
}
|
||||
|
||||
Passes.run(m);
|
||||
|
||||
// Terminate upon errors during the LLVM passes.
|
||||
if (global.errors || global.warnings) {
|
||||
Logger::println("Aborting because of errors/warnings during LLVM passes");
|
||||
fatal();
|
||||
}
|
||||
|
||||
out.keep();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -349,6 +358,15 @@ void writeModule(llvm::Module *m, const char *filename) {
|
|||
runDLLImportRelocationPass(*gTargetMachine, *m);
|
||||
}
|
||||
|
||||
// Check if there are any errors before writing files.
|
||||
// Note: LLVM passes can add new warnings/errors (warnings become errors with
|
||||
// `-w`) such that we reach here with errors that did not trigger earlier
|
||||
// termination of the compiler.
|
||||
if (global.errors) {
|
||||
Logger::println("Aborting because of errors");
|
||||
fatal();
|
||||
}
|
||||
|
||||
// Everything beyond this point is writing file(s) to disk.
|
||||
::TimeTraceScope timeScope("Write file(s)", filename);
|
||||
|
||||
|
@ -371,8 +389,8 @@ void writeModule(llvm::Module *m, const char *filename) {
|
|||
: replaceExtensionWith(bc_ext, filename);
|
||||
Logger::println("Writing LLVM bitcode to: %s\n", bcpath.c_str());
|
||||
std::error_code errinfo;
|
||||
llvm::raw_fd_ostream bos(bcpath.c_str(), errinfo, llvm::sys::fs::OF_None);
|
||||
if (bos.has_error()) {
|
||||
llvm::ToolOutputFile bos(bcpath.c_str(), errinfo, llvm::sys::fs::OF_None);
|
||||
if (bos.os().has_error()) {
|
||||
error(Loc(), "cannot write LLVM bitcode file '%s': %s", bcpath.c_str(),
|
||||
errinfo.message().c_str());
|
||||
fatal();
|
||||
|
@ -390,11 +408,20 @@ void writeModule(llvm::Module *m, const char *filename) {
|
|||
auto moduleSummaryIndex = buildModuleSummaryIndex(
|
||||
*m, /* function freq callback */ nullptr, &PSI);
|
||||
|
||||
llvm::WriteBitcodeToFile(M, bos, true, &moduleSummaryIndex,
|
||||
llvm::WriteBitcodeToFile(M, bos.os(), true, &moduleSummaryIndex,
|
||||
/* generate ThinLTO hash */ true);
|
||||
} else {
|
||||
llvm::WriteBitcodeToFile(M, bos);
|
||||
llvm::WriteBitcodeToFile(M, bos.os());
|
||||
}
|
||||
|
||||
// Terminate upon errors during the LLVM passes.
|
||||
if (global.errors || global.warnings) {
|
||||
Logger::println(
|
||||
"Aborting because of errors/warnings during bitcode LLVM passes");
|
||||
fatal();
|
||||
}
|
||||
|
||||
bos.keep();
|
||||
}
|
||||
|
||||
// write LLVM IR
|
||||
|
@ -402,14 +429,22 @@ void writeModule(llvm::Module *m, const char *filename) {
|
|||
const auto llpath = replaceExtensionWith(ll_ext, filename);
|
||||
Logger::println("Writing LLVM IR to: %s\n", llpath.c_str());
|
||||
std::error_code errinfo;
|
||||
llvm::raw_fd_ostream aos(llpath.c_str(), errinfo, llvm::sys::fs::OF_None);
|
||||
if (aos.has_error()) {
|
||||
llvm::ToolOutputFile aos(llpath.c_str(), errinfo, llvm::sys::fs::OF_None);
|
||||
if (aos.os().has_error()) {
|
||||
error(Loc(), "cannot write LLVM IR file '%s': %s", llpath.c_str(),
|
||||
errinfo.message().c_str());
|
||||
fatal();
|
||||
}
|
||||
AssemblyAnnotator annotator(m->getDataLayout());
|
||||
m->print(aos, &annotator);
|
||||
m->print(aos.os(), &annotator);
|
||||
|
||||
// Terminate upon errors during the LLVM passes.
|
||||
if (global.errors || global.warnings) {
|
||||
Logger::println("Aborting because of errors/warnings during LLVM passes");
|
||||
fatal();
|
||||
}
|
||||
|
||||
aos.keep();
|
||||
}
|
||||
|
||||
const bool writeObj = outputObj && !emitBitcodeAsObjectFile;
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
|
||||
// RUN: not %ldc -w -c --fwarn-stack-size=200 %s 2>&1 | FileCheck %s
|
||||
|
||||
// Test that IR caching does not hide the warning-error in a second compilation run
|
||||
// RUN: not %ldc -cache=%t-dir -w -c --fwarn-stack-size=200 %s 2>&1 | FileCheck %s
|
||||
// RUN: not %ldc -cache=%t-dir -w -c --fwarn-stack-size=200 %s 2>&1 | FileCheck %s
|
||||
// Test that indeed the IR cache does not exist
|
||||
// RUN: not %prunecache -f %t-dir --max-bytes=1
|
||||
|
||||
module fwarnstacksize;
|
||||
|
||||
void small_stack()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue