rust/tests/codegen-llvm/sanitizer/kcfi/fn-ptr-reify-shim.rs
Jonathan Pallant 6ecb3f33f0
Adds two new Tier 3 targets - aarch64v8r-unknown-none and aarch64v8r-unknown-none-softfloat.
The existing `aarch64-unknown-none` target assumes Armv8.0-A as a baseline. However, Arm recently released the Arm Cortex-R82 processor which is the first to implement the Armv8-R AArch64 mode architecture. This architecture is similar to Armv8-A AArch64, however it has a different set of mandatory features, and is based off of Armv8.4. It is largely unrelated to the existing Armv8-R architecture target (`armv8r-none-eabihf`), which only operates in AArch32 mode.

The second `aarch64v8r-unknown-none-softfloat` target allows for possible Armv8-R AArch64 CPUs with no FPU, or for use-cases where FPU register stacking is not desired. As with the existing `aarch64-unknown-none` target we have coupled FPU support and Neon support together - there is no 'has FPU but does not have NEON' target proposed even though the architecture technically allows for it.

This PR was developed by Ferrous Systems on behalf of Arm. Arm is the owner of these changes.
2026-01-26 12:43:52 +00:00

76 lines
2.3 KiB
Rust

//@ add-minicore
//@ revisions: aarch64 aarch64v8r x86_64
//@ [aarch64] compile-flags: --target aarch64-unknown-none
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64v8r] compile-flags: --target aarch64v8r-unknown-none
//@ [aarch64v8r] needs-llvm-components: aarch64
//@ [x86_64] compile-flags: --target x86_64-unknown-none
//@ [x86_64] needs-llvm-components: x86
//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Cno-prepopulate-passes -Copt-level=0
#![feature(no_core, lang_items)]
#![crate_type = "lib"]
#![no_core]
// A `ReifyShim` should only be created when the trait is dyn-compatible.
extern crate minicore;
use minicore::*;
trait DynCompatible {
fn dyn_name(&self) -> &'static str;
fn dyn_name_default(&self) -> &'static str {
let _ = self;
"dyn_default"
}
}
// Not dyn-compatible because the `Self: Sized` bound is missing.
trait NotDynCompatible {
fn not_dyn_name() -> &'static str;
fn not_dyn_name_default() -> &'static str {
"not_dyn_default"
}
}
struct S;
impl DynCompatible for S {
fn dyn_name(&self) -> &'static str {
"dyn_compatible"
}
}
impl NotDynCompatible for S {
fn not_dyn_name() -> &'static str {
"not_dyn_compatible"
}
}
#[no_mangle]
pub fn main() {
let s = S;
// `DynCompatible` is indeed dyn-compatible.
let _: &dyn DynCompatible = &s;
// CHECK: call <fn_ptr_reify_shim::S as fn_ptr_reify_shim::DynCompatible>::dyn_name::{shim:reify_fnptr#0}
let dyn_name = S::dyn_name as fn(&S) -> &str;
let _unused = dyn_name(&s);
// CHECK: call <fn_ptr_reify_shim::S as fn_ptr_reify_shim::DynCompatible>::dyn_name_default::{shim:reify_fnptr#0}
let dyn_name_default = S::dyn_name_default as fn(&S) -> &str;
let _unused = dyn_name_default(&s);
// Check using $ (end-of-line) that these calls do not contain `reify.shim.fnptr`.
// CHECK: call <fn_ptr_reify_shim::S as fn_ptr_reify_shim::NotDynCompatible>::not_dyn_name{{$}}
let not_dyn_name = S::not_dyn_name as fn() -> &'static str;
let _unused = not_dyn_name();
// CHECK: call <fn_ptr_reify_shim::S as fn_ptr_reify_shim::NotDynCompatible>::not_dyn_name_default{{$}}
let not_dyn_name_default = S::not_dyn_name_default as fn() -> &'static str;
let _unused = not_dyn_name_default();
}