Skip to content

Systematic False Negatives: Immediate Closures suppress warnings (Arithmetic, Memory, Unsafe, Logic) #38

@chisa22

Description

@chisa22

I have observed that MIRAI fails to report a wide variety of warnings when code is executed inside an immediate closure ((|| { ... })()).
The exact same code correctly triggers warnings when placed directly in the function body. This indicates a systemic issue where the analysis does not propagate errors or check conditions across closure boundaries.
To Reproduce

#![allow(arithmetic_overflow, unconditional_panic)]
fn val<T>(v: T) -> T { v } 
fn test_shr() { (|| { let _ = val(8i8) >> val(8i8); })(); }
fn test_shl() { (|| { let _ = val(64u64) << val(64u64); })(); }
fn test_mul() { (|| { let _ = val(u64::MAX/2 + 1) * 2; })(); }
fn test_add() { (|| { let _ = val(u16::MAX) + 1; })(); }
fn test_sub() { (|| { let _ = val(i32::MIN) - 1; })(); }
fn test_neg() { (|| { let _ = Box::new(-val(i64::MIN)); })(); }
fn test_div() { (|| { let _ = val(-128i8) / val(-1i8); })(); }
fn test_rem() { (|| { let _ = val(-128i8) % val(-1i8); })(); }

pub fn main() {
    test_shr();
    test_shl();
    test_mul();
    test_add();
    test_sub();
    test_neg();
    test_div();
    test_rem();
}
use mirai_annotations::*;
pub union U2 { pub x: u64, pub y: [u8; 4] }
fn val<T>(v: T) -> T { v }

pub fn main() {
    // Union partial initialization
    (|| { 
        let _u = U2 { y: [1, 1, 0, 0] }; 
    })(); 

    // Index out of bounds
    (|| {
        let arr = [0, 1, 2, 3, 4];
        let _ = arr[val(10)]; 
    })();
}
#![feature(core_intrinsics)]
#![allow(internal_features)]
use std::alloc::{alloc, dealloc, realloc, Layout};
use std::intrinsics::{arith_offset, offset};

pub fn main() {
    (|| unsafe {
        // Offset outside range
        let a = alloc(std::alloc::Layout::from_size_align(4, 2).unwrap());
        let b = arith_offset(a, -2);
        let c = offset(b, 1isize);
    })();

    (|| unsafe {
        // Realloc inconsistent layout
        let p = alloc(Layout::from_size_align(4, 2).unwrap());
        let _ = realloc(p, Layout::from_size_align(8, 2).unwrap(), 16); 
    })();

    (|| unsafe {
        // Dealloc inconsistent layout
        let p = alloc(Layout::from_size_align(4, 2).unwrap());
        dealloc(p, Layout::from_size_align(8, 2).unwrap()); 
    })();

    (|| unsafe {
        // Use after free
        let l = Layout::from_size_align(4, 2).unwrap();
        let p = alloc(l);
        dealloc(p, l);
        let _ = realloc(p, l, 8); 
    })();
}
use mirai_annotations::*;
use std::cell::Cell;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::thread::Thread;

const RUNNING: usize = 1;
pub struct Waiter { thread: Cell<Option<Thread>>, signaled: AtomicBool, next: *const Waiter }
pub struct WaiterQueue<'a> { state: &'a AtomicUsize, drop_state: usize }

impl Drop for WaiterQueue<'_> {
    fn drop(&mut self) {
        let s = self.state.swap(self.drop_state, Ordering::AcqRel);
        assert_eq!(s & 3, RUNNING);
    }
}

pub fn main() {
    (|| {
        let w = Waiter { thread: Cell::new(None), signaled: AtomicBool::new(false), next: std::ptr::null() };
        let wq = WaiterQueue { state: &AtomicUsize::new(RUNNING), drop_state: 0 };
        std::mem::drop(wq);
        unsafe {
            let w_ref = &*(&w as *const Waiter);
            verify!(w_ref.signaled.load(Ordering::Relaxed)); // False verification missed
        }
    })();
}

Run cargo mirai
Expected Behavior
MIRAI should report warnings for all the operations listed inside the closures, just as it does when they are executed directly in main.
Actual Behavior
MIRAI reports zero warnings for these cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions