-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Miscompilation of is_whitespace
inside rustc on Windows-msvc (with -Zdylib-lto)
#109067
Comments
I have a spare windows system, I'll test further once I get home |
Hm, I can't seem to see a way to reproduce this. There isn't any platform-specific code involved in that warning. Are the logs from the GItHub Actions run publicly available? |
To clarify, do you mean that you compiled the above code using a Windows system and saw no warnings?
I'm not very familiar with Windows, but isn't it the case that Git checkout puts CRLF in text files on Windows, by default? That could have an influence while not being actually due to platform dependence in
Yep — https://github.com/kpreid/all-is-cubes/actions/runs/4400743620/jobs/7706316716 is the run I used to test the above code. (It has a lot of other noise because it's just a quick hack upon my regular CI — if I have to I could set up a whole new repository with a custom setup.) |
I can reproduce locally using stable msvc rustc:
Switching between Unix and Windows line endings does not seem to make a difference. Using windows-gnu does not have this warning. But that makes no sense to me. |
Ok, this is super weird. It only appears to affect x86_64-msvc:
|
Ah, I see, I was using aarch64-pc-windows-msvc. I tried x86_64-pc-windows-msvc, and that reproduces. How strange! |
I did a little bit of poking around. Inside |
is_whitespace
inside rustc on Windows-msvc (with thin-LTO)
I removed the diagnostic labels since this isn't an error in the diagnostics themselves. I'm assuming this is a miscompilation during thin-LTO, and thus implying it is related to LLVM, but the underlying cause could be elsewhere. To anyone wanting to reproduce the necessary build settings, I think the only thing needed is |
Adding I-unsound since I see no reason to believe the impact is limited to |
I'll put up a revert of using thin LTO in the meantime. |
cc @lqd @Mark-Simulacrum @bjorn3 @Kobzol as the people involved in LTO for MSVC |
…jyn514 Revert "enable ThinLTO for rustc on x86_64-pc-windows-msvc dist builds" This lead to a miscompilation in at least `char::is_whitespace` and probably in more unknown places..... See rust-lang#109067 This reverts commit 684663e, PR rust-lang#103591.
Here's a partially minimized sample. It can maybe get smaller than this, but after a point it seems to be fairly sensitive to the code shifting around. use std::ops::Range;
use std::str::Chars;
#[derive(Debug)]
enum EscapeError {
UnskippedWhitespaceWarning,
}
fn scan_escape(chars: &mut Chars<'_>) -> Result<char, EscapeError> {
let res = match chars.next().unwrap() {
_ => panic!("invalid"),
};
// Ok(res)
}
fn unescape_str_or_byte_str<F>(src: &str, callback: &mut F)
where
F: FnMut(Range<usize>, Result<char, EscapeError>),
{
let mut chars = src.chars();
// The `start` and `end` computation here is complicated because
// `skip_ascii_whitespace` makes us to skip over chars without counting
// them in the range computation.
while let Some(c) = chars.next() {
let start = src.len() - chars.as_str().len() - c.len_utf8();
let res = match c {
'\\' => {
match chars.clone().next() {
Some('\n') => {
// Rust language specification requires us to skip whitespaces
// if unescaped '\' character is followed by '\n'.
// For details see [Rust language reference]
// (https://doc.rust-lang.org/reference/tokens.html#string-literals).
skip_ascii_whitespace(&mut chars, start, callback);
continue;
}
_ => scan_escape(&mut chars),
}
}
_ => Ok(c)
};
let end = src.len() - chars.as_str().len();
callback(start..end, res);
}
fn skip_ascii_whitespace<F>(chars: &mut Chars<'_>, start: usize, callback: &mut F)
where
F: FnMut(Range<usize>, Result<char, EscapeError>),
{
let tail = chars.as_str();
println!("tail={tail:?}");
let first_non_space = tail
.bytes()
.position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r')
.unwrap_or(tail.len());
println!("first_non_space={first_non_space:?} start={start:?}", );
if tail[1..first_non_space].contains('\n') {
// The +1 accounts for the escaping slash.
// let end = start + first_non_space + 1;
// callback(start..end, Err(EscapeError::MultipleSkippedLinesWarning));
}
let tail = &tail[first_non_space..];
println!("tail={tail:?}");
if let Some(c) = tail.chars().nth(0) {
// For error reporting, we would like the span to contain the character that was not
// skipped. The +1 is necessary to account for the leading \ that started the escape.
// println!("{:?}", '£'.is_whitespace());
println!("first char is {c:?}");
let end = start + first_non_space + c.len_utf8() + 1;
println!("end is {end:?}");
if c.is_whitespace() {
println!("{c:?} is whitespace, err range is {:?}", start..end);
callback(start..end, Err(EscapeError::UnskippedWhitespaceWarning));
}
}
*chars = tail.chars();
}
}
fn main() {
unescape_str_or_byte_str("\\\n£", &mut |_range, result| {
eprintln!("cb={result:?}", );
});
} Build with
|
WG-prioritization assigning priority (Zulip discussion). @rustbot label -I-prioritize +P-critical |
is_whitespace
inside rustc on Windows-msvc (with thin-LTO)is_whitespace
inside rustc on Windows-msvc (with -Zdylib-lto)
I've split up this issue "we have shipped a miscompiled rustc" from "-Zdylib-lto is broken on windows-msvc (#109114)" so that we can close this issue soon after the backport while still keeping track of the other one. |
#108978, a crash in rusc seen by multiple people was also caused by the same issue. |
If folks here could verify this is fixed on the dev-static build (https://internals.rust-lang.org/t/rust-1-68-1-pre-release-testing/18547 for instructions) that would be great - we're expecting a point release on Thursday with what is believed to be a fix. |
There's no warning on the MCVE in the OP on 1.68.1. |
I can confirm that the program which I originally found the problem in now compiles without the warning. |
Seems to me the entire idea of doing this for dist builds before testing it on nightly builds was a bad idea. |
"dist builds" refers to all distributed builds including stable, beta, nightly and CI artifacts from master or try builds. This went through the normal nightly/beta release cycle, but apparently no one found issues there. |
I'm going to close this since we've published a 1.68.1 point release. |
Code
Current output
Desired output
No warning, since U+2022 "
•
" is not whitespace.Anything else?
stable-x86_64-pc-windows-msvc - rustc 1.68.0 (2c8cc3432 2023-03-06)
Weirdly, this warning only occurs on Windows. Unfortunately, I have no Windows systems to test on other than GitHub Actions, so it isn't convenient to test further. I hope this bug report is useful anyway.
The text was updated successfully, but these errors were encountered: