Auto merge of #59744 - cuviper:output-errors, r=sanxiyn
Show better errors for LLVM IR output I was trying to output LLVM IR directly to the console: $ rustc hello.rs --emit=llvm-ir -o /dev/stdout LLVM ERROR: IO failure on output stream: Bad file descriptor Now `LLVMRustPrintModule` returns an error, and we print: error: failed to write LLVM IR to /dev/stdout.hello.7rcbfp3g-cgu.0.rcgu.ll: Permission denied ... which is more informative.
This commit is contained in:
commit
2982dbf855
3 changed files with 26 additions and 13 deletions
|
@ -73,12 +73,10 @@ pub fn write_output_file(
|
||||||
unsafe {
|
unsafe {
|
||||||
let output_c = path_to_c_string(output);
|
let output_c = path_to_c_string(output);
|
||||||
let result = llvm::LLVMRustWriteOutputFile(target, pm, m, output_c.as_ptr(), file_type);
|
let result = llvm::LLVMRustWriteOutputFile(target, pm, m, output_c.as_ptr(), file_type);
|
||||||
if result.into_result().is_err() {
|
result.into_result().map_err(|()| {
|
||||||
let msg = format!("could not write output to {}", output.display());
|
let msg = format!("could not write output to {}", output.display());
|
||||||
Err(llvm_err(handler, &msg))
|
llvm_err(handler, &msg)
|
||||||
} else {
|
})
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,7 +503,8 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||||
if write_bc {
|
if write_bc {
|
||||||
let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_bitcode");
|
let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_bitcode");
|
||||||
if let Err(e) = fs::write(&bc_out, data) {
|
if let Err(e) = fs::write(&bc_out, data) {
|
||||||
diag_handler.err(&format!("failed to write bytecode: {}", e));
|
let msg = format!("failed to write bytecode to {}: {}", bc_out.display(), e);
|
||||||
|
diag_handler.err(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,7 +519,8 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||||
let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION);
|
let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION);
|
||||||
let data = bytecode::encode(&module.name, data);
|
let data = bytecode::encode(&module.name, data);
|
||||||
if let Err(e) = fs::write(&dst, data) {
|
if let Err(e) = fs::write(&dst, data) {
|
||||||
diag_handler.err(&format!("failed to write bytecode: {}", e));
|
let msg = format!("failed to write bytecode to {}: {}", dst.display(), e);
|
||||||
|
diag_handler.err(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if config.embed_bitcode_marker {
|
} else if config.embed_bitcode_marker {
|
||||||
|
@ -532,7 +532,7 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||||
if config.emit_ir {
|
if config.emit_ir {
|
||||||
let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_ir");
|
let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_ir");
|
||||||
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
|
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
|
||||||
let out = path_to_c_string(&out);
|
let out_c = path_to_c_string(&out);
|
||||||
|
|
||||||
extern "C" fn demangle_callback(input_ptr: *const c_char,
|
extern "C" fn demangle_callback(input_ptr: *const c_char,
|
||||||
input_len: size_t,
|
input_len: size_t,
|
||||||
|
@ -566,9 +566,14 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||||
}
|
}
|
||||||
|
|
||||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
||||||
llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr(), demangle_callback);
|
let result =
|
||||||
|
llvm::LLVMRustPrintModule(cpm, llmod, out_c.as_ptr(), demangle_callback);
|
||||||
llvm::LLVMDisposePassManager(cpm);
|
llvm::LLVMDisposePassManager(cpm);
|
||||||
});
|
result.into_result().map_err(|()| {
|
||||||
|
let msg = format!("failed to write LLVM IR to {}", out.display());
|
||||||
|
llvm_err(diag_handler, &msg)
|
||||||
|
})
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.emit_asm || asm_to_obj {
|
if config.emit_asm || asm_to_obj {
|
||||||
|
|
|
@ -1687,7 +1687,8 @@ extern "C" {
|
||||||
Demangle: extern fn(*const c_char,
|
Demangle: extern fn(*const c_char,
|
||||||
size_t,
|
size_t,
|
||||||
*mut c_char,
|
*mut c_char,
|
||||||
size_t) -> size_t);
|
size_t) -> size_t,
|
||||||
|
) -> LLVMRustResult;
|
||||||
pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
|
pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
|
||||||
pub fn LLVMRustPrintPasses();
|
pub fn LLVMRustPrintPasses();
|
||||||
pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char);
|
pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char);
|
||||||
|
|
|
@ -646,8 +646,9 @@ char RustPrintModulePass::ID = 0;
|
||||||
INITIALIZE_PASS(RustPrintModulePass, "print-rust-module",
|
INITIALIZE_PASS(RustPrintModulePass, "print-rust-module",
|
||||||
"Print rust module to stderr", false, false)
|
"Print rust module to stderr", false, false)
|
||||||
|
|
||||||
extern "C" void LLVMRustPrintModule(LLVMPassManagerRef PMR, LLVMModuleRef M,
|
extern "C" LLVMRustResult
|
||||||
const char *Path, DemangleFn Demangle) {
|
LLVMRustPrintModule(LLVMPassManagerRef PMR, LLVMModuleRef M,
|
||||||
|
const char *Path, DemangleFn Demangle) {
|
||||||
llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
|
llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
|
||||||
std::string ErrorInfo;
|
std::string ErrorInfo;
|
||||||
|
|
||||||
|
@ -655,12 +656,18 @@ extern "C" void LLVMRustPrintModule(LLVMPassManagerRef PMR, LLVMModuleRef M,
|
||||||
raw_fd_ostream OS(Path, EC, sys::fs::F_None);
|
raw_fd_ostream OS(Path, EC, sys::fs::F_None);
|
||||||
if (EC)
|
if (EC)
|
||||||
ErrorInfo = EC.message();
|
ErrorInfo = EC.message();
|
||||||
|
if (ErrorInfo != "") {
|
||||||
|
LLVMRustSetLastError(ErrorInfo.c_str());
|
||||||
|
return LLVMRustResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
formatted_raw_ostream FOS(OS);
|
formatted_raw_ostream FOS(OS);
|
||||||
|
|
||||||
PM->add(new RustPrintModulePass(FOS, Demangle));
|
PM->add(new RustPrintModulePass(FOS, Demangle));
|
||||||
|
|
||||||
PM->run(*unwrap(M));
|
PM->run(*unwrap(M));
|
||||||
|
|
||||||
|
return LLVMRustResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void LLVMRustPrintPasses() {
|
extern "C" void LLVMRustPrintPasses() {
|
||||||
|
|
Loading…
Reference in a new issue