diff options
| author | Ralf Jung <post@ralfj.de> | 2023-09-02 11:59:31 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2023-09-08 08:59:55 +0200 |
| commit | c3e14edd8b7cbb502002a2390bf0ca5c6d09a315 (patch) | |
| tree | 0b002faa1bb5b9585721b84a16627f3d8e59791a /compiler/rustc_target/src | |
| parent | 8922c0c541c0fbfe6d0465eed6362a2bdbe6a0f0 (diff) | |
| download | rust-c3e14edd8b7cbb502002a2390bf0ca5c6d09a315.tar.gz rust-c3e14edd8b7cbb502002a2390bf0ca5c6d09a315.zip | |
accept some differences for rustc_abi(assert_eq), so that we can test more things to be compatible
Diffstat (limited to 'compiler/rustc_target/src')
| -rw-r--r-- | compiler/rustc_target/src/abi/call/mod.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 9a905dbc806..42483b7c6a5 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -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. |
