Fix drop handling in hint::select_unpredictable · rust-lang/rust@e5e5fb9 (original) (raw)

`@@ -4,6 +4,7 @@

`

4

4

`//!

`

5

5

`//! Hints may be compile time or runtime.

`

6

6

``

``

7

`+

use crate::mem::MaybeUninit;

`

7

8

`use crate::{intrinsics, ub_checks};

`

8

9

``

9

10

`/// Informs the compiler that the site which is calling this function is not

`

`@@ -735,9 +736,9 @@ pub const fn cold_path() {

`

735

736

`crate::intrinsics::cold_path()

`

736

737

`}

`

737

738

``

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.

`

741

742

`///

`

742

743

`/// This method is functionally equivalent to

`

743

744

```` /// ```ignore (this is just for illustrative purposes)


`@@ -753,10 +754,10 @@ pub const fn cold_path() {

`

`753`

`754`

`/// search.

`

`754`

`755`

`///

`

`755`

`756`

`/// 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.

`

`760`

`761`

`///

`

`761`

`762`

`/// # Examples

`

`762`

`763`

`///

`

`@@ -780,6 +781,17 @@ pub const fn cold_path() {

`

`780`

`781`

```` /// ```

781

782

`#[inline(always)]

`

782

783

`#[unstable(feature = "select_unpredictable", issue = "133962")]

`

783

``

`-

pub fn select_unpredictable(b: bool, true_val: T, false_val: T) -> T {

`

784

``

`-

crate::intrinsics::select_unpredictable(b, true_val, false_val)

`

``

784

`+

pub fn select_unpredictable(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

`+

}

`

785

797

`}

`