diff options
| -rw-r--r-- | src/tools/miri/src/helpers.rs | 17 | ||||
| -rw-r--r-- | src/tools/miri/tests/pass/shims/ctor.rs | 15 |
2 files changed, 22 insertions, 10 deletions
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 0c96ddf00db..ab7e35710d3 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -1087,8 +1087,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "failed to evaluate static in required link_section: {def_id:?}\n{err:?}" ) }); - let val = this.read_immediate(&const_val)?; - array.push(val); + match const_val.layout.ty.kind() { + ty::FnPtr(..) => { + array.push(this.read_immediate(&const_val)?); + } + ty::Array(elem_ty, _) if matches!(elem_ty.kind(), ty::FnPtr(..)) => { + let mut elems = this.project_array_fields(&const_val)?; + while let Some((_idx, elem)) = elems.next(this)? { + array.push(this.read_immediate(&elem)?); + } + } + _ => + throw_unsup_format!( + "only function pointers and arrays of function pointers are supported in well-known linker sections" + ), + } } interp_ok(()) })?; diff --git a/src/tools/miri/tests/pass/shims/ctor.rs b/src/tools/miri/tests/pass/shims/ctor.rs index b997d2386b8..a0fcdb1081e 100644 --- a/src/tools/miri/tests/pass/shims/ctor.rs +++ b/src/tools/miri/tests/pass/shims/ctor.rs @@ -2,13 +2,13 @@ use std::sync::atomic::{AtomicUsize, Ordering}; static COUNT: AtomicUsize = AtomicUsize::new(0); -unsafe extern "C" fn ctor() { - COUNT.fetch_add(1, Ordering::Relaxed); +unsafe extern "C" fn ctor<const N: usize>() { + COUNT.fetch_add(N, Ordering::Relaxed); } #[rustfmt::skip] macro_rules! ctor { - ($ident:ident = $ctor:ident) => { + ($ident:ident: $ty:ty = $ctor:expr) => { #[cfg_attr( all(any( target_os = "linux", @@ -33,14 +33,13 @@ macro_rules! ctor { link_section = "__DATA,__mod_init_func" )] #[used] - static $ident: unsafe extern "C" fn() = $ctor; + static $ident: $ty = $ctor; }; } -ctor! { CTOR1 = ctor } -ctor! { CTOR2 = ctor } -ctor! { CTOR3 = ctor } +ctor! { CTOR1: unsafe extern "C" fn() = ctor::<1> } +ctor! { CTOR2: [unsafe extern "C" fn(); 2] = [ctor::<2>, ctor::<3>] } fn main() { - assert_eq!(COUNT.load(Ordering::Relaxed), 3, "ctors did not run"); + assert_eq!(COUNT.load(Ordering::Relaxed), 6, "ctors did not run"); } |
