Skip to content

Rollup of 5 pull requests #71707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Apr 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9a2bca6
rustc: fix check_attr() for methods, closures and foreign functions
neocturne Apr 16, 2020
6c700dc
Extend UI tests for fixed check_attr()
neocturne Apr 16, 2020
e8ffa21
better document const-pattern dynamic soundness checks, and fix a sou…
RalfJung Apr 28, 2020
a84e2a0
add test for const-ref-to-cross-crate-mutable-static
RalfJung Apr 28, 2020
a089801
clarify comment
RalfJung Apr 28, 2020
edfca5f
Move branch point upwards to avoid unnecessary mk_ptr()
ldm0 Apr 26, 2020
a9340b1
Rename function to `suggest_deref_ref_or_into` because it's suggesting
ldm0 Apr 28, 2020
979bbf2
also test reference into static field
RalfJung Apr 29, 2020
a03355d
some more test cases
RalfJung Apr 29, 2020
07772fc
expand comment in memory.rs with extra soundness concerns
RalfJung Apr 29, 2020
827d6f6
document stable counterparts of intrinsics
lcnr Apr 29, 2020
a985879
Suggest deref when coercing `ty::Ref` to `ty::RawPtr`
ldm0 Apr 29, 2020
4813a81
Add clarification on std::cfg macro docs v. #[cfg] attribute
dfreese Apr 29, 2020
610f944
Update src/libcore/macros/mod.rs
dfreese Apr 29, 2020
4e6772b
Rollup merge of #71205 - NeoRaider:check_attr, r=jonas-schievink
Dylan-DPC Apr 30, 2020
58d955e
Rollup merge of #71540 - ldm0:ref2ptr, r=oli-obk
Dylan-DPC Apr 30, 2020
71bf986
Rollup merge of #71655 - RalfJung:const-pattern-soundness, r=oli-obk
Dylan-DPC Apr 30, 2020
e2333a9
Rollup merge of #71672 - lcnr:instrinsics-wow, r=Dylan-DPC
Dylan-DPC Apr 30, 2020
8f6eabf
Rollup merge of #71692 - dfreese:cfgdocs, r=kennytm
Dylan-DPC Apr 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 84 additions & 12 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -782,36 +782,43 @@ extern "rust-intrinsic" {
/// characteristics.
///
/// The `locality` argument must be a constant integer and is a temporal locality specifier
/// ranging from (0) - no locality, to (3) - extremely local keep in cache
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
///
/// This intrinsic does not have a stable counterpart.
pub fn prefetch_read_data<T>(data: *const T, locality: i32);
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
/// if supported; otherwise, it is a no-op.
/// Prefetches have no effect on the behavior of the program but can change its performance
/// characteristics.
///
/// The `locality` argument must be a constant integer and is a temporal locality specifier
/// ranging from (0) - no locality, to (3) - extremely local keep in cache
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
///
/// This intrinsic does not have a stable counterpart.
pub fn prefetch_write_data<T>(data: *const T, locality: i32);
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
/// if supported; otherwise, it is a no-op.
/// Prefetches have no effect on the behavior of the program but can change its performance
/// characteristics.
///
/// The `locality` argument must be a constant integer and is a temporal locality specifier
/// ranging from (0) - no locality, to (3) - extremely local keep in cache
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
///
/// This intrinsic does not have a stable counterpart.
pub fn prefetch_read_instruction<T>(data: *const T, locality: i32);
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
/// if supported; otherwise, it is a no-op.
/// Prefetches have no effect on the behavior of the program but can change its performance
/// characteristics.
///
/// The `locality` argument must be a constant integer and is a temporal locality specifier
/// ranging from (0) - no locality, to (3) - extremely local keep in cache
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
///
/// This intrinsic does not have a stable counterpart.
pub fn prefetch_write_instruction<T>(data: *const T, locality: i32);
}

