Skip to content
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

Separate MIR lints from validation #119077

Merged
merged 5 commits into from
Dec 23, 2023
Merged

Separate MIR lints from validation #119077

merged 5 commits into from
Dec 23, 2023

Conversation

tmiasko
Copy link
Contributor

@tmiasko tmiasko commented Dec 18, 2023

Add a MIR lint pass, enabled with -Zlint-mir, which identifies undefined or
likely erroneous behaviour.

The initial implementation mostly migrates existing checks of this nature from
MIR validator, where they did not belong (those checks have false positives and
there is nothing inherently invalid about MIR with undefined behaviour).

Fixes #104736
Fixes #104843
Fixes #116079
Fixes #116736
Fixes #118990

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 18, 2023
@rustbot
Copy link
Collaborator

rustbot commented Dec 18, 2023

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@matthiaskrgr
Copy link
Member

Could you mention the new flag in the pr body somewhere so that git log --grep Zlint-mir finds it? 🙃

@saethlin
Copy link
Member

there is nothing inherently invalid about MIR with undefined behaviour

I can see this being true for dead code, but I don't understand how this is true in general. Can you explain?

@tmiasko
Copy link
Contributor Author

tmiasko commented Dec 19, 2023

there is nothing inherently invalid about MIR with undefined behaviour

I can see this being true for dead code, but I don't understand how this is true in general. Can you explain?

Validator should only check that MIR is well-formed. It shouldn't be concerned with behaviour as such, and the fact that it encountered MIR with an undefined behaviour is not a reason to raise an internal compiler error.

Copy link
Contributor

@cjgillot cjgillot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we enable this by default for miropt tests ? Eventually with an 'allow' attr if ub is expected ?

@rustbot rustbot added A-testsuite Area: The testsuite used to check the correctness of rustc T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) labels Dec 21, 2023
@tmiasko
Copy link
Contributor Author

tmiasko commented Dec 21, 2023

  • Updated compiletest to use -Zlint-mir by default for mir opt tests (one of tests violates the new return when still live check, so I disabled the lint there).

@cjgillot
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Dec 22, 2023

📌 Commit ba430a3 has been approved by cjgillot

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 22, 2023
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 23, 2023
…mpiler-errors

Rollup of 6 pull requests

Successful merges:

 - rust-lang#119012 (Extract `layout_of_{struct,enum}` fn)
 - rust-lang#119077 (Separate MIR lints from validation)
 - rust-lang#119171 (Cleanup error handlers: round 4)
 - rust-lang#119198 (Split coroutine desugaring kind from source)
 - rust-lang#119222 (Add `IntoAsyncIterator`)
 - rust-lang#119230 (Exhaustiveness: clean up after librarification)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 7dd0955 into rust-lang:master Dec 23, 2023
11 checks passed
@rustbot rustbot added this to the 1.77.0 milestone Dec 23, 2023
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Dec 23, 2023
Rollup merge of rust-lang#119077 - tmiasko:lint, r=cjgillot

Separate MIR lints from validation

Add a MIR lint pass, enabled with -Zlint-mir, which identifies undefined or
likely erroneous behaviour.

The initial implementation mostly migrates existing checks of this nature from
MIR validator, where they did not belong (those checks have false positives and
there is nothing inherently invalid about MIR with undefined behaviour).

Fixes rust-lang#104736
Fixes rust-lang#104843
Fixes rust-lang#116079
Fixes rust-lang#116736
Fixes rust-lang#118990
@matthiaskrgr
Copy link
Member

Fixes https://github.com/rust-lang/rust/issues/104736
Fixes https://github.com/rust-lang/rust/issues/104843
Fixes https://github.com/rust-lang/rust/issues/116079
Fixes https://github.com/rust-lang/rust/issues/116736
Fixes https://github.com/rust-lang/rust/issues/118990

Hm, so I guess all of these still ICE with -Zlint-mir?
What does this mean wrt the classification of such bugs?
Should they be reopened?

@est31
Copy link
Member

est31 commented Dec 23, 2023

