Skip to content

Commit 15e0d8b

Browse files
committed
add test file for functional generics/const/impl/trait usage of naked functions
1 parent 489e8dd commit 15e0d8b

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

tests/codegen/naked-fn/generics.rs

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//@ compile-flags: -O
2+
//@ only-x86_64
3+
4+
#![crate_type = "lib"]
5+
#![feature(naked_functions, asm_const)]
6+
7+
use std::arch::asm;
8+
9+
#[no_mangle]
10+
fn test(x: u64) {
11+
// just making sure these symbols get used
12+
using_const_generics::<1>(x);
13+
using_const_generics::<2>(x);
14+
15+
generic_function::<i64>(x as i64);
16+
17+
let foo = Foo(x);
18+
19+
foo.method();
20+
foo.trait_method();
21+
}
22+
23+
// CHECK: .balign 4
24+
// CHECK: add rax, 2
25+
// CHECK: add rax, 42
26+
27+
// CHECK: .balign 4
28+
// CHECK: add rax, 1
29+
// CHECK: add rax, 42
30+
31+
#[naked]
32+
pub extern "C" fn using_const_generics<const N: u64>(x: u64) -> u64 {
33+
const M: u64 = 42;
34+
35+
unsafe {
36+
asm!(
37+
"xor rax, rax",
38+
"add rax, rdi",
39+
"add rax, {}",
40+
"add rax, {}",
41+
"ret",
42+
const N,
43+
const M,
44+
options(noreturn),
45+
)
46+
}
47+
}
48+
49+
trait Invert {
50+
fn invert(self) -> Self;
51+
}
52+
53+
impl Invert for i64 {
54+
fn invert(self) -> Self {
55+
-1 * self
56+
}
57+
}
58+
59+
// CHECK-LABEL: generic_function
60+
// CHECK: .balign 4
61+
// CHECK: call
62+
// CHECK: ret
63+
64+
#[naked]
65+
pub extern "C" fn generic_function<T: Invert>(x: i64) -> i64 {
66+
unsafe {
67+
asm!(
68+
"call {}",
69+
"ret",
70+
sym <T as Invert>::invert,
71+
options(noreturn),
72+
)
73+
}
74+
}
75+
76+
#[derive(Copy, Clone)]
77+
#[repr(transparent)]
78+
struct Foo(u64);
79+
80+
// CHECK-LABEL: method
81+
// CHECK: .balign 4
82+
// CHECK: mov rax, rdi
83+
84+
impl Foo {
85+
#[naked]
86+
#[no_mangle]
87+
extern "C" fn method(self) -> u64 {
88+
unsafe { asm!("mov rax, rdi", "ret", options(noreturn)) }
89+
}
90+
}
91+
92+
// CHECK-LABEL: trait_method
93+
// CHECK: .balign 4
94+
// CHECK: mov rax, rdi
95+
96+
trait Bar {
97+
extern "C" fn trait_method(self) -> u64;
98+
}
99+
100+
impl Bar for Foo {
101+
#[naked]
102+
#[no_mangle]
103+
extern "C" fn trait_method(self) -> u64 {
104+
unsafe { asm!("mov rax, rdi", "ret", options(noreturn)) }
105+
}
106+
}
107+
108+
// CHECK-LABEL: naked_with_args_and_return
109+
// CHECK: .balign 4
110+
// CHECK: lea rax, [rdi + rsi]
111+
112+
// this previously ICE'd, see https://github.com/rust-lang/rust/issues/124375
113+
#[naked]
114+
#[no_mangle]
115+
pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
116+
asm!("lea rax, [rdi + rsi]", "ret", options(noreturn));
117+
}

0 commit comments

Comments
 (0)