Skip to content

Commit

Permalink
Rollup merge of #95372 - RalfJung:unaligned_references, r=oli-obk
Browse files Browse the repository at this point in the history
make unaligned_references lint deny-by-default

This lint has been warn-by-default for a year now (since #82525), so I think it is time to crank it up a bit. Code that triggers the lint causes UB (without `unsafe`) when executed, so we really don't want people to write code like this.
  • Loading branch information
Dylan-DPC authored Apr 16, 2022
2 parents 6dd92bf + 1a6c2ff commit 49a31cd
Show file tree
Hide file tree
Showing 17 changed files with 490 additions and 41 deletions.
1 change: 0 additions & 1 deletion compiler/rustc_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#![feature(thread_id_value)]
#![feature(vec_into_raw_parts)]
#![allow(rustc::default_hash_types)]
#![deny(unaligned_references)]
#![allow(rustc::potential_query_instability)]

#[macro_use]
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1110,8 +1110,6 @@ declare_lint! {
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(unaligned_references)]
///
/// #[repr(packed)]
/// pub struct Foo {
/// field1: u64,
Expand Down Expand Up @@ -1139,10 +1137,11 @@ declare_lint! {
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
/// [issue #82523]: https://github.com/rust-lang/rust/issues/82523
pub UNALIGNED_REFERENCES,
Warn,
Deny,
"detects unaligned references to fields of packed structs",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #82523 <https://github.com/rust-lang/rust/issues/82523>",
reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
};
report_in_external_macro
}
Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/binding/issue-53114-safety-checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ fn let_wild_gets_unsafe_field() {
let u1 = U { a: I(0) };
let u2 = U { a: I(1) };
let p = P { a: &2, b: &3 };
let _ = &p.b; //~ WARN reference to packed field
let _ = &p.b; //~ ERROR reference to packed field
//~^ WARN will become a hard error
let _ = u1.a; // #53114: should eventually signal error as well
let _ = &u2.a; //~ ERROR [E0133]

// variation on above with `_` in substructure
let (_,) = (&p.b,); //~ WARN reference to packed field
let (_,) = (&p.b,); //~ ERROR reference to packed field
//~^ WARN will become a hard error
let (_,) = (u1.a,); //~ ERROR [E0133]
let (_,) = (&u2.a,); //~ ERROR [E0133]
Expand All @@ -36,13 +36,13 @@ fn match_unsafe_field_to_wild() {
let u1 = U { a: I(0) };
let u2 = U { a: I(1) };
let p = P { a: &2, b: &3 };
match &p.b { _ => { } } //~ WARN reference to packed field
match &p.b { _ => { } } //~ ERROR reference to packed field
//~^ WARN will become a hard error
match u1.a { _ => { } } //~ ERROR [E0133]
match &u2.a { _ => { } } //~ ERROR [E0133]

// variation on above with `_` in substructure
match (&p.b,) { (_,) => { } } //~ WARN reference to packed field
match (&p.b,) { (_,) => { } } //~ ERROR reference to packed field
//~^ WARN will become a hard error
match (u1.a,) { (_,) => { } } //~ ERROR [E0133]
match (&u2.a,) { (_,) => { } } //~ ERROR [E0133]
Expand Down
64 changes: 58 additions & 6 deletions src/test/ui/binding/issue-53114-safety-checks.stderr
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
warning: reference to packed field is unaligned
error: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:23:13
|
LL | let _ = &p.b;
| ^^^^
|
= note: `#[warn(unaligned_references)]` on by default
= note: `#[deny(unaligned_references)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

warning: reference to packed field is unaligned
error: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:29:17
|
LL | let (_,) = (&p.b,);
Expand All @@ -21,7 +21,7 @@ LL | let (_,) = (&p.b,);
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

warning: reference to packed field is unaligned
error: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:39:11
|
LL | match &p.b { _ => { } }
Expand All @@ -32,7 +32,7 @@ LL | match &p.b { _ => { } }
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

warning: reference to packed field is unaligned
error: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:45:12
|
LL | match (&p.b,) { (_,) => { } }
Expand Down Expand Up @@ -99,6 +99,58 @@ LL | match (&u2.a,) { (_,) => { } }
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior

error: aborting due to 7 previous errors; 4 warnings emitted
error: aborting due to 11 previous errors

For more information about this error, try `rustc --explain E0133`.
Future incompatibility report: Future breakage diagnostic:
error: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:23:13
|
LL | let _ = &p.b;
| ^^^^
|
= note: `#[deny(unaligned_references)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

Future breakage diagnostic:
error: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:29:17
|
LL | let (_,) = (&p.b,);
| ^^^^
|
= note: `#[deny(unaligned_references)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

Future breakage diagnostic:
error: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:39:11
|
LL | match &p.b { _ => { } }
| ^^^^
|
= note: `#[deny(unaligned_references)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

Future breakage diagnostic:
error: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:45:12
|
LL | match (&p.b,) { (_,) => { } }
| ^^^^
|
= note: `#[deny(unaligned_references)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// edition:2021

// check-pass

// Given how the closure desugaring is implemented (at least at the time of writing this test),
// we don't need to truncate the captured path to a reference into a packed-struct if the field
// being referenced will be moved into the closure, since it's safe to move out a field from a
Expand All @@ -11,9 +9,8 @@
// inlined we will truncate the capture to access just the struct regardless of if the field
// might get moved into the closure.
//
// It is possible for someone to try writing the code that relies on the desugaring to access a ref
// into a packed-struct without explicity using unsafe. Here we test that the compiler warns the
// user that such an access is still unsafe.
// It is possible for someone to try writing the code that relies on the desugaring to create a ref
// into a packed-struct. Here we test that the compiler still detects that case.
fn test_missing_unsafe_warning_on_repr_packed() {
#[repr(packed)]
struct Foo { x: String }
Expand All @@ -22,7 +19,7 @@ fn test_missing_unsafe_warning_on_repr_packed() {

let c = || {
println!("{}", foo.x);
//~^ WARNING: reference to packed field is unaligned
//~^ ERROR: reference to packed field is unaligned
//~| WARNING: this was previously accepted by the compiler but is being phased out
let _z = foo.x;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
warning: reference to packed field is unaligned
--> $DIR/repr_packed.rs:24:24
error: reference to packed field is unaligned
--> $DIR/repr_packed.rs:21:24
|
LL | println!("{}", foo.x);
| ^^^^^
|
= note: `#[warn(unaligned_references)]` on by default
= note: `#[deny(unaligned_references)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
= note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: 1 warning emitted
error: aborting due to previous error

Future incompatibility report: Future breakage diagnostic:
error: reference to packed field is unaligned
--> $DIR/repr_packed.rs:21:24
|
LL | println!("{}", foo.x);
| ^^^^^
|
= note: `#[deny(unaligned_references)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
= note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

64 changes: 64 additions & 0 deletions src/test/ui/derives/deriving-with-repr-packed.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,67 @@ LL | #[derive(PartialEq)]

error: aborting due to 4 previous errors

Future incompatibility report: Future breakage diagnostic:
error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133)
--> $DIR/deriving-with-repr-packed.rs:8:16
|
LL | #[derive(Copy, Clone, PartialEq, Eq)]
| ^^^^^
|
note: the lint level is defined here
--> $DIR/deriving-with-repr-packed.rs:1:9
|
LL | #![deny(unaligned_references)]
| ^^^^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)

Future breakage diagnostic:
error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133)
--> $DIR/deriving-with-repr-packed.rs:8:23
|
LL | #[derive(Copy, Clone, PartialEq, Eq)]
| ^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/deriving-with-repr-packed.rs:1:9
|
LL | #![deny(unaligned_references)]
| ^^^^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)

Future breakage diagnostic:
error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133)
--> $DIR/deriving-with-repr-packed.rs:16:10
|
LL | #[derive(PartialEq, Eq)]
| ^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/deriving-with-repr-packed.rs:1:9
|
LL | #![deny(unaligned_references)]
| ^^^^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)

Future breakage diagnostic:
error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133)
--> $DIR/deriving-with-repr-packed.rs:25:10
|
LL | #[derive(PartialEq)]
| ^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/deriving-with-repr-packed.rs:1:9
|
LL | #![deny(unaligned_references)]
| ^^^^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)

Loading

0 comments on commit 49a31cd

Please sign in to comment.