Skip to content

Commit aa59f29

Browse files
committed
Make the alignment intrinsics return ptr::Alignment
1 parent 4e79e36 commit aa59f29

33 files changed

Lines changed: 248 additions & 281 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
@@ -645,6 +645,12 @@ pub union MaybeUninit<T> {
645645
pub value: ManuallyDrop<T>,
646646
}
647647

648+
pub mod ptr {
649+
#[lang = "Alignment"]
650+
#[repr(transparent)]
651+
pub struct Alignment(pub usize);
652+
}
653+
648654
pub mod intrinsics {
649655
#[rustc_intrinsic]
650656
pub fn abort() -> !;
@@ -653,9 +659,9 @@ pub mod intrinsics {
653659
#[rustc_intrinsic]
654660
pub unsafe fn size_of_val<T: ?crate::Sized>(val: *const T) -> usize;
655661
#[rustc_intrinsic]
656-
pub const fn align_of<T>() -> usize;
662+
pub const fn align_of<T>() -> crate::ptr::Alignment;
657663
#[rustc_intrinsic]
658-
pub unsafe fn align_of_val<T: ?crate::Sized>(val: *const T) -> usize;
664+
pub unsafe fn align_of_val<T: ?crate::Sized>(val: *const T) -> crate::ptr::Alignment;
659665
#[rustc_intrinsic]
660666
pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize);
661667
#[rustc_intrinsic]
@@ -723,15 +729,15 @@ pub const fn size_of<T>() -> usize {
723729
}
724730

725731
pub const fn align_of<T>() -> usize {
726-
<T as SizedTypeProperties>::ALIGN
732+
<T as SizedTypeProperties>::ALIGN.0
727733
}
728734

729735
trait SizedTypeProperties: Sized {
730736
#[lang = "mem_size_const"]
731737
const SIZE: usize = intrinsics::size_of::<Self>();
732738

733739
#[lang = "mem_align_const"]
734-
const ALIGN: usize = intrinsics::align_of::<Self>();
740+
const ALIGN: crate::ptr::Alignment = intrinsics::align_of::<Self>();
735741
}
736742
impl<T> SizedTypeProperties for T {}
737743

compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs

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

218218
assert_eq!(align_of::<u16>() as u8, 2);
219-
assert_eq!(intrinsics::align_of_val(&a) as u8, align_of::<&str>() as u8);
219+
assert_eq!(intrinsics::align_of_val(&a).0 as u8, align_of::<&str>() as u8);
220220

221221
let u8_needs_drop = const { intrinsics::needs_drop::<u8>() };
222222
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
@@ -602,7 +602,8 @@ fn codegen_regular_intrinsic_call<'tcx>(
602602
None
603603
};
604604
let (_size, align) = crate::unsize::size_and_align_of(fx, layout, meta);
605-
ret.write_cvalue(fx, CValue::by_val(align, usize_layout));
605+
let alignment_layout = fx.layout_of(fx.tcx.ty_alignment(source_info.span));
606+
ret.write_cvalue(fx, CValue::by_val(align, alignment_layout));
606607
}
607608

608609
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
@@ -651,6 +651,12 @@ pub union MaybeUninit<T> {
651651
pub value: ManuallyDrop<T>,
652652
}
653653

654+
pub mod ptr {
655+
#[lang = "Alignment"]
656+
#[repr(transparent)]
657+
pub struct Alignment(pub usize);
658+
}
659+
654660
pub mod intrinsics {
655661
#[rustc_intrinsic]
656662
pub const fn black_box<T>(_dummy: T) -> T;
@@ -661,9 +667,9 @@ pub mod intrinsics {
661667
#[rustc_intrinsic]
662668
pub unsafe fn size_of_val<T: ?::Sized>(val: *const T) -> usize;
663669
#[rustc_intrinsic]
664-
pub const fn align_of<T>() -> usize;
670+
pub const fn align_of<T>() -> crate::ptr::Alignment;
665671
#[rustc_intrinsic]
666-
pub unsafe fn align_of_val<T: ?::Sized>(val: *const T) -> usize;
672+
pub unsafe fn align_of_val<T: ?::Sized>(val: *const T) -> crate::ptr::Alignment;
667673
#[rustc_intrinsic]
668674
pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize);
669675
#[rustc_intrinsic]
@@ -704,15 +710,15 @@ pub const fn size_of<T>() -> usize {
704710
}
705711

706712
pub const fn align_of<T>() -> usize {
707-
<T as SizedTypeProperties>::ALIGN
713+
<T as SizedTypeProperties>::ALIGN.0
708714
}
709715

710716
trait SizedTypeProperties: Sized {
711717
#[lang = "mem_size_const"]
712718
const SIZE: usize = intrinsics::size_of::<Self>();
713719

714720
#[lang = "mem_align_const"]
715-
const ALIGN: usize = intrinsics::align_of::<Self>();
721+
const ALIGN: crate::ptr::Alignment = intrinsics::align_of::<Self>();
716722
}
717723

718724
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
@@ -168,6 +168,7 @@ language_item_table! {
168168
MetaSized, sym::meta_sized, meta_sized_trait, Target::Trait, GenericRequirement::Exact(0);
169169
PointeeSized, sym::pointee_sized, pointee_sized_trait, Target::Trait, GenericRequirement::Exact(0);
170170
Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1);
171+
Alignment, sym::Alignment, alignment_type, Target::Struct, GenericRequirement::Exact(0);
171172
AlignOf, sym::mem_align_const, align_const, Target::AssocConst, GenericRequirement::Exact(0);
172173
SizeOf, sym::mem_size_const, size_const, Target::AssocConst, GenericRequirement::Exact(0);
173174
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
@@ -291,10 +291,10 @@ pub(crate) fn check_intrinsic_type(
291291
sym::amdgpu_dispatch_ptr => (0, 0, vec![], Ty::new_imm_ptr(tcx, tcx.types.unit)),
292292
sym::unreachable => (0, 0, vec![], tcx.types.never),
293293
sym::breakpoint => (0, 0, vec![], tcx.types.unit),
294-
sym::size_of | sym::align_of | sym::variant_count => (1, 0, vec![], tcx.types.usize),
295-
sym::size_of_val | sym::align_of_val => {
296-
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
297-
}
294+
sym::size_of | sym::variant_count => (1, 0, vec![], tcx.types.usize),
295+
sym::align_of => (1, 0, vec![], tcx.ty_alignment(span)),
296+
sym::size_of_val => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize),
297+
sym::align_of_val => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.ty_alignment(span)),
298298
sym::offset_of => (1, 0, vec![tcx.types.u32, tcx.types.u32], tcx.types.usize),
299299
sym::rustc_peek => (1, 0, vec![param(0)], param(0)),
300300
sym::caller_location => (0, 0, vec![], tcx.caller_location_ty()),

compiler/rustc_middle/src/ty/context.rs

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

1082+
/// Gets a `Ty` representing the [`LangItem::Alignment`]
1083+
#[track_caller]
1084+
pub fn ty_alignment(self, span: Span) -> Ty<'tcx> {
1085+
let alignment = self.require_lang_item(hir::LangItem::Alignment, span);
1086+
self.type_of(alignment).no_bound_vars().unwrap()
1087+
}
1088+
10821089
/// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
10831090
/// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
10841091
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

@@ -139,10 +148,10 @@ fn insert_alignment_check<'tcx>(
139148
// Emit a check that asserts on the alignment and otherwise triggers a
140149
// AssertKind::MisalignedPointerDereference.
141150
PointerCheck {
142-
cond: Operand::Copy(is_ok),
151+
cond: Operand::Move(is_ok),
143152
assert_kind: Box::new(AssertKind::MisalignedPointerDereference {
144153
required: alignment,
145-
found: Operand::Copy(addr),
154+
found: Operand::Move(addr),
146155
}),
147156
}
148157
}

library/alloc/src/alloc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,8 @@ unsafe impl const Allocator for Global {
484484
#[lang = "exchange_malloc"]
485485
#[inline]
486486
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
487-
unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
488-
let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
487+
unsafe fn exchange_malloc(size: usize, align: Alignment) -> *mut u8 {
488+
let layout = unsafe { Layout::from_size_alignment_unchecked(size, align) };
489489
match Global.allocate(layout) {
490490
Ok(ptr) => ptr.as_mut_ptr(),
491491
Err(_) => handle_alloc_error(layout),

0 commit comments

Comments
 (0)