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

Warn on unions with no #[repr] attribute #8235

Closed
5225225 opened this issue Jan 6, 2022 · 1 comment · Fixed by #8289
Closed

Warn on unions with no #[repr] attribute #8235

5225225 opened this issue Jan 6, 2022 · 1 comment · Fixed by #8289
Labels
A-lint Area: New lints E-medium Call for participation: Medium difficulty level problem and requires some initial experience. L-pedantic Lint: Belongs in the pedantic lint group

Comments

@5225225
Copy link
Contributor

5225225 commented Jan 6, 2022

What it does

Unions in rust have unspecified layout by default, despite many people thinking that they lay out each type at the start of the union (like C does)

Lint Name

unspecified_layout_union

Category

pedantic

Advantage

If the user intended the union to be #[repr(C)] because they are using it to read fields other than the most recently written one, the code becomes defined behaviour.

If the user did not intend any specific representation because they are using it in an externally tagged way, the #[allow(unspecified_layout_union)] calls this out specifically.

Drawbacks

Some unions don't rely on the representation being C-like, and this may be the majority of the unions that have no explicit representation.

This lint, once added, would fire on all of these unions, as it's currently impossible to specify the rust repr explicitly. This might be a source of noise. I originally thought about suspicious as a category for this lint, but downgraded it to pedantic because of that.

Example

union Foo {
    a: i32,
    b: u32,
}

fn main() {
    let _x: u32 = unsafe {
        Foo { a: 0_i32 }.b // UB, `b` is allowed to be padding
    };
}

Could be written as:

#[repr(C)]
union Foo {
    a: i32,
    b: u32,
}

fn main() {
    let _x: u32 = unsafe {
        Foo { a: 0_i32 }.b // Now defined behaviour, this is just an i32 -> u32 transmute.
    };
}
@5225225 5225225 added the A-lint Area: New lints label Jan 6, 2022
@giraffate
Copy link
Contributor

FYI there is a similar lint, though for a different purpose: https://rust-lang.github.io/rust-clippy/master/index.html#trailing_empty_array

@giraffate giraffate added the good-first-issue These issues are a good way to get started with Clippy label Jan 7, 2022
jubnzv added a commit to jubnzv/rust-clippy that referenced this issue Jan 15, 2022
jubnzv added a commit to jubnzv/rust-clippy that referenced this issue Jan 15, 2022
jubnzv added a commit to jubnzv/rust-clippy that referenced this issue Jan 15, 2022
@flip1995 flip1995 added E-medium Call for participation: Medium difficulty level problem and requires some initial experience. L-pedantic Lint: Belongs in the pedantic lint group and removed good-first-issue These issues are a good way to get started with Clippy labels Jan 20, 2022
bors added a commit that referenced this issue Jan 29, 2022
Add `default_union_representation` lint

Closes #8235

changelog: Added a new lint  [`default_union_representation`]
@bors bors closed this as completed in b7000b2 Jan 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints E-medium Call for participation: Medium difficulty level problem and requires some initial experience. L-pedantic Lint: Belongs in the pedantic lint group
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants