Skip to content

Commit 3634e54

Browse files
Auto merge of #148018 - tardyp:lto_big_filesize_utf8, r=<try>
fix panic when rustc tries to reduce intermediate filenames len with utf8 try-job: x86_64-mingw-* try-job: i686-msvc-*
2 parents 8aab621 + c6acffe commit 3634e54

File tree

3 files changed

+37
-5
lines changed

3 files changed

+37
-5
lines changed

compiler/rustc_session/src/config.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,13 +1211,22 @@ fn maybe_strip_file_name(mut path: PathBuf) -> PathBuf {
12111211
if path.file_name().map_or(0, |name| name.len()) > MAX_FILENAME_LENGTH {
12121212
let filename = path.file_name().unwrap().to_string_lossy();
12131213
let hash_len = 64 / 4; // Hash64 is 64 bits encoded in hex
1214-
let stripped_len = filename.len() - MAX_FILENAME_LENGTH + hash_len;
1214+
let hyphen_len = 1; // the '-' we insert between hash and suffix
1215+
1216+
// number of bytes of suffix we can keep so that "hash-<suffix>" fits
1217+
let allowed_suffix = MAX_FILENAME_LENGTH.saturating_sub(hash_len + hyphen_len);
1218+
1219+
// number of bytes to remove from the start
1220+
let stripped_bytes = filename.len().saturating_sub(allowed_suffix);
1221+
1222+
// ensure we don't cut in a middle of a char
1223+
let split_at = filename.ceil_char_boundary(stripped_bytes);
12151224

12161225
let mut hasher = StableHasher::new();
1217-
filename[..stripped_len].hash(&mut hasher);
1226+
filename[..split_at].hash(&mut hasher);
12181227
let hash = hasher.finish::<Hash64>();
12191228

1220-
path.set_file_name(format!("{:x}-{}", hash, &filename[stripped_len..]));
1229+
path.set_file_name(format!("{:x}-{}", hash, &filename[split_at..]));
12211230
}
12221231
path
12231232
}

tests/run-make/lto-long-filenames/rmake.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
//@ ignore-cross-compile
1111

12-
use std::fs;
13-
1412
use run_make_support::{rfs, rustc};
1513

1614
// This test make sure we don't get such following error:
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//@ ignore-cross-compile
2+
// gnu ld is confused with intermediate files having multibytes characters in their names:
3+
// = note: ld.exe: cannot find f0d5ff18d6510ebc-???_???_??????????_?_?????_?_???????.d50c2 \
4+
// 4c0c4ea93cc-cgu.0.rcgu.o: Invalid argument
5+
// as this is not something rustc can fix by itself,
6+
// we just skip the test on windows-gnu for now. Hence:
7+
//@ ignore-windows-gnu
8+
9+
use run_make_support::{rfs, rustc};
10+
11+
// This test make sure we don't crash when lto creates output files with long names.
12+
// cn characters can be multi-byte and thus trigger the long filename reduction code more easily.
13+
// we need to make sure that the code is properly generating names at char boundaries.
14+
// as reported in issue #147975
15+
fn main() {
16+
let lto_flags = ["-Clto", "-Clto=yes", "-Clto=off", "-Clto=thin", "-Clto=fat"];
17+
for prefix_len in 0..4 {
18+
let prefix: String = std::iter::repeat("_").take(prefix_len).collect();
19+
let main_file = format!("{}ⵅⴻⵎⵎⴻⵎ_ⴷⵉⵎⴰ_ⵖⴻⴼ_ⵢⵉⵙⴻⴽⴽⵉⵍⴻⵏ_ⵏ_ⵡⴰⵟⴰⵙ_ⵏ_ⵢⵉⴱⵢⵜⴻⵏ.rs", prefix);
20+
rfs::write(&main_file, "fn main() {}\n");
21+
for flag in lto_flags {
22+
rustc().input(&main_file).arg(flag).run();
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)