Rollup merge of #82525 - RalfJung:unaligned-ref-warn, r=petrochenkov

make unaligned_references future-incompat lint warn-by-default

and also remove the safe_packed_borrows lint that it replaces.

`std::ptr::addr_of!` has hit beta now and will hit stable in a month, so I propose we start fixing https://github.com/rust-lang/rust/issues/27060 for real: creating a reference to a field of a packed struct needs to eventually become a hard error; this PR makes it a warn-by-default future-incompat lint. (The lint already existed, this just raises its default level.) At the same time I removed the corresponding code from unsafety checking; really there's no reason an `unsafe` block should make any difference here.

For references to packed fields outside `unsafe` blocks, this means `unaligned_refereces` replaces the previous `safe_packed_borrows` warning with a link to https://github.com/rust-lang/rust/issues/82523 (and no more talk about unsafe blocks making any difference). So behavior barely changes, the warning is just worded differently. For references to packed fields inside `unsafe` blocks, this PR shows a new future-incompat warning.

Closes https://github.com/rust-lang/rust/issues/46043 because that lint no longer exists.
This commit is contained in:
Dylan DPC 2021-03-27 20:37:05 +01:00 committed by GitHub
commit a900677eb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 251 additions and 415 deletions

View File

@ -325,6 +325,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
store.register_renamed("exceeding_bitshifts", "arithmetic_overflow");
store.register_renamed("redundant_semicolon", "redundant_semicolons");
store.register_renamed("overlapping_patterns", "overlapping_range_endpoints");
store.register_renamed("safe_packed_borrows", "unaligned_references");
// These were moved to tool lints, but rustc still sees them when compiling normally, before
// tool lints are registered, so `check_tool_name_for_backwards_compat` doesn't work. Use

View File

