Skip to content

TVM: INT_MIN % -1 throws integer overflow #226

Description

@jubnzv

INT_MIN % -1 aborts with integer overflow, while the C++ reference TVM returns 0 (which is correct, x % -1 is 0 for every x).

MRE

Create a test vm/tests/repro_mod_intmin.rs:

use ton_assembler::compile_code_to_cell;
use ton_vm::executor::Engine;
use ton_vm::stack::{Stack, StackItem};

const INT_MIN: &str = "-115792089237316195423570985008687907853269984665640564039457584007913129639936"; // -2^256

#[test]
fn mod_int_min_by_neg_one() {
    let code = compile_code_to_cell(&format!("PUSHINT {INT_MIN} PUSHINT -1 MOD")).unwrap();
    let mut engine =
        Engine::with_capabilities(0).setup(code, None, Some(Stack::new()), None, vec![]).unwrap();
    let res = engine.execute();
    println!("execute() = {res:?}");
    assert!(res.is_ok(), "INT_MIN % -1 must not trap, got {:?}", res.err());
    assert_eq!(engine.stack().get(0).unwrap(), &StackItem::int(0));
}

Command:

cd src
cargo test --release -p ton_vm --test repro_mod_intmin -- --nocapture

Results:

execute() = Err(integer overflow, code 4, , vm/src/executor/math.rs:621)

test mod_int_min_by_neg_one ................. FAILED       # INT_MIN % -1 traps (WRONG, expected 0)

C++ TVM

Identical instructions on the C++ TVM (fift's inline assembler) return 0, no trap:

printf '"Asm.fif" include <{ -115792089237316195423570985008687907853269984665640564039457584007913129639936 PUSHINT -1 PUSHINT MOD }>c <s constant code code 1 runvmx .s\n' | FIFTPATH=$TON/crypto/fift/lib $TON/build/crypto/fift -i
0 0        # result 0, exit code 0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions