about summary refs log tree commit diff
path: root/src/tools/miri/tests/pass/function_calls/exported_symbol.rs
blob: d804f3642b1d29f410e122c1fc4a5da225689c5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#![feature(rustc_attrs)]

#[no_mangle]
extern "C" fn foo() -> i32 {
    -1
}

#[export_name = "bar"]
fn bar() -> i32 {
    -2
}

#[rustc_std_internal_symbol]
fn baz() -> i32 {
    -3
}

struct AssocFn;

impl AssocFn {
    #[no_mangle]
    fn qux() -> i32 {
        -4
    }
}

fn main() {
    // Repeat calls to make sure the `Instance` cache is not broken.
    for _ in 0..3 {
        extern "C" {
            fn foo() -> i32;
            fn free(_: *mut std::ffi::c_void);
        }

        assert_eq!(unsafe { foo() }, -1);

        // `free()` is a built-in shim, so calling it will add ("free", None) to the cache.
        // Test that the cache is not broken with ("free", None).
        unsafe { free(std::ptr::null_mut()) }

        extern "Rust" {
            fn bar() -> i32;
            #[rustc_std_internal_symbol]
            fn baz() -> i32;
            fn qux() -> i32;
        }

        assert_eq!(unsafe { bar() }, -2);
        assert_eq!(unsafe { baz() }, -3);
        assert_eq!(unsafe { qux() }, -4);

        #[allow(clashing_extern_declarations)]
        {
            extern "Rust" {
                fn foo() -> i32;
            }

            assert_eq!(
                unsafe {
                    std::mem::transmute::<unsafe fn() -> i32, unsafe extern "C" fn() -> i32>(foo)()
                },
                -1
            );

            extern "C" {
                fn bar() -> i32;
                #[rustc_std_internal_symbol]
                fn baz() -> i32;
                fn qux() -> i32;
            }

            unsafe {
                let transmute =
                    |f| std::mem::transmute::<unsafe extern "C" fn() -> i32, unsafe fn() -> i32>(f);
                assert_eq!(transmute(bar)(), -2);
                assert_eq!(transmute(baz)(), -3);
                assert_eq!(transmute(qux)(), -4);
            }
        }
    }
}