Skip to content

fix(ir): validate casts and emit unambiguous quoted IR - #240

Merged
LunaStev merged 1 commit into
wavefnd:masterfrom
LunaStev:fix/ir-casts-and-text-identities
Oct 7, 2026
Merged

LunaStev merged 1 commit into
wavefnd:masterfrom
LunaStev:fix/ir-casts-and-text-identities

Conversation

@LunaStev

@LunaStev LunaStev commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Problem and resulting behavior

A Bool value falsely annotated as an f64 cast source previously passed verification, as did checked i32 arithmetic using Bool operands. Printed IR also omitted parameter/block definition IDs while references used numeric IDs, making repeated friendly block names ambiguous. Raw names and control characters could split printed records.

This change rejects malformed conversions and checked operands, and emits typed IR format 3 with explicit identities and consistently quoted strings. AST JSON remains format 2 and semantics version remains 1.

Closes #109
Closes #52
Closes #53

Verification

  • Verify each cast's actual source against its source annotation and its result against the value type table. InvalidCast records the result ID, opcode and source/destination types.
  • Require increasing integer widths for zero/sign extension, decreasing widths for truncation, and the corresponding increasing/decreasing floating widths for fext/ftrunc. Integer bit operations may change signedness.
  • Distinguish signed/unsigned integer-to-float and float-to-integer opcode categories. Scalar bitcasts require equal numeric bit widths; data-pointer-to-data-pointer bitcasts are accepted. Pointer/integer operations check their respective operand categories. Function-pointer casts remain rejected, including attempts to disguise the actual source type.
  • Permit Bool's explicit 0/1 zero-extension to integer destinations except signed i1, including u1. Bool cannot be sign-extended, truncated or reinterpreted as an integer bit pattern.
  • Require signed types for signed checked arithmetic, unsigned types for unsigned checked arithmetic, exact types for both operands and tuple<T, bool> results. Add regression coverage for existing tuple extraction checks: tuple category, field bounds and exact field/result type.

Textual IR format 3

Function/global definitions and references use @fN/@gN; parameters and instructions define %vN; block definitions, branch/switch targets and phi predecessors use %bN. The printer preserves the supplied IDs and physical order, and explicitly records each function's entry %bN. Value and block IDs are scoped to their containing function. Friendly names are quoted annotations, so duplicate block names and equal names in the function/global namespaces do not confuse references.

For example:

fn @f21 "flow"(%v40 "x": i32, %v41 "c": bool) -> i32, entry %b10 {
%b40 "repeat":
  %v42: i32 = phi i32 [ %v40, %b20 ], [ %v40, %b30 ]
  switch i32 %v42, label %b60 [ 0: %b50 ]

This is a syntax fragment; the full verified multi-function fixture is ir/tests/fixtures/text-identities-v3.wir.

All target/name/link-name/constant-declaration/trap string fields use the same quoting function. It escapes quote, backslash, LF, CR, tab, NUL, other Unicode control characters and U+2028/U+2029; printable Unicode is preserved. No Rust Debug-dependent spelling remains in string records.

The AST-call golden output is renamed to calls-v3.wir; existing printer assertions and the README are updated. LF fixture normalization remains enforced for Windows checkouts.

Validation

  • Offline locked workspace tests: default 147 passed, all-features 182 passed.
  • Rust 1.86.0 locked all-features workspace tests passed.
  • Workspace Clippy, all targets, default and all-features with -D warnings passed.
  • Workspace fmt and diff whitespace checks passed.
  • Both feature configurations built and passed standalone CLI smoke with an empty PATH.
  • New tests cover every cast opcode, illegal type/width pairs, forged annotations, checked operands/result tuples, tuple extraction, repeated block names, function-local ID reuse, a non-first stored entry block, branch/switch/phi references and all string fields.

Boundaries and follow-up

These are structural verification and printing changes. They do not implement numeric execution, runtime conversion traps, pointer metadata, a text parser or full text round trips. The arithmetic wrap/trap contract is unchanged. #89, #67 and #83 remain separate work.

The audit also reproduced and filed public-IR-API stack overflows as #238 (type/signature validation) and #239 (constant expression evaluation). Those issues remain open and are not claimed as fixed here.

Official reference updates across all nine existing Whale documentation languages are submitted separately to wave-platform, with complete IR/Rust examples, permitted/rejected conversion shapes, the new ID/escape syntax and format migration guidance.

@LunaStev
LunaStev merged commit b80bbbe into wavefnd:master Oct 7, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant