ABI compat check: detect unadjusted ABI mismatches
This commit is contained in:
parent
bf662eb808
commit
ab7b03e3f4
@ -1700,7 +1700,9 @@ pub fn is_zst(&self) -> bool {
|
|||||||
|
|
||||||
/// Checks if these two `Layout` are equal enough to be considered "the same for all function
|
/// Checks if these two `Layout` are equal enough to be considered "the same for all function
|
||||||
/// call ABIs". Note however that real ABIs depend on more details that are not reflected in the
|
/// call ABIs". Note however that real ABIs depend on more details that are not reflected in the
|
||||||
/// `Layout`; the `PassMode` need to be compared as well.
|
/// `Layout`; the `PassMode` need to be compared as well. Also note that we assume
|
||||||
|
/// aggregates are passed via `PassMode::Indirect` or `PassMode::Cast`; more strict
|
||||||
|
/// checks would otherwise be required.
|
||||||
pub fn eq_abi(&self, other: &Self) -> bool {
|
pub fn eq_abi(&self, other: &Self) -> bool {
|
||||||
// The one thing that we are not capturing here is that for unsized types, the metadata must
|
// The one thing that we are not capturing here is that for unsized types, the metadata must
|
||||||
// also have the same ABI, and moreover that the same metadata leads to the same size. The
|
// also have the same ABI, and moreover that the same metadata leads to the same size. The
|
||||||
|
@ -745,10 +745,25 @@ pub fn is_ignore(&self) -> bool {
|
|||||||
|
|
||||||
/// Checks if these two `ArgAbi` are equal enough to be considered "the same for all
|
/// Checks if these two `ArgAbi` are equal enough to be considered "the same for all
|
||||||
/// function call ABIs".
|
/// function call ABIs".
|
||||||
pub fn eq_abi(&self, other: &Self) -> bool {
|
pub fn eq_abi(&self, other: &Self) -> bool
|
||||||
|
where
|
||||||
|
Ty: PartialEq,
|
||||||
|
{
|
||||||
// Ideally we'd just compare the `mode`, but that is not enough -- for some modes LLVM will look
|
// Ideally we'd just compare the `mode`, but that is not enough -- for some modes LLVM will look
|
||||||
// at the type.
|
// at the type.
|
||||||
self.layout.eq_abi(&other.layout) && self.mode.eq_abi(&other.mode)
|
self.layout.eq_abi(&other.layout) && self.mode.eq_abi(&other.mode) && {
|
||||||
|
// `fn_arg_sanity_check` accepts `PassMode::Direct` for some aggregates.
|
||||||
|
// That elevates any type difference to an ABI difference since we just use the
|
||||||
|
// full Rust type as the LLVM argument/return type.
|
||||||
|
if matches!(self.mode, PassMode::Direct(..))
|
||||||
|
&& matches!(self.layout.abi, Abi::Aggregate { .. })
|
||||||
|
{
|
||||||
|
// For aggregates in `Direct` mode to be compatible, the types need to be equal.
|
||||||
|
self.layout.ty == other.layout.ty
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,8 @@ pub enum Abi {
|
|||||||
},
|
},
|
||||||
RustIntrinsic,
|
RustIntrinsic,
|
||||||
RustCall,
|
RustCall,
|
||||||
|
/// *Not* a stable ABI, just directly use the Rust types to describe the ABI for LLVM. Even
|
||||||
|
/// normally ABI-compatible Rust types can become ABI-incompatible with this ABI!
|
||||||
Unadjusted,
|
Unadjusted,
|
||||||
/// For things unlikely to be called, where reducing register pressure in
|
/// For things unlikely to be called, where reducing register pressure in
|
||||||
/// `extern "Rust"` callers is worth paying extra cost in the callee.
|
/// `extern "Rust"` callers is worth paying extra cost in the callee.
|
||||||
|
@ -40,9 +40,10 @@
|
|||||||
//@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
|
//@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
|
||||||
//@[loongarch64] needs-llvm-components: loongarch
|
//@[loongarch64] needs-llvm-components: loongarch
|
||||||
//@[loongarch64] min-llvm-version: 18
|
//@[loongarch64] min-llvm-version: 18
|
||||||
//@ revisions: wasm
|
//FIXME: wasm is disabled due to <https://github.com/rust-lang/rust/issues/115666>.
|
||||||
//@[wasm] compile-flags: --target wasm32-unknown-unknown
|
//FIXME @ revisions: wasm
|
||||||
//@[wasm] needs-llvm-components: webassembly
|
//FIXME @[wasm] compile-flags: --target wasm32-unknown-unknown
|
||||||
|
//FIXME @[wasm] needs-llvm-components: webassembly
|
||||||
//@ revisions: wasip1
|
//@ revisions: wasip1
|
||||||
//@[wasip1] compile-flags: --target wasm32-wasip1
|
//@[wasip1] compile-flags: --target wasm32-wasip1
|
||||||
//@[wasip1] needs-llvm-components: webassembly
|
//@[wasip1] needs-llvm-components: webassembly
|
||||||
|
Loading…
Reference in New Issue
Block a user