Skip to content

Commit 2982dbf

Browse files
committed
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.
2 parents b025802 + aafe2c6 commit 2982dbf

File tree

3 files changed

+26
-13
lines changed

3 files changed

+26
-13
lines changed

src/librustc_codegen_llvm/back/write.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,10 @@ pub fn write_output_file(
7373
unsafe {
7474
let output_c = path_to_c_string(output);
7575
let result = llvm::LLVMRustWriteOutputFile(target, pm, m, output_c.as_ptr(), file_type);
76-
if result.into_result().is_err() {
76+
result.into_result().map_err(|()| {
7777
let msg = format!("could not write output to {}", output.display());
78-
Err(llvm_err(handler, &msg))
79-
} else {
80-
Ok(())
81-
}
78+
llvm_err(handler, &msg)
79+
})
8280
}
8381
}
8482

@@ -505,7 +503,8 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
505503
if write_bc {
506504
let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_bitcode");
507505
if let Err(e) = fs::write(&bc_out, data) {
508-
diag_handler.err(&format!("failed to write bytecode: {}", e));
506+
let msg = format!("failed to write bytecode to {}: {}", bc_out.display(), e);
507+
diag_handler.err(&msg);
509508
}
510509
}
511510

@@ -520,7 +519,8 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
520519
let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION);
521520
let data = bytecode::encode(&module.name, data);
522521
if let Err(e) = fs::write(&dst, data) {
523-
diag_handler.err(&format!("failed to write bytecode: {}", e));
522+
let msg = format!("failed to write bytecode to {}: {}", dst.display(), e);
523+
diag_handler.err(&msg);
524524
}
525525
}
526526
} else if config.embed_bitcode_marker {
@@ -532,7 +532,7 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
532532
if config.emit_ir {
533533
let _timer = cgcx.profile_activity(ProfileCategory::Codegen, "LLVM_emit_ir");
534534
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
535-
let out = path_to_c_string(&out);
535+
let out_c = path_to_c_string(&out);
536536

537537
extern "C" fn demangle_callback(input_ptr: *const c_char,
538538
input_len: size_t,
@@ -566,9 +566,14 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
566566
}
567567

568568
with_codegen(tm, llmod, config.no_builtins, |cpm| {
569-
llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr(), demangle_callback);
569+
let result =
570+
llvm::LLVMRustPrintModule(cpm, llmod, out_c.as_ptr(), demangle_callback);
570571
llvm::LLVMDisposePassManager(cpm);
571-
});
572+
result.into_result().map_err(|()| {
573+
let msg = format!("failed to write LLVM IR to {}", out.display());
574+
llvm_err(diag_handler, &msg)
575+
})
576+
})?;
572577
}
573578

574579
if config.emit_asm || asm_to_obj {

src/librustc_codegen_llvm/llvm/ffi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1687,7 +1687,8 @@ extern "C" {
16871687
Demangle: extern fn(*const c_char,
16881688
size_t,
16891689
*mut c_char,
1690-
size_t) -> size_t);
1690+
size_t) -> size_t,
1691+
) -> LLVMRustResult;
16911692
pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
16921693
pub fn LLVMRustPrintPasses();
16931694
pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char);

src/rustllvm/PassWrapper.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -646,21 +646,28 @@ char RustPrintModulePass::ID = 0;
646646
INITIALIZE_PASS(RustPrintModulePass, "print-rust-module",
647647
"Print rust module to stderr", false, false)
648648

649-
extern "C" void LLVMRustPrintModule(LLVMPassManagerRef PMR, LLVMModuleRef M,
650-
const char *Path, DemangleFn Demangle) {
649+
extern "C" LLVMRustResult
650+
LLVMRustPrintModule(LLVMPassManagerRef PMR, LLVMModuleRef M,
651+
const char *Path, DemangleFn Demangle) {
651652
llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
652653
std::string ErrorInfo;
653654

654655
std::error_code EC;
655656
raw_fd_ostream OS(Path, EC, sys::fs::F_None);
656657
if (EC)
657658
ErrorInfo = EC.message();
659+
if (ErrorInfo != "") {
660+
LLVMRustSetLastError(ErrorInfo.c_str());
661+
return LLVMRustResult::Failure;
662+
}
658663

659664
formatted_raw_ostream FOS(OS);
660665

661666
PM->add(new RustPrintModulePass(FOS, Demangle));
662667

663668
PM->run(*unwrap(M));
669+
670+
return LLVMRustResult::Success;
664671
}
665672

666673
extern "C" void LLVMRustPrintPasses() {

0 commit comments

Comments
 (0)