Skip to content
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

MIRI fails to detect overflow in signed division #112864

Closed
celinval opened this issue Jun 21, 2023 · 4 comments
Closed

MIRI fails to detect overflow in signed division #112864

celinval opened this issue Jun 21, 2023 · 4 comments
Labels
A-miri Area: The miri tool C-bug Category: This is a bug.

Comments

@celinval
Copy link
Contributor

I tried running MIRI in this code:

#![feature(core_intrinsics)]
fn main() {
    let ub = unsafe { unchecked_div(i32::MAX, -1) };
    // ---> Uncomment this line to see MIRI correctly finding the overflow.
    // let ub = unsafe { std::intrinsics::unchecked_div(i32::MIN, -1) };
    println!("{ub}");
}

unsafe fn unchecked_div(a: i32, b: i32) -> i32 {
    std::intrinsics::unchecked_div(a, b)
}

I expected to see this happen: MIRI should fail with the following error:

error: Undefined Behavior: overflow in signed division (dividing MIN by -1)

Instead, this happened: No UB is detected and the program prints -2147483647.

Meta

I ran this using playground. The version reported is:

0.1.0 (2023-06-18 2d0aa57)
@celinval celinval added the C-bug Category: This is a bug. label Jun 21, 2023
@celinval
Copy link
Contributor Author

@rustbot label A-miri

@rustbot rustbot added the A-miri Area: The miri tool label Jun 21, 2023
@celinval
Copy link
Contributor Author

I wonder if this is related to #112168

@saethlin
Copy link
Member

I'm confused. i32::MAX / -1 doesn't overflow, and Miri correctly does not report UB for the unchecked version. i32::MIN / -1 does overflow, and Miri correctly reports UB for the unchecked version.

#![feature(core_intrinsics)]

fn main() {
    println!("{:?}", i32::MAX.checked_div(-1));
    let not_ub = unsafe { std::intrinsics::unchecked_div(i32::MAX, -1) };
    println!("{not_ub}");

    println!("{:?}", i32::MIN.checked_div(-1));
    let ub = unsafe { std::intrinsics::unchecked_div(i32::MIN, -1) };
    println!("{ub}");
}

Reports UB on the second unchecked_div:

 --> src/main.rs:9:23
  |
9 |     let ub = unsafe { std::intrinsics::unchecked_div(i32::MIN, -1) };
  |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow in signed division (dividing MIN by -1)
  |

@celinval
Copy link
Contributor Author

Shoot, my bad. I did have a typo there, didn't I. Sorry

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-miri Area: The miri tool C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

4 participants
@saethlin @celinval @rustbot and others