1
Fork 0

accept some differences for rustc_abi(assert_eq), so that we can test more things to be compatible

This commit is contained in:
Ralf Jung 2023-09-02 11:59:31 +02:00
parent 8922c0c541
commit c3e14edd8b
7 changed files with 449 additions and 64 deletions

View file

@ -55,6 +55,28 @@ pub enum PassMode {
Indirect { attrs: ArgAttributes, extra_attrs: Option<ArgAttributes>, on_stack: bool },
}
impl PassMode {
/// Checks if these two `PassMode` are equal enough to be considered "the same for all
/// function call ABIs".
pub fn eq_abi(&self, other: &Self) -> bool {
match (self, other) {
(PassMode::Ignore, PassMode::Ignore) => true, // can still be reached for the return type
(PassMode::Direct(a1), PassMode::Direct(a2)) => a1.eq_abi(a2),
(PassMode::Pair(a1, b1), PassMode::Pair(a2, b2)) => a1.eq_abi(a2) && b1.eq_abi(b2),
(PassMode::Cast(c1, pad1), PassMode::Cast(c2, pad2)) => c1.eq_abi(c2) && pad1 == pad2,
(
PassMode::Indirect { attrs: a1, extra_attrs: None, on_stack: s1 },
PassMode::Indirect { attrs: a2, extra_attrs: None, on_stack: s2 },
) => a1.eq_abi(a2) && s1 == s2,
(
PassMode::Indirect { attrs: a1, extra_attrs: Some(e1), on_stack: s1 },
PassMode::Indirect { attrs: a2, extra_attrs: Some(e2), on_stack: s2 },
) => a1.eq_abi(a2) && e1.eq_abi(e2) && s1 == s2,
_ => false,
}
}
}
// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest
// of this module
pub use attr_impl::ArgAttribute;
@ -127,6 +149,24 @@ impl ArgAttributes {
pub fn contains(&self, attr: ArgAttribute) -> bool {
self.regular.contains(attr)
}
/// Checks if these two `ArgAttributes` are equal enough to be considered "the same for all
/// function call ABIs".
pub fn eq_abi(&self, other: &Self) -> bool {
// There's only one regular attribute that matters for the call ABI: InReg.
// Everything else is things like noalias, dereferenceable, nonnull, ...
// (This also applies to pointee_size, pointee_align.)
if self.regular.contains(ArgAttribute::InReg) != other.regular.contains(ArgAttribute::InReg)
{
return false;
}
// We also compare the sign extension mode -- this could let the callee make assumptions
// about bits that conceptually were not even passed.
if self.arg_ext != other.arg_ext {
return false;
}
return true;
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
@ -272,6 +312,14 @@ impl CastTarget {
acc.max(align)
})
}
/// Checks if these two `CastTarget` are equal enough to be considered "the same for all
/// function call ABIs".
pub fn eq_abi(&self, other: &Self) -> bool {
let CastTarget { prefix: prefix_l, rest: rest_l, attrs: attrs_l } = self;
let CastTarget { prefix: prefix_r, rest: rest_r, attrs: attrs_r } = other;
prefix_l == prefix_r && rest_l == rest_r && attrs_l.eq_abi(attrs_r)
}
}
/// Return value from the `homogeneous_aggregate` test function.