Skip to content

Fix C undefined behavior in integer arithmetic across interpreter and compiler#506

Open
nbeerbower wants to merge 2 commits into
mainfrom
claude/fix-c-undefined-behavior-rSKph
Open

Fix C undefined behavior in integer arithmetic across interpreter and compiler#506
nbeerbower wants to merge 2 commits into
mainfrom
claude/fix-c-undefined-behavior-rSKph

Conversation

@nbeerbower

Copy link
Copy Markdown
Collaborator

Audit and fix multiple categories of C undefined behavior that could manifest
through Hemlock programs:

  1. i8/i16 signed overflow (interpreter): Add overflow-checked arithmetic
    using widening to i32 and range validation, matching i32/i64 behavior.

  2. Increment/decrement overflow (interpreter + compiler): Replace unchecked
    +1/-1 with overflow-detected versions using __builtin_add/sub_overflow for
    i32/i64, and boundary checks for i8/i16.

  3. Negation of INT_MIN (interpreter + compiler): Add checks before negating
    signed integers at their minimum value (-INT8_MIN, -INT32_MIN, etc. are UB).

  4. Compiler runtime fast paths (builtins_ops.c): Add _builtin*_overflow
    checks to i32/i64 add/sub/mul in the hml_binary_op fast paths, which
    previously used raw C arithmetic.

  5. Compiler runtime generic path: Add make_int_result_checked() that
    validates narrowing conversions, preventing silent truncation.

  6. Compiler native codegen: Disable unboxed native C arithmetic optimization
    for add/sub/mul/div/mod, falling through to safe runtime functions that have
    proper overflow and division-by-zero checks.

All fixes maintain parity between interpreter and compiler. Three new parity
tests verify the fixes across i8/i16/i32/i64 types.

https://claude.ai/code/session_01HdPatswVjgnAPaLktY2bPQ

claude added 2 commits April 8, 2026 01:31
… compiler

Audit and fix multiple categories of C undefined behavior that could manifest
through Hemlock programs:

1. **i8/i16 signed overflow** (interpreter): Add overflow-checked arithmetic
   using widening to i32 and range validation, matching i32/i64 behavior.

2. **Increment/decrement overflow** (interpreter + compiler): Replace unchecked
   +1/-1 with overflow-detected versions using __builtin_add/sub_overflow for
   i32/i64, and boundary checks for i8/i16.

3. **Negation of INT_MIN** (interpreter + compiler): Add checks before negating
   signed integers at their minimum value (-INT8_MIN, -INT32_MIN, etc. are UB).

4. **Compiler runtime fast paths** (builtins_ops.c): Add __builtin_*_overflow
   checks to i32/i64 add/sub/mul in the hml_binary_op fast paths, which
   previously used raw C arithmetic.

5. **Compiler runtime generic path**: Add make_int_result_checked() that
   validates narrowing conversions, preventing silent truncation.

6. **Compiler native codegen**: Disable unboxed native C arithmetic optimization
   for add/sub/mul/div/mod, falling through to safe runtime functions that have
   proper overflow and division-by-zero checks.

All fixes maintain parity between interpreter and compiler. Three new parity
tests verify the fixes across i8/i16/i32/i64 types.

https://claude.ai/code/session_01HdPatswVjgnAPaLktY2bPQ
Keep upstream's division-by-zero check in native DIV path (safe since it
casts to double). ADD/SUB/MUL/MOD still fall through to safe runtime path
for overflow detection.

https://claude.ai/code/session_01HdPatswVjgnAPaLktY2bPQ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants