Skip to content

Commit dba6102

Browse files
committed
Make the alignment intrinsics return ptr::Alignment
1 parent eb25fe3 commit dba6102

38 files changed

Lines changed: 317 additions & 379 deletions

File tree

compiler/rustc_codegen_cranelift/example/mini_core.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,12 @@ pub union MaybeUninit<T> {
686686
pub value: ManuallyDrop<T>,
687687
}
688688

689+
pub mod mem {
690+
#[lang = "Alignment"]
691+
#[repr(transparent)]
692+
pub struct Alignment(pub usize);
693+
}
694+
689695
pub mod intrinsics {
690696
#[rustc_intrinsic]
691697
pub fn abort() -> !;
@@ -694,9 +700,9 @@ pub mod intrinsics {
694700
#[rustc_intrinsic]
695701
pub unsafe fn size_of_val<T: ?crate::Sized>(val: *const T) -> usize;
696702
#[rustc_intrinsic]
697-
pub const fn align_of<T>() -> usize;
703+
pub const fn align_of<T>() -> crate::mem::Alignment;
698704
#[rustc_intrinsic]
699-
pub unsafe fn align_of_val<T: ?crate::Sized>(val: *const T) -> usize;
705+
pub unsafe fn align_of_val<T: ?crate::Sized>(val: *const T) -> crate::mem::Alignment;
700706
#[rustc_intrinsic]
701707
pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize);
702708
#[rustc_intrinsic]
@@ -764,15 +770,15 @@ pub const fn size_of<T>() -> usize {
764770
}
765771

766772
pub const fn align_of<T>() -> usize {
767-
<T as SizedTypeProperties>::ALIGN
773+
<T as SizedTypeProperties>::ALIGN.0
768774
}
769775

770776
trait SizedTypeProperties: Sized {
771777
#[lang = "mem_size_const"]
772778
const SIZE: usize = intrinsics::size_of::<Self>();
773779

774780
#[lang = "mem_align_const"]
775-
const ALIGN: usize = intrinsics::align_of::<Self>();
781+
const ALIGN: crate::mem::Alignment = intrinsics::align_of::<Self>();
776782
}
777783
impl<T> SizedTypeProperties for T {}
778784

compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ fn main() {
220220
assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);
221221

222222
assert_eq!(align_of::<u16>() as u8, 2);
223-
assert_eq!(intrinsics::align_of_val(&a) as u8, align_of::<&str>() as u8);
223+
assert_eq!(intrinsics::align_of_val(&a).0 as u8, align_of::<&str>() as u8);
224224

225225
let u8_needs_drop = const { intrinsics::needs_drop::<u8>() };
226226
assert!(!u8_needs_drop);

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,8 @@ fn codegen_regular_intrinsic_call<'tcx>(
592592
None
593593
};
594594
let (_size, align) = crate::unsize::size_and_align_of(fx, layout, meta);
595-
ret.write_cvalue(fx, CValue::by_val(align, usize_layout));
595+
let alignment_layout = fx.layout_of(fx.tcx.ty_alignment(source_info.span));
596+
ret.write_cvalue(fx, CValue::by_val(align, alignment_layout));
596597
}
597598

598599
sym::vtable_size => {

compiler/rustc_codegen_gcc/example/mini_core.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,12 @@ pub union MaybeUninit<T> {
694694
pub value: ManuallyDrop<T>,
695695
}
696696

697+
pub mod mem {
698+
#[lang = "Alignment"]
699+
#[repr(transparent)]
700+
pub struct Alignment(pub usize);
701+
}
702+
697703
pub mod intrinsics {
698704
#[rustc_intrinsic]
699705
pub const fn black_box<T>(_dummy: T) -> T;
@@ -704,9 +710,9 @@ pub mod intrinsics {
704710
#[rustc_intrinsic]
705711
pub unsafe fn size_of_val<T: ?::Sized>(val: *const T) -> usize;
706712
#[rustc_intrinsic]
707-
pub const fn align_of<T>() -> usize;
713+
pub const fn align_of<T>() -> crate::mem::Alignment;
708714
#[rustc_intrinsic]
709-
pub unsafe fn align_of_val<T: ?::Sized>(val: *const T) -> usize;
715+
pub unsafe fn align_of_val<T: ?::Sized>(val: *const T) -> crate::mem::Alignment;
710716
#[rustc_intrinsic]
711717
pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize);
712718
#[rustc_intrinsic]
@@ -747,15 +753,15 @@ pub const fn size_of<T>() -> usize {
747753
}
748754

749755
pub const fn align_of<T>() -> usize {
750-
<T as SizedTypeProperties>::ALIGN
756+
<T as SizedTypeProperties>::ALIGN.0
751757
}
752758

753759
trait SizedTypeProperties: Sized {
754760
#[lang = "mem_size_const"]
755761
const SIZE: usize = intrinsics::size_of::<Self>();
756762

757763
#[lang = "mem_align_const"]
758-
const ALIGN: usize = intrinsics::align_of::<Self>();
764+
const ALIGN: crate::mem::Alignment = intrinsics::align_of::<Self>();
759765
}
760766

761767
impl<T> SizedTypeProperties for T {}

compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ fn main() {
196196
assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);
197197

198198
assert_eq!(align_of::<u16>() as u8, 2);
199-
assert_eq!(intrinsics::align_of_val(&a) as u8, align_of::<&str>() as u8);
199+
assert_eq!(intrinsics::align_of_val(&a).0 as u8, align_of::<&str>() as u8);
200200

201201
let u8_needs_drop = const { intrinsics::needs_drop::<u8>() };
202202
assert!(!u8_needs_drop);

compiler/rustc_hir/src/lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ language_item_table! {
156156
MetaSized, sym::meta_sized, meta_sized_trait, Target::Trait, GenericRequirement::Exact(0);
157157
PointeeSized, sym::pointee_sized, pointee_sized_trait, Target::Trait, GenericRequirement::Exact(0);
158158
Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1);
159+
Alignment, sym::Alignment, alignment_type, Target::Struct, GenericRequirement::Exact(0);
159160
AlignOf, sym::mem_align_const, align_const, Target::AssocConst, GenericRequirement::Exact(0);
160161
SizeOf, sym::mem_size_const, size_const, Target::AssocConst, GenericRequirement::Exact(0);
161162
OffsetOf, sym::offset_of, offset_of, Target::Fn, GenericRequirement::Exact(1);

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,10 +292,10 @@ pub(crate) fn check_intrinsic_type(
292292
sym::amdgpu_dispatch_ptr => (0, 0, vec![], Ty::new_imm_ptr(tcx, tcx.types.unit)),
293293
sym::unreachable => (0, 0, vec![], tcx.types.never),
294294
sym::breakpoint => (0, 0, vec![], tcx.types.unit),
295-
sym::size_of | sym::align_of | sym::variant_count => (1, 0, vec![], tcx.types.usize),
296-
sym::size_of_val | sym::align_of_val => {
297-
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
298-
}
295+
sym::size_of | sym::variant_count => (1, 0, vec![], tcx.types.usize),
296+
sym::align_of => (1, 0, vec![], tcx.ty_alignment(span)),
297+
sym::size_of_val => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize),
298+
sym::align_of_val => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.ty_alignment(span)),
299299
sym::size_of_type_id => (0, 0, vec![type_id_ty()], Ty::new_option(tcx, tcx.types.usize)),
300300
sym::offset_of => (1, 0, vec![tcx.types.u32, tcx.types.u32], tcx.types.usize),
301301
sym::field_offset => (1, 0, vec![], tcx.types.usize),

compiler/rustc_middle/src/ty/context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,13 @@ impl<'tcx> TyCtxt<'tcx> {
979979
self.type_of(ordering_enum).no_bound_vars().unwrap()
980980
}
981981

982+
/// Gets a `Ty` representing the [`LangItem::Alignment`]
983+
#[track_caller]
984+
pub fn ty_alignment(self, span: Span) -> Ty<'tcx> {
985+
let alignment = self.require_lang_item(hir::LangItem::Alignment, span);
986+
self.type_of(alignment).no_bound_vars().unwrap()
987+
}
988+
982989
/// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
983990
/// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
984991
pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {

compiler/rustc_mir_transform/src/check_alignment.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,23 @@ fn insert_alignment_check<'tcx>(
5555
stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((thin_ptr, rvalue)))));
5656

5757
// Transmute the pointer to a usize (equivalent to `ptr.addr()`).
58-
let rvalue = Rvalue::Cast(CastKind::Transmute, Operand::Copy(thin_ptr), tcx.types.usize);
58+
let rvalue = Rvalue::Cast(CastKind::Transmute, Operand::Move(thin_ptr), tcx.types.usize);
5959
let addr = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
6060
stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((addr, rvalue)))));
6161

6262
// Get the alignment of the pointee
6363
let align_def_id = tcx.require_lang_item(LangItem::AlignOf, source_info.span);
64+
let alignment_usize =
65+
local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
6466
let alignment =
6567
Operand::unevaluated_constant(tcx, align_def_id, &[pointee_ty.into()], source_info.span);
68+
stmts.push(Statement::new(
69+
source_info,
70+
StatementKind::Assign(Box::new((
71+
alignment_usize,
72+
Rvalue::Cast(CastKind::Transmute, alignment.clone(), tcx.types.usize),
73+
))),
74+
));
6675

6776
// Subtract 1 from the alignment to get the alignment mask
6877
let alignment_mask =
@@ -76,7 +85,7 @@ fn insert_alignment_check<'tcx>(
7685
source_info,
7786
StatementKind::Assign(Box::new((
7887
alignment_mask,
79-
Rvalue::BinaryOp(BinOp::Sub, Box::new((alignment.clone(), one))),
88+
Rvalue::BinaryOp(BinOp::SubUnchecked, Box::new((Operand::Move(alignment_usize), one))),
8089
))),
8190
));
8291

@@ -138,10 +147,10 @@ fn insert_alignment_check<'tcx>(
138147
// Emit a check that asserts on the alignment and otherwise triggers a
139148
// AssertKind::MisalignedPointerDereference.
140149
PointerCheck {
141-
cond: Operand::Copy(is_ok),
150+
cond: Operand::Move(is_ok),
142151
assert_kind: Box::new(AssertKind::MisalignedPointerDereference {
143152
required: alignment,
144-
found: Operand::Copy(addr),
153+
found: Operand::Move(addr),
145154
}),
146155
}
147156
}

library/alloc/src/alloc.rs

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -216,18 +216,16 @@ impl Global {
216216

217217
#[inline]
218218
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
219-
fn deallocate_impl_runtime(ptr: NonNull<u8>, layout: Layout) {
220-
if layout.size() != 0 {
221-
// SAFETY:
222-
// * We have checked that `layout` is non-zero in size.
223-
// * The caller is obligated to provide a layout that "fits", and in this case,
224-
// "fit" always means a layout that is equal to the original, because our
225-
// `allocate()`, `grow()`, and `shrink()` implementations never returns a larger
226-
// allocation than requested.
227-
// * Other conditions must be upheld by the caller, as per `Allocator::deallocate()`'s
228-
// safety documentation.
229-
unsafe { dealloc_nonnull(ptr, layout) }
230-
}
219+
fn deallocate_nonzero_impl_runtime(ptr: NonNull<u8>, layout: Layout) {
220+
// SAFETY:
221+
// * The caller provided a `layout` that is non-zero in size.
222+
// * The caller is obligated to provide a layout that "fits", and in this case,
223+
// "fit" always means a layout that is equal to the original, because our
224+
// `allocate()`, `grow()`, and `shrink()` implementations never returns a larger
225+
// allocation than requested.
226+
// * Other conditions must be upheld by the caller, as per `Allocator::deallocate()`'s
227+
// safety documentation.
228+
unsafe { dealloc_nonnull(ptr, layout) }
231229
}
232230

233231
// SAFETY: Same as `Allocator::grow`
@@ -340,11 +338,11 @@ impl Global {
340338
#[inline]
341339
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
342340
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
343-
const unsafe fn deallocate_impl(&self, ptr: NonNull<u8>, layout: Layout) {
341+
const unsafe fn deallocate_nonzero_impl(&self, ptr: NonNull<u8>, layout: Layout) {
344342
core::intrinsics::const_eval_select(
345343
(ptr, layout),
346-
Global::deallocate_impl_const,
347-
Global::deallocate_impl_runtime,
344+
Global::deallocate_nonzero_impl_const,
345+
Global::deallocate_nonzero_impl_runtime,
348346
)
349347
}
350348

@@ -405,12 +403,10 @@ impl Global {
405403
#[inline]
406404
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
407405
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
408-
const fn deallocate_impl_const(ptr: NonNull<u8>, layout: Layout) {
409-
if layout.size() != 0 {
410-
// SAFETY: We checked for nonzero size; other preconditions must be upheld by caller.
411-
unsafe {
412-
core::intrinsics::const_deallocate(ptr.as_ptr(), layout.size(), layout.align());
413-
}
406+
const fn deallocate_nonzero_impl_const(ptr: NonNull<u8>, layout: Layout) {
407+
// SAFETY: all conditions must be upheld by the caller
408+
unsafe {
409+
core::intrinsics::const_deallocate(ptr.as_ptr(), layout.size(), layout.align());
414410
}
415411
}
416412

@@ -434,7 +430,7 @@ impl Global {
434430
);
435431
}
436432
unsafe {
437-
self.deallocate_impl(ptr, old_layout);
433+
self.deallocate(ptr, old_layout);
438434
}
439435
Ok(new_ptr)
440436
}
@@ -458,8 +454,17 @@ unsafe impl const Allocator for Global {
458454
#[inline]
459455
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
460456
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
457+
if layout.size() != 0 {
458+
// SAFETY: We checked for nonzero size; other preconditions must be upheld by caller.
459+
unsafe { self.deallocate_nonzero_size(ptr, layout) }
460+
}
461+
}
462+
463+
#[inline]
464+
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
465+
unsafe fn deallocate_nonzero_size(&self, ptr: NonNull<u8>, layout: Layout) {
461466
// SAFETY: all conditions must be upheld by the caller
462-
unsafe { self.deallocate_impl(ptr, layout) }
467+
unsafe { self.deallocate_nonzero_impl(ptr, layout) }
463468
}
464469

465470
#[inline]

0 commit comments

Comments
 (0)