@ -1057,6 +1057,7 @@ declare_lint! {
/// unsafe {
/// let foo = Foo { field1: 0, field2: 0 };
/// let _ = &foo.field1;
/// println!("{}", foo.field1); // An implicit `&` is added here, triggering the lint.
/// }
/// }
/// ```
@ -1065,20 +1066,20 @@ declare_lint! {
///
/// ### Explanation
///
/// Creating a reference to an insufficiently aligned packed field is
/// [undefined behavior] and should be disallowed.
///
/// This lint is "allow" by default because there is no stable
/// alternative, and it is not yet certain how widespread existing code
/// will trigger this lint.
///
/// See [issue #27060] for more discussion.
/// Creating a reference to an insufficiently aligned packed field is [undefined behavior] and
/// should be disallowed. Using an `unsafe` block does not change anything about this. Instead,
/// the code should do a copy of the data in the packed field or use raw pointers and unaligned
/// accesses. See [issue #82523] for more information.
///
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
/// [issue #27060]: https://github.com/rust-lang/rust/issues/27060
/// [issue #82523]: https://github.com/rust-lang/rust/issues/82523
pub UNALIGNED_REFERENCES,
Allow,
Warn,
"detects unaligned references to fields of packed structs",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #82523 <https://github.com/rust-lang/rust/issues/82523>",
edition: None,
};
report_in_external_macro
}
@ -1150,49 +1151,6 @@ declare_lint! {
"detects attempts to mutate a `const` item",
}
declare_lint! {
/// The `safe_packed_borrows` lint detects borrowing a field in the
/// interior of a packed structure with alignment other than 1.
///
/// ### Example
///
/// ```rust
/// #[repr(packed)]
/// pub struct Unaligned<T>(pub T);
///
/// pub struct Foo {
/// start: u8,
/// data: Unaligned<u32>,
/// }
///
/// fn main() {
/// let x = Foo { start: 0, data: Unaligned(1) };
/// let y = &x.data.0;
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// This type of borrow is unsafe and can cause errors on some platforms
/// and violates some assumptions made by the compiler. This was
/// previously allowed unintentionally. This is a [future-incompatible]
/// lint to transition this to a hard error in the future. See [issue
/// #46043] for more details, including guidance on how to solve the
/// problem.
///
/// [issue #46043]: https://github.com/rust-lang/rust/issues/46043
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub SAFE_PACKED_BORROWS,
Warn,
"safe borrows of fields of packed structs were erroneously allowed",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
edition: None,
};
}
declare_lint! {
/// The `patterns_in_fns_without_body` lint detects `mut` identifier
/// patterns as a parameter in functions without a body.
@ -2953,7 +2911,6 @@ declare_lint_pass! {
RENAMED_AND_REMOVED_LINTS,
UNALIGNED_REFERENCES,
CONST_ITEM_MUTATION,
SAFE_PACKED_BORROWS,
PATTERNS_IN_FNS_WITHOUT_BODY,
MISSING_FRAGMENT_SPECIFIER,
LATE_BOUND_LIFETIME_ARGUMENTS,

View File

@ -23,15 +23,9 @@ pub enum UnsafetyViolationKind {
General,
/// Permitted both in `const fn`s and regular `fn`s.
GeneralAndConstFn,
/// Borrow of packed field.
/// Has to be handled as a lint for backwards compatibility.
BorrowPacked,
/// Unsafe operation in an `unsafe fn` but outside an `unsafe` block.
/// Has to be handled as a lint for backwards compatibility.
UnsafeFn,
/// Borrow of packed field in an `unsafe fn` but outside an `unsafe` block.
/// Has to be handled as a lint for backwards compatibility.
UnsafeFnBorrowPacked,
}
#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]

View File

@ -1,11 +1,18 @@
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::UNALIGNED_REFERENCES;
use rustc_span::symbol::sym;
use crate::transform::MirPass;
use crate::util;
pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers { unsafe_derive_on_repr_packed, ..*providers };
}
pub struct CheckPackedRef;
impl<'tcx> MirPass<'tcx> for CheckPackedRef {
@ -24,6 +31,41 @@ struct PackedRefChecker<'a, 'tcx> {
source_info: SourceInfo,
}
fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let lint_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
tcx.struct_span_lint_hir(UNALIGNED_REFERENCES, lint_hir_id, tcx.def_span(def_id), |lint| {
// FIXME: when we make this a hard error, this should have its
// own error code.
let message = if tcx.generics_of(def_id).own_requires_monomorphization() {
"`#[derive]` can't be used on a `#[repr(packed)]` struct with \
type or const parameters (error E0133)"
.to_string()
} else {
"`#[derive]` can't be used on a `#[repr(packed)]` struct that \
does not derive Copy (error E0133)"
.to_string()
};
lint.build(&message).emit()
});
}
fn builtin_derive_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
debug!("builtin_derive_def_id({:?})", def_id);
if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
if tcx.has_attr(impl_def_id, sym::automatically_derived) {
debug!("builtin_derive_def_id({:?}) - is {:?}", def_id, impl_def_id);
Some(impl_def_id)
} else {
debug!("builtin_derive_def_id({:?}) - not automatically derived", def_id);
None
}
} else {
debug!("builtin_derive_def_id({:?}) - not a method", def_id);
None
}
}
impl<'a, 'tcx> Visitor<'tcx> for PackedRefChecker<'a, 'tcx> {
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
// Make sure we know where in the MIR we are.
@ -40,26 +82,33 @@ impl<'a, 'tcx> Visitor<'tcx> for PackedRefChecker<'a, 'tcx> {
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
if context.is_borrow() {
if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
let source_info = self.source_info;
let lint_root = self.body.source_scopes[source_info.scope]
.local_data
.as_ref()
.assert_crate_local()
.lint_root;
self.tcx.struct_span_lint_hir(
UNALIGNED_REFERENCES,
lint_root,
source_info.span,
|lint| {
lint.build("reference to packed field is unaligned")
.note(
"fields of packed structs are not properly aligned, and creating \
a misaligned reference is undefined behavior (even if that \
reference is never dereferenced)",
)
.emit()
},
);
let def_id = self.body.source.instance.def_id();
if let Some(impl_def_id) = builtin_derive_def_id(self.tcx, def_id) {
// If a method is defined in the local crate,
// the impl containing that method should also be.
self.tcx.ensure().unsafe_derive_on_repr_packed(impl_def_id.expect_local());
} else {
let source_info = self.source_info;
let lint_root = self.body.source_scopes[source_info.scope]
.local_data
.as_ref()
.assert_crate_local()
.lint_root;
self.tcx.struct_span_lint_hir(
UNALIGNED_REFERENCES,
lint_root,
source_info.span,
|lint| {
lint.build("reference to packed field is unaligned")
.note(
"fields of packed structs are not properly aligned, and creating \
a misaligned reference is undefined behavior (even if that \
reference is never dereferenced)",
)
.emit()
},
);
}
}
}
}

