From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- src/test/ui/abi/nullable-pointer-ffi-compat.rs | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/ui/abi/nullable-pointer-ffi-compat.rs (limited to 'src/test/ui/abi/nullable-pointer-ffi-compat.rs') diff --git a/src/test/ui/abi/nullable-pointer-ffi-compat.rs b/src/test/ui/abi/nullable-pointer-ffi-compat.rs new file mode 100644 index 000000000..0647a18c3 --- /dev/null +++ b/src/test/ui/abi/nullable-pointer-ffi-compat.rs @@ -0,0 +1,28 @@ +// run-pass +// #11303, #11040: +// This would previously crash on i686 Linux due to abi differences +// between returning an Option and T, where T is a non nullable +// pointer. +// If we have an enum with two variants such that one is zero sized +// and the other contains a nonnullable pointer, we don't use a +// separate discriminant. Instead we use that pointer field to differentiate +// between the 2 cases. +// Also, if the variant with the nonnullable pointer has no other fields +// then we simply express the enum as just a pointer and not wrap it +// in a struct. + + +use std::mem; + +#[inline(never)] +extern "C" fn foo(x: &isize) -> Option<&isize> { Some(x) } + +static FOO: isize = 0xDEADBEE; + +pub fn main() { + unsafe { + let f: extern "C" fn(&isize) -> &isize = + mem::transmute(foo as extern "C" fn(&isize) -> Option<&isize>); + assert_eq!(*f(&FOO), FOO); + } +} -- cgit v1.2.3