Skip to content

Commit 9112f0f

Browse files
Unlink temporary file hard links from previous session before writing into them
1 parent c211076 commit 9112f0f

File tree

5 files changed

+89
-13
lines changed

5 files changed

+89
-13
lines changed

Diff for: compiler/rustc_codegen_gcc/src/back/write.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ pub(crate) unsafe fn codegen(
3838
let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
3939
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
4040

41+
// Ensure we don't overwrite any hard links from previous compilation sessions.
42+
ensure_removed(dcx, &bc_out);
43+
ensure_removed(dcx, &obj_out);
44+
4145
if config.bitcode_needed() {
4246
if fat_lto {
4347
let _timer = cgcx
@@ -117,15 +121,19 @@ pub(crate) unsafe fn codegen(
117121
}
118122

119123
if config.emit_ir {
120-
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
121-
std::fs::write(out, "").expect("write file");
124+
let ir_out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
125+
// Ensure we don't overwrite any hard links from previous compilation sessions.
126+
ensure_removed(dcx, &ir_out);
127+
std::fs::write(ir_out, "").expect("write file");
122128
}
123129

124130
if config.emit_asm {
125131
let _timer =
126132
cgcx.prof.generic_activity_with_arg("GCC_module_codegen_emit_asm", &*module.name);
127-
let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
128-
context.compile_to_file(OutputKind::Assembler, path.to_str().expect("path to str"));
133+
let asm_out = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
134+
// Ensure we don't overwrite any hard links from previous compilation sessions.
135+
ensure_removed(dcx, &asm_out);
136+
context.compile_to_file(OutputKind::Assembler, asm_out.to_str().expect("path to str"));
129137
}
130138

131139
match config.emit_obj {

Diff for: compiler/rustc_codegen_llvm/src/back/write.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,10 @@ pub(crate) unsafe fn codegen(
820820
let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
821821
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
822822

823+
// Ensure we don't overwrite any hard links from previous compilation sessions.
824+
ensure_removed(dcx, &bc_out);
825+
ensure_removed(dcx, &obj_out);
826+
823827
if config.bitcode_needed() {
824828
if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
825829
let thin = {
@@ -860,8 +864,11 @@ pub(crate) unsafe fn codegen(
860864
if config.emit_ir {
861865
let _timer =
862866
cgcx.prof.generic_activity_with_arg("LLVM_module_codegen_emit_ir", &*module.name);
863-
let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
864-
let out_c = path_to_c_string(&out);
867+
let ir_out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
868+
// Ensure we don't overwrite any hard links from previous compilation sessions.
869+
ensure_removed(dcx, &ir_out);
870+
871+
let out_c = path_to_c_string(&ir_out);
865872

866873
extern "C" fn demangle_callback(
867874
input_ptr: *const c_char,
@@ -893,16 +900,20 @@ pub(crate) unsafe fn codegen(
893900
unsafe { llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback) };
894901

895902
if result == llvm::LLVMRustResult::Success {
896-
record_artifact_size(&cgcx.prof, "llvm_ir", &out);
903+
record_artifact_size(&cgcx.prof, "llvm_ir", &ir_out);
897904
}
898905

899-
result.into_result().map_err(|()| llvm_err(dcx, LlvmError::WriteIr { path: &out }))?;
906+
result
907+
.into_result()
908+
.map_err(|()| llvm_err(dcx, LlvmError::WriteIr { path: &ir_out }))?;
900909
}
901910

902911
if config.emit_asm {
903912
let _timer =
904913
cgcx.prof.generic_activity_with_arg("LLVM_module_codegen_emit_asm", &*module.name);
905-
let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
914+
let asm_out = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
915+
// Ensure we don't overwrite any hard links from previous compilation sessions.
916+
ensure_removed(dcx, &asm_out);
906917

907918
// We can't use the same module for asm and object code output,
908919
// because that triggers various errors like invalid IR or broken
@@ -918,7 +929,7 @@ pub(crate) unsafe fn codegen(
918929
tm.raw(),
919930
config.no_builtins,
920931
llmod,
921-
&path,
932+
&asm_out,
922933
None,
923934
llvm::FileType::AssemblyFile,
924935
&cgcx.prof,
@@ -933,6 +944,9 @@ pub(crate) unsafe fn codegen(
933944
.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &*module.name);
934945

935946
let dwo_out = cgcx.output_filenames.temp_path_dwo(module_name);
947+
// Ensure we don't overwrite any hard links from previous compilation sessions.
948+
ensure_removed(dcx, &dwo_out);
949+
936950
let dwo_out = match (cgcx.split_debuginfo, cgcx.split_dwarf_kind) {
937951
// Don't change how DWARF is emitted when disabled.
938952
(SplitDebuginfo::Off, _) => None,

Diff for: compiler/rustc_codegen_ssa/src/base.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -640,20 +640,20 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
640640
let metadata_cgu_name =
641641
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("metadata")).to_string();
642642
tcx.sess.time("write_compressed_metadata", || {
643-
let file_name =
643+
let metadata_out =
644644
tcx.output_filenames(()).temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
645645
let data = create_compressed_metadata_file(
646646
tcx.sess,
647647
&metadata,
648648
&exported_symbols::metadata_symbol_name(tcx),
649649
);
650-
if let Err(error) = std::fs::write(&file_name, data) {
650+
if let Err(error) = std::fs::write(&metadata_out, data) {
651651
tcx.dcx().emit_fatal(errors::MetadataObjectFileWrite { error });
652652
}
653653
CompiledModule {
654654
name: metadata_cgu_name,
655655
kind: ModuleKind::Metadata,
656-
object: Some(file_name),
656+
object: Some(metadata_out),
657657
dwarf_object: None,
658658
bytecode: None,
659659
assembly: None,

Diff for: tests/run-make/dirty-incr-due-to-hard-link/rmake.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use run_make_support::{run, rustc};
2+
3+
fn main() {
4+
let mk_rustc = || {
5+
let mut rustc = rustc();
6+
rustc.input("test.rs").incremental("incr").arg("-Csave-temps").output("test");
7+
rustc
8+
};
9+
10+
// Revision 1
11+
mk_rustc().cfg("rpass1").run();
12+
13+
run("test");
14+
15+
// Revision 2
16+
mk_rustc().cfg("cfail2").run_fail();
17+
// Expected to fail.
18+
19+
// Revision 3
20+
mk_rustc().cfg("rpass3").run();
21+
22+
run("test");
23+
}

Diff for: tests/run-make/dirty-incr-due-to-hard-link/test.rs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#[inline(never)]
2+
#[cfg(any(rpass1, rpass3))]
3+
fn a() -> i32 {
4+
0
5+
}
6+
7+
#[cfg(any(cfail2))]
8+
fn a() -> i32 {
9+
1
10+
}
11+
12+
fn main() {
13+
evil::evil();
14+
assert_eq!(a(), 0);
15+
}
16+
17+
mod evil {
18+
#[cfg(any(rpass1, rpass3))]
19+
pub fn evil() {
20+
unsafe {
21+
std::arch::asm!("/* */");
22+
}
23+
}
24+
25+
#[cfg(any(cfail2))]
26+
pub fn evil() {
27+
unsafe {
28+
std::arch::asm!("missing");
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)