Skip to content

Commit 56da6b5

Browse files
author
The Miri Cronjob Bot
committed
Merge from rustc
2 parents 39890cf + 4b57af8 commit 56da6b5

File tree

11 files changed

+92
-45
lines changed

11 files changed

+92
-45
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

alloc/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ bench = false
1616

1717
[dependencies]
1818
core = { path = "../core", public = true }
19-
compiler_builtins = { version = "=0.1.153", features = ['rustc-dep-of-std'] }
19+
compiler_builtins = { version = "=0.1.155", features = ['rustc-dep-of-std'] }
2020

2121
[features]
2222
compiler-builtins-mem = ['compiler_builtins/mem']

core/src/hint.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//!
55
//! Hints may be compile time or runtime.
66
7+
use crate::mem::MaybeUninit;
78
use crate::{intrinsics, ub_checks};
89

910
/// Informs the compiler that the site which is calling this function is not
@@ -735,9 +736,9 @@ pub const fn cold_path() {
735736
crate::intrinsics::cold_path()
736737
}
737738

738-
/// Returns either `true_val` or `false_val` depending on the value of `b`,
739-
/// with a hint to the compiler that `b` is unlikely to be correctly
740-
/// predicted by a CPU’s branch predictor.
739+
/// Returns either `true_val` or `false_val` depending on the value of
740+
/// `condition`, with a hint to the compiler that `condition` is unlikely to be
741+
/// correctly predicted by a CPU’s branch predictor.
741742
///
742743
/// This method is functionally equivalent to
743744
/// ```ignore (this is just for illustrative purposes)
@@ -753,10 +754,10 @@ pub const fn cold_path() {
753754
/// search.
754755
///
755756
/// Note however that this lowering is not guaranteed (on any platform) and
756-
/// should not be relied upon when trying to write constant-time code. Also
757-
/// be aware that this lowering might *decrease* performance if `condition`
758-
/// is well-predictable. It is advisable to perform benchmarks to tell if
759-
/// this function is useful.
757+
/// should not be relied upon when trying to write cryptographic constant-time
758+
/// code. Also be aware that this lowering might *decrease* performance if
759+
/// `condition` is well-predictable. It is advisable to perform benchmarks to
760+
/// tell if this function is useful.
760761
///
761762
/// # Examples
762763
///
@@ -780,6 +781,17 @@ pub const fn cold_path() {
780781
/// ```
781782
#[inline(always)]
782783
#[unstable(feature = "select_unpredictable", issue = "133962")]
783-
pub fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {
784-
crate::intrinsics::select_unpredictable(b, true_val, false_val)
784+
pub fn select_unpredictable<T>(condition: bool, true_val: T, false_val: T) -> T {
785+
// FIXME(https://github.com/rust-lang/unsafe-code-guidelines/issues/245):
786+
// Change this to use ManuallyDrop instead.
787+
let mut true_val = MaybeUninit::new(true_val);
788+
let mut false_val = MaybeUninit::new(false_val);
789+
// SAFETY: The value that is not selected is dropped, and the selected one
790+
// is returned. This is necessary because the intrinsic doesn't drop the
791+
// value that is not selected.
792+
unsafe {
793+
crate::intrinsics::select_unpredictable(!condition, &mut true_val, &mut false_val)
794+
.assume_init_drop();
795+
crate::intrinsics::select_unpredictable(condition, true_val, false_val).assume_init()
796+
}
785797
}

core/src/intrinsics/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,6 +1327,8 @@ pub const fn unlikely(b: bool) -> bool {
13271327
/// any safety invariants.
13281328
///
13291329
/// The public form of this instrinsic is [`core::hint::select_unpredictable`].
1330+
/// However unlike the public form, the intrinsic will not drop the value that
1331+
/// is not selected.
13301332
#[unstable(feature = "core_intrinsics", issue = "none")]
13311333
#[rustc_intrinsic]
13321334
#[rustc_nounwind]

core/src/num/f128.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,16 @@ impl f128 {
224224

225225
/// Not a Number (NaN).
226226
///
227-
/// Note that IEEE 754 doesn't define just a single NaN value;
228-
/// a plethora of bit patterns are considered to be NaN.
229-
/// Furthermore, the standard makes a difference
230-
/// between a "signaling" and a "quiet" NaN,
231-
/// and allows inspecting its "payload" (the unspecified bits in the bit pattern).
232-
/// This constant isn't guaranteed to equal to any specific NaN bitpattern,
233-
/// and the stability of its representation over Rust versions
234-
/// and target platforms isn't guaranteed.
227+
/// Note that IEEE 754 doesn't define just a single NaN value; a plethora of bit patterns are
228+
/// considered to be NaN. Furthermore, the standard makes a difference between a "signaling" and
229+
/// a "quiet" NaN, and allows inspecting its "payload" (the unspecified bits in the bit pattern)
230+
/// and its sign. See the [specification of NaN bit patterns](f32#nan-bit-patterns) for more
231+
/// info.
232+
///
233+
/// This constant is guaranteed to be a quiet NaN (on targets that follow the Rust assumptions
234+
/// that the quiet/signaling bit being set to 1 indicates a quiet NaN). Beyond that, nothing is
235+
/// guaranteed about the specific bit pattern chosen here: both payload and sign are arbitrary.
236+
/// The concrete bit pattern may change across Rust versions and target platforms.
235237
#[allow(clippy::eq_op)]
236238
#[rustc_diagnostic_item = "f128_nan"]
237239
#[unstable(feature = "f128", issue = "116909")]

core/src/num/f16.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,16 @@ impl f16 {
219219

220220
/// Not a Number (NaN).
221221
///
222-
/// Note that IEEE 754 doesn't define just a single NaN value;
223-
/// a plethora of bit patterns are considered to be NaN.
224-
/// Furthermore, the standard makes a difference
225-
/// between a "signaling" and a "quiet" NaN,
226-
/// and allows inspecting its "payload" (the unspecified bits in the bit pattern).
227-
/// This constant isn't guaranteed to equal to any specific NaN bitpattern,
228-
/// and the stability of its representation over Rust versions
229-
/// and target platforms isn't guaranteed.
222+
/// Note that IEEE 754 doesn't define just a single NaN value; a plethora of bit patterns are
223+
/// considered to be NaN. Furthermore, the standard makes a difference between a "signaling" and
224+
/// a "quiet" NaN, and allows inspecting its "payload" (the unspecified bits in the bit pattern)
225+
/// and its sign. See the [specification of NaN bit patterns](f32#nan-bit-patterns) for more
226+
/// info.
227+
///
228+
/// This constant is guaranteed to be a quiet NaN (on targets that follow the Rust assumptions
229+
/// that the quiet/signaling bit being set to 1 indicates a quiet NaN). Beyond that, nothing is
230+
/// guaranteed about the specific bit pattern chosen here: both payload and sign are arbitrary.
231+
/// The concrete bit pattern may change across Rust versions and target platforms.
230232
#[allow(clippy::eq_op)]
231233
#[rustc_diagnostic_item = "f16_nan"]
232234
#[unstable(feature = "f16", issue = "116909")]

core/src/num/f32.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -470,14 +470,16 @@ impl f32 {
470470

471471
/// Not a Number (NaN).
472472
///
473-
/// Note that IEEE 754 doesn't define just a single NaN value;
474-
/// a plethora of bit patterns are considered to be NaN.
475-
/// Furthermore, the standard makes a difference
476-
/// between a "signaling" and a "quiet" NaN,
477-
/// and allows inspecting its "payload" (the unspecified bits in the bit pattern).
478-
/// This constant isn't guaranteed to equal to any specific NaN bitpattern,
479-
/// and the stability of its representation over Rust versions
480-
/// and target platforms isn't guaranteed.
473+
/// Note that IEEE 754 doesn't define just a single NaN value; a plethora of bit patterns are
474+
/// considered to be NaN. Furthermore, the standard makes a difference between a "signaling" and
475+
/// a "quiet" NaN, and allows inspecting its "payload" (the unspecified bits in the bit pattern)
476+
/// and its sign. See the [specification of NaN bit patterns](f32#nan-bit-patterns) for more
477+
/// info.
478+
///
479+
/// This constant is guaranteed to be a quiet NaN (on targets that follow the Rust assumptions
480+
/// that the quiet/signaling bit being set to 1 indicates a quiet NaN). Beyond that, nothing is
481+
/// guaranteed about the specific bit pattern chosen here: both payload and sign are arbitrary.
482+
/// The concrete bit pattern may change across Rust versions and target platforms.
481483
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
482484
#[rustc_diagnostic_item = "f32_nan"]
483485
#[allow(clippy::eq_op)]

core/src/num/f64.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -469,14 +469,16 @@ impl f64 {
469469

470470
/// Not a Number (NaN).
471471
///
472-
/// Note that IEEE 754 doesn't define just a single NaN value;
473-
/// a plethora of bit patterns are considered to be NaN.
474-
/// Furthermore, the standard makes a difference
475-
/// between a "signaling" and a "quiet" NaN,
476-
/// and allows inspecting its "payload" (the unspecified bits in the bit pattern).
477-
/// This constant isn't guaranteed to equal to any specific NaN bitpattern,
478-
/// and the stability of its representation over Rust versions
479-
/// and target platforms isn't guaranteed.
472+
/// Note that IEEE 754 doesn't define just a single NaN value; a plethora of bit patterns are
473+
/// considered to be NaN. Furthermore, the standard makes a difference between a "signaling" and
474+
/// a "quiet" NaN, and allows inspecting its "payload" (the unspecified bits in the bit pattern)
475+
/// and its sign. See the [specification of NaN bit patterns](f32#nan-bit-patterns) for more
476+
/// info.
477+
///
478+
/// This constant is guaranteed to be a quiet NaN (on targets that follow the Rust assumptions
479+
/// that the quiet/signaling bit being set to 1 indicates a quiet NaN). Beyond that, nothing is
480+
/// guaranteed about the specific bit pattern chosen here: both payload and sign are arbitrary.
481+
/// The concrete bit pattern may change across Rust versions and target platforms.
480482
#[rustc_diagnostic_item = "f64_nan"]
481483
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
482484
#[allow(clippy::eq_op)]

coretests/tests/hint.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#[test]
2+
fn select_unpredictable_drop() {
3+
use core::cell::Cell;
4+
struct X<'a>(&'a Cell<bool>);
5+
impl Drop for X<'_> {
6+
fn drop(&mut self) {
7+
self.0.set(true);
8+
}
9+
}
10+
11+
let a_dropped = Cell::new(false);
12+
let b_dropped = Cell::new(false);
13+
let a = X(&a_dropped);
14+
let b = X(&b_dropped);
15+
assert!(!a_dropped.get());
16+
assert!(!b_dropped.get());
17+
let selected = core::hint::select_unpredictable(core::hint::black_box(true), a, b);
18+
assert!(!a_dropped.get());
19+
assert!(b_dropped.get());
20+
drop(selected);
21+
assert!(a_dropped.get());
22+
assert!(b_dropped.get());
23+
}

coretests/tests/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
#![feature(pointer_is_aligned_to)]
6969
#![feature(portable_simd)]
7070
#![feature(ptr_metadata)]
71+
#![feature(select_unpredictable)]
7172
#![feature(slice_from_ptr_range)]
7273
#![feature(slice_internals)]
7374
#![feature(slice_partition_dedup)]
@@ -147,6 +148,7 @@ mod ffi;
147148
mod fmt;
148149
mod future;
149150
mod hash;
151+
mod hint;
150152
mod intrinsics;
151153
mod io;
152154
mod iter;

0 commit comments

Comments
 (0)