extern "rust-intrinsic" {

/// An atomic fence.
///
/// The stabilized version of this intrinsic is available in
Expand Down Expand Up @@ -905,12 +912,14 @@ extern "rust-intrinsic" {
/// that `rustc_peek(potentially_uninitialized)` would actually
/// double-check that dataflow did indeed compute that it is
/// uninitialized at that point in the control flow.
///
/// This intrinsic should not be used outside of the compiler.
pub fn rustc_peek<T>(_: T) -> T;

/// Aborts the execution of the process.
///
/// The stabilized version of this intrinsic is
/// [`std::process::abort`](../../std/process/fn.abort.html)
/// [`std::process::abort`](../../std/process/fn.abort.html).
pub fn abort() -> !;

/// Tells LLVM that this point in the code is not reachable, enabling
Expand All @@ -932,21 +941,29 @@ extern "rust-intrinsic" {
/// with optimization of surrounding code and reduce performance. It should
/// not be used if the invariant can be discovered by the optimizer on its
/// own, or if it does not enable any significant optimizations.
///
/// This intrinsic does not have a stable counterpart.
pub fn assume(b: bool);

/// Hints to the compiler that branch condition is likely to be true.
/// Returns the value passed to it.
///
/// Any use other than with `if` statements will probably not have an effect.
///
/// This intrinsic does not have a stable counterpart.
pub fn likely(b: bool) -> bool;

/// Hints to the compiler that branch condition is likely to be false.
/// Returns the value passed to it.
///
/// Any use other than with `if` statements will probably not have an effect.
///
/// This intrinsic does not have a stable counterpart.
pub fn unlikely(b: bool) -> bool;

/// Executes a breakpoint trap, for inspection by a debugger.
///
/// This intrinsic does not have a stable counterpart.
pub fn breakpoint();

/// The size of a type in bytes.
Expand All @@ -973,6 +990,9 @@ extern "rust-intrinsic" {
/// [`std::mem::align_of`](../../std/mem/fn.align_of.html).
#[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
pub fn min_align_of<T>() -> usize;
/// The prefered alignment of a type.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_const_unstable(feature = "const_pref_align_of", issue = "none")]
pub fn pref_align_of<T>() -> usize;

Expand All @@ -981,6 +1001,10 @@ extern "rust-intrinsic" {
/// The stabilized version of this intrinsic is
/// [`std::mem::size_of_val`](../../std/mem/fn.size_of_val.html).
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
/// The required alignment of the referenced value.
///
/// The stabilized version of this intrinsic is
/// [`std::mem::align_of_val`](../../std/mem/fn.align_of_val.html).
pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize;

/// Gets a static string slice containing the name of a type.
Expand All @@ -1001,22 +1025,33 @@ extern "rust-intrinsic" {

/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
/// This will statically either panic, or do nothing.
///
/// This intrinsic does not have a stable counterpart.
pub fn assert_inhabited<T>();

/// A guard for unsafe functions that cannot ever be executed if `T` does not permit
/// zero-initialization: This will statically either panic, or do nothing.
///
/// This intrinsic does not have a stable counterpart.
pub fn assert_zero_valid<T>();

/// A guard for unsafe functions that cannot ever be executed if `T` has invalid
/// bit patterns: This will statically either panic, or do nothing.
///
/// This intrinsic does not have a stable counterpart.
pub fn assert_uninit_valid<T>();

/// Gets a reference to a static `Location` indicating where it was called.
///
/// Consider using [`std::panic::Location::caller`](../../std/panic/struct.Location.html#method.caller)
/// instead.
#[rustc_const_unstable(feature = "const_caller_location", issue = "47809")]
pub fn caller_location() -> &'static crate::panic::Location<'static>;

/// Moves a value out of scope without running drop glue.
/// This exists solely for `mem::forget_unsized`; normal `forget` uses `ManuallyDrop` instead.
///
/// This exists solely for [`mem::forget_unsized`](../../std/mem/fn.forget_unsized.html);
/// normal `forget` uses `ManuallyDrop` instead.
pub fn forget<T: ?Sized>(_: T);

/// Reinterprets the bits of a value of one type as another type.
Expand Down Expand Up @@ -1300,20 +1335,26 @@ extern "rust-intrinsic" {
///
/// The volatile parameter is set to `true`, so it will not be optimized out
/// unless size is equal to zero.
///
/// This intrinsic does not have a stable counterpart.
pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
/// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
/// a size of `count` * `size_of::<T>()` and an alignment of
/// `min_align_of::<T>()`
///
/// The volatile parameter is set to `true`, so it will not be optimized out
/// unless size is equal to zero.
///
/// This intrinsic does not have a stable counterpart.
pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize);
/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
/// size of `count` * `size_of::<T>()` and an alignment of
/// `min_align_of::<T>()`.
///
/// The volatile parameter is set to `true`, so it will not be optimized out
/// unless size is equal to zero.
///
/// This intrinsic does not have a stable counterpart.
pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: usize);

/// Performs a volatile load from the `src` pointer.
Expand All @@ -1329,9 +1370,13 @@ extern "rust-intrinsic" {

/// Performs a volatile load from the `src` pointer
/// The pointer is not required to be aligned.
///
/// This intrinsic does not have a stable counterpart.
pub fn unaligned_volatile_load<T>(src: *const T) -> T;
/// Performs a volatile store to the `dst` pointer.
/// The pointer is not required to be aligned.
///
/// This intrinsic does not have a stable counterpart.
pub fn unaligned_volatile_store<T>(dst: *mut T, val: T);

/// Returns the square root of an `f32`
Expand Down Expand Up @@ -1539,8 +1584,12 @@ extern "rust-intrinsic" {
pub fn rintf64(x: f64) -> f64;

/// Returns the nearest integer to an `f32`.
///
/// This intrinsic does not have a stable counterpart.
pub fn nearbyintf32(x: f32) -> f32;
/// Returns the nearest integer to an `f64`.
///
/// This intrinsic does not have a stable counterpart.
pub fn nearbyintf64(x: f64) -> f64;

/// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero.
Expand All @@ -1556,28 +1605,39 @@ extern "rust-intrinsic" {

/// Float addition that allows optimizations based on algebraic rules.
/// May assume inputs are finite.
///
/// This intrinsic does not have a stable counterpart.
pub fn fadd_fast<T: Copy>(a: T, b: T) -> T;

/// Float subtraction that allows optimizations based on algebraic rules.
/// May assume inputs are finite.
///
/// This intrinsic does not have a stable counterpart.
pub fn fsub_fast<T: Copy>(a: T, b: T) -> T;

/// Float multiplication that allows optimizations based on algebraic rules.
/// May assume inputs are finite.
///
/// This intrinsic does not have a stable counterpart.
pub fn fmul_fast<T: Copy>(a: T, b: T) -> T;

/// Float division that allows optimizations based on algebraic rules.
/// May assume inputs are finite.
///
/// This intrinsic does not have a stable counterpart.
pub fn fdiv_fast<T: Copy>(a: T, b: T) -> T;

/// Float remainder that allows optimizations based on algebraic rules.
/// May assume inputs are finite.
///
/// This intrinsic does not have a stable counterpart.
pub fn frem_fast<T: Copy>(a: T, b: T) -> T;

/// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range
/// (<https://github.com/rust-lang/rust/issues/10184>)
///
/// Stabilized as `f32::to_int_unchecked` and `f64::to_int_unchecked`.
/// Stabilized as [`f32::to_int_unchecked`](../../std/primitive.f32.html#method.to_int_unchecked)
/// and [`f64::to_int_unchecked`](../../std/primitive.f64.html#method.to_int_unchecked).
pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;

/// Returns the number of bits set in an integer type `T`
Expand Down Expand Up @@ -1623,6 +1683,8 @@ extern "rust-intrinsic" {
/// Like `ctlz`, but extra-unsafe as it returns `undef` when
/// given an `x` with value `0`.
///
/// This intrinsic does not have a stable counterpart.
///
/// # Examples
///
/// ```
Expand Down Expand Up @@ -1672,6 +1734,8 @@ extern "rust-intrinsic" {
/// Like `cttz`, but extra-unsafe as it returns `undef` when
/// given an `x` with value `0`.
///
/// This intrinsic does not have a stable counterpart.
///
/// # Examples
///
/// ```
Expand Down Expand Up @@ -1728,20 +1792,22 @@ extern "rust-intrinsic" {

/// Performs an exact division, resulting in undefined behavior where
/// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`
///
/// This intrinsic does not have a stable counterpart.
pub fn exact_div<T: Copy>(x: T, y: T) -> T;

/// Performs an unchecked division, resulting in undefined behavior
/// where y = 0 or x = `T::MIN` and y = -1
///
/// The stabilized versions of this intrinsic are available on the integer
/// Safe wrappers for this intrinsic are available on the integer
/// primitives via the `checked_div` method. For example,
/// [`std::u32::checked_div`](../../std/primitive.u32.html#method.checked_div)
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
pub fn unchecked_div<T: Copy>(x: T, y: T) -> T;
/// Returns the remainder of an unchecked division, resulting in
/// undefined behavior where y = 0 or x = `T::MIN` and y = -1
///
/// The stabilized versions of this intrinsic are available on the integer
/// Safe wrappers for this intrinsic are available on the integer
/// primitives via the `checked_rem` method. For example,
/// [`std::u32::checked_rem`](../../std/primitive.u32.html#method.checked_rem)
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
Expand All @@ -1750,32 +1816,38 @@ extern "rust-intrinsic" {
/// Performs an unchecked left shift, resulting in undefined behavior when
/// y < 0 or y >= N, where N is the width of T in bits.
///
/// The stabilized versions of this intrinsic are available on the integer
/// Safe wrappers for this intrinsic are available on the integer
/// primitives via the `checked_shl` method. For example,
/// [`std::u32::checked_shl`](../../std/primitive.u32.html#method.checked_shl)
#[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
pub fn unchecked_shl<T: Copy>(x: T, y: T) -> T;
/// Performs an unchecked right shift, resulting in undefined behavior when
/// y < 0 or y >= N, where N is the width of T in bits.
///
/// The stabilized versions of this intrinsic are available on the integer
/// Safe wrappers for this intrinsic are available on the integer
/// primitives via the `checked_shr` method. For example,
/// [`std::u32::checked_shr`](../../std/primitive.u32.html#method.checked_shr)
#[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
pub fn unchecked_shr<T: Copy>(x: T, y: T) -> T;

/// Returns the result of an unchecked addition, resulting in
/// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
pub fn unchecked_add<T: Copy>(x: T, y: T) -> T;

/// Returns the result of an unchecked subtraction, resulting in
/// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
pub fn unchecked_sub<T: Copy>(x: T, y: T) -> T;

/// Returns the result of an unchecked multiplication, resulting in
/// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
pub fn unchecked_mul<T: Copy>(x: T, y: T) -> T;

Expand Down
4 changes: 4 additions & 0 deletions src/libcore/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,10 @@ pub(crate) mod builtin {
/// The syntax given to this macro is the same syntax as the [`cfg`]
/// attribute.
///
/// `cfg!`, unlike `#[cfg]`, does not remove any code and only evaluates to true or false. For
/// example, all blocks in an if/else expression need to be valid when `cfg!` is used for
/// the condition, regardless of what `cfg!` is evaluating.
///
/// [`cfg`]: ../reference/conditional-compilation.html#the-cfg-attribute
///
/// # Examples
Expand Down
2 changes: 2 additions & 0 deletions src/libcore/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ impl<'a> Location<'a> {
/// assert_ne!(this_location.line(), another_location.line());
/// assert_ne!(this_location.column(), another_location.column());
/// ```
// FIXME: When stabilizing this method, please also update the documentation
// of `intrinsics::caller_location`.
#[unstable(
feature = "track_caller",
reason = "uses #[track_caller] which is not yet stable",
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ fn validate_and_turn_into_const<'tcx>(
mplace.into(),
path,
&mut ref_tracking,
/*may_ref_to_static*/ is_static,
/*may_ref_to_static*/ ecx.memory.extra.can_access_statics,
)?;
}
}
Expand Down
11 changes: 10 additions & 1 deletion src/librustc_mir/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,12 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {

#[derive(Copy, Clone, Debug)]
pub struct MemoryExtra {
/// Whether this machine may read from statics
/// We need to make sure consts never point to anything mutable, even recursively. That is
/// relied on for pattern matching on consts with references.
/// To achieve this, two pieces have to work together:
/// * Interning makes everything outside of statics immutable.
/// * Pointers to allocations inside of statics can never leak outside, to a non-static global.
/// This boolean here controls the second part.
pub(super) can_access_statics: bool,
}

Expand Down Expand Up @@ -337,6 +342,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
} else if static_def_id.is_some() {
// Machine configuration does not allow us to read statics
// (e.g., `const` initializer).
// See const_eval::machine::MemoryExtra::can_access_statics for why
// this check is so important: if we could read statics, we could read pointers
// to mutable allocations *inside* statics. These allocations are not themselves
// statics, so pointers to them can get around the check in `validity.rs`.
Err(ConstEvalErrKind::ConstAccessesStatic.into())
} else {
// Immutable global, this read is fine.
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_mir/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
// thing here: one maps to `GlobalAlloc::Static`, this is the "lazy" ID,
// and the other one is maps to `GlobalAlloc::Memory`, this is returned by
// `const_eval_raw` and it is the "resolved" ID.
// The resolved ID is never used by the interpreted progrma, it is hidden.
// The resolved ID is never used by the interpreted program, it is hidden.
// This is relied upon for soundness of const-patterns; a pointer to the resolved
// ID would "sidestep" the checks that make sure consts do not point to statics!
// The `GlobalAlloc::Memory` branch here is still reachable though; when a static
// contains a reference to memory that was created during its evaluation (i.e., not
// to another static), those inner references only exist in "resolved" form.
Expand Down
Loading