mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
strip readonly/captures from MaybeDangling<&T>
This commit is contained in:
@@ -2153,18 +2153,14 @@ pub enum PointerKind {
|
||||
pub struct PointeeInfo {
|
||||
/// If this is `None`, then this is a raw pointer.
|
||||
pub safe: Option<PointerKind>,
|
||||
/// If this is true, the pointer is wrapped in `MaybeDangling` and thus can't be assumed to
|
||||
/// not alias. Having this as separate state from `safe: None` allows us to keep `readonly` and
|
||||
/// `captures(address, read_provenance)` llvm attributes.
|
||||
pub may_dangle: bool,
|
||||
/// If `size` is not zero, then the pointer is either null or dereferenceable for this many bytes
|
||||
/// (independent of `safe` and `may_dangle`).
|
||||
/// (independent of `safe`).
|
||||
///
|
||||
/// On a function argument, "dereferenceable" here means "dereferenceable for the entire duration
|
||||
/// of this function call", i.e. it is UB for the memory that this pointer points to be freed
|
||||
/// while this function is still running.
|
||||
pub size: Size,
|
||||
/// The pointer is guaranteed to be aligned this much (independent of `safe` and `may_dangle`).
|
||||
/// The pointer is guaranteed to be aligned this much (independent of `safe`).
|
||||
pub align: Align,
|
||||
}
|
||||
|
||||
|
||||
@@ -1028,12 +1028,9 @@ fn ty_and_layout_pointee_info_at(
|
||||
let optimize = tcx.sess.opts.optimize != OptLevel::No;
|
||||
|
||||
let pointee_info = match *this.ty.kind() {
|
||||
ty::RawPtr(_, _) | ty::FnPtr(..) if offset.bytes() == 0 => Some(PointeeInfo {
|
||||
safe: None,
|
||||
size: Size::ZERO,
|
||||
align: Align::ONE,
|
||||
may_dangle: false,
|
||||
}),
|
||||
ty::RawPtr(_, _) | ty::FnPtr(..) if offset.bytes() == 0 => {
|
||||
Some(PointeeInfo { safe: None, size: Size::ZERO, align: Align::ONE })
|
||||
}
|
||||
ty::Ref(_, ty, mt) if offset.bytes() == 0 => {
|
||||
tcx.layout_of(typing_env.as_query_input(ty)).ok().map(|layout| {
|
||||
let (size, kind);
|
||||
@@ -1062,12 +1059,7 @@ fn ty_and_layout_pointee_info_at(
|
||||
kind = PointerKind::MutableRef { unpin };
|
||||
}
|
||||
};
|
||||
PointeeInfo {
|
||||
safe: Some(kind),
|
||||
size,
|
||||
align: layout.align.abi,
|
||||
may_dangle: false,
|
||||
}
|
||||
PointeeInfo { safe: Some(kind), size, align: layout.align.abi }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1090,20 +1082,19 @@ fn ty_and_layout_pointee_info_at(
|
||||
size: Size::ZERO,
|
||||
|
||||
align: layout.align.abi,
|
||||
may_dangle: false,
|
||||
})
|
||||
}
|
||||
|
||||
ty::Adt(adt_def, ..) if adt_def.is_maybe_dangling() => {
|
||||
Self::ty_and_layout_pointee_info_at(this.field(cx, 0), cx, offset).map(|info| {
|
||||
PointeeInfo {
|
||||
// Mark the pointer as possibly dangling
|
||||
// (thus removing noalias in case of llvm backend)
|
||||
may_dangle: true,
|
||||
// Mark the pointer as raw
|
||||
// (thus removing noalias/readonly/etc in case of the llvm backend)
|
||||
safe: None,
|
||||
// Make sure we don't assert dereferenceability of the pointer.
|
||||
size: Size::ZERO,
|
||||
// Preserve the alignment assertion! That is required even inside `MaybeDangling`.
|
||||
..info
|
||||
align: info.align,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -351,12 +351,11 @@ fn arg_attrs_for_rust_scalar<'tcx>(
|
||||
// not return values.
|
||||
//
|
||||
// `&mut T` and `Box<T>` where `T: Unpin` are unique and hence `noalias`.
|
||||
let no_alias = !pointee.may_dangle
|
||||
&& match kind {
|
||||
PointerKind::SharedRef { frozen } => frozen,
|
||||
PointerKind::MutableRef { unpin } => unpin && noalias_mut_ref,
|
||||
PointerKind::Box { unpin, global } => unpin && global && noalias_for_box,
|
||||
};
|
||||
let no_alias = match kind {
|
||||
PointerKind::SharedRef { frozen } => frozen,
|
||||
PointerKind::MutableRef { unpin } => unpin && noalias_mut_ref,
|
||||
PointerKind::Box { unpin, global } => unpin && global && noalias_for_box,
|
||||
};
|
||||
// We can never add `noalias` in return position; that LLVM attribute has some very surprising semantics
|
||||
// (see <https://github.com/rust-lang/unsafe-code-guidelines/issues/385#issuecomment-1368055745>).
|
||||
if no_alias && !is_return {
|
||||
|
||||
@@ -15,7 +15,7 @@ pub fn f(x: MaybeDangling<Box<u8>>) -> MaybeDangling<Box<u8>> {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: define {{(dso_local )?}}noundef nonnull ptr @g(ptr noundef nonnull readonly captures(address, read_provenance) %x) unnamed_addr
|
||||
// CHECK: define {{(dso_local )?}}noundef nonnull ptr @g(ptr noundef nonnull %x) unnamed_addr
|
||||
#[no_mangle]
|
||||
pub fn g(x: MaybeDangling<&u8>) -> MaybeDangling<&u8> {
|
||||
x
|
||||
@@ -33,7 +33,7 @@ pub fn i(x: MaybeDangling<Box<u32>>) -> MaybeDangling<Box<u32>> {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: define {{(dso_local )?}}noundef nonnull align 4 ptr @j(ptr noundef nonnull readonly align 4 captures(address, read_provenance) %x) unnamed_addr
|
||||
// CHECK: define {{(dso_local )?}}noundef nonnull align 4 ptr @j(ptr noundef nonnull align 4 %x) unnamed_addr
|
||||
#[no_mangle]
|
||||
pub fn j(x: MaybeDangling<&u32>) -> MaybeDangling<&u32> {
|
||||
x
|
||||
|
||||
Reference in New Issue
Block a user