I don't understand either why these issues were closed. Were they closed because they are false positives? Because I think that any case is a bug where you have safe Rust leading to UB in the generated MIR, whether there is an ICE about it or not. I think at least #104736 and #118990 fall under this. There is two more issues that don't have unsafe but use nightly features: those issues are also still important (unless they are false positives).

@tmiasko
Copy link
Contributor Author

tmiasko commented Dec 24, 2023

I think all those issues are false positives.

Those false positives arise from our MIR building strategy for temporaries, where StorageLive doesn't always dominate drop and StorageDead.

@tmiasko tmiasko deleted the lint branch December 24, 2023 10:23
@saethlin
Copy link
Member

In what sense are those false positives? Our documentation for the semantics of StorageLive/StorageDead clearly says such code is UB, and therefore it is a bug for MIR building to produce such code.

@tmiasko
Copy link
Contributor Author

tmiasko commented Dec 24, 2023

In all those issues the MIR after building looks roughly as follows:

flowchart TD
    Start --> Drop["Drop(x)"];
    Live["StorageLive(x)"] --> Init["x = ..."];
    Init --> Drop;
    Drop --> Dead["StorageDead(x)"];
Loading

Before drop elaboration Drop(x) uses x but only when x is initialized. Since x is uninitialized, drop is never executed. Behavior is well defined and we have a false positive.

@saethlin
Copy link
Member

That sounds to me like a rather specific issue with the use of storage check disagreeing with pre-drop-elaboration MIR. Why didn't you propose a targeted fix?

@tmiasko
Copy link
Contributor Author

tmiasko commented Dec 27, 2023

That sounds to me like a rather specific issue with the use of storage check disagreeing with pre-drop-elaboration MIR.

Why would it be specific to pre drop elaboration? Because drop is definitely dead and removed? It happens sometimes, for example in #118990. In general, the same situation could arise later on. Continuing with example from #118990, Replace break 'code; with if true { break 'code; } to obscure from drop elaboration the fact that temporary is definitely uninitialized. The false positive arise at a later stage.

@RalfJung
Copy link
Member

FWIW there are more UB checks in the validator, such as the check whether LHS and RHS overlap in assignment.

@tmiasko
Copy link
Contributor Author

tmiasko commented Dec 30, 2023

I was planning to do some follow up work, including migrating remaining checks as well. In fact, we already had a false positive regarding memory overlap.

@RalfJung
Copy link
Member

we already had a false positive regarding memory overlap.

Do you have a link to that?

@tmiasko
Copy link
Contributor Author

tmiasko commented Dec 31, 2023

we already had a false positive regarding memory overlap.

Do you have a link to that?

#105428

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 5, 2024
Migrate memory overlap check from validator to lint

The check attempts to identify potential undefined behaviour, rather
than whether MIR is well-formed. It belongs in the lint not validator.

Follow up to changes from rust-lang#119077.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 5, 2024
Migrate memory overlap check from validator to lint

The check attempts to identify potential undefined behaviour, rather
than whether MIR is well-formed. It belongs in the lint not validator.

Follow up to changes from rust-lang#119077.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 5, 2024
Migrate memory overlap check from validator to lint

The check attempts to identify potential undefined behaviour, rather
than whether MIR is well-formed. It belongs in the lint not validator.

Follow up to changes from rust-lang#119077.
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jan 5, 2024
Migrate memory overlap check from validator to lint

The check attempts to identify potential undefined behaviour, rather
than whether MIR is well-formed. It belongs in the lint not validator.

Follow up to changes from rust-lang#119077.
compiler-errors added a commit to compiler-errors/rust that referenced this pull request Jan 5, 2024
Migrate memory overlap check from validator to lint

The check attempts to identify potential undefined behaviour, rather
than whether MIR is well-formed. It belongs in the lint not validator.

Follow up to changes from rust-lang#119077.
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Jan 5, 2024
Rollup merge of rust-lang#119577 - tmiasko:lint, r=oli-obk

Migrate memory overlap check from validator to lint

The check attempts to identify potential undefined behaviour, rather
than whether MIR is well-formed. It belongs in the lint not validator.

Follow up to changes from rust-lang#119077.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
8 participants