Skip to content

Commit 2d21c14

Browse files
committed
respect repr(align(N)) on functions in miri
1 parent 49e5e4e commit 2d21c14

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

compiler/rustc_const_eval/src/interpret/memory.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -872,8 +872,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
872872

873873
// # Function pointers
874874
// (both global from `alloc_map` and local from `extra_fn_ptr_map`)
875-
if self.get_fn_alloc(id).is_some() {
876-
return AllocInfo::new(Size::ZERO, Align::ONE, AllocKind::Function, Mutability::Not);
875+
if let Some(fn_val) = self.get_fn_alloc(id) {
876+
let align = match fn_val {
877+
FnVal::Instance(instance) => {
878+
// Function alignment can be set globally with the `-Zmin-function-alignment=<n>` flag;
879+
// the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment.
880+
let fn_align = self.tcx.codegen_fn_attrs(instance.def_id()).alignment;
881+
let global_align = self.tcx.sess.opts.unstable_opts.min_function_alignment;
882+
883+
Ord::max(global_align, fn_align).unwrap_or(Align::ONE)
884+
}
885+
FnVal::Other(_) => Align::ONE,
886+
};
887+
888+
return AllocInfo::new(Size::ZERO, align, AllocKind::Function, Mutability::Not);
877889
}
878890

879891
// # Global allocations

src/tools/miri/tests/pass/fn_align.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@compile-flags: -Zmin-function-alignment=8
2+
#![feature(fn_align)]
3+
4+
// When a function uses `repr(align(N))`, the function address should be a multiple of `N`.
5+
6+
#[repr(align(256))]
7+
fn foo() {}
8+
9+
#[repr(align(16))]
10+
fn bar() {}
11+
12+
#[repr(align(4))]
13+
fn baz() {}
14+
15+
fn main() {
16+
assert!((foo as usize).is_multiple_of(256));
17+
assert!((bar as usize).is_multiple_of(16));
18+
19+
// The maximum of `repr(align(N))` and `-Zmin-function-alignment=N` is used.
20+
assert!((baz as usize).is_multiple_of(8));
21+
}

0 commit comments

Comments
 (0)