// Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
-#![feature(no_core, unboxed_closures, start, lang_items, box_syntax, slice_patterns, never_type, linkage)]
+#![feature(
+ no_core, unboxed_closures, start, lang_items, box_syntax, never_type, linkage,
+ extern_types, thread_local
+)]
#![no_core]
-#![allow(dead_code)]
+#![allow(dead_code, non_camel_case_types)]
extern crate mini_core;
macro_rules! assert {
($e:expr) => {
if !$e {
- panic(&(stringify!(! $e), file!(), line!(), 0));
+ panic(stringify!(! $e));
}
};
}
macro_rules! assert_eq {
($l:expr, $r: expr) => {
if $l != $r {
- panic(&(stringify!($l != $r), file!(), line!(), 0));
+ panic(stringify!($l != $r));
}
}
}
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
+unsafe fn zeroed<T>() -> T {
+ let mut uninit = MaybeUninit { uninit: () };
+ intrinsics::write_bytes(&mut uninit.value.value as *mut T, 0, 1);
+ uninit.value.value
+}
+
fn take_f32(_f: f32) {}
fn take_unique(_u: Unique<()>) {}
y: !,
}
- unsafe fn zeroed<T>() -> T {
- intrinsics::init::<T>()
- }
-
unsafe fn uninitialized<T>() -> T {
- MaybeUninit { uninit: () }.value
+ MaybeUninit { uninit: () }.value.value
}
zeroed::<(u8, u8)>();
assert_eq!(*ANOTHER_STATIC, 42);
check_niche_behavior();
+
+ extern "C" {
+ type ExternType;
+ }
+
+ struct ExternTypeWrapper {
+ _a: ExternType,
+ }
+
+ let nullptr = 0 as *const ();
+ let extern_nullptr = nullptr as *const ExternTypeWrapper;
+ extern_nullptr as *const ();
+ let slice_ptr = &[] as *const [u8];
+ slice_ptr as *const u8;
+
+ #[cfg(not(jit))]
+ test_tls();
+}
+
+#[repr(C)]
+enum c_void {
+ _1,
+ _2,
+}
+
+type c_int = i32;
+type c_ulong = u64;
+
+type pthread_t = c_ulong;
+
+#[repr(C)]
+struct pthread_attr_t {
+ __size: [u64; 7],
+}
+
+#[link(name = "pthread")]
+extern "C" {
+ fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int;
+
+ fn pthread_create(
+ native: *mut pthread_t,
+ attr: *const pthread_attr_t,
+ f: extern "C" fn(_: *mut c_void) -> *mut c_void,
+ value: *mut c_void
+ ) -> c_int;
+
+ fn pthread_join(
+ native: pthread_t,
+ value: *mut *mut c_void
+ ) -> c_int;
+}
+
+#[thread_local]
+#[cfg(not(jit))]
+static mut TLS: u8 = 42;
+
+#[cfg(not(jit))]
+extern "C" fn mutate_tls(_: *mut c_void) -> *mut c_void {
+ unsafe { TLS = 0; }
+ 0 as *mut c_void
+}
+
+#[cfg(not(jit))]
+fn test_tls() {
+ unsafe {
+ let mut attr: pthread_attr_t = zeroed();
+ let mut thread: pthread_t = 0;
+
+ assert_eq!(TLS, 42);
+
+ if pthread_attr_init(&mut attr) != 0 {
+ assert!(false);
+ }
+
+ if pthread_create(&mut thread, &attr, mutate_tls, 0 as *mut c_void) != 0 {
+ assert!(false);
+ }
+
+ let mut res = 0 as *mut c_void;
+ pthread_join(thread, &mut res);
+
+ // TLS of main thread must not have been changed by the other thread.
+ assert_eq!(TLS, 42);
+
+ puts("TLS works!\n\0" as *const str as *const u8);
+ }
}
// Copied ui/issues/issue-61696.rs
fn check_niche_behavior () {
if let E1::V2 { .. } = (E1::V1 { f: true }) {
- unsafe { intrinsics::abort(); }
+ intrinsics::abort();
}
if let E2::V1 { .. } = E2::V3::<Infallible> {
- unsafe { intrinsics::abort(); }
+ intrinsics::abort();
}
}