mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
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:
commit
a900677eb9
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)]
|
||||
|
@ -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()
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 =
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
#![deny(safe_packed_borrows)]
|
||||
#![deny(unaligned_references)]
|
||||
#![feature(raw_ref_op)]
|
||||
// ignore-emscripten weird assertion?
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
33
src/test/ui/packed/packed-struct-borrow-element.stderr
Normal file
33
src/test/ui/packed/packed-struct-borrow-element.stderr
Normal 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
|
||||
|
@ -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() {}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user