Skip to content

Commit 76b3e6d

Browse files
committed
Fix c_variadic flag and add opaque info to PassMode
We should expand the information in PassMode later.
1 parent 1a83c5b commit 76b3e6d

File tree

3 files changed

+53
-17
lines changed

3 files changed

+53
-17
lines changed

compiler/rustc_smir/src/rustc_smir/convert/abi.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,14 @@ impl<'tcx> Stable<'tcx> for rustc_target::abi::call::FnAbi<'tcx, ty::Ty<'tcx>> {
6666
type T = FnAbi;
6767

6868
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
69+
assert!(self.args.len() >= self.fixed_count as usize);
70+
assert!(!self.c_variadic || matches!(self.conv, Conv::C));
6971
FnAbi {
7072
args: self.args.as_ref().stable(tables),
7173
ret: self.ret.stable(tables),
7274
fixed_count: self.fixed_count,
7375
conv: self.conv.stable(tables),
76+
c_variadic: self.c_variadic,
7477
}
7578
}
7679
}
@@ -122,10 +125,20 @@ impl<'tcx> Stable<'tcx> for rustc_target::abi::call::PassMode {
122125
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
123126
match self {
124127
rustc_target::abi::call::PassMode::Ignore => PassMode::Ignore,
125-
rustc_target::abi::call::PassMode::Direct(_) => PassMode::Direct,
126-
rustc_target::abi::call::PassMode::Pair(_, _) => PassMode::Pair,
127-
rustc_target::abi::call::PassMode::Cast { .. } => PassMode::Cast,
128-
rustc_target::abi::call::PassMode::Indirect { .. } => PassMode::Indirect,
128+
rustc_target::abi::call::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)),
129+
rustc_target::abi::call::PassMode::Pair(first, second) => {
130+
PassMode::Pair(opaque(first), opaque(second))
131+
}
132+
rustc_target::abi::call::PassMode::Cast { pad_i32, cast } => {
133+
PassMode::Cast { pad_i32: *pad_i32, cast: opaque(cast) }
134+
}
135+
rustc_target::abi::call::PassMode::Indirect { attrs, meta_attrs, on_stack } => {
136+
PassMode::Indirect {
137+
attrs: opaque(attrs),
138+
meta_attrs: opaque(meta_attrs),
139+
on_stack: *on_stack,
140+
}
141+
}
129142
}
130143
}
131144
}

compiler/stable_mir/src/abi.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,9 @@ pub struct FnAbi {
2121

2222
/// The ABI convention.
2323
pub conv: CallConvention,
24-
}
2524

26-
impl FnAbi {
27-
pub fn is_c_variadic(&self) -> bool {
28-
self.args.len() > self.fixed_count as usize
29-
}
25+
/// Whether this is a variadic C function,
26+
pub c_variadic: bool,
3027
}
3128

3229
/// Information about the ABI of a function's argument, or return value.
@@ -47,15 +44,15 @@ pub enum PassMode {
4744
/// Pass the argument directly.
4845
///
4946
/// The argument has a layout abi of `Scalar` or `Vector`.
50-
Direct,
47+
Direct(Opaque),
5148
/// Pass a pair's elements directly in two arguments.
5249
///
5350
/// The argument has a layout abi of `ScalarPair`.
54-
Pair,
51+
Pair(Opaque, Opaque),
5552
/// Pass the argument after casting it.
56-
Cast,
53+
Cast { pad_i32: bool, cast: Opaque },
5754
/// Pass the argument indirectly via a hidden pointer.
58-
Indirect,
55+
Indirect { attrs: Opaque, meta_attrs: Opaque, on_stack: bool },
5956
}
6057

6158
/// The layout of a type, alongside the type itself.

tests/ui-fulldeps/stable-mir/check_layout.rs renamed to tests/ui-fulldeps/stable-mir/check_abi.rs

+30-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_middle::ty::TyCtxt;
2323
use rustc_smir::rustc_internal;
2424
use stable_mir::abi::{ArgAbi, CallConvention, FieldsShape, PassMode, VariantsShape};
2525
use stable_mir::mir::mono::Instance;
26-
use stable_mir::{CrateDef, CrateItems, ItemKind};
26+
use stable_mir::{CrateDef, CrateItem, CrateItems, ItemKind};
2727
use std::assert_matches::assert_matches;
2828
use std::convert::TryFrom;
2929
use std::io::Write;
@@ -35,6 +35,8 @@ const CRATE_NAME: &str = "input";
3535
fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
3636
// Find items in the local crate.
3737
let items = stable_mir::all_local_items();
38+
39+
// Test fn_abi
3840
let target_fn = *get_item(&items, (ItemKind::Fn, "fn_abi")).unwrap();
3941
let instance = Instance::try_from(target_fn).unwrap();
4042
let fn_abi = instance.fn_abi().unwrap();
@@ -45,9 +47,26 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
4547
check_primitive(&fn_abi.args[1]);
4648
check_result(fn_abi.ret);
4749

50+
// Test variadic function.
51+
let variadic_fn = *get_item(&items, (ItemKind::Fn, "variadic_fn")).unwrap();
52+
check_variadic(variadic_fn);
53+
4854
ControlFlow::Continue(())
4955
}
5056

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+
5170
/// Check the argument to be ignored: `ignore: [u8; 0]`.
5271
fn check_ignore(abi: &ArgAbi) {
5372
assert!(abi.ty.kind().is_array());
@@ -60,7 +79,7 @@ fn check_ignore(abi: &ArgAbi) {
6079
/// Check the primitive argument: `primitive: char`.
6180
fn check_primitive(abi: &ArgAbi) {
6281
assert!(abi.ty.kind().is_char());
63-
assert_eq!(abi.mode, PassMode::Direct);
82+
assert_matches!(abi.mode, PassMode::Direct(_));
6483
let layout = abi.layout.shape();
6584
assert!(layout.is_sized());
6685
assert!(!layout.is_1zst());
@@ -70,7 +89,7 @@ fn check_primitive(abi: &ArgAbi) {
7089
/// Check the return value: `Result<usize, &str>`.
7190
fn check_result(abi: ArgAbi) {
7291
assert!(abi.ty.kind().is_enum());
73-
assert_eq!(abi.mode, PassMode::Indirect);
92+
assert_matches!(abi.mode, PassMode::Indirect { .. });
7493
let layout = abi.layout.shape();
7594
assert!(layout.is_sized());
7695
assert_matches!(layout.fields, FieldsShape::Arbitrary { .. });
@@ -106,11 +125,18 @@ fn generate_input(path: &str) -> std::io::Result<()> {
106125
write!(
107126
file,
108127
r#"
109-
#[allow(unused_variables)]
128+
#![feature(c_variadic)]
129+
#![allow(unused_variables)]
130+
110131
pub fn fn_abi(ignore: [u8; 0], primitive: char) -> Result<usize, &'static str> {{
111132
// We only care about the signature.
112133
todo!()
113134
}}
135+
136+
137+
pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) -> usize {{
138+
0
139+
}}
114140
"#
115141
)?;
116142
Ok(())

0 commit comments

Comments
 (0)