diff options
| -rw-r--r-- | compiler/rustc_lint/src/lints.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/transmute.rs | 30 | ||||
| -rw-r--r-- | tests/ui/lint/int_to_ptr-unsized.rs | 23 | ||||
| -rw-r--r-- | tests/ui/lint/int_to_ptr-unsized.stderr | 27 |
4 files changed, 69 insertions, 13 deletions
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 426500dda4a..56d65ed08f9 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1554,7 +1554,7 @@ impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> { #[help(lint_help_exposed_provenance)] pub(crate) struct IntegerToPtrTransmutes<'tcx> { #[subdiagnostic] - pub suggestion: IntegerToPtrTransmutesSuggestion<'tcx>, + pub suggestion: Option<IntegerToPtrTransmutesSuggestion<'tcx>>, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_lint/src/transmute.rs b/compiler/rustc_lint/src/transmute.rs index 239c8649041..98510eea73b 100644 --- a/compiler/rustc_lint/src/transmute.rs +++ b/compiler/rustc_lint/src/transmute.rs @@ -169,19 +169,25 @@ fn check_int_to_ptr_transmute<'tcx>( expr.hir_id, expr.span, IntegerToPtrTransmutes { - suggestion: if dst.is_ref() { - IntegerToPtrTransmutesSuggestion::ToRef { - dst: *inner_ty, - suffix, - ref_mutbl: mutbl.prefix_str(), - start_call: expr.span.shrink_to_lo().until(arg.span), - } + suggestion: if layout_inner_ty.is_sized() { + Some(if dst.is_ref() { + IntegerToPtrTransmutesSuggestion::ToRef { + dst: *inner_ty, + suffix, + ref_mutbl: mutbl.prefix_str(), + start_call: expr.span.shrink_to_lo().until(arg.span), + } + } else { + IntegerToPtrTransmutesSuggestion::ToPtr { + dst: *inner_ty, + suffix, + start_call: expr.span.shrink_to_lo().until(arg.span), + } + }) } else { - IntegerToPtrTransmutesSuggestion::ToPtr { - dst: *inner_ty, - suffix, - start_call: expr.span.shrink_to_lo().until(arg.span), - } + // We can't suggest using `with_exposed_provenance` for unsized type + // so don't suggest anything. + None }, }, ); diff --git a/tests/ui/lint/int_to_ptr-unsized.rs b/tests/ui/lint/int_to_ptr-unsized.rs new file mode 100644 index 00000000000..bbdc2474561 --- /dev/null +++ b/tests/ui/lint/int_to_ptr-unsized.rs @@ -0,0 +1,23 @@ +// Checks for the `integer_to_pointer_transmutes` lint with unsized types +// +// Related to https://github.com/rust-lang/rust/issues/145935 + +//@ check-pass + +#![allow(non_camel_case_types)] +#![allow(unused_unsafe)] + +#[cfg(target_pointer_width = "64")] +type usizemetadata = i128; + +#[cfg(target_pointer_width = "32")] +type usizemetadata = i64; + +unsafe fn unsized_type(a: usize) { + let _ref = unsafe { std::mem::transmute::<usizemetadata, &'static str>(0xff) }; + //~^ WARN transmuting an integer to a pointer + let _ptr = unsafe { std::mem::transmute::<usizemetadata, *const [u8]>(0xff) }; + //~^ WARN transmuting an integer to a pointer +} + +fn main() {} diff --git a/tests/ui/lint/int_to_ptr-unsized.stderr b/tests/ui/lint/int_to_ptr-unsized.stderr new file mode 100644 index 00000000000..9799af8b12c --- /dev/null +++ b/tests/ui/lint/int_to_ptr-unsized.stderr @@ -0,0 +1,27 @@ +warning: transmuting an integer to a pointer creates a pointer without provenance + --> $DIR/int_to_ptr-unsized.rs:17:25 + | +LL | let _ref = unsafe { std::mem::transmute::<usizemetadata, &'static str>(0xff) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this is dangerous because dereferencing the resulting pointer is undefined behavior + = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance + = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut` + = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers> + = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance> + = note: `#[warn(integer_to_ptr_transmutes)]` on by default + +warning: transmuting an integer to a pointer creates a pointer without provenance + --> $DIR/int_to_ptr-unsized.rs:19:25 + | +LL | let _ptr = unsafe { std::mem::transmute::<usizemetadata, *const [u8]>(0xff) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this is dangerous because dereferencing the resulting pointer is undefined behavior + = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance + = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut` + = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers> + = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance> + +warning: 2 warnings emitted + |
