]> git.proxmox.com Git - rustc.git/blob - src/test/codegen/avr/avr-func-addrspace.rs
6d25ca56f1488340855427af287ed4f724e0f2da
[rustc.git] / src / test / codegen / avr / avr-func-addrspace.rs
1 // compile-flags: -O --target=avr-unknown-unknown --crate-type=rlib
2 // needs-llvm-components: avr
3
4 // This test validates that function pointers can be stored in global variables
5 // and called upon. It ensures that Rust emits function pointers in the correct
6 // address space to LLVM so that an assertion error relating to casting is
7 // not triggered.
8 //
9 // It also validates that functions can be called through function pointers
10 // through traits.
11
12 #![feature(no_core, lang_items, unboxed_closures, arbitrary_self_types)]
13 #![crate_type = "lib"]
14 #![no_core]
15
16 #[lang = "sized"]
17 pub trait Sized { }
18 #[lang = "copy"]
19 pub trait Copy { }
20 #[lang = "receiver"]
21 pub trait Receiver { }
22
23 pub struct Result<T, E> { _a: T, _b: E }
24
25 impl Copy for usize {}
26
27 #[lang = "drop_in_place"]
28 pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) {}
29
30 #[lang = "fn_once"]
31 pub trait FnOnce<Args> {
32 #[lang = "fn_once_output"]
33 type Output;
34
35 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
36 }
37
38 #[lang = "fn_mut"]
39 pub trait FnMut<Args> : FnOnce<Args> {
40 extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
41 }
42
43 #[lang = "fn"]
44 pub trait Fn<Args>: FnOnce<Args> {
45 /// Performs the call operation.
46 extern "rust-call" fn call(&self, args: Args) -> Self::Output;
47 }
48
49 impl<'a, A, R> FnOnce<A> for &'a fn(A) -> R {
50 type Output = R;
51
52 extern "rust-call" fn call_once(self, args: A) -> R {
53 (*self)(args)
54 }
55 }
56
57 pub static mut STORAGE_FOO: fn(&usize, &mut u32) -> Result<(), ()> = arbitrary_black_box;
58 pub static mut STORAGE_BAR: u32 = 12;
59
60 fn arbitrary_black_box(ptr: &usize, _: &mut u32) -> Result<(), ()> {
61 let raw_ptr = ptr as *const usize;
62 let _v: usize = unsafe { *raw_ptr };
63 loop {}
64 }
65
66 #[inline(never)]
67 #[no_mangle]
68 fn call_through_fn_trait(a: &mut impl Fn<(), Output=()>) {
69 (*a)()
70 }
71
72 #[inline(never)]
73 fn update_bar_value() {
74 unsafe {
75 STORAGE_BAR = 88;
76 }
77 }
78
79 // CHECK: define void @test(){{.+}}addrspace(1)
80 #[no_mangle]
81 pub extern "C" fn test() {
82 let mut buf = 7;
83
84 // A call through the Fn trait must use address space 1.
85 //
86 // CHECK: call{{.+}}addrspace(1) void @call_through_fn_trait()
87 call_through_fn_trait(&mut update_bar_value);
88
89 // A call through a global variable must use address space 1.
90 // CHECK: load {{.*}}addrspace(1){{.+}}FOO
91 unsafe {
92 STORAGE_FOO(&1, &mut buf);
93 }
94 }