2023-12-16 09:24:25 -06:00
|
|
|
//@ stderr-per-bitwidth
|
|
|
|
//@ compile-flags: -Zunleash-the-miri-inside-of-you
|
|
|
|
#![feature(const_refs_to_cell, const_mut_refs)]
|
|
|
|
// All "inner" allocations that come with a `static` are interned immutably. This means it is
|
|
|
|
// crucial that we do not accept any form of (interior) mutability there.
|
2024-03-08 13:13:57 -06:00
|
|
|
#![deny(const_eval_mutable_ptr_in_final_value)]
|
2023-12-16 09:24:25 -06:00
|
|
|
use std::sync::atomic::*;
|
|
|
|
|
2024-03-08 13:13:57 -06:00
|
|
|
static REF: &AtomicI32 = &AtomicI32::new(42);
|
2024-03-26 04:46:30 -05:00
|
|
|
//~^ ERROR it is undefined behavior to use this value
|
2024-03-08 13:13:57 -06:00
|
|
|
|
|
|
|
static REFMUT: &mut i32 = &mut 0;
|
2024-03-26 04:46:30 -05:00
|
|
|
//~^ ERROR it is undefined behavior to use this value
|
2023-12-16 09:24:25 -06:00
|
|
|
|
|
|
|
// Different way of writing this that avoids promotion.
|
2024-03-08 13:13:57 -06:00
|
|
|
static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
|
2024-03-26 04:46:30 -05:00
|
|
|
//~^ ERROR it is undefined behavior to use this value
|
2024-03-08 13:13:57 -06:00
|
|
|
static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
|
2024-03-26 04:46:30 -05:00
|
|
|
//~^ ERROR it is undefined behavior to use this value
|
2023-12-16 09:24:25 -06:00
|
|
|
|
|
|
|
// This one is obvious, since it is non-Sync. (It also suppresses the other errors, so it is
|
|
|
|
// commented out.)
|
|
|
|
// static RAW: *const AtomicI32 = &AtomicI32::new(42);
|
|
|
|
|
|
|
|
struct SyncPtr<T> { x : *const T }
|
|
|
|
unsafe impl<T> Sync for SyncPtr<T> {}
|
|
|
|
|
|
|
|
// All of these pass the lifetime checks because of the "tail expression" / "outer scope" rule.
|
|
|
|
// (This relies on `SyncPtr` being a curly brace struct.)
|
|
|
|
// Then they get interned immutably, which is not great.
|
|
|
|
// `mut_ref_in_final.rs` and `std/cell.rs` ensure that we don't accept this even with the feature
|
|
|
|
// fate, but for unleashed Miri there's not really any way we can reject them: it's just
|
|
|
|
// non-dangling raw pointers.
|
|
|
|
static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
|
|
|
|
//~^ ERROR mutable pointer in final value
|
2024-03-08 13:13:57 -06:00
|
|
|
//~| WARNING this was previously accepted by the compiler
|
|
|
|
|
2023-12-16 09:24:25 -06:00
|
|
|
static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
|
|
|
|
//~^ ERROR mutable pointer in final value
|
2024-03-08 13:13:57 -06:00
|
|
|
//~| WARNING this was previously accepted by the compiler
|
|
|
|
|
2023-12-16 09:24:25 -06:00
|
|
|
static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
|
|
|
|
//~^ ERROR mutable pointer in final value
|
2024-03-08 13:13:57 -06:00
|
|
|
//~| WARNING this was previously accepted by the compiler
|
2023-12-16 09:24:25 -06:00
|
|
|
|
|
|
|
fn main() {}
|