@@ -23,7 +23,7 @@ use rustc_middle::ty::TyCtxt;
23
23
use rustc_smir:: rustc_internal;
24
24
use stable_mir:: abi:: { ArgAbi , CallConvention , FieldsShape , PassMode , VariantsShape } ;
25
25
use stable_mir:: mir:: mono:: Instance ;
26
- use stable_mir:: { CrateDef , CrateItems , ItemKind } ;
26
+ use stable_mir:: { CrateDef , CrateItem , CrateItems , ItemKind } ;
27
27
use std:: assert_matches:: assert_matches;
28
28
use std:: convert:: TryFrom ;
29
29
use std:: io:: Write ;
@@ -35,6 +35,8 @@ const CRATE_NAME: &str = "input";
35
35
fn test_stable_mir ( _tcx : TyCtxt < ' _ > ) -> ControlFlow < ( ) > {
36
36
// Find items in the local crate.
37
37
let items = stable_mir:: all_local_items ( ) ;
38
+
39
+ // Test fn_abi
38
40
let target_fn = * get_item ( & items, ( ItemKind :: Fn , "fn_abi" ) ) . unwrap ( ) ;
39
41
let instance = Instance :: try_from ( target_fn) . unwrap ( ) ;
40
42
let fn_abi = instance. fn_abi ( ) . unwrap ( ) ;
@@ -45,9 +47,26 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
45
47
check_primitive ( & fn_abi. args [ 1 ] ) ;
46
48
check_result ( fn_abi. ret ) ;
47
49
50
+ // Test variadic function.
51
+ let variadic_fn = * get_item ( & items, ( ItemKind :: Fn , "variadic_fn" ) ) . unwrap ( ) ;
52
+ check_variadic ( variadic_fn) ;
53
+
48
54
ControlFlow :: Continue ( ( ) )
49
55
}
50
56
57
+ /// Check the variadic function ABI:
58
+ /// ```no_run
59
+ /// pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) -> usize {
60
+ /// 0
61
+ /// }
62
+ /// ```
63
+ fn check_variadic ( variadic_fn : CrateItem ) {
64
+ let instance = Instance :: try_from ( variadic_fn) . unwrap ( ) ;
65
+ let abi = instance. fn_abi ( ) . unwrap ( ) ;
66
+ assert ! ( abi. c_variadic) ;
67
+ assert_eq ! ( abi. args. len( ) , 1 ) ;
68
+ }
69
+
51
70
/// Check the argument to be ignored: `ignore: [u8; 0]`.
52
71
fn check_ignore ( abi : & ArgAbi ) {
53
72
assert ! ( abi. ty. kind( ) . is_array( ) ) ;
@@ -60,7 +79,7 @@ fn check_ignore(abi: &ArgAbi) {
60
79
/// Check the primitive argument: `primitive: char`.
61
80
fn check_primitive ( abi : & ArgAbi ) {
62
81
assert ! ( abi. ty. kind( ) . is_char( ) ) ;
63
- assert_eq ! ( abi. mode, PassMode :: Direct ) ;
82
+ assert_matches ! ( abi. mode, PassMode :: Direct ( _ ) ) ;
64
83
let layout = abi. layout . shape ( ) ;
65
84
assert ! ( layout. is_sized( ) ) ;
66
85
assert ! ( !layout. is_1zst( ) ) ;
@@ -70,7 +89,7 @@ fn check_primitive(abi: &ArgAbi) {
70
89
/// Check the return value: `Result<usize, &str>`.
71
90
fn check_result ( abi : ArgAbi ) {
72
91
assert ! ( abi. ty. kind( ) . is_enum( ) ) ;
73
- assert_eq ! ( abi. mode, PassMode :: Indirect ) ;
92
+ assert_matches ! ( abi. mode, PassMode :: Indirect { .. } ) ;
74
93
let layout = abi. layout . shape ( ) ;
75
94
assert ! ( layout. is_sized( ) ) ;
76
95
assert_matches ! ( layout. fields, FieldsShape :: Arbitrary { .. } ) ;
@@ -106,11 +125,18 @@ fn generate_input(path: &str) -> std::io::Result<()> {
106
125
write ! (
107
126
file,
108
127
r#"
109
- #[allow(unused_variables)]
128
+ #![feature(c_variadic)]
129
+ #![allow(unused_variables)]
130
+
110
131
pub fn fn_abi(ignore: [u8; 0], primitive: char) -> Result<usize, &'static str> {{
111
132
// We only care about the signature.
112
133
todo!()
113
134
}}
135
+
136
+
137
+ pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) -> usize {{
138
+ 0
139
+ }}
114
140
"#
115
141
) ?;
116
142
Ok ( ( ) )
0 commit comments