Skip to content

signed int multiply translated as checked *, panics instead of wrapping like C #33

Description

@awto-au

Bug: signed int multiply translated as checked *, panics instead of wrapping like C

Related to the already-fixed #27 (refcount.h overflow-detection idiom) — same root cause class (C's implementation-defined-wrapping signed arithmetic translated as Rust's panic-on-overflow */+/-), different call site.

Repro

C source (lib/tests/test_sort.c, a bounded LCG-style pseudo-random sequence):

static void test_sort(struct kunit *test)
{
	int *a, i, r = 1;
	...
	for (i = 0; i < TEST_LEN; i++) {
		r = (r * 725861) % 6599;
		a[i] = r;
	}
	...
}

r is always reduced mod 6599 after each iteration, so on the surface this looks bounded — but the intermediate product r * 725861 (with r up to 6598) is up to ~4.79 billion, which overflows i32 (max ~2.1 billion) before the % 6599 brings it back down. C's signed overflow here wraps in practice (GCC/clang default codegen); c2rust's transpile emits a plain Rust * operator:

r = r * 725861 as ::core::ffi::c_int % 6599 as ::core::ffi::c_int;

With overflow-checks on (as in a debug/kernel Rust build), this panics at runtime:

panicked at lib/tests/test_sort_rs.rs:4088:17:
attempt to multiply with overflow

Fix applied locally (narrow, not upstreamed yet)

r = r.wrapping_mul(725861 as ::core::ffi::c_int) % 6599 as ::core::ffi::c_int;

Suggested general fix

Same shape as #27's resolution: any C signed-integer */+/- operation should translate to wrapping_mul/wrapping_add/wrapping_sub rather than the bare Rust operator, since C's actual (if technically UB) runtime behavior for these ops is 2's-complement wraparound on every mainstream target — matching what #27 already established for +/-, this closes the same gap for *.

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