View File

@ -10,14 +10,12 @@ use rustc_middle::mir::*;
use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::{SAFE_PACKED_BORROWS, UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
use rustc_session::lint::Level;
use rustc_span::symbol::sym;
use std::ops::Bound;
use crate::const_eval::is_min_const_fn;
use crate::util;
pub struct UnsafetyChecker<'a, 'tcx> {
body: &'a Body<'tcx>,
@ -182,18 +180,6 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
self.check_mut_borrowing_layout_constrained_field(*place, context.is_mutating_use());
}
// Check for borrows to packed fields.
// `is_disaligned` already traverses the place to consider all projections after the last
// `Deref`, so this only needs to be called once at the top level.
if context.is_borrow() {
if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
self.require_unsafe(
UnsafetyViolationKind::BorrowPacked,
UnsafetyViolationDetails::BorrowOfPackedField,
);
}
}
// Some checks below need the extra metainfo of the local declaration.
let decl = &self.body.local_decls[place.local];
@ -317,25 +303,15 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
// `unsafe` blocks are required in safe code
Safety::Safe => {
for violation in violations {
let mut violation = *violation;
match violation.kind {
UnsafetyViolationKind::GeneralAndConstFn
| UnsafetyViolationKind::General => {}
UnsafetyViolationKind::BorrowPacked => {
if self.min_const_fn {
// const fns don't need to be backwards compatible and can
// emit these violations as a hard error instead of a backwards
// compat lint
violation.kind = UnsafetyViolationKind::General;
}
}
UnsafetyViolationKind::UnsafeFn
| UnsafetyViolationKind::UnsafeFnBorrowPacked => {
UnsafetyViolationKind::UnsafeFn => {
bug!("`UnsafetyViolationKind::UnsafeFn` in an `Safe` context")
}
}
if !self.violations.contains(&violation) {
self.violations.push(violation)
if !self.violations.contains(violation) {
self.violations.push(*violation)
}
}
false
@ -345,11 +321,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
for violation in violations {
let mut violation = *violation;
if violation.kind == UnsafetyViolationKind::BorrowPacked {
violation.kind = UnsafetyViolationKind::UnsafeFnBorrowPacked;
} else {
violation.kind = UnsafetyViolationKind::UnsafeFn;
}
violation.kind = UnsafetyViolationKind::UnsafeFn;
if !self.violations.contains(&violation) {
self.violations.push(violation)
}
@ -369,8 +341,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
// these unsafe things are stable in const fn
UnsafetyViolationKind::GeneralAndConstFn => {}
// these things are forbidden in const fns
UnsafetyViolationKind::General
| UnsafetyViolationKind::BorrowPacked => {
UnsafetyViolationKind::General => {
let mut violation = *violation;
// const fns don't need to be backwards compatible and can
// emit these violations as a hard error instead of a backwards
@ -380,8 +351,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
self.violations.push(violation)
}
}
UnsafetyViolationKind::UnsafeFn
| UnsafetyViolationKind::UnsafeFnBorrowPacked => bug!(
UnsafetyViolationKind::UnsafeFn => bug!(
"`UnsafetyViolationKind::UnsafeFn` in an `ExplicitUnsafe` context"
),
}
@ -464,7 +434,6 @@ pub(crate) fn provide(providers: &mut Providers) {
ty::WithOptConstParam { did, const_param_did: Some(param_did) },
)
},
unsafe_derive_on_repr_packed,
..*providers
};
}
@ -544,25 +513,6 @@ fn unsafety_check_result<'tcx>(
})
}
fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let lint_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
tcx.struct_span_lint_hir(SAFE_PACKED_BORROWS, lint_hir_id, tcx.def_span(def_id), |lint| {
// FIXME: when we make this a hard error, this should have its
// own error code.
let message = if tcx.generics_of(def_id).own_requires_monomorphization() {
"`#[derive]` can't be used on a `#[repr(packed)]` struct with \
type or const parameters (error E0133)"
.to_string()
} else {
"`#[derive]` can't be used on a `#[repr(packed)]` struct that \
does not derive Copy (error E0133)"
.to_string()
};
lint.build(&message).emit()
});
}
/// Returns the `HirId` for an enclosing scope that is also `unsafe`.
fn is_enclosed(
tcx: TyCtxt<'_>,
@ -609,22 +559,6 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, used_unsafe: &FxHashSet<hir::HirId>, id
});
}
fn builtin_derive_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
debug!("builtin_derive_def_id({:?})", def_id);
if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
if tcx.has_attr(impl_def_id, sym::automatically_derived) {
debug!("builtin_derive_def_id({:?}) - is {:?}", def_id, impl_def_id);
Some(impl_def_id)
} else {
debug!("builtin_derive_def_id({:?}) - not automatically derived", def_id);
None
}
} else {
debug!("builtin_derive_def_id({:?}) - not a method", def_id);
None
}
}
pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
debug!("check_unsafety({:?})", def_id);
@ -657,27 +591,6 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
.note(note)
.emit();
}
UnsafetyViolationKind::BorrowPacked => {
if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id.to_def_id()) {
// If a method is defined in the local crate,
// the impl containing that method should also be.
tcx.ensure().unsafe_derive_on_repr_packed(impl_def_id.expect_local());
} else {
tcx.struct_span_lint_hir(
SAFE_PACKED_BORROWS,
lint_root,
source_info.span,
|lint| {
lint.build(&format!(
"{} is unsafe and requires unsafe{} block (error E0133)",
description, unsafe_fn_msg,
))
.note(note)
.emit()
},
)
}
}
UnsafetyViolationKind::UnsafeFn => tcx.struct_span_lint_hir(
UNSAFE_OP_IN_UNSAFE_FN,
lint_root,
@ -692,35 +605,6 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
.emit();
},
),
UnsafetyViolationKind::UnsafeFnBorrowPacked => {
// When `unsafe_op_in_unsafe_fn` is disallowed, the behavior of safe and unsafe functions
// should be the same in terms of warnings and errors. Therefore, with `#[warn(safe_packed_borrows)]`,
// a safe packed borrow should emit a warning *but not an error* in an unsafe function,
// just like in a safe function, even if `unsafe_op_in_unsafe_fn` is `deny`.
//
// Also, `#[warn(unsafe_op_in_unsafe_fn)]` can't cause any new errors. Therefore, with
// `#[deny(safe_packed_borrows)]` and `#[warn(unsafe_op_in_unsafe_fn)]`, a packed borrow
// should only issue a warning for the sake of backwards compatibility.
//
// The solution those 2 expectations is to always take the minimum of both lints.
// This prevent any new errors (unless both lints are explicitly set to `deny`).
let lint = if tcx.lint_level_at_node(SAFE_PACKED_BORROWS, lint_root).0
<= tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, lint_root).0
{
SAFE_PACKED_BORROWS
} else {
UNSAFE_OP_IN_UNSAFE_FN
};
tcx.struct_span_lint_hir(&lint, lint_root, source_info.span, |lint| {
lint.build(&format!(
"{} is unsafe and requires unsafe block (error E0133)",
description,
))
.span_label(source_info.span, description)
.note(note)
.emit();
})
}
}
}

