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

pointee_info_at: fix logic for recursing into enums #132745

Merged
merged 1 commit into from
Nov 9, 2024

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented Nov 7, 2024

Fixes #131834

The logic in pointee_info_at was likely written at a time when the null pointer optimization was the only enum layout optimization -- and as Variant::Multiple kept getting expanded, nobody noticed that the logic is now unsound.

The job of this function is to figure out whether there is a dereferenceable-or-null and aligned pointer at a given offset inside a type. So when we recurse into a multi-variant enum, we better make sure that all the other enum variants must be null! This is the part that was forgotten, and this PR adds it.

The reason this didn't explode in many ways so far is that our references only have 1 niche value (null), so it's not possible on stable to have a multi-variant enum with a dereferenceable pointer and other enum variants that are not null. But with rustc_layout_scalar_valid_range attributes one can force such a layout, and if @the8472's work on alignment niches ever lands, that will make this possible on stable.

@rustbot
Copy link
Collaborator

rustbot commented Nov 7, 2024

r? @cjgillot

rustbot has assigned @cjgillot.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@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 Nov 7, 2024
// the pointer's alignment.
Some(this.for_variant(cx, *untagged_variant))
} else {
None
Copy link
Member

Choose a reason for hiding this comment

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

IIUC, this align will always be 1. I adjusted align at #131739, and I think it's sound.

Copy link
Member

Choose a reason for hiding this comment

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

How about adding a dereferenceable field to PointeeInfo? Or something similar?

Copy link
Member Author

@RalfJung RalfJung Nov 8, 2024

Choose a reason for hiding this comment

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

No, align here can be larger than 1. This is checked by the existing test:

// CHECK: @option_borrow(ptr noalias noundef readonly align 4 dereferenceable_or_null(4) %_x)
#[no_mangle]
pub fn option_borrow(_x: Option<&i32>) {}

// CHECK: @option_borrow_mut(ptr noalias noundef align 4 dereferenceable_or_null(4) %_x)
#[no_mangle]
pub fn option_borrow_mut(_x: Option<&mut i32>) {}

Notice the align 4. Not sure why you are saying align will be 1 here.

I don't see why adding a "dereferenceable" field would help. The entire PointeeInfo struct is the "derefernceable-or-null" flag; a non-dereferenceable type must return None. The "or-null" part is easy to deal with later since we can use the scalar range to check whether null is allowed or not; it would be redundant to also compute that here.

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps my comment was a bit misplaced. See https://github.com/rust-lang/rust/pull/131739/files#diff-a93329b2efc9dabaf147bfdb806fb52501ed7889eb08e26e1a2714bb43862531R22-R39. In this case, we need to drop dereferenceable, but we can keep align 8.

Copy link
Member Author

@RalfJung RalfJung Nov 8, 2024

Choose a reason for hiding this comment

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

I don't think that's worth the effort. We shouldn't implement complicated logic like that unless it actually has real-world benefit.

In particular, I think it is actually impossible for stable code to even potentially benefit from this.

@DianQK
Copy link
Member

DianQK commented Nov 8, 2024

Feel free to r=me or not. This will unlock @the8472's work even without #131739.
The align related discussion can be continued entirely in #131739.

@RalfJung
Copy link
Member Author

RalfJung commented Nov 9, 2024

Thanks!
@bors r=DianQK

@bors
Copy link
Contributor

bors commented Nov 9, 2024

📌 Commit 35a913b has been approved by DianQK

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 Nov 9, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Nov 9, 2024
…iaskrgr

Rollup of 5 pull requests

Successful merges:

 - rust-lang#132552 (Add v9, v8plus, and leoncasa target feature to sparc and use v8plus in create_object_file)
 - rust-lang#132745 (pointee_info_at: fix logic for recursing into enums)
 - rust-lang#132777 (try_question_mark_nop: update test for LLVM 20)
 - rust-lang#132785 (rustc_target: more target string fixes for LLVM 20)
 - rust-lang#132794 (Use a separate dir for r-a builds consistently in helix config)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 6e05afd into rust-lang:master Nov 9, 2024
6 checks passed
@rustbot rustbot added this to the 1.84.0 milestone Nov 9, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Nov 9, 2024
Rollup merge of rust-lang#132745 - RalfJung:pointee-info-inside-enum, r=DianQK

pointee_info_at: fix logic for recursing into enums

Fixes rust-lang#131834

The logic in `pointee_info_at` was likely written at a time when the null pointer optimization was the *only* enum layout optimization -- and as `Variant::Multiple` kept getting expanded, nobody noticed that the logic is now unsound.

The job of this function is to figure out whether there is a dereferenceable-or-null and aligned pointer at a given offset inside a type. So when we recurse into a multi-variant enum, we better make sure that all the other enum variants must be null! This is the part that was forgotten, and this PR adds it.

The reason this didn't explode in many ways so far is that our references only have 1 niche value (null), so it's not possible on stable to have a multi-variant enum with a dereferenceable pointer and other enum variants that are not null. But with `rustc_layout_scalar_valid_range` attributes one can force such a layout, and if `@the8472's` work on alignment niches ever lands, that will make this possible on stable.
@RalfJung RalfJung deleted the pointee-info-inside-enum branch November 9, 2024 14:56
mati865 pushed a commit to mati865/rust that referenced this pull request Nov 12, 2024
… r=DianQK

pointee_info_at: fix logic for recursing into enums

Fixes rust-lang#131834

The logic in `pointee_info_at` was likely written at a time when the null pointer optimization was the *only* enum layout optimization -- and as `Variant::Multiple` kept getting expanded, nobody noticed that the logic is now unsound.

The job of this function is to figure out whether there is a dereferenceable-or-null and aligned pointer at a given offset inside a type. So when we recurse into a multi-variant enum, we better make sure that all the other enum variants must be null! This is the part that was forgotten, and this PR adds it.

The reason this didn't explode in many ways so far is that our references only have 1 niche value (null), so it's not possible on stable to have a multi-variant enum with a dereferenceable pointer and other enum variants that are not null. But with `rustc_layout_scalar_valid_range` attributes one can force such a layout, and if `@the8472's` work on alignment niches ever lands, that will make this possible on stable.
mati865 pushed a commit to mati865/rust that referenced this pull request Nov 12, 2024
…iaskrgr

Rollup of 5 pull requests

Successful merges:

 - rust-lang#132552 (Add v9, v8plus, and leoncasa target feature to sparc and use v8plus in create_object_file)
 - rust-lang#132745 (pointee_info_at: fix logic for recursing into enums)
 - rust-lang#132777 (try_question_mark_nop: update test for LLVM 20)
 - rust-lang#132785 (rustc_target: more target string fixes for LLVM 20)
 - rust-lang#132794 (Use a separate dir for r-a builds consistently in helix config)

r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Drop the dereferenceable attribute when a reference is passed in an enum
5 participants