View File

@ -59,6 +59,7 @@ pub use rustc_middle::mir::MirSource;
pub(crate) fn provide(providers: &mut Providers) {
self::check_unsafety::provide(providers);
self::check_packed_ref::provide(providers);
*providers = Providers {
mir_keys,
mir_const,

View File

@ -767,6 +767,7 @@ pub const unsafe fn read<T>(src: *const T) -> T {
/// unaligned: 0x01020304,
/// };
///
/// #[allow(unaligned_references)]
/// let v = unsafe {
/// // Here we attempt to take the address of a 32-bit integer which is not aligned.
/// let unaligned =
@ -960,6 +961,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
/// let v = 0x01020304;
/// let mut packed: Packed = unsafe { std::mem::zeroed() };
///
/// #[allow(unaligned_references)]
/// let v = unsafe {
/// // Here we attempt to take the address of a 32-bit integer which is not aligned.
/// let unaligned =

View File

@ -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 E0133
let _ = &p.b; //~ WARN 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 E0133
let (_,) = (&p.b,); //~ WARN reference to packed field
//~^ WARN will become a hard error
let (_,) = (u1.a,); //~ ERROR [E0133]
let (_,) = (&u2.a,); //~ ERROR [E0133]
@ -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 E0133
match &p.b { _ => { } } //~ WARN 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 E0133
match (&p.b,) { (_,) => { } } //~ WARN reference to packed field
//~^ WARN will become a hard error
match (u1.a,) { (_,) => { } } //~ ERROR [E0133]
match (&u2.a,) { (_,) => { } } //~ ERROR [E0133]

View File

@ -1,13 +1,43 @@
warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
warning: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:23:13
|
LL | let _ = &p.b;
| ^^^^
|
= note: `#[warn(safe_packed_borrows)]` on by default
= note: `#[warn(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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
= 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)
warning: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:29:17
|
LL | let (_,) = (&p.b,);
| ^^^^
|
= 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)
warning: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:39:11
|
LL | match &p.b { _ => { } }
| ^^^^
|
= 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)
warning: reference to packed field is unaligned
--> $DIR/issue-53114-safety-checks.rs:45:12
|
LL | match (&p.b,) { (_,) => { } }
| ^^^^
|
= 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)
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/issue-53114-safety-checks.rs:26:13
@ -17,16 +47,6 @@ LL | let _ = &u2.a;
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
--> $DIR/issue-53114-safety-checks.rs:29:17
|
LL | let (_,) = (&p.b,);
| ^^^^
|
= 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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/issue-53114-safety-checks.rs:31:17
|
@ -43,16 +63,6 @@ LL | let (_,) = (&u2.a,);
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
--> $DIR/issue-53114-safety-checks.rs:39:11
|
LL | match &p.b { _ => { } }
| ^^^^
|
= 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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/issue-53114-safety-checks.rs:41:11
|
@ -69,16 +79,6 @@ LL | match &u2.a { _ => { } }
|
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
--> $DIR/issue-53114-safety-checks.rs:45:12
|
LL | match (&p.b,) { (_,) => { } }
| ^^^^
|
= 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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
error[E0133]: access to union field is unsafe and requires unsafe function or block
--> $DIR/issue-53114-safety-checks.rs:47:12
|

View File

@ -23,7 +23,7 @@ fn test_missing_unsafe_warning_on_repr_packed() {
let c = || {
println!("{}", foo.x);
//~^ WARNING: borrow of packed field is unsafe and requires unsafe function or block
//~^ WARNING: reference to packed field is unaligned
//~| WARNING: this was previously accepted by the compiler but is being phased out
let _z = foo.x;
};

View File

@ -7,16 +7,16 @@ LL | #![feature(capture_disjoint_fields)]
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
warning: reference to packed field is unaligned
--> $DIR/repr_packed.rs:25:24
|
LL | println!("{}", foo.x);
| ^^^^^
|
= note: `#[warn(safe_packed_borrows)]` on by default
= note: `#[warn(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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
= 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)
warning: 2 warnings emitted

View File

@ -1,4 +1,4 @@
#![deny(safe_packed_borrows)]
#![deny(unaligned_references)]
// check that derive on a packed struct with non-Copy fields
// correctly. This can't be made to work perfectly because

View File

@ -7,10 +7,10 @@ LL | #[derive(Copy, Clone, PartialEq, Eq)]
note: the lint level is defined here
--> $DIR/deriving-with-repr-packed.rs:1:9
|
LL | #![deny(safe_packed_borrows)]
| ^^^^^^^^^^^^^^^^^^^
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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133)
@ -20,7 +20,7 @@ LL | #[derive(Copy, Clone, PartialEq, Eq)]
| ^^^^^^^^^
|
= 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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133)
@ -30,7 +30,7 @@ LL | #[derive(PartialEq, Eq)]
| ^^^^^^^^^
|
= 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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133)
@ -40,7 +40,7 @@ LL | #[derive(PartialEq)]
| ^^^^^^^^^
|
= 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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 4 previous errors

View File

@ -8,14 +8,12 @@ pub struct Good {
}
// kill this test when that turns to a hard error
#[allow(safe_packed_borrows)]
#[allow(unaligned_references)]
fn main() {
let good = Good { data: &0, data2: [&0, &0], aligned: [0; 32] };
unsafe {
let _ = &good.data; // ok
let _ = &good.data2[0]; // ok
}
let _ = &good.data; // ok
let _ = &good.data2[0]; // ok
let _ = &good.data;
let _ = &good.data2[0];

View File

@ -5,7 +5,7 @@ pub struct Good {
aligned: [u8; 32],
}
#[deny(safe_packed_borrows)]
#[deny(unaligned_references)]
fn main() {
let good = Good {
data: &0,
@ -13,14 +13,14 @@ fn main() {
aligned: [0; 32]
};
unsafe {
let _ = &good.data; // ok
let _ = &good.data2[0]; // ok
}
let _ = &good.data; //~ ERROR reference to packed field
//~| hard error
let _ = &good.data2[0]; //~ ERROR reference to packed field
//~| hard error
let _ = &good.data; //~ ERROR borrow of packed field is unsafe
let _ = &good.data; //~ ERROR reference to packed field
//~| hard error
let _ = &good.data2[0]; //~ ERROR borrow of packed field is unsafe
let _ = &good.data2[0]; //~ ERROR reference to packed field
//~| hard error
let _ = &*good.data; // ok, behind a pointer
let _ = &good.aligned; // ok, has align 1

View File

@ -1,5 +1,5 @@
error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
--> $DIR/issue-27060.rs:21:13
error: reference to packed field is unaligned
--> $DIR/issue-27060.rs:16:13
|
LL | let _ = &good.data;
| ^^^^^^^^^^
@ -7,21 +7,41 @@ LL | let _ = &good.data;
note: the lint level is defined here
--> $DIR/issue-27060.rs:8:8
|
LL | #[deny(safe_packed_borrows)]
| ^^^^^^^^^^^^^^^^^^^
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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
= 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)
error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
error: reference to packed field is unaligned
--> $DIR/issue-27060.rs:18:13
|
LL | let _ = &good.data2[0];
| ^^^^^^^^^^^^^^
|
= 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)
error: reference to packed field is unaligned
--> $DIR/issue-27060.rs:21:13
|
LL | let _ = &good.data;
| ^^^^^^^^^^
|
= 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)
error: reference to packed field is unaligned
--> $DIR/issue-27060.rs:23:13
|
LL | let _ = &good.data2[0];
| ^^^^^^^^^^^^^^
|
= 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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
= 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)
error: aborting due to 2 previous errors
error: aborting due to 4 previous errors

View File

@ -13,14 +13,20 @@ fn main() {
let good = Good { data: 0, ptr: &0, data2: [0, 0], aligned: [0; 32] };
let _ = &good.ptr; //~ ERROR reference to packed field
//~^ previously accepted
let _ = &good.data; //~ ERROR reference to packed field
//~^ previously accepted
// Error even when turned into raw pointer immediately.
let _ = &good.data as *const _; //~ ERROR reference to packed field
//~^ previously accepted
let _: *const _ = &good.data; //~ ERROR reference to packed field
//~^ previously accepted
// Error on method call.
let _ = good.data.clone(); //~ ERROR reference to packed field
//~^ previously accepted
// Error for nested fields.
let _ = &good.data2[0]; //~ ERROR reference to packed field
//~^ previously accepted
let _ = &*good.ptr; // ok, behind a pointer
let _ = &good.aligned; // ok, has align 1

View File

@ -9,46 +9,58 @@ note: the lint level is defined here
|
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: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
error: reference to packed field is unaligned
--> $DIR/unaligned_references.rs:16:17
--> $DIR/unaligned_references.rs:17:17
|
LL | let _ = &good.data;
| ^^^^^^^^^^
|
= 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)
error: reference to packed field is unaligned
--> $DIR/unaligned_references.rs:18:17
--> $DIR/unaligned_references.rs:20:17
|
LL | let _ = &good.data as *const _;
| ^^^^^^^^^^
|
= 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)
error: reference to packed field is unaligned
--> $DIR/unaligned_references.rs:19:27
--> $DIR/unaligned_references.rs:22:27
|
LL | let _: *const _ = &good.data;
| ^^^^^^^^^^
|
= 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)
error: reference to packed field is unaligned
--> $DIR/unaligned_references.rs:21:17
--> $DIR/unaligned_references.rs:25:17
|
LL | let _ = good.data.clone();
| ^^^^^^^^^
|
= 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)
error: reference to packed field is unaligned
--> $DIR/unaligned_references.rs:23:17
--> $DIR/unaligned_references.rs:28:17
|
LL | let _ = &good.data2[0];
| ^^^^^^^^^^^^^^
|
= 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)
error: aborting due to 6 previous errors

View File

@ -1,10 +1,9 @@
// aux-build:unaligned_references_external_crate.rs
#![allow(safe_packed_borrows)]
extern crate unaligned_references_external_crate;
unaligned_references_external_crate::mac! { //~ERROR reference to packed field is unaligned
//~^ previously accepted
#[repr(packed)]
pub struct X {
pub field: u16

View File

@ -1,7 +1,8 @@
error: reference to packed field is unaligned
--> $DIR/unaligned_references_external_macro.rs:7:1
--> $DIR/unaligned_references_external_macro.rs:5:1
|
LL | / unaligned_references_external_crate::mac! {
LL | |
LL | | #[repr(packed)]
LL | | pub struct X {
LL | | pub field: u16
@ -10,15 +11,18 @@ LL | | }
| |_^
|
note: the lint level is defined here
--> $DIR/unaligned_references_external_macro.rs:7:1
--> $DIR/unaligned_references_external_macro.rs:5:1
|
LL | / unaligned_references_external_crate::mac! {
LL | |
LL | | #[repr(packed)]
LL | | pub struct X {
LL | | pub field: u16
LL | | }
LL | | }
| |_^
= 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)
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@ -1,6 +1,6 @@
// run-pass
#![allow(dead_code)]
#![deny(safe_packed_borrows)]
#![deny(unaligned_references)]
#![feature(raw_ref_op)]
// ignore-emscripten weird assertion?

View File

@ -22,14 +22,17 @@ struct Foo4C {
pub fn main() {
let foo = Foo1 { bar: 1, baz: 2 };
let brw = unsafe { &foo.baz };
let brw = &foo.baz; //~WARN reference to packed field is unaligned
//~^ previously accepted
assert_eq!(*brw, 2);
let foo = Foo2 { bar: 1, baz: 2 };
let brw = unsafe { &foo.baz };
let brw = &foo.baz; //~WARN reference to packed field is unaligned
//~^ previously accepted
assert_eq!(*brw, 2);
let foo = Foo4C { bar: 1, baz: 2 };
let brw = unsafe { &foo.baz };
let brw = &foo.baz; //~WARN reference to packed field is unaligned
//~^ previously accepted
assert_eq!(*brw, 2);
}

View File

@ -0,0 +1,33 @@
warning: reference to packed field is unaligned
--> $DIR/packed-struct-borrow-element.rs:25:15
|
LL | let brw = &foo.baz;
| ^^^^^^^^
|
= note: `#[warn(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)
warning: reference to packed field is unaligned
--> $DIR/packed-struct-borrow-element.rs:30:15
|
LL | let brw = &foo.baz;
| ^^^^^^^^
|
= 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)
warning: reference to packed field is unaligned
--> $DIR/packed-struct-borrow-element.rs:35:15
|
LL | let brw = &foo.baz;
| ^^^^^^^^
|
= 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)
warning: 3 warnings emitted

View File

@ -1,67 +0,0 @@
#![feature(unsafe_block_in_unsafe_fn)]
#[repr(packed)]
pub struct Packed {
data: &'static u32,
}
const PACKED: Packed = Packed { data: &0 };
#[allow(safe_packed_borrows)]
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn allow_allow() {
&PACKED.data; // allowed
}
#[allow(safe_packed_borrows)]
#[warn(unsafe_op_in_unsafe_fn)]
unsafe fn allow_warn() {
&PACKED.data; // allowed
}
#[allow(safe_packed_borrows)]
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn allow_deny() {
&PACKED.data; // allowed
}
#[warn(safe_packed_borrows)]
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn warn_allow() {
&PACKED.data; // allowed
}
#[warn(safe_packed_borrows)]
#[warn(unsafe_op_in_unsafe_fn)]
unsafe fn warn_warn() {
&PACKED.data; //~ WARN
//~| WARNING this was previously accepted by the compiler but is being phased out
}
#[warn(safe_packed_borrows)]
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn warn_deny() {
&PACKED.data; //~ WARN
//~| WARNING this was previously accepted by the compiler but is being phased out
}
#[deny(safe_packed_borrows)]
#[allow(unsafe_op_in_unsafe_fn)]
unsafe fn deny_allow() {
&PACKED.data; // allowed
}
#[deny(safe_packed_borrows)]
#[warn(unsafe_op_in_unsafe_fn)]
unsafe fn deny_warn() {
&PACKED.data; //~ WARN
}
#[deny(safe_packed_borrows)]
#[deny(unsafe_op_in_unsafe_fn)]
unsafe fn deny_deny() {
&PACKED.data; //~ ERROR
//~| WARNING this was previously accepted by the compiler but is being phased out
}
fn main() {}

View File

@ -1,60 +0,0 @@
warning: borrow of packed field is unsafe and requires unsafe block (error E0133)
--> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:37:5
|
LL | &PACKED.data;
| ^^^^^^^^^^^^ borrow of packed field
|
note: the lint level is defined here
--> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:34:8
|
LL | #[warn(safe_packed_borrows)]
| ^^^^^^^^^^^^^^^^^^^
= 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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
warning: borrow of packed field is unsafe and requires unsafe block (error E0133)
--> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:44:5
|
LL | &PACKED.data;
| ^^^^^^^^^^^^ borrow of packed field
|
note: the lint level is defined here
--> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:41:8
|
LL | #[warn(safe_packed_borrows)]
| ^^^^^^^^^^^^^^^^^^^
= 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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
warning: borrow of packed field is unsafe and requires unsafe block (error E0133)
--> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:57:5
|
LL | &PACKED.data;
| ^^^^^^^^^^^^ borrow of packed field
|
note: the lint level is defined here
--> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:55:8
|
LL | #[warn(unsafe_op_in_unsafe_fn)]
| ^^^^^^^^^^^^^^^^^^^^^^
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
error: borrow of packed field is unsafe and requires unsafe block (error E0133)
--> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:63:5
|
LL | &PACKED.data;
| ^^^^^^^^^^^^ borrow of packed field
|
note: the lint level is defined here
--> $DIR/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs:60:8
|
LL | #[deny(safe_packed_borrows)]
| ^^^^^^^^^^^^^^^^^^^
= 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 #46043 <https://github.com/rust-lang/rust/issues/46043>
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
error: aborting due to previous error; 3 warnings emitted